mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-05 12:52:24 +08:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
21408993c2 | |||
7a8b5b50d1 | |||
1a5e843070 | |||
ade7539fde | |||
5c588e5a03 | |||
af094832fe | |||
af0ee2e690 | |||
d2d6fb4d55 | |||
6c25662fe9 | |||
4bcf82ca10 | |||
ce38e8ac50 | |||
12cd718f12 | |||
995e2a3e93 | |||
2c95fec646 | |||
69912d7ea4 | |||
9c5596ace4 | |||
d4dac58fc8 | |||
77b97cbe17 | |||
c6f0f34ac0 | |||
d1f4f74d32 | |||
f13068bf01 | |||
dfc288a101 | |||
544009dc21 |
56
README.md
56
README.md
@ -17,7 +17,6 @@
|
|||||||
- [Features](#features)
|
- [Features](#features)
|
||||||
- [How to install](#how-to-install)
|
- [How to install](#how-to-install)
|
||||||
- [Mod Config](#mod-config)
|
- [Mod Config](#mod-config)
|
||||||
- [Mouse Control](#mouse-control)
|
|
||||||
- [Building](#building)
|
- [Building](#building)
|
||||||
- [Credits](#credits)
|
- [Credits](#credits)
|
||||||
|
|
||||||
@ -25,8 +24,12 @@
|
|||||||
|
|
||||||
| Mod Loader | IL2CPP | Mono |
|
| Mod Loader | IL2CPP | Mono |
|
||||||
| ----------- | ------ | ---- |
|
| ----------- | ------ | ---- |
|
||||||
| [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.MelonLoader.Il2Cpp.zip) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.MelonLoader.Mono.zip) |
|
| [BepInEx](https://github.com/BepInEx/BepInEx) 6.X | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx.Il2Cpp.zip) | ❔* [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx6.Mono.zip) |
|
||||||
| [BepInEx](https://github.com/BepInEx/BepInEx) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx.Il2Cpp.zip) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx.Mono.zip) |
|
| [BepInEx](https://github.com/BepInEx/BepInEx) 5.X | ❌ n/a | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx5.Mono.zip) |
|
||||||
|
| [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) 0.3 | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.MelonLoader.Il2Cpp.zip) | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.MelonLoader.Mono.zip) |
|
||||||
|
| Standalone | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.Standalone.Il2Cpp.zip) | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.Standalone.Mono.zip) |
|
||||||
|
|
||||||
|
\* BepInEx 6.X Mono release may not work on all games yet.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@ -41,26 +44,44 @@
|
|||||||
* <b>Reflection Inspector</b>: Inspect Properties and Fields. Can also set primitive values and evaluate primitive methods.
|
* <b>Reflection Inspector</b>: Inspect Properties and Fields. Can also set primitive values and evaluate primitive methods.
|
||||||
* <b>Search</b>: Search for UnityEngine.Objects with various filters, or use the helpers for static Instances and Classes.
|
* <b>Search</b>: Search for UnityEngine.Objects with various filters, or use the helpers for static Instances and Classes.
|
||||||
* <b>C# Console</b>: Interactive console for evaluating C# methods on the fly, with some basic helpers.
|
* <b>C# Console</b>: Interactive console for evaluating C# methods on the fly, with some basic helpers.
|
||||||
* <b>Inspect-under-mouse</b>: Hover over an object with a collider and inspect it by clicking on it.
|
* <b>Inspect-under-mouse</b>: 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
|
## How to install
|
||||||
|
|
||||||
### BepInEx
|
### BepInEx
|
||||||
|
|
||||||
|
Note: For IL2CPP you should use [BepInEx 6 (Bleeding Edge)](https://builds.bepis.io/projects/bepinex_be), for Mono you should use [BepInEx 5](https://github.com/BepInEx/BepInEx/releases) (until Mono support stabilizes in BepInEx 6).
|
||||||
|
|
||||||
0. Install [BepInEx](https://github.com/BepInEx/BepInEx) for your game.
|
0. Install [BepInEx](https://github.com/BepInEx/BepInEx) for your game.
|
||||||
1. Download the UnityExplorer release for BepInEx IL2CPP or Mono above.
|
1. Download the UnityExplorer release for BepInEx IL2CPP or Mono above.
|
||||||
2. Take the `UnityExplorer.BIE.___.dll` file and put it in `[GameFolder]\BepInEx\plugins\`
|
2. Take the `UnityExplorer.BIE.___.dll` file and put it in `[GameFolder]\BepInEx\plugins\`
|
||||||
3. In IL2CPP, it is highly recommended to get the base Unity libs for the game's Unity version and put them in the `BepInEx\unhollowed\base\` folder.
|
3. In IL2CPP, it is highly recommended to get the base Unity libs for the game's Unity version and put them in the `BepInEx\unity-libs\` folder.
|
||||||
|
|
||||||
### MelonLoader
|
### MelonLoader
|
||||||
|
|
||||||
|
Note: You must use version 0.3 of MelonLoader or greater. Version 0.3 is currently in pre-release, so you must opt-in from your MelonLoader installer (enable alpha releases).
|
||||||
|
|
||||||
0. Install [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) for your game.
|
0. Install [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) for your game.
|
||||||
1. Download the UnityExplorer release for MelonLoader IL2CPP or Mono above.
|
1. Download the UnityExplorer release for MelonLoader IL2CPP or Mono above.
|
||||||
2. Take the contents of the release and put it in the `[GameFolder]\Mods\` folder. It should look like `[GameFolder]\Mods\UnityExplorer.ML.___.dll`
|
2. Take the contents of the release and put it in the `[GameFolder]\Mods\` folder. It should look like `[GameFolder]\Mods\UnityExplorer.ML.___.dll`
|
||||||
|
|
||||||
## Mod Config
|
### Standalone
|
||||||
|
|
||||||
You can access the settings via the "Options" page of the main menu, or directly from the config at `Mods\UnityExplorer\config.ini` (generated after first launch).
|
The standalone release is based on the BepInEx build, so it requires Harmony 2.0 (or HarmonyX) to function properly.
|
||||||
|
|
||||||
|
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 `ExplorerStandalone.CreateInstance();`
|
||||||
|
2. Optionally 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
|
||||||
|
|
||||||
|
You can change the settings via the "Options" page of the main menu, or directly from the config file (generated after first launch). The config file will be found either inside a "UnityExplorer" folder in the same directory as where you put the DLL file, or for BepInEx it will be at `BepInEx\config\UnityExplorer\`.
|
||||||
|
|
||||||
`Main Menu Toggle` (KeyCode)
|
`Main Menu Toggle` (KeyCode)
|
||||||
* Default: `F7`
|
* Default: `F7`
|
||||||
@ -78,23 +99,30 @@ You can access the settings via the "Options" page of the main menu, or directly
|
|||||||
`Default Output Path` (string)
|
`Default Output Path` (string)
|
||||||
* Default: `Mods\UnityExplorer`
|
* Default: `Mods\UnityExplorer`
|
||||||
* Where output is generated to, by default (for Texture PNG saving, etc).
|
* Where output is generated to, by default (for Texture PNG saving, etc).
|
||||||
* Currently this is not actually used for anything, but it will be soon.
|
|
||||||
|
|
||||||
`Log Unity Debug` (bool)
|
`Log Unity Debug` (bool)
|
||||||
* Default: `false`
|
* Default: `false`
|
||||||
* Listens for Unity `Debug.Log` messages and prints them to UnityExplorer's log.
|
* Listens for Unity `Debug.Log` messages and prints them to UnityExplorer's log.
|
||||||
|
|
||||||
|
`Hide on Startup` (bool)
|
||||||
|
* Default: `false`
|
||||||
|
* If true, UnityExplorer will be hidden when you start the game, you must open it via the keybind.
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
If you'd like to build this yourself, you will need to have installed BepInEx and/or MelonLoader for at least one Unity game. If you want to build all 4 versions, you will need at least one IL2CPP and one Mono game, with BepInEx and MelonLoader installed for both.
|
If you'd like to build this yourself, all you need to do is download this repository and build from Visual Studio. If you want to build for BepInEx or MelonLoader IL2CPP then you will need to install the mod loader for a game and set the directory in the `csproj` file.
|
||||||
|
|
||||||
|
For IL2CPP:
|
||||||
1. Install BepInEx or MelonLoader for your game.
|
1. Install BepInEx or MelonLoader for your game.
|
||||||
2. Open the `src\UnityExplorer.csproj` file in a text editor.
|
2. Open the `src\UnityExplorer.csproj` file in a text editor.
|
||||||
3. For IL2CPP builds, make sure you set `BIECppGameFolder` (for BepInEx) and/or `MLCppGameFolder` (for MelonLoader) so the project can locate the necessary references.
|
3. Set `BIECppGameFolder` (for BepInEx) and/or `MLCppGameFolder` (for MelonLoader) so the project can locate the necessary references.
|
||||||
4. Open the `src\UnityExplorer.sln` project.
|
4. For Standalone builds, you can either install BepInEx for the game to build, or just change the .csproj file and set the Unhollower reference manually.
|
||||||
5. Select `Solution 'UnityExplorer' (1 of 1 project)` in the Solution Explorer panel, and set the <b>Active config</b> property to the version you want to build, then build it.
|
|
||||||
5. The DLLs are built to the `Release\` folder in the root of the repository.
|
For all builds:
|
||||||
6. If ILRepack fails or is missing, use the NuGet package manager to re-install `ILRepack.Lib.MSBuild.Task`, then re-build.
|
1. Open the `src\UnityExplorer.sln` project.
|
||||||
|
2. Select `Solution 'UnityExplorer' (1 of 1 project)` in the Solution Explorer panel, and set the <b>Active config</b> property to the version you want to build, then build it.
|
||||||
|
3. The DLLs are built to the `Release\` folder in the root of the repository.
|
||||||
|
4. If ILRepack fails or is missing, use the NuGet package manager to re-install `ILRepack.Lib.MSBuild.Task`, then re-build.
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
|
BIN
lib/0Harmony.dll
BIN
lib/0Harmony.dll
Binary file not shown.
BIN
lib/BepInEx.Unity.dll
Normal file
BIN
lib/BepInEx.Unity.dll
Normal file
Binary file not shown.
BIN
lib/BepInEx.dll
BIN
lib/BepInEx.dll
Binary file not shown.
Binary file not shown.
BIN
lib/MelonLoader.dll
Normal file
BIN
lib/MelonLoader.dll
Normal file
Binary file not shown.
@ -32,7 +32,7 @@ namespace UnityExplorer.CSConsole
|
|||||||
private Text inputHighlightText;
|
private Text inputHighlightText;
|
||||||
|
|
||||||
private readonly CSharpLexer highlightLexer;
|
private readonly CSharpLexer highlightLexer;
|
||||||
private readonly StringBuilder sbHighlight;
|
//private readonly StringBuilder sbHighlight;
|
||||||
|
|
||||||
internal int m_lastCaretPos;
|
internal int m_lastCaretPos;
|
||||||
internal int m_fixCaretPos;
|
internal int m_fixCaretPos;
|
||||||
@ -68,7 +68,6 @@ The following helper methods are available:
|
|||||||
|
|
||||||
public CodeEditor()
|
public CodeEditor()
|
||||||
{
|
{
|
||||||
sbHighlight = new StringBuilder();
|
|
||||||
highlightLexer = new CSharpLexer();
|
highlightLexer = new CSharpLexer();
|
||||||
|
|
||||||
ConstructUI();
|
ConstructUI();
|
||||||
@ -76,8 +75,24 @@ The following helper methods are available:
|
|||||||
InputField.onValueChanged.AddListener((string s) => { OnInputChanged(s); });
|
InputField.onValueChanged.AddListener((string s) => { OnInputChanged(s); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static bool IsUserCopyPasting()
|
||||||
|
{
|
||||||
|
return (InputManager.GetKey(KeyCode.LeftControl) || InputManager.GetKey(KeyCode.RightControl))
|
||||||
|
&& InputManager.GetKeyDown(KeyCode.V);
|
||||||
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
|
if (s_copyPasteBuffer != null)
|
||||||
|
{
|
||||||
|
if (!IsUserCopyPasting())
|
||||||
|
{
|
||||||
|
OnInputChanged(s_copyPasteBuffer);
|
||||||
|
|
||||||
|
s_copyPasteBuffer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (EnableCtrlRShortcut)
|
if (EnableCtrlRShortcut)
|
||||||
{
|
{
|
||||||
if ((InputManager.GetKey(KeyCode.LeftControl) || InputManager.GetKey(KeyCode.RightControl))
|
if ((InputManager.GetKey(KeyCode.LeftControl) || InputManager.GetKey(KeyCode.RightControl))
|
||||||
@ -149,11 +164,18 @@ The following helper methods are available:
|
|||||||
AutoCompleter.ClearAutocompletes();
|
AutoCompleter.ClearAutocompletes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnInputChanged(string newInput, bool forceUpdate = false)
|
internal static string s_copyPasteBuffer;
|
||||||
{
|
|
||||||
string newText = newInput;
|
|
||||||
|
|
||||||
UpdateIndent(newInput);
|
public void OnInputChanged(string newText, bool forceUpdate = false)
|
||||||
|
{
|
||||||
|
if (IsUserCopyPasting())
|
||||||
|
{
|
||||||
|
//Console.WriteLine("Copy+Paste detected!");
|
||||||
|
s_copyPasteBuffer = newText;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateIndent(newText);
|
||||||
|
|
||||||
if (!forceUpdate && string.IsNullOrEmpty(newText))
|
if (!forceUpdate && string.IsNullOrEmpty(newText))
|
||||||
inputHighlightText.text = string.Empty;
|
inputHighlightText.text = string.Empty;
|
||||||
@ -203,35 +225,29 @@ The following helper methods are available:
|
|||||||
{
|
{
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
sbHighlight.Length = 0;
|
//Console.WriteLine("Highlighting input text:\r\n" + inputText);
|
||||||
|
|
||||||
|
string ret = "";
|
||||||
|
|
||||||
foreach (LexerMatchInfo match in highlightLexer.GetMatches(inputText))
|
foreach (LexerMatchInfo match in highlightLexer.GetMatches(inputText))
|
||||||
{
|
{
|
||||||
for (int i = offset; i < match.startIndex; i++)
|
for (int i = offset; i < match.startIndex; i++)
|
||||||
{
|
ret += inputText[i];
|
||||||
sbHighlight.Append(inputText[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
sbHighlight.Append($"{match.htmlColor}");
|
ret += $"{match.htmlColor}";
|
||||||
|
|
||||||
for (int i = match.startIndex; i < match.endIndex; i++)
|
for (int i = match.startIndex; i < match.endIndex; i++)
|
||||||
{
|
ret += inputText[i];
|
||||||
sbHighlight.Append(inputText[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
sbHighlight.Append(CLOSE_COLOR_TAG);
|
ret += CLOSE_COLOR_TAG;
|
||||||
|
|
||||||
offset = match.endIndex;
|
offset = match.endIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = offset; i < inputText.Length; i++)
|
for (int i = offset; i < inputText.Length; i++)
|
||||||
{
|
ret += inputText[i];
|
||||||
sbHighlight.Append(inputText[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
inputText = sbHighlight.ToString();
|
return ret;
|
||||||
|
|
||||||
return inputText;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AutoIndentCaret()
|
private void AutoIndentCaret()
|
||||||
|
@ -6,14 +6,14 @@ using IniParser.Parser;
|
|||||||
|
|
||||||
namespace UnityExplorer.Config
|
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 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 = "#";
|
_parser.Configuration.CommentString = "#";
|
||||||
}
|
}
|
||||||
@ -22,9 +22,10 @@ namespace UnityExplorer.Config
|
|||||||
public KeyCode Main_Menu_Toggle = KeyCode.F7;
|
public KeyCode Main_Menu_Toggle = KeyCode.F7;
|
||||||
public bool Force_Unlock_Mouse = true;
|
public bool Force_Unlock_Mouse = true;
|
||||||
public int Default_Page_Limit = 25;
|
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 Log_Unity_Debug = false;
|
||||||
public bool Save_Logs_To_Disk = true;
|
public bool Hide_On_Startup = false;
|
||||||
|
//public bool Save_Logs_To_Disk = true;
|
||||||
|
|
||||||
public static event Action OnConfigChanged;
|
public static event Action OnConfigChanged;
|
||||||
|
|
||||||
@ -35,7 +36,7 @@ namespace UnityExplorer.Config
|
|||||||
|
|
||||||
public static void OnLoad()
|
public static void OnLoad()
|
||||||
{
|
{
|
||||||
Instance = new ModConfig();
|
Instance = new ExplorerConfig();
|
||||||
|
|
||||||
if (LoadSettings())
|
if (LoadSettings())
|
||||||
return;
|
return;
|
||||||
@ -56,24 +57,27 @@ namespace UnityExplorer.Config
|
|||||||
{
|
{
|
||||||
switch (config.KeyName)
|
switch (config.KeyName)
|
||||||
{
|
{
|
||||||
case "Main_Menu_Toggle":
|
case nameof(Main_Menu_Toggle):
|
||||||
Instance.Main_Menu_Toggle = (KeyCode)Enum.Parse(typeof(KeyCode), config.Value);
|
Instance.Main_Menu_Toggle = (KeyCode)Enum.Parse(typeof(KeyCode), config.Value);
|
||||||
break;
|
break;
|
||||||
case "Force_Unlock_Mouse":
|
case nameof(Force_Unlock_Mouse):
|
||||||
Instance.Force_Unlock_Mouse = bool.Parse(config.Value);
|
Instance.Force_Unlock_Mouse = bool.Parse(config.Value);
|
||||||
break;
|
break;
|
||||||
case "Default_Page_Limit":
|
case nameof(Default_Page_Limit):
|
||||||
Instance.Default_Page_Limit = int.Parse(config.Value);
|
Instance.Default_Page_Limit = int.Parse(config.Value);
|
||||||
break;
|
break;
|
||||||
case "Log_Unity_Debug":
|
case nameof(Log_Unity_Debug):
|
||||||
Instance.Log_Unity_Debug = bool.Parse(config.Value);
|
Instance.Log_Unity_Debug = bool.Parse(config.Value);
|
||||||
break;
|
break;
|
||||||
case "Save_Logs_To_Disk":
|
case nameof(Default_Output_Path):
|
||||||
Instance.Save_Logs_To_Disk = bool.Parse(config.Value);
|
|
||||||
break;
|
|
||||||
case "Default_Output_Path":
|
|
||||||
Instance.Default_Output_Path = config.Value;
|
Instance.Default_Output_Path = config.Value;
|
||||||
break;
|
break;
|
||||||
|
case nameof(Hide_On_Startup):
|
||||||
|
Instance.Hide_On_Startup = bool.Parse(config.Value);
|
||||||
|
break;
|
||||||
|
//case nameof(Save_Logs_To_Disk):
|
||||||
|
// Instance.Save_Logs_To_Disk = bool.Parse(config.Value);
|
||||||
|
// break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,12 +91,16 @@ namespace UnityExplorer.Config
|
|||||||
data.Sections.AddSection("Config");
|
data.Sections.AddSection("Config");
|
||||||
|
|
||||||
var sec = data.Sections["Config"];
|
var sec = data.Sections["Config"];
|
||||||
sec.AddKey("Main_Menu_Toggle", Instance.Main_Menu_Toggle.ToString());
|
sec.AddKey(nameof(Main_Menu_Toggle), Instance.Main_Menu_Toggle.ToString());
|
||||||
sec.AddKey("Force_Unlock_Mouse", Instance.Force_Unlock_Mouse.ToString());
|
sec.AddKey(nameof(Force_Unlock_Mouse), Instance.Force_Unlock_Mouse.ToString());
|
||||||
sec.AddKey("Default_Page_Limit", Instance.Default_Page_Limit.ToString());
|
sec.AddKey(nameof(Default_Page_Limit), Instance.Default_Page_Limit.ToString());
|
||||||
sec.AddKey("Log_Unity_Debug", Instance.Log_Unity_Debug.ToString());
|
sec.AddKey(nameof(Log_Unity_Debug), Instance.Log_Unity_Debug.ToString());
|
||||||
sec.AddKey("Save_Logs_To_Disk", Instance.Save_Logs_To_Disk.ToString());
|
sec.AddKey(nameof(Default_Output_Path), Instance.Default_Output_Path);
|
||||||
sec.AddKey("Default_Output_Path", Instance.Default_Output_Path);
|
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());
|
File.WriteAllText(INI_PATH, data.ToString());
|
||||||
}
|
}
|
@ -1,42 +1,37 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
using UnityExplorer.Config;
|
using UnityExplorer.Config;
|
||||||
|
using UnityExplorer.Helpers;
|
||||||
using UnityExplorer.Input;
|
using UnityExplorer.Input;
|
||||||
using UnityExplorer.Inspectors;
|
using UnityExplorer.Inspectors;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityExplorer.UI.Modules;
|
using UnityExplorer.UI.Modules;
|
||||||
#if CPP
|
|
||||||
using UnityExplorer.Helpers;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace UnityExplorer
|
namespace UnityExplorer
|
||||||
{
|
{
|
||||||
public class ExplorerCore
|
public class ExplorerCore
|
||||||
{
|
{
|
||||||
public const string NAME = "UnityExplorer";
|
public const string NAME = "UnityExplorer";
|
||||||
public const string VERSION = "3.1.6";
|
public const string VERSION = "3.2.1";
|
||||||
public const string AUTHOR = "Sinai";
|
public const string AUTHOR = "Sinai";
|
||||||
public const string GUID = "com.sinai.unityexplorer";
|
public const string GUID = "com.sinai.unityexplorer";
|
||||||
|
|
||||||
#if ML
|
|
||||||
public const string EXPLORER_FOLDER = @"Mods\UnityExplorer";
|
|
||||||
#elif BIE
|
|
||||||
public static string EXPLORER_FOLDER = Path.Combine(BepInEx.Paths.ConfigPath, "UnityExplorer");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static ExplorerCore Instance { get; private set; }
|
public static ExplorerCore Instance { get; private set; }
|
||||||
|
|
||||||
public static bool ShowMenu
|
private static IExplorerLoader s_loader;
|
||||||
{
|
public static IExplorerLoader Loader => s_loader
|
||||||
get => s_showMenu;
|
#if ML
|
||||||
set => SetShowMenu(value);
|
?? (s_loader = ExplorerMelonMod.Instance);
|
||||||
}
|
#elif BIE
|
||||||
public static bool s_showMenu;
|
?? (s_loader = ExplorerBepInPlugin.Instance);
|
||||||
|
#elif STANDALONE
|
||||||
|
?? (s_loader = ExplorerStandalone.Instance);
|
||||||
|
#endif
|
||||||
|
|
||||||
private static bool s_doneUIInit;
|
public static string ExplorerFolder => Loader.ExplorerFolder;
|
||||||
private static float s_timeSinceStartup;
|
|
||||||
|
|
||||||
public ExplorerCore()
|
public ExplorerCore()
|
||||||
{
|
{
|
||||||
@ -52,56 +47,29 @@ namespace UnityExplorer
|
|||||||
ReflectionHelpers.TryLoadGameModules();
|
ReflectionHelpers.TryLoadGameModules();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!Directory.Exists(EXPLORER_FOLDER))
|
if (!Directory.Exists(ExplorerFolder))
|
||||||
Directory.CreateDirectory(EXPLORER_FOLDER);
|
Directory.CreateDirectory(ExplorerFolder);
|
||||||
|
|
||||||
ModConfig.OnLoad();
|
ExplorerConfig.OnLoad();
|
||||||
|
|
||||||
InputManager.Init();
|
InputManager.Init();
|
||||||
ForceUnlockCursor.Init();
|
ForceUnlockCursor.Init();
|
||||||
|
|
||||||
SetupEvents();
|
SetupEvents();
|
||||||
|
|
||||||
ShowMenu = true;
|
UIManager.ShowMenu = true;
|
||||||
|
|
||||||
Log($"{NAME} {VERSION} initialized.");
|
Log($"{NAME} {VERSION} initialized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Update()
|
public static void Update()
|
||||||
{
|
{
|
||||||
if (!s_doneUIInit)
|
UIManager.CheckUIInit();
|
||||||
CheckUIInit();
|
|
||||||
|
|
||||||
if (MouseInspector.Enabled)
|
if (MouseInspector.Enabled)
|
||||||
MouseInspector.UpdateInspect();
|
MouseInspector.UpdateInspect();
|
||||||
else
|
else
|
||||||
{
|
UIManager.Update();
|
||||||
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.");
|
|
||||||
// InspectorManager.Instance.Inspect(Tests.TestClass.Instance);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LogWarning($"Exception setting up UI: {e}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetupEvents()
|
private void SetupEvents()
|
||||||
@ -110,10 +78,14 @@ namespace UnityExplorer
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Application.add_logMessageReceived(new Action<string, string, LogType>(OnUnityLog));
|
Application.add_logMessageReceived(new Action<string, string, LogType>(OnUnityLog));
|
||||||
|
|
||||||
SceneManager.add_sceneLoaded(new Action<Scene, LoadSceneMode>((Scene a, LoadSceneMode b) => { OnSceneLoaded(); }));
|
SceneManager.add_sceneLoaded(new Action<Scene, LoadSceneMode>((Scene a, LoadSceneMode b) => { OnSceneLoaded(); }));
|
||||||
SceneManager.add_activeSceneChanged(new Action<Scene, Scene>((Scene a, Scene b) => { OnSceneLoaded(); }));
|
SceneManager.add_activeSceneChanged(new Action<Scene, Scene>((Scene a, Scene b) => { OnSceneLoaded(); }));
|
||||||
}
|
}
|
||||||
catch { }
|
catch
|
||||||
|
{
|
||||||
|
// exceptions here are non-fatal, just ignore.
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
Application.logMessageReceived += OnUnityLog;
|
Application.logMessageReceived += OnUnityLog;
|
||||||
SceneManager.sceneLoaded += (Scene a, LoadSceneMode b) => { OnSceneLoaded(); };
|
SceneManager.sceneLoaded += (Scene a, LoadSceneMode b) => { OnSceneLoaded(); };
|
||||||
@ -126,23 +98,6 @@ namespace UnityExplorer
|
|||||||
UIManager.OnSceneChange();
|
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)
|
private void OnUnityLog(string message, string stackTrace, LogType type)
|
||||||
{
|
{
|
||||||
if (!DebugConsole.LogUnity)
|
if (!DebugConsole.LogUnity)
|
||||||
@ -173,11 +128,7 @@ namespace UnityExplorer
|
|||||||
if (unity)
|
if (unity)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if ML
|
Loader.OnLogMessage(message);
|
||||||
MelonLoader.MelonLogger.Log(message?.ToString());
|
|
||||||
#else
|
|
||||||
ExplorerBepInPlugin.Logging?.LogMessage(message?.ToString());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LogWarning(object message, bool unity = false)
|
public static void LogWarning(object message, bool unity = false)
|
||||||
@ -187,11 +138,7 @@ namespace UnityExplorer
|
|||||||
if (unity)
|
if (unity)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if ML
|
Loader.OnLogWarning(message);
|
||||||
MelonLoader.MelonLogger.LogWarning(message?.ToString());
|
|
||||||
#else
|
|
||||||
ExplorerBepInPlugin.Logging?.LogWarning(message?.ToString());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LogError(object message, bool unity = false)
|
public static void LogError(object message, bool unity = false)
|
||||||
@ -201,22 +148,7 @@ namespace UnityExplorer
|
|||||||
if (unity)
|
if (unity)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if ML
|
Loader.OnLogError(message);
|
||||||
MelonLoader.MelonLogger.LogError(message?.ToString());
|
|
||||||
#else
|
|
||||||
ExplorerBepInPlugin.Logging?.LogError(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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 OnLevelWasLoaded(int level)
|
|
||||||
{
|
|
||||||
ExplorerCore.Instance.OnSceneLoaded();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -93,16 +93,38 @@ namespace UnityExplorer.Helpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CPP
|
#if CPP
|
||||||
private static readonly Dictionary<CppType, Type> Il2CppToMonoType = new Dictionary<CppType, Type>();
|
private static readonly Dictionary<string, Type> Il2CppToMonoType = new Dictionary<string, Type>();
|
||||||
|
|
||||||
public static Type GetMonoType(CppType cppType)
|
public static Type GetMonoType(CppType cppType)
|
||||||
{
|
{
|
||||||
if (Il2CppToMonoType.ContainsKey(cppType))
|
if (Il2CppToMonoType.ContainsKey(cppType.AssemblyQualifiedName))
|
||||||
return Il2CppToMonoType[cppType];
|
return Il2CppToMonoType[cppType.AssemblyQualifiedName];
|
||||||
|
|
||||||
var getType = Type.GetType(cppType.AssemblyQualifiedName);
|
var getType = Type.GetType(cppType.AssemblyQualifiedName);
|
||||||
Il2CppToMonoType.Add(cppType, getType);
|
|
||||||
return getType;
|
if (getType != null)
|
||||||
|
{
|
||||||
|
Il2CppToMonoType.Add(cppType.AssemblyQualifiedName, getType);
|
||||||
|
return getType;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string baseName = cppType.FullName;
|
||||||
|
string baseAssembly = cppType.Assembly.GetName().name;
|
||||||
|
|
||||||
|
Type unhollowedType = AppDomain.CurrentDomain
|
||||||
|
.GetAssemblies()
|
||||||
|
.FirstOrDefault(a => a.GetName().Name == baseAssembly)?
|
||||||
|
.TryGetTypes()
|
||||||
|
.FirstOrDefault(t =>
|
||||||
|
t.CustomAttributes.Any(ca
|
||||||
|
=> ca.AttributeType.Name == "ObfuscatedNameAttribute"
|
||||||
|
&& (string)ca.ConstructorArguments[0].Value == baseName));
|
||||||
|
|
||||||
|
Il2CppToMonoType.Add(cppType.AssemblyQualifiedName, unhollowedType);
|
||||||
|
|
||||||
|
return unhollowedType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Dictionary<Type, IntPtr> CppClassPointers = new Dictionary<Type, IntPtr>();
|
private static readonly Dictionary<Type, IntPtr> CppClassPointers = new Dictionary<Type, IntPtr>();
|
||||||
|
@ -38,7 +38,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Inspect(object obj)
|
public void Inspect(object obj, CacheObjectBase parentMember = null)
|
||||||
{
|
{
|
||||||
#if CPP
|
#if CPP
|
||||||
obj = obj.Il2CppCast(ReflectionHelpers.GetActualType(obj));
|
obj = obj.Il2CppCast(ReflectionHelpers.GetActualType(obj));
|
||||||
@ -76,6 +76,9 @@ namespace UnityExplorer.Inspectors
|
|||||||
else
|
else
|
||||||
inspector = new InstanceInspector(obj);
|
inspector = new InstanceInspector(obj);
|
||||||
|
|
||||||
|
if (inspector is ReflectionInspector ri)
|
||||||
|
ri.ParentMember = parentMember;
|
||||||
|
|
||||||
m_currentInspectors.Add(inspector);
|
m_currentInspectors.Add(inspector);
|
||||||
SetInspectorTab(inspector);
|
SetInspectorTab(inspector);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,9 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
var fi = MemInfo as FieldInfo;
|
var fi = MemInfo as FieldInfo;
|
||||||
fi.SetValue(fi.IsStatic ? null : DeclaringInstance, IValue.Value);
|
fi.SetValue(fi.IsStatic ? null : DeclaringInstance, IValue.Value);
|
||||||
|
|
||||||
|
if (this.ParentInspector?.ParentMember != null)
|
||||||
|
this.ParentInspector.ParentMember.SetValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
|
|
||||||
public override Type FallbackType { get; }
|
public override Type FallbackType { get; }
|
||||||
|
|
||||||
|
public ReflectionInspector ParentInspector { get; set; }
|
||||||
public MemberInfo MemInfo { get; set; }
|
public MemberInfo MemInfo { get; set; }
|
||||||
public Type DeclaringType { get; set; }
|
public Type DeclaringType { get; set; }
|
||||||
public object DeclaringInstance { get; set; }
|
public object DeclaringInstance { get; set; }
|
||||||
|
@ -63,6 +63,9 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance;
|
var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance;
|
||||||
|
|
||||||
pi.SetValue(target, IValue.Value, ParseArguments());
|
pi.SetValue(target, IValue.Value, ParseArguments());
|
||||||
|
|
||||||
|
if (this.ParentInspector?.ParentMember != null)
|
||||||
|
this.ParentInspector.ParentMember.SetValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
if (string.IsNullOrEmpty(name))
|
if (string.IsNullOrEmpty(name))
|
||||||
name = "untitled";
|
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;
|
inputField.text = savePath;
|
||||||
|
|
||||||
saveBtn.onClick.AddListener(() =>
|
saveBtn.onClick.AddListener(() =>
|
||||||
|
@ -59,7 +59,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
= new List<KeyValuePair<CachePaired, CachePaired>>();
|
= new List<KeyValuePair<CachePaired, CachePaired>>();
|
||||||
|
|
||||||
internal readonly KeyValuePair<CachePaired, CachePaired>[] m_displayedEntries
|
internal readonly KeyValuePair<CachePaired, CachePaired>[] m_displayedEntries
|
||||||
= new KeyValuePair<CachePaired, CachePaired>[ModConfig.Instance.Default_Page_Limit];
|
= new KeyValuePair<CachePaired, CachePaired>[ExplorerConfig.Instance.Default_Page_Limit];
|
||||||
|
|
||||||
internal bool m_recacheWanted = true;
|
internal bool m_recacheWanted = true;
|
||||||
|
|
||||||
|
@ -47,13 +47,34 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
|
|
||||||
var list = new List<KeyValuePair<int, string>>();
|
var list = new List<KeyValuePair<int, string>>();
|
||||||
var set = new HashSet<string>();
|
var set = new HashSet<string>();
|
||||||
|
|
||||||
foreach (var value in values)
|
foreach (var value in values)
|
||||||
{
|
{
|
||||||
var name = value.ToString();
|
var name = value.ToString();
|
||||||
|
|
||||||
if (set.Contains(name))
|
if (set.Contains(name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
set.Add(name);
|
set.Add(name);
|
||||||
list.Add(new KeyValuePair<int, string>((int)value, name));
|
|
||||||
|
var backingType = Enum.GetUnderlyingType(type);
|
||||||
|
int intValue;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// this approach is necessary, a simple '(int)value' is not sufficient.
|
||||||
|
|
||||||
|
var unbox = Convert.ChangeType(value, backingType);
|
||||||
|
|
||||||
|
intValue = (int)Convert.ChangeType(unbox, typeof(int));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
ExplorerCore.LogWarning("[InteractiveEnum] Could not Unbox underlying type " + backingType.Name + " from " + type.FullName);
|
||||||
|
ExplorerCore.Log(ex.ToString());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Add(new KeyValuePair<int, string>(intValue, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
s_enumNamesCache.Add(type, list.ToArray());
|
s_enumNamesCache.Add(type, list.ToArray());
|
||||||
|
@ -46,7 +46,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
internal readonly Type m_baseEntryType;
|
internal readonly Type m_baseEntryType;
|
||||||
|
|
||||||
internal readonly List<CacheEnumerated> m_entries = new List<CacheEnumerated>();
|
internal readonly List<CacheEnumerated> m_entries = new List<CacheEnumerated>();
|
||||||
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;
|
internal bool m_recacheWanted = true;
|
||||||
|
|
||||||
public override void OnValueUpdated()
|
public override void OnValueUpdated()
|
||||||
|
@ -176,6 +176,10 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
ConstructSubcontent();
|
ConstructSubcontent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal MethodInfo m_toStringMethod;
|
||||||
|
internal MethodInfo m_toStringFormatMethod;
|
||||||
|
internal bool m_gotToStringMethods;
|
||||||
|
|
||||||
public string GetDefaultLabel(bool updateType = true)
|
public string GetDefaultLabel(bool updateType = true)
|
||||||
{
|
{
|
||||||
var valueType = Value?.GetType() ?? this.FallbackType;
|
var valueType = Value?.GetType() ?? this.FallbackType;
|
||||||
@ -205,8 +209,29 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var toString = (string)valueType.GetMethod("ToString", new Type[0])?.Invoke(Value, null)
|
if (!m_gotToStringMethods)
|
||||||
?? Value.ToString();
|
{
|
||||||
|
m_gotToStringMethods = true;
|
||||||
|
|
||||||
|
m_toStringMethod = valueType.GetMethod("ToString", new Type[0]);
|
||||||
|
m_toStringFormatMethod = valueType.GetMethod("ToString", new Type[] { typeof(string) });
|
||||||
|
|
||||||
|
// test format method actually works
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_toStringFormatMethod.Invoke(Value, new object[] { "F3" });
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
m_toStringFormatMethod = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string toString;
|
||||||
|
if (m_toStringFormatMethod != null)
|
||||||
|
toString = (string)m_toStringFormatMethod.Invoke(Value, new object[] { "F3" });
|
||||||
|
else
|
||||||
|
toString = (string)m_toStringMethod.Invoke(Value, new object[0]);
|
||||||
|
|
||||||
var fullnametemp = valueType.ToString();
|
var fullnametemp = valueType.ToString();
|
||||||
if (fullnametemp.StartsWith("Il2CppSystem"))
|
if (fullnametemp.StartsWith("Il2CppSystem"))
|
||||||
@ -303,7 +328,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
void OnInspectClicked()
|
void OnInspectClicked()
|
||||||
{
|
{
|
||||||
if (!Value.IsNullOrDestroyed(false))
|
if (!Value.IsNullOrDestroyed(false))
|
||||||
InspectorManager.Instance.Inspect(this.Value);
|
InspectorManager.Instance.Inspect(this.Value, this.Owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_inspectButton.SetActive(false);
|
m_inspectButton.SetActive(false);
|
||||||
|
@ -43,6 +43,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
"Collider2D.Cast",
|
"Collider2D.Cast",
|
||||||
"Collider2D.Raycast",
|
"Collider2D.Raycast",
|
||||||
"Texture2D.SetPixelDataImpl",
|
"Texture2D.SetPixelDataImpl",
|
||||||
|
"Camera.CalculateProjectionMatrixFromPhysicalProperties",
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
private static readonly HashSet<string> bl_memberNameStartsWith = new HashSet<string>
|
private static readonly HashSet<string> bl_memberNameStartsWith = new HashSet<string>
|
||||||
@ -58,6 +59,8 @@ namespace UnityExplorer.Inspectors
|
|||||||
|
|
||||||
public override string TabLabel => m_targetTypeShortName;
|
public override string TabLabel => m_targetTypeShortName;
|
||||||
|
|
||||||
|
internal CacheObjectBase ParentMember { get; set; }
|
||||||
|
|
||||||
internal readonly Type m_targetType;
|
internal readonly Type m_targetType;
|
||||||
internal readonly string m_targetTypeShortName;
|
internal readonly string m_targetTypeShortName;
|
||||||
|
|
||||||
@ -66,7 +69,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
// filtered members based on current filters
|
// filtered members based on current filters
|
||||||
internal readonly List<CacheMember> m_membersFiltered = new List<CacheMember>();
|
internal readonly List<CacheMember> m_membersFiltered = new List<CacheMember>();
|
||||||
// actual shortlist of displayed members
|
// 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;
|
internal bool m_autoUpdate;
|
||||||
|
|
||||||
@ -170,11 +173,11 @@ namespace UnityExplorer.Inspectors
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var sig = GetSig(member);
|
||||||
|
|
||||||
//ExplorerCore.Log($"Trying to cache member {sig}...");
|
//ExplorerCore.Log($"Trying to cache member {sig}...");
|
||||||
//ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name);
|
//ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name);
|
||||||
|
|
||||||
var sig = GetSig(member);
|
|
||||||
|
|
||||||
var mi = member as MethodInfo;
|
var mi = member as MethodInfo;
|
||||||
var pi = member as PropertyInfo;
|
var pi = member as PropertyInfo;
|
||||||
var fi = member as FieldInfo;
|
var fi = member as FieldInfo;
|
||||||
@ -202,6 +205,8 @@ namespace UnityExplorer.Inspectors
|
|||||||
list.Add(new CacheProperty(pi, target, m_scrollContent));
|
list.Add(new CacheProperty(pi, target, m_scrollContent));
|
||||||
else
|
else
|
||||||
list.Add(new CacheField(fi, target, m_scrollContent));
|
list.Add(new CacheField(fi, target, m_scrollContent));
|
||||||
|
|
||||||
|
list.Last().ParentInspector = this;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -55,16 +55,15 @@ namespace UnityExplorer.Inspectors
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!m_dontDestroyObject)
|
if (!s_dontDestroyObject)
|
||||||
{
|
{
|
||||||
m_dontDestroyObject = new GameObject("DontDestroyMe");
|
s_dontDestroyObject = new GameObject("DontDestroyMe");
|
||||||
GameObject.DontDestroyOnLoad(m_dontDestroyObject);
|
GameObject.DontDestroyOnLoad(s_dontDestroyObject);
|
||||||
}
|
}
|
||||||
return m_dontDestroyObject;
|
return s_dontDestroyObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
internal static GameObject s_dontDestroyObject;
|
||||||
internal static GameObject m_dontDestroyObject;
|
|
||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
@ -97,22 +96,6 @@ namespace UnityExplorer.Inspectors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if CPP
|
|
||||||
// public int GetSceneHandle(string sceneName)
|
|
||||||
// {
|
|
||||||
// if (sceneName == "DontDestroyOnLoad")
|
|
||||||
// return DontDestroyScene;
|
|
||||||
|
|
||||||
// for (int i = 0; i < SceneManager.sceneCount; i++)
|
|
||||||
// {
|
|
||||||
// var scene = SceneManager.GetSceneAt(i);
|
|
||||||
// if (scene.name == sceneName)
|
|
||||||
// return scene.handle;
|
|
||||||
// }
|
|
||||||
// return -1;
|
|
||||||
// }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
internal void OnSceneChange()
|
internal void OnSceneChange()
|
||||||
{
|
{
|
||||||
m_sceneDropdown.OnCancel(null);
|
m_sceneDropdown.OnCancel(null);
|
||||||
@ -121,8 +104,13 @@ namespace UnityExplorer.Inspectors
|
|||||||
|
|
||||||
private void RefreshSceneSelector()
|
private void RefreshSceneSelector()
|
||||||
{
|
{
|
||||||
var names = new List<string>();
|
var newNames = new List<string>();
|
||||||
var scenes = new List<Scene>();
|
var newScenes = new List<Scene>();
|
||||||
|
|
||||||
|
if (m_currentScenes == null)
|
||||||
|
m_currentScenes = new Scene[0];
|
||||||
|
|
||||||
|
bool anyChange = SceneManager.sceneCount != m_currentScenes.Length - 1;
|
||||||
|
|
||||||
for (int i = 0; i < SceneManager.sceneCount; i++)
|
for (int i = 0; i < SceneManager.sceneCount; i++)
|
||||||
{
|
{
|
||||||
@ -131,33 +119,32 @@ namespace UnityExplorer.Inspectors
|
|||||||
if (scene == default)
|
if (scene == default)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
scenes.Add(scene);
|
if (!anyChange && !m_currentScenes.Any(it => it.GetHandle() == scene.GetHandle()))
|
||||||
names.Add(scene.name);
|
anyChange = true;
|
||||||
|
|
||||||
|
newScenes.Add(scene);
|
||||||
|
newNames.Add(scene.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
names.Add("DontDestroyOnLoad");
|
newNames.Add("DontDestroyOnLoad");
|
||||||
scenes.Add(DontDestroyScene);
|
newScenes.Add(DontDestroyScene);
|
||||||
|
|
||||||
m_sceneDropdown.options.Clear();
|
m_sceneDropdown.options.Clear();
|
||||||
|
|
||||||
foreach (string scene in names)
|
foreach (string scene in newNames)
|
||||||
{
|
{
|
||||||
m_sceneDropdown.options.Add(new Dropdown.OptionData { text = scene });
|
m_sceneDropdown.options.Add(new Dropdown.OptionData { text = scene });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!names.Contains(m_sceneDropdownText.text))
|
if (anyChange)
|
||||||
{
|
{
|
||||||
m_sceneDropdownText.text = names[0];
|
m_sceneDropdownText.text = newNames[0];
|
||||||
SetTargetScene(scenes[0]);
|
SetTargetScene(newScenes[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentScenes = scenes.ToArray();
|
m_currentScenes = newScenes.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if CPP
|
|
||||||
// public void SetTargetScene(string name) => SetTargetScene(scene.handle);
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
public void SetTargetScene(Scene scene)
|
public void SetTargetScene(Scene scene)
|
||||||
{
|
{
|
||||||
if (scene == default)
|
if (scene == default)
|
||||||
@ -167,7 +154,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
#if CPP
|
#if CPP
|
||||||
GameObject[] rootObjs = SceneUnstrip.GetRootGameObjects(scene.handle);
|
GameObject[] rootObjs = SceneUnstrip.GetRootGameObjects(scene.handle);
|
||||||
#else
|
#else
|
||||||
GameObject[] rootObjs = SceneUnstrip.GetRootGameObjects(scene);
|
GameObject[] rootObjs = scene.GetRootGameObjects();
|
||||||
#endif
|
#endif
|
||||||
SetSceneObjectList(rootObjs);
|
SetSceneObjectList(rootObjs);
|
||||||
|
|
||||||
|
41
src/Loader/ExplorerBepIn5Plugin.cs
Normal file
41
src/Loader/ExplorerBepIn5Plugin.cs
Normal file
@ -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<object> OnLogMessage => (object log) => { Logging?.LogMessage(log?.ToString() ?? ""); };
|
||||||
|
public Action<object> OnLogWarning => (object log) => { Logging?.LogWarning(log?.ToString() ?? ""); };
|
||||||
|
public Action<object> OnLogError => (object log) => { Logging?.LogError(log?.ToString() ?? ""); };
|
||||||
|
|
||||||
|
internal void Awake()
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
|
||||||
|
new ExplorerCore();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Update()
|
||||||
|
{
|
||||||
|
ExplorerCore.Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -1,4 +1,4 @@
|
|||||||
#if BIE
|
#if BIE6
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@ -18,21 +18,27 @@ namespace UnityExplorer
|
|||||||
{
|
{
|
||||||
#if MONO
|
#if MONO
|
||||||
[BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)]
|
[BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)]
|
||||||
public class ExplorerBepInPlugin : BaseUnityPlugin
|
public class ExplorerBepInPlugin : BaseUnityPlugin, IExplorerLoader
|
||||||
{
|
{
|
||||||
public static ExplorerBepInPlugin Instance;
|
public static ExplorerBepInPlugin Instance;
|
||||||
|
|
||||||
public static ManualLogSource Logging => Instance?.Logger;
|
public static ManualLogSource Logging => Instance?.Logger;
|
||||||
|
|
||||||
public static readonly Harmony HarmonyInstance = new Harmony(ExplorerCore.GUID);
|
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<object> OnLogMessage => (object log) => { Logging?.LogMessage(log?.ToString() ?? ""); };
|
||||||
|
public Action<object> OnLogWarning => (object log) => { Logging?.LogWarning(log?.ToString() ?? ""); };
|
||||||
|
public Action<object> OnLogError => (object log) => { Logging?.LogError(log?.ToString() ?? ""); };
|
||||||
|
|
||||||
internal void Awake()
|
internal void Awake()
|
||||||
{
|
{
|
||||||
Instance = this;
|
Instance = this;
|
||||||
|
|
||||||
new ExplorerCore();
|
new ExplorerCore();
|
||||||
|
|
||||||
// HarmonyInstance.PatchAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Update()
|
internal void Update()
|
||||||
@ -44,13 +50,21 @@ namespace UnityExplorer
|
|||||||
|
|
||||||
#if CPP
|
#if CPP
|
||||||
[BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)]
|
[BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)]
|
||||||
public class ExplorerBepInPlugin : BasePlugin
|
public class ExplorerBepInPlugin : BasePlugin, IExplorerLoader
|
||||||
{
|
{
|
||||||
public static ExplorerBepInPlugin Instance;
|
public static ExplorerBepInPlugin Instance;
|
||||||
|
|
||||||
public static ManualLogSource Logging => Instance?.Log;
|
public static ManualLogSource Logging => Instance?.Log;
|
||||||
|
|
||||||
public static readonly Harmony HarmonyInstance = new Harmony(ExplorerCore.GUID);
|
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<object> OnLogMessage => (object log) => { Logging?.LogMessage(log?.ToString() ?? ""); };
|
||||||
|
public Action<object> OnLogWarning => (object log) => { Logging?.LogWarning(log?.ToString() ?? ""); };
|
||||||
|
public Action<object> OnLogError => (object log) => { Logging?.LogError(log?.ToString() ?? ""); };
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
public override void Load()
|
public override void Load()
|
||||||
@ -67,8 +81,6 @@ namespace UnityExplorer
|
|||||||
GameObject.DontDestroyOnLoad(obj);
|
GameObject.DontDestroyOnLoad(obj);
|
||||||
|
|
||||||
new ExplorerCore();
|
new ExplorerCore();
|
||||||
|
|
||||||
// HarmonyInstance.PatchAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BepInEx Il2Cpp mod class doesn't have monobehaviour methods yet, so wrap them in a dummy.
|
// BepInEx Il2Cpp mod class doesn't have monobehaviour methods yet, so wrap them in a dummy.
|
39
src/Loader/ExplorerMelonMod.cs
Normal file
39
src/Loader/ExplorerMelonMod.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#if ML
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using MelonLoader;
|
||||||
|
|
||||||
|
namespace UnityExplorer
|
||||||
|
{
|
||||||
|
public class ExplorerMelonMod : MelonMod, IExplorerLoader
|
||||||
|
{
|
||||||
|
public static ExplorerMelonMod Instance;
|
||||||
|
|
||||||
|
public string ExplorerFolder => Path.Combine("Mods", ExplorerCore.NAME);
|
||||||
|
public string ConfigFolder => ExplorerFolder;
|
||||||
|
|
||||||
|
public Action<object> OnLogMessage => (object log) => { MelonLogger.Msg(log?.ToString() ?? ""); };
|
||||||
|
public Action<object> OnLogWarning => (object log) => { MelonLogger.Warning(log?.ToString() ?? ""); };
|
||||||
|
public Action<object> OnLogError => (object log) => { MelonLogger.Error(log?.ToString() ?? ""); };
|
||||||
|
|
||||||
|
public Harmony.HarmonyInstance HarmonyInstance => Instance.Harmony;
|
||||||
|
|
||||||
|
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
|
105
src/Loader/ExplorerStandalone.cs
Normal file
105
src/Loader/ExplorerStandalone.cs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
#if STANDALONE
|
||||||
|
using HarmonyLib;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using UnityEngine;
|
||||||
|
#if CPP
|
||||||
|
using UnhollowerRuntimeLib;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace UnityExplorer
|
||||||
|
{
|
||||||
|
public class ExplorerStandalone : IExplorerLoader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Call this to initialize UnityExplorer. Optionally, also subscribe to the 'OnLog' event to handle logging.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The new (or active, if one exists) instance of ExplorerStandalone.</returns>
|
||||||
|
public static ExplorerStandalone CreateInstance()
|
||||||
|
{
|
||||||
|
if (Instance != null)
|
||||||
|
return Instance;
|
||||||
|
|
||||||
|
return new ExplorerStandalone();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExplorerStandalone()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExplorerStandalone Instance { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked whenever Explorer logs something. Subscribe to this to handle logging.
|
||||||
|
/// </summary>
|
||||||
|
public static event Action<string, LogType> OnLog;
|
||||||
|
|
||||||
|
public Harmony HarmonyInstance => s_harmony;
|
||||||
|
public static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID);
|
||||||
|
|
||||||
|
public string ExplorerFolder
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (s_explorerFolder == null)
|
||||||
|
{
|
||||||
|
s_explorerFolder =
|
||||||
|
Path.Combine(
|
||||||
|
Path.GetDirectoryName(
|
||||||
|
Uri.UnescapeDataString(new Uri(Assembly.GetExecutingAssembly().CodeBase)
|
||||||
|
.AbsolutePath)),
|
||||||
|
"UnityExplorer");
|
||||||
|
|
||||||
|
if (!Directory.Exists(s_explorerFolder))
|
||||||
|
Directory.CreateDirectory(s_explorerFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_explorerFolder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static string s_explorerFolder;
|
||||||
|
|
||||||
|
public string ConfigFolder => ExplorerFolder;
|
||||||
|
|
||||||
|
Action<object> IExplorerLoader.OnLogMessage => (object log) => { OnLog?.Invoke(log?.ToString() ?? "", LogType.Log); };
|
||||||
|
Action<object> IExplorerLoader.OnLogWarning => (object log) => { OnLog?.Invoke(log?.ToString() ?? "", LogType.Warning); };
|
||||||
|
Action<object> IExplorerLoader.OnLogError => (object log) => { OnLog?.Invoke(log?.ToString() ?? "", LogType.Error); };
|
||||||
|
|
||||||
|
private void Init()
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
#if CPP
|
||||||
|
ClassInjector.RegisterTypeInIl2Cpp<ExplorerBehaviour>();
|
||||||
|
|
||||||
|
var obj = new GameObject(
|
||||||
|
"ExplorerBehaviour",
|
||||||
|
new Il2CppSystem.Type[] { Il2CppType.Of<ExplorerBehaviour>() }
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
var obj = new GameObject(
|
||||||
|
"ExplorerBehaviour",
|
||||||
|
new Type[] { typeof(ExplorerBehaviour) }
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
obj.hideFlags = HideFlags.HideAndDontSave;
|
||||||
|
GameObject.DontDestroyOnLoad(obj);
|
||||||
|
|
||||||
|
new ExplorerCore();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ExplorerBehaviour : MonoBehaviour
|
||||||
|
{
|
||||||
|
#if CPP
|
||||||
|
public ExplorerBehaviour(IntPtr ptr) : base(ptr) { }
|
||||||
|
#endif
|
||||||
|
internal void Update()
|
||||||
|
{
|
||||||
|
ExplorerCore.Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
24
src/Loader/IExplorerLoader.cs
Normal file
24
src/Loader/IExplorerLoader.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace UnityExplorer
|
||||||
|
{
|
||||||
|
public interface IExplorerLoader
|
||||||
|
{
|
||||||
|
string ExplorerFolder { get; }
|
||||||
|
|
||||||
|
string ConfigFolder { get; }
|
||||||
|
|
||||||
|
Action<object> OnLogMessage { get; }
|
||||||
|
Action<object> OnLogWarning { get; }
|
||||||
|
Action<object> OnLogError { get; }
|
||||||
|
|
||||||
|
#if ML
|
||||||
|
Harmony.HarmonyInstance HarmonyInstance { get; }
|
||||||
|
#else
|
||||||
|
HarmonyLib.Harmony HarmonyInstance { get; }
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,14 @@ using UnityExplorer.Helpers;
|
|||||||
|
|
||||||
namespace UnityExplorer.Tests
|
namespace UnityExplorer.Tests
|
||||||
{
|
{
|
||||||
|
internal enum TestByteEnum : byte
|
||||||
|
{
|
||||||
|
One,
|
||||||
|
Two,
|
||||||
|
Three,
|
||||||
|
TwoFiftyFive = 255,
|
||||||
|
}
|
||||||
|
|
||||||
public static class StaticTestClass
|
public static class StaticTestClass
|
||||||
{
|
{
|
||||||
public static int StaticProperty => 5;
|
public static int StaticProperty => 5;
|
||||||
@ -28,6 +36,8 @@ namespace UnityExplorer.Tests
|
|||||||
|
|
||||||
public class TestClass
|
public class TestClass
|
||||||
{
|
{
|
||||||
|
internal static TestByteEnum testingByte = TestByteEnum.One;
|
||||||
|
|
||||||
public string AAALongString = @"1
|
public string AAALongString = @"1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
|
@ -28,7 +28,7 @@ namespace UnityExplorer.UI
|
|||||||
UpdateCursorControl();
|
UpdateCursorControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ShouldForceMouse => ExplorerCore.ShowMenu && Unlock;
|
public static bool ShouldForceMouse => UIManager.ShowMenu && Unlock;
|
||||||
|
|
||||||
private static CursorLockMode m_lastLockMode;
|
private static CursorLockMode m_lastLockMode;
|
||||||
private static bool m_lastVisibleState;
|
private static bool m_lastVisibleState;
|
||||||
@ -42,7 +42,7 @@ namespace UnityExplorer.UI
|
|||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
ModConfig.OnConfigChanged += ModConfig_OnConfigChanged;
|
ExplorerConfig.OnConfigChanged += ModConfig_OnConfigChanged;
|
||||||
|
|
||||||
SetupPatches();
|
SetupPatches();
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ namespace UnityExplorer.UI
|
|||||||
|
|
||||||
internal static void ModConfig_OnConfigChanged()
|
internal static void ModConfig_OnConfigChanged()
|
||||||
{
|
{
|
||||||
Unlock = ModConfig.Instance.Force_Unlock_Mouse;
|
Unlock = ExplorerConfig.Instance.Force_Unlock_Mouse;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetupPatches()
|
private static void SetupPatches()
|
||||||
@ -102,12 +102,7 @@ namespace UnityExplorer.UI
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var harmony =
|
var harmony = ExplorerCore.Loader.HarmonyInstance;
|
||||||
#if ML
|
|
||||||
ExplorerMelonMod.Instance.harmonyInstance;
|
|
||||||
#else
|
|
||||||
ExplorerBepInPlugin.HarmonyInstance;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
System.Reflection.PropertyInfo prop = type.GetProperty(property);
|
System.Reflection.PropertyInfo prop = type.GetProperty(property);
|
||||||
|
|
||||||
@ -206,7 +201,7 @@ namespace UnityExplorer.UI
|
|||||||
m_lastEventSystem = value;
|
m_lastEventSystem = value;
|
||||||
m_lastInputModule = value?.currentInputModule;
|
m_lastInputModule = value?.currentInputModule;
|
||||||
|
|
||||||
if (ExplorerCore.ShowMenu)
|
if (UIManager.ShowMenu)
|
||||||
{
|
{
|
||||||
value = UIManager.EventSys;
|
value = UIManager.EventSys;
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ namespace UnityExplorer.UI
|
|||||||
GameObject hideBtnObj = UIFactory.CreateButton(titleBar);
|
GameObject hideBtnObj = UIFactory.CreateButton(titleBar);
|
||||||
|
|
||||||
Button hideBtn = hideBtnObj.GetComponent<Button>();
|
Button hideBtn = hideBtnObj.GetComponent<Button>();
|
||||||
hideBtn.onClick.AddListener(() => { ExplorerCore.ShowMenu = false; });
|
hideBtn.onClick.AddListener(() => { UIManager.ShowMenu = false; });
|
||||||
ColorBlock colorBlock = hideBtn.colors;
|
ColorBlock colorBlock = hideBtn.colors;
|
||||||
colorBlock.normalColor = new Color(65f / 255f, 23f / 255f, 23f / 255f);
|
colorBlock.normalColor = new Color(65f / 255f, 23f / 255f, 23f / 255f);
|
||||||
colorBlock.pressedColor = new Color(35f / 255f, 10f / 255f, 10f / 255f);
|
colorBlock.pressedColor = new Color(35f / 255f, 10f / 255f, 10f / 255f);
|
||||||
@ -224,13 +224,13 @@ namespace UnityExplorer.UI
|
|||||||
hideText.resizeTextForBestFit = true;
|
hideText.resizeTextForBestFit = true;
|
||||||
hideText.resizeTextMinSize = 8;
|
hideText.resizeTextMinSize = 8;
|
||||||
hideText.resizeTextMaxSize = 14;
|
hideText.resizeTextMaxSize = 14;
|
||||||
hideText.text = $"Hide ({ModConfig.Instance.Main_Menu_Toggle})";
|
hideText.text = $"Hide ({ExplorerConfig.Instance.Main_Menu_Toggle})";
|
||||||
|
|
||||||
ModConfig.OnConfigChanged += ModConfig_OnConfigChanged;
|
ExplorerConfig.OnConfigChanged += ModConfig_OnConfigChanged;
|
||||||
|
|
||||||
void ModConfig_OnConfigChanged()
|
void ModConfig_OnConfigChanged()
|
||||||
{
|
{
|
||||||
hideText.text = $"Hide ({ModConfig.Instance.Main_Menu_Toggle})";
|
hideText.text = $"Hide ({ExplorerConfig.Instance.Main_Menu_Toggle})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ namespace UnityExplorer.UI.Modules
|
|||||||
{
|
{
|
||||||
public static DebugConsole Instance { get; private set; }
|
public static DebugConsole Instance { get; private set; }
|
||||||
|
|
||||||
public static bool LogUnity { get; set; } = ModConfig.Instance.Log_Unity_Debug;
|
public static bool LogUnity { get; set; } = ExplorerConfig.Instance.Log_Unity_Debug;
|
||||||
public static bool SaveToDisk { get; set; } = ModConfig.Instance.Save_Logs_To_Disk;
|
//public static bool SaveToDisk { get; set; } = ModConfig.Instance.Save_Logs_To_Disk;
|
||||||
|
|
||||||
internal static StreamWriter s_streamWriter;
|
internal static StreamWriter s_streamWriter;
|
||||||
|
|
||||||
@ -49,10 +49,10 @@ namespace UnityExplorer.UI.Modules
|
|||||||
|
|
||||||
// set up IO
|
// set up IO
|
||||||
|
|
||||||
if (!SaveToDisk)
|
//if (!SaveToDisk)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
var path = ExplorerCore.EXPLORER_FOLDER + @"\Logs";
|
var path = ExplorerCore.ExplorerFolder + @"\Logs";
|
||||||
|
|
||||||
if (!Directory.Exists(path))
|
if (!Directory.Exists(path))
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
@ -69,7 +69,7 @@ namespace UnityExplorer.UI.Modules
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fileName = "UnityExplorer " + DateTime.Now.ToString("u") + ".txt";
|
var fileName = "UnityExplorer " + DateTime.Now.ToString("u") + ".txt";
|
||||||
fileName = ExplorerCore.RemoveInvalidFilenameChars(fileName);
|
fileName = RemoveInvalidFilenameChars(fileName);
|
||||||
|
|
||||||
var stream = File.Create(path + @"\" + fileName);
|
var stream = File.Create(path + @"\" + fileName);
|
||||||
s_streamWriter = new StreamWriter(stream)
|
s_streamWriter = new StreamWriter(stream)
|
||||||
@ -81,6 +81,16 @@ namespace UnityExplorer.UI.Modules
|
|||||||
s_streamWriter.WriteLine(msg);
|
s_streamWriter.WriteLine(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string RemoveInvalidFilenameChars(string s)
|
||||||
|
{
|
||||||
|
var invalid = Path.GetInvalidFileNameChars();
|
||||||
|
foreach (var c in invalid)
|
||||||
|
{
|
||||||
|
s = s.Replace(c.ToString(), "");
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
public static void Log(string message)
|
public static void Log(string message)
|
||||||
{
|
{
|
||||||
Log(message, null);
|
Log(message, null);
|
||||||
@ -256,8 +266,8 @@ namespace UnityExplorer.UI.Modules
|
|||||||
void ToggleLogUnity(bool val)
|
void ToggleLogUnity(bool val)
|
||||||
{
|
{
|
||||||
LogUnity = val;
|
LogUnity = val;
|
||||||
ModConfig.Instance.Log_Unity_Debug = val;
|
ExplorerConfig.Instance.Log_Unity_Debug = val;
|
||||||
ModConfig.SaveSettings();
|
ExplorerConfig.SaveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
var unityToggleLayout = unityToggleObj.AddComponent<LayoutElement>();
|
var unityToggleLayout = unityToggleObj.AddComponent<LayoutElement>();
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
//using TMPro;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.Config;
|
using UnityExplorer.Config;
|
||||||
@ -19,6 +18,7 @@ namespace UnityExplorer.UI.Modules
|
|||||||
private Toggle m_unlockMouseToggle;
|
private Toggle m_unlockMouseToggle;
|
||||||
private InputField m_pageLimitInput;
|
private InputField m_pageLimitInput;
|
||||||
private InputField m_defaultOutputInput;
|
private InputField m_defaultOutputInput;
|
||||||
|
private Toggle m_hideOnStartupToggle;
|
||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
{
|
{
|
||||||
@ -27,29 +27,24 @@ namespace UnityExplorer.UI.Modules
|
|||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
// not needed?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OnApply()
|
internal void OnApply()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(m_keycodeInput.text) && Enum.Parse(typeof(KeyCode), m_keycodeInput.text) is KeyCode keyCode)
|
if (!string.IsNullOrEmpty(m_keycodeInput.text) && Enum.Parse(typeof(KeyCode), m_keycodeInput.text) is KeyCode keyCode)
|
||||||
{
|
ExplorerConfig.Instance.Main_Menu_Toggle = keyCode;
|
||||||
ModConfig.Instance.Main_Menu_Toggle = keyCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
ModConfig.Instance.Force_Unlock_Mouse = m_unlockMouseToggle.isOn;
|
ExplorerConfig.Instance.Force_Unlock_Mouse = m_unlockMouseToggle.isOn;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(m_pageLimitInput.text) && int.TryParse(m_pageLimitInput.text, out int lim))
|
if (!string.IsNullOrEmpty(m_pageLimitInput.text) && int.TryParse(m_pageLimitInput.text, out int lim))
|
||||||
{
|
ExplorerConfig.Instance.Default_Page_Limit = lim;
|
||||||
ModConfig.Instance.Default_Page_Limit = lim;
|
|
||||||
}
|
|
||||||
|
|
||||||
ModConfig.Instance.Default_Output_Path = m_defaultOutputInput.text;
|
ExplorerConfig.Instance.Default_Output_Path = m_defaultOutputInput.text;
|
||||||
|
|
||||||
// todo default output path
|
ExplorerConfig.Instance.Hide_On_Startup = m_hideOnStartupToggle.isOn;
|
||||||
|
|
||||||
ModConfig.SaveSettings();
|
ExplorerConfig.SaveSettings();
|
||||||
ModConfig.InvokeConfigChanged();
|
ExplorerConfig.InvokeConfigChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region UI CONSTRUCTION
|
#region UI CONSTRUCTION
|
||||||
@ -98,6 +93,7 @@ namespace UnityExplorer.UI.Modules
|
|||||||
ConstructMouseUnlockOpt(optionsGroupObj);
|
ConstructMouseUnlockOpt(optionsGroupObj);
|
||||||
ConstructPageLimitOpt(optionsGroupObj);
|
ConstructPageLimitOpt(optionsGroupObj);
|
||||||
ConstructOutputPathOpt(optionsGroupObj);
|
ConstructOutputPathOpt(optionsGroupObj);
|
||||||
|
ConstructHideOnStartupOpt(optionsGroupObj);
|
||||||
|
|
||||||
var applyBtnObj = UIFactory.CreateButton(Content, new Color(0.2f, 0.2f, 0.2f));
|
var applyBtnObj = UIFactory.CreateButton(Content, new Color(0.2f, 0.2f, 0.2f));
|
||||||
var applyText = applyBtnObj.GetComponentInChildren<Text>();
|
var applyText = applyBtnObj.GetComponentInChildren<Text>();
|
||||||
@ -113,10 +109,34 @@ namespace UnityExplorer.UI.Modules
|
|||||||
applyBtn.onClick.AddListener(OnApply);
|
applyBtn.onClick.AddListener(OnApply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ConstructHideOnStartupOpt(GameObject optionsGroupObj)
|
||||||
|
{
|
||||||
|
var rowObj = UIFactory.CreateHorizontalGroup(optionsGroupObj, new Color(1, 1, 1, 0));
|
||||||
|
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
|
||||||
|
rowGroup.childControlWidth = true;
|
||||||
|
rowGroup.childForceExpandWidth = false;
|
||||||
|
rowGroup.childControlHeight = true;
|
||||||
|
rowGroup.childForceExpandHeight = true;
|
||||||
|
var groupLayout = rowObj.AddComponent<LayoutElement>();
|
||||||
|
groupLayout.minHeight = 25;
|
||||||
|
groupLayout.flexibleHeight = 0;
|
||||||
|
groupLayout.minWidth = 200;
|
||||||
|
groupLayout.flexibleWidth = 1000;
|
||||||
|
|
||||||
|
var labelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
|
||||||
|
var labelText = labelObj.GetComponent<Text>();
|
||||||
|
labelText.text = "Hide UI on startup:";
|
||||||
|
var labelLayout = labelObj.AddComponent<LayoutElement>();
|
||||||
|
labelLayout.minWidth = 150;
|
||||||
|
labelLayout.minHeight = 25;
|
||||||
|
|
||||||
|
UIFactory.CreateToggle(rowObj, out m_hideOnStartupToggle, out Text toggleText);
|
||||||
|
m_hideOnStartupToggle.isOn = ExplorerConfig.Instance.Hide_On_Startup;
|
||||||
|
toggleText.text = "";
|
||||||
|
}
|
||||||
|
|
||||||
internal void ConstructKeycodeOpt(GameObject parent)
|
internal void ConstructKeycodeOpt(GameObject parent)
|
||||||
{
|
{
|
||||||
//public KeyCode Main_Menu_Toggle = KeyCode.F7;
|
|
||||||
|
|
||||||
var rowObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
|
var rowObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
|
||||||
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
|
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
|
||||||
rowGroup.childControlWidth = true;
|
rowGroup.childControlWidth = true;
|
||||||
@ -139,15 +159,13 @@ namespace UnityExplorer.UI.Modules
|
|||||||
var keycodeInputObj = UIFactory.CreateInputField(rowObj);
|
var keycodeInputObj = UIFactory.CreateInputField(rowObj);
|
||||||
|
|
||||||
m_keycodeInput = keycodeInputObj.GetComponent<InputField>();
|
m_keycodeInput = keycodeInputObj.GetComponent<InputField>();
|
||||||
m_keycodeInput.text = ModConfig.Instance.Main_Menu_Toggle.ToString();
|
m_keycodeInput.text = ExplorerConfig.Instance.Main_Menu_Toggle.ToString();
|
||||||
|
|
||||||
m_keycodeInput.placeholder.gameObject.GetComponent<Text>().text = "KeyCode, eg. F7";
|
m_keycodeInput.placeholder.gameObject.GetComponent<Text>().text = "KeyCode, eg. F7";
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ConstructMouseUnlockOpt(GameObject parent)
|
internal void ConstructMouseUnlockOpt(GameObject parent)
|
||||||
{
|
{
|
||||||
//public bool Force_Unlock_Mouse = true;
|
|
||||||
|
|
||||||
var rowObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
|
var rowObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
|
||||||
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
|
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
|
||||||
rowGroup.childControlWidth = true;
|
rowGroup.childControlWidth = true;
|
||||||
@ -168,7 +186,7 @@ namespace UnityExplorer.UI.Modules
|
|||||||
labelLayout.minHeight = 25;
|
labelLayout.minHeight = 25;
|
||||||
|
|
||||||
UIFactory.CreateToggle(rowObj, out m_unlockMouseToggle, out Text toggleText);
|
UIFactory.CreateToggle(rowObj, out m_unlockMouseToggle, out Text toggleText);
|
||||||
m_unlockMouseToggle.isOn = ModConfig.Instance.Force_Unlock_Mouse;
|
m_unlockMouseToggle.isOn = ExplorerConfig.Instance.Force_Unlock_Mouse;
|
||||||
toggleText.text = "";
|
toggleText.text = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +216,7 @@ namespace UnityExplorer.UI.Modules
|
|||||||
var inputObj = UIFactory.CreateInputField(rowObj);
|
var inputObj = UIFactory.CreateInputField(rowObj);
|
||||||
|
|
||||||
m_pageLimitInput = inputObj.GetComponent<InputField>();
|
m_pageLimitInput = inputObj.GetComponent<InputField>();
|
||||||
m_pageLimitInput.text = ModConfig.Instance.Default_Page_Limit.ToString();
|
m_pageLimitInput.text = ExplorerConfig.Instance.Default_Page_Limit.ToString();
|
||||||
|
|
||||||
m_pageLimitInput.placeholder.gameObject.GetComponent<Text>().text = "Integer, eg. 20";
|
m_pageLimitInput.placeholder.gameObject.GetComponent<Text>().text = "Integer, eg. 20";
|
||||||
}
|
}
|
||||||
@ -229,7 +247,7 @@ namespace UnityExplorer.UI.Modules
|
|||||||
var inputObj = UIFactory.CreateInputField(rowObj);
|
var inputObj = UIFactory.CreateInputField(rowObj);
|
||||||
|
|
||||||
m_defaultOutputInput = inputObj.GetComponent<InputField>();
|
m_defaultOutputInput = inputObj.GetComponent<InputField>();
|
||||||
m_defaultOutputInput.text = ModConfig.Instance.Default_Output_Path.ToString();
|
m_defaultOutputInput.text = ExplorerConfig.Instance.Default_Output_Path.ToString();
|
||||||
|
|
||||||
m_defaultOutputInput.placeholder.gameObject.GetComponent<Text>().text = @"Directory, eg. Mods\UnityExplorer";
|
m_defaultOutputInput.placeholder.gameObject.GetComponent<Text>().text = @"Directory, eg. Mods\UnityExplorer";
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ namespace UnityExplorer.UI.Modules
|
|||||||
{
|
{
|
||||||
var name = UISyntaxHighlight.ParseFullSyntax(obj.GetActualType(), true);
|
var name = UISyntaxHighlight.ParseFullSyntax(obj.GetActualType(), true);
|
||||||
|
|
||||||
if (unityObj && m_context != SearchContext.Singleton && m_context != SearchContext.StaticClass)
|
if (unityObj && m_context != SearchContext.Singleton)
|
||||||
{
|
{
|
||||||
if (unityObj && !string.IsNullOrEmpty(unityObj.name))
|
if (unityObj && !string.IsNullOrEmpty(unityObj.name))
|
||||||
name += $": {unityObj.name}";
|
name += $": {unityObj.name}";
|
||||||
@ -301,8 +301,8 @@ namespace UnityExplorer.UI.Modules
|
|||||||
|
|
||||||
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||||
{
|
{
|
||||||
// All non-static classes
|
// Search all non-static, non-enum classes.
|
||||||
foreach (var type in asm.TryGetTypes().Where(it => !it.IsSealed && !it.IsAbstract))
|
foreach (var type in asm.TryGetTypes().Where(it => !(it.IsSealed && it.IsAbstract) && !it.IsEnum))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -336,7 +336,7 @@ namespace UnityExplorer.UI.Modules
|
|||||||
if (instance != null)
|
if (instance != null)
|
||||||
{
|
{
|
||||||
instances.Add(instance);
|
instances.Add(instance);
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,8 @@ namespace UnityExplorer.UI.Shared
|
|||||||
this.sliderScroller = sliderScroller;
|
this.sliderScroller = sliderScroller;
|
||||||
this.inputField = inputField;
|
this.inputField = inputField;
|
||||||
|
|
||||||
|
sliderScroller.m_parentInputScroller = this;
|
||||||
|
|
||||||
inputField.onValueChanged.AddListener(OnTextChanged);
|
inputField.onValueChanged.AddListener(OnTextChanged);
|
||||||
|
|
||||||
inputRect = inputField.GetComponent<RectTransform>();
|
inputRect = inputField.GetComponent<RectTransform>();
|
||||||
@ -68,6 +70,17 @@ namespace UnityExplorer.UI.Shared
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal bool CheckDestroyed()
|
||||||
|
{
|
||||||
|
if (sliderScroller == null || sliderScroller.CheckDestroyed())
|
||||||
|
{
|
||||||
|
Instances.Remove(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
internal void OnTextChanged(string text)
|
internal void OnTextChanged(string text)
|
||||||
{
|
{
|
||||||
m_lastText = text;
|
m_lastText = text;
|
||||||
|
@ -21,7 +21,7 @@ namespace UnityExplorer.UI.Shared
|
|||||||
{
|
{
|
||||||
public PageHandler(SliderScrollbar scroll)
|
public PageHandler(SliderScrollbar scroll)
|
||||||
{
|
{
|
||||||
ItemsPerPage = ModConfig.Instance?.Default_Page_Limit ?? 20;
|
ItemsPerPage = ExplorerConfig.Instance?.Default_Page_Limit ?? 20;
|
||||||
m_scrollbar = scroll;
|
m_scrollbar = scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,150 +8,154 @@ using UnityExplorer;
|
|||||||
using UnityExplorer.Helpers;
|
using UnityExplorer.Helpers;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
|
|
||||||
// Basically just to fix an issue with Scrollbars, instead we use a Slider as the scrollbar.
|
namespace UnityExplorer.UI.Shared
|
||||||
public class SliderScrollbar
|
|
||||||
{
|
{
|
||||||
internal static readonly List<SliderScrollbar> Instances = new List<SliderScrollbar>();
|
// Basically just to fix an issue with Scrollbars, instead we use a Slider as the scrollbar.
|
||||||
|
public class SliderScrollbar
|
||||||
public bool IsActive { get; private set; }
|
|
||||||
|
|
||||||
internal readonly Scrollbar m_scrollbar;
|
|
||||||
internal readonly Slider m_slider;
|
|
||||||
internal readonly RectTransform m_scrollRect;
|
|
||||||
|
|
||||||
public SliderScrollbar(Scrollbar scrollbar, Slider slider)
|
|
||||||
{
|
{
|
||||||
Instances.Add(this);
|
internal static readonly List<SliderScrollbar> Instances = new List<SliderScrollbar>();
|
||||||
|
|
||||||
this.m_scrollbar = scrollbar;
|
public bool IsActive { get; private set; }
|
||||||
this.m_slider = slider;
|
|
||||||
this.m_scrollRect = scrollbar.transform.parent.GetComponent<RectTransform>();
|
|
||||||
|
|
||||||
this.m_scrollbar.onValueChanged.AddListener(this.OnScrollbarValueChanged);
|
internal readonly Scrollbar m_scrollbar;
|
||||||
this.m_slider.onValueChanged.AddListener(this.OnSliderValueChanged);
|
internal readonly Slider m_slider;
|
||||||
|
internal readonly RectTransform m_scrollRect;
|
||||||
|
|
||||||
this.RefreshVisibility();
|
internal InputFieldScroller m_parentInputScroller;
|
||||||
this.m_slider.Set(1f, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal bool CheckDestroyed()
|
public SliderScrollbar(Scrollbar scrollbar, Slider slider)
|
||||||
{
|
|
||||||
if (!m_slider || !m_scrollbar)
|
|
||||||
{
|
{
|
||||||
Instances.Remove(this);
|
Instances.Add(this);
|
||||||
return true;
|
|
||||||
|
this.m_scrollbar = scrollbar;
|
||||||
|
this.m_slider = slider;
|
||||||
|
this.m_scrollRect = scrollbar.transform.parent.GetComponent<RectTransform>();
|
||||||
|
|
||||||
|
this.m_scrollbar.onValueChanged.AddListener(this.OnScrollbarValueChanged);
|
||||||
|
this.m_slider.onValueChanged.AddListener(this.OnSliderValueChanged);
|
||||||
|
|
||||||
|
this.RefreshVisibility();
|
||||||
|
this.m_slider.Set(1f, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
internal bool CheckDestroyed()
|
||||||
}
|
|
||||||
|
|
||||||
internal void Update()
|
|
||||||
{
|
|
||||||
this.RefreshVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void RefreshVisibility()
|
|
||||||
{
|
|
||||||
if (!m_slider.gameObject.activeInHierarchy)
|
|
||||||
{
|
{
|
||||||
IsActive = false;
|
if (!m_slider || !m_scrollbar)
|
||||||
return;
|
{
|
||||||
|
Instances.Remove(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldShow = !Mathf.Approximately(this.m_scrollbar.size, 1);
|
internal void Update()
|
||||||
var obj = this.m_slider.handleRect.gameObject;
|
|
||||||
|
|
||||||
if (IsActive != shouldShow)
|
|
||||||
{
|
{
|
||||||
IsActive = shouldShow;
|
this.RefreshVisibility();
|
||||||
obj.SetActive(IsActive);
|
|
||||||
|
|
||||||
if (IsActive)
|
|
||||||
this.m_slider.Set(this.m_scrollbar.value, false);
|
|
||||||
else
|
|
||||||
m_slider.Set(1f, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void RefreshVisibility()
|
||||||
|
{
|
||||||
|
if (!m_slider.gameObject.activeInHierarchy)
|
||||||
|
{
|
||||||
|
IsActive = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool shouldShow = !Mathf.Approximately(this.m_scrollbar.size, 1);
|
||||||
|
var obj = this.m_slider.handleRect.gameObject;
|
||||||
|
|
||||||
|
if (IsActive != shouldShow)
|
||||||
|
{
|
||||||
|
IsActive = shouldShow;
|
||||||
|
obj.SetActive(IsActive);
|
||||||
|
|
||||||
|
if (IsActive)
|
||||||
|
this.m_slider.Set(this.m_scrollbar.value, false);
|
||||||
|
else
|
||||||
|
m_slider.Set(1f, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnScrollbarValueChanged(float _value)
|
||||||
|
{
|
||||||
|
if (this.m_slider.value != _value)
|
||||||
|
this.m_slider.Set(_value, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnSliderValueChanged(float _value)
|
||||||
|
{
|
||||||
|
this.m_scrollbar.value = _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region UI CONSTRUCTION
|
||||||
|
|
||||||
|
public static GameObject CreateSliderScrollbar(GameObject parent, out Slider slider)
|
||||||
|
{
|
||||||
|
GameObject sliderObj = UIFactory.CreateUIObject("Slider", parent, UIFactory.thinSize);
|
||||||
|
|
||||||
|
GameObject bgObj = UIFactory.CreateUIObject("Background", sliderObj);
|
||||||
|
GameObject fillAreaObj = UIFactory.CreateUIObject("Fill Area", sliderObj);
|
||||||
|
GameObject fillObj = UIFactory.CreateUIObject("Fill", fillAreaObj);
|
||||||
|
GameObject handleSlideAreaObj = UIFactory.CreateUIObject("Handle Slide Area", sliderObj);
|
||||||
|
GameObject handleObj = UIFactory.CreateUIObject("Handle", handleSlideAreaObj);
|
||||||
|
|
||||||
|
Image bgImage = bgObj.AddComponent<Image>();
|
||||||
|
bgImage.type = Image.Type.Sliced;
|
||||||
|
bgImage.color = new Color(0.05f, 0.05f, 0.05f, 1.0f);
|
||||||
|
|
||||||
|
RectTransform bgRect = bgObj.GetComponent<RectTransform>();
|
||||||
|
bgRect.anchorMin = Vector2.zero;
|
||||||
|
bgRect.anchorMax = Vector2.one;
|
||||||
|
bgRect.sizeDelta = Vector2.zero;
|
||||||
|
bgRect.offsetMax = new Vector2(-10f, 0f);
|
||||||
|
|
||||||
|
RectTransform fillAreaRect = fillAreaObj.GetComponent<RectTransform>();
|
||||||
|
fillAreaRect.anchorMin = new Vector2(0f, 0.25f);
|
||||||
|
fillAreaRect.anchorMax = new Vector2(1f, 0.75f);
|
||||||
|
fillAreaRect.anchoredPosition = new Vector2(-5f, 0f);
|
||||||
|
fillAreaRect.sizeDelta = new Vector2(-20f, 0f);
|
||||||
|
|
||||||
|
Image fillImage = fillObj.AddComponent<Image>();
|
||||||
|
fillImage.type = Image.Type.Sliced;
|
||||||
|
fillImage.color = Color.clear;
|
||||||
|
|
||||||
|
fillObj.GetComponent<RectTransform>().sizeDelta = new Vector2(10f, 0f);
|
||||||
|
|
||||||
|
RectTransform handleSlideRect = handleSlideAreaObj.GetComponent<RectTransform>();
|
||||||
|
handleSlideRect.anchorMin = new Vector2(0f, 0f);
|
||||||
|
handleSlideRect.anchorMax = new Vector2(1f, 1f);
|
||||||
|
handleSlideRect.offsetMin = new Vector2(15f, 30f);
|
||||||
|
handleSlideRect.offsetMax = new Vector2(-15f, 0f);
|
||||||
|
handleSlideRect.sizeDelta = new Vector2(-30f, -30f);
|
||||||
|
|
||||||
|
Image handleImage = handleObj.AddComponent<Image>();
|
||||||
|
handleImage.color = new Color(0.5f, 0.5f, 0.5f, 1.0f);
|
||||||
|
|
||||||
|
var handleRect = handleObj.GetComponent<RectTransform>();
|
||||||
|
handleRect.sizeDelta = new Vector2(15f, 30f);
|
||||||
|
handleRect.offsetMin = new Vector2(-13f, -28f);
|
||||||
|
handleRect.offsetMax = new Vector2(3f, -2f);
|
||||||
|
|
||||||
|
var sliderBarLayout = sliderObj.AddComponent<LayoutElement>();
|
||||||
|
sliderBarLayout.minWidth = 25;
|
||||||
|
sliderBarLayout.flexibleWidth = 0;
|
||||||
|
sliderBarLayout.minHeight = 30;
|
||||||
|
sliderBarLayout.flexibleHeight = 5000;
|
||||||
|
|
||||||
|
slider = sliderObj.AddComponent<Slider>();
|
||||||
|
slider.fillRect = fillObj.GetComponent<RectTransform>();
|
||||||
|
slider.handleRect = handleObj.GetComponent<RectTransform>();
|
||||||
|
slider.targetGraphic = handleImage;
|
||||||
|
slider.direction = Slider.Direction.BottomToTop;
|
||||||
|
UIFactory.SetDefaultColorTransitionValues(slider);
|
||||||
|
|
||||||
|
return sliderObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnScrollbarValueChanged(float _value)
|
|
||||||
{
|
|
||||||
if (this.m_slider.value != _value)
|
|
||||||
this.m_slider.Set(_value, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnSliderValueChanged(float _value)
|
|
||||||
{
|
|
||||||
this.m_scrollbar.value = _value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region UI CONSTRUCTION
|
|
||||||
|
|
||||||
public static GameObject CreateSliderScrollbar(GameObject parent, out Slider slider)
|
|
||||||
{
|
|
||||||
GameObject sliderObj = UIFactory.CreateUIObject("Slider", parent, UIFactory.thinSize);
|
|
||||||
|
|
||||||
GameObject bgObj = UIFactory.CreateUIObject("Background", sliderObj);
|
|
||||||
GameObject fillAreaObj = UIFactory.CreateUIObject("Fill Area", sliderObj);
|
|
||||||
GameObject fillObj = UIFactory.CreateUIObject("Fill", fillAreaObj);
|
|
||||||
GameObject handleSlideAreaObj = UIFactory.CreateUIObject("Handle Slide Area", sliderObj);
|
|
||||||
GameObject handleObj = UIFactory.CreateUIObject("Handle", handleSlideAreaObj);
|
|
||||||
|
|
||||||
Image bgImage = bgObj.AddComponent<Image>();
|
|
||||||
bgImage.type = Image.Type.Sliced;
|
|
||||||
bgImage.color = new Color(0.05f, 0.05f, 0.05f, 1.0f);
|
|
||||||
|
|
||||||
RectTransform bgRect = bgObj.GetComponent<RectTransform>();
|
|
||||||
bgRect.anchorMin = Vector2.zero;
|
|
||||||
bgRect.anchorMax = Vector2.one;
|
|
||||||
bgRect.sizeDelta = Vector2.zero;
|
|
||||||
bgRect.offsetMax = new Vector2(-10f, 0f);
|
|
||||||
|
|
||||||
RectTransform fillAreaRect = fillAreaObj.GetComponent<RectTransform>();
|
|
||||||
fillAreaRect.anchorMin = new Vector2(0f, 0.25f);
|
|
||||||
fillAreaRect.anchorMax = new Vector2(1f, 0.75f);
|
|
||||||
fillAreaRect.anchoredPosition = new Vector2(-5f, 0f);
|
|
||||||
fillAreaRect.sizeDelta = new Vector2(-20f, 0f);
|
|
||||||
|
|
||||||
Image fillImage = fillObj.AddComponent<Image>();
|
|
||||||
fillImage.type = Image.Type.Sliced;
|
|
||||||
fillImage.color = Color.clear;
|
|
||||||
|
|
||||||
fillObj.GetComponent<RectTransform>().sizeDelta = new Vector2(10f, 0f);
|
|
||||||
|
|
||||||
RectTransform handleSlideRect = handleSlideAreaObj.GetComponent<RectTransform>();
|
|
||||||
handleSlideRect.anchorMin = new Vector2(0f, 0f);
|
|
||||||
handleSlideRect.anchorMax = new Vector2(1f, 1f);
|
|
||||||
handleSlideRect.offsetMin = new Vector2(15f, 30f);
|
|
||||||
handleSlideRect.offsetMax = new Vector2(-15f, 0f);
|
|
||||||
handleSlideRect.sizeDelta = new Vector2(-30f, -30f);
|
|
||||||
|
|
||||||
Image handleImage = handleObj.AddComponent<Image>();
|
|
||||||
handleImage.color = new Color(0.5f, 0.5f, 0.5f, 1.0f);
|
|
||||||
|
|
||||||
var handleRect = handleObj.GetComponent<RectTransform>();
|
|
||||||
handleRect.sizeDelta = new Vector2(15f, 30f);
|
|
||||||
handleRect.offsetMin = new Vector2(-13f, -28f);
|
|
||||||
handleRect.offsetMax = new Vector2(3f, -2f);
|
|
||||||
|
|
||||||
var sliderBarLayout = sliderObj.AddComponent<LayoutElement>();
|
|
||||||
sliderBarLayout.minWidth = 25;
|
|
||||||
sliderBarLayout.flexibleWidth = 0;
|
|
||||||
sliderBarLayout.minHeight = 30;
|
|
||||||
sliderBarLayout.flexibleHeight = 5000;
|
|
||||||
|
|
||||||
slider = sliderObj.AddComponent<Slider>();
|
|
||||||
slider.fillRect = fillObj.GetComponent<RectTransform>();
|
|
||||||
slider.handleRect = handleObj.GetComponent<RectTransform>();
|
|
||||||
slider.targetGraphic = handleImage;
|
|
||||||
slider.direction = Slider.Direction.BottomToTop;
|
|
||||||
UIFactory.SetDefaultColorTransitionValues(slider);
|
|
||||||
|
|
||||||
return sliderObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
#if MONO
|
#if MONO
|
||||||
public static class SliderExtensions
|
public static class SliderExtensions
|
||||||
{
|
{
|
||||||
@ -175,4 +179,5 @@ public static class SliderExtensions
|
|||||||
SetMethod.Invoke(slider, new object[] { value, invokeCallback });
|
SetMethod.Invoke(slider, new object[] { value, invokeCallback });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
@ -8,6 +8,8 @@ using System.Reflection;
|
|||||||
using UnityExplorer.Helpers;
|
using UnityExplorer.Helpers;
|
||||||
using UnityExplorer.UI.Shared;
|
using UnityExplorer.UI.Shared;
|
||||||
using UnityExplorer.Input;
|
using UnityExplorer.Input;
|
||||||
|
using System;
|
||||||
|
using UnityExplorer.Config;
|
||||||
#if CPP
|
#if CPP
|
||||||
using UnityExplorer.Unstrip;
|
using UnityExplorer.Unstrip;
|
||||||
#endif
|
#endif
|
||||||
@ -24,6 +26,43 @@ namespace UnityExplorer.UI
|
|||||||
internal static Sprite ResizeCursor { get; private set; }
|
internal static Sprite ResizeCursor { get; private set; }
|
||||||
internal static Shader BackupShader { get; private set; }
|
internal static Shader BackupShader { get; private set; }
|
||||||
|
|
||||||
|
public static bool ShowMenu
|
||||||
|
{
|
||||||
|
get => s_showMenu;
|
||||||
|
set => SetShowMenu(value);
|
||||||
|
}
|
||||||
|
public static bool s_showMenu;
|
||||||
|
|
||||||
|
private static bool s_doneUIInit;
|
||||||
|
private static float s_timeSinceStartup;
|
||||||
|
|
||||||
|
internal static void CheckUIInit()
|
||||||
|
{
|
||||||
|
if (s_doneUIInit)
|
||||||
|
return;
|
||||||
|
|
||||||
|
s_timeSinceStartup += Time.deltaTime;
|
||||||
|
|
||||||
|
if (s_timeSinceStartup > 0.1f)
|
||||||
|
{
|
||||||
|
s_doneUIInit = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
ExplorerCore.Log("Initialized UnityExplorer UI.");
|
||||||
|
|
||||||
|
if (ExplorerConfig.Instance.Hide_On_Startup)
|
||||||
|
ShowMenu = false;
|
||||||
|
|
||||||
|
// InspectorManager.Instance.Inspect(Tests.TestClass.Instance);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
ExplorerCore.LogWarning($"Exception setting up UI: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
LoadBundle();
|
LoadBundle();
|
||||||
@ -40,13 +79,40 @@ namespace UnityExplorer.UI
|
|||||||
Canvas.ForceUpdateCanvases();
|
Canvas.ForceUpdateCanvases();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void SetShowMenu(bool show)
|
||||||
|
{
|
||||||
|
if (s_showMenu == show)
|
||||||
|
return;
|
||||||
|
|
||||||
|
s_showMenu = show;
|
||||||
|
|
||||||
|
if (CanvasRoot)
|
||||||
|
{
|
||||||
|
CanvasRoot.SetActive(show);
|
||||||
|
|
||||||
|
if (show)
|
||||||
|
ForceUnlockCursor.SetEventSystem();
|
||||||
|
else
|
||||||
|
ForceUnlockCursor.ReleaseEventSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
ForceUnlockCursor.UpdateCursorControl();
|
||||||
|
}
|
||||||
|
|
||||||
public static void OnSceneChange()
|
public static void OnSceneChange()
|
||||||
{
|
{
|
||||||
SceneExplorer.Instance?.OnSceneChange();
|
SceneExplorer.Instance?.OnSceneChange();
|
||||||
SearchPage.Instance?.OnSceneChange();
|
SearchPage.Instance?.OnSceneChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Update()
|
public static void Update()
|
||||||
{
|
{
|
||||||
|
if (InputManager.GetKeyDown(ExplorerConfig.Instance.Main_Menu_Toggle))
|
||||||
|
ShowMenu = !ShowMenu;
|
||||||
|
|
||||||
|
if (!ShowMenu || !s_doneUIInit || !CanvasRoot)
|
||||||
|
return;
|
||||||
|
|
||||||
MainMenu.Instance?.Update();
|
MainMenu.Instance?.Update();
|
||||||
|
|
||||||
if (EventSys)
|
if (EventSys)
|
||||||
@ -81,7 +147,7 @@ namespace UnityExplorer.UI
|
|||||||
{
|
{
|
||||||
var input = InputFieldScroller.Instances[i];
|
var input = InputFieldScroller.Instances[i];
|
||||||
|
|
||||||
if (input.sliderScroller.CheckDestroyed())
|
if (input.CheckDestroyed())
|
||||||
i--;
|
i--;
|
||||||
else
|
else
|
||||||
input.Update();
|
input.Update();
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<Deterministic>true</Deterministic>
|
<Deterministic>true</Deterministic>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
<OutputPath>..\Release\Explorer.MelonLoader.Il2Cpp\</OutputPath>
|
<OutputPath>..\Release\UnityExplorer.MelonLoader.Il2Cpp\</OutputPath>
|
||||||
<DefineConstants>
|
<DefineConstants>
|
||||||
</DefineConstants>
|
</DefineConstants>
|
||||||
<IsCpp>false</IsCpp>
|
<IsCpp>false</IsCpp>
|
||||||
@ -53,21 +53,50 @@
|
|||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Cpp|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Cpp|AnyCPU' ">
|
||||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
<OutputPath>..\Release\UnityExplorer.BepInEx.Il2Cpp\</OutputPath>
|
<OutputPath>..\Release\UnityExplorer.BepInEx.Il2Cpp\</OutputPath>
|
||||||
<DefineConstants>CPP,BIE</DefineConstants>
|
<DefineConstants>CPP,BIE,BIE6</DefineConstants>
|
||||||
<AssemblyName>UnityExplorer.BIE.IL2CPP</AssemblyName>
|
<AssemblyName>UnityExplorer.BIE.IL2CPP</AssemblyName>
|
||||||
<IsCpp>true</IsCpp>
|
<IsCpp>true</IsCpp>
|
||||||
<IsMelonLoader>false</IsMelonLoader>
|
<IsMelonLoader>false</IsMelonLoader>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Mono|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE6_Mono|AnyCPU' ">
|
||||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||||
<OutputPath>..\Release\UnityExplorer.BepInEx.Mono\</OutputPath>
|
<OutputPath>..\Release\UnityExplorer.BepInEx6.Mono\</OutputPath>
|
||||||
<DefineConstants>MONO,BIE</DefineConstants>
|
<DefineConstants>MONO,BIE,BIE6</DefineConstants>
|
||||||
<AssemblyName>UnityExplorer.BIE.Mono</AssemblyName>
|
<AssemblyName>UnityExplorer.BIE6.Mono</AssemblyName>
|
||||||
<IsCpp>false</IsCpp>
|
<IsCpp>false</IsCpp>
|
||||||
<IsMelonLoader>false</IsMelonLoader>
|
<IsMelonLoader>false</IsMelonLoader>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_BIE5_Mono|AnyCPU'">
|
||||||
|
<OutputPath>..\Release\UnityExplorer.BepInEx5.Mono\</OutputPath>
|
||||||
|
<DefineConstants>MONO,BIE,BIE5</DefineConstants>
|
||||||
|
<AssemblyName>UnityExplorer.BIE5.Mono</AssemblyName>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<LangVersion>7.3</LangVersion>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_STANDALONE_Mono|AnyCPU'">
|
||||||
|
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||||
|
<OutputPath>..\Release\UnityExplorer.Standalone.Mono\</OutputPath>
|
||||||
|
<DefineConstants>MONO,STANDALONE</DefineConstants>
|
||||||
|
<AssemblyName>UnityExplorer.STANDALONE.Mono</AssemblyName>
|
||||||
|
<IsCpp>false</IsCpp>
|
||||||
|
<IsMelonLoader>false</IsMelonLoader>
|
||||||
|
<IsStandalone>true</IsStandalone>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_STANDALONE_Cpp|AnyCPU'">
|
||||||
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
|
<OutputPath>..\Release\UnityExplorer.Standalone.Il2Cpp\</OutputPath>
|
||||||
|
<DefineConstants>CPP,STANDALONE</DefineConstants>
|
||||||
|
<AssemblyName>UnityExplorer.STANDALONE.IL2CPP</AssemblyName>
|
||||||
|
<IsCpp>true</IsCpp>
|
||||||
|
<IsMelonLoader>false</IsMelonLoader>
|
||||||
|
<IsStandalone>true</IsStandalone>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="INIFileParser, Version=2.5.2.0, Culture=neutral, PublicKeyToken=79af7b307b65cf3c, processorArchitecture=MSIL">
|
<Reference Include="INIFileParser, Version=2.5.2.0, Culture=neutral, PublicKeyToken=79af7b307b65cf3c, processorArchitecture=MSIL">
|
||||||
<HintPath>packages\ini-parser.2.5.2\lib\net20\INIFileParser.dll</HintPath>
|
<HintPath>packages\ini-parser.2.5.2\lib\net20\INIFileParser.dll</HintPath>
|
||||||
@ -98,13 +127,13 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- MelonLoader Mono refs -->
|
<!-- MelonLoader Mono refs -->
|
||||||
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='true|false'">
|
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='true|false'">
|
||||||
<Reference Include="MelonLoader.ModHandler">
|
<Reference Include="MelonLoader">
|
||||||
<HintPath>..\lib\MelonLoader.ModHandler.dll</HintPath>
|
<HintPath>..\lib\MelonLoader.dll</HintPath>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- BepInEx Mono refs -->
|
<!-- BepInEx 5 Mono refs -->
|
||||||
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='false|false'">
|
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)|$(Configuration)'=='false|false|Release_BIE5_Mono'">
|
||||||
<Reference Include="BepInEx">
|
<Reference Include="BepInEx">
|
||||||
<HintPath>..\lib\BepInEx.dll</HintPath>
|
<HintPath>..\lib\BepInEx.dll</HintPath>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
@ -114,10 +143,32 @@
|
|||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<!-- BepInEx 6 Mono refs -->
|
||||||
|
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)|$(Configuration)'=='false|false|Release_BIE6_Mono'">
|
||||||
|
<Reference Include="BepInEx">
|
||||||
|
<HintPath>..\lib\BepInEx.Core.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="BepInEx.Unity">
|
||||||
|
<HintPath>..\lib\BepInEx.Unity.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="0Harmony">
|
||||||
|
<HintPath>..\lib\0Harmony.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<!-- Standalone refs -->
|
||||||
|
<ItemGroup Condition="'$(IsStandalone)'=='true'">
|
||||||
|
<Reference Include="0Harmony">
|
||||||
|
<HintPath>..\lib\0Harmony.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
<!-- MelonLoader Il2Cpp refs -->
|
<!-- MelonLoader Il2Cpp refs -->
|
||||||
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='true|true'">
|
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='true|true'">
|
||||||
<Reference Include="MelonLoader.ModHandler">
|
<Reference Include="MelonLoader">
|
||||||
<HintPath>$(MLCppGameFolder)\MelonLoader\MelonLoader.ModHandler.dll</HintPath>
|
<HintPath>$(MLCppGameFolder)\MelonLoader\MelonLoader.dll</HintPath>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="UnhollowerBaseLib">
|
<Reference Include="UnhollowerBaseLib">
|
||||||
@ -217,6 +268,8 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Loader\ExplorerBepIn6Plugin.cs" />
|
||||||
|
<Compile Include="Loader\ExplorerStandalone.cs" />
|
||||||
<Compile Include="Helpers\EventHelper.cs" />
|
<Compile Include="Helpers\EventHelper.cs" />
|
||||||
<Compile Include="Inspectors\MouseInspector.cs" />
|
<Compile Include="Inspectors\MouseInspector.cs" />
|
||||||
<Compile Include="Inspectors\Reflection\CacheObject\CacheEnumerated.cs" />
|
<Compile Include="Inspectors\Reflection\CacheObject\CacheEnumerated.cs" />
|
||||||
@ -227,10 +280,10 @@
|
|||||||
<Compile Include="Inspectors\Reflection\CacheObject\CacheProperty.cs" />
|
<Compile Include="Inspectors\Reflection\CacheObject\CacheProperty.cs" />
|
||||||
<Compile Include="Inspectors\Reflection\CacheObject\CacheObjectBase.cs" />
|
<Compile Include="Inspectors\Reflection\CacheObject\CacheObjectBase.cs" />
|
||||||
<Compile Include="Helpers\Texture2DHelpers.cs" />
|
<Compile Include="Helpers\Texture2DHelpers.cs" />
|
||||||
<Compile Include="Config\ModConfig.cs" />
|
<Compile Include="Config\ExplorerConfig.cs" />
|
||||||
<Compile Include="ExplorerCore.cs" />
|
<Compile Include="ExplorerCore.cs" />
|
||||||
<Compile Include="ExplorerBepInPlugin.cs" />
|
<Compile Include="Loader\ExplorerBepIn5Plugin.cs" />
|
||||||
<Compile Include="ExplorerMelonMod.cs" />
|
<Compile Include="Loader\ExplorerMelonMod.cs" />
|
||||||
<Compile Include="Helpers\ReflectionHelpers.cs" />
|
<Compile Include="Helpers\ReflectionHelpers.cs" />
|
||||||
<Compile Include="Helpers\UnityHelpers.cs" />
|
<Compile Include="Helpers\UnityHelpers.cs" />
|
||||||
<Compile Include="Inspectors\GameObjects\ChildList.cs" />
|
<Compile Include="Inspectors\GameObjects\ChildList.cs" />
|
||||||
@ -244,6 +297,7 @@
|
|||||||
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveNumber.cs" />
|
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveNumber.cs" />
|
||||||
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveString.cs" />
|
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveString.cs" />
|
||||||
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveUnityStruct.cs" />
|
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveUnityStruct.cs" />
|
||||||
|
<Compile Include="Loader\IExplorerLoader.cs" />
|
||||||
<Compile Include="UI\ForceUnlockCursor.cs" />
|
<Compile Include="UI\ForceUnlockCursor.cs" />
|
||||||
<Compile Include="Input\IHandleInput.cs" />
|
<Compile Include="Input\IHandleInput.cs" />
|
||||||
<Compile Include="Tests\Tests.cs" />
|
<Compile Include="Tests\Tests.cs" />
|
||||||
|
@ -8,19 +8,28 @@ EndProject
|
|||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Release_BIE_Cpp|Any CPU = Release_BIE_Cpp|Any CPU
|
Release_BIE_Cpp|Any CPU = Release_BIE_Cpp|Any CPU
|
||||||
Release_BIE_Mono|Any CPU = Release_BIE_Mono|Any CPU
|
Release_BIE5_Mono|Any CPU = Release_BIE5_Mono|Any CPU
|
||||||
|
Release_BIE6_Mono|Any CPU = Release_BIE6_Mono|Any CPU
|
||||||
Release_ML_Cpp|Any CPU = Release_ML_Cpp|Any CPU
|
Release_ML_Cpp|Any CPU = Release_ML_Cpp|Any CPU
|
||||||
Release_ML_Mono|Any CPU = Release_ML_Mono|Any CPU
|
Release_ML_Mono|Any CPU = Release_ML_Mono|Any CPU
|
||||||
|
Release_STANDALONE_Cpp|Any CPU = Release_STANDALONE_Cpp|Any CPU
|
||||||
|
Release_STANDALONE_Mono|Any CPU = Release_STANDALONE_Mono|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_BIE_Cpp|Any CPU.ActiveCfg = Release_BIE_Cpp|Any CPU
|
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_BIE_Cpp|Any CPU.ActiveCfg = Release_BIE_Cpp|Any CPU
|
||||||
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_BIE_Cpp|Any CPU.Build.0 = Release_BIE_Cpp|Any CPU
|
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_BIE_Cpp|Any CPU.Build.0 = Release_BIE_Cpp|Any CPU
|
||||||
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_BIE_Mono|Any CPU.ActiveCfg = Release_BIE_Mono|Any CPU
|
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_BIE5_Mono|Any CPU.ActiveCfg = Release_BIE5_Mono|Any CPU
|
||||||
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_BIE_Mono|Any CPU.Build.0 = Release_BIE_Mono|Any CPU
|
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_BIE5_Mono|Any CPU.Build.0 = Release_BIE5_Mono|Any CPU
|
||||||
|
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_BIE6_Mono|Any CPU.ActiveCfg = Release_BIE6_Mono|Any CPU
|
||||||
|
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_BIE6_Mono|Any CPU.Build.0 = Release_BIE6_Mono|Any CPU
|
||||||
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_ML_Cpp|Any CPU.ActiveCfg = Release_ML_Cpp|Any CPU
|
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_ML_Cpp|Any CPU.ActiveCfg = Release_ML_Cpp|Any CPU
|
||||||
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_ML_Cpp|Any CPU.Build.0 = Release_ML_Cpp|Any CPU
|
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_ML_Cpp|Any CPU.Build.0 = Release_ML_Cpp|Any CPU
|
||||||
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_ML_Mono|Any CPU.ActiveCfg = Release_ML_Mono|Any CPU
|
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_ML_Mono|Any CPU.ActiveCfg = Release_ML_Mono|Any CPU
|
||||||
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_ML_Mono|Any CPU.Build.0 = Release_ML_Mono|Any CPU
|
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_ML_Mono|Any CPU.Build.0 = Release_ML_Mono|Any CPU
|
||||||
|
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_STANDALONE_Cpp|Any CPU.ActiveCfg = Release_STANDALONE_Cpp|Any CPU
|
||||||
|
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_STANDALONE_Cpp|Any CPU.Build.0 = Release_STANDALONE_Cpp|Any CPU
|
||||||
|
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_STANDALONE_Mono|Any CPU.ActiveCfg = Release_STANDALONE_Mono|Any CPU
|
||||||
|
{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_STANDALONE_Mono|Any CPU.Build.0 = Release_STANDALONE_Mono|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -3,36 +3,25 @@ using UnityExplorer.Helpers;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
using UnityExplorer.Inspectors;
|
using UnityExplorer.Inspectors;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace UnityExplorer.Unstrip
|
namespace UnityExplorer.Unstrip
|
||||||
{
|
{
|
||||||
public class SceneUnstrip
|
public static class SceneUnstrip
|
||||||
{
|
{
|
||||||
#if MONO
|
#if MONO
|
||||||
public static GameObject[] GetRootGameObjects(Scene scene) => scene.GetRootGameObjects();
|
private static readonly FieldInfo fi_Scene_handle = typeof(Scene).GetField("m_Handle", ReflectionHelpers.CommonFlags);
|
||||||
|
|
||||||
//public static GameObject[] GetRootGameObjects(int handle)
|
|
||||||
//{
|
|
||||||
// Scene scene = default;
|
|
||||||
// if (handle == SceneExplorer.DontDestroyHandle)
|
|
||||||
// scene = SceneExplorer.DontDestroyObject.scene;
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// for (int i = 0; i < SceneManager.sceneCount; i++)
|
|
||||||
// {
|
|
||||||
// var iscene = SceneManager.GetSceneAt(i);
|
|
||||||
// if (iscene.handle == handle)
|
|
||||||
// scene = iscene;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (scene != default && scene.handle != -1)
|
|
||||||
// return scene.GetRootGameObjects();
|
|
||||||
|
|
||||||
// return new GameObject[0];
|
|
||||||
//}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
public static int GetHandle(this Scene scene)
|
||||||
|
{
|
||||||
|
#if CPP
|
||||||
|
return scene.handle;
|
||||||
|
#else
|
||||||
|
return (int)fi_Scene_handle.GetValue(scene);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if CPP
|
#if CPP
|
||||||
//Scene.GetRootGameObjects();
|
//Scene.GetRootGameObjects();
|
||||||
|
|
||||||
@ -43,13 +32,16 @@ namespace UnityExplorer.Unstrip
|
|||||||
public static GameObject[] GetRootGameObjects(int handle)
|
public static GameObject[] GetRootGameObjects(int handle)
|
||||||
{
|
{
|
||||||
if (handle == -1)
|
if (handle == -1)
|
||||||
{
|
|
||||||
return new GameObject[0];
|
return new GameObject[0];
|
||||||
}
|
|
||||||
|
|
||||||
Il2CppSystem.Collections.Generic.List<GameObject> list = new Il2CppSystem.Collections.Generic.List<GameObject>(GetRootCount(handle));
|
int count = GetRootCount(handle);
|
||||||
|
|
||||||
d_GetRootGameObjects iCall = ICallHelper.GetICall<d_GetRootGameObjects>("UnityEngine.SceneManagement.Scene::GetRootGameObjectsInternal");
|
if (count < 1)
|
||||||
|
return new GameObject[0];
|
||||||
|
|
||||||
|
var list = new Il2CppSystem.Collections.Generic.List<GameObject>(count);
|
||||||
|
|
||||||
|
var iCall = ICallHelper.GetICall<d_GetRootGameObjects>("UnityEngine.SceneManagement.Scene::GetRootGameObjectsInternal");
|
||||||
|
|
||||||
iCall.Invoke(handle, list.Pointer);
|
iCall.Invoke(handle, list.Pointer);
|
||||||
|
|
||||||
@ -58,14 +50,14 @@ namespace UnityExplorer.Unstrip
|
|||||||
|
|
||||||
//Scene.rootCount;
|
//Scene.rootCount;
|
||||||
|
|
||||||
internal delegate int GetRootCountInternal_delegate(int handle);
|
internal delegate int d_GetRootCountInternal(int handle);
|
||||||
|
|
||||||
public static int GetRootCount(Scene scene) => GetRootCount(scene.handle);
|
public static int GetRootCount(Scene scene) => GetRootCount(scene.handle);
|
||||||
|
|
||||||
public static int GetRootCount(int handle)
|
public static int GetRootCount(int handle)
|
||||||
{
|
{
|
||||||
GetRootCountInternal_delegate iCall = ICallHelper.GetICall<GetRootCountInternal_delegate>("UnityEngine.SceneManagement.Scene::GetRootCountInternal");
|
return ICallHelper.GetICall<d_GetRootCountInternal>("UnityEngine.SceneManagement.Scene::GetRootCountInternal")
|
||||||
return iCall.Invoke(handle);
|
.Invoke(handle);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user