private async Task OnGuildAvailable(DiscordClient dClient, GuildCreateEventArgs args) { if (args.Guild.Id != Guilds.Bloon) { return; } await this.dClient.Guilds[Guilds.Bloon].GetEmojisAsync(); DiscordChannel settingsChannel = await this.dClient.GetChannelAsync(BloonChannels.Settings); IReadOnlyList <DiscordMessage> messages = await settingsChannel.GetMessagesAsync(this.featureManager.Features.Count); for (int i = 0; i < this.featureManager.Features.Count; i++) { Feature feature = this.featureManager.Features[i]; DiscordMessage message = messages.Where(m => m.Embeds[0]?.Title == feature.Name).FirstOrDefault(); DiscordEmbed newEmbed = CreateFeatureEmbed(feature); if (message == null) { message = await settingsChannel.SendMessageAsync(embed : newEmbed); await message.CreateReactionAsync(DiscordEmoji.FromGuildEmote(this.dClient, FeatureEmojis.ToggleOff)); await message.CreateReactionAsync(DiscordEmoji.FromGuildEmote(this.dClient, FeatureEmojis.ToggleOn)); } else if (!IdenticalEmbed(message.Embeds[0], newEmbed)) { await message.ModifyAsync(embed : newEmbed); } } }
static async Task DeleteChnMessages(DiscordChannel channel) { Console.WriteLine($"Deleting messages...", Color.Green); ulong?first = null; int cnt = 0; do { var messages = await channel.GetMessagesAsync(100, first); if (messages.Count == 0) { break; } var ownMessages = messages.Where(k => k.Author.Id == client.CurrentUser.Id); cnt += ownMessages.Count(); first = messages.Last().Id; foreach (var message in ownMessages) { await channel.DeleteMessageAsync(message); } }while (first.HasValue); Console.WriteLine($"Deleted {cnt} messages!", Color.Green); }
private async Task RemoveAllReactionsAsync(DiscordChannel textChannel) { if (textChannel != null) { var messages = (await textChannel.GetMessagesAsync()).ToList(); _lastMessage = messages.OrderByDescending(x => x.Timestamp.Ticks).FirstOrDefault(); // Remove all existing reactions foreach (var message in messages) { // If the previous message hooked to, is the same as what is the new last message, don't remove all reactions // This is to prevent unhandled reactions being wiped if (!message.IsUserMessage() || _lastMessage != null && message.Id == _lastMessage.Id) { continue; } if (message.Reactions.Count > 0) { await message.DeleteAllReactionsAsync(); } } } }
public async Task sil(CommandContext ctx, int miktar) { try { await ctx.TriggerTypingAsync(); await ctx.Message.DeleteAsync(); DiscordChannel kanal = ctx.Channel; int sayi = miktar; do { List <DiscordMessage> messages = (await kanal.GetMessagesAsync(sayi > 100 ? 100 : sayi)).ToList(); await kanal.DeleteMessagesAsync(messages); sayi -= 100; } while (sayi >= 100); DiscordMessage msg = await ctx.RespondAsync($"Son {miktar} Mesaj Başarı İle Silindi."); await Task.Delay(TimeSpan.FromSeconds(3)); await msg.DeleteAsync(); } catch (Exception ex) { Console.WriteLine("HATA : " + ex.Message); } }
public async Task MarkovUserChannel(CommandContext ctx, [Description("Which channel the bot should look at.")] DiscordChannel channel, [Description("Which user's messages the bot should look at.")] DiscordUser user, [Description("How many messages the bot should look at.")] int amount = 500, int order = 0) { if (amount >= 10000) { amount = 10000; } var messages = await channel.GetMessagesAsync(amount); messages = messages.Where(msg => msg.Author == user).ToList(); var lines = messages.Select(msg => msg.Content).ToList(); //Select content lines = lines.Where(s => !string.IsNullOrWhiteSpace(s)).ToList(); //Remove empty messages lines = lines.Where(s => !s.Contains($"{Guilds.GetGuild(ctx.Guild).Prefix}markov")).ToList(); if (lines.Count == 0) { await MarkovUser(ctx, user, amount + 10); return; } await ctx.RespondAsync(MarkovResponse(order, lines)); }
private async Task <(IEnumerable <KeyValuePair <ulong, int> >, IEnumerable <KeyValuePair <string, int> >)> GetStatsOfChannel(DiscordChannel channel) { var messagesListByUser = new Dictionary <ulong, int>(); var messagesListByDate = new Dictionary <string, int>(); var lastMessageId = (await channel.GetMessagesAsync(1)).FirstOrDefault()?.Id; while (lastMessageId != null) { var last100Messages = await channel.GetMessagesBeforeAsync(lastMessageId.Value, 100); var lastUserGroupedMessages = last100Messages .GroupBy(p => p.Author.Id, (authorId, messages) => new { AuthorId = authorId, MessagesCount = messages.Count() }); var lastDateGroupedMessages = last100Messages .GroupBy(p => p.CreationTimestamp.ToString("yyyy/MM"), (monthAndYear, messagesInMonth) => new { Date = monthAndYear, MessagesCount = messagesInMonth.Count() }); foreach (var message in lastUserGroupedMessages) { if (messagesListByUser.ContainsKey(message.AuthorId)) { messagesListByUser[message.AuthorId] += message.MessagesCount; } else { messagesListByUser[message.AuthorId] = message.MessagesCount; } } foreach (var message in lastDateGroupedMessages) { if (messagesListByDate.ContainsKey(message.Date)) { messagesListByDate[message.Date] += message.MessagesCount; } else { messagesListByDate[message.Date] = message.MessagesCount; } } if (last100Messages.Count < 100) { break; } lastMessageId = last100Messages.Last().Id; } return(messagesListByUser.AsEnumerable(), messagesListByDate.AsEnumerable()); }
// Called when we have connected to our discord and can start sending messages. // This will create our repeating timer at a safe point. private async Task Client_GuildAvailable(GuildCreateEventArgs e) { if (e.Guild.Name == "bhoptimer") { Channel = e.Guild.Channels.First(chan => chan.Name.ToLower() == Config.Channel); } (await Channel.GetMessagesAsync()).First(); }
// Non-Command Methods public static async Task UpdateStats() { var ocs = RPClass.Users.Where(x => x.UserData.Xp > 0); if (!ocs.Any()) { return; } DiscordChannel c = RPClass.XPChannel; var members = await c.Guild.GetAllMembersAsync(); int longestName = 1; longestName = RPClass.Users.Where(x => x.UserData.Xp > 0).Max(x => members.First(y => y.Id == x.UserData.UserID).DisplayName.Length) + 1; int longestXP = 5; if (longestName < 5) { longestName = 5; } string Name = "Name".PadRight(longestName) + "| "; string XP = "XP "; string value = "```" + Name + XP + "\n---------" + new string('-', longestName) + "\n"; List <UserObject.RootObject> SortedUsers = new List <UserObject.RootObject>(); SortedUsers = RPClass.Users.OrderByDescending(x => x.UserData.Xp).ToList(); try { List <DiscordMessage> msgs = new List <DiscordMessage>(await c.GetMessagesAsync(100)); foreach (DiscordMessage msg in msgs) { await msg.DeleteAsync(); await Task.Delay(500); } } catch { } foreach (UserObject.RootObject user in SortedUsers) { if (user.UserData.Xp > 0) { if (value.Length > 1500) { await c.SendMessageAsync(value + "```"); value = "```"; } value += members.First(y => y.Id == user.UserData.UserID).DisplayName.PadRight(longestName) + "| " + user.UserData.Xp.ToString().PadRight(longestXP) + "\n"; } } await c.SendMessageAsync(value + "```"); }
public static async Task UpdateStandingsAsync() { DiscordChannel standingChannel = await Client.GetChannelAsync(592230066654674945); foreach (DiscordMessage discordMessage in await standingChannel.GetMessagesAsync()) { await standingChannel.DeleteMessageAsync(discordMessage, "Standings update."); } SdlPlayer[] players = await MySqlClient.RetrieveAllSdlPlayers(); List <SdlPlayer> orderedPlayers = players .Where(x => standingChannel.Guild.Members.Any(y => y.Id == x.DiscordId && MySqlClient.CheckHasPlayedSet(x).Result&& y.Roles.Any(z => z.Name.Equals("player", StringComparison.InvariantCultureIgnoreCase)))) .OrderByDescending(x => x.PowerLevel).ToList(); var playerStandings = orderedPlayers.Select(x => new { Player = x, Rank = orderedPlayers.FindLastIndex(y => y.PowerLevel == x.PowerLevel) + 1 }); List <DiscordEmbedBuilder> standingEmbeds = new List <DiscordEmbedBuilder> { new DiscordEmbedBuilder().WithDescription("").WithColor(Color.Gold) }; int startStanding = 1; int endStanding = 0; foreach (var playerStanding in playerStandings) { string standingLine = $"\n{playerStanding.Rank}: {playerStanding.Player.DiscordId.ToUserMention()} [{playerStanding.Player.PowerLevel}]"; if (standingEmbeds.Last().Description.Length + standingLine.Length > 2048) { standingEmbeds.Last().Title = $"Standings ({startStanding} - {endStanding})"; standingEmbeds.Add(new DiscordEmbedBuilder().WithDescription("").WithColor(Color.Silver)); startStanding = endStanding + 1; endStanding = startStanding; } standingEmbeds.Last().Description += standingLine; endStanding++; } standingEmbeds.Last().Title = $"Standings ({startStanding} - {endStanding})"; foreach (DiscordEmbedBuilder standingEmbed in standingEmbeds) { await standingChannel.SendMessageAsync(embed : standingEmbed.Build()); } }
public async Task <IEnumerable <MessageView> > GetMessagesFrom(DiscordChannel channel) { var msgs = await channel.GetMessagesAsync(10); return(msgs.Select(m => new MessageView { AuthorAvatarUrl = m.Author.AvatarUrl, AuthorName = m.Author.Username, Content = m.Content, TimeStamp = m.CreationTimestamp.ToLocalTime() })); }
private async Task <DiscordMessage> FindStarPost(DiscordChannel starboardChannel, ulong messageId, bool timeLimited = true) { var dateThreshold = DateTimeOffset.Now.AddDays(-1); // TODO: optimize this with a cache when we hit 100+ servers with star msg id -> chan,msg id var cacheEntry = await _database.StarboardCache.FirstOrDefaultAsync(e => e.MessageId == messageId && e.GuildId == starboardChannel.GuildId); if (cacheEntry != null) { var message = await starboardChannel.GetMessageAsync(cacheEntry.StarboardId); return(message); } var messageIdStr = messageId.ToString(); var messages = await starboardChannel.GetMessagesAsync(); var count = 0; while (messages.Count > 0) { foreach (var message in messages) { count++; // break when message is too old. if (timeLimited && message.CreationTimestamp <= dateThreshold) { return(null); } if (message.Author.Id == _client.CurrentUser.Id && message.Embeds .SelectMany(e => e.Fields ?? EmptyEmbedFields) .Any(f => f.Name == "Message ID" && f.Value == messageIdStr)) { return(message); } } // break when we hit 400 messages if (count > 400) { return(null); } messages = await starboardChannel.GetMessagesBeforeAsync(messages.Last().Id); } return(null); }
private async Task DeleteChannelMessages(CommandContext ctx, DiscordChannel channel) { var messages = await channel.GetMessagesAsync(); while (messages.Count > 0) { for (var j = 0; j < messages.Count; j++) { var message = messages[j]; if (message == null) { continue; } await message.DeleteAsync("Channel reset."); } messages = await channel.GetMessagesAsync(); } await ctx.RespondEmbed($"{ctx.User.Username} Channel {channel.Mention} messages have been deleted."); }
public async Task ReadChannel(DiscordChannel channel) => await Task.Run(async() => { var messages = await channel.GetMessagesAsync(100); int readCount = 0; Console.WriteLine($"Read {readCount} first messages"); do { foreach (var message in messages) { if (!history.ContainsKey(message.Id)) { readCount++; Read(message); Console.WriteLine($"Read: {message.Content}"); } } Console.WriteLine($"Read {messages.Count} messages -----------------------------------------------------------------------------"); messages = (await channel.GetMessagesAsync(100, messages.Last().Id)); } while (messages.Count > 0); Done: Console.WriteLine($"Read {readCount} messages"); });
//Discord has said this may be deprecated from the API at some point because the client doesn't use it to render it, but I find it very useful smh.// private async Task <IEnumerable <DiscordMessage> > GetImages(DiscordChannel channel, int messageScanCount) { IReadOnlyList <DiscordMessage> messages = await channel.GetMessagesAsync(messageScanCount); var @return = new List <DiscordMessage>(); IEnumerable <DiscordMessage> rawImageMessages = messages.Where(m => m.Attachments.Count > 0 && m.Attachments.Select(a => a.Width).Any(w => w > 0)); IEnumerable <DiscordMessage> linkImageMessages = messages.Where(m => m.Embeds.Select(e => e.Type).Where(t => t == "image").Count() > 0); @return.AddRange(rawImageMessages); @return.AddRange(linkImageMessages); return(@return); }
private async Task DeleteChannelMessages(CommandContext ctx, DiscordChannel channel) { var messages = await channel.GetMessagesAsync(); while (messages.Count > 0) { for (var j = 0; j < messages.Count; j++) { var message = messages[j]; if (message == null) { continue; } await message.DeleteAsync("Channel reset."); Thread.Sleep(100); } messages = await channel.GetMessagesAsync(); } await ctx.RespondEmbed(Translator.Instance.Translate("CHANNEL_MESSAGES_DELETED").FormatText(ctx.User.Username, channel.Mention)); }
private Task _discordClient_GuildsDownloaded(DiscordClient sender, GuildDownloadCompletedEventArgs e) { _ = Task.Run(async() => { UpdateTextChannel(); // Enter and lock the semaphore, incase this occurs simultaneously with updating streams await semaphoreSlimLock.WaitAsync(); var messages = (await _textChannel.GetMessagesAsync()).ToList(); await TryParseExistingEmbedsAsync(messages); semaphoreSlimLock.Release(); // When reconnects occur, this will stack update events // Therefore, dispose every time if (_intervalFunctionTimer != null) { await _intervalFunctionTimer.DisposeAsync(); } _intervalFunctionTimer = new Timer(UpdateCurrentStreamersAsync, null, TimeSpan.Zero, _updateInterval); }); return(Task.CompletedTask); }
private async Task LoadExistingRoleEmbedsAsync() { _existingRoleEmbeds = new Dictionary <ulong, ulong>(); // Filter only messages from this bot var existingMessages = (await _textChannel.GetMessagesAsync()).FromSelf(_discordClient); foreach (var message in existingMessages) { var(result, role) = await TryParseRoleFromEmbedAsync(message); if (result) { _existingRoleEmbeds.Add(role.Id, message.Id); } } }
public static async Task MoveChat(DiscordGuild guild, DiscordChannel channel, int limit, DiscordChannel target) { var lastMessages = await channel.GetMessagesAsync(limit); // check if everyone has access var permSend = true; var channelOverwrites = channel.PermissionOverwrites.ToList(); channelOverwrites.ForEach(o => { if (o.Id == guild.EveryoneRole.Id) { permSend = !o.Denied.HasPermission(Permissions.SendMessages) && !o.Denied.HasPermission(Permissions.AccessChannels); } }); await channel.SendMessageAsync("This conversation belongs to " + target.Mention + " and was moved there! \n" + (permSend ? channel.Mention + " is now closed for 2 mins to cool things down.\n" : "") + "\n*Remember to avoid offtopic chats!*"); if (permSend) { await channel.AddOverwriteAsync(guild.EveryoneRole, DSharpPlus.Permissions.None, DSharpPlus.Permissions.SendMessages, "Temp timeout start"); } // build embed with recent chat var embedChat = new DiscordEmbedBuilder { Title = "**Moved chat from *#" + channel.Name + "* **", Description = "This conversation didn't meet the channel topic and should be continued here.\n\n\n<a:typing:745068588909592737>" }; embedChat.Color = new DiscordColor("#ff1744"); lastMessages.Reverse().ToList().ForEach( (m) => { if (m.Author != Client.CurrentUser) { embedChat.AddField("**" + m.Author.Username + "**", m.Content); } } ); await target.SendMessageAsync(embed : embedChat); if (permSend) { await Task.Delay(120000); // release channel await channel.AddOverwriteAsync(guild.EveryoneRole, DSharpPlus.Permissions.SendMessages, DSharpPlus.Permissions.None, "Temp timeout stop"); } }
public static async Task <IReadOnlyList <DiscordMessage> > GetMessagesAsync(DiscordChannel channel) { if (!ChannelHasPermission(channel, Permissions.ReadMessageHistory)) { return(null); } try { return(await channel.GetMessagesAsync()); } catch (Exception e) { Logger.Error("Error occurred when attempting to read message history from channel \"" + channel.Name + "\". Error message: " + e); return(null); } }
/// <summary> /// Deletes all the responses in the specific channel /// </summary> /// <param name="channel"></param> /// <param name="count"></param> /// <returns></returns> public async Task DeleteAllResponseAsync(DiscordChannel channel, int count = 10) { //if (!(Redis is StackExchangeClient)) // throw new Exception("The redis client must be a StackExchangeClient to utlise the SCAN."); // //var key = Namespace.Combine(channel.Guild, "replies", "*"); //var redis = Redis as StackExchangeClient; //var server = redis.GetServersEnumable().First(); //IEnumerable<DiscordMessage> deletes = server.Keys(pattern: key) // .Select(k => redis.FetchStringAsync(key, "ResponseMsg", "0").Result) // .Select(str => ulong.TryParse(str, out var id) ? id : 0) // .Select(id => { try { return channel.GetMessageAsync(id).Result; } catch { return null; } }) // .Where(msg => msg != null); var messages = await channel.GetMessagesAsync(); await channel.DeleteMessagesAsync(messages.Where(m => m.Author.Id == Bot.Discord.CurrentUser.Id).Take(count), "Cleanup"); }
internal static Task <List <DiscordMessage> > GetMessagesCachedAsync(this DiscordChannel ch, int count = 100) { if (!MessageQueue.TryGetValue(ch.Id, out var queue)) { lock (MessageQueue) if (!MessageQueue.TryGetValue(ch.Id, out queue)) { MessageQueue[ch.Id] = queue = new FixedLengthBuffer <ulong, DiscordMessage>(KeyGen); } } List <DiscordMessage> result; lock (queue.syncObj) result = queue.Reverse().Take(count).ToList(); var cacheCount = result.Count; var fetchCount = Math.Max(count - cacheCount, 0); if (fetchCount > 0) { IReadOnlyList <DiscordMessage> fetchedList; if (result.Any()) { fetchedList = ch.GetMessagesBeforeAsync(result[0].Id, fetchCount).ConfigureAwait(false).GetAwaiter().GetResult(); } else { fetchedList = ch.GetMessagesAsync(fetchCount).ConfigureAwait(false).GetAwaiter().GetResult(); } result.AddRange(fetchedList); if (queue.Count < Config.ChannelMessageHistorySize) { lock (queue.syncObj) { // items in queue might've changed since the previous check at the beginning of this method var freshCopy = queue.Reverse().ToList(); queue.Clear(); queue.AddRange(freshCopy.Concat(fetchedList).Distinct().Reverse()); } } } return(Task.FromResult(result)); }
public static async Task <IReadOnlyList <DiscordMessage> > GetMessagesFromAsync(this DiscordChannel channel, DiscordMember member, int limit = 1) { var messages = new List <DiscordMessage>(); for (int step = 50; messages.Count < limit && step < 400; step *= 2) { ulong?lastId = messages.FirstOrDefault()?.Id; IReadOnlyList <DiscordMessage> requested; if (lastId is null) { requested = await channel.GetMessagesAsync(step); } else { requested = await channel.GetMessagesBeforeAsync(messages.FirstOrDefault().Id, step - messages.Count); } messages.AddRange(requested.Where(m => m.Author.Id == member.Id).Take(limit)); } return(messages.AsReadOnly()); }
private async Task <List <DiscordMessage> > GetAllMessagesFromChannel(DiscordChannel channel) { var messagesList = new List <DiscordMessage>(); var lastMessageId = (await channel.GetMessagesAsync(1)).FirstOrDefault()?.Id; while (lastMessageId != null) { var last100Messages = await channel.GetMessagesBeforeAsync(lastMessageId.Value, 100); messagesList.AddRange(last100Messages); if (last100Messages.Count < 100) { break; } lastMessageId = last100Messages.Last().Id; } return(messagesList); }
public async Task UpdateWelcomeAgents(CommandContext ctx) { DiscordChannel rulesAndInfo = ctx.Guild.GetChannel(SBGChannels.RulesAndInfo); StringBuilder roleLinks = new StringBuilder(); roleLinks.Append($"<@&{SBGRoles.Developer}> : The developers of Intruder! \n"); roleLinks.Append($"<@&{SBGRoles.Nerds}> : Official staff partners working along with the developer for community management.\n"); roleLinks.Append($"<@&{SBGRoles.Mod}> : The amazing community volunteers assisting the team to keep the peace. \n"); roleLinks.Append($"<@&{SBGRoles.AUG}> : A group of serious players who engage the community. \n"); roleLinks.Append($"<@&{SBGRoles.Agent}> : All members of the community. \n"); StringBuilder importLinks = new StringBuilder(); importLinks.Append($"{DiscordEmoji.FromGuildEmote(ctx.Client, PlatformEmojis.YouTube)} | [**Youtube**](https://www.youtube.com/superbossgames)\n"); importLinks.Append($"{DiscordEmoji.FromGuildEmote(ctx.Client, PlatformEmojis.Twitter)} | [**Twitter**](https://twitter.com/SuperbossGames/)\n"); importLinks.Append($"{DiscordEmoji.FromGuildEmote(ctx.Client, PlatformEmojis.Helprace)} | [**Helprace**](https://superbossgames.helprace.com/)\n"); importLinks.Append($"{DiscordEmoji.FromGuildEmote(ctx.Client, PlatformEmojis.Reddit)} | [**Reddit**](https://www.reddit.com/r/Intruder)\n"); importLinks.Append($"{DiscordEmoji.FromGuildEmote(ctx.Client, PlatformEmojis.Twitch)} | [**Twitch**](https://www.twitch.tv/superbossgames)\n"); importLinks.Append($"{DiscordEmoji.FromGuildEmote(ctx.Client, PlatformEmojis.Discord)} | [**Server Invite**](https://discord.gg/superbossgames)\n"); this.rulesEmbed.AddField($"Roles", roleLinks.ToString(), false); this.rulesEmbed.AddField($"Important Links", importLinks.ToString(), false); try { foreach (DiscordMessage msg in await rulesAndInfo.GetMessagesAsync()) { if (msg.Author.Id == ctx.Client.CurrentUser.Id && msg.Id == 892811059897991208) { await msg.ModifyAsync(embed : this.rulesEmbed.Build()); return; } } } catch (Exception e) { Log.Error(e.InnerException, "Failed to edit or update the Current Server Info."); } }
private async Task WarnIfDuplicatedNewAccountAsync(DiscordUser member) { var messages = await _joinLogChannel.GetMessagesAsync(); // Find a matching user in the recent history var altAccount = messages .FromSelf(_discordClient) .OrderByDescending(x => x.Timestamp) // Parse the username from the bot's message, and make sure it has the new user emote .FirstOrDefault(x => x.Reactions.Any(x => x.Emoji == DiscordEmoji.FromName(_discordClient, _config.NewUserEmoteString)) && x.Content.Split(' ', 3)[1].Split('#')[0] == member.Username); // Is there a matching account if (altAccount != null) { await altAccount.DeleteReactionsEmojiAsync( DiscordEmoji.FromName(_discordClient, _config.NewUserEmoteString)); await altAccount.CreateReactionAsync(_config.AltAccountEmoji); } }
public async Task UpdateRoleEmbed(CommandContext ctx) { this.roleEmbed.Description = $"React to this message using {DiscordEmoji.FromGuildEmote(ctx.Client, ManageRoleEmojis.BloonMoji)} reaction to subscribe to news and stay up to date. This way, we will reserve using the @everyone for essential news only.\n"; DiscordChannel rulesAndInfo = ctx.Guild.GetChannel(SBGChannels.RulesAndInfo); StringBuilder roleLinks = new StringBuilder(); try { foreach (DiscordMessage msg in await rulesAndInfo.GetMessagesAsync()) { if (msg.Author.Id == ctx.Client.CurrentUser.Id && msg.Id == SBGMessages.TheOnlyMessageIDWeCurrentlyCareAboutAtleastInAPublicFacingPerspective) { await msg.ModifyAsync(embed : this.rulesEmbed.Build()); return; } } } catch (Exception e) { Log.Error(e.InnerException, "Failed to edit or update the Current Server Info."); } }
QueryMemberMentions(List <ulong> memberIds, DiscordChannel actionChannel, int warnThreshold, DiscordMessage originalMessage) { const int MESSAGE_COUNT = 2000; // Remember to use DTO in the current timezone and not in UTC! API is running on OUR time. DateTimeOffset startTime = DateTimeOffset.Now.AddMonths(warnThreshold * -1); // We want to set the initial messages. IReadOnlyList <DiscordMessage> messages; if (originalMessage.ChannelId != Program.Settings.ActionChannelId) { // If the original message is anywhere besides the action channel, we want to start at the most recent message. messages = await actionChannel.GetMessagesAsync(MESSAGE_COUNT); } else { // If the original message is in the action channel, we want to exclude the message that triggered this response, as to not count it. messages = await actionChannel.GetMessagesBeforeAsync(originalMessage.Id, MESSAGE_COUNT); } // We want a "stop" value, so to speak. If this is true, it means we've gone before startTime. bool exceededStartTime = false; // Every instance where this user has been mentioned. var warnInstances = new Dictionary <ulong, List <DiscordMessage> >(); // Populate the dictionary. memberIds.ForEach(a => warnInstances.Add(a, new List <DiscordMessage>())); do { if (messages.Count > 0) { foreach (var message in messages) { // For each message, we want to check its mentioned users. if (startTime.ToUnixTimeMilliseconds() <= message.CreationTimestamp.ToUnixTimeMilliseconds()) { // We only want to continue if this is after our startValue. foreach (ulong memberId in memberIds) { if (MentionedUsersContains(message, memberId)) { // Only continue if there are actually mentioned users, and if the mentioned users has the member we want. warnInstances[memberId].Add(message); } // end if } // end foreach } // end if else { // We've gone way too far back, so we need to stop this. exceededStartTime = true; break; // Break out of the foreach. NON-SESE ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! } // end else } // end foreach if (!exceededStartTime && messages.Count == MESSAGE_COUNT) { // Only repopulate if we're still within the time range AND if there are still messages to grab. My logic behind checking the // message count is that there should be 2,000 or more messages if there's still messages to be found, unless the message // count is exactly a multiple of 2,000. messages = await actionChannel.GetMessagesBeforeAsync(messages.Last().Id, MESSAGE_COUNT); // Give the bot some time to process. await Task.Delay(500); } else { // Stop the loop. exceededStartTime = false; messages = default; } // end else } // end if } while (!exceededStartTime && !(messages is null) && messages.Count > 0); // ^ Only continue if we haven't gone back far enough in history AND if we still have messages. return(warnInstances); }
public async Task Execute() { Log.Information("Looking for available Intruder servers.."); DiscordChannel sbgCSI = await this.dClient.GetChannelAsync(SBGChannels.CurrentServerInfo); CurrentServerInfo csi = await this.roomService.GetCSIRooms(null, null, null, null, "false", "true", "false", "false", "false", null, 1, 100); DiscordEmbedBuilder serverEmbed = new DiscordEmbedBuilder { Footer = new DiscordEmbedBuilder.EmbedFooter { IconUrl = DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Unofficial).Url, }, Color = new DiscordColor(217, 187, 19), Timestamp = DateTime.UtcNow, Title = "Current Server Information", Url = "https://intruderfps.com/rooms", }; int skipRoomCount = 0; if (csi.Rooms.Count > 0) { StringBuilder serverList = new StringBuilder(); int roomCount = 0; foreach (Rooms room in csi.Rooms) { roomCount++; if (roomCount >= 12) { skipRoomCount++; } else { serverList.AppendLine($"{room.ServerIcon} | {room.RegionFlag} | {room.Name} - [{room.AgentCount}/{room.MaxAgents}]"); } } if (skipRoomCount >= 1) { serverList.Append($"<:unofficial:{ServerEmojis.Unofficial}> <:os:{ServerEmojis.Official}> <:passworded:{ServerEmojis.Password}> and **{skipRoomCount}** more."); } serverEmbed.AddField($"Server | Region | Name - [Agents]", serverList.ToString(), true); } else { serverEmbed.AddField( $"Current Server Information", $"Publicly no current servers available.\nUse `.ltp` to join the **Looking to Play** role", true); } #pragma warning disable SA1118 // Parameter should not span multiple lines serverEmbed.AddField( "Statistics", $"{RegionFlagEmojis.US}|{DiscordEmoji.FromGuildEmote(this.dClient, csi.USTOD)}| **{csi.USPlayerCount}** {DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Players)}| **{csi.USRoomCount}** {DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Unofficial)}\n" + $"{RegionFlagEmojis.SA}|{DiscordEmoji.FromGuildEmote(this.dClient, csi.SATOD)}| **{csi.SAPlayerCount}** {DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Players)}| **{csi.SARoomCount}** {DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Unofficial)}\n" + $"{RegionFlagEmojis.EU}|{DiscordEmoji.FromGuildEmote(this.dClient, csi.EUTOD)}| **{csi.EUPlayerCount}** {DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Players)}| **{csi.EURoomCount}** {DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Unofficial)}\n" + $"{RegionFlagEmojis.RU}|{DiscordEmoji.FromGuildEmote(this.dClient, csi.RUTOD)}| **{csi.RUPlayerCount}** {DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Players)}| **{csi.RURoomCount}** {DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Unofficial)}\n" + $"{RegionFlagEmojis.JP}|{DiscordEmoji.FromGuildEmote(this.dClient, csi.JPTOD)}| **{csi.JPPlayerCount}** {DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Players)}| **{csi.JPRoomCount}** {DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Unofficial)}\n" + $"{RegionFlagEmojis.Asia}|{DiscordEmoji.FromGuildEmote(this.dClient, csi.ASTOD)}| **{csi.AsiaPlayerCount}** {DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Players)}| **{csi.AsiaRoomCount}** {DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Unofficial)}\n" + $"{RegionFlagEmojis.AU}|{DiscordEmoji.FromGuildEmote(this.dClient, csi.AUTOD)}| **{csi.AUPlayerCount}** {DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Players)}| **{csi.AURoomCount}** {DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Unofficial)}\n" + $"Agents: **{csi.PlayerCount}** | Rooms: **{csi.Rooms.Count}**\n", true); #pragma warning restore SA1118 // Parameter should not span multiple lines string extensions = $"{DiscordEmoji.FromGuildEmote(this.dClient, BrowserEmojis.Chrome)} [**Chrome**](https://chrome.google.com/webstore/detail/intruder-notifications/aoebpknpfcepopfgnbnikaipjeekalim) | " + $"[**Firefox**](https://addons.mozilla.org/en-US/firefox/addon/intruder-notifications/) {DiscordEmoji.FromGuildEmote(this.dClient, BrowserEmojis.Firefox)}"; serverEmbed.AddField("Browser Extensions", extensions); serverEmbed.Footer.Text = $"SuperbossGames | #current-server-info"; serverEmbed.Footer.IconUrl = DiscordEmoji.FromGuildEmote(this.dClient, ServerEmojis.Unofficial).Url; serverEmbed.Color = new DiscordColor(217, 187, 19); serverEmbed.Timestamp = DateTime.UtcNow; await this.activityManager.TrySetActivityAsync($"{csi.PlayerCount} agents ", ActivityType.Watching); try { foreach (DiscordMessage msg in await sbgCSI.GetMessagesAsync()) { if (msg.Author.Id == this.dClient.CurrentUser.Id) { await msg.ModifyAsync(embed : serverEmbed.Build()); return; } } } catch (Exception e) { Log.Error(e.InnerException, "Failed to edit or update the Current Server Info."); } Log.Information("Finished looking for Intruder Servers"); }
/// <summary> /// Gets the last very last <see cref="DiscordMessage" />. /// </summary> /// <param name="channel">Represents the <see cref="DiscordChannel" />.</param> /// <returns></returns> public static async Task <DiscordMessage> GetLastMessageAsync(this DiscordChannel channel) { return(channel.GetMessagesAsync(1) .Result.First()); }
private async Task WaitForCancellationAsync() { while (!_cts.IsCancellationRequested) { if (!Ready) { await Task.Delay(TimeSpan.FromMilliseconds(500)); continue; } lock (_lockerObject) { Task.Run(async() => { while (Ready) { if (DateTime.Now >= _nextStatusCheck) { _nextStatusCheck = DateTime.Now + Program.Config.UpdateDelay; try { var request = (HttpWebRequest)WebRequest.Create(Program.Config.StatusURL); request.ContentType = "application/json"; request.Credentials = CredentialCache.DefaultCredentials; var res = request.GetResponse(); var serverList = new List <ServerModel>(); await using (var stream = res.GetResponseStream()) { if (stream != null) { using var reader = new StreamReader(stream); var result = await reader.ReadToEndAsync(); serverList = JsonConvert.DeserializeObject <List <ServerModel> >(result); } } res.Close(); res.Dispose(); foreach (var serverModel in serverList) { if (await Program.ServerStatusRepository.EntryExists(Convert.ToInt32(serverModel.Id))) { var model = await Program.ServerStatusRepository.FindById( Convert.ToInt32(serverModel.Id)); model.CurrentStatus.EditTime = DateTime.Now; model.CurrentStatus.Online = serverModel.Online == "1"; model.CurrentStatus.UserCount = Convert.ToInt32(serverModel.UserCount); model.History = new List <ServerEntryStatusHistory> { new ServerEntryStatusHistory { EntryTime = DateTime.Now, Id = Guid.NewGuid(), Online = serverModel.Online == "1", ServerId = model.Id, UserCount = model.CurrentStatus.UserCount } }; await Program.ServerStatusRepository.UpdateCurrentStatusAsync(model); } else { var model = new ServerEntry { CurrentStatus = new ServerEntryStatus(), ExpRate = serverModel.EXPRate, Id = Guid.NewGuid(), RgbColor = "rgb(0, 0, 0)", ServerId = Convert.ToInt32(serverModel.Id), ServerName = serverModel.Name, ServerType = serverModel.Type }; model.CurrentStatus.Id = Guid.NewGuid(); model.CurrentStatus.EditTime = DateTime.Now; model.CurrentStatus.Online = serverModel.Online == "1"; model.CurrentStatus.UserCount = Convert.ToInt32(serverModel.UserCount); model.History = new List <ServerEntryStatusHistory> { new ServerEntryStatusHistory { EntryTime = DateTime.Now, Id = Guid.NewGuid(), Online = serverModel.Online == "1", ServerId = model.Id, UserCount = model.CurrentStatus.UserCount } }; await _serverStatusRepository.AddServerAsync(model); } } } catch (Exception e) { Program.Log(e); } } if (DateTime.Now < _nextOutputTime) { await Task.Delay(500); continue; } _nextOutputTime = DateTime.Now + Program.Config.OutputDelay; try { var models = await _serverStatusRepository.GetAllAsync(); models = models.OrderByDescending(a => a.CurrentStatus.Online) .ThenByDescending(a => a.CurrentStatus.UserCount != -1) .ThenByDescending(a => a.CurrentStatus.UserCount).ToList(); var temp = "```md\r\n"; foreach (var serverEntry in models) { temp += Program.Config.OutputFormat .Replace("$SERVERNAME$", serverEntry.ServerName) .Replace("$STATUS$", serverEntry.CurrentStatus.Online ? "Online" : "Offline") .Replace("$USERCOUNT$", $"{serverEntry.CurrentStatus.UserCount}"); if (!temp.EndsWith("\r\n")) { temp += "\r\n"; } } temp += "```"; if (_lastMessage != null) { await _channel.DeleteMessageAsync(_lastMessage); } else { var currentMessages = await _channel.GetMessagesAsync(); if (currentMessages != null) { await _channel.DeleteMessagesAsync(currentMessages); } } _lastMessage = await _channel.SendMessageAsync(temp); } catch (Exception e) { Program.Log(e); } await Task.Delay(500); } }); } await Task.Delay(-1); } }