This commit is contained in:
Chenx221 2024-10-27 13:37:38 +08:00
parent 3adf8c207a
commit ea52c2128b
Signed by: chenx221
GPG Key ID: D7A9EC07024C3021
5 changed files with 734 additions and 587 deletions

View File

@ -170,7 +170,7 @@ namespace EscudeTools
// Add columns to the create table query // Add columns to the create table query
foreach (var column in sheet.col) foreach (var column in sheet.col)
{ {
createTableQuery.Append($"{column.name} {Utils.GetSQLiteColumnType(column.type, column.size)}, "); createTableQuery.Append($"{column.name} {Utils.GetSQLiteColumnType(column.type)}, ");
} }
createTableQuery.Remove(createTableQuery.Length - 2, 2); // Remove the last comma and space createTableQuery.Remove(createTableQuery.Length - 2, 2); // Remove the last comma and space

View File

@ -114,9 +114,8 @@ namespace EscudeTools
{ {
static readonly byte[] lsfFileSignature = [0x4C, 0x53, 0x46, 0x00]; static readonly byte[] lsfFileSignature = [0x4C, 0x53, 0x46, 0x00];
static readonly byte[] lsfLayerSkipSignature = [0x00, 0x75, 0x6C, 0x00]; //flowchat部分的lsf块 static readonly byte[] lsfLayerSkipSignature = [0x00, 0x75, 0x6C, 0x00]; //flowchat部分的lsf块
private static string WorkPath = string.Empty;
private LsfData lsfData = new(); private LsfData lsfData = new();
private Dictionary<string, LsfData> lsfDataLookup = new(); private Dictionary<string, LsfData> lsfDataLookup = [];
private bool preFetchInfo; private bool preFetchInfo;
@ -158,7 +157,7 @@ namespace EscudeTools
return lsfData; // 如果未找到,则返回 null return lsfData; // 如果未找到,则返回 null
} }
private LsfFileHeader LoadLsfHeader(string path) private static LsfFileHeader LoadLsfHeader(string path)
{ {
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read); using var fs = new FileStream(path, FileMode.Open, FileAccess.Read);
if (fs.Length < 0x1C) if (fs.Length < 0x1C)

View File

@ -226,7 +226,7 @@ namespace EscudeTools
return true; return true;
} }
private void LzwDecode(List<LzwEntry> lzwManifest, string output) private static void LzwDecode(List<LzwEntry> lzwManifest, string output)
{ {
foreach (var i in lzwManifest) foreach (var i in lzwManifest)
{ {
@ -244,19 +244,13 @@ namespace EscudeTools
} }
} }
internal sealed class LzwDecoder : IDisposable internal sealed class LzwDecoder(Stream input, int unpacked_size) : IDisposable
{ {
private MsbBitStream m_input; private MsbBitStream m_input = new(input, true);
private byte[] m_output; private byte[] m_output = new byte[unpacked_size];
public byte[] Output { get { return m_output; } } public byte[] Output { get { return m_output; } }
public LzwDecoder(Stream input, int unpacked_size)
{
m_input = new MsbBitStream(input, true);
m_output = new byte[unpacked_size];
}
public void Unpack() public void Unpack()
{ {
int dst = 0; int dst = 0;
@ -320,9 +314,9 @@ namespace EscudeTools
#endregion #endregion
} }
public bool Repack(string path, int version, bool useCustomKey = false, string customKeyProviderPath = "") //目前支持v2v1 public bool Repack(string path, int version, string customKeyProviderPath = "") //目前支持v2v1
{ {
if (useCustomKey) if (customKeyProviderPath!="")
LoadKey(customKeyProviderPath); LoadKey(customKeyProviderPath);
ReadPItem(path); ReadPItem(path);
List<LzwEntry> lzwManifest = []; List<LzwEntry> lzwManifest = [];
@ -330,78 +324,76 @@ namespace EscudeTools
lzwManifest = JsonSerializer.Deserialize<List<LzwEntry>>(File.ReadAllText(Path.Combine(path, "lzwManifest.json"))) ?? []; lzwManifest = JsonSerializer.Deserialize<List<LzwEntry>>(File.ReadAllText(Path.Combine(path, "lzwManifest.json"))) ?? [];
m_seed = isLoaded ? LoadedKey : 2210579460; m_seed = isLoaded ? LoadedKey : 2210579460;
string outputPath = Path.Combine(Path.GetDirectoryName(path), Path.GetFileName(path) + ".bin"); string outputPath = Path.Combine(Path.GetDirectoryName(path), Path.GetFileName(path) + ".bin");
using (FileStream fs = new(outputPath, FileMode.Create)) using FileStream fs = new(outputPath, FileMode.Create);
using (BinaryWriter bw = new(fs)) using BinaryWriter bw = new(fs);
bw.Write(fileSignature);
bw.Write(supportPackVersion[version - 1]);
bw.Write(m_seed);
m_count = (uint)pItem.Count;
bw.Write(m_count ^ NextKey());
EncodingProvider provider = CodePagesEncodingProvider.Instance;
Encoding? shiftJis = provider.GetEncoding("shift-jis");
if (version == 1) //未经测试
{ {
bw.Write(fileSignature); long storeOffset = 0x10 + m_count * 0x88;
bw.Write(supportPackVersion[version - 1]); for (int i = 0; i < m_count; i++)
bw.Write(m_seed);
m_count = (uint)pItem.Count;
bw.Write(m_count ^ NextKey());
EncodingProvider provider = CodePagesEncodingProvider.Instance;
Encoding? shiftJis = provider.GetEncoding("shift-jis");
if (version == 1) //未经测试
{ {
long storeOffset = 0x10 + m_count * 0x88; byte[] strbytes = shiftJis.GetBytes(pItem[i].Name);
for (int i = 0; i < m_count; i++) byte[] result = new byte[80];
{ int lengthToCopy = Math.Min(strbytes.Length, 78);
byte[] strbytes = shiftJis.GetBytes(pItem[i].Name); Array.Copy(strbytes, result, lengthToCopy);
byte[] result = new byte[80]; bw.Write(result);
int lengthToCopy = Math.Min(strbytes.Length, 78); bw.Write(storeOffset);
Array.Copy(strbytes, result, lengthToCopy); uint size = pItem[i].Size;
bw.Write(result); if (Utils.SearchLzwEntryList(lzwManifest, pItem[i].Name) != -1)
bw.Write(storeOffset); size = (uint)FakeCompress(File.ReadAllBytes(Path.Combine(path, pItem[i].Name))).Length;
uint size = pItem[i].Size; bw.Write(size);
if (Utils.searchLzwEntryList(lzwManifest, pItem[i].Name) != -1) storeOffset += size;
size = (uint)FakeCompress(File.ReadAllBytes(Path.Combine(path, pItem[i].Name))).Length;
bw.Write(size);
storeOffset += size;
}
} }
else }
else
{
uint namesSize = (uint)pItem.Sum(e => e.Name.Length + 1);
bw.Write(namesSize ^ NextKey());
uint filenameOffset = 0;
long storeOffset = 0x14 + m_count * 12 + namesSize;
byte[] index = new byte[m_count * 12];
int indexOffset = 0;
for (int i = 0; i < m_count; i++)
{ {
uint namesSize = (uint)pItem.Sum(e => e.Name.Length + 1); BitConverter.GetBytes(filenameOffset).CopyTo(index, indexOffset);
bw.Write(namesSize ^ NextKey()); indexOffset += 4;
uint filenameOffset = 0; BitConverter.GetBytes(storeOffset).CopyTo(index, indexOffset);
long storeOffset = 0x14 + m_count * 12 + namesSize; indexOffset += 4;
byte[] index = new byte[m_count * 12]; uint size = pItem[i].Size;
int indexOffset = 0; if (Utils.SearchLzwEntryList(lzwManifest, pItem[i].Name) != -1)
for (int i = 0; i < m_count; i++) size = (uint)FakeCompress(File.ReadAllBytes(Path.Combine(path, pItem[i].Name))).Length;
{ BitConverter.GetBytes(size).CopyTo(index, indexOffset);
BitConverter.GetBytes(filenameOffset).CopyTo(index, indexOffset); indexOffset += 4;
indexOffset += 4; filenameOffset += (uint)pItem[i].Name.Length + 1;
BitConverter.GetBytes(storeOffset).CopyTo(index, indexOffset); storeOffset += size;
indexOffset += 4;
uint size = pItem[i].Size;
if (Utils.searchLzwEntryList(lzwManifest, pItem[i].Name) != -1)
size = (uint)FakeCompress(File.ReadAllBytes(Path.Combine(path, pItem[i].Name))).Length;
BitConverter.GetBytes(size).CopyTo(index, indexOffset);
indexOffset += 4;
filenameOffset += (uint)pItem[i].Name.Length + 1;
storeOffset += size;
}
Decrypt(ref index);
bw.Write(index);
foreach (Entry entry in pItem)
{
byte[] nameBytes = shiftJis.GetBytes(entry.Name);
bw.Write(nameBytes);
bw.Write((byte)0);
}
} }
Decrypt(ref index);
bw.Write(index);
foreach (Entry entry in pItem) foreach (Entry entry in pItem)
{ {
byte[] data; byte[] nameBytes = shiftJis.GetBytes(entry.Name);
if (Utils.searchLzwEntryList(lzwManifest, entry.Name) != -1) bw.Write(nameBytes);
data = FakeCompress(File.ReadAllBytes(Path.Combine(path, entry.Name))); bw.Write((byte)0);
else
data = File.ReadAllBytes(Path.Combine(path, entry.Name));
bw.Write(data);
} }
} }
foreach (Entry entry in pItem)
{
byte[] data;
if (Utils.SearchLzwEntryList(lzwManifest, entry.Name) != -1)
data = FakeCompress(File.ReadAllBytes(Path.Combine(path, entry.Name)));
else
data = File.ReadAllBytes(Path.Combine(path, entry.Name));
bw.Write(data);
}
return true; return true;
} }
@ -437,29 +429,27 @@ namespace EscudeTools
//不压其实也没事 //不压其实也没事
public static byte[] FakeCompress(byte[] Data) public static byte[] FakeCompress(byte[] Data)
{ {
using (MemoryStream Stream = new()) using MemoryStream Stream = new();
{ byte[] Buffer = new byte[4];
byte[] Buffer = new byte[4]; ((uint)Utils.Reverse((uint)Data.Length)).WriteTo(Buffer, 0);
((uint)Utils.Reverse((uint)Data.Length)).WriteTo(Buffer, 0); Stream.WriteCString("acp");
Stream.WriteCString("acp"); Stream.Write(Buffer, 0, Buffer.Length);
Stream.Write(Buffer, 0, Buffer.Length);
BitWriter Writer = new(Stream); BitWriter Writer = new(Stream);
for (int i = 0; i < Data.Length; i++) for (int i = 0; i < Data.Length; i++)
{
if (i > 0 && (i % 0x4000) == 0)
{ {
if (i > 0 && (i % 0x4000) == 0) Writer.PutBit(true);
{ Writer.PutBits(2);
Writer.PutBit(true);
Writer.PutBits(2);
}
Writer.PutBit(false);
Writer.PutBits(Data[i]);
} }
Writer.PutBit(true); Writer.PutBit(false);
Writer.PutBits(0); Writer.PutBits(Data[i]);
Writer.Flush();
return Stream.ToArray();
} }
Writer.PutBit(true);
Writer.PutBits(0);
Writer.Flush();
return Stream.ToArray();
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -105,7 +105,7 @@ namespace EscudeTools
stream.CopyTo(fileStream); stream.CopyTo(fileStream);
} }
public static string GetSQLiteColumnType(ushort type, uint size) public static string GetSQLiteColumnType(ushort type)
{ {
if (type == 1) if (type == 1)
return "INTEGER"; return "INTEGER";
@ -197,37 +197,26 @@ namespace EscudeTools
byte[] Arr = BitConverter.GetBytes(Data); byte[] Arr = BitConverter.GetBytes(Data);
Array.Reverse(Arr, 0, Arr.Length); Array.Reverse(Arr, 0, Arr.Length);
string type = Data.GetType().FullName; string type = Data.GetType().FullName;
switch (type) return type switch
{ {
case Const.INT8: Const.INT8 or Const.UINT8 => Data,
case Const.UINT8: Const.INT16 => BitConverter.ToInt16(Arr, 0),
return Data; Const.UINT16 => BitConverter.ToUInt16(Arr, 0),
case Const.INT16: Const.INT32 => BitConverter.ToInt32(Arr, 0),
return BitConverter.ToInt16(Arr, 0); Const.UINT32 => BitConverter.ToUInt32(Arr, 0),
case Const.UINT16: Const.INT64 => BitConverter.ToInt64(Arr, 0),
return BitConverter.ToUInt16(Arr, 0); Const.UINT64 => BitConverter.ToUInt64(Arr, 0),
case Const.INT32: Const.DOUBLE => BitConverter.ToDouble(Arr, 0),
return BitConverter.ToInt32(Arr, 0); Const.FLOAT => BitConverter.ToSingle(Arr, 0),
case Const.UINT32: _ => throw new Exception("Unk Data Type."),
return BitConverter.ToUInt32(Arr, 0); };
case Const.INT64:
return BitConverter.ToInt64(Arr, 0);
case Const.UINT64:
return BitConverter.ToUInt64(Arr, 0);
case Const.DOUBLE:
return BitConverter.ToDouble(Arr, 0);
case Const.FLOAT:
return BitConverter.ToSingle(Arr, 0);
default:
throw new Exception("Unk Data Type.");
}
} }
public static void WriteTo(uint Value, byte[] Binary, uint At) public static void WriteTo(uint Value, byte[] Binary, uint At)
{ {
BitConverter.GetBytes(Value).CopyTo(Binary, At); BitConverter.GetBytes(Value).CopyTo(Binary, At);
} }
public static int searchLzwEntryList(List<LzwEntry> lle, string keyword) public static int SearchLzwEntryList(List<LzwEntry> lle, string keyword)
{ {
foreach (LzwEntry le in lle) foreach (LzwEntry le in lle)
{ {