diff --git a/src/ExplorerCore.cs b/src/ExplorerCore.cs index b594a28..d40e945 100644 --- a/src/ExplorerCore.cs +++ b/src/ExplorerCore.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Reflection; using UnityEngine; using UnityEngine.SceneManagement; using UnityExplorer.Config; @@ -16,7 +17,7 @@ namespace UnityExplorer public class ExplorerCore { public const string NAME = "UnityExplorer"; - public const string VERSION = "3.1.6"; + public const string VERSION = "3.1.7"; public const string AUTHOR = "Sinai"; public const string GUID = "com.sinai.unityexplorer"; @@ -24,6 +25,22 @@ namespace UnityExplorer public const string EXPLORER_FOLDER = @"Mods\UnityExplorer"; #elif BIE public static string EXPLORER_FOLDER = Path.Combine(BepInEx.Paths.ConfigPath, "UnityExplorer"); +#elif STANDALONE + public static string EXPLORER_FOLDER + { + get + { + if (s_explorerFolder == null) + { + s_explorerFolder = (new Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath; + s_explorerFolder = Uri.UnescapeDataString(s_explorerFolder); + s_explorerFolder = Path.GetDirectoryName(s_explorerFolder); + } + + return s_explorerFolder; + } + } + private static string s_explorerFolder; #endif public static ExplorerCore Instance { get; private set; } @@ -166,6 +183,12 @@ namespace UnityExplorer } } +#if STANDALONE + public static Action OnLogMessage; + public static Action OnLogWarning; + public static Action OnLogError; +#endif + public static void Log(object message, bool unity = false) { DebugConsole.Log(message?.ToString()); @@ -175,8 +198,10 @@ namespace UnityExplorer #if ML MelonLoader.MelonLogger.Log(message?.ToString()); -#else +#elif BIE ExplorerBepInPlugin.Logging?.LogMessage(message?.ToString()); +#elif STANDALONE + OnLogMessage?.Invoke(message?.ToString()); #endif } @@ -189,8 +214,10 @@ namespace UnityExplorer #if ML MelonLoader.MelonLogger.LogWarning(message?.ToString()); -#else - ExplorerBepInPlugin.Logging?.LogWarning(message?.ToString()); +#elif BIE + ExplorerBepInPlugin.Logging?.LogWarning(message?.ToString()); +#elif STANDALONE + OnLogWarning?.Invoke(message?.ToString()); #endif } @@ -203,8 +230,10 @@ namespace UnityExplorer #if ML MelonLoader.MelonLogger.LogError(message?.ToString()); -#else - ExplorerBepInPlugin.Logging?.LogError(message?.ToString()); +#elif BIE + ExplorerBepInPlugin.Logging?.LogError(message?.ToString()); +#elif STANDALONE + OnLogError?.Invoke(message?.ToString()); #endif } diff --git a/src/ExplorerStandalone.cs b/src/ExplorerStandalone.cs new file mode 100644 index 0000000..d55c01c --- /dev/null +++ b/src/ExplorerStandalone.cs @@ -0,0 +1,11 @@ +#if STANDALONE +using HarmonyLib; + +namespace UnityExplorer +{ + public class ExplorerStandalone + { + public static readonly Harmony HarmonyInstance = new Harmony(ExplorerCore.GUID); + } +} +#endif \ No newline at end of file diff --git a/src/Inspectors/InspectorManager.cs b/src/Inspectors/InspectorManager.cs index 2ec0ee3..bf77588 100644 --- a/src/Inspectors/InspectorManager.cs +++ b/src/Inspectors/InspectorManager.cs @@ -38,7 +38,7 @@ namespace UnityExplorer.Inspectors } } - public void Inspect(object obj) + public void Inspect(object obj, CacheObjectBase parentMember = null) { #if CPP obj = obj.Il2CppCast(ReflectionHelpers.GetActualType(obj)); @@ -76,6 +76,9 @@ namespace UnityExplorer.Inspectors else inspector = new InstanceInspector(obj); + if (inspector is ReflectionInspector ri) + ri.ParentMember = parentMember; + m_currentInspectors.Add(inspector); SetInspectorTab(inspector); } diff --git a/src/Inspectors/Reflection/CacheObject/CacheField.cs b/src/Inspectors/Reflection/CacheObject/CacheField.cs index 6f05c95..e21dd51 100644 --- a/src/Inspectors/Reflection/CacheObject/CacheField.cs +++ b/src/Inspectors/Reflection/CacheObject/CacheField.cs @@ -33,6 +33,9 @@ namespace UnityExplorer.Inspectors.Reflection { var fi = MemInfo as FieldInfo; fi.SetValue(fi.IsStatic ? null : DeclaringInstance, IValue.Value); + + if (this.ParentInspector?.ParentMember != null) + this.ParentInspector.ParentMember.SetValue(); } } } diff --git a/src/Inspectors/Reflection/CacheObject/CacheMember.cs b/src/Inspectors/Reflection/CacheObject/CacheMember.cs index f493c40..732ca5e 100644 --- a/src/Inspectors/Reflection/CacheObject/CacheMember.cs +++ b/src/Inspectors/Reflection/CacheObject/CacheMember.cs @@ -19,6 +19,7 @@ namespace UnityExplorer.Inspectors.Reflection public override Type FallbackType { get; } + public ReflectionInspector ParentInspector { get; set; } public MemberInfo MemInfo { get; set; } public Type DeclaringType { get; set; } public object DeclaringInstance { get; set; } diff --git a/src/Inspectors/Reflection/CacheObject/CacheProperty.cs b/src/Inspectors/Reflection/CacheObject/CacheProperty.cs index c058d94..9634b04 100644 --- a/src/Inspectors/Reflection/CacheObject/CacheProperty.cs +++ b/src/Inspectors/Reflection/CacheObject/CacheProperty.cs @@ -63,6 +63,9 @@ namespace UnityExplorer.Inspectors.Reflection var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance; pi.SetValue(target, IValue.Value, ParseArguments()); + + if (this.ParentInspector?.ParentMember != null) + this.ParentInspector.ParentMember.SetValue(); } } } diff --git a/src/Inspectors/Reflection/InteractiveValue/InteractiveValue.cs b/src/Inspectors/Reflection/InteractiveValue/InteractiveValue.cs index 3bcb787..b231822 100644 --- a/src/Inspectors/Reflection/InteractiveValue/InteractiveValue.cs +++ b/src/Inspectors/Reflection/InteractiveValue/InteractiveValue.cs @@ -176,6 +176,10 @@ namespace UnityExplorer.Inspectors.Reflection ConstructSubcontent(); } + internal MethodInfo m_toStringMethod; + internal MethodInfo m_toStringFormatMethod; + internal bool m_gotToStringMethods; + public string GetDefaultLabel(bool updateType = true) { var valueType = Value?.GetType() ?? this.FallbackType; @@ -205,8 +209,33 @@ namespace UnityExplorer.Inspectors.Reflection } else { - var toString = (string)valueType.GetMethod("ToString", new Type[0])?.Invoke(Value, null) - ?? Value.ToString(); + if (!m_gotToStringMethods) + { + m_gotToStringMethods = true; + + m_toStringMethod = valueType.GetMethod("ToString", new Type[0]); + m_toStringFormatMethod = valueType.GetMethod("ToString", new Type[] { typeof(string) }); + + // test format method actually works + try + { + m_toStringFormatMethod.Invoke(Value, new object[] { "F3" }); + } + catch + { + m_toStringFormatMethod = null; + } + } + + string toString; + if (m_toStringFormatMethod != null) + { + toString = (string)m_toStringFormatMethod.Invoke(Value, new object[] { "F3" }); + } + else + { + toString = (string)m_toStringMethod.Invoke(Value, new object[0]); + } var fullnametemp = valueType.ToString(); if (fullnametemp.StartsWith("Il2CppSystem")) @@ -303,7 +332,7 @@ namespace UnityExplorer.Inspectors.Reflection void OnInspectClicked() { if (!Value.IsNullOrDestroyed(false)) - InspectorManager.Instance.Inspect(this.Value); + InspectorManager.Instance.Inspect(this.Value, this.Owner); } m_inspectButton.SetActive(false); diff --git a/src/Inspectors/Reflection/ReflectionInspector.cs b/src/Inspectors/Reflection/ReflectionInspector.cs index d56a1b0..5b9bcf8 100644 --- a/src/Inspectors/Reflection/ReflectionInspector.cs +++ b/src/Inspectors/Reflection/ReflectionInspector.cs @@ -58,6 +58,8 @@ namespace UnityExplorer.Inspectors public override string TabLabel => m_targetTypeShortName; + internal CacheObjectBase ParentMember { get; set; } + internal readonly Type m_targetType; internal readonly string m_targetTypeShortName; @@ -202,6 +204,8 @@ namespace UnityExplorer.Inspectors list.Add(new CacheProperty(pi, target, m_scrollContent)); else list.Add(new CacheField(fi, target, m_scrollContent)); + + list.Last().ParentInspector = this; } catch (Exception e) { diff --git a/src/UI/ForceUnlockCursor.cs b/src/UI/ForceUnlockCursor.cs index 8c98296..5942cbf 100644 --- a/src/UI/ForceUnlockCursor.cs +++ b/src/UI/ForceUnlockCursor.cs @@ -105,8 +105,10 @@ namespace UnityExplorer.UI var harmony = #if ML ExplorerMelonMod.Instance.harmonyInstance; -#else +#elif BIE ExplorerBepInPlugin.HarmonyInstance; +#elif STANDALONE + ExplorerStandalone.HarmonyInstance; #endif System.Reflection.PropertyInfo prop = type.GetProperty(property); diff --git a/src/UnityExplorer.csproj b/src/UnityExplorer.csproj index 48921ac..e0d600b 100644 --- a/src/UnityExplorer.csproj +++ b/src/UnityExplorer.csproj @@ -68,6 +68,24 @@ false true + + v3.5 + ..\Release\UnityExplorer.Standalone.Mono\ + MONO,STANDALONE + UnityExplorer.STANDALONE.Mono + false + false + true + + + v4.7.2 + ..\Release\UnityExplorer.Standalone.Il2Cpp\ + CPP,STANDALONE + UnityExplorer.STANDALONE.IL2CPP + true + false + true + packages\ini-parser.2.5.2\lib\net20\INIFileParser.dll @@ -217,6 +235,7 @@ + diff --git a/src/UnityExplorer.sln b/src/UnityExplorer.sln index 7dca438..21180ec 100644 --- a/src/UnityExplorer.sln +++ b/src/UnityExplorer.sln @@ -11,6 +11,8 @@ Global Release_BIE_Mono|Any CPU = Release_BIE_Mono|Any CPU Release_ML_Cpp|Any CPU = Release_ML_Cpp|Any CPU Release_ML_Mono|Any CPU = Release_ML_Mono|Any CPU + Release_STANDALONE_Cpp|Any CPU = Release_STANDALONE_Cpp|Any CPU + Release_STANDALONE_Mono|Any CPU = Release_STANDALONE_Mono|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_BIE_Cpp|Any CPU.ActiveCfg = Release_BIE_Cpp|Any CPU @@ -21,6 +23,10 @@ Global {B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_ML_Cpp|Any CPU.Build.0 = Release_ML_Cpp|Any CPU {B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_ML_Mono|Any CPU.ActiveCfg = Release_ML_Mono|Any CPU {B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_ML_Mono|Any CPU.Build.0 = Release_ML_Mono|Any CPU + {B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_STANDALONE_Cpp|Any CPU.ActiveCfg = Release_STANDALONE_Cpp|Any CPU + {B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_STANDALONE_Cpp|Any CPU.Build.0 = Release_STANDALONE_Cpp|Any CPU + {B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_STANDALONE_Mono|Any CPU.ActiveCfg = Release_STANDALONE_Mono|Any CPU + {B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}.Release_STANDALONE_Mono|Any CPU.Build.0 = Release_STANDALONE_Mono|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE