add: Context for task data

This commit is contained in:
Boris Nikolaev
2026-02-15 22:49:04 +03:00
parent 5e2df678ab
commit c9373df232
3 changed files with 160 additions and 72 deletions
+90 -63
View File
@@ -4,6 +4,7 @@ using System.IO;
using System.Text; using System.Text;
using dq8chr2glb.Container; using dq8chr2glb.Container;
using dq8chr2glb.Converter; using dq8chr2glb.Converter;
using dq8chr2glb.Converter.GLTF;
using dq8chr2glb.Core.InfoCfg; using dq8chr2glb.Core.InfoCfg;
using dq8chr2glb.Core.MDSFormat; using dq8chr2glb.Core.MDSFormat;
using dq8chr2glb.Core.MOTFormat; using dq8chr2glb.Core.MOTFormat;
@@ -15,61 +16,72 @@ namespace dq8chr2glb;
public class ChrFile public class ChrFile
{ {
public ModelConfig infoCfg;
public List<TM2Format.Texture> textures = new();
public List<MDSConverter> mdsConverters = new();
public bool extract; public bool extract;
public bool convert; public bool convert;
public bool textFormat; public bool textFormat;
public void Process(string inputPath, string outputPath, bool isBatch = false) public void Process(string inputPath, string outputPath)
{ {
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var chrData = File.ReadAllBytes(inputPath);
var ctx = new Context();
ctx.inputPath = inputPath;
ctx.modelName = Path.GetFileNameWithoutExtension(ctx.inputPath);
ctx.outputPath = Path.Combine(outputPath, ctx.modelName);
var chrData = File.ReadAllBytes(ctx.inputPath);
var container = ChrContainer.FromBytes(chrData); var container = ChrContainer.FromBytes(chrData);
var outputName = Path.GetFileNameWithoutExtension(inputPath); EnsurePath(ctx.outputPath);
var outputDir = Path.Combine(outputPath, outputName);
EnsurePath(outputDir);
foreach (var file in container) foreach (var file in container)
{ {
if (!isBatch) PrintTask(file);
{
PrintTask(file);
}
switch (file.extension) switch (file.extension)
{ {
case FileExtension.CFG: case FileExtension.CFG:
ProcessConfig(file, outputDir); ProcessConfig(file);
break; break;
case FileExtension.TEXT: case FileExtension.TEXT:
ProcessTextFile(file, outputDir); ProcessTextFile(file);
break; break;
case FileExtension.TM2: case FileExtension.TM2:
ProcessTextures(file, outputDir); ProcessTextures(file);
break; break;
case FileExtension.MDS: case FileExtension.MDS:
ProcessMDSFile(file, outputDir); ProcessMDSFile(file);
break; break;
case FileExtension.MOT: case FileExtension.MOT:
ProcessMOTFile(file, outputDir); ProcessMOTFile(file);
break; break;
default: default:
ProcessRawFile(file, outputDir); ProcessRawFile(file);
break; break;
} }
} }
if (convert) if (convert)
{ {
foreach (var converter in mdsConverters) foreach (var converter in Context.current.mdsConverters)
{ {
converter.Save(outputDir, textFormat); converter.Save(ctx.outputPath, textFormat);
} }
} }
foreach (var err in Context.current.errors)
{
Log.Line($"{err.name}, {err.text}", LogLevel.Error);
if (err.exception != null)
{
Log.Error(err.exception);
}
}
foreach (var err in Context.current.messages)
{
Log.Line($"{err.name}, {err.text}");
}
} }
private void PrintTask(IncludedFile file) private void PrintTask(IncludedFile file)
@@ -84,13 +96,6 @@ public class ChrFile
Log.Line($" Process: {file.name + spacer} {file.data.Length} bytes"); Log.Line($" Process: {file.name + spacer} {file.data.Length} bytes");
} }
public void Clean()
{
infoCfg = null;
textures = new();
mdsConverters = new();
}
private void EnsurePath(string path) private void EnsurePath(string path)
{ {
if (!Directory.Exists(path)) if (!Directory.Exists(path))
@@ -99,34 +104,35 @@ public class ChrFile
} }
} }
private void ProcessMOTFile(IncludedFile file, string outputDir) private void ProcessMOTFile(IncludedFile file)
{ {
if (extract) if (extract)
{ {
ProcessRawFile(file, outputDir); ProcessRawFile(file);
} }
if (convert) if (convert)
{ {
foreach (var converter in mdsConverters) foreach (var converter in Context.current.mdsConverters)
{ {
var motImporter = new Importer(); var motImporter = new Importer();
var animation = motImporter.Import(file.data); var animation = motImporter.Import(file.data);
converter.CreateAnimation(animation, infoCfg); converter.CreateAnimation(animation, Context.current.infoCfg);
} }
} }
} }
private void ProcessMDSFile(IncludedFile file, string outputDir) private void ProcessMDSFile(IncludedFile file)
{ {
if (extract) if (extract)
{ {
ProcessRawFile(file, outputDir); ProcessRawFile(file);
} }
var mdsScene = Reader.Read(file.data, file.name); var mdsScene = Reader.Read(file.data, file.name);
if (mdsScene == null) if (mdsScene == null)
{ {
Context.current.errors.Add(new Error(file.name, "mdsScene is empty!"));
return; return;
} }
@@ -134,73 +140,94 @@ public class ChrFile
{ {
var converter = new MDSConverter(file.name); var converter = new MDSConverter(file.name);
var rootName = Path.GetFileNameWithoutExtension(file.name); var rootName = Path.GetFileNameWithoutExtension(file.name);
converter.Convert(mdsScene, textures, rootName); converter.Convert(mdsScene, Context.current.textures, rootName);
mdsConverters.Add(converter); Context.current.mdsConverters.Add(converter);
} }
} }
private void ProcessConfig(IncludedFile file, string outputDir) private void ProcessConfig(IncludedFile file)
{ {
if (extract) if (extract)
{ {
var isSecond = infoCfg != null; var isSecond = Context.current.infoCfg != null;
if (isSecond) if (isSecond)
{ {
file.name = file.name.Replace(".cfg", "_2.cfg"); file.name = file.name.Replace(".cfg", "_2.cfg");
} }
ProcessTextFile(file, outputDir); ProcessTextFile(file);
} }
var data = Encoding.GetEncoding("shift_jis").GetString(file.data).TrimEnd('\0'); var data = Encoding.GetEncoding("shift_jis").GetString(file.data).TrimEnd('\0');
var configFile = new ConfigFile(data); var configFile = new ConfigFile(data);
var info = configFile.ReadConfig(); var info = configFile.ReadConfig();
if (infoCfg == null) if (Context.current.infoCfg == null)
{ {
infoCfg = info; Context.current.infoCfg = info;
} }
} }
private void ProcessTextFile(IncludedFile file, string outputDir) private void ProcessTextFile(IncludedFile file)
{ {
var root = Path.GetDirectoryName(file.name); try
var fileName = Path.GetFileName(file.name);
var outputPath = Path.Combine(outputDir, root);
var text = Encoding.GetEncoding("shift_jis").GetString(file.data).TrimEnd('\0');
if (extract)
{ {
EnsurePath(outputPath); var root = Path.GetDirectoryName(file.name);
File.WriteAllText(Path.Combine(outputPath, fileName), text); var fileName = Path.GetFileName(file.name);
var outputPath = Path.Combine(Context.current.outputPath, root);
var text = Encoding.GetEncoding("shift_jis").GetString(file.data).TrimEnd('\0');
if (string.IsNullOrEmpty(text))
{
Context.current.errors.Add(new Error(file.name, "Text data is empty!"));
return;
}
if (extract)
{
EnsurePath(outputPath);
File.WriteAllText(Path.Combine(outputPath, fileName), text);
}
}
catch (Exception e)
{
Context.current.errors.Add(new Error(file.name, "Error then process text file", e));
} }
} }
private void ProcessRawFile(IncludedFile file, string outputDir) private void ProcessRawFile(IncludedFile file)
{ {
var root = Path.GetDirectoryName(file.name); try
var fileName = Path.GetFileName(file.name);
var outputPath = Path.Combine(outputDir, root);
if (extract)
{ {
EnsurePath(outputPath); var root = Path.GetDirectoryName(file.name);
File.WriteAllBytes(Path.Combine(outputPath, fileName), file.data); var fileName = Path.GetFileName(file.name);
var outputPath = Path.Combine(Context.current.outputPath, root);
if (extract)
{
EnsurePath(outputPath);
File.WriteAllBytes(Path.Combine(outputPath, fileName), file.data);
}
}
catch (Exception e)
{
Context.current.errors.Add(new Error(file.name, $"File extraction failed", e));
} }
} }
private void ProcessTextures(IncludedFile file, string outputDir) private void ProcessTextures(IncludedFile file)
{ {
var root = Path.GetDirectoryName(file.name); var root = Path.GetDirectoryName(file.name);
var fileName = Path.GetFileNameWithoutExtension(file.name); var fileName = Path.GetFileNameWithoutExtension(file.name);
var outputPath = Path.Combine(outputDir, root); var outputPath = Path.Combine(Context.current.outputPath, root);
var image = TM2Format.TM2Format.GetImage(file.data, fileName); var image = TM2Format.TM2Format.GetImage(file, fileName);
if (extract) if (extract)
{ {
EnsurePath(outputPath); EnsurePath(outputPath);
image.data.SaveAsPng(Path.Combine(outputPath, fileName + ".png")); image.data.SaveAsPng(Path.Combine(outputPath, fileName + ".png"));
} }
textures.Add(image); Context.current.textures.Add(image);
} }
} }
+51
View File
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using dq8chr2glb.Converter.GLTF;
using dq8chr2glb.Core.InfoCfg;
namespace dq8chr2glb.Converter;
public class Message
{
public readonly string name;
public readonly string text;
public Message(string name, string text)
{
this.name = name;
this.text = text;
}
}
public class Error
{
public readonly string name;
public readonly string text;
public readonly Exception? exception;
public Error(string name, string text, Exception? exception = null)
{
this.name = name;
this.text = text;
this.exception = exception;
}
}
public class Context
{
public static Context current;
public string modelName;
public string inputPath;
public string outputPath;
public ModelConfig infoCfg;
public List<TM2Format.Texture> textures = new();
public List<MDSConverter> mdsConverters = new();
public List<Error> errors = new();
public List<Message> messages = new();
public Context()
{
current = this;
}
}
+19 -9
View File
@@ -2,6 +2,16 @@ using System;
namespace dq8chr2glb.Logger; namespace dq8chr2glb.Logger;
public enum LogMode
{
ALL = 8, // show all debug info
DEBUG = 4, // show task name, .chr content and status with stacktrace
EXTEND = 2, // show task name, .chr content and status with general errors
MINIMAL = 1, // show task name and result status
NONE = 0, // squeaky clean console
}
[Flags]
public enum LogLevel public enum LogLevel
{ {
Debug, Debug,
@@ -14,8 +24,8 @@ public enum LogLevel
public static class Log public static class Log
{ {
// public const LogLevel LogLevel = Logger.LogLevel.Info; // public const LogLevel LogLevel = Logger.LogLevel.Info;
public static void Line(object data, LogLevel level = LogLevel.Debug) public static void Line(object? data, LogLevel level = LogLevel.Debug)
{ {
var lastColor = Console.ForegroundColor; var lastColor = Console.ForegroundColor;
var color = level switch var color = level switch
@@ -27,13 +37,13 @@ public static class Log
LogLevel.None => ConsoleColor.White, LogLevel.None => ConsoleColor.White,
}; };
if (level == LogLevel.Debug) // if (level == LogLevel.Debug)
{ // {
return; // return;
} // }
Console.ForegroundColor = color; Console.ForegroundColor = color;
Console.WriteLine(data.ToString()); Console.WriteLine(data != null ? data.ToString() : "");
Console.ForegroundColor = lastColor; Console.ForegroundColor = lastColor;
} }
@@ -43,8 +53,8 @@ public static class Log
Console.ForegroundColor = ConsoleColor.Red; Console.ForegroundColor = ConsoleColor.Red;
Console.Write($"[{level}] "); Console.Write($"[{level}] ");
Console.ForegroundColor = ConsoleColor.DarkRed; Console.ForegroundColor = ConsoleColor.DarkRed;
// Console.Write($"{e.Message}\n From:\n{e.Source}\nStacktrace:\n{e.StackTrace}\n"); Console.Write($"{e.Message}\n From:\n{e.Source}\nStacktrace:\n{e.StackTrace}\n");
Console.Write($"{e.Message}\n"); Console.Write($"{e.Message}\n");
Console.ForegroundColor = lastColor; Console.ForegroundColor = lastColor;
} }
} }