Decompiled source of MeteorCore v0.2.1

MeteorCore.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Koop;
using MeteorCore.Localiser;
using MeteorCore.Localiser.Dictionaries;
using MeteorCore.Setting;
using MeteorCore.Setting.AbstractClasses;
using MeteorCore.Setting.Interfaces;
using MeteorCore.Setting.Interfaces.Internal;
using MeteorCore.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Rewired;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[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.6", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("MeteorCore")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Core plugin for MeteorMod")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0+0e3f2f6e4dbe75d8844716add93267e4a32980ca")]
[assembly: AssemblyProduct("MeteorCore")]
[assembly: AssemblyTitle("MeteorCore")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MeteorCore
{
	[BepInPlugin("MeteorCore", "MeteorCore", "0.2.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		internal static Transform PluginManager;

		internal static Harmony harmony;

		internal static BepInPlugin metadata;

		private void Awake()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UnityLogging", true, "Enables unity logging");
			Debug.unityLogger.logEnabled = val.Value;
			Debug.unityLogger.filterLogType = (LogType)2;
			metadata = MetadataHelper.GetMetadata((object)this);
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"Plugin MeteorCore is loaded!");
			harmony = new Harmony("MeteorCore");
			harmony.PatchAll();
			PluginLocaliser.RegisterPlugin(metadata);
			GameObject val2 = GameObject.Find("MANAGER_MASTER");
			PluginManager = new GameObject("MeteorCore").transform;
			PluginManager.SetParent(val2.transform);
			SceneHelper.Init();
			Mgr_PluginSettings.Create();
		}
	}
	public static class SceneHelper
	{
		public static bool IsSplashScene { get; private set; }

		public static bool IsTitleScene { get; private set; }

		public static bool IsPerformenceScene { get; private set; }

		public static bool IsMinigameScene { get; private set; }

		public static bool IsGameScene { get; private set; }

		public static bool IsLNLScene { get; private set; }

		public static void Init()
		{
			SceneManager.sceneLoaded += SceneLoaded;
		}

		private static void SceneLoaded(Scene scene, LoadSceneMode mode)
		{
			IsTitleScene = ((Scene)(ref scene)).name == "Title";
			IsSplashScene = ((Scene)(ref scene)).name == "Splash";
			GameObject val = GameObject.Find("GameplayUI Root");
			IsPerformenceScene = (Object)(object)val != (Object)null;
			GameObject val2 = GameObject.Find("MG_Basics/Controller");
			IsMinigameScene = (Object)(object)val2 != (Object)null;
			IsLNLScene = false;
			IsGameScene = !IsSplashScene && !IsTitleScene && !IsPerformenceScene && !IsMinigameScene;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "MeteorCore";

		public const string PLUGIN_NAME = "MeteorCore";

		public const string PLUGIN_VERSION = "0.2.0";
	}
}
namespace MeteorCore.Utils
{
	public static class MeteorUtils
	{
		public static T CopyComponent<T>(T original, GameObject destination) where T : Component
		{
			Type type = ((object)original).GetType();
			Component component = destination.GetComponent(type);
			T val = (T)(object)((component is T) ? component : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Component obj = destination.AddComponent(type);
				val = (T)(object)((obj is T) ? obj : null);
			}
			FieldInfo[] fields = type.GetFields();
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				if (!fieldInfo.IsStatic)
				{
					fieldInfo.SetValue(val, fieldInfo.GetValue(original));
				}
			}
			PropertyInfo[] properties = type.GetProperties();
			PropertyInfo[] array2 = properties;
			foreach (PropertyInfo propertyInfo in array2)
			{
				if (propertyInfo.CanWrite && propertyInfo.CanWrite && !(propertyInfo.Name == "name"))
				{
					propertyInfo.SetValue(val, propertyInfo.GetValue(original, null), null);
				}
			}
			return val;
		}

		public static T CopyComponentValues<T>(T original, T destination, bool copyPrivate, ICollection<string> ignoreFields = null, ICollection<string> ignoreProperties = null) where T : Component
		{
			if ((Object)(object)destination == (Object)null)
			{
				Plugin.Logger.LogError((object)"CopyComponent destination is null");
			}
			if ((Object)(object)original == (Object)null)
			{
				Plugin.Logger.LogError((object)"CopyComponent original is null");
			}
			BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
			if (copyPrivate)
			{
				bindingFlags |= BindingFlags.NonPublic;
			}
			Type typeFromHandle = typeof(T);
			FieldInfo[] fields = typeFromHandle.GetFields(bindingFlags);
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				try
				{
					if (!fieldInfo.IsStatic && (ignoreFields == null || !ignoreFields.Contains(fieldInfo.Name)))
					{
						fieldInfo.SetValue(destination, fieldInfo.GetValue(original));
					}
				}
				catch (Exception ex)
				{
					Plugin.Logger.LogError((object)("Could not copy field \"" + fieldInfo.Name + "\" from \"" + ((object)original).GetType().Name + "\" to \"" + ((object)destination).GetType().Name + "\""));
					Plugin.Logger.LogError((object)ex);
					throw ex;
				}
			}
			PropertyInfo[] properties = typeFromHandle.GetProperties(bindingFlags);
			PropertyInfo[] array2 = properties;
			foreach (PropertyInfo propertyInfo in array2)
			{
				try
				{
					if (propertyInfo.CanWrite && propertyInfo.CanWrite && !(propertyInfo.Name == "name") && (ignoreProperties == null || !ignoreProperties.Contains(propertyInfo.Name)))
					{
						propertyInfo.SetValue(destination, propertyInfo.GetValue(original, null), null);
					}
				}
				catch (Exception ex2)
				{
					Plugin.Logger.LogError((object)("Could not copy property " + propertyInfo.Name + " from " + ((object)original).GetType().Name + " to " + ((object)destination).GetType().Name));
					Plugin.Logger.LogError((object)ex2);
					throw ex2;
				}
			}
			return destination;
		}
	}
}
namespace MeteorCore.Setting
{
	public class Mgr_PluginSettings : MonoBehaviour
	{
		private class PluginSettingContainer
		{
			public BepInPlugin ownerMetadata;

			public ConfigEntryBase configEntryBase;

			public string pageName;

			public IPluginSetting setting;

			public Type settingUIItemType;
		}

		private class PluginSettingPageContainer
		{
			public string pageGameObjectName;

			public string pageName;

			public string dictionaryName;

			public Type pageType;

			public IPluginSettingsPage pageInstance;
		}

		private static Mgr_PluginSettings _instance;

		public static Transform settingPagesHolder;

		private Dictionary<string, PluginSettingPageContainer> settingPages = new Dictionary<string, PluginSettingPageContainer>();

		private List<PluginSettingContainer> settings = new List<PluginSettingContainer>();

		private Dictionary<BepInPlugin, ConfigFile> configFiles = new Dictionary<BepInPlugin, ConfigFile>();

		public static Mgr_PluginSettings Instance
		{
			get
			{
				if ((Object)(object)_instance == (Object)null)
				{
					_instance = Object.FindObjectOfType<Mgr_PluginSettings>();
				}
				return _instance;
			}
		}

		public static bool SceneHasSettingsMenu => SceneHelper.IsTitleScene || SceneHelper.IsGameScene || SceneHelper.IsLNLScene;

		private void Awake()
		{
			if ((Object)(object)_instance == (Object)null)
			{
				_instance = this;
			}
			if ((Object)(object)_instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)this);
			}
			SceneManager.sceneLoaded += SceneLoaded;
		}

		public static GameObject Create()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			GameObject val = new GameObject("Mgr_PluginSettings");
			val.AddComponent<Mgr_PluginSettings>();
			val.transform.SetParent(Plugin.PluginManager);
			GameObject val2 = SettingsUIPrefabs.Create();
			val2.transform.SetParent(val.transform);
			return val;
		}

		public static void AddPage<T>(string pageName, string dictionaryName, string pageGameObjectName) where T : IPluginSettingsPage
		{
			if (Instance.settingPages.ContainsKey(pageName))
			{
				Plugin.Logger.LogError((object)("Setting page " + pageName + " already exists"));
				return;
			}
			Plugin.Logger.LogInfo((object)("Adding setting page " + pageName));
			Instance.settingPages.Add(pageName, new PluginSettingPageContainer
			{
				pageGameObjectName = pageGameObjectName,
				dictionaryName = dictionaryName,
				pageName = pageName,
				pageType = typeof(T),
				pageInstance = null
			});
		}

		public static void AddSetting<TSettingValue, TUIItem>(IPluginSetting<TSettingValue> setting, string pageName, BepInPlugin owner) where TUIItem : MonoBehaviour, IPluginSettingUIItem
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			Plugin.Logger.LogInfo((object)("Adding setting " + setting.settingKey + " to page " + pageName));
			if (!Instance.settingPages.ContainsKey(pageName))
			{
				Plugin.Logger.LogError((object)("Setting is not added as the page " + pageName + ", it does not exist. Make sure to call AddPage first"));
				return;
			}
			try
			{
				GameObject val = new GameObject($"Generic Test {typeof(TUIItem)}");
				Component val2 = (Component)(object)val.AddComponent<TUIItem>();
				if (!(val2 is IPluginSettingUIItem))
				{
					Plugin.Logger.LogError((object)$"Could not add setting ui item {typeof(TUIItem)}, it may have a generic type problem. Make sure to pass a concrete type.");
					return;
				}
				Object.Destroy((Object)(object)val);
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)$"Could not add setting ui item {typeof(TUIItem)}, it may have a generic type problem. Make sure to pass a concrete type.");
				Plugin.Logger.LogError((object)ex);
				throw ex;
			}
			if (!Instance.configFiles.ContainsKey(owner))
			{
				Instance.CreateConfigFile(owner);
			}
			ConfigEntry<TSettingValue> val3 = Instance.configFiles[owner].Bind<TSettingValue>(pageName, setting.settingKey, setting.DefaultValue, setting.tooltip);
			Instance.settings.Add(new PluginSettingContainer
			{
				ownerMetadata = owner,
				configEntryBase = (ConfigEntryBase)(object)val3,
				pageName = pageName,
				setting = setting,
				settingUIItemType = typeof(TUIItem)
			});
			setting.SetValue(val3.Value, save: false, pending: false, notify: false);
		}

		private void SceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			SettingsUIPrefabs.Instance.SceneLoaded(scene, mode);
			if (!SceneHasSettingsMenu)
			{
				return;
			}
			foreach (KeyValuePair<string, PluginSettingPageContainer> settingPage in settingPages)
			{
				Plugin.Logger.LogInfo((object)("Creating page " + settingPage.Key));
				PluginSettingPageContainer value = settingPage.Value;
				IPluginSettingsPage pageInstance = CreatePageInstance(value);
				value.pageInstance = pageInstance;
			}
			foreach (PluginSettingContainer setting in settings)
			{
				Plugin.Logger.LogInfo((object)("Creating setting UI item for" + setting.setting.settingKey));
				string pageName = setting.pageName;
				if (!settingPages.ContainsKey(pageName))
				{
					return;
				}
				IPluginSettingsPage pageInstance2 = settingPages[pageName].pageInstance;
				IPluginSettingUIItem pluginSettingUIItem = CreateUIItem(setting.settingUIItemType, setting.setting, pageInstance2.settingsHolder);
				pageInstance2.AddSettingUIItem(pluginSettingUIItem);
				pluginSettingUIItem.SetSettingInternal(setting.setting);
			}
			foreach (PluginSettingPageContainer value2 in settingPages.Values)
			{
				value2.pageInstance.OnInitialized();
			}
		}

		private IPluginSettingUIItem CreateUIItem(Type settingType, IPluginSetting setting, Transform parent)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			try
			{
				GameObject val = new GameObject(settingType.Name);
				Component val2 = val.AddComponent(settingType);
				if (!(val2 is IPluginSettingUIItem pluginSettingUIItem))
				{
					Plugin.Logger.LogError((object)("Could not create ui item instance of type " + settingType.Name + " does it implement IPluginSettingUIItem?"));
					return null;
				}
				GameObject val3 = pluginSettingUIItem.Initialize(parent, setting);
				return val3.GetComponent<IPluginSettingUIItem>();
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Error creating ui item instance of type " + settingType.Name));
				Plugin.Logger.LogError((object)ex);
				throw ex;
			}
		}

		private IPluginSettingsPage CreatePageInstance(PluginSettingPageContainer pageContainer)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			GameObject val = new GameObject(pageContainer.pageGameObjectName);
			val.transform.SetParent(settingPagesHolder);
			IPluginSettingsPage pluginSettingsPage = val.AddComponent(pageContainer.pageType) as IPluginSettingsPage;
			if (pluginSettingsPage == null)
			{
				Plugin.Logger.LogError((object)("Could not create page instance of type " + pageContainer.pageType?.Name + " with name " + pageContainer.pageGameObjectName + " does it implement IPluginSettingsPage?"));
			}
			try
			{
				val = pluginSettingsPage.Initialize(pageContainer.pageName, GetPageSettingsByPageName(pageContainer.pageName));
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Could not initialize page instance of type " + pageContainer.pageType?.Name + " with name " + pageContainer.pageGameObjectName));
				Plugin.Logger.LogError((object)ex);
				throw ex;
			}
			return val.GetComponent<IPluginSettingsPage>();
		}

		private List<IPluginSetting> GetPageSettingsByPageName(string pageName)
		{
			List<IPluginSetting> list = new List<IPluginSetting>();
			foreach (PluginSettingContainer setting in settings)
			{
				if (setting.pageName == pageName)
				{
					list.Add(setting.setting);
				}
			}
			return list;
		}

		private void CreateConfigFile(BepInPlugin ownerMetadata)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			string text = Path.Combine(Paths.ConfigPath, ownerMetadata.Name + ".cfg");
			ConfigFile val = new ConfigFile(text, true, ownerMetadata);
			val.SaveOnConfigSet = false;
			configFiles.Add(ownerMetadata, val);
		}

		public void ApplySettings()
		{
			foreach (PluginSettingContainer setting in settings)
			{
				setting.setting.ApplyPendingValue();
			}
		}

		public void RevertSettings()
		{
			foreach (PluginSettingContainer setting in settings)
			{
				setting.setting.RevertPendingValue();
			}
		}

		public void SaveSettings()
		{
			foreach (PluginSettingContainer setting in settings)
			{
				ConfigEntryBase configEntryBase = setting.configEntryBase;
				configEntryBase.BoxedValue = setting.setting.BoxedValue;
			}
			foreach (ConfigFile value in configFiles.Values)
			{
				value.Save();
			}
			Plugin.Logger.LogInfo((object)"Saved settings");
		}

		public bool HaveSettingsChangedWhileOpen()
		{
			foreach (PluginSettingContainer setting in settings)
			{
				if (setting.setting.isDirty)
				{
					return true;
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(SettingsMenu), "HaveSettingsChangedWhileOpen")]
	public class SettingsPage_HaveSettingsChangedWhileOpen_Patch
	{
		public static void Postfix(ref bool __result)
		{
			__result = __result || Mgr_PluginSettings.Instance.HaveSettingsChangedWhileOpen();
		}
	}
	[HarmonyPatch(typeof(Mgr_Settings), "ApplySettings")]
	public class Mgr_Settings_ApplySettings_Patch
	{
		public static void Postfix()
		{
			Mgr_PluginSettings.Instance.ApplySettings();
			Mgr_PluginSettings.Instance.SaveSettings();
		}
	}
	[HarmonyPatch(typeof(SettingsMenu), "RevertAllPendingSettingsChanges")]
	public class SettingsMenu_RevertAllPendingSettingsChanges_Patch
	{
		public static void Postfix()
		{
			Mgr_PluginSettings.Instance.RevertSettings();
		}
	}
	public class SettingsUIPrefabs : MonoBehaviour
	{
		private static SettingsUIPrefabs _instance;

		private bool firstSceneLoad = true;

		public static SettingsUIPrefabs Instance
		{
			get
			{
				if ((Object)(object)_instance == (Object)null)
				{
					_instance = Object.FindObjectOfType<SettingsUIPrefabs>();
				}
				return _instance;
			}
		}

		public static GameObject LabelPrefab { get; private set; }

		public static GameObject TogglePrefab { get; private set; }

		public static GameObject SliderPrefab { get; private set; }

		public static GameObject ListPrefab { get; private set; }

		private void Awake()
		{
			if ((Object)(object)_instance == (Object)null)
			{
				_instance = this;
			}
			if ((Object)(object)_instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)this);
			}
		}

		public static GameObject Create()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			GameObject val = new GameObject("SettingsUIPrefabs");
			val.transform.SetParent(((Component)Mgr_PluginSettings.Instance).transform);
			val.AddComponent<RectTransform>();
			val.AddComponent<SettingsUIPrefabs>();
			return val;
		}

		public void SceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (firstSceneLoad && Mgr_PluginSettings.SceneHasSettingsMenu)
			{
				firstSceneLoad = false;
				CopyBaseUIITems();
			}
		}

		private void CopyBaseUIITems()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			GameObject val = new GameObject("SettingsUIPrefabs");
			val.transform.SetParent(((Component)this).transform);
			SettingsItemToggle val2 = Object.FindObjectOfType<SettingsItemToggle>(true);
			if ((Object)(object)val2 != (Object)null)
			{
				TogglePrefab = Object.Instantiate<GameObject>(((Component)val2).gameObject, val.transform);
				TogglePrefab.SetActive(false);
				((Object)TogglePrefab).name = "PluginSettingsItemToggle";
			}
			else
			{
				Plugin.Logger.LogError((object)"Could not find toggle prefab");
			}
			StaticStringLocaliser componentInChildren = TogglePrefab.GetComponentInChildren<StaticStringLocaliser>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				LabelPrefab = Object.Instantiate<GameObject>(((Component)componentInChildren).gameObject, val.transform);
				LabelPrefab.SetActive(false);
				((Object)LabelPrefab).name = "PluginSettingsLabel";
				componentInChildren.BaseText = "LocaliserUnsetText";
				componentInChildren.Dictionary = "LocaliserUnsetDictionary";
			}
			else
			{
				Plugin.Logger.LogError((object)"Could not find label prefab");
			}
			SettingsItemSlider val3 = Object.FindObjectOfType<SettingsItemSlider>(true);
			if ((Object)(object)val3 != (Object)null)
			{
				SliderPrefab = Object.Instantiate<GameObject>(((Component)val3).gameObject, val.transform);
				SliderPrefab.SetActive(false);
				((Object)SliderPrefab).name = "PluginSettingsItemSlider";
			}
			else
			{
				Plugin.Logger.LogError((object)"Could not find slider prefab");
			}
			SettingsItemList val4 = Object.FindObjectOfType<SettingsItemList>(true);
			if ((Object)(object)val4 != (Object)null)
			{
				ListPrefab = Object.Instantiate<GameObject>(((Component)val4).gameObject, val.transform);
				ListPrefab.SetActive(false);
				((Object)ListPrefab).name = "PluginSettingsItemList";
			}
			else
			{
				Plugin.Logger.LogError((object)"Could not find list prefab");
			}
			Plugin.Logger.LogInfo((object)"Loaded base setting UI prefabs");
		}

		private void EnableAllChildComponents(GameObject gameObject)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			MonoBehaviour[] components = gameObject.GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val in components)
			{
				((Behaviour)val).enabled = true;
			}
			foreach (Transform item in gameObject.transform)
			{
				Transform val2 = item;
				EnableAllChildComponents(((Component)val2).gameObject);
			}
		}
	}
	public class PluginSettingBool : PluginSetting<bool>
	{
		public PluginSettingBool(string settingKey, string settingName, bool defaultValue, string tooltip, string configSection, BepInPlugin owner)
			: base(settingKey, settingName, defaultValue, tooltip, configSection, owner)
		{
		}

		public override string GetValueText(bool value)
		{
			return PluginLocaliser.Translate(value ? "On" : "Off", Plugin.metadata);
		}
	}
	public class PluginSettingFloat : PluginSetting<float>
	{
		public float minValue { get; set; }

		public float maxValue { get; set; }

		public float steps { get; set; }

		public PluginSettingFloat(string settingKey, string settingName, string tooltip, string configSection, BepInPlugin owner, float defaultValue, float minValue = 0f, float maxValue = 1f, float steps = 0.1f)
			: base(settingKey, settingName, defaultValue, tooltip, configSection, owner)
		{
			this.minValue = minValue;
			this.maxValue = maxValue;
			this.steps = steps;
		}

		public override void SetValue(float value, bool save, bool pending, bool notify)
		{
			value = Normalize(value);
			if ((!pending || value != PendingValue) && (pending || value != Value))
			{
				base.SetValue(value, save, pending, notify);
			}
		}

		public float Normalize(float value)
		{
			value = Mathf.Clamp(value, minValue, maxValue);
			if (steps > 0f)
			{
				value = Mathf.Round(value / steps) * steps;
			}
			return value;
		}

		public override string GetValueText(float value)
		{
			return value.ToString("F" + CalculateDecimals());
		}

		private int CalculateDecimals()
		{
			if (steps == 0f || steps > 1f)
			{
				return 0;
			}
			return Mathf.CeilToInt(Mathf.Log10(steps) * -1f);
		}
	}
	public class PluginSettingList<T> : PluginSetting<int>
	{
		public List<PluginSettingListOption<T>> options;

		public Type optionType { get; protected set; }

		public int optionCount => options.Count;

		public PluginSettingList(string settingKey, string settingName, int defaultValue, string tooltip, string configSection, BepInPlugin owner, List<PluginSettingListOption<T>> options)
			: base(settingKey, settingName, defaultValue, tooltip, configSection, owner)
		{
			this.options = options;
			optionType = typeof(T);
			if (!this.options.Exists((PluginSettingListOption<T> option) => option.id == defaultValue))
			{
				Plugin.Logger.LogError((object)$"Default value id {defaultValue} not found in options for {settingKey}. Using first option instead");
				DefaultValue = this.options[0].id;
			}
		}

		public virtual PluginSettingListOption<T> GetCurrentOption()
		{
			return GetOptionById(Value);
		}

		public virtual PluginSettingListOption<T> GetPendingOption()
		{
			return GetOptionById(PendingValue);
		}

		public virtual PluginSettingListOption<T> GetOptionById(int id)
		{
			return options.Find((PluginSettingListOption<T> option) => option.id == id);
		}

		public virtual int GetOptionIndex(int id)
		{
			return options.FindIndex((PluginSettingListOption<T> option) => option.id == id);
		}

		public virtual int GetOptionIndex(PluginSettingListOption<T> value)
		{
			return options.IndexOf(value);
		}

		public override string GetValueText(int id)
		{
			return PluginLocaliser.Translate(GetOptionById(id).text, owner);
		}
	}
	public struct PluginSettingListOption<T>
	{
		public int id { get; set; }

		public string text { get; set; }

		public T value { get; set; }

		public PluginSettingListOption(int id, string text, T value)
		{
			this.id = id;
			this.text = text;
			this.value = value;
		}
	}
	public class PluginSettingListUIItem<T> : PluginSettingUIItem<PluginSettingList<T>, int>
	{
		protected TextMeshProUGUI valueLabel;

		protected Image imgLeftButton;

		protected Image imgRightButton;

		protected bool wrapAround = false;

		protected float arrowOffAlpha = 0.2f;

		protected RewiredAxisAction uiHorizontal;

		protected StaticStringLocaliser localiser;

		protected float holdTime;

		protected int lastInput;

		protected int selectedOptionIndex;

		public override GameObject Initialize(Transform parent, IPluginSetting setting)
		{
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Expected O, but got Unknown
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Expected O, but got Unknown
			if (!(setting is PluginSettingList<T> pluginSettingList))
			{
				Plugin.Logger.LogError((object)("Could not convert setting to PluginSettingList<T> with key " + setting?.settingKey));
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(SettingsUIPrefabs.ListPrefab, parent);
			((Object)val).name = setting.settingKey;
			SettingsItemList component = val.GetComponent<SettingsItemList>();
			Component val2 = val.AddComponent(((object)this).GetType());
			PluginSettingListUIItem<T> pluginSettingListUIItem = val2 as PluginSettingListUIItem<T>;
			if ((Object)(object)pluginSettingListUIItem == (Object)null)
			{
				Plugin.Logger.LogError((object)$"PluginSettingListUIItem Could not add component {((object)this).GetType()} to {((Object)val).name}");
				return null;
			}
			MeteorUtils.CopyComponentValues<SelectableElement>((SelectableElement)(object)component, (SelectableElement)(object)pluginSettingListUIItem, copyPrivate: true, (ICollection<string>)null, (ICollection<string>)null);
			pluginSettingListUIItem.setting = pluginSettingList;
			pluginSettingListUIItem.label = ((SettingsItem)component).label;
			pluginSettingListUIItem.isDirtyIndicator = ((SettingsItem)component).isDirtyIndicator;
			pluginSettingListUIItem.actionsToAddToControls = ((SettingsItem)component).actionsToAddToControls;
			pluginSettingListUIItem.settingChangedAudio = ((SettingsItem)component).settingChangedAudio;
			pluginSettingListUIItem.valueLabel = component.textLabel;
			pluginSettingListUIItem.imgLeftButton = component.imgLeftButton;
			pluginSettingListUIItem.imgRightButton = component.imgRightButton;
			pluginSettingListUIItem.wrapAround = component.wrapAround;
			pluginSettingListUIItem.arrowOffAlpha = component.arrowOffAlpha;
			pluginSettingListUIItem.uiHorizontal = component.uiHorizontal;
			pluginSettingListUIItem.localiser = component.Localiser;
			pluginSettingListUIItem.holdTime = component.holdTime;
			pluginSettingListUIItem.lastInput = component.lastInput;
			((UnityEvent)((Component)pluginSettingListUIItem.imgLeftButton).GetComponent<Button>().onClick).AddListener(new UnityAction(pluginSettingListUIItem.PreviousChoice));
			((UnityEvent)((Component)pluginSettingListUIItem.imgRightButton).GetComponent<Button>().onClick).AddListener(new UnityAction(pluginSettingListUIItem.NextChoice));
			StaticStringLocaliser component2 = ((Component)pluginSettingListUIItem.valueLabel).GetComponent<StaticStringLocaliser>();
			if ((Object)(object)component2 != (Object)null)
			{
				Object.Destroy((Object)(object)component2);
			}
			Object.Destroy((Object)(object)component);
			((Behaviour)component).enabled = false;
			Object.Destroy((Object)(object)((Component)this).gameObject);
			StaticStringLocaliser component3 = ((Component)((Component)pluginSettingListUIItem).transform.GetChild(0)).GetComponent<StaticStringLocaliser>();
			if ((Object)(object)component3 == (Object)null)
			{
				Plugin.Logger.LogError((object)"PluginSettingListUIItem Could not find localiser");
				return null;
			}
			component3.BaseText = setting.settingName;
			component3.Dictionary = PluginLocaliser.ConvertPluginToDictionaryName(setting.owner);
			val.SetActive(true);
			pluginSettingListUIItem.SelectOption(pluginSettingListUIItem.setting.GetOptionIndex(pluginSettingListUIItem.setting.Value), pending: false);
			pluginSettingListUIItem.Refresh();
			return val;
		}

		protected virtual void Update()
		{
			if (!((SelectableElement)this).isSelected || !((Interactable)this).IsInteractable())
			{
				return;
			}
			bool flag = RewiredExtensions.GetButtonDown(base.Player, uiHorizontal, (Dir)1);
			bool flag2 = RewiredExtensions.GetButtonDown(base.Player, uiHorizontal, (Dir)0);
			if (flag)
			{
				holdTime = 0f;
				lastInput = 1;
			}
			else if (flag2)
			{
				holdTime = 0f;
				lastInput = -1;
			}
			else if (lastInput != 0)
			{
				if (!RewiredExtensions.GetButton(base.Player, uiHorizontal, (Dir)(lastInput == 1)))
				{
					lastInput = 0;
				}
				else
				{
					holdTime += Time.deltaTime;
					if (holdTime >= Scr_InputMaster.Instance.TimeToHoldBeforeLoopInputs)
					{
						while (holdTime > Scr_InputMaster.Instance.TimeToHoldBeforeLoopInputs + Scr_InputMaster.Instance.TimeBetweenLoopInputs)
						{
							holdTime -= Scr_InputMaster.Instance.TimeBetweenLoopInputs;
							if (lastInput == 1)
							{
								flag = true;
							}
							else if (lastInput == -1)
							{
								flag2 = true;
							}
						}
					}
				}
			}
			if (flag)
			{
				PreviousChoice();
			}
			else if (flag2)
			{
				NextChoice();
			}
		}

		protected virtual void PreviousChoice()
		{
			SelectOption(selectedOptionIndex - 1, pending: true);
			Mgr_AudioPersistant.Instance.oneShotAudioSource.PlayOneShot(settingChangedAudio, ((SelectableElement)this).sfxVol);
		}

		protected virtual void NextChoice()
		{
			SelectOption(selectedOptionIndex + 1, pending: true);
			Mgr_AudioPersistant.Instance.oneShotAudioSource.PlayOneShot(settingChangedAudio, ((SelectableElement)this).sfxVol);
		}

		protected virtual void SelectOption(int index, bool pending)
		{
			if (index < 0)
			{
				Scr_GamepadManager.Instance.PlayGamepadFeedback(Scr_GamepadManager.SettingsListLeft, (Side)30, 1f, 1f);
				if (!wrapAround)
				{
					return;
				}
				index = base.setting.optionCount - 1;
			}
			else if (index >= base.setting.optionCount)
			{
				Scr_GamepadManager.Instance.PlayGamepadFeedback(Scr_GamepadManager.SettingsListRight, (Side)20, 1f, 1f);
				if (!wrapAround)
				{
					return;
				}
				index = 0;
			}
			selectedOptionIndex = index;
			SetValue(base.setting.options[index].id, save: false, pending, notify: true);
		}

		public override void SetValue(int id, bool save = false, bool pending = true, bool notify = true)
		{
			base.setting.SetValue(id, save, pending, notify);
			Refresh();
		}

		public override void RevertToDefault()
		{
			base.setting.RevertPendingValue();
			selectedOptionIndex = base.setting.GetOptionIndex(base.setting.Value);
			Mgr_AudioPersistant.Instance.oneShotAudioSource.PlayOneShot(settingChangedAudio, ((SelectableElement)this).sfxVol);
			Refresh();
		}

		protected override void OnLanguagedChanged()
		{
			Refresh();
		}

		protected override void Refresh()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			base.Refresh();
			RefreshValueLabel();
			if ((Object)(object)imgLeftButton != (Object)null)
			{
				Color color = ((Graphic)imgLeftButton).color;
				color.a = ((selectedOptionIndex > 0) ? 1f : arrowOffAlpha);
				((Graphic)imgLeftButton).color = color;
			}
			if ((Object)(object)imgRightButton != (Object)null)
			{
				Color color2 = ((Graphic)imgRightButton).color;
				color2.a = ((selectedOptionIndex < base.setting.optionCount - 1) ? 1f : arrowOffAlpha);
				((Graphic)imgRightButton).color = color2;
			}
		}

		protected virtual void RefreshValueLabel()
		{
			if ((Object)(object)valueLabel != (Object)null)
			{
				((TMP_Text)valueLabel).text = base.setting.GetPendingValueText();
			}
		}
	}
	public class PluginStringListSettingUIItem : PluginSettingListUIItem<string>
	{
	}
	public class PluginIntListSettingUIItem : PluginSettingListUIItem<int>
	{
	}
	public class PluginFloatListSettingUIItem : PluginSettingListUIItem<float>
	{
	}
	public class PluginBoolListSettingUIItem : PluginSettingListUIItem<bool>
	{
	}
	public class PluginSettingsPage : ElementListPage, IPluginSettingsPage
	{
		protected TextMeshProUGUI tooltipTitle;

		protected TextMeshProUGUI tooltip;

		protected TextMeshProUGUI defaultValueTip;

		protected LabelledRewiredAction revertToDefault;

		public List<IPluginSettingUIItem> settingsUIItems = new List<IPluginSettingUIItem>();

		protected IPluginSettingUIItem selectedSettingUIItem
		{
			get
			{
				if ((Object)(object)base.elementController == (Object)null || base.elementController.selectedElementIndex < 0)
				{
					return null;
				}
				return settingsUIItems[base.elementController.selectedElementIndex];
			}
		}

		public Transform settingsHolder { get; private set; }

		public List<IPluginSetting> settings { get; private set; }

		public override void OnEnable()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			((ElementListPage)this).OnEnable();
			RefreshTooltip(selectedSettingUIItem);
			LocalisationManager instance = LocalisationManager.Instance;
			instance.LanguageChanged = (Notify)Delegate.Combine((Delegate?)(object)instance.LanguageChanged, (Delegate?)new Notify(OnLanguagedChanged));
			if ((Object)(object)base.elementController != (Object)null && base.elementController.selectedElementIndex == -1)
			{
				base.elementController.SelectElement(0);
			}
		}

		protected override void OnDisable()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			((UIBehaviour)this).OnDisable();
			LocalisationManager instance = LocalisationManager.Instance;
			instance.LanguageChanged = (Notify)Delegate.Remove((Delegate?)(object)instance.LanguageChanged, (Delegate?)new Notify(OnLanguagedChanged));
		}

		protected override void OnDestroy()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			if ((Object)(object)LocalisationManager.Instance != (Object)null)
			{
				LocalisationManager instance = LocalisationManager.Instance;
				instance.LanguageChanged = (Notify)Delegate.Remove((Delegate?)(object)instance.LanguageChanged, (Delegate?)new Notify(OnLanguagedChanged));
			}
		}

		public override void Update()
		{
			if (((MenuPage)this).isActive && ((Interactable)this).IsInteractable())
			{
				((ElementListPage)this).Update();
				if (base.elementController.selectedElementIndex != -1 && base.player.GetButtonDown(revertToDefault.action))
				{
					selectedSettingUIItem.RevertToDefault();
				}
			}
		}

		public override void InitializePage()
		{
		}

		protected virtual void OnLanguagedChanged()
		{
			RefreshTooltip(selectedSettingUIItem);
		}

		public override void OnSelectionChanged(int previousIndex, int currentIndex)
		{
			if ((Object)(object)((MenuPage)this).selectionChangedAudio != (Object)null)
			{
				Mgr_AudioPersistant.instance.oneShotAudioSource.PlayOneShot(((MenuPage)this).selectionChangedAudio, ((MenuPage)this).sfxVol);
			}
			IPluginSettingUIItem settingUIItem = settingsUIItems[currentIndex];
			RefreshTooltip(settingUIItem);
			((MenuPage)this).UpdateControls();
		}

		protected virtual void RefreshTooltip(IPluginSettingUIItem settingUIItem)
		{
			if (!((Object)(object)tooltipTitle == (Object)null) && !((Object)(object)tooltip == (Object)null) && settingUIItem != null)
			{
				((TMP_Text)tooltipTitle).text = settingUIItem.settingInterface.GetSettingName();
				((TMP_Text)tooltip).text = settingUIItem.settingInterface.GetTooltip();
				string text = PluginLocaliser.Translate("Default", Plugin.metadata);
				string value = settingUIItem.settingInterface.DefaultValueText();
				if (string.IsNullOrEmpty(value))
				{
					((TMP_Text)defaultValueTip).text = "";
					return;
				}
				((TMP_Text)defaultValueTip).text = "(" + text + ": " + settingUIItem.settingInterface.DefaultValueText() + ")";
			}
		}

		public override void GetControlsToAdd(List<LabelledRewiredAction> actions)
		{
			((MenuPage)this).GetControlsToAdd(actions);
			if (base.elementController.selectedElementIndex != -1)
			{
				actions.Add(revertToDefault);
				actions.AddRange(settingsUIItems[base.elementController.selectedElementIndex].actionsToAddToControls);
			}
		}

		public virtual GameObject Initialize(string pageName, List<IPluginSetting> settings)
		{
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Expected O, but got Unknown
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			SettingsMenu val = Object.FindObjectOfType<SettingsMenu>(true);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Logger.LogError((object)"Could not find SettingsMenu GameObject");
				return null;
			}
			GameObject gameObject = ((Component)((TabbedMenu)val).pages[0]).gameObject;
			Transform parent = gameObject.transform.parent;
			GameObject val2 = Object.Instantiate<GameObject>(gameObject, parent);
			SettingsPage component = val2.GetComponent<SettingsPage>();
			PluginSettingsPage pluginSettingsPage = val2.AddComponent<PluginSettingsPage>();
			MeteorUtils.CopyComponentValues<MenuPage>((MenuPage)(object)component, (MenuPage)(object)pluginSettingsPage, copyPrivate: true, (ICollection<string>)null, (ICollection<string>)null);
			MeteorUtils.CopyComponentValues<ElementListPage>((ElementListPage)(object)component, (ElementListPage)(object)pluginSettingsPage, copyPrivate: true, (ICollection<string>)null, (ICollection<string>)null);
			pluginSettingsPage.tooltip = component.tooltip;
			pluginSettingsPage.tooltipTitle = component.tooltipTitle;
			pluginSettingsPage.defaultValueTip = component.defaultValueTip;
			pluginSettingsPage.revertToDefault = component.revertToDefault;
			((MenuPage)pluginSettingsPage).tabName = pageName;
			Array.Resize(ref ((TabbedMenu)val).pages, ((TabbedMenu)val).pages.Length + 1);
			((TabbedMenu)val).pages[((TabbedMenu)val).pages.Length - 1] = (MenuPage)(object)pluginSettingsPage;
			pluginSettingsPage.settingsHolder = val2.transform.Find("ContentCanvasGroup/ContentParent/Content/Viewport/Items/");
			if ((Object)(object)pluginSettingsPage.settingsHolder == (Object)null)
			{
				Plugin.Logger.LogError((object)"Could not get Items of newly instantiated settings page");
			}
			foreach (Transform item in pluginSettingsPage.settingsHolder)
			{
				Transform val3 = item;
				Object.Destroy((Object)(object)((Component)val3).gameObject);
			}
			RectTransform component2 = ((Component)pluginSettingsPage.settingsHolder).gameObject.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 1f);
			component2.pivot = new Vector2(0f, 1f);
			ContentSizeFitter val4 = ((Component)pluginSettingsPage.settingsHolder).gameObject.AddComponent<ContentSizeFitter>();
			val4.verticalFit = (FitMode)1;
			((Behaviour)component).enabled = false;
			Object.Destroy((Object)(object)component);
			Object.Destroy((Object)(object)((Component)this).gameObject);
			val2.SetActive(false);
			return val2;
		}

		public void OnInitialized()
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			if ((Object)(object)base.elementController == (Object)null)
			{
				Plugin.Logger.LogError((object)"Could not get ElementController in PluginSettingsPage");
				return;
			}
			List<SelectableElement> list = new List<SelectableElement>();
			foreach (IPluginSettingUIItem settingsUIItem in settingsUIItems)
			{
				SelectableElement[] components = settingsUIItem.gameObject.GetComponents<SelectableElement>();
				if (components.Length == 0)
				{
					Plugin.Logger.LogWarning((object)("SelectableElement not found for setting UI item " + settingsUIItem.settingInterface?.settingKey));
					continue;
				}
				SelectableElement[] array = components;
				foreach (SelectableElement val in array)
				{
					if (((Behaviour)val).enabled)
					{
						list.Add(val);
					}
				}
			}
			SelectableGroupController elementController = base.elementController;
			elementController.onSelectionChanged = (SelectionChangeCallback)Delegate.Combine((Delegate?)(object)elementController.onSelectionChanged, (Delegate?)new SelectionChangeCallback(((ElementListPage)this).OnSelectionChanged));
			base.elementController.SetSelectableList(list.ToArray());
			((ElementListPage)this).SetElements(list.ToArray());
		}

		public void AddSettingUIItem(IPluginSettingUIItem setting)
		{
			settingsUIItems.Add(setting);
		}
	}
	public class PluginSettingSliderUIItem : PluginSettingUIItem<PluginSettingFloat, float>
	{
		protected TextMeshProUGUI valueLabel;

		protected Slider slider;

		protected RewiredAxisAction uiHorizontal;

		protected float holdTime;

		protected int lastInput;

		public override GameObject Initialize(Transform parent, IPluginSetting setting)
		{
			if (!(setting is PluginSettingFloat pluginSettingFloat))
			{
				Plugin.Logger.LogError((object)("Could not convert setting to PluginSettingFloat with key " + setting?.settingKey));
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(SettingsUIPrefabs.SliderPrefab, parent);
			((Object)val).name = setting.settingKey;
			SettingsItemSlider component = val.GetComponent<SettingsItemSlider>();
			PluginSettingSliderUIItem pluginSettingSliderUIItem = val.AddComponent<PluginSettingSliderUIItem>();
			MeteorUtils.CopyComponentValues<SelectableElement>((SelectableElement)(object)component, (SelectableElement)(object)pluginSettingSliderUIItem, copyPrivate: true, (ICollection<string>)null, (ICollection<string>)null);
			pluginSettingSliderUIItem.setting = pluginSettingFloat;
			pluginSettingSliderUIItem.label = ((SettingsItem)component).label;
			pluginSettingSliderUIItem.isDirtyIndicator = ((SettingsItem)component).isDirtyIndicator;
			pluginSettingSliderUIItem.actionsToAddToControls = ((SettingsItem)component).actionsToAddToControls;
			pluginSettingSliderUIItem.settingChangedAudio = ((SettingsItem)component).settingChangedAudio;
			pluginSettingSliderUIItem.valueLabel = component.textLabel;
			pluginSettingSliderUIItem.slider = component.slider;
			pluginSettingSliderUIItem.uiHorizontal = component.uiHorizontal;
			pluginSettingSliderUIItem.holdTime = component.holdTime;
			pluginSettingSliderUIItem.lastInput = component.lastInput;
			Slider componentInChildren = ((Component)pluginSettingSliderUIItem).GetComponentInChildren<Slider>();
			((UnityEvent<float>)(object)componentInChildren.onValueChanged).AddListener((UnityAction<float>)pluginSettingSliderUIItem.OnSliderValueChanged);
			componentInChildren.maxValue = pluginSettingFloat.maxValue;
			componentInChildren.minValue = pluginSettingFloat.minValue;
			componentInChildren.wholeNumbers = false;
			Object.Destroy((Object)(object)component);
			((Behaviour)component).enabled = false;
			Object.Destroy((Object)(object)((Component)this).gameObject);
			StaticStringLocaliser component2 = ((Component)((Component)pluginSettingSliderUIItem).transform.GetChild(0)).GetComponent<StaticStringLocaliser>();
			if ((Object)(object)component2 == (Object)null)
			{
				Plugin.Logger.LogError((object)"PluginSettingSliderUIItem Could not find localiser");
				return null;
			}
			component2.BaseText = setting.settingName;
			component2.Dictionary = PluginLocaliser.ConvertPluginToDictionaryName(setting.owner);
			val.SetActive(true);
			pluginSettingSliderUIItem.slider.value = pluginSettingFloat.Value;
			pluginSettingSliderUIItem.Refresh();
			return val;
		}

		protected virtual void Update()
		{
			if (!((SelectableElement)this).isSelected || !((Interactable)this).IsInteractable())
			{
				return;
			}
			bool flag = RewiredExtensions.GetButtonDown(base.Player, uiHorizontal, (Dir)1);
			bool flag2 = RewiredExtensions.GetButtonDown(base.Player, uiHorizontal, (Dir)0);
			if (flag)
			{
				holdTime = 0f;
				lastInput = 1;
			}
			else if (flag2)
			{
				holdTime = 0f;
				lastInput = -1;
			}
			else if (lastInput != 0)
			{
				if (!RewiredExtensions.GetButton(base.Player, uiHorizontal, (Dir)(lastInput == 1)))
				{
					lastInput = 0;
				}
				else
				{
					holdTime += Time.deltaTime;
					if (holdTime >= Scr_InputMaster.Instance.TimeToHoldBeforeLoopInputs)
					{
						while (holdTime > Scr_InputMaster.Instance.TimeToHoldBeforeLoopInputs + Scr_InputMaster.Instance.TimeBetweenLoopInputs)
						{
							holdTime -= Scr_InputMaster.Instance.TimeBetweenLoopInputs;
							if (lastInput == 1)
							{
								flag = true;
							}
							else if (lastInput == -1)
							{
								flag2 = true;
							}
						}
					}
				}
			}
			if (flag)
			{
				MoveDownStep();
			}
			else if (flag2)
			{
				MoveUpStep();
			}
		}

		private void MoveDownStep()
		{
			SetValue(base.setting.PendingValue - base.setting.steps, save: false, pending: true, notify: true);
		}

		private void MoveUpStep()
		{
			SetValue(base.setting.PendingValue + base.setting.steps, save: false, pending: true, notify: true);
		}

		public override void SetValue(float value, bool save = false, bool pending = true, bool notify = true)
		{
			value = base.setting.Normalize(value);
			slider.value = value;
			base.setting.SetValue(value, save, pending, notify);
			Refresh();
		}

		public override void RevertToDefault()
		{
			if (!IsDirty())
			{
				RefreshDirtyIndicator();
				return;
			}
			Mgr_AudioPersistant.Instance.oneShotAudioSource.PlayOneShot(settingChangedAudio, ((SelectableElement)this).sfxVol);
			base.setting.SetValue(base.setting.DefaultValue, save: false, pending: false, notify: true);
			RefreshDirtyIndicator();
			slider.value = base.setting.DefaultValue;
		}

		protected override void OnLanguagedChanged()
		{
		}

		protected virtual void OnSliderValueChanged(float value)
		{
			value = base.setting.Normalize(value);
			slider.value = value;
			if (value != base.setting.PendingValue)
			{
				Mgr_AudioPersistant.Instance.oneShotAudioSource.PlayOneShot(settingChangedAudio, ((SelectableElement)this).sfxVol);
				if (value > base.setting.PendingValue)
				{
					Scr_GamepadManager.Instance.PlayGamepadFeedback(Scr_GamepadManager.SettingsListLeft, (Side)30, 1f, 1f);
				}
				else
				{
					Scr_GamepadManager.Instance.PlayGamepadFeedback(Scr_GamepadManager.SettingsListRight, (Side)20, 1f, 1f);
				}
				base.setting.SetValue(value, save: false, pending: true, notify: true);
				Refresh();
			}
		}

		protected override void Refresh()
		{
			base.Refresh();
			RefreshDirtyIndicator();
			if (base.setting != null)
			{
				((TMP_Text)valueLabel).text = base.setting.GetPendingValueText();
			}
		}
	}
	public class PluginSettingToggleUIItem : PluginSettingUIItem<PluginSettingBool, bool>
	{
		private Image background;

		private RectTransform knobParent;

		private RectTransform knob;

		private TextMeshProUGUI valueLabel;

		private Coroutine animCoroutine;

		private float animT;

		private float animTotalTime = 0.1f;

		private Color toggledOffColor = Color.gray;

		private Color toggledOnColor = Color.white;

		public int input_select { get; set; }

		public override GameObject Initialize(Transform parent, IPluginSetting setting)
		{
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			if (!(setting is PluginSettingBool pluginSettingBool))
			{
				Plugin.Logger.LogError((object)("Could not convert setting to PluginSettingBool with key " + setting?.settingKey));
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(SettingsUIPrefabs.TogglePrefab, parent);
			((Object)val).name = setting.settingKey;
			SettingsItemToggle component = val.GetComponent<SettingsItemToggle>();
			PluginSettingToggleUIItem pluginSettingToggleUIItem = val.AddComponent<PluginSettingToggleUIItem>();
			MeteorUtils.CopyComponentValues<SelectableElement>((SelectableElement)(object)component, (SelectableElement)(object)pluginSettingToggleUIItem, copyPrivate: true, (ICollection<string>)null, (ICollection<string>)null);
			pluginSettingToggleUIItem.setting = pluginSettingBool;
			pluginSettingToggleUIItem.label = ((SettingsItem)component).label;
			pluginSettingToggleUIItem.isDirtyIndicator = ((SettingsItem)component).isDirtyIndicator;
			pluginSettingToggleUIItem.actionsToAddToControls = ((SettingsItem)component).actionsToAddToControls;
			pluginSettingToggleUIItem.settingChangedAudio = ((SettingsItem)component).settingChangedAudio;
			pluginSettingToggleUIItem.knob = component.knob;
			pluginSettingToggleUIItem.knobParent = component.knobParent;
			pluginSettingToggleUIItem.background = component.background;
			pluginSettingToggleUIItem.valueLabel = component.valueLabel;
			pluginSettingToggleUIItem.animCoroutine = component.animCoroutine;
			pluginSettingToggleUIItem.toggledOffColor = component.toggledOffColor;
			pluginSettingToggleUIItem.toggledOnColor = component.toggledOnColor;
			pluginSettingToggleUIItem.input_select = component.input_select;
			((UnityEvent)((Component)pluginSettingToggleUIItem).GetComponentInChildren<Button>().onClick).AddListener(new UnityAction(pluginSettingToggleUIItem.Toggle));
			Object.Destroy((Object)(object)component);
			((Behaviour)component).enabled = false;
			Object.Destroy((Object)(object)((Component)this).gameObject);
			StaticStringLocaliser component2 = ((Component)((Component)pluginSettingToggleUIItem).transform.GetChild(0)).GetComponent<StaticStringLocaliser>();
			if ((Object)(object)component2 == (Object)null)
			{
				Plugin.Logger.LogError((object)"PluginSettingToggleUIItem Could not find localiser");
				return null;
			}
			component2.BaseText = setting.settingName;
			component2.Dictionary = PluginLocaliser.ConvertPluginToDictionaryName(setting.owner);
			val.SetActive(true);
			pluginSettingToggleUIItem.RefreshLabel();
			return val;
		}

		public override void OnEnable()
		{
			base.OnEnable();
			OnLanguagedChanged();
		}

		public virtual void Update()
		{
			if (((SelectableElement)this).isSelected && ((Interactable)this).IsInteractable() && base.Player.GetButtonDown(input_select))
			{
				Toggle();
			}
		}

		public virtual void Toggle()
		{
			Mgr_AudioPersistant.Instance.oneShotAudioSource.PlayOneShot(settingChangedAudio, ((SelectableElement)this).sfxVol);
			SetValue(!base.setting.PendingValue, save: false, pending: true, notify: true);
			RefreshLabel();
		}

		public override void SetValue(bool value, bool save = false, bool pending = true, bool notify = true)
		{
			base.setting.SetValue(value, save, pending, notify);
			RefreshDirtyIndicator();
			TriggerAnimation();
		}

		public override void RevertToDefault()
		{
			if (IsDirty())
			{
				Mgr_AudioPersistant.Instance.oneShotAudioSource.PlayOneShot(settingChangedAudio, ((SelectableElement)this).sfxVol);
				base.setting.SetValue(base.setting.DefaultValue, save: false, pending: false, notify: true);
				RefreshDirtyIndicator();
				TriggerAnimation();
			}
		}

		protected virtual void RefreshLabel()
		{
			SetT(base.setting.PendingValue ? 1f : 0f);
			OnLanguagedChanged();
		}

		protected override void OnLanguagedChanged()
		{
			if ((Object)(object)valueLabel != (Object)null)
			{
				((TMP_Text)valueLabel).text = base.setting.GetPendingValueText();
			}
		}

		private void TriggerAnimation()
		{
			if (animCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(animCoroutine);
			}
			animCoroutine = ((MonoBehaviour)this).StartCoroutine(AnimCoroutine(base.setting.PendingValue));
		}

		private IEnumerator AnimCoroutine(bool on)
		{
			float goTo = (on ? 1f : 0f);
			float currentT = animT;
			float time = 0f;
			while (time < animTotalTime)
			{
				time += Time.deltaTime;
				SetT(Mathf.Lerp(currentT, goTo, time / animTotalTime));
				yield return null;
			}
		}

		private void SetT(float t)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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)
			//IL_006e: 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)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)knob == (Object)null) && !((Object)(object)background == (Object)null) && !((Object)(object)knobParent == (Object)null))
			{
				animT = t;
				((Graphic)background).color = Color.Lerp(toggledOffColor, toggledOnColor, t);
				RectTransform obj = knob;
				Rect rect = knobParent.rect;
				float width = ((Rect)(ref rect)).width;
				rect = knob.rect;
				obj.anchoredPosition = new Vector2(Mathf.Lerp(2f, width - ((Rect)(ref rect)).width - 2f, t), knob.anchoredPosition.y);
			}
		}
	}
}
namespace MeteorCore.Setting.Interfaces
{
	public interface IPluginSetting<T> : IPluginSetting
	{
		T Value { get; }

		T PendingValue { get; }

		T DefaultValue { get; }

		event Action<IPluginSetting<T>> OnAppliedPendingValue;

		event Action<IPluginSetting<T>> OnRevertedPendingValue;

		event Action<IPluginSetting<T>> OnPendingValueChanged;

		event Action<IPluginSetting<T>> OnValueChanged;

		void SetValue(T value, bool save, bool pending, bool notify);

		string GetValueText(T value);
	}
	public interface IPluginSettingsPage
	{
		Transform settingsHolder { get; }

		List<IPluginSetting> settings { get; }

		GameObject Initialize(string pageName, List<IPluginSetting> settings);

		void OnInitialized();

		void AddSettingUIItem(IPluginSettingUIItem setting);
	}
	public interface IPluginSettingUIItem<T, D> : IPluginSettingUIItem where T : IPluginSetting<D>
	{
		T setting { get; }

		void SetValue(D value, bool save, bool pending, bool notify);

		void SetSetting(T setting);
	}
}
namespace MeteorCore.Setting.Interfaces.Internal
{
	public interface IPluginSetting
	{
		object BoxedValue { get; }

		bool isDirty { get; }

		Type type { get; }

		string settingKey { get; }

		string configSection { get; }

		string tooltip { get; }

		string settingName { get; }

		BepInPlugin owner { get; }

		void SetValue(object value, bool save, bool pending, bool notify);

		void ApplyPendingValue();

		void RevertPendingValue();

		string DefaultValueText();

		string GetCurrentValueText();

		string GetPendingValueText();

		string GetSettingName();

		string GetTooltip();
	}
	public interface IPluginSettingUIItem
	{
		IPluginSetting settingInterface { get; }

		GameObject isDirtyIndicator { get; }

		TextMeshProUGUI label { get; }

		GameObject gameObject { get; }

		List<LabelledRewiredAction> actionsToAddToControls { get; }

		GameObject Initialize(Transform parent, IPluginSetting setting);

		void SetSettingInternal(IPluginSetting setting);

		void RevertToDefault();
	}
}
namespace MeteorCore.Setting.AbstractClasses
{
	public abstract class PluginSetting<T> : IPluginSetting<T>, IPluginSetting
	{
		public virtual object BoxedValue
		{
			get
			{
				return Value;
			}
			set
			{
				Value = (T)value;
			}
		}

		public virtual T Value { get; private set; }

		public virtual T PendingValue { get; protected set; }

		public virtual T DefaultValue { get; protected set; }

		public virtual string tooltip { get; protected set; }

		public virtual string configSection { get; protected set; }

		public virtual BepInPlugin owner { get; protected set; }

		public virtual Type type => typeof(T);

		public virtual string settingKey { get; }

		public virtual string settingName { get; }

		public virtual bool isDirty { get; protected set; }

		public event Action<IPluginSetting<T>> OnAppliedPendingValue;

		public event Action<IPluginSetting<T>> OnRevertedPendingValue;

		public event Action<IPluginSetting<T>> OnPendingValueChanged;

		public event Action<IPluginSetting<T>> OnValueChanged;

		public PluginSetting(string settingKey, string settingName, T defaultValue, string tooltip, string configSection, BepInPlugin owner)
		{
			this.settingKey = settingKey;
			this.settingName = settingName;
			DefaultValue = defaultValue;
			this.tooltip = tooltip;
			this.configSection = configSection;
			this.owner = owner;
			isDirty = false;
		}

		public virtual void SetValue(T value, bool save, bool pending, bool notify)
		{
			if (pending)
			{
				PendingValue = value;
				isDirty = true;
				this.OnPendingValueChanged?.Invoke(this);
			}
			else
			{
				Value = value;
				PendingValue = value;
				isDirty = false;
				this.OnValueChanged?.Invoke(this);
			}
			if (save)
			{
				Mgr_PluginSettings.Instance.SaveSettings();
			}
		}

		public virtual void SetValue(object value, bool save, bool pending, bool notify)
		{
			if (!(value is T))
			{
				Plugin.Logger.LogError((object)$"Setting {settingKey} could not be set to {value} because it is not of type {typeof(T)}");
			}
			else
			{
				SetValue((T)value, save, pending, notify);
			}
		}

		public virtual void ApplyPendingValue()
		{
			SetValue(PendingValue, save: false, pending: false, notify: true);
			this.OnAppliedPendingValue?.Invoke(this);
		}

		public virtual void RevertPendingValue()
		{
			PendingValue = Value;
			isDirty = false;
			this.OnRevertedPendingValue?.Invoke(this);
		}

		public virtual string GetValueText(T value)
		{
			return PluginLocaliser.Translate(value.ToString(), owner);
		}

		public virtual string DefaultValueText()
		{
			return GetValueText(DefaultValue);
		}

		public virtual string GetCurrentValueText()
		{
			return GetValueText(Value);
		}

		public virtual string GetPendingValueText()
		{
			return GetValueText(PendingValue);
		}

		public virtual string GetSettingName()
		{
			return PluginLocaliser.Translate(settingName, owner);
		}

		public virtual string GetTooltip()
		{
			return PluginLocaliser.Translate(tooltip, owner);
		}
	}
	public abstract class PluginSettingUIItem<T, D> : SelectableElement, IPluginSettingUIItem<T, D>, IPluginSettingUIItem where T : IPluginSetting<D>
	{
		public AudioClip settingChangedAudio;

