Decompiled source of BoplTranslator v2.0.1

BoplTranslator.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("BoplTranslator")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Custom translation support for Bopl Battle")]
[assembly: AssemblyFileVersion("2.0.1.0")]
[assembly: AssemblyInformationalVersion("2.0.1+91ea9bba8bc487602bef1d62c569cc140e497ae5")]
[assembly: AssemblyProduct("BoplTranslator")]
[assembly: AssemblyTitle("BoplTranslator")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.1.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 BoplTranslator
{
	public enum GameFont
	{
		English,
		Japanese,
		Korean,
		Russian,
		Chinese,
		Polish
	}
	public class CustomLanguage
	{
		internal Dictionary<string, string> translationPairs = new Dictionary<string, string>();

		public string Name { get; internal set; }

		public GameFont Font { get; set; }

		public bool IsReferenced { get; private set; }

		public string this[string guid]
		{
			get
			{
				return GetTranslation(guid);
			}
			set
			{
				EditTranslation(guid, value);
			}
		}

		public CustomLanguage(string name, GameFont font = GameFont.English)
			: this(name, font, copyFallback: true)
		{
		}

		public string GetTranslation(string guid)
		{
			return translationPairs[guid];
		}

		public void EditTranslation(string guid, string newTranslation)
		{
			translationPairs[guid] = newTranslation.ToLower();
		}

		public void EditTranslations(Dictionary<string, string> guidTranslationPair)
		{
			foreach (KeyValuePair<string, string> item in guidTranslationPair)
			{
				translationPairs[item.Key] = item.Value.ToLower();
			}
		}

		internal CustomLanguage(string name, GameFont font, bool copyFallback)
		{
			name = name.ToLower();
			CustomLanguage customLanguage = BoplTranslator.GetCustomLanguage(name);
			if (customLanguage != null)
			{
				Name = customLanguage.Name;
				Font = customLanguage.Font;
				translationPairs = customLanguage.translationPairs;
				IsReferenced = true;
				return;
			}
			Name = name;
			Font = font;
			if (copyFallback)
			{
				CustomLanguage fallbackLanguage = LanguagePatch.fallbackLanguage;
				translationPairs = new Dictionary<string, string>(fallbackLanguage.translationPairs) { ["name"] = name };
				LanguagePatch.customLanguages.Add(this);
			}
		}
	}
	public static class BoplTranslator
	{
		private static readonly FieldInfo textToLocalize2Field = typeof(LocalizedText).GetField("textToLocalize2", AccessTools.all);

		public static void UpdateTexts()
		{
			LocalizedText[] array = Resources.FindObjectsOfTypeAll<LocalizedText>();
			foreach (LocalizedText val in array)
			{
				try
				{
					val.UpdateText();
				}
				catch (Exception arg)
				{
					if (textToLocalize2Field.GetValue(val) != null)
					{
						Plugin.logger.LogFatal((object)$"Error at updateText: {arg}");
						Plugin.logger.LogFatal((object)("name: " + ((Object)val).name + ", enText: " + ((LanguagePatch.textField.GetValue(val) as string) ?? "null")));
					}
				}
			}
		}

		public static bool IsCustomLanguage(this Language lang)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			return (int)lang > LanguagePatch.OGLanguagesCount;
		}

		public static CustomLanguage GetCustomLanguage(Language lang)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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: Expected I4, but got Unknown
			if (!lang.IsCustomLanguage())
			{
				return LanguagePatch.ogLanguages[(int)lang];
			}
			return LanguagePatch.GetCustomLanguage(lang);
		}

		public static CustomLanguage GetCustomLanguage(string langName)
		{
			langName = langName.ToLower();
			CustomLanguage customLanguage = LanguagePatch.ogLanguages.Find((CustomLanguage e) => e.Name == langName);
			if (customLanguage != null)
			{
				return customLanguage;
			}
			return LanguagePatch.customLanguages.Find((CustomLanguage e) => e.Name == langName);
		}

		public static CustomLanguage GetCurrentLanguage()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return GetCustomLanguage(Settings.Get().Language);
		}

		public static LocalizedText AttachLocalizedText(GameObject textObject, string translationGUID, bool stroke = false)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)textObject == (Object)null)
			{
				throw new ArgumentNullException("textObject");
			}
			LocalizedText component = textObject.GetComponent<LocalizedText>();
			LocalizedText val = component ?? textObject.AddComponent<LocalizedText>();
			Traverse val2 = new Traverse((object)val);
			LanguagePatch.textField.SetValue(val, translationGUID);
			val.useFontWithStroke = stroke;
			val2.Field("textToLocalize").SetValue((object)textObject.GetComponent<TextMeshProUGUI>());
			val2.Field("textToLocalize2").SetValue((object)textObject.GetComponent<TextMesh>());
			if (component != null)
			{
				component.UpdateText();
			}
			return val;
		}
	}
	internal static class LanguagePatch
	{
		private static readonly Dictionary<string, string> _translationLookUp = new Dictionary<string, string>
		{
			{ "name", "en" },
			{ "menu_play", "play" },
			{ "play_start", "start!" },
			{ "menu_online", "online" },
			{ "menu_settings", "settings" },
			{ "menu_exit", "exit" },
			{ "settings_sfx_vol", "sfx\nvol" },
			{ "settings_music_vol", "music\nvol" },
			{ "settings_abilities", "abilities" },
			{ "settings_screen_shake", "screen shake" },
			{ "settings_rumble", "rumble" },
			{ "settings_resolution", "resolution" },
			{ "settings_save", "save" },
			{ "general_on", "on" },
			{ "general_off", "off" },
			{ "general_high", "high" },
			{ "screen_fullscreen", "fullscreen" },
			{ "screen_windowed", "windowed" },
			{ "screen_borderless", "borderless" },
			{ "settings_screen", "screen" },
			{ "play_click", "click to join!" },
			{ "play_ready", "ready!" },
			{ "play_color", "color" },
			{ "play_team", "team" },
			{ "rebind_keys", "rebind keys" },
			{ "rebind_jump", "click jump" },
			{ "rebind_ability_left", "click ability_left" },
			{ "rebind_ability_right", "click ability_right" },
			{ "rebind_ability_top", "click ability_top" },
			{ "rebind_move_left", "click move_left" },
			{ "rebind_move_down", "click move_down" },
			{ "rebind_move_right", "click move_right" },
			{ "rebind_move_up", "click move_up" },
			{ "settings_vsync", "vsync" },
			{ "hide_nothing", "nothing" },
			{ "settings_hide", "hide" },
			{ "hide_names", "names" },
			{ "hide_names_avatars", "names and avatars" },
			{ "undefined_mouse_only", "mouse only" },
			{ "play_local_game", "local game" },
			{ "undefined_click_start", "click to start!" },
			{ "end_next_level", "next level" },
			{ "end_ability_select", "ability select" },
			{ "end_winner", "winner!!" },
			{ "end_winners", "winners!!" },
			{ "end_draw", "draw!" },
			{ "undefined_whishlist", "wishlist bopl battle!" },
			{ "play_choosing", "choosing..." },
			{ "pause_leave", "leave game?" },
			{ "menu_invite", "invite friend" },
			{ "undefined_practice", "practice" },
			{ "tutorial_hold_dow", "hold down" },
			{ "tutorial_aim", "to aim" },
			{ "tutorial_throw_greneade", "to throw grenade" },
			{ "tutorial_dash", "to dash" },
			{ "tutorial_click", "click" },
			{ "menu_credits", "credits" },
			{ "credits_back", "back" },
			{ "menu_tutorial", "tutorial" },
			{ "play_empty_lobby", "your lobby is empty" },
			{ "play_invite", "invite a friend to play online" },
			{ "play_not_abailable_demo", "not available in demo" },
			{ "play_find_players", "find players" },
			{ "play_stop_player_search", "stop search" },
			{ "item_bow", "bow" },
			{ "item_tesla_coil", "tesla coil" },
			{ "item_engine", "engine" },
			{ "item_smoke", "smoke" },
			{ "item_invisibility", "invisibility" },
			{ "item_platform", "platform" },
			{ "item_meteor", "meteor" },
			{ "item_random", "random" },
			{ "item_missile", "missile" },
			{ "item_black_hole", "black hole" },
			{ "item_rock", "rock" },
			{ "item_push", "push" },
			{ "item_dash", "dash" },
			{ "item_grenade", "grenade" },
			{ "item_roll", "roll" },
			{ "item_time_stop", "time stop" },
			{ "item_blink_gun", "blink gun" },
			{ "item_gust", "gust" },
			{ "item_mine", "mine" },
			{ "item_revival", "revival" },
			{ "item_spike", "spike" },
			{ "item_shrink_ray", "shrink ray" },
			{ "item_growth_ray", "growth ray" },
			{ "item_chain", "chain" },
			{ "item_time_lock", "time lock" },
			{ "item_throw", "throw" },
			{ "item_teleport", "teleport" },
			{ "item_grappling_hook", "grappling hook" },
			{ "item_drill", "drill" },
			{ "item_beam", "beam" }
		};

		internal static readonly List<CustomLanguage> ogLanguages = new List<CustomLanguage>();

		internal static readonly List<CustomLanguage> customLanguages = new List<CustomLanguage>();

		internal static CustomLanguage fallbackLanguage;

		internal static readonly FieldInfo textField = typeof(LocalizedText).GetField("enText", AccessTools.all);

		internal static int OGLanguagesCount { get; private set; }

		internal static void Init()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			Plugin.harmony.Patch((MethodBase)AccessTools.Method(typeof(LocalizationTable), "GetText", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LanguagePatch), "GetText_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Plugin.harmony.Patch((MethodBase)AccessTools.Method(typeof(LocalizedText), "Start", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LanguagePatch), "TextStart_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Plugin.harmony.Patch((MethodBase)AccessTools.Method(typeof(LocalizationTable), "GetFont", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LanguagePatch), "GetFont_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			OGLanguagesCount = Utils.MaxOfEnum<Language>();
			Dictionary<string, string>.KeyCollection keys = _translationLookUp.Keys;
			int num = 0;
			string[] array = new string[keys.Count];
			foreach (string item in keys)
			{
				array[num] = item;
				num++;
			}
			string[] translationKeys = array;
			Dictionary<string, string>.ValueCollection values = _translationLookUp.Values;
			List<string> list = new List<string>(values.Count);
			list.AddRange(values);
			List<string> translationValues = list;
			LocalizationTable table = Resources.FindObjectsOfTypeAll<LocalizationTable>()[0];
			MakeCustomFromBuiltIn(table.en, GameFont.English);
			MakeCustomFromBuiltIn(table.de, GameFont.English);
			MakeCustomFromBuiltIn(table.es, GameFont.English);
			MakeCustomFromBuiltIn(table.fr, GameFont.English);
			MakeCustomFromBuiltIn(table.it, GameFont.English);
			MakeCustomFromBuiltIn(table.jp, GameFont.Japanese);
			MakeCustomFromBuiltIn(table.ko, GameFont.Korean);
			MakeCustomFromBuiltIn(table.pl, GameFont.Polish);
			MakeCustomFromBuiltIn(table.ptbr, GameFont.Polish);
			MakeCustomFromBuiltIn(table.ru, GameFont.Russian);
			MakeCustomFromBuiltIn(table.se, GameFont.English);
			MakeCustomFromBuiltIn(table.tr, GameFont.Polish);
			MakeCustomFromBuiltIn(table.zhcn, GameFont.Chinese);
			MakeCustomFromBuiltIn(table.zhtw, GameFont.Chinese);
			fallbackLanguage = BoplTranslator.GetCustomLanguage(Plugin.fallbackLanguage.Value);
			foreach (FileInfo item2 in Plugin.translationsDir.EnumerateFiles())
			{
				Plugin.logger.LogInfo((object)("Reading \"" + item2.Name + "\""));
				Dictionary<string, string> dictionary = new Dictionary<string, string>();
				foreach (string item3 in File.ReadLines(item2.FullName))
				{
					string text = item3;
					int num2 = text.IndexOf('#');
					if (num2 != -1)
					{
						text = text.Remove(num2);
					}
					string[] array2 = text.Split(new char[1] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries);
					if (array2.Length >= 2)
					{
						string key = array2[0].Trim();
						string value = array2[1].Trim().Replace("\\n", "\n");
						dictionary[key] = value;
					}
				}
				if (!dictionary.TryGetValue("name", out var value2))
				{
					if (dictionary.ContainsKey("menu_language"))
					{
						Plugin.logger.LogError((object)"Use 'name' instead of 'menu_language'!");
					}
					else
					{
						Plugin.logger.LogError((object)"No 'name' entry!");
					}
					continue;
				}
				GameFont result = fallbackLanguage.Font;
				if (dictionary.TryGetValue("font", out var value3) && Enum.TryParse<GameFont>(value3, out result))
				{
					dictionary.Remove("font");
				}
				CustomLanguage customLanguage = new CustomLanguage(value2, result, copyFallback: false);
				customLanguage.EditTranslations(dictionary);
				array = translationKeys;
				foreach (string text2 in array)
				{
					if (!customLanguage.translationPairs.ContainsKey(text2))
					{
						string translation = fallbackLanguage.GetTranslation(text2);
						customLanguage.translationPairs.Add(text2, translation);
						if (!text2.StartsWith("undefined"))
						{
							Plugin.logger.LogWarning((object)("No translation for \"" + text2 + "\" in \"" + item2.Name + "\""));
						}
					}
				}
				if (!customLanguage.IsReferenced)
				{
					customLanguages.Add(customLanguage);
				}
				Plugin.logger.LogInfo((object)("Successfully read \"" + item2.Name + "\""));
			}
			void MakeCustomFromBuiltIn(string[] translations, GameFont font)
			{
				CustomLanguage customLanguage2 = new CustomLanguage(translations[0], font, copyFallback: false);
				for (int i = 0; i < translations.Length; i++)
				{
					string text3 = table.en[i];
					int num3 = translationValues.FindIndex((string e) => e == text3);
					if (num3 != -1)
					{
						customLanguage2.translationPairs.Add(translationKeys[num3], translations[i]);
					}
				}
				ogLanguages.Add(customLanguage2);
			}
		}

		internal static bool GetText_Prefix(LocalizationTable __instance, ref string __result, string enText, Language lang)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (enText == null)
			{
				return false;
			}
			__result = enText;
			CustomLanguage customLanguage = BoplTranslator.GetCustomLanguage(lang);
			if (customLanguage == null)
			{
				return false;
			}
			if (customLanguage.translationPairs.TryGetValue(enText, out var value))
			{
				__result = value;
				return false;
			}
			foreach (KeyValuePair<string, string> item in _translationLookUp)
			{
				if (!(item.Value != enText))
				{
					__result = customLanguage.translationPairs[item.Key];
					return false;
				}
			}
			return false;
		}

		internal static void TextStart_Prefix(LocalizedText __instance)
		{
			string ogText = textField.GetValue(__instance) as string;
			if (ogText == null)
			{
				return;
			}
			try
			{
				string key = _translationLookUp.First((KeyValuePair<string, string> e) => e.Value == ogText).Key;
				textField.SetValue(__instance, key);
			}
			catch (InvalidOperationException)
			{
			}
		}

		internal static void GetFont_Prefix(ref Language lang)
		{
			if (lang.IsCustomLanguage())
			{
				switch (GetCustomLanguage(lang)?.Font ?? fallbackLanguage.Font)
				{
				case GameFont.English:
					lang = (Language)0;
					break;
				case GameFont.Japanese:
					lang = (Language)5;
					break;
				case GameFont.Korean:
					lang = (Language)6;
					break;
				case GameFont.Russian:
					lang = (Language)9;
					break;
				case GameFont.Chinese:
					lang = (Language)12;
					break;
				case GameFont.Polish:
					lang = (Language)7;
					break;
				}
			}
		}

		internal static CustomLanguage GetCustomLanguage(Language lang)
		{
			//IL_0005: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected I4, but got Unknown
			return customLanguages.ElementAtOrDefault(lang - OGLanguagesCount - 1);
		}
	}
	[BepInPlugin("com.almafa64.BoplTranslator", "BoplTranslator", "2.0.1")]
	[BepInProcess("BoplBattle.exe")]
	public class Plugin : BaseUnityPlugin
	{
		internal static Harmony harmony;

		internal static DirectoryInfo translationsDir;

		internal static ConfigFile config;

		internal static ConfigEntry<string> lastCustomLanguageCode;

		internal static ConfigEntry<Language> fallbackLanguage;

		internal static ManualLogSource logger;

		private void Awake()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			translationsDir = new DirectoryInfo(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "translations"));
			translationsDir.Create();
			harmony = new Harmony("BoplTranslator");
			logger = ((BaseUnityPlugin)this).Logger;
			config = ((BaseUnityPlugin)this).Config;
			lastCustomLanguageCode = ((BaseUnityPlugin)this).Config.Bind<string>("store", "last_custom_language_code", "", "dont modify pls");
			fallbackLanguage = ((BaseUnityPlugin)this).Config.Bind<Language>("settings", "fallback language", (Language)0, new ConfigDescription("The built-in language to use when translation is not found", (AcceptableValueBase)(object)new AcceptableLanguageRange(), Array.Empty<object>()));
			SceneManager.sceneLoaded += OnSceneLoaded;
			try
			{
				LanguagePatch.Init();
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogFatal((object)$"Error at Language: {Environment.NewLine}{arg}");
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (((Scene)(ref scene)).name == "MainMenu")
			{
				((MonoBehaviour)this).StartCoroutine(TimeoutSceneLoad());
			}
		}

		private IEnumerator TimeoutSceneLoad()
		{
			if (LanguagePatch.customLanguages.Count == 0)
			{
				if ((int)Settings.Get().Language > LanguagePatch.OGLanguagesCount)
				{
					Settings.Get().Language = fallbackLanguage.Value;
					BoplTranslator.UpdateTexts();
				}
				yield break;
			}
			yield return (object)new WaitForSeconds(0.05f);
			GameObject val = GameObject.Find("LanguageMenu_leaveACTIVE");
			int index = val.transform.childCount - 1;
			GameObject val2 = Object.Instantiate<GameObject>(GameObject.Find("Resolution"));
			GameObject val3 = Object.Instantiate<GameObject>(GameObject.Find("en"), val.transform);
			Button[] componentsInChildren = val2.GetComponentsInChildren<Button>();
			val3.GetComponentInChildren<SelectionBorder>().ButtonsWithTextColors = componentsInChildren;
			Button[] array = componentsInChildren;
			foreach (Button obj in array)
			{
				((Component)obj).transform.SetParent(val3.transform);
				((Component)obj).transform.localScale = new Vector3(1f, 1f, 1f);
			}
			((Component)componentsInChildren[0]).transform.localPosition = new Vector3(370f, 35f, 0f);
			((Component)componentsInChildren[1]).transform.localPosition = new Vector3(-300f, 35f, 0f);
			Object.Destroy((Object)(object)val2);
			Object.Destroy((Object)(object)val3.GetComponent<OptionsButton>());
			LanguageSelector selector = val3.AddComponent<LanguageSelector>();
			foreach (CustomLanguage customLanguage in LanguagePatch.customLanguages)
			{
				selector.languageNames.Add(customLanguage.Name);
			}
			if (lastCustomLanguageCode.Value == "")
			{
				lastCustomLanguageCode.Value = selector.languageNames[0];
			}
			selector.langMenu = val;
			selector.Init();
			MainMenu menu = val.GetComponent<MainMenu>();
			menu.ConfiguredMenuItems.Add(val3);
			Traverse obj2 = Traverse.Create((object)menu);
			obj2.Field("Indices").GetValue<List<int>>().Add(0);
			obj2.Field("MenuItemTransforms").GetValue<List<RectTransform>>().Add(val3.GetComponent<RectTransform>());
			obj2.Field("MenuItems").GetValue<List<IMenuItem>>().Add((IMenuItem)(object)val3.GetComponent<OptionsButton>());
			List<Vector2> value = obj2.Field("originalMenuItemPositions").GetValue<List<Vector2>>();
			float num = value[0].y - value[2].y;
			value.Add(new Vector2(0f, value[index].y - num));
			((Object)val3).name = "Custom Languages";
			CallOnHover component = val3.GetComponent<CallOnHover>();
			UnityEvent onHover = component.onHover;
			((UnityEventBase)onHover).RemoveAllListeners();
			onHover.AddListener((UnityAction)delegate
			{
				menu.Select(14);
				selector.InputActive = true;
			});
			component.onExitHover.AddListener((UnityAction)delegate
			{
				selector.InputActive = false;
			});
			UnityEvent onClick = component.onClick;
			((UnityEventBase)onClick).RemoveAllListeners();
			onClick.AddListener(new UnityAction(selector.Click));
		}
	}
	public class LanguageSelector : MonoBehaviour, IMenuItem
	{
		private BindInputAxisToButton[] InputArrows;

		public TextMeshProUGUI textMesh;

		public List<string> languageNames = new List<string>();

		public GameObject langMenu;

		public bool InputActive { get; set; }

		public int OptionIndex { get; private set; }

		private void TryFindLastLanguage()
		{
			int num = languageNames.IndexOf(Plugin.lastCustomLanguageCode.Value);
			if (num != -1)
			{
				OptionIndex = num;
				langMenu.GetComponent<LanguageMenu>().SetLanguage(num + LanguagePatch.OGLanguagesCount + 1);
				Plugin.logger.LogInfo((object)("Found last used language \"" + Plugin.lastCustomLanguageCode.Value + "\""));
			}
			else
			{
				langMenu.GetComponent<LanguageMenu>().SetLanguage(0);
				OptionIndex = 0;
				Plugin.lastCustomLanguageCode.Value = languageNames[0];
				Plugin.logger.LogError((object)("Couldn't find last used language \"" + Plugin.lastCustomLanguageCode.Value + "\""));
			}
		}

		public void Init()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected I4, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Expected O, but got Unknown
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Expected O, but got Unknown
			OptionIndex = (int)Settings.Get().Language;
			if (OptionIndex <= LanguagePatch.OGLanguagesCount)
			{
				OptionIndex = 0;
			}
			else
			{
				OptionIndex -= LanguagePatch.OGLanguagesCount + 1;
				if (OptionIndex >= languageNames.Count)
				{
					Plugin.logger.LogWarning((object)$"Language number {OptionIndex} was selected, but no language with that number exists");
					TryFindLastLanguage();
				}
				else if (languageNames[OptionIndex] != Plugin.lastCustomLanguageCode.Value)
				{
					Plugin.logger.LogWarning((object)("last language wasn't \"" + languageNames[OptionIndex] + "\", it was \"" + Plugin.lastCustomLanguageCode.Value + "\""));
					TryFindLastLanguage();
				}
			}
			InputArrows = ((Component)this).GetComponentsInChildren<BindInputAxisToButton>();
			textMesh = ((Component)this).GetComponentInChildren<TextMeshProUGUI>();
			((TMP_Text)textMesh).font = LocalizedText.localizationTable.enFontAsset;
			Button component = ((Component)InputArrows[1]).GetComponent<Button>();
			((UnityEventBase)component.onClick).RemoveAllListeners();
			((UnityEvent)component.onClick).AddListener(new UnityAction(Previous));
			Button component2 = ((Component)InputArrows[0]).GetComponent<Button>();
			((UnityEventBase)component2.onClick).RemoveAllListeners();
			((UnityEvent)component2.onClick).AddListener(new UnityAction(Next));
		}

		private void Update()
		{
			((TMP_Text)textMesh).text = languageNames[OptionIndex];
			for (int i = 0; i < InputArrows.Length; i++)
			{
				((Behaviour)InputArrows[i]).enabled = InputActive;
			}
		}

		public void Next()
		{
			OptionIndex = (OptionIndex + 1) % languageNames.Count;
			Update();
		}

		public void Previous()
		{
			OptionIndex = (OptionIndex - 1 + languageNames.Count) % languageNames.Count;
			Update();
		}

		public void Click()
		{
			if (InputActive && ((Behaviour)this).isActiveAndEnabled)
			{
				langMenu.GetComponent<LanguageMenu>().SetLanguage(LanguagePatch.OGLanguagesCount + 1 + OptionIndex);
				GameObject.Find("mainMenu_leaveACTIVE").GetComponent<MainMenu>().EnableAll();
				langMenu.GetComponent<MainMenu>().DisableAll();
				AudioManager.Get().Play("return3");
				Plugin.lastCustomLanguageCode.Value = languageNames[OptionIndex];
			}
		}
	}
	internal class AcceptableLanguageRange : AcceptableValueRange<Language>
	{
		public AcceptableLanguageRange()
			: base((Language)Utils.MinOfEnum<Language>(), (Language)Utils.MaxOfEnum<Language>())
		{
		}

		public override string ToDescriptionString()
		{
			return "# Acceptable langauges: " + string.Join(", ", Enum.GetNames(typeof(Language)));
		}
	}
	public static class Utils
	{
		public static int MaxOfEnum<T>()
		{
			return Enum.GetValues(typeof(T)).Cast<int>().Max();
		}

		public static int MinOfEnum<T>()
		{
			return Enum.GetValues(typeof(T)).Cast<int>().Min();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "BoplTranslator";

		public const string PLUGIN_NAME = "BoplTranslator";

		public const string PLUGIN_VERSION = "2.0.1";
	}
}