Example #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;
        }
Example #2
0
        private void HandleMaximumClientPacketResponse(string incomingEndpoint, IPEndPoint groupEP)
        {
            // Tell the client why they are being disconnected
            Error frame = Error.CreateErrorMessage(Time.Timestep, "Max Players Reached On Server",
                                                   false, MessageGroupIds.MAX_CONNECTIONS, false);

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

            UDPPacketComposer.SendNewUDPPacket(this, playerToDisconnect, frame, false);

            // Send the close connection frame to the client
            UDPPacketComposer.SendNewUDPPacket(this, playerToDisconnect,
                                               new ConnectionClose(Time.Timestep, false, Receivers.Target,
                                                                   MessageGroupIds.DISCONNECT, false), false);
        }
Example #3
0
        private void HandleNotAcceptingConnectionsPacketResponse(string incomingEndpoint, IPEndPoint groupEP)
        {
            // Tell the client why they are being disconnected
            var frame = Error.CreateErrorMessage(Time.Timestep,
                                                 "The server is busy and not accepting connections", false,
                                                 MessageGroupIds.NOT_ACCEPT_CONNECTIONS, false);

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

            UDPPacketComposer.SendNewUDPPacket(this, playerToDisconnect, frame, false);

            // Send the close connection frame to the client
            UDPPacketComposer.SendNewUDPPacket(this, playerToDisconnect,
                                               new ConnectionClose(Time.Timestep, false, Receivers.Target,
                                                                   MessageGroupIds.DISCONNECT, false), false);
        }
Example #4
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;
        }
Example #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>
        /// <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);
                    }
                }
            }
        }
Example #6
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);
                    }
                }
            }
        }
Example #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 (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);
                    }
                }
            }
        }
Example #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
                {
                    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);
                    }
                }
            }
        }