Due to update 2.4.3, some mods may no longer function. FixedConfig may be necessary.
Decompiled source of BoplTranslator v2.0.1
BoplTranslator.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using 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"; } }