Compare commits

...

13 Commits
4.5.0 ... 4.5.2

24 changed files with 254 additions and 256 deletions

3
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,3 @@
# These are supported funding model platforms
ko_fi: sinaidev

View File

@ -57,7 +57,7 @@ Although UnityExplorer should work out of the box for most Unity games, in some
To adjust the settings, open the config file: To adjust the settings, open the config file:
* BepInEx: `BepInEx\config\com.sinai.unityexplorer.cfg` * BepInEx: `BepInEx\config\com.sinai.unityexplorer.cfg`
* MelonLoader: `UserData\MelonPreferences.cfg` * MelonLoader: `UserData\MelonPreferences.cfg`
* Standalone: `UnityExplorer\config.ini` * Standalone: `UnityExplorer\config.cfg`
Try adjusting the following settings and see if it fixes your issues: Try adjusting the following settings and see if it fixes your issues:
* `Startup_Delay_Time` - increase to 5-10 seconds (or more as needed), can fix issues with UnityExplorer being destroyed or corrupted during startup. * `Startup_Delay_Time` - increase to 5-10 seconds (or more as needed), can fix issues with UnityExplorer being destroyed or corrupted during startup.
@ -126,7 +126,7 @@ The inspector is used to see detailed information on objects of any type and man
* You can change the settings via the "Options" tab of the menu, or directly from the config file. * You can change the settings via the "Options" tab of the menu, or directly from the config file.
* BepInEx: `BepInEx\config\com.sinai.unityexplorer.cfg` * BepInEx: `BepInEx\config\com.sinai.unityexplorer.cfg`
* MelonLoader: `UserData\MelonPreferences.cfg` * MelonLoader: `UserData\MelonPreferences.cfg`
* Standalone `{DLL_location}\UnityExplorer\config.ini` * Standalone `{DLL_location}\UnityExplorer\config.cfg`
# Building # Building

View File

@ -12,11 +12,16 @@ namespace UnityExplorer.Config
{ {
public static class ConfigManager public static class ConfigManager
{ {
internal static readonly Dictionary<string, IConfigElement> ConfigElements = new();
internal static readonly Dictionary<string, IConfigElement> InternalConfigs = new();
// Each Mod Loader has its own ConfigHandler. // Each Mod Loader has its own ConfigHandler.
// See the UnityExplorer.Loader namespace for the implementations. // See the UnityExplorer.Loader namespace for the implementations.
public static ConfigHandler Handler { get; private set; } public static ConfigHandler Handler { get; private set; }
// Actual UE Settings
public static ConfigElement<KeyCode> Master_Toggle; public static ConfigElement<KeyCode> Master_Toggle;
public static ConfigElement<int> Target_Display;
public static ConfigElement<UIManager.VerticalAnchor> Main_Navbar_Anchor; public static ConfigElement<UIManager.VerticalAnchor> Main_Navbar_Anchor;
public static ConfigElement<bool> Force_Unlock_Mouse; public static ConfigElement<bool> Force_Unlock_Mouse;
public static ConfigElement<KeyCode> Force_Unlock_Toggle; public static ConfigElement<KeyCode> Force_Unlock_Toggle;
@ -26,22 +31,18 @@ namespace UnityExplorer.Config
public static ConfigElement<bool> Log_Unity_Debug; public static ConfigElement<bool> Log_Unity_Debug;
public static ConfigElement<bool> Hide_On_Startup; public static ConfigElement<bool> Hide_On_Startup;
public static ConfigElement<float> Startup_Delay_Time; public static ConfigElement<float> Startup_Delay_Time;
public static ConfigElement<string> Reflection_Signature_Blacklist; public static ConfigElement<string> Reflection_Signature_Blacklist;
// internal configs // internal configs
internal static InternalConfigHandler InternalHandler { get; private set; } internal static InternalConfigHandler InternalHandler { get; private set; }
internal static readonly Dictionary<UIManager.Panels, ConfigElement<string>> PanelSaveData = new();
public static ConfigElement<string> ObjectExplorerData; internal static ConfigElement<string> GetPanelSaveData(UIManager.Panels panel)
public static ConfigElement<string> InspectorData; {
public static ConfigElement<string> CSConsoleData; if (!PanelSaveData.ContainsKey(panel))
public static ConfigElement<string> OptionsPanelData; PanelSaveData.Add(panel, new ConfigElement<string>(panel.ToString(), string.Empty, string.Empty, true));
public static ConfigElement<string> ConsoleLogData; return PanelSaveData[panel];
public static ConfigElement<string> HookManagerData; }
public static ConfigElement<string> ClipboardData;
internal static readonly Dictionary<string, IConfigElement> ConfigElements = new Dictionary<string, IConfigElement>();
internal static readonly Dictionary<string, IConfigElement> InternalConfigs = new Dictionary<string, IConfigElement>();
public static void Init(ConfigHandler configHandler) public static void Init(ConfigHandler configHandler)
{ {
@ -79,6 +80,11 @@ namespace UnityExplorer.Config
"The key to enable or disable UnityExplorer's menu and features.", "The key to enable or disable UnityExplorer's menu and features.",
KeyCode.F7); KeyCode.F7);
Target_Display = new ConfigElement<int>("Target Display",
"The monitor index for UnityExplorer to use, if you have multiple. 0 is the default display, 1 is secondary, etc. " +
"Restart recommended when changing this setting. Make sure your extra monitors are the same resolution as your primary monitor.",
0);
Main_Navbar_Anchor = new ConfigElement<UIManager.VerticalAnchor>("Main Navbar Anchor", Main_Navbar_Anchor = new ConfigElement<UIManager.VerticalAnchor>("Main Navbar Anchor",
"The vertical anchor of the main UnityExplorer Navbar, in case you want to move it.", "The vertical anchor of the main UnityExplorer Navbar, in case you want to move it.",
UIManager.VerticalAnchor.Top); UIManager.VerticalAnchor.Top);
@ -124,16 +130,6 @@ namespace UnityExplorer.Config
"Seperate signatures with a semicolon ';'.\r\n" + "Seperate signatures with a semicolon ';'.\r\n" +
"For example, to blacklist Camera.main, you would add 'UnityEngine.Camera.main;'", "For example, to blacklist Camera.main, you would add 'UnityEngine.Camera.main;'",
""); "");
// Internal configs (panel save data)
ObjectExplorerData = new ConfigElement<string>("ObjectExplorer", "", "", true);
InspectorData = new ConfigElement<string>("Inspector", "", "", true);
CSConsoleData = new ConfigElement<string>("CSConsole", "", "", true);
OptionsPanelData = new ConfigElement<string>("OptionsPanel", "", "", true);
ConsoleLogData = new ConfigElement<string>("ConsoleLog", "", "", true);
HookManagerData = new ConfigElement<string>("HookManager", "", "", true);
ClipboardData = new ConfigElement<string>("Clipboard", "", "", true);
} }
} }
} }

