Solved Conversation(API) not ending

Discussion in 'Spigot Plugin Help' started by Damascus2000, Jan 11, 2019.

  1. Hey guys,
    I'm writing a plugin to make teams, everything went fine untill I got stuck on the Conversation API, it seems it doesn't end. So when I test it in-game everything works properly, the conversations starts and I get 2 prompts, 1 for the Teamname and one for the TeamColor
    Howerver after I finished the conversation (I get a message that the team is created, see TeamColorPrompt) I don't recieve the message "It worked"
    Does somebody know the problem?


    Code (Java):
        @EventHandler
        public void onSignClick(PlayerInteractEvent e) throws InterruptedException {
            if ((e.getAction() == Action.RIGHT_CLICK_BLOCK)){
               if (e.getClickedBlock().getState() instanceof Sign) {
                    Sign sign = (Sign) e.getClickedBlock().getState();
                    if (sign.getLine(0).equalsIgnoreCase(ChatColor.AQUA + "Create Team")){
                        ConversationFactory cf = new ConversationFactory(Main.getPlugin()).withFirstPrompt(new TeamNamePrompt(e.getPlayer().getName())).withLocalEcho(false).withEscapeSequence("exit");
                        Conversation conv = cf.buildConversation(e.getPlayer());
                        conv.begin();
                        e.getPlayer().sendMessage("IT worked!");
    Code (Java):
    public class TeamNamePrompt extends ValidatingPrompt {

        private String playername;
        public TeamNamePrompt(String player){
            playername = player;
        }
        @Override
        public String getPromptText(ConversationContext context) {
            return "Please enter the name for your team";
        }

        @Override
        protected boolean isInputValid(ConversationContext context, String input) {
            if (!input.equalsIgnoreCase("")){
                return true;
            }
            else {
                return false;
            }
        }

        @Override
        protected Prompt acceptValidatedInput(ConversationContext context, String input) {
            context.getForWhom().sendRawMessage("Teamname: " + input);
            context.setSessionData("Name", input);
            return new TeamColorPrompt(playername);
        }
    }
    Code (Java):
    public class TeamColorPrompt extends StringPrompt {
        private String player;
        public TeamColorPrompt(String playername){
            player  = playername;
        }

        @Override
        public String getPromptText(ConversationContext context) {
            return "Please enter the color of your team";
        }

        @Override
        public Prompt acceptInput(ConversationContext context, String input) {
            context.getForWhom().sendRawMessage(input);
            context.setSessionData("Color", input);
            context.getForWhom().sendRawMessage(player + context.getSessionData("Name"));
            Main.createTeam(context.getSessionData("Name").toString(), context.getSessionData("Color").toString(), player);
            context.getForWhom().sendRawMessage("Team created");
            return END_OF_CONVERSATION;
        }
    }
     
  2. Instead of using #withEscapeSequence, use a ConversationCanceller (or ConversationAbandonedListener) to send a message to the player when the conversation ends. Right now, you're probably just being sent the message while still in conversation, since the server won't wait for the conversation to end before sending the player "it worked".
     
  3. The server does not send the player "It worked" that's in fact the problem
    But I will try use a ConversationCanceller
     
  4. I'm aware of that, no worries. The reason is that, while you're in a Conversation provided by the Bukkit API, you won't see other chat messages.
     
  5. Okay, I see then how do I make the class wait for the conversation to finish. I tried this : (at the end of the conversation it creates a team and puts the player in it, so I just check if the player has a team) but this does not work as it doesn't allow me to type in the conversation and after a few seconds makes the server crash
    Code (Text):
    conv.begin();
                        while (Main.getTeam(e.getPlayer().getName()) == null){
                        }
                        e.getPlayer().sendMessage("IT worked!");
     
  6. The server is crashing because that while loop is bugging out the main thread >_> you can't make the class wait for the player to finish their conversation without hanging up the main thread like that. That's why there are ConversationCancellers and ConversationAbandonedListeners. They have methods that will be fired when a conversation is ended or abandoned.
     
  7. So I make a second method in that class that gets executed by the conversationAbandonedListener? To get around that?
     
  8. You'd implement ConversationAbandonedListener in one of your own classes. An anonymous inner class also works here, since the interface is a functional interface.
    Ex:
    Code (Java):
    Conversation conv = new Conversation(plugin)...addConversationAbandonedListener((event) -> {
        // This is only assuming that the conversing entity is a player, which isn't guaranteed
        Player player = (Player)event.getConversation().getForWhom();
        player.sendMessage("It worked!");
    })...
     
  9. Okay Thank you very much
     

Share This Page