public void ProcessHandshakeRequest(TPeer source, ref PacketReader reader) { //Parse packet string name; CodecSettings codecSettings; reader.ReadHandshakeRequest(out name, out codecSettings); // Validate that we have a player name, and ignore if not if (name == null) { Log.Warn("Ignoring a handshake with a null player name"); return; } // Check if this client is already in the session but with a different connection to the current one. // We'll assume name collisions never happen, so this is probably a client reconnecting before the server has cleaned up after a very recent disconnection ClientInfo <TPeer> currentInfoByName; ClientInfo <TPeer> currentInfoByConn; if (TryGetClientInfoByName(name, out currentInfoByName) | TryFindClientByConnection(source, out currentInfoByConn)) { //We got the client by name and by current connection. If they are different then the client is in the session with a different connection if (!EqualityComparer <ClientInfo <TPeer> > .Default.Equals(currentInfoByName, currentInfoByConn)) { //Remove clients who were already connected if (currentInfoByConn != null && currentInfoByConn.IsConnected) { RemoveClient(currentInfoByConn); } if (currentInfoByName != null && currentInfoByName.IsConnected) { RemoveClient(currentInfoByName); } Log.Debug("Client '{0}' handshake received but client is already connected! Disconnecting client '{1}' & '{2}', connecting '{3}'", name, currentInfoByConn, currentInfoByName, source ); } } //Get or register the ID for this client var id = PlayerIds.GetId(name) ?? PlayerIds.Register(name); var info = GetOrCreateClientInfo(id, name, codecSettings, source); //Send back handshake response _tmpClientBufferHandshake.Clear(); GetClients(_tmpClientBufferHandshake); var writer = new PacketWriter(_tmpSendBuffer); writer.WriteHandshakeResponse(_server.SessionId, info.PlayerId, _tmpClientBufferHandshake, ClientsInRooms.ByName); _server.SendReliable(source, writer.Written); }
public void ProcessHandshakeRequest(TPeer source, ref PacketReader reader) { //Parse packet string name; CodecSettings codecSettings; reader.ReadHandshakeRequest(out name, out codecSettings); // Validate that we have a player name, and ignore if not if (name == null) { Log.Warn("Ignoring a handshake with a null player name"); return; } // Check if this client is already in the session but with a different connection to the current one. // We'll assume name collisions never happen, so this is probably a client reconnecting before the server has cleaned up after a very recent disconnection ClientInfo <TPeer> currentInfoByName; ClientInfo <TPeer> currentInfoByConn; if (TryGetClientInfoByName(name, out currentInfoByName) | TryFindClientByConnection(source, out currentInfoByConn)) { //We got the client by name and by current connection. If they are different then the client is in the session with a different connection if (!EqualityComparer <ClientInfo <TPeer> > .Default.Equals(currentInfoByName, currentInfoByConn)) { //Remove clients who were already connected if (currentInfoByConn != null && currentInfoByConn.IsConnected) { RemoveClient(currentInfoByConn); } if (currentInfoByName != null && currentInfoByName.IsConnected) { RemoveClient(currentInfoByName); } Log.Debug("Client '{0}' handshake received but client is already connected! Disconnecting client '{1}' & '{2}', connecting '{3}'", name, currentInfoByConn, currentInfoByName, source ); } } //Get or register the ID for this client var id = PlayerIds.GetId(name) ?? PlayerIds.Register(name); var info = GetOrCreateClientInfo(id, name, codecSettings, source); // Send the handshake response - but with _no_ clients in the list, as if the session has no one in it. The handshake packet previously listed everyone in the session and what rooms they're in. However, // this could cause the packet to become very large and eventually it would overflow a buffers. Rather than expand all the buffers (which could break network integrations) we're not going to send any of // that data in the handshake (as if it's an empty session) and then we'll immediately send all the client data in separate packets. var writer = new PacketWriter(_tmpSendBuffer); _tmpClientBufferHandshake.Clear(); writer.WriteHandshakeResponse(_server.SessionId, info.PlayerId, _tmpClientBufferHandshake, _tmpClientByRoomsBufferHandshake); _server.SendReliable(source, writer.Written); //Send individual client state messages for all clients in the session GetClients(_tmpClientBufferHandshake); for (var i = 0; i < _tmpClientBufferHandshake.Count; i++) { SendFakeClientState(source, _tmpClientBufferHandshake[i]); } }