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.

458 lines
17 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Text.RegularExpressions;
  8. using Hack.Xenosaga.Common;
  9. using Hack.Tools.Common;
  10. using Hack.Tools.Pointers;
  11. using Hack.Tools.Table;
  12. namespace Hack.Xenosaga.Process
  13. {
  14. public class Scripts
  15. {
  16. #region Private methods
  17. private static Table loadTable(string tblName, Encoding encode)
  18. {
  19. Table tbl = new Table(encode);
  20. tbl.Load(tblName);
  21. if (tblName == Variables.tblCard)
  22. {
  23. tbl.Remove("2C");
  24. tbl.Remove("27");
  25. }
  26. return tbl;
  27. }
  28. #region card.dat
  29. private static bool extractCard(string filename, Encoding encode)
  30. {
  31. int nbBlocs = 0;
  32. try
  33. {
  34. Trace.Write("Extract card.dat : ");
  35. Directory.CreateDirectory(Variables.dirExtract);
  36. Directory.CreateDirectory(Variables.dirInsert);
  37. using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open)))
  38. {
  39. cTblPointers tblPt = new cTblPointers();
  40. Table tbl = new Table(encode);
  41. tbl.Load(Variables.tblCard);
  42. nbBlocs = br.ReadInt32();
  43. br.BaseStream.Seek(0x10, SeekOrigin.Begin);
  44. // Get all pointers
  45. for (int i = 0; i < nbBlocs; i++)
  46. {
  47. for (int j = 0; j < 6; j++)
  48. br.ReadUInt32();
  49. tblPt.add(br.BaseStream.Position, br.ReadUInt32());
  50. tblPt.add(br.BaseStream.Position, br.ReadUInt32());
  51. br.ReadUInt32();
  52. }
  53. using (StreamWriter sw = new StreamWriter(Variables.dirExtract + filename + ".txt", false, encode))
  54. {
  55. // Extracting text from pointers
  56. foreach (Pointers pt in tblPt.ListPointers)
  57. {
  58. br.BaseStream.Seek((long)pt.Value, SeekOrigin.Begin);
  59. sw.Write(string.Format(pt.Format, pt.Adress, pt.Num));
  60. sw.Write(br.BytesToStringWithTable(tbl));
  61. }
  62. }
  63. }
  64. Trace.WriteLine("OK");
  65. }
  66. catch (Exception ex)
  67. {
  68. Trace.WriteLine(string.Format("ERROR : {0}", ex.Message));
  69. return false;
  70. }
  71. return true;
  72. }
  73. private static bool insertCard(string filename, Encoding encode)
  74. {
  75. int nbBlocs = 0;
  76. try
  77. {
  78. Trace.Write("Insert card.dat : ");
  79. using (BinaryReader brIn = new BinaryReader(File.Open(filename, FileMode.Open)))
  80. using (MemoryStream ms = new MemoryStream())
  81. {
  82. cTblPointers tblPt = new cTblPointers();
  83. Table tbl = loadTable(Variables.tblCard, encode);
  84. nbBlocs = brIn.ReadInt32();
  85. ms.Write(BitConverter.GetBytes(nbBlocs), 0, 4);
  86. for (int i = 0; i < 12; i++)
  87. ms.WriteByte(brIn.ReadByte());
  88. for (int i = 0; i < nbBlocs; i++)
  89. {
  90. for (int j = 0; j < 9; j++)
  91. ms.Write(BitConverter.GetBytes(brIn.ReadUInt32()), 0, 4);
  92. }
  93. using (BinaryReader brTxt = new BinaryReader(File.Open(Variables.dirInsert + filename + ".txt", FileMode.Open), encode))
  94. {
  95. string line = "";
  96. int sizeMax = tbl.ValueMaxSize;
  97. if (tblPt.SizeFormat > tbl.ValueMaxSize)
  98. sizeMax = tblPt.SizeFormat;
  99. long pos = 0;
  100. while (pos < brTxt.BaseStream.Length)
  101. {
  102. brTxt.BaseStream.Seek(pos, SeekOrigin.Begin);
  103. if (brTxt.BaseStream.Length - pos < sizeMax)
  104. sizeMax = (int)(brTxt.BaseStream.Length - pos);
  105. line = brTxt.BytestoString(encode, sizeMax);
  106. int adress, num;
  107. if (tblPt.textIsPointerInfo(line))
  108. {
  109. tblPt.getInfoPt(line, out adress, out num);
  110. tblPt.add(adress, (ulong)ms.Position, 2, (int)typeEndian.LITTLE, num);
  111. pos += tblPt.SizeFormat;
  112. }
  113. else
  114. {
  115. stElement stResult = tbl.FindKeyFromValue(line.ToCharArray());
  116. switch (stResult.type)
  117. {
  118. case typeEntries.NORMAL:
  119. case typeEntries.ENDBLOCK:
  120. ms.Write(stResult.keyBytes, 0, stResult.keySize);
  121. break;
  122. case typeEntries.PARAM:
  123. break;
  124. case typeEntries.NOT_FOUND:
  125. Trace.WriteLine(string.Format("ERROR : Unknown character {0} in {1}", line.Substring(0, 1), line));
  126. return false;
  127. }
  128. pos += stResult.valueSize;
  129. }
  130. }
  131. }
  132. // Write pointer in file
  133. tblPt.insertPointersToFile(ms);
  134. Directory.CreateDirectory(Variables.dirPack);
  135. using (FileStream fs = new FileStream(Variables.dirPack + filename, FileMode.Create))
  136. {
  137. ms.Position = 0;
  138. ms.CopyTo(fs);
  139. }
  140. }
  141. Trace.WriteLine("OK");
  142. return true;
  143. }
  144. catch (Exception ex)
  145. {
  146. Trace.WriteLine(string.Format("ERROR : {0}", ex.Message));
  147. return false;
  148. }
  149. }
  150. #endregion
  151. #region *.evt
  152. private static bool decompilEvt(string nameFile, MemoryStream ms)
  153. {
  154. Encoding encode = new UTF8Encoding(false);
  155. using (BinaryReader br = new BinaryReader(ms))
  156. {
  157. JavaClass jc = new JavaClass();
  158. jc.load(br);
  159. //using (StreamWriter sw = new StreamWriter("ST0210_constantes.txt"))
  160. //{
  161. // jc.writeConstants(sw);
  162. //}
  163. Dictionary<int, byte[]> dictBytes = jc.getConstantsBytes();
  164. if (dictBytes.Count > 0)
  165. {
  166. using (StreamWriter sw = new StreamWriter(Variables.dirExtract + nameFile + ".txt", false, encode))
  167. {
  168. Table tbl = loadTable(Variables.tblEvt, Encoding.Default);
  169. foreach (KeyValuePair<int, byte[]> bytes in dictBytes)
  170. {
  171. sw.Write(string.Format("[{0:X4}]\n", bytes.Key));
  172. if (bytes.Value != null)
  173. sw.Write(tbl.BytesToString(bytes.Value));
  174. }
  175. }
  176. }
  177. }
  178. return true;
  179. }
  180. private static bool extractEvt(string pathName, Encoding encode)
  181. {
  182. try
  183. {
  184. Trace.Write(string.Format("Extract {0} : ", pathName));
  185. evtClass evtFile = new evtClass(pathName);
  186. Directory.CreateDirectory(Variables.dirExtract);
  187. Directory.CreateDirectory(Variables.dirInsert);
  188. foreach (evtClass.stFile file in evtFile.listFiles)
  189. {
  190. using (MemoryStream ms = new MemoryStream())
  191. {
  192. ms.Write(file.file, 0, (int)file.fileLength);
  193. ms.Position = 0;
  194. decompilEvt(file.name, ms);
  195. }
  196. }
  197. Trace.WriteLine("OK");
  198. return true;
  199. }
  200. catch (Exception ex)
  201. {
  202. Trace.WriteLine(string.Format("ERROR : {0}", ex.Message));
  203. return false;
  204. }
  205. }
  206. private static bool insertEvt(string pathName, Encoding encode)
  207. {
  208. try
  209. {
  210. Trace.WriteLine(string.Format("Insert {0} : ", pathName));
  211. using (BinaryReader br = new BinaryReader(File.Open(pathName, FileMode.Open)))
  212. {
  213. evtClass origEvt = new evtClass(br);
  214. Table tbl = loadTable(Variables.tblEvt, Encoding.Default);
  215. using (MemoryStream destEvt = new MemoryStream())
  216. {
  217. destEvt.Write(BitConverter.GetBytes(origEvt.id), 0, 4);
  218. destEvt.Write(BitConverter.GetBytes(origEvt.unkAdr4), 0, 2);
  219. destEvt.Write(BitConverter.GetBytes(origEvt.unkAdr6), 0, 2);
  220. destEvt.Position = 16;
  221. destEvt.Write(BitConverter.GetBytes(origEvt.unkAdr16), 0, 2);
  222. destEvt.Write(BitConverter.GetBytes(origEvt.nbFiles), 0, 2);
  223. destEvt.Position = 16 * origEvt.nbFiles + 20;
  224. using (MemoryStream msIndex = new MemoryStream())
  225. using (MemoryStream msName = new MemoryStream())
  226. {
  227. msName.WriteByte(0);
  228. msName.WriteByte(0);
  229. foreach (evtClass.stFile classFile in origEvt.listFiles)
  230. {
  231. msIndex.Write(BitConverter.GetBytes(msName.Position), 0, 4);
  232. msIndex.Write(BitConverter.GetBytes(classFile.nameLength), 0, 4);
  233. msIndex.Write(BitConverter.GetBytes(destEvt.Position), 0, 4);
  234. msName.Write(encode.GetBytes(classFile.name), 0, (int)classFile.nameLength);
  235. msName.WriteByte(0);
  236. if (File.Exists(Variables.dirInsert + classFile.name + ".txt"))
  237. {
  238. Dictionary<string, byte[]> list = tbl.StringToBytesArray(Variables.dirInsert + classFile.name + ".txt", new Regex(@"\[(.{4})\]\n"));
  239. JavaClass jc = new JavaClass();
  240. using (MemoryStream msFile = new MemoryStream())
  241. {
  242. msFile.Write(classFile.file, 0, (int)classFile.fileLength);
  243. msFile.Position = 0;
  244. using (BinaryReader brFile = new BinaryReader(msFile))
  245. {
  246. br.BaseStream.Position = 0;
  247. jc.load(brFile);
  248. }
  249. }
  250. Dictionary<int, byte[]> dictBytes = jc.getConstantsBytes();
  251. if (dictBytes.Count > 0)
  252. {
  253. string pt = "";
  254. foreach (KeyValuePair<int, byte[]> bytes in dictBytes)
  255. {
  256. pt = string.Format("{0:X4}", bytes.Key);
  257. if (dictBytes.ContainsKey(Convert.ToInt32(pt, 16)) && list[pt] != null)
  258. jc.setConstantsBytes(bytes.Key, list[pt]);
  259. }
  260. }
  261. MemoryStream newFile = jc.compilClass(classFile);
  262. msIndex.Write(BitConverter.GetBytes(newFile.Length), 0, 4);
  263. destEvt.Write(newFile.ToArray(), 0, (int)newFile.Length);
  264. }
  265. else
  266. {
  267. msIndex.Write(BitConverter.GetBytes(classFile.fileLength), 0, 4);
  268. destEvt.Write(classFile.file, 0, (int)classFile.fileLength);
  269. }
  270. Functions.Padding(destEvt);
  271. }
  272. long posName = destEvt.Position;
  273. // Write filename table
  274. msName.Write(BitConverter.GetBytes(msName.Length-2), 0, 2, 0);
  275. msName.Position = 0;
  276. destEvt.Write(BitConverter.GetBytes(posName), 0, 4, 12);
  277. destEvt.Write(msName.ToArray(), 0, (int)msName.Length);
  278. destEvt.Write(BitConverter.GetBytes(destEvt.Length), 0, 4, 8);
  279. // Write index of files
  280. destEvt.Position = 20;
  281. msIndex.Position = 0;
  282. for (int i = 0; i < origEvt.nbFiles; i++)
  283. {
  284. destEvt.Write(BitConverter.GetBytes(msIndex.Read() + posName), 0, 4);
  285. destEvt.Write(BitConverter.GetBytes(msIndex.Read()), 0, 4);
  286. destEvt.Write(BitConverter.GetBytes(msIndex.Read()), 0, 4);
  287. destEvt.Write(BitConverter.GetBytes(msIndex.Read()), 0, 4);
  288. }
  289. }
  290. Directory.CreateDirectory(Variables.dirPack);
  291. using (FileStream fs = new FileStream(Variables.dirPack + Path.GetFileName(pathName), FileMode.Create))
  292. {
  293. destEvt.Position = 0;
  294. fs.Write(destEvt.ToArray(), 0, (int)destEvt.Length);
  295. }
  296. }
  297. }
  298. Trace.WriteLine("OK");
  299. return true;
  300. }
  301. catch (Exception ex)
  302. {
  303. Trace.WriteLine(string.Format("ERROR : {0}", ex.Message));
  304. return false;
  305. }
  306. }
  307. #endregion
  308. #endregion
  309. #region Public methods
  310. public static void extract(string pathName, Encoding encode)
  311. {
  312. bool result;
  313. if (File.Exists(pathName))
  314. {
  315. if (Path.GetFileName(pathName) == "card.dat")
  316. result = extractCard(pathName, encode);
  317. if (Path.GetExtension(pathName) == ".evt")
  318. result = extractEvt(pathName, encode);
  319. }
  320. else if (Directory.Exists(pathName))
  321. {
  322. var listFiles = Directory
  323. .EnumerateFiles(pathName)
  324. .Where(file => file.ToLower().EndsWith("dat") || file.ToLower().EndsWith("evt"))
  325. .ToList();
  326. foreach (string file in listFiles)
  327. {
  328. if (Path.GetFileName(file) == "card.dat")
  329. result = extractCard(file.ToLower(), encode);
  330. else if (Path.GetExtension(file) == ".evt")
  331. result = extractEvt(file.ToLower(), encode);
  332. }
  333. }
  334. else
  335. Trace.WriteLine("Unknown file or directory");
  336. }
  337. public static void insert(string pathName, Encoding encode)
  338. {
  339. bool result;
  340. if (File.Exists(pathName))
  341. {
  342. if (Path.GetFileName(pathName) == "card.dat")
  343. result = insertCard(pathName, encode);
  344. if (Path.GetExtension(pathName) == ".evt")
  345. result = insertEvt(pathName, encode);
  346. }
  347. else if (Directory.Exists(pathName))
  348. {
  349. var listFiles = Directory
  350. .EnumerateFiles(pathName)
  351. .Where(file => file.ToLower().EndsWith("dat") || file.ToLower().EndsWith("evt"))
  352. .ToList();
  353. foreach (string file in listFiles)
  354. {
  355. if (Path.GetFileName(file) == "card.dat")
  356. result = insertCard(file.ToLower(), encode);
  357. else if (Path.GetExtension(file) == ".evt")
  358. result = insertEvt(file.ToLower(), encode);
  359. }
  360. }
  361. else
  362. Trace.WriteLine("Unknown file of directory");
  363. }
  364. #endregion
  365. }
  366. }