예제 #1
0
        /// <summary>
        /// Opens the CDNs, Versions from Ribbit and the config files from Blizzard's CDN
        /// </summary>
        public void OpenRemote(ManifestContainer manifestContainer)
        {
            if (manifestContainer?.VersionsFile == null || manifestContainer?.CDNsFile == null)
            {
                throw new Exception("Versions and CDNs files must be loaded first");
            }

            if (!manifestContainer.VersionsFile.HasLocale(manifestContainer.Locale))
            {
                throw new Exception($"Versions missing {manifestContainer.Locale} locale");
            }

            var cdnClient = new CDNClient(manifestContainer);

            if (manifestContainer.BuildConfigMD5.Value != null)
            {
                string configUrl = Helpers.GetCDNUrl(manifestContainer.BuildConfigMD5.ToString(), "config");
                BuildConfig = new KeyValueConfig(cdnClient.OpenStream(configUrl).Result, ConfigType.BuildConfig);
            }

            if (manifestContainer.CDNConfigMD5.Value != null)
            {
                string configUrl = Helpers.GetCDNUrl(manifestContainer.CDNConfigMD5.ToString(), "config");
                CDNConfig = new KeyValueConfig(cdnClient.OpenStream(configUrl).Result, ConfigType.CDNConfig);
            }

            if (PatchConfigMD5.Value != null)
            {
                string configUrl = Helpers.GetCDNUrl(PatchConfigMD5.ToString(), "config");
                PatchConfig = new KeyValueConfig(cdnClient.OpenStream(configUrl).Result, ConfigType.PatchConfig);
            }
        }
예제 #2
0
        /// <summary>
        /// Opens a stream to an entry in a remote CDN's data archives
        /// </summary>
        /// <param name="type"></param>
        /// <param name="ekey"></param>
        /// <returns></returns>
        private Stream OpenRemoteFile(IndexType type, MD5Hash ekey)
        {
            var index = GetIndexFileAndEntry(type, ekey, out var indexEntry);

            if (index == null || indexEntry == null)
            {
                return(null);
            }

            string archive = index.IsLooseIndex ? ekey.ToString() : index.Checksum.ToString();
            string url     = Helpers.GetCDNUrl(archive, type.ToString().ToLowerInvariant());

            var stream = _client.OpenStream(url, indexEntry.Offset, indexEntry.Offset + (long)indexEntry.CompressedSize - 1).Result;

            if (stream == null)
            {
                return(null);
            }

            switch (type)
            {
            case IndexType.Data:
                return(new BlockTableStreamReader(stream));

            case IndexType.Patch:
                return(stream);

            default:
                stream.Dispose();
                return(null);
            }
        }
예제 #3
0
        /// <summary>
        /// Loads an existing PatchFile from a remote CDN
        /// </summary>
        /// <param name="client"></param>
        /// <param name="ekey"></param>
        public PatchFile(CDNClient client, MD5Hash ekey) : this()
        {
            string url = Helpers.GetCDNUrl(ekey.ToString(), "patch");

            using (var stream = client.OpenStream(url).Result)
                Read(stream);
        }
예제 #4
0
        /// <summary>
        /// Loads an existing DownloadFile from a remote CDN
        /// </summary>
        /// <param name="client"></param>
        /// <param name="ekey"></param>
        public DownloadFile(CDNClient client, MD5Hash ekey) : this()
        {
            string url = Helpers.GetCDNUrl(ekey.ToString(), "data");

            using (var stream = client.OpenStream(url).Result)
                using (var bt = new BlockTableStreamReader(stream))
                    Read(bt);
        }
예제 #5
0
        /// <summary>
        /// Loads an existing EncodingFile from a remote CDN
        /// </summary>
        /// <param name="client"></param>
        /// <param name="ekey"></param>
        /// <param name="partial">Only reads the mandatory information. Prevents write support</param>
        public EncodingFile(CDNClient client, MD5Hash ekey, bool partial = false) : this()
        {
            Partial = partial;

            string url = Helpers.GetCDNUrl(ekey.ToString(), "data");

            using (var stream = client.OpenStream(url).Result)
                using (var bt = new BlockTableStreamReader(stream))
                    Read(bt);
        }
예제 #6
0
        /// <summary>
        /// Opens the CDNs, Versions from Ribbit and the config files from Blizzard's CDN
        /// </summary>
        public void OpenRemote()
        {
            var ribbit = new RibbitClient(Locale);

            using (var cdnstream = ribbit.GetStream(RibbitCommand.CDNs, Product).Result)
                using (var verstream = ribbit.GetStream(RibbitCommand.Versions, Product).Result)
                {
                    CDNsFile     = new VariableConfig(cdnstream, ConfigType.CDNs);
                    VersionsFile = new VariableConfig(verstream, ConfigType.Versions);

                    if (!VersionsFile.HasLocale(Locale))
                    {
                        throw new Exception($"Versions missing {Locale} locale");
                    }

                    var cdnClient = new CDNClient(this);

                    if (BuildConfigMD5.Value != null)
                    {
                        string configUrl = Helpers.GetCDNUrl(BuildConfigMD5.ToString(), "config");
                        BuildConfig = new KeyValueConfig(cdnClient.OpenStream(configUrl).Result, ConfigType.BuildConfig);
                    }

                    if (CDNConfigMD5.Value != null)
                    {
                        string configUrl = Helpers.GetCDNUrl(CDNConfigMD5.ToString(), "config");
                        CDNConfig = new KeyValueConfig(cdnClient.OpenStream(configUrl).Result, ConfigType.CDNConfig);
                    }

                    if (PatchConfigMD5.Value != null)
                    {
                        string configUrl = Helpers.GetCDNUrl(PatchConfigMD5.ToString(), "config");
                        PatchConfig = new KeyValueConfig(cdnClient.OpenStream(configUrl).Result, ConfigType.PatchConfig);
                    }
                }
        }
예제 #7
0
        /// <summary>
        /// Loads an IndexFile from a remote CDN
        /// </summary>
        /// <param name="stream"></param>
        public IndexFile(CDNClient client, string path, IndexType type) : this(IndexType.Unknown)
        {
            if (!path.EndsWith(".index", StringComparison.OrdinalIgnoreCase))
            {
                path += ".index";
            }

            string endpoint = type.HasFlag(IndexType.Data) ? "data" : "patch";
            string url      = Helpers.GetCDNUrl(path, endpoint);

            using (var stream = client.OpenStream(url).Result)
                Read(stream);

            Type = DetermineType(type);
        }
예제 #8
0
        private async Task <bool> TryGetRoot(UnshippedBuild model, EncodingFile encoding)
        {
            // find the zlib espec only used for a few files
            // namely root and world/liquid.tex
            var espec = encoding.ESpecStringTable.IndexOf("z");

            // attemp to filter out just the root with min size
            var files = encoding.EKeyEntries
                        .Where(x => x.ESpecIndex == espec && x.CompressedSize > Consts.MinRootSize)
                        .ToArray();

            if (files.Length == 0)
            {
                return(false);
            }

            // read the magic of each file
            var buffer = new byte[4];

            for (var i = 0; i < files.Length; i++)
            {
                var endpoint = Helpers.GetCDNUrl(files[i].EKey.ToString(), "data");
                var stream   = await Client.OpenStream(endpoint, 0, 0x1000); // arbitary peek size

                var blte = new BlockTableStreamReader(stream);
                blte.Read(buffer);

                if (BitConverter.ToUInt32(buffer) == Consts.RootMagic)
                {
                    model.Root = files[i].EKey.ToString();
                    return(true);
                }
            }

            return(false);
        }