コード例 #1
0
        /// <summary>
        /// Creates inter-player peer-to-peer connections between known players.
        /// </summary>
        public async Task ConnectPlayers()
        {
            if (this.state != MultiPlayerState.FindingPlayers)
            {
                throw new Exception("The multiplayer environment is not in the state of finding players.");
            }

            await this.SetState(MultiPlayerState.ConnectingPlayers);

            int          Index  = 0;
            BinaryOutput Output = new BinaryOutput();

            Output.WriteByte(1);
            Output.WriteString(this.applicationName);
            this.localPlayer.Index = Index++;
            this.Serialize(this.localPlayer, Output);

#if LineListener
            Console.Out.Write("Tx: INTERCONNECT(" + this.localPlayer.ToString());
#endif
            lock (this.remotePlayersByEndpoint)
            {
                Output.WriteUInt((uint)this.remotePlayersByEndpoint.Count);

                foreach (Player Player in this.remotePlayersByEndpoint.Values)
                {
                    Player.Index = Index++;
                    this.Serialize(Player, Output);

#if LineListener
                    Console.Out.Write("," + Player.ToString());
#endif
                }
            }

            this.mqttTerminatedPacketIdentifier = await this.mqttConnection.PUBLISH(this.mqttNegotiationTopic, MqttQualityOfService.AtLeastOnce, false, Output);

            this.mqttConnection.OnPublished += this.MqttConnection_OnPublished;

#if LineListener
            Console.Out.WriteLine(")");
#endif
            await this.StartConnecting();
        }
コード例 #2
0
        private void MqttConnection_OnStateChanged(object Sender, MqttState NewState)
        {
            if (NewState == MqttState.Connected)
            {
                this.mqttConnection.SUBSCRIBE(this.mqttNegotiationTopic);

                BinaryOutput Output = new BinaryOutput();
                Output.WriteByte(0);
                Output.WriteString(this.applicationName);

                this.localPlayer.SetEndpoints(this.p2pNetwork.ExternalEndpoint, this.p2pNetwork.LocalEndpoint);
                this.Serialize(this.localPlayer, Output);

                this.mqttConnection.PUBLISH(this.mqttNegotiationTopic, MqttQualityOfService.AtLeastOnce, false, Output);

#if LineListener
                Console.Out.WriteLine("Tx: HELLO(" + this.localPlayer.ToString() + ")");
#endif
            }
        }
コード例 #3
0
        /// <summary>
        /// Subscribes to information from a set of topics. Topics can include wildcards.
        /// </summary>
        /// <param name="Topics">Topics together with Quality of Service levels for each topic.</param>
        /// <returns>Packet identifier assigned to subscription.</returns>
        public ushort SUBSCRIBE(params KeyValuePair <string, MqttQualityOfService>[] Topics)
        {
            BinaryOutput Payload = new BinaryOutput();
            ushort       PacketIdentifier;

            PacketIdentifier = this.packetIdentifier++;
            if (PacketIdentifier == 0)
            {
                PacketIdentifier = this.packetIdentifier++;
            }

            Payload.WriteUInt16(PacketIdentifier);

            foreach (KeyValuePair <string, MqttQualityOfService> Pair in Topics)
            {
                Payload.WriteString(Pair.Key);
                Payload.WriteByte((byte)Pair.Value);
            }

            byte[] PayloadData = Payload.GetPacket();

            BinaryOutput Packet = new BinaryOutput();
            byte         b      = (byte)((int)MqttControlPacketType.SUBSCRIBE << 4);

            b |= 2;

            Packet.WriteByte(b);
            Packet.WriteUInt((uint)PayloadData.Length);
            Packet.WriteBytes(PayloadData);

            byte[] PacketData = Packet.GetPacket();

            this.BeginWrite(PacketData, PacketIdentifier);

            return(PacketIdentifier);
        }
