Decompiled source of MuckKorean v0.0.7

plugins/MuckKorean/MuckKorean.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.TextCore.LowLevel;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("MuckKorean")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+cb2e24b718fb47f0f1bd35c5976a293a70acfdaa")]
[assembly: AssemblyProduct("MuckKorean")]
[assembly: AssemblyTitle("MuckKorean")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 MuckKorean
{
	public static class FontManager
	{
		private static readonly ManualLogSource Log = Logger.CreateLogSource("MuckKorean.Font");

		private static bool _initialized;

		public static TMP_FontAsset KoreanFont { get; private set; }

		public static Font SourceFont { get; private set; }

		public static string FontFilePath { get; private set; }

		public static void PreInitialize(string pluginPath)
		{
			FontFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "malgun.ttf");
			if (!File.Exists(FontFilePath))
			{
				Log.LogWarning((object)("malgun.ttf를 찾을 수 없습니다: " + FontFilePath));
				FontFilePath = null;
				return;
			}
			SourceFont = Font.CreateDynamicFontFromOSFont("Malgun Gothic", 44);
			if ((Object)(object)SourceFont == (Object)null)
			{
				Log.LogWarning((object)"Font.CreateDynamicFontFromOSFont 실패");
				return;
			}
			Object.DontDestroyOnLoad((Object)(object)SourceFont);
			Font.textureRebuilt += OnFontTextureRebuilt;
			Log.LogInfo((object)("맑은 고딕 폰트 준비 완료: " + FontFilePath));
		}

		private static void OnFontTextureRebuilt(Font rebuiltFont)
		{
			if ((Object)(object)rebuiltFont != (Object)(object)SourceFont)
			{
				return;
			}
			TextMesh[] array = Object.FindObjectsOfType<TextMesh>();
			foreach (TextMesh val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.font != (Object)(object)SourceFont))
				{
					MeshRenderer component = ((Component)val).GetComponent<MeshRenderer>();
					if ((Object)(object)component != (Object)null && (Object)(object)((Renderer)component).material != (Object)null)
					{
						((Renderer)component).material.mainTexture = SourceFont.material.mainTexture;
					}
				}
			}
		}

		public static void CreateFontAsset()
		{
			if ((Object)(object)SourceFont == (Object)null || FontFilePath == null)
			{
				return;
			}
			KoreanFont = TMP_FontAsset.CreateFontAsset(SourceFont);
			if ((Object)(object)KoreanFont == (Object)null)
			{
				Log.LogWarning((object)"TMP_FontAsset 생성 실패 (패치 적용 후에도)");
				return;
			}
			((Object)KoreanFont).name = "KoreanFont-Dynamic";
			Object.DontDestroyOnLoad((Object)(object)KoreanFont);
			if (KoreanFont.atlasTextures != null)
			{
				Texture2D[] atlasTextures = KoreanFont.atlasTextures;
				foreach (Texture2D val in atlasTextures)
				{
					if ((Object)(object)val != (Object)null)
					{
						Object.DontDestroyOnLoad((Object)(object)val);
					}
				}
			}
			if ((Object)(object)((TMP_Asset)KoreanFont).material != (Object)null)
			{
				Object.DontDestroyOnLoad((Object)(object)((TMP_Asset)KoreanFont).material);
			}
			PrePopulateAtlas();
			_initialized = true;
			Log.LogInfo((object)"한글 TMP 폰트 에셋 생성 완료!");
		}

		private static void PrePopulateAtlas()
		{
			string allKoreanCharacters = TranslationManager.GetAllKoreanCharacters();
			if (string.IsNullOrEmpty(allKoreanCharacters))
			{
				return;
			}
			string text = default(string);
			bool flag = KoreanFont.TryAddCharacters(allKoreanCharacters, ref text, false);
			Log.LogInfo((object)$"아틀라스 사전 등록: {allKoreanCharacters.Length}자 요청, 성공={flag}");
			if (!string.IsNullOrEmpty(text))
			{
				Log.LogWarning((object)$"아틀라스 등록 실패 문자 {text.Length}자: {text.Substring(0, Math.Min(20, text.Length))}...");
			}
			if (KoreanFont.atlasTextures == null)
			{
				return;
			}
			Texture2D[] atlasTextures = KoreanFont.atlasTextures;
			foreach (Texture2D val in atlasTextures)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.DontDestroyOnLoad((Object)(object)val);
				}
			}
		}

		public static void ApplyFont(TextMesh textMesh, string translatedText)
		{
			if (!((Object)(object)SourceFont == (Object)null) && !((Object)(object)textMesh == (Object)null) && !string.IsNullOrEmpty(translatedText))
			{
				SourceFont.RequestCharactersInTexture(translatedText);
				textMesh.font = SourceFont;
				MeshRenderer component = ((Component)textMesh).GetComponent<MeshRenderer>();
				if ((Object)(object)component != (Object)null && (Object)(object)((Renderer)component).material != (Object)null && (Object)(object)SourceFont.material != (Object)null)
				{
					((Renderer)component).material.mainTexture = SourceFont.material.mainTexture;
				}
			}
		}

		public static void ApplyFont(Text uiText, string translatedText)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)SourceFont == (Object)null) && !((Object)(object)uiText == (Object)null) && !string.IsNullOrEmpty(translatedText))
			{
				SourceFont.RequestCharactersInTexture(translatedText, uiText.fontSize, uiText.fontStyle);
				uiText.font = SourceFont;
			}
		}

		public static void ApplyFont(TMP_Text textComponent)
		{
			if (!_initialized || (Object)(object)KoreanFont == (Object)null || (Object)(object)textComponent == (Object)null)
			{
				return;
			}
			if ((Object)(object)textComponent.font != (Object)null && (Object)(object)textComponent.font != (Object)(object)KoreanFont)
			{
				if ((Object)(object)((TMP_Asset)textComponent.font).material != (Object)null && (Object)(object)((TMP_Asset)KoreanFont).material != (Object)null && (Object)(object)((TMP_Asset)textComponent.font).material.shader != (Object)(object)((TMP_Asset)KoreanFont).material.shader)
				{
					((TMP_Asset)KoreanFont).material.shader = ((TMP_Asset)textComponent.font).material.shader;
				}
				List<TMP_FontAsset> fallbackFontAssetTable = textComponent.font.fallbackFontAssetTable;
				if (fallbackFontAssetTable == null)
				{
					textComponent.font.fallbackFontAssetTable = new List<TMP_FontAsset> { KoreanFont };
				}
				else if (!fallbackFontAssetTable.Contains(KoreanFont))
				{
					fallbackFontAssetTable.Add(KoreanFont);
				}
			}
			else if ((Object)(object)textComponent.font == (Object)null)
			{
				textComponent.font = KoreanFont;
			}
		}
	}
	[BepInPlugin("com.muck.korean", "Muck Korean", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.muck.korean";

		public const string PluginName = "Muck Korean";

		public const string PluginVersion = "1.0.0";

		public static Plugin Instance { get; private set; }

		public static string PluginPath { get; private set; }

		private void Awake()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			PluginPath = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Muck Korean v1.0.0 로딩 중...");
			TranslationManager.Load(PluginPath);
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"번역 항목 {TranslationManager.Count}개 로드 완료");
			FontManager.PreInitialize(PluginPath);
			new Harmony("com.muck.korean").PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Harmony 패치 적용 완료");
			FontManager.CreateFontAsset();
			SceneManager.sceneLoaded += OnSceneLoaded;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Muck Korean 로드 완료!");
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)("씬 로드됨: " + ((Scene)(ref scene)).name + " - 텍스트 번역 적용 중..."));
			((MonoBehaviour)this).StartCoroutine(TranslateAllTextDelayed());
		}

		private IEnumerator TranslateAllTextDelayed()
		{
			yield return null;
			yield return null;
			TranslateAllActiveText();
			yield return (object)new WaitForSeconds(0.5f);
			TranslateAllActiveText();
		}

		private void TranslateAllActiveText()
		{
			int num = 0;
			TMP_Text[] array = Object.FindObjectsOfType<TMP_Text>();
			foreach (TMP_Text val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				FontManager.ApplyFont(val);
				if (!string.IsNullOrEmpty(val.text))
				{
					string text = TranslationManager.Translate(val.text);
					if (text != val.text)
					{
						val.text = text;
						num++;
					}
				}
			}
			Text[] array2 = Object.FindObjectsOfType<Text>();
			foreach (Text val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null) && !string.IsNullOrEmpty(val2.text))
				{
					string text2 = TranslationManager.Translate(val2.text);
					if (text2 != val2.text)
					{
						val2.text = text2;
						num++;
					}
				}
			}
			TextMesh[] array3 = Object.FindObjectsOfType<TextMesh>();
			foreach (TextMesh val3 in array3)
			{
				if (!((Object)(object)val3 == (Object)null) && !string.IsNullOrEmpty(val3.text))
				{
					string text3 = TranslationManager.Translate(val3.text);
					if (text3 != val3.text)
					{
						FontManager.ApplyFont(val3, text3);
						val3.text = text3;
						num++;
					}
				}
			}
			if (num > 0)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"씬 스캔: {num}개 텍스트 번역 적용");
			}
		}
	}
	public static class TranslationManager
	{
		private static readonly ManualLogSource Log = Logger.CreateLogSource("MuckKorean.Translation");

		private static Dictionary<string, string> _translations = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

		private static List<KeyValuePair<Regex, string>> _regexTranslations = new List<KeyValuePair<Regex, string>>();

		private static HashSet<string> _missedKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static string _pluginPath;

		private static readonly Regex RichTextTagRegex = new Regex("<[^>]+>", RegexOptions.Compiled);

		private static readonly Regex NxItemRegex = new Regex("^(\\d+)x (.+)$", RegexOptions.Compiled);

		private static readonly Regex UnlockedRegex = new Regex("^Unlocked (.+)$", RegexOptions.Compiled);

		private static readonly Regex GoldRegex = new Regex("^(\\d+) Gold$", RegexOptions.Compiled);

		private static readonly Regex ItemXnRegex = new Regex("^(.+) \\(x(\\d+)\\)$", RegexOptions.Compiled);

		private static readonly Regex RepairCostRegex = new Regex("^(.+) \\((\\d+)\\)$", RegexOptions.Compiled);

		private static readonly Regex CraftReqRegex = new Regex("^(.+) - (\\d+)$", RegexOptions.Compiled);

		private static readonly Regex ChatPickupRegex = new Regex("^(.+): Picked up \\((.+)\\)$", RegexOptions.Compiled);

		private static readonly Regex LeadingTagsRegex = new Regex("^((?:<[^>]+>)+)", RegexOptions.Compiled);

		public static int Count => _translations.Count;

		public static void Load(string pluginPath)
		{
			_pluginPath = pluginPath;
			string text = Path.Combine(pluginPath, "translations.json5");
			if (!File.Exists(text))
			{
				Log.LogWarning((object)("translations.json5 파일을 찾을 수 없습니다: " + text));
				return;
			}
			ParseJson(File.ReadAllText(text, Encoding.UTF8));
			try
			{
				File.WriteAllText(Path.Combine(pluginPath, "missed_strings.txt"), "", Encoding.UTF8);
			}
			catch
			{
			}
			if (_regexTranslations.Count > 0)
			{
				Log.LogInfo((object)$"정규식 번역 {_regexTranslations.Count}개 로드");
			}
		}

		private static string PreserveLeadingTags(string original, string translated)
		{
			Match match = LeadingTagsRegex.Match(original);
			if (match.Success)
			{
				return match.Value + translated;
			}
			return translated;
		}

		public static string Translate(string original)
		{
			if (string.IsNullOrEmpty(original))
			{
				return original;
			}
			string text = original.Trim();
			if (_translations.TryGetValue(text, out var value))
			{
				return value;
			}
			string text2 = RichTextTagRegex.Replace(text, "").Trim();
			if (text2 != text && !string.IsNullOrEmpty(text2) && _translations.TryGetValue(text2, out value))
			{
				return PreserveLeadingTags(text, value);
			}
			if (text.Contains("\n"))
			{
				string[] array = text.Split(new char[1] { '\n' });
				bool flag = false;
				for (int i = 0; i < array.Length; i++)
				{
					string text3 = TranslateLine(array[i]);
					if (text3 != array[i])
					{
						array[i] = text3;
						flag = true;
					}
				}
				if (flag)
				{
					return string.Join("\n", array);
				}
			}
			foreach (KeyValuePair<Regex, string> regexTranslation in _regexTranslations)
			{
				if (regexTranslation.Key.IsMatch(text))
				{
					return regexTranslation.Key.Replace(text, regexTranslation.Value);
				}
				if (text2 != text && regexTranslation.Key.IsMatch(text2))
				{
					return PreserveLeadingTags(text, regexTranslation.Key.Replace(text2, regexTranslation.Value));
				}
			}
			Match match = NxItemRegex.Match(text);
			if (match.Success)
			{
				string value2 = match.Groups[2].Value;
				if (_translations.TryGetValue(value2, out value))
				{
					return match.Groups[1].Value + "x " + value;
				}
			}
			Match match2 = UnlockedRegex.Match(text);
			if (match2.Success)
			{
				string value3 = match2.Groups[1].Value;
				if (_translations.TryGetValue(value3, out value))
				{
					return value + " 해금!";
				}
			}
			Match match3 = GoldRegex.Match(text);
			if (match3.Success)
			{
				return match3.Groups[1].Value + " 골드";
			}
			Match match4 = ItemXnRegex.Match(text);
			if (match4.Success)
			{
				string value4 = match4.Groups[1].Value;
				string value5 = match4.Groups[2].Value;
				if (_translations.TryGetValue(value4, out value))
				{
					return value + " (x" + value5 + ")";
				}
			}
			Match match5 = RepairCostRegex.Match(text);
			if (!match5.Success && text2 != text)
			{
				match5 = RepairCostRegex.Match(text2);
			}
			if (match5.Success)
			{
				string value6 = match5.Groups[1].Value;
				string value7 = match5.Groups[2].Value;
				if (_translations.TryGetValue(value6, out value))
				{
					return PreserveLeadingTags(text, value + " (" + value7 + ")");
				}
			}
			Match match6 = CraftReqRegex.Match(text);
			if (!match6.Success && text2 != text)
			{
				match6 = CraftReqRegex.Match(text2);
			}
			if (match6.Success)
			{
				string value8 = match6.Groups[1].Value;
				string value9 = match6.Groups[2].Value;
				if (_translations.TryGetValue(value8, out value))
				{
					return PreserveLeadingTags(text, value + " - " + value9);
				}
			}
			Match match7 = ChatPickupRegex.Match((text2 != text) ? text2 : text);
			if (match7.Success)
			{
				string value10 = match7.Groups[1].Value;
				string value11 = match7.Groups[2].Value;
				string text4 = (_translations.TryGetValue(value11, out value) ? value : value11);
				string value12;
				string text5 = (_translations.TryGetValue("Picked up", out value12) ? value12 : "획득");
				return PreserveLeadingTags(text, value10 + ": " + text4 + " " + text5);
			}
			return original;
		}

		private static string TranslateLine(string line)
		{
			if (string.IsNullOrEmpty(line))
			{
				return line;
			}
			string text = line.Trim();
			if (_translations.TryGetValue(text, out var value))
			{
				return value;
			}
			string text2 = RichTextTagRegex.Replace(text, "").Trim();
			if (text2 != text && !string.IsNullOrEmpty(text2) && _translations.TryGetValue(text2, out value))
			{
				return PreserveLeadingTags(text, value);
			}
			foreach (KeyValuePair<Regex, string> regexTranslation in _regexTranslations)
			{
				if (regexTranslation.Key.IsMatch(text))
				{
					return regexTranslation.Key.Replace(text, regexTranslation.Value);
				}
				if (text2 != text && regexTranslation.Key.IsMatch(text2))
				{
					return PreserveLeadingTags(text, regexTranslation.Key.Replace(text2, regexTranslation.Value));
				}
			}
			Match match = NxItemRegex.Match(text);
			if (match.Success)
			{
				string value2 = match.Groups[2].Value;
				if (_translations.TryGetValue(value2, out value))
				{
					return match.Groups[1].Value + "x " + value;
				}
			}
			Match match2 = UnlockedRegex.Match(text);
			if (match2.Success)
			{
				string value3 = match2.Groups[1].Value;
				if (_translations.TryGetValue(value3, out value))
				{
					return value + " 해금!";
				}
			}
			Match match3 = GoldRegex.Match(text);
			if (match3.Success)
			{
				return match3.Groups[1].Value + " 골드";
			}
			Match match4 = ItemXnRegex.Match(text);
			if (match4.Success)
			{
				string value4 = match4.Groups[1].Value;
				string value5 = match4.Groups[2].Value;
				if (_translations.TryGetValue(value4, out value))
				{
					return value + " (x" + value5 + ")";
				}
			}
			Match match5 = RepairCostRegex.Match(text);
			if (!match5.Success && text2 != text)
			{
				match5 = RepairCostRegex.Match(text2);
			}
			if (match5.Success)
			{
				string value6 = match5.Groups[1].Value;
				string value7 = match5.Groups[2].Value;
				if (_translations.TryGetValue(value6, out value))
				{
					return value + " (" + value7 + ")";
				}
			}
			Match match6 = CraftReqRegex.Match(text);
			if (!match6.Success && text2 != text)
			{
				match6 = CraftReqRegex.Match(text2);
			}
			if (match6.Success)
			{
				string value8 = match6.Groups[1].Value;
				string value9 = match6.Groups[2].Value;
				if (_translations.TryGetValue(value8, out value))
				{
					return value + " - " + value9;
				}
			}
			Match match7 = ChatPickupRegex.Match((text2 != text) ? text2 : text);
			if (match7.Success)
			{
				string value10 = match7.Groups[1].Value;
				string value11 = match7.Groups[2].Value;
				string text3 = (_translations.TryGetValue(value11, out value) ? value : value11);
				string value12;
				string text4 = (_translations.TryGetValue("Picked up", out value12) ? value12 : "획득");
				return PreserveLeadingTags(text, value10 + ": " + text3 + " " + text4);
			}
			return line;
		}

		public static void DumpMissedKey(string key)
		{
			if (string.IsNullOrWhiteSpace(key) || key.Length < 2 || key.Length > 200 || Regex.IsMatch(key, "^[\\d\\s\\.\\,\\:\\;\\-\\+\\=\\!\\?\\#\\%\\&\\*\\(\\)\\[\\]\\{\\}\\/\\\\]+$"))
			{
				return;
			}
			foreach (char c in key)
			{
				if (c >= '가' && c <= '힣')
				{
					return;
				}
			}
			if (!_missedKeys.Add(key))
			{
				return;
			}
			try
			{
				File.AppendAllText(Path.Combine(_pluginPath, "missed_strings.txt"), key + Environment.NewLine, Encoding.UTF8);
			}
			catch
			{
			}
		}

		private static void ParseJson(string json)
		{
			json = Regex.Replace(json, "//.*?$", "", RegexOptions.Multiline);
			json = Regex.Replace(json, "/\\*.*?\\*/", "", RegexOptions.Singleline);
			foreach (Match item in Regex.Matches(json, "\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"\\s*:\\s*\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\""))
			{
				string text = UnescapeJson(item.Groups[1].Value);
				string value = UnescapeJson(item.Groups[2].Value);
				if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(value))
				{
					continue;
				}
				if (text.StartsWith("regex:"))
				{
					string text2 = text.Substring(6);
					try
					{
						Regex key = new Regex(text2, RegexOptions.Compiled | RegexOptions.Singleline);
						_regexTranslations.Add(new KeyValuePair<Regex, string>(key, value));
					}
					catch (Exception ex)
					{
						Log.LogWarning((object)("정규식 패턴 오류: '" + text2 + "' - " + ex.Message));
					}
				}
				else
				{
					_translations[text] = value;
				}
			}
		}

		public static string GetAllKoreanCharacters()
		{
			HashSet<char> hashSet = new HashSet<char>();
			foreach (string value in _translations.Values)
			{
				foreach (char c in value)
				{
					if (c >= '가' && c <= '힣')
					{
						hashSet.Add(c);
					}
				}
			}
			foreach (KeyValuePair<Regex, string> regexTranslation in _regexTranslations)
			{
				string current = regexTranslation.Value;
				foreach (char c2 in current)
				{
					if (c2 >= '가' && c2 <= '힣')
					{
						hashSet.Add(c2);
					}
				}
			}
			StringBuilder stringBuilder = new StringBuilder(hashSet.Count);
			foreach (char item in hashSet)
			{
				stringBuilder.Append(item);
			}
			return stringBuilder.ToString();
		}

		private static string UnescapeJson(string s)
		{
			return s.Replace("\\n", "\n").Replace("\\t", "\t").Replace("\\\"", "\"")
				.Replace("\\\\", "\\");
		}
	}
}
namespace MuckKorean.Patches
{
	public class DelayedMeshUpdater : MonoBehaviour
	{
		private void OnEnable()
		{
			((MonoBehaviour)this).StartCoroutine(RebuildAfterLayout());
		}

