feat: gateway service

This commit is contained in:
alyssa 2024-09-14 12:19:47 +09:00
parent 1118d8bdf8
commit e4ed354536
50 changed files with 1737 additions and 545 deletions

View file

@ -6,5 +6,5 @@ public interface IEventHandler<in T> where T : IGatewayEvent
{
Task Handle(int shardId, T evt);
ulong? ErrorChannelFor(T evt, ulong userId) => null;
(ulong?, ulong?) ErrorChannelFor(T evt, ulong userId) => (null, null);
}

View file

@ -52,7 +52,7 @@ public class MessageCreated: IEventHandler<MessageCreateEvent>
_dmCache = dmCache;
}
public ulong? ErrorChannelFor(MessageCreateEvent evt, ulong userId) => evt.ChannelId;
public (ulong?, ulong?) ErrorChannelFor(MessageCreateEvent evt, ulong userId) => (evt.GuildId, evt.ChannelId);
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)?.Current.Id == msg.Id;
@ -63,7 +63,7 @@ public class MessageCreated: IEventHandler<MessageCreateEvent>
if (evt.Type != Message.MessageType.Default && evt.Type != Message.MessageType.Reply) return;
if (IsDuplicateMessage(evt)) return;
var botPermissions = await _cache.BotPermissionsIn(evt.ChannelId);
var botPermissions = await _cache.BotPermissionsIn(evt.GuildId ?? 0, evt.ChannelId);
if (!botPermissions.HasFlag(PermissionSet.SendMessages)) return;
// spawn off saving the private channel into another thread
@ -71,8 +71,8 @@ public class MessageCreated: IEventHandler<MessageCreateEvent>
_ = _dmCache.TrySavePrivateChannel(evt);
var guild = evt.GuildId != null ? await _cache.GetGuild(evt.GuildId.Value) : null;
var channel = await _cache.GetChannel(evt.ChannelId);
var rootChannel = await _cache.GetRootChannel(evt.ChannelId);
var channel = await _cache.GetChannel(evt.GuildId ?? 0, evt.ChannelId);
var rootChannel = await _cache.GetRootChannel(evt.GuildId ?? 0, evt.ChannelId);
// Log metrics and message info
_metrics.Measure.Meter.Mark(BotMetrics.MessagesReceived);
@ -90,7 +90,8 @@ public class MessageCreated: IEventHandler<MessageCreateEvent>
if (await TryHandleCommand(shardId, evt, guild, channel))
return;
await TryHandleProxy(evt, guild, channel, rootChannel.Id, botPermissions);
if (evt.GuildId != null)
await TryHandleProxy(evt, guild, channel, rootChannel.Id, botPermissions);
}
private async Task TryHandleLogClean(Channel channel, MessageCreateEvent evt)

View file

@ -52,10 +52,12 @@ public class MessageEdited: IEventHandler<MessageUpdateEvent>
if (!evt.Content.HasValue || !evt.Author.HasValue || !evt.Member.HasValue)
return;
var channel = await _cache.GetChannel(evt.ChannelId);
var guildIdMaybe = evt.GuildId.HasValue ? evt.GuildId.Value ?? 0 : 0;
var channel = await _cache.GetChannel(guildIdMaybe, evt.ChannelId); // todo: is this correct for message update?
if (!DiscordUtils.IsValidGuildChannel(channel))
return;
var rootChannel = await _cache.GetRootChannel(channel.Id);
var rootChannel = await _cache.GetRootChannel(guildIdMaybe, channel.Id);
var guild = await _cache.GetGuild(channel.GuildId!.Value);
var lastMessage = _lastMessageCache.GetLastMessage(evt.ChannelId)?.Current;
@ -69,7 +71,7 @@ public class MessageEdited: IEventHandler<MessageUpdateEvent>
ctx = await _repo.GetMessageContext(evt.Author.Value!.Id, channel.GuildId!.Value, rootChannel.Id, evt.ChannelId);
var equivalentEvt = await GetMessageCreateEvent(evt, lastMessage, channel);
var botPermissions = await _cache.BotPermissionsIn(channel.Id);
var botPermissions = await _cache.BotPermissionsIn(guildIdMaybe, channel.Id);
try
{
@ -91,7 +93,7 @@ public class MessageEdited: IEventHandler<MessageUpdateEvent>
private async Task<MessageCreateEvent> GetMessageCreateEvent(MessageUpdateEvent evt, CachedMessage lastMessage,
Channel channel)
{
var referencedMessage = await GetReferencedMessage(evt.ChannelId, lastMessage.ReferencedMessage);
var referencedMessage = await GetReferencedMessage(evt.GuildId.HasValue ? evt.GuildId.Value ?? 0 : 0, evt.ChannelId, lastMessage.ReferencedMessage);
var messageReference = lastMessage.ReferencedMessage != null
? new Message.Reference(channel.GuildId, evt.ChannelId, lastMessage.ReferencedMessage.Value)
@ -118,12 +120,12 @@ public class MessageEdited: IEventHandler<MessageUpdateEvent>
return equivalentEvt;
}
private async Task<Message?> GetReferencedMessage(ulong channelId, ulong? referencedMessageId)
private async Task<Message?> GetReferencedMessage(ulong guildId, ulong channelId, ulong? referencedMessageId)
{
if (referencedMessageId == null)
return null;
var botPermissions = await _cache.BotPermissionsIn(channelId);
var botPermissions = await _cache.BotPermissionsIn(guildId, channelId);
if (!botPermissions.HasFlag(PermissionSet.ReadMessageHistory))
{
_logger.Warning(

View file

@ -62,7 +62,7 @@ public class ReactionAdded: IEventHandler<MessageReactionAddEvent>
// but we aren't able to get DMs from bots anyway, so it's not really needed
if (evt.GuildId != null && (evt.Member?.User?.Bot ?? false)) return;
var channel = await _cache.GetChannel(evt.ChannelId);
var channel = await _cache.GetChannel(evt.GuildId ?? 0, evt.ChannelId);
// check if it's a command message first
// since this can happen in DMs as well
@ -75,10 +75,10 @@ public class ReactionAdded: IEventHandler<MessageReactionAddEvent>
return;
}
var (authorId, _) = await _commandMessageService.GetCommandMessage(evt.MessageId);
if (authorId != null)
var cmessage = await _commandMessageService.GetCommandMessage(evt.MessageId);
if (cmessage != null)
{
await HandleCommandDeleteReaction(evt, authorId.Value, false);
await HandleCommandDeleteReaction(evt, cmessage.AuthorId, false);
return;
}
}
@ -123,7 +123,7 @@ public class ReactionAdded: IEventHandler<MessageReactionAddEvent>
private async ValueTask HandleProxyDeleteReaction(MessageReactionAddEvent evt, PKMessage msg)
{
if (!(await _cache.BotPermissionsIn(evt.ChannelId)).HasFlag(PermissionSet.ManageMessages))
if (!(await _cache.BotPermissionsIn(evt.GuildId ?? 0, evt.ChannelId)).HasFlag(PermissionSet.ManageMessages))
return;
var isSameSystem = msg.Member != null && await _repo.IsMemberOwnedByAccount(msg.Member.Value, evt.UserId);
@ -150,7 +150,7 @@ public class ReactionAdded: IEventHandler<MessageReactionAddEvent>
if (authorId != null && authorId != evt.UserId)
return;
if (!((await _cache.BotPermissionsIn(evt.ChannelId)).HasFlag(PermissionSet.ManageMessages) || isDM))
if (!((await _cache.BotPermissionsIn(evt.GuildId ?? 0, evt.ChannelId)).HasFlag(PermissionSet.ManageMessages) || isDM))
return;
// todo: don't try to delete the user's own messages in DMs
@ -206,14 +206,14 @@ public class ReactionAdded: IEventHandler<MessageReactionAddEvent>
private async ValueTask HandlePingReaction(MessageReactionAddEvent evt, FullMessage msg)
{
if (!(await _cache.BotPermissionsIn(evt.ChannelId)).HasFlag(PermissionSet.ManageMessages))
if (!(await _cache.BotPermissionsIn(evt.GuildId ?? 0, evt.ChannelId)).HasFlag(PermissionSet.ManageMessages))
return;
// Check if the "pinger" has permission to send messages in this channel
// (if not, PK shouldn't send messages on their behalf)
var member = await _rest.GetGuildMember(evt.GuildId!.Value, evt.UserId);
var requiredPerms = PermissionSet.ViewChannel | PermissionSet.SendMessages;
if (member == null || !(await _cache.PermissionsForMemberInChannel(evt.ChannelId, member)).HasFlag(requiredPerms)) return;
if (member == null || !(await _cache.PermissionsForMemberInChannel(evt.GuildId ?? 0, evt.ChannelId, member)).HasFlag(requiredPerms)) return;
if (msg.Member == null) return;
@ -266,7 +266,7 @@ public class ReactionAdded: IEventHandler<MessageReactionAddEvent>
private async Task TryRemoveOriginalReaction(MessageReactionAddEvent evt)
{
if ((await _cache.BotPermissionsIn(evt.ChannelId)).HasFlag(PermissionSet.ManageMessages))
if ((await _cache.BotPermissionsIn(evt.GuildId ?? 0, evt.ChannelId)).HasFlag(PermissionSet.ManageMessages))
await _rest.DeleteUserReaction(evt.ChannelId, evt.MessageId, evt.Emoji, evt.UserId);
}
}