Decompiled source of Auto Translate v1.1.1

AutoTranslate.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 Newtonsoft.Json.Linq;
using SGUI;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[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.1")]
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.1";

	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_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Expected O, but got Unknown
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: 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.1 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.1 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.1 started successfully.", "#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_09ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_09b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b7f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b84: 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
		{
			TranslationAPI = TranslationAPI.Value,
			ToggleTranslationKeyBinding = ToggleTranslationKeyBinding.Value,
			FilterForFullTextNeedToTranslate = FilterForFullTextNeedToTranslate.Value,
			RegexForFullTextNeedToTranslate = RegexForFullTextNeedToTranslate.Value,
			FilterForEachLineNeedToTranslate = FilterForEachLineNeedToTranslate.Value,
			RegexForEachLineNeedToTranslate = RegexForEachLineNeedToTranslate.Value,
			FilterForIgnoredSubstringWithinText = FilterForIgnoredSubstringWithinText.Value,
			RegexForIgnoredSubstringWithinText = RegexForIgnoredSubstringWithinText.Value,
			MaxBatchCharacterCount = MaxBatchCharacterCount.Value,
			MaxBatchTextCount = MaxBatchTextCount.Value,
			MaxRetryCount = MaxRetryCount.Value,
			RetryInterval = ((RetryInterval.Value > 0f) ? RetryInterval.Value : 2f),
			TranslationCacheCapacity = TranslationCacheCapacity.Value,
			PresetTranslations = PresetTranslations.Value,
			CachedTranslations = CachedTranslations.Value,
			AutoSaveCachedTranslationsUponQuit = AutoSaveCachedTranslationsUponQuit.Value,
			LogRequestedTexts = LogRequestedTexts.Value,
			OverrideFont = OverrideFont.Value,
			FontAssetBundleName = FontAssetBundleName.Value,
			CustomDfFontName = CustomDfFontName.Value,
			CustomTk2dFontName = CustomTk2dFontName.Value,
			OverrideDfTokenizer = OverrideDfTokenizer.Value,
			RegexForDfTokenizer = RegexForDfTokenizer.Value,
			DfTextScaleExpandThreshold = DfTextScaleExpandThreshold.Value,
			DfTextScaleExpandToValue = DfTextScaleExpandToValue.Value,
			ShowRequestedCharacterCount = ShowRequestedCharacterCount.Value,
			RequestedCharacterCountAlertThreshold = RequestedCharacterCountAlertThreshold.Value,
			ToggleRequestedCharacterCountKeyBinding = ToggleRequestedCharacterCountKeyBinding.Value,
			CountLabelAnchor = CountLabelAnchor.Value,
			CountLabelPivot = CountLabelPivot.Value,
			TranslateTextsOfItemTipsMod = TranslateTextsOfItemTipsMod.Value,
			OverrideItemTipsTokenizer = OverrideItemTipsTokenizer.Value,
			RegexForItemTipsModTokenizer = RegexForItemTipsModTokenizer.Value,
			ItemTipsFontScale = ((ItemTipsFontScale.Value > 0f) ? ItemTipsFontScale.Value : 1f),
			ItemTipsBackgroundWidthScale = ((ItemTipsBackgroundWidthScale.Value > 0f) ? ItemTipsBackgroundWidthScale.Value : 1f),
			ItemTipsLineHeightScale = ((ItemTipsLineHeightScale.Value > 0f) ? ItemTipsLineHeightScale.Value : 1f),
			ItemTipsAnchor = ItemTipsAnchor.Value,
			ItemTipsPivot = ItemTipsPivot.Value,
			ItemTipsSourceBitmapFontBaseLine = ItemTipsSourceBitmapFontBaseLine.Value,
			TencentSecretId = TencentSecretId.Value,
			TencentSecretKey = TencentSecretKey.Value,
			TencentSourceLanguage = TencentSourceLanguage.Value,
			TencentTargetLanguage = TencentTargetLanguage.Value,
			TencentRegion = TencentRegion.Value,
			BaiduAppId = BaiduAppId.Value,
			BaiduSecretKey = BaiduSecretKey.Value,
			BaiduSourceLanguage = BaiduSourceLanguage.Value,
			BaiduTargetLanguage = BaiduTargetLanguage.Value,
			AzureSubscriptionKey = AzureSubscriptionKey.Value,
			AzureSourceLanguage = AzureSourceLanguage.Value,
			AzureTargetLanguage = AzureTargetLanguage.Value,
			AzureRegion = AzureRegion.Value,
			LlmBaseUrl = LlmBaseUrl.Value,
			LlmApiKey = LlmApiKey.Value,
			LlmName = LlmName.Value,
			LlmPrompt = LlmPrompt.Value,
			LlmMaxTokens = LlmMaxTokens.Value,
			LlmTemperature = LlmTemperature.Value,
			LlmTopP = LlmTopP.Value,
			LlmTopK = LlmTopK.Value,
			LlmFrequencyPenalty = LlmFrequencyPenalty.Value,
			LlmExtraParametersJson = LlmExtraParametersJson.Value,
			LlmQuotePreprocess = LlmQuotePreprocess.Value,
			LlmDataFormat = LlmDataFormat.Value,
			LlmSplitText = LlmSplitText.Value,
			LlmPositionText = LlmPositionText.Value,
			LlmSegmentText = LlmSegmentText.Value
		};
		autoTranslateConfig.CheckConfig();
		return autoTranslateConfig;
	}

	private void DoOptionalPatches()
	{
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Expected O, but got Unknown
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Expected O, but got Unknown
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Expected O, but got Unknown
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Expected O, but got Unknown
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Expected O, but got Unknown
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Expected O, but got Unknown
		//IL_0231: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Expected O, but got Unknown
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ac: Expected O, but got Unknown
		//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ed: Expected O, but got Unknown
		//IL_032c: Unknown result type (might be due to invalid IL or missing references)
		//IL_033a: Expected O, but got Unknown
		//IL_0371: Unknown result type (might be due to invalid IL or missing references)
		//IL_037b: 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);
			Type type = AccessTools.TypeByName("ItemTipsMod.Label");
			MethodInfo methodInfo11 = AccessTools.Method(type, "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)
		{
			try
			{
				if (__instance.tokens != null)
				{
					if ((object)__instance.tokens[0].Source == text)
					{
						return false;
					}
					__instance.tokens.ReleaseItems();
					__instance.tokens.Release();
				}
				__instance.tokens = FontManager.instance?.Tokenize(text);
				for (int i = 0; i < __instance.tokens.Count; i++)
				{
					__instance.calculateTokenRenderSize(__instance.tokens[i]);
				}
			}
			finally
			{
			}
			return false;
		}
	}

	public class DynamicFontRendererCalculateLinebreaksPatchClass
	{
		[HarmonyILManipulator]
		public static void CalculateLinebreaksPatch(ILContext ctx)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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)
		{
			try
			{
				if (__instance.tokens != null)
				{
					if ((object)__instance.tokens[0].Source == text)
					{
						__result = __instance.tokens;
						return false;
					}
					__instance.tokens.ReleaseItems();
					__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;
			}
			finally
			{
			}
			return false;
		}
	}

	public class BitmappedFontRendererCalculateLinebreaksPatchClass
	{
		public static void CalculateLinebreaksPatch(ILContext ctx)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_003d: 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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_003d: 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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_003d: 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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_003d: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_003d: 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)
		{
			DefaultLabelController fieldValueInEnumerator = GetFieldValueInEnumerator<DefaultLabelController>(selfObject, "this");
			return ((dfControl)fieldValueInEnumerator.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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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;
			}
		}
	}

	private static AutoTranslateConfig config = AutoTranslateModule.instance.config;

	private static readonly Regex spritePattern = new Regex("(\\[sprite\\s+\"[^\"]*\")(?!\\])", RegexOptions.Compiled);

	public static void EmitCall<T>(this ILCursor iLCursor, string methodName, Type[] parameters = null, Type[] generics = null)
	{
		//IL_0015: 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)
	{
		return spritePattern.Replace(input, (Match match) => match.Groups[1].Value + "]");
	}

	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";

	public AzureTranslationService(AutoTranslateConfig config)
	{
		this.config = config;
	}

	private string[] ParseResponse(string responseJson)
	{
		//IL_000d: Expected O, but got Unknown
		JArray val;
		try
		{
			val = JArray.Parse(responseJson);
		}
		catch (JsonReaderException val2)
		{
			JsonReaderException innerException = val2;
			throw new InvalidOperationException("响应的JSON格式无效 The JSON format of the response is invalid: ", (Exception?)(object)innerException);
		}
		List<string> list = new List<string>();
		foreach (JToken item in val)
		{
			JToken obj = item[(object)"translations"];
			JArray val3 = (JArray)(object)((obj is JArray) ? obj : null);
			if (val3 == null)
			{
				continue;
			}
			foreach (JToken item2 in val3)
			{
				list.Add(((object)item2[(object)"text"]).ToString());
			}
		}
		if (list.Count == 0)
		{
			throw new InvalidOperationException("翻译结果为空!The translation result is empty!");
		}
		return list.ToArray();
	}

	public static string[] PreprocessText(List<string> inputTexts)
	{
		return inputTexts.Select((string text) => text.Replace("\r", "")).ToArray();
	}

	public IEnumerator StartTranslation(List<string> texts, Action<string[]> callback)
	{
		string[] preprocessedTexts = PreprocessText(texts);
		var payload = preprocessedTexts.Select((string text) => new
		{
			Text = text
		}).ToArray();
		string payloadJson = JsonConvert.SerializeObject((object)payload);
		string subscriptionKey = config.AzureSubscriptionKey;
		string region = config.AzureRegion;
		string requestUrl = endpoint + action + "?api-version=" + version + "&to=" + config.AzureTargetLanguage;
		if (config.AzureSourceLanguage != string.Empty)
		{
			requestUrl = requestUrl + "&from=" + config.AzureSourceLanguage;
		}
		int retryCount = 0;
		bool needRetry = false;
		while (true)
		{
			if (needRetry)
			{
				if (retryCount >= config.MaxRetryCount)
				{
					break;
				}
				retryCount++;
				Debug.Log((object)$"正在重试。。。尝试第 {retryCount} 次。Retrying... Attempt time {retryCount}.");
				needRetry = false;
				yield return (object)new WaitForSecondsRealtime(config.RetryInterval);
			}
			UnityWebRequest request = new UnityWebRequest(requestUrl, "POST");
			try
			{
				byte[] bodyRaw = Encoding.UTF8.GetBytes(payloadJson);
				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 request.SendWebRequest();
				if (request.isNetworkError || request.isHttpError)
				{
					Debug.LogError((object)("请求失败 Request failed: " + request.error));
					needRetry = true;
					continue;
				}
				string responseJson = request.downloadHandler.text;
				string[] translatedTexts;
				try
				{
					translatedTexts = ParseResponse(responseJson);
				}
				catch (Exception ex2)
				{
					Exception ex = ex2;
					Debug.LogError((object)("解析翻译结果失败 Failed to parse translation result:" + ex.Message));
					Debug.LogError((object)("响应JSON Response JSON:\n" + responseJson));
					needRetry = true;
					goto end_IL_027d;
				}
				if (translatedTexts != null)
				{
					callback?.Invoke(translatedTexts);
					yield break;
				}
				Debug.LogError((object)"翻译失败,未获得翻译结果!Translation failed, no translation result obtained!");
				needRetry = true;
				yield break;
				end_IL_027d:;
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
		}
		Debug.LogError((object)$"多次尝试失败。已重试 {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";

	public BaiduTranslationService(AutoTranslateConfig config)
	{
		this.config = config;
	}

	private string[] ParseResponse(string responseJson)
	{
		//IL_000d: Expected O, but got Unknown
		JObject val;
		try
		{
			val = JObject.Parse(responseJson);
		}
		catch (JsonReaderException val2)
		{
			JsonReaderException innerException = val2;
			throw new InvalidOperationException("响应的JSON格式无效 The JSON format of the response is invalid: ", (Exception?)(object)innerException);
		}
		if (val["error_code"] != null)
		{
			string text = ((object)val["error_code"])?.ToString();
			string text2 = ((object)val["error_msg"])?.ToString();
			throw new InvalidOperationException("API请求失败 API request failed: " + text + " - " + text2);
		}
		JToken val3 = val["trans_result"];
		if (val3 == null)
		{
			throw new InvalidOperationException("响应JSON中缺少trans_result字段!The 'trans_desult' field is missing in the response JSON!");
		}
		if (!((IEnumerable<JToken>)val3).Any())
		{
			throw new InvalidOperationException("翻译结果为空!The translation result is empty!");
		}
		return ((IEnumerable<JToken>)val3).Select((JToken result) => ((object)result[(object)"dst"])?.ToString() ?? string.Empty).ToArray();
	}

	public static string[] PreprocessText(List<string> inputTexts)
	{
		return inputTexts.Select((string text) => text.Replace("\n", "\\n").Replace("\r", "")).ToArray();
	}

	public IEnumerator StartTranslation(List<string> texts, Action<string[]> callback)
	{
		string salt = Guid.NewGuid().ToString();
		string[] preprocessedTexts = PreprocessText(texts);
		string sign = GenerateSign(config.BaiduAppId, string.Join("\n", preprocessedTexts), salt, config.BaiduSecretKey);
		string url = apiUrl + "?q=" + Uri.EscapeDataString(string.Join("\n", preprocessedTexts)) + "&from=" + config.BaiduSourceLanguage + "&to=" + config.BaiduTargetLanguage + "&appid=" + config.BaiduAppId + "&salt=" + salt + "&sign=" + sign;
		bool needRetry = false;
		int retryCount = 0;
		while (true)
		{
			if (needRetry)
			{
				if (retryCount >= config.MaxRetryCount)
				{
					break;
				}
				retryCount++;
				Debug.Log((object)$"正在重试。。。尝试第 {retryCount} 次。Retrying... Attempt time {retryCount}.");
				needRetry = false;
				yield return (object)new WaitForSecondsRealtime(config.RetryInterval);
			}
			UnityWebRequest request = UnityWebRequest.Get(url);
			try
			{
				yield return request.SendWebRequest();
				if (request.isNetworkError || request.isHttpError)
				{
					Debug.LogError((object)("请求失败 Request failed: " + request.error));
					needRetry = true;
					continue;
				}
				string responseJson = request.downloadHandler.text;
				string[] translatedTexts;
				try
				{
					translatedTexts = ParseResponse(responseJson);
				}
				catch (Exception ex2)
				{
					Exception ex = ex2;
					Debug.LogError((object)("解析翻译结果失败 Failed to parse translation result:" + ex.Message));
					Debug.LogError((object)("响应JSON Response JSON:\n" + responseJson));
					needRetry = true;
					goto end_IL_027b;
				}
				if (translatedTexts != null)
				{
					callback?.Invoke(translatedTexts);
					yield break;
				}
				Debug.LogError((object)"翻译失败,未获得翻译结果!Translation failed, no translation result obtained!");
				needRetry = true;
				yield break;
				end_IL_027b:;
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
		}
		Debug.LogError((object)$"多次尝试失败。已重试 {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();
		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<string[]> callback);
}
public class LlmTranslationService : ITranslationService
{
	private AutoTranslateConfig config;

	private StringBuilder builder = new StringBuilder();

	private StringBuilder jsonBuilder = new StringBuilder();

	private StringBuilder positionedBuilder = new StringBuilder();

	private readonly string[] cachedSplitPattern = new string[1];

	private static Regex positionedResponseRegex;

	public LlmTranslationService(AutoTranslateConfig config)
	{
		this.config = config;
		cachedSplitPattern[0] = config.LlmSplitText;
	}

	private string[] ParseJsonResponse(string content)
	{
		//IL_0053: Expected O, but got Unknown
		List<string> list = new List<string>();
		try
		{
			JArray val = JArray.Parse(content);
			foreach (JToken item in val)
			{
				list.Add(((object)item[(object)"text"]).ToString());
			}
		}
		catch (JsonReaderException val2)
		{
			JsonReaderException val3 = val2;
			Debug.LogError((object)("解析 'content' 字段时失败: " + ((Exception)(object)val3).Message));
		}
		return list.ToArray();
	}

	private string[] ParseSplittedResponse(string response)
	{
		if (string.IsNullOrEmpty(response))
		{
			return null;
		}
		string[] result = null;
		try
		{
			result = response.Split(cachedSplitPattern, StringSplitOptions.RemoveEmptyEntries);
		}
		catch (Exception arg)
		{
			Debug.LogError((object)$"分割字符串时发生意外错误。An unexpected error occurred while splitting the string.{arg}");
		}
		return result;
	}

	private 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.");
		}
		string llmPositionText = config.LlmPositionText;
		string llmSegmentText = config.LlmSegmentText;
		List<string> list = new List<string>();
		int length = response.Length;
		int num = 0;
		int length2 = llmPositionText.Length;
		int length3 = llmSegmentText.Length;
		while (num < length)
		{
			int num2 = response.IndexOf(llmPositionText, num, StringComparison.OrdinalIgnoreCase);
			if (num2 == -1)
			{
				string text = response.Substring(num);
				if (!IsNullOrWhiteSpace(text))
				{
					list.Add(text.Trim());
				}
				break;
			}
			if (num2 > num)
			{
				string text2 = response.Substring(num, num2 - num);
				if (!IsNullOrWhiteSpace(text2))
				{
					list.Add(text2.Trim());
				}
			}
			int i;
			for (i = num2 + length2; i < length && response[i] >= '0' && response[i] <= '9'; i++)
			{
			}
			num = ((i + length3 > length || string.Compare(response, i, llmSegmentText, 0, length3, StringComparison.OrdinalIgnoreCase) != 0) ? i : (i + length3));
		}
		return (list.Count > 0) ? list.ToArray() : null;
	}

	private static bool IsNullOrWhiteSpace(string value)
	{
		return string.IsNullOrEmpty(value) || value.Trim().Length == 0;
	}

	private string[] ParseFormattedResponse(string responseJson, List<string> texts)
	{
		string text = ParseResponse(responseJson);
		string[] array = null;
		if (!string.IsNullOrEmpty(text))
		{
			switch (config.LlmDataFormat)
			{
			case AutoTranslateModule.LlmDataFormatType.Json:
				array = ParseJsonResponse(text);
				break;
			case AutoTranslateModule.LlmDataFormatType.Split:
				array = ParseSplittedResponse(text);
				break;
			case AutoTranslateModule.LlmDataFormatType.Positioned:
				array = ParsePositionedResponse(text);
				break;
			}
		}
		if (array == null || array.Length == 0)
		{
			throw new InvalidOperationException("翻译结果为空!The translation result is empty!");
		}
		if (array.Length != texts.Count)
		{
			Debug.LogError((object)"翻译结果数量与请求数量不匹配!The number of translation results does not match the number of requests!");
			Debug.LogError((object)"请求 Requests:");
			foreach (string text3 in texts)
			{
				Debug.Log((object)("      " + text3));
			}
			Debug.LogError((object)"结果 Results:");
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				Debug.Log((object)("      " + text2));
			}
			throw new InvalidOperationException("翻译结果数量与请求数量不匹配!The number of translation results does not match the number of requests!");
		}
		return array;
	}

	private string ParseResponse(string responseJson)
	{
		//IL_000d: Expected O, but got Unknown
		JObject val;
		try
		{
			val = JObject.Parse(responseJson);
		}
		catch (JsonReaderException val2)
		{
			JsonReaderException innerException = val2;
			throw new InvalidOperationException("响应的JSON格式无效 The JSON format of the response is invalid: ", (Exception?)(object)innerException);
		}
		string text = null;
		JToken obj = val["choices"];
		JArray val3 = (JArray)(object)((obj is JArray) ? obj : null);
		if (val3 != null)
		{
			JToken obj2 = val3[0][(object)"message"];
			string text2 = ((obj2 == null) ? null : ((object)obj2[(object)"content"])?.ToString());
			if (!string.IsNullOrEmpty(text2))
			{
				text = text2;
			}
		}
		if (text == null)
		{
			throw new InvalidOperationException("翻译结果为空!The translation result is empty!");
		}
		return text;
	}

	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;
		AutoTranslateModule.LlmQuotePreprocessType llmQuotePreprocessType = llmQuotePreprocess;
		if (llmQuotePreprocessType != 0 && llmQuotePreprocessType == AutoTranslateModule.LlmQuotePreprocessType.Chinese)
		{
			return ReplaceQuotesWithChinese(source);
		}
		return source.Replace("\"", "\\\"");
	}

	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\": \"")
				.Append(PreprocessQuotes(texts[i].Replace("\\\\", "\\").Replace("\r", "")))
				.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]);
		}
		return positionedBuilder.ToString().Replace("\r", "");
	}

	private string ConvertListToFormatted(List<string> texts)
	{
		return config.LlmDataFormat switch
		{
			AutoTranslateModule.LlmDataFormatType.Json => ConvertListToJson(texts), 
			AutoTranslateModule.LlmDataFormatType.Split => ConvertListToSplitted(texts), 
			_ => ConvertListToPositioned(texts), 
		};
	}

	public IEnumerator StartSingleTranslation(List<string> texts, Action<string[]> callback)
	{
		JObject val = new JObject();
		val.Add("model", JToken.op_Implicit(config.LlmName));
		JArray val2 = new JArray();
		JObject val3 = new JObject();
		val3.Add("role", JToken.op_Implicit("system"));
		val3.Add("content", JToken.op_Implicit(config.LlmPrompt));
		val2.Add((JToken)val3);
		JObject val4 = new JObject();
		val4.Add("role", JToken.op_Implicit("user"));
		val4.Add("content", JToken.op_Implicit(ConvertListToFormatted(texts)));
		val2.Add((JToken)val4);
		val.Add("messages", (JToken)val2);
		val.Add("temperature", JToken.op_Implicit(config.LlmTemperature));
		val.Add("max_tokens", JToken.op_Implicit(config.LlmMaxTokens));
		val.Add("top_p", JToken.op_Implicit(config.LlmTopP));
		val.Add("top_k", JToken.op_Implicit(config.LlmTopK));
		val.Add("frequency_penalty", JToken.op_Implicit(config.LlmFrequencyPenalty));
		val.Add("n", JToken.op_Implicit(1));
		JObject jsonObject = val;
		if (!string.IsNullOrEmpty(config.LlmExtraParametersJson))
		{
			JObject extraObj = JObject.Parse(config.LlmExtraParametersJson);
			foreach (JProperty property in extraObj.Properties())
			{
				jsonObject[property.Name] = property.Value;
			}
		}
		string payloadJson = ((JToken)jsonObject).ToString((Formatting)0, (JsonConverter[])(object)new JsonConverter[0]);
		string requestUrl = config.LlmBaseUrl ?? "";
		int retryCount = 0;
		bool needRetry = false;
		while (true)
		{
			if (needRetry)
			{
				if (retryCount >= config.MaxRetryCount)
				{
					break;
				}
				retryCount++;
				Debug.Log((object)$"正在重试。。。尝试第 {retryCount} 次。Retrying... Attempt time {retryCount}.");
				needRetry = false;
				yield return (object)new WaitForSecondsRealtime(config.RetryInterval);
			}
			UnityWebRequest request = new UnityWebRequest(requestUrl, "POST");
			try
			{
				byte[] bodyRaw = Encoding.UTF8.GetBytes(payloadJson);
				request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
				request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
				request.SetRequestHeader("Content-Type", "application/json");
				request.SetRequestHeader("Authorization", "Bearer " + config.LlmApiKey);
				yield return request.SendWebRequest();
				if (request.isNetworkError || request.isHttpError)
				{
					Debug.LogError((object)("请求失败 Request failed: " + request.error));
					needRetry = true;
					continue;
				}
				string responseJson = request.downloadHandler.text;
				string[] translatedTexts;
				try
				{
					translatedTexts = ParseFormattedResponse(responseJson, texts);
				}
				catch (Exception ex2)
				{
					Exception ex = ex2;
					Debug.LogError((object)("解析翻译结果失败 Failed to parse translation result: " + ex.Message));
					Debug.LogError((object)("响应JSON Response JSON:\n" + responseJson));
					needRetry = true;
					goto end_IL_03cd;
				}
				if (translatedTexts != null && translatedTexts.Length != 0)
				{
					callback?.Invoke(translatedTexts);
					yield break;
				}
				Debug.LogError((object)"翻译失败,未获得翻译结果!Translation failed, no translation result obtained!");
				needRetry = true;
				yield break;
				end_IL_03cd:;
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
		}
		Debug.LogError((object)$"多次尝试失败。已重试 {config.MaxRetryCount} 次。翻译中止!Multiple attempts failed. Retried {config.MaxRetryCount} times. Translation aborted!");
		callback?.Invoke(null);
	}

	public IEnumerator StartTranslation(List<string> texts, Action<string[]> callback)
	{
		if (config.LlmDataFormat == AutoTranslateModule.LlmDataFormatType.Parallel)
		{
			yield return ((MonoBehaviour)TranslationManager.instance).StartCoroutine(StartParallelBatchTranslation(texts, callback));
		}
		else
		{
			yield return ((MonoBehaviour)TranslationManager.instance).StartCoroutine(StartSingleTranslation(texts, callback));
		}
	}

	public IEnumerator StartParallelBatchTranslation(List<string> texts, Action<string[]> callback)
	{
		int totalBatches = texts.Count;
		int completedBatches = 0;
		bool anyFailed = false;
		string[] batchResults = new string[totalBatches];
		for (int i = 0; i < totalBatches; i++)
		{
			int batchIndex = i;
			string singleText = texts[i];
			((MonoBehaviour)TranslationManager.instance).StartCoroutine(SendBatchRequest(singleText, batchIndex, delegate(bool success, string results)
			{
				int num = completedBatches;
				completedBatches = num + 1;
				if (success && results != null)
				{
					batchResults[batchIndex] = results;
				}
				else
				{
					anyFailed = true;
				}
				if (completedBatches == totalBatches)
				{
					if (anyFailed)
					{
						Debug.LogError((object)"并行批量模式存在失败批次。There are failed batches in parallel batch mode.");
						callback?.Invoke(null);
					}
					else
					{
						callback?.Invoke(batchResults);
					}
				}
			}));
		}
		while (completedBatches < totalBatches)
		{
			yield return null;
		}
	}

	private IEnumerator SendBatchRequest(string singleText, int batchIndex, Action<bool, string> batchCallback)
	{
		JObject val = new JObject();
		val.Add("model", JToken.op_Implicit(config.LlmName));
		JArray val2 = new JArray();
		JObject val3 = new JObject();
		val3.Add("role", JToken.op_Implicit("system"));
		val3.Add("content", JToken.op_Implicit(config.LlmPrompt));
		val2.Add((JToken)val3);
		JObject val4 = new JObject();
		val4.Add("role", JToken.op_Implicit("user"));
		val4.Add("content", JToken.op_Implicit(singleText.Replace("\r", "")));
		val2.Add((JToken)val4);
		val.Add("messages", (JToken)val2);
		val.Add("temperature", JToken.op_Implicit(config.LlmTemperature));
		val.Add("max_tokens", JToken.op_Implicit(config.LlmMaxTokens));
		val.Add("top_p", JToken.op_Implicit(config.LlmTopP));
		val.Add("top_k", JToken.op_Implicit(config.LlmTopK));
		val.Add("frequency_penalty", JToken.op_Implicit(config.LlmFrequencyPenalty));
		val.Add("n", JToken.op_Implicit(1));
		JObject jsonObject = val;
		if (!string.IsNullOrEmpty(config.LlmExtraParametersJson))
		{
			JObject extraObj = JObject.Parse(config.LlmExtraParametersJson);
			foreach (JProperty property in extraObj.Properties())
			{
				jsonObject[property.Name] = property.Value;
			}
		}
		string payloadJson = ((JToken)jsonObject).ToString((Formatting)0, (JsonConverter[])(object)new JsonConverter[0]);
		string requestUrl = config.LlmBaseUrl ?? "";
		int retryCount = 0;
		bool needRetry = false;
		while (true)
		{
			if (needRetry)
			{
				if (retryCount >= config.MaxRetryCount)
				{
					break;
				}
				retryCount++;
				Debug.Log((object)$"批次 {batchIndex} 正在重试... 尝试第 {retryCount} 次。Batch {batchIndex} is retrying... Attempt time {retryCount}.");
				needRetry = false;
				yield return (object)new WaitForSecondsRealtime(config.RetryInterval);
			}
			UnityWebRequest request = new UnityWebRequest(requestUrl, "POST");
			try
			{
				byte[] bodyRaw = Encoding.UTF8.GetBytes(payloadJson);
				request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
				request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
				request.SetRequestHeader("Content-Type", "application/json");
				request.SetRequestHeader("Authorization", "Bearer " + config.LlmApiKey);
				yield return request.SendWebRequest();
				if (request.isNetworkError || request.isHttpError)
				{
					Debug.LogError((object)$"批次 {batchIndex} 请求失败 Request failed in batch {batchIndex}: {request.error}");
					needRetry = true;
					continue;
				}
				string responseJson = request.downloadHandler.text;
				string translatedText;
				try
				{
					translatedText = ParseResponse(responseJson);
				}
				catch (Exception ex2)
				{
					Exception ex = ex2;
					Debug.LogError((object)$"批次 {batchIndex} 解析翻译结果失败 Failed to parse translation result in batch {batchIndex}: {ex.Message}");
					Debug.LogError((object)("响应JSON Response JSON:\n" + responseJson));
					needRetry = true;
					goto end_IL_0425;
				}
				if (translatedText != null)
				{
					batchCallback?.Invoke(arg1: true, translatedText);
					yield break;
				}
				Debug.LogError((object)$"批次 {batchIndex} 无翻译结果。No translation results in batch {batchIndex}.");
				needRetry = true;
				yield break;
				end_IL_0425:;
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
		}
		Debug.LogError((object)$"批次 {batchIndex} 多次尝试失败。已重试 {config.MaxRetryCount} 次。Multiple attempts failed in batch {batchIndex}. Retried {config.MaxRetryCount} times. Translation aborted!");
		batchCallback?.Invoke(arg1: false, null);
	}
}
public class LRUCache<TKey, TValue>
{
	public class CacheItem
	{
		public TKey Key;

		public TValue Value;

		public void Reset(TKey key, TValue value)
		{
			Key = key;
			Value = value;
		}
	}

	private readonly int _capacity;

	private readonly Dictionary<TKey, LinkedListNode<CacheItem>> _cache;

	private readonly LinkedList<CacheItem> _order;

	private readonly ObjectPool<LinkedListNode<CacheItem>> _nodePool;

	private readonly ObjectPool<CacheItem> _cacheItemPool;

	public LRUCache(int capacity)
	{
		if (capacity <= 0)
		{
			throw new ArgumentException("容量必须大于0。Capacity must be greater than zero.");
		}
		_capacity = capacity;
		_cache = new Dictionary<TKey, LinkedListNode<CacheItem>>(capacity);
		_order = new LinkedList<CacheItem>();
		_nodePool = new ObjectPool<LinkedListNode<CacheItem>>(() => new LinkedListNode<CacheItem>(null), capacity, delegate(LinkedListNode<CacheItem> node)
		{
			node.Value = null;
		});
		_cacheItemPool = new ObjectPool<CacheItem>(() => new CacheItem(), capacity, delegate(CacheItem item)
		{
			item.Reset(default(TKey), default(TValue));
		});
	}

	public TValue Get(TKey key)
	{
		if (_cache.TryGetValue(key, out var value))
		{
			_order.Remove(value);
			_order.AddFirst(value);
			return value.Value.Value;
		}
		return default(TValue);
	}

	public bool TryGetValue(TKey key, out TValue value)
	{
		if (_cache.TryGetValue(key, out var value2))
		{
			_order.Remove(value2);
			_order.AddFirst(value2);
			value = value2.Value.Value;
			return true;
		}
		value = default(TValue);
		return false;
	}

	public void Set(TKey key, TValue value)
	{
		if (_cache.TryGetValue(key, out var value2))
		{
			if (!EqualityComparer<TValue>.Default.Equals(value2.Value.Value, value))
			{
				value2.Value.Reset(key, value);
			}
			return;
		}
		if (_cache.Count >= _capacity)
		{
			LinkedListNode<CacheItem> last = _order.Last;
			_cache.Remove(last.Value.Key);
			_order.RemoveLast();
			_cacheItemPool.Return(last.Value);
			_nodePool.Return(last);
		}
		CacheItem cacheItem = _cacheItemPool.Get();
		cacheItem.Reset(key, value);
		value2 = _nodePool.Get();
		value2.Value = cacheItem;
		_order.AddFirst(value2);
		_cache[key] = value2;
	}

	public bool ContainsKey(TKey key)
	{
		return _cache.ContainsKey(key);
	}

	public List<KeyValuePair<TKey, TValue>> GetOrderedKeyValuePairs()
	{
		List<KeyValuePair<TKey, TValue>> list = new List<KeyValuePair<TKey, TValue>>(_cache.Count);
		for (LinkedListNode<CacheItem> linkedListNode = _order.First; linkedListNode != null; linkedListNode = linkedListNode.Next)
		{
			if (linkedListNode.Value != null)
			{
				list.Add(new KeyValuePair<TKey, TValue>(linkedListNode.Value.Key, linkedListNode.Value.Value));
			}
		}
		return list;
	}

	public int GetCapacity()
	{
		return _capacity;
	}

	public Dictionary<TKey, LinkedListNode<CacheItem>> GetCache()
	{
		return _cache;
	}

	public LinkedList<CacheItem> GetOrder()
	{
		return _order;
	}
}
public class ObjectPool<T> where T : class
{
	private readonly Queue<T> _pool;

	private readonly int _maxSize;

	private readonly Func<T> _factory;

	private readonly Action<T> _resetAction;

	public ObjectPool(Func<T> factory, int maxSize = 16, Action<T> resetAction = null)
	{
		_factory = factory ?? throw new ArgumentNullException("factory");
		_maxSize = maxSize;
		_pool = new Queue<T>(maxSize);
		_resetAction = resetAction;
	}

	public T Get()
	{
		if (_pool.Count > 0)
		{
			return _pool.Dequeue();
		}
		return _factory();
	}

	public void Return(T obj)
	{
		if (_resetAction != null)
		{
			_resetAction(obj);
		}
		if (_pool.Count < _maxSize)
		{
			_pool.Enqueue(obj);
		}
	}
}
public class StatusLabelController
{
	internal class StatusLabelModifier : SModifier
	{
		private AutoTranslateConfig config;

		private StatusLabelController statusLabel;

		public StatusLabelModifier(AutoTranslateConfig autoTranslateConfig, StatusLabelController statusLabelController)
		{
			config = autoTranslateConfig;
			statusLabel = statusLabelController;
		}

		public override void Update()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(config.ToggleRequestedCharacterCountKeyBinding))
			{
				statusLabel.ToggleVisibility();
			}
		}
	}

	internal SLabel label;

	private Font font;

	private readonly Color backgroundColor = new Color(0f, 0f, 0f, 0.5f);

	private readonly Color defaultColor = Color.white;

	private readonly Color highlightColor = Color.red;

	private StatusLabelModifier modifier;

	private bool highlight = false;

	private AutoTranslateConfig config;

	private readonly Vector2 defaultAnchor = new Vector2(0.5f, 0f);

	private readonly Vector2 defaultPivot = new Vector2(0.5f, 0f);

	private Vector2 anchor;

	private Vector2 pivot;

	public static StatusLabelController instance;

	internal void InitializeStatusLabel()
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Expected O, but got Unknown
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		instance = this;
		config = AutoTranslateModule.instance.config;
		try
		{
			anchor = ParseVector2(config.CountLabelAnchor);
			pivot = ParseVector2(config.CountLabelPivot);
		}
		catch
		{
			anchor = defaultAnchor;
			pivot = defaultPivot;
		}
		label = new SLabel();
		((SElement)label).Background = backgroundColor;
		((SElement)label).Foreground = defaultColor;
		modifier = new StatusLabelModifier(config, this);
		((SElement)label).With.Add((SModifier)(object)modifier);
		((SElement)label).OnUpdateStyle = delegate(SElement element)
		{
			element.Font = LoadFont();
			Reposition();
		};
		((SElement)label).Visible = config.ShowRequestedCharacterCount;
		SGUIRoot.Main.Children.Add((SElement)(object)label);
	}

	private Font LoadFont()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		if ((Object)(object)font == (Object)null)
		{
			dfFont val = (dfFont)GameUIRoot.Instance.Manager.DefaultFont;
			font = FontConverter.GetFontFromdfFont(val, 2);
		}
		return font;
	}

	internal void SetText(string text)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		label.Text = text;
		((SElement)label).Size = ((SElement)label).Backend.MeasureText(text, (Vector2?)null, (object)font);
		Reposition();
	}

	private void Reposition()
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		if (((SElement)label).Root != null)
		{
			((SElement)label).Position.x = ((SElement)label).Root.Size.x * anchor.x - ((SElement)label).Size.x * pivot.x;
			((SElement)label).Position.y = ((SElement)label).Root.Size.y * anchor.y - ((SElement)label).Size.y * pivot.y;
		}
	}

	internal void SetHighlight()
	{
		if (!highlight)
		{
			highlight = true;
			ForceSetVisibility(value: true);
			((MonoBehaviour)TranslationManager.instance).StartCoroutine(AlternateColor());
		}
	}

	private IEnumerator AlternateColor()
	{
		while (true)
		{
			((SElement)label).Foreground = highlightColor;
			yield return (object)new WaitForSecondsRealtime(0.5f);
			((SElement)label).Foreground = defaultColor;
			yield return (object)new WaitForSecondsRealtime(0.5f);
		}
	}

	internal void ForceSetVisibility(bool value)
	{
		((SElement)label).Visible = value;
		Debug.Log((object)("请求字符计数强制设置为" + (value ? "ON" : "OFF") + "。RequestedCharacterCount forcefully set to " + (value ? "ON" : "OFF") + "."));
	}

	internal void ToggleVisibility()
	{
		((SElement)label).Visible = !((SElement)label).Visible;
		Debug.Log((object)("请求字符计数切换为" + (((SElement)label).Visible ? "ON" : "OFF") + "。RequestedCharacterCount toggled set to " + (((SElement)label).Visible ? "ON" : "OFF") + "."));
	}

	public static Vector2 ParseVector2(string input)
	{
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
		if (input == null)
		{
			throw new ArgumentException("输入不能为空。Input cannot be empty.");
		}
		int length = input.Length;
		int i;
		for (i = 0; i < length && char.IsWhiteSpace(input[i]); i++)
		{
		}
		if (i >= length)
		{
			throw new FormatException("输入不能为空。Input cannot be empty.");
		}
		int num = i;
		if (input[i] == '-' || input[i] == '+')
		{
			i++;
		}
		bool flag = false;
		while (i < length)
		{
			char c = input[i];
			if (char.IsDigit(c))
			{
				i++;
				continue;
			}
			if (c == '.' && !flag)
			{
				flag = true;
				i++;
				continue;
			}
			break;
		}
		if (i == num || (i == num + 1 && (input[num] == '-' || input[num] == '+')))
		{
			throw new FormatException("第一个数字不能为空。First number cannot be empty.");
		}
		if (!float.TryParse(input.Substring(num, i - num), out