Beispiel #1
0
        private void SetupClient(BMSByte packet, string incomingEndpoint, IPEndPoint groupEP)
        {
            // Check for a local listing request
            if (packet.Size.Between(2, 4) && packet[0] == BROADCAST_LISTING_REQUEST_1 && packet[1] == BROADCAST_LISTING_REQUEST_2 && packet[2] == BROADCAST_LISTING_REQUEST_3)
            {
                // Don't reply if the server is not currently accepting connections
                if (!AcceptingConnections)
                {
                    return;
                }

                // This may be a local listing request so respond with the server flag byte
                Client.Send(new byte[] { SERVER_BROADCAST_CODE }, 1, groupEP);
                return;
            }

            if (Players.Count == MaxConnections)
            {
                // Tell the client why they are being disconnected
                Send(Error.CreateErrorMessage(Time.Timestep, "Max Players Reached On Server", false, MessageGroupIds.MAX_CONNECTIONS, true));

                // Send the close connection frame to the client
                Send(new ConnectionClose(Time.Timestep, false, Receivers.Target, MessageGroupIds.DISCONNECT, false));

                return;
            }
            else if (!AcceptingConnections)
            {
                // Tell the client why they are being disconnected
                Send(Error.CreateErrorMessage(Time.Timestep, "The server is busy and not accepting connections", false, MessageGroupIds.MAX_CONNECTIONS, true));

                // Send the close connection frame to the client
                Send(new ConnectionClose(Time.Timestep, false, Receivers.Target, MessageGroupIds.DISCONNECT, false));

                return;
            }

            // Validate that the connection headers are properly formatted
            byte[] response = Websockets.ValidateConnectionHeader(packet.CompressBytes());

            // The response will be null if the header sent is invalid, if so then disconnect client as they are sending invalid headers
            if (response == null)
            {
                return;
            }

            UDPNetworkingPlayer player = new UDPNetworkingPlayer(ServerPlayerCounter++, incomingEndpoint, false, groupEP, this);

            // If all is in order then send the validated response to the client
            Client.Send(response, response.Length, groupEP);

            OnPlayerConnected(player);
            udpPlayers.Add(incomingEndpoint, player);

            // The player has successfully connected
            player.Connected = true;
        }
Beispiel #2
0
        private void SetupClient(BMSByte packet, CSteamID steamId)
        {
            if (Players.Count == MaxConnections)
            {
                // Tell the client why they are being disconnected
                Send(Error.CreateErrorMessage(Time.Timestep, "Max Players Reached On Server", false, MessageGroupIds.MAX_CONNECTIONS, true));

                // Send the close connection frame to the client
                Send(new ConnectionClose(Time.Timestep, false, Receivers.Target, MessageGroupIds.DISCONNECT, false));

                return;
            }
            else if (!AcceptingConnections)
            {
                // Tell the client why they are being disconnected
                Send(Error.CreateErrorMessage(Time.Timestep, "The server is busy and not accepting connections", false, MessageGroupIds.MAX_CONNECTIONS, true));

                // Send the close connection frame to the client
                Send(new ConnectionClose(Time.Timestep, false, Receivers.Target, MessageGroupIds.DISCONNECT, false));

                return;
            }

            // Validate that the connection headers are properly formatted
            byte[] response = Websockets.ValidateConnectionHeader(packet.CompressBytes());

            // The response will be null if the header sent is invalid, if so then disconnect client as they are sending invalid headers
            if (response == null)
            {
                return;
            }

            SteamNetworkingPlayer player = new SteamNetworkingPlayer(ServerPlayerCounter++, steamId, false, this);

            // If all is in order then send the validated response to the client
            Client.Send(response, response.Length, steamId);

            OnPlayerConnected(player);
            steamPlayers.Add(steamId, player);

            // The player has successfully connected
            player.Connected = true;
        }
Beispiel #3
0
        private void HandleClientAcceptance(BMSByte packet, string incomingEndpoint, IPEndPoint groupEP)
        {
            // Validate that the connection headers are properly formatted
            byte[] response = Websockets.ValidateConnectionHeader(packet.CompressBytes());

            // The response will be null if the header sent is invalid, if so then disconnect client as they are sending invalid headers
            if (response == null)
            {
                return;
            }

            var player = new UDPNetworkingPlayer(ServerPlayerCounter++, incomingEndpoint,
                                                 false, groupEP, this);

            // If all is in order then send the validated response to the client
            Client.Send(response, response.Length, groupEP);

            OnPlayerConnected(player);
            udpPlayers.Add(incomingEndpoint, player);

            // The player has successfully connected
            player.Connected = true;
        }
Beispiel #4
0
        /// <summary>
        /// Infinite loop listening for new data from all connected clients on a separate thread.
        /// This loop breaks when readThreadCancel is set to true
        /// </summary>
        /// <summary>
        ///无限循环在单独的线程上监听来自所有连接客户端的新数据。
        ///当readThreadCancel设置为true时,此循环中断
        /// </ summary>
        private void ReadClients()
        {
            IPEndPoint groupEP          = new IPEndPoint(IPAddress.Any, 0);
            string     incomingEndpoint = string.Empty;

            BMSByte packet = null;

            // 故意无限循环
            // Intentional infinite loop
            while (IsBound)
            {
                //如果读取已被标记为取消,则从此循环中断开
                // If the read has been flagged to be canceled then break from this loop
                if (readThreadCancel)
                {
                    return;
                }

                try
                {
                    //从网络读取数据包
                    // Read a packet from the network
                    packet = Client.Receive(ref groupEP, ref incomingEndpoint);

                    // 模拟丢包
                    if (PacketLossSimulation > 0.0f && new Random().NextDouble() <= PacketLossSimulation)
                    {
                        // 丢掉这个消息
                        // Skip this message
                        continue;
                    }
                    // 统计 宽带接收数据大小
                    BandwidthIn += (ulong)packet.Size;
                }
                catch
                {
                    // 如果出错, 就查找该IP PROT的玩家,将该玩家踢掉
                    UDPNetworkingPlayer player;
                    if (udpPlayers.TryGetValue(incomingEndpoint, out player))
                    {
                        FinalizeRemovePlayer(player, true);
                    }

                    continue;
                }

                //检查以确保收到消息
                // Check to make sure a message was received
                if (packet == null || packet.Size <= 0)
                {
                    continue;
                }

                //如果玩家列表里不包含该包的发送者
                if (!udpPlayers.ContainsKey(incomingEndpoint))
                {
                    // 创建该发送者的结构体保存 UDPNetworkingPlayer
                    SetupClient(packet, incomingEndpoint, groupEP);
                    continue;
                }
                else
                {
                    currentReadingPlayer = udpPlayers[incomingEndpoint];

                    if (!currentReadingPlayer.Accepted && !currentReadingPlayer.PendingAccepted)
                    {
                        //响应验证可能会被丢弃
                        //检查客户端是否正在重新发送响应
                        // It is possible that the response validation was dropped so
                        // check if the client is resending for a response
                        byte[] response = Websockets.ValidateConnectionHeader(packet.CompressBytes());

                        //客户端再次发送连接请求
                        // The client has sent the connection request again
                        if (response != null)
                        {
                            Client.Send(response, response.Length, groupEP);
                            continue;
                        }
                        else
                        {
                            // 将该玩家设置为等待接受确认
                            currentReadingPlayer.PendingAccepted = true;
                            // 读取该玩家发来的数据包
                            ReadPacket(packet);
                        }
                    }
                    else
                    {
                        //由于Forge网络协议,数据包唯一的时间1
                        //将是71,第二个数据包是69是强制断开连接
                        // Due to the Forge Networking protocol, the only time that packet 1
                        // will be 71 and the second packet be 69 is a forced disconnect reconnect
                        if (packet[0] == 71 && packet[1] == 69)
                        {
                            udpPlayers.Remove(currentReadingPlayer.Ip + "+" + currentReadingPlayer.Port);
                            FinalizeRemovePlayer(currentReadingPlayer, true);
                            continue;
                        }

                        // 设置玩家最好ping时间
                        currentReadingPlayer.Ping();
                        // 读取该玩家发来的数据包
                        ReadPacket(packet);
                    }
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Infinite loop listening for new data from all connected clients on a separate thread.
        /// This loop breaks when readThreadCancel is set to true
        /// </summary>
        private void ReadClients()
        {
            CSteamID messageFrom = default(CSteamID);

            BMSByte packet = null;

            // Intentional infinite loop
            while (IsBound)
            {
                // If the read has been flagged to be canceled then break from this loop
                if (readThreadCancel)
                {
                    return;
                }

                try
                {
                    // Read a packet from the network
                    uint msgSize = 0;

                    if (SteamNetworking.IsP2PPacketAvailable(out msgSize))
                    {
                        packet = Client.Receive(msgSize, out messageFrom);
                    }
                    else
                    {
                        Thread.Sleep(1);
                        continue;
                    }

                    if (PacketLossSimulation > 0.0f && new Random().NextDouble() <= PacketLossSimulation)
                    {
                        // Skip this message
                        continue;
                    }

                    BandwidthIn += (ulong)packet.Size;
                }
                catch (Exception e)
                {
                    Logging.BMSLog.LogException(e);

                    SteamNetworkingPlayer player;
                    if (steamPlayers.TryGetValue(messageFrom, out player))
                    {
                        FinalizeRemovePlayer(player, true);
                    }

                    continue;
                }

                // Check to make sure a message was received
                if (packet == null || packet.Size <= 0)
                {
                    continue;
                }

                if (!steamPlayers.ContainsKey(messageFrom))
                {
                    SetupClient(packet, messageFrom);
                    continue;
                }
                else
                {
                    currentReadingPlayer = steamPlayers[messageFrom];

                    if (!currentReadingPlayer.Accepted && !currentReadingPlayer.PendingAccepted)
                    {
                        // It is possible that the response validation was dropped so
                        // check if the client is resending for a response
                        byte[] response = Websockets.ValidateConnectionHeader(packet.CompressBytes());

                        // The client has sent the connection request again
                        if (response != null)
                        {
                            Client.Send(response, response.Length, messageFrom, EP2PSend.k_EP2PSendReliable);
                            continue;
                        }
                        else
                        {
                            currentReadingPlayer.PendingAccepted = true;
                            ReadPacket(packet);
                        }
                    }
                    else
                    {
                        // Due to the Forge Networking protocol, the only time that packet 1
                        // will be 71 and the second packet be 69 is a forced disconnect reconnect
                        if (packet[0] == 71 && packet[1] == 69)
                        {
                            Logging.BMSLog.LogFormat("Received packet[0]=71 & packet[1]=69");
                            steamPlayers.Remove(messageFrom);
                            FinalizeRemovePlayer(currentReadingPlayer, true);
                            continue;
                        }

                        currentReadingPlayer.Ping();
                        ReadPacket(packet);
                    }
                }
            }
        }
        /// <summary>
        /// Infinite loop listening for new data from all connected clients on a separate thread.
        /// This loop breaks when readThreadCancel is set to true
        /// </summary>
        private void ReadClients()
        {
            // Intentional infinite loop
            while (IsBound && !NetWorker.EndingSession)
            {
                try
                {
                    // If the read has been flagged to be canceled then break from this loop
                    if (readThreadCancel)
                    {
                        return;
                    }

                    // This will loop through all of the players, so make sure to set the lock to
                    // prevent any changes from other threads
                    lock (Players)
                    {
                        for (int i = 0; i < Players.Count; i++)
                        {
                            // If the read has been flagged to be canceled then break from this loop
                            if (readThreadCancel)
                            {
                                return;
                            }

                            NetworkStream playerStream = null;

                            if (Players[i].IsHost)
                            {
                                continue;
                            }

                            try
                            {
                                lock (Players[i].MutexLock)
                                {
                                    // Try to get the client stream if it is still available
                                    playerStream = Players[i].TcpClientHandle.GetStream();
                                }
                            }
                            catch
                            {
                                // Failed to get the stream for the client so forcefully disconnect it
                                //Console.WriteLine("Exception: Failed to get stream for client (Forcefully disconnecting)");
                                Disconnect(Players[i], true);
                                continue;
                            }

                            // If the player is no longer connected, then make sure to disconnect it properly
                            if (!Players[i].TcpClientHandle.Connected)
                            {
                                Disconnect(Players[i], false);
                                continue;
                            }

                            // Only continue to read for this client if there is any data available for it
                            if (!playerStream.DataAvailable)
                            {
                                continue;
                            }

                            int available = Players[i].TcpClientHandle.Available;

                            // Determine if the player is fully connected
                            if (!Players[i].Accepted)
                            {
                                // Determine if the player has been accepted by the server
                                if (!Players[i].Connected)
                                {
                                    lock (Players[i].MutexLock)
                                    {
                                        // Read everything from the stream as the client hasn't been accepted yet
                                        byte[] bytes = new byte[available];
                                        playerStream.Read(bytes, 0, bytes.Length);

                                        // Validate that the connection headers are properly formatted
                                        byte[] response = Websockets.ValidateConnectionHeader(bytes);

                                        // The response will be null if the header sent is invalid, if so then disconnect client as they are sending invalid headers
                                        if (response == null)
                                        {
                                            OnPlayerRejected(Players[i]);
                                            Disconnect(Players[i], false);
                                            continue;
                                        }

                                        // If all is in order then send the validated response to the client
                                        playerStream.Write(response, 0, response.Length);

                                        // The player has successfully connected
                                        Players[i].Connected = true;
                                    }
                                }
                                else
                                {
                                    lock (Players[i].MutexLock)
                                    {
                                        // Consume the message even though it is not being used so that it is removed from the buffer
                                        Text frame = (Text)Factory.DecodeMessage(GetNextBytes(playerStream, available, true), true, MessageGroupIds.TCP_FIND_GROUP_ID, Players[i]);
                                        Players[i].InstanceGuid = frame.ToString();

                                        OnPlayerGuidAssigned(Players[i]);

                                        lock (writeBuffer)
                                        {
                                            writeBuffer.Clear();
                                            writeBuffer.Append(BitConverter.GetBytes(Players[i].NetworkId));
                                            Send(Players[i].TcpClientHandle, new Binary(Time.Timestep, false, writeBuffer, Receivers.Target, MessageGroupIds.NETWORK_ID_REQUEST, true));

                                            SendBuffer(Players[i]);

                                            // All systems go, the player has been accepted
                                            OnPlayerAccepted(Players[i]);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                try
                                {
                                    lock (Players[i].MutexLock)
                                    {
                                        Players[i].Ping();

                                        // Get the frame that was sent by the client, the client
                                        // does send masked data
                                        //TODO: THIS IS CAUSING ISSUES!!! WHY!?!?!!?
                                        FrameStream frame = Factory.DecodeMessage(GetNextBytes(playerStream, available, true), true, MessageGroupIds.TCP_FIND_GROUP_ID, Players[i]);

                                        // The client has told the server that it is disconnecting
                                        if (frame is ConnectionClose)
                                        {
                                            // Confirm the connection close
                                            Send(Players[i].TcpClientHandle, new ConnectionClose(Time.Timestep, false, Receivers.Target, MessageGroupIds.DISCONNECT, true));

                                            Disconnect(Players[i], false);
                                            continue;
                                        }

                                        FireRead(frame, Players[i]);
                                    }
                                }
                                catch
                                {
                                    // The player is sending invalid data so disconnect them
                                    Disconnect(Players[i], true);
                                }
                            }
                        }
                    }

                    // Go through all of the pending disconnections and clean them
                    // up and finalize the disconnection
                    CleanupDisconnections();

                    // Sleep so that we free up the CPU a bit from this thread
                    Thread.Sleep(10);
                }
                catch (Exception ex)
                {
                    Logging.BMSLog.LogException(ex);
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Infinite loop listening for new data from all connected clients on a separate thread.
        /// This loop breaks when readThreadCancel is set to true
        /// </summary>
        private void ReadClients()
        {
            IPEndPoint groupEP          = new IPEndPoint(IPAddress.Any, 0);
            string     incomingEndpoint = string.Empty;

            BMSByte packet = null;

            // Intentional infinite loop
            while (IsBound)
            {
                // If the read has been flagged to be canceled then break from this loop
                if (readThreadCancel)
                {
                    return;
                }

                try
                {
                    // Read a packet from the network
                    packet = Client.Receive(ref groupEP, ref incomingEndpoint);

                    if (PacketLossSimulation > 0.0f && new Random().NextDouble() <= PacketLossSimulation)
                    {
                        // Skip this message
                        continue;
                    }

                    BandwidthIn += (ulong)packet.Size;
                }
                catch
                {
                    UDPNetworkingPlayer player;
                    if (udpPlayers.TryGetValue(incomingEndpoint, out player))
                    {
                        FinalizeRemovePlayer(player, true);
                    }

                    continue;
                }

                // Check to make sure a message was received
                if (packet == null || packet.Size <= 0)
                {
                    continue;
                }

                if (!udpPlayers.ContainsKey(incomingEndpoint))
                {
                    SetupClient(packet, incomingEndpoint, groupEP);
                    continue;
                }
                else
                {
                    currentReadingPlayer = udpPlayers[incomingEndpoint];

                    if (!currentReadingPlayer.Accepted && !currentReadingPlayer.PendingAccepted)
                    {
                        // It is possible that the response validation was dropped so
                        // check if the client is resending for a response
                        byte[] response = Websockets.ValidateConnectionHeader(packet.CompressBytes());

                        // The client has sent the connection request again
                        if (response != null)
                        {
                            Client.Send(response, response.Length, groupEP);
                            continue;
                        }
                        else
                        {
                            currentReadingPlayer.PendingAccepted = true;
                            ReadPacket(packet);
                        }
                    }
                    else
                    {
                        // Due to the Forge Networking protocol, the only time that packet 1
                        // will be 71 and the second packet be 69 is a forced disconnect reconnect
                        if (packet[0] == 71 && packet[1] == 69)
                        {
                            udpPlayers.Remove(currentReadingPlayer.Ip + "+" + currentReadingPlayer.Port);
                            FinalizeRemovePlayer(currentReadingPlayer, true);
                            continue;
                        }

                        currentReadingPlayer.Ping();
                        ReadPacket(packet);
                    }
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Infinite loop listening for new data from all connected clients on a separate thread.
        /// This loop breaks when readThreadCancel is set to true
        /// </summary>
        private void ReadClients()
        {
            IPEndPoint groupEP          = new IPEndPoint(IPAddress.Any, 0);
            string     incomingEndpoint = string.Empty;

            BMSByte packet = null;

            // Intentional infinite loop
            while (IsBound)
            {
                // If the read has been flagged to be canceled then break from this loop
                if (readThreadCancel)
                {
                    return;
                }

                try
                {
                    // Read a packet from the network
                    packet = Client.Receive(ref groupEP, ref incomingEndpoint);
                    if (PacketLossSimulation > 0.0f && new Random().NextDouble() <= PacketLossSimulation)
                    {
                        // Skip this message
                        continue;
                    }

                    BandwidthIn += (ulong)packet.Size;
                }
                catch (Exception ex) when(!(ex is SocketException))
                {
                    Console.WriteLine($"Error in ReadClients() infinite loop, error was {ex.Message}");

                    UDPNetworkingPlayer player;

                    if (udpPlayers.TryGetValue(incomingEndpoint, out player))
                    {
                        Console.WriteLine($"Following the error, player '{player.NetworkId}' will be removed");
                        FinalizeRemovePlayer(player, true);
                    }

                    continue;
                }

                // Check to make sure a message was received
                if (packet == null || packet.Size <= 0)
                {
                    continue;
                }

                if (!udpPlayers.ContainsKey(incomingEndpoint))
                {
                    SetupClient(packet, incomingEndpoint, groupEP);
                    continue;
                }
                else
                {
                    currentReadingPlayer = udpPlayers[incomingEndpoint];

                    if (!currentReadingPlayer.Accepted && !currentReadingPlayer.PendingAccepted)
                    {
                        // It is possible that the response validation was dropped so
                        // check if the client is resending for a response
                        byte[] response = Websockets.ValidateConnectionHeader(packet.CompressBytes());

                        // The client has sent the connection request again
                        if (response != null)
                        {
                            Client.Send(response, response.Length, groupEP);
                            continue;
                        }
                        else
                        {
                            currentReadingPlayer.PendingAccepted = true;
                            ReadPacket(packet);
                        }
                    }
                    else
                    {
                        currentReadingPlayer.Ping();
                        ReadPacket(packet);
                    }
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Infinite loop listening for new data from all connected clients on a separate thread.
        /// This loop breaks when readThreadCancel is set to true
        /// </summary>
        private void ReadClients()
        {
            IPEndPoint groupEP          = new IPEndPoint(IPAddress.Any, 0);
            string     incomingEndpoint = string.Empty;

            BMSByte packet = null;

            // Intentional infinite loop
            while (IsBound)
            {
                // If the read has been flagged to be canceled then break from this loop
                if (readThreadCancel)
                {
                    return;
                }

                try
                {
                    // Read a packet from the network
                    packet = Client.Receive(ref groupEP, ref incomingEndpoint);

                    if (PacketLossSimulation > 0.0f && new Random().NextDouble() <= PacketLossSimulation)
                    {
                        // Skip this message
                        continue;
                    }

                    BandwidthIn += (ulong)packet.Size;
                }
                catch
                {
                    if (udpPlayers.ContainsKey(incomingEndpoint))
                    {
                        Disconnect(udpPlayers[incomingEndpoint], true);
                        CleanupDisconnections();
                    }

                    continue;
                }

                // Check to make sure a message was received
                if (packet == null || packet.Size <= 0)
                {
                    continue;
                }

                if (!udpPlayers.ContainsKey(incomingEndpoint))
                {
                    SetupClient(packet, incomingEndpoint, groupEP);
                    continue;
                }
                else
                {
                    currentReadingPlayer = udpPlayers[incomingEndpoint];

                    if (!currentReadingPlayer.Accepted && !currentReadingPlayer.PendingAccpeted)
                    {
                        // It is possible that the response validation was dropped so
                        // check if the client is resending for a response
                        byte[] response = Websockets.ValidateConnectionHeader(packet.CompressBytes());

                        // The client has sent the connection request again
                        if (response != null)
                        {
                            Client.Send(response, response.Length, groupEP);
                            continue;
                        }
                        else
                        {
                            currentReadingPlayer.PendingAccpeted = true;
                            ReadPacket(packet);
                        }
                    }
                    else
                    {
                        ReadPacket(packet);
                    }
                }
            }
        }
Beispiel #10
0
        private void ReceiveAsync_Completed(object sender, SocketAsyncEventArgs e)
        {
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                int          bytesAlreadyProcessed = 0;
                ReceiveToken token = (ReceiveToken)e.UserToken;
                if (!token.player.Accepted && !token.player.Connected)
                {
                    byte[] header = HandleHttpHeader(e, ref bytesAlreadyProcessed);
                    if (header == null)
                    {
                        DoRead(e);
                        return;
                    }
                    byte[] response = Websockets.ValidateConnectionHeader(header);

                    // The response will be null if the header sent is invalid, if so then disconnect client as they are sending invalid headers
                    if (response == null)
                    {
                        OnPlayerRejected(token.player);
                        Disconnect(token.player, true);
                        ReturnBuffer(e);
                        return;
                    }

                    // If all is in order then send the validated response to the client
                    token.player.TcpClientHandle.GetStream().Write(response, 0, response.Length);

                    // The player has successfully connected
                    token.player.Connected = true;
                }
                while (bytesAlreadyProcessed < e.BytesTransferred)
                {
                    byte[] data = HandleData(e, true, ref bytesAlreadyProcessed);
                    if (data == null)
                    {
                        break;
                    }
                    FrameStream frame = Factory.DecodeMessage(data, true, MessageGroupIds.TCP_FIND_GROUP_ID, token.player);
                    if (!token.player.Accepted)
                    {
                        if (frame.GroupId == MessageGroupIds.NETWORK_ID_REQUEST)
                        {
                            token.player.InstanceGuid = ((Text)frame).ToString();

                            // If the player was rejected during the handling of the playerGuidAssigned event, don't accept them.
                            if (!TryPlayerGuidAssignment(token.player))
                            {
                                break;
                            }

                            token.maxAllowedBytes = int.MaxValue;

                            if (authenticator != null)
                            {
                                authenticator.IssueChallenge(this, token.player, IssueChallenge, AuthUser);
                            }
                            else
                            {
                                AuthUser(token.player);
                            }
                        }
                        else if (frame.GroupId == MessageGroupIds.AUTHENTICATION_RESPONSE)
                        {
                            // Authenticate user response
                            if (authenticator == null)
                            {
                                return;
                            }

                            authenticator.VerifyResponse(this, token.player, frame.StreamData, AuthUser, RejectUser);
                        }
                        else
                        {
                            Disconnect(token.player, true);
                            ReturnBuffer(e);
                        }
                    }
                    else
                    {
                        token.player.Ping();
                        FireRead(frame, token.player);
                    }
                }
                DoRead(e);
            }
            else
            {
                Disconnect(((ReceiveToken)e.UserToken).player, true);
                ReturnBuffer(e);
            }
        }