Пример #1
0
 public ulong Read(AssetsFileReader reader, ulong filePos)
 {
     reader.bigEndian = false;
     header           = reader.ReadStringLength(4);
     if (header != "cldb")
     {
         return(reader.Position);
     }
     fileVersion = reader.ReadByte();
     if (fileVersion != 3)
     {
         return(reader.Position);
     }
     compressionType = reader.ReadByte();
     if (compressionType != 0)
     {
         return(reader.Position);
     }
     compressedSize    = reader.ReadUInt32();
     uncompressedSize  = reader.ReadUInt32();
     unityVersionCount = reader.ReadByte();
     pUnityVersions    = new string[unityVersionCount];
     for (int i = 0; i < unityVersionCount; i++)
     {
         pUnityVersions[i] = reader.ReadCountString();
     }
     stringTableLen = reader.ReadUInt32();
     stringTablePos = reader.ReadUInt32();
     return(reader.Position);
 }
Пример #2
0
        public bool Read(AssetsFileReader reader, bool prefReplacersInMemory = false)
        {
            reader.bigEndian = false;

            magic = reader.ReadStringLength(4);
            if (magic != "EMIP")
            {
                return(false);
            }

            includesCldb = reader.ReadByte() != 0;

            modName        = reader.ReadCountStringInt16();
            modCreators    = reader.ReadCountStringInt16();
            modDescription = reader.ReadCountStringInt16();

            if (includesCldb)
            {
                addedTypes = new ClassDatabaseFile();
                addedTypes.Read(reader);
                //get past the string table since the reader goes back to the beginning
                reader.Position = addedTypes.header.stringTablePos + addedTypes.header.stringTableLen;
            }
            else
            {
                addedTypes = null;
            }

            int affectedFilesCount = reader.ReadInt32();

            affectedFiles = new List <InstallerPackageAssetsDesc>();
            for (int i = 0; i < affectedFilesCount; i++)
            {
                List <object> replacers         = new List <object>();
                InstallerPackageAssetsDesc desc = new InstallerPackageAssetsDesc()
                {
                    isBundle = reader.ReadByte() != 0,
                    path     = reader.ReadCountStringInt16()
                };
                int replacerCount = reader.ReadInt32();
                for (int j = 0; j < replacerCount; j++)
                {
                    object repObj = ParseReplacer(reader, prefReplacersInMemory);
                    if (repObj is AssetsReplacer repAsset)
                    {
                        replacers.Add(repAsset);
                    }
                    else if (repObj is BundleReplacer repBundle)
                    {
                        replacers.Add(repBundle);
                    }
                }
                desc.replacers = replacers;
                affectedFiles.Add(desc);
            }

            return(true);
        }
Пример #3
0
 public ulong Read(AssetsFileReader reader, ulong filePos, int version)
 {
     typeName = new ClassDatabaseFileString();
     typeName.Read(reader, reader.Position);
     fieldName = new ClassDatabaseFileString();
     fieldName.Read(reader, reader.Position);
     depth   = reader.ReadByte();
     isArray = reader.ReadByte();
     size    = reader.ReadUInt32();
     version = reader.ReadUInt16();
     flags2  = reader.ReadUInt32();
     return(reader.Position);
 }
Пример #4
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);
 }
Пример #5
0
 public uint   flags;                        //0x14
 public ulong Read(ulong absFilePos, AssetsFileReader reader, bool bigEndian)
 {
     version          = reader.ReadUInt16();
     depth            = reader.ReadByte();
     isArray          = reader.ReadBoolean();
     typeStringOffset = reader.ReadUInt32();
     nameStringOffset = reader.ReadUInt32();
     size             = reader.ReadUInt32();
     index            = reader.ReadUInt32();
     flags            = reader.ReadUInt32();
     return(reader.Position);
 }
Пример #6
0
 public ulong Read(ulong absFilePos, AssetsFileReader reader, bool bigEndian)
 {
     guid = new GUID128();
     guid.Read(reader.Position, reader);
     bufferedPath = new byte[] { reader.ReadByte() }; //todo: why
     type         = reader.ReadInt32();
     assetPath    = reader.ReadNullTerminated();
     if (assetPath.StartsWith("library/"))
     {
         assetPath = "Resources\\" + assetPath.Substring(8);
     }
     return(reader.Position);
 }
        public void Read(AssetsFileReader reader, int version)
        {
            typeName = new ClassDatabaseFileString();
            typeName.Read(reader);
            fieldName = new ClassDatabaseFileString();
            fieldName.Read(reader);
            depth   = reader.ReadByte();
            isArray = reader.ReadByte();
            size    = reader.ReadInt32();
            switch (version)
            {
            case 1:
                flags2 = reader.ReadUInt32();
                break;

            case 3:
            case 4:
                this.version = reader.ReadUInt16();
                flags2       = reader.ReadUInt32();
                break;
            }
        }
Пример #8
0
        private void addFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            ofd.DefaultExt = "";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                string possibleBundleHeader;
                int    possibleFormat;
                string emptyVersion;
                using (FileStream fs = File.OpenRead(ofd.FileName))
                    using (AssetsFileReader reader = new AssetsFileReader(fs))
                    {
                        if (fs.Length < 0x20)
                        {
                            MessageBox.Show("File too small. Are you sure this is a unity file?", "Assets View");
                            return;
                        }
                        possibleBundleHeader = reader.ReadStringLength(7);
                        reader.Position      = 0x08;
                        possibleFormat       = reader.ReadInt32();
                        reader.Position      = 0x14;

                        string possibleVersion = "";
                        char   curChar;
                        while ((curChar = (char)reader.ReadByte()) != 0x00 && possibleVersion.Length < 100)
                        {
                            possibleVersion += curChar;
                        }
                        emptyVersion = Regex.Replace(possibleVersion, "[a-zA-Z0-9\\.]", "");
                    }
                if (possibleBundleHeader == "UnityFS")
                {
                    LoadBundleFile(ofd.FileName);
                }
                else if (possibleFormat < 0xFF && emptyVersion == "")
                {
                    LoadAssetsFile(ofd.FileName);
                }
                else
                {
                    MessageBox.Show("Couldn't detect file type. Are you sure this is a unity file?", "Assets View");
                }
            }
        }
Пример #9
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;
     }
 }
Пример #10
0
        public static DetectedFileType DetectFileType(string filePath)
        {
            string possibleBundleHeader;
            int    possibleFormat;
            string emptyVersion;

            using (FileStream fs = File.OpenRead(filePath))
                using (AssetsFileReader r = new AssetsFileReader(fs))
                {
                    if (fs.Length < 0x20)
                    {
                        return(DetectedFileType.Unknown);
                    }
                    possibleBundleHeader = r.ReadStringLength(7);
                    r.Position           = 0x08;
                    possibleFormat       = r.ReadInt32();
                    r.Position           = 0x14;

                    string possibleVersion = "";
                    char   curChar;
                    while (r.Position < r.BaseStream.Length && (curChar = (char)r.ReadByte()) != 0x00)
                    {
                        possibleVersion += curChar;
                        if (possibleVersion.Length < 0xFF)
                        {
                            break;
                        }
                    }
                    emptyVersion = Regex.Replace(possibleVersion, "[a-zA-Z0-9\\.]", "");
                }
            if (possibleBundleHeader == "UnityFS")
            {
                return(DetectedFileType.BundleFile);
            }
            else if (possibleFormat < 0xFF && emptyVersion == "")
            {
                return(DetectedFileType.AssetsFile);
            }
            return(DetectedFileType.Unknown);
        }
Пример #11
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);
 }
Пример #12
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);
        }
