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 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."); } }