using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
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")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace DSPProliferatorTweak
{
internal static class IncCeilingTranspiler
{
private static readonly FieldInfo CargoIncTableField = AccessTools.Field(typeof(Cargo), "incTable");
private static readonly FieldInfo CeilingField = AccessTools.Field(typeof(ProliferatorTweakPlugin), "IncLevelAggregationCeiling");
internal static readonly MethodInfo AssemblerSplitInc = AccessTools.Method(typeof(AssemblerComponent), "split_inc_level", (Type[])null, (Type[])null);
internal static readonly MethodInfo LabSplitInc = AccessTools.Method(typeof(LabComponent), "split_inc_level", (Type[])null, (Type[])null);
internal static IEnumerable<CodeInstruction> ReplaceTenBeforeSplitInc(IEnumerable<CodeInstruction> instructions, MethodInfo splitMethod)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
int num = FindCallIndex(list, splitMethod);
if (num < 0)
{
return list;
}
int num2 = Math.Max(0, num - 48);
for (int num3 = num - 1; num3 >= num2; num3--)
{
if (IsLdcI4S10(list[num3]))
{
CodeInstruction val = list[num3];
CodeInstruction val2 = new CodeInstruction(OpCodes.Ldsfld, (object)CeilingField);
foreach (Label label in val.labels)
{
val2.labels.Add(label);
}
foreach (ExceptionBlock block in val.blocks)
{
val2.blocks.Add(block);
}
list[num3] = val2;
break;
}
}
return list;
}
internal static IEnumerable<CodeInstruction> ReplaceTenBeforeCargoIncTableRead(IEnumerable<CodeInstruction> instructions)
{
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
for (int num = list.Count - 1; num >= 0; num--)
{
if (!(list[num].opcode != OpCodes.Ldsfld) && list[num].operand == CargoIncTableField)
{
int num2 = Math.Max(0, num - 20);
for (int num3 = num - 1; num3 >= num2; num3--)
{
if (IsLdcI4S10(list[num3]))
{
CodeInstruction val = list[num3];
CodeInstruction val2 = new CodeInstruction(OpCodes.Ldsfld, (object)CeilingField);
foreach (Label label in val.labels)
{
val2.labels.Add(label);
}
foreach (ExceptionBlock block in val.blocks)
{
val2.blocks.Add(block);
}
list[num3] = val2;
return list;
}
}
}
}
return list;
}
private static int FindCallIndex(List<CodeInstruction> list, MethodInfo splitMethod)
{
for (int i = 0; i < list.Count; i++)
{
if ((!(list[i].opcode != OpCodes.Call) || !(list[i].opcode != OpCodes.Callvirt)) && list[i].operand is MethodInfo methodInfo && methodInfo == splitMethod)
{
return i;
}
}
return -1;
}
private static bool IsLdcI4S10(CodeInstruction c)
{
if (c.opcode != OpCodes.Ldc_I4_S)
{
return false;
}
object operand = c.operand;
if (!(operand is sbyte b))
{
if (operand is byte b2)
{
return b2 == 10;
}
return false;
}
return b == 10;
}
}
[HarmonyPatch(typeof(AssemblerComponent), "InternalUpdate")]
internal static class AssemblerIncCeilingPatch
{
[HarmonyTranspiler]
internal static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
return IncCeilingTranspiler.ReplaceTenBeforeSplitInc(instructions, IncCeilingTranspiler.AssemblerSplitInc);
}
}
[HarmonyPatch(typeof(LabComponent), "InternalUpdateAssemble")]
internal static class LabIncCeilingPatch
{
[HarmonyTranspiler]
internal static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
return IncCeilingTranspiler.ReplaceTenBeforeSplitInc(instructions, IncCeilingTranspiler.LabSplitInc);
}
}
[HarmonyPatch(typeof(SpraycoaterComponent), "InternalUpdate")]
internal static class SpraycoaterIncCeilingPatch
{
[HarmonyTranspiler]
internal static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
return IncCeilingTranspiler.ReplaceTenBeforeCargoIncTableRead(instructions);
}
}
[HarmonyPatch(typeof(GameMain), "Start")]
internal static class GameMainStartGenesisPatch
{
[HarmonyPostfix]
internal static void Postfix()
{
ProliferatorTweakPlugin.NotifyGameStarted();
}
}
[HarmonyPatch(typeof(ItemProto), "GetPropValue", new Type[]
{
typeof(int),
typeof(StringBuilder),
typeof(int)
})]
internal static class ItemProtoTooltipGuard
{
[HarmonyPrefix]
internal static void Prefix(ItemProto __instance)
{
int ability = __instance.Ability;
if (ability > 0 && (Cargo.incTable == null || ability >= Cargo.incTable.Length))
{
ProliferatorTweakPlugin.Instance?.EnsureCargoCoversAbilityIndex(ability);
}
}
}
[BepInPlugin("DSP.Kawaayi.ProliferatorTweak", "DSP Proliferator Tweak", "1.2.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class ProliferatorTweakPlugin : BaseUnityPlugin
{
public const string PluginGuid = "DSP.Kawaayi.ProliferatorTweak";
public const string PluginName = "DSP Proliferator Tweak";
public const string PluginVersion = "1.2.0";
public static int IncLevelAggregationCeiling = 10;
private const int VanillaTableLength = 11;
private const int DefaultCustomSlot = 11;
private ConfigEntry<int> _customAbilitySlot;
private ConfigEntry<int> _slotIncTenths;
private ConfigEntry<int> _slotAccTenths;
private ConfigEntry<int> _slotPowerTenths;
private ConfigEntry<bool> _patchGenesisProliferator;
private ConfigEntry<int> _genesisItemId;
private ConfigEntry<bool> _setGenesisSprayTimesHpMax;
private ConfigEntry<int> _genesisSprayTimesHpMax;
private int[]? _vanillaInc;
private int[]? _vanillaAcc;
private int[]? _vanillaPower;
private double[]? _vanillaIncMilli;
private double[]? _vanillaAccMilli;
private double[]? _vanillaPowerRatio;
private int[]? _vanillaIncFastNum;
private byte[]? _vanillaFastIncArrow;
private Harmony? _harmony;
public static ProliferatorTweakPlugin? Instance { get; private set; }
private void Awake()
{
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Expected O, but got Unknown
//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0203: Expected O, but got Unknown
Instance = this;
_customAbilitySlot = ((BaseUnityPlugin)this).Config.Bind<int>("CustomSlot", "AbilityIndex", 11, "自定义增产档位下标(与 ItemProto.Ability 一致)。原版合法为 1~10;默认 11 表示在 Cargo 表末尾新增一档。若 ≤10 则只覆盖该格数据、不扩容表。");
_slotIncTenths = ((BaseUnityPlugin)this).Config.Bind<int>("CustomSlot", "ExtraOutputTenths", 250, "该下标「额外产出」千分比×10 的整数(与原版 Cargo.incTable 一致):250 表示 +25.0%。");
_slotAccTenths = ((BaseUnityPlugin)this).Config.Bind<int>("CustomSlot", "SpeedBonusTenths", 1000, "该下标「制造速度」千分比×10:1000 表示 +100.0%。");
_slotPowerTenths = ((BaseUnityPlugin)this).Config.Bind<int>("CustomSlot", "ExtraPowerCostTenths", 1500, "该下标「额外耗电」千分比×10:1500 表示 +150.0%(可按需改)。");
_patchGenesisProliferator = ((BaseUnityPlugin)this).Config.Bind<bool>("GenesisBook", "SetGenesisItemAbility", true, "若为 true:尝试把创世之书物品 ItemProto.Ability 改为上面的自定义下标(默认物品 ID 1143)。");
_genesisItemId = ((BaseUnityPlugin)this).Config.Bind<int>("GenesisBook", "ItemId", 1143, "要改 Ability 的物品 ID(默认创世增产剂 1143)。");
_setGenesisSprayTimesHpMax = ((BaseUnityPlugin)this).Config.Bind<bool>("GenesisBook", "SetItemSprayTimesHpMax", true, "若为 true:把该物品的 ItemProto.HpMax 设为下方数值。喷涂机用 HpMax 作为每次喷涂的「次数」基准(与物品说明里喷涂次数一致)。");
_genesisSprayTimesHpMax = ((BaseUnityPlugin)this).Config.Bind<int>("GenesisBook", "SprayTimesHpMax", 60, new ConfigDescription("喷涂次数(写入 ItemProto.HpMax)。原版 Mk.I/II/III 增产约 12/24/60 量级,可按需调大。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 99999), Array.Empty<object>()));
_customAbilitySlot.SettingChanged += delegate
{
FullApply();
};
_slotIncTenths.SettingChanged += delegate
{
FullApply();
};
_slotAccTenths.SettingChanged += delegate
{
FullApply();
};
_slotPowerTenths.SettingChanged += delegate
{
FullApply();
};
_patchGenesisProliferator.SettingChanged += delegate
{
FullApply();
};
_genesisItemId.SettingChanged += delegate
{
FullApply();
};
_setGenesisSprayTimesHpMax.SettingChanged += delegate
{
FullApply();
};
_genesisSprayTimesHpMax.SettingChanged += delegate
{
FullApply();
};
SnapshotVanilla();
_harmony = new Harmony("DSP.Kawaayi.ProliferatorTweak");
_harmony.PatchAll(typeof(ProliferatorTweakPlugin).Assembly);
FullApply();
((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} v{1}:下标={2} 增产‰×10={3} 加速‰×10={4} 耗电‰×10={5};喷涂HpMax={6}", "DSP Proliferator Tweak", "1.2.0", _customAbilitySlot.Value, _slotIncTenths.Value, _slotAccTenths.Value, _slotPowerTenths.Value, _setGenesisSprayTimesHpMax.Value ? _genesisSprayTimesHpMax.Value.ToString() : "不改"));
}
private void OnDestroy()
{
Harmony? harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
Instance = null;
}
internal static void NotifyGameStarted()
{
Instance?.ApplyGenesisItemOnly();
}
private void FullApply()
{
ApplyCargoTablesAndCeiling();
ApplyGenesisItemOnly();
}
internal void EnsureCargoCoversAbilityIndex(int abilityIndex)
{
if (_vanillaInc != null && abilityIndex >= 0 && Cargo.incTable != null && abilityIndex >= Cargo.incTable.Length)
{
int value = _customAbilitySlot.Value;
if (value >= 0 && value <= 63)
{
int needLen = Math.Max(11, Math.Max(value + 1, abilityIndex + 1));
EnsureTableLengths(needLen);
IncLevelAggregationCeiling = Math.Max(IncLevelAggregationCeiling, Math.Max(10, Math.Max(value, abilityIndex)));
WriteCustomSlotValues();
}
}
}
private void ApplyGenesisItemOnly()
{
if ((!_patchGenesisProliferator.Value && !_setGenesisSprayTimesHpMax.Value) || (Object)(object)LDB.items == (Object)null)
{
return;
}
int value = _genesisItemId.Value;
int value2 = _customAbilitySlot.Value;
ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(value);
if (val != null && ((Proto)val).ID == value)
{
if (_patchGenesisProliferator.Value)
{
val.Ability = value2;
}
if (_setGenesisSprayTimesHpMax.Value)
{
val.HpMax = _genesisSprayTimesHpMax.Value;
}
}
}
private void ApplyCargoTablesAndCeiling()
{
if (_vanillaInc != null)
{
int value = _customAbilitySlot.Value;
if (value < 0 || value > 63)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)$"AbilityIndex={value} 超出安全范围,已忽略。");
return;
}
int needLen = Math.Max(11, value + 1);
EnsureTableLengths(needLen);
IncLevelAggregationCeiling = Math.Max(10, value);
WriteCustomSlotValues();
}
}
private void WriteCustomSlotValues()
{
if (_vanillaInc != null && Cargo.incTable != null)
{
int value = _customAbilitySlot.Value;
if (value >= 0 && value < Cargo.incTable.Length)
{
int num = Math.Max(0, _slotIncTenths.Value);
int num2 = Math.Max(0, _slotAccTenths.Value);
int num3 = Math.Max(0, _slotPowerTenths.Value);
Cargo.incTable[value] = num;
Cargo.accTable[value] = num2;
Cargo.powerTable[value] = num3;
Cargo.incTableMilli[value] = (double)num * 0.001;
Cargo.accTableMilli[value] = (double)num2 * 0.001;
Cargo.powerTableRatio[value] = 1.0 + (double)num3 * 0.001;
}
}
}
private void EnsureTableLengths(int needLen)
{
if (_vanillaInc != null && _vanillaAcc != null && _vanillaPower != null && _vanillaIncMilli != null && _vanillaAccMilli != null && _vanillaPowerRatio != null && _vanillaIncFastNum != null && _vanillaFastIncArrow != null && Cargo.incTable.Length < needLen)
{
Cargo.incTable = GrowArray(_vanillaInc, Cargo.incTable, needLen);
Cargo.accTable = GrowArray(_vanillaAcc, Cargo.accTable, needLen);
Cargo.powerTable = GrowArray(_vanillaPower, Cargo.powerTable, needLen);
Cargo.incTableMilli = GrowArray(_vanillaIncMilli, Cargo.incTableMilli, needLen);
Cargo.accTableMilli = GrowArray(_vanillaAccMilli, Cargo.accTableMilli, needLen);
Cargo.powerTableRatio = GrowArray(_vanillaPowerRatio, Cargo.powerTableRatio, needLen);
Cargo.incFastDivisionNumerator = GrowArray(_vanillaIncFastNum, Cargo.incFastDivisionNumerator, needLen);
Cargo.fastIncArrowTable = GrowArray(_vanillaFastIncArrow, Cargo.fastIncArrowTable, needLen);
}
}
private static int[] GrowArray(int[] snapshot, int[] current, int needLen)
{
if (current.Length >= needLen)
{
return current;
}
int[] array = new int[needLen];
Array.Copy(snapshot, array, snapshot.Length);
int num = snapshot[^1];
for (int i = snapshot.Length; i < needLen; i++)
{
array[i] = num;
}
return array;
}
private static double[] GrowArray(double[] snapshot, double[] current, int needLen)
{
if (current.Length >= needLen)
{
return current;
}
double[] array = new double[needLen];
Array.Copy(snapshot, array, snapshot.Length);
double num = snapshot[^1];
for (int i = snapshot.Length; i < needLen; i++)
{
array[i] = num;
}
return array;
}
private static byte[] GrowArray(byte[] snapshot, byte[] current, int needLen)
{
if (current.Length >= needLen)
{
return current;
}
byte[] array = new byte[needLen];
Array.Copy(snapshot, array, snapshot.Length);
byte b = snapshot[^1];
for (int i = snapshot.Length; i < needLen; i++)
{
array[i] = b;
}
return array;
}
private void SnapshotVanilla()
{
_vanillaInc = (int[])Cargo.incTable.Clone();
_vanillaAcc = (int[])Cargo.accTable.Clone();
_vanillaPower = (int[])Cargo.powerTable.Clone();
_vanillaIncMilli = (double[])Cargo.incTableMilli.Clone();
_vanillaAccMilli = (double[])Cargo.accTableMilli.Clone();
_vanillaPowerRatio = (double[])Cargo.powerTableRatio.Clone();
_vanillaIncFastNum = (int[])Cargo.incFastDivisionNumerator.Clone();
_vanillaFastIncArrow = (byte[])Cargo.fastIncArrowTable.Clone();
}
}
}