/// <summary> /// 导入一整个目录的资源文件 /// </summary> /// <param name="directoryPath"></param> /// <param name="targetFileName"></param> public static void ImportAssets(string directoryPath, string targetFileName) { if (Directory.Exists(directoryPath)) { var files = Directory.GetFiles(directoryPath); var replList = new List <AssetsReplacer>(); //清空LOG文件 logPath = Path.GetFileNameWithoutExtension(targetFileName) + ".txt"; File.WriteAllText(logPath, "", Encoding.UTF8); for (int i = 0; i < files.Length; i++) { //锁定范围(920,1000] //if (i >= 920 && i <= 960) continue; //if (i >= 1000 && i <= 1500) continue; //if (i >= int.Parse(arr[0]) && i <= int.Parse(arr[1])) continue; var splitArr = Path.GetFileNameWithoutExtension(files[i]).Split(new string[] { "--" }, StringSplitOptions.None); string name; if (splitArr.Length == 2) { name = splitArr[1]; } else { name = splitArr[3]; } var temp = GenReplacerFromMemory(long.Parse(name), files[i], splitArr); //var temp = GenReplacerFromMemoryByJson(long.Parse(name), files[i]); if (temp != null) { replList.Add(temp); } } var inst = IEManager.AssetsFileInstance; var writer = new AssetsFileWriter(File.OpenWrite(targetFileName)); //Bundle和普通的分离操作 if (IEManager.IsBundle) { AssetBundleFile abFile = inst.parentBundle.file; var index = FindAssetsIDInBundle(inst, abFile); BundleReplacerFromAssets brfa = new BundleReplacerFromAssets(Path.GetFileName(inst.path), null, inst.file, replList, index); List <BundleReplacer> bRepList = new List <BundleReplacer>(); bRepList.Add(brfa); abFile.Write(writer, bRepList); } else { inst.file.Write(writer, 0, replList, 0); } writer.Close(); } }
private static void ApplyEmip(string[] args) { HashSet <string> flags = GetFlags(args); string emipFile = args[1]; string rootDir = args[2]; if (!File.Exists(emipFile)) { Console.WriteLine($"File {emipFile} does not exist!"); return; } InstallerPackageFile instPkg = new InstallerPackageFile(); FileStream fs = File.OpenRead(emipFile); AssetsFileReader r = new AssetsFileReader(fs); instPkg.Read(r, true); Console.WriteLine($"Installing emip..."); Console.WriteLine($"{instPkg.modName} by {instPkg.modCreators}"); Console.WriteLine(instPkg.modDescription); foreach (var affectedFile in instPkg.affectedFiles) { string affectedFileName = Path.GetFileName(affectedFile.path); string affectedFilePath = Path.Combine(rootDir, affectedFile.path); if (affectedFile.isBundle) { string decompFile = $"{affectedFilePath}.decomp"; string modFile = $"{affectedFilePath}.mod"; string bakFile = GetNextBackup(affectedFilePath); if (bakFile == null) { return; } if (flags.Contains("-md")) { decompFile = null; } Console.WriteLine($"Decompressing {affectedFileName} to {decompFile??"memory"}..."); AssetBundleFile bun = DecompressBundle(affectedFilePath, decompFile); List <BundleReplacer> reps = new List <BundleReplacer>(); foreach (var rep in affectedFile.replacers) { var bunRep = (BundleReplacer)rep; if (bunRep is BundleReplacerFromAssets) { //read in assets files from the bundle for replacers that need them string assetName = bunRep.GetOriginalEntryName(); var bunRepInf = BundleHelper.GetDirInfo(bun, assetName); long pos = bun.bundleHeader6.GetFileDataOffset() + bunRepInf.offset; bunRep.Init(bun.reader, pos, bunRepInf.decompressedSize); } reps.Add(bunRep); } Console.WriteLine($"Writing {modFile}..."); FileStream mfs = File.OpenWrite(modFile); AssetsFileWriter mw = new AssetsFileWriter(mfs); bun.Write(mw, reps, instPkg.addedTypes); //addedTypes does nothing atm mfs.Close(); bun.Close(); Console.WriteLine($"Swapping mod file..."); File.Move(affectedFilePath, bakFile); File.Move(modFile, affectedFilePath); if (!flags.Contains("-kd") && !flags.Contains("-md") && File.Exists(decompFile)) { File.Delete(decompFile); } Console.WriteLine($"Done."); } else //isAssetsFile { string modFile = $"{affectedFilePath}.mod"; string bakFile = GetNextBackup(affectedFilePath); if (bakFile == null) { return; } FileStream afs = File.OpenRead(affectedFilePath); AssetsFileReader ar = new AssetsFileReader(afs); AssetsFile assets = new AssetsFile(ar); List <AssetsReplacer> reps = new List <AssetsReplacer>(); foreach (var rep in affectedFile.replacers) { var assetsReplacer = (AssetsReplacer)rep; reps.Add(assetsReplacer); } Console.WriteLine($"Writing {modFile}..."); FileStream mfs = File.OpenWrite(modFile); AssetsFileWriter mw = new AssetsFileWriter(mfs); assets.Write(mw, 0, reps, 0, instPkg.addedTypes); mfs.Close(); ar.Close(); Console.WriteLine($"Swapping mod file..."); File.Move(affectedFilePath, bakFile); File.Move(modFile, affectedFilePath); Console.WriteLine($"Done."); } } return; }
private static void BatchImport(string[] args) { string mainFileName = GetMainFileName(args); HashSet <string> flags = GetFlags(args); HashSet <string> files = GetAllFilesFromBatchFile(mainFileName); foreach (string file in files) { string decompFile = $"{file}.decomp"; if (flags.Contains("-md")) { decompFile = null; } if (!File.Exists(file)) { Console.WriteLine($"File {file} does not exist!"); return; } Console.WriteLine($"Decompressing {file} to {decompFile}..."); AssetBundleFile bun = DecompressBundle(file, decompFile); List <BundleReplacer> reps = new List <BundleReplacer>(); List <Stream> streams = new List <Stream>(); int entryCount = bun.bundleInf6.dirInf.Length; for (int i = 0; i < entryCount; i++) { string name = bun.bundleInf6.dirInf[i].name; string matchName = Path.Combine(file, $"{Path.GetFileName(file)}_{name}.assets"); if (File.Exists(matchName)) { FileStream fs = File.OpenRead(matchName); long length = fs.Length; reps.Add(new BundleReplacerFromStream(matchName, matchName, true, fs, 0, length)); streams.Add(fs); Console.WriteLine($"Importing {matchName}..."); } } //I guess uabe always writes to .decomp even if //the bundle is already decompressed, that way //here it can be used as a temporary file. for //now I'll write to memory since having a .decomp //file isn't guaranteed here byte[] data; using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter w = new AssetsFileWriter(ms)) { bun.Write(w, reps); data = ms.ToArray(); } Console.WriteLine($"Writing changes to {file}..."); //uabe doesn't seem to compress here foreach (Stream stream in streams) { stream.Close(); } bun.Close(); bun.reader.Close(); File.WriteAllBytes(file, data); if (!flags.Contains("-kd") && !flags.Contains("-md") && File.Exists(decompFile)) { File.Delete(decompFile); } Console.WriteLine("Done."); } }