コード例 #1
0
        private void AddFilesFromManifest(Stream stream, Dictionary <int, int> baseIds)
        {
            List <Net.AssetDownloader.Asset> assets = new List <Net.AssetDownloader.Asset>();
            var  manifest = Dat.Manifest.Parse(stream);
            long size     = 0;

            lock (baseIds)
            {
                foreach (var record in manifest.records)
                {
                    int existing;
                    if (!baseIds.TryGetValue(record.baseId, out existing))
                    {
                        existing = 0;
                    }

                    if (existing != record.fileId)
                    {
                        baseIds[record.baseId] = record.fileId;

                        Net.AssetDownloader.Asset asset;
                        if (existing == 0)
                        {
                            asset = new Net.AssetDownloader.Asset(record.fileId, true, (int)(record.size * AVG_COMPRESSION + 0.5f));
                        }
                        else
                        {
                            asset = new Net.AssetDownloader.Asset(existing, record.fileId, (int)(record.size * AVG_PATCH_COMPRESSION + 0.5f));
                        }

                        asset.Complete  += file_Complete;
                        asset.Cancelled += file_Cancelled;
                        asset.Progress  += asset_Progress;

                        assets.Add(asset);

                        size += asset.size;
                    }
                }

                progress.filesTotal += assets.Count;
            }

            if (assets.Count > 0)
            {
                lock (this)
                {
                    progress.estimatedBytesRemaining += size;
                    progress.estimatedTotalBytes     += size;
                }
                downloader.Add(assets);
            }
        }
コード例 #2
0
        void downloader_Error(object sender, Net.AssetDownloader.Asset asset, Exception exception)
        {
            Util.Logging.Log(exception);

            lock (this)
            {
                if (progress.errored)
                {
                    return;
                }
                progress.errored = true;
            }

            if (Error != null)
            {
                Error(this, "Failed to download files", exception);
            }
        }
コード例 #3
0
        private async Task <bool> GetManifests(int manifestId, int manifestSize, Dictionary <int, int> baseIds, bool rescan)
        {
            int existing;

            if (baseIds.TryGetValue(MANIFEST_BASE_ID, out existing) && existing == manifestId)
            {
                if (!rescan)
                {
                    return(true); //the manifest is already up to date
                }
            }
            else if (rescan)
            {
                progress.rescan = false;
            }

            progress.manifestsTotal++;
            progress.estimatedBytesRemaining += manifestSize;
            progress.estimatedTotalBytes     += manifestSize;

            int language;

            switch (Settings.BackgroundPatchingLang.Value)
            {
            case 1:     //DE
                language = 296042;
                break;

            case 3:     //FR
                language = 296043;
                break;

            case 2:     //ES (n/a)
            case 0:     //EN
            default:
                language = 296040;
                break;
            }

#warning useCompression = BitConverter.IsLittleEndian
            var useCompression = BitConverter.IsLittleEndian;

            if (useCompression && archive == null)
            {
                archive = new Dat.Compression.Archive();
            }

            //var asset = new Net.AssetDownloader.Asset(manifestId, false, manifestSize);
            var asset = new Net.AssetDownloader.Asset(manifestId, useCompression, useCompression ? (int)(manifestSize * AVG_COMPRESSION + 0.5f) : manifestSize);
            asset.Complete += delegate(object o, Net.AssetDownloader.Asset.CompleteEventArgs c)
            {
                progress.contentBytesCore += c.ContentLength;
            };
            asset.Progress += asset_Progress;

            var cache = await downloader.Download(asset);

            using (cache)
            {
                if (cache != null && cache.HasData)
                {
                    cache.SetPositionToContent();
                    var          p = cache.Position;
                    Dat.Manifest manifest;

                    if (useCompression)
                    {
                        using (var ms = new MemoryStream(archive.DecompressRaw(cache, manifestSize)))
                        {
                            manifest = Tools.Dat.Manifest.Parse(ms);
                        }
                    }
                    else
                    {
                        manifest = Tools.Dat.Manifest.Parse(cache);
                        Create404Manifest(manifestId);
                    }

                    List <Net.AssetDownloader.Asset> assets = new List <Net.AssetDownloader.Asset>(manifest.records.Length);
                    long size = 0;

                    foreach (var record in manifest.records)
                    {
                        bool isUsed = true;

                        switch (record.baseId)
                        {
                        case 724786:        //Launcher
                            break;

                        case 1283391:       //Launcher64

                            if (!Is64())
                            {
                                isUsed = false;
                            }

                            break;

                        case 1475411:       //LauncherOSX

                            isUsed = false;

                            break;

                        case 622855:        //ClientContent86
                            break;

                        case 1283393:       //ClientContent64
                            break;

                        case 296040:        //English
                        case 296042:        //German
                        case 296043:        //French
                        case 1051220:       //Chinese

                            isUsed = record.baseId == language;

                            break;
                        }

                        //asset = new Net.AssetDownloader.Asset(record.fileId, !isUsed, !isUsed ? (int)(record.size * AVG_COMPRESSION + 0.5f) : record.size);
                        asset = new Net.AssetDownloader.Asset(record.fileId, useCompression, useCompression ? (int)(record.size * AVG_COMPRESSION + 0.5f) : record.size);
                        if (isUsed)
                        {
                            asset.Complete += manifestUsed_Complete;
                        }
                        else
                        {
                            asset.Complete += manifestUnused_Complete;
                        }
                        asset.Cancelled += manifest_Cancelled;
                        asset.Progress  += asset_Progress;

                        assets.Add(asset);

                        size += asset.size;
                    }

                    progress.manifestsTotal += assets.Count;
                    progress.manifestsDownloaded++;
                    progress.estimatedBytesRemaining += size;
                    progress.estimatedTotalBytes     += size;

                    downloader.Add(assets);

                    return(true);
                }
            }

            return(false);
        }
