Editing JSON messages

Discussion in 'Spigot Plugin Development' started by HeyAwesomePeople, May 25, 2017.

  1. Hello guys,

    I'm working a plugin that will allow you to type something like "[item]" in chat and it'll replace those words with the item you're holding and when you hover it, it'll give item metadata. So for example,

    Input: Hey guys check out my [item]
    Output: Hey guys check out my >> Diamond Sword <<

    Input: Look at my [item], it's awesome!
    Output: Look at my >> Diamond Sword <<, it's awesome!

    As you can tell, the replacement includes the item name and the arrow thingies, and when you hover over the replaced part it will show the item's data.

    I can use FancyMessage, like so:
    Code (Text):
    new FancyMessage(replacementSyntax.replace("%itemname%", matName)).itemTooltip(itemInHand).toJSONString();
    But with FancyMessage, I cannot edit the JSON that the user has already said in chat. At least, I don't think. How would I go about doing this sort of replacement? I know the JSON is possible, but I don't know how to do it exactly. I was thinking maybe just getting the raw text and then creating a new JSON string with that, but I feel like that would interrupt any JSON changes that DeluxeChat tries to make itself before I add my additions.

    Thanks guys
     
  2. Why not make the player send a JSON message?
     
  3. What do you mean by that?

    DeluxePlugin handles the chat in JSON format. I am trying to figure out how to handle the JSON to edit the message and replace the "[item]" text with something else that also has a hover effect on it (tool item hover through fancymessage).
     
  4. Some chat event, replace [item] with whatever they have on their hand. message.replace("[item]", "Item, get from player's inventory");
     
  5. I built a plugin a while ago that did this, I'll check the code when I'm home but I'm sure I made the player send the fancy message (yes I was using deluxechat).
     
  6. This is not hard to create by yourself.
     
    • Like Like x 1
  7. Thanks for the help.

    Yeah I'm using FancyMessage to make the itemToolTip hover on a piece of text and it's giving me a MalformedJsonError.

    Code (Text):
        @EventHandler(priority = EventPriority.HIGH)
        public void playerChat(DeluxeChatJSONEvent e) {
            String jsonMsg = e.getJSONChatMessage();

            Bukkit.broadcastMessage("Message: " + jsonMsg);
            String keyword = plugin.getConfig().getString("keyword");


            List<JsonElement> textPieces = new ArrayList<>();
            JsonElement element = new JsonParser().parse(jsonMsg);
            JsonObject object = element.getAsJsonObject();
            JsonArray array = object.getAsJsonArray("extra");

            for (JsonElement je : array) {
                textPieces.add(je);
            }

            for (JsonElement el : textPieces) {
                if (el.getAsJsonObject().get("text") == null) continue;
                if (el.getAsJsonObject().get("text").toString().contains(keyword)) {
                    String s = el.getAsJsonObject().get("text").toString();
                    el.getAsJsonObject().remove("text");

                    ItemStack i = e.getPlayer().getItemInHand();
                    if (i == null || i.getType() == null || i.getType() == Material.AIR) continue;
                 
                    String jToParse = s.replace(keyword, new FancyMessage("REPLACEMENT").itemTooltip(i).toJSONString());

                    JsonElement parsed = new JsonParser().parse(jToParse); // ERROR HERE
                 
                    el.getAsJsonObject().add("text", parsed);

                }
            }

            object.remove("extra");
            JsonArray newArray = new JsonArray();
            for (JsonElement elem : textPieces) {
                newArray.add(elem);
            }
            object.add("extra", newArray);

            e.setJSONChatMessage(object.toString());
        }
    Code (Text):
    Could not pass event DeluxeChatJSONEvent to ItemsInChat v1.0
    org.bukkit.event.EventException
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:310) ~[spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487) [spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at me.clip.deluxechat.listeners.AsyncPlayerChatListener.onChat(AsyncPlayerChatListener.java:108) [DeluxeChat.jar:?]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_131]
            at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_131]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_131]
            at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_131]
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) [spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) [spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:484) [spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at net.minecraft.server.v1_8_R3.PlayerConnection.chat(PlayerConnection.java:1084) [spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:1022) [spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at net.minecraft.server.v1_8_R3.PacketPlayInChat$1.run(PacketPlayInChat.java:39) [spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_131]
            at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_131]
            at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [?:1.8.0_131]
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [?:1.8.0_131]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_131]
    Caused by: com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 5
            at com.google.gson.JsonParser.parse(JsonParser.java:65) ~[spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at com.google.gson.JsonParser.parse(JsonParser.java:45) ~[spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at me.HeyAwesomePeople.ItemsInChat.ChatListener.playerChat(ChatListener.java:67) ~[?:?]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_131]
            at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_131]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_131]
            at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_131]
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            ... 20 more
    Caused by: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 5
            at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1505) ~[spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at com.google.gson.stream.JsonReader.checkLenient(JsonReader.java:1386) ~[spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:531) ~[spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at com.google.gson.stream.JsonReader.peek(JsonReader.java:414) ~[spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at com.google.gson.JsonParser.parse(JsonParser.java:60) ~[spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at com.google.gson.JsonParser.parse(JsonParser.java:45) ~[spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            at me.HeyAwesomePeople.ItemsInChat.ChatListener.playerChat(ChatListener.java:67) ~[?:?]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_131]
            at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_131]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_131]
            at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_131]
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[spigot-1.8.8.jar:git-Spigot-5f38d38-18fbb24]
            ... 20 more
    I looked into it and I noticed that some people had said that invisible characters in the string can cause this to happen, so I tried to remove non-breaking white spaces (char 160) but that didn't work.

    Code (Text):
    jToParse = jToParse.replace("\\u00A0","");
    When I do string.length, I get 130. When I print the strong and count the characters, I get 128. Do you think maybe there are 2 invisible characters that could be causing this exception?

    Thanks guys

    EDIT: When I take the string "jToParse" and print it out, copy it, then do:

    Code (Text):
    e.setJSONChatMessage("{\"text\":\"REPLACEMENT\",\"color\":\"white\",\"hoverEvent\":{\"action\":\"show_item\",\"value\":\"{id:\\\"minecraft:grass\\\",Count:1b,Damage:0s}\"}}");
    It works perfectly. So I know the JSON is fine (confirmed with jsonlint), but why isn't it able to be parsed correctly?
     
  8. I don't know if relevant, but why are you using JsonElement#get("key").toString() when in reality you should be using JsonElement#get("key").getAsString()?
     
  9. Because i haven't looked at your code, it's simple to create it with logic, yeah i know this doesn't help but i can't give you any code. What you should do is, when you have the diamond sword in your hand and you write in the chat check out my [item] guys, it's legendary! you should get the current item from your hands, the full details, get all the lore's if it has, get the display name, get enchants, and just change the chat message from [item] to the <Item_Name> and send a text component to it so whey they move their mouse to the name to show up the full things with the text component. What you actually do is changing the [item] message to a message by using a text Component

    This is what i used, an example.
    Code (Text):
                TextComponent msg = new TextComponent(ChatColor.DARK_GREEN + " ยป Your destiny ");
                TextComponent c = new TextComponent(ChatColor.translateAlternateColorCodes('&', "" + "&7[Move your cursor here&7]"));
                c.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(ChatColor.GOLD +
                        "Your destiny is bad").create()));
                msg.addExtra(c);
                p.spigot().sendMessage(msg);
     
    #9 Nosmakos, May 26, 2017
    Last edited: May 26, 2017
  10. I was getting some errors when using .getAsString() and online solutions said to use just .toString(). I don't think it makes a difference, but you can check out the error: https://pastebin.com/1GShSu6M

    Yup, so I'm almost doing all of that. I have the whole replacement thing down and everything, the issue I have now is that the JsonParser cannot parse the Json from the FancyMessage itemToolTip. Do you recommend I just create my own method to do that, since it seems to be kind of broken?
     
  11. Yeah i would recommend create one of your own, i mean that would take a few hours to create the full thing with only a text component and nothing else. It's really easy basically if you know where to start, i think it's only to change the message when a player is sending something that contains [item] by taking the item player is holding and also checking if player does not have anything on his hands to change the [item] something else you want, or even cancel his whole message if the item is null and send him a message that he has nothing to show.
    Then it's only creating a text component which can be really easy. You don't need any API or something to do that, you need only AsyncPlayerChatEvent if i am correct. Then if (playerMessage.contains(word)) ([item] to change the message.
     
  12. I haven't tried this
    (took me 10 mins to make)
    Code (Text):
    package bukkit;

    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.AsyncPlayerChatEvent;
    import org.bukkit.permissions.Permission;
    import org.bukkit.permissions.PermissionDefault;
    import org.bukkit.plugin.java.JavaPlugin;

    public class ItemShower extends JavaPlugin implements Listener {

        private static final Permission ITEMPERM = new Permission("itemchat");

        public void onEnable() {
            ITEMPERM.setDefault(PermissionDefault.OP);
           
            getServer().getPluginManager().addPermission(ITEMPERM);
            getServer().getPluginManager().registerEvents(this, this);
        }
       
        @EventHandler
        public void onChat(AsyncPlayerChatEvent event) {
            Player p = event.getPlayer();
           
            if(!p.hasPermission(ITEMPERM)) return;
           
            String chat = event.getMessage();
           
            chat = chat.replace("[item]", p.getInventory().getItemInMainHand().getItemMeta().getDisplayName());
           
            event.setMessage(chat);
        }
    }
     
     
  13. This is the default way, with a text component it's almost the same. He should replace only the item with a text component of the item he is holding.
     
  14. Oh, you want to use textcomponetes? ok
     
  15. He wants not me XD
     
  16. Why would you have a private constant? Also this is pretty far away from what they want, also I don't know if it'd be compatible with other chat plugins.