【发布时间】:2019-08-26 16:39:23
【问题描述】:
我想让我的不和谐机器人只响应具有@Member 角色的人,所以当没有该角色的人写命令(例如>say Hello)时,机器人不会响应它,但是当一个人@Member 角色写道,它会。
【问题讨论】:
标签: c# discord discord.net
我想让我的不和谐机器人只响应具有@Member 角色的人,所以当没有该角色的人写命令(例如>say Hello)时,机器人不会响应它,但是当一个人@Member 角色写道,它会。
【问题讨论】:
标签: c# discord discord.net
理想情况下,如果这用于一个命令或更确切地说是多个命令,则应使用前置条件(例如管理命令)。这使您不必在每个命令中重复检查。
可以在here 找到此类前提条件的示例。 你可以阅读更多preconditions here
【讨论】:
您需要为每个命令添加角色验证。
快速简便的方法是执行以下操作:
[Command("test")]
public async Task TestCommand()
{
var user as Context.User as IGuildUser;
var roleToValidate = Context.Guild.Roles.First(r => r.Name == "SomeRoleName");
if (!user.RoleIDs.Any(r => r == roleToValidate.Id))
return;
// the rest of the code
}
另一种方法(我会推荐)是使用 PreconditionAttribute
/// CheckRole.cs
using Discord;
using Discord.Commands;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Example.Attributes
{
public class CheckRole : PreconditionAttribute
{
private List<string> _roles;
public CheckRole(params string[] roles)
{
_roles = roles.ToList();
}
public async override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command)
{
var user = context.User as IGuildUser;
var discordRoles = context.Guild.Roles.Where(gr => _roles.Any(r => gr.Name == r));
foreach (var role in discordRoles)
{
var userInRole = user.RoleIds.Any(ri => ri == role.Id);
if (userInRole)
{
return await Task.FromResult(PreconditionResult.FromSuccess());
}
}
return await Task.FromResult(PreconditionResult.FromError("You do not have permission to use this role."));
}
}
}
/// WhateverClassThatYouWriteCommandsIn.cs
[Command("test")]
[CheckRole("AdminRoleName", "ModeratorRole", "NormalRole")]
public async Task TestCommandForMostRoles()
{
var user as Context.User as IGuildUser;
var roleToValidate = Context.Guild.Roles.First(r => r.Name == "Some Role Name");
if (!user.RoleIDs.Any(r => r == roleToValidate.Id))
return;
// the rest of the code
}
[Command("test")]
[CheckRole("AdminRoleName", "ModeratorRole")]
public async Task TestCommandForAdmins()
{
var user as Context.User as IGuildUser;
var roleToValidate = Context.Guild.Roles.First(r => r.Name == "Some Role Name");
if (!user.RoleIDs.Any(r => r == roleToValidate.Id))
return;
// the rest of the code
}
此文字代码可能无法正常工作,因为我尚未对其进行测试,但它是基于我自己的角色先决条件授权实现的。
分解代码:
我有一个变量来存储多个角色名称,并在构造函数中使用 params[] 来允许提供任意数量的角色名称。它们存储在变量中。
private List<string> _roles;
public CheckRole(params string[] roles)
{
_roles = roles.ToList();
}
每次调用特定命令时都会自动调用CheckPermissionsAsync。
public async override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command)
var user = context.User as IGuildUser;
var discordRoles = context.Guild.Roles.Where(gr => _roles.Any(r => gr.Name == r));
foreach (var role in discordRoles)
{
var userInRole = user.RoleIds.Any(ri => ri == role.Id);
if (userInRole)
{
return await Task.FromResult(PreconditionResult.FromSuccess());
}
}
return await Task.FromResult(PreconditionResult.FromError("You do not have permission to use this role."));
这可能看起来很多,但您不需要再次重写角色授权代码,您可以简单地将这个属性添加到您想要的任何命令中。如果您希望该类中的每个命令都由该角色授权,您还可以将此属性添加到该类:
[CheckRoles("Moderator", "LowLevelModerator")]
public class ModeratorCommands : ModuleBase<SocketCommandContext>
{
[Command("CheckStats")]
public async Task ModeratorCommandForCheckStats()
{
// the code
}
[Command("BanUser")]
public async Task ModeratorCommandForBanUser()
{
// the code
}
[CheckRole("Admin")]
[Command("BanUser")]
public async Task ModeratorCommandOnlyForAdminsForBanModerator()
{
// the code
}
}
【讨论】: