Decompiled source of ExtraUIScreens v0.0.2

ExtraUIScreens.dll

Decompiled a year ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using Belzont.AssemblyUtility;
using Belzont.Interfaces;
using Belzont.Utils;
using BepInEx;
using BepInEx.Logging;
using Colossal;
using Colossal.IO.AssetDatabase;
using Colossal.Localization;
using Colossal.Logging;
using Colossal.OdinSerializer.Utilities;
using Colossal.Serialization.Entities;
using Colossal.UI;
using Colossal.UI.Binding;
using Game;
using Game.Input;
using Game.Modding;
using Game.SceneFlow;
using Game.Settings;
using Game.UI;
using Game.UI.Localization;
using HarmonyLib;
using K45EUIS_Ext;
using Unity.Entities;
using Unity.Jobs;
using UnityEngine;
using cohtml;
using cohtml.InputSystem;
using cohtml.Net;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: KlyteModCanonVersion("0.0.7.4", "0.0.2")]
[assembly: AssemblyCompany("ExtraUIScreens")]
[assembly: AssemblyConfiguration("Thunderstore")]
[assembly: AssemblyFileVersion("0.0.2.65534")]
[assembly: AssemblyInformationalVersion("0.0.2.65534")]
[assembly: AssemblyProduct("ExtraUIScreens")]
[assembly: AssemblyTitle("ExtraUIScreens")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.2.65534")]
[module: UnverifiableCode]
namespace ExtraUIScreens
{
	[FileLocation("K45_EUIS")]
	[SettingsUITabOrder(new string[] { "MonitorsData", "About" })]
	public class EuisModData : BasicModData
	{
		public const string kMonitorsTab = "MonitorsData";

		public static ExtraUIScreensMod EuisInstance { get; private set; }

		public static EuisModData EuisDataInstance { get; private set; }

		[SettingsUIHidden]
		public int InactiveMonitors { get; set; }

		private string[][] m_DisabledApps { get; set; }

		public List<string> DisabledAppsByMonitor
		{
			get
			{
				return m_DisabledApps?.Select((string[] x) => string.Join(",", new HashSet<string>(x ?? new string[0]))).ToList();
			}
			set
			{
				m_DisabledApps = value?.Select((string x) => new HashSet<string>(x?.Split(",") ?? new string[0]).ToArray())?.ToArray() ?? new string[0][];
			}
		}

		[SettingsUISection("MonitorsData", null)]
		public bool UseMonitor1
		{
			get
			{
				return IsMonitorActive(0);
			}
			set
			{
				SetMonitorActive(0, value);
			}
		}

		[SettingsUISection("MonitorsData", null)]
		[SettingsUIHideByCondition(typeof(EuisModData), "IsMonitor1Unavailable")]
		public bool UseMonitor2
		{
			get
			{
				return IsMonitorActive(1);
			}
			set
			{
				SetMonitorActive(1, value);
			}
		}

		[SettingsUISection("MonitorsData", null)]
		[SettingsUIHideByCondition(typeof(EuisModData), "IsMonitor2Unavailable")]
		public bool UseMonitor3
		{
			get
			{
				return IsMonitorActive(2);
			}
			set
			{
				SetMonitorActive(2, value);
			}
		}

		[SettingsUISection("MonitorsData", null)]
		[SettingsUIHideByCondition(typeof(EuisModData), "IsMonitor3Unavailable")]
		public bool UseMonitor4
		{
			get
			{
				return IsMonitorActive(3);
			}
			set
			{
				SetMonitorActive(3, value);
			}
		}

		[SettingsUISection("MonitorsData", null)]
		[SettingsUIHideByCondition(typeof(EuisModData), "IsMonitor4Unavailable")]
		public bool UseMonitor5
		{
			get
			{
				return IsMonitorActive(4);
			}
			set
			{
				SetMonitorActive(4, value);
			}
		}

		[SettingsUISection("MonitorsData", null)]
		[SettingsUIHideByCondition(typeof(EuisModData), "IsMonitor5Unavailable")]
		public bool UseMonitor6
		{
			get
			{
				return IsMonitorActive(5);
			}
			set
			{
				SetMonitorActive(5, value);
			}
		}

		[SettingsUISection("MonitorsData", null)]
		[SettingsUIHideByCondition(typeof(EuisModData), "IsMonitor6Unavailable")]
		public bool UseMonitor7
		{
			get
			{
				return IsMonitorActive(6);
			}
			set
			{
				SetMonitorActive(6, value);
			}
		}

		[SettingsUISection("MonitorsData", null)]
		[SettingsUIHideByCondition(typeof(EuisModData), "IsMonitor7Unavailable")]
		public bool UseMonitor8
		{
			get
			{
				return IsMonitorActive(7);
			}
			set
			{
				SetMonitorActive(7, value);
			}
		}

		public EuisModData(IMod mod)
			: base(mod)
		{
			EuisInstance = mod as ExtraUIScreensMod;
			EuisDataInstance = this;
		}

		public bool IsMonitorActive(int displayIdx)
		{
			return (InactiveMonitors & (1 << displayIdx)) == 0;
		}

		public void SetMonitorActive(int displayId, bool newValue)
		{
			if (newValue)
			{
				InactiveMonitors &= ~(1 << displayId);
				EuisScreenManager.Instance?.InitializeMonitor(displayId);
			}
			else
			{
				InactiveMonitors |= 1 << displayId;
			}
			EuisScreenManager.Instance?.OnMonitorActivityChanged();
		}

		public string[][] GetDisabledAppsByMonitor()
		{
			return m_DisabledApps ?? new string[0][];
		}

		public void SetDisabledAppsByMonitor(string[][] newVal)
		{
			m_DisabledApps = newVal;
		}

		public override void OnSetDefaults()
		{
		}

		public bool IsMonitor1Unavailable()
		{
			return Display.displays.Length < 2;
		}

		public bool IsMonitor2Unavailable()
		{
			return Display.displays.Length < 3;
		}

		public bool IsMonitor3Unavailable()
		{
			return Display.displays.Length < 4;
		}

		public bool IsMonitor4Unavailable()
		{
			return Display.displays.Length < 5;
		}

		public bool IsMonitor5Unavailable()
		{
			return Display.displays.Length < 6;
		}

		public bool IsMonitor6Unavailable()
		{
			return Display.displays.Length < 7;
		}

		public bool IsMonitor7Unavailable()
		{
			return Display.displays.Length < 8;
		}
	}
	public class EuisResourceHandler : DefaultResourceHandler
	{
		public CohtmlUISystem System { get; set; }

		public string liveViewData => "[" + string.Join(",", (typeof(UserImagesManager).GetField("m_LiveViews", ReflectionUtils.allFlags).GetValue(System.UserImagesManager) as Dictionary<string, CohtmlLiveView>)?.Keys) + "]";

		public override void OnResourceRequest(IResourceRequest request, IResourceResponse response)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			LogUtils.DoLog("EuisResourceHandler.OnResourceRequest {0} - LiveViews = {1}", request.GetURL(), liveViewData);
			if (IsLiveViewRequest(request.GetURL()))
			{
				ResourceRequestData requestData = new ResourceRequestData(request.GetId(), request.GetURL(), response);
				((DefaultResourceHandler)this).coroutineHost.StartCoroutine(TryPreloadedTextureRequestAsync(requestData));
			}
			else
			{
				((DefaultResourceHandler)this).OnResourceRequest(request, response);
			}
		}

		private void RequestLiveViewResource(ResourceRequestData requestData)
		{
			UserImageData val = System.UserImagesManager.CreateLiveViewImageData(((RequestData)requestData).UriBuilder.Uri.AbsoluteUri);
			if (val != null)
			{
				requestData.Response.ReceiveUserImage(val);
				((RequestData)requestData).RespondWithSuccess();
			}
			else
			{
				((RequestData)requestData).RespondWithFailure($"Cannot find live View Url: {((RequestData)requestData).UriBuilder.Uri}");
			}
		}

		private bool IsLiveViewRequest(string uri)
		{
			return System.UserImagesManager.ContainsLiveView(uri);
		}

		private IEnumerator TryPreloadedTextureRequestAsync(ResourceRequestData requestData)
		{
			RequestLiveViewResource(requestData);
			yield break;
		}
	}
	public class EuisScreenManager : MonoBehaviour
	{
		private UIInputSystem[] inputSystemArray;

		private UISystem[] uiSystemArray;

		private bool showMonitor1;

		private static readonly FieldInfo fieldUIInput = typeof(GameManager).GetField("m_UIInputSystem", RedirectorUtils.allFlags);

		private EuisResourceHandler defaultResourceHandlerDisplays;

		private Coroutine RunningAppSelectionDefaultSave;

		private int lastMonitorId = -1;

		private Barrier m_GlobalBarrier;

		private readonly HashSet<IEUISAppRegister> registeredApplications = new HashSet<IEUISAppRegister>();

		private readonly Dictionary<string, RawValueBinding> m_cachedBindings = new Dictionary<string, RawValueBinding>();

		public static EuisScreenManager Instance { get; private set; }

		public static bool DebugMode { get; set; } = true;


		private int ReadyCount { get; set; }

		private int ReadyCountTarget { get; set; } = -1;


		private bool Ready { get; set; }

		private event Action OnReady;

		private event Action<int> OnceOnReady;

		private event Action OnBeforeSceneLoad;

		public void Awake()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)this);
		}

		public void Start()
		{
			uiSystemArray = (UISystem[])(object)new UISystem[8];
			ReadyCount = 0;
			ReadyCountTarget = Display.displays.Length;
			UIView view = GameManager.instance.userInterface.view;
			UISystem uiSystem = GameManager.instance.userInterface.view.uiSystem;
			inputSystemArray = (UIInputSystem[])(object)new UIInputSystem[9];
			inputSystemArray[0] = GameManager.UIInputSystem;
			m_GlobalBarrier = InputManager.instance.CreateGlobalBarrier();
			view.Listener.NodeMouseEvent += delegate(INodeProxy a, IMouseEventData eventData, IntPtr c, PhaseType d)
			{
				//IL_000b: 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)
				UpdateInputSystem(eventData, 0);
				return (Actions)0;
			};
			for (int i = 0; i < Display.displays.Length; i++)
			{
				if (EuisModData.EuisDataInstance.IsMonitorActive(i))
				{
					InitializeMonitor(i);
				}
				else
				{
					ReadyCountTarget--;
				}
			}
		}

		public void Update()
		{
			if (lastMonitorId < 2 && EuisModData.EuisDataInstance.IsMonitorActive(0) && Input.GetKeyDown((KeyCode)9) && Input.GetKey((KeyCode)306))
			{
				showMonitor1 = !showMonitor1;
				uiSystemArray[0].UIViews[0].View.TriggerEvent<bool>("k45::euis.toggleMon1", showMonitor1);
				UpdateActiveMonitor();
			}
		}

		public void InitializeMonitor(int displayId)
		{
			((MonoBehaviour)this).StartCoroutine(InitializeMonitor_impl(displayId));
		}

		private IEnumerator InitializeMonitor_impl(int displayId)
		{
			if ((displayId > 0 && Display.displays[displayId].active) || (displayId == 0 && uiSystemArray[0] != null))
			{
				yield break;
			}
			yield return 0;
			UIView defView = GameManager.instance.userInterface.view;
			if (displayId > 0)
			{
				Display.displays[displayId].Activate();
			}
			if (defaultResourceHandlerDisplays == null)
			{
				defaultResourceHandlerDisplays = new EuisResourceHandler();
				IResourceHandler resourceHandler = defView.uiSystem.resourceHandler;
				DefaultResourceHandler defaultRH = (DefaultResourceHandler)(object)((resourceHandler is DefaultResourceHandler) ? resourceHandler : null);
				((DefaultResourceHandler)defaultResourceHandlerDisplays).HostLocationsMap = defaultRH.HostLocationsMap;
				((DefaultResourceHandler)defaultResourceHandlerDisplays).coroutineHost = defaultRH.coroutineHost;
				((DefaultResourceHandler)defaultResourceHandlerDisplays).userImagesManager = defaultRH.userImagesManager;
				defaultResourceHandlerDisplays.System = CohtmlUISystem.GetDefaultUISystem();
			}
			UISystem[] array = uiSystemArray;
			int num = displayId;
			UIManager instance = UIManager.instance;
			Settings val = new Settings
			{
				debuggerPort = 9450 + displayId,
				enableDebugger = DebugMode
			};
			((Settings)(ref val)).localizationManager = (ILocalizationManager)new UILocalizationManager(GameManager.instance.localizationManager);
			((Settings)(ref val)).resourceHandler = (IResourceHandler)(object)defaultResourceHandlerDisplays;
			array[num] = instance.CreateUISystem(val);
			int thisMonitorId = displayId + 1;
			inputSystemArray[thisMonitorId] = new UIInputSystem(uiSystemArray[displayId], true);
			yield return 0;
			Settings settings = Settings.New;
			settings.isTransparent = true;
			settings.acceptsInput = true;
			settings.pixelPerfect = true;
			Camera cam;
			if (displayId != 0)
			{
				GameObject camgo = new GameObject();
				Object.DontDestroyOnLoad((Object)(object)camgo);
				cam = camgo.AddComponent<Camera>();
				cam.farClipPlane = 1f;
				cam.nearClipPlane = 0.9f;
				cam.cameraType = (CameraType)4;
				cam.clearFlags = (CameraClearFlags)2;
				cam.backgroundColor = Color.black;
				cam.targetDisplay = displayId;
			}
			else
			{
				cam = defView.RenderingCamera;
				settings.enableBackdropFilter = false;
			}
			string baseUri = new UriBuilder
			{
				Scheme = "coui",
				Host = BasicIMod.Instance.CouiHost,
				Path = "UI/esos/index.html"
			}.Uri.AbsoluteUri;
			yield return 0;
			UIView modView = uiSystemArray[displayId].CreateView(baseUri, settings, cam);
			modView.enabled = true;
			modView.Listener.ReadyForBindings += delegate
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_0104: Unknown result type (might be due to invalid IL or missing references)
				//IL_0139: Unknown result type (might be due to invalid IL or missing references)
				//IL_0160: Unknown result type (might be due to invalid IL or missing references)
				//IL_0187: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0226: Unknown result type (might be due to invalid IL or missing references)
				modView.View.BindCall("k45::euis.getMonitorId", (Delegate)(Func<int>)(() => thisMonitorId));
				modView.View.BindCall("k45::euis.getQuantityMonitors", (Delegate)(Func<int>)(() => Display.displays.Length));
				modView.View.BindCall("k45::euis.getDisabledAppsByDisplay", (Delegate)(Func<string[][]>)(() => EuisModData.EuisDataInstance.GetDisabledAppsByMonitor()));
				modView.View.RegisterForEvent("k45::euis.getMonitorEnabledApplcations", (Delegate)(Action<int>)delegate(int monitorId)
				{
					((MonoBehaviour)this).StartCoroutine(GetMonitorEnabledApplcations(monitorId, modView.View));
				});
				modView.View.RegisterForEvent("k45::euis.getVosEnabledApplcations", (Delegate)(Action<int>)delegate
				{
					((MonoBehaviour)this).StartCoroutine(GetVosEnabledApplcations(modView.View));
				});
				modView.View.BindCall("k45::euis.saveAppSelectionAsDefault", (Delegate)(Action)delegate
				{
					SaveAppSelectionAsDefault();
				});
				modView.View.BindCall("k45::euis.removeAppButton", (Delegate)new Action<string, int>(RemoveAppFromMonitor));
				modView.View.BindCall("k45::euis.reintroduceAppButton", (Delegate)new Action<string, int>(AddAppToMonitor));
				modView.View.BindCall("k45::euis.getActiveMonitorMask", (Delegate)(Func<int>)(() => EuisModData.EuisDataInstance.InactiveMonitors));
				modView.View.BindCall("k45::euis.frontEndReady", (Delegate)(Action<int>)delegate(int x)
				{
					if (!Ready)
					{
						int readyCount = ReadyCount;
						ReadyCount = readyCount + 1;
						Ready = ReadyCount >= ReadyCountTarget;
						if (Ready)
						{
							this.OnReady?.Invoke();
							this.OnceOnReady?.Invoke(-1);
						}
					}
					else
					{
						this.OnReady?.Invoke();
						this.OnceOnReady?.Invoke(x);
					}
					OnMonitorActivityChanged();
				});
				modView.View.BindCall("k45::euis.interfaceStyle", (Delegate)(Func<string>)(() => SharedSettings.instance.userInterface.interfaceStyle));
			};
			modView.Listener.NodeMouseEvent += delegate(INodeProxy a, IMouseEventData eventData, IntPtr c, PhaseType d)
			{
				//IL_0015: 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)
				UpdateInputSystem(eventData, thisMonitorId);
				return (Actions)0;
			};
			GameManager.instance.localizationManager.onActiveDictionaryChanged += delegate
			{
				modView.View.TriggerEvent("k45::euis.localeChanged");
			};
			OnBeforeSceneLoad += delegate
			{
				((MonoBehaviour)this).StartCoroutine(DisableViewOnLoad(modView, (displayId != 0) ? cam : null));
			};
			GameManager.instance.onGameLoadingComplete += (EventGamePreload)delegate
			{
				if (displayId != 0)
				{
					((Behaviour)cam).enabled = true;
				}
				modView.enabled = true;
				modView.View.LoadURL(modView.url);
			};
		}

		public void RunOnBeforeSceneLoad()
		{
			this.OnBeforeSceneLoad?.Invoke();
		}

		private IEnumerator DisableViewOnLoad(UIView view, Camera cam)
		{
			view.enabled = false;
			yield return 0;
			if ((Object)(object)cam != (Object)null)
			{
				((Behaviour)cam).enabled = false;
			}
		}

		private void SaveAppSelectionAsDefault()
		{
			if (RunningAppSelectionDefaultSave == null)
			{
				RunningAppSelectionDefaultSave = ((MonoBehaviour)this).StartCoroutine(SaveAppSelectionAsDefault_impl());
			}
		}

		private IEnumerator SaveAppSelectionAsDefault_impl()
		{
			yield return 0;
			string[][] result = new string[Display.displays.Length + 1][];
			if (BasicIMod.DebugMode)
			{
				LogUtils.DoLog("Registered apps: " + string.Join("|", registeredApplications.Select((IEUISAppRegister x) => EUISAppRegisterExtensions.GetFullAppName(x))));
			}
			for (int i = 0; i <= Display.displays.Length; i++)
			{
				Wrapper<string[]> wrapper = new Wrapper<string[]>();
				yield return DoCallToMonitorToGetApplicationsEnabled(i, wrapper);
				if (BasicIMod.DebugMode)
				{
					LogUtils.DoLog(string.Format("Apps enabled in display {0}: {1}", i, string.Join("|", wrapper.Value ?? new string[0])));
				}
				result[i] = ((wrapper.Value != null) ? (from x in registeredApplications
					select EUISAppRegisterExtensions.GetFullAppName(x) into x
					where !wrapper.Value.Contains(x)
					select x).ToArray() : new string[0]);
			}
			EuisModData.EuisDataInstance.SetDisabledAppsByMonitor(result);
			RunningAppSelectionDefaultSave = null;
		}

		private bool UpdateInputSystem(IMouseEventData b, int thisMonitorId)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			if ((int)b.Type == 0 || (int)b.Type == 3 || (int)b.Type == 1)
			{
				UpdateActiveMonitor();
			}
			return thisMonitorId == lastMonitorId;
		}

		private void UpdateActiveMonitor()
		{
			//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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Display.RelativeMouseAt(Input.mousePosition);
			int num = Mathf.RoundToInt(val.z);
			if (num != 0 || showMonitor1)
			{
				num++;
			}
			if (num > 0)
			{
				InputManager.instance.mouseOverUI = true;
			}
			if (num == lastMonitorId)
			{
				return;
			}
			lastMonitorId = num;
			fieldUIInput.SetValue(GameManager.instance, inputSystemArray[lastMonitorId]);
			for (int i = 0; i < inputSystemArray.Length; i++)
			{
				UIInputSystem val2 = inputSystemArray[i];
				if (val2 != null)
				{
					if (lastMonitorId == i)
					{
						FieldInfo field = typeof(UIInputSystem).GetField("m_InputEvents", RedirectorUtils.allFlags);
						((Queue<GenericInputEvent>)field.GetValue(val2)).Clear();
						val2.Enable();
					}
					else
					{
						val2.Disable();
					}
				}
			}
			m_GlobalBarrier.blocked = lastMonitorId != 0;
		}

		private IEnumerator GetMonitorEnabledApplcations(int monitorId, View callerView)
		{
			yield return 0;
			Wrapper<string[]> wrapper = new Wrapper<string[]>();
			yield return DoCallToMonitorToGetApplicationsEnabled(monitorId, wrapper);
			callerView.TriggerEvent<string[]>("k45::euis.getMonitorEnabledApplcations->" + monitorId, wrapper.Value);
		}

		private IEnumerator GetVosEnabledApplcations(View callerView)
		{
			yield return 0;
			Wrapper<string[]> wrapper = new Wrapper<string[]>();
			yield return DoCallToMonitorToGetApplicationsEnabled(0, wrapper);
			callerView.TriggerEvent<string[]>("k45::euis.getVosEnabledApplcations->", wrapper.Value);
		}

		private IEnumerator DoCallToMonitorToGetApplicationsEnabled(int monitorId, Wrapper<string[]> appList)
		{
			if (monitorId != 0)
			{
				if (monitorId < 0 || monitorId >= uiSystemArray.Length || uiSystemArray[monitorId - 1] == null)
				{
					appList.Value = new string[0];
					yield break;
				}
				while (uiSystemArray[monitorId - 1].UIViews.Count < 1)
				{
					yield return (object)new WaitForSeconds(0.2f);
				}
			}
			View targetView = ((monitorId == 0) ? GameManager.instance.userInterface.view.View : uiSystemArray[monitorId - 1].UIViews[0].View);
			while (!targetView.IsReadyForBindings())
			{
				yield return (object)new WaitForSeconds(0.2f);
			}
			string[] localAppList = null;
			BoundEventHandle eventRegister = targetView.RegisterForEvent("k45::euis.listActiveAppsInMonitor->", (Delegate)(Action<string[]>)delegate(string[] x)
			{
				localAppList = x;
			});
			targetView.TriggerEvent<int>("k45::euis.listActiveAppsInMonitor", monitorId);
			int framesRemaining = 5;
			while (framesRemaining > 0 && localAppList == null)
			{
				yield return 0;
				framesRemaining--;
			}
			targetView.UnregisterFromEvent(eventRegister);
			appList.Value = localAppList;
		}

		private void RemoveAppFromMonitor(string appName, int monitorId)
		{
			if (monitorId > 0 && monitorId <= uiSystemArray.Length && uiSystemArray[monitorId - 1] != null)
			{
				DoWithEachMonitorView(delegate(View View)
				{
					View.TriggerEvent<int, string>("k45::euis.removeAppButton->", monitorId, appName);
				});
			}
		}

		private void AddAppToMonitor(string appName, int monitorId)
		{
			if (monitorId > 0 && monitorId <= uiSystemArray.Length && uiSystemArray[monitorId - 1] != null)
			{
				DoWithEachMonitorView(delegate(View View)
				{
					View.TriggerEvent<int, string>("k45::euis.reintroduceAppButton->", monitorId, appName);
				});
			}
		}

		private void DoWithEachMonitorView(Action<View> action)
		{
			UISystem[] array = uiSystemArray;
			foreach (UISystem val in array)
			{
				if (val != null && val.UIViews[0].enabled && val.UIViews[0].View.IsReadyForBindings())
				{
					action(val.UIViews[0].View);
				}
			}
		}

		private void SendEventToApp(string modderId, string appName, string eventName, params object[] args)
		{
			string appNameFull;
			View val2;
			if (eventName.StartsWith("^"))
			{
				appNameFull = "@" + modderId + "/" + appName;
				if (!(eventName == "^openApp"))
				{
					return;
				}
				if (args.Length >= 1 && args[0] is int num)
				{
					if (num < uiSystemArray.Length && num > 0)
					{
						UISystem val = uiSystemArray[num];
						if (val != null && val.UIViews[0].enabled)
						{
							val2 = val.UIViews[0].View;
							goto IL_0182;
						}
					}
					throw new Exception($"Invalid monitor index! It's out of bounds (1 to {uiSystemArray.Length - 1}) or it's not activated. Check the mod code! Value: {num}");
				}
				string[][] inactiveAppsMonitor = EuisModData.EuisDataInstance.GetDisabledAppsByMonitor();
				UISystem item = uiSystemArray.Select((UISystem x, int i) => (x, i)).FirstOrDefault<(UISystem, int)>(delegate((UISystem x, int i) x)
				{
					int result;
					if (x.i > 0)
					{
						var (val4, _) = x;
						if (val4 != null && val4.UIViews[0].enabled)
						{
							result = ((inactiveAppsMonitor == null || !inactiveAppsMonitor[x.i].Contains(appNameFull)) ? 1 : 0);
							goto IL_0056;
						}
					}
					result = 0;
					goto IL_0056;
					IL_0056:
					return (byte)result != 0;
				}).Item1;
				val2 = ((item != null) ? item.UIViews[0].View : null);
				if (val2 == null)
				{
					throw new Exception("The app " + appName + " is not active in any EUIS extra screen or there's no active EUIS extra screen! Check the mod code.");
				}
				goto IL_0182;
			}
			string text = modderId + "::" + appName + "." + eventName;
			LogUtils.DoLog("Calling event: {0}", text);
			UISystem[] array = uiSystemArray;
			foreach (UISystem val3 in array)
			{
				if (val3 != null && val3.UIViews[0].enabled && val3.UIViews[0].View.IsReadyForBindings())
				{
					View view = val3.UIViews[0].View;
					SendTriggerToView(args, text, view);
				}
			}
			return;
			IL_0182:
			val2.TriggerEvent<string>("k45::euis.switchToApp", appNameFull);
		}

		private static void SendTriggerToView(object[] args, string eventNameFull, View targetView)
		{
			switch ((args != null) ? args.Length : 0)
			{
			case 0:
				targetView.TriggerEvent(eventNameFull);
				break;
			case 1:
				targetView.TriggerEvent<object>(eventNameFull, args[0]);
				break;
			case 2:
				targetView.TriggerEvent<object, object>(eventNameFull, args[0], args[1]);
				break;
			case 3:
				targetView.TriggerEvent<object, object, object>(eventNameFull, args[0], args[1], args[2]);
				break;
			case 4:
				targetView.TriggerEvent<object, object, object, object>(eventNameFull, args[0], args[1], args[2], args[3]);
				break;
			case 5:
				targetView.TriggerEvent<object, object, object, object, object>(eventNameFull, args[0], args[1], args[2], args[3], args[4]);
				break;
			case 6:
				targetView.TriggerEvent<object, object, object, object, object, object>(eventNameFull, args[0], args[1], args[2], args[3], args[4], args[5]);
				break;
			case 7:
				targetView.TriggerEvent<object, object, object, object, object, object, object>(eventNameFull, args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
				break;
			default:
				targetView.TriggerEvent<object, object, object, object, object, object, object, object>(eventNameFull, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
				break;
			}
		}

		internal void RegisterApplication(IEUISAppRegister appRegisterData)
		{
			if (!ValidateAppRegister(appRegisterData))
			{
				return;
			}
			for (int i = 0; i < uiSystemArray.Length; i++)
			{
				UISystem val = uiSystemArray[i];
				if (val != null && val.UIViews[0].View.IsReadyForBindings())
				{
					if (DebugMode)
					{
						LogUtils.DoLog($"Sending app for monitor {i + 1}: {EUISAppRegisterExtensions.GetFullAppName(appRegisterData)}");
					}
					val.UIViews[0].View.TriggerEvent<string, string, string, string, string>("k45::euis.registerApplication", EUISAppRegisterExtensions.GetFullAppName(appRegisterData), appRegisterData.DisplayName, appRegisterData.UrlJs, appRegisterData.UrlCss, appRegisterData.UrlIcon);
					registeredApplications.Add(appRegisterData);
				}
			}
		}

		internal void RegisterModActions(IEUISModRegister modRegisterData, int targetMonitor)
		{
			if (ValidateModRegister(modRegisterData))
			{
				string internalAppName = modRegisterData.ModAcronym;
				string modderId = modRegisterData.ModderIdentifier;
				modRegisterData.OnGetEventEmitter(delegate(string eventName, object[] args)
				{
					SendEventToApp(modderId, internalAppName, eventName, args);
				});
				modRegisterData.OnGetCallsBinder(delegate(string eventName, Delegate action)
				{
					RegisterCall(modRegisterData, eventName, action, targetMonitor);
				});
				modRegisterData.OnGetEventsBinder(delegate(string eventName, Delegate action)
				{
					RegisterEvent(modRegisterData, eventName, action, targetMonitor);
				});
			}
		}

		private void RegisterCall(IEUISModRegister appRegisterData, string callName, Delegate action, int targetMonitor)
		{
			if (targetMonitor < 0)
			{
				for (int i = 0; i < uiSystemArray.Length; i++)
				{
					RegisterCallInDisplay(appRegisterData, callName, action, i);
				}
			}
			else
			{
				RegisterCallInDisplay(appRegisterData, callName, action, targetMonitor - 1);
			}
		}

		private void RegisterCallInDisplay(IEUISModRegister appRegisterData, string callName, Delegate action, int displayId)
		{
			UISystem uiSys = uiSystemArray[displayId];
			int monitorId;
			string callAddress;
			if (uiSys != null)
			{
				monitorId = displayId + 1;
				callAddress = appRegisterData.ModderIdentifier + "::" + appRegisterData.ModAcronym + "." + callName;
				LogUtils.DoLog("Sending call '{0}' for register @ Monitor #'{1}'", callAddress, monitorId);
				if (uiSys.UIViews[0].View.IsReadyForBindings())
				{
					registerCall();
				}
				else
				{
					uiSys.UIViews[0].Listener.ReadyForBindings += registerCall;
				}
			}
			void registerCall()
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				uiSys.UIViews[0].View.BindCall(callAddress, action);
				LogUtils.DoLog("Registered call '{0}' @ Monitor #'{1}'", callAddress, monitorId);
			}
		}

		private void RegisterEvent(IEUISModRegister appRegisterData, string eventName, Delegate action, int targetMonitor)
		{
			if (targetMonitor < 0)
			{
				for (int i = 0; i < uiSystemArray.Length; i++)
				{
					RegisterEventToDisplay(appRegisterData, eventName, action, i);
				}
			}
			else
			{
				RegisterEventToDisplay(appRegisterData, eventName, action, targetMonitor - 1);
			}
		}

		private void RegisterEventToDisplay(IEUISModRegister appRegisterData, string eventName, Delegate action, int displayId)
		{
			UISystem uiSys = uiSystemArray[displayId];
			int monitorId;
			string eventAddress;
			if (uiSys != null)
			{
				monitorId = displayId + 1;
				eventAddress = appRegisterData.ModderIdentifier + "::" + appRegisterData.ModAcronym + "." + eventName;
				LogUtils.DoLog("Sending event '{0}' for register @ Monitor #'{1}'", eventAddress, monitorId);
				if (uiSys.UIViews[0].View.IsReadyForBindings())
				{
					registerCall();
				}
				else
				{
					uiSys.UIViews[0].Listener.ReadyForBindings += registerCall;
				}
			}
			void registerCall()
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				uiSys.UIViews[0].View.RegisterForEvent(eventAddress, action);
				LogUtils.DoLog("Registered for event '{0}' @ Monitor #'{1}'", eventAddress, monitorId);
			}
		}

		private bool ValidateAppRegister(IEUISAppRegister appRegisterData)
		{
			if (!Regex.IsMatch(appRegisterData.ModderIdentifier, "^[a-z0-9\\-]{3,10}$"))
			{
				LogUtils.DoWarnLog("Invalid app register for type '" + ((object)appRegisterData).GetType().FullName + "': Modder name must be 3-10 characters and must contain only characters in this regex: [a-z0-9\\-]");
				return false;
			}
			if (!Regex.IsMatch(appRegisterData.ModAcronym, "^[a-z0-9]{2,5}$"))
			{
				LogUtils.DoWarnLog("Invalid app register for type '" + ((object)appRegisterData).GetType().FullName + "': Mod acronym must be 2-5 characters and must contain only characters in this regex: [a-z0-9]");
				return false;
			}
			if (!Regex.IsMatch(appRegisterData.ModAppIdentifier, "^[a-z0-9\\-]{0,24}$"))
			{
				LogUtils.DoWarnLog("Invalid app register for type '" + ((object)appRegisterData).GetType().FullName + "': App name must be 0-24 characters and must contain only characters in this regex: [a-z0-9\\-]");
				return false;
			}
			if (!appRegisterData.UrlJs.StartsWith("coui://") && !appRegisterData.UrlJs.StartsWith("http://localhost"))
			{
				LogUtils.DoWarnLog("Invalid app register for type '" + ((object)appRegisterData).GetType().FullName + "': The application js must be registered in the game ui system (under coui://) or under localhost if under development (starting with http://localhost).");
				return false;
			}
			if (!appRegisterData.UrlCss.StartsWith("coui://") && !appRegisterData.UrlCss.StartsWith("http://localhost"))
			{
				LogUtils.DoWarnLog("Invalid app register for type '" + ((object)appRegisterData).GetType().FullName + "': The application css must be registered in the game ui system (under coui://) or under localhost if under development (starting with http://localhost).");
				return false;
			}
			if (!appRegisterData.UrlIcon.StartsWith("coui://"))
			{
				LogUtils.DoWarnLog("Invalid app register for type '" + ((object)appRegisterData).GetType().FullName + "': The application icon must be registered in the game ui system (under coui://).");
				return false;
			}
			return true;
		}

		internal static bool ValidateModRegister(IEUISModRegister appRegisterData)
		{
			if (!Regex.IsMatch(appRegisterData.ModderIdentifier, "^[a-z0-9\\-]{3,10}$"))
			{
				LogUtils.DoWarnLog("Invalid app register for type '" + ((object)appRegisterData).GetType().FullName + "': Modder name must be 3-10 characters and must contain only characters in this regex: [a-z0-9\\-]");
				return false;
			}
			if (!Regex.IsMatch(appRegisterData.ModAcronym, "^[a-z0-9]{2,5}$"))
			{
				LogUtils.DoWarnLog("Invalid app register for type '" + ((object)appRegisterData).GetType().FullName + "': Mod acronym must be 2-5 characters and must contain only characters in this regex: [a-z0-9]");
				return false;
			}
			if (appRegisterData.OnGetCallsBinder == null)
			{
				LogUtils.DoWarnLog("Invalid app register for type '" + ((object)appRegisterData).GetType().FullName + "': OnGetCallsBinder must not be null!");
				return false;
			}
			if (appRegisterData.OnGetEventsBinder == null)
			{
				LogUtils.DoWarnLog("Invalid app register for type '" + ((object)appRegisterData).GetType().FullName + "': OnGetEventsBinder must not be null!");
				return false;
			}
			if (appRegisterData.OnGetEventEmitter == null)
			{
				LogUtils.DoWarnLog("Invalid app register for type '" + ((object)appRegisterData).GetType().FullName + "': OnGetEventEmitter must not be null!");
				return false;
			}
			return true;
		}

		internal void UnregisterApplication(string appName)
		{
			for (int i = 0; i < uiSystemArray.Length; i++)
			{
				UISystem val = uiSystemArray[i];
				if (val != null && val.UIViews[0].View.IsReadyForBindings())
				{
					if (DebugMode)
					{
						LogUtils.DoLog($"Removing app from monitor {i + 1}: {appName}");
					}
					val.UIViews[0].View.TriggerEvent<string>("k45::euis.unregisterApplication", appName);
				}
			}
		}

		internal void OnMonitorActivityChanged()
		{
			for (int i = 0; i < uiSystemArray.Length; i++)
			{
				UISystem val = uiSystemArray[i];
				if (val != null && val.UIViews[0].View.IsReadyForBindings())
				{
					val.UIViews[0].View.TriggerEvent<int>("k45::euis.activeMonitorMaskChange->", EuisModData.EuisDataInstance.InactiveMonitors);
				}
			}
		}

		public void DoWhenReady(Action action)
		{
			OnReady += action;
			if (Ready)
			{
				action();
			}
		}

		public void DoOnceWhenReady(Action<int> action)
		{
			OnceOnReady += action;
		}

		internal void OnInterfaceStyleChanged()
		{
			DoWithEachMonitorView(delegate(View View)
			{
				View.TriggerEvent<string>("k45::euis.interfaceStyle->", SharedSettings.instance.userInterface.interfaceStyle);
			});
		}
	}
	[BepInPlugin("ExtraUIScreens", "ExtraUIScreens", "0.0.2.65534")]
	public class EUIBepinexPlugin : BaseUnityPlugin
	{
		public void Awake()
		{
			LogUtils.LogsEnabled = false;
			LogUtils.Logger = ((BaseUnityPlugin)this).Logger;
			LogUtils.DoInfoLog("STARTING MOD!");
			Redirector.PatchAll();
		}
	}
	public class ExtraUIScreensMod : BasicIMod, IMod
	{
		private class EUISAppRegisterCurrent : IEUISAppRegister
		{
			public string AppName { get; set; }

			public string DisplayName { get; set; }

			public string UrlJs { get; set; }

			public string UrlCss { get; set; }

			public string UrlIcon { get; set; }

			public string ModderIdentifier { get; set; }

			public string ModAcronym { get; set; }

			public string ModAppIdentifier { get; set; }
		}

		private class EUISOverlayRegisterCurrent : IEUISOverlayRegister
		{
			public string AppName { get; set; }

			public string DisplayName { get; set; }

			public string UrlJs { get; set; }

			public string UrlCss { get; set; }

			public string UrlIcon { get; set; }

			public string ModderIdentifier { get; set; }

			public string ModAcronym { get; set; }

			public string ModAppIdentifier { get; set; }
		}

		private class EUISModRegisterCurrent : IEUISModRegister
		{
			public Action<Action<string, object[]>> OnGetEventEmitter { get; set; }

			public Action<Action<string, Delegate>> OnGetEventsBinder { get; set; }

			public Action<Action<string, Delegate>> OnGetCallsBinder { get; set; }

			public string ModderIdentifier { get; set; }

			public string ModAcronym { get; set; }
		}

		private GameObject euisGO;

		public new static ExtraUIScreensMod Instance => (ExtraUIScreensMod)BasicIMod.Instance;

		public override string SimpleName => "Extra UI Screens Mod";

		public override string SafeName => "ExtraScreens";

		public override string Acronym => "EUIS";

		public override string Description => "Adds extra screens!";

		public override void DoOnCreateWorld(UpdateSystem updateSystem)
		{
			LoadExtraScreenFromMods();
		}

		public override void OnDispose()
		{
			Object.Destroy((Object)(object)euisGO);
		}

		public override void DoOnLoad()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			euisGO = new GameObject("EUIS");
			euisGO.AddComponent<EuisScreenManager>();
		}

		private static void LoadExtraScreenFromMods()
		{
			HashSet<string> hashSet = (from x in Directory.GetFiles(Path.Combine(Path.GetDirectoryName(BasicIMod.ModInstallFolder), ".."), "*.euis", SearchOption.AllDirectories)
				select x.Trim()).ToHashSet();
			LogUtils.DoLog("EUIS Files found:\n " + string.Join("\n", hashSet));
			foreach (string assemblyPath in hashSet)
			{
				try
				{
					LogUtils.DoLog("Loading assemblyPath: " + assemblyPath);
					Assembly assembly = Assembly.LoadFile(assemblyPath);
					LogUtils.DoLog($"Loaded assemblyPath: {assembly}");
					LogUtils.DoLog($"Instance = {EuisScreenManager.Instance}");
					EuisScreenManager.Instance.DoWhenReady(delegate
					{
						IEUISAppRegister[] allLoadableClassesByTypeName2 = BridgeUtils.GetAllLoadableClassesByTypeName<IEUISAppRegister, IEUISAppRegister>(() => (IEUISAppRegister)(object)new EUISAppRegisterCurrent(), assembly);
						if (BasicIMod.DebugMode)
						{
							LogUtils.DoLog("[ESOS] Apps to load from '{0}':\n " + string.Join("\n", allLoadableClassesByTypeName2.Select((IEUISAppRegister x) => x.DisplayName)), assemblyPath);
						}
						IEUISAppRegister[] array2 = allLoadableClassesByTypeName2;
						foreach (IEUISAppRegister appRegisterData in array2)
						{
							EuisScreenManager.Instance.RegisterApplication(appRegisterData);
						}
					});
					EuisScreenManager.Instance.DoOnceWhenReady(delegate(int x)
					{
						IEUISModRegister[] allLoadableClassesByTypeName = BridgeUtils.GetAllLoadableClassesByTypeName<IEUISModRegister, IEUISModRegister>(() => (IEUISModRegister)(object)new EUISModRegisterCurrent(), assembly);
						if (BasicIMod.DebugMode)
						{
							LogUtils.DoLog("[ESOS] Apps to load from '{0}':\n " + string.Join("\n", allLoadableClassesByTypeName.Select((IEUISModRegister x) => x.ModAcronym)), assemblyPath);
						}
						IEUISModRegister[] array = allLoadableClassesByTypeName;
						foreach (IEUISModRegister modRegisterData in array)
						{
							EuisScreenManager.Instance.RegisterModActions(modRegisterData, x);
						}
					});
				}
				catch (Exception e)
				{
					LogUtils.DoErrorLog("Error loading euis assembly file @ {0}", e, assemblyPath);
				}
			}
		}

		public override BasicModData CreateSettingsFile()
		{
			return new EuisModData((IMod)(object)this);
		}
	}
	public class UIInputSystemOverrides : Redirector, IRedirectableWorldless
	{
		public void Awake()
		{
			AddRedirect(typeof(UIInputSystem).GetMethod("SetMousePosition", RedirectorUtils.allFlags), ((object)this).GetType().GetMethod("BeforeSetMousePosition", RedirectorUtils.allFlags));
		}

		private static bool BeforeSetMousePosition(ref UIView uiView, ref Vector2 mousePosition, ref MouseEventDataCached mouseData)
		{
			//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)
			int num = (int)Display.RelativeMouseAt(Input.mousePosition).z;
			((MouseEventData)mouseData).X = (int)(mousePosition.x / (float)Display.displays[num].renderingWidth * (float)uiView.width);
			((MouseEventData)mouseData).Y = (int)((1f - mousePosition.y / (float)Display.displays[num].renderingHeight) * (float)uiView.height);
			return false;
		}
	}
	public class InterfaceSettingsOverrides : Redirector, IRedirectableWorldless
	{
		public void Awake()
		{
			AddRedirect(typeof(InterfaceSettings).GetProperty("interfaceStyle", RedirectorUtils.allFlags).SetMethod, null, ((object)this).GetType().GetMethod("AfterSetInterfaceStyle", RedirectorUtils.allFlags));
		}

		private static void AfterSetInterfaceStyle()
		{
			EuisScreenManager.Instance?.OnInterfaceStyleChanged();
		}
	}
	public class GameManagerOverrides : Redirector, IRedirectableWorldless
	{
		public void Awake()
		{
			AddRedirect(typeof(GameManager).GetMethod("Load", RedirectorUtils.allFlags, null, new Type[4]
			{
				typeof(GameMode),
				typeof(Purpose),
				typeof(AsyncReadDescriptor),
				typeof(Guid)
			}, null), ((object)this).GetType().GetMethod("BeforeSceneLoad", RedirectorUtils.allFlags), ((object)this).GetType().GetMethod("AfterSceneLoad", RedirectorUtils.allFlags));
		}

		private static void BeforeSceneLoad()
		{
			EuisScreenManager.Instance.RunOnBeforeSceneLoad();
		}

		private static void AfterSceneLoad(Task<bool> __result)
		{
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "ExtraUIScreens";

		public const string PLUGIN_NAME = "ExtraUIScreens";

		public const string PLUGIN_VERSION = "0.0.2.65534";
	}
}
namespace Belzont.AssemblyUtility
{
	[AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)]
	internal sealed class KlyteModCanonVersionAttribute : Attribute
	{
		public string CanonVersion { get; }

		public string ThunderstoreVersion { get; }

		public KlyteModCanonVersionAttribute(string canonVersion, string thunderstore)
		{
			CanonVersion = canonVersion;
			ThunderstoreVersion = thunderstore;
		}
	}
}
namespace Belzont.Utils
{
	public static class BridgeUtils
	{
		public static object[] GetAllLoadableClassesInAssemblyList(Type t, IEnumerable<Assembly> assemblies = null)
		{
			if (assemblies == null)
			{
				assemblies = AppDomain.CurrentDomain.GetAssemblies();
			}
			return (from x in assemblies.SelectMany(delegate(Assembly s)
				{
					try
					{
						return s.GetExportedTypes();
					}
					catch (ReflectionTypeLoadException ex2)
					{
						return ex2.Types;
					}
					catch (Exception arg)
					{
						LogUtils.DoWarnLog($"Error exporting types from assembly {s}\n{arg}");
						return new Type[0];
					}
				}).Where(delegate(Type p)
				{
					try
					{
						IEnumerable<string> enumerable = CollectionExtensions.AddItem<string>(from x in p.GetInterfaces()
							select x.Name, p.BaseType.Name);
						LogUtils.DoLog("srcs " + p.Name + " => " + string.Join("; ", enumerable));
						return enumerable.Any((string x) => x == t.Name) && p.IsClass && !p.IsAbstract;
					}
					catch
					{
						return false;
					}
				}).Select(delegate(Type x)
				{
					try
					{
						LogUtils.DoLog("Trying to instantiate '{0}'", x.AssemblyQualifiedName);
						return x.GetConstructor(new Type[0]).Invoke(new object[0]);
					}
					catch (Exception ex)
					{
						LogUtils.DoLog("Failed instantiate '{0}': {1}", x.AssemblyQualifiedName, ex);
						return null;
					}
				})
				where x != null
				select x).ToArray();
		}

