如何使Discord Bot等待特定用户使用JDA发送消息?

时间:2019-02-02 09:21:47

标签: java discord discord-jda

我目前服用介绍到Java编程类,最近已经开始与JDA工具尝试做一个基本的不和谐机器人为我的服务器。理想情况下,我希望我的机器人在有人说“你好苹果!”时做出回应。询问他们的名字,然后回答“嗨!”如果此消息是由说“你好苹果!”的同一个人发送的现在我的机器人不能等待过去初始任何用户输入“你好苹果!”消息,并立即溢出所有文本。我相信我当前的代码已正确设置,以确保漫游器仅以“嗨!”响应。如果它收到来自谁最初发送“嗨苹果!”同一个人的消息,但我不能完全确定,因为它不等待一个额外的消息,并因此从相同的消息两次读取并打印出来:
嗨!告诉我你的名字,或者说“停”!
嗨,嗨,苹果!
轮到您

我真的想知道如何创建一个某种形式的“一站式”的方法,或者会导致机器人等待来自谁最初映入眼帘的机器人用户除了用户输入,如果可能的话,办法设置时间限制,以使漫游器在不回复的情况下也不会无法运行。

import net.dv8tion.jda.core.AccountType;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.JDABuilder;

public class Main {
  public static void main(String[] args) throws Exception {
    try {
      JDA api = new     JDABuilder(AccountType.BOT).setToken("NTQxMTMxMDc4MTY1ODU2MjYw.DzbGoQ.oFIM_py    pLMOc60qU1PgeeUXU8Qo").build();
      api.addEventListener(new MyEventListener());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.Message;
import net.dv8tion.jda.core.entities.MessageChannel;
import net.dv8tion.jda.core.entities.Role;
import net.dv8tion.jda.core.entities.User;
import net.dv8tion.jda.core.entities.*;
import net.dv8tion.jda.core.events.message.MessageReceivedEvent;
import net.dv8tion.jda.core.hooks.ListenerAdapter;

public class MyEventListener extends ListenerAdapter {
  public void onMessageReceived(MessageReceivedEvent event) {
    if (event.getAuthor().isBot()) return;

    Message message = event.getMessage();
    String content = message.getContentRaw();
    MessageChannel channel = event.getChannel();

    if (content.startsWith("Hi Apples!")) {
      Member member = message.getMember();
      channel.sendMessage("Hi! Tell me your name, or say \"Stop\"!").queue();
      int n = 0;    
      while (n == 0) {
        Message message2 = event.getMessage(); 
        String content2 = message.getContentRaw();
        Member member2 = message2.getMember();
        String nick = member2.getNickname();
        if (member == member2) {
          channel.sendMessage("Hi " + content2 + "!").queue();
          n = 1;
        }
        else {
        }
          channel.sendMessage("Wait your turn " + nick + "!").queue();
        if (content2 == "Stop") {
          channel.sendMessage("Understood!").queue();
          n = 1;
        }
      }   
    }        
  }
}

我的预期结果是:
网友:苹果喜
BOT:嗨!告诉我你的名字,或者说停止!
用户2:嗨!
BOT:等待轮到你USER2
! USER:吉米
BOT:吉米,你好!

实际结果:(一次发送)
嗨!告诉我你的名字,或说“停”!
嗨,嗨,苹果!
等待轮到你了(我的不和谐昵称)!

1 个答案:

答案 0 :(得分:0)

由于您使用的是基于事件的框架,因此可以使用状态机来实现此行为。只要有初始触发器,在这种情况下,"Hi Apple!"就会为该文本通道启动一个新的状态机。

在此状态机中,您将处理消息事件,直到终止信号到达为止,在这种情况下为"Stop!"

状态机将使用事件方法中的切换用例以及专用的state字段来实现。在这种情况下,您整个对话中只有一次互动,因此只有一种状态使这一点变得毫无意义。

但是例如,在进行对话的情况下(我认为这将在以后发生),您需要使用状态机概念。

public class AppleStateMachine extends ListenerAdapter {
    private final long channelId, authorId; // id because keeping the entity would risk cache to become outdated

    public AppleStateMachine(MessageChannel channel, User author) {
        this.channelId = channel.getIdLong();
        this.authorId = author.getIdLong();
    }

    @Override
    public void onMessageReceived(MessageReceivedEvent event) {
        if (event.getAuthor().isBot()) return; // don't respond to other bots
        if (event.getChannel().getIdLong() != channelId) return; // ignore other channels
        MessageChannel channel = event.getChannel();
        String content = event.getMessage().getContentRaw();
        // since only one state is present you don't need a switch but that would be the concept if you had more than 1 interaction point in this protocol
        if (content.equals("Stop")) {
            channel.sendMessage("Understood!").queue();
            event.getJDA().removeEventListener(this); // stop listening
        }
        else if (event.getAuthor().getIdLong() == authorId) {
            channel.sendMessage("Hi " + content + "!").queue();
            event.getJDA().removeEventListener(this); // stop listening
        }
        else {
            channel.sendMessage("Wait your turn " + event.getMember().getEffectiveName() + "!").queue();
        }
    }
}

然后,您只需要在初始事件处理程序中注册此实例

if (content.startsWith("Hi Apples!")) {
    channel.sendMessage("Hi! Tell me your name, or say \"Stop\"!").queue();
    event.getJDA().addEventListener(new AppleStateMachine(channel, member.getUser());
}

另一种替代方法是使用JDA-UtilitiesEventWaiter