public static bool IsBundleDataCompressed(AssetBundleFile bundle) { AssetsFileReader reader = bundle.reader; reader.Position = bundle.bundleHeader6.GetBundleInfoOffset(); MemoryStream blocksInfoStream; AssetsFileReader memReader; int compressedSize = (int)bundle.bundleHeader6.compressedSize; byte[] uncompressedBytes; switch (bundle.bundleHeader6.GetCompressionType()) { case 1: uncompressedBytes = new byte[bundle.bundleHeader6.decompressedSize]; using (MemoryStream mstream = new MemoryStream(reader.ReadBytes(compressedSize))) { MemoryStream decoder = SevenZipHelper.StreamDecompress(mstream, compressedSize); decoder.Read(uncompressedBytes, 0, (int)bundle.bundleHeader6.decompressedSize); decoder.Dispose(); } blocksInfoStream = new MemoryStream(uncompressedBytes); break; case 2: case 3: uncompressedBytes = new byte[bundle.bundleHeader6.decompressedSize]; using (MemoryStream mstream = new MemoryStream(reader.ReadBytes(compressedSize))) { var decoder = new Lz4DecoderStream(mstream); decoder.Read(uncompressedBytes, 0, (int)bundle.bundleHeader6.decompressedSize); decoder.Dispose(); } blocksInfoStream = new MemoryStream(uncompressedBytes); break; default: blocksInfoStream = null; break; } var uncompressedInf = bundle.bundleInf6; if (bundle.bundleHeader6.GetCompressionType() != 0) { using (memReader = new AssetsFileReader(blocksInfoStream)) { memReader.Position = 0; uncompressedInf = new AssetBundleBlockAndDirectoryList06(); uncompressedInf.Read(0, memReader); } } return(uncompressedInf.blockInf.Any(inf => (inf.flags & 0x3f) != 0)); }
public bool Read(AssetsFileReader reader) { header = new ClassDatabaseFileHeader(); header.Read(reader, 0); if (header.header != "cldb" || header.fileVersion != 3 || header.compressionType != 0) { valid = false; return(valid); } classes = new List <ClassDatabaseType>(); long classTablePos = reader.BaseStream.Position; reader.BaseStream.Position = header.stringTablePos; stringTable = reader.ReadBytes((int)header.stringTableLen); reader.BaseStream.Position = classTablePos; uint size = reader.ReadUInt32(); for (int i = 0; i < size; i++) { ClassDatabaseType cdt = new ClassDatabaseType(); cdt.Read(reader, reader.Position, header.fileVersion); classes.Add(cdt); } valid = true; return(valid); }
private static byte[] FixTexture2DFast(AssetsFileInstance inst, AssetFileInfoEx inf) { AssetsFileReader r = inst.file.reader; r.Position = inf.absoluteFilePos; r.Position += (ulong)r.ReadInt32() + 4; r.Align(); r.Position += 0x48; r.Position += (ulong)r.ReadInt32() + 4; r.Align(); r.Position += 0x8; ulong filePathPos = r.Position; int assetLengthMinusFP = (int)(filePathPos - inf.absoluteFilePos); string filePath = r.ReadCountStringInt32(); string directory = Path.GetDirectoryName(inst.path); string fixedPath = Path.Combine(directory, filePath); byte[] newData = new byte[assetLengthMinusFP + 4 + fixedPath.Length]; r.Position = inf.absoluteFilePos; //imo easier to write it with binary writer than manually copy the bytes using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter w = new AssetsFileWriter(ms)) { w.bigEndian = false; w.Write(r.ReadBytes(assetLengthMinusFP)); w.WriteCountStringInt32(fixedPath); var ret = ms.ToArray(); if (ret == null) { return(null); } return(ret); } }
public override void Parse(AssetIdentifier identifier, AssetsFileReader reader, ResourceAssets resourceAssets, Dictionary <int, string> relativeFileIdToPath) { string assetName = reader.ReadCountStringInt32(); if (assetName == "RandomStart") { reader.Position += 9; int width = reader.ReadInt32(); int height = reader.ReadInt32(); int imageSize = reader.ReadInt32(); reader.Position += 52; byte[] data = reader.ReadBytes(imageSize); byte[] decodedData = AssetsTools.NET.Extra.DXTDecoders.ReadDXT1(data, width, height); using (MemoryStream stream = new MemoryStream(decodedData)) { Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb); Rectangle dimension = new Rectangle(0, 0, bmp.Width, bmp.Height); BitmapData picData = bmp.LockBits(dimension, ImageLockMode.ReadWrite, bmp.PixelFormat); picData.Stride = width * 4; IntPtr pixelStartAddress = picData.Scan0; Marshal.Copy(decodedData, 0, pixelStartAddress, decodedData.Length); bmp.UnlockBits(picData); resourceAssets.NitroxRandom = new RandomStartGenerator(bmp); } } }
private void BackgroundWorkData(object sender, DoWorkEventArgs e) { running = true; foreach (string fileName in fileNames) { AssetsFileInstance inst = am.LoadAssetsFile(fileName, true); inst.table.GenerateQuickLookupTree(); am.LoadClassDatabaseFromPackage(inst.file.typeTree.unityVersion); foreach (AssetFileInfoEx inf in inst.table.assetFileInfo) { AssetsFileReader fr = new AssetsFileReader(inst.file.readerPar); fr.bigEndian = false; fr.Position = inf.absoluteFilePos; byte[] data = fr.ReadBytes((int)inf.curFileSize); int location = SearchBytes(data, searchQuery); if (location != -1) { AssetID assetId = new AssetID(Path.GetFileName(fileName), inf.index); if (fileMatches.ContainsKey(fileName)) { fileMatches[fileName].Add(assetId); } else { fileMatches[fileName] = new List <AssetID>(); fileMatches[fileName].Add(assetId); bw.ReportProgress(0, fileName); } } } } bw.ReportProgress(0); running = false; }
public static void UnpackInfoOnly(this AssetBundleFile bundle) { AssetsFileReader reader = bundle.reader; reader.Position = 0; if (bundle.Read(reader, true)) { reader.Position = bundle.bundleHeader6.GetBundleInfoOffset(); MemoryStream blocksInfoStream; AssetsFileReader memReader; int compressedSize = (int)bundle.bundleHeader6.compressedSize; switch (bundle.bundleHeader6.GetCompressionType()) { case 1: using (MemoryStream mstream = new MemoryStream(reader.ReadBytes(compressedSize))) { blocksInfoStream = SevenZipHelper.StreamDecompress(mstream); } break; case 2: case 3: byte[] uncompressedBytes = new byte[bundle.bundleHeader6.decompressedSize]; using (MemoryStream mstream = new MemoryStream(reader.ReadBytes(compressedSize))) { var decoder = new Lz4DecoderStream(mstream); decoder.Read(uncompressedBytes, 0, (int)bundle.bundleHeader6.decompressedSize); decoder.Dispose(); } blocksInfoStream = new MemoryStream(uncompressedBytes); break; default: blocksInfoStream = null; break; } if (bundle.bundleHeader6.GetCompressionType() != 0) { using (memReader = new AssetsFileReader(blocksInfoStream)) { memReader.Position = 0; bundle.bundleInf6.Read(0, memReader); } } } }
public static byte[] LoadAssetDataFromBundle(AssetBundleFile bundle, int index) { AssetsFileReader reader = bundle.reader; int start = (int)(bundle.bundleHeader6.GetFileDataOffset() + bundle.bundleInf6.dirInf[index].offset); int length = (int)bundle.bundleInf6.dirInf[index].decompressedSize; reader.Position = start; return(reader.ReadBytes(length)); }
public static byte[] LoadAssetDataFromBundle(AssetBundleFile bundle, int index) { bundle.GetFileRange(index, out long offset, out long length); AssetsFileReader reader = bundle.reader; reader.Position = offset; return(reader.ReadBytes((int)length)); }
public ulong Read(ulong absFilePos, AssetsFileReader reader) { metadataSize = reader.ReadUInt32(); fileSize = reader.ReadUInt32(); format = reader.ReadUInt32(); offs_firstFile = reader.ReadUInt32(); endianness = reader.ReadByte(); reader.bigEndian = endianness == 1 ? true : false; unknown = reader.ReadBytes(3); return(reader.Position); }
private static byte[] AddMetadataMonobehaviour(byte[] data, long behaviourId) { //it seems unity is so broken that after something other than //gameobjects are added to the asset list, you can't add any //monobehaviour components to gameobjects after it or it crashes //anyway, since I'm stuck on this one and I can't really push //to the beginning of the list, I'll just put the info onto //the first gameobject in the scene using (MemoryStream fms = new MemoryStream(data)) using (AssetsFileReader fr = new AssetsFileReader(fms)) { fr.bigEndian = false; int componentSize = fr.ReadInt32(); List <AssetPPtr> pptrs = new List <AssetPPtr>(); for (int i = 0; i < componentSize; i++) { int fileId = fr.ReadInt32(); long pathId = fr.ReadInt64(); //this gets rid of assets that have no reference if (!(fileId == 0 && pathId == 0)) { pptrs.Add(new AssetPPtr((uint)fileId, (ulong)pathId)); } } //add reference to Metadata mb pptrs.Add(new AssetPPtr(0, (ulong)behaviourId)); int assetLengthMinusCP = (int)(data.Length - 4 - (componentSize * 12)); using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter w = new AssetsFileWriter(ms)) { w.bigEndian = false; w.Write(pptrs.Count); foreach (AssetPPtr pptr in pptrs) { w.Write(pptr.fileID); w.Write(pptr.pathID); } w.Write(fr.ReadBytes(assetLengthMinusCP)); return(ms.ToArray()); } } }
//this one has to work differently since we already modified the value field //so we save it to a stream and read from it manually so it works faster //note it may be better to loop through all objects but this would be slower //in the future, all components should be added so we won't need this private static byte[] FixGameObjectFast(AssetsFileInstance inst, AssetFileInfoEx inf, AssetTypeValueField field, ulong editDifferPid) { //dump current data to ms using (MemoryStream fms = new MemoryStream()) using (AssetsFileWriter fw = new AssetsFileWriter(fms)) { fw.bigEndian = false; field.Write(fw); fms.Position = 0; AssetsFileReader r = new AssetsFileReader(fms); r.bigEndian = false; int componentSize = r.ReadInt32(); List <AssetPPtr> pptrs = new List <AssetPPtr>(); for (int i = 0; i < componentSize; i++) { int fileId = r.ReadInt32(); long pathId = r.ReadInt64(); //this gets rid of assets that have no reference if (!(fileId == 0 && pathId == 0)) { pptrs.Add(new AssetPPtr((uint)fileId, (ulong)pathId)); } } //add reference to EditDiffer mb pptrs.Add(new AssetPPtr(0, editDifferPid)); int assetLengthMinusCP = (int)(inf.curFileSize - 4 - (componentSize * 12)); using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter w = new AssetsFileWriter(ms)) { w.bigEndian = false; w.Write(pptrs.Count); foreach (AssetPPtr pptr in pptrs) { w.Write(pptr.fileID); w.Write(pptr.pathID); } w.Write(r.ReadBytes(assetLengthMinusCP)); return(ms.ToArray()); } } }
public AssetsFileTable(AssetsFile pFile, bool readNames = true) { this.pFile = pFile; reader = new AssetsFileReader(pFile.readerPar); //todo, look back and see why I made a new reader here readerPar = pFile.readerPar; reader.bigEndian = pFile.header.endianness == 1 ? true : false; reader.BaseStream.Position = pFile.AssetTablePos; assetFileInfoCount = pFile.AssetCount; pAssetFileInfo = new AssetFileInfoEx[assetFileInfoCount]; for (int i = 0; i < assetFileInfoCount; i++) { AssetFileInfoEx assetFileInfoSet = new AssetFileInfoEx(); if (pFile.header.format >= 0x0E) { assetFileInfoSet.index = reader.ReadUInt64(); } else { assetFileInfoSet.index = reader.ReadUInt32(); } assetFileInfoSet.offs_curFile = reader.ReadUInt32(); assetFileInfoSet.curFileSize = reader.ReadUInt32(); assetFileInfoSet.curFileTypeOrIndex = reader.ReadUInt32(); if (pFile.header.format < 0x10) { assetFileInfoSet.inheritedUnityClass = reader.ReadUInt16(); } if (pFile.header.format <= 0x10) { assetFileInfoSet.scriptIndex = reader.ReadUInt16(); } if (0x0F <= pFile.header.format && pFile.header.format <= 0x10) { assetFileInfoSet.unknown1 = reader.ReadByte(); reader.ReadBytes(3); } assetFileInfoSet.absoluteFilePos = pFile.header.offs_firstFile + assetFileInfoSet.offs_curFile; assetFileInfoSet.curFileType = (uint)pFile.typeTree.pTypes_Unity5[assetFileInfoSet.curFileTypeOrIndex].classId; //todo: fix this variable (it can be from a different variable (index)) pAssetFileInfo[i] = assetFileInfoSet; } }
public ulong Read(bool hasTypeTree, ulong absFilePos, AssetsFileReader reader, uint version, uint typeVersion, bool bigEndian) { classId = reader.ReadInt32(); if (version >= 0x10) { unknown16_1 = reader.ReadByte(); } if (version >= 0x11) { scriptIndex = reader.ReadUInt16(); } if ((version < 0x11 && classId < 0) || (version >= 0x11 && scriptIndex != 0xFFFF)) { unknown1 = reader.ReadUInt32(); unknown2 = reader.ReadUInt32(); unknown3 = reader.ReadUInt32(); unknown4 = reader.ReadUInt32(); } unknown5 = reader.ReadUInt32(); unknown6 = reader.ReadUInt32(); unknown7 = reader.ReadUInt32(); unknown8 = reader.ReadUInt32(); if (hasTypeTree) { typeFieldsExCount = reader.ReadUInt32(); stringTableLen = reader.ReadUInt32(); pTypeFieldsEx = new TypeField_0D[typeFieldsExCount]; for (int i = 0; i < typeFieldsExCount; i++) { TypeField_0D typefield0d = new TypeField_0D(); typefield0d.Read(reader.Position, reader, bigEndian); pTypeFieldsEx[i] = typefield0d; } string rawStringTable = Encoding.UTF8.GetString(reader.ReadBytes((int)stringTableLen)); pStringTable = rawStringTable.Split('\0'); Array.Resize(ref pStringTable, pStringTable.Length - 1); } return(reader.Position); }
private static byte[] GetBundleData(string bunPath, int index) { AssetsFileReader r = new AssetsFileReader(File.Open(bunPath, FileMode.Open, FileAccess.Read, FileShare.Read)); AssetsBundleFile bun = new AssetsBundleFile(); bun.Read(r, true); //if the bundle doesn't have this section return empty if (index >= bun.bundleInf6.dirInf.Length) { return(new byte[0]); } AssetsBundleDirectoryInfo06 dirInf = bun.bundleInf6.dirInf[index]; int start = (int)(bun.bundleHeader6.GetFileDataOffset() + dirInf.offset); int length = (int)dirInf.decompressedSize; byte[] data; r.BaseStream.Position = start; data = r.ReadBytes(length); return(data); }
private bool GetResSTexture(TextureFile texFile, AssetContainer cont) { TextureFile.StreamingInfo streamInfo = texFile.m_StreamData; if (streamInfo.path != null && streamInfo.path != "" && cont.FileInstance.parentBundle != null) { //some versions apparently don't use archive:/ string searchPath = streamInfo.path; if (searchPath.StartsWith("archive:/")) { searchPath = searchPath.Substring(9); } searchPath = Path.GetFileName(searchPath); AssetBundleFile bundle = cont.FileInstance.parentBundle.file; AssetsFileReader reader = bundle.reader; AssetBundleDirectoryInfo06[] dirInf = bundle.bundleInf6.dirInf; for (int i = 0; i < dirInf.Length; i++) { AssetBundleDirectoryInfo06 info = dirInf[i]; if (info.name == searchPath) { reader.Position = bundle.bundleHeader6.GetFileDataOffset() + info.offset + streamInfo.offset; texFile.pictureData = reader.ReadBytes((int)streamInfo.size); texFile.m_StreamData.offset = 0; texFile.m_StreamData.size = 0; texFile.m_StreamData.path = ""; return(true); } } return(false); } else { return(true); } }
public Hash128(AssetsFileReader reader) { data = reader.ReadBytes(16); }
public TextureViewer(AssetsFileInstance inst, AssetTypeValueField baseField) { InitializeComponent(); loaded = false; TextureFile tf = TextureFile.ReadTextureFile(baseField); //bundle resS TextureFile.StreamingInfo streamInfo = tf.m_StreamData; if (streamInfo.path != null && inst.parentBundle != null) { string searchPath = streamInfo.path; if (streamInfo.path.StartsWith("archive:/")) { searchPath = searchPath.Substring(9); } searchPath = Path.GetFileName(searchPath); AssetBundleFile bundle = inst.parentBundle.file; AssetsFileReader reader = bundle.reader; AssetBundleDirectoryInfo06[] dirInf = bundle.bundleInf6.dirInf; bool foundFile = false; for (int i = 0; i < dirInf.Length; i++) { AssetBundleDirectoryInfo06 info = dirInf[i]; if (info.name == searchPath) { reader.Position = bundle.bundleHeader6.GetFileDataOffset() + info.offset + (long)streamInfo.offset; tf.pictureData = reader.ReadBytes((int)streamInfo.size); tf.m_StreamData.offset = 0; tf.m_StreamData.size = 0; tf.m_StreamData.path = ""; foundFile = true; break; } } if (!foundFile) { MessageBox.Show("resS was detected but no file was found in bundle"); } } byte[] texDat = tf.GetTextureData(inst); if (texDat != null && texDat.Length > 0) { string fmtName = ((TextureFormat)tf.m_TextureFormat).ToString().Replace("_", " "); Text = $"Texture Viewer [{fmtName}]"; loadedFileName = tf.m_Name; image = new Bitmap(tf.m_Width, tf.m_Height, PixelFormat.Format32bppArgb); Rectangle rect = new Rectangle(0, 0, image.Width, image.Height); BitmapData picData = image.LockBits(rect, ImageLockMode.ReadWrite, image.PixelFormat); picData.Stride = tf.m_Width * 4; IntPtr startAddr = picData.Scan0; Marshal.Copy(texDat, 0, startAddr, texDat.Length); image.UnlockBits(picData); image.RotateFlip(RotateFlipType.RotateNoneFlipY); x = 0; y = 0; width = image.Width; height = image.Height; sc = 1f; mouseDown = false; DoubleBuffered = true; Rectangle workingArea = Screen.PrimaryScreen.WorkingArea; int waWidth = workingArea.Width; int waHeight = workingArea.Height; int cliDiffWidth = Size.Width - ClientSize.Width; int cliDiffHeight = Size.Height - ClientSize.Height; ClientSize = new Size(Math.Min(width, waWidth - cliDiffWidth), Math.Min(height, waHeight - cliDiffHeight)); loaded = true; } }
//todo: use a faster custom bundle decompressor. currently a copy paste of unity studio's public bool Unpack(AssetsFileReader reader, AssetsFileWriter writer) { if (Read(reader, true)) { reader.Position = bundleHeader6.GetBundleInfoOffset(); MemoryStream blocksInfoStream; AssetsFileReader memReader; switch (bundleHeader6.flags & 0x3F) { case 1: blocksInfoStream = SevenZipHelper.StreamDecompress(new MemoryStream(reader.ReadBytes((int)bundleHeader6.compressedSize))); break; case 2: case 3: byte[] uncompressedBytes = new byte[bundleHeader6.decompressedSize]; using (var mstream = new MemoryStream(reader.ReadBytes((int)bundleHeader6.compressedSize))) { var decoder = new Lz4DecoderStream(mstream); decoder.Read(uncompressedBytes, 0, (int)bundleHeader6.decompressedSize); decoder.Dispose(); } blocksInfoStream = new MemoryStream(uncompressedBytes); break; default: blocksInfoStream = null; break; } if ((bundleHeader6.flags & 0x3F) != 0) { using (memReader = new AssetsFileReader(blocksInfoStream)) { bundleInf6.Read(0, memReader); } } reader.Position = bundleHeader6.GetFileDataOffset(); byte[][] blocksData = new byte[bundleInf6.blockCount][]; for (int i = 0; i < bundleInf6.blockCount; i++) { AssetsBundleBlockInfo06 info = bundleInf6.blockInf[i]; byte[] data = reader.ReadBytes((int)info.compressedSize); switch (info.flags & 0x3F) { case 0: blocksData[i] = data; break; case 1: blocksData[i] = new byte[info.decompressedSize]; using (MemoryStream mstream = new MemoryStream(data)) { MemoryStream decoder = SevenZipHelper.StreamDecompress(mstream, info.decompressedSize); decoder.Read(blocksData[i], 0, (int)info.decompressedSize); decoder.Dispose(); } break; case 2: case 3: blocksData[i] = new byte[info.decompressedSize]; using (MemoryStream mstream = new MemoryStream(data)) { var decoder = new Lz4DecoderStream(mstream); decoder.Read(blocksData[i], 0, (int)info.decompressedSize); decoder.Dispose(); } break; } } AssetsBundleHeader06 newBundleHeader6 = new AssetsBundleHeader06() { signature = bundleHeader6.signature, fileVersion = bundleHeader6.fileVersion, minPlayerVersion = bundleHeader6.minPlayerVersion, fileEngineVersion = bundleHeader6.fileEngineVersion, totalFileSize = 0, compressedSize = bundleHeader6.decompressedSize, decompressedSize = bundleHeader6.decompressedSize, flags = bundleHeader6.flags & 0x40 //set compression and block position to 0 }; ulong fileSize = newBundleHeader6.GetFileDataOffset(); for (int i = 0; i < bundleInf6.blockCount; i++) { fileSize += bundleInf6.blockInf[i].decompressedSize; } newBundleHeader6.totalFileSize = fileSize; AssetsBundleBlockAndDirectoryList06 newBundleInf6 = new AssetsBundleBlockAndDirectoryList06() { checksumLow = 0, //todo, figure out how to make real checksums, uabe sets these to 0 too checksumHigh = 0, blockCount = bundleInf6.blockCount, directoryCount = bundleInf6.directoryCount }; newBundleInf6.blockInf = new AssetsBundleBlockInfo06[newBundleInf6.blockCount]; for (int i = 0; i < newBundleInf6.blockCount; i++) { newBundleInf6.blockInf[i] = new AssetsBundleBlockInfo06(); newBundleInf6.blockInf[i].compressedSize = bundleInf6.blockInf[i].decompressedSize; newBundleInf6.blockInf[i].decompressedSize = bundleInf6.blockInf[i].decompressedSize; newBundleInf6.blockInf[i].flags = (ushort)(bundleInf6.blockInf[i].flags & 0xC0); //set compression to none } newBundleInf6.dirInf = new AssetsBundleDirectoryInfo06[newBundleInf6.directoryCount]; for (int i = 0; i < newBundleInf6.directoryCount; i++) { newBundleInf6.dirInf[i].offset = bundleInf6.dirInf[i].offset; newBundleInf6.dirInf[i].decompressedSize = bundleInf6.dirInf[i].decompressedSize; newBundleInf6.dirInf[i].flags = bundleInf6.dirInf[i].flags; newBundleInf6.dirInf[i].name = bundleInf6.dirInf[i].name; } newBundleHeader6.Write(writer, 0); newBundleInf6.Write(writer, writer.Position); for (int i = 0; i < newBundleInf6.blockCount; i++) { writer.Write(blocksData[i]); } return(true); } return(false); }
private List <AssetInfo> GetFSMInfos(AssetsFile file, AssetsFileTable table, bool hasDataField) { List <AssetInfo> assetInfos = new List <AssetInfo>(); uint assetCount = table.assetFileInfoCount; uint fsmTypeId = 0; foreach (AssetFileInfoEx info in table.assetFileInfo) { bool isMono = false; if (fsmTypeId == 0) { ushort monoType; if (file.header.format <= 0x10) { monoType = info.scriptIndex; } else { monoType = file.typeTree.unity5Types[info.curFileTypeOrIndex].scriptIndex; } if (monoType != 0xFFFF) { isMono = true; } } else if (info.curFileType == fsmTypeId) { isMono = true; } if (isMono) { AssetTypeInstance monoAti = am.GetATI(file, info); AssetExternal ext = am.GetExtAsset(curFile, monoAti.GetBaseField().Get("m_Script")); AssetTypeInstance scriptAti = am.GetExtAsset(curFile, monoAti.GetBaseField().Get("m_Script")).instance; AssetTypeInstance goAti = am.GetExtAsset(curFile, monoAti.GetBaseField().Get("m_GameObject")).instance; if (goAti == null) //found a scriptable object, oops { fsmTypeId = 0; continue; } string m_Name = goAti.GetBaseField().Get("m_Name").GetValue().AsString(); string m_ClassName = scriptAti.GetBaseField().Get("m_ClassName").GetValue().AsString(); if (m_ClassName == "PlayMakerFSM") { if (fsmTypeId == 0) { fsmTypeId = info.curFileType; } AssetsFileReader reader = file.reader; long oldPos = reader.BaseStream.Position; reader.BaseStream.Position = info.absoluteFilePos; reader.BaseStream.Position += 28; uint length = reader.ReadUInt32(); reader.ReadBytes((int)length); reader.Align(); reader.BaseStream.Position += 16; if (!hasDataField) { reader.BaseStream.Position -= 4; } uint length2 = reader.ReadUInt32(); string fsmName = Encoding.UTF8.GetString(reader.ReadBytes((int)length2)); reader.BaseStream.Position = oldPos; assetInfos.Add(new AssetInfo() { id = info.index, size = info.curFileSize, name = m_Name + "-" + fsmName }); } } } assetInfos.Sort((x, y) => x.name.CompareTo(y.name)); return(assetInfos); }
private static object ParseReplacer(AssetsFileReader reader, bool prefReplacersInMemory) { short replacerType = reader.ReadInt16(); byte fileType = reader.ReadByte(); if (fileType == 0) //BundleReplacer { string oldName = reader.ReadCountStringInt16(); string newName = reader.ReadCountStringInt16(); bool hasSerializedData = reader.ReadByte() != 0; //guess long replacerCount = reader.ReadInt64(); List <AssetsReplacer> replacers = new List <AssetsReplacer>(); for (int i = 0; i < replacerCount; i++) { AssetsReplacer assetReplacer = (AssetsReplacer)ParseReplacer(reader, prefReplacersInMemory); replacers.Add(assetReplacer); } if (replacerType == 4) //BundleReplacerFromAssets { //we have to null the assetsfile here and call init later BundleReplacer replacer = new BundleReplacerFromAssets(oldName, newName, null, replacers, 0); return(replacer); } } else if (fileType == 1) //AssetsReplacer { byte unknown01 = reader.ReadByte(); //always 1 int fileId = reader.ReadInt32(); long pathId = reader.ReadInt64(); int classId = reader.ReadInt32(); ushort monoScriptIndex = reader.ReadUInt16(); List <AssetPPtr> preloadDependencies = new List <AssetPPtr>(); int preloadDependencyCount = reader.ReadInt32(); for (int i = 0; i < preloadDependencyCount; i++) { AssetPPtr pptr = new AssetPPtr(reader.ReadInt32(), reader.ReadInt64()); preloadDependencies.Add(pptr); } if (replacerType == 0) //remover { AssetsReplacer replacer = new AssetsRemover(fileId, pathId, classId, monoScriptIndex); if (preloadDependencyCount != 0) { replacer.SetPreloadDependencies(preloadDependencies); } return(replacer); } else if (replacerType == 2) //adder/replacer? { Hash128? propertiesHash = null; Hash128? scriptHash = null; ClassDatabaseFile?classData = null; AssetsReplacer replacer; bool flag1 = reader.ReadByte() != 0; //no idea, couldn't get it to be 1 if (flag1) { throw new NotSupportedException("you just found a file with the mysterious flag1 set, send the file to nes"); } bool flag2 = reader.ReadByte() != 0; //has properties hash if (flag2) { propertiesHash = new Hash128(reader); } bool flag3 = reader.ReadByte() != 0; //has script hash if (flag3) { scriptHash = new Hash128(reader); } bool flag4 = reader.ReadByte() != 0; //has cldb if (flag4) { classData = new ClassDatabaseFile(); classData.Read(reader); } long bufLength = reader.ReadInt64(); if (prefReplacersInMemory) { byte[] buf = reader.ReadBytes((int)bufLength); replacer = new AssetsReplacerFromMemory(fileId, pathId, classId, monoScriptIndex, buf); } else { replacer = new AssetsReplacerFromStream(fileId, pathId, classId, monoScriptIndex, reader.BaseStream, reader.Position, bufLength); } if (propertiesHash != null) { replacer.SetPropertiesHash(propertiesHash.Value); } if (scriptHash != null) { replacer.SetScriptIDHash(scriptHash.Value); } if (scriptHash != null) { replacer.SetTypeInfo(classData, null, false); //idk what the last two are supposed to do } if (preloadDependencyCount != 0) { replacer.SetPreloadDependencies(preloadDependencies); } return(replacer); } } return(null); }
public async Task <bool> ExecutePlugin(Window win, AssetWorkspace workspace, List <AssetExternal> selection) { AssetExternal tex = selection[0]; AssetTypeValueField texBaseField = GetByteArrayTexture(workspace, tex); TextureFile texFile = TextureFile.ReadTextureFile(texBaseField); SaveFileDialog sfd = new SaveFileDialog(); sfd.Title = "Save texture"; sfd.Filters = new List <FileDialogFilter>() { new FileDialogFilter() { Name = "PNG file", Extensions = new List <string>() { "png" } } }; string file = await sfd.ShowAsync(win); if (file != null && file != string.Empty) { //bundle resS TextureFile.StreamingInfo streamInfo = texFile.m_StreamData; if (streamInfo.path != null && streamInfo.path != "" && tex.file.parentBundle != null) { //some versions apparently don't use archive:/ string searchPath = streamInfo.path; if (searchPath.StartsWith("archive:/")) { searchPath = searchPath.Substring(9); } searchPath = Path.GetFileName(searchPath); AssetBundleFile bundle = tex.file.parentBundle.file; AssetsFileReader reader = bundle.reader; AssetBundleDirectoryInfo06[] dirInf = bundle.bundleInf6.dirInf; bool foundFile = false; for (int i = 0; i < dirInf.Length; i++) { AssetBundleDirectoryInfo06 info = dirInf[i]; if (info.name == searchPath) { reader.Position = bundle.bundleHeader6.GetFileDataOffset() + info.offset + streamInfo.offset; texFile.pictureData = reader.ReadBytes((int)streamInfo.size); texFile.m_StreamData.offset = 0; texFile.m_StreamData.size = 0; texFile.m_StreamData.path = ""; foundFile = true; break; } } if (!foundFile) { await MessageBoxUtil.ShowDialog(win, "Error", "resS was detected but no file was found in bundle"); return(false); } } byte[] data = GetRawTextureBytes(texFile, tex.file); bool success = await TextureImportExport.ExportPng(data, file, texFile.m_Width, texFile.m_Height, (TextureFormat)texFile.m_TextureFormat); return(success); } return(false); }