/// <summary> /// Gets the replay file json. /// </summary> /// <param name="mapname">Required</param> /// <param name="username">Optional, must provide username or rank</param> /// <param name="rank">Optional, must provide username or rank</param> /// <returns>Empty string on error, else replay json</returns> public static string GetReplayJson(string mapname, string username, int?rank) { string replayJson = string.Empty; long? mapId = GetMapIdFromMapName(mapname); if (mapId.HasValue) { if (rank.HasValue && rank.Value > 0 && rank <= _cacheMaptimes[mapId.Value].Count) { MapTimeModel maptime = _cacheMaptimes[mapId.Value][rank.Value - 1]; long userId = maptime.UserId; string replayFile = GetReplayFilename(mapname, userId); if (File.Exists(replayFile)) { replayJson = File.ReadAllText(replayFile); } } else if (!string.IsNullOrEmpty(username)) { long?userId = GetUserIdFromUserName(username); if (userId.HasValue) { string replayFile = GetReplayFilename(mapname, userId.Value); if (File.Exists(replayFile)) { replayJson = File.ReadAllText(replayFile); } } } } return(replayJson); }
public static void LoadAllStatistics(IDbConnection connection) { // Get all servers Dictionary <long, string> serverIdsShortNames = new Dictionary <long, string>(); // <serverId, shortName> var command = connection.CreateCommand(); command.CommandText = $@" SELECT ServerId, ServerNameShort FROM Servers "; var reader = command.ExecuteReader(); while (reader.Read()) { long serverId = (long)reader[0]; string serverShortName = (string)reader[1]; serverIdsShortNames.Add(serverId, serverShortName); } // Get all maps Dictionary <long, string> mapIdsNames = new Dictionary <long, string>(); // <mapId, mapName> command = connection.CreateCommand(); command.CommandText = $@" SELECT MapId, MapName FROM Maps "; reader = command.ExecuteReader(); while (reader.Read()) { long mapId = (long)reader[0]; string mapName = (string)reader[1]; mapIdsNames.Add(mapId, mapName); } // Get all users Dictionary <long, string> userIdsNames = new Dictionary <long, string>(); // <userId, userName> command = connection.CreateCommand(); command.CommandText = $@" SELECT UserId, UserName FROM Users "; reader = command.ExecuteReader(); while (reader.Read()) { long userId = (long)reader[0]; string userName = (string)reader[1]; userIdsNames.Add(userId, userName); } // Get highscores list for each map Dictionary <long, List <MapTimeModel> > maptimes = new Dictionary <long, List <MapTimeModel> >(); // <mapId, sorted times> foreach (var mapIdName in mapIdsNames) { maptimes.Add(mapIdName.Key, new List <MapTimeModel>()); command = connection.CreateCommand(); command.CommandText = $@" SELECT UserId, ServerId, TimeMs, PMoveTimeMs, Date FROM MapTimes WHERE MapId = {mapIdName.Key} ORDER BY TimeMs "; reader = command.ExecuteReader(); while (reader.Read()) { MapTimeModel time = new MapTimeModel(); time.MapId = mapIdName.Key; time.UserId = (long)reader[0]; time.ServerId = (long)reader[1]; time.TimeMs = (long)reader[2]; time.PmoveTimeMs = (long)reader[3]; time.Date = (string)reader[4]; maptimes[mapIdName.Key].Add(time); } } // Calculate global playertimes (top 15) const int MaxHighscores = 15; Dictionary <long, int[]> userHighscores = new Dictionary <long, int[]>(); // <userId, highscores[15]> foreach (var userIdName in userIdsNames) { long userId = userIdName.Key; int[] highscores = new int[MaxHighscores]; userHighscores.Add(userId, highscores); } foreach (var maptime in maptimes) { int maxIndex = MaxHighscores; if (maptime.Value.Count < maxIndex) { maxIndex = maptime.Value.Count; } for (int i = 0; i < maxIndex; ++i) { long userId = maptime.Value[i].UserId; userHighscores[userId][i]++; } } // Calculate score for each user Dictionary <long, int> totalScores = new Dictionary <long, int>(); // <userId, score> foreach (var userHighscore in userHighscores) { long userId = userHighscore.Key; int score = CalculateScore(userHighscore.Value); totalScores.Add(userId, score); } var sortedScores = totalScores.OrderByDescending(x => x.Value).ToList(); // Calculate the maps completed by each user Dictionary <long, List <MapTimeModel> > userMapCompletions = new Dictionary <long, List <MapTimeModel> >(); // <userId, all maps> foreach (var userIdName in userIdsNames) { userMapCompletions.Add(userIdName.Key, new List <MapTimeModel>()); } foreach (var maptime in maptimes) { foreach (var record in maptime.Value) { userMapCompletions[record.UserId].Add(record); } } var sortedMapCompletions = userMapCompletions.OrderByDescending(x => x.Value.Count).ToList(); // Calculate playerscores Dictionary <long, double> playerScores = new Dictionary <long, double>(); // <userId, % score> foreach (var userIdName in userIdsNames) { playerScores.Add(userIdName.Key, 0.0); } foreach (var totalScore in totalScores) { long userId = totalScore.Key; int completions = userMapCompletions[userId].Count; int score = totalScore.Value; double percent = 0.0; if (completions >= 50) { percent = (double)score / (completions * 25) * 100; } playerScores[userId] = percent; } var sortedPlayerScores = playerScores.OrderByDescending(x => x.Value).ToList(); // Update the cached statistics _cacheServerIdsShortNames = serverIdsShortNames; _cacheUserIdsNames = userIdsNames; _cacheMapIdsNames = mapIdsNames; _cacheMaptimes = maptimes; _cacheUserHighscores = userHighscores; _cacheTotalScores = sortedScores; _cacheUserMapCompletions = userMapCompletions; _cacheCompletions = sortedMapCompletions; _cachePercentScores = sortedPlayerScores; _cacheLastUpdated = DateTime.UtcNow; }