diff --git a/src/main/java/io/github/thetrouper/sentinel/Sentinel.java b/src/main/java/io/github/thetrouper/sentinel/Sentinel.java index 4706434..a3b5f63 100644 --- a/src/main/java/io/github/thetrouper/sentinel/Sentinel.java +++ b/src/main/java/io/github/thetrouper/sentinel/Sentinel.java @@ -212,7 +212,13 @@ public final class Sentinel extends JavaPlugin { * @return true if the command is logged, false otherwise */ public static boolean isLoggedCommand(String command) { - return Sentinel.mainConfig.plugin.logged.contains(command); + if (command.startsWith("/")) { + command = command.substring(1); + } + for (String logged : Sentinel.mainConfig.plugin.logged) { + if (command.contains(logged)) return true; + } + return false; } /** @@ -221,7 +227,13 @@ public final class Sentinel extends JavaPlugin { * @return true if the command is dangerous, false otherwise */ public static boolean isDangerousCommand(String command) { - return Sentinel.mainConfig.plugin.dangerous.contains(command); + if (command.startsWith("/")) { + command = command.substring(1); + } + for (String blocked : Sentinel.mainConfig.plugin.dangerous) { + if (command.contains(blocked)) return true; + } + return false; } /** * Returns an instance of this plugin diff --git a/src/main/java/io/github/thetrouper/sentinel/cmds/SentinelCommand.java b/src/main/java/io/github/thetrouper/sentinel/cmds/SentinelCommand.java index 22e9ee4..986cc36 100644 --- a/src/main/java/io/github/thetrouper/sentinel/cmds/SentinelCommand.java +++ b/src/main/java/io/github/thetrouper/sentinel/cmds/SentinelCommand.java @@ -7,6 +7,7 @@ import io.github.itzispyder.pdk.commands.Permission; import io.github.itzispyder.pdk.commands.completions.CompletionBuilder; import io.github.thetrouper.sentinel.Sentinel; import io.github.thetrouper.sentinel.server.functions.ProfanityFilter; +import io.github.thetrouper.sentinel.server.functions.SystemCheck; import io.github.thetrouper.sentinel.server.functions.Telemetry; import io.github.thetrouper.sentinel.server.util.CipherUtils; import io.github.thetrouper.sentinel.server.util.Text; @@ -34,7 +35,7 @@ public class SentinelCommand implements CustomCommand { instance.loadConfig(); } case "full-system-check" -> { - + SystemCheck.fullCheck(p); } case "debug" -> { switch (args.get(1).toString()) { diff --git a/src/main/java/io/github/thetrouper/sentinel/data/FAT.java b/src/main/java/io/github/thetrouper/sentinel/data/FAT.java index 62b91e5..d506982 100644 --- a/src/main/java/io/github/thetrouper/sentinel/data/FAT.java +++ b/src/main/java/io/github/thetrouper/sentinel/data/FAT.java @@ -7,7 +7,8 @@ public enum FAT { BLOCK_SPAM("Sentinel Anti-Spam", null, "spam-block-warn", "spam-notification",null,0x000000), SWEAR_PUNISH("Sentinel Anti-Swear Log","Anti-Swear", "profanity-mute-warn", "profanity-mute-notification", Sentinel.mainConfig.chat.antiSwear.swearPunishCommand, 0xFFB000), SLUR_PUNISH("Sentinel Anti-Slur Log", "Anti-Slur", "slur-mute-warn", "slur-mute-notification", Sentinel.mainConfig.chat.antiSwear.strictPunishCommand, 0xFF0000), - SPAM_PUNISH("Sentinel Anti-Spam Log", "Anti-Spam", "spam-mute-warn", "spam-mute-notification", Sentinel.mainConfig.chat.antiSpam.spamPunishCommand, 0xFF8000); + SPAM_PUNISH("Sentinel Anti-Spam Log", "Anti-Spam", "spam-mute-warn", "spam-mute-notification", Sentinel.mainConfig.chat.antiSpam.spamPunishCommand, 0xFF8000), + SAFE("Sentinel Chat Log", "You Shouldn't See this!", "spam-mute-warn", "spam-mute-notification", Sentinel.mainConfig.chat.antiSpam.spamPunishCommand, 0x00FF00); private final String title; private final String name; diff --git a/src/main/java/io/github/thetrouper/sentinel/data/config/AdvancedConfig.java b/src/main/java/io/github/thetrouper/sentinel/data/config/AdvancedConfig.java index bcf86b4..532e6c4 100644 --- a/src/main/java/io/github/thetrouper/sentinel/data/config/AdvancedConfig.java +++ b/src/main/java/io/github/thetrouper/sentinel/data/config/AdvancedConfig.java @@ -33,8 +33,9 @@ public class AdvancedConfig implements JsonSerializable { put("V", "u"); put("v", "u"); }}; + public String allowedCharRegex = "[A-Za-z0-9\\[,./?><|\\]§()*&^%$#@!~`{}:;'\"-_]"; public String falsePosRegex = ""; public String swearRegex = ""; public String strictRegex = ""; - public String urlRegex = "(http(s)?:\\/\\/.)?(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)"; + public String urlRegex = "(?:https?://)?(?:www.)?(?:(?[a-z0-9-]+).)?(?[a-z0-9-]+).(?:(?[a-z]{1,63}))?(?::(?[0-9]{1,5}))?(?:[/#](?[A-Za-z0-9_/.~:/?#\\[\\]@!$&'()*+,;=.]*)?)?"; } diff --git a/src/main/java/io/github/thetrouper/sentinel/discord/DiscordWebhook.java b/src/main/java/io/github/thetrouper/sentinel/discord/DiscordWebhook.java deleted file mode 100644 index ca734e2..0000000 --- a/src/main/java/io/github/thetrouper/sentinel/discord/DiscordWebhook.java +++ /dev/null @@ -1,425 +0,0 @@ -package io.github.thetrouper.sentinel.discord; - -import javax.net.ssl.HttpsURLConnection; -import java.awt.*; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.Array; -import java.net.URL; -import java.util.List; -import java.util.*; - -/** - * Class used to execute Discord Webhooks with low effort - */ - -@Deprecated -public class DiscordWebhook { - - private final String url; - private String content; - private String username; - private String avatarUrl; - private boolean tts; - private final List embeds = new ArrayList<>(); - private final List attachments = new ArrayList<>(); - - /** - * Constructs a new DiscordWebhook instance - * - * @param url The webhook URL obtained in Discord - */ - public DiscordWebhook(String url) { - this.url = url; - } - - public void setContent(String content) { - this.content = content; - } - - public void setUsername(String username) { - this.username = username; - } - - public void setAvatarUrl(String avatarUrl) { - this.avatarUrl = avatarUrl; - } - - public void setTts(boolean tts) { - this.tts = tts; - } - - public void addEmbed(EmbedObject embed) { - this.embeds.add(embed); - } - - public void addAttachment(String filename, String content) { - attachments.add(new Attachment(filename, content)); - } - - public void execute() throws IOException { - if (this.content == null && this.embeds.isEmpty() && this.attachments.isEmpty()) { - throw new IllegalArgumentException("Set content, add at least one EmbedObject, or add an attachment"); - } - - JSONObject json = new JSONObject(); - - json.put("content", this.content); - json.put("username", this.username); - json.put("avatar_url", this.avatarUrl); - json.put("tts", this.tts); - - if (!this.embeds.isEmpty()) { - List embedObjects = new ArrayList<>(); - - for (EmbedObject embed : this.embeds) { - JSONObject jsonEmbed = new JSONObject(); - - jsonEmbed.put("title", embed.getTitle()); - jsonEmbed.put("description", embed.getDescription()); - jsonEmbed.put("url", embed.getUrl()); - - if (embed.getColor() != null) { - Color color = embed.getColor(); - int rgb = color.getRed(); - rgb = (rgb << 8) + color.getGreen(); - rgb = (rgb << 8) + color.getBlue(); - - jsonEmbed.put("color", rgb); - } - - EmbedObject.Footer footer = embed.getFooter(); - EmbedObject.Image image = embed.getImage(); - EmbedObject.Thumbnail thumbnail = embed.getThumbnail(); - EmbedObject.Author author = embed.getAuthor(); - List fields = embed.getFields(); - - if (footer != null) { - JSONObject jsonFooter = new JSONObject(); - - jsonFooter.put("text", footer.getText()); - jsonFooter.put("icon_url", footer.getIconUrl()); - jsonEmbed.put("footer", jsonFooter); - } - - if (image != null) { - JSONObject jsonImage = new JSONObject(); - - jsonImage.put("url", image.getUrl()); - jsonEmbed.put("image", jsonImage); - } - - if (thumbnail != null) { - JSONObject jsonThumbnail = new JSONObject(); - - jsonThumbnail.put("url", thumbnail.getUrl()); - jsonEmbed.put("thumbnail", jsonThumbnail); - } - - if (author != null) { - JSONObject jsonAuthor = new JSONObject(); - - jsonAuthor.put("name", author.getName()); - jsonAuthor.put("url", author.getUrl()); - jsonAuthor.put("icon_url", author.getIconUrl()); - jsonEmbed.put("author", jsonAuthor); - } - - List jsonFields = new ArrayList<>(); - for (EmbedObject.Field field : fields) { - JSONObject jsonField = new JSONObject(); - - jsonField.put("name", field.getName()); - jsonField.put("value", field.getValue()); - jsonField.put("inline", field.isInline()); - - jsonFields.add(jsonField); - } - - jsonEmbed.put("fields", jsonFields.toArray()); - embedObjects.add(jsonEmbed); - } - - json.put("embeds", embedObjects.toArray()); - } - - if (!this.attachments.isEmpty()) { - List attachmentObjects = new ArrayList<>(); - - for (Attachment attachment : this.attachments) { - JSONObject attachmentObject = new JSONObject(); - attachmentObject.put("name", attachment.getFilename()); - attachmentObject.put("content", attachment.getContent()); - attachmentObjects.add(attachmentObject); - } - - json.put("attachments", attachmentObjects.toArray()); - } - - URL url = new URL(this.url); - HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); - connection.addRequestProperty("Content-Type", "application/json"); - connection.addRequestProperty("User-Agent", "Java-DiscordWebhook-BY-Gelox_"); - connection.setDoOutput(true); - connection.setRequestMethod("POST"); - - OutputStream stream = connection.getOutputStream(); - stream.write(json.toString().getBytes()); - stream.flush(); - stream.close(); - - connection.getInputStream().close(); //I'm not sure why but it doesn't work without getting the InputStream - connection.disconnect(); - } - - public static class EmbedObject { - private String title; - private String description; - private String url; - private Color color; - - private Footer footer; - private Thumbnail thumbnail; - private Image image; - private Author author; - private final List fields = new ArrayList<>(); - - public String getTitle() { - return title; - } - - public String getDescription() { - return description; - } - - public String getUrl() { - return url; - } - - public Color getColor() { - return color; - } - - public Footer getFooter() { - return footer; - } - - public Thumbnail getThumbnail() { - return thumbnail; - } - - public Image getImage() { - return image; - } - - public Author getAuthor() { - return author; - } - - public List getFields() { - return fields; - } - - public EmbedObject setTitle(String title) { - this.title = title; - return this; - } - - public EmbedObject setDescription(String description) { - this.description = description; - return this; - } - - public EmbedObject setUrl(String url) { - this.url = url; - return this; - } - - public EmbedObject setColor(Color color) { - this.color = color; - return this; - } - - public EmbedObject setFooter(String text, String icon) { - this.footer = new Footer(text, icon); - return this; - } - - public EmbedObject setThumbnail(String url) { - this.thumbnail = new Thumbnail(url); - return this; - } - - public EmbedObject setImage(String url) { - this.image = new Image(url); - return this; - } - - public EmbedObject setAuthor(String name, String url, String icon) { - this.author = new Author(name, url, icon); - return this; - } - - public EmbedObject addField(String name, String value, boolean inline) { - this.fields.add(new Field(name, value, inline)); - return this; - } - - private class Footer { - private final String text; - private final String iconUrl; - - private Footer(String text, String iconUrl) { - this.text = text; - this.iconUrl = iconUrl; - } - - private String getText() { - return text; - } - - private String getIconUrl() { - return iconUrl; - } - } - - private class Thumbnail { - private final String url; - - private Thumbnail(String url) { - this.url = url; - } - - private String getUrl() { - return url; - } - } - - private class Image { - private final String url; - - private Image(String url) { - this.url = url; - } - - private String getUrl() { - return url; - } - } - - private class Author { - private final String name; - private final String url; - private final String iconUrl; - - private Author(String name, String url, String iconUrl) { - this.name = name; - this.url = url; - this.iconUrl = iconUrl; - } - - private String getName() { - return name; - } - - private String getUrl() { - return url; - } - - private String getIconUrl() { - return iconUrl; - } - } - - private class Field { - private final String name; - private final String value; - private final boolean inline; - - private Field(String name, String value, boolean inline) { - this.name = name; - this.value = value; - this.inline = inline; - } - - private String getName() { - return name; - } - - private String getValue() { - return value; - } - - private boolean isInline() { - return inline; - } - } - } - - private class Attachment { - private final String filename; - private final String content; - - private Attachment(String filename, String content) { - this.filename = filename; - this.content = content; - } - - private String getFilename() { - return filename; - } - - private String getContent() { - return content; - } - } - - private class JSONObject { - - private final HashMap map = new HashMap<>(); - - void put(String key, Object value) { - if (value != null) { - map.put(key, value); - } - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - Set> entrySet = map.entrySet(); - builder.append("{"); - - int i = 0; - for (Map.Entry entry : entrySet) { - Object val = entry.getValue(); - builder.append(quote(entry.getKey())).append(":"); - - if (val instanceof String) { - builder.append(quote(String.valueOf(val))); - } else if (val instanceof Integer) { - builder.append(Integer.valueOf(String.valueOf(val))); - } else if (val instanceof Boolean) { - builder.append(val); - } else if (val instanceof JSONObject) { - builder.append(val); - } else if (val.getClass().isArray()) { - builder.append("["); - int len = Array.getLength(val); - for (int j = 0; j < len; j++) { - builder.append(Array.get(val, j).toString()).append(j != len - 1 ? "," : ""); - } - builder.append("]"); - } - - builder.append(++i == entrySet.size() ? "}" : ","); - } - - return builder.toString(); - } - - private String quote(String string) { - return "\"" + string + "\""; - } - } -} diff --git a/src/main/java/io/github/thetrouper/sentinel/discord/Webhook.java b/src/main/java/io/github/thetrouper/sentinel/discord/Webhook.java deleted file mode 100644 index e319a05..0000000 --- a/src/main/java/io/github/thetrouper/sentinel/discord/Webhook.java +++ /dev/null @@ -1,5 +0,0 @@ -package io.github.thetrouper.sentinel.discord; - -public class Webhook { - -} diff --git a/src/main/java/io/github/thetrouper/sentinel/events/ChatEvent.java b/src/main/java/io/github/thetrouper/sentinel/events/ChatEvent.java index a9aaf11..ce1a2e5 100644 --- a/src/main/java/io/github/thetrouper/sentinel/events/ChatEvent.java +++ b/src/main/java/io/github/thetrouper/sentinel/events/ChatEvent.java @@ -2,38 +2,53 @@ package io.github.thetrouper.sentinel.events; import io.github.itzispyder.pdk.events.CustomListener; import io.github.thetrouper.sentinel.Sentinel; +import io.github.thetrouper.sentinel.server.functions.AdvancedBlockers; import io.github.thetrouper.sentinel.server.functions.AntiSpam; -import io.github.thetrouper.sentinel.server.functions.AntiUnicode; import io.github.thetrouper.sentinel.server.functions.ProfanityFilter; import io.github.thetrouper.sentinel.server.util.ServerUtils; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.AsyncPlayerChatEvent; -public class ChatEvent implements CustomListener { +import java.util.function.Consumer; +public class ChatEvent implements CustomListener { @EventHandler - public static void onChat(AsyncPlayerChatEvent e) { + private void onChat(AsyncPlayerChatEvent e) { + handleChatEvent(e); + } + public static void handleChatEvent(AsyncPlayerChatEvent e) { if (e.isCancelled()) return; - ServerUtils.sendDebugMessage("ChatEvent: Chat event detected!"); - if (!Sentinel.isTrusted(e.getPlayer()) || !e.getPlayer().hasPermission("sentinel.chat.antiunicode.bypass")) { - ServerUtils.sendDebugMessage("ChatEvent: Permission bypass failed, checking for unicode"); - if (Sentinel.mainConfig.chat.antiUnicode) { - ServerUtils.sendDebugMessage(("ChatEvent: Enabled, Continuing unicode check!")); - AntiUnicode.handleAntiUnicode(e); - } - } - if (!Sentinel.isTrusted(e.getPlayer()) || !e.getPlayer().hasPermission("sentinel.chat.antiswear.bypass")) { - ServerUtils.sendDebugMessage("ChatEvent: Permission bypass failed, checking for swears"); - if (Sentinel.mainConfig.chat.antiSwear.antiSwearEnabled) { - ServerUtils.sendDebugMessage(("ChatEvent: Enabled, Continuing swear check!")); - ProfanityFilter.handleProfanityFilter(e); - } - } - if (!Sentinel.isTrusted(e.getPlayer()) || !e.getPlayer().hasPermission("sentinel.chat.antispam.bypass")) { - ServerUtils.sendDebugMessage(("ChatEvent: Permission bypass failed, checking for spam")); - if (Sentinel.mainConfig.chat.antiSpam.antiSpamEnabled) { - ServerUtils.sendDebugMessage(("ChatEvent: Enabled, Continuing spam check!")); - AntiSpam.handleAntiSpam(e); + + Player p = e.getPlayer(); + + handleEventIfNotBypassed(p, + "sentinel.chat.antiunicode.bypass", + Sentinel.mainConfig.chat.antiUnicode, "unicode", + e, + AdvancedBlockers::handleAdvanced); + + handleEventIfNotBypassed(p, + "sentinel.chat.antiswear.bypass", + Sentinel.mainConfig.chat.antiSwear.antiSwearEnabled, + "swear", + e, + ProfanityFilter::handleProfanityFilter); + + handleEventIfNotBypassed(p, + "sentinel.chat.antispam.bypass", + Sentinel.mainConfig.chat.antiSpam.antiSpamEnabled, + "spam", + e, + AntiSpam::handleAntiSpam); + } + + private static void handleEventIfNotBypassed(Player p, String permission, boolean isEnabled, String eventType, AsyncPlayerChatEvent e, Consumer handler) { + if (!Sentinel.isTrusted(p) || !p.hasPermission(permission)) { + ServerUtils.sendDebugMessage("ChatEvent: Permission bypass failed, checking for " + eventType); + if (isEnabled) { + ServerUtils.sendDebugMessage("ChatEvent: " + eventType + " check enabled, continuing!"); + handler.accept(e); } } } diff --git a/src/main/java/io/github/thetrouper/sentinel/events/CommandEvent.java b/src/main/java/io/github/thetrouper/sentinel/events/CommandEvent.java index ea3d0b4..217f8cc 100644 --- a/src/main/java/io/github/thetrouper/sentinel/events/CommandEvent.java +++ b/src/main/java/io/github/thetrouper/sentinel/events/CommandEvent.java @@ -10,61 +10,59 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerCommandPreprocessEvent; public class CommandEvent implements CustomListener { - private String trusted; + @EventHandler - private void onCommand(PlayerCommandPreprocessEvent e) { + public void onCommand(PlayerCommandPreprocessEvent e) { Player p = e.getPlayer(); + if (Sentinel.isTrusted(p)) return; String command = e.getMessage().substring(1).split(" ")[0]; String fullcommand = e.getMessage(); ServerUtils.sendDebugMessage("CommandEvent: Checking command"); - if (Sentinel.isDangerousCommand(command)) { + if (Sentinel.isDangerousCommand(fullcommand)) { ServerUtils.sendDebugMessage("CommandEvent: Command is dangerous"); - if (!Sentinel.isTrusted(p)) { - e.setCancelled(true); - ServerUtils.sendDebugMessage("CommandEvent: Command is canceled"); - Action a = new Action.Builder() - .setAction(ActionType.DANGEROUS_COMMAND) - .setEvent(e) - .setPlayer(p) - .setCommand(fullcommand) - .setDenied(true) - .setDeoped(Sentinel.mainConfig.plugin.deop) - .setPunished(Sentinel.mainConfig.plugin.commandPunish) - .setnotifyDiscord(Sentinel.mainConfig.plugin.logDangerous) - .setNotifyConsole(true) - .setNotifyTrusted(true) - .execute(); - } + e.setCancelled(true); + ServerUtils.sendDebugMessage("CommandEvent: Command is canceled"); + Action a = new Action.Builder() + .setAction(ActionType.DANGEROUS_COMMAND) + .setEvent(e) + .setPlayer(p) + .setCommand(fullcommand) + .setDenied(true) + .setDeoped(Sentinel.mainConfig.plugin.deop) + .setPunished(Sentinel.mainConfig.plugin.commandPunish) + .setnotifyDiscord(Sentinel.mainConfig.plugin.logDangerous) + .setNotifyConsole(true) + .setNotifyTrusted(true) + .execute(); } if (Sentinel.mainConfig.plugin.blockSpecific) { ServerUtils.sendDebugMessage("CommandEvent: Checking command for specific"); if (command.contains(":")) { ServerUtils.sendDebugMessage("CommandEvent: Failed check"); - if (!Sentinel.isTrusted(p)) { - e.setCancelled(true); - ServerUtils.sendDebugMessage(("CommandEvent: Not trusted, preforming action")); - Action a = new Action.Builder() - .setAction(ActionType.SPECIFIC_COMMAND) - .setEvent(e) - .setPlayer(p) - .setCommand(command) - .setDenied(true) - .setDeoped(Sentinel.mainConfig.plugin.deop) - .setPunished(Sentinel.mainConfig.plugin.specificPunish) - .setnotifyDiscord(Sentinel.mainConfig.plugin.logSpecific) - .setNotifyConsole(true) - .setNotifyTrusted(true) - .execute(); - } + e.setCancelled(true); + ServerUtils.sendDebugMessage(("CommandEvent: Not trusted, preforming action")); + Action a = new Action.Builder() + .setAction(ActionType.SPECIFIC_COMMAND) + .setEvent(e) + .setPlayer(p) + .setCommand(fullcommand) + .setDenied(true) + .setDeoped(Sentinel.mainConfig.plugin.deop) + .setPunished(Sentinel.mainConfig.plugin.specificPunish) + .setnotifyDiscord(Sentinel.mainConfig.plugin.logSpecific) + .setNotifyConsole(true) + .setNotifyTrusted(true) + .execute(); + } } - if (Sentinel.isLoggedCommand(command)) { + if (Sentinel.isLoggedCommand(fullcommand)) { ServerUtils.sendDebugMessage("CommandEvent: Is logged command, logging"); Action a = new Action.Builder() .setAction(ActionType.LOGGED_COMMAND) .setEvent(e) .setPlayer(p) - .setCommand(command) + .setCommand(fullcommand) .setDenied(false) .setDeoped(false) .setPunished(false) diff --git a/src/main/java/io/github/thetrouper/sentinel/events/NBTEvents.java b/src/main/java/io/github/thetrouper/sentinel/events/NBTEvents.java index d99d901..af81e1a 100644 --- a/src/main/java/io/github/thetrouper/sentinel/events/NBTEvents.java +++ b/src/main/java/io/github/thetrouper/sentinel/events/NBTEvents.java @@ -22,7 +22,7 @@ import java.util.Map; public class NBTEvents implements CustomListener { @EventHandler - private void onNBTPull(InventoryCreativeEvent e) { + public void onNBTPull(InventoryCreativeEvent e) { ServerUtils.sendDebugMessage("NBT: Detected creative mode action"); if (!Sentinel.mainConfig.plugin.preventNBT) return; ServerUtils.sendDebugMessage("NBT: Enabled"); diff --git a/src/main/java/io/github/thetrouper/sentinel/server/FilterAction.java b/src/main/java/io/github/thetrouper/sentinel/server/FilterAction.java index 317bb4f..bb7a81e 100644 --- a/src/main/java/io/github/thetrouper/sentinel/server/FilterAction.java +++ b/src/main/java/io/github/thetrouper/sentinel/server/FilterAction.java @@ -44,8 +44,7 @@ public class FilterAction { similarity ))); - playerWarning = Component.text(Text.prefix(Sentinel.language.get("spam-block-warn"))) - .hoverEvent(Component.text(Sentinel.language.get("action-automatic-reportable"))); + playerWarning = Component.text(Text.prefix(Sentinel.language.get("spam-block-warn"))); } case SPAM_PUNISH -> { staffNotif = Component.text(Text.prefix(String.format(Sentinel.language.get("spam-mute-notification"), @@ -59,8 +58,7 @@ public class FilterAction { similarity ))); - playerWarning = Component.text(Sentinel.language.get("spam-mute-warn")) - .hoverEvent(Component.text(Sentinel.language.get("action-automatic-reportable"))); + playerWarning = Component.text(Sentinel.language.get("spam-mute-warn")); sendConsoleLog(offender,e,type); sendDiscordLog(offender,e,type); } @@ -77,7 +75,8 @@ public class FilterAction { ))); playerWarning = Component.text(Text.prefix(Sentinel.language.get("profanity-block-warn"))) - .hoverEvent(Component.text(Sentinel.language.get("action-automatic-reportable"))); + .hoverEvent(Component.text(Sentinel.language.get("action-automatic-reportable"))) + .clickEvent(ClickEvent.runCommand("sentinelcallback fpreport " + report)); } case SWEAR_PUNISH -> { staffNotif = Component.text(Text.prefix(String.format(Sentinel.language.get("profanity-mute-notification"), diff --git a/src/main/java/io/github/thetrouper/sentinel/server/functions/AdvancedBlockers.java b/src/main/java/io/github/thetrouper/sentinel/server/functions/AdvancedBlockers.java index 20203d5..2e5d16b 100644 --- a/src/main/java/io/github/thetrouper/sentinel/server/functions/AdvancedBlockers.java +++ b/src/main/java/io/github/thetrouper/sentinel/server/functions/AdvancedBlockers.java @@ -1,20 +1,67 @@ package io.github.thetrouper.sentinel.server.functions; import io.github.thetrouper.sentinel.Sentinel; +import io.github.thetrouper.sentinel.data.FAT; +import io.github.thetrouper.sentinel.data.FilterSeverity; +import io.github.thetrouper.sentinel.server.FilterAction; import io.github.thetrouper.sentinel.server.util.Text; import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.jetbrains.annotations.Async; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class AdvancedBlockers { - public static void handleAntiURL(AsyncPlayerChatEvent e) { + public static void handleAdvanced(AsyncPlayerChatEvent e) { + if (!Sentinel.advConfig.allowedCharRegex.isBlank()) handleAntiUnicode(e); + if (!Sentinel.advConfig.urlRegex.isBlank()) handleAntiURL(e); + if (!Sentinel.advConfig.strictRegex.isBlank()) handleStrictRegex(e); + if (!Sentinel.advConfig.swearRegex.isBlank()) handleSwearRegex(e); + } + public static void handleAntiUnicode(AsyncPlayerChatEvent e) { String message = Text.removeFirstColor(e.getMessage()); - String nonAllowed = message.replaceAll("[A-Za-z0-9\\[,./?><|\\]§()*&^%$#@!~`{}:;'\"-_]", "").trim(); - if (message.matches("https?://(www\\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)")) { - - } + String nonAllowed = message.replaceAll(Sentinel.advConfig.allowedCharRegex, "").trim(); if (nonAllowed.length() != 0) { e.getPlayer().sendMessage(Text.prefix(Sentinel.language.get("unicode-warn"))); e.setCancelled(true); } } + + public static void handleSwearRegex(AsyncPlayerChatEvent e) { + String urlRegex = Sentinel.advConfig.swearRegex; + + Pattern pattern = Pattern.compile(urlRegex, Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(e.getMessage()); + + if (matcher.find()) { + e.setCancelled(true); + FilterAction.filterPunish(e,FAT.SWEAR_PUNISH,null,FilterSeverity.HIGH); + } + } + + public static void handleStrictRegex(AsyncPlayerChatEvent e) { + String urlRegex = Sentinel.advConfig.strictRegex; + + Pattern pattern = Pattern.compile(urlRegex, Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(e.getMessage()); + + if (matcher.find()) { + e.setCancelled(true); + FilterAction.filterPunish(e, FAT.SLUR_PUNISH,null, FilterSeverity.SLUR); + } + } + + public static void handleAntiURL(AsyncPlayerChatEvent e) { + String urlRegex = Sentinel.advConfig.urlRegex; + + Pattern pattern = Pattern.compile(urlRegex, Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(e.getMessage()); + + if (matcher.find()) { + e.setCancelled(true); + e.getPlayer().sendMessage(Text.prefix(Sentinel.language.get("unicode-warn"))); + } + } + } diff --git a/src/main/java/io/github/thetrouper/sentinel/server/functions/AntiUnicode.java b/src/main/java/io/github/thetrouper/sentinel/server/functions/AntiUnicode.java index 994cdf9..ae5f660 100644 --- a/src/main/java/io/github/thetrouper/sentinel/server/functions/AntiUnicode.java +++ b/src/main/java/io/github/thetrouper/sentinel/server/functions/AntiUnicode.java @@ -5,15 +5,5 @@ import io.github.thetrouper.sentinel.server.util.Text; import org.bukkit.event.player.AsyncPlayerChatEvent; public class AntiUnicode { - public static void handleAntiUnicode(AsyncPlayerChatEvent e) { - String message = Text.removeFirstColor(e.getMessage()); - String nonAllowed = message.replaceAll("[A-Za-z0-9\\[,./?><|\\]§()*&^%$#@!~`{}:;'\"-_]", "").trim(); - if (message.matches("https?://(www\\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)")) { - } - if (nonAllowed.length() != 0) { - e.getPlayer().sendMessage(Text.prefix(Sentinel.language.get("unicode-warn"))); - e.setCancelled(true); - } - } } diff --git a/src/main/java/io/github/thetrouper/sentinel/server/functions/Message.java b/src/main/java/io/github/thetrouper/sentinel/server/functions/Message.java index d7d3a09..9537a74 100644 --- a/src/main/java/io/github/thetrouper/sentinel/server/functions/Message.java +++ b/src/main/java/io/github/thetrouper/sentinel/server/functions/Message.java @@ -3,6 +3,7 @@ package io.github.thetrouper.sentinel.server.functions; import io.github.itzispyder.pdk.utils.ServerUtils; import io.github.thetrouper.sentinel.Sentinel; import io.github.thetrouper.sentinel.cmds.SocialSpyCommand; +import io.github.thetrouper.sentinel.events.ChatEvent; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.hover.content.Text; @@ -22,9 +23,7 @@ public class Message { receivers.add(sender); AsyncPlayerChatEvent checkEvent = new AsyncPlayerChatEvent(true,sender,message,receivers); if (checkEvent.isCancelled()) return; - if (!Sentinel.isTrusted(sender) || !sender.hasPermission("sentinel.chat.antiswear.bypass")) if (Sentinel.mainConfig.chat.antiSwear.antiSwearEnabled) ProfanityFilter.handleProfanityFilter(checkEvent); - if (!Sentinel.isTrusted(sender) || !sender.hasPermission("sentinel.chat.antispam.bypass")) if (Sentinel.mainConfig.chat.antiSpam.antiSpamEnabled) AntiSpam.handleAntiSpam(checkEvent); - if (!Sentinel.isTrusted(sender) || !sender.hasPermission("sentinel.chat.antiunicode.bypass")) if (Sentinel.mainConfig.chat.antiUnicode) AntiUnicode.handleAntiUnicode(checkEvent); + ChatEvent.handleChatEvent(checkEvent); if (checkEvent.isCancelled()) return; sender.sendMessage(Sentinel.language.get("message-sent").formatted(receiver.getName(),message)); diff --git a/src/main/java/io/github/thetrouper/sentinel/server/functions/ProfanityFilter.java b/src/main/java/io/github/thetrouper/sentinel/server/functions/ProfanityFilter.java index 7dcfb76..d24f25a 100644 --- a/src/main/java/io/github/thetrouper/sentinel/server/functions/ProfanityFilter.java +++ b/src/main/java/io/github/thetrouper/sentinel/server/functions/ProfanityFilter.java @@ -35,7 +35,7 @@ public class ProfanityFilter { ServerUtils.sendDebugMessage("AntiSwear Flag, Message: " + message + " Concentrated: " + fullSimplify(message) + " Severity: " + severity + " Previous Score: " + scoreMap.get(p) +" Adding Score: " + severity.getScore()); e.setCancelled(true); - if (scoreMap.get(p)+severity.getScore() > Sentinel.mainConfig.chat.antiSwear.punishScore) { + if (scoreMap.get(p) + severity.getScore() > Sentinel.mainConfig.chat.antiSwear.punishScore) { scoreMap.put(p,scoreMap.get(p)+severity.getScore()); FilterAction.filterPunish(e,FAT.SWEAR_PUNISH,null,severity); return; @@ -48,6 +48,9 @@ public class ProfanityFilter { private static FAT getFAT(FilterSeverity severity) { switch (severity) { + case SAFE -> { + return FAT.SAFE; + } case LOW, MEDIUM_LOW, MEDIUM, MEDIUM_HIGH, HIGH -> { return FAT.BLOCK_SWEAR; } @@ -179,6 +182,7 @@ public class ProfanityFilter { for (String falsePositive : swearWhitelist) { text = text.replace(falsePositive, ""); } + text = text.replaceAll(Sentinel.advConfig.falsePosRegex,""); return text; } public static String convertLeetSpeakCharacters(String text) { @@ -208,124 +212,4 @@ public class ProfanityFilter { } } } - - /*public static void handleProfanityFilter(AsyncPlayerChatEvent e) { - Player p = e.getPlayer(); - String message = Text.removeFirstColor(e.getMessage()); - String highlighted = highlightProfanity(message); - String severity = ProfanityFilter.checkSeverity(message); - if (!scoreMap.containsKey(p)) scoreMap.put(p, 0); - // Old: if (scoreMap.get(p) > Config.punishScore) punishSwear(p,highlighted,message,e); - if (scoreMap.get(p) > Sentinel.mainConfig.chat.antiSwear.punishScore) FilterAction.filterAction(p,e,highlighted,severity, null, FAT.SWEAR); - - switch (severity) { - case "low" -> { - ServerUtils.sendDebugMessage("AntiSwear Flag, Message: " + message + " Concentrated: " + fullSimplify(message) + " Severity: " + severity + " Previous Score: " + scoreMap.get(p) +" Adding Score: " + Sentinel.mainConfig.chat.antiSwear.lowScore); - scoreMap.put(p, scoreMap.get(p) + Sentinel.mainConfig.chat.antiSwear.lowScore); - e.setCancelled(true); - // Old: blockSwear(p,highlighted,message,severity,e); - FilterAction.filterAction(p,e,highlighted,severity, null, FAT.BLOCK_SWEAR); - } - case "medium-low" -> { - ServerUtils.sendDebugMessage("AntiSwear Flag, Message: " + message + " Concentrated: " + fullSimplify(message) + " Severity: " + severity + " Previous Score: " + scoreMap.get(p) +" Adding Score: " + Sentinel.mainConfig.chat.antiSwear.mediumLowScore); - scoreMap.put(p, scoreMap.get(p) + Sentinel.mainConfig.chat.antiSwear.mediumLowScore); - e.setCancelled(true); - // Old: blockSwear(p,highlighted,message,severity,e); - FilterAction.filterAction(p,e,highlighted,severity, null, FAT.BLOCK_SWEAR); - } - case "medium" -> { - ServerUtils.sendDebugMessage("AntiSwear Flag, Message: " + message + " Concentrated: " + fullSimplify(message) + " Severity: " + severity + " Previous Score: " + scoreMap.get(p) +" Adding Score: " + Sentinel.mainConfig.chat.antiSwear.mediumScore); - scoreMap.put(p, scoreMap.get(p) + Sentinel.mainConfig.chat.antiSwear.mediumScore); - e.setCancelled(true); - // Old: blockSwear(p,highlighted,message,severity,e); - FilterAction.filterAction(p,e,highlighted,severity, null, FAT.BLOCK_SWEAR); - } - case "medium-high" -> { - ServerUtils.sendDebugMessage("AntiSwear Flag, Message: " + message + " Concentrated: " + fullSimplify(message) + " Severity: " + severity + " Previous Score: " + scoreMap.get(p) +" Adding Score: " + Sentinel.mainConfig.chat.antiSwear.mediumHighScore); - scoreMap.put(p, scoreMap.get(p) + Sentinel.mainConfig.chat.antiSwear.mediumHighScore); - e.setCancelled(true); - // Old: blockSwear(p,highlighted,message,severity,e); - FilterAction.filterAction(p,e,highlighted,severity, null, FAT.BLOCK_SWEAR); - } - case "high" -> { - ServerUtils.sendDebugMessage("AntiSwear Flag, Message: " + message + " Concentrated: " + fullSimplify(message) + " Severity: " + severity + " Previous Score: " + scoreMap.get(p) +" Adding Score: " + Sentinel.mainConfig.chat.antiSwear.highScore); - scoreMap.put(p, scoreMap.get(p) + Sentinel.mainConfig.chat.antiSwear.highScore); - e.setCancelled(true); - // Old: blockSwear(p,highlighted,message,severity,e); - FilterAction.filterAction(p,e,highlighted,severity, null, FAT.BLOCK_SWEAR); - } - case "slur" -> { - // Insta-Punish - ServerUtils.sendDebugMessage("AntiSwear Flag, Message: " + message + " Concentrated: " + fullSimplify(message) + " Severity: " + severity + " Previous Score: " + scoreMap.get(p) +" Adding Score: " + Sentinel.mainConfig.chat.antiSwear.highScore); - scoreMap.put(p, scoreMap.get(p) + Sentinel.mainConfig.chat.antiSwear.highScore); - e.setCancelled(true); - // Old: punishSlur(p,highlighted,message,e); - FilterAction.filterAction(p,e,highlighted,severity, null,FAT.SLUR); - } - } - }*/ - - /* - public static void punishSwear(Player player, String highlightedMSG, String origMessage, AsyncPlayerChatEvent e) { - ServerUtils.sendCommand(Config.swearPunishCommand.replace("%player%", player.getName())); - String fpreport = ReportFalsePositives.generateReport(e); - TextComponent offender = new TextComponent(); - String hoverPlayer = Sentinel.language.get("action-automatic-reportable"); - offender.setText(Text.prefix(Sentinel.language.get("profanity-mute-warn"))); - offender.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(hoverPlayer))); - offender.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/sentinelcallback fpreport " + fpreport)); - player.spigot().sendMessage(offender); - - TextComponent text = new TextComponent(); - text.setText(Text.prefix(Sentinel.language.get("profanity-mute-notification").formatted(player.getName(),scoreMap.get(player),Config.punishScore))); - text.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(Sentinel.language.get("filter-notification-hover").formatted(origMessage,highlightedMSG)))); - text.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/sentinelcallback fpreport " + fpreport)); - - ServerUtils.forEachStaff(staff -> { - staff.spigot().sendMessage(text); - }); - if (Config.logSwear) WebhookSender.sendSwearLog(player,origMessage,scoreMap.get(player)); - } - - - public static void punishSlur(Player player, String highlightedMSG, String origMessage, AsyncPlayerChatEvent e) { - if (!Config.strictInstaPunish) return; - - ServerUtils.sendCommand(Config.strictPunishCommand.replace("%player%", player.getName())); - String fpreport = ReportFalsePositives.generateReport(e); - TextComponent offender = new TextComponent(); - String hoverPlayer = Sentinel.language.get("action-automatic-reportable"); - offender.setText(Text.prefix((Sentinel.language.get("slur-mute-warn")))); - offender.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(hoverPlayer))); - offender.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/sentinelcallback fpreport " + fpreport)); - player.spigot().sendMessage(offender); - TextComponent text = new TextComponent(); - text.setText(Text.prefix(Sentinel.language.get("slur-mute-notification").formatted(player.getName(),scoreMap.get(player),Config.punishScore))); - text.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(Sentinel.language.get("filter-notification-hover").formatted(origMessage,highlightedMSG)))); - text.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/sentinelcallback fpreport " + fpreport)); - - ServerUtils.forEachStaff(staff -> { - staff.spigot().sendMessage(text); - }); - if (Config.logSwear) WebhookSender.sendSlurLog(player,origMessage,scoreMap.get(player)); - } - public static void blockSwear(Player player, String highlightedMSG, String origMessage, String severity, AsyncPlayerChatEvent e) { - String FPReport = ReportFalsePositives.generateReport(e); - TextComponent offender = new TextComponent(); - String hover = Sentinel.language.get("action-automatic-reportable"); - offender.setText(Text.prefix((Sentinel.language.get("swear-block-warn")))); - offender.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(hover))); - offender.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/sentinelcallback fpreport " + FPReport)); - player.spigot().sendMessage(offender); - - TextComponent staff = new TextComponent(); - staff.setText(Text.prefix(Sentinel.language.get("swear-block-notification").formatted(player.getName(),scoreMap.get(player),Config.punishScore))); - staff.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(Sentinel.language.get("severity-notification-hover").formatted(origMessage,highlightedMSG,severity)))); - staff.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/sentinelcallback fpreport " + FPReport)); - - ServerUtils.forEachStaff(staffmember -> { - staffmember.spigot().sendMessage(staff); - }); - } -*/ } diff --git a/src/main/java/io/github/thetrouper/sentinel/server/functions/ReportFalsePositives.java b/src/main/java/io/github/thetrouper/sentinel/server/functions/ReportFalsePositives.java index 68143cd..49ea1cc 100644 --- a/src/main/java/io/github/thetrouper/sentinel/server/functions/ReportFalsePositives.java +++ b/src/main/java/io/github/thetrouper/sentinel/server/functions/ReportFalsePositives.java @@ -1,15 +1,17 @@ package io.github.thetrouper.sentinel.server.functions; +import io.github.itzispyder.pdk.utils.SchedulerUtils; +import io.github.itzispyder.pdk.utils.discord.DiscordEmbed; +import io.github.itzispyder.pdk.utils.discord.DiscordWebhook; import io.github.thetrouper.sentinel.Sentinel; import io.github.thetrouper.sentinel.data.Emojis; -import io.github.thetrouper.sentinel.discord.DiscordWebhook; import io.github.thetrouper.sentinel.server.util.Randomizer; import io.github.thetrouper.sentinel.server.util.ServerUtils; +import io.github.thetrouper.sentinel.server.util.Text; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.player.AsyncPlayerChatEvent; -import java.awt.*; import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -22,10 +24,10 @@ public class ReportFalsePositives { ServerUtils.sendDebugMessage("FP Report: Generating chat filter report"); reportMap.put(reportID,e); ServerUtils.sendDebugMessage(("FP Report: Generated chat filter report. ID:" + reportID + " Message: \"" + reportMap.get(reportID).getMessage() + "\" Expires in 60 seconds")); - Bukkit.getScheduler().runTaskLater(Sentinel.getInstance(),()->{ + SchedulerUtils.later(60000,()->{ reportMap.remove(reportID); ServerUtils.sendDebugMessage("FP Report: Chat filter Report expired. ID: " + reportID); - },60000); + }); return reportID; } public static void sendFalsePositiveReport(String reportID) { @@ -38,9 +40,12 @@ public class ReportFalsePositives { String remSpecials = ProfanityFilter.stripSpecialCharacters(convertedLeet); String simplifyRep = ProfanityFilter.simplifyRepeatingLetters(remSpecials); String sanitized = ProfanityFilter. removePeriodsAndSpaces(simplifyRep); - - sendEmbed(e.getPlayer(),orig,lowercasedText,remFP,convertedLeet,remSpecials,simplifyRep,sanitized); - + try { + sendEmbed(e.getPlayer(),orig,lowercasedText,remFP,convertedLeet,remSpecials,simplifyRep,sanitized); + } catch (Exception ex) { + e.getPlayer().sendMessage(Text.prefix("Report Failed!")); + Sentinel.log.warning(ex.getMessage()); + } } public static void sendEmbed(Player player, @@ -50,34 +55,32 @@ public class ReportFalsePositives { String convertedLeet, String remSpecials, String simplifyRep, - String sanitized) { + String sanitized) throws IOException { ServerUtils.sendDebugMessage("Creating FalsePositive Webhook..."); - DiscordWebhook webhook = new DiscordWebhook(Sentinel.mainConfig.plugin.webhook); - webhook.setAvatarUrl("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png"); - webhook.setUsername("Sentinel Anti-Nuke | Logs"); - DiscordWebhook.EmbedObject embed = new DiscordWebhook.EmbedObject() - .setAuthor("Anti-Swear False Positive","","") - .setTitle("Flag Report:") - .setDescription( - Emojis.rightSort + "Player: " + player.getName() + " " + Emojis.target + "\\n" + - Emojis.space + Emojis.arrowRight + "UUID: `" + player.getUniqueId() + "`\\n" - ) - .addField("Original Message", "`" + message + "` " + (ProfanityFilter.ContainsProfanity(message) ? Emojis.alarm : ""), false) - .addField("Lowercase", "`" + lowercased + "` " + (ProfanityFilter.ContainsProfanity(lowercased) ? Emojis.alarm : ""), false) - .addField("Removed FPs", "`" + remFP + "` " + (ProfanityFilter.ContainsProfanity(remFP) ? Emojis.alarm : ""), false) - .addField("Converted Leet", "`" + convertedLeet + "` " + (ProfanityFilter.ContainsProfanity(convertedLeet) ? Emojis.alarm : ""), false) - .addField("Removed Specials", "`" + remSpecials + "` " + (ProfanityFilter.ContainsProfanity(remSpecials) ? Emojis.alarm : ""), false) - .addField("Simplify Repeats", "`" + simplifyRep + "` " + (ProfanityFilter.ContainsProfanity(simplifyRep) ? Emojis.alarm : ""), false) - .addField("Fully Sanitized Message", ProfanityFilter.highlightProfanity(sanitized,"`", "`") + " " + Emojis.noDM, false) - .setColor(Color.green) - .setThumbnail("https://crafatar.com/avatars/" + player.getUniqueId() + "?size=64&&overlay"); - webhook.addEmbed(embed); - try { - ServerUtils.sendDebugMessage("FP Report: Executing webhook..."); - webhook.execute(); - } catch (IOException e) { - ServerUtils.sendDebugMessage("FP Report: Epic webhook failure!!!"); - Sentinel.log.info(e.toString()); - } + DiscordWebhook.create() + .avatar("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png") + .username("Sentinel Anti-Nuke | Logs") + .addEmbed(DiscordEmbed.create() + .author(new DiscordEmbed.Author("Anti-Swear False Positive","",null)) + .title("Flag Report:") + .desc(String.format("%1$sPlayer: %2$s %3$s\n%4$s %5$sUUID: `%2$s`\n", + Emojis.rightSort, + player.getName(), + Emojis.target, + Emojis.space, + Emojis.arrowRight + )) + .addField("Original Message", "`" + message + "` " + (ProfanityFilter.ContainsProfanity(message) ? Emojis.alarm : ""), false) + .addField("Lowercase", "`" + lowercased + "` " + (ProfanityFilter.ContainsProfanity(lowercased) ? Emojis.alarm : ""), false) + .addField("Removed FPs", "`" + remFP + "` " + (ProfanityFilter.ContainsProfanity(remFP) ? Emojis.alarm : ""), false) + .addField("Converted Leet", "`" + convertedLeet + "` " + (ProfanityFilter.ContainsProfanity(convertedLeet) ? Emojis.alarm : ""), false) + .addField("Removed Specials", "`" + remSpecials + "` " + (ProfanityFilter.ContainsProfanity(remSpecials) ? Emojis.alarm : ""), false) + .addField("Simplify Repeats", "`" + simplifyRep + "` " + (ProfanityFilter.ContainsProfanity(simplifyRep) ? Emojis.alarm : ""), false) + .addField("Fully Sanitized Message", ProfanityFilter.highlightProfanity(sanitized,"`", "`") + " " + Emojis.noDM, false) + .color(0x00FF00) + .thumbnail("https://crafatar.com/avatars/" + player.getUniqueId() + "?size=64&&overlay") + .build()) + .build().send(Sentinel.mainConfig.plugin.webhook); + } } diff --git a/src/main/java/io/github/thetrouper/sentinel/server/functions/SystemCheck.java b/src/main/java/io/github/thetrouper/sentinel/server/functions/SystemCheck.java index f888806..15390b6 100644 --- a/src/main/java/io/github/thetrouper/sentinel/server/functions/SystemCheck.java +++ b/src/main/java/io/github/thetrouper/sentinel/server/functions/SystemCheck.java @@ -1,29 +1,145 @@ package io.github.thetrouper.sentinel.server.functions; +import io.github.itzispyder.pdk.plugin.builders.ItemBuilder; import io.github.itzispyder.pdk.utils.SchedulerUtils; +import io.github.thetrouper.sentinel.Sentinel; import io.github.thetrouper.sentinel.cmds.SocialSpyCommand; +import io.github.thetrouper.sentinel.data.ActionType; +import io.github.thetrouper.sentinel.events.CommandEvent; +import io.github.thetrouper.sentinel.server.Action; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.block.data.type.CommandBlock; +import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.inventory.InventoryCreativeEvent; +import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import java.util.List; import java.util.Set; public class SystemCheck { public static void fullCheck(Player p) { - chatCheck(p); + boolean wasTrusted = false; + if (Sentinel.isTrusted(p)) { + wasTrusted = true; + Sentinel.mainConfig.plugin.trustedPlayers.remove(p.getUniqueId().toString()); + } + chatCheck(p); + cmdPlaceCheck(p); + cmdBlockUseCheck(p); + commandCheck(p); + nbtCheck(p); + + if (wasTrusted) Sentinel.mainConfig.plugin.trustedPlayers.add(p.getUniqueId().toString()); } + + public static void cmdPlaceCheck(Player p) { + Block placed = p.getLocation().clone().add(0,-2,0).getBlock(); + BlockState bs = placed.getState(); + placed.setType(Material.COMMAND_BLOCK); + EquipmentSlot es = EquipmentSlot.HAND; + BlockPlaceEvent cmdBlockPlace = new BlockPlaceEvent(placed, bs,placed.getLocation().clone().add(0,-1,0).getBlock(),new ItemBuilder().material(Material.COMMAND_BLOCK).build(),p,true,es); + Action a = new Action.Builder() + .setAction(ActionType.UPDATE_COMMAND_BLOCK) + .setEvent(cmdBlockPlace) + .setBlock(placed) + .setCommand("Sentinel CMDBlockPlace Check") + .setPlayer(p) + .setDenied(true) + .setPunished(Sentinel.mainConfig.plugin.cmdBlockPunish) + .setDeoped(Sentinel.mainConfig.plugin.deop) + .setnotifyDiscord(Sentinel.mainConfig.plugin.logCmdBlocks) + .setNotifyTrusted(true) + .setNotifyConsole(true) + .execute(); + } + + public static void cmdBlockUseCheck(Player p) { + Block placed = p.getLocation().clone().add(0,-2,0).getBlock(); + placed.setType(Material.COMMAND_BLOCK); + CommandBlock cmd = (CommandBlock) placed; + PlayerInteractEvent cmdUse = new PlayerInteractEvent(p, org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK,ItemBuilder.create().material(Material.AIR).build(),placed, BlockFace.UP); + Action a = new Action.Builder() + .setAction(ActionType.USE_COMMAND_BLOCK) + .setEvent(cmdUse) + .setBlock(placed) + .setPlayer(p) + .setDenied(true) + .setPunished(Sentinel.mainConfig.plugin.cmdBlockPunish) + .setDeoped(Sentinel.mainConfig.plugin.deop) + .setnotifyDiscord(Sentinel.mainConfig.plugin.logCmdBlocks) + .setNotifyTrusted(true) + .setNotifyConsole(true) + .execute(); + } + + public static void commandCheck(Player p) { + PlayerCommandPreprocessEvent command = new PlayerCommandPreprocessEvent(p,"/deop"); + PlayerCommandPreprocessEvent command2 = new PlayerCommandPreprocessEvent(p,"deop"); + new CommandEvent().onCommand(command); + } + + public static void nbtCheck(Player p) { + ItemStack i = ItemBuilder.create() + .material(Material.STICK) + .name("Name") + .lore(List.of("lore")) + .enchant(Enchantment.DAMAGE_ALL,255) + .attribute(Attribute.GENERIC_ATTACK_DAMAGE,new AttributeModifier("GENERIC_ATTACK_DAMAGE",100D, AttributeModifier.Operation.ADD_NUMBER)) + .build(); + InventoryCreativeEvent nbt = new InventoryCreativeEvent(p.openInventory(p.getInventory()), InventoryType.SlotType.QUICKBAR,8, i); + nbt.setCursor(i); + Action a = new Action.Builder() + .setEvent(nbt) + .setAction(ActionType.NBT) + .setPlayer(Bukkit.getPlayer(nbt.getWhoClicked().getName())) + .setItem(nbt.getCursor()) + .setDenied(Sentinel.mainConfig.plugin.preventNBT) + .setDeoped(Sentinel.mainConfig.plugin.deop) + .setPunished(Sentinel.mainConfig.plugin.nbtPunish) + .setRevertGM(Sentinel.mainConfig.plugin.preventNBT) + .setNotifyConsole(true) + .setNotifyTrusted(true) + .setnotifyDiscord(Sentinel.mainConfig.plugin.logNBT) + .execute(); + } + + public static void chatCheck(Player p) { SocialSpyCommand.spyMap.put(p.getUniqueId(),true); AsyncPlayerChatEvent swear = new AsyncPlayerChatEvent(true,p,"Sentinel AntiSwear check > Fvck", Set.of(p)); - AsyncPlayerChatEvent spam = new AsyncPlayerChatEvent(true,p,"Sentinel AntiSpam Check", Set.of(p)); + AsyncPlayerChatEvent spam = new AsyncPlayerChatEvent(true,p,"Sentinel AntiSpam check", Set.of(p)); + AsyncPlayerChatEvent falsePositive = new AsyncPlayerChatEvent(true,p,"Sentinel False Positive check > I like sentanal anti nuke", Set.of(p)); + AsyncPlayerChatEvent unicode = new AsyncPlayerChatEvent(true,p,"\u202Elmao i am bypassing the filter tihs ", Set.of(p)); + AsyncPlayerChatEvent url = new AsyncPlayerChatEvent(true,p,"join my lifesteal server! play.cringsteal.net", Set.of(p)); ProfanityFilter.handleProfanityFilter(swear); - SchedulerUtils.loop(10,5, (loop)->{ + AdvancedBlockers.handleAntiUnicode(unicode); + AdvancedBlockers.handleAntiURL(url); + SchedulerUtils.loop(10,3, (loop)->{ AntiSpam.lastMessageMap.put(p,"Sentinel AntiSpam Check"); AntiSpam.handleAntiSpam(spam); }); + String report = ReportFalsePositives.generateReport(falsePositive); - Message.messagePlayer(p,p,"Sentinel Automatic System Check > Private Message"); + SchedulerUtils.later(20,()->{ + ReportFalsePositives.sendFalsePositiveReport(report); + }); + + Message.messagePlayer(p,p,"Sentinel Automatic System check > Private Message"); } }