Example #1
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;
        }