stefvanschie / if Goto Github PK
View Code? Open in Web Editor NEWAn inventory framework for managing GUIs
License: The Unlicense
An inventory framework for managing GUIs
License: The Unlicense
When using IF with 1.8, and someone clicks an empty slot in the GUI, this error appears: https://pastebin.com/K9VY5V74
Is this framework incompatible with 1.8? If it is, is there a previous version which has 1.8 support I can/should be using?
When setting the name of a gui via NamedGui#setTitle
, any other changes that were done in between the last Gui#update
call and this NamedGui#setTitle
invocation will not be updated in the newly refreshed gui. This is unlike the javadocs and wiki state, which both specify that calling this method will automatically update the gui as well.
I am really not sure, how to do that from the technical side of things, but i think having a top half of inventory act as text input(anvil gui), and player inventory as existing inventory-based gui, would allow for much more complex interactions
https://github.com/WesJD/AnvilGUI
Would it be possible to implement a method that lets us populate a paginated pane with gui items? this would allow us to populate easily with events. Otherwise we need to add panes manually and populate them manually as well since theres no way to attach events.
After updating a gui, the previous items in the underlying inventory component(s) are not removed. This can cause issues when spots previously occupied by an item, are now no longer occupied. In such a case, the previous item will render again erroneously. A good example is making a pane invisible,. Currently unless the spots the pane occupied are overwritten, the pane will appear to stay as is, even after an update.
Yeah, not the best title...
Well, I've been having some issues looping through a Set and adding items into a static pane, my math is probably all wrong but it works very well when I enter the number itself and not by my math stuff, although I've debugged and my math doesn't seem to be wrong since it prints out the correct numbers.
Screenshot of the current issue: https://gyazo.com/ee658c4b25df45e4646d5c10b8fd50dc
My code for the explanation above is: https://sourceb.in/6e9cb16ecd
( The github code selector didn't want to work )
Any assistance would be lovely at this point, thanks in advance.
~ Sincerely, RarLab.
Hello!
I'm currently working on a project where I'd like to have an item that, when clicked, displays a pane underneath. I just wanted to see if it was possible to add a pane to a GUI that someone currently has open (to specify, it would only appear for that one player, as a new GUI is created each time a player opens it)
Thanks
let's allow every element of gui to have a UUID, so they can be found when needed
Hi, I have a problem to open new gui while another gui is already open.
This problem happens because of this feature: https://github.com/stefvanschie/IF/blob/master/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/GuiListener.java#L310-L314
To avoid the problem problem, I used below code in my plugin, but in my opinion its not good solution:
player.closeInventory();
Bukkit.getScheduler().runTask(JavaPlugin.getProvidingPlugin(this.getClass()), () ->
{
Gui menu = this.getGui();
menu.show(player);
});
According to me the problem should be resolved in inventory framework because I lost long time to find solution and it hinders implementation.
lets say you put a few items in a GUI and let users remove those items. Once the last item is removed, after calling the Gui#update()
method, you'll get an NPE. This also happens when just trying to display an empty gui.
Stacktrace:
org.bukkit.event.EventException
at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
at net.minecraft.server.v1_11_R1.PlayerConnection.a(PlayerConnection.java:1849) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
at net.minecraft.server.v1_11_R1.PacketPlayInWindowClick.a(SourceFile:33) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
at net.minecraft.server.v1_11_R1.PacketPlayInWindowClick.a(SourceFile:10) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
at net.minecraft.server.v1_11_R1.PlayerConnectionUtils$1.run(SourceFile:13) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_202]
at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_202]
at net.minecraft.server.v1_11_R1.SystemUtils.a(SourceFile:46) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
at net.minecraft.server.v1_11_R1.MinecraftServer.D(MinecraftServer.java:747) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
at net.minecraft.server.v1_11_R1.DedicatedServer.D(DedicatedServer.java:399) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
at net.minecraft.server.v1_11_R1.MinecraftServer.C(MinecraftServer.java:678) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
at net.minecraft.server.v1_11_R1.MinecraftServer.run(MinecraftServer.java:576) [spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_202]
Caused by: java.lang.NullPointerException
at ca.yomnetwork.mythicshop.inventoryframework.pane.PaginatedPane.display(PaginatedPane.java:170) ~[?:?]
at ca.yomnetwork.mythicshop.inventoryframework.Gui.lambda$show$0(Gui.java:160) ~[?:?]
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source) ~[?:1.8.0_202]
at java.util.stream.ReferencePipeline$2$1.accept(Unknown Source) ~[?:1.8.0_202]
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source) ~[?:1.8.0_202]
at java.util.stream.AbstractPipeline.copyInto(Unknown Source) ~[?:1.8.0_202]
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source) ~[?:1.8.0_202]
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source) ~[?:1.8.0_202]
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source) ~[?:1.8.0_202]
at java.util.stream.AbstractPipeline.evaluate(Unknown Source) ~[?:1.8.0_202]
at java.util.stream.ReferencePipeline.forEach(Unknown Source) ~[?:1.8.0_202]
at ca.yomnetwork.mythicshop.inventoryframework.Gui.show(Gui.java:160) ~[?:?]
at java.lang.Iterable.forEach(Unknown Source) ~[?:1.8.0_202]
at ca.yomnetwork.mythicshop.inventoryframework.Gui.update(Gui.java:238) ~[?:?]
at ca.yomnetwork.mythicshop.command.SurvivorShop.lambda$onCommand$1(SurvivorShop.java:100) ~[?:?]
at ca.yomnetwork.mythicshop.inventoryframework.GuiListener.onInventoryClick(GuiListener.java:55) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_202]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_202]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_202]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_202]
at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:302) ~[spigot-1.11.2.jar:git-Spigot-3fb9445-6e3cec8]
... 15 more```
Hi there,
Since you added non-chest inventory types to your framework, I wanted to make you aware of SPIGOT-4274. I encountered this regression in Spigot myself when I worked on my own inventory gui framework. Paper has patched it, but it seems that md_5 considers it a wontfix for Spigot.
An example plugin that triggers the issue:
package com.janboerman.iftest;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.Material;
import com.github.stefvanschie.inventoryframework.gui.*;
import com.github.stefvanschie.inventoryframework.gui.type.*;
import com.github.stefvanschie.inventoryframework.pane.*;
import com.github.stefvanschie.inventoryframework.pane.OutlinePane;
public final class IFTest extends JavaPlugin implements Listener {
@Override
public void onEnable() {
// Plugin startup logic
getServer().getPluginManager().registerEvents(this, this);
}
@EventHandler
public void onJoin(PlayerJoinEvent joinEvent) {
getServer().getScheduler().runTaskLater(this, () -> {
//create a hopper gui and the title My GUI
HopperGui gui = new HopperGui("My GUI");
//create a new pane occupying the entire gui
OutlinePane pane = new OutlinePane(0, 0, 5, 1);
ItemStack item = new ItemStack(Material.ICE);
//create an item which will send a message when clicked
GuiItem guiItem = new GuiItem(item, event -> event.getWhoClicked().sendMessage("You clicked on ice!"));
//add the item to the pane
pane.addItem(guiItem);
//add the pane to the gui
gui.getSlotsComponent().addPane(pane);
//open the gui!
gui.show(joinEvent.getPlayer());
}, 20L);
}
}
I worked around this bug in Spigot by storing the custom inventoryholders in a WeakHashMap<Inventory, WeakReference<GuiInventoryHolder>>
in the GuiListener if the Inventory itself does not store the InventoryHolder internally (it's a WeakReference because entries won't get removed from the map automatically if a value has a strong reference to a key). See GuiListener.
Edit:
One other possbile way to fix it is to set the InventoryHolder in the nms class for the inventory. I didn't want to resort to NMS for my plugin, but for you this might be a viable alternative.
Groetjes,
Jan
Whenever i try to change my dependency to use newer version
<dependency>
<groupId>com.github.stefvanschie.inventoryframework</groupId>
<artifactId>IF</artifactId>
<version>0.8.0</version>
<scope>provided</scope>
</dependency>
i get Failed to read artifact descriptor for com.github.stefvanschie.inventoryframework:IF:jar:0.8.0
error from maven
Using properties, it's possible to transfer data from the XML to the plugin.
Is the reverse also possible?
For example, if I wanted to use the return string of a method named "getPlayersBalance" to populate the lore of an item in my XML representation of the GuiItem
The click
calculation of panes such as StaticPane
uses the incorrect length variable in the last stage of calculation.
Lines 125 and 126 should be using inventoryComponent.getLength()
instead of length
.
Below is an example of the values generated by this formula on an example 9x6 inventory (the '5x3 test pane' is highlighted in blue):
Top left are the slot
values for each inventory slot, top middle are the adjustedSlot
values, top right are the x
and y
values for the respective slot, and bottom right are the x
and y
values for the respective slot using inventoryComponent.getLength()
instead of length
.
Testing the original version in-game yields unexpected results (the behavior is correctly predicted by the top right table), and testing a version using a custompane with the different click
calculation produces the expected behaviour.
I haven't done in-game testing of the other pane types, but as they share this code I imagine they also have this logical error.
I first attempted to shade IF into my plugin. It did not work and never ended up in the plugin. So then i copied exact word-for-word, char-for-char your example, replacing my maven-shade-plugin configuration with yours. Still does not work. Please help!
Also, in-game stacktrace for not finding the lib
Caused by: java.lang.NoClassDefFoundError: com/elytraforce/libs/inventoryframework/pane/Pane at com.elytraforce.voidcore.commands.TeleportCommands$VisitCommand.onCommand(TeleportCommands.java:59) ~[?:?] at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[server.jar:git-Paper-385] ... 17 more Caused by: java.lang.ClassNotFoundException: com.elytraforce.libs.inventoryframework.pane.Pane at java.net.URLClassLoader.findClass(URLClassLoader.java:471) ~[?:?] at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:171) ~[server.jar:git-Paper-385] at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:100) ~[server.jar:git-Paper-385] at java.lang.ClassLoader.loadClass(ClassLoader.java:588) ~[?:?] at java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[?:?] at com.elytraforce.voidcore.commands.TeleportCommands$VisitCommand.onCommand(TeleportCommands.java:59) ~[?:?] at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[server.jar:git-Paper-385] ... 17 more
As well as the compiler log
[INFO] --- maven-shade-plugin:3.1.0:shade (default) @ voidcore --- [INFO] Including com.intellectualsites.fawe:FAWE-Bukkit:jar:1.16-434 in the shaded jar. [INFO] Replacing original artifact with shaded artifact. [INFO] Replacing C:\Users\Matt\VoidCore\target\VoidCore-1.0.0-SNAPSHOT.jar with C:\Users\Matt\VoidCore\target\voidcore-1.0.0-SNAPSHOT-shaded.jar [INFO] Dependency-reduced POM written at: C:\Users\Matt\VoidCore\target\dependency-reduced-pom.xml [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 49.328 s [INFO] Finished at: 2020-11-08T20:34:22-07:00 [INFO] ------------------------------------------------------------------------
Since Bukkit has its own "NBT API", we should consider using it instead of a third-party library. This Bukkit one is called PersistentDataContainer
or org.bukkit.persistence
. Using it requires a Plugin
instance for creating a NamespacedKey
, but that should be no issue: Gui
instances already keep a reference to the plugin that created them. This feature does not have any of the issues described in #45.
I would be more than happy to implement and PR this, I am just asking for input regarding it. This is a place for discussion.
https://youtu.be/Oq2GrtH9gK4
This video shows that dragging items into an inventory where gui.setOnTopClick(e -> e.setCancelled(true));
is used gets bypassed.
I suggest adding:
gui.setOnTopDrag(event -> {});
gui.setOnBottomDrag(event -> {});
gui.setOnGlobalDrag(event -> {});
so you can cancel Inventory drags separately from Inventory clicks.
Usage example:
gui.setOnGlobalDrag(event -> e.setCancelled(true));
cancels all inventory drags.
When trying to open a gui with a percentage bar in it, an exception will be thrown. This is caused by not properly resizing the mask when an outline pane is resized, causing lookups to invalid indices. When resizing an outline pane via OutlinePane#setLength
and OutlinePane#setHeight
, the mask should be properly resized as well, to keep the mask size and outline pane size consistent.
Code to reproduce:
ChestGui gui = new ChestGui(6, "Gui");
PercentageBar percentageBar = new PercentageBar(1, 3, 7, 1);
percentageBar.setPercentage(0.5f);
gui.addPane(percentageBar);
gui.show(humanEntity);
The stacktrace can be found here: https://pastie.io/fskbcm.groovy
(Issue reported by DMtp.)
@Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { ChestGui cg = new ChestGui(3, "test"); cg.setOnClose(e -> System.out.println("TEST"); }); cg.show((HumanEntity) sender); return true; }
I was using version 0.9.0 and "TEST" was not being printed to the terminal when the gui was closed. I then switched back to version 0.8.0 and it then worked. (Tested on spigot 1.16.4)
UPDATE - Just tested with version 0.8.1 and it appears to have been broken here.
Hi,
I'm trying to use this framework but I keep getting this error:
java.lang.BootstrapMethodError: java.lang.IllegalAccessError: no such method: net.matixmedia.mlgrush.inventoryframework.pane.MasonryPane.load(Object,Element)MasonryPane/invokeStatic
I've already tried version 0.8.0 and 0.9.0 but the same error reoccurs.
I've already checked the jar and decompiled it, but the library is where it should be. If you need the pom.xml dependency:
<dependency>
<groupId>com.github.stefvanschie.inventoryframework</groupId>
<artifactId>IF</artifactId>
<version>0.9.0</version>
</dependency>
Where I create the GUI:
mapSelectionGUI = new ChestGui(5, ChatColor.DARK_AQUA + "Select a map"); // Error occurses here.
OutlinePane mapsPane = new OutlinePane(0, 0, 9, 5);
mapManager.getMaps().forEach(map -> {
ItemStack item = new ItemBuilder(Material.PAPER, 0).setName(ChatColor.AQUA + map.getName())
.setLore(ChatColor.GRAY + "Right/Left click to select").toItemStack();
GuiItem gItem = new GuiItem(item, event -> {
if (votes.containsKey(map.getName())) {
votes.put(map.getName(), votes.get(map.getName()) + 1);
} else {
votes.put(map.getName(), 1);
}
if (event.getCurrentItem() != null) {
event.getCurrentItem().setAmount(votes.get(map.getName()));
}
event.getWhoClicked().sendMessage(Main.getPrefix() + "You voted for " + ChatColor.GREEN +
map.getName() + ChatColor.GRAY + "!");
});
mapsPane.addItem(gItem);
});
mapSelectionGUI.addPane(mapsPane);
I hope you can help me out!
I might be stupid for saying this but as I added the framework as a dependency and made a gui object, set it up and showed it to the player, I can grab the things from inside etc (the usual nonworking-gui stuff). I wandered around your code and I cannot find any parts cancelling the event. Isn't the gui supposed to have clickable items which are unobtainable from the player?
If i understood how it all works correctly, right now when making a copy of gui, the actions called on click still reference original class, where the gui was constructed from xml.
I think an option to update the action performed by button after copying the gui would help a lot.
The populateWithItemStacks
method inside PaginatedPane
can cause out of bounds exceptions.
Any PR for this should be pushed to branch 0.5.4.
When adding an empty element to an outline pane in an XML file, this causes an exception to occur when this XML file is being loaded. This is because gui items don't accept air items, since they can't store persistent data.
A possible workaround would be to not set the persistent data for air items. This is unnecessary to begin with, since air items cannot be moved and therefore do not need to be tracked.
Example code that causes such an error:
<gui title="test" rows="1" type="chest">
<outlinepane x="0" y= "0" length="1" height="1">
<empty />
</outlinepane>
</gui>
Stacktrace: https://pastie.io/qgvtbz.txt
What happens while players receive items while their inventory (the player inventory) is also used as a GUI?
As far as I know, there are two main ways in which players can receive items:
PlayerPickupItemEvent
: this event could simply be cancelled while such an IF GUI is openedInventory#addItem
or equivalent methods: we could attempt to detect foreign items in the GUI when it is updated/closed and just drop them on the groundStill an issue: Inventory#removeItem
, which might be used for eg. item-based economies.
The best solution would be to publish the GUI to the player using packets, in which case the Bukkit API method calls from other plugins, etc would still act upon the real player GUI. But such a system is complicated and probably beyond the scope of this project, especially due to maintenance costs.
I personally believe the best course of action, if it's not already done, is to cancel the PlayerPickupItemEvent
if such a IF GUI is open, and leave this issue at that. The other solutions are too complicated and the problems they solve are probably orders of magnitude rarer.
Right now players can put their stuff into the GUI inventory and it will be lost after the GUI is closed, any tips on how to avoid that?
Initialize Slider (or PercentageBar) object throw exception Length and height of pane must be greater than zero
it would be very convenient to have something like that
When switching between pages in a PaginatedPane thats inside of a MasonryPane the page index is updated but the items in the GUI stay the same.
It seems that MasonryPane ignores index of the paginated pane when its already shown.
recreating the Gui and setting the paginated pane index before showing it works fine
Let's say i have some basic GUI which will have some information different for all of the players - such as a playerhead and some texts inside of it.
Right now, i need to construct a fresh new GUI from existing XML template, and then manually update it for my needs for each player issuing a command.
This means that each time someone runs a command, there happens a file read, which isnt that good is it?
What i suggest, is the ability to create a copy of an existing gui instance, allowing to store one instance of a gui, and make a copy of it for each player who i need to show it to, and then destroy it when it isnt needed anymore.
Item equality comparisons on 1.12 for some items are broken.
https://github.com/stefvanschie/IF/blob/master/src/main/java/com/github/stefvanschie/inventoryframework/pane/OutlinePane.java#L213 this line will always return false when comparing broken item in the code below, tested StaticPane and OutlinePane, didn't work for both.
Code:
Gui brokenGui = new Gui(plugin, 2, "test");
OutlinePane pane = new OutlinePane(9, 2);
brokenGui.addPane(pane);
brokenGui.setOnGlobalClick(e -> Bukkit.broadcastMessage("Global click"));
ItemStack brokenBanner = new ItemStack(Material.BANNER);
BannerMeta bannerMeta = (BannerMeta) brokenBanner.getItemMeta();
bannerMeta.setBaseColor(DyeColor.ORANGE);
bannerMeta.addPattern(new Pattern(DyeColor.LIGHT_BLUE, PatternType.CREEPER));
brokenBanner.setItemMeta(bannerMeta);
pane.addItem(new GuiItem(brokenBanner, e -> Bukkit.broadcastMessage("Banner click")));
ItemStack workingItem = new ItemStack(Material.DIAMOND);
ItemMeta meta = workingItem.getItemMeta();
meta.setDisplayName("test test");
meta.setLore(Arrays.asList("testtt"));
workingItem.setItemMeta(meta);
pane.addItem(new GuiItem(workingItem, e -> Bukkit.broadcastMessage("Working diamond click")));
brokenGui.show(player);
Expected behaviour:
Actual behaviour:
Affected versions:
1.12 only, tested on 1.13 with BLACK_BANNER as an item and worked
I applied a temporary fix for this issue by removing item equality comparison and it was working, not sure if it's safe though.
After updating to 8.0.0, all my click events stopped working, I was unable to make them fire at all. Copied the first navigation example from the wiki and seems like the issue was still present, so it shouldn't be because of my code. So the gui opens up just fine, but no click actions fire and no errors show up.
So to reproduce, just create the navigator example from wiki and add for example logs in click events, I didn't manage to get them firing. I was using ChestGui and 1.16.2.
The listener currently does not seem to handle or cancel the InventoryDragEvent. This could lead to cases where a player could insert (and loose) items into the GUI or even extracting them as dragging of an item (even for a single pixel!) does not call a click event anymore but a drag event. The best solution imo. would be to just cancel it and handle it as if it was clicked if only one item was dragged. (This would allow accidental drags that are meant to be clicks but resulted in slight mouse movement to still be counted as clicks)
Would allow easier data retrieval or search of items inside of the gui.
Even when u set inventoryclickevent#setCancelled(true) the item gets duped to the offhand. (i only tested this with the chestgui)
possible fix:
listen to the PlayerSwapHandItemsEvent and then distribute that event like the inventoryclickevent to the gui and the items of the gui.
Hi, i was just wondering if u have a discord where u can ask questions and stuff like that cuz i don't see a link to one. (not that i have any questions rn but there will certainly be some in the future.
I folowed the emxaple on the wiki so I have this
`public class BankGui {
public static Gui bankGUI;
public BankGui() {
bankGUI = new Gui(6, "Test Bank GUI");
OutlinePane pane = new OutlinePane(0, 0, 9, 6);
ItemStack item = new ItemStack(Material.ICE);
GuiItem guiItem = new GuiItem(item, e -> e.getWhoClicked().sendMessage(ChatColor.AQUA + "YOU CLICKED ON ICE"));
pane.addItem(guiItem);
bankGUI.addPane(pane);
}
public void openBankGui(Player p) {
bankGUI.show(p);
}
}`
And when I create a new BankGui and then call openBankGui I guess an error saying null...
It also did this with other librairies .. Am I missing something ? Might be me just being dumb but if anyone can help would be appreciated :)
https://github.com/stefvanschie/IF/wiki/Custom-Panes
Methods and function arguments dont match anymore, please take your time and update this section, thank you.
Hi, I see a unnecessary store, clear and restore inventory when opening ChestGui which causes more packets to be sent and ugly animation: toolbar items momentarily disappear then reappear.
It's not a big deal, but in my opinion it's not good behaviour.
When referring to a to be invoked method for an item click in an XML file, the optional first parameter for the underlying InventoryClickEvent only accepts InventoryClickEvents and not any super type (e.g., Cancellable). This should be changed so that super types of InventoryClickEvent are also accepted as possible parameter values.
Encountered the issue some time ago but forgot to mention it.
PaginatedPane offset doesn't work properly, when moved either on x or y axis it's moved by double value.
Example:
Gui gui = new Gui(plugin, 4, "test");
PaginatedPane pane = new PaginatedPane(1, 1, 2, 2);
gui.addPane(pane);
pane.populateWithItemStacks(new ArrayList<ItemStack>() {{
for(int i = 0; i < 10; i++) {
add(new ItemStack(Material.DIRT));
}
}});
Expected: https://i.imgur.com/daLMk48.png
Got: https://i.imgur.com/KfzWBQ0.png x and y axis are in 2 slots offset not one
When setting x/y to 2 it goes 4 also.
Tested on StaticPane and OutlinePane, works good, broken only on this one.
ToggleButton
referring to Material
for GREEN_STAINED_GLASS_PANE
or RED_STAINED_GLASS_PANE
, but fields not available on some versions or has changed to another, we need to move it to constructor or something else to prevent NoSuchFieldException
on some versions.
An instance of Plugin
is required to register an event listener. At the moment only one listener exists in IF: GuiListener
, so I will exclusively use that in my examples. The Gui
class has a static hasRegisteredListeners
boolean variable that is used to register an event listener if one hasn't been registered yet. The plugin instance is the one passed into the Gui
constructor. What happens if that plugin gets disabled? Even if we ignore the broken reload command and the even better PlugMan plugin, plugins are still disabled if they throw an exception in their onEnable()
. If the plugin associated with IF's event listener is disabled, IF's event listener gets unregistered without IF knowing about it. I see three options:
PluginDisableEvent
, migrate to another plugin and register a new listener when it's called (this solution seems a bit complicated, could go wrong a thousand ways)I would be more than happy to implement and PR whatever we decide on (if it's not the "don't worry about this" option, of course). This is a place for arguments and counter-arguments.
This happen when i try to click outside ui
can you help me with ##this
Error : Could not pass event InventoryClickEvent java.lang.NullPointerException: null
Hey there,
After some testing, I have come to realize that the update() method only works on GUI's that have been manipulated programatically. Currently I have a plugin that uses IF to load items into a virtual inventory, where players can edit these items, and later save them back to the config. Thing is, If I open the inventory using IF, remove items, and run GUI.update(), once the GUI is shown to another user, the changes are reset back to it's initial loaded state. Is there any possibility update() could also refresh backwards?
Let me know if this can be done, thanks in advanced!
I personally strongly believe that all callbacks should be wrapped in try-catch blocks so that even if these 3rd party code sections throw exceptions, the rest of the code continues as normal. This way we don't have to worry about IF code being interrupted, left in an intermediate, broken state. The plugin's name and if possible, some sort of gui identifier (eg. the associated class's simple name) should be included the error messages that the catch blocks produce.
Sometimes the best way to achieve this wrapping/boxing is to not expose a getter to the callback, but a method that calls the callback instead. This breaks all logic that relies on the getters, the real question is whether anything at all relies on it. Eg. GuiItem#getAction()
returns a non-null value (it internally creates an empty lambda), in that case relying on the return value is very hard and probably no one does it. It might be possible in connection with nullable getters though.
List of what would be affected: (hopefully this is a complete list)
GuiItem#getAction()
Pane#onClick
(protected variable)Gui#getOnClose()
Gui#getOnOutsideClick()
Gui#getOnGlobalClick()
Gui#getOnBottomClick()
Gui#getOnTopClick()
I would be more than happy to implement and PR this, the question is whether I should. This is a place for arguments and counter-arguments.
Calling Gui#update
closes the currently opened gui instead of updating it.
Plugins can get disabled for many reasons (the topic is explored a bit in #45), but one of them is when the server stops (gracefully). In this case, plugins are disabled before players quit/close their inventories. So if the plugins don't explicitly close their GUIs in onDisable
or some PluginDisableEvent
listener, then problems arise. Even if I'm wrong about /stop
, /reload
is surely affected. (Although whether we want to support that command is another question.)
I suggest the addition of a safeguard that catches plugins neglecting the proper closure of inventories and therefore the restoration of player inventories. The best way to this would be to have a PluginDisableEvent
listener and keep track of all plugin-to-gui connections in some sort of Map
. To be able to properly implement this, #45 should be finished first.
I would be more than happy to implement and PR this, I am just asking for input regarding it. This is a place for discussion.
Hello,
Player heads are causing an issue with IF, whenever I set the playerhead's owner, when showing the GUI, it changes the item as it has to show the player.
Then the system in IF for checking if the item stack is equal no longer works.
Since the head is changed. What can we do about tracking this somehow and making it recognize, as the head will no longer use its assigned code for cancelling event etc.
Thanks,
ProSavage
By using MiniNBT it seems that you cannot set ItemMeta and lore anymore, I tried to change the code like this (at line 58~):
NBTWrappers.NBTTagCompound compound = ItemNBTUtil.getTag(item);
compound.setString("IF-uuid", uuid.toString());
this.item = ItemNBTUtil.setNBTTag(compound, item);
Now you will not lose ItemMeta data but only lore.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.