ItemStack in Nms

Discussion in 'Spigot Discussion' started by AngyGam3r89, Apr 21, 2021.

  1. hello, first of all sorry for the english, i have a problem. I want to use the nms method to make the plugin accessible to all versions, but in the code of my gui when I import the libraries of other versions it gives me an error in itemstack, how can I fix it? This is the code...
    Code (Text):
    import java.util.ArrayList;
    import java.util.List;

    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemFlag;
    import org.bukkit.inventory.meta.ItemMeta;

    import com.angy.controlguiplus.Manager.Config.ConfigManager;
    import com.angy.controlguiplus.Manager.Messages.En.MessageManagerEn;
    import com.angy.controlguiplus.Manager.Messages.En.MessagesConfigEn;
    import com.angy.controlguiplus.Manager.Messages.It.MessageManagerIt;
    import com.angy.controlguiplus.Manager.Messages.It.MessagesConfigIt;

    import net.minecraft.server.v1_13_R1.Enchantment;
    import net.minecraft.server.v1_13_R1.ItemStack;
    import net.minecraft.server.v1_13_R1.Material;

    public class GuiControl {

        private int size = ConfigManager.getInstance().getInt("Gui-Settings.Size");
        private String paperboolean = ConfigManager.getInstance().get("Gui-Settings.EnableEnchant.Paper");
        private String glassboolean = ConfigManager.getInstance().get("Gui-Settings.EnableEnchant.Glass");

        public void gui(Player p) {
            if (size != 27 && size != 36 && size != 45 && size != 54) {
                System.out.println("Size " + size + " is not available for gui");
                p.sendMessage("§cError in Config, please see console");
                return;
            }
            if (ConfigManager.getInstance().get("lang").equals("en")) {
                Inventory gui = Bukkit.createInventory(null, size, MessagesConfigEn.onGuiName());

                if (gui.getSize() != 27 && gui.getSize() != 36 && gui.getSize() != 45 && gui.getSize() != 54) {
                    System.out.println("Size " + size + " is not available for gui");
                    p.sendMessage("§cError in Config, please see console");
                    return;
                } else {
                    for (int i = 0; i < gui.getContents().length; i++) {
                        ItemStack is = gui.getItem(i);
                        ItemStack glass = new ItemStack(Material.STAINED_GLASS_PANE, 1,
                                (short) ConfigManager.getInstance().getInt("Gui-Settings.Glass-Id"));
                        ItemMeta glassmeta = glass.getItemMeta();
                        if (Boolean.parseBoolean(glassboolean)) {
                            glassmeta.addEnchant(Enchantment.ARROW_KNOCKBACK, 3, true);
                            glassmeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
                        }
                        glass.setItemMeta(glassmeta);
                        if (is == null || is.getType() == Material.AIR)
                            gui.setItem(i, glass);
                        // Control ItemStack
                        ItemStack Control = new ItemStack(Material.PAPER);
                        ItemMeta ControlMeta = Control.getItemMeta();
                        if (ConfigManager.getInstance().get("lang").equals("en")) {
                            ControlMeta.setDisplayName(MessagesConfigEn.onControlName());
                        } else if (ConfigManager.getInstance().get("lang").equals("it")) {
                            ControlMeta.setDisplayName(MessagesConfigIt.onControlName());
                        }
                        if (Boolean.parseBoolean(paperboolean)) {
                            ControlMeta.addEnchant(Enchantment.ARROW_DAMAGE, 1, true);
                            ControlMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
                        }
                        List<String> controllore = new ArrayList<String>();
                        if (ConfigManager.getInstance().get("lang").equals("en")) {
                            for (String string : MessageManagerEn.getInstance()
                                    .getStringList("Gui-Settings.Contens.Control.Lore")) {
                                controllore.add(ChatColor.translateAlternateColorCodes('&', string));
                                ControlMeta.setLore(controllore);
                                Control.setItemMeta(ControlMeta);
                            }
                        } else if (ConfigManager.getInstance().get("lang").equals("it")) {
                            for (String string : MessageManagerIt.getInstance()
                                    .getStringList("Gui-Settings.Contens.Control.Lore")) {
                                controllore.add(ChatColor.translateAlternateColorCodes('&', string));
                                ControlMeta.setLore(controllore);
                                Control.setItemMeta(ControlMeta);
                            }
                        }
     

    Attached Files:

  2. You brought the wrong import.
     
  3. And what should I import? Because if I import org.bukkit.Material it gives me the materials of the first buidpath, that is 1.8 and not 1.13
    upload_2021-4-21_17-1-27.png
     
  4. I don't think you really understand Java all that well.
    ItemStack in NMS is very VERY different from ItemStack in Bukkit.
    You are using the NMS ItemStack import, but treating it as a Bukkit ItemStack (using Bukkit's methods)
     
  5. It's not that I'm not good at java, it's that I don't know how to use the nms method well to convert it from bukkit to nms ....
    upload_2021-4-21_17-11-1.png
     
  6. can someone help me?
     
  7. 1) you should really explain why you need NMS itemstack if you want help. Your issue is very XY problem, and its hard to help you if we don't know what your goal is.

    2) Theres a static OBC method, something like CraftItemStack.asNMSCopy(ItemStack item). This will take a Bukkit ItemStack and covert it to an NMS ItemStack.
     
  8. I don't need to convert an itemstack but to get a material from version 1.13+ because as main buildpath I am using 1.8
     
  9. wtf... this whole thread is titled ItemStack NMS, talking about getting an ItemStack from Bukkit to NMS

    (here you are telling me you are literally trying to convert an ItemStack from Bukkit to NMS)

    NOW you're telling me this is nothing to do with ItemStacks?!?!?

    Seriously, if you need help, rather than spending 10+ days and 10+ replies trying to figure out your XY problem, how about you actually state what you are trying to do.

    Also:
    Bukkit Materials do not directly correlate to NMS (Minecraft) Types. Minecraft does not have a class for all materials, It has an Items class and a Blocks class which have static fields for each Item/Block.
     
    • Winner Winner x 1
  10. first of all stay calm, if you don't want to help me don't do it, if you want can you guide me on how the materials of the other versions in nms work?
     
    • Optimistic Optimistic x 1
  11. You don't need NMS for this. In fact, using NMS might make this harder rather than simpler.

    What you want is to use a resource like XMaterial. If you want to do it yourself because the resource is a bit big for your use-case, the basic idea is to use Material.valueOf("NAME");. Depending on the version (You can easily detect it through Bukkit#getBukkitVersion, which will return something like 1.16.5-R0.1-SNAPSHOT), you get a different String to input in that method. Other than that, there's not much work that you have to do. The creation of ItemStack as well as setting most ItemMeta properties stayed the same across all versions.
     
  12. Can you do an example?
     
  13. Sure, for the sake of the example, let's open an inventory containing a crafting table.

    First, we need to get the version the server is on. There are many, many ways to achieve this. Here's the one I used:
    Code (Java):
    public final class Example extends JavaPlugin {
     
        // Pattern matches the major number in the version format #getBukkitVersion returns.
        // This is in the main class, because there's really no reason to do it more than once.
        private final Pattern majorVersionPattern = Pattern.compile("\\.([\\d]+)\\.");
        private int majorVersion = -1;

        @Override
        public void onEnable() {
            // Register a command to open the GUI in the example.
            getCommand("example").setExecutor(new ExampleCommand(this));
     
            // Apply the pattern against the provided server version.
            Matcher matcher = majorVersionPattern.matcher(getServer().getBukkitVersion());
            // This check is a formality. We know for sure that the matcher will find something.
            if (matcher.find())
                majorVersion = Integer.parseInt(matcher.group(1));
        }

        // You can have more utility methods than this, but the difference between 1.12 and 1.13 is the biggest one, so I included it as default.
        public boolean isPreFlattening() {
            return majorVersion < 13;
        }
    }
    Now that we have that out of the way, we can do the actual "magic":
    Code (Java):
    public class ExampleCommand implements CommandExecutor {

        private final Example plugin;

        public ExampleCommand(Example plugin) {
            this.plugin = plugin;
        }

        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            // Create an inventory.
            Inventory inventory = plugin.getServer().createInventory(null, 9, "Title");
            // Set the item.
            inventory.setItem(0, new ItemStack(
                    Material.valueOf(
                            // This is all the "magic". Get a different material string based on the version, and you're done.
                            plugin.isPreFlattening() ? "WORKBENCH" : "CRAFTING_TABLE"
                    ))
            );
            // Open it. Obviously, in a real case scenario, there's an instanceof check, etc., but not what this example is supposed to cover.
            ((Player) sender).openInventory(inventory);

            return true;
        }
    }
    Of course, with some ItemStacks, such as glass panes, you might have to implement a bit more logic than that, for example:
    Code (Java):
    public ItemStack getBlackStainedGlassPane() {
        if (plugin.isPreFlattening())
            return new ItemStack(Material.valueOf("STAINED_GLASS_PANE"), 1, (byte) 15);
        else
            return new ItemStack(Material.valueOf("BLACK_STAINED_GLASS_PANE"));
    }
    But there are many ways to apply this concept and the one above is just one of them. Good luck :)

    // EDIT:
    One key thing I forgot to mention: You have to supply api-version: 1.13 in your plugin.yml. Otherwise, the server will give you legacy materials. The API version doesn't affect servers below 1.13, so doing this is perfectly fine.
     
    #13 Gadse, May 5, 2021
    Last edited: May 5, 2021
    • Agree Agree x 1
  14.