Converted enough to send the system card

This commit is contained in:
Ske
2020-12-22 16:55:13 +01:00
parent a6fbd869be
commit 05334f0d25
28 changed files with 343 additions and 198 deletions

View File

@@ -11,10 +11,14 @@ using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using DSharpPlus.Exceptions;
using Myriad.Types;
using NodaTime;
using PluralKit.Core;
using Permissions = DSharpPlus.Permissions;
namespace PluralKit.Bot {
public static class ContextUtils {
public static async Task<bool> ConfirmClear(this Context ctx, string toClear)
@@ -149,7 +153,8 @@ namespace PluralKit.Bot {
if (currentPage < 0) currentPage += pageCount;
// If we can, remove the user's reaction (so they can press again quickly)
if (ctx.BotHasAllPermissions(Permissions.ManageMessages)) await msg.DeleteReactionAsync(reaction.Emoji, reaction.User);
if (ctx.BotPermissions.HasFlag(PermissionSet.ManageMessages))
await msg.DeleteReactionAsync(reaction.Emoji, reaction.User);
// Edit the embed with the new page
var embed = await MakeEmbedForPage(currentPage);
@@ -159,7 +164,8 @@ namespace PluralKit.Bot {
// "escape hatch", clean up as if we hit X
}
if (ctx.BotHasAllPermissions(Permissions.ManageMessages)) await msg.DeleteAllReactionsAsync();
if (ctx.BotPermissions.HasFlag(PermissionSet.ManageMessages))
await msg.DeleteAllReactionsAsync();
}
// If we get a "NotFound" error, the message has been deleted and thus not our problem
catch (NotFoundException) { }
@@ -245,12 +251,7 @@ namespace PluralKit.Bot {
return items[Array.IndexOf(indicators, reaction.Emoji.Name)];
}
}
public static Permissions BotPermissions(this Context ctx) => ctx.Channel.BotPermissions();
public static bool BotHasAllPermissions(this Context ctx, Permissions permission) =>
ctx.Channel.BotHasAllPermissions(permission);
public static async Task BusyIndicator(this Context ctx, Func<Task> f, string emoji = "\u23f3" /* hourglass */)
{
await ctx.BusyIndicator<object>(async () =>
@@ -265,8 +266,8 @@ namespace PluralKit.Bot {
var task = f();
// If we don't have permission to add reactions, don't bother, and just await the task normally.
var neededPermissions = Permissions.AddReactions | Permissions.ReadMessageHistory;
if ((ctx.BotPermissions() & neededPermissions) != neededPermissions) return await task;
var neededPermissions = PermissionSet.AddReactions | PermissionSet.ReadMessageHistory;
if ((ctx.BotPermissions & neededPermissions) != neededPermissions) return await task;
try
{

View File

@@ -12,6 +12,8 @@ using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using DSharpPlus.Exceptions;
using Myriad.Extensions;
using Myriad.Rest.Types;
using Myriad.Types;
using NodaTime;
@@ -50,6 +52,11 @@ namespace PluralKit.Bot
{
return $"{user.Username}#{user.Discriminator} ({user.Mention})";
}
public static string NameAndMention(this User user)
{
return $"{user.Username}#{user.Discriminator} ({user.Mention()})";
}
// We funnel all "permissions from DiscordMember" calls through here
// This way we can ensure we do the read permission correction everywhere
@@ -74,20 +81,7 @@ namespace PluralKit.Bot
var invalidRoleIds = roleIdCache.Where(x => !currentRoleIds.Contains(x)).ToList();
roleIdCache.RemoveAll(x => invalidRoleIds.Contains(x));
}
public static async Task<Permissions> PermissionsIn(this DiscordChannel channel, DiscordUser user)
{
// Just delegates to PermissionsInSync, but handles the case of a non-member User in a guild properly
// This is a separate method because it requires an async call
if (channel.Guild != null && !(user is DiscordMember))
{
var member = await channel.Guild.GetMember(user.Id);
if (member != null)
return PermissionsInSync(channel, member);
}
return PermissionsInSync(channel, user);
}
// Same as PermissionsIn, but always synchronous. DiscordUser must be a DiscordMember if channel is in guild.
public static Permissions PermissionsInSync(this DiscordChannel channel, DiscordUser user)
@@ -194,23 +188,27 @@ namespace PluralKit.Bot
return false;
}
public static IEnumerable<IMention> ParseAllMentions(this string input, Guild guild, bool allowEveryone = false)
public static AllowedMentions ParseMentions(this string input)
{
var mentions = new List<IMention>();
mentions.AddRange(USER_MENTION.Matches(input)
.Select(x => new UserMention(ulong.Parse(x.Groups[1].Value)) as IMention));
var users = USER_MENTION.Matches(input).Select(x => ulong.Parse(x.Groups[1].Value));
var roles = ROLE_MENTION.Matches(input).Select(x => ulong.Parse(x.Groups[1].Value));
var everyone = EVERYONE_HERE_MENTION.IsMatch(input);
return new AllowedMentions
{
Users = users.ToArray(),
Roles = roles.ToArray(),
Parse = everyone ? new[] {AllowedMentions.ParseType.Everyone} : null
};
}
// Only allow role mentions through where the role is actually listed as *mentionable*
// (ie. any user can @ them, regardless of permissions)
// Still let the allowEveryone flag override this though (privileged users can @ *any* role)
// Original fix by Gwen
mentions.AddRange(ROLE_MENTION.Matches(input)
.Select(x => ulong.Parse(x.Groups[1].Value))
.Where(x => allowEveryone || guild != null && (guild.Roles.FirstOrDefault(g => g.Id == x)?.Mentionable ?? false))
.Select(x => new RoleMention(x) as IMention));
if (EVERYONE_HERE_MENTION.IsMatch(input) && allowEveryone)
mentions.Add(new EveryoneMention());
return mentions;
public static AllowedMentions RemoveUnmentionableRoles(this AllowedMentions mentions, Guild guild)
{
return mentions with {
Roles = mentions.Roles
?.Where(id => guild.Roles.FirstOrDefault(r => r.Id == id)?.Mentionable == true)
.ToArray()
};
}
public static string EscapeMarkdown(this string input)