private static void ExtractIDX(KH1ISOReader input, string tfolder = "export/") { for (int i = 0, idxC = input.idxEntries.Count; i < idxC; ++i) { IDXEntry entry = input.idxEntries[i]; bool compressed = entry.flags == 1; string name2; if (!HashList.pairs.TryGetValue(entry.hash, out name2)) { name2 = String.Format("@noname/{0:x8}.bin", entry.hash); } if (name2 == "system.cnf") { continue; } if (name2 == "SLPS_251.98") { continue; } if (name2 == "ioprp250.img") { continue; } if (name2 == "sio2man.irx") { continue; } if (name2 == "sio2d.irx") { continue; } if (name2 == "dbcman.irx") { continue; } if (name2 == "ds2o.irx") { continue; } if (name2 == "mcman.irx") { continue; } if (name2 == "mcserv.irx") { continue; } if (name2 == "libsd.irx") { continue; } if (name2 == "libssl.irx") { continue; } if (name2 == "dev9.irx") { continue; } if (name2 == "atad.irx") { continue; } if (name2 == "hdd.irx") { continue; } if (name2 == "pfs.irx") { continue; } if (name2 == "kingdom.idx") { continue; } if (name2 == "kingdom.img") { continue; } var idxs = new List <Tuple <IDXFile, string> >(); if (_advanced) { Console.WriteLine("-----------File {0,4}/{1}, using KINGDOM.IDX\n", i, input.idxEntries.Count - 1); Console.WriteLine("Hashed filename: {0}", entry.hash); Console.WriteLine("Compression flags: {0}", compressed); Console.WriteLine("Size (packed): {0}", entry.size); Console.WriteLine("Real name: {0}", name2); } else { Console.WriteLine("[KINGDOM: {0,4}/{1}]\tExtracting {2}", i, input.idxEntries.Count - 1, name2); } string filename = tfolder + "/KINGDOM/" + name2; Directory.CreateDirectory(Path.GetDirectoryName(filename)); bool adSize = _advanced; byte[] file = input.readFile(entry); if (compressed) { if (entry.size > int.MaxValue) { throw new NotSupportedException("File to big to decompress"); } try { byte[] decompressed = KH1Compressor.decompress(file, adSize); File.WriteAllBytes(filename, decompressed); } catch (Exception e) { WriteError(" ERROR: Failed to decompress: " + e.Message); } } else { File.WriteAllBytes(filename, file); } } }
public void WriteDecrypted(Stream stream) { stream.Position = 0; uint changeLen = 0, creditLen = 0; changeLen = Changelogs.Aggregate(changeLen, (current, b) => current + (4 + (uint)b.Length)); creditLen = Credits.Aggregate(creditLen, (current, b) => current + (4 + (uint)b.Length)); using (var bw = new BinaryStream(stream, leaveOpen: true)) { uint i; bw.Write(Signature); bw.Write((uint)(16 + _Author.Length)); bw.Write((uint)(16 + _Author.Length + 16 + changeLen + 4 + creditLen + _OtherInfo.Length)); bw.Write(Version); bw.Write(_Author); bw.Write((uint)12); bw.Write(16 + changeLen); bw.Write(16 + changeLen + 4 + creditLen); bw.Write(i = (uint)Changelogs.Count); i *= 4; foreach (var b in Changelogs) { bw.Write(i); i += (uint)b.Length; } foreach (var b in Changelogs) { bw.Write(b); } bw.Write(i = (uint)Credits.Count); i *= 4; foreach (var b in Credits) { bw.Write(i); i += (uint)b.Length; } foreach (var b in Credits) { bw.Write(b); } bw.Write(_OtherInfo); bw.Write((uint)Files.Count); //Check total size to add long fileTotal = 0; try { fileTotal = Files.Where(file => file.Relink == 0) .Aggregate(fileTotal, (current, file) => checked (current + file.Data.Length)); } catch (OverflowException) { ISOTP.WriteError( "That's WAY too much file data... is there even that much in the gameo.O?\r\nTry to split up the patch..."); return; } Stream filedata = null; string filename = null; //Use a MemoryStream if we can, much cleaner\faster if (fileTotal <= int.MaxValue) { try { filedata = new MemoryStream((int)fileTotal); } catch (OutOfMemoryException) { filedata = null; ISOTP.WriteWarning("Failed to allocate enough memory, trying temporary file fallback..."); } } //If we can't use a MemStream (or that failed), try a FileStream as a temp file if (filedata == null) { filename = Path.GetTempFileName(); Console.WriteLine("Wow there's a lot of file data! Using a temporary file now!\r\nUsing {0}", filename); filedata = File.Open(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.None); } using (filedata) { i = (uint)(stream.Position + Files.Count * 92); foreach (FileEntry file in Files) { bw.Write(file.Hash); if (file.Relink != 0) { bw.Write((uint)0); bw.Write((uint)0); bw.Write((uint)0); bw.Write(file.ParentHash); bw.Write(file.Relink); bw.Write((uint)0); } else { uint cSize; file.Data.Position = 0; if (file.IsCompressed) { try { var input = new byte[file.Data.Length]; file.Data.Read(input, 0, (int)file.Data.Length); Console.Write("Compressing {0}: ", file.name ?? file.Hash.ToString("X8")); byte[] output = KH1Compressor.compress(input); uint cSizeSectors = (uint)Math.Ceiling((double)output.Length / 2048) - 1; if (output.LongLength > int.MaxValue) { throw new NotSupportedException( "Compressed data too big to store (Program limitation)"); } if (cSizeSectors > 0x2FFF) { throw new NotSupportedException( "Compressed data too big to store (IDX limitation)"); } if ((cSizeSectors & 0x1000u) == 0x1000u) { throw new NotSupportedException( "Compressed data size hit 0x1000 bit limitation (IDX limitation)"); } cSize = (uint)output.Length; filedata.Write(output, 0, output.Length); } catch (NotCompressableException e) { string es = "ERROR: Failed to compress file: " + e.Message; ISOTP.WriteWarning(es); Console.Write("Add it without compressing? [Y/n] "); if (Program.GetYesNoInput()) { file.IsCompressed = false; cSize = (uint)file.Data.Length; file.Data.Position = 0; //Ensure at beginning file.Data.CopyTo(filedata); } else { throw new NotCompressableException(es, e); } } } else { Console.WriteLine("Adding {0}", file.name ?? file.Hash.ToString("X8")); cSize = (uint)file.Data.Length; file.Data.Position = 0; //Ensure at beginning file.Data.CopyTo(filedata); } if (!file.IsCompressed && (((uint)Math.Ceiling((double)cSize / 2048) - 1) & 0x1000u) == 0x1000u) { ISOTP.WriteWarning( "Data size hit 0x1000 bit limitation, but this file may be OK if it's streamed."); } bw.Write(i); i += cSize; bw.Write(cSize); bw.Write((uint)file.Data.Length); bw.Write(file.ParentHash); bw.Write((uint)0); bw.Write((uint)(file.IsCompressed ? 1 : 0)); } bw.Write((uint)(file.IsNewFile ? 1 : 0)); //Custom //Padding bw.Write((uint)0); bw.Write((uint)0); bw.Write((uint)0); bw.Write((uint)0); bw.Write((uint)0); bw.Write((uint)0); bw.Write((uint)0); bw.Write((uint)0); bw.Write((uint)0); bw.Write((uint)0); bw.Write((uint)0); bw.Write((uint)0); bw.Write((uint)0); bw.Write((uint)0); bw.Write((uint)0); } filedata.Position = 0; //Ensure at beginning filedata.CopyTo(stream); } //If we used a temp file, delete it if (filename != null) { File.Delete(filename); } } }