/// <summary> /// Does the actual downloading of the mod. This is it's own function, to avoid double code /// </summary> /// <param name="update">The update info coming from the update server</param> /// <param name="mod">The mod metadata from Everest for the installed mod</param> /// <param name="button">The button for that mod shown on the interface</param> /// <returns>Bool wether the update failed or not</returns> private bool doDownloadModUpdate(ModUpdateInfo update, EverestModuleMetadata mod, TextMenu.Button button) { // we will download the mod to Celeste_Directory/[update.GetHashCode()].zip at first. string zipPath = Path.Combine(Everest.PathGame, $"modupdate-{update.GetHashCode()}.zip"); try { // download it... button.Label = $"{ModUpdaterHelper.FormatModName(update.Name)} ({Dialog.Clean("MODUPDATECHECKER_DOWNLOADING")})"; downloadMod(update, button, zipPath); // verify its checksum ModUpdaterHelper.VerifyChecksum(update, zipPath); // mark restarting as required, as we will do weird stuff like closing zips afterwards. shouldRestart = true; // install it button.Label = $"{ModUpdaterHelper.FormatModName(update.Name)} ({Dialog.Clean("MODUPDATECHECKER_INSTALLING")})"; ModUpdaterHelper.InstallModUpdate(update, mod, zipPath); // done! button.Label = $"{ModUpdaterHelper.FormatModName(update.Name)} ({Dialog.Clean("MODUPDATECHECKER_UPDATED")})"; return(true); } catch (Exception e) { // update failed button.Label = $"{ModUpdaterHelper.FormatModName(update.Name)} ({Dialog.Clean("MODUPDATECHECKER_FAILED")})"; Logger.Log("OuiModUpdateList", $"Updating {update.Name} failed"); Logger.LogDetailed(e); // try to delete mod-update.zip if it still exists. ModUpdaterHelper.TryDelete(zipPath); return(false); } }
/// <summary> /// Downloads and installs a mod update. /// </summary> /// <param name="update">The update info coming from the update server</param> /// <param name="mod">The mod metadata from Everest for the installed mod</param> /// <param name="button">The button for that mod shown on the interface</param> private void downloadModUpdate(ModUpdateInfo update, EverestModuleMetadata mod, TextMenu.Button button) { task = new Task(() => { // we will download the mod to Celeste_Directory/mod-update.zip at first. string zipPath = Path.Combine(Everest.PathGame, "mod-update.zip"); try { // download it... button.Label = $"{update.Name.SpacedPascalCase()} ({Dialog.Clean("MODUPDATECHECKER_DOWNLOADING")})"; downloadMod(update, button, zipPath); // verify its checksum ModUpdaterHelper.VerifyChecksum(update, zipPath); // mark restarting as required, as we will do weird stuff like closing zips afterwards. if (!shouldRestart) { shouldRestart = true; subHeader.TextColor = Color.OrangeRed; subHeader.Title = $"{Dialog.Clean("MODUPDATECHECKER_MENU_HEADER")} ({Dialog.Clean("MODUPDATECHECKER_WILLRESTART")})"; } // install it button.Label = $"{update.Name.SpacedPascalCase()} ({Dialog.Clean("MODUPDATECHECKER_INSTALLING")})"; ModUpdaterHelper.InstallModUpdate(update, mod, zipPath); // done! button.Label = $"{update.Name.SpacedPascalCase()} ({Dialog.Clean("MODUPDATECHECKER_UPDATED")})"; // select another enabled option: the next one, or the last one if there is no next one. if (menu.Selection + 1 > menu.LastPossibleSelection) { menu.Selection = menu.LastPossibleSelection; } else { menu.MoveSelection(1); } } catch (Exception e) { // update failed button.Label = $"{update.Name.SpacedPascalCase()} ({Dialog.Clean("MODUPDATECHECKER_FAILED")})"; Logger.Log("OuiModUpdateList", $"Updating {update.Name} failed"); Logger.LogDetailed(e); button.Disabled = false; // try to delete mod-update.zip if it still exists. ModUpdaterHelper.TryDelete(zipPath); } // give the menu control back to the player menu.Focused = true; }); task.Start(); }
private void autoUpdate(SortedDictionary <ModUpdateInfo, EverestModuleMetadata> updateList) { int currentlyUpdatedModIndex = 1; // this is common to all mods. string zipPath = Path.Combine(Everest.PathGame, "mod-update.zip"); bool restartRequired = false; bool failuresOccured = false; // iterate through all mods to update now. foreach (ModUpdateInfo update in updateList.Keys) { // common beginning for all messages: f.e. [1/3] Auto-updating Polygon Dreams string progressString = $"[{currentlyUpdatedModIndex}/{updateList.Count}] {Dialog.Clean("AUTOUPDATECHECKER_UPDATING")} {ModUpdaterHelper.FormatModName(update.Name)}:"; try { // show the cancel button for downloading showCancel = true; // download it... modUpdatingMessage = $"{progressString} {Dialog.Clean("AUTOUPDATECHECKER_DOWNLOADING")}"; Logger.Log("AutoModUpdater", $"Downloading {update.URL} to {zipPath}"); Func <int, long, int, bool> progressCallback = (position, length, speed) => { if (skipUpdate) { return(false); } if (length > 0) { modUpdatingMessage = $"{progressString} {Dialog.Clean("AUTOUPDATECHECKER_DOWNLOADING")} " + $"({((int) Math.Floor(100D * (position / (double) length)))}% @ {speed} KiB/s)"; } else { modUpdatingMessage = $"{progressString} {Dialog.Clean("AUTOUPDATECHECKER_DOWNLOADING")} " + $"({((int) Math.Floor(position / 1000D))}KiB @ {speed} KiB/s)"; } return(true); }; try { Everest.Updater.DownloadFileWithProgress(update.URL, zipPath, progressCallback); } catch (WebException e) { Logger.Log(LogLevel.Warn, "AutoModUpdater", $"Download failed, trying mirror {update.MirrorURL}"); Logger.LogDetailed(e); Everest.Updater.DownloadFileWithProgress(update.MirrorURL, zipPath, progressCallback); } // hide the cancel button for downloading, download is done showCancel = false; if (skipUpdate) { Logger.Log("AutoModUpdater", "Update was skipped"); // try to delete mod-update.zip if it still exists. ModUpdaterHelper.TryDelete(zipPath); if (restartRequired) { // stop trying to update mods; restart right away break; } else { // proceed to the game right away shouldContinue = true; return; } } // verify its checksum modUpdatingMessage = $"{progressString} {Dialog.Clean("AUTOUPDATECHECKER_VERIFYING")}"; ModUpdaterHelper.VerifyChecksum(update, zipPath); // install it restartRequired = true; modUpdatingMessage = $"{progressString} {Dialog.Clean("AUTOUPDATECHECKER_INSTALLING")}"; ModUpdaterHelper.InstallModUpdate(update, updateList[update], zipPath); } catch (Exception e) { // update failed Logger.Log("AutoModUpdater", $"Updating {update.Name} failed"); Logger.LogDetailed(e); failuresOccured = true; // try to delete mod-update.zip if it still exists. ModUpdaterHelper.TryDelete(zipPath); // stop trying to update further mods. break; } currentlyUpdatedModIndex++; } // don't show "cancel" anymore, install ended. showCancel = false; if (!failuresOccured) { // restart when everything is done modUpdatingMessage = Dialog.Clean("DEPENDENCYDOWNLOADER_RESTARTING"); Thread.Sleep(1000); Everest.QuickFullRestart(); } else { modUpdatingMessage = Dialog.Clean("AUTOUPDATECHECKER_FAILED"); // stop the cogwheel cogwheelSpinning = false; cogwheelStopTime = RawTimeActive; if (restartRequired) { // failures occured, restart is required modUpdatingSubMessage = Dialog.Clean("AUTOUPDATECHECKER_REBOOT"); confirmToRestart = true; } else { // failures occured, restart is not required modUpdatingSubMessage = Dialog.Clean("AUTOUPDATECHECKER_CONTINUE"); confirmToContinue = true; } } }
private void downloadDependency(ModUpdateInfo mod, EverestModuleMetadata installedVersion) { string downloadDestination = Path.Combine(Everest.PathGame, $"dependency-download.zip"); try { // 1. Download LogLine(string.Format(Dialog.Get("DEPENDENCYDOWNLOADER_DOWNLOADING"), mod.Name, mod.URL)); LogLine("", false); Everest.Updater.DownloadFileWithProgress(mod.URL, downloadDestination, (position, length, speed) => { if (length > 0) { Lines[Lines.Count - 1] = $"{((int) Math.Floor(100D * (position / (double) length)))}% @ {speed} KiB/s"; Progress = position; ProgressMax = (int)length; } else { Lines[Lines.Count - 1] = $"{((int) Math.Floor(position / 1000D))}KiB @ {speed} KiB/s"; ProgressMax = 0; } }); ProgressMax = 0; Lines[Lines.Count - 1] = Dialog.Clean("DEPENDENCYDOWNLOADER_DOWNLOAD_FINISHED"); // 2. Verify checksum LogLine(Dialog.Clean("DEPENDENCYDOWNLOADER_VERIFYING_CHECKSUM")); ModUpdaterHelper.VerifyChecksum(mod, downloadDestination); // 3. Install mod shouldRestart = true; if (installedVersion != null) { LogLine(string.Format(Dialog.Get("DEPENDENCYDOWNLOADER_UPDATING"), mod.Name, installedVersion.Version, mod.Version, installedVersion.PathArchive)); ModUpdaterHelper.InstallModUpdate(mod, installedVersion, downloadDestination); } else { string installDestination = Path.Combine(Everest.Loader.PathMods, $"{mod.Name}.zip"); LogLine(string.Format(Dialog.Get("DEPENDENCYDOWNLOADER_INSTALLING"), mod.Name, mod.Version, installDestination)); File.Move(downloadDestination, installDestination); } } catch (Exception e) { // install failed LogLine(string.Format(Dialog.Get("DEPENDENCYDOWNLOADER_INSTALL_FAILED"), mod.Name)); Logger.LogDetailed(e); shouldAutoRestart = false; // try to delete the file if it still exists. if (File.Exists(downloadDestination)) { try { Logger.Log("OuiDependencyDownloader", $"Deleting temp file {downloadDestination}"); File.Delete(downloadDestination); } catch (Exception) { Logger.Log("OuiDependencyDownloader", $"Removing {downloadDestination} failed"); } } } }
private void autoUpdate(SortedDictionary <ModUpdateInfo, EverestModuleMetadata> updateList) { int currentlyUpdatedModIndex = 1; // this is common to all mods. string zipPath = Path.Combine(Everest.PathGame, "mod-update.zip"); bool restartRequired = false; bool failuresOccured = false; // iterate through all mods to update now. foreach (ModUpdateInfo update in updateList.Keys) { // common beginning for all messages: f.e. [1/3] Auto-updating Polygon Dreams string progressString = $"[{currentlyUpdatedModIndex}/{updateList.Count}] {Dialog.Clean("AUTOUPDATECHECKER_UPDATING")} {update.Name.SpacedPascalCase()}:"; try { // download it... modUpdatingMessage = $"{progressString} {Dialog.Clean("AUTOUPDATECHECKER_DOWNLOADING")}"; Logger.Log("AutoModUpdater", $"Downloading {update.URL} to {zipPath}"); Everest.Updater.DownloadFileWithProgress(update.URL, zipPath, (position, length, speed) => { if (length > 0) { modUpdatingMessage = $"{progressString} {Dialog.Clean("AUTOUPDATECHECKER_DOWNLOADING")} " + $"({((int)Math.Floor(100D * (position / (double)length)))}% @ {speed} KiB/s)"; } else { modUpdatingMessage = $"{progressString} {Dialog.Clean("AUTOUPDATECHECKER_DOWNLOADING")} " + $"({((int)Math.Floor(position / 1000D))}KiB @ {speed} KiB/s)"; } }); // verify its checksum modUpdatingMessage = $"{progressString} {Dialog.Clean("AUTOUPDATECHECKER_VERIFYING")}"; ModUpdaterHelper.VerifyChecksum(update, zipPath); // install it restartRequired = true; modUpdatingMessage = $"{progressString} {Dialog.Clean("AUTOUPDATECHECKER_INSTALLING")}"; ModUpdaterHelper.InstallModUpdate(update, updateList[update], zipPath); } catch (Exception e) { // update failed Logger.Log("AutoModUpdater", $"Updating {update.Name} failed"); Logger.LogDetailed(e); failuresOccured = true; // try to delete mod-update.zip if it still exists. ModUpdaterHelper.TryDelete(zipPath); } currentlyUpdatedModIndex++; } if (!failuresOccured) { // restart when everything is done modUpdatingMessage = Dialog.Clean("DEPENDENCYDOWNLOADER_RESTARTING"); Thread.Sleep(1000); Everest.QuickFullRestart(); } else { modUpdatingMessage = Dialog.Clean("AUTOUPDATECHECKER_FAILED"); // stop the cogwheel cogwheelSpinning = false; cogwheelStopTime = RawTimeActive; if (restartRequired) { // failures occured, restart is required modUpdatingSubMessage = Dialog.Clean("AUTOUPDATECHECKER_REBOOT"); confirmToRestart = true; } else { // failures occured, restart is not required modUpdatingSubMessage = Dialog.Clean("AUTOUPDATECHECKER_CONTINUE"); confirmToContinue = true; } } }