More of the plugin's language can be edited now

This commit is contained in:
trouper
2025-02-23 20:57:55 -06:00
parent a9b434a210
commit 0b21ea4b39
110 changed files with 1037 additions and 994 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -141,4 +141,8 @@ task copyLibs {
println "All JAR files have been extracted to: ${targetDir}"
}
}
test {
useJUnitPlatform()
}

View File

@@ -2,7 +2,6 @@ package me.trouper.sentinel.data.config.lang;
import io.github.itzispyder.pdk.utils.misc.config.JsonSerializable;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.utils.Text;
import java.io.File;
@@ -97,213 +96,143 @@ public class LanguageFile implements JsonSerializable<LanguageFile> {
public String removeSuccess = "Successfully removed %1$s from the false positive list!";
}
public Generic generic = new Generic();
public class Generic {
public String yes = "Yes";
public String no = "No";
public String success = "Success";
public String failure = "Failure";
public String t = "True";
public String f = "False";
}
public Violations violations = new Violations();
public class Violations {
public Chat chat = new Chat();
public class Chat {
public Profanity profanity = new Profanity();
public Spam spam = new Spam();
public Unicode unicode = new Unicode();
public URL url = new URL();
public String denyMessage = "Blocked the message";
public String originalMessage = "Original Message";
public String highlightedMessage = "Highlighted Message";
public Profanity profanity = new Profanity();
public class Profanity {
public String preventNotification = "has been prevented from swearing.";
public String autoPunishNotification = "has been auto-punished for swearing.";
public String preventNotification = "§b§n%1$s§r §7has been prevented from swearing.";
public String autoPunishNotification = "§b§n%1$s§r §7has been auto-punished for swearing.";
public String preventWarning = "Do not use profanity in chat. Any attempt to bypass this filter will be detected, and you will be punished.";
public String autoPunishWarning = "&cYou have been auto-punished for attempting to bypass the profanity filter!";
public String autoPunishWarning = "§cYou have been auto-punished for attempting to bypass the profanity filter!";
public String treeTitle = "The Profanity Filter has been triggered.";
public String playerInfoTitle = "Player: %s";
public String uuid = "UUID";
public String score = "Score";
public String reportInfoTitle = "Profanity Filter Detection";
public String originalMessage = "Original Message";
public String processedMessage = "Processed Message";
public String processedMessage = "Processed Message";
public String severity = "Severity";
public String actionTitle = "Actions";
public String blockAction = "Blocked the message";
public String commandAction = "Executed Punishment Commands";
}
public Spam spam = new Spam();
public class Spam {
public String autoPunishNotification = "has been auto-punished for spamming.";
public String preventNotification = "might be spamming!";
public String autoPunishNotification = "§b§n%1$s§r §7has been auto-punished for spamming.";
public String preventNotification = "§b§n%1$s§r §7might be spamming!";
public String preventWarning = "Do not spam in chat! Please wait before sending another message.";
public String autoPunishWarning = "&cYou have been auto-punished for violating the anti-spam repetitively!";
public String autoPunishWarning = "§cYou have been auto-punished for violating the anti-spam repetitively!";
public String treeTitle = "The Anti-Spam has been triggered.";
public String playerInfoTitle = "Player: %s";
public String uuid = "UUID";
public String heat = "Heat";
public String reportInfoTitle = "Spam Filter Detection";
public String previousMessage = "Previous Message";
public String currentMessage = "Current Message";
public String similarity = "Similarity";
public String actionTitle = "Actions";
public String blockAction = "Blocked the message";
public String commandAction = "Executed Punishment Commands";
}
public Unicode unicode = new Unicode();
public class Unicode {
public String autoPunishNotification = "has been punished for triggering the Unicode filter.";
public String preventNotification = "has been prevented from using invalid Unicode characters.";
public String autoPunishNotification = "§b§n%1$s§r §7has been punished for triggering the Unicode filter.";
public String preventNotification = "§b§n%1$s§r §7has been prevented from using invalid Unicode characters.";
public String autoPunishWarning = "You have been punished for triggered the Unicode filter.";
public String preventWarning = "You may only use unicode from the QWERTY keyboard.";
public String treeTitle = "The Unicode Filter has been triggered.";
public String playerInfoTitle = "Player: %s";
public String uuid = "UUID";
public String reportInfoTitle = "Unicode Filter Detection";
public String originalMessage = "Original Message";
public String highlightedMessage = "Highlighted Message";
public String actionTitle = "Actions";
public String blockAction = "Blocked the message";
public String commandAction = "Executed Punishment Commands";
}
public URL url = new URL();
public class URL {
public String autoPunishNotification = "has been punished for triggering the URL filter.";
public String preventNotification = "has been prevented from sending a URL.";
public String autoPunishNotification = "§b§n%1$s§r §7has been punished for triggering the URL filter.";
public String preventNotification = "§b§n%1$s§r §7has been prevented from sending a URL.";
public String autoPunishWarning = "You have been punished for triggered the URL filter.";
public String preventWarning = "You may not send links in chat.";
public String treeTitle = "The URL Filter has been triggered.";
public String playerInfoTitle = "Player: %s";
public String uuid = "UUID";
public String reportInfoTitle = "URL Filter Detection";
public String originalMessage = "Original Message";
public String highlightedMessage = "Highlighted Message";
public String actionTitle = "Actions";
public String blockAction = "Blocked the message";
public String commandAction = "Executed Punishment Commands";
}
}
public CommandBlockEdit commandBlockEdit = new CommandBlockEdit();
public class CommandBlockEdit {
public String playerAttemptEdit = "A player has attempted to edit a command block!";
public String playerInfoTitle = "Player: %s";
public String uuid = "UUID";
public String location = "Location";
public String violationInfoTitle = "Command Block Edit Info";
public String blockLocation = "Block Location";
public String insertedCommand = "Inserted Command";
}
public CommandBlockExecute commandBlockExecute = new CommandBlockExecute();
public class CommandBlockExecute {
public String commandBlockWhitelistTripped = "Command block whitelist has been tripped.";
public String actionsTitle = "Actions";
public String commandBlockInfoTitle = "Command Block Info";
public String blockLocation = "Block Location";
public String executedCommand = "Executed Command";
public String destroyedBlock = "Destroyed block";
public String preventExecution = "Prevented Execution";
public String restore = "Restore";
public String restoreSuccess = "Success";
public String restoreFailure = "Failure";
public String loggedToDiscord = "Logged to Discord";
}
public Protections protections = new Protections();
public class Protections {
public RootName rootName = new RootName();
public class RootName {
// Headers
public String rootNameFormat = "The §e§n%1$s§r §7has been triggered!";
public String rootNameFormatPlayer = "§b§n%1$s§r §7has attempted to §e%2$s§r §7a §b%3$s§r§7!";
public CommandBlockMinecartPlace commandBlockMinecartPlace = new CommandBlockMinecartPlace();
public class CommandBlockMinecartPlace {
public String detectionChat = "&b&n%s&r &7has attempted to place a command block minecart.";
public String detectionTree = "A player has attempted to place a command block minecart!";
public String playerInfoTitle = "Player: %s";
public String uuid = "UUID";
public String location = "Location";
public String blockLocation = "Block Location";
public String minecartPlaceInfoTitle = "Minecart Place Info";
public String locationFormat = "X: %s Y: %s Z: %s";
public String blockLocationFormat = "World: %s X: %s Y: %s Z: %s";
}
// Triggers
public String use = "use";
public String edit = "edit";
public String place = "place";
public String run = "run";
public String grab = "grab";
public CommandBlockMinecartUse commandBlockMinecartUse = new CommandBlockMinecartUse();
public class CommandBlockMinecartUse {
public String detectionChat = "&b&n%s&r &7has attempted to use a command block minecart.";
public String detectionTree = "A player has attempted to use a command block minecart!";
public String playerInfoTitle = "Player: %s";
public String uuid = "UUID";
public String location = "Location";
public String cartLocation = "Cart Location";
public String minecartUseInfoTitle = "Minecart Use Info";
public String locationFormat = "X: %s Y: %s Z: %s";
public String cartLocationFormat = "World: %s X: %s Y: %s Z: %s";
}
// Types
public String commandBlock = "Command Block";
public String minecartCommandBlock = "Minecart Command Block";
public String commandBlockWhitelist = "Command Block Whitelist";
public String specificCommand = "Specific Command";
public String loggedCommand = "Logged Command";
public String dangerousCommand = "Dangerous Command";
public String nbtItem = "NBT item";
}
public CommandBlockPlace commandBlockPlace = new CommandBlockPlace();
public class CommandBlockPlace {
public String detectionChat = "&b&n%s&r &7has attempted to place a command block.";
public String detectionTree = "A player has attempted to place a command block!";
public String playerInfoTitle = "Player: %s";
public String uuid = "UUID";
public String location = "Location";
public String blockLocation = "Block Location";
public String commandBlockEditInfoTitle = "Command Block Edit Info";
public String locationFormat = "X: %s Y: %s Z: %s";
public String blockLocationFormat = "World: %s X: %s Y: %s Z: %s";
public String insertedCommand = "Inserted Command";
public String insertedCommandUploadedTo = "Inserted Command Uploaded to";
}
public InfoNode infoNode = new InfoNode();
public class InfoNode {
public String playerInfo = "Player Info";
public String commandInfo = "Command Info";
public String blockInfo = "Block Info";
public String itemInfo = "Item Info";
public String minecartInfo = "Minecart Info";
public CommandBlockUse commandBlockUse = new CommandBlockUse();
public class CommandBlockUse {
public String detectionChat = "&b&n%s&r &7has attempted to use a command block.";
public String detectionTree = "A player has attempted to use a command block!";
public String playerInfoTitle = "Player: %s";
public String uuid = "UUID";
public String location = "Location";
public String blockLocation = "Block Location";
public String commandBlockUseInfoTitle = "Command Block Use Info";
public String locationFormat = "X: %s Y: %s Z: %s";
public String blockLocationFormat = "World: %s X: %s Y: %s Z: %s";
public String commandInside = "Command Inside";
public String commandUploadedTo = "Command Uploaded to";
}
public String uuid = "UUID";
public String name = "Name";
public String permissionRequired = "Permission Required";
public String permissionSatisfied = "Permission Satisfied";
public String operator = "Operator";
public String hasMeta = "Has Meta";
public String hasName = "Has Name";
public String hasLore = "Has Lore";
public String hasEnchants = "Has Enchants";
public String hasAttributes = "Has Attributes";
public CommandExecute commandExecute = new CommandExecute();
public class CommandExecute {
public String specificCommandDetection = "A player has attempted to run a %s command.";
public String playerInfoTitle = "Player: %s";
public String uuid = "UUID";
public String location = "Location";
public String commandField = "Command";
public String commandUploadedTo = "Command Uploaded to";
public String violationInfoTitle = "Violation Info";
public String locationFormat = "X: %s Y: %s Z: %s";
public String specificCommandViolation = "&b&n%s&r &7has attempted to run a specific command.";
public String dangerousCommandViolation = "&b&n%s&r &7has attempted to run a dangerous command.";
public String loggedCommandViolation = "&b&n%s&r &7has ran a logged command.";
}
public String locationField = "Location";
public String worldField = "World";
public String commandField = "Command";
public String commandTooLargeField = "Command Too Large (Uploaded)";
public String nbtStored = "NBT Stored";
public String blockLocationField = "Block Location";
public String cartLocationField = "Cart Location";
public String locationFormat = "X: %s Y: %s Z: %s";
}
public CreativeHotbar creativeHotbar = new CreativeHotbar();
public class CreativeHotbar {
public String nbtAttemptDetection = "A player has attempted to grab an NBT item!";
public String playerInfoTitle = "Player: %s";
public String uuid = "UUID";
public String location = "Location";
public String locationFormat = "X: %s Y: %s Z: %s";
public String itemType = "Type";
public String nbtUpload = "NBT Upload";
public String itemInfoTitle = "Item Info";
public String nbtAttemptViolation = "&b&n%s&r &7has attempted to grab an NBT item.";
public ActionNode actionNode = new ActionNode();
public class ActionNode {
public String actionNodeTitle = "Actions";
public String eventCancelled = "Canceled Event";
public String destroyedBlock = "Destroyed Block";
public String restore = "Restored Original Block";
public String restoreFailed = "Failed to Restore Original Block";
public String punishmentCommandsExecuted = "Executed Punishment Commands";
public String userDeoped = "De-OP'd Player";
public String loggedToDiscord = "Logged to Discord";
}
}
public ViolationMessages violationMessages = new ViolationMessages();
public class ViolationMessages {
public String actions = "Actions";
public String eventCancelled = "Canceled Event";
public String punishmentCommandsExecuted = "Executed Punishment Commands";
public String userOpStripped = "Stripped user's OP";
public String loggedToDiscord = "Logged to Discord";
}
}
}

