private static int Main(string[] args) { try { var sw = Stopwatch.StartNew(); ParseParans(args, out int ageHours, out int maxClans, out int maxRunMinutes, out bool noSaveOnDatabase, out TimeSpan webFetchInterval, out int maxToAutoAdd, out int hourToAutoAdd, out int autoMinNumberOfMembers); var saveOnDatabase = !noSaveOnDatabase; var cacheDirectory = ConfigurationManager.AppSettings["CacheDirectory"]; Log.Info("------------------------------------------------------------------------------------"); Log.Info("FetchClanMembership iniciando..."); Log.InfoFormat( "ageHours: {0}; maxClans: {1}; maxRunMinutes: {2}; cacheDirectory: {3}; noSaveOnDatabase:{4}; webFetchInterval:{5}", ageHours, maxClans, maxRunMinutes, cacheDirectory, noSaveOnDatabase, webFetchInterval); var connectionString = ConfigurationManager.ConnectionStrings["Main"].ConnectionString; var provider = new DbProvider(connectionString); var fetcher = new Fetcher(cacheDirectory) { WebCacheAge = TimeSpan.FromHours(ageHours - 1), WebFetchInterval = webFetchInterval, ApplicationId = ConfigurationManager.AppSettings["WgApi"] }; var recorder = new DbRecorder(connectionString); var mailSender = new MailSender(ConfigurationManager.AppSettings["SmtpHost"], int.Parse(ConfigurationManager.AppSettings["SmtpPort"]), true, ConfigurationManager.AppSettings["SmtpUsername"], ConfigurationManager.AppSettings["SmtpPassword"]) { From = new MailAddress(ConfigurationManager.AppSettings["SmtpUsername"], "Membership Service") }; // Verifica a necessidade de adicionar novos clãs ao sistema var clansToAdd = provider.GetClansToAdd().ToArray(); foreach (var clanToAdd in clansToAdd) { var clanWithId = fetcher.FindClan(clanToAdd.Plataform, clanToAdd.ClanTag); if (clanWithId != null) { var existingClan = provider.GetClan(clanWithId.Plataform, clanWithId.ClanId); if (existingClan != null) { if (existingClan.Enabled) { Log.WarnFormat( "Foi requerido adicionar o clã {0}@{1}, mas já existe no sistema o clã {2}.{3}@{4}.", clanToAdd.ClanTag, clanToAdd.Plataform, existingClan.ClanId, existingClan.ClanTag, existingClan.Plataform); mailSender.Send($"Clã {clanWithId.ClanTag} já existe e está habilitado", $"Id: {clanWithId.ClanId}; Plataforma: {clanWithId.Plataform}; URL: {GetClanUrl(clanWithId.Plataform, clanWithId.ClanTag)}"); } else { // Reabilitar o cla recorder.EnableClan(clanWithId.Plataform, clanWithId.ClanId); mailSender.Send($"Habilitado manualmente o clã {clanWithId.ClanTag}", $"Id: {clanWithId.ClanId}; Plataforma: {clanWithId.Plataform}; URL: {GetClanUrl(clanWithId.Plataform, clanWithId.ClanTag)}"); } } else { clanWithId.Country = clanToAdd.Country; recorder.Add(clanWithId); mailSender.Send($"Adicionado manualmente o clã {clanWithId.ClanTag}", $"Id: {clanWithId.ClanId}; Plataforma: {clanWithId.Plataform}; URL: {GetClanUrl(clanWithId.Plataform, clanWithId.ClanTag)}"); } } else { Log.WarnFormat( "Foi requerido adicionar o clã {0}@{1}, mas ele não foi encontrado, ou é muito pequeno.", clanToAdd.ClanTag, clanToAdd.Plataform); mailSender.Send($"Clã {clanToAdd.ClanTag}@{clanToAdd.Plataform} não adicionado", $"Foi requerido adicionar o clã {clanToAdd.ClanTag}@{clanToAdd.Plataform}, mas ele não foi encontrado, ou é muito pequeno."); } } recorder.ClearClansToAddQueue(); // Autocadastro de clãs if (maxToAutoAdd > 0 && DateTime.UtcNow.Hour == hourToAutoAdd) { var toAdd = fetcher.GetClans(Platform.XBOX, autoMinNumberOfMembers) .Where(c => !provider.ClanExists(c.Plataform, c.ClanId)) .Concat(fetcher.GetClans(Platform.PS, autoMinNumberOfMembers) .Where(c => !provider.ClanExists(c.Plataform, c.ClanId))) .OrderByDescending(c => c.AllMembersCount).ThenBy(c => c.ClanId).ToArray(); foreach (var c in toAdd.Take(maxToAutoAdd)) { recorder.Add(c); mailSender.Send($"Adicionado automaticamente o clã {c.ClanTag}@{c.Plataform}", $"Id: {c.ClanId}, Plataforma: {c.Plataform}; Membros: {c.AllMembersCount}; URL: {GetClanUrl(c.Plataform, c.ClanTag)}"); } // Readição de clãs pequenos ou que ficaram inativos recorder.ReAddClans(maxToAutoAdd); } var clans = provider.GetClanMembershipUpdateOrder(maxClans, ageHours).ToArray(); Log.InfoFormat("{0} clãs devem ser atualizados.", clans.Length); if (clans.Length == 0) { Log.Info("Nenhum clã para atualizar."); return(0); } var clansToRename = new List <Clan>(); var clansToUpdate = fetcher.GetClans(clans).ToArray(); // Clãs debandados foreach (var clan in clansToUpdate.Where(c => c.IsDisbanded)) { var disbandedClan = provider.GetClan(clan.Plataform, clan.ClanId); if (saveOnDatabase) { recorder.DisableClan(disbandedClan.Plataform, disbandedClan.ClanId, DisabledReason.Disbanded); var putter = new Putter(disbandedClan.Plataform, ConfigurationManager.AppSettings["ApiAdminKey"]); putter.DeleteClan(disbandedClan.ClanTag); } var sb = new StringBuilder(); sb.AppendLine( $"Clã {disbandedClan.ClanTag}, id {disbandedClan.ClanId}, no {disbandedClan.Plataform}, com {disbandedClan.Count} jogadores, foi debandado."); sb.AppendLine($"WN8t15: {disbandedClan.Top15Wn8:N0} em {disbandedClan.Moment:yyyy-MM-dd HH:mm:ss}"); sb.AppendLine($"URL: {GetClanUrl(disbandedClan.Plataform, disbandedClan.ClanTag)}"); sb.AppendLine(); sb.AppendLine("Jogadores:"); foreach (var player in disbandedClan.Players) { sb.AppendLine( $"{player.Name}: WN8 recente de {player.MonthWn8:N0} em {player.MonthBattles:N0}"); } mailSender.Send($"Clã {disbandedClan.ClanTag}@{disbandedClan.Plataform} foi debandado", sb.ToString()); } // Clãs que ficaram pequenos demais foreach (var clan in clansToUpdate.Where(c => !c.IsDisbanded && c.Count < 4)) { if (saveOnDatabase) { recorder.DisableClan(clan.Plataform, clan.ClanId, DisabledReason.TooSmall); } mailSender.Send($"Clã {clan.ClanTag}@{clan.Plataform} foi suspenso", $"Clã {clan.ClanTag}@{clan.Plataform} com {clan.Count} jogadores foi suspenso de atualizações futuras. " + $"URL: {GetClanUrl(clan.Plataform, clan.ClanTag)}"); } foreach (var clan in clansToUpdate.Where(c => !c.IsDisbanded && c.Count >= 4)) { Log.DebugFormat("Clã {0}.{1}@{2}...", clan.ClanId, clan.ClanTag, clan.Plataform); if (saveOnDatabase) { recorder.Set(clan, true); if (clan.HasChangedTag) { clansToRename.Add(clan); } } } if (clansToRename.Any(c => c.Plataform == Platform.XBOX)) { var putter = new FtpPutter(ConfigurationManager.AppSettings["FtpFolder"], ConfigurationManager.AppSettings["FtpUser"], ConfigurationManager.AppSettings["FtpPassworld"]); var resultDirectory = Path.Combine(ConfigurationManager.AppSettings["ResultDirectory"], "Clans"); foreach (var clan in clansToRename.Where(c => c.Plataform == Platform.XBOX)) { Log.InfoFormat("O clã {0}.{1}@{2} teve o tag trocado a partir de {3}.", clan.ClanId, clan.ClanTag, clan.Plataform, clan.OldTag); // Faz copia do arquivo local, e o upload com o novo nome string oldFile = Path.Combine(resultDirectory, $"clan.{clan.OldTag}.json"); if (File.Exists(oldFile)) { string newFile = Path.Combine(resultDirectory, $"clan.{clan.ClanTag}.json"); File.Copy(oldFile, newFile, true); _ = Task.Run(() => { try { putter.PutClan(newFile); putter.DeleteFile($"Clans/clan.{clan.OldTag}.json"); putter.SetRenameFile(clan.OldTag, clan.ClanTag); } catch (Exception ex) { Log.Error($"Error on XBOX renaming clan {clan.OldTag} to {clan.ClanTag}", ex); } }); } mailSender.Send($"Clã Renomeado: {clan.OldTag} -> {clan.ClanTag} em {clan.Plataform}", $"URL: {GetClanUrl(clan.Plataform, clan.ClanTag)}"); } } if (clansToRename.Any(c => c.Plataform == Platform.PS)) { var putter = new FtpPutter(ConfigurationManager.AppSettings["PsFtpFolder"], ConfigurationManager.AppSettings["PsFtpUser"], ConfigurationManager.AppSettings["PsFtpPassworld"]); var resultDirectory = ConfigurationManager.AppSettings["PsResultDirectory"]; foreach (var clan in clansToRename.Where(c => c.Plataform == Platform.PS)) { Log.InfoFormat("O clã {0}.{1}@{2} teve o tag trocado a partir de {3}.", clan.ClanId, clan.ClanTag, clan.Plataform, clan.OldTag); // Faz copia do arquivo local, e o upload com o novo nome string oldFile = Path.Combine(resultDirectory, $"clan.{clan.OldTag}.json"); if (File.Exists(oldFile)) { string newFile = Path.Combine(resultDirectory, $"clan.{clan.ClanTag}.json"); File.Copy(oldFile, newFile, true); _ = Task.Run(() => { try { putter.PutClan(newFile); putter.DeleteFile($"Clans/clan.{clan.OldTag}.json"); putter.SetRenameFile(clan.OldTag, clan.ClanTag); } catch (Exception ex) { Log.Error($"Error on PS renaming clan {clan.OldTag} to {clan.ClanTag}", ex); } }); } mailSender.Send($"Clã Renomeado: {clan.OldTag} -> {clan.ClanTag} em {clan.Plataform}", $"URL: {GetClanUrl(clan.Plataform, clan.ClanTag)}"); } } // Tempo extra para os e-mails terminarem de serem enviados Log.Info("Esperando 2 minutos antes de encerrar para terminar de enviar os e-mails..."); Thread.Sleep(TimeSpan.FromMinutes(2)); Log.InfoFormat("FetchClanMembership terminando normalmente em {0}.", sw.Elapsed); return(0); } catch (Exception ex) { Log.Fatal(ex); Console.WriteLine(ex); return(1); } }
public async Task SetClan(CommandContext ctx, [Description("The clan tag")] string clanTag, [Description("The clan flag")] string flagCode = null, [Description("Enable or Disable the Clan")] bool enable = true, [Description("To ban or not a clan from the site")] bool isBan = false) { await ctx.TriggerTypingAsync(); var userId = ctx?.User?.Id ?? 0; Log.Info($"Requesting {nameof(SetClan)} by {userId}..."); if (userId != _coder) { var emoji = DiscordEmoji.FromName(ctx.Client, ":no_entry:"); var embed = new DiscordEmbedBuilder { Title = "Access denied", Description = $"{emoji} You may be a *coder*, but you are not **The Coder**!", Color = DiscordColor.Red }; await ctx.RespondAsync("", embed : embed); return; } var cfg = GuildConfiguration.FromGuild(ctx.Guild); var plataform = GetPlataform(clanTag, cfg.Plataform, out clanTag); clanTag = clanTag.Trim('[', ']'); clanTag = clanTag.ToUpperInvariant(); if (!ClanTagRegex.IsMatch(clanTag)) { await ctx.RespondAsync($"You must send a **valid** clan **tag** as parameter, {ctx.User.Mention}."); return; } if (!string.IsNullOrWhiteSpace(flagCode)) { flagCode = flagCode.RemoveDiacritics().ToUpperInvariant(); if (flagCode.Length != 2) { await ctx.RespondAsync($"The flag code must be 2 letters only, {ctx.User.Mention}."); return; } } Log.Warn($"{nameof(SetClan)}({clanTag}, {plataform}, {flagCode}, {enable}, {isBan})..."); try { await ctx.TriggerTypingAsync(); var provider = new DbProvider(_connectionString); var recorder = new DbRecorder(_connectionString); var cacheDirectory = ConfigurationManager.AppSettings["CacheDir"] ?? Path.GetTempPath(); var webCacheAge = TimeSpan.FromHours(4); var appId = ConfigurationManager.AppSettings["WgAppId"] ?? "demo"; var fetcher = new Fetcher(cacheDirectory) { ApplicationId = appId, WebCacheAge = webCacheAge, WebFetchInterval = TimeSpan.FromSeconds(1) }; var clan = provider.GetClan(plataform, clanTag); if (clan == null && enable) { // Check to add... await ctx.RespondAsync($"Not found `{clanTag}` on the database. Searching the WG API..."); await ctx.TriggerTypingAsync(); var clanOnSite = fetcher.FindClan(plataform, clanTag, true); if (clanOnSite == null) { await ctx.RespondAsync($"Not found `{clanTag}` on the WG API for `{plataform}`. Check the clan tag."); return; } if (clanOnSite.AllMembersCount < 7) { await ctx.RespondAsync($"The clan `{clanTag}` on `{plataform}` has only {clanOnSite.AllMembersCount}, and will not be added to the system."); return; } clanOnSite.Country = flagCode; recorder.Add(clanOnSite); await ctx.RespondAsync($"The clan `{clanTag}` on `{plataform}` with {clanOnSite.AllMembersCount} members was added to the system and " + $"should appear on the site in ~12 hours. Keep playing to achieve at least 7 members with 21 recent battles and appear on the default view."); Log.Info($"Added {plataform}.{clanTag}"); return; } if (!clan.Enabled && enable) { // Can be enabled? var clanOnSite = fetcher.GetClans(new[] { clan }).FirstOrDefault(); if (clanOnSite == null) { await ctx.RespondAsync($"Not found `{clanTag}` on the WG API for `{plataform}`. Check the clan tag."); return; } if (clanOnSite.IsDisbanded) { await ctx.RespondAsync($"The clan `{clanTag}` on `{plataform}` was disbanded."); return; } if (clanOnSite.Count < 7) { await ctx.RespondAsync($"The clan `{clanTag}` on `{plataform}` has only {clanOnSite.Count} members and will not be enabled."); return; } if (clan.DisabledReason == DisabledReason.Banned) { await ctx.RespondAsync($"The clan `{clanTag}` ({clan.ClanId}) on `{plataform}` was **banned** from the site."); return; } recorder.EnableClan(clanOnSite.Plataform, clanOnSite.ClanId); await ctx.RespondAsync($"The clan `{clanTag}` on `{plataform}` disabled for `{clan.DisabledReason}` is enabled again."); Log.Info($"Enabled {plataform}.{clanTag}"); } else if (clan.Enabled && !enable) { if (isBan) { recorder.DisableClan(clan.Plataform, clan.ClanId, DisabledReason.Banned); await ctx.RespondAsync($"The clan `{clanTag}` ({clan.ClanId}) on `{plataform}` was **BANNED** from the site."); Log.Warn($"BANNED {plataform}.{clanTag}"); } else { recorder.DisableClan(clan.Plataform, clan.ClanId, DisabledReason.Unknow); await ctx.RespondAsync($"The clan `{clanTag}` ({clan.ClanId}) on `{plataform}` was **disabled** from the site."); Log.Warn($"Disabled {plataform}.{clanTag}"); } } // change flag? flagCode = flagCode ?? string.Empty; if (flagCode.ToUpperInvariant() != (clan.Country ?? string.Empty).ToUpperInvariant()) { recorder.SetClanFlag(clan.Plataform, clan.ClanId, flagCode); await ctx.RespondAsync($"The flag of the clan `{clanTag}` on `{plataform}` was changed to `{flagCode}`."); Log.Info($"Flag changed on {plataform}.{clanTag} to {flagCode}."); } await ctx.RespondAsync($"all done for `{clan.ClanTag}` on `{plataform}`."); } catch (Exception ex) { Log.Error($"{nameof(SetClan)}", ex); await ctx.RespondAsync($"Sorry, {ctx.User.Mention}. There was an error... the *Coder* will be notified of `{ex.Message}`."); return; } }