public async Task ClanDelete(CommandContext ctx, [Description("The clan Tag")] string clanTag) { await ctx.TriggerTypingAsync(); var userId = ctx.User?.Id ?? 0; Log.Info($"Requesting {nameof(ClanDelete)}({clanTag}) 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 platform = GetPlatform(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; } try { var putter = new Putter(platform, ConfigurationManager.AppSettings["ApiAdminKey"]); putter.DeleteClan(clanTag); await ctx.RespondAsync( $"The clan `{clanTag}` on `{platform}` was deleted from the site."); Log.Debug($"{nameof(ClanDelete)} returned ok."); } catch (Exception ex) { Log.Error($"{nameof(ClanDelete)}", ex); await ctx.RespondAsync( $"Sorry, {ctx.User?.Mention}. There was an error... the *Coder* will be notified of `{ex.Message}`."); } }
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; } }
public async Task ClanInactives(CommandContext ctx, [Description("The clan **tag**")] string clanTag) { try { if (!await CanExecute(ctx, Features.Clans)) { return; } await ctx.TriggerTypingAsync(); if (string.IsNullOrWhiteSpace(clanTag)) { await ctx.RespondAsync($"You must send a clan tag as parameter, {ctx.User.Mention}."); return; } Log.Debug($"Requesting {nameof(ClanInactives)}({clanTag})..."); var cfg = GuildConfiguration.FromGuild(ctx.Guild); var platform = GetPlatform(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; } var provider = new DbProvider(_connectionString); var clan = provider.GetClan(platform, clanTag); if (clan == null) { platform = platform == Platform.PS ? Platform.XBOX : Platform.PS; clan = provider.GetClan(platform, clanTag); if (clan == null) { await ctx.RespondAsync( $"Can't find on a clan with tag `[{clanTag}]`, {ctx.User.Mention}. Maybe my site doesn't track it yet... or you have the wrong clan tag."); return; } } if (!clan.Enabled) { await ctx.RespondAsync($"Data collection for this clan is **disabled**, the reason for this is {clan.DisabledReason}, {ctx.User.Mention}."); return; } var inactives = clan.Players.Where(p => !p.IsActive).ToArray(); if (inactives.Length <= 0) { await ctx.RespondAsync($"There are no inactive tankers on this clan, {ctx.User.Mention}."); return; } // To retrieve the last battle for (int i = 0; i < inactives.Length; i++) { inactives[i] = provider.GetPlayer(inactives[i].Id, true); } inactives = inactives.OrderBy(p => p.MonthBattles).ThenBy(p => p.LastBattle ?? DateTime.Today.AddYears(-5)).ToArray(); var sb = new StringBuilder(); sb.Append($"Information about `{clan.ClanTag}`'s {inactives.Length} inactives tankers on the {clan.Plataform}, {ctx.User.Mention}:"); sb.AppendLine(); var maxNameLength = inactives.Max(p => p.Name.Length); sb.AppendLine("```"); sb.AppendLine($"{platform.TagName().PadRight(maxNameLength)} {"Days".PadLeft(5)} {"Battles".PadLeft(7)} {"WN8".PadLeft(6)}"); foreach (var p in inactives.Take(30)) { sb.AppendLine($"{(p.Name ?? string.Empty).PadRight(maxNameLength)} {(DateTime.UtcNow - (p.LastBattle ?? DateTime.Today.AddYears(-5))).TotalDays.ToString("N0").PadLeft(5)} {p.MonthBattles.ToString("N0").PadLeft(7)} {p.TotalWn8.ToString("N0").PadLeft(6)}"); } sb.AppendLine("```"); var color = clan.InactivesWn8.ToColor(); var platformPrefix = clan.Plataform == Platform.PS ? "ps." : string.Empty; var embed = new DiscordEmbedBuilder { Title = $"{clan.ClanTag}'s Inactives Tankers", Description = sb.ToString(), Color = new DiscordColor(color.R, color.G, color.B), Url = $"https://{platformPrefix}wotclans.com.br/Clan/{clan.ClanTag}", Author = new DiscordEmbedBuilder.EmbedAuthor { Name = "WoTClans", Url = $"https://{platformPrefix}wotclans.com.br" }, Footer = new DiscordEmbedBuilder.EmbedFooter { Text = $"Calculated at {DateTime.UtcNow:yyyy-MM-dd HH:mm} UTC" } }; await ctx.RespondAsync("", embed : embed); } catch (Exception ex) { Log.Error($"Error calling {nameof(ClanInactives)}({clanTag})", ex); await ctx.RespondAsync( $"Sorry, {ctx.User.Mention}. There was an error... the *Coder* will be notified of `{ex.Message}`."); } }
public async Task Clan(CommandContext ctx, [Description("The clan **tag**")] string clanTag, [Description("Put `true` to dump all members of the clan")] bool all = false) { if (!await CanExecute(ctx, Features.Clans)) { return; } await ctx.TriggerTypingAsync(); if (string.IsNullOrWhiteSpace(clanTag)) { await ctx.RespondAsync($"You must send a clan tag as parameter, {ctx.User.Mention}."); return; } Log.Debug($"Requesting {nameof(Clan)}({clanTag}, {all})..."); var cfg = GuildConfiguration.FromGuild(ctx.Guild); var platform = GetPlatform(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; } var provider = new DbProvider(_connectionString); var clan = provider.GetClan(platform, clanTag); if (clan == null) { platform = platform == Platform.PS ? Platform.XBOX : Platform.PS; clan = provider.GetClan(platform, clanTag); if (clan == null) { await ctx.RespondAsync( $"Can't find on a clan with tag `[{clanTag}]`, {ctx.User.Mention}. Maybe my site doesn't track it yet... or you have the wrong clan tag."); return; } } var sb = new StringBuilder(); sb.Append($"Information about the `{clan.ClanTag}`"); if (!string.IsNullOrWhiteSpace(clan.Country)) { sb.Append($" ({clan.Country.ToUpperInvariant()})"); } sb.AppendLine($", on the {clan.Plataform}, {ctx.User.Mention}:"); if (!clan.Enabled) { sb.AppendLine($"Data collection for this clan is **disabled**, the reason for this is {clan.DisabledReason}."); } sb.AppendLine(); sb.AppendLine($"Active Members: {clan.Active}; Total Members: {clan.Count};"); sb.AppendLine($"Recent Win Rate: {clan.ActiveWinRate:P1}; Overall Win Rate: {clan.TotalWinRate:P1};"); sb.AppendLine($"Recent WN8t15: {clan.Top15Wn8:N0}; Overall WN8: {clan.TotalWn8:N0};"); if (clan.DeltaDayTop15Wn8.HasValue) { sb.AppendLine($"WN8t15 Variation from 1 day ago: {clan.DeltaDayTop15Wn8.Value:N0}"); } if (clan.DeltaWeekTop15Wn8.HasValue) { sb.AppendLine($"WN8t15 Variation from 1 week ago: {clan.DeltaWeekTop15Wn8.Value:N0}"); } if (clan.DeltaMonthTop15Wn8.HasValue) { sb.AppendLine($"WN8t15 Variation from 1 month ago: {clan.DeltaMonthTop15Wn8.Value:N0}"); } sb.AppendLine($"Recent Actives Battles: {clan.ActiveBattles:N0}; Recent Avg Tier: {clan.ActiveAvgTier:N1}"); sb.AppendLine(); sb.AppendLine("**Top 15 Active Players**"); foreach (var p in clan.Top15Players) { sb.AppendLine( $"{Formatter.MaskedUrl(p.Name, new Uri(p.PlayerOverallUrl))}, {p.MonthBattles} battles, WN8: {p.MonthWn8:N0}"); } var title = clan.ClanTag.EqualsCiAi(clan.Name) ? clan.ClanTag : $"{clan.ClanTag} - {clan.Name}"; var color = clan.Top15Wn8.ToColor(); var platformPrefix = clan.Plataform == Platform.PS ? "ps." : string.Empty; var embed = new DiscordEmbedBuilder { Title = title, Description = sb.ToString(), Color = new DiscordColor(color.R, color.G, color.B), Url = $"https://{platformPrefix}wotclans.com.br/Clan/{clan.ClanTag}", Author = new DiscordEmbedBuilder.EmbedAuthor { Name = "WoTClans", Url = $"https://{platform}wotclans.com.br" }, Footer = new DiscordEmbedBuilder.EmbedFooter { Text = $"Data calculated at {clan.Moment:yyyy-MM-dd HH:mm} UTC." } }; Log.Debug($"Returned {nameof(Clan)}({clan.Plataform}.{clan.ClanTag})"); await ctx.RespondAsync("", embed : embed); if (all) { // We need more responses, as discord limits the amount of data we can send on one message var allPlayers = clan.Players.OrderByDescending(p => p.MonthBattles).ThenByDescending(p => p.TotalBattles).ToArray(); const int pageSize = 15; var pages = allPlayers.Length / pageSize + 1; color = clan.TotalWn8.ToColor(); for (var currentPage = 0; currentPage < pages; ++currentPage) { sb.Clear(); title = (clan.ClanTag.EqualsCiAi(clan.Name) ? clan.ClanTag : $"{clan.ClanTag} - {clan.Name}") + $" - Page {currentPage + 1} of {pages}"; sb.Append($"All members of the `{clan.ClanTag}`"); if (!string.IsNullOrWhiteSpace(clan.Country)) { sb.Append($" ({clan.Country.ToUpperInvariant()})"); } sb.AppendLine($", on the {clan.Plataform}:"); sb.AppendLine(); foreach (var p in allPlayers.Skip(currentPage * pageSize).Take(pageSize)) { sb.AppendLine($"{Formatter.MaskedUrl(p.Name, new Uri(p.PlayerOverallUrl))}, {p.MonthBattles} battles, WN8: {p.MonthWn8:N0}"); } embed = new DiscordEmbedBuilder { Title = title, Description = sb.ToString(), Color = new DiscordColor(color.R, color.G, color.B), Url = $"https://{platformPrefix}wotclans.com.br/Clan/{clan.ClanTag}", Author = new DiscordEmbedBuilder.EmbedAuthor { Name = "WoTClans", Url = $"https://{platform}wotclans.com.br" }, Footer = new DiscordEmbedBuilder.EmbedFooter { Text = $"Page {currentPage + 1} of {pages}" } }; await ctx.RespondAsync("", embed : embed); } } }
public async Task ClanTopOnTank(CommandContext ctx, [Description("The clan **tag**")] string clanTag, [Description("The Tank name, as it appears in battles. If it has spaces, enclose it on quotes.")][RemainingText] string tankName) { if (!await CanExecute(ctx, Features.Clans)) { return; } await ctx.TriggerTypingAsync(); if (string.IsNullOrWhiteSpace(clanTag)) { await ctx.RespondAsync($"You must send a clan tag as parameter, {ctx.User.Mention}."); return; } Log.Debug($"Requesting {nameof(ClanTopOnTank)}({clanTag}, {tankName})..."); var cfg = GuildConfiguration.FromGuild(ctx.Guild); var platform = GetPlatform(clanTag, cfg.Plataform, out clanTag); if (!ClanTagRegex.IsMatch(clanTag)) { await ctx.RespondAsync($"You must send a **valid** clan **tag** as parameter, {ctx.User.Mention}."); return; } var provider = new DbProvider(_connectionString); var clan = provider.GetClan(platform, clanTag); if (clan == null) { platform = platform == Platform.PS ? Platform.XBOX : Platform.PS; clan = provider.GetClan(platform, clanTag); if (clan == null) { await ctx.RespondAsync( $"Can't find on a clan with tag `[{clanTag}]`, {ctx.User.Mention}. Maybe my site doesn't track it yet... or you have the wrong clan tag."); return; } } if (!clan.Enabled) { await ctx.RespondAsync( $"Data collection for the `[{clan.ClanTag}]` is disabled, {ctx.User.Mention}. Maybe the clan went too small, or inactive."); return; } var tankCommands = new TankCommands(); var tank = tankCommands.FindTank(platform, tankName, out _); if (tank == null) { await ctx.RespondAsync($"Can't find a tank with `{tankName}` on the name, {ctx.User.Mention}."); return; } var tr = provider.GetTanksReferences(tank.Plataform, null, tank.TankId, false, false, false).FirstOrDefault(); if (tr == null) { await ctx.RespondAsync($"Sorry, there is no tank statistics for the `{tank.Name}`, {ctx.User.Mention}."); return; } if (tr.Tier < 5) { await ctx.RespondAsync($"Sorry, this command is meant to be used only with tanks Tier 5 and above, {ctx.User.Mention}."); return; } var players = provider.GetClanPlayerIdsOnTank(platform, clan.ClanId, tr.TankId).ToList(); if (players.Count <= 0) { await ctx.RespondAsync($"No players from the `[{clan.ClanTag}]` has battles on the `{tank.Name}`, {ctx.User.Mention}, as far as the database is up to date."); return; } var waitMsg = await ctx.RespondAsync($"Please wait as data for {players.Count} tankers is being retrieved, {ctx.User.Mention}..."); var playerCommands = new PlayerCommands(); var fullPlayers = new ConcurrentBag <Player>(); var tasks = players.Select(async p => { var player = await playerCommands.GetPlayer(ctx, ((p.Plataform == Platform.XBOX) ? "x." : "ps.") + p.Name); if (player == null) { await ctx.RespondAsync($"Sorry, could not get updated information for player `{p.Name}`, {ctx.User.Mention}."); return; } fullPlayers.Add(player); }); await Task.WhenAll(tasks); await waitMsg.DeleteAsync(); var sb = new StringBuilder(); var maxNameLength = fullPlayers.Max(p => p.Name.Length); //sb.AppendLine($"Here `[{clan.ClanTag}]` top players on the `{tank.Name}`, {ctx.User.Mention}:"); //sb.AppendLine(); sb.AppendLine("```"); sb.AppendLine($"{platform.TagName().PadRight(maxNameLength)} {"Days".PadLeft(5)} {"Battles".PadLeft(7)} {"WN8".PadLeft(6)}"); foreach (var p in fullPlayers.OrderByDescending(p => p.Performance.All[tank.TankId].Wn8).Take(25)) { var tp = p.Performance.All[tank.TankId]; sb.AppendLine($"{(p.Name ?? string.Empty).PadRight(maxNameLength)} {(DateTime.UtcNow - tp.LastBattle).TotalDays.ToString("N0").PadLeft(5)} {tp.Battles.ToString("N0").PadLeft(7)} {tp.Wn8.ToString("N0").PadLeft(6)}"); } sb.AppendLine("```"); sb.AppendLine(); sb.AppendLine("This command is a **Premium** feature on the bot. For now it's free to use this command, but be advised that on the near future access will be restricted to Premium subscribers."); var color = clan.Top15Wn8.ToColor(); var platformPrefix = clan.Plataform == Platform.PS ? "ps." : string.Empty; var embed = new DiscordEmbedBuilder { Title = $"`{clan.ClanTag}` top players on the `{tank.Name}`", Description = sb.ToString(), Color = new DiscordColor(color.R, color.G, color.B), ThumbnailUrl = tank.SmallImageUrl, Url = $"https://{platformPrefix}wotclans.com.br/Clan/{clan.ClanTag}", Author = new DiscordEmbedBuilder.EmbedAuthor { Name = "WoTClans", Url = $"https://{platformPrefix}wotclans.com.br" }, Footer = new DiscordEmbedBuilder.EmbedFooter { Text = $"Calculated at {DateTime.UtcNow:yyyy-MM-dd HH:mm} UTC" } }; await ctx.RespondAsync("", embed : embed); }
public async Task Clan(CommandContext ctx, [Description("The clan **tag**")] string clanTag) { if (!await CanExecute(ctx, Features.Clans)) { return; } await ctx.TriggerTypingAsync(); if (string.IsNullOrWhiteSpace(clanTag)) { await ctx.RespondAsync($"You must send a clan tag as parameter, {ctx.User.Mention}."); return; } Log.Debug($"Requesting {nameof(Clan)}({clanTag})..."); 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; } var provider = new DbProvider(_connectionString); var clan = provider.GetClan(plataform, clanTag); if (clan == null) { if (plataform == Plataform.PS) { plataform = Plataform.XBOX; } else { plataform = Plataform.PS; } clan = provider.GetClan(plataform, clanTag); if (clan == null) { await ctx.RespondAsync($"Can't find on a clan with tag `[{clanTag}]`, {ctx.User.Mention}. Maybe my site doesn't track it yet... or you have the wrong clan tag."); return; } } var sb = new StringBuilder(); sb.Append($"Information about the `{clan.ClanTag}`"); if (!string.IsNullOrWhiteSpace(clan.Country)) { sb.Append($" ({clan.Country.ToUpperInvariant()})"); } sb.AppendLine($", on the {clan.Plataform}, {ctx.User.Mention}:"); if (!clan.Enabled) { sb.AppendLine("Data collection for this clan is **disabled**!"); } sb.AppendLine(); sb.AppendLine($"Active Members: {clan.Active}; Total Members: {clan.Count};"); sb.AppendLine($"Recent Win Rate: {clan.ActiveWinRate:P1}; Overall Win Rate: {clan.TotalWinRate:P1};"); sb.AppendLine($"Recent WN8t15: {clan.Top15Wn8:N0}; Overall WN8: {clan.TotalWn8:N0};"); if (clan.DeltaDayTop15Wn8.HasValue) { sb.AppendLine($"WN8t15 Variation from 1 day ago: {clan.DeltaDayTop15Wn8.Value:N0}"); } if (clan.DeltaWeekTop15Wn8.HasValue) { sb.AppendLine($"WN8t15 Variation from 1 week ago: {clan.DeltaWeekTop15Wn8.Value:N0}"); } if (clan.DeltaMonthTop15Wn8.HasValue) { sb.AppendLine($"WN8t15 Variation from 1 month ago: {clan.DeltaMonthTop15Wn8.Value:N0}"); } sb.AppendLine($"Recent Actives Battles: {clan.ActiveBattles:N0}; Recent Avg Tier: {clan.ActiveAvgTier:N1}"); sb.AppendLine(); sb.AppendLine("**Top 15 Active Players**"); foreach (var p in clan.Top15Players) { sb.AppendLine($"{Formatter.MaskedUrl(p.Name, new Uri(p.PlayerOverallUrl))}, {p.MonthBattles} battles, WN8: {p.MonthWn8:N0}"); } string title; if (clan.ClanTag.EqualsCiAi(clan.Name)) { title = clan.ClanTag; } else { title = $"{clan.ClanTag} - {clan.Name}"; } var color = clan.Top15Wn8.ToColor(); var plataformPrefix = clan.Plataform == Plataform.PS ? "ps." : string.Empty; var embed = new DiscordEmbedBuilder { Title = title, Description = sb.ToString(), Color = new DiscordColor(color.R, color.G, color.B), Url = $"https://{plataformPrefix}wotclans.com.br/Clan/{clan.ClanTag}", Author = new DiscordEmbedBuilder.EmbedAuthor { Name = "WoTClans", Url = $"https://{plataform}wotclans.com.br" }, Footer = new DiscordEmbedBuilder.EmbedFooter { Text = $"Data calculatet at {clan.Moment:yyyy-MM-dd HH:mm} UTC." } }; Log.Debug($"Returned {nameof(Clan)}({clan.Plataform}.{clan.ClanTag})"); await ctx.RespondAsync("", embed : embed); }