public override IEnumerator Enter(Oui from) { Everest.Loader.AutoLoadNewMods = false; menu = new 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"))); fetchingButton = new TextMenu.Button(Dialog.Clean("MODUPDATECHECKER_FETCHING")); fetchingButton.Disabled = true; menu.Add(fetchingButton); Scene.Add(menu); currentCheckForUpdates = new CheckForUpdates(); task = new Task(() => currentCheckForUpdates.Fetch()); task.Start(); menu.Visible = Visible = true; menu.Focused = false; for (float p = 0f; p < 1f; p += Engine.DeltaTime * 4f) { menu.X = offScreenX + -1920f * Ease.CubeOut(p); alpha = Ease.CubeOut(p); yield return(null); } menu.Focused = true; menuOnScreen = true; }
public override IEnumerator Enter(Oui from) { Everest.Loader.AutoLoadNewMods = false; menu = new 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"))); fetchingButton = new TextMenu.Button(Dialog.Clean("MODUPDATECHECKER_FETCHING")); fetchingButton.Disabled = true; menu.Add(fetchingButton); Scene.Add(menu); menu.Visible = Visible = true; menu.Focused = false; for (float p = 0f; p < 1f; p += Engine.DeltaTime * 4f) { menu.X = offScreenX + -1920f * Ease.CubeOut(p); alpha = Ease.CubeOut(p); yield return(null); } menu.Focused = true; menuOnScreen = true; task = new Task(() => { // 1. Download the mod updates database updateCatalog = ModUpdaterHelper.DownloadModUpdateList(); // 2. Find out what actually has been updated if (updateCatalog != null) { availableUpdatesCatalog = ModUpdaterHelper.ListAvailableUpdates(updateCatalog); } }); task.Start(); }
protected override void addOptionsToMenu(TextMenu menu) { // if there is a whitelist, warn the user that it will break those settings. if (Everest.Loader.Whitelist != null) { menu.Add(restartMessage1 = new TextMenuExt.SubHeaderExt(Dialog.Clean("MODOPTIONS_MODTOGGLE_WHITELISTWARN")) { TextColor = Color.OrangeRed }); } // display the warning about blacklist.txt + restarting menu.Add(restartMessage1 = new TextMenuExt.SubHeaderExt(Dialog.Clean("MODOPTIONS_MODTOGGLE_MESSAGE_1"))); menu.Add(restartMessage2 = new TextMenuExt.SubHeaderExt(Dialog.Clean("MODOPTIONS_MODTOGGLE_MESSAGE_2")) { HeightExtra = 0f }); // reduce spacing between the whitelist warning and the blacklist overwrite warning if (Everest.Loader.Whitelist != null) { restartMessage1.HeightExtra = 30f; } // "enable all" and "disable all" buttons List <TextMenu.OnOff> allToggles = new List <TextMenu.OnOff>(); menu.Add(new TextMenu.Button(Dialog.Clean("MODOPTIONS_MODTOGGLE_ENABLEALL")).Pressed(() => { foreach (TextMenu.OnOff toggle in allToggles) { if (toggle.Index != 1) { toggle.Index = 1; toggle.OnValueChange(true); } } })); menu.Add(new TextMenu.Button(Dialog.Clean("MODOPTIONS_MODTOGGLE_DISABLEALL")).Pressed(() => { foreach (TextMenu.OnOff toggle in allToggles) { if (toggle.Index != 0) { toggle.Index = 0; toggle.OnValueChange(false); } } })); // "cancel" button to leave the screen without saving menu.Add(new TextMenu.Button(Dialog.Clean("MODOPTIONS_MODTOGGLE_CANCEL")).Pressed(() => { blacklistedMods = blacklistedModsOriginal; onBackPressed(Overworld); })); // reset the mods list allMods = new List <string>(); blacklistedMods = new HashSet <string>(); string[] files; bool headerInserted; // crawl directories files = Directory.GetDirectories(Everest.Loader.PathMods); headerInserted = false; for (int i = 0; i < files.Length; i++) { string file = Path.GetFileName(files[i]); if (file != "Cache") { if (!headerInserted) { menu.Add(new TextMenu.SubHeader(Dialog.Clean("MODOPTIONS_MODTOGGLE_DIRECTORIES"))); headerInserted = true; } allToggles.Add(addFileToMenu(menu, file)); } } // crawl zips files = Directory.GetFiles(Everest.Loader.PathMods); headerInserted = false; for (int i = 0; i < files.Length; i++) { string file = Path.GetFileName(files[i]); if (file.EndsWith(".zip")) { if (!headerInserted) { menu.Add(new TextMenu.SubHeader(Dialog.Clean("MODOPTIONS_MODTOGGLE_ZIPS"))); headerInserted = true; } allToggles.Add(addFileToMenu(menu, file)); } } // crawl map bins files = Directory.GetFiles(Everest.Loader.PathMods); headerInserted = false; for (int i = 0; i < files.Length; i++) { string file = Path.GetFileName(files[i]); if (file.EndsWith(".bin")) { if (!headerInserted) { menu.Add(new TextMenu.SubHeader(Dialog.Clean("MODOPTIONS_MODTOGGLE_BINS"))); headerInserted = true; } allToggles.Add(addFileToMenu(menu, file)); } } // sort the mods list alphabetically, for output in the blacklist.txt file later. allMods.Sort(); // clone the list to be able to check if the list changed when leaving the menu. blacklistedModsOriginal = new HashSet <string>(blacklistedMods); }
protected override void addOptionsToMenu(TextMenu menu) { // for now, display a "loading" message. TextMenu.Button loading = new TextMenu.Button(Dialog.Clean("MODOPTIONS_MODTOGGLE_LOADING")) { Disabled = true }; menu.Add(loading); modLoadingTask = new Task(() => { // load all the mod yamls (that can take some time), update the progress every 500ms so that the text doesn't go crazy since it is centered. Stopwatch updateTimer = Stopwatch.StartNew(); modYamls = LoadAllModYamls(progress => { if (updateTimer.ElapsedMilliseconds > 500) { updateTimer.Restart(); loading.Label = $"{Dialog.Clean("MODOPTIONS_MODTOGGLE_LOADING")} ({(int) (progress * 100)}%)"; } }); updateTimer.Stop(); MainThreadHelper.Do(() => { modToggles = new Dictionary <string, TextMenu.OnOff>(); // remove the "loading..." message menu.Remove(loading); // if there is a whitelist, warn the user that it will break those settings. if (Everest.Loader.Whitelist != null) { menu.Add(restartMessage1 = new TextMenuExt.SubHeaderExt(Dialog.Clean("MODOPTIONS_MODTOGGLE_WHITELISTWARN")) { TextColor = Color.OrangeRed }); } // display the warning about blacklist.txt + restarting menu.Add(restartMessage1 = new TextMenuExt.SubHeaderExt(Dialog.Clean("MODOPTIONS_MODTOGGLE_MESSAGE_1"))); menu.Add(restartMessage2 = new TextMenuExt.SubHeaderExt(Dialog.Clean("MODOPTIONS_MODTOGGLE_MESSAGE_2")) { HeightExtra = 0f }); menu.Add(new TextMenuExt.SubHeaderExt(Dialog.Clean("MODOPTIONS_MODTOGGLE_MESSAGE_3")) { HeightExtra = 20f, TextColor = Color.Goldenrod }); // reduce spacing between the whitelist warning and the blacklist overwrite warning if (Everest.Loader.Whitelist != null) { restartMessage1.HeightExtra = 30f; } // "enable all" and "disable all" buttons menu.Add(new TextMenu.Button(Dialog.Clean("MODOPTIONS_MODTOGGLE_ENABLEALL")).Pressed(() => { foreach (TextMenu.OnOff toggle in modToggles.Values) { toggle.Index = 1; } blacklistedMods.Clear(); updateHighlightedMods(); })); menu.Add(new TextMenu.Button(Dialog.Clean("MODOPTIONS_MODTOGGLE_DISABLEALL")).Pressed(() => { blacklistedMods.Clear(); foreach (KeyValuePair <string, TextMenu.OnOff> toggle in modToggles) { toggle.Value.Index = 0; blacklistedMods.Add(toggle.Key); } updateHighlightedMods(); })); // "toggle dependencies automatically" button TextMenu.Item toggleDependenciesButton; menu.Add(toggleDependenciesButton = new TextMenu.OnOff(Dialog.Clean("MODOPTIONS_MODTOGGLE_TOGGLEDEPS"), true) .Change(value => toggleDependencies = value)); toggleDependenciesButton.AddDescription(menu, Dialog.Clean("MODOPTIONS_MODTOGGLE_TOGGLEDEPS_MESSAGE2")); toggleDependenciesButton.AddDescription(menu, Dialog.Clean("MODOPTIONS_MODTOGGLE_TOGGLEDEPS_MESSAGE1")); // "cancel" button to leave the screen without saving menu.Add(new TextMenu.Button(Dialog.Clean("MODOPTIONS_MODTOGGLE_CANCEL")).Pressed(() => { blacklistedMods = blacklistedModsOriginal; onBackPressed(Overworld); })); // reset the mods list allMods = new List <string>(); blacklistedMods = new HashSet <string>(); string[] files; bool headerInserted; // crawl directories files = Directory.GetDirectories(Everest.Loader.PathMods); Array.Sort(files, (a, b) => a.ToLowerInvariant().CompareTo(b.ToLowerInvariant())); headerInserted = false; for (int i = 0; i < files.Length; i++) { string file = Path.GetFileName(files[i]); if (file != "Cache") { if (!headerInserted) { menu.Add(new patch_TextMenu.patch_SubHeader(Dialog.Clean("MODOPTIONS_MODTOGGLE_DIRECTORIES"))); headerInserted = true; } addFileToMenu(menu, file); } } // crawl zips files = Directory.GetFiles(Everest.Loader.PathMods); Array.Sort(files, (a, b) => a.ToLowerInvariant().CompareTo(b.ToLowerInvariant())); headerInserted = false; for (int i = 0; i < files.Length; i++) { string file = Path.GetFileName(files[i]); if (file.EndsWith(".zip")) { if (!headerInserted) { menu.Add(new patch_TextMenu.patch_SubHeader(Dialog.Clean("MODOPTIONS_MODTOGGLE_ZIPS"))); headerInserted = true; } addFileToMenu(menu, file); } } // crawl map bins files = Directory.GetFiles(Everest.Loader.PathMods); Array.Sort(files, (a, b) => a.ToLowerInvariant().CompareTo(b.ToLowerInvariant())); headerInserted = false; for (int i = 0; i < files.Length; i++) { string file = Path.GetFileName(files[i]); if (file.EndsWith(".bin")) { if (!headerInserted) { menu.Add(new patch_TextMenu.patch_SubHeader(Dialog.Clean("MODOPTIONS_MODTOGGLE_BINS"))); headerInserted = true; } addFileToMenu(menu, file); } } // sort the mods list alphabetically, for output in the blacklist.txt file later. allMods.Sort((a, b) => a.ToLowerInvariant().CompareTo(b.ToLowerInvariant())); // adjust the mods' color if they are required dependencies for other mods foreach (KeyValuePair <string, TextMenu.OnOff> toggle in modToggles) { if (modHasDependencies(toggle.Key)) { ((patch_TextMenu.patch_Option <bool>)(object) toggle.Value).UnselectedColor = Color.Goldenrod; } } // snap the menu so that it doesn't show a scroll up. menu.Y = menu.ScrollTargetY; // clone the list to be able to check if the list changed when leaving the menu. blacklistedModsOriginal = new HashSet <string>(blacklistedMods); // loading is done! modLoadingTask = null; }); }); modLoadingTask.Start(); }
private void ReloadItems() { foreach (TextMenu.Item item in items) { menu.Remove(item); } items.Clear(); string filterSet = null; if (type == 0) { filterSet = "Celeste"; } else if (type >= 2) { filterSet = sets[type - 2]; } string lastLevelSet = null; LevelSetStats levelSetStats = null; int levelSetAreaOffset = 0; int levelSetUnlockedAreas = int.MaxValue; int levelSetUnlockedModes = int.MaxValue; string name; List <AreaStats> areaStatsAll = SaveData.Instance.Areas; for (int i = 0; i < AreaData.Areas.Count; i++) { AreaData area = AreaData.Areas[i]; if (!area.HasMode((AreaMode)side)) { continue; } string levelSet = area.GetLevelSet(); if ((filterSet == null && levelSet == "Celeste") || (filterSet != null && filterSet != levelSet)) { continue; } if (lastLevelSet != levelSet) { lastLevelSet = levelSet; levelSetStats = SaveData.Instance.GetLevelSetStatsFor(levelSet); levelSetAreaOffset = levelSetStats.AreaOffset; levelSetUnlockedAreas = levelSetStats.UnlockedAreas; levelSetUnlockedModes = levelSetStats.UnlockedModes; if (levelSet != "Celeste") { name = DialogExt.CleanLevelSet(levelSet); TextMenuExt.SubHeaderExt levelSetHeader = new TextMenuExt.SubHeaderExt(name); levelSetHeader.Alpha = 0f; menu.Add(levelSetHeader); items.Add(levelSetHeader); } } name = area.Name; name = name.DialogCleanOrNull() ?? name.SpacedPascalCase(); TextMenuExt.ButtonExt button = new TextMenuExt.ButtonExt(name); button.Alpha = 0f; if (area.Icon != "areas/null") { button.Icon = area.Icon; } button.IconWidth = 64f; if (levelSet == "Celeste" && i > levelSetAreaOffset + levelSetUnlockedAreas) { button.Disabled = true; } if (side == 1 && !areaStatsAll[i].Cassette) { button.Disabled = true; } if (side >= 2 && levelSetUnlockedModes < (side + 1)) { button.Disabled = true; } menu.Add(button.Pressed(() => { Inspect(area, (AreaMode)side); })); items.Add(button); } // Do this afterwards as the menu has now properly updated its size. for (int i = 0; i < items.Count; i++) { Add(new Coroutine(FadeIn(i, items[i]))); } if (menu.Height > menu.ScrollableMinSize) { menu.Position.Y = menu.ScrollTargetY; } }
private void ReloadItems() { foreach (TextMenu.Item item in items) { menu.Remove(item); } items.Clear(); string filterSet = null; if (type == 0) { filterSet = "Celeste"; } else if (type >= 3) { filterSet = sets[type - 3]; } string lastLevelSet = null; LevelSetStats levelSetStats = null; int levelSetAreaOffset = 0; int levelSetUnlockedAreas = int.MaxValue; int levelSetUnlockedModes = int.MaxValue; string name; SaveData save = SaveData.Instance; List <AreaStats> areaStatsAll = save.Areas; for (int i = 0; i < AreaData.Areas.Count; i++) { AreaData area = AreaData.Get(i); if (area == null || !area.HasMode((AreaMode)side)) { continue; } // TODO: Make subchapters hidden by default in the map list, even in debug mode. if (!save.DebugMode && !string.IsNullOrEmpty(area.GetMeta()?.Parent)) { continue; } string levelSet = area.GetLevelSet(); if (type != 1 && ((filterSet == null && levelSet == "Celeste") || (filterSet != null && filterSet != levelSet))) { continue; } name = area.Name; name = name.DialogCleanOrNull() ?? name.SpacedPascalCase(); if (lastLevelSet != levelSet) { lastLevelSet = levelSet; levelSetStats = SaveData.Instance.GetLevelSetStatsFor(levelSet); levelSetAreaOffset = levelSetStats.AreaOffset; levelSetUnlockedAreas = levelSetStats.UnlockedAreas; levelSetUnlockedModes = levelSetStats.UnlockedModes; string setname = DialogExt.CleanLevelSet(levelSet); TextMenuExt.SubHeaderExt levelSetHeader = new TextMenuExt.SubHeaderExt(setname); levelSetHeader.Alpha = 0f; menu.Add(levelSetHeader); items.Add(levelSetHeader); } TextMenuExt.ButtonExt button = new TextMenuExt.ButtonExt(name); button.Alpha = 0f; if (area.Icon != "areas/null") { button.Icon = area.Icon; } button.IconWidth = 64f; if (levelSet == "Celeste" && i > levelSetAreaOffset + levelSetUnlockedAreas) { button.Disabled = true; } if (side == 1 && !areaStatsAll[i].Cassette) { button.Disabled = true; } if (side >= 2 && levelSetUnlockedModes < (side + 1)) { button.Disabled = true; } menu.Add(button.Pressed(() => { Inspect(area, (AreaMode)side); })); items.Add(button); } // compute a delay so that options don't take more than a second to show up if many mods are installed. float delayBetweenOptions = 0.03f; if (items.Count > 0) { delayBetweenOptions = Math.Min(0.03f, 1f / items.Count); } // Do this afterwards as the menu has now properly updated its size. for (int i = 0; i < items.Count; i++) { Add(new Coroutine(FadeIn(i, delayBetweenOptions, items[i]))); } if (menu.Height > menu.ScrollableMinSize) { menu.Position.Y = menu.ScrollTargetY; } }
private void ReloadItems() { foreach (TextMenu.Item item in items) { menu.Remove(item); } items.Clear(); foreach (Everest.Updater.Source source in Everest.Updater.Sources) { TextMenuExt.SubHeaderExt header = new TextMenuExt.SubHeaderExt(source.NameDialog.DialogClean()); header.Alpha = 0f; menu.Add(header); items.Add(header); if (source.ErrorDialog != null) { string text = source.ErrorDialog.DialogClean(); TextMenuExt.SubHeaderExt error = new TextMenuExt.SubHeaderExt(text); error.Alpha = 0f; menu.Add(error); items.Add(error); continue; } if (source.Entries == null) { TextMenuExt.SubHeaderExt info = new TextMenuExt.SubHeaderExt(Dialog.Clean("updater_versions_requesting")); info.Alpha = 0f; menu.Add(info); items.Add(info); continue; } string branch = null; int count = 0; foreach (Everest.Updater.Entry entry in source.Entries) { if (entry.Branch != branch) { branch = entry.Branch; count = 0; if (!string.IsNullOrEmpty(entry.Branch)) { TextMenuExt.SubHeaderExt headerBranch = new TextMenuExt.SubHeaderExt("branch: " + entry.Branch); headerBranch.Alpha = 0f; menu.Add(headerBranch); items.Add(headerBranch); } } if (count >= buildsPerBranch) { continue; } count++; TextMenuExt.ButtonExt item = new TextMenuExt.ButtonExt(entry.Name); item.Alpha = 0f; menu.Add(item.Pressed(() => { Everest.Updater.Update(OuiModOptions.Instance.Overworld.Goto <OuiLoggedProgress>(), entry); })); items.Add(item); continue; } } // Do this afterwards as the menu has now properly updated its size. for (int i = 0; i < items.Count; i++) { Add(new Coroutine(FadeIn(i, items[i]))); } if (menu.Height > menu.ScrollableMinSize) { menu.Position.Y = menu.ScrollTargetY; } }
public override IEnumerator Enter(Oui from) { menu = new 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"))); fetchingButton = new TextMenu.Button(Dialog.Clean("MODUPDATECHECKER_FETCHING")); fetchingButton.Disabled = true; menu.Add(fetchingButton); Scene.Add(menu); menu.Visible = Visible = true; menu.Focused = false; for (float p = 0f; p < 1f; p += Engine.DeltaTime * 4f) { menu.X = offScreenX + -1920f * Ease.CubeOut(p); alpha = Ease.CubeOut(p); yield return(null); } menu.Focused = true; task = new Task(() => { try { // 1. Download the updates list string modUpdaterDatabaseUrl = getModUpdaterDatabaseUrl(); Logger.Log("OuiModUpdateList", $"Downloading last versions list from {modUpdaterDatabaseUrl}"); using (WebClient wc = new WebClient()) { string yamlData = wc.DownloadString(modUpdaterDatabaseUrl); updateCatalog = new Deserializer().Deserialize <Dictionary <string, ModUpdateInfo> >(yamlData); foreach (string name in updateCatalog.Keys) { updateCatalog[name].Name = name; } Logger.Log("OuiModUpdateList", $"Downloaded {updateCatalog.Count} item(s)"); } } catch (Exception e) { Logger.Log("OuiModUpdateList", $"Downloading database failed!"); Logger.LogDetailed(e); } // 2. Find out what actually has been updated availableUpdatesCatalog.Clear(); if (updateCatalog != null) { Logger.Log("OuiModUpdateList", "Checking for updates"); foreach (EverestModule module in Everest.Modules) { EverestModuleMetadata metadata = module.Metadata; if (metadata.PathArchive != null && updateCatalog.ContainsKey(metadata.Name)) { string xxHashStringInstalled = BitConverter.ToString(metadata.Hash).Replace("-", "").ToLowerInvariant(); Logger.Log("OuiModUpdateList", $"Mod {metadata.Name}: installed hash {xxHashStringInstalled}, latest hash(es) {string.Join(", ", updateCatalog[metadata.Name].xxHash)}"); if (!updateCatalog[metadata.Name].xxHash.Contains(xxHashStringInstalled)) { availableUpdatesCatalog.Add(updateCatalog[metadata.Name], metadata); } } } Logger.Log("OuiModUpdateList", $"{availableUpdatesCatalog.Count} update(s) available"); } }); task.Start(); }