forked from github-mirror/CoreProtect
Added logging for dropping items into a hopper
This commit is contained in:
1 parent
829bcc530d
commit
cdc8082c3e
3 files changed
+171
-5
No files matched your search
@@ -53,6 +53,9 @@ public class ContainerLogger extends Queue {
|
||||
else if (type == Material.JUKEBOX || type == Material.ARMOR_STAND) {
|
||||
contents = (ItemStack[]) ((Object[]) container)[1];
|
||||
}
|
||||
else if (container instanceof ItemStack[]) {
|
||||
contents = (ItemStack[]) container;
|
||||
}
|
||||
else {
|
||||
Inventory inventory = (Inventory) container;
|
||||
if (inventory != null) {
|
||||
|
||||
@@ -13,6 +13,8 @@ import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.DoubleChest;
|
||||
import org.bukkit.block.Hopper;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@@ -22,6 +24,7 @@ import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.event.inventory.InventoryMoveItemEvent;
|
||||
import org.bukkit.event.inventory.InventoryPickupItemEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.BlockInventoryHolder;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
@@ -139,6 +142,15 @@ public final class InventoryChangeListener extends Queue implements Listener {
|
||||
inventoryData = inventory.getContents();
|
||||
}
|
||||
|
||||
return queueContainerTransaction(user, playerLocation, type, inventory, inventoryData, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean queueContainerTransaction(String user, Location playerLocation, Material type, Object inventory, ItemStack[] inventoryData, ItemStack[] forceInventoryData) {
|
||||
int x = playerLocation.getBlockX();
|
||||
int y = playerLocation.getBlockY();
|
||||
int z = playerLocation.getBlockZ();
|
||||
@@ -226,15 +238,14 @@ public final class InventoryChangeListener extends Queue implements Listener {
|
||||
ConfigHandler.oldContainer.put(loggingChestId, list);
|
||||
}
|
||||
|
||||
if (forceInventoryData != null) {
|
||||
ConfigHandler.forceContainer.computeIfAbsent(loggingChestId, k -> new ArrayList<>()).add(ItemUtils.getContainerState(forceInventoryData));
|
||||
}
|
||||
|
||||
ConfigHandler.transactingChest.computeIfAbsent(transactingChestId, k -> Collections.synchronizedList(new ArrayList<>()));
|
||||
Queue.queueContainerTransaction(user, playerLocation, type, inventory, chestId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void onInventoryInteractAsync(Player player, Inventory inventory, boolean enderChest) {
|
||||
if (inventory == null) {
|
||||
@@ -542,6 +553,105 @@ public final class InventoryChangeListener extends Queue implements Listener {
|
||||
HopperPullListener.processHopperPull(location, "#hopper", sourceHolder, destinationHolder, event.getItem());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
protected void onInventoryPickupItem(InventoryPickupItemEvent event) {
|
||||
Inventory inventory = event.getInventory();
|
||||
if (inventory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
InventoryHolder holder = PaperAdapter.ADAPTER.getHolder(inventory, false);
|
||||
if (!(holder instanceof Hopper)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Location location = inventory.getLocation();
|
||||
if (location == null) {
|
||||
location = ((Hopper) holder).getLocation();
|
||||
}
|
||||
|
||||
if (location == null || !Config.getConfig(location.getWorld()).ITEM_TRANSACTIONS) {
|
||||
return;
|
||||
}
|
||||
|
||||
Item item = event.getItem();
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack[] oldContents = ItemUtils.getContainerState(inventory.getContents());
|
||||
ItemStack[] newContents = addPickedItem(oldContents, item.getItemStack(), inventory.getMaxStackSize());
|
||||
if (newContents == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String user = PlayerDropItemListener.getDroppedItemUser(item.getUniqueId());
|
||||
if (user == null) {
|
||||
user = "#hopper";
|
||||
}
|
||||
|
||||
queueContainerTransaction(user, location, Material.HOPPER, newContents, oldContents, newContents);
|
||||
}
|
||||
|
||||
private static ItemStack[] addPickedItem(ItemStack[] contents, ItemStack itemStack, int inventoryMaxStackSize) {
|
||||
if (contents == null || itemStack == null || itemStack.getAmount() <= 0 || itemStack.getType() == Material.AIR) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ItemStack[] result = ItemUtils.getContainerState(contents);
|
||||
ItemStack pickedItem = itemStack.clone();
|
||||
int remaining = pickedItem.getAmount();
|
||||
|
||||
for (ItemStack item : result) {
|
||||
if (remaining <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (item == null || item.getType() == Material.AIR || !item.isSimilar(pickedItem)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int maxStackSize = getMaxStackSize(item, inventoryMaxStackSize);
|
||||
int accepted = Math.min(remaining, maxStackSize - item.getAmount());
|
||||
if (accepted > 0) {
|
||||
item.setAmount(item.getAmount() + accepted);
|
||||
remaining -= accepted;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < result.length && remaining > 0; i++) {
|
||||
ItemStack item = result[i];
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int accepted = Math.min(remaining, getMaxStackSize(pickedItem, inventoryMaxStackSize));
|
||||
ItemStack addedItem = pickedItem.clone();
|
||||
addedItem.setAmount(accepted);
|
||||
result[i] = addedItem;
|
||||
remaining -= accepted;
|
||||
}
|
||||
|
||||
if (remaining == pickedItem.getAmount()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int getMaxStackSize(ItemStack itemStack, int inventoryMaxStackSize) {
|
||||
int maxStackSize = itemStack.getMaxStackSize();
|
||||
if (inventoryMaxStackSize > 0 && (inventoryMaxStackSize < maxStackSize || maxStackSize == -1)) {
|
||||
maxStackSize = inventoryMaxStackSize;
|
||||
}
|
||||
|
||||
if (maxStackSize == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return maxStackSize;
|
||||
}
|
||||
|
||||
private boolean isAdvancedChest(Inventory inventory) {
|
||||
return CoreProtect.getInstance().isAdvancedChestsEnabled() && AdvancedChestsAPI.getInventoryManager().getAdvancedChest(inventory) != null;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@ package net.coreprotect.listener.player;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Item;
|
||||
@@ -18,6 +22,19 @@ import net.coreprotect.consumer.Queue;
|
||||
|
||||
public final class PlayerDropItemListener extends Queue implements Listener {
|
||||
|
||||
private static final long ITEM_DROP_ATTRIBUTION_MS = TimeUnit.MINUTES.toMillis(5);
|
||||
private static final Map<UUID, DropAttribution> itemDropAttributions = new ConcurrentHashMap<>();
|
||||
|
||||
private static class DropAttribution {
|
||||
private final String user;
|
||||
private final long expiresAt;
|
||||
|
||||
private DropAttribution(String user, long expiresAt) {
|
||||
this.user = user;
|
||||
this.expiresAt = expiresAt;
|
||||
}
|
||||
}
|
||||
|
||||
public static void playerDropItem(Location location, String user, ItemStack itemStack) {
|
||||
if (!Config.getConfig(location.getWorld()).ITEM_DROPS || itemStack == null) {
|
||||
return;
|
||||
@@ -34,10 +51,46 @@ public final class PlayerDropItemListener extends Queue implements Listener {
|
||||
Queue.queueItemTransaction(user, location.clone(), time, 0, itemId);
|
||||
}
|
||||
|
||||
public static String getDroppedItemUser(UUID itemId) {
|
||||
if (itemId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
long timestamp = System.currentTimeMillis();
|
||||
clearExpiredAttributions(timestamp);
|
||||
|
||||
DropAttribution attribution = itemDropAttributions.get(itemId);
|
||||
if (attribution == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (attribution.expiresAt < timestamp) {
|
||||
itemDropAttributions.remove(itemId);
|
||||
return null;
|
||||
}
|
||||
|
||||
return attribution.user;
|
||||
}
|
||||
|
||||
private static void trackDroppedItem(Item item, String user) {
|
||||
if (item == null || user == null || user.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
long timestamp = System.currentTimeMillis();
|
||||
clearExpiredAttributions(timestamp);
|
||||
itemDropAttributions.put(item.getUniqueId(), new DropAttribution(user, timestamp + ITEM_DROP_ATTRIBUTION_MS));
|
||||
}
|
||||
|
||||
private static void clearExpiredAttributions(long timestamp) {
|
||||
itemDropAttributions.entrySet().removeIf(entry -> entry.getValue().expiresAt < timestamp);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
protected void onPlayerDropItem(PlayerDropItemEvent event) {
|
||||
Item item = event.getItemDrop();
|
||||
ItemStack itemStack = item.getItemStack();
|
||||
trackDroppedItem(item, event.getPlayer().getName());
|
||||
playerDropItem(item.getLocation(), event.getPlayer().getName(), itemStack);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user