Signs - Editing, Getting, Using

Oct 18, 2017
Signs - Editing, Getting, Using
  • Editing, Getting, and Using Signs

    A tutorial on how to manipulate signs through a plugin.



    This is a simple tutorial teaching beginners how to work with, edit interact with signs :D. I’m not the best with organising these sorts of things, and if I miss anything feel free to reply, and I shall include it.


    The SignChangeEvent:

    This event is obviously called when a sign is changed. This event is cancellable. As is the case with most API related classes, the rest can be seen on the Spigot Developer Hub. Now, let's get into doing some simple color code applying. We will first start out with a simple event handler:

    Code (Java):
    @EventHandler
    public void onSignChange(SignChangeEvent e) {
        if (e.getPlayer().hasPermission("sign.color")) {
         
        }
    }
     
    The above code also includes a simple permission check, which would be useful for most main-stream server implementations! Next, we obviously know there are 4 lines on a sign, so we can update our handler the following:

    Code (Java):
    @EventHandler
    public void onSignChange(SignChangeEvent e) {
        if (e.getPlayer().hasPermission("sign.color")) {
            for (int i = 0; i < 4; i++) {
                String line = e.getLine(i);
                if (line != null && !line.equals("")) {
                    e.setLine(i, ChatColor.translateAlternateColorCodes('&', line));
                }
            }
        }
    }
     
    Now, let's break this down a notch (Pun intended?). We have the loop that runs 4 times, one for each of the 4 lines on the sign:

    Code (Java):
    for (int i = 0; i < 4; i++) {
    Then, the code gets the line and makes sure it is has content (is not a null reference or an empty String literal). We must do this because the player doesn’t have to type anything on every line.

    Code (Java):
    String line = e.getLine(i);
    if (line != null && !line.equals("")) {
    With the previous checks done, we can now modify the line from the Event Object. For this example, we will replace color codes beginning with '&' to true color codes:

    Code (Java):
    e.setLine(i, ChatColor.translateAlternateColorCodes('&', line));
    And that's it! That is the SignChangeEvent at its finest! We can use it for getting and setting lines, and don’t forget there is also a method that returns the string array of all the lines called
    Code (Java):
    getLines()
    .


    How to get a sign from a block

    So, in code, you can run:

    Code (Java):
    Block b = p.getLocation().getBlock();
    In your mind, you know it's a sign and that you just want to edit it. But you can’t… Well, I get you right now, but unfortunately a computer doesn’t think like us, so we have to tell it what to do. So, we start off by double checking that this block is for sure a sign.

    (This IF Statement checks to make sure that the Block's
    Code (Java):
    getType()
    returns a Material enum that means the block is a sign.)

    Code (Java):
    if (b.getType() == Material.WALL_SIGN || b.getType() == Material.SIGN_POST)
    due the a sign being able to go on a wall there are two material types that a sign can be, next we need to cast the block STATE to a sign

    Code (Java):
    Sign sign = (Sign)b.getState();
    WARNING!!! Make sure you import the Block object:

    import org.bukkit.block.Sign;

    NOT

    import org.bukkit.material.Sign; (the Material object)

    They are two totally different things, and when working with blocks you need to import the block. Now that we have the block, we can do many things, such as:

    Code (Java):
    sign.getLine(int line); // Get any line (line ranges from 0 to 3); returns String
    sign.setLine(int line, String text); // Set any line (Same range for line); returns void
    sign.getLines(); // Get all the lines; returns String[]
    Now, continuing on with this knowledge, we can design a PlayerInteractEvent to create the illusion of someone clicking a sign, so the following is all of the above into one:

    Code (Java):
    @EventHandler
    public void onSignClick(PlayerInteractEvent e) {

        if (e.getAction() != Action.RIGHT_CLICK_BLOCK) {
            return;
        }

        Player p = e.getPlayer();
        if (p.hasPermission("sign.use")) {
     
            Block b = e.getClickedBlock();
            if (b.getType() == Material.SIGN_POST || b.getType() == Material.WALL_SIGN) {
         
                Sign sign = (Sign) b.getState();
                if (ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase("[WARP]")) {

                    String warp = sign.getLine(2);
                    Bukkit.dispatchCommand(p, "warp " + warp);
             
                }
         
            }
     
        }

    }
     
    The only part of this that you don’t already know is

    Code (Java):

    if (ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase("[WARP]")) {

        String warp = sign.getLine(2);
        Bukkit.dispatchCommand(p, "warp " + warp);

    }
     
    Now, the if is stripping the color of line 0 (only from our String Object, not the actual block NBT) and checking if line 0 (first line) is [WARP]. If it is, then it's getting the warp location (which is on the third line) and then dispatching the command as the player, which also means that it will tell them if they don’t have permission to use that command.

    All of the above combined can produce some really neat sign warping, arena joining, or even fun little mini games. I hope this tutorial has taught the people that didn't know this already a bit more about signs. Feel free to leave a rating or comment and highlight everything that I did wrong in this mini tutorial xD i just hope that I have taught some people how signs can be used in Bukkit/Spigot.

    If you feel you can add more, or fix some of the mistakes that I have made in this mini tutorial, feel free to edit away! I would love for many people to help out to make this tutorial near perfect for anyone wanting to learn!

    (All messages at the end have been agreed upon by all Editors of this page. PLEASE DO NOT DELETE THIS LINE)
  • Loading...
  • Loading...