Compare commits

..

776 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
Sinai
e92556805b Update BepInExConfigHandler.cs 2022-04-23 01:05:51 +10:00
Sinai
8662742461 Bump version 2022-04-23 00:19:31 +10:00
Sinai
63393a9d66 Update README.md 2022-04-22 22:31:36 +10:00
Sinai
13986f95c1 Update UnityExplorer.STANDALONE.Mono.dll 2022-04-22 22:27:48 +10:00
Sinai
b47bfa1e83 Remove Mono restriction on generic type eligibility 2022-04-22 22:27:43 +10:00
Sinai
12c51248fe Update Editor package 2022-04-22 22:20:01 +10:00
Sinai
9b9cb54a79 Fix a typo 2022-04-22 22:19:43 +10:00
Sinai
6a28a93e3a Update for obsolete method 2022-04-22 22:11:24 +10:00
Sinai
32e718faeb Bump UniverseLib 2022-04-22 21:31:30 +10:00
Sinai
4d46b74d54 Fix references for rename 2022-04-22 21:04:50 +10:00
Sinai
7e5246cead Recache types when borrowing 2022-04-22 21:04:23 +10:00
Sinai
abf5267364 Fix HookCreator method filtering 2022-04-22 21:03:51 +10:00
Sinai
3afee7254c Fix results TypeCompleter issues 2022-04-22 21:03:33 +10:00
Sinai
1643d4b7dd Allow generic class construction for unbound types 2022-04-22 21:03:11 +10:00
Sinai
cef8c12d20 Fix TryFocusActiveInspector for classes 2022-04-22 21:02:45 +10:00
Sinai
5e07847356 Make current hooks view smaller in height 2022-04-22 21:02:08 +10:00
Sinai
2dc6e386df Fix generated patch code for ref and subclasses 2022-04-22 21:01:47 +10:00
Sinai
ff882296fd Fix for GenericConstructorWidget, adjust UI 2022-04-22 21:01:09 +10:00
Sinai
ecc33927ee Make GenericConstructorWidget reusable 2022-04-22 21:00:18 +10:00
Sinai
6e91f2a792 Hooks: Add support for generic classes and methods 2022-04-22 09:15:51 +10:00
Sinai
97cb14d6fc HookInstance: Clean up generated patch code 2022-04-22 09:12:38 +10:00
Sinai
8b861f7c77 Log Panel: Remove a todo 2022-04-22 09:12:22 +10:00
Sinai
9379e0f813 Fix constraints on AddComponent TypeCompleter 2022-04-22 09:08:49 +10:00
Sinai
bdda12a040 Remove redundant reference to EvaluateWidget 2022-04-22 09:08:17 +10:00
Sinai
75bd654a94 TypeCompleter: Allow generics, support shorthand names 2022-04-22 09:07:51 +10:00
Sinai
f174c7543a C# Console: Fix autocomplete caret deselection 2022-04-22 09:06:52 +10:00
Sinai
08f2c6035e Bump version 2022-04-20 18:47:23 +10:00
Sinai
475e24a66a Update editor package 2022-04-20 18:47:19 +10:00
Sinai
c62b93535d Update position input when Reset button clicked 2022-04-20 18:47:12 +10:00
Sinai
374d0b3bae Bump UniverseLib 2022-04-20 18:46:48 +10:00
Sinai
1f87e89b97 Add some more functionality to Freecam
- Option to use Game's camera
- Button to reset position back to original cam pos
- Free cam position will be stored between stopping/starting free cam
2022-04-19 19:37:05 +10:00
Sinai
495bc41a8d Bump Editor package 2022-04-19 18:06:16 +10:00
Sinai
9cf62c3250 Bump UniverseLib, fix EventSystem issue 2022-04-19 18:05:55 +10:00
Sinai
4c9b3115cd Update UnityEditorPackage 2022-04-19 01:23:11 +10:00
Sinai
ebdce70418 Move instructions 2022-04-19 01:22:25 +10:00
Sinai
7c0b37440b Update UnityEditorPackage 2022-04-19 01:19:04 +10:00
Sinai
0d8ab8bf14 Allow FreeCam to run when menu closed 2022-04-19 01:12:33 +10:00
Sinai
5a3cad9be2 Fix weird Behaviour inheritance issue 2022-04-19 00:57:13 +10:00
Sinai
70d67f1dad Bump version 2022-04-18 21:39:50 +10:00
Sinai
469484d129 Add FreeCam panel 2022-04-18 21:39:17 +10:00
Sinai
c5e262d1c3 Fix UEPanel save data issue 2022-04-18 21:39:11 +10:00
Sinai
53c8dfcb6d Bump UniverseLib 2022-04-18 21:38:49 +10:00
Sinai
ae3ac21992 Add test for Il2CppSystem.Array 2022-04-18 19:12:42 +10:00
Sinai
7765b64748 Make MouseInspector panel just a PanelBase 2022-04-18 19:12:21 +10:00
Sinai
a5023d03f4 Update to UniverseLib 1.3.4 2022-04-18 19:11:39 +10:00
Sinai
a5e6b65dee Add UniverseLib to C# Console default usings 2022-04-18 19:10:24 +10:00
Sinai
c45cd8c1e1 Update editor package 2022-04-14 02:41:18 +10:00
Sinai
e46e24e1af Fix typo 2022-04-14 02:32:01 +10:00
Sinai
3d66493f9c Use UniverseLib PanelBase/PanelDragger 2022-04-14 01:25:59 +10:00
Sinai
7e0f98ef91 Automatic code cleanup (no real changes)
- Use explicit type of var
- Use 'new()'
- Remove unnecessary usings
- Sort usings
- Apply formatting
2022-04-12 05:20:35 +10:00
Sinai
693f5818be Remove duplicate UIManager.Update call 2022-04-12 04:46:04 +10:00
Sinai
1d1dad5cb1 Merge branch 'master' of https://github.com/sinai-dev/UnityExplorer 2022-04-12 02:52:17 +10:00
Sinai
79157a2fab Add UnityEditorPackage 2022-04-12 02:52:09 +10:00
Sinai
7ef8eff0d4
Fix missing space character in dotnet.yaml 2022-04-12 02:40:25 +10:00
Sinai
8a4d418ffb Finalize 4.7.0 release, cleanups 2022-04-12 02:36:12 +10:00
Sinai
b56960dba2 Update readme, remove pause from build script 2022-04-12 01:34:43 +10:00
Sinai
006ab2ee6f Update dotnet.yml 2022-04-12 01:20:13 +10:00
Sinai
a0ed26eb8e Delete .gitmodules 2022-04-12 00:36:24 +10:00
Sinai
7665987794 Add powershell build script 2022-04-12 00:29:02 +10:00
Sinai
4516e9b9f6 Migrate project to dotnet SDK, add net6 build 2022-04-12 00:28:53 +10:00
Sinai
e1aac57a51 Refactor class for future expansion 2022-04-12 00:27:20 +10:00
Sinai
8f1f6cd0b2 Fix JumpToTransform exception with HideAndDontSave 2022-04-12 00:27:05 +10:00
Sinai
409a468b55 Fix exception when adding certain references in net6 2022-04-12 00:26:49 +10:00
Sinai
6110c59721 Update Emit exception message 2022-04-12 00:26:29 +10:00
Sinai
96451477ee Change ExplorerFolder path and refactor 2022-04-12 00:26:01 +10:00
Sinai
f19a1dd25e Code cleanup 2022-04-12 00:17:06 +10:00
Sinai
47629d4764 Update libs
- Added net6 MelonLoader.dll reference
- Added net6 mcs.dll reference
- Restructured dlls into framework folders
2022-04-11 23:17:13 +10:00
Sinai
62fa7f30f3 Fix exception state being "sticky" 2022-04-11 17:37:03 +10:00
Sinai
4af86e0e25 Fix InspectingAssetScene returning incorrect value 2022-04-11 17:14:20 +10:00
Sinai
27ae78a043 Remove redundant UIManager.Update call 2022-04-11 17:14:05 +10:00
Sinai
d6a07f05ea Bump version 2022-04-10 05:37:28 +10:00
Sinai
27d5398dea Add throttling to prune method, remove logging 2022-04-10 05:32:07 +10:00
Sinai
7a5570a070 Bump version 2022-04-09 18:59:34 +10:00
Sinai
d40537775f Bump UniverseLib 2022-04-09 18:59:13 +10:00
Sinai
9b6f3fd3ea Cleanups / refactoring 2022-04-09 18:58:56 +10:00
Sinai
bacac929e9 Show InputField for exceptions to view/copy full exception 2022-04-01 18:14:50 +11:00
Sinai
4e3d3a2e5c Update README.md 2022-04-01 01:37:51 +11:00
Sinai
7dbc8fd66e Merge branch 'master' of https://github.com/sinai-dev/UnityExplorer 2022-04-01 01:31:53 +11:00
Sinai
892cefcc91 Bump version 2022-04-01 01:31:45 +11:00
Sinai
a986b92963 Don't try to get UnityObjectWidget for static class inspection 2022-04-01 01:31:40 +11:00
Sinai
8837119781
Merge pull request #132 from liesauer/master
Fix standalone reading config item type casting bug
2022-04-01 01:21:39 +11:00
L!εsAμεr
7eda249ddb
Fix standalone reading config item type casting bug 2022-03-31 21:07:06 +08:00
Sinai
710b4ba74a Use switch expression instead of if/else block 2022-03-29 22:39:26 +11:00
Sinai
4bee55fb25 Cleanups, remove redundancy 2022-03-29 22:36:17 +11:00
Sinai
c71748d22a Remove pointless ToArray() call 2022-03-23 19:02:17 +11:00
Sinai
621035c732 Bump UniverseLib 2022-03-23 18:04:27 +11:00
Sinai
2285a495be Add support for Unity Editor release 2022-03-21 21:25:51 +11:00
Sinai
efdf2446bd A few cleanups and optimizations 2022-03-21 21:25:18 +11:00
Sinai
6ad45ac8ae Delete social.png 2022-03-21 21:24:36 +11:00
Sinai
2d3c83cfa3 Bump version 2022-03-21 01:05:00 +11:00
Sinai
3213717ff6 Add outline to resize arrow 2022-03-21 01:04:55 +11:00
Sinai
a6a1a4d046 cleanup 2022-03-21 01:04:44 +11:00
Sinai
078c2e2b51 Add AudioClipWidget 2022-03-21 01:04:39 +11:00
Sinai
49bce650b4 Fix text clipping with transform cell name and sibling index 2022-03-20 21:21:23 +11:00
Sinai
bd9e80f2b4 Refactor unity inspector widgets into proper classes 2022-03-20 21:21:01 +11:00
Sinai
d1eb5671bf Move GetCacheMembers into separate class 2022-03-20 21:20:17 +11:00
Sinai
f1ca484712 Fix generic arguments for parameterless struct ctors 2022-03-16 23:21:39 +11:00
Sinai
3b71b40843 More accurate check if enum value has flag 2022-03-15 01:51:27 +11:00
Sinai
1292affe6d Fix autocomplete panel resizing 2022-03-15 01:50:50 +11:00
Sinai
6614762fe8 Bump version 2022-03-15 01:19:52 +11:00
Sinai
d81d6d034b Implement support for implicit struct constructors 2022-03-15 01:19:48 +11:00
Sinai
5dfe3bbf0c Fix missing and incorrect ctor caching
- Shouldn't include ctors on abstract types
- Missing parameterless ctors for structs (implicit)
2022-03-15 01:19:01 +11:00
Sinai
dc81451ce5 Make Constructor toggle button actually do something 2022-03-15 01:18:12 +11:00
Sinai
d7ab0a23c6 Skip private/anonymous types in TypeCompleter results 2022-03-15 01:17:54 +11:00
Sinai
1a01c740e2 Move AutoCompleteModal into Panels folder 2022-03-15 01:17:35 +11:00
Sinai
040fb1f11a Bump version 2022-03-14 05:22:44 +11:00
Sinai
e44ff9e207 Add support for Constructors in Reflection Inspector
- Added CacheConstructor : CacheMember
- Changed default scope to "All" from "Instance" when inspecting an instance
- Bumped UniverseLib
2022-03-14 05:20:43 +11:00
Sinai
b5c69fc1ea Fix UI mouse inspector results panel not always coming to front 2022-03-13 02:59:52 +11:00
Sinai
4fdb2aacd8 Move logic out of UIManager.SetPanelActive into panel.SetActive 2022-03-13 02:21:25 +11:00
Sinai
48e688cb75 use SetPanelActive instead of manually setting gameobject active 2022-03-13 02:08:46 +11:00
Sinai
647b0d353d Fix text clipping on inspector tab button 2022-03-12 20:17:03 +11:00
Sinai
2b715f3dbe Hide SiblingIndex input when invalid 2022-03-12 20:16:55 +11:00
Sinai
938a991594 Update TransformTree immediately on user changes 2022-03-12 20:16:37 +11:00
Sinai
f00134b283 Add "one-shot" option for TransformTree updating 2022-03-10 17:56:21 +11:00
Sinai
3b6b9768fb Bump UniverseLib 2022-03-10 05:29:55 +11:00
Sinai
5fbfa1b7aa Bump UniverseLib 2022-03-10 05:06:49 +11:00
Sinai
7d26965c12 Bump UniverseLib 2022-03-10 04:44:45 +11:00
Sinai
862523399a Bump version 2022-03-10 04:35:11 +11:00
Sinai
0afccadc64 Improve TransformTree efficiency
- Added batching to the update method so that a maximum of 2000 GameObjects are traversed each frame.
- Changed from OrderedDictionary.Remove to OrderedDictionary.RemoveAt when pruning entries as the former needs to iterate through all entries to find the index of the key, whereas the latter is constant time.
2022-03-10 04:35:06 +11:00
Sinai
0e37e8030c Add sibling index input to transform tree cells 2022-03-10 04:32:19 +11:00
Sinai
621a9cd72e Use RemoveHighlighting to get raw copy+paste name 2022-03-10 04:31:19 +11:00
Sinai
56be5414f9 Bump UniverseLib 2022-03-10 04:30:52 +11:00
Sinai
b8c4be473f Fix disposed TextWriter bug, bump version 2022-03-06 00:21:48 +11:00
Sinai
b6966f8836 Bump UniverseLib, bump version 2022-03-05 07:32:32 +11:00
Sinai
ad8c5293a0 Add keybinds for Mouse Inspect, small cleanup 2022-03-04 00:20:04 +11:00
Sinai
a7165c849c Bump UniverseLib, cleanup, bump version 2022-03-04 00:09:19 +11:00
Sinai
79f2514109 Fix issue with partially unloaded scenes(?) 2022-03-03 03:22:17 +11:00
Sinai
4e76eca73a Use new melonloader logging method 2022-02-24 19:26:16 +11:00
Sinai
2f0876466c bump mod loader versions 2022-02-24 19:26:01 +11:00
Sinai
fdefc3d567 Include runtime context in "initialized" log. 2022-02-21 01:46:13 +11:00
Sinai
64193ff1b0 Use a patch instead of manual check on every property 2022-02-21 01:45:46 +11:00
Sinai
a90292f47f Prevent Unity crashing on PropertyInfo evaluation
Unity crashes from checking Canvas.renderingDisplaySize on a Canvas set to WorldSpace with no worldCamera set.
2022-02-19 17:50:10 +11:00
Sinai
d0bccae50c Update TypeCompleter.cs 2022-02-11 19:39:11 +11:00
Sinai
bdf08f014f Use ReflectionUtility.AllTypes for type autocompleter, bump UniverseLib 2022-02-11 19:37:17 +11:00
Sinai
df8522963e Use reflection for AllTypes until it's public 2022-02-07 22:12:18 +11:00
Sinai
f6d0acab7b Bump version 2022-02-07 00:45:19 +11:00
Sinai
d4fbc89158 Use ReflectionUtility.AllTypes when doing class search to include static classes 2022-02-06 04:50:52 +11:00
Sinai
9e49f09a79 Bump UniverseLib, fix C# Console issues, add Stop helper 2022-02-04 20:34:05 +11:00
Sinai
b9a3ab7439 Fix CSConsole not re-selecting properly after Escape is pressed 2022-02-04 18:07:34 +11:00
Sinai
03661cdd0b Bump UniverseLib 2022-02-03 23:51:38 +11:00
Sinai
10f2b7e849 Bump UniverseLib and fix changes to CreatePanel 2022-02-03 23:33:45 +11:00
Sinai
4602f07c34 Add NuGet config 2022-02-01 18:20:01 +11:00
Sinai
18bcfed434 Bump UniverseLib 2022-02-01 08:05:01 +11:00
Sinai
c7d2ce6d36 Merge branch 'master' of https://github.com/sinai-dev/UnityExplorer 2022-01-31 22:01:35 +11:00
Sinai
f961add7f4 Bump version 2022-01-31 22:00:59 +11:00
Sinai
798b881dcb
Update dotnet.yml 2022-01-31 21:31:18 +11:00
Sinai
c90f339882
Update dotnet.yml 2022-01-31 21:29:10 +11:00
Sinai
c351ce5a6d
Remove Il2CppAssemblyUnhollower from build process 2022-01-31 21:24:57 +11:00
Sinai
9985ed0fd8 Update to UniverseLib 1.2, cleanups 2022-01-31 21:24:01 +11:00
Sinai
f35232bb64 Removed Unhollower submodule 2022-01-30 06:36:01 +11:00
Sinai
49cc1f7df3 Fix issue with DontDestroyOnLoad not existing in some games, cleanups 2022-01-24 17:50:01 +11:00
Sinai
9f78c50854 Use "untitled" for transforms with empty names 2022-01-24 17:49:49 +11:00
Sinai
bc64a04339 Cleanup 2022-01-24 17:49:34 +11:00
Sinai
7d961ce8ad Cleanup and DontDestroy fixes 2022-01-24 17:49:22 +11:00
Sinai
c7d7569f71 Fix NullReferenceException in some older Unity games 2022-01-24 17:49:01 +11:00
Sinai
ee8f33a754 Bump version 2022-01-24 01:10:19 +11:00
Sinai
a95d91c824 Fix hidden UiBase not being deactivated with main one 2022-01-24 00:35:45 +11:00
Sinai
177b78f4e7 Bump UniverseLib 2022-01-23 23:12:06 +11:00
Sinai
3804d0aab0 Update ConfigManager.cs 2022-01-23 23:09:01 +11:00
Sinai
97a82c1661 Make sure mouse is in target display for resize/dragging/panel operations 2022-01-23 23:08:34 +11:00
Sinai
96a1cc69fb Bump UniverseLib 2022-01-23 17:44:01 +11:00
Sinai
589abe6193 Fix panel draggers on display change 2022-01-22 21:44:22 +11:00
Sinai
91bb58b020 Fix panel resizing on alternate monitors 2022-01-22 21:08:12 +11:00
Sinai
d67507ead2 Implement DisplayManager, ability to use other monitors 2022-01-22 20:20:44 +11:00
Sinai
d730fbe49c
Update FUNDING.yml 2022-01-19 18:25:16 +11:00
Sinai
9e0784ce54
Create FUNDING.yml 2022-01-19 18:24:49 +11:00
Sinai
67c602b32f Use Tomlet for Standalone config, fix ML double reference 2022-01-19 18:20:26 +11:00
Sinai
8fb7d87ca6 Use Tomlet, simplify panel data saving 2022-01-19 17:34:53 +11:00
Sinai
c740c3c54d Update README.md 2022-01-18 20:34:15 +11:00
Sinai
ea7b91f7fd Implement Clipboard and Notifications, misc cleanups 2022-01-18 20:19:20 +11:00
Sinai
c79223f537 Move MouseInspector dropdown to Inspector panel 2022-01-17 21:00:55 +11:00
Sinai
aae248bf69 Bump UniverseLib to 1.0.4, use HighlightMethod, add Clipboard (unfinished) 2022-01-17 20:23:58 +11:00
Sinai
a73e992a0c Remove "Core" namespace, move everything in it up one level 2022-01-17 19:42:05 +11:00
Sinai
3984550bb6 Bump Unhollower to latest 2022-01-17 19:41:00 +11:00
Sinai
7928363aeb Bumped UniverseLib to 1.0.3 2022-01-11 05:54:38 +11:00
Sinai
12758606fa Bump UniverseLib to 1.0.2 2022-01-09 19:56:59 +11:00
Sinai
c927ac54be Fix potential NullReference in UpdateMouseInspect 2022-01-09 19:20:17 +11:00
Sinai
9f1df11940 Add some more tests 2022-01-08 17:56:56 +11:00
Sinai
62354b6aa2 Fix disposed TextWriter bug, add System.Collections to default using 2022-01-08 17:56:48 +11:00
Sinai
44e57c32c3 Raise LangVersion to 9.0 2022-01-08 17:56:33 +11:00
Sinai
274352d665 fix ParameterHandler parsing Types 2022-01-02 19:55:09 +11:00
Sinai
7b477a8b0e Rewrite EvaluateWidget, add BaseArgumentHandler, use autocomplete for InteractiveEnum 2022-01-02 19:43:55 +11:00
Sinai
e585fc6da0 Allow evaluating non-primitive methods 2022-01-01 21:40:47 +11:00
Sinai
0dd19345ed Fix FPS drop with MelonLoader 2021-12-28 23:24:44 +11:00
Sinai
0050cff185 bump version 2021-12-24 15:17:53 +11:00
Sinai
5f1d635eb3 Only filter transform tree on end edit 2021-12-24 15:17:48 +11:00
Sinai
e0f7fad00e Cleanup 2021-12-24 15:17:35 +11:00
Sinai
f92c215a88 update libs 2021-12-24 15:17:28 +11:00
Sinai
d58a5df82c Merge branch 'master' of https://github.com/sinai-dev/UnityExplorer 2021-12-24 15:17:23 +11:00
Sinai
12dd85ecfd Update README.md 2021-12-03 01:06:57 +11:00
Sinai
03fb165967
Update README (moved to UniverseLib) -noci 2021-12-02 21:11:25 +11:00
Sinai
834f4b7c4c Update README.md 2021-12-02 20:27:51 +11:00
Sinai
3415eb8e77 Bump version 2021-12-02 20:25:09 +11:00
Sinai
6c1a5b8ae2 Update README.md 2021-12-02 18:36:33 +11:00
Sinai
3334549902 use UniverseLib 2021-12-02 18:35:46 +11:00
Sinai
077a2b434a Null ptr check on AssetBundle loading 2021-11-30 17:31:49 +11:00
Sinai
8123ec2412 Revert "Use PatchProcessor ctor directly instead of Harmony.CreatePatchProcessor"
This reverts commit 9c1d4596554773c4cce9fbccba837c927800e16c.
2021-11-20 18:57:53 +11:00
Sinai
3f31db8dd8 Merge branch 'master' of https://github.com/sinai-dev/UnityExplorer 2021-11-20 17:47:14 +11:00
Sinai
9c1d459655 Use PatchProcessor ctor directly instead of Harmony.CreatePatchProcessor 2021-11-20 17:47:01 +11:00
Sinai
2cb510a82e
Cleanup readme
"Common issues" probably not that common anymore, removing to reduce clutter.
2021-11-18 05:12:04 +11:00
Sinai
6aa9b3aa15 Bump version 2021-10-26 15:12:56 +11:00
Sinai
587842f46b Add search filter to scene loader dropdown 2021-10-26 15:12:52 +11:00
Sinai
b9c641f170 Fix scene loader not showing 2021-10-26 15:12:44 +11:00
Sinai
1e68529430 Don't patch stripped UnloadAllAssetBundles 2021-10-22 15:54:14 +11:00
Sinai
e84e96a63c Bump version 2021-10-21 20:04:48 +11:00
Sinai
ec8c88ab9b Actually fix Logs folder 2021-10-19 16:34:46 +11:00
Sinai
0eae78eeb2 Update LogPanel.cs 2021-10-19 16:32:33 +11:00
Sinai
a07ead2142 Fix log folder not being created 2021-10-19 04:30:35 +11:00
Sinai
b93567c7ea Bump version 2021-10-16 18:11:08 +11:00
Sinai
957d80c7ec Fix IOUtility creating folders for file paths 2021-10-16 18:10:23 +11:00
Sinai
d530d10798 Exceptions is IsNullOrDestroyed should return true 2021-10-12 20:27:32 +11:00
Sinai
66daabf770 Add try/catch to IsNullOrDestroyed 2021-10-12 20:20:08 +11:00
Sinai
9fe998aa22 Cleanup 2021-10-01 17:21:54 +10:00
Sinai
28b6db80f9 Fix InputSystem EventSystem bug 2021-10-01 17:21:50 +10:00
Sinai
22effbb399 Update README.md 2021-09-30 21:13:29 +10:00
Sinai
50f0c31e98 Add patch for asset bundle unloading to prevent UnityExplorer's bundle being unloaded 2021-09-30 21:09:27 +10:00
Sinai
911522457e Clarify "Classes" help in C# Console 2021-09-30 21:09:04 +10:00
Sinai
d5d1841109 Include Unhollower in ILRepack references 2021-09-30 21:08:45 +10:00
Sinai
239534e09c Add GetAllLoadedAssetBundles 2021-09-30 21:08:29 +10:00
Sinai
bc5d16051f Fix issue with InputSystem 2021-09-30 21:08:08 +10:00
Sinai
f81822f219 bump lib versions 2021-09-30 21:06:38 +10:00
Sinai
f159cf5ea7 Attempt fix at bundle unloading 2021-09-23 16:40:47 +10:00
Sinai
1e6bacb32b manual unity libs no longer required for BepInEx 2021-09-23 16:21:47 +10:00
Sinai
a80cef4c1d Bump version 2021-09-07 19:11:58 +10:00
Sinai
450bb77f2e Use Harmony's FullDescription for hook parameter types 2021-09-07 19:11:19 +10:00
Sinai
0479102db6 Cleanup toggle Enabled logic 2021-09-07 18:06:38 +10:00
Sinai
93181f02be Update README.md 2021-09-07 17:33:01 +10:00
Sinai
371054d6df Add hook source editor for custom dynamic hooks 2021-09-07 17:23:20 +10:00
Sinai
427f23b80a Bump version 2021-09-07 03:40:14 +10:00
Sinai
a0d5ab8792 Fix ByRef parameters breaking generated patch code 2021-09-07 03:40:09 +10:00
Sinai
297034e38b Cleanup 2021-09-07 03:19:40 +10:00
Sinai
57f59d1295 Finalize hook manager update 2021-09-06 23:10:10 +10:00
Sinai
fbdb84eefa Implement HookManager UI and logic 2021-09-06 23:04:40 +10:00
Sinai
6989ea1b19 Misc cleanups 2021-09-06 23:03:55 +10:00
Sinai
fcdfeb2dec Redesign mouse inspector class, add UI results panel 2021-09-06 17:10:01 +10:00
Sinai
a1d0b6432e Cleanup 2021-09-06 15:51:40 +10:00
Sinai
0b84405e57 Fix incorrect startup delay logic 2021-09-02 18:29:21 +10:00
Sinai
c31e0949d3 Update ExplorerMelonMod.cs 2021-09-02 17:30:56 +10:00
Sinai
5f0495a7ea
Update README.md 2021-08-24 18:42:22 +10:00
Sinai
28de6779d8 Fix for Canvas.renderingDisplaySize crash 2021-08-24 17:47:42 +10:00
Sinai
fae85c2968 Bump version 2021-08-23 18:35:36 +10:00
Sinai
fc8fa9aa7a Fix TestClass init mistake 2021-08-23 18:35:31 +10:00
Sinai
bcf9a801a9 Fix suggestions still being given in comments sometimes 2021-08-23 18:35:22 +10:00
Sinai
20298aa47b Make Type and Member names selectable / copy+paste-able 2021-08-23 18:35:08 +10:00
Sinai
e2c1c186c3 Add wrapper to handle LemonAction issue 2021-08-23 18:31:26 +10:00
Sinai
9ce6508828 Update README.md 2021-08-19 16:20:41 +10:00
Sinai
506e75c5fe Handle Unhollowed modules path through IExplorerLoader. Allow Standalone release to specify manually. 2021-08-19 16:20:25 +10:00
Sinai
a2f22051f0 Cleanup 2021-08-19 16:19:49 +10:00
Sinai
4e3203a91b Make Assembly.GetTypes patch a finalizer instead of prefix 2021-08-10 17:31:12 +10:00
Sinai
a411ce2dba Add patch for Assembly.GetTypes to catch exceptions 2021-08-10 17:17:44 +10:00
Sinai
48132b3d46 Cleanup ILRepack 2021-08-10 17:17:21 +10:00
Sinai
e49ed3028f Cleanup 2021-08-06 18:44:13 +10:00
Sinai
31dd54d25c Reduce string alloc 2021-08-06 16:02:58 +10:00
Sinai
3cfdd6fa43 Update readme -noci 2021-08-04 01:16:52 +10:00
Sinai
1fa1283a68 Cleanup and update readme 2021-08-03 18:30:07 +10:00
Sinai
afa4135b67 Update ML lib for "LemonCleanup" breaking changes 2021-08-03 16:12:28 +10:00
Sinai
48d1cf574d Fix evaluate exception logic with methods that have arguments 2021-08-03 16:11:54 +10:00
Sinai
df0abbc847 Small optimizations/cleanup 2021-08-03 16:11:16 +10:00
Sinai
5c9dcb1d43 Bump HarmonyX to 2.5.2 2021-07-28 19:14:37 +10:00
Sinai
602770d980 Cleanup 2021-07-28 19:01:43 +10:00
Sinai
f26371f95f Go back to previous panel transform saving, no need to change 2021-07-28 18:27:10 +10:00
Sinai
a673c39f4a Include arial in legacy bundles 2021-07-28 18:26:53 +10:00
Sinai
40583cae3d Include arial in legacy bundles, cleanup 2021-07-28 06:41:02 +10:00
Sinai
20018a9ba9 Use invariant decimal separator for NumberFormatString 2021-07-28 06:40:05 +10:00
Sinai
dabf92a1a5 Use CurrentCulture, and use whitespace instead of comma as separator 2021-07-27 22:17:26 +10:00
Sinai
b7e275f02c Cleanup 2021-07-27 22:12:48 +10:00
Sinai
f393e0d706 Include Arial font, don't rely on built-in resource
TODO add font to legacy bundles
2021-07-27 18:14:44 +10:00
Sinai
ab8acc9e84 Change directory case 2021-07-21 20:53:03 +10:00
Sinai
66c30ee70e Cleanup 2021-07-21 20:48:21 +10:00
Sinai
ddd271c00d Cleanup 2021-07-21 20:12:34 +10:00
Sinai
30fe9e4dde Cleanup 2021-07-21 18:37:01 +10:00
Sinai
fa3a436037 Cleanup 2021-07-21 18:29:01 +10:00
Sinai
ca27d2b20f Update CursorUnlocker.cs 2021-07-21 05:18:22 +10:00
Sinai
4315e0c547 Merge branch 'master' of https://github.com/sinai-dev/UnityExplorer 2021-07-21 04:23:55 +10:00
Sinai
3e19e74329 Update readme -noci 2021-07-21 04:17:41 +10:00
Sinai
5a3ffebadc
Remove legacy build 2021-07-21 04:16:53 +10:00
Sinai
6e6b6239d8 Do patching in CursorUnlocker, add patch for SetSelectedGameObject 2021-07-21 04:14:34 +10:00
Sinai
03c8e5a8bd Add Harmony instance to ExplorerCore, bump version 2021-07-21 04:14:12 +10:00
Sinai
44f7209843 Remove ML 0.3 builds 2021-07-21 04:13:54 +10:00
Sinai
734e45cf9f Remove patching in mod loader classes 2021-07-21 04:13:42 +10:00
Sinai
97838e0b3a Update Unhollower 2021-07-21 04:13:15 +10:00
Sinai
304b47f898 Bump version 2021-07-19 21:43:40 +10:00
Sinai
3d1fcbcd9f Fix duplicate Scene hashcodes breaking PopulateSceneDropdown 2021-07-19 21:43:36 +10:00
Sinai
36fc17aa43 Get rid of pointless ReadOnlyCollection properties 2021-07-19 21:43:16 +10:00
Sinai
adfa29e63c Bump version 2021-07-15 05:20:31 +10:00
Sinai
3ffdcea73b Force all devices to always be supported by InputSystem 2021-07-15 05:20:26 +10:00
Sinai
dfd55260a8 Fallback to null check loading if unityVersion throws an exception 2021-07-15 05:19:48 +10:00
Sinai
29c78dc5a6 Manually get Major and Minor instead of using Version class 2021-07-11 23:22:33 +10:00
Sinai
bf59d9d6cd Handle cases where Unity doesn't include 'f' suffix on version
Not sure if this ever happens but just in case
2021-07-11 18:19:09 +10:00
Sinai
bb0c59534a Bump version 2021-07-11 18:11:18 +10:00
Sinai
802bb722bc Use Application.unityVersion to load appropriate AssetBundle
And fix issue with Dropdowns and Time input label not refreshing properly on launch
2021-07-11 18:11:14 +10:00
Sinai
9ca992b0d7
Fix incorrect config description example 2021-07-07 23:27:43 +10:00
Sinai
5f3b3a6870
cleanup -noci 2021-07-07 23:21:40 +10:00
Sinai
f5bce439cb Favor public GetEnumerator over private. Use GetActualType. Improve logging. 2021-07-06 16:42:20 +10:00
Sinai
e2b2c9038a Add 'other' issue template -noci 2021-07-05 19:05:04 +10:00
Sinai
fbefccd6b7 Update issue template -noci 2021-07-02 23:32:02 +10:00
Sinai
271c91f0d0 Update README.md 2021-07-02 20:03:41 +10:00
Sinai
eb221bd868 Bump version 2021-07-02 18:45:09 +10:00
Sinai
5b516eb4cc Add assembly name to class search result labels 2021-07-02 18:45:03 +10:00
Sinai
601567f9d2 Remove arbitrary static restriction on class search 2021-07-02 17:53:12 +10:00
Sinai
7ff508b874 [IL2CPP] Support private interface implementations on IDictionary and IEnumerable 2021-07-02 17:45:18 +10:00
Sinai
09a7cd35cf Remove known issues from readme -noci 2021-07-02 17:35:34 +10:00
Sinai
db4a338d26 Update issue template -noci 2021-07-02 17:33:41 +10:00
Sinai
c08e02057c
Create enhancement.yaml 2021-07-02 17:31:36 +10:00
Sinai
362fcdc51a Update bug_report.yaml 2021-07-02 17:22:24 +10:00
Sinai
73bd172e4d Update bug_report.yaml 2021-07-02 17:16:09 +10:00
Sinai
454d3bd0b4 Add bug report issue template 2021-07-02 17:10:26 +10:00
Sinai
f815a13d9a Namespace cleanup, move some categories out of UI namespace 2021-06-30 07:49:58 +10:00
Sinai
65c4d49274 Update readme 2021-06-26 18:08:21 +10:00
Sinai
d99137526e Fix InspectUnderMouse breaking ScrollPool in rare cases 2021-06-22 20:39:46 +10:00
Sinai
92447b55cd Update README.md 2021-06-22 19:48:41 +10:00
Sinai
87d5d5a2de Bump version 2021-06-22 19:46:14 +10:00
Sinai
08cff3386b Fix issues with Il2Cpp nullables 2021-06-22 19:46:09 +10:00
Sinai
6033200579 Don't use WaitForEndOfFrame in SrollPool init coroutine 2021-06-22 19:45:57 +10:00
Sinai
94ec1c4908 Update line numbers on panel resize 2021-06-21 19:50:11 +10:00
Sinai
7a400e762c Cleanup 2021-06-21 19:49:44 +10:00
Sinai
67f9f744bb Handle Unity 2021+ InputField.onEndEdit change 2021-06-21 19:26:05 +10:00
Sinai
7a59f9a2a1 Update info about startup script -noci 2021-06-20 19:10:44 +10:00
Sinai
9b42eef1b9 Line numbers and startup script 2021-06-20 19:06:52 +10:00
Sinai
830000b019 Bump version 2021-06-20 19:06:33 +10:00
Sinai
34910ab273 Bump version 2021-06-14 18:56:56 +10:00
Sinai
86b036095e Allow panels to be dragged further outside the game window 2021-06-14 18:56:51 +10:00
Sinai
b57e5be2e6 Add GameObject.activeSelf toggle to TransformTree, adjust UI Toggle design 2021-06-14 18:43:26 +10:00
Sinai
2d8ae45814 Cleanup 2021-06-14 18:43:08 +10:00
Sinai
66dc262a68 Move inner exception null check outside IL2CPP ppd 2021-06-11 18:12:14 +10:00
Sinai
4342901206 Prevent null exceptions being used in ReflectionExToString 2021-06-11 17:36:35 +10:00
Sinai
58b7c72a5c Allow UI inspect without main camera 2021-06-11 17:36:17 +10:00
Sinai
623dc7b7be Clarify VS build instructions 2021-06-10 18:14:33 +10:00
Sinai
e6f4939cc9
Update README.md 2021-06-07 19:50:36 +10:00
Sinai
7a539ba78b Bump version 2021-06-07 19:28:25 +10:00
Sinai
0d10f94eb5 Use Paths.BepInExRootPath, and cleanup dirs 2021-06-07 19:27:39 +10:00
Sinai
91671bf243 Failsafe in case Component is null from GetComponents? 2021-06-07 19:27:09 +10:00
Sinai
a72877befb Make AllTypes protected, force using GetTypeByName 2021-06-07 19:26:46 +10:00
Sinai
16335c1bc4 Auto-cleanup 2021-06-05 19:36:09 +10:00
Sinai
8fab9e6268 Update readme -noci 2021-06-03 17:50:48 +10:00
Sinai
fdd9039cca Update README.md 2021-06-03 17:47:57 +10:00
Sinai
dcca980635 Merge branch 'master' of https://github.com/sinai-dev/Explorer 2021-06-03 17:19:01 +10:00
Sinai
bfcab8248e Bump version 2021-06-03 17:18:52 +10:00
Sinai
97c20144f1 Fix string/comment state being incorrect if match ended at last character 2021-06-03 17:18:46 +10:00
Sinai
aaab10a0a0 Do auto-indent before highlighting so the characters are in the correct position 2021-06-03 17:18:11 +10:00
Sinai
b42a8dbe6a
Update readme -noci 2021-06-03 02:48:14 +10:00
Sinai
d7008db22e
Update README.md 2021-06-02 16:25:12 +10:00
Sinai
8c1913fe80
Update README.md 2021-06-02 15:33:19 +10:00
Sinai
8d8c9ac7c9 Use whitespace as delimiter in completion composition, handle string/comment state with Lexer 2021-06-01 16:40:51 +10:00
Sinai
f35beeaf58 Bump version 2021-06-01 16:00:56 +10:00
Sinai
d150ff3455 Fix minor issues with CSConsole delimiter logic 2021-06-01 16:00:52 +10:00
Sinai
c4fa0d6bcd Add better time logging to reflection init 2021-06-01 16:00:18 +10:00
Sinai
a5f56cf5a3 Prevent very large Texture images from overflowing outside the Texture Viewer 2021-05-31 19:10:05 +10:00
Sinai
8c822b2ee9
Simplify ci workflow 2021-05-30 04:50:37 +10:00
Sinai
4681b7e192 Update README -noci 2021-05-29 19:46:39 +10:00
Sinai
97093733d8
Update README -noci 2021-05-29 19:42:12 +10:00
Sinai
615f77979f Update README -noci 2021-05-29 19:41:14 +10:00
Sinai
ba3cf970d9
Update README.md 2021-05-29 19:30:08 +10:00
Sinai
b2fb571b18
Testing ci skip -noci 2021-05-29 19:15:28 +10:00
Sinai
67ce6f946a
Update dotnet.yml 2021-05-29 19:13:30 +10:00
Sinai
1b82ccb49f Bump version 2021-05-29 19:07:44 +10:00
Sinai
480eb5afd5 Use HarmonyX NuGet package 2021-05-29 19:07:26 +10:00
Sinai
88ea2a09c9
Update README.md 2021-05-29 18:46:17 +10:00
Sinai
a678aa4d78
Update dotnet.yml 2021-05-29 18:30:52 +10:00
Sinai
eaf478e314 Using temporary manual HarmonyX reference 2021-05-29 18:27:40 +10:00
Sinai
d391968b32
Update dotnet.yml 2021-05-29 17:50:59 +10:00
Sinai
70349ad7c7
Update dotnet.yml 2021-05-29 17:48:02 +10:00
Sinai
78f2d1070f
Update dotnet.yml 2021-05-29 17:46:59 +10:00
Sinai
51307563ab
Update dotnet.yml 2021-05-29 17:41:08 +10:00
Sinai
185d1aaa0f
Update dotnet.yml 2021-05-29 17:38:21 +10:00
Sinai
3d6e8fcbf8
Update dotnet.yml 2021-05-29 17:36:56 +10:00
Sinai
1daf4fade4 Use HarmonyX NuGet instead of submodule 2021-05-29 17:36:07 +10:00
Sinai
d92fb3f83f
Update dotnet.yml 2021-05-29 17:27:52 +10:00
Sinai
fe24b68fe2
Update dotnet.yml 2021-05-29 17:24:53 +10:00
Sinai
6bf92b9a96
Update dotnet.yml 2021-05-29 17:20:42 +10:00
Sinai
9f1cab019d
Create dotnet.yml 2021-05-29 17:18:09 +10:00
Sinai
a131404ac7 Cleanup 2021-05-29 14:50:27 +10:00
Sinai
773900d749 Fix CacheProperty not resetting Exception state when it has arguments 2021-05-29 14:50:21 +10:00
Sinai
342fc6bdb8 Maintain last timeScale value 2021-05-28 18:48:55 +10:00
Sinai
e85ea6ac3a Make Il2CppProvider actually process FixedUpdate coroutines 2021-05-28 18:23:45 +10:00
Sinai
af889e64cb Fix exception when inspecting UnityObject classes with static reflection 2021-05-28 18:23:30 +10:00
Sinai
0274022ce4 Make sure WaitForEndOfFrame object is never null 2021-05-28 18:23:07 +10:00
Sinai
211576e0f8 Fallback to LateUpdate if OnPostRender listener failed 2021-05-28 18:22:44 +10:00
Sinai
3e42d7479f Update README.md 2021-05-28 16:59:22 +10:00
Sinai
df4dea20c1 Update README.md 2021-05-28 16:55:01 +10:00
Sinai
ece0c43067 Add Time.timeScale helper on main navbar 2021-05-28 16:39:42 +10:00
Sinai
6311c8d09a Bump version 2021-05-28 15:51:09 +10:00
Sinai
04739d0be8 Separate default reflection blacklist from user list, add try/catch 2021-05-28 15:51:03 +10:00
Sinai
a46acba265 Better JumpToIndex height calculation 2021-05-27 19:44:17 +10:00
Sinai
5515b2eae4 Bump version 2021-05-27 19:31:01 +10:00
Sinai
9992029e28 Set DataViewInfo struct back to array in rebuild, cleanup 2021-05-27 19:30:55 +10:00
Sinai
14105785f0 Fix SceneExplorer not properly detecting scene changes sometimes 2021-05-27 19:30:19 +10:00
Sinai
365269b0dd Clear GameObject Component and Transform lists properly on close 2021-05-27 19:29:00 +10:00
Sinai
0b973393d1 Cleanup 2021-05-27 19:28:22 +10:00
Sinai
701d4431ae Delete explorerui.legacy.bundle.bak.5.3.8 2021-05-27 16:00:42 +10:00
Sinai
bfa73bcb55 Cleanup Pool.cs 2021-05-26 19:42:56 +10:00
Sinai
b0bbeb3cf8 Cleanup and fix small issue with JumpToIndex 2021-05-26 18:32:47 +10:00
Sinai
1a26623080 Add option to disable EventSystem override 2021-05-26 18:02:10 +10:00
Sinai
041f2938f7 Implement jumping to index in TransformTree 2021-05-26 17:42:31 +10:00
Sinai
9e7bb1a625 Cleanup 2021-05-26 17:42:14 +10:00
Sinai
36f23b7cdc Move SceneHandler.cs 2021-05-26 17:41:51 +10:00
Sinai
b51b743df4 Prevent very niche recursion situation 2021-05-26 17:41:38 +10:00
Sinai
805aff07cc Update README.md 2021-05-26 17:41:19 +10:00
Sinai
bcdaf3b97e Bump version 2021-05-26 17:41:14 +10:00
Sinai
cb8e947fdf Namespace/structure cleanup 2021-05-26 17:40:09 +10:00
Sinai
c8899be3ae Bump version 2021-05-26 03:59:50 +10:00
Sinai
cd5c69c965 Add timer debug to deobfuscation cache 2021-05-26 03:59:45 +10:00
Sinai
5427312f18 Filter UnityExplorer objects from search results 2021-05-26 03:59:17 +10:00
Sinai
eb7e80d910 Make sure Mouse Inspect dropdown list gets destroyed after option chosen 2021-05-26 03:59:08 +10:00
Sinai
a54888ae3a Make DataViewInfo a struct instead of class 2021-05-25 15:46:30 +10:00
Sinai
4f0553d293 Remove formatting from ToStringUtility 2021-05-23 19:34:32 +10:00
Sinai
9f0f7f9b57 Prevent some niche exceptions with EventSystem 2021-05-23 18:33:19 +10:00
Sinai
383c6f19e8 Update README.md 2021-05-23 16:20:09 +10:00
Sinai
428fab28f9 Cleanup HideAndDontSave detection and support 2021-05-23 16:16:32 +10:00
Sinai
760b2981ad Update README.md 2021-05-23 13:59:29 +10:00
Sinai
eee7d6bcc4 Add ML 0.3.0 build 2021-05-23 13:58:26 +10:00
Sinai
e270f205a1 Fix scroll pool inserting off-by-one 2021-05-20 20:22:45 +10:00
Sinai
084aee617c Prevent null reference if Canvas isn't created yet 2021-05-19 22:21:08 +10:00
Sinai
d0e508727a Prevent deobfuscation crash from using Il2CppType.From, and use faster method anyway 2021-05-19 21:26:44 +10:00
Sinai
a9a53ba924 Force load all Unhollowed DLLs, use Assembly.LoadFile instead of .Load, blacklist some more types 2021-05-19 20:48:34 +10:00
Sinai
3cd9819790 remove backup libs 2021-05-19 19:47:13 +10:00
Sinai
5abfa3da67 Better EntryType checking for enumerables and dicts 2021-05-19 19:24:33 +10:00
Sinai
e5d2d29a47 Update README.md 2021-05-19 19:24:06 +10:00
Sinai
6a47e542e5 Update Extensions.cs 2021-05-19 18:46:01 +10:00
Sinai
f1b83e7c9e Cleanup 2021-05-19 18:45:53 +10:00
Sinai
44c6503ae2 Update unhollowed libs 2021-05-19 18:45:19 +10:00
Sinai
6970dcbbc7
Merge pull request #68 from sinai-dev/4.0.0-alpha
4.0 hotfixes
2021-05-18 21:20:09 +10:00
Sinai
ac9c2d5286 Use recursive GetGenericArguments to catch unusual type structures, cleanup InteractiveList value caching 2021-05-18 20:55:18 +10:00
Sinai
496a5de55e Update README.md 2021-05-18 20:44:42 +10:00
Sinai
b062924af7 Add support for writing to IList<T>'s which don't implement IList 2021-05-18 20:43:51 +10:00
Sinai
5aef8ddc99 Fix UIPanels being broken after resolution changes, better checks on size/position 2021-05-18 19:55:27 +10:00
Sinai
c134c1752e Update README.md 2021-05-18 01:25:57 +10:00
Sinai
e4615aff84
Merge pull request #67 from sinai-dev/4.0.0-alpha
4.0.0 RC1
2021-05-18 00:18:29 +10:00
Sinai
8c5640dd12 Merge branch 'master' into 4.0.0-alpha 2021-05-18 00:18:04 +10:00
Sinai
76f71d9f3d Update README.md 2021-05-18 00:15:20 +10:00
Sinai
82e9c08ae6 Update img and README, cleanup 2021-05-18 00:13:29 +10:00
Sinai
019e589947 Add namespace autocompletions, some adjustments to autocomplete logic 2021-05-17 23:20:06 +10:00
Sinai
d7b0fff949 IL2CPP List/Dict support, cleanups 2021-05-17 21:48:39 +10:00
Sinai
7dbf694642 IL2CPP reflection fixes and improvements 2021-05-17 21:48:10 +10:00
Sinai
2fc9657560 Some UI adjustments and layout fixes 2021-05-17 18:47:37 +10:00
Sinai
fb6e413153 Misc cleanups and adjustments 2021-05-16 21:46:38 +10:00
Sinai
ca65affb5c Finish GameObject Inspector, some UI cleanups 2021-05-16 21:46:19 +10:00
Sinai
f4e473f8e6 Use StringBuilder for GetTransformPath 2021-05-16 21:45:38 +10:00
Sinai
8c5e7678a6 Fix LayerMask Parsing 2021-05-16 21:45:29 +10:00
Sinai
32ad61baea Rename ButtonListSource 2021-05-16 21:45:19 +10:00
Sinai
df330420a3 Add config to change main navbar anchor 2021-05-16 21:45:09 +10:00
Sinai
5af9d3104d Start GO inspector 2021-05-15 20:39:56 +10:00
Sinai
6977f1a31c Prevent any height value being smaller than default height 2021-05-15 20:39:51 +10:00
Sinai
26fb53f183 Color adjustments 2021-05-15 20:39:38 +10:00
Sinai
cccd02255f Force stop panel drag/resize when starting Inspect Under Mouse 2021-05-15 20:39:29 +10:00
Sinai
83f15c7168 Use Il2CppObjectBase instead of Il2CppSystem.Object where possible.
Attempt to fix il2cpp lists/dicts, not currently working properly. Will probably wait for Unhollower rewrite.
2021-05-15 18:00:16 +10:00
Sinai
bf8f838f01 Remove Control Key requirement on autocomplete navigation 2021-05-15 06:23:32 +10:00
Sinai
a915e1028f Update UIManager for new additions, cleanup 2021-05-15 06:23:13 +10:00
Sinai
8b1379f17e Adjust main navbar, expose nav gameobject 2021-05-15 06:23:01 +10:00
Sinai
0c7d8f8435 Update UnityExplorer.csproj 2021-05-15 06:21:45 +10:00
Sinai
72c3af3dd7 Prevent panels dragging outside screen 2021-05-15 06:21:42 +10:00
Sinai
54f78ac10b Implement InspectUnderMouse 2021-05-15 06:20:56 +10:00
Sinai
2a9c4972dd Revised C# Console help/feedback 2021-05-15 06:20:44 +10:00
Sinai
e93edc5b19 Options cleanup 2021-05-15 06:20:07 +10:00
Sinai
c25abfe3ff Fix normal args setting generic arg input field placeholder text 2021-05-15 06:19:44 +10:00
Sinai
8c3603baa0 Add AllowNavigation property to ISuggestionProvider, implement 2021-05-15 01:41:03 +10:00
Sinai
021db69409 Improve C# Console, key navigation on AutoCompleter 2021-05-15 01:21:07 +10:00
Sinai
1c216c0d86 Add some CSConsole interactions, some UI Cleanups 2021-05-14 06:14:25 +10:00
Sinai
12fe19ba8e Implemented the console log, some cleanups 2021-05-14 02:45:59 +10:00
Sinai
89022db5fc Implement Options panel, some cleanups 2021-05-13 23:03:30 +10:00
Sinai
ccd08c3a63 Add configurable reflection signature blacklist, extends to MCS as well 2021-05-13 23:02:46 +10:00
Sinai
843d7ed451 Update mcs-unity 2021-05-13 22:56:23 +10:00
Sinai
3e44317861 Cleanup CSConsole, add start of Options and Log panels 2021-05-13 03:55:08 +10:00
Sinai
70d66f93a5 Update ReflectionUtility.cs 2021-05-13 01:06:14 +10:00
Sinai
275225a284 Better number ToString formatting, cleanups 2021-05-13 00:58:23 +10:00
Sinai
b61020fe67 Cleanup 2021-05-12 21:29:59 +10:00
Sinai
ada239c828 Implement auto-indenting for CSConsole, some cleanups 2021-05-12 20:48:56 +10:00
Sinai
fedecb80a0 Update mcs-unity 2021-05-12 20:47:46 +10:00
Sinai
97738b00c1 Update mcs-unity 2021-05-11 23:17:11 +10:00
Sinai
59cbeec103 cleanup 2021-05-11 23:10:12 +10:00
Sinai
a9f6ed8729 Cleanup libs, target ML 0.3.1 2021-05-11 20:23:52 +10:00
Sinai
7241247d05 Rename some members to avoid confusion 2021-05-11 19:18:27 +10:00
Sinai
ec215a0006 Use SortedSet for type name cache, expose OnTypeLoaded event 2021-05-11 19:16:19 +10:00
Sinai
6e9bb83099 More progress on C# Console - implement AutoCompletes, some cleanups 2021-05-11 19:15:46 +10:00
Sinai
712bf7b669 Cleanup libs, use submodules and packages where appropriate 2021-05-11 19:13:58 +10:00
Sinai
b4b96134c4 add mcs-unity submodule properly 2021-05-11 17:55:47 +10:00
Sinai
d3b942065d temp remove mcs submodule 2021-05-11 17:55:23 +10:00
Sinai
9ea50e232c use submodules for HarmonyX and Unhollower 2021-05-11 17:47:22 +10:00
Sinai
4128f8519d Update .gitmodules 2021-05-11 17:45:54 +10:00
Sinai
53e1e6bf22 Update .gitmodules 2021-05-11 17:44:31 +10:00
Sinai
b67ac145d4 Update .gitmodules 2021-05-11 17:39:00 +10:00
Sinai
586c63b668 Update .gitmodules 2021-05-11 17:32:13 +10:00
Sinai
65323e3b16 Update .gitmodules 2021-05-11 17:29:34 +10:00
Sinai
cfeb5ba018 Create .gitmodules 2021-05-11 17:24:03 +10:00
Sinai
8a15c11289 Remove redundant GameObject search context 2021-05-11 02:39:01 +10:00
Sinai
4019af5936 Hide TypeCompleter on suggestion chosen 2021-05-11 02:38:39 +10:00
Sinai
34c8ad3646 Make PruneString helper 2021-05-11 02:38:24 +10:00
Sinai
617d68f7e9 rename Lexer folder to match namespace, some cleanups and color adjustments 2021-05-11 01:43:08 +10:00
Sinai
2efce9eb0e Simplify keyword highlighting 2021-05-10 23:24:52 +10:00
Sinai
18d2518231 Use the Member color for the member filter toggles, move InspectorManager 2021-05-10 23:09:21 +10:00
Sinai
cef4c2f3fb Cleanup and simplify highlight process, reduce string alloc 2021-05-10 23:00:02 +10:00
Sinai
1d24af5666 Only lexer-highlight what is shown in CS console (fix max vert overflow) 2021-05-10 21:07:27 +10:00
Sinai
4f50afdddc Update SymbolLexer.cs 2021-05-10 16:35:37 +10:00
Sinai
caad39bb9a Rewrite lexer from scratch 2021-05-10 15:58:49 +10:00
Sinai
06122fe8c9 Update CSLexer.cs 2021-05-09 20:32:47 +10:00
Sinai
e6b253fed9 Enum parse support, start work on CSConsole, cleanup 2021-05-09 20:18:33 +10:00
Sinai
7b700cbe55 Cleanup, extend ParseUtility to dict keys 2021-05-09 02:22:03 +10:00
Sinai
c04a864b74 Made ParseUtility helper to simplify and improve parsing of various input types 2021-05-09 01:25:26 +10:00
Sinai
c828d9b642 InteractiveValueStruct, and a few cleanups 2021-05-08 20:54:16 +10:00
Sinai
26052621e5 Cleanup 2021-05-08 06:19:17 +10:00
Sinai
d101e7e35c Cleanup 2021-05-08 06:18:46 +10:00
Sinai
57aace26d3 Refresh for child count or name changes in TransformTree 2021-05-08 06:18:28 +10:00
Sinai
3d94b51d40 Catch bad user input on number input 2021-05-08 06:17:30 +10:00
Sinai
d34aeb81b3 InteractiveEnum, InteractiveColor 2021-05-08 06:16:43 +10:00
Sinai
d8f532d913 Make InputFieldRef helper, InteractiveString and IOUtility 2021-05-07 17:06:56 +10:00
Sinai
4931117b1e Make helper for cache object controller SetCell 2021-05-07 06:27:44 +10:00
Sinai
1f996f52fe Fix casting for dictionary keys, only cast displayed key
And fix layout
2021-05-07 06:27:23 +10:00
Sinai
00c28f781a Allow editing null strings, remove "null" ValueState 2021-05-07 06:26:48 +10:00
Sinai
f080379e8a Update ReflectionUtility.cs 2021-05-07 06:25:49 +10:00
Sinai
2977fd4df5 Handle il2cpp primitives (not boxed) 2021-05-07 06:25:31 +10:00
Sinai
56875e0641 Simplify string obfuscation processing 2021-05-07 01:53:02 +10:00
Sinai
8534c08f49 Reflection cleanup, fix il2cpp struct and enum boxing
And temp removing il2cpp IDictionary / IEnumerable helpers, will see what is necessary after knah's rewrite.
2021-05-07 01:22:55 +10:00
Sinai
1ee10c2507 Setting values from IList / IDictionary to source 2021-05-06 20:28:04 +10:00
Sinai
9e8a18a5e1 Fix cell view link mismatch 2021-05-06 16:47:37 +10:00
Sinai
6c7acf7690 Handle boxing value types to Il2CppSystem.Object, some cleanups 2021-05-06 06:36:39 +10:00
Sinai
e70a1e96da Update ReflectionInspector.cs 2021-05-06 04:18:35 +10:00
Sinai
22435176bf Fix some issues in IL2CPP, improve type cache efficiency, reduce alloc 2021-05-06 04:02:42 +10:00
Sinai
e4ff86259b More progress 2021-05-05 21:27:09 +10:00
Sinai
961ff80c6d Update GameObjectInspector.cs 2021-05-04 20:39:54 +10:00
Sinai
a89d66cf81 More progress, cleanups and fixes 2021-05-04 20:10:46 +10:00
Sinai
302ff29e36 Merge branch '4.0.0-alpha' of https://github.com/sinai-dev/Explorer into 4.0.0-alpha 2021-05-03 21:02:09 +10:00
Sinai
8d9d8f76c2 Cleanup, use Time.realTimeSinceStartup instead of Time.time, add some stuff 2021-05-03 21:02:01 +10:00
Sinai
3dc458ab1b
Merge pull request #62 from HerpDerpinstine/4.0.0-alpha
Added ML v0.3.1 Support and Commented it Out
2021-05-03 20:59:47 +10:00
Herp Derpinstine
f5c0b339ae
Added ML v0.3.1 Support and Commented it Out 2021-05-03 01:13:43 -05:00
Sinai
ad61ff243a progress on lists and dictionaries, fixes for scrollpool 2021-05-03 01:29:02 +10:00
Sinai
bfaba56b76 bump lib versions 2021-05-03 01:10:12 +10:00
Sinai
1c5306b7c8 Fix the onValueChange throttling affecting internal features 2021-05-03 00:59:39 +10:00
Sinai
15ec64b106 Progress on inspector, interactive list basically done 2021-05-01 20:55:27 +10:00
Sinai
ab8b736f7e Improve Il2Cpp Coroutine support, make universal ExplorerBehaviour class 2021-05-01 20:55:14 +10:00
Sinai
ea1e183c4a Fix onValueChanged bursts 2021-05-01 16:32:11 +10:00
Sinai
d6cde68a44 Fix namespaces being included for generic parameters 2021-04-30 23:43:36 +10:00
Sinai
d76bc1f812 Add ContainsIgnoreCase helper to reduce string alloc, cleanup 2021-04-30 23:43:27 +10:00
Sinai
74ff1d8f01 Cleanup 2021-04-30 23:12:18 +10:00
Sinai
2378925a8b More progress 2021-04-30 21:34:50 +10:00
Sinai
8080129d58 Merge branch 'master' of https://github.com/sinai-dev/Explorer 2021-04-30 00:12:48 +10:00
Sinai
4b8298fd2e Update CursorUnlocker.cs 2021-04-30 00:12:41 +10:00
Sinai
ad055b4383
Update README.md 2021-04-29 21:54:13 +10:00
Sinai
23483a6108 Add aggressive mouse unlock option using WaitForEndOfFrame 2021-04-29 21:45:45 +10:00
Sinai
0bc14b2f76 Update CursorUnlocker.cs 2021-04-29 21:05:53 +10:00
Sinai
dba9bdbdc2 More progress, and change Aggressive Mouse Unlock behaviour 2021-04-29 21:01:08 +10:00
Sinai
a2a2b09d33 more progress 2021-04-28 23:58:13 +10:00
Sinai
324d3afa5b
Update CacheMember.cs 2021-04-28 21:52:42 +10:00
Sinai
99e11b41a3
Update DataHeightCache.cs 2021-04-28 21:20:41 +10:00
Sinai
b0d54b1d80 Progress on ReflectionInspector, framework mostly done 2021-04-28 20:47:48 +10:00
Sinai
a2ff37e36d Some progress on inspector rewrites, most of the framework figured out now. 2021-04-27 21:22:48 +10:00
Sinai
07ddba3c3d Update ReflectionUtility.cs 2021-04-27 21:22:21 +10:00
Sinai
73cde0f91f Fix for games where InputSystem is present but not active 2021-04-27 21:22:16 +10:00
Sinai
af3ee07143 Rewriting everything from scratch, added generic ObjectPool system 2021-04-26 19:56:41 +10:00
Sinai
9f8d53f55a Rewriting everything from scratch, developed generic ObjectPool system 2021-04-26 19:56:21 +10:00
Sinai
5a0c2390ce Use StringBuilder and add caching to reduce string allocs 2021-04-25 21:21:05 +10:00
Sinai
f3cd84804d Some UI cleanups, improving caching and reduce image allocation 2021-04-25 21:20:50 +10:00
Sinai
fda5afae46 stress test 2021-04-25 21:19:12 +10:00
Sinai
7f6a4514e4 Handle cases where InputSystem is present but not active 2021-04-25 21:19:00 +10:00
Sinai
1487372832 Update DataHeightCache.cs 2021-04-25 00:28:30 +10:00
Sinai
6d4cc66079 Adding back rest of the menu, ported most of Reflection Inspector for new UI 2021-04-25 00:21:12 +10:00
Sinai
0cf8309a82 Fix DataHeightCache logic, cleanup some loose ends and edge cases, add rebuild fix 2021-04-24 16:45:17 +10:00
Sinai
38bd19c243 cleanup 2021-04-24 05:23:29 +10:00
Sinai
bda286ddae Make AutoCompleter a global widget which anything can use, add support to object search for it 2021-04-24 04:03:33 +10:00
Sinai
5f2f3fe1c6 Fix logic in data height cache, account for spread properly 2021-04-24 04:02:26 +10:00
Sinai
59156492e7 Add jump to top logic for rebuild and refresh 2021-04-24 04:01:30 +10:00
Sinai
ebb89b1b8b Update UnityExplorer.csproj 2021-04-24 04:01:03 +10:00
Sinai
30f847dc23 Some improvements to panel dragging logic 2021-04-24 04:00:58 +10:00
Sinai
7ffaf62895 Improve deobfuscation efficiency 2021-04-24 04:00:15 +10:00
Sinai
f509a985e7 Added Search page and AutoCompleter 2021-04-23 21:50:58 +10:00
Sinai
eb58ab5327 Fix TransformCell for destroyed transforms 2021-04-22 22:57:04 +10:00
Sinai
feb86a77fd Cleanup scroll pool, fix some minor things 2021-04-22 22:56:46 +10:00
Sinai
012994ed02
Fix typo 2021-04-22 21:19:48 +10:00
Sinai
212d9a4d5e
Fix Take from sister cache 2021-04-22 21:18:31 +10:00
Sinai
a4f774b6b2 Fix unity log listeners 2021-04-22 20:11:34 +10:00
Sinai
bd6de84f93 Prevent dragging/resizing panels underneath the focused panel 2021-04-22 20:11:27 +10:00
Sinai
0d385c9cb8 Update ExplorerCore.cs 2021-04-22 19:12:16 +10:00
Sinai
fdfadcefc1 Added 'temp height cache' to ScrollPool for when filtering, fix some issues 2021-04-22 17:53:29 +10:00
Sinai
fc26452f64 Add elasticity to ScrollPool, stop movement on mouse scroll or slider change 2021-04-22 03:57:34 +10:00
Sinai
31fa786574 add MouseScrollDelta support to InputManager 2021-04-22 03:57:11 +10:00
Sinai
29b453dc91 final touches on scroll pool 2021-04-22 03:31:03 +10:00
Sinai
837d5792be Update DataHeightManager.cs 2021-04-22 01:04:59 +10:00
Sinai
1a8c2499fa Improve range start lookup efficiency 2021-04-21 23:39:18 +10:00
Sinai
e1e40950f8 Update DataHeightManager.cs 2021-04-21 23:08:16 +10:00
Sinai
edbb9a2882 Cleanup and fix some small issues with scroll pool 2021-04-21 23:07:15 +10:00
Sinai
0a9639f8a9 attempt at auto-increasing pool size, not quite working properly 2021-04-21 21:04:26 +10:00
Sinai
b32675e3b1 Finally got dynamic scroll pool working perfectly
Just need to add cells to pool if viewport height is expanded, otherwise I'd say its done.
2021-04-21 18:44:43 +10:00
Sinai
ff7c822d69 More progress on the dynamic scroll pool, almost done 2021-04-20 21:09:07 +10:00
Sinai
a619df8e01 Delete ScrollPool_bak.cs 2021-04-19 23:47:41 +10:00
Sinai
300b35c2d3 Finally got the scrollpool working properly with dynamic content height 2021-04-19 23:47:25 +10:00
Sinai
7a253fa0a0 replace old scrollpool with new dynamic one, more progress 2021-04-19 20:08:07 +10:00
Sinai
8b5e385c28 Working on a dynamic-height scroll pool, almost done 2021-04-18 21:38:09 +10:00
Sinai
bcc89455a7 rename "InfiniteScrollRect" to "ScrollPool" 2021-04-17 04:11:45 +10:00
Sinai
2e5fb72716 Update PanelDragger to handle multiple panels, add panel 'focusing' 2021-04-17 04:05:27 +10:00
Sinai
876cffd864 Delete PageHandler.cs 2021-04-16 23:59:58 +10:00
Sinai
7cb4faa596 Adjust panel size/pos 2021-04-16 23:59:54 +10:00
Sinai
c8f3a7f430 Fix min resize 2021-04-16 23:59:41 +10:00
Sinai
6cd7029ffc fix internal config overwriting standalone config 2021-04-16 21:07:54 +10:00
Sinai
225a07bc1b Create ToStringUtility for default labels 2021-04-16 21:07:45 +10:00
Sinai
085c79441b Create preliminary GameObject inspector for testing, cleanup some UI 2021-04-16 21:07:32 +10:00
Sinai
40d32e1919 cleanup scene loader, redundant code 2021-04-16 18:37:26 +10:00
Sinai
480a8cb31c fix DivideByZeroExceptions and add minimum handle size 2021-04-16 18:24:45 +10:00
Sinai
9bdcccaaa1 Add keybind for mouse unlock, and aggressive unlock mode 2021-04-16 18:24:31 +10:00
Sinai
0f69833283 Separate internal and public configs 2021-04-16 17:49:19 +10:00
Sinai
1769a4ed8d Make abstract UIPanel class, refactor SceneExplorer into that, some fixes 2021-04-16 17:49:05 +10:00
Sinai
c8a64c39b1 rename Model folder 2021-04-16 04:33:42 +10:00
Sinai
c1d3aab8e3 Fix transform tree and scroller, add update toggle and refresh button 2021-04-16 04:33:13 +10:00
Sinai
9a9048bcd8 Add CreateCell to ICell interface 2021-04-16 02:53:17 +10:00
Sinai
dec113d2ee Fix RectTransform.GetWorldCorners in il2cpp 2021-04-16 02:53:07 +10:00
Sinai
b03349a3e0 Use HashSet and List instead of Dictionary for TransformTree caching, fix logic 2021-04-16 02:52:54 +10:00
Sinai
896da0157d InfiniteScroll classes no longer need injection, using internal behaviour classes 2021-04-16 02:49:46 +10:00
Sinai
a58e2a0fad Detach ScrollRect class from InfiniteScrollRect, use UIBehaviourModel. Cleanup and fix for il2cpp 2021-04-16 02:48:49 +10:00
Sinai
b13aa74fa1 Use HashSet and List instead of Dictionary for SceneExplorer caching, fix refresh logic 2021-04-16 02:47:15 +10:00
Sinai
8ef6df043c safer UIRoot visibility check 2021-04-16 02:46:21 +10:00
Sinai
f89455549e safer UIBehaviour instance updates, init method 2021-04-16 02:46:04 +10:00
Sinai
a6ff9e02e2 remove menupages enum config entry 2021-04-16 02:45:38 +10:00
Sinai
51f5c68598 Remove temp gameobject creation, scene explorer is working fine 2021-04-15 20:28:27 +10:00
Sinai
5bb612cb5a Update SceneHandler.cs 2021-04-15 20:23:33 +10:00
Sinai
a3fcac1acb Update Il2CppProvider.cs 2021-04-15 20:21:14 +10:00
Sinai
d1d7572945 Remove test assembly resolver 2021-04-15 20:20:11 +10:00
Sinai
7eb4b1bc77 WIP
* Using publicized mono assemblies
* Remaking UI from scratch. Done the Scene Explorer so far.
2021-04-15 20:18:03 +10:00
Sinai
a6c24f91e4 Add startup delay 2021-04-11 20:45:02 +10:00
Sinai
9e4c335a05 Update MelonLoaderConfigHandler.cs 2021-04-10 23:17:49 +10:00
Sinai
a1c2dfbe50 Add support for setting disabled color on ColoBlock 2021-04-10 20:15:03 +10:00
Sinai
a5a07a0a23 Add RuntimeProvider method for setting Selectable.colors 2021-04-10 18:25:13 +10:00
Sinai
e0fd682c81 Add MethodInfo helper 2021-04-10 18:24:16 +10:00
Sinai
7426bd1dd6 Bump version 2021-04-10 17:44:15 +10:00
Sinai
b39b044f79 Add advanced attributes to BepInEx config 2021-04-10 17:44:09 +10:00
Sinai
7a2b4aa257 Fix setting color block when partially stripped 2021-04-10 17:43:56 +10:00
Sinai
3762d14bdb Fix InputSystem for IL2CPP 2021-04-10 17:43:32 +10:00
Sinai
3628f3db31 Fix event system control 2021-04-09 01:46:26 +10:00
Sinai
d39fea69c3 Better InputSystem Key enum resolving 2021-04-07 20:54:08 +10:00
Sinai
95e8b3aa58 fix string unbox 2021-04-07 17:31:06 +10:00
Sinai
b68145385c Fix issue with float struct check 2021-04-07 17:20:54 +10:00
Sinai
2310f2f7ce Add "Default Tab" config setting instead of "last active tab" 2021-04-07 17:20:42 +10:00
Sinai
2cc403ad17 Cleanup runtime-specific 2021-04-07 17:20:09 +10:00
Sinai
c2d9b9b59e a few small fixes
* Fix InteractiveFlags toggles not being properly updated
* Fix cases where games that don't have Reflection.Emit would still have the C# Console available. Also added a "(disabled)" message to the tab button.
2021-04-06 01:01:46 +10:00
Sinai
c748be7bcc Rewrite InteractiveUnityStruct, now called InteractiveFloatStruct
InteractiveFloatStruct supports any struct where all the fields are floats.
2021-04-05 20:32:47 +10:00
Sinai
09dae6f1d3 Add proper support for InputSystem 2021-04-05 16:28:30 +10:00
Sinai
6ca117b070 Fix strings boxed as Il2CppSystem.Objects 2021-04-04 13:44:58 +10:00
Sinai
113f2fd922 3.3.5 - fix Il2Cpp Hashtable, boxed strings 2021-04-04 03:41:36 +10:00
Sinai
7443f6500e Update README.md 2021-04-03 17:24:28 +11:00
Sinai
92566c2729
Update README.md 2021-04-02 19:56:18 +11:00
Sinai
713f87f455
Update THIRDPARTY_LICENSES.md 2021-04-02 17:45:50 +11:00
Sinai
4241e7e207 Include third-party licenses 2021-04-02 17:44:49 +11:00
Sinai
6d479a6703 3.3.4
* Fixed Harmony patches not working properly for games which use older BepInEx releases (ie. Risk of Rain 2)
* Fixed a couple minor issues with the config settings
2021-04-02 17:06:49 +11:00
Sinai
6539f818c3
Update README.md 2021-04-01 22:04:58 +11:00
Sinai
bc5ffcab40 Update README.md 2021-04-01 17:15:50 +11:00
Sinai
d070ded036 3.3.3
* Fix `Hide on Startup` not working
* Fix for cases when we try to `scene.GetRootGameObjects()` but the scene has not yet fully loaded.
* MelonLoader releases will no longer spam "Preferences Saved!" constantly in the Console log
* Fix mistake with UI Event System setting/releasing
* Fix some UI elements not having correct Color transition values
2021-04-01 17:13:31 +11:00
Sinai
8f025622b4 3.3.2
* Added InteractiveColor UI editor to make changing a Color easier
* Added a "Scene Loader" helper which allows you to load any Scene that the game was built with. In some cases you may not find all the Scenes that the game uses, they may be loaded through AssetBundles or other means and won't show up here yet
* Adjusted the SceneExplorer UI, the "Hide" button is now always on the left of the window
*
* Handled some errors related to UI unstripping that could occur in rare cases
2021-03-31 22:58:17 +11:00
Sinai
89f137680e Update DebugConsole.cs 2021-03-31 02:02:12 +11:00
Sinai
f280b45ed3 3.3.1
* Added a 'Default' button for config values to revert to the default value
* Added an internal config entry to save the window position between sessions
* Reordered the config settings in the menu so the important ones are at the top
* Adjusted the UI for config entries, should be a bit easier to read now.
* Adjusted the UI for Dictionaries, the keys and values now alternate background colors.
* A few other minor UI fixes and tweaks for 3.3.0
2021-03-31 01:42:32 +11:00
Sinai
456e15020f
Update README.md 2021-03-31 00:00:39 +11:00
Sinai
d33d46927d
Update README.md 2021-03-30 23:59:08 +11:00
Sinai
7a872cecf9 Update UIFactory.cs 2021-03-30 22:34:59 +11:00
Sinai
b2cbdc1802 Update README.md 2021-03-30 21:31:12 +11:00
Sinai
3501a28fd1 Restore UnlockMouse config, adjust config saving 2021-03-30 21:23:45 +11:00
Sinai
40f698122d Revert colorblock changes 2021-03-30 19:55:18 +11:00
Sinai
0555a644b7 3.3.0 rewrite
* Huge restructure/rewrite. No real changes to any functionality, just a cleaner and more manageable project.
2021-03-30 19:50:04 +11:00
Sinai
f66a04c93f Update README.md 2021-03-26 23:34:06 +11:00
Sinai
8f07255d1b Update README.md 2021-03-26 23:12:31 +11:00
Sinai
46f35129c5 3.2.10
* The following preferences are now persistent between sessions: Active Menu Page, Scene Explorer Hide State, Debug Console Hide State
* The "Resize Cursor" is now just a `↔` Text label instead of a sprite.
* Added support for Unity 5.2+ games (previously was only supporting 5.6)
2021-03-26 19:49:53 +11:00
Sinai
604c499822 Add Reset button to C# Console 2021-03-26 07:31:30 +11:00
Sinai
8964c48ba0 Move melon attributes to ExplorerMelonMod.cs 2021-03-26 06:38:59 +11:00
Sinai
e85a3e0f1e Merge bepinex/melonloader unhollowed libs 2021-03-26 06:04:44 +11:00
Sinai
c658d393f5 Update README.md 2021-03-26 05:59:17 +11:00
Sinai
9a45e29e02 Update README.md 2021-03-26 05:53:03 +11:00
Sinai
418ece55e3 Improve UI inspect-under-mouse 2021-03-26 05:43:53 +11:00
Sinai
bf455893e7 Include all references in lib folder 2021-03-26 05:40:12 +11:00
Sinai
6d9cb8205a Update README.md 2021-03-25 18:48:40 +11:00
Sinai
0f431e997b Update README.md 2021-03-25 18:47:52 +11:00
Sinai
2107df70ad Improvements to CS Console
* Errors are now logged properly.
* Can now define classes, methods, etc - no longer has to be an expression body.
* Added `StartCoroutine(IEnumerator routine)` helper method to easily run a Coroutine
* Disabling suggestions now properly stops Explorer trying to update suggestion cache instead of just not showing them. In the rare cases that suggestions cause a crash, disabling them will now prevent those crashes.
* Various other misc improvements behind the scenes
2021-03-25 18:39:35 +11:00
Sinai
a9fbea7c96 (C# Console) Only update autocomplete and indent if they are enabled 2021-03-24 17:14:13 +11:00
Sinai
77878ddd94 Use reflection for adding Unity log callback to avoid unstripping errors 2021-03-24 17:13:43 +11:00
Sinai
594abc47f8 Move RuntimeProvider.Init to after config is loaded 2021-03-24 17:13:26 +11:00
Sinai
5e326916a2 bump version 2021-03-23 16:16:09 +11:00
Sinai
31c2debb78 fix typo mistake in previous version 2021-03-23 16:15:16 +11:00
Sinai
d919497e43 Config: use en-us culture, fix recursive exception 2021-03-23 04:47:55 +11:00
Sinai
0c40b4fad9 Merge branch 'master' of https://github.com/sinai-dev/Explorer 2021-03-21 16:18:56 +11:00
Sinai
bba912667f fix ToString exception 2021-03-21 16:18:47 +11:00
Sinai
1807e7c5ff
Update TextureUtilProvider.cs 2021-03-21 15:16:36 +11:00
Sinai
9da2ea9b1b Update README and Lexer namespaces 2021-03-18 18:52:30 +11:00
Sinai
1a5843f8e1 disable main menu page on failed init 2021-03-18 18:38:51 +11:00
Sinai
25e48f2f37 Project refactor, namespace cleanup, splitting UI/functionality. 2021-03-18 17:17:29 +11:00
Sinai
1c0011bef9 bump version 2021-03-16 18:13:14 +11:00
Sinai
9e996816ef starting work on a cleanup/rewrite 2021-03-16 18:12:39 +11:00
Sinai
9665753dc8 fix BIE5 mono release 2021-03-16 18:12:26 +11:00
Sinai
942e9d7555 some commenting 2021-03-14 16:08:53 +11:00
Sinai
9efb9581f5 Cleanups, method summaries, bump version 2021-03-12 18:41:57 +11:00
Sinai
f10a462b00 More reflection caching, use deobfuscated names for ToString labels 2021-03-12 18:41:38 +11:00
Sinai
9072b16c5a Save window size between launches 2021-03-12 18:39:57 +11:00
Sinai
21408993c2 create subfolder for standalone 2021-03-11 18:40:04 +11:00
Sinai
7a8b5b50d1 bump version, update readme 2021-03-11 18:32:57 +11:00
Sinai
1a5e843070 handle ExplorerStandalone update internally 2021-03-11 18:16:52 +11:00
Sinai
ade7539fde cleanups 2021-03-11 17:57:58 +11:00
Sinai
5c588e5a03
Update README.md 2021-03-10 05:04:43 +11:00
Sinai
af094832fe Update README.md 2021-03-09 22:31:26 +11:00
Sinai
af0ee2e690 Update README.md 2021-03-09 22:29:53 +11:00
Sinai
d2d6fb4d55 Update README.md 2021-03-09 22:28:43 +11:00
Sinai
6c25662fe9 Update README.md 2021-03-09 17:36:49 +11:00
Sinai
4bcf82ca10 separate Bep5 and Bep6 support. Fix enums not backed by ints. 2021-03-09 17:35:54 +11:00
Sinai
ce38e8ac50 bump to MelonLoader 0.3.0 2021-03-06 17:25:54 +11:00
Sinai
12cd718f12 3.1.12: store Il2CppToMonoType key as string AssemblyQualifiedName instead of Type object 2021-03-04 01:44:34 +11:00
Sinai
995e2a3e93 3.1.11: fix potential crash on scene reload 2021-03-03 22:09:14 +11:00
Sinai
2c95fec646 3.1.10: Add "Hide on startup" config option 2021-02-27 17:04:47 +11:00
Sinai
69912d7ea4 Prevent GC Mark Overflow on C# Console copy+paste 2021-02-26 17:54:00 +11:00
Sinai
9c5596ace4 Update lib versions 2021-02-26 17:52:21 +11:00
Sinai
d4dac58fc8 Fix for deobfuscated unhollowed types not being properly resolved 2021-02-20 19:39:19 +11:00
Sinai
77b97cbe17 Update README.md 2021-02-03 18:31:29 +11:00
Sinai
c6f0f34ac0 Update README.md 2021-01-28 02:09:40 +11:00
Sinai
d1f4f74d32 some ui cleanups (minor) 2021-01-22 21:56:00 +11:00
Sinai
f13068bf01 Update README.md 2021-01-20 23:05:04 +11:00
Sinai
dfc288a101 Update README.md 2021-01-20 19:10:13 +11:00
Sinai
544009dc21 3.1.7
* Added standalone release build (thanks @Alloc86)
* Improved formatting for ToString methods which accept an IFormatProvider
* When editing a struct, the reference to the parent member will now be updated if you modify the struct values.
2021-01-20 17:22:36 +11:00
Sinai
fdfaaadd89 3.1.6 - don't bother setting pixelPerfect on canvas 2021-01-14 17:46:32 +11:00
sinaioutlander
58d60a10d4 Update ForceUnlockCursor.cs 2021-01-04 01:23:20 +11:00
sinaioutlander
0432c6d56c 3.1.5
* Integrate PR from js6pak
2021-01-03 19:27:02 +11:00
Sinai
8c34aa2be5
Merge pull request #29 from js6pak/embedded-assetbundle
Load assetbundle from EmbeddedResource
2021-01-03 19:13:15 +11:00
js6pak
4a1c54fac1
Load assetbundle from EmbeddedResource 2021-01-02 19:38:01 +01:00
sinaioutlander
190467fa5c Update README.md 2020-12-31 18:34:26 +11:00
261 changed files with 18689 additions and 14735 deletions

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

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

60
.github/ISSUE_TEMPLATE/bug_report.yaml vendored Normal file
View File

@ -0,0 +1,60 @@
name: Bug Report
description: File a bug or crash report
title: "[Bug]: "
labels: [bug]
body:
- type: markdown
attributes:
value: |
Thanks for submitting a bug report, please fill out as much detail as possible.
- type: checkboxes
id: latestversion
attributes:
label: Are you on the latest version of UnityExplorer?
description: If not, you must update first.
options:
- label: Yes, I'm on the latest version of UnityExplorer.
required: true
- type: dropdown
id: version
attributes:
label: Which release are you using?
description: Please select your environment for UnityExplorer.
options:
- BepInEx IL2CPP
- BepInEx 6.X Mono
- BepInEx 5.X Mono
- MelonLoader IL2CPP
- MelonLoader Mono
- Standalone IL2CPP
- Standalone Mono
validations:
required: true
- type: textarea
id: game
attributes:
label: Which game did this occur on?
description: Please tell us the name of the game. If it's a personal or private project, just let us know the Unity version.
validations:
required: true
- type: textarea
id: what-happened
attributes:
label: Describe the issue.
description: What happened? Should something else have happened instead? Please provide steps to reproduce the issue if possible.
placeholder: Tell us what you see!
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: |
Please copy and paste any relevant logs and stack traces.
* Unity log: `%userprofile%\AppData\LocalLow\{Company}\{Game}\Player.log` or `output_log.txt`
* BepInEx: `BepInEx\LogOutput.log`
* MelonLoader: `MelonLoader\latest.log`
* Standalone: `{DLL_Location}\UnityExplorer\Logs\` (pick the most recent one)
render: shell
validations:
required: false

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1 @@
blank_issues_enabled: false

18
.github/ISSUE_TEMPLATE/enhancement.yaml vendored Normal file
View File

@ -0,0 +1,18 @@
name: New feature or enhancement
description: Suggest or discuss a feature or enhancement for UnityExplorer
title: "[Enhancement]: "
labels: [enhancement]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to discuss UnityExplorer, please provide as much detail as possible.
- type: textarea
id: description
attributes:
label: Describe the new feature or enhancement
description: |
Please go into as much detail as necessary in describing the new feature or enhancement.
If providing examples or suggestions for the required C# code, please use syntax-highlighted code blocks.
validations:
required: true

13
.github/ISSUE_TEMPLATE/other.yaml vendored Normal file
View File

@ -0,0 +1,13 @@
name: Other
description: Something else?
title: "[Other]: "
labels: [Other]
body:
- type: textarea
id: description
attributes:
label: Describe the issue
description: |
Please describe the issue in as much detail as possible.
validations:
required: true

92
.github/workflows/dotnet.yml vendored Normal file
View File

@ -0,0 +1,92 @@
name: Build UnityExplorer
# Controls when the action will run.
on:
push:
branches: [master]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
build:
runs-on: windows-latest
if: "!contains(github.event.head_commit.message, '-noci')"
steps:
# Setup
- name: Checkout latest
uses: actions/checkout@v2
- name: Setup dotnet
uses: actions/setup-dotnet@v2
with:
dotnet-version: '6.0.x'
include-prerelease: true
# Run build script
- run: |
./build.ps1
# Upload artifacts
# BepInEx IL2CPP
- uses: actions/upload-artifact@v2
with:
name: 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
- uses: actions/upload-artifact@v2
with:
name: UnityExplorer.BepInEx5.Mono.zip
path: ./Release/UnityExplorer.BepInEx5.Mono/
# BepInEx 6 Mono
- uses: actions/upload-artifact@v2
with:
name: UnityExplorer.BepInEx6.Mono.zip
path: ./Release/UnityExplorer.BepInEx6.Mono/
# Editor
- uses: actions/upload-artifact@v2
with:
name: UnityExplorer.Editor.zip
path: ./UnityEditorPackage/
# MelonLoader IL2CPP net6preview
- uses: actions/upload-artifact@v2
with:
name: UnityExplorer.MelonLoader.IL2CPP.net6preview.zip
path: ./Release/UnityExplorer.MelonLoader.IL2CPP.net6preview/
# MelonLoader IL2CPP net472
- uses: actions/upload-artifact@v2
with:
name: UnityExplorer.MelonLoader.IL2CPP.zip
path: ./Release/UnityExplorer.MelonLoader.IL2CPP/
# MelonLoader Mono
- uses: actions/upload-artifact@v2
with:
name: UnityExplorer.MelonLoader.Mono.zip
path: ./Release/UnityExplorer.MelonLoader.Mono/
# Standalone Il2Cpp
- uses: actions/upload-artifact@v2
with:
name: UnityExplorer.Standalone.IL2CPP.zip
path: ./Release/UnityExplorer.Standalone.IL2CPP/
# Standalone Mono
- uses: actions/upload-artifact@v2
with:
name: UnityExplorer.Standalone.Mono.zip
path: ./Release/UnityExplorer.Standalone.Mono/

1
.gitignore vendored
View File

@ -9,7 +9,6 @@
*.user
*.userosscache
*.sln.docstates
*/mcs-unity*
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

217
README.md
View File

@ -3,32 +3,87 @@
</p>
<p align="center">
An in-game explorer and a suite of debugging tools for <a href="https://docs.unity3d.com/Manual/IL2CPP.html">IL2CPP</a> and <b>Mono</b> Unity games, to aid with modding development.
🔍 An in-game UI for exploring, debugging and modifying Unity games.
</p>
<p align="center">
<a href="../../releases/latest">
<img src="https://img.shields.io/github/release/sinai-dev/Explorer.svg" />
</a>
<img src="https://img.shields.io/github/downloads/sinai-dev/Explorer/total.svg" />
✔️ Supports most Unity versions from 5.2 to 2021+ (IL2CPP and Mono).
</p>
<p align="center">
✨ Powered by <a href="https://github.com/sinai-dev/UniverseLib">UniverseLib</a>
</p>
- [Releases](#releases)
- [Features](#features)
- [How to install](#how-to-install)
- [Mod Config](#mod-config)
- [Mouse Control](#mouse-control)
- [Building](#building)
- [Credits](#credits)
# Releases [![](https://img.shields.io/github/downloads/sinai-dev/UnityExplorer/total.svg)](../../releases)
## Releases
[![](https://img.shields.io/github/release/sinai-dev/UnityExplorer.svg?label=version)](../../releases/latest) [![](https://img.shields.io/github/workflow/status/sinai-dev/UnityExplorer/Build%20UnityExplorer)](https://github.com/sinai-dev/UnityExplorer/actions) [![](https://img.shields.io/github/downloads/sinai-dev/UnityExplorer/latest/total.svg)](../../releases/latest)
| Mod Loader | IL2CPP | Mono |
| ----------- | ------ | ---- |
| [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.MelonLoader.Il2Cpp.zip) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.MelonLoader.Mono.zip) |
| [BepInEx](https://github.com/BepInEx/BepInEx) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx.Il2Cpp.zip) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx.Mono.zip) |
⚡ 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)
## Features
## 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
| 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 (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) |
1. Unzip the release file into a folder
2. Take the `plugins/sinai-dev-UnityExplorer` folder and place it in `BepInEx/plugins/`
<i>Note: BepInEx 6 is obtainable via [builds.bepinex.dev](https://builds.bepinex.dev/projects/bepinex_be)</i>
## MelonLoader
| Release | IL2CPP | Mono |
| ------- | ------ | ---- |
| 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) | ✖️ |
1. Unzip the release file into a folder
2. Copy the DLL inside the `Mods` folder into your MelonLoader `Mods` folder
3. Copy all of the DLLs inside the `UserLibs` folder into your MelonLoader `UserLibs` folder
## Standalone
| IL2CPP | Mono |
| ------ | ---- |
| ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.Standalone.IL2CPP.zip) | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.Standalone.Mono.zip) |
The standalone release can be used with any injector or loader of your choice, but it requires you to load the dependencies manually.
1. Ensure the required libs are loaded - UniverseLib, HarmonyX and MonoMod. Take them from the [`UnityExplorer.Editor`](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.Editor.zip) release if you need them.
2. For IL2CPP, load Il2CppAssemblyUnhollower and start an [Il2CppAssemblyUnhollower runtime](https://github.com/knah/Il2CppAssemblyUnhollower#required-external-setup)
2. Load the UnityExplorer DLL
3. Create an instance of Unity Explorer with `UnityExplorer.ExplorerStandalone.CreateInstance();`
4. Optionally subscribe to the `ExplorerStandalone.OnLog` event to handle logging if you wish
## Unity Editor
1. Download the [`UnityExplorer.Editor`](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.Editor.zip) release.
2. Install the package, either by using the Package Manager and importing the `package.json` file, or by manually dragging the folder into your `Assets` folder.
3. Drag the `Runtime/UnityExplorer` prefab into your scene, or create a GameObject and add the `Explorer Editor Behaviour` script to it.
# Common issues and solutions
Although UnityExplorer should work out of the box for most Unity games, in some cases you may need to tweak the settings for it to work properly.
To adjust the settings, open the config file:
* BepInEx: `BepInEx\config\com.sinai.unityexplorer.cfg`
* MelonLoader: `UserData\MelonPreferences.cfg`
* Standalone: `sinai-dev-UnityExplorer\config.cfg`
Try adjusting the following settings and see if it fixes your issues:
* `Startup_Delay_Time` - increase to 5-10 seconds (or more as needed), can fix issues with UnityExplorer being destroyed or corrupted during startup.
* `Disable_EventSystem_Override` - if input is not working properly, try setting this to `true`.
If these fixes do not work, please create an issue in this repo and I'll do my best to look into it.
# Features
<p align="center">
<a href="https://raw.githubusercontent.com/sinai-dev/UnityExplorer/master/img/preview.png">
@ -36,74 +91,94 @@
</a>
</p>
* <b>Scene Explorer</b>: Simple menu to traverse the Transform heirarchy of the scene.
* <b>GameObject Inspector</b>: Various helpful tools to see and manipulate the GameObject, similar to what you can do in the Editor.
* <b>Reflection Inspector</b>: Inspect Properties and Fields. Can also set primitive values and evaluate primitive methods.
* <b>Search</b>: Search for UnityEngine.Objects with various filters, or use the helpers for static Instances and Classes.
* <b>C# Console</b>: Interactive console for evaluating C# methods on the fly, with some basic helpers.
* <b>Inspect-under-mouse</b>: Hover over an object with a collider and inspect it by clicking on it.
### Inspector API
## How to install
If you want to inspect an object or Type from outside the C# console, use the `InspectorManager` class:
### BepInEx
**To inspect an object:**
```csharp
UnityExplorer.InspectorManager.Inspect(theObject);
```
0. Install [BepInEx](https://github.com/BepInEx/BepInEx) for your game.
1. Download the UnityExplorer release for BepInEx IL2CPP or Mono above.
2. Take the `UnityExplorer.dll` file and put it in `[GameFolder]\BepInEx\plugins\`
3. Take the `UnityExplorer\` folder (with `explorerui.bundle`) and put it in `[GameFolder]\Mods\`, so it looks like `[GameFolder]\Mods\UnityExplorer\explorerui.bundle`.
4. In IL2CPP, it is highly recommended to get the base Unity libs for the game's Unity version and put them in the `BepInEx\unhollowed\base\` folder.
**To inspect a Type:**
```cs
UnityExplorer.InspectorManager.Inspect(typeof(SomeClass));
```
### MelonLoader
### Object Explorer
0. Install [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) for your game.
1. Download the UnityExplorer release for MelonLoader IL2CPP or Mono above.
2. Take the contents of the release and put it in the `[GameFolder]\Mods\` folder. It should look like `[GameFolder]\Mods\UnityExplorer.dll` and `[GameFolder]\Mods\UnityExplorer\explorerui.bundle`.
* Use the <b>Scene Explorer</b> tab to traverse the active scenes, as well as the DontDestroyOnLoad and HideAndDontSave objects.
* The "HideAndDontSave" scene contains objects with that flag, as well as Assets and Resources which are not in any scene but behave the same way.
* You can use the Scene Loader to easily load any of the scenes in the build (may not work for Unity 5.X games)
* Use the <b>Object Search</b> tab to search for Unity objects (including GameObjects, Components, etc), C# Singletons or Static Classes.
* Use the UnityObject search to look for any objects which derive from `UnityEngine.Object`, with optional filters
* The singleton search will look for any classes with a typical "Instance" field, and check it for a current value. This may cause unexpected behaviour in some IL2CPP games as we cannot distinguish between true properties and field-properties, so some property accessors will be invoked.
## Mod Config
### Inspector
You can access the settings via the "Options" page of the main menu, or directly from the config at `Mods\UnityExplorer\config.ini` (generated after first launch).
The inspector is used to see detailed information on objects of any type and manipulate their values, as well as to inspect C# Classes with static reflection.
`Main Menu Toggle` (KeyCode)
* Default: `F7`
* See [this article](https://docs.unity3d.com/ScriptReference/KeyCode.html) for a full list of all accepted KeyCodes.
* The <b>GameObject Inspector</b> (tab prefix `[G]`) is used to inspect a `GameObject`, and to see and manipulate its Transform and Components.
* You can edit any of the input fields in the inspector (excluding readonly fields) and press <b>Enter</b> to apply your changes. You can also do this to the GameObject path as a way to change the GameObject's parent. Press the <b>Escape</b> key to cancel your edits.
* <i>note: When inspecting a GameObject with a Canvas, the transform controls may be overridden by the RectTransform anchors.</i>
* The <b>Reflection Inspectors</b> (tab prefix `[R]` and `[S]`) are used for everything else
* 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
* Use the filters at the top to quickly find the members you are looking for
* 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.
`Force Unlock Mouse` (bool)
* Default: `true`
* Forces the cursor to be unlocked and visible while the UnityExplorer menu is open, and prevents anything else taking control.
### C# Console
`Default Page Limit` (int)
* Default: `25`
* Sets the default items per page when viewing lists or search results.
* <b>Requires a restart to take effect</b>, apart from Reflection Inspector tabs.
* The C# Console uses the `Mono.CSharp.Evaluator` to define temporary classes or run immediate REPL code.
* You can execute a script automatically on startup by naming it `startup.cs` and placing it in the `sinai-dev-UnityExplorer\Scripts\` folder (this folder will be created where you placed the DLL file).
* See the "Help" dropdown in the C# console menu for more detailed information.
`Default Output Path` (string)
* Default: `Mods\UnityExplorer`
* Where output is generated to, by default (for Texture PNG saving, etc).
* Currently this is not actually used for anything, but it will be soon.
### Hook Manager
`Log Unity Debug` (bool)
* Default: `false`
* Listens for Unity `Debug.Log` messages and prints them to UnityExplorer's log.
* The Hooks panel allows you to hook methods at the click of a button for debugging purposes.
* Simply enter any class and hook the methods you want from the menu.
* You can edit the source code of the generated hook with the "Edit Hook Source" button. Accepted method names are `Prefix` (which can return `bool` or `void`), `Postfix`, `Finalizer` (which can return `Exception` or `void`), and `Transpiler` (which must return `IEnumerable<HarmonyLib.CodeInstruction>`). You can define multiple patches if you wish.
## Building
### Mouse-Inspect
If you'd like to build this yourself, you will need to have installed BepInEx and/or MelonLoader for at least one Unity game. If you want to build all 4 versions, you will need at least one IL2CPP and one Mono game, with BepInEx and MelonLoader installed for both.
* The "Mouse Inspect" dropdown in the "Inspector" panel allows you to inspect objects under the mouse.
* <b>World</b>: uses Physics.Raycast to look for Colliders
* <b>UI</b>: uses GraphicRaycasters to find UI objects
1. Install BepInEx or MelonLoader for your game.
2. Open the `src\UnityExplorer.csproj` file in a text editor.
3. For IL2CPP builds, make sure you set `BIECppGameFolder` (for BepInEx) and/or `MLCppGameFolder` (for MelonLoader) so the project can locate the necessary references.
4. Open the `src\UnityExplorer.sln` project.
5. Select `Solution 'UnityExplorer' (1 of 1 project)` in the Solution Explorer panel, and set the <b>Active config</b> property to the version you want to build, then build it.
5. The DLLs are built to the `Release\` folder in the root of the repository.
6. If ILRepack fails or is missing, use the NuGet package manager to re-install `ILRepack.Lib.MSBuild.Task`, then re-build.
### Freecam
## Credits
* UnityExplorer provides a basic Free Camera which you can control with your keyboard and mouse.
* Unlike all other features of UnityExplorer, you can still use Freecam while UnityExplorer's menu is hidden.
* Supports using the game's main Camera or a separate custom Camera.
* See the Freecam panel for further instructions and details.
Written by Sinai.
### Clipboard
### Licensing
* The "Clipboard" panel allows you to see your current paste value, or clear it (resets it to `null`)
* Can copy the value from any member in a Reflection Inspector, Enumerable or Dictionary, and from the target of any Inspector tab
* Can paste values onto any member in a Reflection Inspector
* Non-parsable arguments in Method/Property Evaluators allow pasting values
* The C# Console has helper methods `Copy(obj)` and `Paste()` for accessing the Clipboard
This project uses code from:
* (GPL) [ManlyMarco](https://github.com/ManlyMarco)'s [Runtime Unity Editor](https://github.com/ManlyMarco/RuntimeUnityEditor), which I used for some aspects of the C# Console and Auto-Complete features. The snippets I used are indicated with a comment.
* (MIT) [denikson](https://github.com/denikson) (aka Horse)'s [mcs-unity](https://github.com/denikson/mcs-unity). I commented out the `SkipVisibilityExt` constructor since it was causing an exception with the Hook it attempted in IL2CPP.
* (Apache) [InGameCodeEditor](https://assetstore.unity.com/packages/tools/gui/ingame-code-editor-144254) was used as the base for the syntax highlighting for UnityExplorer's C# console, although it has been heavily rewritten and optimized. Used classes are in the `UnityExplorer.CSConsole.Lexer` namespace.
### Settings
* You can change the settings via the "Options" tab of the menu, or directly from the config file.
* BepInEx: `BepInEx\config\com.sinai.unityexplorer.cfg`
* MelonLoader: `UserData\MelonPreferences.cfg`
* Standalone `{DLL_location}\sinai-dev-UnityExplorer\config.cfg`
# Building
1. Run the `build.ps1` powershell script to build UnityExplorer. Releases are found in the `Release` folder.
Building individual configurations from your IDE is fine, though note that the intial build process builds into `Release/<version>/...` instead of the subfolders that the powershell script uses. Batch building is not currently supported with the project.
# Acknowledgments
* [ManlyMarco](https://github.com/ManlyMarco) for [Runtime Unity Editor](https://github.com/ManlyMarco/RuntimeUnityEditor) \[[license](THIRDPARTY_LICENSES.md#runtimeunityeditor-license)\], the ScriptEvaluator from RUE's REPL console was used as the base for UnityExplorer's C# console.
* [Geoffrey Horsington](https://github.com/ghorsington) for [mcs-unity](https://github.com/sinai-dev/mcs-unity) \[no license\], used as the `Mono.CSharp` reference for the C# Console.
### Disclaimer
UnityExplorer is in no way associated with Unity Technologies. "Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere.

874
THIRDPARTY_LICENSES.md Normal file
View File

@ -0,0 +1,874 @@
* [RuntimeUnityEditor License](#runtimeunityeditor-license)
* [MelonLoader License](#melonloader-license)
## RuntimeUnityEditor License
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
## MelonLoader License
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2020 - 2021 Lava Gang
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View File

@ -0,0 +1,74 @@
# UnityExplorer
🔍 An in-game UI for exploring, debugging and modifying Unity games.
✔️ Supports most Unity versions from 5.2 to 2021+ (IL2CPP and Mono).
✨ Powered by [UniverseLib](https://github.com/sinai-dev/UniverseLib)
# Setup
* Install this package, either by using the Package Manager and importing the `package.json` file, or by manually dragging this folder into your Assets folder.
* Drag the `Runtime/UnityExplorer` prefab into your scene, or create a GameObject and add the `Explorer Editor Behaviour` script to it.
# Features
### Object Explorer
* Use the <b>Scene Explorer</b> tab to traverse the active scenes, as well as the DontDestroyOnLoad and HideAndDontSave objects.
* The "HideAndDontSave" scene contains objects with that flag, as well as Assets and Resources which are not in any scene but behave the same way.
* You can use the Scene Loader to easily load any of the scenes in the build (may not work for Unity 5.X games)
* Use the <b>Object Search</b> tab to search for Unity objects (including GameObjects, Components, etc), C# Singletons or Static Classes.
* Use the UnityObject search to look for any objects which derive from `UnityEngine.Object`, with optional filters
* The singleton search will look for any classes with a typical "Instance" field, and check it for a current value. This may cause unexpected behaviour in some IL2CPP games as we cannot distinguish between true properties and field-properties, so some property accessors will be invoked.
### Inspector
The inspector is used to see detailed information on objects of any type and manipulate their values, as well as to inspect C# Classes with static reflection.
* The <b>GameObject Inspector</b> (tab prefix `[G]`) is used to inspect a `GameObject`, and to see and manipulate its Transform and Components.
* You can edit any of the input fields in the inspector (excluding readonly fields) and press <b>Enter</b> to apply your changes. You can also do this to the GameObject path as a way to change the GameObject's parent. Press the <b>Escape</b> key to cancel your edits.
* <i>note: When inspecting a GameObject with a Canvas, the transform controls may be overridden by the RectTransform anchors.</i>
* The <b>Reflection Inspectors</b> (tab prefix `[R]` and `[S]`) are used for everything else
* 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
* 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
### C# Console
* The C# Console uses the `Mono.CSharp.Evaluator` to define temporary classes or run immediate REPL code.
* You can execute a script automatically on startup by naming it `startup.cs` and placing it in the `UnityExplorer\Scripts\` folder (this folder will be created where you placed the DLL file).
* See the "Help" dropdown in the C# console menu for more detailed information.
### Hook Manager
* The Hooks panel allows you to hook methods at the click of a button for debugging purposes.
* Simply enter any class (generic types not yet supported) and hook the methods you want from the menu.
* You can edit the source code of the generated hook with the "Edit Hook Source" button. Accepted method names are `Prefix` (which can return `bool` or `void`), `Postfix`, `Finalizer` (which can return `Exception` or `void`), and `Transpiler` (which must return `IEnumerable<HarmonyLib.CodeInstruction>`). You can define multiple patches if you wish.
### Mouse-Inspect
* The "Mouse Inspect" dropdown in the "Inspector" panel allows you to inspect objects under the mouse.
* <b>World</b>: uses Physics.Raycast to look for Colliders
* <b>UI</b>: uses GraphicRaycasters to find UI objects
### Clipboard
* The "Clipboard" panel allows you to see your current paste value, or clear it (resets it to `null`)
* Can copy the value from any member in a Reflection Inspector, Enumerable or Dictionary, and from the target of any Inspector tab
* Can paste values onto any member in a Reflection Inspector
* Non-parsable arguments in Method/Property Evaluators allow pasting values
* The C# Console has helper methods `Copy(obj)` and `Paste()` for accessing the Clipboard
### Settings
* You can change the settings via the "Options" tab of the menu, or directly from the config file.
* <AssetsFolder>/sinai-dev-UnityExplorer~/config.cfg
# Acknowledgments
* [ManlyMarco](https://github.com/ManlyMarco) for [Runtime Unity Editor](https://github.com/ManlyMarco/RuntimeUnityEditor) \[[license](THIRDPARTY_LICENSES.md#runtimeunityeditor-license)\], the ScriptEvaluator from RUE's REPL console was used as the base for UnityExplorer's C# console.
* [Geoffrey Horsington](https://github.com/ghorsington) for [mcs-unity](https://github.com/sinai-dev/mcs-unity) \[no license\], used as the `Mono.CSharp` reference for the C# Console.
### Disclaimer
UnityExplorer is in no way associated with Unity Technologies. "Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere.

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.

View File

@ -0,0 +1,45 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2342243352467007562
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2342243352467007560}
- component: {fileID: 2342243352467007563}
m_Layer: 0
m_Name: UnityExplorer
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2342243352467007560
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2342243352467007562}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2342243352467007563
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2342243352467007562}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 255528132, guid: 7e940c577136f52428020c8e128f06f3, type: 3}
m_Name:
m_EditorClassIdentifier:

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,874 @@
* [RuntimeUnityEditor License](#runtimeunityeditor-license)
* [MelonLoader License](#melonloader-license)
## RuntimeUnityEditor License
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
## MelonLoader License
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2020 - 2021 Lava Gang
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,19 @@
{
"name": "com.sinai-dev.unityexplorer",
"version": "4.7.12",
"displayName": "UnityExplorer",
"description": "An in-game UI for exploring, debugging and modifying Unity games.",
"unity": "2017.1",
"documentationUrl": "https://github.com/sinai-dev/UnityExplorer",
"changelogUrl": "https://github.com/sinai-dev/UnityExplorer/releases",
"licensesUrl": "https://github.com/sinai-dev/UnityExplorer/blob/master/LICENSE",
"keywords": [
"inspector",
"debug",
"runtime"
],
"author": {
"name": "Sinai",
"url": "https://github.com/sinai-dev"
}
}

155
build.ps1 Normal file
View File

@ -0,0 +1,155 @@
# ----------- MelonLoader IL2CPP (net6) -----------
dotnet build src/UnityExplorer.sln -c Release_ML_Cpp_net6
$Path = "Release\UnityExplorer.MelonLoader.IL2CPP.net6preview"
# ILRepack
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
Move-Item -Path $Path/UnityExplorer.ML.IL2CPP.net6preview.dll -Destination $Path/Mods -Force
New-Item -Path "$Path" -Name "UserLibs" -ItemType "directory" -Force
Move-Item -Path $Path/UniverseLib.IL2CPP.Unhollower.dll -Destination $Path/UserLibs -Force
# (create zip archive)
Remove-Item $Path/../UnityExplorer.MelonLoader.IL2CPP.net6preview.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.MelonLoader.IL2CPP.net6preview.zip .\$Path\*
# ----------- MelonLoader IL2CPP (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)
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
Move-Item -Path $Path/UnityExplorer.ML.IL2CPP.dll -Destination $Path/Mods -Force
New-Item -Path "$Path" -Name "UserLibs" -ItemType "directory" -Force
Move-Item -Path $Path/UniverseLib.IL2CPP.Unhollower.dll -Destination $Path/UserLibs -Force
# (create zip archive)
Remove-Item $Path/../UnityExplorer.MelonLoader.IL2CPP.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.MelonLoader.IL2CPP.zip .\$Path\*
# ----------- MelonLoader 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)
Remove-Item $Path/Tomlet.dll
Remove-Item $Path/mcs.dll
New-Item -Path "$Path" -Name "Mods" -ItemType "directory" -Force
Move-Item -Path $Path/UnityExplorer.ML.Mono.dll -Destination $Path/Mods -Force
New-Item -Path "$Path" -Name "UserLibs" -ItemType "directory" -Force
Move-Item -Path $Path/UniverseLib.Mono.dll -Destination $Path/UserLibs -Force
# (create zip archive)
Remove-Item $Path/../UnityExplorer.MelonLoader.Mono.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.MelonLoader.Mono.zip .\$Path\*
# ----------- BepInEx IL2CPP -----------
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)
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/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/UniverseLib.IL2CPP.Unhollower.dll -Destination $Path/plugins/sinai-dev-UnityExplorer -Force
# (create zip archive)
Remove-Item $Path/../UnityExplorer.BepInEx.IL2CPP.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.BepInEx.IL2CPP.zip .\$Path\*
# ----------- BepInEx IL2CPP CoreCLR -----------
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)
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/sinai-dev-UnityExplorer" -ItemType "directory" -Force
Move-Item -Path $Path/UnityExplorer.BIE.IL2CPP.CoreCLR.dll -Destination $Path/plugins/sinai-dev-UnityExplorer -Force
Move-Item -Path $Path/UniverseLib.IL2CPP.Interop.dll -Destination $Path/plugins/sinai-dev-UnityExplorer -Force
# (create zip archive)
Remove-Item $Path/../UnityExplorer.BepInEx.IL2CPP.CoreCLR.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.BepInEx.IL2CPP.CoreCLR.zip .\$Path\*
# ----------- BepInEx 5 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)
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.BIE5.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.BepInEx5.Mono.zip -ErrorAction SilentlyContinue
7z a $Path/../UnityExplorer.BepInEx5.Mono.zip .\$Path\*
# ----------- BepInEx 6 Mono -----------
dotnet build src/UnityExplorer.sln -c Release_BIE6_Mono
$Path = "Release/UnityExplorer.BepInEx6.Mono"
# 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 Mono -----------
dotnet build src/UnityExplorer.sln -c Release_STANDALONE_Mono
$Path = "Release/UnityExplorer.Standalone.Mono"
# 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\*
# ----------- Standalone IL2CPP -----------
dotnet build src/UnityExplorer.sln -c Release_STANDALONE_Cpp
$Path = "Release/UnityExplorer.Standalone.IL2CPP"
# ILRepack
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
# (cleanup and move files)
Remove-Item $Path/Tomlet.dll
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\*

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 KiB

After

Width:  |  Height:  |  Size: 495 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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.

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.

Binary file not shown.

BIN
lib/net35/BepInEx.Core.dll Normal file

Binary file not shown.

BIN
lib/net35/BepInEx.Unity.dll Normal file

Binary file not shown.

BIN
lib/net35/BepInEx.dll Normal file

Binary file not shown.

BIN
lib/net35/MelonLoader.dll Normal file

Binary file not shown.

Binary file not shown.

BIN
lib/net35/UnityEngine.dll Normal file

Binary file not shown.

BIN
lib/net35/mcs.dll Normal file

Binary file not shown.

BIN
lib/net472/BepInEx.Core.dll Normal file

Binary file not shown.

Binary file not shown.

BIN
lib/net6/MelonLoader.dll Normal file

Binary file not shown.

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

Binary file not shown.

BIN
lib/net6/mcs.dll 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.

Binary file not shown.

Binary file not shown.

View File

@ -1,314 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityExplorer.Helpers;
using UnityExplorer.UI;
using UnityExplorer.UI.Modules;
namespace UnityExplorer.CSConsole
{
public class AutoCompleter
{
public static AutoCompleter Instance;
public const int MAX_LABELS = 500;
private const int UPDATES_PER_BATCH = 100;
public static GameObject m_mainObj;
//private static RectTransform m_thisRect;
private static readonly List<GameObject> m_suggestionButtons = new List<GameObject>();
private static readonly List<Text> m_suggestionTexts = new List<Text>();
private static readonly List<Text> m_hiddenSuggestionTexts = new List<Text>();
private static bool m_suggestionsDirty;
private static Suggestion[] m_suggestions = new Suggestion[0];
private static int m_lastBatchIndex;
private static string m_prevInput = "NULL";
private static int m_lastCaretPos;
public static void Init()
{
ConstructUI();
m_mainObj.SetActive(false);
}
public static void Update()
{
if (!m_mainObj)
{
return;
}
if (!CodeEditor.EnableAutocompletes)
{
if (m_mainObj.activeSelf)
{
m_mainObj.SetActive(false);
}
return;
}
RefreshButtons();
UpdatePosition();
}
public static void SetSuggestions(Suggestion[] suggestions)
{
m_suggestions = suggestions;
m_suggestionsDirty = true;
m_lastBatchIndex = 0;
}
private static void RefreshButtons()
{
if (!m_suggestionsDirty)
{
return;
}
if (m_suggestions.Length < 1)
{
if (m_mainObj.activeSelf)
{
m_mainObj?.SetActive(false);
}
return;
}
if (!m_mainObj.activeSelf)
{
m_mainObj.SetActive(true);
}
if (m_suggestions.Length < 1 || m_lastBatchIndex >= MAX_LABELS)
{
m_suggestionsDirty = false;
return;
}
int end = m_lastBatchIndex + UPDATES_PER_BATCH;
for (int i = m_lastBatchIndex; i < end && i < MAX_LABELS; i++)
{
if (i >= m_suggestions.Length)
{
if (m_suggestionButtons[i].activeSelf)
{
m_suggestionButtons[i].SetActive(false);
}
}
else
{
if (!m_suggestionButtons[i].activeSelf)
{
m_suggestionButtons[i].SetActive(true);
}
var suggestion = m_suggestions[i];
var label = m_suggestionTexts[i];
var hiddenLabel = m_hiddenSuggestionTexts[i];
label.text = suggestion.Full;
hiddenLabel.text = suggestion.Addition;
label.color = suggestion.TextColor;
}
m_lastBatchIndex = i;
}
m_lastBatchIndex++;
}
private static void UpdatePosition()
{
try
{
var editor = CSConsolePage.Instance.m_codeEditor;
if (!editor.InputField.isFocused)
return;
var textGen = editor.InputText.cachedTextGenerator;
int caretPos = editor.m_lastCaretPos;
if (caretPos == m_lastCaretPos)
return;
m_lastCaretPos = caretPos;
if (caretPos >= 1)
caretPos--;
var pos = textGen.characters[caretPos].cursorPos;
pos = editor.InputField.transform.TransformPoint(pos);
m_mainObj.transform.position = new Vector3(pos.x + 10, pos.y - 20, 0);
}
catch //(Exception e)
{
//ExplorerCore.Log(e.ToString());
}
}
private static readonly char[] splitChars = new[] { '{', '}', ',', ';', '<', '>', '(', ')', '[', ']', '=', '|', '&', '?' };
public static void CheckAutocomplete()
{
var m_codeEditor = CSConsolePage.Instance.m_codeEditor;
string input = m_codeEditor.InputField.text;
int caretIndex = m_codeEditor.InputField.caretPosition;
if (!string.IsNullOrEmpty(input))
{
try
{
int start = caretIndex <= 0 ? 0 : input.LastIndexOfAny(splitChars, caretIndex - 1) + 1;
input = input.Substring(start, caretIndex - start).Trim();
}
catch (ArgumentException) { }
}
if (!string.IsNullOrEmpty(input) && input != m_prevInput)
{
GetAutocompletes(input);
}
else
{
ClearAutocompletes();
}
m_prevInput = input;
}
public static void ClearAutocompletes()
{
if (CodeEditor.AutoCompletes.Any())
{
CodeEditor.AutoCompletes.Clear();
}
}
public static void GetAutocompletes(string input)
{
try
{
// Credit ManylMarco
CodeEditor.AutoCompletes.Clear();
string[] completions = CSConsolePage.Instance.m_evaluator.GetCompletions(input, out string prefix);
if (completions != null)
{
if (prefix == null)
{
prefix = input;
}
CodeEditor.AutoCompletes.AddRange(completions
.Where(x => !string.IsNullOrEmpty(x))
.Select(x => new Suggestion(x, prefix, Suggestion.Contexts.Other))
);
}
string trimmed = input.Trim();
if (trimmed.StartsWith("using"))
{
trimmed = trimmed.Remove(0, 5).Trim();
}
IEnumerable<Suggestion> namespaces = Suggestion.Namespaces
.Where(x => x.StartsWith(trimmed) && x.Length > trimmed.Length)
.Select(x => new Suggestion(
x.Substring(trimmed.Length),
x.Substring(0, trimmed.Length),
Suggestion.Contexts.Namespace));
CodeEditor.AutoCompletes.AddRange(namespaces);
IEnumerable<Suggestion> keywords = Suggestion.Keywords
.Where(x => x.StartsWith(trimmed) && x.Length > trimmed.Length)
.Select(x => new Suggestion(
x.Substring(trimmed.Length),
x.Substring(0, trimmed.Length),
Suggestion.Contexts.Keyword));
CodeEditor.AutoCompletes.AddRange(keywords);
}
catch (Exception ex)
{
ExplorerCore.Log("Autocomplete error:\r\n" + ex.ToString());
ClearAutocompletes();
}
}
#region UI Construction
private static void ConstructUI()
{
var parent = UIManager.CanvasRoot;
var obj = UIFactory.CreateScrollView(parent, out GameObject content, out _, new Color(0.1f, 0.1f, 0.1f, 0.95f));
m_mainObj = obj;
var mainRect = obj.GetComponent<RectTransform>();
//m_thisRect = mainRect;
mainRect.pivot = new Vector2(0f, 1f);
mainRect.anchorMin = new Vector2(0.45f, 0.45f);
mainRect.anchorMax = new Vector2(0.65f, 0.6f);
mainRect.offsetMin = Vector2.zero;
mainRect.offsetMax = Vector2.zero;
var mainGroup = content.GetComponent<VerticalLayoutGroup>();
mainGroup.childControlHeight = false;
mainGroup.childControlWidth = true;
mainGroup.childForceExpandHeight = false;
mainGroup.childForceExpandWidth = true;
for (int i = 0; i < MAX_LABELS; i++)
{
var buttonObj = UIFactory.CreateButton(content);
Button btn = buttonObj.GetComponent<Button>();
ColorBlock btnColors = btn.colors;
btnColors.normalColor = new Color(0f, 0f, 0f, 0f);
btnColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1.0f);
btn.colors = btnColors;
var nav = btn.navigation;
nav.mode = Navigation.Mode.Vertical;
btn.navigation = nav;
var btnLayout = buttonObj.AddComponent<LayoutElement>();
btnLayout.minHeight = 20;
var text = btn.GetComponentInChildren<Text>();
text.alignment = TextAnchor.MiddleLeft;
text.color = Color.white;
var hiddenChild = UIFactory.CreateUIObject("HiddenText", buttonObj);
hiddenChild.SetActive(false);
var hiddenText = hiddenChild.AddComponent<Text>();
m_hiddenSuggestionTexts.Add(hiddenText);
btn.onClick.AddListener(UseAutocompleteButton);
void UseAutocompleteButton()
{
CSConsolePage.Instance.m_codeEditor.UseAutocomplete(hiddenText.text);
}
m_suggestionButtons.Add(buttonObj);
m_suggestionTexts.Add(text);
}
}
#endregion
}
}

View File

@ -0,0 +1,147 @@
using System.Text;
using UnityExplorer.CSConsole.Lexers;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib.UI.Models;
namespace UnityExplorer.CSConsole
{
public class CSAutoCompleter : ISuggestionProvider
{
public InputFieldRef InputField => ConsoleController.Input;
public bool AnchorToCaretPosition => true;
bool ISuggestionProvider.AllowNavigation => true;
public void OnSuggestionClicked(Suggestion suggestion)
{
ConsoleController.InsertSuggestionAtCaret(suggestion.UnderlyingValue);
AutoCompleteModal.Instance.ReleaseOwnership(this);
}
private readonly HashSet<char> delimiters = new()
{
'{',
'}',
',',
';',
'<',
'>',
'(',
')',
'[',
']',
'=',
'|',
'&',
'?'
};
private readonly List<Suggestion> suggestions = new();
public void CheckAutocompletes()
{
if (string.IsNullOrEmpty(InputField.Text))
{
AutoCompleteModal.Instance.ReleaseOwnership(this);
return;
}
suggestions.Clear();
int caret = Math.Max(0, Math.Min(InputField.Text.Length - 1, InputField.Component.caretPosition - 1));
int startIdx = caret;
// If the character at the caret index is whitespace or delimiter,
// or if the next character (if it exists) is not whitespace,
// then we don't want to provide suggestions.
if (char.IsWhiteSpace(InputField.Text[caret])
|| delimiters.Contains(InputField.Text[caret])
|| (InputField.Text.Length > caret + 1 && !char.IsWhiteSpace(InputField.Text[caret + 1])))
{
AutoCompleteModal.Instance.ReleaseOwnership(this);
return;
}
// get the current composition string (from caret back to last delimiter)
while (startIdx > 0)
{
startIdx--;
char c = InputField.Text[startIdx];
if (delimiters.Contains(c) || char.IsWhiteSpace(c))
{
startIdx++;
break;
}
}
string input = InputField.Text.Substring(startIdx, caret - startIdx + 1);
// Get MCS completions
string[] evaluatorCompletions = ConsoleController.Evaluator.GetCompletions(input, out string prefix);
if (evaluatorCompletions != null && evaluatorCompletions.Any())
{
suggestions.AddRange(from completion in evaluatorCompletions
select new Suggestion(GetHighlightString(prefix, completion), completion));
}
// Get manual namespace completions
foreach (string ns in ReflectionUtility.AllNamespaces)
{
if (ns.StartsWith(input))
{
if (!namespaceHighlights.ContainsKey(ns))
namespaceHighlights.Add(ns, $"<color=#CCCCCC>{ns}</color>");
string completion = ns.Substring(input.Length, ns.Length - input.Length);
suggestions.Add(new Suggestion(namespaceHighlights[ns], completion));
}
}
// Get manual keyword completions
foreach (string kw in KeywordLexer.keywords)
{
if (kw.StartsWith(input))// && kw.Length > input.Length)
{
if (!keywordHighlights.ContainsKey(kw))
keywordHighlights.Add(kw, $"<color=#{SignatureHighlighter.keywordBlueHex}>{kw}</color>");
string completion = kw.Substring(input.Length, kw.Length - input.Length);
suggestions.Add(new Suggestion(keywordHighlights[kw], completion));
}
}
if (suggestions.Any())
{
AutoCompleteModal.TakeOwnership(this);
AutoCompleteModal.Instance.SetSuggestions(suggestions);
}
else
{
AutoCompleteModal.Instance.ReleaseOwnership(this);
}
}
private readonly Dictionary<string, string> namespaceHighlights = new();
private readonly Dictionary<string, string> keywordHighlights = new();
private readonly StringBuilder highlightBuilder = new();
private const string OPEN_HIGHLIGHT = "<color=cyan>";
private string GetHighlightString(string prefix, string completion)
{
highlightBuilder.Clear();
highlightBuilder.Append(OPEN_HIGHLIGHT);
highlightBuilder.Append(prefix);
highlightBuilder.Append(SignatureHighlighter.CLOSE_COLOR);
highlightBuilder.Append(completion);
return highlightBuilder.ToString();
}
}
}

View File

@ -1,308 +0,0 @@
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityExplorer.CSConsole.Lexer;
namespace UnityExplorer.CSConsole
{
public struct LexerMatchInfo
{
public int startIndex;
public int endIndex;
public string htmlColor;
}
public enum DelimiterType
{
Start,
End,
};
public class CSharpLexer
{
private string inputString;
private readonly Matcher[] matchers;
private readonly HashSet<char> startDelimiters;
private readonly HashSet<char> endDelimiters;
private int currentIndex;
private int currentLookaheadIndex;
public char Current { get; private set; }
public char Previous { get; private set; }
public bool EndOfStream => currentLookaheadIndex >= inputString.Length;
public static char indentOpen = '{';
public static char indentClose = '}';
private static StringBuilder indentBuilder = new StringBuilder();
public static char[] delimiters = new[]
{
'[', ']', '(', ')', '{', '}', ';', ':', ',', '.'
};
public static CommentMatch commentMatcher = new CommentMatch();
public static SymbolMatch symbolMatcher = new SymbolMatch();
public static NumberMatch numberMatcher = new NumberMatch();
public static StringMatch stringMatcher = new StringMatch();
public static KeywordMatch validKeywordMatcher = new KeywordMatch
{
highlightColor = new Color(0.33f, 0.61f, 0.83f, 1.0f),
Keywords = new[] { "add", "as", "ascending", "await", "bool", "break", "by", "byte",
"case", "catch", "char", "checked", "const", "continue", "decimal", "default", "descending", "do", "dynamic",
"else", "equals", "false", "finally", "float", "for", "foreach", "from", "global", "goto", "group",
"if", "in", "int", "into", "is", "join", "let", "lock", "long", "new", "null", "object", "on", "orderby", "out",
"ref", "remove", "return", "sbyte", "select", "short", "sizeof", "stackalloc", "string",
"switch", "throw", "true", "try", "typeof", "uint", "ulong", "ushort", "var", "where", "while", "yield" }
};
public static KeywordMatch invalidKeywordMatcher = new KeywordMatch()
{
highlightColor = new Color(0.95f, 0.10f, 0.10f, 1.0f),
Keywords = new[] { "abstract", "async", "base", "class", "delegate", "enum", "explicit", "extern", "fixed", "get",
"implicit", "interface", "internal", "namespace", "operator", "override", "params", "private", "protected", "public",
"using", "partial", "readonly", "sealed", "set", "static", "struct", "this", "unchecked", "unsafe", "value", "virtual", "volatile", "void" }
};
// ~~~~~~~ ctor ~~~~~~~
public CSharpLexer()
{
startDelimiters = new HashSet<char>(delimiters);
endDelimiters = new HashSet<char>(delimiters);
this.matchers = new Matcher[]
{
commentMatcher,
symbolMatcher,
numberMatcher,
stringMatcher,
validKeywordMatcher,
invalidKeywordMatcher,
};
foreach (Matcher lexer in matchers)
{
foreach (char c in lexer.StartChars)
{
if (!startDelimiters.Contains(c))
startDelimiters.Add(c);
}
foreach (char c in lexer.EndChars)
{
if (!endDelimiters.Contains(c))
endDelimiters.Add(c);
}
}
}
// ~~~~~~~ Lex Matching ~~~~~~~
public IEnumerable<LexerMatchInfo> GetMatches(string input)
{
if (input == null || matchers == null || matchers.Length == 0)
{
yield break;
}
inputString = input;
Current = ' ';
Previous = ' ';
currentIndex = 0;
currentLookaheadIndex = 0;
while (!EndOfStream)
{
bool didMatchLexer = false;
ReadWhiteSpace();
foreach (Matcher matcher in matchers)
{
int startIndex = currentIndex;
bool isMatched = matcher.IsMatch(this);
if (isMatched)
{
int endIndex = currentIndex;
didMatchLexer = true;
yield return new LexerMatchInfo
{
startIndex = startIndex,
endIndex = endIndex,
htmlColor = matcher.HexColor,
};
break;
}
}
if (!didMatchLexer)
{
ReadNext();
Commit();
}
}
}
// ~~~~~~~ Indent ~~~~~~~
public static string GetIndentForInput(string input, int indent, out int caretPosition)
{
indentBuilder = new StringBuilder();
indent += 1;
bool stringState = false;
for (int i = 0; i < input.Length; i++)
{
if (input[i] == '"')
{
stringState = !stringState;
}
if (input[i] == '\n')
{
indentBuilder.Append('\n');
for (int j = 0; j < indent; j++)
{
indentBuilder.Append("\t");
}
}
else if (input[i] == '\t')
{
continue;
}
else if (!stringState && input[i] == indentOpen)
{
indentBuilder.Append(indentOpen);
indent++;
}
else if (!stringState && input[i] == indentClose)
{
indentBuilder.Append(indentClose);
indent--;
}
else
{
indentBuilder.Append(input[i]);
}
}
string formattedSection = indentBuilder.ToString();
caretPosition = formattedSection.Length - 1;
for (int i = formattedSection.Length - 1; i >= 0; i--)
{
if (formattedSection[i] == '\n')
{
continue;
}
caretPosition = i;
break;
}
return formattedSection;
}
public static int GetIndentLevel(string inputString, int startIndex, int endIndex)
{
int indent = 0;
for (int i = startIndex; i < endIndex; i++)
{
if (inputString[i] == '\t')
{
indent++;
}
// Check for end line or other characters
if (inputString[i] == '\n' || inputString[i] != ' ')
{
break;
}
}
return indent;
}
// Lexer reading
public char ReadNext()
{
if (EndOfStream)
{
return '\0';
}
Previous = Current;
Current = inputString[currentLookaheadIndex];
currentLookaheadIndex++;
return Current;
}
public void Rollback(int amount = -1)
{
if (amount == -1)
{
currentLookaheadIndex = currentIndex;
}
else
{
if (currentLookaheadIndex > currentIndex)
{
currentLookaheadIndex -= amount;
}
}
int previousIndex = currentLookaheadIndex - 1;
if (previousIndex >= inputString.Length)
{
Previous = inputString[inputString.Length - 1];
}
else if (previousIndex >= 0)
{
Previous = inputString[previousIndex];
}
else
{
Previous = ' ';
}
}
public void Commit()
{
currentIndex = currentLookaheadIndex;
}
public bool IsSpecialSymbol(char character, DelimiterType position = DelimiterType.Start)
{
if (position == DelimiterType.Start)
{
return startDelimiters.Contains(character);
}
return endDelimiters.Contains(character);
}
private void ReadWhiteSpace()
{
while (char.IsWhiteSpace(ReadNext()) == true)
{
Commit();
}
Rollback();
}
}
}

View File

@ -1,481 +0,0 @@
using System;
using System.Linq;
using System.Text;
using UnityExplorer.Input;
using UnityExplorer.CSConsole.Lexer;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityExplorer.UI;
using UnityExplorer.UI.Modules;
using System.Collections.Generic;
using System.Reflection;
using UnityExplorer.UI.Shared;
using UnityExplorer.Helpers;
namespace UnityExplorer.CSConsole
{
// Handles most of the UI side of the C# console, including syntax highlighting.
public class CodeEditor
{
public InputField InputField { get; internal set; }
public Text InputText { get; internal set; }
public int CurrentIndent { get; private set; }
public static bool EnableCtrlRShortcut { get; set; } = true;
public static bool EnableAutoIndent { get; set; } = true;
public static bool EnableAutocompletes { get; set; } = true;
public static List<Suggestion> AutoCompletes = new List<Suggestion>();
public string HighlightedText => inputHighlightText.text;
private Text inputHighlightText;
private readonly CSharpLexer highlightLexer;
private readonly StringBuilder sbHighlight;
internal int m_lastCaretPos;
internal int m_fixCaretPos;
internal bool m_fixwanted;
internal float m_lastSelectAlpha;
private static readonly KeyCode[] onFocusKeys =
{
KeyCode.Return, KeyCode.Backspace, KeyCode.UpArrow,
KeyCode.DownArrow, KeyCode.LeftArrow, KeyCode.RightArrow
};
internal const string STARTUP_TEXT = @"Welcome to the UnityExplorer C# Console.
The following helper methods are available:
* <color=#add490>Log(""message"")</color> logs a message to the debug console
* <color=#add490>CurrentTarget()</color> returns the currently inspected target on the Home page
* <color=#add490>AllTargets()</color> returns an object[] array containing all inspected instances
* <color=#add490>Inspect(someObject)</color> to inspect an instance, eg. Inspect(Camera.main);
* <color=#add490>Inspect(typeof(SomeClass))</color> to inspect a Class with static reflection
* <color=#add490>AddUsing(""SomeNamespace"")</color> adds a using directive to the C# console
* <color=#add490>GetUsing()</color> logs the current using directives to the debug console
* <color=#add490>Reset()</color> resets all using directives and variables
";
public CodeEditor()
{
sbHighlight = new StringBuilder();
highlightLexer = new CSharpLexer();
ConstructUI();
InputField.onValueChanged.AddListener((string s) => { OnInputChanged(s); });
}
public void Update()
{
if (EnableCtrlRShortcut)
{
if ((InputManager.GetKey(KeyCode.LeftControl) || InputManager.GetKey(KeyCode.RightControl))
&& InputManager.GetKeyDown(KeyCode.R))
{
var text = InputField.text.Trim();
if (!string.IsNullOrEmpty(text))
{
CSConsolePage.Instance.Evaluate(text);
return;
}
}
}
if (EnableAutoIndent && InputManager.GetKeyDown(KeyCode.Return))
AutoIndentCaret();
if (EnableAutocompletes && InputField.isFocused)
{
if (InputManager.GetMouseButton(0) || onFocusKeys.Any(it => InputManager.GetKeyDown(it)))
UpdateAutocompletes();
}
if (m_fixCaretPos > 0)
{
if (!m_fixwanted)
{
EventSystem.current.SetSelectedGameObject(InputField.gameObject, null);
m_fixwanted = true;
}
else
{
InputField.caretPosition = m_fixCaretPos;
InputField.selectionFocusPosition = m_fixCaretPos;
m_fixwanted = false;
m_fixCaretPos = -1;
var color = InputField.selectionColor;
color.a = m_lastSelectAlpha;
InputField.selectionColor = color;
}
}
else if (InputField.caretPosition > 0)
{
m_lastCaretPos = InputField.caretPosition;
}
}
internal void UpdateAutocompletes()
{
AutoCompleter.CheckAutocomplete();
AutoCompleter.SetSuggestions(AutoCompletes.ToArray());
}
public void UseAutocomplete(string suggestion)
{
string input = InputField.text;
input = input.Insert(m_lastCaretPos, suggestion);
InputField.text = input;
m_fixCaretPos = m_lastCaretPos += suggestion.Length;
var color = InputField.selectionColor;
m_lastSelectAlpha = color.a;
color.a = 0f;
InputField.selectionColor = color;
AutoCompleter.ClearAutocompletes();
}
public void OnInputChanged(string newInput, bool forceUpdate = false)
{
string newText = newInput;
UpdateIndent(newInput);
if (!forceUpdate && string.IsNullOrEmpty(newText))
inputHighlightText.text = string.Empty;
else
inputHighlightText.text = SyntaxHighlightContent(newText);
UpdateAutocompletes();
}
private void UpdateIndent(string newText)
{
int caret = InputField.caretPosition;
int len = newText.Length;
if (caret < 0 || caret >= len)
{
while (caret >= 0 && caret >= len)
caret--;
if (caret < 0)
return;
}
CurrentIndent = 0;
bool stringState = false;
for (int i = 0; i < caret && i < newText.Length; i++)
{
char character = newText[i];
if (character == '"')
stringState = !stringState;
else if (!stringState && character == CSharpLexer.indentOpen)
CurrentIndent++;
else if (!stringState && character == CSharpLexer.indentClose)
CurrentIndent--;
}
if (CurrentIndent < 0)
CurrentIndent = 0;
}
private const string CLOSE_COLOR_TAG = "</color>";
private string SyntaxHighlightContent(string inputText)
{
int offset = 0;
sbHighlight.Length = 0;
foreach (LexerMatchInfo match in highlightLexer.GetMatches(inputText))
{
for (int i = offset; i < match.startIndex; i++)
{
sbHighlight.Append(inputText[i]);
}
sbHighlight.Append($"{match.htmlColor}");
for (int i = match.startIndex; i < match.endIndex; i++)
{
sbHighlight.Append(inputText[i]);
}
sbHighlight.Append(CLOSE_COLOR_TAG);
offset = match.endIndex;
}
for (int i = offset; i < inputText.Length; i++)
{
sbHighlight.Append(inputText[i]);
}
inputText = sbHighlight.ToString();
return inputText;
}
private void AutoIndentCaret()
{
if (CurrentIndent > 0)
{
string indent = GetAutoIndentTab(CurrentIndent);
if (indent.Length > 0)
{
int caretPos = InputField.caretPosition;
string indentMinusOne = indent.Substring(0, indent.Length - 1);
// get last index of {
// chuck it on the next line if its not already
string text = InputField.text;
string sub = InputField.text.Substring(0, InputField.caretPosition);
int lastIndex = sub.LastIndexOf("{");
int offset = lastIndex - 1;
if (offset >= 0 && text[offset] != '\n' && text[offset] != '\t')
{
string open = "\n" + indentMinusOne;
InputField.text = text.Insert(offset + 1, open);
caretPos += open.Length;
}
// check if should add auto-close }
int numOpen = InputField.text.Where(x => x == CSharpLexer.indentOpen).Count();
int numClose = InputField.text.Where(x => x == CSharpLexer.indentClose).Count();
if (numOpen > numClose)
{
// add auto-indent closing
indentMinusOne = $"\n{indentMinusOne}}}";
InputField.text = InputField.text.Insert(caretPos, indentMinusOne);
}
// insert the actual auto indent now
InputField.text = InputField.text.Insert(caretPos, indent);
//InputField.stringPosition = caretPos + indent.Length;
InputField.caretPosition = caretPos + indent.Length;
}
}
// Update line column and indent positions
UpdateIndent(InputField.text);
InputText.text = InputField.text;
//inputText.SetText(InputField.text, true);
InputText.Rebuild(CanvasUpdate.Prelayout);
InputField.ForceLabelUpdate();
InputField.Rebuild(CanvasUpdate.Prelayout);
OnInputChanged(InputText.text, true);
}
private string GetAutoIndentTab(int amount)
{
string tab = string.Empty;
for (int i = 0; i < amount; i++)
{
tab += "\t";
}
return tab;
}
// ========== UI CONSTRUCTION =========== //
public void ConstructUI()
{
CSConsolePage.Instance.Content = UIFactory.CreateUIObject("C# Console", MainMenu.Instance.PageViewport);
var mainLayout = CSConsolePage.Instance.Content.AddComponent<LayoutElement>();
mainLayout.preferredHeight = 500;
mainLayout.flexibleHeight = 9000;
var mainGroup = CSConsolePage.Instance.Content.AddComponent<VerticalLayoutGroup>();
mainGroup.childControlHeight = true;
mainGroup.childControlWidth = true;
mainGroup.childForceExpandHeight = true;
mainGroup.childForceExpandWidth = true;
#region TOP BAR
// Main group object
var topBarObj = UIFactory.CreateHorizontalGroup(CSConsolePage.Instance.Content);
LayoutElement topBarLayout = topBarObj.AddComponent<LayoutElement>();
topBarLayout.minHeight = 50;
topBarLayout.flexibleHeight = 0;
var topBarGroup = topBarObj.GetComponent<HorizontalLayoutGroup>();
topBarGroup.padding.left = 30;
topBarGroup.padding.right = 30;
topBarGroup.padding.top = 8;
topBarGroup.padding.bottom = 8;
topBarGroup.spacing = 10;
topBarGroup.childForceExpandHeight = true;
topBarGroup.childForceExpandWidth = true;
topBarGroup.childControlWidth = true;
topBarGroup.childControlHeight = true;
topBarGroup.childAlignment = TextAnchor.LowerCenter;
var topBarLabel = UIFactory.CreateLabel(topBarObj, TextAnchor.MiddleLeft);
var topBarLabelLayout = topBarLabel.AddComponent<LayoutElement>();
topBarLabelLayout.preferredWidth = 150;
topBarLabelLayout.flexibleWidth = 5000;
var topBarText = topBarLabel.GetComponent<Text>();
topBarText.text = "C# Console";
topBarText.fontSize = 20;
// Enable Ctrl+R toggle
var ctrlRToggleObj = UIFactory.CreateToggle(topBarObj, out Toggle ctrlRToggle, out Text ctrlRToggleText);
ctrlRToggle.onValueChanged.AddListener(CtrlRToggleCallback);
void CtrlRToggleCallback(bool val)
{
EnableCtrlRShortcut = val;
}
ctrlRToggleText.text = "Run on Ctrl+R";
ctrlRToggleText.alignment = TextAnchor.UpperLeft;
var ctrlRLayout = ctrlRToggleObj.AddComponent<LayoutElement>();
ctrlRLayout.minWidth = 140;
ctrlRLayout.flexibleWidth = 0;
ctrlRLayout.minHeight = 25;
// Enable Suggestions toggle
var suggestToggleObj = UIFactory.CreateToggle(topBarObj, out Toggle suggestToggle, out Text suggestToggleText);
suggestToggle.onValueChanged.AddListener(SuggestToggleCallback);
void SuggestToggleCallback(bool val)
{
EnableAutocompletes = val;
AutoCompleter.Update();
}
suggestToggleText.text = "Suggestions";
suggestToggleText.alignment = TextAnchor.UpperLeft;
var suggestLayout = suggestToggleObj.AddComponent<LayoutElement>();
suggestLayout.minWidth = 120;
suggestLayout.flexibleWidth = 0;
suggestLayout.minHeight = 25;
// Enable Auto-indent toggle
var autoIndentToggleObj = UIFactory.CreateToggle(topBarObj, out Toggle autoIndentToggle, out Text autoIndentToggleText);
autoIndentToggle.onValueChanged.AddListener(OnIndentChanged);
void OnIndentChanged(bool val) => EnableAutoIndent = val;
autoIndentToggleText.text = "Auto-indent on Enter";
autoIndentToggleText.alignment = TextAnchor.UpperLeft;
var autoIndentLayout = autoIndentToggleObj.AddComponent<LayoutElement>();
autoIndentLayout.minWidth = 180;
autoIndentLayout.flexibleWidth = 0;
autoIndentLayout.minHeight = 25;
#endregion
#region CONSOLE INPUT
int fontSize = 16;
var inputObj = UIFactory.CreateSrollInputField(CSConsolePage.Instance.Content, out InputFieldScroller consoleScroll, fontSize);
var inputField = consoleScroll.inputField;
var mainTextObj = inputField.textComponent.gameObject;
var mainTextInput = inputField.textComponent;
mainTextInput.supportRichText = false;
mainTextInput.color = new Color(1, 1, 1, 0.5f);
var placeHolderText = inputField.placeholder.GetComponent<Text>();
placeHolderText.text = STARTUP_TEXT;
placeHolderText.fontSize = fontSize;
var highlightTextObj = UIFactory.CreateUIObject("HighlightText", mainTextObj.gameObject);
var highlightTextRect = highlightTextObj.GetComponent<RectTransform>();
highlightTextRect.pivot = new Vector2(0, 1);
highlightTextRect.anchorMin = Vector2.zero;
highlightTextRect.anchorMax = Vector2.one;
highlightTextRect.offsetMin = new Vector2(20, 0);
highlightTextRect.offsetMax = new Vector2(14, 0);
var highlightTextInput = highlightTextObj.AddComponent<Text>();
highlightTextInput.supportRichText = true;
highlightTextInput.fontSize = fontSize;
#endregion
#region COMPILE BUTTON
var compileBtnObj = UIFactory.CreateButton(CSConsolePage.Instance.Content);
var compileBtnLayout = compileBtnObj.AddComponent<LayoutElement>();
compileBtnLayout.preferredWidth = 80;
compileBtnLayout.flexibleWidth = 0;
compileBtnLayout.minHeight = 45;
compileBtnLayout.flexibleHeight = 0;
var compileButton = compileBtnObj.GetComponent<Button>();
var compileBtnColors = compileButton.colors;
compileBtnColors.normalColor = new Color(14f / 255f, 80f / 255f, 14f / 255f);
compileButton.colors = compileBtnColors;
var btnText = compileBtnObj.GetComponentInChildren<Text>();
btnText.text = "Run";
btnText.fontSize = 18;
btnText.color = Color.white;
// Set compile button callback now that we have the Input Field reference
compileButton.onClick.AddListener(CompileCallback);
void CompileCallback()
{
if (!string.IsNullOrEmpty(inputField.text))
{
CSConsolePage.Instance.Evaluate(inputField.text.Trim());
}
}
#endregion
//mainTextInput.supportRichText = false;
mainTextInput.font = UIManager.ConsoleFont;
placeHolderText.font = UIManager.ConsoleFont;
highlightTextInput.font = UIManager.ConsoleFont;
// reset this after formatting finalized
highlightTextRect.anchorMin = Vector2.zero;
highlightTextRect.anchorMax = Vector2.one;
highlightTextRect.offsetMin = Vector2.zero;
highlightTextRect.offsetMax = Vector2.zero;
// assign references
this.InputField = inputField;
this.InputText = mainTextInput;
this.inputHighlightText = highlightTextInput;
}
}
}

View File

@ -0,0 +1,747 @@
using Mono.CSharp;
using System.Collections;
using System.Text;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels;
using UniverseLib.Input;
using UniverseLib.UI.Models;
namespace UnityExplorer.CSConsole
{
public static class ConsoleController
{
public static ScriptEvaluator Evaluator { get; private set; }
public static LexerBuilder Lexer { get; private set; }
public static CSAutoCompleter Completer { get; private set; }
public static bool SRENotSupported { get; private set; }
public static int LastCaretPosition { get; private set; }
public static float DefaultInputFieldAlpha { get; set; }
public static bool EnableCtrlRShortcut { get; private set; } = true;
public static bool EnableAutoIndent { get; private set; } = true;
public static bool EnableSuggestions { get; private set; } = true;
public static CSConsolePanel Panel => UIManager.GetPanel<CSConsolePanel>(UIManager.Panels.CSConsole);
public static InputFieldRef Input => Panel.Input;
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.Linq",
"System.Text",
"System.Collections",
"System.Collections.Generic",
"System.Reflection",
"UnityEngine",
"UniverseLib",
#if CPP
"UnhollowerBaseLib",
"UnhollowerRuntimeLib",
#endif
};
const int CSCONSOLE_LINEHEIGHT = 18;
public static void Init()
{
try
{
ResetConsole(false);
// ensure the compiler is supported (if this fails then SRE is probably stripped)
Evaluator.Compile("0 == 0");
}
catch (Exception ex)
{
DisableConsole(ex);
return;
}
// Setup console
Lexer = new LexerBuilder();
Completer = new CSAutoCompleter();
SetupHelpInteraction();
Panel.OnInputChanged += OnInputChanged;
Panel.InputScroller.OnScroll += OnInputScrolled;
Panel.OnCompileClicked += Evaluate;
Panel.OnResetClicked += ResetConsole;
Panel.OnHelpDropdownChanged += HelpSelected;
Panel.OnAutoIndentToggled += OnToggleAutoIndent;
Panel.OnCtrlRToggled += OnToggleCtrlRShortcut;
Panel.OnSuggestionsToggled += OnToggleSuggestions;
Panel.OnPanelResized += OnInputScrolled;
// Run startup script
try
{
if (!Directory.Exists(ScriptsFolder))
Directory.CreateDirectory(ScriptsFolder);
string startupPath = Path.Combine(ScriptsFolder, "startup.cs");
if (File.Exists(startupPath))
{
ExplorerCore.Log($"Executing startup script from '{startupPath}'...");
string text = File.ReadAllText(startupPath);
Input.Text = text;
Evaluate();
}
}
catch (Exception ex)
{
ExplorerCore.LogWarning($"Exception executing startup script: {ex}");
}
}
#region Evaluating
static void GenerateTextWriter()
{
evaluatorOutput = new StringBuilder();
evaluatorStringWriter = new StringWriter(evaluatorOutput);
}
public static void ResetConsole() => ResetConsole(true);
public static void ResetConsole(bool logSuccess = true)
{
if (SRENotSupported)
return;
if (Evaluator != null)
Evaluator.Dispose();
GenerateTextWriter();
Evaluator = new ScriptEvaluator(evaluatorStringWriter)
{
InteractiveBaseClass = typeof(ScriptInteraction)
};
usingDirectives = new HashSet<string>();
foreach (string use in DefaultUsing)
AddUsing(use);
if (logSuccess)
ExplorerCore.Log($"C# Console reset");//. Using directives:\r\n{Evaluator.GetUsing()}");
}
public static void AddUsing(string assemblyName)
{
if (!usingDirectives.Contains(assemblyName))
{
Evaluate($"using {assemblyName};", true);
usingDirectives.Add(assemblyName);
}
}
public static void Evaluate()
{
if (SRENotSupported)
return;
Evaluate(Input.Text);
}
public static void Evaluate(string input, bool supressLog = false)
{
if (SRENotSupported)
return;
if (evaluatorStringWriter == null || evaluatorOutput == null)
{
GenerateTextWriter();
Evaluator._textWriter = evaluatorStringWriter;
}
try
{
// Compile the code. If it returned a CompiledMethod, it is REPL.
CompiledMethod repl = Evaluator.Compile(input);
if (repl != null)
{
// Valid REPL, we have a delegate to the evaluation.
try
{
object ret = null;
repl.Invoke(ref ret);
string result = ret?.ToString();
if (!string.IsNullOrEmpty(result))
ExplorerCore.Log($"Invoked REPL, result: {ret}");
else
ExplorerCore.Log($"Invoked REPL (no return value)");
}
catch (Exception ex)
{
ExplorerCore.LogWarning($"Exception invoking REPL: {ex}");
}
}
else
{
// The compiled code was not REPL, so it was a using directive or it defined classes.
string output = Evaluator._textWriter.ToString();
string[] outputSplit = output.Split('\n');
if (outputSplit.Length >= 2)
output = outputSplit[outputSplit.Length - 2];
evaluatorOutput.Clear();
if (ScriptEvaluator._reportPrinter.ErrorsCount > 0)
throw new FormatException($"Unable to compile the code. Evaluator's last output was:\r\n{output}");
else if (!supressLog)
ExplorerCore.Log($"Code compiled without errors.");
}
}
catch (FormatException fex)
{
if (!supressLog)
ExplorerCore.LogWarning(fex.Message);
}
catch (Exception ex)
{
if (!supressLog)
ExplorerCore.LogWarning(ex);
}
}
#endregion
#region Update loop and event listeners
public static void Update()
{
if (SRENotSupported)
return;
if (!InputManager.GetKey(KeyCode.LeftControl) && !InputManager.GetKey(KeyCode.RightControl))
{
if (InputManager.GetKeyDown(KeyCode.Home))
JumpToStartOrEndOfLine(true);
else if (InputManager.GetKeyDown(KeyCode.End))
JumpToStartOrEndOfLine(false);
}
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);
}
}
static void OnInputScrolled() => HighlightVisibleInput(out _);
static void OnInputChanged(string value)
{
if (SRENotSupported)
return;
// prevent escape wiping input
if (InputManager.GetKeyDown(KeyCode.Escape))
{
Input.Text = previousInput;
if (EnableSuggestions && AutoCompleteModal.CheckEscape(Completer))
OnAutocompleteEscaped();
return;
}
previousInput = value;
if (EnableSuggestions && AutoCompleteModal.CheckEnter(Completer))
OnAutocompleteEnter();
if (!settingCaretCoroutine)
{
if (EnableAutoIndent)
DoAutoIndent();
}
HighlightVisibleInput(out bool inStringOrComment);
if (!settingCaretCoroutine)
{
if (EnableSuggestions)
{
if (inStringOrComment)
AutoCompleteModal.Instance.ReleaseOwnership(Completer);
else
Completer.CheckAutocompletes();
}
}
UpdateCaret(out _);
}
static void OnToggleAutoIndent(bool value)
{
EnableAutoIndent = value;
}
static void OnToggleCtrlRShortcut(bool value)
{
EnableCtrlRShortcut = value;
}
static void OnToggleSuggestions(bool value)
{
EnableSuggestions = value;
}
#endregion
#region Caret position
static void UpdateCaret(out bool caretMoved)
{
int prevCaret = LastCaretPosition;
caretMoved = false;
// Override up/down arrow movement when autocompleting
if (EnableSuggestions && AutoCompleteModal.CheckNavigation(Completer))
{
Input.Component.caretPosition = LastCaretPosition;
return;
}
if (Input.Component.isFocused)
{
LastCaretPosition = Input.Component.caretPosition;
caretMoved = LastCaretPosition != prevCaret;
}
if (Input.Text.Length == 0)
return;
// If caret moved, ensure caret is visible in the viewport
if (caretMoved)
{
UICharInfo charInfo = Input.TextGenerator.characters[LastCaretPosition];
float charTop = charInfo.cursorPos.y;
float charBot = charTop - CSCONSOLE_LINEHEIGHT;
float viewportMin = Input.Transform.rect.height - Input.Transform.anchoredPosition.y - (Input.Transform.rect.height * 0.5f);
float viewportMax = viewportMin - Panel.InputScroller.ViewportRect.rect.height;
float diff = 0f;
if (charTop > viewportMin)
diff = charTop - viewportMin;
else if (charBot < viewportMax)
diff = charBot - viewportMax;
if (Math.Abs(diff) > 1)
{
RectTransform rect = Input.Transform;
rect.anchoredPosition = new Vector2(rect.anchoredPosition.x, rect.anchoredPosition.y - diff);
}
}
}
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;
Input.Component.readOnly = true;
RuntimeHelper.StartCoroutine(DoSetCaretCoroutine(caretPosition));
}
static IEnumerator DoSetCaretCoroutine(int caretPosition)
{
Color color = Input.Component.selectionColor;
color.a = 0f;
Input.Component.selectionColor = color;
EventSystemHelper.SetSelectionGuard(false);
Input.Component.Select();
yield return null; // ~~~~~~~ YIELD FRAME ~~~~~~~~~
Input.Component.caretPosition = caretPosition;
Input.Component.selectionFocusPosition = caretPosition;
LastCaretPosition = Input.Component.caretPosition;
color.a = DefaultInputFieldAlpha;
Input.Component.selectionColor = color;
Input.Component.readOnly = 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
private static void HighlightVisibleInput(out bool inStringOrComment)
{
inStringOrComment = false;
if (string.IsNullOrEmpty(Input.Text))
{
Panel.HighlightText.text = "";
Panel.LineNumberText.text = "1";
return;
}
// Calculate the visible lines
int topLine = -1;
int bottomLine = -1;
// the top and bottom position of the viewport in relation to the text height
// they need the half-height adjustment to normalize against the 'line.topY' value.
float viewportMin = Input.Transform.rect.height - Input.Transform.anchoredPosition.y - (Input.Transform.rect.height * 0.5f);
float viewportMax = viewportMin - Panel.InputScroller.ViewportRect.rect.height;
for (int i = 0; i < Input.TextGenerator.lineCount; i++)
{
UILineInfo line = Input.TextGenerator.lines[i];
// if not set the top line yet, and top of line is below the viewport top
if (topLine == -1 && line.topY <= viewportMin)
topLine = i;
// if bottom of line is below the viewport bottom
if ((line.topY - line.height) >= viewportMax)
bottomLine = i;
}
topLine = Math.Max(0, topLine - 1);
bottomLine = Math.Min(Input.TextGenerator.lineCount - 1, bottomLine + 1);
int startIdx = Input.TextGenerator.lines[topLine].startCharIdx;
int endIdx = (bottomLine >= Input.TextGenerator.lineCount - 1)
? Input.Text.Length - 1
: (Input.TextGenerator.lines[bottomLine + 1].startCharIdx - 1);
// Highlight the visible text with the LexerBuilder
Panel.HighlightText.text = Lexer.BuildHighlightedString(Input.Text, startIdx, endIdx, topLine, LastCaretPosition, out inStringOrComment);
// Set the line numbers
// determine true starting line number (not the same as the cached TextGenerator line numbers)
int realStartLine = 0;
for (int i = 0; i < startIdx; i++)
{
if (LexerBuilder.IsNewLine(Input.Text[i]))
realStartLine++;
}
realStartLine++;
char lastPrev = '\n';
StringBuilder sb = new();
// append leading new lines for spacing (no point rendering line numbers we cant see)
for (int i = 0; i < topLine; i++)
sb.Append('\n');
// append the displayed line numbers
for (int i = topLine; i <= bottomLine; i++)
{
if (i > 0)
lastPrev = Input.Text[Input.TextGenerator.lines[i].startCharIdx - 1];
// previous line ended with a newline character, this is an actual new line.
if (LexerBuilder.IsNewLine(lastPrev))
{
sb.Append(realStartLine.ToString());
realStartLine++;
}
sb.Append('\n');
}
Panel.LineNumberText.text = sb.ToString();
return;
}
#endregion
#region Autocompletes
public static void InsertSuggestionAtCaret(string suggestion)
{
settingCaretCoroutine = true;
Input.Text = Input.Text.Insert(LastCaretPosition, suggestion);
SetCaretPosition(LastCaretPosition + suggestion.Length);
LastCaretPosition = Input.Component.caretPosition;
}
private static void OnAutocompleteEnter()
{
// Remove the new line
int lastIdx = Input.Component.caretPosition - 1;
Input.Text = Input.Text.Remove(lastIdx, 1);
// Use the selected suggestion
Input.Component.caretPosition = LastCaretPosition;
Completer.OnSuggestionClicked(AutoCompleteModal.SelectedSuggestion);
}
private static void OnAutocompleteEscaped()
{
AutoCompleteModal.Instance.ReleaseOwnership(Completer);
SetCaretPosition(LastCaretPosition);
}
#endregion
#region Auto indenting
private static void DoAutoIndent()
{
if (Input.Text.Length > previousContentLength)
{
int inc = Input.Text.Length - previousContentLength;
if (inc == 1)
{
int caret = Input.Component.caretPosition;
Input.Text = Lexer.IndentCharacter(Input.Text, ref caret);
Input.Component.caretPosition = caret;
LastCaretPosition = caret;
}
else
{
// todo indenting for copy+pasted content
//ExplorerCore.Log("Content increased by " + inc);
//var comp = Input.Text.Substring(PreviousCaretPosition, inc);
//ExplorerCore.Log("composition string: " + comp);
}
}
previousContentLength = Input.Text.Length;
}
#endregion
#region "Help" interaction
private static void DisableConsole(Exception ex)
{
SRENotSupported = true;
Input.Component.readOnly = true;
Input.Component.textComponent.color = "5d8556".ToColor();
if (ex is NotSupportedException)
{
Input.Text = $@"The C# Console has been disabled because System.Reflection.Emit threw a NotSupportedException.
Easy, dirty fix: (will likely break on game updates)
* Download the corlibs for the game's Unity version from here: https://unity.bepinex.dev/corlibs/
* Unzip and copy mscorlib.dll (and System.Reflection.Emit DLLs, if present) from the folder
* Paste and overwrite the files into <Game>_Data/Managed/
With UnityDoorstop: (BepInEx only, or if you use UnityDoorstop + Standalone release):
* Download the corlibs for the game's Unity version from here: https://unity.bepinex.dev/corlibs/
* Unzip and copy mscorlib.dll (and System.Reflection.Emit DLLs, if present) from the folder
* Find the folder which contains doorstop_config.ini (the game folder, or your r2modman/ThunderstoreModManager profile folder)
* Make a subfolder called 'corlibs' inside this folder.
* Paste the DLLs inside the corlibs folder.
* In doorstop_config.ini, set 'dllSearchPathOverride=corlibs'.
Doorstop example:
- <Game>\
- <Game>_Data\...
- BepInEx\...
- corlibs\
- mscorlib.dll
- doorstop_config.ini (with dllSearchPathOverride=corlibs)
- <Game>.exe
- winhttp.dll";
}
else
{
Input.Text = $"The C# Console has been disabled. {ex}";
}
}
private static readonly Dictionary<string, string> helpDict = new();
public static void SetupHelpInteraction()
{
Dropdown drop = Panel.HelpDropdown;
helpDict.Add("Help", "");
helpDict.Add("Usings", HELP_USINGS);
helpDict.Add("REPL", HELP_REPL);
helpDict.Add("Classes", HELP_CLASSES);
helpDict.Add("Coroutines", HELP_COROUTINES);
foreach (KeyValuePair<string, string> opt in helpDict)
drop.options.Add(new Dropdown.OptionData(opt.Key));
}
public static void HelpSelected(int index)
{
if (index == 0)
return;
KeyValuePair<string, string> helpText = helpDict.ElementAt(index);
Input.Text = helpText.Value;
Panel.HelpDropdown.value = 0;
}
internal const string STARTUP_TEXT = @"<color=#5d8556>// Welcome to the UnityExplorer C# Console!
// It is recommended to use the Log panel (or a console log window) while using this tool.
// Use the Help dropdown to see detailed examples of how to use the console.
// To execute a script automatically on startup, put the script at 'sinai-dev-UnityExplorer\Scripts\startup.cs'</color>";
internal const string HELP_USINGS = @"// You can add a using directive to any namespace, but you must compile for it to take effect.
// It will remain in effect until you Reset the console.
using UnityEngine.UI;
// To see your current usings, use the ""GetUsing();"" helper.
// Note: You cannot add usings and evaluate REPL at the same time.";
internal const string HELP_REPL = @"/* REPL (Read-Evaluate-Print-Loop) is a way to execute code immediately.
* REPL code cannot contain any using directives or classes.
* The return value of the last line of your REPL will be printed to the log.
* Variables defined in REPL will exist until you Reset the console.
*/
// eg: This code would print 'Hello, World!', and then print 6 as the return value.
Log(""Hello, world!"");
var x = 5;
++x;
/* The following helpers are available in REPL mode:
* CurrentTarget; - System.Object, the target of the active Inspector tab
* AllTargets; - System.Object[], the targets of all Inspector tabs
* Log(obj); - prints a message to the console log
* Inspect(obj); - inspect the object with the Inspector
* Inspect(someType); - inspect a Type with static reflection
* Start(enumerator); - Coroutine, starts the IEnumerator as a Coroutine, and returns the Coroutine.
* Stop(coroutine); - stop the Coroutine ONLY if it was started with Start(ienumerator).
* Copy(obj); - copies the object to the UnityExplorer Clipboard
* Paste(); - System.Object, the contents of the Clipboard.
* GetUsing(); - prints the current using directives to the console log
* GetVars(); - prints the names and values of the REPL variables you have defined
* GetClasses(); - prints the names and members of the classes you have defined
* help; - the default REPL help command, contains additional helpers.
*/";
internal const string HELP_CLASSES = @"// Classes you compile will exist until the application closes.
// You can soft-overwrite a class by compiling it again with the same name. The old class will still technically exist in memory.
// Compiled classes can be accessed from both inside and outside this console.
// Note: in IL2CPP, you must declare a Namespace to inject these classes with ClassInjector or it will crash the game.
public class HelloWorld
{
public static void Main()
{
UnityExplorer.ExplorerCore.Log(""Hello, world!"");
}
}
// In REPL, you could call the example method above with ""HelloWorld.Main();""
// Note: The compiler does not allow you to run REPL code and define classes at the same time.
// In REPL, use the ""GetClasses();"" helper to see the classes you have defined since the last Reset.";
internal const string HELP_COROUTINES = @"// To start a Coroutine directly, use ""Start(SomeCoroutine());"" in REPL mode.
// To declare a coroutine, you will need to compile it separately. For example:
public class MyCoro
{
public static IEnumerator Main()
{
yield return null;
UnityExplorer.ExplorerCore.Log(""Hello, world after one frame!"");
}
}
// To run this Coroutine in REPL, it would look like ""Start(MyCoro.Main());""";
#endregion
}
}

View File

@ -1,46 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
namespace UnityExplorer.CSConsole.Lexer
{
public class CommentMatch : Matcher
{
public string lineCommentStart = @"//";
public string blockCommentStart = @"/*";
public string blockCommentEnd = @"*/";
public override Color HighlightColor => new Color(0.34f, 0.65f, 0.29f, 1.0f);
public override IEnumerable<char> StartChars => new char[] { lineCommentStart[0], blockCommentStart[0] };
public override IEnumerable<char> EndChars => new char[] { blockCommentEnd[0] };
public override bool IsImplicitMatch(CSharpLexer lexer) => IsMatch(lexer, lineCommentStart) || IsMatch(lexer, blockCommentStart);
private bool IsMatch(CSharpLexer lexer, string commentType)
{
if (!string.IsNullOrEmpty(commentType))
{
lexer.Rollback();
bool match = true;
for (int i = 0; i < commentType.Length; i++)
{
if (commentType[i] != lexer.ReadNext())
{
match = false;
break;
}
}
if (match)
{
// Read until end of line or file
while (!IsEndLineOrEndFile(lexer, lexer.ReadNext())) { }
return true;
}
}
return false;
}
private bool IsEndLineOrEndFile(CSharpLexer lexer, char character) => lexer.EndOfStream || character == '\n' || character == '\r';
}
}

View File

@ -1,97 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
namespace UnityExplorer.CSConsole.Lexer
{
// I use two different KeywordMatch instances (valid and invalid).
// This class just contains common implementations.
public class KeywordMatch : Matcher
{
public string[] Keywords;
public override Color HighlightColor => highlightColor;
public Color highlightColor;
private readonly HashSet<string> shortlist = new HashSet<string>();
private readonly Stack<string> removeList = new Stack<string>();
public override bool IsImplicitMatch(CSharpLexer lexer)
{
if (!char.IsWhiteSpace(lexer.Previous) &&
!lexer.IsSpecialSymbol(lexer.Previous, DelimiterType.End))
{
return false;
}
shortlist.Clear();
int currentIndex = 0;
char currentChar = lexer.ReadNext();
for (int i = 0; i < Keywords.Length; i++)
{
if (Keywords[i][0] == currentChar)
{
shortlist.Add(Keywords[i]);
}
}
if (shortlist.Count == 0)
{
return false;
}
do
{
if (lexer.EndOfStream)
{
RemoveLongStrings(currentIndex + 1);
break;
}
currentChar = lexer.ReadNext();
currentIndex++;
if (char.IsWhiteSpace(currentChar) ||
lexer.IsSpecialSymbol(currentChar, DelimiterType.Start))
{
RemoveLongStrings(currentIndex);
lexer.Rollback(1);
break;
}
foreach (string keyword in shortlist)
{
if (currentIndex >= keyword.Length || keyword[currentIndex] != currentChar)
{
removeList.Push(keyword);
}
}
while (removeList.Count > 0)
{
shortlist.Remove(removeList.Pop());
}
}
while (shortlist.Count > 0);
return shortlist.Count > 0;
}
private void RemoveLongStrings(int length)
{
foreach (string keyword in shortlist)
{
if (keyword.Length > length)
{
removeList.Push(keyword);
}
}
while (removeList.Count > 0)
{
shortlist.Remove(removeList.Pop());
}
}
}
}

View File

@ -1,32 +0,0 @@
using System.Collections.Generic;
using UnityExplorer.Unstrip;
using UnityEngine;
using System.Linq;
namespace UnityExplorer.CSConsole.Lexer
{
public abstract class Matcher
{
public abstract Color HighlightColor { get; }
public string HexColor => htmlColor ?? (htmlColor = "<color=#" + HighlightColor.ToHex() + ">");
private string htmlColor;
public virtual IEnumerable<char> StartChars => Enumerable.Empty<char>();
public virtual IEnumerable<char> EndChars => Enumerable.Empty<char>();
public abstract bool IsImplicitMatch(CSharpLexer lexer);
public bool IsMatch(CSharpLexer lexer)
{
if (IsImplicitMatch(lexer))
{
lexer.Commit();
return true;
}
lexer.Rollback();
return false;
}
}
}

View File

@ -1,39 +0,0 @@
using UnityEngine;
namespace UnityExplorer.CSConsole.Lexer
{
public class NumberMatch : Matcher
{
public override Color HighlightColor => new Color(0.58f, 0.33f, 0.33f, 1.0f);
public override bool IsImplicitMatch(CSharpLexer lexer)
{
if (!char.IsWhiteSpace(lexer.Previous) &&
!lexer.IsSpecialSymbol(lexer.Previous, DelimiterType.End))
{
return false;
}
bool matchedNumber = false;
while (!lexer.EndOfStream)
{
if (IsNumberOrDecimalPoint(lexer.ReadNext()))
{
matchedNumber = true;
lexer.Commit();
}
else
{
lexer.Rollback();
break;
}
}
return matchedNumber;
}
private bool IsNumberOrDecimalPoint(char character) => char.IsNumber(character) || character == '.';
}
}

View File

@ -1,26 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
namespace UnityExplorer.CSConsole.Lexer
{
public class StringMatch : Matcher
{
public override Color HighlightColor => new Color(0.79f, 0.52f, 0.32f, 1.0f);
public override IEnumerable<char> StartChars => new[] { '"' };
public override IEnumerable<char> EndChars => new[] { '"' };
public override bool IsImplicitMatch(CSharpLexer lexer)
{
if (lexer.ReadNext() == '"')
{
while (!IsClosingQuoteOrEndFile(lexer, lexer.ReadNext())) { }
return true;
}
return false;
}
private bool IsClosingQuoteOrEndFile(CSharpLexer lexer, char character) => lexer.EndOfStream || character == '"';
}
}

View File

@ -1,106 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityExplorer.CSConsole.Lexer
{
public class SymbolMatch : Matcher
{
public override Color HighlightColor => new Color(0.58f, 0.47f, 0.37f, 1.0f);
private readonly string[] symbols = new[]
{
"[", "]", "(", ")", ".", "?", ":", "+", "-", "*", "/", "%", "&", "|", "^", "~", "=", "<", ">",
"++", "--", "&&", "||", "<<", ">>", "==", "!=", "<=", ">=", "+=", "-=", "*=", "/=", "%=", "&=",
"|=", "^=", "<<=", ">>=", "->", "??", "=>",
};
private static readonly List<string> shortlist = new List<string>();
private static readonly Stack<string> removeList = new Stack<string>();
public override IEnumerable<char> StartChars => symbols.Select(s => s[0]);
public override IEnumerable<char> EndChars => symbols.Select(s => s[0]);
public override bool IsImplicitMatch(CSharpLexer lexer)
{
if (lexer == null)
return false;
if (!char.IsWhiteSpace(lexer.Previous) &&
!char.IsLetter(lexer.Previous) &&
!char.IsDigit(lexer.Previous) &&
!lexer.IsSpecialSymbol(lexer.Previous, DelimiterType.End))
{
return false;
}
shortlist.Clear();
int currentIndex = 0;
char currentChar = lexer.ReadNext();
for (int i = symbols.Length - 1; i >= 0; i--)
{
if (symbols[i][0] == currentChar)
shortlist.Add(symbols[i]);
}
if (shortlist.Count == 0)
return false;
do
{
if (lexer.EndOfStream)
{
RemoveLongStrings(currentIndex + 1);
break;
}
currentChar = lexer.ReadNext();
currentIndex++;
if (char.IsWhiteSpace(currentChar) ||
char.IsLetter(currentChar) ||
char.IsDigit(currentChar) ||
lexer.IsSpecialSymbol(currentChar, DelimiterType.Start))
{
RemoveLongStrings(currentIndex);
lexer.Rollback(1);
break;
}
foreach (string symbol in shortlist)
{
if (currentIndex >= symbol.Length || symbol[currentIndex] != currentChar)
{
removeList.Push(symbol);
}
}
while (removeList.Count > 0)
{
shortlist.Remove(removeList.Pop());
}
}
while (shortlist.Count > 0);
return shortlist.Count > 0;
}
private void RemoveLongStrings(int length)
{
foreach (string keyword in shortlist)
{
if (keyword.Length > length)
{
removeList.Push(keyword);
}
}
while (removeList.Count > 0)
{
shortlist.Remove(removeList.Pop());
}
}
}
}

View File

@ -0,0 +1,351 @@
using System.Text;
using UnityExplorer.CSConsole.Lexers;
namespace UnityExplorer.CSConsole
{
public struct MatchInfo
{
public int startIndex;
public int endIndex;
public bool isStringOrComment;
public bool matchToEndOfLine;
public string htmlColorTag;
}
public class LexerBuilder
{
public const char WHITESPACE = ' ';
public readonly HashSet<char> IndentOpenChars = new() { '{', '(' };
public readonly HashSet<char> IndentCloseChars = new() { '}', ')' };
private readonly Lexer[] lexers;
private readonly HashSet<char> delimiters = new();
private readonly StringLexer stringLexer = new();
private readonly CommentLexer commentLexer = new();
public LexerBuilder()
{
lexers = new Lexer[]
{
commentLexer,
stringLexer,
new SymbolLexer(),
new NumberLexer(),
new KeywordLexer(),
};
foreach (Lexer matcher in lexers)
{
foreach (char c in matcher.Delimiters)
{
if (!delimiters.Contains(c))
delimiters.Add(c);
}
}
}
/// <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; }
/// <summary>The index of the character we are currently parsing, at minimum it will be CommittedIndex + 1.</summary>
public int CurrentIndex { get; private set; }
/// <summary>The current character we are parsing, determined by CurrentIndex.</summary>
public char Current => !EndOfInput ? currentInput[CurrentIndex] : WHITESPACE;
/// <summary>The previous character (CurrentIndex - 1), or whitespace if no previous character.</summary>
public char Previous => CurrentIndex >= 1 ? currentInput[CurrentIndex - 1] : WHITESPACE;
/// <summary>Returns true if CurrentIndex is >= the current input length.</summary>
public bool EndOfInput => CurrentIndex > currentEndIdx;
/// <summary>Returns true if EndOfInput or current character is a new line.</summary>
public bool EndOrNewLine => EndOfInput || IsNewLine(Current);
public static bool IsNewLine(char c) => c == '\n' || c == '\r';
private string currentInput;
private int currentStartIdx;
private int currentEndIdx;
/// <summary>
/// Parse the range of the string with the Lexer and build a RichText-highlighted representation of it.
/// </summary>
/// <param name="input">The entire input string which you want to parse a section (or all) of</param>
/// <param name="startIdx">The first character you want to highlight</param>
/// <param name="endIdx">The last character you want to highlight</param>
/// <param name="leadingLines">The amount of leading empty lines you want before the first character in the return string.</param>
/// <returns>A string which contains the amount of leading lines specified, as well as the rich-text highlighted section.</returns>
public string BuildHighlightedString(string input, int startIdx, int endIdx, int leadingLines, int caretIdx, out bool caretInStringOrComment)
{
caretInStringOrComment = false;
if (string.IsNullOrEmpty(input) || endIdx <= startIdx)
return input;
currentInput = input;
currentStartIdx = startIdx;
currentEndIdx = endIdx;
StringBuilder sb = new();
for (int i = 0; i < leadingLines; i++)
sb.Append('\n');
int lastUnhighlighted = startIdx;
foreach (MatchInfo match in GetMatches())
{
// append non-highlighted text between last match and this
for (int i = lastUnhighlighted; i < match.startIndex; i++)
sb.Append(input[i]);
// append the highlighted match
sb.Append(match.htmlColorTag);
for (int i = match.startIndex; i <= match.endIndex && i <= currentEndIdx; i++)
sb.Append(input[i]);
sb.Append(SignatureHighlighter.CLOSE_COLOR);
// update the last unhighlighted start index
lastUnhighlighted = match.endIndex + 1;
int matchEndIdx = match.endIndex;
if (match.matchToEndOfLine)
{
while (input.Length - 1 >= matchEndIdx)
{
matchEndIdx++;
if (IsNewLine(input[matchEndIdx]))
break;
}
}
// check caretIdx to determine inStringOrComment state
if (caretIdx >= match.startIndex && (caretIdx <= (matchEndIdx + 1) || (caretIdx >= input.Length && matchEndIdx >= input.Length - 1)))
caretInStringOrComment = match.isStringOrComment;
}
// Append trailing unhighlighted input
while (lastUnhighlighted <= endIdx)
{
sb.Append(input[lastUnhighlighted]);
lastUnhighlighted++;
}
return sb.ToString();
}
// Match builder, iterates through each Lexer and returns all matches found.
public IEnumerable<MatchInfo> GetMatches()
{
CommittedIndex = currentStartIdx - 1;
Rollback();
while (!EndOfInput)
{
SkipWhitespace();
bool anyMatch = false;
int startIndex = CommittedIndex + 1;
foreach (Lexer lexer in lexers)
{
if (lexer.TryMatchCurrent(this))
{
anyMatch = true;
yield return new MatchInfo
{
startIndex = startIndex,
endIndex = CommittedIndex,
htmlColorTag = lexer.ColorTag,
isStringOrComment = lexer is StringLexer || lexer is CommentLexer,
};
break;
}
else
Rollback();
}
if (!anyMatch)
{
CurrentIndex = CommittedIndex + 1;
Commit();
}
}
}
// Methods used by the Lexers for interfacing with the current parse process
public char PeekNext(int amount = 1)
{
CurrentIndex += amount;
return Current;
}
public void Commit()
{
CommittedIndex = Math.Min(currentEndIdx, CurrentIndex);
}
public void Rollback()
{
CurrentIndex = CommittedIndex + 1;
}
public void RollbackBy(int amount)
{
CurrentIndex = Math.Max(CommittedIndex + 1, CurrentIndex - amount);
}
public bool IsDelimiter(char character, bool orWhitespace = false, bool orLetterOrDigit = false)
{
return delimiters.Contains(character)
|| (orWhitespace && char.IsWhiteSpace(character))
|| (orLetterOrDigit && char.IsLetterOrDigit(character));
}
private void SkipWhitespace()
{
// peek and commit as long as there is whitespace
while (!EndOfInput && char.IsWhiteSpace(Current))
{
Commit();
PeekNext();
}
if (!char.IsWhiteSpace(Current))
Rollback();
}
#region Auto Indenting
// Using the Lexer for indenting as it already has what we need to tokenize strings and comments.
// At the moment this only handles when a single newline or close-delimiter is composed.
// Does not handle copy+paste or any other characters yet.
public string IndentCharacter(string input, ref int caretIndex)
{
int lastCharIndex = caretIndex - 1;
char c = input[lastCharIndex];
// we only want to indent for new lines and close indents
if (!IsNewLine(c) && !IndentCloseChars.Contains(c))
return input;
// perform a light parse up to the caret to determine indent level
currentInput = input;
currentStartIdx = 0;
currentEndIdx = lastCharIndex;
CommittedIndex = -1;
Rollback();
int indent = 0;
while (!EndOfInput)
{
if (CurrentIndex >= lastCharIndex)
{
// reached the caret index
if (indent <= 0)
break;
if (IsNewLine(c))
input = IndentNewLine(input, indent, ref caretIndex);
else // closing indent
input = IndentCloseDelimiter(input, indent, lastCharIndex, ref caretIndex);
break;
}
// Try match strings and comments (Lexer will commit to the end of the match)
if (stringLexer.TryMatchCurrent(this) || commentLexer.TryMatchCurrent(this))
{
PeekNext();
continue;
}
// Still parsing, check indent
if (IndentOpenChars.Contains(Current))
indent++;
else if (IndentCloseChars.Contains(Current))
indent--;
Commit();
PeekNext();
}
return input;
}
private string IndentNewLine(string input, int indent, ref int caretIndex)
{
// continue until the end of line or next non-whitespace character.
// if there's a close-indent on this line, reduce the indent level.
while (CurrentIndex < input.Length - 1)
{
CurrentIndex++;
char next = input[CurrentIndex];
if (IsNewLine(next))
break;
if (char.IsWhiteSpace(next))
continue;
else if (IndentCloseChars.Contains(next))
indent--;
break;
}
if (indent > 0)
{
input = input.Insert(caretIndex, new string('\t', indent));
caretIndex += indent;
}
return input;
}
private string IndentCloseDelimiter(string input, int indent, int lastCharIndex, ref int caretIndex)
{
if (CurrentIndex > lastCharIndex)
{
return input;
}
// lower the indent level by one as we would not have accounted for this closing symbol
indent--;
// go back from the caret to the start of the line, calculate how much indent we need to adjust.
while (CurrentIndex > 0)
{
CurrentIndex--;
char prev = input[CurrentIndex];
if (IsNewLine(prev))
break;
if (!char.IsWhiteSpace(prev))
{
// the line containing the closing bracket has non-whitespace characters before it. do not indent.
indent = 0;
break;
}
else if (prev == '\t')
indent--;
}
if (indent > 0)
{
input = input.Insert(caretIndex, new string('\t', indent));
caretIndex += indent;
}
else if (indent < 0)
{
// line is overly indented
input = input.Remove(lastCharIndex - 1, -indent);
caretIndex += indent;
}
return input;
}
#endregion
}
}

View File

@ -0,0 +1,49 @@
namespace UnityExplorer.CSConsole.Lexers
{
public class CommentLexer : Lexer
{
private enum CommentType
{
Line,
Block
}
// forest green
protected override Color HighlightColor => new(0.34f, 0.65f, 0.29f, 1.0f);
public override bool TryMatchCurrent(LexerBuilder lexer)
{
if (lexer.Current == '/')
{
lexer.PeekNext();
if (lexer.Current == '/')
{
// line comment. read to end of line or file.
do
{
lexer.Commit();
lexer.PeekNext();
}
while (!lexer.EndOrNewLine);
return true;
}
else if (lexer.Current == '*')
{
// block comment, read until end of file or closing '*/'
lexer.PeekNext();
do
{
lexer.PeekNext();
lexer.Commit();
}
while (!lexer.EndOfInput && !(lexer.Current == '/' && lexer.Previous == '*'));
return true;
}
}
return false;
}
}
}

View File

@ -0,0 +1,61 @@
using System.Text;
namespace UnityExplorer.CSConsole.Lexers
{
public class KeywordLexer : Lexer
{
// system blue
protected override Color HighlightColor => new(0.33f, 0.61f, 0.83f, 1.0f);
public static readonly HashSet<string> keywords = new()
{
// reserved keywords
"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue",
"decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally",
"fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock",
"long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", "public",
"readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch",
"this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void",
"volatile", "while",
// contextual keywords
"add", "and", "alias", "ascending", "async", "await", "by", "descending", "dynamic", "equals", "from", "get",
"global", "group", "init", "into", "join", "let", "managed", "nameof", "not", "notnull", "on",
"or", "orderby", "partial", "record", "remove", "select", "set", "unmanaged", "value", "var", "when", "where",
"where", "with", "yield", "nint", "nuint"
};
public override bool TryMatchCurrent(LexerBuilder lexer)
{
char prev = lexer.Previous;
char first = lexer.Current;
// check for keywords
if (lexer.IsDelimiter(prev, true) && char.IsLetter(first))
{
// can be a keyword...
StringBuilder sb = new();
sb.Append(lexer.Current);
while (!lexer.EndOfInput && char.IsLetter(lexer.PeekNext()))
sb.Append(lexer.Current);
// next must be whitespace or delimiter
if (!lexer.EndOfInput && !(char.IsWhiteSpace(lexer.Current) || lexer.IsDelimiter(lexer.Current)))
return false;
if (keywords.Contains(sb.ToString()))
{
if (!lexer.EndOfInput)
lexer.RollbackBy(1);
lexer.Commit();
return true;
}
return false;
}
else
return false;
}
}
}

View File

@ -0,0 +1,14 @@
namespace UnityExplorer.CSConsole.Lexers
{
public abstract class Lexer
{
public virtual IEnumerable<char> Delimiters => Enumerable.Empty<char>();
protected abstract Color HighlightColor { get; }
public string ColorTag => colorTag ?? (colorTag = "<color=#" + HighlightColor.ToHex() + ">");
private string colorTag;
public abstract bool TryMatchCurrent(LexerBuilder lexer);
}
}

View File

@ -0,0 +1,30 @@
namespace UnityExplorer.CSConsole.Lexers
{
public class NumberLexer : Lexer
{
// Maroon
protected override Color HighlightColor => new(0.58f, 0.33f, 0.33f, 1.0f);
private bool IsNumeric(char c) => char.IsNumber(c) || c == '.';
public override bool TryMatchCurrent(LexerBuilder lexer)
{
// previous character must be whitespace or delimiter
if (!lexer.IsDelimiter(lexer.Previous, true))
return false;
if (!IsNumeric(lexer.Current))
return false;
while (!lexer.EndOfInput)
{
lexer.Commit();
if (!IsNumeric(lexer.PeekNext()))
break;
}
return true;
}
}
}

View File

@ -0,0 +1,77 @@
namespace UnityExplorer.CSConsole.Lexers
{
public class StringLexer : Lexer
{
public override IEnumerable<char> Delimiters => new[] { '"', '\'', };
// orange
protected override Color HighlightColor => new(0.79f, 0.52f, 0.32f, 1.0f);
public override bool TryMatchCurrent(LexerBuilder lexer)
{
if (lexer.Current == '"')
{
if (lexer.Previous == '@')
{
// verbatim string, continue until un-escaped quote.
while (!lexer.EndOfInput)
{
lexer.Commit();
if (lexer.PeekNext() == '"')
{
lexer.Commit();
// possibly the end, check for escaped quotes.
// commit the character and flip the escape bool for each quote.
bool escaped = false;
while (lexer.PeekNext() == '"')
{
lexer.Commit();
escaped = !escaped;
}
// if the last quote wasnt escaped, that was the end of the string.
if (!escaped)
break;
}
}
}
else
{
// normal string
// continue until a quote which is not escaped, or end of input
while (!lexer.EndOfInput)
{
lexer.Commit();
lexer.PeekNext();
if ((lexer.Current == '"') && lexer.Previous != '\\')
{
lexer.Commit();
break;
}
}
}
return true;
}
else if (lexer.Current == '\'')
{
// char
while (!lexer.EndOfInput)
{
lexer.Commit();
lexer.PeekNext();
if ((lexer.Current == '\'') && lexer.Previous != '\\')
{
lexer.Commit();
break;
}
}
return true;
}
else
return false;
}
}
}

View File

@ -0,0 +1,38 @@
namespace UnityExplorer.CSConsole.Lexers
{
public class SymbolLexer : Lexer
{
// silver
protected override Color HighlightColor => new(0.6f, 0.6f, 0.6f);
// all symbols are delimiters
public override IEnumerable<char> Delimiters => symbols.Where(it => it != '.'); // '.' is not a delimiter, only a separator.
public static bool IsSymbol(char c) => symbols.Contains(c);
public static readonly HashSet<char> symbols = new()
{
'[', '{', '(', // open
']', '}', ')', // close
'.', ',', ';', ':', '?', '@', // special
// operators
'+', '-', '*', '/', '%', '&', '|', '^', '~', '=', '<', '>', '!',
};
public override bool TryMatchCurrent(LexerBuilder lexer)
{
// previous character must be delimiter, whitespace, or alphanumeric.
if (!lexer.IsDelimiter(lexer.Previous, true, true))
return false;
if (IsSymbol(lexer.Current))
{
lexer.Commit();
return true;
}
return false;
}
}
}

View File

@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Mono.CSharp;
using Mono.CSharp;
using UnityExplorer.Config;
// Thanks to ManlyMarco for this
@ -10,43 +7,65 @@ namespace UnityExplorer.CSConsole
{
public class ScriptEvaluator : Evaluator, IDisposable
{
private static readonly HashSet<string> StdLib = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)
{
"mscorlib", "System.Core", "System", "System.Xml"
};
internal TextWriter _textWriter;
internal static StreamReportPrinter _reportPrinter;
private readonly TextWriter tw;
private static readonly HashSet<string> StdLib = new(StringComparer.InvariantCultureIgnoreCase)
{
"mscorlib",
"System.Core",
"System",
"System.Xml"
};
public ScriptEvaluator(TextWriter tw) : base(BuildContext(tw))
{
this.tw = tw;
_textWriter = tw;
ImportAppdomainAssemblies(ReferenceAssembly);
ImportAppdomainAssemblies();
AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoad;
}
public void Dispose()
{
AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoad;
tw.Dispose();
_textWriter.Dispose();
}
private void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
string name = args.LoadedAssembly.GetName().Name;
if (StdLib.Contains(name))
return;
Reference(args.LoadedAssembly);
}
private void Reference(Assembly asm)
{
string name = asm.GetName().Name;
if (name == "completions") // ignore assemblies generated by mcs' autocomplete.
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(args.LoadedAssembly);
ReferenceAssembly(asm);
}
private static CompilerContext BuildContext(TextWriter tw)
{
var reporter = new StreamReportPrinter(tw);
_reportPrinter = new StreamReportPrinter(tw);
var settings = new CompilerSettings
CompilerSettings settings = new()
{
Version = LanguageVersion.Experimental,
GenerateDebugInfo = false,
@ -56,20 +75,25 @@ namespace UnityExplorer.CSConsole
EnhancedWarnings = false
};
return new CompilerContext(settings, reporter);
return new CompilerContext(settings, _reportPrinter);
}
private static void ImportAppdomainAssemblies(Action<Assembly> import)
private void ImportAppdomainAssemblies()
{
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
string name = assembly.GetName().Name;
if (StdLib.Contains(name))
{
continue;
}
import(assembly);
try
{
Reference(assembly);
}
catch // (Exception ex)
{
//ExplorerCore.LogWarning($"Excepting referencing '{name}': {ex.GetType()}.{ex.Message}");
}
}
}
}

View File

@ -1,57 +1,71 @@
using System;
using HarmonyLib;
using Mono.CSharp;
using UnityExplorer.UI;
using UnityExplorer.UI.Modules;
using UnityExplorer.Inspectors;
using System.Collections;
using System.Text;
using UnityExplorer.UI.Panels;
namespace UnityExplorer.CSConsole
{
public class ScriptInteraction : InteractiveBase
{
public static object CurrentTarget
=> InspectorManager.ActiveInspector?.Target;
public static object[] AllTargets
=> InspectorManager.Inspectors.Select(it => it.Target).ToArray();
public static void Log(object message)
{
ExplorerCore.Log(message);
}
public static void AddUsing(string directive)
{
CSConsolePage.Instance.AddUsing(directive);
}
public static void GetUsing()
{
ExplorerCore.Log(CSConsolePage.Instance.m_evaluator.GetUsing());
}
public static void Reset()
{
CSConsolePage.Instance.ResetConsole();
}
public static object CurrentTarget()
{
return InspectorManager.Instance?.m_activeInspector?.Target;
}
public static object[] AllTargets()
{
int count = InspectorManager.Instance?.m_currentInspectors.Count ?? 0;
object[] ret = new object[count];
for (int i = 0; i < count; i++)
{
ret[i] = InspectorManager.Instance?.m_currentInspectors[i].Target;
}
return ret;
}
=> ExplorerCore.Log(message);
public static void Inspect(object obj)
{
InspectorManager.Instance.Inspect(obj);
}
=> InspectorManager.Inspect(obj);
public static void Inspect(Type type)
=> InspectorManager.Inspect(type);
public static Coroutine Start(IEnumerator ienumerator)
=> RuntimeHelper.StartCoroutine(ienumerator);
public static void Stop(Coroutine coro)
=> RuntimeHelper.StopCoroutine(coro);
public static void Copy(object obj)
=> ClipboardPanel.Copy(obj);
public static object Paste()
=> ClipboardPanel.Current;
public static void GetUsing()
=> Log(Evaluator.GetUsing());
public static void GetVars()
{
InspectorManager.Instance.Inspect(type);
string vars = Evaluator.GetVars()?.Trim();
if (string.IsNullOrEmpty(vars))
ExplorerCore.LogWarning("No variables seem to be defined!");
else
Log(vars);
}
public static void GetClasses()
{
if (AccessTools.Field(typeof(Evaluator), "source_file")
.GetValue(Evaluator) is CompilationSourceFile sourceFile
&& sourceFile.Containers.Any())
{
StringBuilder sb = new();
sb.Append($"There are {sourceFile.Containers.Count} defined classes:");
foreach (TypeDefinition type in sourceFile.Containers.Where(it => it is TypeDefinition))
{
sb.Append($"\n\n{type.MemberName.Name}:");
foreach (MemberCore member in type.Members)
sb.Append($"\n\t- {member.AttributeTargets}: \"{member.MemberName.Name}\" ({member.ModFlags})");
}
Log(sb.ToString());
}
else
ExplorerCore.LogWarning("No classes seem to be defined.");
}
}
}

View File

@ -1,69 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityExplorer.Helpers;
namespace UnityExplorer.CSConsole
{
public struct Suggestion
{
public enum Contexts
{
Namespace,
Keyword,
Other
}
// ~~~~ Instance ~~~~
public readonly string Prefix;
public readonly string Addition;
public readonly Contexts Context;
public string Full => Prefix + Addition;
public Color TextColor => GetTextColor();
public Suggestion(string addition, string prefix, Contexts type)
{
Addition = addition;
Prefix = prefix;
Context = type;
}
private Color GetTextColor()
{
switch (Context)
{
case Contexts.Namespace: return Color.grey;
case Contexts.Keyword: return keywordColor;
default: return Color.white;
}
}
// ~~~~ Static ~~~~
public static HashSet<string> Namespaces => m_namspaces ?? GetNamespaces();
private static HashSet<string> m_namspaces;
public static HashSet<string> Keywords => m_keywords ?? (m_keywords = new HashSet<string>(CSharpLexer.validKeywordMatcher.Keywords));
private static HashSet<string> m_keywords;
private static readonly Color keywordColor = new Color(80f / 255f, 150f / 255f, 215f / 255f);
private static HashSet<string> GetNamespaces()
{
HashSet<string> set = new HashSet<string>(
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(GetTypes)
.Where(x => x.IsPublic && !string.IsNullOrEmpty(x.Namespace))
.Select(x => x.Namespace));
return m_namspaces = set;
IEnumerable<Type> GetTypes(Assembly asm) => asm.TryGetTypes();
}
}
}

View File

@ -0,0 +1,45 @@
using UnityExplorer.CacheObject.Views;
using UnityExplorer.Config;
namespace UnityExplorer.CacheObject
{
public class CacheConfigEntry : CacheObjectBase
{
public CacheConfigEntry(IConfigElement configElement)
{
this.RefConfigElement = configElement;
this.FallbackType = configElement.ElementType;
this.NameLabelText = $"<color=cyan>{configElement.Name}</color>" +
$"\r\n<color=grey><i>{configElement.Description}</i></color>";
this.NameLabelTextRaw = string.Empty;
configElement.OnValueChangedNotify += UpdateValueFromSource;
}
public IConfigElement RefConfigElement;
public override bool ShouldAutoEvaluate => true;
public override bool HasArguments => false;
public override bool CanWrite => true;
public void UpdateValueFromSource()
{
//if (RefConfigElement.BoxedValue.Equals(this.Value))
// return;
SetValueFromSource(RefConfigElement.BoxedValue);
if (this.CellView != null)
this.SetDataToCell(CellView);
}
public override void TrySetUserValue(object value)
{
this.Value = value;
RefConfigElement.BoxedValue = value;
}
protected override bool TryAutoEvaluateIfUnitialized(CacheObjectCell cell) => true;
}
}

View File

@ -0,0 +1,81 @@
using UnityExplorer.Inspectors;
namespace UnityExplorer.CacheObject
{
public class CacheConstructor : CacheMember
{
public ConstructorInfo CtorInfo { get; }
readonly Type typeForStructConstructor;
public override Type DeclaringType => typeForStructConstructor ?? CtorInfo.DeclaringType;
public override bool IsStatic => true;
public override bool ShouldAutoEvaluate => false;
public override bool CanWrite => false;
public CacheConstructor(ConstructorInfo ci)
{
this.CtorInfo = ci;
}
public CacheConstructor(Type typeForStructConstructor)
{
this.typeForStructConstructor = typeForStructConstructor;
}
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
{
Type ctorReturnType;
// if is parameterless struct ctor
if (typeForStructConstructor != null)
{
ctorReturnType = typeForStructConstructor;
this.Owner = inspector;
// eg. Vector3.Vector3()
this.NameLabelText = SignatureHighlighter.Parse(typeForStructConstructor, false);
NameLabelText += $".{NameLabelText}()";
this.NameForFiltering = SignatureHighlighter.RemoveHighlighting(NameLabelText);
this.NameLabelTextRaw = NameForFiltering;
return;
}
else
{
base.SetInspectorOwner(inspector, member);
Arguments = CtorInfo.GetParameters();
ctorReturnType = CtorInfo.DeclaringType;
}
if (ctorReturnType.IsGenericTypeDefinition)
GenericArguments = ctorReturnType.GetGenericArguments();
}
protected override object TryEvaluate()
{
try
{
Type returnType = DeclaringType;
if (returnType.IsGenericTypeDefinition)
returnType = DeclaringType.MakeGenericType(Evaluator.TryParseGenericArguments());
object ret;
if (HasArguments)
ret = Activator.CreateInstance(returnType, Evaluator.TryParseArguments());
else
ret = Activator.CreateInstance(returnType, ArgumentUtility.EmptyArgs);
LastException = null;
return ret;
}
catch (Exception ex)
{
LastException = ex;
return null;
}
}
protected override void TrySetValue(object value) => throw new NotImplementedException("You can't set a constructor");
}
}

View File

@ -0,0 +1,52 @@
using UnityExplorer.Inspectors;
namespace UnityExplorer.CacheObject
{
public class CacheField : CacheMember
{
public FieldInfo FieldInfo { get; internal set; }
public override Type DeclaringType => FieldInfo.DeclaringType;
public override bool IsStatic => FieldInfo.IsStatic;
public override bool CanWrite => m_canWrite ?? (bool)(m_canWrite = !(FieldInfo.IsLiteral && !FieldInfo.IsInitOnly));
private bool? m_canWrite;
public override bool ShouldAutoEvaluate => true;
public CacheField(FieldInfo fi)
{
this.FieldInfo = fi;
}
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
{
base.SetInspectorOwner(inspector, member);
}
protected override object TryEvaluate()
{
try
{
object ret = FieldInfo.GetValue(DeclaringInstance);
LastException = null;
return ret;
}
catch (Exception ex)
{
LastException = ex;
return null;
}
}
protected override void TrySetValue(object value)
{
try
{
FieldInfo.SetValue(DeclaringInstance, value);
}
catch (Exception ex)
{
ExplorerCore.LogWarning(ex);
}
}
}
}

View File

@ -0,0 +1,92 @@
using UnityExplorer.CacheObject.IValues;
using UnityExplorer.CacheObject.Views;
namespace UnityExplorer.CacheObject
{
public class CacheKeyValuePair : CacheObjectBase
{
//public InteractiveList CurrentList { get; set; }
public int DictIndex;
public object DictKey;
public object DisplayedKey;
public bool KeyInputWanted;
public bool InspectWanted;
public string KeyLabelText;
public string KeyInputText;
public string KeyInputTypeText;
public float DesiredKeyWidth;
public float DesiredValueWidth;
public override bool ShouldAutoEvaluate => true;
public override bool HasArguments => false;
public override bool CanWrite => Owner.CanWrite;
public void SetDictOwner(InteractiveDictionary dict, int index)
{
this.Owner = dict;
this.DictIndex = index;
}
public void SetKey(object key)
{
this.DictKey = key;
this.DisplayedKey = key.TryCast();
Type type = DisplayedKey.GetType();
if (ParseUtility.CanParse(type))
{
KeyInputWanted = true;
KeyInputText = ParseUtility.ToStringForInput(DisplayedKey, type);
KeyInputTypeText = SignatureHighlighter.Parse(type, false);
}
else
{
KeyInputWanted = false;
InspectWanted = type != typeof(bool) && !type.IsEnum;
KeyLabelText = ToStringUtility.ToStringWithType(DisplayedKey, type, true);
}
}
public override void SetDataToCell(CacheObjectCell cell)
{
base.SetDataToCell(cell);
CacheKeyValuePairCell kvpCell = cell as CacheKeyValuePairCell;
kvpCell.NameLabel.text = $"{DictIndex}:";
kvpCell.HiddenNameLabel.Text = "";
kvpCell.Image.color = DictIndex % 2 == 0 ? CacheListEntryCell.EvenColor : CacheListEntryCell.OddColor;
if (KeyInputWanted)
{
kvpCell.KeyInputField.UIRoot.SetActive(true);
kvpCell.KeyInputTypeLabel.gameObject.SetActive(true);
kvpCell.KeyLabel.gameObject.SetActive(false);
kvpCell.KeyInspectButton.Component.gameObject.SetActive(false);
kvpCell.KeyInputField.Text = KeyInputText;
kvpCell.KeyInputTypeLabel.text = KeyInputTypeText;
}
else
{
kvpCell.KeyInputField.UIRoot.SetActive(false);
kvpCell.KeyInputTypeLabel.gameObject.SetActive(false);
kvpCell.KeyLabel.gameObject.SetActive(true);
kvpCell.KeyInspectButton.Component.gameObject.SetActive(InspectWanted);
kvpCell.KeyLabel.text = KeyLabelText;
}
}
public override void TrySetUserValue(object value)
{
(Owner as InteractiveDictionary).TrySetValueToKey(DictKey, value, DictIndex);
}
protected override bool TryAutoEvaluateIfUnitialized(CacheObjectCell cell) => true;
}
}

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