diff --git a/CringeLauncher/ImGuiHandler.cs b/CringeLauncher/ImGuiHandler.cs index fbca287..a220e76 100644 --- a/CringeLauncher/ImGuiHandler.cs +++ b/CringeLauncher/ImGuiHandler.cs @@ -10,6 +10,7 @@ using CringePlugins.Render; using ImGuiNET; using SharpDX.Direct3D11; using static ImGuiNET.ImGui; +using VRage; namespace CringeLauncher; @@ -91,6 +92,10 @@ internal class ImGuiHandler : IDisposable [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] private static unsafe int WndProcHook(HWND hWnd, int msg, nint wParam, nint lParam) { + //ignore input if mouse is hidden + if (MyVRage.Platform?.Input?.ShowCursor == false && Instance?.DrawMouse != true) + return CallWindowProc(_wndproc, hWnd, msg, wParam, lParam); + var hookResult = ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam); if (hookResult != 0) @@ -101,16 +106,12 @@ internal class ImGuiHandler : IDisposable if (!_init) return CallWindowProc(_wndproc, hWnd, msg, wParam, lParam); - //todo: block GetKeyStatesAsync or something related, find mouse input code in sharpDx var blockMessage = (msg is >= 256 and <= 265 && io.WantTextInput) || (msg is >= 512 and <= 526 && io.WantCaptureMouse); - /*if (!blockMessage) - Console.WriteLine($"{msg} - M:{io.WantCaptureMouse}, K:{io.WantTextInput}");*/ - return blockMessage ? hookResult : CallWindowProc(_wndproc, hWnd, msg, wParam, lParam); } - + [DllImport("USER32.dll", ExactSpelling = true, EntryPoint = "CallWindowProcW")] [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] [SupportedOSPlatform("windows5.0")] diff --git a/CringeLauncher/Patches/InputPatch.cs b/CringeLauncher/Patches/InputPatch.cs index 0b04449..03fa0d7 100644 --- a/CringeLauncher/Patches/InputPatch.cs +++ b/CringeLauncher/Patches/InputPatch.cs @@ -1,23 +1,28 @@ using HarmonyLib; +using Sandbox.Graphics; using VRage; using VRage.Input; using VRage.Input.Keyboard; using VRage.Platform.Windows.Input; +using VRageMath; namespace CringeLauncher.Patches; [HarmonyPatch] internal static class InputPatch { - [HarmonyPrefix, HarmonyPatch(typeof(MyDirectInput), nameof(MyDirectInput.GetMouseState))] - private static bool GetMouseStatePrefix(ref MyMouseState state) + [HarmonyPostfix, HarmonyPatch(typeof(MyDirectInput), nameof(MyDirectInput.GetMouseState))] + private static void GetMouseStatePostfix(ref MyMouseState state) { if (ImGuiHandler.Instance?.BlockMouse == true && (MyVRage.Platform.Input.ShowCursor || ImGuiHandler.Instance.DrawMouse)) { - state = default; - return false; + state.LeftButton = false; + state.RightButton = false; + state.MiddleButton = false; + state.XButton1 = false; + state.XButton2 = false; + state.ScrollWheelValue = 0; } - return true; } [HarmonyPrefix, HarmonyPatch(typeof(MyGuiLocalizedKeyboardState), nameof(MyGuiLocalizedKeyboardState.GetCurrentState))] @@ -30,4 +35,15 @@ internal static class InputPatch } return true; } + + [HarmonyPrefix, HarmonyPatch(typeof(MyGuiManager), nameof(MyGuiManager.MouseCursorPosition), MethodType.Getter)] + private static bool GetMouseCursorPositionPrefix(ref Vector2 __result) + { + if (ImGuiHandler.Instance?.BlockMouse == true && (MyVRage.Platform.Input.ShowCursor || ImGuiHandler.Instance.DrawMouse)) + { + __result = Vector2.Zero; + return false; + } + return true; + } } diff --git a/CringeLauncher/Patches/ModScriptCompilerPatch.cs b/CringeLauncher/Patches/ModScriptCompilerPatch.cs index 0463b72..39f53e8 100644 --- a/CringeLauncher/Patches/ModScriptCompilerPatch.cs +++ b/CringeLauncher/Patches/ModScriptCompilerPatch.cs @@ -21,6 +21,7 @@ using System.Runtime.CompilerServices; using System.Runtime.Loader; using System.Text; using VRage; +using VRage.Collections; using VRage.ModAPI; using VRage.Scripting; using Message = VRage.Scripting.Message; @@ -30,6 +31,8 @@ namespace CringeLauncher.Patches; [HarmonyPatch] public static class ModScriptCompilerPatch { + internal static readonly MyConcurrentHashSet CompilingPbs = []; + private static readonly Logger Log = LogManager.GetCurrentClassLogger(); private static ModAssemblyLoadContext _modContext; private static readonly HashSet LoadedModAssemblyNames = []; @@ -87,7 +90,7 @@ public static class ModScriptCompilerPatch ref MyProgrammableBlock.ScriptTerminationReason ___m_terminationReason, MyIngameScriptComponent ___m_scriptComponent) { - if (!MySession.Static.EnableIngameScripts || __instance.CubeGrid is { IsPreview: true } or { CreatePhysics: false }) + if (!MySession.Static.EnableIngameScripts || __instance.CubeGrid is { IsPreview: true } or { CreatePhysics: false } || !CompilingPbs.Add(__instance)) return false; ___m_terminationReason = MyProgrammableBlock.ScriptTerminationReason.None; @@ -164,13 +167,13 @@ public static class ModScriptCompilerPatch string storage, bool instantiate, MyIngameScriptComponent scriptComponent) { - scriptComponent.NeedsUpdate = MyEntityUpdateEnum.NONE; - scriptComponent.UpdateFrequency = UpdateFrequency.None; - - SetDetailedInfoMethod.Invoke(block, ["Compiling..."]); - try { + scriptComponent.NeedsUpdate = MyEntityUpdateEnum.NONE; + scriptComponent.UpdateFrequency = UpdateFrequency.None; + + SetDetailedInfoMethod.Invoke(block, ["Compiling..."]); + if (LoadContexts.TryGetValue(block, out var context)) { AccessTools.FieldRefAccess(block, InstanceField) = null; @@ -203,6 +206,10 @@ public static class ModScriptCompilerPatch SetDetailedInfoMethod.Invoke(block, [e.ToString()]); Log.Error(e); } + finally + { + CompilingPbs.Remove(block); + } } private static async Task CompileAsync(AssemblyLoadContext context, MyApiTarget target, diff --git a/CringeLauncher/Patches/PbInstantiatePatch.cs b/CringeLauncher/Patches/PbInstantiatePatch.cs new file mode 100644 index 0000000..1e2a670 --- /dev/null +++ b/CringeLauncher/Patches/PbInstantiatePatch.cs @@ -0,0 +1,36 @@ +using HarmonyLib; +using Sandbox.Game.Entities.Blocks; +using System.Reflection.Emit; + +namespace CringeLauncher.Patches; + +[HarmonyPatch(typeof(MyProgrammableBlock), "UpdateBeforeSimulation")] +internal static class PbInstantiatePatch +{ + [HarmonyTranspiler] + public static List UpdateBeforeSimulationTranspiler(IEnumerable instructions) + { + var list = instructions.ToList(); + + var index = list.FindIndex(b => b.opcode == OpCodes.Brfalse); + + //get second brfase + index = list.FindIndex(index, b => b.opcode == OpCodes.Brfalse); + + var jump = new CodeInstruction(list[index]) + { + opcode = OpCodes.Brtrue + }; + + index++; + + list.Insert(index++, new CodeInstruction(OpCodes.Ldarg_0)); + list.Insert(index++, CodeInstruction.CallClosure(PveMethod)); + list.Insert(index, jump); + + return list; + } + + //IMPORTANT: if you reference CompilingPbs in the transpiler, ModScriptCompilerPatch will cause static init of MyScriptWhitelist, crashing the game + private static bool PveMethod(MyProgrammableBlock block) => ModScriptCompilerPatch.CompilingPbs.Contains(block); +}