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