		public T setting { get; protected set; }

		public IPluginSetting settingInterface => setting;

		public GameObject isDirtyIndicator { get; protected set; }

		public TextMeshProUGUI label { get; protected set; }

		public List<LabelledRewiredAction> actionsToAddToControls { get; protected set; }

		public Player Player => Scr_InputMaster.Instance.Player;

		public virtual GameObject Initialize(Transform parent, IPluginSetting setting)
		{
			Plugin.Logger.LogWarning((object)"Using Initialize from base PluginSettingUIItem is not recommended");
			T val = (T)(setting as IPluginSetting<D>);
			if (val == null)
			{
				Plugin.Logger.LogError((object)"Could not convert setting to IPluginSetting<D>");
				Plugin.Logger.LogError((object)$"Setting type: {setting.GetType()}");
				Plugin.Logger.LogError((object)("With key " + setting.settingKey));
				return null;
			}
			this.setting = val;
			return null;
		}

		public virtual void SetSetting(T setting)
		{
			this.setting = setting;
		}

		public virtual void SetSettingInternal(IPluginSetting setting)
		{
			this.setting = (T)setting;
		}

		protected override void Awake()
		{
			((UIBehaviour)this).Awake();
			base._selectOnPointerEnter = true;
		}

		public override void OnEnable()
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			((SelectableElement)this).OnEnable();
			Refresh();
			if (setting != null)
			{
				T val = setting;
				val.OnAppliedPendingValue += OnApplied;
				val = setting;
				val.OnRevertedPendingValue += OnRevert;
			}
			LocalisationManager instance = LocalisationManager.Instance;
			instance.LanguageChanged = (Notify)Delegate.Combine((Delegate?)(object)instance.LanguageChanged, (Delegate?)new Notify(OnLanguagedChanged));
		}

		public override void OnDisable()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			((SelectableElement)this).OnDisable();
			if (setting != null)
			{
				T val = setting;
				val.OnAppliedPendingValue -= OnApplied;
				val = setting;
				val.OnRevertedPendingValue -= OnRevert;
			}
			LocalisationManager instance = LocalisationManager.Instance;
			instance.LanguageChanged = (Notify)Delegate.Remove((Delegate?)(object)instance.LanguageChanged, (Delegate?)new Notify(OnLanguagedChanged));
		}

		protected override void OnDestroy()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			if (setting != null)
			{
				T val = setting;
				val.OnAppliedPendingValue -= OnApplied;
				val = setting;
				val.OnRevertedPendingValue -= OnRevert;
			}
			LocalisationManager instance = LocalisationManager.Instance;
			instance.LanguageChanged = (Notify)Delegate.Remove((Delegate?)(object)instance.LanguageChanged, (Delegate?)new Notify(OnLanguagedChanged));
		}

		private void OnApplied(IPluginSetting<D> setting)
		{
			Refresh();
		}

		private void OnRevert(IPluginSetting<D> setting)
		{
			Refresh();
		}

		protected virtual void Refresh()
		{
			RefreshDirtyIndicator();
			RefreshNameLabel();
		}

		protected virtual void RefreshDirtyIndicator()
		{
			GameObject obj = isDirtyIndicator;
			if (obj != null)
			{
				obj.SetActive(IsDirty());
			}
		}

		protected virtual void RefreshNameLabel()
		{
			if ((Object)(object)label != (Object)null && setting != null)
			{
				((TMP_Text)label).text = setting.GetSettingName();
			}
		}

		protected virtual bool IsDirty()
		{
			T val = setting;
			return val != null && val.isDirty;
		}

		public abstract void SetValue(D value, bool save, bool pending, bool notify);

		public abstract void RevertToDefault();

		protected abstract void OnLanguagedChanged();

		GameObject IPluginSettingUIItem.get_gameObject()
		{
			return ((Component)this).gameObject;
		}
	}
}
namespace MeteorCore.Localiser
{
	public static class PluginLocaliser
	{
		public static Dictionary<string, PluginDictionary> dictionaries = new Dictionary<string, PluginDictionary>();

