mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-16 14:17:51 +08:00
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
This commit is contained in:
parent
a9fbea7c96
commit
2107df70ad
29
src/Core/CSharp/DummyBehaviour.cs
Normal file
29
src/Core/CSharp/DummyBehaviour.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#if MONO
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace UnityExplorer.Core.CSharp
|
||||||
|
{
|
||||||
|
public class DummyBehaviour : MonoBehaviour
|
||||||
|
{
|
||||||
|
public static DummyBehaviour Instance;
|
||||||
|
|
||||||
|
public static void Setup()
|
||||||
|
{
|
||||||
|
var obj = new GameObject("Explorer_DummyBehaviour");
|
||||||
|
DontDestroyOnLoad(obj);
|
||||||
|
obj.hideFlags |= HideFlags.HideAndDontSave;
|
||||||
|
|
||||||
|
obj.AddComponent<DummyBehaviour>();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Awake()
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -15,11 +15,12 @@ namespace UnityExplorer.Core.CSharp
|
|||||||
"mscorlib", "System.Core", "System", "System.Xml"
|
"mscorlib", "System.Core", "System", "System.Xml"
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly TextWriter tw;
|
internal static TextWriter _textWriter;
|
||||||
|
internal static StreamReportPrinter _reportPrinter;
|
||||||
|
|
||||||
public ScriptEvaluator(TextWriter tw) : base(BuildContext(tw))
|
public ScriptEvaluator(TextWriter tw) : base(BuildContext(tw))
|
||||||
{
|
{
|
||||||
this.tw = tw;
|
_textWriter = tw;
|
||||||
|
|
||||||
ImportAppdomainAssemblies(ReferenceAssembly);
|
ImportAppdomainAssemblies(ReferenceAssembly);
|
||||||
AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoad;
|
AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoad;
|
||||||
@ -28,23 +29,22 @@ namespace UnityExplorer.Core.CSharp
|
|||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoad;
|
AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoad;
|
||||||
tw.Dispose();
|
_textWriter.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
|
private void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
|
||||||
{
|
{
|
||||||
string name = args.LoadedAssembly.GetName().Name;
|
string name = args.LoadedAssembly.GetName().Name;
|
||||||
|
|
||||||
if (StdLib.Contains(name))
|
if (StdLib.Contains(name))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
ReferenceAssembly(args.LoadedAssembly);
|
ReferenceAssembly(args.LoadedAssembly);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CompilerContext BuildContext(TextWriter tw)
|
private static CompilerContext BuildContext(TextWriter tw)
|
||||||
{
|
{
|
||||||
var reporter = new StreamReportPrinter(tw);
|
_reportPrinter = new StreamReportPrinter(tw);
|
||||||
|
|
||||||
var settings = new CompilerSettings
|
var settings = new CompilerSettings
|
||||||
{
|
{
|
||||||
@ -56,7 +56,7 @@ namespace UnityExplorer.Core.CSharp
|
|||||||
EnhancedWarnings = false
|
EnhancedWarnings = false
|
||||||
};
|
};
|
||||||
|
|
||||||
return new CompilerContext(settings, reporter);
|
return new CompilerContext(settings, _reportPrinter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ImportAppdomainAssemblies(Action<Assembly> import)
|
private static void ImportAppdomainAssemblies(Action<Assembly> import)
|
||||||
|
@ -4,6 +4,11 @@ using UnityExplorer.UI;
|
|||||||
using UnityExplorer.UI.Main;
|
using UnityExplorer.UI.Main;
|
||||||
using UnityExplorer.Core.Inspectors;
|
using UnityExplorer.Core.Inspectors;
|
||||||
using UnityExplorer.UI.Main.CSConsole;
|
using UnityExplorer.UI.Main.CSConsole;
|
||||||
|
using System.Collections;
|
||||||
|
using UnityEngine;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityExplorer.Core.Runtime;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.CSharp
|
namespace UnityExplorer.Core.CSharp
|
||||||
{
|
{
|
||||||
@ -14,6 +19,11 @@ namespace UnityExplorer.Core.CSharp
|
|||||||
ExplorerCore.Log(message);
|
ExplorerCore.Log(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void StartCoroutine(IEnumerator ienumerator)
|
||||||
|
{
|
||||||
|
RuntimeProvider.Instance.StartConsoleCoroutine(ienumerator);
|
||||||
|
}
|
||||||
|
|
||||||
public static void AddUsing(string directive)
|
public static void AddUsing(string directive)
|
||||||
{
|
{
|
||||||
CSharpConsole.Instance.AddUsing(directive);
|
CSharpConsole.Instance.AddUsing(directive);
|
||||||
@ -21,7 +31,7 @@ namespace UnityExplorer.Core.CSharp
|
|||||||
|
|
||||||
public static void GetUsing()
|
public static void GetUsing()
|
||||||
{
|
{
|
||||||
ExplorerCore.Log(CSharpConsole.Instance.m_evaluator.GetUsing());
|
ExplorerCore.Log(CSharpConsole.Instance.Evaluator.GetUsing());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Reset()
|
public static void Reset()
|
||||||
|
156
src/Core/Runtime/Il2Cpp/Il2CppCoroutine.cs
Normal file
156
src/Core/Runtime/Il2Cpp/Il2CppCoroutine.cs
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
#if CPP
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnhollowerBaseLib;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
// CREDIT HerpDerpenstine
|
||||||
|
// https://github.com/LavaGang/MelonLoader/blob/master/MelonLoader.Support.Il2Cpp/MelonCoroutines.cs
|
||||||
|
|
||||||
|
namespace UnityExplorer.Core.Runtime.Il2Cpp
|
||||||
|
{
|
||||||
|
public static class Il2CppCoroutine
|
||||||
|
{
|
||||||
|
private struct CoroTuple
|
||||||
|
{
|
||||||
|
public object WaitCondition;
|
||||||
|
public IEnumerator Coroutine;
|
||||||
|
}
|
||||||
|
private static readonly List<CoroTuple> ourCoroutinesStore = new List<CoroTuple>();
|
||||||
|
private static readonly List<IEnumerator> ourNextFrameCoroutines = new List<IEnumerator>();
|
||||||
|
private static readonly List<IEnumerator> ourWaitForFixedUpdateCoroutines = new List<IEnumerator>();
|
||||||
|
private static readonly List<IEnumerator> ourWaitForEndOfFrameCoroutines = new List<IEnumerator>();
|
||||||
|
|
||||||
|
private static readonly List<IEnumerator> tempList = new List<IEnumerator>();
|
||||||
|
|
||||||
|
internal static object Start(IEnumerator routine)
|
||||||
|
{
|
||||||
|
if (routine != null) ProcessNextOfCoroutine(routine);
|
||||||
|
return routine;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void Stop(IEnumerator enumerator)
|
||||||
|
{
|
||||||
|
if (ourNextFrameCoroutines.Contains(enumerator)) // the coroutine is running itself
|
||||||
|
ourNextFrameCoroutines.Remove(enumerator);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int coroTupleIndex = ourCoroutinesStore.FindIndex(c => c.Coroutine == enumerator);
|
||||||
|
if (coroTupleIndex != -1) // the coroutine is waiting for a subroutine
|
||||||
|
{
|
||||||
|
object waitCondition = ourCoroutinesStore[coroTupleIndex].WaitCondition;
|
||||||
|
if (waitCondition is IEnumerator waitEnumerator)
|
||||||
|
Stop(waitEnumerator);
|
||||||
|
|
||||||
|
ourCoroutinesStore.RemoveAt(coroTupleIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ProcessCoroList(List<IEnumerator> target)
|
||||||
|
{
|
||||||
|
if (target.Count == 0) return;
|
||||||
|
|
||||||
|
// use a temp list to make sure waits made during processing are not handled by same processing invocation
|
||||||
|
// additionally, a temp list reduces allocations compared to an array
|
||||||
|
tempList.AddRange(target);
|
||||||
|
target.Clear();
|
||||||
|
foreach (var enumerator in tempList) ProcessNextOfCoroutine(enumerator);
|
||||||
|
tempList.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void Process()
|
||||||
|
{
|
||||||
|
for (var i = ourCoroutinesStore.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var tuple = ourCoroutinesStore[i];
|
||||||
|
if (tuple.WaitCondition is WaitForSeconds waitForSeconds)
|
||||||
|
{
|
||||||
|
if ((waitForSeconds.m_Seconds -= Time.deltaTime) <= 0)
|
||||||
|
{
|
||||||
|
ourCoroutinesStore.RemoveAt(i);
|
||||||
|
ProcessNextOfCoroutine(tuple.Coroutine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessCoroList(ourNextFrameCoroutines);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void ProcessWaitForFixedUpdate() => ProcessCoroList(ourWaitForFixedUpdateCoroutines);
|
||||||
|
|
||||||
|
internal static void ProcessWaitForEndOfFrame() => ProcessCoroList(ourWaitForEndOfFrameCoroutines);
|
||||||
|
|
||||||
|
private static void ProcessNextOfCoroutine(IEnumerator enumerator)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!enumerator.MoveNext()) // Run the next step of the coroutine. If it's done, restore the parent routine
|
||||||
|
{
|
||||||
|
var indices = ourCoroutinesStore.Select((it, idx) => (idx, it)).Where(it => it.it.WaitCondition == enumerator).Select(it => it.idx).ToList();
|
||||||
|
for (var i = indices.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var index = indices[i];
|
||||||
|
ourNextFrameCoroutines.Add(ourCoroutinesStore[index].Coroutine);
|
||||||
|
ourCoroutinesStore.RemoveAt(index);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
ExplorerCore.LogError(e.ToString());
|
||||||
|
Stop(FindOriginalCoro(enumerator)); // We want the entire coroutine hierachy to stop when an error happen
|
||||||
|
}
|
||||||
|
|
||||||
|
var next = enumerator.Current;
|
||||||
|
switch (next)
|
||||||
|
{
|
||||||
|
case null:
|
||||||
|
ourNextFrameCoroutines.Add(enumerator);
|
||||||
|
return;
|
||||||
|
case WaitForFixedUpdate _:
|
||||||
|
ourWaitForFixedUpdateCoroutines.Add(enumerator);
|
||||||
|
return;
|
||||||
|
case WaitForEndOfFrame _:
|
||||||
|
ourWaitForEndOfFrameCoroutines.Add(enumerator);
|
||||||
|
return;
|
||||||
|
case WaitForSeconds _:
|
||||||
|
break; // do nothing, this one is supported in Process
|
||||||
|
case Il2CppObjectBase il2CppObjectBase:
|
||||||
|
var nextAsEnumerator = il2CppObjectBase.TryCast<Il2CppSystem.Collections.IEnumerator>();
|
||||||
|
if (nextAsEnumerator != null) // il2cpp IEnumerator also handles CustomYieldInstruction
|
||||||
|
next = new Il2CppEnumeratorWrapper(nextAsEnumerator);
|
||||||
|
else
|
||||||
|
ExplorerCore.LogWarning($"Unknown coroutine yield object of type {il2CppObjectBase} for coroutine {enumerator}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ourCoroutinesStore.Add(new CoroTuple { WaitCondition = next, Coroutine = enumerator });
|
||||||
|
|
||||||
|
if (next is IEnumerator nextCoro)
|
||||||
|
ProcessNextOfCoroutine(nextCoro);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerator FindOriginalCoro(IEnumerator enumerator)
|
||||||
|
{
|
||||||
|
int index = ourCoroutinesStore.FindIndex(ct => ct.WaitCondition == enumerator);
|
||||||
|
if (index == -1)
|
||||||
|
return enumerator;
|
||||||
|
return FindOriginalCoro(ourCoroutinesStore[index].Coroutine);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Il2CppEnumeratorWrapper : IEnumerator
|
||||||
|
{
|
||||||
|
private readonly Il2CppSystem.Collections.IEnumerator il2cppEnumerator;
|
||||||
|
|
||||||
|
public Il2CppEnumeratorWrapper(Il2CppSystem.Collections.IEnumerator il2CppEnumerator) => il2cppEnumerator = il2CppEnumerator;
|
||||||
|
public bool MoveNext() => il2cppEnumerator.MoveNext();
|
||||||
|
public void Reset() => il2cppEnumerator.Reset();
|
||||||
|
public object Current => il2cppEnumerator.Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -10,6 +10,7 @@ using UnhollowerRuntimeLib;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Runtime.Il2Cpp
|
namespace UnityExplorer.Core.Runtime.Il2Cpp
|
||||||
{
|
{
|
||||||
@ -41,6 +42,11 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void StartConsoleCoroutine(IEnumerator routine)
|
||||||
|
{
|
||||||
|
Il2CppCoroutine.Start(routine);
|
||||||
|
}
|
||||||
|
|
||||||
internal delegate IntPtr d_LayerToName(int layer);
|
internal delegate IntPtr d_LayerToName(int layer);
|
||||||
|
|
||||||
public override string LayerToName(int layer)
|
public override string LayerToName(int layer)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#if MONO
|
#if MONO
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@ -7,6 +8,7 @@ using System.Text;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
using UnityExplorer.Core;
|
using UnityExplorer.Core;
|
||||||
|
using UnityExplorer.Core.CSharp;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Runtime.Mono
|
namespace UnityExplorer.Core.Runtime.Mono
|
||||||
{
|
{
|
||||||
@ -25,6 +27,11 @@ namespace UnityExplorer.Core.Runtime.Mono
|
|||||||
//SceneManager.activeSceneChanged += ExplorerCore.Instance.OnSceneLoaded2;
|
//SceneManager.activeSceneChanged += ExplorerCore.Instance.OnSceneLoaded2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void StartConsoleCoroutine(IEnumerator routine)
|
||||||
|
{
|
||||||
|
DummyBehaviour.Instance.StartCoroutine(routine);
|
||||||
|
}
|
||||||
|
|
||||||
public override string LayerToName(int layer)
|
public override string LayerToName(int layer)
|
||||||
=> LayerMask.LayerToName(layer);
|
=> LayerMask.LayerToName(layer);
|
||||||
|
|
||||||
@ -50,4 +57,12 @@ namespace UnityExplorer.Core.Runtime.Mono
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class MonoExtensions
|
||||||
|
{
|
||||||
|
public static void Clear(this StringBuilder sb)
|
||||||
|
{
|
||||||
|
sb.Remove(0, sb.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -36,6 +37,8 @@ namespace UnityExplorer.Core.Runtime
|
|||||||
|
|
||||||
public abstract void SetupEvents();
|
public abstract void SetupEvents();
|
||||||
|
|
||||||
|
public abstract void StartConsoleCoroutine(IEnumerator routine);
|
||||||
|
|
||||||
// Unity API handlers
|
// Unity API handlers
|
||||||
|
|
||||||
public abstract string LayerToName(int layer);
|
public abstract string LayerToName(int layer);
|
||||||
|
@ -205,7 +205,7 @@ namespace UnityExplorer.UI.Main.CSConsole
|
|||||||
{
|
{
|
||||||
// Credit ManylMarco
|
// Credit ManylMarco
|
||||||
CSharpConsole.AutoCompletes.Clear();
|
CSharpConsole.AutoCompletes.Clear();
|
||||||
string[] completions = CSharpConsole.Instance.m_evaluator.GetCompletions(input, out string prefix);
|
string[] completions = CSharpConsole.Instance.Evaluator.GetCompletions(input, out string prefix);
|
||||||
if (completions != null)
|
if (completions != null)
|
||||||
{
|
{
|
||||||
if (prefix == null)
|
if (prefix == null)
|
||||||
|
@ -53,15 +53,10 @@ namespace UnityExplorer.UI.Main.CSConsole
|
|||||||
"else", "equals", "false", "finally", "float", "for", "foreach", "from", "global", "goto", "group",
|
"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",
|
"if", "in", "int", "into", "is", "join", "let", "lock", "long", "new", "null", "object", "on", "orderby", "out",
|
||||||
"ref", "remove", "return", "sbyte", "select", "short", "sizeof", "stackalloc", "string",
|
"ref", "remove", "return", "sbyte", "select", "short", "sizeof", "stackalloc", "string",
|
||||||
"switch", "throw", "true", "try", "typeof", "uint", "ulong", "ushort", "var", "where", "while", "yield" }
|
"switch", "throw", "true", "try", "typeof", "uint", "ulong", "ushort", "var", "where", "while", "yield",
|
||||||
};
|
"abstract", "async", "base", "class", "delegate", "enum", "explicit", "extern", "fixed", "get",
|
||||||
|
|
||||||
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",
|
"implicit", "interface", "internal", "namespace", "operator", "override", "params", "private", "protected", "public",
|
||||||
"using", "partial", "readonly", "sealed", "set", "static", "struct", "this", "unchecked", "unsafe", "value", "virtual", "volatile", "void" }
|
"using", "partial", "readonly", "sealed", "set", "static", "struct", "this", "unchecked", "unsafe", "value", "virtual", "volatile", "void"}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ~~~~~~~ ctor ~~~~~~~
|
// ~~~~~~~ ctor ~~~~~~~
|
||||||
@ -78,7 +73,6 @@ namespace UnityExplorer.UI.Main.CSConsole
|
|||||||
numberMatcher,
|
numberMatcher,
|
||||||
stringMatcher,
|
stringMatcher,
|
||||||
validKeywordMatcher,
|
validKeywordMatcher,
|
||||||
invalidKeywordMatcher,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (Matcher lexer in matchers)
|
foreach (Matcher lexer in matchers)
|
||||||
|
@ -12,6 +12,9 @@ using UnityEngine.UI;
|
|||||||
using UnityExplorer.UI.Reusable;
|
using UnityExplorer.UI.Reusable;
|
||||||
using UnityExplorer.UI.Main.CSConsole;
|
using UnityExplorer.UI.Main.CSConsole;
|
||||||
using UnityExplorer.Core;
|
using UnityExplorer.Core;
|
||||||
|
#if CPP
|
||||||
|
using UnityExplorer.Core.Runtime.Il2Cpp;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Main.CSConsole
|
namespace UnityExplorer.UI.Main.CSConsole
|
||||||
{
|
{
|
||||||
@ -21,8 +24,8 @@ namespace UnityExplorer.UI.Main.CSConsole
|
|||||||
|
|
||||||
public static CSharpConsole Instance { get; private set; }
|
public static CSharpConsole Instance { get; private set; }
|
||||||
|
|
||||||
//public UI.CSConsole.CSharpConsole m_codeEditor;
|
public ScriptEvaluator Evaluator;
|
||||||
public ScriptEvaluator m_evaluator;
|
internal StringBuilder m_evalLogBuilder;
|
||||||
|
|
||||||
public static List<string> UsingDirectives;
|
public static List<string> UsingDirectives;
|
||||||
|
|
||||||
@ -49,11 +52,13 @@ namespace UnityExplorer.UI.Main.CSConsole
|
|||||||
InitConsole();
|
InitConsole();
|
||||||
|
|
||||||
AutoCompleter.Init();
|
AutoCompleter.Init();
|
||||||
|
#if MONO
|
||||||
|
DummyBehaviour.Setup();
|
||||||
|
#endif
|
||||||
|
|
||||||
ResetConsole();
|
ResetConsole();
|
||||||
|
|
||||||
// Make sure compiler is supported on this platform
|
// Make sure compiler is supported on this platform
|
||||||
m_evaluator.Compile("");
|
Evaluator.Compile("");
|
||||||
|
|
||||||
foreach (string use in DefaultUsing)
|
foreach (string use in DefaultUsing)
|
||||||
AddUsing(use);
|
AddUsing(use);
|
||||||
@ -74,10 +79,27 @@ namespace UnityExplorer.UI.Main.CSConsole
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResetConsole()
|
||||||
|
{
|
||||||
|
if (Evaluator != null)
|
||||||
|
Evaluator.Dispose();
|
||||||
|
|
||||||
|
m_evalLogBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
Evaluator = new ScriptEvaluator(new StringWriter(m_evalLogBuilder)) { InteractiveBaseClass = typeof(ScriptInteraction) };
|
||||||
|
|
||||||
|
UsingDirectives = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
UpdateConsole();
|
UpdateConsole();
|
||||||
|
|
||||||
AutoCompleter.Update();
|
AutoCompleter.Update();
|
||||||
|
|
||||||
|
#if CPP
|
||||||
|
Il2CppCoroutine.Process();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddUsing(string asm)
|
public void AddUsing(string asm)
|
||||||
@ -89,40 +111,34 @@ namespace UnityExplorer.UI.Main.CSConsole
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Evaluate(string code, bool suppressWarning = false)
|
public void Evaluate(string code, bool supressLog = false)
|
||||||
{
|
|
||||||
m_evaluator.Compile(code, out Mono.CSharp.CompiledMethod compiled);
|
|
||||||
|
|
||||||
if (compiled == null)
|
|
||||||
{
|
|
||||||
if (!suppressWarning)
|
|
||||||
ExplorerCore.LogWarning("Unable to compile the code!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
object ret = VoidType.Value;
|
Evaluator.Run(code);
|
||||||
compiled.Invoke(ref ret);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
if (!suppressWarning)
|
|
||||||
ExplorerCore.LogWarning($"Exception executing code: {e.GetType()}, {e.Message}\r\n{e.StackTrace}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResetConsole()
|
string output = ScriptEvaluator._textWriter.ToString();
|
||||||
{
|
var outputSplit = output.Split('\n');
|
||||||
if (m_evaluator != null)
|
if (outputSplit.Length >= 2)
|
||||||
{
|
output = outputSplit[outputSplit.Length - 2];
|
||||||
m_evaluator.Dispose();
|
m_evalLogBuilder.Clear();
|
||||||
|
|
||||||
|
if (ScriptEvaluator._reportPrinter.ErrorsCount > 0)
|
||||||
|
throw new FormatException($"Unable to compile the code. Evaluator's last output was:\r\n{output}");
|
||||||
|
|
||||||
|
if (!supressLog)
|
||||||
|
ExplorerCore.Log("Code executed successfully.");
|
||||||
|
}
|
||||||
|
catch (FormatException fex)
|
||||||
|
{
|
||||||
|
if (!supressLog)
|
||||||
|
ExplorerCore.LogWarning(fex.Message);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (!supressLog)
|
||||||
|
ExplorerCore.LogWarning(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_evaluator = new ScriptEvaluator(new StringWriter(new StringBuilder())) { InteractiveBaseClass = typeof(ScriptInteraction) };
|
|
||||||
|
|
||||||
UsingDirectives = new List<string>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
@ -160,6 +176,8 @@ The following helper methods are available:
|
|||||||
|
|
||||||
* <color=#add490>Log(""message"")</color> logs a message to the debug console
|
* <color=#add490>Log(""message"")</color> logs a message to the debug console
|
||||||
|
|
||||||
|
* <color=#add490>StartCoroutine(IEnumerator routine)</color> start the IEnumerator as a UnityEngine.Coroutine
|
||||||
|
|
||||||
* <color=#add490>CurrentTarget()</color> returns the currently inspected target on the Home page
|
* <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>AllTargets()</color> returns an object[] array containing all inspected instances
|
||||||
@ -447,7 +465,7 @@ The following helper methods are available:
|
|||||||
mainGroup.childForceExpandHeight = true;
|
mainGroup.childForceExpandHeight = true;
|
||||||
mainGroup.childForceExpandWidth = true;
|
mainGroup.childForceExpandWidth = true;
|
||||||
|
|
||||||
#region TOP BAR
|
#region TOP BAR
|
||||||
|
|
||||||
// Main group object
|
// Main group object
|
||||||
|
|
||||||
@ -523,9 +541,9 @@ The following helper methods are available:
|
|||||||
autoIndentLayout.flexibleWidth = 0;
|
autoIndentLayout.flexibleWidth = 0;
|
||||||
autoIndentLayout.minHeight = 25;
|
autoIndentLayout.minHeight = 25;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region CONSOLE INPUT
|
#region CONSOLE INPUT
|
||||||
|
|
||||||
int fontSize = 16;
|
int fontSize = 16;
|
||||||
|
|
||||||
@ -554,9 +572,9 @@ The following helper methods are available:
|
|||||||
highlightTextInput.supportRichText = true;
|
highlightTextInput.supportRichText = true;
|
||||||
highlightTextInput.fontSize = fontSize;
|
highlightTextInput.fontSize = fontSize;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region COMPILE BUTTON
|
#region COMPILE BUTTON
|
||||||
|
|
||||||
var compileBtnObj = UIFactory.CreateButton(Content);
|
var compileBtnObj = UIFactory.CreateButton(Content);
|
||||||
var compileBtnLayout = compileBtnObj.AddComponent<LayoutElement>();
|
var compileBtnLayout = compileBtnObj.AddComponent<LayoutElement>();
|
||||||
@ -583,7 +601,7 @@ The following helper methods are available:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
//mainTextInput.supportRichText = false;
|
//mainTextInput.supportRichText = false;
|
||||||
|
|
||||||
|
@ -261,6 +261,8 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Core\CSharp\DummyBehaviour.cs" />
|
||||||
|
<Compile Include="Core\Runtime\Il2Cpp\Il2CppCoroutine.cs" />
|
||||||
<Compile Include="Loader\ExplorerBepIn6Plugin.cs" />
|
<Compile Include="Loader\ExplorerBepIn6Plugin.cs" />
|
||||||
<Compile Include="Loader\ExplorerStandalone.cs" />
|
<Compile Include="Loader\ExplorerStandalone.cs" />
|
||||||
<Compile Include="Core\Runtime\Il2Cpp\Il2CppReflection.cs" />
|
<Compile Include="Core\Runtime\Il2Cpp\Il2CppReflection.cs" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user