Decompiled source of Muck Translater v1.0.1

BepInEx/plugins/UU9.Muck.Translater.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.TextCore;
using UnityEngine.TextCore.LowLevel;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("UU9.Muck.Translater")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("P R C")]
[assembly: AssemblyProduct("UU9.Muck.Translater")]
[assembly: AssemblyCopyright("Copyright © P R C 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("63b5c9fb-b128-4ef9-bbde-452c57595106")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace UU9.Muck.Translater;

[BepInPlugin("UU9.Muck.Translater", "UU9 Muck Translater", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
	public const string PluginGuid = "UU9.Muck.Translater";

	public const string PluginName = "UU9 Muck Translater";

	public const string PluginVersion = "1.0.0";

	private Harmony _harmony;

	private static Plugin _instance;

	private int _pendingTextRefreshFrames;

	private static ConfigEntry<string> _fontFile;

	private static ConfigEntry<bool> _enableF5Reload;

	private static ConfigEntry<bool> _enableF6Toggle;

	public static ManualLogSource Log { get; private set; }

	public static string FontFile => _fontFile?.Value ?? "msyh.ttc";

	public static bool IsF5ReloadEnabled => _enableF5Reload?.Value ?? true;

	public static bool IsF6ToggleEnabled => _enableF6Toggle?.Value ?? true;

	public static bool IsTranslationEnabled { get; private set; } = true;

	private void Awake()
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		_instance = this;
		try
		{
			InitializeSettings();
			FontManager.Initialize(Log);
			TranslationManager.Initialize(Log);
			_harmony = new Harmony("UU9.Muck.Translater");
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			SceneManager.sceneLoaded += OnSceneLoaded;
			RefreshSceneTexts();
			Log.LogInfo((object)"[UU9 Translater] UU9 Muck Translater v1.0.0 初始化成功!按下 F5 可热重载词典。");
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[UU9 Translater] 初始化阶段抛出异常: " + ex.Message));
		}
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		Log.LogInfo((object)("[UU9 Translater] 检测到场景加载: " + ((Scene)(ref scene)).name + ",正在自动刷新 UI 汉化文本..."));
		RefreshSceneTexts();
	}

	private static void InitializeSettings()
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Expected O, but got Unknown
		string text = Path.Combine(Paths.ConfigPath, "UU9.Muck.Translater");
		Directory.CreateDirectory(text);
		string text2 = Path.Combine(text, "UU9.Muck.Translater.cfg");
		ConfigFile val = new ConfigFile(text2, true);
		_fontFile = val.Bind<string>("General", "FontFile", "msyh.ttc", "Font filename to use. Searches C:\\Windows\\Fonts first, then BepInEx\\config\\UU9.Muck.Translater\\Font.");
		_enableF5Reload = val.Bind<bool>("Hotkeys", "EnableF5Reload", true, "Enable F5 dictionary reload.");
		_enableF6Toggle = val.Bind<bool>("Hotkeys", "EnableF6Toggle", true, "Enable F6 translation toggle.");
	}

	private void Update()
	{
		if (_pendingTextRefreshFrames > 0)
		{
			_pendingTextRefreshFrames--;
			if (_pendingTextRefreshFrames == 0 && IsTranslationEnabled)
			{
				RefreshSceneTexts(logCompletion: false);
			}
		}
		if (IsF5ReloadEnabled && Input.GetKeyDown((KeyCode)286))
		{
			Log.LogInfo((object)"[UU9 Translater] 触发 F5 热重载,正在重新读取汉化词典并更新界面...");
			TranslationManager.LoadTranslations();
			if (IsTranslationEnabled)
			{
				RefreshSceneTexts();
			}
		}
		if (IsF6ToggleEnabled && Input.GetKeyDown((KeyCode)287))
		{
			IsTranslationEnabled = !IsTranslationEnabled;
			if (IsTranslationEnabled)
			{
				Log.LogInfo((object)"[UU9 Translater] 触发 F6:开启汉化,正在还原汉化文本...");
				RefreshSceneTexts();
			}
			else
			{
				Log.LogInfo((object)"[UU9 Translater] 触发 F6:暂时关闭汉化,正在还原为英文原文...");
				RestoreOriginalSceneTexts();
			}
		}
	}

	public static void RequestSceneTextRefresh()
	{
		if (!((Object)(object)_instance == (Object)null) && _instance._pendingTextRefreshFrames == 0)
		{
			_instance._pendingTextRefreshFrames = 2;
		}
	}

	private void RestoreOriginalSceneTexts()
	{
		try
		{
			int num = 0;
			TMP_Text[] array = Resources.FindObjectsOfTypeAll<TMP_Text>();
			TMP_Text[] array2 = array;
			foreach (TMP_Text val in array2)
			{
				if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeInHierarchy && TranslationManager.TryGetOriginal(val.text, out var original) && val.text != original)
				{
					val.text = original;
					num++;
				}
			}
			Text[] array3 = Resources.FindObjectsOfTypeAll<Text>();
			Text[] array4 = array3;
			foreach (Text val2 in array4)
			{
				if (!((Object)(object)val2 == (Object)null) && ((Component)val2).gameObject.activeInHierarchy && TranslationManager.TryGetOriginal(val2.text, out var original2) && val2.text != original2)
				{
					val2.text = original2;
					num++;
				}
			}
			FontManager.RestoreOriginalFonts();
			Log.LogInfo((object)$"[UU9 Translater] F6 还原完成,成功将 {num} 处文本还原为英文原文。");
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[UU9 Translater] 还原英文原文 UI 出错: " + ex.Message));
		}
	}

	private void RefreshSceneTexts(bool logCompletion = true)
	{
		try
		{
			int num = 0;
			TMP_Text[] array = Resources.FindObjectsOfTypeAll<TMP_Text>();
			TMP_Text[] array2 = array;
			foreach (TMP_Text val in array2)
			{
				if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeInHierarchy)
				{
					FontManager.ApplyFont(val);
					if (TranslationManager.TryGetTranslation(val.text, out var translated) && val.text != translated)
					{
						FontManager.ApplyTranslatedFont(val, translated);
						val.text = translated;
						FontManager.RefreshLayout(val);
						num++;
					}
				}
			}
			Text[] array3 = Resources.FindObjectsOfTypeAll<Text>();
			Text[] array4 = array3;
			foreach (Text val2 in array4)
			{
				if (!((Object)(object)val2 == (Object)null) && ((Component)val2).gameObject.activeInHierarchy)
				{
					FontManager.ApplyFont(val2);
					if (TranslationManager.TryGetTranslation(val2.text, out var translated2) && val2.text != translated2)
					{
						val2.text = translated2;
						num++;
					}
				}
			}
			if (logCompletion)
			{
				Log.LogInfo((object)$"[UU9 Translater] F5 刷新完成,成功更新 {num} 处文本。");
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[UU9 Translater] 刷新场景 UI 文本出错: " + ex.Message));
		}
	}

	private void OnDestroy()
	{
		SceneManager.sceneLoaded -= OnSceneLoaded;
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		if ((Object)(object)_instance == (Object)(object)this)
		{
			_instance = null;
		}
	}
}
public static class FontManager
{
	private static Font _chineseOSFont;

