Tool dedicated to isohacking for Xenosaga on Playstation 2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

472 lines
18 KiB

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
}
}