Decompiled source of Auto Translate v1.1.6
AutoTranslate.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using ETGGUI; using HarmonyLib; using Mono.Cecil.Cil; using MonoMod.Cil; using Newtonsoft.Json; using SGUI; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("AutoTranslate")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("AutoTranslate")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("825bc8e2-2faf-496c-803c-3f3e31eba1a0")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace AutoTranslate; internal class AssetBundleLoader { public static AssetBundle LoadAssetBundle(string filePath) { AssetBundle result = null; if (File.Exists(filePath)) { try { result = AssetBundle.LoadFromFile(filePath); Debug.Log((object)"已成功加载AssetBundle!Successfully loaded AssetBundle!"); } catch (Exception ex) { Debug.LogError((object)"从文件加载AssetBundle失败。Failed loading AssetBundle from file."); Debug.LogError((object)ex.ToString()); } } else { Debug.LogError((object)"AssetBundle不存在!AssetBundle does not exist!"); } return result; } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("kleirof.etg.autotranslate", "Auto Translate", "1.1.6")] public class AutoTranslateModule : BaseUnityPlugin { public enum FilterForFullTextNeedToTranslateType { Chinese, CustomRegex } public enum FilterForEachLineNeedToTranslateType { Chinese, CustomRegex } public enum FilterForIgnoredSubstringWithinTextType { Chinese, CustomRegex } public enum TranslationAPIType { Tencent, Baidu, Azure, Llm } public enum OverrideFontType { None, Chinese, English, Japanese, Korean, Russian, Polish, Custom } public enum OverrideDfTokenizerType { None, Chinese, CustomRegex } public enum OverrideItemTipsTokenizerType { Chinese, CustomRegex } public enum LlmQuotePreprocessType { None, Chinese } public enum LlmDataFormatType { Json, Split, Positioned, Parallel } public const string GUID = "kleirof.etg.autotranslate"; public const string NAME = "Auto Translate"; public const string VERSION = "1.1.6"; public const string TEXT_COLOR = "#AA3399"; internal static AutoTranslateModule instance; private ConfigEntry<bool> AcceptedModDeclaration; private ConfigEntry<TranslationAPIType> TranslationAPI; private ConfigEntry<KeyCode> ToggleTranslationKeyBinding; private ConfigEntry<FilterForFullTextNeedToTranslateType> FilterForFullTextNeedToTranslate; private ConfigEntry<string> RegexForFullTextNeedToTranslate; private ConfigEntry<FilterForEachLineNeedToTranslateType> FilterForEachLineNeedToTranslate; private ConfigEntry<string> RegexForEachLineNeedToTranslate; private ConfigEntry<FilterForIgnoredSubstringWithinTextType> FilterForIgnoredSubstringWithinText; private ConfigEntry<string> RegexForIgnoredSubstringWithinText; private ConfigEntry<int> MaxBatchCharacterCount; private ConfigEntry<int> MaxBatchTextCount; private ConfigEntry<int> MaxRetryCount; private ConfigEntry<float> RetryInterval; private ConfigEntry<int> TranslationCacheCapacity; private ConfigEntry<string> PresetTranslations; private ConfigEntry<string> CachedTranslations; private ConfigEntry<bool> AutoSaveCachedTranslationsUponQuit; private ConfigEntry<bool> LogRequestedTexts; private ConfigEntry<OverrideFontType> OverrideFont; private ConfigEntry<string> FontAssetBundleName; private ConfigEntry<string> CustomDfFontName; private ConfigEntry<string> CustomTk2dFontName; private ConfigEntry<string> RegexForDfTokenizer; private ConfigEntry<OverrideDfTokenizerType> OverrideDfTokenizer; private ConfigEntry<float> DfTextScaleExpandThreshold; private ConfigEntry<float> DfTextScaleExpandToValue; private ConfigEntry<bool> ShowRequestedCharacterCount; private ConfigEntry<int> RequestedCharacterCountAlertThreshold; private ConfigEntry<KeyCode> ToggleRequestedCharacterCountKeyBinding; private ConfigEntry<string> CountLabelAnchor; private ConfigEntry<string> CountLabelPivot; private ConfigEntry<bool> TranslateTextsOfItemTipsMod; private ConfigEntry<OverrideItemTipsTokenizerType> OverrideItemTipsTokenizer; private ConfigEntry<string> RegexForItemTipsModTokenizer; private ConfigEntry<float> ItemTipsFontScale; private ConfigEntry<float> ItemTipsBackgroundWidthScale; private ConfigEntry<float> ItemTipsLineHeightScale; private ConfigEntry<string> ItemTipsAnchor; private ConfigEntry<string> ItemTipsPivot; private ConfigEntry<int> ItemTipsSourceBitmapFontBaseLine; private ConfigEntry<string> TencentSecretId; private ConfigEntry<string> TencentSecretKey; private ConfigEntry<string> TencentSourceLanguage; private ConfigEntry<string> TencentTargetLanguage; private ConfigEntry<string> TencentRegion; private ConfigEntry<string> BaiduAppId; private ConfigEntry<string> BaiduSecretKey; private ConfigEntry<string> BaiduSourceLanguage; private ConfigEntry<string> BaiduTargetLanguage; private ConfigEntry<string> AzureSubscriptionKey; private ConfigEntry<string> AzureSourceLanguage; private ConfigEntry<string> AzureTargetLanguage; private ConfigEntry<string> AzureRegion; private ConfigEntry<string> LlmBaseUrl; private ConfigEntry<string> LlmApiKey; private ConfigEntry<string> LlmName; private ConfigEntry<string> LlmPrompt; private ConfigEntry<int> LlmMaxTokens; private ConfigEntry<float> LlmTemperature; private ConfigEntry<float> LlmTopP; private ConfigEntry<int> LlmTopK; private ConfigEntry<float> LlmFrequencyPenalty; private ConfigEntry<string> LlmExtraParametersJson; private ConfigEntry<LlmQuotePreprocessType> LlmQuotePreprocess; private ConfigEntry<LlmDataFormatType> LlmDataFormat; private ConfigEntry<string> LlmSplitText; private ConfigEntry<string> LlmPositionText; private ConfigEntry<string> LlmSegmentText; private Harmony harmony; private GameObject autoTranslateObject; internal TranslationManager translateManager; internal FontManager fontManager; internal AutoTranslateConfig config; internal StatusLabelController statusLabel; private readonly string errorColor = "#FF0000"; public void Start() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown ETGModMainBehaviour.WaitForGameManagerStart((Action<GameManager>)GMStart); instance = this; config = InitializeConfigs(); if (!AcceptedModDeclaration.Value) { Debug.LogError((object)"AutoTranslate: 还未接受Mod声明!Mod declaration not accepted!"); return; } if (!config.isConfigValid) { Debug.LogError((object)"AutoTranslate: 翻译配置无效!Invalid Translate Config!"); } fontManager = new FontManager(); harmony = new Harmony("kleirof.etg.autotranslate"); harmony.PatchAll(); autoTranslateObject = new GameObject("Auto Translate Object"); Object.DontDestroyOnLoad((Object)(object)autoTranslateObject); translateManager = autoTranslateObject.AddComponent<TranslationManager>(); translateManager.Initialize(); DoOptionalPatches(); statusLabel = new StatusLabelController(); } internal static void Log(string text, string color = "FFFFFF") { ETGModConsole.Log((object)("<color=" + color + ">" + text + "</color>"), false); } internal void GMStart(GameManager g) { if (!AcceptedModDeclaration.Value) { Log("Auto Translate v1.1.6 started, but AcceptedModDeclaration not checked!", errorColor); Log("(Important!) Please read the declaration on mod website and then check the config in mod manager or manually edit it.", errorColor); return; } if (!config.isConfigValid) { Log("Auto Translate v1.1.6 started, but config is invalid!", errorColor); Log("Please check the config in mod manager or manually edit it.", errorColor); return; } Log("Auto Translate v1.1.6 started successfully.", "#AA3399"); Log($" Translate Api: {config.TranslationAPI}", "#AA3399"); fontManager?.InitializeFontAfterGameManager(OverrideFont.Value); statusLabel?.InitializeStatusLabel(); ETGModConsole.Commands.AddGroup("autotranslate", (Action<string[]>)LogHelp); ETGModConsole.Commands.GetGroup("autotranslate").AddUnit("help", (Action<string[]>)LogHelp); ETGModConsole.Commands.GetGroup("autotranslate").AddUnit("save_cache", (Action<string[]>)SaveCache); ETGModConsole.Commands.GetGroup("autotranslate").AddUnit("load_cache", (Action<string[]>)LoadCache); } private AutoTranslateConfig InitializeConfigs() { //IL_09ab: Unknown result type (might be due to invalid IL or missing references) //IL_09b0: Unknown result type (might be due to invalid IL or missing references) //IL_0b7e: Unknown result type (might be due to invalid IL or missing references) //IL_0b83: Unknown result type (might be due to invalid IL or missing references) AcceptedModDeclaration = ((BaseUnityPlugin)this).Config.Bind<bool>("1.General", "AcceptedModDeclaration", false, "作为Mod用户,我已阅读并同意网站上此mod的声明,清楚潜在费用的去向并信任此mod的行为,并对自己的选择负责任。As a mod user, I have read and accepted the declaration on this mod's website, understand the potential destination of the fees, trust the actions of this mod, and take responsibility for my choice."); TranslationAPI = ((BaseUnityPlugin)this).Config.Bind<TranslationAPIType>("1.General", "TranslationAPI", TranslationAPIType.Tencent, "选择使用的翻译API。Choose the translation API to use."); ToggleTranslationKeyBinding = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("1.General", "ToggleTranslationKeyBinding", (KeyCode)291, "启用或关闭翻译的按键。The key binding of toggling translation."); FilterForFullTextNeedToTranslate = ((BaseUnityPlugin)this).Config.Bind<FilterForFullTextNeedToTranslateType>("1.General", "FilterForFullTextNeedToTranslate", FilterForFullTextNeedToTranslateType.Chinese, "对整个文本生效。用来筛选待翻译的文本以节省翻译额度。Effective for the full text. Used to filter the text to be translated to save translation quotas."); RegexForFullTextNeedToTranslate = ((BaseUnityPlugin)this).Config.Bind<string>("1.General", "RegexForFullTextNeedToTranslate", "^(?!Enter the Gungeon).*$", "正则表达式,一个多行文本若匹配为真,则这个多行文本保留以待翻译。只在FilterForFullTextNeedToTranslate为CustomRegex时生效。Regular expression, if a multiple line text matches true, then this multiple line text is retained for translation. Only effective when FilterForFullTextNeedToTranslate is set to CustomRegex."); FilterForEachLineNeedToTranslate = ((BaseUnityPlugin)this).Config.Bind<FilterForEachLineNeedToTranslateType>("1.General", "FilterForEachLineNeedToTranslate", FilterForEachLineNeedToTranslateType.Chinese, "对文本的每一行生效。用来筛选待翻译的文本以节省翻译额度。Effective for each line of text. Used to filter the text to be translated to save translation quotas."); RegexForEachLineNeedToTranslate = ((BaseUnityPlugin)this).Config.Bind<string>("1.General", "RegexForEachLineNeedToTranslate", "^(?![@#])(?=\\S)(?!^[\\d\\p{P}]+$)(?!.*[\\u4e00-\\u9fa5\\u3000-\\u303F\\uFF00-\\uFFEF]).*$", "正则表达式,多行文本若存在一行匹配,整个多行文本保留以待翻译。只在FilterForEachLineNeedToTranslate为CustomRegex时生效。Regular expression, if there is a matching line in multiple lines of text, the entire multiple lines of text are retained for translation. Only effective when FilterForEachLineNeedToTranslate is set to CustomRegex."); FilterForIgnoredSubstringWithinText = ((BaseUnityPlugin)this).Config.Bind<FilterForIgnoredSubstringWithinTextType>("1.General", "FilterForIgnoredSubstringWithinText", FilterForIgnoredSubstringWithinTextType.Chinese, "用来过滤文本中需要忽略的子文本。这通常包括一些要特殊处理的贴图和转义符。Used to filter sub texts that need to be ignored in the text. This usually includes some textures and escape characters that require special handling."); RegexForIgnoredSubstringWithinText = ((BaseUnityPlugin)this).Config.Bind<string>("1.General", "RegexForIgnoredSubstringWithinText", "(?:\\[color\\s+[^\\]]+\\])|(?:\\[sprite\\s+[^\\]]+\\])|(?:\\[/color\\])|(?:\\{[^}]*\\})|(?:\\^[\\w\\d]{9})|(?:[\\u4e00-\\u9fa5\\u3000-\\u303F\\uFF00-\\uFFEF]+)|(?:<color=[^>]+>)|(?:</color>)|(?:^\\s*[\\d\\p{P}]+\\s*$)|(?:[<>\\[\\]])|(?:@[a-fA-F0-9]{6})", "正则表达式,匹配文本中需要忽略的子文本。请使用非捕获组。只在FilterForIgnoredSubstringWithinText为CustomRegex时生效。Regular expression, matching sub texts that need to be ignored in the text. Please use non capture groups. Only effective when FilterForIgnoredSubstringWithinText is set to CustomRegex."); MaxBatchCharacterCount = ((BaseUnityPlugin)this).Config.Bind<int>("1.General", "MaxBatchCharacterCount", 1024, "处理的批量数据最大字符数。若翻译api提示单次请求过长,请减小此值。The maximum count of batch data characters for processing. If the translation API prompts that a single request is too long, please reduce this value."); MaxBatchTextCount = ((BaseUnityPlugin)this).Config.Bind<int>("1.General", "MaxBatchTextCount", 0, "处理的批量数据最大项数。为0表示不限制。The maximum count of batch data texts for processing. A value of 0 indicates no restriction."); MaxRetryCount = ((BaseUnityPlugin)this).Config.Bind<int>("1.General", "MaxRetryCount", 3, "发生错误时的最大重试次数。The maximum number of retries when an error occurs."); RetryInterval = ((BaseUnityPlugin)this).Config.Bind<float>("1.General", "RetryInterval", 2f, "发生错误时的重试时间间隔。The interval of retries when an error occurs."); TranslationCacheCapacity = ((BaseUnityPlugin)this).Config.Bind<int>("1.General", "TranslationCacheCapacity", 1024, "最大翻译缓存容量。Maximum translation cache capacity."); PresetTranslations = ((BaseUnityPlugin)this).Config.Bind<string>("1.General", "PresetTranslations", "CachedTranslations.json;PresetTranslations.json", "预设翻译的文件名。使用预设翻译以减少加载时常见文本的翻译请求,留空表示不使用。预设翻译为位于dll同目录下的JSON文件。用“;”分割,文件会按顺序先后加载。The file name for preset translations. Use preset translation to reduce translation requests for common text during loading, leaving blank to indicate not using. The preset translation is a JSON file located in the same directory as the DLL. Separated by ';', files will be loaded sequentially."); CachedTranslations = ((BaseUnityPlugin)this).Config.Bind<string>("1.General", "CachedTranslations", "CachedTranslations.json", "缓存翻译的文件名。缓存翻译为位于dll同目录下的JSON文件。The file name cached translations. The preset translation is a JSON file located in the same directory as the DLL."); AutoSaveCachedTranslationsUponQuit = ((BaseUnityPlugin)this).Config.Bind<bool>("1.General", "AutoSaveCachedTranslationsUponQuit", false, "是否在退出时自动保存缓存翻译。强制退出时不会生效。Whether to automatically save cached translations upon quit. It will not take effect when quiting abnormally."); LogRequestedTexts = ((BaseUnityPlugin)this).Config.Bind<bool>("1.General", "LogRequestedTexts", false, "是否在日志中显示请求翻译的文本。Whether to log the text requested for translation."); OverrideFont = ((BaseUnityPlugin)this).Config.Bind<OverrideFontType>("2.Font", "OverrideFont", OverrideFontType.Custom, "用来覆盖游戏字体的字体。根据你需要的目标语言选择。Font used to override the font of the game. Choose according to the target language you need."); FontAssetBundleName = ((BaseUnityPlugin)this).Config.Bind<string>("2.Font", "FontAssetBundleName", "fusion_pixel_12px_zh_cn", "包含自定义字体的AssetBundle名称。位于dll同目录下。AssetBundle name containing custom fonts. Located in the same directory as DLL."); CustomDfFontName = ((BaseUnityPlugin)this).Config.Bind<string>("2.Font", "CustomDfFontName", "Fusion_Pixel_12px_Monospaced_dfDynamic", "要使用的自定义df字体。请把它包含于FontAssetBundle。The custom df font to be used. Please include it in FontAssetBundle."); CustomTk2dFontName = ((BaseUnityPlugin)this).Config.Bind<string>("2.Font", "CustomTk2dFontName", "Fusion_Pixel_12px_Monospaced_tk2d", "要使用的自定义tk2d字体。请把它包含于FontAssetBundle。The custom tk2d font to be used. Please include it in FontAssetBundle."); OverrideDfTokenizer = ((BaseUnityPlugin)this).Config.Bind<OverrideDfTokenizerType>("2.Font", "OverrideDfTokenizer", OverrideDfTokenizerType.Chinese, "覆盖的Df分词器。Token可以用于处理文本的自动换行位置。如每个字换行还是单词后换行。Override Df tokenizer. Token is used to handle the automatic line break position of text. Whether to wrap each word or to wrap after each word."); RegexForDfTokenizer = ((BaseUnityPlugin)this).Config.Bind<string>("2.Font", "RegexForDfTokenizer", FontManager.defaultRegexForTokenizer, "用于Df生成token的正则表达式。只在OverrideDfTokenizer为CustomRegex时生效。A regular expression used for generating tokens for Df. Only effective when OverrideDfTokenizer is set to CustomRegex."); DfTextScaleExpandThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("2.Font", "DfTextScaleExpandThreshold", 1f, "低于这个值的Df TextScale会被扩大。为负表示不生效。Df TextScale below this value will be expanded. Negative indicates non effectiveness."); DfTextScaleExpandToValue = ((BaseUnityPlugin)this).Config.Bind<float>("2.Font", "DfTextScaleExpandToValue", 2f, "低于门槛的Df TextScale被扩大到多少。How much is the Df TextScale below the threshold expanded to."); ShowRequestedCharacterCount = ((BaseUnityPlugin)this).Config.Bind<bool>("3.RequestedCharacterCount", "ShowRequestedCharacterCount", true, "显示已翻译字符数。Show requested character count."); RequestedCharacterCountAlertThreshold = ((BaseUnityPlugin)this).Config.Bind<int>("3.RequestedCharacterCount", "RequestedCharacterCountAlertThreshold", 50000, "已请求翻译字符数警报阈值。当翻译请求即将超出时,会暂停翻译。为零表示不设阈值。The alert threshold of the count of characters requested for translation. When this count is about to exceed, translation will be paused. A value of zero indicates no threshold is set."); ToggleRequestedCharacterCountKeyBinding = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("3.RequestedCharacterCount", "ToggleRequestedCharacterCountKeyBinding", (KeyCode)287, "开启或关闭已翻译字符数的显示的按键。The key binding of toggling the display of requested character count."); CountLabelAnchor = ((BaseUnityPlugin)this).Config.Bind<string>("3.RequestedCharacterCount", "CountLabelAnchor", "0.5 0", "用空格或逗号分隔的一个二维向量,决定计数标签相对于父级的锚点位置。左上角为0 0,右下角是1 1。A two-dimensional vector separated by spaces or commas, which determines where the count label is anchored relative to its parent. The top left corner is 0 0, and the bottom right corner is 1 1."); CountLabelPivot = ((BaseUnityPlugin)this).Config.Bind<string>("3.RequestedCharacterCount", "CountLabelPivot", "0.5 0", "用空格或逗号分隔的一个二维向量,定义计数标签的定位基准点。左上角为0 0,右下角是1 1。A two-dimensional vector separated by spaces or commas, which defines the pivot point of the count label for positioning. The top left corner is 0 0, and the bottom right corner is 1 1."); TranslateTextsOfItemTipsMod = ((BaseUnityPlugin)this).Config.Bind<bool>("4.Compatibility", "TranslateTextsOfItemTipsMod", true, "翻译ItemTipsMod中的文本。Translate the text in ItemTipsMod."); OverrideItemTipsTokenizer = ((BaseUnityPlugin)this).Config.Bind<OverrideItemTipsTokenizerType>("4.Compatibility", "OverrideItemTipsTokenizer", OverrideItemTipsTokenizerType.Chinese, "覆盖的ItemTips分词器。Token可以用于处理文本的自动换行位置。如每个字换行还是单词后换行。Override ItemTips tokenizer. Token is used to handle the automatic line break position of text. Whether to wrap each word or to wrap after each word."); RegexForItemTipsModTokenizer = ((BaseUnityPlugin)this).Config.Bind<string>("4.Compatibility", "RegexForItemTipsModTokenizer", FontManager.defaultRegexForItemTipsModTokenizer, "用于ItemTips生成token的正则表达式。只在OverrideItemTipsTokenizer为CustomRegex时生效。A regular expression used for generating tokens for ItemTips. Only effective when OverrideItemTipsTokenizer is set to CustomRegex."); ItemTipsFontScale = ((BaseUnityPlugin)this).Config.Bind<float>("4.Compatibility", "ItemTipsFontScale", 1.5f, "ItemTips的字体缩放大小。The font scale of ItemTips."); ItemTipsBackgroundWidthScale = ((BaseUnityPlugin)this).Config.Bind<float>("4.Compatibility", "ItemTipsBackgroundWidthScale", 1f, "ItemTips的背景宽度缩放大小。The width scale of ItemTips background."); ItemTipsLineHeightScale = ((BaseUnityPlugin)this).Config.Bind<float>("4.Compatibility", "ItemTipsLineHeightScale", 1.4f, "ItemTips的行高缩放大小。The width scale of ItemTips line height."); ItemTipsAnchor = ((BaseUnityPlugin)this).Config.Bind<string>("4.Compatibility", "ItemTipsAnchor", "0.1 0.5", "用空格或逗号分隔的一个二维向量,决定ItemTips相对于父级的锚点位置。左上角为0 0,右下角是1 1。A two-dimensional vector separated by spaces or commas, which determines where ItemTips is anchored relative to its parent. The top left corner is 0 0, and the bottom right corner is 1 1."); ItemTipsPivot = ((BaseUnityPlugin)this).Config.Bind<string>("4.Compatibility", "ItemTipsPivot", "0 0.5", "用空格或逗号分隔的一个二维向量,定义ItemTips的定位基准点。左上角为0 0,右下角是1 1。A two-dimensional vector separated by spaces or commas, which defines the pivot point of ItemTips for positioning. The top left corner is 0 0, and the bottom right corner is 1 1."); ItemTipsSourceBitmapFontBaseLine = ((BaseUnityPlugin)this).Config.Bind<int>("4.Compatibility", "ItemTipsSourceBitmapFontBaseLine", 10, "ItemTips的字体如果由位图字体生成,可以在此控制位图字体的基准线。If the font used by ItemTips is generated from a bitmap font, you can adjust the baseline of the bitmap font here."); TencentSecretId = ((BaseUnityPlugin)this).Config.Bind<string>("5.TencentTranslation", "SecretId", "", "腾讯翻译的SecretId。The SecretId of Tencent Translate."); TencentSecretKey = ((BaseUnityPlugin)this).Config.Bind<string>("5.TencentTranslation", "SecretKey", "", "腾讯翻译的SecretKey。The SecretKey of Tencent Translate."); TencentSourceLanguage = ((BaseUnityPlugin)this).Config.Bind<string>("5.TencentTranslation", "SourceLanguage", "en", "腾讯翻译的源语言,如en。The source language of Tencent Translate, such as en."); TencentTargetLanguage = ((BaseUnityPlugin)this).Config.Bind<string>("5.TencentTranslation", "TargetLanguage", "zh", "腾讯翻译的目标语言,如zh。Tencent Translate's target language, such as zh."); TencentRegion = ((BaseUnityPlugin)this).Config.Bind<string>("5.TencentTranslation", "Region", "ap-beijing", "地域,用来标识希望连接哪个地域的服务器,如ap-beijing。Region, used to identify which region's server you want to connect to, such as ap-beijing."); BaiduAppId = ((BaseUnityPlugin)this).Config.Bind<string>("6.BaiduTranslate", "SecretId", "", "百度翻译的AppId。The AppId of Baidu Translate."); BaiduSecretKey = ((BaseUnityPlugin)this).Config.Bind<string>("6.BaiduTranslate", "SecretKey", "", "百度翻译的SecretKey。The SecretKey for Baidu Translate."); BaiduSourceLanguage = ((BaseUnityPlugin)this).Config.Bind<string>("6.BaiduTranslate", "SourceLanguage", "en", "百度翻译的源语言,如en。The source language of Baidu Translate, such as en."); BaiduTargetLanguage = ((BaseUnityPlugin)this).Config.Bind<string>("6.BaiduTranslate", "TargetLanguage", "zh", "百度翻译的目标语言,如zh。The target language for Baidu Translate, such as zh."); AzureSubscriptionKey = ((BaseUnityPlugin)this).Config.Bind<string>("7.AzureTranslate", "AzureSubscriptionKey", "", "Azure翻译的SubscriptionKey。Subscription Key for Azure Translation."); AzureSourceLanguage = ((BaseUnityPlugin)this).Config.Bind<string>("7.AzureTranslate", "SourceLanguage", "en", "Azure翻译的源语言,如en。The source language for Azure translation, such as en."); AzureTargetLanguage = ((BaseUnityPlugin)this).Config.Bind<string>("7.AzureTranslate", "TargetLanguage", "zh-Hans", "Azure翻译的目标语言,如zh-Hans。The target language for Azure translation, such as zh-Hans."); AzureRegion = ((BaseUnityPlugin)this).Config.Bind<string>("7.AzureTranslate", "AzureRegion", "global", "地域,用来标识希望连接哪个地域的服务器,如global。Region, used to identify which region's server you want to connect to, such as global."); LlmBaseUrl = ((BaseUnityPlugin)this).Config.Bind<string>("8.Llm", "LlmBaseUrl", "", "大模型API的基础URL,用来连接到目标大模型服务的接口地址。Base URL of the large model API, used to connect to the target large model service endpoint."); LlmApiKey = ((BaseUnityPlugin)this).Config.Bind<string>("8.Llm", "LlmApiKey", "", "大模型API的访问密钥,用来进行身份验证并访问API服务。API key for the large model, used for authentication and accessing the API service."); LlmName = ((BaseUnityPlugin)this).Config.Bind<string>("8.Llm", "LlmName", "", "大模型的名称,指定要使用的模型版本或名称。The name of the large model, specifying which model version or name to use."); LlmPrompt = ((BaseUnityPlugin)this).Config.Bind<string>("8.Llm", "LlmPrompt", "英文翻译为中文,仅返回JSON的内容。输出格式和输入一致。输入:[{\"id\":1,\"text\":\"Hello\"}, {\"id\":2,\"text\":\"World\"}] 输出:[{\"id\":1,\"text\":\"你好\"}, {\"id\":2,\"text\":\"世界\"}]", "Prompt是向语言模型提供指示或请求的输入文本,帮助模型理解任务并生成响应。A prompt is the input text given to a language model to guide it in understanding the task and generating a response."); LlmMaxTokens = ((BaseUnityPlugin)this).Config.Bind<int>("8.Llm", "LlmMaxTokens", 1024, "大模型API允许的最大token数,控制生成内容的最大长度。Maximum number of tokens allowed by the large model API, controlling the maximum length of generated content."); LlmTemperature = ((BaseUnityPlugin)this).Config.Bind<float>("8.Llm", "LlmTemperature", 1.3f, "控制大模型生成文本的创造性,值越高,生成的文本越随机,越低则越确定。Controls the creativity of the large model's text generation, with higher values leading to more random and lower values leading to more deterministic output."); LlmTopP = ((BaseUnityPlugin)this).Config.Bind<float>("8.Llm", "LlmTopP", 0.7f, "控制大模型生成文本时的采样范围,值越低,结果越集中。Controls the sampling range of the large model's text generation, with lower values leading to more focused results."); LlmTopK = ((BaseUnityPlugin)this).Config.Bind<int>("8.Llm", "LlmTopK", 30, "控制大模型生成文本时考虑的最高概率词的数量,值越高,结果越多样化。Controls the number of highest probability words considered by the large model during text generation, with higher values leading to more diverse results."); LlmFrequencyPenalty = ((BaseUnityPlugin)this).Config.Bind<float>("8.Llm", "LlmFrequencyPenalty", 0f, "控制生成文本中词汇重复的概率。值越高,生成内容越多样化;值越低,生成内容越集中和重复。Controls the likelihood of token repetition in generated text.Higher values promote diversity, while lower values result in more focused and repetitive outputs."); LlmExtraParametersJson = ((BaseUnityPlugin)this).Config.Bind<string>("8.Llm", "LlmExtraParametersJson", "{\"enable_thinking\": false}", "一个JSON,列举了大模型需要的额外参数。A JSON listing the additional parameters required by the large language model."); LlmQuotePreprocess = ((BaseUnityPlugin)this).Config.Bind<LlmQuotePreprocessType>("8.Llm", "LlmQuotePreprocess", LlmQuotePreprocessType.Chinese, "用于设置引号预处理的类型。Sets the quote preprocessing type."); LlmDataFormat = ((BaseUnityPlugin)this).Config.Bind<LlmDataFormatType>("8.Llm", "LlmDataFormat", LlmDataFormatType.Json, "用于设置收发数据的格式类型。Set the format type for sending and receiving data."); LlmSplitText = ((BaseUnityPlugin)this).Config.Bind<string>("8.Llm", "LlmSplitText", "<tspl>", "仅当LlmDataFormat为Split时生效。分割形式收发数据时的分隔符。Only takes effect when LlmDataFormat is set to Split. The split text for sending and receiving data in the format of splitted."); LlmPositionText = ((BaseUnityPlugin)this).Config.Bind<string>("8.Llm", "LlmPositionText", "<!pos!>", "仅当LlmDataFormat为PositionTagged时生效。位置编号的起始标记。Only takes effect when LlmDataFormat is set to PositionTagged. The starting tag of the position number."); LlmSegmentText = ((BaseUnityPlugin)this).Config.Bind<string>("8.Llm", "LlmSegmentText", "<!seg!>", "仅当LlmDataFormat为Positioned时生效。被定位的段的起始标记。Only takes effect when LlmDataFormat is set to Positioned. The starting tag of the positioned segment."); AutoTranslateConfig autoTranslateConfig = new AutoTranslateConfig(); autoTranslateConfig.TranslationAPI = TranslationAPI.Value; autoTranslateConfig.ToggleTranslationKeyBinding = ToggleTranslationKeyBinding.Value; autoTranslateConfig.FilterForFullTextNeedToTranslate = FilterForFullTextNeedToTranslate.Value; autoTranslateConfig.RegexForFullTextNeedToTranslate = RegexForFullTextNeedToTranslate.Value; autoTranslateConfig.FilterForEachLineNeedToTranslate = FilterForEachLineNeedToTranslate.Value; autoTranslateConfig.RegexForEachLineNeedToTranslate = RegexForEachLineNeedToTranslate.Value; autoTranslateConfig.FilterForIgnoredSubstringWithinText = FilterForIgnoredSubstringWithinText.Value; autoTranslateConfig.RegexForIgnoredSubstringWithinText = RegexForIgnoredSubstringWithinText.Value; autoTranslateConfig.MaxBatchCharacterCount = MaxBatchCharacterCount.Value; autoTranslateConfig.MaxBatchTextCount = MaxBatchTextCount.Value; autoTranslateConfig.MaxRetryCount = MaxRetryCount.Value; autoTranslateConfig.RetryInterval = ((RetryInterval.Value > 0f) ? RetryInterval.Value : 2f); autoTranslateConfig.TranslationCacheCapacity = TranslationCacheCapacity.Value; autoTranslateConfig.PresetTranslations = PresetTranslations.Value; autoTranslateConfig.CachedTranslations = CachedTranslations.Value; autoTranslateConfig.AutoSaveCachedTranslationsUponQuit = AutoSaveCachedTranslationsUponQuit.Value; autoTranslateConfig.LogRequestedTexts = LogRequestedTexts.Value; autoTranslateConfig.OverrideFont = OverrideFont.Value; autoTranslateConfig.FontAssetBundleName = FontAssetBundleName.Value; autoTranslateConfig.CustomDfFontName = CustomDfFontName.Value; autoTranslateConfig.CustomTk2dFontName = CustomTk2dFontName.Value; autoTranslateConfig.OverrideDfTokenizer = OverrideDfTokenizer.Value; autoTranslateConfig.RegexForDfTokenizer = RegexForDfTokenizer.Value; autoTranslateConfig.DfTextScaleExpandThreshold = DfTextScaleExpandThreshold.Value; autoTranslateConfig.DfTextScaleExpandToValue = DfTextScaleExpandToValue.Value; autoTranslateConfig.ShowRequestedCharacterCount = ShowRequestedCharacterCount.Value; autoTranslateConfig.RequestedCharacterCountAlertThreshold = RequestedCharacterCountAlertThreshold.Value; autoTranslateConfig.ToggleRequestedCharacterCountKeyBinding = ToggleRequestedCharacterCountKeyBinding.Value; autoTranslateConfig.CountLabelAnchor = CountLabelAnchor.Value; autoTranslateConfig.CountLabelPivot = CountLabelPivot.Value; autoTranslateConfig.TranslateTextsOfItemTipsMod = TranslateTextsOfItemTipsMod.Value; autoTranslateConfig.OverrideItemTipsTokenizer = OverrideItemTipsTokenizer.Value; autoTranslateConfig.RegexForItemTipsModTokenizer = RegexForItemTipsModTokenizer.Value; autoTranslateConfig.ItemTipsFontScale = ((ItemTipsFontScale.Value > 0f) ? ItemTipsFontScale.Value : 1f); autoTranslateConfig.ItemTipsBackgroundWidthScale = ((ItemTipsBackgroundWidthScale.Value > 0f) ? ItemTipsBackgroundWidthScale.Value : 1f); autoTranslateConfig.ItemTipsLineHeightScale = ((ItemTipsLineHeightScale.Value > 0f) ? ItemTipsLineHeightScale.Value : 1f); autoTranslateConfig.ItemTipsAnchor = ItemTipsAnchor.Value; autoTranslateConfig.ItemTipsPivot = ItemTipsPivot.Value; autoTranslateConfig.ItemTipsSourceBitmapFontBaseLine = ItemTipsSourceBitmapFontBaseLine.Value; autoTranslateConfig.TencentSecretId = TencentSecretId.Value; autoTranslateConfig.TencentSecretKey = TencentSecretKey.Value; autoTranslateConfig.TencentSourceLanguage = TencentSourceLanguage.Value; autoTranslateConfig.TencentTargetLanguage = TencentTargetLanguage.Value; autoTranslateConfig.TencentRegion = TencentRegion.Value; autoTranslateConfig.BaiduAppId = BaiduAppId.Value; autoTranslateConfig.BaiduSecretKey = BaiduSecretKey.Value; autoTranslateConfig.BaiduSourceLanguage = BaiduSourceLanguage.Value; autoTranslateConfig.BaiduTargetLanguage = BaiduTargetLanguage.Value; autoTranslateConfig.AzureSubscriptionKey = AzureSubscriptionKey.Value; autoTranslateConfig.AzureSourceLanguage = AzureSourceLanguage.Value; autoTranslateConfig.AzureTargetLanguage = AzureTargetLanguage.Value; autoTranslateConfig.AzureRegion = AzureRegion.Value; autoTranslateConfig.LlmBaseUrl = LlmBaseUrl.Value; autoTranslateConfig.LlmApiKey = LlmApiKey.Value; autoTranslateConfig.LlmName = LlmName.Value; autoTranslateConfig.LlmPrompt = LlmPrompt.Value; autoTranslateConfig.LlmMaxTokens = LlmMaxTokens.Value; autoTranslateConfig.LlmTemperature = LlmTemperature.Value; autoTranslateConfig.LlmTopP = LlmTopP.Value; autoTranslateConfig.LlmTopK = LlmTopK.Value; autoTranslateConfig.LlmFrequencyPenalty = LlmFrequencyPenalty.Value; autoTranslateConfig.LlmExtraParametersJson = LlmExtraParametersJson.Value; autoTranslateConfig.LlmQuotePreprocess = LlmQuotePreprocess.Value; autoTranslateConfig.LlmDataFormat = LlmDataFormat.Value; autoTranslateConfig.LlmSplitText = LlmSplitText.Value; autoTranslateConfig.LlmPositionText = LlmPositionText.Value; autoTranslateConfig.LlmSegmentText = LlmSegmentText.Value; autoTranslateConfig.CheckConfig(); return autoTranslateConfig; } private void DoOptionalPatches() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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 //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Expected O, but got Unknown //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Expected O, but got Unknown //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Expected O, but got Unknown //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Expected O, but got Unknown //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Expected O, but got Unknown //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Expected O, but got Unknown //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Expected O, but got Unknown if (Chainloader.PluginInfos.ContainsKey("glorfindel.etg.itemtips")) { FontManager.instance.itemTipsModuleType = AccessTools.TypeByName("ItemTipsMod.ItemTipsModule"); MethodInfo methodInfo = AccessTools.Method(FontManager.instance.itemTipsModuleType, "GmStart", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(AutoTranslatePatches.GmStartPatchClass), "GmStartPostfix", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo3 = AccessTools.Method(FontManager.instance.itemTipsModuleType, "LoadFont", (Type[])null, (Type[])null); MethodInfo methodInfo4 = AccessTools.Method(typeof(AutoTranslatePatches.LoadFontPatchClass), "LoadFontPrefix", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo5 = AccessTools.Method(FontManager.instance.itemTipsModuleType, "ConvertStringToFixedWidthLines", (Type[])null, (Type[])null); MethodInfo methodInfo6 = AccessTools.Method(typeof(AutoTranslatePatches.ConvertStringToFixedWidthLinesPatchClass), "ConvertStringToFixedWidthLinesPrefix", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo5, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo7 = AccessTools.Method(FontManager.instance.itemTipsModuleType, "GenerateTextInfo", (Type[])null, (Type[])null); MethodInfo methodInfo8 = AccessTools.Method(typeof(AutoTranslatePatches.GenerateTextInfoPatchClass), "GenerateTextInfoPatch", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo7, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo8)); MethodInfo methodInfo9 = AccessTools.Method(FontManager.instance.itemTipsModuleType, "ShowTip", (Type[])null, (Type[])null); MethodInfo methodInfo10 = AccessTools.Method(typeof(AutoTranslatePatches.ShowTipPatchClass), "ShowTipPostfix", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo9, (HarmonyMethod)null, new HarmonyMethod(methodInfo10), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo11 = AccessTools.Method(AccessTools.TypeByName("ItemTipsMod.Label"), "Reposition", (Type[])null, (Type[])null); MethodInfo methodInfo12 = AccessTools.Method(typeof(AutoTranslatePatches.RepositionPatchClass), "RepositionPostfix", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo11, (HarmonyMethod)null, new HarmonyMethod(methodInfo12), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (Chainloader.PluginInfos.ContainsKey("lazymo3_and_NilT_PL.etg.NoBrain")) { MethodInfo methodInfo13 = AccessTools.Method(AccessTools.TypeByName("NBInteractableBehaviour"), "onNewShopItemController", (Type[])null, (Type[])null); MethodInfo methodInfo14 = AccessTools.Method(typeof(AutoTranslatePatches.NewShopItemControllerPatchClass), "NewShopItemControllerPrefix", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo13, new HarmonyMethod(methodInfo14), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (RegexForDfTokenizer.Value != string.Empty) { Type typeFromHandle = typeof(DynamicFontRenderer); MethodInfo methodInfo15 = AccessTools.Method(typeFromHandle, "tokenize", (Type[])null, (Type[])null); MethodInfo methodInfo16 = AccessTools.Method(typeof(AutoTranslatePatches.DynamicFontRendererTokenizePatchClass), "TokenizePrefix", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo15, new HarmonyMethod(methodInfo16), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo17 = AccessTools.Method(typeFromHandle, "calculateLinebreaks", (Type[])null, (Type[])null); MethodInfo methodInfo18 = AccessTools.Method(typeof(AutoTranslatePatches.DynamicFontRendererCalculateLinebreaksPatchClass), "CalculateLinebreaksPatch", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo17, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo18)); Type typeFromHandle2 = typeof(BitmappedFontRenderer); MethodInfo methodInfo19 = AccessTools.Method(typeFromHandle2, "tokenize", (Type[])null, (Type[])null); MethodInfo methodInfo20 = AccessTools.Method(typeof(AutoTranslatePatches.BitmappedFontRendererTokenizePatchClass), "TokenizePrefix", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo19, new HarmonyMethod(methodInfo20), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo21 = AccessTools.Method(typeFromHandle2, "calculateLinebreaks", (Type[])null, (Type[])null); MethodInfo methodInfo22 = AccessTools.Method(typeof(AutoTranslatePatches.BitmappedFontRendererCalculateLinebreaksPatchClass), "CalculateLinebreaksPatch", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo21, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo22)); } } private void LogHelp(string[] args) { ETGModConsole.Log((object)"", false); ETGModConsole.Log((object)"Command list:", false); ETGModConsole.Log((object)" -- <color=#AA3399>autotranslate save_cache [cache_json_name]</color>", false); ETGModConsole.Log((object)" - Save the translation cache to [cache_json_name], which defaults to CachedTranslations.json.", false); ETGModConsole.Log((object)" -- <color=#AA3399>autotranslate load_cache [cache_json_name]</color>", false); ETGModConsole.Log((object)" - Load the translation cache from [cache_json_name], which defaults to CachedTranslations.json.", false); } private void SaveCache(string[] args) { string text = Path.Combine(path2: (args != null && args.Length != 0) ? args[0] : (string.IsNullOrEmpty(config.CachedTranslations) ? "CachedTranslations.json" : config.CachedTranslations), path1: ETGMod.FolderPath((BaseUnityPlugin)(object)instance)); translateManager.SaveTranslationCache(text, config.TranslationCacheCapacity); ETGModConsole.Log((object)("Translation cache saved successfully to " + text), false); } private void LoadCache(string[] args) { string text = Path.Combine(path2: (args != null && args.Length != 0) ? args[0] : (string.IsNullOrEmpty(config.CachedTranslations) ? "CachedTranslations.json" : config.CachedTranslations), path1: ETGMod.FolderPath((BaseUnityPlugin)(object)instance)); translateManager.ReadAndRestoreTranslationCache(text); ETGModConsole.Log((object)("Translation cache loaded successfully from " + text), false); } public void OnApplicationQuit() { if (config.AutoSaveCachedTranslationsUponQuit) { SaveCache(null); } } } public static class AutoTranslatePatches { [HarmonyPatch(/*Could not decode attribute arguments.*/)] public class DfLabelTextPatchClass { [HarmonyPostfix] public static void DfLabelTextPostfix(dfLabel __instance) { DfLabelTextAddCall(__instance); } } [HarmonyPatch(typeof(dfLabel), "OnLocalize")] public class DfLabelOnLocalizePatchClass { [HarmonyPostfix] public static void DfLabelOnLocalizePostfix(dfLabel __instance) { DfLabelTextAddCall(__instance); } } [HarmonyPatch(typeof(dfLabel), "ModifyLocalizedText")] public class DfLabelModifyLocalizedTextPatchClass { [HarmonyPostfix] public static void DfLabelModifyLocalizedTextPostfix(dfLabel __instance) { DfLabelTextAddCall(__instance); } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] public class DfButtonTextPatchClass { [HarmonyPostfix] public static void DfButtonTextPostfix(dfButton __instance) { DfButtonTextAddCall(__instance); } } [HarmonyPatch(typeof(dfButton), "OnLocalize")] public class DfButtonOnLocalizePatchClass { [HarmonyPostfix] public static void DfButtonOnLocalizePostfix(dfButton __instance) { DfButtonTextAddCall(__instance); } } [HarmonyPatch(typeof(dfButton), "ModifyLocalizedText")] public class DfButtonModifyLocalizedTextPatchClass { [HarmonyPostfix] public static void DfButtonModifyLocalizedTextPostfix(dfButton __instance) { DfButtonTextAddCall(__instance); } } public class GmStartPatchClass { public static void GmStartPostfix(object __instance) { FontManager.instance.itemTipsModuleObject = __instance; FieldInfo field = FontManager.instance.itemTipsModuleType.GetField("_infoLabel", BindingFlags.Instance | BindingFlags.NonPublic); ref SLabel itemTipsModuleLabel = ref FontManager.instance.itemTipsModuleLabel; object? value = field.GetValue(__instance); itemTipsModuleLabel = (SLabel)((value is SLabel) ? value : null); } } public class ShowTipPatchClass { public static void ShowTipPostfix() { if (FontManager.instance.itemTipsModuleText != null && config.TranslateTextsOfItemTipsMod) { TranslationManager.instance.AddTranslationRequest(FontManager.instance.itemTipsModuleText, FontManager.instance.itemTipsModuleLabel); } } } public class LoadFontPatchClass { public static bool LoadFontPrefix(ref Font __result) { FieldInfo field = FontManager.instance.itemTipsModuleType.GetField("_gameFont", BindingFlags.Instance | BindingFlags.NonPublic); dfFontBase dfFontBase = FontManager.instance.dfFontBase; if ((Object)(object)dfFontBase != (Object)null) { dfDynamicFont val = (dfDynamicFont)(object)((dfFontBase is dfDynamicFont) ? dfFontBase : null); if (val != null) { FontManager.instance.potentialItemTipsDynamicBaseFont = val.baseFont; __result = val.baseFont; field.SetValue(FontManager.instance.itemTipsModuleObject, __result); FontManager.instance.itemTipsModuleFont = __result; return false; } } if ((Object)(object)dfFontBase != (Object)null) { dfFont val2 = (dfFont)(object)((dfFontBase is dfFont) ? dfFontBase : null); if (val2 != null) { FontManager.instance.originalLineHeight = ((dfFontBase)val2).LineHeight; __result = FontManager.GetFontFromdfFont(val2, 1.3f * config.ItemTipsFontScale, config.ItemTipsSourceBitmapFontBaseLine); field.SetValue(FontManager.instance.itemTipsModuleObject, __result); FontManager.instance.itemTipsModuleFont = __result; return false; } } dfFont gameFont = FontManager.GetGameFont(); if ((Object)(object)gameFont != (Object)null) { FontManager.instance.originalLineHeight = ((dfFontBase)gameFont).LineHeight; __result = FontManager.GetFontFromdfFont(gameFont, 1.3f * config.ItemTipsFontScale, config.ItemTipsSourceBitmapFontBaseLine); field.SetValue(FontManager.instance.itemTipsModuleObject, __result); FontManager.instance.itemTipsModuleFont = __result; return false; } return true; } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] public class Tk2dTextMeshTextPatchClass { [HarmonyPostfix] public static void Tk2dTextMeshTextPostfix(tk2dTextMesh __instance) { tk2dFontData tk2dFont = FontManager.instance.tk2dFont; if ((Object)(object)tk2dFont != (Object)null && (Object)(object)__instance.font != (Object)(object)tk2dFont) { FontManager.SetTextMeshFont(__instance, tk2dFont); } if (__instance.data != null && __instance.data.text != null) { TranslationManager.instance.AddTranslationRequest(__instance.data.text, __instance); } } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] public class Tk2dTextMeshFontPatchClass { [HarmonyPrefix] public static bool Tk2dTextMeshFontPrefix(tk2dTextMesh __instance) { tk2dFontData tk2dFont = FontManager.instance.tk2dFont; if ((Object)(object)tk2dFont != (Object)null && (Object)(object)__instance.font != (Object)(object)tk2dFont) { FontManager.SetTextMeshFont(__instance, tk2dFont); } return false; } } [HarmonyPatch(typeof(TextBoxManager), "SetText")] public class SetTextPatchClass { [HarmonyPrefix] public static void SetTextPrefix(ref bool instant) { instant = true; } } public class DynamicFontRendererTokenizePatchClass { public static bool TokenizePrefix(DynamicFontRenderer __instance, string text) { if (__instance.tokens != null) { if ((object)__instance.tokens[0].Source == text) { return false; } __instance.tokens.Release(); } __instance.tokens = FontManager.instance?.Tokenize(text); for (int i = 0; i < __instance.tokens.Count; i++) { __instance.calculateTokenRenderSize(__instance.tokens[i]); } return false; } } public class DynamicFontRendererCalculateLinebreaksPatchClass { [HarmonyILManipulator] public static void CalculateLinebreaksPatch(ILContext ctx) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) ILCursor crs = new ILCursor(ctx); if (TheNthTime(() => crs.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 0) }), 8)) { crs.Emit(OpCodes.Ldloca_S, (byte)3); crs.EmitCall<DynamicFontRendererCalculateLinebreaksPatchClass>("CalculateLinebreaksPatchCall_1"); ILCursor obj = crs; int index = obj.Index; obj.Index = index + 1; } if (crs.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 0) })) { crs.Emit(OpCodes.Ldloca_S, (byte)3); crs.EmitCall<DynamicFontRendererCalculateLinebreaksPatchClass>("CalculateLinebreaksPatchCall_1"); } if (crs.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 2) })) { crs.EmitCall<DynamicFontRendererCalculateLinebreaksPatchClass>("CalculateLinebreaksPatchCall_2"); } } private static void CalculateLinebreaksPatchCall_1(ref int orig) { orig--; } private static int CalculateLinebreaksPatchCall_2(int orig) { return 2; } } public class BitmappedFontRendererTokenizePatchClass { public static bool TokenizePrefix(BitmappedFontRenderer __instance, string text, ref dfList<dfMarkupToken> __result) { if (__instance.tokens != null) { if ((object)__instance.tokens[0].Source == text) { __result = __instance.tokens; return false; } __instance.tokens.Release(); } __instance.tokens = FontManager.instance?.Tokenize(text); for (int i = 0; i < __instance.tokens.Count; i++) { __instance.calculateTokenRenderSize(__instance.tokens[i]); } __result = __instance.tokens; return false; } } public class BitmappedFontRendererCalculateLinebreaksPatchClass { public static void CalculateLinebreaksPatch(ILContext ctx) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(ctx); if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 7) })) { val.EmitCall<BitmappedFontRendererCalculateLinebreaksPatchClass>("CalculateLinebreaksPatchCall_1"); } if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 2) })) { val.EmitCall<BitmappedFontRendererCalculateLinebreaksPatchClass>("CalculateLinebreaksPatchCall_2"); } } private static int CalculateLinebreaksPatchCall_1(int orig) { return 7; } private static int CalculateLinebreaksPatchCall_2(int orig) { return 2; } } [HarmonyPatch(typeof(tk2dTextMesh), "CheckFontsForLanguage")] public class Tk2dTextMeshCheckFontsForLanguagePatchClass { [HarmonyPrefix] public static bool CheckFontsForLanguagePrefix() { if ((Object)(object)FontManager.instance.tk2dFont != (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(dfLabel), "CheckFontsForLanguage")] public class DfLabelCheckFontsForLanguagePatchClass { [HarmonyPrefix] public static bool CheckFontsForLanguagePrefix() { if ((Object)(object)FontManager.instance.dfFontBase != (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(dfButton), "CheckFontsForLanguage")] public class DfButtonCheckFontsForLanguagePatchClass { [HarmonyPrefix] public static bool CheckFontsForLanguagePrefix() { if ((Object)(object)FontManager.instance.dfFontBase != (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(DefaultLabelController), "Trigger", new Type[] { typeof(Transform), typeof(Vector3) })] public class DefaultLabelControllerTriggerPatchClass { [HarmonyPrefix] public static void TriggerPrefix(DefaultLabelController __instance) { __instance.label.AutoSize = true; } } [HarmonyPatch(typeof(SimpleStatLabel), "Start")] public class SimpleStatLabelStartPatchClass { [HarmonyPostfix] public static void StartPostfix(SimpleStatLabel __instance) { __instance.m_label.autoSize = true; } } [HarmonyPatch(typeof(GameUIRoot), "UpdatePlayerConsumables")] public class UpdatePlayerConsumablesPatchClass { [HarmonyPrefix] public static void UpdatePlayerConsumablesPrefix(GameUIRoot __instance) { __instance.p_playerKeyLabel.autoSize = true; __instance.p_playerCoinLabel.autoSize = true; } } [HarmonyPatch(typeof(DynamicFontRenderer), "renderText")] public class RenderTextPatchClass { [HarmonyILManipulator] public static void RenderTextPatch(ILContext ctx) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(ctx); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCall<CharacterInfo>(x, "get_maxX") })) { val.Emit(OpCodes.Ldloca_S, (byte)3); val.EmitCall<RenderTextPatchClass>("RenderTextPatchCall"); } } private static int RenderTextPatchCall(int orig, ref CharacterInfo characterInfo) { return ((CharacterInfo)(ref characterInfo)).advance; } } [HarmonyPatch(typeof(DynamicFontRenderer), "calculateTokenRenderSize")] public class CalculateTokenRenderSizePatchClass { [HarmonyILManipulator] public static void CalculateTokenRenderSizePatch(ILContext ctx) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(ctx); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCall<CharacterInfo>(x, "get_maxX") })) { val.Emit(OpCodes.Ldloca_S, (byte)3); val.EmitCall<CalculateTokenRenderSizePatchClass>("CalculateTokenRenderSizePatchCall"); } } private static int CalculateTokenRenderSizePatchCall(int orig, ref CharacterInfo characterInfo) { return ((CharacterInfo)(ref characterInfo)).advance; } } [HarmonyPatch] public class GetCharacterWidthsPatchClass { public static MethodBase TargetMethod() { return AccessTools.Method(typeof(DynamicFontRenderer), "GetCharacterWidths", new Type[4] { typeof(string), typeof(int), typeof(int), typeof(float).MakeByRefType() }, (Type[])null); } [HarmonyILManipulator] public static void GetCharacterWidthsPatch(ILContext ctx) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(ctx); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCall<CharacterInfo>(x, "get_maxX") })) { val.Emit(OpCodes.Ldloca_S, (byte)5); val.EmitCall<GetCharacterWidthsPatchClass>("GetCharacterWidthsPatchCall"); } } private static int GetCharacterWidthsPatchCall(int orig, ref CharacterInfo characterInfo) { return ((CharacterInfo)(ref characterInfo)).advance; } } public class ConvertStringToFixedWidthLinesPatchClass { public static bool ConvertStringToFixedWidthLinesPrefix(string text, ref List<string> __result) { __result = new List<string> { text }; return false; } } public class GenerateTextInfoPatchClass { public static void GenerateTextInfoPatch(ILContext ctx) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(ctx); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCall<string>(x, "Join") })) { val.Emit(OpCodes.Ldloca_S, (byte)4); val.EmitCall<GenerateTextInfoPatchClass>("GenerateTextInfoPatchCall"); } } private static string GenerateTextInfoPatchCall(string text, ref Vector2 size) { //IL_0019: 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) FontManager.instance.itemTipsModuleText = text; Vector2 resultSize; string result = FontManager.instance.WrapText(text, out resultSize); size = resultSize; return result; } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] public class Expand_CRPatchClass { [HarmonyILManipulator] public static void Expand_CRPatch(ILContext ctx) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(ctx); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, "DefaultLabelController+<Expand_CR>c__Iterator0", "<targetWidth>__0") })) { val.Emit(OpCodes.Ldarg_0); val.EmitCall<Expand_CRPatchClass>("Expand_CRPatchCall"); } } private static float Expand_CRPatchCall(float orig, object selfObject) { return ((dfControl)GetFieldValueInEnumerator<DefaultLabelController>(selfObject, "this").label).Width + 1f; } } [HarmonyPatch(typeof(DefaultLabelController), "UpdateForLanguage")] public class DefaultLabelControllerUpdateForLanguagePatchClass { [HarmonyPrefix] public static bool UpdateForLanguagePrefix() { if (FontManager.instance.overrideFont == AutoTranslateModule.OverrideFontType.Custom && (Object)(object)FontManager.instance.dfFontBase != (Object)null) { return false; } return true; } [HarmonyILManipulator] public static void UpdateForLanguagePatch(ILContext ctx) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(ctx); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, -6) })) { val.EmitCall<DefaultLabelControllerUpdateForLanguagePatchClass>("UpdateForLanguagePatchCall"); } } private static int UpdateForLanguagePatchCall(int orig) { return -2; } } public class NewShopItemControllerPatchClass { public static void NewShopItemControllerPrefix(DefaultLabelController labelController) { labelController.label.AutoSize = false; } } public class RepositionPatchClass { public static void RepositionPostfix(SLabel __instance) { FontManager.instance.ItemTipsReposition(__instance); } } [HarmonyPatch] public class MeasureTextPatchClass { public static MethodBase TargetMethod() { return AccessTools.Method(typeof(SGUIIMBackend), "MeasureText", new Type[3] { typeof(string).MakeByRefType(), typeof(Vector2?), typeof(object) }, (Type[])null); } [HarmonyILManipulator] public static void MeasureTextPatch(ILContext ctx) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0039: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(ctx); if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallvirt<Font>(x, "RequestCharactersInTexture") })) { val.Emit(OpCodes.Ldloc_0); val.EmitCall<MeasureTextPatchClass>("MeasureTextPatchCall_1"); } if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallvirt<Font>(x, "GetCharacterInfo") })) { val.Emit(OpCodes.Ldloc_0); val.Emit(OpCodes.Ldloc_S, (byte)9); val.Emit(OpCodes.Ldloca_S, (byte)10); val.EmitCall<MeasureTextPatchClass>("MeasureTextPatchCall_2"); } } private static int MeasureTextPatchCall_1(int orig, Font font2) { if ((Object)(object)FontManager.instance.potentialItemTipsDynamicBaseFont != (Object)null && (Object)(object)font2 == (Object)(object)FontManager.instance.potentialItemTipsDynamicBaseFont) { return Mathf.RoundToInt((float)font2.fontSize * config.ItemTipsFontScale); } return orig; } private static bool MeasureTextPatchCall_2(bool orig, Font font2, char c, out CharacterInfo characterInfo2) { if ((Object)(object)FontManager.instance.potentialItemTipsDynamicBaseFont != (Object)null && (Object)(object)font2 == (Object)(object)FontManager.instance.potentialItemTipsDynamicBaseFont) { return font2.GetCharacterInfo(c, ref characterInfo2, Mathf.RoundToInt((float)font2.fontSize * config.ItemTipsFontScale)); } return font2.GetCharacterInfo(c, ref characterInfo2); } } [HarmonyPatch(typeof(SLabel), "Render")] public class SLabelRenderPatchClass { [HarmonyPrefix] public static void RenderPrefix(SLabel __instance) { object font = ((SElement)__instance).Font; Font val = (Font)((font is Font) ? font : null); if (val != null && (Object)(object)FontManager.instance.potentialItemTipsDynamicBaseFont != (Object)null && (Object)(object)val == (Object)(object)FontManager.instance.potentialItemTipsDynamicBaseFont) { ISGUIBackend backend = ((SElement)__instance).Backend; SGUIIMBackend val2 = (SGUIIMBackend)(object)((backend is SGUIIMBackend) ? backend : null); if (val2 != null) { val2.Skin.label.fontSize = Mathf.RoundToInt((float)val.fontSize * config.ItemTipsFontScale); } } } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] public class GetLineHeightPatchClass { [HarmonyPostfix] public static void GetLineHeightPostfix(SGUIIMBackend __instance, ref float __result) { if ((Object)(object)__instance.Skin.font != (Object)null && (Object)(object)__instance.Skin.font == (Object)(object)FontManager.instance.potentialItemTipsDynamicBaseFont) { __result = (float)__instance.Skin.font.fontSize * config.ItemTipsFontScale * config.ItemTipsLineHeightScale; } else if ((Object)(object)__instance.Skin.font != (Object)null && (Object)(object)__instance.Skin.font == (Object)(object)FontManager.instance.itemTipsModuleFont) { __result = 1.1f * (float)FontManager.instance.originalLineHeight * config.ItemTipsFontScale * config.ItemTipsLineHeightScale; } } } [HarmonyPatch(typeof(FoyerPreloader), "Awake")] public class FoyerPreloaderAwakePatchClass { [HarmonyPostfix] public static void FoyerPreloaderAwakePostfix(FoyerPreloader __instance) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)__instance).transform; Transform val = ((transform != null) ? transform.Find("weird name thing") : null); if ((Object)(object)val == (Object)null) { return; } DFScaleFixer component = ((Component)val).GetComponent<DFScaleFixer>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } dfGUIManager component2 = ((Component)val).GetComponent<dfGUIManager>(); if ((Object)(object)component2 == (Object)null) { return; } component2.UIScale = 1f; component2.PixelPerfectMode = true; for (int i = 0; i < val.childCount; i++) { Transform child = val.GetChild(i); if ((Object)(object)((Component)child).GetComponent<dfLabel>() == (Object)null) { child.localScale *= 5f; } } } } [HarmonyPatch(typeof(Object), "Destroy", new Type[] { typeof(Object), typeof(float) })] public class ObjectDestroyPatchClass { [HarmonyPrefix] private static void DestroyPrefix(object obj, float t) { TextObjectManager.MarkIfTarget(obj); } } [HarmonyPatch(typeof(Object), "DestroyImmediate", new Type[] { typeof(Object), typeof(bool) })] public class ObjectDestroyImmediatePatchClass { [HarmonyPrefix] private static void DestroyImmediatePrefix(object obj, bool allowDestroyingAssets) { TextObjectManager.MarkIfTarget(obj); } } [HarmonyPatch(typeof(Object), "DestroyObject", new Type[] { typeof(Object), typeof(float) })] public class ObjectDestroyObjectPatchClass { [HarmonyPrefix] private static void DestroyObjectPrefix(object obj, float t) { TextObjectManager.MarkIfTarget(obj); } } private static AutoTranslateConfig config = AutoTranslateModule.instance.config; private static StringBuilder addBracketBuilder = new StringBuilder(1024); public static void EmitCall<T>(this ILCursor iLCursor, string methodName, Type[] parameters = null, Type[] generics = null) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) MethodInfo methodInfo = AccessTools.Method(typeof(T), methodName, parameters, generics); iLCursor.Emit(OpCodes.Call, (MethodBase)methodInfo); } public static bool TheNthTime(this Func<bool> predict, int n = 1) { for (int i = 0; i < n; i++) { if (!predict()) { return false; } } return true; } public static T GetFieldValueInEnumerator<T>(object instance, string fieldNamePattern) { return (T)instance.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((FieldInfo f) => f.Name.Contains("$" + fieldNamePattern) || f.Name.Contains("<" + fieldNamePattern + ">") || f.Name == fieldNamePattern) .GetValue(instance); } private static string AddMissingBracket(string input) { if (string.IsNullOrEmpty(input)) { return input; } addBracketBuilder.Length = 0; int i = 0; int length = input.Length; bool flag = false; while (i < length) { if (i + 7 < length && TextProcessor.StartsWithString(input, i, "[sprite") && char.IsWhiteSpace(input[i + 7])) { int num = i; for (i += 8; i < length && char.IsWhiteSpace(input[i]); i++) { } if (i < length && input[i] == '"') { i++; while (i < length && input[i] != '"') { i = ((input[i] != '\\' || i + 1 >= length || input[i + 1] != '"') ? (i + 1) : (i + 2)); } if (i < length && input[i] == '"') { i++; if (i >= length || input[i] != ']') { addBracketBuilder.Append(input, num, i - num); addBracketBuilder.Append(']'); flag = true; } else { addBracketBuilder.Append(input, num, i - num + 1); i++; } } else { addBracketBuilder.Append(input, num, i - num); flag = true; } } else { addBracketBuilder.Append(input, num, i - num); flag = true; } } else { addBracketBuilder.Append(input[i]); i++; } } if (!flag && addBracketBuilder.Length == input.Length) { return input; } return addBracketBuilder.ToString(); } private static void DfLabelTextAddCall(dfLabel instance) { dfFontBase dfFontBase = FontManager.instance.dfFontBase; if ((Object)(object)dfFontBase != (Object)null && (Object)(object)instance.Font != (Object)(object)dfFontBase) { instance.Font = dfFontBase; dfFont val = (dfFont)(object)((dfFontBase is dfFont) ? dfFontBase : null); if (val != null) { instance.Atlas = val.Atlas; } if (config.DfTextScaleExpandThreshold >= 0f && instance.TextScale < config.DfTextScaleExpandThreshold) { instance.TextScale = config.DfTextScaleExpandToValue; } } TranslationManager.instance.AddTranslationRequest(instance.text, instance); } private static void DfButtonTextAddCall(dfButton instance) { dfFontBase dfFontBase = FontManager.instance.dfFontBase; if ((Object)(object)dfFontBase != (Object)null && (Object)(object)instance.Font != (Object)(object)dfFontBase) { instance.Font = dfFontBase; dfFont val = (dfFont)(object)((dfFontBase is dfFont) ? dfFontBase : null); if (val != null) { ((dfInteractiveBase)instance).Atlas = val.Atlas; } if (config.DfTextScaleExpandThreshold >= 0f && instance.TextScale < config.DfTextScaleExpandThreshold) { instance.TextScale = config.DfTextScaleExpandToValue; } } string text = AddMissingBracket(instance.text); if (text != instance.text) { instance.text = text; ((dfControl)instance).Invalidate(); } TranslationManager.instance.AddTranslationRequest(instance.text, instance); } } public class AzureTranslationService : ITranslationService { private AutoTranslateConfig config; private string endpoint = "https://api.cognitive.microsofttranslator.com"; private string action = "/translate"; private string version = "3.0"; private StringBuilder stringBuilder = new StringBuilder(1024); private ReusableStringReader pooledReader = new ReusableStringReader(); public AzureTranslationService(AutoTranslateConfig config) { this.config = config; } private List<string> ParseResponse(string responseJson) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_0047: Invalid comparison between Unknown and I4 //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Invalid comparison between Unknown and I4 //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected I4, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Invalid comparison between Unknown and I4 //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 List<string> list = Pools.listStringPool.Get(); try { pooledReader.Reset(responseJson); JsonTextReader val = new JsonTextReader((TextReader)pooledReader); try { bool flag = false; bool flag2 = false; bool flag3 = false; bool flag4 = false; int num = -1; int num2 = -1; int num3 = -1; while (((JsonReader)val).Read()) { JsonToken tokenType = ((JsonReader)val).TokenType; if ((int)tokenType <= 9) { switch (tokenType - 1) { case 1: if (!flag) { flag = true; num = ((JsonReader)val).Depth; } else if (flag && !flag2 && ((JsonReader)val).Path.EndsWith(".translations")) { flag2 = true; num2 = ((JsonReader)val).Depth; } continue; case 0: if (flag2 && ((JsonReader)val).Depth == num2 + 1) { flag3 = true; num3 = ((JsonReader)val).Depth; } continue; case 3: { string text = (string)((JsonReader)val).Value; if (flag3 && text == "text" && ((JsonReader)val).Depth == num3 + 1) { flag4 = true; } continue; } case 2: continue; } if ((int)tokenType == 9 && flag4 && flag3) { string text2 = ((JsonReader)val).Value?.ToString(); if (!string.IsNullOrEmpty(text2)) { list.Add(text2); } flag4 = false; } } else if ((int)tokenType != 13) { if ((int)tokenType == 14) { if (flag2 && ((JsonReader)val).Depth == num2) { flag2 = false; num2 = -1; } else if (flag && ((JsonReader)val).Depth == num) { flag = false; num = -1; } } } else if (flag3 && ((JsonReader)val).Depth == num3) { flag3 = false; num3 = -1; } } } finally { ((IDisposable)val)?.Dispose(); } if (list.Count == 0) { throw new InvalidOperationException("翻译结果为空!The translation result is empty!"); } return list; } catch (Exception) { Pools.listStringPool.Return(list); throw; } } public static string[] PreprocessText(List<string> inputTexts) { return inputTexts.Select((string text) => text.Replace("\r", "")).ToArray(); } private string BuildAzurePayloadJson(string[] preprocessedTexts) { stringBuilder.Length = 0; stringBuilder.Append("["); for (int i = 0; i < preprocessedTexts.Length; i++) { if (i > 0) { stringBuilder.Append(","); } stringBuilder.Append("{\"Text\":\""); TextProcessor.AppendEscapeJsonString(preprocessedTexts[i], stringBuilder); stringBuilder.Append("\"}"); } stringBuilder.Append("]"); return stringBuilder.ToString(); } private string BuildAzureRequestUrl(string endpoint, string action, string version, string targetLang, string sourceLang) { stringBuilder.Length = 0; stringBuilder.Append(endpoint).Append(action).Append("?api-version=") .Append(version) .Append("&to=") .Append(targetLang); if (!string.IsNullOrEmpty(sourceLang)) { stringBuilder.Append("&from=").Append(sourceLang); } return stringBuilder.ToString(); } public IEnumerator StartTranslation(List<string> texts, Action<List<string>> callback) { string[] preprocessedTexts = PreprocessText(texts); string s = BuildAzurePayloadJson(preprocessedTexts); string subscriptionKey = config.AzureSubscriptionKey; string region = config.AzureRegion; string requestUrl = BuildAzureRequestUrl(endpoint, action, version, config.AzureTargetLanguage, config.AzureSourceLanguage); int retryCount = 0; bool flag = false; byte[] bodyRaw = Encoding.UTF8.GetBytes(s); while (true) { if (flag) { yield return null; if (retryCount >= config.MaxRetryCount) { break; } retryCount++; Debug.Log((object)$"[{config.TranslationAPI}] 正在重试。。。尝试第 {retryCount} 次。Retrying... Attempt time {retryCount}."); yield return (object)new WaitForSecondsRealtime(config.RetryInterval); } UnityWebRequest request = new UnityWebRequest(requestUrl, "POST"); try { request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); request.SetRequestHeader("Ocp-Apim-Subscription-Key", subscriptionKey); request.SetRequestHeader("Ocp-Apim-Subscription-Region", region); yield return null; yield return request.SendWebRequest(); if (request.isNetworkError || request.isHttpError) { Debug.LogError((object)("请求失败 Request failed: " + request.error)); flag = true; continue; } string text = request.downloadHandler.text; List<string> translatedTexts = null; try { translatedTexts = ParseResponse(text); } catch (Exception ex) { Debug.LogError((object)("解析翻译结果失败 Failed to parse translation result:" + ex.Message)); Debug.LogError((object)("响应JSON Response JSON:\n" + text)); } if (translatedTexts != null && translatedTexts.Count > 0) { yield return null; callback?.Invoke(translatedTexts); yield break; } Debug.LogError((object)"翻译失败,未获得翻译结果!Translation failed, no translation result obtained!"); flag = true; } finally { ((IDisposable)request)?.Dispose(); } } Debug.LogError((object)$"[{config.TranslationAPI}] 多次尝试失败。已重试 {config.MaxRetryCount} 次。翻译中止!Multiple attempts failed. Retried {config.MaxRetryCount} times. translation aborted!"); callback?.Invoke(null); } } public class BaiduTranslationService : ITranslationService { private AutoTranslateConfig config; private string apiUrl = "https://fanyi-api.baidu.com/api/trans/vip/translate"; private ReusableStringReader pooledReader = new ReusableStringReader(); private StringBuilder stringBuilder = new StringBuilder(); public BaiduTranslationService(AutoTranslateConfig config) { this.config = config; } private List<string> ParseResponse(string responseJson) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_003b: Invalid comparison between Unknown and I4 //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Invalid comparison between Unknown and I4 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected I4, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Invalid comparison between Unknown and I4 //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Invalid comparison between Unknown and I4 //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Invalid comparison between Unknown and I4 List<string> list = Pools.listStringPool.Get(); try { pooledReader.Reset(responseJson); JsonTextReader val = new JsonTextReader((TextReader)pooledReader); try { bool flag = false; bool flag2 = false; bool flag3 = false; while (((JsonReader)val).Read()) { JsonToken tokenType = ((JsonReader)val).TokenType; if ((int)tokenType <= 9) { switch (tokenType - 1) { case 3: { string text = (string)((JsonReader)val).Value; if (text == "error_code") { ((JsonReader)val).Read(); string text2 = ((JsonReader)val).Value?.ToString(); if (string.IsNullOrEmpty(text2)) { continue; } string text3 = "Unknown error"; while (((JsonReader)val).Read() && (int)((JsonReader)val).TokenType != 13) { if ((int)((JsonReader)val).TokenType == 4 && (string)((JsonReader)val).Value == "error_msg") { ((JsonReader)val).Read(); text3 = ((JsonReader)val).Value?.ToString() ?? "Unknown error"; break; } } throw new InvalidOperationException("API请求失败 API request failed: " + text2 + " - " + text3); } if (text == "trans_result") { flag = true; } else if (flag2 && text == "dst") { flag3 = true; } continue; } case 0: if (flag) { flag2 = true; } continue; case 1: case 2: continue; } if ((int)tokenType == 9 && flag3 && flag2) { string text4 = ((JsonReader)val).Value?.ToString(); if (!string.IsNullOrEmpty(text4)) { list.Add(text4); } flag3 = false; } } else if ((int)tokenType != 13) { if ((int)tokenType == 14 && flag) { flag = false; } } else if (flag2) { flag2 = false; } } } finally { ((IDisposable)val)?.Dispose(); } if (list.Count == 0) { Pools.listStringPool.Return(list); throw new InvalidOperationException("翻译结果为空或缺少trans_result字段!Translation result is empty or missing 'trans_result' field!"); } return list; } catch (Exception ex) { Pools.listStringPool.Return(list); throw new InvalidOperationException("解析响应失败 Failed to parse response: " + ex.Message); } } public static string[] PreprocessText(List<string> inputTexts) { return inputTexts.Select((string text) => text.Replace("\n", "\\n").Replace("\r", "")).ToArray(); } private string JoinStringsWithSeparator(string[] strings, char separator) { if (strings == null || strings.Length == 0) { return string.Empty; } stringBuilder.Length = 0; for (int i = 0; i < strings.Length; i++) { if (i > 0) { stringBuilder.Append(separator); } stringBuilder.Append(strings[i]); } return stringBuilder.ToString(); } private string BuildBaiduApiUrl(string apiUrl, string queryText, string sourceLang, string targetLang, string appId, string salt, string sign) { stringBuilder.Length = 0; stringBuilder.Append(apiUrl).Append("?q=").Append(Uri.EscapeDataString(queryText)) .Append("&from=") .Append(sourceLang) .Append("&to=") .Append(targetLang) .Append("&appid=") .Append(appId) .Append("&salt=") .Append(salt) .Append("&sign=") .Append(sign); return stringBuilder.ToString(); } public IEnumerator StartTranslation(List<string> texts, Action<List<string>> callback) { string salt = Guid.NewGuid().ToString(); string[] strings = PreprocessText(texts); string text = JoinStringsWithSeparator(strings, '\n'); string sign = GenerateSign(config.BaiduAppId, text, salt, config.BaiduSecretKey); string url = BuildBaiduApiUrl(apiUrl, text, config.BaiduSourceLanguage, config.BaiduTargetLanguage, config.BaiduAppId, salt, sign); bool flag = false; int retryCount = 0; while (true) { if (flag) { yield return null; if (retryCount >= config.MaxRetryCount) { break; } retryCount++; Debug.Log((object)$"[{config.TranslationAPI}] 正在重试。。。尝试第 {retryCount} 次。Retrying... Attempt time {retryCount}."); yield return (object)new WaitForSecondsRealtime(config.RetryInterval); } UnityWebRequest request = UnityWebRequest.Get(url); try { yield return null; yield return request.SendWebRequest(); if (request.isNetworkError || request.isHttpError) { Debug.LogError((object)("请求失败 Request failed: " + request.error)); flag = true; continue; } string text2 = request.downloadHandler.text; List<string> translatedTexts = null; try { translatedTexts = ParseResponse(text2); } catch (Exception ex) { Debug.LogError((object)("解析翻译结果失败 Failed to parse translation result: " + ex.Message)); Debug.LogError((object)("响应JSON Response JSON: \n" + text2)); } if (translatedTexts != null && translatedTexts.Count > 0) { yield return null; callback?.Invoke(translatedTexts); yield break; } Debug.LogError((object)"翻译失败,未获得翻译结果!Translation failed, no translation result obtained!"); flag = true; } finally { ((IDisposable)request)?.Dispose(); } } Debug.LogError((object)$"[{config.TranslationAPI}] 多次尝试失败。已重试 {config.MaxRetryCount} 次。翻译中止!Multiple attempts failed. Retried {config.MaxRetryCount} times. translation aborted!"); callback?.Invoke(null); } private string GenerateSign(string appId, string query, string salt, string secretKey) { string s = appId + query + salt + secretKey; using MD5 mD = MD5.Create(); byte[] array = mD.ComputeHash(Encoding.UTF8.GetBytes(s)); StringBuilder stringBuilder = new StringBuilder(1024); byte[] array2 = array; foreach (byte b in array2) { stringBuilder.Append(b.ToString("x2")); } return stringBuilder.ToString(); } } public interface ITranslationService { IEnumerator StartTranslation(List<string> texts, Action<List<string>> callback); } public class LlmTranslationService : ITranslationService { private AutoTranslateConfig config; private StringBuilder builder = new StringBuilder(1024); private StringBuilder jsonBuilder = new StringBuilder(1024); private StringBuilder positionedBuilder = new StringBuilder(1024); private readonly string[] cachedSplitPattern = new string[1]; private StringBuilder payloadBuilder = new StringBuilder(1024); private ReusableStringReader pooledReader = new ReusableStringReader(); private static string cachedModelName; private static string cachedPrompt; private static string cachedTemperature; private static string cachedTopP; private static string cachedFrequencyPenalty; private static int cachedMaxTokens; private static int cachedTopK; private static string cachedExtraParams; public LlmTranslationService(AutoTranslateConfig config) { this.config = config; cachedSplitPattern[0] = config.LlmSplitText; cachedModelName = TextProcessor.EscapeJsonString(config.LlmName); cachedPrompt = TextProcessor.EscapeJsonString(config.LlmPrompt); cachedTemperature = config.LlmTemperature.ToString(CultureInfo.InvariantCulture); cachedTopP = config.LlmTopP.ToString(CultureInfo.InvariantCulture); cachedFrequencyPenalty = config.LlmFrequencyPenalty.ToString(CultureInfo.InvariantCulture); cachedMaxTokens = config.LlmMaxTokens; cachedTopK = config.LlmTopK; if (!string.IsNullOrEmpty(config.LlmExtraParametersJson)) { string text = config.LlmExtraParametersJson.Trim(); if (text.StartsWith("{") && text.EndsWith("}")) { cachedExtraParams = text.Substring(1, text.Length - 2); } else { cachedExtraParams = text; } } else { cachedExtraParams = null; } } private List<string> ParseJsonResponse(string content) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Invalid comparison between Unknown and I4 //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Invalid comparison between Unknown and I4 //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected I4, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Invalid comparison between Unknown and I4 //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Invalid comparison between Unknown and I4 if (string.IsNullOrEmpty(content)) { Debug.LogError((object)"解析JSON失败: 内容为空。Failed to parse JSON: Content is empty."); return null; } List<string> list = Pools.listStringPool.Get(); try { pooledReader.Reset(content); JsonTextReader val = new JsonTextReader((TextReader)pooledReader); try { int num = -1; bool flag = false; bool flag2 = false; bool flag3 = false; while (((JsonReader)val).Read()) { JsonToken tokenType = ((JsonReader)val).TokenType; if ((int)tokenType <= 9) { switch (tokenType - 1) { case 1: flag = true; continue; case 0: if (flag) { flag2 = true; num = ((JsonReader)val).Depth; } continue; case 3: if (flag2 && (string)((JsonReader)val).Value == "text" && ((JsonReader)val).Depth == num + 1) { flag3 = true; } continue; case 2: continue; } if ((int)tokenType == 9 && flag3 && flag2) { string text = ((JsonReader)val).Value?.ToString(); if (!string.IsNullOrEmpty(text)) { list.Add(text); } flag3 = false; } } else if ((int)tokenType != 13) { if ((int)tokenType == 14 && flag) { flag = false; } } else if (flag2 && ((JsonReader)val).Depth == num) { flag2 = false; num = -1; flag3 = false; } } } finally { ((IDisposable)val)?.Dispose(); } if (list.Count == 0) { Debug.LogError((object)"解析JSON失败: 未找到任何 'text' 字段。 Failed to parse JSON: No 'text' field found."); Pools.listStringPool.Return(list); return null; } return list; } catch (Exception ex) { Debug.LogError((object)("解析JSON失败 Failed to parse JSON: " + ex.Message)); Pools.listStringPool.Return(list); return null; } } private List<string> ParseSplittedResponse(string response) { if (string.IsNullOrEmpty(response)) { return null; } List<string> list = Pools.listStringPool.Get(); try { string llmSplitText = config.LlmSplitText; int length = llmSplitText.Length; int num = 0; while (num < response.Length) { int num2 = TextProcessor.IndexOfString(response, llmSplitText, num); if (num2 == -1) { num2 = response.Length; } if (num2 > num) { string text = response.Substring(num, num2 - num); if (!string.IsNullOrEmpty(text)) { list.Add(text); } } num = num2 + length; } return list; } catch (Exception arg) { Debug.LogError((object)$"分割字符串时发生意外错误 An unexpected error occurred while splitting the string: {arg}"); Pools.listStringPool.Return(list); return null; } } private List<string> ParsePositionedResponse(string response) { if (string.IsNullOrEmpty(response)) { return null; } if (string.IsNullOrEmpty(config.LlmPositionText) || string.IsNullOrEmpty(config.LlmSegmentText)) { throw new ArgumentException("标记不能为空。The tag cannot be empty."); } List<string> list = Pools.listStringPool.Get(); try { string llmPositionText = config.LlmPositionText; string llmSegmentText = config.LlmSegmentText; int length = response.Length; int num = 0; int length2 = llmPositionText.Length; int length3 = llmSegmentText.Length; while (num < length) { int num2 = TextProcessor.IndexOfString(response, llmPositionText, num); if (num2 == -1) { if (TextProcessor.HasNonWhitespace(response, num, length - num)) { string str = response.Substring(num); list.Add(TextProcessor.TrimOnlyIfNeeded(str)); } break; } if (num2 > num && TextProcessor.HasNonWhitespace(response, num, num2 - num)) { string item = TextProcessor.TrimOnlyIfNeeded(response.Substring(num, num2 - num)); list.Add(item); } int i; for (i = num2 + length2; i < length && char.IsDigit(response[i]); i++) { } num = ((i + length3 > length || !TextProcessor.StartsWithString(response, i, llmSegmentText)) ? i : (i + length3)); } if (list.Count > 0) { return list; } Pools.listStringPool.Return(list); return null; } catch (Exception arg) { Debug.LogError((object)$"解析定位响应时发生错误 An error occurred while parsing the positioning response: {arg}"); Pools.listStringPool.Return(list); return null; } } private List<string> ParseFormattedResponse(string responseJson, List<string> texts) { string text = ParseResponse(responseJson); List<string> list = null; try { if (string.IsNullOrEmpty(text)) { throw new InvalidOperationException("翻译结果为空!The translation result is empty!"); } switch (config.LlmDataFormat) { case AutoTranslateModule.LlmDataFormatType.Json: list = ParseJsonResponse(text); break; case AutoTranslateModule.LlmDataFormatType.Split: list = ParseSplittedResponse(text); break; case AutoTranslateModule.LlmDataFormatType.Positioned: list = ParsePositionedResponse(text); break; } if (list == null || list.Count == 0) { throw new InvalidOperationException("翻译结果为空!The translation result is empty!"); } if (list.Count != texts.Count) { Debug.LogError((object)"翻译结果数量与请求数量不匹配!The number of translation results does not match the number of requests!"); Debug.LogError((object)"请求 Requests:"); foreach (string text2 in texts) { Debug.Log((object)(" " + text2)); } Debug.LogError((object)"结果 Results:"); foreach (string item in list) { Debug.Log((object)(" " + item)); } throw new InvalidOperationException("翻译结果数量与请求数量不匹配!The number of translation results does not match the number of requests!"); } return list; } catch (Exception) { if (list != null) { Pools.listStringPool.Return(list); } throw; } } public string ParseResponse(string responseJson) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0150: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0047: Expected I4, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Invalid comparison between Unknown and I4 //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 try { pooledReader.Reset(responseJson); JsonTextReader val = new JsonTextReader((TextReader)pooledReader); try { int num = -1; bool flag = false; bool flag2 = false; bool flag3 = false; while (((JsonReader)val).Read()) { JsonToken tokenType = ((JsonReader)val).TokenType; switch (tokenType - 1) { case 1: if (((JsonReader)val).Path == "choices") { flag = true; } continue; case 0: if (flag && ((JsonReader)val).Path == "choices[0]") { flag2 = true; } else if (flag2 && ((JsonReader)val).Path == "choices[0].message") { flag3 = true; num = ((JsonReader)val).Depth + 1; } continue; case 3: if (flag3 && (string)((JsonReader)val).Value == "content" && ((JsonReader)val).Depth == num) { ((JsonReader)val).Read(); string text = ((JsonReader)val).Value?.ToString(); if (!string.IsNullOrEmpty(text)) { return text; } throw new InvalidOperationException("翻译结果为空!The translation result is empty!"); } continue; case 2: continue; } if ((int)tokenType != 13) { if ((int)tokenType == 14 && flag) { flag = false; } } else if (flag3) { flag3 = false; num = -1; } else if (flag2) { flag2 = false; } } } finally { ((IDisposable)val)?.Dispose(); } throw new InvalidOperationException("翻译结果为空!The translation result is empty!"); } catch (JsonReaderException val2) { JsonReaderException innerException = val2; throw new InvalidOperationException("响应的JSON格式无效 The JSON format of the response is invalid: ", (Exception?)(object)innerException); } catch (Exception ex) { throw new InvalidOperationException("解析响应失败 Failed to parse response: " + ex.Message); } } private string ReplaceQuotesWithChinese(string source) { builder.Length = 0; bool flag = false; bool flag2 = false; foreach (char c in source) { switch (c) { case '"': builder.Append(flag ? '”' : '“'); flag = !flag; break; case '\'': builder.Append(flag2 ? '’' : '‘'); flag2 = !flag2; break; default: builder.Append(c); break; } } return builder.ToString(); } private string PreprocessQuotes(string source) { AutoTranslateModule.LlmQuotePreprocessType llmQuotePreprocess = config.LlmQuotePreprocess; if (llmQuotePreprocess != 0 && llmQuotePreprocess == AutoTranslateModule.LlmQuotePreprocessType.Chinese) { return ReplaceQuotesWithChinese(source); } return source; } private string ConvertListToJson(List<string> texts) { jsonBuilder.Length = 0; jsonBuilder.Append("["); for (int i = 0; i < texts.Count; i++) { if (i > 0) { jsonBuilder.Append(", "); } int value = i + 1; jsonBuilder.Append("{\"id\": ").Append(value).Append(", \"text\": \""); TextProcessor.AppendEscapeJsonString(PreprocessQuotes(texts[i]), jsonBuilder); jsonBuilder.Append("\"}"); } jsonBuilder.Append("]"); return jsonBuilder.ToString(); } private string ConvertListToSplitted(List<string> texts) { if (texts == null || texts.Count == 0) { return string.Empty; } return string.Join(config.LlmSplitText, texts.ToArray()).Replace("\r", ""); } private string ConvertListToPositioned(List<string> texts) { if (texts == null || texts.Count == 0) { return string.Empty; } positionedBuilder.Length = 0; for (int i = 0; i < texts.Count; i++) { positionedBuilder.Append("<!pos!>").Append(i + 1).Append("<!seg!>") .Append(texts[i]); positionedBuilder.Replace("\r", ""); } return positionedBuilder.ToString(); } private string ConvertListToFormatted(List<string> texts) { return config.LlmDataFormat switch { AutoTranslateModule.LlmDataFormatType.Json => ConvertListToJson(texts), AutoTranslateModule.LlmDataFormatType.Split => ConvertListToSplitted(texts), _ => ConvertListToPositioned(texts), }; } private string BuildTranslationRequestJson(string formattedTexts) { payloadBuilder.Length = 0; payloadBuilder.Append("{\"model\":\"").Append(cachedModelName).Append("\",\"messages\":[{\"role\":\"system\",\"content\":\"") .Append(cachedPrompt) .Append("\"},{\"role\":\"user\",\"content\":\"") .Append(formattedTexts) .Append("\"}],\"temperature\":") .Append(cachedTemperature) .Append(",\"max_tokens\":") .Append(cachedMaxTokens) .Append(",\"top_p\":") .Append(cachedTopP); if (cachedTopK > 0) { payloadBuilder.Append(",\"top_k\":").Append(cachedTopK); } payloadBuilder.Append(",\"frequency_penalty\":").Append(cachedFrequencyPenalty).Append(",\"n\":1"); if (!string.IsNullOrEmpty(cachedExtraParams)) { payloadBuilder.Append(',').Append(cachedExtraParams); } payloadBuilder.Append('}'); return payloadBuilder.ToString(); } public IEnumerator StartSingleTranslation(List<string> texts, Action<List<string>> callback) { string payloadJson = BuildTranslationRequestJson(TextProcessor.EscapeJsonString(ConvertListToFormatted(texts))); int re