Solved [1.8] Player#openInventory() is not functioning

Discussion in 'Plugin Development' started by JRL1004, Mar 16, 2016.

Thread Status:
Not open for further replies.
  1. Offline

    JRL1004

    PRENOTE: This is a thread I am putting here because the Spigot Forums are not being very helpful. I feel as if that should not be an issue, since I am using a CraftBukkit 1.8 jar for my buildpath instead of a Spigot one.

    I am trying to make custom inventories the way I normally do (an abstract parent class with smaller classes extending it that each handle their own click events), and I am having issues with getting the inventories to open. I previously had the main inventory working, but now it will not open. The only change I have made was adding a few more inventory classes extending the parent class
    Here is the class when I call player.openInventory():
    Listener Class (open)

    Code:
    import java.util.ArrayList;
    import java.util.Arrays;
    
    import org.bukkit.ChatColor;
    import org.bukkit.block.Sign;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.player.PlayerInteractEvent;
    
    import com.Jacobb6816.testingProject.core.AbstractModularInventory;
    import com.Jacobb6816.testingProject.core.inventories.InventoryParticleMain;
    import com.Jacobb6816.testingProject.core.inventories.InventoryTestingMain;
    
    public class GeneralEventHandler implements Listener {
    
        private ArrayList<AbstractModularInventory>    inventoryList;
    
        public GeneralEventHandler() {
            inventoryList = new ArrayList<AbstractModularInventory>(Arrays.asList(new InventoryTestingMain(), new InventoryParticleMain()));
        }
    
        @EventHandler
        public void onInteractSign(PlayerInteractEvent event) {
            if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
            if (!(event.getClickedBlock().getState() instanceof Sign)) return;
            Sign sign = (Sign) event.getClickedBlock().getState();
            String[] signText = sign.getLines();
            if (!signText[0].equalsIgnoreCase("[TestPlugin]") || signText[1].length() == 0) return;
            Player player = event.getPlayer();
            player.sendMessage(ChatColor.AQUA + "Looking for inventory: " + signText[1]);
            AbstractModularInventory ami = findInventoryByname(signText[1]);
            if (ami != null) {
                player.sendMessage(ChatColor.GREEN + "Located inventory: " + signText[1]);
                player.openInventory(ami.getInventory());
                return;
            }
            player.sendMessage(ChatColor.RED + "Unrecognized Inventory");
        }
    
        public AbstractModularInventory findInventoryByname(String name) {
            for (AbstractModularInventory ami : inventoryList) {
                if (ami.isInventory(name)) {
                    return ami;
                }
                else continue;
            }
            return null;
        }
    
    }
    

    I know that it is not the sign event because I receive the message saying that the inventory was located.

    Here is the abstract and main inventories (in that order):

    Abstract Class (open)

    Code:
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.event.inventory.InventoryOpenEvent;
    import org.bukkit.inventory.Inventory;
    
    import com.Jacobb6816.testingProject.TestingPlugin;
    
    public abstract class AbstractModularInventory implements Listener {
    
        protected Inventory    inventory;
        private String        name;
    
        public AbstractModularInventory(int slots, String key) {
            this(slots, key, ChatColor.DARK_GREEN.toString() + ChatColor.BOLD + "Testing >> " + key);
        }
    
        public AbstractModularInventory(int slots, String key, String invName) {
            this.name = key;
            while (slots % 9 != 0)
                slots++;
            inventory = Bukkit.createInventory(null, slots, invName.substring(0, Math.min(31, invName.length())));
            Bukkit.getPluginManager().registerEvents(this, TestingPlugin.getInst());
        }
    
        public abstract void fillInventory();
    
        [USER=17846]@EventHandler[/USER]
        public void onClick(InventoryClickEvent event) {
            if (inventory == null) return;
            if (event.getInventory().hashCode() == inventory.hashCode()) {
                event.setCancelled(true);
                onVerifiedInventoryClick(event);
            }
        }
    
        public void onVerifiedInventoryClick(InventoryClickEvent event) {
    
        }
    
        [USER=17846]@EventHandler[/USER]
        public void onOpen(InventoryOpenEvent event) {
            if (inventory == null) return;
            if (event.getInventory().hashCode() == inventory.hashCode()) {
                event.setCancelled(true);
                onVerifiedInventoryOpen(event);
            }
        }
    
        public void onVerifiedInventoryOpen(InventoryOpenEvent event) {
            fillInventory();
        }
    
        public Inventory getInventory() {
            return inventory;
        }
    
        public boolean isInventory(String string) {
            return string.equalsIgnoreCase(name) || string.equalsIgnoreCase("Inventory" + name);
        }
    
    }
    
    

    Main inventory class (open)

    Code:
    import org.bukkit.Material;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.inventory.ItemStack;
    
    import com.Jacobb6816.testingProject.core.AbstractModularInventory;
    
    public class InventoryTestingMain extends AbstractModularInventory {
    
        public InventoryTestingMain() {
            super(27, "Main");
        }
    
        @Override
        public void fillInventory() {
            inventory.setItem(1, new ItemStack(Material.STICK));
        }
    
        @Override
        public void onVerifiedInventoryClick(InventoryClickEvent event) {
            // TODO Auto-generated method stub
            super.onVerifiedInventoryClick(event);
        }
    
    }
    


    I have left out the other inventories for the sake of space on this post, as well as because I feel that getting Main to work will allow me to fix the other three.

    The Spigot forums has, of course, requested a stack-trace, but there is not one. I have two pictures, one showing a clear console and the other showing that the inventory should be usable.
    Images (open)
    [​IMG][​IMG]
    [​IMG]


    EDIT: The most help I have received so far was being told that I do not know how to use abstraction or abstract classes, and that I should just ":Just make a regular class and call the constructor and get the methods"
     
  2. Offline

    Rufus5

    Whatever your plugin code is doing, it's not defining a new AbstractModularInventory and initiating your variable. The game can't open a null/uninitiated inventory. Try making a new AbstractModularInventory(args here) on the sign click
     
  3. Offline

    JRL1004

    @Rufus5m No, I'm not initializing an AbstractModularInventory. Because the class is abstract, it cannot be initialized anyway. I am initializing the classes that extend the AbstractModularInventory, however. You are able to see that the class and inventory are initializing in the second screenshot, where I use the class to get the inventory, and then check to make sure the inventory is valid my ensuring that the name, title, size, and type are all correct.
     
  4. Offline

    MajorSkillage

    Why compare using inventories hashcode? Why not just compare viewers?
     
  5. Offline

    JRL1004

    I use hashCode comparison because I feel as if it's the easier way to make sure objects are thing same. As far as I know, every object *SHOULD* have a different hashCode due to this line from the Oracle documentation:
    By this logic, I tend to feel that there is no reason to compare viewers, names, etc when I can just compare integers.

    Also, bump since this still won't work
     
  6. Offline

    MajorSkillage

    Instead of making an ArrayList of AbstractModularInventory why not make a HashMap and map it by its primary value (its name) then you wont have to loop through all values every time you want to compare inventories (such as findInventoryByName()) Also in your AbstractModularInventory class you don't need to check if the Inventory value isn't null inside the class because you're defining it through a hierarchy through its parameters, if there was a problem defining it then there would be a stack print trace in console.
     
  7. Offline

    JRL1004

    @MajorSkillage I like the idea of using a Map<String, AbstractModularInventory>. As for the null check, I mainly added that in an attempt to fix the issue, but did not help, sadly. Would you happen to have any ideas as to why my inventory will not open? Or maybe an idea of where I could add debug to make finding out easier? I'm open to suggestions.
     
  8. Offline

    Lordloss

    If theres no stacktrace and just nothing happens, it sounds like the event is cancelled from somewhere.

    Code:
     public void onOpen(InventoryOpenEvent event) {
            if (inventory == null) return;
            if (event.getInventory().hashCode() == inventory.hashCode()) {
                event.setCancelled(true);
                onVerifiedInventoryOpen(event);
            }
        }
    Try to set some debug messages in here.
     
  9. Offline

    Konato_K

    @JRL1004 Two different objects can have the same hashcode (because of the way is calculated and the fact that the full hash code doesn't fit in the size of an int), yes, it's unlikely to have same hashcodes in this case, but still something, if you really want to know they are the same object then use #equals
     
  10. Offline

    mythbusterma

    @Konato_K

    Two Objects having the same hash code affects this how? It just makes the Map slightly slower.

    It's very unlikely, considering they're pointers to the address.
     
  11. Offline

    JRL1004

    I got back to this thread quite late, but I want to express my gratitude for you noticing this. It turns out that cancelling the InventoryOpenEvent stops the inventory from opening (who knew, right?). I don't even know why I had that cancel there but removing it worked. My inventories now function as expected! That you so much for the assistance. I'll be sure to mark this thread as solved.
     
    Lordloss likes this.
Thread Status:
Not open for further replies.

Share This Page