View File

@ -1,24 +1,22 @@
using IniParser.Parser; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityExplorer.UI; using UnityExplorer.UI;
using Tomlet;
using Tomlet.Models;
namespace UnityExplorer.Config namespace UnityExplorer.Config
{ {
public class InternalConfigHandler : ConfigHandler public class InternalConfigHandler : ConfigHandler
{ {
internal static IniDataParser _parser; internal static string CONFIG_PATH;
internal static string INI_PATH;
public override void Init() public override void Init()
{ {
INI_PATH = Path.Combine(ExplorerCore.Loader.ExplorerFolder, "data.ini"); CONFIG_PATH = Path.Combine(ExplorerCore.Loader.ExplorerFolder, "data.cfg");
_parser = new IniDataParser();
_parser.Configuration.CommentString = "#";
} }
public override void LoadConfig() public override void LoadConfig()
@ -37,32 +35,24 @@ namespace UnityExplorer.Config
// Not necessary // Not necessary
} }
public override T GetConfigValue<T>(ConfigElement<T> element) // Not necessary, just return the value.
{ public override T GetConfigValue<T>(ConfigElement<T> element) => element.Value;
// Not necessary, just return the value.
return element.Value;
}
public override void OnAnyConfigChanged() // Always just auto-save.
{ public override void OnAnyConfigChanged() => SaveConfig();
SaveConfig();
}
public bool TryLoadConfig() public bool TryLoadConfig()
{ {
try try
{ {
if (!File.Exists(INI_PATH)) if (!File.Exists(CONFIG_PATH))
return false; return false;
string ini = File.ReadAllText(INI_PATH); TomlDocument document = TomlParser.ParseFile(CONFIG_PATH);
foreach (var key in document.Keys)
var data = _parser.Parse(ini);
foreach (var config in data.Sections["Config"])
{ {
if (ConfigManager.InternalConfigs.TryGetValue(config.KeyName, out IConfigElement configElement)) var panelKey = (UIManager.Panels)Enum.Parse(typeof(UIManager.Panels), key);
configElement.BoxedValue = StringToConfigValue(config.Value, configElement.ElementType); ConfigManager.GetPanelSaveData(panelKey).Value = document.GetString(key);
} }
return true; return true;
@ -79,27 +69,11 @@ namespace UnityExplorer.Config
if (UIManager.Initializing) if (UIManager.Initializing)
return; return;
var data = new IniParser.Model.IniData(); var tomlDocument = TomlDocument.CreateEmpty();
data.Sections.AddSection("Config");
var sec = data.Sections["Config"];
foreach (var entry in ConfigManager.InternalConfigs) foreach (var entry in ConfigManager.InternalConfigs)
sec.AddKey(entry.Key, entry.Value.BoxedValue.ToString()); tomlDocument.Put(entry.Key, entry.Value.BoxedValue as string, false);
File.WriteAllText(INI_PATH, data.ToString()); File.WriteAllText(CONFIG_PATH, tomlDocument.SerializedValue);
}
public object StringToConfigValue(string value, Type elementType)
{
if (elementType.IsEnum)
return Enum.Parse(elementType, value);
else if (elementType == typeof(bool))
return bool.Parse(value);
else if (elementType == typeof(int))
return int.Parse(value);
else
return value;
} }
} }
} }

View File

