Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about compatibility implementation #155

Open
n0ct opened this issue Oct 4, 2021 · 12 comments
Open

Question about compatibility implementation #155

n0ct opened this issue Oct 4, 2021 · 12 comments

Comments

@n0ct
Copy link

n0ct commented Oct 4, 2021

Hi guys. I just discovered your work and it's really amazing. I was thinking about creating a menu creation library but you developed almost everything I need.
I'm now wondering about how to plug my item library into your framework.

As I am not familiar with your framework, I am creating this issue to exchange with you on this subject and to think about the best way to do what I need. I hope I am not disturbing you in doing so, and if I am, please excuse me and tell me how I should go about it (where to ask such questions).

To be precise it is based on 3 other libs I made (JsonLib, TranslationLib and event-wrapper-lib) but that does not change anything for your understanding.

ItemLib is currently private but it will be published with an open source license in the next months.

I would therefore like to slightly modify or extend your framework in order to meet several needs.

These are my needs:
1 - Show ItemStack according to the player's language.

  • [In my lib] An ItemStack can be retrieved using:
    • a String "technicalName" which is an unique identifier
    • a Language (that can be retrieved from the player)
  • [How ?] Could I extend GuiItem in order to do so. Is it possible to retrieve the player that will see the GUI when working with a GuiItem ?

2 - Translate every text according to the player's language

  • [In my lib] A translated text can be retrieved using:
    • a String "key" which is the translation key
    • a Language (that can be retrieved from the player)
  • [How ?] I don't even know every places where there can be a text message in your framework but since I saw you made adventure compatibility possible, maybe I could follow the same technical design to allow compatibility with my translation system. Or should I plug into adventure instead ?

3 - Be able to refresh/close a GUI according to an event (for example, if the GUI is related to a block and if another player destroy this block, the GUI should be closed)

  • [How ?] Maybe you already have a similar feature but I could not find it in your documentation. I already imagined some ways to do so but I would prefer ask you first to avoid starting some bad implementation.

4 - Your library seems to be only working for Inventories but I would like to also modify the players shortcut bar. In order to do so I have to save the player's inventory (ItemLib does that well) and to replace it by a GUI until the player exit this menu. Do you think I could plug such a feature in your framework (and keep, for example, the pane feature) ?

If you wonder, my library (called, without more imagination, ItemLib) allows plugin developers to :

  • Define all the plugin's items quickly and simply using JSON files.
  • Let server owners modify those items in JSON files.
  • Update those item data as a developer (and override the modifications done by server owners if required).
  • Translate those item names and lore in multiple languages.
  • Translate any other text (like messages).
  • Define all the plugin's translations quickly and simply using JSON files.
  • Let server owners modify those translations in JSON files.
  • Update those translations as a developer (and override the modifications done by server owners if required).
  • Set and modify the player lang.
  • Listen to events related to each item and triggered according to the slot in which this object is located.
  • This event system simplifies the detection of player clicks because it contains an ItemClickEvent that removes the complexities of the PlayerInterractEvent, EntityDamageByEntityEvent and PlayerAnimationEvent bukkit events.
  • Save the player inventory and allow it to be restored automatically depending on event conditions (which can persist even after a server restart).
  • Create/Modify ItemStacks using an ItemStackWrapper (and ItemStackUtils).
  • Compare/Count/remove ItemStacks using ItemStackTrait (and ItemStackUtils).
  • Create custom heads based on custom textures.
  • Create items based on custom 3D models / textured according to a texture pack.
  • 1.12-1.17 compatibility

Please advice

@stefvanschie
Copy link
Owner

A single gui instance is the same for all viewers. Therefore if you need to display different items or different text for different players (for example, due to their language setting), you should use multiple different gui instances. It's probably easiest if you create a gui instance for a single person. That way you can adjust this single gui instance to the player's settings. This should hopefully answer questions one and two.

Refreshing a gui can be done via Gui#update. Closing a gui for a player can simply be done via Player#closeInventory. You can simply call these methods in your event handler.

