从 DiscordBot CommandService 中删除命令

Posted

技术标签:

【中文标题】从 DiscordBot CommandService 中删除命令【英文标题】:Removing a command from DiscordBot CommandService 【发布时间】:2017-09-11 06:26:47 【问题描述】:

我试图弄清楚如何在创建 discord 机器人后从它中删除命令。以下是我创建命令的方式:

_commandService.CreateCommand("create").Parameter("message", ParameterType.Multiple).Do(async e =>
        
    var message = e.Args.Skip(1).Aggregate("", (current, t) => current + (t + " "));;

    _commandService.CreateCommand("hello").Do(async cc =>
    
        await e.User.SendMessage(customCommand.Message);
    );
);

_commandService 对象的类型为Discord.Commands.CommandService

现在,我希望能够运行:

_commandService.CreateCommand("delete").Parameter("message", ParameterType.Multiple).Do(async e =>
    
    _commandService.DeleteCommand("hello");
);

但是,不存在这样的方法,我也无法访问 _commandService 对象中的命令,因为所有内容都是只读的 get;

有谁知道如何在不重启机器人的情况下删除命令?

【问题讨论】:

【参考方案1】:

这是可能的,但从 discord.net 1.0 开始,您需要使用 Modules 系统来执行此操作。不幸的是,它使事情变得非常复杂。希望他们能在未来的更新中添加适当的DeleteCommand(string commandName)

为什么需要这样做(如果您不关心 discord.net 来源,则不需要此部分): 类 CommandMap (毫不奇怪,它存储命令)公开了一个方法 RemoveCommand ,它可以完成您想要做的事情。源中对此类对象的唯一引用是在 CommandService 中的私有方法 RemoveModuleInternal 中。这通过以下两种公共方法之一公开:RemoveModuleAsync(ModuleInfo module)RemoveModuleAsync<T>()。从 1.0 版本开始,没有其他方法可以影响命令。

如何做:首先为您的模块获取 ModuleInfo 对象。最好,您创建的模块将仅包含您要删除的命令,原因很快就会很明显。当您使用CreateModuleAsync(string primaryAlias, Action<ModuleBuilder> buildFunc)(或用于添加模块的其他方法之一)时,您将获得 ModuleInfo 对象。这确实意味着您需要使用 ModuleBuilder 而不是您使用的简单 commandService.CreateCommand 方法。阅读如何做到这一点here...如果这个过程仍然让你感到困惑,那么这是另一个问题的好话题。

您需要跟踪 CreateModuleAsync 以某种方式返回的 ModuleInfo 对象(我将使用的方法如下),然后您的第二个命令变为:

// private ModuleInfo createInfo
_commandService.CreateCommand("delete").Parameter("message", ParameterType.Multiple).Do(async e =>
    
    if (createInfo != null)
    
        await _commandService.DeleteModuleAsync(createInfo);
    
);

请注意整个模块实例正在被删除...这就是为什么你的“创建”命令应该是其中唯一的东西。

另一种解决方案(虽然明显不那么优雅)如果整个模块业务看起来太复杂,则存储一个布尔值并简单地切换它以模拟命令的删除。那就是:

// bool createNotDeleted = true;
_commandService.CreateCommand("create").Parameter("message", ParameterType.Multiple).Do(async e =>
    
    if (createNotDeleted) 
    
        var message = e.Args.Skip(1).Aggregate("", (current, t) => current + (t + " "));;

        _commandService.CreateCommand("hello").Do(async cc =>
        
            await e.User.SendMessage(customCommand.Message);
        );
    
    else
    
        // error handling
        

);

_commandService.CreateCommand("delete").Parameter("message", ParameterType.Multiple).Do(async e =>
    
    if (createNotDeleted)
    
        createNotDeleted = false
        // return something indicating command is deleted
    
    else
    
        // error handling
    
);

【讨论】:

以上是关于从 DiscordBot CommandService 中删除命令的主要内容,如果未能解决你的问题,请参考以下文章

Discord Bot - 无法从 Intents 访问 FLAGS

discord bot - 从用户发送多个变量

Discordbot 读取 DM 消息并记录它们

为多个服务器设置 DiscordBot 的频道 ID

serverDeafen discordbot |不和谐/ js

Discord Bot - 从网站下载 JSON 文件并提取其中的某些元素