@ -10,13 +10,14 @@ using UnityExplorer.ObjectExplorer;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UnityExplorer.Runtime; using UnityExplorer.Runtime;
using UniverseLib.Input; using UniverseLib.Input;
using UniverseLib.UI;
namespace UnityExplorer namespace UnityExplorer
{ {
public static class ExplorerCore public static class ExplorerCore
{ {
public const string NAME = "UnityExplorer"; public const string NAME = "UnityExplorer";
public const string VERSION = "4.5.0"; public const string VERSION = "4.5.2";
public const string AUTHOR = "Sinai"; public const string AUTHOR = "Sinai";
public const string GUID = "com.sinai.unityexplorer"; public const string GUID = "com.sinai.unityexplorer";

View File

@ -6,9 +6,9 @@
<ItemGroup> <ItemGroup>
<InputAssemblies Include="$(OutputPath)$(AssemblyName).dll" /> <InputAssemblies Include="$(OutputPath)$(AssemblyName).dll" />
<InputAssemblies Include="..\lib\mcs-unity\mcs\bin\Release\mcs.dll" /> <InputAssemblies Include="..\lib\mcs-unity\mcs\bin\Release\mcs.dll" />
<InputAssemblies Include="packages\ini-parser.2.5.2\lib\net20\INIFileParser.dll" /> <InputAssemblies Include="packages\Samboy063.Tomlet.3.1.3\lib\net35\Tomlet.dll" />
</ItemGroup> </ItemGroup>
<!-- Required references for ILRepack --> <!-- Required references for ILRepack -->
<ItemGroup> <ItemGroup>
<ReferenceFolders Include="packages\HarmonyX.2.5.2\lib\net35\" /> <ReferenceFolders Include="packages\HarmonyX.2.5.2\lib\net35\" />

View File

@ -31,24 +31,19 @@ namespace UnityExplorer.Inspectors
public static bool Inspecting { get; set; } public static bool Inspecting { get; set; }
public static MouseInspectMode Mode { get; set; } public static MouseInspectMode Mode { get; set; }
public MouseInspectorBase CurrentInspector => Mode switch
{
MouseInspectMode.UI => uiInspector,
MouseInspectMode.World => worldInspector,
_ => null,
};
private static Vector3 lastMousePos; private static Vector3 lastMousePos;
public MouseInspectorBase CurrentInspector
{
get
{
switch (Mode)
{
case MouseInspectMode.UI:
return uiInspector;
case MouseInspectMode.World:
return worldInspector;
}
return null;
}
}
// UIPanel // UIPanel
internal static readonly string UIBaseGUID = $"{ExplorerCore.GUID}.MouseInspector";
private UIBase inspectorUIBase;
public override string Name => "Inspect Under Mouse"; public override string Name => "Inspect Under Mouse";
public override UIManager.Panels PanelType => UIManager.Panels.MouseInspector; public override UIManager.Panels PanelType => UIManager.Panels.MouseInspector;
public override int MinWidth => -1; public override int MinWidth => -1;
@ -164,7 +159,7 @@ namespace UnityExplorer.Inspectors
mousePos.y -= 10; mousePos.y -= 10;
// calculate and set our UI position // calculate and set our UI position
var inversePos = UIManager.UIRoot.transform.InverseTransformPoint(mousePos); var inversePos = inspectorUIBase.RootObject.transform.InverseTransformPoint(mousePos);
UIRoot.transform.localPosition = new Vector3(inversePos.x, inversePos.y, 0); UIRoot.transform.localPosition = new Vector3(inversePos.x, inversePos.y, 0);
} }
@ -207,10 +202,12 @@ namespace UnityExplorer.Inspectors
UIFactory.SetLayoutElement(objPathLabel.gameObject, minHeight: 75); UIFactory.SetLayoutElement(objPathLabel.gameObject, minHeight: 75);
UIRoot.SetActive(false); UIRoot.SetActive(false);
// Create a new canvas for this panel to live on.
// It needs to always be shown on the main display, other panels can move displays.
inspectorUIBase = UniversalUI.RegisterUI(UIBaseGUID, null);
UIRoot.transform.SetParent(inspectorUIBase.RootObject.transform);
} }
public override void DoSaveToConfigElement() { }
public override string GetSaveDataFromConfigManager() => null;
} }
} }

View File

@ -4,22 +4,20 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using UnityExplorer.Config; using UnityExplorer.Config;
using IniParser.Parser;
using System.IO; using System.IO;
using UnityEngine; using UnityEngine;
using Tomlet;
using Tomlet.Models;
namespace UnityExplorer.Loader.STANDALONE namespace UnityExplorer.Loader.STANDALONE
{ {
public class StandaloneConfigHandler : ConfigHandler public class StandaloneConfigHandler : ConfigHandler
{ {
internal static IniDataParser _parser;
internal static string CONFIG_PATH; internal static string CONFIG_PATH;
public override void Init() public override void Init()
{ {
CONFIG_PATH = Path.Combine(ExplorerCore.Loader.ExplorerFolder, "config.ini"); CONFIG_PATH = Path.Combine(ExplorerCore.Loader.ExplorerFolder, "config.cfg");
_parser = new IniDataParser();
_parser.Configuration.CommentString = "#";
} }
public override void LoadConfig() public override void LoadConfig()
@ -52,14 +50,11 @@ namespace UnityExplorer.Loader.STANDALONE
if (!File.Exists(CONFIG_PATH)) if (!File.Exists(CONFIG_PATH))
return false; return false;
string ini = File.ReadAllText(CONFIG_PATH); var document = TomlParser.ParseFile(CONFIG_PATH);
foreach (var key in document.Keys)
var data = _parser.Parse(ini);
foreach (var config in data.Sections["Config"])
{ {
if (ConfigManager.ConfigElements.TryGetValue(config.KeyName, out IConfigElement configElement)) var config = ConfigManager.ConfigElements[key];
configElement.BoxedValue = StringToConfigValue(config.Value, configElement.ElementType); config.BoxedValue = StringToConfigValue(document.GetValue(key).StringValue, config.ElementType);
} }
return true; return true;
@ -89,18 +84,14 @@ namespace UnityExplorer.Loader.STANDALONE
public override void SaveConfig() public override void SaveConfig()
{ {
var data = new IniParser.Model.IniData(); var document = TomlDocument.CreateEmpty();
foreach (var config in ConfigManager.ConfigElements)
data.Sections.AddSection("Config"); document.Put(config.Key, config.Value.BoxedValue.ToString());
var sec = data.Sections["Config"];
foreach (var entry in ConfigManager.ConfigElements)
sec.AddKey(entry.Key, entry.Value.BoxedValue.ToString());
if (!Directory.Exists(ExplorerCore.Loader.ExplorerFolder)) if (!Directory.Exists(ExplorerCore.Loader.ExplorerFolder))
Directory.CreateDirectory(ExplorerCore.Loader.ExplorerFolder); Directory.CreateDirectory(ExplorerCore.Loader.ExplorerFolder);
File.WriteAllText(CONFIG_PATH, data.ToString()); File.WriteAllText(CONFIG_PATH, document.SerializedValue);
} }
} }
} }

80
src/UI/DisplayManager.cs Normal file
View File

