Example #1
0
        private bool LoadCache(ulong build)
        {
            if (!CacheFileExists(build))
            {
                return(false);
            }

            using (Stream file = File.OpenRead(CacheFile(build)))
                using (LZ4Stream lz4Stream = new LZ4Stream(file, LZ4StreamMode.Decompress))
                    using (BinaryReader reader = new BinaryReader(lz4Stream)) {
                        if (reader.ReadUInt64() != APM_VERSION)
                        {
                            return(false);
                        }

                        int packageEntryCount = PackageEntries.Length;
                        Packages = reader.ReadArray <Types.Package>(packageEntryCount);

                        Records         = new Types.PackageRecord[packageEntryCount][];
                        PackageSiblings = new ulong[packageEntryCount][];

                        Types.CachePackageRecord[][] cacheRecords = new Types.CachePackageRecord[packageEntryCount][];

                        for (int i = 0; i < packageEntryCount; i++)
                        {
                            int recordCount = reader.ReadInt32();
                            cacheRecords[i] = reader.ReadArray <Types.CachePackageRecord>(recordCount);
                            int siblingCount = reader.ReadInt32();
                            PackageSiblings[i] = reader.ReadArray <ulong>(siblingCount);
                        }

                        Parallel.For(0, packageEntryCount, new ParallelOptions {
                            MaxDegreeOfParallelism = CASCConfig.MaxThreads
                        }, i =>
                        {
                            Types.CachePackageRecord[] cache = cacheRecords[i];
                            Records[i] = new Types.PackageRecord[cache.Length];

                            Types.Package package = Packages[i];
                            MD5Hash bundleLoadHash;
                            if (package.BundleGUID != 0)
                            {
                                bundleLoadHash = CMF.Map[package.BundleGUID].HashKey;
                            }

                            for (int j = 0; j < cache.Length; j++)
                            {
                                Types.CachePackageRecord cacheRecord   = cache[j];
                                ContentManifestFile.HashData cmfRecord = CMF.HashList[cacheRecord.Index];
                                Types.PackageRecord record             = new Types.PackageRecord {
                                    GUID   = cmfRecord.GUID,
                                    Size   = cacheRecord.Size,
                                    Flags  = cacheRecord.Flags,
                                    Offset = cacheRecord.Offset
                                };
                                if ((record.Flags & ContentFlags.Bundle) != 0)
                                {
                                    record.LoadHash = bundleLoadHash;
                                }
                                else
                                {
                                    record.LoadHash = cmfRecord.HashKey;
                                }
                                if (!FirstOccurence.ContainsKey(record.GUID))
                                {
                                    FirstOccurence.TryAdd(record.GUID, record);
                                }
                                Records[i][j] = record;
                            }
                        });
                    }

            return(true);
        }
Example #2
0
        private void LoadPackages(CASCHandler casc, ProgressReportSlave worker)
        {
            int c = 0;

            Parallel.For(0, Header.PackageCount, new ParallelOptions {
                MaxDegreeOfParallelism = CASCConfig.MaxThreads
            }, i => {
                c++;
                if (c % 1000 == 0)
                {
                    if (!Console.IsOutputRedirected)
                    {
                        Console.Out.Write($"Loading packages: {System.Math.Floor(c / (float)Header.PackageCount * 10000) / 100:F0}% ({c}/{Header.PackageCount})\r");
                    }

                    worker?.ReportProgress((int)((float)c / Header.PackageCount * 100));
                }
                Types.PackageEntry entry = PackageEntries[i];
                if (!CMF.Map.ContainsKey(entry.PackageGUID))
                {
                    return;     // lol?
                }

                EncodingEntry packageEncoding;
                if (!casc.EncodingHandler.GetEntry(CMF.Map[entry.PackageGUID].HashKey, out packageEncoding))
                {
                    return;
                }
                using (Stream packageStream = casc.OpenFile(packageEncoding.Key))
                    using (BinaryReader packageReader = new BinaryReader(packageStream)) {
                        Packages[i] = packageReader.Read <Types.Package>();

                        if (CMFHeaderCommon.IsV22((uint)Header.Build))    // todo: hack
                        //Packages[i].SiblingCount *= 2;
                        {
                            Packages[i].SiblingCount = 0;
                        }
                        if (Packages[i].SiblingCount > 0)
                        {
                            packageStream.Position = Packages[i].OffsetSiblings;
                            PackageSiblings[i]     = packageReader.ReadArray <ulong>((int)Packages[i].SiblingCount);
                        }
                        else
                        {
                            PackageSiblings[i] = new ulong[0];
                        }

                        packageStream.Position = Packages[i].OffsetRecords;
                        Types.PackageRecordRaw[] recordsRaw;
                        using (GZipStream recordGunzipped = new GZipStream(packageStream, CompressionMode.Decompress))
                            using (BinaryReader recordReader = new BinaryReader(recordGunzipped)) {
                                recordsRaw = recordReader.ReadArray <Types.PackageRecordRaw>((int)Packages[i].RecordCount);
                                Records[i] = new Types.PackageRecord[Packages[i].RecordCount];
                            }

                        for (uint j = 0; j < Packages[i].RecordCount; ++j)
                        {
                            Types.PackageRecordRaw rawRecord = recordsRaw[j];

                            ContentManifestFile.HashData recordCMF = CMF.Map[rawRecord.GUID];
                            Types.PackageRecord record             = new Types.PackageRecord {
                                GUID   = rawRecord.GUID,
                                Flags  = rawRecord.Flags,
                                Offset = rawRecord.Offset
                            };
                            if (record.Flags.HasFlag(ContentFlags.Bundle))
                            {
                                record.LoadHash = CMF.Map[Packages[i].BundleGUID].HashKey;
                            }
                            else
                            {
                                if (CMF.Map.ContainsKey(record.GUID))
                                {
                                    record.LoadHash = recordCMF.HashKey;
                                }
                            }
                            record.Size = recordCMF.Size;
                            if (!FirstOccurence.ContainsKey(record.GUID))
                            {
                                FirstOccurence[record.GUID] = record;
                            }
                            Records[i][j] = record;
                        }
                    }
            });
        }