From 8e22226d99028d13193dc2d2abf8592586ee988e Mon Sep 17 00:00:00 2001 From: Omar Akermi Date: Thu, 24 Apr 2025 01:39:11 +0200 Subject: [PATCH 1/3] fix: safe Il2cpp clear children --- S1API/UI/UIFactory.cs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/S1API/UI/UIFactory.cs b/S1API/UI/UIFactory.cs index 831f68ab..8001625e 100644 --- a/S1API/UI/UIFactory.cs +++ b/S1API/UI/UIFactory.cs @@ -10,6 +10,8 @@ using System; using UnityEngine.Events; using System.Collections.Generic; +using MelonLoader; +using Object = UnityEngine.Object; namespace S1API.UI { @@ -239,8 +241,28 @@ public static void CreateRowButton(GameObject go, UnityAction clickHandler, bool /// The transform whose child objects will be destroyed. public static void ClearChildren(Transform parent) { - foreach (Transform child in parent) - GameObject.Destroy(child.gameObject); + if (parent == null) + { + MelonLogger.Warning("[UIFactory] ClearChildren called with null parent."); + return; + } + + try + { + int count = parent.childCount; + for (int i = count - 1; i >= 0; i--) + { + var child = parent.GetChild(i); + if (child != null) + Object.Destroy(child.gameObject); + } + + MelonLogger.Msg($"[UIFactory] Cleared {count} children from: {parent.name}"); + } + catch (System.Exception e) + { + MelonLogger.Error($"[UIFactory] Exception during ClearChildren: {e.Message}"); + } } /// Configures a GameObject to use a VerticalLayoutGroup with specified spacing and padding. From a5c4f1d823593b9496995d2f959b6d7683c1db3f Mon Sep 17 00:00:00 2001 From: Omar Akermi Date: Thu, 24 Apr 2025 01:42:58 +0200 Subject: [PATCH 2/3] fix: unnecessary --- S1API/UI/UIFactory.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/S1API/UI/UIFactory.cs b/S1API/UI/UIFactory.cs index 8001625e..fc3795a3 100644 --- a/S1API/UI/UIFactory.cs +++ b/S1API/UI/UIFactory.cs @@ -243,7 +243,6 @@ public static void ClearChildren(Transform parent) { if (parent == null) { - MelonLogger.Warning("[UIFactory] ClearChildren called with null parent."); return; } @@ -257,11 +256,10 @@ public static void ClearChildren(Transform parent) Object.Destroy(child.gameObject); } - MelonLogger.Msg($"[UIFactory] Cleared {count} children from: {parent.name}"); } catch (System.Exception e) { - MelonLogger.Error($"[UIFactory] Exception during ClearChildren: {e.Message}"); + return; } } From 93d89564e5fb44166b4fd6b1b32b9255f0db8478 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Wed, 23 Apr 2025 19:11:13 -0500 Subject: [PATCH 3/3] fix: Resolved issue with missing folder for Thunderstore installations (original fix did not work) --- S1APILoader/S1APILoader.cs | 19 ++++++++----------- S1APILoader/S1APILoader.csproj | 3 +++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/S1APILoader/S1APILoader.cs b/S1APILoader/S1APILoader.cs index 61a0d1ac..4c53f247 100644 --- a/S1APILoader/S1APILoader.cs +++ b/S1APILoader/S1APILoader.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Reflection; using MelonLoader; [assembly: MelonInfo(typeof(S1APILoader.S1APILoader), "S1APILoader", "{VERSION_NUMBER}", "KaBooMa")] @@ -12,29 +13,25 @@ public class S1APILoader : MelonPlugin public override void OnPreModsLoaded() { - string? pluginsFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); + string? pluginsFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (pluginsFolder == null) throw new Exception("Failed to identify plugins folder."); - string gameFolder = Path.Combine(pluginsFolder, ".."); - string modsFolder = Path.Combine(gameFolder, "Mods"); - string buildsFolder = Path.Combine(pluginsFolder, BuildFolderName); string activeBuild = MelonUtils.IsGameIl2Cpp() ? "Il2Cpp" : "Mono"; MelonLogger.Msg($"Loading S1API for {activeBuild}..."); string s1APIBuildFile = Path.Combine(buildsFolder, $"S1API.{activeBuild}.dll"); - - - string s1APIModFile = Path.Combine(modsFolder, "S1API.dll"); // FIX: https://github.com/KaBooMa/S1API/issues/30 - // Create the Mods directory. - // Thunderstore doesn't by default like MelonLoader in your base installation folder. - Directory.CreateDirectory(modsFolder); + // Manual assembly loading versus file manipulation. + // Thunderstore doesn't pick it up if we do file manipulation. + Assembly assembly = Assembly.LoadFile(s1APIBuildFile); + MelonAssembly melonAssembly = MelonAssembly.LoadMelonAssembly(s1APIBuildFile, assembly); + foreach (MelonBase melon in melonAssembly.LoadedMelons) + melon.Register(); - File.Copy(s1APIBuildFile, s1APIModFile, true); MelonLogger.Msg($"Successfully loaded S1API for {activeBuild}!"); } } diff --git a/S1APILoader/S1APILoader.csproj b/S1APILoader/S1APILoader.csproj index fd88de01..8d79d7be 100644 --- a/S1APILoader/S1APILoader.csproj +++ b/S1APILoader/S1APILoader.csproj @@ -14,6 +14,9 @@ + + $(MelonLoaderAssembliesPath)\0Harmony.dll +