feat: fetch from REST instead of cache for cross-cluster lookups

This commit is contained in:
spiral
2022-03-09 20:06:53 -05:00
parent d0ad7abb03
commit ae543b9c18
7 changed files with 80 additions and 19 deletions

View File

@@ -14,6 +14,7 @@ namespace PluralKit.Bot;
public class Checks
{
private readonly BotConfig _botConfig;
// this must ONLY be used to get the bot's user ID
private readonly IDiscordCache _cache;
private readonly ProxyMatcher _matcher;
private readonly ProxyService _proxy;
@@ -26,6 +27,7 @@ public class Checks
PermissionSet.ManageWebhooks, PermissionSet.ReadMessageHistory
};
// todo: make sure everything uses the minimum amount of REST calls necessary
public Checks(DiscordApiClient rest, IDiscordCache cache, BotConfig botConfig, ProxyService proxy, ProxyMatcher matcher)
{
_rest = rest;
@@ -67,16 +69,17 @@ public class Checks
throw Errors.GuildNotFound(guildId);
}
var guildMember = await _rest.GetGuildMember(guild.Id, await _cache.GetOwnUser());
// Loop through every channel and group them by sets of permissions missing
var permissionsMissing = new Dictionary<ulong, List<Channel>>();
var hiddenChannels = false;
var missingEmojiPermissions = false;
foreach (var channel in await _rest.GetGuildChannels(guild.Id))
{
var botPermissions = await _cache.PermissionsIn(channel.Id);
var webhookPermissions = await _cache.EveryonePermissions(channel);
var userPermissions =
PermissionExtensions.PermissionsFor(guild, channel, ctx.Author.Id, senderGuildUser);
var botPermissions = PermissionExtensions.PermissionsFor(guild, channel, await _cache.GetOwnUser(), guildMember);
var webhookPermissions = PermissionExtensions.EveryonePermissions(guild, channel);
var userPermissions = PermissionExtensions.PermissionsFor(guild, channel, ctx.Author.Id, senderGuildUser);
if ((userPermissions & PermissionSet.ViewChannel) == 0)
{
@@ -153,15 +156,23 @@ public class Checks
throw new PKSyntaxError("You need to specify a channel.");
var error = "Channel not found or you do not have permissions to access it.";
// todo: this breaks if channel is not in cache and bot does not have View Channel permissions
var channel = await ctx.MatchChannel();
if (channel == null || channel.GuildId == null)
throw new PKError(error);
var guild = await _rest.GetGuildOrNull(channel.GuildId.Value);
if (guild == null)
throw new PKError(error);
var guildMember = await _rest.GetGuildMember(channel.GuildId.Value, await _cache.GetOwnUser());
if (!await ctx.CheckPermissionsInGuildChannel(channel, PermissionSet.ViewChannel))
throw new PKError(error);
var botPermissions = await _cache.PermissionsIn(channel.Id);
var webhookPermissions = await _cache.EveryonePermissions(channel);
var botPermissions = PermissionExtensions.PermissionsFor(guild, channel, await _cache.GetOwnUser(), guildMember);
var webhookPermissions = PermissionExtensions.EveryonePermissions(guild, channel);
// We use a bitfield so we can set individual permission bits
ulong missingPermissions = 0;
@@ -240,7 +251,7 @@ public class Checks
throw new PKError("You can only check your own messages.");
// get the channel info
var channel = await _cache.GetChannel(channelId.Value);
var channel = await _rest.GetChannelOrNull(channelId.Value);
if (channel == null)
throw new PKError("Unable to get the channel associated with this message.");

View File

@@ -20,7 +20,7 @@ namespace PluralKit.Bot;
public class ProxiedMessage
{
private static readonly Duration EditTimeout = Duration.FromMinutes(10);
private readonly IDiscordCache _cache;
// private readonly IDiscordCache _cache;
private readonly IClock _clock;
private readonly EmbedService _embeds;
@@ -37,7 +37,7 @@ public class ProxiedMessage
_rest = rest;
_webhookExecutor = webhookExecutor;
_logChannel = logChannel;
_cache = cache;
// _cache = cache;
}
public async Task EditMessage(Context ctx)
@@ -112,7 +112,7 @@ public class ProxiedMessage
var error =
"The channel where the message was sent does not exist anymore, or you are missing permissions to access it.";
var channel = await _cache.GetChannel(msg.Message.Channel);
var channel = await _rest.GetChannelOrNull(msg.Message.Channel);
if (channel == null)
throw new PKError(error);
@@ -165,7 +165,7 @@ public class ProxiedMessage
var showContent = true;
var noShowContentError = "Message deleted or inaccessible.";
var channel = await _cache.GetChannel(message.Message.Channel);
var channel = await _rest.GetChannelOrNull(message.Message.Channel);
if (channel == null)
showContent = false;
else if (!await ctx.CheckPermissionsInGuildChannel(channel, PermissionSet.ViewChannel))
@@ -222,7 +222,7 @@ public class ProxiedMessage
if (ctx.Match("author") || ctx.MatchFlag("author"))
{
var user = await _cache.GetOrFetchUser(_rest, message.Message.Sender);
var user = await _rest.GetUser(message.Message.Sender);
var eb = new EmbedBuilder()
.Author(new Embed.EmbedAuthor(
user != null