public async Task PermCheckChannel(Context ctx) { if (!ctx.HasNext()) { 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 = 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; foreach (var requiredPermission in requiredPermissions) { if ((botPermissions & requiredPermission) == 0) { missingPermissions |= (ulong)requiredPermission; } } if ((webhookPermissions & PermissionSet.UseExternalEmojis) == 0) { missingPermissions |= (ulong)PermissionSet.UseExternalEmojis; } // Generate the output embed var eb = new EmbedBuilder() .Title($"Permission check for **{channel.Name}**"); if (missingPermissions == 0) { eb.Description("No issues found, channel is proxyable :)"); } else { var missing = ""; foreach (var permission in requiredPermissions) { if (((ulong)permission & missingPermissions) == (ulong)permission) { missing += $"\n- **{permission.ToPermissionString()}**"; } } if (((ulong)PermissionSet.UseExternalEmojis & missingPermissions) == (ulong)PermissionSet.UseExternalEmojis) { missing += $"\n- **{PermissionSet.UseExternalEmojis.ToPermissionString()}**"; } eb.Description($"Missing permissions:\n{missing}"); } await ctx.Reply(embed : eb.Build()); }