Skip to content

Commit 34e90bd

Browse files
committed
Resolve conflict with other plugin frameworks when hooking ProcessUserCmds
Delay detouring ProcessUserCmds until after other plugin/frameworks have had a chance to hook it, such as CS2Fixes. If some other plugin hooked it, then use a fallback input method. This fallback method is subpar in that: - It does not prevent weapon switching when number keys bound - It does not freeze the player in place when using WASD input As it stands, just delaying hooking results in a successful hook by CS# too, so this may let both work together. In any case, if the signature is not found then the fallback method is selected, and is sufficient Fixes #12
1 parent 3aae84c commit 34e90bd

1 file changed

Lines changed: 63 additions & 4 deletions

File tree

src/SharpModMenu/SharpModMenu.cs

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,26 @@ public sealed class SharpModMenuPlugin : BasePlugin
3333
? "48 8B C4 44 88 48 20 44 89 40 18 48 89 50 10 53"
3434
: "55 48 89 E5 41 57 41 56 41 89 D6 41 55 41 54 49 89 FC 53 48 83 EC 38";
3535
// void* FASTCALL ProcessUsercmds(CCSPlayerController* player, CUserCmdPB* cmds, int cmdCount, bool paused, float margin);
36-
private static MemoryFunctionVoid<nint, nint, int, bool, float, nint> ProcessUserCmdsFunc { get; } = new(ProcessUserCmdsSig, Addresses.ServerPath);
36+
private static MemoryFunctionWithReturn<nint, nint, int, bool, float, nint, nint>? ProcessUserCmdsFunc { get; set; }
37+
private bool UseFallbackWasdInputMethod { get; set; } = false;
3738

3839
public override void Load(bool hotReload)
3940
{
4041
DriverInstance = new();
4142

42-
ProcessUserCmdsFunc.Hook(ProcessUserCmds, HookMode.Pre);
43+
// delay hooking ProcessUserCmds until CS2Fixes et al have had a chance to hook it
44+
Server.NextWorldUpdate(() =>
45+
{
46+
ProcessUserCmdsFunc ??= new(ProcessUserCmdsSig, Addresses.ServerPath);
47+
if (ProcessUserCmdsFunc.Handle == nint.Zero)
48+
{
49+
Console.WriteLine($"SharpModMenu: Failed to hook ProcessUserCmds, using subpar fallback method");
50+
UseFallbackWasdInputMethod = true;
51+
return;
52+
}
53+
54+
ProcessUserCmdsFunc.Hook(ProcessUserCmds, HookMode.Pre);
55+
});
4356

4457
UniversalMenu.RegisterDriver("SharpModMenu", DriverInstance);
4558

@@ -51,12 +64,58 @@ public override void Unload(bool hotReload)
5164
{
5265
UniversalMenu.UnregisterDriver("SharpModMenu");
5366

54-
ProcessUserCmdsFunc.Unhook(ProcessUserCmds, HookMode.Pre);
67+
ProcessUserCmdsFunc?.Unhook(ProcessUserCmds, HookMode.Pre);
5568
}
5669

5770
private void OnTick()
5871
{
59-
for(int i = 0; i < DriverInstance!.ActiveMenuStates.Count; i++)
72+
if (UseFallbackWasdInputMethod)
73+
{
74+
for (int i = 0; i < DriverInstance!.ActiveMenuStates.Count; i++)
75+
{
76+
var menuState = DriverInstance!.ActiveMenuStates[i];
77+
if (!menuState.Player.IsValid)
78+
continue;
79+
80+
if (!menuState.IsUsingKeybinds)
81+
{
82+
var buttons = menuState.Player.Buttons;
83+
84+
bool pressingForward = buttons.HasFlag(PlayerButtons.Forward);
85+
bool pressingBack = buttons.HasFlag(PlayerButtons.Back);
86+
bool pressingLeft = buttons.HasFlag(PlayerButtons.Left);
87+
bool pressingRight = buttons.HasFlag(PlayerButtons.Right);
88+
bool pressingUse = buttons.HasFlag(PlayerButtons.Use);
89+
bool pressingTab = buttons.HasFlag((PlayerButtons)0x200000000);
90+
bool pressingReload = buttons.HasFlag(PlayerButtons.Reload);
91+
92+
if (pressingForward && pressingForward != menuState.WasPressingForward)
93+
menuState.HandleInput(PlayerKey.Up, false);
94+
if (pressingBack && pressingBack != menuState.WasPressingBack)
95+
menuState.HandleInput(PlayerKey.Down, false);
96+
if (pressingLeft && pressingLeft != menuState.WasPressingLeft)
97+
menuState.HandleInput(PlayerKey.Left, false);
98+
if (pressingRight && pressingRight != menuState.WasPressingRight)
99+
menuState.HandleInput(PlayerKey.Right, false);
100+
if (pressingUse && pressingUse != menuState.WasPressingUse)
101+
menuState.HandleInput(PlayerKey.Select, false);
102+
if (pressingTab && pressingTab != menuState.WasPressingTab)
103+
menuState.HandleInput(PlayerKey.ToggleFocus, false);
104+
if (pressingReload && pressingReload != menuState.WasPressingReload)
105+
menuState.HandleInput(PlayerKey.Close, false);
106+
107+
menuState.WasPressingForward = pressingForward;
108+
menuState.WasPressingBack = pressingBack;
109+
menuState.WasPressingLeft = pressingLeft;
110+
menuState.WasPressingRight = pressingRight;
111+
menuState.WasPressingUse = pressingUse;
112+
menuState.WasPressingTab = pressingTab;
113+
menuState.WasPressingReload = pressingReload;
114+
}
115+
}
116+
}
117+
118+
for (int i = 0; i < DriverInstance!.ActiveMenuStates.Count; i++)
60119
DriverInstance!.ActiveMenuStates[i].Tick();
61120
}
62121

0 commit comments

Comments
 (0)