/// <summary>
        /// Updates the server database with statistics about a player's game session after the player dies.
        /// </summary>
        private static void UpdateDbWithDeadPlayerStats(Cube player)
        {
            // playerStats contains the info we want to store in the DB
            PlayerSessionStats playerStats = world.TeamStatistics[player.team_id];

            // Mark the player's time of death and calculate how long they survived, in seconds
            DateTime timeOfDeath = DateTime.Now;
            DateTime timeOfBirth = playerStats.TimeOfBirth;
            double   timeAlive   = timeOfDeath.Subtract(timeOfBirth).TotalSeconds;

            String rank;

            if (playerStats.HighestRankAchieved == int.MaxValue)
            {
                rank = "NR";
            }
            else
            {
                rank = playerStats.HighestRankAchieved + "";
            }


            int totalCubesEaten = playerStats.NumberOfFoodEaten + playerStats.NumberOfPlayersEaten;

            using (MySqlConnection conn = new MySqlConnection(DbConnectionString))
            {
                try
                {
                    // Open a DB connection
                    conn.Open();

                    // Create an SQL command that enters player's info into the Player_Games DB table
                    MySqlCommand command = conn.CreateCommand();

                    command.CommandText = "INSERT INTO Player_Games (Name, Lifespan, Maximum_Mass, Number_Of_Cubes_Eaten, Number_Of_Food_Eaten, Number_Of_Player_Cubes_Eaten, Rank) VALUES (\"" +
                                          player.Name + "\", " + timeAlive + ", " + playerStats.MaximumMass + ", " + totalCubesEaten + ", " + playerStats.NumberOfFoodEaten + ", " +
                                          playerStats.NumberOfPlayersEaten + ", " + rank + ")";

                    // Run the command
                    command.ExecuteNonQuery();
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error with Database: " + e.ToString());
                }
            }
            // If the player obtained a Top-5 position or ate any player cubes, record this info in the appropriate DB tables
            // For these insertions, we use the SessionID as the primary key. However, we don't have the SessionID so we must
            // query the Player_Games table for it. The SessionID is an integer. The first session in the Player_Games table
            // has a SessionID of 1, the second session recorded in the table has a SessionID of 2, etc. So the sessionID
            // for this player's game is the COUNT of all records in the Player_Games table.



            using (MySqlConnection conn = new MySqlConnection(DbConnectionString))
            {
                try
                {
                    // Open a DB connection
                    conn.Open();

                    // Create an SQL command that enters player's info into the Player_Games DB table
                    MySqlCommand command = conn.CreateCommand();
                    // Create command that returns the number of rows (i.e., the most recent SessionID) in the Player_Games table
                    command.CommandText = "SELECT * FROM Player_Games";

                    int sessionID = 0;

                    using (MySqlDataReader reader = command.ExecuteReader())
                    {
                        //sessionID = Convert.ToInt32(command.ExecuteScalar());

                        while (reader.Read())
                        {
                            sessionID++;
                        }
                    }



                    // If the player ate any cubes, concatenate the cube names into a single string and make a record in the
                    // Names_Of_Players_Eaten table in the DB, using the SessionID as the primary key
                    if (playerStats.NamesOfPlayersEaten.Count > 0)
                    {
                        string eatenPlayerNames = "";
                        foreach (string playerName in playerStats.NamesOfPlayersEaten)
                        {
                            eatenPlayerNames += playerName + ", ";
                        }

                        command.CommandText = "INSERT INTO Names_Of_Players_Eaten(Session_ID, Players_Eaten) VALUES (" +
                                              sessionID + ", \"" + eatenPlayerNames + "\")";


                        command.ExecuteNonQuery();
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error with Database: " + e.ToString());
                }
            }
        }
예제 #2
0
        public void TestRankingLoopInUpdate6players()
        {
            // Create world.
            World world = new World("C:\\Users\\weisched\\Source\\Repos\\JacksonRepo\\AgCubio\\Resources\\XMLWorldParameters.xml");

            // Create Player1
            Cube player1 = new Cube(100.0, 100.0, -2134567, 1, 1, false, "Player1", 1000);

            world.AddOrUpdateCube(player1);

            PlayerSessionStats player1Stats = new PlayerSessionStats();

            world.TeamStatistics.Add(player1.team_id, player1Stats);

            world.TeamStatistics[player1.team_id].CurrentMass = player1.Mass;

            // Create Player2
            Cube player2 = new Cube(100.0, 100.0, -2134567, 2, 2, false, "Player2", 2000);

            world.AddOrUpdateCube(player2);

            PlayerSessionStats player2Stats = new PlayerSessionStats();

            world.TeamStatistics.Add(player2.team_id, player2Stats);

            world.TeamStatistics[player2.team_id].CurrentMass = player2.Mass;

            // Create Player3
            Cube player3 = new Cube(100.0, 100.0, -2134567, 3, 3, false, "Player3", 3000);

            world.AddOrUpdateCube(player3);

            PlayerSessionStats player3Stats = new PlayerSessionStats();

            world.TeamStatistics.Add(player3.team_id, player3Stats);

            world.TeamStatistics[player3.team_id].CurrentMass = player3.Mass;


            // Create Player4
            Cube player4 = new Cube(100.0, 100.0, -2134567, 4, 4, false, "Player1", 4000);

            world.AddOrUpdateCube(player4);

            PlayerSessionStats player4Stats = new PlayerSessionStats();

            world.TeamStatistics.Add(player4.team_id, player4Stats);

            world.TeamStatistics[player4.team_id].CurrentMass = player4.Mass;

            // Create Player5
            Cube player5 = new Cube(100.0, 100.0, -2134567, 5, 5, false, "Player2", 5000);

            world.AddOrUpdateCube(player5);

            PlayerSessionStats player5Stats = new PlayerSessionStats();

            world.TeamStatistics.Add(player5.team_id, player5Stats);

            world.TeamStatistics[player5.team_id].CurrentMass = player5.Mass;

            // Create Player6
            Cube player6 = new Cube(100.0, 100.0, -2134567, 6, 6, false, "Player3", 6000);

            world.AddOrUpdateCube(player6);

            PlayerSessionStats player6Stats = new PlayerSessionStats();

            world.TeamStatistics.Add(player6.team_id, player6Stats);

            world.TeamStatistics[player6.team_id].CurrentMass = player6.Mass;

            // 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;
                    }
                }
            }

            Assert.AreEqual(int.MaxValue, player1Stats.HighestRankAchieved);

            Assert.AreEqual(5, player2Stats.HighestRankAchieved);

            Assert.AreEqual(4, player3Stats.HighestRankAchieved);

            Assert.AreEqual(3, player4Stats.HighestRankAchieved);

            Assert.AreEqual(2, player5Stats.HighestRankAchieved);

            Assert.AreEqual(1, player6Stats.HighestRankAchieved);


            world.TeamStatistics[player1.team_id].CurrentMass = 10000;

            world.TeamStatistics[player2.team_id].CurrentMass = 5000;

            world.TeamStatistics[player6.team_id].CurrentMass = 1000;


            // Create a list of all the current teams that exist masses.
            teamMasses.Clear();

            // 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;
                    }
                }
            }


            Assert.AreEqual(1, player1Stats.HighestRankAchieved);

            Assert.AreEqual(2, player2Stats.HighestRankAchieved);

            Assert.AreEqual(4, player3Stats.HighestRankAchieved);

            Assert.AreEqual(3, player4Stats.HighestRankAchieved);

            Assert.AreEqual(2, player5Stats.HighestRankAchieved);

            Assert.AreEqual(1, player6Stats.HighestRankAchieved);
        }
        /// <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);
        }