Solved NMS Enchantment Table Inventory

Discussion in 'Spigot Plugin Development' started by ItsSchatten, Jun 19, 2021.

Thread Status:
Not open for further replies.
  1. Greetings,

    I've been attempting to get an Enchantment table to work with NMS in 1.17 and have been unsuccessful in my endeavors.

    I'm able to open the inventory but upon attempting to enchant something (putting an item or book into the slot and having lapis in it's slot) I don't see any enchantments show up, the PrepareItemEnchantEvent does not seem to trigger. I am able to get enchants to show with the InventoryClickEvent but when using the event to set the enchantments for the NMS version I'm unable to actually click on an enchant to apply it.

    This is my code for opening the NMS table if needed:
    Code (Java):
                final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
                final EnchantmentMenu menu = new EnchantmentMenu(serverPlayer.nextContainerCounter(), serverPlayer.getInventory());
                menu.checkReachable = false;
                menu.setTitle(new TextComponent("WOO!"));
                serverPlayer.containerMenu = menu;
                serverPlayer.initMenu(menu); // This registers the slot listener and the container synchronizer.
    I've also attempted to get a working enchant table with the API I am capable of getting the menu to open I'm not entirely sure where I would go from here, when clicking items into this inventory the PrepareItemEnchantEvent also doesn't seem to be triggered.

    This thread is more asking if anyone has been successful in obtaining a usable version of the enchantment table, NMS or API, in 1.17, if so any help with what I'm doing wrong would be appreciated.
  2. Sorry to ask but is ServerPlayer a new class in 1.17? I haven't seen it yet. But again i only used 1.8 NMS so far.
    Why do you even want to use NMS for this? Is the API not working yet? The version is very new so maybe its just buggy in both regards.
  3. I think this has to do that the vanilla EnchantmentMenu checks the location of the enchantment table in the world and checks how many book cases there are around in order to determine the available enchantment levels. You need to somehow spoof that.
  4. ServerPlayer is basically the 1.17 equivalent to EntityPlayer. NMS was the only effective way I was able to create a workable enchantment table in previous versions.

    Interesting, I'll see if I can figure this out.
  5. Update:

    I've solved this issue, new code:
    Code (Java):
    // How I call to open the inventory.
                final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
                int containerCounter = serverPlayer.nextContainerCounter();
                FakeEnchant enchant = new FakeEnchant(containerCounter, player);
                serverPlayer.containerMenu = serverPlayer.inventoryMenu;
                serverPlayer.connection.send(new ClientboundOpenScreenPacket(containerCounter, MenuType.ENCHANTMENT, new TextComponent("ENCHANT CUSTOM")));
                serverPlayer.containerMenu = enchant;

    // The fake container class.
    static class FakeEnchant extends EnchantmentMenu {

            public FakeEnchant(int i, Player player) {
                super(i, ((CraftPlayer) player).getHandle().getInventory(),
                        ContainerLevelAccess.create(((CraftPlayer) player).getHandle().level, new BlockPos(player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ())));
                this.checkReachable = false;
                setTitle(new TextComponent("Enchant Menu CUSTOM"));
    Perhaps I just needed sleep and some away time from the code to figure this out.
    • Like Like x 1
Thread Status:
Not open for further replies.