コード例 #4
0
        private void Connection_OnReceived(object Sender, byte[] Packet)
        {
            PeerConnection Connection = (PeerConnection)Sender;
            Guid           PlayerId;
            IPAddress      PlayerRemoteAddress;
            IPEndPoint     PlayerRemoteEndpoint;

            try
            {
                BinaryInput Input = new BinaryInput(Packet);

                PlayerId             = Input.ReadGuid();
                PlayerRemoteAddress  = IPAddress.Parse(Input.ReadString());
                PlayerRemoteEndpoint = new IPEndPoint(PlayerRemoteAddress, Input.ReadUInt16());
            }
            catch (Exception)
            {
                Connection.Dispose();
                return;
            }

            Player Player = (Player)Connection.StateObject;

            lock (this.remotePlayersByEndpoint)
            {
                if (!this.playersById.TryGetValue(PlayerId, out Player Player2) || Player2.PlayerId != Player.PlayerId)
                {
                    Connection.Dispose();
                    return;
                }

                Player.Connection = Connection;
            }

            Connection.RemoteEndpoint = Player.GetExpectedEndpoint(this.p2pNetwork);

            Connection.OnReceived -= new BinaryEventHandler(Connection_OnReceived);
            Connection.OnReceived += new BinaryEventHandler(Peer_OnReceived);

            Connection.OnSent += new BinaryEventHandler(Connection_OnSent);

            BinaryOutput Output = new BinaryOutput();

            Output.WriteGuid(this.localPlayer.PlayerId);
            Output.WriteString(this.ExternalAddress.ToString());
            Output.WriteUInt16((ushort)this.ExternalEndpoint.Port);

            Connection.SendTcp(Output.GetPacket());

            MultiPlayerEnvironmentPlayerInformationEventHandler h = this.OnPlayerConnected;

            if (h != null)
            {
                try
                {
                    h(this, Player);
                }
                catch (Exception ex)
                {
                    Events.Log.Critical(ex);
                }
            }
        }
コード例 #5
0
		private ushort PUBLISH(string Topic, MqttQualityOfService QoS, bool Retain, bool Duplicate, byte[] Data)
		{
			BinaryOutput Payload = new BinaryOutput();
			ushort PacketIdentifier;

			Payload.WriteString(Topic);

			if (QoS > MqttQualityOfService.AtMostOne)
			{
				PacketIdentifier = this.packetIdentifier++;
				if (PacketIdentifier == 0)
					PacketIdentifier = this.packetIdentifier++;

				Payload.WriteUInt16(PacketIdentifier);
			}
			else
				PacketIdentifier = 0;

			Payload.WriteBytes(Data);

			byte[] PayloadData = Payload.GetPacket();

			BinaryOutput Packet = new BinaryOutput();
			byte b = (byte)((int)MqttControlPacketType.PUBLISH << 4);
			if (Duplicate)
				b |= 8;

			b |= (byte)((int)QoS << 1);

			if (Retain)
				b |= 1;

			Packet.WriteByte(b);
			Packet.WriteUInt((uint)PayloadData.Length);
			Packet.WriteBytes(PayloadData);

			byte[] PacketData = Packet.GetPacket();

			this.BeginWrite(PacketData, PacketIdentifier);

			return PacketIdentifier;
		}
コード例 #6
0
		private void CONNECT(int KeepAliveSeconds)
		{
			this.State = MqttState.Authenticating;
			this.keepAliveSeconds = KeepAliveSeconds;
			this.nextPing = DateTime.Now.AddMilliseconds(KeepAliveSeconds * 500);
			this.secondTimer = new Timer(this.secondTimer_Elapsed, null, 1000, 1000);

			BinaryOutput Payload = new BinaryOutput();
			Payload.WriteString("MQTT");
			Payload.WriteByte(4);	// v3.1.1

			byte b = 2;		// Clean session.

			Payload.WriteByte(b);

			Payload.WriteByte((byte)(KeepAliveSeconds >> 8));
			Payload.WriteByte((byte)KeepAliveSeconds);

			Payload.WriteString(this.clientId);
			if (!string.IsNullOrEmpty(this.userName))
			{
				b |= 128;
				Payload.WriteString(this.userName);

				if (!string.IsNullOrEmpty(this.password))
				{
					b |= 64;
					Payload.WriteString(this.password);
				}
			}

			byte[] PayloadData = Payload.GetPacket();

			BinaryOutput Packet = new BinaryOutput();
			Packet.WriteByte((byte)MqttControlPacketType.CONNECT << 4);
			Packet.WriteUInt((uint)PayloadData.Length);
			Packet.WriteBytes(PayloadData);

			byte[] PacketData = Packet.GetPacket();

			this.BeginWrite(PacketData, 0);
			this.inputState = 0;
			this.BeginRead();
		}
コード例 #7
0
		/// <summary>
		/// Unsubscribes from information earlier subscribed to. Topics can include wildcards.
		/// </summary>
		/// <param name="Topics">Topics</param>
		/// <returns>Packet identifier assigned to unsubscription.</returns>
		public ushort UNSUBSCRIBE(params string[] Topics)
		{
			BinaryOutput Payload = new BinaryOutput();
			ushort PacketIdentifier;

			PacketIdentifier = this.packetIdentifier++;
			if (PacketIdentifier == 0)
				PacketIdentifier = this.packetIdentifier++;

			Payload.WriteUInt16(PacketIdentifier);

			foreach (string Topic in Topics)
				Payload.WriteString(Topic);

			byte[] PayloadData = Payload.GetPacket();

			BinaryOutput Packet = new BinaryOutput();
			byte b = (byte)((int)MqttControlPacketType.UNSUBSCRIBE << 4);
			b |= 2;

			Packet.WriteByte(b);
			Packet.WriteUInt((uint)PayloadData.Length);
			Packet.WriteBytes(PayloadData);

			byte[] PacketData = Packet.GetPacket();

			this.BeginWrite(PacketData, PacketIdentifier);

			return PacketIdentifier;
		}
コード例 #8
0
		/// <summary>
		/// Subscribes to information from a set of topics. Topics can include wildcards.
		/// </summary>
		/// <param name="Topics">Topics together with Quality of Service levels for each topic.</param>
		/// <returns>Packet identifier assigned to subscription.</returns>
		public ushort SUBSCRIBE(params KeyValuePair<string, MqttQualityOfService>[] Topics)
		{
			BinaryOutput Payload = new BinaryOutput();
			ushort PacketIdentifier;

			PacketIdentifier = this.packetIdentifier++;
			if (PacketIdentifier == 0)
				PacketIdentifier = this.packetIdentifier++;

			Payload.WriteUInt16(PacketIdentifier);

			foreach (KeyValuePair<string, MqttQualityOfService> Pair in Topics)
			{
				Payload.WriteString(Pair.Key);
				Payload.WriteByte((byte)Pair.Value);
			}

			byte[] PayloadData = Payload.GetPacket();

			BinaryOutput Packet = new BinaryOutput();
			byte b = (byte)((int)MqttControlPacketType.SUBSCRIBE << 4);
			b |= 2;

			Packet.WriteByte(b);
			Packet.WriteUInt((uint)PayloadData.Length);
			Packet.WriteBytes(PayloadData);

			byte[] PacketData = Packet.GetPacket();

			this.BeginWrite(PacketData, PacketIdentifier);

			return PacketIdentifier;
		}
コード例 #9
0
ファイル: Program.cs プロジェクト: PeterWaher/RetroSharp
        public static void Main(string[] args)
        {
            Initialize();

            try
            {
                DateTime Start    = DateTime.Now;
                Guid     PlayerId = Guid.NewGuid();
                string   Name;

                Console.Out.WriteLine("Hello. What is your name?");
                Name = Console.ReadLine();

                using (MultiPlayerEnvironment MPE = new MultiPlayerEnvironment("MultiPlayerSetup", true,
                                                                               "iot.eclipse.org", 1883, false, string.Empty, string.Empty, "RetroSharp/Examples/Networking/MultiPlayerSetup",
                                                                               5, PlayerId, new KeyValuePair <string, string>("NAME", Name)))
                {
                    MPE.OnStateChange += (sender, newstate) => Console.Out.WriteLine(newstate.ToString());

                    MPE.OnPlayerAvailable += (sender, player) =>
                    {
                        Console.Out.WriteLine("New player available: " + player["NAME"]);
                        if (sender.PlayerCount >= 5 || (DateTime.Now - Start).TotalSeconds >= 20)
                        {
                            MPE.ConnectPlayers();
                        }
                    };

                    MPE.OnPlayerConnected += (sender, player) => Console.Out.WriteLine("Player connected: " + player["NAME"]);

                    MPE.OnGameDataReceived += (sender, e) => Console.Out.WriteLine(e.FromPlayer["NAME"] + ": " + e.Data.ReadString());

                    MPE.OnPlayerDisconnected += (sender, player) => Console.Out.WriteLine("Player disconnected: " + player["NAME"]);

                    if (!MPE.Wait(20000))
                    {
                        if (MPE.State == MultiPlayerState.FindingPlayers)
                        {
                            MPE.ConnectPlayers();
                        }
                        else
                        {
                            throw new Exception("Unable to setup multi-player environment.");
                        }
                    }

                    Console.Out.WriteLine(MPE.PlayerCount.ToString() + " player(s) now connected.");
                    Console.Out.WriteLine("Write anything and send it to the others.");
                    Console.Out.WriteLine("An empty row will quit the application.");
                    Console.Out.WriteLine();

                    string s = Console.In.ReadLine();

                    while (!string.IsNullOrEmpty(s))
                    {
                        BinaryOutput Msg = new BinaryOutput();
                        Msg.WriteString(s);
                        MPE.SendTcpToAll(Msg.GetPacket());

                        s = Console.In.ReadLine();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.Out.WriteLine(ex.Message);
                Console.In.ReadLine();
            }

            Terminate();
        }
コード例 #10
0
ファイル: Program.cs プロジェクト: PeterWaher/RetroSharp
        public static void Main(string[] args)
        {
            Initialize();

            Console.Out.Write("Host Name (default iot.eclipse.org): ");
            string Host = Console.In.ReadLine();

            if (string.IsNullOrEmpty(Host))
            {
                Console.Out.WriteLine("Using iot.eclipse.org.");
                Host = "iot.eclipse.org";
            }

            Console.Out.WriteLine();
            Console.Out.Write("Port Number (default 1883): ");
            string s = Console.In.ReadLine();
            int    Port;

            if (string.IsNullOrEmpty(s))
            {
                Console.Out.WriteLine("Using port 1883.");
                Port = 1883;
            }
            else
            {
                Port = int.Parse(s);
            }

            Console.Out.WriteLine();

            BinaryOutput Payload;
            int          PacketsLeft = NrTestsPerQoS;

            using (MqttConnection MqttConnection = ConnectToMqttServer("iot.eclipse.org", Port, string.Empty, string.Empty))
            {
                WriteLine("<" + MqttConnection.State.ToString() + ">", C64Colors.LightGreen);

                MqttConnection.TrustServer = true;

                MqttConnection.OnConnectionError += (sender, ex) =>
                {
                    WriteLine("Unable to connect:", C64Colors.Red);
                };

                MqttConnection.OnError += (sender, ex) =>
                {
                    WriteLine(ex.Message, C64Colors.Red);
                };

                MqttConnection.OnContentReceived += (sender, Content) =>
                {
                    string ClientId = Content.DataInput.ReadString();
                    if (ClientId == sender.ClientId)
                    {
                        DateTime             TP  = Content.DataInput.ReadDateTime();
                        MqttQualityOfService QoS = (MqttQualityOfService)Content.DataInput.ReadByte();
                        Console.Out.WriteLine("Latency: " + (DateTime.Now - TP).TotalMilliseconds + " ms (" + QoS.ToString() + ")");

                        bool Resend;

                        if (--PacketsLeft > 0)
                        {
                            Resend = true;
                        }
                        else if (QoS < MqttQualityOfService.ExactlyOne)
                        {
                            QoS         = (MqttQualityOfService)((int)QoS + 1);
                            PacketsLeft = NrTestsPerQoS;
                            Resend      = true;
                        }
                        else
                        {
                            Resend = false;
                        }

                        if (Resend)
                        {
                            Payload = new BinaryOutput();
                            Payload.WriteString(MqttConnection.ClientId);
                            Payload.WriteDateTime(DateTime.Now);
                            Payload.WriteByte((byte)QoS);

                            MqttConnection.PUBLISH("RetroSharp/Examples/Networking/Latency", QoS, false, Payload);
                        }
                        else
                        {
                            Console.Out.WriteLine("Press ENTER to continue.");
                        }
                    }
                };

                MqttConnection.OnStateChanged += (sender, state) =>
                {
                    WriteLine("<" + MqttConnection.State.ToString() + ">", C64Colors.LightGreen);

                    if (state == MqttState.Connected)
                    {
                        MqttConnection.SUBSCRIBE("RetroSharp/Examples/Networking/Latency");

                        Payload = new BinaryOutput();
                        Payload.WriteString(MqttConnection.ClientId);
                        Payload.WriteDateTime(DateTime.Now);
                        Payload.WriteByte((byte)MqttQualityOfService.AtMostOne);

                        MqttConnection.PUBLISH("RetroSharp/Examples/Networking/Latency", MqttQualityOfService.AtMostOne, false, Payload);
                    }
                };

                Console.In.ReadLine();
            }

            Terminate();
        }
コード例 #11
0
ファイル: Program.cs プロジェクト: PeterWaher/RetroSharp
        public static void Main(string[] args)
        {
            ManualResetEvent Terminated = new ManualResetEvent(false);

            Initialize();

            Console.Out.WriteLine("Move the mouse to move the pointer on the screen.");
            Console.Out.WriteLine("Press left mouse button while moving to draw.");
            Console.Out.WriteLine("Press the ESC key to close the application.");
            Console.Out.WriteLine("You will be able to see what others draw as well.");

            OnKeyDown += (sender, e) =>
            {
                if (e.Key == Key.Escape || (e.Key == Key.C && e.Control))
                {
                    Terminated.Set();
                }
            };

            FillRectangle(0, 0, ScreenWidth, ScreenHeight, C64Colors.Blue);

            int          PointerTexture = AddSpriteTexture(GetResourceBitmap("Pointer.png"), System.Drawing.Color.FromArgb(0, 0, 255), true);
            Point        P       = GetMousePointer();
            Point        LastP   = P;
            Sprite       Pointer = CreateSprite(P.X, P.Y, PointerTexture);
            Random       Rnd     = new System.Random();
            int          R       = Rnd.Next(128, 255);
            int          G       = Rnd.Next(128, 255);
            int          B       = Rnd.Next(128, 255);
            Color        Color   = Color.FromArgb(R, G, B);
            bool         Draw    = false;
            BinaryOutput Payload;

            using (MqttConnection MqttConnection = ConnectToMqttServer("iot.eclipse.org", false, string.Empty, string.Empty))
            {
                WriteLine("<" + MqttConnection.State.ToString() + ">", C64Colors.LightGreen);

                MqttConnection.TrustServer = true;

                MqttConnection.OnConnectionError += (sender, ex) =>
                {
                    WriteLine("Unable to connect:", C64Colors.Red);
                };

                MqttConnection.OnError += (sender, ex) =>
                {
                    WriteLine(ex.Message, C64Colors.Red);
                };

                MqttConnection.OnStateChanged += (sender, state) =>
                {
                    WriteLine("<" + MqttConnection.State.ToString() + ">", C64Colors.LightGreen);

                    if (state == MqttState.Connected)
                    {
                        MqttConnection.SUBSCRIBE("RetroSharp/Examples/Networking/MultiUserDraw");
                    }
                };

                OnMouseMove += (sender, e) =>
                {
                    P = e.Position;
                    Pointer.SetPosition(P);

                    int DX = P.X - RasterWidth / 2;
                    int DY = P.Y - RasterHeight / 2;

                    Pointer.Angle = 90 + 22.5 + System.Math.Atan2(DY, DX) * 180 / System.Math.PI;

                    if (Draw)
                    {
                        Payload = new BinaryOutput();
                        Payload.WriteString(MqttConnection.ClientId);
                        Payload.WriteInt(LastP.X);
                        Payload.WriteInt(LastP.Y);
                        Payload.WriteInt(P.X);
                        Payload.WriteInt(P.Y);
                        Payload.WriteColor(Color);

                        MqttConnection.PUBLISH("RetroSharp/Examples/Networking/MultiUserDraw", MqttQualityOfService.AtMostOne, false, Payload);

                        DrawLine(LastP.X, LastP.Y, P.X, P.Y, Color);
                    }

                    LastP = P;
                };

                OnMouseDown += (sender, e) =>
                {
                    Draw = e.LeftButton;
                };

                OnMouseUp += (sender, e) =>
                {
                    Draw = e.LeftButton;
                };

                MqttConnection.OnContentReceived += (sender, Content) =>
                {
                    BinaryInput Input    = Content.DataInput;
                    string      ClientId = Input.ReadString();
                    if (ClientId != MqttConnection.ClientId)
                    {
                        int   X1 = (int)Input.ReadInt();
                        int   Y1 = (int)Input.ReadInt();
                        int   X2 = (int)Input.ReadInt();
                        int   Y2 = (int)Input.ReadInt();
                        Color cl = Input.ReadColor();

                        DrawLine(X1, Y1, X2, Y2, cl);
                    }
                };

                while (!Terminated.WaitOne(1000))
                {
                    ;
                }
            }

            Terminate();
        }
コード例 #12
0
        public static void Main(string[] args)
        {
            Initialize();

            WriteLine("What is your name?", C64Colors.LightBlue);
            string       Name = Console.In.ReadLine();
            BinaryOutput Payload;

            WriteLine("Hello " + Name + ".", C64Colors.LightBlue);
            WriteLine("Strings entered below will be seen by everybody running the application.", C64Colors.LightBlue);
            WriteLine("Enter an empty string to close the application.", C64Colors.LightBlue);
            WriteLine(new string('-', ConsoleWidth), C64Colors.LightBlue);

            using (MqttConnection MqttConnection = ConnectToMqttServer("iot.eclipse.org", true, string.Empty, string.Empty))
            {
                WriteLine("<" + MqttConnection.State.ToString() + ">", C64Colors.LightGreen);

                MqttConnection.TrustServer = true;

                MqttConnection.OnConnectionError += (sender, ex) =>
                {
                    WriteLine("Unable to connect:", C64Colors.Red);
                };

                MqttConnection.OnError += (sender, ex) =>
                {
                    WriteLine(ex.Message, C64Colors.Red);
                };

                MqttConnection.OnStateChanged += (sender, state) =>
                {
                    WriteLine("<" + MqttConnection.State.ToString() + ">", C64Colors.LightGreen);

                    if (state == MqttState.Connected)
                    {
                        MqttConnection.SUBSCRIBE("RetroSharp/Examples/Networking/MultiUserChat");

                        Payload = new BinaryOutput();
                        Payload.WriteString(MqttConnection.ClientId);
                        Payload.WriteString(Name);
                        Payload.WriteByte(0);

                        MqttConnection.PUBLISH("RetroSharp/Examples/Networking/MultiUserChat", MqttQualityOfService.AtLeastOne, false, Payload);
                    }
                };

                MqttConnection.OnContentReceived += (sender, Content) =>
                {
                    string ClientId = Content.DataInput.ReadString();
                    if (ClientId != sender.ClientId)
                    {
                        string Author  = Content.DataInput.ReadString();
                        byte   Command = Content.DataInput.ReadByte();

                        switch (Command)
                        {
                        case 0:
                            WriteLine("<" + Author + " enters the room.>", C64Colors.LightGreen);
                            break;

                        case 1:
                            string Text = Content.DataInput.ReadString();
                            WriteLine(Author + ": " + Text, C64Colors.LightBlue);
                            break;

                        case 2:
                            WriteLine("<" + Author + " left the room.>", C64Colors.LightGreen);
                            break;
                        }
                    }
                };

                while (true)
                {
                    string s = Console.In.ReadLine();
                    if (string.IsNullOrEmpty(s))
                    {
                        break;
                    }

                    Payload = new BinaryOutput();
                    Payload.WriteString(MqttConnection.ClientId);
                    Payload.WriteString(Name);
                    Payload.WriteByte(1);
                    Payload.WriteString(s);

                    MqttConnection.PUBLISH("RetroSharp/Examples/Networking/MultiUserChat", MqttQualityOfService.AtLeastOne, false, Payload);
                }

                MqttConnection.UNSUBSCRIBE("RetroSharp/Examples/Networking/MultiUserChat");

                int PacketIdentifier        = 0;
                ManualResetEvent Terminated = new ManualResetEvent(false);

                MqttConnection.OnPublished += (sender, e) =>
                {
                    if (PacketIdentifier == e)
                    {
                        Terminated.Set();
                    }
                };

                Payload = new BinaryOutput();
                Payload.WriteString(MqttConnection.ClientId);
                Payload.WriteString(Name);
                Payload.WriteByte(2);

                PacketIdentifier = MqttConnection.PUBLISH("RetroSharp/Examples/Networking/MultiUserChat", MqttQualityOfService.AtLeastOne, false, Payload);

                Terminated.WaitOne(5000);
            }

            Terminate();
        }
コード例 #13
0
        private async Task <bool> Connection_OnReceived(object Sender, byte[] Buffer, int Offset, int Count)
        {
            PeerConnection Connection = (PeerConnection)Sender;
            Guid           PlayerId;
            IPAddress      PlayerRemoteAddress;
            IPEndPoint     PlayerRemoteEndpoint;

            try
            {
                BinaryInput Input = new BinaryInput(BinaryTcpClient.ToArray(Buffer, Offset, Count));

                PlayerId             = Input.ReadGuid();
                PlayerRemoteAddress  = IPAddress.Parse(Input.ReadString());
                PlayerRemoteEndpoint = new IPEndPoint(PlayerRemoteAddress, Input.ReadUInt16());
            }
            catch (Exception)
            {
                Connection.Dispose();
                return(true);
            }

            Player Player = (Player)Connection.StateObject;

            lock (this.remotePlayersByEndpoint)
            {
                if (!this.playersById.TryGetValue(PlayerId, out Player Player2) || Player2.PlayerId != Player.PlayerId)
                {
                    Connection.Dispose();
                    return(true);
                }

                Player.Connection = Connection;
            }

            Connection.RemoteEndpoint = Player.GetExpectedEndpoint(this.p2pNetwork);

            Connection.OnReceived -= this.Connection_OnReceived;
            Connection.OnReceived += this.Peer_OnReceived;
            Connection.OnSent     += this.Connection_OnSent;

            BinaryOutput Output = new BinaryOutput();

            Output.WriteGuid(this.localPlayer.PlayerId);
            Output.WriteString(this.ExternalAddress.ToString());
            Output.WriteUInt16((ushort)this.ExternalEndpoint.Port);

            await Connection.SendTcp(Output.GetPacket());

            MultiPlayerEnvironmentPlayerInformationEventHandler h = this.OnPlayerConnected;

            if (!(h is null))
            {
                try
                {
                    await h(this, Player);
                }
                catch (Exception ex)
                {
                    Log.Critical(ex);
                }
            }

            return(true);
        }