Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of UnityMDK v1.3.0
UnityMDK.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UIElements; using UnityMDK.Injection; using UnityMDK.Logging; using UnityMDK.Patches; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("Saradora")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.0.0")] [assembly: AssemblyInformationalVersion("0.2.0")] [assembly: AssemblyProduct("UnityMDK")] [assembly: AssemblyTitle("UnityMDK")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.0.0")] [module: UnverifiableCode] namespace UnityMDK { [BepInPlugin("Saradora.UnityMDK", "Unity MDK", "1.3.0")] public class PluginInitializer : BaseUnityPlugin { internal static readonly Harmony HarmonyInstance = new Harmony("Saradora.UnityMDK"); private void Awake() { HarmonyInstance.PatchAll(); UnityEngine_Object_Patching.PatchGenericInstantiate(); SceneManager.sceneLoaded += OnSceneLoaded; } private static void OnSceneLoaded(Scene scene, LoadSceneMode loadMode) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) SceneManager.sceneLoaded -= OnSceneLoaded; new GameObject("Unity Injector (instance)").AddComponent<UnityMDK>(); } } [Initializer(0)] public static class PrefabPatcher { private static readonly SortedDictionary<string, string> _prefabs = new SortedDictionary<string, string>(); private static readonly List<GameObject> _patchedPrefabs = new List<GameObject>(); [Initializer(0)] private static void Init() { SceneManager.sceneLoaded += OnSceneLoaded; } private static void OnSceneLoading(int scene) { PatchPrefabs(); } private static void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode) { PatchPrefabs(); } private static void PatchPrefabs() { //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) if (SceneInjection.PrefabsToPatch.Count <= 0) { return; } GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>(); foreach (GameObject val in array) { if ((Object)(object)val.transform.parent != (Object)null) { continue; } Scene scene = val.scene; if (((Scene)(ref scene)).IsValid() || _patchedPrefabs.Contains(val)) { continue; } _patchedPrefabs.Add(val); if (!SceneInjection.PrefabsToPatch.TryGetValue(((Object)val).name, out var value)) { continue; } foreach (IPrefabInjector item in value) { item.OnInject(val); } SceneInjection.PrefabsToPatch.Remove(((Object)val).name); } } private static void LogPrefab(GameObject gameObject, ref int prefabsLogged) { string name = ((Object)gameObject).name; string key = "P" + StringUtilsExtensions.ToPascalCase(name); if (_prefabs.TryGetValue(key, out var value)) { if (value != name) { Log.Error("Couldn't log prefab " + name + " because its Pascal variant " + value + " already exists..."); } } else { _prefabs.Add(key, name); prefabsLogged++; } } private static void OnApplicationQuitting() { if (_prefabs.Count <= 0) { return; } string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (string.IsNullOrEmpty(directoryName)) { Log.Error("Couldn't find path for assembly"); return; } using FileStream stream = File.Open(directoryName + "/PrefabList.cs", FileMode.Create, FileAccess.Write); using StreamWriter streamWriter = new StreamWriter(stream); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("// ----- AUTO-GENERATED CODE ----- //"); stringBuilder.AppendLine(""); stringBuilder.AppendLine("public class PrefabList"); stringBuilder.AppendLine("{"); foreach (var (text3, text4) in _prefabs) { stringBuilder.AppendLine("\tpublic const string " + text3 + " = \"" + text4 + "\";"); } stringBuilder.AppendLine("}"); streamWriter.Write(stringBuilder.ToString()); } } public static class PrefabUtils { private static GameObject _prefabRoot; private static GameObject PrefabRoot { get { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (Object.op_Implicit((Object)(object)_prefabRoot)) { return _prefabRoot; } _prefabRoot = new GameObject("PrefabRoot"); _prefabRoot.SetActive(false); ((Object)_prefabRoot).hideFlags = (HideFlags)61; return _prefabRoot; } } public static GameObject GetEmptyPrefab(string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown GameObject val = new GameObject(name) { hideFlags = (HideFlags)61 }; val.transform.SetParent(PrefabRoot.transform); return val; } } public class UnityMDK : MonoBehaviour { public const string ModGuid = "Saradora.UnityMDK"; public const string ModVersion = "1.3.0"; public const string ModName = "Unity MDK"; public static UnityMDK Instance { get; private set; } private void Awake() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Instance != (Object)null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } SceneInjection.Initialize(); InjectScene(((Component)this).gameObject.scene); SceneManager.sceneLoaded += OnSceneLoaded; Instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } private void OnSceneLoaded(Scene scene, LoadSceneMode loadMode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) InjectScene(scene); } private void InjectScene(Scene scene) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ((MonoBehaviour)this).StartCoroutine(InjectionRoutine(scene)); } private static IEnumerator InjectionRoutine(Scene scene) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) SceneInjection.InjectScene(scene); SceneInjection.ConstructScene(scene, EConstructorEvent.AfterAwake); yield return null; SceneInjection.ConstructScene(scene, EConstructorEvent.AfterStart); yield return null; SceneInjection.ConstructScene(scene, EConstructorEvent.AfterFirstUpdate); } } } namespace UnityMDK.Reflection { public static class ReflectionUtility { private static readonly BindingFlags DefaultBindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; public static void InvokeMethod(this object target, string methodName) { MethodInfo method = target.GetType().GetMethod(methodName, DefaultBindingFlags); if ((object)method == null) { Log.Error("Method " + methodName + " not found"); } else { method.Invoke(target, null); } } public static TReturn InvokeMethod<TReturn>(this object target, string methodName) { MethodInfo method = target.GetType().GetMethod(methodName, DefaultBindingFlags); if ((object)method == null) { Log.Error("Method " + methodName + " not found"); return default(TReturn); } object obj = method.Invoke(target, null); if (obj == null) { return default(TReturn); } if (obj is TReturn) { return (TReturn)obj; } throw new ArgumentException("Method " + methodName + " isn't of type " + typeof(TReturn).Name); } public static bool TryGetField<TObject>(this object target, string fieldName, out TObject outObject) { if (target.TryGetField(fieldName, out var outObject2) && outObject2 is TObject val) { outObject = val; return true; } outObject = default(TObject); return false; } public static bool TryGetField(this object target, string fieldName, out object outObject) { FieldInfo field = target.GetType().GetField(fieldName, DefaultBindingFlags); if ((object)field == null) { outObject = null; return false; } outObject = field.GetValue(target); return true; } public static bool TryGetProperty<TObject>(this object target, string fieldName, out TObject outObject) { PropertyInfo property = target.GetType().GetProperty(fieldName, DefaultBindingFlags); if ((object)property == null) { outObject = default(TObject); return false; } if (property.GetValue(target) is TObject val) { outObject = val; return true; } outObject = default(TObject); return true; } public static void SetProperty<TObject>(this object target, string propertyName, TObject value) { PropertyInfo property = target.GetType().GetProperty(propertyName, DefaultBindingFlags); if ((object)property == null) { Log.Error("Field " + propertyName + " not found"); } else if (property.PropertyType != typeof(TObject)) { Log.Error($"Property {propertyName} isn't of type {typeof(TObject)}"); } else { property.SetValue(target, value); } } public static TObject GetField<TObject>(this object target, string fieldName) { object obj = target.GetType().GetField(fieldName, DefaultBindingFlags)?.GetValue(target); if (obj is TObject) { return (TObject)obj; } return default(TObject); } public static void SetField<TObject>(this object target, string fieldName, TObject value) { FieldInfo field = target.GetType().GetField(fieldName, DefaultBindingFlags); if ((object)field == null) { Log.Error("Field " + fieldName + " not found"); } else if (field.GetValue(target) is TObject) { field.SetValue(target, value); } } } } namespace UnityMDK.Logging { public static class Log { private static readonly Dictionary<Assembly, ManualLogSource> LOGSources = new Dictionary<Assembly, ManualLogSource>(); public static void Print(object message) { GetLogger(Assembly.GetCallingAssembly()).LogInfo(message ?? "Null"); } public static void Warning(object message) { GetLogger(Assembly.GetCallingAssembly()).LogWarning(message ?? "Null"); } public static void Error(object message) { GetLogger(Assembly.GetCallingAssembly()).LogError(message ?? "Null"); } public static void Exception(Exception exception) { GetLogger(Assembly.GetCallingAssembly()).LogError((object)(exception?.Message ?? "Null")); } [Conditional("DEBUG")] public static void DebugPrint(object message) { Print(message); } [Conditional("DEBUG")] public static void DebugWarning(object message) { Warning(message); } [Conditional("DEBUG")] public static void DebugError(object message) { Error(message); } [Conditional("DEBUG")] public static void DebugException(Exception exception) { Exception(exception); } private static ManualLogSource GetLogger(Assembly assembly) { if (LOGSources.TryGetValue(assembly, out var value)) { return value; } LOGSources[assembly] = Logger.CreateLogSource(assembly.GetName().Name); return LOGSources[assembly]; } } } namespace UnityMDK.Patches { public static class MDKSceneManager { public static event Action<int> LoadingScene; internal static void InvokeLoadingScene(int scene) { MDKSceneManager.LoadingScene?.Invoke(scene); } } [HarmonyPatch(typeof(SceneManager))] public static class SceneManager_Patching { [HarmonyPrefix] [HarmonyPatch("LoadScene", new Type[] { typeof(string), typeof(LoadSceneMode) })] [HarmonyPatch("LoadScene", new Type[] { typeof(string), typeof(LoadSceneParameters) })] [HarmonyPatch("LoadSceneAsync", new Type[] { typeof(string), typeof(LoadSceneMode) })] [HarmonyPatch("LoadSceneAsync", new Type[] { typeof(string), typeof(LoadSceneParameters) })] private static void LoadScene_String_Prefix(string sceneName) { LoadScene_Int_Prefix(SceneUtility.GetBuildIndexByScenePath(sceneName)); } [HarmonyPrefix] [HarmonyPatch("LoadScene", new Type[] { typeof(int), typeof(LoadSceneMode) })] [HarmonyPatch("LoadScene", new Type[] { typeof(int), typeof(LoadSceneParameters) })] [HarmonyPatch("LoadSceneAsync", new Type[] { typeof(int), typeof(LoadSceneMode) })] [HarmonyPatch("LoadSceneAsync", new Type[] { typeof(int), typeof(LoadSceneParameters) })] private static void LoadScene_Int_Prefix(int sceneBuildIndex) { if (sceneBuildIndex >= 0 && sceneBuildIndex < SceneManager.sceneCountInBuildSettings) { MDKSceneManager.InvokeLoadingScene(sceneBuildIndex); } } } [HarmonyPatch(typeof(GameObject))] internal static class UnityEngine_GameObject_Patching { [HarmonyPatch("AddComponent", new Type[] { typeof(Type) })] [HarmonyPostfix] private static void AddComponent_PostFix(ref Component __result) { if (__result != null) { SceneInjection.InjectComponent(__result); } } } [HarmonyPatch(typeof(Object))] internal static class UnityEngine_Object_Patching { [HarmonyPatch("Instantiate", new Type[] { typeof(Object), typeof(Transform), typeof(bool) })] [HarmonyPatch("Instantiate", new Type[] { typeof(Object) })] [HarmonyPrefix] private static void Instantiate_Prefix(ref Object original) { InjectInstance(original); } [HarmonyPatch("Internal_InstantiateSingleWithParent", new Type[] { typeof(Object), typeof(Transform), typeof(Vector3), typeof(Quaternion) })] [HarmonyPatch("Internal_InstantiateSingle", new Type[] { typeof(Object), typeof(Vector3), typeof(Quaternion) })] [HarmonyPrefix] private static void Internal_InstantiateSingle_Prefix(ref Object data) { InjectInstance(data); } [HarmonyPatch("Instantiate", new Type[] { typeof(Object), typeof(Transform), typeof(bool) })] [HarmonyPatch("Instantiate", new Type[] { typeof(Object) })] [HarmonyPostfix] private static void Instantiate_Postfix(ref Object __result) { InjectInstancePostFix(__result); } [HarmonyPatch("Internal_InstantiateSingleWithParent", new Type[] { typeof(Object), typeof(Transform), typeof(Vector3), typeof(Quaternion) })] [HarmonyPatch("Internal_InstantiateSingle", new Type[] { typeof(Object), typeof(Vector3), typeof(Quaternion) })] [HarmonyPostfix] private static void Internal_InstantiateSingle_Postfix(ref Object __result) { InjectInstancePostFix(__result); } internal static void PatchGenericInstantiate() { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00be: Expected O, but got Unknown MethodInfo[] methods = typeof(Object).GetMethods(BindingFlags.Static | BindingFlags.Public); MethodInfo methodInfo = null; MethodInfo[] array = methods; foreach (MethodInfo methodInfo2 in array) { if (methodInfo2.GetGenericArguments().Length == 1 && !(methodInfo2.Name != "Instantiate") && methodInfo2.GetParameters().Length == 1) { methodInfo = methodInfo2; break; } } methodInfo = methodInfo.MakeGenericMethod(typeof(Object)); MethodInfo method = typeof(UnityEngine_Object_Patching).GetMethod("GenericInstantiate_Prefix", BindingFlags.Static | BindingFlags.NonPublic); MethodInfo method2 = typeof(UnityEngine_Object_Patching).GetMethod("GenericInstantiate_Postfix", BindingFlags.Static | BindingFlags.NonPublic); PluginInitializer.HarmonyInstance.Patch((MethodBase)methodInfo, new HarmonyMethod(method), new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static void GenericInstantiate_Prefix(Object original) { InjectInstance(original); } private static void GenericInstantiate_Postfix(Object __result) { InjectInstancePostFix(__result); } private static void InjectInstance(Object data) { GameObject val = (GameObject)(object)((data is GameObject) ? data : null); if (val == null) { Component val2 = (Component)(object)((data is Component) ? data : null); if (val2 != null) { SceneInjection.InjectGameObject(val2.gameObject); } } else { SceneInjection.InjectGameObject(val); } } private static void InjectInstancePostFix(Object data) { GameObject val = (GameObject)(object)((data is GameObject) ? data : null); if (val == null) { Component val2 = (Component)(object)((data is Component) ? data : null); if (val2 != null) { SceneInjection.InjectGameObjectPost(val2.gameObject); } } else { SceneInjection.InjectGameObjectPost(val); } } } } namespace UnityMDK.Injection { public readonly struct AddComponentInjector : IInjectable { private readonly Type _type; public AddComponentInjector(Type type) { if (!typeof(Component).IsAssignableFrom(type)) { throw new ArgumentException($"{type} is not a component."); } _type = type; } public bool CanBeInjected(Component component) { return !Object.op_Implicit((Object)(object)component.GetComponent(_type)); } public void Inject(Component component) { component.gameObject.AddComponent(_type); } } public abstract class ComponentInjector : IInjectable { public abstract bool CanBeInjected(Component component); public abstract void Inject(Component component); } public abstract class ComponentInjector<TComponent> : IInjectable where TComponent : Component { public bool CanBeInjected(Component component) { return CanBeInjected((TComponent)(object)component); } public void Inject(Component component) { Inject((TComponent)(object)component); } protected abstract bool CanBeInjected(TComponent component); protected abstract void Inject(TComponent component); } public enum EConstructorEvent { AfterAwake, AfterStart, AfterFirstUpdate } internal interface IInjectable { bool CanBeInjected(Component component); void Inject(Component component); } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class InitializerAttribute : Attribute { public readonly int Order; public InitializerAttribute(int order = 0) { Order = order; } } [AttributeUsage(AttributeTargets.Class)] public class InjectToComponentAttribute : Attribute { internal readonly Type ComponentType; internal readonly bool PostAwake; public InjectToComponentAttribute(Type type, bool postAwake = false) { if (!typeof(Component).IsAssignableFrom(type)) { throw new ArgumentException(type.Name + " isn't a Component."); } PostAwake = postAwake; ComponentType = type; } } [AttributeUsage(AttributeTargets.Class)] public class InjectToPrefabAttribute : Attribute { internal string PrefabName { get; } public InjectToPrefabAttribute(string prefabName) { PrefabName = prefabName; } } public interface IPrefabInjector { protected internal void OnInject(GameObject obj); } [AttributeUsage(AttributeTargets.Class)] public class SceneConstructorAttribute : Attribute { public EConstructorEvent Event { get; } public SceneConstructorAttribute() { Event = EConstructorEvent.AfterAwake; } public SceneConstructorAttribute(EConstructorEvent @event) { Event = @event; } } public static class SceneInjection { private static readonly SortedList<int, List<MethodInfo>> Initializers = new SortedList<int, List<MethodInfo>>(); private static readonly Dictionary<EConstructorEvent, List<MethodInfo>> SceneConstructors = new Dictionary<EConstructorEvent, List<MethodInfo>>(); private static readonly Dictionary<Type, List<IInjectable>> ObjectPreInjectors = new Dictionary<Type, List<IInjectable>>(); private static readonly Dictionary<Type, List<IInjectable>> ObjectPostInjectors = new Dictionary<Type, List<IInjectable>>(); private static readonly List<GameObject> ConstructedPrefabs = new List<GameObject>(); private static readonly List<int> ConstructedScenes = new List<int>(); internal static readonly Dictionary<string, List<IPrefabInjector>> PrefabsToPatch = new Dictionary<string, List<IPrefabInjector>>(); private static bool _initialized; private static readonly Type ComponentType = typeof(Component); private static readonly Type InjectAttributeType = typeof(InjectToComponentAttribute); private static readonly Type IPrefabInjectorType = typeof(IPrefabInjector); private static Scene _dontDestroyOnLoadScene; public static void Initialize() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown if (_initialized) { return; } _initialized = true; GameObject val = new GameObject("Dummy"); Object.DontDestroyOnLoad((Object)val); _dontDestroyOnLoadScene = val.scene; Object.Destroy((Object)val); foreach (EConstructorEvent value in Enum.GetValues(typeof(EConstructorEvent))) { SceneConstructors.Add(value, new List<MethodInfo>()); } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { Type[] types = assembly.GetTypes(); foreach (Type type in types) { try { RegisterPrefabInjector(type); RegisterInjector(type); RegisterSceneConstructor(type); RegisterInitializer(type); } catch { string text = type.Assembly.GetName().Name + "."; if (!string.IsNullOrEmpty(type.Namespace)) { text = text + type.Namespace + "."; } text += type.Name; Log.Warning("Failed analysis of [" + text + "]. If this type doesn't use UnityMDK, this message can be safely ignored."); } } } catch { Log.Warning("Failed analysis of [" + assembly.GetName().Name + "]. If this assembly doesn't use UnityMDK, this message can be safely ignored."); } } RunInitializers(); SceneManager.sceneUnloaded += OnSceneUnloaded; } public static void AddComponentInjector<TComponent>(ComponentInjector injector, bool postAwake = false) where TComponent : Component { Type typeFromHandle = typeof(TComponent); if (typeFromHandle == ComponentType) { Log.Error("Specified component type is too vague"); } else { DoAddComponentInjector(typeFromHandle, injector, postAwake); } } public static void AddComponentInjector<TComponent>(ComponentInjector<TComponent> injector, bool postAwake = false) where TComponent : Component { Type typeFromHandle = typeof(TComponent); if (typeFromHandle == ComponentType) { Log.Error("Specified component type is too vague"); } else { DoAddComponentInjector(typeFromHandle, injector, postAwake); } } private static void DoAddComponentInjector(Type type, IInjectable injectable, bool postAwake) { if (postAwake) { if (!ObjectPostInjectors.ContainsKey(type)) { ObjectPostInjectors.Add(type, new List<IInjectable>()); } ObjectPostInjectors[type].Add(injectable); } else { if (!ObjectPreInjectors.ContainsKey(type)) { ObjectPreInjectors.Add(type, new List<IInjectable>()); } ObjectPreInjectors[type].Add(injectable); } Log.Warning($"Constructable: Adding {injectable.GetType()} to {type}"); } public static void RemoveComponentInjector<TComponent>(bool postAwake = false) where TComponent : Component { DoRemoveComponentInjector(typeof(TComponent), postAwake); } private static void DoRemoveComponentInjector(Type type, bool postAwake) { if (postAwake) { ObjectPostInjectors.Remove(type); } else { ObjectPreInjectors.Remove(type); } } private static void RegisterInjector(Type type) { if (!type.IsDefined(InjectAttributeType, inherit: false) || !ComponentType.IsAssignableFrom(type)) { return; } InjectToComponentAttribute injectToComponentAttribute = (InjectToComponentAttribute)type.GetCustomAttribute(InjectAttributeType); if ((object)injectToComponentAttribute.ComponentType == null) { return; } if (injectToComponentAttribute.PostAwake) { if (!ObjectPostInjectors.ContainsKey(injectToComponentAttribute.ComponentType)) { ObjectPostInjectors.Add(injectToComponentAttribute.ComponentType, new List<IInjectable>()); } ObjectPostInjectors[injectToComponentAttribute.ComponentType].Add(new AddComponentInjector(type)); } else { if (!ObjectPreInjectors.ContainsKey(injectToComponentAttribute.ComponentType)) { ObjectPreInjectors.Add(injectToComponentAttribute.ComponentType, new List<IInjectable>()); } ObjectPreInjectors[injectToComponentAttribute.ComponentType].Add(new AddComponentInjector(type)); } Log.Warning($"Constructable: Adding {type} to {injectToComponentAttribute.ComponentType}"); } private static void RegisterPrefabInjector(Type type) { if (!IPrefabInjectorType.IsAssignableFrom(type)) { return; } InjectToPrefabAttribute customAttribute = type.GetCustomAttribute<InjectToPrefabAttribute>(inherit: true); if (customAttribute == null || string.IsNullOrEmpty(customAttribute.PrefabName)) { return; } if (!PrefabsToPatch.ContainsKey(customAttribute.PrefabName)) { PrefabsToPatch.Add(customAttribute.PrefabName, new List<IPrefabInjector>()); } try { IPrefabInjector prefabInjector = (IPrefabInjector)Activator.CreateInstance(type); PrefabsToPatch[customAttribute.PrefabName].Add(prefabInjector); Log.Warning("Added Prefab '" + customAttribute.PrefabName + "' patch: " + prefabInjector.GetType().Name); } catch (Exception exception) { Log.Exception(exception); } } private static void RegisterSceneConstructor(Type type) { SceneConstructorAttribute sceneConstructorAttribute = (SceneConstructorAttribute)type.GetCustomAttribute(typeof(SceneConstructorAttribute)); if (sceneConstructorAttribute == null) { return; } MethodInfo method = type.GetMethod("SceneConstructor", BindingFlags.Static | BindingFlags.NonPublic); if ((object)method != null) { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == 1 && !(parameters[0].ParameterType != typeof(Scene))) { Log.Warning($"Constructable: Adding {type} to scene constructors"); SceneConstructors[sceneConstructorAttribute.Event].Add(method); } } } private static void RegisterInitializer(Type type) { InitializerAttribute customAttribute = type.GetCustomAttribute<InitializerAttribute>(); if (customAttribute == null) { return; } SortedList<int, List<MethodInfo>> sortedList = new SortedList<int, List<MethodInfo>>(); MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { InitializerAttribute customAttribute2 = methodInfo.GetCustomAttribute<InitializerAttribute>(); if (customAttribute2 != null && methodInfo.GetParameters().Length == 0) { if (!sortedList.ContainsKey(customAttribute2.Order)) { sortedList.Add(customAttribute2.Order, new List<MethodInfo>()); } sortedList[customAttribute2.Order].Add(methodInfo); } } if (!Initializers.ContainsKey(customAttribute.Order)) { Initializers.Add(customAttribute.Order, new List<MethodInfo>()); } foreach (KeyValuePair<int, List<MethodInfo>> item in sortedList) { Initializers[customAttribute.Order].AddRange(item.Value); } } private static void RunInitializers() { object[] parameters = Array.Empty<object>(); foreach (KeyValuePair<int, List<MethodInfo>> initializer in Initializers) { foreach (MethodInfo item in initializer.Value) { item.Invoke(null, parameters); } } } private static void OnSceneUnloaded(Scene scene) { ConstructedScenes.Remove(((Scene)(ref scene)).handle); } internal static void InjectScene(Scene scene) { if (!ConstructedScenes.Contains(((Scene)(ref scene)).handle)) { Log.Print("Injecting scene: " + ((Scene)(ref scene)).name); GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); for (int i = 0; i < rootGameObjects.Length; i++) { InjectGameObject(rootGameObjects[i]); } ConstructedScenes.Add(((Scene)(ref scene)).handle); } } internal static void ConstructScene(Scene scene, EConstructorEvent eventType) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) object[] parameters = new object[1] { scene }; Log.Print("Constructing scene " + ((Scene)(ref scene)).name + " [" + eventType.ToString() + "]"); if (!SceneConstructors.TryGetValue(eventType, out var value)) { return; } foreach (MethodInfo item in value) { item.Invoke(null, parameters); } InjectDontDestroyOnLoadScene(); } private static void InjectDontDestroyOnLoadScene() { if (((Scene)(ref _dontDestroyOnLoadScene)).IsValid()) { GameObject[] rootGameObjects = ((Scene)(ref _dontDestroyOnLoadScene)).GetRootGameObjects(); for (int i = 0; i < rootGameObjects.Length; i++) { InjectGameObject(rootGameObjects[i]); } } } internal static void InjectGameObject(GameObject gameObject) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) Scene scene = gameObject.scene; if (((Scene)(ref scene)).IsValid()) { List<int> constructedScenes = ConstructedScenes; scene = gameObject.scene; if (!constructedScenes.Contains(((Scene)(ref scene)).handle)) { DoInjectGameObject(gameObject); } } else if (!ConstructedPrefabs.Contains(gameObject)) { DoInjectGameObject(gameObject); ConstructedPrefabs.Add(gameObject); } } internal static void InjectGameObjectPost(GameObject gameObject) { foreach (KeyValuePair<Type, List<IInjectable>> objectPostInjector in ObjectPostInjectors) { objectPostInjector.Deconstruct(out var key, out var value); Type type = key; List<IInjectable> list = value; Component[] componentsInChildren = gameObject.GetComponentsInChildren(type, true); foreach (Component component in componentsInChildren) { foreach (IInjectable item in list) { if (item.CanBeInjected(component)) { item.Inject(component); } } } } } private static void DoInjectGameObject(GameObject gameObject) { foreach (KeyValuePair<Type, List<IInjectable>> objectPreInjector in ObjectPreInjectors) { objectPreInjector.Deconstruct(out var key, out var value); Type type = key; List<IInjectable> list = value; Component[] componentsInChildren = gameObject.GetComponentsInChildren(type, true); foreach (Component component in componentsInChildren) { foreach (IInjectable item in list) { if (item.CanBeInjected(component)) { item.Inject(component); } } } } } internal static void InjectComponent(Component component) { Type type = ((object)component).GetType(); Type key; List<IInjectable> value; foreach (KeyValuePair<Type, List<IInjectable>> objectPreInjector in ObjectPreInjectors) { objectPreInjector.Deconstruct(out key, out value); Type type2 = key; List<IInjectable> list = value; if (!type2.IsAssignableFrom(type)) { continue; } foreach (IInjectable item in list) { if (item.CanBeInjected(component)) { item.Inject(component); } } } foreach (KeyValuePair<Type, List<IInjectable>> objectPostInjector in ObjectPostInjectors) { objectPostInjector.Deconstruct(out key, out value); Type type3 = key; List<IInjectable> list2 = value; if (!type3.IsAssignableFrom(type)) { continue; } foreach (IInjectable item2 in list2) { if (item2.CanBeInjected(component)) { item2.Inject(component); } } } } } } namespace UnityMDK.Config { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] public class ConfigSectionAttribute : Attribute { internal string Section; public ConfigSectionAttribute(string section) { Section = section; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] public class ConfigDescriptionAttribute : Attribute { internal string Description; public ConfigDescriptionAttribute(string description) { Description = description; } } public static class ConfigBinder { private static readonly Type ConfigDataType = typeof(IConfigData); private static ConfigFile _currentFile; public static void BindAll(ConfigFile cfg) { _currentFile = cfg; Type[] types = Assembly.GetCallingAssembly().GetTypes(); for (int i = 0; i < types.Length; i++) { BindType(types[i]); } _currentFile = null; } private static void BindType(Type type) { string section = "General"; MemberInfo[] members = type.GetMembers(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MemberInfo memberInfo in members) { if (!memberInfo.MemberType.HasFlag((MemberTypes)0)) { continue; } ConfigSectionAttribute customAttribute = memberInfo.GetCustomAttribute<ConfigSectionAttribute>(); if (customAttribute != null) { section = customAttribute.Section; } string description = memberInfo.GetCustomAttribute<ConfigDescriptionAttribute>()?.Description; string input = memberInfo.Name.Replace("_", ""); input = Regex.Replace(input, "\\b\\p{Ll}", (Match match) => match.Value.ToUpper()); FieldInfo fieldInfo2 = ((memberInfo is PropertyInfo) ? type.GetField("<" + memberInfo.Name + ">k__BackingField", BindingFlags.Static | BindingFlags.NonPublic) : ((!(memberInfo is FieldInfo fieldInfo)) ? null : (fieldInfo.Name.Contains("k__BackingField") ? null : fieldInfo))); FieldInfo fieldInfo3 = fieldInfo2; if ((object)fieldInfo3 != null) { Type fieldType = fieldInfo3.FieldType; if (ConfigDataType.IsAssignableFrom(fieldType)) { BindField(fieldInfo3, section, input, description); } } } } private static void BindField(FieldInfo fieldInfo, string section, string name, string description) { Type type = fieldInfo.FieldType.GetGenericArguments()[0]; if (!TomlTypeConverter.CanConvert(type)) { Log.Error("Type " + type.Name + " is not supported by the config system. Supported types: " + string.Join(", ", (from x in TomlTypeConverter.GetSupportedTypes() select x.Name).ToArray())); return; } IConfigData configData = (IConfigData)fieldInfo.GetValue(null); if (configData == null) { configData = (IConfigData)Activator.CreateInstance(typeof(ConfigData<>).MakeGenericType(type)); fieldInfo.SetValue(null, configData); } configData.Bind(_currentFile, name, section, description); } } internal interface IConfigData { internal void Bind(ConfigFile cfg, string name, string section, string description); } public class ConfigData<T> : IConfigData { private ConfigEntry<T> _configEntry; private readonly T _defaultValue; public T Value => _configEntry.Value; public event Action<T> ConfigChanged; public static implicit operator T(ConfigData<T> config) { return config.Value; } public ConfigData(T defaultValue = default(T)) { _defaultValue = defaultValue; } void IConfigData.Bind(ConfigFile cfg, string name, string section, string description) { if (_configEntry != null) { Log.Warning("Config " + name + " is already bound"); return; } if (description == null) { _configEntry = cfg.Bind<T>(section, name, _defaultValue, (ConfigDescription)null); } else { _configEntry = cfg.Bind<T>(section, name, _defaultValue, description); } _configEntry.SettingChanged += OnSettingChanged; } private void OnSettingChanged(object sender, EventArgs e) { this.ConfigChanged?.Invoke(Value); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }