Example #1
0
        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);
            }
        }
Example #2
0
        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;
            }
        }