예제 #1
0
        private Object FindObject(int fileIndex, long pathID, bool isSafe)
        {
            if (fileIndex >= m_dependencies.Count)
            {
                if (isSafe)
                {
                    return(null);
                }
                throw new Exception($"AssetsFile with index {fileIndex} was not found in dependencies");
            }

            AssetsFilePtr filePtr = m_dependencies[fileIndex];
            IAssetsFile   file    = m_collection.FindAssetsFile(filePtr);

            if (file == null)
            {
                if (isSafe)
                {
                    return(null);
                }
                throw new Exception($"AssetsFile with index {fileIndex} was not found in collection");
            }

            Object @object = file.FindObject(pathID);

            if (@object == null)
            {
                if (isSafe)
                {
                    return(null);
                }
                throw new Exception($"Object with path ID {pathID} was not found");
            }
            return(@object);
        }
예제 #2
0
        public void Parse(Stream baseStream)
        {
            Reset();
            using (EndianStream stream = new EndianStream(baseStream, EndianType.BigEndian))
            {
                long startPosition = baseStream.Position;
                stream.AlignPosition = startPosition;
                int tableSize = stream.ReadInt32();
                if (tableSize <= 0)
                {
                    throw new Exception($"Invalid table size {tableSize} for asset file {Name}");
                }
                int dataEnd = stream.ReadInt32();
                if (dataEnd <= 0)
                {
                    throw new Exception($"Invalid data end {dataEnd} for asset file {Name}");
                }
                Generation = (FileGeneration)stream.ReadInt32();
                if (!Enum.IsDefined(typeof(FileGeneration), Generation))
                {
                    throw new Exception($"Unsuported file generation {Generation} for asset file '{Name}'");
                }
                long dataOffset = startPosition + stream.ReadUInt32();

                //reference itself because sharedFileIDs start from 1
                AssetsFilePtr dependency = new AssetsFilePtr(Name, string.Empty);
                m_dependencies.Add(dependency);

                if (IsTableAtTheEnd)
                {
                    stream.BaseStream.Position = dataEnd - tableSize;
                    stream.BaseStream.Position++;
                }
                else
                {
                    stream.BaseStream.Position += 4;
                }

                if (IsReadVersion)
                {
                    string version = stream.ReadStringZeroTerm();
                    Version.Parse(version);
                }
                if (IsReadPlatform)
                {
                    Platform = (Platform)stream.ReadUInt32();

                    // reverse stream endian
                    if ((uint)Platform > byte.MaxValue)
                    {
                        Platform          = (Platform)BitConverterExtensions.Reverse((uint)Platform);
                        stream.EndianType = EndianType.LittleEndian;
                    }

                    if (!Enum.IsDefined(typeof(Platform), Platform))
                    {
                        throw new Exception($"Unsuported platform {Platform} for asset file '{Name}'");
                    }
                }
                if (IsReadBaseDefinitions)
                {
                    BaseDefinitions = stream.ReadBoolean();
                }

                int baseCount = stream.ReadInt32();
                for (int i = 0; i < baseCount; i++)
                {
                    if (IsBase5)
                    {
                        ReadBase5(stream);
                    }
                    else
                    {
                        ReadBase(stream);
                    }
                }

                if (IsSkipZero)
                {
                    stream.BaseStream.Position += 4;
                }

                int assetCount = stream.ReadInt32();
                if (assetCount < 0)
                {
                    throw new Exception($"Invalid asset count {assetCount} for asset file {Name}");
                }

                for (int i = 0; i < assetCount; i++)
                {
                    if (IsNeedAlign)
                    {
                        stream.AlignStream(AlignType.Align4);
                    }

                    long pathID;
                    if (IsLongPathID)
                    {
                        pathID = stream.ReadInt64();
                    }
                    else
                    {
                        pathID = stream.ReadInt32();
                    }
                    long offset = dataOffset + stream.ReadUInt32();
                    int  size   = stream.ReadInt32();

                    ClassIDMap classMap;
                    if (IsReadSubClass)
                    {
                        int index = stream.ReadInt32();
                        classMap = m_classIDs[index];
                    }
                    else
                    {
                        int uniqueID = stream.ReadInt32();
                        int classID  = stream.ReadUInt16();
                        classMap = new ClassIDMap(uniqueID, classID);
                        stream.BaseStream.Position += 2;
                    }

                    if (IsSkipUnknown)
                    {
                        //this is a single byte, not an int32
                        //the next entry is aligned after this
                        //but not the last!
                        stream.BaseStream.Position++;
                    }

                    AssetInfo        assetInfo = new AssetInfo(this, pathID, classMap);
                    AssetPreloadData asset     = new AssetPreloadData(assetInfo, offset, size);
                    m_assetPreloads.Add(pathID, asset);
                }

                if (IsReadPreload)
                {
                    //this looks like a list of assets that need to be preloaded in memory before anytihng else
                    int count = stream.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        int num1 = stream.ReadInt32();
                        stream.AlignStream(AlignType.Align4);
                        long pathID = stream.ReadInt64();
                    }
                }

                int dependenciesCount = stream.ReadInt32();
                for (int i = 0; i < dependenciesCount; i++)
                {
                    string name = stream.ReadStringZeroTerm();
                    stream.BaseStream.Position += 20;
                    string fileName = stream.ReadStringZeroTerm();
                    dependency = new AssetsFilePtr(fileName, name);
                    m_dependencies.Add(dependency);
                }

                foreach (AssetPreloadData preload in m_assetPreloads.Values)
                {
                    preload.Parse(stream);
                }
            }
        }