update
This commit is contained in:
parent
8965c9aacb
commit
ec42590b0e
@ -279,22 +279,17 @@ namespace EscudeTools
|
|||||||
}
|
}
|
||||||
private static bool CsvProcess(Sheet s, string path)
|
private static bool CsvProcess(Sheet s, string path)
|
||||||
{
|
{
|
||||||
//s是单张表,col存放标题(对应csv应该是标题),records存放数据(对应数据库中应该是数据)
|
|
||||||
if (string.IsNullOrEmpty(path))
|
if (string.IsNullOrEmpty(path))
|
||||||
throw new ArgumentException("File path cannot be null or empty.", nameof(path));
|
throw new ArgumentException("File path cannot be null or empty.", nameof(path));
|
||||||
|
|
||||||
// 创建一个StringBuilder来构建CSV内容
|
|
||||||
StringBuilder csvContent = new();
|
StringBuilder csvContent = new();
|
||||||
|
|
||||||
// 写入列标题
|
|
||||||
foreach (Column column in s.col)
|
foreach (Column column in s.col)
|
||||||
{
|
{
|
||||||
csvContent.Append(column.name);
|
csvContent.Append(column.name);
|
||||||
csvContent.Append(',');
|
csvContent.Append(',');
|
||||||
}
|
}
|
||||||
csvContent.AppendLine(); // 换行
|
csvContent.AppendLine();
|
||||||
|
|
||||||
// 写入记录数据
|
|
||||||
foreach (Record record in s.records.values.Cast<Record>())
|
foreach (Record record in s.records.values.Cast<Record>())
|
||||||
{
|
{
|
||||||
foreach (object value in record.values)
|
foreach (object value in record.values)
|
||||||
@ -302,10 +297,8 @@ namespace EscudeTools
|
|||||||
csvContent.Append(value);
|
csvContent.Append(value);
|
||||||
csvContent.Append(',');
|
csvContent.Append(',');
|
||||||
}
|
}
|
||||||
csvContent.AppendLine(); // 换行
|
csvContent.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将CSV内容写入文件
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File.WriteAllText(path, csvContent.ToString());
|
File.WriteAllText(path, csvContent.ToString());
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
namespace EscudeTools
|
using Microsoft.Data.Sqlite;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace EscudeTools
|
||||||
{
|
{
|
||||||
public class ScriptMessage
|
public class ScriptMessage
|
||||||
{
|
{
|
||||||
public byte[] Data { get; set; } // MESS領域 (消息区域)
|
public byte[] Data { get; set; } // MESS領域 (消息区域)
|
||||||
public uint Size { get; set; } // MESS領域サイズ (消息区域大小)
|
public uint Size { get; set; } // MESS領域サイズ (消息区域大小)
|
||||||
public uint[] Offset { get; set; } // MESSオフセット (消息偏移)
|
public List<uint> Offset { get; set; } // MESSオフセット (消息偏移)
|
||||||
public uint Count { get; set; } // MESS数 (消息数量)
|
public uint Count { get; set; } // MESS数 (消息数量)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,14 +30,315 @@
|
|||||||
{
|
{
|
||||||
static readonly byte[] MessHeader = [0x40, 0x6D, 0x65, 0x73, 0x73, 0x3A, 0x5F, 0x5F]; //@mess:__
|
static readonly byte[] MessHeader = [0x40, 0x6D, 0x65, 0x73, 0x73, 0x3A, 0x5F, 0x5F]; //@mess:__
|
||||||
static readonly byte[] FileHeader = [0x40, 0x63, 0x6F, 0x64, 0x65, 0x3A, 0x5F, 0x5F]; //@code:__
|
static readonly byte[] FileHeader = [0x40, 0x63, 0x6F, 0x64, 0x65, 0x3A, 0x5F, 0x5F]; //@code:__
|
||||||
|
private ScriptMessage sm;
|
||||||
|
private bool smEncrypted;
|
||||||
|
private string smName = string.Empty;
|
||||||
|
private ScriptFile sf;
|
||||||
|
private string sfName = string.Empty;
|
||||||
|
|
||||||
|
public ScriptMessage GetSM()
|
||||||
|
{
|
||||||
|
return sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScriptFile GetSF()
|
||||||
|
{
|
||||||
|
return sf;
|
||||||
|
}
|
||||||
|
|
||||||
public bool LoadScriptFile(string path)
|
public bool LoadScriptFile(string path)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
if (!File.Exists(path))
|
||||||
|
return false;
|
||||||
|
sf ??= new ScriptFile();
|
||||||
|
sfName = Path.GetFileNameWithoutExtension(path);
|
||||||
|
using FileStream fs = new(path, FileMode.Open);
|
||||||
|
using BinaryReader br = new(fs);
|
||||||
|
byte[] head = br.ReadBytes(8);
|
||||||
|
if (!head.SequenceEqual(FileHeader))
|
||||||
|
return false;
|
||||||
|
sf.CodeSize = ReadUInt32(br);
|
||||||
|
sf.TextCount = ReadUInt32(br);
|
||||||
|
sf.TextSize = ReadUInt32(br);
|
||||||
|
sf.MessCount = ReadUInt32(br);
|
||||||
|
|
||||||
|
if (fs.Length < sf.CodeSize + sf.TextSize + 16 + sf.TextCount * 4)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
sf.Code = br.ReadBytes((int)sf.CodeSize);
|
||||||
|
sf.TextOffset = new uint[sf.TextCount];
|
||||||
|
for (int i = 0; i < sf.TextCount; i++)
|
||||||
|
{
|
||||||
|
sf.TextOffset[i] = br.ReadUInt32();
|
||||||
|
}
|
||||||
|
sf.Text = br.ReadBytes((int)sf.TextSize);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint ReadUInt32(BinaryReader reader)
|
||||||
|
{
|
||||||
|
byte[] bytes = reader.ReadBytes(4);
|
||||||
|
if (bytes.Length < 4)
|
||||||
|
throw new EndOfStreamException("Unexpected end of stream while reading UInt32.");
|
||||||
|
return BitConverter.ToUInt32(bytes, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool LoadScriptMess(string path)
|
public bool LoadScriptMess(string path)
|
||||||
{
|
{
|
||||||
|
if (!File.Exists(path))
|
||||||
|
return false;
|
||||||
|
sm ??= new ScriptMessage();
|
||||||
|
smName = Path.GetFileNameWithoutExtension(path);
|
||||||
|
using FileStream fs = new(path, FileMode.Open);
|
||||||
|
using BinaryReader br = new(fs);
|
||||||
|
byte[] head = br.ReadBytes(8);
|
||||||
|
smEncrypted = head.SequenceEqual(MessHeader);
|
||||||
|
if (smEncrypted)
|
||||||
|
{
|
||||||
|
sm.Count = ReadUInt32(br);
|
||||||
|
sm.Size = ReadUInt32(br);
|
||||||
|
sm.Offset = [];
|
||||||
|
for (int i = 0; i < sm.Count; i++)
|
||||||
|
{
|
||||||
|
sm.Offset.Add(br.ReadUInt32());
|
||||||
|
}
|
||||||
|
byte[] encryptData = br.ReadBytes((int)sm.Size);
|
||||||
|
for (int i = 0; i <= encryptData.Length; i++)
|
||||||
|
{
|
||||||
|
encryptData[i] ^= 0x55;
|
||||||
|
}
|
||||||
|
sm.Data = encryptData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fs.Position = 0;
|
||||||
|
sm.Count = 0;
|
||||||
|
sm.Size = (uint)fs.Length;
|
||||||
|
sm.Data = br.ReadBytes((int)sm.Size);
|
||||||
|
sm.Offset = [];
|
||||||
|
uint offset = 0;
|
||||||
|
for (uint i = 0; i < sm.Size; i++)
|
||||||
|
{
|
||||||
|
if (ISKANJI(sm.Data[i]))
|
||||||
|
i++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (sm.Data[i] == '\r')
|
||||||
|
{
|
||||||
|
if (sm.Data[i + 1] != '\n')
|
||||||
|
{
|
||||||
|
sm.Data[i] = (byte)'\n';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sm.Data[i++] = (byte)'\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sm.Data[i] == '\n')
|
||||||
|
{
|
||||||
|
sm.Data[i] = (byte)'\0';
|
||||||
|
if (sm.Count < 4096)
|
||||||
|
{
|
||||||
|
sm.Offset.Add(offset);
|
||||||
|
}
|
||||||
|
sm.Count++;
|
||||||
|
offset = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool ISKANJI(byte x)
|
||||||
|
{
|
||||||
|
return (((x) ^ 0x20) - 0xa1) <= 0x3b;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ExtractEmbeddedDatabase(string outputPath)
|
||||||
|
{
|
||||||
|
if (File.Exists(outputPath))
|
||||||
|
{
|
||||||
|
Console.WriteLine($"File {outputPath} already exists. Do you want to overwrite it? (y/n)");
|
||||||
|
string? input = Console.ReadLine();
|
||||||
|
if (input?.ToLower() != "y")
|
||||||
|
{
|
||||||
|
Console.WriteLine("Task cancelled, Exporting database aborted.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
|
string resourceName = "EscudeTools.empty.db";
|
||||||
|
using Stream stream = assembly.GetManifestResourceStream(resourceName) ?? throw new Exception($"Error, No resource with name {resourceName} found.");
|
||||||
|
using FileStream fileStream = new(outputPath, FileMode.Create, FileAccess.Write);
|
||||||
|
stream.CopyTo(fileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ExportDatabase(int outputType, string? storePath)
|
||||||
|
{
|
||||||
|
storePath ??= Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? throw new InvalidOperationException("Unable to determine the directory."); //导出位置
|
||||||
|
throw new NotImplementedException();
|
||||||
|
//switch (outputType)
|
||||||
|
//{
|
||||||
|
// case 0: //sf
|
||||||
|
// if (string.IsNullOrEmpty(sfName))
|
||||||
|
// return false;
|
||||||
|
// ExtractEmbeddedDatabase(Path.Combine(storePath, sfName + ".db"));
|
||||||
|
// return SqliteProcess(sf, Path.Combine(storePath, sfName + ".db"));
|
||||||
|
// case 1: //sm
|
||||||
|
// if (string.IsNullOrEmpty(smName))
|
||||||
|
// return false;
|
||||||
|
// ExtractEmbeddedDatabase(Path.Combine(storePath, smName + ".db"));
|
||||||
|
// return SqliteProcess(sm, Path.Combine(storePath, smName + ".db"));
|
||||||
|
// default:
|
||||||
|
// throw new NotSupportedException("Unsupported output type.");
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
//private bool SqliteProcess(ScriptMessage sm, string path)
|
||||||
|
//{
|
||||||
|
// using SqliteConnection connection = new($"Data Source={path};");
|
||||||
|
// connection.Open();
|
||||||
|
|
||||||
|
// using (SqliteCommand createTableCommand = connection.CreateCommand())
|
||||||
|
// {
|
||||||
|
// StringBuilder createTableQuery = new();
|
||||||
|
// createTableQuery.Append($"CREATE TABLE IF NOT EXISTS {smName} (");
|
||||||
|
|
||||||
|
// // Add columns to the create table query
|
||||||
|
// foreach (var column in sheet.col)
|
||||||
|
// {
|
||||||
|
// createTableQuery.Append($"{column.name} {GetSQLiteColumnType(column.type)}, ");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// createTableQuery.Remove(createTableQuery.Length - 2, 2); // Remove the last comma and space
|
||||||
|
// createTableQuery.Append(");");
|
||||||
|
|
||||||
|
// createTableCommand.CommandText = createTableQuery.ToString();
|
||||||
|
// createTableCommand.ExecuteNonQuery();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// using SqliteCommand insertDataCommand = connection.CreateCommand();
|
||||||
|
// StringBuilder insertDataQuery = new();
|
||||||
|
// insertDataQuery.Append($"INSERT INTO {sheet.name} (");
|
||||||
|
|
||||||
|
// // Add column names to the insert data query
|
||||||
|
// foreach (var column in sheet.col)
|
||||||
|
// {
|
||||||
|
// insertDataQuery.Append($"{column.name}, ");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// insertDataQuery.Remove(insertDataQuery.Length - 2, 2); // Remove the last comma and space
|
||||||
|
// insertDataQuery.Append(") VALUES (");
|
||||||
|
|
||||||
|
// // Add parameter placeholders to the insert data query
|
||||||
|
// for (int i = 0; i < sheet.cols; i++)
|
||||||
|
// {
|
||||||
|
// insertDataQuery.Append($"@param{i}, ");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// insertDataQuery.Remove(insertDataQuery.Length - 2, 2); // Remove the last comma and space
|
||||||
|
// insertDataQuery.Append(");");
|
||||||
|
|
||||||
|
// insertDataCommand.CommandText = insertDataQuery.ToString();
|
||||||
|
|
||||||
|
// // Add data parameters to the insert data command
|
||||||
|
// for (int i = 0; i < sheet.records.values.Length; i++)
|
||||||
|
// {
|
||||||
|
// var record = (Record)sheet.records.values[i];
|
||||||
|
// for (int j = 0; j < sheet.cols; j++)
|
||||||
|
// {
|
||||||
|
// var parameter = new SqliteParameter($"@param{j}", record.values[j]);
|
||||||
|
// insertDataCommand.Parameters.Add(parameter);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// insertDataCommand.ExecuteNonQuery();
|
||||||
|
// insertDataCommand.Parameters.Clear();
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//private bool SqliteProcess(ScriptFile sf, string path)
|
||||||
|
//{
|
||||||
|
// //db含有多个sheet,每个sheet中col存放标题(对应数据库中应该是字段),records存放数据(对应数据库中应该是记录)
|
||||||
|
// using SqliteConnection connection = new($"Data Source={path};");
|
||||||
|
// connection.Open();
|
||||||
|
|
||||||
|
// foreach (var sheet in db)
|
||||||
|
// {
|
||||||
|
// using (SqliteCommand createTableCommand = connection.CreateCommand())
|
||||||
|
// {
|
||||||
|
// StringBuilder createTableQuery = new();
|
||||||
|
// createTableQuery.Append($"CREATE TABLE IF NOT EXISTS {sheet.name} (");
|
||||||
|
|
||||||
|
// // Add columns to the create table query
|
||||||
|
// foreach (var column in sheet.col)
|
||||||
|
// {
|
||||||
|
// createTableQuery.Append($"{column.name} {GetSQLiteColumnType(column.type)}, ");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// createTableQuery.Remove(createTableQuery.Length - 2, 2); // Remove the last comma and space
|
||||||
|
// createTableQuery.Append(");");
|
||||||
|
|
||||||
|
// createTableCommand.CommandText = createTableQuery.ToString();
|
||||||
|
// createTableCommand.ExecuteNonQuery();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// using SqliteCommand insertDataCommand = connection.CreateCommand();
|
||||||
|
// StringBuilder insertDataQuery = new();
|
||||||
|
// insertDataQuery.Append($"INSERT INTO {sheet.name} (");
|
||||||
|
|
||||||
|
// // Add column names to the insert data query
|
||||||
|
// foreach (var column in sheet.col)
|
||||||
|
// {
|
||||||
|
// insertDataQuery.Append($"{column.name}, ");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// insertDataQuery.Remove(insertDataQuery.Length - 2, 2); // Remove the last comma and space
|
||||||
|
// insertDataQuery.Append(") VALUES (");
|
||||||
|
|
||||||
|
// // Add parameter placeholders to the insert data query
|
||||||
|
// for (int i = 0; i < sheet.cols; i++)
|
||||||
|
// {
|
||||||
|
// insertDataQuery.Append($"@param{i}, ");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// insertDataQuery.Remove(insertDataQuery.Length - 2, 2); // Remove the last comma and space
|
||||||
|
// insertDataQuery.Append(");");
|
||||||
|
|
||||||
|
// insertDataCommand.CommandText = insertDataQuery.ToString();
|
||||||
|
|
||||||
|
// // Add data parameters to the insert data command
|
||||||
|
// for (int i = 0; i < sheet.records.values.Length; i++)
|
||||||
|
// {
|
||||||
|
// var record = (Record)sheet.records.values[i];
|
||||||
|
// for (int j = 0; j < sheet.cols; j++)
|
||||||
|
// {
|
||||||
|
// var parameter = new SqliteParameter($"@param{j}", record.values[j]);
|
||||||
|
// insertDataCommand.Parameters.Add(parameter);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// insertDataCommand.ExecuteNonQuery();
|
||||||
|
// insertDataCommand.Parameters.Clear();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
//}
|
||||||
|
|
||||||
|
private static string GetSQLiteColumnType(ushort type)
|
||||||
|
{
|
||||||
|
return type switch
|
||||||
|
{
|
||||||
|
// int
|
||||||
|
0x1 => "INTEGER",
|
||||||
|
// float
|
||||||
|
0x2 => "REAL",
|
||||||
|
// string
|
||||||
|
0x3 => "TEXT",
|
||||||
|
// bool
|
||||||
|
0x4 => "INTEGER",
|
||||||
|
_ => throw new NotSupportedException($"Unsupported column type: {type}"),
|
||||||
|
};
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user