/// <summary> /// Dumps all raw protobuf data that can be converted into proto classes. /// </summary> /// <param name="inDir">Directory that contains the raw DLC assets</param> /// <param name="outDir">Directory to write the result to.</param> /// <param name="resmap">Resource Map object instance</param> private static void DumpExtra(string inDir, string outDir, PbResMap resmap) { var dirDumpLangMap = Path.Combine(outDir, "LanguageMap"); var dirDumpDataBin = Path.Combine(outDir, "Databins"); var dirDumpLua = Path.Combine(outDir, "Lua"); var dirDumpAssetBundle = Path.Combine(outDir, "AssetBundles"); Directory.CreateDirectory(dirDumpLangMap); Directory.CreateDirectory(dirDumpDataBin); Directory.CreateDirectory(dirDumpLua); Directory.CreateDirectory(dirDumpAssetBundle); var dataBinPath = Path.Combine(inDir, "Databins.zip"); using var databinZip = ZipFile.OpenRead(dataBinPath); foreach (var(hash, name) in resmap.HashToAssetNames) { if (name.StartsWith("languagemap")) { var path = Path.Combine(inDir, "LanguageMap", $"{hash}.bytes"); var raw = File.ReadAllBytes(path); var data = DecryptAndDecompress(EncryptKey._0x9B1728AF, raw); var dest = Path.Combine(dirDumpLangMap, name); File.WriteAllBytes(dest, data); } else if (name.StartsWith("databin")) { var entry = databinZip.GetEntry($"{hash}.bytes"); var raw = ReadZipEntry(entry); var data = DecryptAndDecompress(EncryptKey._0x9B1728AF, raw); var dest = Path.Combine(dirDumpDataBin, name); File.WriteAllBytes(dest, data); } else if (name.StartsWith("lua")) { foreach (var node in resmap.ResNodeList) { if (node.AssetNameHash != hash) { continue; } var ep = resmap.ExtracPathStrPool[node.ExtractionPathId]; var lastIndex = ep.LastIndexOf('/'); var relativePath = $"{ep[(lastIndex + 1)..]}.zip";
private static void ExportResMapJson(string outDir, PbResMap resmap) { var serialized = JsonConvert.SerializeObject(resmap, Formatting.Indented); File.WriteAllText(Path.Combine(outDir, "ResMapPb.json"), serialized); }