		private IEnumerator RebuildAfterLayout()
		{
			yield return (object)new WaitForEndOfFrame();
			yield return null;
			TMP_Text component = ((Component)this).GetComponent<TMP_Text>();
			if ((Object)(object)component != (Object)null && ((Component)component).gameObject.activeInHierarchy)
			{
				component.ForceMeshUpdate(false, false);
			}
			Object.Destroy((Object)(object)this);
		}
	}
	internal static class KoreanTextHelper
	{
		internal static void FixOverflowIfNeeded(TMP_Text tmp)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			if (!((Object)(object)tmp == (Object)null) && !tmp.enableAutoSizing && ((int)tmp.overflowMode == 1 || (int)tmp.overflowMode == 3))
			{
				tmp.enableAutoSizing = true;
				tmp.fontSizeMin = Mathf.Max(1f, tmp.fontSize - 4f);
				tmp.fontSizeMax = tmp.fontSize;
			}
		}

		internal static bool ContainsKorean(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			foreach (char c in text)
			{
				if (c >= '가' && c <= '힣')
				{
					return true;
				}
			}
			return false;
		}
	}
	internal static class PatchLog
	{
		internal static readonly ManualLogSource Log = Logger.CreateLogSource("MuckKorean.Patch");
	}
	[HarmonyPatch(typeof(FontEngine), "LoadFontFace", new Type[]
	{
		typeof(Font),
		typeof(int)
	})]
	public static class FontEngine_LoadFontFace_Patch
	{
		private static bool Prefix(Font font, int pointSize, ref FontEngineError __result)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected I4, but got Unknown
			if ((Object)(object)font == (Object)null || (Object)(object)FontManager.SourceFont == (Object)null || FontManager.FontFilePath == null)
			{
				return true;
			}
			if ((Object)(object)font == (Object)(object)FontManager.SourceFont)
			{
				__result = (FontEngineError)(int)FontEngine.LoadFontFace(FontManager.FontFilePath, pointSize);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(TMP_Text), "set_text")]
	public static class TMP_Text_SetText_Patch
	{
		private static void Prefix(TMP_Text __instance, ref string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				return;
			}
			string text = TranslationManager.Translate(value);
			if (text != value)
			{
				FontManager.ApplyFont(__instance);
				value = text;
				if (KoreanTextHelper.ContainsKorean(text))
				{
					KoreanTextHelper.FixOverflowIfNeeded(__instance);
					if (!((Component)__instance).gameObject.activeInHierarchy && (Object)(object)((Component)__instance).gameObject.GetComponent<DelayedMeshUpdater>() == (Object)null)
					{
						((Component)__instance).gameObject.AddComponent<DelayedMeshUpdater>();
					}
				}
			}
			else
			{
				TranslationManager.DumpMissedKey(value);
			}
		}
	}
	[HarmonyPatch(typeof(TextMeshProUGUI), "OnEnable")]
	public static class TMP_UGUI_OnEnable_Patch
	{
		private static void Postfix(TextMeshProUGUI __instance)
		{
			FontManager.ApplyFont((TMP_Text)(object)__instance);
			TranslateExistingText((TMP_Text)(object)__instance);
			if ((Object)(object)__instance != (Object)null && !string.IsNullOrEmpty(((TMP_Text)__instance).text) && KoreanTextHelper.ContainsKorean(((TMP_Text)__instance).text))
			{
				KoreanTextHelper.FixOverflowIfNeeded((TMP_Text)(object)__instance);
				((Graphic)__instance).SetAllDirty();
			}
		}

		private static void TranslateExistingText(TMP_Text tmp)
		{
			if (!((Object)(object)tmp == (Object)null) && !string.IsNullOrEmpty(tmp.text))
			{
				string text = TranslationManager.Translate(tmp.text);
				if (text != tmp.text)
				{
					tmp.text = text;
				}
			}
		}
	}
	[HarmonyPatch(typeof(TextMeshPro), "OnEnable")]
	public static class TMP_OnEnable_Patch
	{
		private static void Postfix(TextMeshPro __instance)
		{
			FontManager.ApplyFont((TMP_Text)(object)__instance);
			if ((Object)(object)__instance != (Object)null && !string.IsNullOrEmpty(((TMP_Text)__instance).text))
			{
				string text = TranslationManager.Translate(((TMP_Text)__instance).text);
				if (text != ((TMP_Text)__instance).text)
				{
					((TMP_Text)__instance).text = text;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Text), "set_text")]
	public static class UIText_SetText_Patch
	{
		private static void Prefix(Text __instance, ref string value)
		{
			if (!string.IsNullOrEmpty(value))
			{
				string text = TranslationManager.Translate(value);
				if (text != value)
				{
					FontManager.ApplyFont(__instance, text);
					value = text;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Text), "OnEnable")]
	public static class UIText_OnEnable_Patch
	{
		private static void Postfix(Text __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !string.IsNullOrEmpty(__instance.text))
			{
				string text = TranslationManager.Translate(__instance.text);
				if (text != __instance.text)
				{
					FontManager.ApplyFont(__instance, text);
					__instance.text = text;
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemInfo), "FitToText")]
	public static class ItemInfo_FitToText_Patch
	{
		private static readonly FieldRef<ItemInfo, bool> leftCornerRef = AccessTools.FieldRefAccess<ItemInfo, bool>("leftCorner");

		private static readonly FieldRef<ItemInfo, Vector3> defaultTextPosRef = AccessTools.FieldRefAccess<ItemInfo, Vector3>("defaultTextPos");

		private static bool Prefix(ItemInfo __instance)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI text = __instance.text;
			if ((Object)(object)text == (Object)null)
			{
				return true;
			}
			Bounds textBounds = ((TMP_Text)text).textBounds;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(((Bounds)(ref textBounds)).size.x + __instance.padding, ((Bounds)(ref textBounds)).size.y + __instance.padding);
			bool num = leftCornerRef.Invoke(__instance);
			Vector3 val2 = defaultTextPosRef.Invoke(__instance);
			if (num)
			{
				((TMP_Text)text).transform.localPosition = -val2 - new Vector3(val.x, val.y, 0f);
			}
			else
			{
				((TMP_Text)text).transform.localPosition = val2;
			}
			((Graphic)__instance.image).rectTransform.sizeDelta = val;
			((Transform)((Graphic)__instance.image).rectTransform).position = ((Transform)((TMP_Text)text).rectTransform).position;
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(__instance.padding / 2f, 0f, 0f);
			((Transform)((Graphic)__instance.image).rectTransform).localPosition = ((Transform)((TMP_Text)text).rectTransform).localPosition - val3;
			return false;
		}
	}
	[HarmonyPatch(typeof(TextMesh), "set_text")]
	public static class TextMesh_SetText_Patch
	{
		private static void Prefix(TextMesh __instance, ref string value)
		{
			if (!string.IsNullOrEmpty(value))
			{
				string text = TranslationManager.Translate(value);
				if (text != value)
				{
					FontManager.ApplyFont(__instance, text);
					value = text;
				}
			}
		}
	}
}