using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace zzInfinity; [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("zz.zzInfinity", "zz无限", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "zz.zzInfinity"; public const string PluginName = "zz无限"; public const string PluginVersion = "1.0.0"; public static Plugin Instance; public static ManualLogSource Logger; public static Harmony HarmonyInstance; public static ConfigEntry AssemblerSpeedMult; public static ConfigEntry SmelterSpeedMult; public static ConfigEntry ChemicalSpeedMult; public static ConfigEntry RefinerySpeedMult; public static ConfigEntry ColliderSpeedMult; public static ConfigEntry BeltDoubleSpeed; public static ConfigEntry PoleCoverMult; public static ConfigEntry PoleConnectMult; public static ConfigEntry PowerGenMult; public static ConfigEntry EnableStackingTechExt; public static ConfigEntry StackingTechCostMult; private bool _applied; private bool _gameLoaded; private int _waitFrames; private bool _ldbPostFired; private int _ldbPostFrames; private void Awake() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; HarmonyInstance = new Harmony("zz.zzInfinity"); Logger.LogInfo((object)"zz无限 启动 v1.0.0"); InitConfig(); HarmonyInstance.PatchAll(typeof(Patches)); HarmonyInstance.PatchAll(typeof(InfiniteTech)); InfiniteTech.ManualPatchOptionalGetters(); try { Type type = Type.GetType("xiaoye97.LDBTool, LDBTool"); if (!(type != null)) { return; } FieldInfo field = type.GetField("PostAddDataAction", BindingFlags.Static | BindingFlags.Public); if (field != null) { Action a = (Action)field.GetValue(null); a = (Action)Delegate.Combine(a, (Action)delegate { _ldbPostFired = true; _ldbPostFrames = 0; }); field.SetValue(null, a); Logger.LogInfo((object)"已订阅 LDBTool.PostAddDataAction"); } } catch { } } private void InitConfig() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Expected O, but got Unknown //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Expected O, but got Unknown //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Expected O, but got Unknown //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Expected O, but got Unknown //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Expected O, but got Unknown //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Expected O, but got Unknown AssemblerSpeedMult = ((BaseUnityPlugin)this).Config.Bind("01-制造台", "速度倍率", 2f, new ConfigDescription("制造台 Mk.I / II / III 的工作速度倍率。范围 0(无加成) ~ 100(100倍);1 = 原版默认;默认 = 2倍。", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), new object[0])); SmelterSpeedMult = ((BaseUnityPlugin)this).Config.Bind("02-熔炉类", "速度倍率", 2f, new ConfigDescription("熔炉、电弧熔炉、位面熔炉的工作速度倍率。范围 0(无加成) ~ 100(100倍);1 = 原版默认;默认 = 2倍。", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), new object[0])); ChemicalSpeedMult = ((BaseUnityPlugin)this).Config.Bind("03-化工厂", "速度倍率", 2f, new ConfigDescription("化工厂的工作速度倍率。范围 0(无加成) ~ 100(100倍);1 = 原版默认;默认 = 2倍。", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), new object[0])); RefinerySpeedMult = ((BaseUnityPlugin)this).Config.Bind("04-精炼厂", "速度倍率", 2f, new ConfigDescription("原油精炼厂的工作速度倍率。范围 0(无加成) ~ 100(100倍);1 = 原版默认;默认 = 2倍。", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), new object[0])); ColliderSpeedMult = ((BaseUnityPlugin)this).Config.Bind("05-粒子对撞机", "速度倍率", 2f, new ConfigDescription("粒子对撞机的工作速度倍率。范围 0(无加成) ~ 100(100倍);1 = 原版默认;默认 = 2倍。", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), new object[0])); BeltDoubleSpeed = ((BaseUnityPlugin)this).Config.Bind("06-传送带", "启用2倍速度", true, new ConfigDescription("关闭 = 原版速度(3种传送带);开启 = 相对原版提升至2倍。\n游戏硬上限 60 格/秒 不会突破。", (AcceptableValueBase)null, new object[0])); PoleCoverMult = ((BaseUnityPlugin)this).Config.Bind("07-电线杆", "覆盖范围倍率", 2f, new ConfigDescription("特斯拉塔/无线输电塔/卫星配电站 等电力节点的 覆盖半径 × 倍率。范围 1 – 10,默认 2×。\n【安全说明】仅对新放置的建筑生效;已建造的电线杆不会自动升级,避免电网每帧重新计算导致的归零跳动。", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 10f), new object[0])); PoleConnectMult = ((BaseUnityPlugin)this).Config.Bind("07-电线杆", "连接距离倍率", 2f, new ConfigDescription("电力节点之间的 可连线最大距离 × 倍率。范围 1 – 10,默认 2×。\n【安全说明】仅对新放置的建筑生效;已建造的电线杆不会自动升级,避免电网每帧重新计算导致的归零跳动。", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 10f), new object[0])); PowerGenMult = ((BaseUnityPlugin)this).Config.Bind("08-发电设施", "发电力倍率", 2f, new ConfigDescription("火力/地热/燃油/太阳能/风力/射线接收/聚变发电站 等 每tick产能量 × 倍率。\n范围 0 – 100。默认 2×。\n【安全说明】仅对新放置的建筑生效;已建造的电线杆不会自动升级,避免电网每帧重新计算导致的归零跳动。", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), new object[0])); EnableStackingTechExt = ((BaseUnityPlugin)this).Config.Bind("20-运输站集装科技", "启用上限扩展", true, new ConfigDescription("开启后运输站集装物流科技最大等级从原版扩展到 50 级;\n到达 50 级后研究按钮显示 MAX 无法点击;每级科研点消耗递增 1.3×(可调)。", (AcceptableValueBase)null, new object[0])); StackingTechCostMult = ((BaseUnityPlugin)this).Config.Bind("20-运输站集装科技", "消耗递增倍率", 1.3f, new ConfigDescription("集装科技 2 级及以上,每级科研点消耗相对原版再乘 (倍率)^(level-1)。\n默认 1.3 = 2级×1.3,3级×1.69,...;填 1.0 保持原版消耗。", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 10f), new object[0])); ((BaseUnityPlugin)this).Config.SettingChanged += delegate { if (_applied) { MultiplierApplier.ApplyAllMultipliers(); } }; } public static float GetSpeedMultiplier(MultiplierApplier.BuildingCategory category) { switch (category) { case MultiplierApplier.BuildingCategory.Assembler: return AssemblerSpeedMult.Value; case MultiplierApplier.BuildingCategory.Smelter: return SmelterSpeedMult.Value; case MultiplierApplier.BuildingCategory.ChemicalPlant: return ChemicalSpeedMult.Value; case MultiplierApplier.BuildingCategory.Refinery: return RefinerySpeedMult.Value; case MultiplierApplier.BuildingCategory.Collider: return ColliderSpeedMult.Value; case MultiplierApplier.BuildingCategory.Belt: if (!BeltDoubleSpeed.Value) { return 1f; } return 2f; default: return 1f; } } private void Update() { if (!_applied) { if (_ldbPostFired) { _ldbPostFrames++; if (_ldbPostFrames >= 300) { ApplyNow("LDBToolPost 300帧延迟"); } return; } _waitFrames++; if (_waitFrames < 1800 || (Object)(object)LDB.items == (Object)null || ((ProtoSet)(object)LDB.items).dataArray == null || ((ProtoSet)(object)LDB.items).dataArray.Length < 500) { return; } ApplyNow("备用轮询 30秒"); } if (_applied && !_gameLoaded && GameMain.data != null && GameMain.data.factoryCount > 0) { _gameLoaded = true; MultiplierApplier.OnGameLoaded(); } else if (_gameLoaded && (GameMain.data == null || GameMain.data.factoryCount == 0)) { _gameLoaded = false; } } private void ApplyNow(string source) { try { MultiplierApplier.CaptureOriginals(); MultiplierApplier.ApplyAllMultipliers(); InfiniteTech.Initialize(); _applied = true; Logger.LogInfo((object)("zz无限 倍率已应用(来源:" + source + ")")); } catch (Exception ex) { Logger.LogError((object)("应用倍率失败: " + ex.Message + "\n" + ex.StackTrace)); _applied = true; } } private void OnDestroy() { if (HarmonyInstance != null) { HarmonyInstance.UnpatchSelf(); } } } public static class MultiplierApplier { public enum BuildingCategory { Unknown, Assembler, Smelter, ChemicalPlant, Refinery, Collider, Belt, PowerNode, PowerGenerator } private static readonly Dictionary OrigAssembler = new Dictionary(); private static readonly Dictionary OrigBelt = new Dictionary(); private static readonly Dictionary CatOf = new Dictionary(); private static readonly List PoleFields = new List(); private static readonly List GenFields = new List(); private static readonly Dictionary> OrigPole = new Dictionary>(); private static readonly Dictionary> OrigGen = new Dictionary>(); private static bool _captured; private static bool _fieldCacheBuilt; private static void BuildFieldCache() { if (_fieldCacheBuilt) { return; } _fieldCacheBuilt = true; if ((Object)(object)LDB.items == (Object)null || ((ProtoSet)(object)LDB.items).dataArray == null) { return; } Type type = null; ItemProto[] dataArray = ((ProtoSet)(object)LDB.items).dataArray; foreach (ItemProto val in dataArray) { if (val != null && val.prefabDesc != null) { type = ((object)val.prefabDesc).GetType(); break; } } if (type == null) { return; } string[] array = new string[9] { "powerConnectDistance", "powerCoverRadius", "poleCoverRadius", "poleConnectDistance", "coverRadius", "connectDistance", "wirelessMaxPower", "wirelessPower", "wirelessChargePower" }; string[] array2 = new string[9] { "powerGenEnergyPerTick", "generatorEnergyPerTick", "genEnergyPerTick", "solarEnergyPerTick", "energyPerTickGen", "generateEnergyPerTick", "powerEnergyPerTick", "fuelEnergyPerTick", "energyPerTick" }; string[] array3 = array; foreach (string name in array3) { FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && (field.FieldType == typeof(float) || field.FieldType == typeof(long) || field.FieldType == typeof(double))) { PoleFields.Add(field); } } string[] array4 = array2; foreach (string name2 in array4) { FieldInfo field2 = type.GetField(name2, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field2 != null && (field2.FieldType == typeof(float) || field2.FieldType == typeof(long) || field2.FieldType == typeof(double) || field2.FieldType == typeof(int))) { GenFields.Add(field2); } } string text = ""; foreach (FieldInfo poleField in PoleFields) { text = text + poleField.Name + " "; } Plugin.Logger.LogInfo((object)("zz无限 电线杆候选字段: " + text)); text = ""; foreach (FieldInfo genField in GenFields) { text = text + genField.Name + " "; } Plugin.Logger.LogInfo((object)("zz无限 发电候选字段: " + text)); } public static void CaptureOriginals() { if (_captured) { return; } BuildFieldCache(); if ((Object)(object)LDB.items == (Object)null || ((ProtoSet)(object)LDB.items).dataArray == null) { return; } ItemProto[] dataArray = ((ProtoSet)(object)LDB.items).dataArray; foreach (ItemProto val in dataArray) { if (val == null || val.prefabDesc == null) { continue; } PrefabDesc prefabDesc = val.prefabDesc; if (prefabDesc.isAssembler && prefabDesc.assemblerSpeed > 0) { OrigAssembler[((Proto)val).ID] = prefabDesc.assemblerSpeed; } if (prefabDesc.beltSpeed > 0) { OrigBelt[((Proto)val).ID] = prefabDesc.beltSpeed; } Dictionary dictionary; if (PoleFields.Count > 0) { dictionary = null; foreach (FieldInfo poleField in PoleFields) { float num = FieldToFloat(poleField, prefabDesc); if (num > 0f) { if (dictionary == null) { dictionary = new Dictionary(); } dictionary[poleField.Name] = num; } } if (dictionary != null) { OrigPole[((Proto)val).ID] = dictionary; } } if (GenFields.Count <= 0) { continue; } dictionary = null; foreach (FieldInfo genField in GenFields) { float num2 = FieldToFloat(genField, prefabDesc); if (num2 > 0f) { if (dictionary == null) { dictionary = new Dictionary(); } dictionary[genField.Name] = num2; } } if (dictionary != null) { OrigGen[((Proto)val).ID] = dictionary; } } _captured = true; Plugin.Logger.LogInfo((object)("zz无限 捕获原版: 制造类=" + OrigAssembler.Count + ", 传送带=" + OrigBelt.Count + ", 电线杆类=" + OrigPole.Count + ", 发电设施=" + OrigGen.Count)); } public static void ApplyAllMultipliers() { if ((Object)(object)LDB.items == (Object)null || ((ProtoSet)(object)LDB.items).dataArray == null) { return; } if (!_captured) { CaptureOriginals(); } CatOf.Clear(); int num = 0; ItemProto[] dataArray = ((ProtoSet)(object)LDB.items).dataArray; foreach (ItemProto val in dataArray) { if (val == null) { continue; } PrefabDesc prefabDesc = val.prefabDesc; if (prefabDesc == null) { continue; } int iD = ((Proto)val).ID; BuildingCategory buildingCategory = Classify(prefabDesc, iD); if (buildingCategory != BuildingCategory.Unknown) { CatOf[iD] = buildingCategory; } bool flag = false; if (OrigAssembler.ContainsKey(iD)) { float speedMultiplier = Plugin.GetSpeedMultiplier(buildingCategory); int num2 = (int)((float)OrigAssembler[iD] * speedMultiplier); if (num2 < 0) { num2 = 0; } if (prefabDesc.assemblerSpeed != num2) { prefabDesc.assemblerSpeed = num2; flag = true; } } if (OrigBelt.ContainsKey(iD)) { float speedMultiplier2 = Plugin.GetSpeedMultiplier(BuildingCategory.Belt); int num3 = (int)((float)OrigBelt[iD] * speedMultiplier2); if (num3 < 0) { num3 = 0; } if (prefabDesc.beltSpeed != num3) { prefabDesc.beltSpeed = num3; flag = true; } } if (OrigPole.TryGetValue(iD, out var value)) { float value2 = Plugin.PoleConnectMult.Value; float value3 = Plugin.PoleCoverMult.Value; foreach (FieldInfo poleField in PoleFields) { if (value.TryGetValue(poleField.Name, out var value4)) { float num4 = ((poleField.Name.Contains("Cover") || poleField.Name.Contains("Radius")) ? value3 : value2); float num5 = value4 * num4; if (num5 < 0f) { num5 = 0f; } if (SetField(poleField, prefabDesc, num5)) { flag = true; } } } if (buildingCategory == BuildingCategory.Unknown) { CatOf[iD] = BuildingCategory.PowerNode; } } if (OrigGen.TryGetValue(iD, out var value5)) { float value6 = Plugin.PowerGenMult.Value; foreach (FieldInfo genField in GenFields) { if (value5.TryGetValue(genField.Name, out var value7)) { float num6 = value7 * value6; if (num6 < 0f) { num6 = 0f; } if (SetField(genField, prefabDesc, num6)) { flag = true; } } } if (buildingCategory == BuildingCategory.Unknown) { CatOf[iD] = BuildingCategory.PowerGenerator; } } if (flag) { num++; } } Plugin.Logger.LogInfo((object)("zz无限 倍率已应用: 影响建筑 " + num + " 个")); } public static void OnGameLoaded() { } public static BuildingCategory GetCategory(int protoId) { if (CatOf.TryGetValue(protoId, out var value)) { return value; } return BuildingCategory.Unknown; } private static BuildingCategory Classify(PrefabDesc d, int id) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected I4, but got Unknown if (OrigPole.ContainsKey(id)) { return BuildingCategory.PowerNode; } if (OrigGen.ContainsKey(id)) { return BuildingCategory.PowerGenerator; } if (d.beltSpeed > 0) { return BuildingCategory.Belt; } if (!d.isAssembler) { return BuildingCategory.Unknown; } int num = (int)d.assemblerRecipeType; if ((num & 2) != 0) { return BuildingCategory.Smelter; } if ((num & 4) != 0) { return BuildingCategory.ChemicalPlant; } if ((num & 8) != 0) { return BuildingCategory.Refinery; } if ((num & 0x10) != 0 || num == 5) { return BuildingCategory.Collider; } return BuildingCategory.Assembler; } private static float FieldToFloat(FieldInfo f, object inst) { object value = f.GetValue(inst); if (value == null) { return 0f; } if (f.FieldType == typeof(float)) { return (float)value; } if (f.FieldType == typeof(double)) { return (float)(double)value; } if (f.FieldType == typeof(long)) { return (long)value; } if (f.FieldType == typeof(int)) { return (int)value; } return 0f; } private static bool SetField(FieldInfo f, object inst, float newValue) { float num = FieldToFloat(f, inst); if (num - newValue < 1E-05f && newValue - num < 1E-05f) { return false; } if (f.FieldType == typeof(float)) { f.SetValue(inst, newValue); } else if (f.FieldType == typeof(double)) { f.SetValue(inst, (double)newValue); } else if (f.FieldType == typeof(long)) { f.SetValue(inst, (long)newValue); } else if (f.FieldType == typeof(int)) { f.SetValue(inst, (int)newValue); } return true; } } public static class Patches { } public static class InfiniteTech { private static bool _inited; private static int _stationTechId; public static void Initialize() { if (_inited) { return; } _inited = true; if (!Plugin.EnableStackingTechExt.Value) { return; } try { Find(); if (_stationTechId != 0) { SetMax(_stationTechId, 50); } Plugin.Logger.LogInfo((object)("zz无限 集装科技扩展: 目标ID=" + _stationTechId + ", 上限=50级")); } catch (Exception ex) { Plugin.Logger.LogError((object)("初始化集装科技扩展失败: " + ex.Message)); } } private static void Find() { if ((Object)(object)LDB.techs == (Object)null || ((ProtoSet)(object)LDB.techs).dataArray == null) { return; } int num = -1; int num2 = 0; TechProto[] dataArray = ((ProtoSet)(object)LDB.techs).dataArray; foreach (TechProto val in dataArray) { if (val == null || ((Proto)val).name == null) { continue; } string name = ((Proto)val).name; if (name.IndexOf("分拣", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("sorter", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("爪子", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("claw", StringComparison.OrdinalIgnoreCase) >= 0) { num2++; continue; } bool flag = name.IndexOf("station", StringComparison.OrdinalIgnoreCase) >= 0 && (name.IndexOf("pile", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("container", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("logistics", StringComparison.OrdinalIgnoreCase) >= 0); bool flag2 = name.IndexOf("运输站", StringComparison.Ordinal) >= 0 || name.IndexOf("集装物流", StringComparison.Ordinal) >= 0 || (name.IndexOf("集装", StringComparison.Ordinal) >= 0 && name.IndexOf("物流", StringComparison.Ordinal) >= 0); if ((flag || flag2) && val.MaxLevel >= num) { num = val.MaxLevel; _stationTechId = ((Proto)val).ID; } } Plugin.Logger.LogInfo((object)("zz无限 集装科技查找: 候选目标ID=" + _stationTechId + " MaxLevel=" + num + " 已排除分拣器/爪子类科技=" + num2)); } private static void SetMax(int id, int cap) { TechProto val = ((ProtoSet)(object)LDB.techs).Select(id); if (val != null) { Plugin.Logger.LogInfo((object)("zz无限 科技 " + id + " MaxLevel: " + val.MaxLevel + " → " + cap)); val.MaxLevel = cap; } } [HarmonyPatch(typeof(GameHistoryData), "UnlockTech")] [HarmonyPostfix] public static void UnlockTech_Postfix(GameHistoryData __instance, int techId) { if (!_inited || !Plugin.EnableStackingTechExt.Value || techId != _stationTechId) { return; } try { int num = 50; TechProto val = ((ProtoSet)(object)LDB.techs).Select(techId); if (val != null) { num = val.MaxLevel; } Traverse val2 = Traverse.Create((object)__instance); Traverse val3 = val2.Field("techStates"); if (!val3.FieldExists()) { return; } Dictionary value = val3.GetValue>(); if (value != null && value.TryGetValue(techId, out var value2) && value2 != null) { Traverse val4 = Traverse.Create(value2); int value3 = val4.Field("curLevel").GetValue(); int num2 = Math.Min(value3 + 1, num); val4.Field("curLevel").SetValue((object)num2); val4.Field("maxLevel").SetValue((object)num); Traverse val5 = val2.Field("stationPilerLevel"); if (val5.FieldExists()) { val5.SetValue((object)(val5.GetValue() + 1)); } if (num2 == 1 || num2 % 10 == 0 || num2 == num) { Plugin.Logger.LogInfo((object)("zz无限 集装科技研究: 等级 " + value3 + " → " + num2 + "/" + num)); } } } catch (Exception ex) { Plugin.Logger.LogWarning((object)("集装研究后处理失败: " + ex.Message)); } } public static void ManualPatchOptionalGetters() { Harmony harmonyInstance = Plugin.HarmonyInstance; if (harmonyInstance != null) { TryPatchM(harmonyInstance, typeof(GameHistoryData), "GetStationPilerLevel", typeof(InfiniteTech).GetMethod("GetStationPilerLevel_Postfix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); TryPatchPropGet(harmonyInstance, typeof(GameHistoryData), "stationPilerLevel", typeof(InfiniteTech).GetMethod("stationPilerLevel_Getter_Postfix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); TryPatchMArgs(harmonyInstance, typeof(TechProto), "GetHashNeeded", new Type[1] { typeof(int) }, typeof(InfiniteTech).GetMethod("HashNeeded_Postfix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); Plugin.Logger.LogInfo((object)"zz无限 手动补丁完成"); } } private static void TryPatchM(Harmony h, Type type, string methodName, MethodInfo postfix) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown try { MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(method == null)) { h.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(postfix), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } catch { } } private static void TryPatchMArgs(Harmony h, Type type, string methodName, Type[] args, MethodInfo postfix) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown try { MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, args, null); if (!(method == null)) { h.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(postfix), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } catch { } } private static void TryPatchPropGet(Harmony h, Type type, string prop, MethodInfo postfix) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown try { PropertyInfo property = type.GetProperty(prop, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(property == null)) { MethodInfo getMethod = property.GetGetMethod(nonPublic: true); if (!(getMethod == null)) { h.Patch((MethodBase)getMethod, (HarmonyMethod)null, new HarmonyMethod(postfix), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } catch { } } public static void GetStationPilerLevel_Postfix(GameHistoryData __instance, ref int __result) { if (!_inited || !Plugin.EnableStackingTechExt.Value) { return; } try { Traverse val = Traverse.Create((object)__instance).Field("stationPilerLevel"); if (val.FieldExists()) { int value = val.GetValue(); if (value != __result) { __result = value; } } } catch { } } public static void stationPilerLevel_Getter_Postfix(GameHistoryData __instance, ref int __result) { if (!_inited || !Plugin.EnableStackingTechExt.Value) { return; } try { Traverse val = Traverse.Create((object)__instance).Field("stationPilerLevel"); if (val.FieldExists()) { int value = val.GetValue(); if (value != __result) { __result = value; } } } catch { } } public static void HashNeeded_Postfix(TechProto __instance, int level, ref long __result) { if (!_inited || !Plugin.EnableStackingTechExt.Value || __instance == null || ((Proto)__instance).ID != _stationTechId || level <= 1) { return; } float value = Plugin.StackingTechCostMult.Value; if (!(value <= 1f)) { double num = Math.Pow(value, level - 1); long num2 = (long)Math.Round((double)__result * num); if (num2 > 0) { __result = num2; } } } }