From 994d2ef04f2684c8a9484db643e1f5e2f029a1c0 Mon Sep 17 00:00:00 2001 From: Da_google Date: Sat, 3 Aug 2019 00:53:14 -0700 Subject: [PATCH] Added Mod reloading Logs work Disable mods works last working build --- BWModLoader.csproj | 3 +- src/Loader.cs | 96 ++++++------------------------------ src/ModGUI.cs | 70 ++++++++++++++++++--------- src/Utils.cs | 118 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 182 insertions(+), 105 deletions(-) create mode 100644 src/Utils.cs diff --git a/BWModLoader.csproj b/BWModLoader.csproj index 5e5de05..0bd4721 100644 --- a/BWModLoader.csproj +++ b/BWModLoader.csproj @@ -7,7 +7,7 @@ Library BWModLoader BWModLoader - v4.7 + v3.5 true @@ -36,6 +36,7 @@ + diff --git a/src/Loader.cs b/src/Loader.cs index baaae82..380819f 100644 --- a/src/Loader.cs +++ b/src/Loader.cs @@ -7,104 +7,36 @@ namespace ModLoader { public static class Loader { - public static GameObject modObjects; - public static Dictionary loadedMods = new Dictionary(); - - public static void Log(string output) - { - Console.WriteLine("[BWML]" + output); - //UnityEngine.Debug.Log("[BWML]" + output); - } - - public static void DebugLog(string output) - { -#if DEBUG - Log(output); -#endif // DEBUG - } - - static void FindMods(DirectoryInfo path) - { - FileInfo[] files = path.GetFiles("*.dll"); - foreach (FileInfo file in files) - { - try - { - Assembly modDll = Assembly.LoadFrom(path.FullName + "/" + file.Name); - Type[] modType = modDll.GetTypes(); - foreach (Type t in modType) - { - DebugLog("Found type in " + file.Name + ": " + t.Name); - if (t.IsClass && t.IsSubclassOf(typeof(MonoBehaviour))) - { - loadedMods.Add(modObjects.AddComponent(t), file); - Log("Loaded " + t.Name + " from file: " + file.Name); - //CleanMods(); - } - } - } - catch (Exception e) - { - Log("Exception raised while loading mod " + file.Name); - Log(e.Message); - Log("Skipped loading this mod"); - } - } - } - public static void RemoveMod(Component mod) - { - UnityEngine.Object.Destroy(mod); - loadedMods.Remove(mod); - } - static void CleanMods() - { - foreach(KeyValuePair mod in loadedMods) - { - if (modObjects.GetComponent(mod.Key.GetType()) == null) - { - loadedMods.Remove(mod.Key); - } - } - } - public static void Load() { - Log("Starting mod loader..."); + Utils.Log("Starting mod loader..."); + Utils.DebugLog("Mods dir: "+Utils.modsPath); - string dllpath = new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath; - string Path = new FileInfo(dllpath).Directory.FullName; - string modsPath = Path + "\\Mods"; - string assetsPath = modsPath + "\\Assets"; - - DebugLog("Dll dir: "+Path); - DebugLog("Mods dir: "+modsPath); - - if (!Directory.Exists(modsPath)) + if (!Directory.Exists(Utils.modsPath)) { - Directory.CreateDirectory(modsPath); + Directory.CreateDirectory(Utils.modsPath); } - if (!Directory.Exists(assetsPath)) + if (!Directory.Exists(Utils.assetsPath)) { - Directory.CreateDirectory(assetsPath); + Directory.CreateDirectory(Utils.assetsPath); } - modObjects = new GameObject(); + Utils.modObjects = new GameObject(); //For each DLL in "Blackwake/Blackwake_Data/Managed/Mods/" //Open them, Get the mod class, then add it in the game. - DirectoryInfo d = new DirectoryInfo(modsPath); - FindMods(d); - foreach(Component mod in loadedMods.Keys) + Utils.RefreshModFiles(); + foreach(FileInfo file in Utils.allMods.Keys) { - Log("Mod \"" + mod.name + "\" loaded from \"" + loadedMods[mod].Name + "\""); + Utils.Load(file); } - Log("All Mods have been Loaded!"); - modObjects.AddComponent(); - Log("GUI has been loaded"); + Utils.Log("All Mods have been Loaded!"); + Utils.modObjects.AddComponent(); + Utils.Log("GUI has been loaded"); //Keep mods active - UnityEngine.Object.DontDestroyOnLoad(modObjects); + UnityEngine.Object.DontDestroyOnLoad(Utils.modObjects); } } } diff --git a/src/ModGUI.cs b/src/ModGUI.cs index 0d6c28c..82b0a33 100644 --- a/src/ModGUI.cs +++ b/src/ModGUI.cs @@ -1,4 +1,9 @@ -using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEngine; namespace ModGUI { public class ModGUI : MonoBehaviour @@ -6,10 +11,8 @@ namespace ModGUI static bool debugEnabled; static int currentScreen; static Vector2 scrollPosition; - //static Dictionary test; static Vector2 size; static Vector2 position; - void Start() { currentScreen = 0; @@ -54,32 +57,55 @@ namespace ModGUI void LogWindow() { - GUI.Label(new Rect(0, 100, 100, 25), "LogWindow"); + GUI.Label(new Rect(0, 100, 100, 25), "LogWindow"); + int logNum = 0; + if (ModLoader.Utils.logs.Any()) + { + scrollPosition = GUI.BeginScrollView(new Rect(0, 100, size.x, size.y - 100), scrollPosition, new Rect(0, 0, size.x, 50)); + foreach (string log in ModLoader.Utils.logs) + { + logNum++; + GUI.Label(new Rect(0, 25 * logNum, 1000, 25), log); + } + GUI.EndScrollView(); + } } void ModWindow() { - GUI.Label(new Rect(0, 100, 100, 25), "ModWindow"); + if (GUI.Button(new Rect(0, 100, 100, 25), "Reload all mods")) + { + ModLoader.Utils.RefreshModFiles(); + } scrollPosition = GUI.BeginScrollView(new Rect(0, 100, size.x, size.y-100), scrollPosition, new Rect(0, 0, size.x, 50)); int modNum = 0; - foreach (Component mod in ModLoader.Loader.modObjects.GetComponents(typeof(Component))) - { - GUI.Label(new Rect(0, modNum * 25, 100, 25), mod.name); - modNum++; + foreach (FileInfo file in ModLoader.Utils.allMods.Keys) + { + foreach (Type mod in ModLoader.Utils.allMods[file]) + { + modNum++; + GUI.Label(new Rect(0, modNum * 25, 100, 25), mod.Name); + if (!ModLoader.Utils.IsLoaded(mod)) + { + if (GUI.Button(new Rect(100, modNum * 25, 100, 25), "Enable")) + { + ModLoader.Utils.Load(file); + } + } + else + { + if (GUI.Button(new Rect(100, modNum * 25, 100, 25), "Disable")) + { + ModLoader.Utils.Unload(file); + } + } + if (GUI.Button(new Rect(200, modNum * 25, 100, 25), "Reload")) + { + ModLoader.Utils.Unload(file); + ModLoader.Utils.RefreshModFiles(); + } + } } GUI.EndScrollView(); } } - /* - static class DebugWindows - { - public static void LogWindow() - { - GUI.Label(new Rect(0, 100, 100, 25), "LogWindow"); - } - public static void ModWindow() - { - GUI.Label(new Rect(0, 100, 100, 25), "ModWindow"); - scrollPosition = GUI.BeginScrollView(new Rect(10, 300, 100, 100), scrollPosition, new Rect(0, 0, 220, 200)); - } - }*/ } \ No newline at end of file diff --git a/src/Utils.cs b/src/Utils.cs new file mode 100644 index 0000000..94dba98 --- /dev/null +++ b/src/Utils.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using UnityEngine; +namespace ModLoader +{ + public static class Utils + { + static readonly string dllpath = new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath; + static readonly string path = new FileInfo(dllpath).Directory.FullName; + public static string modsPath = path + "\\Mods"; + public static string assetsPath = modsPath + "\\Assets"; + + //all known mods files and their classes + public static Dictionary> allMods = new Dictionary>(); + //Log history + public static List logs = new List(); + //Object that holds our mods + public static GameObject modObjects; + + //checks if mod is loaded + public static bool IsLoaded(Type mod) + { + if (modObjects.GetComponent(mod) != null) + { + return true; + } + return false; + } + //Refresh all known mods + public static void RefreshModFiles() + { + DirectoryInfo dir = new DirectoryInfo(modsPath); + //Clears known mods + allMods.Clear(); + + //Find all files to refresh + foreach (FileInfo file in dir.GetFiles("*.dll")) + { + + allMods.Add(file, new List()); + foreach(Type mod in FindModTypes(file)) + { + //Save mod type and file path + allMods[file].Add(mod); + } + Log("Found dll: " + file.Name); + } + } + //Find all mod classes in a file + static List FindModTypes(FileInfo file) + { + List mods = new List(); + try + { + Assembly modDll = Assembly.LoadFrom(file.FullName); + Type[] modType = modDll.GetTypes(); + foreach (Type t in modType) + { + Log("Found type in " + file.Name + ": " + t.Name); + if (t.IsClass && t.IsSubclassOf(typeof(MonoBehaviour))) + { + mods.Add(t); + } + } + } + catch (Exception e) + { + Log("Exception raised while loading mod " + file.Name); + Log(e.Message); + Log("Skipped loading this mod"); + } + return mods; + } + //will load a mod from memory + public static void Load(FileInfo file) + { + if (allMods.ContainsKey(file)) + { + foreach (Type mod in allMods[file]) + { + //if mod is not loaded + if (modObjects.GetComponent(mod) == null) + { + modObjects.AddComponent(mod); + Log("Loaded: " + mod.Name + " From file: " + file.Name); + } + } + } + } + //Unloads a mod from game + public static void Unload(FileInfo file) + { + foreach(Type mod in allMods[file]) + { + //if mod is loaded + if (modObjects.GetComponent(mod) != null) + { + UnityEngine.Object.Destroy(modObjects.GetComponent(mod)); + Log("Unloaded: " + mod.Name + " From file: " + file.Name); + } + } + } + //Log to debugger and output.txt + public static void Log(string output) + { + Console.WriteLine("[BWML]" + output); + logs.Add(output); + } + public static void DebugLog(string output) + { + #if DEBUG + Log(output); + #endif // DEBUG + } + } +}