diff --git a/docs/config.md b/docs/config.md index d54d7411..502b4c9e 100644 --- a/docs/config.md +++ b/docs/config.md @@ -21,15 +21,30 @@ Secondary configuration files override the value specified in config.yml. If you To disable logging for specific users, blocks or commands, simply do the following: 1. In the CoreProtect plugin directory, create a file named `blacklist.txt`. -2. Enter the names of the users (or commands) you'd like to disable logging for (each username on a new line). +2. Enter the names of the users, commands, blocks, or entities you'd like to disable logging for (each entry on a new line). 3. Either restart your server, or type "/co reload" in-game. -This can be used to disable logging for non-player users, such as "#creeper". For example, if you'd like to disable logging for the user "Notch", TNT explosions, stone blocks, and the "/help" command, the blacklist.txt file would look like this: +The blacklist supports disabling logs for: +- Users, which includes Players and non-player users, such as "#creeper" +- Commands, such as `/help` +- Blocks, such as minecraft:stone. Only `block` actions are affected. +- Entities, such as minecraft:creeper, which will disable logging the death for that entity. *Note: renamed entities will be logged even if blacklisted.* +- Filters can also be specified for a particular user, by using the `@` symbol after the specific item, block, or entity namespaced ID. The format is `id@user`. This will filter all `block`, `kill`, `item` and `container` actions involving that particular block, item or mob, only when caused by the specified player or non-player user. +- Items and container actions are only affected by filtered blacklist entries, not by generic item or block IDs. + +*Please note that you must include the namespace (e.g. minecraft:) for blocks, entities and items.* + +An example blacklist.txt file would look like this: + ```text -Notch -#tnt -/help -minecraft:stone +Notch # User +#tnt # TNT explosions +/help # Help command +minecraft:stone # Stone blocks +minecraft:creeper # Creeper entity +minecraft:shears@#dispenser # Shears being dispensed ``` -*Please note that to disable logging for blocks, CoreProtect v23+ is required, and you must include the namespace. For example, to disable logging for dirt, you must add it as "minecraft:dirt".* \ No newline at end of file + +*Please note that to disable logging for blocks, CoreProtect v23+ is required.* +*To disable logging for entities or to use filtering, CoreProtect v23.4+ is required.* diff --git a/src/main/java/net/coreprotect/config/ConfigHandler.java b/src/main/java/net/coreprotect/config/ConfigHandler.java index 07bc75fb..5b54ef57 100644 --- a/src/main/java/net/coreprotect/config/ConfigHandler.java +++ b/src/main/java/net/coreprotect/config/ConfigHandler.java @@ -8,6 +8,7 @@ import java.sql.Statement; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -23,6 +24,7 @@ import org.bukkit.plugin.PluginManager; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; +import net.coreprotect.CoreProtect; import net.coreprotect.bukkit.BukkitAdapter; import net.coreprotect.consumer.Queue; import net.coreprotect.database.Database; @@ -65,6 +67,10 @@ public class ConfigHandler extends Queue { public static String prefixConfig = "co_"; public static int maximumPoolSize = 10; + public static final String BLACKLIST_COMMENT_SEPARATOR = "#"; + public static final String BLACKLIST_FILTER_SEPARATOR = "@"; + public static final String BLACKLIST_FILENAME = "blacklist.txt"; + public static HikariDataSource hikariDataSource = null; public static final CentralProcessor processorInfo = SystemUtils.getProcessorInfo(); public static final boolean isSpigot = VersionUtils.isSpigot(); @@ -100,6 +106,7 @@ public class ConfigHandler extends Queue { public static Map rollbackHash = syncMap(); public static Map inspecting = syncMap(); public static Map blacklist = syncMap(); + public static Map> FilteredBlacklist = syncMap(); public static Map loggingChest = syncMap(); public static Map loggingItem = syncMap(); public static ConcurrentHashMap> transactingChest = new ConcurrentHashMap<>(); @@ -152,23 +159,53 @@ public class ConfigHandler extends Queue { } } + public static boolean isBlacklisted(String user){ + return ConfigHandler.blacklist.containsKey(user.toLowerCase(Locale.ROOT)); + } + + public static boolean isBlacklisted(String user, String object){ + if (ConfigHandler.blacklist.containsKey(object) || ConfigHandler.blacklist.containsKey(user.toLowerCase(Locale.ROOT))){ + return true; + } + return isFilterBlacklisted(user, object); + } + + public static boolean isFilterBlacklisted(String user, String object){ + HashSet blUserSet = FilteredBlacklist.get(object); + if (blUserSet == null){ + return false; + } + return blUserSet.contains(user.toLowerCase(Locale.ROOT)); + } + private static void loadBlacklist() { try { ConfigHandler.blacklist.clear(); - String blacklist = ConfigHandler.path + "blacklist.txt"; - boolean exists = (new File(blacklist)).exists(); - if (exists) { - RandomAccessFile blfile = new RandomAccessFile(blacklist, "rw"); - long blc = blfile.length(); - if (blc > 0) { - while (blfile.getFilePointer() < blfile.length()) { - String blacklistUser = blfile.readLine().replaceAll(" ", "").toLowerCase(Locale.ROOT); - if (blacklistUser.length() > 0) { - ConfigHandler.blacklist.put(blacklistUser, true); - } + ConfigHandler.FilteredBlacklist.clear(); + + File file = new File(ConfigHandler.path, BLACKLIST_FILENAME); + if (!file.exists()){ + return; + } + try (RandomAccessFile blfile = new RandomAccessFile(file, "r")){ + if (blfile.length() == 0){ + return; + } + String blLine; + while (( blLine = blfile.readLine()) != null ) { + blLine = blLine.replace(" ", "").toLowerCase(Locale.ROOT).split(BLACKLIST_COMMENT_SEPARATOR)[0]; + if (blLine.isEmpty()) { + continue; + } + String[] blSplit = blLine.split(BLACKLIST_FILTER_SEPARATOR); + if (blSplit.length == 1){ + ConfigHandler.blacklist.put(blLine, true); + } else { + ConfigHandler.FilteredBlacklist. + computeIfAbsent(blSplit[0], k-> new HashSet<>()) + .add(blSplit[1]); } } - blfile.close(); } } catch (Exception e) { diff --git a/src/main/java/net/coreprotect/database/logger/BlockBreakLogger.java b/src/main/java/net/coreprotect/database/logger/BlockBreakLogger.java index cfe06184..16111e24 100644 --- a/src/main/java/net/coreprotect/database/logger/BlockBreakLogger.java +++ b/src/main/java/net/coreprotect/database/logger/BlockBreakLogger.java @@ -26,10 +26,6 @@ public class BlockBreakLogger { public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int type, int data, List meta, String blockData, String overrideData) { try { - if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || location == null) { - return; - } - Material checkType = net.coreprotect.utility.MaterialUtils.getType(type); if (checkType == null) { return; @@ -38,7 +34,7 @@ public class BlockBreakLogger { return; } - if (ConfigHandler.blacklist.get(checkType.getKey().toString()) != null) { + if (ConfigHandler.isBlacklisted(user, checkType.getKey().toString())) { return; } diff --git a/src/main/java/net/coreprotect/database/logger/BlockPlaceLogger.java b/src/main/java/net/coreprotect/database/logger/BlockPlaceLogger.java index 59db0ddb..8a7bd94c 100644 --- a/src/main/java/net/coreprotect/database/logger/BlockPlaceLogger.java +++ b/src/main/java/net/coreprotect/database/logger/BlockPlaceLogger.java @@ -28,10 +28,6 @@ public class BlockPlaceLogger { public static void log(PreparedStatement preparedStmt, int batchCount, String user, BlockState block, int replacedType, int replacedData, Material forceType, int forceData, boolean force, List meta, String blockData, String replaceBlockData) { try { - if (user == null || ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) { - return; - } - Material type = block.getType(); if (blockData == null && (forceType == null || (!forceType.equals(Material.WATER)) && (!forceType.equals(Material.LAVA)))) { blockData = block.getBlockData().getAsString(); @@ -58,7 +54,7 @@ public class BlockPlaceLogger { return; } - if (ConfigHandler.blacklist.get(type.getKey().toString()) != null) { + if (ConfigHandler.isBlacklisted(user, type.getKey().toString())){ return; } diff --git a/src/main/java/net/coreprotect/database/logger/ChatLogger.java b/src/main/java/net/coreprotect/database/logger/ChatLogger.java index b14e2886..8a52b235 100644 --- a/src/main/java/net/coreprotect/database/logger/ChatLogger.java +++ b/src/main/java/net/coreprotect/database/logger/ChatLogger.java @@ -17,7 +17,7 @@ public class ChatLogger { public static void log(PreparedStatement preparedStmt, int batchCount, long time, Location location, String user, String message) { try { - if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) { + if (ConfigHandler.isBlacklisted(user)) { return; } int x = location.getBlockX(); diff --git a/src/main/java/net/coreprotect/database/logger/CommandLogger.java b/src/main/java/net/coreprotect/database/logger/CommandLogger.java index d85faeca..99a46a5c 100644 --- a/src/main/java/net/coreprotect/database/logger/CommandLogger.java +++ b/src/main/java/net/coreprotect/database/logger/CommandLogger.java @@ -22,10 +22,10 @@ public class CommandLogger { public static void log(PreparedStatement preparedStmt, int batchCount, long time, Location location, String user, String message) { try { - if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) { + if (ConfigHandler.isBlacklisted(user)) { return; } - if (ConfigHandler.blacklist.get(((message + " ").split(" "))[0].toLowerCase(Locale.ROOT)) != null) { + if (ConfigHandler.isBlacklisted(((message + " ").split(" "))[0])) { return; } diff --git a/src/main/java/net/coreprotect/database/logger/ContainerLogger.java b/src/main/java/net/coreprotect/database/logger/ContainerLogger.java index bb9a7183..ee3594ce 100644 --- a/src/main/java/net/coreprotect/database/logger/ContainerLogger.java +++ b/src/main/java/net/coreprotect/database/logger/ContainerLogger.java @@ -209,7 +209,7 @@ public class ContainerLogger extends Queue { protected static void logTransaction(PreparedStatement preparedStmt, int batchCount, String user, Material type, String faceData, ItemStack[] items, int action, Location location) { try { - if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) { + if (ConfigHandler.isBlacklisted(user)) { return; } boolean success = false; @@ -218,6 +218,10 @@ public class ContainerLogger extends Queue { if (item != null) { if (item.getAmount() > 0 && !BlockUtils.isAir(item.getType())) { // Object[] metadata = new Object[] { slot, item.getItemMeta() }; + if (ConfigHandler.isFilterBlacklisted(user, item.getType().getKey().toString())){ + continue; + } + List>> metadata = ItemMetaHandler.serialize(item, type, faceData, slot); if (metadata.size() == 0) { metadata = null; @@ -230,7 +234,8 @@ public class ContainerLogger extends Queue { if (event.isCancelled()) { return; - } + } + int userId = UserStatement.getId(preparedStmt, event.getUser(), true); Location eventLocation = event.getLocation(); diff --git a/src/main/java/net/coreprotect/database/logger/EntityKillLogger.java b/src/main/java/net/coreprotect/database/logger/EntityKillLogger.java index f929bf8f..03e166ae 100644 --- a/src/main/java/net/coreprotect/database/logger/EntityKillLogger.java +++ b/src/main/java/net/coreprotect/database/logger/EntityKillLogger.java @@ -3,11 +3,11 @@ package net.coreprotect.database.logger; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.List; -import java.util.Locale; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.block.BlockState; +import org.bukkit.entity.EntityType; import net.coreprotect.CoreProtect; import net.coreprotect.config.Config; @@ -27,7 +27,18 @@ public class EntityKillLogger { public static void log(PreparedStatement preparedStmt, PreparedStatement preparedStmt2, int batchCount, String user, BlockState block, List data, int type) { try { - if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) { + if (ConfigHandler.isBlacklisted(user)){ + return; + } + + EntityType checkType = net.coreprotect.utility.EntityUtils.getEntityType(type); + if (checkType == null) { + return; + } + // Ignore blacklist if the entity has a custom name + // data[4] contains custom name data + if (ConfigHandler.isBlacklisted(user, checkType.getKey().toString()) && + !(data.size() > 4 && data.get(4) != null)){ return; } diff --git a/src/main/java/net/coreprotect/database/logger/ItemLogger.java b/src/main/java/net/coreprotect/database/logger/ItemLogger.java index 2092822b..e482ea53 100644 --- a/src/main/java/net/coreprotect/database/logger/ItemLogger.java +++ b/src/main/java/net/coreprotect/database/logger/ItemLogger.java @@ -44,7 +44,7 @@ public class ItemLogger { public static void log(PreparedStatement preparedStmt, int batchCount, Location location, int offset, String user) { try { - if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) { + if (ConfigHandler.isBlacklisted(user)) { return; } @@ -124,6 +124,10 @@ public class ItemLogger { for (ItemStack item : items) { if (item != null && item.getAmount() > 0 && !BlockUtils.isAir(item.getType())) { // Object[] metadata = new Object[] { slot, item.getItemMeta() }; + if (ConfigHandler.isFilterBlacklisted(user, item.getType().getKey().toString())){ + continue; + } + List>> data = ItemMetaHandler.serialize(item, null, null, 0); if (data.size() == 0) { data = null; @@ -137,7 +141,7 @@ public class ItemLogger { if (event.isCancelled()) { return; } - + int userId = UserStatement.getId(preparedStmt, event.getUser(), true); Location eventLocation = event.getLocation(); int wid = WorldUtils.getWorldId(eventLocation.getWorld().getName()); diff --git a/src/main/java/net/coreprotect/database/logger/PlayerInteractLogger.java b/src/main/java/net/coreprotect/database/logger/PlayerInteractLogger.java index c4a7c462..00ad5c7f 100644 --- a/src/main/java/net/coreprotect/database/logger/PlayerInteractLogger.java +++ b/src/main/java/net/coreprotect/database/logger/PlayerInteractLogger.java @@ -26,7 +26,7 @@ public class PlayerInteractLogger { public static void log(PreparedStatement preparedStmt, int batchCount, String user, BlockState block, Material blockType) { try { int type = MaterialUtils.getBlockId(blockType.name(), true); - if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || MaterialUtils.getType(type).equals(Material.AIR) || MaterialUtils.getType(type).equals(Material.CAVE_AIR)) { + if (ConfigHandler.isBlacklisted(user) || MaterialUtils.getType(type).equals(Material.AIR) || MaterialUtils.getType(type).equals(Material.CAVE_AIR)) { return; } diff --git a/src/main/java/net/coreprotect/database/logger/PlayerKillLogger.java b/src/main/java/net/coreprotect/database/logger/PlayerKillLogger.java index a11d21c8..570e1dd3 100644 --- a/src/main/java/net/coreprotect/database/logger/PlayerKillLogger.java +++ b/src/main/java/net/coreprotect/database/logger/PlayerKillLogger.java @@ -23,7 +23,7 @@ public class PlayerKillLogger { public static void log(PreparedStatement preparedStmt, int batchCount, String user, BlockState block, String player) { try { - if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) { + if (ConfigHandler.isBlacklisted(user)) { return; } diff --git a/src/main/java/net/coreprotect/database/logger/PlayerSessionLogger.java b/src/main/java/net/coreprotect/database/logger/PlayerSessionLogger.java index b10fd178..06817c22 100644 --- a/src/main/java/net/coreprotect/database/logger/PlayerSessionLogger.java +++ b/src/main/java/net/coreprotect/database/logger/PlayerSessionLogger.java @@ -17,7 +17,7 @@ public class PlayerSessionLogger { public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int time, int action) { try { - if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) { + if (ConfigHandler.isBlacklisted(user)) { return; } int x = location.getBlockX(); diff --git a/src/main/java/net/coreprotect/database/logger/SignTextLogger.java b/src/main/java/net/coreprotect/database/logger/SignTextLogger.java index 42d3ca85..44846c08 100644 --- a/src/main/java/net/coreprotect/database/logger/SignTextLogger.java +++ b/src/main/java/net/coreprotect/database/logger/SignTextLogger.java @@ -22,7 +22,7 @@ public class SignTextLogger { public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int action, int color, int colorSecondary, int data, boolean isWaxed, boolean isFront, String line1, String line2, String line3, String line4, String line5, String line6, String line7, String line8, int timeOffset) { try { - if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) { + if (ConfigHandler.isBlacklisted(user)) { return; } diff --git a/src/main/java/net/coreprotect/database/logger/SkullBreakLogger.java b/src/main/java/net/coreprotect/database/logger/SkullBreakLogger.java index 0cfb3191..eed90c71 100644 --- a/src/main/java/net/coreprotect/database/logger/SkullBreakLogger.java +++ b/src/main/java/net/coreprotect/database/logger/SkullBreakLogger.java @@ -21,7 +21,7 @@ public class SkullBreakLogger { public static void log(PreparedStatement preparedStmt, PreparedStatement preparedStmt2, int batchCount, String user, BlockState block) { try { - if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || block == null) { + if (ConfigHandler.isBlacklisted(user) || block == null) { return; } int time = (int) (System.currentTimeMillis() / 1000L); diff --git a/src/main/java/net/coreprotect/database/logger/SkullPlaceLogger.java b/src/main/java/net/coreprotect/database/logger/SkullPlaceLogger.java index 2e538625..cfcf346b 100644 --- a/src/main/java/net/coreprotect/database/logger/SkullPlaceLogger.java +++ b/src/main/java/net/coreprotect/database/logger/SkullPlaceLogger.java @@ -21,7 +21,7 @@ public class SkullPlaceLogger { public static void log(PreparedStatement preparedStmt, PreparedStatement preparedStmt2, int batchCount, String user, BlockState block, int replaceType, int replaceData) { try { - if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || block == null) { + if (ConfigHandler.isBlacklisted(user) || block == null) { return; } int time = (int) (System.currentTimeMillis() / 1000L); diff --git a/src/main/java/net/coreprotect/database/logger/UsernameLogger.java b/src/main/java/net/coreprotect/database/logger/UsernameLogger.java index a639c146..0e6e0f29 100644 --- a/src/main/java/net/coreprotect/database/logger/UsernameLogger.java +++ b/src/main/java/net/coreprotect/database/logger/UsernameLogger.java @@ -15,7 +15,7 @@ public class UsernameLogger { public static void log(Connection connection, String user, String uuid, int configUsernames, int time) { try { - if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) { + if (ConfigHandler.isBlacklisted(user)) { return; }