private static async Task <int> DumpDDSInfo(DumpDDSOptions options) { var dt = DateTime.Now; string idx = RED.CRC32.Crc32Algorithm.Compute(Encoding.ASCII.GetBytes($"{dt.Year}{dt.Month}{dt.Day}{dt.Hour}{dt.Minute}{dt.Second}")).ToString(); var outDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "DDSTest", $"ExtractedFiles_{idx}"); using (var pb = new ProgressBar()) { if (!Directory.Exists(outDir)) { Directory.CreateDirectory(outDir); } var txc = new TextureManager(); //using (var p11 = pb.Progress.Fork(0.25, "Loading TextureManager")) { txc.LoadAll("C:\\Steam\\steamapps\\common\\The Witcher 3\\bin\\x64"); } System.Console.WriteLine($"Loaded TextureManager"); //combined bundle dump // load xbm bundle infos var bundlexbmDict = new Dictionary <uint, XBMBundleInfo>(); var mc = new BundleManager(); //using (var p12 = pb.Progress.Fork(0.25, "Loading BundleManager")) { mc.LoadAll("C:\\Steam\\steamapps\\common\\The Witcher 3\\bin\\x64"); } System.Console.WriteLine($"Loaded BundleManager"); //using (var p2 = pb.Progress.Fork(0.5, "Loading Bundle Info")) using (var p2 = pb.Progress.Fork(0.5, "Bundle Info")) { var filesb = mc.FileList.Where(x => x.Name.EndsWith("xbm")).ToList(); for (int i = 0; i < filesb.Count; i++) { var f = filesb[i]; try { var buff = new byte[f.Size]; using (var s = new MemoryStream()) { f.Extract(s); using (var ms = new MemoryStream(s.ToArray())) using (var br = new BinaryReader(ms)) { var crw = new CR2WFile(); crw.Read(br); foreach (var c in crw.chunks) { if (c.data is CBitmapTexture) { var x = c.data as CBitmapTexture; if (!bundlexbmDict.ContainsKey(((CUInt32)x.GetVariableByName("textureCacheKey")).val)) { var ecompression = (CName)x.GetVariableByName("compression"); ETextureCompression compression = (ETextureCompression)Enum.Parse(typeof(ETextureCompression), ecompression.Value); var eformat = (CName)x.GetVariableByName("format"); ETextureRawFormat format = (ETextureRawFormat)Enum.Parse(typeof(ETextureRawFormat), eformat.Value); bundlexbmDict.Add(((CUInt32)x.GetVariableByName("textureCacheKey")).val, new XBMBundleInfo() { Name = f.Name, Width = (CUInt32)x.GetVariableByName("width") == null ? 0 : ((CUInt32)x.GetVariableByName("width")).val, Height = (CUInt32)x.GetVariableByName("width") == null ? 0 : ((CUInt32)x.GetVariableByName("height")).val, Format = format, Compression = compression, TextureGroup = (CName)x.GetVariableByName("textureGroup") == null ? "" : ((CName)x.GetVariableByName("textureGroup")).Value, } ); } else { } } } } } } catch (Exception ex) { throw ex; } p2.Report(i / (double)filesb.Count, $"Loading bundle entries: {i}/{filesb.Count}"); } } System.Console.WriteLine($"Loaded {bundlexbmDict.Values.Count} Bundle Entries"); using (var p3 = pb.Progress.Fork(0.5, "Cache Info")) { // Dump texture cache infos using (StreamWriter writer = File.CreateText(Path.Combine(outDir, $"__ddsdump_{idx}.txt"))) { string head = "Format1\t" + "Format2\t" + "BPP\t" + "Width\t" + "Height\t" + "Size\t" + "Mips\t" + "Slices\t" + "Cube\t" + "Unk1\t" + "Hash\t" + "Name\t"; head += "XBMFormat\t" + "XBMCompression\t" + "XBMTExtureGroup\t" ; writer.WriteLine(head); //string ext = "xbm"; //var files = txc.FileList.Where(x => x.Name.EndsWith(ext)).ToList(); var files = txc.FileList; for (int j = 0; j < files.Count; j++) { IWitcherFile f = files[j]; TextureCacheItem x = f as TextureCacheItem; string info = $"{x.Type1}/{x.Type1:X2}\t" + $"{x.Type2}/{x.Type2:X2}\t" + $"{x.BaseAlignment}\t" + $"{x.BaseWidth}\t" + $"{x.BaseHeight}\t" + $"{x.Size}\t" + $"{x.Mipcount}\t" + $"{x.SliceCount}\t" + $"{x.IsCube:X2}\t" + $"{x.Unk1}/{x.Unk1:X2}\t" + $"{x.Hash}\t" + $"{x.Name}\t" ; //info += "<"; //foreach (var y in x.MipMapInfo) //{ // info += $"<{y.Item1},{y.Item2}>"; //} //info += ">"; if (bundlexbmDict.ContainsKey(x.Hash)) { XBMBundleInfo bundleinfo = bundlexbmDict[x.Hash]; info += //$"{bundleinfo.Width}\t" + //$"{bundleinfo.Height}\t" + $"{bundleinfo.Format}\t" + $"{bundleinfo.Compression}\t" + $"{bundleinfo.TextureGroup}\t" ; } else { } //System.Console.WriteLine(info); writer.WriteLine(info); p3.Report(j / (double)files.Count, $"Dumping cache entries: {j}/{files.Count}"); } System.Console.WriteLine($"Finished dumping {files.Count} texture cache infos.\r\n"); } } } System.Console.WriteLine($"Finished.\r\n"); System.Console.ReadLine(); return(1); }
public static async Task <int> DumpDDSInfo(DumpDDSOptions options) { var dt = DateTime.Now; string idx = RED.CRC32.Crc32Algorithm.Compute(Encoding.ASCII.GetBytes($"{dt.Year}{dt.Month}{dt.Day}{dt.Hour}{dt.Minute}{dt.Second}")).ToString(); var outDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "DDSTest", $"ExtractedFiles_{idx}"); if (!Directory.Exists(outDir)) { Directory.CreateDirectory(outDir); } // load TextureManager var txc = new TextureManager(); var W3_DIR = System.Environment.GetEnvironmentVariable("W3_DIR", EnvironmentVariableTarget.User); if (!Directory.Exists(W3_DIR)) { return(0); } txc.LoadAll(W3_DIR); System.Console.WriteLine($"Loaded TextureManager"); // load BundleManager var bundlexbmDict = new Dictionary <uint, XBMBundleInfo>(); var bm = new BundleManager(); bm.LoadAll(W3_DIR); System.Console.WriteLine($"Loaded BundleManager"); var memorymappedbundles = new Dictionary <string, MemoryMappedFile>(); foreach (var b in bm.Bundles.Values) { var e = b.ArchiveAbsolutePath.GetHashMD5(); memorymappedbundles.Add(e, MemoryMappedFile.CreateFromFile(b.ArchiveAbsolutePath, FileMode.Open, e, 0, MemoryMappedFileAccess.Read)); } #region XBM DUMP const string ext = "xbm"; using (var pb = new ConsoleProgressBar.ProgressBar()) using (var p1 = pb.Progress.Fork()) { int progress = 0; var files1 = bm.FileList.Where(x => x.Name.EndsWith(ext)).ToList(); Parallel.For(0, files1.Count, new ParallelOptions { MaxDegreeOfParallelism = 8 }, i => { var f = files1[i]; if (f is BundleItem bi) { var buff = new byte[f.Size]; using (var s = new MemoryStream()) { bi.ExtractExistingMMF(s); using (var ms = new MemoryStream(s.ToArray())) using (var br = new BinaryReader(ms)) { var crw = new CR2WFile(); crw.Read(br); foreach (var c in crw.chunks) { if (!(c.data is CBitmapTexture x)) { continue; } lock (bundlexbmDict) { if (!bundlexbmDict.ContainsKey(x.TextureCacheKey.val)) { bundlexbmDict.Add(x.TextureCacheKey.val, new XBMBundleInfo() { //Name = f.Name, //Width = x.Width == null ? "NULL" : x.Width.val.ToString(), //Height = x.Height == null ? "NULL" : x.Height.val.ToString(), Format = x.Format == null ? "NULL" : x.Format.WrappedEnum.ToString(), Compression = x.Compression == null ? "NULL" : x.Compression.WrappedEnum.ToString(), TextureGroup = x.TextureGroup == null ? "NULL" : x.TextureGroup.Value, Unk = x.unk?.ToString() ?? "NULL", Unk1 = x.unk1?.ToString() ?? "NULL", Unk2 = x.unk2?.ToString() ?? "NULL", } ); } } } }