public GameStream(FileSystemEntry manifestFileEntry, Game game) { ManifestFileEntry = manifestFileEntry; ManifestFile = ManifestFile.FromFileSystemEntry(manifestFileEntry); _assetReferenceToAssetLookup = new Dictionary <AssetReference, Asset>(); foreach (var asset in ManifestFile.Assets) { var assetReference = new AssetReference( asset.Header.TypeId, asset.Header.InstanceId); _assetReferenceToAssetLookup[assetReference] = asset; } var assetParseContext = new AssetParseContext(game); // Parse .bin, .relo, and .imp files simultaneously. ParseStreamFile(".bin", 3132817408u, binReader => { ParseStreamFile(".relo", 3133014016u, reloReader => { ParseStreamFile(".imp", 3132162048u, impReader => { foreach (var asset in ManifestFile.Assets) { ReadBinReloImpData( binReader, reloReader, impReader, asset, out var instanceData, out var relocationData, out var imports); asset.AssetImports = imports; if (instanceData.Length == 0) { continue; } if (Enum.IsDefined(typeof(AssetType), asset.Header.TypeId)) // TODO: Remove this. { if (AssetTypeUtility.ShouldSkipFor(asset.Header.TypeId, game.SageGame)) { Logger.Warn($"Skipped AssetType: {asset.Name.Split(':')[0]} = 0x{asset.Header.TypeId:X}"); continue; } if (AssetReaderCatalog.TryGetAssetReader(asset.Header.TypeId, out var assetReader)) { using (var instanceDataStream = new MemoryStream(instanceData, false)) using (var instanceDataReader = new BinaryReader(instanceDataStream, Encoding.ASCII, true)) { var zero = instanceDataReader.ReadUInt32(); if (zero != 0) { throw new InvalidDataException(); } asset.InstanceData = assetReader(asset, instanceDataReader, imports, assetParseContext); var assetCollection = assetParseContext.AssetStore.GetAssetCollection(asset.Header.TypeId); if (assetCollection != null) // TODO: Eventually this shouldn't be null. { assetCollection.Add(asset.InstanceData); } else { var singleAssetStorage = assetParseContext.AssetStore.GetSingleAsset(asset.Header.TypeId); if (singleAssetStorage != null) // TODO: Eventually this shouldn't be null. { singleAssetStorage.Current = (BaseAsset)asset.InstanceData; } } } } else { // TODO } } else { // TODO Logger.Info($"Missing AssetType: {asset.Name.Split(':')[0]} = 0x{asset.Header.TypeId:X}"); } } }); });
public GameStream(FileSystemEntry manifestFileEntry, Game game) { ManifestFileEntry = manifestFileEntry; ManifestFile = ManifestFile.FromFileSystemEntry(manifestFileEntry); _assetReferenceToAssetLookup = new Dictionary <AssetReference, Asset>(); foreach (var asset in ManifestFile.Assets) { var assetReference = new AssetReference( asset.Header.TypeId, asset.Header.InstanceId); _assetReferenceToAssetLookup[assetReference] = asset; } var assetParseContext = new AssetParseContext(game); // Parse .bin, .relo, and .imp files simultaneously. ParseStreamFile(".bin", 3132817408u, binReader => { ParseStreamFile(".relo", 3133014016u, reloReader => { ParseStreamFile(".imp", 3132162048u, impReader => { foreach (var asset in ManifestFile.Assets) { ReadBinReloImpData( binReader, reloReader, impReader, asset, out var instanceData, out var relocationData, out var imports); asset.AssetImports = imports; if (instanceData.Length == 0) { continue; } if (AssetReaderCatalog.TryGetAssetReader(asset.Header.TypeId, out var assetReader)) { using (var instanceDataStream = new MemoryStream(instanceData, false)) using (var instanceDataReader = new BinaryReader(instanceDataStream, Encoding.ASCII, true)) { var zero = instanceDataReader.ReadUInt32(); if (zero != 0) { throw new InvalidDataException(); } asset.InstanceData = assetReader.Parse(asset, instanceDataReader, imports, assetParseContext); } } else { // TODO } } }); });