Compare commits

..

62 Commits

Author SHA1 Message Date
Sinai
1e1fb0e27b Merge branch 'master' of https://github.com/sinai-dev/UnityExplorer 2022-06-23 10:53:16 +10:00
Sinai
6b8a7d90c8 Update README.md 2022-06-23 10:53:14 +10:00
Sinai
1b4657dead
Update workflow for BepInEx CoreCLR build 2022-06-23 06:14:22 +10:00
Sinai
1af20ead9f Add BepInEx Il2CppInterop build 2022-06-23 06:03:58 +10:00
Sinai
706a18d1f6 Bump UniverseLib 2022-06-05 20:44:29 +10:00
Sinai
81dd8bad0e Update to C# 10.0, global usings 2022-05-26 06:19:50 +10:00
Sinai
97dffc81e1 Fix patch target on Time.timeScale 2022-05-19 00:07:12 +10:00
Sinai
bf2b22e768
Fix double zipped artifacts 2022-05-17 19:06:26 +10:00
Sinai
d1fbbfa62d Bump version 2022-05-15 19:12:00 +10:00
Sinai
56a3cef245 Add C# Console Assembly blacklist 2022-05-15 18:16:04 +10:00
Sinai
61e7915a55 Merge branch 'master' of https://github.com/sinai-dev/UnityExplorer 2022-05-14 01:55:13 +10:00
Sinai
88e63c8d6a Fix logic after changes in UniverseLib 2022-05-14 01:55:10 +10:00
Sinai
048e5980a0
Update README.md 2022-05-13 20:44:51 +10:00
Sinai
3b851b6e08 Use 7zip instead of Compress-Archive 2022-05-13 17:11:25 +10:00
Sinai
4c029dad90 Update TimeScaleWidget.cs 2022-05-11 22:49:28 +10:00
Sinai
3d61011e59 Move Time Scale Widget into separate class
And change "pause" to "lock" behaviour. Added patch to implement locking feature.
2022-05-10 01:44:08 +10:00
Sinai
5285239bc5 Update hooks list after edit save 2022-05-10 01:43:41 +10:00
Sinai
57d3a3f52e Fix UI Mouse Inspect hotkey not being implemented 2022-05-10 01:02:37 +10:00
Sinai
c88182c831 Bump version 2022-05-08 18:06:56 +10:00
Sinai
02e0102041 Merge branch 'master' of https://github.com/sinai-dev/UnityExplorer 2022-05-07 05:19:46 +10:00
Sinai
6adecef785 Fix generated patch code for static void methods
And always show the patch even if it failed to apply
2022-05-07 05:19:43 +10:00
Sinai
ff6c03e1f3
Update README.md 2022-05-06 15:46:49 +10:00
Sinai
1aedc505b2 Bump UniverseLib 2022-05-05 23:13:51 +10:00
Sinai
dbe993a7c7 Fix some casts for IL2CPP 2022-05-05 22:18:19 +10:00
Sinai
5a1676fb84 Update README.md 2022-05-05 19:56:29 +10:00
Sinai
a7a663aefa Prevent update overwriting input field changes 2022-05-05 19:53:02 +10:00
Sinai
76c77fb082 Add button to inspect scene of a GameObject 2022-05-05 19:52:25 +10:00
Sinai
a25017df69 Add wider Texture2DWidget support 2022-05-05 19:52:13 +10:00
Sinai
a1fab0c4a7 Add support for opening inspected Type in dnSpy 2022-05-05 19:50:52 +10:00
Sinai
4599747bfe Merge branch 'master' of https://github.com/sinai-dev/UnityExplorer 2022-05-05 02:45:43 +10:00
Sinai
3856e84c08 Bump version 2022-05-05 02:45:41 +10:00
Sinai
104288a912 Add support for Cubemaps in Texture2DWidget 2022-05-05 02:45:24 +10:00
Sinai
41e8a5ae33
Update README.md 2022-05-03 06:10:22 +10:00
Sinai
ef4bc75d5e Bump version 2022-04-30 20:53:31 +10:00
Sinai
68b81c6b53 Bump UniverseLib 2022-04-30 20:47:53 +10:00
Sinai
bd86f09313 Cleanup and refactor GameObjectControls
Split into proper classes, cleanup ugly code
2022-04-30 20:32:31 +10:00
Sinai
b35d6f5787 Cleanup 2022-04-30 20:31:33 +10:00
Sinai
b97eada516
Update README.md 2022-04-29 16:56:29 +10:00
Sinai
0a05848bef Implement control modifier to Home/End jump 2022-04-28 04:10:36 +10:00
Sinai
6e5610129a Add ILRepack back to build process 2022-04-27 20:13:17 +10:00
Sinai
acd30880a8 Bump UniverseLib 2022-04-27 03:04:28 +10:00
Sinai
f54ff89290 Bump UniverseLib 2022-04-25 22:52:24 +10:00
Sinai
62d565777d Bump UniverseLib and version 2022-04-25 19:39:44 +10:00
Sinai
870f82ab26 Fix Home jump when line is entirely whitespace 2022-04-25 05:48:13 +10:00
Sinai
9370c5e0e6 Fix jumpToTop and panel position behaviour 2022-04-25 05:47:57 +10:00
Sinai
b8cf96438c Correct a comment position 2022-04-24 19:38:17 +10:00
Sinai
7be7daf4d7 Bump version 2022-04-24 19:24:43 +10:00
Sinai
8f54415ae0 Remove small logic error with SymbolLexer 2022-04-24 19:23:05 +10:00
Sinai
aef4e11c01 C# Console: Implement Home and End keys 2022-04-24 19:13:43 +10:00
Sinai
af7e32ec49 Add a null check 2022-04-24 18:16:13 +10:00
Sinai
6f44a3376b Bump UniverseLib 2022-04-24 05:58:36 +10:00
Sinai
3a6b573ac3 Bump version 2022-04-24 05:57:29 +10:00
Sinai
cbe17927fb Ensure valid panel size after loading save data 2022-04-24 05:57:22 +10:00
Sinai
15f3f37948 Clean up all objects in editor 2022-04-24 05:56:47 +10:00
Sinai
de6760e427 Add more convenient editor config serialization 2022-04-24 05:56:36 +10:00
Sinai
83edd1b9bb Bump editor package 2022-04-24 02:12:57 +10:00
Sinai
613be34e95 Bump UniverseLib 2022-04-24 02:04:08 +10:00
Sinai
58c65b9b8b Make TypeCompleter asynchronous 2022-04-24 02:02:34 +10:00
Sinai
6fcf6a521c Bump version 2022-04-24 02:02:29 +10:00
Sinai
81a174f865 Remove call to obsolete methods 2022-04-24 01:59:53 +10:00
Sinai
b5e3cc2ea5 Use separate TypeCompleters for different contexts 2022-04-24 01:59:03 +10:00
Sinai
14f46ade6a Cancel pending generic when edit button pressed 2022-04-24 01:58:27 +10:00
125 changed files with 2310 additions and 1819 deletions

View File

@ -34,53 +34,59 @@ jobs:
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: UnityExplorer.BepInEx.IL2CPP.zip name: UnityExplorer.BepInEx.IL2CPP.zip
path: ./Release/UnityExplorer.BepInEx.IL2CPP.zip path: ./Release/UnityExplorer.BepInEx.IL2CPP/
# BepInEx IL2CPP CoreCLR
- uses: actions/upload-artifact@v2
with:
name: UnityExplorer.BepInEx.IL2CPP.CoreCLR.zip
path: ./Release/UnityExplorer.BepInEx.IL2CPP.CoreCLR/
# BepInEx 5 Mono # BepInEx 5 Mono
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: UnityExplorer.BepInEx5.Mono.zip name: UnityExplorer.BepInEx5.Mono.zip
path: ./Release/UnityExplorer.BepInEx5.Mono.zip path: ./Release/UnityExplorer.BepInEx5.Mono/
# BepInEx 6 Mono # BepInEx 6 Mono
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: UnityExplorer.BepInEx6.Mono.zip name: UnityExplorer.BepInEx6.Mono.zip
path: ./Release/UnityExplorer.BepInEx6.Mono.zip path: ./Release/UnityExplorer.BepInEx6.Mono/
# Editor # Editor
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: UnityExplorer.Editor.zip name: UnityExplorer.Editor.zip
path: ./Release/UnityExplorer.Editor.zip path: ./UnityEditorPackage/
# MelonLoader IL2CPP net6preview # MelonLoader IL2CPP net6preview
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: UnityExplorer.MelonLoader.IL2CPP.net6preview.zip name: UnityExplorer.MelonLoader.IL2CPP.net6preview.zip
path: ./Release/UnityExplorer.MelonLoader.IL2CPP.net6preview.zip path: ./Release/UnityExplorer.MelonLoader.IL2CPP.net6preview/
# MelonLoader IL2CPP net472 # MelonLoader IL2CPP net472
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: UnityExplorer.MelonLoader.IL2CPP.zip name: UnityExplorer.MelonLoader.IL2CPP.zip
path: ./Release/UnityExplorer.MelonLoader.IL2CPP.zip path: ./Release/UnityExplorer.MelonLoader.IL2CPP/
# MelonLoader Mono # MelonLoader Mono
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: UnityExplorer.MelonLoader.Mono.zip name: UnityExplorer.MelonLoader.Mono.zip
path: ./Release/UnityExplorer.MelonLoader.Mono.zip path: ./Release/UnityExplorer.MelonLoader.Mono/
# Standalone Il2Cpp # Standalone Il2Cpp
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: UnityExplorer.Standalone.IL2CPP.zip name: UnityExplorer.Standalone.IL2CPP.zip
path: ./Release/UnityExplorer.Standalone.IL2CPP.zip path: ./Release/UnityExplorer.Standalone.IL2CPP/
# Standalone Mono # Standalone Mono
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: UnityExplorer.Standalone.Mono.zip name: UnityExplorer.Standalone.Mono.zip
path: ./Release/UnityExplorer.Standalone.Mono.zip path: ./Release/UnityExplorer.Standalone.Mono/

View File

@ -18,11 +18,18 @@
⚡ Thunderstore releases: [BepInEx Mono](https://thunderstore.io/package/sinai-dev/UnityExplorer) | [BepInEx IL2CPP](https://gtfo.thunderstore.io/package/sinai-dev/UnityExplorer_IL2CPP) | [MelonLoader IL2CPP](https://boneworks.thunderstore.io/package/sinai-dev/UnityExplorer_IL2CPP_ML) ⚡ Thunderstore releases: [BepInEx Mono](https://thunderstore.io/package/sinai-dev/UnityExplorer) | [BepInEx IL2CPP](https://gtfo.thunderstore.io/package/sinai-dev/UnityExplorer_IL2CPP) | [MelonLoader IL2CPP](https://boneworks.thunderstore.io/package/sinai-dev/UnityExplorer_IL2CPP_ML)
## Release schedule
Releases will be posted at most once per week, generally on weekends.
Nightly builds can be found [here](https://github.com/sinai-dev/UnityExplorer/actions).
## BepInEx ## BepInEx
| Release | IL2CPP | Mono | | Release | IL2CPP | Mono |
| ------- | ------ | ---- | | ------- | ------ | ---- |
| BIE 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) | | BIE 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) |
| BIE 6.X (CoreCLR) | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx.IL2CPP.CoreCLR.zip) | ✖ |
| BIE 5.X | ✖️ n/a | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx5.Mono.zip) | | BIE 5.X | ✖️ n/a | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx5.Mono.zip) |
1. Unzip the release file into a folder 1. Unzip the release file into a folder
@ -32,10 +39,10 @@
## MelonLoader ## MelonLoader
| Release | IL2CPP | Mono | | Release | IL2CPP | Mono |
| ---------- | ------ | ---- | | ------- | ------ | ---- |
| ML 0.4/0.5 | ✅ [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) | | ML 0.5 | ✅ [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) |
| ML 0.6 | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.MelonLoader.IL2CPP.net6preview.zip) | ✖️ | | ML 0.6 | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.MelonLoader.IL2CPP.net6preview.zip) | ✖️ |
1. Unzip the release file into a folder 1. Unzip the release file into a folder
2. Copy the DLL inside the `Mods` folder into your MelonLoader `Mods` folder 2. Copy the DLL inside the `Mods` folder into your MelonLoader `Mods` folder
@ -84,6 +91,20 @@ If these fixes do not work, please create an issue in this repo and I'll do my b
</a> </a>
</p> </p>
### Inspector API
If you want to inspect an object or Type from outside the C# console, use the `InspectorManager` class:
**To inspect an object:**
```csharp
UnityExplorer.InspectorManager.Inspect(theObject);
```
**To inspect a Type:**
```cs
UnityExplorer.InspectorManager.Inspect(typeof(SomeClass));
```
### Object Explorer ### Object Explorer
* Use the <b>Scene Explorer</b> tab to traverse the active scenes, as well as the DontDestroyOnLoad and HideAndDontSave objects. * Use the <b>Scene Explorer</b> tab to traverse the active scenes, as well as the DontDestroyOnLoad and HideAndDontSave objects.
@ -104,7 +125,8 @@ The inspector is used to see detailed information on objects of any type and man
* Automatic updating is not enabled by default, and you must press Apply for any changes you make to take effect. * Automatic updating is not enabled by default, and you must press Apply for any changes you make to take effect.
* Press the `▼` button to expand certain values such as strings, enums, lists, dictionaries, some structs, etc * Press the `▼` button to expand certain values such as strings, enums, lists, dictionaries, some structs, etc
* Use the filters at the top to quickly find the members you are looking for * Use the filters at the top to quickly find the members you are looking for
* For `Texture2D` objects, there is a `View Texture` button at the top of the inspector which lets you view it and save it as a PNG file. Currently there are no other similar helpers yet, but I may add more at some point for Mesh, Sprite, Material, etc * For `Texture2D`, `Image`, `Sprite` and `Material` objects, there is a `View Texture` button at the top of the inspector which lets you view the Texture(s) and save them as a PNG file.
* For `AudioClip` objects there is a `Show Player` button which opens an audio player widget. For clips which are loaded as `DecompressOnLoad`, there is also a button to save them to a `.wav` file.
### C# Console ### C# Console

View File

