public IncrementalPatchApplier(PatchIntercomms comms, PatchInfo patchInfo)
        {
            this.comms     = comms;
            this.patchInfo = patchInfo;

            string patchVersion = patchInfo.PatchVersion();

            patchDownloadPath   = comms.GetDownloadPathForPatch(patchVersion);
            patchDecompressPath = comms.GetDecompressPathForPatch(patchVersion);
        }
Пример #2
0
        private PatchResult CreateIncrementalPatch()
        {
            if (cancel)
            {
                return(PatchResult.Failed);
            }

            Directory.CreateDirectory(incrementalPatchOutputPath);
            Directory.CreateDirectory(incrementalPatchTempPath);

            incrementalPatch = new PatchInfo
            {
                FromVersion = previousVersion,
                ToVersion   = version
            };

            Log(Localization.Get(StringId.CreatingIncrementalPatch));
            Stopwatch timer = Stopwatch.StartNew();

            DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);

            TraverseIncrementalPatchRecursively(rootDirectory, "");

            if (cancel)
            {
                return(PatchResult.Failed);
            }

            Log(Localization.Get(StringId.CompressingPatchIntoOneFile));
            string compressedPatchPath = incrementalPatchOutputPath + incrementalPatch.PatchVersion() + PatchParameters.PATCH_FILE_EXTENSION;

            ZipUtils.CompressFolderLZMA(incrementalPatchTempPath, compressedPatchPath);

            Log(Localization.Get(StringId.WritingIncrementalPatchInfoToXML));
            PatchUtils.SerializePatchInfoToXML(incrementalPatch, incrementalPatchOutputPath + incrementalPatch.PatchVersion() + PatchParameters.PATCH_INFO_EXTENSION);

            patch.Patches.Add(new IncrementalPatch(previousVersion, version, new FileInfo(compressedPatchPath)));

            PatchUtils.DeleteDirectory(incrementalPatchTempPath);

            Log(Localization.Get(StringId.IncrementalPatchCreatedInXSeconds, timer.ElapsedSeconds()));

            return(PatchResult.Success);
        }
        public PatchResult Run()
        {
            if (comms.Cancel)
            {
                return(PatchResult.Failed);
            }

            if (comms.IsUnderMaintenance())
            {
                return(PatchResult.Failed);
            }

            if (patchInfo.Files.Count > 0)
            {
                PatchUtils.DeleteDirectory(patchDecompressPath);
                Directory.CreateDirectory(patchDecompressPath);
            }

            if (comms.Cancel)
            {
                return(PatchResult.Failed);
            }

            Stopwatch timer = Stopwatch.StartNew();

            if (patchInfo.Files.Count > 0)
            {
                FileInfo patchFile = new FileInfo(patchDownloadPath);
                if (!patchFile.Exists || !patchFile.MatchesSignature(patchInfo.CompressedFileSize, patchInfo.CompressedMd5Hash))
                {
                    comms.Stage = PatchStage.DownloadingFiles;

                    Stopwatch downloadTimer = Stopwatch.StartNew();
                    comms.Log(Localization.Get(StringId.DownloadingPatchX, patchInfo.PatchVersion()));

                    patchFile = comms.DownloadManager.DownloadFileFromURLToPath(patchInfo.DownloadURL, patchDownloadPath, patchInfo.CompressedFileSize);
                    if (patchFile == null)
                    {
                        comms.FailReason  = PatchFailReason.DownloadError;
                        comms.FailDetails = Localization.Get(StringId.E_PatchXCouldNotBeDownloaded, patchInfo.PatchVersion());

                        return(PatchResult.Failed);
                    }
                    else if (!patchFile.MatchesSignature(patchInfo.CompressedFileSize, patchInfo.CompressedMd5Hash))
                    {
                        comms.FailReason  = PatchFailReason.CorruptDownloadError;
                        comms.FailDetails = Localization.Get(StringId.E_DownloadedFileXIsCorrupt, patchInfo.PatchVersion());

                        return(PatchResult.Failed);
                    }
                    else
                    {
                        comms.Log(Localization.Get(StringId.XDownloadedInYSeconds, patchInfo.PatchVersion(), downloadTimer.ElapsedSeconds()));
                    }
                }

                if (comms.Cancel)
                {
                    return(PatchResult.Failed);
                }

                comms.Stage = PatchStage.ExtractingFilesFromArchive;
                comms.Log(Localization.Get(StringId.DecompressingPatchX, patchInfo.PatchVersion()));

                ZipUtils.DecompressFolderLZMA(patchFile.FullName, patchDecompressPath);

                comms.Stage = PatchStage.UpdatingFiles;
                comms.Log(Localization.Get(StringId.UpdatingXFiles, patchInfo.Files.Count));

                int failedItemCount = 0;
                for (int i = 0; i < patchInfo.Files.Count; i++)
                {
                    if (comms.Cancel)
                    {
                        return(PatchResult.Failed);
                    }

                    string fileRelativePath     = patchInfo.Files[i].Path;
                    string diffFileAbsolutePath = patchDecompressPath + fileRelativePath;
                    if (!File.Exists(diffFileAbsolutePath))
                    {
                        comms.Log(Localization.Get(StringId.E_DiffOfXDoesNotExist, Path.GetFileName(fileRelativePath)));

                        failedItemCount++;
                        continue;
                    }

                    string decompressAbsolutePath = comms.DecompressedFilesPath + fileRelativePath;
                    if (comms.SelfPatching && ApplyDiffToFile(decompressAbsolutePath, diffFileAbsolutePath, decompressAbsolutePath, i))
                    {
                        continue;
                    }

                    string localFileAbsolutePath = comms.RootPath + fileRelativePath;
                    string targetPath            = comms.SelfPatching ? decompressAbsolutePath : localFileAbsolutePath;
                    if (!ApplyDiffToFile(localFileAbsolutePath, diffFileAbsolutePath, targetPath, i))
                    {
                        failedItemCount++;
                    }
                }

                comms.Log(Localization.Get(StringId.XFilesUpdatedSuccessfully, patchInfo.Files.Count - failedItemCount, patchInfo.Files.Count));
            }

            if (patchInfo.RenamedFiles.Count > 0)
            {
                comms.Log(Localization.Get(StringId.RenamingXFiles, patchInfo.RenamedFiles.Count));
                if (!RenameItems(patchInfo.RenamedFiles))
                {
                    return(PatchResult.Failed);
                }
            }

            // Updating version code to the latest one will be done by SimplePatchTool, after checking
            // whether or not all files are correctly updated
            if (patchInfo.ToVersion < comms.VersionInfo.Version)
            {
                comms.UpdateVersion(patchInfo.ToVersion);
            }

            if (patchInfo.Files.Count > 0)
            {
                PatchUtils.DeleteDirectory(patchDecompressPath);
                File.Delete(patchDownloadPath);
            }

            comms.Log(Localization.Get(StringId.PatchAppliedInXSeconds, timer.ElapsedSeconds()));
            return(PatchResult.Success);
        }