		public static T[] GetAllLoadableClassesInAppDomain<T>() where T : class
		{
			return GetAllLoadableClassesInAssemblyList(typeof(T)).Cast<T>().ToArray();
		}

		public static T[] GetAllLoadableClassesByTypeName<T, U>(Func<U> destinationGenerator, Assembly targetAssembly = null) where T : class where U : T
		{
			string fullName = typeof(T).FullName;
			Type[] allInterfacesWithTypeName = GetAllInterfacesWithTypeName(fullName);
			LogUtils.DoLog("Classes with same name of '{0}' found: {1}", fullName, allInterfacesWithTypeName.Length);
			return (from x in allInterfacesWithTypeName.SelectMany(delegate(Type x)
				{
					object[] allLoadableClassesInAssemblyList = GetAllLoadableClassesInAssemblyList(x, new Assembly[1] { targetAssembly });
					LogUtils.DoLog("Objects loaded: {0}", allLoadableClassesInAssemblyList.Length);
					return allLoadableClassesInAssemblyList;
				})
				select TryConvertClass<T, U>(x, destinationGenerator) into x
				where x != null
				select x).ToArray();
		}

		public static Type[] GetAllInterfacesWithTypeName(string typeName)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			return assemblies.SelectMany(delegate(Assembly s)
			{
				try
				{
					return s.GetExportedTypes();
				}
				catch
				{
					return new Type[0];
				}
			}).Where(delegate(Type p)
			{
				try
				{
					return p.FullName == typeName && p.IsInterface;
				}
				catch
				{
					return false;
				}
			}).ToArray();
		}

