Using virtual Anvil GUI doesn't work properly

Discussion in 'Spigot Plugin Development' started by Gadse, Jul 19, 2015.

  1. Hello!

    I'm currently trying to write a plugin (for CraftBukkit), that is able to open multiple inventory types.

    So far it works pretty good, but now I need to add an Anvil. The problem is not, to open the GUI itself.
    Code (Text):
    Inventory i = Bukkit.createInventory(p, InventoryType.ANVIL);
                p.openInventory(i);
    The GUI opens normally and ingame there doesn't seem to be an problem. I can put Items in, rename them, etc. But if you relog or something else, everything is still normal. No rename/repair costs have been charged actually, the item still has its old durability and its old name, etc.

    In the console, I get the following error, after putting an item into the first slot:
    Code (Text):
    [19:50:42 FATAL]: Error executing task
    java.util.concurrent.ExecutionException: java.lang.IndexOutOfBoundsException: In
    dex: 13, Size: 0
            at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_51]
            at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_51]
            at net.minecraft.server.v1_8_R3.SystemUtils.a(SystemUtils.java:20) [Craf
    tBukkit.jar:git-Bukkit-994b2aa]
            at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:6
    76) [CraftBukkit.jar:git-Bukkit-994b2aa]
            at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:3
    35) [CraftBukkit.jar:git-Bukkit-994b2aa]
            at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:6
    32) [CraftBukkit.jar:git-Bukkit-994b2aa]
            at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java
    :540) [CraftBukkit.jar:git-Bukkit-994b2aa]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_51]
    Caused by: java.lang.IndexOutOfBoundsException: Index: 13, Size: 0
            at java.util.ArrayList.rangeCheck(Unknown Source) ~[?:1.8.0_51]
            at java.util.ArrayList.get(Unknown Source) ~[?:1.8.0_51]
            at net.minecraft.server.v1_8_R3.Container.getSlot(Container.java:107) ~[
    CraftBukkit.jar:git-Bukkit-994b2aa]
            at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java
    :1420) ~[CraftBukkit.jar:git-Bukkit-994b2aa]
            at net.minecraft.server.v1_8_R3.PacketPlayInWindowClick.a(SourceFile:31)
    ~[CraftBukkit.jar:git-Bukkit-994b2aa]
            at net.minecraft.server.v1_8_R3.PacketPlayInWindowClick.a(SourceFile:9)
    ~[CraftBukkit.jar:git-Bukkit-994b2aa]
            at net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(SourceFile:1
    3) ~[CraftBukkit.jar:git-Bukkit-994b2aa]
            at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~
    [?:1.8.0_51]
            at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_51]
            at net.minecraft.server.v1_8_R3.SystemUtils.a(SystemUtils.java:19) ~[Cra
    ftBukkit.jar:git-Bukkit-994b2aa]
            ... 5 more
    It seems that I get the same error everytime I try to do something with the anvil. (Taking the item out, renaming it, etc.)

    I seriously don't know what I'm doing wrong.. I tried to use alternative methods, but they all seemed to be pretty outdated, so I'm sorry if this is a duplicate of something...

    Sincerely,
    GummiBoat
     
  2. Use Google :)
     
    • Funny Funny x 2
    • Informative Informative x 1
  3. That's what I did for round a bout an hour and also the reason why I wrote
     
  4. There should be an uphelpful vote...
     
    • Funny Funny x 2
    • Like Like x 1
    • Agree Agree x 1
    • Winner Winner x 1
  5. I just search on Google Create Anvil Inventory Bukkit and it appears:

    Code (Text):
    public static void openAnvil(Player player) {
        EntityPlayer p = ((CraftPlayer) player).getHandle();
        AnvilContainer container = new AnvilContainer(p);
        int c = p.nextContainerCounter();
        p.playerConnection.sendPacket(new Packet100OpenWindow(c, 8, "Repairing", 9));
        p.activeContainer = container;
        p.activeContainer.windowId = c;
        p.activeContainer.addSlotListener(p);
    }
    public class AnvilContainer extends ContainerAnvil {
        public AnvilContainer(EntityHuman entity) {
            super(entity.inventory, entity.world, 0, 0, 0, entity);
        }
        @Override
        public boolean a(EntityHuman entityhuman) {
            return true;
        }
    }
    And it works :)
     
  6. Well, but it doesn't for me.

    My Imports
    [​IMG]
    and the error
    [​IMG]

    I already found your answer a million times, but i always had the error ^ above.
    It's not telling me, what i need to import or what i could fix either.
     
  7. Replace the line 492 with
    Code (Text):
    p.playerConnection.sendPacket(new PacketPlayOutOpenWindow(c,"minecraft:anvil",new ChatMessage("Repairing",new Object[]{}),0));
    And replace the line 499 with
    Code (Text):
    super(entity.inventory, entity.world, new BlockPosition(0, 0, 0), entity);

    Should work :)
     
  8. Okay, I additionally imported
    Code (Text):
    import org.bukkit.craftbukkit.v1_8_R1.entity.CraftPlayer;
    and now this is left. Excuse me, but I have zero experience with using additional classes. (I assume that is what he wants here from me.)
    [​IMG]
     
  9. Oh god does anyone know how to read stack traces these days -.-

    Code (Text):
    Caused by: java.lang.IndexOutOfBoundsException: Index: 13, Size: 0
            at java.util.ArrayList.rangeCheck(Unknown Source) ~[?:1.8.0_51]
            at java.util.ArrayList.get(Unknown Source) ~[?:1.8.0_51]
            at net.minecraft.server.v1_8_R3.Container.getSlot(Container.java:107) ~[
    CraftBukkit.jar:git-Bukkit-994b2aa]
    Your error is that you are trying ti get a slot in the inventory that doesnt actually exist, aka out of bounds you are accessing something that is out of bounds... please post any code that uses the anvil inventory so we can find this error of yours

    If the errir is still there this answer shoudl help
     
    • Agree Agree x 1
  10. That's why I'm here, because I certainly don't know everything about java, and I admit it openly.
    Well, if you just want the code that accesses the Anvil Inventory itself, the old one (without the complex code from Xelfe) looks like this:
    Code (Text):

    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args)
      {
        if (((sender instanceof Player)) && (
          (cmd.getName().equalsIgnoreCase("pb")) || (cmd.getName().equalsIgnoreCase("packbude"))))
        {
          Player p = (Player)sender;
          if (args.length == 0)
          {
            if (p.hasPermission("pb.gui")) {
                Inventory i = Bukkit.createInventory(p, InventoryType.ANVIL);
                p.openInventory(i);
                //openGUI(p);
            } else {
              p.sendMessage(this.noPerm);
            }
          }
          else if (args.length > 0) {
            p.sendMessage(this.invName + "§6>§7 Bitte benutze nur \"§a/pb§7\". §oPackBude v1.2 by GummiBoat");
          }
        }
        return true;
      }
     
    The new one is similar,
    Code (Text):

    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args)
      {
        if (((sender instanceof Player)) && (
          (cmd.getName().equalsIgnoreCase("pb")) || (cmd.getName().equalsIgnoreCase("packbude"))))
        {
          Player p = (Player)sender;
          if (args.length == 0)
          {
            if (p.hasPermission("pb.gui")) {
                PackBude.openAnvil(p);
                //openGUI(p);
            } else {
              p.sendMessage(this.noPerm);
            }
          }
          else if (args.length > 0) {
            p.sendMessage(this.invName + "§6>§7 Bitte benutze nur \"§a/pb§7\". §oPackBude v1.2 by GummiBoat");
          }
        }
        return true;
      }
    //"some" lines of unimportant code here
    public static void openAnvil(Player player) {
           EntityPlayer p = ((CraftPlayer) player).getHandle();
           AnvilContainer container = new AnvilContainer(p);
           int c = p.nextContainerCounter();
           p.playerConnection.sendPacket(new PacketPlayOutOpenWindow(c,"minecraft:anvil",new ChatMessage("Repairing",new Object[]{}),0));
           p.activeContainer = container;
           p.activeContainer.windowId = c;
           p.activeContainer.addSlotListener(p);
        }

    public class AnvilContainer extends ContainerAnvil {
        public AnvilContainer(EntityHuman entity) {
            super(entity.inventory, entity.world, new BlockPosition(0, 0, 0), entity);
        }
        @Override
        public boolean a(EntityHuman entityhuman) {
            return true;
        }
    }

     
    That's just for testing tho, the final product opens, if I click an anvil in the clickGUI. I just placed it there to make things faster. Btw, I tried to place it inside the ClickGUI, results in the same thing.
     
    #10 Gadse, Jul 20, 2015
    Last edited: Jul 20, 2015
  11. I'm sorry, I know this is a bit out of context, but what software is this? Looks amazing compared to the Eclipse, which is super dull xD Thank you so much!
     
  12. This is regular Eclipse with a Color Theme. Changeable under Window -> Preferences -> General Appearance -> Color Theme, you can install custom Color Themes too tho. For more information, look here.
     
    • Friendly Friendly x 2
    • Useful Useful x 1
  13. You're lovely <3 Thank you so much!
     
    • Friendly Friendly x 1
  14. /Can be closed, I used an alternative API which I can somehow work with. Thanks for the support tho.
     
  15. I were in the same situation like you, and what I did was creating a hashmap for each enum stage where the player was in. Because maybe this works out now, but when you have a shop with more then 15+ inventories things get pretty messed up.
     
  16. Thank you so much! mine didn't worked, but your solution make it work! Thanks!
     
  17. lol