/// <summary>
        /// Send a web brower and html page stating all the current game statistics of all games ever played.
        /// <param name="state">The state obj containing the callback to end the socket.</param>
        /// </summary>
        private static void SendScores(PreservedState state)
        {
            // Begin generating the information for the html page.
            String html = "<h1>Scores</h1><table border = 1><tr><td><b>Player</b></td><td><b>Max Mass</b></td><td><b>Rank</b></td><td><b>Cubes Eaten</b></td><td><b>Time Alive (MM:SS)</b></td></tr>";

            // Access our database
            using (MySqlConnection conn = new MySqlConnection(DbConnectionString))
            {
                try
                {
                    conn.Open();

                    MySqlCommand command = conn.CreateCommand();

                    // Generate teh command of what information we want from the database.
                    command.CommandText = "select Name, Maximum_Mass, Rank, Number_Of_Cubes_Eaten, Lifespan from Player_Games";

                    // Retrive the information from the database and attach it to the string going to the web browser.
                    using (MySqlDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            html += "<tr><td><a href = \"http://localhost:11100/games?player=" + reader["Name"] + "\">" + reader["Name"] + "</a>" + "</td><td>" + reader["Maximum_Mass"] + "</td><td>" + reader["Rank"] + "</td><td>" + reader["Number_Of_Cubes_Eaten"] + "</td><td>" + ToDateFormat(reader["Lifespan"].ToString()) + "</td></tr>";
                        }

                        html += "</table>";
                    }
                }
                // Send the error html page if there is an issue.
                catch (Exception e)
                {
                    SendErrorMessage(state);
                }
            }

            // Send the information to the webpage and close the socket.
            Network.Send(state.socket, HttpResponseHeader);

            Network.Send(state.socket, html, (Object) => { Console.WriteLine("Sent HTML"); state.socket.Close(); return; });
        }
Example #2
0
        /// <summary>
        /// Callback for receiving client name.
        /// </summary>
        /// <param name="ss">The ss.</param>
        private static void ReceiveName(SocketState ss)
        {
            // Extract name from received data
            string name = ss.Builder.ToString();

            name = name.Remove(name.Length - 1);
            Console.WriteLine("Received name: " + name);

            Network.Send(ss.Socket, ss.ID + "\n" + world.WorldSize + "\n");
            clients.Add(ss);
            Ship newShip = new Ship(ss.ID, name, random.Next(universeSize + 1) - (universeSize / 2), random.Next(universeSize + 1) - (universeSize / 2));

            // Don't start ship in star's location
            while (Math.Abs(newShip.Loc.GetX()) < starSize && Math.Abs(newShip.Loc.GetX()) < starSize)
            {
                newShip.Loc = new Vector2D(random.Next(universeSize + 1) - (universeSize / 2), random.Next(universeSize + 1) - (universeSize / 2));
            }
            world.AddShip(newShip);

            ss.CallMe = ReceiveMoveRequest;
            Network.GetData(ss);
        }
Example #3
0
        /// <summary>
        /// This is a delegate callback that handles the server's side of the initial handshake.
        /// It receives the player's name and sends the client startup data, then requests direciton
        /// change information from the client.
        /// </summary>
        /// <param name="client">The client.</param>
        private void ReceivePlayerName(SocketState client)
        {
            // Get player's name.
            string playerName = client.Messages[0];

            // Create snake object corresponding to new player.
            CreateNewPlayerSnake(playerName);

            // Change callback to method that handles direction change requests.
            client.Callback = ReceiveDirection;

            // Store the assigned ID into the client state.
            client.ID = playerCount;

            // Send startup information to client.
            Network.Send(client.Socket, playerCount + "\n" + boardWidth + "\n" + boardHeight + "\n");

            playerCount++;

            // Can't have the server modifying the clients list if it's braodcasting a message.
            lock (clients)
            {
                clients.Add(client);
            }

            try
            {
                Network.GetData(client);
            }
            catch (SocketException e)
            {
                Debug.WriteLine("Could not receive from client due to disconnect. " + e);
                client.Socket.Shutdown(SocketShutdown.Both);
                client.Socket.Close();
            }
        }
