colyseus / colyseus

⚔ Multiplayer Framework for Node.js

Home Page:https://colyseus.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Bug]: maxClients not (fully) respected

hunkydoryrepair opened this issue · comments

Context

We had 1500 players in one room, when maxClients was set to 1000. With so many clients, they are constantly leaving and entering.

Bug description

maxClients is not strictly enforced.

There is a small window for a flaw, allowing more clients to connect to a room than strictly allowed.
I believe this sequence is due to the await onAsync call in _onJoin.
Note: the reservedSeat is cleared before await onAsync is called, and the client is added to the this.clients only AFTER onAsync is called. This leaves a brief moment (however long onAsync takes) where the client count is off by 1 when hasReachedMaxClients is called.

I notice that reserveSeat is also deleted in the finally clause later. Since it is deleted above, this should never do anything, but perhaps the intention was to delete it only after the client is added to the clients.

Some other aspects that may exacerbate this:

  • when a client leaves, there is no check for hasReachedMaxClients, so room will be unlocked even if maxclients exceeds count. This will only make the room appear available when it really is not.
  • _reserveSeat doesn't check if room is locked. Since the room is not unlocked in the "gap" discussed, if the room was actually locked and CHECKED then _reserveSeat would not allow more clients, even though the count is < max. When requests are sent from multiple servers at once, even though the first one may lock the room, the subsequent ones may still go through and the previous requests are causing room count to drop below the max.

Reproduction

No response

Steps to reproduce

  1. use async onAuth that takes a long time to complete (30 seconds +)
  2. set maxClients to a low number on the room (2)
  3. sequentially add clients, pausing briefly between each (long enough to enter onAuth). Each client will enter onAuth and wait, and the room count (as calculated in hasReachedMaxClients) will be 0, allowing another client to start the process without locking the room.

Environment & Versions

Colyseus: 0.15.15

I think proper fix would be to only remove reservedSeat AFTER client is added to clients array, in the finally for the non-reconnection case, and just after the add for the reconnection case.

Thank you for reporting and for the suggestion @hunkydoryrepair, it turns out the first delete operation was there by mistake - as it is already deleted on the other final code branches (reconnection at cleanup, and at the finally block)

turns out other tests are failing after this, pls don't upgrade, I'm on it 🥵

properly fixed now on @colyseus/core version 0.15.22 🙌