From 04d020f3efcca10f71c17d3d66669523fd51c2fe Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 18 Jan 2025 10:09:45 +0000 Subject: [PATCH 1/5] @TheRealLyonic has signed the CLA in SubnauticaModding/Nautilus#583 --- CLA/Signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CLA/Signatures.json b/CLA/Signatures.json index 4eda0689..5226e154 100644 --- a/CLA/Signatures.json +++ b/CLA/Signatures.json @@ -103,6 +103,14 @@ "created_at": "2024-12-06T23:01:55Z", "repoId": 123711758, "pullRequestNo": 568 + }, + { + "name": "TheRealLyonic", + "id": 67993317, + "comment_id": 2599656575, + "created_at": "2025-01-18T10:09:32Z", + "repoId": 123711758, + "pullRequestNo": 583 } ] } \ No newline at end of file From 2ff809975fe07505b1282b96644ff87d9acf4ab5 Mon Sep 17 00:00:00 2001 From: Lee23 <31892011+LeeTwentyThree@users.noreply.github.com> Date: Sat, 1 Feb 2025 02:51:23 -0500 Subject: [PATCH 2/5] Commit the forgotten pre.34 version tag --- Version.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Version.targets b/Version.targets index 60adffa4..9c035281 100644 --- a/Version.targets +++ b/Version.targets @@ -3,7 +3,7 @@ 1.0.0 - 33 + 34 pre.$(SuffixNumber) \ No newline at end of file From c70f4086b27e3d6fabd432357417580c56198a1a Mon Sep 17 00:00:00 2001 From: Lee23 <31892011+LeeTwentyThree@users.noreply.github.com> Date: Sun, 2 Feb 2025 20:14:19 -0500 Subject: [PATCH 3/5] feat: Add a dependency warning popup and a user-friendly menu to view errors (#586) * Add dependency warning messages * Completely overhaul the system * Move button to bottom of screen * Fix formatting in BZ * Fix old options existing over menu in BZ * Organize error messages better --- Nautilus/Initializer.cs | 1 + .../MonoBehaviours/PluginLoadErrorMenu.cs | 9 + Nautilus/Patchers/DependencyWarningPatcher.cs | 202 ++++++++++++++++++ 3 files changed, 212 insertions(+) create mode 100644 Nautilus/MonoBehaviours/PluginLoadErrorMenu.cs create mode 100644 Nautilus/Patchers/DependencyWarningPatcher.cs diff --git a/Nautilus/Initializer.cs b/Nautilus/Initializer.cs index 0b7b4ac7..3ff1461b 100644 --- a/Nautilus/Initializer.cs +++ b/Nautilus/Initializer.cs @@ -85,5 +85,6 @@ static Initializer() WaterParkPatcher.Patch(_harmony); ModMessageSystem.Patch(); BiomePatcher.Patch(_harmony); + DependencyWarningPatcher.Patch(_harmony); } } diff --git a/Nautilus/MonoBehaviours/PluginLoadErrorMenu.cs b/Nautilus/MonoBehaviours/PluginLoadErrorMenu.cs new file mode 100644 index 00000000..aa337d07 --- /dev/null +++ b/Nautilus/MonoBehaviours/PluginLoadErrorMenu.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace Nautilus.MonoBehaviours; + +internal class PluginLoadErrorMenu : MonoBehaviour +{ + public void OnButtonOpen() => gameObject.SetActive(true); + public void OnButtonClose() => gameObject.SetActive(false); +} \ No newline at end of file diff --git a/Nautilus/Patchers/DependencyWarningPatcher.cs b/Nautilus/Patchers/DependencyWarningPatcher.cs new file mode 100644 index 00000000..1175ed57 --- /dev/null +++ b/Nautilus/Patchers/DependencyWarningPatcher.cs @@ -0,0 +1,202 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using BepInEx.Bootstrap; +using HarmonyLib; +using Nautilus.MonoBehaviours; +using Nautilus.Utility; +using TMPro; +using UnityEngine; +using UnityEngine.UI; +using Object = UnityEngine.Object; + +namespace Nautilus.Patchers; + +internal static class DependencyWarningPatcher +{ + internal static void Patch(Harmony harmony) + { + harmony.PatchAll(typeof(DependencyWarningPatcher)); + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(uGUI_MainMenu), nameof(uGUI_MainMenu.Start))] + private static void MainMenuStartPostfix(uGUI_MainMenu __instance) + { + try + { + CreateDependencyWarningUI(__instance); + } + catch (Exception e) + { + InternalLogger.Error("Failed to create main menu dependency warning UI! Exception thrown: " + e); + } + } + + private static void CreateDependencyWarningUI(uGUI_MainMenu mainMenu) + { + var dependencyErrors = Chainloader.DependencyErrors; + if (dependencyErrors.Count == 0) + return; + + var missingDependencies = GetMissingDependencies(); + var formattedMissingDependencies = FormatMissingDependencies(missingDependencies); + + // -- Add warning text -- + var textReference = mainMenu.transform.Find("Panel/MainMenu/PlayerName").gameObject; + var textObject = Object.Instantiate(textReference, textReference.transform.parent, true); + textObject.name = "NautilusDependencyWarningText"; + Object.DestroyImmediate(textObject.GetComponent()); + textObject.SetActive(true); + var transform = textObject.GetComponent(); + transform.anchorMin = new Vector2(0, 1); + transform.anchorMax = new Vector2(1, 1); + transform.pivot = new Vector2(0.5f, 0); + transform.sizeDelta = new Vector2(1, 40); + transform.offsetMin = new Vector2(-0.5f, 0); + transform.offsetMax = new Vector2(-0.5f, 570); + var text = textObject.GetComponentInChildren(); + text.overflowMode = TextOverflowModes.Ellipsis; + text.alignment = TextAlignmentOptions.Center; + text.color = Color.red; + text.richText = true; + text.geometrySortingOrder = VertexSortingOrder.Reverse; + text.fontStyle = FontStyles.Bold; + text.text = "Some mods failed to load! Please view the mod load errors for more details.\n" + + formattedMissingDependencies + ""; + + // -- Add mod load errors window -- + var optionsWindowReference = mainMenu.transform.Find("Panel/Options"); + var errorsMenuPanel = + Object.Instantiate(optionsWindowReference.gameObject, optionsWindowReference.parent, true); + errorsMenuPanel.name = "NautilusModErrorsWindow"; + var menuBehaviour = errorsMenuPanel.AddComponent(); + errorsMenuPanel.SetActive(false); + var optionsPanel = errorsMenuPanel.GetComponentInChildren(); + var panePrefab = optionsPanel.panePrefab; + Object.DestroyImmediate(optionsPanel); + var errorsMenuHeader = errorsMenuPanel.transform.Find("Header"); + errorsMenuHeader.gameObject.GetComponent().text = "BepInEx plugin load errors"; + Object.DestroyImmediate(errorsMenuHeader.GetComponent()); + errorsMenuPanel.transform.Find("Middle/TabsHolder").gameObject.SetActive(false); + var panesHolder = errorsMenuPanel.transform.Find("Middle/PanesHolder"); + foreach (Transform child in panesHolder) + { + Object.Destroy(child.gameObject); + } + var mainPaneTransform = Object.Instantiate(panePrefab, panesHolder).transform; + var mainPaneContent = mainPaneTransform.Find("Viewport/Content"); +#if BELOWZERO + var layoutGroup = mainPaneContent.gameObject.GetComponent(); + layoutGroup.spacing = 65; + layoutGroup.padding = new RectOffset(15, 15, 40, 15); +#endif + // Create a list of all error messages that should be displayed + var errorsToDisplay = new List + { + $"{formattedMissingDependencies}", + "Mod load errors:" + }; + errorsToDisplay.AddRange(dependencyErrors.Where(ShouldDisplayError)); + // Add error messages to menu + foreach (var error in errorsToDisplay) + { + var errorEntryTextObj = Object.Instantiate(textReference, mainPaneContent, true); + Object.DestroyImmediate(errorEntryTextObj.GetComponent()); + var errorEntryText = errorEntryTextObj.GetComponent(); + errorEntryText.text = error; + errorEntryText.enableWordWrapping = true; + errorEntryText.fontSize = 25; + errorEntryText.richText = true; + errorEntryTextObj.SetActive(true); + errorEntryTextObj.transform.localScale = Vector3.one; + } + + // Fix up buttons and add close window button + var closeWindowButton = errorsMenuPanel.transform.Find("Bottom/ButtonBack").gameObject; + Object.DestroyImmediate(closeWindowButton.GetComponentInChildren()); + closeWindowButton.GetComponentInChildren().text = "Close"; + var closeWindowButtonComponent = closeWindowButton.GetComponent