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); } }
//Extact function public int ExtractSelected(List <FileNode> itemlist, string BaseLocation, bool FlagBaseGame) { int failed = 0; foreach (FileNode node in itemlist) { try { if (node.Childern.Count > 0) { failed += ExtractSelected(node.Childern, BaseLocation, FlagBaseGame); } else if (node.IsSelected) { ChunkOTF CurNodeChunk = this; CurNodeChunk.cur_index = node.ChunkIndex; CurNodeChunk.cur_pointer = node.ChunkPointer; long size = node.Size; if (CurNodeChunk.ChunkCache.ContainsKey(CurNodeChunk.cur_index)) { CurNodeChunk.ChunkDecompressed = CurNodeChunk.ChunkCache[CurNodeChunk.cur_index]; } else { if (CurNodeChunk.ChunkCache.Count > 20) { CurNodeChunk.ChunkCache.Clear(); } CurNodeChunk.ChunkDecompressed = CurNodeChunk.getDecompressedChunk(CurNodeChunk.ChunkOffsetDict[CurNodeChunk.cur_index], CurNodeChunk.MetaChunk[CurNodeChunk.ChunkOffsetDict[CurNodeChunk.cur_index]], CurNodeChunk.Reader, FlagBaseGame); CurNodeChunk.ChunkCache.Add(CurNodeChunk.cur_index, CurNodeChunk.ChunkDecompressed); } if (CurNodeChunk.ChunkCache.ContainsKey(CurNodeChunk.cur_index + 1)) { CurNodeChunk.NextChunkDecompressed = CurNodeChunk.ChunkCache[CurNodeChunk.cur_index + 1]; } else { if (CurNodeChunk.ChunkCache.Count > 20) { CurNodeChunk.ChunkCache.Clear(); } if (CurNodeChunk.cur_index + 1 < CurNodeChunk.DictCount) { CurNodeChunk.NextChunkDecompressed = CurNodeChunk.getDecompressedChunk(CurNodeChunk.ChunkOffsetDict[CurNodeChunk.cur_index + 1], CurNodeChunk.MetaChunk[CurNodeChunk.ChunkOffsetDict[CurNodeChunk.cur_index + 1]], CurNodeChunk.Reader, FlagBaseGame); } else { CurNodeChunk.NextChunkDecompressed = new byte[0]; } CurNodeChunk.ChunkCache.Add(CurNodeChunk.cur_index + 1, CurNodeChunk.NextChunkDecompressed); } if (!node.IsFile) { new FileInfo(BaseLocation + node.EntireName + "\\").Directory.Create(); } else { new FileInfo(BaseLocation + node.EntireName).Directory.Create(); } if (node.IsFile) { Console.Write($"Extracting {node.EntireName} ... \r"); File.WriteAllBytes(BaseLocation + node.EntireName, CurNodeChunk.getOnLength(size, new byte[size], 0, FlagBaseGame)); } } } catch (Exception ex) { Console.WriteLine($"Error occured while extracting {node.EntireName}{node.FromChunkName}, skipped. Please try again later."); Console.WriteLine(ex.StackTrace); failed += 1; } } return(failed); }