/// <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());
                }
            }
        }
Example #2
0
 /// <summary>
 /// Creation of a split cube. Takes in parent cube as member variable
 /// </summary>
 /// <param name="_X"></param>
 /// <param name="_Y"></param>
 /// <param name="_Uid"></param>
 /// <param name="_Team"></param>
 /// <param name="_Mass"></param>
 /// <param name="_Name"></param>
 /// <param name="_Color"></param>
 /// <param name="_Food"></param>
 public Cube(double _X, double _Y, int _Uid, int _Team, double _Mass, string _Name, int _Color, bool _Food, Cube parent)
 {
     X        = _X;
     Y        = _Y;
     Uid      = _Uid;
     Team     = _Team;
     CubeMass = _Mass;
     Name     = _Name;
     IntColor = _Color;
     Food     = _Food;
     Width    = (int)Math.Sqrt(_Mass);
     Parent   = parent;
 }
        /// <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);
        }