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); }
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); } } }