// returns true if there was no integrity errors, false if there was and repair was performed private bool PerformInternal(PatchKit.Unity.Patcher.Cancellation.CancellationToken cancellationToken) { int installedVersionId = Context.App.GetInstalledVersionId(); VersionIntegrity results = CheckIntegrity(cancellationToken, installedVersionId); var filesNeedFixing = FilesNeedFixing(results); if (filesNeedFixing.Count() == 0) { DebugLogger.Log("No missing or invalid size files."); return(true); } // need to collect some data about the application to calculate the repair cost and make decisions int latestVersionId = Context.App.GetLatestVersionId(true, cancellationToken); AppContentSummary installedVersionContentSummary = Context.App.RemoteMetaData.GetContentSummary(installedVersionId, cancellationToken); AppContentSummary latestVersionContentSummary = Context.App.RemoteMetaData.GetContentSummary(latestVersionId, cancellationToken); bool isNewVersionAvailable = installedVersionId < latestVersionId; long contentSize = isNewVersionAvailable ? latestVersionContentSummary.Files.Sum(f => f.Size) : installedVersionContentSummary.Files.Sum(f => f.Size); double repairCost = CalculateRepairCost(installedVersionContentSummary, filesNeedFixing); // increasing repair costs that reinstallation will be done for 1/3 of the content size repairCost *= IncreaseRepairCost; if (_lowestVersionWithContentId > installedVersionId) { DebugLogger.Log( "Repair is impossible because lowest version with content id is " + _lowestVersionWithContentId + " and currently installed version id is " + installedVersionId + ". Reinstalling."); ReinstallContent(cancellationToken); } else if (repairCost < contentSize) { DebugLogger.Log(string.Format("Repair cost {0} is smaller than content cost {1}, repairing...", repairCost, contentSize)); IAppUpdaterStrategy repairStrategy = _strategyResolver.Create(StrategyType.Repair, Context); repairStrategy.Update(cancellationToken); } else { DebugLogger.Log(string.Format("Content cost {0} is smaller than repair {1}. Reinstalling.", contentSize, repairCost)); ReinstallContent(cancellationToken); } return(false); }
public AppUpdaterRepairAndDiffStrategy(AppUpdaterContext context, UpdaterStatus status) { Assert.IsNotNull(context, "Context is null"); _repairStrategy = new AppUpdaterRepairStrategy(context, status); _diffStrategy = new AppUpdaterDiffStrategy(context, status); }
private bool TryHandleFallback(PatchKit.Unity.Patcher.Cancellation.CancellationToken cancellationToken) { var fallbackType = _strategyResolver.GetFallbackStrategy(_strategy.GetStrategyType()); if (fallbackType == StrategyType.None) { return(false); } _strategy = _strategyResolver.Create(fallbackType, Context); _strategy.Update(cancellationToken); return(true); }
private bool TryHandleFallback(CancellationToken cancellationToken) { var fallbackType = _strategyResolver.GetFallbackStrategy(_strategy.GetStrategyType()); if (fallbackType == StrategyType.None) { return(false); } Context.App.ReloadTemporaryDirectories(); // FIX: Bug #724 _strategy = _strategyResolver.Create(fallbackType, Context); _strategy.Update(cancellationToken); return(true); }
public void Update(PatchKit.Unity.Patcher.Cancellation.CancellationToken cancellationToken) { Assert.MethodCalledOnlyOnce(ref _updateHasBeenCalled, "Update"); if (Context.App.IsInstallationBroken() || Context.App.IsFullyInstalled()) { PreUpdate(cancellationToken); } DebugLogger.Log("Updating."); StrategyType type = _strategyResolver.Resolve(Context, cancellationToken); _strategy = _strategyResolver.Create(type, Context); try { _strategy.Update(cancellationToken); } catch (Exception ex) { if (ex is OperationCanceledException || ex is UnauthorizedAccessException || ex is NotEnoughtDiskSpaceException || ex is ThreadInterruptedException || ex is ThreadAbortException) { DebugLogger.LogWarning("Strategy caused exception, to be handled further"); throw; } else { DebugLogger.LogWarningFormat("Strategy caused exception, being handled by fallback: {0}, Trace: {1}", ex, ex.StackTrace); if (!TryHandleFallback(cancellationToken)) { throw; } } } }
private void PreUpdate(PatchKit.Unity.Patcher.Cancellation.CancellationToken cancellationToken) { DebugLogger.Log("Pre update integrity check"); var commandFactory = new AppUpdaterCommandFactory(); int installedVersionId = Context.App.GetInstalledVersionId(); int latestVersionId = Context.App.GetLatestVersionId(); int lowestVersionWithContentId = Context.App.GetLowestVersionWithContentId(); if (lowestVersionWithContentId > installedVersionId) { DebugLogger.Log( "Repair is impossible because lowest version with content id is " + lowestVersionWithContentId + " and currently installed version id is " + installedVersionId + ". Uninstalling to prepare for content strategy."); IUninstallCommand uninstall = commandFactory.CreateUninstallCommand(Context); uninstall.Prepare(_status); uninstall.Execute(cancellationToken); return; } AppContentSummary installedVersionContentSummary = Context.App.RemoteMetaData.GetContentSummary(installedVersionId); AppContentSummary latestVersionContentSummary = Context.App.RemoteMetaData.GetContentSummary(latestVersionId); bool isNewVersionAvailable = installedVersionId < latestVersionId; long contentSize = isNewVersionAvailable ? latestVersionContentSummary.Size : installedVersionContentSummary.Size; ICheckVersionIntegrityCommand checkIntegrity = commandFactory .CreateCheckVersionIntegrityCommand( versionId: installedVersionId, context: Context, isCheckingHash: false, isCheckingSize: true); checkIntegrity.Prepare(_status); checkIntegrity.Execute(cancellationToken); var missingFiles = checkIntegrity.Results.Files .Where(f => f.Status == FileIntegrityStatus.MissingData); int missingFilesCount = missingFiles.Count(); var invalidSizeFiles = checkIntegrity.Results.Files .Where(f => f.Status == FileIntegrityStatus.InvalidSize); int invalidSizeFilesCount = invalidSizeFiles.Count(); if (missingFilesCount + invalidSizeFilesCount == 0) { DebugLogger.Log("No missing or invalid size files."); return; } double repairCost = CalculateRepairCost(installedVersionContentSummary, missingFiles.Concat(invalidSizeFiles)); if (repairCost < contentSize) { DebugLogger.Log(string.Format("Repair cost {0} is smaller than content cost {1}, repairing...", repairCost, contentSize)); IAppUpdaterStrategy repairStrategy = _strategyResolver.Create(StrategyType.Repair, Context); repairStrategy.Update(cancellationToken); } else { DebugLogger.Log("Content cost is smaller than repair. Uninstalling to prepare for content strategy."); IUninstallCommand uninstall = commandFactory.CreateUninstallCommand(Context); uninstall.Prepare(_status); uninstall.Execute(cancellationToken); } }