@ -0,0 +1,80 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityExplorer.Config;
using UniverseLib;
using UniverseLib.Input;
namespace UnityExplorer.UI
{
public static class DisplayManager
{
public static int ActiveDisplayIndex { get; private set; }
public static Display ActiveDisplay => Display.displays[ActiveDisplayIndex];
public static int Width => ActiveDisplay.renderingWidth;
public static int Height => ActiveDisplay.renderingHeight;
public static Vector3 MousePosition => Display.RelativeMouseAt(InputManager.MousePosition);
public static bool MouseInTargetDisplay => MousePosition.z == ActiveDisplayIndex;
private static Camera canvasCamera;
internal static void Init()
{
SetDisplay(ConfigManager.Target_Display.Value);
ConfigManager.Target_Display.OnValueChanged += SetDisplay;
}
public static void SetDisplay(int display)
{
if (ActiveDisplayIndex == display)
return;
if (Display.displays.Length <= display)
{
ExplorerCore.LogWarning($"Cannot set display index to {display} as there are not enough monitors connected!");
if (ConfigManager.Target_Display.Value == display)
ConfigManager.Target_Display.Value = 0;
return;
}
ActiveDisplayIndex = display;
ActiveDisplay.Activate();
UIManager.UICanvas.targetDisplay = display;
// ensure a camera is targeting the display
if (!Camera.main || Camera.main.targetDisplay != display)
{
if (!canvasCamera)
{
canvasCamera = new GameObject("UnityExplorer_CanvasCamera").AddComponent<Camera>();
GameObject.DontDestroyOnLoad(canvasCamera.gameObject);
canvasCamera.hideFlags = HideFlags.HideAndDontSave;
}
canvasCamera.targetDisplay = display;
}
RuntimeProvider.Instance.StartCoroutine(FixPanels());
}
private static IEnumerator FixPanels()
{
yield return null;
yield return null;
foreach (var panel in UIManager.UIPanels.Values)
{
panel.EnsureValidSize();
panel.EnsureValidPosition();
panel.Dragger.OnEndResize();
}
}
}
}

View File

@ -27,7 +27,7 @@ namespace UnityExplorer.UI
_currentNotification = message; _currentNotification = message;
_timeOfLastNotification = Time.realtimeSinceStartup; _timeOfLastNotification = Time.realtimeSinceStartup;
popupLabel.transform.localPosition = UIManager.UIRootRect.InverseTransformPoint(InputManager.MousePosition) + (Vector3.up * 25); popupLabel.transform.localPosition = UIManager.UIRootRect.InverseTransformPoint(DisplayManager.MousePosition) + (Vector3.up * 25);
} }
public static void Update() public static void Update()

View File

@ -55,15 +55,6 @@ namespace UnityExplorer.UI.Panels
ConsoleController.Update(); ConsoleController.Update();
} }
// Saving
public override void DoSaveToConfigElement()
{
ConfigManager.CSConsoleData.Value = this.ToSaveData();
}
public override string GetSaveDataFromConfigManager() => ConfigManager.CSConsoleData.Value;
// UI Construction // UI Construction
public override void OnFinishResize(RectTransform panel) public override void OnFinishResize(RectTransform panel)

View File

@ -27,8 +27,6 @@ namespace UnityExplorer.UI.Panels
public override bool NavButtonWanted => true; public override bool NavButtonWanted => true;
public override bool ShouldSaveActiveState => true; public override bool ShouldSaveActiveState => true;
public override bool ShowByDefault => true; public override bool ShowByDefault => true;
public override string GetSaveDataFromConfigManager() => ConfigManager.ClipboardData.Value;
public override void DoSaveToConfigElement() => ConfigManager.ClipboardData.Value = this.ToSaveData();
private static Text CurrentPasteLabel; private static Text CurrentPasteLabel;

View File