IF allows you to place panes inside the player's inventory when they have an inventory open. For merged guis (these are barrel, chest, ender chest and shulker box guis) this can simply by done by moving a pane lower done. The gui is assumed to extend across both the top inventory and bottom inventory and act as one whole. For the other guis, you can place the panes in the player inventory component by first getting this component and then adding the pane to it. If you place a pane in the bottom inventory, IF will take care of saving the player's inventory before the gui is opened and restoring it after the gui is closed again.

Hopefully this answers your questions.

@n0ct
Copy link
Author

n0ct commented Oct 4, 2021

Thank you for your very clear answers. There is only one point I am not sure I understood:

If I understood correctly, it is not possible to use IF to modify the shortcutbar if there is no open inventory. In other words, IF can save the player's inventory, modify the shortcut bar, and then, when closing the GUI, put the saved inventory back. But all this can only be done when opening (and then closing) an inventory.

Do I have this right?

@n0ct
Copy link
Author

n0ct commented Oct 5, 2021

Another question comes to mind:
You were telling me that IF restoves the player's inventory when the GUI closes (in case the GUI overlaps (and override) the player's inventory).

What happens if:
1 - A player leaves the server while this overlaping GUI is open?
2 - A player dies with this GUI open (and if inventory retention is enabled/disabled on the server)?
3 - What if the server crashes at that moment?

Will the player's inventory be restored in all 3 cases? And in the second case, will the GUI items fall to the ground?

@stefvanschie
Copy link
Owner

Yes, that's correct, the inventory of the player can only be modified while a gui is opened since IF is intended for guis, so it essentially does nothing if there's no open gui.

The intention is that the player's inventory is always restored (and gui items are not dropped on the ground). I would need to test these specific scenarios you mentioned (and update IF if they happen to not work), but the idea is that these cases are handled. (A server crashing might be a bit troublesome, though.)

@n0ct
Copy link
Author

n0ct commented Oct 11, 2021

I'm really going to be faced with a complex situation because I would like to develop a feature that I think would benefit from being integrated directly into IF:

I would like the shortcutbar to be considered a menu (and could be modified with the pane system you made).

Example :

  • You write a command and then the shortcutbar is replaced (as well as the whole player inventory which is then saved) but no inventory GUI is opened.
  • You click on one of the items in the shortcutbar and an inventory GUI opens.

In short, the shortcutbar can then be considered as a kind of GUI in its own right but without an inventory being open.
This allows a player to select locations or to continue moving while consulting the GUI.

The typical example of this is what I have already done in the https://gitlab.com/lasersenigma/lasersenigma/ plugin.

Would you like this feature to be included in IF? If so, would you like to develop it on your own (you will probably go faster as you know the IF code) or would you like my help or that of one of the developers of my association?

Otherwise, we could fork your project but it would be a pity as it would make 2 projects to maintain and would force to postpone the evolutions/corrections that could be mutualised from one project to the other.

@stefvanschie
Copy link
Owner

While I understand the want for this feature, I feel like this is out-of-scope for this framework. The hotbar itself is not really a gui, which is the target of this framework, especially considering interaction with the hotbar from the player's perspective is completely different than the interaction with a gui. I personally think it'd make more sense to keep these separate, with IF being for guis and some other kind of library/API for just hotbars.

@n0ct
Copy link
Author

n0ct commented Oct 12, 2021

Ok. That does make sense. However, I think that the amount of code that could be pooled between what IF already does and these new features would justify such a choice (pane system/inventory recover/...). Especially as coding it separately would risk creating conflicts (inventory recover, ...).

Anyway, thank you for your clear and useful answers and for your amazing work.

In any case, even if my last arguments did not change your mind, we can keep this issue open in order to let you check what's required among those inventory recovering potential error cases:

What happens if:
1 - A player leaves the server while this overlaping GUI is open?
2 - A player dies with this GUI open (and if inventory retention is enabled/disabled on the server)?
3 - What if the server crashes at that moment?
Will the player's inventory be restored in all 3 cases? And in the second case, will the GUI items fall to the ground?

Or would you prefer to close this issue and to create one separately ?

@stefvanschie
Copy link
Owner

Leaving this one open is fine, after those points are done we can then close this.

@n0ct
Copy link
Author

n0ct commented Oct 14, 2021

