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

  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 MemoryStream compilEvt(evtClass.stFile file)
  181. {
  182. MemoryStream ms = new MemoryStream();
  183. using (BinaryReader br = new BinaryReader(ms))
  184. {
  185. JavaClass jc = new JavaClass();
  186. jc.load(br);
  187. }
  188. return ms;
  189. }
  190. private static bool extractEvt(string pathName, Encoding encode)
  191. {
  192. try
  193. {
  194. Trace.Write(string.Format("Extract {0} : ", pathName));
  195. evtClass evtFile = new evtClass(pathName);
  196. Directory.CreateDirectory(Variables.dirExtract);
  197. Directory.CreateDirectory(Variables.dirInsert);
  198. foreach (evtClass.stFile file in evtFile.listFiles)
  199. {
  200. using (MemoryStream ms = new MemoryStream())
  201. {
  202. ms.Write(file.file, 0, (int)file.fileLength);
  203. ms.Position = 0;
  204. decompilEvt(file.name, ms);
  205. }
  206. }
  207. Trace.WriteLine("OK");
  208. return true;
  209. }
  210. catch (Exception ex)
  211. {
  212. Trace.WriteLine(string.Format("ERROR : {0}", ex.Message));
  213. return false;
  214. }
  215. }
  216. private static bool insertEvt(string pathName, Encoding encode)
  217. {
  218. try
  219. {
  220. Trace.WriteLine(string.Format("Insert {0} : ", pathName));
  221. using (BinaryReader br = new BinaryReader(File.Open(pathName, FileMode.Open)))
  222. {
  223. evtClass origEvt = new evtClass(br);
  224. Table tbl = loadTable(Variables.tblEvt, Encoding.Default);
  225. using (MemoryStream destEvt = new MemoryStream())
  226. {
  227. destEvt.Write(BitConverter.GetBytes(origEvt.id), 0, 4);
  228. destEvt.Write(BitConverter.GetBytes(origEvt.unkAdr4), 0, 2);
  229. destEvt.Write(BitConverter.GetBytes(origEvt.unkAdr6), 0, 2);
  230. destEvt.Position = 16;
  231. destEvt.Write(BitConverter.GetBytes(origEvt.unkAdr16), 0, 2);
  232. destEvt.Write(BitConverter.GetBytes(origEvt.nbFiles), 0, 2);
  233. destEvt.Position = 16 * origEvt.nbFiles + 20;
  234. using (MemoryStream msIndex = new MemoryStream())
  235. using (MemoryStream msName = new MemoryStream())
  236. {
  237. msName.WriteByte(0);
  238. msName.WriteByte(0);
  239. foreach (evtClass.stFile classFile in origEvt.listFiles)
  240. {
  241. msIndex.Write(BitConverter.GetBytes(msName.Position), 0, 4);
  242. msIndex.Write(BitConverter.GetBytes(classFile.nameLength), 0, 4);
  243. msIndex.Write(BitConverter.GetBytes(destEvt.Position), 0, 4);
  244. msName.Write(encode.GetBytes(classFile.name), 0, (int)classFile.nameLength);
  245. msName.WriteByte(0);
  246. if (File.Exists(Variables.dirInsert + classFile.name + ".txt"))
  247. {
  248. Dictionary<string, byte[]> list = tbl.StringToBytesArray(Variables.dirInsert + classFile.name + ".txt", new Regex(@"\[(.{4})\]\n"));
  249. JavaClass jc = new JavaClass();
  250. using (MemoryStream msFile = new MemoryStream())
  251. {
  252. msFile.Write(classFile.file, 0, (int)classFile.fileLength);
  253. msFile.Position = 0;
  254. using (BinaryReader brFile = new BinaryReader(msFile))
  255. {
  256. br.BaseStream.Position = 0;
  257. jc.load(brFile);
  258. }
  259. }
  260. Dictionary<int, byte[]> dictBytes = jc.getConstantsBytes();
  261. if (dictBytes.Count > 0)
  262. {
  263. string pt = "";
  264. foreach (KeyValuePair<int, byte[]> bytes in dictBytes)
  265. {
  266. pt = string.Format("{0:X4}", bytes.Key);
  267. if (dictBytes.ContainsKey(Convert.ToInt32(pt, 16)) && list[pt] != null)
  268. jc.setConstantsBytes(bytes.Key, list[pt]);
  269. }
  270. }
  271. MemoryStream newFile = jc.compilClass(classFile);
  272. msIndex.Write(BitConverter.GetBytes(newFile.Length), 0, 4);
  273. destEvt.Write(newFile.ToArray(), 0, (int)newFile.Length);
  274. }
  275. else
  276. {
  277. msIndex.Write(BitConverter.GetBytes(classFile.fileLength), 0, 4);
  278. destEvt.Write(classFile.file, 0, (int)classFile.fileLength);
  279. }
  280. Functions.Padding(destEvt);
  281. }
  282. long posName = destEvt.Position;
  283. // Write filename table
  284. msName.Write(BitConverter.GetBytes(msName.Length-2), 0, 2, 0);
  285. msName.Position = 0;
  286. destEvt.Write(BitConverter.GetBytes(posName), 0, 4, 12);
  287. destEvt.Write(msName.ToArray(), 0, (int)msName.Length);
  288. destEvt.Write(BitConverter.GetBytes(destEvt.Length), 0, 2, 8);
  289. // Write index of files
  290. destEvt.Position = 20;
  291. msIndex.Position = 0;
  292. for (int i = 0; i < origEvt.nbFiles; i++)
  293. {
  294. destEvt.Write(BitConverter.GetBytes(msIndex.Read() + posName), 0, 4);
  295. destEvt.Write(BitConverter.GetBytes(msIndex.Read()), 0, 4);
  296. destEvt.Write(BitConverter.GetBytes(msIndex.Read()), 0, 4);
  297. destEvt.Write(BitConverter.GetBytes(msIndex.Read()), 0, 4);
  298. }
  299. }
  300. using (FileStream fs = new FileStream(Variables.dirPack + Path.GetFileName(pathName), FileMode.Create))
  301. {
  302. destEvt.Position = 0;
  303. fs.Write(destEvt.ToArray(), 0, (int)destEvt.Length);
  304. }
  305. }
  306. }
  307. Trace.WriteLine("OK");
  308. return true;
  309. }
  310. catch (Exception ex)
  311. {
  312. Trace.WriteLine(string.Format("ERROR : {0}", ex.Message));
  313. return false;
  314. }
  315. }
  316. #endregion
  317. #endregion
  318. #region Public methods
  319. public static void extract(string pathName, Encoding encode)
  320. {
  321. bool result;
  322. if (File.Exists(pathName))
  323. {
  324. if (Path.GetFileName(pathName) == "card.dat")
  325. result = extractCard(pathName, encode);
  326. if (Path.GetExtension(pathName) == ".evt")
  327. result = extractEvt(pathName, encode);
  328. }
  329. else if (Directory.Exists(pathName))
  330. {
  331. var listFiles = Directory
  332. .EnumerateFiles(pathName)
  333. .Where(file => file.ToLower().EndsWith("dat") || file.ToLower().EndsWith("evt"))
  334. .ToList();
  335. foreach (string file in listFiles)
  336. {
  337. if (Path.GetFileName(file) == "card.dat")
  338. result = extractCard(file.ToLower(), encode);
  339. else if (Path.GetExtension(file) == ".evt")
  340. result = extractEvt(file.ToLower(), encode);
  341. }
  342. }
  343. else
  344. Trace.WriteLine("Unknown file or directory");
  345. }
  346. public static void insert(string pathName, Encoding encode)
  347. {
  348. bool result;
  349. if (File.Exists(pathName))
  350. {
  351. if (Path.GetFileName(pathName) == "card.dat")
  352. result = insertCard(pathName, encode);
  353. if (Path.GetExtension(pathName) == ".evt")
  354. result = insertEvt(pathName, encode);
  355. }
  356. else if (Directory.Exists(pathName))
  357. {
  358. var listFiles = Directory
  359. .EnumerateFiles(pathName)
  360. .Where(file => file.ToLower().EndsWith("dat") || file.ToLower().EndsWith("evt"))
  361. .ToList();
  362. foreach (string file in listFiles)
  363. {
  364. if (Path.GetFileName(file) == "card.dat")
  365. result = insertCard(file.ToLower(), encode);
  366. else if (Path.GetExtension(file) == ".evt")
  367. result = insertEvt(file.ToLower(), encode);
  368. }
  369. }
  370. else
  371. Trace.WriteLine("Unknown file of directory");
  372. }
  373. #endregion
  374. }
  375. }