Ejemplo n.º 1
0
        public async Task PatchSingleItem(IArchiveFileEntry file, CancellationToken cancellationToken)
        {
            OnProgress(new ProgressUpdateEventArgs(file, 0, 0));
            if (await PatchWriter.Exists(file).ConfigureAwait(false))
            {
                return;
            }
            int              counter    = 0;
            Stream           fileData   = null;
            List <Exception> exceptions = new List <Exception>();

            do
            {
                try
                {
                    fileData = await PatchSource.DownloadHashAsync((int)Index.RootIndex.BuildNumber, file.Hash,
                                                                   cancellationToken);
                }
                catch (Exception ex)
                {
                    counter++;
                    exceptions.Add(ex);
                }
            } while (fileData == null && counter < FileRetryCount);

            if (fileData == null)
            {
                throw new AggregateException(exceptions);
            }

            counter = 0;
            do
            {
                try
                {
                    await PatchWriter.AppendAsync(fileData, file).ConfigureAwait(false);

                    break;
                }
                catch (Exception ex)
                {
                    exceptions.Add(ex);
                    counter++;
                }
            } while (counter < FileRetryCount);

            if (counter >= FileRetryCount)
            {
                throw new AggregateException(exceptions);
            }
        }
Ejemplo n.º 2
0
        public async Task DownloadAndProcessPatchIndexAsync()
        {
            // This stuff here is bootstrap, we trust the files are correct, because we assume this was done first.
            // Because it has to be done first, or we don't have the index files to begin with.
            var patchFileName = Path.Combine(PatchPath, "Patch.index");
            var serverBuild   = await PatchSource.GetServerBuildAsync().ConfigureAwait(false);

            var patchIndexHash = await PatchSource.GetFileHashAsync(Path.GetFileName(patchFileName)).ConfigureAwait(false);

            bool downloadRequired = true;

            if (File.Exists(patchFileName))
            {
                using (var sha1 = SHA1.Create())
                    using (var fileStream = File.Open(patchFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        var fileHash = sha1.ComputeHash(fileStream);
                        downloadRequired = !fileHash.SequenceEqual(patchIndexHash);
                    }
            }

            if (downloadRequired)
            {
                void WriteProgress(long length, long progress)
                {
                    var message = length <= 0 ? $"Downloaded {progress} bytes" : $"Downloaded {progress} of {length} bytes";

                    Output.WriteLine(message);
                }

                var dataStream = await PatchSource.DownloadHashAsync(serverBuild, patchIndexHash);

                using (var fileStream =
                           File.Open(patchFileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
                {
                    await dataStream.CopyToAsync(fileStream, WriteProgress);
                }
            }
            // But right here, we can just reuse our existing stuff.
            // So CoreData.archive is optional, and if it exists, we need to check it for existing data
            // Before we just blindly re-download it.
            await PatchIndex(patchFileName, PatchPath).ConfigureAwait(false);
        }