Exemplo n.º 1
0
 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);
         }
     }
 }
Exemplo n.º 2
0
        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);
                }
            }
        }