public void WriteDecrypted(Stream stream) { ConsoleProgress consoleProgress = null; if(!Program.oldui){ consoleProgress = new ConsoleProgress(Files.Count, "Creating kh2patch...", ConsoleColor.Green);} 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; if(!fast_patch) { bw.Write(Signature); } else { bw.Write(Signature_Fast); } 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); if (Program.oldui) { Console.Write("Compressing {0}: ", file.name ?? file.Hash.ToString("X8")); } else { if (Program.UISwitch) { consoleProgress.Text = string.Format("Compressing {0}", file.name ?? file.Hash.ToString("X8")); } else { decimal nmbpercent = (((decimal)consoleProgress.Current / (decimal)consoleProgress.Total) * 100); consoleProgress.Text = string.Format(" [{0}% Done]", (int)nmbpercent); } consoleProgress.Increment(1L); } byte[] output = KH2Compressor.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 { if (Program.oldui) { Console.WriteLine("Adding {0}", file.name ?? file.Hash.ToString("X8")); } else { if (Program.UISwitch) { consoleProgress.Text = string.Format("Adding {0}", file.name ?? file.Hash.ToString("X8")); } else { decimal nmbpercent = (((decimal)consoleProgress.Current / (decimal)consoleProgress.Total) * 100); consoleProgress.Text = string.Format(" [{0}% Done]", (int)nmbpercent); } consoleProgress.Increment(1L); } 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); } if (Program.oldui){Console.WriteLine("Patch created.");} else{ consoleProgress.Text = "Patch created."; consoleProgress.Finish(); } } }
/// <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(); } }
/// <param name="idx">Stream of the idx inside the iso.</param> /// <param name="img">Stream of the img inside the iso.</param> /// <param name="imgd">File descriptor of the img file.</param> /// <param name="niso">New ISO.</param> /// <param name="IsOVL">Bool which define if the OVL should be patched</param> private static MemoryStream PatchIDX(Stream idx, Stream img, FileDescriptor imgd, ISOCopyWriter niso,ConsoleProgress progress, bool IsOVL = false) { using (idx) using (img) { niso.SeekEnd(); long imgOffset = niso.file.Position; MemoryStream idxms = PatchIDXInternal(idx, img, niso.file, imgOffset, progress, IsOVL ? 1u : 0u); imgd.ExtentLBA = (uint) imgOffset/2048; imgd.ExtentLength = (uint) (niso.file.Position - imgOffset); imgd.RecordingDate = DateTime.UtcNow; niso.PatchFile(imgd); niso.SeekEnd(); return idxms; } }
private static void ExtractISO(Stream isofile, string tfolder = "export/") { if (oldui) { using (var iso = new ISOFileReader(isofile)) { var idxs = new List<IDXFile>(); var idxnames = new List<string>(); int i = 0; foreach (FileDescriptor file in iso) { ++i; string filename = file.FullName; if (filename.EndsWith(".IDX")) { idxs.Add(new IDXFile(iso.GetFileStream(file))); idxnames.Add(Path.GetFileNameWithoutExtension(filename)); //continue; //Write the IDX too } else if (filename.EndsWith(".IMG") && idxnames.Contains(Path.GetFileNameWithoutExtension(filename))) { continue; } Console.WriteLine("[ISO: {0,3}]\tExtracting {1}", i, filename); filename = Path.GetFullPath(tfolder + "ISO/" + filename); try { Directory.CreateDirectory(Path.GetDirectoryName(filename)); } catch (IOException e) { WriteError("Failed creating directory: {0}", e.Message); continue; } using (var output = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { iso.CopyFile(file, output); } } for (i = 0; i < idxs.Count; ++i) { try { FileDescriptor file = iso.FindFile(idxnames[i] + ".IMG"); using (Substream img = iso.GetFileStream(file)) { ConsoleProgress consoleProgress = new ConsoleProgress(1L, null, ConsoleColor.Green, false); ExtractIDX(idxs[i], img, consoleProgress,true,tfolder + "" + idxnames[i] + "/", idxnames[i]); } } catch (FileNotFoundException) { WriteError("ERROR: Failed to find matching IMG for IDX"); } } } } else { ConsoleProgress consoleProgress = new ConsoleProgress(1L, null, ConsoleColor.Green); Dictionary<string, IDXFile> dictionary = new Dictionary<string, IDXFile>(); using (var iso = new ISOFileReader(isofile)) { var idxs = new List<IDXFile>(); var idxnames = new List<string>(); int i = 0; foreach (FileDescriptor file in iso) { ++i; string filename = file.FullName; if (filename.EndsWith(".IDX")) { idxs.Add(new IDXFile(iso.GetFileStream(file))); idxnames.Add(Path.GetFileNameWithoutExtension(filename)); //continue; //Write the IDX too } else if (filename.EndsWith(".IMG") && idxnames.Contains(Path.GetFileNameWithoutExtension(filename))) { continue; } if (UISwitch) { consoleProgress.Text = string.Format("Extracting [{0}] {1}", "ISO", filename); } else { decimal nmbpercent = (((decimal)consoleProgress.Current / (decimal)consoleProgress.Total) * 100); consoleProgress.Text = string.Format(" [{0}% Done]", (int)nmbpercent); } long total; consoleProgress.Total = (total = consoleProgress.Total) + 1L; consoleProgress.Update(total); filename = Path.GetFullPath(tfolder + "ISO/" + filename); try { Directory.CreateDirectory(Path.GetDirectoryName(filename)); } catch (IOException e) { consoleProgress.Color = ConsoleColor.DarkRed; consoleProgress.ReDraw(); WriteError("Failed creating directory: {0}", e.Message); continue; } using (var output = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { iso.CopyFile(file, output); } } consoleProgress.Total += dictionary.Sum((KeyValuePair<string, IDXFile> kvp) => (long)((ulong)kvp.Value.Count)); for (i = 0; i < idxs.Count; ++i) { try { FileDescriptor file = iso.FindFile(idxnames[i] + ".IMG"); using (Substream img = iso.GetFileStream(file)) { ExtractIDX(idxs[i], img, consoleProgress , true, tfolder + "" + idxnames[i] + "/", idxnames[i]); } } catch (FileNotFoundException) { consoleProgress.Color = ConsoleColor.DarkRed; consoleProgress.ReDraw(); WriteError("ERROR: Failed to find matching IMG for IDX"); } } consoleProgress.Text = "Done extracting."; consoleProgress.Finish(); } } }
/// <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="isofile">Original ISO</param> /// <param name="nisofile">New ISO file</param> private static void PatchISO(Stream isofile, Stream nisofile) { if (oldui) { using (var iso = new ISOFileReader(isofile)) using (var niso = new ISOCopyWriter(nisofile, iso)) { uint i = 0; Trivalent cKh2 = Patches.KH2Changed ? Trivalent.ChangesPending : Trivalent.NoChanges, cOvl = Patches.OVLChanged ? Trivalent.ChangesPending : Trivalent.NoChanges; bool cIso = Patches.ISOChanged; foreach (FileDescriptor file in iso) { Console.Write("[ISO: {0,4}]\t{1}", ++i, file.FullName); string name = file.FileName; if (name.EndsWith("KH2.IDX") || name.EndsWith("KH2.IMG")) { if (cKh2.HasFlag(Trivalent.ChangesPending)) { cKh2 = Trivalent.Changed; long lpos = niso.file.Position; if (oldui) { Console.WriteLine("\tRe-Building..."); } try { FileDescriptor img = iso.FindFile("KH2.IMG"), idx = iso.FindFile("KH2.IDX"); ConsoleProgress consoleProgress = new ConsoleProgress(1L, null, ConsoleColor.Green, false); using ( MemoryStream ms = PatchIDX(iso.GetFileStream(idx), iso.GetFileStream(img), img, niso, consoleProgress ) ) { idx.RecordingDate = DateTime.UtcNow; niso.AddFile2(idx, ms, name); } continue; } catch (Exception e) { WriteError(" Error creating IDX/IMG: {0}\n{1}", e.Message, e.StackTrace); niso.file.Position = lpos; } } else if (cKh2.HasFlag(Trivalent.Changed)) { Console.WriteLine("\tRe-Built"); continue; } } else if (name.EndsWith("OVL.IDX") || name.EndsWith("OVL.IMG")) { if (cOvl.HasFlag(Trivalent.ChangesPending)) { cOvl = Trivalent.Changed; long lpos = niso.file.Position; Console.WriteLine("\tRe-Building..."); try { FileDescriptor img = iso.FindFile("OVL.IMG"), idx = iso.FindFile("OVL.IDX"); ConsoleProgress consoleProgress = new ConsoleProgress(1L, null, ConsoleColor.Green, false); using ( MemoryStream ms = PatchIDX(iso.GetFileStream(idx), iso.GetFileStream(img), img, niso,consoleProgress, true)) { idx.RecordingDate = DateTime.UtcNow; niso.AddFile2(idx, ms, name); } continue; } catch (Exception e) { WriteError(" Error creating IDX/IMG: " + e.Message); niso.file.Position = lpos; } } else if (cOvl.HasFlag(Trivalent.Changed)) { Console.WriteLine("\tRe-Built"); continue; } } else if (cIso) { PatchManager.Patch patch; if (Patches.patches.TryGetValue(PatchManager.ToHash(name), out patch) && patch.IsinISO) { Console.WriteLine("\tPatching..."); file.RecordingDate = DateTime.UtcNow; niso.AddFile2(file, patch.Stream, name); continue; } } Console.WriteLine(""); niso.CopyFile(file); if (niso.SectorCount >= 0x230540) { WriteWarning( "Warning: This ISO has the size of a dual-layer ISO, but it isn't one. Some\nprograms may take a while to start while they search for the 2nd layer."); } } } } else { using (var iso = new ISOFileReader(isofile)) using (var niso = new ISOCopyWriter(nisofile, iso)) { ConsoleProgress consoleProgress = new ConsoleProgress((long)iso.Count<FileDescriptor>(), "Patching ISO...", ConsoleColor.Green); Trivalent cKh2 = Patches.KH2Changed ? Trivalent.ChangesPending : Trivalent.NoChanges, cOvl = Patches.OVLChanged ? Trivalent.ChangesPending : Trivalent.NoChanges; bool cIso = Patches.ISOChanged; foreach (FileDescriptor file in iso) { if (UISwitch) { consoleProgress.Text = string.Format("Adding [{0}] {1}", "ISO", file.FullName); } else { decimal nmbpercent = (((decimal)consoleProgress.Current / (decimal)consoleProgress.Total) * 100); consoleProgress.Text = string.Format(" [{0}% Done]", (int)nmbpercent); } consoleProgress.Increment(1L); string name = file.FileName; if (name.EndsWith("KH2.IDX") || name.EndsWith("KH2.IMG")) { if (cKh2.HasFlag(Trivalent.ChangesPending)) { cKh2 = Trivalent.Changed; long lpos = niso.file.Position; try { FileDescriptor img = iso.FindFile("KH2.IMG"), idx = iso.FindFile("KH2.IDX"); using ( MemoryStream ms = PatchIDX(iso.GetFileStream(idx), iso.GetFileStream(img), img, niso, consoleProgress, false) ) { idx.RecordingDate = DateTime.UtcNow; niso.AddFile2(idx, ms, name); } continue; } catch (Exception e) { WriteError(" Error creating IDX/IMG: {0}\n{1}", e.Message, e.StackTrace); niso.file.Position = lpos; } } else if (cKh2.HasFlag(Trivalent.Changed)) { continue; } } else if (name.EndsWith("OVL.IDX") || name.EndsWith("OVL.IMG")) { if (cOvl.HasFlag(Trivalent.ChangesPending)) { cOvl = Trivalent.Changed; long lpos = niso.file.Position; try { FileDescriptor img = iso.FindFile("OVL.IMG"), idx = iso.FindFile("OVL.IDX"); using ( MemoryStream ms = PatchIDX(iso.GetFileStream(idx), iso.GetFileStream(img), img, niso, consoleProgress, true )) { idx.RecordingDate = DateTime.UtcNow; niso.AddFile2(idx, ms, name); } continue; } catch (Exception e) { WriteError(" Error creating IDX/IMG: " + e.Message); niso.file.Position = lpos; } } else if (cOvl.HasFlag(Trivalent.Changed)) { continue; } } else if (cIso) { PatchManager.Patch patch; if (Patches.patches.TryGetValue(PatchManager.ToHash(name), out patch) && patch.IsinISO) { file.RecordingDate = DateTime.UtcNow; niso.AddFile2(file, patch.Stream, name); continue; } } niso.CopyFile(file); if (niso.SectorCount >= 0x230540) { WriteWarning( "Warning: This ISO has the size of a dual-layer ISO, but it isn't one. Some\nprograms may take a while to start while they search for the 2nd layer."); } } consoleProgress.Text = "Done patching."; consoleProgress.Finish(); } } }