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<float> AssemblerSpeedMult;
public static ConfigEntry<float> SmelterSpeedMult;
public static ConfigEntry<float> ChemicalSpeedMult;
public static ConfigEntry<float> RefinerySpeedMult;
public static ConfigEntry<float> ColliderSpeedMult;
public static ConfigEntry<bool> BeltDoubleSpeed;
public static ConfigEntry<float> PoleCoverMult;
public static ConfigEntry<float> PoleConnectMult;
public static ConfigEntry<float> PowerGenMult;
public static ConfigEntry<bool> EnableStackingTechExt;
public static ConfigEntry<float> 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<float>("01-制造台", "速度倍率", 2f, new ConfigDescription("制造台 Mk.I / II / III 的工作速度倍率。范围 0(无加成) ~ 100(100倍);1 = 原版默认;默认 = 2倍。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[0]));
SmelterSpeedMult = ((BaseUnityPlugin)this).Config.Bind<float>("02-熔炉类", "速度倍率", 2f, new ConfigDescription("熔炉、电弧熔炉、位面熔炉的工作速度倍率。范围 0(无加成) ~ 100(100倍);1 = 原版默认;默认 = 2倍。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[0]));
ChemicalSpeedMult = ((BaseUnityPlugin)this).Config.Bind<float>("03-化工厂", "速度倍率", 2f, new ConfigDescription("化工厂的工作速度倍率。范围 0(无加成) ~ 100(100倍);1 = 原版默认;默认 = 2倍。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[0]));
RefinerySpeedMult = ((BaseUnityPlugin)this).Config.Bind<float>("04-精炼厂", "速度倍率", 2f, new ConfigDescription("原油精炼厂的工作速度倍率。范围 0(无加成) ~ 100(100倍);1 = 原版默认;默认 = 2倍。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[0]));
ColliderSpeedMult = ((BaseUnityPlugin)this).Config.Bind<float>("05-粒子对撞机", "速度倍率", 2f, new ConfigDescription("粒子对撞机的工作速度倍率。范围 0(无加成) ~ 100(100倍);1 = 原版默认;默认 = 2倍。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[0]));
BeltDoubleSpeed = ((BaseUnityPlugin)this).Config.Bind<bool>("06-传送带", "启用2倍速度", true, new ConfigDescription("关闭 = 原版速度(3种传送带);开启 = 相对原版提升至2倍。\n游戏硬上限 60 格/秒 不会突破。", (AcceptableValueBase)null, new object[0]));
PoleCoverMult = ((BaseUnityPlugin)this).Config.Bind<float>("07-电线杆", "覆盖范围倍率", 2f, new ConfigDescription("特斯拉塔/无线输电塔/卫星配电站 等电力节点的 覆盖半径 × 倍率。范围 1 – 10,默认 2×。\n【安全说明】仅对新放置的建筑生效;已建造的电线杆不会自动升级,避免电网每帧重新计算导致的归零跳动。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), new object[0]));
PoleConnectMult = ((BaseUnityPlugin)this).Config.Bind<float>("07-电线杆", "连接距离倍率", 2f, new ConfigDescription("电力节点之间的 可连线最大距离 × 倍率。范围 1 – 10,默认 2×。\n【安全说明】仅对新放置的建筑生效;已建造的电线杆不会自动升级,避免电网每帧重新计算导致的归零跳动。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), new object[0]));
PowerGenMult = ((BaseUnityPlugin)this).Config.Bind<float>("08-发电设施", "发电力倍率", 2f, new ConfigDescription("火力/地热/燃油/太阳能/风力/射线接收/聚变发电站 等 每tick产能量 × 倍率。\n范围 0 – 100。默认 2×。\n【安全说明】仅对新放置的建筑生效;已建造的电线杆不会自动升级,避免电网每帧重新计算导致的归零跳动。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[0]));
EnableStackingTechExt = ((BaseUnityPlugin)this).Config.Bind<bool>("20-运输站集装科技", "启用上限扩展", true, new ConfigDescription("开启后运输站集装物流科技最大等级从原版扩展到 50 级;\n到达 50 级后研究按钮显示 MAX 无法点击;每级科研点消耗递增 1.3×(可调)。", (AcceptableValueBase)null, new object[0]));
StackingTechCostMult = ((BaseUnityPlugin)this).Config.Bind<float>("20-运输站集装科技", "消耗递增倍率", 1.3f, new ConfigDescription("集装科技 2 级及以上,每级科研点消耗相对原版再乘 (倍率)^(level-1)。\n默认 1.3 = 2级×1.3,3级×1.69,...;填 1.0 保持原版消耗。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(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<ItemProto>)(object)LDB.items).dataArray == null || ((ProtoSet<ItemProto>)(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<int, int> OrigAssembler = new Dictionary<int, int>();
private static readonly Dictionary<int, int> OrigBelt = new Dictionary<int, int>();
private static readonly Dictionary<int, BuildingCategory> CatOf = new Dictionary<int, BuildingCategory>();
private static readonly List<FieldInfo> PoleFields = new List<FieldInfo>();
private static readonly List<FieldInfo> GenFields = new List<FieldInfo>();
private static readonly Dictionary<int, Dictionary<string, float>> OrigPole = new Dictionary<int, Dictionary<string, float>>();
private static readonly Dictionary<int, Dictionary<string, float>> OrigGen = new Dictionary<int, Dictionary<string, float>>();
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<ItemProto>)(object)LDB.items).dataArray == null)
{
return;
}
Type type = null;
ItemProto[] dataArray = ((ProtoSet<ItemProto>)(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<ItemProto>)(object)LDB.items).dataArray == null)
{
return;
}
ItemProto[] dataArray = ((ProtoSet<ItemProto>)(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<string, float> 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<string, float>();
}
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<string, float>();
}
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<ItemProto>)(object)LDB.items).dataArray == null)
{
return;
}
if (!_captured)
{
CaptureOriginals();
}
CatOf.Clear();
int num = 0;
ItemProto[] dataArray = ((ProtoSet<ItemProto>)(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<TechProto>)(object)LDB.techs).dataArray == null)
{
return;
}
int num = -1;
int num2 = 0;
TechProto[] dataArray = ((ProtoSet<TechProto>)(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<TechProto>)(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<TechProto>)(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<int, object> value = val3.GetValue<Dictionary<int, object>>();
if (value != null && value.TryGetValue(techId, out var value2) && value2 != null)
{
Traverse val4 = Traverse.Create(value2);
int value3 = val4.Field("curLevel").GetValue<int>();
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<int>() + 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<int>();
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<int>();
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;
}
}
}
}