Configurable entity logging

This commit is contained in:
Brokkonaut
2018-11-09 04:04:31 +01:00
parent ea16656fcb
commit 4e1a79ca0f
5 changed files with 210 additions and 47 deletions

View File

@ -0,0 +1,28 @@
package de.diddiz.LogBlock;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.bukkit.entity.EntityType;
public enum EntityLogging {
SPAWN(new String[] { EntityType.ARMOR_STAND.name(), EntityType.ITEM_FRAME.name(), EntityType.IRON_GOLEM.name(), EntityType.SNOWMAN.name() }),
DESTROY(new String[] { EntityType.ARMOR_STAND.name(), EntityType.ITEM_FRAME.name(), EntityType.VILLAGER.name(), EntityType.IRON_GOLEM.name(), EntityType.SNOWMAN.name(), "ANIMAL" }),
MODIFY(new String[] { "ALL" });
public static final int length = EntityLogging.values().length;
private final List<String> defaultEnabled;
private EntityLogging() {
this(null);
}
private EntityLogging(String[] defaultEnabled) {
this.defaultEnabled = defaultEnabled == null ? Collections.emptyList() : Collections.unmodifiableList(Arrays.asList(defaultEnabled));
}
public List<String> getDefaultEnabled() {
return defaultEnabled;
}
}

View File

