Exemplo n.º 1
0
        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);
            }
        }
Exemplo n.º 2
0
        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");
            }
        }
Exemplo n.º 3
0
        public static NetOutgoingMessage CreatePlayerDisconnectedMessage(NetPeer sender, PlayerConnection player)
        {
            NetOutgoingMessage output = sender.CreateMessage();

            output.Write(PacketType.PlayerDisconnected);
            output.Write(ByteSerializer.ObjectToByteArray(player));
            return(output);
        }