@ -46,10 +46,6 @@ namespace UnityExplorer.UI.Panels
public Text EditorInputText { get; private set; } public Text EditorInputText { get; private set; }
public Text EditorHighlightText { get; private set; } public Text EditorHighlightText { get; private set; }
public override string GetSaveDataFromConfigManager() => ConfigManager.HookManagerData.Value;
public override void DoSaveToConfigElement() => ConfigManager.HookManagerData.Value = this.ToSaveData();
private void OnClassInputAddClicked() private void OnClassInputAddClicked()
{ {
HookManager.Instance.OnClassSelectedForHooks(this.classSelectorInputField.Text); HookManager.Instance.OnClassSelectedForHooks(this.classSelectorInputField.Text);

View File

@ -44,10 +44,6 @@ namespace UnityExplorer.UI.Panels
InspectorManager.OnPanelResized(panel.rect.width); InspectorManager.OnPanelResized(panel.rect.width);
} }
public override string GetSaveDataFromConfigManager() => ConfigManager.InspectorData.Value;
public override void DoSaveToConfigElement() => ConfigManager.InspectorData.Value = this.ToSaveData();
protected internal override void DoSetDefaultPosAndAnchors() protected internal override void DoSetDefaultPosAndAnchors()
{ {
Rect.localPosition = Vector2.zero; Rect.localPosition = Vector2.zero;

View File

@ -144,18 +144,6 @@ namespace UnityExplorer.UI.Panels
RuntimeProvider.Instance.SetColorBlock(cell.Input.Component, color); RuntimeProvider.Instance.SetColorBlock(cell.Input.Component, color);
} }
// Panel save data
public override string GetSaveDataFromConfigManager()
{
return ConfigManager.ConsoleLogData.Value;
}
public override void DoSaveToConfigElement()
{
ConfigManager.ConsoleLogData.Value = this.ToSaveData();
}
protected internal override void DoSetDefaultPosAndAnchors() protected internal override void DoSetDefaultPosAndAnchors()
{ {
Rect.localPosition = Vector2.zero; Rect.localPosition = Vector2.zero;

View File

@ -46,7 +46,7 @@ namespace UnityExplorer.UI.Panels
RuntimeProvider.Instance.SetColorBlock(button.Component, UniversalUI.enabledButtonColor, UniversalUI.enabledButtonColor * 1.2f); RuntimeProvider.Instance.SetColorBlock(button.Component, UniversalUI.enabledButtonColor, UniversalUI.enabledButtonColor * 1.2f);
SelectedTab = tabIndex; SelectedTab = tabIndex;
SaveToConfigManager(); SaveInternalData();
} }
private void DisableTab(int tabIndex) private void DisableTab(int tabIndex)
@ -63,21 +63,12 @@ namespace UnityExplorer.UI.Panels
ObjectSearch.Update(); ObjectSearch.Update();
} }
public override string GetSaveDataFromConfigManager() => ConfigManager.ObjectExplorerData.Value;
public override void DoSaveToConfigElement()
{
ConfigManager.ObjectExplorerData.Value = this.ToSaveData();
}
public override string ToSaveData() public override string ToSaveData()
{ {
string ret = base.ToSaveData(); return string.Join("|", new string[] { base.ToSaveData(), SelectedTab.ToString() });
ret += "|" + SelectedTab;
return ret;
} }
public override void ApplySaveData(string data) protected override void ApplySaveData(string data)
{ {
base.ApplySaveData(data); base.ApplySaveData(data);

View File

@ -55,17 +55,7 @@ namespace UnityExplorer.UI.Panels
CacheObjectControllerHelper.SetCell(cell, index, this.configEntries, null); CacheObjectControllerHelper.SetCell(cell, index, this.configEntries, null);
} }
// Panel save data // UI Construction
public override string GetSaveDataFromConfigManager()
{
return ConfigManager.OptionsPanelData.Value;
}
public override void DoSaveToConfigElement()
{
ConfigManager.OptionsPanelData.Value = this.ToSaveData();
}
protected internal override void DoSetDefaultPosAndAnchors() protected internal override void DoSetDefaultPosAndAnchors()
{ {
@ -76,8 +66,6 @@ namespace UnityExplorer.UI.Panels
Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 600f); Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 600f);
} }
// UI Construction
public override void ConstructPanelContent() public override void ConstructPanelContent()
{ {
// Save button // Save button

View File

@ -67,6 +67,9 @@ namespace UnityExplorer.UI.Panels
public static void UpdateInstances() public static void UpdateInstances()
{ {
if (!DisplayManager.MouseInTargetDisplay)
return;
if (!resizeCursorObj) if (!resizeCursorObj)
CreateCursorUI(); CreateCursorUI();
@ -78,7 +81,7 @@ namespace UnityExplorer.UI.Panels
else else
state = MouseState.NotPressed; state = MouseState.NotPressed;
var mousePos = InputManager.MousePosition; var mousePos = DisplayManager.MousePosition;
handledInstanceThisFrame = false; handledInstanceThisFrame = false;
foreach (var instance in Instances) foreach (var instance in Instances)
@ -234,12 +237,12 @@ namespace UnityExplorer.UI.Panels
{ {
wasAnyDragging = true; wasAnyDragging = true;
WasDragging = true; WasDragging = true;
lastDragPosition = InputManager.MousePosition; lastDragPosition = DisplayManager.MousePosition;
} }
public void OnDrag() public void OnDrag()
{ {
var mousePos = InputManager.MousePosition; var mousePos = DisplayManager.MousePosition;
Vector2 diff = (Vector2)mousePos - lastDragPosition; Vector2 diff = (Vector2)mousePos - lastDragPosition;
lastDragPosition = mousePos; lastDragPosition = mousePos;
@ -260,7 +263,7 @@ namespace UnityExplorer.UI.Panels
#region RESIZE #region RESIZE
private readonly Dictionary<ResizeTypes, Rect> m_resizeMask = new Dictionary<ResizeTypes, Rect> private readonly Dictionary<ResizeTypes, Rect> m_resizeMask = new()
{ {
{ ResizeTypes.Top, default }, { ResizeTypes.Top, default },
{ ResizeTypes.Left, default }, { ResizeTypes.Left, default },
@ -388,7 +391,7 @@ namespace UnityExplorer.UI.Panels
// update the resize icon position to be above the mouse // update the resize icon position to be above the mouse
private void UpdateHoverImagePos() private void UpdateHoverImagePos()
{ {
resizeCursorObj.transform.localPosition = UIManager.UIRootRect.InverseTransformPoint(InputManager.MousePosition); resizeCursorObj.transform.localPosition = UIManager.UIRootRect.InverseTransformPoint(DisplayManager.MousePosition);
} }
public void OnHoverResizeEnd() public void OnHoverResizeEnd()
@ -400,26 +403,26 @@ namespace UnityExplorer.UI.Panels
public void OnBeginResize(ResizeTypes resizeType) public void OnBeginResize(ResizeTypes resizeType)
{ {
currentResizeType = resizeType; currentResizeType = resizeType;
lastResizePos = InputManager.MousePosition; lastResizePos = DisplayManager.MousePosition;
WasResizing = true; WasResizing = true;
Resizing = true; Resizing = true;
} }
public void OnResize() public void OnResize()
{ {
Vector3 mousePos = InputManager.MousePosition; Vector3 mousePos = DisplayManager.MousePosition;
Vector2 diff = lastResizePos - (Vector2)mousePos; Vector2 diff = lastResizePos - (Vector2)mousePos;
if ((Vector2)mousePos == lastResizePos) if ((Vector2)mousePos == lastResizePos)
return; return;
if (mousePos.x < 0 || mousePos.y < 0 || mousePos.x > Screen.width || mousePos.y > Screen.height) if (mousePos.x < 0 || mousePos.y < 0 || mousePos.x > DisplayManager.Width || mousePos.y > DisplayManager.Height)
return; return;
lastResizePos = mousePos; lastResizePos = mousePos;
float diffX = (float)((decimal)diff.x / Screen.width); float diffX = (float)((decimal)diff.x / DisplayManager.Width);
float diffY = (float)((decimal)diff.y / Screen.height); float diffY = (float)((decimal)diff.y / DisplayManager.Height);
Vector2 anchorMin = Panel.anchorMin; Vector2 anchorMin = Panel.anchorMin;
Vector2 anchorMax = Panel.anchorMax; Vector2 anchorMax = Panel.anchorMax;

View File

@ -11,6 +11,7 @@ using UnityExplorer.UI.Widgets;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib; using UniverseLib;
using System.Collections;
namespace UnityExplorer.UI.Panels namespace UnityExplorer.UI.Panels
{ {
@ -32,10 +33,11 @@ namespace UnityExplorer.UI.Panels
return; return;
// if the user is clicking // if the user is clicking
if (InputManager.GetMouseButtonDown(0) || InputManager.GetMouseButtonDown(1)) if (DisplayManager.MouseInTargetDisplay
&& (InputManager.GetMouseButtonDown(0) || InputManager.GetMouseButtonDown(1)))
{ {
int count = UIManager.PanelHolder.transform.childCount; int count = UIManager.PanelHolder.transform.childCount;
var mousePos = InputManager.MousePosition; var mousePos = DisplayManager.MousePosition;
bool clickedInAny = false; bool clickedInAny = false;
for (int i = count - 1; i >= 0; i--) for (int i = count - 1; i >= 0; i--)
@ -92,19 +94,16 @@ namespace UnityExplorer.UI.Panels
protected GameObject uiRoot; protected GameObject uiRoot;
public RectTransform Rect; public RectTransform Rect;
public GameObject content; public GameObject content;
public GameObject titleBar; public GameObject titleBar;
public abstract void ConstructPanelContent();
public virtual void OnFinishResize(RectTransform panel) public virtual void OnFinishResize(RectTransform panel)
{ {
SaveToConfigManager(); SaveInternalData();
} }
public virtual void OnFinishDrag(RectTransform panel) public virtual void OnFinishDrag(RectTransform panel)
{ {
SaveToConfigManager(); SaveInternalData();
} }
public override void SetActive(bool active) public override void SetActive(bool active)
@ -115,7 +114,7 @@ namespace UnityExplorer.UI.Panels
base.SetActive(active); base.SetActive(active);
if (!ApplyingSaveData) if (!ApplyingSaveData)
SaveToConfigManager(); SaveInternalData();
if (NavButtonWanted) if (NavButtonWanted)
{ {
@ -148,13 +147,15 @@ namespace UnityExplorer.UI.Panels
Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, MinHeight); Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, MinHeight);
} }
public void EnsureValidPosition() => EnsureValidPosition(this.Rect);
public static void EnsureValidPosition(RectTransform panel) public static void EnsureValidPosition(RectTransform panel)
{ {
var pos = panel.localPosition; var pos = panel.localPosition;
// Prevent panel going oustide screen bounds // Prevent panel going oustide screen bounds
var halfW = Screen.width * 0.5f; var halfW = DisplayManager.Width * 0.5f;
var halfH = Screen.height * 0.5f; var halfH = DisplayManager.Height * 0.5f;
pos.x = Math.Max(-halfW - panel.rect.width + 50, Math.Min(pos.x, halfW - 50)); pos.x = Math.Max(-halfW - panel.rect.width + 50, Math.Min(pos.x, halfW - 50));
pos.y = Math.Max(-halfH + 50, Math.Min(pos.y, halfH)); pos.y = Math.Max(-halfH + 50, Math.Min(pos.y, halfH));
@ -162,29 +163,30 @@ namespace UnityExplorer.UI.Panels
panel.localPosition = pos; panel.localPosition = pos;
} }
#region Save Data // Save Data
public abstract void DoSaveToConfigElement(); public bool ApplyingSaveData { get; set; }
public void SaveToConfigManager() public void SaveInternalData()
{ {
if (UIManager.Initializing) if (UIManager.Initializing)
return; return;
DoSaveToConfigElement(); SetSaveDataToConfigValue();
} }
public abstract string GetSaveDataFromConfigManager(); private void SetSaveDataToConfigValue() => ConfigManager.GetPanelSaveData(this.PanelType).Value = this.ToSaveData();
public bool ApplyingSaveData { get; set; }
public virtual string ToSaveData() public virtual string ToSaveData()
{ {
try try
{ {
return $"{ShouldSaveActiveState && Enabled}" + return string.Join("|", new string[]
$"|{Rect.RectAnchorsToString()}" + {
$"|{Rect.RectPositionToString()}"; $"{ShouldSaveActiveState && Enabled}",
Rect.RectAnchorsToString(),
Rect.RectPositionToString()
});
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -193,7 +195,13 @@ namespace UnityExplorer.UI.Panels
} }
} }
public virtual void ApplySaveData(string data) public virtual void ApplySaveData()
{
string data = ConfigManager.GetPanelSaveData(this.PanelType).Value;
ApplySaveData(data);
}
protected virtual void ApplySaveData(string data)
{ {
if (string.IsNullOrEmpty(data)) if (string.IsNullOrEmpty(data))
return; return;
@ -210,17 +218,14 @@ namespace UnityExplorer.UI.Panels
{ {
ExplorerCore.LogWarning("Invalid or corrupt panel save data! Restoring to default."); ExplorerCore.LogWarning("Invalid or corrupt panel save data! Restoring to default.");
SetTransformDefaults(); SetTransformDefaults();
UIManager.Initializing = false; SetSaveDataToConfigValue();
DoSaveToConfigElement();
ConfigManager.InternalHandler.SaveConfig();
UIManager.Initializing = true;
} }
} }
#endregion
// UI Construction // UI Construction
public abstract void ConstructPanelContent();
public void ConstructUI() public void ConstructUI()
{ {
//this.Enabled = true; //this.Enabled = true;
@ -275,7 +280,7 @@ namespace UnityExplorer.UI.Panels
closeBtn.OnClick += () => closeBtn.OnClick += () =>
{ {
UIManager.SetPanelActive(this.PanelType, false); UIManager.SetPanelActive(this.PanelType, false);
SaveToConfigManager(); SaveInternalData();
}; };
if (!CanDragAndResize) if (!CanDragAndResize)
@ -300,7 +305,7 @@ namespace UnityExplorer.UI.Panels
// apply panel save data or revert to default // apply panel save data or revert to default
try try
{ {
ApplySaveData(GetSaveDataFromConfigManager()); ApplySaveData();
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -308,7 +313,20 @@ namespace UnityExplorer.UI.Panels
SetTransformDefaults(); SetTransformDefaults();
} }
LayoutRebuilder.ForceRebuildLayoutImmediate(this.Rect); RuntimeProvider.Instance.StartCoroutine(LateSetupCoroutine());
// simple listener for saving enabled state
this.OnToggleEnabled += (bool val) =>
{
SaveInternalData();
};
ApplyingSaveData = false;
}
private IEnumerator LateSetupCoroutine()
{
yield return null;
// ensure initialized position is valid // ensure initialized position is valid
EnsureValidSize(); EnsureValidSize();
@ -316,14 +334,6 @@ namespace UnityExplorer.UI.Panels
// update dragger and save data // update dragger and save data
Dragger.OnEndResize(); Dragger.OnEndResize();
// simple listener for saving enabled state
this.OnToggleEnabled += (bool val) =>
{
SaveToConfigManager();
};
ApplyingSaveData = false;
} }
public override void ConstructUI(GameObject parent) => ConstructUI(); public override void ConstructUI(GameObject parent) => ConstructUI();
@ -380,7 +390,7 @@ namespace UnityExplorer.UI.Panels
return string.Format(CultureInfo.InvariantCulture, "{0},{1}", new object[] return string.Format(CultureInfo.InvariantCulture, "{0},{1}", new object[]
{ {
rect.localPosition.x, rect.localPosition.y rect.anchoredPosition.x, rect.anchoredPosition.y
}); });
} }
@ -398,10 +408,10 @@ namespace UnityExplorer.UI.Panels
if (split.Length != 2) if (split.Length != 2)
throw new Exception($"stringPosition split is unexpected length: {split.Length}"); throw new Exception($"stringPosition split is unexpected length: {split.Length}");
Vector3 vector = rect.localPosition; Vector3 vector = rect.anchoredPosition;
vector.x = float.Parse(split[0], CultureInfo.InvariantCulture); vector.x = float.Parse(split[0], CultureInfo.InvariantCulture);
vector.y = float.Parse(split[1], CultureInfo.InvariantCulture); vector.y = float.Parse(split[1], CultureInfo.InvariantCulture);
rect.localPosition = vector; rect.anchoredPosition = vector;
} }
} }

View File

@ -72,8 +72,5 @@ namespace UnityExplorer.UI.Panels
this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 500f); this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 500f);
this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 500f); this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 500f);
} }
public override void DoSaveToConfigElement() { }
public override string GetSaveDataFromConfigManager() => null;
} }
} }

