コード例 #1
0
        public ApplicationPackageManifest(ClientHandler client, ProductHandler_Tank tankHandler, Stream stream, string name)
        {
            ClientCreateArgs_Tank args = client.CreateArgs.HandlerArgs as ClientCreateArgs_Tank ?? new ClientCreateArgs_Tank();

            var cmf = tankHandler.m_rootContentManifest;

            using (BinaryReader reader = new BinaryReader(stream)) {
                m_header = reader.Read <APMHeader>();

                if (m_header.m_buildVersion >= 12923648 || m_header.m_buildVersion < 52320)
                {
                    throw new NotSupportedException("Overwatch 1.29 or earlier is not supported");
                }

                m_entries        = reader.ReadArray <Entry>(m_header.m_entryCount);
                m_packageEntries = reader.ReadArray <PackageEntry>(m_header.m_packageCount);

                if (!VerifyEntries(cmf))
                {
                    Logger.Debug("APM", "Entry hash invalid. IV may be wrong");
                }

                m_packages       = new PackageHeader[m_header.m_packageCount];
                m_packageRecords = new PackageRecord[m_header.m_packageCount][];
                m_packageBundles = new ulong[m_header.m_packageCount][];

                int c = 0;
                using (PerfCounter _ = new PerfCounter("APM:LoadPackages"))
                    Parallel.For(0, m_header.m_packageCount, new ParallelOptions {
                        MaxDegreeOfParallelism = 4
                    }, i => {
                        c++;
                        if (c % 1000 == 0)
                        {
                            if (!Console.IsOutputRedirected)
                            {
                                Console.Out.Write($"Loading packages: {Math.Floor(c / (float)m_header.m_packageCount * 10000) / 100:F0}% ({c}/{m_header.m_packageCount})\r");
                            }
                        }

                        LoadPackage(i, client, cmf);
                    });

                if (!Console.IsOutputRedirected)
                {
                    Console.Write(new string(' ', Console.WindowWidth - 1) + "\r");
                }
            }
        }
コード例 #2
0
ファイル: APM.cs プロジェクト: Veninger/OWLib
        public APM(Stream apmStream, LookupContentByKeyDelegate lookupContentByKey)
        {
            using (BinaryReader reader = new BinaryReader(apmStream)) {
                header = reader.Read <APMHeader>();

                entries = new APMEntry[header.entryCount];
                for (int i = 0; i < header.entryCount; ++i)
                {
                    entries[i] = reader.Read <APMEntry>();
                }

                packages     = new APMPackage[header.packageCount];
                indices      = new PackageIndex[header.packageCount];
                records      = new PackageIndexRecord[header.packageCount][];
                dependencies = new uint[header.packageCount][];

                for (int i = 0; i < header.packageCount; ++i)
                {
                    packages[i] = reader.Read <APMPackage>();

                    Stream indexStream = lookupContentByKey(packages[i].packageKey);
                    using (BinaryReader indexReader = new BinaryReader(indexStream)) {
                        indices[i]           = indexReader.Read <PackageIndex>();
                        indexStream.Position = indices[i].recordsOffset;

                        using (GZipStream recordStream = new GZipStream(indexStream, CompressionMode.Decompress, true))
                            using (BinaryReader recordReader = new BinaryReader(recordStream)) {
                                PackageIndexRecord[] recs = new PackageIndexRecord[indices[i].numRecords];
                                for (int j = 0; j < indices[i].numRecords; ++j)
                                {
                                    recs[j] = recordReader.Read <PackageIndexRecord>();
                                }
                                records[i] = recs;
                            }

                        indexStream.Position = indices[i].depsOffset;
                        uint[] deps = new uint[indices[i].numDeps];
                        for (int j = 0; j < indices[i].numDeps; ++j)
                        {
                            deps[j] = indexReader.ReadUInt32();
                        }
                        dependencies[i] = deps;
                    }
                    indexStream.Close();
                    indexStream.Dispose();
                }
            }
        }