static public void AnalyzePaths(string filename, FileStream fileStream) { long matchID = 0; string mapName = ""; List <ingameRound> allRoundsList = new List <ingameRound>(); List <ingameRound> matchRoundsList = new List <ingameRound>(); List <ingameRound> existingStratRoundsList = new List <ingameRound>(); List <ingamePathpoint> allPathpointsList = new List <ingamePathpoint>(); MySqlConnection sqlConnection = null; MySqlDataReader sqlReader = null; //Setup connection with the MySQL Server////////////////////////////////////// try { string connectionString = "SERVER=localhost;DATABASE=demostatistics;UID=demostatistics;PASSWORD=1ax4X7M4;"; sqlConnection = new MySqlConnection(connectionString); sqlConnection.Open(); Console.WriteLine(getTimeStamp() + "Connected to MySQL Server"); } catch (MySqlException er) { Console.WriteLine(getTimeStamp() + "Error: {0}", er.ToString()); } ////////////////////////////////////////////////////////////////////////////// //Preloading info for analysis./////////////////////////////////////////////// //Get match based on the demo filename string matchSelectQuery = "SELECT id,mapName FROM `match` WHERE filename='" + filename + "'"; MySqlCommand matchSelectionCommand = new MySqlCommand(matchSelectQuery, sqlConnection); sqlReader = matchSelectionCommand.ExecuteReader(); while (sqlReader.Read()) { //For each match matchID = sqlReader.GetInt64("id"); mapName = sqlReader.GetString("mapName"); } sqlReader.Close(); //If match is not found in database launch PathGenerator if (matchID == 0) { Console.WriteLine(getTimeStamp() + "Match not found in DB... Running PathGenerator..."); Console.WriteLine(); Console.WriteLine(); Console.WriteLine(); using (var parser = new DemoParser(fileStream)) { PathGenerator.GeneratePath(parser, false, false, true, filename); } sqlReader = matchSelectionCommand.ExecuteReader(); while (sqlReader.Read()) { //For each match matchID = sqlReader.GetInt64("id"); mapName = sqlReader.GetString("mapName"); } sqlReader.Close(); //System.Environment.Exit(1); } Console.WriteLine(getTimeStamp() + filename + " is being analyzed"); //Prepare statement to get all viable rounds from database Console.Write(getTimeStamp() + "Loading all rounds in DB... "); string allRoundsSelectionQuery = "SELECT id,roundType,stratFound FROM `round` WHERE bombPlanted=1 OR enemyTeamWiped=1 AND mapName='" + mapName + "'"; MySqlCommand allRoundsSelectionCommand = new MySqlCommand(allRoundsSelectionQuery, sqlConnection); sqlReader = allRoundsSelectionCommand.ExecuteReader(); //Load each round which meets the query while (sqlReader.Read()) { allRoundsList.Add(new ingameRound(sqlReader.GetInt64("id"), sqlReader.GetString("roundType"), sqlReader.GetBoolean("stratFound"))); } sqlReader.Close(); Console.WriteLine(allRoundsList.Count + " entries - Done"); //Prepare statement to get viable rounds from match Console.Write(getTimeStamp() + "Loading rounds from Demo-File... "); string matchRoundSelectionQuery = "SELECT id,roundType,stratFound FROM `round` WHERE matchID=" + matchID + " AND bombPlanted=1 OR enemyTeamWiped=1 AND stratFound=0"; MySqlCommand matchRoundSelectionCommand = new MySqlCommand(matchRoundSelectionQuery, sqlConnection); sqlReader = matchRoundSelectionCommand.ExecuteReader(); while (sqlReader.Read()) { matchRoundsList.Add(new ingameRound(sqlReader.GetInt64("id"), sqlReader.GetString("roundType"), sqlReader.GetBoolean("stratFound"))); } sqlReader.Close(); Console.WriteLine(matchRoundsList.Count + " entries - Done"); //Prepare statement to get viable rounds from existing strats Console.Write(getTimeStamp() + "Loading rounds from existing strats... "); string existingStratsRoundSelectionQuery = "SELECT stratID,roundID,roundType FROM `stratrounds`"; MySqlCommand existingStratsRoundSelectionCommand = new MySqlCommand(existingStratsRoundSelectionQuery, sqlConnection); sqlReader = existingStratsRoundSelectionCommand.ExecuteReader(); while (sqlReader.Read()) { existingStratRoundsList.Add(new ingameRound(sqlReader.GetInt64("roundID"), sqlReader.GetString("roundType"), true)); //existingStratRoundsList.Find(n => n.roundID == sqlReader.GetInt64("roundID")).stratID = sqlReader.GetInt64("stratID"); foreach (var existingRound in existingStratRoundsList.Where(n => n.roundID == sqlReader.GetInt64("roundID"))) { existingRound.stratID = sqlReader.GetInt64("stratID"); } } sqlReader.Close(); Console.WriteLine(existingStratRoundsList.Count + " entries - Done"); //Prepare statement to get all viable pathpoints from database Console.Write(getTimeStamp() + "Loading all pathpoints in DB... "); foreach (var round in allRoundsList) { string pathpointsSelectionQuery = "SELECT roundID,X,Y,Z FROM `pathpoints` WHERE roundID=" + round.roundID; MySqlCommand pathpointsSelectionCommand = new MySqlCommand(pathpointsSelectionQuery, sqlConnection); sqlReader = pathpointsSelectionCommand.ExecuteReader(); while (sqlReader.Read()) { allPathpointsList.Add(new ingamePathpoint(sqlReader.GetInt64("roundID"), sqlReader.GetInt32("X"), sqlReader.GetInt32("Y"), sqlReader.GetInt32("Z"))); } sqlReader.Close(); } Console.WriteLine(allPathpointsList.Count + " entries - Done"); ///////////////////////////////////////////////////////////////////////////// //Analysis Loop - ITS HAPPENING!!! Console.WriteLine(); Console.WriteLine(); Console.WriteLine(getTimeStamp() + "Starting analysis loop"); foreach (var round in matchRoundsList) { //Load all pathpoints for this round in the demo file List <ingamePathpoint> demoPathpointList = new List <ingamePathpoint>(); Console.Write(getTimeStamp() + "Loading pathpoints for round " + round.roundID + "... "); string demoPathpointsSelectionQuery = "SELECT roundID,X,Y,Z FROM `pathpoints` WHERE roundID=" + round.roundID; MySqlCommand demoPathpointsSelectionCommand = new MySqlCommand(demoPathpointsSelectionQuery, sqlConnection); sqlReader = demoPathpointsSelectionCommand.ExecuteReader(); while (sqlReader.Read()) { demoPathpointList.Add(new ingamePathpoint(sqlReader.GetInt64("roundID"), sqlReader.GetInt32("X"), sqlReader.GetInt32("Y"), sqlReader.GetInt32("Z"))); } sqlReader.Close(); Console.WriteLine(demoPathpointList.Count + " entries - Done"); bool matchingRoundInDB = false; //List which contains all rounds which are similar to this round from the Demo List <ingameRound> demoRoundSimilarRounds = new List <ingameRound>(); //Add the round from the demo itself to the list demoRoundSimilarRounds.Add(round); Parallel.ForEach(allRoundsList, dbRound => { int counter = 0; int successCounter = 0; foreach (var demoPathPoint in demoPathpointList) { ingamePathpoint roundedDemoPathPoint = new ingamePathpoint(demoPathPoint.roundID, (((int)Math.Round((int)demoPathPoint.X / 30.0)) * 30), (((int)Math.Round((int)demoPathPoint.Y / 30.0)) * 30), (((int)Math.Round((int)demoPathPoint.Z / 30.0)) * 30)); foreach (var dbPathPoint in allPathpointsList.Where(n => n.roundID != demoPathPoint.roundID && n.roundID == dbRound.roundID)) { ingamePathpoint roundedDbPathPoint = new ingamePathpoint(dbPathPoint.roundID, (((int)Math.Round((int)dbPathPoint.X / 30.0)) * 30), (((int)Math.Round((int)dbPathPoint.Y / 30.0)) * 30), (((int)Math.Round((int)dbPathPoint.Z / 30.0)) * 30)); counter++; double distance = Math.Sqrt(MyPow((roundedDbPathPoint.X - roundedDemoPathPoint.X), 2) + MyPow((roundedDbPathPoint.Y - roundedDemoPathPoint.Y), 2) + MyPow((roundedDbPathPoint.Z - roundedDemoPathPoint.Z), 2)); if (distance == 0) { successCounter++; } } } if (counter != 0) { //Calculate percentage of pathpoints from the DB which are close to the pathpoints from the demo float successPercentage = ((float)successCounter / (float)counter) * 100; if (successPercentage >= 1.7) { //Found a round which seems to be the same strat like the the round from the demo Console.WriteLine("Success round " + dbRound.roundID + ": " + successPercentage.ToString(".0###") + "%"); //Add the round from the database which seems similar to the list. demoRoundSimilarRounds.Add(dbRound); matchingRoundInDB = true; } } }); //If a match has been found if (matchingRoundInDB) { long existingStratID = -1; foreach (var similarRound in demoRoundSimilarRounds.Where(n => n.stratFound == true)) { foreach (var stratRound in existingStratRoundsList.Where(n => n.roundID == similarRound.roundID)) { Console.WriteLine("The matching round " + similarRound.roundID + " is already in the strat " + stratRound.stratID); existingStratID = stratRound.stratID; } } if (existingStratID != -1) { int newRoundCounter = 0; string addRoundToExistingStratQuery = "INSERT INTO `stratrounds` (stratID,roundID,roundType) VALUES "; foreach (var similarRound in demoRoundSimilarRounds.Where(n => n.stratFound == false)) { Console.WriteLine("Adding round " + similarRound.roundID + " to the existing strat " + existingStratID); newRoundCounter++; similarRound.stratFound = true; similarRound.stratID = existingStratID; existingStratRoundsList.Add(similarRound); foreach (var dbRound in allRoundsList.Where(n => n.roundID == similarRound.roundID)) { dbRound.stratFound = true; dbRound.stratID = existingStratID; } foreach (var matchRound in matchRoundsList.Where(n => n.roundID == similarRound.roundID)) { matchRound.stratFound = true; matchRound.stratID = existingStratID; } //Write stratFound into DB MySqlCommand setStratFoundForRound = new MySqlCommand("UPDATE `round` SET stratFound=1 WHERE id=" + similarRound.roundID, sqlConnection); setStratFoundForRound.ExecuteNonQuery(); addRoundToExistingStratQuery += "(" + existingStratID + "," + similarRound.roundID + ",'" + similarRound.roundType + "'),"; } if (newRoundCounter >= 1) { addRoundToExistingStratQuery = addRoundToExistingStratQuery.Remove(addRoundToExistingStratQuery.Length - 1); addRoundToExistingStratQuery += ";"; MySqlCommand addRoundToExistingStrat = new MySqlCommand(addRoundToExistingStratQuery, sqlConnection); addRoundToExistingStrat.ExecuteNonQuery(); Console.WriteLine("Added all rounds to the existing strat " + existingStratID); } } else if (existingStratID == -1) { //Create new strat in DB MySqlCommand createNewStratForRounds = new MySqlCommand("INSERT INTO `strats` (mapName,stratType) VALUES ('" + mapName + "','" + round.roundType + "')", sqlConnection); createNewStratForRounds.ExecuteNonQuery(); Console.WriteLine("Created new strat " + createNewStratForRounds.LastInsertedId); string addRoundToNewStratQuery = "INSERT INTO `stratrounds` (stratID,roundID,roundType) VALUES "; string updateRoundsQuery = "UPDATE `round` SET stratFound=1 WHERE"; foreach (var similarRound in demoRoundSimilarRounds) { Console.WriteLine("Adding round " + similarRound.roundID + " to the new strat " + createNewStratForRounds.LastInsertedId); similarRound.stratFound = true; similarRound.stratID = createNewStratForRounds.LastInsertedId; existingStratRoundsList.Add(similarRound); foreach (var dbRound in allRoundsList.Where(n => n.roundID == similarRound.roundID)) { dbRound.stratFound = true; dbRound.stratID = createNewStratForRounds.LastInsertedId; } foreach (var matchRound in matchRoundsList.Where(n => n.roundID == similarRound.roundID)) { matchRound.stratFound = true; matchRound.stratID = createNewStratForRounds.LastInsertedId; } addRoundToNewStratQuery += "(" + createNewStratForRounds.LastInsertedId + "," + similarRound.roundID + ",'" + similarRound.roundType + "'),"; updateRoundsQuery += " id=" + similarRound.roundID + " OR"; } addRoundToNewStratQuery = addRoundToNewStratQuery.Remove(addRoundToNewStratQuery.Length - 1); addRoundToNewStratQuery += ";"; MySqlCommand insertRoundToStrat = new MySqlCommand(addRoundToNewStratQuery, sqlConnection); insertRoundToStrat.ExecuteNonQuery(); updateRoundsQuery = updateRoundsQuery.Remove(updateRoundsQuery.Length - 3); updateRoundsQuery += ";"; MySqlCommand updateRounds = new MySqlCommand(updateRoundsQuery, sqlConnection); updateRounds.ExecuteNonQuery(); Console.WriteLine("Added all rounds to the new strat " + createNewStratForRounds.LastInsertedId); } } } }
static public void GenerateStratMeta(int analyseStratID) { Console.WriteLine(); Console.WriteLine(getTimeStamp() + "---StratMetaGenerator---"); //Setup connection with the MySQL Server////////////////////////////////////// MySqlConnection sqlConnection = null; MySqlDataReader sqlReader = null; try { string connectionString = "SERVER=localhost;DATABASE=demostatistics;UID=demostatistics;PASSWORD=1ax4X7M4;"; sqlConnection = new MySqlConnection(connectionString); sqlConnection.Open(); Console.WriteLine(getTimeStamp() + "Connected to MySQL Server"); } catch (MySqlException er) { Console.WriteLine(getTimeStamp() + "Error: {0}", er.ToString()); } ////////////////////////////////////////////////////////////////////////////// //Variables/////////////////////////////////////////////////////////////////// List <ingameRound> stratRounds = new List <ingameRound>(); List <ingamePathpoint> stratPathpoints = new List <ingamePathpoint>(); string mapName = ""; ////////////////////////////////////////////////////////////////////////////// //Load mapName from DB MySqlCommand getStratInfo = new MySqlCommand("SELECT mapName FROM `strats` WHERE id=" + analyseStratID, sqlConnection); sqlReader = getStratInfo.ExecuteReader(); while (sqlReader.Read()) { mapName = sqlReader.GetString("mapName"); } sqlReader.Close(); Console.WriteLine(getTimeStamp() + "Loaded info for the strat " + analyseStratID); //Load all stratrounds MySqlCommand getRoundsFromStrat = new MySqlCommand("SELECT stratID,roundID,roundType FROM `stratrounds` WHERE stratID=" + analyseStratID, sqlConnection); sqlReader = getRoundsFromStrat.ExecuteReader(); while (sqlReader.Read()) { stratRounds.Add(new ingameRound(sqlReader.GetInt64("roundID"), sqlReader.GetString("roundType"), true)); } sqlReader.Close(); Console.WriteLine(getTimeStamp() + "Loaded " + stratRounds.Count + " rounds for the strat"); //Load all pathpoints foreach (var round in stratRounds) { MySqlCommand getPathpointsFromStrat = new MySqlCommand("SELECT steamID,X,Y,Z FROM `pathpoints` WHERE roundID=" + round.roundID, sqlConnection); sqlReader = getPathpointsFromStrat.ExecuteReader(); while (sqlReader.Read()) { ingamePathpoint pathpoint = new ingamePathpoint(round.roundID, sqlReader.GetInt32("X"), sqlReader.GetInt32("Y"), sqlReader.GetInt32("Z")); stratPathpoints.Add(pathpoint); stratPathpoints[stratPathpoints.IndexOf(pathpoint)].steamID = sqlReader.GetInt64("steamID"); } sqlReader.Close(); } Console.WriteLine(getTimeStamp() + "Loaded " + stratPathpoints.Count + " pathpoints for the strat"); Parallel.ForEach(stratRounds, (round) =>//Limit to round --> Find way to combine data from different rounds { Bitmap bitmap = new Bitmap(1024, 1024); Graphics graphics = Graphics.FromImage(bitmap); Image mapBackground = Image.FromFile("overviews/" + mapName + "_radar.png"); graphics.DrawImage(mapBackground, 0, 0); //List to store the players steamIDs List <long> steamIDs = new List <long>(); steamIDs.Clear(); foreach (var pathpoint in stratPathpoints.Where(n => !steamIDs.Contains(n.steamID) && n.roundID == round.roundID)) { steamIDs.Add(pathpoint.steamID); } //Foreach player get all pathpoints and draw lines between them. int playerNumberT = 0; foreach (var playerSteamID in steamIDs) { Pen pen; playerNumberT++; switch (playerNumberT) { case 1: pen = new Pen(Color.DarkRed); break; case 2: pen = new Pen(Color.DarkGreen); break; case 3: pen = new Pen(Color.Blue); break; case 4: pen = new Pen(Color.Yellow); break; case 5: pen = new Pen(Color.Purple); break; default: pen = new Pen(Color.White); break; } //Generate a list with the pathpoints for this player. List <ingamePathpoint> validPathpoints = new List <ingamePathpoint>(); validPathpoints.Clear(); foreach (var validPathpoint in stratPathpoints) { if (validPathpoint.steamID == playerSteamID && validPathpoint.roundID == round.roundID) { validPathpoints.Add(validPathpoint); } } for (int i = 1; i < validPathpoints.Count; i++) { //if(validPathpoints[i] != null && validPathpoints[i-1] != null) graphics.DrawLine(pen, validPathpoints[i - 1].X, validPathpoints[i - 1].Y, validPathpoints[i].X, validPathpoints[i].Y); } } graphics.Dispose(); DirectoryInfo di = Directory.CreateDirectory("renderings/strat" + analyseStratID); bitmap.Save("renderings/strat" + analyseStratID + "/" + round.roundID + ".png", ImageFormat.Png); bitmap.Dispose(); }); }