		public static bool ignoreMissingTranslations = false;

		public static string language => Enum.GetName(typeof(Language), LocalisationManager.Instance.CurrentLanguage);

		public static string ConvertPluginToDictionaryName(BepInPlugin plugin)
		{
			return plugin.Name;
		}

		public static string Translate(string key, BepInPlugin plugin)
		{
			return Translate(key, ConvertPluginToDictionaryName(plugin));
		}

		public static string Translate(string key, string dictionaryName, bool returnNullIfNotFound = false)
		{
			if (dictionaries.ContainsKey(dictionaryName))
			{
				string text = dictionaries[dictionaryName].Translate(key);
				if (!Utility.IsNullOrWhiteSpace(text))
				{
					return text;
				}
			}
			foreach (KeyValuePair<string, PluginDictionary> dictionary in dictionaries)
			{
				string text2 = dictionary.Value.TranslateFromAdditionalDictionary(key, dictionaryName, language);
				if (!Utility.IsNullOrWhiteSpace(text2))
				{
					return text2;
				}
			}
			if (ignoreMissingTranslations)
			{
				return key;
			}
			Plugin.Logger.LogWarning((object)("Could not find translation for key " + key + " in dictionary " + dictionaryName));
			if (returnNullIfNotFound)
			{
				return null;
			}
			return GetTranslationNotFoundString(key, dictionaryName);
		}

		internal static string GetTranslationNotFoundString(string key, string dictionaryName)
		{
			return "\"No '" + key + "' translation in " + dictionaryName + "\"";
		}

		public static PluginDictionary RegisterPlugin(BepInPlugin plugin, string dictionaryPath = null, string projectName = null)
		{
			if (projectName == null)
			{
				projectName = plugin.Name;
			}
			string text = ConvertPluginToDictionaryName(plugin);
			if (dictionaries.ContainsKey(text))
			{
				Plugin.Logger.LogWarning((object)("Plugin " + projectName + " already has a dictionary registered with name " + text));
				return dictionaries[text];
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			Assembly assembly = null;
			Assembly[] array = assemblies;
			foreach (Assembly assembly2 in array)
			{
				if (assembly2.GetName().Name == projectName)
				{
					assembly = assembly2;
				}
			}
			if (assembly == null)
			{
				Plugin.Logger.LogError((object)("Plugin " + projectName + " has no loaded assembly. Does it have the same name as the plugin?"));
				return null;
			}
			string text2 = dictionaryPath ?? (projectName + ".Assets.localisation.json");
			Stream manifestResourceStream = assembly.GetManifestResourceStream(text2);
			if (manifestResourceStream == null)
			{
				Plugin.Logger.LogError((object)("Could not find dictionary asset at path " + text2 + " for plugin " + plugin.Name + ". Use embedded resource as the dictionary asset's Build Action property and place the dictionary inside the Assets folder."));
				return null;
			}
			using StreamReader streamReader = new StreamReader(manifestResourceStream);
			string text3 = streamReader.ReadToEnd();
			if (string.IsNullOrEmpty(text3))
			{
				Plugin.Logger.LogError((object)("Dictionary asset at path " + text2 + " for plugin " + plugin.Name + " is empty"));
				return null;
			}
			PluginDictionary pluginDictionary;
			try
			{
				pluginDictionary = JsonConvert.DeserializeObject<PluginDictionary>(text3);
				if (pluginDictionary == null)
				{
					Plugin.Logger.LogError((object)("Could not parse dictionary asset at path " + text2 + " for plugin " + plugin.Name + ", it is null"));
					return null;
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Could not parse dictionary asset at path " + text2 + " for plugin " + plugin.Name));
				Plugin.Logger.LogError((object)ex);
				throw ex;
			}
			pluginDictionary.name = text;
			pluginDictionary.plugin = plugin;
			dictionaries.Add(text, pluginDictionary);
			Plugin.Logger.LogInfo((object)("Plugin " + projectName + " registered with dictionary " + text));
			return pluginDictionary;
		}
	}
}
namespace MeteorCore.Localiser.Dictionaries
{
	[JsonObject(/*Could not decode attribute arguments.*/)]
	public class PluginDictionary
	{
		public string name { get; set; }

		public BepInPlugin plugin { get; set; }

		[JsonProperty("dictionary")]
		public Dictionary<string, Dictionary<string, string>> dictionary { get; set; }

		[JsonProperty("additionalDictionaries")]
		public Dictionary<string, Dictionary<string, Dictionary<string, string>>> additionalDictionaries { get; set; }

		[OnDeserialized]
		private void OnDeserialized(StreamingContext context)
		{
			if (dictionary == null)
			{
				Plugin.Logger.LogWarning((object)("Plugin " + name + " dictionary file does not include dictionary field"));
				dictionary = new Dictionary<string, Dictionary<string, string>>();
			}
			if (additionalDictionaries == null)
			{
				Plugin.Logger.LogInfo((object)("Plugin " + name + " dictionary file does not include additionalDictionaries field"));
				additionalDictionaries = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
			}
		}

		public string Translate(string key)
		{
			return Translate(key, PluginLocaliser.language);
		}

		public string Translate(string key, string language)
		{
			if (dictionary.ContainsKey(language) && dictionary[language].ContainsKey(key))
			{
				return dictionary[language][key];
			}
			if (PluginLocaliser.ignoreMissingTranslations)
			{
				return key;
			}
			return null;
		}

		public bool HasAdditionalDictionary(string dictionaryName)
		{
			return additionalDictionaries.ContainsKey(dictionaryName);
		}

		public string TranslateFromAdditionalDictionary(string key, string dictionaryName, string language)
		{
			if (additionalDictionaries.ContainsKey(dictionaryName) && additionalDictionaries[dictionaryName].ContainsKey(language) && additionalDictionaries[dictionaryName][language].ContainsKey(key))
			{
				return additionalDictionaries[dictionaryName][language][key];
			}
			return null;
		}

		public override string ToString()
		{
			string text = "PluginDictionary: " + name + "\n";
			foreach (KeyValuePair<string, Dictionary<string, string>> item in dictionary)
			{
				text = text + item.Key + "\n";
				foreach (KeyValuePair<string, string> item2 in item.Value)
				{
					text = text + item2.Key + ": " + item2.Value + "\n";
				}
			}
			foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, string>>> additionalDictionary in additionalDictionaries)
			{
				text = text + "Additional Dictionaries: " + additionalDictionary.Key + "\n";
				foreach (KeyValuePair<string, Dictionary<string, string>> item3 in additionalDictionary.Value)
				{
					text = text + item3.Key + "\n";
					foreach (KeyValuePair<string, string> item4 in item3.Value)
					{
						text = text + item4.Key + ": " + item4.Value + "\n";
					}
				}
			}
			return text;
		}
	}
}
namespace MeteorCore.Localiser.Patches
{
	[HarmonyPatch(typeof(LocalisationManager), "TranslateDialogue")]
	public class PluginLocalisationPatcher
	{
		public static void Postfix(ref string __result)
		{
			if (__result.Contains("No translation found"))
			{
				string text = __result.Replace("No translation found for '", "");
				text = text.Substring(0, text.IndexOf("' in"));
				string dictionaryName = __result.Substring(__result.IndexOf(" in ") + 4);
				string text2 = PluginLocaliser.Translate(text, dictionaryName);
				__result = text2;
			}
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldloc_0 && list[i + 1].opcode == OpCodes.Call && list[i + 1].operand is MethodInfo methodInfo && methodInfo.Name == "LogError")
				{
					list[i].opcode = OpCodes.Nop;
					list[i + 1].opcode = OpCodes.Nop;
					Plugin.Logger.LogInfo((object)"LocalisationManager.TranslateDialogue Patch Success");
					return list;
				}
			}
			Plugin.Logger.LogError((object)"LocalisationManager.TranslateDialogue Patch Failed");
			return list;
		}
	}
}