Example #1
0
		internal PeerConnection(TcpClient TcpConnection, PeerToPeerNetwork Network, IPEndPoint RemoteEndpoint)
		{
			this.network = Network;
			this.remoteEndpoint = RemoteEndpoint;
			this.tcpConnection = TcpConnection;
			this.stream = this.tcpConnection.GetStream();
		}
Example #2
0
 internal PeerConnection(TcpClient TcpConnection, PeerToPeerNetwork Network, IPEndPoint RemoteEndpoint)
 {
     this.network        = Network;
     this.remoteEndpoint = RemoteEndpoint;
     this.tcpConnection  = TcpConnection;
     this.stream         = this.tcpConnection.GetStream();
 }
Example #3
0
		public static void Main(string[] args)
		{
			Initialize();

			try
			{
				using (PeerToPeerNetwork P2PNetwork = new PeerToPeerNetwork("Retro Peer-to-Peer example"))
				{
					P2PNetwork.OnStateChange += (sender, newstate) => Console.Out.WriteLine(newstate.ToString());
					P2PNetwork.OnPeerConnected += (sender, connection) =>
					{
						Console.Out.WriteLine("Client connected from: " + connection.Tcp.Client.RemoteEndPoint.ToString());
					};

					if (!P2PNetwork.Wait())
						throw new Exception("Unable to configure Internet Gateway NAT traversal.");

					Console.Out.WriteLine("External IP Endpoint: " + P2PNetwork.ExternalEndpoint.ToString());

					Console.Out.WriteLine("Press ENTER to try to connect.");
					Console.In.ReadLine();

					using (PeerConnection Client = P2PNetwork.ConnectToPeer(P2PNetwork.ExternalEndpoint))
					{
						Client.Start();
						Console.In.ReadLine();
					}
				}
			}
			catch (Exception ex)
			{
				Console.Out.WriteLine(ex.Message);
				Console.In.ReadLine();
			}

			Terminate();
		}
