Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Switch Language in Game v1.4.0
SwitchLanguageInGame.dll
Decompiled 7 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; 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 GlobalEnums; using HarmonyLib; using HutongGames.PlayMaker; using HutongGames.PlayMaker.Actions; using Microsoft.CodeAnalysis; using MonoMod.Utils; using Silksong.SwitchLanguageInGame.Config; using TMProOld; using TeamCherry.Localization; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SwitchLanguageInGame")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.4.0.0")] [assembly: AssemblyInformationalVersion("1.4.0+476a8610753a6b113cd827600bb01b0ce3a11222")] [assembly: AssemblyProduct("SwitchLanguageInGame")] [assembly: AssemblyTitle("Switch_Language_in_Game")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/DemoJameson/Silksong.SwitchLanguageInGame")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.4.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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; } } } internal sealed class ConfigurationManagerAttributes { public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput); public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public CustomHotkeyDrawerFunc CustomHotkeyDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace Silksong.SwitchLanguageInGame { [HarmonyPatch] public class DebugComponent : MonoBehaviour { private void Start() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(Language), "Get", new Type[2] { typeof(string), typeof(string) }, (Type[])null); HarmonyMethod val = new HarmonyMethod(typeof(DebugComponent), "LanguageGet", (Type[])null); Harmony? harmonyInstance = Plugin.HarmonyInstance; if (harmonyInstance != null) { harmonyInstance.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } methodInfo = AccessTools.PropertySetter(typeof(TMP_Text), "text"); val = new HarmonyMethod(typeof(DebugComponent), "TMP_TextSetText", (Type[])null); Harmony? harmonyInstance2 = Plugin.HarmonyInstance; if (harmonyInstance2 != null) { harmonyInstance2.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } methodInfo = AccessTools.Method(typeof(LocalisedString), "ToString", new Type[1] { typeof(bool) }, (Type[])null); val = new HarmonyMethod(typeof(DebugComponent), "LocalisedStringToString", (Type[])null); } private static void LanguageGet(string key, string sheetTitle, string __result) { Plugin.Log.LogWarning((object)("Language.Get(" + key + ", " + sheetTitle + ") = " + __result)); Plugin.Log.LogInfo((object)new StackTrace()); } private static void TMP_TextSetText(string value) { Plugin.Log.LogWarning((object)("TMP_Text.set_text(" + value + ")")); Plugin.Log.LogInfo((object)new StackTrace()); } private static void LocalisedStringToString(bool allowBlankText, string __result) { Plugin.Log.LogWarning((object)$"LocalisedString.ToString({allowBlankText}) = {__result}"); Plugin.Log.LogInfo((object)new StackTrace()); } } [HarmonyPatch] public class DialogueBoxComponent : MonoBehaviour { [CompilerGenerated] private sealed class <DialogueBoxCloseAndEnd>d__11 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator __result; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DialogueBoxCloseAndEnd>d__11(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (__result.MoveNext()) { <>2__current = __result.Current; <>1__state = 1; return true; } savedText = null; savedOnDialogueEnd = null; savedOnDialogueCancelled = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static LocalisedString? savedText; private static bool savedOverrideContinue; private static DisplayOptions savedDisplayOptions; private static Action? savedOnDialogueEnd; private static Action? savedOnDialogueCancelled; private static ManualLogSource Log => Plugin.Log; private void Awake() { Plugin.OnLanguageSwitched += delegate { UpdateText(); }; } private static void UpdateText() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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) UpdateAreaTitle(); DialogueBox instance = DialogueBox._instance; if (Object.op_Implicit((Object)(object)instance) && instance.isDialogueRunning && savedText.HasValue) { LocalisedString value = savedText.Value; DialogueBox.StartConversation(((LocalisedString)(ref value)).ToString(false), instance.instigator, savedOverrideContinue, savedDisplayOptions, savedOnDialogueEnd, savedOnDialogueCancelled); } } private static void UpdateAreaTitle() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) AreaTitle instance = ManagerSingleton<AreaTitle>.Instance; if (!Object.op_Implicit((Object)(object)instance)) { return; } TextMeshPro[] componentsInChildren = ((Component)instance).gameObject.GetComponentsInChildren<TextMeshPro>(); if (componentsInChildren == null) { return; } TextMeshPro[] array = componentsInChildren; foreach (TextMeshPro val in array) { LocalisedString? val2 = LanguageUtils.guessLocalisedString(((TMP_Text)val).text, (LanguageCode?)null, "Titles"); if (val2.HasValue) { LocalisedString value = val2.Value; ((TMP_Text)val).text = ((object)(LocalisedString)(ref value)).ToString(); } } } [HarmonyPatch(typeof(DialogueBox), "StartConversation", new Type[] { typeof(string), typeof(NPCControlBase), typeof(bool), typeof(DisplayOptions), typeof(Action), typeof(Action) })] [HarmonyPrefix] private static void DialogueBoxStartConversation(string text, NPCControlBase instigator, bool overrideContinue, DisplayOptions displayOptions, Action onDialogueEnd, Action onDialogueCancelled) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)DialogueBox._instance)) { LocalisedString? val = LanguageUtils.guessLocalisedString(text, Language._currentLanguage); if (val.HasValue) { savedText = val.Value; savedOverrideContinue = overrideContinue; savedDisplayOptions = displayOptions; savedOnDialogueEnd = onDialogueEnd; savedOnDialogueCancelled = onDialogueCancelled; } } } [IteratorStateMachine(typeof(<DialogueBoxCloseAndEnd>d__11))] [HarmonyPatch(typeof(DialogueBox), "CloseAndEnd")] [HarmonyPostfix] private static IEnumerator DialogueBoxCloseAndEnd(IEnumerator __result) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DialogueBoxCloseAndEnd>d__11(0) { __result = __result }; } } public static class LanguageUtils { private static readonly Dictionary<LanguageCode, Dictionary<string, Dictionary<string, string>>> reversedEntrySheets = new Dictionary<LanguageCode, Dictionary<string, Dictionary<string, string>>>(); public static LocalisedString? guessLocalisedString(string? text, LanguageCode? specifiedLanguage = null, string? specifiedSheet = null) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(text)) { return null; } foreach (var (val2, dictionary2) in reversedEntrySheets) { if (specifiedLanguage.HasValue && (LanguageCode?)val2 != specifiedLanguage) { continue; } foreach (var (text3, dictionary4) in dictionary2) { if ((specifiedSheet == null || !(text3 != specifiedSheet)) && dictionary4.TryGetValue(text, out var value)) { return new LocalisedString(text3, value); } } } return null; } public static LocalisedString? guessLocalisedString(string? text, params string[] sheets) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) foreach (string text2 in sheets) { string specifiedSheet = text2; LocalisedString? val = guessLocalisedString(text, (LanguageCode?)null, specifiedSheet); if (val.HasValue) { return val.GetValueOrDefault(); } } return null; } public static void AddReversedEntrySheets() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (reversedEntrySheets.ContainsKey(Language._currentLanguage)) { return; } Dictionary<string, Dictionary<string, string>> dictionary = new Dictionary<string, Dictionary<string, string>>(); reversedEntrySheets.Add(Language._currentLanguage, dictionary); foreach (KeyValuePair<string, Dictionary<string, string>> currentEntrySheet in Language._currentEntrySheets) { Dictionary<string, string> value = currentEntrySheet.Value; Dictionary<string, string> dictionary2 = new Dictionary<string, string>(); foreach (KeyValuePair<string, string> item in value) { dictionary2[item.Value] = item.Key; } dictionary.Add(currentEntrySheet.Key, dictionary2); } } public static void Switch(LanguageCode language) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) UIManager._instance.uiAudioPlayer.PlaySubmit(); if (language != Language.CurrentLanguage()) { Language.SwitchLanguage(language); } } public static string ToWord(this LanguageCode languageCode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 if ((int)languageCode <= 105) { if ((int)languageCode <= 44) { if ((int)languageCode == 37) { return "German"; } if ((int)languageCode == 44) { return "English"; } } else { if ((int)languageCode == 57) { return "Spanish"; } if ((int)languageCode == 82) { return "French"; } if ((int)languageCode == 105) { return "Italian"; } } } else if ((int)languageCode <= 117) { if ((int)languageCode == 109) { return "Japanese"; } if ((int)languageCode == 117) { return "Korean"; } } else { if ((int)languageCode == 147) { return "Portuguese"; } if ((int)languageCode == 154) { return "Russian"; } if ((int)languageCode == 199) { return "Chinese"; } } return ((object)(LanguageCode)(ref languageCode)).ToString(); } public static LanguageCode ToLanguageCode(this string word) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) foreach (LanguageCode value in Enum.GetValues(typeof(LanguageCode))) { if (string.Equals(ToWord(value), word.Trim(), StringComparison.OrdinalIgnoreCase)) { return value; } } return (LanguageCode)44; } } [HarmonyPatch] public class PlayMakerFSMComponent : MonoBehaviour { private static List<WeakReference<PlayMakerFSM>> playMakerFSMList = new List<WeakReference<PlayMakerFSM>>(); private static WeakReference<PlayMakerFSM>? itemListControl; private static ManualLogSource Log => Plugin.Log; private void Awake() { Plugin.OnLanguageSwitched += delegate { UpdateText(); }; DynData<GameManager> obj = new DynData<GameManager>(GameManager._instance); playMakerFSMList = obj.Get<List<WeakReference<PlayMakerFSM>>>("playMakerFSMList") ?? new List<WeakReference<PlayMakerFSM>>(); itemListControl = obj.Get<WeakReference<PlayMakerFSM>>("itemListControl"); } private void OnDestroy() { DynData<GameManager> obj = new DynData<GameManager>(GameManager._instance); obj.Set<List<WeakReference<PlayMakerFSM>>>("playMakerFSMList", playMakerFSMList); obj.Set<WeakReference<PlayMakerFSM>>("itemListControl", itemListControl); } [HarmonyPatch(typeof(PlayMakerFSM), "Awake")] [HarmonyPostfix] private static void PlayMakerFSMAwake(PlayMakerFSM __instance) { if (((Object)__instance).GetName() == "Item List" && __instance.FsmName == "Item List Control") { itemListControl = new WeakReference<PlayMakerFSM>(__instance); } FsmState[] fsmStates = __instance.FsmStates; for (int i = 0; i < fsmStates.Length; i++) { if (fsmStates[i].Actions.OfType<SetTextMeshProText>().Any()) { playMakerFSMList.Add(new WeakReference<PlayMakerFSM>(__instance)); } } } private static void UpdateText() { if (Object.op_Implicit((Object)(object)GameManager._instance) && GameManager._instance.isPaused) { return; } foreach (WeakReference<PlayMakerFSM> item in playMakerFSMList.ToList()) { if (item.TryGetTarget(out var target) && Object.op_Implicit((Object)(object)target)) { if (!Object.op_Implicit((Object)(object)((Component)target).gameObject) || !((Component)target).gameObject.activeInHierarchy) { continue; } bool flag = (Object)(object)target == (Object)(object)itemListControl.GetTarget(); FsmState[] fsmStates = target.FsmStates; foreach (FsmState val in fsmStates) { if (flag) { bool flag2; switch (val.name) { case "Purchase": case "Craft": case "Repair": flag2 = true; break; default: flag2 = false; break; } if (flag2) { Enum value = target.FsmVariables.FindFsmEnum("Purchase Type").value; if (value != null && !string.Equals(val.name, value.ToString())) { continue; } } } FsmStateAction[] actions = val.actions; for (int j = 0; j < actions.Length; j++) { FsmStateAction val2 = actions[j]; SetTextMeshProText val3 = (SetTextMeshProText)(object)((val2 is SetTextMeshProText) ? val2 : null); if (val3 != null) { if (!Utility.IsNullOrWhiteSpace(val3.textString.value) && val3.textString.value != "!!/!!") { val2.OnEnter(); } } else if ((val2 is GetLanguageStringProcessed || val2 is GetLanguageString) ? true : false) { val2.OnEnter(); } else if (j < actions.Length - 1 && actions[j + 1] is SetTextMeshProText && val2 is CallMethodProper) { val2.OnEnter(); } } } } else { playMakerFSMList.Remove(item); } } } } public static class WeakReferenceExtensions { public static PlayMakerFSM? GetTarget(this WeakReference<PlayMakerFSM>? weakReference) { if (weakReference != null && weakReference.TryGetTarget(out PlayMakerFSM target) && Object.op_Implicit((Object)(object)target)) { return target; } return null; } public static void Invoke(this WeakReference<PlayMakerFSM>? weakReference, Action<PlayMakerFSM> action) { PlayMakerFSM target = weakReference.GetTarget(); if (Object.op_Implicit((Object)(object)target)) { action(target); } } public static T? Invoke<T>(this WeakReference<PlayMakerFSM>? weakReference, Func<PlayMakerFSM, T> func) { PlayMakerFSM target = weakReference.GetTarget(); if (!Object.op_Implicit((Object)(object)target)) { return default(T); } return func(target); } } [HarmonyPatch] [BepInPlugin("com.demojameson.switchlanguageingame", "Switch Language in Game", "1.4.0")] public class Plugin : BaseUnityPlugin { public static ManualLogSource Log; public const string Id = "com.demojameson.switchlanguageingame"; public static Harmony? HarmonyInstance { get; private set; } public static string Name => "Switch Language in Game"; public static string Version => "1.4.0"; public static event Action<LanguageCode>? OnLanguageSwitched; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; try { HarmonyInstance = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); } ((Component)this).gameObject.AddComponent<ShortcutComponent>(); ((Component)this).gameObject.AddComponent<PlayMakerFSMComponent>(); ((Component)this).gameObject.AddComponent<DialogueBoxComponent>(); ((Component)this).gameObject.AddComponent<PromptMarkerComponent>(); } private void Start() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown PluginConfig.Bind((BaseUnityPlugin)(object)this); MethodInfo methodInfo = AccessTools.Method(typeof(Language), "SwitchLanguage", new Type[1] { typeof(LanguageCode) }, (Type[])null); HarmonyMethod val = new HarmonyMethod(typeof(Plugin), "LanguageDoSwitchPostfix", (Type[])null); Harmony? harmonyInstance = HarmonyInstance; if (harmonyInstance != null) { harmonyInstance.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } LanguageDoSwitchPostfix(); } private void OnDestroy() { Harmony? harmonyInstance = HarmonyInstance; if (harmonyInstance != null) { harmonyInstance.UnpatchSelf(); } } [HarmonyPatch(typeof(GameMenuOptions), "ConfigureNavigation")] [HarmonyPostfix] private static void GameMenuOptionsConfigureNavigation(GameMenuOptions __instance) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 if (PluginConfig.Enabled.Value && (int)GameManager.instance.GameState != 1) { MenuSelectable languageOption = __instance.languageOption; ((Selectable)languageOption).interactable = true; ((Component)((Component)languageOption).transform.parent).gameObject.SetActive(true); __instance.languageOptionDescription.SetActive(false); __instance.gameOptionsMenuScreen.defaultHighlight = (Selectable)(object)languageOption; MenuLanguageSetting val = (MenuLanguageSetting)(object)((languageOption is MenuLanguageSetting) ? languageOption : null); if (val != null) { val.UpdateAlpha(); } } } private static void LanguageDoSwitchPostfix() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) PluginConfig.SelectedLanguage.Value = Language._currentLanguage.ToWord(); LanguageUtils.AddReversedEntrySheets(); UpdateSetting(); UpdateSlotButton(); UpdateComponents(); UpdatePanel(); UpdateQuestBoard(); UpdateQuestShop(); UpdateMsgBox(); Plugin.OnLanguageSwitched?.Invoke(Language._currentLanguage); } private static void UpdateSetting() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) GameManager instance = GameManager._instance; if (Object.op_Implicit((Object)(object)instance)) { instance.gameSettings.gameLanguage = (SupportedLanguages)Language._currentLanguage; instance.RefreshLocalization(); ((MenuOptionHorizontal)UIManager.instance.languageSetting).UpdateText(); } } private static void UpdateSlotButton() { Plugin.UpdateComponents<SaveSlotButton>((Action<SaveSlotButton>)delegate(SaveSlotButton button) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)button.locationText)) { string text = button.locationText.text; if (!Utility.IsNullOrWhiteSpace(text)) { text = text.Replace(Environment.NewLine, "<br>"); LocalisedString? val = LanguageUtils.guessLocalisedString(text, "Map Zones"); if (val.HasValue) { LocalisedString valueOrDefault = val.GetValueOrDefault(); button.locationText.text = ((object)(LocalisedString)(ref valueOrDefault)).ToString().Replace("<br>", Environment.NewLine); } } } }); } private static void UpdateComponents() { Plugin.UpdateComponents<SetTextMeshProGameText>((Action<SetTextMeshProGameText>)delegate(SetTextMeshProGameText component) { component.UpdateText(); }); Plugin.UpdateComponents<ActivatePerLanguage>((Action<ActivatePerLanguage>)delegate(ActivatePerLanguage component) { component.UpdateLanguage(); }); Plugin.UpdateComponents<ChangeByLanguageBase>((Action<ChangeByLanguageBase>)delegate(ChangeByLanguageBase component) { component.DoUpdate(); }); Plugin.UpdateComponents<InventoryItemManager>((Action<InventoryItemManager>)delegate(InventoryItemManager component) { if (Object.op_Implicit((Object)(object)component.CurrentSelected)) { component.SetDisplay(component.CurrentSelected); } }); Plugin.UpdateComponents<ChangeFontByLanguage>((Action<ChangeFontByLanguage>)delegate(ChangeFontByLanguage component) { if (Object.op_Implicit((Object)(object)component.defaultMaterial)) { component.SetFont(); } }); } private static void UpdatePanel() { GameManager instance = GameManager._instance; if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance.gameMap)) { InventoryMapManager mapManager = instance.gameMap.mapManager; ((TMP_Text)mapManager.paneList.currentPaneText).text = mapManager.pane.DisplayName; mapManager.UpdateKeyPromptState(false); } } private static void UpdateQuestBoard() { Plugin.UpdateComponents<QuestItemBoard>((Action<QuestItemBoard>)delegate(QuestItemBoard component) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)((InventoryItemListManager<InventoryItemQuest, BasicQuestBase>)(object)component).itemList)) { return; } try { List<InventoryItemQuest> selectables = ((InventoryItemListManager<InventoryItemQuest, BasicQuestBase>)(object)component).GetSelectables((Func<InventoryItemQuest, bool>)null); List<BasicQuestBase> items = ((InventoryItemListManager<InventoryItemQuest, BasicQuestBase>)(object)component).GetItems(); if (selectables != null && items != null) { for (int i = 0; i < selectables.Count; i++) { InventoryItemQuest val = selectables[i]; BasicQuestBase val2 = items[i]; if (Object.op_Implicit((Object)(object)val2.QuestType)) { if (Object.op_Implicit((Object)(object)val.icon)) { val.icon.sprite = val2.QuestType.Icon; } if (Object.op_Implicit((Object)(object)val.typeText)) { ((TMP_Text)val.typeText).text = val2.QuestType.DisplayName; } } if (Object.op_Implicit((Object)(object)val.nameText)) { ((TMP_Text)val.nameText).text = LocalisedString.op_Implicit(val2.DisplayName); } } } } catch { } }); } private static void UpdateQuestShop() { SimpleShopMenu spawnedMenu = SimpleShopMenuOwner._spawnedMenu; if (!Object.op_Implicit((Object)(object)spawnedMenu)) { return; } SimpleShopMenuOwner owner = spawnedMenu.owner; if (Object.op_Implicit((Object)(object)owner)) { if (Object.op_Implicit((Object)(object)spawnedMenu.titleText)) { spawnedMenu.titleText.text = owner.ShopTitle; } if (Object.op_Implicit((Object)(object)spawnedMenu.purchaseText)) { spawnedMenu.purchaseText.text = owner.PurchaseText; } } for (int i = 0; i < spawnedMenu.activeItemCount; i++) { SimpleShopItemDisplay val = spawnedMenu.spawnedItemDisplays[i]; ISimpleShopItem val2 = spawnedMenu.shopItems[i]; if (Object.op_Implicit((Object)(object)val.titleText)) { val.titleText.text = val2.GetDisplayName(); } } } private static void UpdateMsgBox() { Plugin.UpdateComponents<NeedolinMsgBox>((Action<NeedolinMsgBox>)delegate(NeedolinMsgBox component) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)component.primaryText)) { LocalisedString? val3 = LanguageUtils.guessLocalisedString(component.primaryText.text, "Song", "Lore"); if (val3.HasValue) { LocalisedString valueOrDefault2 = val3.GetValueOrDefault(); component.primaryText.text = LocalisedString.op_Implicit(valueOrDefault2); } } if (Object.op_Implicit((Object)(object)component.secondaryText)) { LocalisedString? val3 = LanguageUtils.guessLocalisedString(component.secondaryText.text, "Song", "Lore"); if (val3.HasValue) { LocalisedString valueOrDefault3 = val3.GetValueOrDefault(); component.secondaryText.text = LocalisedString.op_Implicit(valueOrDefault3); } } }); Plugin.UpdateComponents<MemoryMsgBox>((Action<MemoryMsgBox>)delegate(MemoryMsgBox component) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (component.textDisplays != null) { TMP_Text[] textDisplays = component.textDisplays; foreach (TMP_Text val in textDisplays) { if (Object.op_Implicit((Object)(object)val)) { LocalisedString? val2 = LanguageUtils.guessLocalisedString(val.text, (LanguageCode?)null, "Lore"); if (val2.HasValue) { LocalisedString valueOrDefault = val2.GetValueOrDefault(); val.text = LocalisedString.op_Implicit(valueOrDefault); } } } } }); } public static void UpdateComponents<T>(Action<T> action) where T : MonoBehaviour { T[] array = Resources.FindObjectsOfTypeAll<T>(); if (array != null) { T[] array2 = array; foreach (T obj in array2) { action(obj); } } } } [HarmonyPatch] public class PromptMarkerComponent : MonoBehaviour { private static readonly ConditionalWeakTable<PromptMarker, string> labelNameTable = new ConditionalWeakTable<PromptMarker, string>(); private static ManualLogSource Log => Plugin.Log; private void Awake() { Plugin.OnLanguageSwitched += delegate { UpdateText(); }; } [HarmonyPatch(typeof(PromptMarker), "SetLabel")] [HarmonyPostfix] private static void PromptMarkerSetLabel(PromptMarker __instance, string labelName) { labelNameTable.AddOrUpdate(__instance, labelName); } private static void UpdateText() { Plugin.UpdateComponents<PromptMarker>((Action<PromptMarker>)delegate(PromptMarker component) { if (labelNameTable.TryGetValue(component, out string value)) { component.SetLabel(value); } }); } } [HarmonyPatch] public class ShortcutComponent : MonoBehaviour { private List<LanguageCode> availableLanguages = new List<LanguageCode>(); private void Start() { availableLanguages = ((IEnumerable<string>)Language.GetLanguages()).Select((Func<string, LanguageCode>)LocalizationSettings.GetLanguageEnum).ToList(); } private void Update() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) if (PluginConfig.PrevLanguageKey.IsDown()) { int index = (availableLanguages.IndexOf(Language._currentLanguage) - 1 + availableLanguages.Count) % availableLanguages.Count; LanguageUtils.Switch(availableLanguages[index]); return; } if (PluginConfig.NextLanguageKey.IsDown()) { int index2 = (availableLanguages.IndexOf(Language._currentLanguage) + 1) % availableLanguages.Count; LanguageUtils.Switch(availableLanguages[index2]); return; } foreach (var (language, configEntry) in PluginConfig.LanguagesKey) { if (configEntry.IsDown()) { LanguageUtils.Switch(language); break; } } } } } namespace Silksong.SwitchLanguageInGame.Config { public class AcceptableValueEnum<T> : AcceptableValueBase where T : Enum { public virtual T[] AcceptableValues { get; } public AcceptableValueEnum(params T[]? acceptableValues) : base(typeof(T)) { if (acceptableValues == null || acceptableValues.Length == 0) { acceptableValues = Enum.GetValues(typeof(T)).Cast<T>().ToArray(); } AcceptableValues = acceptableValues; } public override object Clamp(object value) { if (((AcceptableValueBase)this).IsValid(value)) { return value; } return AcceptableValues[0]; } public override bool IsValid(object value) { if (value is T) { T v = (T)value; return AcceptableValues.Any((T x) => x.Equals(v)); } return false; } public override string ToDescriptionString() { return "# Acceptable values: " + string.Join(", ", AcceptableValues.Select((T x) => x.ToString()).ToArray()); } } public static class ConfigExtensions { public static bool IsDown(this ConfigEntry<KeyboardShortcut> configEntry) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = configEntry.Value; if (!((KeyboardShortcut)(ref value)).Modifiers.Any()) { IInputSystem current = UnityInput.Current; value = configEntry.Value; return current.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey); } value = configEntry.Value; return ((KeyboardShortcut)(ref value)).IsDown(); } public static ConfigEntry<T> BindEx<T>(this ConfigFile config, string section, string key, string description, T defaultValue, int? order = null, AcceptableValueBase? acceptableValue = null) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValue, new object[1] { new ConfigurationManagerAttributes { Order = order } })); } } public static class PluginConfig { public static ConfigEntry<bool> Enabled = null; public static ConfigEntry<KeyboardShortcut> PrevLanguageKey = null; public static ConfigEntry<KeyboardShortcut> NextLanguageKey = null; public static readonly Dictionary<LanguageCode, ConfigEntry<KeyboardShortcut>> LanguagesKey = new Dictionary<LanguageCode, ConfigEntry<KeyboardShortcut>>(); public static ConfigEntry<string> SelectedLanguage = null; public static void Bind(BaseUnityPlugin plugin) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) ConfigFile config = plugin.Config; int num = 0; Enabled = config.BindEx("General", "Switch Language in Game", "Support language switching in the game", defaultValue: true, num -= 1); string[] array = (from code in ((IEnumerable<string>)Language.GetLanguages()).Select((Func<string, LanguageCode>)LocalizationSettings.GetLanguageEnum) select code.ToWord()).ToArray(); SelectedLanguage = config.BindEx("General", "Selected Language", "Switch languages in the available languages", Language._currentLanguage.ToWord(), num -= 1, (AcceptableValueBase?)(object)new AcceptableValueList<string>(array)); SelectedLanguage.Value = Language._currentLanguage.ToWord(); SelectedLanguage.SettingChanged += OnSelectedLanguageSettingChanged; PrevLanguageKey = config.BindEx<KeyboardShortcut>("Shortcut Key", "Switch to Previous Language", "Key for switching to previous language", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), num -= 1); NextLanguageKey = config.BindEx<KeyboardShortcut>("Shortcut Key", "Switch to Next Language", "Key for switching to next language", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), num -= 1); foreach (LanguageCode item in ((IEnumerable<string>)Language.GetLanguages()).Select((Func<string, LanguageCode>)LocalizationSettings.GetLanguageEnum)) { LanguagesKey.Add(item, config.BindEx<KeyboardShortcut>("Shortcut Key", "Switch to " + item.ToWord(), "Key for switching to " + item.ToWord(), new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), num -= 1)); } } private static void OnSelectedLanguageSettingChanged(object sender, EventArgs eventArgs) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) LanguageUtils.Switch(SelectedLanguage.Value.ToLanguageCode()); } } }