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;
|
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.InventoryAccess;
|
||||||
import com.lishid.openinv.util.Permissions;
|
import com.lishid.openinv.util.Permissions;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
|
@ -25,11 +26,14 @@ import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.inventory.InventoryAction;
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||||
import org.bukkit.event.inventory.InventoryInteractEvent;
|
import org.bukkit.event.inventory.InventoryInteractEvent;
|
||||||
import org.bukkit.inventory.Inventory;
|
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.
|
* 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 {
|
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;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onInventoryClose(final InventoryCloseEvent event) {
|
public void onInventoryClose(@NotNull final InventoryCloseEvent event) {
|
||||||
if (!(event.getPlayer() instanceof Player)) {
|
if (!(event.getPlayer() instanceof Player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -58,37 +62,92 @@ public class InventoryListener implements Listener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onInventoryClick(InventoryClickEvent event) {
|
public void onInventoryClick(@NotNull final InventoryClickEvent event) {
|
||||||
onInventoryInteract(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)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onInventoryDrag(InventoryDragEvent event) {
|
public void onInventoryDrag(@NotNull final InventoryDragEvent event) {
|
||||||
onInventoryInteract(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();
|
HumanEntity entity = event.getWhoClicked();
|
||||||
|
|
||||||
|
// Un-cancel spectator interactions.
|
||||||
if (Permissions.SPECTATE.hasPermission(entity) && entity.getGameMode() == GameMode.SPECTATOR) {
|
if (Permissions.SPECTATE.hasPermission(entity) && entity.getGameMode() == GameMode.SPECTATOR) {
|
||||||
event.setCancelled(false);
|
event.setCancelled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Inventory inventory = event.getInventory();
|
Inventory inventory = event.getView().getTopInventory();
|
||||||
|
|
||||||
if (InventoryAccess.isPlayerInventory(inventory)) {
|
// Is the inventory a special ender chest?
|
||||||
if (!Permissions.EDITINV.hasPermission(entity)) {
|
if (InventoryAccess.isEnderChest(inventory)) {
|
||||||
event.setCancelled(true);
|
// Disallow ender chest interaction for users without edit permission.
|
||||||
}
|
|
||||||
} else if (InventoryAccess.isEnderChest(inventory)) {
|
|
||||||
if (!Permissions.EDITENDER.hasPermission(entity)) {
|
if (!Permissions.EDITENDER.hasPermission(entity)) {
|
||||||
event.setCancelled(true);
|
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