From c63fd4499edbbd48bf9def7654612b308365302a Mon Sep 17 00:00:00 2001 From: MaxtorCoder Date: Sat, 26 Apr 2025 12:55:52 +0200 Subject: [PATCH 1/3] feat: Implement BepInEx modloader support - Add centralized Log class for both BepInEx and MelonLoader - Add `MonoBepInEx` and `Il2CppBepInEx` configurations - Improve `.csproj` layout for S1API --- .gitignore | 1 + S1API.sln | 30 ++-- S1API/Console/ConsoleHelper.cs | 6 +- S1API/DeadDrops/DeadDropInstance.cs | 6 +- S1API/DeadDrops/DeadDropManager.cs | 6 +- S1API/GameTime/GameDateTime.cs | 6 +- S1API/GameTime/TimeManager.cs | 6 +- S1API/Internal/Abstraction/ISaveable.cs | 4 +- S1API/Internal/Abstraction/Saveable.cs | 4 +- S1API/Internal/Patches/NPCPatches.cs | 6 +- S1API/Internal/Patches/PhoneAppPatches.cs | 11 +- S1API/Internal/Patches/QuestPatches.cs | 6 +- S1API/Internal/Patches/TimePatches.cs | 6 +- S1API/Internal/Utils/CrossType.cs | 26 ++-- S1API/Internal/Utils/ImageUtils.cs | 13 +- S1API/Items/ItemDefinition.cs | 6 +- S1API/Items/ItemInstance.cs | 6 +- S1API/Items/ItemManager.cs | 6 +- S1API/Items/ItemSlotInstance.cs | 6 +- S1API/Leveling/LevelManager.cs | 6 +- S1API/Logging/Log.cs | 81 +++++++++++ S1API/Money/CashDefinition.cs | 6 +- S1API/Money/CashInstance.cs | 6 +- S1API/NPCs/NPC.cs | 14 +- S1API/NPCs/NPCInstance.cs | 6 +- S1API/NPCs/Response.cs | 6 +- S1API/PhoneApp/PhoneApp.cs | 27 +++- S1API/Products/CocaineDefinition.cs | 6 +- S1API/Products/MethDefinition.cs | 6 +- S1API/Products/PackagingDefinition.cs | 6 +- S1API/Products/ProductDefinition.cs | 6 +- S1API/Products/ProductDefinitionWrapper.cs | 4 +- S1API/Products/ProductInstance.cs | 6 +- S1API/Products/ProductManager.cs | 6 +- S1API/Products/WeedDefinition.cs | 6 +- S1API/Quests/Quest.cs | 10 +- S1API/Quests/QuestEntry.cs | 6 +- S1API/S1API.cs | 18 ++- S1API/S1API.csproj | 154 +++++++++------------ S1API/Storages/StorageInstance.cs | 6 +- S1API/UI/UIFactory.cs | 8 +- S1APILoader/S1APILoader.csproj | 2 +- example.build.props | 3 +- 43 files changed, 334 insertions(+), 232 deletions(-) create mode 100644 S1API/Logging/Log.cs diff --git a/.gitignore b/.gitignore index cf6412f6..4b329393 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ obj/ bin/ *.user +.vs/ # Build props local.* diff --git a/S1API.sln b/S1API.sln index b923963a..72b17c00 100644 --- a/S1API.sln +++ b/S1API.sln @@ -6,17 +6,27 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "S1APILoader", "S1APILoader\ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Mono|Any CPU = Mono|Any CPU - Il2Cpp|Any CPU = Il2Cpp|Any CPU + MonoBepInEx|Any CPU = MonoBepInEx|Any CPU + Il2CppMelon|Any CPU = Il2CppMelon|Any CPU + MonoMelon|Any CPU = MonoMelon|Any CPU + Il2CppBepInEx|Any CPU = Il2CppBepInEx|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Mono|Any CPU.ActiveCfg = Mono|Any CPU - {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Mono|Any CPU.Build.0 = Mono|Any CPU - {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Il2Cpp|Any CPU.ActiveCfg = Il2Cpp|Any CPU - {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Il2Cpp|Any CPU.Build.0 = Il2Cpp|Any CPU - {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Mono|Any CPU.ActiveCfg = Mono|Any CPU - {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Mono|Any CPU.Build.0 = Mono|Any CPU - {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Il2Cpp|Any CPU.ActiveCfg = Il2Cpp|Any CPU - {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Il2Cpp|Any CPU.Build.0 = Il2Cpp|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.MonoBepInEx|Any CPU.ActiveCfg = MonoBepInEx|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.MonoBepInEx|Any CPU.Build.0 = MonoBepInEx|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Il2CppMelon|Any CPU.ActiveCfg = Il2CppMelon|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Il2CppMelon|Any CPU.Build.0 = Il2CppMelon|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.MonoMelon|Any CPU.ActiveCfg = MonoMelon|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.MonoMelon|Any CPU.Build.0 = MonoMelon|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Il2CppBepInEx|Any CPU.ActiveCfg = Il2CppBepInEx|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Il2CppBepInEx|Any CPU.Build.0 = Il2CppBepInEx|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.MonoBepInEx|Any CPU.ActiveCfg = MonoBepInEx|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.MonoBepInEx|Any CPU.Build.0 = MonoBepInEx|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Il2CppMelon|Any CPU.ActiveCfg = Il2CppMelon|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Il2CppMelon|Any CPU.Build.0 = Il2CppMelon|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.MonoMelon|Any CPU.ActiveCfg = MonoMelon|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.MonoMelon|Any CPU.Build.0 = MonoMelon|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Il2CppBepInEx|Any CPU.ActiveCfg = Il2CppBepInEx|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Il2CppBepInEx|Any CPU.Build.0 = Il2CppBepInEx|Any CPU EndGlobalSection EndGlobal diff --git a/S1API/Console/ConsoleHelper.cs b/S1API/Console/ConsoleHelper.cs index 60e54d82..ef60823b 100644 --- a/S1API/Console/ConsoleHelper.cs +++ b/S1API/Console/ConsoleHelper.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using Il2CppSystem.Collections.Generic; using static Il2CppScheduleOne.Console; @@ -19,7 +19,7 @@ public static class ConsoleHelper /// The cash amount to add or remove. public static void RunCashCommand(int amount) { -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX var command = new ChangeCashCommand(); var args = new Il2CppSystem.Collections.Generic.List(); #else @@ -30,4 +30,4 @@ public static void RunCashCommand(int amount) command.Execute(args); } } -} \ No newline at end of file +} diff --git a/S1API/DeadDrops/DeadDropInstance.cs b/S1API/DeadDrops/DeadDropInstance.cs index ee49c249..91c57942 100644 --- a/S1API/DeadDrops/DeadDropInstance.cs +++ b/S1API/DeadDrops/DeadDropInstance.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Economy = Il2CppScheduleOne.Economy; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Economy = ScheduleOne.Economy; #endif @@ -59,4 +59,4 @@ internal DeadDropInstance(S1Economy.DeadDrop deadDrop) => public Vector3 Position => S1DeadDrop.transform.position; } -} \ No newline at end of file +} diff --git a/S1API/DeadDrops/DeadDropManager.cs b/S1API/DeadDrops/DeadDropManager.cs index edf1345c..e162f337 100644 --- a/S1API/DeadDrops/DeadDropManager.cs +++ b/S1API/DeadDrops/DeadDropManager.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Economy = Il2CppScheduleOne.Economy; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Economy = ScheduleOne.Economy; #endif @@ -19,4 +19,4 @@ public class DeadDropManager public static DeadDropInstance[] All => S1Economy.DeadDrop.DeadDrops.ToArray() .Select(deadDrop => new DeadDropInstance(deadDrop)).ToArray(); } -} \ No newline at end of file +} diff --git a/S1API/GameTime/GameDateTime.cs b/S1API/GameTime/GameDateTime.cs index bf72ea81..ce8ac68c 100644 --- a/S1API/GameTime/GameDateTime.cs +++ b/S1API/GameTime/GameDateTime.cs @@ -1,7 +1,7 @@ // TODO: Implement GameDateTime wrapper -// #if (IL2CPP) +// #if (IL2CPPMELON || IL2CPPBEPINEX) // using S1GameTime = Il2CppScheduleOne.GameTime; -// #elif (MONO) +// #elif (MONOMELON || MONOBEPINEX) // using S1GameTime = ScheduleOne.GameTime; // #endif // @@ -19,4 +19,4 @@ // // public void Ad // } -// } \ No newline at end of file +// } diff --git a/S1API/GameTime/TimeManager.cs b/S1API/GameTime/TimeManager.cs index 45f78f9c..5f658135 100644 --- a/S1API/GameTime/TimeManager.cs +++ b/S1API/GameTime/TimeManager.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1GameTime = Il2CppScheduleOne.GameTime; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1GameTime = ScheduleOne.GameTime; #endif @@ -24,4 +24,4 @@ public static class TimeManager public static Day CurrentDay => (Day)S1GameTime.TimeManager.Instance.CurrentDay; } -} \ No newline at end of file +} diff --git a/S1API/Internal/Abstraction/ISaveable.cs b/S1API/Internal/Abstraction/ISaveable.cs index 6ac86151..94a5431e 100644 --- a/S1API/Internal/Abstraction/ISaveable.cs +++ b/S1API/Internal/Abstraction/ISaveable.cs @@ -1,4 +1,4 @@ -#if (MONO) +#if (MONOMELON || MONOBEPINEX) using System.Collections.Generic; #elif (IL2CPP) using Il2CppSystem.Collections.Generic; @@ -46,4 +46,4 @@ internal interface ISaveable : IRegisterable Converters = new System.Collections.Generic.List() { new GUIDReferenceConverter() } }; } -} \ No newline at end of file +} diff --git a/S1API/Internal/Abstraction/Saveable.cs b/S1API/Internal/Abstraction/Saveable.cs index b40c61aa..4dd23602 100644 --- a/S1API/Internal/Abstraction/Saveable.cs +++ b/S1API/Internal/Abstraction/Saveable.cs @@ -1,4 +1,4 @@ -#if (MONO) +#if (MONOMELON || MONOBEPINEX) using System.Collections.Generic; #elif (IL2CPP) using Il2CppSystem.Collections.Generic; @@ -119,4 +119,4 @@ void ISaveable.OnSaved() => /// protected virtual void OnSaved() { } } -} \ No newline at end of file +} diff --git a/S1API/Internal/Patches/NPCPatches.cs b/S1API/Internal/Patches/NPCPatches.cs index c4304982..b00bba50 100644 --- a/S1API/Internal/Patches/NPCPatches.cs +++ b/S1API/Internal/Patches/NPCPatches.cs @@ -1,8 +1,8 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Loaders = Il2CppScheduleOne.Persistence.Loaders; using S1NPCs = Il2CppScheduleOne.NPCs; using Il2CppSystem.Collections.Generic; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Loaders = ScheduleOne.Persistence.Loaders; using S1NPCs = ScheduleOne.NPCs; using System.Collections.Generic; @@ -84,4 +84,4 @@ private static void NPCOnDestroy(S1NPCs.NPC __instance) NPCs.Remove(npc); } } -} \ No newline at end of file +} diff --git a/S1API/Internal/Patches/PhoneAppPatches.cs b/S1API/Internal/Patches/PhoneAppPatches.cs index 30804bfb..7d48da32 100644 --- a/S1API/Internal/Patches/PhoneAppPatches.cs +++ b/S1API/Internal/Patches/PhoneAppPatches.cs @@ -3,11 +3,12 @@ using UnityEngine.SceneManagement; using S1API.Internal.Utils; using S1API.Internal.Abstraction; +using S1API.Logging; using S1API.PhoneApp; namespace S1API.Internal.Patches -{ -#if IL2CPP +{ +#if IL2CPPMELON || IL2CPPBEPINEX [HarmonyPatch(typeof(SceneManager), nameof(SceneManager.Internal_SceneLoaded))] #else [HarmonyPatch(typeof(SceneManager), "Internal_SceneLoaded", new Type[] { typeof(Scene), typeof(LoadSceneMode) })] @@ -15,6 +16,8 @@ namespace S1API.Internal.Patches #endif internal static class PhoneAppPatches { + private static readonly Log _loggerInstance = new Log("PhoneAppPatches"); + private static bool _loaded = false; /// @@ -41,9 +44,9 @@ static void Postfix(Scene scene, LoadSceneMode mode) } catch (System.Exception e) { - MelonLoader.MelonLogger.Warning($"[PhoneApp] Failed to register {type.FullName}: {e.Message}"); + _loggerInstance.Warning($"[PhoneApp] Failed to register {type.FullName}: {e.Message}"); } } } } -} \ No newline at end of file +} diff --git a/S1API/Internal/Patches/QuestPatches.cs b/S1API/Internal/Patches/QuestPatches.cs index 6e9fd49a..6b825e21 100644 --- a/S1API/Internal/Patches/QuestPatches.cs +++ b/S1API/Internal/Patches/QuestPatches.cs @@ -1,9 +1,9 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Loaders = Il2CppScheduleOne.Persistence.Loaders; using S1Datas = Il2CppScheduleOne.Persistence.Datas; using S1Quests = Il2CppScheduleOne.Quests; using Il2CppSystem.Collections.Generic; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Loaders = ScheduleOne.Persistence.Loaders; using S1Datas = ScheduleOne.Persistence.Datas; using S1Quests = ScheduleOne.Quests; @@ -128,4 +128,4 @@ private static void QuestStart(S1Quests.Quest __instance) => // NPCs.Remove(npc); // } } -} \ No newline at end of file +} diff --git a/S1API/Internal/Patches/TimePatches.cs b/S1API/Internal/Patches/TimePatches.cs index 34a3f176..32712fbe 100644 --- a/S1API/Internal/Patches/TimePatches.cs +++ b/S1API/Internal/Patches/TimePatches.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1GameTime = Il2CppScheduleOne.GameTime; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1GameTime = ScheduleOne.GameTime; #endif @@ -33,4 +33,4 @@ void DayPass() __instance.onDayPass += (Action)DayPass; } } -} \ No newline at end of file +} diff --git a/S1API/Internal/Utils/CrossType.cs b/S1API/Internal/Utils/CrossType.cs index 5ce09684..f1d0bdad 100644 --- a/S1API/Internal/Utils/CrossType.cs +++ b/S1API/Internal/Utils/CrossType.cs @@ -1,6 +1,6 @@ -#if (MONO) +#if (MONOMELON || MONOBEPINEX) using System; -# elif (IL2CPP) +# elif (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppSystem; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; @@ -21,9 +21,9 @@ internal static class CrossType /// The type of the class. internal static Type Of() { -#if (MONO) +#if (MONOMELON || MONOBEPINEX) return typeof(T); -# elif (IL2CPP) +# elif (IL2CPPMELON || IL2CPPBEPINEX) return Il2CppType.Of(); #endif } @@ -36,13 +36,13 @@ internal static Type Of() /// The class we're checking against. /// Whether obj is of class T or not. internal static bool Is(object obj, out T result) -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) where T : Il2CppObjectBase -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) where T : class #endif { -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) if (obj is Object il2CppObj) { Type il2CppType = Il2CppType.Of(); @@ -52,7 +52,7 @@ internal static bool Is(object obj, out T result) return true; } } -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) if (obj is T t) { result = t; @@ -71,16 +71,16 @@ internal static bool Is(object obj, out T result) /// The type to cast to. /// The object cast to the specified type. internal static T As(object obj) -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) where T : Il2CppObjectBase -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) where T : class #endif => -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) obj is Object il2CppObj ? il2CppObj.Cast() : null!; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) (T)obj; #endif } -} \ No newline at end of file +} diff --git a/S1API/Internal/Utils/ImageUtils.cs b/S1API/Internal/Utils/ImageUtils.cs index 1f072b6f..8ca166e1 100644 --- a/S1API/Internal/Utils/ImageUtils.cs +++ b/S1API/Internal/Utils/ImageUtils.cs @@ -1,14 +1,13 @@ -using MelonLoader; -using System; -using System.Collections.Generic; +using S1API.Logging; using System.IO; -using System.Text; using UnityEngine; namespace S1API.Internal.Utils { public static class ImageUtils { + private static readonly Log _loggerInstance = new Log("ImageUtils"); + /// /// Loads an image from the specified file path and converts it into a Sprite object. /// @@ -21,7 +20,7 @@ public static Sprite LoadImage(string fileName) string fullPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) ?? string.Empty, fileName); if (!File.Exists(fullPath)) { - MelonLogger.Error($"❌ Icon file not found: {fullPath}"); + _loggerInstance.Error($"❌ Icon file not found: {fullPath}"); return null; } @@ -36,10 +35,10 @@ public static Sprite LoadImage(string fileName) } catch (System.Exception ex) { - MelonLogger.Error("❌ Failed to load sprite: " + ex); + _loggerInstance.Error("❌ Failed to load sprite: " + ex); } return null; } } -} \ No newline at end of file +} diff --git a/S1API/Items/ItemDefinition.cs b/S1API/Items/ItemDefinition.cs index b7884c67..cff1924b 100644 --- a/S1API/Items/ItemDefinition.cs +++ b/S1API/Items/ItemDefinition.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; #endif @@ -115,4 +115,4 @@ public override int GetHashCode() => public virtual ItemInstance CreateInstance(int quantity = 1) => new ItemInstance(S1ItemDefinition.GetDefaultInstance(quantity)); } -} \ No newline at end of file +} diff --git a/S1API/Items/ItemInstance.cs b/S1API/Items/ItemInstance.cs index 5d498184..2fdb7f35 100644 --- a/S1API/Items/ItemInstance.cs +++ b/S1API/Items/ItemInstance.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; #endif @@ -32,4 +32,4 @@ internal ItemInstance(S1ItemFramework.ItemInstance itemInstance) => public ItemDefinition Definition => new ItemDefinition(S1ItemInstance.Definition); } -} \ No newline at end of file +} diff --git a/S1API/Items/ItemManager.cs b/S1API/Items/ItemManager.cs index 10551c92..e886c6df 100644 --- a/S1API/Items/ItemManager.cs +++ b/S1API/Items/ItemManager.cs @@ -1,8 +1,8 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1 = Il2CppScheduleOne; using S1ItemFramework = Il2CppScheduleOne.ItemFramework; using S1Product = Il2CppScheduleOne.Product; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1 = ScheduleOne; using S1ItemFramework = ScheduleOne.ItemFramework; using S1Product = ScheduleOne.Product; @@ -39,4 +39,4 @@ public static ItemDefinition GetItemDefinition(string itemID) return new ItemDefinition(itemDefinition); } } -} \ No newline at end of file +} diff --git a/S1API/Items/ItemSlotInstance.cs b/S1API/Items/ItemSlotInstance.cs index 5b6d750b..ad51429d 100644 --- a/S1API/Items/ItemSlotInstance.cs +++ b/S1API/Items/ItemSlotInstance.cs @@ -1,7 +1,7 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; using S1Product = Il2CppScheduleOne.Product; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; using S1Product = ScheduleOne.Product; #endif @@ -67,4 +67,4 @@ public ItemInstance? ItemInstance public void AddQuantity(int amount) => S1ItemSlot.ChangeQuantity(amount); } -} \ No newline at end of file +} diff --git a/S1API/Leveling/LevelManager.cs b/S1API/Leveling/LevelManager.cs index c9a8ac8e..5bbc31a1 100644 --- a/S1API/Leveling/LevelManager.cs +++ b/S1API/Leveling/LevelManager.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Levelling = Il2CppScheduleOne.Levelling; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Levelling = ScheduleOne.Levelling; #endif @@ -16,4 +16,4 @@ public static class LevelManager /// public static Rank Rank = (Rank)S1Levelling.LevelManager.Instance.Rank; } -} \ No newline at end of file +} diff --git a/S1API/Logging/Log.cs b/S1API/Logging/Log.cs new file mode 100644 index 00000000..939309dd --- /dev/null +++ b/S1API/Logging/Log.cs @@ -0,0 +1,81 @@ +#if MONOMELON || IL2CPPMELON +using MelonLoader +#else +using BepInEx.Logging; +#endif + +namespace S1API.Logging +{ + /// + /// Centralized Logging class that handles both BepInEx and MelonLoader logging. + /// + public class Log + { +#if MONOMELON || IL2CPPMELON + private readonly MelonLogger.Instance _loggerInstance; +#else + private readonly ManualLogSource _loggerInstance; +#endif + + public Log(string sourceName) + { +#if MONOMELON || IL2CPPMELON + _loggerInstance = new MelonLogger.Instancer(sourceName); +#else + _loggerInstance = new ManualLogSource(sourceName); +#endif + } + + /// + /// Logs a message with Info level + /// + /// Message to log + public void Msg(string message) + { +#if MONOMELON || IL2CPPMELON + _loggerInstance.Msg(message); +#else + _loggerInstance.LogInfo(message); +#endif + } + + /// + /// Logs a message with Warning level + /// + /// Message to log + public void Warning(string message) + { +#if MONOMELON || IL2CPPMELON + _loggerInstance.Warning(message); +#else + _loggerInstance.LogWarning(message); +#endif + } + + /// + /// Logs a message with Error level + /// + /// Message to log + public void Error(string message) + { +#if MONOMELON || IL2CPPMELON + _loggerInstance.Error(message); +#else + _loggerInstance.LogError(message); +#endif + } + + /// + /// Logs a message with Fatal level + /// + /// Message to log + public void BigError(string message) + { +#if MONOMELON || IL2CPPMELON + _loggerInstance.BigError(message); +#else + _loggerInstance.LogFatal(message); +#endif + } + } +} diff --git a/S1API/Money/CashDefinition.cs b/S1API/Money/CashDefinition.cs index 67186f63..47cc026d 100644 --- a/S1API/Money/CashDefinition.cs +++ b/S1API/Money/CashDefinition.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; #endif @@ -35,4 +35,4 @@ internal CashDefinition(S1ItemFramework.CashDefinition s1ItemDefinition) : base( public override ItemInstance CreateInstance(int quantity = 1) => new CashInstance(S1CashDefinition.GetDefaultInstance(quantity)); } -} \ No newline at end of file +} diff --git a/S1API/Money/CashInstance.cs b/S1API/Money/CashInstance.cs index f555c355..a9b96e9c 100644 --- a/S1API/Money/CashInstance.cs +++ b/S1API/Money/CashInstance.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; #endif @@ -42,4 +42,4 @@ public void AddQuantity(float amount) => public void SetQuantity(float newQuantity) => S1CashInstance.SetBalance(newQuantity); } -} \ No newline at end of file +} diff --git a/S1API/NPCs/NPC.cs b/S1API/NPCs/NPC.cs index a9a14699..f39611db 100644 --- a/S1API/NPCs/NPC.cs +++ b/S1API/NPCs/NPC.cs @@ -1,4 +1,4 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1DevUtilities = Il2CppScheduleOne.DevUtilities; using S1Interaction = Il2CppScheduleOne.Interaction; using S1Messaging = Il2CppScheduleOne.Messaging; @@ -14,7 +14,7 @@ using S1Vision = Il2CppScheduleOne.Vision; using S1NPCs = Il2CppScheduleOne.NPCs; using Il2CppSystem.Collections.Generic; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1DevUtilities = ScheduleOne.DevUtilities; using S1Interaction = ScheduleOne.Interaction; using S1Messaging = ScheduleOne.Messaging; @@ -91,9 +91,9 @@ public NPC(string guid, string firstName, string lastName) S1NPC.ConversationCategories.Add(S1Messaging.EConversationCategory.Customer); // Create our MessageConversation -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) S1NPC.CreateMessageConversation(); -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) MethodInfo createConvoMethod = AccessTools.Method(typeof(S1NPCs.NPC), "CreateMessageConversation"); createConvoMethod.Invoke(S1NPC, null); #endif @@ -162,9 +162,9 @@ public NPC(string guid, string firstName, string lastName) S1NPC.awareness.VisionCone.QuestionMarkPopup = _gameObject.AddComponent(); // Interaction behaviour -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) S1NPC.intObj = _gameObject.AddComponent(); -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) FieldInfo intObjField = AccessTools.Field(typeof(S1NPCs.NPC), "intObj"); intObjField.SetValue(S1NPC, _gameObject.AddComponent()); #endif @@ -267,4 +267,4 @@ public void SendTextMessage(string message, Response[]? responses = null, float /// The response that was loaded. protected virtual void OnResponseLoaded(Response response) { } } -} \ No newline at end of file +} diff --git a/S1API/NPCs/NPCInstance.cs b/S1API/NPCs/NPCInstance.cs index d4858d1b..27354028 100644 --- a/S1API/NPCs/NPCInstance.cs +++ b/S1API/NPCs/NPCInstance.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1NPCs = Il2CppScheduleOne.NPCs; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1NPCs = ScheduleOne.NPCs; #endif @@ -10,4 +10,4 @@ public class NPCInstance { } -} \ No newline at end of file +} diff --git a/S1API/NPCs/Response.cs b/S1API/NPCs/Response.cs index 100dc6b7..9ab12e45 100644 --- a/S1API/NPCs/Response.cs +++ b/S1API/NPCs/Response.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Messaging = Il2CppScheduleOne.Messaging; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Messaging = ScheduleOne.Messaging; #endif using System; @@ -55,4 +55,4 @@ public string Text set => S1Response.text = value; } } -} \ No newline at end of file +} diff --git a/S1API/PhoneApp/PhoneApp.cs b/S1API/PhoneApp/PhoneApp.cs index 44385db8..4b9dbb33 100644 --- a/S1API/PhoneApp/PhoneApp.cs +++ b/S1API/PhoneApp/PhoneApp.cs @@ -1,19 +1,25 @@ -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using UnityEngine; using UnityEngine.UI; using UnityEngine.Events; -#elif MONO +#elif MONOMELON || MONOBEPINEX using UnityEngine; using UnityEngine.UI; using UnityEngine.Events; #endif +using FishNet; using System.Collections; using System.IO; +#if MONOMELON || IL2CPPMELON using MelonLoader; -using Object = UnityEngine.Object; using MelonLoader.Utils; +#elif MONOBEPINEX || IL2CPPBEPINEX +using BepInEx.Logging; +#endif +using Object = UnityEngine.Object; using S1API.Internal.Abstraction; +using S1API.Logging; namespace S1API.PhoneApp { @@ -27,7 +33,7 @@ namespace S1API.PhoneApp /// public abstract class PhoneApp : Registerable { - protected static readonly MelonLogger.Instance LoggerInstance = new MelonLogger.Instance("PhoneApp"); + protected static readonly Log LoggerInstance = new Log("PhoneApp"); /// /// The player object in the scene. @@ -80,7 +86,10 @@ public abstract class PhoneApp : Registerable /// protected override void OnCreated() { - MelonCoroutines.Start(InitApp()); + // @TODO: Find out if this actually is the proper way of starting a coroutine + // for both BepInEx and MelonLoader + // Old code: MelonCoroutines.Start(InitApp()); + InstanceFinder.TimeManager.StartCoroutine(InitApp()); } /// @@ -197,14 +206,14 @@ private bool ModifyAppIcon(string labelText, string fileName) GameObject parent = GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/HomeScreen/AppIcons/"); if (parent == null) { - LoggerInstance?.Error("AppIcons not found."); + LoggerInstance.Error("AppIcons not found."); return false; } Transform lastIcon = parent.transform.childCount > 0 ? parent.transform.GetChild(parent.transform.childCount - 1) : null; if (lastIcon == null) { - LoggerInstance?.Error("No icon found to clone."); + LoggerInstance.Error("No icon found to clone."); return false; } @@ -235,7 +244,11 @@ private bool ChangeAppIconImage(GameObject iconObj, string filename) return false; } +#if MONOMELON || IL2CPPMELON string path = Path.Combine(MelonEnvironment.ModsDirectory, filename); +#elif MONOBEPINEX || IL2CPPBEPINEX + string path = Path.Combine(BepInEx.Paths.PluginPath, filename); +#endif if (!File.Exists(path)) { LoggerInstance?.Error("Icon file not found: " + path); diff --git a/S1API/Products/CocaineDefinition.cs b/S1API/Products/CocaineDefinition.cs index e0b45e3c..18b0e5ab 100644 --- a/S1API/Products/CocaineDefinition.cs +++ b/S1API/Products/CocaineDefinition.cs @@ -1,7 +1,7 @@ -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using Il2CppScheduleOne.Product; using S1CocaineDefinition = Il2CppScheduleOne.Product.CocaineDefinition; -#elif MONO +#elif MONOMELON || MONOBEPINEX using ScheduleOne.Product; using S1CocaineDefinition = ScheduleOne.Product.CocaineDefinition; #endif @@ -37,4 +37,4 @@ public override ItemInstance CreateInstance(int quantity = 1) => new ProductInstance(CrossType.As( S1CocaineDefinition.GetDefaultInstance(quantity))); } -} \ No newline at end of file +} diff --git a/S1API/Products/MethDefinition.cs b/S1API/Products/MethDefinition.cs index 943f5d72..46cb4926 100644 --- a/S1API/Products/MethDefinition.cs +++ b/S1API/Products/MethDefinition.cs @@ -1,7 +1,7 @@ -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using Il2CppScheduleOne.Product; using S1MethDefinition = Il2CppScheduleOne.Product.MethDefinition; -#elif MONO +#elif MONOMELON || MONOBEPINEX using ScheduleOne.Product; using S1MethDefinition = ScheduleOne.Product.MethDefinition; #endif @@ -36,4 +36,4 @@ public override ItemInstance CreateInstance(int quantity = 1) => new ProductInstance(CrossType.As( S1MethDefinition.GetDefaultInstance(quantity))); } -} \ No newline at end of file +} diff --git a/S1API/Products/PackagingDefinition.cs b/S1API/Products/PackagingDefinition.cs index b9dfee8c..54052293 100644 --- a/S1API/Products/PackagingDefinition.cs +++ b/S1API/Products/PackagingDefinition.cs @@ -1,7 +1,7 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Packaging = Il2CppScheduleOne.Product.Packaging; using S1ItemFramework = Il2CppScheduleOne.ItemFramework; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Packaging = ScheduleOne.Product.Packaging; using S1ItemFramework = ScheduleOne.ItemFramework; #endif @@ -35,4 +35,4 @@ internal PackagingDefinition(S1ItemFramework.ItemDefinition s1ItemDefinition) : public int Quantity => S1PackagingDefinition.Quantity; } -} \ No newline at end of file +} diff --git a/S1API/Products/ProductDefinition.cs b/S1API/Products/ProductDefinition.cs index bcb467a7..38dbadb2 100644 --- a/S1API/Products/ProductDefinition.cs +++ b/S1API/Products/ProductDefinition.cs @@ -1,8 +1,8 @@ -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using Il2CppInterop.Runtime.InteropTypes; using S1Product = Il2CppScheduleOne.Product; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Product = ScheduleOne.Product; #endif @@ -52,4 +52,4 @@ public Sprite Icon } } -} \ No newline at end of file +} diff --git a/S1API/Products/ProductDefinitionWrapper.cs b/S1API/Products/ProductDefinitionWrapper.cs index 97903e3e..a8374c83 100644 --- a/S1API/Products/ProductDefinitionWrapper.cs +++ b/S1API/Products/ProductDefinitionWrapper.cs @@ -1,5 +1,5 @@ using S1API.Internal.Utils; -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using S1Product = Il2CppScheduleOne.Product; #else using S1Product = ScheduleOne.Product; @@ -21,4 +21,4 @@ public static ProductDefinition Wrap(ProductDefinition def) return def; } } -} \ No newline at end of file +} diff --git a/S1API/Products/ProductInstance.cs b/S1API/Products/ProductInstance.cs index a1380bce..f3763101 100644 --- a/S1API/Products/ProductInstance.cs +++ b/S1API/Products/ProductInstance.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Product = Il2CppScheduleOne.Product; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Product = ScheduleOne.Product; #endif @@ -38,4 +38,4 @@ internal ProductInstance(S1Product.ProductItemInstance productInstance) : base(p public PackagingDefinition AppliedPackaging => new PackagingDefinition(S1ProductInstance.AppliedPackaging); } -} \ No newline at end of file +} diff --git a/S1API/Products/ProductManager.cs b/S1API/Products/ProductManager.cs index 264d65ca..4c5625e1 100644 --- a/S1API/Products/ProductManager.cs +++ b/S1API/Products/ProductManager.cs @@ -1,7 +1,7 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Product = Il2CppScheduleOne.Product; using Il2CppSystem.Collections.Generic; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Product = ScheduleOne.Product; #endif using System.Linq; @@ -21,4 +21,4 @@ public static class ProductManager .ToArray(); } -} \ No newline at end of file +} diff --git a/S1API/Products/WeedDefinition.cs b/S1API/Products/WeedDefinition.cs index 6c953289..bbff0a17 100644 --- a/S1API/Products/WeedDefinition.cs +++ b/S1API/Products/WeedDefinition.cs @@ -1,7 +1,7 @@ -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using Il2CppScheduleOne.Product; using S1WeedDefinition = Il2CppScheduleOne.Product.WeedDefinition; -#elif MONO +#elif MONOMELON || MONOBEPINEX using ScheduleOne.Product; using S1WeedDefinition = ScheduleOne.Product.WeedDefinition; #endif @@ -37,4 +37,4 @@ public override ItemInstance CreateInstance(int quantity = 1) => new ProductInstance(CrossType.As( S1WeedDefinition.GetDefaultInstance(quantity))); } -} \ No newline at end of file +} diff --git a/S1API/Quests/Quest.cs b/S1API/Quests/Quest.cs index 4fdfdc88..eb094abe 100644 --- a/S1API/Quests/Quest.cs +++ b/S1API/Quests/Quest.cs @@ -1,11 +1,11 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Quests = Il2CppScheduleOne.Quests; using S1Dev = Il2CppScheduleOne.DevUtilities; using S1Map = Il2CppScheduleOne.Map; using S1Data = Il2CppScheduleOne.Persistence.Datas; using S1Contacts = Il2CppScheduleOne.UI.Phone.ContactsApp; using Il2CppSystem.Collections.Generic; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Quests = ScheduleOne.Quests; using S1Dev = ScheduleOne.DevUtilities; using S1Map = ScheduleOne.Map; @@ -87,7 +87,7 @@ public Quest() S1Quest.onTrackChange = new UnityEvent(); S1Quest.TrackOnBegin = true; S1Quest.AutoCompleteOnAllEntriesComplete = true; -#if (MONO) +#if (MONOMELON || MONOBEPINEX) FieldInfo autoInitField = AccessTools.Field(typeof(S1Quests.Quest), "autoInitialize"); autoInitField.SetValue(S1Quest, false); #elif (IL2CPP) @@ -138,7 +138,7 @@ public Quest() poiPrefabObject.transform.SetParent(_gameObject.transform); S1Map.POI poi = poiPrefabObject.AddComponent(); poi.DefaultMainText = "Did it work?"; -#if (MONO) +#if (MONOMELON || MONOBEPINEX) FieldInfo uiPrefabField = AccessTools.Field(typeof(S1Map.POI), "UIPrefab"); uiPrefabField.SetValue(poi, uiPrefabObject); #elif (IL2CPP) @@ -241,4 +241,4 @@ protected QuestEntry AddEntry(string title, Vector3? poiPosition = null) /// public void End() => S1Quest?.End(); } -} \ No newline at end of file +} diff --git a/S1API/Quests/QuestEntry.cs b/S1API/Quests/QuestEntry.cs index 956fb5f9..68ffb545 100644 --- a/S1API/Quests/QuestEntry.cs +++ b/S1API/Quests/QuestEntry.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Quests = Il2CppScheduleOne.Quests; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Quests = ScheduleOne.Quests; #endif @@ -72,4 +72,4 @@ public Vector3 POIPosition public void SetState(QuestState questState) => S1QuestEntry.SetState((S1Quests.EQuestState)questState); } -} \ No newline at end of file +} diff --git a/S1API/S1API.cs b/S1API/S1API.cs index b50ec326..9aabfbec 100644 --- a/S1API/S1API.cs +++ b/S1API/S1API.cs @@ -1,4 +1,6 @@ -using MelonLoader; + +#if MONOMELON || IL2CPPMELON +using MelonLoader; [assembly: MelonInfo(typeof(S1API.S1API), "S1API", "{VERSION_NUMBER}", "KaBooMa")] @@ -8,3 +10,17 @@ public class S1API : MelonMod { } } +#elif MONOBEPINEX || IL2CPPBEPINEX +using BepInEx; +using BepInEx.Unity.Mono; + +namespace S1API +{ + [BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)] + public class S1API : BaseUnityPlugin + { + + } +} + +#endif diff --git a/S1API/S1API.csproj b/S1API/S1API.csproj index e154ad15..51a19069 100644 --- a/S1API/S1API.csproj +++ b/S1API/S1API.csproj @@ -1,10 +1,10 @@  - + - + netstandard2.1 @@ -14,107 +14,87 @@ https://github.com/KaBooMa/S1API MIT enable - Mono;Il2Cpp + MonoMelon;MonoBepInEx;Il2CppMelon;Il2CppBepInEx AnyCPU S1API + + + https://api.nuget.org/v3/index.json; + https://nuget.bepinex.dev/v3/index.json; + https://nuget.samboy.dev/v3/index.json + + + - - - $(MelonLoaderAssembliesPath)\Il2CppInterop.Runtime.dll - - - $(MelonLoaderAssembliesPath)\Il2CppInterop.Common.dll - - - $(MelonLoaderAssembliesPath)\Il2CppInterop.HarmonySupport.dll - - - $(MelonLoaderAssembliesPath)\Il2CppInterop.Generator.dll - - - $(Il2CppAssembliesPath)\Assembly-CSharp.dll - - - $(Il2CppAssembliesPath)\Il2CppFishNet.Runtime.dll - - - $(Il2CppAssembliesPath)\Il2Cppmscorlib.dll - - - $(Il2CppAssembliesPath)\UnityEngine.dll - - - $(Il2CppAssembliesPath)\UnityEngine.CoreModule.dll - - - $(Il2CppAssembliesPath)\UnityEngine.UI.dll - - - $(Il2CppAssembliesPath)\UnityEngine.UIModule.dll - - - $(Il2CppAssembliesPath)\UnityEngine.JSONSerializeModule.dll - - - $(Il2CppAssembliesPath)\UnityEngine.TextRenderingModule.dll - - - $(Il2CppAssembliesPath)\UnityEngine.ImageConversionModule.dll - + + + + + + + + + + + + + + + + + + + + + - - - $(MonoAssembliesPath)\Assembly-CSharp.dll - - - $(MonoAssembliesPath)\UnityEngine.dll - - - $(MonoAssembliesPath)\UnityEngine.CoreModule.dll - - - $(MonoAssembliesPath)\FishNet.Runtime.dll - - - $(MonoAssembliesPath)\UnityEngine.UI.dll - - - $(MonoAssembliesPath)\UnityEngine.UIModule.dll - - - $(MonoAssembliesPath)\UnityEngine.JSONSerializeModule.dll - - - $(MonoAssembliesPath)\UnityEngine.TextRenderingModule.dll - - - $(MonoAssembliesPath)\UnityEngine.ImageConversionModule.dll - + + + + + + + + + + + + + + + + + + + + + + + + + + - - $(MelonLoaderAssembliesPath)\0Harmony.dll - - - - - - + + + + - - - - + + + + - \ No newline at end of file + diff --git a/S1API/Storages/StorageInstance.cs b/S1API/Storages/StorageInstance.cs index 217f49f1..46561db8 100644 --- a/S1API/Storages/StorageInstance.cs +++ b/S1API/Storages/StorageInstance.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Storage = Il2CppScheduleOne.Storage; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Storage = ScheduleOne.Storage; #endif @@ -67,4 +67,4 @@ public event Action OnClosed remove => EventHelper.RemoveListener(value, S1Storage.onClosed); } } -} \ No newline at end of file +} diff --git a/S1API/UI/UIFactory.cs b/S1API/UI/UIFactory.cs index fc3795a3..f97eab43 100644 --- a/S1API/UI/UIFactory.cs +++ b/S1API/UI/UIFactory.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using UnityEngine; using UnityEngine.UI; using Il2CppInterop.Runtime.InteropTypes.Arrays; @@ -9,8 +9,6 @@ using System; using UnityEngine.Events; -using System.Collections.Generic; -using MelonLoader; using Object = UnityEngine.Object; namespace S1API.UI @@ -290,8 +288,8 @@ public static GameObject CreateQuestRow(string name, Transform parent, out GameO rowRT.sizeDelta = new Vector2(0f, 90f); // Let layout handle width row.AddComponent().minHeight = 50f; row.AddComponent().effectColor = new Color(0, 0, 0, 0.2f); // or Image line separator below - - + + var line = UIFactory.Panel("Separator", row.transform, new Color(1,1,1,0.05f)); line.GetComponent().sizeDelta = new Vector2(300f, 1f); diff --git a/S1APILoader/S1APILoader.csproj b/S1APILoader/S1APILoader.csproj index 8d79d7be..7fdb89ee 100644 --- a/S1APILoader/S1APILoader.csproj +++ b/S1APILoader/S1APILoader.csproj @@ -8,7 +8,7 @@ netstandard2.1 enable - Mono;Il2Cpp + Il2CppMelon;MonoBepInEx;MonoMelon;Il2CppBepInEx AnyCPU S1APILoader diff --git a/example.build.props b/example.build.props index 3c0a2143..475f048a 100644 --- a/example.build.props +++ b/example.build.props @@ -11,6 +11,7 @@ C:\Program Files (x86)\Steam\steamapps\common\Schedule I\MelonLoader\net6 + C:\Program Files (x86)\Steam\steamapps\common\Schedule I\BepInEx\core @@ -28,4 +29,4 @@ C:\Program Files (x86)\Steam\steamapps\common\Schedule I\Melonloader\Il2CppAssemblies - \ No newline at end of file + From c7933e435f8d7272004d0f5e2705a700b2dbdd7f Mon Sep 17 00:00:00 2001 From: MaxtorCoder Date: Sat, 26 Apr 2025 13:47:21 +0200 Subject: [PATCH 2/3] Improve logging code and documentation --- S1API/Logging/Log.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/S1API/Logging/Log.cs b/S1API/Logging/Log.cs index 939309dd..03986b93 100644 --- a/S1API/Logging/Log.cs +++ b/S1API/Logging/Log.cs @@ -17,15 +17,30 @@ public class Log private readonly ManualLogSource _loggerInstance; #endif + /// + /// Default constructor for instance + /// + /// The source name to use for logging public Log(string sourceName) { #if MONOMELON || IL2CPPMELON _loggerInstance = new MelonLogger.Instancer(sourceName); #else - _loggerInstance = new ManualLogSource(sourceName); + _loggerInstance = Logger.CreateLogSource(sourceName); #endif } +#if MONOBEPINEX || IL2CPPBEPINEX + /// + /// Default constructor for instance when BepInEx is enabled + /// + /// Existing instance to use + public Log(ManualLogSource loggerInstance) + { + _loggerInstance = loggerInstance; + } +#endif + /// /// Logs a message with Info level /// From 0517550dff338fa30786b6ac487c37a46ae77e42 Mon Sep 17 00:00:00 2001 From: MaxtorCoder Date: Sat, 26 Apr 2025 14:01:20 +0200 Subject: [PATCH 3/3] Add Harmony patching to main Plugin file --- S1API/S1API.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/S1API/S1API.cs b/S1API/S1API.cs index 9aabfbec..b3c3936b 100644 --- a/S1API/S1API.cs +++ b/S1API/S1API.cs @@ -1,5 +1,4 @@ - -#if MONOMELON || IL2CPPMELON +#if MONOMELON || IL2CPPMELON using MelonLoader; [assembly: MelonInfo(typeof(S1API.S1API), "S1API", "{VERSION_NUMBER}", "KaBooMa")] @@ -14,12 +13,17 @@ public class S1API : MelonMod using BepInEx; using BepInEx.Unity.Mono; +using HarmonyLib; + namespace S1API { [BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)] public class S1API : BaseUnityPlugin { - + private void Awake() + { + new Harmony("com.S1API").PatchAll(); + } } }