namespace Supercell.Laser.Server.Logic.Game { using Newtonsoft.Json; using Supercell.Laser.Logic.Club; using Supercell.Laser.Server.Database.Models; using Supercell.Laser.Server.Networking.Session; using System.Text; public class DataEntry { public DateTime Time { get; set; } [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] public int Online { get; set; } } public class DataContainer { public List Data { get; set; } } public static class Leaderboards { private static List Accounts; private static List RankedAccounts; private static List Alliances; private static Dictionary> Brawlers; private static Thread Thread; private static int timeg; private static StringBuilder FileLogger; public static void Init() { Accounts = new List(); RankedAccounts = new List(); Alliances = new List(); Brawlers = new Dictionary>(); Thread = new Thread(Update); Thread.Start(); FileLogger = new(); } public static Account[] GetAvatarRankingList() { return Accounts.ToArray(); } public static Account[] GetRankedRankingList() { return RankedAccounts.ToArray(); } public static Dictionary> GetBrawlersRankingList() { return Brawlers; } public static Alliance[] GetAllianceRankingList() { return Alliances.ToArray(); } private static void Update() { while (true) { try { // Fix 9: GetAllNames() вызывается один раз за цикл и передаётся // во все три ranking-метода. Раньше каждый метод делал свой // «SELECT id, name FROM alliances» — итого 3 запроса за цикл вместо 1. var allianceNames = Database.Alliances.GetAllNames(); // Строим новые списки в локальных переменных, публикуем атомарно. // Так читатели (GetAvatarRankingList / ToArray) не видят пустой список // в промежутке между обнулением и заполнением старого подхода. var newAccounts = Database.Accounts.GetRankingList(allianceNames); var newRankedAccounts = Database.Accounts.GetRankedRankingList(allianceNames); var newAlliances = Database.Alliances.GetRankingList(); var newBrawlers = Database.Accounts.GetBrawlersRankingList(allianceNames); Accounts = newAccounts; RankedAccounts = newRankedAccounts; Alliances = newAlliances; Brawlers = newBrawlers; } catch (Exception ex) { Logger.Error("[Leaderboards.Update] " + ex.Message); } // Fix 9: Интервал увеличен с 15 с до 120 с. Лидерборд — не real-time // данные; пересчёт каждые 15 с = 8 полных сканов таблицы аккаунтов // в минуту без реальной пользы. 2 минуты — разумный компромисс. Thread.Sleep(1000 * 120); } } } }