Util JSONMessage

Discussion in 'Resources' started by PhantomUnicorns, May 8, 2018.

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

    PhantomUnicorns

    Hey this util does JSON messages with multiple json strings in one message. After seeing @xTechno_'s thread (this) it made me want to do JSON messages with multiple events in one message. Here it is:

    Code (open)

    Code:
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.ItemStack;
    
    public class Jinx {
    
        private static Class<?> _CRAFTPLAYER_CLASS;
        private static Constructor<?> _PACKET_PLAY_OUT_CHAT_CONSTRUCTOR;
        private static Method _A_METHOD, _GETHANDLE_METHOD, _SEND_PACKET_METHOD;
        private static Field _PLAYER_CONNECTION_FIELD;
    
        private static final HoverEvent _BLANK_HOVER_EVENT;
        private static final ClickEvent _BLANK_CLICK_EVENT;
        private static final Jinx _JINX;
    
        static {
            String name = Bukkit.getServer().getClass().getName();
            name = name.substring(name.indexOf("craftbukkit.") + "craftbukkit.".length());
            final String _VERSION = name.substring(0, name.indexOf("."));
            try {
                Class<?> _ICHAT_BASE_COMPONENT_CLASS = Class
                        .forName("net.minecraft.server." + _VERSION + ".IChatBaseComponent");
                Class<?> _PACKET_PLAY_OUT_CHAT_CLASS = Class
                        .forName("net.minecraft.server." + _VERSION + ".PacketPlayOutChat");
                _CRAFTPLAYER_CLASS = Class.forName("org.bukkit.craftbukkit." + _VERSION + ".entity.CraftPlayer");
                Class<?> _ENTITYPLAYER_CLASS = Class.forName("net.minecraft.server." + _VERSION + ".EntityPlayer");
                Class<?> _PLAYER_CONNECTION_CLASS = Class.forName("net.minecraft.server." + _VERSION + ".PlayerConnection");
    
                _PACKET_PLAY_OUT_CHAT_CONSTRUCTOR = _PACKET_PLAY_OUT_CHAT_CLASS.getConstructor(_ICHAT_BASE_COMPONENT_CLASS);
    
                _A_METHOD = Class.forName("net.minecraft.server." + _VERSION + ".IChatBaseComponent$ChatSerializer")
                        .getMethod("a", String.class);
                _GETHANDLE_METHOD = _CRAFTPLAYER_CLASS.getMethod("getHandle");
                _SEND_PACKET_METHOD = _PLAYER_CONNECTION_CLASS.getMethod("sendPacket",
                        Class.forName("net.minecraft.server." + _VERSION + ".Packet"));
    
                _PLAYER_CONNECTION_FIELD = _ENTITYPLAYER_CLASS.getDeclaredField("playerConnection");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    
            _BLANK_HOVER_EVENT = new HoverEvent(null, "");
            _BLANK_CLICK_EVENT = new ClickEvent("", "");
            _JINX = new Jinx();
        }
    
        private Jinx() {
        }
    
        public static class JSONMessage {
    
            private List<MessagePart> _messageParts;
            private String _message;
    
            private boolean _compiled;
    
            {
                this._messageParts = new ArrayList<>();
                this._compiled = false;
            }
    
            public JSONMessage() {
                this._compiled = true;
            }
    
            public JSONMessage(String msg) {
                this._messageParts.add(_JINX.new MessagePart(msg));
            }
    
            public JSONMessage(String msg, HoverEvent hoverEvent) {
                this._messageParts.add(_JINX.new MessagePart(msg, hoverEvent));
            }
    
            public JSONMessage(String msg, ClickEvent clickEvent) {
                this._messageParts.add(_JINX.new MessagePart(msg, clickEvent));
            }
    
            public JSONMessage(String msg, HoverEvent hoverEvent, ClickEvent clickEvent) {
                this._messageParts.add(_JINX.new MessagePart(msg, hoverEvent, clickEvent));
            }
    
            public JSONMessage append(String msg) {
                this._messageParts.add(_JINX.new MessagePart(msg));
                this._compiled = false;
                return this;
            }
    
            public JSONMessage append(String msg, HoverEvent hoverEvent) {
                this._messageParts.add(_JINX.new MessagePart(msg, hoverEvent));
                this._compiled = false;
                return this;
            }
    
            public JSONMessage append(String msg, ClickEvent clickEvent) {
                this._messageParts.add(_JINX.new MessagePart(msg, clickEvent));
                this._compiled = false;
                return this;
            }
    
            public JSONMessage append(String msg, HoverEvent hoverEvent, ClickEvent clickEvent) {
                this._messageParts.add(_JINX.new MessagePart(msg, hoverEvent, clickEvent));
                this._compiled = false;
                return this;
            }
    
            @SuppressWarnings("deprecation")
            private String compile() {
                StringBuilder sb = new StringBuilder("[");
                boolean hadHoverEvent = false, hadClickEvent = false;
                for (MessagePart part : this._messageParts) {
                    sb.append(",{\"text\":\"" + part._msg + "\"");
                    HoverEvent hoverEvent = part._hoverEvent;
                    if (hoverEvent._type.equals(HoverEvent.SHOW_TEXT)) {
                        sb.append(",\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\""
                                + part._hoverEvent._value + "\"}}");
                        hadHoverEvent = true;
                    } else if (hoverEvent._type.equals(HoverEvent.SHOW_ACHIEVEMENT)) {
                        sb.append(",\"hoverEvent\":{\"action\":\"show_achievement\",\"value\":\"achievement."
                                + hoverEvent._value + "\"}}");
                        hadHoverEvent = true;
                    } else if (hoverEvent._type.equals(HoverEvent.SHOW_STATISTIC)) {
                        sb.append(",\"hoverEvent\":{\"action\":\"show_achievement\",\"value\":\"achievement."
                                + hoverEvent._value + "\"}}");
                        hadHoverEvent = true;
                    } else if (hoverEvent._type.equals(HoverEvent.SHOW_ITEM)) {
                        ItemStack item = ((ItemStack) part._hoverEvent._value).clone();
                        String name = item.hasItemMeta() ? item.getType().toString().toLowerCase()
                                : item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName()
                                        : item.getType().toString().toLowerCase();
                        sb.append(",\"hoverEvent\":{\"action\":\"show_item\",\"value\":\"{id:minecraft:"
                                + item.getType().toString().toLowerCase() + ",Count:" + item.getAmount() + "b");
    
                        if (item.hasItemMeta()) {
                            if ((item.getItemMeta().hasDisplayName())
                                    || ((item.getItemMeta().hasLore()) && (item.getItemMeta().getLore().size() > 0))) {
                                sb.append(",tag:{display:{");
                            }
    
                            if (item.getItemMeta().hasDisplayName()) {
                                sb.append("Name:" + name);
                            }
    
                            if ((item.getItemMeta().hasLore()) && (item.getItemMeta().getLore().size() > 0)) {
                                sb.append(",Lore:[");
                                boolean firstLore = true;
    
                                for (String lore : item.getItemMeta().getLore()) {
                                    if (!firstLore) {
                                        sb.append("," + lore);
                                    } else {
                                        sb.append(lore);
                                        firstLore = false;
                                    }
                                }
    
                                sb.append("]");
                            }
    
                            if ((item.getItemMeta().hasDisplayName())
                                    || ((item.getItemMeta().hasLore()) && (item.getItemMeta().getLore().size() > 0))) {
                                if (item.getEnchantments().size() > 0) {
                                    sb.append("},ench:[");
                                    boolean firstEnchant = true;
    
                                    for (Enchantment enchant : item.getEnchantments().keySet()) {
                                        if (!firstEnchant) {
                                            sb.append(",{id:" + enchant.getId() + ",lvl:"
                                                    + item.getEnchantments().get(enchant) + "}");
                                        } else {
                                            sb.append("{id:" + enchant.getId() + ",lvl:"
                                                    + item.getEnchantments().get(enchant) + "}");
                                            firstEnchant = false;
                                        }
                                    }
    
                                    sb.append("]}");
                                } else {
                                    sb.append("}}");
                                }
                            }
                        }
                        if ((item.getEnchantments().size() > 0) && (!sb.toString().contains("},ench:["))) {
                            sb.append(",tag:{ench:[");
                            boolean firstEnchant = true;
    
                            for (Enchantment enchant : item.getEnchantments().keySet()) {
                                if (!firstEnchant) {
                                    sb.append(",{id:" + enchant.getId() + ",lvl:" + item.getEnchantments().get(enchant)
                                            + "}");
                                } else {
                                    sb.append(
                                            "{id:" + enchant.getId() + ",lvl:" + item.getEnchantments().get(enchant) + "}");
                                    firstEnchant = false;
                                }
                            }
    
                            sb.append("]}");
                        }
                        sb.append("}\"}");
                        hadHoverEvent = true;
                    } else if (hoverEvent._type.equals(HoverEvent.SHOW_ENTITY)) {
                        Entity entity = (Entity) hoverEvent._value;
                        sb.append(",\"hoverEvent\":{\"action\":\"show_entity\",\"value\":\"{name:\""
                                + entity.getCustomName() + "\", type:\"" + entity.getName() + "\", id:\""
                                + entity.getUniqueId().toString() + "\"}}");
                        hadHoverEvent = true;
                    } else {
                        if (hadHoverEvent) {
                            sb.append(",\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\"}}");
                        }
                    }
                    if (!part._clickEvent._value.equals("")) {
                        sb.append(",\"clickEvent\":{\"action\":\"" + part._clickEvent._type + "\",\"value\":\""
                                + part._clickEvent._value + "\"}");
                        hadClickEvent = true;
                    } else {
                        if (hadClickEvent) {
                            sb.append(",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"\"}");
                        }
                    }
                    sb.append("}");
                }
                this._message = sb.toString().replaceFirst(",", "") + "]";
                this._compiled = true;
                return this._message;
            }
    
            public void sendMessage(Player player) {
                if (!this._compiled) {
                    compile();
                }
                try {
                    Object messageComponent = _A_METHOD.invoke(null, this._message);
                    Object packet = _PACKET_PLAY_OUT_CHAT_CONSTRUCTOR.newInstance(messageComponent);
                    Object craftPlayer = _CRAFTPLAYER_CLASS.cast(player);
                    Object entityPlayer = _GETHANDLE_METHOD.invoke(craftPlayer);
                    Object playerConnection = _PLAYER_CONNECTION_FIELD.get(entityPlayer);
                    _SEND_PACKET_METHOD.invoke(playerConnection, packet);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    
        private class MessagePart {
            private String _msg;
            private ClickEvent _clickEvent;
            private HoverEvent _hoverEvent;
    
            {
                this._hoverEvent = _BLANK_HOVER_EVENT;
                this._clickEvent = _BLANK_CLICK_EVENT;
            }
    
            public MessagePart(String msg) {
                this._msg = ChatColor.translateAlternateColorCodes('&', msg + "&r");
            }
    
            public MessagePart(String msg, Jinx.HoverEvent hoverEvent) {
                this._msg = ChatColor.translateAlternateColorCodes('&', msg + "&r");
                this._hoverEvent = hoverEvent;
            }
    
            public MessagePart(String msg, Jinx.ClickEvent clickEvent) {
                this._msg = ChatColor.translateAlternateColorCodes('&', msg + "&r");
                this._clickEvent = clickEvent;
            }
    
            public MessagePart(String msg, HoverEvent hoverEvent, ClickEvent clickEvent) {
                this._msg = ChatColor.translateAlternateColorCodes('&', msg + "&r");
                this._hoverEvent = hoverEvent;
                this._clickEvent = clickEvent;
            }
        }
    
        public static class HoverEvent {
    
            public static final String SHOW_TEXT, SHOW_ACHIEVEMENT, SHOW_STATISTIC, SHOW_ITEM, SHOW_ENTITY;
    
            static {
                SHOW_TEXT = "show_text";
                SHOW_ACHIEVEMENT = "show_achievement";
                SHOW_STATISTIC = "show_statistic";
                SHOW_ITEM = "show_item";
                SHOW_ENTITY = "show_entity";
            }
    
            private Object _value;
            private String _type;
    
            public HoverEvent(String value) {
                this._value = ChatColor.translateAlternateColorCodes('&', value + "&r");
                this._type = SHOW_TEXT;
            }
    
            public HoverEvent(Object value, String type) {
                if (value instanceof String) {
                    this._value = ChatColor.translateAlternateColorCodes('&', value + "&r");
                } else {
                    this._value = value;
                }
                this._type = type;
            }
        }
    
        public static class ClickEvent {
    
            public static final String OPEN_URL, RUN_COMMAND, SUGGEST_COMMAND;
    
            static {
                OPEN_URL = "open_url";
                RUN_COMMAND = "run_command";
                SUGGEST_COMMAND = "suggest_command";
            }
    
            private String _value;
            private String _type;
    
            public ClickEvent(String value, String type) {
                this._value = ChatColor.translateAlternateColorCodes('&', value + "&r");
                this._type = type;
            }
        }
    }
    


    This is an example code:

    Example (open)

    Code:
    JSONMessage message = new JSONMessage();
    message.append("This is hoverable", new HoverEvent("Hovered me"));
    message.append(" ");
    message.append("This is clickable", new ClickEvent("Test", ClickEvent.SUGGEST_COMMAND));
    message.append(" ");
    message.append("This is both", new HoverEvent(new ItemStack(Material.IRON_SWORD), HoverEvent.SHOW_ITEM),
            new ClickEvent("This is a sword!", ClickEvent.SUGGEST_COMMAND));
    
    for (Player player : Bukkit.getOnlinePlayers()) {
        message.sendMessage(player);
    }
    

    All hover events:
    Show Spoiler
    SHOW_TEXT, SHOW_ACHIEVEMENT, SHOW_STATISTIC, SHOW_ITEM, SHOW_ENTITY

    All click events:
    Show Spoiler
    OPEN_URL, RUN_COMMAND, SUGGEST_COMMAND

    Within the class Jinx:
    public static class JSONMessage = Used to create JSONMessages
    JSONMessage(String msg) = Starts it off with the plain message
    JSONMessage(String msg, HoverEvent hoverEvent) = Msg + HoverEvent
    JSONMessage(String msg, ClickEvent clickEvent) = Msg + ClickEvent
    JSONMessage(String msg, HoverEvent hoverEvent, ClickEvent clickEvent) = Msg + Events
    JSONMessage append(String msg) = Adds a plain message
    JSONMessage append(String msg, HoverEvent hoverEvent) = Msg + HoverEvent
    JSONMessage append(String msg, ClickEvent clickEvent) = Msg + ClickEvent
    JSONMessage append(String msg, HoverEvent hoverEvent, ClickEvent clickEvent) = Msg + Events
    private class MessagePart = Used to store the parts in JSONMesssage
    Its methods/constructors you don't really need to know
    public static class HoverEvent = Used to make hover events
    HoverEvent(String value) = A SHOW_TEXT hoverevent
    HoverEvent(Object value, String type) You input the appropriate type for the value inputted (SHOW_ITEM = ItemStack, ect.)​
    public static class ClickEvent = Used to make click events
    ClickEvent(String value, String type) = Makes a ClickEvent with the type
    public static final fields available incase you don't know for HoverEvent and ClickEvent. Color code compatibility with & symbols. Finally thanks to @xTechno_ again bc without them this thread wouldn't of happened
     
    Last edited: May 8, 2018
    Reflxction and Zombie_Striker like this.
  2. Offline

    Reflxction

    Dam, that's actually pretty cool, I always wondered how to make multiple events. Good job!
     
Thread Status:
Not open for further replies.

Share This Page