public static Task OnMessageCreated(DiscordClient _, MessageCreateEventArgs args) { if (args.Channel.IsPrivate) { return(Task.CompletedTask); } if (!MessageQueue.TryGetValue(args.Channel.Id, out var queue)) { lock (MessageQueue) { if (!MessageQueue.TryGetValue(args.Channel.Id, out queue)) { MessageQueue[args.Channel.Id] = queue = new FixedLengthBuffer <ulong, DiscordMessage>(KeyGen); } } } lock (queue.syncObj) queue.Add(args.Message); while (queue.Count > Config.ChannelMessageHistorySize) { lock (queue.syncObj) queue.TrimExcess(); } return(Task.CompletedTask); }
internal static Task <List <DiscordMessage> > GetMessagesBeforeCachedAsync(this DiscordChannel ch, ulong msgId, 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().SkipWhile(m => m.Id >= msgId).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(); 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()); } } } else { fetchedList = ch.GetMessagesBeforeAsync(msgId, fetchCount).ConfigureAwait(false).GetAwaiter().GetResult(); } result.AddRange(fetchedList); } return(Task.FromResult(result)); }