using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using REPOJapaneseTranslation.Localization; using REPOJapaneseTranslation.Patches; using TMPro; using UnityEngine; using UnityEngine.TextCore; using UnityEngine.TextCore.LowLevel; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("LocalBuild")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Japanese localization and Checkpoint Revenge font mod for R.E.P.O. v0.4.4.")] [assembly: AssemblyFileVersion("4.1.0.0")] [assembly: AssemblyInformationalVersion("4.1.0")] [assembly: AssemblyProduct("REPO JP Translation and Font Updated")] [assembly: AssemblyTitle("REPOJPTranslationAndFontUpdated")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("4.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 REPOJapaneseTranslation { [BepInPlugin("local.REPOJPTranslationAndFontUpdated", "REPO JP Translation and Font Updated", "4.1.0")] [BepInProcess("REPO.exe")] public sealed class Plugin : BaseUnityPlugin { private readonly Harmony _harmony = new Harmony("local.REPOJPTranslationAndFontUpdated"); internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static ConfigEntry EnableTranslation { get; private set; } internal static ConfigEntry EnableJapaneseFont { get; private set; } internal static ConfigEntry FontSizeScale { get; private set; } internal static ConfigEntry FontLineHeightScale { get; private set; } internal static ConfigEntry LogUntranslated { get; private set; } private void Awake() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)((Component)this).gameObject); EnableTranslation = ((BaseUnityPlugin)this).Config.Bind("General", "EnableTranslation", true, "ゲーム内テキストを日本語へ翻訳します。"); EnableJapaneseFont = ((BaseUnityPlugin)this).Config.Bind("General", "EnableJapaneseFont", true, "チェックポイント★リベンジをTextMeshProへ適用します。"); FontSizeScale = ((BaseUnityPlugin)this).Config.Bind("General", "FontSizeScale", 0.72f, new ConfigDescription("日本語フォントの表示倍率。1.0がゲーム本来のフォントサイズです。", (AcceptableValueBase)new AcceptableValueRange(0.5f, 1f), Array.Empty())); FontLineHeightScale = ((BaseUnityPlugin)this).Config.Bind("General", "FontLineHeightScale", 1.35f, new ConfigDescription("複数行テキストの行高倍率。文字が重なる場合に大きくします。", (AcceptableValueBase)new AcceptableValueRange(1f, 2f), Array.Empty())); LogUntranslated = ((BaseUnityPlugin)this).Config.Bind("Debug", "LogUntranslated", false, "未翻訳テキストをBepInExログへ出力します(翻訳追加作業用)。"); TranslationManager.Initialize(((BaseUnityPlugin)this).Info.Location); FontManager.Initialize(((BaseUnityPlugin)this).Info.Location); _harmony.PatchAll(typeof(TMPTextTranslationPatch).Assembly); InstallTMPComponentHooks(); InstallUGUITextHooks(); Log.LogInfo((object)"REPO JP Translation and Font Updated v4.1.0 を読み込みました。"); Log.LogInfo((object)$"翻訳エントリ: {TranslationManager.TranslationCount}件"); } private void InstallTMPComponentHooks() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(TMPComponentRefreshHook), "Postfix", (Type[])null, (Type[])null); Type[] obj = new Type[2] { typeof(TextMeshProUGUI), typeof(TextMeshPro) }; int num = 0; Type[] array = obj; foreach (Type type in array) { MethodInfo methodInfo2 = AccessTools.Method(type, "OnEnable", (Type[])null, (Type[])null); if (methodInfo2 != null) { _harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)("TMP表示対象をパッチしました: " + type.Name + ".OnEnable")); num++; } } Log.LogInfo((object)$"TMP表示パッチ数: {num}"); } private void InstallUGUITextHooks() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(UGUITextRefreshHook), "Postfix", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(UGUITextSetterHook), "Prefix", (Type[])null, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(typeof(Text), "OnEnable", (Type[])null, (Type[])null); MethodInfo methodInfo4 = AccessTools.PropertySetter(typeof(Text), "text"); int num = 0; if (methodInfo3 != null) { _harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)"UGUI表示対象をパッチしました: Text.OnEnable"); num++; } if (methodInfo4 != null) { _harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)"UGUI表示対象をパッチしました: Text.text"); num++; } Log.LogInfo((object)$"UGUI表示パッチ数: {num}"); } private void OnDestroy() { _harmony.UnpatchSelf(); } internal bool RefreshTextComponent(TMP_Text textComponent) { if (!FontManager.ShouldProcess(textComponent)) { return false; } if (!EnableTranslation.Value || string.IsNullOrEmpty(textComponent.text)) { return false; } string text = TranslationManager.Translate(textComponent.text); bool num = text != textComponent.text; if (num) { textComponent.text = text; } FontManager.AdjustTranslatedLayout(textComponent, text); return num; } internal bool RefreshTextComponent(Text textComponent) { if (!EnableTranslation.Value || string.IsNullOrEmpty(textComponent.text)) { return false; } string text = TranslationManager.Translate(textComponent.text); bool num = text != textComponent.text; if (num) { textComponent.text = text; } FontManager.AdjustTranslatedLayout(textComponent, text); return num; } } internal static class PluginInfo { public const string PLUGIN_GUID = "local.REPOJPTranslationAndFontUpdated"; public const string PLUGIN_NAME = "REPO JP Translation and Font Updated"; public const string PLUGIN_VERSION = "4.1.0"; } } namespace REPOJapaneseTranslation.Patches { [HarmonyPatch(typeof(ItemAttributes), "GetItemNameLocalized")] internal static class ItemAttributesLocalizedNamePatch { [HarmonyPostfix] private static void Postfix(ItemAttributes __instance, ref string __result) { string text = __result; string text2 = (((Object)(object)__instance != (Object)null && (Object)(object)__instance.item != (Object)null) ? __instance.item.itemName : null); if (string.IsNullOrWhiteSpace(text)) { text = text2; } if (!string.IsNullOrEmpty(text)) { string text3 = TranslationManager.Translate(text, logUntranslated: false); if (string.IsNullOrWhiteSpace(text3)) { text3 = text; } if (string.IsNullOrWhiteSpace(text3)) { text3 = text2; } __result = NormalizeItemName(text3); } } internal static string NormalizeItemName(string text) { if (string.IsNullOrEmpty(text)) { return text; } return text.Replace("\r\n", " ").Replace('\r', ' ').Replace('\n', ' ') .Trim(); } } [HarmonyPatch(typeof(StatsUI), "GetUpgradeDisplayName")] internal static class StatsUIUpgradeDisplayNamePatch { [HarmonyPostfix] private static void Postfix(ref string __result) { string text = __result; if (!string.IsNullOrWhiteSpace(text)) { string text2 = TranslationManager.Translate(text, logUntranslated: false); if (string.IsNullOrWhiteSpace(text2)) { text2 = text; } __result = ItemAttributesLocalizedNamePatch.NormalizeItemName(text2); } } } [HarmonyPatch(typeof(StatsUI), "Fetch")] internal static class StatsUIColumnLayoutPatch { [HarmonyPostfix] private static void Postfix(StatsUI __instance) { TextMeshProUGUI component = ((Component)__instance).GetComponent(); Transform val = ((Component)__instance).transform.Find("StatsNumbers"); TextMeshProUGUI val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if (!((Object)(object)component == (Object)null) && !((Object)(object)val2 == (Object)null)) { ((TMP_Text)val2).font = ((TMP_Text)component).font; ((TMP_Text)val2).fontSize = ((TMP_Text)component).fontSize; ((TMP_Text)val2).fontSizeMin = ((TMP_Text)component).fontSizeMin; ((TMP_Text)val2).fontSizeMax = ((TMP_Text)component).fontSizeMax; ((TMP_Text)val2).enableAutoSizing = false; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; ((TMP_Text)val2).lineSpacing = ((TMP_Text)component).lineSpacing; } } } [HarmonyPatch(typeof(ItemInfoUI), "ItemInfoText")] internal static class ItemInfoUITranslationPatch { [HarmonyPrefix] private static void Prefix(ref string message) { message = TranslationManager.Translate(message, logUntranslated: false); } } [HarmonyPatch(typeof(ItemInfoUI), "Update")] internal static class ItemInfoUIPositionPatch { [HarmonyPostfix] private static void Postfix(ItemInfoUI __instance) { //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) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)((SemiUI)__instance).textRectTransform == (Object)null)) { Vector3 localPosition = ((SemiUI)__instance).textRectTransform.localPosition; localPosition.y += 3f; ((SemiUI)__instance).textRectTransform.localPosition = localPosition; } } } [HarmonyPatch(typeof(ItemInfoExtraUI), "ItemInfoText")] internal static class ItemInfoExtraUITranslationPatch { [HarmonyPrefix] private static void Prefix(ref string message) { message = TranslationManager.Translate(message, logUntranslated: false); } } [HarmonyPatch(typeof(ArenaMessageUI), "ArenaText")] internal static class ArenaMessageUITranslationPatch { [HarmonyPrefix] private static void Prefix(ref string message) { message = TranslationManager.Translate(message, logUntranslated: false); } } [HarmonyPatch(typeof(ArenaMessageWinUI), "ArenaText")] internal static class ArenaMessageWinUITranslationPatch { [HarmonyPrefix] private static void Prefix(ref string message) { message = TranslationManager.Translate(message, logUntranslated: false); } } [HarmonyPatch(typeof(MenuButton), "Awake")] internal static class MenuButtonTranslationPatch { [HarmonyPrefix] private static void Prefix() { FontManager.SuppressTMPTranslation = true; } [HarmonyPostfix] private static void Postfix(MenuButton __instance) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown FontManager.SuppressTMPTranslation = false; if ((Object)__instance == (Object)null) { return; } TextMeshProUGUI componentInChildren = ((Component)__instance).GetComponentInChildren(); if (string.Equals(__instance.buttonTextString, "BUTTON", StringComparison.Ordinal)) { if (!((Object)componentInChildren == (Object)null) && string.Equals(((TMP_Text)componentInChildren).text, "BUTTON", StringComparison.Ordinal)) { ((TMP_Text)componentInChildren).text = string.Empty; } } else if (!string.IsNullOrEmpty(__instance.buttonTextString) && !((Object)componentInChildren == (Object)null)) { string text = TranslationManager.Translate(__instance.buttonTextString); ((TMP_Text)componentInChildren).text = text; } } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { FontManager.SuppressTMPTranslation = false; return __exception; } } [HarmonyPatch(typeof(MenuButton), "RegisterHover")] internal static class LobbyButtonRowAlignmentPatch { [HarmonyPrefix] private static void Prefix(MenuButton __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_00a2: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if ((Object)__instance == (Object)null) { return; } string text = TranslationManager.Translate(__instance.buttonTextString); string text2; if (text == "招待") { text2 = "カスタマイズ"; } else { if (text != "はじめる") { return; } text2 = "退室"; } MenuPage componentInParent = ((Component)__instance).GetComponentInParent(); if ((Object)componentInParent == (Object)null) { return; } MenuButton[] componentsInChildren = ((Component)componentInParent).GetComponentsInChildren(true); foreach (MenuButton val in componentsInChildren) { if ((Object)val != (Object)null && TranslationManager.Translate(val.buttonTextString) == text2) { RectTransform component = ((Component)__instance).GetComponent(); RectTransform component2 = ((Component)val).GetComponent(); Vector3 position = ((Transform)component).position; position.y = ((Transform)component2).position.y; ((Transform)component).position = position; break; } } } } [HarmonyPatch(typeof(MenuManager), "PageOpen", new Type[] { typeof(MenuPageIndex), typeof(bool) })] internal static class MenuPageOpenTranslationPatch { [HarmonyPostfix] private static void Postfix(MenuPage __result) { MenuPageTranslator.TranslatePage(__result); } } [HarmonyPatch(typeof(MenuPageSaves), "SaveFileSelected")] internal static class MenuPageSavesSaveFileSelectedPatch { [HarmonyPostfix] private static void Postfix(MenuPageSaves __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_0174: Expected O, but got Unknown if ((Object)__instance == (Object)null) { return; } string newValue = TranslationManager.Translate("Total Haul:", logUntranslated: false); string newValue2 = TranslationManager.Translate("Current Moon:", logUntranslated: false); TMP_Text[] componentsInChildren = ((Component)__instance).GetComponentsInChildren(true); foreach (TMP_Text val in componentsInChildren) { if (!((Object)val == (Object)null) && !string.IsNullOrEmpty(val.text) && FontManager.ShouldProcess(val)) { string text = val.text; string text2 = text.Replace("Total Haul:", newValue).Replace("Current Moon:", newValue2); if (text2 != text) { val.text = text2; } FontManager.AdjustTranslatedLayout(val, text2); } } if (!((Object)__instance.saveFileHeader != (Object)null)) { return; } TextMeshProUGUI saveFileHeader = __instance.saveFileHeader; ((TMP_Text)saveFileHeader).enableWordWrapping = false; ((TMP_Text)saveFileHeader).overflowMode = (TextOverflowModes)0; ((TMP_Text)saveFileHeader).maxVisibleCharacters = int.MaxValue; float targetWidth = ((TMP_Text)saveFileHeader).GetPreferredValues(((TMP_Text)saveFileHeader).text).x + 8f; ExpandKeepingLeft(((TMP_Text)saveFileHeader).rectTransform, targetWidth); if ((Object)__instance.saveFileRenameButton != (Object)null) { RectTransform component = __instance.saveFileRenameButton.GetComponent(); ExpandKeepingLeft(component, targetWidth); MenuButton component2 = __instance.saveFileRenameButton.GetComponent(); if ((Object)component2 != (Object)null && (Object)component2.rectTransformSelection != (Object)null && (Object)component2.rectTransformSelection != (Object)component) { ExpandKeepingLeft(component2.rectTransformSelection, targetWidth); } } ((TMP_Text)saveFileHeader).ForceMeshUpdate(true, true); } private static void ExpandKeepingLeft(RectTransform rectTransform, float targetWidth) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0027: 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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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)rectTransform == (Object)null)) { Rect rect = rectTransform.rect; if (!(targetWidth <= ((Rect)(ref rect)).width)) { rect = rectTransform.rect; float num = targetWidth - ((Rect)(ref rect)).width; Vector2 anchoredPosition = rectTransform.anchoredPosition; anchoredPosition.x += num * rectTransform.pivot.x; rectTransform.SetSizeWithCurrentAnchors((Axis)0, targetWidth); rectTransform.anchoredPosition = anchoredPosition; } } } } [HarmonyPatch(typeof(MenuPage), "Start")] internal static class MenuPageStartTranslationPatch { [HarmonyPostfix] private static void Postfix(MenuPage __instance) { MenuPageTranslator.TranslatePage(__instance); } } internal static class MenuPageTranslator { internal static void TranslatePage(MenuPage? menuPage) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown if (!((Object)menuPage == (Object)null)) { menuPage.menuHeaderName = TranslationManager.Translate(menuPage.menuHeaderName, logUntranslated: false); TMP_Text[] componentsInChildren = ((Component)menuPage).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { TranslateTextComponent(componentsInChildren[i]); } } } private static void TranslateTextComponent(TMP_Text text) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown if (!((Object)text == (Object)null) && !string.IsNullOrEmpty(text.text) && FontManager.ShouldProcess(text)) { string text2 = TranslationManager.Translate(text.text, logUntranslated: false); if (text2 != text.text) { text.text = text2; } FontManager.AdjustTranslatedLayout(text, text2); } } } [HarmonyPatch(typeof(MenuManager), "PagePopUp")] internal static class MenuPopUpTranslationPatch { [HarmonyPrefix] private static void Prefix(ref string headerText, ref string bodyText, ref string buttonText) { headerText = TranslationManager.Translate(headerText); bodyText = TranslationManager.Translate(bodyText); buttonText = TranslationManager.Translate(buttonText); } } [HarmonyPatch(typeof(MenuManager), "PagePopUpTwoOptions")] internal static class MenuTwoOptionPopUpTranslationPatch { [HarmonyPrefix] private static void Prefix(ref string popUpHeader, ref string popUpText, ref string option1Text, ref string option2Text) { popUpHeader = TranslationManager.Translate(popUpHeader); popUpText = TranslationManager.Translate(popUpText); option1Text = TranslationManager.Translate(option1Text); option2Text = TranslationManager.Translate(option2Text); } } internal static class SkipPromptInputTagResolver { internal static void Resolve(TMP_Text skipText) { if (!((Object)(object)skipText == (Object)null) && !((Object)(object)InputManager.instance == (Object)null) && !string.IsNullOrEmpty(skipText.text) && skipText.text.IndexOf("[menu]", StringComparison.OrdinalIgnoreCase) >= 0) { string text = InputManager.instance.InputDisplayReplaceTags(skipText.text, "", ""); if (!string.Equals(text, skipText.text, StringComparison.Ordinal)) { skipText.text = text; } } } } [HarmonyPatch(typeof(MoonUI), "StateStart")] internal static class MoonUISkipPromptInputTagPatch { [HarmonyPostfix] private static void Postfix(MoonUI __instance) { SkipPromptInputTagResolver.Resolve((TMP_Text)(object)__instance.skipText); } } [HarmonyPatch(typeof(ResultScreenUI), "StateFadeIn")] internal static class ResultScreenUISkipPromptInputTagPatch { [HarmonyPostfix] private static void Postfix(ResultScreenUI __instance) { SkipPromptInputTagResolver.Resolve((TMP_Text)(object)__instance.skipText); } } internal static class TMPComponentRefreshHook { private static bool s_loggedFirstComponent; internal static void Postfix(TMP_Text __instance) { if (!s_loggedFirstComponent) { s_loggedFirstComponent = true; Plugin.Log.LogInfo((object)("TMP表示コンポーネントを検出しました: " + ((object)__instance).GetType().Name)); } Plugin.Instance.RefreshTextComponent(__instance); } } [HarmonyPatch] internal static class TMPFontPatch { [HarmonyPatch(typeof(RunManager), "Awake")] [HarmonyPostfix] private static void ApplyFontAfterSceneLoad() { FontManager.ApplyToAllTextComponents(); } } [HarmonyPatch] internal static class TMPTextTranslationPatch { [HarmonyTargetMethods] private static IEnumerable TargetMethods() { MethodInfo methodInfo = AccessTools.PropertySetter(typeof(TMP_Text), "text"); if (methodInfo != null) { yield return methodInfo; } foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(typeof(TMP_Text))) { if (!(declaredMethod.Name != "SetText")) { ParameterInfo[] parameters = declaredMethod.GetParameters(); if (parameters.Length != 0 && !(parameters[0].ParameterType != typeof(string))) { yield return declaredMethod; } } } } [HarmonyPrefix] private static void TranslateText(TMP_Text __instance, ref string __0) { if (!FontManager.SuppressTMPTranslation && FontManager.ShouldProcess(__instance)) { __0 = TranslationManager.Translate(__0); __0 = FontManager.NormalizeTranslatedMarkup(__instance, __0); FontManager.AdjustTranslatedLayout(__instance, __0); } } } [HarmonyPatch(typeof(TruckScreenText), "UpdateTaxmanNickname")] internal static class TruckScreenTextUpdateTaxmanNicknamePatch { [HarmonyPrefix] private static void Prefix(ref string newName) { newName = TranslationManager.Translate(newName, logUntranslated: false); } } [HarmonyPatch(typeof(TuckScreenLocked), "LockChatToggle")] internal static class TuckScreenLockedLockChatTogglePatch { [HarmonyPrefix] private static void Prefix(ref string _lockedText) { _lockedText = TranslationManager.Translate(_lockedText, logUntranslated: false); } } internal static class UGUITextRefreshHook { private static bool s_loggedFirstComponent; internal static void Postfix(Text __instance) { if (!s_loggedFirstComponent) { s_loggedFirstComponent = true; Plugin.Log.LogInfo((object)"UGUI Textコンポーネントを検出しました。"); } Plugin.Instance.RefreshTextComponent(__instance); } } internal static class UGUITextSetterHook { internal static void Prefix(Text __instance, ref string __0) { __0 = TranslationManager.Translate(__0); FontManager.AdjustTranslatedLayout(__instance, __0); } } } namespace REPOJapaneseTranslation.Localization { internal static class FontManager { private readonly struct LayoutProfile { internal float Scale { get; } internal float MinimumScale { get; } internal bool AllowWrapping { get; } internal bool AutoSizing { get; } internal float AdditionalLineSpacing { get; } internal bool ConstrainToBounds { get; } internal float AbsoluteSize { get; } internal LayoutProfile(float scale, float minimumScale, bool allowWrapping, bool autoSizing = true, float additionalLineSpacing = 0f, bool constrainToBounds = false, float absoluteSize = 0f) { Scale = scale; MinimumScale = minimumScale; AllowWrapping = allowWrapping; AutoSizing = autoSizing; AdditionalLineSpacing = additionalLineSpacing; ConstrainToBounds = constrainToBounds; AbsoluteSize = absoluteSize; } } private readonly struct TMPFontState { private WeakReference Owner { get; } internal TMP_FontAsset Font { get; } internal float FontSize { get; } internal float FontSizeMin { get; } internal float FontSizeMax { get; } internal bool AutoSizing { get; } internal bool WordWrapping { get; } internal TextOverflowModes Overflow { get; } internal float LineSpacing { get; } internal TMPFontState(TMP_Text component) { //IL_0056: 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) Owner = new WeakReference(component); Font = component.font; FontSize = component.fontSize; FontSizeMin = component.fontSizeMin; FontSizeMax = component.fontSizeMax; AutoSizing = component.enableAutoSizing; WordWrapping = component.enableWordWrapping; Overflow = component.overflowMode; LineSpacing = component.lineSpacing; } internal bool Matches(TMP_Text component) { if (Owner.TryGetTarget(out TMP_Text target)) { return (Object)(object)target == (Object)(object)component; } return false; } internal void Restore(TMP_Text component) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) component.font = Font; component.fontSize = FontSize; component.fontSizeMin = FontSizeMin; component.fontSizeMax = FontSizeMax; component.enableAutoSizing = AutoSizing; component.enableWordWrapping = WordWrapping; component.overflowMode = Overflow; component.lineSpacing = LineSpacing; } } private readonly struct UGUIFontState { private WeakReference Owner { get; } internal Font Font { get; } internal int FontSize { get; } internal int MinSize { get; } internal int MaxSize { get; } internal bool BestFit { get; } internal HorizontalWrapMode Overflow { get; } internal UGUIFontState(Text component) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) Owner = new WeakReference(component); Font = component.font; FontSize = component.fontSize; MinSize = component.resizeTextMinSize; MaxSize = component.resizeTextMaxSize; BestFit = component.resizeTextForBestFit; Overflow = component.horizontalOverflow; } internal bool Matches(Text component) { if (Owner.TryGetTarget(out Text target)) { return (Object)(object)target == (Object)(object)component; } return false; } internal void Restore(Text component) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) component.font = Font; component.fontSize = FontSize; component.resizeTextMinSize = MinSize; component.resizeTextMaxSize = MaxSize; component.resizeTextForBestFit = BestFit; component.horizontalOverflow = Overflow; } } private const string FontResourceName = "REPOJapaneseTranslation.fonts.CP_Revenge.ttf"; private const string FontEnginePatchId = "local.REPOJPTranslationAndFontUpdated.FontEngine"; private static readonly Dictionary s_fontBytesByDummyFont = new Dictionary(); private static readonly Dictionary s_originalTMPStates = new Dictionary(); private static readonly Dictionary s_originalUGUIStates = new Dictionary(); private static readonly HashSet s_compactTitles = new HashSet(StringComparer.Ordinal) { "ゲームプレイ", "グラフィックス", "オーディオ", "コントロール", "パスワード", "ロビー", "メインメニュー", "警告", "自爆", "ランダム", "プリセット", "セーブをロード", "ゲームをホストする", "設定を初期化", "デフォルト設定にリセット" }; private static readonly HashSet s_dialogButtons = new HashSet(StringComparer.Ordinal) { "はい", "はい!", "いいえ", "いいえ…", "戻る", "続ける", "スキップ", "わかりました", "セーブをロード", "セーブを削除" }; private static readonly HashSet s_uniformMenuItems = new HashSet(StringComparer.Ordinal) { "プライベート", "パブリック", "プライベートゲーム", "パブリックゲーム", "フレンドに参加", "シングルプレイ", "シングルプレイモード", "チュートリアル", "続ける", "カスタマイズ", "変更", "設定", "はじめる", "閉じる", "自爆", "メインメニュー", "タイトルに戻る", "ゲームを終わる", "ゲームを終了する" }; private static readonly HashSet s_settingsRows = new HashSet(StringComparer.Ordinal) { "ヒント", "プレイヤー名", "光感受性", "光過敏症設定", "クモ恐怖症", "照準感度", "エイム感度", "カメラスムージング", "カメラの滑らかさ", "カメラシェイク", "カメラの揺れ", "シャドウ距離", "モーションブラー", "レンズ歪み", "ブルーム", "色収差", "グレイン", "グリッチループ", "ピクセル化", "すべての音量", "音楽音量", "BGM", "効果音", "効果音音量", "近接音声", "近接ボイス音量", "読み上げ", "マイク音量", "プッシュトゥトーク", "掴む", "回転", "押す", "引く", "ウィンドウモード", "垂直同期", "ガンマ", "最大FPS", "ライト距離", "シャドウ品質", "シャドウ距離", "マスター音量", "テキスト読み上げ音量", "オン", "オフ", "デフォルト", "フルスクリーン", "ウィンドウ", "ボーダーレス", "低", "中", "高", "最高" }; private static readonly HashSet s_extractionStatusLabels = new HashSet(StringComparer.Ordinal) { "アクティブ", "準備完了", "未準備", "回収中", "完了", "回収ポイントが起動した", "回収ポイント完了" }; private static readonly HashSet s_settingsNavigationItems = new HashSet(StringComparer.Ordinal) { "ゲームプレイ", "グラフィック", "グラフィックス", "音声", "オーディオ", "コントロール", "操作", "戻る" }; private static readonly HashSet s_settingsPageTitles = new HashSet(StringComparer.Ordinal) { "ゲームプレイ", "グラフィック", "グラフィックス", "音声", "オーディオ", "コントロール", "操作" }; private static readonly HashSet s_controlSectionTitles = new HashSet(StringComparer.Ordinal) { "移動", "掴み動作", "その他", "プレイヤー表情" }; private static readonly HashSet s_controlRows = new HashSet(StringComparer.Ordinal) { "前", "前進", "左", "後", "後退", "右", "右移動", "ジャンプ", "しゃがむ", "スプリント", "転がる", "掴み", "回転", "押す", "引く", "引っぱる", "インベントリ1", "インベントリ2", "インベントリ3", "マップ", "インタラクト", "チャット", "次の観戦", "前の観戦", "プッシュトゥトーク", "表情 - 目を閉じる", "表情 - 怪しむ", "表情 - 悲しみ", "表情 - 怒り", "表情 - クレイジー", "表情 - 幸せ" }; private static TMP_FontAsset? s_checkpointFont; private static Font? s_checkpointUnityFont; private static bool s_initialized; private static bool s_fontEnginePatched; internal static bool SuppressTMPTranslation { get; set; } internal static void Initialize(string pluginLocation) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown if (s_initialized) { return; } s_initialized = true; if (!Plugin.EnableJapaneseFont.Value) { return; } try { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("REPOJapaneseTranslation.fonts.CP_Revenge.ttf"); if (stream == null) { Plugin.Log.LogError((object)"埋め込みフォントが見つかりません: REPOJapaneseTranslation.fonts.CP_Revenge.ttf"); return; } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num == 0) { throw new EndOfStreamException("埋め込みフォントを最後まで読み取れませんでした。"); } } PatchFontEngine(); s_checkpointFont = CreateFontAsset(array); if ((Object)s_checkpointFont == (Object)null) { Plugin.Log.LogError((object)"チェックポイント★リベンジのTMPフォント生成に失敗しました。"); return; } ApplyToAllTextComponents(); Plugin.Log.LogInfo((object)$"チェックポイント★リベンジを読み込みました (埋め込み未改変TTF ({array.Length:N0} bytes))。"); } catch (Exception arg) { Plugin.Log.LogError((object)$"フォント初期化に失敗しました: {arg}"); } } internal static void ApplyToText(TMP_Text? textComponent) { if (ShouldProcess(textComponent) && ContainsJapanese(textComponent.text)) { AdjustTranslatedLayout(textComponent, textComponent.text); } } internal static bool ShouldProcess(TMP_Text? textComponent) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown if ((Object)textComponent == (Object)null) { return false; } if (IsPlayerNameText(textComponent)) { return false; } string text = GetHierarchyPath(textComponent.transform).ToLowerInvariant(); return !text.Contains("monitor") && !text.Contains("truckscreen") && (!text.Contains("truck") || !text.Contains("screen")); } private static bool IsPlayerNameText(TMP_Text component) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_002b: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_005a: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_0089: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown //IL_00cd: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //IL_00ff: Expected O, but got Unknown MenuPlayerListed componentInParent = ((Component)component).GetComponentInParent(); if ((Object)componentInParent != (Object)null && (Object)componentInParent.playerName == (Object)component) { return true; } WorldSpaceUIPlayerName componentInParent2 = ((Component)component).GetComponentInParent(); if ((Object)componentInParent2 != (Object)null && (Object)componentInParent2.text == (Object)component) { return true; } LobbyChatUI componentInParent3 = ((Component)component).GetComponentInParent(); if ((Object)componentInParent3 != (Object)null && (Object)componentInParent3.spectateName == (Object)component) { return true; } if ((Object)((Component)component).GetComponentInParent() != (Object)null) { return true; } PlayerListDisplay componentInParent4 = ((Component)component).GetComponentInParent(); if ((Object)componentInParent4 != (Object)null && (Object)componentInParent4.playerListText == (Object)component) { return true; } MenuPageSaves componentInParent5 = ((Component)component).GetComponentInParent(); if ((Object)componentInParent5 != (Object)null) { return (Object)componentInParent5.saveFileInfoRow3 == (Object)component; } return false; } internal static void ApplyToText(Text? textComponent) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown if ((Object)textComponent != (Object)null && ContainsJapanese(textComponent.text)) { AdjustTranslatedLayout(textComponent, textComponent.text); } } internal static void ApplyToAllTextComponents() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown if ((Object)s_checkpointFont == (Object)null) { return; } TMP_Text[] array = Object.FindObjectsOfType(true); TMP_Text[] array2 = array; foreach (TMP_Text textComponent in array2) { if (ShouldProcess(textComponent)) { ApplyToText(textComponent); } } Plugin.Log.LogDebug((object)$"{array.Length}個のTMPテキストを確認しました。"); } internal static void AdjustTranslatedLayout(TMP_Text textComponent, string translatedText) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (!Plugin.EnableJapaneseFont.Value || (Object)s_checkpointFont == (Object)null || !ShouldProcess(textComponent)) { return; } int instanceID = ((Object)textComponent).GetInstanceID(); if (!s_originalTMPStates.TryGetValue(instanceID, out var value) || !value.Matches(textComponent)) { value = new TMPFontState(textComponent); s_originalTMPStates[instanceID] = value; } if (!ContainsJapanese(translatedText)) { value.Restore(textComponent); if (IsSettingsHierarchy(GetHierarchyPath(textComponent.transform)) && ContainsDigit(translatedText)) { ApplyOriginalFontScale(textComponent, value, 0.78f); } return; } LayoutProfile layoutProfile = ResolveProfile(textComponent, translatedText); textComponent.font = s_checkpointFont; textComponent.enableAutoSizing = layoutProfile.AutoSizing; float val = ((layoutProfile.AbsoluteSize > 0f) ? layoutProfile.AbsoluteSize : (value.FontSize * layoutProfile.Scale)); float val2 = ((layoutProfile.AbsoluteSize > 0f) ? layoutProfile.AbsoluteSize : (value.FontSizeMax * layoutProfile.Scale)); float val3 = ((layoutProfile.AbsoluteSize > 0f) ? (layoutProfile.AbsoluteSize * layoutProfile.MinimumScale) : (value.FontSizeMax * layoutProfile.MinimumScale)); textComponent.fontSize = Math.Max(1f, val); textComponent.fontSizeMax = Math.Max(1f, val2); textComponent.fontSizeMin = Math.Max(1f, val3); textComponent.enableWordWrapping = layoutProfile.AllowWrapping; textComponent.overflowMode = (TextOverflowModes)layoutProfile.ConstrainToBounds; textComponent.lineSpacing = value.LineSpacing + layoutProfile.AdditionalLineSpacing; } internal static void AdjustTranslatedLayout(Text textComponent, string translatedText) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (Plugin.EnableJapaneseFont.Value && !((Object)s_checkpointUnityFont == (Object)null) && !((Object)textComponent == (Object)null)) { int instanceID = ((Object)textComponent).GetInstanceID(); if (!s_originalUGUIStates.TryGetValue(instanceID, out var value) || !value.Matches(textComponent)) { value = new UGUIFontState(textComponent); s_originalUGUIStates[instanceID] = value; } if (!ContainsJapanese(translatedText)) { value.Restore(textComponent); return; } float num = ResolveUGUIScale(translatedText); textComponent.font = s_checkpointUnityFont; textComponent.fontSize = Math.Max(1, (int)Math.Round((float)value.FontSize * num)); textComponent.resizeTextForBestFit = true; textComponent.resizeTextMinSize = Math.Max(1, (int)Math.Round((float)value.MaxSize * 0.28f)); textComponent.resizeTextMaxSize = Math.Max(1, (int)Math.Round((float)value.MaxSize * num)); textComponent.horizontalOverflow = (HorizontalWrapMode)(!translatedText.Contains('\n')); } } private static LayoutProfile ResolveProfile(TMP_Text component, string text) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_004d: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_009c: Expected O, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_00e9: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Expected O, but got Unknown //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown //IL_0136: Expected O, but got Unknown //IL_0173: 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_0183: Expected O, but got Unknown //IL_0183: Expected O, but got Unknown string text2 = RemoveSimpleRichText(text).Trim(); string text3 = GetHierarchyPath(component.transform).ToLowerInvariant(); ItemInfoUI componentInParent = ((Component)component).GetComponentInParent(); if ((Object)componentInParent != (Object)null && (Object)component.transform == (Object)((Component)componentInParent).transform) { return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 15f); } StatsUI componentInParent2 = ((Component)component).GetComponentInParent(); if ((Object)componentInParent2 != (Object)null && (Object)component.transform == (Object)((Component)componentInParent2).transform) { return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 20f); } MoonAttributeUI componentInParent3 = ((Component)component).GetComponentInParent(); if ((Object)componentInParent3 != (Object)null && (Object)componentInParent3.text == (Object)component) { return new LayoutProfile(1f, 0.45f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: false, 10f); } MenuElementMoonAttribute componentInParent4 = ((Component)component).GetComponentInParent(); if ((Object)componentInParent4 != (Object)null && (Object)componentInParent4.text == (Object)component) { return new LayoutProfile(1f, 0.45f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 10f); } ExtractionPoint componentInParent5 = ((Component)component).GetComponentInParent(); if ((Object)componentInParent5 != (Object)null && (Object)componentInParent5.tubeScreenText == (Object)component) { return new LayoutProfile(0.55f, 0.42f, allowWrapping: false, autoSizing: false); } if (text2 == "モード: 強" || text2 == "モード: 弱") { return new LayoutProfile(1f, 0.78f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 10f); } if (IsExtractionHierarchy(text3) && s_extractionStatusLabels.Contains(text2)) { return new LayoutProfile(0.36f, 0.28f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true); } bool flag = IsSettingsHierarchy(text3); bool flag2 = IsLeftSideOfScreen(component); bool flag3 = text3.Contains("lobby"); bool flag4 = IsLowerHalfOfScreen(component); if (s_settingsNavigationItems.Contains(text2) && flag2 && (flag || text2 == "操作")) { return new LayoutProfile(1f, 0.78f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 15f); } if (s_settingsPageTitles.Contains(text2) && flag && !flag2) { return new LayoutProfile(1f, 0.78f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 15f); } if (text2 == "設定" && !flag3 && flag4) { return new LayoutProfile(1f, 0.78f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 18f); } if (text2 == "設定" && flag && !flag3) { return new LayoutProfile(1f, 0.78f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 14f); } if (text2 == "デフォルト設定にリセット" && flag) { return new LayoutProfile(1f, 0.78f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 15f); } if (flag3 && text2 == "Tを押してチャット") { return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 8f); } if (text2 == "地域") { return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 18f); } if (text2 == "最適な地域を選択する") { return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 11f); } if (flag3) { switch (text2) { case "カスタマイズ": case "退室": case "設定": case "招待": case "はじめる": return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 18f); } } if (IsFocusMissionHudText(text3, text2)) { return new LayoutProfile(1f, 0.78f, allowWrapping: true, autoSizing: false, 2f, constrainToBounds: false, 10f); } switch (text2) { case "パスワード": return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 24f); case "ロビー": return new LayoutProfile(0.46f, 0.23f, allowWrapping: false); case "セーブをロード": return new LayoutProfile(0.52f, 0.26f, allowWrapping: false); case "光敏感性発作についての警告": case "光過敏症の警告": return new LayoutProfile(0.62f, 0.52f, allowWrapping: true, autoSizing: false, 12f); case "サーバー一覧": return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 15f); default: if (text2.StartsWith("このゲームには点滅する光が含まれています。", StringComparison.Ordinal) || text2.StartsWith("<このゲームには光の点滅表現が含まれています>", StringComparison.Ordinal)) { return new LayoutProfile(0.65f, 0.54f, allowWrapping: true, autoSizing: false, 14f); } if (text2.StartsWith("一部の方は、光のパターンや点滅する光", StringComparison.Ordinal) || text2.StartsWith("一部の人は光や点滅や模様に晒されると", StringComparison.Ordinal)) { return new LayoutProfile(0.58f, 0.46f, allowWrapping: true, autoSizing: false, 24f); } if (text2 == "メニュー") { return new LayoutProfile(0.4f, 0.28f, allowWrapping: false); } if (s_uniformMenuItems.Contains(text2)) { return new LayoutProfile(1f, 0.78f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 20f); } if (text2.StartsWith("総回収額:", StringComparison.Ordinal) || text2.StartsWith("現在の月:", StringComparison.Ordinal)) { return new LayoutProfile(0.68f, 0.48f, allowWrapping: false); } switch (text2) { case "(クリックして名前変更)": return new LayoutProfile(0.52f, 0.36f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true); case "シングルプレイモード": return new LayoutProfile(0.44f, 0.3f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true); case "ウィンドウモード": return new LayoutProfile(0.23f, 0.16f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true); case "モーションブラー": return new LayoutProfile(0.24f, 0.16f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true); case "カメラの滑らかさ": case "カメラスムージング": return new LayoutProfile(0.22f, 0.15f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true); case "カメラアニメーション": case "カメラの動き": return new LayoutProfile(0.22f, 0.15f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true); case "アンチエイリアシング": return new LayoutProfile(0.22f, 0.15f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true); case "リッチプレゼンス": return new LayoutProfile(0.22f, 0.15f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true); case "アイテム自動装備": return new LayoutProfile(0.22f, 0.15f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true); case "オフ": case "オン": return new LayoutProfile(0.48f, 0.34f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true); default: { if (s_controlSectionTitles.Contains(text2)) { return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 14f); } if (s_settingsRows.Contains(text2) || s_controlRows.Contains(text2)) { return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true, 10f); } if (IsControlHierarchy(text3)) { return new LayoutProfile(1f, 0.58f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true, 10f); } if (text2 == "プリセット") { return new LayoutProfile(0.82f, 0.58f, allowWrapping: false); } if (text2 == "確認") { return new LayoutProfile(0.95f, 0.66f, allowWrapping: false); } if (text2.StartsWith("マイク", StringComparison.Ordinal)) { return new LayoutProfile(1f, 0.5f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true, 9f); } if (s_dialogButtons.Contains(text2)) { return new LayoutProfile(0.58f, 0.3f, allowWrapping: false); } if (s_compactTitles.Contains(text2)) { return new LayoutProfile(0.52f, 0.25f, allowWrapping: false); } bool flag5 = text3.Contains("popup") || text3.Contains("dialog") || text3.Contains("confirm") || text3.Contains("warning"); bool flag6 = flag; bool num = text3.Contains("password"); bool flag7 = text3.Contains("lobby"); bool flag8 = text3.Contains("save"); if (num) { return new LayoutProfile(0.5f, 0.24f, text.Contains('\n')); } if (flag7) { return new LayoutProfile(0.5f, 0.24f, text.Contains('\n')); } if (flag8) { return new LayoutProfile(0.62f, 0.34f, text.Length > 18 || text.Contains('\n')); } if (flag6) { return new LayoutProfile(0.24f, 0.14f, text.Length > 20 || text.Contains('\n'), autoSizing: true, 0f, constrainToBounds: true); } if (flag5) { return new LayoutProfile(0.45f, 0.2f, allowWrapping: true, autoSizing: true, 0f, constrainToBounds: true); } if (text.Contains('\n') || text2.Length >= 18) { return new LayoutProfile(0.46f, 0.2f, allowWrapping: true, autoSizing: true, 0f, constrainToBounds: true); } return new LayoutProfile(Plugin.FontSizeScale.Value, 0.28f, allowWrapping: false); } } } } private static float ResolveUGUIScale(string text) { string text2 = RemoveSimpleRichText(text).Trim(); if (s_dialogButtons.Contains(text2)) { return 0.58f; } if (s_settingsRows.Contains(text2)) { return 0.47f; } if (s_compactTitles.Contains(text2)) { return 0.52f; } if (text2.Length < 18 && !text.Contains('\n')) { return Plugin.FontSizeScale.Value; } return 0.46f; } private static bool ContainsJapanese(string? text) { if (string.IsNullOrEmpty(text)) { return false; } foreach (char c in text) { if ((c >= '\u3040' && c <= 'ヿ') || (c >= '㐀' && c <= '鿿') || (c >= '豈' && c <= '\ufaff') || (c >= 'ヲ' && c <= '゚')) { return true; } } return false; } private static bool ContainsDigit(string? text) { if (string.IsNullOrEmpty(text)) { return false; } for (int i = 0; i < text.Length; i++) { if (char.IsDigit(text[i])) { return true; } } return false; } private static bool IsSettingsHierarchy(string hierarchy) { string text = hierarchy.ToLowerInvariant(); if (!text.Contains("setting") && !text.Contains("graphic") && !text.Contains("audio") && !text.Contains("control")) { return text.Contains("gameplay"); } return true; } private static bool IsControlHierarchy(string hierarchy) { string text = hierarchy.ToLowerInvariant(); if (!text.Contains("control") && !text.Contains("keybind")) { return text.Contains("input"); } return true; } private static bool IsExtractionHierarchy(string hierarchy) { string text = hierarchy.ToLowerInvariant(); if (!text.Contains("extraction") && !text.Contains("extractpoint")) { return text.Contains("extractionpoint"); } return true; } private static bool IsLeftSideOfScreen(TMP_Text component) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (Screen.width <= 0) { return false; } Canvas componentInParent = ((Component)component).GetComponentInParent(); return RectTransformUtility.WorldToScreenPoint(((Object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null, ((Transform)component.rectTransform).position).x <= (float)Screen.width * 0.48f; } private static bool IsLowerHalfOfScreen(TMP_Text component) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (Screen.height <= 0) { return false; } Canvas componentInParent = ((Component)component).GetComponentInParent(); return RectTransformUtility.WorldToScreenPoint(((Object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null, ((Transform)component.rectTransform).position).y <= (float)Screen.height * 0.5f; } internal static string NormalizeTranslatedMarkup(TMP_Text component, string text) { string hierarchy = GetHierarchyPath(component.transform).ToLowerInvariant(); string text2 = RemoveSimpleRichText(text).Trim(); if (text2 == "パスワード") { return "パスワード"; } if (text2 == "サーバー一覧") { return "サーバー一覧"; } if (s_controlSectionTitles.Contains(text2)) { return text2; } if (!ShouldProcess(component) || !IsFocusMissionHudText(hierarchy, text2)) { return text; } return RemoveSizeTags(text); } private static bool IsFocusMissionHudText(string hierarchy, string text) { if (hierarchy.Contains("uifocustext") || hierarchy.Contains("localizedfocustext") || hierarchy.Contains("focustext")) { return true; } if (!text.StartsWith("FOCUS >", StringComparison.OrdinalIgnoreCase) && !text.StartsWith("FOCUS>", StringComparison.OrdinalIgnoreCase) && !text.StartsWith("目標 >", StringComparison.Ordinal) && !text.StartsWith("目標>", StringComparison.Ordinal) && !text.StartsWith("ミッション >", StringComparison.Ordinal) && !text.StartsWith("ミッション>", StringComparison.Ordinal) && !text.StartsWith("注目 >", StringComparison.Ordinal)) { return text.StartsWith("注目>", StringComparison.Ordinal); } return true; } private static string RemoveSizeTags(string text) { StringBuilder stringBuilder = new StringBuilder(text.Length); for (int i = 0; i < text.Length; i++) { if (text[i] == '<' && (text.AsSpan(i).StartsWith("", StringComparison.OrdinalIgnoreCase))) { int num = text.IndexOf('>', i); if (num >= 0) { i = num; continue; } } stringBuilder.Append(text[i]); } return stringBuilder.ToString(); } private static void ApplyOriginalFontScale(TMP_Text component, TMPFontState original, float scale) { component.enableAutoSizing = false; component.fontSize = Math.Max(1f, original.FontSize * scale); component.fontSizeMax = Math.Max(1f, original.FontSizeMax * scale); component.fontSizeMin = Math.Max(1f, original.FontSizeMax * scale * 0.65f); component.overflowMode = (TextOverflowModes)0; } private static string GetHierarchyPath(Transform? transform) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown if ((Object)transform == (Object)null) { return string.Empty; } string text = ((Object)transform).name; Transform parent = transform.parent; int num = 0; while ((Object)parent != (Object)null && num++ < 12) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private static string RemoveSimpleRichText(string text) { StringBuilder stringBuilder = new StringBuilder(text.Length); bool flag = false; foreach (char c in text) { if (c == '<') { flag = true; } else if (c == '>' && flag) { flag = false; } else if (!flag) { stringBuilder.Append(c); } } return stringBuilder.ToString(); } private static TMP_FontAsset? CreateFontAsset(byte[] fontBytes) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_003d: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00af: 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_007b: Expected O, but got Unknown FontEngine.InitializeFontEngine(); FontEngineError val = FontEngine.LoadFontFace(fontBytes); if ((int)val != 0) { Plugin.Log.LogError((object)$"TTFの検証に失敗しました: {val}"); return null; } Font val2 = new Font("CP_Revenge"); s_checkpointUnityFont = val2; Font val3 = val2; s_fontBytesByDummyFont[val3] = fontBytes; TMP_FontAsset val4 = TMP_FontAsset.CreateFontAsset(val3); if ((Object)val4 == (Object)null) { s_fontBytesByDummyFont.Remove(val3); s_checkpointUnityFont = null; Object.Destroy((Object)val3); return null; } ((Object)val4).name = "Checkpoint Revenge Dynamic"; val4.atlasPopulationMode = (AtlasPopulationMode)1; FaceInfo faceInfo = val4.faceInfo; ((FaceInfo)(ref faceInfo)).lineHeight = ((FaceInfo)(ref faceInfo)).lineHeight * Plugin.FontLineHeightScale.Value; val4.faceInfo = faceInfo; ConfigureTextMeshProMaterial(val4); return val4; } private static void ConfigureTextMeshProMaterial(TMP_FontAsset fontAsset) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) Shader val = Shader.Find("TextMeshPro/Distance Field"); if ((Object)val == (Object)null) { Plugin.Log.LogWarning((object)"TextMeshPro/Distance Fieldシェーダーが見つかりません。"); return; } Material material = ((TMP_Asset)fontAsset).material; material.shader = val; if (material.HasProperty("_GlowColor")) { material.SetColor("_GlowColor", Color.clear); } if (material.HasProperty("_GlowPower")) { material.SetFloat("_GlowPower", 0f); } } private static void PatchFontEngine() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown if (!s_fontEnginePatched) { MethodInfo method = typeof(FontEngine).GetMethod("LoadFontFace", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { typeof(Font), typeof(int) }, null); MethodInfo method2 = typeof(FontManager).GetMethod("LoadFontFacePrefix", BindingFlags.Static | BindingFlags.NonPublic); if (method == null || method2 == null) { throw new MissingMethodException("FontEngine.LoadFontFace(Font, int) が見つかりません。"); } new Harmony("local.REPOJPTranslationAndFontUpdated.FontEngine").Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); s_fontEnginePatched = true; } } private static bool LoadFontFacePrefix(Font font, int pointSize, ref FontEngineError __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected I4, but got Unknown if ((Object)font == (Object)null || !s_fontBytesByDummyFont.TryGetValue(font, out byte[] value)) { return true; } __result = (FontEngineError)(int)FontEngine.LoadFontFace(value, pointSize); return false; } } internal static class TranslationManager { private sealed class TranslationTemplate { private readonly Regex _pattern; private readonly string _translatedTemplate; private readonly string[] _placeholderTokens; internal int SourceLength { get; } private TranslationTemplate(Regex pattern, string translatedTemplate, string[] placeholderTokens, int sourceLength) { _pattern = pattern; _translatedTemplate = translatedTemplate; _placeholderTokens = placeholderTokens; SourceLength = sourceLength; } internal static TranslationTemplate Create(string sourceTemplate, string translatedTemplate) { MatchCollection matchCollection = s_placeholderTokenRegex.Matches(sourceTemplate); StringBuilder stringBuilder = new StringBuilder(); string[] array = new string[matchCollection.Count]; stringBuilder.Append('^'); int num = 0; int num2; for (int i = 0; i < matchCollection.Count; i++) { Match match = matchCollection[i]; num2 = num; stringBuilder.Append(Regex.Escape(sourceTemplate.Substring(num2, match.Index - num2))); stringBuilder.Append($"(?.+?)"); array[i] = match.Value; num = match.Index + match.Length; } num2 = num; stringBuilder.Append(Regex.Escape(sourceTemplate.Substring(num2, sourceTemplate.Length - num2))); stringBuilder.Append('$'); return new TranslationTemplate(new Regex(stringBuilder.ToString(), RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant), translatedTemplate, array, sourceTemplate.Length); } internal bool TryTranslate(string text, out string result) { Match match = _pattern.Match(text); if (!match.Success) { result = text; return false; } Dictionary dictionary = new Dictionary(StringComparer.Ordinal); for (int i = 0; i < _placeholderTokens.Length; i++) { string key = _placeholderTokens[i]; if (!dictionary.ContainsKey(key)) { dictionary[key] = match.Groups[$"p{i}"].Value; } } result = _translatedTemplate; foreach (KeyValuePair item in dictionary) { item.Deconstruct(out var key2, out var value); string oldValue = key2; string newValue = value; result = result.Replace(oldValue, newValue, StringComparison.Ordinal); } return true; } } private static readonly string[] s_originalTranslationResources = new string[4] { "REPOJapaneseTranslation.original.TranslationJP_Main.txt", "REPOJapaneseTranslation.original.TranslationJP_MOD.txt", "REPOJapaneseTranslation.original.TranslationJP_Other.txt", "REPOJapaneseTranslation.original.TranslationJP_Upgrade.txt" }; private static readonly Regex s_placeholderTokenRegex = new Regex("\\{[^{}]+\\}|\\[[^\\[\\]]+\\]", RegexOptions.Compiled | RegexOptions.CultureInvariant); private static readonly Regex s_actionSuffixRegex = new Regex("^(?.+?)(?\\s*(?:<[^>]+>)*\\[[^\\[\\]]+\\](?:]+>)*\\s*)$", RegexOptions.Compiled | RegexOptions.CultureInvariant); private static readonly Regex s_richTextSuffixRegex = new Regex("^(?.+?)(?\\s*(?:<[^>]+>)+\\s*)$", RegexOptions.Compiled | RegexOptions.CultureInvariant); private static readonly Regex s_labeledPrefixRegex = new Regex("^(?(?:<[^>]+>)*)(?