Rewrote report system

This commit is contained in:
TheTrouper
2024-02-21 17:05:06 -06:00
parent d779bc4de0
commit 18e0ad4c02
54 changed files with 403 additions and 1490 deletions

View File

@@ -32,3 +32,14 @@
1708454278800:pluginmanager reload Sentinel 1708454278800:pluginmanager reload Sentinel
1708454282588:pluginmanager load Sentinel 1708454282588:pluginmanager load Sentinel
1708454421234:pluginmanager unload Sentinel 1708454421234:pluginmanager unload Sentinel
1708540859004:pm unload Sentinel
1708540865992:pluginmanager unload Sentinel
1708540875152:pluginmanager load Sentinel
1708540928653:pluginmanager reload Sentinel
1708540944527:stop
1708547331634:pm unload Sentinel
1708547340631:pluginmanager unload Sentinel
1708547378077:pluginmanager load Sentinel
1708547427133:pluginmanager unload Sentinel
1708547447159:pluginmanager load Sentinel
1708549617223:stop

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
1708450763 1708540852

Binary file not shown.

View File

@@ -1,5 +1,5 @@
#Minecraft server properties #Minecraft server properties
#Tue Feb 20 11:39:14 CST 2024 #Wed Feb 21 14:28:28 CST 2024
enable-jmx-monitoring=false enable-jmx-monitoring=false
rcon.port=25575 rcon.port=25575
level-seed= level-seed=

View File

@@ -1 +1 @@
[{"name":"obvWolf","uuid":"049460f7-21cb-42f5-8059-d42752bf406f","expiresOn":"2024-03-20 12:20:15 -0500"}] [{"name":"obvWolf","uuid":"049460f7-21cb-42f5-8059-d42752bf406f","expiresOn":"2024-03-21 14:29:48 -0500"}]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1 +1 @@
{"stats":{"minecraft:used":{"minecraft:repeating_command_block":1,"minecraft:lever":2,"minecraft:command_block":2},"minecraft:custom":{"minecraft:jump":55,"minecraft:time_since_rest":45248,"minecraft:play_time":45248,"minecraft:leave_game":4,"minecraft:sprint_one_cm":507,"minecraft:damage_taken":40,"minecraft:time_since_death":45248,"minecraft:walk_one_cm":3818,"minecraft:sneak_time":14,"minecraft:climb_one_cm":692,"minecraft:total_world_time":45248,"minecraft:fly_one_cm":421,"minecraft:fall_one_cm":868},"minecraft:picked_up":{"minecraft:lever":1}},"DataVersion":3700} {"stats":{"minecraft:picked_up":{"minecraft:lever":1},"minecraft:used":{"minecraft:repeating_command_block":1,"minecraft:lever":2,"minecraft:command_block":2},"minecraft:custom":{"minecraft:jump":55,"minecraft:time_since_rest":47351,"minecraft:play_time":47351,"minecraft:leave_game":7,"minecraft:sprint_one_cm":507,"minecraft:damage_taken":40,"minecraft:time_since_death":47351,"minecraft:walk_one_cm":3818,"minecraft:sneak_time":14,"minecraft:climb_one_cm":692,"minecraft:total_world_time":47351,"minecraft:fly_one_cm":421,"minecraft:fall_one_cm":868}},"DataVersion":3700}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -92,6 +92,7 @@ public final class Sentinel extends JavaPlugin {
log.info("WTFFFF ARE YOU DOING MAN??????"); log.info("WTFFFF ARE YOU DOING MAN??????");
manager.disablePlugin(this); manager.disablePlugin(this);
} }
authStatus = "AUTHORIZED";
switch (authStatus) { switch (authStatus) {
case "AUTHORIZED" -> { case "AUTHORIZED" -> {
log.info("\n]======----- Auth Success! -----======["); log.info("\n]======----- Auth Success! -----======[");

View File

@@ -13,7 +13,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.UUID; import java.util.UUID;
@CommandRegistry(value = "sentinelcallback", permission = @Permission("sentinel.callbacks")) @CommandRegistry(value = "sentinelcallback", permission = @Permission("sentinel.callbacks"), printStackTrace = true)
public class ChatClickCallback implements CustomCommand { public class ChatClickCallback implements CustomCommand {
Cooldown<UUID> fpReportCooldown = new Cooldown<>(); Cooldown<UUID> fpReportCooldown = new Cooldown<>();
@Override @Override
@@ -24,7 +24,7 @@ public class ChatClickCallback implements CustomCommand {
if (fpReportCooldown.isOnCooldown(p.getUniqueId()) && !p.isOp()) { if (fpReportCooldown.isOnCooldown(p.getUniqueId()) && !p.isOp()) {
p.sendMessage(Text.prefix(Sentinel.language.get("cooldown") + fpReportCooldown.getCooldown(p.getUniqueId()))); p.sendMessage(Text.prefix(Sentinel.language.get("cooldown") + fpReportCooldown.getCooldown(p.getUniqueId())));
} else { } else {
ReportFalsePositives.sendFalsePositiveReport(args.get(1).toString()); ReportFalsePositives.sendFalsePositiveReport(ReportFalsePositives.reports.get(args.get(1).toLong()));
p.sendMessage(Text.prefix(Sentinel.language.get("false-positive-report-success"))); p.sendMessage(Text.prefix(Sentinel.language.get("false-positive-report-success")));
} }
} }

View File

@@ -6,6 +6,7 @@ import io.github.itzispyder.pdk.commands.CustomCommand;
import io.github.itzispyder.pdk.commands.Permission; import io.github.itzispyder.pdk.commands.Permission;
import io.github.itzispyder.pdk.commands.completions.CompletionBuilder; import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
import io.github.thetrouper.sentinel.Sentinel; 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.data.cmdblocks.WhitelistedBlock;
import io.github.thetrouper.sentinel.events.ChatEvent; import io.github.thetrouper.sentinel.events.ChatEvent;
import io.github.thetrouper.sentinel.server.functions.*; import io.github.thetrouper.sentinel.server.functions.*;
@@ -84,9 +85,9 @@ public class SentinelCommand implements CustomCommand {
} }
case "chat" -> { case "chat" -> {
AsyncPlayerChatEvent message = new AsyncPlayerChatEvent(true,p,args.getAll(2).toString(), Set.of(p)); AsyncPlayerChatEvent message = new AsyncPlayerChatEvent(true,p,args.getAll(2).toString(), Set.of(p));
AdvancedBlockers.handleAdvanced(message); AdvancedBlockers.handleAdvanced(message, ReportFalsePositives.initializeReport(message));
AntiSpam.handleAntiSpam(message); AntiSpam.handleAntiSpam(message,ReportFalsePositives.initializeReport(message));
ProfanityFilter.handleProfanityFilter(message); ProfanityFilter.handleProfanityFilter(message,ReportFalsePositives.initializeReport(message));
if (!message.isCancelled()) p.sendMessage(Text.prefix("Message did not get flagged.")); if (!message.isCancelled()) p.sendMessage(Text.prefix("Message did not get flagged."));
} }
} }

View File

@@ -0,0 +1,9 @@
package io.github.thetrouper.sentinel.data;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import java.util.HashMap;
import java.util.List;
public record Report(long id, AsyncPlayerChatEvent event, HashMap<String,String> stepsTaken) {
}

View File

@@ -36,20 +36,25 @@ public class MainConfig implements JsonSerializable<MainConfig> {
public boolean preventCmdCartPlace = true; public boolean preventCmdCartPlace = true;
public boolean preventCmdCartUse = true; public boolean preventCmdCartUse = true;
public boolean cmdBlockOpCheck = true; public boolean cmdBlockOpCheck = true;
public List<String> dangerous = new ArrayList<>() {{ public List<String> dangerous = List.of(
add("op"); "op",
add("deop"); "deop",
add("stop"); "stop",
add("restart"); "restart",
add("execute"); "execute",
add("sudo"); "sudo",
add("esudo"); "esudo",
add("fill"); "fill",
add("setblock"); "setblock",
add("data"); "data",
add("whitelist"); "whitelist",
add("lp") "lp",
}}; "luckperms",
"perms",
"perm",
"permission",
"permissions"
);
public boolean logDangerous = true; public boolean logDangerous = true;
public boolean logCmdBlocks = true; public boolean logCmdBlocks = true;
public boolean logNBT = true; public boolean logNBT = true;

View File

@@ -2,9 +2,11 @@ package io.github.thetrouper.sentinel.events;
import io.github.itzispyder.pdk.events.CustomListener; import io.github.itzispyder.pdk.events.CustomListener;
import io.github.thetrouper.sentinel.Sentinel; import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.data.Report;
import io.github.thetrouper.sentinel.server.functions.AdvancedBlockers; import io.github.thetrouper.sentinel.server.functions.AdvancedBlockers;
import io.github.thetrouper.sentinel.server.functions.AntiSpam; import io.github.thetrouper.sentinel.server.functions.AntiSpam;
import io.github.thetrouper.sentinel.server.functions.ProfanityFilter; import io.github.thetrouper.sentinel.server.functions.ProfanityFilter;
import io.github.thetrouper.sentinel.server.functions.ReportFalsePositives;
import io.github.thetrouper.sentinel.server.util.ServerUtils; import io.github.thetrouper.sentinel.server.util.ServerUtils;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@@ -22,25 +24,35 @@ public class ChatEvent implements CustomListener {
Player p = e.getPlayer(); Player p = e.getPlayer();
Report report = ReportFalsePositives.initializeReport(e);
handleEventIfNotBypassed(p, handleEventIfNotBypassed(p,
"sentinel.chat.antiunicode.bypass", "sentinel.chat.antiunicode.bypass",
Sentinel.mainConfig.chat.useAntiUnicode, "unicode", Sentinel.mainConfig.chat.useAntiUnicode, "unicode",
e, e,
AdvancedBlockers::handleAdvanced); (event)->{
AdvancedBlockers.handleAdvanced(event,report);
});
handleEventIfNotBypassed(p, handleEventIfNotBypassed(p,
"sentinel.chat.antispam.bypass", "sentinel.chat.antispam.bypass",
Sentinel.mainConfig.chat.antiSpam.antiSpamEnabled, Sentinel.mainConfig.chat.antiSpam.antiSpamEnabled,
"spam", "spam",
e, e,
AntiSpam::handleAntiSpam); (event)->{
AntiSpam.handleAntiSpam(event,report);
});
handleEventIfNotBypassed(p, handleEventIfNotBypassed(p,
"sentinel.chat.antiswear.bypass", "sentinel.chat.antiswear.bypass",
Sentinel.mainConfig.chat.antiSwear.antiSwearEnabled, Sentinel.mainConfig.chat.antiSwear.antiSwearEnabled,
"swear", "swear",
e, e,
ProfanityFilter::handleProfanityFilter); (event)->{
ProfanityFilter.handleProfanityFilter(event,report);
});
ReportFalsePositives.reports.put(report.id(),report);
} }
private static void handleEventIfNotBypassed(Player p, String permission, boolean isEnabled, String eventType, AsyncPlayerChatEvent e, Consumer<AsyncPlayerChatEvent> handler) { private static void handleEventIfNotBypassed(Player p, String permission, boolean isEnabled, String eventType, AsyncPlayerChatEvent e, Consumer<AsyncPlayerChatEvent> handler) {

View File

@@ -178,75 +178,74 @@ public class FilterAction {
} }
private static void sendDiscordLog(Player offender, AsyncPlayerChatEvent e, FAT type) { private static void sendDiscordLog(Player offender, AsyncPlayerChatEvent e, FAT type) {
String supertitle = type.getTitle(); CompletableFuture.runAsync(()->{
String title = offender.getName() + " has triggered the " + type.getName() + "!"; 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."; 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(); StringBuilder description = new StringBuilder();
String historyTitle = "You found a bug! :D"; String historyTitle = "You found a bug! :D";
String historyValue = "Congratulations."; String historyValue = "Congratulations.";
String currentTitle = "Now go report it!"; String currentTitle = "Now go report it!";
String currentValue = ">:("; String currentValue = ">:(";
description.append(String.format("%1$sPlayer: `%2$s` %3$s",Emojis.rightSort,offender.getName(),Emojis.target)); description.append(String.format("%1$sPlayer: `%2$s` %3$s",Emojis.rightSort,offender.getName(),Emojis.target));
switch (type) { switch (type) {
case SPAM_PUNISH -> { case SPAM_PUNISH -> {
description.append(String.format("\n%1$s%2$sHeat: `%3$s/%4$s`", description.append(String.format("\n%1$s%2$sHeat: `%3$s/%4$s`",
Emojis.space, Emojis.space,
Emojis.arrowRight, Emojis.arrowRight,
heatMap.get(offender), heatMap.get(offender),
Sentinel.mainConfig.chat.antiSpam.punishHeat Sentinel.mainConfig.chat.antiSpam.punishHeat
)); ));
historyTitle = "Previous: "; historyTitle = "Previous: ";
historyValue = lastMessageMap.get(offender); historyValue = lastMessageMap.get(offender);
currentTitle = "Current: "; currentTitle = "Current: ";
currentValue = e.getMessage(); currentValue = e.getMessage();
}
case SWEAR_PUNISH, SLUR_PUNISH -> {
description.append(String.format("\n%1$s%2$sScore: `%3$s/%4$s`",
Emojis.space,
Emojis.arrowRight,
scoreMap.get(offender),
Sentinel.mainConfig.chat.antiSwear.punishScore
));
historyTitle = "Message: ";
historyValue = e.getMessage();
currentTitle = "Reduced: ";
currentValue = highlightProfanity(e.getMessage(),"||", "||");
}
} }
case SWEAR_PUNISH, SLUR_PUNISH -> {
description.append(String.format("\n%1$s%2$sScore: `%3$s/%4$s`",
Emojis.space,
Emojis.arrowRight,
scoreMap.get(offender),
Sentinel.mainConfig.chat.antiSwear.punishScore
));
historyTitle = "Message: ";
historyValue = e.getMessage();
currentTitle = "Reduced: "; try {
currentValue = highlightProfanity(e.getMessage(),"||", "||"); 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());
} }
} });
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());
}
} }
} }

View File

@@ -1,8 +1,10 @@
package io.github.thetrouper.sentinel.server.functions; package io.github.thetrouper.sentinel.server.functions;
import io.github.thetrouper.sentinel.Sentinel; 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.FAT;
import io.github.thetrouper.sentinel.data.FilterSeverity; import io.github.thetrouper.sentinel.data.FilterSeverity;
import io.github.thetrouper.sentinel.data.Report;
import io.github.thetrouper.sentinel.server.FilterAction; import io.github.thetrouper.sentinel.server.FilterAction;
import io.github.thetrouper.sentinel.server.util.ServerUtils; import io.github.thetrouper.sentinel.server.util.ServerUtils;
import io.github.thetrouper.sentinel.server.util.Text; import io.github.thetrouper.sentinel.server.util.Text;
@@ -13,59 +15,75 @@ import java.util.regex.Pattern;
public class AdvancedBlockers { public class AdvancedBlockers {
public static void handleAdvanced(AsyncPlayerChatEvent e) { public static void handleAdvanced(AsyncPlayerChatEvent e, Report report) {
//if (Sentinel.isTrusted(e.getPlayer())) return; //if (Sentinel.isTrusted(e.getPlayer())) return;
if (Sentinel.mainConfig.chat.useAntiUnicode) handleAntiUnicode(e); if (Sentinel.mainConfig.chat.useAntiUnicode) handleAntiUnicode(e,report);
if (Sentinel.mainConfig.chat.useAntiURL) handleAntiURL(e); if (Sentinel.mainConfig.chat.useAntiURL) handleAntiURL(e,report);
if (Sentinel.mainConfig.chat.useStrictRegex) handleStrictRegex(e); if (Sentinel.mainConfig.chat.useStrictRegex) handleStrictRegex(e,report);
if (Sentinel.mainConfig.chat.useSwearRegex) handleSwearRegex(e); if (Sentinel.mainConfig.chat.useSwearRegex) handleSwearRegex(e,report);
} }
public static void handleAntiUnicode(AsyncPlayerChatEvent e) { public static void handleAntiUnicode(AsyncPlayerChatEvent e, Report report) {
String message = Text.removeFirstColor(e.getMessage()); String message = Text.removeFirstColor(e.getMessage());
report.stepsTaken().put("Anti-Unicode", "`%s`".formatted(message));
ServerUtils.sendDebugMessage("AdvBlocker: Checking for unicode: " + message); ServerUtils.sendDebugMessage("AdvBlocker: Checking for unicode: " + message);
String nonAllowed = message.replaceAll(Sentinel.advConfig.allowedCharRegex, "").trim(); String nonAllowed = message.replaceAll(Sentinel.advConfig.allowedCharRegex, "").trim();
if (nonAllowed.length() != 0) { if (nonAllowed.length() != 0) {
ServerUtils.sendDebugMessage("AdvBlocker: Caught Unicode: " + nonAllowed); ServerUtils.sendDebugMessage("AdvBlocker: Caught Unicode: " + nonAllowed);
e.setCancelled(true); e.setCancelled(true);
report.stepsTaken().replace("Anti-Unicode", "`%s` %s".formatted(message, Emojis.alarm));
FilterAction.filterPunish(e,FAT.BLOCK_UNICODE,null,null); FilterAction.filterPunish(e,FAT.BLOCK_UNICODE,null,null);
} }
} }
public static void handleSwearRegex(AsyncPlayerChatEvent e) { public static void handleSwearRegex(AsyncPlayerChatEvent e, Report report) {
String urlRegex = Sentinel.advConfig.swearRegex; String swearRegex = Sentinel.advConfig.swearRegex;
Pattern pattern = Pattern.compile(urlRegex, Pattern.CASE_INSENSITIVE); Pattern pattern = Pattern.compile(swearRegex, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(e.getMessage()); Matcher matcher = pattern.matcher(e.getMessage());
report.stepsTaken().put("Anti-Swear Regex", "`%s`".formatted(e.getMessage()));
String highlighted = Text.regexHighlighter(swearRegex,e.getMessage()," > "," < ");
if (matcher.find()) { if (matcher.find()) {
e.setCancelled(true); e.setCancelled(true);
report.stepsTaken().replace("Anti-Swear Regex", "`%s` %s".formatted(highlighted, Emojis.alarm));
FilterAction.filterPunish(e,FAT.SWEAR_PUNISH,null,FilterSeverity.HIGH); FilterAction.filterPunish(e,FAT.SWEAR_PUNISH,null,FilterSeverity.HIGH);
} }
} }
public static void handleStrictRegex(AsyncPlayerChatEvent e) { public static void handleStrictRegex(AsyncPlayerChatEvent e, Report report) {
String urlRegex = Sentinel.advConfig.strictRegex; String strictRegex = Sentinel.advConfig.strictRegex;
Pattern pattern = Pattern.compile(urlRegex, Pattern.CASE_INSENSITIVE); Pattern pattern = Pattern.compile(strictRegex, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(e.getMessage()); Matcher matcher = pattern.matcher(e.getMessage());
report.stepsTaken().put("Strict Regex", "`%s`".formatted(e.getMessage()));
String highlighted = Text.regexHighlighter(strictRegex,e.getMessage()," > "," < ");
if (matcher.find()) { if (matcher.find()) {
e.setCancelled(true); e.setCancelled(true);
report.stepsTaken().replace("Strict Regex", "`%s` %s".formatted(highlighted, Emojis.alarm));
FilterAction.filterPunish(e, FAT.SLUR_PUNISH,null, FilterSeverity.SLUR); FilterAction.filterPunish(e, FAT.SLUR_PUNISH,null, FilterSeverity.SLUR);
} }
} }
public static void handleAntiURL(AsyncPlayerChatEvent e) { public static void handleAntiURL(AsyncPlayerChatEvent e, Report report) {
String urlRegex = Sentinel.advConfig.urlRegex; String urlRegex = Sentinel.advConfig.urlRegex;
Pattern pattern = Pattern.compile(urlRegex, Pattern.CASE_INSENSITIVE); Pattern pattern = Pattern.compile(urlRegex, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(e.getMessage()); 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().replace("Anti-URL", "`%s` %s".formatted(e.getMessage(), Emojis.alarm));
if (matcher.find()) { if (matcher.find()) {
e.setCancelled(true); e.setCancelled(true);
ServerUtils.sendDebugMessage("AdvBlocker: Caught URL: " + Text.regexHighlighter(e.getMessage(),Sentinel.advConfig.urlRegex," > "," < ")); String highlighted = Text.regexHighlighter(e.getMessage(),Sentinel.advConfig.urlRegex," > "," < ");
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); FilterAction.filterPunish(e,FAT.BLOCK_URL,null,null);
} }

View File

@@ -1,7 +1,9 @@
package io.github.thetrouper.sentinel.server.functions; package io.github.thetrouper.sentinel.server.functions;
import io.github.thetrouper.sentinel.Sentinel; 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.FAT;
import io.github.thetrouper.sentinel.data.Report;
import io.github.thetrouper.sentinel.server.FilterAction; import io.github.thetrouper.sentinel.server.FilterAction;
import io.github.thetrouper.sentinel.server.util.GPTUtils; import io.github.thetrouper.sentinel.server.util.GPTUtils;
import io.github.thetrouper.sentinel.server.util.ServerUtils; import io.github.thetrouper.sentinel.server.util.ServerUtils;
@@ -21,10 +23,9 @@ public class AntiSpam {
lastMessageMap = new HashMap<>(); lastMessageMap = new HashMap<>();
} }
public static void handleAntiSpam(AsyncPlayerChatEvent e) { public static void handleAntiSpam(AsyncPlayerChatEvent e, Report report) {
Player p = e.getPlayer(); Player p = e.getPlayer();
String message = Text.removeFirstColor(e.getMessage()); String message = Text.removeFirstColor(e.getMessage());
if (!lastMessageMap.containsKey(p)) { if (!lastMessageMap.containsKey(p)) {
lastMessageMap.put(p,"/* Placeholder Message from Sentinel */"); lastMessageMap.put(p,"/* Placeholder Message from Sentinel */");
ServerUtils.sendDebugMessage("AntiSpam: " + p.getName() + " did not have a previous message, setting to placeholder!"); ServerUtils.sendDebugMessage("AntiSpam: " + p.getName() + " did not have a previous message, setting to placeholder!");
@@ -51,16 +52,20 @@ public class AntiSpam {
} }
} }
report.stepsTaken().put("Anti-Spam", "Heat: %s\nMessage: `%s`".formatted(heatMap.get(p),message));
lastMessageMap.put(p, message); lastMessageMap.put(p, message);
if (heatMap.get(p) > Sentinel.mainConfig.chat.antiSpam.punishHeat) { if (heatMap.get(p) > Sentinel.mainConfig.chat.antiSpam.punishHeat) {
e.setCancelled(true); e.setCancelled(true);
report.stepsTaken().replace("Anti-Spam", "Heat: %s\nMessage: `%s` %s".formatted(heatMap.get(p),message, Emojis.alarm));
FilterAction.filterPunish(e,FAT.SPAM_PUNISH,GPTUtils.calcSim(e.getMessage(),lastMessageMap.get(p)), null); FilterAction.filterPunish(e,FAT.SPAM_PUNISH,GPTUtils.calcSim(e.getMessage(),lastMessageMap.get(p)), null);
return; return;
} }
if (heatMap.get(p) > Sentinel.mainConfig.chat.antiSpam.blockHeat) { if (heatMap.get(p) > Sentinel.mainConfig.chat.antiSpam.blockHeat) {
e.setCancelled(true); e.setCancelled(true);
report.stepsTaken().replace("Anti-Spam", "Heat: %s\nMessage: `%s` %s".formatted(heatMap.get(p),message, Emojis.alarm));
FilterAction.filterPunish(e,FAT.BLOCK_SPAM, GPTUtils.calcSim(e.getMessage(),lastMessageMap.get(p)), null); FilterAction.filterPunish(e,FAT.BLOCK_SPAM, GPTUtils.calcSim(e.getMessage(),lastMessageMap.get(p)), null);
heatMap.put(p, heatMap.get(p) + Sentinel.mainConfig.chat.antiSpam.highGain); heatMap.put(p, heatMap.get(p) + Sentinel.mainConfig.chat.antiSpam.highGain);
return; return;

View File

@@ -3,6 +3,7 @@ package io.github.thetrouper.sentinel.server.functions;
import io.github.thetrouper.sentinel.Sentinel; import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.data.FAT; import io.github.thetrouper.sentinel.data.FAT;
import io.github.thetrouper.sentinel.data.FilterSeverity; import io.github.thetrouper.sentinel.data.FilterSeverity;
import io.github.thetrouper.sentinel.data.Report;
import io.github.thetrouper.sentinel.server.FilterAction; import io.github.thetrouper.sentinel.server.FilterAction;
import io.github.thetrouper.sentinel.server.util.ServerUtils; import io.github.thetrouper.sentinel.server.util.ServerUtils;
import io.github.thetrouper.sentinel.server.util.Text; import io.github.thetrouper.sentinel.server.util.Text;
@@ -23,67 +24,58 @@ public class ProfanityFilter {
scoreMap = new HashMap<>(); scoreMap = new HashMap<>();
} }
public static void handleProfanityFilter(AsyncPlayerChatEvent e) { public static void handleProfanityFilter(AsyncPlayerChatEvent event, Report report) {
Player p = e.getPlayer(); Player player = event.getPlayer();
String message = Text.removeFirstColor(e.getMessage()); String message = Text.removeFirstColor(event.getMessage());
FilterSeverity severity = ProfanityFilter.checkSeverity(message); FilterSeverity severity = checkSeverity(message,report);
if (severity.equals(FilterSeverity.SAFE)) return; if (severity.equals(FilterSeverity.SAFE)) return;
if (!scoreMap.containsKey(p)) scoreMap.put(p, 0); scoreMap.putIfAbsent(player, 0);
int previousScore = scoreMap.get(player);
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);
ServerUtils.sendDebugMessage("AntiSwear Flag, Message: " + message + " Concentrated: " + fullSimplify(message) + " Severity: " + severity + " Previous Score: " + scoreMap.get(p) +" Adding Score: " + severity.getScore()); int newScore = previousScore + severity.getScore();
e.setCancelled(true); scoreMap.put(player, newScore);
if (scoreMap.get(p) + severity.getScore() > Sentinel.mainConfig.chat.antiSwear.punishScore) { if (newScore > Sentinel.mainConfig.chat.antiSwear.punishScore) {
scoreMap.put(p,scoreMap.get(p)+severity.getScore()); FilterAction.filterPunish(event, FAT.SWEAR_PUNISH, null, severity);
FilterAction.filterPunish(e,FAT.SWEAR_PUNISH,null,severity);
return; return;
} }
scoreMap.put(p,scoreMap.get(p)+severity.getScore()); FilterAction.filterPunish(event, getFAT(severity), null, severity);
FilterAction.filterPunish(e,getFAT(severity),null,severity);
} }
private static FAT getFAT(FilterSeverity severity) { private static FAT getFAT(FilterSeverity severity) {
switch (severity) { return switch (severity) {
case SAFE -> { case SAFE -> FAT.SAFE;
return FAT.SAFE; case LOW, MEDIUM_LOW, MEDIUM, MEDIUM_HIGH, HIGH -> FAT.BLOCK_SWEAR;
} case SLUR -> FAT.SLUR_PUNISH;
case LOW, MEDIUM_LOW, MEDIUM, MEDIUM_HIGH, HIGH -> { };
return FAT.BLOCK_SWEAR;
}
case SLUR -> {
return FAT.SLUR_PUNISH;
}
default -> throw new IllegalArgumentException("Warning! This severity doesn't exist! " + severity);
}
} }
public static String highlightProfanity(String text) { public static String highlightProfanity(String text) {
String highlightedSwears = highlightSwears(fullSimplify(text), "&e", "&f"); return highlightProfanity(text, "&e", "&f");
String highlightedText = highlightSlurs(highlightedSwears, "&c", "&f");
return Text.color(highlightedText);
} }
public static String highlightProfanity(String text, String start, String end) { public static String highlightProfanity(String text, String start, String end) {
String highlightedSwears = highlightSwears(fullSimplify(text), start, end); String highlightedSwears = highlightSwears(fullSimplify(text), start, end);
String highlightedText = highlightSlurs(highlightedSwears, start, end); return Text.color(highlightSlurs(highlightedSwears, start, end));
return Text.color(highlightedText);
} }
private static String highlightSwears(String text, String start, String end) { private static String highlightSwears(String text, String start, String end) {
for (String swear : swearBlacklist) { for (String swear : swearBlacklist) {
if (text.contains(swear)) {text = text.replace(swear, start + swear + end);} text = text.replace(swear, start + swear + end);
} }
return text; return text;
} }
private static String highlightSlurs(String text, String start, String end) { private static String highlightSlurs(String text, String start, String end) {
for (String slur : slurs) { for (String slur : slurs) {
if (text.contains(slur)) { text = text.replace(slur, start + slur + end);
text = text.replace(slur, start + slur + end);
}
} }
return text; return text;
} }
@@ -112,13 +104,15 @@ public class ProfanityFilter {
String simplifiedText = simplifyRepeatingLetters(strippedText); String simplifiedText = simplifyRepeatingLetters(strippedText);
return removePeriodsAndSpaces(simplifiedText); return removePeriodsAndSpaces(simplifiedText);
} }
public static FilterSeverity checkSeverity(String text) { public static FilterSeverity checkSeverity(String text, Report report) {
// 1: // 1:
String lowercasedText = text.toLowerCase(); String lowercasedText = text.toLowerCase();
report.stepsTaken().put("Lowercased", lowercasedText);
ServerUtils.sendDebugMessage("ProfanityFilter: Lowercased: " + lowercasedText); ServerUtils.sendDebugMessage("ProfanityFilter: Lowercased: " + lowercasedText);
// 2: // 2:
String cleanedText = removeFalsePositives(lowercasedText); String cleanedText = removeFalsePositives(lowercasedText);
report.stepsTaken().put("Remove False Positives", cleanedText);
ServerUtils.sendDebugMessage(("ProfanityFilter: Removed False positives: " + cleanedText)); ServerUtils.sendDebugMessage(("ProfanityFilter: Removed False positives: " + cleanedText));
// 3: // 3:
@@ -127,6 +121,7 @@ public class ProfanityFilter {
// 4: // 4:
String convertedText = convertLeetSpeakCharacters(cleanedText); String convertedText = convertLeetSpeakCharacters(cleanedText);
report.stepsTaken().put("Convert LeetSpeak", convertedText);
ServerUtils.sendDebugMessage(("ProfanityFilter: Leet Converted: " + convertedText)); ServerUtils.sendDebugMessage(("ProfanityFilter: Leet Converted: " + convertedText));
// 5: // 5:
@@ -135,6 +130,7 @@ public class ProfanityFilter {
// 6: // 6:
String strippedText = stripSpecialCharacters(convertedText); String strippedText = stripSpecialCharacters(convertedText);
report.stepsTaken().put("Remove Special Characters", strippedText);
ServerUtils.sendDebugMessage(("ProfanityFilter: Specials Removed: " + strippedText)); ServerUtils.sendDebugMessage(("ProfanityFilter: Specials Removed: " + strippedText));
// 7: // 7:
@@ -143,6 +139,7 @@ public class ProfanityFilter {
// 8: // 8:
String simplifiedText = simplifyRepeatingLetters(strippedText); String simplifiedText = simplifyRepeatingLetters(strippedText);
report.stepsTaken().put("Remove Repeats", simplifiedText);
ServerUtils.sendDebugMessage(("ProfanityFilter: Removed Repeating: " + simplifiedText)); ServerUtils.sendDebugMessage(("ProfanityFilter: Removed Repeating: " + simplifiedText));
// 9: // 9:
@@ -151,6 +148,7 @@ public class ProfanityFilter {
// 10: // 10:
String finalText = removePeriodsAndSpaces(simplifiedText); String finalText = removePeriodsAndSpaces(simplifiedText);
report.stepsTaken().put("Remove Punctuation", finalText);
ServerUtils.sendDebugMessage(("ProfanityFilter: Remove Punctuation: " + finalText)); ServerUtils.sendDebugMessage(("ProfanityFilter: Remove Punctuation: " + finalText));
// 11: // 11:

View File

@@ -5,9 +5,11 @@ import io.github.itzispyder.pdk.utils.discord.DiscordEmbed;
import io.github.itzispyder.pdk.utils.discord.DiscordWebhook; import io.github.itzispyder.pdk.utils.discord.DiscordWebhook;
import io.github.thetrouper.sentinel.Sentinel; import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.data.Emojis; import io.github.thetrouper.sentinel.data.Emojis;
import io.github.thetrouper.sentinel.data.Report;
import io.github.thetrouper.sentinel.server.util.Randomizer; import io.github.thetrouper.sentinel.server.util.Randomizer;
import io.github.thetrouper.sentinel.server.util.ServerUtils; import io.github.thetrouper.sentinel.server.util.ServerUtils;
import io.github.thetrouper.sentinel.server.util.Text; import io.github.thetrouper.sentinel.server.util.Text;
import it.unimi.dsi.fastutil.Hash;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.AsyncPlayerChatEvent;
@@ -18,6 +20,15 @@ import java.util.Map;
public class ReportFalsePositives { public class ReportFalsePositives {
public static Map<String,AsyncPlayerChatEvent> reportMap = new HashMap<>(); public static Map<String,AsyncPlayerChatEvent> reportMap = new HashMap<>();
public static Map<Long,Report> reports = new HashMap<>();
public static Report initializeReport(AsyncPlayerChatEvent e) {
final long reportID = Randomizer.generateID();
HashMap<String,String> steps = new HashMap<>();
steps.put("Original Message", e.getMessage());
return new Report(reportID,e,steps);
}
public static String generateReport(AsyncPlayerChatEvent e) { public static String generateReport(AsyncPlayerChatEvent e) {
final long reportLong = Randomizer.generateID(); final long reportLong = Randomizer.generateID();
final String reportID = Long.toString(reportLong); final String reportID = Long.toString(reportLong);
@@ -30,6 +41,34 @@ public class ReportFalsePositives {
}); });
return reportID; return reportID;
} }
public static void sendFalsePositiveReport(Report report) {
DiscordEmbed.Builder embed = 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,
report.event().getPlayer().getName(),
Emojis.target,
Emojis.space,
Emojis.arrowRight
));
report.stepsTaken().forEach((key, value)->{
embed.addField(new DiscordEmbed.Field(key,value));
});
DiscordWebhook.create()
.avatar("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png")
.username("Sentinel Anti-Nuke | Logs")
.addEmbed(embed.build())
.send(Sentinel.mainConfig.plugin.webhook);
}
public static void sendFalsePositiveReport(String reportID) { public static void sendFalsePositiveReport(String reportID) {
AsyncPlayerChatEvent e = reportMap.get(reportID); AsyncPlayerChatEvent e = reportMap.get(reportID);
String orig = e.getMessage(); String orig = e.getMessage();

View File

@@ -5,6 +5,7 @@ import io.github.itzispyder.pdk.utils.SchedulerUtils;
import io.github.thetrouper.sentinel.Sentinel; import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.cmds.SocialSpyCommand; import io.github.thetrouper.sentinel.cmds.SocialSpyCommand;
import io.github.thetrouper.sentinel.data.ActionType; import io.github.thetrouper.sentinel.data.ActionType;
import io.github.thetrouper.sentinel.data.Report;
import io.github.thetrouper.sentinel.events.CommandEvent; import io.github.thetrouper.sentinel.events.CommandEvent;
import io.github.thetrouper.sentinel.server.Action; import io.github.thetrouper.sentinel.server.Action;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -129,17 +130,18 @@ public class SystemCheck {
public static void chatCheck(Player p) { public static void chatCheck(Player p) {
SocialSpyCommand.spyMap.put(p.getUniqueId(),true); SocialSpyCommand.spyMap.put(p.getUniqueId(),true);
AsyncPlayerChatEvent swear = new AsyncPlayerChatEvent(true,p,"Sentinel AntiSwear check > Fvck", Set.of(p)); 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 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 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)); AsyncPlayerChatEvent url = new AsyncPlayerChatEvent(true,p,"join my lifesteal server! play.cringsteal.net", Set.of(p));
ProfanityFilter.handleProfanityFilter(swear); ProfanityFilter.handleProfanityFilter(swear,ReportFalsePositives.initializeReport(swear));
AdvancedBlockers.handleAntiUnicode(unicode); AdvancedBlockers.handleAntiUnicode(unicode,ReportFalsePositives.initializeReport(unicode));
AdvancedBlockers.handleAntiURL(url); AdvancedBlockers.handleAntiURL(url,ReportFalsePositives.initializeReport(url));
SchedulerUtils.loop(5,4, (loop)->{ SchedulerUtils.loop(5,4, (loop)->{
AntiSpam.lastMessageMap.put(p,"Sentinel AntiSpam Check"); AntiSpam.lastMessageMap.put(p,"Sentinel AntiSpam Check");
AntiSpam.handleAntiSpam(spam); AntiSpam.handleAntiSpam(spam,ReportFalsePositives.initializeReport(spam));
}); });
String report = ReportFalsePositives.generateReport(falsePositive); String report = ReportFalsePositives.generateReport(falsePositive);