Example #4
0
		internal void UdpDatagramReceived(PeerToPeerNetwork Sender, UdpDatagramEventArgs e)
		{
			LinkedList<KeyValuePair<ushort, byte[]>> LostPackets = null;
			byte[] FirstPacket = null;
			ushort FirstPacketNr = 0;
			ushort PacketNr;
			byte[] Packet;
			byte[] Data = e.Data;
			int Len = Data.Length;
			int Pos = 0;
			int PacketLen;
			int Offset;
			byte b;

			lock (this.udpReceiveLock)
			{
				while (Pos < Len)
				{
					b = Data[Pos++];
					PacketLen = (b & 127);
					Offset = 7;
					while (Pos < Len && (b & 128) != 0)
					{
						b = Data[Pos++];
						PacketLen |= (b & 127) << Offset;
						Offset += 7;
					}

					if (Pos + 2 > Len)
						break;

					PacketNr = Data[Pos++];
					PacketNr |= (ushort)(Data[Pos++] << 8);

					if (Pos + PacketLen > Len)
						break;

					Packet = new byte[PacketLen];
					Array.Copy(Data, Pos, Packet, 0, PacketLen);
					Pos += PacketLen;

					if ((short)(PacketNr - this.lastReceivedPacket) > 0)
					{
						if (FirstPacket == null)
						{
							FirstPacket = Packet;
							FirstPacketNr = PacketNr;
						}
						else
						{
							if (LostPackets == null)
								LostPackets = new LinkedList<KeyValuePair<ushort, byte[]>>();

							LostPackets.AddFirst(new KeyValuePair<ushort, byte[]>(PacketNr, Packet));	// Reverse order
						}
					}
				}

				if (FirstPacket != null)
					this.lastReceivedPacket = FirstPacketNr;
			}

			BinaryEventHandler h = this.OnReceived;
			if (h != null)
			{
				if (LostPackets != null)
				{
					foreach (KeyValuePair<ushort, byte[]> P in LostPackets)
					{
						try
						{
							h(this, P.Value);
						}
						catch (Exception ex)
						{
							Debug.WriteLine(ex.Message);
							Debug.WriteLine(ex.StackTrace.ToString());
						}
					}
				}

				if (FirstPacket != null)
				{
					try
					{
						h(this, FirstPacket);
					}
					catch (Exception ex)
					{
						Debug.WriteLine(ex.Message);
						Debug.WriteLine(ex.StackTrace.ToString());
					}
				}
			}
		}
		private void p2pNetwork_OnPeerConnected(PeerToPeerNetwork Listener, PeerConnection Peer)
		{
			IPEndPoint Endpoint = (IPEndPoint)Peer.Tcp.Client.RemoteEndPoint;

#if LineListener
			Console.Out.WriteLine("Receiving connection from " + Endpoint.ToString());
#endif

			lock (this.remotePlayersByEndpoint)
			{
				if (!this.remotePlayerIPs.ContainsKey(Endpoint.Address))
				{
					Peer.Dispose();
					return;
				}
			}

			Peer.OnClosed += new EventHandler(Peer_OnClosed);
			Peer.OnReceived += new BinaryEventHandler(Peer_OnReceived);

			BinaryOutput Output = new BinaryOutput();

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

			Peer.SendTcp(Output.GetPacket());
		}
		private void p2pNetwork_OnUdpDatagramReceived(PeerToPeerNetwork Sender, UdpDatagramEventArgs e)
		{
			Player Player;

			lock (this.remotePlayersByEndpoint)
			{
				if (!this.remotePlayersByEndpoint.TryGetValue(e.RemoteEndpoint, out Player))
					return;
			}

			if (Player.Connection != null)
				Player.Connection.UdpDatagramReceived(Sender, e);
		}
		public MultiPlayerEnvironment(string ApplicationName, bool AllowMultipleApplicationsOnSameMachine, 
			string MqttServer, int MqttPort, bool MqttTls, string MqttUserName, string MqttPassword,
			string MqttNegotiationTopic, int EstimatedMaxNrPlayers, Guid PlayerId, params KeyValuePair<string, string>[] PlayerMetaInfo)
		{
			this.localPlayer = new Player(PlayerId, new IPEndPoint(IPAddress.Any, 0), new IPEndPoint(IPAddress.Any, 0), PlayerMetaInfo);
			this.playersById[PlayerId] = this.localPlayer;
			this.applicationName = ApplicationName;

			this.mqttServer = MqttServer;
			this.mqttPort = MqttPort;
			this.mqttTls = MqttTls;
			this.mqttUserName = MqttUserName;
			this.mqttPassword = MqttPassword;
			this.mqttNegotiationTopic = MqttNegotiationTopic;

			this.p2pNetwork = new PeerToPeerNetwork(AllowMultipleApplicationsOnSameMachine ? this.applicationName + " (" + PlayerId.ToString() + ")" : 
				this.applicationName, 0, EstimatedMaxNrPlayers);
			this.p2pNetwork.OnStateChange += this.P2PNetworkStateChange;
			this.p2pNetwork.OnPeerConnected += new PeerConnectedEventHandler(p2pNetwork_OnPeerConnected);
			this.p2pNetwork.OnUdpDatagramReceived += new UdpDatagramEvent(p2pNetwork_OnUdpDatagramReceived);
		}
		/// <summary>
		/// <see cref="IDisposable.Dispose"/>
		/// </summary>
		public void Dispose()
		{
			this.CloseMqtt();

			this.State = MultiPlayerState.Closed;

			if (this.p2pNetwork != null)
			{
				this.p2pNetwork.Dispose();
				this.p2pNetwork = null;
			}

			if (this.ready != null)
			{
				this.ready.Close();
				this.ready = null;
			}

			if (this.error != null)
			{
				this.error.Close();
				this.error = null;
			}

			if (this.remotePlayersByEndpoint != null)
			{
				lock (this.remotePlayersByEndpoint)
				{
					this.playersById.Clear();
					this.remotePlayersByIndex.Clear();

					foreach (Player Player in this.remotePlayersByEndpoint.Values)
					{
						if (Player.Connection != null)
							Player.Connection.Dispose();
					}

					this.remotePlayersByEndpoint.Clear();
					this.remotePlayers = null;
				}
			}
		}