private static byte[] SerializeSPT(string file) { var ms = new MemoryStream(); using (var bw = new BinaryWriterY(ms, true)) using (var reader = new SPT.TXTReader(File.ReadAllText(file))) { var header = new SPT.Structs.SPTHeader(); List <byte[]> partitions = new List <byte[]>(); List <(int, int)> flags = new List <(int, int)>(); while (reader.ReadNextPartition()) { flags.Add((reader.GetCurrentPartitionInfo().flags1, reader.GetCurrentPartitionInfo().flags2)); var intMs = new MemoryStream(); using (var intBw = new BinaryWriterY(intMs, true)) { while (reader.ReadNextCode()) { intBw.Write((ushort)(reader.GetCurrentCodeInfo().code ^ header.XORKey)); if (reader.GetCurrentCodeInfo().arguments.Count > 0) { foreach (var arg in reader.GetCurrentCodeInfo().arguments) { intBw.Write((ushort)(arg ^ header.XORKey)); } } } intBw.Write((short)0); } partitions.Add(intMs.ToArray()); } header.biggestPartitionSize = (short)(partitions.Max(p => p.Length) / 2); header.partitionCount = (short)partitions.Count; bw.WriteStruct(header); var dataOffset = 0xc + partitions.Count * 8; for (int i = 0; i < partitions.Count; i++) { bw.Write((short)(dataOffset / 2)); bw.Write((short)(partitions[i].Length / 2 - 1)); bw.Write((short)flags[i].Item1); bw.Write((short)flags[i].Item2); dataOffset += partitions[i].Length; } foreach (var part in partitions) { bw.Write(part); } } return(ms.ToArray()); }
static void Main(string[] args2) { var options = ParseArgs(args2); if (options.mode == "extract") { var sections = new List <byte[]>(); using (var br = new BinaryReaderY(File.OpenRead(options.path))) { try { var entryCount = br.ReadInt32(); var entryList = br.ReadMultiple <DlgEntry>(entryCount); foreach (var e in entryList) { br.BaseStream.Position = e.offset; sections.Add(Nintendo.Decompress(new MemoryStream(br.ReadBytes(e.size)))); } } catch (Exception ex) { Console.WriteLine("This file seems a bit corrupted or isn't a dlg. Either way it won't work."); Console.WriteLine(ex.Message + " - " + ex.InnerException); return; } } var writeDir = Path.Combine(Path.GetDirectoryName(options.path), Path.GetFileNameWithoutExtension(options.path)); if (!Directory.Exists(writeDir)) { Directory.CreateDirectory(writeDir); } var txtCount = 0; foreach (var s in sections) { using (var br = new BinaryReaderY(new MemoryStream(s))) { if (options.isBinary) { File.WriteAllBytes(Path.Combine(writeDir, $"{txtCount++:000}.bin"), s); } else { var enc = new AAEncoding(options.lang, options.game); File.WriteAllText(Path.Combine(writeDir, $"{txtCount++:000}.txt"), enc.GetSectionText(s)); } } } } else if (options.mode == "create") { var enc = new AAEncoding(options.lang, options.game); var files = Directory.GetFiles(options.path).Where(f => Path.GetExtension(f) == ((options.isBinary) ? ".bin" : ".txt")).OrderBy(name => name).ToList(); var entries = new List <DlgEntry>(); var ms = new MemoryStream(); using (var bw = new BinaryWriterY(ms, true)) { bw.BaseStream.Position = files.Count * 8 + 4; foreach (var file in files) { byte[] compBytes = null; if (options.isBinary) { compBytes = Nintendo.Compress(new MemoryStream(File.ReadAllBytes(file)), Nintendo.Method.LZ10); } else { var sectionText = File.ReadAllText(file).Replace("\r\n", ""); var bytes = enc.GetBytes(sectionText); compBytes = Nintendo.Compress(new MemoryStream(bytes), Nintendo.Method.LZ10); } entries.Add(new DlgEntry { offset = (int)bw.BaseStream.Position, size = compBytes.Length }); bw.Write(compBytes); bw.BaseStream.Position = (bw.BaseStream.Position + 3) & ~3; } bw.BaseStream.Position = 0; bw.Write(entries.Count); foreach (var entry in entries) { bw.WriteStruct(entry); } } File.WriteAllBytes("new.dlg", ms.ToArray()); } }