forked from LogBlock/LogBlock
Log & rollback armor stand/item frame modifications
This commit is contained in:
@ -5,11 +5,14 @@ import java.sql.SQLException;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import de.diddiz.LogBlock.config.Config;
|
||||
import de.diddiz.util.Utils;
|
||||
|
||||
public class EntityChange implements LookupCacheElement {
|
||||
public static enum EntityChangeType {
|
||||
@ -75,9 +78,21 @@ public class EntityChange implements LookupCacheElement {
|
||||
} else if (changeType == EntityChangeType.KILL) {
|
||||
msg.append(living ? "killed " : "destroyed ");
|
||||
} else if (changeType == EntityChangeType.ADDEQUIP) {
|
||||
msg.append("added an item to ");
|
||||
YamlConfiguration conf = Utils.deserializeYamlConfiguration(data);
|
||||
ItemStack stack = conf == null ? null : conf.getItemStack("item");
|
||||
if (stack == null) {
|
||||
msg.append("added an item to ");
|
||||
} else {
|
||||
msg.append("added " + stack.getType() + " to ");
|
||||
}
|
||||
} else if (changeType == EntityChangeType.REMOVEEQUIP) {
|
||||
msg.append("removed an item from ");
|
||||
YamlConfiguration conf = Utils.deserializeYamlConfiguration(data);
|
||||
ItemStack stack = conf == null ? null : conf.getItemStack("item");
|
||||
if (stack == null) {
|
||||
msg.append("removed an item from ");
|
||||
} else {
|
||||
msg.append("removed " + stack.getType() + " from ");
|
||||
}
|
||||
} else if (changeType == EntityChangeType.MODIFY) {
|
||||
msg.append("modified ");
|
||||
}
|
||||
|
@ -19,7 +19,10 @@ import org.bukkit.block.data.type.PistonHead;
|
||||
import org.bukkit.block.data.type.TechnicalPiston.Type;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import de.diddiz.LogBlock.blockstate.BlockStateCodecs;
|
||||
@ -201,7 +204,7 @@ public class WorldEditor implements Runnable {
|
||||
float yaw = (float) deserialized.getDouble("yaw");
|
||||
float pitch = (float) deserialized.getDouble("pitch");
|
||||
Location location = new Location(world, x, y, z, yaw, pitch);
|
||||
Entity existing = Utils.loadChunksForEntity(location.getChunk(), uuid);
|
||||
Entity existing = BukkitUtils.loadEntityAround(location.getChunk(), uuid);
|
||||
if (existing != null) {
|
||||
return PerformResult.NO_ACTION;
|
||||
}
|
||||
@ -228,12 +231,60 @@ public class WorldEditor implements Runnable {
|
||||
float yaw = (float) deserialized.getDouble("yaw");
|
||||
float pitch = (float) deserialized.getDouble("pitch");
|
||||
Location location = new Location(world, x, y, z, yaw, pitch);
|
||||
Entity existing = Utils.loadChunksForEntity(location.getChunk(), uuid);
|
||||
Entity existing = BukkitUtils.loadEntityAround(location.getChunk(), uuid);
|
||||
if (existing != null) {
|
||||
existing.remove();
|
||||
return PerformResult.SUCCESS;
|
||||
}
|
||||
return PerformResult.NO_ACTION; // the entity is not there, so we cannot do anything
|
||||
} else if (changeType == (rollback ? EntityChangeType.REMOVEEQUIP : EntityChangeType.ADDEQUIP)) {
|
||||
// set equip
|
||||
UUID uuid = getReplacedUUID(entityId, entityUUID);
|
||||
Entity existing = BukkitUtils.loadEntityAround(loc.getChunk(), uuid);
|
||||
if (existing != null) {
|
||||
YamlConfiguration deserialized = Utils.deserializeYamlConfiguration(data);
|
||||
ItemStack item = deserialized.getItemStack("item");
|
||||
if (item != null && existing instanceof ItemFrame) {
|
||||
ItemStack old = ((ItemFrame) existing).getItem();
|
||||
if (old == null || old.getType() == Material.AIR) {
|
||||
((ItemFrame) existing).setItem(item);
|
||||
return PerformResult.SUCCESS;
|
||||
}
|
||||
} else if (item != null && existing instanceof ArmorStand) {
|
||||
EquipmentSlot slot = EquipmentSlot.valueOf(deserialized.getString("slot"));
|
||||
ArmorStand stand = (ArmorStand) existing;
|
||||
ItemStack old = BukkitUtils.getItemInSlot(stand, slot);
|
||||
if (old == null || old.getType() == Material.AIR) {
|
||||
BukkitUtils.setItemInSlot(stand, slot, item);
|
||||
return PerformResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return PerformResult.NO_ACTION; // the entity is not there, or equip does not match
|
||||
} else if (changeType == (rollback ? EntityChangeType.ADDEQUIP : EntityChangeType.REMOVEEQUIP)) {
|
||||
// remove equip
|
||||
UUID uuid = getReplacedUUID(entityId, entityUUID);
|
||||
Entity existing = BukkitUtils.loadEntityAround(loc.getChunk(), uuid);
|
||||
if (existing != null) {
|
||||
YamlConfiguration deserialized = Utils.deserializeYamlConfiguration(data);
|
||||
ItemStack item = deserialized.getItemStack("item");
|
||||
if (item != null && existing instanceof ItemFrame) {
|
||||
ItemStack old = ((ItemFrame) existing).getItem();
|
||||
if (old != null && old.isSimilar(item)) {
|
||||
((ItemFrame) existing).setItem(null);
|
||||
return PerformResult.SUCCESS;
|
||||
}
|
||||
} else if (item != null && existing instanceof ArmorStand) {
|
||||
EquipmentSlot slot = EquipmentSlot.valueOf(deserialized.getString("slot"));
|
||||
ArmorStand stand = (ArmorStand) existing;
|
||||
ItemStack old = BukkitUtils.getItemInSlot(stand, slot);
|
||||
if (old != null && old.isSimilar(item)) {
|
||||
BukkitUtils.setItemInSlot(stand, slot, null);
|
||||
return PerformResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return PerformResult.NO_ACTION; // the entity is not there, or equip does not match
|
||||
}
|
||||
return PerformResult.NO_ACTION;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package de.diddiz.LogBlock.config;
|
||||
import de.diddiz.LogBlock.EntityLogging;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import de.diddiz.util.Utils;
|
||||
import de.diddiz.util.BukkitUtils;
|
||||
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Ambient;
|
||||
@ -90,7 +90,7 @@ public class WorldConfig extends LoggingEnabledMapping {
|
||||
boolean monsters = false;
|
||||
boolean living = false;
|
||||
for (String type : types) {
|
||||
EntityType et = Utils.matchEntityType(type);
|
||||
EntityType et = BukkitUtils.matchEntityType(type);
|
||||
if (et != null) {
|
||||
logged.add(et);
|
||||
} else {
|
||||
|
@ -8,6 +8,7 @@ import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Hanging;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Snowman;
|
||||
@ -24,6 +25,7 @@ import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
|
||||
import org.bukkit.event.hanging.HangingBreakEvent;
|
||||
import org.bukkit.event.hanging.HangingPlaceEvent;
|
||||
import org.bukkit.event.player.PlayerArmorStandManipulateEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
@ -98,11 +100,26 @@ public class AdvancedEntityLogging extends LoggingListener {
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
ItemStack inHand = event.getHand() == EquipmentSlot.HAND ? event.getPlayer().getInventory().getItemInMainHand() : event.getPlayer().getInventory().getItemInOffHand();
|
||||
if (inHand != null) {
|
||||
if (inHand != null && inHand.getType() != Material.AIR) {
|
||||
Material mat = inHand.getType();
|
||||
if (mat.name().endsWith("_SPAWN_EGG")) {
|
||||
setLastSpawner(event.getPlayer(), null, true);
|
||||
}
|
||||
|
||||
Entity entity = event.getRightClicked();
|
||||
if (entity instanceof ItemFrame) {
|
||||
ItemStack oldItem = ((ItemFrame) entity).getItem();
|
||||
if (oldItem == null || oldItem.getType() == Material.AIR) {
|
||||
if (Config.isLogging(entity.getWorld(), EntityLogging.MODIFY, entity)) {
|
||||
Actor actor = Actor.actorFromEntity(event.getPlayer());
|
||||
YamlConfiguration data = new YamlConfiguration();
|
||||
inHand = inHand.clone();
|
||||
inHand.setAmount(1);
|
||||
data.set("item", inHand);
|
||||
consumer.queueEntityModification(actor, entity.getUniqueId(), entity.getType(), entity.getLocation(), EntityChange.EntityChangeType.ADDEQUIP, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,6 +186,54 @@ public class AdvancedEntityLogging extends LoggingListener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onEntityDamage(EntityDamageEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
if (entity instanceof ItemFrame) {
|
||||
ItemStack oldItem = ((ItemFrame) entity).getItem();
|
||||
if (oldItem != null && oldItem.getType() != Material.AIR) {
|
||||
if (Config.isLogging(entity.getWorld(), EntityLogging.MODIFY, entity)) {
|
||||
Actor actor;
|
||||
if (event instanceof EntityDamageByEntityEvent) {
|
||||
actor = Actor.actorFromEntity(((EntityDamageByEntityEvent) event).getDamager());
|
||||
} else {
|
||||
actor = new Actor(event.getCause().toString());
|
||||
}
|
||||
YamlConfiguration data = new YamlConfiguration();
|
||||
data.set("item", oldItem);
|
||||
consumer.queueEntityModification(actor, entity.getUniqueId(), entity.getType(), entity.getLocation(), EntityChange.EntityChangeType.REMOVEEQUIP, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPlayerArmorStandManipulate(PlayerArmorStandManipulateEvent event) {
|
||||
ArmorStand entity = event.getRightClicked();
|
||||
ItemStack oldItem = event.getArmorStandItem();
|
||||
ItemStack newItem = event.getPlayerItem();
|
||||
boolean oldEmpty = oldItem == null || oldItem.getType() == Material.AIR;
|
||||
boolean newEmpty = newItem == null || newItem.getType() == Material.AIR;
|
||||
if ((!oldEmpty || !newEmpty) && Config.isLogging(entity.getWorld(), EntityLogging.MODIFY, entity)) {
|
||||
Actor actor = Actor.actorFromEntity(event.getPlayer());
|
||||
if (!oldEmpty && !newEmpty && newItem.getAmount() > 1) {
|
||||
return;
|
||||
}
|
||||
if (!oldEmpty) {
|
||||
YamlConfiguration data = new YamlConfiguration();
|
||||
data.set("item", oldItem);
|
||||
data.set("slot", event.getSlot().name());
|
||||
consumer.queueEntityModification(actor, entity.getUniqueId(), entity.getType(), entity.getLocation(), EntityChange.EntityChangeType.REMOVEEQUIP, data);
|
||||
}
|
||||
if (!newEmpty) {
|
||||
YamlConfiguration data = new YamlConfiguration();
|
||||
data.set("item", newItem);
|
||||
data.set("slot", event.getSlot().name());
|
||||
consumer.queueEntityModification(actor, entity.getUniqueId(), entity.getType(), entity.getLocation(), EntityChange.EntityChangeType.ADDEQUIP, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void queueEntitySpawnOrKill(Entity entity, Actor actor, EntityChange.EntityChangeType changeType) {
|
||||
Location location = entity.getLocation();
|
||||
YamlConfiguration data = new YamlConfiguration();
|
||||
|
@ -12,10 +12,12 @@ import org.bukkit.block.data.type.Slab;
|
||||
import org.bukkit.block.data.type.Slab.Type;
|
||||
import org.bukkit.block.data.type.Stairs;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -746,4 +748,85 @@ public class BukkitUtils {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Entity loadEntityAround(Chunk chunk, UUID uuid) {
|
||||
Entity e = Bukkit.getEntity(uuid);
|
||||
if (e != null) {
|
||||
return e;
|
||||
}
|
||||
if (!chunk.isLoaded()) {
|
||||
chunk.load();
|
||||
e = Bukkit.getEntity(uuid);
|
||||
if (e != null) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
int chunkx = chunk.getX();
|
||||
int chunkz = chunk.getZ();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int x = i < 3 ? chunkx - 1 : (i < 5 ? chunkx : chunkx + 1);
|
||||
int z = i == 0 || i == 3 || i == 5 ? chunkz - 1 : (i == 1 || i == 6 ? chunkz : chunkz + 1);
|
||||
if (!chunk.getWorld().isChunkLoaded(x, z)) {
|
||||
chunk.getWorld().loadChunk(x, z);
|
||||
e = Bukkit.getEntity(uuid);
|
||||
if (e != null) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final HashMap<String, EntityType> types = new HashMap<>();
|
||||
static {
|
||||
for (EntityType t : EntityType.values()) {
|
||||
types.put(t.name().toLowerCase(), t);
|
||||
@SuppressWarnings("deprecation")
|
||||
String typeName = t.getName();
|
||||
if (typeName != null) {
|
||||
types.put(typeName.toLowerCase(), t);
|
||||
}
|
||||
Class<? extends Entity> ec = t.getEntityClass();
|
||||
if (ec != null) {
|
||||
types.put(ec.getSimpleName().toLowerCase(), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static EntityType matchEntityType(String typeName) {
|
||||
return types.get(typeName.toLowerCase());
|
||||
}
|
||||
|
||||
public static ItemStack getItemInSlot(ArmorStand stand, EquipmentSlot slot) {
|
||||
if (slot == EquipmentSlot.HAND) {
|
||||
return stand.getEquipment().getItemInMainHand();
|
||||
} else if (slot == EquipmentSlot.OFF_HAND) {
|
||||
return stand.getEquipment().getItemInOffHand();
|
||||
} else if (slot == EquipmentSlot.FEET) {
|
||||
return stand.getEquipment().getBoots();
|
||||
} else if (slot == EquipmentSlot.LEGS) {
|
||||
return stand.getEquipment().getLeggings();
|
||||
} else if (slot == EquipmentSlot.CHEST) {
|
||||
return stand.getEquipment().getChestplate();
|
||||
} else if (slot == EquipmentSlot.HEAD) {
|
||||
return stand.getEquipment().getHelmet();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void setItemInSlot(ArmorStand stand, EquipmentSlot slot, ItemStack stack) {
|
||||
if (slot == EquipmentSlot.HAND) {
|
||||
stand.getEquipment().setItemInMainHand(stack);
|
||||
} else if (slot == EquipmentSlot.OFF_HAND) {
|
||||
stand.getEquipment().setItemInOffHand(stack);
|
||||
} else if (slot == EquipmentSlot.FEET) {
|
||||
stand.getEquipment().setBoots(stack);
|
||||
} else if (slot == EquipmentSlot.LEGS) {
|
||||
stand.getEquipment().setLeggings(stack);
|
||||
} else if (slot == EquipmentSlot.CHEST) {
|
||||
stand.getEquipment().setChestplate(stack);
|
||||
} else if (slot == EquipmentSlot.HEAD) {
|
||||
stand.getEquipment().setHelmet(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,21 +10,15 @@ import java.io.OutputStreamWriter;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import java.util.zip.ZipException;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
@ -290,52 +284,4 @@ public class Utils {
|
||||
public static String serializeForSQL(YamlConfiguration conf) {
|
||||
return mysqlPrepareBytesForInsertAllowNull(serializeYamlConfiguration(conf));
|
||||
}
|
||||
|
||||
public static Entity loadChunksForEntity(Chunk chunk, UUID uuid) {
|
||||
Entity e = Bukkit.getEntity(uuid);
|
||||
if (e != null) {
|
||||
return e;
|
||||
}
|
||||
if (!chunk.isLoaded()) {
|
||||
chunk.load();
|
||||
e = Bukkit.getEntity(uuid);
|
||||
if (e != null) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
int chunkx = chunk.getX();
|
||||
int chunkz = chunk.getZ();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int x = i < 3 ? chunkx - 1 : (i < 5 ? chunkx : chunkx + 1);
|
||||
int z = i == 0 || i == 3 || i == 5 ? chunkz - 1 : (i == 1 || i == 6 ? chunkz : chunkz + 1);
|
||||
if (!chunk.getWorld().isChunkLoaded(x, z)) {
|
||||
chunk.getWorld().loadChunk(x, z);
|
||||
e = Bukkit.getEntity(uuid);
|
||||
if (e != null) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final HashMap<String, EntityType> types = new HashMap<>();
|
||||
static {
|
||||
for (EntityType t : EntityType.values()) {
|
||||
types.put(t.name().toLowerCase(), t);
|
||||
@SuppressWarnings("deprecation")
|
||||
String typeName = t.getName();
|
||||
if (typeName != null) {
|
||||
types.put(typeName.toLowerCase(), t);
|
||||
}
|
||||
Class<? extends Entity> ec = t.getEntityClass();
|
||||
if (ec != null) {
|
||||
types.put(ec.getSimpleName().toLowerCase(), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static EntityType matchEntityType(String typeName) {
|
||||
return types.get(typeName.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user