[Tutorial] How to get user chat input after a command or event

Discussion in 'Resources' started by MrAwellstein, Apr 15, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    MrAwellstein

    Okay, so please bear with me, as I am not the best at English or explaining things...
    But this basically works like this:
    1. User does command
    2. Command adds user to a hashmap
    3. asyncplayerchatevent picks up the chat, and checks if the player is in the hashmap
    4. if the player is in the hashmap, then send chat handling over to something to manage it
    5. cancel the event so no one sees it, and parse the message.
    Also you can have stages, so if you want to have multiple parsed responses, like if you have multiple options you want other than just all on one parse line.


    Anyways, here is my code. (Please ignore improper names, I get lazy and or just don't want to deal with things...).



    First, you will need to create your HashMap that deals with each of the players, and the Parser object/class/method.
    Code:java
    1. import java.util.HashMap;
    2.  
    3. import org.bukkit.entity.Player;
    4. import org.bukkit.event.player.AsyncPlayerChatEvent;
    5. import org.bukkit.plugin.Plugin;
    6.  
    7. public class ChatInputMap {
    8.  
    9. private HashMap<String, Object> chatmap = new HashMap<String, Object>();
    10. public HashMap<String, Object> getChatMap(){return chatmap;}
    11.  
    12. public void addToMap(Player p, Object o){
    13. addToMap(p.getName().toString(),(ChatInputStuff) o);
    14. }
    15.  
    16. public void addToMap(String p, ChatInputStuff o){
    17. if(chatmap.containsKey(p)){
    18. ((ChatInputStuff)chatmap.get(p)).cleanup();
    19. chatmap.remove(p);
    20. }else{
    21. chatmap.put(p, o);
    22. }
    23. }
    24.  
    25. public void doSomething(String name, String message, AsyncPlayerChatEvent event, Plugin plugin){
    26. if(chatmap.containsKey(name)){
    27. if(chatmap.get(name)!= null){
    28. ((ChatInputStuff)chatmap.get(name)).doSomething(this, name, message, event, plugin);
    29. }
    30. }
    31. }
    32.  
    33. public boolean PlayerInChat(String name){return chatmap.containsKey(name);}
    34.  
    35. public void removePlayer(String name){
    36. if(chatmap.containsKey(name)){
    37. ((ChatInputStuff)chatmap.get(name)).cleanup();
    38. chatmap.remove(name);
    39. }
    40. }
    41.  
    42. }
    43.  



    Then you will want to create your Parser class (The order really doesn't matter to me). Should look something like this (or you can use this as a base or something).
    Code:java
    1. import org.bukkit.Bukkit;
    2. import org.bukkit.entity.Player;
    3. import org.bukkit.event.player.AsyncPlayerChatEvent;
    4. import org.bukkit.plugin.Plugin;
    5.  
    6. public abstract class ChatInputStuff {
    7.  
    8. private int stage;
    9. public int getStage(){return stage;}
    10. public void setStage(int a){stage = a;}
    11.  
    12. private String message;
    13. public String getMessage(){return message;}
    14.  
    15. private String user;
    16. public String getUser(){return user;}
    17.  
    18. public Player getPlayer(){return Bukkit.getPlayer(user);}
    19.  
    20. public void doSomething(ChatInputMap map, String username, String message, AsyncPlayerChatEvent event, Plugin plugin){
    21.  
    22. }
    23.  
    24. public void doSomething(ChatInputMap map, Player p, String message, AsyncPlayerChatEvent event){
    25.  
    26. }
    27.  
    28. public void cleanup() {
    29.  
    30. }
    31.  
    32. }



    I personally just extended the ChatInputStuff class, and had something like this (this is my example of how to create a Parser class based off of the base parser class I created).
    Code:java
    1. import org.bukkit.Bukkit;
    2. import org.bukkit.entity.Player;
    3. import org.bukkit.event.player.AsyncPlayerChatEvent;
    4. import org.bukkit.plugin.Plugin;
    5.  
    6. public class ExampleParser extends ChatInputStuff {
    7.  
    8. private int stage = 0;
    9. @Override public int getStage(){return stage;}
    10. @Override public void setStage(int a){stage = a;}
    11.  
    12. @Override public void doSomething(ChatInputMap map, String username, String message, AsyncPlayerChatEvent event, Plugin plugin){
    13. event.setCancelled(true);
    14. /*
    15. * Note this requires something to inform them. This only works after they say something, not before.
    16. */
    17. if(stage == 0){
    18. Bukkit.getPlayer(username).sendMessage("The Thing you just said was " + message+", right?");
    19. stage++;
    20. return;
    21. }else if(stage == 2){
    22. if(message.toLowerCase().contains("yes")){
    23. Bukkit.getPlayer(username).sendMessage("Okay, so I did hear you correctly :)");
    24. }else{
    25. Bukkit.getPlayer(username).sendMessage("Huh, my hearing must be off :(");
    26. }
    27. Bukkit.getPlayer(username).sendMessage("Anyways, how are you?");
    28. stage++;
    29. return;
    30. }else if(stage >= 3){
    31. Bukkit.getPlayer("Ah Okay. Anyways I gtg. Ttyl!");
    32. stage = 9001;
    33. map.removePlayer(username);
    34. }
    35.  
    36. }
    37.  
    38. @Override
    39. public void doSomething(ChatInputMap map, Player p, String message, AsyncPlayerChatEvent event, Plugin plugin){
    40. doSomething(map, p.getName(),message,event, plugin);
    41. }
    42.  
    43. @Override
    44. public void cleanup() {
    45.  
    46. }
    47.  
    48. }



    You will need to set up an event like this..
    Code:java
    1. private ChatInputStuff cis = new ChatInputStuff();
    2.  
    3. @EventHandler
    4. public void onPlayerChat(AsyncPlayerChatEvent event){
    5. if(cis.PlayerInChat(event.getPlayer().getName())){
    6. cis.doSomething(event.getPlayer().getName(), event.getMessage(), event, plugin);
    7. }
    8. }



    And finally, you would add someone to the list like....
    Code:java
    1.  
    2. sender.sendMessage("Enter Here what it should queue the player with");
    3. cis.addToMap((Player)sender, new ExampleParser());



    Any questions, ask below. If you are getting any errors with what you are doing, then please try to trouble shoot the errors before you actually ask here.
    Thanks for reading this awful tutorial ^w^

    Note: If anyone has any ideas that they could use this for, please mention below, because I would like to know of other ideas that this could be used for, besides for my own ideas.

    SideNote: Wrote this with a migraine.
     
  2. Offline

    iiHeroo

    CONGRATS ON THIS BEING THE 1000TH THREAD IN RESOURCES
     
    Phasesaber and GregMC like this.
  3. Offline

    MrAwellstein

    wait what.
     
  4. Offline

    Garris0n

    Isn't this what the conversation API is for?
     
  5. Offline

    MrAwellstein


    Never actually heard of that API. Anyways this is just showing how I did it, and I posted in case anyone was looking.
     
  6. Offline

    Garris0n

    It's a (rather obscure) API in Bukkit that, I believe, does what you're doing right now.
     
  7. Offline

    MrAwellstein


    It probably does. I couldn't really imagine another logical way of going about this.
     
  8. Offline

    Garris0n

    You should check it out, it's pretty interesting.
     
  9. Offline

    MrAwellstein


    Alright, will do. Thanks for telling me about it :D
     
  10. Offline

    iiHeroo

  11. Offline

    MrAwellstein

  12. Offline

    xTrollxDudex

    MrAwellstein
    Code not thread safe for async player chat event
     
  13. Offline

    MrAwellstein

    There isn't a syncchatevent is there? Do I need to do something to run a runnable on the main thread?
     
  14. Offline

    TheE

    There is the normal PlayerChatEvent. As xTrollxDudex said, the code you posted is not threadsafe for multiple reasons including bukkit-api usage from outside the main-thread, non-threadsafe collections and probably missing synchronizing. It must not been used.
     
    xTrollxDudex likes this.
  15. Offline

    xTrollxDudex

  16. Offline

    MrAwellstein

    Ah okay.
     
  17. Offline

    atesin

    in the original post .. instead

    could it be ...

    1. player fires some event (block place, interact, etc)
    2. PLUGIN FORCEDLY OPENS the player chat input line, as if user were pressed "T"
    3. plugin picks up the the answer, and do something with it if was empty or not
    ... so your plugin fires the string prompt on the client when he needs, forcing the player answer instead of just "waiting" when the player wants to? , like c "scan" or javascript "prompt()" functions??
     
Thread Status:
Not open for further replies.

Share This Page