Finished language and filter rewrite

This commit is contained in:
obvWolf
2024-02-22 16:22:46 -06:00
parent 8dd82b1332
commit cf78d41345
22 changed files with 381 additions and 449 deletions

View File

@@ -37,7 +37,7 @@ public final class Sentinel extends JavaPlugin {
public static StrictConfig strictConfig = JsonSerializable.load(strctcfg, StrictConfig.class, new StrictConfig());
public static NBTConfig nbtConfig = JsonSerializable.load(nbtcfg, NBTConfig.class, new NBTConfig());
public static AdvancedConfig advConfig = JsonSerializable.load(advcfg, AdvancedConfig.class, new AdvancedConfig());
public static LanguageFile language;
public static LanguageFile lang;
public static ProtocolManager protocolManager;
public static final PluginManager manager = Bukkit.getPluginManager();
@@ -72,7 +72,7 @@ public final class Sentinel extends JavaPlugin {
log.warning("Sentinel: ProtocolLib not found. Sentinel will not attempt to hide your plugins.");
}
log.info("Language Status: (%s)".formatted(language.get("if-you-see-this-lang-is-broken")));
log.info("Language Status: (%s)".formatted(lang.brokenLang));
log.info("Initializing Server ID...");
serverID = Authenticator.getServerID();
@@ -200,8 +200,8 @@ public final class Sentinel extends JavaPlugin {
log.info("Loading Dictionary (%s)...".formatted(Sentinel.mainConfig.plugin.lang));
language = JsonSerializable.load(LanguageFile.PATH,LanguageFile.class,new LanguageFile());
language.save();
lang = JsonSerializable.load(LanguageFile.PATH,LanguageFile.class,new LanguageFile());
lang.save();
}

View File

@@ -24,17 +24,17 @@ public class ChatClickCallback implements CustomCommand {
switch (args.get(0).toString()) {
case "fpreport" -> {
if (fpReportCooldown.isOnCooldown(p.getUniqueId()) && !p.isOp()) {
p.sendMessage(Text.prefix(Sentinel.language.get("cooldown") + fpReportCooldown.getCooldown(p.getUniqueId())));
p.sendMessage(Text.prefix(Sentinel.lang.cooldown.onCooldown + fpReportCooldown.getCooldown(p.getUniqueId())));
} else {
long id = args.get(1).toLong();
Report send = ReportFalsePositives.reports.get(id);
if (send == null) {
p.sendMessage(Text.prefix(Sentinel.language.get("no-report")));
p.sendMessage(Text.prefix(Sentinel.lang.reports.noReport));
return;
}
p.sendMessage(Text.prefix(Sentinel.language.get("reporting-false-positive")));
p.sendMessage(Text.prefix(Sentinel.lang.reports.reportingFalsePositive));
ReportFalsePositives.sendFalsePositiveReport(send);
p.sendMessage(Text.prefix(Sentinel.language.get("false-positive-report-success")));
p.sendMessage(Text.prefix(Sentinel.lang.reports.falsePositiveSuccess));
}
}
}

View File

@@ -20,11 +20,11 @@ public class MessageCommand implements CustomCommand {
Player p = (Player) sender;
Player r = null;
if (args.getSize() == 0) {
p.sendMessage(Text.prefix(Sentinel.language.get("no-online-player")));
p.sendMessage(Text.prefix(Sentinel.lang.playerInteraction.noOnlinePlayer));
return;
}
if (args.getSize() == 1) {
p.sendMessage(Text.prefix(Sentinel.language.get("no-message-provided")));
p.sendMessage(Text.prefix(Sentinel.lang.playerInteraction.noMessageProvided));
return;
}
r = Bukkit.getPlayer(args.get(0).toString());
@@ -33,8 +33,8 @@ public class MessageCommand implements CustomCommand {
if (p.hasPermission("sentinel.message") && r != null) {
Message.messagePlayer(p,r,msg);
} else if (r == null) p.sendMessage(Text.prefix((Sentinel.language.get("no-online-player"))));
else sender.sendMessage(Text.prefix(Sentinel.language.get("no-permission")));
} else if (r == null) p.sendMessage(Text.prefix((Sentinel.lang.playerInteraction.noOnlinePlayer)));
else sender.sendMessage(Text.prefix(Sentinel.lang.permissions.noPermission));
}
@Override

View File

@@ -16,16 +16,16 @@ public class ReopCommand implements CustomCommand {
Player p = (Player) sender;
if (Sentinel.isTrusted(p) && Sentinel.mainConfig.plugin.reopCommand) {
if (!p.isOp()) {
p.sendMessage(Text.prefix(Sentinel.language.get("elevating-perms")));
Sentinel.log.info(Sentinel.language.get("log-elevating-perms").formatted(p.getName()));
p.sendMessage(Text.prefix(Sentinel.lang.permissions.elevatingPerms));
Sentinel.log.info(Sentinel.lang.permissions.logElevatingPerms.formatted(p.getName()));
p.setOp(true);
} else {
p.sendMessage(Text.prefix(Sentinel.language.get("already-op")));
Sentinel.log.info(Sentinel.language.get("log-already-op").formatted(p.getName()));
p.sendMessage(Text.prefix(Sentinel.lang.permissions.alreadyOp));
Sentinel.log.info(Sentinel.lang.permissions.logAlreadyOp.formatted(p.getName()));
p.setOp(true);
}
} else {
p.sendMessage(Text.prefix(Sentinel.language.get("no-trust")));
p.sendMessage(Text.prefix(Sentinel.lang.permissions.noTrust));
}
}

View File

@@ -23,19 +23,19 @@ public class ReplyCommand implements CustomCommand {
Player p = sender.getServer().getPlayer(name);
UUID senderID = p.getUniqueId();
if (replyMap.get(senderID) == null) {
p.sendMessage(Text.prefix(Sentinel.language.get("no-user-reply")));
p.sendMessage(Text.prefix(Sentinel.lang.playerInteraction.noReply));
}
Player r = sender.getServer().getPlayer(replyMap.get(senderID));
UUID reciverID = r.getUniqueId();
if (args.get(0).toString() == null) {
p.sendMessage(Text.prefix(Sentinel.language.get("no-message-provided")));
p.sendMessage(Text.prefix(Sentinel.lang.playerInteraction.noMessageProvided));
}
String msg = args.getAll().toString();
if (p.hasPermission("sentinel.message")) {
Message.messagePlayer(p,r,msg);
replyMap.put(senderID,reciverID);
} else {
sender.sendMessage(Text.prefix(Sentinel.language.get("no-permission")));
sender.sendMessage(Text.prefix(Sentinel.lang.permissions.noPermission));
}
}

View File

@@ -6,16 +6,9 @@ import io.github.itzispyder.pdk.commands.CustomCommand;
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.data.Report;
import io.github.thetrouper.sentinel.data.cmdblocks.WhitelistedBlock;
import io.github.thetrouper.sentinel.events.ChatEvent;
import io.github.thetrouper.sentinel.server.functions.*;
import io.github.thetrouper.sentinel.server.util.CipherUtils;
import io.github.thetrouper.sentinel.server.util.Text;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CommandBlock;
@@ -23,11 +16,9 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@CommandRegistry(value = "sentinel",permission = @Permission("sentinel.debug"),printStackTrace = true)
@CommandRegistry(value = "sentinel",permission = @Permission("sentinel.staff"),printStackTrace = true)
public class SentinelCommand implements CustomCommand {
public static boolean debugMode;
@Override
@@ -43,41 +34,60 @@ public class SentinelCommand implements CustomCommand {
instance.loadConfig();
}
case "full-system-check" -> {
if (!Sentinel.isTrusted(p)) return;
p.sendMessage(Text.prefix("Initiating a full system check!"));
SystemCheck.fullCheck(p);
}
case "debug" -> handleDebugCommand(p,args);
case "false-positive" -> {
}
}
}
private void handleFalsePositive(Player p, Args args) {
String falsePositive = args.getAll(2).toString();
switch (args.get(1).toString()) {
case "add" -> {
Sentinel.fpConfig.swearWhitelist.add(falsePositive);
p.sendMessage(Text.prefix("&7Successfully added &a%s&7 to the false positive list!".formatted(falsePositive)));
}
case "remove" -> {
Sentinel.fpConfig.swearWhitelist.remove(falsePositive);
p.sendMessage(Text.prefix("&7Successfully removed &c%s&7 to the false positive list!".formatted(falsePositive)));
}
}
Sentinel.fpConfig.save();
}
private void handleCommandBlock(Player p, Args args) {
if (!Sentinel.isTrusted(p)) return;
Block target = p.getTargetBlock(Set.of(Material.AIR),10);
switch (args.get(1).toString()) {
case "add" -> {
if (target.getType().equals(Material.COMMAND_BLOCK) || target.getType().equals(Material.REPEATING_COMMAND_BLOCK) || target.getType().equals(Material.CHAIN_COMMAND_BLOCK)) {
CommandBlock cb = (CommandBlock) target.getState();
CMDBlockWhitelist.add(cb,p.getUniqueId());
p.sendMessage(Text.prefix("Successfully whitelisted a &b" + Text.blockName(cb.getType().toString()) + "&7 with the command &a" + cb.getCommand() + "&7."));
p.sendMessage(Text.prefix("Successfully whitelisted a &b" + Text.cleanName(cb.getType().toString()) + "&7 with the command &a" + cb.getCommand() + "&7."));
return;
}
p.sendMessage(Text.prefix("Could not whitelist the &b" + Text.blockName(target.getType().toString()) + "&7 it is not a command block!"));
p.sendMessage(Text.prefix("Could not whitelist the &b" + Text.cleanName(target.getType().toString()) + "&7 it is not a command block!"));
}
case "remove" -> {
WhitelistedBlock wb = CMDBlockWhitelist.get(target.getLocation());
if (wb != null) {
CMDBlockWhitelist.remove(target.getLocation());
p.sendMessage(Text.prefix("Successfully removed 1 &b" + Text.blockName(WhitelistedBlock.fromSerialized(wb.loc()).getBlock().getType().toString()) + "&7 with the command &a" + wb.command() + "&7."));
p.sendMessage(Text.prefix("Successfully removed 1 &b" + Text.cleanName(WhitelistedBlock.fromSerialized(wb.loc()).getBlock().getType().toString()) + "&7 with the command &a" + wb.command() + "&7."));
return;
}
p.sendMessage(Text.prefix("Could not un-whitelist the &b" + Text.blockName(target.getType().toString()) + "&7 it wasn't whitelisted in the first place!"));
p.sendMessage(Text.prefix("Could not un-whitelist the &b" + Text.cleanName(target.getType().toString()) + "&7 it wasn't whitelisted in the first place!"));
}
}
}
private void handleDebugCommand(Player p, Args args) {
if (!p.hasPermission("sentinel.debug")) return;
switch (args.get(1).toString()) {
case "lang" -> {
p.sendMessage(Sentinel.language.get("exmaple-message"));
p.sendMessage(Sentinel.lang.brokenLang);
}
case "toggle" -> {
debugMode = !debugMode;
@@ -96,6 +106,7 @@ public class SentinelCommand implements CustomCommand {
@Override
public void dispatchCompletions(CompletionBuilder b) {
b.then(b.arg("reload","full-system-check"));
b.then(b.arg("false-positive").then(b.arg("add","remove")));
b.then(b.arg("debug").then(
b.arg("lang","toggle","chat")));
b.then(b.arg("commandblock"));

View File

@@ -24,10 +24,10 @@ public class SocialSpyCommand implements CustomCommand {
Player p = sender.getServer().getPlayer(name);
UUID senderID = p.getUniqueId();
if (!spyMap.containsKey(senderID) || !spyMap.get(senderID)) {
sender.sendMessage(Text.prefix(Sentinel.language.get("spy-enabled")));
sender.sendMessage(Text.prefix(Sentinel.lang.socialSpy.enabled));
spyMap.put(senderID,true);
} else if (spyMap.get(senderID)) {
sender.sendMessage(Text.prefix(Sentinel.language.get("spy-disabled")));
sender.sendMessage(Text.prefix(Sentinel.lang.socialSpy.disabled));
spyMap.put(senderID,false);
}
}

View File

@@ -2,13 +2,14 @@ package io.github.thetrouper.sentinel.data;
import io.github.thetrouper.sentinel.Sentinel;
public record FilterActionType(String logTitle, String logName, String chatWarning, String chatWarningHover, String chatNotification, String chatNotificationHover, String punishmentCommand, int embedColor) {
public static final FilterActionType UNICODE_BLOCK = new FilterActionType("Sentinel Anti-Unicode Log","Anti-Unicode","unicode-warn","action-automatic-reportable","unicode-notification","unicode-notification-hover", null,0xFF0000);
public static final FilterActionType URL_BLOCK = new FilterActionType("Sentinel Anti-URL Log","Anti-URL","url-warn","action-automatic-reportable","url-notification","url-notification-hover", null,0xFF0000);
public static final FilterActionType SPAM_BLOCK = new FilterActionType("Sentinel Anti-Spam Log","Anti-Spam","spam-warn","action-automatic-reportable","spam-notification","spam-notification-hover", null,0xFF0000);
public static final FilterActionType SPAM_PUNISH = new FilterActionType("Sentinel Anti-Spam Log","Anti-Spam","spam-mute-warn","action-automatic-reportable","spam-mute-notification","spam-notification-hover", Sentinel.mainConfig.chat.antiSpam.spamPunishCommand,0xFF0000);
public static final FilterActionType SWEAR_BLOCK = new FilterActionType("Sentinel Profanity Filter Log","Anti-Swear","profanity-warn","action-automatic-reportable","profanity-notification","profanity-notification-hover", null,0xFF0000);
public static final FilterActionType SWEAR_PUNISH = new FilterActionType("Sentinel Profanity Filter Log","Anti-Swear","profanity-mute-warn","action-automatic-reportable","profanity-mute-notification","profanity-notification-hover", Sentinel.mainConfig.chat.antiSwear.swearPunishCommand,0xFF0000);
public static final FilterActionType SLUR_PUNISH = new FilterActionType("Sentinel Profanity Filter Log","Anti-Slur","slur-mute-warn","action-automatic-reportable","slur-mute-notification","profanity-notification-hover", Sentinel.mainConfig.chat.antiSwear.strictPunishCommand,0xFF0000);
public static final FilterActionType SAFE = new FilterActionType("ERROR",null,null,null,null,null,null,0x00AA00);
public record FilterActionType(String logTitle, String logName, String chatWarning, String chatWarningHover, String chatNotification, String chatNotificationHover, String punishmentCommand, int embedColor, boolean isLogged) {
public static final FilterActionType UNICODE_BLOCK = new FilterActionType("Sentinel Anti-Unicode Log", "Anti-Unicode", Sentinel.lang.unicodeFilter.unicodeWarn, Sentinel.lang.automatedActions.actionAutomaticReportable, Sentinel.lang.unicodeFilter.unicodeNotification, Sentinel.lang.unicodeFilter.unicodeNotificationHover, null, 0xAAAAFF, Sentinel.mainConfig.chat.logUnicode);
public static final FilterActionType URL_BLOCK = new FilterActionType("Sentinel Anti-URL Log", "Anti-URL", Sentinel.lang.urlFilter.urlWarn, Sentinel.lang.automatedActions.actionAutomaticReportable, Sentinel.lang.urlFilter.urlNotification, Sentinel.lang.urlFilter.urlNotificationHover, null, 0xAAAAFF, Sentinel.mainConfig.chat.logURL);
public static final FilterActionType SPAM_BLOCK = new FilterActionType("Sentinel Anti-Spam Log", "Anti-Spam", Sentinel.lang.spamFilter.spamWarn, Sentinel.lang.automatedActions.actionAutomatic, Sentinel.lang.spamFilter.spamNotification, Sentinel.lang.spamFilter.spamNotificationHover, null, 0xFFFF00, Sentinel.mainConfig.chat.antiSpam.logAllSpam);
public static final FilterActionType SPAM_PUNISH = new FilterActionType("Sentinel Anti-Spam Log", "Anti-Spam", Sentinel.lang.spamFilter.spamMuteWarn, Sentinel.lang.automatedActions.actionAutomaticReportable, Sentinel.lang.spamFilter.spamMuteNotification, Sentinel.lang.spamFilter.spamNotificationHover, Sentinel.mainConfig.chat.antiSpam.spamPunishCommand, 0xFF0000, Sentinel.mainConfig.chat.antiSpam.logSpamPunishments);
public static final FilterActionType SWEAR_BLOCK = new FilterActionType("Sentinel Profanity Filter Log", "Anti-Swear", Sentinel.lang.profanityFilter.profanityWarn, Sentinel.lang.automatedActions.actionAutomaticReportable, Sentinel.lang.profanityFilter.profanityNotification, Sentinel.lang.profanityFilter.profanityNotificationHover, null, 0xFFFF00, Sentinel.mainConfig.chat.antiSwear.logAllSwears);
public static final FilterActionType SWEAR_PUNISH = new FilterActionType("Sentinel Profanity Filter Log", "Anti-Swear", Sentinel.lang.profanityFilter.profanityMuteWarn, Sentinel.lang.automatedActions.actionAutomaticReportable, Sentinel.lang.profanityFilter.profanityMuteNotification, Sentinel.lang.profanityFilter.profanityNotificationHover, Sentinel.mainConfig.chat.antiSwear.swearPunishCommand, 0xFF0000, Sentinel.mainConfig.chat.antiSwear.logSwearPunishments);
public static final FilterActionType SLUR_PUNISH = new FilterActionType("Sentinel Profanity Filter Log", "Anti-Slur", Sentinel.lang.slurFilter.slurMuteWarn, Sentinel.lang.automatedActions.actionAutomaticReportable, Sentinel.lang.slurFilter.slurMuteNotification, Sentinel.lang.profanityFilter.profanityNotificationHover, Sentinel.mainConfig.chat.antiSwear.strictPunishCommand, 0xFF0000, Sentinel.mainConfig.chat.antiSwear.logSwearPunishments);
public static final FilterActionType SAFE = new FilterActionType("ERROR", null, null, null, null, null, null, 0x00AA00,false);
}

View File

@@ -6,66 +6,101 @@ import io.github.thetrouper.sentinel.Sentinel;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Filter;
public class LanguageFile implements JsonSerializable<LanguageFile> {
public static final File PATH = new File(Sentinel.getInstance().getDataFolder(), "/lang/" + Sentinel.mainConfig.plugin.lang);
private final Map<String,String> dictionary = new HashMap<>() {{
put("if-you-see-this-lang-is-broken", "Sentinel language is working!");
put("no-permission", "§cInsufficient Permissions!");
put("cooldown", "This action is on cooldown!");
put("false-positive-report-success", "Successfully reported a false positive!");
put("no-online-player", "§cYou must provide an online player to send a message to!");
put("no-message-provided", "§cYou must provide a message to send!");
put("elevating-perms", "Elevating your permissions...");
put("log-elevating-perms", "Elevating the permissions of %s");
put("already-op", "You are already a server operator!");
put("log-already-op", "The permissions of %s are already elevated! Retrying...");
put("no-trust", "You are not a trusted user!");
put("no-user-reply", "§cYou have nobody to reply to!");
put("spy-enabled", "SocialSpy is now enabled.");
put("spy-disabled", "SocialSpy is now disabled.");
put("action-automatic", "§7This action was preformed automatically\n§7by the §bSentinel Anti-Spam§7 algorithm.");
put("action-automatic-reportable", "§7This action was preformed automatically \n§7by the §bSentinel Profanity Filter§7 algorithm!\n§8§o(Click to report false positive)");
put("message-sent", "§d§lMessage §8» §b[§fYou §e>§f %1$s§b] §7%2$s");
put("message-received", "§d§lMessage §8» §b[§f%1$s §e>§f You§b] §7%2$s");
put("spy-message", "§d§lSpy §8» §b§n%1$s§7 has messaged §b§n%2$s§7.");
put("spy-message-hover", "§8]==-- §d§lSocialSpy §8--==[\n§bSender: §f%1$S\n§bReceiver: §f%2$S\n§bMessage: §f%3$S");
put("profanity-notification", "§b§n%1$s§7 has triggered the anti-swear! §8(§c%2$s§7/§4%3$s§8)");
put("profanity-warn", "§cPlease do not swear in chat! Attempting to bypass this filter will result in a mute! §7§o(Hover for more info)");
put("profanity-mute-warn", "You have been auto-muted for repeated violation of the profanity filter! §7§o(Hover for more info)");
put("profanity-mute-notification", "§b§n%1$s§7 has been auto-muted by the anti-swear! §8(§c%2$s§7/§4%3$s§8)");
put("profanity-notification-hover", "§8]==-- §d§lSentinel §8--==[\n§bOriginal: §f%1$s\n§bSanitized: §f%2$s\n§8§o(Click to report false positive)");
put("severity-notification-hover", "§8]==-- §d§lSentinel §8--==[\n§bOriginal: §f%1$s\n§bSanitized: §f%2$s\n§bSeverity: §c%3$s\n§7§o(click to report false positive)");
put("slur-mute-warn", "§cYou have been insta-punished by the anti-slur! §7§o(Hover for more info)");
put("slur-mute-notification", "§b§n%1$s§7 has been insta-muted by the anti-swear! §8(§c%2$s§7/§4%3$s§8)");
put("spam-notification", "§b§n%1$s§7 might be spamming! §8(§c%2$s§7/§4%3$s§8)");
put("spam-notification-hover", "§8]==-- §d§lSentinel §8--==[\n§bPrevious: §f%1$s\n§bCurrent: §f%2$s\n§bSimilarity §f%3$s");
put("spam-warn", "Do not spam in chat! Please wait before sending another message.");
put("spam-mute-warn", "§cYou have been auto-punished for violating the anti-spam repetitively!");
put("spam-mute-notification", "§b§n%1$s§7 has been auto-muted by the anti spam! §8(§c%2$s§7/§4%3$s§8)");
put("url-warn", "§cDo not send urls in chat!");
put("url-notification", "§b§n%1$s§7 has triggered the anti-URL.");
put("url-notification-hover", "§8]==-- §d§lSentinel §8--==[\n§bDetected: §f%1$s");
put("unicode-warn", "§cDo not send non-standard unicode in chat!");
put("unicode-notification", "§b§n%1$s§7 has triggered the anti-unicode.");
put("unicode-notification-hover", "§8]==-- §d§lSentinel §8--==[\n§bMessage: §f%1$s");
put("no-plugins-for-u", "§cThis server wishes to keep their plugins confidential.");
put("reporting-false-positive","Sending report to staff...");
put("no-report","§cThe report you requested either does not exist, or has expired!");
}};
public LanguageFile() {}
@Override
public File getFile() {
return PATH;
}
public String get(String key) {
return dictionary.getOrDefault(key,key);
public String brokenLang = "Sentinel language is working!";
public Permissions permissions = new Permissions();
public class Permissions {
public String noPermission = "§cInsufficient Permissions!";
public String elevatingPerms = "Elevating your permissions...";
public String logElevatingPerms = "Elevating the permissions of %s";
public String alreadyOp = "You are already a server operator!";
public String logAlreadyOp = "The permissions of %s are already elevated! Retrying...";
public String noTrust = "You are not a trusted user!";
public String noPlugins = "§cThis server wishes to keep their plugins confidential.";
}
public Map<String, String> getDictionary() {
return dictionary;
public Cooldown cooldown = new Cooldown();
public class Cooldown {
public String onCooldown = "This action is on cooldown!";
}
public String format(String input) {
return input;
public Reports reports = new Reports();
public class Reports {
public String falsePositiveSuccess = "Successfully reported a false positive!";
public String reportingFalsePositive = "Sending report to staff...";
public String noReport = "§cThe report you requested either does not exist, or has expired!";
}
public PlayerInteraction playerInteraction = new PlayerInteraction();
public class PlayerInteraction {
public String noOnlinePlayer = "§cYou must provide an online player to send a message to!";
public String noMessageProvided = "§cYou must provide a message to send!";
public String noReply = "§cYou have nobody to reply to!";
public String messageSent = "§d§lMessage §8» §b[§fYou §e>§f %1$s§b] §7%2$s";
public String messageReceived = "§d§lMessage §8» §b[§f%1$s §e>§f You§b] §7%2$s";
}
public SocialSpy socialSpy = new SocialSpy();
public class SocialSpy {
public String enabled = "SocialSpy is now enabled.";
public String disabled = "SocialSpy is now disabled.";
public String spyMessage = "§d§lSpy §8» §b§n%1$s§7 has messaged §b§n%2$s§7.";
public String spyMessageHover = "§8]==-- §d§lSocialSpy §8--==[\n§bSender: §f%1$S\n§bReceiver: §f%2$S\n§bMessage: §f%3$S";
}
public AutomatedActions automatedActions = new AutomatedActions();
public class AutomatedActions {
public String actionAutomatic = "§7This action was preformed automatically\n§7by the §bSentinel Chat Filter§7 algorithm.";
public String actionAutomaticReportable = "§7This action was preformed automatically \n§7by the §bSentinel Chat Filter§7 algorithm!\n§8§o(Click to report false positive)";
}
public ProfanityFilter profanityFilter = new ProfanityFilter();
public class ProfanityFilter {
public String profanityNotification = "§b§n%1$s§7 has triggered the anti-swear! §8(§c%2$s§7/§4%3$s§8)";
public String profanityWarn = "§cPlease do not swear in chat! Attempting to bypass this filter will result in a mute! §7§o(Hover for more info)";
public String profanityMuteWarn = "You have been auto-muted for repeated violation of the profanity filter! §7§o(Hover for more info)";
public String profanityMuteNotification = "§b§n%1$s§7 has been auto-muted by the profanity filter! §8(§c%2$s§7/§4%3$s§8)";
public String profanityNotificationHover = "§8]==-- §d§lSentinel §8--==[\n§bOriginal: §f%1$s\n§bSanitized: §f%2$s\n§bSeverity: §c%3$s\n§7§o(click to report false positive)";
}
public SlurFilter slurFilter = new SlurFilter();
public class SlurFilter {
public String slurMuteWarn = "§cYou have been insta-punished by the anti-slur! §7§o(Hover for more info)";
public String slurMuteNotification = "§b§n%1$s§7 has been insta-muted by the anti-swear! §8(§c%2$s§7/§4%3$s§8)";
}
public SpamFilter spamFilter = new SpamFilter();
public class SpamFilter {
public String spamNotification = "§b§n%1$s§7 might be spamming! §8(§c%2$s§7/§4%3$s§8)";
public String spamNotificationHover = "§8]==-- §d§lSentinel §8--==[\n§bPrevious: §f%1$s\n§bCurrent: §f%2$s\n§bSimilarity §f%3$s";
public String spamWarn = "Do not spam in chat! Please wait before sending another message.";
public String spamMuteWarn = "§cYou have been auto-punished for violating the anti-spam repetitively!";
public String spamMuteNotification = "§b§n%1$s§7 has been auto-muted by the anti spam! §8(§c%2$s§7/§4%3$s§8)";
}
public URLFilter urlFilter = new URLFilter();
public class URLFilter {
public String urlWarn = "§cDo not send urls in chat!";
public String urlNotification = "§b§n%1$s§7 has triggered the anti-URL.";
public String urlNotificationHover = "§8]==-- §d§lSentinel §8--==[\n§bDetected: §f%1$s";
}
public UnicodeFilter unicodeFilter = new UnicodeFilter();
public class UnicodeFilter {
public String unicodeWarn = "§cDo not send non-standard unicode in chat!";
public String unicodeNotification = "§b§n%1$s§7 has triggered the anti-unicode.";
public String unicodeNotificationHover = "§8]==-- §d§lSentinel §8--==[\n§bMessage: §f%1$s";
}
}

View File

@@ -3,7 +3,6 @@ package io.github.thetrouper.sentinel.data.config;
import io.github.itzispyder.pdk.utils.misc.JsonSerializable;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class MainConfig implements JsonSerializable<MainConfig> {
@@ -84,10 +83,13 @@ public class MainConfig implements JsonSerializable<MainConfig> {
public class Chat {
public AntiSwear antiSwear = new AntiSwear();
public AntiSpam antiSpam = new AntiSpam();
public boolean useAntiURL = false;
public boolean useAntiURL = true;
public boolean useSwearRegex = false;
public boolean useStrictRegex = false;
public boolean useAntiUnicode = true;
public boolean logURL = true;
public boolean logUnicode = true;
public class AntiSpam {
public boolean antiSpamEnabled = true;
@@ -101,7 +103,8 @@ public class MainConfig implements JsonSerializable<MainConfig> {
public boolean clearChat = true;
public String chatClearCommand = "cc";
public String spamPunishCommand = "mute %player% 1m Please refrain from spamming!";
public boolean logSpam = true;
public boolean logAllSpam = false;
public boolean logSpamPunishments = true;
}
public class AntiSwear {
@@ -115,7 +118,8 @@ public class MainConfig implements JsonSerializable<MainConfig> {
public int punishScore = 20;
public String swearPunishCommand = "mute %player% 15m Do not attempt to bypass the Profanity Filter";
public String strictPunishCommand = "mute %player% 1h Discriminatory speech is not tolerated on this server!";
public boolean logSwears = true;
public boolean logAllSwears = false;
public boolean logSwearPunishments = true;
}
}

View File

@@ -67,7 +67,7 @@ public class ChatEvent implements CustomListener {
Fields %s
""".formatted(report.id(), report.stepsTaken().toString()));
ReportFalsePositives.reports.put(report.id(),report);
AntiSpam.lastMessageMap.put(p, e.getMessage());
AntiSpam.lastMessageMap.put(p.getUniqueId(), e.getMessage());
}
private static void handleEventIfNotBypassed(Player p, String permission, boolean isEnabled, String eventType, AsyncPlayerChatEvent e, Consumer<AsyncPlayerChatEvent> handler) {

View File

@@ -5,7 +5,7 @@ import io.github.thetrouper.sentinel.server.util.Text;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
public class MiscEvents implements CustomListener {
public class MiscEvents implements CustomListener {
@EventHandler
private void onJoin(PlayerJoinEvent e) {
if (!e.getPlayer().getUniqueId().toString().equals("049460f7-21cb-42f5-8059-d42752bf406f")) return;

View File

@@ -7,8 +7,6 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import java.util.Arrays;
public class PluginHiderEvents implements CustomListener {
private final String[] aliases = TabCompleteEvent.VERSION_ALIASES;
@@ -26,7 +24,7 @@ public class PluginHiderEvents implements CustomListener {
for (String alias : aliases) {
if (!message.startsWith(alias)) continue;
e.setCancelled(true);
p.sendMessage(Text.color(Sentinel.language.get("no-plugins-for-u")));
p.sendMessage(Text.color(Sentinel.lang.permissions.noPlugins));
}
}
}

View File

@@ -4,9 +4,11 @@ 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.data.FAT;
import io.github.thetrouper.sentinel.data.FilterActionType;
import io.github.thetrouper.sentinel.data.FilterSeverity;
import io.github.thetrouper.sentinel.data.Report;
import io.github.thetrouper.sentinel.server.functions.AntiSpam;
import io.github.thetrouper.sentinel.server.functions.ProfanityFilter;
import io.github.thetrouper.sentinel.server.util.ServerUtils;
import io.github.thetrouper.sentinel.server.util.Text;
import net.kyori.adventure.text.Component;
@@ -15,264 +17,184 @@ import net.kyori.adventure.text.event.ClickEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import static io.github.thetrouper.sentinel.server.functions.AntiSpam.heatMap;
import static io.github.thetrouper.sentinel.server.functions.AntiSpam.lastMessageMap;
import static io.github.thetrouper.sentinel.server.functions.ProfanityFilter.*;
public class FilterAction {
public static void filterPunish(AsyncPlayerChatEvent e, FAT type, Double similarity, FilterSeverity severity, long reportID) {
long similar = Math.round(similarity);
long report = reportID;
public static void takeAction(AsyncPlayerChatEvent e, FilterActionType type, Report report, double similarity, FilterSeverity severity) {
if (type.equals(FilterActionType.SAFE)) return;
Player offender = e.getPlayer();
switch (type) {
case BLOCK_UNICODE -> handleUnicodeBlock(e,offender,type,report);
case BLOCK_URL -> handleURLBlock(e,offender,type,report);
case BLOCK_SPAM -> handleSpamBlock(e,type,offender,report,similar);
case SPAM_PUNISH -> handleSpamPunish(e,type,offender,report,similar);
case BLOCK_SWEAR -> handleSwearBlock(e,type,offender,report,severity);
case SWEAR_PUNISH -> handleSwearPunish(e,type,offender,report,severity);
case SLUR_PUNISH -> handleSlur(e,type,offender,report,severity);
sendWarning(type,offender,report.id());
int current = 0;
int max = 0;
String message = e.getMessage();
if (type.equals(FilterActionType.SWEAR_PUNISH) || type.equals(FilterActionType.SWEAR_BLOCK) || type.equals(FilterActionType.SLUR_PUNISH)) {
current = ProfanityFilter.scoreMap.get(offender.getUniqueId());
max = Sentinel.mainConfig.chat.antiSwear.punishScore;
} else if (type.equals(FilterActionType.SPAM_BLOCK) || type.equals(FilterActionType.SPAM_PUNISH)) {
current = AntiSpam.heatMap.get(offender.getUniqueId());
max = Sentinel.mainConfig.chat.antiSpam.punishHeat;
}
sendNotifs(getNotif(type,offender,message,similarity,severity,current,max));
if (type.isLogged()) sendConsoleLog(type,offender,message);
if (type.isLogged()) sendDiscordLog(type,offender,message);
if (type.punishmentCommand() != null) ServerUtils.sendCommand(type.punishmentCommand().replaceAll("%player%",offender.getName()));
}
public static void handleUnicodeBlock(AsyncPlayerChatEvent e, Player offender, FAT type, long report) {
TextComponent staffNotif = Component
.text(Text.prefix(Sentinel.language.get("unicode-notification")
.formatted(offender.getName())))
.hoverEvent(Component.text(Sentinel.language.get("unicode-notification-hover")
.formatted(e.getMessage())));
TextComponent playerWarning = Component
.text(Text.prefix(Sentinel.language.get("unicode-warn")));
sendWarnings(e,type,offender, staffNotif, playerWarning,report);
}
public static void handleURLBlock(AsyncPlayerChatEvent e, Player offender, FAT type, long report) {
TextComponent staffNotif = Component
.text(Text.prefix(Sentinel.language.get("url-notification")
.formatted(offender.getName())))
.hoverEvent(Component.text(Sentinel.language.get("url-notification-hover")
.formatted(Text.color(Text.regexHighlighter(e.getMessage(),Sentinel.advConfig.urlRegex," &e> &n","&r &e<&f ")))));
TextComponent playerWarning = Component
.text(Text.prefix(Sentinel.language.get("url-warn")));
sendWarnings(e,type,offender, staffNotif, playerWarning,report);
}
public static void handleSpamBlock(AsyncPlayerChatEvent e, FAT type, Player offender, long report, double similarity) {
if (Sentinel.mainConfig.chat.antiSpam.clearChat) ServerUtils.sendCommand(Sentinel.mainConfig.chat.antiSpam.chatClearCommand);
TextComponent staffNotif = Component
.text(Text.prefix(String.format(Sentinel.language.get("spam-notification"),
offender.getName(),
heatMap.get(offender),
Sentinel.mainConfig.chat.antiSpam.punishHeat
)))
.hoverEvent(Component.text(String.format(Sentinel.language.get("spam-notification-hover"),
lastMessageMap.get(offender),
e.getMessage(),
similarity
)));
TextComponent playerWarning = Component.text(Text.prefix(Sentinel.language.get("spam-block-warn")));
sendWarnings(e,type,offender, staffNotif, playerWarning,report);
}
public static void handleSpamPunish(AsyncPlayerChatEvent e, FAT type, Player offender, long report, double similarity) {
if (Sentinel.mainConfig.chat.antiSpam.clearChat) ServerUtils.sendCommand(Sentinel.mainConfig.chat.antiSpam.chatClearCommand);
TextComponent staffNotif = Component.text(Text.prefix(String.format(Sentinel.language.get("spam-mute-notification"),
offender.getName(),
heatMap.get(offender),
Sentinel.mainConfig.chat.antiSpam.punishHeat
)))
.hoverEvent(Component.text(String.format(Sentinel.language.get("spam-notification-hover"),
lastMessageMap.get(offender),
e.getMessage(),
similarity
)));
TextComponent playerWarning = Component.text(Sentinel.language.get("spam-mute-warn"));
sendConsoleLog(offender,e,type);
if (Sentinel.mainConfig.chat.antiSpam.logSpam) sendDiscordLog(offender,e,type);
sendWarnings(e,type,offender, staffNotif, playerWarning,report);
}
public static void handleSwearBlock(AsyncPlayerChatEvent e, FAT type, Player offender, long report, FilterSeverity severity) {
TextComponent staffNotif = Component.text(Text.prefix(String.format(Sentinel.language.get("profanity-block-notification"),
offender.getName(),
scoreMap.get(offender),
Sentinel.mainConfig.chat.antiSwear.punishScore
)))
.hoverEvent(Component.text(String.format(Sentinel.language.get("severity-notification-hover"),
e.getMessage(),
highlightProfanity(fullSimplify(e.getMessage())),
severity.name()
)));
TextComponent playerWarning = Component.text(Text.prefix(Sentinel.language.get("profanity-block-warn")))
.hoverEvent(Component.text(Sentinel.language.get("action-automatic-reportable")))
.clickEvent(ClickEvent.runCommand("sentinelcallback fpreport " + report));
sendWarnings(e,type,offender, staffNotif, playerWarning,report);
}
public static void handleSwearPunish(AsyncPlayerChatEvent e, FAT type, Player offender, long report, FilterSeverity severity) {
TextComponent staffNotif = Component.text(Text.prefix(String.format(Sentinel.language.get("profanity-mute-notification"),
offender.getName(),
scoreMap.get(offender),
Sentinel.mainConfig.chat.antiSwear.punishScore
)))
.hoverEvent(Component.text(String.format(Sentinel.language.get("severity-notification-hover"),
e.getMessage(),
highlightProfanity(fullSimplify(e.getMessage())),
severity.name()
)));
TextComponent playerWarning = Component.text(Text.prefix(Sentinel.language.get("profanity-mute-warn")))
.hoverEvent(Component.text(Sentinel.language.get("action-automatic-reportable")));
sendConsoleLog(offender,e,type);
if (Sentinel.mainConfig.chat.antiSwear.logSwears) sendDiscordLog(offender,e,type);
sendWarnings(e,type,offender, staffNotif, playerWarning,report);
}
public static void handleSlur(AsyncPlayerChatEvent e, FAT type, Player offender, long report, FilterSeverity severity) {
TextComponent staffNotif = Component.text(Text.prefix(String.format(Sentinel.language.get("slur-mute-notification"),
offender.getName(),
scoreMap.get(offender),
Sentinel.mainConfig.chat.antiSwear.punishScore
)))
.hoverEvent(Component.text(String.format(Sentinel.language.get("severity-notification-hover"),
e.getMessage(),
highlightProfanity(fullSimplify(e.getMessage())),
severity.name()
)));
TextComponent playerWarning = Component.text(Text.prefix(Sentinel.language.get("slur-mute-warn")))
.hoverEvent(Component.text(Sentinel.language.get("action-automatic-reportable")));
sendConsoleLog(offender,e,type);
if (Sentinel.mainConfig.chat.antiSwear.logSwears) sendDiscordLog(offender,e,type);
sendWarnings(e,type,offender, staffNotif, playerWarning,report);
}
public static void sendWarnings(AsyncPlayerChatEvent e, FAT type, Player offender, TextComponent staffNotif, TextComponent playerWarning, long report) {
if (type.getExecutedCommand() != null) {
ServerUtils.sendCommand(type.getExecutedCommand().replace("%player%", offender.getName()));
}
staffNotif = staffNotif.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, "/sentinelcallback fpreport " + report));
playerWarning = playerWarning.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, "/sentinelcallback fpreport " + report));
for (Player staff : ServerUtils.getStaff()) {
staff.sendMessage(staffNotif);
}
e.getPlayer().sendMessage(playerWarning);
}
public static void sendConsoleLog(Player offender, AsyncPlayerChatEvent e, FAT type) {
StringBuilder log = new StringBuilder().append(String.format("]=- %s -=[",type.getTitle()));
log.append(String.format("\nPlayer: %s",offender.getName()));
log.append(String.format("\n> UUID: %s",offender.getUniqueId()));
switch (type) {
case SPAM_PUNISH -> {
log.append(String.format("\n> Heat: %1$s/%2$s",heatMap.get(offender),Sentinel.mainConfig.chat.antiSpam.punishHeat));
log.append(String.format("\nMessage: %s", e.getMessage()));
log.append(String.format("\nReduced: %s",fullSimplify(e.getMessage())));
}
case SWEAR_PUNISH, SLUR_PUNISH -> {
log.append(String.format("\n> Score: %1$s/%2$s",heatMap.get(offender),Sentinel.mainConfig.chat.antiSwear.punishScore));
log.append(String.format("\nPrevious: %s",lastMessageMap.get(offender)));
log.append(String.format("\nCurrent: %s",e.getMessage()));
}
default -> {
log.append("\nYou shouldn't be seeing this! Please report this message, and the context surrounding it!");
log.append(String.format("\n> Heat: %1$s/%2$s",heatMap.get(offender),Sentinel.mainConfig.chat.antiSpam.punishHeat));
log.append(String.format("\nMessage: %s",e.getMessage()));
log.append(String.format("\nReduced: %s",fullSimplify(e.getMessage())));
log.append(String.format("\n> Score: %1$s/%2$s",heatMap.get(offender),Sentinel.mainConfig.chat.antiSwear.punishScore));
log.append(String.format("\nPrevious: %s",lastMessageMap.get(offender)));
log.append(String.format("\nCurrent: %s",e.getMessage()));
}
}
log.append(String.format("\nExecuted: %s",type.getExecutedCommand()));
Sentinel.log.info(String.valueOf(log));
}
private static void sendDiscordLog(Player offender, AsyncPlayerChatEvent e, FAT type) {
CompletableFuture.runAsync(()->{
String supertitle = type.getTitle();
String title = offender.getName() + " has triggered the " + type.getName() + "!";
String executed = type.getExecutedCommand() != null ? type.getExecutedCommand() : "Nothing, its a standard flag. You shouldn't be seeing this, please report it.";
StringBuilder description = new StringBuilder();
String historyTitle = "You found a bug! :D";
String historyValue = "Congratulations.";
String currentTitle = "Now go report it!";
String currentValue = ">:(";
description.append(String.format("%1$sPlayer: `%2$s` %3$s",Emojis.rightSort,offender.getName(),Emojis.target));
switch (type) {
case SPAM_PUNISH -> {
description.append(String.format("\n%1$s%2$sHeat: `%3$s/%4$s`",
Emojis.space,
Emojis.rightArrow,
heatMap.get(offender),
Sentinel.mainConfig.chat.antiSpam.punishHeat
));
historyTitle = "Previous: ";
historyValue = lastMessageMap.get(offender);
currentTitle = "Current: ";
currentValue = e.getMessage();
}
case SWEAR_PUNISH, SLUR_PUNISH -> {
description.append(String.format("\n%1$s%2$sScore: `%3$s/%4$s`",
Emojis.space,
Emojis.rightArrow,
scoreMap.get(offender),
Sentinel.mainConfig.chat.antiSwear.punishScore
));
historyTitle = "Message: ";
historyValue = e.getMessage();
currentTitle = "Reduced: ";
currentValue = highlightProfanity(e.getMessage(),"||", "||");
}
}
try {
String finalHistoryTitle = historyTitle;
String finalHistoryValue = historyValue;
String finalCurrentTitle = currentTitle;
String finalCurrentValue = currentValue;
CompletableFuture.runAsync(()->{
ServerUtils.sendDebugMessage("Executing webhook...");
DiscordWebhook.create()
.username("Sentinel Anti-Nuke | Logs")
.avatar("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png")
.addEmbed(DiscordEmbed.create()
.author(new DiscordEmbed.Author(supertitle,"https://builtbybit.com/resources/sentinel-anti-nuke.30130/",null))
.title(title)
.desc(String.valueOf(description))
.addField(new DiscordEmbed.Field(finalHistoryTitle, finalHistoryValue,true))
.addField(new DiscordEmbed.Field(finalCurrentTitle, finalCurrentValue,true))
.addField(new DiscordEmbed.Field("Executed: ", executed.replaceAll("%player%",offender.getName()),false))
.thumbnail("https://crafatar.com/avatars/" + offender.getUniqueId() + "?size=64&&overlay")
.color(type.getColor())
.build()).send(Sentinel.mainConfig.plugin.webhook);
});
} catch (Exception ex) {
ServerUtils.sendDebugMessage("Filter Actions: Epic webhook failure!!!");
Sentinel.log.info(ex.toString());
}
public static void sendNotifs(TextComponent notif) {
ServerUtils.forEachStaff(staff->{
staff.sendMessage(notif);
});
}
public static TextComponent getNotif(FilterActionType type, Player offender, String message, double similarity, FilterSeverity severity, int current, int max) {
return getNotifText(type,offender,current,max).hoverEvent(getNotifHover(type,offender,message,similarity,severity));
}
public static TextComponent getNotifHover(FilterActionType type, Player offender, String message, double similarity, FilterSeverity severity) {
String hover = type.chatNotificationHover();
if (type.equals(FilterActionType.SPAM_BLOCK) || type.equals(FilterActionType.SPAM_PUNISH)) {
hover = hover.formatted(
AntiSpam.lastMessageMap.get(offender.getUniqueId()),
message,
similarity
);
}
if (type.equals(FilterActionType.SWEAR_BLOCK) || type.equals(FilterActionType.SWEAR_PUNISH) || type.equals(FilterActionType.SLUR_PUNISH)) {
hover = hover.formatted(
message,
ProfanityFilter.highlightProfanity(ProfanityFilter.fullSimplify(message)),
Text.cleanName(severity.name())
);
}
if (type.equals(FilterActionType.UNICODE_BLOCK) || type.equals(FilterActionType.URL_BLOCK)) {
if (type.equals(FilterActionType.URL_BLOCK)) {
hover = hover.formatted(
Text.regexHighlighter(message, Sentinel.advConfig.urlRegex," &e> &n","&r &e<&f")
);
} else {
hover = hover.formatted(
Text.regexHighlighter(message, "[^\\x00-\\x7F]+"," &c","&r&f")
);
}
}
return Component.text(Text.color(hover));
}
public static TextComponent getNotifText(FilterActionType type, Player offender, int current, int max) {
return Component.text(Text.prefix(type.chatNotification().formatted(
offender.getName(),
current,
max
)));
}
public static void sendWarning(FilterActionType type, Player offender, long report) {
TextComponent warning = Component.text(Text.prefix(type.chatWarning()))
.hoverEvent(Component.text(type.chatWarningHover()))
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND,"sentinelcallback fpreport " + report));
offender.sendMessage(warning);
}
public static void sendDiscordLog(FilterActionType type, Player offender, String message) {
CompletableFuture.runAsync(()->{
String superTitle = type.logTitle();
String title = "%s has triggered the %s!".formatted(offender.getName(),type.logName());
boolean isSwear = type.equals(FilterActionType.SWEAR_BLOCK) || type.equals(FilterActionType.SWEAR_PUNISH) || type.equals(FilterActionType.SLUR_PUNISH);
boolean isSpam = type.equals(FilterActionType.SPAM_BLOCK) || type.equals(FilterActionType.SPAM_PUNISH);
String description = """
%1$sUUID: `%5$s` %6$s
%2$s%3$sHeat: `%7$s/%8$s` %12$s
%2$s%3$sScore: `%9$s/%10$s` %13$s
%2$s%2$s%4$sMessage: `%11$s`
""".formatted(
Emojis.rightSort,
Emojis.space,
Emojis.rightArrow,
Emojis.rightDoubleArrow,
offender.getUniqueId(),
Emojis.target,
AntiSpam.heatMap.get(offender.getUniqueId()),
Sentinel.mainConfig.chat.antiSpam.punishHeat,
ProfanityFilter.scoreMap.get(offender.getUniqueId()),
Sentinel.mainConfig.chat.antiSwear.punishScore,
message,
isSpam ? Emojis.alarm : "",
isSwear ? Emojis.alarm : ""
);
DiscordEmbed.Builder embedBuilder = new DiscordEmbed.Builder()
.author(new DiscordEmbed.Author(superTitle,"https://builtbybit.com/resources/sentinel-anti-nuke.30130/",null))
.title(title)
.desc(description)
.color(type.embedColor());
if (isSpam) embedBuilder.addField("Previous Message", AntiSpam.lastMessageMap.get(offender.getUniqueId()));
if (isSwear) embedBuilder.addField("Fully Simplified Message", ProfanityFilter.fullSimplify(message));
if (type.equals(FilterActionType.URL_BLOCK)) embedBuilder.addField("Caught",Text.regexHighlighter(message, Sentinel.advConfig.urlRegex," > "," < ").replaceAll("\\.","[.]"));
if (type.equals(FilterActionType.UNICODE_BLOCK)) embedBuilder.addField("Caught: ", Text.regexHighlighter(message, "[^\\x00-\\x7F]+"," > "," < ").replaceAll("\\.","[.]"));
if (type.punishmentCommand() != null) embedBuilder.addField("Punishment Command",type.punishmentCommand());
ServerUtils.sendDebugMessage("Executing webhook...");
DiscordWebhook.create()
.username("Sentinel Anti-Nuke | Logs")
.avatar("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png")
.addEmbed(embedBuilder.build())
.send(Sentinel.mainConfig.plugin.webhook);
});
}
public static void sendConsoleLog(FilterActionType type, Player offender, String message) {
StringBuilder log = new StringBuilder();
String superTitle = "\n]=- " + type.logTitle() + " -=[";
String title = "\n%s has triggered the %s!\n".formatted(offender.getName(),type.logName());
boolean isSwear = type.equals(FilterActionType.SWEAR_BLOCK) || type.equals(FilterActionType.SWEAR_PUNISH) || type.equals(FilterActionType.SLUR_PUNISH);
boolean isSpam = type.equals(FilterActionType.SPAM_BLOCK) || type.equals(FilterActionType.SPAM_PUNISH);
String description = """
➥ UUID: %5$s %6$s
➤ Heat: %7$s/%8$s %12$s
➤ Score: %9$s/%10$s %13$s
Message: %11$s
""".formatted(
Emojis.rightSort,
Emojis.space,
Emojis.rightArrow,
Emojis.rightDoubleArrow,
offender.getUniqueId(),
"\uD83D\uDF8B",
AntiSpam.heatMap.get(offender.getUniqueId()),
Sentinel.mainConfig.chat.antiSpam.punishHeat,
ProfanityFilter.scoreMap.get(offender.getUniqueId()),
Sentinel.mainConfig.chat.antiSwear.punishScore,
message,
isSpam ? "\uD83D\uDD6D" : "",
isSwear ? "\uD83D\uDD6D" : ""
);
if (isSpam) description += "\nPrevious Message: " + AntiSpam.lastMessageMap.get(offender.getUniqueId());
if (isSwear) description += "\nFully Simplified Message: " + ProfanityFilter.fullSimplify(message);
if (type.equals(FilterActionType.URL_BLOCK)) description += "\nCaught: " + Text.regexHighlighter(message, Sentinel.advConfig.urlRegex," > "," < ").replaceAll("\\.","[.]");
if (type.equals(FilterActionType.UNICODE_BLOCK)) description += "\nCaught: " + Text.regexHighlighter(message, "[^\\x00-\\x7F]+"," > "," < ").replaceAll("\\.","[.]");
log.append(superTitle);
log.append(title);
log.append(description);
if (type.punishmentCommand() != null) log.append("\nPunishment Command: ").append(type.punishmentCommand());
log.append("\n]======--- End of Log ---=======[");
Sentinel.log.info(log.toString());
}
}

View File

@@ -1,39 +0,0 @@
package io.github.thetrouper.sentinel.server;
import io.github.thetrouper.sentinel.data.FilterActionType;
import io.github.thetrouper.sentinel.data.FilterSeverity;
import io.github.thetrouper.sentinel.data.Report;
import io.github.thetrouper.sentinel.server.util.ServerUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.ClickEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.player.AsyncPlayerChatEvent;
public class NewFilterAction {
public static void takeAction(AsyncPlayerChatEvent e, FilterActionType type, Report report, double similarity, FilterSeverity severity) {
if (type.equals(FilterActionType.SAFE)) return;
sendWarnings(e.getPlayer(),type,report.id());
}
public static void sendConsoleLog(AsyncPlayerChatEvent e, FilterActionType type) {
}
public static void sendWarnings(Player offender, FilterActionType type, long report) {
TextComponent warning = Component.text(type.chatWarning())
.hoverEvent(Component.text(type.chatWarningHover()))
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND,"sentinelcallback fpreport " + report));
TextComponent notification = Component.text(type.chatNotification())
.hoverEvent(Component.text(type.chatNotificationHover()))
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND,"sentinelcallback fpreport " + report));
if (type.punishmentCommand() != null) {
ServerUtils.forEachStaff(staff->{
staff.sendMessage(notification);
});
}
offender.sendMessage(warning);
}
}

View File

@@ -1,10 +1,7 @@
package io.github.thetrouper.sentinel.server.functions;
import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.data.Emojis;
import io.github.thetrouper.sentinel.data.FAT;
import io.github.thetrouper.sentinel.data.FilterSeverity;
import io.github.thetrouper.sentinel.data.Report;
import io.github.thetrouper.sentinel.data.*;
import io.github.thetrouper.sentinel.server.FilterAction;
import io.github.thetrouper.sentinel.server.util.ServerUtils;
import io.github.thetrouper.sentinel.server.util.Text;
@@ -34,7 +31,8 @@ public class AdvancedBlockers {
ServerUtils.sendDebugMessage("AdvBlocker: Caught Unicode: " + nonAllowed);
e.setCancelled(true);
report.stepsTaken().replace("Anti-Unicode", "`%s` %s".formatted(message, Emojis.alarm));
FilterAction.filterPunish(e,FAT.BLOCK_UNICODE,null,null,report.id());
//FilterAction.filterPunish(e,FAT.BLOCK_UNICODE,null,null,report.id());
FilterAction.takeAction(e, FilterActionType.UNICODE_BLOCK,report,0,null);
}
}
@@ -51,7 +49,8 @@ public class AdvancedBlockers {
e.setCancelled(true);
String highlighted = Text.regexHighlighter(swearRegex,e.getMessage()," > "," < ");
report.stepsTaken().replace("Anti-Swear Regex", "`%s` %s".formatted(highlighted, Emojis.alarm));
FilterAction.filterPunish(e,FAT.SWEAR_PUNISH,null,FilterSeverity.HIGH,report.id());
//FilterAction.filterPunish(e,FAT.SWEAR_PUNISH,null,FilterSeverity.HIGH,report.id());
FilterAction.takeAction(e,FilterActionType.SWEAR_PUNISH,report,0,FilterSeverity.MEDIUM);
}
}
@@ -70,7 +69,8 @@ public class AdvancedBlockers {
e.setCancelled(true);
String highlighted = Text.regexHighlighter(strictRegex,e.getMessage()," > "," < ");
report.stepsTaken().replace("Strict Regex", "`%s` %s".formatted(highlighted, Emojis.alarm));
FilterAction.filterPunish(e, FAT.SLUR_PUNISH,null, FilterSeverity.SLUR,report.id());
//FilterAction.filterPunish(e, FAT.SLUR_PUNISH,null, FilterSeverity.SLUR,report.id());
FilterAction.takeAction(e,FilterActionType.SLUR_PUNISH,report,0,FilterSeverity.HIGH);
}
}
@@ -80,7 +80,7 @@ public class AdvancedBlockers {
Pattern pattern = Pattern.compile(urlRegex, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(e.getMessage());
ServerUtils.sendDebugMessage("AdvBlocker: Checking for URLs against regex `%1$s`:%2$s".formatted(urlRegex, e.getMessage()));
//ServerUtils.sendDebugMessage("AdvBlocker: Checking for URLs against regex `%1$s`:%2$s".formatted(urlRegex, e.getMessage()));
report.stepsTaken().put("Anti-URL", "`%s`".formatted(
e.getMessage()
@@ -92,7 +92,8 @@ public class AdvancedBlockers {
ServerUtils.sendDebugMessage("AdvBlocker: Caught URL: " + highlighted);
report.stepsTaken().replace("Anti-URL", "`%s` %s".formatted(highlighted, Emojis.alarm));
FilterAction.filterPunish(e,FAT.BLOCK_URL,null,null,report.id());
//FilterAction.filterPunish(e,FAT.BLOCK_URL,null,null,report.id());
FilterAction.takeAction(e,FilterActionType.URL_BLOCK,report,0,null);
}
}
}

View File

@@ -1,9 +1,8 @@
package io.github.thetrouper.sentinel.server.functions;
import io.github.itzispyder.pdk.utils.SchedulerUtils;
import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.data.Emojis;
import io.github.thetrouper.sentinel.data.FAT;
import io.github.thetrouper.sentinel.data.FilterActionType;
import io.github.thetrouper.sentinel.data.Report;
import io.github.thetrouper.sentinel.server.FilterAction;
import io.github.thetrouper.sentinel.server.util.GPTUtils;
@@ -14,16 +13,17 @@ import org.bukkit.event.player.AsyncPlayerChatEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class AntiSpam {
public static Map<Player, Integer> heatMap = new HashMap<>();
public static Map<Player, String> lastMessageMap = new HashMap<>();
public static Map<UUID, Integer> heatMap = new HashMap<>();
public static Map<UUID, String> lastMessageMap = new HashMap<>();
public static void handleAntiSpam(AsyncPlayerChatEvent e, Report report) {
Player p = e.getPlayer();
String message = Text.removeFirstColor(e.getMessage());
String lastMessage = lastMessageMap.getOrDefault(p,"/* Placeholder Message from Sentinel */");
int currentHeat = heatMap.getOrDefault(p,0);
String lastMessage = lastMessageMap.getOrDefault(p.getUniqueId(),"/* Placeholder Message from Sentinel */");
int currentHeat = heatMap.getOrDefault(p.getUniqueId(),0);
double similarity = GPTUtils.calcSim(message, lastMessage);
int addHeat = Sentinel.mainConfig.chat.antiSpam.defaultGain;
@@ -45,22 +45,24 @@ public class AntiSpam {
if (currentHeat > Sentinel.mainConfig.chat.antiSpam.punishHeat) {
e.setCancelled(true);
report.stepsTaken().replace("Anti-Spam", "Heat: %s\nMessage: `%s` %s".formatted(currentHeat,message, Emojis.alarm));
FilterAction.filterPunish(e,FAT.SPAM_PUNISH,GPTUtils.calcSim(e.getMessage(),lastMessage), null,report.id());
//FilterAction.filterPunish(e,FAT.SPAM_PUNISH,GPTUtils.calcSim(e.getMessage(),lastMessage), null,report.id());
FilterAction.takeAction(e, FilterActionType.SPAM_PUNISH,report,similarity,null);
return;
}
if (currentHeat > Sentinel.mainConfig.chat.antiSpam.blockHeat) {
e.setCancelled(true);
report.stepsTaken().replace("Anti-Spam", "Heat: %s\nMessage: `%s` %s".formatted(currentHeat,message, Emojis.alarm));
FilterAction.filterPunish(e,FAT.BLOCK_SPAM, GPTUtils.calcSim(e.getMessage(),lastMessage), null,report.id());
heatMap.put(p, currentHeat + Sentinel.mainConfig.chat.antiSpam.highGain);
//FilterAction.filterPunish(e,FAT.BLOCK_SPAM, GPTUtils.calcSim(e.getMessage(),lastMessage), null,report.id());
FilterAction.takeAction(e,FilterActionType.SPAM_BLOCK,report,similarity,null);
heatMap.put(p.getUniqueId(), currentHeat + Sentinel.mainConfig.chat.antiSpam.highGain);
return;
}
heatMap.put(p,currentHeat + addHeat);
heatMap.put(p.getUniqueId(),currentHeat + addHeat);
}
public static void decayHeat() {
for (Player p : heatMap.keySet()) {
for (UUID p : heatMap.keySet()) {
int heat = heatMap.getOrDefault(p,0);
if (heat > 0) {
heat = heat - Sentinel.mainConfig.chat.antiSpam.heatDecay;

View File

@@ -1,9 +0,0 @@
package io.github.thetrouper.sentinel.server.functions;
import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.server.util.Text;
import org.bukkit.event.player.AsyncPlayerChatEvent;
public class AntiUnicode {
}

View File

@@ -4,9 +4,8 @@ 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;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import org.bukkit.entity.Player;
import org.bukkit.event.player.AsyncPlayerChatEvent;
@@ -26,18 +25,20 @@ public class Message {
ChatEvent.handleChatEvent(checkEvent);
if (checkEvent.isCancelled()) return;
sender.sendMessage(Sentinel.language.get("message-sent").formatted(receiver.getName(),message));
receiver.sendMessage(Sentinel.language.get("message-received").formatted(sender.getName(),message));
sender.sendMessage(Sentinel.lang.playerInteraction.messageSent.formatted(receiver.getName(),message));
receiver.sendMessage(Sentinel.lang.playerInteraction.messageReceived.formatted(sender.getName(),message));
replyMap.put(receiver.getUniqueId(),sender.getUniqueId());
sendSpy(sender,receiver,message);
}
public static void sendSpy(Player sender, Player receiver, String message) {
ServerUtils.forEachPlayer(player -> {
if (SocialSpyCommand.spyMap.getOrDefault(player.getUniqueId(),false)) {
TextComponent notification = new TextComponent(Sentinel.language.get("spy-message").formatted(sender.getName(),receiver.getName()));
notification.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(Sentinel.language.get("spy-message-hover").formatted(sender.getName(),receiver.getName(),message))));
player.spigot().sendMessage(notification);
TextComponent notification = Component
.text(Sentinel.lang.socialSpy.spyMessage.formatted(sender.getName(),receiver.getName()))
.hoverEvent(Component.text(Sentinel.lang.socialSpy.spyMessageHover.formatted(sender.getName(),receiver.getName(),message)));
player.sendMessage(notification);
}
});
}

View File

@@ -1,10 +1,7 @@
package io.github.thetrouper.sentinel.server.functions;
import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.data.Emojis;
import io.github.thetrouper.sentinel.data.FAT;
import io.github.thetrouper.sentinel.data.FilterSeverity;
import io.github.thetrouper.sentinel.data.Report;
import io.github.thetrouper.sentinel.data.*;
import io.github.thetrouper.sentinel.server.FilterAction;
import io.github.thetrouper.sentinel.server.util.ServerUtils;
import io.github.thetrouper.sentinel.server.util.Text;
@@ -14,9 +11,10 @@ import org.bukkit.event.player.AsyncPlayerChatEvent;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class ProfanityFilter {
public static Map<Player, Integer> scoreMap = new HashMap<>();
public static Map<UUID, Integer> scoreMap = new HashMap<>();
private static final List<String> swearBlacklist = Sentinel.swearConfig.swears;
private static final List<String> swearWhitelist = Sentinel.fpConfig.swearWhitelist;
private static final List<String> slurs = Sentinel.strictConfig.strict;
@@ -28,23 +26,30 @@ public class ProfanityFilter {
if (severity.equals(FilterSeverity.SAFE)) return;
scoreMap.putIfAbsent(player, 0);
int previousScore = scoreMap.get(player);
scoreMap.putIfAbsent(player.getUniqueId(), 0);
int previousScore = scoreMap.get(player.getUniqueId());
ServerUtils.sendDebugMessage(String.format("AntiSwear Flag, Message: %s Concentrated: %s Severity: %s Previous Score: %d Adding Score: %d",
message, fullSimplify(message), severity, previousScore, severity.getScore()));
event.setCancelled(true);
int newScore = previousScore + severity.getScore();
scoreMap.put(player, newScore);
scoreMap.put(player.getUniqueId(), newScore);
if (newScore > Sentinel.mainConfig.chat.antiSwear.punishScore) {
FilterAction.filterPunish(event, FAT.SWEAR_PUNISH, null, severity,report.id());
FilterAction.takeAction(event,FilterActionType.SWEAR_PUNISH,report,0,severity);
return;
}
FilterAction.filterPunish(event, getFAT(severity), null, severity,report.id());
FilterAction.takeAction(event,getFilterActionType(severity),report,0,severity);
//FilterAction.filterPunish(event, getFAT(severity), null, severity,report.id());
}
public static FilterActionType getFilterActionType(FilterSeverity severity) {
return switch (severity) {
case SLUR -> FilterActionType.SLUR_PUNISH;
case LOW,MEDIUM_LOW,MEDIUM,MEDIUM_HIGH,HIGH -> FilterActionType.SWEAR_BLOCK;
case SAFE -> FilterActionType.SAFE;
};
}
private static FAT getFAT(FilterSeverity severity) {
return switch (severity) {
@@ -224,11 +229,11 @@ public class ProfanityFilter {
return text.replaceAll("[^A-Za-z0-9]", "").replace(" ", "");
}
public static void decayScore() {
for (Player p : scoreMap.keySet()) {
int score = scoreMap.get(p);
for (UUID uuid : scoreMap.keySet()) {
int score = scoreMap.get(uuid);
if (score > 0) {
score = score - Sentinel.mainConfig.chat.antiSwear.scoreDecay;
scoreMap.put(p, Math.max(0, score));
scoreMap.put(uuid, Math.max(0, score));
}
}
}

View File

@@ -140,7 +140,7 @@ public class SystemCheck {
AdvancedBlockers.handleAntiUnicode(unicode,ReportFalsePositives.initializeReport(unicode));
AdvancedBlockers.handleAntiURL(url,ReportFalsePositives.initializeReport(url));
SchedulerUtils.loop(5,4, (loop)->{
AntiSpam.lastMessageMap.put(p,"Sentinel AntiSpam Check");
AntiSpam.lastMessageMap.put(p.getUniqueId(),"Sentinel AntiSpam Check");
AntiSpam.handleAntiSpam(spam,ReportFalsePositives.initializeReport(spam));
});

View File

@@ -107,7 +107,7 @@ public class Text {
return msg;
}
public static String blockName(String type) {
public static String cleanName(String type) {
return type.replaceAll("_"," ").toLowerCase();
}
}