@ -6,6 +6,7 @@ import de.diddiz.util.ComparableVersion;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
import org.bukkit.permissions.PermissionDefault;
import java.io.File;
@ -322,6 +323,11 @@ public class Config {
public static Collection<WorldConfig> getLoggedWorlds() {
return worldConfigs.values();
}
public static boolean isLogging(World world, EntityLogging logging, Entity entity) {
final WorldConfig wcfg = worldConfigs.get(world.getName());
return wcfg != null && wcfg.isLogging(logging, entity);
}
}
class LoggingEnabledMapping {

View File

@ -1,13 +1,30 @@
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 org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Ambient;
import org.bukkit.entity.Animals;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Monster;
import org.bukkit.entity.Player;
import org.bukkit.entity.WaterMob;
import java.io.File;
import java.io.IOException;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
public class WorldConfig extends LoggingEnabledMapping {
public final String world;
@ -19,6 +36,8 @@ public class WorldConfig extends LoggingEnabledMapping {
public final String insertEntityStatementString;
public final String updateEntityUUIDString;
private final EnumMap<EntityLogging, EntitiyLoggingList> entityLogging = new EnumMap<>(EntityLogging.class);
public WorldConfig(String world, File file) throws IOException {
this.world = world;
final Map<String, Object> def = new HashMap<String, Object>();
@ -34,6 +53,12 @@ public class WorldConfig extends LoggingEnabledMapping {
config.set(e.getKey(), e.getValue());
}
}
for (EntityLogging el : EntityLogging.values()) {
if (!(config.get("entity." + el.name().toLowerCase()) instanceof List)) {
config.set("entity." + el.name().toLowerCase(), el.getDefaultEnabled());
}
entityLogging.put(el, new EntitiyLoggingList(config.getStringList("entity." + el.name().toLowerCase())));
}
config.save(file);
table = config.getString("table");
for (final Logging l : Logging.values()) {
@ -47,4 +72,65 @@ public class WorldConfig extends LoggingEnabledMapping {
insertEntityStatementString = "INSERT INTO `" + table + "-entities` (date, playerid, entityid, entitytypeid, x, y, z, action, data) VALUES (FROM_UNIXTIME(?), ?, ?, ?, ?, ?, ?, ?, ?)";
updateEntityUUIDString = "UPDATE `" + table + "-entityids` SET entityuuid = ? WHERE entityid = ?";
}
public boolean isLogging(EntityLogging logging, Entity entity) {
return entityLogging.get(logging).isLogging(entity);
}
private class EntitiyLoggingList {
private final EnumSet<EntityType> logged = EnumSet.noneOf(EntityType.class);
private final boolean logAll;
private final boolean logAnimals;
private final boolean logMonsters;
private final boolean logLiving;
public EntitiyLoggingList(List<String> types) {
boolean all = false;
boolean animals = false;
boolean monsters = false;
boolean living = false;
for (String type : types) {
EntityType et = Utils.matchEntityType(type);
if (et != null) {
logged.add(et);
} else {
if (type.equalsIgnoreCase("all")) {
all = true;
} else if (type.equalsIgnoreCase("animal") || type.equalsIgnoreCase("animals")) {
animals = true;
} else if (type.equalsIgnoreCase("monster") || type.equalsIgnoreCase("monsters")) {
monsters = true;
} else if (type.equalsIgnoreCase("living")) {
living = true;
} else {
LogBlock.getInstance().getLogger().log(Level.WARNING, "Unkown entity type in config for " + world + ": " + type);
}
}
}
logAll = all;
logAnimals = animals;
logMonsters = monsters;
logLiving = living;
}
public boolean isLogging(Entity entity) {
if (entity == null || (entity instanceof Player)) {
return false;
}
EntityType type = entity.getType();
if (logAll || logged.contains(type)) {
return true;
}
if (logLiving && LivingEntity.class.isAssignableFrom(entity.getClass()) && !(entity instanceof ArmorStand)) {
return true;
}
if (logAnimals && (Animals.class.isAssignableFrom(entity.getClass()) || WaterMob.class.isAssignableFrom(entity.getClass()) || Ambient.class.isAssignableFrom(entity.getClass()))) {
return true;
}
if (logMonsters && (Monster.class.isAssignableFrom(entity.getClass()) || entity.getType() == EntityType.SLIME || entity.getType() == EntityType.WITHER || entity.getType() == EntityType.ENDER_DRAGON || entity.getType() == EntityType.SHULKER || entity.getType() == EntityType.GHAST)) {
return true;
}
return false;
}
}
}

View File

@ -2,18 +2,20 @@ package de.diddiz.LogBlock.listeners;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Animals;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Golem;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Snowman;
import org.bukkit.entity.Wither;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
@ -30,7 +32,9 @@ import org.bukkit.scheduler.BukkitRunnable;
import de.diddiz.LogBlock.Actor;
import de.diddiz.LogBlock.EntityChange;
import de.diddiz.LogBlock.EntityLogging;
import de.diddiz.LogBlock.LogBlock;
import de.diddiz.LogBlock.config.Config;
import de.diddiz.worldedit.WorldEditHelper;
public class AdvancedEntityLogging extends LoggingListener {
@ -55,20 +59,25 @@ public class AdvancedEntityLogging extends LoggingListener {
lastSpawnerEgg = false;
}
private void setLastSpawner(Player player, Class<? extends Entity> spawning, boolean spawnEgg) {
lastSpawner = player;
lastSpawning = spawning;
lastSpawnerEgg = spawnEgg;
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onEntityDeath(EntityDeathEvent event) {
LivingEntity entity = event.getEntity();
if (!(entity instanceof Animals) && !(entity instanceof Villager) && !(entity instanceof Golem) && !(entity instanceof ArmorStand)) {
return;
public void onPlayerBlockPlace(BlockPlaceEvent event) {
Material placed = event.getBlock().getType();
if (placed == Material.WITHER_SKELETON_SKULL) {
setLastSpawner(event.getPlayer(), Wither.class, false);
} else if (placed == Material.CARVED_PUMPKIN) {
Material below = event.getBlock().getRelative(BlockFace.DOWN).getType();
if (below == Material.SNOW_BLOCK) {
setLastSpawner(event.getPlayer(), Snowman.class, false);
} else if (below == Material.IRON_BLOCK) {
setLastSpawner(event.getPlayer(), IronGolem.class, false);
}
}
Actor actor;
EntityDamageEvent lastDamage = entity.getLastDamageCause();
if (lastDamage instanceof EntityDamageByEntityEvent) {
actor = Actor.actorFromEntity(((EntityDamageByEntityEvent) lastDamage).getDamager());
} else {
actor = new Actor(lastDamage.getCause().toString());
}
queueEntitySpawnOrKill(entity, actor, EntityChange.EntityChangeType.KILL);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
@ -78,13 +87,9 @@ public class AdvancedEntityLogging extends LoggingListener {
if (inHand != null) {
Material mat = inHand.getType();
if (mat == Material.ARMOR_STAND) {
lastSpawner = event.getPlayer();
lastSpawning = ArmorStand.class;
lastSpawnerEgg = false;
setLastSpawner(event.getPlayer(), ArmorStand.class, false);
} else if (mat.name().endsWith("_SPAWN_EGG")) {
lastSpawner = event.getPlayer();
lastSpawning = null;
lastSpawnerEgg = true;
setLastSpawner(event.getPlayer(), null, true);
}
}
}
@ -96,9 +101,7 @@ public class AdvancedEntityLogging extends LoggingListener {
if (inHand != null) {
Material mat = inHand.getType();
if (mat.name().endsWith("_SPAWN_EGG")) {
lastSpawner = event.getPlayer();
lastSpawning = null;
lastSpawnerEgg = true;
setLastSpawner(event.getPlayer(), null, true);
}
}
}
@ -110,42 +113,60 @@ public class AdvancedEntityLogging extends LoggingListener {
return;
}
LivingEntity entity = event.getEntity();
if (!(entity instanceof Animals) && !(entity instanceof Villager) && !(entity instanceof Golem) && !(entity instanceof ArmorStand)) {
return;
}
Actor actor = null;
if (lastSpawner != null) {
if (lastSpawnerEgg && event.getSpawnReason() == SpawnReason.SPAWNER_EGG) {
actor = Actor.actorFromEntity(lastSpawner);
} else if (lastSpawning != null && lastSpawning.isAssignableFrom(entity.getClass())) {
actor = Actor.actorFromEntity(lastSpawner);
if (Config.isLogging(entity.getWorld(), EntityLogging.SPAWN, entity)) {
Actor actor = null;
if (lastSpawner != null && lastSpawner.getWorld() == entity.getWorld() && lastSpawner.getLocation().distance(entity.getLocation()) < 10) {
if (lastSpawnerEgg && event.getSpawnReason() == SpawnReason.SPAWNER_EGG) {
actor = Actor.actorFromEntity(lastSpawner);
} else if (lastSpawning != null && lastSpawning.isAssignableFrom(entity.getClass())) {
actor = Actor.actorFromEntity(lastSpawner);
}
}
if (actor == null) {
actor = new Actor(event.getSpawnReason().toString());
}
queueEntitySpawnOrKill(entity, actor, EntityChange.EntityChangeType.CREATE);
}
if (actor == null) {
actor = new Actor(event.getSpawnReason().toString());
}
queueEntitySpawnOrKill(entity, actor, EntityChange.EntityChangeType.CREATE);
}
resetLastSpawner();
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onHangingBreak(HangingBreakEvent event) {
Entity entity = event.getEntity();
Actor actor;
if (event instanceof HangingBreakByEntityEvent) {
actor = Actor.actorFromEntity(((HangingBreakByEntityEvent) event).getRemover());
} else {
actor = new Actor(event.getCause().toString());
public void onEntityDeath(EntityDeathEvent event) {
LivingEntity entity = event.getEntity();
if (Config.isLogging(entity.getWorld(), EntityLogging.DESTROY, entity)) {
Actor actor;
EntityDamageEvent lastDamage = entity.getLastDamageCause();
if (lastDamage instanceof EntityDamageByEntityEvent) {
actor = Actor.actorFromEntity(((EntityDamageByEntityEvent) lastDamage).getDamager());
} else {
actor = new Actor(lastDamage.getCause().toString());
}
queueEntitySpawnOrKill(entity, actor, EntityChange.EntityChangeType.KILL);
}
queueEntitySpawnOrKill(entity, actor, EntityChange.EntityChangeType.KILL);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onHangingPlace(HangingPlaceEvent event) {
Hanging entity = event.getEntity();
Actor actor = Actor.actorFromEntity(event.getPlayer());
queueEntitySpawnOrKill(entity, actor, EntityChange.EntityChangeType.CREATE);
if (Config.isLogging(entity.getWorld(), EntityLogging.SPAWN, entity)) {
Actor actor = Actor.actorFromEntity(event.getPlayer());
queueEntitySpawnOrKill(entity, actor, EntityChange.EntityChangeType.CREATE);
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onHangingBreak(HangingBreakEvent event) {
Entity entity = event.getEntity();
if (Config.isLogging(entity.getWorld(), EntityLogging.DESTROY, entity)) {
Actor actor;
if (event instanceof HangingBreakByEntityEvent) {
actor = Actor.actorFromEntity(((HangingBreakByEntityEvent) event).getRemover());
} else {
actor = new Actor(event.getCause().toString());
}
queueEntitySpawnOrKill(entity, actor, EntityChange.EntityChangeType.KILL);
}
}
protected void queueEntitySpawnOrKill(Entity entity, Actor actor, EntityChange.EntityChangeType changeType) {

View File

@ -10,6 +10,7 @@ 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;
@ -23,6 +24,7 @@ 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;
@ -316,4 +318,24 @@ public class Utils {
}
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());
}
}