views:

660

answers:

3

What kind of newbie mistakes you've seen and what are the cures?

One which occurs again and again is client is not checked any way against server.

For example:

  • User decompiles flash game source or listens to network traffic and sees where high score data is going and sends bogus high scores there not even playing the game.
  • User uses trainer and gets item which may even not appear in current level. This sent to server like "client X got item Y" and server just accepts that.

The simple cure is of course handling gaming client only as API to the server. Then user can use trainers and other memory manipulations as much they like but server just says you can't do it. Think server as a database where you can query things with game rules on top of it.

For example

  • Client: starts game
  • Client: connects to server
  • Client: queries amount of available money from server
  • User: enables trainer which sets money to infinite
  • Client: server.buyItem('very expensive')
  • Server: Checks gamestate (user can buy things now). Checks player[0].money -> no bonus.
  • Client: server.buyItem('can get this')
  • Server: Checks gamestate (user can buy things now). Checks player[0].money, ok. player[0].items.add('can get this') which will reduce it's cost from player[0].money. Then inform client send(player[0], 'items', 'can get this'); send(player[0], 'money', player[0].money).

The other way is to record client's movements and send that to highscore server where server plays it. Of course this can lead to that that record is very big.

+6  A: 

Without a doubt, blind trust of the client. In a game I'm working on, we now keep all "business logic" server-side, and have the client machines only send us what commands they are making; for instance "Player B wants to move right" - but the server calculates just how far to the right they moved. This has a performance overhead (and of course issues with lagging which could be handled better), so a possible middle-ground could be to do the heavy calculations client-side, and still have checks in place on the server; for instance checking whether the client's player is moving more than is supposedly possible in the time between updates; i.e. if the max player speed is 200 units/second, if you get an update after 0.5 seconds saying that they moved 150 units, boot them.

Of course, this doesn't necessarily stop someone from coding a bot to send those key presses, so there are other ways to guard against this. Still, having no validation at all is very much a newbie mistake (which admittedly I was guilty of when I took shortcuts)

Smashery
+1 - better said than my answer. =) One way to handle your example of pure server-side player movement is through client-side prediction code, though that is tough to nail properly.
Erik Forbes
Client-side prediction code, hey? Can't say I've heard of it. Have you a link to an explanation perchance? I am intrigued =)
Smashery
It's called interpolation, and it's used by pretty much all modern FPS engines. (It's adjustable in the Source engine via cl_interp, for example.)
strager
+1  A: 

You guys have pretty much covered all that can go wrong with server trusting clients. There are no other real issues I can think of.

So instead of telling you what can go wrong, look at what can go right.

Valve has put a lot of work into their netcode. Read it up

Pyrolistical
Actually, Valve are one of the main culprits for 'trusting the client'. A player who is in cover according to the server and observers can still be shot by another player if he's visible on that player's client. Valve prefer this for their games, but it's not a universally good solution.
Kylotan
Uhh, nope. The server has the final say in all cases. If what you say it true, then it would be possible to create a hack to kill people without ever seeing them.
Pyrolistical
The server has the final say, but it relies on 'rewinding time' based on estimates of lag which can ultimately be manipulated by the client. This gives a better feel to the shooter at the expense of consistency. (http://developer.valvesoftware.com/wiki/Lag_Compensation)
Kylotan
rewinding of time is still done on the server, so while you could receive damage from around the corner, that's because the server as calculated that the client did hit you in the past. Its not manipulable by the client, this is to reduce lag, not trust the client
Pyrolistical
And while its true clients can induce lag to make this bullets around corners effect more apparent, it doesn't give them any advantage to do so. they could have just sent the same information earlier and killed the player faster.
Pyrolistical
+5  A: 

The approach Valve took (at least, at one point) was to have the clients and the server simulate the game independently. Then the server does the authoritative simulation and sends status updates to all of the clients to correct their mistakes/hacking attempts.

E.g. if you press the left arrow your character will move left immediately; there is no wait for the server to say 'OK'. But if it turns out you've hacked yourself through a wall, the next server update will make you appear right next to wall, as the server sees it as solid.

Similarly, if a client sees a character move forwards, it will assume it is going to continue moving forwards until the server comes back with an authoritative response.

This approach defeats hacking attempts as the server makes the main decisions (and performs sanity checks in the process of simulation), and also deals with lag as the clients make predictions until they get word from the server.

Another big mistake related to 'trusting the client' is thinking your network protocol cannot be faked. People tend to assume that if they send binary chunks to the server, that these binary chunks will never be reverse-engineered, and that nobody will attempt to mess with the data to see what happens. This has led to all sorts of problems.

rjh