Decompiled source of Switch Language in Game v1.4.0

SwitchLanguageInGame.dll

Decompiled 3 weeks ago
using 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());
		}
	}
}