1

我正在将我的 Discord 机器人从Discord4J v2重写为v3基于 Reactor 的。我是响应式编程的新手,尤其是 Java Reactor。我想用三种类型的命令实现一个命令系统:

  1. DM 命令——用户作为直接消息发送给机器人的命令,
  2. 公共公会命令——用户#bot-commands在我的 Discord 服务器的特殊频道中发送的命令——每个具有特定角色X的人都可以使用这些命令,并且
  3. admin guild commands — 类似于 public,但用户必须有一些角色Y(高于X)。

如果用户尝试执行某些特定命令但他们没有获得所需的角色,机器人应该告诉他们这一点。否则,应该执行命令(考虑到发送者(消息作者)、发送此命令的通道以及命令本身(消息))。

我不确定如何反应地实现这一切,我在 Discord4J wiki 上找不到必要的信息。这是我目前拥有的:

private final Set<DiscordCommand> discordGuildCommands = new HashSet<>();
private final Set<DiscordCommand> discordDmCommands    = new HashSet<>();

// ...

gateway = DiscordClient.create(discordToken).login().block();

// ...

        gateway.getEventDispatcher()
                .on(MessageCreateEvent.class)
                .filter(event -> !(event.getMessage().getChannel().block() instanceof PrivateChannel))
                .filterWhen(event -> event.getMember().get().hasHigherRoles(Roles.REFLEXBOT_CTRL_SINGLETON))
                .flatMap(event -> Mono.just(event.getMessage().getContent())
                        .flatMap(content -> Flux.fromIterable(discordGuildCommands)
                                .filter(cmd -> content.startsWith(DISCORD_COMMANDS_PREFIX + cmd.getName()))
                                .flatMap(cmd -> cmd.process(event))
                                .next()
                        )
                )
                .subscribe();

此代码似乎工作正常,并允许我处理admin guild commands,即“权限级别”(最高角色级别)至少为我指定的成员在我的 Discord 服务器的文本频道中发送的命令。

但是我如何正确地(反应地和很好地)实现其余的命令呢?我没有在 Reactor 中找到类似 if/else 链接的东西,而且我真的不想多次重复上面的代码,只filter(...)更改 1-2 行。

4

1 回答 1

1

我不熟悉 Discord4J,但我认为你应该逆流并为你的命令添加一些设置。

  1. 添加哈希映射 [命令名 => 通道/私有]
  2. 添加哈希映射 [命令名 => 最小角色]
  3. 添加哈希映射 [命令名 => 命令]

然后构建您的流程:

  1. 从第一张地图获取命令(或返回错误“我不知道该命令”)
  2. 使用第一个映射检查命令是否与请求类型(私有/通道)匹配(或返回错误“我不知道该命令”)
  3. 使用第二个地图检查用户角色(或返回错误“访问被拒绝”)
  4. 从第三张地图获取命令实例
  5. 运行命令
于 2020-11-20T10:37:02.867 回答