从 DiscordBot CommandService 中删除命令
Removing a command from DiscordBot CommandService
我想弄清楚如何在命令创建后从 discord bot 中删除它。以下是我创建命令的方式:
_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;
有谁知道如何在不重启机器人的情况下删除命令?
这是可能的,但是从 discord.net 1.0 开始,您需要使用模块系统来完成它。不幸的是,它使事情变得非常复杂。希望他们会在未来的更新中添加适当的 DeleteCommand(string commandName)
。
为什么需要这样做(如果您不关心 discord.net 来源,则不需要此部分):
class CommandMap(毫不奇怪,它存储命令)公开了一个方法 RemoveCommand 来执行您想要执行的操作。源码中唯一对这个class对象的引用是在CommandService的私有方法RemoveModuleInternal中。这在两个 public 方法之一中公开:RemoveModuleAsync(ModuleInfo module)
或 RemoveModuleAsync<T>()
。从 1.0 版本开始,没有其他方法可以影响命令。
怎么做:首先获取模块的 ModuleInfo 对象。最好,您创建的模块将只包含您要删除的命令,原因很快就会显而易见。当您使用 CreateModuleAsync(string primaryAlias, Action<ModuleBuilder> buildFunc)
(或用于添加模块的其他方法之一)时,您将取回 ModuleInfo 对象。这确实意味着您需要使用 ModuleBuilder 而不是您使用的简单 commandService.CreateCommand
方法。阅读如何做到这一点 here... 如果这个过程仍然让您感到困惑,那么这是另一个问题的绝佳话题。
您需要以某种方式跟踪 CreateModuleAsync returns 的 ModuleInfo 对象(我将使用的方法如下),然后您的第二个命令变为:
// private ModuleInfo createInfo
_commandService.CreateCommand("delete").Parameter("message", ParameterType.Multiple).Do(async e =>
{
if (createInfo != null)
{
await _commandService.DeleteModuleAsync(createInfo);
}
});
请注意,整个模块实例都被删除了...这就是为什么您的 "create" 命令应该是其中唯一的东西。
另一个解决方案(尽管明显不那么优雅)如果整个模块业务看起来太复杂,将存储一个布尔值并简单地切换它以模拟命令的删除。即:
// 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
}
});
我想弄清楚如何在命令创建后从 discord bot 中删除它。以下是我创建命令的方式:
_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;
有谁知道如何在不重启机器人的情况下删除命令?
这是可能的,但是从 discord.net 1.0 开始,您需要使用模块系统来完成它。不幸的是,它使事情变得非常复杂。希望他们会在未来的更新中添加适当的 DeleteCommand(string commandName)
。
为什么需要这样做(如果您不关心 discord.net 来源,则不需要此部分):
class CommandMap(毫不奇怪,它存储命令)公开了一个方法 RemoveCommand 来执行您想要执行的操作。源码中唯一对这个class对象的引用是在CommandService的私有方法RemoveModuleInternal中。这在两个 public 方法之一中公开:RemoveModuleAsync(ModuleInfo module)
或 RemoveModuleAsync<T>()
。从 1.0 版本开始,没有其他方法可以影响命令。
怎么做:首先获取模块的 ModuleInfo 对象。最好,您创建的模块将只包含您要删除的命令,原因很快就会显而易见。当您使用 CreateModuleAsync(string primaryAlias, Action<ModuleBuilder> buildFunc)
(或用于添加模块的其他方法之一)时,您将取回 ModuleInfo 对象。这确实意味着您需要使用 ModuleBuilder 而不是您使用的简单 commandService.CreateCommand
方法。阅读如何做到这一点 here... 如果这个过程仍然让您感到困惑,那么这是另一个问题的绝佳话题。
您需要以某种方式跟踪 CreateModuleAsync returns 的 ModuleInfo 对象(我将使用的方法如下),然后您的第二个命令变为:
// private ModuleInfo createInfo
_commandService.CreateCommand("delete").Parameter("message", ParameterType.Multiple).Do(async e =>
{
if (createInfo != null)
{
await _commandService.DeleteModuleAsync(createInfo);
}
});
请注意,整个模块实例都被删除了...这就是为什么您的 "create" 命令应该是其中唯一的东西。
另一个解决方案(尽管明显不那么优雅)如果整个模块业务看起来太复杂,将存储一个布尔值并简单地切换它以模拟命令的删除。即:
// 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
}
});