Example #4
0
        /// <summary>
        /// Updates the frame.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="ElapsedEventArgs"/> instance containing the event data.</param>
        private void UpdateFrame(object sender, ElapsedEventArgs e)
        {
            lock (world)
            {
                List <SocketState> clientsToRemove = new List <SocketState>(); // A list to temporarily store clients that have disconnected.
                List <Snake.Snake> snakesToDie     = new List <Snake.Snake>(); // A list to temporarily store snakes that must die for the updated frame.
                List <Food>        eatenFood       = new List <Food>();

                // Update the position of every snake. Pass the list to update it with newly dead snakes.
                UpdateSnakePositions(snakesToDie, eatenFood);

                // Kill the snakes in the list.
                List <Snake.Snake> deadSnakes = KillSnakes(snakesToDie);

                // If the dead snake list is not empty, populate food where they died.
                world.RecycleSnakes(snakesToDie, snakeRecycleRate, ref playerCount);

                // Send the relevant information out to all clients.
                foreach (SocketState client in clients)
                {
                    if (!client.Socket.Connected)
                    {
                        clientsToRemove.Add(client);
                        continue;
                    }

                    try
                    {
                        foreach (KeyValuePair <int, Snake.Snake> el in world.Snakes)
                        {
                            string message = JsonConvert.SerializeObject(el.Value);
                            Network.Send(client.Socket, message + "\n");
                        }

                        foreach (Snake.Snake el in deadSnakes)
                        {
                            string message = JsonConvert.SerializeObject(el);
                            Network.Send(client.Socket, message + "\n");
                        }

                        foreach (KeyValuePair <int, Food> el in world.Food)
                        {
                            string message = JsonConvert.SerializeObject(el.Value);
                            Network.Send(client.Socket, message + "\n");
                        }

                        foreach (Food el in eatenFood)
                        {
                            string message = JsonConvert.SerializeObject(el);
                            Network.Send(client.Socket, message + "\n");
                        }
                    }
                    catch (SocketException ex)
                    {
                        Debug.WriteLine("Unable to establish further communication with the client. Client disconnected: " + ex);
                        client.Socket.Shutdown(SocketShutdown.Both);
                        client.Socket.Close();
                        clientsToRemove.Add(client);
                    }
                }

                // Remove the clients that are no longer in use.
                RemoveDisconnectedClients(clientsToRemove);
            }

            //Check to see if the limit on number of food has been reached, if not add food
        }
Example #5
0
        protected void ReceiveWebRequest(NetworkState state)
        {
            try
            {
                string   msg      = _Encoding.GetString(state.Buffer);
                string[] splitMsg = msg.Split(new char[] { '\r', '\n', ' ' });


                int idx;
                for (idx = 0; idx < splitMsg.Length && splitMsg[idx] != "GET"; idx++)
                {
                    ;
                }
                if (idx + 2 >= splitMsg.Length)
                {
                    throw new InvalidOperationException("The Web client is stupid.");
                }
                if (splitMsg[idx + 2] != "HTTP/1.1")
                {
                    throw new InvalidOperationException("The Web client is decrepit.");
                }
                idx++;


                string[] splitCmd = splitMsg[idx].Split('?');
                //Put in the HTML tag and start the table
                StringBuilder response = new StringBuilder("<HTML>\n");
                response.Append(GetHtmlHeader());
                switch (splitCmd[0])
                {
                case "/":
                case "/scores":
                    response.Append(GetTableTitle("Scores:"));
                    response.Append(GetPlayerScores());
                    break;

                case "/games":
                    if (splitCmd.Length < 2)
                    {
                        response.Append(GetErrorPage(splitCmd[0]));
                    }
                    else
                    {
                        response.Append(GetTableTitle("Games:"));
                        response.Append(GetPlayerGames(splitCmd[1]));
                    }
                    break;

                case "/eaten":
                    if (splitCmd.Length < 2)
                    {
                        response.Append(GetErrorPage(splitMsg[idx]));
                    }
                    else
                    {
                        response.Append(GetTableTitle("Players eaten:"));
                        response.Append(GetEatenPlayers(splitCmd[1]));
                    }
                    break;

                case "/highscores":
                    response.Append(GetTableTitle("High Scores:"));
                    response.Append(GetHighscores());
                    break;

                case "/current":
                    response.Append(GetCurrentPlayers());
                    break;

                default:
                    //response = "<html> There was an error with command \"" + splitCmd[0] + "\".</html>";
                    response.Append(GetErrorPage(splitCmd[0]));
                    break;
                }
                response.Append("</HTML>");



                Network.Send(state.Socket, response + "\r\n\r\n", SendCompleteCallback);
            }
            catch (Exception e)
            {
                //Strictly speaking, if something goes wrong, I don't really care.
                Console.WriteLine(e.Message);
            }
        }
Example #6
0
        /// <summary>
        /// Updates the world.
        /// </summary>
        private static void UpdateWorld()
        {
            while (true)
            {
                // Spin until delay is reached
                while (updateStopwatch.ElapsedMilliseconds < msPerFrame)
                {
                }

                updateStopwatch.Restart();

                lock (world) {
                    // Move ships
                    foreach (Ship ship in world.GetShips())
                    {
                        // Only update connected players
                        if (IsConnected(ship.id))
                        {
                            if (ship.ToTurn == 1)
                            {
                                ship.Dir.Rotate(turningRate);
                            }
                            if (ship.ToTurn == -1)
                            {
                                ship.Dir.Rotate(-turningRate);
                            }

                            Vector2D acceleration = new Vector2D(0, 0);
                            Vector2D thrust       = new Vector2D(ship.Dir);
                            if (ship.Thrust)
                            {
                                acceleration = acceleration + (thrust * engineStrength);
                            }

                            foreach (Star star in world.GetStars())
                            {
                                Vector2D g = star.Loc - ship.Loc;
                                g.Normalize();
                                acceleration = acceleration + (g * star.Mass);
                            }

                            ship.Velocity = ship.Velocity + acceleration;
                            ship.Loc      = ship.Loc + ship.Velocity;
                        }
                        else
                        {
                            if (ship.Connected)
                            {
                                Console.WriteLine("Client disconnected: " + ship.Name);
                                ship.Connected = false;
                            }
                        }
                    }

                    // Move stars if mode is set to MovingStars
                    if (mode.Equals("MovingStars"))
                    {
                        foreach (Star star in world.GetStars())
                        {
                            int    xPos = random.Next(2);
                            double xDir = random.NextDouble() / 10;
                            if (xPos == 1)
                            {
                                xDir *= -1;
                            }
                            int    yPos = random.Next(2);
                            double yDir = random.NextDouble() / 10;
                            if (yPos == 1)
                            {
                                yDir *= -1;
                            }
                            Vector2D acceleration = new Vector2D(xDir, yDir);
                            star.Velocity = star.Velocity + acceleration;
                            star.Loc      = star.Loc + star.Velocity;
                            if (star.Velocity.Length() > 10)
                            {
                                double diff = star.Velocity.Length() - 10;
                                star.Velocity = star.Velocity - new Vector2D(diff, diff);
                            }
                        }
                    }

                    // Wrap locations
                    WrapAround();

                    // Move projectiles
                    foreach (Projectile projectile in world.GetProjectiles())
                    {
                        if (projectile.Alive)
                        {
                            projectile.Loc = projectile.Loc + (projectile.Dir * projectileSpeed);
                        }
                        else
                        {
                            world.RemoveProjectile(projectile.id);
                        }
                    }

                    // Check for collisions
                    CollisionChecks();

                    // Generate world string
                    worldStringBuilder.Clear();
                    foreach (Ship ship in world.GetShips())
                    {
                        if (IsConnected(ship.id))
                        {
                            worldStringBuilder.Append(JsonConvert.SerializeObject(ship) + "\n");
                        }
                    }
                    foreach (Projectile projectile in world.GetProjectiles())
                    {
                        worldStringBuilder.Append(JsonConvert.SerializeObject(projectile) + "\n");
                    }
                    foreach (Star star in world.GetStars())
                    {
                        worldStringBuilder.Append(JsonConvert.SerializeObject(star) + "\n");
                    }
                }

                String worldString = worldStringBuilder.ToString();

                // Send updated world to all clients
                foreach (SocketState client in clients)
                {
                    if (client.Socket.Connected)
                    {
                        Network.Send(client.Socket, worldString);
                    }
                }
            }
        }
        /// <summary>
        /// This method is the "heartbeat" of the server. It's executed several times per second, as specified by the UPDATES_PER_SECOND member variable.
        /// It creates new food and viruses, atrophies player cubes, and broadcasts to all clients the most recent state of the world.
        /// </summary>
        private static void Update()
        {
            // Lock the world so that we can update it.
            lock (world)
            {
                // Create more food, if needed.
                if (world.foodCountInWorld < world.MAX_FOOD)
                {
                    world.CreateFood(world.NEW_FOOD_AMT_PER_UPDATE, false);
                }

                // Create more viruses, if needed.
                if (world.virusCountInWorld < world.MAX_VIRUSES)
                {
                    int virusesNeeded = world.MAX_VIRUSES - world.virusCountInWorld;

                    world.CreateVirus(virusesNeeded, false);
                }

                // if any cubes have recently been exploded by a virus, start timers for them to re-merge
                if (world.virusMergeTimersToStart.Count > 0)
                {
                    lock (mergeTimerLocker)
                    {
                        foreach (int teamID in world.virusMergeTimersToStart)
                        {
                            StartMergeTimer(teamID);
                        }
                    }

                    world.virusMergeTimersToStart.Clear();
                }



                // Clear out any old data in the StringBuilder
                allWorldCubes.Clear();

                //List<double> TeamMasses = new List<double>();

                //int Rank = 1;

                //foreach (int teamid in world.TeamStatistics.Keys)
                //{

                //    if (world.TeamStatistics[teamid].CurrentMass > world.TeamStatistics[teamid].MaximumMass)
                //    {
                //        world.TeamStatistics[teamid].MaximumMass = world.TeamStatistics[teamid].CurrentMass;
                //    }

                //    TeamMasses.Add(world.TeamStatistics[teamid].CurrentMass);

                //double largestMass = world.TeamStatistics[teamid].MaximumMass;

                //int largestMassId = teamid;

                //foreach (int teamidRank in world.TeamStatistics.Keys)
                //{
                //    if (world.TeamStatistics[teamidRank].MaximumMass > largestMass)
                //    {
                //        largestMass = world.TeamStatistics[teamidRank].MaximumMass;

                //        largestMassId = teamidRank;
                //    }
                //}

                //    TeamMasses.Sort();

                //}
                //foreach (int teamID in world.TeamStatistics.Keys)
                //{
                //    PlayerSessionStats session = world.TeamStatistics[teamID];
                //    if (TeamMasses.Count > 0 && TeamMasses[TeamMasses.Count - 1] == session.CurrentMass)
                //        session.HighestRankAchieved = 1;

                //    else if (TeamMasses.Count > 1 && TeamMasses[TeamMasses.Count - 2] == session.CurrentMass)
                //        session.HighestRankAchieved = 2;

                //    else if (TeamMasses.Count > 2 && TeamMasses[TeamMasses.Count - 3] == session.CurrentMass)
                //        session.HighestRankAchieved = 3;

                //    else if (TeamMasses.Count > 3 && TeamMasses[TeamMasses.Count - 4] == session.CurrentMass)
                //        session.HighestRankAchieved = 4;

                //    else if (TeamMasses.Count > 4 && TeamMasses[TeamMasses.Count - 5] == session.CurrentMass)
                //        session.HighestRankAchieved = 5;

                //}



                // Create a list of all the current teams that exist masses.
                List <double> teamMasses = new List <double>();

                // Loop through the sessions and get all the teams masses.
                foreach (int teamid in world.TeamStatistics.Keys)
                {
                    // Update their mazimum mass value if needed.
                    if (world.TeamStatistics[teamid].CurrentMass > world.TeamStatistics[teamid].MaximumMass)
                    {
                        world.TeamStatistics[teamid].MaximumMass = world.TeamStatistics[teamid].CurrentMass;
                    }

                    // Add each teams current mass to the list.
                    teamMasses.Add(world.TeamStatistics[teamid].CurrentMass);
                }

                // Sort all the teams masses.
                teamMasses.Sort();

                // Loop through and compare all the the current team masses with each other to determine the top 5 players
                // The list is sorted in acsending order so the top 5 largest players are in the bottom of the list.
                foreach (int teamid in world.TeamStatistics.Keys)
                {
                    // If the team's mass is equal to the mass of the last item in the list, its the largest cube and therefore in 1st place.
                    if (world.TeamStatistics[teamid].CurrentMass == teamMasses[teamMasses.Count - 1])
                    {
                        if (world.TeamStatistics[teamid].HighestRankAchieved > 1)
                        {
                            world.TeamStatistics[teamid].HighestRankAchieved = 1;
                        }
                    }
                    // If the team's mass is equal to the mass of the second to last item in the list, its the largest cube and therefore in 2nd place.
                    else if (world.TeamStatistics[teamid].CurrentMass == teamMasses[teamMasses.Count - 2])
                    {
                        if (world.TeamStatistics[teamid].HighestRankAchieved > 2)
                        {
                            world.TeamStatistics[teamid].HighestRankAchieved = 2;
                        }
                    }
                    // If the team's mass is equal to the mass of the third to last item in the list, its the largest cube and therefore in 3rd place.
                    else if (world.TeamStatistics[teamid].CurrentMass == teamMasses[teamMasses.Count - 3])
                    {
                        if (world.TeamStatistics[teamid].HighestRankAchieved > 3)
                        {
                            world.TeamStatistics[teamid].HighestRankAchieved = 3;
                        }
                    }
                    // If the team's mass is equal to the mass of the fourth to last item in the list, its the largest cube and therefore in 4th place.
                    else if (world.TeamStatistics[teamid].CurrentMass == teamMasses[teamMasses.Count - 4])
                    {
                        if (world.TeamStatistics[teamid].HighestRankAchieved > 4)
                        {
                            world.TeamStatistics[teamid].HighestRankAchieved = 4;
                        }
                    }
                    // If the team's mass is equal to the mass of the fifth to last item in the list, its the largest cube and therefore in 5th place.
                    else if (world.TeamStatistics[teamid].CurrentMass == teamMasses[teamMasses.Count - 5])
                    {
                        if (world.TeamStatistics[teamid].HighestRankAchieved > 5)
                        {
                            world.TeamStatistics[teamid].HighestRankAchieved = 5;
                        }
                    }
                }



                // Perform mass attrition on player cubes, update DB if any players have died,
                // and send a String of all the recently modified cubes to all clients.
                foreach (Cube cube in world.CubesChangedSinceLastUpdate)
                {
                    if (cube.food == false)
                    {
                        // If any players have died, update the game Database with their session stats
                        if (cube.uid == cube.team_id && cube.Mass == 0 && !DeadPlayersUIDs.Contains(cube.uid))
                        {
                            DeadPlayersUIDs.Add(cube.uid);
                            UpdateDbWithDeadPlayerStats(cube);
                        }


                        // Update the attrition value for the player cubes if they have grown or shrunk.
                        if (cube.Mass > world.RAPID_ATTRITION_THRESHOLD)
                        {
                            cube.Mass -= world.HIGH_ATTRITION_PER_UPDATE;
                        }

                        else if (cube.Mass > world.ATTRITION_LOWER_MASS_LIMIT)
                        {
                            cube.Mass -= world.NORMAL_ATTRITION_PER_UPDATE;
                        }
                    }

                    // Serialize the cube so that it can be sent as a string.
                    allWorldCubes.Append(JsonConvert.SerializeObject(cube) + '\n');
                }

                // Empty the set for the next update.
                world.CubesChangedSinceLastUpdate.Clear();


                // Send the recently modified cubes to all connected clients.
                lock (clientSocketsLocker)
                {
                    foreach (Socket socket in ClientSockets.Keys)
                    {
                        Network.Send(socket, allWorldCubes.ToString());
                    }
                }
            }
        }
        /// <summary>
        /// A Callback that's called when a new client connects.
        /// Gets the client's desired player name, sends the client
        /// their player and the world, and then starts listening
        /// for move and split requests.
        /// </summary>
        /// <param name="state">The state object of the newly added player, it contains its socket, callback and str builder.</param>
        static void ReceivePlayerName(PreservedState state)
        {
            // Pull the player name from the state obj str builder and then clear it.
            String playerName = state.strBuilder.ToString();

            state.strBuilder.Clear();

            // Remove the \n from the end of the player name.
            playerName = playerName.Substring(0, playerName.Length - 1);

            // Declare team id and player cube out here so it can be used in all the locks.
            int team_id;

            Cube playerCube;

            // Lock the world in order to generate information to build the player cube.
            lock (world)
            {
                // Create the player's cube atributes
                Point playerXY = world.GetPlayerSpawnLoc();

                int argb_color = world.SetCubeColor();

                double mass = world.INITIAL_PLAYER_MASS;

                int playerUid = world.GetNextUID();

                team_id = playerUid;

                // Generate the player cube and add it to the world, new players list, and teams list.
                playerCube = new Cube(playerXY.X, playerXY.Y, argb_color, playerUid, team_id, false, playerName, mass);

                world.AddOrUpdateCube(playerCube);

                // Create a team for the player
                world.Teams.Add(team_id, new List <Cube>()
                {
                    playerCube
                });

                // Start tracking the player's team's stats
                PlayerSessionStats session = new PlayerSessionStats();
                session.MaximumMass = world.INITIAL_PLAYER_MASS;
                session.CurrentMass = world.INITIAL_PLAYER_MASS;

                world.TeamStatistics.Add(team_id, session);
            }

            // Lock the client sockets set inorder to add the newly created players socket to it.
            lock (clientSocketsLocker)
            {
                ClientSockets.Add(state.socket, team_id);
            }

            // Serialize the player cube to send it to the client.
            String playerCubeStr = JsonConvert.SerializeObject(playerCube) + "\n";

            // Send player their cube
            Network.Send(state.socket, playerCubeStr);

            // Update the callback in order to handle more players potentially adding.
            state.callBack = HandleClientGameRequests;

            // Since there are now players in the game, set this to false so updates can happen.
            noPlayersJoined = false;

            // Send player the current state of the world
            lock (world)
            {
                StringBuilder worldCubes = new StringBuilder();

                foreach (Cube cube in world.Cubes)
                {
                    worldCubes.Append(JsonConvert.SerializeObject(cube) + '\n');
                }

                Network.Send(state.socket, worldCubes.ToString());
            }

            // Request more data from the server.
            Network.i_want_more_data(state);
        }
        /// <summary>
        /// /// /// Send a web brower and html page stating all the game statistics of a certain game session.
        /// <param name="state">The state obj containing the callback to end the socket.</param>
        /// </summary>
        private static void SendEatenCubes(PreservedState state, String req)
        {
            // The game session id requested by the browser
            string id = "";

            // Make sure url has valid format, and pull out the id
            try
            {
                if (req.Substring(0, 9) != "eaten?id=")
                {
                    SendErrorMessage(state);
                    return;
                }

                id = req.Substring(req.IndexOf('=') + 1);
            }
            // If there is an error send the error html page to the browser
            catch (Exception e)
            {
                SendErrorMessage(state);
                return;
            }

            // begin generating the string to be sent to the web browser.
            String html = "<h1>Cubes Eaten During Games Session " + id + "</h1>";

            html += "<table border = 1><tr><td><b>Name</b></td><td><b>Players Eaten</b></td><td><b>Max Mass</b></td><td><b>Rank</b></td><td><b>Cubes Eaten</b></td><td><b>Players Eaten</b></td><td><b>Time Alive (mm:ss)</b></td><td><b>Time Of Death</b></td></tr>";

            String namesOfEatenPlayers = "";

            // Begin requesting information from the database by opening the connection.
            using (MySqlConnection conn = new MySqlConnection(DbConnectionString))
            {
                try
                {
                    conn.Open();

                    MySqlCommand command = conn.CreateCommand();

                    // First, get the names of players eaten, if any exist
                    command.CommandText = "SELECT Players_Eaten FROM Names_Of_Players_Eaten WHERE Names_Of_Players_Eaten.Session_ID = " + id;

                    // Retrive all the eaten players.
                    using (MySqlDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            namesOfEatenPlayers += reader["Players_Eaten"];
                        }
                    }


                    // Then, get all the rest of the info for the session from the main table
                    command.CommandText = "SELECT Name, Maximum_Mass, Rank, Number_Of_Cubes_Eaten, Number_Of_Player_Cubes_Eaten, Lifespan, Time_Of_Death FROM Player_Games WHERE Player_Games.ID = " + id;

                    using (MySqlDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            html += "<tr><td>" + reader["Name"] + "</td><td>" + namesOfEatenPlayers + "</td><td>" + reader["Maximum_Mass"] + "</td><td>" + reader["Rank"] + "</td><td>" + reader["Number_Of_Cubes_Eaten"] + "</td><td>" + reader["Number_Of_Player_Cubes_Eaten"] + "</td><td>" +
                                    ToDateFormat(reader["Lifespan"].ToString()) + "</td><td>" + reader["Time_Of_Death"] + "</td></tr>";
                        }

                        html += "</table>";
                    }
                }
                // If there is an error send the error html page to the browser
                catch (Exception e)
                {
                    SendErrorMessage(state);
                    return;
                }
            }

            // Send the information to the webpage and close the socket.
            Network.Send(state.socket, HttpResponseHeader);

            Network.Send(state.socket, html, (Object) => { Console.WriteLine("Sent HTML"); state.socket.Close(); return; });
        }
        /// <summary>
        /// /// Send a web brower and html page stating all the game statistics of a certain player for all games they have played.
        /// <param name="state">The state obj containing the callback to end the socket.</param>
        /// </summary>
        private static void SendGamesByPlayer(PreservedState state, String req)
        {
            try
            {
                // Retrive the palyer name from the request of whose information we need to pull. If it doesn't exist send an error message.
                if (req.Substring(0, 13) != "games?player=")
                {
                    SendErrorMessage(state);
                    return;
                }

                // Retrieve the player name and begin generating the string to be sent to the web browser.
                string player = req.Substring(req.IndexOf('=') + 1);

                String html = "<h1>Games for " + player + "</h1>";

                html += "<table border = 1><tr><td><b>Max Mass</b></td><td><b>Rank</b></td><td><b>Cubes Eaten</b></td><td><b>Players Eaten</b></td><td><b>Time Alive</b></td><td><b>Time Of Death</b></td></tr>";

                // Access our database
                using (MySqlConnection conn = new MySqlConnection(DbConnectionString))
                {
                    try
                    {
                        conn.Open();

                        MySqlCommand command = conn.CreateCommand();

                        // Generate the command for the desired information we seek from the database.
                        command.CommandText = "select Maximum_Mass, Rank, Number_Of_Cubes_Eaten, Number_Of_Player_Cubes_Eaten, Lifespan, Time_Of_Death from Player_Games where Name = \"" + player + "\"";

                        // Retrieve that inforamtion from the database
                        using (MySqlDataReader reader = command.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                html += "<tr><td>" + reader["Maximum_Mass"] + "</td><td>" + reader["Rank"] + "</td><td>" + reader["Number_Of_Cubes_Eaten"] + "</td><td>" + reader["Number_Of_Player_Cubes_Eaten"] + "</td><td>" +
                                        ToDateFormat(reader["Lifespan"].ToString()) + "</td><td>" + reader["Time_Of_Death"] + "</td></tr>";
                            }

                            html += "</table><br><a href = \"http://localhost:11100/scores\">" + "Go To All Scores" + "</a>";
                        }
                    }
                    // If there is an error send the error html page to the browser
                    catch (Exception e)
                    {
                        SendErrorMessage(state);
                        return;
                    }
                }

                // Send the information to the webpage and close the socket.
                Network.Send(state.socket, HttpResponseHeader);

                Network.Send(state.socket, html, (Object) => { Console.WriteLine("Sent HTML"); state.socket.Close(); return; });
            }
            // If there is an error send the error html page to the browser
            catch (Exception e)
            {
                SendErrorMessage(state);
            }
        }