Clientside to Serverside Communication - Best Practices?
10 replies, posted
I'm starting to get used to the clientside/serverside dynamic and as an infra engineer I'm very curious about the "best practices" regarding networking.
Here's a problem that I've run into - I spawn an entity, then I want to remove it after certain conditions are met.
Should I:
a) Do everything in shared.lua, tracking state on both server and client?
b) Track state on clientside and use the net library to send a message to server to tell me to remove the object once the condition has been met?
c) Do everything in init.lua, tracking state on only the server?
d) Something I haven't thought of
Usually it’s best to do everything on the server, because you have to assume any client can always run any Lua code they want.
This all of course depends on the hooks and functions you’re using. If one needs to be called on the client, then you’d need to do networking.
Would it ever be worth it to keep something on the clientside if it's CPU intensive?
Are trace calculations something we should do on the server or the client if I wanted to remove an object based on the result?
If you want to remove an object or do any destructive action like that, it's best to keep it on the server. A client could give you any trace at all, causing it to hit other players or other props, meaning they can use it to remove whatever they want. This would be an exploit.
That doesn't create an exploit. That's like saying you shouldn't use admin mods because any client can type !ban. Just because you type !ban doesn't mean the server is going to allow you to ban someone. The client can give you any name at all, except it doesn't matter, because the server verifies that they are allowed to ban people, and also whether they are allowed to ban that person specifically. How is deleting a prop any different?
What you should do depends on the type of conditions you want to be met.
For example if you want the entity to be removed when the player looks at it then I would say the code should definitely run on the client and send the message to the server.
And if you want to be sure only Admins could look at it and remove this entity then the "if ply:Admin" statement should be server side for security purposes.
"best practices":
a) If you can do it only in one of them and don't need them to be shared then don't. Probably most of the code would be server sided only.
b) Carefull with exploits but yea this works
c) If you can, sure
It all depends on what you want to accomplish and the conditions you want to be met...
As a followup - let's say I have a SENT that needs to be removed.
Would it be appropriate to send a message with the SENT's EntIndex and have the server remove that?
It would if you do the appropriate security checks server side.
If you let a normal user (like me) remove any ENT by it's EntIndex I could start deleting every single ent from the game, including players if you do not make the conditions you need to do server side, for exemple is ent:IsPlayer() then don't delete it.
I see what you mean. I was thinking of it more as a weapon trace, for example. Every player has the ability to fire a weapon, but the weapons are supposed to only shoot from the player's position, in the direction they are facing. If a client could manipulate the position and direction of their weapon and then send that data to the server, you could end up with fake data sent by hackers to target players across the map. Instead of relying on the player sending correct information regarding their position and orientation, you could just get this on the server and perform the trace from there.
I understand if this is referring to a remove command, in that case, sorry, I got confused.