As you know I would like to create a ShortcutBarGUI.
On the way of doing so I will have to handle multiple problematic :

  • Inventory recover after this ShortcutBarGUI is "closed".
  • The way this ShortcutBarGUI is closed is different from other GUI since it is not like an opened inventory.
  • Event management (we already have custom Right/LeftClickEvent in our ItemLib that simplify the usage of the original bukkit item related events).
  • We want to use your pane system and the others nice features your lib includes.

What would be the best way to implement it into a fork of IF?

  • First option:
    1. Rename GUI class into InventoryGUI.
    2. Create a new class GUI including the common code between InventoryGUI and ShortcutBarGUI.
    3. Create a new class ShortcutBarGUI that inherite GUI.
  • Second option:
    1. Create directly a new subclass of GUI named ShortcutBarGUI

Another option ?

Could you please advise me as I am a bit lost when it comes to defining such an architecture within a framework that I know little about ?

@stefvanschie
Copy link
Owner

I would go for the second option. IF already has an InventoryBased interface which is for inventory specific things, so if you inherit from the default Gui, but don't inherit InventoryBased, then you will not have to do anything with an inventory. You might want to implement MergedGui as well - the shortcut bar is technically not a merged gui, but the methods in there do apply to it. It's not strictly necessary, however, so you can also not do this.
If you create an InventoryComponent of the shortcut bar size (nine by one) in the gui, you can add panes to that and let it handle the rendering. The only thing you then have to do is take the items the InventoryComponent placed and move them over to the player's actual inventory.

As for inventory recovering after closing, you could use the HumanEntityCache, however you might want to create your own system/adapt this one, since you don't need to store the entire inventory (like HumanEntityCache does), but only the shortcut bar. If you do decide to use the HumanEntityCache, there are methods there to store the human entity's current inventory and restore it later.

Event management and closing is something you'll basically have to do yourself, since events for clicking with items in the shortcut bar are different from clicking in an inventory, so IF doesn't have anything for that.

@n0ct
Copy link
Author

n0ct commented Apr 8, 2022

Hi,

Thanks again for your help. With a developer of the association in which I am a volunteer, we started to work on this modified version of IF. Unfortunately we were quickly blocked by a small configuration problem.

Cannot resolve io.papermc:paper:1.16.3-R0.1-SNAPSHOT
Cannot resolve org.spigotmc:spigot:1.17-R0.1-SNAPSHOT
Cannot resolve io.papermc:paper:1.15.2-R0.1-SNAPSHOT
Cannot resolve org.spigotmc:spigot:1.18-R0.1-SNAPSHOT
Cannot resolve io.papermc:paper:1.16.1-R0.1-SNAPSHOT
Cannot resolve io.papermc:paper:1.14.4-R0.1-SNAPSHOT
Cannot resolve org.spigotmc:spigot:1.17.1-R0.1-SNAPSHOT
Cannot resolve org.spigotmc:spigot:1.18.2-R0.1-SNAPSHOT
Cannot resolve io.papermc:paper:1.16.4-R0.1-SNAPSHOT

To fix this problem:

  • For missing spigot dependencies it is probably enough to run BuildTools.jar locally for each desired version. Is that right ?
  • But for Paper it seems to me that it is more complex and I don't know exactly how to do it. I have the impression that I had to run the paper.jar of each version with -Dpaperclip.install=true -jar but some of the versions IF uses as dependencies are not available for download on the paper website, even in their archives. What should we do exactly ?

Could you please either complete your README.md or your wiki with a contributing guide explaining how to prepare the development environment. Or, simply explain it to us right here ?

@stefvanschie
Copy link
Owner

Thank you for your interest in addressing this. Yes, for the Spigot dependencies, running BuildTools for the relevant versions is all you need to do to obtain these files. For the Paper dependencies, the versions are downloaded via the API. Then you can run these JAR files to obtain the patched JAR file. These are then manually installed in the local repository via Maven with the following command.

mvn install:install-file -Dfile=cache/patched_1.16.4.jar -DgroupId="io.papermc" -DartifactId="paper" -Dversion="1.16.4-R0.1-SNAPSHOT" -Dpackaging="jar"

This is an example for version 1.16.4, but the same is used for other versions, but with different version numbers.

That should be everything to get a working environment, but I'll make sure to update the instructions in the README.md as well, so it is clearer as to how you can obtain this environment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants