Example #1
0
        /// <summary>
        /// The server sent us a message before sending a response header to validate
        /// This happens if the server is not accepting connections or the max connection count has been reached
        /// We will get two messages. The first one is either a MAX_CONNECTIONS or NOT_ACCEPT_CONNECTIONS group message.
        /// The second one will be the DISCONNECT message
        /// </summary>
        /// <param name="packet">The packet recieved causing relating to the rejection</param>
        private void HandleServerRejection(BMSByte packet)
        {
            UDPPacket formattedPacket = TranscodePacket(ServerPlayer, packet);

            if (formattedPacket.groupId == MessageGroupIds.MAX_CONNECTIONS)
            {
                Logging.BMSLog.LogWarning("Max Players Reached On Server");
            }
            else if (formattedPacket.groupId == MessageGroupIds.NOT_ACCEPT_CONNECTIONS)
            {
                Logging.BMSLog.LogWarning("The server is busy and not accepting connections");
            }
            else if (formattedPacket.groupId == MessageGroupIds.DISCONNECT)
            {
                CloseConnection();
            }
            else
            {
                // Received something unexpected so do the same thing as the if below
                Disconnect(true);
                CancelReadThread();
            }
        }
Example #2
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 ReadNetwork()
        {
            CSteamID messageFrom = default(CSteamID);

            try
            {
                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
                    {
                        uint msgSize = 0;

                        if (SteamNetworking.IsP2PPacketAvailable(out msgSize))
                        {
                            packet = Client.Receive(msgSize, out messageFrom);
                        }
                        else
                        {
                            Thread.Sleep(1);
                            continue;
                        }
                        // Read a packet from the network


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

                        BandwidthIn += (ulong)packet.Size;
                    }
                    catch (SocketException ex)
                    {
                        // This is a common exception when we exit the blocking call
                        Logging.BMSLog.LogException(ex);
                        Disconnect(true);
                    }

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

                    // Check to see if the headers have been exchanged
                    if (!headerExchanged)
                    {
                        if (Websockets.ValidateResponseHeader(headerHash, packet.CompressBytes()))
                        {
                            headerExchanged = true;

                            // TODO:  When getting the user id, it should also get the server time
                            // by using the current time in the payload and getting it back along with server time

                            // Ping the server to finalize the player's connection
                            Send(Text.CreateFromString(Time.Timestep, InstanceGuid.ToString(), false, Receivers.Server, MessageGroupIds.NETWORK_ID_REQUEST, false), true);
                        }
                        else if (packet.Size != 1 || packet[0] != 0)
                        {
                            Logging.BMSLog.LogWarning("DISCONNECTED: RECEIVED UNKNOWN PACKET BEFORE HEADERS WERE EXCHANGED!");
                            Disconnect(true);
                            break;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (packet.Size < 17)
                        {
                            continue;
                        }

                        // Format the byte data into a UDPPacket struct
                        UDPPacket formattedPacket = TranscodePacket(Server, packet);

                        // Check to see if this is a confirmation packet, which is just
                        // a packet to say that the reliable packet has been read
                        if (formattedPacket.isConfirmation)
                        {
                            if (formattedPacket.groupId == MessageGroupIds.DISCONNECT)
                            {
                                CloseConnection();
                                return;
                            }

                            OnMessageConfirmed(server, formattedPacket);
                            continue;
                        }

                        // Add the packet to the manager so that it can be tracked and executed on complete
                        packetManager.AddPacket(formattedPacket, PacketSequenceComplete, this);
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.BMSLog.LogException(ex);
                Disconnect(true);
            }
        }
        /// <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 ReadNetwork()
        {
            IPEndPoint groupEP          = new IPEndPoint(IPAddress.Any, 0);
            string     incomingEndpoint = string.Empty;

            try
            {
                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 (SocketException /*ex*/)
                    {
                        // This is a common exception when we exit the blocking call
                        //Logging.BMSLog.LogException(ex);
                        Disconnect(true);
                    }

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

                    // This message was not from the server
                    if (groupEP.Address != Server.IPEndPointHandle.Address &&
                        groupEP.Port != Server.IPEndPointHandle.Port)
                    {
                        if (packet.Size == 1 && (packet[0] == SERVER_BROADCAST_CODE || packet[1] == CLIENT_BROADCAST_CODE))
                        {
                        }
                        else if (packet.Size.Between(2, 4) && packet[0] == BROADCAST_LISTING_REQUEST_1 && packet[1] == BROADCAST_LISTING_REQUEST_2 && packet[2] == BROADCAST_LISTING_REQUEST_3)
                        {
                            // This may be a local listing request so respond with the client flag byte
                            Client.Send(new byte[] { CLIENT_BROADCAST_CODE }, 1, groupEP);
                        }

                        continue;
                    }

                    // Check to see if the headers have been exchanged
                    if (!headerExchanged)
                    {
                        if (Websockets.ValidateResponseHeader(headerHash, packet.CompressBytes()))
                        {
                            headerExchanged = true;

                            // TODO:  When getting the user id, it should also get the server time
                            // by using the current time in the payload and getting it back along with server time

                            // Ping the server to finalize the player's connection
                            Send(Text.CreateFromString(Time.Timestep, InstanceGuid.ToString(), false, Receivers.Server, MessageGroupIds.NETWORK_ID_REQUEST, false), true);
                        }
                        else if (packet.Size >= MINIMUM_FRAME_SIZE)
                        {
                            // The server sent us a message before sending a responseheader to validate
                            // This happens if the server is not accepting connections or the max connection count has been reached
                            // We will get two messages. The first one is either a MAX_CONNECTIONS or NOT_ACCEPT_CONNECTIONS group message.
                            // The second one will be the DISCONNECT message
                            UDPPacket formattedPacket = TranscodePacket(Server, packet);

                            if (formattedPacket.groupId == MessageGroupIds.MAX_CONNECTIONS)
                            {
                                Logging.BMSLog.LogWarning("Max Players Reached On Server");
                                // Wait for the second message (Disconnect)
                                continue;
                            }

                            if (formattedPacket.groupId == MessageGroupIds.NOT_ACCEPT_CONNECTIONS)
                            {
                                Logging.BMSLog.LogWarning("The server is busy and not accepting connections");
                                // Wait for the second message (Disconnect)
                                continue;
                            }

                            if (formattedPacket.groupId == MessageGroupIds.DISCONNECT)
                            {
                                CloseConnection();
                                return;
                            }

                            // Received something unexpected so do the same thing as the if below
                            Disconnect(true);
                            break;
                        }
                        else if (packet.Size != 1 || packet[0] != 0)
                        {
                            Disconnect(true);
                            break;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (packet.Size < MINIMUM_FRAME_SIZE)
                        {
                            continue;
                        }

                        // Format the byte data into a UDPPacket struct
                        UDPPacket formattedPacket = TranscodePacket(Server, packet);

                        // Check to see if this is a confirmation packet, which is just
                        // a packet to say that the reliable packet has been read
                        if (formattedPacket.isConfirmation)
                        {
                            if (formattedPacket.groupId == MessageGroupIds.DISCONNECT)
                            {
                                CloseConnection();
                                return;
                            }

                            OnMessageConfirmed(server, formattedPacket);
                            continue;
                        }

                        if (formattedPacket.groupId == MessageGroupIds.AUTHENTICATION_FAILURE)
                        {
                            Logging.BMSLog.LogWarning("The server rejected the authentication attempt");
                            // Wait for the second message (Disconnect)
                            continue;
                        }

                        // Add the packet to the manager so that it can be tracked and executed on complete
                        packetManager.AddPacket(formattedPacket, PacketSequenceComplete, this);
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.BMSLog.LogException(ex);
                Disconnect(true);
            }
        }
Example #4
0
 private bool IsDisconnectableGroupId(UDPPacket formattedPacket)
 {
     return(formattedPacket.groupId == MessageGroupIds.DISCONNECT ||
            formattedPacket.groupId == MessageGroupIds.AUTHENTICATION_FAILURE);
 }
        /// <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 ReadNetwork()
        {
            IPEndPoint groupEP          = new IPEndPoint(IPAddress.Any, 0);
            string     incomingEndpoint = string.Empty;

            try
            {
                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 (SocketException /*ex*/)
                    {
                        // This is a common exception when we exit the blocking call
                        //Logging.BMSLog.LogException(ex);
                        Disconnect(true);
                    }

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

                    // This message was not from the server
                    if (groupEP.Address != Server.IPEndPointHandle.Address &&
                        groupEP.Port != Server.IPEndPointHandle.Port)
                    {
                        if (packet.Size == 1 && (packet[0] == SERVER_BROADCAST_CODE || packet[1] == CLIENT_BROADCAST_CODE))
                        {
                        }
                        else if (packet.Size.Between(2, 4) && packet[0] == BROADCAST_LISTING_REQUEST_1 && packet[1] == BROADCAST_LISTING_REQUEST_2 && packet[2] == BROADCAST_LISTING_REQUEST_3)
                        {
                            //这可能是一个本地列表请求,所以用客户端标志字节进行响应
                            // This may be a local listing request so respond with the client flag byte
                            Client.Send(new byte[] { CLIENT_BROADCAST_CODE }, 1, groupEP);
                        }

                        continue;
                    }

                    // Check to see if the headers have been exchanged
                    if (!headerExchanged)
                    {
                        if (Websockets.ValidateResponseHeader(headerHash, packet.CompressBytes()))
                        {
                            headerExchanged = true;

                            // TODO:  When getting the user id, it should also get the server time
                            // by using the current time in the payload and getting it back along with server time

                            // Ping the server to finalize the player's connection
                            Send(Text.CreateFromString(Time.Timestep, InstanceGuid.ToString(), false, Receivers.Server, MessageGroupIds.NETWORK_ID_REQUEST, false), true);
                        }
                        else if (packet.Size != 1 || packet[0] != 0)
                        {
                            Disconnect(true);
                            break;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (packet.Size < 17)
                        {
                            continue;
                        }

                        // 格式的字节数据到一个udppacket结构
                        // Format the byte data into a UDPPacket struct
                        UDPPacket formattedPacket = TranscodePacket(Server, packet);

                        // Check to see if this is a confirmation packet, which is just
                        // a packet to say that the reliable packet has been read
                        if (formattedPacket.isConfirmation)
                        {
                            if (formattedPacket.groupId == MessageGroupIds.DISCONNECT)
                            {
                                CloseConnection();
                                return;
                            }

                            OnMessageConfirmed(server, formattedPacket);
                            continue;
                        }

                        //将数据包添加到管理器,以便可以在完成时跟踪和执行
                        // Add the packet to the manager so that it can be tracked and executed on complete
                        packetManager.AddPacket(formattedPacket, PacketSequenceComplete, this);
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.BMSLog.LogException(ex);
                Disconnect(true);
            }
        }