Пример #1
0
        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));
        }
Пример #2
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);
        }
Пример #3
0
        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);
                }
        }
Пример #4
0
        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;
 }
Пример #6
0
        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);
                    }
                }
            }
        }
Пример #7
0
        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));
        }
Пример #8
0
        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));
        }
Пример #9
0
 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);
 }
Пример #10
0
        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());
                        }
                }
        }
Пример #11
0
        //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());
                        }
                }
        }
Пример #12
0
 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;
     }
 }
Пример #13
0
 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);
 }
Пример #14
0
        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);
        }
Пример #15
0
        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);
            }
        }
Пример #16
0
 public Hash128(AssetsFileReader reader)
 {
     data = reader.ReadBytes(16);
 }
Пример #17
0
        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;
            }
        }
Пример #18
0
        //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);
        }
Пример #19
0
        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);
        }
Пример #20
0
        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);
        }
Пример #21
0
        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);
        }