using System; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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; } } } internal static class PluginInfo { public const string PLUGIN_GUID = "Unify2Min"; public const string PLUGIN_NAME = "Unify2Min"; public const string PLUGIN_VERSION = "1.0.1"; } namespace Unify2Min { internal static class Unify2MinPatches { [HarmonyPatch(typeof(ItemProto), "GetPropValue")] internal static class ItemProto_GetPropValue_Patch { private static bool _loggedBelt; private static bool _loggedInserter; [HarmonyPostfix] private static void Postfix(ItemProto __instance, int index, ref string __result) { if (!string.IsNullOrEmpty(__result) && __instance.prefabDesc != null) { if (__instance.prefabDesc.isBelt) { TryConvertAndLog(ConvertBeltTooltip(ref __result), ref _loggedBelt, "传送带运载量"); } else if (__instance.prefabDesc.isInserter) { TryConvertAndLog(ConvertInserterTooltip(__instance.prefabDesc, ref __result), ref _loggedInserter, "分拣器运送速度"); } } } } [HarmonyPatch(typeof(UIBeltWindow), "_OnUpdate")] internal static class UIBeltWindow_OnUpdate_Patch { private static bool _logged; [HarmonyPostfix] private static void Postfix(UIBeltWindow __instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (ValidateBeltWindow(__instance, out var belt)) { float num = (float)belt.speed * 60f / 10f * 60f; __instance.speedText.text = Localization.Translate("带速度") + num.ToString("0") + " / min"; LogOnce(ref _logged, "传送带面板速度"); } } private static bool ValidateBeltWindow(UIBeltWindow window, out BeltComponent belt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) belt = default(BeltComponent); if (window.beltId == 0 || window.traffic?.beltPool == null) { return false; } if (window.beltId >= window.traffic.beltPool.Length) { return false; } belt = window.traffic.beltPool[window.beltId]; return belt.id == window.beltId; } } [HarmonyPatch(typeof(UIInserterWindow), "_OnUpdate")] internal static class UIInserterWindow_OnUpdate_Patch { private static bool _logged; [HarmonyPostfix] private static void Postfix(UIInserterWindow __instance) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (ValidateInserterWindow(__instance, out var inserter)) { __instance.rttText.text = CalculateInserterPanelRate(inserter); LogOnce(ref _logged, "分拣器面板往返"); } } private static bool ValidateInserterWindow(UIInserterWindow window, out InserterComponent inserter) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) inserter = default(InserterComponent); if (window.inserterId == 0 || window.factorySystem?.inserterPool == null) { return false; } if (window.inserterId >= window.factorySystem.inserterPool.Length) { return false; } inserter = window.factorySystem.inserterPool[window.inserterId]; return inserter.id == window.inserterId; } private static string CalculateInserterPanelRate(InserterComponent inserter) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (!inserter.bidirectional) { return (int)Math.Round(18000000.0 / (double)inserter.stt) + " / min"; } return "7200 / min"; } } [HarmonyPatch(typeof(UIInserterBuildTip), "_OnUpdate")] internal static class UIInserterBuildTip_OnUpdate_Patch { private static bool _logged; [HarmonyPostfix] private static void Postfix(UIInserterBuildTip __instance) { if (!((Object)(object)__instance.arrowTipText2 == (Object)null) && __instance.desc != null && __instance.topGroup.activeSelf && (__instance.desc.inserterGrade != 4 || GameMain.history.inserterBidirectional)) { __instance.arrowTipText2.text = CalculateBuildTipRate(__instance.desc, __instance.gridLen); LogOnce(ref _logged, "分拣器建造提示"); } } private static string CalculateBuildTipRate(PrefabDesc desc, int gridLen) { if (desc.inserterGrade == 4 && GameMain.history.inserterBidirectional) { return "7200 / min"; } int num = Math.Max((int)((float)(desc.inserterSTT * gridLen) + 0.499f), 10000); if ((float)gridLen < 0.001f) { return "0 / min"; } return (int)Math.Round(300000f / (float)num * 60f) + " / min"; } } private const string UnitPerMin = " / min"; private const string UnitPerMinPerGrid = " /min/格"; private static void TryConvertAndLog(bool converted, ref bool logged, string itemType) { if (!(!converted | logged)) { logged = true; ManualLogSource log = Unify2MinPlugin.Log; if (log != null) { log.LogInfo((object)("[Unify2Min] 物品提示:" + itemType + "已改为 / min")); } } } private static bool ConvertBeltTooltip(ref string text) { if (!text.EndsWith("/s")) { return false; } if (!double.TryParse(text.Substring(0, text.Length - 2).Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out var result)) { return false; } text = (int)Math.Round(result * 60.0) + " / min"; return true; } private static bool ConvertInserterTooltip(PrefabDesc prefabDesc, ref string text) { if (!IsInserterSpeedText(text)) { return false; } if (!TryParseNumber(text, out var numStart, out var rate)) { return false; } int num = (int)Math.Round(rate * 60.0); string unit = ((prefabDesc.inserterGrade == 4) ? " / min" : " /min/格"); text = FormatWithOptionalColor(text, numStart, num.ToString(), unit); return true; } private static bool IsInserterSpeedText(string text) { if (text.IndexOf("单程", StringComparison.Ordinal) >= 0 || text.IndexOf("耗时", StringComparison.Ordinal) >= 0) { return false; } if (text.IndexOf("往返", StringComparison.Ordinal) < 0 && text.IndexOf("每秒", StringComparison.Ordinal) < 0) { return text.IndexOf("/秒", StringComparison.Ordinal) >= 0; } return true; } private static bool TryParseNumber(string text, out int numStart, out double rate) { numStart = 0; rate = 0.0; if (text.StartsWith("', 7); if (num < 0) { return false; } numStart = num + 1; } int i; for (i = numStart; i < text.Length && (char.IsDigit(text[i]) || text[i] == '.'); i++) { } if (i <= numStart) { return false; } return double.TryParse(text.Substring(numStart, i - numStart), NumberStyles.Any, CultureInfo.InvariantCulture, out rate); } private static string FormatWithOptionalColor(string original, int numStart, string value, string unit) { if (numStart <= 0) { return value + unit; } return original.Substring(0, numStart) + value + unit + ""; } private static void LogOnce(ref bool logged, string description) { if (!logged) { logged = true; ManualLogSource log = Unify2MinPlugin.Log; if (log != null) { log.LogInfo((object)("[Unify2Min] " + description + "已改为 / min")); } } } } [BepInPlugin("com.dspmod.unify2min", "统一为分钟 (Unify 2 Min)", "1.0.1")] public class Unify2MinPlugin : BaseUnityPlugin { public const string PLUGIN_GUID = "com.dspmod.unify2min"; public const string PLUGIN_NAME = "统一为分钟 (Unify 2 Min)"; public const string PLUGIN_VERSION = "1.0.1"; internal static ManualLogSource Log; private static Harmony _harmony; private void Awake() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"[Unify2Min] Awake 入口"); _harmony = new Harmony("com.dspmod.unify2min"); ApplyPatch("ItemProto.GetPropValue", AccessTools.Method(typeof(ItemProto), "GetPropValue", new Type[3] { typeof(int), typeof(StringBuilder), typeof(int) }, (Type[])null), AccessTools.Method(typeof(Unify2MinPatches.ItemProto_GetPropValue_Patch), "Postfix", (Type[])null, (Type[])null)); ApplyPatch("UIBeltWindow._OnUpdate", AccessTools.Method(typeof(UIBeltWindow), "_OnUpdate", (Type[])null, (Type[])null), AccessTools.Method(typeof(Unify2MinPatches.UIBeltWindow_OnUpdate_Patch), "Postfix", (Type[])null, (Type[])null)); ApplyPatch("UIInserterWindow._OnUpdate", AccessTools.Method(typeof(UIInserterWindow), "_OnUpdate", (Type[])null, (Type[])null), AccessTools.Method(typeof(Unify2MinPatches.UIInserterWindow_OnUpdate_Patch), "Postfix", (Type[])null, (Type[])null)); ApplyPatch("UIInserterBuildTip._OnUpdate", AccessTools.Method(typeof(UIInserterBuildTip), "_OnUpdate", (Type[])null, (Type[])null), AccessTools.Method(typeof(Unify2MinPatches.UIInserterBuildTip_OnUpdate_Patch), "Postfix", (Type[])null, (Type[])null)); Log.LogInfo((object)"[Unify2Min] 统一为分钟 (Unify 2 Min) v1.0.1 已加载;传送带/分拣器单位已统一为 / min"); } private void ApplyPatch(string label, MethodBase target, MethodBase postfix) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown if (target == null) { Log.LogWarning((object)("[Unify2Min] 未找到目标方法: " + label)); return; } if (postfix == null) { Log.LogWarning((object)("[Unify2Min] 未找到补丁方法: " + label)); return; } try { MethodInfo methodInfo = (postfix as MethodInfo) ?? throw new InvalidOperationException("Postfix must be MethodInfo"); _harmony.Patch(target, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)("[Unify2Min] 已绑定: " + label)); } catch (Exception ex) { Log.LogError((object)("[Unify2Min] 绑定失败 " + label + ": " + ex.Message)); } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } }