diff --git a/README.md b/README.md
index 8bf19e8..faaf22e 100644
--- a/README.md
+++ b/README.md
@@ -44,7 +44,7 @@
* Reflection Inspector: Inspect Properties and Fields. Can also set primitive values and evaluate primitive methods.
* Search: Search for UnityEngine.Objects with various filters, or use the helpers for static Instances and Classes.
* C# Console: Interactive console for evaluating C# methods on the fly, with some basic helpers.
-* Inspect-under-mouse: Hover over an object with a collider and inspect it by clicking on it.
+* Inspect-under-mouse: Hover over an object with a collider and inspect it by clicking on it. There's also a UI mode to inspect UI objects.
## How to install
@@ -68,9 +68,15 @@ Note: You must use version 0.3 of MelonLoader or greater. Version 0.3 is current
### Standalone
0. Load the DLL from your mod or inject it. You must also make sure that the required libraries (Harmony, Unhollower for Il2Cpp, etc) are loaded.
-1. Create an instance of Unity Explorer with `new ExplorerCore();`
-2. You will need to call `ExplorerCore.Update()` (static method) from your Update method.
-3. Subscribe to the `ExplorerCore.OnLog__` methods for logging.
+1. Create an instance of Unity Explorer with `ExplorerStandalone.CreateInstance();`
+2. You will need to call `ExplorerStandalone.Update()` from your Update method.
+3. Subscribe to the `ExplorerStandalone.OnLog` event to handle logging if you wish.
+
+## Logging
+
+Explorer saves all logs to disk (only keeps the most recent 10 logs). They can be found in a "UnityExplorer" folder in the same place as where you put the DLL file.
+
+These logs are also visible in the Debug Console part of the UI.
## Settings
diff --git a/src/Config/ModConfig.cs b/src/Config/ExplorerConfig.cs
similarity index 88%
rename from src/Config/ModConfig.cs
rename to src/Config/ExplorerConfig.cs
index 02b4bee..cd88cb5 100644
--- a/src/Config/ModConfig.cs
+++ b/src/Config/ExplorerConfig.cs
@@ -6,14 +6,14 @@ using IniParser.Parser;
namespace UnityExplorer.Config
{
- public class ModConfig
+ public class ExplorerConfig
{
- public static ModConfig Instance;
+ public static ExplorerConfig Instance;
internal static readonly IniDataParser _parser = new IniDataParser();
- internal static readonly string INI_PATH = Path.Combine(ExplorerCore.EXPLORER_FOLDER, "config.ini");
+ internal static readonly string INI_PATH = Path.Combine(ExplorerCore.Loader.ConfigFolder, "config.ini");
- static ModConfig()
+ static ExplorerConfig()
{
_parser.Configuration.CommentString = "#";
}
@@ -22,7 +22,7 @@ namespace UnityExplorer.Config
public KeyCode Main_Menu_Toggle = KeyCode.F7;
public bool Force_Unlock_Mouse = true;
public int Default_Page_Limit = 25;
- public string Default_Output_Path = ExplorerCore.EXPLORER_FOLDER + @"\Output";
+ public string Default_Output_Path = ExplorerCore.ExplorerFolder + @"\Output";
public bool Log_Unity_Debug = false;
public bool Hide_On_Startup = false;
//public bool Save_Logs_To_Disk = true;
@@ -36,7 +36,7 @@ namespace UnityExplorer.Config
public static void OnLoad()
{
- Instance = new ModConfig();
+ Instance = new ExplorerConfig();
if (LoadSettings())
return;
@@ -99,6 +99,9 @@ namespace UnityExplorer.Config
sec.AddKey(nameof(Hide_On_Startup), Instance.Hide_On_Startup.ToString());
//sec.AddKey("Save_Logs_To_Disk", Instance.Save_Logs_To_Disk.ToString());
+ if (!Directory.Exists(ExplorerCore.Loader.ConfigFolder))
+ Directory.CreateDirectory(ExplorerCore.Loader.ConfigFolder);
+
File.WriteAllText(INI_PATH, data.ToString());
}
}
diff --git a/src/ExplorerBepIn5Plugin.cs b/src/ExplorerBepIn5Plugin.cs
deleted file mode 100644
index e33c07f..0000000
--- a/src/ExplorerBepIn5Plugin.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-#if BIE5
-using System;
-using System.IO;
-using System.Reflection;
-using BepInEx;
-using BepInEx.Logging;
-using HarmonyLib;
-
-namespace UnityExplorer
-{
- [BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)]
- public class ExplorerBepInPlugin : BaseUnityPlugin
- {
- public static ExplorerBepInPlugin Instance;
-
- public static ManualLogSource Logging => Instance?.Logger;
-
- public static readonly Harmony HarmonyInstance = new Harmony(ExplorerCore.GUID);
-
- internal void Awake()
- {
- Instance = this;
-
- new ExplorerCore();
-
- // HarmonyInstance.PatchAll();
- }
-
- internal void Update()
- {
- ExplorerCore.Update();
- }
- }
-}
-#endif
diff --git a/src/ExplorerCore.cs b/src/ExplorerCore.cs
index 6ab5d0c..67d4a1b 100644
--- a/src/ExplorerCore.cs
+++ b/src/ExplorerCore.cs
@@ -19,39 +19,19 @@ namespace UnityExplorer
public const string AUTHOR = "Sinai";
public const string GUID = "com.sinai.unityexplorer";
-#if ML
- public static string EXPLORER_FOLDER = Path.Combine("Mods", NAME);
-#elif BIE
- public static string EXPLORER_FOLDER = Path.Combine(BepInEx.Paths.ConfigPath, NAME);
-#elif STANDALONE
- public static string EXPLORER_FOLDER
- {
- get
- {
- if (s_explorerFolder == null)
- {
- s_explorerFolder = (new Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath;
- s_explorerFolder = Uri.UnescapeDataString(s_explorerFolder);
- s_explorerFolder = Path.GetDirectoryName(s_explorerFolder);
- }
-
- return s_explorerFolder;
- }
- }
- private static string s_explorerFolder;
-#endif
-
public static ExplorerCore Instance { get; private set; }
- public static bool ShowMenu
- {
- get => s_showMenu;
- set => SetShowMenu(value);
- }
- public static bool s_showMenu;
+ private static IExplorerLoader s_loader;
+ public static IExplorerLoader Loader => s_loader
+#if ML
+ ?? (s_loader = ExplorerMelonMod.Instance);
+#elif BIE
+ ?? (s_loader = ExplorerBepInPlugin.Instance);
+#elif STANDALONE
+ ?? (s_loader = ExplorerStandalone.Instance);
+#endif
- private static bool s_doneUIInit;
- private static float s_timeSinceStartup;
+ public static string ExplorerFolder => Loader.ExplorerFolder;
public ExplorerCore()
{
@@ -67,60 +47,29 @@ namespace UnityExplorer
ReflectionHelpers.TryLoadGameModules();
#endif
- if (!Directory.Exists(EXPLORER_FOLDER))
- Directory.CreateDirectory(EXPLORER_FOLDER);
+ if (!Directory.Exists(ExplorerFolder))
+ Directory.CreateDirectory(ExplorerFolder);
- ModConfig.OnLoad();
+ ExplorerConfig.OnLoad();
InputManager.Init();
ForceUnlockCursor.Init();
SetupEvents();
- ShowMenu = true;
+ UIManager.ShowMenu = true;
Log($"{NAME} {VERSION} initialized.");
}
public static void Update()
{
- if (!s_doneUIInit)
- CheckUIInit();
+ UIManager.CheckUIInit();
if (MouseInspector.Enabled)
MouseInspector.UpdateInspect();
else
- {
- if (InputManager.GetKeyDown(ModConfig.Instance.Main_Menu_Toggle))
- ShowMenu = !ShowMenu;
-
- if (ShowMenu && s_doneUIInit)
- UIManager.Update();
- }
- }
-
- private static void CheckUIInit()
- {
- s_timeSinceStartup += Time.deltaTime;
-
- if (s_timeSinceStartup > 0.1f)
- {
- s_doneUIInit = true;
- try
- {
- UIManager.Init();
- Log("Initialized UnityExplorer UI.");
-
- if (ModConfig.Instance.Hide_On_Startup)
- ShowMenu = false;
-
- // InspectorManager.Instance.Inspect(Tests.TestClass.Instance);
- }
- catch (Exception e)
- {
- LogWarning($"Exception setting up UI: {e}");
- }
- }
+ UIManager.Update();
}
private void SetupEvents()
@@ -129,10 +78,14 @@ namespace UnityExplorer
try
{
Application.add_logMessageReceived(new Action(OnUnityLog));
+
SceneManager.add_sceneLoaded(new Action((Scene a, LoadSceneMode b) => { OnSceneLoaded(); }));
SceneManager.add_activeSceneChanged(new Action((Scene a, Scene b) => { OnSceneLoaded(); }));
}
- catch { }
+ catch (Exception ex)
+ {
+ LogWarning($"Exception setting up Unity event listeners!\r\n{ex}");
+ }
#else
Application.logMessageReceived += OnUnityLog;
SceneManager.sceneLoaded += (Scene a, LoadSceneMode b) => { OnSceneLoaded(); };
@@ -145,23 +98,6 @@ namespace UnityExplorer
UIManager.OnSceneChange();
}
- private static void SetShowMenu(bool show)
- {
- s_showMenu = show;
-
- if (UIManager.CanvasRoot)
- {
- UIManager.CanvasRoot.SetActive(show);
-
- if (show)
- ForceUnlockCursor.SetEventSystem();
- else
- ForceUnlockCursor.ReleaseEventSystem();
- }
-
- ForceUnlockCursor.UpdateCursorControl();
- }
-
private void OnUnityLog(string message, string stackTrace, LogType type)
{
if (!DebugConsole.LogUnity)
@@ -185,12 +121,6 @@ namespace UnityExplorer
}
}
-#if STANDALONE
- public static Action OnLogMessage;
- public static Action OnLogWarning;
- public static Action OnLogError;
-#endif
-
public static void Log(object message, bool unity = false)
{
DebugConsole.Log(message?.ToString());
@@ -198,13 +128,7 @@ namespace UnityExplorer
if (unity)
return;
-#if ML
- MelonLoader.MelonLogger.Msg(message?.ToString());
-#elif BIE
- ExplorerBepInPlugin.Logging?.LogMessage(message?.ToString());
-#elif STANDALONE
- OnLogMessage?.Invoke(message?.ToString());
-#endif
+ Loader.OnLogMessage(message);
}
public static void LogWarning(object message, bool unity = false)
@@ -214,13 +138,7 @@ namespace UnityExplorer
if (unity)
return;
-#if ML
- MelonLoader.MelonLogger.Msg(message?.ToString());
-#elif BIE
- ExplorerBepInPlugin.Logging?.LogWarning(message?.ToString());
-#elif STANDALONE
- OnLogWarning?.Invoke(message?.ToString());
-#endif
+ Loader.OnLogWarning(message);
}
public static void LogError(object message, bool unity = false)
@@ -230,24 +148,7 @@ namespace UnityExplorer
if (unity)
return;
-#if ML
- MelonLoader.MelonLogger.Msg(message?.ToString());
-#elif BIE
- ExplorerBepInPlugin.Logging?.LogError(message?.ToString());
-#elif STANDALONE
- OnLogError?.Invoke(message?.ToString());
-#endif
- }
-
-
- public static string RemoveInvalidFilenameChars(string s)
- {
- var invalid = System.IO.Path.GetInvalidFileNameChars();
- foreach (var c in invalid)
- {
- s = s.Replace(c.ToString(), "");
- }
- return s;
+ Loader.OnLogError(message);
}
}
}
diff --git a/src/ExplorerMelonMod.cs b/src/ExplorerMelonMod.cs
deleted file mode 100644
index cc44b2c..0000000
--- a/src/ExplorerMelonMod.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-#if ML
-using System;
-using MelonLoader;
-
-namespace UnityExplorer
-{
- public class ExplorerMelonMod : MelonMod
- {
- public static ExplorerMelonMod Instance;
-
- public override void OnApplicationStart()
- {
- Instance = this;
-
- new ExplorerCore();
- }
-
- public override void OnUpdate()
- {
- ExplorerCore.Update();
- }
-
- public override void OnSceneWasLoaded(int buildIndex, string sceneName)
- {
- ExplorerCore.Instance.OnSceneLoaded();
- }
- }
-}
-#endif
\ No newline at end of file
diff --git a/src/ExplorerStandalone.cs b/src/ExplorerStandalone.cs
deleted file mode 100644
index d55c01c..0000000
--- a/src/ExplorerStandalone.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-#if STANDALONE
-using HarmonyLib;
-
-namespace UnityExplorer
-{
- public class ExplorerStandalone
- {
- public static readonly Harmony HarmonyInstance = new Harmony(ExplorerCore.GUID);
- }
-}
-#endif
\ No newline at end of file
diff --git a/src/Inspectors/Reflection/InstanceInspector.cs b/src/Inspectors/Reflection/InstanceInspector.cs
index 9de3ae7..f431111 100644
--- a/src/Inspectors/Reflection/InstanceInspector.cs
+++ b/src/Inspectors/Reflection/InstanceInspector.cs
@@ -251,7 +251,7 @@ namespace UnityExplorer.Inspectors.Reflection
if (string.IsNullOrEmpty(name))
name = "untitled";
- var savePath = $@"{Config.ModConfig.Instance.Default_Output_Path}\{name}.png";
+ var savePath = $@"{Config.ExplorerConfig.Instance.Default_Output_Path}\{name}.png";
inputField.text = savePath;
saveBtn.onClick.AddListener(() =>
diff --git a/src/Inspectors/Reflection/InteractiveValue/InteractiveDictionary.cs b/src/Inspectors/Reflection/InteractiveValue/InteractiveDictionary.cs
index c49e820..7dff039 100644
--- a/src/Inspectors/Reflection/InteractiveValue/InteractiveDictionary.cs
+++ b/src/Inspectors/Reflection/InteractiveValue/InteractiveDictionary.cs
@@ -59,7 +59,7 @@ namespace UnityExplorer.Inspectors.Reflection
= new List>();
internal readonly KeyValuePair[] m_displayedEntries
- = new KeyValuePair[ModConfig.Instance.Default_Page_Limit];
+ = new KeyValuePair[ExplorerConfig.Instance.Default_Page_Limit];
internal bool m_recacheWanted = true;
diff --git a/src/Inspectors/Reflection/InteractiveValue/InteractiveEnumerable.cs b/src/Inspectors/Reflection/InteractiveValue/InteractiveEnumerable.cs
index 441dd30..89df055 100644
--- a/src/Inspectors/Reflection/InteractiveValue/InteractiveEnumerable.cs
+++ b/src/Inspectors/Reflection/InteractiveValue/InteractiveEnumerable.cs
@@ -46,7 +46,7 @@ namespace UnityExplorer.Inspectors.Reflection
internal readonly Type m_baseEntryType;
internal readonly List m_entries = new List();
- internal readonly CacheEnumerated[] m_displayedEntries = new CacheEnumerated[ModConfig.Instance.Default_Page_Limit];
+ internal readonly CacheEnumerated[] m_displayedEntries = new CacheEnumerated[ExplorerConfig.Instance.Default_Page_Limit];
internal bool m_recacheWanted = true;
public override void OnValueUpdated()
diff --git a/src/Inspectors/Reflection/ReflectionInspector.cs b/src/Inspectors/Reflection/ReflectionInspector.cs
index fdb3a7a..3aedcc8 100644
--- a/src/Inspectors/Reflection/ReflectionInspector.cs
+++ b/src/Inspectors/Reflection/ReflectionInspector.cs
@@ -69,7 +69,7 @@ namespace UnityExplorer.Inspectors
// filtered members based on current filters
internal readonly List m_membersFiltered = new List();
// actual shortlist of displayed members
- internal readonly CacheMember[] m_displayedMembers = new CacheMember[ModConfig.Instance.Default_Page_Limit];
+ internal readonly CacheMember[] m_displayedMembers = new CacheMember[ExplorerConfig.Instance.Default_Page_Limit];
internal bool m_autoUpdate;
diff --git a/src/Loader/ExplorerBepIn5Plugin.cs b/src/Loader/ExplorerBepIn5Plugin.cs
new file mode 100644
index 0000000..26146ea
--- /dev/null
+++ b/src/Loader/ExplorerBepIn5Plugin.cs
@@ -0,0 +1,41 @@
+#if BIE5
+using System;
+using System.IO;
+using System.Reflection;
+using BepInEx;
+using BepInEx.Logging;
+using HarmonyLib;
+
+namespace UnityExplorer
+{
+ [BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)]
+ public class ExplorerBepInPlugin : BaseUnityPlugin, IExplorerLoader
+ {
+ public static ExplorerBepInPlugin Instance;
+
+ public static ManualLogSource Logging => Instance?.Logger;
+
+ public Harmony HarmonyInstance => s_harmony;
+ private static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID);
+
+ public string ExplorerFolder => Path.Combine(Paths.PluginPath, ExplorerCore.NAME);
+ public string ConfigFolder => Path.Combine(Paths.ConfigPath, ExplorerCore.NAME);
+
+ public Action