From aa2a234f8dd0a32dff015708938162d275832cfd Mon Sep 17 00:00:00 2001 From: Ske Date: Mon, 3 May 2021 10:29:22 +0200 Subject: [PATCH] Fix permission error on message edit handler Signed-off-by: Ske --- PluralKit.Bot/Handlers/MessageCreated.cs | 2 +- PluralKit.Bot/Handlers/MessageEdited.cs | 49 ++++++++++++++++--- .../Services/LastMessageCacheService.cs | 23 +++------ 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/PluralKit.Bot/Handlers/MessageCreated.cs b/PluralKit.Bot/Handlers/MessageCreated.cs index 002a641a..72e6b8be 100644 --- a/PluralKit.Bot/Handlers/MessageCreated.cs +++ b/PluralKit.Bot/Handlers/MessageCreated.cs @@ -53,7 +53,7 @@ namespace PluralKit.Bot private bool IsDuplicateMessage(Message msg) => // We consider a message duplicate if it has the same ID as the previous message that hit the gateway - _lastMessageCache.GetLastMessage(msg.ChannelId)?.mid == msg.Id; + _lastMessageCache.GetLastMessage(msg.ChannelId)?.Id == msg.Id; public async Task Handle(Shard shard, MessageCreateEvent evt) { diff --git a/PluralKit.Bot/Handlers/MessageEdited.cs b/PluralKit.Bot/Handlers/MessageEdited.cs index 816914fe..8a35df3a 100644 --- a/PluralKit.Bot/Handlers/MessageEdited.cs +++ b/PluralKit.Bot/Handlers/MessageEdited.cs @@ -11,6 +11,8 @@ using Myriad.Types; using PluralKit.Core; +using Serilog; + namespace PluralKit.Bot { @@ -25,9 +27,9 @@ namespace PluralKit.Bot private readonly IDiscordCache _cache; private readonly Bot _bot; private readonly DiscordApiClient _rest; + private readonly ILogger _logger; - - public MessageEdited(LastMessageCacheService lastMessageCache, ProxyService proxy, IDatabase db, IMetrics metrics, ModelRepository repo, Cluster client, IDiscordCache cache, Bot bot, DiscordApiClient rest) + public MessageEdited(LastMessageCacheService lastMessageCache, ProxyService proxy, IDatabase db, IMetrics metrics, ModelRepository repo, Cluster client, IDiscordCache cache, Bot bot, DiscordApiClient rest, ILogger logger) { _lastMessageCache = lastMessageCache; _proxy = proxy; @@ -38,6 +40,7 @@ namespace PluralKit.Bot _cache = cache; _bot = bot; _rest = rest; + _logger = logger.ForContext(); } public async Task Handle(Shard shard, MessageUpdateEvent evt) @@ -55,7 +58,7 @@ namespace PluralKit.Bot var lastMessage = _lastMessageCache.GetLastMessage(evt.ChannelId); // Only react to the last message in the channel - if (lastMessage?.mid != evt.Id) + if (lastMessage?.Id != evt.Id) return; // Just run the normal message handling code, with a flag to disable autoproxying @@ -64,8 +67,23 @@ namespace PluralKit.Bot using (_metrics.Measure.Timer.Time(BotMetrics.MessageContextQueryTime)) ctx = await _repo.GetMessageContext(conn, evt.Author.Value!.Id, channel.GuildId!.Value, evt.ChannelId); - Message referencedMessage = (lastMessage.referenced_message != null) ? await _rest.GetMessage(evt.ChannelId, lastMessage.referenced_message.Value) : null; + var equivalentEvt = await GetMessageCreateEvent(evt, lastMessage, channel); + var botPermissions = _bot.PermissionsIn(channel.Id); + await _proxy.HandleIncomingMessage(shard, equivalentEvt, ctx, allowAutoproxy: false, guild: guild, channel: channel, botPermissions: botPermissions); + } + private async Task GetMessageCreateEvent(MessageUpdateEvent evt, CachedMessage lastMessage, Channel channel) + { + var referencedMessage = await GetReferencedMessage(evt.ChannelId, lastMessage.ReferencedMessage); + + var messageReference = lastMessage.ReferencedMessage != null + ? new Message.Reference(channel.GuildId, evt.ChannelId, lastMessage.ReferencedMessage.Value) + : null; + + var messageType = lastMessage.ReferencedMessage != null + ? Message.MessageType.Reply + : Message.MessageType.Default; + // TODO: is this missing anything? var equivalentEvt = new MessageCreateEvent { @@ -76,12 +94,27 @@ namespace PluralKit.Bot Member = evt.Member.Value, Content = evt.Content.Value, Attachments = evt.Attachments.Value ?? Array.Empty(), - MessageReference = (lastMessage.referenced_message != null) ? new (channel.GuildId, evt.ChannelId, lastMessage.referenced_message.Value) : null, + MessageReference = messageReference, ReferencedMessage = referencedMessage, - Type = (lastMessage.referenced_message != null) ? Message.MessageType.Reply : Message.MessageType.Default, + Type = messageType, }; - var botPermissions = _bot.PermissionsIn(channel.Id); - await _proxy.HandleIncomingMessage(shard, equivalentEvt, ctx, allowAutoproxy: false, guild: guild, channel: channel, botPermissions: botPermissions); + return equivalentEvt; + } + + private async Task GetReferencedMessage(ulong channelId, ulong? referencedMessageId) + { + if (referencedMessageId == null) + return null; + + var botPermissions = _bot.PermissionsIn(channelId); + if (!botPermissions.HasFlag(PermissionSet.ReadMessageHistory)) + { + _logger.Warning("Tried to get referenced message in channel {ChannelId} to reply but bot does not have Read Message History", + channelId); + return null; + } + + return await _rest.GetMessage(channelId, referencedMessageId.Value); } } } \ No newline at end of file diff --git a/PluralKit.Bot/Services/LastMessageCacheService.cs b/PluralKit.Bot/Services/LastMessageCacheService.cs index 1a8b1d17..0c77d6fc 100644 --- a/PluralKit.Bot/Services/LastMessageCacheService.cs +++ b/PluralKit.Bot/Services/LastMessageCacheService.cs @@ -1,4 +1,5 @@ -using System.Collections.Concurrent; +#nullable enable +using System.Collections.Concurrent; using System.Collections.Generic; using Myriad.Types; @@ -12,26 +13,14 @@ namespace PluralKit.Bot public void AddMessage(Message msg) { - _cache[msg.ChannelId] = new CachedMessage(msg); + _cache[msg.ChannelId] = new CachedMessage(msg.Id, msg.ReferencedMessage.Value?.Id); } - public CachedMessage GetLastMessage(ulong channel) + public CachedMessage? GetLastMessage(ulong channel) { - if (_cache.TryGetValue(channel, out var message)) return message; - return null; + return _cache.TryGetValue(channel, out var message) ? message : null; } } - public class CachedMessage - { - public ulong mid; - public ulong? referenced_message; - - public CachedMessage(Message msg) - { - mid = msg.Id; - if (msg.ReferencedMessage.Value != null) - referenced_message = msg.ReferencedMessage.Value.Id; - } - } + public record CachedMessage(ulong Id, ulong? ReferencedMessage); }