private static void ListClans(int size) { Fetcher fetcher = new Fetcher(@"C:\Projects\wotclans\Cache") { WebFetchInterval = TimeSpan.FromSeconds(1), ApplicationId = ConfigurationManager.AppSettings["WgApi"] }; Clan[] clans = fetcher.GetClans(Platform.XBOX, size).ToArray(); DbProvider provider = new DbProvider(ConfigurationManager.ConnectionStrings["Main"].ConnectionString); int newClans = 0; foreach (Clan clan in clans) { Console.Write(@"{0} ({1}). Já existe? ", clan.ClanTag, clan.ClanId); Clan existingClan = provider.GetClan(clan); Console.WriteLine(@"{0}", existingClan == null ? " não" : "Sim"); if (existingClan == null) { newClans++; } } Console.WriteLine(@"{0} novos clas!", newClans); Console.ReadLine(); }
private static Clan CalculateClan(ClanPlataform clan, DbProvider provider, DbRecorder recorder) { Log.DebugFormat("Calculando cla {0}@{1}...", clan.ClanTag, clan.Plataform); Clan cc = provider.GetClan(clan.Plataform, clan.ClanId); if (cc == null) { Log.Warn("O cla ainda não teve nenhum membro atualizado."); return(null); } if (cc.Count == 0) { Log.Warn("O cla ainda não teve nenhum membro atualizado."); return(null); } Log.InfoFormat("------------------------------------------------------------------"); Log.InfoFormat("cla: {0}@{1}", cc.ClanTag, cc.Plataform); Log.InfoFormat("# Membros: {0};{1};{2} - Patched: {3}", cc.Count, cc.Active, 0, cc.NumberOfPatchedPlayers); Log.InfoFormat("Batalhas: T:{0:N0};A:{1:N0};W:{2:N0}", cc.TotalBattles, cc.ActiveBattles, 0); recorder.SetClanCalculation(cc); return(cc); }
private IEnumerable <Clan> GetClans(Plataform plataform, IEnumerable <ClanPlataform> clans) { var clanPlataforms = clans as ClanPlataform[] ?? clans.ToArray(); if (!clanPlataforms.Any()) { yield break; } Log.DebugFormat("Procurando dados na plataforma {0}...", plataform); string server; switch (plataform) { case Plataform.XBOX: server = "api-xbox-console.worldoftanks.com"; break; case Plataform.PS: server = "api-ps4-console.worldoftanks.com"; break; default: throw new ArgumentOutOfRangeException(nameof(plataform), plataform, null); } var requestedClans = new HashSet <long>(clanPlataforms.Select(c => c.ClanId)); // Verifica se algum dos clãs foi encerrado string disbandedUrl = $"https://{server}/wotx/clans/info/?application_id={ApplicationId}&fields=clan_id%2Cis_clan_disbanded&clan_id={string.Join("%2C", requestedClans.Select(id => id.ToString()))}"; var json = GetContentSync($"DisbandedClan.{plataform}.{DateTime.UtcNow:yyyy-MM-dd.HHmm}.json", disbandedUrl, WebCacheAge, false, Encoding.UTF8).Content; var response = JsonConvert.DeserializeObject <ClansInfoResponse>(json); if (response.IsError) { Log.Error(response.Error); Log.ErrorFormat("Error on Request: {0}", disbandedUrl); yield break; } var disbandedClans = new HashSet <long>(response.Clans.Where(apiClanKv => apiClanKv.Value.IsDisbanded).Select(kv => kv.Key)); Log.WarnFormat("{0} Clãs foram desfeitos.", disbandedClans.Count); // Tira os debandados para não dar pau na serialização requestedClans.ExceptWith(disbandedClans); // Pega os dados normais string requestUrl = $"https://{server}/wotx/clans/info/?application_id={ApplicationId}&clan_id=" + $"{string.Join("%2C", requestedClans.Select(id => id.ToString()))}&fields=clan_id%2Ctag%2Cname%2Cmembers_count%2Ccreated_at%2Cis_clan_disbanded" + "%2Cmembers%2Cmembers.role%2Cmembers.account_name&extra=members"; json = GetContentSync($"InfoClan.{plataform}.{DateTime.UtcNow:yyyy-MM-dd.HHmm}.json", requestUrl, WebCacheAge, false, Encoding.UTF8).Content; response = JsonConvert.DeserializeObject <ClansInfoResponse>(json); if (response.IsError && response.Error?.Code == 504) { Log.Error(response.Error); Log.ErrorFormat("Error on Request: {0}", requestUrl); yield break; } foreach (var apiClanKv in response.Clans) { if (apiClanKv.Value.IsDisbanded) { Log.WarnFormat("Clã id {0} foi desfeito.", apiClanKv.Key); continue; } var clan = new Clan(plataform, apiClanKv.Key, apiClanKv.Value.Tag, apiClanKv.Value.Name) { CreatedAtUtc = apiClanKv.Value.CreatedAtUtc, MembershipMoment = DateTime.UtcNow }; if (apiClanKv.Value.Members.Any()) { foreach (var memberKv in apiClanKv.Value.Members) { clan.Add(new Player { Id = memberKv.Key, Rank = memberKv.Value.Rank, Plataform = plataform, Name = memberKv.Value.Name }); } } yield return(clan); } foreach (var id in disbandedClans) { yield return(new Clan(plataform, id, string.Empty) { IsDisbanded = true }); } }
private static void GetAllTanks(string[] args) { Fetcher fetcher = new Fetcher(ConfigurationManager.AppSettings["CacheDirectory"]) { WebFetchInterval = TimeSpan.FromSeconds(5), ApplicationId = ConfigurationManager.AppSettings["WgApi"] }; int topCount = 20; if (args.Length >= 1) { topCount = int.Parse(args[0]); } Log.InfoFormat("Top Count: {0}", topCount); string dir = "c:\\Projects\\wotclans\\TopTanks"; if (args.Length >= 2) { dir = args[2]; } Log.InfoFormat("Directory: {0}", dir); // Obtem todos os tanques do jogo Log.Debug("Obtendo todos os tanques do jogo..."); Dictionary <long, Tank> allTanks = fetcher.GetTanks(Platform.XBOX).ToDictionary(t => t.TankId); StringBuilder sb = new StringBuilder(); foreach (Tank tank in allTanks.Values) { sb.Append( $"{tank.TankId}\t{tank.Name}\t{tank.Images["big_icon"]}\t{tank.IsPremium}\t{tank.NationString}\t{tank.ShortName}\t{tank.Tag}\t{tank.Tier}\t{tank.TypeString}\r\n"); } string tanksFile = $"{dir}\\AllTanks.{DateTime.Today:yyyy-MM-dd}.txt"; File.WriteAllText(tanksFile, sb.ToString(), Encoding.UTF8); Log.InfoFormat("Salvos {0} tanques em {1}", allTanks.Count, tanksFile); string connectionString = ConfigurationManager.ConnectionStrings["Main"].ConnectionString; DbProvider provider = new DbProvider(connectionString); // Lista todos os clas XBOX Clan[] allClans = provider.GetClans().Where(c => c.Plataform == Platform.XBOX).Select(cp => provider.GetClan(cp)) .OrderByDescending(c => c.Top15Wn8).ToArray(); Log.InfoFormat("Obtidos {0} clas.", allClans.Length); // Seleciona a amostragem Clan[] topClans = allClans.Take(topCount).ToArray(); int topPlayersCount = topClans.Sum(c => c.Active); int i = allClans.Length - 1; List <Clan> bottonClans = new List <Clan>(); while (bottonClans.Sum(c => c.Active) < topPlayersCount && i >= 0) { bottonClans.Add(allClans[i--]); } string[] clanTags = new[] { "ETBR", "UNOT", "BOPBR", "BK", "FERAS", "BR", "VIS", "171BS", "GDAB3", "TCF", "DV", "TOPBR", "OWS", "AR-15", "DBD", "NT", "ITA", "13RCM", "BOPE", "-RSA-" }; foreach (Clan clanTag in topClans) { Console.WriteLine(@"cla {0}...", clanTag.Name); File.Delete($"{dir}\\AllStats.{clanTag}.{DateTime.Today:yyyy-MM-dd}.txt"); Clan cc = clanTag; foreach (Player player in cc.Players) { sb = new StringBuilder(); Console.WriteLine(@" Jogador {0}.{1}@{2}...", player.Id, player.Name, clanTag); Task <IEnumerable <Negri.Wot.WgApi.TankPlayer> > tanksTask = fetcher.GetTanksForPlayerAsync(Platform.XBOX, player.Id); tanksTask.Wait(); Negri.Wot.WgApi.TankPlayer[] tanks = tanksTask.Result.ToArray(); foreach (Negri.Wot.WgApi.TankPlayer t in tanks) { if (!allTanks.TryGetValue(t.TankId, out Tank td)) { td = new Tank { ShortName = "???", Tier = 0, TypeString = "???" }; } sb.Append( $"{cc.ClanId}\t{cc.ClanTag}\t{cc.Top15Wn8}\t{player.Id}\t{player.Name}\t{player.Rank}\t{player.MonthWinRate}\t{player.MonthWn8}\t{player.MonthBattles}\t"); sb.Append($"{t.TankId}\t{td.ShortName}\t{td.Tier}\t{td.Type}\t"); sb.Append( $"{t.BattleLifeTime.TotalMinutes:0}\t{t.LastBattle:yyyy-MM-dd}\t{t.MaxFrags}\t{t.MarkOfMastery}\t"); sb.Append( $"{t.All.Battles}\t{t.All.Wins}\t{t.All.Kills}\t{t.All.SurvivedBattles}\t{t.All.DamageDealt}\t{t.All.DamageAssisted}\t{t.All.DamageReceived}"); sb.AppendLine(); //Console.WriteLine(@" Tanque {0}.{1}...", t.TankId, td.ShortName); } File.AppendAllText($"{dir}\\AllStats.{clanTag}.{DateTime.Today:yyyy-MM-dd}.txt", sb.ToString(), Encoding.UTF8); } } }
/// <summary> /// Calcula todos os clas habilitados e os salva /// </summary> private static void CalculateAllClans() { string connectionString = ConfigurationManager.ConnectionStrings["Main"].ConnectionString; DbProvider provider = new DbProvider(connectionString); ClanPlataform[] clans = provider.GetClans().ToArray(); Log.InfoFormat("{0} clas devem ser calculados.", clans.Length); DbRecorder recorder = new DbRecorder(connectionString); FtpPutter putterXbox = new FtpPutter(ConfigurationManager.AppSettings["FtpFolder"], ConfigurationManager.AppSettings["FtpUser"], ConfigurationManager.AppSettings["FtpPassworld"]); FtpPutter putterPs = new FtpPutter(ConfigurationManager.AppSettings["PsFtpFolder"], ConfigurationManager.AppSettings["PsFtpUser"], ConfigurationManager.AppSettings["PsFtpPassworld"]); string resultDirectory = ConfigurationManager.AppSettings["ResultDirectory"]; string resultDirectoryPs = ConfigurationManager.AppSettings["PsResultDirectory"]; HashSet <string> already = new HashSet <string>(File.ReadAllLines(Path.Combine(resultDirectory, "CalcTask.txt"))); HashSet <string> alreadyPs = new HashSet <string>(File.ReadAllLines(Path.Combine(resultDirectoryPs, "CalcTask.txt"))); object o = new object(); // Calcula cada cla int doneCount = 0; Stopwatch sw = Stopwatch.StartNew(); Parallel.For(0, clans.Length, new ParallelOptions { MaxDegreeOfParallelism = 2 }, i => { ClanPlataform clan = clans[i]; bool done = false; if (clan.Plataform == Platform.XBOX) { done = already.Contains(clan.ClanTag); } else if (clan.Plataform == Platform.PS) { done = alreadyPs.Contains(clan.ClanTag); } if (done) { Log.InfoFormat("cla {0} de {1}: {2}@{3} feito anteriormente.", i + 1, clans.Length, clan.ClanTag, clan.Plataform); Interlocked.Increment(ref doneCount); return; } Log.InfoFormat("Processando cla {0} de {1}: {2}@{3}...", i + 1, clans.Length, clan.ClanTag, clan.Plataform); Stopwatch csw = Stopwatch.StartNew(); Clan cc = CalculateClan(clan, provider, recorder); Log.InfoFormat("Calculado cla {0} de {1}: {2}@{3} em {4:N1}s...", i + 1, clans.Length, clan.ClanTag, clan.Plataform, csw.Elapsed.TotalSeconds); if (cc != null) { Stopwatch fsw = Stopwatch.StartNew(); switch (cc.Plataform) { case Platform.XBOX: { string fileName = cc.ToFile(resultDirectory); Log.InfoFormat("Arquivo de resultado escrito em '{0}'", fileName); putterXbox.PutClan(fileName); lock (o) { File.AppendAllText(Path.Combine(resultDirectory, "CalcTask.txt"), $"{cc.ClanTag}\r\n", Encoding.UTF8); } } break; case Platform.PS: { string fileName = cc.ToFile(resultDirectoryPs); Log.InfoFormat("Arquivo de resultado escrito em '{0}'", fileName); putterPs.PutClan(fileName); lock (o) { File.AppendAllText(Path.Combine(resultDirectoryPs, "CalcTask.txt"), $"{cc.ClanTag}\r\n", Encoding.UTF8); } } break; case Platform.Virtual: break; default: throw new ArgumentOutOfRangeException(); } Log.InfoFormat("Upload do cla {0} de {1}: {2}@{3} em {4:N1}s...", i + 1, clans.Length, clan.ClanTag, clan.Plataform, fsw.Elapsed.TotalSeconds); } Interlocked.Increment(ref doneCount); Log.InfoFormat("Processado cla {0} de {1}: {2}@{3} em {4:N1}s. {5} totais.", i + 1, clans.Length, clan.ClanTag, clan.Plataform, csw.Elapsed.TotalSeconds, doneCount); }); TimeSpan calculationTime = sw.Elapsed; }