View File

@@ -7,8 +7,8 @@ import io.github.itzispyder.pdk.commands.Permission;
import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
import io.github.itzispyder.pdk.utils.misc.Cooldown;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.chatfilter.FalsePositiveReporting;
import me.trouper.sentinel.server.functions.chatfilter.Report;
import me.trouper.sentinel.server.functions.helpers.FalsePositiveReporting;
import me.trouper.sentinel.server.functions.helpers.Report;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.Text;
import org.bukkit.command.Command;

View File

@@ -6,7 +6,7 @@ import io.github.itzispyder.pdk.commands.CustomCommand;
import io.github.itzispyder.pdk.commands.Permission;
import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.Message;
import me.trouper.sentinel.server.functions.helpers.Message;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.Text;
import org.bukkit.Bukkit;

View File

@@ -6,7 +6,7 @@ import io.github.itzispyder.pdk.commands.CustomCommand;
import io.github.itzispyder.pdk.commands.Permission;
import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.Message;
import me.trouper.sentinel.server.functions.helpers.Message;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.Text;
import org.bukkit.command.Command;

View File

@@ -8,9 +8,8 @@ import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
import io.papermc.paper.chat.ChatRenderer;
import io.papermc.paper.event.player.AsyncChatEvent;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.config.MainConfig;
import me.trouper.sentinel.data.types.WhitelistedBlock;
import me.trouper.sentinel.server.functions.CBWhitelistManager;
import me.trouper.sentinel.server.functions.helpers.CBWhitelistManager;
import me.trouper.sentinel.server.functions.chatfilter.profanity.ProfanityFilter;
import me.trouper.sentinel.server.functions.chatfilter.spam.SpamFilter;
import me.trouper.sentinel.server.functions.chatfilter.unicode.UnicodeFilter;
@@ -208,7 +207,6 @@ public class SentinelCommand implements CustomCommand {
switch (sub) {
case "lang" -> sender.sendMessage(Sentinel.lang.brokenLang);
case "toggle" -> {
Sentinel.mainConfig.debugMode = !Sentinel.mainConfig.debugMode;
Sentinel.mainConfig.debugMode = !Sentinel.mainConfig.debugMode;
String message = Sentinel.mainConfig.debugMode
? Sentinel.lang.debug.debugEnabled

View File

@@ -1,69 +0,0 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.CBWhitelistManager;
import me.trouper.sentinel.server.functions.ViolationController;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.trees.Node;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.CommandBlock;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityChangeBlockEvent;
public class CBEditEvent implements CustomListener {
@EventHandler
private void onCMDBlockChange(EntityChangeBlockEvent e) {
//ServerUtils.verbose("CommandBlockChange: Detected the event");
if (!Sentinel.violationConfig.commandBlockEdit.enabled) return;
//ServerUtils.verbose("CommandBlockChange: Enabled");
if (!(e.getEntity() instanceof Player p)) return;
//ServerUtils.verbose("CommandBlockChange: Changer is a player");
Block b = e.getBlock();
if (!(b.getType() == Material.COMMAND_BLOCK || b.getType() == Material.REPEATING_COMMAND_BLOCK || b.getType() == Material.CHAIN_COMMAND_BLOCK))
return;
ServerUtils.verbose("CommandBlockChange: Block is a command block");
BlockState state = b.getState();
CommandBlock cb = (CommandBlock) state;
if (PlayerUtils.isTrusted(p)) {
if (!CBWhitelistManager.autoWhitelist.contains(p.getUniqueId())) return;
CBWhitelistManager.add(cb, p.getUniqueId());
return;
}
ServerUtils.verbose("CommandBlockChange: Not trusted, performing action");
e.setCancelled(true);
Node root = getLog(p, cb);
ViolationController.handleViolation(
"&b&n%s&r &7%s".formatted(p.getName(), Sentinel.lang.violations.commandBlockEdit.playerAttemptEdit),
Sentinel.violationConfig.commandBlockEdit.punish,
Sentinel.violationConfig.commandBlockEdit.deop,
Sentinel.violationConfig.commandBlockEdit.logToDiscord,
p,
Sentinel.violationConfig.commandBlockEdit.punishmentCommands,
root
);
}
private static Node getLog(Player p, CommandBlock cb) {
Node root = new Node("Sentinel");
root.addTextLine(Sentinel.lang.violations.commandBlockEdit.playerAttemptEdit);
Node playerInfo = new Node(Sentinel.lang.violations.commandBlockEdit.playerInfoTitle.formatted(p.getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.commandBlockEdit.uuid, p.getUniqueId().toString());
playerInfo.addField(Sentinel.lang.violations.commandBlockEdit.location, "X: %s Y: %s Z: %s".formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
root.addChild(playerInfo);
Node violationInfo = new Node(Sentinel.lang.violations.commandBlockEdit.violationInfoTitle);
violationInfo.addField(Sentinel.lang.violations.commandBlockEdit.blockLocation,"World: %s X: %s Y: %s Z: %s".formatted(cb.getWorld().getName(), cb.getX(), cb.getY(), cb.getZ()));
violationInfo.addField(Sentinel.lang.violations.commandBlockEdit.insertedCommand, cb.getCommand());
root.addChild(violationInfo);
return root;
}
}

View File

@@ -1,85 +0,0 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.CBWhitelistManager;
import me.trouper.sentinel.utils.FileUtils;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.Text;
import me.trouper.sentinel.utils.trees.ConsoleFormatter;
import me.trouper.sentinel.utils.trees.EmbedFormatter;
import me.trouper.sentinel.utils.trees.HoverFormatter;
import me.trouper.sentinel.utils.trees.Node;
import net.kyori.adventure.text.Component;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CommandBlock;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.server.ServerCommandEvent;
public class CBExecuteEvent implements CustomListener {
@EventHandler
private void commandBlockExecute(ServerCommandEvent e) {
//ServerUtils.verbose("Handling command block event: " + e.getCommand());
if (!Sentinel.violationConfig.commandBlockExecute.enabled) return;
//ServerUtils.verbose("Whitelist not disabled ");
if (!(e.getSender() instanceof BlockCommandSender s)) return;
//ServerUtils.verbose("Sender is command block");
Block cmdBlock = s.getBlock();
if (CBWhitelistManager.canRun(cmdBlock)) return;
ServerUtils.verbose("Command block can't run.");
CommandBlock cb = (CommandBlock) cmdBlock.getState();
Node log = getLog(cb);
Node actions = new Node(Sentinel.lang.violations.commandBlockExecute.actionsTitle);
e.setCancelled(true);
actions.addTextLine(Sentinel.lang.violations.commandBlockExecute.preventExecution);
if (Sentinel.violationConfig.commandBlockExecute.destroyBlock) {
cmdBlock.setType(Material.AIR);
actions.addTextLine(Sentinel.lang.violations.commandBlockExecute.destroyedBlock);
}
if (Sentinel.violationConfig.commandBlockExecute.attemptRestore) {
boolean restored = CBWhitelistManager.restore(cmdBlock.getLocation());
actions.addKeyValue(Sentinel.lang.violations.commandBlockExecute.restore, restored ? Sentinel.lang.violations.commandBlockExecute.restoreSuccess : Sentinel.lang.violations.commandBlockExecute.restoreFailure);
}
if (Sentinel.violationConfig.commandBlockExecute.logToDiscord) actions.addTextLine(Sentinel.lang.violations.commandBlockExecute.loggedToDiscord);
log.addChild(actions);
if (Sentinel.violationConfig.commandBlockExecute.logToDiscord) {
EmbedFormatter.sendEmbed(EmbedFormatter.format(log));
}
ServerUtils.forEachPlayer(trusted -> {
if (PlayerUtils.isTrusted(trusted)) {
trusted.sendMessage(Component.text(Text.prefix("The command block whitelist has been tripped!")).hoverEvent(Component.text(HoverFormatter.format(log)).asHoverEvent()));
}
});
Sentinel.log.info(ConsoleFormatter.format(log));
}
private static Node getLog(CommandBlock cb) {
Node root = new Node("Sentinel");
root.addTextLine(Sentinel.lang.violations.commandBlockExecute.commandBlockWhitelistTripped);
Node violationInfo = new Node(Sentinel.lang.violations.commandBlockExecute.commandBlockInfoTitle);
violationInfo.addField(Sentinel.lang.violations.commandBlockExecute.blockLocation,"World: %s X: %s Y: %s Z: %s".formatted(cb.getWorld().getName(), cb.getX(), cb.getY(), cb.getZ()));
String command = cb.getCommand();
if (command.length() <= 128) {
violationInfo.addField(Sentinel.lang.violations.commandBlockExecute.executedCommand, command);
} else {
violationInfo.addKeyValue(Sentinel.lang.violations.commandBlockExecute.executedCommand, FileUtils.createCommandLog(command));
}
root.addChild(violationInfo);
return root;
}
}

View File

@@ -1,66 +0,0 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.ViolationController;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.trees.Node;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEvent;
public class CBMCPlaceEvent implements CustomListener {
@EventHandler
private void onCMDMinecartPlace(PlayerInteractEvent e) {
//ServerUtils.verbose("MinecartCommandPlace: Detected interaction");
if (!Sentinel.violationConfig.commandBlockMinecartPlace.enabled) return;
//ServerUtils.verbose("MinecartCommandPlace: Check is enabled");
if (!e.getPlayer().isOp()) return;
//ServerUtils.verbose("MinecartCommandPlace: Player is op");
if (e.getItem() == null) return;
ServerUtils.verbose("MinecartCommandPlace: Item isn't null");
if (e.getClickedBlock() == null) return;
ServerUtils.verbose("MinecartCommandPlace: Clicked block isn't null");
if (!e.getItem().getType().equals(Material.COMMAND_BLOCK_MINECART)) return;
ServerUtils.verbose("MinecartCommandPlace: Item is a minecart command");
if (!(e.getClickedBlock().getType() == Material.RAIL || e.getClickedBlock().getType() == Material.POWERED_RAIL || e.getClickedBlock().getType() == Material.ACTIVATOR_RAIL || e.getClickedBlock().getType() == Material.DETECTOR_RAIL)) return;
ServerUtils.verbose("MinecartCommandPlace: Clicked block is a rail");
Player p = e.getPlayer();
if (PlayerUtils.isTrusted(p)) return;
ServerUtils.verbose("MinecartCommandPlace: Not trusted, preforming action");
e.setCancelled(true);
p.getInventory().remove(Material.COMMAND_BLOCK_MINECART);
Node log = getLog(p, e.getClickedBlock());
ViolationController.handleViolation(
Sentinel.lang.violations.commandBlockMinecartPlace.detectionChat.formatted(p.getName()),
Sentinel.violationConfig.commandBlockMinecartPlace.punish,
Sentinel.violationConfig.commandBlockMinecartPlace.deop,
Sentinel.violationConfig.commandBlockMinecartPlace.logToDiscord,
p,
Sentinel.violationConfig.commandBlockMinecartPlace.punishmentCommands,
log
);
}
private static Node getLog(Player p, Block cb) {
Node root = new Node("Sentinel");
root.addTextLine(Sentinel.lang.violations.commandBlockMinecartPlace.detectionTree);
Node playerInfo = new Node(Sentinel.lang.violations.commandBlockMinecartPlace.playerInfoTitle.formatted(p.getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.commandBlockMinecartPlace.uuid, p.getUniqueId().toString());
playerInfo.addField(Sentinel.lang.violations.commandBlockMinecartPlace.location, Sentinel.lang.violations.commandBlockMinecartPlace.locationFormat.formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
root.addChild(playerInfo);
Node violationInfo = new Node(Sentinel.lang.violations.commandBlockMinecartPlace.minecartPlaceInfoTitle);
violationInfo.addField(Sentinel.lang.violations.commandBlockMinecartPlace.blockLocation, Sentinel.lang.violations.commandBlockMinecartPlace.blockLocationFormat.formatted(cb.getWorld().getName(), cb.getX(), cb.getY(), cb.getZ()));
root.addChild(violationInfo);
return root;
}
}

View File

@@ -1,59 +0,0 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.ViolationController;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.trees.Node;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEntityEvent;
public class CBMCUseEvent implements CustomListener {
@EventHandler
private void onCMDBlockMinecartUse(PlayerInteractEntityEvent e) {
//ServerUtils.verbose("MinecartCommandUse: Detected Interaction with entity");
if (!Sentinel.violationConfig.commandBlockMinecartUse.enabled) return;
//ServerUtils.verbose("MinecartCommandUse: Enabled");
if (!e.getPlayer().isOp()) return;
ServerUtils.verbose("MinecartCommandUse: Player op");
if (e.getRightClicked().getType() != EntityType.COMMAND_BLOCK_MINECART) return;
ServerUtils.verbose("MinecartCommandUse: Entity is minecart command");
Player p = e.getPlayer();
if (PlayerUtils.isTrusted(p)) return;
ServerUtils.verbose("MinecartCommandUse: Not trusted, performing action");
e.setCancelled(true);
Node log = getLog(p, e.getRightClicked());
ViolationController.handleViolation(
Sentinel.lang.violations.commandBlockMinecartUse.detectionChat.formatted(p.getName()),
Sentinel.violationConfig.commandBlockMinecartUse.punish,
Sentinel.violationConfig.commandBlockMinecartUse.deop,
Sentinel.violationConfig.commandBlockMinecartUse.logToDiscord,
p,
Sentinel.violationConfig.commandBlockMinecartUse.punishmentCommands,
log
);
}
private static Node getLog(Player p, Entity e) {
Node root = new Node("Sentinel");
root.addTextLine(Sentinel.lang.violations.commandBlockMinecartUse.detectionTree);
Node playerInfo = new Node(Sentinel.lang.violations.commandBlockMinecartUse.playerInfoTitle.formatted(p.getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.commandBlockMinecartUse.uuid, p.getUniqueId().toString());
playerInfo.addField(Sentinel.lang.violations.commandBlockMinecartUse.location, Sentinel.lang.violations.commandBlockMinecartUse.locationFormat.formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
root.addChild(playerInfo);
Node violationInfo = new Node(Sentinel.lang.violations.commandBlockMinecartUse.minecartUseInfoTitle);
violationInfo.addField(Sentinel.lang.violations.commandBlockMinecartUse.cartLocation, Sentinel.lang.violations.commandBlockMinecartUse.cartLocationFormat.formatted(e.getWorld().getName(), e.getX(), e.getY(), e.getZ()));
root.addChild(violationInfo);
return root;
}
}

View File

@@ -1,75 +0,0 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.CBWhitelistManager;
import me.trouper.sentinel.server.functions.ViolationController;
import me.trouper.sentinel.utils.FileUtils;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.trees.Node;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CommandBlock;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockPlaceEvent;
public class CBPlaceEvent implements CustomListener {
@EventHandler
private void onCMDBlockPlace(BlockPlaceEvent e) {
//ServerUtils.verbose("CommandBlockPlace: Detected block place");
if (!Sentinel.violationConfig.commandBlockPlace.enabled) return;
//ServerUtils.verbose("CommandBlockPlace: Enabled");
if (!e.getPlayer().isOp()) return;
//ServerUtils.verbose("CommandBlockPlace: Player is operator");
Block b = e.getBlockPlaced();
if (!(b.getType().equals(Material.COMMAND_BLOCK) ||
b.getType().equals(Material.REPEATING_COMMAND_BLOCK) ||
b.getType().equals(Material.CHAIN_COMMAND_BLOCK))) return;
ServerUtils.verbose("CommandBlockPlace: Block is a command block");
Player p = e.getPlayer();
if (PlayerUtils.isTrusted(p)) {
if (!CBWhitelistManager.autoWhitelist.contains(p.getUniqueId())) return;
CBWhitelistManager.add((CommandBlock) b.getState(), p.getUniqueId());
return;
}
ServerUtils.verbose("CommandBlockPlace: Not trusted, performing action");
e.setCancelled(true);
Node log = getLog(p, (CommandBlock) b.getState());
ViolationController.handleViolation(
Sentinel.lang.violations.commandBlockPlace.detectionChat.formatted(p.getName()),
Sentinel.violationConfig.commandBlockPlace.punish,
Sentinel.violationConfig.commandBlockPlace.deop,
Sentinel.violationConfig.commandBlockPlace.logToDiscord,
p,
Sentinel.violationConfig.commandBlockPlace.punishmentCommands,
log
);
}
private static Node getLog(Player p, CommandBlock cb) {
Node root = new Node("Sentinel");
root.addTextLine(Sentinel.lang.violations.commandBlockPlace.detectionTree);
Node playerInfo = new Node(Sentinel.lang.violations.commandBlockPlace.playerInfoTitle.formatted(p.getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.commandBlockPlace.uuid, p.getUniqueId().toString());
playerInfo.addField(Sentinel.lang.violations.commandBlockPlace.location, Sentinel.lang.violations.commandBlockPlace.locationFormat.formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
root.addChild(playerInfo);
Node violationInfo = new Node(Sentinel.lang.violations.commandBlockPlace.commandBlockEditInfoTitle);
violationInfo.addField(Sentinel.lang.violations.commandBlockPlace.blockLocation, Sentinel.lang.violations.commandBlockPlace.blockLocationFormat.formatted(cb.getWorld().getName(), cb.getX(), cb.getY(), cb.getZ()));
String command = cb.getCommand();
if (command.length() <= 128) {
violationInfo.addField(Sentinel.lang.violations.commandBlockPlace.insertedCommand, command);
} else {
violationInfo.addKeyValue(Sentinel.lang.violations.commandBlockPlace.insertedCommandUploadedTo, FileUtils.createCommandLog(command));
}
root.addChild(violationInfo);
return root;
}
}

View File

@@ -1,80 +0,0 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.CBWhitelistManager;
import me.trouper.sentinel.server.functions.ViolationController;
import me.trouper.sentinel.utils.FileUtils;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.trees.Node;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CommandBlock;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEvent;
public class CBUseEvent implements CustomListener {
@EventHandler
private void onCMDBlockUse(PlayerInteractEvent e) {
//ServerUtils.verbose("CommandBlockUse: Detected Interaction");
if (!Sentinel.violationConfig.commandBlockUse.enabled) return;
//ServerUtils.verbose("CommandBlockUse: Enabled");
if (!e.getPlayer().isOp()) return;
//ServerUtils.verbose("CommandBlockUse: Player is op");
if (e.getClickedBlock() == null) return;
//ServerUtils.verbose("CommandBlockUse: Block isn't null");
Block b = e.getClickedBlock();
if (!(b.getType() == Material.COMMAND_BLOCK || b.getType() == Material.REPEATING_COMMAND_BLOCK || b.getType() == Material.CHAIN_COMMAND_BLOCK)) return;
CommandBlock cb = (CommandBlock) b.getState();
ServerUtils.verbose("CommandBlockUse: Block is a command block");
Player p = e.getPlayer();
if (PlayerUtils.isTrusted(p)) {
if (!CBWhitelistManager.autoWhitelist.contains(p.getUniqueId())) return;
if (CBWhitelistManager.canRun(cb.getBlock())) return;
e.setCancelled(true);
CBWhitelistManager.add(cb, p.getUniqueId());
return;
}
ServerUtils.verbose("CommandBlockUse: Not trusted, performing action");
e.setCancelled(true);
Node log = getLog(p, (CommandBlock) b.getState());
ViolationController.handleViolation(
Sentinel.lang.violations.commandBlockUse.detectionChat.formatted(p.getName()),
Sentinel.violationConfig.commandBlockUse.punish,
Sentinel.violationConfig.commandBlockUse.deop,
Sentinel.violationConfig.commandBlockUse.logToDiscord,
p,
Sentinel.violationConfig.commandBlockUse.punishmentCommands,
log
);
}
private static Node getLog(Player p, CommandBlock cb) {
Node root = new Node("Sentinel");
root.addTextLine(Sentinel.lang.violations.commandBlockUse.detectionTree);
Node playerInfo = new Node(Sentinel.lang.violations.commandBlockUse.playerInfoTitle.formatted(p.getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.commandBlockUse.uuid, p.getUniqueId().toString());
playerInfo.addField(Sentinel.lang.violations.commandBlockUse.location, Sentinel.lang.violations.commandBlockUse.locationFormat.formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
root.addChild(playerInfo);
Node violationInfo = new Node(Sentinel.lang.violations.commandBlockUse.commandBlockUseInfoTitle);
violationInfo.addField(Sentinel.lang.violations.commandBlockUse.blockLocation, Sentinel.lang.violations.commandBlockUse.blockLocationFormat.formatted(cb.getWorld().getName(), cb.getX(), cb.getY(), cb.getZ()));
String command = cb.getCommand();
if (command.length() <= 128) {
violationInfo.addField(Sentinel.lang.violations.commandBlockUse.commandInside, command);
} else {
violationInfo.addKeyValue(Sentinel.lang.violations.commandBlockUse.commandUploadedTo, FileUtils.createCommandLog(command));
}
root.addChild(violationInfo);
return root;
}
}

View File

@@ -0,0 +1,56 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.helpers.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.server.functions.helpers.CBWhitelistManager;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.trees.Node;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.CommandBlock;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityChangeBlockEvent;
public class CommandBlockEdit extends AbstractViolation {
@EventHandler
private void onCMDBlockChange(EntityChangeBlockEvent e) {
//ServerUtils.verbose("CommandBlockChange: Detected the event");
if (!Sentinel.violationConfig.commandBlockEdit.enabled) return;
//ServerUtils.verbose("CommandBlockChange: Enabled");
if (!(e.getEntity() instanceof Player p)) return;
//ServerUtils.verbose("CommandBlockChange: Changer is a player");
Block b = e.getBlock();
if (!(b.getType() == Material.COMMAND_BLOCK || b.getType() == Material.REPEATING_COMMAND_BLOCK || b.getType() == Material.CHAIN_COMMAND_BLOCK))
return;
ServerUtils.verbose("CommandBlockChange: Block is a command block");
CommandBlock cb = (CommandBlock) b.getState();
if (PlayerUtils.isTrusted(p)) {
if (!CBWhitelistManager.autoWhitelist.contains(p.getUniqueId())) return;
CBWhitelistManager.add(cb, p.getUniqueId());
return;
}
ServerUtils.verbose("CommandBlockChange: Not trusted, performing action");
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setEvent(e)
.setPlayer(p)
.deop(Sentinel.violationConfig.commandBlockEdit.deop)
.cancel(true)
.punish(Sentinel.violationConfig.commandBlockEdit.punish)
.setPunishmentCommands(Sentinel.violationConfig.commandBlockEdit.punishmentCommands)
.logToDiscord(Sentinel.violationConfig.commandBlockEdit.logToDiscord);
runActions(
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.edit, Sentinel.lang.violations.protections.rootName.commandBlock),
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.edit, Sentinel.lang.violations.protections.rootName.commandBlock),
generateCommandBlockInfo(cb),
config
);
}
}

View File

@@ -0,0 +1,46 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.helpers.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.server.functions.helpers.CBWhitelistManager;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CommandBlock;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.server.ServerCommandEvent;
public class CommandBlockExecute extends AbstractViolation {
@EventHandler
private void commandBlockExecute(ServerCommandEvent e) {
//ServerUtils.verbose("Handling command block event: " + e.getCommand());
if (!Sentinel.violationConfig.commandBlockExecute.enabled) return;
//ServerUtils.verbose("Whitelist not disabled ");
if (!(e.getSender() instanceof BlockCommandSender s)) return;
//ServerUtils.verbose("Sender is command block");
Block cmdBlock = s.getBlock();
if (CBWhitelistManager.canRun(cmdBlock)) return;
ServerUtils.verbose("Command block can't run.");
CommandBlock cb = (CommandBlock) cmdBlock.getState();
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setBlock(cmdBlock)
.cancel(true)
.destroyBlock(Sentinel.violationConfig.commandBlockExecute.destroyBlock)
.restoreBlock(Sentinel.violationConfig.commandBlockExecute.attemptRestore)
.logToDiscord(Sentinel.violationConfig.commandBlockExecute.logToDiscord);
runActions(
Sentinel.lang.violations.protections.rootName.rootNameFormat.formatted(Sentinel.lang.violations.protections.rootName.commandBlockWhitelist),
Sentinel.lang.violations.protections.rootName.rootNameFormat.formatted( Sentinel.lang.violations.protections.rootName.commandBlockWhitelist),
generateCommandBlockInfo(cb),
config
);
}
}

View File

@@ -0,0 +1,55 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.helpers.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEvent;
public class CommandBlockMinecartPlace extends AbstractViolation {
@EventHandler
private void onCMDMinecartPlace(PlayerInteractEvent e) {
//ServerUtils.verbose("MinecartCommandPlace: Detected interaction");
if (!Sentinel.violationConfig.commandBlockMinecartPlace.enabled) return;
//ServerUtils.verbose("MinecartCommandPlace: Check is enabled");
Player p = e.getPlayer();
if (!p.isOp()) return;
//ServerUtils.verbose("MinecartCommandPlace: Player is op");
if (e.getItem() == null) return;
ServerUtils.verbose("MinecartCommandPlace: Item isn't null");
if (e.getClickedBlock() == null) return;
ServerUtils.verbose("MinecartCommandPlace: Clicked block isn't null");
if (!e.getItem().getType().equals(Material.COMMAND_BLOCK_MINECART)) return;
ServerUtils.verbose("MinecartCommandPlace: Item is a minecart command");
if (!(e.getClickedBlock().getType() == Material.RAIL || e.getClickedBlock().getType() == Material.POWERED_RAIL || e.getClickedBlock().getType() == Material.ACTIVATOR_RAIL || e.getClickedBlock().getType() == Material.DETECTOR_RAIL)) return;
ServerUtils.verbose("MinecartCommandPlace: Clicked block is a rail");
if (PlayerUtils.isTrusted(p)) return;
ServerUtils.verbose("MinecartCommandPlace: Not trusted, performing action");
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setEvent(e)
.setPlayer(p)
.cancel(true)
.punish(Sentinel.violationConfig.commandBlockMinecartPlace.punish)
.deop(Sentinel.violationConfig.commandBlockMinecartPlace.deop)
.setPunishmentCommands(Sentinel.violationConfig.commandBlockMinecartPlace.punishmentCommands)
.logToDiscord(Sentinel.violationConfig.commandBlockMinecartPlace.logToDiscord);
// Remove the command block minecart from the player's inventory
p.getInventory().remove(Material.COMMAND_BLOCK_MINECART);
runActions(
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.place, Sentinel.lang.violations.protections.rootName.minecartCommandBlock),
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.place, Sentinel.lang.violations.protections.rootName.minecartCommandBlock),
generateBlockInfo(e.getClickedBlock()),
config
);
}
}

View File

@@ -0,0 +1,46 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.helpers.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEntityEvent;
public class CommandBlockMinecartUse extends AbstractViolation {
@EventHandler
private void onCMDBlockMinecartUse(PlayerInteractEntityEvent e) {
//ServerUtils.verbose("MinecartCommandUse: Detected Interaction with entity");
if (!Sentinel.violationConfig.commandBlockMinecartUse.enabled) return;
//ServerUtils.verbose("MinecartCommandUse: Enabled");
Player p = e.getPlayer();
if (!p.isOp()) return;
ServerUtils.verbose("MinecartCommandUse: Player op");
if (e.getRightClicked().getType() != EntityType.COMMAND_BLOCK_MINECART) return;
ServerUtils.verbose("MinecartCommandUse: Entity is minecart command");
if (PlayerUtils.isTrusted(p)) return;
ServerUtils.verbose("MinecartCommandUse: Not trusted, performing action");
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setEvent(e)
.setPlayer(p)
.cancel(true)
.punish(Sentinel.violationConfig.commandBlockMinecartUse.punish)
.deop(Sentinel.violationConfig.commandBlockMinecartUse.deop)
.setPunishmentCommands(Sentinel.violationConfig.commandBlockMinecartUse.punishmentCommands)
.logToDiscord(Sentinel.violationConfig.commandBlockMinecartUse.logToDiscord);
runActions(
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.use, Sentinel.lang.violations.protections.rootName.minecartCommandBlock),
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.use, Sentinel.lang.violations.protections.rootName.minecartCommandBlock),
generateMinecartInfo(e.getRightClicked()),
config
);
}
}

View File

@@ -0,0 +1,53 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.helpers.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CommandBlock;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockPlaceEvent;
public class CommandBlockPlace extends AbstractViolation {
@EventHandler
public void listen(BlockPlaceEvent e) {
//ServerUtils.verbose("CommandBlockPlace: Detected block place");
if (!Sentinel.violationConfig.commandBlockPlace.enabled) return;
//ServerUtils.verbose("CommandBlockPlace: Enabled");
Player p = e.getPlayer();
if (!p.isOp()) return;
//ServerUtils.verbose("CommandBlockPlace: Player is operator");
Block b = e.getBlockPlaced();
if (!(b.getType().equals(Material.COMMAND_BLOCK) ||
b.getType().equals(Material.REPEATING_COMMAND_BLOCK) ||
b.getType().equals(Material.CHAIN_COMMAND_BLOCK))) return;
ServerUtils.verbose("CommandBlockPlace: Block is a command block");
CommandBlock cb = (CommandBlock) b.getState();
if (PlayerUtils.isTrusted(p)) return;
ServerUtils.verbose("CommandBlockPlace: Not trusted, performing action");
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setEvent(e)
.setPlayer(p)
.deop(Sentinel.violationConfig.commandBlockPlace.deop)
.cancel(true)
.setEvent(e)
.punish(true)
.setPunishmentCommands(Sentinel.violationConfig.commandBlockPlace.punishmentCommands)
.logToDiscord(Sentinel.violationConfig.commandBlockPlace.logToDiscord);
runActions(
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.place, Sentinel.lang.violations.protections.rootName.commandBlock),
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.place, Sentinel.lang.violations.protections.rootName.commandBlock),
generateCommandBlockInfo(cb),
config
);
}
}

View File

@@ -0,0 +1,58 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.helpers.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.server.functions.helpers.CBWhitelistManager;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CommandBlock;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEvent;
public class CommandBlockUse extends AbstractViolation {
@EventHandler
private void onCMDBlockUse(PlayerInteractEvent e) {
//ServerUtils.verbose("CommandBlockUse: Detected Interaction");
if (!Sentinel.violationConfig.commandBlockUse.enabled) return;
//ServerUtils.verbose("CommandBlockUse: Enabled");
Player p = e.getPlayer();
if (!p.isOp()) return;
//ServerUtils.verbose("CommandBlockUse: Player is op");
if (e.getClickedBlock() == null) return;
//ServerUtils.verbose("CommandBlockUse: Block isn't null");
Block b = e.getClickedBlock();
if (!(b.getType() == Material.COMMAND_BLOCK || b.getType() == Material.REPEATING_COMMAND_BLOCK || b.getType() == Material.CHAIN_COMMAND_BLOCK)) return;
CommandBlock cb = (CommandBlock) b.getState();
ServerUtils.verbose("CommandBlockUse: Block is a command block");
if (PlayerUtils.isTrusted(p)) {
if (!CBWhitelistManager.autoWhitelist.contains(p.getUniqueId())) return;
if (CBWhitelistManager.canRun(cb.getBlock())) return;
e.setCancelled(true);
CBWhitelistManager.add(cb, p.getUniqueId());
return;
}
ServerUtils.verbose("CommandBlockUse: Not trusted, performing action");
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setEvent(e)
.setPlayer(p)
.deop(Sentinel.violationConfig.commandBlockUse.deop)
.cancel(true)
.punish(Sentinel.violationConfig.commandBlockUse.punish)
.setPunishmentCommands(Sentinel.violationConfig.commandBlockUse.punishmentCommands)
.logToDiscord(Sentinel.violationConfig.commandBlockUse.logToDiscord);
runActions(
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.use, Sentinel.lang.violations.protections.rootName.commandBlock),
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.use, Sentinel.lang.violations.protections.rootName.commandBlock),
generateCommandBlockInfo(cb),
config
);
}
}

View File

@@ -0,0 +1,101 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.helpers.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.utils.PlayerUtils;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import java.util.HashSet;
import java.util.Set;
public class CommandExecute extends AbstractViolation {
@EventHandler
private void onCommand(PlayerCommandPreprocessEvent e) {
Player p = e.getPlayer();
if (PlayerUtils.isTrusted(p)) return;
String label = e.getMessage().substring(1).split(" ")[0];
String args = e.getMessage();
Set<String> status = getCommandStatus(label);
if (status.contains("SPECIFIC") && Sentinel.violationConfig.commandExecute.specific.enabled) {
e.setCancelled(true);
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setEvent(e)
.setPlayer(p)
.cancel(true)
.punish(Sentinel.violationConfig.commandExecute.specific.punish)
.setPunishmentCommands(Sentinel.violationConfig.commandExecute.specific.punishmentCommands)
.logToDiscord(Sentinel.violationConfig.commandExecute.specific.logToDiscord);
runActions(
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.run, Sentinel.lang.violations.protections.rootName.specificCommand),
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.run, Sentinel.lang.violations.protections.rootName.specificCommand),
generateCommandInfo(args, p),
config
);
return;
}
if (status.contains("DANGEROUS") && Sentinel.violationConfig.commandExecute.dangerous.enabled) {
e.setCancelled(true);
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setEvent(e)
.setPlayer(p)
.deop(Sentinel.violationConfig.commandExecute.dangerous.deop)
.cancel(true)
.punish(Sentinel.violationConfig.commandExecute.dangerous.punish)
.setPunishmentCommands(Sentinel.violationConfig.commandExecute.dangerous.punishmentCommands)
.logToDiscord(Sentinel.violationConfig.commandExecute.dangerous.logToDiscord);
runActions(
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.run, Sentinel.lang.violations.protections.rootName.dangerousCommand),
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.run, Sentinel.lang.violations.protections.rootName.dangerousCommand),
generateCommandInfo(args, p),
config
);
return;
}
if (status.contains("LOGGED") && Sentinel.violationConfig.commandExecute.logged.enabled) {
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setPlayer(p)
.logToDiscord(Sentinel.violationConfig.commandExecute.logged.logToDiscord);
runActions(
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.run, Sentinel.lang.violations.protections.rootName.loggedCommand),
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.run, Sentinel.lang.violations.protections.rootName.loggedCommand),
generateCommandInfo(args, p),
config
);
return;
}
}
public static Set<String> getCommandStatus(String label) {
Set<String> commandTypes = new HashSet<>();
if (label.startsWith("/")) {
label = label.substring(1);
}
if (label.contains(":")) {
commandTypes.add("SPECIFIC");
}
for (String loggedCommand : Sentinel.violationConfig.commandExecute.logged.commands) {
if (loggedCommand.equals(label)) commandTypes.add("LOGGED");
}
for (String dangerousCommand : Sentinel.violationConfig.commandExecute.dangerous.commands) {
if (dangerousCommand.equals(label)) commandTypes.add("DANGEROUS");
}
return commandTypes;
}
}

