private void CommandRecieved(object sender, CommandEventArgs e)
        {
            if (e.Command.CommandType == CommandType.UserDataInform)
            {
                client.Wins = int.Parse(e.Command.Data.Split(':')[0]);
                client.Losses = int.Parse(e.Command.Data.Split(':')[1]);
            }
            if (e.Command.CommandType == CommandType.UsernameRequest)
            {
                if (e.Command.Data.ToLower() == "false")
                {
                    client.SignOut();
                    MessageBox.Show("Username already in use!", "Invalid Username", MessageBoxButtons.OK);
                    client.Disconnect();

                }
                else if (e.Command.Data.ToLower() == "true")
                {
                    client.CommandRecieved -= CommandRecieved;
                    if (InvokeRequired)
                    {
                        BeginInvoke(new MethodInvoker(delegate
                      {
                          chat = new ChatForm(ref client, this);
                          chat.Show();
                          Hide();
                      }));
                    }
                    else
                    {
                        chat = new ChatForm(ref client, this);
                        chat.Show();
                        Hide();
                    }
                }
            }
        }
        private void CommandRecieved(object sender, CommandEventArgs e)
        {
            if (e.Command.SenderName != client.Username)
            {
                //Recieving a chat message
                if (e.Command.CommandType == CommandType.Message)
                {
                    rtbChat.AppendText(e.Command.SenderName.ToString() + ": " + e.Command.Data);
                }
                //Notify of user connecting
                if (e.Command.CommandType == CommandType.UserConnected)
                {
                    clientList.Add(e.Command.Data);
                    string username = e.Command.Data.Split(':')[2];
                    rtbChat.AppendText(username + " has connected." + Environment.NewLine);
                    lstUsers.Items.Add(username);
                }
                //Notify of user disconnecting
                if (e.Command.CommandType == CommandType.UserDisconnected)
                {
                    string username = e.Command.Data.Split(':')[2];
                    for (int i = 0; i < lstUsers.Items.Count; i++)
                    {
                        if ((string)lstUsers.Items[i] == username)
                        {
                            lstUsers.Items.RemoveAt(i);
                            break;
                        }
                    }
                    for (int i = 0; i < clientList.Count; i++)
                    {
                        if (clientList[i] == e.Command.Data)
                        {
                            clientList.RemoveAt(i);
                        }
                    }
                    rtbChat.AppendText(username + " has disconnected." + Environment.NewLine);
                }
            }
            //Update client list when recieved - Outside self message check to enable server to inform client of it's existence
            if (e.Command.CommandType == CommandType.ClientListRequest)
            {
                string[] clients = Array.ConvertAll(e.Command.Data.Split(','), p => p.Trim());
                lstUsers.Items.Clear();
                for (int i = 0; i < clients.Length; i++)
                {
                    if (clients[i] != "")
                    {
                        string username = clients[i].Split(':')[2];
                        lstUsers.Items.Add(username);
                        clientList.Add(clients[i]);
                    }
                }
            }

            if (e.Command.CommandType == CommandType.ChallengeRequest)
            {
                if (activeChallenge == false)
                {
                    string data = e.Command.Data;
                    DialogResult dr = MessageBox.Show(e.Command.SenderName + " has challenged you!" + Environment.NewLine 
                        + "Wins: " + int.Parse(data.Split(':')[0]) + Environment.NewLine
                        + "Losses: " + int.Parse(data.Split(':')[1]) + Environment.NewLine
                        + "Do You accept?", "You have been challenged!", MessageBoxButtons.YesNo);
                    if (dr == DialogResult.Yes)
                    {
                        activeChallenge = true;
                        //Accept the request
                        Command cmd = new Command(CommandType.ChallengeResponse, e.Command.SenderIP, "true");
                        cmd.TargetPort = e.Command.SenderPort;
                        cmd.SenderIP = client.IP;
                        cmd.SenderName = client.Username;
                        cmd.SenderPort = client.Port;
                        client.SendCommand(cmd);
                    }
                    else
                    {
                        //Reject the request
                        Command cmd = new Command(CommandType.ChallengeResponse, e.Command.SenderIP, "false");
                        cmd.TargetPort = e.Command.SenderPort;
                        cmd.SenderIP = client.IP;
                        cmd.SenderName = client.Username;
                        cmd.SenderPort = client.Port;
                        client.SendCommand(cmd);
                    }
                }
            }

            if (e.Command.CommandType == CommandType.ChallengeResponse)
            {
                if (e.Command.Data.ToString().ToLower() == "true")
                {
                    //Challenge Accepted
                    Command cmd = new Command(CommandType.GameStartRequest, client.ServerIP, e.Command.SenderIP + ":" + e.Command.SenderPort);
                    cmd.TargetPort = client.ServerPort;
                    cmd.SenderIP = client.IP;
                    cmd.SenderPort = client.Port;
                    cmd.SenderName = client.Username;
                    client.SendCommand(cmd);
                }
                else
                {
                    //challenge Rejected
                    activeChallenge = false;
                    rtbChat.AppendText("Your game challenge was rejected." + Environment.NewLine);
                }
            }

            if (e.Command.CommandType == CommandType.GameIDInform)
            {
                activeGameID = int.Parse(e.Command.Data);
                if (InvokeRequired)
                {
                    BeginInvoke(new MethodInvoker(delegate
                    {
                        gameForm = new BattleshipGameForm(ref client, activeGameID);
                        gameForm.Show();
                        gameForm.FormClosed += new FormClosedEventHandler(GameForm_Closed);
                    }));
                }
                else
                {
                    gameForm = new BattleshipGameForm(ref client, activeGameID);
                    gameForm.Show();
                    gameForm.FormClosed += new FormClosedEventHandler(GameForm_Closed);

                }
            }

            if (e.Command.CommandType == CommandType.UserDataInform)
            {
                ConfirmChallenge(e.Command);
            }
        }
        public void GameCommandRecieved(object sender, CommandEventArgs e)
        {
            if (e.Command.CommandType == CommandType.GameStartInform)
            {
                if (e.Command.Data.ToLower() == "true")
                {
                    myTurn = true;
                    rtbLog.AppendText("It is your turn to shoot first, please select a position within enemy waters" + Environment.NewLine);
                    //btnFire.Enabled = true;
                }
                else if (e.Command.Data.ToLower() == "false")
                {
                    myTurn = false;
                    btnFire.Enabled = false;
                    rtbLog.AppendText("It is your opponent's turn to shoot first. Waiting for response..." + Environment.NewLine);

                }
            }
            if (e.Command.CommandType == CommandType.GameShotResult)
            {
                if (e.Command.Data.ToLower().Equals("hit"))
                {
                    //Deal with hits
                    rtbLog.AppendText("Your shot hit!" + Environment.NewLine);
                    pictureBox = (PictureBox)EnemyGrid.GetControlFromPosition(gridTarget.x, gridTarget.y);
                    pictureBox.Image = Properties.Resources.ShipHit;
                    pictureBox.Tag = "ShipHit";
                    btnFire.Enabled = false;
                    myTurn = false;
                    rtbLog.AppendText("It is your opponent's turn to shoot." + Environment.NewLine);

                }
                else if (e.Command.Data.ToLower().Equals("miss"))
                {
                    //deal with misses
                    rtbLog.AppendText("Your shot missed!" + Environment.NewLine);
                    pictureBox = (PictureBox)EnemyGrid.GetControlFromPosition(gridTarget.x, gridTarget.y);
                    pictureBox.Image = Properties.Resources.WaterMiss;
                    pictureBox.Tag = "WaterMiss";
                    btnFire.Enabled = false;
                    myTurn = false;
                    rtbLog.AppendText("It is your opponent's turn to shoot." + Environment.NewLine);
                }
            }
            if (e.Command.CommandType == CommandType.GameHitInform)
            {
                rtbLog.AppendText("One of your ships has been hit!" + Environment.NewLine);
                gridTarget.x = int.Parse(e.Command.Data.Split(',')[0]);
                gridTarget.y = int.Parse(e.Command.Data.Split(',')[1]);
                pictureBox = (PictureBox)PlayerGrid.GetControlFromPosition(gridTarget.x, gridTarget.y);
                pictureBox.Image = Properties.Resources.ShipHit;
                myTurn = true;
                rtbLog.AppendText("It is your turn to shoot." + Environment.NewLine);

            }
            if (e.Command.CommandType == CommandType.GameMissInform)
            {
                rtbLog.AppendText("Your opponent missed your fleet!" + Environment.NewLine);
                gridTarget.x = int.Parse(e.Command.Data.Split(',')[0]);
                gridTarget.y = int.Parse(e.Command.Data.Split(',')[1]);
                pictureBox = (PictureBox)PlayerGrid.GetControlFromPosition(gridTarget.x, gridTarget.y);
                pictureBox.Image = Properties.Resources.WaterMiss;
                myTurn = true;
                rtbLog.AppendText("It is your turn to shoot." + Environment.NewLine);
            }
            if (e.Command.CommandType == CommandType.GameOverInform)
            {
                if (e.Command.Data.ToLower() == "win")
                {
                    Command cmdInform = new Command(CommandType.GameOverInform, client.ServerIP, gameID + ":" + "win");
                    cmdInform.TargetPort = client.ServerPort;
                    cmdInform.SenderIP = client.IP;
                    cmdInform.SenderPort = client.Port;
                    cmdInform.SenderName = client.Username;
                    client.Wins++;
                    client.SendCommand(cmdInform);
                    MessageBox.Show("Congratulations " + client.Username + " you have won the game!" + Environment.NewLine + "Closing this dialog will close the game window.", "Winner!", MessageBoxButtons.OK);
                    Close();
                }
                else if (e.Command.Data.ToLower() == "loss")
                {
                    Command cmdInform = new Command(CommandType.GameOverInform, client.ServerIP, gameID + ":" + "loss");
                    cmdInform.TargetPort = client.ServerPort;
                    cmdInform.SenderIP = client.IP;
                    cmdInform.SenderPort = client.Port;
                    cmdInform.SenderName = client.Username;
                    client.Losses++;
                    client.SendCommand(cmdInform);
                    MessageBox.Show("Sorry " + client.Username + " you have lost the game." + Environment.NewLine + "Closing this dialog will close the game window.", "Game Lost", MessageBoxButtons.OK);
                    Close();

                }
            }
        }
 protected virtual void OnCommandRecieved(CommandEventArgs e)
 {
     if (CommandRecieved != null)
         CommandRecieved(this, e);
 }
        public void CommandRecieved(CommandEventArgs e)
        {
            int clientNo = -1;
            if (clients[0].Username == e.Command.SenderName)
            {
                clientNo = 0;
            }
            else if (clients[1].Username == e.Command.SenderName)
            {
                clientNo = 1;
            }
            if (e.Command.CommandType == CommandType.GameShipRequest)
            {
                ParseShipData(e.Command.Data.Split(':')[1], clientNo);
                PlaceShips(clientNo);
                if (client1Board.setupComplete == true && client2Board.setupComplete == true)
                {
                    Command cmd = new Command(CommandType.GameStartInform, e.Command.SenderIP);
                    cmd.SenderName = "server";
                    cmd.TargetIP = clients[0].IP;
                    cmd.TargetPort = clients[0].Port;
                    cmd.Data = "true";
                    SendCommandToClient(cmd);
                    Command cmd2 = new Command(CommandType.GameStartInform, clients[1].IP);
                    cmd2.SenderName = "server";
                    cmd2.TargetPort = clients[1].Port;
                    cmd2.Data = "false";
                    SendCommandToClient(cmd2);
                }
            }
            if (e.Command.CommandType == CommandType.GameShotRequest)
            {
                if (CheckForHits(clientNo, e.Command.Data.Split(':')[1]))
                {
                    Command cmd = new Command(CommandType.GameShotResult, clients[clientNo].IP);
                    cmd.Data = "hit";
                    cmd.TargetPort = clients[clientNo].Port;
                    cmd.SenderName = "server";
                    SendCommandToClient(cmd);
                    Command cmd2 = new Command(CommandType.GameHitInform, e.Command.TargetIP);
                    cmd2.SenderName = "server";
                    cmd2.Data = e.Command.Data.Split(':')[1];
                    if (clientNo == 0)
                    {
                        cmd2.TargetIP = clients[1].IP;
                        cmd2.TargetPort = clients[1].Port;
                    }
                    else if (clientNo == 1)
                    {
                        cmd2.TargetIP = clients[0].IP;
                        cmd2.TargetPort = clients[0].Port;
                    }
                    SendCommandToClient(cmd2);

                    //Check is any ships remain in each board, if a board has no ships remaining then the game is over and that client loses
                    if (client1Board.AreShipsRemaining() == false)
                    {
                        Command winCmd = new Command(CommandType.GameOverInform, clients[1].IP, "win");
                        winCmd.TargetPort = clients[1].Port;
                        clients[1].Wins++;
                        SendCommandToClient(winCmd);
                        Command lossCmd = new Command(CommandType.GameOverInform, clients[0].IP, "loss");
                        lossCmd.TargetPort = clients[0].Port;
                        clients[0].Losses++;
                        SendCommandToClient(lossCmd);
                    }
                    else if (client2Board.AreShipsRemaining() == false)
                    {
                        Command winCmd = new Command(CommandType.GameOverInform, clients[0].IP, "win");
                        winCmd.TargetPort = clients[0].Port;
                        clients[0].Wins++;
                        SendCommandToClient(winCmd);
                        Command lossCmd = new Command(CommandType.GameOverInform, clients[1].IP, "loss");
                        lossCmd.TargetPort = clients[1].Port;
                        clients[1].Losses++;
                        SendCommandToClient(lossCmd);
                    }
                }
                else
                {
                    Command cmd = new Command(CommandType.GameShotResult, clients[clientNo].IP);
                    cmd.Data = "miss";
                    cmd.TargetPort = clients[clientNo].Port;
                    cmd.SenderName = "server";
                    SendCommandToClient(cmd);
                    Command cmd2 = new Command(CommandType.GameMissInform, e.Command.TargetIP);
                    cmd2.Data = e.Command.Data.Split(':')[1];
                    cmd2.SenderName = "server";


                    if (clientNo == 0)
                    {
                        cmd2.TargetIP = clients[1].IP;
                        cmd2.TargetPort = clients[1].Port;
                    }
                    else if (clientNo == 1)
                    {
                        cmd2.TargetIP = clients[0].IP;
                        cmd2.TargetPort = clients[0].Port;
                    }
                    SendCommandToClient(cmd2);
                }
            }
        }
        private void CommandRecieved(object sender, CommandEventArgs e)
        {
            //When a user connects set their client username
            if (e.Command.CommandType == CommandType.UserConnected)
            {
                string username = e.Command.Data.Split(':')[2];
                Console.WriteLine("Checking for : " + username);
                bool nameAvailability = CheckUsernameAvailability(e.Command.SenderIP, e.Command.SenderPort, username);
                if (nameAvailability)
                {
                    string data = CheckForClientData(username);

                    SetClientUsername(e.Command.SenderIP, e.Command.SenderPort, username);
                    SetClientData(e.Command.SenderIP, e.Command.SenderPort, data);
                    SendUserStats(e.Command.SenderIP, e.Command.SenderPort, data);
                    AnswerUsernameRequest(e.Command.SenderIP, e.Command.SenderPort, nameAvailability);
                    e.Command.Data += (":" + data);
                    SendCommandToAll(e.Command);
                }
                else if (nameAvailability == false)
                {
                    AnswerUsernameRequest(e.Command.SenderIP, e.Command.SenderPort, nameAvailability);
                }

            }

            //User asks to disconnect
            if (e.Command.CommandType == CommandType.UserDisconnectRequest)
            {
                int index = FindClientID(e.Command.SenderIP, e.Command.SenderPort);
                string clientDetails = clientList[index].IP.ToString() + ":" + clientList[index].Port.ToString() + ":" + clientList[index].Username;
                Console.WriteLine("User {0}:{1} ({2}) has disconnected ({3}/{4})", e.Command.SenderIP, e.Command.SenderPort, clientList[index].Username, DateTime.Now.ToShortTimeString(), DateTime.Now.ToLongDateString());
                clientList[index].Disconnect();
                clientList.RemoveAt(index);
                Command cmd = new Command(CommandType.UserDisconnected, IPAddress.Broadcast);
                cmd.SenderName = e.Command.SenderName;
                cmd.SenderIP = e.Command.SenderIP;
                cmd.SenderPort = e.Command.SenderPort;
                cmd.Data = clientDetails;
                SendCommandToAll(cmd);

            }

            //Reply to client list request
            if (e.Command.CommandType == CommandType.ClientListRequest)
            {
                SendClientList(e.Command.SenderIP, e.Command.SenderPort);
            }

            //Sends message commands to all connected clients
            if (e.Command.CommandType == CommandType.Message)
            {
                if (e.Command.TargetIP.Equals(IPAddress.Broadcast))
                {
                    SendCommandToAll(e.Command);
                }
                else
                {
                    SendCommandToClient(e.Command);
                }
            }

            //Pass challenge request to challenged user
            if (e.Command.CommandType == CommandType.ChallengeRequest)
            {
                int challengerID = FindClientID(e.Command.SenderIP, e.Command.SenderPort);
                e.Command.Data = clientList[challengerID].Wins + ":" + clientList[challengerID].Losses;
                SendCommandToClient(e.Command);
            }

            //Pass challenge response to challenger
            if (e.Command.CommandType == CommandType.ChallengeResponse)
            {
                SendCommandToClient(e.Command);
            }

            //Handle game start request
            if (e.Command.CommandType == CommandType.GameStartRequest)
            {
                IPAddress client2IP = IPAddress.Parse(e.Command.Data.Split(':')[0]);
                int client2Port = int.Parse(e.Command.Data.Split(':')[1]);
                int client1ID = FindClientID(e.Command.SenderIP, e.Command.SenderPort);
                int client2ID = FindClientID(client2IP, client2Port);
                BattleshipsGame game = new BattleshipsGame(clientList[client1ID], clientList[client2ID]);

                Command cmd = new Command(CommandType.GameIDInform, e.Command.SenderIP, activeGames.Count.ToString());
                cmd.SenderName = "server";
                cmd.SenderIP = serverIP;
                cmd.SenderPort = serverPort;
                cmd.TargetPort = e.Command.SenderPort;
                SendCommandToClient(cmd);

                cmd.TargetIP = client2IP;
                cmd.TargetPort = client2Port;
                SendCommandToClient(cmd);

                activeGames.Add(game);
            }

            //Handle ShipPlacementRequest
            if (e.Command.CommandType == CommandType.GameShipRequest)
            {
                activeGames[int.Parse(e.Command.Data.Split(':')[0])].CommandRecieved(e);
            }
            //Handle GameShotRequest
            if (e.Command.CommandType == CommandType.GameShotRequest)
            {
                activeGames[int.Parse(e.Command.Data.Split(':')[0])].CommandRecieved(e);
            }
            //Handle GameOverInform
            if (e.Command.CommandType == CommandType.GameOverInform)
            {
                activeGames[int.Parse(e.Command.Data.Split(':')[0])].GameOverMessageCount++;
                if (activeGames[int.Parse(e.Command.Data.Split(':')[0])].GameOverMessageCount >= 2)
                {
                    PostGameStatisticsUpdate(activeGames[int.Parse(e.Command.Data.Split(':')[0])].Clients);
                    activeGames.RemoveAt(int.Parse(e.Command.Data.Split(':')[0]));
                    GC.Collect();
                }
            }

            //Handle user data request
            if (e.Command.CommandType == CommandType.UserDataRequest)
            {
                int ID = FindClientID(e.Command.TargetIP, e.Command.TargetPort);
                string data = CheckForClientData(clientList[ID].Username);
                Command cmd = new Command(CommandType.UserDataInform, e.Command.SenderIP, data);
                cmd.SenderIP = e.Command.TargetIP;
                cmd.SenderPort = e.Command.TargetPort;
                cmd.SenderName = clientList[ID].Username; //Client username and IPEndpoint data is stored as command sender data
                cmd.TargetPort = e.Command.SenderPort;
                SendCommandToClient(cmd);
            }
        }