public static IEnumerable <SysCpkEntry> EnumerateSysFiles(Cpk cpk, int index) { if (cpk.ItocEntries.Count != 16) { throw new InvalidDataException($"{cpk.ItocEntries.Count} != 16"); } byte[] data; using (var ms = new MemoryStream()) { cpk.ExtractItoc(ms, cpk.ItocEntries[index]); if (index != 1) // lzss { Span <byte> span = stackalloc byte[4]; ms.Position = 0; ms.Read(span); var size = BitConverter.ToInt32(span); data = LZSS.Decode(ms.StreamAsIEnumerable()).ToArray(); if (data.Length != size) { throw new InvalidDataException($"itoc {index} decoded size {data.Length} != {size}"); } } else { data = new byte[ms.Length]; ms.Position = 0; ms.Read(data); } } return(HandleNested("", data)); }
byte[] GetType1FileData(int indexOffset) { DataStream.Seek(indexOffset, SeekOrigin.Begin); UInt16 uncmpSize = ReadUInt16LE(DataStream); UInt16 cmpSize = ReadUInt16LE(DataStream); DataStream.Seek(indexOffset + 4, SeekOrigin.Begin); return(LZSS.Decode(DataStream, cmpSize, uncmpSize)); }
// private methods byte[] GetType2FileData(int indexOffset, int part) { DataRunStream.Seek(indexOffset, SeekOrigin.Begin); int data001Offset = DataRunStream.ReadByte() + (DataRunStream.ReadByte() << 8) + (DataRunStream.ReadByte() << 16); for (int i = 0; i < part; i++) { int size = ReadUInt16LE(DataRunStream); data001Offset += size; } DataStream.Seek(data001Offset, SeekOrigin.Begin); UInt16 uncmpSize = ReadUInt16LE(DataStream); UInt16 cmpSize = ReadUInt16LE(DataStream); return(LZSS.Decode(DataStream, cmpSize, uncmpSize)); }
public static int Main(string[] args) { if (args.Length < 1) { Console.WriteLine("No options specified."); return(1); } switch (args[0]) { // Pack a directory of files into DATA.001, DATA.DIR, DATA.RUN. case "--packfiles": { var cmpArchive = new Archive(args[1]); var uncmpArchive = new Archive(args[2]); PackedFileWriter writer = new PackedFileWriter(cmpArchive, uncmpArchive); writer.Save(args[3]); break; } // Decompress a file case "--compressfile": { byte[] data = File.ReadAllBytes(args[1]); byte[] cmpData = LZSS.Encode(data); FileStream output = File.Open(args[2], FileMode.Create); output.WriteByte((byte)(data.Length & 0xff)); output.WriteByte((byte)(data.Length >> 8)); output.Write(cmpData, 0, cmpData.Length); output.Close(); break; } // Decompress a given file case "--decompressfile": { FileStream stream = File.OpenRead(args[1]); byte[] cmpData = new byte[stream.Length - 2]; UInt16 uncmpSize = (UInt16)(stream.ReadByte() + (stream.ReadByte() << 8)); stream.Read(cmpData, 0, cmpData.Length); byte[] data = LZSS.Decode(cmpData, cmpData.Length, uncmpSize); FileStream output = File.Open(args[2], FileMode.Create); output.Write(data, 0, data.Length); output.Close(); break; } // Dump uncompressed versions of all files case "--dumpallfiles": { var archive = new Archive(args[1]); var fileMgr = new PackedFileReader(archive); DumpAllFiles(fileMgr, args[2]); break; } // Dump compressed versions of all files case "--dumpallfilescmp": { var archive = new Archive(args[1]); var fileMgr = new PackedFileReader(archive); DumpAllCompressedFiles(fileMgr, args[2]); break; } // Dump text from an RDF file case "--dumprdftext": { byte[] data = File.ReadAllBytes(args[1]); int textPos = Int32.Parse(args[2]); Console.Write("\""); while (data[textPos] != '\0') { char c = (char)(data[textPos++]); if (c == '\\' || c == '"') { Console.Write("\\"); } Console.Write(c); } Console.Write("\",\n"); break; } // Dump table of text from an RDF file case "--dumprdftexttable": { byte[] data = File.ReadAllBytes(args[1]); int pos = Int32.Parse(args[2]); Console.WriteLine("const char *text[] = {"); do { int textPos = Helper.ReadUInt16(data, pos); Console.Write("\t\""); while (data[textPos] != '\0') { char c = (char)(data[textPos++]); if (c == '\\' || c == '"') { Console.Write("\\"); } Console.Write(c); } Console.Write("\",\n"); pos += 2; }while (Helper.ReadUInt16(data, pos) != 0); Console.WriteLine("\t\"\"\n};"); break; } case "--dumpscript": { if (args.Length >= 3) { DumpScript(args[1], args[2]); } else { DumpScript(args[1], null); } break; } // Dump "scripts" (x86 code) from RDF files into txt files (uses objdump to disassemble) case "--dumpallscripts": { var directory = args[1]; var outputDir = args[2]; string sfxDir = (args.Length >= 3 ? args[2] : null); foreach (String s in Directory.GetFiles(directory)) { if (s.EndsWith(".RDF")) { DumpScript(s, sfxDir, outputDir); } } break; } default: Console.WriteLine("Unrecognized option \"" + args[0] + "\"."); return(1); } return(0); }