		public static T TryConvertClass<T, U>(object srcValue, Func<U> destinationGenerator) where U : T
		{
			LogUtils.DoLog("Trying to convert {0} to class {1}", srcValue.GetType().FullName, typeof(T).FullName);
			if (srcValue.GetType().IsAssignableFrom(typeof(T)))
			{
				return (T)srcValue;
			}
			U val = destinationGenerator();
			Type type = srcValue.GetType();
			Type type2 = val.GetType();
			PropertyInfo[] properties = typeof(T).GetProperties(RedirectorUtils.allFlags);
			foreach (PropertyInfo propertyInfo in properties)
			{
				LogUtils.DoLog("fieldOnItf: {0} {1}=>{2}", TypeExtensions.GetReturnType((MemberInfo)propertyInfo).FullName, typeof(T).FullName, propertyInfo.Name);
				PropertyInfo property = type.GetProperty(propertyInfo.Name, RedirectorUtils.allFlags);
				LogUtils.DoLog("fieldOnSrc: {0} {1}=>{2}", TypeExtensions.GetReturnType((MemberInfo)property).FullName, type.FullName, property.Name);
				PropertyInfo property2 = type2.GetProperty(propertyInfo.Name, RedirectorUtils.allFlags);
				LogUtils.DoLog("fieldOnDst: {0} {1}=>{2}", TypeExtensions.GetReturnType((MemberInfo)property2).FullName, type2.FullName, property2.Name);
				if ((object)property != null && property.PropertyType.IsAssignableFrom(property2.PropertyType))
				{
					property2.SetValue(val, property.GetValue(srcValue));
				}
			}
			return (T)(object)val;
		}
	}
	public static class ColorExtensions
	{
		public static string ToRGBA(this Color32 color)
		{
			//IL_000d: 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)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			return $"{color.r:X2}{color.g:X2}{color.b:X2}{color.a:X2}";
		}

		public static string ToRGB(this Color32 color, bool withHashtag = false)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			return string.Format("{0}{1:X2}{2:X2}{3:X2}", withHashtag ? "#" : "", color.r, color.g, color.b);
		}

		public static string ToRGBA(this Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Color32.op_Implicit(color).ToRGBA();
		}

		public static string ToRGB(this Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Color32.op_Implicit(color).ToRGB();
		}

		public static Color SetBrightness(this Color color, float brightness)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(color, ref num, ref num2, ref num3);
			return Color.HSVToRGB(num, num2, brightness);
		}

		public static Color ClampSaturation(this Color color, float maxSaturation)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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)
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(color, ref num, ref num2, ref num3);
			return Color.HSVToRGB(num, Mathf.Min(num2, maxSaturation), num3);
		}

		public static Color MultiplyChannelsButAlpha(this Color color, Color other)
		{
			//IL_0000: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			return new Color(color.r * other.r, color.g * other.g, color.b * other.b, color.a);
		}

		public static Color32 FromRGBA(string rgba)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			long value = Convert.ToInt64(rgba, 16);
			return FromRGBA(value);
		}

		public static Color32 FromRGBA(long value)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			return new Color32((byte)((value & 0xFF000000u) >> 24), (byte)((value & 0xFF0000) >> 16), (byte)((value & 0xFF00) >> 8), (byte)(value & 0xFF));
		}

		public static Color32 FromRGB(string rgb, bool withHashtag = false)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (withHashtag)
			{
				string text = rgb;
				rgb = text.Substring(1, text.Length - 1);
			}
			int value = Convert.ToInt32(rgb, 16);
			return FromRGB(value);
		}

		public static Color32 FromRGB(int value)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			return new Color32((byte)((value & 0xFF0000) >> 16), (byte)((value & 0xFF00) >> 8), (byte)((uint)value & 0xFFu), byte.MaxValue);
		}

		public static Color ContrastColor(this Color color, bool grayAsWhite = false)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (color == default(Color))
			{
				return Color.black;
			}
			float num = 0.299f * color.r + 0.587f * color.g + 0.114f * color.b;
			float num2 = ((!((double)num > 0.5)) ? (grayAsWhite ? 0.5f : 1f) : 0f);
			return new Color(num2, num2, num2, 1f);
		}
	}
	public class KFileUtils
	{
		public static readonly string BASE_FOLDER_PATH = Application.persistentDataPath + Path.DirectorySeparatorChar + "Klyte45Mods" + Path.DirectorySeparatorChar;

		public static FileInfo EnsureFolderCreation(string folderName)
		{
			if (File.Exists(folderName) && (File.GetAttributes(folderName) & FileAttributes.Directory) != FileAttributes.Directory)
			{
				File.Delete(folderName);
			}
			if (!Directory.Exists(folderName))
			{
				Directory.CreateDirectory(folderName);
			}
			return new FileInfo(folderName);
		}

		public static bool IsFileCreated(string fileName)
		{
			return File.Exists(fileName);
		}

		public static string[] GetAllFilesEmbeddedAtFolder(string packageDirectory, string extension)
		{
			Assembly refAssemblyMod = KResourceLoader.RefAssemblyMod;
			string folderName = "Klyte." + packageDirectory;
			return (from r in refAssemblyMod.GetManifestResourceNames()
				where r.StartsWith(folderName) && r.EndsWith(extension)
				select r).Select(delegate(string r)
			{
				int num = folderName.Length + 1;
				return r.Substring(num, r.Length - num);
			}).ToArray();
		}
	}
	public static class KResourceLoader
	{
		public static Assembly RefAssemblyMod => BasicIMod.Instance.GetType().Assembly;

		private static string NamespaceMod => BasicIMod.Instance.SafeName + ".";

		public static Assembly RefAssemblyBelzont => typeof(KResourceLoader).Assembly;

		public static byte[] LoadResourceDataMod(string name)
		{
			return LoadResourceData(NamespaceMod + name, RefAssemblyMod);
		}

		public static byte[] LoadResourceDataBelzont(string name)
		{
			return LoadResourceData("Belzont." + name, RefAssemblyBelzont);
		}

		private static byte[] LoadResourceData(string name, Assembly refAssembly)
		{
			UnmanagedMemoryStream unmanagedMemoryStream = (UnmanagedMemoryStream)refAssembly.GetManifestResourceStream(name);
			if (unmanagedMemoryStream == null)
			{
				LogUtils.DoLog("Could not find resource: " + name);
				return null;
			}
			BinaryReader binaryReader = new BinaryReader(unmanagedMemoryStream);
			return binaryReader.ReadBytes((int)unmanagedMemoryStream.Length);
		}

		public static string LoadResourceStringMod(string name)
		{
			return LoadResourceString(NamespaceMod + name, RefAssemblyMod);
		}

		public static string LoadResourceStringBelzont(string name)
		{
			return LoadResourceString("Belzont." + name, RefAssemblyBelzont);
		}

		private static string LoadResourceString(string name, Assembly refAssembly)
		{
			UnmanagedMemoryStream unmanagedMemoryStream = (UnmanagedMemoryStream)refAssembly.GetManifestResourceStream(name);
			if (unmanagedMemoryStream == null)
			{
				LogUtils.DoLog("Could not find resource: " + name);
				return null;
			}
			StreamReader streamReader = new StreamReader(unmanagedMemoryStream);
			return streamReader.ReadToEnd();
		}

		public static IEnumerable<string> LoadResourceStringLinesMod(string name)
		{
			return LoadResourceStringLines(NamespaceMod + name, RefAssemblyMod);
		}

		public static IEnumerable<string> LoadResourceStringLinesBelzont(string name)
		{
			return LoadResourceStringLines("Belzont." + name, RefAssemblyBelzont);
		}

		private static IEnumerable<string> LoadResourceStringLines(string name, Assembly refAssembly)
		{
			using UnmanagedMemoryStream stream = (UnmanagedMemoryStream)refAssembly.GetManifestResourceStream(name);
			if (stream == null)
			{
				LogUtils.DoLog("Could not find resource: " + name);
				yield break;
			}
			using StreamReader reader = new StreamReader(stream);
			while (true)
			{
				string text;
				string line = (text = reader.ReadLine());
				if (text == null)
				{
					break;
				}
				yield return line;
			}
		}
	}
	public static class LogUtils
	{
		private static ILog logOutput;

		private static ILog LogOutput
		{
			get
			{
				if (logOutput == null)
				{
					logOutput = LogManager.GetLogger("Mods_K45", true);
					logOutput.effectivenessLevel = Level.Info;
				}
				return logOutput;
			}
		}

		public static bool LogsEnabled { get; internal set; }

		internal static ManualLogSource Logger { get; set; }

		private static string LogLineStart(string level)
		{
			return (!LogsEnabled) ? "" : $"[{BasicIMod.Instance.Acronym,-4}] [v{BasicIMod.FullVersion,-16}] [{level,-8}] ";
		}

		public static void DoLog(string format, params object[] args)
		{
			try
			{
				if (!LogsEnabled)
				{
					ManualLogSource logger = Logger;
					if (logger != null)
					{
						logger.LogDebug((object)string.Format(LogLineStart("DEBUG") + format, args));
					}
				}
				else if (BasicIMod.DebugMode)
				{
					Level effectivenessLevel = LogOutput.effectivenessLevel;
					LogOutput.effectivenessLevel = Level.Debug;
					LogOutput.Log(Level.Debug, string.Format(LogLineStart("DEBUG") + format, args), (Exception)null);
					LogOutput.effectivenessLevel = effectivenessLevel;
				}
			}
			catch (Exception e)
			{
				LogCaughtLogException(format, args, e);
			}
		}

		public static void DoWarnLog(string format, params object[] args)
		{
			try
			{
				if (!LogsEnabled)
				{
					ManualLogSource logger = Logger;
					if (logger != null)
					{
						logger.LogWarning((object)string.Format(LogLineStart("WARNING") + format, args));
					}
				}
				else
				{
					LogOutput.Log(Level.Warn, string.Format(LogLineStart("WARNING") + format, args), (Exception)null);
				}
			}
			catch (Exception e)
			{
				LogCaughtLogException(format, args, e);
			}
		}

		private static void LogCaughtLogException(string format, object[] args, Exception e)
		{
			if (!LogsEnabled)
			{
				ManualLogSource logger = Logger;
				if (logger != null)
				{
					logger.LogFatal((object)string.Format(string.Format("{0} Erro ao fazer log: {{0}} (args = {{1}})\n{1}", LogLineStart("SEVERE"), e), format, (args == null) ? "[]" : string.Join(",", args.Select((object x) => (x != null) ? x.ToString() : "--NULL--").ToArray())));
				}
			}
			else
			{
				LogOutput.Log(Level.Warn, string.Format(LogLineStart("SEVERE") + " Erro ao fazer log: {0} (args = {1})", format, (args == null) ? "[]" : string.Join(",", args.Select((object x) => (x != null) ? x.ToString() : "--NULL--").ToArray())), e);
			}
		}

		public static void DoInfoLog(string format, params object[] args)
		{
			try
			{
				if (!LogsEnabled)
				{
					ManualLogSource logger = Logger;
					if (logger != null)
					{
						logger.LogInfo((object)string.Format(LogLineStart("INFO") + format, args));
					}
				}
				else
				{
					LogOutput.Log(Level.Info, string.Format(LogLineStart("INFO") + format, args), (Exception)null);
				}
			}
			catch (Exception e)
			{
				LogCaughtLogException(format, args, e);
			}
		}

		public static void DoErrorLog(string format, Exception e = null, params object[] args)
		{
			try
			{
				if (!LogsEnabled)
				{
					ManualLogSource logger = Logger;
					if (logger != null)
					{
						logger.LogError((object)string.Format(LogLineStart("ERROR") + format + $"\n{e}", args));
					}
				}
				else
				{
					LogOutput.Log(Level.Error, string.Format(LogLineStart("ERROR") + format, args), e);
				}
			}
			catch (Exception e2)
			{
				if (e != null)
				{
					if (!LogsEnabled)
					{
						ManualLogSource logger2 = Logger;
						if (logger2 != null)
						{
							logger2.LogError((object)string.Format(LogLineStart("ERROR") + $"An exception has occurred.\n{e}"));
						}
					}
					else
					{
						LogOutput.Log(Level.Error, LogLineStart("ERROR") + "An exception has occurred.", e);
					}
				}
				LogCaughtLogException(format, args, e2);
			}
		}

		public static void PrintMethodIL(IEnumerable<CodeInstruction> inst, bool force = false)
		{
			if (force || BasicIMod.DebugMode)
			{
				int i = 0;
				DoInfoLog(LogLineStart("TRANSPILLED") + "\n\t" + string.Join("\n\t", inst.Select((CodeInstruction x) => $"{i++:D8} {x.opcode,-10} {ParseOperand(inst, x.operand)}").ToArray()), null);
			}
		}

		public static string GetLinesPointingToLabel(IEnumerable<CodeInstruction> inst, Label lbl)
		{
			int i = 0;
			return "\t" + string.Join("\n\t", (from x in inst
				select Tuple.New<CodeInstruction, string>(x, $"{i++:D8} {x.opcode.ToString().PadRight(10)} {ParseOperand(inst, x.operand)}") into x
				where x.First.operand is Label label && label == lbl
				select x.Second).ToArray());
		}

		public static string ParseOperand(IEnumerable<CodeInstruction> instr, object operand)
		{
			if (operand == null)
			{
				return null;
			}
			if (operand is Label)
			{
				Label lbl = (Label)operand;
				if (true)
				{
					return "LBL: " + (from x in instr.Select((CodeInstruction x, int y) => Tuple.New<CodeInstruction, int>(x, y))
						where x.First.labels.Contains(lbl)
						select $"{x.Second:D8} {x.First.opcode,-10} {ParseOperand(instr, x.First.operand)}").FirstOrDefault();
				}
			}
			return operand.ToString() + $" (Type={operand.GetType()})";
		}
	}
	public static class NameSystemExtensions
	{
		public class ValuableName
		{
			public readonly string __Type;

			public readonly string name;

			public readonly string nameId;

			public readonly string[] nameArgs;

			internal ValuableName(Name name)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: 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_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Expected I4, but got Unknown
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				NameType nameType = name.GetNameType();
				NameType val = nameType;
				NameType val2 = val;
				switch ((int)val2)
				{
				default:
					__Type = "names.CustomName";
					this.name = name.GetNameID();
					nameId = null;
					nameArgs = null;
					break;
				case 1:
					__Type = "names.LocalizedName";
					this.name = null;
					nameId = name.GetNameID();
					nameArgs = null;
					break;
				case 2:
					__Type = "names.FormattedName";
					this.name = null;
					nameId = name.GetNameID();
					nameArgs = name.GetNameArgs();
					break;
				}
			}
		}

		private static readonly FieldInfo NameTypeFI = typeof(Name).GetField("m_NameType", RedirectorUtils.allFlags);

		private static readonly FieldInfo NameIDFI = typeof(Name).GetField("m_NameID", RedirectorUtils.allFlags);

		private static readonly FieldInfo NameArgsFI = typeof(Name).GetField("m_NameArgs", RedirectorUtils.allFlags);

		public static NameType GetNameType(this Name name)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			return (NameType)NameTypeFI.GetValue(name);
		}

		public static string GetNameID(this Name name)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return (string)NameIDFI.GetValue(name);
		}

		public static string[] GetNameArgs(this Name name)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return (string[])NameArgsFI.GetValue(name);
		}

		internal static ValuableName ToValueableName(this Name name)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return new ValuableName(name);
		}
	}
	public sealed class RedirectorUtils
	{
		public static readonly BindingFlags allFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.GetProperty;
	}
	public interface IRedirectableWorldless
	{
	}
	public interface IRedirectable
	{
		void DoPatches(World world);
	}
	public class Redirector : MonoBehaviour
	{
		private static Harmony m_harmony;

		private static readonly List<MethodInfo> m_patches = new List<MethodInfo>();

		private static readonly List<Action> m_onUnpatchActions = new List<Action>();

		private readonly List<MethodInfo> m_detourList = new List<MethodInfo>();

		public static readonly MethodInfo semiPreventDefaultMI = ((Func<bool>)delegate
		{
			StackTrace stackTrace = new StackTrace();
			StackFrame[] frames = stackTrace.GetFrames();
			LogUtils.DoLog("SemiPreventDefault fullStackTrace: \r\n " + Environment.StackTrace);
			for (int i = 2; i < frames.Length; i++)
			{
				if (frames[i].GetMethod().DeclaringType.ToString().StartsWith("Klyte."))
				{
					return false;
				}
			}
			return true;
		}).Method;

		private static readonly List<IRedirectable> worldDependantRedirectors = new List<IRedirectable>();

		public static Harmony Harmony
		{
			get
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Expected O, but got Unknown
				if (m_harmony == null)
				{
					List<Type> subtypesRecursive = ReflectionUtils.GetSubtypesRecursive(typeof(BasicIMod), null);
					m_harmony = new Harmony("com.klyte.redirectors." + subtypesRecursive.First().Name);
				}
				return m_harmony;
			}
		}

		public static bool PreventDefault()
		{
			return false;
		}

		public void AddRedirect(MethodInfo oldMethod, MethodInfo newMethodPre, MethodInfo newMethodPost = null, MethodInfo transpiler = null)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			LogUtils.DoLog($"Adding patch! {oldMethod.DeclaringType} {oldMethod}");
			object obj = m_detourList;
			obj = Harmony;
			obj = oldMethod;
			obj = (object)((!(newMethodPre != null)) ? ((HarmonyMethod)null) : new HarmonyMethod(newMethodPre));
			obj = (object)((!(newMethodPost != null)) ? ((HarmonyMethod)null) : new HarmonyMethod(newMethodPost));
			obj = (object)((!(transpiler != null)) ? ((HarmonyMethod)null) : new HarmonyMethod(transpiler));
			((List<MethodInfo>)obj).Add(((Harmony)obj).Patch((MethodBase)obj, (HarmonyMethod)obj, (HarmonyMethod)obj, (HarmonyMethod)obj, (HarmonyMethod)null, (HarmonyMethod)null));
			m_patches.Add(oldMethod);
		}

		public void AddUnpatchAction(Action unpatchAction)
		{
			m_onUnpatchActions.Add(unpatchAction);
		}

		public static void UnpatchAll()
		{
			LogUtils.DoInfoLog("Unpatching all: " + Harmony.Id);
			foreach (MethodInfo patch in m_patches)
			{
				Harmony.Unpatch((MethodBase)patch, (HarmonyPatchType)0, Harmony.Id);
			}
			foreach (Action onUnpatchAction in m_onUnpatchActions)
			{
				onUnpatchAction?.Invoke();
			}
			m_onUnpatchActions.Clear();
			m_patches.Clear();
			string text = "k45_Redirectors_" + Harmony.Id;
			Object.DestroyImmediate((Object)(object)GameObject.Find(text));
		}

		public static void PatchAll()
		{
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			LogUtils.DoInfoLog("Patching all: " + Harmony.Id);
			string text = "k45_Redirectors_" + Harmony.Id;
			GameObject val = (GameObject)(((object)GameObject.Find(text)) ?? ((object)new GameObject(text)));
			Object.DontDestroyOnLoad((Object)(object)val);
			Type typeFromHandle = typeof(IRedirectable);
			string basePathLocation = Path.GetDirectoryName(typeof(Redirector).Assembly.Location);
			List<Assembly> assembly = new List<Assembly>(AppDomain.CurrentDomain.GetAssemblies().Where(delegate(Assembly x)
			{
				try
				{
					return x.Location.StartsWith(basePathLocation);
				}
				catch
				{
					return false;
				}
			}));
			List<Type> interfaceImplementations = ReflectionUtils.GetInterfaceImplementations(typeFromHandle, assembly);
			LogUtils.DoLog($"Found Redirectors: {interfaceImplementations.Count}");
			Type typeFromHandle2 = typeof(IRedirectableWorldless);
			List<Type> interfaceImplementations2 = ReflectionUtils.GetInterfaceImplementations(typeFromHandle2, assembly);
			LogUtils.DoLog($"Found Worldless Redirectors: {interfaceImplementations.Count}");
			Application.logMessageReceived += new LogCallback(ErrorPatchingHandler);
			try
			{
				foreach (Type item in interfaceImplementations)
				{
					LogUtils.DoLog($"Redirector: {item}");
					worldDependantRedirectors.Add(val.AddComponent(item) as IRedirectable);
				}
				foreach (Type item2 in interfaceImplementations2)
				{
					LogUtils.DoLog($"Redirector Worldless: {item2}");
					val.AddComponent(item2);
				}
			}
			finally
			{
				Application.logMessageReceived -= new LogCallback(ErrorPatchingHandler);
			}
		}

		public static void OnWorldCreated(World world)
		{
			foreach (IRedirectable worldDependantRedirector in worldDependantRedirectors)
			{
				worldDependantRedirector.DoPatches(world);
			}
		}

		private static void ErrorPatchingHandler(string logString, string stackTrace, LogType type)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)type == 4)
			{
				LogUtils.DoErrorLog(logString + "\n" + stackTrace, null);
			}
		}

		public void EnableDebug()
		{
			Harmony.DEBUG = true;
		}

		public void DisableDebug()
		{
			Harmony.DEBUG = false;
		}
	}
	public static class ReflectionUtils
	{
		public static readonly BindingFlags allFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.GetProperty;

		private static readonly MethodInfo m_setFieldMethod = typeof(ReflectionUtils).GetMethod("SetField", BindingFlags.Static | BindingFlags.NonPublic);

		public static void GetPropertyDelegates<CL, PT>(string propertyName, out Action<CL, PT> setter, out Func<CL, PT> getter)
		{
			setter = (Action<CL, PT>)Delegate.CreateDelegate(typeof(Action<CL, PT>), null, typeof(CL).GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetSetMethod());
			getter = (Func<CL, PT>)Delegate.CreateDelegate(typeof(Func<CL, PT>), null, typeof(CL).GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetGetMethod());
		}

		public static void GetStaticPropertyDelegates<CL, PT>(string propertyName, out Action<PT> setter, out Func<PT> getter)
		{
			setter = (Action<PT>)Delegate.CreateDelegate(typeof(Action<PT>), null, typeof(CL).GetProperty(propertyName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetSetMethod());
			getter = (Func<PT>)Delegate.CreateDelegate(typeof(Func<PT>), null, typeof(CL).GetProperty(propertyName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetGetMethod());
		}

		public static T RunPrivateMethod<T>(object o, string methodName, params object[] paramList)
		{
			if ((methodName ?? "") != string.Empty)
			{
				MethodInfo method = o.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (method != null)
				{
					return (T)method.Invoke(o, paramList);
				}
			}
			return default(T);
		}

		public static T RunPrivateStaticMethod<T>(Type t, string methodName, params object[] paramList)
		{
			if ((methodName ?? "") != string.Empty)
			{
				MethodInfo method = t.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (method != null)
				{
					return (T)method.Invoke(null, paramList);
				}
			}
			return default(T);
		}

		public static void GetFieldDelegates<TSource, TValue>(FieldInfo info, out Func<TSource, TValue> getter, out Action<TSource, TValue> setter)
		{
			getter = GetGetFieldDelegate<TSource, TValue>(info);
			setter = GetSetFieldDelegate<TSource, TValue>(info);
		}

		public static Func<TSource, TValue> GetGetFieldDelegate<TSource, TValue>(FieldInfo fieldInfo)
		{
			if (fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			Type declaringType = fieldInfo.DeclaringType;
			ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "source");
			Expression castOrConvertExpression = GetCastOrConvertExpression(parameterExpression, declaringType);
			MemberExpression expression = Expression.Field(castOrConvertExpression, fieldInfo);
			Expression castOrConvertExpression2 = GetCastOrConvertExpression(expression, typeof(TValue));
			LambdaExpression lambdaExpression = Expression.Lambda(typeof(Func<TSource, TValue>), castOrConvertExpression2, parameterExpression);
			return (Func<TSource, TValue>)lambdaExpression.Compile();
		}

		public static Func<TSource, TValue> GetGetFieldDelegate<TSource, TValue>(string fieldName, Type fieldDeclaringType)
		{
			if (fieldName == null)
			{
				throw new ArgumentNullException("fieldName");
			}
			if (fieldDeclaringType == null)
			{
				throw new ArgumentNullException("fieldDeclaringType");
			}
			FieldInfo field = fieldDeclaringType.GetField(fieldName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			return GetGetFieldDelegate<TSource, TValue>(field);
		}

		public static Action<TSource, TValue> GetSetFieldDelegate<TSource, TValue>(FieldInfo fieldInfo)
		{
			if (fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			Type declaringType = fieldInfo.DeclaringType;
			ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "source");
			ParameterExpression parameterExpression2 = Expression.Parameter(typeof(TValue), "value");
			Expression castOrConvertExpression = GetCastOrConvertExpression(parameterExpression, declaringType);
			Expression expression = Expression.Field(castOrConvertExpression, fieldInfo);
			Expression castOrConvertExpression2 = GetCastOrConvertExpression(parameterExpression2, expression.Type);
			MethodInfo method = m_setFieldMethod.MakeGenericMethod(expression.Type);
			MethodCallExpression body = Expression.Call(null, method, expression, castOrConvertExpression2);
			LambdaExpression lambdaExpression = Expression.Lambda(typeof(Action<TSource, TValue>), body, parameterExpression, parameterExpression2);
			return (Action<TSource, TValue>)lambdaExpression.Compile();
		}

		public static Action<TSource, TValue> GetSetFieldDelegate<TSource, TValue>(string fieldName, Type fieldType, Type fieldDeclaringType)
		{
			if (fieldName == null)
			{
				throw new ArgumentNullException("fieldName");
			}
			if (fieldType == null)
			{
				throw new ArgumentNullException("fieldType");
			}
			if (fieldDeclaringType == null)
			{
				throw new ArgumentNullException("fieldDeclaringType");
			}
			ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "source");
			ParameterExpression parameterExpression2 = Expression.Parameter(typeof(TValue), "value");
			Expression castOrConvertExpression = GetCastOrConvertExpression(parameterExpression, fieldDeclaringType);
			Expression castOrConvertExpression2 = GetCastOrConvertExpression(parameterExpression2, fieldType);
			MemberExpression arg = Expression.Field(castOrConvertExpression, fieldName);
			MethodInfo method = m_setFieldMethod.MakeGenericMethod(fieldType);
			MethodCallExpression body = Expression.Call(null, method, arg, castOrConvertExpression2);
			LambdaExpression lambdaExpression = Expression.Lambda(typeof(Action<TSource, TValue>), body, parameterExpression, parameterExpression2);
			return (Action<TSource, TValue>)lambdaExpression.Compile();
		}

		private static Expression GetCastOrConvertExpression(Expression expression, Type targetType)
		{
			Type type = expression.Type;
			if (targetType.IsAssignableFrom(type))
			{
				return expression;
			}
			if (targetType.IsValueType && !IsNullableType(targetType))
			{
				return Expression.Convert(expression, targetType);
			}
			return Expression.TypeAs(expression, targetType);
		}

		public static T GetPrivateField<T>(object prefabAI, string v)
		{
			return (T)prefabAI.GetType().GetField(v, allFlags).GetValue(prefabAI);
		}

		public static object GetPrivateStaticField(string v, Type type)
		{
			return type.GetField(v, allFlags).GetValue(null);
		}

		public static void SetField<TValue>(ref TValue field, TValue newValue)
		{
			field = newValue;
		}

		public static Delegate GetMethodDelegate(string propertyName, Type targetType, Type actionType)
		{
			return GetMethodDelegate(targetType.GetMethod(propertyName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), actionType);
		}

		public static Delegate GetMethodDelegate(MethodInfo method, Type actionType)
		{
			return Delegate.CreateDelegate(actionType, null, method);
		}

		public static FieldInfo GetEventField(Type type, string eventName)
		{
			FieldInfo fieldInfo = null;
			while (type != null)
			{
				fieldInfo = type.GetField(eventName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				if (fieldInfo != null && (fieldInfo.FieldType == typeof(MulticastDelegate) || fieldInfo.FieldType.IsSubclassOf(typeof(MulticastDelegate))))
				{
					break;
				}
				fieldInfo = type.GetField("EVENT_" + eventName.ToUpper(), BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				if (fieldInfo != null)
				{
					break;
				}
				type = type.BaseType;
			}
			return fieldInfo;
		}

		public static bool IsNullableType(Type type)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			bool result = false;
			if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
			{
				result = true;
			}
			return result;
		}

		public static bool HasField(object o, string fieldName)
		{
			FieldInfo[] fields = o.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				if (fieldInfo.Name == fieldName)
				{
					return true;
				}
			}
			return false;
		}

		public static List<Type> GetSubtypesRecursive(Type typeTarg, Type refType)
		{
			if (BasicIMod.DebugMode)
			{
				LogUtils.DoLog($"typeTarg = {typeTarg} | IsGenType={typeTarg.IsGenericType} ");
			}
			IEnumerable<Type> enumerable = from t in (from x in AppDomain.CurrentDomain.GetAssemblies()
					where refType == null || x == refType.Assembly
					select x)?.SelectMany(delegate(Assembly x)
				{
					try
					{
						return x?.GetTypes();
					}
					catch
					{
						return new Type[0];
					}
				})
				let y = t.BaseType
				where t.IsClass && y != null && ((!typeTarg.IsGenericType && y == typeTarg) || (y.IsGenericType && y.GetGenericTypeDefinition() == typeTarg))
				select t;
			List<Type> list = new List<Type>();
			if (BasicIMod.DebugMode)
			{
				LogUtils.DoLog("classes:\r\n\t " + string.Join("\r\n\t", enumerable.Select((Type x) => x.ToString()).ToArray()) + " ");
			}
			foreach (Type item in enumerable)
			{
				if (!item.IsSealed)
				{
					list.AddRange(GetSubtypesRecursive(item, item));
				}
				if (!item.IsAbstract)
				{
					list.Add(item);
				}
			}
			return list.Distinct().ToList();
		}

		public static List<Type> GetInterfaceImplementations(Type interfaceType, IEnumerable<Assembly> assembly = null)
		{
			if (BasicIMod.DebugMode)
			{
				LogUtils.DoLog($"interfaceType = {interfaceType}\nFrom:{Environment.StackTrace}");
			}
			if (assembly == null)
			{
				throw new NotSupportedException("Aguardando ModsMan Impl");
			}
			IEnumerable<Type> source = from t in assembly.SelectMany(delegate(Assembly x)
				{
					try
					{
						return x?.GetTypes();
					}
					catch
					{
						return new Type[0];
					}
				})
				let y = t.GetInterfaces()
				where t.IsClass && !t.IsAbstract && (y.Contains(interfaceType) || interfaceType.IsAssignableFrom(t))
				select t;
			LogUtils.DoLog("classes:\r\n\t " + string.Join("\r\n\t", source.Select((Type x) => x.ToString()).ToArray()) + " ");
			return source.ToList();
		}

		public static List<Type> GetStructForInterfaceImplementations(Type interfaceType, IEnumerable<Assembly> assembly = null)
		{
			if (BasicIMod.DebugMode)
			{
				LogUtils.DoLog($"interfaceType = {interfaceType}\nFrom:{Environment.StackTrace}");
			}
			if (assembly == null)
			{
				throw new NotSupportedException("Aguardando ModsMan Impl");
			}
			IEnumerable<Type> source = from t in assembly.SelectMany(delegate(Assembly x)
				{
					try
					{
						return x?.GetTypes();
					}
					catch
					{
						return new Type[0];
					}
				})
				let y = t.GetInterfaces()
				where t.IsValueType && (y.Contains(interfaceType) || interfaceType.IsAssignableFrom(t))
				select t;
			LogUtils.DoLog("classes:\r\n\t " + string.Join("\r\n\t", source.Select((Type x) => x.ToString()).ToArray()) + " ");
			return source.ToList();
		}

		public static Type GetImplementationForGenericType(Type typeOr, params Type[] typeArgs)
		{
			Type typeTarg = typeOr.MakeGenericType(typeArgs);
			IEnumerable<Type> source = from t in Assembly.GetAssembly(typeOr).GetTypes()
				where t.IsClass && !t.IsAbstract && typeTarg.IsAssignableFrom(t) && !t.IsGenericType
				select t;
			if (source.Count() != 1)
			{
				throw new Exception(string.Format("Defininções inválidas para [{0}] no tipo genérico {1}", string.Join(", ", typeArgs.Select((Type x) => x.ToString()).ToArray()), typeOr));
			}
			return source.First();
		}

		public static bool CanMakeGenericTypeVia(Type openConstructedType, Type closedConstructedType)
		{
			if (openConstructedType == null)
			{
				throw new ArgumentNullException("openConstructedType");
			}
			if (closedConstructedType == null)
			{
				throw new ArgumentNullException("closedConstructedType");
			}
			if (openConstructedType.IsGenericParameter)
			{
				GenericParameterAttributes genericParameterAttributes = openConstructedType.GenericParameterAttributes;
				if (genericParameterAttributes != 0)
				{
					if ((genericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0 && !closedConstructedType.IsValueType)
					{
						return false;
					}
					if ((genericParameterAttributes & GenericParameterAttributes.ReferenceTypeConstraint) != 0 && closedConstructedType.IsValueType)
					{
						return false;
					}
					if ((genericParameterAttributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0 && closedConstructedType.GetConstructor(Type.EmptyTypes) == null)
					{
						return false;
					}
				}
				Type[] genericParameterConstraints = openConstructedType.GetGenericParameterConstraints();
				foreach (Type type in genericParameterConstraints)
				{
					if (type.IsGenericType != closedConstructedType.BaseType.IsGenericType)
					{
						return false;
					}
					if (type.IsGenericType)
					{
						if (closedConstructedType.BaseType.GetGenericTypeDefinition() != type.GetGenericTypeDefinition())
						{
							return false;
						}
					}
					else if (!type.IsAssignableFrom(closedConstructedType))
					{
						return false;
					}
				}
				return true;
			}
			if (openConstructedType.ContainsGenericParameters)
			{
				if (openConstructedType.IsGenericType)
				{
					Type genericTypeDefinition = openConstructedType.GetGenericTypeDefinition();
					Type[] genericArguments = openConstructedType.GetGenericArguments();
					List<Type> list = new List<Type> { closedConstructedType };
					if (closedConstructedType.BaseType != null)
					{
						list.Add(closedConstructedType.BaseType);
					}
					list.AddRange(closedConstructedType.GetInterfaces());
					foreach (Type item in list)
					{
						if (!item.IsGenericType || !(item.GetGenericTypeDefinition() == genericTypeDefinition))
						{
							continue;
						}
						Type[] genericArguments2 = item.GetGenericArguments();
						for (int j = 0; j < genericArguments.Length; j++)
						{
							if (!CanMakeGenericTypeVia(genericArguments[j], genericArguments2[j]))
							{
								return false;
							}
						}
						return true;
					}
					return false;
				}
				if (openConstructedType.IsArray)
				{
					if (!closedConstructedType.IsArray || closedConstructedType.GetArrayRank() != openConstructedType.GetArrayRank())
					{
						return false;
					}
					Type elementType = openConstructedType.GetElementType();
					Type elementType2 = closedConstructedType.GetElementType();
					return CanMakeGenericTypeVia(elementType, elementType2);
				}
				throw new NotImplementedException("Open-constructed type contains generic parameters, but is neither an array nor a generic type.");
			}
			return openConstructedType.IsAssignableFrom(closedConstructedType);
		}

		public static bool IsAssignableToGenericType(Type givenType, Type genericType)
		{
			Type[] interfaces = givenType.GetInterfaces();
			Type[] array = interfaces;
			foreach (Type type in array)
			{
				if (type.IsGenericType && type.GetGenericTypeDefinition() == genericType)
				{
					return true;
				}
			}
			if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
			{
				return true;
			}
			Type baseType = givenType.BaseType;
			if (baseType == null)
			{
				return false;
			}
			return IsAssignableToGenericType(baseType, genericType);
		}
	}
	[XmlRoot("SimpleEnumerableList")]
	public class SimpleEnumerableList<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable where TKey : Enum
	{
		public XmlSchema GetSchema()
		{
			return null;
		}

		public void ReadXml(XmlReader reader)
		{
			if (reader.IsEmptyElement)
			{
				reader.Read();
				return;
			}
			XmlSerializer xmlSerializer = new XmlSerializer(typeof(ValueContainer<TKey, TValue>), "");
			LogUtils.DoLog($"reader = {reader}; empty = {reader.IsEmptyElement}");
			reader.ReadStartElement();
			while (reader.NodeType != XmlNodeType.EndElement)
			{
				if (reader.NodeType != XmlNodeType.Element)
				{
					reader.Read();
					continue;
				}
				ValueContainer<TKey, TValue> valueContainer = (ValueContainer<TKey, TValue>)xmlSerializer.Deserialize(reader);
				if (valueContainer.Index != null)
				{
					Add(valueContainer.Index, valueContainer.Value);
				}
			}
			reader.ReadEndElement();
		}

		public void WriteXml(XmlWriter writer)
		{
			XmlSerializer xmlSerializer = new XmlSerializer(typeof(ValueContainer<TKey, TValue>), "");
			XmlSerializerNamespaces xmlSerializerNamespaces = new XmlSerializerNamespaces();
			xmlSerializerNamespaces.Add("", "");
			foreach (TKey key in base.Keys)
			{
				TValue value = base[key];
				xmlSerializer.Serialize(writer, new ValueContainer<TKey, TValue>
				{
					Index = key,
					Value = value
				}, xmlSerializerNamespaces);
			}
		}
	}
	[XmlRoot("ValueContainer")]
	public class ValueContainer<TKey, TValue> : IEnumerableIndex<TKey> where TKey : Enum
	{
		[XmlIgnore]
		public TKey Index { get; set; }

		[XmlAttribute("Index")]
		public string EnumValue
		{
			get
			{
				return Index.ToString();
			}
			set
			{
				TKey index;
				try
				{
					index = (TKey)Enum.Parse(typeof(TKey), value);
				}
				catch
				{
					index = (TKey)Enum.ToObject(typeof(TKey), int.TryParse(value, out var result) ? result : 0);
				}
				Index = index;
			}
		}

		[XmlElement]
		public TValue Value { get; set; }
	}
	[XmlRoot("SimpleXmlDictionary")]
	public class SimpleXmlDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable where TKey : class where TValue : class
	{
		public XmlSchema GetSchema()
		{
			return null;
		}

		public void ReadXml(XmlReader reader)
		{
			if (reader.IsEmptyElement)
			{
				reader.Read();
				return;
			}
			XmlSerializer xmlSerializer = new XmlSerializer(typeof(EntryStructValueContainer<TKey, TValue>), "");
			reader.ReadStartElement();
			while (reader.NodeType != XmlNodeType.EndElement)
			{
				if (reader.NodeType != XmlNodeType.Element)
				{
					reader.Read();
					continue;
				}
				EntryStructValueContainer<TKey, TValue> entryStructValueContainer = (EntryStructValueContainer<TKey, TValue>)xmlSerializer.Deserialize(reader);
				if (entryStructValueContainer.Value is IKeyGetter<TKey> keyGetter)
				{
					entryStructValueContainer.Id = keyGetter.GetKeyString() ?? entryStructValueContainer.Id;
				}
				if (entryStructValueContainer.Id != null)
				{
					Add(entryStructValueContainer.Id, entryStructValueContainer.Value ?? null);
				}
			}
			reader.ReadEndElement();
		}

		public void WriteXml(XmlWriter writer)
		{
			XmlSerializer xmlSerializer = new XmlSerializer(typeof(EntryStructValueContainer<TKey, TValue>), "");
			XmlSerializerNamespaces xmlSerializerNamespaces = new XmlSerializerNamespaces();
			xmlSerializerNamespaces.Add("", "");
			foreach (TKey key in base.Keys)
			{
				TValue value = base[key];
				xmlSerializer.Serialize(writer, new EntryStructValueContainer<TKey, TValue>
				{
					Id = key,
					Value = value
				}, xmlSerializerNamespaces);
			}
		}
	}
	[XmlRoot("Entry")]
	public class EntryStructValueContainer<TKey, TValue> where TKey : class where TValue : class
	{
		[XmlAttribute("key")]
		public TKey Id { get; set; }

		[XmlElement]
		public TValue Value { get; set; }
	}
	public interface IKeyGetter<TKey>
	{
		TKey GetKeyString();
	}
	public class Tuple<T1, T2, T3, T4, T5> : Tuple<T1, T2, T3, T4>
	{
		public T5 Fifth { get; protected set; }

		public Tuple(ref T1 first, ref T2 second, ref T3 third, ref T4 fourth, ref T5 fifth)
			: base(ref first, ref second, ref third, ref fourth)
		{
			Fifth = fifth;
		}
	}
	public class Tuple<T1, T2, T3, T4> : Tuple<T1, T2, T3>
	{
		public T4 Fourth { get; protected set; }

		public Tuple(ref T1 first, ref T2 second, ref T3 third, ref T4 fourth)
			: base(ref first, ref second, ref third)
		{
			Fourth = fourth;
		}
	}
	public class Tuple<T1, T2, T3> : Tuple<T1, T2>
	{
		public T3 Third { get; protected set; }

		public Tuple(ref T1 first, ref T2 second, ref T3 third)
			: base(ref first, ref second)
		{
			Third = third;
		}
	}
	public class Tuple<T1, T2>
	{
		public T1 First { get; protected set; }

		public T2 Second { get; protected set; }

		public Tuple(ref T1 first, ref T2 second)
		{
			First = first;
			Second = second;
		}
	}
	public class TupleRef<T1, T2, T3, T4, T5> : TupleRef<T1, T2, T3, T4>
	{
		private T5 m_fifth;

		public ref T5 Fifth => ref m_fifth;

		public TupleRef(ref T1 first, ref T2 second, ref T3 third, ref T4 fourth, ref T5 fifth)
			: base(ref first, ref second, ref third, ref fourth)
		{
			m_fifth = fifth;
		}
	}
	public class TupleRef<T1, T2, T3, T4> : TupleRef<T1, T2, T3>
	{
		private T4 m_fourth;

		public ref T4 Fourth => ref m_fourth;

		public TupleRef(ref T1 first, ref T2 second, ref T3 third, ref T4 fourth)
			: base(ref first, ref second, ref third)
		{
			m_fourth = fourth;
		}
	}
	public class TupleRef<T1, T2, T3> : TupleRef<T1, T2>
	{
		private T3 m_third;

		public ref T3 Third => ref m_third;

		public TupleRef(ref T1 first, ref T2 second, ref T3 third)
			: base(ref first, ref second)
		{
			m_third = third;
		}
	}
	public class TupleRef<T1, T2>
	{
		private T1 m_first;

		private T2 m_second;

		public ref T1 First => ref m_first;

		public ref T2 Second => ref m_second;

		public TupleRef(ref T1 first, ref T2 second)
		{
			m_first = first;
			m_second = second;
		}
	}
	public static class Tuple
	{
		public static Tuple<T1, T2, T3, T4, T5> New<T1, T2, T3, T4, T5>(T1 first, T2 second, T3 third, T4 fourth, T5 fifth)
		{
			return new Tuple<T1, T2, T3, T4, T5>(ref first, ref second, ref third, ref fourth, ref fifth);
		}

		public static Tuple<T1, T2, T3, T4> New<T1, T2, T3, T4>(T1 first, T2 second, T3 third, T4 fourth)
		{
			return new Tuple<T1, T2, T3, T4>(ref first, ref second, ref third, ref fourth);
		}

		public static Tuple<T1, T2, T3> New<T1, T2, T3>(T1 first, T2 second, T3 third)
		{
			return new Tuple<T1, T2, T3>(ref first, ref second, ref third);
		}

		public static Tuple<T1, T2> New<T1, T2>(T1 first, T2 second)
		{
			return new Tuple<T1, T2>(ref first, ref second);
		}

		public static TupleRef<T1, T2, T3, T4, T5> NewRef<T1, T2, T3, T4, T5>(T1 first, T2 second, T3 third, T4 fourth, T5 fifth)
		{
			return new TupleRef<T1, T2, T3, T4, T5>(ref first, ref second, ref third, ref fourth, ref fifth);
		}

		public static TupleRef<T1, T2, T3, T4> NewRef<T1, T2, T3, T4>(T1 first, T2 second, T3 third, T4 fourth)
		{
			return new TupleRef<T1, T2, T3, T4>(ref first, ref second, ref third, ref fourth);
		}

		public static TupleRef<T1, T2, T3> NewRef<T1, T2, T3>(ref T1 first, ref T2 second, ref T3 third)
		{
			return new TupleRef<T1, T2, T3>(ref first, ref second, ref third);
		}

		public static TupleRef<T1, T2> NewRef<T1, T2>(ref T1 first, ref T2 second)
		{
			return new TupleRef<T1, T2>(ref first, ref second);
		}
	}
	public class Wrapper<T>
	{
		public T Value { get; set; }

		public Wrapper(T value)
		{
			Value = value;
		}

		public Wrapper()
		{
		}
	}
	public class XmlUtils
	{
		public class ListWrapper<T>
		{
			[XmlElement("item")]
			public List<T> listVal = new List<T>();
		}

		public static T CloneViaXml<T>(T input)
		{
			return DefaultXmlDeserialize<T>(DefaultXmlSerialize(input));
		}

		public static U TransformViaXml<T, U>(T input)
		{
			return DefaultXmlDeserialize<U>(DefaultXmlSerialize(input));
		}

		public static T DefaultXmlDeserialize<T>(string s, Action<string, Exception> OnException = null)
		{
			XmlSerializer xmlser = new XmlSerializer(typeof(T));
			return DefaultXmlDeserializeImpl<T>(s, xmlser, OnException);
		}

		public static object DefaultXmlDeserialize(Type t, string s, Action<string, Exception> OnException = null)
		{
			XmlSerializer xmlser = new XmlSerializer(t);
			return DefaultXmlDeserializeImpl<object>(s, xmlser, OnException);
		}

		private static T DefaultXmlDeserializeImpl<T>(string s, XmlSerializer xmlser, Action<string, Exception> OnException = null)
		{
			using TextReader input = new StringReader(s);
			using XmlReader xmlReader = XmlReader.Create(input);
			try
			{
				if (xmlser.CanDeserialize(xmlReader))
				{
					return (T)xmlser.Deserialize(xmlReader);
				}
				LogUtils.DoErrorLog($"CAN'T DESERIALIZE {typeof(T)}!\nText : {s}", null);
				OnException?.Invoke(s, null);
			}
			catch (Exception ex)
			{
				LogUtils.DoErrorLog($"CAN'T DESERIALIZE {typeof(T)}!\nText : {s}\n{ex.GetType().Name}: {ex.Message}\n{ex.StackTrace}", null);
				OnException?.Invoke(s, ex);
				throw ex;
			}
			return default(T);
		}

		public static string DefaultXmlSerialize<T>(T targetObj, bool indent = true)
		{
			XmlSerializer xmlSerializer = new XmlSerializer(targetObj?.GetType() ?? typeof(T));
			XmlWriterSettings settings = new XmlWriterSettings
			{
				Indent = indent,
				OmitXmlDeclaration = true
			};
			using StringWriter stringWriter = new StringWriter();
			using XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings);
			XmlSerializerNamespaces xmlSerializerNamespaces = new XmlSerializerNamespaces();
			xmlSerializerNamespaces.Add("", "");
			xmlSerializer.Serialize(xmlWriter, targetObj, xmlSerializerNamespaces);
			return stringWriter.ToString();
		}
	}
}
namespace Belzont.Serialization
{
	internal struct BelzontDeserializeJob<TReader, B> : IJob where TReader : struct, IReader where B : ComponentSystemBase, IBelzontSerializableSingleton<B>, new()
	{
		public int m_WorldIndex;

		public EntityReaderData m_ReaderData;

		public void Execute()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				TReader reader = ((EntityReaderData)(ref m_ReaderData)).GetReader<TReader>();
				World.All[m_WorldIndex].GetExistingSystemManaged<B>().Deserialize(reader);
				LogUtils.DoLog($"Deserialized {typeof(B)}");
			}
			catch (Exception arg)
			{
				LogUtils.DoWarnLog($"Error loading deserialization for {typeof(B)}!\n{arg}");
			}
		}
	}
	internal struct BelzontSerializeJob<TWriter, B> : IJob where TWriter : struct, IWriter where B : ComponentSystemBase, IBelzontSerializableSingleton<B>, new()
	{
		public int m_WorldIndex;

		public EntityWriterData m_WriterData;

		public void Execute()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			TWriter writer = ((EntityWriterData)(ref m_WriterData)).GetWriter<TWriter>();
			World.All[m_WorldIndex].GetExistingSystemManaged<B>().Serialize(writer);
			LogUtils.DoLog($"Serialized {typeof(B)}");
		}
	}
	internal interface IBelzontSerializableSingleton<B> : IJobSerializable where B : ComponentSystemBase, IBelzontSerializableSingleton<B>, new()
	{
		World World { get; }

		internal void Serialize<TWriter>(TWriter writer) where TWriter : IWriter;

		internal void Deserialize<TReader>(TReader reader) where TReader : IReader;

		JobHandle IJobSerializable.Serialize<TWriter>(EntityWriterData writerData, JobHandle inputDeps)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			BelzontSerializeJob<TWriter, B> belzontSerializeJob = default(BelzontSerializeJob<TWriter, B>);
			belzontSerializeJob.m_WriterData = writerData;
			belzontSerializeJob.m_WorldIndex = -1;
			for (int i = 0; i < World.All.Count; i++)
			{
				if (World.All[i] == World)
				{
					belzontSerializeJob.m_WorldIndex = i;
					break;
				}
			}
			return IJobExtensions.Schedule<BelzontSerializeJob<TWriter, B>>(belzontSerializeJob, inputDeps);
		}

		JobHandle IJobSerializable.Deserialize<TReader>(EntityReaderData readerData, JobHandle inputDeps)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			BelzontDeserializeJob<TReader, B> belzontDeserializeJob = default(BelzontDeserializeJob<TReader, B>);
			belzontDeserializeJob.m_ReaderData = readerData;
			belzontDeserializeJob.m_WorldIndex = -1;
			for (int i = 0; i < World.All.Count; i++)
			{
				if (World.All[i] == World)
				{
					belzontDeserializeJob.m_WorldIndex = i;
					break;
				}
			}
			inputDeps = IJobExtensions.Schedule<BelzontDeserializeJob<TReader, B>>(belzontDeserializeJob, inputDeps);
			return inputDeps;
		}
	}
}
namespace Belzont.Thunderstore
{
	public class ModHooksRedirects : Redirector, 

K45EUIS_Ext.dll

Decompiled a year ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("K45EUIS_Ext")]
[assembly: AssemblyConfiguration("Thunderstore")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("K45EUIS_Ext")]
[assembly: AssemblyTitle("K45EUIS_Ext")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace K45EUIS_Ext;

public interface IEUISAppRegister
{
	string DisplayName { get; }

	string UrlJs { get; }

	string UrlCss { get; }

	string UrlIcon { get; }

	string ModderIdentifier { get; }

	string ModAcronym { get; }

	string ModAppIdentifier { get; }
}
public static class EUISAppRegisterExtensions
{
	public static string GetFullAppName(this IEUISAppRegister app)
	{
		string[] obj = new string[6] { "@", app.ModderIdentifier, "/", app.ModAcronym, null, null };
		string modAppIdentifier = app.ModAppIdentifier;
		obj[4] = ((modAppIdentifier != null && modAppIdentifier.Length > 0) ? "-" : "");
		obj[5] = app.ModAppIdentifier;
		return string.Concat(obj);
	}

	public static string GetInternalAppName(this IEUISAppRegister app)
	{
		string modAcronym = app.ModAcronym;
		string modAppIdentifier = app.ModAppIdentifier;
		return modAcronym + ((modAppIdentifier != null && modAppIdentifier.Length > 0) ? "-" : "") + app.ModAppIdentifier;
	}
}
public interface IEUISModRegister
{
	string ModderIdentifier { get; }

	string ModAcronym { get; }

	Action<Action<string, object[]>> OnGetEventEmitter { get; }

	Action<Action<string, Delegate>> OnGetEventsBinder { get; }

	Action<Action<string, Delegate>> OnGetCallsBinder { get; }
}
public static class EUISSpecialEventEmitters
{
	public const string kOpenModAppCmd = "^openApp";
}
public interface IEUISOverlayRegister
{
	string DisplayName { get; }

	string UrlJs { get; }

	string UrlCss { get; }

	string UrlIcon { get; }

	string ModderIdentifier { get; }

	string ModAcronym { get; }

	string ModAppIdentifier { get; }
}
public static class IEUISOverlayRegisterExtensions
{
	public static string GetFullAppName(this IEUISOverlayRegister app)
	{
		string[] obj = new string[6] { "@", app.ModderIdentifier, "/", app.ModAcronym, null, null };
		string modAppIdentifier = app.ModAppIdentifier;
		obj[4] = ((modAppIdentifier != null && modAppIdentifier.Length > 0) ? "-" : "");
		obj[5] = app.ModAppIdentifier;
		return string.Concat(obj);
	}

	public static string GetInternalAppName(this IEUISOverlayRegister app)
	{
		string modAcronym = app.ModAcronym;
		string modAppIdentifier = app.ModAppIdentifier;
		return modAcronym + ((modAppIdentifier != null && modAppIdentifier.Length > 0) ? "-" : "") + app.ModAppIdentifier;
	}
}