void LocalPlayerTurn()
        {
            MouseState previousMouseState = Mouse.GetState();

            while (true)
            {
                // Update Mouse
                MouseState mouseState = Mouse.GetState();

                // Place marker on mouse left click
                if (mouseState.LeftButton == ButtonState.Pressed)
                {
                    if (previousMouseState.LeftButton == ButtonState.Released)
                    {
                        // Get the position of the mouse in the world
                        Vector2 mouseWorldPos = camera.ScreenToWorld(new Vector2(mouseState.X, mouseState.Y));
                        // Get the square that contains that position
                        Point?sq = grid.SquareContains(mouseWorldPos, gridLayout);
                        // If that square is valid, then claim it
                        if (sq != null)
                        {
                            // If the claim was successful
                            if (grid.ClaimSquare((Point)sq, ActivePlayer))
                            {
                                // Send claim square message
                                NetOutgoingMessage outMsg = PacketFactory.CreateClaimSquareMessage(peer, localPlayer, sq.Value.X, sq.Value.Y);
                                peer.SendMessage(outMsg, peer.Connections, NetDeliveryMethod.ReliableOrdered, 0);

                                return;
                            }
                        }
                    }
                }

                // Update previous mouse state
                previousMouseState = mouseState;
            }
        }
        void ActivityCheck()
        {
            // If no game is active
            if (!gameActive)
            {
                // Ask user for command
                string s = ConsoleManager.WaitGetPriorityInput("Input command: ", false);
                if (Enum.TryParse(s, true, out Commands command))
                {
                    switch (command)
                    {
                    case Commands.List:
                        ListFoundHosts();
                        break;

                    case Commands.Join:
                        if (isHost)
                        {
                            Console.WriteLine("host cannot join other hosts");
                        }
                        else
                        {
                            ConnectToHost(GetIPAddress());
                        }
                        break;

                    case Commands.Discover:
                        DiscoverHosts();
                        break;

                    case Commands.Help:
                    case Commands.Commands:
                        // List commands
                        Console.WriteLine("Commands:");
                        foreach (string c in Enum.GetNames(typeof(Commands)))
                        {
                            Console.WriteLine(c);
                        }
                        break;

                    //case Commands.Ready:
                    //    if (ready) Console.WriteLine("You are already ready.");
                    //    else
                    //    {
                    //        ready = true;
                    //        Console.WriteLine("Ready!");
                    //    }
                    //    if (StartGame()) Console.WriteLine("Starting game.");
                    //    else Console.WriteLine("Waiting for other players.");
                    //    break;

                    case Commands.Create:
                        if (isHost)
                        {
                            break;
                        }
                        // Create grid
                        grid    = Grid.GetGameSettingsInput();
                        action += confcam;
                        // Create local player TODO: remake
                        selfTurnIndex = 0;
                        localPlayer   = Player.GetRandomisedPlayer();
                        players.Add(localPlayer);
                        isHost = true;
                        Console.WriteLine("hosting game");
                        break;

                    case Commands.Start:
                        if (!isHost)
                        {
                            break;
                        }
                        if (gameActive)
                        {
                            break;
                        }
                        if (peer.Connections.Count + 1 < grid.minPlayers)
                        {
                            Console.WriteLine("Not enough players to start");
                            break;
                        }

                        peer.SendMessage(PacketFactory.CreatePlayerAssignmentMessage(peer, peers, localPlayer, grid), peer.Connections, NetDeliveryMethod.ReliableOrdered, 0);
                        StartGame();
                        break;

                    default:
                        Console.WriteLine("Unrecognized command");
                        break;
                    }
                }
                else
                {
                    Console.WriteLine("Unrecognized command");
                }
            }
            else
            {
                Thread.Sleep(1000);
            }
        }
        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);
            }
        }