コード例 #4
0
        public async void Start(bool rescan)
        {
            lock (this)
            {
                if (IsActive)
                {
                    return;
                }
                isActive = true;
            }

            Cache.Enabled = true;

            int lastBuild;

            if (!rescan && progress != null && progress.filesTotal > 0 && progress.filesDownloaded == progress.filesTotal)
            {
                lastBuild = progress.build;
            }
            else
            {
                lastBuild = 0;
            }

            progress           = new DownloadProgressEventArgs();
            progress.startTime = DateTime.UtcNow;
            progress.rescan    = rescan;

            if (Starting != null)
            {
                Starting(this, EventArgs.Empty);
            }

            baseIds = await GetBaseIDs();

            if (baseIds.Count > 0)
            {
                #region Initialize downloader

                try
                {
                    if (downloader == null)
                    {
                        byte threads;
                        if (Settings.BackgroundPatchingMaximumThreads.HasValue)
                        {
                            threads = Settings.BackgroundPatchingMaximumThreads.Value;
                        }
                        else
                        {
                            threads = 10;
                        }

                        downloader = new Net.AssetDownloader(threads);

                        downloader.DownloadRate    += downloader_DownloadRate;
                        downloader.Error           += downloader_Error;
                        downloader.Complete        += downloader_Complete;
                        downloader.RequestComplete += downloader_RequestComplete;
                        downloader.Tick            += downloader_Tick;

                        var v = Settings.PatchingSpeedLimit;
                        if (v.HasValue)
                        {
                            downloader.BpsLimit = v.Value;
                        }
                        else
                        {
                            downloader.BpsLimit = Int32.MaxValue;
                        }

                        initializationTime = DateTime.UtcNow;
                    }
                    else if (DateTime.UtcNow.Subtract(initializationTime).TotalDays > 1)
                    {
                        downloader.SetIPPool(null);

                        initializationTime = DateTime.UtcNow;
                    }
                }
                catch (Exception e)
                {
                    progress.errored = true;
                    if (Error != null)
                    {
                        Error(this, "Failed to initialize", e);
                    }

                    isActive = false;
                    if (StateChanged != null)
                    {
                        StateChanged(this, EventArgs.Empty);
                    }
                    return;
                }

                #endregion

                var latest = await GetLatest();

                if (lastBuild > 0 && latest.buildId == lastBuild)
                {
                    //nochange
                    progress.build      = latest.buildId;
                    progress.filesTotal = progress.filesDownloaded = 1;

                    if (Complete != null)
                    {
                        Complete(this, EventArgs.Empty);
                    }
                }
                else if (latest.buildId != 0)
                {
                    progress.build = latest.buildId;

                    downloader.Start();

                    if (await GetManifests(latest.manifestId, latest.manifestSize, baseIds, rescan))
                    {
                        if (progress.manifestsTotal > 0 || latest.buildId != Settings.LastKnownBuild.Value)
                        {
                            if (!progress.rescan)
                            {
                                if (PatchBeginning != null)
                                {
                                    PatchBeginning(null, new PatchEventArgs()
                                    {
                                        Build = latest.buildId
                                    });
                                }

                                lock (baseIds)
                                    progress.filesTotal++;

                                var asset = new Net.AssetDownloader.Asset(latest.exeId, true, (int)(latest.exeSize * AVG_COMPRESSION + 0.5f));

                                lock (this)
                                {
                                    progress.estimatedBytesRemaining += asset.size;
                                    progress.estimatedTotalBytes     += asset.size;
                                }

                                asset.Cancelled += file_Cancelled;
                                asset.Complete  += file_Complete;
                                asset.Progress  += asset_Progress;

                                asset.Complete += delegate(object o, Net.AssetDownloader.Asset.CompleteEventArgs c)
                                {
                                    lock (this)
                                    {
                                        progress.contentBytesCore += c.ContentLength;
                                    }
                                };

                                downloader.Add(asset);
                            }
                        }
                    }
                    else
                    {
                        progress.errored = true;
                        if (Error != null)
                        {
                            Error(this, "Failed to retieve manifests", null);
                        }
                    }

                    downloader.StopWhenComplete();
                }
                else
                {
                    progress.errored = true;
                    if (Error != null)
                    {
                        Error(this, "Failed to retieve latest build", null);
                    }
                }
            }
            else
            {
                progress.errored = true;
                if (Error != null)
                {
                    Error(this, "Failed to read Gw2.dat", null);
                }
            }

            isActive = false;
            if (StateChanged != null)
            {
                StateChanged(this, EventArgs.Empty);
            }
        }