Decompiled source of ReflectionPlugin v1.0.0

ReflectionPlugin.dll

Decompiled 5 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ReflectionPlugin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Nth Dimension")]
[assembly: AssemblyProduct("ReflectionPlugin")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("ReflectionPlugin")]
[assembly: ComVisible(false)]
[assembly: Guid("c303405d-e66c-4316-9cdb-4e3ca15c6360")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LordAshes;

[BepInPlugin("org.lordashes.plugins.reflection", "Reflection Plugin", "1.0.0.0")]
public class ReflectionPlugin : BaseUnityPlugin
{
	public class Reflection
	{
		public static Type Type(string typeName, string[] has = null, string[] hasType = null, int resultIndex = 0)
		{
			Type[] array = Types(typeName, has, hasType);
			return (array.Length != 0) ? array[resultIndex] : null;
		}

		public static Type[] Types(string typeName, string[] has = null, string[] hasType = null)
		{
			List<Type> list = new List<Type>();
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				foreach (Type item in from t in assembly.GetTypes()
					where t != null && t.Name == typeName
					select t)
				{
					if (has == null)
					{
						list.Add(item);
						continue;
					}
					for (int j = 0; j < has.Length; j++)
					{
						if (HasField(item, has[j], (hasType == null) ? null : hasType[j]) || HasProperty(item, has[j], (hasType == null) ? null : hasType[j]))
						{
							list.Add(item);
						}
					}
				}
			}
			return list.ToArray();
		}

		public static object New(Type type, object[] constructorParamaters)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			LoggingPlugin.LogInfo(type.Name + " Build With " + ((constructorParamaters != null) ? constructorParamaters.Length : 0) + " Parameters");
			if ((int)LoggingPlugin.GetLogLevel() >= 4)
			{
				for (int i = 0; i < type.GetConstructors().Length; i++)
				{
					LoggingPlugin.LogInfo(type.Name + " Constructor #" + i + " (" + type.GetConstructors().ElementAt(i).GetParameters()
						.Length + " Parameters)");
					ParameterInfo[] parameters = type.GetConstructors().ElementAt(i).GetParameters();
					foreach (ParameterInfo parameterInfo in parameters)
					{
						LoggingPlugin.LogInfo(type.Name + " Constructor #" + i + " Parameter: " + parameterInfo.Name + " (" + parameterInfo.ParameterType?.ToString() + ")");
					}
				}
			}
			return Activator.CreateInstance(type, constructorParamaters);
		}

		public static bool HasMethod(Type type, string methodName, string[] parameterTypes = null)
		{
			return Method(type, methodName, parameterTypes) != null;
		}

		public static MethodInfo Method(Type type, string methodName, string[] parameterTypes = null)
		{
			return Methods(type, methodName, parameterTypes).FirstOrDefault();
		}

		public static MethodInfo[] Methods(Type type, string methodName, string[] parameterTypes)
		{
			List<MethodInfo> list = new List<MethodInfo>();
			list = ((methodName == null) ? type.GetRuntimeMethods().ToList() : ((parameterTypes != null) ? (from mi in type.GetRuntimeMethods()
				where mi.Name == methodName && mi.GetParameters().Length == parameterTypes.Length
				select mi).ToList() : (from mi in type.GetRuntimeMethods()
				where mi.Name == methodName
				select mi).ToList()));
			for (int i = 0; i < list.Count; i++)
			{
				for (int j = 0; j < list[i].GetParameters().Length; j++)
				{
					if (parameterTypes != null && parameterTypes[j] != null && parameterTypes[j] != list[i].GetParameters()[j].ParameterType.ToString())
					{
						LoggingPlugin.LogDebug("Type '" + type.Name + "' Method '" + methodName + "' Variation " + i + " Parameter " + j + ": No Match (Have " + list[i].GetParameters()[j].ParameterType.ToString() + ", Need " + parameterTypes[j] + ")");
						list.RemoveAt(i);
						i--;
						break;
					}
				}
			}
			LoggingPlugin.LogDebug("Type '" + type.Name + "' " + ((methodName != null && methodName != "") ? ("Method '" + methodName + "'") : "") + ": Found " + list.Count + " Matches");
			return list.ToArray();
		}

		public static object Execute(MethodInfo method, object instance, object[] parameters, int resultIndex = 0)
		{
			List<object> list = new List<object>();
			if (method.ReturnType != typeof(void))
			{
				list.Add(method.Invoke(instance, parameters));
			}
			else
			{
				method.Invoke(instance, parameters);
			}
			list.AddRange(parameters);
			return list.ElementAt(resultIndex);
		}

		public static bool HasField(Type type, string fieldName, string fieldType = null)
		{
			return Field(type, fieldName, fieldType) != null;
		}

		public static FieldInfo Field(Type type, string fieldName, string fieldType = null)
		{
			return Fields(type, fieldName, fieldType = null).FirstOrDefault();
		}

		public static FieldInfo[] Fields(Type type, string fieldName, string fieldType = null)
		{
			List<FieldInfo> list = new List<FieldInfo>();
			list = ((fieldName == null) ? type.GetRuntimeFields().ToList() : (from fi in type.GetRuntimeFields()
				where fi.Name == fieldName && (fieldType == null || fi.FieldType.Name == fieldType)
				select fi).ToList());
			LoggingPlugin.LogDebug("Type '" + type.Name + "' " + ((fieldName != null && fieldName != "") ? ("Field '" + fieldName + "'") : "") + ": Found " + list.Count + " Matches");
			return list.ToArray();
		}

		public static bool HasProperty(Type type, string propertyName, string propertyType = null)
		{
			return Property(type, propertyName, propertyType) != null;
		}

		public static PropertyInfo Property(Type type, string propertyName, string propertyType = null)
		{
			return Properties(type, propertyName, propertyType).FirstOrDefault();
		}

		public static PropertyInfo[] Properties(Type type, string propertyName, string propertyType = null)
		{
			List<PropertyInfo> list = new List<PropertyInfo>();
			list = ((propertyName == null) ? type.GetRuntimeProperties().ToList() : (from fi in type.GetRuntimeProperties()
				where fi.Name == propertyName && (propertyType == null || fi.PropertyType.Name == propertyType)
				select fi).ToList());
			LoggingPlugin.LogDebug("Type '" + type.Name + "' " + ((propertyName != null && propertyName != "") ? ("Field '" + propertyName + "'") : "") + ": Found " + list.Count + " Matches");
			return list.ToArray();
		}

		public static void Info(Type type, object instance)
		{
			LoggingPlugin.LogInfo("Name: " + type.Name);
			LoggingPlugin.LogInfo("Namespace: " + type.Namespace);
			LoggingPlugin.LogInfo("Full Name: " + type.FullName);
			LoggingPlugin.LogInfo("Assembly: " + type.Assembly.FullName);
			LoggingPlugin.LogInfo("Type: " + ((instance == null) ? "Static" : "Instance"));
			if (HasField(type, "Name"))
			{
				LoggingPlugin.LogInfo("Instance: " + Field(type, "Name").GetValue(instance));
			}
			if (HasProperty(type, "Name"))
			{
				LoggingPlugin.LogInfo("Instance: " + Property(type, "Name").GetValue(instance));
			}
			LoggingPlugin.LogInfo("Methods:");
			MethodInfo[] array = Methods(type, null, null);
			if (array.Length == 0)
			{
				LoggingPlugin.LogInfo("  {No Methods}");
			}
			MethodInfo[] array2 = array;
			foreach (MethodInfo methodInfo in array2)
			{
				try
				{
					LoggingPlugin.LogInfo("  Method Name: " + methodInfo.Name);
					LoggingPlugin.LogInfo("    Returns:" + methodInfo.ReturnParameter.Name + " (" + methodInfo.ReturnType.Name + ")");
					ParameterInfo[] parameters = methodInfo.GetParameters();
					foreach (ParameterInfo parameterInfo in parameters)
					{
						try
						{
							string text = "    Parameter (";
							if (parameterInfo.IsIn)
							{
								text += "In/";
							}
							if (parameterInfo.IsOut)
							{
								text += "Out/";
							}
							if (parameterInfo.ParameterType.IsByRef)
							{
								text += "Ref/";
							}
							if (parameterInfo.IsOptional)
							{
								text += "Op/";
							}
							if (text.EndsWith("/"))
							{
								text = text.Substring(0, text.Length - 1);
							}
							text = text + "): " + parameterInfo.Name + " (" + parameterInfo.ParameterType?.ToString() + ")";
							text = text.Replace(" ()", "");
							LoggingPlugin.LogInfo(text);
						}
						catch (Exception ex)
						{
							CatchFullError(ex);
						}
					}
				}
				catch (Exception ex2)
				{
					LoggingPlugin.LogInfo("Exception Analyzing Method");
					CatchFullError(ex2);
				}
			}
			LoggingPlugin.LogInfo("Fields:");
			FieldInfo[] array3 = Fields(type, null);
			if (array3.Length == 0)
			{
				LoggingPlugin.LogInfo("  {No Fields}");
			}
			FieldInfo[] array4 = array3;
			foreach (FieldInfo fieldInfo in array4)
			{
				try
				{
					string text2 = "  Field Name: " + fieldInfo.Name + " (" + fieldInfo.FieldType?.ToString() + ")";
					try
					{
						text2 = ((fieldInfo.GetValue(instance) == null) ? (text2 + " = {NULL}") : (text2 + " = " + fieldInfo.GetValue(instance)));
					}
					catch (Exception ex3)
					{
						text2 = text2 + " = " + ex3.Message;
					}
					LoggingPlugin.LogInfo(text2);
				}
				catch (Exception ex4)
				{
					LoggingPlugin.LogInfo("Exception Analyzing Field");
					CatchFullError(ex4);
				}
			}
			LoggingPlugin.LogInfo("Properties:");
			PropertyInfo[] array5 = Properties(type, null);
			if (array5.Length == 0)
			{
				LoggingPlugin.LogInfo("  {No Properties}");
			}
			PropertyInfo[] array6 = array5;
			foreach (PropertyInfo propertyInfo in array6)
			{
				try
				{
					string text3 = "  Property Name:" + propertyInfo.Name + " (" + propertyInfo.PropertyType?.ToString() + ")";
					try
					{
						text3 = ((propertyInfo.GetValue(instance) == null) ? (text3 + " = {NULL}") : (text3 + " = " + propertyInfo.GetValue(instance)));
					}
					catch (Exception ex5)
					{
						text3 = text3 + " = " + ex5.Message;
					}
					LoggingPlugin.LogInfo(text3);
				}
				catch (Exception ex6)
				{
					LoggingPlugin.LogInfo("Exception Analyzing Property");
					CatchFullError(ex6);
				}
			}
		}

		public static bool HasEvent(Type type, string eventName)
		{
			return Event(type, eventName) != null;
		}

		public static EventInfo Event(Type type, string eventName, string eventType = null)
		{
			return Events(type, eventName).FirstOrDefault();
		}

		public static EventInfo[] Events(Type type, string eventName)
		{
			EventInfo[] array = (from ei in type.GetRuntimeEvents()
				where ei.Name == eventName
				select ei).ToArray();
			LoggingPlugin.LogDebug("Type '" + type.Name + "' Event '" + eventName + "': Found " + array.Length + " Matches");
			return array;
		}

		public static void AddEvent(Type type, string eventName, Delegate handler, object instance)
		{
			EventInfo eventInfo = Event(type, eventName);
			if (eventInfo == null)
			{
				LoggingPlugin.LogError(type.Name + ": Event '" + eventName + "' Not Found In '" + type.Name + "'");
				throw new Exception(type.Name + ": Event '" + eventName + "' Not Found In '" + type.Name + "'");
			}
			Type eventHandlerType = eventInfo.EventHandlerType;
			Delegate handler2 = CreateCompatibleDelegate(eventHandlerType, handler);
			eventInfo.AddEventHandler(instance, handler2);
		}

		private static Delegate CreateCompatibleDelegate(Type targetType, Delegate handler)
		{
			MethodInfo method = targetType.GetMethod("Invoke");
			ParameterInfo[] parameters = method.GetParameters();
			MethodInfo method2 = handler.Method;
			object target = handler.Target;
			ParameterInfo[] parameters2 = method2.GetParameters();
			ParameterExpression[] array = parameters.Select((ParameterInfo p) => Expression.Parameter(p.ParameterType, p.Name)).ToArray();
			Expression expression;
			if (parameters2.Length == 0)
			{
				expression = Expression.Call((target == null) ? null : Expression.Constant(target), method2);
			}
			else if (parameters2.Length == 1 && parameters2[0].ParameterType == typeof(object))
			{
				Expression expression2 = ((array.Length != 0) ? ((Expression)Expression.Convert(array[0], typeof(object))) : ((Expression)Expression.Constant(null)));
				expression = Expression.Call((target == null) ? null : Expression.Constant(target), method2, expression2);
			}
			else
			{
				if (parameters2.Length != 1 || !(parameters2[0].ParameterType == typeof(object[])))
				{
					throw new Exception("Handler signature not supported. Expected: (), (object), or (object[]). Got (" + string.Join(", ", parameters2.Select((ParameterInfo p) => p.ParameterType.Name)) + ")");
				}
				NewArrayExpression newArrayExpression = Expression.NewArrayInit(typeof(object), array.Select((ParameterExpression p) => Expression.Convert(p, typeof(object))));
				expression = Expression.Call((target == null) ? null : Expression.Constant(target), method2, newArrayExpression);
			}
			if (!(method.ReturnType == typeof(void)))
			{
				expression = Expression.Convert(expression, method.ReturnType);
			}
			LambdaExpression lambdaExpression = Expression.Lambda(targetType, expression, array);
			return lambdaExpression.Compile();
		}

		public static void CatchFullError(Exception ex)
		{
			LoggingPlugin.LogError(ex.Message);
			while (ex.InnerException != null)
			{
				ex = ex.InnerException;
				LoggingPlugin.LogError(ex.Message);
			}
		}
	}

	public const string Name = "Reflection Plugin";

	public const string Guid = "org.lordashes.plugins.reflection";

	public const string Version = "1.0.0.0";

	public const string Author = "Lord Ashes";

	public static ReflectionPlugin _self;

	private void Awake()
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		_self = this;
		LoggingPlugin.SetLogLevel(((BaseUnityPlugin)this).Config.Bind<DiagnosticLevel>("Settings", "Diagnostic Level", (DiagnosticLevel)3, (ConfigDescription)null).Value);
		string? assemblyQualifiedName = ((object)this).GetType().AssemblyQualifiedName;
		DiagnosticLevel logLevel = LoggingPlugin.GetLogLevel();
		Debug.Log((object)(assemblyQualifiedName + ": Active. (Diagnostic Mode = " + ((object)(DiagnosticLevel)(ref logLevel)).ToString() + ")"));
	}
}