Beispiel #1
0
        public GameStream(FileSystemEntry manifestFileEntry)
        {
            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;
            }

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

                            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))
                                    {
                                        asset.InstanceData = assetReader.Parse(asset, instanceDataReader, relocationData, imports);
                                    }
                            }
                            else
                            {
                                // TODO
                            }
                        }
                    });
                });
Beispiel #2
0
        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}");
                            }
                        }
                    });
                });