* Reimplement messags bulk deleted event RogueException/Discord.Net#1120 * Update remark * Backwards compatability with config optiontags/2.1.0
@@ -1,4 +1,5 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Threading.Tasks; | |||
namespace Discord.WebSocket | |||
@@ -128,6 +129,38 @@ namespace Discord.WebSocket | |||
remove { _messageDeletedEvent.Remove(value); } | |||
} | |||
internal readonly AsyncEvent<Func<Cacheable<IMessage, ulong>, ISocketMessageChannel, Task>> _messageDeletedEvent = new AsyncEvent<Func<Cacheable<IMessage, ulong>, ISocketMessageChannel, Task>>(); | |||
/// <summary> Fired when multiple messages are bulk deleted. </summary> | |||
/// <remarks> | |||
/// <note> | |||
/// The <see cref="MessageDeleted"/> event will not be fired for individual messages contained in this event. | |||
/// </note> | |||
/// <para> | |||
/// This event is fired when multiple messages are bulk deleted. The event handler must return a | |||
/// <see cref="Task"/> and accept an <see cref="IReadOnlyCollection{Cacheable{TEntity,TId}}"/> and | |||
/// <see cref="ISocketMessageChannel"/> as its parameters. | |||
/// </para> | |||
/// <para> | |||
/// <note type="important"> | |||
/// It is not possible to retrieve the message via | |||
/// <see cref="Cacheable{TEntity,TId}.DownloadAsync"/>; the message cannot be retrieved by Discord | |||
/// after the message has been deleted. | |||
/// </note> | |||
/// If caching is enabled via <see cref="DiscordSocketConfig"/>, the | |||
/// <see cref="Cacheable{TEntity,TId}"/> entity will contain the deleted message; otherwise, in event | |||
/// that the message cannot be retrieved, the snowflake ID of the message is preserved in the | |||
/// <see cref="ulong"/>. | |||
/// </para> | |||
/// <para> | |||
/// The source channel of the removed message will be passed into the | |||
/// <see cref="ISocketMessageChannel"/> parameter. | |||
/// </para> | |||
/// </remarks> | |||
public event Func<IReadOnlyCollection<Cacheable<IMessage, ulong>>, ISocketMessageChannel, Task> MessagesBulkDeleted | |||
{ | |||
add { _messagesBulkDeletedEvent.Add(value); } | |||
remove { _messagesBulkDeletedEvent.Remove(value); } | |||
} | |||
internal readonly AsyncEvent<Func<IReadOnlyCollection<Cacheable<IMessage, ulong>>, ISocketMessageChannel, Task>> _messagesBulkDeletedEvent = new AsyncEvent<Func<IReadOnlyCollection<Cacheable<IMessage, ulong>>, ISocketMessageChannel, Task>>(); | |||
/// <summary> Fired when a message is updated. </summary> | |||
/// <remarks> | |||
/// <para> | |||
@@ -302,6 +302,7 @@ namespace Discord.WebSocket | |||
client.MessageReceived += (msg) => _messageReceivedEvent.InvokeAsync(msg); | |||
client.MessageDeleted += (cache, channel) => _messageDeletedEvent.InvokeAsync(cache, channel); | |||
client.MessagesBulkDeleted += (cache, channel) => _messagesBulkDeletedEvent.InvokeAsync(cache, channel); | |||
client.MessageUpdated += (oldMsg, newMsg, channel) => _messageUpdatedEvent.InvokeAsync(oldMsg, newMsg, channel); | |||
client.ReactionAdded += (cache, channel, reaction) => _reactionAddedEvent.InvokeAsync(cache, channel, reaction); | |||
client.ReactionRemoved += (cache, channel, reaction) => _reactionRemovedEvent.InvokeAsync(cache, channel, reaction); | |||
@@ -66,6 +66,7 @@ namespace Discord.WebSocket | |||
internal WebSocketProvider WebSocketProvider { get; private set; } | |||
internal bool AlwaysDownloadUsers { get; private set; } | |||
internal int? HandlerTimeout { get; private set; } | |||
internal bool UseMessagesBulkDeletedOnly { get; private set; } | |||
internal new DiscordSocketApiClient ApiClient => base.ApiClient as DiscordSocketApiClient; | |||
/// <inheritdoc /> | |||
@@ -128,6 +129,7 @@ namespace Discord.WebSocket | |||
WebSocketProvider = config.WebSocketProvider; | |||
AlwaysDownloadUsers = config.AlwaysDownloadUsers; | |||
HandlerTimeout = config.HandlerTimeout; | |||
UseMessagesBulkDeletedOnly = config.UseMessagesBulkDeletedOnly; | |||
State = new ClientState(0, 0); | |||
Rest = new DiscordSocketRestClient(config, ApiClient); | |||
_heartbeatTimes = new ConcurrentQueue<long>(); | |||
@@ -1365,13 +1367,19 @@ namespace Discord.WebSocket | |||
return; | |||
} | |||
var cacheableList = ImmutableArray<Cacheable<IMessage, ulong>>.Empty; | |||
foreach (ulong id in data.Ids) | |||
{ | |||
var msg = SocketChannelHelper.RemoveMessage(channel, this, id); | |||
bool isCached = msg != null; | |||
var cacheable = new Cacheable<IMessage, ulong>(msg, id, isCached, async () => await channel.GetMessageAsync(id).ConfigureAwait(false)); | |||
await TimedInvokeAsync(_messageDeletedEvent, nameof(MessageDeleted), cacheable, channel).ConfigureAwait(false); | |||
cacheableList = cacheableList.Add(cacheable); | |||
if (!UseMessagesBulkDeletedOnly) | |||
await TimedInvokeAsync(_messageDeletedEvent, nameof(MessageDeleted), cacheable, channel).ConfigureAwait(false); | |||
} | |||
await TimedInvokeAsync(_messagesBulkDeletedEvent, nameof(MessagesBulkDeleted), cacheableList, channel).ConfigureAwait(false); | |||
} | |||
else | |||
{ | |||
@@ -107,6 +107,11 @@ namespace Discord.WebSocket | |||
public int? HandlerTimeout { get; set; } = 3000; | |||
/// <summary> | |||
/// Gets or sets whether or not <see cref="Discord.WebSocket.BaseSocketClient.MessageDeleted"/> is fired for each message on bulk delete. | |||
/// </summary> | |||
public bool UseMessagesBulkDeletedOnly { get; set; } = false; | |||
/// <summary> | |||
/// Initializes a default configuration. | |||
/// </summary> | |||
public DiscordSocketConfig() | |||