Search code examples
minecraftbukkit

How to make a clickable link that executes a command with bukkit


I'm trying to make a bukkit plugin and I can't seem to find any documentation on this but I've seen it done, How would I input commands into a chat message that a user could click on to execute a command on the server like "/motd" in the form of a clickable link like a URL

if (commandLabel.equalsIgnoreCase("cmd") {
    player.sendMessage("Pick a command: " + </motd> + ", " + </mail> );
}

replacing "" and "" to output something like this:

Pick a command: MOTD, Mail

and clicking them would execute the command to the server as them. How would I do this?


Solution

  • You could do it like this:

    IChatBaseComponent comp = ChatSerializer
                .a("{\"text\":\"" + "Choose one: " + "\",\"extra\":[{\"text\":\"" + "MOTD" + "\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"" + "/motd" + "\"}}]}");
        
    PacketPlayOutChat packet = new PacketPlayOutChat(comp, true);
    ((CraftPlayer) <player>).getHandle().playerConnection.sendPacket(packet);
    

    This would send them a message showing:

    Choose one: MOTD
    

    and when the user clicked MOTD, it would run the command /motd as the player. Here's a little breakdown of what we're actually doing:

        IChatBaseComponent comp = ChatSerializer
                .a("{\"text\":\"" + "<Ignored Message> " + 
                "\",\"extra\":[{\"text\":\"" + "<Message that will be clicked>" + 
                "\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"" + 
                "<Command to be run when message is clicked>" + "\"}}]}");
        
    PacketPlayOutChat packet = new PacketPlayOutChat(comp, true);
    ((CraftPlayer) <player>).getHandle().playerConnection.sendPacket(packet);
    

    The above code will send the player:

    <Ignored Message> <Message that will be clicked>
    

    and when the player clicks <Message that will be clicked>

    they will run the command <Command to be run when a message is clicked>, and because it does not start with the command prefix, /, it will force them to chat <Command to be run when a message is clicked>.

    Unfortunately, as far as I know, you can only put one click event per message, so you would have to do something like this:

    Choose one:

    MOTD
    Mail

    So you would have to do, where the variable player is the player:

    player.sendMessage("Choose one:");
    
    IChatBaseComponent comp = ChatSerializer
                .a("{\"text\":\"" + 
                "\",\"extra\":[{\"text\":\"" + "MOTD" + 
                "\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"" + 
                "/motd" + "\"}}]}");    
    PacketPlayOutChat packet = new PacketPlayOutChat(comp, true);
    ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
    
    IChatBaseComponent comp2 = ChatSerializer
                .a("{\"text\":\"" + 
                "\",\"extra\":[{\"text\":\"" + "Mail" + 
                "\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"" + 
                "/mail" + "\"}}]}");    
    PacketPlayOutChat packet2 = new PacketPlayOutChat(comp2, true);
    ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet2);
    

    When MOTD is clicked, /motd will be run by the player, and when Mail is clicked, /mail will be run.

    Just as a side note, you will need to include craftbukkit in your build path, along with bukkit to do this