diff --git a/docs/config.md b/docs/config.md index d54d74119..47b685f38 100644 --- a/docs/config.md +++ b/docs/config.md @@ -21,15 +21,35 @@ 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.* + +All blacklist entries are case-insensitive and ignore spaces. + +Comments can be added with the `%` character, anything after it will be ignored. + +An example blacklist.txt file would look like this: + ```text -Notch -#tnt +Notch % Do not log any action from the creator of Minecraft +#creeper /help minecraft:stone +minecraft:creeper +minecraft:shears @ #dispenser ``` -*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 CoreProtect v23.4+ is required.* +*For user filtered entries, CoreProtect v23.4+ is required.* \ No newline at end of file diff --git a/src/main/java/net/coreprotect/config/ConfigHandler.java b/src/main/java/net/coreprotect/config/ConfigHandler.java index 0275d0d61..bc7d62ae7 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.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 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 enum CacheType { 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 @@ private static Map syncMap() { 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 static void checkPlayers(Connection connection) { } } + 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) { @@ -176,6 +213,13 @@ private static void loadBlacklist() { } } + public static void initializeBlacklist(){ + File file = new File(ConfigHandler.path, BLACKLIST_FILENAME); + if (!file.exists()){ + CoreProtect.getInstance().saveResource(BLACKLIST_FILENAME, false); + } + } + private static void loadConfig() { try { Config.init(); @@ -517,6 +561,7 @@ public static boolean performInitialization(boolean startup) { ConfigHandler.loadConfig(); // Load (or create) the configuration file. ConfigHandler.loadDatabase(); // Initialize MySQL and create tables if necessary. + ConfigHandler.initializeBlacklist(); // Create blacklist.txt file if it doesn't exist. if (startup) { ListenerHandler.registerNetworking(); // Register channels for networking API diff --git a/src/main/java/net/coreprotect/database/logger/BlockBreakLogger.java b/src/main/java/net/coreprotect/database/logger/BlockBreakLogger.java index cfe061844..16111e244 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 @@ private 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 @@ else if (checkType.equals(Material.AIR) || checkType.equals(Material.CAVE_AIR)) 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 59db0ddb9..8a7bd94c5 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 @@ private 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 @@ else if (forceType != null && !type.equals(forceType)) { 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 b14e2886f..8a52b2351 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 @@ private 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 d85faeca4..99a46a5c5 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 @@ private 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 bb9a7183b..ee3594ceb 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 @@ else if (item != null) { 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 @@ protected static void logTransaction(PreparedStatement preparedStmt, int batchCo 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 @@ protected static void logTransaction(PreparedStatement preparedStmt, int batchCo 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 f929bf8fa..03e166ae5 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 @@ 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 @@ private 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 2092822b8..e482ea530 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 @@ private 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 @@ protected static void logTransaction(PreparedStatement preparedStmt, int batchCo 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 @@ protected static void logTransaction(PreparedStatement preparedStmt, int batchCo 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 c4a7c462e..00ad5c7fa 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 @@ private 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 a11d21c8d..570e1dd34 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 @@ private 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 b10fd1786..06817c229 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 @@ private 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 42d3ca851..44846c083 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 @@ private 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 0cfb31915..eed90c71d 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 @@ private 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 2e538625d..cfcf346b5 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 @@ private 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 a639c1465..0e6e0f29c 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 @@ private 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; } diff --git a/src/main/resources/blacklist.txt b/src/main/resources/blacklist.txt new file mode 100644 index 000000000..f60dd838a --- /dev/null +++ b/src/main/resources/blacklist.txt @@ -0,0 +1,5 @@ +% For more information, visit https://docs.coreprotect.net/config/ + +% Notch +% #creeper +% /help