private async Task <bool> VerificarAsync(DiscordChannel channel, DiscordUser autor, int time = 30) { DiscordMessage verificacion = await channel.SendMessageAsync(EasyDualLanguageFormatting("¿Estas seguro?", "Are you sure?")); await WoteAsync(verificacion, false); HelperMethods.Delay(1000); for (int i = 0; i < time; i++) { IReadOnlyList <DiscordUser> reaccionesOK = await verificacion.GetReactionsAsync(DiscordEmoji.FromName(Client, ":white_check_mark:")); IReadOnlyList <DiscordUser> reaccionesNOPE = await verificacion.GetReactionsAsync(DiscordEmoji.FromName(Client, ":x:")); if (reaccionesOK.Contains(autor)) { await verificacion.DeleteAsync(); return(true); } if (reaccionesNOPE.Contains(autor)) { await verificacion.DeleteAsync(); return(false); } HelperMethods.Delay(1000); } await verificacion.DeleteAsync(); return(false); }
private async Task <uint> GetAwardReactionCount(DiscordMessage message, DiscordMember messageAuthor) { uint awardReactionCount = 0; try { var cookieEmoji = DiscordEmoji.FromUnicode(EmojiMap.Cookie); var cookieReactionUsers = await message.GetReactionsAsync(cookieEmoji); if (cookieReactionUsers != null) { var skipAuthor = false; #if DEBUG skipAuthor = true; #endif awardReactionCount = (uint)cookieReactionUsers .Select(u => u.Id) .Distinct() .Count(x => skipAuthor || x != messageAuthor.Id); } } catch (Exception ex) { await _discordErrorLogger.LogDiscordError(ex.ToString()); } return(awardReactionCount); }
public async Task AddUnhandedReactionRolesAsync() { await _semaphoreLock.WaitAsync(); // Get all user reactions with the FAQ emoji, max users is the guild member count var userReactions = (await _lastMessage.GetReactionsAsync(_config.FaqRoleEmoji, _textChannel.Guild.MemberCount)) .Where(x => !x.IsSelf(_discordClient)); var role = _textChannel.Guild.GetRole(_config.FaqRoleId); foreach (var unhandledUserReaction in userReactions) { var member = await _textChannel.Guild.GetMemberAsync(unhandledUserReaction.Id); if (member != null && member.Roles.All(x => x.Id != _config.FaqRoleId)) { await member.GrantRoleAsync(role); } await _lastMessage.DeleteReactionAsync(_config.FaqRoleEmoji, unhandledUserReaction); } _semaphoreLock.Release(); }
private static async Task CheckMediaTalkAsync(DiscordClient client, DiscordChannel channel, DiscordMessage message, DiscordEmoji emoji) { if (!Config.Moderation.Channels.Contains(channel.Id)) { return; } // message.Timestamp throws if it's not in the cache AND is in local time zone if (DateTime.UtcNow - message.CreationTimestamp > Config.ModerationTimeThreshold) { return; } if (message.Reactions.Any(r => r.Emoji == emoji && (r.IsMe || r.Count < Config.Moderation.StarbucksThreshold))) { return; } if (message.Author.IsWhitelisted(client, channel.Guild)) { return; } var users = await message.GetReactionsAsync(emoji).ConfigureAwait(false); var members = users .Select(u => channel.Guild .GetMemberAsync(u.Id) .ContinueWith(ct => ct.IsCompletedSuccessfully ? ct : Task.FromResult((DiscordMember)null), TaskScheduler.Default)) .ToList() //force eager task creation .Select(t => t.Unwrap().ConfigureAwait(false).GetAwaiter().GetResult()) .Where(m => m != null) .ToList(); var reporters = new List <DiscordMember>(Config.Moderation.StarbucksThreshold); foreach (var member in members) { if (member.IsCurrent) { return; } if (member.Roles.Any()) { reporters.Add(member); } } if (reporters.Count < Config.Moderation.StarbucksThreshold) { return; } await message.ReactWithAsync(emoji).ConfigureAwait(false); await client.ReportAsync(Config.Reactions.Starbucks + " Media talk report", message, reporters, null, ReportSeverity.Medium).ConfigureAwait(false); }
public async Task EventCheck(CommandContext ctx, DiscordMessage message, DiscordEmoji reaction) { await ctx.Message.DeleteAsync(); await ctx.TriggerTypingAsync(); var allReactions = new List <DiscordUser>(); var reactions = await message.GetReactionsAsync(reaction); while (reactions.Count() != 0) { allReactions.AddRange(reactions); reactions = await message.GetReactionsAsync(reaction, after : reactions.Last().Id); } var allReactionsMembers = await Task.WhenAll(allReactions.Select(async x => { try { await Task.Delay(400); return(await ctx.Guild.GetMemberAsync(x.Id)); } catch { } return(null); })); var reactionsList = allReactionsMembers.OrderByDescending(x => x.CreationTimestamp).Select(x => $"C: **{x.CreationTimestamp:dd.MM.yyyy}** J: **{x.JoinedAt:dd.MM.yyyy}** V: **{VoiceListener.GetUpdatedVoiceTime(x.Id)}** \n" + $"{x.Username} ({x.Id})").ToList(); var members_pagination = Utility.GeneratePagesInEmbeds(reactionsList, $"Список проголосовавших (По дате создания аккаунта)."); var interactivity = ctx.Client.GetInteractivity(); if (members_pagination.Count() > 1) { await interactivity.SendPaginatedMessageAsync(await ctx.Member.CreateDmChannelAsync(), ctx.User, members_pagination, timeoutoverride : TimeSpan.FromMinutes(5)); } else { await ctx.Member.SendMessageAsync(embed : members_pagination.First().Embed); } }
private async Task TallyVotes() { for (int i = 0; i < optionEmojis.Count; i++) { IReadOnlyList <DiscordUser> voters = await pollMessage.GetReactionsAsync(optionEmojis[i]); foreach (DiscordUser vote in voters) { voter.Vote(vote.Id.ToString() + i.ToString(), i); } } return; }
private static async Task SetReactions(DiscordMessage message, IEnumerable <Answer> answers, bool processOld = false, bool deleteOld = true) { var existingReactions = message.Reactions; var answerEmojis = answers.Select(a => a.Emoji).ToArray(); bool reactionsOk = existingReactions.Count() == answers.Count() ? existingReactions.Select(r => r.Emoji).Zip(answerEmojis).All(p => p.First.Id == p.Second.Id) : false; if (reactionsOk) { //Clean others foreach (var p in existingReactions.SelectMany(r => message.GetReactionsAsync(r.Emoji).Result.Select((u) => (User: u, Reaction: r)))) { if (p.User.IsCurrent) { continue; } if (processOld && answerEmojis.Contains(p.Reaction.Emoji)) { await answers.FirstOrDefault(a => a.Emoji == p.Reaction.Emoji).InvokeFromEmoji(p.User, message); } if (deleteOld) { await message.DeleteReactionAsync(p.Reaction.Emoji, p.User); } } } else { //Clear, replace await message.DeleteAllReactionsAsync(); foreach (var emoji in answerEmojis) { await Task.Delay(100); //Will it suffice? await message.CreateReactionAsync(emoji); } } }
public static async Task <Dictionary <DiscordMember, DiscordGuildEmoji> > GetVotes(DiscordMessage m) { var d = new Dictionary <DiscordMember, DiscordGuildEmoji>(); foreach (var discordReaction in (await Global.Game.Guild.GetEmojisAsync())) { foreach (var discordUserReact in (await m.GetReactionsAsync(discordReaction))) { if (!discordUserReact.IsCurrent) { d.Add(discordUserReact.GetMember(), discordReaction); } // Console.WriteLine($"Reaction : {discordReaction.Emoji.Name} : {discordReaction.Count}"); } } Game.WriteDebug($"Debug"); foreach (var(key, value) in d) { Game.WriteDebug($"\t{key} : {value}"); } return(d); }
public static void GetReactions(DiscordClient client, DiscordMessage msg) { ReactedPlayers.Clear(); DiscordEmoji afk = DiscordEmoji.FromName(client, ":ZzZz:"); foreach (string role in emojis) { foreach (DiscordUser u in msg.GetReactionsAsync(DiscordEmoji.FromName(client, role)).Result) { using (Player p = new Player(u)) { p.Role = role; Player afk_P = p; afk_P.Role = ":ZzZz:"; if (!ReactedPlayers.Contains(afk_P)) { ReactedPlayers.Add(p); } } } } }
private async Task <EncounterData> Encounter(string enemyPath, int enemyLevel, string enemyName) { try { var path = ImageGenerator.CreateOrGetImage(enemyPath, BackgroundPath, CurrentHP / MaxHP); var url = await ImageGenerator.GetImageURL(path); var currentUserIds = UserIds.ToList(); var maxHPEnemy = enemyLevel * 50 * random.Range(0.8f, 1.5f); var currentHPEnemy = maxHPEnemy; DiscordMessage msg = null; var actions = Actions.ActionBase.GetAllActions(); var turnCount = 0; var additional = ""; while (true) { turnCount++; var healthPercentage = CurrentHP / MaxHP; var healthPercentageEnemy = currentHPEnemy / maxHPEnemy; var embed = Bot.GetDefaultEmbed() .WithImageUrl(url) .AddField("Quest", QuestName) .WithColor(new DiscordColor(1f, healthPercentage, healthPercentage)) .AddField("__Encounter__", $"{enemyName} - LVL {enemyLevel}") .AddField($"HP - {CurrentHP.ToString("0.00")} / {MaxHP.ToString("0.00")}", $"`{ProgressBar.GetProcessBar(healthPercentage)}`") .AddField($"Enemy - {currentHPEnemy.ToString("0.00")} / {maxHPEnemy.ToString("0.00")}", $"`{ProgressBar.GetProcessBar(healthPercentageEnemy)}`"); if (!string.IsNullOrEmpty(additional)) { embed.AddField("Info", additional); } if (msg != null) { await msg.DeleteAsync(); await Task.Delay(500); } msg = await Channel.SendMessageAsync(embed : embed); await Task.Delay(500); #region Get Reactions var currentPlayerActions = currentUserIds.ToDictionary(x => x, k => - 1); async Task CollectActions(CancellationToken token) { while (currentPlayerActions.Values.Any(x => x == -1)) { try { if (token.IsCancellationRequested) { return; } await Task.Delay(1000); foreach (var action in actions) { if (token.IsCancellationRequested) { return; } var reactions = await msg.GetReactionsAsync(action.GetEmoji()); await Task.Delay(500); foreach (var user in reactions) { if (user.IsBot) { continue; } if (currentUserIds.Contains(user.Id)) { Logger.Info($"Found {user.Id} with action {action.GetType().Name}"); currentPlayerActions[user.Id] = action.Id; } } } } catch (System.Exception ex) { Logger.Error(ex); } } } #region Add Reactions foreach (var action in actions) { await msg.CreateReactionAsync(action.GetEmoji()); await Task.Delay(500); } #endregion Add Reactions using (var timeout = new CancellationTokenSource()) { var task = CollectActions(timeout.Token); var completed = await Task.WhenAny(Task.Delay(TimeSpan.FromMinutes(1), timeout.Token), task); if (completed == task) { timeout.Cancel(); await task; } else { Logger.Info("TIMEOUT"); } } #endregion Get Reactions #region Handle Actions var totalAttacked = 0f; var totalBlocked = 0f; var ranPlayers = new List <ulong>(); foreach (var kv in currentPlayerActions) { if (kv.Value == -1) { continue; } var action = actions.First(x => x.Id == kv.Value); if (action != null) { var playerId = kv.Key; var type = action.GetType(); if (type == typeof(Flee)) { //remove from current party ranPlayers.Add(playerId); _ = currentUserIds.Remove(playerId); } else if (type == typeof(Attack)) { var player = Player.GetPlayer(Channel.GuildId, playerId); totalAttacked += player.GetAttack(); } else if (type == typeof(Defend)) { var player = Player.GetPlayer(Channel.GuildId, playerId); totalBlocked += player.GetAttack(); } } } //LEAVE IF NO PLAYERS REMAIN if (currentUserIds.Count == 0) { await msg.DeleteAsync(); await Task.Delay(500); var exp = CalculateExp(enemyLevel, currentHPEnemy, maxHPEnemy); var gold = CalculateGold(enemyLevel, currentHPEnemy, maxHPEnemy); foreach (var id in ranPlayers) { var player = Player.GetPlayer(Channel.GuildId, id); player.AddExperience(exp); player.AddGold(gold); MaxHP -= player.GetTotalHP(); player.Update(); } return(new EncounterData { Message = $"The remaining party ran away safely, and received {exp} exp and {gold} gold." }); } currentHPEnemy -= totalAttacked; if (currentHPEnemy <= 0f) { //victory await msg.DeleteAsync(); var players = Player.GetPlayers(Channel.GuildId, currentUserIds); var exp = CalculateExp(enemyLevel, 0, 1); var gold = CalculateGold(enemyLevel, 0, 1); foreach (var player in players) { player.Victory(exp, gold); player.Update(); } await Task.Delay(500); return(new EncounterData() { Ids = currentPlayerActions.Keys, Message = $"Everyone pulled together, and defeated the enemy in {turnCount} turns!\nReceived a total of {exp} exp and {gold} gold.", }); } var damage = CalculateDamage(enemyLevel); CurrentHP -= Math.Max(0, damage - totalBlocked); additional = $"Dealt {totalAttacked.ToString("0.00")} damage, and received {Math.Max(0, damage - totalBlocked).ToString("0.00")} damage"; if (CurrentHP <= 0f) { //dead await msg.DeleteAsync(); var players = Player.GetPlayers(Channel.GuildId, currentUserIds); var exp = (long)Math.Round(CalculateExp(enemyLevel, 0, 1) * 0.75f); foreach (var player in players) { player.CurrentMercenaries = 0; player.AddExperience(-exp); player.Update(); } await Task.Delay(500); return(new EncounterData { Ids = null, Message = $"Everyone died in {turnCount} turns and lost {exp} exp." }); } #endregion Handle Actions } } catch (System.Exception ex) { Logger.Error(ex); return(new EncounterData()); } }
async void TimerUpdate(object o) { duel.minutes -= 10; if (duel.minutes <= 0) { var c = await Program.bot.GetChannelAsync(Program.config.ChannelForDuels); DiscordMessage mess1 = null, mess2 = null; DiscordMember mem1 = null, mem2 = null; try { mess1 = await c.GetMessageAsync(duel.message1); } catch { } try { mess2 = await c.GetMessageAsync(duel.message2); } catch { } try { mem1 = await c.Guild.GetMemberAsync(duel.duelist1); } catch { } try { mem2 = await c.Guild.GetMemberAsync(duel.duelist2); } catch { } if (!duel.flag) { StringBuilder b = new StringBuilder(""); if (mess1 == null || mess2 == null) { if (mess1 != null) { b.Append($"\n**{mem1.DisplayName}** has won as his opponent did not finish his work on time!\nWinner gets **3** points."); await Duelists.UpdateAsync(duel.duelist1, 3, 1, 1); await Duelists.UpdateAsync(duel.duelist2, 0, 1, 0); } else if (mess2 != null) { b.Append($"\n**{mem2.DisplayName}** has won as his opponent did not finish his work on time!\nWinner gets **3** points."); await Duelists.UpdateAsync(duel.duelist2, 3, 1, 1); await Duelists.UpdateAsync(duel.duelist1, 0, 1, 0); } else { b.Append("\nBoth duelists did not finish their work on time and lost :("); await Duelists.UpdateAsync(duel.duelist2, 0, 1, 0); await Duelists.UpdateAsync(duel.duelist1, 0, 1, 0); } await DeleteAsync(); } else { b.Append("\nResults of the duel will be notified in **12 hours**."); duel.minutes = 720; duel.flag = true; await UpdateAsync(); } await c.SendMessageAsync(string.Empty, false, Program.bot.GetEmbed($"The duel between **{mem1?.DisplayName}** and **{mem2?.DisplayName}**", $"Time is over!{b.ToString()}")); } else { DiscordGuildEmoji upv = await c.Guild.GetEmojiAsync(604972398424621066u), dwnv = await c.Guild.GetEmojiAsync(604973811154288660u); int upvotes1 = (await mess1.GetReactionsAsync(upv)).Count - (await mess1.GetReactionsAsync(dwnv)).Count; int upvotes2 = (await mess2.GetReactionsAsync(upv)).Count - (await mess2.GetReactionsAsync(dwnv)).Count; if (upvotes1 > upvotes2) { await c.SendMessageAsync(string.Empty, false, Program.bot.GetEmbed($"The duel between **{mem1?.DisplayName}** and **{mem2?.DisplayName}** has concluded!", $"Count: **{upvotes1}** <:upvote:604972398424621066> vs **{upvotes2}** <:upvote:604972398424621066>.", $"**{mem1.DisplayName}** is winning!", "Winner gets **3** points.")); await Duelists.UpdateAsync(duel.duelist2, 0, 1, 0); await Duelists.UpdateAsync(duel.duelist1, 3, 1, 1); } else if (upvotes1 < upvotes2) { await c.SendMessageAsync(string.Empty, false, Program.bot.GetEmbed($"The duel between **{mem1?.DisplayName}** and **{mem2?.DisplayName}** has concluded!", $"Count: **{upvotes1}** <:upvote:604972398424621066> vs **{upvotes2}** <:upvote:604972398424621066>.", $"**{mem2.DisplayName}** is winning!", "Winner gets **3** points.")); await Duelists.UpdateAsync(duel.duelist1, 0, 1, 0); await Duelists.UpdateAsync(duel.duelist2, 3, 1, 1); } else { await c.SendMessageAsync(string.Empty, false, Program.bot.GetEmbed($"The duel between **{mem1?.DisplayName}** and **{mem2?.DisplayName}** has concluded!", $"Count: **{upvotes1}** <:upvote:604972398424621066> vs **{upvotes2}** <:upvote:604972398424621066>.", "It's a draw!", "Both duelists get **2** points.")); await Duelists.UpdateAsync(duel.duelist1, 2, 1, 0); await Duelists.UpdateAsync(duel.duelist2, 2, 1, 0); } await DeleteAsync(); } } else { await UpdateAsync(); } }
public async Task RemoveCargoReactRoleAsync(CommandContext ctx, DiscordChannel canalReactRole = null, DiscordEmoji emoji = null) { await ctx.TriggerTypingAsync(); new Thread(async() => { try { DiscordEmbedBuilder embed = new DiscordEmbedBuilder(); if (canalReactRole == null || emoji == null) { embed.WithColor(Program.Bot.Utilities.HelpCommandsColor()) .WithAuthor("Como executar este comando:", null, Values.infoLogo) .AddField("PC/Mobile", $"{ctx.Prefix}rr cargo.del Canal[Id] Emoji") .WithFooter($"Comando requisitado pelo: {Program.Bot.Utilities.DiscordNick(ctx.Member)}", iconUrl: ctx.Member.AvatarUrl) .WithTimestamp(DateTime.Now); await ctx.RespondAsync(embed: embed.Build()); return; } if (string.IsNullOrWhiteSpace(emoji.Url)) { embed.WithAuthor("Emoji inválido!", null, Values.infoLogo) .WithColor(Program.Bot.Utilities.RandomColorEmbed()) .WithDescription("Digite um emoji válido!") .WithFooter($"Comando requisitado pelo: {Program.Bot.Utilities.DiscordNick(ctx.Member)}", iconUrl: ctx.Member.AvatarUrl) .WithTimestamp(DateTime.Now); await ctx.RespondAsync(embed: embed.Build()); return; } IMongoDatabase local = Program.Bot.LocalDB; IMongoCollection <Jogos> jogos = local.GetCollection <Jogos>(Values.Mongo.jogos); IMongoCollection <Reacts> reacts = local.GetCollection <Reacts>(Values.Mongo.reacts); FilterDefinition <Jogos> filtroJogos = Builders <Jogos> .Filter.Eq(x => x.idDoEmoji, emoji.Id); List <Jogos> resultadoJogos = await(await jogos.FindAsync(filtroJogos)).ToListAsync(); Jogos ultimoResultadoJogo = resultadoJogos.LastOrDefault(); List <Reacts> resultadoReacts = await(await reacts.FindAsync(Builders <Reacts> .Filter.Eq(x => x.categoria, ultimoResultadoJogo.nomeDaCategoria))).ToListAsync(); Reacts ultimoResultadoReact = resultadoReacts.LastOrDefault(); if (resultadoJogos.Count != 0 && resultadoReacts.Count != 0) { DiscordMessage mensagem = await canalReactRole.GetMessageAsync(ultimoResultadoReact.idDaMensagem); DiscordEmbed embedMensagemReactRole = mensagem.Embeds.LastOrDefault(); DiscordEmbedBuilder builder = new DiscordEmbedBuilder(embedMensagemReactRole); DiscordRole cargoJogoEmbed = ctx.Guild.GetRole(ultimoResultadoJogo.idDoCargo); IReadOnlyList <DiscordUser> MembrosReacoes = await mensagem.GetReactionsAsync(emoji); string linhaMensagemEmbed = $"{emoji.ToString()} - {cargoJogoEmbed.Name}"; if (embedMensagemReactRole.Description.Contains(linhaMensagemEmbed)) { string descricaoEmbed = embedMensagemReactRole.Description; List <string> lista = descricaoEmbed.Split('\n').ToList(); lista.RemoveAt(lista.FindIndex(linha => linha.Contains(linhaMensagemEmbed))); StringBuilder strEmbedFinal = new StringBuilder(); foreach (string linha in lista) { strEmbedFinal.Append($"{linha}\n"); } builder.WithDescription(strEmbedFinal.ToString()); builder.WithAuthor(embedMensagemReactRole.Author.Name, null, Values.logoUBGE); builder.WithColor(embedMensagemReactRole.Color.Value); await mensagem.ModifyAsync(embed: builder.Build()); } await jogos.DeleteOneAsync(filtroJogos); DiscordMessage msgAguarde = await ctx.RespondAsync($"Aguarde, estou removendo as reações dos membros que está no {canalReactRole.Mention}..."); int i = 0; foreach (DiscordUser Membro in MembrosReacoes) { try { await Task.Delay(200); await mensagem.DeleteReactionAsync(emoji, Membro); } catch (Exception) { ++i; } } await msgAguarde.DeleteAsync(); if (i != 0) { await ctx.RespondAsync($"Existem **{i}** reações que não foram removidas por que os membros saíram da {ctx.Guild.Name}, por favor, remova-as manualmente. :wink:"); } embed.WithAuthor("Jogo removido!", null, Values.logoUBGE) .WithColor(Program.Bot.Utilities.RandomColorEmbed()) .WithThumbnailUrl(emoji.Url) .WithDescription($"O cargo: {cargoJogoEmbed.Mention} e a reação: {emoji.ToString()} foram removidos com sucesso!{(i != 0 ? $"\n\n{i} reações restantes para serem removidas manualmente." : string.Empty)}") .WithFooter($"Comando requisitado pelo: {Program.Bot.Utilities.DiscordNick(ctx.Member)}", iconUrl: ctx.Member.AvatarUrl) .WithTimestamp(DateTime.Now); await ctx.RespondAsync(embed: embed.Build()); } else if (resultadoReacts.Count == 0) { await ctx.RespondAsync($"{ctx.Member.Mention}, essa categoria não existe!"); } else if (resultadoJogos.Count == 0) { await ctx.RespondAsync($"{ctx.Member.Mention}, esse jogo não existe!"); } } catch (ArgumentException) { await ctx.RespondAsync($"{ctx.Member.Mention}, este emoji não foi encontrado!"); } catch (Exception exception) { await Program.Bot.Logger.Error(Log.TypeError.Commands, exception); } }).Start(); }
private static async Task CheckMessageAsync(DiscordClient client, DiscordChannel channel, DiscordUser user, DiscordMessage message, DiscordEmoji emoji) { try { if (user.IsBot || channel.IsPrivate) { return; } if (emoji != Config.Reactions.Starbucks) { return; } if (!Config.Moderation.Channels.Contains(channel.Id)) { return; } // message.Timestamp throws if it's not in the cache AND is in local time zone if (DateTime.UtcNow - message.CreationTimestamp > Config.ModerationTimeThreshold) { return; } if (message.Reactions.Any(r => r.Emoji == emoji && (r.IsMe || r.Count < Config.Moderation.StarbucksThreshold))) { return; } // in case it's not in cache and doesn't contain any info, including Author message = await channel.GetMessageAsync(message.Id).ConfigureAwait(false); if (message.Author.IsWhitelisted(client, channel.Guild)) { return; } var users = await message.GetReactionsAsync(emoji).ConfigureAwait(false); var members = users .Select(u => channel.Guild .GetMemberAsync(u.Id) .ContinueWith(ct => ct.IsCompletedSuccessfully ? ct : Task.FromResult((DiscordMember)null))) .ToList() //force eager task creation .Select(t => t.Unwrap().ConfigureAwait(false).GetAwaiter().GetResult()) .Where(m => m != null) .ToList(); var reporters = new List <DiscordMember>(Config.Moderation.StarbucksThreshold); foreach (var member in members) { if (member.IsCurrent) { return; } if (member.Roles.Any()) { reporters.Add(member); } } if (reporters.Count < Config.Moderation.StarbucksThreshold) { return; } await message.ReactWithAsync(client, emoji).ConfigureAwait(false); await client.ReportAsync("User moderation report ⭐💵", message, reporters, null, ReportSeverity.Medium).ConfigureAwait(false); } catch (Exception e) { Config.Log.Error(e); } }