mirror of
https://github.com/TotalFreedomMC/OpenInv.git
synced 2024-12-22 16:05:03 +00:00
Fix item dupe in own inventory
Reduce desync for other actions in own inventory Closes #182
This commit is contained in:
parent
519dd7da33
commit
dad1e16c18
1 changed files with 75 additions and 16 deletions
|
@ -16,7 +16,8 @@
|
|||
|
||||
package com.lishid.openinv.listeners;
|
||||
|
||||
import com.lishid.openinv.IOpenInv;
|
||||
import com.lishid.openinv.OpenInv;
|
||||
import com.lishid.openinv.internal.ISpecialPlayerInventory;
|
||||
import com.lishid.openinv.util.InventoryAccess;
|
||||
import com.lishid.openinv.util.Permissions;
|
||||
import org.bukkit.GameMode;
|
||||
|
@ -25,11 +26,14 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.event.inventory.InventoryInteractEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Listener for inventory-related events to prevent modification of inventories where not allowed.
|
||||
|
@ -38,14 +42,14 @@ import org.bukkit.inventory.Inventory;
|
|||
*/
|
||||
public class InventoryListener implements Listener {
|
||||
|
||||
private final IOpenInv plugin;
|
||||
private final OpenInv plugin;
|
||||
|
||||
public InventoryListener(final IOpenInv plugin) {
|
||||
public InventoryListener(final OpenInv plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClose(final InventoryCloseEvent event) {
|
||||
public void onInventoryClose(@NotNull final InventoryCloseEvent event) {
|
||||
if (!(event.getPlayer() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
@ -58,37 +62,92 @@ public class InventoryListener implements Listener {
|
|||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
onInventoryInteract(event);
|
||||
public void onInventoryClick(@NotNull final InventoryClickEvent event) {
|
||||
if (handleInventoryInteract(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only specially handle actions in the player's own inventory.
|
||||
if (!event.getWhoClicked().equals(event.getView().getTopInventory().getHolder())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Safe cast - has to be a player to be the holder of a special player inventory.
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
|
||||
if (event.getAction() != InventoryAction.MOVE_TO_OTHER_INVENTORY) {
|
||||
// All own-inventory interactions require updates to display properly.
|
||||
// Update in same tick after event completion.
|
||||
this.plugin.getServer().getScheduler().runTask(this.plugin, player::updateInventory);
|
||||
return;
|
||||
}
|
||||
|
||||
// Extra handling for MOVE_TO_OTHER_INVENTORY - apparently Mojang no longer removes the item from the target
|
||||
// inventory prior to adding it to existing stacks.
|
||||
ItemStack currentItem = event.getCurrentItem();
|
||||
if (currentItem == null) {
|
||||
// Other plugin doing some sort of handling (would be NOTHING for null item otherwise), ignore.
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack clone = currentItem.clone();
|
||||
event.setCurrentItem(null);
|
||||
|
||||
// Complete add action in same tick after event completion.
|
||||
this.plugin.getServer().getScheduler().runTask(this.plugin, () -> {
|
||||
player.getInventory().addItem(clone);
|
||||
player.updateInventory();
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onInventoryDrag(InventoryDragEvent event) {
|
||||
onInventoryInteract(event);
|
||||
public void onInventoryDrag(@NotNull final InventoryDragEvent event) {
|
||||
handleInventoryInteract(event);
|
||||
}
|
||||
|
||||
private void onInventoryInteract(InventoryInteractEvent event) {
|
||||
/**
|
||||
* Handle common InventoryInteractEvent functions.
|
||||
*
|
||||
* @param event the InventoryInteractEvent
|
||||
* @return true unless the top inventory is an opened player inventory
|
||||
*/
|
||||
private boolean handleInventoryInteract(@NotNull final InventoryInteractEvent event) {
|
||||
HumanEntity entity = event.getWhoClicked();
|
||||
|
||||
// Un-cancel spectator interactions.
|
||||
if (Permissions.SPECTATE.hasPermission(entity) && entity.getGameMode() == GameMode.SPECTATOR) {
|
||||
event.setCancelled(false);
|
||||
}
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
Inventory inventory = event.getInventory();
|
||||
Inventory inventory = event.getView().getTopInventory();
|
||||
|
||||
if (InventoryAccess.isPlayerInventory(inventory)) {
|
||||
if (!Permissions.EDITINV.hasPermission(entity)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} else if (InventoryAccess.isEnderChest(inventory)) {
|
||||
// Is the inventory a special ender chest?
|
||||
if (InventoryAccess.isEnderChest(inventory)) {
|
||||
// Disallow ender chest interaction for users without edit permission.
|
||||
if (!Permissions.EDITENDER.hasPermission(entity)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ISpecialPlayerInventory playerInventory = InventoryAccess.getPlayerInventory(inventory);
|
||||
|
||||
// Ignore inventories other than special player inventories.
|
||||
if (playerInventory == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Disallow player inventory interaction for users without edit permission.
|
||||
if (!Permissions.EDITINV.hasPermission(entity)) {
|
||||
event.setCancelled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue