Example #1
0
 static int ProcessFile(string FileInput)
 {
     if (!File.Exists(FileInput))
     {
         Console.WriteLine("ERROR: Specified file doesn't exist."); Console.Read(); return(1);
     }
     using (BinaryReader Reader = new BinaryReader(File.Open(FileInput, FileMode.Open, FileAccess.Read, FileShare.Read))) MagicInputFile = Reader.ReadInt32();
     if (MagicInputFile == MagicChunk)
     {
         Console.WriteLine("Chunk file detected.");
         if (!File.Exists($"{AppDomain.CurrentDomain.BaseDirectory}\\oo2core_5_win64.dll"))
         {
             Console.WriteLine("ERROR: oo2core_5_win64.dll is missing. Can't decompress chunk file.");
             if (!FlagAutoConfirm)
             {
                 Console.Read();
             }
             return(2);
         }
         Chunk.DecompressChunks(FileInput, FlagPKGExtraction, FlagAutoConfirm, FlagUnpackAll, FlagPKGDelete);
         if (!FlagAutoConfirm)
         {
             Console.Read();
         }
         return(0);
     }
     else if (MagicInputFile == MagicPKG)
     {
         Console.WriteLine("PKG file detected.");
         PKG.ExtractPKG(FileInput, FlagPKGExtraction, FlagAutoConfirm, FlagUnpackAll, FlagPKGDelete);
         if (!FlagAutoConfirm)
         {
             Console.Read();
         }
         return(0);
     }
     else
     {
         Console.WriteLine($"ERROR: Invalid magic {MagicInputFile.ToString("X8")}.");
         if (!FlagAutoConfirm)
         {
             Console.Read();
         }
         return(0);
     }
 }
Example #2
0
        public static void DecompressChunks(String FileInput, bool FlagAutoConfirm, bool FlagUnpackAll, bool FlagBaseGame)
        {
            string       NamePKG = $"{Environment.CurrentDirectory}\\{Path.GetFileNameWithoutExtension(FileInput)}.pkg";
            BinaryReader Reader  = new BinaryReader(File.Open(FileInput, FileMode.Open, FileAccess.Read, FileShare.Read));

            // Key = ChunkOffset, Value = ChunkSize
            Dictionary <long, long> MetaChunk = new Dictionary <long, long>();

            // Read header
            Reader.BaseStream.Seek(4, SeekOrigin.Begin);
            int    ChunkCount = Reader.ReadInt32(); int ChunkPadding = ChunkCount.ToString().Length;
            double DiskSpace = (Int64)ChunkCount * (Int64)0x40000 * 1e-9;

            Utils.Print($"{ChunkCount} chunks in this file. Requires at least: {Math.Round(DiskSpace, 2)} GB.", false);

            // Read file list
            long totalChunkSize = 0;

            for (int i = 0; i < ChunkCount; i++)
            {
                // Process file size
                byte[] ArrayTmp1      = new byte[8];
                byte[] ArrayChunkSize = Reader.ReadBytes(3);
                //int Low = ArrayChunkSize[0] & 0x0F;
                int High = ArrayChunkSize[0] >> 4;
                ArrayChunkSize[0] = BitConverter.GetBytes(High)[0];
                Array.Copy(ArrayChunkSize, ArrayTmp1, ArrayChunkSize.Length);
                long ChunkSize = BitConverter.ToInt64(ArrayTmp1, 0);
                ChunkSize       = (ChunkSize >> 4) + (ChunkSize & 0xF);
                totalChunkSize += ChunkSize;

                // Process offset
                byte[] ArrayTmp2        = new byte[8];
                byte[] ArrayChunkOffset = Reader.ReadBytes(5);
                Array.Copy(ArrayChunkOffset, ArrayTmp2, ArrayChunkOffset.Length);
                long ChunkOffset = BitConverter.ToInt64(ArrayTmp2, 0);

                MetaChunk.Add(ChunkOffset, ChunkSize);
                // Console.WriteLine((i + 1).ToString("D8") + "," + ChunkOffset + "," + ChunkSize);
            }
            //Console.WriteLine(totalChunkSize);

            // Write decompressed chunks to pkg
            BinaryWriter Writer    = new BinaryWriter(File.Create(NamePKG));
            int          DictCount = 1;

            foreach (KeyValuePair <long, long> Entry in MetaChunk)
            {
                Console.Write($"\rProcessing {DictCount.ToString().PadLeft(ChunkPadding)} / {ChunkCount}...");
                if (Entry.Value != 0)
                {
                    Reader.BaseStream.Seek(Entry.Key, SeekOrigin.Begin);
                    byte[] ChunkCompressed   = Reader.ReadBytes((int)Entry.Value); // Unsafe cast
                    byte[] ChunkDecompressed = Utils.Decompress(ChunkCompressed, ChunkCompressed.Length, 0x40000);
                    if (!FlagBaseGame)
                    {
                        Utils.DecryptChunk(ChunkDecompressed, Utils.GetChunkKey(DictCount - 1));
                    }
                    Writer.Write(ChunkDecompressed);
                }
                else
                {
                    Reader.BaseStream.Seek(Entry.Key, SeekOrigin.Begin);
                    byte[] ChunkDecompressed = Reader.ReadBytes(0x40000);
                    if (!FlagBaseGame)
                    {
                        Utils.DecryptChunk(ChunkDecompressed, Utils.GetChunkKey(DictCount - 1));
                    }
                    Writer.Write(ChunkDecompressed);
                }
                DictCount++;
            }
            Reader.Close();
            Writer.Close();

            Utils.Print("Finished.", true);
            Utils.Print($"Output at: {NamePKG}", false);

            // Write csv
            Utils.Print("Writing file list.", false);
            PKG.ExtractPKG(NamePKG, FlagAutoConfirm, FlagUnpackAll, true);
        }
Example #3
0
        /* Exit Codes:
         * 0 - No error
         * 1 - Input file missing
         * 2 - oo2core_5_win64.dll file missing
         * 3 - Other exception
         */
        static int Main(string[] args)
        {
            int MagicChunk = 0x00504D43;
            int MagicPKG   = 0x20474B50;
            int MagicInputFile;

            string FileInput         = "";
            string StrPKGExtraction  = "";
            string AutoConfirm       = "";
            bool   FlagPKGExtraction = true;
            bool   FlagAutoConfirm   = false;

            Console.WriteLine("==============================");
            Utils.Print("WorldChunkTool v1.1.1 by MHVuze", false);

            // Display commands
            if (args.Length == 0)
            {
                Console.WriteLine("Usage: WorldChunkTool <chunkN_file|PKG_file> (PKGext) (AutoConf)");
                Console.WriteLine("PKGext: use 'false' to turn off PKG file extraction, defaults to 'true'");
                Console.WriteLine("AutoConf: Use 'true' to bypass confirmation prompts, defaults to 'false'");
                Console.Read();
                return(0);
            }

            // Check file
            FileInput = args[0];
            if (!File.Exists(FileInput))
            {
                Console.WriteLine("ERROR: Specified file doesn't exist."); Console.Read(); return(1);
            }

            // Turn PKG extraction output on or off
            if (args.Length > 1)
            {
                StrPKGExtraction = args[1];
            }
            if (StrPKGExtraction.Equals("false", StringComparison.InvariantCultureIgnoreCase))
            {
                FlagPKGExtraction = false; Console.WriteLine("PKG extraction turned off.");
            }

            // Accept confirmation prompts
            if (args.Length > 2)
            {
                AutoConfirm = args[2];
            }
            if (AutoConfirm.Equals("true", StringComparison.InvariantCultureIgnoreCase))
            {
                FlagAutoConfirm = true; Console.WriteLine("Auto Confirmation turned on.");
            }


            // Determine action based on file magic
            try
            {
                using (BinaryReader Reader = new BinaryReader(File.Open(FileInput, FileMode.Open))) MagicInputFile = Reader.ReadInt32();
                if (MagicInputFile == MagicChunk)
                {
                    Console.WriteLine("Chunk file detected.");
                    if (!File.Exists($"{AppDomain.CurrentDomain.BaseDirectory}\\oo2core_5_win64.dll"))
                    {
                        Console.WriteLine("ERROR: oo2core_5_win64.dll is missing. Can't decompress chunk file.");
                        if (!FlagAutoConfirm)
                        {
                            Console.Read();
                        }
                        return(2);
                    }
                    Chunk.DecompressChunks(FileInput, FlagPKGExtraction, FlagAutoConfirm);
                    if (!FlagAutoConfirm)
                    {
                        Console.Read();
                    }
                    return(0);
                }
                else if (MagicInputFile == MagicPKG)
                {
                    Console.WriteLine("PKG file detected.");
                    PKG.ExtractPKG(FileInput, FlagPKGExtraction, FlagAutoConfirm);
                    if (!FlagAutoConfirm)
                    {
                        Console.Read();
                    }
                    return(0);
                }
                else
                {
                    Console.WriteLine($"ERROR: Invalid magic {MagicInputFile.ToString("X8")}.");
                    if (!FlagAutoConfirm)
                    {
                        Console.Read();
                    }
                    return(0);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("ERROR: The following exception was caught.");
                Console.WriteLine(e);
                if (!FlagAutoConfirm)
                {
                    Console.Read();
                }
                return(3);
            }
        }
Example #4
0
        static int ProcessFile(string FileInput)
        {
            if (!File.Exists(FileInput))
            {
                Console.WriteLine("ERROR: Specified file doesn't exist."); Console.Read(); return(1);
            }
            using (BinaryReader Reader = new BinaryReader(File.Open(FileInput, FileMode.Open, FileAccess.Read, FileShare.Read))) MagicInputFile = Reader.ReadInt32();
            if (MagicInputFile == MagicChunk)
            {
                Console.WriteLine("Chunk file detected.");
                if (!File.Exists($"{AppDomain.CurrentDomain.BaseDirectory}\\oo2core_8_win64.dll"))
                {
                    Console.WriteLine("ERROR: oo2core_8_win64.dll is missing. Can't decompress chunk file.");
                    if (!FlagAutoConfirm)
                    {
                        Console.Read();
                    }
                    return(2);
                }

                // Build PKG
                if (FlagBuildPkg)
                {
                    Chunk.DecompressChunks(FileInput, FlagAutoConfirm, FlagUnpackAll, FlagBaseGame);
                }
                // On-the-fly decompression and unpacking
                else
                {
                    ChunkOTF        ChunkOtfInst = new ChunkOTF();
                    List <FileNode> FileCatalog  = new List <FileNode>();
                    string          FilePath     = $"{Environment.CurrentDirectory}\\{Path.GetFileNameWithoutExtension(FileInput)}";
                    if (FlagUnpackAll)
                    {
                        FilePath = $"{Environment.CurrentDirectory}\\chunk_combined";
                    }
                    FileCatalog = ChunkOtfInst.AnalyzeChunk(FileInput, FileCatalog, FlagBaseGame);
                    Console.WriteLine("Extracting chunk file, please wait.");
                    ChunkOtfInst.ExtractSelected(FileCatalog, FilePath, FlagBaseGame);
                    Utils.Print("\nFinished.", false);
                    if (!FlagUnpackAll)
                    {
                        Utils.Print($"Output at: {FilePath}", false);
                    }
                    if (!FlagAutoConfirm)
                    {
                        Console.WriteLine("Press Enter to quit");
                    }
                    if (!FlagAutoConfirm)
                    {
                        Console.Read();
                    }
                }

                return(0);
            }
            else if (MagicInputFile == MagicPKG)
            {
                Console.WriteLine("PKG file detected.");
                PKG.ExtractPKG(FileInput, FlagAutoConfirm, FlagUnpackAll, false);
                if (!FlagAutoConfirm)
                {
                    Console.Read();
                }
                return(0);
            }
            else
            {
                Console.WriteLine($"ERROR: Invalid magic {MagicInputFile.ToString("X8")}.");
                if (!FlagAutoConfirm)
                {
                    Console.Read();
                }
                return(0);
            }
        }
Example #5
0
        public static void DecompressChunks(String FileInput, bool FlagPKGExtraction, bool FlagAutoConfirm)
        {
            string       NamePKG = $"{Environment.CurrentDirectory}\\{Path.GetFileNameWithoutExtension(FileInput)}.pkg";
            BinaryReader Reader  = new BinaryReader(File.Open(FileInput, FileMode.Open));

            // Key = ChunkOffset, Value = ChunkSize
            Dictionary <long, long> MetaChunk = new Dictionary <long, long>();

            // Read header
            Reader.BaseStream.Seek(4, SeekOrigin.Begin);
            int ChunkCount = Reader.ReadInt32(); int ChunkPadding = ChunkCount.ToString().Length;

            Utils.Print($"{ChunkCount} chunks in this file.", false);

            // Read file list
            for (int i = 0; i < ChunkCount; i++)
            {
                // Process file size
                byte[] ArrayTmp1      = new byte[8];
                byte[] ArrayChunkSize = Reader.ReadBytes(3);
                //int Low = ArrayChunkSize[0] & 0x0F;
                int High = ArrayChunkSize[0] >> 4;
                ArrayChunkSize[0] = BitConverter.GetBytes(High)[0];
                Array.Copy(ArrayChunkSize, ArrayTmp1, ArrayChunkSize.Length);
                long ChunkSize = BitConverter.ToInt64(ArrayTmp1, 0);
                ChunkSize = (ChunkSize >> 4) + (ChunkSize & 0xF);

                // Process offset
                byte[] ArrayTmp2        = new byte[8];
                byte[] ArrayChunkOffset = Reader.ReadBytes(5);
                Array.Copy(ArrayChunkOffset, ArrayTmp2, ArrayChunkOffset.Length);
                long ChunkOffset = BitConverter.ToInt64(ArrayTmp2, 0);

                MetaChunk.Add(ChunkOffset, ChunkSize);
            }

            // Write decompressed chunks to pkg
            BinaryWriter Writer    = new BinaryWriter(File.Create(NamePKG));
            int          DictCount = 1;

            foreach (KeyValuePair <long, long> Entry in MetaChunk)
            {
                Console.Write($"\rProcessing {DictCount.ToString().PadLeft(ChunkPadding)} / {ChunkCount}...");
                if (Entry.Value != 0)
                {
                    Reader.BaseStream.Seek(Entry.Key, SeekOrigin.Begin);
                    byte[] ChunkCompressed   = Reader.ReadBytes((int)Entry.Value); // Unsafe cast
                    byte[] ChunkDecompressed = Utils.Decompress(ChunkCompressed, ChunkCompressed.Length, 0x40000);
                    Writer.Write(ChunkDecompressed);
                }
                else
                {
                    Reader.BaseStream.Seek(Entry.Key, SeekOrigin.Begin);
                    byte[] ChunkDecompressed = Reader.ReadBytes(0x40000);
                    Writer.Write(ChunkDecompressed);
                }
                DictCount++;
            }
            Reader.Close();
            Writer.Close();

            Utils.Print("Finished.", true);
            Utils.Print($"Output at: {NamePKG}", false);

            if (!FlagAutoConfirm)
            {
                Console.WriteLine("The PKG file will now be extracted. Press Enter to continue or close window to quit.");
                Console.Read();
            }

            Console.SetCursorPosition(0, Console.CursorTop - 1);
            Console.WriteLine("==============================");
            PKG.ExtractPKG(NamePKG, FlagPKGExtraction, FlagAutoConfirm);
            if (!FlagAutoConfirm)
            {
                Console.Read();
            }
        }