Skip to content

Commit

Permalink
Merge branch 'dev' into core
Browse files Browse the repository at this point in the history
  • Loading branch information
maddie480 committed Oct 21, 2023
2 parents bb51087 + a782688 commit fd44641
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 105 deletions.
2 changes: 1 addition & 1 deletion Celeste.Mod.mm/Content/Dialog/French.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Check English.txt for up-to-date notes.
# Check English.txt for up-to-date notes.

# Helper Postcards
POSTCARD_LEVELGONE= {big}Merci ((player)) !{/big}{n}Mais {#ff1144}((sid)){#} est dans une autre montagne.
Expand Down
156 changes: 52 additions & 104 deletions Celeste.Mod.mm/Mod/UI/OuiModUpdateList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,56 +22,27 @@ class OuiModUpdateList : Oui, OuiModOptions.ISubmenu {

private float alpha = 0f;

private Task task;

private Task renderButtonsTask;

private bool shouldRestart = false;

private bool restartMenuAdded = false;

private static List<ModUpdateHolder> updatableMods = null;

private static bool ongoingUpdateCancelled = false;
private Task updateTask = null;

private static bool isFetchingDone = false;
private List<ModUpdateHolder> updatableMods = null;
private bool isFetchingDone = false;

private bool ongoingUpdateCancelled = false;
private bool menuOnScreen = false;

public override IEnumerator Enter(Oui from) {
Everest.Loader.AutoLoadNewMods = false;

menu = new patch_TextMenu();

// display the title and a dummy "Fetching" button
menu.Add(new TextMenu.Header(Dialog.Clean("MODUPDATECHECKER_MENU_TITLE")));

menu.Add(subHeader = new TextMenuExt.SubHeaderExt(Dialog.Clean("MODUPDATECHECKER_MENU_HEADER")));

if (updatableMods == null) {
updatableMods = new List<ModUpdateHolder>();
task = new Task(() => {checkForUpdates(); isFetchingDone = true;});
task.Start();
fetchingButton = new TextMenu.Button(Dialog.Clean("MODUPDATECHECKER_FETCHING"));
fetchingButton.Disabled = true;
menu.Add(fetchingButton);
} else if (isFetchingDone) { // mods have been already fetched
fetchingButton = null;
// if there are multiple updates...
if (updatableMods.Count > 1) {
// display an "update all" button at the top of the list
updateAllButton = new TextMenu.Button(Dialog.Clean("MODUPDATECHECKER_UPDATE_ALL"));
updateAllButton.Pressed(() => downloadAllMods());
menu.Add(updateAllButton);
}
foreach (ModUpdateHolder modHolder in updatableMods) {
menu.Add(modHolder.button); // buttons should get automatically generated
}
} else { // fetching button without task
fetchingButton = new TextMenu.Button(Dialog.Clean("MODUPDATECHECKER_FETCHING"));
fetchingButton.Disabled = true;
menu.Add(fetchingButton);
}

menu = new patch_TextMenu {
new TextMenu.Header(Dialog.Clean("MODUPDATECHECKER_MENU_TITLE")),
(subHeader = new TextMenuExt.SubHeaderExt(Dialog.Clean("MODUPDATECHECKER_MENU_HEADER"))),
(fetchingButton = new TextMenu.Button(Dialog.Clean("MODUPDATECHECKER_FETCHING")) { Disabled = true })
};

Scene.Add(menu);

Expand Down Expand Up @@ -110,8 +81,9 @@ public override IEnumerator Leave(Oui next) {
updMod.RemoveButton();
}

task = null;
renderButtonsTask = null;
updateTask = null;
updatableMods = null;
isFetchingDone = false;
}

public override void Update() {
Expand All @@ -120,11 +92,11 @@ public override void Update() {
return;
}

if (renderButtonsTask != null) {
renderButtonsTask.RunSynchronously();
renderButtonsTask = null;
if (!isFetchingDone && ModUpdaterHelper.IsAsyncUpdateCheckingDone()) {
renderUpdateList();
isFetchingDone = true;
}

// check if the "press Back to restart" message has to be toggled
if (menu.Focused && shouldRestart) {
subHeader.TextColor = Color.OrangeRed;
Expand All @@ -137,17 +109,15 @@ public override void Update() {
subHeader.TextColor = Color.Gray;
subHeader.Title = Dialog.Clean("MODUPDATECHECKER_MENU_HEADER");
}
if (Input.MenuCancel.Pressed && !menu.Focused && menuOnScreen) {

if (Input.MenuCancel.Pressed && !menu.Focused && menuOnScreen) {
// cancel any ongoing download (this has no effect if no download is ongoing anyway).
ongoingUpdateCancelled = true;

if (!isFetchingDone) {
// cancelling out during check for updates: go back to mod options instead
Audio.Play(SFX.ui_main_button_back);
Overworld.Goto<OuiModOptions>();

renderButtonsTask = null; // make sure no leftover tasks are there
}
} else if (Input.MenuCancel.Pressed && menu.Focused && Selected) {
if (shouldRestart && subRestartHeader != null) {
Expand All @@ -171,14 +141,15 @@ public override void Render() {
}

private void addRestartButtons() {
if (restartMenuAdded) return;
if (restartMenuAdded)
return;
menu.Add(subRestartHeader = new TextMenuExt.SubHeaderExt(Dialog.Clean("MODUPDATECHECKER_MENU_HEADER_RESTART")));
TextMenu.Button shutdownButton = new TextMenu.Button(Dialog.Clean("MODUPDATECHECKER_SHUTDOWN"));
shutdownButton.Pressed(() => {
new FadeWipe(base.Scene, false, delegate {
Engine.Scene = new Scene();
Engine.Instance.Exit();
});
Engine.Scene = new Scene();
Engine.Instance.Exit();
});
});
TextMenu.Button restartButton = new TextMenu.Button(Dialog.Clean("MODUPDATECHECKER_RESTART"));
restartButton.Pressed(() => Everest.QuickFullRestart());
Expand All @@ -190,51 +161,30 @@ private void addRestartButtons() {
}
}

private void checkForUpdates() {
// 1. Download the mod updates database
Dictionary<string, ModUpdateInfo> updateCatalog = null;
updateCatalog = ModUpdaterHelper.DownloadModUpdateList();

// 2. Find out what actually has been updated
SortedDictionary<ModUpdateInfo, EverestModuleMetadata> availableUpdatesCatalog = new SortedDictionary<ModUpdateInfo, EverestModuleMetadata>();
if (updateCatalog != null) {
availableUpdatesCatalog = ModUpdaterHelper.ListAvailableUpdates(updateCatalog, excludeBlacklist: false);
}

private void renderUpdateList() {
Logger.Log(LogLevel.Verbose, "OuiModUpdateList", "Rendering updates");

// remove the "loading" button
menu.Remove(fetchingButton);
fetchingButton = null;

// 3. Render on screen
Logger.Log(LogLevel.Verbose, "OuiModUpdateList", "Rendering updates");
SortedDictionary<ModUpdateInfo, EverestModuleMetadata> availableUpdates = ModUpdaterHelper.GetAsyncLoadedModUpdates();


if (updateCatalog == null) {
if (availableUpdates == null) {
// display an error message
renderButtonsTask = new Task(() => {
menu.Remove(fetchingButton);
fetchingButton = null;
TextMenu.Button button = new TextMenu.Button(Dialog.Clean("MODUPDATECHECKER_ERROR"));
button.Disabled = true;
menu.Add(button);
});
isFetchingDone = false;
updatableMods = null;
menu.Add(new TextMenu.Button(Dialog.Clean("MODUPDATECHECKER_ERROR")) { Disabled = true });
return;
} else if (availableUpdatesCatalog.Count == 0) {
} else if (availableUpdates.Count == 0) {
// display a dummy "no update available" button
renderButtonsTask = new Task(() => {
menu.Remove(fetchingButton);
fetchingButton = null;
TextMenu.Button button = new TextMenu.Button(Dialog.Clean("MODUPDATECHECKER_NOUPDATE"));
button.Disabled = true;
menu.Add(button);
});
menu.Add(new TextMenu.Button(Dialog.Clean("MODUPDATECHECKER_NOUPDATE")) { Disabled = true });
return;
}

List<TextMenu.Button> queuedItems = new List<TextMenu.Button>();
updatableMods = new List<ModUpdateHolder>();

// if there are multiple updates...
if (availableUpdatesCatalog.Count > 1) {
if (availableUpdates.Count > 1) {
// display an "update all" button at the top of the list
updateAllButton = new TextMenu.Button(Dialog.Clean("MODUPDATECHECKER_UPDATE_ALL"));
updateAllButton.Pressed(() => downloadAllMods());
Expand All @@ -243,15 +193,15 @@ private void checkForUpdates() {
}

// then, display one button per update
foreach (ModUpdateInfo update in availableUpdatesCatalog.Keys) {
EverestModuleMetadata metadata = availableUpdatesCatalog[update];
foreach (ModUpdateInfo update in availableUpdates.Keys) {
EverestModuleMetadata metadata = availableUpdates[update];

string versionUpdate = metadata.VersionString;
if (metadata.VersionString != update.Version)
versionUpdate = $"{metadata.VersionString} > {update.Version}";

ModUpdateHolder holder = new ModUpdateHolder(update: update, metadata: metadata, buttonGenerator: () => null);

Func<TextMenu.Button> buttonGenerator = new Func<TextMenu.Button>(() => {

TextMenu.Button button = new TextMenu.Button(
Expand All @@ -270,7 +220,7 @@ private void checkForUpdates() {
// if there isn't, add it to the list of mods that can be updated via "update all"
if (update.xxHash.Count > 1) {
button.Disabled = true;
}
}
return button;
});

Expand All @@ -283,23 +233,20 @@ private void checkForUpdates() {
}

queuedItems.Add(holder.button);


}

foreach (TextMenu.Button button in queuedItems) {
menu.Add(button);
}
renderButtonsTask = new Task(() => {
foreach (TextMenu.Button button in queuedItems) {
menu.Remove(fetchingButton);
fetchingButton = null;
menu.Add(button);
}
});
}

/// <summary>
/// Downloads and installs a mod update.
/// </summary>
/// <param name="modHolder">The relevant info for the mod</param>
private void downloadModUpdate(ModUpdateHolder modHolder) {
task = new Task(() => {
updateTask = new Task(() => {
bool updateSuccess = doDownloadModUpdate(modHolder.update, modHolder.metadata, modHolder.button);

if (updateSuccess) {
Expand All @@ -324,7 +271,7 @@ private void downloadModUpdate(ModUpdateHolder modHolder) {
menu.Focused = true;
});

task.Start();
updateTask.Start();
}

/// <summary>
Expand Down Expand Up @@ -389,7 +336,7 @@ private bool doDownloadModUpdate(ModUpdateInfo update, EverestModuleMetadata mod
/// <param name="update">The update info coming from the update server</param>
/// <param name="button">The button for that mod shown on the interface</param>
/// <param name="zipPath">The path to the zip the update will be downloaded to</param>
private static void downloadMod(ModUpdateInfo update, TextMenu.Button button, string zipPath) {
private void downloadMod(ModUpdateInfo update, TextMenu.Button button, string zipPath) {
Logger.Log(LogLevel.Verbose, "OuiModUpdateList", $"Downloading {update.URL} to {zipPath}");

Func<int, long, int, bool> progressCallback = (position, length, speed) => {
Expand Down Expand Up @@ -418,7 +365,7 @@ private static void downloadMod(ModUpdateInfo update, TextMenu.Button button, st
/// Downloads all automatically updatable mods
/// </summary>
private void downloadAllMods() {
task = new Task(() => {
updateTask = new Task(() => {
// make the menu non-interactive
menu.Focused = false;
updateAllButton.Disabled = true;
Expand Down Expand Up @@ -463,7 +410,8 @@ private void downloadAllMods() {
// give the menu control back to the player
menu.Focused = true;
});
task.Start();

updateTask.Start();
}

private void focusOn(TextMenu.Button button) {
Expand Down

0 comments on commit fd44641

Please sign in to comment.