|
|
@ -0,0 +1,472 @@ |
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Diagnostics; |
|
|
|
using System.IO; |
|
|
|
using System.Linq; |
|
|
|
using System.Text; |
|
|
|
using System.Text.RegularExpressions; |
|
|
|
using Hack.Xenosaga.Common; |
|
|
|
using Hack.Tools.Common; |
|
|
|
using Hack.Tools.Pointers; |
|
|
|
using Hack.Tools.Table; |
|
|
|
|
|
|
|
namespace Hack.Xenosaga.Process |
|
|
|
{ |
|
|
|
public class Scripts |
|
|
|
{ |
|
|
|
#region Private methods
|
|
|
|
|
|
|
|
private static Table loadTable(string tblName, Encoding encode) |
|
|
|
{ |
|
|
|
Table tbl = new Table(encode); |
|
|
|
tbl.Load(tblName); |
|
|
|
|
|
|
|
if (tblName == Variables.tblCard) |
|
|
|
{ |
|
|
|
tbl.Remove("2C"); |
|
|
|
tbl.Remove("27"); |
|
|
|
} |
|
|
|
|
|
|
|
return tbl; |
|
|
|
} |
|
|
|
|
|
|
|
#region card.dat
|
|
|
|
|
|
|
|
private static bool extractCard(string filename, Encoding encode) |
|
|
|
{ |
|
|
|
int nbBlocs = 0; |
|
|
|
|
|
|
|
try |
|
|
|
{ |
|
|
|
Trace.Write("Extract card.dat : "); |
|
|
|
|
|
|
|
Directory.CreateDirectory(Variables.dirExtract); |
|
|
|
Directory.CreateDirectory(Variables.dirInsert); |
|
|
|
|
|
|
|
using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open))) |
|
|
|
{ |
|
|
|
cTblPointers tblPt = new cTblPointers(); |
|
|
|
Table tbl = new Table(encode); |
|
|
|
tbl.Load(Variables.tblCard); |
|
|
|
|
|
|
|
nbBlocs = br.ReadInt32(); |
|
|
|
|
|
|
|
br.BaseStream.Seek(0x10, SeekOrigin.Begin); |
|
|
|
|
|
|
|
// Get all pointers
|
|
|
|
for (int i = 0; i < nbBlocs; i++) |
|
|
|
{ |
|
|
|
for (int j = 0; j < 6; j++) |
|
|
|
br.ReadUInt32(); |
|
|
|
|
|
|
|
tblPt.add(br.BaseStream.Position, br.ReadUInt32()); |
|
|
|
tblPt.add(br.BaseStream.Position, br.ReadUInt32()); |
|
|
|
|
|
|
|
br.ReadUInt32(); |
|
|
|
} |
|
|
|
|
|
|
|
using (StreamWriter sw = new StreamWriter(Variables.dirExtract + filename + ".txt", false, encode)) |
|
|
|
{ |
|
|
|
// Extracting text from pointers
|
|
|
|
foreach (Pointers pt in tblPt.ListPointers) |
|
|
|
{ |
|
|
|
br.BaseStream.Seek((long)pt.Value, SeekOrigin.Begin); |
|
|
|
|
|
|
|
sw.Write(string.Format(pt.Format, pt.Adress, pt.Num)); |
|
|
|
sw.Write(br.BytesToStringWithTable(tbl)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Trace.WriteLine("OK"); |
|
|
|
} |
|
|
|
catch (Exception ex) |
|
|
|
{ |
|
|
|
Trace.WriteLine(string.Format("ERROR : {0}", ex.Message)); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
private static bool insertCard(string filename, Encoding encode) |
|
|
|
{ |
|
|
|
int nbBlocs = 0; |
|
|
|
|
|
|
|
try |
|
|
|
{ |
|
|
|
Trace.Write("Insert card.dat : "); |
|
|
|
|
|
|
|
using (BinaryReader brIn = new BinaryReader(File.Open(filename, FileMode.Open))) |
|
|
|
using (MemoryStream ms = new MemoryStream()) |
|
|
|
{ |
|
|
|
cTblPointers tblPt = new cTblPointers(); |
|
|
|
Table tbl = loadTable(Variables.tblCard, encode); |
|
|
|
|
|
|
|
nbBlocs = brIn.ReadInt32(); |
|
|
|
ms.Write(BitConverter.GetBytes(nbBlocs), 0, 4); |
|
|
|
|
|
|
|
for (int i = 0; i < 12; i++) |
|
|
|
ms.WriteByte(brIn.ReadByte()); |
|
|
|
|
|
|
|
for (int i = 0; i < nbBlocs; i++) |
|
|
|
{ |
|
|
|
for (int j = 0; j < 9; j++) |
|
|
|
ms.Write(BitConverter.GetBytes(brIn.ReadUInt32()), 0, 4); |
|
|
|
} |
|
|
|
|
|
|
|
using (BinaryReader brTxt = new BinaryReader(File.Open(Variables.dirInsert + filename + ".txt", FileMode.Open), encode)) |
|
|
|
{ |
|
|
|
string line = ""; |
|
|
|
int sizeMax = tbl.ValueMaxSize; |
|
|
|
|
|
|
|
if (tblPt.SizeFormat > tbl.ValueMaxSize) |
|
|
|
sizeMax = tblPt.SizeFormat; |
|
|
|
|
|
|
|
long pos = 0; |
|
|
|
while (pos < brTxt.BaseStream.Length) |
|
|
|
{ |
|
|
|
brTxt.BaseStream.Seek(pos, SeekOrigin.Begin); |
|
|
|
|
|
|
|
if (brTxt.BaseStream.Length - pos < sizeMax) |
|
|
|
sizeMax = (int)(brTxt.BaseStream.Length - pos); |
|
|
|
|
|
|
|
line = brTxt.BytestoString(encode, sizeMax); |
|
|
|
|
|
|
|
int adress, num; |
|
|
|
if (tblPt.textIsPointerInfo(line)) |
|
|
|
{ |
|
|
|
tblPt.getInfoPt(line, out adress, out num); |
|
|
|
tblPt.add(adress, (ulong)ms.Position, 2, (int)typeEndian.LITTLE, num); |
|
|
|
pos += tblPt.SizeFormat; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
stElement stResult = tbl.FindKeyFromValue(line.ToCharArray()); |
|
|
|
|
|
|
|
switch (stResult.type) |
|
|
|
{ |
|
|
|
case typeEntries.NORMAL: |
|
|
|
case typeEntries.ENDBLOCK: |
|
|
|
ms.Write(stResult.keyBytes, 0, stResult.keySize); |
|
|
|
break; |
|
|
|
|
|
|
|
case typeEntries.PARAM: |
|
|
|
break; |
|
|
|
|
|
|
|
case typeEntries.NOT_FOUND: |
|
|
|
Trace.WriteLine(string.Format("ERROR : Unknown character {0} in {1}", line.Substring(0, 1), line)); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
pos += stResult.valueSize; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Write pointer in file
|
|
|
|
tblPt.insertPointersToFile(ms); |
|
|
|
|
|
|
|
Directory.CreateDirectory(Variables.dirPack); |
|
|
|
using (FileStream fs = new FileStream(Variables.dirPack + filename, FileMode.Create)) |
|
|
|
{ |
|
|
|
ms.Position = 0; |
|
|
|
ms.CopyTo(fs); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Trace.WriteLine("OK"); |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
catch (Exception ex) |
|
|
|
{ |
|
|
|
Trace.WriteLine(string.Format("ERROR : {0}", ex.Message)); |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region *.evt
|
|
|
|
|
|
|
|
private static bool decompilEvt(string nameFile, MemoryStream ms) |
|
|
|
{ |
|
|
|
Encoding encode = new UTF8Encoding(false); |
|
|
|
|
|
|
|
using (BinaryReader br = new BinaryReader(ms)) |
|
|
|
{ |
|
|
|
JavaClass jc = new JavaClass(); |
|
|
|
|
|
|
|
jc.load(br); |
|
|
|
|
|
|
|
//using (StreamWriter sw = new StreamWriter("ST0210_constantes.txt"))
|
|
|
|
//{
|
|
|
|
// jc.writeConstants(sw);
|
|
|
|
//}
|
|
|
|
|
|
|
|
Dictionary<int, byte[]> dictBytes = jc.getConstantsBytes(); |
|
|
|
|
|
|
|
if (dictBytes.Count > 0) |
|
|
|
{ |
|
|
|
using (StreamWriter sw = new StreamWriter(Variables.dirExtract + nameFile + ".txt", false, encode)) |
|
|
|
{ |
|
|
|
Table tbl = loadTable(Variables.tblEvt, Encoding.Default); |
|
|
|
|
|
|
|
foreach (KeyValuePair<int, byte[]> bytes in dictBytes) |
|
|
|
{ |
|
|
|
sw.Write(string.Format("[{0:X4}]\n", bytes.Key)); |
|
|
|
|
|
|
|
if (bytes.Value != null) |
|
|
|
sw.Write(tbl.BytesToString(bytes.Value)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
private static MemoryStream compilEvt(evtClass.stFile file) |
|
|
|
{ |
|
|
|
MemoryStream ms = new MemoryStream(); |
|
|
|
using (BinaryReader br = new BinaryReader(ms)) |
|
|
|
{ |
|
|
|
JavaClass jc = new JavaClass(); |
|
|
|
|
|
|
|
jc.load(br); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return ms; |
|
|
|
} |
|
|
|
|
|
|
|
private static bool extractEvt(string pathName, Encoding encode) |
|
|
|
{ |
|
|
|
try |
|
|
|
{ |
|
|
|
Trace.Write(string.Format("Extract {0} : ", pathName)); |
|
|
|
|
|
|
|
evtClass evtFile = new evtClass(pathName); |
|
|
|
|
|
|
|
Directory.CreateDirectory(Variables.dirExtract); |
|
|
|
Directory.CreateDirectory(Variables.dirInsert); |
|
|
|
|
|
|
|
foreach (evtClass.stFile file in evtFile.listFiles) |
|
|
|
{ |
|
|
|
using (MemoryStream ms = new MemoryStream()) |
|
|
|
{ |
|
|
|
ms.Write(file.file, 0, (int)file.fileLength); |
|
|
|
ms.Position = 0; |
|
|
|
|
|
|
|
decompilEvt(file.name, ms); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Trace.WriteLine("OK"); |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
catch (Exception ex) |
|
|
|
{ |
|
|
|
Trace.WriteLine(string.Format("ERROR : {0}", ex.Message)); |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private static bool insertEvt(string pathName, Encoding encode) |
|
|
|
{ |
|
|
|
try |
|
|
|
{ |
|
|
|
Trace.WriteLine(string.Format("Insert {0} : ", pathName)); |
|
|
|
|
|
|
|
using (BinaryReader br = new BinaryReader(File.Open(pathName, FileMode.Open))) |
|
|
|
{ |
|
|
|
evtClass origEvt = new evtClass(br); |
|
|
|
|
|
|
|
Table tbl = loadTable(Variables.tblEvt, Encoding.Default); |
|
|
|
|
|
|
|
using (MemoryStream destEvt = new MemoryStream()) |
|
|
|
{ |
|
|
|
destEvt.Write(BitConverter.GetBytes(origEvt.id), 0, 4); |
|
|
|
destEvt.Write(BitConverter.GetBytes(origEvt.unkAdr4), 0, 2); |
|
|
|
destEvt.Write(BitConverter.GetBytes(origEvt.unkAdr6), 0, 2); |
|
|
|
|
|
|
|
destEvt.Position = 16; |
|
|
|
destEvt.Write(BitConverter.GetBytes(origEvt.unkAdr16), 0, 2); |
|
|
|
destEvt.Write(BitConverter.GetBytes(origEvt.nbFiles), 0, 2); |
|
|
|
|
|
|
|
destEvt.Position = 16 * origEvt.nbFiles + 20; |
|
|
|
|
|
|
|
using (MemoryStream msIndex = new MemoryStream()) |
|
|
|
using (MemoryStream msName = new MemoryStream()) |
|
|
|
{ |
|
|
|
msName.WriteByte(0); |
|
|
|
msName.WriteByte(0); |
|
|
|
|
|
|
|
foreach (evtClass.stFile classFile in origEvt.listFiles) |
|
|
|
{ |
|
|
|
msIndex.Write(BitConverter.GetBytes(msName.Position), 0, 4); |
|
|
|
msIndex.Write(BitConverter.GetBytes(classFile.nameLength), 0, 4); |
|
|
|
msIndex.Write(BitConverter.GetBytes(destEvt.Position), 0, 4); |
|
|
|
msName.Write(encode.GetBytes(classFile.name), 0, (int)classFile.nameLength); |
|
|
|
msName.WriteByte(0); |
|
|
|
|
|
|
|
if (File.Exists(Variables.dirInsert + classFile.name + ".txt")) |
|
|
|
{ |
|
|
|
Dictionary<string, byte[]> list = tbl.StringToBytesArray(Variables.dirInsert + classFile.name + ".txt", new Regex(@"\[(.{4})\]\n")); |
|
|
|
JavaClass jc = new JavaClass(); |
|
|
|
|
|
|
|
using (MemoryStream msFile = new MemoryStream()) |
|
|
|
{ |
|
|
|
msFile.Write(classFile.file, 0, (int)classFile.fileLength); |
|
|
|
msFile.Position = 0; |
|
|
|
|
|
|
|
using (BinaryReader brFile = new BinaryReader(msFile)) |
|
|
|
{ |
|
|
|
br.BaseStream.Position = 0; |
|
|
|
jc.load(brFile); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Dictionary<int, byte[]> dictBytes = jc.getConstantsBytes(); |
|
|
|
|
|
|
|
if (dictBytes.Count > 0) |
|
|
|
{ |
|
|
|
string pt = ""; |
|
|
|
foreach (KeyValuePair<int, byte[]> bytes in dictBytes) |
|
|
|
{ |
|
|
|
pt = string.Format("{0:X4}", bytes.Key); |
|
|
|
|
|
|
|
if (dictBytes.ContainsKey(Convert.ToInt32(pt, 16)) && list[pt] != null) |
|
|
|
jc.setConstantsBytes(bytes.Key, list[pt]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
MemoryStream newFile = jc.compilClass(classFile); |
|
|
|
|
|
|
|
msIndex.Write(BitConverter.GetBytes(newFile.Length), 0, 4); |
|
|
|
destEvt.Write(newFile.ToArray(), 0, (int)newFile.Length); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
msIndex.Write(BitConverter.GetBytes(classFile.fileLength), 0, 4); |
|
|
|
destEvt.Write(classFile.file, 0, (int)classFile.fileLength); |
|
|
|
} |
|
|
|
|
|
|
|
Functions.Padding(destEvt); |
|
|
|
} |
|
|
|
|
|
|
|
long posName = destEvt.Position; |
|
|
|
|
|
|
|
// Write filename table
|
|
|
|
msName.Write(BitConverter.GetBytes(msName.Length-2), 0, 2, 0); |
|
|
|
msName.Position = 0; |
|
|
|
|
|
|
|
destEvt.Write(BitConverter.GetBytes(posName), 0, 4, 12); |
|
|
|
destEvt.Write(msName.ToArray(), 0, (int)msName.Length); |
|
|
|
destEvt.Write(BitConverter.GetBytes(destEvt.Length), 0, 2, 8); |
|
|
|
|
|
|
|
// Write index of files
|
|
|
|
destEvt.Position = 20; |
|
|
|
msIndex.Position = 0; |
|
|
|
for (int i = 0; i < origEvt.nbFiles; i++) |
|
|
|
{ |
|
|
|
destEvt.Write(BitConverter.GetBytes(msIndex.Read() + posName), 0, 4); |
|
|
|
destEvt.Write(BitConverter.GetBytes(msIndex.Read()), 0, 4); |
|
|
|
destEvt.Write(BitConverter.GetBytes(msIndex.Read()), 0, 4); |
|
|
|
destEvt.Write(BitConverter.GetBytes(msIndex.Read()), 0, 4); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
using (FileStream fs = new FileStream(Variables.dirPack + Path.GetFileName(pathName), FileMode.Create)) |
|
|
|
{ |
|
|
|
destEvt.Position = 0; |
|
|
|
fs.Write(destEvt.ToArray(), 0, (int)destEvt.Length); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Trace.WriteLine("OK"); |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
catch (Exception ex) |
|
|
|
{ |
|
|
|
Trace.WriteLine(string.Format("ERROR : {0}", ex.Message)); |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Public methods
|
|
|
|
|
|
|
|
public static void extract(string pathName, Encoding encode) |
|
|
|
{ |
|
|
|
bool result; |
|
|
|
|
|
|
|
if (File.Exists(pathName)) |
|
|
|
{ |
|
|
|
if (Path.GetFileName(pathName) == "card.dat") |
|
|
|
result = extractCard(pathName, encode); |
|
|
|
|
|
|
|
if (Path.GetExtension(pathName) == ".evt") |
|
|
|
result = extractEvt(pathName, encode); |
|
|
|
} |
|
|
|
else if (Directory.Exists(pathName)) |
|
|
|
{ |
|
|
|
var listFiles = Directory |
|
|
|
.EnumerateFiles(pathName) |
|
|
|
.Where(file => file.ToLower().EndsWith("dat") || file.ToLower().EndsWith("evt")) |
|
|
|
.ToList(); |
|
|
|
|
|
|
|
foreach (string file in listFiles) |
|
|
|
{ |
|
|
|
if (Path.GetFileName(file) == "card.dat") |
|
|
|
result = extractCard(file.ToLower(), encode); |
|
|
|
else if (Path.GetExtension(file) == ".evt") |
|
|
|
result = extractEvt(file.ToLower(), encode); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
Trace.WriteLine("Unknown file or directory"); |
|
|
|
} |
|
|
|
|
|
|
|
public static void insert(string pathName, Encoding encode) |
|
|
|
{ |
|
|
|
bool result; |
|
|
|
|
|
|
|
if (File.Exists(pathName)) |
|
|
|
{ |
|
|
|
if (Path.GetFileName(pathName) == "card.dat") |
|
|
|
result = insertCard(pathName, encode); |
|
|
|
|
|
|
|
if (Path.GetExtension(pathName) == ".evt") |
|
|
|
result = insertEvt(pathName, encode); |
|
|
|
} |
|
|
|
else if (Directory.Exists(pathName)) |
|
|
|
{ |
|
|
|
var listFiles = Directory |
|
|
|
.EnumerateFiles(pathName) |
|
|
|
.Where(file => file.ToLower().EndsWith("dat") || file.ToLower().EndsWith("evt")) |
|
|
|
.ToList(); |
|
|
|
|
|
|
|
foreach (string file in listFiles) |
|
|
|
{ |
|
|
|
if (Path.GetFileName(file) == "card.dat") |
|
|
|
result = insertCard(file.ToLower(), encode); |
|
|
|
else if (Path.GetExtension(file) == ".evt") |
|
|
|
result = insertEvt(file.ToLower(), encode); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
Trace.WriteLine("Unknown file of directory"); |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
} |
|
|
|
} |