diff --git a/lib/UnityEngine.UI.dll b/lib/UnityEngine.UI.dll new file mode 100644 index 0000000..aeee3d8 Binary files /dev/null and b/lib/UnityEngine.UI.dll differ diff --git a/lib/UnityEngine.dll b/lib/UnityEngine.dll new file mode 100644 index 0000000..ce772f8 Binary files /dev/null and b/lib/UnityEngine.dll differ diff --git a/src/CSConsole/CSharpLexer.cs b/src/CSConsole/CSharpLexer.cs index 4197f36..f4c150c 100644 --- a/src/CSConsole/CSharpLexer.cs +++ b/src/CSConsole/CSharpLexer.cs @@ -34,7 +34,7 @@ namespace UnityExplorer.CSConsole public static char indentOpen = '{'; public static char indentClose = '}'; - private static readonly StringBuilder indentBuilder = new StringBuilder(); + private static StringBuilder indentBuilder = new StringBuilder(); public static char[] delimiters = new[] { @@ -153,7 +153,7 @@ namespace UnityExplorer.CSConsole public static string GetIndentForInput(string input, int indent, out int caretPosition) { - indentBuilder.Clear(); + indentBuilder = new StringBuilder(); indent += 1; diff --git a/src/ExplorerBepInPlugin.cs b/src/ExplorerBepInPlugin.cs index 8478a6e..cb0d780 100644 --- a/src/ExplorerBepInPlugin.cs +++ b/src/ExplorerBepInPlugin.cs @@ -61,11 +61,9 @@ namespace UnityExplorer var obj = new GameObject( "ExplorerBehaviour", - new Il2CppSystem.Type[] - { - Il2CppType.Of() - } + new Il2CppSystem.Type[] { Il2CppType.Of() } ); + obj.hideFlags = HideFlags.HideAndDontSave; GameObject.DontDestroyOnLoad(obj); new ExplorerCore(); diff --git a/src/Helpers/ReflectionHelpers.cs b/src/Helpers/ReflectionHelpers.cs index 59229b1..d47920b 100644 --- a/src/Helpers/ReflectionHelpers.cs +++ b/src/Helpers/ReflectionHelpers.cs @@ -77,7 +77,11 @@ namespace UnityExplorer.Helpers // check if type is injected IntPtr classPtr = il2cpp_object_get_class(ilObject.Pointer); if (RuntimeSpecificsStore.IsInjected(classPtr)) - return GetTypeByName(il2cppType.FullName); + { + var typeByName = GetTypeByName(il2cppType.FullName); + if (typeByName != null) + return typeByName; + } // this should be fine for all other il2cpp objects var getType = GetMonoType(il2cppType); @@ -252,7 +256,13 @@ namespace UnityExplorer.Helpers public static string ExceptionToString(Exception e, bool innerMost = false) { while (innerMost && e.InnerException != null) + { +#if CPP + if (e.InnerException is System.Runtime.CompilerServices.RuntimeWrappedException runtimeEx) + break; +#endif e = e.InnerException; + } return e.GetType() + ", " + e.Message; } diff --git a/src/Inspectors/Reflection/CacheObject/CacheEnumerated.cs b/src/Inspectors/Reflection/CacheObject/CacheEnumerated.cs index 94224dc..cefb230 100644 --- a/src/Inspectors/Reflection/CacheObject/CacheEnumerated.cs +++ b/src/Inspectors/Reflection/CacheObject/CacheEnumerated.cs @@ -12,7 +12,7 @@ namespace UnityExplorer.Inspectors.Reflection public class CacheEnumerated : CacheObjectBase { public override Type FallbackType => ParentEnumeration.m_baseEntryType; - public override bool CanWrite => RefIList != null && ParentEnumeration.OwnerCacheObject.CanWrite; + public override bool CanWrite => RefIList != null && ParentEnumeration.Owner.CanWrite; public int Index { get; set; } public IList RefIList { get; set; } @@ -29,7 +29,7 @@ namespace UnityExplorer.Inspectors.Reflection public override void CreateIValue(object value, Type fallbackType) { IValue = InteractiveValue.Create(value, fallbackType); - IValue.OwnerCacheObject = this; + IValue.Owner = this; } public override void SetValue() @@ -37,7 +37,7 @@ namespace UnityExplorer.Inspectors.Reflection RefIList[Index] = IValue.Value; ParentEnumeration.Value = RefIList; - ParentEnumeration.OwnerCacheObject.SetValue(); + ParentEnumeration.Owner.SetValue(); } internal override void ConstructUI() diff --git a/src/Inspectors/Reflection/CacheObject/CacheMember.cs b/src/Inspectors/Reflection/CacheObject/CacheMember.cs index 999db90..c698f69 100644 --- a/src/Inspectors/Reflection/CacheObject/CacheMember.cs +++ b/src/Inspectors/Reflection/CacheObject/CacheMember.cs @@ -48,6 +48,10 @@ namespace UnityExplorer.Inspectors.Reflection MemInfo = memberInfo; DeclaringType = memberInfo.DeclaringType; DeclaringInstance = declaringInstance; +#if CPP + if (DeclaringInstance != null) + DeclaringInstance = DeclaringInstance.Il2CppCast(DeclaringType); +#endif } public static bool CanProcessArgs(ParameterInfo[] parameters) @@ -70,7 +74,7 @@ namespace UnityExplorer.Inspectors.Reflection public override void CreateIValue(object value, Type fallbackType) { IValue = InteractiveValue.Create(value, fallbackType); - IValue.OwnerCacheObject = this; + IValue.Owner = this; IValue.m_mainContentParent = this.m_rightGroup; IValue.m_subContentParent = this.m_subContent; } @@ -384,7 +388,7 @@ namespace UnityExplorer.Inspectors.Reflection argInputLayout.minWidth = 20; argInputLayout.minHeight = 25; argInputLayout.flexibleHeight = 0; - argInputLayout.layoutPriority = 2; + //argInputLayout.layoutPriority = 2; var argInput = argInputObj.GetComponent(); argInput.onValueChanged.AddListener((string val) => { m_argumentInput[i] = val; }); diff --git a/src/Inspectors/Reflection/CacheObject/CacheObjectBase.cs b/src/Inspectors/Reflection/CacheObject/CacheObjectBase.cs index 871d61f..69de94e 100644 --- a/src/Inspectors/Reflection/CacheObject/CacheObjectBase.cs +++ b/src/Inspectors/Reflection/CacheObject/CacheObjectBase.cs @@ -37,7 +37,8 @@ namespace UnityExplorer.Inspectors.Reflection public virtual void Disable() { - m_mainContent?.SetActive(false); + if (m_mainContent) + m_mainContent.SetActive(false); } public void Destroy() diff --git a/src/Inspectors/Reflection/CacheObject/CachePaired.cs b/src/Inspectors/Reflection/CacheObject/CachePaired.cs index 2706eee..080b616 100644 --- a/src/Inspectors/Reflection/CacheObject/CachePaired.cs +++ b/src/Inspectors/Reflection/CacheObject/CachePaired.cs @@ -41,7 +41,7 @@ namespace UnityExplorer.Inspectors.Reflection public override void CreateIValue(object value, Type fallbackType) { IValue = InteractiveValue.Create(value, fallbackType); - IValue.OwnerCacheObject = this; + IValue.Owner = this; } #region UI CONSTRUCTION diff --git a/src/Inspectors/Reflection/CacheObject/CacheProperty.cs b/src/Inspectors/Reflection/CacheObject/CacheProperty.cs index 2a7991e..93fdff4 100644 --- a/src/Inspectors/Reflection/CacheObject/CacheProperty.cs +++ b/src/Inspectors/Reflection/CacheObject/CacheProperty.cs @@ -43,7 +43,16 @@ namespace UnityExplorer.Inspectors.Reflection } else { - // todo write-only properties? + if (FallbackType == typeof(string)) + { + IValue.Value = ""; + } + else if (FallbackType.IsPrimitive) + { + IValue.Value = Activator.CreateInstance(FallbackType); + } + m_evaluated = true; + ReflectionException = null; } } diff --git a/src/Inspectors/Reflection/InteractiveValue/InteractiveBool.cs b/src/Inspectors/Reflection/InteractiveValue/InteractiveBool.cs index e225941..c4df3b0 100644 --- a/src/Inspectors/Reflection/InteractiveValue/InteractiveBool.cs +++ b/src/Inspectors/Reflection/InteractiveValue/InteractiveBool.cs @@ -18,61 +18,96 @@ namespace UnityExplorer.Inspectors.Reflection public override bool WantInspectBtn => false; internal Toggle m_toggle; + internal Button m_applyBtn; public override void OnValueUpdated() { base.OnValueUpdated(); + } - if (!Value.IsNullOrDestroyed()) + public override void RefreshUIForValue() + { + GetDefaultLabel(); + + if (Owner.HasEvaluated) { - if (OwnerCacheObject.CanWrite) + var val = (bool)Value; + + if (Owner.CanWrite) { if (!m_toggle.gameObject.activeSelf) m_toggle.gameObject.SetActive(true); - var val = (bool)Value; - if (m_toggle.isOn != val) + if (!m_applyBtn.gameObject.activeSelf) + m_applyBtn.gameObject.SetActive(true); + + if (val != m_toggle.isOn) m_toggle.isOn = val; } - RefreshUIElements(); + var color = val + ? "6bc981" // on + : "c96b6b"; // off + + m_baseLabel.text = $"{val}"; + } + else + { + m_baseLabel.text = DefaultLabel; } } - internal void RefreshUIElements() + public override void OnException(CacheMember member) { - if (m_baseLabel) - { - var val = (bool)Value; - var color = val - ? "00FF00" // on - : "FF0000"; // off + base.OnException(member); - m_baseLabel.text = $"{val} ({m_richValueType})"; + if (Owner.CanWrite) + { + if (m_toggle.gameObject.activeSelf) + m_toggle.gameObject.SetActive(false); + + if (m_applyBtn.gameObject.activeSelf) + m_applyBtn.gameObject.SetActive(false); } } internal void OnToggleValueChanged(bool val) { Value = val; - OwnerCacheObject.SetValue(); - RefreshUIElements(); + RefreshUIForValue(); } public override void ConstructUI(GameObject parent, GameObject subGroup) { base.ConstructUI(parent, subGroup); - if (OwnerCacheObject.CanWrite) + var baseLayout = m_baseLabel.gameObject.GetComponent(); + baseLayout.flexibleWidth = 0; + baseLayout.minWidth = 50; + + if (Owner.CanWrite) { var toggleObj = UIFactory.CreateToggle(m_valueContent, out m_toggle, out _, new Color(0.1f, 0.1f, 0.1f)); - toggleObj.SetActive(false); var toggleLayout = toggleObj.AddComponent(); toggleLayout.minWidth = 24; m_toggle.onValueChanged.AddListener(OnToggleValueChanged); m_baseLabel.transform.SetAsLastSibling(); + + var applyBtnObj = UIFactory.CreateButton(m_valueContent, new Color(0.2f, 0.2f, 0.2f)); + var applyLayout = applyBtnObj.AddComponent(); + applyLayout.minWidth = 50; + applyLayout.minHeight = 25; + applyLayout.flexibleWidth = 0; + m_applyBtn = applyBtnObj.GetComponent