How to create a search system with a GUI?

Discussion in 'Spigot Plugin Development' started by devonzimmi, Nov 18, 2019.

  1. I am trying to create a search system within my GUI.

    Essentially this ->
    You click a slot, inventory closes, you are prompted to type the item you're searching for in chat, and then it opens the GUI to the page that the item is in.

    I attempted to cache the player into a HashSet<Player> on my main GUI class with a separate AsyncPlayerChat listener checking for players in that list on chat. If the player was in the set, the chat event would be canceled and the GUI page with the searched for item would open. The player would then be removed from the list.

    However, this all fell apart when I tried to open the GUI to the player inside the chat event.

    Code (Text):
    [19:04:51] [Async Chat Thread - #0/ERROR]: Could not pass event AsyncPlayerChatEvent to plugin
    org.bukkit.event.EventException: null
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:320) ~[spigot.jar:git-Spigot-56f8471-56118c6]
        at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[spigot.jar:git-Spigot-56f8471-56118c6]
        at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:529) [spigot.jar:git-Spigot-56f8471-56118c6]
        at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:508) [spigot.jar:git-Spigot-56f8471-56118c6]
        at net.minecraft.server.v1_14_R1.PlayerConnection.chat(PlayerConnection.java:1563) [spigot.jar:git-Spigot-56f8471-56118c6]
        at net.minecraft.server.v1_14_R1.PlayerConnection.a(PlayerConnection.java:1501) [spigot.jar:git-Spigot-56f8471-56118c6]
        at net.minecraft.server.v1_14_R1.PacketPlayInChat$1.run(PacketPlayInChat.java:41) [spigot.jar:git-Spigot-56f8471-56118c6]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_221]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_221]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_221]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_221]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_221]
    Caused by: java.lang.IllegalStateException: InventoryOpenEvent cannot be triggered asynchronously from another thread.
        at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:511) ~[spigot.jar:git-Spigot-56f8471-56118c6]
        at org.bukkit.craftbukkit.v1_14_R1.event.CraftEventFactory.callInventoryOpenEvent(CraftEventFactory.java:1105) ~[spigot.jar:git-Spigot-56f8471-56118c6]
        at org.bukkit.craftbukkit.v1_14_R1.event.CraftEventFactory.callInventoryOpenEvent(CraftEventFactory.java:1091) ~[spigot.jar:git-Spigot-56f8471-56118c6]
        at org.bukkit.craftbukkit.v1_14_R1.entity.CraftHumanEntity.openCustomInventory(CraftHumanEntity.java:499) ~[spigot.jar:git-Spigot-56f8471-56118c6]
        at org.bukkit.craftbukkit.v1_14_R1.entity.CraftHumanEntity.openInventory(CraftHumanEntity.java:374) ~[spigot.jar:git-Spigot-56f8471-56118c6]
        at io.noved.BlacklistGUI.openInventory(BlacklistGUI.java:105) ~[?:?]
        at io.noved.BlacklistGUISearchListener.SearchListener(BlacklistGUISearchListener.java:43) ~[?:?]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_221]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_221]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_221]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_221]
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:316) ~[spigot.jar:git-Spigot-56f8471-56118c6]
        ... 11 more
    I can figure out the "org.bukkit.event.EventException: null" error on my own, but I need a little help figuring out what direction to take on opening the GUI for the player.

    Code (Text):
    Caused by: java.lang.IllegalStateException: InventoryOpenEvent cannot be triggered asynchronously from another thread.
    When it says it can't be triggered from another thread, does that mean it could work if I put the listener inside the same class as the GUI, if not, how can I open the GUI for the player searching for an item?

    ** I don't need help coding, just need an idea of what could fix this or what other direction I can take. **
     
  2. AsyncPlayerChatEvent most of the cases is called from another thread so you need to run the methods that requires main thread using a runnable and runTask:
    Code (Java):
    new BukkitRunnable() {
        @Override
        public void run() {
            //open the inventory here
        }
    }.runTask(plugin);
     
    • Useful Useful x 1
  3. So if I put the BukkitRunnable into my AsyncPlayerChat listener, it will then run the code on the main thread instead of a seperate? Is there a specific source where I can read up on runnables and tasks with spigot that'll help me better understand what I'm dealing with?