Пример #13
0
        public AssetTypeValueField ReadType(AssetsFileReader reader, ulong filePos, AssetTypeValueField valueField, bool bigEndian)
        {
            if (valueField.templateField.isArray)
            {
                if (valueField.templateField.childrenCount == 2)
                {
                    EnumValueTypes sizeType = valueField.templateField.children[0].valueType;
                    if (sizeType == EnumValueTypes.ValueType_Int32 ||
                        sizeType == EnumValueTypes.ValueType_UInt32)
                    {
                        valueField.childrenCount = reader.ReadUInt32();
                        valueField.pChildren     = new AssetTypeValueField[valueField.childrenCount];
                        for (int i = 0; i < valueField.childrenCount; i++)
                        {
                            valueField.pChildren[i] = new AssetTypeValueField();
                            valueField.pChildren[i].templateField = valueField.templateField.children[1];
                            valueField.pChildren[i] = ReadType(reader, reader.Position, valueField.pChildren[i], bigEndian);
                        }
                        if (valueField.templateField.align)
                        {
                            reader.Align();
                        }
                        AssetTypeArray ata = new AssetTypeArray();
                        ata.size         = valueField.childrenCount;
                        valueField.value = new AssetTypeValue(EnumValueTypes.ValueType_Array, 0);
                        valueField.value.Set(ata);
                    }
                    else
                    {
                        Debug.WriteLine("Invalid array value type! Found an unexpected " + sizeType.ToString() + " type instead!");
                    }
                }
                else
                {
                    Debug.WriteLine("Invalid array!");
                }
            }
            else
            {
                EnumValueTypes type = valueField.templateField.valueType;
                if (type != 0)
                {
                    valueField.value = new AssetTypeValue(type, 0);
                }
                if (type == EnumValueTypes.ValueType_String)
                {
                    valueField.value.Set(reader.ReadCountStringInt32());
                    reader.Align();
                }
                else
                {
                    valueField.childrenCount = valueField.templateField.childrenCount;
                    if (valueField.childrenCount == 0)
                    {
                        valueField.pChildren = new AssetTypeValueField[0];
                        switch (valueField.templateField.valueType)
                        {
                        case EnumValueTypes.ValueType_Int8:
                            valueField.value.Set(reader.ReadSByte());
                            if (valueField.templateField.align)
                            {
                                reader.Align();
                            }
                            break;

                        case EnumValueTypes.ValueType_UInt8:
                        case EnumValueTypes.ValueType_Bool:
                            valueField.value.Set(reader.ReadByte());
                            if (valueField.templateField.align)
                            {
                                reader.Align();
                            }
                            break;

                        case EnumValueTypes.ValueType_Int16:
                            valueField.value.Set(reader.ReadInt16());
                            if (valueField.templateField.align)
                            {
                                reader.Align();
                            }
                            break;

                        case EnumValueTypes.ValueType_UInt16:
                            valueField.value.Set(reader.ReadUInt16());
                            if (valueField.templateField.align)
                            {
                                reader.Align();
                            }
                            break;

                        case EnumValueTypes.ValueType_Int32:
                            valueField.value.Set(reader.ReadInt32());
                            break;

                        case EnumValueTypes.ValueType_UInt32:
                            valueField.value.Set(reader.ReadUInt32());
                            break;

                        case EnumValueTypes.ValueType_Int64:
                            valueField.value.Set(reader.ReadInt64());
                            break;

                        case EnumValueTypes.ValueType_UInt64:
                            valueField.value.Set(reader.ReadUInt64());
                            break;

                        case EnumValueTypes.ValueType_Float:
                            valueField.value.Set(reader.ReadSingle());
                            break;

                        case EnumValueTypes.ValueType_Double:
                            valueField.value.Set(reader.ReadDouble());
                            break;
                        }
                    }
                    else
                    {
                        valueField.pChildren = new AssetTypeValueField[valueField.childrenCount];
                        for (int i = 0; i < valueField.childrenCount; i++)
                        {
                            valueField.pChildren[i] = new AssetTypeValueField();
                            valueField.pChildren[i].templateField = valueField.templateField.children[i];
                            valueField.pChildren[i] = ReadType(reader, reader.Position, valueField.pChildren[i], bigEndian);
                        }
                    }
                }
            }
            return(valueField);
        }