diff --git a/.gitignore b/.gitignore
index 0210746..ed82ae9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,3 +34,5 @@ sysinfo.txt
# Builds
*.apk
*.unitypackage
+
+bin/
diff --git a/BWModLoader.csproj b/BWModLoader.csproj
index 5e5de05..12881a9 100644
--- a/BWModLoader.csproj
+++ b/BWModLoader.csproj
@@ -1,4 +1,4 @@
-
+
Debug
@@ -7,7 +7,7 @@
Library
BWModLoader
BWModLoader
- v4.7
+ v3.5
true
@@ -35,13 +35,13 @@
+
+
-
-
-
+
\ No newline at end of file
diff --git a/src/Loader.cs b/src/Loader.cs
index e2d9412..9d4c0c7 100644
--- a/src/Loader.cs
+++ b/src/Loader.cs
@@ -1,73 +1,49 @@
using System;
+using System.Collections.Generic;
using System.IO;
using System.Reflection;
using UnityEngine;
-namespace ModLoader
+
+namespace BWModLoader
{
public static class Loader
{
- public static void Log(string output)
- {
- Console.WriteLine("[BWML]" + output);
- //UnityEngine.Debug.Log("[BWML]" + output);
- }
public static void Load()
{
- Log("Starting mod loader...");
+ string logfile = null;
+#if DEBUG
+ logfile = ModLoader.LogPath + "\\modloader.log";
+#endif
+ ModLogger logger = new ModLogger("[BWML]", logfile);
+ logger.ClearLog();
+ logger.Log("Starting mod loader...");
+ logger.DebugLog("Mods dir: " + ModLoader.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";
-
- Log("Dll dir: "+Path);
- Log("Mods dir: "+modsPath);
-
- if (!Directory.Exists(modsPath))
+ if (!Directory.Exists(ModLoader.ModsPath))
{
- Directory.CreateDirectory(modsPath);
+ Directory.CreateDirectory(ModLoader.ModsPath);
}
- if (!Directory.Exists(assetsPath))
+ if (!Directory.Exists(ModLoader.AssetsPath))
{
- Directory.CreateDirectory(assetsPath);
+ Directory.CreateDirectory(ModLoader.AssetsPath);
}
- DirectoryInfo d = new DirectoryInfo(modsPath);
-
- GameObject modObjects = new GameObject();
-
//For each DLL in "Blackwake/Blackwake_Data/Managed/Mods/"
//Open them, Get the mod class, then add it in the game.
- foreach (var file in d.GetFiles("*.dll"))
+ ModLoader loader = new ModLoader(logger);
+ ModLoader.Instance = loader;
+ loader.RefreshModFiles();
+ foreach (FileInfo file in loader.GetAllMods().Keys)
{
- try
- {
- Assembly modDll = Assembly.LoadFrom(modsPath + "/" + file.Name);
- Type[] modType = modDll.GetTypes();
- foreach (Type t in modType)
- {
- Log("Found type in " + file.Name + ": " + t.Name);
- if (t.IsClass && t.IsSubclassOf(typeof(MonoBehaviour)))
- {
- modObjects.AddComponent(t);
- Log("Loaded '" + t.Name + "' in " + file.Name);
- }
- }
- }
- catch (Exception e)
- {
- Log("Exception raised while loading mod " + file.Name);
- Log(e.Message);
- Log("Skipped loading this mod");
- }
+ loader.Load(file);
}
- Log("All Mods have been Loaded!");
- modObjects.AddComponent();
- Log("GUI has been loaded");
+ logger.Log("All Mods have been Loaded!");
+ loader.ModObjects.AddComponent();
+ logger.Log("GUI has been loaded");
//Keep mods active
- UnityEngine.Object.DontDestroyOnLoad(modObjects);
+ UnityEngine.Object.DontDestroyOnLoad(loader.ModObjects);
}
}
}
diff --git a/src/ModGUI.cs b/src/ModGUI.cs
index 3c3fd32..c8c8cff 100644
--- a/src/ModGUI.cs
+++ b/src/ModGUI.cs
@@ -1,14 +1,143 @@
using System;
+using System.Collections;
+using System.Collections.Generic;
using System.IO;
+using System.Linq;
using UnityEngine;
-namespace ModGUI
+namespace BWModLoader.ModGUI
{
+ public enum ScreenType
+ {
+ MOD,
+ LOG
+ }
+
+ ///
+ /// Manages contents and behaviour of the Debug Window
+ ///
public class ModGUI : MonoBehaviour
{
+ static bool debugEnabled;
+ static int currentScreen;
+ static Vector2 scrollPosition;
+ static Vector2 size;
+ static Vector2 position;
+
+ void Start()
+ {
+ currentScreen = (int)ScreenType.MOD;
+ scrollPosition = Vector2.zero;
+ debugEnabled = false;
+ size = new Vector2(1000, 1000);
+ position = new Vector2((Screen.width / 2) - (size.x / 2),
+ (Screen.height / 2) - (size.x / 2));
+ }
+
+ ///
+ /// Toggles the Window when the Hotkey is pressed
+ ///
+ void Update()
+ {
+ if (Input.GetKeyUp("insert"))
+ {
+ debugEnabled = !debugEnabled;
+ }
+
+ }
+
+ ///
+ /// Code that executes if the window was opened
+ ///
void OnGUI()
{
- GUI.color = Color.red;
- GUI.Label(new Rect(5f, 0f, 200f, 20f), "ModLoader v0.3");
+ if (debugEnabled)
+ {
+ GUI.ModalWindow(0, new Rect(position, size), DebugWindow, "[BWML]Debug Menu");
+ }
+ }
+
+ ///
+ /// Manages contents of the window
+ ///
+ /// ID of the Debug Window
+ void DebugWindow(int windowID)
+ {
+ GUI.DragWindow(new Rect(0, 0, 10000, 20));
+ currentScreen = GUI.SelectionGrid(new Rect(25, 25, size.x - 50, 75), currentScreen,
+ new string[] { "Mods", "Logs" }, 2);
+ if (currentScreen == (int)ScreenType.MOD)
+ {
+ ModWindow();
+ }
+ else
+ {
+ LogWindow();
+ }
+ }
+
+ ///
+ /// Logging window content
+ ///
+ void LogWindow()
+ {
+ GUI.Label(new Rect(0, 100, 100, 25), "LogWindow");
+ int logNum = 0;
+ if (ModLoader.Instance.Logger.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.Instance.Logger.Logs)
+ {
+ logNum++;
+ GUI.Label(new Rect(0, 25 * logNum, 1000, 25), log);
+ }
+ GUI.EndScrollView();
+ }
+ }
+
+ ///
+ /// Mod window content
+ ///
+ void ModWindow()
+ {
+ if (GUI.Button(new Rect(0, 100, 100, 25), "Reload all mods"))
+ {
+ ModLoader.Instance.RefreshModFiles();
+ }
+
+ scrollPosition = GUI.BeginScrollView(new Rect(0, 100, size.x, size.y - 100), scrollPosition, new Rect(0, 0, size.x, 50));
+ int modNum = 0;
+ var allmods = ModLoader.Instance.GetAllMods();
+ foreach (FileInfo file in allmods.Keys)
+ {
+ foreach (Type mod in allmods[file])
+ {
+ modNum++;
+ //GUI.Label(new Rect(0, modNum * 25, 100, 25), mod.Name);
+ //GUI.Toggle(new Rect(0, modNum * 25, 100, 25), ModLoader.Instance.IsLoaded(mod), mod.Name);
+ bool newCheckboxStatus = GUI.Toggle(new Rect(20, modNum * 25, 100, 25), ModLoader.Instance.IsLoaded(mod), mod.Name);
+ if (newCheckboxStatus)
+ {
+ if (!ModLoader.Instance.IsLoaded(mod))
+ {
+ ModLoader.Instance.Load(file);
+ }
+ }
+ else
+ {
+ if (ModLoader.Instance.IsLoaded(mod))
+ {
+ ModLoader.Instance.Unload(file);
+ }
+ }
+
+ // Reload the respective Mod
+ if (GUI.Button(new Rect(200, modNum * 25, 100, 25), "Reload"))
+ {
+ ModLoader.Instance.RefreshModFiles();
+ }
+ }
+ }
+ GUI.EndScrollView();
}
}
}
\ No newline at end of file
diff --git a/src/ModLoader.cs b/src/ModLoader.cs
new file mode 100644
index 0000000..aa5ef07
--- /dev/null
+++ b/src/ModLoader.cs
@@ -0,0 +1,141 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using UnityEngine;
+
+namespace BWModLoader
+{
+ public class ModLoader
+ {
+ public static ModLoader Instance { get; internal set; }
+
+ private static readonly string dllpath = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;
+ private static readonly string folderPath = Path.GetDirectoryName(dllpath);
+ public static string ModsPath => folderPath + "\\Mods";
+ public static string AssetsPath => ModsPath + "\\Assets";
+ public static string LogPath => ModsPath + "\\Logs";
+
+ public ModLogger Logger;
+
+ ///
+ /// All known mods files
+ ///
+ private readonly Dictionary> allMods = new Dictionary>();
+
+ ///
+ /// Gets all known mods files
+ ///
+ /// Prevent modification from outside by making copy
+ public Dictionary> GetAllMods() => new Dictionary>(allMods);
+
+ ///
+ /// GameObject that holds our mods
+ ///
+ public GameObject ModObjects { get; } = new GameObject();
+
+ public ModLoader(ModLogger logger)
+ {
+ this.Logger = logger;
+ }
+
+ ///
+ /// Checks if a mod is loaded
+ ///
+ ///
+ ///
+ public bool IsLoaded(Type mod)
+ {
+ return ModObjects.GetComponent(mod) != null;
+ }
+
+ ///
+ /// Refresh all known mods
+ ///
+ public void RefreshModFiles()
+ {
+ DirectoryInfo dir = new DirectoryInfo(ModsPath);
+ //Unloads & clears known mods
+ foreach (var mod in allMods)
+ {
+ Unload(mod.Key);
+ }
+ allMods.Clear();
+
+ //Find all files to refresh
+ foreach (FileInfo file in dir.GetFiles("*.dll"))
+ {
+ //Save mod types and file path
+ allMods.Add(file, LoadModTypes(file));
+ Logger.Log("Found dll: " + file.Name);
+ }
+ }
+
+ ///
+ /// Finds and loads all mod classes in a file
+ ///
+ /// The file to load
+ ///
+ private List LoadModTypes(FileInfo file)
+ {
+ List mods = new List();
+ try
+ {
+ Assembly modDll = Assembly.LoadFrom(file.FullName);
+ Type[] modType = modDll.GetTypes();
+ foreach (Type t in modType)
+ {
+ Logger.Log("Found type in " + file.Name + ": " + t.Name);
+ if (t.IsClass && typeof(MonoBehaviour).IsAssignableFrom(t) && !t.IsAbstract && t.IsPublic)
+ {
+ mods.Add(t);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Logger.Log("Exception raised while loading mod " + file.Name);
+ Logger.Log(e.Message);
+ Logger.Log("Skipped loading this mod");
+ }
+ return mods;
+ }
+
+ ///
+ /// will load a mod from memory
+ ///
+ ///
+ public void Load(FileInfo file)
+ {
+ if (allMods.TryGetValue(file, out var types))
+ {
+ foreach (Type mod in types)
+ {
+ //if mod is not loaded
+ if (!IsLoaded(mod))
+ {
+ ModObjects.AddComponent(mod);
+ Logger.Log("Loaded: " + mod.Name + " From file: " + file.Name);
+ }
+ }
+ }
+ }
+
+ //Unloads a mod from game
+ public void Unload(FileInfo file)
+ {
+ if (allMods.TryGetValue(file, out var types))
+ {
+ foreach (Type mod in types)
+ {
+ //if mod is loaded
+ if (IsLoaded(mod))
+ {
+ UnityEngine.Object.Destroy(ModObjects.GetComponent(mod));
+ Logger.Log("Unloaded: " + mod.Name + " From file: " + file.Name);
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ModLogger.cs b/src/ModLogger.cs
new file mode 100644
index 0000000..927d7f2
--- /dev/null
+++ b/src/ModLogger.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace BWModLoader
+{
+ ///
+ /// Handles logging
+ ///
+ public class ModLogger
+ {
+ string prefix;
+ string file;
+
+ ///
+ /// Log history
+ ///
+ public List Logs { get; } = new List();
+
+ public ModLogger(string prefix, string file = null)
+ {
+ this.prefix = prefix;
+ this.file = file;
+ if (!string.IsNullOrEmpty(file) && !File.Exists(file))
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(file));
+ File.WriteAllText(file, "");
+ }
+ }
+
+ ///
+ /// Clears ingame log and log files
+ ///
+ public void ClearLog()
+ {
+ Logs.Clear();
+ if (!string.IsNullOrEmpty(file) && File.Exists(file))
+ {
+ File.Delete(file);
+ }
+ }
+
+ ///
+ /// Log to debugger and output.txt
+ ///
+ public void Log(string output)
+ {
+ Console.WriteLine(prefix + output);
+ Logs.Add(prefix + output);
+ if (!string.IsNullOrEmpty(file))
+ {
+ File.AppendAllText(file, prefix + output + Environment.NewLine);
+ }
+ }
+
+ ///
+ /// Only logs messages in Debug builds of the modloader
+ ///
+ public void DebugLog(string output)
+ {
+#if DEBUG
+ Log(output);
+#endif // DEBUG
+ }
+ }
+}