Decompiled source of GenericClassPlugin v1.0.4

GenericClassPlugin.dll

Decompiled 2 days 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;

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

[BepInPlugin("org.lordashes.plugins.genclass", "Generic Class Plugin", "1.0.4.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class GenClassPlugin : BaseUnityPlugin
{
	public class Generic
	{
		private Type _type = null;

		private object _instance = null;

		private string _name { get; } = "";


		private string _location { get; } = "";


		public Generic(Generic source, object instance = null)
		{
			_type = source._type;
			if (_type != null)
			{
				_name = _type.FullName;
				_location = _type.AssemblyQualifiedName;
				_instance = instance;
				return;
			}
			LoggingPlugin.LogError("Cloning From '" + source._name + "'");
			throw new Exception("Cloning From '" + source._name + "'");
		}

		public Generic(Generic source, object[] constructorParms)
		{
			_type = source._type;
			if (_type != null)
			{
				_name = _type.FullName;
				_location = _type.AssemblyQualifiedName;
				try
				{
					LoggingPlugin.LogDebug("Creature Default Instance With " + constructorParms.Length + " Construction Parameters");
					_instance = Activator.CreateInstance(_type, constructorParms);
					LoggingPlugin.LogTrace("Generic Class Has Instance? " + (_instance != null));
					return;
				}
				catch (Exception innerException)
				{
					LoggingPlugin.LogError("Error In Constructing Type Instance");
					LoggingPlugin.LogError(innerException.Message);
					while (innerException.InnerException != null)
					{
						innerException = innerException.InnerException;
						LoggingPlugin.LogError(innerException.Message);
					}
					LoggingPlugin.LogError("Constructor Parameters Provided:");
					foreach (object obj in constructorParms)
					{
						LoggingPlugin.LogError("  Constructor Parameter: " + obj.GetType().Name);
					}
					ConstructorInfo[] constructors = _type.GetConstructors();
					foreach (ConstructorInfo constructorInfo in constructors)
					{
						LoggingPlugin.LogError("Constructor Needed:");
						ParameterInfo[] parameters = constructorInfo.GetParameters();
						foreach (ParameterInfo parameterInfo in parameters)
						{
							LoggingPlugin.LogError("  Constructor Parameter: " + parameterInfo.ParameterType.Name + " (" + parameterInfo.Name + ")");
						}
					}
					return;
				}
			}
			LoggingPlugin.LogError("Cloning From '" + source._name + "'");
			throw new Exception("Cloning From '" + source._name + "'");
		}

		public Generic(Type type, object instance = null)
		{
			_type = type;
			_instance = instance;
		}

		public Generic(string typeName, object instance = null)
		{
			_type = GetType(typeName, null);
			if (_type != null)
			{
				_name = _type.FullName;
				_location = _type.AssemblyQualifiedName;
				_instance = instance;
				return;
			}
			LoggingPlugin.LogError("Type '" + typeName + "' Not Found");
			throw new Exception("Type '" + typeName + "' Not Found");
		}

		public Generic(string typeName, string[] has, object instance = null)
		{
			_type = GetType(typeName, has);
			if (_type != null)
			{
				_name = _type.FullName;
				_location = _type.AssemblyQualifiedName;
				_instance = instance;
				return;
			}
			LoggingPlugin.LogError("Type '" + typeName + "' Not Found");
			throw new Exception("Type '" + typeName + "' Not Found");
		}

		public Generic(string typeName, string[] has, object[] constructorParms)
		{
			_type = GetType(typeName, has);
			if (_type != null)
			{
				_name = _type.FullName;
				_location = _type.AssemblyQualifiedName;
				try
				{
					LoggingPlugin.LogDebug("Creature Default Instance With " + constructorParms.Length + " Construction Parameters");
					_instance = Activator.CreateInstance(_type, constructorParms);
					LoggingPlugin.LogTrace("Generic Class Has Instance? " + (_instance != null));
					return;
				}
				catch (Exception innerException)
				{
					LoggingPlugin.LogError("Error In Constructing Type Instance");
					LoggingPlugin.LogError(innerException.Message);
					while (innerException.InnerException != null)
					{
						innerException = innerException.InnerException;
						LoggingPlugin.LogError(innerException.Message);
					}
					LoggingPlugin.LogError("Constructor Parameters Provided:");
					foreach (object obj in constructorParms)
					{
						LoggingPlugin.LogError("  Constructor Parameter: " + obj.GetType().Name);
					}
					ConstructorInfo[] constructors = _type.GetConstructors();
					foreach (ConstructorInfo constructorInfo in constructors)
					{
						LoggingPlugin.LogError("Constructor Needed:");
						ParameterInfo[] parameters = constructorInfo.GetParameters();
						foreach (ParameterInfo parameterInfo in parameters)
						{
							LoggingPlugin.LogError("  Constructor Parameter: " + parameterInfo.ParameterType.Name + " (" + parameterInfo.Name + ")");
						}
					}
					return;
				}
			}
			LoggingPlugin.LogError("Type '" + typeName + "' Not Found");
			throw new Exception("Type '" + typeName + "' Not Found");
		}

		public static Generic Close(string baseTypeName, string closeTypeName, object instance = null)
		{
			Generic generic = new Generic(baseTypeName, null);
			Generic generic2 = new Generic(closeTypeName, null);
			Type type = generic.Type().MakeGenericType(generic2.Type());
			return new Generic(type, instance);
		}

		public string Name()
		{
			return _name;
		}

		public string Location()
		{
			return _location;
		}

		public object Instance()
		{
			return _instance;
		}

		public Type Type()
		{
			return _type;
		}

		public object[] Invoke(string methodName, params object[] paramList)
		{
			LoggingPlugin.LogDebug("Invoking '" + methodName + "' On '" + _type.Name + "'");
			MethodInfo methodInfo = Method(methodName);
			if (methodInfo != null)
			{
				return DoInvoke(methodInfo, paramList);
			}
			LoggingPlugin.LogDebug("Suitable Method '" + methodName + "' Not Found. Unable To Invoke.");
			return null;
		}

		public object[] Invoke(string methodName, string[] paramTypes, object[] paramList)
		{
			LoggingPlugin.LogDebug("Invoking '" + methodName + "' On '" + _type.Name + "'");
			MethodInfo methodInfo = Method(methodName, paramTypes);
			if (methodInfo != null)
			{
				return DoInvoke(methodInfo, paramList);
			}
			LoggingPlugin.LogDebug("Suitable Method '" + methodName + "' Not Found. Unable To Invoke.");
			return null;
		}

		public Generic Invoke(string methodName, string[] paramTypes, object[] paramList, string resultType, int resultIndex = 0)
		{
			LoggingPlugin.LogDebug("Invoking '" + methodName + "' On '" + _type.Name + "'");
			MethodInfo methodInfo = Method(methodName, paramTypes);
			if (methodInfo != null)
			{
				return new Generic(resultType, DoInvoke(methodInfo, paramList)[resultIndex]);
			}
			LoggingPlugin.LogDebug("Suitable Method '" + methodName + "' Not Found. Unable To Invoke.");
			return null;
		}

		private object[] DoInvoke(MethodInfo method, params object[] paramList)
		{
			if (method != null)
			{
				LoggingPlugin.LogTrace(_type.Name + ": Setting Types For Output Parameters Type.");
				ParameterInfo[] parameters = method.GetParameters();
				for (int i = 0; i < parameters.Length; i++)
				{
					try
					{
						Type parameterType = parameters[i].ParameterType;
						if (typeof(Delegate).IsAssignableFrom(parameterType) && paramList[i] is Delegate handler)
						{
							LoggingPlugin.LogTrace(_type.Name + ": Adapting delegate parameter " + i);
							paramList[i] = CreateCompatibleDelegate(parameterType, handler);
						}
					}
					catch (Exception ex)
					{
						LoggingPlugin.LogError(_type.Name + ": Exception Adapting Delegate Parameter " + i + " (" + parameters[i].ParameterType?.ToString() + ")");
						LoggingPlugin.LogError(ex.Message);
						if (ex.InnerException != null)
						{
							LoggingPlugin.LogError(ex.InnerException.Message);
						}
					}
				}
				for (int j = 0; j < method.GetParameters().Length; j++)
				{
					if (method.GetParameters()[j].IsOut && paramList[j] == null)
					{
						try
						{
							paramList[j] = Activator.CreateInstance(method.GetParameters()[j].ParameterType);
						}
						catch (Exception ex2)
						{
							paramList[j] = null;
							LoggingPlugin.LogWarning(_type.Name + ": Exception Setting Ouput Parameters Type. " + ex2.Message);
						}
					}
				}
				LoggingPlugin.LogTrace(_type.Name + ": Invoking Compatible Method '" + method.Name + "'.");
				List<object> list = new List<object>();
				try
				{
					if (method.ReturnType != typeof(void))
					{
						list.Add(method.Invoke(_instance, paramList));
						LoggingPlugin.LogTrace(_type.Name + ": Invoke Of " + method.Name + " With Results Successful");
					}
					else
					{
						method.Invoke(_instance, paramList);
						LoggingPlugin.LogTrace(_type.Name + ": Invoke Of " + method.Name + " Without Results Successful");
					}
				}
				catch (Exception ex3)
				{
					LoggingPlugin.LogError(_type.Name + ": Exception Invoking Compatible Method. " + ex3.Message);
					if (ex3.InnerException != null)
					{
						LoggingPlugin.LogError(_type.Name + ": Exception Invoking Compatible Method. " + ex3.InnerException.Message);
					}
				}
				LoggingPlugin.LogTrace(_type.Name + ": Gathering Output Parameters.");
				for (int k = 0; k < paramList.Length; k++)
				{
					if (method.GetParameters()[k].IsOut)
					{
						list.Add(paramList[k]);
					}
				}
				LoggingPlugin.LogTrace(_type.Name + ": Returning Output Parameters.");
				if (list.Count > 0)
				{
					return list.ToArray();
				}
				return null;
			}
			LoggingPlugin.LogError(_type.Name + ": No Compatible Method '" + method.Name + "' Found.");
			throw new Exception(_type.Name + ": No Compatible Method '" + method.Name + "' Found.");
		}

		public object Get(string name)
		{
			FieldInfo[] array = (from fi in _type.GetRuntimeFields()
				where fi.Name == name
				select fi).ToArray();
			if (array.Length != 0)
			{
				LoggingPlugin.LogTrace(_type?.ToString() + " Entry '" + name + "' Get As Field");
				return array[0].GetValue(_instance);
			}
			PropertyInfo[] array2 = (from pi in _type.GetRuntimeProperties()
				where pi.Name == name
				select pi).ToArray();
			if (array2.Length != 0)
			{
				LoggingPlugin.LogTrace(_type?.ToString() + " Entry '" + name + "' Get As Property");
				return array2[0].GetValue(_instance);
			}
			LoggingPlugin.LogTrace(_type?.ToString() + " Entry '" + name + "' Not Found (Get)");
			return null;
		}

		public T Get<T>(string name)
		{
			return (T)Get(name);
		}

		public Generic GetAsGeneric(string name)
		{
			if (HasField(_type, name))
			{
				return new Generic(_type.GetField(name).FieldType.Name, _type.GetField(name).GetValue(_instance));
			}
			if (HasProperty(_type, name))
			{
				return new Generic(_type.GetProperty(name).PropertyType.Name, _type.GetProperty(name).GetValue(_instance));
			}
			return new Generic(null, null);
		}

		public void Set(string name, object value)
		{
			FieldInfo[] array = (from fi in _type.GetRuntimeFields()
				where fi.Name == name
				select fi).ToArray();
			if (array.Length != 0)
			{
				LoggingPlugin.LogTrace(_type?.ToString() + " Entry '" + name + "' Set As Field");
				array[0].SetValue(_instance, value);
				return;
			}
			PropertyInfo[] array2 = (from pi in _type.GetRuntimeProperties()
				where pi.Name == name
				select pi).ToArray();
			if (array2.Length != 0)
			{
				LoggingPlugin.LogTrace(_type?.ToString() + " Entry '" + name + "' Set As Property");
				array2[0].SetValue(_instance, value);
			}
			else
			{
				LoggingPlugin.LogTrace(_type?.ToString() + " Entry '" + name + "' Not Found (Set)");
			}
		}

		public void AddEvent(string eventName, Delegate handler)
		{
			EventInfo @event = _type.GetEvent(eventName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (@event == null)
			{
				LoggingPlugin.LogError(_type.Name + ": Event '" + _name + "' Not Found In '" + _type.Name + "'");
				throw new Exception(_type.Name + ": Event '" + _name + "' Not Found In '" + _type.Name + "'");
			}
			Type eventHandlerType = @event.EventHandlerType;
			Delegate handler2 = CreateCompatibleDelegate(eventHandlerType, handler);
			@event.AddEventHandler(_instance, handler2);
		}

		public static void Info(object obj)
		{
			LoggingPlugin.LogInfo("Object Type: " + obj.GetType());
			Type type = obj.GetType();
			Info(type, obj);
		}

		public static void Info(Type type, object obj)
		{
			foreach (MethodInfo runtimeMethod in type.GetRuntimeMethods())
			{
				string text = type.Name + " Method: " + runtimeMethod.Name + " (";
				ParameterInfo[] parameters = runtimeMethod.GetParameters();
				foreach (ParameterInfo parameterInfo in parameters)
				{
					text = text + parameterInfo.Name + ":" + parameterInfo.ParameterType.Name + ",";
				}
				if (text.EndsWith(","))
				{
					text = text.Substring(0, text.Length - 1);
				}
				text += ")";
				LoggingPlugin.LogInfo(text);
			}
			foreach (FieldInfo runtimeField in type.GetRuntimeFields())
			{
				string text2 = type.Name + " Field: " + runtimeField.Name + " (" + runtimeField.FieldType?.ToString() + ") ";
				try
				{
					text2 = text2 + " = " + runtimeField.GetValue(obj);
				}
				catch
				{
				}
				LoggingPlugin.LogInfo(text2);
			}
			foreach (PropertyInfo runtimeProperty in type.GetRuntimeProperties())
			{
				string text3 = type.Name + " Property: " + runtimeProperty.Name + " (" + runtimeProperty.PropertyType?.ToString() + ")";
				try
				{
					text3 = text3 + " = " + runtimeProperty.GetValue(obj);
				}
				catch
				{
				}
				LoggingPlugin.LogInfo(text3);
			}
		}

		public MethodInfo Method(string methodName)
		{
			return Method(methodName, null);
		}

		public MethodInfo Method(string methodName, string[] paramTypes)
		{
			LoggingPlugin.LogDebug(_type.Name + ": Found " + _type.GetRuntimeMethods().Count() + " Methods On Type " + _type.Name);
			foreach (MethodInfo item in from mi in _type.GetRuntimeMethods()
				where mi.Name == methodName
				select mi)
			{
				bool flag = true;
				if (paramTypes != null)
				{
					if (item.GetParameters().Length == paramTypes.Length)
					{
						for (int i = 0; i < paramTypes.Length; i++)
						{
							if (paramTypes != null && paramTypes[i] != null && item.GetParameters()[i].ParameterType.Name.ToUpper() != paramTypes[i].ToUpper())
							{
								LoggingPlugin.LogTrace(_type.Name + ": Incompatible Method '" + item.Name + "' Parameter Type (Has " + item.GetParameters()[i].ParameterType.Name + " But Needs " + paramTypes[i] + ")");
								flag = false;
							}
							else
							{
								LoggingPlugin.LogTrace(_type.Name + ": Compatible Method '" + item.Name + "' Parameter Type (Is " + item.GetParameters()[i].ParameterType.Name + " Vs " + ((paramTypes[i] != null) ? paramTypes[i] : "(Any)") + ")");
							}
						}
					}
					else
					{
						LoggingPlugin.LogTrace(_type.Name + ": Incompatible Method '" + item.Name + "' Due To Parameter Count (Has " + item.GetParameters().Length + " But Needs " + paramTypes.Length + ")");
						flag = false;
					}
				}
				if (flag)
				{
					return item;
				}
			}
			return null;
		}

		public MethodInfo[] Methods(string methodName, string[] paramTypes)
		{
			LoggingPlugin.LogDebug(_type.Name + ": Found " + _type.GetRuntimeMethods().Count() + " Methods On Type " + _type.Name);
			List<MethodInfo> list = new List<MethodInfo>();
			foreach (MethodInfo item in from mi in _type.GetRuntimeMethods()
				where mi.Name == methodName
				select mi)
			{
				bool flag = true;
				if (paramTypes != null)
				{
					if (item.GetParameters().Length == paramTypes.Length)
					{
						for (int i = 0; i < paramTypes.Length; i++)
						{
							if (paramTypes != null && paramTypes[i] != null && item.GetParameters()[i].ParameterType.Name.ToUpper() != paramTypes[i].ToUpper())
							{
								LoggingPlugin.LogTrace(_type.Name + ": Incompatible Method '" + item.Name + "' Parameter Type (Has " + item.GetParameters()[i].ParameterType.Name + " But Needs " + paramTypes[i] + ")");
								flag = false;
							}
							else
							{
								LoggingPlugin.LogTrace(_type.Name + ": Compatible Method '" + item.Name + "' Parameter Type (Is " + item.GetParameters()[i].ParameterType.Name + " Vs " + ((paramTypes[i] != null) ? paramTypes[i] : "(Any)") + ")");
							}
						}
					}
					else
					{
						LoggingPlugin.LogTrace(_type.Name + ": Incompatible Method '" + item.Name + "' Due To Parameter Count (Has " + item.GetParameters().Length + " But Needs " + paramTypes.Length + ")");
						flag = false;
					}
				}
				if (flag)
				{
					list.Add(item);
				}
			}
			return list.ToArray();
		}

		public FieldInfo Field(string fieldName, string paramType = null)
		{
			FieldInfo[] source = (from fi in _type.GetRuntimeFields()
				where fi.Name == fieldName
				select fi).ToArray();
			if (paramType != null)
			{
				source = source.Where((FieldInfo fi) => fi.FieldType.Name == paramType).ToArray();
			}
			return source.FirstOrDefault();
		}

		public PropertyInfo Property(string propertyName, string paramType = null)
		{
			PropertyInfo[] source = (from pi in _type.GetRuntimeProperties()
				where pi.Name == propertyName
				select pi).ToArray();
			if (paramType != null)
			{
				source = source.Where((PropertyInfo fi) => fi.PropertyType.Name == paramType).ToArray();
			}
			return source.FirstOrDefault();
		}

		private 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 Type GetType(string typeName, string[] has)
		{
			Type[] array = AppDomain.CurrentDomain.GetAssemblies().SelectMany(delegate(Assembly a)
			{
				try
				{
					return a.GetTypes();
				}
				catch (ReflectionTypeLoadException ex)
				{
					return ex.Types.Where((Type t) => t != null);
				}
			}).ToArray();
			if (has == null)
			{
				LoggingPlugin.LogDebug("Found " + array.Length + " Possible '" + typeName + "' Definitions. Using First.");
				return array.FirstOrDefault((Type t) => t.FullName == typeName || t.Name == typeName);
			}
			LoggingPlugin.LogDebug("Found " + array.Length + " Possible '" + typeName + "' Definitions. Looking For Conditions.");
			for (int i = 0; i < array.Length; i++)
			{
				LoggingPlugin.LogTrace("Testing Type '" + typeName + "' #" + (i + 1));
				bool flag = true;
				foreach (string text in has)
				{
					if (!HasField(array[i], text) && !HasProperty(array[i], text))
					{
						LoggingPlugin.LogTrace("Failed Conditions '" + text + "'");
						flag = false;
						break;
					}
				}
				if (flag)
				{
					LoggingPlugin.LogDebug("Found '" + typeName + "' Definitions That Matches All Conditions.");
					return array[i];
				}
			}
			LoggingPlugin.LogDebug("Type '" + typeName + "' Not Found.");
			return null;
		}

		public static bool HasField(Type type, string fieldName)
		{
			return (from fi in type.GetRuntimeFields()
				where fi.Name == fieldName
				select fi).Count() > 0;
		}

		public static bool HasProperty(Type type, string propertyName)
		{
			return (from fi in type.GetRuntimeProperties()
				where fi.Name == propertyName
				select fi).Count() > 0;
		}
	}

	public const string Name = "Generic Class Plugin";

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

	public const string Version = "1.0.4.0";

	public const string Author = "Lord Ashes";

	private void Awake()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		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();
		LoggingPlugin.LogInfo(assemblyQualifiedName + ": Active. (Diagnostic Mode = " + ((object)(DiagnosticLevel)(ref logLevel)).ToString() + ")");
	}
}