Allow configurable commands for each watch category (#8)
iKnowHowToCamelCase Added fields to webhook and added Shadow gradle plugin + Update .drone.yml Allow configurable commands for each watch category + Fixes #7 + Each watchlist has an associated permission and a list of categories + Each category has a list of filters and an optional list of commands + When a match occurs, a warning is sent out and the commands are run Co-authored-by: Joey Hines <joey@ahines.net> Reviewed-on: https://git.etztech.xyz/Minecraft/Hush/pulls/8 Reviewed-by: Etzelia <etzelia@hotmail.com>master
parent
a266178098
commit
8cd551112e
|
@ -30,7 +30,7 @@ steps:
|
||||||
pull: always
|
pull: always
|
||||||
image: gradle:6.6
|
image: gradle:6.6
|
||||||
commands:
|
commands:
|
||||||
- gradle build
|
- gradle shadowjar
|
||||||
- name: gitea-release
|
- name: gitea-release
|
||||||
pull: always
|
pull: always
|
||||||
image: jolheiser/drone-gitea-main:latest
|
image: jolheiser/drone-gitea-main:latest
|
||||||
|
|
|
@ -3,7 +3,7 @@ A plugin to monitor chat for forbidden phrases.
|
||||||
|
|
||||||
## Watch Lists
|
## Watch Lists
|
||||||
Watch lists specifies phrases to monitor. Each watch list has an associated permission. In the form of
|
Watch lists specifies phrases to monitor. Each watch list has an associated permission. In the form of
|
||||||
`hush.<list_name>`. A user with this permission will have their chat messages checked to see if
|
`hush.<watchlist_name>`. A user with this permission will have their chat messages checked to see if
|
||||||
they match the corresponding watch list.
|
they match the corresponding watch list.
|
||||||
|
|
||||||
Watch lists contain two types of phrases, Monitored and Banned.
|
Watch lists contain two types of phrases, Monitored and Banned.
|
||||||
|
|
10
build.gradle
10
build.gradle
|
@ -1,9 +1,10 @@
|
||||||
plugins {
|
plugins {
|
||||||
|
id 'com.github.johnrengelman.shadow' version '6.0.0'
|
||||||
id 'java'
|
id 'java'
|
||||||
}
|
}
|
||||||
|
|
||||||
group = 'com.zerohighdef'
|
group = 'com.zerohighdef'
|
||||||
version = '0.1'
|
version = '0.2.0'
|
||||||
|
|
||||||
sourceCompatibility = '8'
|
sourceCompatibility = '8'
|
||||||
|
|
||||||
|
@ -23,7 +24,10 @@ repositories {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'org.spigotmc:spigot-api:1.16.3-R0.1-SNAPSHOT'
|
compileOnly 'org.spigotmc:spigot-api:1.16.3-R0.1-SNAPSHOT'
|
||||||
compileOnly 'xyz.etztech:plugin-api:1.0.8'
|
compile 'xyz.etztech:javacord:0.2.2'
|
||||||
compileOnly 'xyz.etztech:javacord:0.2.0'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shadowJar {
|
||||||
|
configurations = [project.configurations.compile]
|
||||||
|
archiveClassifier = ""
|
||||||
|
}
|
||||||
|
|
|
@ -3,16 +3,17 @@ package com.zerohighdef.hush;
|
||||||
import com.zerohighdef.hush.commands.MainCommand;
|
import com.zerohighdef.hush.commands.MainCommand;
|
||||||
import com.zerohighdef.hush.listeners.HushAsyncChatListener;
|
import com.zerohighdef.hush.listeners.HushAsyncChatListener;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public final class Hush extends JavaPlugin {
|
public final class Hush extends JavaPlugin {
|
||||||
private final Logger log = Logger.getLogger("Minecraft");
|
private final Logger log = Logger.getLogger("Minecraft");
|
||||||
private List<WatchList> watchLists;
|
private HashMap<String, List<WatchCategory>> watchLists;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
@ -32,15 +33,20 @@ public final class Hush extends JavaPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildWatchLists() {
|
private void buildWatchLists() {
|
||||||
watchLists = new LinkedList<>();
|
watchLists = new HashMap<>();
|
||||||
ConfigurationSection watchListSection = getConfig().getConfigurationSection("watch_lists");
|
ConfigurationSection watchListSection = getConfig().getConfigurationSection("watch_lists");
|
||||||
|
|
||||||
for (String permission: watchListSection.getKeys(false)) {
|
for (String permission: watchListSection.getKeys(false)) {
|
||||||
String banMessage = watchListSection.getString(permission + ".ban_message");
|
ConfigurationSection permissionSection = watchListSection.getConfigurationSection(permission);
|
||||||
List<String> banPatterns = watchListSection.getStringList(permission + ".ban");
|
LinkedList<WatchCategory> watchCategories = new LinkedList<>();
|
||||||
List<String> monitorPatterns = watchListSection.getStringList(permission + ".monitor");
|
|
||||||
|
|
||||||
watchLists.add(new WatchList("hush." + permission, banMessage, banPatterns, monitorPatterns));
|
for (String category: permissionSection.getKeys(false)) {
|
||||||
|
ConfigurationSection categorySection = permissionSection.getConfigurationSection(category);
|
||||||
|
List<String> filters = categorySection.getStringList("filters");
|
||||||
|
List<String> commands = categorySection.getStringList("commands");
|
||||||
|
watchCategories.add(new WatchCategory(category, filters, commands));
|
||||||
|
}
|
||||||
|
watchLists.put(permission, watchCategories);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +54,7 @@ public final class Hush extends JavaPlugin {
|
||||||
log.info( "[Hush]: " + message );
|
log.info( "[Hush]: " + message );
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<WatchList> getWatchLists() {
|
public Map<String, List<WatchCategory>> getWatchLists() {
|
||||||
return watchLists;
|
return watchLists;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.zerohighdef.hush;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class WatchCategory {
|
||||||
|
private final String categoryName;
|
||||||
|
private final List<Pattern> patterns;
|
||||||
|
private final List<String> commands;
|
||||||
|
|
||||||
|
public WatchCategory(String categoryName, List<String> patterns, List<String> commands) {
|
||||||
|
this.categoryName = categoryName;
|
||||||
|
this.patterns = buildPattern(patterns);
|
||||||
|
this.commands = commands;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Pattern> buildPattern(List<String> patternList) {
|
||||||
|
return patternList
|
||||||
|
.stream()
|
||||||
|
.map(p -> Pattern.compile(String.format("(%s)", p)))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Matcher checkPatterns(String string) {
|
||||||
|
for (Pattern p: patterns) {
|
||||||
|
Matcher matcher = p.matcher(string);
|
||||||
|
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCategoryName() {
|
||||||
|
return categoryName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getCommands() {
|
||||||
|
return commands;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,44 +0,0 @@
|
||||||
package com.zerohighdef.hush;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class WatchList {
|
|
||||||
private final String permission;
|
|
||||||
private final String banMessage;
|
|
||||||
private final List<Pattern> banPatterns;
|
|
||||||
private final List<Pattern> monitorPatterns;
|
|
||||||
|
|
||||||
WatchList(String permission, String banMessage, List<String> banPatterns, List<String> monitorPatterns) {
|
|
||||||
this.permission = permission;
|
|
||||||
this.banMessage = banMessage;
|
|
||||||
this.banPatterns = WatchList.buildPattern(banPatterns);
|
|
||||||
this.monitorPatterns = WatchList.buildPattern(monitorPatterns);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Pattern> buildPattern(List<String> patternList) {
|
|
||||||
return patternList
|
|
||||||
.stream()
|
|
||||||
.map(p -> Pattern.compile(String.format("(%s)", p)))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPermission() {
|
|
||||||
return permission;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Pattern> getBanPatterns() {
|
|
||||||
return banPatterns;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Pattern> getMonitorPatterns() {
|
|
||||||
return monitorPatterns;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBanMessage() {
|
|
||||||
return banMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -21,7 +21,6 @@ public class MainCommand implements CommandExecutor {
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) {
|
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) {
|
||||||
if (!commandSender.hasPermission("hush.admin")) {
|
if (!commandSender.hasPermission("hush.admin")) {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
|
@ -46,7 +45,7 @@ public class MainCommand implements CommandExecutor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void help(CommandSender commandSender) {
|
public void help(CommandSender commandSender) {
|
||||||
String version = Bukkit.getPluginManager().getPlugin("MineAlert").getDescription().getVersion();
|
String version = Bukkit.getPluginManager().getPlugin("Hush").getDescription().getVersion();
|
||||||
BaseComponent[] message = new ComponentBuilder()
|
BaseComponent[] message = new ComponentBuilder()
|
||||||
.append(String.format("*** Hush v%s ***", version)).color(ChatColor.DARK_AQUA)
|
.append(String.format("*** Hush v%s ***", version)).color(ChatColor.DARK_AQUA)
|
||||||
.append("\n/hush help - Show this message").color(ChatColor.AQUA)
|
.append("\n/hush help - Show this message").color(ChatColor.AQUA)
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package com.zerohighdef.hush.listeners;
|
package com.zerohighdef.hush.listeners;
|
||||||
|
|
||||||
import com.zerohighdef.hush.Hush;
|
import com.zerohighdef.hush.Hush;
|
||||||
import com.zerohighdef.hush.WatchList;
|
import com.zerohighdef.hush.WatchCategory;
|
||||||
import org.apache.commons.lang.ObjectUtils;
|
|
||||||
import org.bukkit.BanList;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
|
@ -14,14 +12,10 @@ import xyz.etztech.Javacord;
|
||||||
import xyz.etztech.Webhook;
|
import xyz.etztech.Webhook;
|
||||||
import xyz.etztech.embed.Author;
|
import xyz.etztech.embed.Author;
|
||||||
import xyz.etztech.embed.Embed;
|
import xyz.etztech.embed.Embed;
|
||||||
|
import xyz.etztech.embed.Field;
|
||||||
|
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.util.List;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
interface Action {
|
|
||||||
void action();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class HushAsyncChatListener implements Listener {
|
public class HushAsyncChatListener implements Listener {
|
||||||
private final Hush plugin;
|
private final Hush plugin;
|
||||||
|
@ -31,71 +25,57 @@ public class HushAsyncChatListener implements Listener {
|
||||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = false)
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
public boolean onChat(AsyncPlayerChatEvent event) {
|
public boolean onChat(AsyncPlayerChatEvent event) {
|
||||||
String chatMessage = event.getMessage();
|
String chatMessage = event.getMessage();
|
||||||
Player sender = event.getPlayer();
|
Player sender = event.getPlayer();
|
||||||
for (WatchList list : plugin.getWatchLists()) {
|
for (String permission : plugin.getWatchLists().keySet()) {
|
||||||
if (sender.hasPermission(list.getPermission())) {
|
if (sender.hasPermission("hush." + permission)) {
|
||||||
boolean phraseFound = checkPhraseList(list.getBanPatterns(), sender, chatMessage, (() -> {
|
for (WatchCategory category : plugin.getWatchLists().get(permission)) {
|
||||||
banPlayer(sender, list.getBanMessage());
|
checkMessage(category, permission, sender, chatMessage);
|
||||||
}));
|
|
||||||
|
|
||||||
if (phraseFound) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checkPhraseList(list.getMonitorPatterns(), sender, chatMessage, null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void banPlayer(Player player, String banMessage) {
|
private void runCommand(String command) {
|
||||||
Bukkit.getBanList(BanList.Type.NAME)
|
Bukkit.getScheduler().runTask(plugin, () -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command));
|
||||||
.addBan(player.getName(), banMessage, null, null);
|
|
||||||
Bukkit.getScheduler().runTask(plugin, new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
player.kickPlayer("You have been banned: " + banMessage);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkPhraseList(List<Pattern> patternList, Player player, String chatMessage, Action action) {
|
|
||||||
for (Pattern pattern: patternList) {
|
|
||||||
if (pattern.matcher(chatMessage).find()) {
|
|
||||||
if (action != null) {
|
|
||||||
action.action();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkMessage(WatchCategory category, String watchList, Player player, String chatMessage) {
|
||||||
|
Matcher match = category.checkPatterns(chatMessage);
|
||||||
|
if (match != null) {
|
||||||
String playerName = player.getName();
|
String playerName = player.getName();
|
||||||
String webhook = plugin.getConfig().getString("webhook");
|
String webhookURL = plugin.getConfig().getString("webhook");
|
||||||
chatMessage = Javacord.escapeFormat(chatMessage);
|
|
||||||
chatMessage = pattern.matcher(chatMessage).replaceAll("**$0**");
|
|
||||||
|
|
||||||
if (webhook != null) {
|
for (String command: category.getCommands()) {
|
||||||
String message = playerName + " said: " + chatMessage;
|
runCommand(command.replace("{player}", playerName));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (webhookURL != null) {
|
||||||
|
chatMessage = match.replaceAll("**$0**");
|
||||||
|
String message = Javacord.escapeFormat(playerName) + " said: " + chatMessage;
|
||||||
Embed embed = new Embed()
|
Embed embed = new Embed()
|
||||||
.color(0xC70039)
|
.color(0xC70039)
|
||||||
.description(message)
|
.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), ""))
|
.author(new Author(playerName, "", String.format("https://minotar.net/helm/%s/100.png", playerName), ""))
|
||||||
.timestamp(OffsetDateTime.now());
|
.timestamp(OffsetDateTime.now());
|
||||||
|
|
||||||
|
Webhook webhook = new Webhook("@here", embed);
|
||||||
|
|
||||||
this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, () -> {
|
this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, () -> {
|
||||||
try {
|
try {
|
||||||
Javacord.sendWebhook(webhook, new Webhook("@here", embed));
|
Javacord.sendWebhook(webhookURL, webhook);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
this.plugin.log("Webhook failed to send");
|
this.plugin.log("Webhook failed to send.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,18 @@ webhook: ""
|
||||||
|
|
||||||
watch_lists:
|
watch_lists:
|
||||||
# Permission to check
|
# Permission to check
|
||||||
# To enable check give the group the 'hush.<perm>' permission
|
# To enable the check, give the group the 'hush.<watch_list>' permission
|
||||||
guest:
|
guest:
|
||||||
ban_message: "Please respect our players and staff. Appeal online"
|
|
||||||
#Phrases to ban for
|
|
||||||
ban:
|
ban:
|
||||||
|
# Filters to search for
|
||||||
|
filters:
|
||||||
- "heck"
|
- "heck"
|
||||||
- "fricks"
|
- "fricks"
|
||||||
#Phrases to monitor
|
# Commands to run {player} is replaced with the player's name
|
||||||
|
commands:
|
||||||
|
- "ban {player}"
|
||||||
monitor:
|
monitor:
|
||||||
- "hypixel"
|
# Filters to search for
|
||||||
|
filters:
|
||||||
|
- "stupid"
|
||||||
|
- "dumb"
|
|
@ -1,5 +1,5 @@
|
||||||
name: Hush
|
name: Hush
|
||||||
version: 0.1.0
|
version: 0.2.0
|
||||||
main: com.zerohighdef.hush.Hush
|
main: com.zerohighdef.hush.Hush
|
||||||
api-version: "1.16"
|
api-version: "1.16"
|
||||||
authors: [ZeroHighDef]
|
authors: [ZeroHighDef]
|
||||||
|
|
Loading…
Reference in New Issue