diff --git a/.woodpeck.yml b/.woodpeck.yml new file mode 100644 index 0000000..9626f2f --- /dev/null +++ b/.woodpeck.yml @@ -0,0 +1,27 @@ +clone: + git: + image: "woodpeckerci/plugin-git:next" +pipeline: + compliance: + commands: + - "gradle build" + - "gradle test" + image: "gradle:7.4-jdk17" + when: + event: pull_request + build: + commands: + - "gradle shadowJar" + image: "gradle:7.4-jdk17" + when: + branch: main + release: + image: jolheiser/drone-gitea-main:latest + settings: + token: + from_secret: gitea_token + base: https://git.jojodev.com + files: + - "build/libs/*.jar" + when: + branch: main \ No newline at end of file diff --git a/README.md b/README.md index 9463980..81f1212 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,37 @@ -# Hush [![Build Status](https://drone.etztech.xyz/api/badges/Minecraft/Hush/status.svg)](https://drone.etztech.xyz/Minecraft/Hush) +# Hush [![Build Status](https://ci.jojodev.com/api/badges/Minecraft/Hush/status.svg)(https://ci.jojodev.com/Minecraft/Hush) A plugin to monitor chat for forbidden phrases. ## Watch Lists -Watch lists specifies phrases to monitor. Each watch list has an associated permission. In the form of -`hush.`. A user with this permission will have their chat messages checked to see if -they match the corresponding watch list. +Watchlist are groups of categories Hush monitors for. To enable a watchlist for a player, +they should be given the `hush.` permission. -Watch lists contain two types of phrases, Monitored and Banned. +### Categories +A category is a group of regex filters, and the actions to run when a player matches one of those filters. +An example of a category is shown below: -### Monitored -Phrases that should be checked for context. If a user says one of these phrases, a Discord webhook is -sent out. +```yaml + # "ban" category + ban: + # Filters to search for in chat + filters: + - "heck" + - "fricks" + # Optional, commands to run when a filter matches. {player} is replaced with the player's name. + commands: + - "ban {player}" + # Optional, should the message that matched the filter be cancelled? Default is "false". + cancel_msg: true +``` -### Banned -A banned phrase results in an immediate ban. If a user says a banned phrase, they are kicked and added -to the ban list. A webhook is also sent to Discord. +## Permissions +* `hush.admin` - allows access to the `hush` command +* `hush.` - used to determine if a player's messages should be checked by a watchlist + +### Commands +* `hush reload` - reloads the plugin config ## Example Config [Config](src/main/resources/config.yml) -## Permissions -[Permissions](src/main/resources/plugin.yml) - ## License [MIT](LICENSE) diff --git a/build.gradle b/build.gradle index 22c8d2c..ca45bad 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'com.zerohighdef' -version = '0.2.1' +version = '0.2.2' sourceCompatibility = '8' @@ -16,7 +16,7 @@ repositories { } maven { name = 'etztech-repo' - url = 'http://repo.etztech.xyz/' + url = 'https://mvn.jojodev.com/releases/' } maven {url = 'https://jcenter.bintray.com'} maven {url = 'https://jitpack.io'} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 7ad10bf..41dfb87 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists \ No newline at end of file +zipStorePath=wrapper/dists diff --git a/src/main/java/com/zerohighdef/hush/Hush.java b/src/main/java/com/zerohighdef/hush/Hush.java index 76092da..fc8a088 100644 --- a/src/main/java/com/zerohighdef/hush/Hush.java +++ b/src/main/java/com/zerohighdef/hush/Hush.java @@ -44,7 +44,8 @@ public final class Hush extends JavaPlugin { ConfigurationSection categorySection = permissionSection.getConfigurationSection(category); List filters = categorySection.getStringList("filters"); List commands = categorySection.getStringList("commands"); - watchCategories.add(new WatchCategory(category, filters, commands)); + boolean cancelMsg = categorySection.getBoolean("cancel_msg", false); + watchCategories.add(new WatchCategory(category, filters, commands, cancelMsg)); } watchLists.put(permission, watchCategories); } diff --git a/src/main/java/com/zerohighdef/hush/WatchCategory.java b/src/main/java/com/zerohighdef/hush/WatchCategory.java index 1af4fe2..b15fdc9 100644 --- a/src/main/java/com/zerohighdef/hush/WatchCategory.java +++ b/src/main/java/com/zerohighdef/hush/WatchCategory.java @@ -9,11 +9,13 @@ public class WatchCategory { private final String categoryName; private final List patterns; private final List commands; + private final boolean cancelMsg; - public WatchCategory(String categoryName, List patterns, List commands) { + public WatchCategory(String categoryName, List patterns, List commands, boolean cancelMsg) { this.categoryName = categoryName; this.patterns = buildPattern(patterns); this.commands = commands; + this.cancelMsg = cancelMsg; } private static List buildPattern(List patternList) { @@ -42,4 +44,8 @@ public class WatchCategory { public List getCommands() { return commands; } + + public boolean getCancelMsg() { + return cancelMsg; + } } diff --git a/src/main/java/com/zerohighdef/hush/commands/MainCommand.java b/src/main/java/com/zerohighdef/hush/commands/MainCommand.java index 8383baf..414e8bc 100644 --- a/src/main/java/com/zerohighdef/hush/commands/MainCommand.java +++ b/src/main/java/com/zerohighdef/hush/commands/MainCommand.java @@ -21,6 +21,10 @@ public class MainCommand implements CommandExecutor { @Override public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) { if (!commandSender.hasPermission("hush.admin")) { + BaseComponent[] message = new ComponentBuilder() + .append("You don't have permission to to use this command.").color(ChatColor.RED) + .create(); + commandSender.spigot().sendMessage(message); return true; } if (args.length == 0) { diff --git a/src/main/java/com/zerohighdef/hush/listeners/HushAsyncChatListener.java b/src/main/java/com/zerohighdef/hush/listeners/HushAsyncChatListener.java index 86a484a..ff85bf8 100644 --- a/src/main/java/com/zerohighdef/hush/listeners/HushAsyncChatListener.java +++ b/src/main/java/com/zerohighdef/hush/listeners/HushAsyncChatListener.java @@ -26,59 +26,69 @@ public class HushAsyncChatListener implements Listener { } @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public boolean onChat(AsyncPlayerChatEvent event) { + public void onChat(AsyncPlayerChatEvent event) { String chatMessage = event.getMessage(); Player sender = event.getPlayer(); + for (String permission : plugin.getWatchLists().keySet()) { if (sender.hasPermission("hush." + permission)) { for (WatchCategory category : plugin.getWatchLists().get(permission)) { - checkMessage(category, permission, sender, chatMessage); + boolean is_match = checkMessage(category, permission, sender, chatMessage); + + // If the message matched, and the category requires the event to be canceled + if (is_match && category.getCancelMsg()) { + // cancel event + event.setCancelled(true); + } } } } - - return true; } private void runCommand(String command) { Bukkit.getScheduler().runTask(plugin, () -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command)); } - private void checkMessage(WatchCategory category, String watchList, Player player, String chatMessage) { + private boolean checkMessage(WatchCategory category, String watchList, Player player, String chatMessage) { Matcher match = category.checkPatterns(chatMessage); - if (match != null) { - String playerName = player.getName(); - String webhookURL = plugin.getConfig().getString("webhook"); - - for (String command: category.getCommands()) { - runCommand(command.replace("{player}", playerName)); - } - - plugin.log(String.format("%s matched filter in %s.%s", playerName, watchList, category.getCategoryName())); - - if (webhookURL != null && !plugin.isInCoolDown(player)) { - plugin.addCoolDown(player); - chatMessage = match.replaceAll("**$0**"); - String message = Javacord.escapeFormat(playerName) + " said: " + chatMessage; - Embed embed = new Embed() - .color(0xC70039) - .description(message) - .addField(new Field("Watchlist", String.format("`%s`", watchList))) - .addField(new Field("Category", String.format("`%s`", category.getCategoryName()))) - .author(new Author(playerName, "", String.format("https://minotar.net/helm/%s/100.png", playerName), "")) - .timestamp(OffsetDateTime.now()); - - Webhook webhook = new Webhook("@here", embed); - - this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, () -> { - try { - Javacord.sendWebhook(webhookURL, webhook); - } catch (Exception e) { - this.plugin.log("Webhook failed to send."); - } - }); - } + if (match == null) { + // message was not a match + return false; } + + String playerName = player.getName(); + String webhookURL = plugin.getConfig().getString("webhook"); + + for (String command: category.getCommands()) { + runCommand(command.replace("{player}", playerName)); + } + + plugin.log(String.format("%s matched filter in %s.%s", playerName, watchList, category.getCategoryName())); + + if (webhookURL != null && !plugin.isInCoolDown(player)) { + plugin.addCoolDown(player); + chatMessage = match.replaceAll("**$0**"); + String message = Javacord.escapeFormat(playerName) + " said: " + chatMessage; + Embed embed = new Embed() + .color(0xC70039) + .description(message) + .addField(new Field("Watchlist", String.format("`%s`", watchList))) + .addField(new Field("Category", String.format("`%s`", category.getCategoryName()))) + .author(new Author(playerName, "", String.format("https://minotar.net/helm/%s/100.png", playerName), "")) + .timestamp(OffsetDateTime.now()); + + Webhook webhook = new Webhook("@here", embed); + + this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, () -> { + try { + Javacord.sendWebhook(webhookURL, webhook); + } catch (Exception e) { + this.plugin.log("Webhook failed to send."); + } + }); + } + + return true; } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 797ffa7..81bbf2b 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -5,18 +5,22 @@ cooldown: 5 watch_lists: # Permission to check - # To enable the check, give the group the 'hush.' permission + # To enable the check for a user, give the 'hush.' permission guest: + # "ban" category ban: - # Filters to search for + # Filters to search for in chat filters: - "heck" - "fricks" - # Commands to run {player} is replaced with the player's name + # Optional, commands to run when a filter matches. {player} is replaced with the player's name. commands: - "ban {player}" + # Optional, should the message that matched the filter be cancelled. Default is "false". + cancel_msg: true + # "monitor" category monitor: - # Filters to search for + # Filters to search for in chat filters: - "stupid" - "dumb" \ No newline at end of file