This is a proof-of-concept of server-side changes to ItemStacks being played out client-side. Further information can be found below.
Changes, improvements, contributions and additions are welcome via pull request!
This is the overview of the documentation
- Use-Cases (What could it be used for?)
- Evaluation (Does it make sense to use it?)
- Usage (How is it used?)
- Packets (Which packets are intercepted?)
- Dependencies (Which external libraries are used?)
Due to the immense number of changes that take place in the individual packets that affect item or inventory changes, developers should explicitly consider in advance whether and to what scope the use of this procedure makes sense.
- Localization of
ItemStacknames - Control of corrupt
ItemStacks Player-based modification ofItemStacks
If further use cases are not listed here, they can be added via pull request!
Using this method yields both pro and con arguments. Some of these are listed below.
- Central query point of all
ItemStacks that are sent to clients. - Easy modification of the created
ItemStacks.
- Overhead creation through newly cloned
ItemStackobjects.
The ItemProtocolEvent follows the regular Bukkit event-api and can also be intercepted via it. An example Listener might look like the following:
public class ItemProtocolListener implements Listener {
@EventHandler
public void onItemProtocol(ItemProtocolEvent event) {
// The original ItemStack object
ItemStack itemStack = event.getItemStack();
// A clone of the original ItemStack object
ItemStack clone = event.getClonedItemStack();
// Set a modified ItemStack
event.setItemStack(clone);
}
}From an ItemProtocolEvent both the Player and the original ItemStack can be fetched. If the original ItemStack is changed, it should be noted that it may also be changed on the server-side. To make only client-side changes, the cloned ItemStack is provided.
It should also be noted that a new clone is created when the cloned ItemStack method is called, and not when the event is initialized.
Currently the following packets are intercepted and can be retrieved as ItemProtocolEvent.
WrapperPlayServerEntityEquipmentWrapperPlayServerSetSlotWrapperPlayServerWindowItems
These are the only ItemStack-related packets that are sent from the server-to-client. In the current scenario it is assumed that the client does not create any ItemStack objects through GameMode.CREATIVE. This would require that further client-to-server packets would have to be intercepted via PacketAdapter.
This proof-of-concept uses the ProtocolLib library and additionally some classes of the official PacketWrapper library. For more information, please refer to the documentation of the respective library.