Browse Source

Merge branch 'feature/more-preconditions' into dev

tags/1.0-rc
RogueException 8 years ago
parent
commit
c99c78a2fe
5 changed files with 144 additions and 5 deletions
  1. +75
    -0
      src/Discord.Net.Commands/Attributes/Preconditions/RequireBotPermissionAttribute.cs
  2. +16
    -0
      src/Discord.Net.Commands/Attributes/Preconditions/RequireContextAttribute.cs
  3. +23
    -0
      src/Discord.Net.Commands/Attributes/Preconditions/RequireOwnerAttribute.cs
  4. +25
    -3
      src/Discord.Net.Commands/Attributes/Preconditions/RequireUserPermissionAttribute.cs
  5. +5
    -2
      src/Discord.Net.WebSocket/DiscordSocketClient.cs

+ 75
- 0
src/Discord.Net.Commands/Attributes/Preconditions/RequireBotPermissionAttribute.cs View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace Discord.Commands
{
/// <summary>
/// This attribute requires that the bot has a speicifed permission in the channel a command is invoked in.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class RequireBotPermissionAttribute : PreconditionAttribute
{
public GuildPermission? GuildPermission { get; }
public ChannelPermission? ChannelPermission { get; }

/// <summary>
/// Require that the bot account has a specified GuildPermission
/// </summary>
/// <remarks>This precondition will always fail if the command is being invoked in a private channel.</remarks>
/// <param name="permission">The GuildPermission that the bot must have. Multiple permissions can be specified by ORing or ANDing the permissions together.</param>
public RequireBotPermissionAttribute(GuildPermission permission)
{
GuildPermission = permission;
ChannelPermission = null;
}
/// <summary>
/// Require that the bot account has a specified ChannelPermission.
/// </summary>
/// <param name="permission">The ChannelPermission that the bot must have. Multiple permissions can be specified by ORing or ANDing the permissions together.</param>
/// <example>
/// <code language="c#">
/// [Command("permission")]
/// [RequireBotPermission(ChannelPermission.ManageMessages)]
/// public async Task Purge()
/// {
/// }
/// </code>
/// </example>
public RequireBotPermissionAttribute(ChannelPermission permission)
{
ChannelPermission = permission;
GuildPermission = null;
}

public override async Task<PreconditionResult> CheckPermissions(CommandContext context, CommandInfo command, IDependencyMap map)
{
var guildUser = await context.Guild.GetCurrentUserAsync();

if (GuildPermission.HasValue)
{
if (guildUser == null)
return PreconditionResult.FromError("Command must be used in a guild channel");
if (!guildUser.GuildPermissions.Has(GuildPermission.Value))
return PreconditionResult.FromError($"Command requires guild permission {GuildPermission.Value}");
}

if (ChannelPermission.HasValue)
{
var guildChannel = context.Channel as IGuildChannel;

ChannelPermissions perms;
if (guildChannel != null)
perms = guildUser.GetPermissions(guildChannel);
else
perms = ChannelPermissions.All(guildChannel);

if (!perms.Has(ChannelPermission.Value))
return PreconditionResult.FromError($"Command requires channel permission {ChannelPermission.Value}");
}

return PreconditionResult.FromSuccess();
}
}
}

+ 16
- 0
src/Discord.Net.Commands/Attributes/Preconditions/RequireContextAttribute.cs View File

@@ -11,11 +11,27 @@ namespace Discord.Commands
Group = 0x04
}

/// <summary>
/// Require that the command be invoked in a specified context.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class RequireContextAttribute : PreconditionAttribute
{
public ContextType Contexts { get; }

/// <summary>
/// Require that the command be invoked in a specified context.
/// </summary>
/// <param name="contexts">The type of context the command can be invoked in. Multiple contexts can be speicifed by ORing the contexts together.</param>
/// <example>
/// <code language="c#">
/// [Command("private_only")]
/// [RequireContext(ContextType.DM | ContextType.Group)]
/// public async Task PrivateOnly()
/// {
/// }
/// </code>
/// </example>
public RequireContextAttribute(ContextType contexts)
{
Contexts = contexts;


+ 23
- 0
src/Discord.Net.Commands/Attributes/Preconditions/RequireOwnerAttribute.cs View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Discord;

namespace Discord.Commands
{
/// <summary>
/// Require that the command is invoked by the owner of the bot.
/// </summary>
/// <remarks>This precondition will only work if the bot is a bot account.</remarks>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class RequireOwnerAttribute : PreconditionAttribute
{
public override async Task<PreconditionResult> CheckPermissions(CommandContext context, CommandInfo command, IDependencyMap map)
{
var application = await context.Client.GetApplicationInfoAsync();
if (context.User.Id == application.Owner.Id) return PreconditionResult.FromSuccess();
return PreconditionResult.FromError("Command can only be run by the owner of the bot");
}
}
}

src/Discord.Net.Commands/Attributes/Preconditions/RequirePermissionAttribute.cs → src/Discord.Net.Commands/Attributes/Preconditions/RequireUserPermissionAttribute.cs View File

@@ -3,18 +3,40 @@ using System.Threading.Tasks;

namespace Discord.Commands
{
/// <summary>
/// This attribute requires that the user invoking the command has a specified permission.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class RequirePermissionAttribute : PreconditionAttribute
public class RequireUserPermissionAttribute : PreconditionAttribute
{
public GuildPermission? GuildPermission { get; }
public ChannelPermission? ChannelPermission { get; }

public RequirePermissionAttribute(GuildPermission permission)
/// <summary>
/// Require that the user invoking the command has a specified GuildPermission
/// </summary>
/// <remarks>This precondition will always fail if the command is being invoked in a private channel.</remarks>
/// <param name="permission">The GuildPermission that the user must have. Multiple permissions can be specified by ORing or ANDing the permissions together.</param>
public RequireUserPermissionAttribute(GuildPermission permission)
{
GuildPermission = permission;
ChannelPermission = null;
}
public RequirePermissionAttribute(ChannelPermission permission)
/// <summary>
/// Require that the user invoking the command has a specified ChannelPermission.
/// </summary>
/// <param name="permission">The ChannelPermission that the user must have. Multiple permissions can be specified by ORing or ANDing the permissions together.</param>
/// <example>
/// <code language="c#">
/// [Command("permission")]
/// [RequireUserPermission(ChannelPermission.ReadMessageHistory & ChannelPermission.ReadMessages)]
/// public async Task HasPermission()
/// {
/// await ReplyAsync("You can read messages and the message history!");
/// }
/// </code>
/// </example>
public RequireUserPermissionAttribute(ChannelPermission permission)
{
ChannelPermission = permission;
GuildPermission = null;

+ 5
- 2
src/Discord.Net.WebSocket/DiscordSocketClient.cs View File

@@ -38,6 +38,7 @@ namespace Discord.WebSocket
private int _nextAudioId;
private bool _canReconnect;
private DateTimeOffset? _statusSince;
private RestApplication _application;

/// <summary> Gets the shard of of this client. </summary>
public int ShardId { get; }
@@ -333,8 +334,10 @@ namespace Discord.WebSocket
}

/// <inheritdoc />
public Task<RestApplication> GetApplicationInfoAsync()
=> ClientHelper.GetApplicationInfoAsync(this);
public async Task<RestApplication> GetApplicationInfoAsync()
{
return _application ?? (_application = await ClientHelper.GetApplicationInfoAsync(this));
}

/// <inheritdoc />
public SocketGuild GetGuild(ulong id)


Loading…
Cancel
Save