Detecting Keypress Client-side and sending to server

I’m trying to detect when the ‘F’ key is pressed / released by a client and have this information available server-side.

I’m guessing I need to do something with input.IsKeyDown and net it to the server, but there isn’t a input.IsKeyReleased so I don’t seem to be able to stop the message sending every tick.

Does anyone have any efficient suggestions - or any suggestions :slight_smile:

I feel like you shouldn’t have to use the net library, since GM:KeyPress and GM:KeyRelease are available on both the client and server-side… unless you’re trying to send client-side variables to the server when F is pressed, then yes you would use the net library.

KeyPress and KeyRelease only let you detect IN_ENUMS ( as in keys like ATTACK and RELOAD ) - not a specific key - these may change depending on the bind the player has for that event. Plus it limits the amount of binds that can be used.

I’m looking for a way to detect when a KEY_ Enums is pressed and handle it server-side.

Then yes, using IsKeyDown will require you to send variables to the server-side using net.Start (which you send with net.SendToServer). On the server-side, you should then have a net.Receive (same name as net.Start), which will receive anything sent in the order it was sent. Be sure to add the network string to the server, or it wont work.

I think you have mis-understood my question. I know how to use the net library, and I know how to use IsKeyDown - using the KeyPress hook **is not ** an option as it only lets to detect key binds like ATTACK, ATTACK2, RELOAD, SPRINT, JUMP etc. so my only option it seems is to use input.IsKeyDown and send it to the server-side.

My question is how to do this efficiently, as if I detected that in a THINK hook or while loop, it would send every tick, and I can’t check if the key is released to allow it to send again as there’s no input.IsKeyReleased.

Yeah, using a think hook would be the best way to go. And you can technically make an input.IsKeyReleased by inverting input.IsKeyDown (!input.IsKeyDown).

Damn it, I think at 4.30am my brain is finally dying. The opposite of IsKeyDown is not IsKeyReleased :stuck_out_tongue: that doesn’t even make sense.

Thanks a lot - all working now.

To avoid the networking entirely (in Lua, that is), you could use

GM:PlayerButtonDown with the BUTTON enumerations. Example:

hook.Add("PlayerButtonDown", "BlaBlaYourIdentifierHere", function(pl, btn)
    if btn == KEY_F then
        -- bla

do you know if this is predicted or not?

WTF - wow thanks. PlayerButtonDown description was a little vague but I should have tested.

Thanks a lot.

EDIT: Oh no, not vague, I just wasn’t reading: "Encompasses the range of KEY_ Enums , MOUSE_ Enums and JOYSTICK_ Enums, "

It is on the

Predicted Hooks page. As far as I know, it is a predicted hook.

One question: is there a good reason why you don’t want to use binds? It’s important to remember that not everyone uses the same keyboard layout, most prominently international players, and so hard-coding a certain action to a specific key is in most cases a bad idea. If there’s a relevant bind that you could use instead (flashlight?), I think you should use that.

But if you really do HAVE to have F be the key, then it sounds like PlayerButtonDown/Up are the hooks for you :slight_smile:

That is a good point, however I need more binds then is possible. There’s only USE, FLASHLIGHT, ATTACK, ATTACK2, RELOAD possible SCORE, plus there’s no logical positioning usually. I’ll make a way for the player to rebind possible.

I was going to say you might want to use the numpad library (which has for a long time been mapped to the whole keyboard)… But it’s a total mess. Best to stick with PlayerButtonDown/Up :slight_smile:

use a bool, set it to false before running the tick hook, then set it to true and send the message, make a timer.simple in the tick that resets the bool to false every X seconds so it can be pressed again.

I managed to do it in the end, but ButtonDown/Up is a better option for me. Thanks.