Exemplo n.º 1
0
        private void ReadAssetsPreloadTable(EndianBinaryReader reader, int fileFormatVersion, uint dataOffset)
        {
            var assetCount          = reader.ReadInt32();
            var assetUniqueIDFormat = "D" + MathHelper.GetDigitCount(assetCount);

            var preloadDataList = new AssetPreloadData[assetCount];

            for (var i = 0; i < assetCount; ++i)
            {
                if (fileFormatVersion >= 14)
                {
                    reader.AlignBy(4);
                }

                var preloadData = new AssetPreloadData(this);
                preloadDataList[i] = preloadData;

                if (fileFormatVersion < 14)
                {
                    preloadData.PathID = reader.ReadInt32();
                }
                else
                {
                    preloadData.PathID = reader.ReadInt64();
                }

                var offset = reader.ReadUInt32();
                offset            += dataOffset;
                preloadData.Offset = offset;

                preloadData.Size = reader.ReadInt32();

                int type1;
                int type2;
                if (fileFormatVersion > 15)
                {
                    var index = reader.ReadInt32();
                    var t     = _classIDs[index];
                    type1 = t.Type1;
                    type2 = t.Type2;
                }
                else
                {
                    type1            = reader.ReadInt32();
                    type2            = reader.ReadUInt16();
                    reader.Position += 2;
                }

                preloadData.Type1 = type1;
                preloadData.Type2 = type2;

                if (fileFormatVersion == 15)
                {
                    var dummyByte = reader.ReadByte();
                    if (dummyByte == 0)
                    {
                    }
                }

                if (ClassIDReference.TryGetClassName(type2, out var typeName))
                {
                    preloadData.TypeName = typeName;
                }
                else
                {
                    preloadData.TypeName = $"#{type2}";
                }

                preloadData.UniqueID = i.ToString(assetUniqueIDFormat);

                if (fileFormatVersion == 6 && type2 == 141)
                {
                    var nextAssetPosition = reader.Position;
                    var buildSettings     = new BuildSettings(reader, preloadData.Offset, fileFormatVersion, VersionComponents, BuildType);
                    Version         = buildSettings.Version;
                    reader.Position = nextAssetPosition;
                }
            }

            PreloadDataList = preloadDataList;
        }
Exemplo n.º 2
0
        private void Initialize(EndianBinaryReader reader, string fileName)
        {
            var tableSize         = reader.ReadInt32();
            var dataEnd           = reader.ReadInt32();
            var fileFormatVersion = reader.ReadInt32();
            var dataOffset        = reader.ReadUInt32();

            FileFormatVersion = fileFormatVersion;
            FullFileName      = Path.GetFullPath(fileName);

            var baseDefinitions = false;
            var platform        = 0;

            switch (fileFormatVersion)
            {
            case 6:
                reader.Position  = dataEnd - tableSize;
                reader.Position += 1;
                break;

            case 7:
                reader.Position  = dataEnd - tableSize;
                reader.Position += 1;
                Version          = reader.ReadStringToNull();
                break;

            case 8:
                reader.Position  = dataEnd - tableSize;
                reader.Position += 1;
                Version          = reader.ReadStringToNull();
                platform         = reader.ReadInt32();
                break;

            case 9:
                reader.Position += 4;
                Version          = reader.ReadStringToNull();
                platform         = reader.ReadInt32();
                break;

            case 14:
            case 15:
            case 16:
            case 17:
                reader.Position += 4;
                Version          = reader.ReadStringToNull();
                platform         = reader.ReadInt32();
                baseDefinitions  = reader.ReadBoolean();
                break;

            default:
                throw new FormatException();
            }

            if (platform > 255 || platform < 0)
            {
                platform      = EndianHelper.SwapEndian(platform);
                reader.Endian = Endian.LittleEndian;
            }
            Platform = (AssetPlatform)platform;

            ReadClasses(reader, fileFormatVersion, baseDefinitions);

            if (7 <= fileFormatVersion && fileFormatVersion < 14)
            {
                reader.Position += 4;
            }

            ReadAssetsPreloadTable(reader, fileFormatVersion, dataOffset);

            // May be buggy...
            // The original author assumes these two properties are not used in Unity 2.5.x (in BuildSettings class).
            VersionComponents = VersionSplitter
                                .Split(Version)
                                .Select(str => Convert.ToInt32(str))
                                .ToArray();
            BuildType = BuildTypePattern.Match(Version).Groups["build"].Value;

            // 2017.x version handling is solved by better pattern splitting, so we skipped here.

            if (fileFormatVersion >= 14)
            {
                var someCount = reader.ReadInt32();
                for (var i = 0; i < someCount; ++i)
                {
                    var dummy1 = reader.ReadInt32();
                    reader.AlignBy(4);
                    var pathID = reader.ReadInt64();
                }
            }

            var sharedFileCount = reader.ReadInt32();
            var sharedFileList  = new SharedAssetInfo[sharedFileCount];

            for (var i = 0; i < sharedFileCount; ++i)
            {
                var shared = new SharedAssetInfo();
                shared.SomeName  = reader.ReadStringToNull();
                reader.Position += 20;
                var sharedFileName = reader.ReadStringToNull();
                shared.FileName   = sharedFileName;
                sharedFileList[i] = shared;
            }
            SharedAssetList = sharedFileList;
        }
