Limiting players on server

How to limit connections and correctly reject someone on OnServerConnect:

    //Register the connection rejection
    public override void OnStartClient(NetworkClient client) {
        base.OnStartClient(client);
        client.RegisterHandler(Messages.ServerFull, ClServerFull);
    }

    /*
     * SERVER
     */

    /// <summary>
    /// Send this to reject a connection from the server in case of server full.
    /// </summary>
    /// <param name="conn"></param>
    /// <returns></returns>
    IEnumerator RejectConnection(NetworkConnection conn) {
        yield return new WaitForEndOfFrame();//Must wait one frame (Unity known bug)
        conn.Send(Messages.ServerFull, new EmptyMessage());
    }

    // called when a client connects
    public override void OnServerConnect(NetworkConnection conn) {
        //Reject player if max
        if(GetPlayerControllers().Count >= maxPlayers) {
            StartCoroutine(RejectConnection(conn));
            return;
        }
    }

==============Original post bellow==============
Hello there.
I was going to implement max players for my game server thinling something like this would, not only be straightforward, but also would be already in UNET api. Still I’m struggling.
Using,

public virtual NetworkClient StartHost(ConnectionConfig config, int maxConnections);

from the NetworkManager implementation, just causes no clients to be able to connect throwing CRC mismatches.

After trying that, I decided to try to reject connections overriding this:

public override void OnServerConnect(NetworkConnection conn) {
        if(NetworkServer.connections.Count >= maxPlayers) {
            conn.Disconnect();
            conn.Dispose();
            NetworkServer.DestroyPlayersForConnection(conn);
        }
    }

I have tried many variants of that sequence: ‘disconnect dispose destroy’. All of them just throw several errors on the host and the client sometimes goes back to the menu, or sometimes just freezes.

Seems like some people already asked here how to do this but got no useful answers:

(the above is not my case since I want to reject the connection before the player prefab is created)

If I understand your issue correctly then what you want to do is use NetworkManager.maxConnections = playerLimit before starting your server?

Doing that was giving me the CRC mismatches I talked about.

Doing

NetworkManager.singleton.maxConnections = ((int)maxPlayersSlider.value) - 1;
NetworkManager.singleton.StartHost();

Did limit the number of connections correctly. No CRC mismatch.
The problem I now face is… how the client knows he is beeing rejected? The server is not sending any messages. The client just stays there trying to connect until it timeouts…

Also why there is no documentation explaining exactly what happens on those calls?
The official documentation just says ‘Disconnects’. Nothing about how that is handled anywhere.

Also, also… is there somewhere a source or at least some inners of the NW manager code? I really would like to write my own but I want to still be compliant to the HLAPI. The only doc I found for this is: https://docs.unity3d.com/Manual/UNetUsingTransport.html
Though it is not enough since I don’t know exactly how the HLAPI handles those messages…

Ops!
Found it!
https://bitbucket.org/Unity-Technologies/networking/src/78ca8544bbf4e87c310ce2a9a3fc33cdad2f9bb1/Runtime/NetworkManager.cs?at=5.3&fileviewer=file-view-default

Okay! I just read through this classes:
https://bitbucket.org/Unity-Technologies/networking/src/78ca8544bbf4e87c310ce2a9a3fc33cdad2f9bb1/Runtime/NetworkServer.cs?at=5.3&fileviewer=file-view-default

https://bitbucket.org/Unity-Technologies/networking/src/78ca8544bbf4e87c310ce2a9a3fc33cdad2f9bb1/Runtime/NetworkServer.cs?at=5.3&fileviewer=file-view-default
Seems like there is no method (or functionality, or message?) there exposing neither connection rejections nor something to kick players from the server.

There may be something inside

ServerSimpleWrapper m_SimpleServerSimple;

But I can’t read that.
This
https://bitbucket.org/Unity-Technologies/networking/src/78ca8544bbf4e87c310ce2a9a3fc33cdad2f9bb1/Runtime/NetworkServerSimple.cs?at=5.3&fileviewer=file-view-default
Doesn’t help.

So I still don’t have an official way of kicking players from the server nor properly rejecting connections.

What I think the API is lacking?

  • Kick players
  • Store a ‘owner unique id’ for each object even the dummy client ones
  • Reject connections with status

How to solve those currently?
@gintautass

@gintautass
Can you have a look at this please? Or ask someone? I have done a through search without any results.

  • Kick players
    NetworkConnection.Disconnect()

  • Store a ‘owner unique id’ for each object even the dummy client ones
    Not sure what do you mean by that. Currently, every object with NetworkIdentity has their own id(NetworkIdentity.netId) and you can find them by using NetworkServer/ClientScene.FindLocalObject(netId);

  • Reject connections with status
    Has been added to the ToDo list

  • All of them just throw several errors on the host and the client sometimes goes back to the menu

Currently, there is a bug where if you try to disconnect a player in OnServerConnect you get those errors you mentioned. You can work around it by disconnecting them after one frame has passed.

1 Like

Thanks! I’ll work around that.

By owner unique id I just mean that objects should know who owns them. This is a good practice. Store on the manager os somewhere in the system an ID that relates objects to their authority (server or any of the clients). The only ID currently is this NetId that is unique to each object but don’t relate the object to who owns it (not on the clients).

This would be a good practice more for player controllers than anything else. Most of the NW stuff we do is server side, but some client side things (mainly stuff that reads information from the server) like keeping a scoreboard, currently rely on hacking knowledge from connections retrieving this information each time an event occurs. Instead, when the client connects it already receives player objects. It could know those are controllers and just read that.

Still, thanks! You solved many of my problems.

1 Like