void ReadMessage() { NetIncomingMessage inMsg; if ((inMsg = peer.ReadMessage()) != null) { #if DEBUG Console.WriteLine($"msg: {inMsg.MessageType}"); #endif switch (inMsg.MessageType) { case NetIncomingMessageType.Data: // Handle custom messages Process(inMsg); break; case NetIncomingMessageType.DiscoveryResponse: try { // Parse game data FoundGame fg = ByteSerializer.ByteArrayToObject <FoundGame>(inMsg.Data); // skip if game is already discovered / up to date if (DiscoveredHosts.Contains(new KeyValuePair <IPEndPoint, FoundGame>(inMsg.SenderEndPoint, fg))) { break; } // Add server to list DiscoveredHosts.Add(inMsg.SenderEndPoint, fg); Console.WriteLine($"Discovered host at: {inMsg.SenderEndPoint}"); } catch { } break; case NetIncomingMessageType.DiscoveryRequest: if (isHost && !gameActive) { peer.SendDiscoveryResponse(PacketFactory.CreateFoundGameMessage(peer, FoundGame.CreateFromGrid(grid, peer.ConnectionsCount + 1)), inMsg.SenderEndPoint); } break; case NetIncomingMessageType.StatusChanged: // handle connection status messages if (isHost) { switch (inMsg.SenderConnection.Status) { case NetConnectionStatus.Connected: if (isHost) { PlayerConnection np = new PlayerConnection(Player.GetRandomisedPlayer(), inMsg.SenderConnection.RemoteEndPoint); peers.Add(np); players.Add(np.player); } Console.WriteLine($"{inMsg.SenderConnection.RemoteEndPoint} {inMsg.SenderConnection.Status}"); Console.WriteLine($"{peers.Count + 1} players currently connected"); break; case NetConnectionStatus.Disconnected: if (isHost) { PlayerConnection p = (from peer in peers where Equals(inMsg.SenderConnection.RemoteEndPoint, peer.ipEndPoint) select peer).Single(); peers.Remove(p); players.Remove(p.player); } Console.WriteLine($"{inMsg.SenderConnection.RemoteEndPoint} {inMsg.SenderConnection.Status}"); Console.WriteLine($"{peers.Count + 1} players currently connected"); break; } } else { switch (inMsg.SenderConnection.Status) { case NetConnectionStatus.Connected: case NetConnectionStatus.Disconnected: Console.WriteLine($"{inMsg.SenderConnection.RemoteEndPoint} {inMsg.SenderConnection.Status}"); Console.WriteLine($"{peer.Connections.Count + 1} players currently connected"); break; } } break; case NetIncomingMessageType.ConnectionApproval: if (isHost) { if (gameActive) { inMsg.SenderConnection.Deny("Game already started"); break; } // not max players if (grid.maxPlayers >= peer.ConnectionsCount + 1) { inMsg.SenderConnection.Approve(); } else { inMsg.SenderConnection.Deny("Game is full"); } } else { inMsg.SenderConnection.Approve(); // TODO: Validate with gameID } break; case NetIncomingMessageType.DebugMessage: case NetIncomingMessageType.WarningMessage: Console.WriteLine(inMsg.ReadString()); break; default: throw new ArgumentOutOfRangeException(); } peer.Recycle(inMsg); } }
void Process(NetIncomingMessage inMsg) { // Read packet type PacketType packetType = (PacketType)inMsg.ReadUInt16(); #if DEBUG Console.WriteLine("type: " + packetType); #endif switch (packetType) { case PacketType.ClaimSquare: // Parse parameters string playerName = inMsg.ReadString(); Player pl = (from p in players where playerName == p.Name select p).Single(); int x = inMsg.ReadInt32(); int y = inMsg.ReadInt32(); // Claim square grid.ClaimSquare(new Point(x, y), pl); // Start next turn NextTurn(); CheckLocalTurn(); break; case PacketType.PlayerConnected: // connect PlayerConnection newPlayer = ByteSerializer.ByteArrayToObject <PlayerConnection>(inMsg.ReadBytes(inMsg.Data.Length - 2)); peer.Connect(newPlayer.ipEndPoint); break; case PacketType.PlayerDisconnected: // disconnect PlayerConnection player = ByteSerializer.ByteArrayToObject <PlayerConnection>(inMsg.ReadBytes(inMsg.Data.Length - 2)); (from connection in peer.Connections where Equals(connection.RemoteEndPoint, player.ipEndPoint) select connection).Single().Disconnect("BYE"); break; case PacketType.NextTurn: string n = inMsg.ReadString(); Console.WriteLine($"It is {n}´s turn."); if (localPlayer.Name == n) { Thread t = new Thread(LocalPlayerTurn) { Name = nameof(LocalPlayerTurn) }; t.Start(); } break; case PacketType.FailedClaimSquare: Thread tr = new Thread(LocalPlayerTurn) { Name = nameof(LocalPlayerTurn) }; tr.Start(); break; case PacketType.GridData: grid = ByteSerializer.ByteArrayToObject <Grid>(inMsg.ReadBytes(inMsg.Data.Length - 2)); action += confcam; break; case PacketType.Ready: // Set player to ready peers.Find(p => Equals(p.ipEndPoint, inMsg.SenderConnection.RemoteEndPoint)).isReady = true; // Start game if all players are ready if (StartGame()) { Console.WriteLine("Starting game."); } break; case PacketType.PlayerAssignment: // Read data int numberOfBytes = inMsg.ReadInt32(); List <PlayerConnection> newPlayers = ByteSerializer.ByteArrayToObject <List <PlayerConnection> >(inMsg.ReadBytes(numberOfBytes)); Grid newGrid = ByteSerializer.ByteArrayToObject <Grid>(inMsg.ReadBytes(inMsg.Data.Length - inMsg.PositionInBytes)); // Set new grid grid = newGrid; action += confcam; // set players players = new List <Player>(newPlayers.Count); peers = new List <PlayerConnection>(newPlayers.Count - 1); for (int i = 0; i < newPlayers.Count; i++) { try { // Add peers, not self or host //find a corresponding connection (from connection in peer.Connections where Equals(newPlayers[i].ipEndPoint, connection.RemoteEndPoint) select connection).Single(); peers.Add(newPlayers[i]); players.Add(newPlayers[i].player); } catch (Exception e) { // Sync failed, found invalid/no player/connection // Check host if (Equals(newPlayers[i].ipEndPoint, HostIdentIP)) { players.Add(newPlayers[i].player); peers.Add(new PlayerConnection(newPlayers[i].player, peer.Connections[0].RemoteEndPoint)); continue; } // Check self string pip = NetworkHelper.GetPublicIP(); string iip = NetworkHelper.GetLocalIPAddress(); if (Equals(newPlayers[i].ipEndPoint, new IPEndPoint(IPAddress.Parse(pip), peer.Port)) || Equals(newPlayers[i].ipEndPoint, new IPEndPoint(IPAddress.Parse(iip), peer.Port))) { localPlayer = newPlayers[i].player; selfTurnIndex = i; players.Add(newPlayers[i].player); continue; } // Not self either Console.WriteLine(e); throw; } } StartGame(); break; default: throw new ArgumentOutOfRangeException(nameof(PacketType), "unknown packet type"); } }
public static NetOutgoingMessage CreatePlayerDisconnectedMessage(NetPeer sender, PlayerConnection player) { NetOutgoingMessage output = sender.CreateMessage(); output.Write(PacketType.PlayerDisconnected); output.Write(ByteSerializer.ObjectToByteArray(player)); return(output); }