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();
}
}