public static void MergeTextArcs(string mainArc, string fillerArc, string arcOut, out bool clean, bool verbose = false) { clean = true; using (FileStream arcFile1 = File.OpenRead(mainArc)) using (FileStream arcFile2 = File.OpenRead(fillerArc)) using (FileStream arcFileO = File.Create(arcOut)) { var r1 = new ArcReader(arcFile1); var r2 = new ArcReader(arcFile2); var w = new ArcWriter(arcFileO, r1.Header, r1.Unknown1, r1.Unknown2); Dictionary <string, AssetInfo> fi1 = r1.GetFileInfo().ToDictionary(x => r1.GetString(x.NameOffset, x.NameLength)); Dictionary <string, AssetInfo> fi2 = r2.GetFileInfo().ToDictionary(x => r2.GetString(x.NameOffset, x.NameLength)); foreach (var f1 in fi1) { if (string.IsNullOrEmpty(f1.Key)) { if (verbose) { Console.Write("0"); } continue; } AssetInfo f2; if (fi2.TryGetValue(f1.Key, out f2)) { bool c; MergeTextData(r1.GetBytes(f1.Value), r2.GetBytes(f1.Value), out c, verbose); if (!c) { clean = false; } fi2.Remove(f1.Key); } if (verbose) { Console.Write("1"); } w.WriteFile(f1.Key, r1.GetBytes(f1.Value), AssetInfo.StorageType.Uncompressed, f1.Value.Unknown1, f1.Value.Unknown2, f1.Value.Unknown3); } } }
private static bool ExtractFile(string mainPath, ArcReader reader, AssetInfo fileInfo, bool verbose) { string subPath = reader.GetString(fileInfo.NameOffset, fileInfo.NameLength).Replace("/", @"\"); if (subPath.Length > 0) { string filePath = Path.Combine(mainPath, subPath); if (verbose) { Console.WriteLine(" S: " + filePath); } byte[] fileData = reader.GetBytes(fileInfo); lock (WriteLock) { if (!Directory.Exists(Path.GetDirectoryName(filePath))) { Directory.CreateDirectory(Path.GetDirectoryName(filePath)); } File.WriteAllBytes(filePath, fileData); } if (verbose) { Console.WriteLine(" F: " + filePath); } return(true); } Console.WriteLine( " Skipped FileInfo:\n" + " Offset: {0}\n" + " CSize: {1}" + " Size: {2}\n" + " StorageType: {3}", fileInfo.Offset, fileInfo.CompressedSize, fileInfo.RealSize, fileInfo.Storage); return(false); }
private static void Extract(string arc, bool verbose) { Console.WriteLine(arc); string mainPath = arc.Replace(Path.GetExtension(arc), ""); var reader = new ArcReader(File.OpenRead(arc)); AssetInfo[] fileInfos = reader.GetFileInfo().ToArray(); if (fileInfos.Length > 0) { int largestSize = fileInfos.Select(x => x.RealSize).Max(); int threads = 50000000 / largestSize; if (threads > 63) { threads = 63; } if (largestSize < 50000000) { fileInfos.AsParallel().AsUnordered().WithDegreeOfParallelism(threads).Select( x => ExtractFile(mainPath, reader, x, verbose)).Count(); } else { Console.WriteLine("Sequential."); foreach (AssetInfo x in fileInfos) { ExtractFile(mainPath, reader, x, verbose); } } } else { Console.WriteLine("Empty."); } }