* 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 | |||
| { | |||
| @@ -106,6 +106,11 @@ namespace Discord.WebSocket | |||
| /// </summary> | |||
| 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> | |||