Exemplo n.º 3
0
        private static IReadOnlyDictionary <string, object> Read(EndianBinaryReader reader, IReadOnlyList <ClassMember> classMembers, int startIndex, int baseLevel, bool fastReturn)
        {
            var dict = new Dictionary <string, object>();

            for (var i = startIndex; i < classMembers.Count; ++i)
            {
                var member = classMembers[i];
                var level  = member.Level;

                if (level <= baseLevel && fastReturn)
                {
                    return(dict);
                }

                var varName     = member.Name;
                var varType     = member.TypeName;
                var shouldAlign = (member.Flags & 0x4000) != 0;

                object value;
                IReadOnlyList <ClassMember> subList;
                switch (varType)
                {
                case "SInt8":
                    value = reader.ReadSByte();
                    break;

                case "UInt8":
                    value = reader.ReadByte();
                    break;

                case "SInt16":
                case "short":
                    value = reader.ReadInt16();
                    break;

                case "UInt16":
                case "unsigned short":
                    value = reader.ReadUInt16();
                    break;

                case "SInt32":
                case "int":
                    value = reader.ReadInt32();
                    break;

                case "UInt32":
                case "unsigned int":
                    value = reader.ReadUInt32();
                    break;

                case "SInt64":
                case "long long":
                    value = reader.ReadInt64();
                    break;

                case "UInt64":
                case "unsigned long long":
                    value = reader.ReadUInt64();
                    break;

                case "float":
                    value = reader.ReadSingle();
                    break;

                case "double":
                    value = reader.ReadDouble();
                    break;

                case "bool":
                    value = reader.ReadBoolean();
                    break;

                case "string":
                    var strLen = reader.ReadInt32();
                    value = reader.ReadAlignedString(strLen);
                    i    += 3;
                    break;

                case "Array":
                    if (i > 0 && (classMembers[i - 1].Flags & 0x4000) != 0)
                    {
                        shouldAlign = true;
                    }

                    var size = reader.ReadInt32();
                    subList = ReadSubObjectList(classMembers, level, i + 2);

                    var list = new List <object>();
                    for (var j = 0; j < size; ++j)
                    {
                        var d2 = Read(reader, subList);
                        list.Add(d2);
                    }

                    // '1' for "size" field.
                    i += 1 + subList.Count;

                    value = list;
                    break;

                default:
                    var customType = new CustomType {
                        TypeName = varType,
                        Name     = varName,
                        Level    = level
                    };

                    subList = ReadSubObjectList(classMembers, level, i + 1);
                    var objects = Read(reader, subList);
                    customType.Variables = objects;
                    value = customType;

                    i += subList.Count;

                    shouldAlign = false;
                    break;
                }

                dict[varName] = value;

                if (shouldAlign)
                {
                    reader.AlignBy(4);
                }
            }

            return(dict);
        }