ScriptFile(.bin)支持仅导出text
剩余部分以.bat形式存储
This commit is contained in:
parent
6516dbde44
commit
5d23d7d09f
@ -1,4 +1,4 @@
|
||||
//以下是垃圾代码,仅供参考
|
||||
//以下是垃圾代码,闲人勿入
|
||||
namespace EscudeTools
|
||||
{
|
||||
public static class Define
|
||||
@ -19,7 +19,7 @@ namespace EscudeTools
|
||||
"proc_bgv_fx", "proc_set_param", "proc_get_param", "proc_jump", "proc_date", "proc_flow", "proc_diary",
|
||||
"proc_unlock", "proc_section", "proc_omake"
|
||||
];
|
||||
|
||||
// 说句实话,我觉得这些定义可能会发生变化
|
||||
public const byte INST_POP = 1;
|
||||
public const byte INST_POP_N = 2;
|
||||
public const byte INST_POP_RET = 3;
|
||||
@ -151,7 +151,7 @@ namespace EscudeTools
|
||||
|
||||
case INST_POP_N:
|
||||
{
|
||||
Mark(sf, (uint)c.Parameter);
|
||||
Mark(sf, BitConverter.ToUInt32(c.Parameter));
|
||||
return $"Pop multiple values";
|
||||
}
|
||||
case INST_POP_RET:
|
||||
@ -163,7 +163,7 @@ namespace EscudeTools
|
||||
case INST_PUSH_RET:
|
||||
return $"Push the return value";
|
||||
case INST_PUSH_TEXT:
|
||||
return $"Push a string: {sf.TextString[(uint)c.Parameter]}";
|
||||
return $"Push a string: {sf.TextString[BitConverter.ToUInt32(c.Parameter)]}";
|
||||
case INST_PUSH_MESS:
|
||||
{
|
||||
messIndex++;
|
||||
@ -186,7 +186,7 @@ namespace EscudeTools
|
||||
case INST_JMPZ:
|
||||
return $"Conditional jump";
|
||||
case INST_CALL:
|
||||
return $"Call function offset: {(uint)c.Parameter + 1}";
|
||||
return $"Call function offset: {BitConverter.ToUInt32(c.Parameter) + 1}";
|
||||
case INST_RET:
|
||||
return $"Return";
|
||||
case INST_LOG_OR:
|
||||
@ -240,7 +240,7 @@ namespace EscudeTools
|
||||
case INST_LINE:
|
||||
return $"File line number";
|
||||
case INST_PROC:
|
||||
uint index = (uint)c.Parameter;
|
||||
uint index = BitConverter.ToUInt32(c.Parameter);
|
||||
return $"Execute built-in function: {ProcNames[index]} {SetExtStr(c, sf)}";
|
||||
case INST_TEXT:
|
||||
messIndex++;
|
||||
@ -264,7 +264,7 @@ namespace EscudeTools
|
||||
|
||||
private static string SetExtStr(Command c, ScriptFile sf)
|
||||
{
|
||||
switch ((uint)c.Parameter)
|
||||
switch (BitConverter.ToUInt32(c.Parameter))
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
|
@ -4,8 +4,11 @@
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// NOTE
|
||||
// 推荐使用DB Browser for SQLite (https://sqlitebrowser.org/) 查看、编辑导出的数据库文件
|
||||
// 这不是广告,这只是我在开发期间使用的工具
|
||||
|
||||
////Batch Unpack
|
||||
////Batch Unpack ESC-ARC Package
|
||||
//if (Directory.Exists(args[0]))
|
||||
//{
|
||||
// string[] files = Directory.GetFiles(args[0], "*.bin");
|
||||
@ -30,64 +33,66 @@
|
||||
// }
|
||||
//}
|
||||
|
||||
if (Directory.Exists(args[0]) && Directory.Exists(args[1]))
|
||||
////Batch Repack ESC-ARC Package
|
||||
//if (Directory.Exists(args[0]) && Directory.Exists(args[1]))
|
||||
//{
|
||||
// string[] directories = Directory.GetDirectories(args[0]);
|
||||
// foreach (string directory in directories)
|
||||
// {
|
||||
// PackManager pm = new();
|
||||
// string providerFilePath = Path.Combine(args[1], Path.GetFileName(directory) + ".bin");
|
||||
// if (pm.Repack(directory, 2,true, providerFilePath))
|
||||
// Console.WriteLine("Repack Package Success");
|
||||
// else
|
||||
// {
|
||||
// Console.WriteLine("Repack Package Failed");
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
//Batch Unpack Script(Full, Text, Mess)
|
||||
if (Directory.Exists(args[0]))
|
||||
{
|
||||
string[] directories = Directory.GetDirectories(args[0]);
|
||||
foreach (string directory in directories)
|
||||
string[] files = Directory.GetFiles(args[0], "*.bin");
|
||||
foreach (string file in files)
|
||||
{
|
||||
PackManager pm = new();
|
||||
string providerFilePath = Path.Combine(args[1], Path.GetFileName(directory) + ".bin");
|
||||
if (pm.Repack(directory, 2,true, providerFilePath))
|
||||
Console.WriteLine("Export Database Success");
|
||||
ScriptManager smr = new();
|
||||
if (smr.LoadScriptFile(file))
|
||||
{
|
||||
Console.WriteLine($"Load {file} Success");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Export Database Failed");
|
||||
Console.WriteLine($"Load {file} Failed");
|
||||
return;
|
||||
}
|
||||
if (smr.ExportDatabase(Path.GetDirectoryName(args[0])))
|
||||
Console.WriteLine("Export Script Success");
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Export Script Failed");
|
||||
return;
|
||||
}
|
||||
if (smr.ExportTextDatabase(Path.GetDirectoryName(args[0])))
|
||||
Console.WriteLine("Export Text Success");
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Export Text Failed");
|
||||
return;
|
||||
}
|
||||
if (smr.ExportMessDatabase(Path.GetDirectoryName(args[0])))
|
||||
Console.WriteLine("Export Mess Success");
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Export Mess Failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//if (Directory.Exists(args[0]))
|
||||
//{
|
||||
// string[] files = Directory.GetFiles(args[0], "*.bin");
|
||||
// foreach (string file in files)
|
||||
// {
|
||||
// ScriptManager smr = new();
|
||||
// //目前不支持二次加载
|
||||
// //Todo
|
||||
// //修复
|
||||
// if (smr.LoadScriptFile(file))
|
||||
// {
|
||||
// Console.WriteLine($"Load {file} Success");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Console.WriteLine($"Load {file} Failed");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if (smr.ExportDatabase(Path.GetDirectoryName(args[0])))
|
||||
// Console.WriteLine("Export Database Success");
|
||||
// else
|
||||
// {
|
||||
// Console.WriteLine("Export Database Failed");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if (smr.ExportMessDatabase(Path.GetDirectoryName(args[0])))
|
||||
// Console.WriteLine("Export Mess Database Success");
|
||||
// else
|
||||
// {
|
||||
// Console.WriteLine("Export Mess Database Failed");
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
|
||||
//ScriptManager smr = new();
|
||||
//smr.LoadScriptFile(args[0]); //加载.bin文件
|
||||
//smr.ExportDatabase(Path.GetDirectoryName(args[0]));
|
||||
|
@ -2,7 +2,7 @@
|
||||
"profiles": {
|
||||
"EscudeTools": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "G:\\x221.local\\lab\\unpack_pack\\orgin\\output\r\nG:\\x221.local\\lab\\unpack_pack\\1"
|
||||
"commandLineArgs": "G:\\x221.local\\lab\\test1\\script"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using Microsoft.Data.Sqlite;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
|
||||
namespace EscudeTools
|
||||
@ -32,7 +33,7 @@ namespace EscudeTools
|
||||
public uint Offset { get; set; }
|
||||
public byte Instruction { get; set; }
|
||||
public string InstructionString { get; set; }
|
||||
public Object Parameter { get; set; }
|
||||
public byte[] Parameter { get; set; }
|
||||
public String Helper { get; set; }
|
||||
public bool IsProcSet { get; set; }
|
||||
}
|
||||
@ -46,7 +47,6 @@ namespace EscudeTools
|
||||
private string name = string.Empty;
|
||||
private ScriptFile sf;
|
||||
private int messIndex = 0;
|
||||
private bool enableCommandHelper = true;
|
||||
|
||||
public ScriptMessage GetSM()
|
||||
{
|
||||
@ -58,12 +58,6 @@ namespace EscudeTools
|
||||
return sf;
|
||||
}
|
||||
|
||||
public bool ToggleCommandHelper()
|
||||
{
|
||||
enableCommandHelper = !enableCommandHelper;
|
||||
return enableCommandHelper;
|
||||
}
|
||||
|
||||
public bool LoadScriptFile(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
@ -106,19 +100,17 @@ namespace EscudeTools
|
||||
{
|
||||
Instruction = sf.Code[i++],
|
||||
Offset = (uint)i,
|
||||
IsProcSet = false
|
||||
IsProcSet = false,
|
||||
};
|
||||
if (enableCommandHelper)
|
||||
{
|
||||
c.InstructionString = Define.GetInstructionString(c.Instruction, out int paramNum);
|
||||
for (int j = 0; j < paramNum; j++)
|
||||
if (paramNum > 0)
|
||||
{
|
||||
c.Parameter = Define.TyperHelper(c.Instruction, sf.Code, i);
|
||||
i += 4;
|
||||
c.Parameter = new byte[paramNum*4];
|
||||
Buffer.BlockCopy(sf.Code, i, c.Parameter, 0, 4 * paramNum);
|
||||
i += 4 * paramNum;
|
||||
}
|
||||
if (sm != null)
|
||||
c.Helper = Define.SetCommandStr(c, sf, sm, ref messIndex);
|
||||
}
|
||||
sf.Commands.Add(c);
|
||||
}
|
||||
return true;
|
||||
@ -195,7 +187,8 @@ namespace EscudeTools
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ExportDatabase(string? storePath)
|
||||
//此导出功能导出的sqlite数据库
|
||||
public bool ExportDatabase(string storePath)
|
||||
{
|
||||
if (sf.Code == null)
|
||||
return false;
|
||||
@ -208,7 +201,8 @@ namespace EscudeTools
|
||||
return SqliteProcess(sf, targetPath);
|
||||
}
|
||||
|
||||
public bool ExportMessDatabase(string? storePath)
|
||||
//从ScriptMessage中导出游戏文本
|
||||
public bool ExportMessDatabase(string storePath)
|
||||
{
|
||||
if (sf == null)
|
||||
return false;
|
||||
@ -223,6 +217,37 @@ namespace EscudeTools
|
||||
return SqliteProcess(sm, targetPath);
|
||||
}
|
||||
|
||||
//从ScriptFile中导出Text部分,剩余指令部分导出至.dat文件,以便重新封包
|
||||
public bool ExportTextDatabase(string storePath)
|
||||
{
|
||||
if (sf == null)
|
||||
return false;
|
||||
//分成两个文件,一个是放text的sqlite数据库,一个是放code的dat文件
|
||||
|
||||
//dat
|
||||
string datPath = Path.Combine(storePath, name + ".dat");
|
||||
if (File.Exists(datPath))
|
||||
return false;
|
||||
using FileStream fs = new(datPath, FileMode.Create);
|
||||
using BinaryWriter bw = new(fs);
|
||||
bw.Write(FileHeader);//文件头
|
||||
bw.Write(sf.CodeSize);//代码区大小
|
||||
bw.Write(sf.TextCount);//文本数量
|
||||
byte[] empty4B = new byte[4];
|
||||
bw.Write(empty4B);//文本大小(占位)
|
||||
bw.Write(sf.MessCount);//消息数量
|
||||
bw.Write(sf.Code);//代码区
|
||||
|
||||
//sqlite
|
||||
storePath ??= Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? throw new InvalidOperationException("Unable to determine the directory.");
|
||||
if (string.IsNullOrEmpty(name))
|
||||
return false;
|
||||
string targetPath = Path.Combine(storePath, "script_text.db");
|
||||
if (!File.Exists(targetPath))
|
||||
Utils.ExtractEmbeddedDatabase(targetPath);
|
||||
return SqliteProcess(sf.TextString, targetPath);
|
||||
}
|
||||
|
||||
private bool SqliteProcess(ScriptFile sf, string path)
|
||||
{
|
||||
using SqliteConnection connection = new($"Data Source={path};");
|
||||
@ -240,7 +265,7 @@ namespace EscudeTools
|
||||
Offset INTEGER,
|
||||
Instruction INTEGER,
|
||||
InstructionString TEXT,
|
||||
Parameter TEXT,
|
||||
Parameter BLOB,
|
||||
Helper TEXT
|
||||
);";
|
||||
using (var createTableCmd = new SqliteCommand(createTableQuery, connection))
|
||||
@ -259,7 +284,9 @@ namespace EscudeTools
|
||||
insertCmd.Parameters.AddWithValue("@Offset", command.Offset);
|
||||
insertCmd.Parameters.AddWithValue("@Instruction", command.Instruction);
|
||||
insertCmd.Parameters.AddWithValue("@InstructionString", command.InstructionString);
|
||||
insertCmd.Parameters.AddWithValue("@Parameter", command.Parameter ?? "");
|
||||
insertCmd.Parameters.AddWithValue("@Parameter", (command.Parameter == null)
|
||||
? DBNull.Value
|
||||
: command.Parameter);
|
||||
insertCmd.Parameters.AddWithValue("@Helper", command.Helper ?? "");
|
||||
|
||||
insertCmd.ExecuteNonQuery();
|
||||
@ -305,5 +332,57 @@ namespace EscudeTools
|
||||
transaction.Commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool SqliteProcess(string[] ts,string path)
|
||||
{
|
||||
using SqliteConnection connection = new($"Data Source={path};");
|
||||
connection.Open();
|
||||
|
||||
string checkTableExistsQuery = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{name}';";
|
||||
using (var checkTableCmd = new SqliteCommand(checkTableExistsQuery, connection))
|
||||
{
|
||||
var result = checkTableCmd.ExecuteScalar();
|
||||
if (result != null) return true;
|
||||
}
|
||||
|
||||
string createTableQuery = $@"
|
||||
CREATE TABLE {name} (
|
||||
Text TEXT
|
||||
);";
|
||||
using (var createTableCmd = new SqliteCommand(createTableQuery, connection))
|
||||
{
|
||||
createTableCmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
string insertQuery = $"INSERT INTO {name} (Text) VALUES (@Text);";
|
||||
|
||||
using var transaction = connection.BeginTransaction();
|
||||
using var insertCmd = new SqliteCommand(insertQuery, connection, transaction);
|
||||
|
||||
foreach (var t in ts)
|
||||
{
|
||||
insertCmd.Parameters.Clear();
|
||||
insertCmd.Parameters.AddWithValue("@Text", t ?? "");
|
||||
insertCmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Repackv1()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool Repackv2()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool Repackv3()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user