Files
dq8chr2glb/dq8chr2glb/ChrFile.cs
T
Boris Nikolaev 291babd1c0 fix codestyle
2026-05-10 17:05:25 +03:00

234 lines
6.5 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using dq8chr2glb.Container;
using dq8chr2glb.Converter;
using dq8chr2glb.Converter.GLTF;
using dq8chr2glb.Core.InfoCfg;
using dq8chr2glb.Core.MDSFormat;
using dq8chr2glb.Core.MOTFormat;
using dq8chr2glb.Logger;
using SixLabors.ImageSharp;
using Texture = dq8chr2glb.TM2Format.Texture;
namespace dq8chr2glb;
public class ChrFile
{
public bool Extract;
public bool Convert;
public bool TextFormat;
public void Process(string inputPath, string outputPath)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
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 = Container.ChrFile.FromBytes(chrData);
EnsurePath(ctx.OutputPath);
foreach (var file in container)
{
PrintTask(file);
switch (file.Extension)
{
case FileExtension.CFG:
ProcessConfig(file);
break;
case FileExtension.TEXT:
ProcessTextFile(file);
break;
case FileExtension.TM2:
ProcessTextures(file);
break;
case FileExtension.MDS:
ProcessMDSFile(file);
break;
case FileExtension.MOT:
ProcessMOTFile(file);
break;
default:
ProcessRawFile(file);
break;
}
}
if (Convert)
{
foreach (var converter in Context.Current.MdsConverters)
{
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)
{
var spaces = 30 - file.Name.Length;
if (spaces <= 0)
{
spaces = 1;
}
var spacer = new string('.', spaces);
Log.Line($" Process: {file.Name + spacer} {file.Data.Length} bytes");
}
private void EnsurePath(string path)
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
private void ProcessMOTFile(IncludedFile file)
{
if (Extract)
{
ProcessRawFile(file);
}
if (Convert)
{
foreach (var converter in Context.Current.MdsConverters)
{
var motImporter = new Importer();
var animation = motImporter.Import(file.Data);
converter.AddAnimation(animation, Context.Current.InfoCfg);
}
}
}
private void ProcessMDSFile(IncludedFile file)
{
if (Extract)
{
ProcessRawFile(file);
}
var mdsScene = Reader.Read(file.Data, file.Name);
if (mdsScene == null)
{
Context.Current.Errors.Add(new Error(file.Name, "mdsScene is empty!"));
return;
}
if (Convert)
{
var converter = new MDSConverter(file.Name);
var rootName = Path.GetFileNameWithoutExtension(file.Name);
converter.Convert(mdsScene, Context.Current.Textures, rootName);
Context.Current.MdsConverters.Add(converter);
}
}
private void ProcessConfig(IncludedFile file)
{
if (Extract)
{
var isSecond = Context.Current.InfoCfg != null;
if (isSecond)
{
file.Name = file.Name.Replace(".cfg", "_2.cfg");
}
ProcessTextFile(file);
}
var data = Encoding.GetEncoding("shift_jis").GetString(file.Data).TrimEnd('\0');
var configFile = new ConfigFile(data);
var info = configFile.ReadConfig();
if (Context.Current.InfoCfg == null)
{
Context.Current.InfoCfg = info;
}
}
private void ProcessTextFile(IncludedFile file)
{
try
{
var root = Path.GetDirectoryName(file.Name);
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 while process text file", e));
}
}
private void ProcessRawFile(IncludedFile file)
{
try
{
var root = Path.GetDirectoryName(file.Name);
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)
{
var root = Path.GetDirectoryName(file.Name);
var fileName = Path.GetFileNameWithoutExtension(file.Name);
var outputPath = Path.Combine(Context.Current.OutputPath, root);
var image = TM2Format.TM2Format.GetImage(file, fileName);
if (Extract && image != null && image.Data != null)
{
EnsurePath(outputPath);
image.Data.SaveAsPng(Path.Combine(outputPath, fileName + ".png"));
}
Context.Current.Textures.Add(image);
}
}