From b41e40acc07eeecaf5c7371f4195fe0b22bc4f1f Mon Sep 17 00:00:00 2001 From: Intelli Date: Sun, 12 May 2024 12:16:48 -0600 Subject: [PATCH] Minor refactoring on Rollback class --- .../java/net/coreprotect/CoreProtectAPI.java | 2 +- .../command/RollbackRestoreCommand.java | 2 +- .../database/ContainerRollback.java | 6 +- .../java/net/coreprotect/database/Lookup.java | 4 +- .../database/{ => rollback}/Rollback.java | 757 +----------------- .../database/rollback/RollbackComplete.java | 306 +++++++ .../database/rollback/RollbackUtil.java | 487 +++++++++++ .../java/net/coreprotect/utility/Util.java | 2 +- .../utility/entity/EntityUtil.java | 2 +- 9 files changed, 807 insertions(+), 761 deletions(-) rename src/main/java/net/coreprotect/database/{ => rollback}/Rollback.java (69%) create mode 100644 src/main/java/net/coreprotect/database/rollback/RollbackComplete.java create mode 100644 src/main/java/net/coreprotect/database/rollback/RollbackUtil.java diff --git a/src/main/java/net/coreprotect/CoreProtectAPI.java b/src/main/java/net/coreprotect/CoreProtectAPI.java index e76502f1..2235f72b 100755 --- a/src/main/java/net/coreprotect/CoreProtectAPI.java +++ b/src/main/java/net/coreprotect/CoreProtectAPI.java @@ -25,7 +25,7 @@ import net.coreprotect.consumer.Queue; import net.coreprotect.database.Database; import net.coreprotect.database.Lookup; -import net.coreprotect.database.Rollback; +import net.coreprotect.database.rollback.Rollback; import net.coreprotect.language.Phrase; import net.coreprotect.listener.player.InventoryChangeListener; import net.coreprotect.utility.Chat; diff --git a/src/main/java/net/coreprotect/command/RollbackRestoreCommand.java b/src/main/java/net/coreprotect/command/RollbackRestoreCommand.java index 856c4376..2c98a145 100755 --- a/src/main/java/net/coreprotect/command/RollbackRestoreCommand.java +++ b/src/main/java/net/coreprotect/command/RollbackRestoreCommand.java @@ -23,8 +23,8 @@ import net.coreprotect.config.ConfigHandler; import net.coreprotect.database.ContainerRollback; import net.coreprotect.database.Database; -import net.coreprotect.database.Rollback; import net.coreprotect.database.lookup.PlayerLookup; +import net.coreprotect.database.rollback.Rollback; import net.coreprotect.language.Phrase; import net.coreprotect.language.Selector; import net.coreprotect.utility.Chat; diff --git a/src/main/java/net/coreprotect/database/ContainerRollback.java b/src/main/java/net/coreprotect/database/ContainerRollback.java index 61ea742c..df61d23a 100644 --- a/src/main/java/net/coreprotect/database/ContainerRollback.java +++ b/src/main/java/net/coreprotect/database/ContainerRollback.java @@ -21,13 +21,15 @@ import net.coreprotect.config.ConfigHandler; import net.coreprotect.consumer.Queue; import net.coreprotect.consumer.process.Process; +import net.coreprotect.database.rollback.Rollback; +import net.coreprotect.database.rollback.RollbackComplete; import net.coreprotect.language.Phrase; import net.coreprotect.model.BlockGroup; import net.coreprotect.thread.Scheduler; import net.coreprotect.utility.Chat; import net.coreprotect.utility.Util; -public class ContainerRollback extends Queue { +public class ContainerRollback extends Rollback { public static void performContainerRollbackRestore(Statement statement, CommandSender user, List checkUuids, List checkUsers, String timeString, List restrictList, Map excludeList, List excludeUserList, List actionList, final Location location, Integer[] radius, long startTime, long endTime, boolean restrictWorld, boolean lookup, boolean verbose, final int rollbackType) { try { @@ -176,7 +178,7 @@ else if (entity instanceof ItemFrame) { int itemCount = 0; int entityCount = 0; - Rollback.finishRollbackRestore(user, location, checkUsers, restrictList, excludeList, excludeUserList, actionList, timeString, file, totalSeconds, itemCount, blockCount, entityCount, rollbackType, radius, verbose, restrictWorld, 0); + RollbackComplete.output(user, location, checkUsers, restrictList, excludeList, excludeUserList, actionList, timeString, file, totalSeconds, itemCount, blockCount, entityCount, rollbackType, radius, verbose, restrictWorld, 0); } } catch (Exception e) { diff --git a/src/main/java/net/coreprotect/database/Lookup.java b/src/main/java/net/coreprotect/database/Lookup.java index 93b9b2b9..1668464a 100755 --- a/src/main/java/net/coreprotect/database/Lookup.java +++ b/src/main/java/net/coreprotect/database/Lookup.java @@ -29,7 +29,7 @@ public class Lookup extends Queue { - static List convertRawLookup(Statement statement, List list) { + protected static List convertRawLookup(Statement statement, List list) { List newList = new ArrayList<>(); if (list == null) { @@ -122,7 +122,7 @@ public static List performLookup(Statement statement, CommandSender us return newList; } - static List performLookupRaw(Statement statement, CommandSender user, List checkUuids, List checkUsers, List restrictList, Map excludeList, List excludeUserList, List actionList, Location location, Integer[] radius, Long[] rowData, long startTime, long endTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup) { + protected static List performLookupRaw(Statement statement, CommandSender user, List checkUuids, List checkUsers, List restrictList, Map excludeList, List excludeUserList, List actionList, Location location, Integer[] radius, Long[] rowData, long startTime, long endTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup) { List list = new ArrayList<>(); List invalidRollbackActions = new ArrayList<>(); invalidRollbackActions.add(2); diff --git a/src/main/java/net/coreprotect/database/Rollback.java b/src/main/java/net/coreprotect/database/rollback/Rollback.java similarity index 69% rename from src/main/java/net/coreprotect/database/Rollback.java rename to src/main/java/net/coreprotect/database/rollback/Rollback.java index 1dabe44b..666f4623 100644 --- a/src/main/java/net/coreprotect/database/Rollback.java +++ b/src/main/java/net/coreprotect/database/rollback/Rollback.java @@ -1,10 +1,7 @@ -package net.coreprotect.database; +package net.coreprotect.database.rollback; import java.io.ByteArrayInputStream; -import java.math.BigDecimal; -import java.math.RoundingMode; import java.sql.Statement; -import java.text.NumberFormat; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -20,14 +17,9 @@ import org.bukkit.Bukkit; import org.bukkit.DyeColor; -import org.bukkit.FireworkEffect; -import org.bukkit.FireworkEffect.Builder; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.Tag; import org.bukkit.World; -import org.bukkit.attribute.Attribute; -import org.bukkit.attribute.AttributeModifier; import org.bukkit.block.Banner; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -35,7 +27,6 @@ import org.bukkit.block.CommandBlock; import org.bukkit.block.CreatureSpawner; import org.bukkit.block.Jukebox; -import org.bukkit.block.ShulkerBox; import org.bukkit.block.banner.Pattern; import org.bukkit.block.data.Bisected; import org.bukkit.block.data.Bisected.Half; @@ -65,18 +56,6 @@ import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; -import org.bukkit.inventory.meta.BannerMeta; -import org.bukkit.inventory.meta.BlockStateMeta; -import org.bukkit.inventory.meta.CrossbowMeta; -import org.bukkit.inventory.meta.FireworkEffectMeta; -import org.bukkit.inventory.meta.FireworkMeta; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.LeatherArmorMeta; -import org.bukkit.inventory.meta.MapMeta; -import org.bukkit.inventory.meta.PotionMeta; -import org.bukkit.inventory.meta.SuspiciousStewMeta; -import org.bukkit.potion.PotionEffect; import org.bukkit.util.io.BukkitObjectInputStream; import net.coreprotect.CoreProtect; @@ -85,6 +64,7 @@ import net.coreprotect.config.ConfigHandler; import net.coreprotect.consumer.Queue; import net.coreprotect.consumer.process.Process; +import net.coreprotect.database.Lookup; import net.coreprotect.database.logger.ItemLogger; import net.coreprotect.database.statement.UserStatement; import net.coreprotect.language.Phrase; @@ -100,7 +80,7 @@ import net.coreprotect.utility.Util; import net.coreprotect.utility.entity.HangingUtil; -public class Rollback extends Queue { +public class Rollback extends RollbackUtil { public static List performRollbackRestore(Statement statement, CommandSender user, List checkUuids, List checkUsers, String timeString, List restrictList, Map excludeList, List excludeUserList, List actionList, Location location, Integer[] radius, long startTime, long endTime, boolean restrictWorld, boolean lookup, boolean verbose, final int rollbackType, final int preview) { List list = new ArrayList<>(); @@ -1337,7 +1317,7 @@ else if (entity instanceof ItemFrame) { double totalSeconds = (timeFinish - timeStart) / 1000.0; if (user != null) { - finishRollbackRestore(user, location, checkUsers, restrictList, excludeList, excludeUserList, actionList, timeString, chunkCount, totalSeconds, itemCount, blockCount, entityCount, rollbackType, radius, verbose, restrictWorld, preview); + RollbackComplete.output(user, location, checkUsers, restrictList, excludeList, excludeUserList, actionList, timeString, chunkCount, totalSeconds, itemCount, blockCount, entityCount, rollbackType, radius, verbose, restrictWorld, preview); } list = Lookup.convertRawLookup(statement, lookupList); @@ -1350,733 +1330,4 @@ else if (entity instanceof ItemFrame) { return null; } - static void finishRollbackRestore(CommandSender user, Location location, List checkUsers, List restrictList, Map excludeList, List excludeUserList, List actionList, String timeString, Integer chunkCount, Double seconds, Integer itemCount, Integer blockCount, Integer entityCount, int rollbackType, Integer[] radius, boolean verbose, boolean restrictWorld, int preview) { - try { - if (preview == 2) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_CANCELLED)); - return; - } - - Chat.sendMessage(user, "-----"); - - StringBuilder usersBuilder = new StringBuilder(); - for (String value : checkUsers) { - if (usersBuilder.length() == 0) { - usersBuilder = usersBuilder.append("" + value + ""); - } - else { - usersBuilder.append(", ").append(value); - } - } - String users = usersBuilder.toString(); - - if (users.equals("#global") && restrictWorld) { - users = "#" + location.getWorld().getName(); - } - - if (preview > 0) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_COMPLETED, users, Selector.THIRD)); // preview - } - else if (rollbackType == 0) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_COMPLETED, users, Selector.FIRST)); // rollback - } - else if (rollbackType == 1) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_COMPLETED, users, Selector.SECOND)); // restore - } - - if (preview == 1 || rollbackType == 0 || rollbackType == 1) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_TIME, timeString)); - } - - if (radius != null) { - int worldedit = radius[7]; - if (worldedit == 0) { - Integer rollbackRadius = radius[0]; - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_RADIUS, rollbackRadius.toString(), (rollbackRadius == 1 ? Selector.FIRST : Selector.SECOND))); - } - else { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_SELECTION, "#worldedit")); - } - } - - if (restrictWorld && radius == null) { - if (location != null) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, location.getWorld().getName(), Selector.FIRST)); - } - } - - if (actionList.contains(4) && actionList.contains(11)) { - if (actionList.contains(0)) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "+inventory", Selector.SECOND)); - } - else if (actionList.contains(1)) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "-inventory", Selector.SECOND)); - } - else { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "inventory", Selector.SECOND)); - } - } - else if (actionList.contains(4)) { - if (actionList.contains(0)) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "-container", Selector.SECOND)); - } - else if (actionList.contains(1)) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "+container", Selector.SECOND)); - } - else { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "container", Selector.SECOND)); - } - } - else if (actionList.contains(0) && actionList.contains(1)) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "block", Selector.SECOND)); - } - else if (actionList.contains(0)) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "-block", Selector.SECOND)); - } - else if (actionList.contains(1)) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "+block", Selector.SECOND)); - } - else if (actionList.contains(3)) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "kill", Selector.SECOND)); - } - - if (restrictList.size() > 0) { - StringBuilder restrictTargets = new StringBuilder(); - boolean material = false; - boolean item = false; - boolean entity = false; - - int targetCount = 0; - for (Object restrictTarget : restrictList) { - String targetName = ""; - - if (restrictTarget instanceof Material) { - targetName = ((Material) restrictTarget).name().toLowerCase(Locale.ROOT); - item = (!item ? !(((Material) restrictTarget).isBlock()) : item); - material = true; - } - else if (restrictTarget instanceof EntityType) { - targetName = ((EntityType) restrictTarget).name().toLowerCase(Locale.ROOT); - entity = true; - } - - if (targetCount == 0) { - restrictTargets = restrictTargets.append("" + targetName + ""); - } - else { - restrictTargets.append(", ").append(targetName); - } - - targetCount++; - } - - String targetType = Selector.THIRD; - if (material && !item && !entity) { - targetType = Selector.FIRST; - } - else if (material && item && !entity) { - targetType = Selector.THIRD; - } - else if (entity && !material) { - targetType = Selector.SECOND; - } - - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_INCLUDE, restrictTargets.toString(), Selector.FIRST, targetType, (targetCount == 1 ? Selector.FIRST : Selector.SECOND))); // include - } - - if (excludeList.size() > 0) { - StringBuilder excludeTargets = new StringBuilder(); - boolean material = false; - boolean item = false; - boolean entity = false; - - int excludeCount = 0; - for (Map.Entry entry : excludeList.entrySet()) { - Object excludeTarget = entry.getKey(); - Boolean excludeTargetInternal = entry.getValue(); - - // don't display default block excludes - if (Boolean.TRUE.equals(excludeTargetInternal)) { - continue; - } - - // don't display that excluded water/fire/farmland in inventory rollbacks - if (actionList.contains(4) && actionList.contains(11)) { - if (excludeTarget.equals(Material.FIRE) || excludeTarget.equals(Material.WATER) || excludeTarget.equals(Material.FARMLAND)) { - continue; - } - } - - String targetName = ""; - if (excludeTarget instanceof Material) { - targetName = ((Material) excludeTarget).name().toLowerCase(Locale.ROOT); - item = (!item ? !(((Material) excludeTarget).isBlock()) : item); - material = true; - } - else if (excludeTarget instanceof EntityType) { - targetName = ((EntityType) excludeTarget).name().toLowerCase(Locale.ROOT); - entity = true; - } - - if (excludeCount == 0) { - excludeTargets = excludeTargets.append("" + targetName + ""); - } - else { - excludeTargets.append(", ").append(targetName); - } - - excludeCount++; - } - - String targetType = Selector.THIRD; - if (material && !item && !entity) { - targetType = Selector.FIRST; - } - else if (material && item && !entity) { - targetType = Selector.THIRD; - } - else if (entity && !material) { - targetType = Selector.SECOND; - } - - if (excludeCount > 0) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_INCLUDE, excludeTargets.toString(), Selector.SECOND, targetType, (excludeCount == 1 ? Selector.FIRST : Selector.SECOND))); // exclude - } - } - - if (excludeUserList.size() > 0) { - StringBuilder excludeUsers = new StringBuilder(); - - int excludeCount = 0; - for (String excludeUser : excludeUserList) { - // don't display that excluded #hopper in inventory rollbacks - if (actionList.contains(4) && actionList.contains(11)) { - if (excludeUser.equals("#hopper")) { - continue; - } - } - - if (excludeCount == 0) { - excludeUsers = excludeUsers.append("" + excludeUser + ""); - } - else { - excludeUsers.append(", ").append(excludeUser); - } - - excludeCount++; - } - - if (excludeCount > 0) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_EXCLUDED_USERS, excludeUsers.toString(), (excludeCount == 1 ? Selector.FIRST : Selector.SECOND))); - } - } - - StringBuilder modifiedData = new StringBuilder(); - Integer modifyCount = 0; - if (actionList.contains(5)) { - modifiedData = modifiedData.append(Phrase.build(Phrase.AMOUNT_ITEM, NumberFormat.getInstance().format(blockCount), (blockCount == 1 ? Selector.FIRST : Selector.SECOND))); - modifyCount++; - } - else { - if (itemCount > 0 || actionList.contains(4)) { - modifiedData = modifiedData.append(Phrase.build(Phrase.AMOUNT_ITEM, NumberFormat.getInstance().format(itemCount), (itemCount == 1 ? Selector.FIRST : Selector.SECOND))); - modifyCount++; - } - - if (entityCount > 0) { - if (modifyCount > 0) { - modifiedData.append(", "); - } - modifiedData.append(Phrase.build(Phrase.AMOUNT_ENTITY, NumberFormat.getInstance().format(entityCount), (entityCount == 1 ? Selector.FIRST : Selector.SECOND))); - modifyCount++; - } - - if (blockCount > 0 || !actionList.contains(4) || preview > 0) { - if (modifyCount > 0) { - modifiedData.append(", "); - } - modifiedData.append(Phrase.build(Phrase.AMOUNT_BLOCK, NumberFormat.getInstance().format(blockCount), (blockCount == 1 ? Selector.FIRST : Selector.SECOND))); - modifyCount++; - } - } - - StringBuilder modifiedDataVerbose = new StringBuilder(); - if (verbose && preview == 0 && !actionList.contains(11)) { - if (chunkCount > -1 && modifyCount < 3) { - if (modifyCount > 0) { - modifiedData.append(", "); - } - modifiedData.append(Phrase.build(Phrase.AMOUNT_CHUNK, NumberFormat.getInstance().format(chunkCount), (chunkCount == 1 ? Selector.FIRST : Selector.SECOND))); - modifyCount++; - } - else if (chunkCount > 1) { - modifiedDataVerbose.append(Phrase.build(Phrase.AMOUNT_CHUNK, NumberFormat.getInstance().format(chunkCount), (chunkCount == 1 ? Selector.FIRST : Selector.SECOND))); - } - } - - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_MODIFIED, modifiedData.toString(), (preview == 0 ? Selector.FIRST : Selector.SECOND))); - if (modifiedDataVerbose.length() > 0) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_MODIFIED, modifiedDataVerbose.toString(), (preview == 0 ? Selector.FIRST : Selector.SECOND))); - } - - if (preview == 0) { - BigDecimal decimalSeconds = new BigDecimal(seconds).setScale(1, RoundingMode.HALF_EVEN); - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_LENGTH, decimalSeconds.stripTrailingZeros().toPlainString(), (decimalSeconds.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND))); - } - - Chat.sendMessage(user, "-----"); - if (preview > 0) { - Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PLEASE_SELECT, "/co apply", "/co cancel")); - } - } - catch (Exception e) { - e.printStackTrace(); - } - } - - static int modifyContainerItems(Material type, Object container, int slot, ItemStack itemstack, int action) { - int modifiedArmor = -1; - try { - ItemStack[] contents = null; - - if (type != null && type.equals(Material.ARMOR_STAND)) { - EntityEquipment equipment = (EntityEquipment) container; - if (equipment != null) { - if (action == 1) { - itemstack.setAmount(1); - } - else { - itemstack.setType(Material.AIR); - itemstack.setAmount(0); - } - - if (slot < 4) { - contents = equipment.getArmorContents(); - if (slot >= 0) { - contents[slot] = itemstack; - } - equipment.setArmorContents(contents); - } - else { - ArmorStand armorStand = (ArmorStand) equipment.getHolder(); - armorStand.setArms(true); - switch (slot) { - case 4: - equipment.setItemInMainHand(itemstack); - break; - case 5: - equipment.setItemInOffHand(itemstack); - break; - } - } - } - } - else if (type != null && type.equals(Material.ITEM_FRAME)) { - ItemFrame frame = (ItemFrame) container; - if (frame != null) { - if (action == 1) { - itemstack.setAmount(1); - } - else { - itemstack.setType(Material.AIR); - itemstack.setAmount(0); - } - - frame.setItem(itemstack); - } - } - else if (type != null && type.equals(Material.JUKEBOX)) { - Jukebox jukebox = (Jukebox) container; - if (jukebox != null) { - if (action == 1 && Tag.ITEMS_MUSIC_DISCS.isTagged(itemstack.getType())) { - itemstack.setAmount(1); - } - else { - itemstack.setType(Material.AIR); - itemstack.setAmount(0); - } - - jukebox.setRecord(itemstack); - jukebox.update(); - } - } - else { - Inventory inventory = (Inventory) container; - if (inventory != null) { - boolean isPlayerInventory = (inventory instanceof PlayerInventory); - if (action == 1) { - int count = 0; - int amount = itemstack.getAmount(); - itemstack.setAmount(1); - - while (count < amount) { - boolean addedItem = false; - if (isPlayerInventory) { - int setArmor = Util.setPlayerArmor((PlayerInventory) inventory, itemstack); - addedItem = (setArmor > -1); - modifiedArmor = addedItem ? setArmor : modifiedArmor; - } - if (!addedItem) { - if (BukkitAdapter.ADAPTER.isChiseledBookshelf(type)) { - ItemStack[] inventoryContents = inventory.getStorageContents(); - int i = 0; - for (ItemStack stack : inventoryContents) { - if (stack == null) { - inventoryContents[i] = itemstack; - addedItem = true; - break; - } - i++; - } - if (addedItem) { - inventory.setStorageContents(inventoryContents); - } - else { - addedItem = (inventory.addItem(itemstack).size() == 0); - } - } - else { - addedItem = (inventory.addItem(itemstack).size() == 0); - } - } - if (!addedItem && isPlayerInventory) { - PlayerInventory playerInventory = (PlayerInventory) inventory; - ItemStack offhand = playerInventory.getItemInOffHand(); - if (offhand == null || offhand.getType() == Material.AIR || (itemstack.isSimilar(offhand) && offhand.getAmount() < offhand.getMaxStackSize())) { - ItemStack setOffhand = itemstack.clone(); - if (itemstack.isSimilar(offhand)) { - setOffhand.setAmount(offhand.getAmount() + 1); - } - - playerInventory.setItemInOffHand(setOffhand); - } - } - count++; - } - } - else { - int removeAmount = itemstack.getAmount(); - ItemStack removeMatch = itemstack.clone(); - removeMatch.setAmount(1); - - ItemStack[] inventoryContents = (isPlayerInventory ? inventory.getContents() : inventory.getStorageContents()).clone(); - for (int i = inventoryContents.length - 1; i >= 0; i--) { - if (inventoryContents[i] != null) { - ItemStack itemStack = inventoryContents[i].clone(); - int maxAmount = itemStack.getAmount(); - int currentAmount = maxAmount; - itemStack.setAmount(1); - - if (itemStack.toString().equals(removeMatch.toString())) { - for (int scan = 0; scan < maxAmount; scan++) { - if (removeAmount > 0) { - currentAmount--; - itemStack.setAmount(currentAmount); - removeAmount--; - } - else { - break; - } - } - } - else { - itemStack.setAmount(maxAmount); - } - - if (itemStack.getAmount() == 0) { - inventoryContents[i] = null; - } - else { - inventoryContents[i] = itemStack; - } - } - - if (removeAmount == 0) { - break; - } - } - - if (isPlayerInventory) { - inventory.setContents(inventoryContents); - } - else { - inventory.setStorageContents(inventoryContents); - } - - int count = 0; - while (count < removeAmount) { - inventory.removeItem(removeMatch); - count++; - } - } - } - } - } - catch (Exception e) { - e.printStackTrace(); - } - - return modifiedArmor; - } - - public static void sortContainerItems(PlayerInventory inventory, List modifiedArmorSlots) { - try { - ItemStack[] armorContents = inventory.getArmorContents(); - ItemStack[] storageContents = inventory.getStorageContents(); - - for (int armor = 0; armor < armorContents.length; armor++) { - ItemStack armorItem = armorContents[armor]; - if (armorItem == null || !modifiedArmorSlots.contains(armor)) { - continue; - } - - for (int storage = 0; storage < storageContents.length; storage++) { - ItemStack storageItem = storageContents[storage]; - if (storageItem == null) { - storageContents[storage] = armorItem; - armorContents[armor] = null; - break; - } - } - } - - inventory.setArmorContents(armorContents); - inventory.setStorageContents(storageContents); - } - catch (Exception e) { - e.printStackTrace(); - } - } - - private static void buildFireworkEffect(Builder effectBuilder, Material rowType, ItemStack itemstack) { - try { - FireworkEffect effect = effectBuilder.build(); - if ((rowType == Material.FIREWORK_ROCKET)) { - FireworkMeta meta = (FireworkMeta) itemstack.getItemMeta(); - meta.addEffect(effect); - itemstack.setItemMeta(meta); - } - else if ((rowType == Material.FIREWORK_STAR)) { - FireworkEffectMeta meta = (FireworkEffectMeta) itemstack.getItemMeta(); - meta.setEffect(effect); - itemstack.setItemMeta(meta); - } - } - catch (Exception e) { - e.printStackTrace(); - } - } - - @SuppressWarnings("unchecked") - public static Object[] populateItemStack(ItemStack itemstack, Object list) { - int slot = 0; - String faceData = ""; - - try { - /* - if (list instanceof Object[]) { - slot = (int) ((Object[]) list)[0]; - ItemMeta itemMeta = (ItemMeta) ((Object[]) list)[1]; - itemstack.setItemMeta(itemMeta); - return new Object[] { slot, itemstack }; - } - */ - - Material rowType = itemstack.getType(); - List metaList = (List) list; - if (metaList.size() > 0 && !(metaList.get(0) instanceof List)) { - if (rowType.name().endsWith("_BANNER")) { - BannerMeta meta = (BannerMeta) itemstack.getItemMeta(); - for (Object value : metaList) { - if (value instanceof Map) { - Pattern pattern = new Pattern((Map) value); - meta.addPattern(pattern); - } - } - itemstack.setItemMeta(meta); - } - else if (BlockGroup.SHULKER_BOXES.contains(rowType)) { - BlockStateMeta meta = (BlockStateMeta) itemstack.getItemMeta(); - ShulkerBox shulkerBox = (ShulkerBox) meta.getBlockState(); - for (Object value : metaList) { - ItemStack item = Util.unserializeItemStackLegacy(value); - if (item != null) { - shulkerBox.getInventory().addItem(item); - } - } - meta.setBlockState(shulkerBox); - itemstack.setItemMeta(meta); - } - - return new Object[] { slot, faceData, itemstack }; - } - - int itemCount = 0; - Builder effectBuilder = FireworkEffect.builder(); - for (List> map : (List>>) list) { - if (map.size() == 0) { - if (itemCount == 3 && (rowType == Material.FIREWORK_ROCKET || rowType == Material.FIREWORK_STAR)) { - buildFireworkEffect(effectBuilder, rowType, itemstack); - itemCount = 0; - } - - itemCount++; - continue; - } - Map mapData = map.get(0); - - if (mapData.get("slot") != null) { - slot = (Integer) mapData.get("slot"); - } - else if (mapData.get("facing") != null) { - faceData = (String) mapData.get("facing"); - } - else if (mapData.get("modifiers") != null) { - ItemMeta itemMeta = itemstack.getItemMeta(); - if (itemMeta.hasAttributeModifiers()) { - for (Map.Entry entry : itemMeta.getAttributeModifiers().entries()) { - itemMeta.removeAttributeModifier(entry.getKey(), entry.getValue()); - } - } - - List modifiers = (List) mapData.get("modifiers"); - - for (Object item : modifiers) { - Map> modifiersMap = (Map>) item; - for (Map.Entry> entry : modifiersMap.entrySet()) { - try { - Attribute attribute = entry.getKey(); - AttributeModifier modifier = AttributeModifier.deserialize(entry.getValue()); - itemMeta.addAttributeModifier(attribute, modifier); - } - catch (IllegalArgumentException e) { - // AttributeModifier already exists - } - } - } - - itemstack.setItemMeta(itemMeta); - } - else if (itemCount == 0) { - ItemMeta meta = Util.deserializeItemMeta(itemstack.getItemMeta().getClass(), map.get(0)); - itemstack.setItemMeta(meta); - - if (map.size() > 1 && (rowType == Material.POTION)) { - PotionMeta subMeta = (PotionMeta) itemstack.getItemMeta(); - org.bukkit.Color color = org.bukkit.Color.deserialize(map.get(1)); - subMeta.setColor(color); - itemstack.setItemMeta(subMeta); - } - } - else { - if ((rowType == Material.LEATHER_HORSE_ARMOR) || (rowType == Material.LEATHER_HELMET) || (rowType == Material.LEATHER_CHESTPLATE) || (rowType == Material.LEATHER_LEGGINGS) || (rowType == Material.LEATHER_BOOTS)) { // leather armor - for (Map colorData : map) { - LeatherArmorMeta meta = (LeatherArmorMeta) itemstack.getItemMeta(); - org.bukkit.Color color = org.bukkit.Color.deserialize(colorData); - meta.setColor(color); - itemstack.setItemMeta(meta); - } - } - else if ((rowType == Material.POTION)) { // potion - for (Map potionData : map) { - PotionMeta meta = (PotionMeta) itemstack.getItemMeta(); - PotionEffect effect = new PotionEffect(potionData); - meta.addCustomEffect(effect, true); - itemstack.setItemMeta(meta); - } - } - else if (rowType.name().endsWith("_BANNER")) { - for (Map patternData : map) { - BannerMeta meta = (BannerMeta) itemstack.getItemMeta(); - Pattern pattern = new Pattern(patternData); - meta.addPattern(pattern); - itemstack.setItemMeta(meta); - } - } - else if ((rowType == Material.CROSSBOW)) { - CrossbowMeta meta = (CrossbowMeta) itemstack.getItemMeta(); - for (Map itemData : map) { - ItemStack crossbowItem = Util.unserializeItemStack(itemData); - if (crossbowItem != null) { - meta.addChargedProjectile(crossbowItem); - } - } - itemstack.setItemMeta(meta); - } - else if (rowType == Material.MAP || rowType == Material.FILLED_MAP) { - for (Map colorData : map) { - MapMeta meta = (MapMeta) itemstack.getItemMeta(); - org.bukkit.Color color = org.bukkit.Color.deserialize(colorData); - meta.setColor(color); - itemstack.setItemMeta(meta); - } - } - else if ((rowType == Material.FIREWORK_ROCKET) || (rowType == Material.FIREWORK_STAR)) { - if (itemCount == 1) { - effectBuilder = FireworkEffect.builder(); - for (Map fireworkData : map) { - org.bukkit.FireworkEffect.Type type = (org.bukkit.FireworkEffect.Type) fireworkData.getOrDefault("type", org.bukkit.FireworkEffect.Type.BALL); - boolean hasFlicker = (Boolean) fireworkData.get("flicker"); - boolean hasTrail = (Boolean) fireworkData.get("trail"); - effectBuilder.with(type); - effectBuilder.flicker(hasFlicker); - effectBuilder.trail(hasTrail); - } - } - else if (itemCount == 2) { - for (Map colorData : map) { - org.bukkit.Color color = org.bukkit.Color.deserialize(colorData); - effectBuilder.withColor(color); - } - } - else if (itemCount == 3) { - for (Map colorData : map) { - org.bukkit.Color color = org.bukkit.Color.deserialize(colorData); - effectBuilder.withFade(color); - } - buildFireworkEffect(effectBuilder, rowType, itemstack); - itemCount = 0; - } - } - else if ((rowType == Material.SUSPICIOUS_STEW)) { - for (Map suspiciousStewData : map) { - SuspiciousStewMeta meta = (SuspiciousStewMeta) itemstack.getItemMeta(); - PotionEffect effect = new PotionEffect(suspiciousStewData); - meta.addCustomEffect(effect, true); - itemstack.setItemMeta(meta); - } - } - else { - BukkitAdapter.ADAPTER.setItemMeta(rowType, itemstack, map); - } - } - - itemCount++; - } - } - catch (Exception e) { - e.printStackTrace(); - } - return new Object[] { slot, faceData, itemstack }; - } - - public static Object[] populateItemStack(ItemStack itemstack, byte[] metadata) { - if (metadata != null) { - try { - ByteArrayInputStream metaByteStream = new ByteArrayInputStream(metadata); - BukkitObjectInputStream metaObjectStream = new BukkitObjectInputStream(metaByteStream); - Object metaList = metaObjectStream.readObject(); - metaObjectStream.close(); - metaByteStream.close(); - - return populateItemStack(itemstack, metaList); - } - catch (Exception e) { - e.printStackTrace(); - } - } - - return new Object[] { 0, "", itemstack }; - } - } diff --git a/src/main/java/net/coreprotect/database/rollback/RollbackComplete.java b/src/main/java/net/coreprotect/database/rollback/RollbackComplete.java new file mode 100644 index 00000000..451bea39 --- /dev/null +++ b/src/main/java/net/coreprotect/database/rollback/RollbackComplete.java @@ -0,0 +1,306 @@ +package net.coreprotect.database.rollback; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.NumberFormat; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.EntityType; + +import net.coreprotect.language.Phrase; +import net.coreprotect.language.Selector; +import net.coreprotect.utility.Chat; +import net.coreprotect.utility.Color; + +public class RollbackComplete { + + public static void output(CommandSender user, Location location, List checkUsers, List restrictList, Map excludeList, List excludeUserList, List actionList, String timeString, Integer chunkCount, Double seconds, Integer itemCount, Integer blockCount, Integer entityCount, int rollbackType, Integer[] radius, boolean verbose, boolean restrictWorld, int preview) { + try { + if (preview == 2) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_CANCELLED)); + return; + } + + Chat.sendMessage(user, "-----"); + + StringBuilder usersBuilder = new StringBuilder(); + for (String value : checkUsers) { + if (usersBuilder.length() == 0) { + usersBuilder = usersBuilder.append("" + value + ""); + } + else { + usersBuilder.append(", ").append(value); + } + } + String users = usersBuilder.toString(); + + if (users.equals("#global") && restrictWorld) { + users = "#" + location.getWorld().getName(); + } + + if (preview > 0) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_COMPLETED, users, Selector.THIRD)); // preview + } + else if (rollbackType == 0) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_COMPLETED, users, Selector.FIRST)); // rollback + } + else if (rollbackType == 1) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_COMPLETED, users, Selector.SECOND)); // restore + } + + if (preview == 1 || rollbackType == 0 || rollbackType == 1) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_TIME, timeString)); + } + + if (radius != null) { + int worldedit = radius[7]; + if (worldedit == 0) { + Integer rollbackRadius = radius[0]; + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_RADIUS, rollbackRadius.toString(), (rollbackRadius == 1 ? Selector.FIRST : Selector.SECOND))); + } + else { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_SELECTION, "#worldedit")); + } + } + + if (restrictWorld && radius == null) { + if (location != null) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, location.getWorld().getName(), Selector.FIRST)); + } + } + + if (actionList.contains(4) && actionList.contains(11)) { + if (actionList.contains(0)) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "+inventory", Selector.SECOND)); + } + else if (actionList.contains(1)) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "-inventory", Selector.SECOND)); + } + else { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "inventory", Selector.SECOND)); + } + } + else if (actionList.contains(4)) { + if (actionList.contains(0)) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "-container", Selector.SECOND)); + } + else if (actionList.contains(1)) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "+container", Selector.SECOND)); + } + else { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "container", Selector.SECOND)); + } + } + else if (actionList.contains(0) && actionList.contains(1)) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "block", Selector.SECOND)); + } + else if (actionList.contains(0)) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "-block", Selector.SECOND)); + } + else if (actionList.contains(1)) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "+block", Selector.SECOND)); + } + else if (actionList.contains(3)) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "kill", Selector.SECOND)); + } + + if (restrictList.size() > 0) { + StringBuilder restrictTargets = new StringBuilder(); + boolean material = false; + boolean item = false; + boolean entity = false; + + int targetCount = 0; + for (Object restrictTarget : restrictList) { + String targetName = ""; + + if (restrictTarget instanceof Material) { + targetName = ((Material) restrictTarget).name().toLowerCase(Locale.ROOT); + item = (!item ? !(((Material) restrictTarget).isBlock()) : item); + material = true; + } + else if (restrictTarget instanceof EntityType) { + targetName = ((EntityType) restrictTarget).name().toLowerCase(Locale.ROOT); + entity = true; + } + + if (targetCount == 0) { + restrictTargets = restrictTargets.append("" + targetName + ""); + } + else { + restrictTargets.append(", ").append(targetName); + } + + targetCount++; + } + + String targetType = Selector.THIRD; + if (material && !item && !entity) { + targetType = Selector.FIRST; + } + else if (material && item && !entity) { + targetType = Selector.THIRD; + } + else if (entity && !material) { + targetType = Selector.SECOND; + } + + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_INCLUDE, restrictTargets.toString(), Selector.FIRST, targetType, (targetCount == 1 ? Selector.FIRST : Selector.SECOND))); // include + } + + if (excludeList.size() > 0) { + StringBuilder excludeTargets = new StringBuilder(); + boolean material = false; + boolean item = false; + boolean entity = false; + + int excludeCount = 0; + for (Map.Entry entry : excludeList.entrySet()) { + Object excludeTarget = entry.getKey(); + Boolean excludeTargetInternal = entry.getValue(); + + // don't display default block excludes + if (Boolean.TRUE.equals(excludeTargetInternal)) { + continue; + } + + // don't display that excluded water/fire/farmland in inventory rollbacks + if (actionList.contains(4) && actionList.contains(11)) { + if (excludeTarget.equals(Material.FIRE) || excludeTarget.equals(Material.WATER) || excludeTarget.equals(Material.FARMLAND)) { + continue; + } + } + + String targetName = ""; + if (excludeTarget instanceof Material) { + targetName = ((Material) excludeTarget).name().toLowerCase(Locale.ROOT); + item = (!item ? !(((Material) excludeTarget).isBlock()) : item); + material = true; + } + else if (excludeTarget instanceof EntityType) { + targetName = ((EntityType) excludeTarget).name().toLowerCase(Locale.ROOT); + entity = true; + } + + if (excludeCount == 0) { + excludeTargets = excludeTargets.append("" + targetName + ""); + } + else { + excludeTargets.append(", ").append(targetName); + } + + excludeCount++; + } + + String targetType = Selector.THIRD; + if (material && !item && !entity) { + targetType = Selector.FIRST; + } + else if (material && item && !entity) { + targetType = Selector.THIRD; + } + else if (entity && !material) { + targetType = Selector.SECOND; + } + + if (excludeCount > 0) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_INCLUDE, excludeTargets.toString(), Selector.SECOND, targetType, (excludeCount == 1 ? Selector.FIRST : Selector.SECOND))); // exclude + } + } + + if (excludeUserList.size() > 0) { + StringBuilder excludeUsers = new StringBuilder(); + + int excludeCount = 0; + for (String excludeUser : excludeUserList) { + // don't display that excluded #hopper in inventory rollbacks + if (actionList.contains(4) && actionList.contains(11)) { + if (excludeUser.equals("#hopper")) { + continue; + } + } + + if (excludeCount == 0) { + excludeUsers = excludeUsers.append("" + excludeUser + ""); + } + else { + excludeUsers.append(", ").append(excludeUser); + } + + excludeCount++; + } + + if (excludeCount > 0) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_EXCLUDED_USERS, excludeUsers.toString(), (excludeCount == 1 ? Selector.FIRST : Selector.SECOND))); + } + } + + StringBuilder modifiedData = new StringBuilder(); + Integer modifyCount = 0; + if (actionList.contains(5)) { + modifiedData = modifiedData.append(Phrase.build(Phrase.AMOUNT_ITEM, NumberFormat.getInstance().format(blockCount), (blockCount == 1 ? Selector.FIRST : Selector.SECOND))); + modifyCount++; + } + else { + if (itemCount > 0 || actionList.contains(4)) { + modifiedData = modifiedData.append(Phrase.build(Phrase.AMOUNT_ITEM, NumberFormat.getInstance().format(itemCount), (itemCount == 1 ? Selector.FIRST : Selector.SECOND))); + modifyCount++; + } + + if (entityCount > 0) { + if (modifyCount > 0) { + modifiedData.append(", "); + } + modifiedData.append(Phrase.build(Phrase.AMOUNT_ENTITY, NumberFormat.getInstance().format(entityCount), (entityCount == 1 ? Selector.FIRST : Selector.SECOND))); + modifyCount++; + } + + if (blockCount > 0 || !actionList.contains(4) || preview > 0) { + if (modifyCount > 0) { + modifiedData.append(", "); + } + modifiedData.append(Phrase.build(Phrase.AMOUNT_BLOCK, NumberFormat.getInstance().format(blockCount), (blockCount == 1 ? Selector.FIRST : Selector.SECOND))); + modifyCount++; + } + } + + StringBuilder modifiedDataVerbose = new StringBuilder(); + if (verbose && preview == 0 && !actionList.contains(11)) { + if (chunkCount > -1 && modifyCount < 3) { + if (modifyCount > 0) { + modifiedData.append(", "); + } + modifiedData.append(Phrase.build(Phrase.AMOUNT_CHUNK, NumberFormat.getInstance().format(chunkCount), (chunkCount == 1 ? Selector.FIRST : Selector.SECOND))); + modifyCount++; + } + else if (chunkCount > 1) { + modifiedDataVerbose.append(Phrase.build(Phrase.AMOUNT_CHUNK, NumberFormat.getInstance().format(chunkCount), (chunkCount == 1 ? Selector.FIRST : Selector.SECOND))); + } + } + + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_MODIFIED, modifiedData.toString(), (preview == 0 ? Selector.FIRST : Selector.SECOND))); + if (modifiedDataVerbose.length() > 0) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_MODIFIED, modifiedDataVerbose.toString(), (preview == 0 ? Selector.FIRST : Selector.SECOND))); + } + + if (preview == 0) { + BigDecimal decimalSeconds = new BigDecimal(seconds).setScale(1, RoundingMode.HALF_EVEN); + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_LENGTH, decimalSeconds.stripTrailingZeros().toPlainString(), (decimalSeconds.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND))); + } + + Chat.sendMessage(user, "-----"); + if (preview > 0) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PLEASE_SELECT, "/co apply", "/co cancel")); + } + } + catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/net/coreprotect/database/rollback/RollbackUtil.java b/src/main/java/net/coreprotect/database/rollback/RollbackUtil.java new file mode 100644 index 00000000..0ee37fb0 --- /dev/null +++ b/src/main/java/net/coreprotect/database/rollback/RollbackUtil.java @@ -0,0 +1,487 @@ +package net.coreprotect.database.rollback; + +import java.io.ByteArrayInputStream; +import java.util.List; +import java.util.Map; + +import org.bukkit.FireworkEffect; +import org.bukkit.FireworkEffect.Builder; +import org.bukkit.Material; +import org.bukkit.Tag; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.block.Jukebox; +import org.bukkit.block.ShulkerBox; +import org.bukkit.block.banner.Pattern; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.ItemFrame; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.inventory.meta.BannerMeta; +import org.bukkit.inventory.meta.BlockStateMeta; +import org.bukkit.inventory.meta.CrossbowMeta; +import org.bukkit.inventory.meta.FireworkEffectMeta; +import org.bukkit.inventory.meta.FireworkMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.inventory.meta.MapMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.inventory.meta.SuspiciousStewMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.util.io.BukkitObjectInputStream; + +import net.coreprotect.bukkit.BukkitAdapter; +import net.coreprotect.database.Lookup; +import net.coreprotect.model.BlockGroup; +import net.coreprotect.utility.Util; + +public class RollbackUtil extends Lookup { + + protected static int modifyContainerItems(Material type, Object container, int slot, ItemStack itemstack, int action) { + int modifiedArmor = -1; + try { + ItemStack[] contents = null; + + if (type != null && type.equals(Material.ARMOR_STAND)) { + EntityEquipment equipment = (EntityEquipment) container; + if (equipment != null) { + if (action == 1) { + itemstack.setAmount(1); + } + else { + itemstack.setType(Material.AIR); + itemstack.setAmount(0); + } + + if (slot < 4) { + contents = equipment.getArmorContents(); + if (slot >= 0) { + contents[slot] = itemstack; + } + equipment.setArmorContents(contents); + } + else { + ArmorStand armorStand = (ArmorStand) equipment.getHolder(); + armorStand.setArms(true); + switch (slot) { + case 4: + equipment.setItemInMainHand(itemstack); + break; + case 5: + equipment.setItemInOffHand(itemstack); + break; + } + } + } + } + else if (type != null && type.equals(Material.ITEM_FRAME)) { + ItemFrame frame = (ItemFrame) container; + if (frame != null) { + if (action == 1) { + itemstack.setAmount(1); + } + else { + itemstack.setType(Material.AIR); + itemstack.setAmount(0); + } + + frame.setItem(itemstack); + } + } + else if (type != null && type.equals(Material.JUKEBOX)) { + Jukebox jukebox = (Jukebox) container; + if (jukebox != null) { + if (action == 1 && Tag.ITEMS_MUSIC_DISCS.isTagged(itemstack.getType())) { + itemstack.setAmount(1); + } + else { + itemstack.setType(Material.AIR); + itemstack.setAmount(0); + } + + jukebox.setRecord(itemstack); + jukebox.update(); + } + } + else { + Inventory inventory = (Inventory) container; + if (inventory != null) { + boolean isPlayerInventory = (inventory instanceof PlayerInventory); + if (action == 1) { + int count = 0; + int amount = itemstack.getAmount(); + itemstack.setAmount(1); + + while (count < amount) { + boolean addedItem = false; + if (isPlayerInventory) { + int setArmor = Util.setPlayerArmor((PlayerInventory) inventory, itemstack); + addedItem = (setArmor > -1); + modifiedArmor = addedItem ? setArmor : modifiedArmor; + } + if (!addedItem) { + if (BukkitAdapter.ADAPTER.isChiseledBookshelf(type)) { + ItemStack[] inventoryContents = inventory.getStorageContents(); + int i = 0; + for (ItemStack stack : inventoryContents) { + if (stack == null) { + inventoryContents[i] = itemstack; + addedItem = true; + break; + } + i++; + } + if (addedItem) { + inventory.setStorageContents(inventoryContents); + } + else { + addedItem = (inventory.addItem(itemstack).size() == 0); + } + } + else { + addedItem = (inventory.addItem(itemstack).size() == 0); + } + } + if (!addedItem && isPlayerInventory) { + PlayerInventory playerInventory = (PlayerInventory) inventory; + ItemStack offhand = playerInventory.getItemInOffHand(); + if (offhand == null || offhand.getType() == Material.AIR || (itemstack.isSimilar(offhand) && offhand.getAmount() < offhand.getMaxStackSize())) { + ItemStack setOffhand = itemstack.clone(); + if (itemstack.isSimilar(offhand)) { + setOffhand.setAmount(offhand.getAmount() + 1); + } + + playerInventory.setItemInOffHand(setOffhand); + } + } + count++; + } + } + else { + int removeAmount = itemstack.getAmount(); + ItemStack removeMatch = itemstack.clone(); + removeMatch.setAmount(1); + + ItemStack[] inventoryContents = (isPlayerInventory ? inventory.getContents() : inventory.getStorageContents()).clone(); + for (int i = inventoryContents.length - 1; i >= 0; i--) { + if (inventoryContents[i] != null) { + ItemStack itemStack = inventoryContents[i].clone(); + int maxAmount = itemStack.getAmount(); + int currentAmount = maxAmount; + itemStack.setAmount(1); + + if (itemStack.toString().equals(removeMatch.toString())) { + for (int scan = 0; scan < maxAmount; scan++) { + if (removeAmount > 0) { + currentAmount--; + itemStack.setAmount(currentAmount); + removeAmount--; + } + else { + break; + } + } + } + else { + itemStack.setAmount(maxAmount); + } + + if (itemStack.getAmount() == 0) { + inventoryContents[i] = null; + } + else { + inventoryContents[i] = itemStack; + } + } + + if (removeAmount == 0) { + break; + } + } + + if (isPlayerInventory) { + inventory.setContents(inventoryContents); + } + else { + inventory.setStorageContents(inventoryContents); + } + + int count = 0; + while (count < removeAmount) { + inventory.removeItem(removeMatch); + count++; + } + } + } + } + } + catch (Exception e) { + e.printStackTrace(); + } + + return modifiedArmor; + } + + public static void sortContainerItems(PlayerInventory inventory, List modifiedArmorSlots) { + try { + ItemStack[] armorContents = inventory.getArmorContents(); + ItemStack[] storageContents = inventory.getStorageContents(); + + for (int armor = 0; armor < armorContents.length; armor++) { + ItemStack armorItem = armorContents[armor]; + if (armorItem == null || !modifiedArmorSlots.contains(armor)) { + continue; + } + + for (int storage = 0; storage < storageContents.length; storage++) { + ItemStack storageItem = storageContents[storage]; + if (storageItem == null) { + storageContents[storage] = armorItem; + armorContents[armor] = null; + break; + } + } + } + + inventory.setArmorContents(armorContents); + inventory.setStorageContents(storageContents); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + private static void buildFireworkEffect(Builder effectBuilder, Material rowType, ItemStack itemstack) { + try { + FireworkEffect effect = effectBuilder.build(); + if ((rowType == Material.FIREWORK_ROCKET)) { + FireworkMeta meta = (FireworkMeta) itemstack.getItemMeta(); + meta.addEffect(effect); + itemstack.setItemMeta(meta); + } + else if ((rowType == Material.FIREWORK_STAR)) { + FireworkEffectMeta meta = (FireworkEffectMeta) itemstack.getItemMeta(); + meta.setEffect(effect); + itemstack.setItemMeta(meta); + } + } + catch (Exception e) { + e.printStackTrace(); + } + } + + @SuppressWarnings("unchecked") + public static Object[] populateItemStack(ItemStack itemstack, Object list) { + int slot = 0; + String faceData = ""; + + try { + /* + if (list instanceof Object[]) { + slot = (int) ((Object[]) list)[0]; + ItemMeta itemMeta = (ItemMeta) ((Object[]) list)[1]; + itemstack.setItemMeta(itemMeta); + return new Object[] { slot, itemstack }; + } + */ + + Material rowType = itemstack.getType(); + List metaList = (List) list; + if (metaList.size() > 0 && !(metaList.get(0) instanceof List)) { + if (rowType.name().endsWith("_BANNER")) { + BannerMeta meta = (BannerMeta) itemstack.getItemMeta(); + for (Object value : metaList) { + if (value instanceof Map) { + Pattern pattern = new Pattern((Map) value); + meta.addPattern(pattern); + } + } + itemstack.setItemMeta(meta); + } + else if (BlockGroup.SHULKER_BOXES.contains(rowType)) { + BlockStateMeta meta = (BlockStateMeta) itemstack.getItemMeta(); + ShulkerBox shulkerBox = (ShulkerBox) meta.getBlockState(); + for (Object value : metaList) { + ItemStack item = Util.unserializeItemStackLegacy(value); + if (item != null) { + shulkerBox.getInventory().addItem(item); + } + } + meta.setBlockState(shulkerBox); + itemstack.setItemMeta(meta); + } + + return new Object[] { slot, faceData, itemstack }; + } + + int itemCount = 0; + Builder effectBuilder = FireworkEffect.builder(); + for (List> map : (List>>) list) { + if (map.size() == 0) { + if (itemCount == 3 && (rowType == Material.FIREWORK_ROCKET || rowType == Material.FIREWORK_STAR)) { + buildFireworkEffect(effectBuilder, rowType, itemstack); + itemCount = 0; + } + + itemCount++; + continue; + } + Map mapData = map.get(0); + + if (mapData.get("slot") != null) { + slot = (Integer) mapData.get("slot"); + } + else if (mapData.get("facing") != null) { + faceData = (String) mapData.get("facing"); + } + else if (mapData.get("modifiers") != null) { + ItemMeta itemMeta = itemstack.getItemMeta(); + if (itemMeta.hasAttributeModifiers()) { + for (Map.Entry entry : itemMeta.getAttributeModifiers().entries()) { + itemMeta.removeAttributeModifier(entry.getKey(), entry.getValue()); + } + } + + List modifiers = (List) mapData.get("modifiers"); + + for (Object item : modifiers) { + Map> modifiersMap = (Map>) item; + for (Map.Entry> entry : modifiersMap.entrySet()) { + try { + Attribute attribute = entry.getKey(); + AttributeModifier modifier = AttributeModifier.deserialize(entry.getValue()); + itemMeta.addAttributeModifier(attribute, modifier); + } + catch (IllegalArgumentException e) { + // AttributeModifier already exists + } + } + } + + itemstack.setItemMeta(itemMeta); + } + else if (itemCount == 0) { + ItemMeta meta = Util.deserializeItemMeta(itemstack.getItemMeta().getClass(), map.get(0)); + itemstack.setItemMeta(meta); + + if (map.size() > 1 && (rowType == Material.POTION)) { + PotionMeta subMeta = (PotionMeta) itemstack.getItemMeta(); + org.bukkit.Color color = org.bukkit.Color.deserialize(map.get(1)); + subMeta.setColor(color); + itemstack.setItemMeta(subMeta); + } + } + else { + if ((rowType == Material.LEATHER_HORSE_ARMOR) || (rowType == Material.LEATHER_HELMET) || (rowType == Material.LEATHER_CHESTPLATE) || (rowType == Material.LEATHER_LEGGINGS) || (rowType == Material.LEATHER_BOOTS)) { // leather armor + for (Map colorData : map) { + LeatherArmorMeta meta = (LeatherArmorMeta) itemstack.getItemMeta(); + org.bukkit.Color color = org.bukkit.Color.deserialize(colorData); + meta.setColor(color); + itemstack.setItemMeta(meta); + } + } + else if ((rowType == Material.POTION)) { // potion + for (Map potionData : map) { + PotionMeta meta = (PotionMeta) itemstack.getItemMeta(); + PotionEffect effect = new PotionEffect(potionData); + meta.addCustomEffect(effect, true); + itemstack.setItemMeta(meta); + } + } + else if (rowType.name().endsWith("_BANNER")) { + for (Map patternData : map) { + BannerMeta meta = (BannerMeta) itemstack.getItemMeta(); + Pattern pattern = new Pattern(patternData); + meta.addPattern(pattern); + itemstack.setItemMeta(meta); + } + } + else if ((rowType == Material.CROSSBOW)) { + CrossbowMeta meta = (CrossbowMeta) itemstack.getItemMeta(); + for (Map itemData : map) { + ItemStack crossbowItem = Util.unserializeItemStack(itemData); + if (crossbowItem != null) { + meta.addChargedProjectile(crossbowItem); + } + } + itemstack.setItemMeta(meta); + } + else if (rowType == Material.MAP || rowType == Material.FILLED_MAP) { + for (Map colorData : map) { + MapMeta meta = (MapMeta) itemstack.getItemMeta(); + org.bukkit.Color color = org.bukkit.Color.deserialize(colorData); + meta.setColor(color); + itemstack.setItemMeta(meta); + } + } + else if ((rowType == Material.FIREWORK_ROCKET) || (rowType == Material.FIREWORK_STAR)) { + if (itemCount == 1) { + effectBuilder = FireworkEffect.builder(); + for (Map fireworkData : map) { + org.bukkit.FireworkEffect.Type type = (org.bukkit.FireworkEffect.Type) fireworkData.getOrDefault("type", org.bukkit.FireworkEffect.Type.BALL); + boolean hasFlicker = (Boolean) fireworkData.get("flicker"); + boolean hasTrail = (Boolean) fireworkData.get("trail"); + effectBuilder.with(type); + effectBuilder.flicker(hasFlicker); + effectBuilder.trail(hasTrail); + } + } + else if (itemCount == 2) { + for (Map colorData : map) { + org.bukkit.Color color = org.bukkit.Color.deserialize(colorData); + effectBuilder.withColor(color); + } + } + else if (itemCount == 3) { + for (Map colorData : map) { + org.bukkit.Color color = org.bukkit.Color.deserialize(colorData); + effectBuilder.withFade(color); + } + buildFireworkEffect(effectBuilder, rowType, itemstack); + itemCount = 0; + } + } + else if ((rowType == Material.SUSPICIOUS_STEW)) { + for (Map suspiciousStewData : map) { + SuspiciousStewMeta meta = (SuspiciousStewMeta) itemstack.getItemMeta(); + PotionEffect effect = new PotionEffect(suspiciousStewData); + meta.addCustomEffect(effect, true); + itemstack.setItemMeta(meta); + } + } + else { + BukkitAdapter.ADAPTER.setItemMeta(rowType, itemstack, map); + } + } + + itemCount++; + } + } + catch (Exception e) { + e.printStackTrace(); + } + return new Object[] { slot, faceData, itemstack }; + } + + public static Object[] populateItemStack(ItemStack itemstack, byte[] metadata) { + if (metadata != null) { + try { + ByteArrayInputStream metaByteStream = new ByteArrayInputStream(metadata); + BukkitObjectInputStream metaObjectStream = new BukkitObjectInputStream(metaByteStream); + Object metaList = metaObjectStream.readObject(); + metaObjectStream.close(); + metaByteStream.close(); + + return populateItemStack(itemstack, metaList); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + return new Object[] { 0, "", itemstack }; + } + +} diff --git a/src/main/java/net/coreprotect/utility/Util.java b/src/main/java/net/coreprotect/utility/Util.java index 0a19b868..502b3265 100755 --- a/src/main/java/net/coreprotect/utility/Util.java +++ b/src/main/java/net/coreprotect/utility/Util.java @@ -56,7 +56,7 @@ import net.coreprotect.config.Config; import net.coreprotect.config.ConfigHandler; import net.coreprotect.consumer.Queue; -import net.coreprotect.database.Rollback; +import net.coreprotect.database.rollback.Rollback; import net.coreprotect.language.Phrase; import net.coreprotect.model.BlockGroup; import net.coreprotect.thread.CacheHandler; diff --git a/src/main/java/net/coreprotect/utility/entity/EntityUtil.java b/src/main/java/net/coreprotect/utility/entity/EntityUtil.java index a8f4b162..ed619658 100644 --- a/src/main/java/net/coreprotect/utility/entity/EntityUtil.java +++ b/src/main/java/net/coreprotect/utility/entity/EntityUtil.java @@ -57,7 +57,7 @@ import net.coreprotect.CoreProtect; import net.coreprotect.bukkit.BukkitAdapter; -import net.coreprotect.database.Rollback; +import net.coreprotect.database.rollback.Rollback; import net.coreprotect.thread.CacheHandler; import net.coreprotect.thread.Scheduler; import net.coreprotect.utility.Util;