/// <param name="idx">Left open.</param> /// <param name="img">Left open.</param> /// <param name="recurse">recursive</param> /// <param name="tfolder">Complete name</param> /// <param name="name">Complete name</param> private static void ExtractIDX(IDXFile idx, Stream img, ConsoleProgress progress, bool recurse = false,string tfolder = "export/", string name = "") { using (var imgf = new IMGFile(img, leaveOpen: true)) { var idxs = new List<Tuple<IDXFile, string>>(); uint i = 0, total = idx.Count; progress.Total += total; foreach (IDXFile.IDXEntry entry in idx) { string filename = entry.FileName(); if (recurse) { switch (entry.Hash) { case 0x0499386d: //000hb.idx case 0x0b2025ed: //000mu.idx case 0x2b87c9dc: //000di.idx case 0x2bb6ecb2: //000ca.idx case 0x35f6154a: //000al.idx case 0x3604eeef: //000tt.idx case 0x43887a92: //000po.idx case 0x4edb9e9e: //000gumi.idx case 0x608e02b4: //000es.idx case 0x60dd6d06: //000lk.idx case 0x79a2a329: //000eh.idx case 0x84eaa276: //000tr.idx case 0x904a97e0: //000wm.idx case 0xb0be1463: //000wi.idx case 0xd233219f: //000lm.idx case 0xe4633b6f: //000nm.idx case 0xeb89495d: //000bb.idx case 0xf87401c0: //000dc.idx case 0xff7a1379: //000he.idx idxs.Add(new Tuple<IDXFile, string>(new IDXFile(imgf.GetFileStream(entry)), Path.GetFileNameWithoutExtension(filename).Substring(3))); Debug.WriteLine(" Added IDX to list"); break; } } if (_advanced) { if (name == "KH2") { Console.WriteLine("-----------File {0,4}/{1}, using {2}.IDX\n", ++i, total, name); } else { if (name == "OVL") { Console.WriteLine("-----------File {0,4}/{1}, using {2}.IDX\n", ++i, total, name); } else { Console.WriteLine("-----------File {0,4}/{1}, using 000{2}.idx\n", ++i, total, name); } } Console.WriteLine("Dual Hash flag: {0}", entry.IsDualHash); //Always false but anyways Console.WriteLine("Hashed filename: {0}\nHashAlt: {1}", entry.Hash, entry.HashAlt); Console.WriteLine("Compression flags: {0}", entry.IsCompressed); Console.WriteLine("Size (packed): {0}", entry.CompressedDataLength); Console.WriteLine("Real name: {0}", filename); } else { if(oldui) { Console.WriteLine("[{2}: {0,4}/{1}]\tExtracting {3}", ++i, total, name, filename); } else { if (progress != null) { if (UISwitch) { progress.Text = string.Format("Extracting [{0}] {1}", name, filename); } else { decimal nmbpercent = (((decimal)progress.Current / (decimal)progress.Total) * 100); progress.Text = string.Format(" [{0}% Done]", (int)nmbpercent); } progress.Increment(1L); } } } filename = Path.GetFullPath(tfolder + filename); Directory.CreateDirectory(Path.GetDirectoryName(filename)); using (var output = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { bool adSize = _advanced; imgf.ReadFile(entry, output, adSize); } } if (recurse && idxs.Count != 0) { foreach (var sidx in idxs) { ExtractIDX(sidx.Item1, img, progress, false, tfolder, sidx.Item2); } } } }
/// <param name="sidx">Stream of the original idx.</param> /// <param name="simg">Stream of the original img.</param> /// <param name="timg">img of the new iso.</param> /// <param name="imgOffset">Offset of the new img in the new iso.</param> /// <param name="parenthash">Parent Hash(KH2 or OVL or 000's)</param> private static MemoryStream PatchIDXInternal(Stream sidx, Stream simg, Stream timg, long imgOffset,ConsoleProgress progress, uint parenthash = 0) { //Generate Parent name string parentname; if (parenthash == 0) { parentname = "KH2"; } else if (parenthash == 1) { parentname = "OVL"; } #if !RELEASE else if (HashList.HashList.pairs.TryGetValue(parenthash, out parentname)) { parentname = parentname.Substring(3, parentname.IndexOf('.') - 3); } else { parentname = parenthash.ToString("X8"); } #else parentname = parenthash.ToString("X8"); #endif //Need more using using (var idx = new IDXFile(sidx, leaveOpen: true)) using (var img = new IMGFile(simg, leaveOpen: true)) using (var npair = new IDXIMGWriter(timg, imgOffset, true)) { progress.Total += (long)((ulong)idx.Count); uint i = 0, total = idx.Count; foreach (IDXFile.IDXEntry file in idx) { if (oldui) { if (UISwitch) { Console.Write("[{0}: {1,4}/{2}]\t{3}", parentname, ++i, total, file.FileName()); } else { Console.Write("[{0}: {1,4}/{2}]\t{3}", parentname, ++i, total, file.Hash.ToString("X8")); } } else { if (UISwitch) { progress.Text = string.Format("Adding [{0}] {1}", parentname, file.FileName()); } else { decimal nmbpercent = (((decimal)progress.Current / (decimal)progress.Total) * 100); progress.Text = string.Format(" [{0}% Done]", (int)nmbpercent); } progress.Increment(1L); } switch (file.Hash) { case 0x0499386d: //000hb.idx case 0x0b2025ed: //000mu.idx case 0x2b87c9dc: //000di.idx case 0x2bb6ecb2: //000ca.idx case 0x35f6154a: //000al.idx case 0x3604eeef: //000tt.idx case 0x43887a92: //000po.idx case 0x4edb9e9e: //000gumi.idx case 0x608e02b4: //000es.idx case 0x60dd6d06: //000lk.idx case 0x79a2a329: //000eh.idx case 0x84eaa276: //000tr.idx case 0x904a97e0: //000wm.idx case 0xb0be1463: //000wi.idx case 0xd233219f: //000lm.idx case 0xe4633b6f: //000nm.idx case 0xeb89495d: //000bb.idx case 0xf87401c0: //000dc.idx case 0xff7a1379: //000he.idx if (oldui) { Console.WriteLine("\tRe-Building..."); } using (Substream oidx = img.GetFileStream(file)) using (MemoryStream subidx = PatchIDXInternal(oidx, simg, timg, imgOffset, progress, file.Hash)) { npair.AddFile(new IDXFile.IDXEntry { Hash = file.Hash, HashAlt = file.HashAlt, IsDualHash = file.IsDualHash, DataLength = (uint) subidx.Length, IsCompressed = false, CompressedDataLength = (uint) subidx.Length }, subidx); } continue; } PatchManager.Patch patch; // Could make sure the parents match perfectly, but there's only 1 of every name anyway. // So I'll settle for just making sure the file isn't made for the ISO. if (Patches.patches.TryGetValue(file.Hash, out patch) && /*patch.Parent == parenthash*/ !patch.IsinISO) { patch.IsNew = false; if (patch.IsRelink) { try { npair.RelinkFile(file.Hash, patch.Relink); if (oldui) { Console.WriteLine("\tRelinking..."); } } catch { progress.Total -= 1L; if (oldui) { Console.WriteLine("\tDeferred Relinking..."); } // Add the patch to be processed later, in the new file block patch.Parent = parenthash; Patches.AddToNewFiles(patch); } continue; } if (oldui) { Console.WriteLine("\tPatching..."); } #if extract Console.WriteLine("\nEXTRACTING THE FILE!"); Console.WriteLine("\nGetting the name..."); string fname2; HashList.HashList.pairs.TryGetValue(file.Hash, out fname2); Console.WriteLine("\nCreating directory..."); try { Directory.CreateDirectory(Path.GetDirectoryName(fname2)); } catch { Console.WriteLine("\nDirectory is surely null. Trying to create the file anyways..."); } Console.WriteLine("\nCreating the file..."); FileStream fileStream = File.Create(fname2); Console.WriteLine("\nConverting the stream to a byte[]..."); patch.Stream.Position = 0; var buffer = new byte[patch.Stream.Length]; for (int totalBytesCopied = 0; totalBytesCopied < patch.Stream.Length;) totalBytesCopied += patch.Stream.Read(buffer, totalBytesCopied, Convert.ToInt32(patch.Stream.Length) - totalBytesCopied); Console.WriteLine("\nConverting the int to uint..."); byte[] file2; if (patch.Compressed) { Console.WriteLine("\nThe file is compressed!"); Console.WriteLine("\nDecompressing the file..."); file2 = KH2Compressor.decompress(buffer, patch.UncompressedSize); } else { file2 = buffer; } Console.WriteLine("\nOpening the stream for the file.."); Stream decompressed = new MemoryStream(file2); Console.WriteLine("\nCopying the Stream..."); decompressed.CopyTo(fileStream); Console.WriteLine("\nDone!..."); #endif try { npair.AddFile(new IDXFile.IDXEntry { Hash = file.Hash, HashAlt = file.HashAlt, IsDualHash = file.IsDualHash, DataLength = patch.UncompressedSize, IsCompressed = patch.Compressed, CompressedDataLength = patch.CompressedSize }, patch.Stream); continue; } catch (Exception e) { WriteError(" ERROR Patching: " + e.Message); #if DEBUG WriteError(e.StackTrace); #endif } } if (oldui) { Console.WriteLine(""); } npair.AddFile(file, img.GetFileStream(file)); } //Check for new files to add List<uint> newfiles; if (Patches.newfiles.TryGetValue(parenthash, out newfiles)) { progress.Total += (long)newfiles.Count; foreach (uint hash in newfiles) { PatchManager.Patch patch; if (Patches.patches.TryGetValue(hash, out patch) && patch.IsNew) { patch.IsNew = false; string fname; #if !RELEASE if (!HashList.HashList.pairs.TryGetValue(hash, out fname)) { fname = String.Format("@noname/{0:X8}.bin", hash); } #else fname = String.Format("@noname/{0:X8}.bin", hash); #endif if (oldui) { Console.Write("[{0}: NEW]\t{1}", parentname, fname); } else { if (UISwitch) { progress.Text = string.Format("Adding [{0} : NEW] {1}", parentname, fname); } else { decimal nmbpercent = (((decimal)progress.Current / (decimal)progress.Total) * 100); progress.Text = string.Format(" [{0}% Done]", (int)nmbpercent); } progress.Increment(1L); } try { if (patch.IsRelink) { if (oldui) { Console.WriteLine("\tAdding link..."); } npair.RelinkFile(hash, patch.Relink); } else { if (oldui) { Console.WriteLine("\tAdding file..."); } npair.AddFile(new IDXFile.IDXEntry { Hash = hash, HashAlt = 0, IsDualHash = false, DataLength = patch.UncompressedSize, IsCompressed = patch.Compressed, CompressedDataLength = patch.CompressedSize }, patch.Stream); } } catch (FileNotFoundException) { Console.WriteLine(" WARNING Failed to find the file to add!"); } catch (Exception e) { WriteError(" ERROR adding file: {0}", e.Message); } } } } return npair.GetCurrentIDX(); } }
private static void ReplaceISO(Stream isofile) { var iso = new ISOFileReader (isofile); IDXFile KH2idx; IDXFile OVLidx; var KH2IDXName = iso.FindFile("KH2.IDX"); var OVLIDXName = iso.FindFile("OVL.IDX"); var KH2idxStream = iso.GetFileStream (KH2IDXName); var OVLidxStream = iso.GetFileStream (OVLIDXName); KH2idx = new IDXFile (KH2idxStream, leaveOpen: true); OVLidx = new IDXFile (OVLidxStream, leaveOpen: true); /*I need to add all sub hashes found in KH2.IMG: * case 0x0499386d: //000hb.idx case 0x0b2025ed: //000mu.idx case 0x2b87c9dc: //000di.idx case 0x2bb6ecb2: //000ca.idx case 0x35f6154a: //000al.idx case 0x3604eeef: //000tt.idx case 0x43887a92: //000po.idx case 0x4edb9e9e: //000gumi.idx case 0x608e02b4: //000es.idx case 0x60dd6d06: //000lk.idx case 0x79a2a329: //000eh.idx case 0x84eaa276: //000tr.idx case 0x904a97e0: //000wm.idx case 0xb0be1463: //000wi.idx case 0xd233219f: //000lm.idx case 0xe4633b6f: //000nm.idx case 0xeb89495d: //000bb.idx case 0xf87401c0: //000dc.idx case 0xff7a1379: //000he.idx */ Console.WriteLine ("I will now list all the hashes I got in memory."); foreach (IDXFile.IDXEntry idx in OVLidx) { Console.WriteLine ("{0}", String.Format("{0:X8}", idx.Hash)); } foreach (IDXFile.IDXEntry idx in KH2idx) { Console.WriteLine ("{0}", String.Format("{0:X8}", idx.Hash)); } foreach (var PatchEntry in Patches.patches) { Console.WriteLine ("Checking for hash {0} in ISO...", String.Format("{0:X8}", PatchEntry.Value.Hash)); try { /*KH2idx.FindEntryByHash(PatchEntry.Value.Hash); Console.Write("Hash found on KH2 IDX! Replacing..."); KH2idx.file.ReadUInt32(); KH2idx.file.ReadUInt32();//We don't care about compression flags/hashes do we? var IMGOffset = KH2idx.file.ReadUInt32() * 2048; //Such harmonious way to write new file size, isn't it? ;o WARNING: IT CRASHES KH2idxStream.Seek((int)KH2idxStream.Position, SeekOrigin.Begin); KH2idxStream.Write(PatchEntry.Value.CompressedSize); var KH2IMGName = iso.FindFile("KH2.IMG"); var KH2IMGStream = iso.GetFileStream (KH2IMGName); KH2IMGStream.Seek(IMGOffset, SeekOrigin.Begin); MemoryStream ms = new MemoryStream(); PatchEntry.Value.Stream.baseStream.CopyTo(ms); ms.ToArray(); KH2IMGStream.Write(ms.ToArray(), (int)KH2IMGStream.Position, ms.ToArray().Length);*/ Console.WriteLine ("Done!"); } catch { try { /* OVLidx.FindEntryByHash(PatchEntry.Value.Hash); Console.Write("Hash found on OVL IDX! Replacing..."); OVLidx.file.ReadUInt32(); OVLidx.file.ReadUInt32();//We don't care about compression flags/hashes do we? var IMGOffset = OVLidx.file.ReadUInt32() * 2048; OVLidxStream.Seek((int)OVLidxStream.Position, SeekOrigin.Begin); //Such harmonious way to write new file size, isn't it? ;o //OVLidxStream.Write(PatchEntry.Value.CompressedSize); var OVLIMGName = iso.FindFile("OVL.IMG"); var OVLIMGStream = iso.GetFileStream (OVLIMGName); OVLIMGStream.Seek(IMGOffset, SeekOrigin.Begin); MemoryStream ms = new MemoryStream(); PatchEntry.Value.Stream.baseStream.CopyTo(ms); byte[] PatchFile = ms.ToArray(); int FileLength = PatchFile.Length; int offset2 = (int)OVLIMGStream.Position; OVLIMGStream.Write(PatchFile, offset2, FileLength);*/ } catch { WriteError("No matching IDX entry were found in KH2 or OVL! Aborting replacing process..."); } } } }