private void ReadMessages()
        {
            NetIncomingMessage inMsg;

            if ((inMsg = client.ReadMessage()) != null)
            {
#if DEBUG
                System.Console.WriteLine($"msg: {inMsg.MessageType}");
#endif
                switch (inMsg.MessageType)
                {
                case NetIncomingMessageType.Data:
                    // Handle custom messages
                    Process(inMsg);
                    break;

                case NetIncomingMessageType.DiscoveryResponse:
                    // Check if server already is found
                    if (gameServers.ContainsKey(inMsg.SenderEndPoint))
                    {
                        break;
                    }
                    // Parse server status data
                    FoundGame fs = ByteSerializer.ByteArrayToObject <FoundGame>(inMsg.Data);
                    // Add server to list
                    gameServers.Add(inMsg.SenderEndPoint, fs);

                    System.Console.WriteLine($"Discovered server at: {inMsg.SenderEndPoint}");
                    break;

                case NetIncomingMessageType.StatusChanged:
                    // handle connection status messages
                    switch (inMsg.SenderConnection.Status)
                    {
                    case NetConnectionStatus.Connected:
                    case NetConnectionStatus.Disconnecting:
                    case NetConnectionStatus.Disconnected:
                        System.Console.WriteLine($"{inMsg.SenderConnection.Status} from {inMsg.SenderConnection.RemoteEndPoint}");
                        break;
                    }

                    break;

                case NetIncomingMessageType.DebugMessage:
                    // handle debug messages (only received when compiled in DEBUG mode)
                    System.Console.WriteLine(inMsg.ReadString());
                    break;
                }
            }
        }
        private void Process(NetIncomingMessage inMsg)
        {
            // Read packet type
            PacketType packetType = (PacketType)inMsg.ReadUInt16();

#if DEBUG
            System.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);
                break;

            case PacketType.EndGame:
                EndGame();
                gameActive = false;
                break;

            case PacketType.PlayerConnected:
                // Add player to players
                Player newPlayer = ByteSerializer.ByteArrayToObject <Player>(inMsg.ReadBytes(inMsg.Data.Length - 2));
                players.Add(newPlayer);
                break;

            case PacketType.PlayerDisconnected:
                // Add player to players
                Player player = ByteSerializer.ByteArrayToObject <Player>(inMsg.ReadBytes(inMsg.Data.Length - 2));
                players.Remove(player);
                break;

            case PacketType.NextTurn:
                string n = inMsg.ReadString();
                System.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 += ConfigureCamera;
                break;

            case PacketType.StartGame:
                gameActive = true;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(PacketType), "unknown packet type");
            }
        }
Ejemplo n.º 3
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);
            }
        }
Ejemplo n.º 4
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");
            }
        }
Ejemplo n.º 5
0
        public void Run()
        {
            Running = true;
            Console.WriteLine("Starting network loop");
            while (Running)
            {
                server.MessageReceivedEvent.WaitOne(); // Q: should we wait every loop or only the first?
                NetIncomingMessage inMsg;
                while ((inMsg = server.ReadMessage()) != null)
                {
                    Console.WriteLine($"msg {inMsg.MessageType}");
                    switch (inMsg.MessageType)
                    {
                    case NetIncomingMessageType.Data:
                        Process(inMsg);
                        break;

                    case NetIncomingMessageType.DebugMessage:
                        Console.WriteLine(inMsg.ReadString());
                        break;

                    case NetIncomingMessageType.StatusChanged:
                        Console.WriteLine(inMsg.SenderConnection.Status);
                        switch (inMsg.SenderConnection.Status)
                        {
                        case NetConnectionStatus.Connected:
                            PlayerConnection c = GetPlayerConnection(inMsg.SenderConnection);
                            Console.WriteLine($"{c.player.Name} has connected from {c.connection.RemoteEndPoint}.");
                            SendGameData(c);
                            // Check if there are enough players to start the game
                            if (clients.Count >= grid.minPlayers)
                            {
                                // TODO: start voting to start game
                                // Start game
                                server.SendToAll(PacketFactory.CreateStartGameMessage(server), NetDeliveryMethod.ReliableOrdered);
                            }

                            break;

                        case NetConnectionStatus.Disconnected:
                            PlayerConnection pc = GetPlayerConnection(inMsg.SenderConnection);
                            Console.WriteLine($"{pc.player.Name} has disconnected.");
                            PlayerDisconnect(pc);
                            break;
                        }

                        break;

                    case NetIncomingMessageType.ConnectionApproval:
                        // Compare existing connections
                        if ((from client in clients where client.connection == inMsg.SenderConnection select client).Count() != 0)
                        {
                            // If there is an existing connection, reject connection
                            string reason = "Connection already exists";
                            Console.WriteLine($"Player failed to connect: {reason}");
                            inMsg.SenderConnection.Deny(reason);
                            break;
                        }

                        // Check max players
                        if (clients.Count < grid.maxPlayers == false)
                        {
                            string reason = "Max players reached";
                            Console.WriteLine($"Player failed to connect: {reason}");
                            inMsg.SenderConnection.Deny(reason);
                            break;
                        }

                        // Parse player data
                        Player newPlayer = (Player)ByteSerializer.ByteArrayToObject(inMsg.Data);

                        // Compare with existing players
                        // If name or shape and drawingColor already is used
                        if ((from client in clients
                             where string.Equals(newPlayer.Name, client.player.Name, StringComparison.CurrentCultureIgnoreCase) ||     //TODO: refactor into two where
                             newPlayer.Shape == client.player.Shape && newPlayer.Color == client.player.Color
                             select client).Count() != 0)
                        {
                            // If there is a match, reject connection
                            string reason = "Player already exists";
                            Console.WriteLine($"Player failed to connect: {reason}");
                            inMsg.SenderConnection.Deny(reason);
                            break;
                        }

                        // If no match found, accept connection
                        PlayerConnect(new PlayerConnection(inMsg.SenderConnection, (Player)ByteSerializer.ByteArrayToObject(inMsg.Data)));
                        inMsg.SenderConnection.Approve();
                        // Send game data
                        break;

                    case NetIncomingMessageType.DiscoveryRequest:     // TODO: send found server data
                        Console.WriteLine("Discovery Request from Client");
                        NetOutgoingMessage outMsg = server.CreateMessage();
                        FoundServer        v      = new FoundServer(grid.sizeX, grid.sizeY, grid.maxPlayers, grid.minPlayers, clients.Count);
                        outMsg.Write(ByteSerializer.ObjectToByteArray(v));
                        server.SendDiscoveryResponse(outMsg, inMsg.SenderEndPoint);
                        break;

                    default:
                        Console.WriteLine($"Unhandled message received of type: {inMsg.MessageType}");
                        break;
                    }

                    server.Recycle(inMsg);
                }
            }

            Running = false;
        }