View File

@@ -1,115 +0,0 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.ViolationController;
import me.trouper.sentinel.utils.FileUtils;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.trees.Node;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import java.util.HashSet;
import java.util.Set;
public class CommandExecuteEvent implements CustomListener {
@EventHandler
private void onCommand(PlayerCommandPreprocessEvent e) {
Player p = e.getPlayer();
if (PlayerUtils.isTrusted(p)) return;
String label = e.getMessage().substring(1).split(" ")[0];
String args = e.getMessage();
Set<String> status = getCommandStatus(label);
if (status.contains("SPECIFIC") && Sentinel.violationConfig.commandExecute.specific.enabled) {
e.setCancelled(true);
Node log = getLog(p, args, "specific");
ViolationController.handleViolation(
Sentinel.lang.violations.commandExecute.specificCommandViolation.formatted(p.getName()),
Sentinel.violationConfig.commandExecute.specific.punish,
false,
Sentinel.violationConfig.commandExecute.specific.logToDiscord,
p,
Sentinel.violationConfig.commandExecute.specific.punishmentCommands,
log
);
return;
}
if (status.contains("DANGEROUS") && Sentinel.violationConfig.commandExecute.dangerous.enabled) {
e.setCancelled(true);
Node log = getLog(p, args, "dangerous");
ViolationController.handleViolation(
Sentinel.lang.violations.commandExecute.dangerousCommandViolation.formatted(p.getName()),
Sentinel.violationConfig.commandExecute.dangerous.punish,
Sentinel.violationConfig.commandExecute.dangerous.deop,
Sentinel.violationConfig.commandExecute.dangerous.logToDiscord,
p,
Sentinel.violationConfig.commandExecute.dangerous.punishmentCommands,
log
);
return;
}
if (status.contains("LOGGED") && Sentinel.violationConfig.commandExecute.logged.enabled) {
Node log = getLog(p, args, "logged");
ViolationController.handleViolation(
Sentinel.lang.violations.commandExecute.loggedCommandViolation.formatted(p.getName()),
false,
false,
Sentinel.violationConfig.commandExecute.logged.logToDiscord,
p,
null,
log
);
return;
}
}
public static Set<String> getCommandStatus(String label) {
Set<String> commandTypes = new HashSet<>();
if (label.startsWith("/")) {
label = label.substring(1);
}
if (label.contains(":")) {
commandTypes.add("SPECIFIC");
}
for (String loggedCommand : Sentinel.violationConfig.commandExecute.logged.commands) {
if (loggedCommand.equals(label)) commandTypes.add("LOGGED");
}
for (String dangerousCommand : Sentinel.violationConfig.commandExecute.dangerous.commands) {
if (dangerousCommand.equals(label)) commandTypes.add("DANGEROUS");
}
return commandTypes;
}
private Node getLog(Player p, String command, String status) {
Node root = new Node("Sentinel");
root.addTextLine(Sentinel.lang.violations.commandExecute.specificCommandDetection.formatted(status));
Node playerInfo = new Node(Sentinel.lang.violations.commandExecute.playerInfoTitle.formatted(p.getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.commandExecute.uuid, p.getUniqueId().toString());
playerInfo.addField(Sentinel.lang.violations.commandExecute.location, Sentinel.lang.violations.commandExecute.locationFormat.formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
root.addChild(playerInfo);
Node violationInfo = new Node(Sentinel.lang.violations.commandExecute.violationInfoTitle);
if (command.length() <= 128) {
violationInfo.addField(Sentinel.lang.violations.commandExecute.commandField, command);
} else {
violationInfo.addKeyValue(Sentinel.lang.violations.commandExecute.commandUploadedTo, FileUtils.createCommandLog(command));
}
root.addChild(violationInfo);
return root;
}
}

View File

@@ -0,0 +1,52 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.helpers.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.utils.ItemUtils;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryCreativeEvent;
import org.bukkit.inventory.ItemStack;
public class CreativeHotbar extends AbstractViolation {
@EventHandler
private void onNBTPull(InventoryCreativeEvent e) {
//ServerUtils.verbose("NBT: Detected creative mode action");
if (!Sentinel.violationConfig.creativeHotbarAction.enabled) return;
ServerUtils.verbose("NBT: Enabled");
if (!(e.getWhoClicked() instanceof Player p)) return;
ServerUtils.verbose("NBT: Clicker is a player");
if (e.getCursor() == null) return; // Well it threw an exception during testing, so it isn't always false!
ServerUtils.verbose("NBT: Cursor isn't null");
ItemStack i = e.getCursor();
if (PlayerUtils.isTrusted(p)) return;
ServerUtils.verbose("NBT: Not trusted");
if (e.getCursor().getItemMeta() == null) return;
ServerUtils.verbose("NBT: Cursor has meta");
if (!(i.hasItemMeta() && i.getItemMeta() != null)) return;
ServerUtils.verbose("NBT: Item has meta");
if (ItemUtils.itemPasses(i)) return;
ServerUtils.verbose("NBT: Item doesn't pass, performing action");
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setEvent(e)
.setPlayer(p)
.cancel(true)
.punish(Sentinel.violationConfig.creativeHotbarAction.punish)
.deop(Sentinel.violationConfig.creativeHotbarAction.deop)
.setPunishmentCommands(Sentinel.violationConfig.creativeHotbarAction.punishmentCommands)
.logToDiscord(Sentinel.violationConfig.creativeHotbarAction.logToDiscord);
runActions(
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.grab, Sentinel.lang.violations.protections.rootName.nbtItem),
Sentinel.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.lang.violations.protections.rootName.grab, Sentinel.lang.violations.protections.rootName.nbtItem),
generateItemInfo(i),
config
);
}
}