View File

@ -1,19 +1,10 @@
using HarmonyLib; using System.Collections.Generic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine; using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Config; using UnityExplorer.Config;
using UnityExplorer.CSConsole; using UnityExplorer.CSConsole;
using UnityExplorer.Inspectors; using UnityExplorer.Inspectors;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets;
using UnityExplorer.UI.Widgets.AutoComplete; using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib; using UniverseLib;
using UniverseLib.Input; using UniverseLib.Input;
@ -48,13 +39,13 @@ namespace UnityExplorer.UI
public static bool Initializing { get; internal set; } = true; public static bool Initializing { get; internal set; } = true;
private static UIBase uiBase; internal static UIBase UiBase { get; private set; }
public static GameObject UIRoot => uiBase?.RootObject; public static GameObject UIRoot => UiBase?.RootObject;
public static RectTransform UIRootRect => _uiRootRect ??= UIRoot.GetComponent<RectTransform>(); public static RectTransform UIRootRect { get; private set; }
private static RectTransform _uiRootRect; public static Canvas UICanvas { get; private set; }
internal static GameObject PanelHolder { get; private set; } internal static GameObject PanelHolder { get; private set; }
private static readonly Dictionary<Panels, UIPanel> UIPanels = new(); internal static readonly Dictionary<Panels, UIPanel> UIPanels = new();
public static RectTransform NavBarRect; public static RectTransform NavBarRect;
public static GameObject NavbarTabButtonHolder; public static GameObject NavbarTabButtonHolder;
@ -71,13 +62,14 @@ namespace UnityExplorer.UI
public static bool ShowMenu public static bool ShowMenu
{ {
get => uiBase != null && uiBase.Enabled; get => UiBase != null && UiBase.Enabled;
set set
{ {
if (uiBase == null || !UIRoot || uiBase.Enabled == value) if (UiBase == null || !UIRoot || UiBase.Enabled == value)
return; return;
UniversalUI.SetUIActive(ExplorerCore.GUID, value); UniversalUI.SetUIActive(ExplorerCore.GUID, value);
UniversalUI.SetUIActive(InspectUnderMouse.UIBaseGUID, value);
} }
} }
@ -85,11 +77,16 @@ namespace UnityExplorer.UI
internal static void InitUI() internal static void InitUI()
{ {
uiBase = UniversalUI.RegisterUI(ExplorerCore.GUID, Update); UiBase = UniversalUI.RegisterUI(ExplorerCore.GUID, Update);
lastScreenWidth = Screen.width; UIRootRect = UIRoot.GetComponent<RectTransform>();
lastScreenHeight = Screen.height; UICanvas = UIRoot.GetComponent<Canvas>();
DisplayManager.Init();
var display = DisplayManager.ActiveDisplay;
lastScreenWidth = display.renderingWidth;
lastScreenHeight = display.renderingHeight;
// Create UI. // Create UI.
CreatePanelHolder(); CreatePanelHolder();
@ -169,7 +166,8 @@ namespace UnityExplorer.UI
} }
// check screen dimension change // check screen dimension change
if (Screen.width != lastScreenWidth || Screen.height != lastScreenHeight) var display = DisplayManager.ActiveDisplay;
if (display.renderingWidth != lastScreenWidth || display.renderingHeight != lastScreenHeight)
OnScreenDimensionsChanged(); OnScreenDimensionsChanged();
} }
@ -233,8 +231,9 @@ namespace UnityExplorer.UI
private static void OnScreenDimensionsChanged() private static void OnScreenDimensionsChanged()
{ {
lastScreenWidth = Screen.width; var display = DisplayManager.ActiveDisplay;
lastScreenHeight = Screen.height; lastScreenWidth = display.renderingWidth;
lastScreenHeight = display.renderingHeight;
foreach (var panel in UIPanels) foreach (var panel in UIPanels)
{ {
@ -254,6 +253,8 @@ namespace UnityExplorer.UI
closeBtn.ButtonText.text = val.ToString(); closeBtn.ButtonText.text = val.ToString();
} }
// Time controls
private static void OnTimeInputEndEdit(string val) private static void OnTimeInputEndEdit(string val)
{ {
if (pauseButtonPausing) if (pauseButtonPausing)

View File

@ -315,12 +315,5 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
UIRoot.SetActive(false); UIRoot.SetActive(false);
} }
public override void DoSaveToConfigElement()
{
// not savable
}
public override string GetSaveDataFromConfigManager() => null;
} }
} }

View File

@ -106,8 +106,11 @@
<HintPath>..\lib\mcs-unity\mcs\bin\Release\mcs.dll</HintPath> <HintPath>..\lib\mcs-unity\mcs\bin\Release\mcs.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="INIFileParser, Version=2.5.2.0, Culture=neutral, PublicKeyToken=79af7b307b65cf3c, processorArchitecture=MSIL"> </ItemGroup>
<HintPath>packages\ini-parser.2.5.2\lib\net20\INIFileParser.dll</HintPath> <!-- Non-MelonLoader (it includes Tomlet) -->
<ItemGroup Condition="'$(IsMelonLoader)'=='false'">
<Reference Include="Tomlet, Version=3.1.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\Samboy063.Tomlet.3.1.3\lib\net35\Tomlet.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
@ -172,13 +175,13 @@
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="UniverseLib.Mono"> <Reference Include="UniverseLib.Mono">
<HintPath>packages\UniverseLib.1.0.6\lib\net35\UniverseLib.Mono.dll</HintPath> <HintPath>packages\UniverseLib.1.1.2\lib\net35\UniverseLib.Mono.dll</HintPath>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<!-- Il2Cpp refs --> <!-- Il2Cpp refs -->
<ItemGroup Condition="'$(IsCpp)'=='true'"> <ItemGroup Condition="'$(IsCpp)'=='true'">
<Reference Include="UniverseLib.IL2CPP"> <Reference Include="UniverseLib.IL2CPP">
<HintPath>packages\UniverseLib.1.0.6\lib\net472\UniverseLib.IL2CPP.dll</HintPath> <HintPath>packages\UniverseLib.1.1.2\lib\net472\UniverseLib.IL2CPP.dll</HintPath>
</Reference> </Reference>
<Reference Include="UnhollowerBaseLib"> <Reference Include="UnhollowerBaseLib">
<HintPath>..\lib\Il2CppAssemblyUnhollower\UnhollowerBaseLib\bin\Release\net4.7.2\UnhollowerBaseLib.dll</HintPath> <HintPath>..\lib\Il2CppAssemblyUnhollower\UnhollowerBaseLib\bin\Release\net4.7.2\UnhollowerBaseLib.dll</HintPath>
@ -256,6 +259,7 @@
<Compile Include="CacheObject\Views\CacheListEntryCell.cs" /> <Compile Include="CacheObject\Views\CacheListEntryCell.cs" />
<Compile Include="CacheObject\Views\CacheMemberCell.cs" /> <Compile Include="CacheObject\Views\CacheMemberCell.cs" />
<Compile Include="CacheObject\Views\CacheObjectCell.cs" /> <Compile Include="CacheObject\Views\CacheObjectCell.cs" />
<Compile Include="UI\DisplayManager.cs" />
<Compile Include="UI\Notification.cs" /> <Compile Include="UI\Notification.cs" />
<Compile Include="UI\Panels\ClipboardPanel.cs" /> <Compile Include="UI\Panels\ClipboardPanel.cs" />
<Compile Include="UI\Widgets\AutoComplete\EnumCompleter.cs" /> <Compile Include="UI\Widgets\AutoComplete\EnumCompleter.cs" />

View File

@ -2,7 +2,7 @@
<packages> <packages>
<package id="HarmonyX" version="2.5.2" targetFramework="net35" /> <package id="HarmonyX" version="2.5.2" targetFramework="net35" />
<package id="ILRepack.Lib.MSBuild.Task" version="2.0.18.2" targetFramework="net35" /> <package id="ILRepack.Lib.MSBuild.Task" version="2.0.18.2" targetFramework="net35" />
<package id="ini-parser" version="2.5.2" targetFramework="net35" />
<package id="Mono.Cecil" version="0.10.4" targetFramework="net35" /> <package id="Mono.Cecil" version="0.10.4" targetFramework="net35" />
<package id="UniverseLib" version="1.0.6" targetFramework="net35" /> <package id="Samboy063.Tomlet" version="3.1.3" targetFramework="net472" />
<package id="UniverseLib" version="1.1.2" targetFramework="net35" />
</packages> </packages>