支持ESC-ARC2重新封包
This commit is contained in:
parent
007873c955
commit
6505ac4862
@ -1,4 +1,5 @@
|
|||||||
//这里的代码参考(Ctrl+C, Ctrl+V)了Garbro中关于ESCUDE BIN封包的实现
|
//这里的代码参考(Ctrl+C, Ctrl+V)了Garbro中关于ESCUDE BIN封包的实现
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace EscudeTools
|
namespace EscudeTools
|
||||||
@ -14,6 +15,7 @@ namespace EscudeTools
|
|||||||
static readonly byte[] fileSignature = [0x45, 0x53, 0x43, 0x2D, 0x41, 0x52, 0x43]; //"ESC-ARC"
|
static readonly byte[] fileSignature = [0x45, 0x53, 0x43, 0x2D, 0x41, 0x52, 0x43]; //"ESC-ARC"
|
||||||
static readonly byte[] supportPackVersion = [0x31, 0x32]; //1, 2
|
static readonly byte[] supportPackVersion = [0x31, 0x32]; //1, 2
|
||||||
private bool isLoaded = false;
|
private bool isLoaded = false;
|
||||||
|
private uint LoadedKey;
|
||||||
private string pFile = "";
|
private string pFile = "";
|
||||||
private uint m_seed;
|
private uint m_seed;
|
||||||
private uint m_count;
|
private uint m_count;
|
||||||
@ -54,6 +56,7 @@ namespace EscudeTools
|
|||||||
private List<Entry>? ProcessV1(BinaryReader br)
|
private List<Entry>? ProcessV1(BinaryReader br)
|
||||||
{
|
{
|
||||||
m_seed = br.ReadUInt32();
|
m_seed = br.ReadUInt32();
|
||||||
|
LoadedKey = m_seed;
|
||||||
m_count = br.ReadUInt32() ^ NextKey();
|
m_count = br.ReadUInt32() ^ NextKey();
|
||||||
uint index_size = m_count * 0x88;
|
uint index_size = m_count * 0x88;
|
||||||
byte[] index = Utils.ReadBytes(br, index_size);
|
byte[] index = Utils.ReadBytes(br, index_size);
|
||||||
@ -80,6 +83,7 @@ namespace EscudeTools
|
|||||||
private List<Entry>? ProcessV2(BinaryReader br)
|
private List<Entry>? ProcessV2(BinaryReader br)
|
||||||
{
|
{
|
||||||
m_seed = br.ReadUInt32();
|
m_seed = br.ReadUInt32();
|
||||||
|
LoadedKey = m_seed;
|
||||||
m_count = br.ReadUInt32() ^ NextKey();
|
m_count = br.ReadUInt32() ^ NextKey();
|
||||||
uint names_size = br.ReadUInt32() ^ NextKey();
|
uint names_size = br.ReadUInt32() ^ NextKey();
|
||||||
uint index_size = m_count * 12;
|
uint index_size = m_count * 12;
|
||||||
@ -160,9 +164,71 @@ namespace EscudeTools
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Repack(string path)
|
public bool Repack(string path, int version) //目前支持v2
|
||||||
{
|
{
|
||||||
throw new NotSupportedException("Repack not supported");
|
GeneratePItem(path);
|
||||||
|
m_seed = isLoaded ? LoadedKey : 2210579460;
|
||||||
|
string outputPath = Path.Combine(Path.GetDirectoryName(path), Path.GetFileName(path) + ".bin");
|
||||||
|
using (FileStream fs = new(outputPath, FileMode.Create))
|
||||||
|
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());
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
BitConverter.GetBytes(filenameOffset).CopyTo(index, indexOffset);
|
||||||
|
indexOffset += 4;
|
||||||
|
BitConverter.GetBytes(storeOffset).CopyTo(index, indexOffset);
|
||||||
|
indexOffset += 4;
|
||||||
|
BitConverter.GetBytes(pItem[i].Size).CopyTo(index, indexOffset);
|
||||||
|
indexOffset += 4;
|
||||||
|
filenameOffset += (uint)pItem[i].Name.Length + 1;
|
||||||
|
storeOffset += pItem[i].Size;
|
||||||
|
}
|
||||||
|
Decrypt(ref index);
|
||||||
|
bw.Write(index);
|
||||||
|
EncodingProvider provider = CodePagesEncodingProvider.Instance;
|
||||||
|
Encoding? shiftJis = provider.GetEncoding("shift-jis");
|
||||||
|
foreach (Entry entry in pItem)
|
||||||
|
{
|
||||||
|
byte[] nameBytes = shiftJis.GetBytes(entry.Name);
|
||||||
|
bw.Write(nameBytes);
|
||||||
|
bw.Write((byte)0);
|
||||||
|
}
|
||||||
|
foreach (Entry entry in pItem)
|
||||||
|
{
|
||||||
|
byte[] data = File.ReadAllBytes(Path.Combine(path, entry.Name));
|
||||||
|
bw.Write(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void GeneratePItem(string path)
|
||||||
|
{
|
||||||
|
pItem.Clear();
|
||||||
|
var files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
var relativePath = Path.GetRelativePath(path, file);
|
||||||
|
var fileInfo = new FileInfo(file);
|
||||||
|
pItem.Add(new Entry
|
||||||
|
{
|
||||||
|
Name = relativePath,
|
||||||
|
Size = (uint)fileInfo.Length
|
||||||
|
});
|
||||||
|
}
|
||||||
|
m_count = (uint)pItem.Count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,21 +12,29 @@
|
|||||||
PackManager pm = new();
|
PackManager pm = new();
|
||||||
foreach (string file in files)
|
foreach (string file in files)
|
||||||
{
|
{
|
||||||
if (pm.Load(file))
|
//if (pm.Load(file))
|
||||||
{
|
//{
|
||||||
Console.WriteLine($"Load {file} Success");
|
// Console.WriteLine($"Load {file} Success");
|
||||||
}
|
//}
|
||||||
else
|
//else
|
||||||
{
|
//{
|
||||||
Console.WriteLine($"Load {file} Failed");
|
// Console.WriteLine($"Load {file} Failed");
|
||||||
return;
|
// return;
|
||||||
}
|
//}
|
||||||
|
|
||||||
if (pm.Extract())
|
//if (pm.Extract())
|
||||||
Console.WriteLine("Export Database Success");
|
// Console.WriteLine("Extract Package Success");
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// Console.WriteLine("Extract Package Failed");
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (pm.Repack(args[1], 2))
|
||||||
|
Console.WriteLine("Repack Package Success");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Console.WriteLine("Export Database Failed");
|
Console.WriteLine("Repack Package Failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user