如何使不和谐的机器人仅对具有特定角色的人做出反应? [C#] [英] How do I make a discord bot respond only to people with a certain role? [C#]

查看:85
本文介绍了如何使不和谐的机器人仅对具有特定角色的人做出反应? [C#]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让我的不和谐机器人仅对具有@Member角色的人做出响应,因此,当没有该角色的人编写命令时(例如,说 Hello),机器人将不会对此做出响应,但是当有人

解决方案

您将需要为每个命令添加角色验证。 / p>

快速简便的方法是执行以下操作:

  [Command( test)] 
公共异步任务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))
返回;

//代码的其余部分
}

另一个方法(我建议)是使用PreconditionAttribute

  /// CheckRole.cs 

使用Discord ;
使用Discord.Commands;
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Threading.Tasks;

名称空间Example.Attributes
{
public class CheckRole:PreconditionAttribute
{
private List< string> _roles;

public CheckRole(params string []角色)
{
_roles = role.ToList();
}

公共异步覆盖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(discordRoles中的var角色)
{
var userInRole = user.RoleIds.Any(ri => ri == role.Id);

if(userInRole)
{
return await Task.FromResult(PreconditionResult.FromSuccess());
}
}

返回等待Task.FromResult(PreconditionResult.FromError(您无权使用此角色。));
}
}
}



  /// WhateverClassThatYouWriteCommandsIn.cs 

[Command( test)]
[CheckRole( AdminRoleName, ModeratorRole, NormalRole)]
public异步任务TestCommandForMostRoles()
{
var user as Context.User as IGuildUser;
var roleToValidate = Context.Guild.Roles.First(r => r.Name ==某些角色名称);

if(!user.RoleIDs.Any(r => r == roleToValidate.Id))
返回;

//代码的其余部分
}

[Command( test)]
[CheckRole( AdminRoleName, ModeratorRole )]
公共异步任务TestCommandForAdmins()
{
var user as Context.User as IGuildUser;
var roleToValidate = Context.Guild.Roles.First(r => r.Name ==某些角色名称);

if(!user.RoleIDs.Any(r => r == roleToValidate.Id))
返回;

//代码的其余部分
}

此文字代码可能无法运行,因为我尚未对其进行测试,但是它基于我自己的角色前提条件授权的实现,该功能有效。



要分解代码:


  1. 我有一个变量来存储多个角色名称,并在构造函数中使用params []来允许任意数量的角色名称被使用提供。它们存储在变量中。

      private List< string> _roles; 

    public CheckRole(params string []角色)
    {
    _roles = role.ToList();
    }


  2. CheckPermissionsAsync




 公共异步覆盖Task< PreconditionResult> CheckPermissionsAsync(ICommandContext上下文,CommandInfo命令)




  1. 获取名称中上下文中的实际Role对象,在它们之间循环并检查用户以查看它们是否具有该权限。第一次在用户上找到角色时,它将返回成功,并且将运行原始命令功能中的命令代码。如果返回FromError,则命令代码不会运行。



  var user = context.User作为IGuildUser; 
var discordRoles = context.Guild.Roles.Where(gr => _roles.Any(r => gr.Name == r));

foreach(discordRoles中的var角色)
{
var userInRole = user.RoleIds.Any(ri => ri == role.Id);

if(userInRole)
{
return await Task.FromResult(PreconditionResult.FromSuccess());
}
}

返回等待Task.FromResult(PreconditionResult.FromError(您无权使用此角色。));

这似乎很多,但是您无需再次重写角色授权代码,并且您可以简单地将此属性添加到所需的任何命令中。如果希望该类中的每个命令都由角色授权,也可以将此属性添加到该类中:

  [CheckRoles ( Moderator, LowLevelModerator)] 
公共类ModeratorCommands:ModuleBase< SocketCommandContext>
{
[Command( CheckStats)]
公共异步任务ModeratorCommandForCheckStats()
{
//代码
}

[Command( BanUser)]
公共异步任务ModeratorCommandForBanUser()
{
//代码
}

[CheckRole( Admin)]
[Command( BanUser)]
公共异步任务ModeratorCommandOnlyForAdminsForBanModerator()
{
//代码
}
}


I want to make my discord bot respond exclusively to people with a @Member role, so when a person without that role writes a command (ex. >say Hello), the bot will not respond to it, but when a person with the @Member role writes that, it will.

解决方案

You will need to add role validation to each of your commands.

The quick and easy way would be to do the following:

[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
}

Another approach (which I would recommend) is using 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
}

This literal code may not work as I haven't tested it, however it is based on my own implementation of role preconditions authorisation which works.

To break down the code:

  1. I have a variable to store multiple role names and use params[] in the constructor to allow any amount of role names to be provided. They are stored in the variable.

    private List<string> _roles;
    
    public CheckRole(params string[] roles)
    {
        _roles = roles.ToList();
    }
    

  2. CheckPermissionsAsync is automatically called every time that particular command is called.

public async override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command)

  1. Get the actual Role objects from the context from the names, loop through them and check the user to see if they have that permission. The first time a role is found on a user it will return a success and the command code in the original command function will be run. If FromError is returned then the command code is not run.

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."));

This might seem like a lot, but you do not need to re-write role authorisation code again and you can simply add this attribute to whatever commands you want. You can also add this attribute to the class if you want every command in that class to be authorised by the 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
   }
}

这篇关于如何使不和谐的机器人仅对具有特定角色的人做出反应? [C#]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