	private static TMP_FontAsset _chineseTMPFont;

	private static ManualLogSource _logger;

	private static bool _initialized;

	private static readonly Dictionary<int, TMP_FontAsset> OriginalTMPFonts = new Dictionary<int, TMP_FontAsset>();

	private static readonly Dictionary<int, Material> OriginalTMPMaterials = new Dictionary<int, Material>();

	private static readonly Dictionary<int, Font> OriginalUIFonts = new Dictionary<int, Font>();

	private static readonly Dictionary<int, Material> ChineseMaterialsBySource = new Dictionary<int, Material>();

	public static void Initialize(ManualLogSource logger)
	{
		//IL_0255: Unknown result type (might be due to invalid IL or missing references)
		//IL_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0261: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: 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)
		//IL_00bd: Expected O, but got Unknown
		//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
		if (_initialized)
		{
			return;
		}
		_logger = logger;
		try
		{
			string text = Path.GetFileName(Plugin.FontFile);
			if (string.IsNullOrWhiteSpace(text))
			{
				text = "msyh.ttc";
			}
			string path = Path.Combine(Paths.ConfigPath, "UU9.Muck.Translater", "Font");
			string[] array = new string[7]
			{
				Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), text),
				Path.Combine(path, text),
				"C:\\Windows\\Fonts\\msyh.ttc",
				"C:\\Windows\\Fonts\\msyh.ttf",
				"C:\\Windows\\Fonts\\simhei.ttf",
				"C:\\Windows\\Fonts\\simsun.ttc",
				"C:\\Windows\\Fonts\\arial.ttf"
			};
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				if (!File.Exists(text2))
				{
					continue;
				}
				try
				{
					_chineseOSFont = new Font(text2);
					if ((Object)(object)_chineseOSFont != (Object)null)
					{
						Object.DontDestroyOnLoad((Object)(object)_chineseOSFont);
						((Object)_chineseOSFont).hideFlags = (HideFlags)61;
						break;
					}
				}
				catch
				{
				}
			}
			if ((Object)(object)_chineseOSFont == (Object)null)
			{
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text);
				string[] array3 = new string[5] { fileNameWithoutExtension, "Microsoft YaHei UI", "Microsoft YaHei", "SimHei", "Arial" };
				_chineseOSFont = Font.CreateDynamicFontFromOSFont(array3, 24);
				if ((Object)(object)_chineseOSFont != (Object)null)
				{
					Object.DontDestroyOnLoad((Object)(object)_chineseOSFont);
					((Object)_chineseOSFont).hideFlags = (HideFlags)61;
				}
			}
			if ((Object)(object)_chineseOSFont == (Object)null)
			{
				_chineseOSFont = Resources.GetBuiltinResource<Font>("Arial.ttf");
			}
			if ((Object)(object)_chineseOSFont != (Object)null)
			{
				try
				{
					_chineseTMPFont = TMP_FontAsset.CreateFontAsset(_chineseOSFont, 90, 5, (GlyphRenderMode)4165, 4096, 4096, (AtlasPopulationMode)1, false);
				}
				catch
				{
				}
				if ((Object)(object)_chineseTMPFont != (Object)null)
				{
					Object.DontDestroyOnLoad((Object)(object)_chineseTMPFont);
					((Object)_chineseTMPFont).name = "UU9_Chinese_TMPFont";
					((Object)_chineseTMPFont).hideFlags = (HideFlags)61;
					_chineseTMPFont.atlasPopulationMode = (AtlasPopulationMode)1;
					_chineseTMPFont.isMultiAtlasTexturesEnabled = false;
					try
					{
						if ((Object)(object)TMP_Settings.defaultFontAsset != (Object)null)
						{
							FaceInfo faceInfo = TMP_Settings.defaultFontAsset.faceInfo;
							FaceInfo faceInfo2 = _chineseTMPFont.faceInfo;
							if (((FaceInfo)(ref faceInfo)).lineHeight > 0f && ((FaceInfo)(ref faceInfo2)).lineHeight > 0f)
							{
								float num = ((FaceInfo)(ref faceInfo)).lineHeight / ((FaceInfo)(ref faceInfo2)).lineHeight;
								((FaceInfo)(ref faceInfo2)).lineHeight = ((FaceInfo)(ref faceInfo)).lineHeight;
								((FaceInfo)(ref faceInfo2)).ascentLine = (int)(((FaceInfo)(ref faceInfo2)).ascentLine * num);
								((FaceInfo)(ref faceInfo2)).descentLine = (int)(((FaceInfo)(ref faceInfo2)).descentLine * num);
								_chineseTMPFont.faceInfo = faceInfo2;
							}
						}
					}
					catch
					{
					}
					try
					{
						if (TMP_Settings.fallbackFontAssets != null && !TMP_Settings.fallbackFontAssets.Contains(_chineseTMPFont))
						{
							TMP_Settings.fallbackFontAssets.Add(_chineseTMPFont);
						}
						if ((Object)(object)TMP_Settings.defaultFontAsset != (Object)null)
						{
							if (TMP_Settings.defaultFontAsset.fallbackFontAssetTable == null)
							{
								TMP_Settings.defaultFontAsset.fallbackFontAssetTable = new List<TMP_FontAsset>();
							}
							if (!TMP_Settings.defaultFontAsset.fallbackFontAssetTable.Contains(_chineseTMPFont))
							{
								TMP_Settings.defaultFontAsset.fallbackFontAssetTable.Add(_chineseTMPFont);
							}
						}
					}
					catch
					{
					}
				}
			}
			_initialized = true;
		}
		catch (Exception ex)
		{
			ManualLogSource logger2 = _logger;
			if (logger2 != null)
			{
				logger2.LogError((object)("[UU9 Translater] FontManager 初始化异常: " + ex.Message));
			}
		}
	}

	public static void AddCharactersToFont(string text)
	{
		if ((Object)(object)_chineseTMPFont == (Object)null || string.IsNullOrEmpty(text))
		{
			return;
		}
		try
		{
			_chineseTMPFont.TryAddCharacters(text, false);
		}
		catch
		{
		}
	}

	public static void ApplyTranslatedFont(TMP_Text tmpText, string translated)
	{
		if ((Object)(object)tmpText == (Object)null || (Object)(object)_chineseTMPFont == (Object)null || string.IsNullOrEmpty(translated))
		{
			return;
		}
		try
		{
			AddCharactersToFont(translated);
			if (ContainsNonAscii(translated) && (Object)(object)tmpText.font != (Object)(object)_chineseTMPFont)
			{
				RememberOriginalFont(tmpText);
				Material fontSharedMaterial = tmpText.fontSharedMaterial;
				tmpText.font = _chineseTMPFont;
				Material chineseMaterial = GetChineseMaterial(fontSharedMaterial);
				if ((Object)(object)chineseMaterial != (Object)null)
				{
					tmpText.fontSharedMaterial = chineseMaterial;
				}
			}
		}
		catch
		{
		}
	}

	public static void RefreshLayout(TMP_Text tmpText)
	{
		if ((Object)(object)tmpText == (Object)null)
		{
			return;
		}
		try
		{
			((Graphic)tmpText).SetVerticesDirty();
			((Graphic)tmpText).SetLayoutDirty();
			tmpText.ForceMeshUpdate(false, false);
			LayoutRebuilder.ForceRebuildLayoutImmediate(tmpText.rectTransform);
			Transform parent = ((Transform)tmpText.rectTransform).parent;
			RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			if ((Object)(object)val != (Object)null)
			{
				LayoutRebuilder.MarkLayoutForRebuild(val);
			}
		}
		catch
		{
		}
	}

	private static bool ContainsNonAscii(string text)
	{
		foreach (char c in text)
		{
			if (c > '\u007f')
			{
				return true;
			}
		}
		return false;
	}

	public static void ApplyFont(TMP_Text tmpText)
	{
		if ((Object)(object)tmpText == (Object)null || (Object)(object)_chineseTMPFont == (Object)null)
		{
			return;
		}
		try
		{
			if ((Object)(object)tmpText.font != (Object)null)
			{
				if ((Object)(object)tmpText.font != (Object)(object)_chineseTMPFont)
				{
					if (tmpText.font.fallbackFontAssetTable == null)
					{
						tmpText.font.fallbackFontAssetTable = new List<TMP_FontAsset>();
					}
					if (!tmpText.font.fallbackFontAssetTable.Contains(_chineseTMPFont))
					{
						tmpText.font.fallbackFontAssetTable.Add(_chineseTMPFont);
					}
				}
			}
			else
			{
				tmpText.font = _chineseTMPFont;
			}
			if (tmpText.text != null && tmpText.text.Contains("\n"))
			{
				tmpText.lineSpacingAdjustment = 0f;
			}
		}
		catch
		{
		}
	}

	public static void ApplyFont(Text uiText)
	{
		if ((Object)(object)uiText == (Object)null || (Object)(object)_chineseOSFont == (Object)null)
		{
			return;
		}
		try
		{
			RememberOriginalFont(uiText);
			uiText.font = _chineseOSFont;
		}
		catch
		{
		}
	}

	public static void RestoreOriginalFonts()
	{
		try
		{
			TMP_Text[] array = Resources.FindObjectsOfTypeAll<TMP_Text>();
			TMP_Text[] array2 = array;
			foreach (TMP_Text val in array2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				int instanceID = ((Object)val).GetInstanceID();
				if (OriginalTMPFonts.TryGetValue(instanceID, out var value))
				{
					if ((Object)(object)value != (Object)null)
					{
						val.font = value;
					}
					if (OriginalTMPMaterials.TryGetValue(instanceID, out var value2) && (Object)(object)value2 != (Object)null)
					{
						val.fontSharedMaterial = value2;
					}
					OriginalTMPFonts.Remove(instanceID);
					OriginalTMPMaterials.Remove(instanceID);
				}
			}
			Text[] array3 = Resources.FindObjectsOfTypeAll<Text>();
			Text[] array4 = array3;
			foreach (Text val2 in array4)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				int instanceID2 = ((Object)val2).GetInstanceID();
				if (OriginalUIFonts.TryGetValue(instanceID2, out var value3))
				{
					if ((Object)(object)value3 != (Object)null)
					{
						val2.font = value3;
					}
					OriginalUIFonts.Remove(instanceID2);
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogError((object)("[UU9 Translater] Restore original fonts failed: " + ex.Message));
			}
		}
	}

	private static void RememberOriginalFont(TMP_Text tmpText)
	{
		int instanceID = ((Object)tmpText).GetInstanceID();
		if (!OriginalTMPFonts.ContainsKey(instanceID))
		{
			OriginalTMPFonts[instanceID] = tmpText.font;
			OriginalTMPMaterials[instanceID] = tmpText.fontSharedMaterial;
		}
	}

	private static Material GetChineseMaterial(Material sourceMaterial)
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Expected O, but got Unknown
		if ((Object)(object)sourceMaterial == (Object)null || (Object)(object)_chineseTMPFont == (Object)null)
		{
			return null;
		}
		int instanceID = ((Object)sourceMaterial).GetInstanceID();
		if (ChineseMaterialsBySource.TryGetValue(instanceID, out var value) && (Object)(object)value != (Object)null)
		{
			return value;
		}
		try
		{
			Material val = new Material(sourceMaterial);
			((Object)val).name = "UU9_Chinese_" + ((Object)sourceMaterial).name;
			val.mainTexture = (Texture)(object)_chineseTMPFont.atlasTexture;
			((Object)val).hideFlags = (HideFlags)61;
			ChineseMaterialsBySource[instanceID] = val;
			return val;
		}
		catch
		{
			return null;
		}
	}

	private static void RememberOriginalFont(Text uiText)
	{
		int instanceID = ((Object)uiText).GetInstanceID();
		if (!OriginalUIFonts.ContainsKey(instanceID))
		{
			OriginalUIFonts[instanceID] = uiText.font;
		}
	}
}
public static class TranslationManager
{
	private static readonly Dictionary<string, string> Translations = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

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

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

