From e4d79fb8d9c065cdc3fbdd69d0acce7ae66e1779 Mon Sep 17 00:00:00 2001 From: MemencioPerez Date: Sun, 11 May 2025 04:04:35 -0400 Subject: [PATCH 1/7] Velocity placeholder %server_name% for warns --- .../dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java b/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java index e3ac67d..211d210 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java @@ -12,6 +12,7 @@ import com.velocitypowered.api.plugin.annotation.DataDirectory; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ProxyServer; +import com.velocitypowered.api.proxy.ServerConnection; import dev._2lstudios.chatsentinel.shared.chat.ChatEventResult; import dev._2lstudios.chatsentinel.shared.chat.ChatNotificationManager; import dev._2lstudios.chatsentinel.shared.chat.ChatPlayer; @@ -118,10 +119,12 @@ public String[][] getPlaceholders(Player player, ChatPlayer chatPlayer, Moderati int warns = chatPlayer.getWarns(moderationModule); int maxWarns = moderationModule.getMaxWarns(); float remainingTime = moduleManager.getCooldownModule().getRemainingTime(chatPlayer, message); + Optional serverConnection = player.getCurrentServer(); + String serverName = serverConnection.isPresent() ? serverConnection.get().getServerInfo().getName() : ""; return new String[][] { - { "%player%", "%message%", "%warns%", "%maxwarns%", "%cooldown%" }, - { playerName, message, String.valueOf(warns), String.valueOf(maxWarns), String.valueOf(remainingTime) } + { "%player%", "%message%", "%warns%", "%maxwarns%", "%cooldown%", "%server_name%" }, + { playerName, message, String.valueOf(warns), String.valueOf(maxWarns), String.valueOf(remainingTime), serverName } }; } From a693d68c917d5af43c4e5641b1002c78a664ee25 Mon Sep 17 00:00:00 2001 From: MemencioPerez Date: Sun, 11 May 2025 04:24:42 -0400 Subject: [PATCH 2/7] Server whitelist option for Bungeecord and Velocity --- .../chatsentinel/bungee/ChatSentinel.java | 2 +- .../bungee/listeners/ChatListener.java | 13 ++++++++++++- .../bungee/modules/BungeeModuleManager.java | 1 + .../shared/modules/WhitelistModule.java | 11 +++++++++++ .../chatsentinel/velocity/ChatSentinel.java | 2 +- .../velocity/listeners/ChatListener.java | 15 +++++++++++++-- .../velocity/modules/VelocityModuleManager.java | 3 +++ src/main/resources/whitelist.yml | 5 +++++ 8 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/main/java/dev/_2lstudios/chatsentinel/bungee/ChatSentinel.java b/src/main/java/dev/_2lstudios/chatsentinel/bungee/ChatSentinel.java index b163a5e..2789a1d 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/bungee/ChatSentinel.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/bungee/ChatSentinel.java @@ -61,7 +61,7 @@ public void onEnable() { ChatNotificationManager chatNotificationManager = new ChatNotificationManager(); PluginManager pluginManager = server.getPluginManager(); - pluginManager.registerListener(this, new ChatListener(chatPlayerManager, chatNotificationManager)); + pluginManager.registerListener(this, new ChatListener(moduleManager.getWhitelistModule(), chatPlayerManager, chatNotificationManager)); pluginManager.registerListener(this, new PlayerDisconnectListener(generalModule, chatPlayerManager, chatNotificationManager)); pluginManager.registerListener(this, new PostLoginListener(generalModule, chatPlayerManager, chatNotificationManager)); diff --git a/src/main/java/dev/_2lstudios/chatsentinel/bungee/listeners/ChatListener.java b/src/main/java/dev/_2lstudios/chatsentinel/bungee/listeners/ChatListener.java index c581c82..da83748 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/bungee/listeners/ChatListener.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/bungee/listeners/ChatListener.java @@ -5,6 +5,7 @@ import dev._2lstudios.chatsentinel.shared.chat.ChatNotificationManager; import dev._2lstudios.chatsentinel.shared.chat.ChatPlayer; import dev._2lstudios.chatsentinel.shared.chat.ChatPlayerManager; +import dev._2lstudios.chatsentinel.shared.modules.WhitelistModule; import net.md_5.bungee.api.connection.Connection; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.ChatEvent; @@ -13,10 +14,12 @@ import net.md_5.bungee.event.EventPriority; public class ChatListener implements Listener { + private WhitelistModule whitelistModule; private ChatPlayerManager chatPlayerManager; private ChatNotificationManager chatNotificationManager; - public ChatListener(ChatPlayerManager chatPlayerManager, ChatNotificationManager chatNotificationManager) { + public ChatListener(WhitelistModule whitelistModule, ChatPlayerManager chatPlayerManager, ChatNotificationManager chatNotificationManager) { + this.whitelistModule = whitelistModule; this.chatPlayerManager = chatPlayerManager; this.chatNotificationManager = chatNotificationManager; } @@ -37,6 +40,14 @@ public void onChatEvent(ChatEvent event) { // Get player ProxiedPlayer player = (ProxiedPlayer) sender; + // Check if the player's current server is on the whitelist + if (player.getServer() != null) { + String playerCurrentServer = player.getServer().getInfo().getName(); + if (whitelistModule.getWhitelistedServers().contains(playerCurrentServer)) { + return; + } + } + // Check if player has bypass if (player.hasPermission("chatsentinel.bypass")) { return; diff --git a/src/main/java/dev/_2lstudios/chatsentinel/bungee/modules/BungeeModuleManager.java b/src/main/java/dev/_2lstudios/chatsentinel/bungee/modules/BungeeModuleManager.java index 1c837de..01b8b42 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/bungee/modules/BungeeModuleManager.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/bungee/modules/BungeeModuleManager.java @@ -58,6 +58,7 @@ public void reloadData() { configYml.getBoolean("general.filter-other", false), configYml.getStringList("general.commands")); getWhitelistModule().loadData(configYml.getBoolean("whitelist.enabled"), + whitelistYml.getStringList("servers"), whitelistYml.getStringList("expressions").toArray(new String[0])); boolean censorshipEnabled = configYml.getBoolean("blacklist.censorship.enabled", false); String censorshipReplacement = configYml.getString("blacklist.censorship.replacement", "***"); diff --git a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/WhitelistModule.java b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/WhitelistModule.java index c7c85af..67e8916 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/WhitelistModule.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/WhitelistModule.java @@ -1,18 +1,29 @@ package dev._2lstudios.chatsentinel.shared.modules; +import java.util.Collection; import java.util.regex.Pattern; import dev._2lstudios.chatsentinel.shared.utils.PatternUtil; public class WhitelistModule { private boolean enabled; + private Collection whitelistedServers; private Pattern pattern; public void loadData(boolean enabled, String[] patterns) { + loadData(enabled, null, patterns); + } + + public void loadData(boolean enabled, Collection whitelistedServers, String[] patterns) { this.enabled = enabled; + this.whitelistedServers = whitelistedServers; this.pattern = PatternUtil.compile(patterns); } + public Collection getWhitelistedServers() { + return whitelistedServers; + } + public Pattern getPattern() { return pattern; } diff --git a/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java b/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java index 211d210..46fb07a 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java @@ -69,7 +69,7 @@ public void onProxyInitialize(ProxyInitializeEvent event) { chatNotificationManager = new ChatNotificationManager(); EventManager eventManager = server.getEventManager(); - eventManager.register(this, new ChatListener(this)); + eventManager.register(this, new ChatListener(this, moduleManager.getWhitelistModule())); eventManager.register(this, new PlayerDisconnectListener(generalModule, chatPlayerManager, chatNotificationManager)); eventManager.register(this, new PostLoginListener(generalModule, chatPlayerManager, chatNotificationManager)); diff --git a/src/main/java/dev/_2lstudios/chatsentinel/velocity/listeners/ChatListener.java b/src/main/java/dev/_2lstudios/chatsentinel/velocity/listeners/ChatListener.java index 0f6886a..3ab5c0e 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/velocity/listeners/ChatListener.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/velocity/listeners/ChatListener.java @@ -4,16 +4,19 @@ import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.player.PlayerChatEvent; import com.velocitypowered.api.proxy.Player; +import dev._2lstudios.chatsentinel.shared.modules.WhitelistModule; import dev._2lstudios.chatsentinel.velocity.ChatSentinel; import dev._2lstudios.chatsentinel.shared.chat.ChatEventResult; import dev._2lstudios.chatsentinel.shared.chat.ChatPlayer; public class ChatListener { private final ChatSentinel plugin; + private final WhitelistModule whitelistModule; - public ChatListener(ChatSentinel plugin) { + public ChatListener(ChatSentinel plugin, WhitelistModule whitelistModule) { this.plugin = plugin; - } + this.whitelistModule = whitelistModule; + } @Subscribe(order = PostOrder.LAST) public void onChatEvent(PlayerChatEvent event) { @@ -28,6 +31,14 @@ public void onChatEvent(PlayerChatEvent event) { return; } + // Check if the player's current server is on the whitelist + if (player.getCurrentServer().isPresent()) { + String playerCurrentServer = player.getCurrentServer().get().getServerInfo().getName(); + if (whitelistModule.getWhitelistedServers().contains(playerCurrentServer)) { + return; + } + } + // Check if player has bypass if (player.hasPermission("chatsentinel.bypass")) { return; diff --git a/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java b/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java index fcb1188..0d52c9a 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java @@ -77,6 +77,9 @@ public void reloadData() { .map(ConfigurationNode::getString) .collect(Collectors.toList())); getWhitelistModule().loadData(configYml.node("whitelist", "enabled").getBoolean(), + whitelistYml.node("servers").childrenList().stream() + .map(ConfigurationNode::getString) + .collect(Collectors.toList()), whitelistYml.node("expressions").childrenList().stream() .map(ConfigurationNode::getString) .toArray(String[]::new)); diff --git a/src/main/resources/whitelist.yml b/src/main/resources/whitelist.yml index 5f4ac4e..a8f3377 100644 --- a/src/main/resources/whitelist.yml +++ b/src/main/resources/whitelist.yml @@ -1,3 +1,8 @@ +# List of servers on which the plugin will not check messages (only for Bungeecord and Velocity). +servers: + - example + - example2 + # This plugin uses Regex for checking messages. # Set to [] to disable whitelist completely. expressions: From 50b0f1ce55eb20e2df07e9e5df3e61413689e6f7 Mon Sep 17 00:00:00 2001 From: MemencioPerez Date: Sun, 11 May 2025 04:32:06 -0400 Subject: [PATCH 3/7] Update dependency com.velocitypowered:velocity-api to 3.4.0-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b8f1f35..603ae2e 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ com.velocitypowered velocity-api - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT provided From a2143d12d9d78eaedfb462a498e2445724436791 Mon Sep 17 00:00:00 2001 From: MemencioPerez Date: Sun, 11 May 2025 05:13:04 -0400 Subject: [PATCH 4/7] Fix caps moderation module data being loaded twice in Velocity --- .../velocity/modules/VelocityModuleManager.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java b/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java index 0d52c9a..9fe5776 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java @@ -43,13 +43,6 @@ public void reloadData() { locales.put((String) lang, messages); } - getCapsModule().loadData(configYml.node("caps", "enabled").getBoolean(), - configYml.node("caps", "replace").getBoolean(), - configYml.node("caps", "max").getInt(), configYml.node("caps", "warn", "max").getInt(), - configYml.node("caps", "warn", "notification").getString(), - configYml.node("caps", "punishments").childrenList().stream() - .map(ConfigurationNode::getString) - .toArray(String[]::new)); getCapsModule().loadData(configYml.node("caps", "enabled").getBoolean(), configYml.node("caps", "replace").getBoolean(), configYml.node("caps", "max").getInt(), configYml.node("caps", "warn", "max").getInt(), From a9098cb93a5ca38228029613deaefecf1c168f84 Mon Sep 17 00:00:00 2001 From: MemencioPerez Date: Sun, 11 May 2025 05:20:11 -0400 Subject: [PATCH 5/7] Add custom module names and placeholder %module% --- .../chatsentinel/bukkit/ChatSentinel.java | 5 +++-- .../bukkit/modules/BukkitModuleManager.java | 8 ++++---- .../chatsentinel/bungee/ChatSentinel.java | 5 +++-- .../bungee/modules/BungeeModuleManager.java | 8 ++++---- .../modules/BlacklistModerationModule.java | 3 ++- .../shared/modules/CapsModerationModule.java | 3 ++- .../modules/CooldownModerationModule.java | 5 +++++ .../shared/modules/FloodModerationModule.java | 3 ++- .../shared/modules/ModerationModule.java | 9 +++++++++ .../modules/SyntaxModerationModule.java | 3 ++- .../chatsentinel/velocity/ChatSentinel.java | 5 +++-- .../modules/VelocityModuleManager.java | 4 ++++ src/main/resources/config.yml | 20 +++++++++++++++---- 13 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/main/java/dev/_2lstudios/chatsentinel/bukkit/ChatSentinel.java b/src/main/java/dev/_2lstudios/chatsentinel/bukkit/ChatSentinel.java index b817a96..76525d7 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/bukkit/ChatSentinel.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/bukkit/ChatSentinel.java @@ -102,13 +102,14 @@ public void dispatchNotification(ModerationModule moderationModule, String[][] p public String[][] getPlaceholders(Player player, ChatPlayer chatPlayer, ModerationModule moderationModule, String message) { String playerName = player.getName(); + String customModuleName = moderationModule.getCustomName(); int warns = chatPlayer.getWarns(moderationModule); int maxWarns = moderationModule.getMaxWarns(); float remainingTime = moduleManager.getCooldownModule().getRemainingTime(chatPlayer, message); return new String[][] { - { "%player%", "%message%", "%warns%", "%maxwarns%", "%cooldown%" }, - { playerName, message, String.valueOf(warns), String.valueOf(maxWarns), String.valueOf(remainingTime) } + { "%player%", "%module%", "%message%", "%warns%", "%maxwarns%", "%cooldown%" }, + { playerName, customModuleName, message, String.valueOf(warns), String.valueOf(maxWarns), String.valueOf(remainingTime) } }; } diff --git a/src/main/java/dev/_2lstudios/chatsentinel/bukkit/modules/BukkitModuleManager.java b/src/main/java/dev/_2lstudios/chatsentinel/bukkit/modules/BukkitModuleManager.java index 44036ed..5737410 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/bukkit/modules/BukkitModuleManager.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/bukkit/modules/BukkitModuleManager.java @@ -44,14 +44,14 @@ public void reloadData() { locales.put(lang, messages); } - getCapsModule().loadData(configYml.getBoolean("caps.enabled"), configYml.getBoolean("caps.replace"), + getCapsModule().loadData(configYml.getBoolean("caps.enabled"), configYml.getString("caps.custom-module-name"), configYml.getBoolean("caps.replace"), configYml.getInt("caps.max"), configYml.getInt("caps.warn.max"), configYml.getString("caps.warn.notification"), configYml.getStringList("caps.punishments").toArray(new String[0])); getCooldownModule().loadData(configYml.getBoolean("cooldown.enabled"), configYml.getInt("cooldown.time.repeat-global"), configYml.getInt("cooldown.time.repeat"), configYml.getInt("cooldown.time.normal"), configYml.getInt("cooldown.time.command")); - getFloodModule().loadData(configYml.getBoolean("flood.enabled"), configYml.getBoolean("flood.replace"), + getFloodModule().loadData(configYml.getBoolean("flood.enabled"), configYml.getString("flood.custom-module-name"), configYml.getBoolean("flood.replace"), configYml.getInt("flood.warn.max"), configYml.getString("flood.pattern"), configYml.getString("flood.warn.notification"), configYml.getStringList("flood.punishments").toArray(new String[0])); @@ -64,13 +64,13 @@ public void reloadData() { whitelistYml.getStringList("expressions").toArray(new String[0])); boolean censorshipEnabled = configYml.getBoolean("blacklist.censorship.enabled", false); String censorshipReplacement = configYml.getString("blacklist.censorship.replacement", "***"); - getBlacklistModule().loadData(configYml.getBoolean("blacklist.enabled"), + getBlacklistModule().loadData(configYml.getBoolean("blacklist.enabled"), configYml.getString("blacklist.custom-module-name"), configYml.getBoolean("blacklist.fake_message"), censorshipEnabled, censorshipReplacement, configYml.getInt("blacklist.warn.max"), configYml.getString("blacklist.warn.notification"), configYml.getStringList("blacklist.punishments").toArray(new String[0]), blacklistYml.getStringList("expressions").toArray(new String[0]), configYml.getBoolean("blacklist.block_raw_message")); - getSyntaxModule().loadData(configYml.getBoolean("syntax.enabled"), configYml.getInt("syntax.warn.max"), + getSyntaxModule().loadData(configYml.getBoolean("syntax.enabled"), configYml.getString("syntax.custom-module-name"), configYml.getInt("syntax.warn.max"), configYml.getString("syntax.warn.notification"), configYml.getStringList("syntax.whitelist").toArray(new String[0]), configYml.getStringList("syntax.punishments").toArray(new String[0])); diff --git a/src/main/java/dev/_2lstudios/chatsentinel/bungee/ChatSentinel.java b/src/main/java/dev/_2lstudios/chatsentinel/bungee/ChatSentinel.java index 2789a1d..2843a96 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/bungee/ChatSentinel.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/bungee/ChatSentinel.java @@ -106,6 +106,7 @@ public void dispatchNotification(ModerationModule moderationModule, String[][] p public String[][] getPlaceholders(ProxiedPlayer player, ChatPlayer chatPlayer, ModerationModule moderationModule, String message) { String playerName = player.getName(); + String customModuleName = moderationModule.getCustomName(); int warns = chatPlayer.getWarns(moderationModule); int maxWarns = moderationModule.getMaxWarns(); float remainingTime = moduleManager.getCooldownModule().getRemainingTime(chatPlayer, message); @@ -113,8 +114,8 @@ public String[][] getPlaceholders(ProxiedPlayer player, ChatPlayer chatPlayer, M String serverName = server != null ? server.getInfo().getName() : ""; return new String[][] { - { "%player%", "%message%", "%warns%", "%maxwarns%", "%cooldown%", "%server_name%" }, - { playerName, message, String.valueOf(warns), String.valueOf(maxWarns), String.valueOf(remainingTime), serverName } + { "%player%", "%module%", "%message%", "%warns%", "%maxwarns%", "%cooldown%", "%server_name%" }, + { playerName, customModuleName, message, String.valueOf(warns), String.valueOf(maxWarns), String.valueOf(remainingTime), serverName } }; } diff --git a/src/main/java/dev/_2lstudios/chatsentinel/bungee/modules/BungeeModuleManager.java b/src/main/java/dev/_2lstudios/chatsentinel/bungee/modules/BungeeModuleManager.java index 01b8b42..d91a39e 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/bungee/modules/BungeeModuleManager.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/bungee/modules/BungeeModuleManager.java @@ -41,14 +41,14 @@ public void reloadData() { locales.put(lang, messages); } - getCapsModule().loadData(configYml.getBoolean("caps.enabled"), configYml.getBoolean("caps.replace"), + getCapsModule().loadData(configYml.getBoolean("caps.enabled"), configYml.getString("caps.custom-module-name"), configYml.getBoolean("caps.replace"), configYml.getInt("caps.max"), configYml.getInt("caps.warn.max"), configYml.getString("caps.warn.notification"), configYml.getStringList("caps.punishments").toArray(new String[0])); getCooldownModule().loadData(configYml.getBoolean("cooldown.enabled"), configYml.getInt("cooldown.time.repeat-global"), configYml.getInt("cooldown.time.repeat"), configYml.getInt("cooldown.time.normal"), configYml.getInt("cooldown.time.command")); - getFloodModule().loadData(configYml.getBoolean("flood.enabled"), configYml.getBoolean("flood.replace"), + getFloodModule().loadData(configYml.getBoolean("flood.enabled"), configYml.getString("flood.custom-module-name"), configYml.getBoolean("flood.replace"), configYml.getInt("flood.warn.max"), configYml.getString("flood.pattern"), configYml.getString("flood.warn.notification"), configYml.getStringList("flood.punishments").toArray(new String[0])); @@ -62,13 +62,13 @@ public void reloadData() { whitelistYml.getStringList("expressions").toArray(new String[0])); boolean censorshipEnabled = configYml.getBoolean("blacklist.censorship.enabled", false); String censorshipReplacement = configYml.getString("blacklist.censorship.replacement", "***"); - getBlacklistModule().loadData(configYml.getBoolean("blacklist.enabled"), + getBlacklistModule().loadData(configYml.getBoolean("blacklist.enabled"), configYml.getString("blacklist.custom-module-name"), configYml.getBoolean("blacklist.fake_message"), censorshipEnabled, censorshipReplacement, configYml.getInt("blacklist.warn.max"), configYml.getString("blacklist.warn.notification"), configYml.getStringList("blacklist.punishments").toArray(new String[0]), blacklistYml.getStringList("expressions").toArray(new String[0]), configYml.getBoolean("blacklist.block_raw_message")); - getSyntaxModule().loadData(configYml.getBoolean("syntax.enabled"), configYml.getInt("syntax.warn.max"), + getSyntaxModule().loadData(configYml.getBoolean("syntax.enabled"), configYml.getString("syntax.custom-module-name"), configYml.getInt("syntax.warn.max"), configYml.getString("syntax.warn.notification"), configYml.getStringList("syntax.whitelist").toArray(new String[0]), configYml.getStringList("syntax.punishments").toArray(new String[0])); diff --git a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/BlacklistModerationModule.java b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/BlacklistModerationModule.java index 3b5956b..045202a 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/BlacklistModerationModule.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/BlacklistModerationModule.java @@ -20,12 +20,13 @@ public BlacklistModerationModule(ModuleManager moduleManager) { this.moduleManager = moduleManager; } - public void loadData(boolean enabled, boolean fakeMessage, boolean censorshipEnabled, String censorshipReplacement, int maxWarns, + public void loadData(boolean enabled, String customName, boolean fakeMessage, boolean censorshipEnabled, String censorshipReplacement, int maxWarns, String warnNotification, String[] commands, String[] patterns, boolean blockRawMessage) { setEnabled(enabled); setMaxWarns(maxWarns); setWarnNotification(warnNotification); setCommands(commands); + setCustomName(customName); this.fakeMessage = fakeMessage; this.censorshipEnabled = censorshipEnabled; this.censorshipReplacement = censorshipReplacement; diff --git a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/CapsModerationModule.java b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/CapsModerationModule.java index 3f6855d..4f7e8bf 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/CapsModerationModule.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/CapsModerationModule.java @@ -7,12 +7,13 @@ public class CapsModerationModule extends ModerationModule { private boolean replace; private int maxCaps; - public void loadData(boolean enabled, boolean replace, int max, int maxWarns, + public void loadData(boolean enabled, String customName, boolean replace, int max, int maxWarns, String warnNotification, String[] commands) { setEnabled(enabled); setMaxWarns(maxWarns); setWarnNotification(warnNotification); setCommands(commands); + setCustomName(customName); this.replace = replace; this.maxCaps = max; } diff --git a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/CooldownModerationModule.java b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/CooldownModerationModule.java index c606207..8687fb1 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/CooldownModerationModule.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/CooldownModerationModule.java @@ -62,6 +62,11 @@ public String getName() { return "Cooldown"; } + @Override + public String getCustomName() { + return getName(); + } + @Override public String getWarnNotification(String[][] placeholders) { return null; diff --git a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/FloodModerationModule.java b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/FloodModerationModule.java index 4489866..17be0d0 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/FloodModerationModule.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/FloodModerationModule.java @@ -9,12 +9,13 @@ public class FloodModerationModule extends ModerationModule { private boolean replace; private Pattern pattern; - public void loadData(boolean enabled, boolean replace, int maxWarns, String pattern, + public void loadData(boolean enabled, String customName, boolean replace, int maxWarns, String pattern, String warnNotification, String[] commands) { setEnabled(enabled); setMaxWarns(maxWarns); setWarnNotification(warnNotification); setCommands(commands); + setCustomName(customName); this.replace = replace; this.pattern = Pattern.compile(pattern); } diff --git a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/ModerationModule.java b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/ModerationModule.java index bd497ca..4e4ea1a 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/ModerationModule.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/ModerationModule.java @@ -9,6 +9,7 @@ public abstract class ModerationModule { private int maxWarns = 0; private String warnNotification = null; private String[] commands = new String[0]; + private String customName; public boolean isEnabled() { return enabled; @@ -44,6 +45,14 @@ public boolean hasExceededWarns(ChatPlayer chatPlayer) { public abstract String getName(); + public String getCustomName() { + return customName; + } + + public void setCustomName(String customName) { + this.customName = customName; + } + public abstract ChatEventResult processEvent(ChatPlayer chatPlayer, MessagesModule messagesModule, String playerName, String originalMessage, String lang); public String getBypassPermission() { diff --git a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/SyntaxModerationModule.java b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/SyntaxModerationModule.java index b0bdf2d..151485a 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/SyntaxModerationModule.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/SyntaxModerationModule.java @@ -6,12 +6,13 @@ public class SyntaxModerationModule extends ModerationModule { private String[] whitelist; - public void loadData(boolean enabled, int maxWarns, String warnNotification, + public void loadData(boolean enabled, String customName, int maxWarns, String warnNotification, String[] whitelist, String[] commands) { setEnabled(enabled); setMaxWarns(maxWarns); setWarnNotification(warnNotification); setCommands(commands); + setCustomName(customName); this.whitelist = whitelist; } diff --git a/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java b/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java index 46fb07a..e1749ca 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java @@ -116,6 +116,7 @@ public void dispatchNotification(ModerationModule moderationModule, String[][] p public String[][] getPlaceholders(Player player, ChatPlayer chatPlayer, ModerationModule moderationModule, String message) { String playerName = player.getUsername(); + String customModuleName = moderationModule.getCustomName(); int warns = chatPlayer.getWarns(moderationModule); int maxWarns = moderationModule.getMaxWarns(); float remainingTime = moduleManager.getCooldownModule().getRemainingTime(chatPlayer, message); @@ -123,8 +124,8 @@ public String[][] getPlaceholders(Player player, ChatPlayer chatPlayer, Moderati String serverName = serverConnection.isPresent() ? serverConnection.get().getServerInfo().getName() : ""; return new String[][] { - { "%player%", "%message%", "%warns%", "%maxwarns%", "%cooldown%", "%server_name%" }, - { playerName, message, String.valueOf(warns), String.valueOf(maxWarns), String.valueOf(remainingTime), serverName } + { "%player%", "%module%", "%message%", "%warns%", "%maxwarns%", "%cooldown%", "%server_name%" }, + { playerName, customModuleName, message, String.valueOf(warns), String.valueOf(maxWarns), String.valueOf(remainingTime), serverName } }; } diff --git a/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java b/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java index 9fe5776..22030fd 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java @@ -44,6 +44,7 @@ public void reloadData() { } getCapsModule().loadData(configYml.node("caps", "enabled").getBoolean(), + configYml.node("caps", "custom-module-name").getString(), configYml.node("caps", "replace").getBoolean(), configYml.node("caps", "max").getInt(), configYml.node("caps", "warn", "max").getInt(), configYml.node("caps", "warn", "notification").getString(), @@ -56,6 +57,7 @@ public void reloadData() { configYml.node("cooldown", "time", "normal").getInt(), configYml.node("cooldown", "time", "command").getInt()); getFloodModule().loadData(configYml.node("flood", "enabled").getBoolean(), + configYml.node("flood", "custom-module-name").getString(), configYml.node("flood", "replace").getBoolean(), configYml.node("flood", "warn", "max").getInt(), configYml.node("flood", "pattern").getString(), configYml.node("flood", "warn", "notification").getString(), @@ -79,6 +81,7 @@ public void reloadData() { boolean censorshipEnabled = configYml.node("blacklist", "censorship", "enabled").getBoolean(false); String censorshipReplacement = configYml.node("blacklist", "censorship", "replacement").getString("***"); getBlacklistModule().loadData(configYml.node("blacklist", "enabled").getBoolean(), + configYml.node("blacklist", "custom-module-name").getString(), configYml.node("blacklist", "fake_message").getBoolean(), censorshipEnabled, censorshipReplacement, @@ -92,6 +95,7 @@ public void reloadData() { .toArray(String[]::new), configYml.node("blacklist", "block_raw_message").getBoolean()); getSyntaxModule().loadData(configYml.node("syntax", "enabled").getBoolean(), + configYml.node("syntax", "custom-module-name").getString(), configYml.node("syntax", "warn", "max").getInt(), configYml.node("syntax", "warn", "notification").getString(), configYml.node("syntax", "whitelist").childrenList().stream() diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 06c664c..db5de83 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -34,6 +34,9 @@ general: blacklist: enabled: true + # Custom module name. + custom-module-name: "Swearing" + # Show a fake message to the player to make him think his message was sent. # This doesnt work if the plugin is on BungeeCord. fake_message: false @@ -52,7 +55,7 @@ blacklist: # Sends a notification to players with chatsentinel.notify permission. # Set to "" to disable this feature completely. # You can use %server% on BungeeCord to get the server name. - notification: "&c&lCS: &e%player% &ffailed &6Swearing &7(&c%message%&7)" + notification: "&c&lCS: &e%player% &ffailed &6%module% &7(&c%message%&7)" # You need a mute plugin for ChatSentinel to mute players. (Recommended: LiteBans/AdvancedBans) # Set to [] to disable this feature completely. @@ -68,6 +71,9 @@ blacklist: caps: enabled: true + # Custom module name. + custom-module-name: "Caps" + # If this is true it will replace the caps with low-case letters. replace: true @@ -81,7 +87,7 @@ caps: # Sends a notification to players with chatsentinel.notify permission. # Set to "" to disable this feature completely. - notification: "&c&lCS: &e%player% &ffailed &6Caps &7(&c%message%&7)" + notification: "&c&lCS: &e%player% &ffailed &6%module% &7(&c%message%&7)" # You need a mute plugin for ChatSentinel to mute players. (Recommended: LiteBans/AdvancedBans) # Set to [] to disable this feature completely. @@ -102,6 +108,9 @@ cooldown: flood: enabled: true + # Custom module name. + custom-module-name: "Flood" + # If this is true it will replace the flood instead of cancelling it. # Example: Heloooooo would be converted to just Helloo replace: true @@ -116,7 +125,7 @@ flood: # Sends a notification to players with chatsentinel.notify permission. # Set to "" to disable this feature completely. - notification: "&c&lCS: &e%player% &ffailed &6Flood &7(&c%message%&7)" + notification: "&c&lCS: &e%player% &ffailed &6%module% &7(&c%message%&7)" # You need a mute plugin for ChatSentinel to mute players. (Recommended: LiteBans/AdvancedBans) # Set to [] to disable this feature completely. @@ -128,6 +137,9 @@ syntax: # Do you want to enable this module? enabled: true + # Custom module name. + custom-module-name: "Syntax" + # Syntax commands that will not be checked. # Set to {} to disable whitelist. whitelist: @@ -140,7 +152,7 @@ syntax: # Sends a notification to players with chatsentinel.notify permission. # Set to "" to disable this feature completely. - notification: "&c&lCS: &e%player% &ffailed &6Syntax &7(&c%message%&7)" + notification: "&c&lCS: &e%player% &ffailed &6%module% &7(&c%message%&7)" # You need a mute plugin for ChatSentinel to mute players. (Recommended: LiteBans/AdvancedBans) # Set to [] to disable this feature completely. From 0f4f7b632ed0d92182e3bf1e58d3ac0deeb853f1 Mon Sep 17 00:00:00 2001 From: MemencioPerez Date: Sun, 11 May 2025 05:44:06 -0400 Subject: [PATCH 6/7] Add Discord webhooks integration --- pom.xml | 39 +++++++++ .../chatsentinel/bukkit/ChatSentinel.java | 11 +-- .../bukkit/modules/BukkitModuleManager.java | 18 ++++ .../chatsentinel/bungee/ChatSentinel.java | 11 +-- .../bungee/modules/BungeeModuleManager.java | 18 ++++ .../modules/BlacklistModerationModule.java | 3 +- .../shared/modules/CapsModerationModule.java | 3 +- .../shared/modules/DiscordWebhookModule.java | 87 +++++++++++++++++++ .../shared/modules/FloodModerationModule.java | 3 +- .../shared/modules/ModerationModule.java | 9 ++ .../shared/modules/ModuleManager.java | 6 ++ .../modules/SyntaxModerationModule.java | 3 +- .../chatsentinel/velocity/ChatSentinel.java | 4 + .../modules/VelocityModuleManager.java | 19 ++++ src/main/resources/config.yml | 63 ++++++++++++++ 15 files changed, 283 insertions(+), 14 deletions(-) create mode 100644 src/main/java/dev/_2lstudios/chatsentinel/shared/modules/DiscordWebhookModule.java diff --git a/pom.xml b/pom.xml index 603ae2e..685e9d1 100644 --- a/pom.xml +++ b/pom.xml @@ -29,6 +29,10 @@ velocity-repo https://repo.papermc.io/repository/maven-public/ + + jitpack.io + https://jitpack.io + @@ -51,6 +55,11 @@ 3.4.0-SNAPSHOT provided + + com.github.micartey + webhookly + master + @@ -90,6 +99,36 @@ + + org.apache.maven.plugins + maven-shade-plugin + 3.6.0 + + + package + + shade + + + + + me.micartey.webhookly + dev._2lstudios.chatsentinel.libs.webhookly + + + + + com.github.micartey:webhookly + + META-INF/*.MF + + + + true + + + + diff --git a/src/main/java/dev/_2lstudios/chatsentinel/bukkit/ChatSentinel.java b/src/main/java/dev/_2lstudios/chatsentinel/bukkit/ChatSentinel.java index 76525d7..15c6555 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/bukkit/ChatSentinel.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/bukkit/ChatSentinel.java @@ -1,6 +1,7 @@ package dev._2lstudios.chatsentinel.bukkit; import dev._2lstudios.chatsentinel.shared.chat.ChatNotificationManager; +import dev._2lstudios.chatsentinel.shared.modules.*; import org.bukkit.Bukkit; import org.bukkit.Server; import org.bukkit.command.ConsoleCommandSender; @@ -18,11 +19,6 @@ import dev._2lstudios.chatsentinel.shared.chat.ChatEventResult; import dev._2lstudios.chatsentinel.shared.chat.ChatPlayer; import dev._2lstudios.chatsentinel.shared.chat.ChatPlayerManager; -import dev._2lstudios.chatsentinel.shared.modules.CooldownModerationModule; -import dev._2lstudios.chatsentinel.shared.modules.GeneralModule; -import dev._2lstudios.chatsentinel.shared.modules.MessagesModule; -import dev._2lstudios.chatsentinel.shared.modules.ModerationModule; -import dev._2lstudios.chatsentinel.shared.modules.SyntaxModerationModule; public class ChatSentinel extends JavaPlugin { // Static instance @@ -177,6 +173,11 @@ public ChatEventResult processEvent(ChatPlayer chatPlayer, Player player, String // Send admin notification ChatSentinel.getInstance().dispatchNotification(moderationModule, placeholders, chatNotificationManager); + // Send discord webhook notification + Server server = getServer(); + DiscordWebhookModule discordWebhookModule = moduleManager.getDiscordWebhookModule(); + server.getScheduler().runTaskAsynchronously(this, () -> discordWebhookModule.dispatchWebhookNotification(moderationModule, placeholders)); + // Update message finalResult.setMessage(result.getMessage()); diff --git a/src/main/java/dev/_2lstudios/chatsentinel/bukkit/modules/BukkitModuleManager.java b/src/main/java/dev/_2lstudios/chatsentinel/bukkit/modules/BukkitModuleManager.java index 5737410..469e13b 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/bukkit/modules/BukkitModuleManager.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/bukkit/modules/BukkitModuleManager.java @@ -47,6 +47,7 @@ public void reloadData() { getCapsModule().loadData(configYml.getBoolean("caps.enabled"), configYml.getString("caps.custom-module-name"), configYml.getBoolean("caps.replace"), configYml.getInt("caps.max"), configYml.getInt("caps.warn.max"), configYml.getString("caps.warn.notification"), + configYml.getBoolean("caps.warn.webhook-notification"), configYml.getStringList("caps.punishments").toArray(new String[0])); getCooldownModule().loadData(configYml.getBoolean("cooldown.enabled"), configYml.getInt("cooldown.time.repeat-global"), configYml.getInt("cooldown.time.repeat"), @@ -54,6 +55,7 @@ public void reloadData() { getFloodModule().loadData(configYml.getBoolean("flood.enabled"), configYml.getString("flood.custom-module-name"), configYml.getBoolean("flood.replace"), configYml.getInt("flood.warn.max"), configYml.getString("flood.pattern"), configYml.getString("flood.warn.notification"), + configYml.getBoolean("flood.warn.webhook-notification"), configYml.getStringList("flood.punishments").toArray(new String[0])); getMessagesModule().loadData(messagesYml.getString("default"), locales); getGeneralModule().loadData(configYml.getBoolean("general.sanitize", true), @@ -67,12 +69,28 @@ public void reloadData() { getBlacklistModule().loadData(configYml.getBoolean("blacklist.enabled"), configYml.getString("blacklist.custom-module-name"), configYml.getBoolean("blacklist.fake_message"), censorshipEnabled, censorshipReplacement, configYml.getInt("blacklist.warn.max"), configYml.getString("blacklist.warn.notification"), + configYml.getBoolean("blacklist.warn.webhook-notification"), configYml.getStringList("blacklist.punishments").toArray(new String[0]), blacklistYml.getStringList("expressions").toArray(new String[0]), configYml.getBoolean("blacklist.block_raw_message")); getSyntaxModule().loadData(configYml.getBoolean("syntax.enabled"), configYml.getString("syntax.custom-module-name"), configYml.getInt("syntax.warn.max"), configYml.getString("syntax.warn.notification"), + configYml.getBoolean("syntax.warn.webhook-notification"), configYml.getStringList("syntax.whitelist").toArray(new String[0]), configYml.getStringList("syntax.punishments").toArray(new String[0])); + getDiscordWebhookModule().loadData(configYml.getBoolean("discord-webhook.enabled"), configYml.getString("discord-webhook.webhook-url"), + configYml.getString("discord-webhook.warn.max"), + configYml.getString("discord-webhook.sender.avatar-url"), + configYml.getString("discord-webhook.sender.username"), + configYml.getString("discord-webhook.author.name"), + configYml.getString("discord-webhook.author.url"), + configYml.getString("discord-webhook.title"), + configYml.getString("discord-webhook.color"), + configYml.getString("discord-webhook.description"), + configYml.getString("discord-webhook.field-names.message"), + configYml.getString("discord-webhook.field-names.server"), + configYml.getString("discord-webhook.footer.text"), + configYml.getString("discord-webhook.footer.icon-url"), + configYml.getString("discord-webhook.thumbnail-url")); } } diff --git a/src/main/java/dev/_2lstudios/chatsentinel/bungee/ChatSentinel.java b/src/main/java/dev/_2lstudios/chatsentinel/bungee/ChatSentinel.java index 2843a96..90b5750 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/bungee/ChatSentinel.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/bungee/ChatSentinel.java @@ -12,11 +12,7 @@ import dev._2lstudios.chatsentinel.shared.chat.ChatNotificationManager; import dev._2lstudios.chatsentinel.shared.chat.ChatPlayer; import dev._2lstudios.chatsentinel.shared.chat.ChatPlayerManager; -import dev._2lstudios.chatsentinel.shared.modules.CooldownModerationModule; -import dev._2lstudios.chatsentinel.shared.modules.GeneralModule; -import dev._2lstudios.chatsentinel.shared.modules.MessagesModule; -import dev._2lstudios.chatsentinel.shared.modules.ModerationModule; -import dev._2lstudios.chatsentinel.shared.modules.SyntaxModerationModule; +import dev._2lstudios.chatsentinel.shared.modules.*; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -183,6 +179,11 @@ public ChatEventResult processEvent(ChatPlayer chatPlayer, ProxiedPlayer player, // Send admin notification ChatSentinel.getInstance().dispatchNotification(moderationModule, placeholders, chatNotificationManager); + // Send discord webhook notification + ProxyServer server = getProxy(); + DiscordWebhookModule discordWebhookModule = moduleManager.getDiscordWebhookModule(); + server.getScheduler().runAsync(this, () -> discordWebhookModule.dispatchWebhookNotification(moderationModule, placeholders)); + // Update message finalResult.setMessage(result.getMessage()); diff --git a/src/main/java/dev/_2lstudios/chatsentinel/bungee/modules/BungeeModuleManager.java b/src/main/java/dev/_2lstudios/chatsentinel/bungee/modules/BungeeModuleManager.java index d91a39e..b683c30 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/bungee/modules/BungeeModuleManager.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/bungee/modules/BungeeModuleManager.java @@ -44,6 +44,7 @@ public void reloadData() { getCapsModule().loadData(configYml.getBoolean("caps.enabled"), configYml.getString("caps.custom-module-name"), configYml.getBoolean("caps.replace"), configYml.getInt("caps.max"), configYml.getInt("caps.warn.max"), configYml.getString("caps.warn.notification"), + configYml.getBoolean("caps.warn.webhook-notification"), configYml.getStringList("caps.punishments").toArray(new String[0])); getCooldownModule().loadData(configYml.getBoolean("cooldown.enabled"), configYml.getInt("cooldown.time.repeat-global"), configYml.getInt("cooldown.time.repeat"), @@ -51,6 +52,7 @@ public void reloadData() { getFloodModule().loadData(configYml.getBoolean("flood.enabled"), configYml.getString("flood.custom-module-name"), configYml.getBoolean("flood.replace"), configYml.getInt("flood.warn.max"), configYml.getString("flood.pattern"), configYml.getString("flood.warn.notification"), + configYml.getBoolean("flood.warn.webhook-notification"), configYml.getStringList("flood.punishments").toArray(new String[0])); getMessagesModule().loadData(messagesYml.getString("default"), locales); getGeneralModule().loadData(configYml.getBoolean("general.sanitize", true), @@ -65,12 +67,28 @@ public void reloadData() { getBlacklistModule().loadData(configYml.getBoolean("blacklist.enabled"), configYml.getString("blacklist.custom-module-name"), configYml.getBoolean("blacklist.fake_message"), censorshipEnabled, censorshipReplacement, configYml.getInt("blacklist.warn.max"), configYml.getString("blacklist.warn.notification"), + configYml.getBoolean("blacklist.warn.webhook-notification"), configYml.getStringList("blacklist.punishments").toArray(new String[0]), blacklistYml.getStringList("expressions").toArray(new String[0]), configYml.getBoolean("blacklist.block_raw_message")); getSyntaxModule().loadData(configYml.getBoolean("syntax.enabled"), configYml.getString("syntax.custom-module-name"), configYml.getInt("syntax.warn.max"), configYml.getString("syntax.warn.notification"), + configYml.getBoolean("syntax.warn.webhook-notification"), configYml.getStringList("syntax.whitelist").toArray(new String[0]), configYml.getStringList("syntax.punishments").toArray(new String[0])); + getDiscordWebhookModule().loadData(configYml.getBoolean("discord-webhook.enabled"), configYml.getString("discord-webhook.webhook-url"), + configYml.getString("discord-webhook.warn.max"), + configYml.getString("discord-webhook.sender.avatar-url"), + configYml.getString("discord-webhook.sender.username"), + configYml.getString("discord-webhook.author.name"), + configYml.getString("discord-webhook.author.url"), + configYml.getString("discord-webhook.title"), + configYml.getString("discord-webhook.color"), + configYml.getString("discord-webhook.description"), + configYml.getString("discord-webhook.field-names.message"), + configYml.getString("discord-webhook.field-names.server"), + configYml.getString("discord-webhook.footer.text"), + configYml.getString("discord-webhook.footer.icon-url"), + configYml.getString("discord-webhook.thumbnail-url")); } } diff --git a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/BlacklistModerationModule.java b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/BlacklistModerationModule.java index 045202a..595b801 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/BlacklistModerationModule.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/BlacklistModerationModule.java @@ -21,10 +21,11 @@ public BlacklistModerationModule(ModuleManager moduleManager) { } public void loadData(boolean enabled, String customName, boolean fakeMessage, boolean censorshipEnabled, String censorshipReplacement, int maxWarns, - String warnNotification, String[] commands, String[] patterns, boolean blockRawMessage) { + String warnNotification, boolean webhookEnabled, String[] commands, String[] patterns, boolean blockRawMessage) { setEnabled(enabled); setMaxWarns(maxWarns); setWarnNotification(warnNotification); + setWebhookEnabled(webhookEnabled); setCommands(commands); setCustomName(customName); this.fakeMessage = fakeMessage; diff --git a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/CapsModerationModule.java b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/CapsModerationModule.java index 4f7e8bf..2bed8f4 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/CapsModerationModule.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/CapsModerationModule.java @@ -8,10 +8,11 @@ public class CapsModerationModule extends ModerationModule { private int maxCaps; public void loadData(boolean enabled, String customName, boolean replace, int max, int maxWarns, - String warnNotification, String[] commands) { + String warnNotification, boolean webhookEnabled, String[] commands) { setEnabled(enabled); setMaxWarns(maxWarns); setWarnNotification(warnNotification); + setWebhookEnabled(webhookEnabled); setCommands(commands); setCustomName(customName); this.replace = replace; diff --git a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/DiscordWebhookModule.java b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/DiscordWebhookModule.java new file mode 100644 index 0000000..e7b1b89 --- /dev/null +++ b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/DiscordWebhookModule.java @@ -0,0 +1,87 @@ +package dev._2lstudios.chatsentinel.shared.modules; + +import dev._2lstudios.chatsentinel.shared.utils.PlaceholderUtil; +import me.micartey.webhookly.DiscordWebhook; +import me.micartey.webhookly.embeds.*; + +import java.awt.*; +import java.io.IOException; +import java.time.OffsetDateTime; +import java.util.LinkedHashSet; + +public class DiscordWebhookModule { + private boolean enabled; + private String webhookUrl; + private String senderAvatarUrl; + private String senderUsername; + private String authorName; + private String authorUrl; + private String authorIconUrl; + private String title; + private String color; + private String description; + private String messageFieldName; + private String serverFieldName; + private String footerText; + private String footerIconUrl; + private String thumbnailUrl; + private DiscordWebhook webhook; + + public void loadData(boolean enabled, String webhookUrl, String senderAvatarUrl, String senderUsername, String authorName, String authorUrl, String authorIconUrl, String title, String color, String description, String messageFieldName, String serverFieldName, String footerText, String footerIconUrl, String thumbnailUrl) { + this.enabled = enabled; + this.webhookUrl = webhookUrl; + this.senderAvatarUrl = senderAvatarUrl; + this.senderUsername = senderUsername; + this.authorName = authorName; + this.authorUrl = authorUrl; + this.authorIconUrl = authorIconUrl; + this.title = title; + this.color = color; + this.description = description; + this.messageFieldName = messageFieldName; + this.serverFieldName = serverFieldName; + this.footerText = footerText; + this.footerIconUrl = footerIconUrl; + this.thumbnailUrl = thumbnailUrl; + if (isEnabled()) setupDiscordWebhook(); + } + + public boolean isEnabled() { + return enabled; + } + + private void setupDiscordWebhook() { + this.webhook = new DiscordWebhook(webhookUrl); + webhook.setAvatarUrl(senderAvatarUrl); + webhook.setUsername(senderUsername); + } + + public void dispatchWebhookNotification(ModerationModule moderationModule, String[][] placeholders) { + if (!isEnabled() || !moderationModule.isWebhookEnabled() || moderationModule.getWarnNotification(placeholders) == null) { + return; + } + + EmbedObject embed = new EmbedObject() + .setAuthor(new Author(authorName, authorUrl, authorIconUrl)) + .setTitle(title) + .setColor(Color.decode(color)) + .setDescription(PlaceholderUtil.replacePlaceholders(description, placeholders)) + .setFooter(new Footer(footerText, footerIconUrl)) + .setThumbnail(new Thumbnail(thumbnailUrl)) + .setTimestamp(OffsetDateTime.now()); + + embed.getFields().addAll(new LinkedHashSet(){{ + add(new Field(messageFieldName, PlaceholderUtil.replacePlaceholders("%message%", placeholders), true)); + add(new Field(serverFieldName, PlaceholderUtil.replacePlaceholders("%server_name%", placeholders), true)); + }}); + + webhook.getEmbeds().add(embed); + try { + webhook.execute(); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + webhook.getEmbeds().clear(); + } + } +} diff --git a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/FloodModerationModule.java b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/FloodModerationModule.java index 17be0d0..73825e2 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/FloodModerationModule.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/FloodModerationModule.java @@ -10,10 +10,11 @@ public class FloodModerationModule extends ModerationModule { private Pattern pattern; public void loadData(boolean enabled, String customName, boolean replace, int maxWarns, String pattern, - String warnNotification, String[] commands) { + String warnNotification, boolean webhookEnabled, String[] commands) { setEnabled(enabled); setMaxWarns(maxWarns); setWarnNotification(warnNotification); + setWebhookEnabled(webhookEnabled); setCommands(commands); setCustomName(customName); this.replace = replace; diff --git a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/ModerationModule.java b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/ModerationModule.java index 4e4ea1a..1c5b3da 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/ModerationModule.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/ModerationModule.java @@ -8,6 +8,7 @@ public abstract class ModerationModule { private boolean enabled = true; private int maxWarns = 0; private String warnNotification = null; + private boolean webhookEnabled = true; private String[] commands = new String[0]; private String customName; @@ -15,6 +16,10 @@ public boolean isEnabled() { return enabled; } + public boolean isWebhookEnabled() { + return webhookEnabled; + } + public int getMaxWarns() { return maxWarns; } @@ -23,6 +28,10 @@ public void setEnabled(boolean enabled) { this.enabled = enabled; } + public void setWebhookEnabled(boolean webhookEnabled) { + this.webhookEnabled = webhookEnabled; + } + public void setMaxWarns(int maxWarns) { this.maxWarns = maxWarns; } diff --git a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/ModuleManager.java b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/ModuleManager.java index 330977a..0cff874 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/ModuleManager.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/ModuleManager.java @@ -9,6 +9,7 @@ public abstract class ModuleManager { private BlacklistModerationModule blacklistModule; private SyntaxModerationModule syntaxModule; private WhitelistModule whitelistModule; + private DiscordWebhookModule discordWebhookModule; public ModuleManager() { this.capsModule = new CapsModerationModule(); @@ -19,6 +20,7 @@ public ModuleManager() { this.messagesModule = new MessagesModule(); this.generalModule = new GeneralModule(); this.whitelistModule = new WhitelistModule(); + this.discordWebhookModule = new DiscordWebhookModule(); } public CooldownModerationModule getCooldownModule() { @@ -53,5 +55,9 @@ public WhitelistModule getWhitelistModule() { return whitelistModule; } + public DiscordWebhookModule getDiscordWebhookModule() { + return discordWebhookModule; + } + public abstract void reloadData(); } diff --git a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/SyntaxModerationModule.java b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/SyntaxModerationModule.java index 151485a..0298119 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/SyntaxModerationModule.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/shared/modules/SyntaxModerationModule.java @@ -7,10 +7,11 @@ public class SyntaxModerationModule extends ModerationModule { private String[] whitelist; public void loadData(boolean enabled, String customName, int maxWarns, String warnNotification, - String[] whitelist, String[] commands) { + boolean webhookEnabled, String[] whitelist, String[] commands) { setEnabled(enabled); setMaxWarns(maxWarns); setWarnNotification(warnNotification); + setWebhookEnabled(webhookEnabled); setCommands(commands); setCustomName(customName); this.whitelist = whitelist; diff --git a/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java b/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java index e1749ca..3b34538 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/velocity/ChatSentinel.java @@ -193,6 +193,10 @@ public ChatEventResult processEvent(ChatPlayer chatPlayer, Player player, String // Send admin notification dispatchNotification(moderationModule, placeholders); + // Send discord webhook notification + DiscordWebhookModule discordWebhookModule = moduleManager.getDiscordWebhookModule(); + server.getScheduler().buildTask(this, () -> discordWebhookModule.dispatchWebhookNotification(moderationModule, placeholders)).schedule(); + // Update message finalResult.setMessage(result.getMessage()); diff --git a/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java b/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java index 22030fd..aa8fdae 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/velocity/modules/VelocityModuleManager.java @@ -48,6 +48,7 @@ public void reloadData() { configYml.node("caps", "replace").getBoolean(), configYml.node("caps", "max").getInt(), configYml.node("caps", "warn", "max").getInt(), configYml.node("caps", "warn", "notification").getString(), + configYml.node("caps", "warn", "webhook-notification").getBoolean(), configYml.node("caps", "punishments").childrenList().stream() .map(ConfigurationNode::getString) .toArray(String[]::new)); @@ -61,6 +62,7 @@ public void reloadData() { configYml.node("flood", "replace").getBoolean(), configYml.node("flood", "warn", "max").getInt(), configYml.node("flood", "pattern").getString(), configYml.node("flood", "warn", "notification").getString(), + configYml.node("flood", "warn", "webhook-notification").getBoolean(), configYml.node("flood", "punishments").childrenList().stream() .map(ConfigurationNode::getString) .toArray(String[]::new)); @@ -87,6 +89,7 @@ public void reloadData() { censorshipReplacement, configYml.node("blacklist", "warn", "max").getInt(), configYml.node("blacklist", "warn", "notification").getString(), + configYml.node("blacklist", "warn", "webhook-notification").getBoolean(), configYml.node("blacklist", "punishments").childrenList().stream() .map(ConfigurationNode::getString) .toArray(String[]::new), @@ -98,11 +101,27 @@ public void reloadData() { configYml.node("syntax", "custom-module-name").getString(), configYml.node("syntax", "warn", "max").getInt(), configYml.node("syntax", "warn", "notification").getString(), + configYml.node("syntax", "warn", "webhook-notification").getBoolean(), configYml.node("syntax", "whitelist").childrenList().stream() .map(ConfigurationNode::getString) .toArray(String[]::new), configYml.node("syntax", "punishments").childrenList().stream() .map(ConfigurationNode::getString) .toArray(String[]::new)); + getDiscordWebhookModule().loadData(configYml.node("discord-webhook", "enabled").getBoolean(), + configYml.node("discord-webhook", "webhook-url").getString(), + configYml.node("discord-webhook", "sender", "avatar-url").getString(), + configYml.node("discord-webhook", "sender", "username").getString(), + configYml.node("discord-webhook", "author", "name").getString(), + configYml.node("discord-webhook", "author", "url").getString(), + configYml.node("discord-webhook", "author", "icon-url").getString(), + configYml.node("discord-webhook", "title").getString(), + configYml.node("discord-webhook", "color").getString(), + configYml.node("discord-webhook", "description").getString(), + configYml.node("discord-webhook", "field-names", "message").getString(), + configYml.node("discord-webhook", "field-names", "server").getString(), + configYml.node("discord-webhook", "footer", "text").getString(), + configYml.node("discord-webhook", "footer", "icon-url").getString(), + configYml.node("discord-webhook", "thumbnail-url").getString()); } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index db5de83..2ee6fd7 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -57,6 +57,9 @@ blacklist: # You can use %server% on BungeeCord to get the server name. notification: "&c&lCS: &e%player% &ffailed &6%module% &7(&c%message%&7)" + # Discord webhook notification. + webhook-notification: true + # You need a mute plugin for ChatSentinel to mute players. (Recommended: LiteBans/AdvancedBans) # Set to [] to disable this feature completely. punishments: @@ -89,6 +92,9 @@ caps: # Set to "" to disable this feature completely. notification: "&c&lCS: &e%player% &ffailed &6%module% &7(&c%message%&7)" + # Discord webhook notification. + webhook-notification: true + # You need a mute plugin for ChatSentinel to mute players. (Recommended: LiteBans/AdvancedBans) # Set to [] to disable this feature completely. punishments: [] @@ -127,6 +133,9 @@ flood: # Set to "" to disable this feature completely. notification: "&c&lCS: &e%player% &ffailed &6%module% &7(&c%message%&7)" + # Discord webhook notification. + webhook-notification: true + # You need a mute plugin for ChatSentinel to mute players. (Recommended: LiteBans/AdvancedBans) # Set to [] to disable this feature completely. punishments: [] @@ -154,6 +163,60 @@ syntax: # Set to "" to disable this feature completely. notification: "&c&lCS: &e%player% &ffailed &6%module% &7(&c%message%&7)" + # Discord webhook notification. + webhook-notification: true + # You need a mute plugin for ChatSentinel to mute players. (Recommended: LiteBans/AdvancedBans) # Set to [] to disable this feature completely. punishments: [] + +# Discord webhook configuration. +discord-webhook: + # Do you want to enable this module? + enabled: false + + # Discord webhook URL. + webhook-url: "Your Discord Webhook URL here" + + sender: + # Sender avatar URL. + avatar-url: "https://avatars.githubusercontent.com/u/53847752?s=128&v=4" + + # Sender username. + username: "ArkFlame Development" + + author: + # Author name. + name: "ChatSentinel" + + # Author URL. + url: "https://builtbybit.com/resources/23698/" + + # Author icon URL. + icon-url: "https://avatars.githubusercontent.com/u/53847752?s=48&v=4" + + # Discord webhook title. + title: "Notification" + + # Discord webhook color (in hexadecimal format). + color: "#55FFFF" + + # Discord webhook description. + description: "**%player%** failed **%module%** (%warns%/%maxwarns%)" + + field-names: + # Message field name. + message: "Message" + + # Server field name. + server: "Server" + + footer: + # Footer text. + text: "ChatSentinel Detection" + + # Footer icon url. + icon-url: "https://avatars.githubusercontent.com/u/53847752?s=48&v=4" + + # Discord webhook thumbnail URL. + thumbnail-url: "https://avatars.githubusercontent.com/u/53847752?s=128&v=4" From f70764708e8a079e5d33e1cf3d1890960eb7fdbb Mon Sep 17 00:00:00 2001 From: MemencioPerez Date: Sun, 11 May 2025 05:45:40 -0400 Subject: [PATCH 7/7] 1.1.0 --- pom.xml | 2 +- .../dev/_2lstudios/chatsentinel/velocity/utils/Constants.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 685e9d1..cd2634e 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ ChatSentinel Advanced chat management plugin - 1.0.2 + 1.1.0 https://builtbybit.com/resources/23698/ diff --git a/src/main/java/dev/_2lstudios/chatsentinel/velocity/utils/Constants.java b/src/main/java/dev/_2lstudios/chatsentinel/velocity/utils/Constants.java index ce468f6..c4d09e0 100644 --- a/src/main/java/dev/_2lstudios/chatsentinel/velocity/utils/Constants.java +++ b/src/main/java/dev/_2lstudios/chatsentinel/velocity/utils/Constants.java @@ -3,7 +3,7 @@ public class Constants { public static final String ID = "chatsentinel"; public static final String NAME = "ChatSentinel"; - public static final String VERSION = "1.0.1"; + public static final String VERSION = "1.1.0"; public static final String DESCRIPTION = "Advanced chat management plugin"; public static final String URL = "https://builtbybit.com/resources/23698/"; public static final String AUTHOR = "2LS";