Making sounds/materials work both in 1.12 and 1.13

Discussion in 'Plugin Development' started by Kevinzuman22, Dec 15, 2018.

Thread Status:
Not open for further replies.
  1. I've got a plugin that's using the sounds from Noteblocks. Now I'd like to update my plugin to 1.13, but the problem is, is that the naming for the Noteblock sounds have changed from BLOCK_NOTE_ to BLOCK_NOTE_BLOCK.

    Another thing is that the MONSTER_EGG also changed names to LEGACY_MONSTER_EGG (also defined by each different type of monster egg, although I do not know if I actually have to use each seperate one, and that LEGACY_MONSTER_EGG does not work)

    I attempted to have an enumerator incorporate both version's Sounds, but unfortunately, that does not work (or at least, not the way I'm trying).

    This is the code of the enumerator I tried using
    Code (open)

    Code:
    package me.greenadine.advancedspawners;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.Sound;
    
    public enum SoundHandler {
    
        UPGRADE_SPAWNER(Sound.ENTITY_PLAYER_LEVELUP, Sound.ENTITY_PLAYER_LEVELUP),
        OPTION_ENABLE(Sound.BLOCK_NOTE_HARP, Sound.BLOCK_NOTE_BLOCK_HARP),
        OPTION_DISABLE(Sound.BLOCK_NOTE_BASS, Sound.BLOCK_NOTE_BLOCK_BASS),
        MENU_BACK(Sound.BLOCK_NOTE_HAT, Sound.BLOCK_NOTE_BLOCK_HAT),
        MENU_EXIT(Sound.BLOCK_NOTE_BASEDRUM, Sound.BLOCK_NOTE_BLOCK_BASEDRUM);
      
      
        private Sound v1_12;
        private Sound v1_13;
      
        SoundHandler(Sound v1_12, Sound v1_13) {
            this.v1_12 = v1_12;
            this.v1_13 = v1_13;
        }
      
        public void playSound(Location l) {
            if(Bukkit.getVersion().contains("1.13")) {
                l.getWorld().playSound(l, v1_13, 0.3F, 0F);
            } else {
                l.getWorld().playSound(l, v1_12, 0.3F, 0F);
            }
        }
      
        public Sound getSound() {
            if(Bukkit.getVersion().contains("1.13")) {
                return v1_13;
            } else {
                return v1_12;
            }
        }
      
    }
    

    In my project setup, I've added both Spigot version 1.12.2 and 1.13.2 as libraries, either of the two will always give errors.

    Does anyone have some experience in doing stuff like this?
     
  2. Offline

    Zombie_Striker

    @Kevinzuman22
    First, the way you currently have your code makes it so you would have to release a new update for every mc-update. Instead, try using this method to check whether the ID is above 1.12:
    Code:
    
        private static final String SERVER_VERSION;
        static {
            String name = Bukkit.getServer().getClass().getName();
            name = name.substring(name.indexOf("craftbukkit.") + "craftbukkit.".length());
            name = name.substring(0, name.indexOf("."));
            SERVER_VERSION = name;
        }
    
        public static boolean isVersionHigherThan(int mainVersion, int secondVersion) {
            String firstChar = SERVER_VERSION.substring(1, 2);
            int fInt = Integer.parseInt(firstChar);
            if (fInt < mainVersion)
                return false;
            StringBuilder secondChar = new StringBuilder();
            for (int i = 3; i < 10; i++) {
                if (SERVER_VERSION.charAt(i) == '_' || SERVER_VERSION.charAt(i) == '.')
                    break;
                secondChar.append(SERVER_VERSION.charAt(i));
            }
    
            int sInt = Integer.parseInt(secondChar.toString());
            if (sInt <= secondVersion)
                return false;
            return true;
        }
    So you would use this to check if the 1.13 sound names should be used:
    Code:
    isVersionHigherThan(1,12)
    As for the sound names, you can use Sound.valueOf() to get the sound by their name.
     
  3. @Zombie_Striker
    Thanks. This works perfectly!

    I do still have two things: doing the same with WOOL and MONSTER_EGG. In 1.13, all wool types have their own defined Material value, as well as all the monster eggs. In 1.12, I would define any type of wool with this:
    Code:
    wool = new ItemStack(Material.WOOL, 1, DyeColor.LIME.getWoolData());
    but of course, that wouldn't work with 1.13, since that would have to be:
    Code:
    wool = new ItemStack(Material.LIME_WOOL, 1);
    Using an enumerator as I'm using right now would still be possible, I think. It would just be incredibly annoying to code. Is there a good solution to this?

    How I currently have the enumerator set up (the method you gave me is in my Main class):
    SoundHandler.java (open)

    Code:
    package me.greenadine.advancedspawners;
    
    import org.bukkit.Location;
    import org.bukkit.Sound;
    
    public enum SoundHandler {
    
        UPGRADE_SPAWNER("ENTITY_PLAYER_LEVELUP", "ENTITY_PLAYER_LEVELUP"),
        OPTION_ENABLE("BLOCK_NOTE_HARP", "BLOCK_NOTE_BLOCK_HARP"),
        OPTION_DISABLE("BLOCK_NOTE_BASS", "BLOCK_NOTE_BLOCK_BASS"),
        MENU_BACK("BLOCK_NOTE_HAT", "BLOCK_NOTE_BLOCK_HAT"),
        MENU_EXIT("BLOCK_NOTE_BASEDRUM", "BLOCK_NOTE_BLOCK_BASEDRUM");
      
      
        private String v1_12;
        private String v1_13;
      
        SoundHandler(String v1_12, String v1_13) {
            this.v1_12 = v1_12;
            this.v1_13 = v1_13;
        }
      
        public void playSound(Location l) {
            if(Main.isVersionHigherThan(1,12)) {
                l.getWorld().playSound(l, Sound.valueOf(v1_13), 0.3F, 0F);
            } else {
                l.getWorld().playSound(l, Sound.valueOf(v1_12), 0.3F, 0F);
            }
        }
      
        public Sound getSound() {
            if(Main.isVersionHigherThan(1,12)) {
                return Sound.valueOf(v1_13);
            } else {
                return Sound.valueOf(v1_12);
            }
        }
      
    }
    
     
  4. Offline

    Zombie_Striker

    @Kevinzuman22
    Well, for that, it would be mostly the same for the materials. Now normally, I would recommend just remembering or looking up the number ids for each of the colors and use the raw numbers, as it most likely won't come up that much in your code. However, if you need to be able to get the dye color by a String, I'd recommend you create a lookup table that links the color name (as a String) to the number. The easiest way of doing this would be to create a HashMap<String,Integer> and add all of the values somewhere like the onEnable.
     
  5. @Zombie_Striker
    I've thaught of my own solution (probably not the most efficient, but it works) (please do tell me if I should use a different method instead):
    I've created an abstract class Items class, which is being used by Items1_12 class and Items1_13 class. Then the ItemsHandler class picks which of the 2 to use, and then I use the ItemHandler.java to call up the items.

    This all works fine on a 1.12.2 server, but on a 1.13.2 server is where problems start to pop up:
    • On the first run on a 1.13.2 server, startup went fine without any errors. But on every subsequent attempt of starting up the server, this error appears. An attempt to use
      Code:
      Material.valueOf("SPAWNER")
      instead of
      Code:
      Material.SPAWER
      ends up with an error that tells me that the enum constant 'LEGACY_SPAWNER' doesn't exist. The reason for this is beyond me.
    • I've tested what the BlockPlaceEvent and BlockBreakEvent say what the Material of the block is when I try to place/break a Spawner. I'm printing it out with
      Code:
      main.getLogger().info(block.getType().toString());
      but it shows 'AIR'. I have absolutely no clue as to why this is happening as well.
     
    Last edited: Dec 17, 2018
  6. Offline

    Zombie_Striker

    @Kevinzuman22
    1. The reason you are getting that first error is because you did not include the "api-version: 1.13" tag in the plugin.yml, which is required to access any of the 1.13 material names.
    2. The reason it is showing air is most likely because you are getting the "block" instance of the location before the block is placed, or after the block is broken. Could you post the rest of the code?
     
Thread Status:
Not open for further replies.

Share This Page