From fb916b381392ab6fde8f87a5b3d9c46fe7ed504b Mon Sep 17 00:00:00 2001 From: Soar Qin Date: Tue, 17 Sep 2024 01:49:25 +0800 Subject: [PATCH] refactoring UXAssist and CheatEnabler --- CheatEnabler/AbnormalDiabler.cs | 69 ---- CheatEnabler/CheatEnabler.cs | 39 +-- CheatEnabler/DevShortcuts.cs | 110 ------- .../{ => Functions}/DysonSphereFunctions.cs | 35 +- .../{ => Functions}/PlanetFunctions.cs | 2 +- .../{ => Functions}/PlayerFunctions.cs | 2 +- CheatEnabler/{ => Patches}/CombatPatch.cs | 37 +-- .../{ => Patches}/DysonSpherePatch.cs | 120 ++----- CheatEnabler/{ => Patches}/FactoryPatch.cs | 145 ++------- CheatEnabler/Patches/GamePatch.cs | 306 ++++++++++++++++++ CheatEnabler/{ => Patches}/PlanetPatch.cs | 39 +-- CheatEnabler/{ => Patches}/PlayerPatch.cs | 37 +-- CheatEnabler/{ => Patches}/ResourcePatch.cs | 37 +-- CheatEnabler/TechPatch.cs | 154 --------- CheatEnabler/UIConfigWindow.cs | 10 +- UXAssist/AuxilaryfunctionWrapper.cs | 25 -- UXAssist/Common/PatchImpl.cs | 33 ++ UXAssist/Common/Util.cs | 9 +- UXAssist/{ => Functions}/PlanetFunctions.cs | 2 +- .../ModsCompat/AuxilaryfunctionWrapper.cs | 49 +++ UXAssist/ModsCompat/BulletTimeWrapper.cs | 52 +++ UXAssist/{ => Patches}/DysonSpherePatch.cs | 50 +-- UXAssist/{ => Patches}/FactoryPatch.cs | 274 ++++------------ UXAssist/{ => Patches}/GamePatch.cs | 225 +++++++------ UXAssist/{ => Patches}/LogisticsPatch.cs | 50 +-- UXAssist/{ => Patches}/PlanetPatch.cs | 18 +- UXAssist/{ => Patches}/PlayerPatch.cs | 53 +-- UXAssist/{ => Patches}/TechPatch.cs | 39 +-- UXAssist/UI/MyWindow.cs | 1 + UXAssist/UIConfigWindow.cs | 43 ++- UXAssist/UXAssist.cs | 53 +-- 31 files changed, 858 insertions(+), 1260 deletions(-) delete mode 100644 CheatEnabler/AbnormalDiabler.cs delete mode 100644 CheatEnabler/DevShortcuts.cs rename CheatEnabler/{ => Functions}/DysonSphereFunctions.cs (82%) rename CheatEnabler/{ => Functions}/PlanetFunctions.cs (97%) rename CheatEnabler/{ => Functions}/PlayerFunctions.cs (99%) rename CheatEnabler/{ => Patches}/CombatPatch.cs (81%) rename CheatEnabler/{ => Patches}/DysonSpherePatch.cs (89%) rename CheatEnabler/{ => Patches}/FactoryPatch.cs (94%) create mode 100644 CheatEnabler/Patches/GamePatch.cs rename CheatEnabler/{ => Patches}/PlanetPatch.cs (78%) rename CheatEnabler/{ => Patches}/PlayerPatch.cs (76%) rename CheatEnabler/{ => Patches}/ResourcePatch.cs (83%) delete mode 100644 CheatEnabler/TechPatch.cs delete mode 100644 UXAssist/AuxilaryfunctionWrapper.cs create mode 100644 UXAssist/Common/PatchImpl.cs rename UXAssist/{ => Functions}/PlanetFunctions.cs (99%) create mode 100644 UXAssist/ModsCompat/AuxilaryfunctionWrapper.cs create mode 100644 UXAssist/ModsCompat/BulletTimeWrapper.cs rename UXAssist/{ => Patches}/DysonSpherePatch.cs (95%) rename UXAssist/{ => Patches}/FactoryPatch.cs (92%) rename UXAssist/{ => Patches}/GamePatch.cs (86%) rename UXAssist/{ => Patches}/LogisticsPatch.cs (98%) rename UXAssist/{ => Patches}/PlanetPatch.cs (90%) rename UXAssist/{ => Patches}/PlayerPatch.cs (93%) rename UXAssist/{ => Patches}/TechPatch.cs (94%) diff --git a/CheatEnabler/AbnormalDiabler.cs b/CheatEnabler/AbnormalDiabler.cs deleted file mode 100644 index 3553288..0000000 --- a/CheatEnabler/AbnormalDiabler.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System.Collections.Generic; -using BepInEx.Configuration; -using HarmonyLib; - -namespace CheatEnabler; -public static class AbnormalDisabler -{ - public static ConfigEntry Enabled; - private static Dictionary _savedDeterminators; - private static Harmony _patch; - - public static void Init() - { - _patch ??= Harmony.CreateAndPatchAll(typeof(AbnormalDisabler)); - } - - public static void Uninit() - { - _patch?.UnpatchSelf(); - _patch = null; - } - - [HarmonyPrefix] - [HarmonyPatch(typeof(AbnormalityLogic), "NotifyBeforeGameSave")] - [HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnAssemblerRecipePick")] - [HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnGameBegin")] - [HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnMechaForgeTaskComplete")] - [HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnUnlockTech")] - [HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnUseConsole")] - private static bool DisableAbnormalLogic() - { - return !Enabled.Value; - } - - [HarmonyPostfix] - [HarmonyPatch(typeof(AbnormalityLogic), "InitDeterminators")] - private static void DisableAbnormalDeterminators(AbnormalityLogic __instance) - { - _savedDeterminators = __instance.determinators; - Enabled.SettingChanged += (_, _) => - { - if (Enabled.Value) - { - _savedDeterminators = __instance.determinators; - __instance.determinators = new Dictionary(); - foreach (var p in _savedDeterminators) - { - p.Value.OnUnregEvent(); - } - } - else - { - __instance.determinators = _savedDeterminators; - foreach (var p in _savedDeterminators) - { - p.Value.OnRegEvent(); - } - } - }; - - _savedDeterminators = __instance.determinators; - if (!Enabled.Value) return; - __instance.determinators = new Dictionary(); - foreach (var p in _savedDeterminators) - { - p.Value.OnUnregEvent(); - } - } -} diff --git a/CheatEnabler/CheatEnabler.cs b/CheatEnabler/CheatEnabler.cs index 88930d5..d7c3a6e 100644 --- a/CheatEnabler/CheatEnabler.cs +++ b/CheatEnabler/CheatEnabler.cs @@ -1,4 +1,9 @@ -using BepInEx; +using System.Reflection; +using BepInEx; +using CheatEnabler.Functions; +using CheatEnabler.Patches; +using HarmonyLib; +using UXAssist.Common; namespace CheatEnabler; @@ -11,10 +16,10 @@ public class CheatEnabler : BaseUnityPlugin private void Awake() { - DevShortcuts.Enabled = Config.Bind("General", "DevShortcuts", false, "Enable DevMode shortcuts"); - AbnormalDisabler.Enabled = Config.Bind("General", "DisableAbnormalChecks", false, + GamePatch.DevShortcutsEnabled = Config.Bind("General", "DevShortcuts", false, "Enable DevMode shortcuts"); + GamePatch.AbnormalDisablerEnabled = Config.Bind("General", "DisableAbnormalChecks", false, "disable all abnormal checks"); - TechPatch.Enabled = Config.Bind("General", "UnlockTech", false, + GamePatch.UnlockTechEnabled = Config.Bind("General", "UnlockTech", false, "Unlock clicked tech by holding key-modifilers(Shift/Alt/Ctrl)"); FactoryPatch.ImmediateEnabled = Config.Bind("Build", "ImmediateBuild", false, "Build immediately"); @@ -78,33 +83,19 @@ public class CheatEnabler : BaseUnityPlugin "Mecha and Drones/Fleets invincible"); CombatPatch.BuildingsInvincibleEnabled = Config.Bind("Battle", "BuildingsInvincible", false, "Buildings invincible"); - + } + private void Start() { UIConfigWindow.Init(); - - DevShortcuts.Init(); - AbnormalDisabler.Init(); - TechPatch.Init(); - FactoryPatch.Init(); - ResourcePatch.Init(); - PlanetPatch.Init(); + Util.GetTypesInNamespace(Assembly.GetExecutingAssembly(), "CheatEnabler.Patches") + .Do(type => type.GetMethod("Init")?.Invoke(null, null)); PlayerFunctions.Init(); - PlayerPatch.Init(); - DysonSpherePatch.Init(); DysonSphereFunctions.Init(); - CombatPatch.Init(); } private void OnDestroy() { - CombatPatch.Uninit(); - DysonSpherePatch.Uninit(); - PlayerPatch.Uninit(); - PlanetPatch.Uninit(); - ResourcePatch.Uninit(); - FactoryPatch.Uninit(); - TechPatch.Uninit(); - AbnormalDisabler.Uninit(); - DevShortcuts.Uninit(); + Util.GetTypesInNamespace(Assembly.GetExecutingAssembly(), "CheatEnabler.Patches") + .Do(type => type.GetMethod("Uninit")?.Invoke(null, null)); } private void Update() diff --git a/CheatEnabler/DevShortcuts.cs b/CheatEnabler/DevShortcuts.cs deleted file mode 100644 index 01b3824..0000000 --- a/CheatEnabler/DevShortcuts.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System.Collections.Generic; -using System.Reflection.Emit; -using BepInEx.Configuration; -using HarmonyLib; - -namespace CheatEnabler; -public static class DevShortcuts -{ - public static ConfigEntry Enabled; - private static Harmony _patch; - private static PlayerAction_Test _test; - - public static void Init() - { - _patch ??= Harmony.CreateAndPatchAll(typeof(DevShortcuts)); - Enabled.SettingChanged += (_, _) => - { - if (_test != null) _test.active = Enabled.Value; - }; - } - - public static void Uninit() - { - _patch?.UnpatchSelf(); - _patch = null; - } - - [HarmonyPostfix] - [HarmonyPatch(typeof(PlayerController), nameof(PlayerController.Init))] - private static void PlayerController_Init_Postfix(PlayerController __instance) - { - var cnt = __instance.actions.Length; - var newActions = new PlayerAction[cnt + 1]; - for (var i = 0; i < cnt; i++) - { - newActions[i] = __instance.actions[i]; - } - - _test = new PlayerAction_Test(); - _test.Init(__instance.player); - _test.active = Enabled.Value; - newActions[cnt] = _test; - __instance.actions = newActions; - } - - [HarmonyPostfix] - [HarmonyPatch(typeof(PlayerAction_Test), nameof(PlayerAction_Test.GameTick))] - private static void PlayerAction_Test_GameTick_Postfix(PlayerAction_Test __instance) - { - __instance.Update(); - } - - [HarmonyTranspiler] - [HarmonyPatch(typeof(PlayerAction_Test), nameof(PlayerAction_Test.Update))] - private static IEnumerable PlayerAction_Test_Update_Transpiler(IEnumerable instructions, ILGenerator generator) - { - var matcher = new CodeMatcher(instructions, generator); - matcher.End().MatchBack(false, - new CodeMatch(OpCodes.Ldarg_0), - new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PlayerAction_Test), nameof(PlayerAction_Test.active))) - ); - var pos = matcher.Pos; - /* Remove Shift+F4 part of the method */ - matcher.Start().RemoveInstructions(pos).MatchForward(false, - new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(GameMain), "get_sandboxToolsEnabled")), - new CodeMatch(OpCodes.Ldc_I4_0), - new CodeMatch(OpCodes.Ceq) - ); - var labels = matcher.Labels; - matcher.SetInstructionAndAdvance( - new CodeInstruction(OpCodes.Ldc_I4_1).WithLabels(labels) - ).RemoveInstructions(2); - /* Remove Ctrl+A */ - matcher.Start().MatchForward(false, - new CodeMatch(instr => (instr.opcode == OpCodes.Ldc_I4_S || instr.opcode == OpCodes.Ldc_I4) && instr.OperandIs(0x61)), - new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(UnityEngine.Input), nameof(UnityEngine.Input.GetKeyDown), new[] { typeof(UnityEngine.KeyCode) })) - ); - labels = matcher.Labels; - matcher.Labels = null; - matcher.RemoveInstructions(2); - matcher.Opcode = OpCodes.Br; - matcher.Labels = labels; - return matcher.InstructionEnumeration(); - } - - [HarmonyTranspiler] - [HarmonyPatch(typeof(GameCamera), nameof(GameCamera.FrameLogic))] - private static IEnumerable GameCamera_Logic_Transpiler(IEnumerable instructions) - { - var matcher = new CodeMatcher(instructions); - matcher.MatchForward(false, - new CodeMatch(OpCodes.Ldarg_0), - new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(GameCamera), nameof(GameCamera.finalPoser))), - new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(CameraPoser), nameof(CameraPoser.cameraPose))) - ); - var labels = matcher.Labels; - matcher.Labels = null; - matcher.Insert( - new CodeInstruction(OpCodes.Ldarg_0).WithLabels(labels), - Transpilers.EmitDelegate((GameCamera camera) => - { - if (PlayerAction_Test.lockCam) - { - camera.finalPoser.cameraPose = PlayerAction_Test.camPose; - } - }) - ); - return matcher.InstructionEnumeration(); - } -} diff --git a/CheatEnabler/DysonSphereFunctions.cs b/CheatEnabler/Functions/DysonSphereFunctions.cs similarity index 82% rename from CheatEnabler/DysonSphereFunctions.cs rename to CheatEnabler/Functions/DysonSphereFunctions.cs index 3c800d7..784d5b6 100644 --- a/CheatEnabler/DysonSphereFunctions.cs +++ b/CheatEnabler/Functions/DysonSphereFunctions.cs @@ -1,7 +1,7 @@ using HarmonyLib; using UXAssist.Common; -namespace CheatEnabler; +namespace CheatEnabler.Functions; public static class DysonSphereFunctions { @@ -42,8 +42,8 @@ public static class DysonSphereFunctions var totalFrameSpInfo = AccessTools.Field(typeof(DysonSphereLayer), "totalFrameSP"); var totalCpInfo = AccessTools.Field(typeof(DysonSphereLayer), "totalCP"); - var rocketCount = 0; - var solarSailCount = 0; + var rocketCount = 0L; + var solarSailCount = 0L; foreach (var dysonSphereLayer in dysonSphere.layersIdBased) { if (dysonSphereLayer == null) continue; @@ -112,11 +112,24 @@ public static class DysonSphereFunctions { lock (productRegister) { - if (rocketCount > 0) productRegister[11902] += rocketCount; - if (solarSailCount > 0) + var count = rocketCount; + while (count > 0x40000000L) { - productRegister[11901] += solarSailCount; - productRegister[11903] += solarSailCount; + productRegister[11902] += 0x40000000; + count -= 0x40000000; + } + if (count > 0L) productRegister[11902] += (int)count; + count = solarSailCount; + while (count > 0x40000000L) + { + productRegister[11901] += 0x40000000; + productRegister[11903] += 0x40000000; + count -= 0x40000000; + } + if (count > 0L) + { + productRegister[11901] += (int)count; + productRegister[11903] += (int)count; } } } @@ -125,7 +138,13 @@ public static class DysonSphereFunctions { lock (consumeRegister) { - if (solarSailCount > 0) consumeRegister[11901] += solarSailCount; + var count = solarSailCount; + while (count > 0x40000000L) + { + consumeRegister[11901] += 0x40000000; + count -= 0x40000000; + } + if (count > 0L) consumeRegister[11901] += (int)count; } } }); diff --git a/CheatEnabler/PlanetFunctions.cs b/CheatEnabler/Functions/PlanetFunctions.cs similarity index 97% rename from CheatEnabler/PlanetFunctions.cs rename to CheatEnabler/Functions/PlanetFunctions.cs index 3201466..61e036d 100644 --- a/CheatEnabler/PlanetFunctions.cs +++ b/CheatEnabler/Functions/PlanetFunctions.cs @@ -1,6 +1,6 @@ using Random = UnityEngine.Random; -namespace CheatEnabler; +namespace CheatEnabler.Functions; public static class PlanetFunctions { public static void BuryAllVeins(bool bury) diff --git a/CheatEnabler/PlayerFunctions.cs b/CheatEnabler/Functions/PlayerFunctions.cs similarity index 99% rename from CheatEnabler/PlayerFunctions.cs rename to CheatEnabler/Functions/PlayerFunctions.cs index b8aead7..59eec21 100644 --- a/CheatEnabler/PlayerFunctions.cs +++ b/CheatEnabler/Functions/PlayerFunctions.cs @@ -2,7 +2,7 @@ using System.Linq; using UXAssist.Common; -namespace CheatEnabler; +namespace CheatEnabler.Functions; public static class PlayerFunctions { diff --git a/CheatEnabler/CombatPatch.cs b/CheatEnabler/Patches/CombatPatch.cs similarity index 81% rename from CheatEnabler/CombatPatch.cs rename to CheatEnabler/Patches/CombatPatch.cs index 52479a1..1203b05 100644 --- a/CheatEnabler/CombatPatch.cs +++ b/CheatEnabler/Patches/CombatPatch.cs @@ -3,8 +3,9 @@ using System.Reflection; using System.Reflection.Emit; using BepInEx.Configuration; using HarmonyLib; +using UXAssist.Common; -namespace CheatEnabler; +namespace CheatEnabler.Patches; public static class CombatPatch { @@ -25,23 +26,8 @@ public static class CombatPatch MechaInvincible.Enable(false); } - private static class MechaInvincible + private class MechaInvincible: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(MechaInvincible)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } - [HarmonyTranspiler] [HarmonyPatch(typeof(Player), nameof(Player.invincible), MethodType.Getter)] private static IEnumerable Player_get_invincible_Transpiler(IEnumerable instructions, ILGenerator generator) @@ -75,23 +61,8 @@ public static class CombatPatch } } - private static class BuildingsInvincible + private class BuildingsInvincible: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(BuildingsInvincible)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } - [HarmonyTranspiler] [HarmonyPatch(typeof(SkillSystem), nameof(SkillSystem.DamageGroundObjectByLocalCaster))] [HarmonyPatch(typeof(SkillSystem), nameof(SkillSystem.DamageGroundObjectByRemoteCaster))] diff --git a/CheatEnabler/DysonSpherePatch.cs b/CheatEnabler/Patches/DysonSpherePatch.cs similarity index 89% rename from CheatEnabler/DysonSpherePatch.cs rename to CheatEnabler/Patches/DysonSpherePatch.cs index 6f740e1..a393aea 100644 --- a/CheatEnabler/DysonSpherePatch.cs +++ b/CheatEnabler/Patches/DysonSpherePatch.cs @@ -5,7 +5,7 @@ using BepInEx.Configuration; using HarmonyLib; using UXAssist.Common; -namespace CheatEnabler; +namespace CheatEnabler.Patches; public static class DysonSpherePatch { @@ -82,12 +82,11 @@ public static class DysonSpherePatch return matcher.InstructionEnumeration(); } - private static class SkipBulletPatch + private class SkipBulletPatch: PatchImpl { private static long _sailLifeTime; private static DysonSailCache[][] _sailsCache; private static int[] _sailsCacheLen, _sailsCacheCapacity; - private static Harmony _patch; private struct DysonSailCache { @@ -107,21 +106,16 @@ public static class DysonSpherePatch } } - public static void Enable(bool on) + protected override void OnEnable() { - if (on) - { - UpdateSailLifeTime(); - UpdateSailsCacheForThisGame(); - _patch ??= Harmony.CreateAndPatchAll(typeof(SkipBulletPatch)); - GameLogic.OnGameBegin += GameMain_Begin_Postfix; - } - else - { - GameLogic.OnGameBegin -= GameMain_Begin_Postfix; - _patch?.UnpatchSelf(); - _patch = null; - } + UpdateSailLifeTime(); + UpdateSailsCacheForThisGame(); + GameLogic.OnGameBegin += GameMain_Begin_Postfix; + } + + protected override void OnDisable() + { + GameLogic.OnGameBegin -= GameMain_Begin_Postfix; } private static void UpdateSailLifeTime() @@ -286,20 +280,16 @@ public static class DysonSpherePatch } } - private static class SkipAbsorbPatch + private class SkipAbsorbPatch: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) + protected override void OnEnable() { - _instantAbsorb = SkipAbsorbEnabled.Value && QuickAbsorbEnabled.Value; - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(SkipAbsorbPatch)); - return; - } - _patch?.UnpatchSelf(); - _patch = null; + _instantAbsorb = QuickAbsorbEnabled.Value; + } + + protected override void OnDisable() + { + _instantAbsorb = false; } [HarmonyTranspiler] @@ -342,23 +332,18 @@ public static class DysonSpherePatch } } - private static class QuickAbsorbPatch + private class QuickAbsorbPatch: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) + protected override void OnEnable() { - _instantAbsorb = SkipAbsorbEnabled.Value && QuickAbsorbEnabled.Value; - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(QuickAbsorbPatch)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } + _instantAbsorb = SkipAbsorbEnabled.Value; } + + protected override void OnDisable() + { + _instantAbsorb = false; + } + [HarmonyTranspiler] [HarmonyPatch(typeof(DysonSphereLayer), nameof(DysonSphereLayer.GameTick))] private static IEnumerable DysonSphereLayer_GameTick_Transpiler(IEnumerable instructions, ILGenerator generator) @@ -398,22 +383,8 @@ public static class DysonSpherePatch } } - private static class EjectAnywayPatch + private class EjectAnywayPatch: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(EjectAnywayPatch)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } [HarmonyTranspiler] [HarmonyPatch(typeof(EjectorComponent), nameof(EjectorComponent.InternalUpdate))] private static IEnumerable EjectorComponent_InternalUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) @@ -443,23 +414,8 @@ public static class DysonSpherePatch } } - private static class OverclockEjector + private class OverclockEjector: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(OverclockEjector)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } - [HarmonyTranspiler] [HarmonyPatch(typeof(EjectorComponent), nameof(EjectorComponent.InternalUpdate))] private static IEnumerable EjectAndSiloComponent_InternalUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) @@ -511,22 +467,8 @@ public static class DysonSpherePatch } } - private static class OverclockSilo + private class OverclockSilo: PatchImpl { - private static Harmony _patch; - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(OverclockSilo)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } - [HarmonyTranspiler] [HarmonyPatch(typeof(SiloComponent), nameof(SiloComponent.InternalUpdate))] private static IEnumerable EjectAndSiloComponent_InternalUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) diff --git a/CheatEnabler/FactoryPatch.cs b/CheatEnabler/Patches/FactoryPatch.cs similarity index 94% rename from CheatEnabler/FactoryPatch.cs rename to CheatEnabler/Patches/FactoryPatch.cs index 03ef8a9..13706bd 100644 --- a/CheatEnabler/FactoryPatch.cs +++ b/CheatEnabler/Patches/FactoryPatch.cs @@ -8,7 +8,7 @@ using UnityEngine; using UnityEngine.UI; using UXAssist.Common; -namespace CheatEnabler; +namespace CheatEnabler.Patches; public static class FactoryPatch { @@ -224,9 +224,9 @@ public static class FactoryPatch new CodeInstruction(OpCodes.Call, AccessTools.PropertyGetter(typeof(ConfigEntry), nameof(ConfigEntry.Value))), new CodeInstruction(OpCodes.Brfalse, label1), new CodeInstruction(OpCodes.Ldstr, "Build without condition is enabled!"), - new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Localization), nameof(Localization.Translate), new[] { typeof(string) })), + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Localization), nameof(Localization.Translate), [typeof(string)])), new CodeInstruction(OpCodes.Ldstr, "\r\n"), - new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(string), nameof(string.Concat), new[] { typeof(string), typeof(string) })), + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(string), nameof(string.Concat), [typeof(string), typeof(string)])), new CodeInstruction(OpCodes.Call, AccessTools.PropertySetter(typeof(WarningSystem), nameof(WarningSystem.criticalWarningTexts))) ); if (m.InstructionAt(2).opcode == OpCodes.Ret) @@ -302,9 +302,9 @@ public static class FactoryPatch ); return matcher.InstructionEnumeration(); } - + [HarmonyPostfix] - [HarmonyPatch(typeof(UXAssist.PlanetFunctions), nameof(UXAssist.PlanetFunctions.BuildOrbitalCollectors))] + [HarmonyPatch(typeof(UXAssist.Functions.PlanetFunctions), nameof(UXAssist.Functions.PlanetFunctions.BuildOrbitalCollectors))] private static void UXAssist_PlanetFunctions_BuildOrbitalCollectors_Postfix() { var factory = GameMain.mainPlayer?.factory; @@ -315,33 +315,24 @@ public static class FactoryPatch } } - private static class ArchitectMode + private class ArchitectMode: PatchImpl { - private static Harmony _patch; private static bool[] _canBuildItems; - public static void Enable(bool enable) + protected override void OnEnable() { - if (enable) + var factory = GameMain.mainPlayer?.factory; + if (factory != null) { - if (_patch != null) return; - var factory = GameMain.mainPlayer?.factory; - if (factory != null) - { - ArrivePlanet(factory); - } - _patch = Harmony.CreateAndPatchAll(typeof(ArchitectMode)); - return; + ArrivePlanet(factory); } - _patch?.UnpatchSelf(); - _patch = null; } [HarmonyPrefix] - [HarmonyPatch(typeof(StorageComponent), nameof(StorageComponent.TakeTailItems), new[] { typeof(int), typeof(int), typeof(int), typeof(bool) }, - new[] { ArgumentType.Ref, ArgumentType.Ref, ArgumentType.Out, ArgumentType.Normal })] - [HarmonyPatch(typeof(StorageComponent), nameof(StorageComponent.TakeTailItems), new[] { typeof(int), typeof(int), typeof(int[]), typeof(int), typeof(bool) }, - new[] { ArgumentType.Ref, ArgumentType.Ref, ArgumentType.Normal, ArgumentType.Out, ArgumentType.Normal })] + [HarmonyPatch(typeof(StorageComponent), nameof(StorageComponent.TakeTailItems), [typeof(int), typeof(int), typeof(int), typeof(bool)], + [ArgumentType.Ref, ArgumentType.Ref, ArgumentType.Out, ArgumentType.Normal])] + [HarmonyPatch(typeof(StorageComponent), nameof(StorageComponent.TakeTailItems), [typeof(int), typeof(int), typeof(int[]), typeof(int), typeof(bool)], + [ArgumentType.Ref, ArgumentType.Ref, ArgumentType.Normal, ArgumentType.Out, ArgumentType.Normal])] public static bool TakeTailItemsPatch(StorageComponent __instance, int itemId) { if (__instance == null || __instance.id != GameMain.mainPlayer.package.id) return true; @@ -1123,20 +1114,8 @@ public static class FactoryPatch /* END: Item sources calculation */ } - private static class RemovePowerSpaceLimit + private class RemovePowerSpaceLimit: PatchImpl { - private static Harmony _patch; - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(RemovePowerSpaceLimit)); - return; - } - _patch?.UnpatchSelf(); - _patch = null; - } - [HarmonyTranspiler] [HarmonyPatch(typeof(BuildTool_Click), nameof(BuildTool_Click.CheckBuildConditions))] [HarmonyPatch(typeof(BuildTool_BlueprintPaste), nameof(BuildTool_BlueprintPaste.CheckBuildConditions))] @@ -1165,19 +1144,8 @@ public static class FactoryPatch } } - private static class BoostWindPower + private class BoostWindPower: PatchImpl { - private static Harmony _patch; - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(BoostWindPower)); - return; - } - _patch?.UnpatchSelf(); - _patch = null; - } [HarmonyTranspiler] [HarmonyPatch(typeof(PowerGeneratorComponent), nameof(PowerGeneratorComponent.EnergyCap_Wind))] private static IEnumerable PowerGeneratorComponent_EnergyCap_Wind_Transpiler(IEnumerable instructions, ILGenerator generator) @@ -1201,19 +1169,8 @@ public static class FactoryPatch } } - private static class BoostSolarPower + private class BoostSolarPower: PatchImpl { - private static Harmony _patch; - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(BoostSolarPower)); - return; - } - _patch?.UnpatchSelf(); - _patch = null; - } [HarmonyTranspiler] [HarmonyPatch(typeof(PowerGeneratorComponent), nameof(PowerGeneratorComponent.EnergyCap_PV))] private static IEnumerable PowerGeneratorComponent_EnergyCap_PV_Transpiler(IEnumerable instructions, ILGenerator generator) @@ -1236,19 +1193,8 @@ public static class FactoryPatch } } - private static class BoostFuelPower + private class BoostFuelPower: PatchImpl { - private static Harmony _patch; - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(BoostFuelPower)); - return; - } - _patch?.UnpatchSelf(); - _patch = null; - } [HarmonyTranspiler] [HarmonyPatch(typeof(PowerGeneratorComponent), nameof(PowerGeneratorComponent.EnergyCap_Fuel))] private static IEnumerable PowerGeneratorComponent_EnergyCap_Fuel_Transpiler(IEnumerable instructions, ILGenerator generator) @@ -1288,19 +1234,8 @@ public static class FactoryPatch } } - private static class BoostGeothermalPower + private class BoostGeothermalPower: PatchImpl { - private static Harmony _patch; - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(BoostGeothermalPower)); - return; - } - _patch?.UnpatchSelf(); - _patch = null; - } [HarmonyTranspiler] [HarmonyPatch(typeof(PowerGeneratorComponent), nameof(PowerGeneratorComponent.EnergyCap_GTH))] private static IEnumerable PowerGeneratorComponent_EnergyCap_GTH_Transpiler(IEnumerable instructions, ILGenerator generator) @@ -1382,25 +1317,22 @@ public static class FactoryPatch } } - private static class GreaterPowerUsageInLogistics + private class GreaterPowerUsageInLogistics: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool enable) + protected override void OnEnable() { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(GreaterPowerUsageInLogistics)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } var window = UIRoot.instance?.uiGame?.stationWindow; if (window == null) return; window._Close(); - window.maxMiningSpeedSlider.maxValue = enable ? 27f : 20f; + window.maxMiningSpeedSlider.maxValue = 27f; + } + + protected override void OnDisable() + { + var window = UIRoot.instance?.uiGame?.stationWindow; + if (window == null) return; + window._Close(); + window.maxMiningSpeedSlider.maxValue = 20f; } [HarmonyTranspiler] @@ -1535,23 +1467,8 @@ public static class FactoryPatch } } - private static class ControlPanelRemoteLogistics + private class ControlPanelRemoteLogistics: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(ControlPanelRemoteLogistics)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } - [HarmonyTranspiler] [HarmonyPatch(typeof(UIControlPanelDispenserInspector), nameof(UIControlPanelDispenserInspector.OnItemIconMouseDown))] [HarmonyPatch(typeof(UIControlPanelDispenserInspector), nameof(UIControlPanelDispenserInspector.OnHoldupItemClick))] diff --git a/CheatEnabler/Patches/GamePatch.cs b/CheatEnabler/Patches/GamePatch.cs new file mode 100644 index 0000000..ccb30e3 --- /dev/null +++ b/CheatEnabler/Patches/GamePatch.cs @@ -0,0 +1,306 @@ +using System; +using System.Collections.Generic; +using System.Reflection.Emit; +using BepInEx.Configuration; +using HarmonyLib; +using UnityEngine.Bindings; +using UXAssist.Common; + +namespace CheatEnabler.Patches; + +public static class GamePatch +{ + public static ConfigEntry DevShortcutsEnabled; + public static ConfigEntry AbnormalDisablerEnabled; + public static ConfigEntry UnlockTechEnabled; + + public static void Init() + { + DevShortcutsEnabled.SettingChanged += (_, _) => DevShortcuts.Enable(DevShortcutsEnabled.Value); + AbnormalDisablerEnabled.SettingChanged += (_, _) => AbnormalDisabler.Enable(AbnormalDisablerEnabled.Value); + UnlockTechEnabled.SettingChanged += (_, _) => UnlockTech.Enable(UnlockTechEnabled.Value); + DevShortcuts.Enable(DevShortcutsEnabled.Value); + AbnormalDisabler.Enable(AbnormalDisablerEnabled.Value); + UnlockTech.Enable(UnlockTechEnabled.Value); + } + + public static void Uninit() + { + UnlockTech.Enable(false); + AbnormalDisabler.Enable(false); + DevShortcuts.Enable(false); + } + + public class AbnormalDisabler : PatchImpl + { + private static Dictionary _savedDeterminators; + + protected override void OnEnable() + { + if (_savedDeterminators == null) return; + var abnormalLogic = GameMain.gameScenario.abnormalityLogic; + foreach (var p in _savedDeterminators) + { + p.Value.OnUnregEvent(); + } + + abnormalLogic.determinators = new Dictionary(); + } + + protected override void OnDisable() + { + if (_savedDeterminators == null) return; + var abnormalLogic = GameMain.gameScenario.abnormalityLogic; + abnormalLogic.determinators = _savedDeterminators; + foreach (var p in _savedDeterminators) + { + p.Value.OnRegEvent(); + } + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(AbnormalityLogic), "NotifyBeforeGameSave")] + [HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnAssemblerRecipePick")] + [HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnGameBegin")] + [HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnMechaForgeTaskComplete")] + [HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnUnlockTech")] + [HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnUseConsole")] + private static bool DisableAbnormalLogic() + { + return false; + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(AbnormalityLogic), "InitDeterminators")] + private static void DisableAbnormalDeterminators(AbnormalityLogic __instance) + { + _savedDeterminators = __instance.determinators; + if (!AbnormalDisablerEnabled.Value) return; + __instance.determinators = new Dictionary(); + foreach (var p in _savedDeterminators) + { + p.Value.OnUnregEvent(); + } + } + } + + public class DevShortcuts : PatchImpl + { + private static PlayerAction_Test _test; + + protected override void OnEnable() + { + if (_test != null) _test.active = true; + } + + protected override void OnDisable() + { + if (_test != null) _test.active = false; + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(PlayerController), nameof(PlayerController.Init))] + private static void PlayerController_Init_Postfix(PlayerController __instance) + { + var cnt = __instance.actions.Length; + var newActions = new PlayerAction[cnt + 1]; + for (var i = 0; i < cnt; i++) + { + newActions[i] = __instance.actions[i]; + } + + _test = new PlayerAction_Test(); + _test.Init(__instance.player); + _test.active = DevShortcutsEnabled.Value; + newActions[cnt] = _test; + __instance.actions = newActions; + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(PlayerAction_Test), nameof(PlayerAction_Test.GameTick))] + private static void PlayerAction_Test_GameTick_Postfix(PlayerAction_Test __instance) + { + __instance.Update(); + } + + [HarmonyTranspiler] + [HarmonyPatch(typeof(PlayerAction_Test), nameof(PlayerAction_Test.Update))] + private static IEnumerable PlayerAction_Test_Update_Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + matcher.End().MatchBack(false, + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PlayerAction_Test), nameof(PlayerAction_Test.active))) + ); + var pos = matcher.Pos; + /* Remove Shift+F4 part of the method */ + matcher.Start().RemoveInstructions(pos).MatchForward(false, + new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(GameMain), "get_sandboxToolsEnabled")), + new CodeMatch(OpCodes.Ldc_I4_0), + new CodeMatch(OpCodes.Ceq) + ); + var labels = matcher.Labels; + matcher.SetInstructionAndAdvance( + new CodeInstruction(OpCodes.Ldc_I4_1).WithLabels(labels) + ).RemoveInstructions(2); + /* Remove Ctrl+A */ + matcher.Start().MatchForward(false, + new CodeMatch(instr => (instr.opcode == OpCodes.Ldc_I4_S || instr.opcode == OpCodes.Ldc_I4) && instr.OperandIs(0x61)), + new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(UnityEngine.Input), nameof(UnityEngine.Input.GetKeyDown), [typeof(UnityEngine.KeyCode)])) + ); + labels = matcher.Labels; + matcher.Labels = null; + matcher.RemoveInstructions(2); + matcher.Opcode = OpCodes.Br; + matcher.Labels = labels; + return matcher.InstructionEnumeration(); + } + + [HarmonyTranspiler] + [HarmonyPatch(typeof(GameCamera), nameof(GameCamera.FrameLogic))] + private static IEnumerable GameCamera_Logic_Transpiler(IEnumerable instructions) + { + var matcher = new CodeMatcher(instructions); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(GameCamera), nameof(GameCamera.finalPoser))), + new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(CameraPoser), nameof(CameraPoser.cameraPose))) + ); + var labels = matcher.Labels; + matcher.Labels = null; + matcher.Insert( + new CodeInstruction(OpCodes.Ldarg_0).WithLabels(labels), + Transpilers.EmitDelegate((GameCamera camera) => + { + if (PlayerAction_Test.lockCam) + { + camera.finalPoser.cameraPose = PlayerAction_Test.camPose; + } + }) + ); + return matcher.InstructionEnumeration(); + } + } + + public class UnlockTech: PatchImpl + { + private static void UnlockTechRecursive(GameHistoryData history, [NotNull] TechProto techProto, int maxLevel = 10000) + { + var techStates = history.techStates; + var techID = techProto.ID; + if (techStates == null || !techStates.TryGetValue(techID, out var value)) + { + return; + } + + if (value.unlocked) + { + return; + } + + var maxLvl = Math.Min(maxLevel < 0 ? value.curLevel - maxLevel - 1 : maxLevel, value.maxLevel); + + foreach (var preid in techProto.PreTechs) + { + var preProto = LDB.techs.Select(preid); + if (preProto != null) + UnlockTechRecursive(history, preProto, techProto.PreTechsMax ? 10000 : -1); + } + + foreach (var preid in techProto.PreTechsImplicit) + { + var preProto = LDB.techs.Select(preid); + if (preProto != null) + UnlockTechRecursive(history, preProto, techProto.PreTechsMax ? 10000 : -1); + } + + if (value.curLevel < techProto.Level) value.curLevel = techProto.Level; + while (value.curLevel <= maxLvl) + { + if (value.curLevel == 0) + { + foreach (var recipe in techProto.UnlockRecipes) + { + history.UnlockRecipe(recipe); + } + } + + for (var j = 0; j < techProto.UnlockFunctions.Length; j++) + { + history.UnlockTechFunction(techProto.UnlockFunctions[j], techProto.UnlockValues[j], value.curLevel); + } + + for (var k = 0; k < techProto.AddItems.Length; k++) + { + history.GainTechAwards(techProto.AddItems[k], techProto.AddItemCounts[k]); + } + + value.curLevel++; + } + + value.unlocked = maxLvl >= value.maxLevel; + value.curLevel = value.unlocked ? maxLvl : maxLvl + 1; + value.hashNeeded = techProto.GetHashNeeded(value.curLevel); + value.hashUploaded = value.unlocked ? value.hashNeeded : 0; + techStates[techID] = value; + history.RegFeatureKey(1000100); + history.NotifyTechUnlock(techID, maxLvl, true); + } + + private static void OnClickTech(UITechNode node) + { + var history = GameMain.history; + if (VFInput.shift) + { + if (VFInput.alt) return; + if (VFInput.control) + UnlockTechRecursive(history, node.techProto, -100); + else + UnlockTechRecursive(history, node.techProto, -1); + } + else + { + if (VFInput.control) + { + if (!VFInput.alt) + UnlockTechRecursive(history, node.techProto, -10); + else + return; + } + else if (VFInput.alt) + { + UnlockTechRecursive(history, node.techProto); + } + else + { + return; + } + } + + history.VarifyTechQueue(); + if (history.currentTech != history.techQueue[0]) + { + history.currentTech = history.techQueue[0]; + } + } + + [HarmonyTranspiler] + [HarmonyPatch(typeof(UITechNode), nameof(UITechNode.OnPointerDown))] + private static IEnumerable UITechNode_OnPointerDown_Transpiler(IEnumerable instructions, ILGenerator generator) + { + 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))), + new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(UITechTree), "get_selected")) + ); + var labels = matcher.Labels; + matcher.Labels = null; + matcher.Insert( + new CodeInstruction(OpCodes.Ldarg_0).WithLabels(labels), + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(UnlockTech), nameof(UnlockTech.OnClickTech))) + ); + return matcher.InstructionEnumeration(); + } + } +} \ No newline at end of file diff --git a/CheatEnabler/PlanetPatch.cs b/CheatEnabler/Patches/PlanetPatch.cs similarity index 78% rename from CheatEnabler/PlanetPatch.cs rename to CheatEnabler/Patches/PlanetPatch.cs index bdfa3ff..986294b 100644 --- a/CheatEnabler/PlanetPatch.cs +++ b/CheatEnabler/Patches/PlanetPatch.cs @@ -3,8 +3,9 @@ using System.Collections.Generic; using System.Reflection.Emit; using BepInEx.Configuration; using HarmonyLib; +using UXAssist.Common; -namespace CheatEnabler; +namespace CheatEnabler.Patches; public static class PlanetPatch { public static ConfigEntry WaterPumpAnywhereEnabled; @@ -24,23 +25,8 @@ public static class PlanetPatch TerraformAnyway.Enable(false); } - private static class WaterPumperPatch + private class WaterPumperPatch: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(WaterPumperPatch)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } - [HarmonyTranspiler] [HarmonyPatch(typeof(BuildTool_BlueprintPaste), nameof(BuildTool_BlueprintPaste.CheckBuildConditions))] [HarmonyPatch(typeof(BuildTool_Click), nameof(BuildTool_Click.CheckBuildConditions))] @@ -61,23 +47,8 @@ public static class PlanetPatch } } - private static class TerraformAnyway + private class TerraformAnyway: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(TerraformAnyway)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } - [HarmonyTranspiler] [HarmonyPatch(typeof(BuildTool_Reform), nameof(BuildTool_Reform.ReformAction))] private static IEnumerable BuildTool_Reform_ReformAction_Patch(IEnumerable instructions, ILGenerator generator) @@ -96,7 +67,7 @@ public static class PlanetPatch new CodeMatch(OpCodes.Sub) ).Advance(2).InsertAndAdvance( new CodeInstruction(OpCodes.Ldc_I8, 0L), - new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Math), "Max", new[] { typeof(long), typeof(long) })) + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Math), "Max", [typeof(long), typeof(long)])) ); return matcher.InstructionEnumeration(); } diff --git a/CheatEnabler/PlayerPatch.cs b/CheatEnabler/Patches/PlayerPatch.cs similarity index 76% rename from CheatEnabler/PlayerPatch.cs rename to CheatEnabler/Patches/PlayerPatch.cs index e6642fe..c719ee7 100644 --- a/CheatEnabler/PlayerPatch.cs +++ b/CheatEnabler/Patches/PlayerPatch.cs @@ -2,8 +2,9 @@ using System.Reflection.Emit; using BepInEx.Configuration; using HarmonyLib; +using UXAssist.Common; -namespace CheatEnabler; +namespace CheatEnabler.Patches; public static class PlayerPatch { @@ -24,23 +25,8 @@ public static class PlayerPatch WarpWithoutSpaceWarpers.Enable(false); } - private static class InstantTeleport + private class InstantTeleport: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(InstantTeleport)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } - [HarmonyTranspiler] [HarmonyPatch(typeof(UIGlobemap), nameof(UIGlobemap._OnUpdate))] [HarmonyPatch(typeof(UIStarmap), nameof(UIStarmap.DoRightClickFastTravel))] @@ -62,23 +48,8 @@ public static class PlayerPatch } } - private static class WarpWithoutSpaceWarpers + private class WarpWithoutSpaceWarpers: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(WarpWithoutSpaceWarpers)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } - [HarmonyPrefix] [HarmonyPatch(typeof(Mecha), nameof(Mecha.HasWarper))] private static bool Mecha_HasWarper_Prefix(ref bool __result) diff --git a/CheatEnabler/ResourcePatch.cs b/CheatEnabler/Patches/ResourcePatch.cs similarity index 83% rename from CheatEnabler/ResourcePatch.cs rename to CheatEnabler/Patches/ResourcePatch.cs index 464ed94..9ced6f0 100644 --- a/CheatEnabler/ResourcePatch.cs +++ b/CheatEnabler/Patches/ResourcePatch.cs @@ -2,8 +2,9 @@ using System.Reflection.Emit; using BepInEx.Configuration; using HarmonyLib; +using UXAssist.Common; -namespace CheatEnabler; +namespace CheatEnabler.Patches; public static class ResourcePatch { @@ -24,23 +25,8 @@ public static class ResourcePatch FastMining.Enable(false); } - private static class InfiniteResource + private class InfiniteResource: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(InfiniteResource)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } - [HarmonyTranspiler] [HarmonyPatch(typeof(FactorySystem), "GameTick", typeof(long), typeof(bool))] [HarmonyPatch(typeof(FactorySystem), "GameTick", typeof(long), typeof(bool), typeof(int), typeof(int), typeof(int))] @@ -69,23 +55,8 @@ public static class ResourcePatch } } - private static class FastMining + private class FastMining: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(FastMining)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } - [HarmonyTranspiler] [HarmonyPatch(typeof(FactorySystem), "GameTick", typeof(long), typeof(bool))] [HarmonyPatch(typeof(FactorySystem), "GameTick", typeof(long), typeof(bool), typeof(int), typeof(int), typeof(int))] diff --git a/CheatEnabler/TechPatch.cs b/CheatEnabler/TechPatch.cs deleted file mode 100644 index f29091c..0000000 --- a/CheatEnabler/TechPatch.cs +++ /dev/null @@ -1,154 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection.Emit; -using BepInEx.Configuration; -using HarmonyLib; -using JetBrains.Annotations; - -namespace CheatEnabler; - -public static class TechPatch -{ - public static ConfigEntry Enabled; - private static Harmony _patch; - - public static void Init() - { - Enabled.SettingChanged += (_, _) => ValueChanged(); - ValueChanged(); - } - - public static void Uninit() - { - _patch?.UnpatchSelf(); - _patch = null; - } - - private static void ValueChanged() - { - if (Enabled.Value) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(TechPatch)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } - - private static void UnlockTechRecursive(GameHistoryData history, [NotNull] TechProto techProto, int maxLevel = 10000) - { - var techStates = history.techStates; - var techID = techProto.ID; - if (techStates == null || !techStates.TryGetValue(techID, out var value)) - { - return; - } - - if (value.unlocked) - { - return; - } - - var maxLvl = Math.Min(maxLevel < 0 ? value.curLevel - maxLevel - 1 : maxLevel, value.maxLevel); - - foreach (var preid in techProto.PreTechs) - { - var preProto = LDB.techs.Select(preid); - if (preProto != null) - UnlockTechRecursive(history, preProto, techProto.PreTechsMax ? 10000 : -1); - } - foreach (var preid in techProto.PreTechsImplicit) - { - var preProto = LDB.techs.Select(preid); - if (preProto != null) - UnlockTechRecursive(history, preProto, techProto.PreTechsMax ? 10000 : -1); - } - - if (value.curLevel < techProto.Level) value.curLevel = techProto.Level; - while (value.curLevel <= maxLvl) - { - if (value.curLevel == 0) - { - foreach (var recipe in techProto.UnlockRecipes) - { - history.UnlockRecipe(recipe); - } - } - for (var j = 0; j < techProto.UnlockFunctions.Length; j++) - { - history.UnlockTechFunction(techProto.UnlockFunctions[j], techProto.UnlockValues[j], value.curLevel); - } - for (var k = 0; k < techProto.AddItems.Length; k++) - { - history.GainTechAwards(techProto.AddItems[k], techProto.AddItemCounts[k]); - } - value.curLevel++; - } - - value.unlocked = maxLvl >= value.maxLevel; - value.curLevel = value.unlocked ? maxLvl : maxLvl + 1; - value.hashNeeded = techProto.GetHashNeeded(value.curLevel); - value.hashUploaded = value.unlocked ? value.hashNeeded : 0; - techStates[techID] = value; - history.RegFeatureKey(1000100); - history.NotifyTechUnlock(techID, maxLvl, true); - } - - private static void OnClickTech(UITechNode node) - { - var history = GameMain.history; - if (VFInput.shift) - { - if (VFInput.alt) return; - if (VFInput.control) - UnlockTechRecursive(history, node.techProto, -100); - else - UnlockTechRecursive(history, node.techProto, -1); - } - else - { - if (VFInput.control) - { - if (!VFInput.alt) - UnlockTechRecursive(history, node.techProto, -10); - else - return; - } - else if (VFInput.alt) - { - UnlockTechRecursive(history, node.techProto); - } - else - { - return; - } - } - history.VarifyTechQueue(); - if (history.currentTech != history.techQueue[0]) - { - history.currentTech = history.techQueue[0]; - } - } - - [HarmonyTranspiler] - [HarmonyPatch(typeof(UITechNode), nameof(UITechNode.OnPointerDown))] - private static IEnumerable UITechNode_OnPointerDown_Transpiler(IEnumerable instructions, ILGenerator generator) - { - 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))), - new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(UITechTree), "get_selected")) - ); - var labels = matcher.Labels; - matcher.Labels = null; - matcher.Insert( - new CodeInstruction(OpCodes.Ldarg_0).WithLabels(labels), - new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(TechPatch), nameof(TechPatch.OnClickTech))) - ); - return matcher.InstructionEnumeration(); - } - -} \ No newline at end of file diff --git a/CheatEnabler/UIConfigWindow.cs b/CheatEnabler/UIConfigWindow.cs index e0e2a85..ec11512 100644 --- a/CheatEnabler/UIConfigWindow.cs +++ b/CheatEnabler/UIConfigWindow.cs @@ -1,4 +1,6 @@ -using UnityEngine; +using CheatEnabler.Functions; +using CheatEnabler.Patches; +using UnityEngine; using UXAssist.UI; using UXAssist.Common; @@ -84,15 +86,15 @@ public static class UIConfigWindow wnd.AddSplitter(trans, 10f); wnd.AddTabGroup(trans, "Cheat Enabler", "tab-group-cheatenabler"); var tab1 = wnd.AddTab(_windowTrans, "General"); - var cb = wnd.AddCheckBox(x, y, tab1, DevShortcuts.Enabled, "Enable Dev Shortcuts"); + var cb = wnd.AddCheckBox(x, y, tab1, GamePatch.DevShortcutsEnabled, "Enable Dev Shortcuts"); x += cb.Width + 5f; y += 6f; wnd.AddTipsButton2(x, y, tab1, "Dev Shortcuts", "Dev Shortcuts Tips", "dev-shortcuts-tips"); x = 0; y += 30f; - wnd.AddCheckBox(x, y, tab1, AbnormalDisabler.Enabled, "Disable Abnormal Checks"); + wnd.AddCheckBox(x, y, tab1, GamePatch.AbnormalDisablerEnabled, "Disable Abnormal Checks"); y += 36f; - cb = wnd.AddCheckBox(x, y, tab1, TechPatch.Enabled, "Unlock Tech with Key-Modifiers"); + cb = wnd.AddCheckBox(x, y, tab1, GamePatch.UnlockTechEnabled, "Unlock Tech with Key-Modifiers"); x += cb.Width + 5f; y += 6f; wnd.AddTipsButton2(x, y, tab1, "Unlock Tech with Key-Modifiers", "Unlock Tech with Key-Modifiers Tips", "unlock-tech-tips"); diff --git a/UXAssist/AuxilaryfunctionWrapper.cs b/UXAssist/AuxilaryfunctionWrapper.cs deleted file mode 100644 index 9dc4115..0000000 --- a/UXAssist/AuxilaryfunctionWrapper.cs +++ /dev/null @@ -1,25 +0,0 @@ -using BepInEx.Configuration; -using HarmonyLib; - -namespace UXAssist; - -public static class AuxilaryfunctionWrapper -{ - private const string AuxilaryfunctionGuid = "cn.blacksnipe.dsp.Auxilaryfunction"; - public static ConfigEntry ShowStationInfo; - - public static void Init(Harmony harmony) - { - if (!BepInEx.Bootstrap.Chainloader.PluginInfos.TryGetValue(AuxilaryfunctionGuid, out var pluginInfo)) return; - var assembly = pluginInfo.Instance.GetType().Assembly; - try - { - var classType = assembly.GetType("Auxilaryfunction.Auxilaryfunction"); - ShowStationInfo = (ConfigEntry)AccessTools.Field(classType, "ShowStationInfo").GetValue(pluginInfo.Instance); - } - catch - { - UXAssist.Logger.LogWarning("Failed to get ShowStationInfo from Auxilaryfunction"); - } - } -} \ No newline at end of file diff --git a/UXAssist/Common/PatchImpl.cs b/UXAssist/Common/PatchImpl.cs new file mode 100644 index 0000000..b666105 --- /dev/null +++ b/UXAssist/Common/PatchImpl.cs @@ -0,0 +1,33 @@ +using HarmonyLib; + +namespace UXAssist.Common; + +public class PatchImpl where T : new() +{ + private static T Instance { get; } = new(); + + private Harmony _patch; + + public static void Enable(bool enable) + { + if (Instance is not PatchImpl thisInstance) + { + UXAssist.Logger.LogError($"PatchImpl<{typeof(T).Name}> is not inherited correctly"); + return; + } + if (enable) + { + thisInstance._patch ??= Harmony.CreateAndPatchAll(typeof(T)); + thisInstance.OnEnable(); + return; + } + thisInstance.OnDisable(); + thisInstance._patch?.UnpatchSelf(); + thisInstance._patch = null; + } + + protected static Harmony GetPatch() => (Instance as PatchImpl)?._patch; + + protected virtual void OnEnable() { } + protected virtual void OnDisable() { } +} diff --git a/UXAssist/Common/Util.cs b/UXAssist/Common/Util.cs index 523bb60..f36e3ec 100644 --- a/UXAssist/Common/Util.cs +++ b/UXAssist/Common/Util.cs @@ -1,4 +1,6 @@ -using System.IO; +using System; +using System.IO; +using System.Linq; using System.Reflection; using UnityEngine; @@ -6,6 +8,11 @@ namespace UXAssist.Common; public static class Util { + public static Type[] GetTypesInNamespace(Assembly assembly, string nameSpace) + { + return assembly.GetTypes().Where(t => string.Equals(t.Namespace, nameSpace, StringComparison.Ordinal)).ToArray(); + } + public static byte[] LoadEmbeddedResource(string path, Assembly assembly = null) { if (assembly == null) diff --git a/UXAssist/PlanetFunctions.cs b/UXAssist/Functions/PlanetFunctions.cs similarity index 99% rename from UXAssist/PlanetFunctions.cs rename to UXAssist/Functions/PlanetFunctions.cs index f3c9ba8..b86162b 100644 --- a/UXAssist/PlanetFunctions.cs +++ b/UXAssist/Functions/PlanetFunctions.cs @@ -3,7 +3,7 @@ using System.Threading; using BepInEx.Configuration; using UnityEngine; -namespace UXAssist; +namespace UXAssist.Functions; public static class PlanetFunctions { diff --git a/UXAssist/ModsCompat/AuxilaryfunctionWrapper.cs b/UXAssist/ModsCompat/AuxilaryfunctionWrapper.cs new file mode 100644 index 0000000..ca70aac --- /dev/null +++ b/UXAssist/ModsCompat/AuxilaryfunctionWrapper.cs @@ -0,0 +1,49 @@ +using System; +using BepInEx.Configuration; +using HarmonyLib; +using UXAssist.Patches; + +namespace UXAssist.ModsCompat; + +public static class AuxilaryfunctionWrapper +{ + private const string AuxilaryfunctionGuid = "cn.blacksnipe.dsp.Auxilaryfunction"; + public static ConfigEntry ShowStationInfo; + + public static void Init(Harmony harmony) + { + if (!BepInEx.Bootstrap.Chainloader.PluginInfos.TryGetValue(AuxilaryfunctionGuid, out var pluginInfo)) return; + var assembly = pluginInfo.Instance.GetType().Assembly; + try + { + var classType = assembly.GetType("Auxilaryfunction.Auxilaryfunction"); + ShowStationInfo = (ConfigEntry)AccessTools.Field(classType, "ShowStationInfo").GetValue(pluginInfo.Instance); + } + catch + { + UXAssist.Logger.LogWarning("Failed to get ShowStationInfo from Auxilaryfunction"); + } + try + { + var classType = assembly.GetType("Auxilaryfunction.Patch.SpeedUpPatch"); + harmony.Patch(AccessTools.PropertySetter(classType, "Enable"), + new HarmonyMethod(AccessTools.Method(typeof(AuxilaryfunctionWrapper), nameof(PatchSpeedUpPatchEnable)))); + } + catch + { + UXAssist.Logger.LogWarning("Failed to patch SpeedUpPatch.set_Enable() from Auxilaryfunction"); + } + } + + public static void PatchSpeedUpPatchEnable(bool value) + { + if (!value) + { + GamePatch.EnableGameUpsFactor = true; + return; + } + if (Math.Abs(GamePatch.GameUpsFactor.Value - 1.0) < 0.001) return; + GamePatch.EnableGameUpsFactor = false; + UXAssist.Logger.LogInfo("Game UPS changing is disabled when using Auxilaryfunction's speed up feature"); + } +} \ No newline at end of file diff --git a/UXAssist/ModsCompat/BulletTimeWrapper.cs b/UXAssist/ModsCompat/BulletTimeWrapper.cs new file mode 100644 index 0000000..787c977 --- /dev/null +++ b/UXAssist/ModsCompat/BulletTimeWrapper.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; +using System.Reflection.Emit; +using BepInEx.Configuration; +using HarmonyLib; + +namespace UXAssist.ModsCompat; + +public static class BulletTimeWrapper +{ + private const string BulletTimeGuid = "com.starfi5h.plugin.BulletTime"; + public static bool HasBulletTime; + + public static void Init(Harmony harmony) + { + HasBulletTime = BepInEx.Bootstrap.Chainloader.PluginInfos.TryGetValue(BulletTimeGuid, out var pluginInfo); + if (!HasBulletTime) return; + var assembly = pluginInfo.Instance.GetType().Assembly; + try + { + var classType = assembly.GetType("BulletTime.IngameUI"); + harmony.Patch(AccessTools.Method(classType, "Init"), + null, null, new HarmonyMethod(AccessTools.Method(typeof(BulletTimeWrapper), nameof(IngameUI_Init_Transpiler)))); + harmony.Patch(AccessTools.Method(classType, "OnSpeedButtonClick"), + null, null, new HarmonyMethod(AccessTools.Method(typeof(BulletTimeWrapper), nameof(IngameUI_OnSpeedButtonClick_Transpiler)))); + } + catch + { + UXAssist.Logger.LogWarning("Failed to patch BulletTime functions()"); + } + } + + private static IEnumerable IngameUI_Init_Transpiler(IEnumerable instructions) + { + var matcher = new CodeMatcher(instructions); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldstr, "Increase game speed (max 4x)") + ).Set(OpCodes.Ldstr, "Increase game speed (max 10x)"); + UXAssist.Logger.LogDebug($"Patched IngameUI.Init @ {matcher.Pos}"); + return matcher.InstructionEnumeration(); + } + + private static IEnumerable IngameUI_OnSpeedButtonClick_Transpiler(IEnumerable instructions) + { + var matcher = new CodeMatcher(instructions); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldc_R8, 240.0) + ).Set(OpCodes.Ldc_R8, 600.0); + UXAssist.Logger.LogDebug($"Patched IngameUI.OnSpeedButtonClick @ {matcher.Pos}"); + return matcher.InstructionEnumeration(); + } + +} \ No newline at end of file diff --git a/UXAssist/DysonSpherePatch.cs b/UXAssist/Patches/DysonSpherePatch.cs similarity index 95% rename from UXAssist/DysonSpherePatch.cs rename to UXAssist/Patches/DysonSpherePatch.cs index da9bb0e..30a3fad 100644 --- a/UXAssist/DysonSpherePatch.cs +++ b/UXAssist/Patches/DysonSpherePatch.cs @@ -5,7 +5,7 @@ using BepInEx.Configuration; using HarmonyLib; using UXAssist.Common; -namespace UXAssist; +namespace UXAssist.Patches; public static class DysonSpherePatch { @@ -286,30 +286,24 @@ public static class DysonSpherePatch return matcher.InstructionEnumeration(); } - private static class StopEjectOnNodeComplete + private class StopEjectOnNodeComplete: PatchImpl { - private static Harmony _patch; private static HashSet[] _nodeForAbsorb; private static bool _initialized; - public static void Enable(bool on) + protected override void OnEnable() { - if (on) - { - InitNodeForAbsorb(); - _patch ??= Harmony.CreateAndPatchAll(typeof(StopEjectOnNodeComplete)); - GameLogic.OnGameBegin += GameMain_Begin_Postfix; - GameLogic.OnGameEnd += GameMain_End_Postfix; - } - else - { - GameLogic.OnGameEnd -= GameMain_End_Postfix; - GameLogic.OnGameBegin -= GameMain_Begin_Postfix; - _patch?.UnpatchSelf(); - _patch = null; - _initialized = false; - _nodeForAbsorb = null; - } + InitNodeForAbsorb(); + GameLogic.OnGameBegin += GameMain_Begin_Postfix; + GameLogic.OnGameEnd += GameMain_End_Postfix; + } + + protected override void OnDisable() + { + GameLogic.OnGameEnd -= GameMain_End_Postfix; + GameLogic.OnGameBegin -= GameMain_Begin_Postfix; + _initialized = false; + _nodeForAbsorb = null; } private static void InitNodeForAbsorb() @@ -506,22 +500,10 @@ public static class DysonSpherePatch } } - private static class OnlyConstructNodes + private class OnlyConstructNodes: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) + protected override void OnEnable() { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(OnlyConstructNodes)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - var spheres = GameMain.data?.dysonSpheres; if (spheres == null) return; foreach (var sphere in spheres) diff --git a/UXAssist/FactoryPatch.cs b/UXAssist/Patches/FactoryPatch.cs similarity index 92% rename from UXAssist/FactoryPatch.cs rename to UXAssist/Patches/FactoryPatch.cs index 73a2ac8..8244857 100644 --- a/UXAssist/FactoryPatch.cs +++ b/UXAssist/Patches/FactoryPatch.cs @@ -10,7 +10,7 @@ using HarmonyLib; using UnityEngine; using UXAssist.Common; -namespace UXAssist; +namespace UXAssist.Patches; public static class FactoryPatch { @@ -162,9 +162,8 @@ public static class FactoryPatch return matcher.InstructionEnumeration(); } - public static class NightLight + public class NightLight: PatchImpl { - private static Harmony _patch; private const float NightLightAngleX = -8; private const float NightLightAngleY = -2; public static bool Enabled; @@ -173,25 +172,21 @@ public static class FactoryPatch private static AnimationState _sail; private static Light _sunlight; - public static void Enable(bool on) + protected override void OnEnable() + { + Enabled = _mechaOnEarth; + } + + protected override void OnDisable() { - if (on) - { - Enabled = _mechaOnEarth; - _patch ??= Harmony.CreateAndPatchAll(typeof(NightLight)); - return; - } - Enabled = false; - _patch?.UnpatchSelf(); - _patch = null; if (_sunlight == null) return; _sunlight.transform.localEulerAngles = new Vector3(0f, 180f); } public static void LateUpdate() { - if (_patch == null) return; + if (!Enabled) return; switch (_nightlightInitialized) { @@ -281,7 +276,7 @@ public static class FactoryPatch new CodeMatch(OpCodes.Ldarg_0), new CodeMatch(OpCodes.Call, AccessTools.PropertyGetter(typeof(Component), nameof(Component.transform))) ).InsertAndAdvance( - new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(NightLight), nameof(NightLight.Enabled))), + new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(NightLight), nameof(Enabled))), 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))), @@ -307,7 +302,7 @@ public static class FactoryPatch matcher.MatchForward(false, new CodeMatch(OpCodes.Stloc_1) ).Advance(1).InsertAndAdvance( - new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(NightLight), nameof(NightLight.Enabled))), + new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(NightLight), nameof(Enabled))), 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))), @@ -323,22 +318,8 @@ public static class FactoryPatch } } - private static class UnlimitInteractive + private class UnlimitInteractive: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(UnlimitInteractive)); - return; - } - - _patch?.UnpatchSelf(); - _patch = null; - } - [HarmonyTranspiler] [HarmonyPatch(typeof(PlayerAction_Inspect), nameof(PlayerAction_Inspect.GetObjectSelectDistance))] private static IEnumerable PlayerAction_Inspect_GetObjectSelectDistance_Transpiler(IEnumerable instructions) @@ -348,22 +329,8 @@ public static class FactoryPatch } } - private static class RemoveSomeConditionBuild + private class RemoveSomeConditionBuild: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(RemoveSomeConditionBuild)); - return; - } - - _patch?.UnpatchSelf(); - _patch = null; - } - [HarmonyTranspiler, HarmonyPriority(Priority.First)] [HarmonyPatch(typeof(BuildTool_BlueprintPaste), nameof(BuildTool_BlueprintPaste.CheckBuildConditions))] [HarmonyPatch(typeof(BuildTool_Click), nameof(BuildTool_Click.CheckBuildConditions))] @@ -459,26 +426,14 @@ public static class FactoryPatch } } - private static class RemoveBuildRangeLimit + private class RemoveBuildRangeLimit: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool enable) + protected override void OnEnable() { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(RemoveBuildRangeLimit)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - var controller = GameMain.mainPlayer?.controller; if (controller == null) return; controller.actionBuild?.clickTool?._OnInit(); - } + } [HarmonyTranspiler] [HarmonyPatch(typeof(BuildTool_Click), nameof(BuildTool_Click._OnInit))] @@ -522,22 +477,8 @@ public static class FactoryPatch } } - private static class LargerAreaForUpgradeAndDismantle + private class LargerAreaForUpgradeAndDismantle: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(LargerAreaForUpgradeAndDismantle)); - return; - } - - _patch?.UnpatchSelf(); - _patch = null; - } - [HarmonyTranspiler] [HarmonyPatch(typeof(BuildTool_Dismantle), nameof(BuildTool_Dismantle.DeterminePreviews))] [HarmonyPatch(typeof(BuildTool_Upgrade), nameof(BuildTool_Upgrade.DeterminePreviews))] @@ -552,22 +493,8 @@ public static class FactoryPatch } } - private static class LargerAreaForTerraform + private class LargerAreaForTerraform: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(LargerAreaForTerraform)); - return; - } - - _patch?.UnpatchSelf(); - _patch = null; - } - [HarmonyTranspiler, HarmonyPatch(typeof(BuildTool_Reform), nameof(BuildTool_Reform.ReformAction))] private static IEnumerable BuildTool_Reform_ReformAction_Transpiler(IEnumerable instructions, ILGenerator generator) { @@ -586,23 +513,10 @@ public static class FactoryPatch } } - public static class OffGridBuilding + public class OffGridBuilding: PatchImpl { - private static Harmony _patch; private const float SteppedRotationDegrees = 15f; - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(OffGridBuilding)); - return; - } - - _patch?.UnpatchSelf(); - _patch = null; - } - private static bool _initialized; [HarmonyPostfix, HarmonyPatch(typeof(UIRoot), "_OnOpen")] @@ -784,8 +698,8 @@ public static class FactoryPatch var jmp0 = generator.DefineLabel(); var jmp1 = generator.DefineLabel(); matcher.InsertAndAdvance( - new CodeInstruction(OpCodes.Call, AccessTools.PropertyGetter(typeof(VFInput), nameof(VFInput._switchModelStyle))), - new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(VFInput.InputValue), nameof(VFInput.InputValue.pressing))), + new CodeInstruction(OpCodes.Ldc_I4, (int)KeyCode.LeftControl), + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Input), nameof(Input.GetKeyInt))), new CodeInstruction(OpCodes.Brfalse, jmp0), new CodeInstruction(OpCodes.Ldarg_0), new CodeInstruction(OpCodes.Ldarg_0), @@ -836,7 +750,7 @@ public static class FactoryPatch matcher.InsertAndAdvance( new CodeInstruction(OpCodes.Brfalse, existingEntryLabel), new CodeInstruction(OpCodes.Ldarg_0), - CodeInstruction.Call(typeof(OffGridBuilding), nameof(OffGridBuilding.RotateStepped)), + CodeInstruction.Call(typeof(OffGridBuilding), nameof(RotateStepped)), new CodeInstruction(OpCodes.Br, ifBlockExitLabel) ); @@ -861,22 +775,8 @@ public static class FactoryPatch } } - public static class TreatStackingAsSingle + public class TreatStackingAsSingle: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(TreatStackingAsSingle)); - return; - } - - _patch?.UnpatchSelf(); - _patch = null; - } - [HarmonyTranspiler] [HarmonyPatch(typeof(MonitorComponent), nameof(MonitorComponent.InternalUpdate))] private static IEnumerable MonitorComponent_InternalUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) @@ -896,22 +796,8 @@ public static class FactoryPatch } } - private static class QuickBuildAndDismantleLab + private class QuickBuildAndDismantleLab: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(QuickBuildAndDismantleLab)); - return; - } - - _patch?.UnpatchSelf(); - _patch = null; - } - private static bool DetermineMoreLabsForDismantle(BuildTool dismantle, int id) { if (!VFInput._chainReaction) return true; @@ -1056,25 +942,11 @@ public static class FactoryPatch } } - public static class ProtectVeinsFromExhaustion + public class ProtectVeinsFromExhaustion: PatchImpl { public static int KeepVeinAmount = 100; public static float KeepOilSpeed = 1f; - private static int _keepOilAmount = Math.Max((int)(KeepOilSpeed / 0.00004f + 0.5f), 2500); - - private static Harmony _patch; - - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(ProtectVeinsFromExhaustion)); - return; - } - - _patch?.UnpatchSelf(); - _patch = null; - } + private static readonly int KeepOilAmount = Math.Max((int)(KeepOilSpeed / 0.00004f + 0.5f), 2500); [HarmonyPrefix] [HarmonyPatch(typeof(MinerComponent), nameof(MinerComponent.InternalUpdate))] @@ -1243,10 +1115,10 @@ public static class FactoryPatch __instance.productId = veinPool[veinId].productId; times = __instance.time / __instance.period; var outputCount = 0; - if (miningRate > 0f && amount > _keepOilAmount) + if (miningRate > 0f && amount > KeepOilAmount) { var usedCount = 0; - var maxAllowed = amount - _keepOilAmount; + var maxAllowed = amount - KeepOilAmount; for (var j = 0; j < times; j++) { __instance.seed = (uint)((__instance.seed % 2147483646U + 1U) * 48271UL % 2147483647UL) - 1U; @@ -1272,7 +1144,7 @@ public static class FactoryPatch } } } - else if (_keepOilAmount <= 2500) + else if (KeepOilAmount <= 2500) { outputCount = times; } @@ -1350,22 +1222,8 @@ public static class FactoryPatch } } - private static class DoNotRenderEntities + private class DoNotRenderEntities: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(DoNotRenderEntities)); - return; - } - - _patch?.UnpatchSelf(); - _patch = null; - } - [HarmonyPrefix] [HarmonyPatch(typeof(ObjectRenderer), nameof(ObjectRenderer.Render))] [HarmonyPatch(typeof(DynamicRenderer), nameof(DynamicRenderer.Render))] @@ -1422,29 +1280,24 @@ public static class FactoryPatch } } - private static class DragBuildPowerPoles + private class DragBuildPowerPoles: PatchImpl { - private static Harmony _patch; private static readonly List OldDragBuild = []; private static readonly List OldDragBuildDist = []; private static readonly int[] PowerPoleIds = [2201, 2202, 2212]; - public static void Enable(bool enable) + protected override void OnEnable() + { + GameLogic.OnGameBegin += GameMain_Begin_Postfix; + GameLogic.OnGameEnd += GameMain_End_Postfix; + FixProto(); + } + + protected override void OnDisable() { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(DragBuildPowerPoles)); - GameLogic.OnGameBegin += GameMain_Begin_Postfix; - GameLogic.OnGameEnd += GameMain_End_Postfix; - FixProto(); - return; - } - UnfixProto(); GameLogic.OnGameEnd -= GameMain_End_Postfix; GameLogic.OnGameBegin -= GameMain_Begin_Postfix; - _patch?.UnpatchSelf(); - _patch = null; } private static bool IsPowerPole(int id) @@ -1471,7 +1324,7 @@ public static class FactoryPatch private static void UnfixProto() { - if (_patch == null || OldDragBuild.Count < 3 || DSPGame.IsMenuDemo) return; + if (GetPatch() == null || OldDragBuild.Count < 3 || DSPGame.IsMenuDemo) return; var i = 0; foreach (var id in PowerPoleIds) { @@ -1593,10 +1446,8 @@ public static class FactoryPatch } } - private static class BeltSignalsForBuyOut + private class BeltSignalsForBuyOut: PatchImpl { - private static Harmony _patch; - private static Harmony _persistPatch; private static bool _initialized; private static bool _loaded; private static long _clusterSeedKey; @@ -1608,30 +1459,12 @@ public static class FactoryPatch public static void InitPersist() { - AddBeltSignalProtos(); - _persistPatch = Harmony.CreateAndPatchAll(typeof(Persist)); - GameLogic.OnDataLoaded += Persist.VFPreload_InvokeOnLoadWorkEnded_Postfix; - GameLogic.OnGameBegin += Persist.GameMain_Begin_Postfix; + Persist.Enable(true); } public static void UninitPersist() { - GameLogic.OnGameBegin -= Persist.GameMain_Begin_Postfix; - GameLogic.OnDataLoaded -= Persist.VFPreload_InvokeOnLoadWorkEnded_Postfix; - _persistPatch?.UnpatchSelf(); - _persistPatch = null; - } - - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(BeltSignalsForBuyOut)); - return; - } - - _patch?.UnpatchSelf(); - _patch = null; + Persist.Enable(false); } private static void AddBeltSignalProtos() @@ -1801,13 +1634,26 @@ public static class FactoryPatch SignalBeltFactoryIndices.Remove(factory); } - private static class Persist + private class Persist: PatchImpl { + protected override void OnEnable() + { + AddBeltSignalProtos(); + GameLogic.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix; + GameLogic.OnGameBegin += GameMain_Begin_Postfix; + } + + protected override void OnDisable() + { + GameLogic.OnGameBegin -= GameMain_Begin_Postfix; + GameLogic.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix; + } + public static void VFPreload_InvokeOnLoadWorkEnded_Postfix() { - if (BeltSignalsForBuyOut._initialized) return; - BeltSignalsForBuyOut._initialized = true; - BeltSignalsForBuyOut.AddBeltSignalProtos(); + if (_initialized) return; + _initialized = true; + AddBeltSignalProtos(); } [HarmonyPostfix] diff --git a/UXAssist/GamePatch.cs b/UXAssist/Patches/GamePatch.cs similarity index 86% rename from UXAssist/GamePatch.cs rename to UXAssist/Patches/GamePatch.cs index 998cb95..53cf869 100644 --- a/UXAssist/GamePatch.cs +++ b/UXAssist/Patches/GamePatch.cs @@ -7,7 +7,7 @@ using HarmonyLib; using UnityEngine; using UXAssist.Common; -namespace UXAssist; +namespace UXAssist.Patches; public static class GamePatch { @@ -24,6 +24,32 @@ public static class GamePatch public static ConfigEntry LastWindowRect; public static ConfigEntry ProfileBasedSaveFolderEnabled; public static ConfigEntry DefaultProfileName; + public static ConfigEntry GameUpsFactor; + + private static bool _enableGameUpsFactor = true; + public static bool EnableGameUpsFactor + { + get => _enableGameUpsFactor; + set + { + _enableGameUpsFactor = value; + if (value) + { + var oldFixUps = FPSController.instance.fixUPS; + if (oldFixUps <= 1.0) + { + GameUpsFactor.Value = 1.0; + return; + } + GameUpsFactor.Value = Maths.Clamp(FPSController.instance.fixUPS / GameMain.tickPerSec, 0.1, 10.0); + } + else + { + GameUpsFactor.Value = 1.0; + } + } + } + private static Harmony _gamePatch; public static void Init() @@ -55,21 +81,27 @@ public static class GamePatch LoadLastWindowRectEnabled.SettingChanged += (_, _) => LoadLastWindowRect.Enable(LoadLastWindowRectEnabled.Value); MouseCursorScaleUpMultiplier.SettingChanged += (_, _) => { - MouseCursorScaleUp.Enable(MouseCursorScaleUpMultiplier.Value > 1, true); + MouseCursorScaleUp.reload = true; + MouseCursorScaleUp.Enable(MouseCursorScaleUpMultiplier.Value > 1); }; // AutoSaveOptEnabled.SettingChanged += (_, _) => AutoSaveOpt.Enable(AutoSaveOptEnabled.Value); ConvertSavesFromPeaceEnabled.SettingChanged += (_, _) => ConvertSavesFromPeace.Enable(ConvertSavesFromPeaceEnabled.Value); - ProfileBasedSaveFolderEnabled.SettingChanged += (_, _) => + ProfileBasedSaveFolderEnabled.SettingChanged += (_, _) => RefreshSavePath(); + DefaultProfileName.SettingChanged += (_, _) => RefreshSavePath(); + GameUpsFactor.SettingChanged += (_, _) => { - RefreshSavePath(); - }; - DefaultProfileName.SettingChanged += (_, _) => - { - RefreshSavePath(); + if (!EnableGameUpsFactor || GameUpsFactor.Value == 0.0) return; + if (Math.Abs(GameUpsFactor.Value - 1.0) < 0.001) + { + FPSController.SetFixUPS(0.0); + return; + } + FPSController.SetFixUPS(GameMain.tickPerSec * GameUpsFactor.Value); }; EnableWindowResize.Enable(EnableWindowResizeEnabled.Value); LoadLastWindowRect.Enable(LoadLastWindowRectEnabled.Value); - MouseCursorScaleUp.Enable(MouseCursorScaleUpMultiplier.Value > 1, false); + MouseCursorScaleUp.reload = false; + MouseCursorScaleUp.Enable(MouseCursorScaleUpMultiplier.Value > 1); // AutoSaveOpt.Enable(AutoSaveOptEnabled.Value); ConvertSavesFromPeace.Enable(ConvertSavesFromPeaceEnabled.Value); _gamePatch ??= Harmony.CreateAndPatchAll(typeof(GamePatch)); @@ -79,7 +111,8 @@ public static class GamePatch { LoadLastWindowRect.Enable(false); EnableWindowResize.Enable(false); - MouseCursorScaleUp.Enable(false, false); + MouseCursorScaleUp.reload = false; + MouseCursorScaleUp.Enable(false); // AutoSaveOpt.Enable(false); ConvertSavesFromPeace.Enable(false); _gamePatch?.UnpatchSelf(); @@ -121,28 +154,36 @@ public static class GamePatch LastWindowRect.Value = new Vector4(rect.Left, rect.Top, Screen.width, Screen.height); } - private static class EnableWindowResize + private class EnableWindowResize: PatchImpl { + private static bool _enabled; - private static Harmony _patch; - public static void Enable(bool on) + + protected override void OnEnable() { var wnd = WinApi.FindWindow(GameWindowClass, _gameWindowTitle); - if (wnd == IntPtr.Zero) return; - _enabled = on; - if (on) + if (wnd == IntPtr.Zero) { - WinApi.SetWindowLong(wnd, (int)WindowLongFlags.GWL_STYLE, - WinApi.GetWindowLong(wnd, (int)WindowLongFlags.GWL_STYLE) | (int)WindowStyles.WS_THICKFRAME | (int)WindowStyles.WS_MAXIMIZEBOX); - _patch ??= Harmony.CreateAndPatchAll(typeof(EnableWindowResize)); + Enable(false); return; } - _patch?.UnpatchSelf(); - _patch = null; + + _enabled = true; + WinApi.SetWindowLong(wnd, (int)WindowLongFlags.GWL_STYLE, + WinApi.GetWindowLong(wnd, (int)WindowLongFlags.GWL_STYLE) | (int)WindowStyles.WS_THICKFRAME | (int)WindowStyles.WS_MAXIMIZEBOX); + } + + protected override void OnDisable() + { + var wnd = WinApi.FindWindow(GameWindowClass, _gameWindowTitle); + if (wnd == IntPtr.Zero) + return; + + _enabled = false; WinApi.SetWindowLong(wnd, (int)WindowLongFlags.GWL_STYLE, WinApi.GetWindowLong(wnd, (int)WindowLongFlags.GWL_STYLE) & ~((int)WindowStyles.WS_THICKFRAME | (int)WindowStyles.WS_MAXIMIZEBOX)); } - + [HarmonyPostfix] [HarmonyPatch(typeof(UIOptionWindow), nameof(UIOptionWindow.ApplyOptions))] private static void UIOptionWindow_ApplyOptions_Postfix() @@ -158,67 +199,64 @@ public static class GamePatch } } - private static class LoadLastWindowRect + private class LoadLastWindowRect: PatchImpl { - private static Harmony _patch; private static bool _loaded; - public static void Enable(bool on) + + protected override void OnEnable() { - if (on) + GameLogic.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix; + if (Screen.fullScreenMode is not (FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow)) { - _patch ??= Harmony.CreateAndPatchAll(typeof(LoadLastWindowRect)); - GameLogic.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix; - if (Screen.fullScreenMode is not (FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow)) + var rect = LastWindowRect.Value; + var x = Mathf.RoundToInt(rect.x); + var y = Mathf.RoundToInt(rect.y); + var w = Mathf.RoundToInt(rect.z); + var h = Mathf.RoundToInt(rect.w); + var needFix = false; + if (w < 100) { - var rect = LastWindowRect.Value; - var x = Mathf.RoundToInt(rect.x); - var y = Mathf.RoundToInt(rect.y); - var w = Mathf.RoundToInt(rect.z); - var h = Mathf.RoundToInt(rect.w); - var needFix = false; - if (w < 100) - { - w = 1280; - needFix = true; - } - if (h < 100) - { - h = 720; - needFix = true; - } - var sw = Screen.currentResolution.width; - var sh = Screen.currentResolution.height; - if (x + w > sw) - { - x = sw - w; - needFix = true; - } - if (y + h > sh) - { - y = sh - h; - needFix = true; - } - if (x < 0) - { - x = 0; - needFix = true; - } - if (y < 0) - { - y = 0; - needFix = true; - } - if (needFix) - { - LastWindowRect.Value = new Vector4(x, y, w, h); - } + w = 1280; + needFix = true; + } + if (h < 100) + { + h = 720; + needFix = true; + } + var sw = Screen.currentResolution.width; + var sh = Screen.currentResolution.height; + if (x + w > sw) + { + x = sw - w; + needFix = true; + } + if (y + h > sh) + { + y = sh - h; + needFix = true; + } + if (x < 0) + { + x = 0; + needFix = true; + } + if (y < 0) + { + y = 0; + needFix = true; + } + if (needFix) + { + LastWindowRect.Value = new Vector4(x, y, w, h); } - MoveWindowPosition(); - return; } + MoveWindowPosition(); + } + + protected override void OnDisable() + { GameLogic.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix; - _patch?.UnpatchSelf(); - _patch = null; } private static void MoveWindowPosition() @@ -447,20 +485,9 @@ public static class GamePatch } */ - private static class ConvertSavesFromPeace + private class ConvertSavesFromPeace: PatchImpl { - private static Harmony _patch; private static bool _needConvert; - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(ConvertSavesFromPeace)); - return; - } - _patch?.UnpatchSelf(); - _patch = null; - } [HarmonyPostfix] [HarmonyPatch(typeof(GameDesc), nameof(GameDesc.Import))] @@ -496,24 +523,20 @@ public static class GamePatch } } - private static class MouseCursorScaleUp + private class MouseCursorScaleUp: PatchImpl { - private static Harmony _patch; + public static bool reload; - public static void Enable(bool on, bool reload) + protected override void OnEnable() { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(MouseCursorScaleUp)); - if (!reload) return; - if (!UICursor.loaded) return; - UICursor.loaded = false; - UICursor.LoadCursors(); - return; - } + if (!reload) return; + if (!UICursor.loaded) return; + UICursor.loaded = false; + UICursor.LoadCursors(); + } - _patch?.UnpatchSelf(); - _patch = null; + protected override void OnDisable() + { if (!reload) return; if (!UICursor.loaded) return; UICursor.loaded = false; diff --git a/UXAssist/LogisticsPatch.cs b/UXAssist/Patches/LogisticsPatch.cs similarity index 98% rename from UXAssist/LogisticsPatch.cs rename to UXAssist/Patches/LogisticsPatch.cs index 96d2df7..b7f9b3f 100644 --- a/UXAssist/LogisticsPatch.cs +++ b/UXAssist/Patches/LogisticsPatch.cs @@ -10,7 +10,7 @@ using UnityEngine.Serialization; using UnityEngine.UI; using UXAssist.Common; -namespace UXAssist; +namespace UXAssist.Patches; public static class LogisticsPatch { @@ -61,22 +61,8 @@ public static class LogisticsPatch } } - public static class LogisticsCapacityTweaks + public class LogisticsCapacityTweaks: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(LogisticsCapacityTweaks)); - return; - } - - _patch?.UnpatchSelf(); - _patch = null; - } - private static KeyCode _lastKey = KeyCode.None; private static long _nextKeyTick; private static bool _skipNextEvent; @@ -263,22 +249,8 @@ public static class LogisticsPatch } } - private static class AllowOverflowInLogistics + private class AllowOverflowInLogistics: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(AllowOverflowInLogistics)); - return; - } - - _patch?.UnpatchSelf(); - _patch = null; - } - // Do not check for overflow when try to send hand items into storages [HarmonyTranspiler] [HarmonyPatch(typeof(UIStationStorage), nameof(UIStationStorage.OnItemIconMouseDown))] @@ -329,22 +301,8 @@ public static class LogisticsPatch } } - private static class LogisticsConstrolPanelImprovement + private class LogisticsConstrolPanelImprovement: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool enable) - { - if (enable) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(LogisticsConstrolPanelImprovement)); - return; - } - - _patch?.UnpatchSelf(); - _patch = null; - } - private static int ItemIdHintUnderMouse() { List targets = []; diff --git a/UXAssist/PlanetPatch.cs b/UXAssist/Patches/PlanetPatch.cs similarity index 90% rename from UXAssist/PlanetPatch.cs rename to UXAssist/Patches/PlanetPatch.cs index 56f080d..9364675 100644 --- a/UXAssist/PlanetPatch.cs +++ b/UXAssist/Patches/PlanetPatch.cs @@ -2,8 +2,9 @@ using System.Reflection.Emit; using BepInEx.Configuration; using HarmonyLib; +using UXAssist.Common; -namespace UXAssist; +namespace UXAssist.Patches; public static class PlanetPatch { public static ConfigEntry PlayerActionsInGlobeViewEnabled; @@ -19,21 +20,8 @@ public static class PlanetPatch PlayerActionsInGlobeView.Enable(false); } - public static class PlayerActionsInGlobeView + public class PlayerActionsInGlobeView: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(PlayerActionsInGlobeView)); - return; - } - _patch?.UnpatchSelf(); - _patch = null; - } - [HarmonyTranspiler] [HarmonyPatch(typeof(VFInput), nameof(VFInput.UpdateGameStates))] private static IEnumerable VFInput_UpdateGameStates_Transpiler(IEnumerable instructions, ILGenerator generator) diff --git a/UXAssist/PlayerPatch.cs b/UXAssist/Patches/PlayerPatch.cs similarity index 93% rename from UXAssist/PlayerPatch.cs rename to UXAssist/Patches/PlayerPatch.cs index 2028bdf..f6d8eb6 100644 --- a/UXAssist/PlayerPatch.cs +++ b/UXAssist/Patches/PlayerPatch.cs @@ -6,7 +6,7 @@ using HarmonyLib; using UnityEngine; using UXAssist.Common; -namespace UXAssist; +namespace UXAssist.Patches; public static class PlayerPatch { @@ -52,23 +52,8 @@ public static class PlayerPatch AutoNavigation.Enable(false); } - private static class EnhancedMechaForgeCountControl + private class EnhancedMechaForgeCountControl: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(EnhancedMechaForgeCountControl)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } - [HarmonyTranspiler] [HarmonyPatch(typeof(UIReplicatorWindow), nameof(UIReplicatorWindow.OnOkButtonClick))] private static IEnumerable UIReplicatorWindow_OnOkButtonClick_Transpiler(IEnumerable instructions, ILGenerator generator) @@ -118,23 +103,8 @@ public static class PlayerPatch } } - private static class HideTipsForSandsChanges + private class HideTipsForSandsChanges: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(HideTipsForSandsChanges)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } - [HarmonyTranspiler] [HarmonyPatch(typeof(Player), nameof(Player.SetSandCount))] private static IEnumerable Player_SetSandCount_Transpiler(IEnumerable instructions, ILGenerator generator) @@ -147,27 +117,12 @@ public static class PlayerPatch } } - public static class AutoNavigation + public class AutoNavigation: PatchImpl { - private static Harmony _patch; - private static bool _canUseWarper; private static int _indicatorAstroId; private static bool _speedUp; private static Vector3 _direction; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(AutoNavigation)); - } - else - { - _patch?.UnpatchSelf(); - _patch = null; - } - } public static void ToggleAutoCruise() { diff --git a/UXAssist/TechPatch.cs b/UXAssist/Patches/TechPatch.cs similarity index 94% rename from UXAssist/TechPatch.cs rename to UXAssist/Patches/TechPatch.cs index 21750b4..643164f 100644 --- a/UXAssist/TechPatch.cs +++ b/UXAssist/Patches/TechPatch.cs @@ -6,7 +6,7 @@ using HarmonyLib; using UnityEngine; using UXAssist.Common; -namespace UXAssist; +namespace UXAssist.Patches; public static class TechPatch { @@ -28,23 +28,20 @@ public static class TechPatch SorterCargoStacking.Enable(false); } - private static class SorterCargoStacking + private class SorterCargoStacking: PatchImpl { - private static Harmony _patch; private static bool _protoPatched; - public static void Enable(bool on) + protected override void OnEnable() + { + TryPatchProto(true); + GameLogic.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix; + } + + protected override void OnDisable() { - TryPatchProto(on); - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(SorterCargoStacking)); - GameLogic.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix; - return; - } GameLogic.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix; - _patch?.UnpatchSelf(); - _patch = null; + TryPatchProto(false); } private static void TryPatchProto(bool on) @@ -113,22 +110,8 @@ public static class TechPatch } } - private static class BatchBuyoutTech + private class BatchBuyoutTech: PatchImpl { - private static Harmony _patch; - - public static void Enable(bool on) - { - if (on) - { - _patch ??= Harmony.CreateAndPatchAll(typeof(BatchBuyoutTech)); - return; - } - - _patch?.UnpatchSelf(); - _patch = null; - } - private static void GenerateTechList(GameHistoryData history, int techId, List techIdList) { var techProto = LDB.techs.Select(techId); diff --git a/UXAssist/UI/MyWindow.cs b/UXAssist/UI/MyWindow.cs index 2d7a410..cf3434a 100644 --- a/UXAssist/UI/MyWindow.cs +++ b/UXAssist/UI/MyWindow.cs @@ -225,6 +225,7 @@ public class MyWindow : ManualBehaviour { var index = OnConfigValueChanged(config); slider.Value = index; + slider.SetLabelText(valueMapper.FormatValue(format, config.Value)); }; slider.OnValueChanged += () => { diff --git a/UXAssist/UIConfigWindow.cs b/UXAssist/UIConfigWindow.cs index 68e1577..4d89937 100644 --- a/UXAssist/UIConfigWindow.cs +++ b/UXAssist/UIConfigWindow.cs @@ -1,6 +1,8 @@ using UnityEngine; using UXAssist.UI; using UXAssist.Common; +using UXAssist.Functions; +using UXAssist.Patches; namespace UXAssist; @@ -30,6 +32,8 @@ public static class UIConfigWindow I18N.Add("Profile-based save folder tips", "Save files are stored in 'Save\\' folder.\nWill use original save location if matching default profile name", "存档文件会存储在'Save\\'文件夹中\n如果匹配默认配置档案名则使用原始存档位置"); I18N.Add("Default profile name", "Default profile name", "默认配置档案名"); + I18N.Add("Logical Frame Rate", "Logical Frame Rate", "逻辑帧倍率"); + I18N.Add("Reset", "Reset", "重置"); I18N.Add("Unlimited interactive range", "Unlimited interactive range", "无限交互距离"); I18N.Add("Night Light", "Sunlight at night", "夜间日光灯"); I18N.Add("Remove some build conditions", "Remove some build conditions", "移除部分不影响游戏逻辑的建造条件"); @@ -108,6 +112,14 @@ public static class UIConfigWindow public override int ValueToIndex(double value) => Mathf.RoundToInt((float)(value * 2.0)); } + private class UpsMapper : MyWindow.ValueMapper + { + public override int Min => 1; + public override int Max => 100; + public override double IndexToValue(int index) => index * 0.1; + public override int ValueToIndex(double value) => Mathf.RoundToInt((float)(value * 10.0)); + } + private static void CreateUI(MyConfigWindow wnd, RectTransform trans) { MyCheckBox checkBoxForMeasureTipsPos; @@ -121,9 +133,9 @@ public static class UIConfigWindow y += 36f; wnd.AddCheckBox(x, y, tab1, GamePatch.LoadLastWindowRectEnabled, "Remeber window position and size on last exit"); y += 36f; - var txt = wnd.AddText2(x, y, tab1, "Scale up mouse cursor", 15, "text-scale-up-mouse-cursor"); + var txt = wnd.AddText2(x + 2f, y, tab1, "Scale up mouse cursor", 15, "text-scale-up-mouse-cursor"); x += txt.preferredWidth + 5f; - wnd.AddSlider(x, y + 6f, tab1, GamePatch.MouseCursorScaleUpMultiplier, [1, 2, 3, 4], "0x", 100f); + wnd.AddSlider(x + 2f, y + 6f, tab1, GamePatch.MouseCursorScaleUpMultiplier, [1, 2, 3, 4], "0x", 100f); x = 0f; /* y += 30f; @@ -147,6 +159,17 @@ public static class UIConfigWindow wnd.AddText2(x, y, tab1, "Default profile name", 15, "text-default-profile-name"); y += 24f; wnd.AddInputField(x, y, 200f, tab1, GamePatch.DefaultProfileName, 15, "input-profile-save-folder"); + y += 18f; + } + + if (!ModsCompat.BulletTimeWrapper.HasBulletTime) + { + y += 36f; + txt = wnd.AddText2(x + 2f, y, tab1, "Logical Frame Rate", 15, "game-frame-rate"); + x += txt.preferredWidth + 5f; + wnd.AddSlider(x + 2f, y + 6f, tab1, GamePatch.GameUpsFactor, new UpsMapper(), "0.0x", 200f); + var btn = wnd.AddFlatButton(x + 204f, y + 6f, tab1, "Reset", 13, "reset-game-frame-rate", () => GamePatch.GameUpsFactor.Value = 1.0f); + ((RectTransform)btn.transform).sizeDelta = new Vector2(40f, 20f); } var tab2 = wnd.AddTab(trans, "Planet/Factory"); @@ -212,13 +235,11 @@ public static class UIConfigWindow y += 36f; var cb0 = wnd.AddCheckBox(x, y, tab2, LogisticsPatch.RealtimeLogisticsInfoPanelEnabled, "Real-time logistic stations info panel"); var cb1 = wnd.AddCheckBox(x + 26f, y + 26f, tab2, LogisticsPatch.RealtimeLogisticsInfoPanelBarsEnabled, "Show status bars for storage items", 13); - if (AuxilaryfunctionWrapper.ShowStationInfo != null) + if (ModsCompat.AuxilaryfunctionWrapper.ShowStationInfo != null) { - AuxilaryfunctionWrapper.ShowStationInfo.SettingChanged += (_, _) => { OnAuxilaryInfoPanelChanged(); }; + ModsCompat.AuxilaryfunctionWrapper.ShowStationInfo.SettingChanged += (_, _) => { OnAuxilaryInfoPanelChanged(); }; } - LogisticsPatch.RealtimeLogisticsInfoPanelEnabled.SettingChanged += (_, _) => { OnRealtimeLogisticsInfoPanelChanged(); }; OnAuxilaryInfoPanelChanged(); - OnRealtimeLogisticsInfoPanelChanged(); var tab3 = wnd.AddTab(trans, "Player/Mecha"); x = 0f; @@ -324,13 +345,13 @@ public static class UIConfigWindow void OnAuxilaryInfoPanelChanged() { - if (AuxilaryfunctionWrapper.ShowStationInfo == null) + if (ModsCompat.AuxilaryfunctionWrapper.ShowStationInfo == null) { cb0.gameObject.SetActive(true); cb1.gameObject.SetActive(true); return; } - var on = !AuxilaryfunctionWrapper.ShowStationInfo.Value; + var on = !ModsCompat.AuxilaryfunctionWrapper.ShowStationInfo.Value; cb0.gameObject.SetActive(on); cb1.gameObject.SetActive(on); if (!on) @@ -338,12 +359,6 @@ public static class UIConfigWindow LogisticsPatch.RealtimeLogisticsInfoPanelEnabled.Value = false; } } - - void OnRealtimeLogisticsInfoPanelChanged() - { - var on = LogisticsPatch.RealtimeLogisticsInfoPanelEnabled.Value; - cb1.gameObject.SetActive(on); - } } private static void UpdateUI() diff --git a/UXAssist/UXAssist.cs b/UXAssist/UXAssist.cs index c9c5e0a..f0ee42d 100644 --- a/UXAssist/UXAssist.cs +++ b/UXAssist/UXAssist.cs @@ -1,17 +1,20 @@ using System; using System.Collections.Generic; using System.IO; +using System.Reflection; using System.Reflection.Emit; using BepInEx; using BepInEx.Configuration; using CommonAPI; using CommonAPI.Systems; +using crecheng.DSPModSave; using HarmonyLib; using UnityEngine; using UnityEngine.UI; using UXAssist.Common; +using UXAssist.Functions; +using UXAssist.Patches; using UXAssist.UI; -using crecheng.DSPModSave; namespace UXAssist; @@ -30,6 +33,7 @@ public class UXAssist : BaseUnityPlugin, IModCanSave private static Harmony _persistPatch; private static bool _initialized; private static PressKeyBind _toggleKey; + private static ConfigFile _dummyConfig; #region IModCanSave private const ushort ModSaveVersion = 1; @@ -54,6 +58,10 @@ public class UXAssist : BaseUnityPlugin, IModCanSave private void Awake() { + _dummyConfig = new ConfigFile(Path.Combine(Paths.ConfigPath, PluginInfo.PLUGIN_GUID + "_dummy.cfg"), false) + { + SaveOnConfigSet = false + }; _toggleKey = KeyBindings.RegisterKeyBinding(new BuiltinKey { key = new CombineKey((int)KeyCode.BackQuote, CombineKey.ALT_COMB, ECombineKeyAction.OnceClick, false), @@ -79,6 +87,8 @@ public class UXAssist : BaseUnityPlugin, IModCanSave */ GamePatch.ConvertSavesFromPeaceEnabled = Config.Bind("Game", "ConvertSavesFromPeace", false, "Convert saves from Peace mode to Combat mode on save loading"); + GamePatch.GameUpsFactor = _dummyConfig.Bind("Game", "GameUpsFactor", 1.0, + "Game UPS factor (1.0 for normal speed)"); FactoryPatch.UnlimitInteractiveEnabled = Config.Bind("Factory", "UnlimitInteractive", false, "Unlimit interactive range"); FactoryPatch.RemoveSomeConditionEnabled = Config.Bind("Factory", "RemoveSomeBuildConditionCheck", false, @@ -140,49 +150,42 @@ public class UXAssist : BaseUnityPlugin, IModCanSave DysonSpherePatch.OnlyConstructNodesEnabled = Config.Bind("DysonSphere", "OnlyConstructNodes", false, "Construct only nodes but frames"); DysonSpherePatch.AutoConstructMultiplier = Config.Bind("DysonSphere", "AutoConstructMultiplier", 1, "Dyson Sphere auto-construct speed multiplier"); - + I18N.Init(); + } + + private void Start() + { I18N.Add("UXAssist Config", "UXAssist Config", "UX助手设置"); I18N.Add("KEYOpenUXAssistConfigWindow", "Open UXAssist Config Window", "打开UX助手设置面板"); I18N.Add("KEYToggleAutoCruise", "Toggle auto-cruise", "切换自动巡航"); // UI Patch - _patch ??= Harmony.CreateAndPatchAll(typeof(UXAssist)); + _patch ??= Harmony.CreateAndPatchAll(typeof(UXAssist), PluginInfo.PLUGIN_GUID); _persistPatch ??= Harmony.CreateAndPatchAll(typeof(Persist)); + GameLogic.Init(); MyWindowManager.Init(); UIConfigWindow.Init(); - GamePatch.Init(); - FactoryPatch.Init(); - LogisticsPatch.Init(); - PlanetPatch.Init(); - PlayerPatch.Init(); - TechPatch.Init(); - DysonSpherePatch.Init(); + + Common.Util.GetTypesInNamespace(Assembly.GetExecutingAssembly(), "UXAssist.Patches") + .Do(type => type.GetMethod("Init")?.Invoke(null, null)); + + ModsCompat.AuxilaryfunctionWrapper.Init(_patch); + ModsCompat.BulletTimeWrapper.Init(_patch); I18N.Apply(); I18N.OnInitialized += RecreateConfigWindow; - GameLogic.OnDataLoaded += () => - { - AuxilaryfunctionWrapper.Init(_patch); - }; - } - - private void Start() - { + LogisticsPatch.Start(); } private void OnDestroy() { - DysonSpherePatch.Uninit(); - TechPatch.Uninit(); - PlayerPatch.Uninit(); - PlanetPatch.Uninit(); - LogisticsPatch.Uninit(); - FactoryPatch.Uninit(); - GamePatch.Uninit(); + Common.Util.GetTypesInNamespace(Assembly.GetExecutingAssembly(), "UXAssist.Patches") + .Do(type => type.GetMethod("Uninit")?.Invoke(null, null)); + MyWindowManager.Uninit(); GameLogic.Uninit();