예제 #1
0
        /// <summary>
        /// Instantiate an instance of Player
        /// </summary>
        /// <returns>
        /// A local instance of PlayerBehavior
        /// </returns>
        /// <param name="index">The index of the Player prefab in the NetworkManager to Instantiate</param>
        /// <param name="position">Optional parameter which defines the position of the created GameObject</param>
        /// <param name="rotation">Optional parameter which defines the rotation of the created GameObject</param>
        /// <param name="sendTransform">Optional Parameter to send transform data to other connected clients on Instantiation</param>
        public PlayerBehavior InstantiatePlayer(int index          = 0, Vector3?position = null, Quaternion?rotation = null,
                                                bool sendTransform = true)
        {
            if (PlayerNetworkObject.Length <= index)
            {
                Debug.Log("Prefab(s) missing for: Player. Add them at the NetworkManager prefab.");
                return(null);
            }

            var go          = Instantiate(PlayerNetworkObject[index]);
            var netBehavior = go.GetComponent <PlayerBehavior>();

            NetworkObject obj = null;

            if (!sendTransform && position == null && rotation == null)
            {
                obj = netBehavior.CreateNetworkObject(Networker, index);
            }
            else
            {
                metadata.Clear();

                if (position == null && rotation == null)
                {
                    byte transformFlags = 0x1 | 0x2;
                    ObjectMapper.Instance.MapBytes(metadata, transformFlags);
                    ObjectMapper.Instance.MapBytes(metadata, go.transform.position, go.transform.rotation);
                }
                else
                {
                    byte transformFlags = 0x0;
                    transformFlags |= (byte)(position != null ? 0x1 : 0x0);
                    transformFlags |= (byte)(rotation != null ? 0x2 : 0x0);
                    ObjectMapper.Instance.MapBytes(metadata, transformFlags);

                    if (position != null)
                    {
                        ObjectMapper.Instance.MapBytes(metadata, position.Value);
                    }

                    if (rotation != null)
                    {
                        ObjectMapper.Instance.MapBytes(metadata, rotation.Value);
                    }
                }

                obj = netBehavior.CreateNetworkObject(Networker, index, metadata.CompressBytes());
            }

            go.GetComponent <PlayerBehavior>().networkObject = (PlayerNetworkObject)obj;

            FinalizeInitialization(go, netBehavior, obj, position, rotation, sendTransform);

            return(netBehavior);
        }
예제 #2
0
        public BulletBehavior InstantiateBullet(int index = 0, Vector3?position = null, Quaternion?rotation = null, bool sendTransform = true)
        {
            var go          = Instantiate(BulletNetworkObject[index]);
            var netBehavior = go.GetComponent <BulletBehavior>();

            NetworkObject obj = null;

            if (!sendTransform && position == null && rotation == null)
            {
                obj = netBehavior.CreateNetworkObject(Networker, index);
            }
            else
            {
                metadata.Clear();

                if (position == null && rotation == null)
                {
                    metadata.Clear();
                    byte transformFlags = 0x1 | 0x2;
                    ObjectMapper.Instance.MapBytes(metadata, transformFlags);
                    ObjectMapper.Instance.MapBytes(metadata, go.transform.position, go.transform.rotation);
                }
                else
                {
                    byte transformFlags = 0x0;
                    transformFlags |= (byte)(position != null ? 0x1 : 0x0);
                    transformFlags |= (byte)(rotation != null ? 0x2 : 0x0);
                    ObjectMapper.Instance.MapBytes(metadata, transformFlags);

                    if (position != null)
                    {
                        ObjectMapper.Instance.MapBytes(metadata, position.Value);
                    }

                    if (rotation != null)
                    {
                        ObjectMapper.Instance.MapBytes(metadata, rotation.Value);
                    }
                }

                obj = netBehavior.CreateNetworkObject(Networker, index, metadata.CompressBytes());
            }

            go.GetComponent <BulletBehavior>().networkObject = (BulletNetworkObject)obj;

            FinalizeInitialization(go, netBehavior, obj, position, rotation, sendTransform);

            return(netBehavior);
        }
예제 #3
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;
        }
예제 #4
0
        /// <summary>
        /// This constructor will take a payload and create a new frame with the appropriate structure
        /// </summary>
        /// <param name="timestep">The timestep that this frame is created within</param>
        /// <param name="useMask">If set to <c>true</c> a mask will be used to encode the payload.</param>
        /// <param name="payload">The new frame initial data data</param>
        /// <param name="routerId">A byte that can be used to route data within a user program</param>
        public FrameStream(ulong timestep, bool useMask, BMSByte payload, Receivers receivers, int groupId, bool isStream, byte routerId = 0)
        {
            if (payload == null)
            {
                // TODO:  Throw frame exception
                throw new BaseNetworkException("The payload for the frame is not allowed to be null, otherwise use other constructor");
            }

            CreateFrame(useMask, timestep, payload.CompressBytes(), receivers, groupId, routerId, isStream);
        }
예제 #5
0
        protected override BMSByte SerializeDirtyFields()
        {
            if (firstFrame)
            {
                BMSByte bmsByte = new BMSByte();
                bmsByte = WritePayload(bmsByte);

                PTK.ArenaObservable.PlayerData _playerData = new PTK.ArenaObservable.PlayerData();
                _playerData.BMSData   = Convert.ToBase64String(bmsByte.CompressBytes());
                _playerData.UID       = PTK.Ansuz.Instance.UID;
                _playerData.RequestID = (int)PTK.AnsuzRequestID.CreatePlayer;
                PTK.ArenaObservable.PlayerData[] objs = { _playerData };
                string json = _playerData.ToJson <PTK.ArenaObservable.PlayerData>(objs, false);
                PTK.Ansuz.Instance.PublishToTopic("arena/playerData/all", json, 0);
                firstFrame = false;
            }

            dirtyFieldsData.Clear();
            dirtyFieldsData.Append(_dirtyFields);

            if ((0x1 & _dirtyFields[0]) != 0)
            {
                UnityObjectMapper.Instance.MapBytes(dirtyFieldsData, _position);
            }
            if ((0x2 & _dirtyFields[0]) != 0)
            {
                UnityObjectMapper.Instance.MapBytes(dirtyFieldsData, _rotation);
            }
            if ((0x4 & _dirtyFields[0]) != 0)
            {
                UnityObjectMapper.Instance.MapBytes(dirtyFieldsData, _spineRotation);
            }
            if ((0x8 & _dirtyFields[0]) != 0)
            {
                UnityObjectMapper.Instance.MapBytes(dirtyFieldsData, _vertical);
            }
            if ((0x10 & _dirtyFields[0]) != 0)
            {
                UnityObjectMapper.Instance.MapBytes(dirtyFieldsData, _horizontal);
            }
            if ((0x20 & _dirtyFields[0]) != 0)
            {
                UnityObjectMapper.Instance.MapBytes(dirtyFieldsData, _isMoving);
            }

            // Reset all the dirty fields
            for (int i = 0; i < _dirtyFields.Length; i++)
            {
                _dirtyFields[i] = 0;
            }


            return(dirtyFieldsData);
        }
        public virtual NetworkBehavior InstantiateNetworkBehavior(int pCreateCode = -1, IRPCSerializable pBehaviorData = null, Vector3?pPosition = null, Quaternion?pRotation = null, bool pSendTransform = true)
        {
            GameObject prefab = _networkBehaviorListSO.behaviorList.GetByCreateCode(pCreateCode);

            if (prefab == null)
            {
                return(null);
            }

            var           go          = Instantiate(prefab);
            var           netBehavior = go.GetComponent <NetworkBehavior>();
            NetworkObject obj         = null;

            if (!pSendTransform && pPosition == null && pRotation == null)
            {
                obj = netBehavior.CreateNetworkObject(_networker, pCreateCode);
            }
            else
            {
                _tmpMetadata.Clear();
                if (pPosition == null && pRotation == null)
                {
                    byte transformFlags = 0x1 | 0x2;
                    ObjectMapper.Instance.MapBytes(_tmpMetadata, transformFlags);
                    ObjectMapper.Instance.MapBytes(_tmpMetadata, go.transform.position, go.transform.rotation);
                }
                else
                {
                    byte transformFlags = 0x0;
                    transformFlags |= (byte)(pPosition != null ? 0x1 : 0x0);
                    transformFlags |= (byte)(pRotation != null ? 0x2 : 0x0);
                    ObjectMapper.Instance.MapBytes(_tmpMetadata, transformFlags);

                    if (pPosition != null)
                    {
                        ObjectMapper.Instance.MapBytes(_tmpMetadata, pPosition.Value);
                    }

                    if (pRotation != null)
                    {
                        ObjectMapper.Instance.MapBytes(_tmpMetadata, pRotation.Value);
                    }
                }

                obj = netBehavior.CreateNetworkObject(_networker, pCreateCode, _tmpMetadata.CompressBytes());
            }

            SetINetworkSceneObject(netBehavior, obj);
            SetIRPCSerializable(netBehavior, pBehaviorData);
            FinalizeInitialization(go, netBehavior, obj, pPosition, pRotation, pSendTransform);
            return(netBehavior);
        }
예제 #7
0
        public void AppendBytesRemoveStart3()
        {
            byte[] data  = new byte[] { 1, 8, 9, 34, 255, 0, 33, 66, 100, 128 };
            var    cache = new BMSByte();

            cache.Append(data);
            cache.RemoveStart(3);
            byte[] response = cache.CompressBytes();
            for (int i = 3; i < data.Length; i++)
            {
                Assert.AreEqual(data[i], response[i - 3]);
            }
        }
예제 #8
0
        public void AppendBytesAndCompressBytes()
        {
            byte[] data  = new byte[] { 1, 8, 9, 34, 255, 0, 33, 66, 100, 128 };
            var    cache = new BMSByte();

            cache.Append(data);
            byte[] response = cache.CompressBytes();
            Assert.AreEqual(data.Length, response.Length);
            for (int i = 0; i < data.Length; i++)
            {
                Assert.AreEqual(data[i], response[i]);
            }
        }
예제 #9
0
        private static void ReadBinaryMessage(NetworkingPlayer player, Binary frame, NetWorker sender)
        {
            BMSByte data = new BMSByte();

            data.Clone(frame.GetData());

            if (data[0] == 212)
            {
                data.MoveStartIndex(1);
                System.IO.File.WriteAllBytes("testRead.txt", data.CompressBytes());
                Console.WriteLine("Wrote file from network");
            }
        }
예제 #10
0
        /// <summary>
        /// Gets the raw data for this frame
        /// </summary>
        /// <returns>The raw byte data prepared by this frame</returns>
        public byte[] GetData(bool makeReliable = false, NetworkingPlayer player = null)
        {
            if (makeReliable)
            {
                MakeReliable(player);
                reliableCloneData.Clone(StreamData);

                reliableCloneData.InsertRange(StreamData.Size - (sizeof(ulong) * 2), BitConverter.GetBytes(UniqueReliableId));
                return(reliableCloneData.CompressBytes());
            }

            return(StreamData.CompressBytes());
        }
예제 #11
0
        private void PacketSequenceComplete(BMSByte data, int groupId, byte receivers)
        {
            // Pull the frame from the sent message
            FrameStream frame = Factory.DecodeMessage(data.CompressBytes(), false, groupId, Server, receivers);

            if (frame is ConnectionClose)
            {
                CloseConnection();
                return;
            }

            // Send an event off that a packet has been read
            OnMessageReceived(Server, frame);
        }
예제 #12
0
        private void PacketSequenceComplete(BMSByte data, int groupId, byte receivers, bool isReliable)
        {
            // Pull the frame from the sent message
            FrameStream frame = Factory.DecodeMessage(data.CompressBytes(), false, groupId, ServerPlayer, receivers);

            if (isReliable)
            {
                ProcessCompletedReliableFrame(frame);
            }
            else
            {
                FireRead(frame, ServerPlayer);
            }
        }
예제 #13
0
        protected UDPPacket TranscodePacket(NetworkingPlayer sender, BMSByte packet)
        {
            byte meta = PullPacketMetadata(packet);

            // If the last byte says it is reliable
            bool reliable = (0x1 & meta) != 0;

            // If the last byte says that it is the last packet for this group
            bool endPacket = (0x2 & meta) != 0;

            // If the last byte says that it is a conformation packet
            bool confirmationPacket = (0x4 & meta) != 0;

            // Get the receivers from the frist 4 bits
            Receivers receivers = (Receivers)(meta >> 4);

            // The group and order for this packet are assigned to the trailer of the packet, as
            // the header is reserved for frame formation
            int orderId = PullPacketOrderId(packet);
            int groupId = PullPacketGroupId(packet);

            ulong uniqueId = PullPacketUniqueId(packet, endPacket);

            // Check to see if this should respond to the sender that this packet has been received
            if (reliable && !confirmationPacket)
            {
#if DEEP_LOGGING
                Logging.BMSLog.Log($">>>>>>>>>>>>>>>>>>>>>>>>>>> SEND CONFIRM: {uniqueId}");
#endif

                byte[] confirmation = new byte[sizeof(ulong) + sizeof(int) + sizeof(int) + sizeof(byte)];
                Buffer.BlockCopy(BitConverter.GetBytes(uniqueId), 0, confirmation, 0, sizeof(ulong));
                Buffer.BlockCopy(BitConverter.GetBytes(groupId), 0, confirmation, sizeof(ulong), sizeof(int));
                Buffer.BlockCopy(BitConverter.GetBytes(orderId), 0, confirmation, sizeof(ulong) + sizeof(int),
                                 sizeof(int));

                // Register the confirmation flag in the last byte
                confirmation[confirmation.Length - 1] = (byte)(meta | 0x4);

                Client.Send(confirmation, confirmation.Length, sender.IPEndPointHandle);
            }

            // Create an instance of a packet struct to be sent off to the packet manager
            UDPPacket formattedPacket = new UDPPacket(reliable, endPacket, groupId, orderId, uniqueId,
                                                      packet.CompressBytes(), confirmationPacket, receivers);

            return(formattedPacket);
        }
예제 #14
0
 private void HandleHeaderExchanging(BMSByte packet)
 {
     if (Websockets.ValidateResponseHeader(headerHash, packet.CompressBytes()))
     {
         CompleteHeaderExchange();
     }
     else if (packet.Size >= MINIMUM_FRAME_SIZE)
     {
         HandleServerRejection(packet);
         CancelReadThread();
     }
     else if (packet.Size != 1 || packet[0] != 0)
     {
         Disconnect(true);
         CancelReadThread();
     }
 }
예제 #15
0
        private void PacketSequenceComplete(BMSByte data, int groupId, byte receivers, bool isReliable)
        {
            // Pull the frame from the sent message
            FrameStream frame = Factory.DecodeMessage(data.CompressBytes(), false, groupId, currentReadingPlayer, receivers);

            if (isReliable)
            {
                frame.ExtractReliableId();

                // TODO:  If the current reliable index for this player is not at
                // the specified index, then it needs to wait for the correct ordering
                currentReadingPlayer.WaitReliable(frame);
            }
            else
            {
                FireRead(frame, currentReadingPlayer);
            }
        }
예제 #16
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;
        }
예제 #17
0
        public void AppendBytesRemoveStart3Add3ToEnd()
        {
            int removeSize = 3;

            byte[] data  = new byte[] { 1, 8, 9, 34, 255, 0, 33, 66, 100, 128 };
            var    cache = new BMSByte();

            cache.Append(data);
            cache.RemoveStart(removeSize);
            byte[] trailer = new byte[] { 9, 3, 9 };
            cache.Append(trailer);
            byte[] response = cache.CompressBytes();
            for (int i = removeSize; i < data.Length; i++)
            {
                Assert.AreEqual(data[i], response[i - removeSize]);
                Assert.AreEqual(data[i], cache[i - removeSize]);
            }
            for (int i = trailer.Length - 1; i >= 0; i--)
            {
                Assert.AreEqual(trailer[i], response[response.Length - trailer.Length + i]);
            }
        }
예제 #18
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;
        }
        private void PacketSequenceComplete(BMSByte data, int groupId, byte receivers)
        {
            // Pull the frame from the sent message
            FrameStream frame = Factory.DecodeMessage(data.CompressBytes(), false, groupId, currentReadingPlayer, receivers);

            // Check for default messages
            if (frame is Text)
            {
                // This packet is sent if the player did not receive it's network id
                if (frame.GroupId == MessageGroupIds.NETWORK_ID_REQUEST)
                {
                    currentReadingPlayer.InstanceGuid = frame.ToString();

                    OnPlayerGuidAssigned(currentReadingPlayer);

                    // If so, just resend the player id
                    writeBuffer.Clear();
                    writeBuffer.Append(BitConverter.GetBytes(currentReadingPlayer.NetworkId));
                    Send(currentReadingPlayer, new Binary(Time.Timestep, false, writeBuffer, Receivers.Target, MessageGroupIds.NETWORK_ID_REQUEST, false), true);

                    SendBuffer(currentReadingPlayer);
                    return;
                }
            }

            if (frame is ConnectionClose)
            {
                Send(currentReadingPlayer, new ConnectionClose(Time.Timestep, false, Receivers.Server, MessageGroupIds.DISCONNECT, false), false);

                Disconnect(currentReadingPlayer, false);
                CleanupDisconnections();
                return;
            }

            // Send an event off that a packet has been read
            OnMessageReceived(currentReadingPlayer, frame);
        }
예제 #20
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);
                    }
                }
            }
        }
예제 #21
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);
                    }
                }
            }
        }
예제 #22
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);
            }
        }
예제 #23
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 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);
            }
        }
예제 #24
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);
                    }
                }
            }
        }
예제 #25
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()
        {
            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);
            }
        }
예제 #26
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);
                    }
                }
            }
        }
예제 #27
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);
                    }
                }
            }
        }