using 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)
{
}
}
}