From f34dcf4f9679c90e6007b7764e56fca5f88f6048 Mon Sep 17 00:00:00 2001 From: Soar Qin Date: Thu, 14 Sep 2023 00:31:26 +0800 Subject: [PATCH] CheatEnabler 2.0.0 --- CheatEnabler/BuildPatch.cs | 195 +++++++++++++++++++++++++++++---- CheatEnabler/CheatEnabler.cs | 13 ++- CheatEnabler/README.md | 22 +++- CheatEnabler/TechPatch.cs | 5 +- CheatEnabler/UIConfigWindow.cs | 11 +- 5 files changed, 208 insertions(+), 38 deletions(-) diff --git a/CheatEnabler/BuildPatch.cs b/CheatEnabler/BuildPatch.cs index f1020cd..3679ef0 100644 --- a/CheatEnabler/BuildPatch.cs +++ b/CheatEnabler/BuildPatch.cs @@ -1,15 +1,17 @@ using System; using System.Collections.Generic; using System.Reflection.Emit; +using BepInEx; using BepInEx.Configuration; using HarmonyLib; +using UnityEngine; namespace CheatEnabler; public static class BuildPatch { public static ConfigEntry ImmediateEnabled; - public static ConfigEntry NoCostEnabled; + public static ConfigEntry ArchitectModeEnabled; public static ConfigEntry NoConditionEnabled; public static ConfigEntry NoCollisionEnabled; @@ -20,11 +22,11 @@ public static class BuildPatch { if (_patch != null) return; ImmediateEnabled.SettingChanged += (_, _) => ImmediateValueChanged(); - NoCostEnabled.SettingChanged += (_, _) => NoCostValueChanged(); + ArchitectModeEnabled.SettingChanged += (_, _) => ArchitectModeValueChanged(); NoConditionEnabled.SettingChanged += (_, _) => NoConditionValueChanged(); NoCollisionEnabled.SettingChanged += (_, _) => NoCollisionValueChanged(); ImmediateValueChanged(); - NoCostValueChanged(); + ArchitectModeValueChanged(); NoConditionValueChanged(); NoCollisionValueChanged(); _patch = Harmony.CreateAndPatchAll(typeof(BuildPatch)); @@ -43,16 +45,18 @@ public static class BuildPatch _noConditionPatch = null; } ImmediateBuild.Enable(false); - NoCostBuild.Enable(false); + ArchitectMode.Enable(false); + NightLightEnd(); } private static void ImmediateValueChanged() { ImmediateBuild.Enable(ImmediateEnabled.Value); } - private static void NoCostValueChanged() + private static void ArchitectModeValueChanged() { - NoCostBuild.Enable(NoCostEnabled.Value); + ArchitectMode.Enable(ArchitectModeEnabled.Value); + NightLightUpdateState(); } private static void NoConditionValueChanged() @@ -85,8 +89,8 @@ public static class BuildPatch public static void ArrivePlanet(PlanetFactory factory) { var imm = ImmediateEnabled.Value; - var noCost = NoCostEnabled.Value; - if (!imm && !noCost) return; + var architect = ArchitectModeEnabled.Value; + if (!imm && !architect) return; var prebuilds = factory.prebuildPool; if (imm) factory.BeginFlattenTerrain(); for (var i = factory.prebuildCursor - 1; i > 0; i--) @@ -94,7 +98,7 @@ public static class BuildPatch if (prebuilds[i].id != i) continue; if (prebuilds[i].itemRequired > 0) { - if (!noCost) continue; + if (!architect) continue; prebuilds[i].itemRequired = 0; if (imm) factory.BuildFinally(GameMain.mainPlayer, i, false); @@ -117,6 +121,153 @@ public static class BuildPatch ArrivePlanet(__instance.factory); } + /* Night Light Begin */ + private const float NightLightAngleX = -8; + private const float NightLightAngleY = -2; + public static bool NightlightEnabled; + private static bool _nightlightInitialized; + private static bool _mechaOnEarth; + private static AnimationState _sail; + private static Light _sunlight; + + private static void NightLightUpdateState() + { + if (ArchitectModeEnabled.Value) + { + NightlightEnabled = _mechaOnEarth; + return; + } + NightlightEnabled = false; + if (_sunlight == null) return; + _sunlight.transform.localEulerAngles = new Vector3(0f, 180f); + } + + public static void NightLightLateUpdate() + { + switch (_nightlightInitialized) + { + case false: + NightLightReady(); + break; + case true: + NightLightGo(); + break; + } + } + + private static void NightLightReady() + { + if (!GameMain.isRunning || !GameMain.mainPlayer.controller.model.gameObject.activeInHierarchy) return; + if (_sail == null) + { + _sail = GameMain.mainPlayer.animator.sails[GameMain.mainPlayer.animator.sailAnimIndex]; + } + + _nightlightInitialized = true; + } + + private static void NightLightGo() + { + if (!GameMain.isRunning) + { + NightLightEnd(); + return; + } + + if (_sail.enabled) + { + _mechaOnEarth = false; + NightlightEnabled = false; + if (_sunlight == null) return; + _sunlight.transform.localEulerAngles = new Vector3(0f, 180f); + _sunlight = null; + return; + } + + if (!_mechaOnEarth) + { + if (_sunlight == null) + { + _sunlight = GameMain.universeSimulator.LocalStarSimulator().sunLight; + if (_sunlight == null) return; + } + _mechaOnEarth = true; + NightlightEnabled = ArchitectModeEnabled.Value; + } + if (NightlightEnabled) + { + _sunlight.transform.rotation = + Quaternion.LookRotation(-GameMain.mainPlayer.transform.up + GameMain.mainPlayer.transform.forward * NightLightAngleX / 10f + GameMain.mainPlayer.transform.right * NightLightAngleY / 10f); + } + } + + private static void NightLightEnd() + { + _mechaOnEarth = false; + NightlightEnabled = false; + if (_sunlight != null) + { + _sunlight.transform.localEulerAngles = new Vector3(0f, 180f); + _sunlight = null; + } + _sail = null; + _nightlightInitialized = false; + } + + [HarmonyTranspiler] + [HarmonyPatch(typeof(StarSimulator), "LateUpdate")] + private static IEnumerable StarSimulator_LateUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) + { + // var vec = NightlightEnabled ? GameMain.mainPlayer.transform.up : __instance.transform.forward; + var matcher = new CodeMatcher(instructions, generator); + var label1 = generator.DefineLabel(); + var label2 = generator.DefineLabel(); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(OpCodes.Call, AccessTools.PropertyGetter(typeof(Component), nameof(Component.transform))) + ).InsertAndAdvance( + new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(BuildPatch), nameof(BuildPatch.NightlightEnabled))), + new CodeInstruction(OpCodes.Brfalse_S, label1), + new CodeInstruction(OpCodes.Call, AccessTools.PropertyGetter(typeof(GameMain), nameof(GameMain.mainPlayer))), + new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Player), nameof(Player.transform))), + new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Transform), nameof(Transform.up))), + new CodeInstruction(OpCodes.Stloc_0), + new CodeInstruction(OpCodes.Br_S, label2) + ); + matcher.Labels.Add(label1); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Stloc_0) + ).Advance(1).Labels.Add(label2); + return matcher.InstructionEnumeration(); + } + + [HarmonyTranspiler] + [HarmonyPatch(typeof(PlanetSimulator), "LateUpdate")] + private static IEnumerable PlanetSimulator_LateUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) + { + // var vec = (NightlightEnabled ? GameMain.mainPlayer.transform.up : (Quaternion.Inverse(localPlanet.runtimeRotation) * (__instance.planetData.star.uPosition - __instance.planetData.uPosition).normalized)); + var matcher = new CodeMatcher(instructions, generator); + var label1 = generator.DefineLabel(); + var label2 = generator.DefineLabel(); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Pop) + ).Advance(1).InsertAndAdvance( + new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(BuildPatch), nameof(BuildPatch.NightlightEnabled))), + new CodeInstruction(OpCodes.Brfalse_S, label1), + new CodeInstruction(OpCodes.Call, AccessTools.PropertyGetter(typeof(GameMain), nameof(GameMain.mainPlayer))), + new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Player), nameof(Player.transform))), + new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Transform), nameof(Transform.up))), + new CodeInstruction(OpCodes.Stloc_1), + new CodeInstruction(OpCodes.Br_S, label2) + ); + matcher.Labels.Add(label1); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(typeof(FactoryModel), nameof(FactoryModel.whiteMode0))) + ).Labels.Add(label2); + return matcher.InstructionEnumeration(); + } + /* Night Light End */ + private static class ImmediateBuild { private static Harmony _immediatePatch; @@ -159,22 +310,22 @@ public static class BuildPatch ).Insert( new CodeInstruction(OpCodes.Ldarg_0), new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(BuildTool), nameof(BuildTool.factory))), - new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(BuildPatch), nameof(BuildPatch.ArrivePlanet))) + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(BuildPatch), nameof(ArrivePlanet))) ); return matcher.InstructionEnumeration(); } } - private static class NoCostBuild + private static class ArchitectMode { - private static Harmony _noCostPatch; + private static Harmony _architectPatch; private static bool[] _canBuildItems; public static void Enable(bool enable) { if (enable) { - if (_noCostPatch != null) + if (_architectPatch != null) { return; } @@ -185,12 +336,12 @@ public static class BuildPatch ArrivePlanet(factory); } - _noCostPatch = Harmony.CreateAndPatchAll(typeof(NoCostBuild)); + _architectPatch = Harmony.CreateAndPatchAll(typeof(ArchitectMode)); } - else if (_noCostPatch != null) + else if (_architectPatch != null) { - _noCostPatch.UnpatchSelf(); - _noCostPatch = null; + _architectPatch.UnpatchSelf(); + _architectPatch = null; } } @@ -205,7 +356,7 @@ public static class BuildPatch { DoInit(); } - return itemId >= 10000 || !_canBuildItems[itemId]; + return itemId >= 12000 || !_canBuildItems[itemId]; } [HarmonyPostfix] [HarmonyPatch(typeof(StorageComponent), "GetItemCount", new Type[] { typeof(int) })] @@ -218,7 +369,7 @@ public static class BuildPatch { DoInit(); } - if (itemId < 10000 && _canBuildItems[itemId]) __result = 100; + if (itemId < 12000 && _canBuildItems[itemId]) __result = 100; } [HarmonyTranspiler] [HarmonyPatch(typeof(PlayerAction_Inspect), nameof(PlayerAction_Inspect.GetObjectSelectDistance))] @@ -230,10 +381,10 @@ public static class BuildPatch private static void DoInit() { - _canBuildItems = new bool[10000]; + _canBuildItems = new bool[12000]; foreach (var ip in LDB.items.dataArray) { - if (ip.CanBuild && ip.ID < 10000) _canBuildItems[ip.ID] = true; + if (ip.CanBuild && ip.ID < 12000) _canBuildItems[ip.ID] = true; } } } @@ -255,7 +406,7 @@ public static class BuildPatch private static IEnumerable BuildTool_Click_CheckBuildConditions_Transpiler(IEnumerable instructions) { yield return new CodeInstruction(OpCodes.Ldarg_0); - yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(NoConditionBuild), nameof(NoConditionBuild.CheckForMiner))); + yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(NoConditionBuild), nameof(CheckForMiner))); yield return new CodeInstruction(OpCodes.Ret); } diff --git a/CheatEnabler/CheatEnabler.cs b/CheatEnabler/CheatEnabler.cs index 5ac6bc5..bec8a6d 100644 --- a/CheatEnabler/CheatEnabler.cs +++ b/CheatEnabler/CheatEnabler.cs @@ -19,8 +19,6 @@ public class CheatEnabler : BaseUnityPlugin public static ConfigEntry Hotkey; private static bool _configWinInitialized = false; private static UIConfigWindow _configWin; - private static string _unlockTechToMaximumLevel = ""; - private static readonly List TechToUnlock = new(); private static Harmony _windowPatch; private static Harmony _patch; @@ -37,8 +35,8 @@ public class CheatEnabler : BaseUnityPlugin "Unlock clicked tech by holding key-modifilers(Shift/Alt/Ctrl)"); BuildPatch.ImmediateEnabled = Config.Bind("Build", "ImmediateBuild", false, "Build immediately"); - BuildPatch.NoCostEnabled = Config.Bind("Build", "InfiniteBuildings", false, - "Infinite buildings"); + BuildPatch.ArchitectModeEnabled = Config.Bind("Build", "Architect", false, + "Architect Mode"); BuildPatch.NoConditionEnabled = Config.Bind("Build", "BuildWithoutCondition", false, "Build without condition"); BuildPatch.NoCollisionEnabled = Config.Bind("Build", "NoCollision", false, @@ -103,7 +101,7 @@ public class CheatEnabler : BaseUnityPlugin BirthPlanetPatch.Init(); } - public void OnDestroy() + private void OnDestroy() { BirthPlanetPatch.Uninit(); DysonSpherePatch.Uninit(); @@ -129,6 +127,11 @@ public class CheatEnabler : BaseUnityPlugin ToggleConfigWindow(); } + private void LateUpdate() + { + BuildPatch.NightLightLateUpdate(); + } + [HarmonyPostfix, HarmonyPatch(typeof(UIRoot), nameof(UIRoot.OpenMainMenuUI))] public static void UIRoot_OpenMainMenuUI_Postfix() { diff --git a/CheatEnabler/README.md b/CheatEnabler/README.md index 392a983..fde4478 100644 --- a/CheatEnabler/README.md +++ b/CheatEnabler/README.md @@ -3,6 +3,14 @@ #### Add various cheat functions while disabling abnormal determinants #### 添加一些作弊功能,同时屏蔽异常检测 +## Changlog +* 2.0.0 + + Refactorying codes + + UI implementation + + Add a lot of functions +* 1.0.0 + + Initial release + ## Usage * Press `` LAlt+`(BackQuote) `` to call up the config panel. You can change the shortcut on the panel. @@ -15,7 +23,7 @@ + Unlock techs with key-modifiers (Ctrl/Alt/Shift) + Build: + Finish build immediately - + Architect mode (Infinite buildings + Interactive without distance limit) + + Architect mode (Infinite buildings + Interactive without distance limit + Sunlight at night) + Build without condition + No collision + Planet: @@ -43,19 +51,27 @@ * [Multifunction_mod](https://github.com/blacksnipebiu/Multifunction_mod): Some cheat functions * [LSTM](https://github.com/hetima/DSP_LSTM) & [PlanetFinder](https://github.com/hetima/DSP_PlanetFinder): UI implemnetations +## 更新日志 +* 2.0.0 + + 重构代码 + + UI实现 + + 添加了很多功能 +* 1.0.0 + + 初始版本 + ## 使用说明 * 按 `` 左Alt+`(反引号) `` 键呼出主面板,可以在面板上修改快捷键。 * 标题界面和行星小地图旁也有按钮呼出主面板。 * 功能: - + 更严格的建造菜单热键检测,因此在按住Ctrl/Alt/Shift时不再会触发建造热键(0~9, F1~F10, X, U)。 + + 更严格的建造菜单热键检测,因此在按住Ctrl/Alt/Shift时不再会触发建造热键(0~9, F1~F10, X, U) + 常规: + 启用开发模式快捷键(使用说明见设置面板) + 屏蔽异常检测 + 使用组合键解锁科技(Ctrl/Alt/Shift) + 建造: + 建造秒完成 - + 建筑师模式(无限建筑+无视距离操作) + + 建筑师模式(无限建筑+无视距离操作+夜间日光灯) + 无条件建造 + 无碰撞 + 行星: diff --git a/CheatEnabler/TechPatch.cs b/CheatEnabler/TechPatch.cs index cd3f62f..7af5c80 100644 --- a/CheatEnabler/TechPatch.cs +++ b/CheatEnabler/TechPatch.cs @@ -140,10 +140,9 @@ public static class TechPatch [HarmonyTranspiler] [HarmonyPatch(typeof(UITechNode), nameof(UITechNode.OnPointerDown))] - private static IEnumerable UITechNode_OnPointerDown_Transpiler( - IEnumerable instructions) + private static IEnumerable UITechNode_OnPointerDown_Transpiler(IEnumerable instructions, ILGenerator generator) { - var matcher = new CodeMatcher(instructions); + var matcher = new CodeMatcher(instructions, generator); matcher.MatchForward(false, new CodeMatch(OpCodes.Ldarg_0), new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UITechNode), nameof(UITechNode.tree))), diff --git a/CheatEnabler/UIConfigWindow.cs b/CheatEnabler/UIConfigWindow.cs index b7406e3..999929f 100644 --- a/CheatEnabler/UIConfigWindow.cs +++ b/CheatEnabler/UIConfigWindow.cs @@ -11,10 +11,10 @@ public class UIConfigWindow : UI.MyWindowWithTabs static UIConfigWindow() { I18N.Add("General", "General", "常规"); - I18N.Add("Enable Dev Shortcuts", "Enable Dev Shortcuts", "启用开发模式快捷键"); + I18N.Add("Enable Dev Shortcuts", "Enable Dev Shortcuts", "开发模式快捷键"); I18N.Add("Disable Abnormal Checks", "Disable Abnormal Checks", "关闭数据异常检查"); I18N.Add("Hotkey", "Hotkey", "快捷键"); - I18N.Add("Unlock Tech with Key-Modifiers", "Unlock Tech with Key-Modifiers", "使用组合键解锁科技"); + I18N.Add("Unlock Tech with Key-Modifiers", "Unlock Tech with Key-Modifiers", "使用组合键点击解锁科技"); I18N.Add("Dev Shortcuts", "Dev Shortcuts", "开发模式快捷键"); I18N.Add("Dev Shortcuts Tips", "Caution: Some function may trigger abnormal check!\nNumpad 1: Gets all items and extends bag.\nNumpad 2: Boosts walk speed, gathering speed and mecha energy restoration.\nNumpad 3: Fills planet with foundations and bury all veins.\nNumpad 4: +1 construction drone.\nNumpad 5: Upgrades drone engine tech to full.\nNumpad 6: Unlocks researching tech.\nNumpad 7: Unlocks Drive Engine 1.\nNumpad 8: Unlocks Drive Engine 2 and maximize energy.\nNumpad 9: Unlocks ability to warp.\nNumpad 0: No costs for Logistic Storages' output.\nLCtrl + T: Unlocks all techs (not upgrades).\nLCtrl + A: Resets all local achievements.\nLCtrl + Q: Adds 10000 to every metadata.\nLCtrl + W: Enters Sandbox Mode.\nLCtrl + Shift + W: Leaves Sandbox Mode.\nNumpad *: Proliferates items on hand.\nNumpad /: Removes proliferations from items on hand.\nPageDown: Remembers Pose of game camera.\nPageUp: Locks game camera using remembered Pose.", "警告:某些功能可能触发异常检查!\n小键盘1:获得所有物品并扩展背包\n小键盘2:加快行走速度及采集速度,加快能量恢复速度\n小键盘3:将地基铺设整个星球并掩埋所有矿物\n小键盘4:建设机器人 +1\n小键盘5:建设机器人满级\n小键盘6:解锁当前科技\n小键盘7:解锁驱动技术I\n小键盘8:解锁驱动技术II 最大化能量\n小键盘9:机甲曲速解锁\n小键盘0:物流站通过传送带出物品无消耗\n左Ctrl + T:解锁所有非升级科技\n左Ctrl + A:重置所有本地成就\n左Ctrl + Q:增加各项元数据10000点\n左Ctrl + W:进入沙盒模式\n左Ctrl + Shift + W:离开沙盒模式\n小键盘乘号 *:给手上物品喷涂增产剂\n小键盘除号 /:清除手上物品的增产剂\nPageDown:记录摄像机当前的Pose\nPageUp:用记录的Pose锁定摄像机"); @@ -23,7 +23,7 @@ public class UIConfigWindow : UI.MyWindowWithTabs I18N.Add("Build", "Build", "建造"); I18N.Add("Finish build immediately", "Finish build immediately", "建造秒完成"); I18N.Add("Architect mode", "Architect mode", "建筑师模式"); - I18N.Add("Build without condition", "Build without condition", "无条件建造"); + I18N.Add("Build without condition", "Build without condition check", "无条件建造"); I18N.Add("No collision", "No collision", "无碰撞"); I18N.Add("Planet", "Planet", "行星"); I18N.Add("Infinite Natural Resources", "Infinite Natural Resources", "自然资源采集不消耗"); @@ -81,9 +81,10 @@ public class UIConfigWindow : UI.MyWindowWithTabs UI.MyCheckBox.CreateCheckBox(x, y, tab1, TechPatch.Enabled, "Unlock Tech with Key-Modifiers"); y += 50f; UI.MyKeyBinder.CreateKeyBinder(x, y, tab1, CheatEnabler.Hotkey, "Hotkey"); - x = 180f; + x = 156f; y = 16f; AddTipsButton(x, y, tab1, "Dev Shortcuts", "Dev Shortcuts Tips", "dev-shortcuts-tips"); + x += 52f; y += 72f; AddTipsButton(x, y, tab1, "Unlock Tech with Key-Modifiers", "Unlock Tech with Key-Modifiers Tips", "unlock-tech-tips"); @@ -92,7 +93,7 @@ public class UIConfigWindow : UI.MyWindowWithTabs y = 10f; UI.MyCheckBox.CreateCheckBox(x, y, tab2, BuildPatch.ImmediateEnabled, "Finish build immediately"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab2, BuildPatch.NoCostEnabled, "Infinite buildings"); + UI.MyCheckBox.CreateCheckBox(x, y, tab2, BuildPatch.ArchitectModeEnabled, "Architect mode"); y += 36f; UI.MyCheckBox.CreateCheckBox(x, y, tab2, BuildPatch.NoConditionEnabled, "Build without condition"); y += 36f;