public IEnumerable <AssetFile> BuildAssetsFileInstance(Stream stream) { List <AssetFile> result = new List <AssetFile>(); classPackage = new ClassDatabasePackage(); Console.WriteLine("Reading class-data..."); using (var reader = new AssetsFileReader(new FileStream("classdata.tpk", FileMode.Open, FileAccess.Read, FileShare.Read))) { classPackage.Read(reader); } var file = new AssetBundleFile(); activeBundleFile = file; Console.WriteLine("Reading bundleFileStream..."); file.Read(new AssetsFileReader(stream), true); file.reader.Position = 0; Stream memoryStream = new MemoryStream(); Console.WriteLine("Unpacking bundleFile..."); file.Unpack(file.reader, new AssetsFileWriter(memoryStream)); memoryStream.Position = 0; file.Close(); file = new AssetBundleFile(); file.Read(new AssetsFileReader(memoryStream)); Console.WriteLine("file.bundleInf6.dirInf.Length: " + file.bundleInf6.dirInf.Length); for (int i = 0; i < file.bundleInf6.dirInf.Length; i++) { try { if (file.IsAssetsFile(file.reader, file.bundleInf6.dirInf[i])) { byte[] assetData = BundleHelper.LoadAssetDataFromBundle(file, i); var mainStream = new MemoryStream(assetData); activeStreams.Add(mainStream); string mainName = file.bundleInf6.dirInf[i].name; var fileInstance = new AssetsFileInstance(mainStream, mainName, ""); ClassDatabaseFile classDBFile = LoadClassDatabaseFromPackage(fileInstance.file.typeTree.unityVersion); if (classDBFile == null) { Console.WriteLine("classDatabaseFile was null? Okay, that's probably bad. Continuing anyway..."); } result.Add(new AssetFile(fileInstance, classDBFile)); } } catch (Exception e) { Console.WriteLine("caught exception while reading AssetsFile: " + e); //guess it's not an assetsFile then? } } Console.WriteLine("found " + result.Count + " AssetFiles"); return(result); }
private static void BatchExport(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"; string filePath = Path.GetDirectoryName(file); if (flags.Contains("-md")) { decompFile = null; } if (!File.Exists(file)) { Console.WriteLine($"File {file} does not exist!"); return; } Console.WriteLine($"Decompressing {file}..."); AssetBundleFile bun = DecompressBundle(file, decompFile); int entryCount = bun.bundleInf6.dirInf.Length; for (int i = 0; i < entryCount; i++) { string name = bun.bundleInf6.dirInf[i].name; byte[] data = BundleHelper.LoadAssetDataFromBundle(bun, i); string outName; if (flags.Contains("-keepnames")) { outName = Path.Combine(filePath, $"{name}.assets"); } else { outName = Path.Combine(filePath, $"{Path.GetFileName(file)}_{name}.assets"); } Console.WriteLine($"Exporting {outName}..."); File.WriteAllBytes(outName, data); } bun.Close(); if (!flags.Contains("-kd") && !flags.Contains("-md") && File.Exists(decompFile)) { File.Delete(decompFile); } Console.WriteLine("Done."); } }
public void CloseActiveStreams() { for (int i = 0; i < activeStreams.Count; i++) { activeStreams[i].Dispose(); activeStreams[i] = null; } activeStreams = new List <MemoryStream>(); if (activeBundleFile != null) { activeBundleFile.Close(); activeBundleFile = null; } }
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."); } }