	private static string _translationDir;

	private static ManualLogSource _logger;

	private static List<string> _cachedSortedKeys;

	public static void Initialize(ManualLogSource logger)
	{
		_logger = logger;
		_translationDir = Path.Combine(Paths.ConfigPath, "UU9.Muck.Translater", "Translation");
		Directory.CreateDirectory(_translationDir);
		LoadTranslations();
	}

	public static void LoadTranslations()
	{
		Translations.Clear();
		ReverseTranslations.Clear();
		_cachedSortedKeys = null;
		if (string.IsNullOrEmpty(_translationDir) || !Directory.Exists(_translationDir))
		{
			return;
		}
		try
		{
			string[] files = Directory.GetFiles(_translationDir, "*.cfg", SearchOption.AllDirectories);
			int num = 0;
			StringBuilder stringBuilder = new StringBuilder();
			string[] array = files;
			foreach (string path in array)
			{
				string[] array2 = File.ReadAllLines(path, Encoding.UTF8);
				foreach (string text in array2)
				{
					if (string.IsNullOrWhiteSpace(text) || text.StartsWith("#") || text.StartsWith("//"))
					{
						continue;
					}
					int num2 = text.IndexOf('=');
					if (num2 <= 0)
					{
						continue;
					}
					string text2 = text.Substring(0, num2).Trim().Replace("\\n", "\n")
						.Replace("\\r", "\r");
					string text3 = text.Substring(num2 + 1).Trim().Replace("\\n", "\n")
						.Replace("\\r", "\r");
					if (!string.IsNullOrEmpty(text2) && !Translations.ContainsKey(text2))
					{
						Translations[text2] = text3;
						if (!string.IsNullOrEmpty(text3) && !ReverseTranslations.ContainsKey(text3))
						{
							ReverseTranslations[text3] = text2;
						}
						stringBuilder.Append(text3);
						num++;
					}
				}
			}
			for (char c = ' '; c <= '~'; c = (char)(c + 1))
			{
				stringBuilder.Append(c);
			}
			FontManager.AddCharactersToFont(stringBuilder.ToString());
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogInfo((object)$"[UU9 Translater] 从 {files.Length} 个词典文件加载 {num} 条翻译文本:{_translationDir}");
			}
		}
		catch (Exception ex)
		{
			ManualLogSource logger2 = _logger;
			if (logger2 != null)
			{
				logger2.LogError((object)("[UU9 Translater] 读取词典目录失败: " + ex.Message));
			}
		}
	}

	public static bool TryGetOriginal(string translated, out string original)
	{
		original = null;
		if (string.IsNullOrWhiteSpace(translated))
		{
			return false;
		}
		if (ReverseTranslations.TryGetValue(translated, out original))
		{
			return true;
		}
		string key = translated.Trim();
		if (ReverseTranslations.TryGetValue(key, out var value))
		{
			original = PreserveOuterWhitespace(translated, value);
			return true;
		}
		return TryTranslateLines(translated, ReverseTranslations, out original);
	}

	public static bool TryGetTranslation(string original, out string translated)
	{
		translated = null;
		if (string.IsNullOrWhiteSpace(original))
		{
			return false;
		}
		if (Translations.TryGetValue(original, out translated))
		{
			return true;
		}
		string key = original.Trim();
		if (Translations.TryGetValue(key, out var value))
		{
			translated = PreserveOuterWhitespace(original, value);
			return true;
		}
		if (TryTranslateLines(original, Translations, out translated))
		{
			return true;
		}
		string text = original;
		bool flag = false;
		foreach (string sortedTranslationKey in GetSortedTranslationKeys())
		{
			if (!string.IsNullOrEmpty(sortedTranslationKey) && text.IndexOf(sortedTranslationKey, StringComparison.OrdinalIgnoreCase) >= 0)
			{
				text = ReplaceWordOrPhrase(text, sortedTranslationKey, Translations[sortedTranslationKey]);
				flag = true;
			}
		}
		if (!flag)
		{
			return false;
		}
		translated = text;
		return true;
	}

	private static bool TryTranslateLines(string input, Dictionary<string, string> dictionary, out string translated)
	{
		translated = null;
		if (!input.Contains("\n"))
		{
			return false;
		}
		string[] array = input.Split(new char[1] { '\n' });
		bool flag = false;
		for (int i = 0; i < array.Length; i++)
		{
			string text = array[i];
			string text2 = text.Trim('\r', ' ');
			if (!dictionary.TryGetValue(text2, out var value))
			{
				string text3 = RichTextRegex.Replace(text2, string.Empty);
				if (!dictionary.TryGetValue(text3, out value))
				{
					continue;
				}
				array[i] = text.Replace(text3, value);
			}
			else
			{
				array[i] = text.Replace(text2, value);
			}
			flag = true;
		}
		if (!flag)
		{
			return false;
		}
		translated = string.Join("\n", array);
		return true;
	}

	private static string PreserveOuterWhitespace(string original, string replacement)
	{
		int length = original.Length - original.TrimStart(Array.Empty<char>()).Length;
		int num = original.Length - original.TrimEnd(Array.Empty<char>()).Length;
		return original.Substring(0, length) + replacement + original.Substring(original.Length - num);
	}

	private static List<string> GetSortedTranslationKeys()
	{
		if (_cachedSortedKeys != null)
		{
			return _cachedSortedKeys;
		}
		_cachedSortedKeys = new List<string>(Translations.Keys);
		_cachedSortedKeys.Sort((string a, string b) => b.Length.CompareTo(a.Length));
		return _cachedSortedKeys;
	}

	private static string ReplaceWordOrPhrase(string input, string pattern, string replacement)
	{
		bool flag = true;
		foreach (char c in pattern)
		{
			if (!char.IsLetterOrDigit(c) && c != '_')
			{
				flag = false;
				break;
			}
		}
		string text = Regex.Escape(pattern);
		if (flag)
		{
			text = "\\b" + text + "\\b";
		}
		return Regex.Replace(input, text, replacement, RegexOptions.IgnoreCase);
	}
}
[HarmonyPatch(typeof(TMP_Text))]
internal static class TMP_Text_Patches
{
	[HarmonyPrefix]
	[HarmonyPatch("SetTextInternal")]
	public static void SetTextInternal_Prefix(TMP_Text __instance, ref string __0)
	{
		TranslateAndUpdateFont(__instance, ref __0);
	}

	[HarmonyPrefix]
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static void SetTextProperty_Prefix(TMP_Text __instance, ref string value)
	{
		TranslateAndUpdateFont(__instance, ref value);
	}

	[HarmonyPrefix]
	[HarmonyPatch("SetText", new Type[]
	{
		typeof(string),
		typeof(bool)
	})]
	public static void SetText_Prefix(TMP_Text __instance, ref string __0)
	{
		TranslateAndUpdateFont(__instance, ref __0);
	}

	[HarmonyPrefix]
	[HarmonyPatch("SetText", new Type[]
	{
		typeof(string),
		typeof(float)
	})]
	public static void SetText_OneValue_Prefix(TMP_Text __instance, ref string __0)
	{
		TranslateAndUpdateFont(__instance, ref __0);
	}

	[HarmonyPrefix]
	[HarmonyPatch("SetText", new Type[]
	{
		typeof(string),
		typeof(float),
		typeof(float)
	})]
	public static void SetText_TwoValues_Prefix(TMP_Text __instance, ref string __0)
	{
		TranslateAndUpdateFont(__instance, ref __0);
	}

	[HarmonyPrefix]
	[HarmonyPatch("SetText", new Type[]
	{
		typeof(string),
		typeof(float),
		typeof(float),
		typeof(float)
	})]
	public static void SetText_ThreeValues_Prefix(TMP_Text __instance, ref string __0)
	{
		TranslateAndUpdateFont(__instance, ref __0);
	}

