private Player Deserialize(BinaryInput Input) { IPAddress PublicAddress = IPAddress.Parse(Input.ReadString()); ushort PublicPort = Input.ReadUInt16(); IPEndPoint PublicEndpoint = new IPEndPoint(PublicAddress, PublicPort); IPAddress LocalAddress = IPAddress.Parse(Input.ReadString()); ushort LocalPort = Input.ReadUInt16(); IPEndPoint LocalEndpoint = new IPEndPoint(LocalAddress, LocalPort); Guid PlayerId = Input.ReadGuid(); bool LocalPlayer = PlayerId == this.localPlayer.PlayerId; int i, c = (int)Input.ReadUInt(); KeyValuePair <string, string>[] PlayerMetaInfo = LocalPlayer ? null : new KeyValuePair <string, string> [c]; string Key, Value; for (i = 0; i < c; i++) { Key = Input.ReadString(); Value = Input.ReadString(); if (!LocalPlayer) { PlayerMetaInfo[i] = new KeyValuePair <string, string>(Key, Value); } } if (LocalPlayer) { return(null); } else { return(new Player(PlayerId, PublicEndpoint, LocalEndpoint, PlayerMetaInfo)); } }
private async void MqttConnection_OnContentReceived(object Sender, MqttContent Content) { try { BinaryInput Input = Content.DataInput; byte Command = Input.ReadByte(); switch (Command) { case 0: // Hello string ApplicationName = Input.ReadString(); if (ApplicationName != this.applicationName) { break; } Player Player = this.Deserialize(Input); if (Player is null) { break; } #if LineListener Console.Out.WriteLine("Rx: HELLO(" + Player.ToString() + ")"); #endif IPEndPoint ExpectedEndpoint = Player.GetExpectedEndpoint(this.p2pNetwork); lock (this.remotePlayersByEndpoint) { this.remotePlayersByEndpoint[ExpectedEndpoint] = Player; this.remotePlayerIPs[ExpectedEndpoint.Address] = true; this.playersById[Player.PlayerId] = Player; this.UpdateRemotePlayersLocked(); } MultiPlayerEnvironmentPlayerInformationEventHandler h = this.OnPlayerAvailable; if (h != null) { try { h(this, Player); } catch (Exception ex) { Events.Log.Critical(ex); } } break; case 1: // Interconnect ApplicationName = Input.ReadString(); if (ApplicationName != this.applicationName) { break; } Player = this.Deserialize(Input); if (Player is null) { break; } #if LineListener Console.Out.Write("Rx: INTERCONNECT(" + Player.ToString()); #endif int Index = 0; int i, c; LinkedList <Player> Players = new LinkedList <Player>(); bool LocalPlayerIncluded = false; Player.Index = Index++; Players.AddLast(Player); c = (int)Input.ReadUInt(); for (i = 0; i < c; i++) { Player = this.Deserialize(Input); if (Player is null) { #if LineListener Console.Out.Write("," + this.localPlayer.ToString()); #endif this.localPlayer.Index = Index++; LocalPlayerIncluded = true; } else { #if LineListener Console.Out.Write("," + Player.ToString()); #endif Player.Index = Index++; Players.AddLast(Player); } } #if LineListener Console.Out.WriteLine(")"); #endif if (!LocalPlayerIncluded) { break; } this.mqttConnection.Dispose(); this.mqttConnection = null; lock (this.remotePlayersByEndpoint) { this.remotePlayersByEndpoint.Clear(); this.remotePlayerIPs.Clear(); this.remotePlayersByIndex.Clear(); this.playersById.Clear(); this.remotePlayersByIndex[this.localPlayer.Index] = this.localPlayer; this.playersById[this.localPlayer.PlayerId] = this.localPlayer; foreach (Player Player2 in Players) { ExpectedEndpoint = Player2.GetExpectedEndpoint(this.p2pNetwork); this.remotePlayersByIndex[Player2.Index] = Player2; this.remotePlayersByEndpoint[ExpectedEndpoint] = Player2; this.remotePlayerIPs[ExpectedEndpoint.Address] = true; this.playersById[Player2.PlayerId] = Player2; } this.UpdateRemotePlayersLocked(); } this.State = MultiPlayerState.ConnectingPlayers; await this.StartConnecting(); break; case 2: // Bye ApplicationName = Input.ReadString(); if (ApplicationName != this.applicationName) { break; } Guid PlayerId = Input.ReadGuid(); lock (this.remotePlayersByEndpoint) { if (!this.playersById.TryGetValue(PlayerId, out Player)) { break; } #if LineListener Console.Out.WriteLine("Rx: BYE(" + Player.ToString() + ")"); #endif ExpectedEndpoint = Player.GetExpectedEndpoint(this.p2pNetwork); this.playersById.Remove(PlayerId); this.remotePlayersByEndpoint.Remove(ExpectedEndpoint); this.remotePlayersByIndex.Remove(Player.Index); IPAddress ExpectedAddress = ExpectedEndpoint.Address; bool AddressFound = false; foreach (IPEndPoint EP in this.remotePlayersByEndpoint.Keys) { if (IPAddress.Equals(EP.Address, ExpectedAddress)) { AddressFound = true; break; } } if (!AddressFound) { this.remotePlayerIPs.Remove(ExpectedAddress); } this.UpdateRemotePlayersLocked(); } break; } } catch (Exception ex) { Log.Critical(ex); } }