View File

@@ -1,65 +0,0 @@
package me.trouper.sentinel.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.ViolationController;
import me.trouper.sentinel.utils.FileUtils;
import me.trouper.sentinel.utils.ItemUtils;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.trees.Node;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryCreativeEvent;
import org.bukkit.inventory.ItemStack;
public class CreativeHotbarEvent implements CustomListener {
@EventHandler
private void onNBTPull(InventoryCreativeEvent e) {
//ServerUtils.verbose("NBT: Detected creative mode action");
if (!Sentinel.violationConfig.creativeHotbarAction.enabled) return;
ServerUtils.verbose("NBT: Enabled");
if (!(e.getWhoClicked() instanceof Player p)) return;
ServerUtils.verbose("NBT: Clicker is a player");
if (e.getCursor() == null) return; // Well it through an exception during testing, so it isn't always false!
ServerUtils.verbose("NBT: Cursor isn't null");
ItemStack i = e.getCursor();
if (PlayerUtils.isTrusted(p)) return;
ServerUtils.verbose("NBT: Not trusted");
if (e.getCursor().getItemMeta() == null) return;
ServerUtils.verbose("NBT: Cursor has meta");
if (!(i.hasItemMeta() && i.getItemMeta() != null)) return;
ServerUtils.verbose("NBT: Item has meta");
if (ItemUtils.itemPasses(i)) return;
ServerUtils.verbose("NBT: Item doesn't pass, performing action");
e.setCancelled(true);
Node root = getLog(p, i);
ViolationController.handleViolation(
Sentinel.lang.violations.creativeHotbar.nbtAttemptViolation.formatted(p.getName()),
Sentinel.violationConfig.creativeHotbarAction.punish,
Sentinel.violationConfig.creativeHotbarAction.deop,
Sentinel.violationConfig.creativeHotbarAction.logToDiscord,
p,
Sentinel.violationConfig.creativeHotbarAction.punishmentCommands,
root
);
}
private static Node getLog(Player p, ItemStack item) {
Node root = new Node("Sentinel");
root.addTextLine(Sentinel.lang.violations.creativeHotbar.nbtAttemptDetection);
Node playerInfo = new Node(Sentinel.lang.violations.creativeHotbar.playerInfoTitle.formatted(p.getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.creativeHotbar.uuid, p.getUniqueId().toString());
playerInfo.addField(Sentinel.lang.violations.creativeHotbar.location, Sentinel.lang.violations.creativeHotbar.locationFormat.formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
root.addChild(playerInfo);
Node violationInfo = new Node(Sentinel.lang.violations.creativeHotbar.itemInfoTitle);
violationInfo.addKeyValue(Sentinel.lang.violations.creativeHotbar.itemType, item.getType().toString());
violationInfo.addField(Sentinel.lang.violations.creativeHotbar.nbtUpload, FileUtils.createNBTLog(item));
root.addChild(violationInfo);
return root;
}
}

View File

@@ -1,50 +0,0 @@
package me.trouper.sentinel.server.functions;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.Text;
import me.trouper.sentinel.utils.trees.ConsoleFormatter;
import me.trouper.sentinel.utils.trees.EmbedFormatter;
import me.trouper.sentinel.utils.trees.HoverFormatter;
import me.trouper.sentinel.utils.trees.Node;
import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player;
import java.util.List;
public class ViolationController {
public static void handleViolation(String message, boolean punish, boolean deopUser, boolean logToDiscord, Player perp, List<String> punishCommands, Node tree) {
Node actions = new Node(Sentinel.lang.violations.violationMessages.actions);
actions.addTextLine(Sentinel.lang.violations.violationMessages.eventCancelled);
if (punish) {
for (String punishCommand : punishCommands) {
ServerUtils.sendCommand(punishCommand.replaceAll("%player%", perp.getName()));
}
actions.addTextLine(Sentinel.lang.violations.violationMessages.punishmentCommandsExecuted);
}
if (deopUser) {
perp.setOp(false);
actions.addTextLine(Sentinel.lang.violations.violationMessages.userOpStripped);
}
if (logToDiscord) actions.addTextLine(Sentinel.lang.violations.violationMessages.loggedToDiscord);
tree.addChild(actions);
if (logToDiscord) {
EmbedFormatter.sendEmbed(EmbedFormatter.format(tree));
}
ServerUtils.forEachPlayer(trusted -> {
if (PlayerUtils.isTrusted(trusted)) {
trusted.sendMessage(Component.text(Text.prefix(message)).hoverEvent(Component.text(HoverFormatter.format(tree)).asHoverEvent()));
}
});
Sentinel.log.info(ConsoleFormatter.format(tree));
}
}

View File

@@ -2,6 +2,8 @@ package me.trouper.sentinel.server.functions.chatfilter;
import io.github.itzispyder.pdk.utils.discord.DiscordEmbed;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.helpers.FalsePositiveReporting;
import me.trouper.sentinel.server.functions.helpers.FilterHelpers;
import me.trouper.sentinel.utils.trees.ConsoleFormatter;
import me.trouper.sentinel.utils.trees.EmbedFormatter;
import me.trouper.sentinel.utils.trees.Node;
@@ -19,10 +21,11 @@ public abstract class AbstractActionHandler<T extends FilterResponse> {
punish(response);
discordNotification(tree);
}
staffWarning(response, tree);
if (shouldWarnPlayer(response)) {
playerWarning(response);
}
staffWarning(response, tree);
consoleLog(tree);
}

View File

@@ -1,6 +1,7 @@
package me.trouper.sentinel.server.functions.chatfilter;
import io.papermc.paper.event.player.AsyncChatEvent;
import me.trouper.sentinel.server.functions.helpers.Report;
import org.bukkit.entity.Player;
public interface FilterResponse {

View File

@@ -53,20 +53,20 @@ public class ProfanityAction extends AbstractActionHandler<ProfanityResponse> {
Node root = new Node("Sentinel");
root.addTextLine(Sentinel.lang.violations.chat.profanity.treeTitle);
Node playerInfo = new Node(Sentinel.lang.violations.chat.profanity.playerInfoTitle.formatted(response.getPlayer().getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.chat.profanity.uuid, response.getPlayer().getUniqueId().toString());
Node playerInfo = new Node(Sentinel.lang.violations.protections.infoNode.playerInfo.formatted(response.getPlayer().getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.uuid, response.getPlayer().getUniqueId().toString());
playerInfo.addKeyValue(Sentinel.lang.violations.chat.profanity.score, "%s/%s".formatted(ProfanityFilter.scoreMap.getOrDefault(response.getPlayer().getUniqueId(),0),Sentinel.mainConfig.chat.profanityFilter.punishScore));
root.addChild(playerInfo);
Node reportInfo = new Node(Sentinel.lang.violations.chat.profanity.reportInfoTitle);
reportInfo.addField(Sentinel.lang.violations.chat.profanity.originalMessage, response.getOriginalMessage());
reportInfo.addField(Sentinel.lang.violations.chat.originalMessage, response.getOriginalMessage());
reportInfo.addField(Sentinel.lang.violations.chat.profanity.processedMessage, response.getProcessedMessage());
reportInfo.addKeyValue(Sentinel.lang.violations.chat.profanity.severity, response.getSeverity().toString());
root.addChild(reportInfo);
Node actions = new Node(Sentinel.lang.violations.chat.profanity.actionTitle);
actions.addTextLine(Sentinel.lang.violations.chat.profanity.blockAction);
if (response.isPunished()) actions.addTextLine(Sentinel.lang.violations.chat.profanity.commandAction);
Node actions = new Node(Sentinel.lang.violations.protections.actionNode.actionNodeTitle);
actions.addTextLine(Sentinel.lang.violations.chat.denyMessage);
if (response.isPunished()) actions.addTextLine(Sentinel.lang.violations.protections.actionNode.punishmentCommandsExecuted);
root.addChild(actions);
return root;

View File

@@ -2,15 +2,14 @@ package me.trouper.sentinel.server.functions.chatfilter.profanity;
import io.papermc.paper.event.player.AsyncChatEvent;
import me.trouper.sentinel.data.Emojis;
import me.trouper.sentinel.server.functions.chatfilter.FalsePositiveReporting;
import me.trouper.sentinel.server.functions.chatfilter.FilterHelpers;
import me.trouper.sentinel.server.functions.helpers.FalsePositiveReporting;
import me.trouper.sentinel.server.functions.helpers.FilterHelpers;
import me.trouper.sentinel.server.functions.chatfilter.FilterResponse;
import me.trouper.sentinel.server.functions.chatfilter.Report;
import me.trouper.sentinel.server.functions.helpers.Report;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.Text;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.entity.Player;
import org.bukkit.event.player.AsyncPlayerChatEvent;
public class ProfanityResponse implements FilterResponse {

View File

@@ -48,8 +48,8 @@ public class SpamAction extends AbstractActionHandler<SpamResponse> {
Node root = new Node("Sentinel");
root.addTextLine(Sentinel.lang.violations.chat.spam.treeTitle);
Node playerInfo = new Node(Sentinel.lang.violations.chat.spam.playerInfoTitle.formatted(response.getEvent().getPlayer().getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.chat.spam.uuid, response.getEvent().getPlayer().getUniqueId().toString());
Node playerInfo = new Node(Sentinel.lang.violations.protections.infoNode.playerInfo.formatted(response.getEvent().getPlayer().getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.uuid, response.getEvent().getPlayer().getUniqueId().toString());
playerInfo.addKeyValue(Sentinel.lang.violations.chat.spam.heat, "%s/%s".formatted(SpamFilter.heatMap.get(response.getEvent().getPlayer().getUniqueId()),Sentinel.mainConfig.chat.spamFilter.punishHeat));
root.addChild(playerInfo);
@@ -59,9 +59,9 @@ public class SpamAction extends AbstractActionHandler<SpamResponse> {
reportInfo.addKeyValue(Sentinel.lang.violations.chat.spam.similarity, "%s/%s".formatted((int) Math.round(response.getSimilarity()),Sentinel.mainConfig.chat.spamFilter.blockSimilarity));
root.addChild(reportInfo);
Node actions = new Node(Sentinel.lang.violations.chat.spam.actionTitle);
actions.addTextLine(Sentinel.lang.violations.chat.spam.blockAction);
if (response.isPunished()) actions.addTextLine(Sentinel.lang.violations.chat.spam.commandAction);
Node actions = new Node(Sentinel.lang.violations.protections.actionNode.actionNodeTitle);
actions.addTextLine(Sentinel.lang.violations.chat.denyMessage);
if (response.isPunished()) actions.addTextLine(Sentinel.lang.violations.protections.actionNode.punishmentCommandsExecuted);
root.addChild(actions);
return root;

View File

@@ -3,14 +3,13 @@ package me.trouper.sentinel.server.functions.chatfilter.spam;
import io.github.retrooper.packetevents.adventure.serializer.legacy.LegacyComponentSerializer;
import io.papermc.paper.event.player.AsyncChatEvent;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.server.functions.chatfilter.FalsePositiveReporting;
import me.trouper.sentinel.server.functions.helpers.FalsePositiveReporting;
import me.trouper.sentinel.server.functions.chatfilter.FilterResponse;
import me.trouper.sentinel.server.functions.chatfilter.Report;
import me.trouper.sentinel.server.functions.helpers.Report;
import me.trouper.sentinel.utils.MathUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.Text;
import org.bukkit.entity.Player;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import static me.trouper.sentinel.server.functions.chatfilter.spam.SpamFilter.lastMessageMap;

View File

@@ -45,18 +45,18 @@ public class UnicodeAction extends AbstractActionHandler<UnicodeResponse> {
Node root = new Node("Sentinel");
root.addTextLine(Sentinel.lang.violations.chat.unicode.treeTitle);
Node playerInfo = new Node(Sentinel.lang.violations.chat.unicode.playerInfoTitle.formatted(response.getPlayer().getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.chat.unicode.uuid, response.getPlayer().getUniqueId().toString());
Node playerInfo = new Node(Sentinel.lang.violations.protections.infoNode.playerInfo.formatted(response.getPlayer().getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.uuid, response.getPlayer().getUniqueId().toString());
root.addChild(playerInfo);
Node reportInfo = new Node(Sentinel.lang.violations.chat.unicode.reportInfoTitle);
reportInfo.addField(Sentinel.lang.violations.chat.unicode.originalMessage, response.getOriginalMessage());
reportInfo.addField(Sentinel.lang.violations.chat.unicode.highlightedMessage, response.getHighlightedMessage());
reportInfo.addField(Sentinel.lang.violations.chat.originalMessage, response.getOriginalMessage());
reportInfo.addField(Sentinel.lang.violations.chat.highlightedMessage, response.getHighlightedMessage());
root.addChild(reportInfo);
Node actions = new Node(Sentinel.lang.violations.chat.unicode.actionTitle);
actions.addTextLine(Sentinel.lang.violations.chat.unicode.blockAction);
if (response.isPunished()) actions.addTextLine(Sentinel.lang.violations.chat.unicode.commandAction);
Node actions = new Node(Sentinel.lang.violations.protections.actionNode.actionNodeTitle);
actions.addTextLine(Sentinel.lang.violations.chat.denyMessage);
if (response.isPunished()) actions.addTextLine(Sentinel.lang.violations.protections.actionNode.punishmentCommandsExecuted);
root.addChild(actions);
return root;

View File

@@ -4,9 +4,9 @@ import io.github.retrooper.packetevents.adventure.serializer.legacy.LegacyCompon
import io.papermc.paper.event.player.AsyncChatEvent;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.Emojis;
import me.trouper.sentinel.server.functions.chatfilter.FalsePositiveReporting;
import me.trouper.sentinel.server.functions.helpers.FalsePositiveReporting;
import me.trouper.sentinel.server.functions.chatfilter.FilterResponse;
import me.trouper.sentinel.server.functions.chatfilter.Report;
import me.trouper.sentinel.server.functions.helpers.Report;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.Text;
import org.bukkit.entity.Player;

View File

@@ -45,18 +45,18 @@ public class UrlAction extends AbstractActionHandler<UrlResponse> {
Node root = new Node("Sentinel");
root.addTextLine(Sentinel.lang.violations.chat.url.treeTitle);
Node playerInfo = new Node(Sentinel.lang.violations.chat.url.playerInfoTitle.formatted(response.getPlayer().getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.chat.url.uuid, response.getPlayer().getUniqueId().toString());
Node playerInfo = new Node(Sentinel.lang.violations.protections.infoNode.playerInfo.formatted(response.getPlayer().getName()));
playerInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.uuid, response.getPlayer().getUniqueId().toString());
root.addChild(playerInfo);
Node reportInfo = new Node(Sentinel.lang.violations.chat.url.reportInfoTitle);
reportInfo.addField(Sentinel.lang.violations.chat.url.originalMessage, response.getOriginalMessage());
reportInfo.addField(Sentinel.lang.violations.chat.url.highlightedMessage, response.getHighlightedMessage());
reportInfo.addField(Sentinel.lang.violations.chat.originalMessage, response.getOriginalMessage());
reportInfo.addField(Sentinel.lang.violations.chat.highlightedMessage, response.getHighlightedMessage());
root.addChild(reportInfo);
Node actions = new Node(Sentinel.lang.violations.chat.url.actionTitle);
actions.addTextLine(Sentinel.lang.violations.chat.url.blockAction);
if (response.isPunished()) actions.addTextLine(Sentinel.lang.violations.chat.url.commandAction);
Node actions = new Node(Sentinel.lang.violations.protections.actionNode.actionNodeTitle);
actions.addTextLine(Sentinel.lang.violations.chat.denyMessage);
if (response.isPunished()) actions.addTextLine(Sentinel.lang.violations.protections.actionNode.punishmentCommandsExecuted);
root.addChild(actions);
return root;

View File

@@ -4,10 +4,9 @@ import io.github.retrooper.packetevents.adventure.serializer.legacy.LegacyCompon
import io.papermc.paper.event.player.AsyncChatEvent;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.Emojis;
import me.trouper.sentinel.server.functions.chatfilter.FalsePositiveReporting;
import me.trouper.sentinel.server.functions.helpers.FalsePositiveReporting;
import me.trouper.sentinel.server.functions.chatfilter.FilterResponse;
import me.trouper.sentinel.server.functions.chatfilter.Report;
import me.trouper.sentinel.server.functions.chatfilter.unicode.UnicodeResponse;
import me.trouper.sentinel.server.functions.helpers.Report;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.Text;
import org.bukkit.entity.Player;

View File

@@ -0,0 +1,133 @@
package me.trouper.sentinel.server.functions.helpers;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.utils.FileUtils;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.Text;
import me.trouper.sentinel.utils.trees.ConsoleFormatter;
import me.trouper.sentinel.utils.trees.EmbedFormatter;
import me.trouper.sentinel.utils.trees.HoverFormatter;
import me.trouper.sentinel.utils.trees.Node;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.block.CommandBlock;
import org.bukkit.command.Command;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReference;
public abstract class AbstractViolation implements CustomListener {
public void runActions(String rootName, String rootNamePlayer, Node violationInfo, ActionConfiguration.Builder configuration) {
ActionConfiguration config = configuration.build();
Node root = new Node("Sentinel");
root.addTextLine(rootName);
if (config.getPlayer() != null) root.addChild(generatePlayerInfo(config.getPlayer()));
root.addChild(violationInfo);
root.addChild(configuration.getActionNode());
notifyTrusted(root,(rootNamePlayer == null || rootNamePlayer.isBlank()) ? rootName : rootNamePlayer);
if (configuration.isLoggedToDiscord()) EmbedFormatter.sendEmbed(EmbedFormatter.format(root));
Sentinel.log.info(ConsoleFormatter.format(root));
}
public void notifyTrusted(Node root, String rootNamePlayer) {
ServerUtils.forEachPlayer(trusted -> {
if (PlayerUtils.isTrusted(trusted)) {
trusted.sendMessage(Component.text(Text.prefix(rootNamePlayer)).hoverEvent(Component.text(HoverFormatter.format(root)).asHoverEvent()));
}
});
}
public Node generatePlayerInfo(Player p) {
Node playerInfo = new Node(Sentinel.lang.violations.protections.infoNode.playerInfo);
playerInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.name, p.getName());
playerInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.uuid, p.getUniqueId().toString());
playerInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.operator, p.isOp() ? Sentinel.lang.generic.yes : Sentinel.lang.generic.no);
playerInfo.addField(Sentinel.lang.violations.protections.infoNode.locationField, Sentinel.lang.violations.protections.infoNode.locationFormat.formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
return playerInfo;
}
public static Node generateBlockInfo(Block block) {
Node blockInfo = new Node(Sentinel.lang.violations.protections.infoNode.blockInfo);
blockInfo.addTextLine(Text.cleanName(block.getType().toString()));
blockInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.worldField,block.getWorld().getName());
blockInfo.addField(Sentinel.lang.violations.protections.infoNode.blockLocationField,Sentinel.lang.violations.protections.infoNode.locationFormat.formatted(block.getX(), block.getY(), block.getZ()));
return blockInfo;
}
public Node generateCommandBlockInfo(CommandBlock commandBlock) {
Node commandBlockInfo = new Node(Sentinel.lang.violations.protections.infoNode.blockInfo);
commandBlockInfo.addTextLine(Text.cleanName(commandBlock.getType().toString()));
commandBlockInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.worldField,commandBlock.getWorld().getName());
commandBlockInfo.addField(Sentinel.lang.violations.protections.infoNode.blockLocationField,Sentinel.lang.violations.protections.infoNode.locationFormat.formatted(commandBlock.getX(), commandBlock.getY(), commandBlock.getZ()));
String command = commandBlock.getCommand();
if (command == null || command.isBlank()) {
return commandBlockInfo;
} else if (command.length() <= 128) {
commandBlockInfo.addField(Sentinel.lang.violations.protections.infoNode.commandField, command);
} else {
commandBlockInfo.addField(Sentinel.lang.violations.protections.infoNode.commandTooLargeField, FileUtils.createCommandLog(command));
}
return commandBlockInfo;
}
public Node generateMinecartInfo(Entity entity) {
Node minecartInfo = new Node(Sentinel.lang.violations.protections.infoNode.minecartInfo);
minecartInfo.addTextLine(Text.cleanName(entity.getType().toString()));
minecartInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.worldField,entity.getWorld().getName());
minecartInfo.addField(Sentinel.lang.violations.protections.infoNode.cartLocationField,Sentinel.lang.violations.protections.infoNode.locationFormat.formatted(Math.round(entity.getX()), Math.round(entity.getY()), Math.round(entity.getZ())));
return minecartInfo;
}
public Node generateItemInfo(ItemStack item) {
Node itemInfo = new Node(Sentinel.lang.violations.protections.infoNode.itemInfo);
itemInfo.addTextLine(Text.cleanName(item.getType().toString()));
itemInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.hasMeta,item.hasItemMeta() ? Sentinel.lang.generic.yes : Sentinel.lang.generic.no);
if (item.hasItemMeta()) {
itemInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.hasName,item.getItemMeta().hasCustomName() ? Sentinel.lang.generic.yes : Sentinel.lang.generic.no);
itemInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.hasLore,item.getItemMeta().hasLore() ? Sentinel.lang.generic.yes : Sentinel.lang.generic.no);
itemInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.hasAttributes,item.getItemMeta().hasAttributeModifiers() ? Sentinel.lang.generic.yes : Sentinel.lang.generic.no);
itemInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.hasEnchants,item.getItemMeta().hasEnchants() ? Sentinel.lang.generic.yes : Sentinel.lang.generic.no);
itemInfo.addField(Sentinel.lang.violations.protections.infoNode.nbtStored, FileUtils.createNBTLog(item));
}
return itemInfo;
}
public Node generateCommandInfo(String command, Player executor) {
Node commandInfo = new Node(Sentinel.lang.violations.protections.infoNode.commandInfo);
String name = command.split(" ")[0].substring(1);
ServerUtils.verbose("Command Name: " + name);
Command executed = Bukkit.getServer().getCommandMap().getCommand(name);
commandInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.name,name);
if (command.length() <= 128) {
commandInfo.addField(Sentinel.lang.violations.protections.infoNode.commandField, command);
} else {
commandInfo.addField(Sentinel.lang.violations.protections.infoNode.commandTooLargeField, FileUtils.createCommandLog(command));
}
if (executed == null || executed.getPermission() == null) return commandInfo;
commandInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.permissionRequired,executed.getPermission());
commandInfo.addKeyValue(Sentinel.lang.violations.protections.infoNode.permissionSatisfied,executor.hasPermission(executed.getPermission()) ? Sentinel.lang.generic.yes : Sentinel.lang.generic.no);
return commandInfo;
}
}

View File

@@ -0,0 +1,255 @@
package me.trouper.sentinel.server.functions.helpers;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.trees.Node;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class ActionConfiguration {
private Player player;
private boolean deop;
private Cancellable event;
private boolean cancel;
private Block block;
private boolean destroyBlock;
private boolean restoreBlock;
private boolean punish;
private List<String> punishmentCommands;
private boolean logToDiscord;
private Node actionNode;
public ActionConfiguration(Builder builder) {
this.player = builder.player;
this.deop = builder.deop;
this.event = builder.event;
this.cancel = builder.cancel;
this.block = builder.block;
this.destroyBlock = builder.destroyBlock;
this.restoreBlock = builder.restoreBlock;
this.punish = builder.punish;
this.punishmentCommands = builder.punishmentCommands;
this.logToDiscord = builder.logToDiscord;
this.actionNode = builder.actionNode;
// Removed the actions being run here to prevent double execution
}
public Player getPlayer() {
return player;
}
public void setPlayer(Player player) {
this.player = player;
}
public boolean isDeop() {
return deop;
}
public void setDeop(boolean deop) {
this.deop = deop;
}
public Cancellable getEvent() {
return event;
}
public void setEvent(Cancellable event) {
this.event = event;
}
public boolean isCancel() {
return cancel;
}
public void setCancel(boolean cancel) {
this.cancel = cancel;
}
public Block getBlock() {
return block;
}
public void setBlock(Block block) {
this.block = block;
}
public boolean isDestroyBlock() {
return destroyBlock;
}
public void setDestroyBlock(boolean destroyBlock) {
this.destroyBlock = destroyBlock;
}
public boolean isRestoreBlock() {
return restoreBlock;
}
public void setRestoreBlock(boolean restoreBlock) {
this.restoreBlock = restoreBlock;
}
public boolean isPunish() {
return punish;
}
public void setPunish(boolean punish) {
this.punish = punish;
}
public List<String> getPunishmentCommands() {
return punishmentCommands;
}
public void setPunishmentCommands(List<String> punishmentCommands) {
this.punishmentCommands = punishmentCommands;
}
public boolean isLogToDiscord() {
return logToDiscord;
}
public void setLogToDiscord(boolean logToDiscord) {
this.logToDiscord = logToDiscord;
}
public Node getActionNode() {
return actionNode;
}
public void setActionNode(Node actionNode) {
this.actionNode = actionNode;
}
public static class Builder {
private Player player;
private boolean deop;
private Cancellable event;
private boolean cancel;
private Block block;
private boolean destroyBlock;
private boolean restoreBlock;
private boolean punish;
private List<String> punishmentCommands = new ArrayList<>();
private boolean logToDiscord;
private Node actionNode = new Node(Sentinel.lang.violations.protections.actionNode.actionNodeTitle);
private List<Consumer<ActionConfiguration>> actions = new ArrayList<>();
public Builder setPlayer(Player player) {
this.player = player;
actions.add(config -> config.player = player);
return this;
}
public Builder deop(boolean deop) {
this.deop = deop;
actions.add(config -> {
config.deop = deop;
if (config.player != null) {
config.player.setOp(false);
}
config.actionNode.addTextLine(Sentinel.lang.violations.protections.actionNode.userDeoped);
});
return this;
}
public Builder setEvent(Cancellable event) {
this.event = event;
actions.add(config -> config.event = event);
return this;
}
public Builder cancel(boolean cancel) {
this.cancel = cancel;
actions.add(config -> {
config.cancel = cancel;
if (config.event != null) {
config.event.setCancelled(true);
}
config.actionNode.addTextLine(Sentinel.lang.violations.protections.actionNode.eventCancelled);
});
return this;
}
public Builder setBlock(Block block) {
this.block = block;
actions.add(config -> config.block = block);
return this;
}
public Builder destroyBlock(boolean destroyBlock) {
this.destroyBlock = destroyBlock;
actions.add(config -> {
config.destroyBlock = destroyBlock;
if (config.block != null) {
config.block.setType(Material.AIR);
config.actionNode.addTextLine(Sentinel.lang.violations.protections.actionNode.destroyedBlock);
}
});
return this;
}
public Builder restoreBlock(boolean restoreBlock) {
this.restoreBlock = restoreBlock;
actions.add(config -> {
config.restoreBlock = restoreBlock;
if (config.block != null) {
if (CBWhitelistManager.restore(config.block.getLocation())) {
config.actionNode.addTextLine(Sentinel.lang.violations.protections.actionNode.restore);
} else {
config.actionNode.addTextLine(Sentinel.lang.violations.protections.actionNode.restoreFailed);
}
}
});
return this;
}
public Builder punish(boolean punish) {
this.punish = punish;
actions.add(config -> config.punish = punish);
return this;
}
public Builder setPunishmentCommands(List<String> punishmentCommands) {
this.punishmentCommands = punishmentCommands;
actions.add(config -> {
config.punishmentCommands = punishmentCommands;
if (config.punish && config.player != null) {
for (String cmd : punishmentCommands) {
ServerUtils.sendCommand(cmd.replaceAll("%player%", config.player.getName()));
}
config.actionNode.addTextLine(Sentinel.lang.violations.protections.actionNode.punishmentCommandsExecuted);
}
});
return this;
}
public Builder logToDiscord(boolean logToDiscord) {
this.logToDiscord = logToDiscord;
actions.add(config -> config.logToDiscord = logToDiscord);
return this;
}
public boolean isLoggedToDiscord() {
return this.logToDiscord;
}
public Node getActionNode() {
return this.actionNode;
}
public ActionConfiguration build() {
ActionConfiguration config = new ActionConfiguration(this);
actions.forEach(action -> action.accept(config));
return config;
}
}
}

View File

@@ -1,4 +1,4 @@
package me.trouper.sentinel.server.functions;
package me.trouper.sentinel.server.functions.helpers;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.types.WhitelistedBlock;

View File

@@ -1,9 +1,9 @@
package me.trouper.sentinel.server.functions.chatfilter;
package me.trouper.sentinel.server.functions.helpers;
import io.github.itzispyder.pdk.utils.SchedulerUtils;
import io.github.itzispyder.pdk.utils.discord.DiscordEmbed;
import me.trouper.sentinel.data.Emojis;
import me.trouper.sentinel.server.functions.Randomizer;
import me.trouper.sentinel.utils.Randomizer;
import me.trouper.sentinel.utils.trees.EmbedFormatter;
import org.bukkit.entity.Player;

View File

@@ -1,4 +1,4 @@
package me.trouper.sentinel.server.functions.chatfilter;
package me.trouper.sentinel.server.functions.helpers;
import io.papermc.paper.event.player.AsyncChatEvent;
import me.trouper.sentinel.Sentinel;

Some files were not shown because too many files have changed in this diff Show More