Fixed bugs and added msg reply and socialspy also split the events up so it looks cleaner

This commit is contained in:
TheTelly1
2023-07-21 21:58:26 -05:00
parent 12765046eb
commit 6fd3572953
25 changed files with 629 additions and 332 deletions

View File

@@ -1,7 +1,7 @@
# Plugin
group = 'io.github.thetrouper'
version = 0.1.5
version = 0.1.7
# Minecraft
mc_version = 1.19.4

View File

@@ -4,27 +4,19 @@
package io.github.thetrouper.sentinel;
import io.github.thetrouper.sentinel.commands.InfoCommand;
import io.github.thetrouper.sentinel.commands.ReopCommand;
import io.github.thetrouper.sentinel.commands.*;
import io.github.thetrouper.sentinel.data.Config;
import io.github.thetrouper.sentinel.events.ChatEvent;
import io.github.thetrouper.sentinel.events.CmdBlockEvents;
import io.github.thetrouper.sentinel.events.CommandEvent;
import io.github.thetrouper.sentinel.events.NBTEvents;
import io.github.thetrouper.sentinel.events.*;
import io.github.thetrouper.sentinel.server.functions.AntiSpam;
import io.github.thetrouper.sentinel.server.functions.Authenticator;
import io.github.thetrouper.sentinel.server.functions.ProfanityFilter;
import io.github.thetrouper.sentinel.server.util.FileUtils;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.logging.Logger;
/**
@@ -33,6 +25,7 @@ import java.util.logging.Logger;
* To build the jar, go to terminal and run "./gradlew build"
*/
public final class Sentinel extends JavaPlugin {
private static Sentinel instance;
public static final PluginManager manager = Bukkit.getPluginManager();
public static String prefix = "";
@@ -44,6 +37,7 @@ public final class Sentinel extends JavaPlugin {
*/
@Override
public void onEnable() {
instance = this;
Config.loadConfiguration();
String serverID = Authenticator.getServerID();
log.info("Your license key is: " + key + " Your server ID is: " + serverID);
@@ -64,6 +58,7 @@ public final class Sentinel extends JavaPlugin {
getConfig().options().copyDefaults();
saveDefaultConfig();
// Plugin startup logic
log.info("Sentinel has loaded! (" + getDescription().getVersion() + ")");
@@ -74,13 +69,19 @@ public final class Sentinel extends JavaPlugin {
prefix = Config.Plugin.getPrefix();
// Commands -> BE SURE TO REGISTER ANY NEW COMMANDS IN PLUGIN.YML (src/main/java/resources/plugin.yml)!
getCommand("sentinel").setExecutor(new InfoCommand());
getCommand("sentinel").setTabCompleter(new InfoCommand());
getCommand("reop").setExecutor(new ReopCommand());
new SentinelCommand().register();
new MessageCommand().register();
new ReplyCommand().register();
new ReopCommand().register();
new SocialSpyCommand().register();
// Events
manager.registerEvents(new CommandEvent(),this);
manager.registerEvents(new CmdBlockEvents(), this);
manager.registerEvents(new CMDBlockExecute(), this);
manager.registerEvents(new CMDBlockPlace(), this);
manager.registerEvents(new CMDBlockUse(), this);
manager.registerEvents(new CMDMinecartPlace(), this);
manager.registerEvents(new CMDMinecartUse(), this);
manager.registerEvents(new NBTEvents(), this);
manager.registerEvents(new ChatEvent(),this);
@@ -140,8 +141,8 @@ public final class Sentinel extends JavaPlugin {
* Returns an instance of this plugin
* @return an instance of this plugin
*/
public static Plugin getInstance() {
return manager.getPlugin("Sentinel");
public static Sentinel getInstance() {
return instance;
}
}

View File

@@ -0,0 +1,166 @@
package io.github.thetrouper.sentinel.commands;
import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.server.util.TextUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
public abstract class CustomCommand implements TabExecutor {
protected static final Sentinel system = Sentinel.getInstance();
private final String name;
private boolean printStacktrace;
public CustomCommand(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setPrintStacktrace(boolean printStacktrace) {
this.printStacktrace = printStacktrace;
}
public boolean canPrintStacktrace() {
return printStacktrace;
}
public abstract void dispatchCommand(CommandSender sender, Command command, String label, String[] args);
public abstract void registerCompletions(CompletionBuilder builder);
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
try {
dispatchCommand(sender, command, label, args);
}
catch (Exception ex) {
String msg = ex.getMessage();
if (ex instanceof IndexOutOfBoundsException)
msg = "command incomplete";
else if (ex instanceof NullPointerException)
msg = "command contains a null value";
sender.sendMessage(TextUtils.prefix("§4Command Error: §cUnknown or incomplete command!"));
sender.sendMessage(TextUtils.prefix("§cCaused by: §8§o(" + ex.getClass().getSimpleName() + ") §7" + msg));
sender.sendMessage(TextUtils.prefix("§cCorrect Usage: §7" + command.getUsage()));
if (printStacktrace) {
ex.printStackTrace();
}
}
return true;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
CompletionBuilder builder = new CompletionBuilder(sender, command, label, args);
registerCompletions(builder);
return builder.build();
}
public CustomCommand register() {
return register(this);
}
public static CustomCommand register(CustomCommand command) {
system.getCommand(command.name).setExecutor(command);
system.getCommand(command.name).setTabCompleter(command);
return command;
}
public static class CompletionBuilder {
public final CommandSender sender;
public final Command command;
public final String label;
public final String[] args;
private final Map<Integer, List<String>> entries;
public CompletionBuilder(CommandSender sender, Command command, String label, String[] args) {
this.sender = sender;
this.command = command;
this.label = label;
this.args = args;
this.entries = new HashMap<>();
}
public CompletionBuilder addCompletion(int index, Predicate<CompletionBuilder> condition, Iterable<String> args) {
addCompletion(index, condition.test(this), args);
return this;
}
public CompletionBuilder addCompletion(int index, Predicate<CompletionBuilder> condition, String... args) {
addCompletion(index, condition.test(this), args);
return this;
}
public CompletionBuilder addCompletion(int index, Predicate<CompletionBuilder> condition, List<String> args) {
addCompletion(index, condition.test(this), args);
return this;
}
public CompletionBuilder addCompletion(int index, boolean condition, Iterable<String> args) {
if (condition) {
addCompletion(index, args);
}
return this;
}
public CompletionBuilder addCompletion(int index, boolean condition, String... args) {
if (condition) {
addCompletion(index, args);
}
return this;
}
public CompletionBuilder addCompletion(int index, boolean condition, List<String> args) {
if (condition) {
addCompletion(index, args);
}
return this;
}
public CompletionBuilder addCompletion(int index, Iterable<String> args) {
List<String> list = new ArrayList<>();
args.forEach(list::add);
addCompletion(index, list);
return this;
}
public CompletionBuilder addCompletion(int index, String... args) {
addCompletion(index, Arrays.asList(args));
return this;
}
public CompletionBuilder addCompletion(int index, List<String> args) {
entries.put(index, args);
return this;
}
public void removeCompletion(int index) {
entries.remove(index);
}
public <I> List<String> convertLists(Collection<I> input, Function<I, String> conversion) {
List<String> list = new ArrayList<>();
for (I i : input) {
list.add(conversion.apply(i));
}
return list;
}
public List<String> build() {
return entries.getOrDefault(args.length, new ArrayList<>()).stream()
.filter(s -> s.toLowerCase().contains(args[args.length - 1].toLowerCase()))
.toList();
}
}
}

View File

@@ -1,79 +0,0 @@
/**
* This file is for tutorial purposes made by ImproperIssues. Distribute if you want :)
*/
package io.github.thetrouper.sentinel.commands;
import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.data.Config;
import io.github.thetrouper.sentinel.discord.WebhookSender;
import io.github.thetrouper.sentinel.exceptions.CmdExHandler;
import io.github.thetrouper.sentinel.server.TakeAction;
import io.github.thetrouper.sentinel.server.functions.AntiSpam;
import io.github.thetrouper.sentinel.server.util.FileUtils;
import io.github.thetrouper.sentinel.server.util.ServerUtils;
import io.github.thetrouper.sentinel.server.util.TextUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.*;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import java.util.List;
/**
* Example command
*/
public class InfoCommand implements TabExecutor {
public static boolean debugmode;
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
try {
if (args.length == 0) {
sender.sendMessage(TextUtils.prefix("§cYou must specify an option!"));
return true;
}
switch (args[0]) {
case "debugmode" -> {
debugmode = !debugmode;
sender.sendMessage(TextUtils.prefix("Debug mode set to §b" + debugmode));
}
case "webhooktest" -> {
sender.sendMessage(TextUtils.prefix("Testing the webhook..."));
TakeAction.command(new PlayerCommandPreprocessEvent((Player) sender,"hehehehaw"));
}
case "checkheat" -> {
sender.sendMessage(TextUtils.prefix("Your heat is §e" + AntiSpam.heatMap.get(sender).toString()));
}
case "dispatchtest" -> {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "say " + " ]=- Sentinel Anti-Grief -=[ You have been banned for attempting a dangerous command. Contact an administrator if you believe this to be a mistake.");
ServerUtils.sendCommand("say test complete!");
}
case "filetest" -> {
sender.sendMessage(TextUtils.prefix("testing file stuff"));
if (!FileUtils.folderExists("/LoggedNBT")) {
FileUtils.createFolder("/LoggedNBT");
}
FileUtils.createNBTLog("{[IDFK MINECRAFT NBT LMAO]}; [][]\\ima just fill this with text to test it. ()()() ||||| &^%$#@!@#$%^&*(){}|:\"\"<><>");
}
}
return true;
} catch (Exception ex) {
CmdExHandler handler = new CmdExHandler(ex,command);
sender.sendMessage(handler.getErrorMessage());
ex.printStackTrace();
return true;
}
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
return new TabComplBuilder(sender,command,alias,args)
.add(1,new String[]{
"debugmode",
"webhooktest",
"checkheat",
"dispatchtest",
"filetest"
}).build();
}
}

View File

@@ -0,0 +1,57 @@
package io.github.thetrouper.sentinel.commands;
import io.github.thetrouper.sentinel.server.functions.Message;
import io.github.thetrouper.sentinel.server.util.ArrayUtils;
import io.github.thetrouper.sentinel.server.util.TextUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class MessageCommand extends CustomCommand {
public static Map<UUID, UUID> replyMap = new HashMap<>();
public MessageCommand() {
super("msg");
this.setPrintStacktrace(true);
}
@Override
public void dispatchCommand(CommandSender sender, Command command, String label, String[] args) {
Player p = (Player) sender;
Player r = null;
if (args.length == 0) {
p.sendMessage(TextUtils.prefix("§cYou must provide an online player to send a message to!"));
}
if (args.length == 1) {
p.sendMessage(TextUtils.prefix("§cYou must provide a message to send!"));
}
r = Bukkit.getPlayer(args[0]);
String msg = "";
for (int i = 1; i < args.length; i++) {
msg = msg.concat(" " + args[i]);
}
msg = msg.trim();
if (p.hasPermission("sentinel.message") && r != null) {
Message.messagePlayer(p,r,msg);
} else if (r == null) {
p.sendMessage(TextUtils.prefix("§cYou must provide an §c§l§nonline §cplayer to send a message to!"));
}
else {
sender.sendMessage(TextUtils.prefix("Invalid Permissions!"));
}
}
@Override
public void registerCompletions(CompletionBuilder builder) {
builder.addCompletion(1, ArrayUtils.toNewList(Bukkit.getOnlinePlayers(), Player::getName));
builder.addCompletion(2,builder.args.length >= 2,new String[]{
"[<message>]"
});
}
}

View File

@@ -1,41 +1,33 @@
package io.github.thetrouper.sentinel.commands;
import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.data.Config;
import io.github.thetrouper.sentinel.exceptions.CmdExHandler;
import io.github.thetrouper.sentinel.server.util.TextUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.w3c.dom.Text;
import java.util.ArrayList;
import java.util.List;
public class ReopCommand implements CommandExecutor {
public class ReopCommand extends CustomCommand {
public ReopCommand() {
super("reop");
this.setPrintStacktrace(true);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
try {
if (Config.reopCommand) {
String name = sender.getName().toString();
Player p = sender.getServer().getPlayer(name);
public void dispatchCommand(CommandSender sender, Command command, String label, String[] args) {
Player p = (Player) sender;
if (Sentinel.isTrusted(p)) {
sender.sendMessage(TextUtils.prefix("Elevating your permissions..."));
p.sendMessage(TextUtils.prefix("Elevating your permissions..."));
Sentinel.log.info("Elevating the permissions of " + p.getName());
p.setOp(true);
Sentinel.log.info("Sentinel has elevated the permissions of " + name + "!");
} else {
sender.sendMessage(TextUtils.prefix("You are not trusted!"));
}
} else {
sender.sendMessage(TextUtils.prefix("This command is not enabled!"));
}
return true;
} catch (Exception ex) {
CmdExHandler handler = new CmdExHandler(ex,command);
sender.sendMessage(handler.getErrorMessage());
return true;
p.sendMessage(TextUtils.prefix("§cYou are not trusted!"));
}
}
@Override
public void registerCompletions(CompletionBuilder builder) {
}
}

View File

@@ -0,0 +1,52 @@
package io.github.thetrouper.sentinel.commands;
import io.github.thetrouper.sentinel.server.functions.Message;
import io.github.thetrouper.sentinel.server.util.ArrayUtils;
import io.github.thetrouper.sentinel.server.util.TextUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class ReplyCommand extends CustomCommand {
public static Map<UUID, UUID> replyMap = MessageCommand.replyMap;
public ReplyCommand() {
super("reply");
this.setPrintStacktrace(true);
}
@Override
public void dispatchCommand(CommandSender sender, Command command, String label, String[] args) {
String name = sender.getName().toString();
Player p = sender.getServer().getPlayer(name);
UUID senderID = p.getUniqueId();
if (replyMap.get(senderID) == null) {
p.sendMessage(TextUtils.prefix("§cYou have nobody to reply to!"));
}
Player r = sender.getServer().getPlayer(replyMap.get(senderID));
UUID reciverID = r.getUniqueId();
if (args[0] == null) {
p.sendMessage(TextUtils.prefix("§cYou must provide a message to send!"));
}
String msg = String.join(" ", Arrays.asList(args));
if (p.hasPermission("sentinel.message")) {
Message.messagePlayer(p,r,msg);
replyMap.put(senderID,reciverID);
} else {
sender.sendMessage(TextUtils.prefix("Invalid Permissions!"));
}
}
@Override
public void registerCompletions(CompletionBuilder builder) {
builder.addCompletion(1,builder.args.length >= 2,new String[]{
"[<message>]"
});
}
}

View File

@@ -0,0 +1,38 @@
/**
* This file is for tutorial purposes made by ImproperIssues. Distribute if you want :)
*/
package io.github.thetrouper.sentinel.commands;
import io.github.thetrouper.sentinel.server.util.TextUtils;
import org.bukkit.command.*;
import org.bukkit.entity.Player;
/**
* Example command
*/
public class SentinelCommand extends CustomCommand {
public static boolean debugmode;
public SentinelCommand() {
super("sentinel");
}
@Override
public void dispatchCommand(CommandSender sender, Command command, String label, String[] args) {
Player p = (Player) sender;
switch (args[0]) {
case "debugmode" -> {
debugmode = !debugmode;
p.sendMessage(TextUtils.prefix(TextUtils.boolString(debugmode,"§aEnabled","§cDisabled") + "§7 debug mode."));
}
case "whitelistcommandblock" -> {
}
}
}
@Override
public void registerCompletions(CompletionBuilder builder) {
builder.addCompletion(1,"debugmode");
}
}

View File

@@ -0,0 +1,42 @@
package io.github.thetrouper.sentinel.commands;
import io.github.thetrouper.sentinel.server.functions.Message;
import io.github.thetrouper.sentinel.server.util.ArrayUtils;
import io.github.thetrouper.sentinel.server.util.TextUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class SocialSpyCommand extends CustomCommand {
public static Map<UUID, Boolean> spyMap = new HashMap<>();
public SocialSpyCommand() {
super("socialspy");
this.setPrintStacktrace(true);
}
@Override
public void dispatchCommand(CommandSender sender, Command command, String label, String[] args) {
String name = sender.getName().toString();
Player p = sender.getServer().getPlayer(name);
UUID senderID = p.getUniqueId();
if (!spyMap.containsKey(senderID) || !spyMap.get(senderID)) {
sender.sendMessage(TextUtils.prefix("SocialSpy is now enabled."));
spyMap.put(senderID,true);
}
if (spyMap.get(senderID)) {
sender.sendMessage(TextUtils.prefix("SocialSpy is now disabled."));
spyMap.put(senderID,false);
}
}
@Override
public void registerCompletions(CompletionBuilder builder) {
}
}

View File

@@ -1,60 +0,0 @@
package io.github.thetrouper.sentinel.commands;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.util.*;
public class TabComplBuilder {
private Map<Integer,List<String>> entries = new HashMap<>();
private final CommandSender sender;
private final Command command;
private final String alias;
private final String[] args;
public TabComplBuilder(CommandSender sender, Command command, String alias, String[] args) {
this.sender = sender;
this.command = command;
this.alias = alias;
this.args = args;
}
/**
* Adds to the tab completion
* @param atIndex should be a number above or equal to 1
* @param entry string array
* @param condition condition
*/
public TabComplBuilder add(int atIndex, String[] entry, boolean condition) {
if (condition) add(atIndex,entry);
return this;
}
/**
* Adds to the tab completion
* @param atIndex should be a number above or equal to 1
* @param entry string array
*/
public TabComplBuilder add(int atIndex, String[] entry) {
atIndex = Math.max(1,atIndex);
entries.put(atIndex,Arrays.stream(entry).toList());
return this;
}
public TabComplBuilder add(int atIndex, List<String> entry, boolean condition) {
if (condition) add(atIndex,entry);
return this;
}
public TabComplBuilder add(int atIndex, List<String> entry) {
entries.put(atIndex,entry);
return this;
}
public List<String> build() {
List<String> list = new ArrayList<>(entries.get(args.length) != null ? entries.get(args.length) : new ArrayList<>());
list.removeIf(s -> !s.toLowerCase().contains(args[args.length - 1].toLowerCase()));
return list;
}
}

View File

@@ -41,6 +41,7 @@ public abstract class Config {
public static List<String> dangerousCommands;
public static boolean logDangerousCommands;
public static List<String> loggedCommands;
public static boolean logSpecific;
public static boolean deop;
public static boolean nbtPunish;
public static boolean commandPunish;
@@ -82,6 +83,7 @@ public abstract class Config {
public static void loadConfiguration() {
Sentinel.prefix = config.getString("config.plugin.prefix");
Sentinel.key = config.getString("config.plugin.key");
// antiNuke
webhook = config.getString("config.plugin.webhook");
@@ -92,6 +94,7 @@ public abstract class Config {
preventCmdBlocks = config.getBoolean("config.plugin.prevent-cmdblocks");
logCmdBlocks = config.getBoolean("config.plugin.log-cmdblocks");
cmdBlockOpCheck = config.getBoolean("config.plugin.cmdblock-op-check");
logSpecific = config.getBoolean("config.plugin.log-specific");
dangerousCommands = config.getStringList("config.plugin.dangerous");
logDangerousCommands = config.getBoolean("config.plugin.log-dangerous");
loggedCommands = config.getStringList("config.plugin.logged");
@@ -126,12 +129,12 @@ public abstract class Config {
highScore = config.getInt("config.chat.anti-swear.high-score");
punishScore = config.getInt("config.chat.anti-swear.punish-score");
swearPunishCommand = config.getString("config.chat.anti-swear.punish-command");
slurInstaPunish = config.getBoolean("config.chat.anti-swear.slur-insta-punish");
slurPunishCommand = config.getString("config.chat.anti-swear.slur-command");
slurInstaPunish = config.getBoolean("config.chat.anti-swear.strict-insta-punish");
slurPunishCommand = config.getString("config.chat.anti-swear.strict-command");
scoreDecay = config.getInt("config.chat.anti-swear.score-decay");
swearWhitelist = config.getStringList("config.chat.anti-swear.whitelisted");
swearWhitelist = config.getStringList("config.chat.anti-swear.false-positives");
swearBlacklist = config.getStringList("config.chat.anti-swear.blacklisted");
slurs = config.getStringList("config.chat.anti-swear.slurs");
slurs = config.getStringList("config.chat.anti-swear.strict");
leetPatterns = loadLeetPatterns();
logSwear = config.getBoolean("config.chat.anti-swear.log-swear");

View File

@@ -0,0 +1,16 @@
package io.github.thetrouper.sentinel.events;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.ServerCommandEvent;
public class CMDBlockExecute implements Listener {
@EventHandler
private void onCMDBlockTick(ServerCommandEvent e) {
if (e.getSender() instanceof BlockCommandSender) {
}
}
}

View File

@@ -0,0 +1,27 @@
package io.github.thetrouper.sentinel.events;
import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.data.Config;
import io.github.thetrouper.sentinel.server.TakeAction;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
public class CMDBlockPlace implements Listener {
@EventHandler
private void onCMDBlockPlace(BlockPlaceEvent e) {
if (!Config.preventCmdBlocks) return;
if (Config.cmdBlockOpCheck && !e.getPlayer().isOp()) return;
Block b = e.getBlockPlaced();
if (b.getType() == Material.COMMAND_BLOCK || b.getType() == Material.CHAIN_COMMAND_BLOCK || b.getType() == Material.REPEATING_COMMAND_BLOCK ) {
Player p = e.getPlayer();
if (!Sentinel.isTrusted(p)) {
e.setCancelled(true);
TakeAction.placeBlock(e);
}
}
}
}

View File

@@ -0,0 +1,26 @@
package io.github.thetrouper.sentinel.events;
import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.data.Config;
import io.github.thetrouper.sentinel.server.TakeAction;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
public class CMDBlockUse implements Listener {
private void onCMDBlockUse(PlayerInteractEvent e) {
if (!Config.preventCmdBlocks) return;
if (Config.cmdBlockOpCheck && !e.getPlayer().isOp()) return;
if (e.getClickedBlock() == null) return;
Block b = e.getClickedBlock();
if (b.getType() == Material.COMMAND_BLOCK || b.getType() == Material.REPEATING_COMMAND_BLOCK || b.getType() == Material.CHAIN_COMMAND_BLOCK) {
Player p = e.getPlayer();
if (!Sentinel.isTrusted(p)) {
e.setCancelled(true);
TakeAction.useBlock(e);
}
}
}
}

View File

@@ -0,0 +1,33 @@
package io.github.thetrouper.sentinel.events;
import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.data.Config;
import io.github.thetrouper.sentinel.server.TakeAction;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent;
public class CMDMinecartPlace implements Listener {
@EventHandler
private void onCMDMinecartPlace(PlayerInteractEvent e) {
if (!Config.preventCmdBlocks) {
if (Config.cmdBlockOpCheck && !e.getPlayer().isOp()) return;
if (e.getItem() == null) return;
if (e.getClickedBlock() == null) return;
if (!e.getItem().getType().equals(Material.COMMAND_BLOCK_MINECART)) return;
if (e.getClickedBlock().getType() == Material.RAIL || e.getClickedBlock().getType() == Material.POWERED_RAIL || e.getClickedBlock().getType() == Material.ACTIVATOR_RAIL || e.getClickedBlock().getType() == Material.DETECTOR_RAIL) {
Player p = e.getPlayer();
if (!Sentinel.isTrusted(p)) {
e.setCancelled(true);
p.getInventory().remove(Material.COMMAND_BLOCK_MINECART);
TakeAction.useBlock(e);
}
}
}
}
}

View File

@@ -0,0 +1,25 @@
package io.github.thetrouper.sentinel.events;
import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.data.Config;
import io.github.thetrouper.sentinel.server.TakeAction;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEntityEvent;
public class CMDMinecartUse implements Listener {
@EventHandler
private void onCMDBlockMinecartUse(PlayerInteractEntityEvent e) {
if (!Config.preventCmdBlocks) return;
if (Config.cmdBlockOpCheck && !e.getPlayer().isOp()) return;
if (e.getRightClicked().getType() == EntityType.MINECART_COMMAND) {
Player p = e.getPlayer();
if (!Sentinel.isTrusted(p)) {
e.setCancelled(true);
TakeAction.useEntity(e);
}
}
}
}

View File

@@ -1,73 +0,0 @@
package io.github.thetrouper.sentinel.events;
import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.data.Config;
import io.github.thetrouper.sentinel.server.TakeAction;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
public class CmdBlockEvents implements Listener {
@EventHandler
private void onCMDBlockUse(PlayerInteractEvent e) {
if (!Config.preventCmdBlocks) return;
if (Config.cmdBlockOpCheck && !e.getPlayer().isOp()) return;
if (e.getClickedBlock() == null) return;
Block b = e.getClickedBlock();
if (b.getType() == Material.COMMAND_BLOCK || b.getType() == Material.REPEATING_COMMAND_BLOCK || b.getType() == Material.CHAIN_COMMAND_BLOCK) {
Player p = e.getPlayer();
if (!Sentinel.isTrusted(p)) {
e.setCancelled(true);
TakeAction.useBlock(e);
}
}
}
@EventHandler
private void onCMDBlockPlace(BlockPlaceEvent e) {
if (!Config.preventCmdBlocks) return;
if (Config.cmdBlockOpCheck && !e.getPlayer().isOp()) return;
Block b = e.getBlockPlaced();
if (b.getType() == Material.COMMAND_BLOCK || b.getType() == Material.CHAIN_COMMAND_BLOCK || b.getType() == Material.REPEATING_COMMAND_BLOCK ) {
Player p = e.getPlayer();
if (!Sentinel.isTrusted(p)) {
e.setCancelled(true);
TakeAction.placeBlock(e);
}
}
}
@EventHandler
private void onCMDBlockMinecartUse(PlayerInteractEntityEvent e) {
if (!Config.preventCmdBlocks) return;
if (Config.cmdBlockOpCheck && !e.getPlayer().isOp()) return;
if (e.getRightClicked().getType() == EntityType.MINECART_COMMAND) {
Player p = e.getPlayer();
if (!Sentinel.isTrusted(p)) {
e.setCancelled(true);
TakeAction.useEntity(e);
}
}
}
@EventHandler
private void onCMDBlockMinecartPlace(PlayerInteractEvent e) {
if (!Config.preventCmdBlocks) {
if (Config.cmdBlockOpCheck && !e.getPlayer().isOp()) return;
if (e.getItem() == null) return;
if (e.getClickedBlock() == null) return;
if (!e.getItem().getType().equals(Material.COMMAND_BLOCK_MINECART)) return;
if (e.getClickedBlock().getType() == Material.RAIL || e.getClickedBlock().getType() == Material.POWERED_RAIL || e.getClickedBlock().getType() == Material.ACTIVATOR_RAIL || e.getClickedBlock().getType() == Material.DETECTOR_RAIL) {
Player p = e.getPlayer();
if (!Sentinel.isTrusted(p)) {
e.setCancelled(true);
p.getInventory().remove(Material.COMMAND_BLOCK_MINECART);
TakeAction.useBlock(e);
}
}
}
}
}

View File

@@ -40,9 +40,7 @@ public class CommandEvent implements Listener {
}
}
if (Sentinel.isLoggedCommand(command)) {
NotifyConsole.command(p,command,false,false,false,true);
NotifyDiscord.command(p,command,false,false,false,true);
NotifyTrusted.command(p,command,false,false,false,true);
TakeAction.logged(e);
}
}
}

View File

@@ -1,46 +0,0 @@
/**
* This file is for tutorial purposes made by ImproperIssues. Distribute if you want :)
*/
package io.github.thetrouper.sentinel.exceptions;
import org.bukkit.command.Command;
/**
* Handles a command exception
*/
public class CmdExHandler {
private Exception exception;
private Command command;
/**
* Constructs the command exception
* @param exception the exception caught
* @param command the command run
*/
public CmdExHandler(Exception exception, Command command) {
this.exception = exception;
this.command = command;
}
/**
* Returns the error message
* @return the error message
*/
public String getErrorMessage() {
String msg = "§cCommand Error: ";
if (exception instanceof NullPointerException) msg += "Command contains a null value!";
else if (exception instanceof IndexOutOfBoundsException) msg += "Unknown or incomplete command!";
else msg += exception.getMessage();
return msg + "\n§cCorrect usage: §7" + command.getUsage();
}
public Exception getException() {
return exception;
}
public Command getCommand() {
return command;
}
}

View File

@@ -59,7 +59,7 @@ public class TakeAction {
}
punished = true;
}
if (Config.logDangerousCommands) {
if (Config.logSpecific) {
logged = true;
NotifyDiscord.specific(e.getPlayer(),message,denied,deoped,punished,true);
}
@@ -115,9 +115,9 @@ public class TakeAction {
String message = e.getMessage();
String command = e.getMessage().substring(1).split(" ")[0];
if (Sentinel.isLoggedCommand(command)) {
NotifyDiscord.command(e.getPlayer(),message,denied,deoped,punished,true);
NotifyConsole.command(e.getPlayer(),message,denied,deoped,punished,logged);
NotifyTrusted.command(e.getPlayer(),message,denied,deoped,punished,logged);
NotifyDiscord.logged(e.getPlayer(),message,denied,deoped,punished,true);
NotifyConsole.logged(e.getPlayer(),message,denied,deoped,punished,logged);
NotifyTrusted.logged(e.getPlayer(),message,denied,deoped,punished,logged);
}
}
public static void NBT(InventoryCreativeEvent e) {

View File

@@ -0,0 +1,37 @@
package io.github.thetrouper.sentinel.server.functions;
import io.github.thetrouper.sentinel.commands.MessageCommand;
import io.github.thetrouper.sentinel.commands.SocialSpyCommand;
import io.github.thetrouper.sentinel.server.util.ServerUtils;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.hover.content.Text;
import org.bukkit.entity.Player;
import java.util.Map;
import java.util.UUID;
public class Message {
private static Map<UUID,UUID> replyMap = MessageCommand.replyMap;
public static void messagePlayer(Player sender, Player receiver, String message) {
sender.sendMessage("§d§lMessage §8» §b[§fYou §e>§f " + receiver.getName() + "§b] §7" + message);
receiver.sendMessage("§d§lMessage §8» §b[§f" + sender.getName() + " §e>§f You§b] §7" + message);
replyMap.put(receiver.getUniqueId(),sender.getUniqueId());
sendSpy(sender,receiver,message);
}
public static void sendSpy(Player sender, Player receiver, String message) {
ServerUtils.forEachPlayer(player -> {
if (SocialSpyCommand.spyMap.getOrDefault(player.getUniqueId(),false)) {
TextComponent notification = new TextComponent("§d§lSpy §8» §b§n" + sender.getName() + "§7 has messaged §b§n " + receiver.getName() + "§7.");
notification.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(
"§8]==-- §d§lSocialSpy §8--==[" +
"\n§bSender: §f" + sender.getName() +
"\n§bReceiver: §f" + receiver.getName() +
"\n§bMessage: §f" + message
)));
player.spigot().sendMessage(notification);
}
});
}
}

View File

@@ -1,18 +1,16 @@
package io.github.thetrouper.sentinel.server.util;
import io.github.thetrouper.sentinel.Sentinel;
import io.github.thetrouper.sentinel.commands.InfoCommand;
import io.github.thetrouper.sentinel.commands.SentinelCommand;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -29,7 +27,7 @@ public class ServerUtils {
},1);
}
public static void sendDebugMessage(String message) {
if (InfoCommand.debugmode) {
if (SentinelCommand.debugmode) {
Sentinel.log.info(message);
for (Player trustedPlayer : Bukkit.getOnlinePlayers()) {
if (Sentinel.isTrusted(trustedPlayer)) {

View File

@@ -67,10 +67,6 @@ public class TextUtils {
return msg;
}
public static String boolString(boolean bool, String caseTrue, String caseFalse) {
if (bool) {
return caseTrue;
} else {
return caseFalse;
}
return bool ? caseTrue : caseFalse;
}
}

View File

@@ -9,7 +9,7 @@
# ]======------ Configuration & Setup Guide ------=====[
# Sentinel is inspired by WickBot.com
# Be sure to check out their amazing discord bot!
config :
config:
plugin:
key: "beta" # if you are a beta tester, leave this value as "beta"
# --------------------------------
@@ -79,11 +79,11 @@ config :
high-score: 7 # Default 7 | How much score should be gained for "extreme" attempt to bypass
score-decay: 3 # Default 3 | Rate at which score is lost every minute
punish-score: 20 # Default 20 | how much score is required to get punished
slur-insta-punish: true # Default true | Should players get insta punished for any words on the "slurs" list?
strict-insta-punish: true # Default true | Should players get insta punished for any words on the "strict" list?
punish-command: "mute %player% 15m Do not attempt to bypass the Profanity Filter"
slur-command: "mute %player% 1h Discriminatory speech is not tolerated on this server!"
strict-command: "mute %player% 1h Discriminatory speech is not tolerated on this server!"
log-swear: true # Default true | Logs swear punishments to the webhook
whitelisted:
false-positives: # Words that will falsly flag the anti-swear
- but then
- was scamming
- an alt
@@ -138,7 +138,7 @@ config :
- shoe
- stitch
- therapist
blacklisted:
blacklisted: # Swears to check for
- anal
- anus
- arse
@@ -217,7 +217,7 @@ config :
- vagina
- wank
- whore
slurs:
strict: # Very bad words to insta-punish for
- nigg
- niger
- nlgg
@@ -226,7 +226,7 @@ config :
- tranny
- fag
- beaner
leet-patterns:
leet-patterns: # Replacement patterns for "l33t" strings
'0': o
'1': i
'3': e

View File

@@ -6,6 +6,11 @@ authors: [ TheTrouper ]
description: Detect Block and Ban players who attempt to grief your server.
website: https://thetrouper.github.io/
permissions:
sentinel.message:
description: Access to the direct messages
default: op
sentinel.reply:
description: Reply commands
sentinel.debug:
description: Permission to use debug commands
default: op
@@ -34,10 +39,53 @@ permissions:
sentinel.chat.antispam.bypass: true
commands:
sentinel:
description: An info command.
description: A command for testing.
usage: /sentinel
permission: sentinel.info
permission-message: You do not have permission!
reop:
description: Allows trusted players to elevate their permissions
usage: /reop
socialspy:
permission: sentinel.spy
usage: /socialspy
permission-message: You do not have permission to use this command!
description: View direct messages sent between players
aliases:
- spy
- sspy
msg:
permission: sentinel.message
usage: /msg <player> [<message>]
permission-message: You do not have permission to message through sentinel!
description: Send messages directly to players
aliases:
- message
- etell
- tell
- t
- ewhisper
- whisper
- w
- privatemessage
- pm
- m
- directmessage
- dm
- sentinelmessage
- sm
- stell
- smsg
reply:
description: Reply to the last person messaging you
usage: /r [<message>]
permission: sentinel.reply
permission-message: You do not have permission to reply through sentinel!
aliases:
- r
- er
- rply
- ereply
- sr
- sreply
- sentinelreply