	[HarmonyPrefix]
	[HarmonyPatch("SetText", new Type[] { typeof(StringBuilder) })]
	public static void SetText_StringBuilder_Prefix(TMP_Text __instance, ref StringBuilder __0)
	{
		try
		{
			if (__0 != null && !((Object)(object)__instance == (Object)null))
			{
				string original = __0.ToString();
				FontManager.ApplyFont(__instance);
				if (TranslationManager.TryGetTranslation(original, out var translated))
				{
					FontManager.ApplyTranslatedFont(__instance, translated);
					__0 = new StringBuilder(translated);
				}
			}
		}
		catch
		{
		}
	}

	private static void TranslateAndUpdateFont(TMP_Text component, ref string text)
	{
		try
		{
			if (Plugin.IsTranslationEnabled && !((Object)(object)component == (Object)null) && !string.IsNullOrEmpty(text))
			{
				FontManager.ApplyFont(component);
				if (TranslationManager.TryGetTranslation(text, out var translated))
				{
					FontManager.ApplyTranslatedFont(component, translated);
					text = translated;
				}
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch]
internal static class TMP_GetTextElement_Patch
{
	[HarmonyTargetMethod]
	public static MethodBase TargetMethod()
	{
		MethodInfo methodInfo = AccessTools.Method(typeof(TMP_Text), "GetTextElement", new Type[1] { typeof(int) }, (Type[])null);
		if (methodInfo == null)
		{
			methodInfo = AccessTools.Method(typeof(TMP_Text), "GetTextElement", new Type[1] { typeof(uint) }, (Type[])null);
		}
		if (methodInfo == null)
		{
			methodInfo = AccessTools.Method(typeof(TMP_Text), "GetTextElement", new Type[1] { typeof(char) }, (Type[])null);
		}
		if (methodInfo == null)
		{
			methodInfo = AccessTools.FirstMethod(typeof(TMP_Text), (Func<MethodInfo, bool>)((MethodInfo m) => m.Name == "GetTextElement"));
		}
		return methodInfo;
	}

	[HarmonyPostfix]
	public static void Postfix(object __0, ref TMP_TextElement __result)
	{
		if (__result != null || __0 == null)
		{
			return;
		}
		try
		{
			int num = Convert.ToInt32(__0);
			if (num > 0)
			{
				string text = char.ConvertFromUtf32(num);
				FontManager.AddCharactersToFont(text);
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(Text))]
internal static class UnityEngine_UI_Text_Patches
{
	[HarmonyPrefix]
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static void SetTextProperty_Prefix(Text __instance, ref string value)
	{
		TranslateAndUpdateFont(__instance, ref value);
	}

	private static void TranslateAndUpdateFont(Text component, ref string text)
	{
		try
		{
			if (Plugin.IsTranslationEnabled && !((Object)(object)component == (Object)null) && !string.IsNullOrEmpty(text))
			{
				FontManager.ApplyFont(component);
				if (TranslationManager.TryGetTranslation(text, out var translated))
				{
					text = translated;
				}
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(TextMeshProUGUI))]
internal static class TextMeshProUGUI_OnEnable_Patch
{
	[HarmonyPostfix]
	[HarmonyPatch("OnEnable")]
	public static void Postfix(TextMeshProUGUI __instance)
	{
		try
		{
			if (!Plugin.IsTranslationEnabled || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			string text = ((TMP_Text)__instance).text;
			if (!string.IsNullOrEmpty(text))
			{
				FontManager.ApplyFont((TMP_Text)(object)__instance);
				if (TranslationManager.TryGetTranslation(text, out var translated) && text != translated)
				{
					FontManager.ApplyTranslatedFont((TMP_Text)(object)__instance, translated);
					((TMP_Text)__instance).text = translated;
					FontManager.RefreshLayout((TMP_Text)(object)__instance);
				}
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(TextMeshPro))]
internal static class TextMeshPro_OnEnable_Patch
{
	[HarmonyPostfix]
	[HarmonyPatch("OnEnable")]
	public static void Postfix(TextMeshPro __instance)
	{
		try
		{
			if (!Plugin.IsTranslationEnabled || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			string text = ((TMP_Text)__instance).text;
			if (!string.IsNullOrEmpty(text))
			{
				FontManager.ApplyFont((TMP_Text)(object)__instance);
				if (TranslationManager.TryGetTranslation(text, out var translated) && text != translated)
				{
					FontManager.ApplyTranslatedFont((TMP_Text)(object)__instance, translated);
					((TMP_Text)__instance).text = translated;
					FontManager.RefreshLayout((TMP_Text)(object)__instance);
				}
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(Text))]
internal static class Text_OnEnable_Patch
{
	[HarmonyPostfix]
	[HarmonyPatch("OnEnable")]
	public static void Postfix(Text __instance)
	{
		try
		{
			if (!Plugin.IsTranslationEnabled || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			string text = __instance.text;
			if (!string.IsNullOrEmpty(text))
			{
				FontManager.ApplyFont(__instance);
				if (TranslationManager.TryGetTranslation(text, out var translated) && text != translated)
				{
					__instance.text = translated;
				}
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch]
internal static class CraftingUI_UpdateCraftables_Patch
{
	[HarmonyTargetMethod]
	public static MethodBase TargetMethod()
	{
		Type type = AccessTools.TypeByName("CraftingUI");
		return (type == null) ? null : AccessTools.Method(type, "UpdateCraftables", (Type[])null, (Type[])null);
	}

	[HarmonyPostfix]
	public static void Postfix()
	{
		Plugin.RequestSceneTextRefresh();
	}
}
[HarmonyPatch]
internal static class InventoryCell_OnPointerEnter_Patch
{
	[HarmonyTargetMethod]
	public static MethodBase TargetMethod()
	{
		Type type = AccessTools.TypeByName("InventoryCell");
		return (type == null) ? null : AccessTools.Method(type, "OnPointerEnter", (Type[])null, (Type[])null);
	}

	[HarmonyPostfix]
	public static void Postfix()
	{
		Plugin.RequestSceneTextRefresh();
	}
}