using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using XUnity.AutoTranslator.Plugin.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("TooRed")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.2.0")] [assembly: AssemblyInformationalVersion("1.1.2+fbd89a8936acdcb5bb5482f144e0582819ae3382")] [assembly: AssemblyProduct("StatsUIPlugin")] [assembly: AssemblyTitle("StatsUIPlugin")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace StatsUIPlugin { internal class SPConfig { public static ConfigEntry EnableTranslation { get; private set; } public static ConfigEntry BaseSize { get; private set; } public static ConfigEntry MinSize { get; private set; } public static ConfigEntry ReducePerItem { get; private set; } public static ConfigEntry HeaderOffset { get; private set; } public static ConfigEntry NumOffset { get; private set; } public static ConfigEntry FontMode { get; private set; } public static ConfigEntry DebugMode { get; private set; } public static ConfigEntry AutoCheck { get; private set; } public static bool ConfigChanged { get; private set; } = true; internal static void Init(ConfigFile config) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected O, but got Unknown //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Expected O, but got Unknown //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Expected O, but got Unknown //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Expected O, but got Unknown string text = "状态栏设置"; EnableTranslation = config.Bind(text, "状态栏翻译功能", true, new ConfigDescription("启用翻译功能", (AcceptableValueBase)(object)new AcceptableValueList(new bool[2] { true, false }), Array.Empty())); FontMode = config.Bind(text, "字体大小变更", true, new ConfigDescription("字体大小变更", (AcceptableValueBase)(object)new AcceptableValueList(new bool[2] { true, false }), Array.Empty())); AutoCheck = config.Bind(text, "检测mod升级项", true, new ConfigDescription("自动检测额外的mod升级", (AcceptableValueBase)(object)new AcceptableValueList(new bool[2] { true, false }), Array.Empty())); BaseSize = config.Bind(text, "基础字体大小", 35f, new ConfigDescription("基础字体大小", (AcceptableValueBase)(object)new AcceptableValueRange(8f, 48f), Array.Empty())); MinSize = config.Bind(text, "最小字体大小", 16f, new ConfigDescription("最小字体大小", (AcceptableValueBase)(object)new AcceptableValueRange(4f, 24f), Array.Empty())); ReducePerItem = config.Bind(text, "字体递减", 1.4f, new ConfigDescription("每多一项升级减少的字体大小", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); HeaderOffset = config.Bind(text, "标题偏移", 7f, new ConfigDescription("标题字体偏移", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 15f), Array.Empty())); NumOffset = config.Bind(text, "数字偏移", 0.4f, new ConfigDescription("数字字体偏移", (AcceptableValueBase)(object)new AcceptableValueRange(-2f, 2f), Array.Empty())); DebugMode = config.Bind(text, "调试模式", false, new ConfigDescription("调试模式", (AcceptableValueBase)(object)new AcceptableValueList(new bool[2] { true, false }), Array.Empty())); BaseSize.SettingChanged += delegate { ConfigChanged = true; }; MinSize.SettingChanged += delegate { ConfigChanged = true; }; ReducePerItem.SettingChanged += delegate { ConfigChanged = true; }; HeaderOffset.SettingChanged += delegate { ConfigChanged = true; }; NumOffset.SettingChanged += delegate { ConfigChanged = true; }; FontMode.SettingChanged += delegate { ConfigChanged = true; }; } internal static bool IsConfigChanged() { bool configChanged = ConfigChanged; ConfigChanged = false; return configChanged; } } internal class SPManager { private static readonly HashSet _failedTrans = new HashSet(); private static readonly string _bugFilePath = Path.Combine(Paths.ConfigPath, "Translation", "zh", "Bug.txt"); private static readonly StringBuilder _sb = new StringBuilder(512); private static readonly ConcurrentDictionary _transCache = new ConcurrentDictionary(); private static bool _hasModUpg = false; private static int _lastUpgHash; internal static void DetectModdedUpgrades() { try { if (!SPConfig.AutoCheck.Value) { _hasModUpg = true; StatsUIPlugin.LogDebug($"自动检测模组升级项已关闭,默认开启翻译"); return; } Type type = (from asm in AppDomain.CurrentDomain.GetAssemblies() select asm.GetType("REPOLib.Modules.Upgrades", throwOnError: false)).FirstOrDefault((Type type2) => (object)type2 != null); if ((object)type == null) { _hasModUpg = false; StatsUIPlugin.LogDebug($"未检测到 REPOLib,大概不需翻译"); return; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int num = 0; num < assemblies.Length; num++) { if (assemblies[num].FullName.Contains("GoopUpgrades")) { _hasModUpg = true; StatsUIPlugin.LogDebug($"检测到 GoopUpgrades 升级项"); return; } } FieldInfo fieldInfo = AccessTools.Field(type, "_playerUpgrades"); if (fieldInfo == null) { _hasModUpg = false; } else if (fieldInfo.GetValue(null) is IDictionary dictionary) { _hasModUpg = dictionary.Count > 0; StatsUIPlugin.LogDebug($"检测到 {dictionary.Count} 个模组升级项"); } } catch (Exception ex) { _hasModUpg = false; StatsUIPlugin.Log.LogError((object)("REPOLib 检测失败:" + ex.Message)); } } internal static string GetTranslatedName(string displayName) { if (!_hasModUpg) { return displayName; } if (!SPConfig.EnableTranslation.Value) { return displayName; } if (string.IsNullOrEmpty(displayName)) { return displayName; } string text = displayName.ToUpper(); if (_transCache.TryGetValue(text, out var value)) { return value; } try { string text2 = default(string); if (AutoTranslator.Default.TryTranslate(text, ref text2)) { _transCache[text] = text2; StatsUIPlugin.LogDebug($"翻译:{text} → {text2}"); return text2; } } catch (Exception ex) { StatsUIPlugin.Log.LogError((object)("翻译失败:" + ex.Message)); } _transCache[text] = displayName; LogTranslationFailed(text); return displayName; } internal static void ProcessStatsUI(StatsUI instance) { try { if (!SPConfig.FontMode.Value) { return; } TextMeshProUGUI upgradesHeader = instance.upgradesHeader; if (upgradesHeader != null && !((Behaviour)upgradesHeader).enabled) { return; } TextMeshProUGUI text = instance.Text; TextMeshProUGUI textNumbers = instance.textNumbers; Dictionary playerUpgrades = instance.playerUpgrades; int num = ((playerUpgrades != null && playerUpgrades.Count != 0) ? playerUpgrades.Values.Sum() : 0); if (num != _lastUpgHash || SPConfig.IsConfigChanged()) { UpdateFontSize(text, textNumbers, upgradesHeader, playerUpgrades?.Count ?? 0); StatsUIPlugin.LogDebug($"字体大小更改"); _sb.Clear(); foreach (KeyValuePair item in playerUpgrades) { if (item.Value > 0) { _sb.Append("").Append(item.Value).Append("\n"); } } StatsUIPlugin.LogDebug($"数字拼接"); _lastUpgHash = num; } ((TMP_Text)textNumbers).text = _sb.ToString(); } catch (Exception ex) { StatsUIPlugin.Log.LogError((object)("处理StatsUI出错:" + ex.Message + "\n" + ex.StackTrace)); } } private static void UpdateFontSize(TextMeshProUGUI Text, TextMeshProUGUI numbersText, TextMeshProUGUI headerText, int upgradeCount) { float num = ((upgradeCount > 5) ? ((float)(upgradeCount - 5) * SPConfig.ReducePerItem.Value) : 0f); float num2 = (((TMP_Text)Text).fontSize = Mathf.Clamp(SPConfig.BaseSize.Value - num, SPConfig.MinSize.Value, SPConfig.BaseSize.Value - num)); ((TMP_Text)numbersText).fontSize = num2 + SPConfig.NumOffset.Value; ((TMP_Text)headerText).fontSize = num2 + SPConfig.HeaderOffset.Value; } internal static void LogTranslationFailed(string key) { if (!_failedTrans.Contains(key)) { try { Directory.CreateDirectory(Path.GetDirectoryName(_bugFilePath)); File.AppendAllText(_bugFilePath, key + "=" + key + "\n", Encoding.UTF8); } catch (Exception ex) { StatsUIPlugin.Log.LogError((object)("写入Bug.txt失败:" + ex.Message)); } _failedTrans.Add(key); StatsUIPlugin.Log.LogWarning((object)("翻译失败 [" + key + "]:无对应中文,请清除其它翻译模组或联系汉化作者TooRed求助,QQ群:1050816144")); } } internal static void PlayerAvatarStart() { _lastUpgHash = 0; StatsUIPlugin.LogDebug($"重置状态栏缓存"); } } [BepInPlugin("StatsUIPlugin", "状态栏辅助插件", "1.1.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class StatsUIPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(StatsUI), "Fetch")] private static class StatsUIFetchPatch { private static void Postfix(StatsUI __instance) { SPManager.ProcessStatsUI(__instance); } } [HarmonyPatch(typeof(StatsUI), "GetUpgradeDisplayName")] private static class GetUpgradeDisplayNamePatch { private static void Postfix(ref string __result) { __result = SPManager.GetTranslatedName(__result); } } [HarmonyPatch(typeof(PlayerAvatar), "Start")] private static class HookPlayerAvatarStart { private static void Postfix() { SPManager.PlayerAvatarStart(); } } private Harmony Harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; if (AutoTranslator.Default == null) { Log.LogError((object)"XUnity.AutoTranslator未加载!"); return; } Harmony = new Harmony("StatsUIPlugin"); Harmony.PatchAll(); SPConfig.Init(((BaseUnityPlugin)this).Config); SPManager.DetectModdedUpgrades(); Log.LogInfo((object)"加载成功!"); } internal static void LogDebug(FormattableString message) { if (SPConfig.DebugMode.Value) { Log.LogDebug((object)message.ToString()); Log.LogInfo((object)message.ToString()); } } } }