Editor/Contracts/EditorRuntime.cs
#nullable enable
using System;
using System.Linq;
using System.Reflection;
namespace Editor.Mcp
{
internal static class EditorRuntime
{
public static bool Trigger(string action)
{
var type = FindType("Editor.ActionManager");
var method = type?.GetMethod("Trigger", BindingFlags.Public | BindingFlags.Static, binder: null, types: new[] { typeof(string) }, modifiers: null);
if (method is null) return false;
method.Invoke(null, new object[] { action }); return true;
}
public static (bool Available, bool IsPlaying) PlayMode(string action)
{
var utility = FindType("Editor.EditorUtility"); var property = utility?.GetProperty("PlayMode", BindingFlags.Public | BindingFlags.Static); var value = property?.GetValue(null); if (value is null) return (false, false);
var type = value.GetType(); var isPlaying = type.GetProperty("IsPlaying", BindingFlags.Public | BindingFlags.Instance)?.GetValue(value) as bool? ?? false; var methodName = action == "start" ? "Start" : action == "stop" ? "Stop" : null; if (methodName is not null) type.GetMethod(methodName, BindingFlags.Public | BindingFlags.Instance)?.Invoke(value, null); isPlaying = type.GetProperty("IsPlaying", BindingFlags.Public | BindingFlags.Instance)?.GetValue(value) as bool? ?? isPlaying; return (true, isPlaying);
}
public static object? GetComponentType(string name)
{
var library = FindType("Sandbox.Internal.TypeLibrary"); var editor = library?.GetProperty("Editor", BindingFlags.Public | BindingFlags.Static)?.GetValue(null); var method = editor?.GetType().GetMethod("GetType", new[] { typeof(string), typeof(bool) }); return method?.Invoke(editor, new object[] { name, false });
}
public static Type? FindType(string fullName) => AppDomain.CurrentDomain.GetAssemblies().Select(a => a.GetType(fullName, false)).FirstOrDefault(t => t is not null);
public static object? InvokeStatic(string fullTypeName, string methodName, params object?[] arguments)
{
var type = FindType(fullTypeName);
if (type is null) return null;
var method = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)
.FirstOrDefault(candidate => candidate.Name == methodName && candidate.GetParameters().Length == arguments.Length);
return method?.Invoke(null, arguments);
}
public static bool InvokeStaticAction(string fullTypeName, string methodName, params object?[] arguments)
{
var type = FindType(fullTypeName);
if (type is null) return false;
var method = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)
.FirstOrDefault(candidate => candidate.Name == methodName && candidate.GetParameters().Length == arguments.Length);
if (method is null) return false;
method.Invoke(null, arguments);
return true;
}
public static object? GetStaticProperty(string fullTypeName, string propertyName)
{
var type = FindType(fullTypeName);
return type?.GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)?.GetValue(null);
}
public static object? GetStaticField(string fullTypeName, string fieldName)
{
var type = FindType(fullTypeName);
return type?.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)?.GetValue(null);
}
public static object? GetMember(object? target, string memberName)
{
if (target is null) return null;
var type = target.GetType();
return type.GetProperty(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase)?.GetValue(target)
?? type.GetField(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase)?.GetValue(target);
}
public static bool SetMember(object? target, string memberName, object? value)
{
if (target is null) return false;
var type = target.GetType();
var property = type.GetProperty(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (property?.SetMethod is not null)
{
property.SetValue(target, value);
return true;
}
var field = type.GetField(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (field is null || field.IsInitOnly) return false;
field.SetValue(target, value);
return true;
}
public static object? InvokeInstance(object? target, string methodName, params object?[] arguments)
{
if (target is null) return null;
var method = target.GetType().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.FirstOrDefault(candidate => candidate.Name == methodName && candidate.GetParameters().Length == arguments.Length);
return method?.Invoke(target, arguments);
}
}
}