@ -1,6 +1,6 @@
{ {
"name": "com.sinai-dev.unityexplorer", "name": "com.sinai-dev.unityexplorer",
"version": "4.7.3", "version": "4.7.12",
"displayName": "UnityExplorer", "displayName": "UnityExplorer",
"description": "An in-game UI for exploring, debugging and modifying Unity games.", "description": "An in-game UI for exploring, debugging and modifying Unity games.",
"unity": "2017.1", "unity": "2017.1",

194
build.ps1
View File

@ -1,97 +1,155 @@
# MelonLoader IL2CPP (net6) # ----------- MelonLoader IL2CPP (net6) -----------
dotnet build src\UnityExplorer.sln -c Release_ML_Cpp_net6 dotnet build src/UnityExplorer.sln -c Release_ML_Cpp_net6
# (cleanup and move files)
$Path = "Release\UnityExplorer.MelonLoader.IL2CPP.net6preview" $Path = "Release\UnityExplorer.MelonLoader.IL2CPP.net6preview"
Remove-Item $Path\UnityExplorer.ML.IL2CPP.net6preview.deps.json # ILRepack
Remove-Item $Path\Tomlet.dll lib/ILRepack.exe /target:library /lib:lib/net6 /lib:lib/unhollowed /lib:$Path /internalize /out:$Path/UnityExplorer.ML.IL2CPP.net6preview.dll $Path/UnityExplorer.ML.IL2CPP.net6preview.dll $Path/mcs.dll
# (cleanup and move files)
Remove-Item $Path/UnityExplorer.ML.IL2CPP.net6preview.deps.json
Remove-Item $Path/Tomlet.dll
Remove-Item $Path/mcs.dll
Remove-Item $Path/Iced.dll
Remove-Item $Path/UnhollowerBaseLib.dll
New-Item -Path "$Path" -Name "Mods" -ItemType "directory" -Force New-Item -Path "$Path" -Name "Mods" -ItemType "directory" -Force
Move-Item -Path $Path\UnityExplorer.ML.IL2CPP.net6preview.dll -Destination $Path\Mods -Force Move-Item -Path $Path/UnityExplorer.ML.IL2CPP.net6preview.dll -Destination $Path/Mods -Force
New-Item -Path "$Path" -Name "UserLibs" -ItemType "directory" -Force New-Item -Path "$Path" -Name "UserLibs" -ItemType "directory" -Force
Move-Item -Path $Path\mcs.dll -Destination $Path\UserLibs -Force Move-Item -Path $Path/UniverseLib.IL2CPP.Unhollower.dll -Destination $Path/UserLibs -Force
Move-Item -Path $Path\UniverseLib.IL2CPP.dll -Destination $Path\UserLibs -Force
# (create zip archive) # (create zip archive)
Compress-Archive -Path $Path\* -CompressionLevel Fastest -DestinationPath $Path\..\UnityExplorer.MelonLoader.IL2CPP.net6preview.zip -Force Remove-Item $Path/../UnityExplorer.MelonLoader.IL2CPP.net6preview.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.MelonLoader.IL2CPP.net6preview.zip .\$Path\*
# MelonLoader IL2CPP (net472) # ----------- MelonLoader IL2CPP (net472) -----------
dotnet build src\UnityExplorer.sln -c Release_ML_Cpp_net472 dotnet build src/UnityExplorer.sln -c Release_ML_Cpp_net472
$Path = "Release/UnityExplorer.MelonLoader.IL2CPP"
# ILRepack
lib/ILRepack.exe /target:library /lib:lib/net472 /lib:lib/net35 /lib:lib/unhollowed /lib:$Path /internalize /out:$Path/UnityExplorer.ML.IL2CPP.dll $Path/UnityExplorer.ML.IL2CPP.dll $Path/mcs.dll
# (cleanup and move files) # (cleanup and move files)
$Path = "Release\UnityExplorer.MelonLoader.IL2CPP" Remove-Item $Path/Tomlet.dll
Remove-Item $Path\Tomlet.dll Remove-Item $Path/mcs.dll
Remove-Item $Path/Iced.dll
Remove-Item $Path/UnhollowerBaseLib.dll
New-Item -Path "$Path" -Name "Mods" -ItemType "directory" -Force New-Item -Path "$Path" -Name "Mods" -ItemType "directory" -Force
Move-Item -Path $Path\UnityExplorer.ML.IL2CPP.dll -Destination $Path\Mods -Force Move-Item -Path $Path/UnityExplorer.ML.IL2CPP.dll -Destination $Path/Mods -Force
New-Item -Path "$Path" -Name "UserLibs" -ItemType "directory" -Force New-Item -Path "$Path" -Name "UserLibs" -ItemType "directory" -Force
Move-Item -Path $Path\mcs.dll -Destination $Path\UserLibs -Force Move-Item -Path $Path/UniverseLib.IL2CPP.Unhollower.dll -Destination $Path/UserLibs -Force
Move-Item -Path $Path\UniverseLib.IL2CPP.dll -Destination $Path\UserLibs -Force
# (create zip archive) # (create zip archive)
Compress-Archive -Path $Path\* -CompressionLevel Fastest -DestinationPath $Path\..\UnityExplorer.MelonLoader.IL2CPP.zip -Force Remove-Item $Path/../UnityExplorer.MelonLoader.IL2CPP.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.MelonLoader.IL2CPP.zip .\$Path\*
# MelonLoader Mono # ----------- MelonLoader Mono -----------
dotnet build src\UnityExplorer.sln -c Release_ML_Mono dotnet build src/UnityExplorer.sln -c Release_ML_Mono
$Path = "Release/UnityExplorer.MelonLoader.Mono"
# ILRepack
lib/ILRepack.exe /target:library /lib:lib/net35 /lib:$Path /internalize /out:$Path/UnityExplorer.ML.Mono.dll $Path/UnityExplorer.ML.Mono.dll $Path/mcs.dll
# (cleanup and move files) # (cleanup and move files)
$Path = "Release\UnityExplorer.MelonLoader.Mono" Remove-Item $Path/Tomlet.dll
Remove-Item $Path\Tomlet.dll Remove-Item $Path/mcs.dll
New-Item -Path "$Path" -Name "Mods" -ItemType "directory" -Force New-Item -Path "$Path" -Name "Mods" -ItemType "directory" -Force
Move-Item -Path $Path\UnityExplorer.ML.Mono.dll -Destination $Path\Mods -Force Move-Item -Path $Path/UnityExplorer.ML.Mono.dll -Destination $Path/Mods -Force
New-Item -Path "$Path" -Name "UserLibs" -ItemType "directory" -Force New-Item -Path "$Path" -Name "UserLibs" -ItemType "directory" -Force
Move-Item -Path $Path\mcs.dll -Destination $Path\UserLibs -Force Move-Item -Path $Path/UniverseLib.Mono.dll -Destination $Path/UserLibs -Force
Move-Item -Path $Path\UniverseLib.Mono.dll -Destination $Path\UserLibs -Force
# (create zip archive) # (create zip archive)
Compress-Archive -Path $Path\* -CompressionLevel Fastest -DestinationPath $Path\..\UnityExplorer.MelonLoader.Mono.zip -Force Remove-Item $Path/../UnityExplorer.MelonLoader.Mono.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.MelonLoader.Mono.zip .\$Path\*
# BepInEx IL2CPP # ----------- BepInEx IL2CPP -----------
dotnet build src\UnityExplorer.sln -c Release_BIE_Cpp dotnet build src/UnityExplorer.sln -c Release_BIE_Cpp
$Path = "Release/UnityExplorer.BepInEx.IL2CPP"
# ILRepack
lib/ILRepack.exe /target:library /lib:lib/net472 /lib:lib/unhollowed /lib:$Path /internalize /out:$Path/UnityExplorer.BIE.IL2CPP.dll $Path/UnityExplorer.BIE.IL2CPP.dll $Path/mcs.dll $Path/Tomlet.dll
# (cleanup and move files) # (cleanup and move files)
$Path = "Release\UnityExplorer.BepInEx.IL2CPP" Remove-Item $Path/Tomlet.dll
Remove-Item $Path/mcs.dll
Remove-Item $Path/Iced.dll
Remove-Item $Path/UnhollowerBaseLib.dll
New-Item -Path "$Path" -Name "plugins" -ItemType "directory" -Force New-Item -Path "$Path" -Name "plugins" -ItemType "directory" -Force
New-Item -Path "$Path" -Name "plugins\sinai-dev-UnityExplorer" -ItemType "directory" -Force New-Item -Path "$Path" -Name "plugins/sinai-dev-UnityExplorer" -ItemType "directory" -Force
Move-Item -Path $Path\UnityExplorer.BIE.IL2CPP.dll -Destination $Path\plugins\sinai-dev-UnityExplorer -Force Move-Item -Path $Path/UnityExplorer.BIE.IL2CPP.dll -Destination $Path/plugins/sinai-dev-UnityExplorer -Force
Move-Item -Path $Path\mcs.dll -Destination $Path\plugins\sinai-dev-UnityExplorer -Force Move-Item -Path $Path/UniverseLib.IL2CPP.Unhollower.dll -Destination $Path/plugins/sinai-dev-UnityExplorer -Force
Move-Item -Path $Path\Tomlet.dll -Destination $Path\plugins\sinai-dev-UnityExplorer -Force
Move-Item -Path $Path\UniverseLib.IL2CPP.dll -Destination $Path\plugins\sinai-dev-UnityExplorer -Force
# (create zip archive) # (create zip archive)
Compress-Archive -Path $Path\* -CompressionLevel Fastest -DestinationPath $Path\..\UnityExplorer.BepInEx.IL2CPP.zip -Force Remove-Item $Path/../UnityExplorer.BepInEx.IL2CPP.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.BepInEx.IL2CPP.zip .\$Path\*
# BepInEx 5 Mono # ----------- BepInEx IL2CPP CoreCLR -----------
dotnet build src\UnityExplorer.sln -c Release_BIE5_Mono dotnet build src/UnityExplorer.sln -c Release_BIE_CoreCLR
$Path = "Release/UnityExplorer.BepInEx.IL2CPP.CoreCLR"
# ILRepack
lib/ILRepack.exe /target:library /lib:lib/net472 /lib:lib/net6/ /lib:lib/interop/ /lib:$Path /internalize /out:$Path/UnityExplorer.BIE.IL2CPP.CoreCLR.dll $Path/UnityExplorer.BIE.IL2CPP.CoreCLR.dll $Path/mcs.dll $Path/Tomlet.dll
# (cleanup and move files) # (cleanup and move files)
$Path = "Release\UnityExplorer.BepInEx5.Mono" Remove-Item $Path/Tomlet.dll
Remove-Item $Path/mcs.dll
Remove-Item $Path/Iced.dll
Remove-Item $Path/Il2CppInterop.Common.dll
Remove-Item $Path/Il2CppInterop.Runtime.dll
Remove-Item $Path/Microsoft.Extensions.Logging.Abstractions.dll
Remove-Item $Path/UnityExplorer.BIE.IL2CPP.CoreCLR.deps.json
New-Item -Path "$Path" -Name "plugins" -ItemType "directory" -Force New-Item -Path "$Path" -Name "plugins" -ItemType "directory" -Force
New-Item -Path "$Path" -Name "plugins\sinai-dev-UnityExplorer" -ItemType "directory" -Force New-Item -Path "$Path" -Name "plugins/sinai-dev-UnityExplorer" -ItemType "directory" -Force
Move-Item -Path $Path\UnityExplorer.BIE5.Mono.dll -Destination $Path\plugins\sinai-dev-UnityExplorer -Force Move-Item -Path $Path/UnityExplorer.BIE.IL2CPP.CoreCLR.dll -Destination $Path/plugins/sinai-dev-UnityExplorer -Force
Move-Item -Path $Path\mcs.dll -Destination $Path\plugins\sinai-dev-UnityExplorer -Force Move-Item -Path $Path/UniverseLib.IL2CPP.Interop.dll -Destination $Path/plugins/sinai-dev-UnityExplorer -Force
Move-Item -Path $Path\Tomlet.dll -Destination $Path\plugins\sinai-dev-UnityExplorer -Force
Move-Item -Path $Path\UniverseLib.Mono.dll -Destination $Path\plugins\sinai-dev-UnityExplorer -Force
# (create zip archive) # (create zip archive)
Compress-Archive -Path $Path\* -CompressionLevel Fastest -DestinationPath $Path\..\UnityExplorer.BepInEx5.Mono.zip -Force Remove-Item $Path/../UnityExplorer.BepInEx.IL2CPP.CoreCLR.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.BepInEx.IL2CPP.CoreCLR.zip .\$Path\*
# BepInEx 6 Mono # ----------- BepInEx 5 Mono -----------
dotnet build src\UnityExplorer.sln -c Release_BIE6_Mono dotnet build src/UnityExplorer.sln -c Release_BIE5_Mono
$Path = "Release/UnityExplorer.BepInEx5.Mono"
# ILRepack
lib/ILRepack.exe /target:library /lib:lib/net35 /lib:$Path /internalize /out:$Path/UnityExplorer.BIE5.Mono.dll $Path/UnityExplorer.BIE5.Mono.dll $Path/mcs.dll $Path/Tomlet.dll
# (cleanup and move files) # (cleanup and move files)
$Path = "Release\UnityExplorer.BepInEx6.Mono" Remove-Item $Path/Tomlet.dll
Remove-Item $Path/mcs.dll
New-Item -Path "$Path" -Name "plugins" -ItemType "directory" -Force New-Item -Path "$Path" -Name "plugins" -ItemType "directory" -Force
New-Item -Path "$Path" -Name "plugins\sinai-dev-UnityExplorer" -ItemType "directory" -Force New-Item -Path "$Path" -Name "plugins/sinai-dev-UnityExplorer" -ItemType "directory" -Force
Move-Item -Path $Path\UnityExplorer.BIE6.Mono.dll -Destination $Path\plugins\sinai-dev-UnityExplorer -Force Move-Item -Path $Path/UnityExplorer.BIE5.Mono.dll -Destination $Path/plugins/sinai-dev-UnityExplorer -Force
Move-Item -Path $Path\mcs.dll -Destination $Path\plugins\sinai-dev-UnityExplorer -Force Move-Item -Path $Path/UniverseLib.Mono.dll -Destination $Path/plugins/sinai-dev-UnityExplorer -Force
Move-Item -Path $Path\Tomlet.dll -Destination $Path\plugins\sinai-dev-UnityExplorer -Force
Move-Item -Path $Path\UniverseLib.Mono.dll -Destination $Path\plugins\sinai-dev-UnityExplorer -Force
# (create zip archive) # (create zip archive)
Compress-Archive -Path $Path\* -CompressionLevel Fastest -DestinationPath $Path\..\UnityExplorer.BepInEx6.Mono.zip -Force Remove-Item $Path/../UnityExplorer.BepInEx5.Mono.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.BepInEx5.Mono.zip .\$Path\*
# Standalone Mono # ----------- BepInEx 6 Mono -----------
dotnet build src\UnityExplorer.sln -c Release_STANDALONE_Mono dotnet build src/UnityExplorer.sln -c Release_BIE6_Mono
$Path = "Release\UnityExplorer.Standalone.Mono" $Path = "Release/UnityExplorer.BepInEx6.Mono"
Compress-Archive -Path $Path\* -CompressionLevel Fastest -DestinationPath $Path\..\UnityExplorer.Standalone.Mono.zip -Force # ILRepack
lib/ILRepack.exe /target:library /lib:lib/net35 /lib:$Path /internalize /out:$Path/UnityExplorer.BIE6.Mono.dll $Path/UnityExplorer.BIE6.Mono.dll $Path/mcs.dll $Path/Tomlet.dll
# (cleanup and move files)
Remove-Item $Path/Tomlet.dll
Remove-Item $Path/mcs.dll
New-Item -Path "$Path" -Name "plugins" -ItemType "directory" -Force
New-Item -Path "$Path" -Name "plugins/sinai-dev-UnityExplorer" -ItemType "directory" -Force
Move-Item -Path $Path/UnityExplorer.BIE6.Mono.dll -Destination $Path/plugins/sinai-dev-UnityExplorer -Force
Move-Item -Path $Path/UniverseLib.Mono.dll -Destination $Path/plugins/sinai-dev-UnityExplorer -Force
# (create zip archive)
Remove-Item $Path/../UnityExplorer.BepInEx6.Mono.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.BepInEx6.Mono.zip .\$Path\*
# Standalone IL2CPP # ----------- Standalone Mono -----------
dotnet build src\UnityExplorer.sln -c Release_STANDALONE_Cpp dotnet build src/UnityExplorer.sln -c Release_STANDALONE_Mono
$Path = "Release\UnityExplorer.Standalone.IL2CPP" $Path = "Release/UnityExplorer.Standalone.Mono"
Compress-Archive -Path $Path\* -CompressionLevel Fastest -DestinationPath $Path\..\UnityExplorer.Standalone.IL2CPP.zip -Force # ILRepack
lib/ILRepack.exe /target:library /lib:lib/net35 /lib:$Path /internalize /out:$Path/UnityExplorer.Standalone.Mono.dll $Path/UnityExplorer.Standalone.Mono.dll $Path/mcs.dll $Path/Tomlet.dll
# (cleanup and move files)
Remove-Item $Path/Tomlet.dll
Remove-Item $Path/mcs.dll
Remove-Item $Path/../UnityExplorer.Standalone.Mono.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.Standalone.Mono.zip .\$Path\*
# Editor (mono) # ----------- Standalone IL2CPP -----------
$Path1 = "Release\UnityExplorer.Standalone.Mono" dotnet build src/UnityExplorer.sln -c Release_STANDALONE_Cpp
$Path2 = "UnityEditorPackage\Runtime" $Path = "Release/UnityExplorer.Standalone.IL2CPP"
Copy-Item $Path1\UnityExplorer.STANDALONE.Mono.dll -Destination $Path2 # ILRepack
Copy-Item $Path1\mcs.dll -Destination $Path2 lib/ILRepack.exe /target:library /lib:lib/net472 /lib:lib/unhollowed /lib:$Path /internalize /out:$Path/UnityExplorer.Standalone.IL2CPP.dll $Path/UnityExplorer.Standalone.IL2CPP.dll $Path/mcs.dll $Path/Tomlet.dll
Copy-Item $Path1\Tomlet.dll -Destination $Path2 # (cleanup and move files)
Copy-Item $Path1\UniverseLib.Mono.dll -Destination $Path2 Remove-Item $Path/Tomlet.dll
Compress-Archive -Path UnityEditorPackage\* -CompressionLevel Fastest -DestinationPath Release\UnityExplorer.Editor.zip -Force Remove-Item $Path/mcs.dll
Remove-Item $Path/Iced.dll
Remove-Item $Path/UnhollowerBaseLib.dll
Remove-Item $Path/../UnityExplorer.Standalone.IL2CPP.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.Standalone.IL2CPP.zip .\$Path\*
# ----------- Editor (mono) -----------
$Path1 = "Release/UnityExplorer.Standalone.Mono"
$Path2 = "UnityEditorPackage/Runtime"
Copy-Item $Path1/UnityExplorer.STANDALONE.Mono.dll -Destination $Path2
Copy-Item $Path1/UniverseLib.Mono.dll -Destination $Path2
Remove-Item Release/UnityExplorer.Editor.zip -ErrorAction SilentlyContinue
7z a Release/UnityExplorer.Editor.zip .\UnityEditorPackage\*

BIN
lib/ILRepack.exe Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib/interop/UnityEngine.dll Normal file

Binary file not shown.

BIN
lib/net6/System.Runtime.dll Normal file

Binary file not shown.

View File

@ -1,13 +1,8 @@
using System; using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityExplorer.CSConsole.Lexers; using UnityExplorer.CSConsole.Lexers;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets.AutoComplete; using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.Utility;
namespace UnityExplorer.CSConsole namespace UnityExplorer.CSConsole
{ {

View File

@ -1,56 +1,49 @@
using HarmonyLib; using Mono.CSharp;
using Mono.CSharp;
using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib;
using UniverseLib.Input; using UniverseLib.Input;
using UniverseLib.Runtime;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.Utility;
namespace UnityExplorer.CSConsole namespace UnityExplorer.CSConsole
{ {
public static class ConsoleController public static class ConsoleController
{ {
public static ScriptEvaluator Evaluator; public static ScriptEvaluator Evaluator { get; private set; }
public static LexerBuilder Lexer; public static LexerBuilder Lexer { get; private set; }
public static CSAutoCompleter Completer; public static CSAutoCompleter Completer { get; private set; }
private static HashSet<string> usingDirectives;
private static StringBuilder evaluatorOutput;
private static StringWriter evaluatorStringWriter;
public static CSConsolePanel Panel => UIManager.GetPanel<CSConsolePanel>(UIManager.Panels.CSConsole);
public static InputFieldRef Input => Panel.Input;
public static bool SRENotSupported { get; private set; }
public static int LastCaretPosition { get; private set; } public static int LastCaretPosition { get; private set; }
internal static float defaultInputFieldAlpha; public static float DefaultInputFieldAlpha { get; set; }
// Todo save as config?
public static bool EnableCtrlRShortcut { get; private set; } = true; public static bool EnableCtrlRShortcut { get; private set; } = true;
public static bool EnableAutoIndent { get; private set; } = true; public static bool EnableAutoIndent { get; private set; } = true;
public static bool EnableSuggestions { get; private set; } = true; public static bool EnableSuggestions { get; private set; } = true;
internal static string ScriptsFolder => Path.Combine(ExplorerCore.ExplorerFolder, "Scripts"); public static CSConsolePanel Panel => UIManager.GetPanel<CSConsolePanel>(UIManager.Panels.CSConsole);
public static InputFieldRef Input => Panel.Input;
internal static readonly string[] DefaultUsing = new string[] public static string ScriptsFolder => Path.Combine(ExplorerCore.ExplorerFolder, "Scripts");
static HashSet<string> usingDirectives;
static StringBuilder evaluatorOutput;
static StringWriter evaluatorStringWriter;
static float timeOfLastCtrlR;
static bool settingCaretCoroutine;
static string previousInput;
static int previousContentLength = 0;
static readonly string[] DefaultUsing = new string[]
{ {
"System", "System",
"System.Linq", "System.Linq",
"System.Text", "System.Text",
"System.Collections", "System.Collections",
"System.Collections.Generic", "System.Collections.Generic",
"System.Reflection",
"UnityEngine", "UnityEngine",
"UniverseLib", "UniverseLib",
#if CPP #if CPP
@ -59,9 +52,10 @@ namespace UnityExplorer.CSConsole
#endif #endif
}; };
const int CSCONSOLE_LINEHEIGHT = 18;
public static void Init() public static void Init()
{ {
// Make sure console is supported on this platform
try try
{ {
ResetConsole(false); ResetConsole(false);
@ -111,31 +105,10 @@ namespace UnityExplorer.CSConsole
} }
} }
#region UI Listeners and options
// TODO save
private static void OnToggleAutoIndent(bool value)
{
EnableAutoIndent = value;
}
private static void OnToggleCtrlRShortcut(bool value)
{
EnableCtrlRShortcut = value;
}
private static void OnToggleSuggestions(bool value)
{
EnableSuggestions = value;
}
#endregion
#region Evaluating #region Evaluating
private static void GenerateTextWriter() static void GenerateTextWriter()
{ {
evaluatorOutput = new StringBuilder(); evaluatorOutput = new StringBuilder();
evaluatorStringWriter = new StringWriter(evaluatorOutput); evaluatorStringWriter = new StringWriter(evaluatorOutput);
@ -247,16 +220,48 @@ namespace UnityExplorer.CSConsole
#endregion #endregion
// Updating and event listeners #region Update loop and event listeners
private static bool settingCaretCoroutine; public static void Update()
{
if (SRENotSupported)
return;
private static void OnInputScrolled() => HighlightVisibleInput(); if (!InputManager.GetKey(KeyCode.LeftControl) && !InputManager.GetKey(KeyCode.RightControl))
{
if (InputManager.GetKeyDown(KeyCode.Home))
JumpToStartOrEndOfLine(true);
else if (InputManager.GetKeyDown(KeyCode.End))
JumpToStartOrEndOfLine(false);
}
private static string previousInput; UpdateCaret(out bool caretMoved);
// Invoked at most once per frame if (!settingCaretCoroutine && EnableSuggestions)
private static void OnInputChanged(string value) {
if (AutoCompleteModal.CheckEscape(Completer))
{
OnAutocompleteEscaped();
return;
}
if (caretMoved)
AutoCompleteModal.Instance.ReleaseOwnership(Completer);
}
if (EnableCtrlRShortcut
&& (InputManager.GetKey(KeyCode.LeftControl) || InputManager.GetKey(KeyCode.RightControl))
&& InputManager.GetKeyDown(KeyCode.R)
&& timeOfLastCtrlR.OccuredEarlierThanDefault())
{
timeOfLastCtrlR = Time.realtimeSinceStartup;
Evaluate(Panel.Input.Text);
}
}
static void OnInputScrolled() => HighlightVisibleInput(out _);
static void OnInputChanged(string value)
{ {
if (SRENotSupported) if (SRENotSupported)
return; return;
@ -283,7 +288,7 @@ namespace UnityExplorer.CSConsole
DoAutoIndent(); DoAutoIndent();
} }
bool inStringOrComment = HighlightVisibleInput(); HighlightVisibleInput(out bool inStringOrComment);
if (!settingCaretCoroutine) if (!settingCaretCoroutine)
{ {
@ -299,40 +304,27 @@ namespace UnityExplorer.CSConsole
UpdateCaret(out _); UpdateCaret(out _);
} }
private static float timeOfLastCtrlR; static void OnToggleAutoIndent(bool value)
public static void Update()
{ {
if (SRENotSupported) EnableAutoIndent = value;
return;
UpdateCaret(out bool caretMoved);
if (!settingCaretCoroutine && EnableSuggestions)
{
if (AutoCompleteModal.CheckEscape(Completer))
{
OnAutocompleteEscaped();
return;
}
if (caretMoved)
AutoCompleteModal.Instance.ReleaseOwnership(Completer);
}
if (EnableCtrlRShortcut
&& (InputManager.GetKey(KeyCode.LeftControl) || InputManager.GetKey(KeyCode.RightControl))
&& InputManager.GetKeyDown(KeyCode.R)
&& timeOfLastCtrlR.OccuredEarlierThanDefault())
{
timeOfLastCtrlR = Time.realtimeSinceStartup;
Evaluate(Panel.Input.Text);
}
} }
private const int CSCONSOLE_LINEHEIGHT = 18; static void OnToggleCtrlRShortcut(bool value)
{
EnableCtrlRShortcut = value;
}
private static void UpdateCaret(out bool caretMoved) static void OnToggleSuggestions(bool value)
{
EnableSuggestions = value;
}
#endregion
#region Caret position
static void UpdateCaret(out bool caretMoved)
{ {
int prevCaret = LastCaretPosition; int prevCaret = LastCaretPosition;
caretMoved = false; caretMoved = false;
@ -377,14 +369,18 @@ namespace UnityExplorer.CSConsole
} }
} }
private static void SetCaretPosition(int caretPosition) public static void SetCaretPosition(int caretPosition)
{ {
Input.Component.caretPosition = caretPosition;
// Fix to make sure we always really set the caret position.
// Yields a frame and fixes text-selection issues.
settingCaretCoroutine = true; settingCaretCoroutine = true;
Input.Component.readOnly = true; Input.Component.readOnly = true;
RuntimeHelper.StartCoroutine(SetCaretCoroutine(caretPosition)); RuntimeHelper.StartCoroutine(DoSetCaretCoroutine(caretPosition));
} }
private static IEnumerator SetCaretCoroutine(int caretPosition) static IEnumerator DoSetCaretCoroutine(int caretPosition)
{ {
Color color = Input.Component.selectionColor; Color color = Input.Component.selectionColor;
color.a = 0f; color.a = 0f;
@ -399,25 +395,69 @@ namespace UnityExplorer.CSConsole
Input.Component.selectionFocusPosition = caretPosition; Input.Component.selectionFocusPosition = caretPosition;
LastCaretPosition = Input.Component.caretPosition; LastCaretPosition = Input.Component.caretPosition;
color.a = defaultInputFieldAlpha; color.a = DefaultInputFieldAlpha;
Input.Component.selectionColor = color; Input.Component.selectionColor = color;
Input.Component.readOnly = false; Input.Component.readOnly = false;
settingCaretCoroutine = false; settingCaretCoroutine = false;
} }
// For Home and End keys
static void JumpToStartOrEndOfLine(bool toStart)
{
// Determine the current and next line
UILineInfo thisline = default;
UILineInfo? nextLine = null;
for (int i = 0; i < Input.Component.cachedInputTextGenerator.lineCount; i++)
{
UILineInfo line = Input.Component.cachedInputTextGenerator.lines[i];
if (line.startCharIdx > LastCaretPosition)
{
nextLine = line;
break;
}
thisline = line;
}
if (toStart)
{
// Determine where the indented text begins
int endOfLine = nextLine == null ? Input.Text.Length : nextLine.Value.startCharIdx;
int indentedStart = thisline.startCharIdx;
while (indentedStart < endOfLine - 1 && char.IsWhiteSpace(Input.Text[indentedStart]))
indentedStart++;
// Jump to either the true start or the non-whitespace position,
// depending on which one we are not at.
if (LastCaretPosition == indentedStart)
SetCaretPosition(thisline.startCharIdx);
else
SetCaretPosition(indentedStart);
}
else
{
// If there is no next line, jump to the end of this line (+1, to the invisible next character position)
if (nextLine == null)
SetCaretPosition(Input.Text.Length);
else // jump to the next line start index - 1, ie. end of this line
SetCaretPosition(nextLine.Value.startCharIdx - 1);
}
}
#endregion
#region Lexer Highlighting #region Lexer Highlighting
/// <summary> private static void HighlightVisibleInput(out bool inStringOrComment)
/// Returns true if caret is inside string or comment, false otherwise
/// </summary>
private static bool HighlightVisibleInput()
{ {
inStringOrComment = false;
if (string.IsNullOrEmpty(Input.Text)) if (string.IsNullOrEmpty(Input.Text))
{ {
Panel.HighlightText.text = ""; Panel.HighlightText.text = "";
Panel.LineNumberText.text = "1"; Panel.LineNumberText.text = "1";
return false; return;
} }
// Calculate the visible lines // Calculate the visible lines
@ -452,7 +492,7 @@ namespace UnityExplorer.CSConsole
// Highlight the visible text with the LexerBuilder // Highlight the visible text with the LexerBuilder
Panel.HighlightText.text = Lexer.BuildHighlightedString(Input.Text, startIdx, endIdx, topLine, LastCaretPosition, out bool ret); Panel.HighlightText.text = Lexer.BuildHighlightedString(Input.Text, startIdx, endIdx, topLine, LastCaretPosition, out inStringOrComment);
// Set the line numbers // Set the line numbers
@ -490,7 +530,7 @@ namespace UnityExplorer.CSConsole
Panel.LineNumberText.text = sb.ToString(); Panel.LineNumberText.text = sb.ToString();
return ret; return;
} }
#endregion #endregion
@ -530,13 +570,11 @@ namespace UnityExplorer.CSConsole
#region Auto indenting #region Auto indenting
private static int prevContentLen = 0;
private static void DoAutoIndent() private static void DoAutoIndent()
{ {
if (Input.Text.Length > prevContentLen) if (Input.Text.Length > previousContentLength)
{ {
int inc = Input.Text.Length - prevContentLen; int inc = Input.Text.Length - previousContentLength;
if (inc == 1) if (inc == 1)
{ {
@ -555,7 +593,7 @@ namespace UnityExplorer.CSConsole
} }
} }
prevContentLen = Input.Text.Length; previousContentLength = Input.Text.Length;
} }
#endregion #endregion
@ -563,8 +601,6 @@ namespace UnityExplorer.CSConsole
#region "Help" interaction #region "Help" interaction
private static bool SRENotSupported;
private static void DisableConsole(Exception ex) private static void DisableConsole(Exception ex)
{ {
SRENotSupported = true; SRENotSupported = true;

View File

@ -1,8 +1,5 @@
using System; using System.Text;
using System.Collections.Generic;
using System.Text;
using UnityExplorer.CSConsole.Lexers; using UnityExplorer.CSConsole.Lexers;
using UniverseLib.Utility;
namespace UnityExplorer.CSConsole namespace UnityExplorer.CSConsole
{ {
@ -17,8 +14,6 @@ namespace UnityExplorer.CSConsole
public class LexerBuilder public class LexerBuilder
{ {
#region Core and initialization
public const char WHITESPACE = ' '; public const char WHITESPACE = ' ';
public readonly HashSet<char> IndentOpenChars = new() { '{', '(' }; public readonly HashSet<char> IndentOpenChars = new() { '{', '(' };
public readonly HashSet<char> IndentCloseChars = new() { '}', ')' }; public readonly HashSet<char> IndentCloseChars = new() { '}', ')' };
@ -50,8 +45,6 @@ namespace UnityExplorer.CSConsole
} }
} }
#endregion
/// <summary>The last committed index for a match or no-match. Starts at -1 for a new parse.</summary> /// <summary>The last committed index for a match or no-match. Starts at -1 for a new parse.</summary>
public int CommittedIndex { get; private set; } public int CommittedIndex { get; private set; }
/// <summary>The index of the character we are currently parsing, at minimum it will be CommittedIndex + 1.</summary> /// <summary>The index of the character we are currently parsing, at minimum it will be CommittedIndex + 1.</summary>

View File

@ -1,6 +1,4 @@
using UnityEngine; namespace UnityExplorer.CSConsole.Lexers
namespace UnityExplorer.CSConsole.Lexers
{ {
public class CommentLexer : Lexer public class CommentLexer : Lexer
{ {

View File

@ -1,6 +1,4 @@
using System.Collections.Generic; using System.Text;
using System.Text;
using UnityEngine;
namespace UnityExplorer.CSConsole.Lexers namespace UnityExplorer.CSConsole.Lexers
{ {

View File

@ -1,9 +1,4 @@
using System.Collections.Generic; namespace UnityExplorer.CSConsole.Lexers
using System.Linq;
using UnityEngine;
using UniverseLib.Utility;
namespace UnityExplorer.CSConsole.Lexers
{ {
public abstract class Lexer public abstract class Lexer
{ {

View File

@ -1,6 +1,4 @@
using UnityEngine; namespace UnityExplorer.CSConsole.Lexers
namespace UnityExplorer.CSConsole.Lexers
{ {
public class NumberLexer : Lexer public class NumberLexer : Lexer
{ {

View File

@ -1,7 +1,4 @@
using System.Collections.Generic; namespace UnityExplorer.CSConsole.Lexers
using UnityEngine;
namespace UnityExplorer.CSConsole.Lexers
{ {
public class StringLexer : Lexer public class StringLexer : Lexer
{ {

View File

@ -1,8 +1,4 @@
using System.Collections.Generic; namespace UnityExplorer.CSConsole.Lexers
using System.Linq;
using UnityEngine;
namespace UnityExplorer.CSConsole.Lexers
{ {
public class SymbolLexer : Lexer public class SymbolLexer : Lexer
{ {
@ -32,13 +28,7 @@ namespace UnityExplorer.CSConsole.Lexers
if (IsSymbol(lexer.Current)) if (IsSymbol(lexer.Current))
{ {
do lexer.Commit();
{
lexer.Commit();
lexer.PeekNext();
}
while (IsSymbol(lexer.Current));
return true; return true;
} }

View File

@ -1,8 +1,5 @@
using Mono.CSharp; using Mono.CSharp;
using System; using UnityExplorer.Config;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
// Thanks to ManlyMarco for this // Thanks to ManlyMarco for this
@ -10,6 +7,9 @@ namespace UnityExplorer.CSConsole
{ {
public class ScriptEvaluator : Evaluator, IDisposable public class ScriptEvaluator : Evaluator, IDisposable
{ {
internal TextWriter _textWriter;
internal static StreamReportPrinter _reportPrinter;
private static readonly HashSet<string> StdLib = new(StringComparer.InvariantCultureIgnoreCase) private static readonly HashSet<string> StdLib = new(StringComparer.InvariantCultureIgnoreCase)
{ {
"mscorlib", "mscorlib",
@ -18,9 +18,6 @@ namespace UnityExplorer.CSConsole
"System.Xml" "System.Xml"
}; };
internal TextWriter _textWriter;
internal static StreamReportPrinter _reportPrinter;
public ScriptEvaluator(TextWriter tw) : base(BuildContext(tw)) public ScriptEvaluator(TextWriter tw) : base(BuildContext(tw))
{ {
_textWriter = tw; _textWriter = tw;
@ -48,8 +45,19 @@ namespace UnityExplorer.CSConsole
private void Reference(Assembly asm) private void Reference(Assembly asm)
{ {
string name = asm.GetName().Name; string name = asm.GetName().Name;
if (name == "completions")
if (name == "completions") // ignore assemblies generated by mcs' autocomplete.
return; return;
foreach (string blacklisted in ConfigManager.CSConsole_Assembly_Blacklist.Value.Split(';'))
{
string bl = blacklisted;
if (bl.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
bl = blacklisted.Substring(0, bl.Length - 4);
if (string.Equals(bl, name, StringComparison.OrdinalIgnoreCase))
return;
}
ReferenceAssembly(asm); ReferenceAssembly(asm);
} }

View File

@ -1,12 +1,8 @@
using HarmonyLib; using HarmonyLib;
using Mono.CSharp; using Mono.CSharp;
using System;
using System.Collections; using System.Collections;
using System.Linq;
using System.Text; using System.Text;
using UnityEngine;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UniverseLib;
namespace UnityExplorer.CSConsole namespace UnityExplorer.CSConsole
{ {

View File

@ -1,7 +1,4 @@
using System; using UnityExplorer.Inspectors;
using System.Reflection;
using UnityExplorer.Inspectors;
using UniverseLib.Utility;
namespace UnityExplorer.CacheObject namespace UnityExplorer.CacheObject
{ {

View File

@ -1,6 +1,4 @@
using System; using UnityExplorer.Inspectors;
using System.Reflection;
using UnityExplorer.Inspectors;
namespace UnityExplorer.CacheObject namespace UnityExplorer.CacheObject
{ {

View File

@ -1,8 +1,5 @@
using System; using UnityExplorer.CacheObject.IValues;
using UnityExplorer.CacheObject.IValues;
using UnityExplorer.CacheObject.Views; using UnityExplorer.CacheObject.Views;
using UniverseLib;
using UniverseLib.Utility;
namespace UnityExplorer.CacheObject namespace UnityExplorer.CacheObject
{ {

View File

@ -1,12 +1,7 @@
using System; using UnityExplorer.CacheObject.Views;
using System.Reflection;
using UnityEngine;
using UnityExplorer.CacheObject.Views;
using UnityExplorer.Inspectors; using UnityExplorer.Inspectors;
using UnityExplorer.UI.Widgets; using UnityExplorer.UI.Widgets;
using UniverseLib;
using UniverseLib.UI.ObjectPool; using UniverseLib.UI.ObjectPool;
using UniverseLib.Utility;
namespace UnityExplorer.CacheObject namespace UnityExplorer.CacheObject
{ {

View File

@ -1,11 +1,6 @@
using HarmonyLib; using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityExplorer.Inspectors; using UnityExplorer.Inspectors;
using UnityExplorer.Runtime; using UnityExplorer.Runtime;
using UniverseLib;
namespace UnityExplorer.CacheObject namespace UnityExplorer.CacheObject
{ {

View File

@ -1,7 +1,4 @@
using System; using UnityExplorer.Inspectors;
using System.Reflection;
using UnityExplorer.Inspectors;
using UniverseLib.Utility;
namespace UnityExplorer.CacheObject namespace UnityExplorer.CacheObject
{ {

View File

@ -1,12 +1,8 @@
using System; using System.Collections;
using System.Collections;
using UnityEngine;
using UnityExplorer.CacheObject.IValues; using UnityExplorer.CacheObject.IValues;
using UnityExplorer.CacheObject.Views; using UnityExplorer.CacheObject.Views;
using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.ObjectPool; using UniverseLib.UI.ObjectPool;
using UniverseLib.Utility;
namespace UnityExplorer.CacheObject namespace UnityExplorer.CacheObject
{ {
@ -28,28 +24,31 @@ namespace UnityExplorer.CacheObject
public abstract class CacheObjectBase public abstract class CacheObjectBase
{ {
public ICacheObjectController Owner { get; set; } public ICacheObjectController Owner { get; set; }
public CacheObjectCell CellView { get; internal set; } public CacheObjectCell CellView { get; internal set; }
public object Value { get; protected set; } public object Value { get; protected set; }
public Type FallbackType { get; protected set; } public Type FallbackType { get; protected set; }
public bool LastValueWasNull { get; private set; } public ValueState State { get; set; }
public Exception LastException { get; protected set; }
public ValueState State = ValueState.NotEvaluated; bool valueIsNull;
public Type LastValueType; Type currentValueType;
// InteractiveValues
public InteractiveValue IValue { get; private set; } public InteractiveValue IValue { get; private set; }
public Type CurrentIValueType { get; private set; } public Type CurrentIValueType { get; private set; }
public bool SubContentShowWanted { get; private set; } public bool SubContentShowWanted { get; private set; }
// UI
public string NameLabelText { get; protected set; } public string NameLabelText { get; protected set; }
public string NameLabelTextRaw { get; protected set; } public string NameLabelTextRaw { get; protected set; }
public string ValueLabelText { get; protected set; } public string ValueLabelText { get; protected set; }
// Abstract
public abstract bool ShouldAutoEvaluate { get; } public abstract bool ShouldAutoEvaluate { get; }
public abstract bool HasArguments { get; } public abstract bool HasArguments { get; }
public abstract bool CanWrite { get; } public abstract bool CanWrite { get; }
public Exception LastException { get; protected set; }
protected const string NOT_YET_EVAL = "<color=grey>Not yet evaluated</color>";
public virtual void SetFallbackType(Type fallbackType) public virtual void SetFallbackType(Type fallbackType)
{ {
@ -57,17 +56,6 @@ namespace UnityExplorer.CacheObject
this.ValueLabelText = GetValueLabel(); this.ValueLabelText = GetValueLabel();
} }
protected const string NOT_YET_EVAL = "<color=grey>Not yet evaluated</color>";
public virtual void ReleasePooledObjects()
{
if (this.IValue != null)
ReleaseIValue();
if (this.CellView != null)
UnlinkFromView();
}
public virtual void SetView(CacheObjectCell cellView) public virtual void SetView(CacheObjectCell cellView)
{ {
this.CellView = cellView; this.CellView = cellView;
@ -86,6 +74,15 @@ namespace UnityExplorer.CacheObject
this.IValue.UIRoot.transform.SetParent(InactiveIValueHolder.transform, false); this.IValue.UIRoot.transform.SetParent(InactiveIValueHolder.transform, false);
} }
public virtual void ReleasePooledObjects()
{
if (this.IValue != null)
ReleaseIValue();
if (this.CellView != null)
UnlinkFromView();
}
// Updating and applying values // Updating and applying values
// The only method which sets the CacheObjectBase.Value // The only method which sets the CacheObjectBase.Value
@ -130,18 +127,18 @@ namespace UnityExplorer.CacheObject
if (LastException != null) if (LastException != null)
{ {
LastValueWasNull = true; valueIsNull = true;
LastValueType = FallbackType; currentValueType = FallbackType;
State = ValueState.Exception; State = ValueState.Exception;
} }
else if (Value.IsNullOrDestroyed()) else if (Value.IsNullOrDestroyed())
{ {
LastValueWasNull = true; valueIsNull = true;
State = GetStateForType(FallbackType); State = GetStateForType(FallbackType);
} }
else else
{ {
LastValueWasNull = false; valueIsNull = false;
State = GetStateForType(Value.GetActualType()); State = GetStateForType(Value.GetActualType());
} }
@ -163,10 +160,10 @@ namespace UnityExplorer.CacheObject
public ValueState GetStateForType(Type type) public ValueState GetStateForType(Type type)
{ {
if (LastValueType == type && (State != ValueState.Exception || LastException != null)) if (currentValueType == type && (State != ValueState.Exception || LastException != null))
return State; return State;
LastValueType = type; currentValueType = type;
if (type == typeof(bool)) if (type == typeof(bool))
return ValueState.Boolean; return ValueState.Boolean;
else if (type.IsPrimitive || type == typeof(decimal)) else if (type.IsPrimitive || type == typeof(decimal))
@ -189,7 +186,7 @@ namespace UnityExplorer.CacheObject
protected string GetValueLabel() protected string GetValueLabel()
{ {
string label = ""; string label = string.Empty;
switch (State) switch (State)
{ {
@ -206,19 +203,19 @@ namespace UnityExplorer.CacheObject
// and valuestruct also doesnt want it if we can parse it // and valuestruct also doesnt want it if we can parse it
case ValueState.ValueStruct: case ValueState.ValueStruct:
if (ParseUtility.CanParse(LastValueType)) if (ParseUtility.CanParse(currentValueType))
return null; return null;
break; break;
// string wants it trimmed to max 200 chars // string wants it trimmed to max 200 chars
case ValueState.String: case ValueState.String:
if (!LastValueWasNull) if (!valueIsNull)
return $"\"{ToStringUtility.PruneString(Value as string, 200, 5)}\""; return $"\"{ToStringUtility.PruneString(Value as string, 200, 5)}\"";
break; break;
// try to prefix the count of the collection for lists and dicts // try to prefix the count of the collection for lists and dicts
case ValueState.Collection: case ValueState.Collection:
if (!LastValueWasNull) if (!valueIsNull)
{ {
if (Value is IList iList) if (Value is IList iList)
label = $"[{iList.Count}] "; label = $"[{iList.Count}] ";
@ -230,7 +227,7 @@ namespace UnityExplorer.CacheObject
break; break;
case ValueState.Dictionary: case ValueState.Dictionary:
if (!LastValueWasNull) if (!valueIsNull)
{ {
if (Value is IDictionary iDict) if (Value is IDictionary iDict)
label = $"[{iDict.Count}] "; label = $"[{iDict.Count}] ";
@ -291,7 +288,7 @@ namespace UnityExplorer.CacheObject
SetValueState(cell, new(false, typeLabelActive: true, inputActive: true, applyActive: CanWrite)); SetValueState(cell, new(false, typeLabelActive: true, inputActive: true, applyActive: CanWrite));
break; break;
case ValueState.String: case ValueState.String:
if (LastValueWasNull) if (valueIsNull)
SetValueState(cell, new(true, subContentButtonActive: true)); SetValueState(cell, new(true, subContentButtonActive: true));
else else
SetValueState(cell, new(true, false, SignatureHighlighter.StringOrange, subContentButtonActive: true)); SetValueState(cell, new(true, false, SignatureHighlighter.StringOrange, subContentButtonActive: true));
@ -301,17 +298,17 @@ namespace UnityExplorer.CacheObject
break; break;
case ValueState.Color: case ValueState.Color:
case ValueState.ValueStruct: case ValueState.ValueStruct:
if (ParseUtility.CanParse(LastValueType)) if (ParseUtility.CanParse(currentValueType))
SetValueState(cell, new(false, false, null, true, false, true, CanWrite, true, true)); SetValueState(cell, new(false, false, null, true, false, true, CanWrite, true, true));
else else
SetValueState(cell, new(true, inspectActive: true, subContentButtonActive: true)); SetValueState(cell, new(true, inspectActive: true, subContentButtonActive: true));
break; break;
case ValueState.Collection: case ValueState.Collection:
case ValueState.Dictionary: case ValueState.Dictionary:
SetValueState(cell, new(true, inspectActive: !LastValueWasNull, subContentButtonActive: !LastValueWasNull)); SetValueState(cell, new(true, inspectActive: !valueIsNull, subContentButtonActive: !valueIsNull));
break; break;
case ValueState.Unsupported: case ValueState.Unsupported:
SetValueState(cell, new(true, inspectActive: !LastValueWasNull)); SetValueState(cell, new(true, inspectActive: !valueIsNull));
break; break;
} }
@ -333,7 +330,7 @@ namespace UnityExplorer.CacheObject
// Type label (for primitives) // Type label (for primitives)
cell.TypeLabel.gameObject.SetActive(args.typeLabelActive); cell.TypeLabel.gameObject.SetActive(args.typeLabelActive);
if (args.typeLabelActive) if (args.typeLabelActive)
cell.TypeLabel.text = SignatureHighlighter.Parse(LastValueType, false); cell.TypeLabel.text = SignatureHighlighter.Parse(currentValueType, false);
// toggle for bools // toggle for bools
cell.Toggle.gameObject.SetActive(args.toggleActive); cell.Toggle.gameObject.SetActive(args.toggleActive);
@ -348,7 +345,7 @@ namespace UnityExplorer.CacheObject
cell.InputField.UIRoot.SetActive(args.inputActive); cell.InputField.UIRoot.SetActive(args.inputActive);
if (args.inputActive) if (args.inputActive)
{ {
cell.InputField.Text = ParseUtility.ToStringForInput(Value, LastValueType); cell.InputField.Text = ParseUtility.ToStringForInput(Value, currentValueType);
cell.InputField.Component.readOnly = !CanWrite; cell.InputField.Component.readOnly = !CanWrite;
} }
@ -357,12 +354,12 @@ namespace UnityExplorer.CacheObject
// Inspect button only if last value not null. // Inspect button only if last value not null.
if (cell.InspectButton != null) if (cell.InspectButton != null)
cell.InspectButton.Component.gameObject.SetActive(args.inspectActive && !LastValueWasNull); cell.InspectButton.Component.gameObject.SetActive(args.inspectActive && !valueIsNull);
// set subcontent button if needed, and for null strings and exceptions // set subcontent button if needed, and for null strings and exceptions
cell.SubContentButton.Component.gameObject.SetActive( cell.SubContentButton.Component.gameObject.SetActive(
args.subContentButtonActive args.subContentButtonActive
&& (!LastValueWasNull || State == ValueState.String || State == ValueState.Exception)); && (!valueIsNull || State == ValueState.String || State == ValueState.Exception));
} }
// CacheObjectCell Apply // CacheObjectCell Apply
@ -373,7 +370,7 @@ namespace UnityExplorer.CacheObject
SetUserValue(this.CellView.Toggle.isOn); SetUserValue(this.CellView.Toggle.isOn);
else else
{ {
if (ParseUtility.TryParse(CellView.InputField.Text, LastValueType, out object value, out Exception ex)) if (ParseUtility.TryParse(CellView.InputField.Text, currentValueType, out object value, out Exception ex))
{ {
SetUserValue(value); SetUserValue(value);
} }

View File

@ -1,6 +1,4 @@
using System; using UnityExplorer.Inspectors;
using System.Reflection;
using UnityExplorer.Inspectors;
namespace UnityExplorer.CacheObject namespace UnityExplorer.CacheObject
{ {

View File

@ -1,5 +1,4 @@
using System; using System.Collections;
using System.Collections;
using UnityExplorer.CacheObject.Views; using UnityExplorer.CacheObject.Views;
namespace UnityExplorer.CacheObject namespace UnityExplorer.CacheObject

View File

@ -1,9 +1,5 @@
using System; using UniverseLib.UI;
using UnityEngine;
using UnityEngine.UI;
using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib;
namespace UnityExplorer.CacheObject.IValues namespace UnityExplorer.CacheObject.IValues
{ {

View File

@ -1,14 +1,8 @@
using System; using System.Collections;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CacheObject.Views; using UnityExplorer.CacheObject.Views;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
namespace UnityExplorer.CacheObject.IValues namespace UnityExplorer.CacheObject.IValues
{ {

View File

@ -1,14 +1,8 @@
using System; using System.Collections.Specialized;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets.AutoComplete; using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.Utility;
namespace UnityExplorer.CacheObject.IValues namespace UnityExplorer.CacheObject.IValues
{ {

View File

@ -1,16 +1,8 @@
using System; using System.Collections;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CacheObject.Views; using UnityExplorer.CacheObject.Views;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
namespace UnityExplorer.CacheObject.IValues namespace UnityExplorer.CacheObject.IValues
{ {

View File

@ -1,10 +1,6 @@
using System.IO; using UnityExplorer.Config;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Config;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.Utility;
namespace UnityExplorer.CacheObject.IValues namespace UnityExplorer.CacheObject.IValues
{ {

View File

@ -1,6 +1,4 @@
using System; using UniverseLib.UI.ObjectPool;
using UnityEngine;
using UniverseLib.UI.ObjectPool;
namespace UnityExplorer.CacheObject.IValues namespace UnityExplorer.CacheObject.IValues
{ {

View File

@ -1,13 +1,5 @@
using System; using UniverseLib.UI;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.Utility;
namespace UnityExplorer.CacheObject.IValues namespace UnityExplorer.CacheObject.IValues
{ {

View File

@ -1,8 +1,4 @@
using UnityEngine; using UniverseLib.UI;
using UnityEngine.UI;
using UniverseLib.UI;
using UniverseLib.Utility;
using UniverseLib;
namespace UnityExplorer.CacheObject.Views namespace UnityExplorer.CacheObject.Views
{ {

View File

@ -1,6 +1,4 @@
using UnityEngine; using UnityExplorer.CacheObject.IValues;
using UnityEngine.UI;
using UnityExplorer.CacheObject.IValues;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;

View File

@ -1,6 +1,4 @@
using UnityEngine; using UnityExplorer.CacheObject.IValues;
using UnityEngine.UI;
using UnityExplorer.CacheObject.IValues;
namespace UnityExplorer.CacheObject.Views namespace UnityExplorer.CacheObject.Views
{ {

View File

@ -1,6 +1,4 @@
using UnityEngine; using UniverseLib.UI;
using UnityEngine.UI;
using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
namespace UnityExplorer.CacheObject.Views namespace UnityExplorer.CacheObject.Views

View File

@ -1,11 +1,7 @@
using UnityEngine; using UnityExplorer.UI.Panels;
using UnityEngine.UI;
using UnityExplorer.UI.Panels;
using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
namespace UnityExplorer.CacheObject.Views namespace UnityExplorer.CacheObject.Views
{ {

View File

@ -1,6 +1,4 @@
using System; namespace UnityExplorer.Config
namespace UnityExplorer.Config
{ {
public class ConfigElement<T> : IConfigElement public class ConfigElement<T> : IConfigElement
{ {

View File

@ -1,7 +1,4 @@
using System.Collections.Generic; using UnityExplorer.UI;
using System.IO;
using UnityEngine;
using UnityExplorer.UI;
namespace UnityExplorer.Config namespace UnityExplorer.Config
{ {
@ -16,19 +13,20 @@ namespace UnityExplorer.Config
// Actual UE Settings // Actual UE Settings
public static ConfigElement<KeyCode> Master_Toggle; public static ConfigElement<KeyCode> Master_Toggle;
public static ConfigElement<int> Target_Display;
public static ConfigElement<UIManager.VerticalAnchor> Main_Navbar_Anchor;
public static ConfigElement<bool> Force_Unlock_Mouse;
public static ConfigElement<KeyCode> Force_Unlock_Toggle;
public static ConfigElement<bool> Aggressive_Mouse_Unlock;
public static ConfigElement<bool> Disable_EventSystem_Override;
public static ConfigElement<string> Default_Output_Path;
public static ConfigElement<bool> Log_Unity_Debug;
public static ConfigElement<bool> Hide_On_Startup; public static ConfigElement<bool> Hide_On_Startup;
public static ConfigElement<float> Startup_Delay_Time; public static ConfigElement<float> Startup_Delay_Time;
public static ConfigElement<string> Reflection_Signature_Blacklist; public static ConfigElement<bool> Disable_EventSystem_Override;
public static ConfigElement<int> Target_Display;
public static ConfigElement<bool> Force_Unlock_Mouse;
public static ConfigElement<KeyCode> Force_Unlock_Toggle;
public static ConfigElement<string> Default_Output_Path;
public static ConfigElement<string> DnSpy_Path;
public static ConfigElement<bool> Log_Unity_Debug;
public static ConfigElement<UIManager.VerticalAnchor> Main_Navbar_Anchor;
public static ConfigElement<KeyCode> World_MouseInspect_Keybind; public static ConfigElement<KeyCode> World_MouseInspect_Keybind;
public static ConfigElement<KeyCode> UI_MouseInspect_Keybind; public static ConfigElement<KeyCode> UI_MouseInspect_Keybind;
public static ConfigElement<string> CSConsole_Assembly_Blacklist;
public static ConfigElement<string> Reflection_Signature_Blacklist;
// internal configs // internal configs
internal static InternalConfigHandler InternalHandler { get; private set; } internal static InternalConfigHandler InternalHandler { get; private set; }
@ -54,7 +52,9 @@ namespace UnityExplorer.Config
Handler.LoadConfig(); Handler.LoadConfig();
InternalHandler.LoadConfig(); InternalHandler.LoadConfig();
//InitConsoleCallback(); #if STANDALONE
Loader.Standalone.ExplorerEditorBehaviour.Instance?.LoadConfigs();
#endif
} }
internal static void RegisterConfigElement<T>(ConfigElement<T> configElement) internal static void RegisterConfigElement<T>(ConfigElement<T> configElement)
@ -73,23 +73,53 @@ namespace UnityExplorer.Config
private static void CreateConfigElements() private static void CreateConfigElements()
{ {
Master_Toggle = new ConfigElement<KeyCode>("UnityExplorer Toggle", Master_Toggle = new("UnityExplorer Toggle",
"The key to enable or disable UnityExplorer's menu and features.", "The key to enable or disable UnityExplorer's menu and features.",
KeyCode.F7); KeyCode.F7);
Hide_On_Startup = new ConfigElement<bool>("Hide On Startup", Hide_On_Startup = new("Hide On Startup",
"Should UnityExplorer be hidden on startup?", "Should UnityExplorer be hidden on startup?",
false); false);
Target_Display = new ConfigElement<int>("Target Display", Startup_Delay_Time = new("Startup Delay Time",
"The delay on startup before the UI is created.",
1f);
Target_Display = new("Target Display",
"The monitor index for UnityExplorer to use, if you have multiple. 0 is the default display, 1 is secondary, etc. " + "The monitor index for UnityExplorer to use, if you have multiple. 0 is the default display, 1 is secondary, etc. " +
"Restart recommended when changing this setting. Make sure your extra monitors are the same resolution as your primary monitor.", "Restart recommended when changing this setting. Make sure your extra monitors are the same resolution as your primary monitor.",
0); 0);
Main_Navbar_Anchor = new ConfigElement<UIManager.VerticalAnchor>("Main Navbar Anchor", Force_Unlock_Mouse = new("Force Unlock Mouse",
"Force the Cursor to be unlocked (visible) when the UnityExplorer menu is open.",
true);
Force_Unlock_Mouse.OnValueChanged += (bool value) => UniverseLib.Config.ConfigManager.Force_Unlock_Mouse = value;
Force_Unlock_Toggle = new("Force Unlock Toggle Key",
"The keybind to toggle the 'Force Unlock Mouse' setting. Only usable when UnityExplorer is open.",
KeyCode.None);
Disable_EventSystem_Override = new("Disable EventSystem override",
"If enabled, UnityExplorer will not override the EventSystem from the game.\n<b>May require restart to take effect.</b>",
false);
Disable_EventSystem_Override.OnValueChanged += (bool value) => UniverseLib.Config.ConfigManager.Disable_EventSystem_Override = value;
Default_Output_Path = new("Default Output Path",
"The default output path when exporting things from UnityExplorer.",
Path.Combine(ExplorerCore.ExplorerFolder, "Output"));
DnSpy_Path = new("dnSpy Path",
"The full path to dnSpy.exe (64-bit).",
@"C:/Program Files/dnspy/dnSpy.exe");
Main_Navbar_Anchor = new("Main Navbar Anchor",
"The vertical anchor of the main UnityExplorer Navbar, in case you want to move it.", "The vertical anchor of the main UnityExplorer Navbar, in case you want to move it.",
UIManager.VerticalAnchor.Top); UIManager.VerticalAnchor.Top);
Log_Unity_Debug = new("Log Unity Debug",
"Should UnityEngine.Debug.Log messages be printed to UnityExplorer's log?",
false);
World_MouseInspect_Keybind = new("World Mouse-Inspect Keybind", World_MouseInspect_Keybind = new("World Mouse-Inspect Keybind",
"Optional keybind to being a World-mode Mouse Inspect.", "Optional keybind to being a World-mode Mouse Inspect.",
KeyCode.None); KeyCode.None);
@ -98,33 +128,13 @@ namespace UnityExplorer.Config
"Optional keybind to begin a UI-mode Mouse Inspect.", "Optional keybind to begin a UI-mode Mouse Inspect.",
KeyCode.None); KeyCode.None);
Force_Unlock_Mouse = new ConfigElement<bool>("Force Unlock Mouse", CSConsole_Assembly_Blacklist = new("CSharp Console Assembly Blacklist",
"Force the Cursor to be unlocked (visible) when the UnityExplorer menu is open.", "Use this to blacklist Assembly names from being referenced by the C# Console. Requires a Reset of the C# Console.\n" +
true); "Separate each Assembly with a semicolon ';'." +
Force_Unlock_Mouse.OnValueChanged += (bool value) => UniverseLib.Config.ConfigManager.Force_Unlock_Mouse = value; "For example, to blacklist Assembly-CSharp, you would add 'Assembly-CSharp;'",
"");
Force_Unlock_Toggle = new ConfigElement<KeyCode>("Force Unlock Toggle Key", Reflection_Signature_Blacklist = new("Member Signature Blacklist",
"The keybind to toggle the 'Force Unlock Mouse' setting. Only usable when UnityExplorer is open.",
KeyCode.None);
Disable_EventSystem_Override = new ConfigElement<bool>("Disable EventSystem override",
"If enabled, UnityExplorer will not override the EventSystem from the game.\n<b>May require restart to take effect.</b>",
false);
Disable_EventSystem_Override.OnValueChanged += (bool value) => UniverseLib.Config.ConfigManager.Disable_EventSystem_Override = value;
Log_Unity_Debug = new ConfigElement<bool>("Log Unity Debug",
"Should UnityEngine.Debug.Log messages be printed to UnityExplorer's log?",
false);
Default_Output_Path = new ConfigElement<string>("Default Output Path",
"The default output path when exporting things from UnityExplorer.",
Path.Combine(ExplorerCore.ExplorerFolder, "Output"));
Startup_Delay_Time = new ConfigElement<float>("Startup Delay Time",
"The delay on startup before the UI is created.",
1f);
Reflection_Signature_Blacklist = new ConfigElement<string>("Member Signature Blacklist",
"Use this to blacklist certain member signatures if they are known to cause a crash or other issues.\r\n" + "Use this to blacklist certain member signatures if they are known to cause a crash or other issues.\r\n" +
"Seperate signatures with a semicolon ';'.\r\n" + "Seperate signatures with a semicolon ';'.\r\n" +
"For example, to blacklist Camera.main, you would add 'UnityEngine.Camera.main;'", "For example, to blacklist Camera.main, you would add 'UnityEngine.Camera.main;'",

View File

@ -1,6 +1,4 @@
using System; namespace UnityExplorer.Config
namespace UnityExplorer.Config
{ {
public interface IConfigElement public interface IConfigElement
{ {

View File

@ -1,7 +1,4 @@
using System; using Tomlet;
using System.Collections.Generic;
using System.IO;
using Tomlet;
using Tomlet.Models; using Tomlet.Models;
using UnityExplorer.UI; using UnityExplorer.UI;

View File

@ -1,6 +1,10 @@
using UnityEngine; using UnityExplorer.UI;
#if CPP #if CPP
#if UNHOLLOWER
using UnhollowerRuntimeLib; using UnhollowerRuntimeLib;
#else
using Il2CppInterop.Runtime.Injection;
#endif
#endif #endif
namespace UnityExplorer namespace UnityExplorer
@ -29,5 +33,39 @@ namespace UnityExplorer
{ {
ExplorerCore.Update(); ExplorerCore.Update();
} }
// For editor, to clean up objects
internal void OnDestroy()
{
OnApplicationQuit();
}
internal bool quitting;
internal void OnApplicationQuit()
{
if (quitting) return;
quitting = true;
TryDestroy(UIManager.UIRoot?.transform.root.gameObject);
TryDestroy((typeof(Universe).Assembly.GetType("UniverseLib.UniversalBehaviour")
.GetProperty("Instance", BindingFlags.Static | BindingFlags.NonPublic)
.GetValue(null, null)
as Component).gameObject);
TryDestroy(this.gameObject);
}
internal void TryDestroy(GameObject obj)
{
try
{
if (obj)
Destroy(obj);
}
catch { }
}
} }
} }

View File

@ -1,12 +1,17 @@
using System; global using System;
using System.IO; global using System.Collections.Generic;
using UnityEngine; global using System.IO;
global using System.Linq;
global using System.Reflection;
global using UnityEngine;
global using UnityEngine.UI;
global using UniverseLib;
global using UniverseLib.Utility;
using UnityExplorer.Config; using UnityExplorer.Config;
using UnityExplorer.ObjectExplorer; using UnityExplorer.ObjectExplorer;
using UnityExplorer.Runtime; using UnityExplorer.Runtime;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UniverseLib;
using UniverseLib.Input; using UniverseLib.Input;
namespace UnityExplorer namespace UnityExplorer
@ -14,7 +19,7 @@ namespace UnityExplorer
public static class ExplorerCore public static class ExplorerCore
{ {
public const string NAME = "UnityExplorer"; public const string NAME = "UnityExplorer";
public const string VERSION = "4.7.6"; public const string VERSION = "4.9.0";
public const string AUTHOR = "Sinai"; public const string AUTHOR = "Sinai";
public const string GUID = "com.sinai.unityexplorer"; public const string GUID = "com.sinai.unityexplorer";
@ -72,7 +77,9 @@ namespace UnityExplorer
{ {
// check master toggle // check master toggle
if (InputManager.GetKeyDown(ConfigManager.Master_Toggle.Value)) if (InputManager.GetKeyDown(ConfigManager.Master_Toggle.Value))
{
UIManager.ShowMenu = !UIManager.ShowMenu; UIManager.ShowMenu = !UIManager.ShowMenu;
}
} }

View File

@ -1,6 +1,4 @@
using UnityEngine; using UniverseLib.UI;
using UnityEngine.UI;
using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.UI.Widgets.ScrollView;

View File

@ -1,7 +1,4 @@
using UnityEngine; using UniverseLib.UI;
using UnityEngine.UI;
using UnityExplorer.UI.Panels;
using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.UI.Widgets.ScrollView;

View File

@ -1,20 +1,12 @@
using HarmonyLib; using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CSConsole; using UnityExplorer.CSConsole;
using UnityExplorer.Runtime; using UnityExplorer.Runtime;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets;
using UnityExplorer.UI.Widgets.AutoComplete; using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets; using UniverseLib.UI.Widgets;
using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
namespace UnityExplorer.Hooks namespace UnityExplorer.Hooks
{ {
@ -39,6 +31,8 @@ namespace UnityExplorer.Hooks
internal static Type pendingGenericDefinition; internal static Type pendingGenericDefinition;
internal static MethodInfo pendingGenericMethod; internal static MethodInfo pendingGenericMethod;
public static bool PendingGeneric => pendingGenericDefinition != null || pendingGenericMethod != null;
// Hook Source Editor UI // Hook Source Editor UI
public static GameObject EditorRoot { get; private set; } public static GameObject EditorRoot { get; private set; }
public static Text EditingHookLabel { get; private set; } public static Text EditingHookLabel { get; private set; }
@ -156,11 +150,8 @@ namespace UnityExplorer.Hooks
} }
HookInstance hook = new(method); HookInstance hook = new(method);
if (hook.Enabled) HookList.hookedSignatures.Add(sig);
{ HookList.currentHooks.Add(sig, hook);
HookList.hookedSignatures.Add(sig);
HookList.currentHooks.Add(sig, hook);
}
AddHooksScrollPool.Refresh(true, false); AddHooksScrollPool.Refresh(true, false);
HookList.HooksScrollPool.Refresh(true, false); HookList.HooksScrollPool.Refresh(true, false);
@ -237,6 +228,8 @@ namespace UnityExplorer.Hooks
CurrentEditedHook = null; CurrentEditedHook = null;
HookManagerPanel.Instance.SetPage(HookManagerPanel.Pages.ClassMethodSelector); HookManagerPanel.Instance.SetPage(HookManagerPanel.Pages.ClassMethodSelector);
} }
HookList.HooksScrollPool.Refresh(true, false);
} }
// UI Construction // UI Construction

View File

@ -1,13 +1,7 @@
using HarmonyLib; using HarmonyLib;
using Mono.CSharp; using Mono.CSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
using UnityExplorer.CSConsole; using UnityExplorer.CSConsole;
using UniverseLib;
namespace UnityExplorer.Hooks namespace UnityExplorer.Hooks
{ {
@ -15,7 +9,6 @@ namespace UnityExplorer.Hooks
{ {
// Static // Static
//static readonly StringBuilder evalOutput = new();
static readonly StringBuilder evaluatorOutput; static readonly StringBuilder evaluatorOutput;
static readonly ScriptEvaluator scriptEvaluator = new(new StringWriter(evaluatorOutput = new StringBuilder())); static readonly ScriptEvaluator scriptEvaluator = new(new StringWriter(evaluatorOutput = new StringBuilder()));
@ -31,21 +24,22 @@ namespace UnityExplorer.Hooks
// Instance // Instance
public bool Enabled; public bool Enabled;
public MethodInfo TargetMethod; public MethodInfo TargetMethod;
public string PatchSourceCode; public string PatchSourceCode;
private readonly string shortSignature; readonly string signature;
private PatchProcessor patchProcessor; PatchProcessor patchProcessor;
private MethodInfo postfix; MethodInfo postfix;
private MethodInfo prefix; MethodInfo prefix;
private MethodInfo finalizer; MethodInfo finalizer;
private MethodInfo transpiler; MethodInfo transpiler;
public HookInstance(MethodInfo targetMethod) public HookInstance(MethodInfo targetMethod)
{ {
this.TargetMethod = targetMethod; this.TargetMethod = targetMethod;
this.shortSignature = TargetMethod.FullDescription(); this.signature = TargetMethod.FullDescription();
GenerateDefaultPatchSourceCode(targetMethod); GenerateDefaultPatchSourceCode(targetMethod);
@ -144,28 +138,29 @@ namespace UnityExplorer.Hooks
{ {
StringBuilder codeBuilder = new(); StringBuilder codeBuilder = new();
codeBuilder.Append("static void Postfix("); // System.Reflection.MethodBase __originalMethod codeBuilder.Append("static void Postfix(");
bool isStatic = targetMethod.IsStatic; bool isStatic = targetMethod.IsStatic;
List<string> arguments = new();
if (!isStatic) if (!isStatic)
codeBuilder.Append($"{FullDescriptionClean(targetMethod.DeclaringType)} __instance"); arguments.Add($"{FullDescriptionClean(targetMethod.DeclaringType)} __instance");
if (targetMethod.ReturnType != typeof(void)) if (targetMethod.ReturnType != typeof(void))
{ arguments.Add($"{FullDescriptionClean(targetMethod.ReturnType)} __result");
if (!isStatic)
codeBuilder.Append(", ");
codeBuilder.Append($"{FullDescriptionClean(targetMethod.ReturnType)} __result");
}
ParameterInfo[] parameters = targetMethod.GetParameters(); ParameterInfo[] parameters = targetMethod.GetParameters();
int paramIdx = 0; int paramIdx = 0;
foreach (ParameterInfo param in parameters) foreach (ParameterInfo param in parameters)
{ {
codeBuilder.Append($", {FullDescriptionClean(param.ParameterType)} __{paramIdx}"); arguments.Add($"{FullDescriptionClean(param.ParameterType)} __{paramIdx}");
paramIdx++; paramIdx++;
} }
codeBuilder.Append(string.Join(", ", arguments.ToArray()));
codeBuilder.Append(")\n"); codeBuilder.Append(")\n");
// Patch body // Patch body
@ -173,8 +168,8 @@ namespace UnityExplorer.Hooks
codeBuilder.AppendLine("{"); codeBuilder.AppendLine("{");
codeBuilder.AppendLine(" try {"); codeBuilder.AppendLine(" try {");
codeBuilder.AppendLine(" StringBuilder sb = new StringBuilder();"); codeBuilder.AppendLine(" StringBuilder sb = new StringBuilder();");
codeBuilder.AppendLine($" sb.AppendLine(\"---- Patched called ----\");"); codeBuilder.AppendLine($" sb.AppendLine(\"--------------------\");");
codeBuilder.AppendLine($" sb.AppendLine(\"{shortSignature}\");"); codeBuilder.AppendLine($" sb.AppendLine(\"{signature}\");");
if (!targetMethod.IsStatic) if (!targetMethod.IsStatic)
codeBuilder.AppendLine($" sb.Append(\"- __instance: \").AppendLine(__instance.ToString());"); codeBuilder.AppendLine($" sb.Append(\"- __instance: \").AppendLine(__instance.ToString());");
@ -206,15 +201,11 @@ namespace UnityExplorer.Hooks
codeBuilder.AppendLine($" UnityExplorer.ExplorerCore.Log(sb.ToString());"); codeBuilder.AppendLine($" UnityExplorer.ExplorerCore.Log(sb.ToString());");
codeBuilder.AppendLine(" }"); codeBuilder.AppendLine(" }");
codeBuilder.AppendLine(" catch (System.Exception ex) {"); codeBuilder.AppendLine(" catch (System.Exception ex) {");
codeBuilder.AppendLine($" UnityExplorer.ExplorerCore.LogWarning($\"Exception in patch of {shortSignature}:\\n{{ex}}\");"); codeBuilder.AppendLine($" UnityExplorer.ExplorerCore.LogWarning($\"Exception in patch of {signature}:\\n{{ex}}\");");
codeBuilder.AppendLine(" }"); codeBuilder.AppendLine(" }");
// End patch body
codeBuilder.AppendLine("}"); codeBuilder.AppendLine("}");
//ExplorerCore.Log(codeBuilder.ToString());
return PatchSourceCode = codeBuilder.ToString(); return PatchSourceCode = codeBuilder.ToString();
} }

View File

@ -1,15 +1,8 @@
using HarmonyLib; using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
namespace UnityExplorer.Hooks namespace UnityExplorer.Hooks
{ {
@ -47,6 +40,9 @@ namespace UnityExplorer.Hooks
public static void EditPatchClicked(int index) public static void EditPatchClicked(int index)
{ {
if (HookCreator.PendingGeneric)
HookManagerPanel.genericArgsHandler.Cancel();
HookManagerPanel.Instance.SetPage(HookManagerPanel.Pages.HookSourceEditor); HookManagerPanel.Instance.SetPage(HookManagerPanel.Pages.HookSourceEditor);
HookInstance hook = (HookInstance)currentHooks[index]; HookInstance hook = (HookInstance)currentHooks[index];
HookCreator.SetEditedHook(hook); HookCreator.SetEditedHook(hook);

View File

@ -1,28 +1,21 @@
using System; using System.Collections;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets; using UnityExplorer.UI.Widgets;
using UnityExplorer.UI.Widgets.AutoComplete; using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets; using UniverseLib.UI.Widgets;
using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
namespace UnityExplorer.Inspectors namespace UnityExplorer.Inspectors
{ {
public class GameObjectInspector : InspectorBase public class GameObjectInspector : InspectorBase
{ {
public GameObject GOTarget => Target as GameObject; public new GameObject Target => base.Target as GameObject;
public GameObject Content; public GameObject Content;
public GameObjectControls GOControls; public GameObjectControls Controls;
public TransformTree TransformTree; public TransformTree TransformTree;
private ScrollPool<TransformCell> transformScroll; private ScrollPool<TransformCell> transformScroll;
@ -38,10 +31,10 @@ namespace UnityExplorer.Inspectors
{ {
base.OnBorrowedFromPool(target); base.OnBorrowedFromPool(target);
Target = target as GameObject; base.Target = target as GameObject;
GOControls.UpdateGameObjectInfo(true, true); Controls.UpdateGameObjectInfo(true, true);
GOControls.UpdateTransformControlValues(true); Controls.TransformControl.UpdateTransformControlValues(true);
RuntimeHelper.StartCoroutine(InitCoroutine()); RuntimeHelper.StartCoroutine(InitCoroutine());
} }
@ -76,9 +69,9 @@ namespace UnityExplorer.Inspectors
public void OnTransformCellClicked(GameObject newTarget) public void OnTransformCellClicked(GameObject newTarget)
{ {
this.Target = newTarget; base.Target = newTarget;
GOControls.UpdateGameObjectInfo(true, true); Controls.UpdateGameObjectInfo(true, true);
GOControls.UpdateTransformControlValues(true); Controls.TransformControl.UpdateTransformControlValues(true);
TransformTree.RefreshData(true, false, true, false); TransformTree.RefreshData(true, false, true, false);
UpdateComponents(); UpdateComponents();
} }
@ -90,21 +83,21 @@ namespace UnityExplorer.Inspectors
if (!this.IsActive) if (!this.IsActive)
return; return;
if (Target.IsNullOrDestroyed(false)) if (base.Target.IsNullOrDestroyed(false))
{ {
InspectorManager.ReleaseInspector(this); InspectorManager.ReleaseInspector(this);
return; return;
} }
GOControls.UpdateVectorSlider(); Controls.UpdateVectorSlider();
GOControls.UpdateTransformControlValues(false); Controls.TransformControl.UpdateTransformControlValues(false);
// Slow update // Slow update
if (timeOfLastUpdate.OccuredEarlierThan(1)) if (timeOfLastUpdate.OccuredEarlierThan(1))
{ {
timeOfLastUpdate = Time.realtimeSinceStartup; timeOfLastUpdate = Time.realtimeSinceStartup;
GOControls.UpdateGameObjectInfo(false, false); Controls.UpdateGameObjectInfo(false, false);
TransformTree.RefreshData(true, false, false, false); TransformTree.RefreshData(true, false, false, false);
UpdateComponents(); UpdateComponents();
@ -115,12 +108,12 @@ namespace UnityExplorer.Inspectors
private IEnumerable<GameObject> GetTransformEntries() private IEnumerable<GameObject> GetTransformEntries()
{ {
if (!GOTarget) if (!Target)
return Enumerable.Empty<GameObject>(); return Enumerable.Empty<GameObject>();
cachedChildren.Clear(); cachedChildren.Clear();
for (int i = 0; i < GOTarget.transform.childCount; i++) for (int i = 0; i < Target.transform.childCount; i++)
cachedChildren.Add(GOTarget.transform.GetChild(i).gameObject); cachedChildren.Add(Target.transform.GetChild(i).gameObject);
return cachedChildren; return cachedChildren;
} }
@ -130,11 +123,11 @@ namespace UnityExplorer.Inspectors
private readonly List<bool> behaviourEnabledStates = new(); private readonly List<bool> behaviourEnabledStates = new();
// ComponentList.GetRootEntriesMethod // ComponentList.GetRootEntriesMethod
private List<Component> GetComponentEntries() => GOTarget ? componentEntries : Enumerable.Empty<Component>().ToList(); private List<Component> GetComponentEntries() => Target ? componentEntries : Enumerable.Empty<Component>().ToList();
public void UpdateComponents() public void UpdateComponents()
{ {
if (!GOTarget) if (!Target)
{ {
componentEntries.Clear(); componentEntries.Clear();
compInstanceIDs.Clear(); compInstanceIDs.Clear();
@ -146,8 +139,8 @@ namespace UnityExplorer.Inspectors
} }
// Check if we actually need to refresh the component cells or not. // Check if we actually need to refresh the component cells or not.
IEnumerable<Component> comps = GOTarget.GetComponents<Component>(); IEnumerable<Component> comps = Target.GetComponents<Component>();
IEnumerable<Behaviour> behaviours = GOTarget.GetComponents<Behaviour>(); IEnumerable<Behaviour> behaviours = Target.GetComponents<Behaviour>();
bool needRefresh = false; bool needRefresh = false;
@ -231,7 +224,7 @@ namespace UnityExplorer.Inspectors
private void OnAddChildClicked(string input) private void OnAddChildClicked(string input)
{ {
GameObject newObject = new(input); GameObject newObject = new(input);
newObject.transform.parent = GOTarget.transform; newObject.transform.parent = Target.transform;
TransformTree.RefreshData(true, false, true, false); TransformTree.RefreshData(true, false, true, false);
} }
@ -242,7 +235,7 @@ namespace UnityExplorer.Inspectors
{ {
try try
{ {
RuntimeHelper.AddComponent<Component>(GOTarget, type); RuntimeHelper.AddComponent<Component>(Target, type);
UpdateComponents(); UpdateComponents();
} }
catch (Exception ex) catch (Exception ex)
@ -270,7 +263,7 @@ namespace UnityExplorer.Inspectors
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(Content, spacing: 3, padTop: 2, padBottom: 2, padLeft: 2, padRight: 2); UIFactory.SetLayoutGroup<VerticalLayoutGroup>(Content, spacing: 3, padTop: 2, padBottom: 2, padLeft: 2, padRight: 2);
// Construct GO Controls // Construct GO Controls
GOControls = new GameObjectControls(this); Controls = new GameObjectControls(this);
ConstructLists(); ConstructLists();

View File

@ -1,696 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels;
using UniverseLib;
using UniverseLib.Input;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.Utility;
namespace UnityExplorer.Inspectors
{
public class GameObjectControls
{
public GameObjectInspector Parent;
private GameObject GOTarget => Parent.GOTarget;
// Top info
private ButtonRef ViewParentButton;
private InputFieldRef PathInput;
private InputFieldRef NameInput;
private Toggle ActiveSelfToggle;
private Text ActiveSelfText;
private Toggle IsStaticToggle;
private InputFieldRef SceneInput;
private InputFieldRef InstanceIDInput;
private InputFieldRef TagInput;
private Dropdown LayerDropdown;
private Dropdown FlagsDropdown;
// transform controls
private TransformControl PositionControl;
private TransformControl LocalPositionControl;
private TransformControl RotationControl;
private TransformControl ScaleControl;
private VectorSlider currentSlidingVectorControl;
private float currentVectorValue;
public GameObjectControls(GameObjectInspector parent)
{
this.Parent = parent;
ConstructTopInfo();
ConstructTransformControls();
}
private void OnCopyClicked()
{
ClipboardPanel.Copy(this.GOTarget);
}
#region GO Controls
private string lastGoName;
private string lastPath;
private bool lastParentState;
private int lastSceneHandle;
private string lastTag;
private int lastLayer;
private int lastFlags;
public void UpdateGameObjectInfo(bool firstUpdate, bool force)
{
if (firstUpdate)
{
InstanceIDInput.Text = GOTarget.GetInstanceID().ToString();
}
if (force || (!NameInput.Component.isFocused && GOTarget.name != lastGoName))
{
lastGoName = GOTarget.name;
Parent.Tab.TabText.text = $"[G] {GOTarget.name}";
NameInput.Text = GOTarget.name;
}
if (force || !PathInput.Component.isFocused)
{
string path = GOTarget.transform.GetTransformPath();
if (path != lastPath)
{
lastPath = path;
PathInput.Text = path;
}
}
if (force || GOTarget.transform.parent != lastParentState)
{
lastParentState = GOTarget.transform.parent;
ViewParentButton.Component.interactable = lastParentState;
if (lastParentState)
{
ViewParentButton.ButtonText.color = Color.white;
ViewParentButton.ButtonText.text = "◄ View Parent";
}
else
{
ViewParentButton.ButtonText.color = Color.grey;
ViewParentButton.ButtonText.text = "No parent";
}
}
if (force || GOTarget.activeSelf != ActiveSelfToggle.isOn)
{
ActiveSelfToggle.Set(GOTarget.activeSelf, false);
ActiveSelfText.color = ActiveSelfToggle.isOn ? Color.green : Color.red;
}
if (force || GOTarget.isStatic != IsStaticToggle.isOn)
{
IsStaticToggle.Set(GOTarget.isStatic, false);
}
if (force || GOTarget.scene.handle != lastSceneHandle)
{
lastSceneHandle = GOTarget.scene.handle;
SceneInput.Text = GOTarget.scene.IsValid() ? GOTarget.scene.name : "None (Asset/Resource)";
}
if (force || (!TagInput.Component.isFocused && GOTarget.tag != lastTag))
{
lastTag = GOTarget.tag;
TagInput.Text = lastTag;
}
if (force || (GOTarget.layer != lastLayer))
{
lastLayer = GOTarget.layer;
LayerDropdown.value = GOTarget.layer;
}
if (force || ((int)GOTarget.hideFlags != lastFlags))
{
lastFlags = (int)GOTarget.hideFlags;
FlagsDropdown.captionText.text = GOTarget.hideFlags.ToString();
}
}
private void OnViewParentClicked()
{
if (this.GOTarget && this.GOTarget.transform.parent)
{
Parent.OnTransformCellClicked(this.GOTarget.transform.parent.gameObject);
}
}
private void OnPathEndEdit(string input)
{
lastPath = input;
if (string.IsNullOrEmpty(input))
{
DoSetParent(null);
}
else
{
Transform parentToSet = null;
if (input.EndsWith("/"))
input = input.Remove(input.Length - 1);
// try the easy way
if (GameObject.Find(input) is GameObject found)
{
parentToSet = found.transform;
}
else
{
// look for inactive objects
string name = input.Split('/').Last();
UnityEngine.Object[] allObjects = RuntimeHelper.FindObjectsOfTypeAll(typeof(GameObject));
List<GameObject> shortList = new();
foreach (UnityEngine.Object obj in allObjects)
if (obj.name == name) shortList.Add(obj.TryCast<GameObject>());
foreach (GameObject go in shortList)
{
string path = go.transform.GetTransformPath(true);
if (path.EndsWith("/"))
path = path.Remove(path.Length - 1);
if (path == input)
{
parentToSet = go.transform;
break;
}
}
}
if (parentToSet)
DoSetParent(parentToSet);
else
{
ExplorerCore.LogWarning($"Could not find any GameObject name or path '{input}'!");
UpdateGameObjectInfo(false, true);
}
}
}
private void DoSetParent(Transform transform)
{
ExplorerCore.Log($"Setting target's transform parent to: {(transform == null ? "null" : $"'{transform.name}'")}");
if (GOTarget.GetComponent<RectTransform>())
GOTarget.transform.SetParent(transform, false);
else
GOTarget.transform.parent = transform;
UpdateGameObjectInfo(false, false);
UpdateTransformControlValues(false);
}
private void OnNameEndEdit(string value)
{
GOTarget.name = value;
UpdateGameObjectInfo(false, true);
}
private void OnActiveSelfToggled(bool value)
{
GOTarget.SetActive(value);
UpdateGameObjectInfo(false, true);
}
private void OnTagEndEdit(string value)
{
try
{
GOTarget.tag = value;
UpdateGameObjectInfo(false, true);
}
catch (Exception ex)
{
ExplorerCore.LogWarning($"Exception setting tag! {ex.ReflectionExToString()}");
}
}
private void OnExploreButtonClicked()
{
ObjectExplorerPanel panel = UIManager.GetPanel<UI.Panels.ObjectExplorerPanel>(UIManager.Panels.ObjectExplorer);
panel.SceneExplorer.JumpToTransform(this.Parent.GOTarget.transform);
}
private void OnLayerDropdownChanged(int value)
{
GOTarget.layer = value;
UpdateGameObjectInfo(false, true);
}
private void OnFlagsDropdownChanged(int value)
{
try
{
HideFlags enumVal = hideFlagsValues[FlagsDropdown.options[value].text];
GOTarget.hideFlags = enumVal;
UpdateGameObjectInfo(false, true);
}
catch (Exception ex)
{
ExplorerCore.LogWarning($"Exception setting hideFlags: {ex}");
}
}
private void OnDestroyClicked()
{
GameObject.Destroy(this.GOTarget);
InspectorManager.ReleaseInspector(Parent);
}
private void OnInstantiateClicked()
{
GameObject clone = GameObject.Instantiate(this.GOTarget);
InspectorManager.Inspect(clone);
}
#endregion
#region Transform Controls
private enum TransformType { Position, LocalPosition, Rotation, Scale }
private class TransformControl
{
public TransformType Type;
public InputFieldRef Input;
public TransformControl(TransformType type, InputFieldRef input)
{
this.Type = type;
this.Input = input;
}
}
private class VectorSlider
{
public int axis;
public Slider slider;
public TransformControl parentControl;
public VectorSlider(int axis, Slider slider, TransformControl parentControl)
{
this.axis = axis;
this.slider = slider;
this.parentControl = parentControl;
}
}
private Vector3 lastPosValue;
private Vector3 lastLocalValue;
private Quaternion lastRotValue;
private Vector3 lastScaleValue;
public void UpdateTransformControlValues(bool force)
{
Transform transform = GOTarget.transform;
if (force || (!PositionControl.Input.Component.isFocused && lastPosValue != transform.position))
{
PositionControl.Input.Text = ParseUtility.ToStringForInput(transform.position, typeof(Vector3));
lastPosValue = transform.position;
}
if (force || (!LocalPositionControl.Input.Component.isFocused && lastLocalValue != transform.localPosition))
{
LocalPositionControl.Input.Text = ParseUtility.ToStringForInput(transform.localPosition, typeof(Vector3));
lastLocalValue = transform.localPosition;
}
if (force || (!RotationControl.Input.Component.isFocused && lastRotValue != transform.localRotation))
{
RotationControl.Input.Text = ParseUtility.ToStringForInput(transform.localRotation, typeof(Quaternion));
lastRotValue = transform.localRotation;
}
if (force || (!ScaleControl.Input.Component.isFocused && lastScaleValue != transform.localScale))
{
ScaleControl.Input.Text = ParseUtility.ToStringForInput(transform.localScale, typeof(Vector3));
lastScaleValue = transform.localScale;
}
}
private void OnTransformInputEndEdit(TransformType type, string input)
{
switch (type)
{
case TransformType.Position:
{
if (ParseUtility.TryParse(input, typeof(Vector3), out object boxed, out _))
GOTarget.transform.position = (Vector3)boxed;
}
break;
case TransformType.LocalPosition:
{
if (ParseUtility.TryParse(input, typeof(Vector3), out object boxed, out _))
GOTarget.transform.localPosition = (Vector3)boxed;
}
break;
case TransformType.Rotation:
{
if (ParseUtility.TryParse(input, typeof(Quaternion), out object boxed, out _))
GOTarget.transform.localRotation = (Quaternion)boxed;
}
break;
case TransformType.Scale:
{
if (ParseUtility.TryParse(input, typeof(Vector3), out object boxed, out _))
GOTarget.transform.localScale = (Vector3)boxed;
}
break;
}
UpdateTransformControlValues(true);
}
private void OnVectorSliderChanged(VectorSlider slider, float value)
{
if (value == 0f)
{
currentSlidingVectorControl = null;
}
else
{
currentSlidingVectorControl = slider;
currentVectorValue = value;
}
}
public void UpdateVectorSlider()
{
if (currentSlidingVectorControl == null)
return;
if (!InputManager.GetMouseButton(0))
{
currentSlidingVectorControl.slider.value = 0f;
currentSlidingVectorControl = null;
currentVectorValue = 0f;
return;
}
Transform transform = GOTarget.transform;
Vector3 vector = Vector2.zero;
switch (currentSlidingVectorControl.parentControl.Type)
{
case TransformType.Position:
vector = transform.position; break;
case TransformType.LocalPosition:
vector = transform.localPosition; break;
case TransformType.Rotation:
vector = transform.eulerAngles; break;
case TransformType.Scale:
vector = transform.localScale; break;
}
// apply vector value change
switch (currentSlidingVectorControl.axis)
{
case 0:
vector.x += currentVectorValue; break;
case 1:
vector.y += currentVectorValue; break;
case 2:
vector.z += currentVectorValue; break;
}
// set vector back to transform
switch (currentSlidingVectorControl.parentControl.Type)
{
case TransformType.Position:
transform.position = vector; break;
case TransformType.LocalPosition:
transform.localPosition = vector; break;
case TransformType.Rotation:
transform.eulerAngles = vector; break;
case TransformType.Scale:
transform.localScale = vector; break;
}
UpdateTransformControlValues(false);
}
#endregion
#region GO Controls UI Construction
private void ConstructTopInfo()
{
GameObject topInfoHolder = UIFactory.CreateVerticalGroup(Parent.Content, "TopInfoHolder", false, false, true, true, 3,
new Vector4(3, 3, 3, 3), new Color(0.1f, 0.1f, 0.1f), TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(topInfoHolder, minHeight: 100, flexibleWidth: 9999);
topInfoHolder.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
// first row (parent, path)
GameObject firstRow = UIFactory.CreateUIObject("ParentRow", topInfoHolder);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(firstRow, false, false, true, true, 5, 0, 0, 0, 0, default);
UIFactory.SetLayoutElement(firstRow, minHeight: 25, flexibleWidth: 9999);
ViewParentButton = UIFactory.CreateButton(firstRow, "ViewParentButton", "◄ View Parent", new Color(0.2f, 0.2f, 0.2f));
ViewParentButton.ButtonText.fontSize = 13;
UIFactory.SetLayoutElement(ViewParentButton.Component.gameObject, minHeight: 25, minWidth: 100);
ViewParentButton.OnClick += OnViewParentClicked;
this.PathInput = UIFactory.CreateInputField(firstRow, "PathInput", "...");
PathInput.Component.textComponent.color = Color.grey;
PathInput.Component.textComponent.fontSize = 14;
UIFactory.SetLayoutElement(PathInput.UIRoot, minHeight: 25, minWidth: 100, flexibleWidth: 9999);
PathInput.Component.lineType = InputField.LineType.MultiLineSubmit;
ButtonRef copyButton = UIFactory.CreateButton(firstRow, "CopyButton", "Copy to Clipboard", new Color(0.2f, 0.2f, 0.2f, 1));
copyButton.ButtonText.color = Color.yellow;
UIFactory.SetLayoutElement(copyButton.Component.gameObject, minHeight: 25, minWidth: 120);
copyButton.OnClick += OnCopyClicked;
//var pathApplyBtn = UIFactory.CreateButton(firstRow, "PathButton", "Set Parent Path", new Color(0.2f, 0.2f, 0.2f));
//UIFactory.SetLayoutElement(pathApplyBtn.Component.gameObject, minHeight: 25, minWidth: 120);
//pathApplyBtn.OnClick += () => { OnPathEndEdit(PathInput.Text); };
PathInput.Component.GetOnEndEdit().AddListener((string val) => { OnPathEndEdit(val); });
// Title and update row
GameObject titleRow = UIFactory.CreateUIObject("TitleRow", topInfoHolder);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(titleRow, false, false, true, true, 5);
Text titleLabel = UIFactory.CreateLabel(titleRow, "Title", SignatureHighlighter.Parse(typeof(GameObject), false),
TextAnchor.MiddleLeft, fontSize: 17);
UIFactory.SetLayoutElement(titleLabel.gameObject, minHeight: 30, minWidth: 100);
// name
NameInput = UIFactory.CreateInputField(titleRow, "NameInput", "untitled");
UIFactory.SetLayoutElement(NameInput.Component.gameObject, minHeight: 30, minWidth: 100, flexibleWidth: 9999);
NameInput.Component.textComponent.fontSize = 15;
NameInput.Component.GetOnEndEdit().AddListener((string val) => { OnNameEndEdit(val); });
// second row (toggles, instanceID, tag, buttons)
GameObject secondRow = UIFactory.CreateUIObject("ParentRow", topInfoHolder);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(secondRow, false, false, true, true, 5, 0, 0, 0, 0, default);
UIFactory.SetLayoutElement(secondRow, minHeight: 25, flexibleWidth: 9999);
// activeSelf
GameObject activeToggleObj = UIFactory.CreateToggle(secondRow, "ActiveSelf", out ActiveSelfToggle, out ActiveSelfText);
UIFactory.SetLayoutElement(activeToggleObj, minHeight: 25, minWidth: 100);
ActiveSelfText.text = "ActiveSelf";
ActiveSelfToggle.onValueChanged.AddListener(OnActiveSelfToggled);
// isStatic
GameObject isStaticObj = UIFactory.CreateToggle(secondRow, "IsStatic", out IsStaticToggle, out Text staticText);
UIFactory.SetLayoutElement(isStaticObj, minHeight: 25, minWidth: 80);
staticText.text = "IsStatic";
staticText.color = Color.grey;
IsStaticToggle.interactable = false;
// InstanceID
Text instanceIdLabel = UIFactory.CreateLabel(secondRow, "InstanceIDLabel", "Instance ID:", TextAnchor.MiddleRight, Color.grey);
UIFactory.SetLayoutElement(instanceIdLabel.gameObject, minHeight: 25, minWidth: 90);
InstanceIDInput = UIFactory.CreateInputField(secondRow, "InstanceIDInput", "error");
UIFactory.SetLayoutElement(InstanceIDInput.Component.gameObject, minHeight: 25, minWidth: 110);
InstanceIDInput.Component.textComponent.color = Color.grey;
InstanceIDInput.Component.readOnly = true;
//Tag
Text tagLabel = UIFactory.CreateLabel(secondRow, "TagLabel", "Tag:", TextAnchor.MiddleRight, Color.grey);
UIFactory.SetLayoutElement(tagLabel.gameObject, minHeight: 25, minWidth: 40);
TagInput = UIFactory.CreateInputField(secondRow, "TagInput", "none");
UIFactory.SetLayoutElement(TagInput.Component.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 999);
TagInput.Component.textComponent.color = Color.white;
TagInput.Component.GetOnEndEdit().AddListener((string val) => { OnTagEndEdit(val); });
// Instantiate
ButtonRef instantiateBtn = UIFactory.CreateButton(secondRow, "InstantiateBtn", "Instantiate", new Color(0.2f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(instantiateBtn.Component.gameObject, minHeight: 25, minWidth: 120);
instantiateBtn.OnClick += OnInstantiateClicked;
// Destroy
ButtonRef destroyBtn = UIFactory.CreateButton(secondRow, "DestroyBtn", "Destroy", new Color(0.3f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(destroyBtn.Component.gameObject, minHeight: 25, minWidth: 80);
destroyBtn.OnClick += OnDestroyClicked;
// third row (scene, layer, flags)
GameObject thirdrow = UIFactory.CreateUIObject("ParentRow", topInfoHolder);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(thirdrow, false, false, true, true, 5, 0, 0, 0, 0, default);
UIFactory.SetLayoutElement(thirdrow, minHeight: 25, flexibleWidth: 9999);
// Inspect in Explorer button
ButtonRef explorerBtn = UIFactory.CreateButton(thirdrow, "ExploreBtn", "Show in Explorer", new Color(0.15f, 0.15f, 0.15f));
UIFactory.SetLayoutElement(explorerBtn.Component.gameObject, minHeight: 25, minWidth: 100);
explorerBtn.ButtonText.fontSize = 12;
explorerBtn.OnClick += OnExploreButtonClicked;
// Scene
Text sceneLabel = UIFactory.CreateLabel(thirdrow, "SceneLabel", "Scene:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(sceneLabel.gameObject, minHeight: 25, minWidth: 50);
SceneInput = UIFactory.CreateInputField(thirdrow, "SceneInput", "untitled");
UIFactory.SetLayoutElement(SceneInput.Component.gameObject, minHeight: 25, minWidth: 120, flexibleWidth: 999);
SceneInput.Component.readOnly = true;
SceneInput.Component.textComponent.color = new Color(0.7f, 0.7f, 0.7f);
// Layer
Text layerLabel = UIFactory.CreateLabel(thirdrow, "LayerLabel", "Layer:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(layerLabel.gameObject, minHeight: 25, minWidth: 50);
GameObject layerDrop = UIFactory.CreateDropdown(thirdrow, "LayerDropdown", out LayerDropdown, "0", 14, OnLayerDropdownChanged);
UIFactory.SetLayoutElement(layerDrop, minHeight: 25, minWidth: 110, flexibleWidth: 999);
LayerDropdown.captionText.color = SignatureHighlighter.EnumGreen;
if (layerToNames == null)
GetLayerNames();
foreach (string name in layerToNames)
LayerDropdown.options.Add(new Dropdown.OptionData(name));
LayerDropdown.value = 0;
LayerDropdown.RefreshShownValue();
// Flags
Text flagsLabel = UIFactory.CreateLabel(thirdrow, "FlagsLabel", "Flags:", TextAnchor.MiddleRight, Color.grey);
UIFactory.SetLayoutElement(flagsLabel.gameObject, minHeight: 25, minWidth: 50);
GameObject flagsDrop = UIFactory.CreateDropdown(thirdrow, "FlagsDropdown", out FlagsDropdown, "None", 14, OnFlagsDropdownChanged);
FlagsDropdown.captionText.color = SignatureHighlighter.EnumGreen;
UIFactory.SetLayoutElement(flagsDrop, minHeight: 25, minWidth: 135, flexibleWidth: 999);
if (hideFlagsValues == null)
GetHideFlagNames();
foreach (string name in hideFlagsValues.Keys)
FlagsDropdown.options.Add(new Dropdown.OptionData(name));
FlagsDropdown.value = 0;
FlagsDropdown.RefreshShownValue();
}
private static List<string> layerToNames;
private static void GetLayerNames()
{
layerToNames = new List<string>();
for (int i = 0; i < 32; i++)
{
string name = RuntimeHelper.LayerToName(i);
if (string.IsNullOrEmpty(name))
name = i.ToString();
layerToNames.Add(name);
}
}
private static Dictionary<string, HideFlags> hideFlagsValues;
private static void GetHideFlagNames()
{
hideFlagsValues = new Dictionary<string, HideFlags>();
Array names = Enum.GetValues(typeof(HideFlags));
foreach (HideFlags value in names)
{
hideFlagsValues.Add(value.ToString(), value);
}
}
#endregion
#region Transform Controls UI Construction
private void ConstructTransformControls()
{
GameObject transformGroup = UIFactory.CreateVerticalGroup(Parent.Content, "TransformControls", false, false, true, true, 2,
new Vector4(2, 2, 0, 0), new Color(0.1f, 0.1f, 0.1f));
UIFactory.SetLayoutElement(transformGroup, minHeight: 100, flexibleWidth: 9999);
//transformGroup.SetActive(false);
//var groupRect = transformGroup.GetComponent<RectTransform>();
//groupRect.anchorMin = new Vector2(0, 1);
//groupRect.anchorMax = new Vector2(1, 1);
//groupRect.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Top, 0, 100);
PositionControl = AddTransformRow(transformGroup, "Position:", TransformType.Position);
LocalPositionControl = AddTransformRow(transformGroup, "Local Position:", TransformType.LocalPosition);
RotationControl = AddTransformRow(transformGroup, "Rotation:", TransformType.Rotation);
ScaleControl = AddTransformRow(transformGroup, "Scale:", TransformType.Scale);
}
private TransformControl AddTransformRow(GameObject transformGroup, string title, TransformType type)
{
GameObject rowObj = UIFactory.CreateUIObject("Row_" + title, transformGroup);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(rowObj, false, false, true, true, 5, 0, 0, 0, 0, default);
UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleWidth: 9999);
Text titleLabel = UIFactory.CreateLabel(rowObj, "PositionLabel", title, TextAnchor.MiddleRight, Color.grey);
UIFactory.SetLayoutElement(titleLabel.gameObject, minHeight: 25, minWidth: 110);
InputFieldRef inputField = UIFactory.CreateInputField(rowObj, "InputField", "...");
UIFactory.SetLayoutElement(inputField.Component.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 999);
inputField.Component.GetOnEndEdit().AddListener((string value) => { OnTransformInputEndEdit(type, value); });
TransformControl control = new(type, inputField);
AddVectorAxisSlider(rowObj, "X", 0, control);
AddVectorAxisSlider(rowObj, "Y", 1, control);
AddVectorAxisSlider(rowObj, "Z", 2, control);
return control;
}
private VectorSlider AddVectorAxisSlider(GameObject parent, string title, int axis, TransformControl control)
{
Text label = UIFactory.CreateLabel(parent, "Label_" + title, title + ":", TextAnchor.MiddleRight, Color.grey);
UIFactory.SetLayoutElement(label.gameObject, minHeight: 25, minWidth: 30);
GameObject sliderObj = UIFactory.CreateSlider(parent, "Slider_" + title, out Slider slider);
UIFactory.SetLayoutElement(sliderObj, minHeight: 25, minWidth: 120, flexibleWidth: 0);
slider.m_FillImage.color = Color.clear;
slider.minValue = -1;
slider.maxValue = 1;
VectorSlider sliderControl = new(axis, slider, control);
slider.onValueChanged.AddListener((float val) =>
{
OnVectorSliderChanged(sliderControl, val);
});
return sliderControl;
}
#endregion
}
}

View File

@ -1,8 +1,4 @@
using System; using UnityExplorer.UI.Panels;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI.Panels;
using UniverseLib;
using UniverseLib.UI.ObjectPool; using UniverseLib.UI.ObjectPool;
namespace UnityExplorer.Inspectors namespace UnityExplorer.Inspectors

View File

@ -1,14 +1,8 @@
using System; using UnityExplorer.CacheObject;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityExplorer.CacheObject;
using UnityExplorer.Inspectors; using UnityExplorer.Inspectors;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UniverseLib;
using UniverseLib.UI.ObjectPool; using UniverseLib.UI.ObjectPool;
using UniverseLib.Utility;
namespace UnityExplorer namespace UnityExplorer
{ {

View File

@ -1,7 +1,4 @@
using UnityEngine; using UniverseLib.UI;
using UnityEngine.UI;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.UI.ObjectPool; using UniverseLib.UI.ObjectPool;

View File

@ -1,13 +1,10 @@
using UnityEngine; using UnityExplorer.Config;
using UnityEngine.UI;
using UnityExplorer.Config;
using UnityExplorer.Inspectors.MouseInspectors; using UnityExplorer.Inspectors.MouseInspectors;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UniverseLib.Input; using UniverseLib.Input;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Panels; using UniverseLib.UI.Panels;
using UniverseLib.Utility;
namespace UnityExplorer.Inspectors namespace UnityExplorer.Inspectors
{ {
@ -113,17 +110,11 @@ namespace UnityExplorer.Inspectors
public bool TryUpdate() public bool TryUpdate()
{ {
if (ConfigManager.World_MouseInspect_Keybind.Value != KeyCode.None) if (InputManager.GetKeyDown(ConfigManager.World_MouseInspect_Keybind.Value))
{ Instance.StartInspect(MouseInspectMode.World);
if (InputManager.GetKeyDown(ConfigManager.World_MouseInspect_Keybind.Value))
Instance.StartInspect(MouseInspectMode.World);
}
if (ConfigManager.World_MouseInspect_Keybind.Value != KeyCode.None) if (InputManager.GetKeyDown(ConfigManager.UI_MouseInspect_Keybind.Value))
{ Instance.StartInspect(MouseInspectMode.UI);
if (InputManager.GetKeyDown(ConfigManager.World_MouseInspect_Keybind.Value))
Instance.StartInspect(MouseInspectMode.World);
}
if (Inspecting) if (Inspecting)
UpdateInspect(); UpdateInspect();

View File

@ -1,6 +1,4 @@
using UnityEngine; namespace UnityExplorer.Inspectors.MouseInspectors
namespace UnityExplorer.Inspectors.MouseInspectors
{ {
public abstract class MouseInspectorBase public abstract class MouseInspectorBase
{ {

View File

@ -1,12 +1,7 @@
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UniverseLib;
namespace UnityExplorer.Inspectors.MouseInspectors namespace UnityExplorer.Inspectors.MouseInspectors
{ {

View File

@ -1,7 +1,4 @@
using UnityEngine; namespace UnityExplorer.Inspectors.MouseInspectors
using UniverseLib.Utility;
namespace UnityExplorer.Inspectors.MouseInspectors
{ {
public class WorldInspector : MouseInspectorBase public class WorldInspector : MouseInspectorBase
{ {

View File

@ -1,21 +1,16 @@
using System; using System.Collections;
using System.Collections; using System.Diagnostics;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Reflection.Emit; using System.Reflection.Emit;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CacheObject; using UnityExplorer.CacheObject;
using UnityExplorer.CacheObject.Views; using UnityExplorer.CacheObject.Views;
using UnityExplorer.Config;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets; using UnityExplorer.UI.Widgets;
using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.UI.ObjectPool; using UniverseLib.UI.ObjectPool;
using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
namespace UnityExplorer.Inspectors namespace UnityExplorer.Inspectors
{ {
@ -33,7 +28,6 @@ namespace UnityExplorer.Inspectors
public class ReflectionInspector : InspectorBase, ICellPoolDataSource<CacheMemberCell>, ICacheObjectController public class ReflectionInspector : InspectorBase, ICellPoolDataSource<CacheMemberCell>, ICacheObjectController
{ {
public CacheObjectBase ParentCacheObject { get; set; } public CacheObjectBase ParentCacheObject { get; set; }
//public Type TargetType { get; private set; }
public bool StaticOnly { get; internal set; } public bool StaticOnly { get; internal set; }
public bool CanWrite => true; public bool CanWrite => true;
@ -73,6 +67,8 @@ namespace UnityExplorer.Inspectors
Text assemblyText; Text assemblyText;
Toggle autoUpdateToggle; Toggle autoUpdateToggle;
ButtonRef dnSpyButton;
ButtonRef makeGenericButton; ButtonRef makeGenericButton;
GenericConstructorWidget genericConstructor; GenericConstructorWidget genericConstructor;
@ -155,9 +151,15 @@ namespace UnityExplorer.Inspectors
string asmText; string asmText;
if (TargetType.Assembly is AssemblyBuilder || string.IsNullOrEmpty(TargetType.Assembly.Location)) if (TargetType.Assembly is AssemblyBuilder || string.IsNullOrEmpty(TargetType.Assembly.Location))
{
asmText = $"{TargetType.Assembly.GetName().Name} <color=grey><i>(in memory)</i></color>"; asmText = $"{TargetType.Assembly.GetName().Name} <color=grey><i>(in memory)</i></color>";
dnSpyButton.GameObject.SetActive(false);
}
else else
{
asmText = Path.GetFileName(TargetType.Assembly.Location); asmText = Path.GetFileName(TargetType.Assembly.Location);
dnSpyButton.GameObject.SetActive(true);
}
assemblyText.text = $"<color=grey>Assembly:</color> {asmText}"; assemblyText.text = $"<color=grey>Assembly:</color> {asmText}";
// Unity object helper widget // Unity object helper widget
@ -350,6 +352,25 @@ namespace UnityExplorer.Inspectors
ClipboardPanel.Copy(this.Target ?? this.TargetType); ClipboardPanel.Copy(this.Target ?? this.TargetType);
} }
void OnDnSpyButtonClicked()
{
string path = ConfigManager.DnSpy_Path.Value;
if (File.Exists(path) && path.EndsWith("dnspy.exe", StringComparison.OrdinalIgnoreCase))
{
Type type = TargetType;
// if constructed generic type, use the generic type definition
if (type.IsGenericType && !type.IsGenericTypeDefinition)
type = type.GetGenericTypeDefinition();
string args = $"\"{type.Assembly.Location}\" --select T:{type.FullName}";
Process.Start(path, args);
}
else
{
Notification.ShowMessage($"Please set a valid dnSpy path in UnityExplorer Settings.");
}
}
void OnMakeGenericClicked() void OnMakeGenericClicked()
{ {
ContentRoot.SetActive(false); ContentRoot.SetActive(false);
@ -425,10 +446,21 @@ namespace UnityExplorer.Inspectors
UIFactory.SetLayoutElement(copyButton.Component.gameObject, minHeight: 25, minWidth: 120, flexibleWidth: 0); UIFactory.SetLayoutElement(copyButton.Component.gameObject, minHeight: 25, minWidth: 120, flexibleWidth: 0);
copyButton.OnClick += OnCopyClicked; copyButton.OnClick += OnCopyClicked;
assemblyText = UIFactory.CreateLabel(UIRoot, "AssemblyLabel", "not set", TextAnchor.MiddleLeft); // Assembly row
GameObject asmRow = UIFactory.CreateHorizontalGroup(UIRoot, "AssemblyRow", false, false, true, true, 5, default, new(1, 1, 1, 0));
UIFactory.SetLayoutElement(asmRow, flexibleWidth: 9999, minHeight: 25);
assemblyText = UIFactory.CreateLabel(asmRow, "AssemblyLabel", "not set", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(assemblyText.gameObject, minHeight: 25, flexibleWidth: 9999); UIFactory.SetLayoutElement(assemblyText.gameObject, minHeight: 25, flexibleWidth: 9999);
ContentRoot = UIFactory.CreateVerticalGroup(UIRoot, "MemberHolder", false, false, true, true, 5, new Vector4(2, 2, 2, 2), dnSpyButton = UIFactory.CreateButton(asmRow, "DnSpyButton", "View in dnSpy");
UIFactory.SetLayoutElement(dnSpyButton.GameObject, minWidth: 120, minHeight: 25);
dnSpyButton.OnClick += OnDnSpyButtonClicked;
// Content
ContentRoot = UIFactory.CreateVerticalGroup(UIRoot, "ContentRoot", false, false, true, true, 5, new Vector4(2, 2, 2, 2),
new Color(0.12f, 0.12f, 0.12f)); new Color(0.12f, 0.12f, 0.12f));
UIFactory.SetLayoutElement(ContentRoot, flexibleWidth: 9999, flexibleHeight: 9999); UIFactory.SetLayoutElement(ContentRoot, flexibleWidth: 9999, flexibleHeight: 9999);

View File

@ -1,7 +1,5 @@
#if BIE #if BIE
using BepInEx.Configuration; using BepInEx.Configuration;
using System;
using System.Collections.Generic;
using UnityExplorer.Config; using UnityExplorer.Config;
namespace UnityExplorer.Loader.BIE namespace UnityExplorer.Loader.BIE

View File

@ -2,13 +2,10 @@
using BepInEx; using BepInEx;
using BepInEx.Logging; using BepInEx.Logging;
using HarmonyLib; using HarmonyLib;
using System;
using System.IO;
using UnityExplorer.Config; using UnityExplorer.Config;
using UnityExplorer.Loader.BIE; using UnityExplorer.Loader.BIE;
#if CPP #if CPP
using BepInEx.IL2CPP; using BepInEx.IL2CPP;
using UnhollowerRuntimeLib;
#endif #endif
namespace UnityExplorer namespace UnityExplorer
@ -31,8 +28,14 @@ namespace UnityExplorer
#else #else
=> Log; => Log;
#endif #endif
const string IL2CPP_LIBS_FOLDER =
public string UnhollowedModulesFolder => Path.Combine(Paths.BepInExRootPath, "unhollowed"); #if UNHOLLOWER
"unhollowed"
#else
"interop"
#endif
;
public string UnhollowedModulesFolder => Path.Combine(Paths.BepInExRootPath, IL2CPP_LIBS_FOLDER);
public ConfigHandler ConfigHandler => _configHandler; public ConfigHandler ConfigHandler => _configHandler;
private BepInExConfigHandler _configHandler; private BepInExConfigHandler _configHandler;

View File

@ -1,5 +1,4 @@
using System; using UnityExplorer.Config;
using UnityExplorer.Config;
namespace UnityExplorer namespace UnityExplorer
{ {

View File

@ -6,27 +6,53 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityExplorer.Config;
using UnityExplorer.UI;
using UniverseLib;
namespace UnityExplorer.Loader.Standalone namespace UnityExplorer.Loader.Standalone
{ {
public class ExplorerEditorBehaviour : MonoBehaviour public class ExplorerEditorBehaviour : MonoBehaviour
{ {
internal static ExplorerEditorBehaviour Instance { get; private set; }
public bool Hide_On_Startup = true;
public KeyCode Master_Toggle_Key = KeyCode.F7;
public UIManager.VerticalAnchor Main_Navbar_Anchor = UIManager.VerticalAnchor.Top;
public bool Log_Unity_Debug = false;
public float Startup_Delay_Time = 1f;
public KeyCode World_MouseInspect_Keybind;
public KeyCode UI_MouseInspect_Keybind;
public bool Force_Unlock_Mouse = true;
public KeyCode Force_Unlock_Toggle;
public bool Disable_EventSystem_Override;
internal void Awake() internal void Awake()
{ {
Instance = this;
ExplorerEditorLoader.Initialize(); ExplorerEditorLoader.Initialize();
DontDestroyOnLoad(this); DontDestroyOnLoad(this);
this.gameObject.hideFlags = HideFlags.HideAndDontSave; this.gameObject.hideFlags = HideFlags.HideAndDontSave;
} }
internal void OnDestroy()
{
OnApplicationQuit();
}
internal void OnApplicationQuit() internal void OnApplicationQuit()
{ {
if (UI.UIManager.UIRoot) Destroy(this.gameObject);
Destroy(UI.UIManager.UIRoot.transform.root.gameObject); }
internal void LoadConfigs()
{
ConfigManager.Hide_On_Startup.Value = this.Hide_On_Startup;
ConfigManager.Master_Toggle.Value = this.Master_Toggle_Key;
ConfigManager.Main_Navbar_Anchor.Value = this.Main_Navbar_Anchor;
ConfigManager.Log_Unity_Debug.Value = this.Log_Unity_Debug;
ConfigManager.Startup_Delay_Time.Value = this.Startup_Delay_Time;
ConfigManager.World_MouseInspect_Keybind.Value = this.World_MouseInspect_Keybind;
ConfigManager.UI_MouseInspect_Keybind.Value = this.UI_MouseInspect_Keybind;
ConfigManager.Force_Unlock_Mouse.Value = this.Force_Unlock_Mouse;
ConfigManager.Force_Unlock_Toggle.Value = this.Force_Unlock_Toggle;
ConfigManager.Disable_EventSystem_Override.Value = this.Disable_EventSystem_Override;
} }
} }
} }

View File

@ -36,7 +36,7 @@ namespace UnityExplorer.Loader.Standalone
protected override void CheckExplorerFolder() protected override void CheckExplorerFolder()
{ {
if (explorerFolderDest == null) if (explorerFolderDest == null)
explorerFolderDest = Application.dataPath; explorerFolderDest = Path.GetDirectoryName(Application.dataPath);
} }
} }
} }

View File

@ -1,16 +1,9 @@
using System; using UnityExplorer.UI.Panels;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets.AutoComplete; using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets.ButtonList; using UniverseLib.UI.Widgets.ButtonList;
using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
namespace UnityExplorer.ObjectExplorer namespace UnityExplorer.ObjectExplorer
{ {
@ -34,12 +27,15 @@ namespace UnityExplorer.ObjectExplorer
private ScrollPool<ButtonCell> resultsScrollPool; private ScrollPool<ButtonCell> resultsScrollPool;
private List<object> currentResults = new(); private List<object> currentResults = new();
//public TypeCompleter typeAutocompleter;
public TypeCompleter unityObjectTypeCompleter;
public TypeCompleter allTypesCompleter;
public override GameObject UIRoot => uiRoot; public override GameObject UIRoot => uiRoot;
private GameObject uiRoot; private GameObject uiRoot;
private GameObject sceneFilterRow; private GameObject sceneFilterRow;
private GameObject childFilterRow; private GameObject childFilterRow;
private GameObject classInputRow; private GameObject classInputRow;
public TypeCompleter typeAutocompleter;
private GameObject nameInputRow; private GameObject nameInputRow;
private InputFieldRef nameInputField; private InputFieldRef nameInputField;
private Text resultsLabel; private Text resultsLabel;
@ -98,14 +94,18 @@ namespace UnityExplorer.ObjectExplorer
nameInputRow.SetActive(context == SearchContext.UnityObject); nameInputRow.SetActive(context == SearchContext.UnityObject);
if (context == SearchContext.Class) switch (context)
typeAutocompleter.AllTypes = true;
else
{ {
typeAutocompleter.BaseType = context == SearchContext.UnityObject ? typeof(UnityEngine.Object) : typeof(object); case SearchContext.UnityObject:
typeAutocompleter.AllTypes = false; unityObjectTypeCompleter.Enabled = true;
allTypesCompleter.Enabled = false;
break;
case SearchContext.Singleton:
case SearchContext.Class:
allTypesCompleter.Enabled = true;
unityObjectTypeCompleter.Enabled = false;
break;
} }
typeAutocompleter.CacheTypes();
} }
private void OnSceneFilterDropChanged(int value) => sceneFilter = (SceneFilter)value; private void OnSceneFilterDropChanged(int value) => sceneFilter = (SceneFilter)value;
@ -185,7 +185,9 @@ namespace UnityExplorer.ObjectExplorer
InputFieldRef classInputField = UIFactory.CreateInputField(classInputRow, "ClassInput", "..."); InputFieldRef classInputField = UIFactory.CreateInputField(classInputRow, "ClassInput", "...");
UIFactory.SetLayoutElement(classInputField.UIRoot, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999); UIFactory.SetLayoutElement(classInputField.UIRoot, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
typeAutocompleter = new TypeCompleter(typeof(UnityEngine.Object), classInputField); unityObjectTypeCompleter = new(typeof(UnityEngine.Object), classInputField, true, false, true);
allTypesCompleter = new(null, classInputField, true, false, true);
allTypesCompleter.Enabled = false;
classInputField.OnValueChanged += OnTypeInputChanged; classInputField.OnValueChanged += OnTypeInputChanged;
//unityObjectClassRow.SetActive(false); //unityObjectClassRow.SetActive(false);

View File

@ -1,18 +1,9 @@
using System; using System.Collections;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets;
using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.Utility;
using UniverseLib.UI.Widgets; using UniverseLib.UI.Widgets;
namespace UnityExplorer.ObjectExplorer namespace UnityExplorer.ObjectExplorer

View File

@ -1,9 +1,4 @@
using System; using UnityEngine.SceneManagement;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
using UniverseLib;
namespace UnityExplorer.ObjectExplorer namespace UnityExplorer.ObjectExplorer
{ {

View File

@ -1,11 +1,4 @@
using System; using UnityEngine.SceneManagement;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.SceneManagement;
using UniverseLib;
using UniverseLib.Utility;
namespace UnityExplorer.ObjectExplorer namespace UnityExplorer.ObjectExplorer
{ {
@ -135,7 +128,7 @@ namespace UnityExplorer.ObjectExplorer
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
{ {
foreach (Type type in asm.TryGetTypes()) foreach (Type type in asm.GetTypes())
{ {
if (!string.IsNullOrEmpty(nameFilter) && !type.FullName.ContainsIgnoreCase(nameFilter)) if (!string.IsNullOrEmpty(nameFilter) && !type.FullName.ContainsIgnoreCase(nameFilter))
continue; continue;
@ -173,7 +166,7 @@ namespace UnityExplorer.ObjectExplorer
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
{ {
// Search all non-static, non-enum classes. // Search all non-static, non-enum classes.
foreach (Type type in asm.TryGetTypes().Where(it => !(it.IsSealed && it.IsAbstract) && !it.IsEnum)) foreach (Type type in asm.GetTypes().Where(it => !(it.IsSealed && it.IsAbstract) && !it.IsEnum))
{ {
try try
{ {

View File

@ -1,5 +1,4 @@
using System.Reflection; using System.Runtime.InteropServices;
using System.Runtime.InteropServices;
using UnityExplorer; using UnityExplorer;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following

View File

@ -1,5 +1,4 @@
#if MONO #if MONO
using UnityEngine;
namespace UnityExplorer.Runtime namespace UnityExplorer.Runtime
{ {

View File

@ -1,9 +1,4 @@
using System; using UnityExplorer.Config;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityExplorer.Config;
using UniverseLib;
namespace UnityExplorer.Runtime namespace UnityExplorer.Runtime
{ {

View File

@ -1,10 +1,4 @@
using System; namespace UnityExplorer.Runtime
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
namespace UnityExplorer.Runtime
{ {
internal static class UnityCrashPrevention internal static class UnityCrashPrevention
{ {

View File

@ -1,12 +1,13 @@
using System; using System.Collections;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
#if CPP #if CPP
#if INTEROP
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime;
#else
using UnhollowerRuntimeLib; using UnhollowerRuntimeLib;
using UnhollowerBaseLib; using UnhollowerBaseLib;
#endif #endif
#endif
namespace UnityExplorer.Tests namespace UnityExplorer.Tests
{ {
@ -257,7 +258,7 @@ namespace UnityExplorer.Tests
} }
ExplorerCore.Log($"IL2CPP 9: Il2Cpp struct array of ints"); ExplorerCore.Log($"IL2CPP 9: Il2Cpp struct array of ints");
IL2CPP_structArray = new UnhollowerBaseLib.Il2CppStructArray<int>(5); IL2CPP_structArray = new Il2CppStructArray<int>(5);
IL2CPP_structArray[0] = 0; IL2CPP_structArray[0] = 0;
IL2CPP_structArray[1] = 1; IL2CPP_structArray[1] = 1;
IL2CPP_structArray[2] = 2; IL2CPP_structArray[2] = 2;
@ -265,7 +266,7 @@ namespace UnityExplorer.Tests
IL2CPP_structArray[4] = 4; IL2CPP_structArray[4] = 4;
ExplorerCore.Log($"IL2CPP 10: Il2Cpp reference array of boxed objects"); ExplorerCore.Log($"IL2CPP 10: Il2Cpp reference array of boxed objects");
IL2CPP_ReferenceArray = new UnhollowerBaseLib.Il2CppReferenceArray<Il2CppSystem.Object>(3); IL2CPP_ReferenceArray = new Il2CppReferenceArray<Il2CppSystem.Object>(3);
IL2CPP_ReferenceArray[0] = new Il2CppSystem.Int32 { m_value = 5 }.BoxIl2CppObject(); IL2CPP_ReferenceArray[0] = new Il2CppSystem.Int32 { m_value = 5 }.BoxIl2CppObject();
IL2CPP_ReferenceArray[1] = null; IL2CPP_ReferenceArray[1] = null;
IL2CPP_ReferenceArray[2] = (Il2CppSystem.String)"whats up"; IL2CPP_ReferenceArray[2] = (Il2CppSystem.String)"whats up";

View File

@ -1,7 +1,5 @@
using System.Collections; using System.Collections;
using UnityEngine;
using UnityExplorer.Config; using UnityExplorer.Config;
using UniverseLib;
using UniverseLib.Input; using UniverseLib.Input;
namespace UnityExplorer.UI namespace UnityExplorer.UI

View File

@ -1,8 +1,4 @@
using System; using UniverseLib.UI;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniverseLib.UI;
using UniverseLib.UI.Panels; using UniverseLib.UI.Panels;
namespace UnityExplorer.UI namespace UnityExplorer.UI

View File

@ -1,6 +1,4 @@
using UnityEngine; using UniverseLib.UI;
using UnityEngine.UI;
using UniverseLib.UI;
namespace UnityExplorer.UI namespace UnityExplorer.UI
{ {
@ -39,7 +37,6 @@ namespace UnityExplorer.UI
private static void ConstructUI() private static void ConstructUI()
{ {
popupLabel = UIFactory.CreateLabel(UIManager.UIRoot, "ClipboardNotification", "", TextAnchor.MiddleCenter); popupLabel = UIFactory.CreateLabel(UIManager.UIRoot, "ClipboardNotification", "", TextAnchor.MiddleCenter);
popupLabel.rectTransform.sizeDelta = new(500, 100); popupLabel.rectTransform.sizeDelta = new(500, 100);
popupLabel.gameObject.AddComponent<Outline>(); popupLabel.gameObject.AddComponent<Outline>();

View File

@ -1,17 +1,9 @@
using System; using UnityExplorer.UI.Widgets.AutoComplete;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib;
using UniverseLib.Input; using UniverseLib.Input;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets.ButtonList; using UniverseLib.UI.Widgets.ButtonList;
using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
namespace UnityExplorer.UI.Panels namespace UnityExplorer.UI.Panels
{ {
@ -69,15 +61,22 @@ namespace UnityExplorer.UI.Panels
if (CurrentHandler == provider) if (CurrentHandler == provider)
{ {
Suggestions.Clear();
CurrentHandler = null; CurrentHandler = null;
UIRoot.SetActive(false); UIRoot.SetActive(false);
} }
} }
public void SetSuggestions(IEnumerable<Suggestion> suggestions) public void SetSuggestions(List<Suggestion> suggestions, bool jumpToTop = true)
{ {
Suggestions = suggestions as List<Suggestion> ?? suggestions.ToList(); Suggestions = suggestions;
SelectedIndex = 0;
if (jumpToTop)
{
SelectedIndex = 0;
if (scrollPool.DataSource.ItemCount > 0)
scrollPool.JumpToIndex(0, null);
}
if (!Suggestions.Any()) if (!Suggestions.Any())
base.UIRoot.SetActive(false); base.UIRoot.SetActive(false);
@ -86,7 +85,7 @@ namespace UnityExplorer.UI.Panels
base.UIRoot.SetActive(true); base.UIRoot.SetActive(true);
base.UIRoot.transform.SetAsLastSibling(); base.UIRoot.transform.SetAsLastSibling();
buttonListDataHandler.RefreshData(); buttonListDataHandler.RefreshData();
scrollPool.Refresh(true, true); scrollPool.Refresh(true, jumpToTop);
} }
} }
@ -194,6 +193,12 @@ namespace UnityExplorer.UI.Panels
private void SetCell(ButtonCell cell, int index) private void SetCell(ButtonCell cell, int index)
{ {
if (CurrentHandler == null)
{
UIRoot.SetActive(false);
return;
}
if (index < 0 || index >= Suggestions.Count) if (index < 0 || index >= Suggestions.Count)
{ {
cell.Disable(); cell.Disable();
@ -225,13 +230,18 @@ namespace UnityExplorer.UI.Panels
InputFieldRef input = CurrentHandler.InputField; InputFieldRef input = CurrentHandler.InputField;
if (!input.Component.isFocused || input.Component.caretPosition == lastCaretPosition && input.UIRoot.transform.position == lastInputPosition) //if (!input.Component.isFocused
// || (input.Component.caretPosition == lastCaretPosition && input.UIRoot.transform.position == lastInputPosition))
// return;
if (input.Component.caretPosition == lastCaretPosition && input.UIRoot.transform.position == lastInputPosition)
return; return;
lastInputPosition = input.UIRoot.transform.position;
lastCaretPosition = input.Component.caretPosition;
if (CurrentHandler.AnchorToCaretPosition) if (CurrentHandler.AnchorToCaretPosition)
{ {
if (!input.Component.isFocused)
return;
TextGenerator textGen = input.Component.cachedInputTextGenerator; TextGenerator textGen = input.Component.cachedInputTextGenerator;
int caretIdx = Math.Max(0, Math.Min(textGen.characterCount - 1, input.Component.caretPosition)); int caretIdx = Math.Max(0, Math.Min(textGen.characterCount - 1, input.Component.caretPosition));
@ -248,6 +258,9 @@ namespace UnityExplorer.UI.Panels
uiRoot.transform.position = input.Transform.position + new Vector3(-(input.Transform.rect.width / 2) + 10, -20, 0); uiRoot.transform.position = input.Transform.position + new Vector3(-(input.Transform.rect.width / 2) + 10, -20, 0);
} }
lastInputPosition = input.UIRoot.transform.position;
lastCaretPosition = input.Component.caretPosition;
this.Dragger.OnEndResize(); this.Dragger.OnEndResize();
} }

View File

@ -1,9 +1,5 @@
using System; using System.Collections;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CSConsole; using UnityExplorer.CSConsole;
using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets; using UniverseLib.UI.Widgets;
@ -145,7 +141,7 @@ namespace UnityExplorer.UI.Panels
GameObject inputObj = UIFactory.CreateScrollInputField(inputArea, "ConsoleInput", ConsoleController.STARTUP_TEXT, GameObject inputObj = UIFactory.CreateScrollInputField(inputArea, "ConsoleInput", ConsoleController.STARTUP_TEXT,
out InputFieldScroller inputScroller, fontSize); out InputFieldScroller inputScroller, fontSize);
InputScroller = inputScroller; InputScroller = inputScroller;
ConsoleController.defaultInputFieldAlpha = Input.Component.selectionColor.a; ConsoleController.DefaultInputFieldAlpha = Input.Component.selectionColor.a;
Input.OnValueChanged += InvokeOnValueChanged; Input.OnValueChanged += InvokeOnValueChanged;
// move line number text with input field // move line number text with input field

View File

@ -1,9 +1,4 @@
using System; using UniverseLib.UI;
using UnityEngine;
using UnityEngine.UI;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.Utility;
namespace UnityExplorer.UI.Panels namespace UnityExplorer.UI.Panels
{ {

View File

@ -1,17 +1,12 @@
using HarmonyLib; using UniverseLib.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UniverseLib;
using UniverseLib.Input;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.Utility; #if UNHOLLOWER
using UnhollowerRuntimeLib;
#endif
#if INTEROP
using Il2CppInterop.Runtime.Injection;
#endif
namespace UnityExplorer.UI.Panels namespace UnityExplorer.UI.Panels
{ {
@ -171,6 +166,9 @@ namespace UnityExplorer.UI.Panels
if (!ourCamera) if (!ourCamera)
return; return;
if (positionInput.Component.isFocused)
return;
lastSetCameraPosition = ourCamera.transform.position; lastSetCameraPosition = ourCamera.transform.position;
positionInput.Text = ParseUtility.ToStringForInput<Vector3>(lastSetCameraPosition); positionInput.Text = ParseUtility.ToStringForInput<Vector3>(lastSetCameraPosition);
} }
@ -332,7 +330,7 @@ namespace UnityExplorer.UI.Panels
#if CPP #if CPP
static FreeCamBehaviour() static FreeCamBehaviour()
{ {
UnhollowerRuntimeLib.ClassInjector.RegisterTypeInIl2Cpp<FreeCamBehaviour>(); ClassInjector.RegisterTypeInIl2Cpp<FreeCamBehaviour>();
} }
public FreeCamBehaviour(IntPtr ptr) : base(ptr) { } public FreeCamBehaviour(IntPtr ptr) : base(ptr) { }

View File

@ -1,14 +1,6 @@
using System; using UnityExplorer.Hooks;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Hooks;
using UnityExplorer.UI.Widgets; using UnityExplorer.UI.Widgets;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets;
using UniverseLib.UI.Widgets.ScrollView;
namespace UnityExplorer.UI.Panels namespace UnityExplorer.UI.Panels
{ {

View File

@ -1,6 +1,4 @@
using UnityEngine; using UnityExplorer.Inspectors;
using UnityEngine.UI;
using UnityExplorer.Inspectors;
using UniverseLib.UI; using UniverseLib.UI;
namespace UnityExplorer.UI.Panels namespace UnityExplorer.UI.Panels

View File

@ -1,16 +1,8 @@
using System; using System.Diagnostics;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Config; using UnityExplorer.Config;
using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
namespace UnityExplorer.UI.Panels namespace UnityExplorer.UI.Panels
{ {

View File

@ -1,10 +1,7 @@
using System.Collections.Generic; using UnityExplorer.Inspectors.MouseInspectors;
using UnityEngine;
using UnityExplorer.Inspectors.MouseInspectors;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Widgets.ButtonList; using UniverseLib.UI.Widgets.ButtonList;
using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
namespace UnityExplorer.UI.Panels namespace UnityExplorer.UI.Panels
{ {

View File

@ -1,9 +1,4 @@
using System; using UnityExplorer.ObjectExplorer;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityExplorer.ObjectExplorer;
using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;

View File

@ -1,7 +1,4 @@
using System; using UnityExplorer.CacheObject;
using System.Collections.Generic;
using UnityEngine;
using UnityExplorer.CacheObject;
using UnityExplorer.CacheObject.Views; using UnityExplorer.CacheObject.Views;
using UnityExplorer.Config; using UnityExplorer.Config;
using UniverseLib.UI; using UniverseLib.UI;

View File

@ -1,12 +1,5 @@
using System; using System.Globalization;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Config; using UnityExplorer.Config;
using UniverseLib;
using UniverseLib.Input;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.UI.Panels; using UniverseLib.UI.Panels;
@ -71,6 +64,17 @@ namespace UnityExplorer.UI.Panels
// Save Data // Save Data
bool setDefault = false;
public override void SetDefaultSizeAndPosition()
{
if (setDefault)
return;
setDefault = true;
base.SetDefaultSizeAndPosition();
}
public bool ApplyingSaveData { get; set; } public bool ApplyingSaveData { get; set; }
public void SaveInternalData() public void SaveInternalData()
@ -119,6 +123,8 @@ namespace UnityExplorer.UI.Panels
{ {
Rect.SetAnchorsFromString(split[1]); Rect.SetAnchorsFromString(split[1]);
Rect.SetPositionFromString(split[2]); Rect.SetPositionFromString(split[2]);
this.EnsureValidSize();
this.EnsureValidPosition();
this.SetActive(bool.Parse(split[0])); this.SetActive(bool.Parse(split[0]));
} }
catch catch

Some files were not shown because too many files have changed in this diff Show More