1
0
mirror of https://github.com/soarqin/DSP_Mods.git synced 2025-12-08 21:33:28 +08:00

CheatEnabler v2.2.3

This commit is contained in:
2023-09-25 20:39:18 +08:00
parent 80df6b3727
commit e79b906f91
7 changed files with 153 additions and 124 deletions

View File

@@ -38,6 +38,8 @@ public class CheatEnabler : BaseUnityPlugin
"Architect Mode");
FactoryPatch.UnlimitInteractiveEnabled = Config.Bind("Build", "UnlimitInteractive", false,
"Unlimit interactive range");
FactoryPatch.RemoveSomeConditionEnabled = Config.Bind("Build", "RemoveSomeBuildConditionCheck", false,
"Remove part of build condition checks that does not affect game logic");
FactoryPatch.NoConditionEnabled = Config.Bind("Build", "BuildWithoutCondition", false,
"Build without condition");
FactoryPatch.NoCollisionEnabled = Config.Bind("Build", "NoCollision", false,

View File

@@ -5,7 +5,7 @@
<TargetFramework>net472</TargetFramework>
<BepInExPluginGuid>org.soardev.cheatenabler</BepInExPluginGuid>
<Description>DSP MOD - CheatEnabler</Description>
<Version>2.2.2</Version>
<Version>2.2.3</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<PackageId>CheatEnabler</PackageId>

View File

@@ -12,6 +12,7 @@ public static class FactoryPatch
public static ConfigEntry<bool> ImmediateEnabled;
public static ConfigEntry<bool> ArchitectModeEnabled;
public static ConfigEntry<bool> UnlimitInteractiveEnabled;
public static ConfigEntry<bool> RemoveSomeConditionEnabled;
public static ConfigEntry<bool> NoConditionEnabled;
public static ConfigEntry<bool> NoCollisionEnabled;
public static ConfigEntry<bool> BeltSignalGeneratorEnabled;
@@ -25,6 +26,7 @@ public static class FactoryPatch
public static ConfigEntry<bool> BoostGeothermalPowerEnabled;
private static Harmony _factoryPatch;
private static Harmony _removeSomeConditionPatch;
private static Harmony _noConditionPatch;
public static void Init()
@@ -33,6 +35,7 @@ public static class FactoryPatch
ImmediateEnabled.SettingChanged += (_, _) => ImmediateValueChanged();
ArchitectModeEnabled.SettingChanged += (_, _) => ArchitectModeValueChanged();
UnlimitInteractiveEnabled.SettingChanged += (_, _) => UnlimitInteractiveValueChanged();
RemoveSomeConditionEnabled.SettingChanged += (_, _) => RemoveSomeConditionValueChanged();
NoConditionEnabled.SettingChanged += (_, _) => NoConditionValueChanged();
NoCollisionEnabled.SettingChanged += (_, _) => NoCollisionValueChanged();
BeltSignalGeneratorEnabled.SettingChanged += (_, _) => BeltSignalGeneratorValueChanged();
@@ -46,6 +49,7 @@ public static class FactoryPatch
ImmediateValueChanged();
ArchitectModeValueChanged();
UnlimitInteractiveValueChanged();
RemoveSomeConditionValueChanged();
NoConditionValueChanged();
NoCollisionValueChanged();
BeltSignalGeneratorValueChanged();
@@ -62,6 +66,8 @@ public static class FactoryPatch
{
_factoryPatch?.UnpatchSelf();
_factoryPatch = null;
_removeSomeConditionPatch?.UnpatchSelf();
_removeSomeConditionPatch = null;
_noConditionPatch?.UnpatchSelf();
_noConditionPatch = null;
ImmediateBuild.Enable(false);
@@ -91,6 +97,17 @@ public static class FactoryPatch
UnlimitInteractive.Enable(UnlimitInteractiveEnabled.Value);
}
private static void RemoveSomeConditionValueChanged()
{
if (RemoveSomeConditionEnabled.Value)
{
_removeSomeConditionPatch ??= Harmony.CreateAndPatchAll(typeof(RemoveSomeConditionBuild));
return;
}
_removeSomeConditionPatch?.UnpatchSelf();
_removeSomeConditionPatch = null;
}
private static void NoConditionValueChanged()
{
if (NoConditionEnabled.Value)
@@ -382,7 +399,7 @@ public static class FactoryPatch
if (matcher.Opcode != OpCodes.Nop && (matcher.Opcode != OpCodes.Call || !matcher.Instruction.OperandIs(AccessTools.Method(typeof(GC), nameof(GC.Collect)))))
return matcher.InstructionEnumeration();
var labels = matcher.Labels;
matcher.Labels = null;
matcher.Labels = new List<Label>();
matcher.Insert(
new CodeInstruction(OpCodes.Ldarg_0).WithLabels(labels),
new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(BuildTool), nameof(BuildTool.factory))),
@@ -432,7 +449,7 @@ public static class FactoryPatch
}
[HarmonyPostfix]
[HarmonyPatch(typeof(StorageComponent), "GetItemCount", new Type[] { typeof(int) })]
[HarmonyPatch(typeof(StorageComponent), "GetItemCount", typeof(int))]
public static void GetItemCountPatch(StorageComponent __instance, int itemId, ref int __result)
{
if (__result > 99) return;
@@ -442,7 +459,6 @@ public static class FactoryPatch
{
DoInit();
}
if (itemId < 12000 && _canBuildItems[itemId]) __result = 100;
}
@@ -480,6 +496,102 @@ public static class FactoryPatch
}
}
private static class RemoveSomeConditionBuild
{
[HarmonyTranspiler, HarmonyPriority(Priority.First)]
[HarmonyPatch(typeof(BuildTool_BlueprintPaste), nameof(BuildTool_BlueprintPaste.CheckBuildConditions))]
[HarmonyPatch(typeof(BuildTool_Click), nameof(BuildTool_Click.CheckBuildConditions))]
private static IEnumerable<CodeInstruction> BuildTool_Click_CheckBuildConditions_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
var matcher = new CodeMatcher(instructions, generator);
/* search for:
* ldloc.s V_8 (8)
* ldfld class PrefabDesc BuildPreview::desc
* ldfld bool PrefabDesc::isInserter
* brtrue 2358 (1C12) ldloc.s V_8 (8)
* ldloca.s V_10 (10)
* call instance float32 [UnityEngine.CoreModule]UnityEngine.Vector3::get_magnitude()
*/
matcher.MatchForward(false,
new CodeMatch(OpCodes.Ldloc_S),
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(BuildPreview), nameof(BuildPreview.desc))),
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PrefabDesc), nameof(PrefabDesc.isInserter))),
new CodeMatch(instr => instr.opcode == OpCodes.Brtrue || instr.opcode == OpCodes.Brtrue_S),
new CodeMatch(OpCodes.Ldloca_S),
new CodeMatch(OpCodes.Call, AccessTools.PropertyGetter(typeof(Vector3), nameof(Vector3.magnitude)))
);
var jumpPos = matcher.InstructionAt(3).operand;
var labels = matcher.Labels;
matcher.Labels = new List<Label>();
/* Insert: br 2358 (1C12) ldloc.s V_8 (8)
*/
matcher.Insert(new CodeInstruction(OpCodes.Br, jumpPos).WithLabels(labels));
return matcher.InstructionEnumeration();
}
[HarmonyTranspiler, HarmonyPriority(Priority.First)]
[HarmonyPatch(typeof(BuildTool_Path), nameof(BuildTool_Path.CheckBuildConditions))]
private static IEnumerable<CodeInstruction> BuildTool_Path_CheckBuildConditions_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
var matcher = new CodeMatcher(instructions, generator);
/* search for:
* ldloc.s V_88 (88)
* ldloc.s V_120 (120)
* brtrue.s 2054 (173A) ldc.i4.s 17
* ldc.i4.s 18
* br.s 2055 (173C) stfld valuetype EBuildCondition BuildPreview::condition
* ldc.i4.s 17
* stfld valuetype EBuildCondition BuildPreview::condition
*/
matcher.MatchForward(false,
new CodeMatch(OpCodes.Ldloc_S),
new CodeMatch(OpCodes.Ldloc_S),
new CodeMatch(instr => instr.opcode == OpCodes.Brtrue_S || instr.opcode == OpCodes.Brtrue),
new CodeMatch(instr => instr.opcode == OpCodes.Ldc_I4_S && instr.OperandIs(18)),
new CodeMatch(instr => instr.opcode == OpCodes.Br_S || instr.opcode == OpCodes.Br),
new CodeMatch(instr => instr.opcode == OpCodes.Ldc_I4_S && instr.OperandIs(17)),
new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(BuildPreview), nameof(BuildPreview.condition)))
);
if (matcher.IsValid)
{
// Remove 7 instructions, if the following instruction is br/br.s, remove it as well
var labels = matcher.Labels;
matcher.Labels = new List<Label>();
matcher.RemoveInstructions(7);
var opcode = matcher.Opcode;
if (opcode == OpCodes.Br || opcode == OpCodes.Br_S)
matcher.RemoveInstruction();
matcher.Labels.AddRange(labels);
}
/* search for:
* ldloc.s V_88 (88)
* ldc.i4.s 15-18
* stfld valuetype EBuildCondition BuildPreview::condition
*/
matcher.Start().MatchForward(false,
new CodeMatch(instr => instr.opcode == OpCodes.Ldloc_S || instr.opcode == OpCodes.Ldloc),
new CodeMatch(instr => (instr.opcode == OpCodes.Ldc_I4_S || instr.opcode == OpCodes.Ldc_I4) &&
(instr.OperandIs(15) || instr.OperandIs(16) || instr.OperandIs(17) || instr.OperandIs(18))),
new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(BuildPreview), nameof(BuildPreview.condition)))
);
if (matcher.IsValid)
{
// Remove 3 instructions, if the following instruction is br/br.s, remove it as well
matcher.Repeat(codeMatcher =>
{
var labels = codeMatcher.Labels;
codeMatcher.Labels = new List<Label>();
codeMatcher.RemoveInstructions(3);
var opcode = codeMatcher.Opcode;
if (opcode == OpCodes.Br || opcode == OpCodes.Br_S)
codeMatcher.RemoveInstruction();
codeMatcher.Labels.AddRange(labels);
});
}
return matcher.InstructionEnumeration();
}
}
private static class NoConditionBuild
{
[HarmonyTranspiler, HarmonyPriority(Priority.Last)]
@@ -621,7 +733,7 @@ public static class FactoryPatch
continue;
case >= 601 and <= 609:
if (number > 0)
SetSignalBeltPortalTo(factory.index, i, (int)signalId, number);
SetSignalBeltPortalTo(factory.index, i, number);
continue;
}
}
@@ -744,7 +856,7 @@ public static class FactoryPatch
beltSignal.SourceProgress = progress;
}
private static void SetSignalBeltPortalTo(int factory, int beltId, int signalId, int number)
private static void SetSignalBeltPortalTo(int factory, int beltId, int number)
{
var v = ((long)factory << 32) | (uint)beltId;
_portalFrom[v] = number;
@@ -817,7 +929,7 @@ public static class FactoryPatch
var factoryIndex = planet.factoryIndex;
var beltId = factory.entityPool[entityId].beltId;
if (number > 0)
SetSignalBeltPortalTo(factoryIndex, beltId, signalId, number);
SetSignalBeltPortalTo(factoryIndex, beltId, number);
RemoveSignalBelt(factoryIndex, beltId);
return;
default:
@@ -863,7 +975,7 @@ public static class FactoryPatch
var factoryIndex = planet.factoryIndex;
var beltId = factory.entityPool[entityId].beltId;
RemoveSignalBeltPortalEnd(factoryIndex, beltId);
SetSignalBeltPortalTo(factoryIndex, beltId, (int)signalId, Mathf.RoundToInt(number));
SetSignalBeltPortalTo(factoryIndex, beltId, Mathf.RoundToInt(number));
return;
default:
return;
@@ -1279,7 +1391,7 @@ public static class FactoryPatch
new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(PowerGeneratorComponent), nameof(PowerGeneratorComponent.capacityCurrentTick)))
);
var labels = matcher.Labels;
matcher.Labels = null;
matcher.Labels = new List<Label>();
matcher.Insert(
// if (this.fuelMask == 4)
new CodeInstruction(OpCodes.Ldarg_0).WithLabels(labels),

View File

@@ -1,113 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using HarmonyLib;
using System.Threading;
using Random = UnityEngine.Random;
namespace CheatEnabler;
public static class PlanetFunctions
{
/*
private static Harmony _patch;
private static PumpSource[] _pumpItemSources = new PumpSource[16];
private static int _pumpItemSourcesLength = 16;
private class PumpSource
{
public Tuple<int, float>[] Items;
public float[] Progress;
}
public static void Init()
{
if (_patch != null) return;
_patch = Harmony.CreateAndPatchAll(typeof(PlanetFunctions));
}
public static void Uninit()
{
_patch?.UnpatchSelf();
_patch = null;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))]
private static void GameMain_Begin_Postfix()
{
InitItemSources();
var factories = GameMain.data.factories;
for (var i = GameMain.data.factoryCount - 1; i >= 0; i--)
{
if (factories[i].index != i) continue;
UpdatePumpItemSources(factories[i]);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlanetFactory), nameof(PlanetFactory.Init))]
private static void PlanetFactory_Init_Postfix(PlanetFactory __instance)
{
const int waterItemId = 6006;
__instance.planet.waterItemId = waterItemId;
CheatEnabler.Logger.LogDebug($"Init PlanetFactory with waterItemId {waterItemId}");
UpdatePumpItemSources(__instance);
}
private static void UpdatePumpItemSources(PlanetFactory factory)
{
var index = factory.index;
var waterItemId = factory.planet.waterItemId;
if (waterItemId == 0 || !ItemSources.TryGetValue(waterItemId, out var itemSource) || itemSource.From == null)
{
if (index < _pumpItemSourcesLength)
{
_pumpItemSources[index] = null;
}
return;
}
if (index >= _pumpItemSourcesLength)
{
var newLength = _pumpItemSourcesLength * 2;
while (index >= newLength)
{
newLength *= 2;
}
var newPumpItemSources = new PumpSource[newLength];
Array.Copy(_pumpItemSources, newPumpItemSources, _pumpItemSourcesLength);
_pumpItemSources = newPumpItemSources;
_pumpItemSourcesLength = newLength;
}
var pump = _pumpItemSources[index];
if (pump == null)
{
pump = new PumpSource();
_pumpItemSources[index] = pump;
}
var result = new Dictionary<int, float>();
var extra = new Dictionary<int, float>();
CalculateAllProductions(result, extra, waterItemId, 1f);
foreach (var p in extra)
{
if (!result.TryGetValue(p.Key, out var cnt) || cnt < p.Value)
{
result[p.Key] = p.Value;
}
}
var count = result.Count;
var items = new Tuple<int, float>[count];
var progress = new float[count];
foreach (var p in result)
{
items[--count] = Tuple.Create(p.Key, p.Value);
}
pump.Items = items;
pump.Progress = progress;
}
*/
public static void DismantleAll(bool toBag)
{
var player = GameMain.mainPlayer;

View File

@@ -4,6 +4,9 @@
#### 添加一些作弊功能,同时屏蔽异常检测
## Changlog
* 2.2.3
+ New function: `Remove some build conditions`
+ Fix compatibility with some mods
* 2.2.2
+ New function: `Assign game to currrnet account`
+ New subfunction: `Belt signal alt format`
@@ -32,7 +35,7 @@
* There are also buttons on title screen and planet minimap area to call up the config panel.
* Features:
+ Strict hotkey dectection for build menu, thus building hotkeys(0~9, F1~F10, X, U) are not triggered while holding Ctrl/Alt/Shift.
+ General:
+ General:
+ Enable Dev Shortcuts (check config panel for usage)
+ Disable Abnormal Checks
+ Unlock techs with key-modifiers (Ctrl/Alt/Shift)
@@ -42,6 +45,7 @@
+ Architect mode (Infinite buildings)
+ Unlimited interactive range
+ Build without condition
+ Remove some build conditions
+ No collision
+ Sunlight at night
+ Belt signal item generation
@@ -80,6 +84,9 @@
* [LSTM](https://github.com/hetima/DSP_LSTM) & [PlanetFinder](https://github.com/hetima/DSP_PlanetFinder): UI implementations
## 更新日志
* 2.2.3
+ 新功能:`移除部分不影响游戏逻辑的建造条件`
+ 修复了与一些mod的兼容性问题
* 2.2.2
+ 新功能:`将游戏绑定给当前账号`
+ 新子功能:`传送带信号替换格式`
@@ -118,6 +125,7 @@
+ 建筑师模式(无限建筑)
+ 无限交互距离
+ 无条件建造
+ 移除部分不影响游戏逻辑的建造条件
+ 无碰撞
+ 夜间日光灯
+ 传送带信号物品生成

View File

@@ -29,6 +29,7 @@ public class UIConfigWindow : UI.MyWindowWithTabs
I18N.Add("Finish build immediately", "Finish build immediately", "建造秒完成");
I18N.Add("Architect mode", "Architect mode", "建筑师模式");
I18N.Add("Unlimited interactive range", "Unlimited interactive range", "无限交互距离");
I18N.Add("Remove some build conditions", "Remove some build conditions", "移除部分不影响游戏逻辑的建造条件");
I18N.Add("Build without condition", "Build without condition check", "无条件建造");
I18N.Add("No collision", "No collision", "无碰撞");
I18N.Add("Belt signal generator", "Belt signal generator", "传送带信号物品生成");
@@ -133,18 +134,19 @@ public class UIConfigWindow : UI.MyWindowWithTabs
var cb = UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BeltSignalCountRecipeEnabled, "Count all raws and intermediates in statistics", 13);
y += 26f;
var cb2 = UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BeltSignalNumberAltFormat, "Belt signal alt format", 13);
cb.gameObject.SetActive(FactoryPatch.BeltSignalGeneratorEnabled.Value);
cb2.gameObject.SetActive(FactoryPatch.BeltSignalGeneratorEnabled.Value);
FactoryPatch.BeltSignalGeneratorEnabled.SettingChanged += (_, _) =>
{
cb.gameObject.SetActive(FactoryPatch.BeltSignalGeneratorEnabled.Value);
cb2.gameObject.SetActive(FactoryPatch.BeltSignalGeneratorEnabled.Value);
};
x += 180f;
y += 6f;
AddTipsButton(x, y, tab2, "Belt signal alt format", "Belt signal alt format tips", "belt-signal-alt-format-tips");
var tip1 = AddTipsButton(x, y, tab2, "Belt signal alt format", "Belt signal alt format tips", "belt-signal-alt-format-tips");
FactoryPatch.BeltSignalGeneratorEnabled.SettingChanged += (_, _) =>
{
OnBeltSignalChanged();
};
OnBeltSignalChanged();
x = 240f;
y = 10f;
UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.RemoveSomeConditionEnabled, "Remove some build conditions");
y += 36f;
UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.RemovePowerSpaceLimitEnabled, "Remove power space limit");
y += 36f;
UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BoostWindPowerEnabled, "Boost wind power");
@@ -259,6 +261,15 @@ public class UIConfigWindow : UI.MyWindowWithTabs
SetCurrentTab(0);
UpdateUI();
return;
void OnBeltSignalChanged()
{
var on = FactoryPatch.BeltSignalGeneratorEnabled.Value;
cb.gameObject.SetActive(on);
cb2.gameObject.SetActive(on);
tip1.gameObject.SetActive(on);
}
}
public void UpdateUI()

View File

@@ -1,6 +1,6 @@
{
"name": "CheatEnabler",
"version_number": "2.2.2",
"version_number": "2.2.3",
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/CheatEnabler",
"description": "Add various cheat functions while disabling abnormal determinants / 添加一些作弊功能,同时屏蔽异常检测",
"dependencies": [