private static void KH2PatchExtractor(Stream patch, string outputname) { try { Directory.CreateDirectory(Path.GetDirectoryName("output/")); } catch { } //Creating folder using (var br = new BinaryStream(patch, Encoding.ASCII, leaveOpen: true)) { using (TextWriter op = new StreamWriter("output/log.log")) { uint tmp = br.ReadUInt32(); if (tmp != 1345472587u && tmp != 1362249803u) { br.Close(); br.Close(); throw new InvalidDataException("Invalid KH2Patch file!"); } uint oaAuther = br.ReadUInt32(), obFileCount = br.ReadUInt32(), num = br.ReadUInt32(); string patchname = ""; patchname = Path.GetFileName(patchname); try { string author = br.ReadCString(); op.WriteLine(author); op.WriteLine(num); Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("Loading patch {0} version {1} by {2}", patchname, num, author); Console.ResetColor(); br.Seek(oaAuther, SeekOrigin.Begin); uint os1 = br.ReadUInt32(), os2 = br.ReadUInt32(), os3 = br.ReadUInt32(); br.Seek(oaAuther + os1, SeekOrigin.Begin); num = br.ReadUInt32(); if (num > 0) { br.Seek(num * 4, SeekOrigin.Current); //Console.WriteLine("Changelog:"); Console.ForegroundColor = ConsoleColor.Green; while (num > 0) { --num; op.WriteLine(br.ReadCString()); //Console.WriteLine(" * {0}", br.ReadCString()); } op.WriteLine(""); } br.Seek(oaAuther + os2, SeekOrigin.Begin); num = br.ReadUInt32(); if (num > 0) { br.Seek(num * 4, SeekOrigin.Current); Console.ResetColor(); //Console.WriteLine("Credits:"); Console.ForegroundColor = ConsoleColor.Green; while (num > 0) { --num; op.WriteLine(br.ReadCString()); //Console.WriteLine(" * {0}", br.ReadCString()); } op.WriteLine(""); Console.ResetColor(); } br.Seek(oaAuther + os3, SeekOrigin.Begin); author = br.ReadCString(); /*author = author.Replace("\r\n", string.Empty); author = author.Replace("\n", string.Empty);//Shitty but I know someone who made mods for adding more than one line...*/ if (author.Length != 0) { // Console.WriteLine("Other information:\r\n"); Console.ForegroundColor = ConsoleColor.Green; op.WriteLine(author); //Console.WriteLine("{0}", author); } op.WriteLine(""); Console.ResetColor(); } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Error reading kh2patch header: {0}: {1}\r\nAttempting to continue files...", e.GetType(), e.Message); Console.ResetColor(); } Console.WriteLine(""); br.Seek(obFileCount, SeekOrigin.Begin); num = br.ReadUInt32(); while (num > 0) { --num; uint Hash = br.ReadUInt32(); oaAuther = br.ReadUInt32(); uint CompressedSize = br.ReadUInt32(); uint UncompressedSize = br.ReadUInt32(); uint Parent = br.ReadUInt32(); uint Relink = br.ReadUInt32(); bool Compressed = br.ReadUInt32() != 0; bool IsNew = br.ReadUInt32() == 1; //Custom string fname3 = ""; string fname2; if (Relink == 0) { if (CompressedSize != 0) { var KH2PFileStream = new Substream(patch, oaAuther, CompressedSize); if (HashList.HashList.pairs.TryGetValue(Hash, out fname2)) { Console.Write("Extracting {0}...", fname2); } else { fname2 = String.Format("@noname/{0:X8}.bin", Hash); ; Console.Write("Extracting {0}...", fname2); } long brpos = br.Tell(); KH2PATCHInternal(KH2PFileStream, fname2, Compressed, UncompressedSize); br.ChangePosition((int)brpos); //Changing the original position of the BinaryReader for what's next } else { throw new InvalidDataException("File length is 0, but not relinking."); } op.WriteLine(fname2); op.WriteLine(fname3); string Compressed2 = ""; if (Compressed) { Compressed2 = "y"; } else { Compressed2 = "n"; } op.WriteLine(Compressed2); string Parent2 = ""; if (Parent == 0) { } if (Parent == 1) { Parent2 = "OVL"; } if (Parent == 2) { Parent2 = "ISO"; } op.WriteLine(Parent2); string IsNew2 = ""; if (IsNew) { IsNew2 = "y"; } else { IsNew2 = "n"; } op.WriteLine(IsNew2); } else { if (!HashList.HashList.pairs.TryGetValue(Hash, out fname2)) { fname2 = String.Format("@noname/{0:X8}.bin", Hash); } if (!HashList.HashList.pairs.TryGetValue(Relink, out fname3)) { fname3 = String.Format("@noname/{0:X8}.bin", Relink); } Console.WriteLine("File {1} relinked to {0}, no need to extract", fname3, fname2); op.WriteLine(fname2); op.WriteLine(fname3); string Parent2 = ""; if (Parent == 0) { } if (Parent == 1) { Parent2 = "OVL"; } if (Parent == 2) { Parent2 = "ISO"; } op.WriteLine(Parent2); string IsNew2 = ""; if (IsNew) { IsNew2 = "y"; } else { IsNew2 = "n"; } op.WriteLine(IsNew2); } br.Seek(60, SeekOrigin.Current); } op.WriteLine(""); using (TextWriter bat = new StreamWriter("output/output.bat")) { bat.WriteLine("@echo off"); bat.WriteLine("KH2FM_Toolkit.exe -patchmaker -batch -uselog log.log -output \"{0}\"", outputname); } File.Copy(System.Reflection.Assembly.GetEntryAssembly().Location, "output/KH2FM_Toolkit.exe"); } } //End of br }
private void AddPatch(Stream ms, string patchname = "") { using (var br = new BinaryStream(ms, Encoding.ASCII, leaveOpen: true)) { if (br.ReadUInt32() != 0x5032484b) { br.Seek(0, SeekOrigin.Begin); if (br.ReadUInt32() != 0x5132484b) { br.Seek(0, SeekOrigin.Begin); if (br.ReadUInt32() != 0x4632484b) { br.Close(); ms.Close(); throw new InvalidDataException("Invalid KH2Patch file!"); } else { fast_patch=true; Console.WriteLine("Fast patch and dev flags detected! You might get some issues with those!"); } } } patchms.Add(ms); uint oaAuther = br.ReadUInt32(), obFileCount = br.ReadUInt32(), num = br.ReadUInt32(); patchname = Path.GetFileName(patchname); try { string author = br.ReadCString(); Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("Loading patch {0} version {1} by {2}", patchname, num, author); Console.ResetColor(); br.Seek(oaAuther, SeekOrigin.Begin); uint os1 = br.ReadUInt32(), os2 = br.ReadUInt32(), os3 = br.ReadUInt32(); br.Seek(oaAuther + os1, SeekOrigin.Begin); num = br.ReadUInt32(); if (num > 0) { br.Seek(num*4, SeekOrigin.Current); Console.WriteLine("Changelog:"); Console.ForegroundColor = ConsoleColor.Green; while (num > 0) { --num; Console.WriteLine(" * {0}", br.ReadCString()); } } br.Seek(oaAuther + os2, SeekOrigin.Begin); num = br.ReadUInt32(); if (num > 0) { br.Seek(num*4, SeekOrigin.Current); Console.ResetColor(); Console.WriteLine("Credits:"); Console.ForegroundColor = ConsoleColor.Green; while (num > 0) { --num; Console.WriteLine(" * {0}", br.ReadCString()); } Console.ResetColor(); } br.Seek(oaAuther + os3, SeekOrigin.Begin); author = br.ReadCString(); if (author.Length != 0) { Console.WriteLine("Other information:\r\n"); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("{0}", author); } Console.ResetColor(); } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Error reading kh2patch header: {0}: {1}\r\nAttempting to continue files...", e.GetType(), e.Message); Console.ResetColor(); } Console.WriteLine(""); br.Seek(obFileCount, SeekOrigin.Begin); num = br.ReadUInt32(); while (num > 0) { --num; var nPatch = new Patch(); nPatch.Hash = br.ReadUInt32(); oaAuther = br.ReadUInt32(); nPatch.CompressedSize = br.ReadUInt32(); nPatch.UncompressedSize = br.ReadUInt32(); nPatch.Parent = br.ReadUInt32(); nPatch.Relink = br.ReadUInt32(); nPatch.Compressed = br.ReadUInt32() != 0; nPatch.IsNew = br.ReadUInt32() == 1; //Custom if (!nPatch.IsRelink) { if (nPatch.CompressedSize != 0) { nPatch.Stream = new Substream(ms, oaAuther, nPatch.CompressedSize); } else { throw new InvalidDataException("File length is 0, but not relinking."); } } // Use the last file patch if (patches.ContainsKey(nPatch.Hash)) { Console.ForegroundColor = ConsoleColor.Red; #if DEBUG Console.WriteLine("The file {0} has been included multiple times. Using the one from {1}.", HashList.HashList.NameFromHash(nPatch.Hash), patchname); #endif patches[nPatch.Hash].Dispose(); patches.Remove(nPatch.Hash); Console.ResetColor(); } patches.Add(nPatch.Hash, nPatch); //Global checks if (!KH2Changed && nPatch.IsInKH2 || nPatch.IsInKH2Sub) { KH2Changed = true; } else if (!OVLChanged && nPatch.IsInOVL) { OVLChanged = true; } else if (!ISOChanged && nPatch.IsinISO) { ISOChanged = true; } if (nPatch.IsNew) { AddToNewFiles(nPatch); } br.Seek(60, SeekOrigin.Current); } } }