mirror of
https://github.com/PlayPro/CoreProtect.git
synced 2025-01-29 22:51:21 +01:00
Added logging and rollback support for players crafting items
This commit is contained in:
parent
30c1921968
commit
5494bce0fc
@ -24,6 +24,7 @@ import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.Database;
|
||||
import net.coreprotect.database.Lookup;
|
||||
import net.coreprotect.database.logger.ItemLogger;
|
||||
import net.coreprotect.database.lookup.BlockLookup;
|
||||
import net.coreprotect.database.lookup.ChestTransactionLookup;
|
||||
import net.coreprotect.database.lookup.InteractionLookup;
|
||||
@ -890,6 +891,10 @@ public class LookupCommand {
|
||||
selector = Selector.SECOND;
|
||||
tag = Color.RED + "-";
|
||||
}
|
||||
else if (daction == ItemLogger.ITEM_BREAK || daction == ItemLogger.ITEM_DESTROY || daction == ItemLogger.ITEM_CREATE) {
|
||||
selector = (daction == ItemLogger.ITEM_CREATE ? Selector.FIRST : Selector.SECOND);
|
||||
tag = (daction == ItemLogger.ITEM_CREATE ? Color.GREEN + "+" : Color.RED + "-");
|
||||
}
|
||||
else { // LOOKUP_CONTAINER
|
||||
selector = (daction == 0 ? Selector.FIRST : Selector.SECOND);
|
||||
tag = (daction == 0 ? Color.GREEN + "+" : Color.RED + "-");
|
||||
|
@ -92,6 +92,9 @@ public class ConfigHandler extends Queue {
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsDrop = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsThrown = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsShot = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsBreak = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsDestroy = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsCreate = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, Object[]> hopperAbort = new ConcurrentHashMap<>();
|
||||
public static Map<String, List<ItemStack[]>> forceContainer = syncMap();
|
||||
public static Map<String, Integer> lookupType = syncMap();
|
||||
|
@ -18,7 +18,7 @@ class ItemTransactionProcess extends Queue {
|
||||
|
||||
if (ConfigHandler.loggingItem.get(loggingItemId) != null) {
|
||||
int current_chest = ConfigHandler.loggingItem.get(loggingItemId);
|
||||
if (ConfigHandler.itemsPickup.get(loggingItemId) == null && ConfigHandler.itemsDrop.get(loggingItemId) == null && ConfigHandler.itemsThrown.get(loggingItemId) == null && ConfigHandler.itemsShot.get(loggingItemId) == null) {
|
||||
if (ConfigHandler.itemsPickup.get(loggingItemId) == null && ConfigHandler.itemsDrop.get(loggingItemId) == null && ConfigHandler.itemsThrown.get(loggingItemId) == null && ConfigHandler.itemsShot.get(loggingItemId) == null && ConfigHandler.itemsBreak.get(loggingItemId) == null && ConfigHandler.itemsDestroy.get(loggingItemId) == null && ConfigHandler.itemsCreate.get(loggingItemId) == null) {
|
||||
return;
|
||||
}
|
||||
if (current_chest == forceData) {
|
||||
@ -29,6 +29,9 @@ class ItemTransactionProcess extends Queue {
|
||||
ConfigHandler.itemsDrop.remove(loggingItemId);
|
||||
ConfigHandler.itemsThrown.remove(loggingItemId);
|
||||
ConfigHandler.itemsShot.remove(loggingItemId);
|
||||
ConfigHandler.itemsBreak.remove(loggingItemId);
|
||||
ConfigHandler.itemsDestroy.remove(loggingItemId);
|
||||
ConfigHandler.itemsCreate.remove(loggingItemId);
|
||||
ConfigHandler.loggingItem.remove(loggingItemId);
|
||||
}
|
||||
else {
|
||||
|
@ -304,6 +304,7 @@ public class Lookup extends Queue {
|
||||
String queryLimit = "";
|
||||
String queryTable = "block";
|
||||
String action = "";
|
||||
String actionExclude = "";
|
||||
String includeBlock = "";
|
||||
String includeEntity = "";
|
||||
String excludeBlock = "";
|
||||
@ -445,6 +446,15 @@ public class Lookup extends Queue {
|
||||
excludeUsers = excludeUserText.toString();
|
||||
}
|
||||
|
||||
// Specify actions to exclude from a:item
|
||||
if ((lookup && actionList.size() == 0) || (actionList.contains(11) && actionList.size() == 1)) {
|
||||
StringBuilder actionText = new StringBuilder();
|
||||
actionText = actionText.append(ItemLogger.ITEM_BREAK);
|
||||
actionText.append(",").append(ItemLogger.ITEM_DESTROY);
|
||||
actionText.append(",").append(ItemLogger.ITEM_CREATE);
|
||||
actionExclude = actionText.toString();
|
||||
}
|
||||
|
||||
if (!actionList.isEmpty()) {
|
||||
StringBuilder actionText = new StringBuilder();
|
||||
for (Integer actionTarget : actionList) {
|
||||
@ -471,12 +481,15 @@ public class Lookup extends Queue {
|
||||
if (actionTarget == ItemLogger.ITEM_REMOVE) {
|
||||
actionText.append(",").append(ItemLogger.ITEM_PICKUP);
|
||||
actionText.append(",").append(ItemLogger.ITEM_REMOVE_ENDER);
|
||||
actionText.append(",").append(ItemLogger.ITEM_CREATE);
|
||||
}
|
||||
if (actionTarget == ItemLogger.ITEM_ADD) {
|
||||
actionText.append(",").append(ItemLogger.ITEM_DROP);
|
||||
actionText.append(",").append(ItemLogger.ITEM_ADD_ENDER);
|
||||
actionText.append(",").append(ItemLogger.ITEM_THROW);
|
||||
actionText.append(",").append(ItemLogger.ITEM_SHOOT);
|
||||
actionText.append(",").append(ItemLogger.ITEM_BREAK);
|
||||
actionText.append(",").append(ItemLogger.ITEM_DESTROY);
|
||||
}
|
||||
}
|
||||
// If just looking up drops/pickups, include ender chest transactions
|
||||
@ -535,7 +548,7 @@ public class Lookup extends Queue {
|
||||
if (validAction) {
|
||||
queryBlock = queryBlock + " action IN(" + action + ") AND";
|
||||
}
|
||||
else if (inventoryQuery || includeBlock.length() > 0 || includeEntity.length() > 0 || excludeBlock.length() > 0 || excludeEntity.length() > 0) {
|
||||
else if (inventoryQuery || actionExclude.length() > 0 || includeBlock.length() > 0 || includeEntity.length() > 0 || excludeBlock.length() > 0 || excludeEntity.length() > 0) {
|
||||
queryBlock = queryBlock + " action NOT IN(-1) AND";
|
||||
}
|
||||
|
||||
@ -708,10 +721,19 @@ public class Lookup extends Queue {
|
||||
rows = "rowid as id,time,user,wid,x,y,z,type,data as metadata,0 as data,amount,action,rolled_back";
|
||||
queryOrder = " ORDER BY time DESC, tbl DESC, id DESC";
|
||||
}
|
||||
|
||||
if (actionExclude.length() > 0) {
|
||||
queryBlock = queryBlock.replace("action NOT IN(-1)", "action NOT IN(" + actionExclude + ")");
|
||||
}
|
||||
|
||||
query = query + unionSelect + "SELECT " + "'2' as tbl," + rows + " FROM " + ConfigHandler.prefix + "item WHERE" + queryBlock + unionLimit + ")";
|
||||
}
|
||||
|
||||
if (query.length() == 0) {
|
||||
if (actionExclude.length() > 0) {
|
||||
baseQuery = baseQuery.replace("action NOT IN(-1)", "action NOT IN(" + actionExclude + ")");
|
||||
}
|
||||
|
||||
query = "SELECT " + "'0' as tbl," + rows + " FROM " + ConfigHandler.prefix + queryTable + " " + index + "WHERE" + baseQuery;
|
||||
}
|
||||
|
||||
|
@ -1071,8 +1071,8 @@ public class Rollback extends Queue {
|
||||
}
|
||||
|
||||
int inventoryAction = 0;
|
||||
if (rowAction == ItemLogger.ITEM_DROP || rowAction == ItemLogger.ITEM_PICKUP || rowAction == ItemLogger.ITEM_THROW || rowAction == ItemLogger.ITEM_SHOOT) {
|
||||
inventoryAction = (rowAction == ItemLogger.ITEM_PICKUP ? 1 : 0);
|
||||
if (rowAction == ItemLogger.ITEM_DROP || rowAction == ItemLogger.ITEM_PICKUP || rowAction == ItemLogger.ITEM_THROW || rowAction == ItemLogger.ITEM_SHOOT || rowAction == ItemLogger.ITEM_BREAK || rowAction == ItemLogger.ITEM_DESTROY || rowAction == ItemLogger.ITEM_CREATE) {
|
||||
inventoryAction = ((rowAction == ItemLogger.ITEM_PICKUP || rowAction == ItemLogger.ITEM_CREATE) ? 1 : 0);
|
||||
}
|
||||
else if (rowAction == ItemLogger.ITEM_REMOVE_ENDER || rowAction == ItemLogger.ITEM_ADD_ENDER) {
|
||||
inventoryAction = (rowAction == ItemLogger.ITEM_REMOVE_ENDER ? 1 : 0);
|
||||
|
@ -27,6 +27,9 @@ public class ItemLogger {
|
||||
public static final int ITEM_ADD_ENDER = 5;
|
||||
public static final int ITEM_THROW = 6;
|
||||
public static final int ITEM_SHOOT = 7;
|
||||
public static final int ITEM_BREAK = 8;
|
||||
public static final int ITEM_DESTROY = 9;
|
||||
public static final int ITEM_CREATE = 10;
|
||||
|
||||
private ItemLogger() {
|
||||
throw new IllegalStateException("Database class");
|
||||
@ -60,14 +63,35 @@ public class ItemLogger {
|
||||
itemShots = shotList.toArray(itemShots);
|
||||
shotList.clear();
|
||||
|
||||
List<ItemStack> breakList = ConfigHandler.itemsBreak.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
ItemStack[] itemBreaks = new ItemStack[breakList.size()];
|
||||
itemBreaks = breakList.toArray(itemBreaks);
|
||||
breakList.clear();
|
||||
|
||||
List<ItemStack> destroyList = ConfigHandler.itemsDestroy.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
ItemStack[] itemDestroys = new ItemStack[destroyList.size()];
|
||||
itemDestroys = destroyList.toArray(itemDestroys);
|
||||
destroyList.clear();
|
||||
|
||||
List<ItemStack> createList = ConfigHandler.itemsCreate.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
ItemStack[] itemCreates = new ItemStack[createList.size()];
|
||||
itemCreates = createList.toArray(itemCreates);
|
||||
createList.clear();
|
||||
|
||||
Util.mergeItems(null, itemPickups);
|
||||
Util.mergeItems(null, itemDrops);
|
||||
Util.mergeItems(null, itemThrows);
|
||||
Util.mergeItems(null, itemShots);
|
||||
Util.mergeItems(null, itemBreaks);
|
||||
Util.mergeItems(null, itemDestroys);
|
||||
Util.mergeItems(null, itemCreates);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemPickups, ITEM_PICKUP);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemDrops, ITEM_DROP);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemThrows, ITEM_THROW);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemShots, ITEM_SHOOT);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemBreaks, ITEM_BREAK);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemDestroys, ITEM_DESTROY);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemCreates, ITEM_CREATE);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -28,6 +28,7 @@ import net.coreprotect.listener.entity.HangingBreakByEntityListener;
|
||||
import net.coreprotect.listener.entity.HangingBreakListener;
|
||||
import net.coreprotect.listener.entity.HangingPlaceListener;
|
||||
import net.coreprotect.listener.player.ArmorStandManipulateListener;
|
||||
import net.coreprotect.listener.player.CraftItemListener;
|
||||
import net.coreprotect.listener.player.FoodLevelChangeListener;
|
||||
import net.coreprotect.listener.player.InventoryChangeListener;
|
||||
import net.coreprotect.listener.player.PlayerBucketEmptyListener;
|
||||
@ -83,8 +84,9 @@ public final class ListenerHandler {
|
||||
pluginManager.registerEvents(new HangingBreakByEntityListener(), plugin);
|
||||
|
||||
// Player Listeners
|
||||
pluginManager.registerEvents(new InventoryChangeListener(), plugin);
|
||||
pluginManager.registerEvents(new ArmorStandManipulateListener(), plugin);
|
||||
pluginManager.registerEvents(new CraftItemListener(), plugin);
|
||||
pluginManager.registerEvents(new InventoryChangeListener(), plugin);
|
||||
pluginManager.registerEvents(new PlayerBucketEmptyListener(), plugin);
|
||||
pluginManager.registerEvents(new PlayerBucketFillListener(), plugin);
|
||||
pluginManager.registerEvents(new PlayerCommandListener(), plugin);
|
||||
|
@ -0,0 +1,131 @@
|
||||
package net.coreprotect.listener.player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event.Result;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.CraftItemEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.CraftingInventory;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.ShapedRecipe;
|
||||
import org.bukkit.inventory.ShapelessRecipe;
|
||||
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.database.logger.ItemLogger;
|
||||
|
||||
public final class CraftItemListener extends Queue implements Listener {
|
||||
|
||||
protected static void playerCraftItem(Location location, String user, ItemStack itemStack, int action) {
|
||||
if (!Config.getConfig(location.getWorld()).ITEM_TRANSACTIONS || itemStack == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String loggingItemId = user.toLowerCase(Locale.ROOT) + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
|
||||
int itemId = getItemId(loggingItemId);
|
||||
|
||||
if (action == ItemLogger.ITEM_CREATE) {
|
||||
List<ItemStack> list = ConfigHandler.itemsCreate.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
list.add(itemStack);
|
||||
ConfigHandler.itemsCreate.put(loggingItemId, list);
|
||||
}
|
||||
else {
|
||||
List<ItemStack> list = ConfigHandler.itemsDestroy.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
list.add(itemStack);
|
||||
ConfigHandler.itemsDestroy.put(loggingItemId, list);
|
||||
}
|
||||
|
||||
int time = (int) (System.currentTimeMillis() / 1000L) + 1;
|
||||
Queue.queueItemTransaction(user, location.clone(), time, 0, itemId);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
protected void onCraftItem(CraftItemEvent event) {
|
||||
if (event.getResult() == Result.DENY) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
if (event.getClick() == ClickType.NUMBER_KEY && player.getInventory().getItem(event.getHotbarButton()) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((event.getClick() == ClickType.DROP || event.getClick() == ClickType.CONTROL_DROP) && event.getCursor().getType() != Material.AIR) {
|
||||
return;
|
||||
}
|
||||
|
||||
CraftingInventory craftingInventory = event.getInventory();
|
||||
if (craftingInventory.getResult() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Inventory bottomInventory = event.getView().getBottomInventory();
|
||||
if (bottomInventory.getType() != InventoryType.PLAYER) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack addItem = event.getRecipe().getResult().clone();
|
||||
int amount = addItem.getAmount();
|
||||
if (amount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int amountMultiplier = 1;
|
||||
if (event.getClick() == ClickType.SHIFT_LEFT || event.getClick() == ClickType.SHIFT_RIGHT) {
|
||||
int newMultiplier = Integer.MIN_VALUE;
|
||||
for (ItemStack item : craftingInventory.getMatrix()) {
|
||||
if (item != null && (newMultiplier == Integer.MIN_VALUE || item.getAmount() < newMultiplier)) {
|
||||
newMultiplier = item.getAmount();
|
||||
}
|
||||
}
|
||||
amountMultiplier = (newMultiplier == Integer.MIN_VALUE ? 1 : newMultiplier);
|
||||
|
||||
int addAmount = amount * amountMultiplier;
|
||||
Inventory virtualInventory = Bukkit.createInventory(null, 36);
|
||||
virtualInventory.setStorageContents(bottomInventory.getStorageContents());
|
||||
addItem.setAmount(addAmount);
|
||||
|
||||
HashMap<Integer, ItemStack> result = virtualInventory.addItem(addItem);
|
||||
for (ItemStack itemFailed : result.values()) {
|
||||
if (itemFailed.isSimilar(addItem)) {
|
||||
addAmount = (int) (Math.ceil((addAmount - itemFailed.getAmount()) / (double) amount) * amount);
|
||||
amountMultiplier = addAmount / amount;
|
||||
}
|
||||
}
|
||||
virtualInventory.clear();
|
||||
addItem.setAmount(addAmount);
|
||||
}
|
||||
|
||||
List<ItemStack> oldItems = new ArrayList<>();
|
||||
if (event.getRecipe() instanceof ShapelessRecipe) {
|
||||
oldItems.addAll(((ShapelessRecipe) event.getRecipe()).getIngredientList());
|
||||
}
|
||||
if (event.getRecipe() instanceof ShapedRecipe) {
|
||||
oldItems.addAll(((ShapedRecipe) event.getRecipe()).getIngredientMap().values());
|
||||
}
|
||||
|
||||
if (addItem.getAmount() > 0) {
|
||||
for (ItemStack oldItem : oldItems) {
|
||||
ItemStack removedItem = oldItem.clone();
|
||||
removedItem.setAmount(oldItem.getAmount() * amountMultiplier);
|
||||
playerCraftItem(player.getLocation(), player.getName(), removedItem, ItemLogger.ITEM_DESTROY);
|
||||
}
|
||||
|
||||
playerCraftItem(player.getLocation(), player.getName(), addItem, ItemLogger.ITEM_CREATE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user