Fixed some typos in the GUI, added logging for false positive editing, fixed auto-similarity based blocking, and fixed logging related to such.
This commit is contained in:
@@ -1,140 +0,0 @@
|
||||
package io.github.thetrouper.sentinel;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import io.github.itzispyder.pdk.PDK;
|
||||
import io.github.itzispyder.pdk.utils.misc.JsonSerializable;
|
||||
import io.github.thetrouper.sentinel.data.cmdblocks.WhitelistStorage;
|
||||
import io.github.thetrouper.sentinel.data.config.*;
|
||||
import io.github.thetrouper.sentinel.server.functions.Authenticator;
|
||||
import io.github.thetrouper.sentinel.server.functions.Load;
|
||||
import io.github.thetrouper.sentinel.server.functions.Telemetry;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public final class Sentinel extends JavaPlugin {
|
||||
|
||||
private static Sentinel instance;
|
||||
private static final File cfgfile = new File("plugins/Sentinel/main-config.json");
|
||||
private static final File nbtcfg = new File("plugins/Sentinel/nbt-config.json");
|
||||
private static final File strctcfg = new File("plugins/Sentinel/strict.json");
|
||||
private static final File swrcfg = new File("plugins/Sentinel/swears.json");
|
||||
private static final File fpcfg = new File("plugins/Sentinel/false-positives.json");
|
||||
private static final File advcfg = new File("plugins/Sentinel/advanced-config.json");
|
||||
private static final File cmdWhitelist = new File("plugins/Sentinel/storage/whitelist.json");
|
||||
public static WhitelistStorage whitelist = JsonSerializable.load(cmdWhitelist, WhitelistStorage.class, new WhitelistStorage());
|
||||
|
||||
public static MainConfig mainConfig = JsonSerializable.load(cfgfile, MainConfig.class, new MainConfig());
|
||||
public static FPConfig fpConfig = JsonSerializable.load(fpcfg, FPConfig.class, new FPConfig());
|
||||
public static SwearsConfig swearConfig = JsonSerializable.load(swrcfg, SwearsConfig.class, new SwearsConfig());
|
||||
public static StrictConfig strictConfig = JsonSerializable.load(strctcfg, StrictConfig.class, new StrictConfig());
|
||||
public static NBTConfig nbtConfig = JsonSerializable.load(nbtcfg, NBTConfig.class, new NBTConfig());
|
||||
public static AdvancedConfig advConfig = JsonSerializable.load(advcfg, AdvancedConfig.class, new AdvancedConfig());
|
||||
public static LanguageFile lang;
|
||||
public static ProtocolManager protocolManager;
|
||||
public static final PluginManager manager = Bukkit.getPluginManager();
|
||||
|
||||
public static final Logger log = Bukkit.getLogger();
|
||||
public static boolean usesDynamicIP;
|
||||
public static String serverID;
|
||||
public static String license;
|
||||
public static String IP;
|
||||
public static boolean doNoPlugins = false;
|
||||
|
||||
Load load = new Load();
|
||||
|
||||
/**
|
||||
* Plugin startup logic
|
||||
*/
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
||||
log.info("\n]======------ Pre-load started! ------======[");
|
||||
PDK.init(this);
|
||||
instance = this;
|
||||
|
||||
log.info("Loading Config...");
|
||||
|
||||
loadConfig();
|
||||
|
||||
log.info("Loading ProtocolLib");
|
||||
|
||||
if (Bukkit.getServer().getPluginManager().isPluginEnabled("ProtocolLib") && mainConfig.plugin.pluginHider) {
|
||||
doNoPlugins = true;
|
||||
protocolManager = ProtocolLibrary.getProtocolManager();
|
||||
} else {
|
||||
doNoPlugins = false;
|
||||
log.warning("Sentinel: ProtocolLib not found. Sentinel will not attempt to hide your plugins.");
|
||||
}
|
||||
|
||||
log.info("Language Status: (%s)".formatted(lang.brokenLang));
|
||||
|
||||
log.info("Initializing Server ID...");
|
||||
serverID = Authenticator.getServerID();
|
||||
|
||||
license = mainConfig.plugin.license;
|
||||
|
||||
log.info("Pre-load finished!\n]====---- Requesting Authentication ----====[ \n- License Key: %s\n- Server ID: %s".formatted(license,serverID));
|
||||
|
||||
load.load(license,serverID);
|
||||
}
|
||||
|
||||
public void loadConfig() {
|
||||
|
||||
// Init
|
||||
mainConfig = JsonSerializable.load(cfgfile,MainConfig.class,new MainConfig());
|
||||
advConfig = JsonSerializable.load(advcfg,AdvancedConfig.class,new AdvancedConfig());
|
||||
fpConfig = JsonSerializable.load(fpcfg,FPConfig.class,new FPConfig());
|
||||
strictConfig = JsonSerializable.load(strctcfg,StrictConfig.class,new StrictConfig());
|
||||
swearConfig = JsonSerializable.load(swrcfg,SwearsConfig.class,new SwearsConfig());
|
||||
nbtConfig = JsonSerializable.load(nbtcfg,NBTConfig.class,new NBTConfig());
|
||||
|
||||
|
||||
// Save
|
||||
mainConfig.save();
|
||||
advConfig.save();
|
||||
fpConfig.save();
|
||||
strictConfig.save();
|
||||
swearConfig.save();
|
||||
nbtConfig.save();
|
||||
|
||||
whitelist = JsonSerializable.load(cmdWhitelist, WhitelistStorage.class, new WhitelistStorage());
|
||||
whitelist.save();
|
||||
|
||||
log.info("Loading Dictionary (%s)...".formatted(Sentinel.mainConfig.plugin.lang));
|
||||
|
||||
lang = JsonSerializable.load(LanguageFile.PATH,LanguageFile.class,new LanguageFile());
|
||||
lang.save();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Plugin shutdown logic
|
||||
*/
|
||||
@Override
|
||||
public void onDisable() {
|
||||
// Plugin shutdown logic
|
||||
log.info("Sentinel has disabled! (%s) Your server is now no longer protected!".formatted(getDescription().getVersion()));
|
||||
if (usesDynamicIP) {
|
||||
Telemetry.sendShutdownLog();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isTrusted(Player player) {
|
||||
return Sentinel.mainConfig.plugin.trustedPlayers.contains(player.getUniqueId().toString());
|
||||
}
|
||||
|
||||
public static boolean isTrusted(String uuid) {
|
||||
return Sentinel.mainConfig.plugin.trustedPlayers.contains(uuid);
|
||||
}
|
||||
|
||||
public static Sentinel getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,322 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.auth;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Auth {
|
||||
public
|
||||
Auth(
|
||||
|
||||
) throws
|
||||
UnknownHostException
|
||||
{
|
||||
}
|
||||
private
|
||||
static
|
||||
final
|
||||
String
|
||||
ENCRYPTION_KEY
|
||||
=
|
||||
"If I am reading this and I am not a verified developer for Sentinel AntiNuke, I solely swear that my attempts to de-obfuscate this plugin are purely for investigation, and have no malicious intentions such as cracking, leaking, or ratting this plugin.";
|
||||
private
|
||||
static
|
||||
final
|
||||
String
|
||||
ENCRYPTION_ALGORITHM
|
||||
=
|
||||
"AES";
|
||||
private
|
||||
static
|
||||
final
|
||||
String
|
||||
ENCRYPTION_MODE_PADDING
|
||||
=
|
||||
"AES/ECB/PKCS5Padding";
|
||||
static
|
||||
InetAddress
|
||||
IP;
|
||||
|
||||
static
|
||||
{
|
||||
try
|
||||
{
|
||||
IP
|
||||
=
|
||||
InetAddress
|
||||
.
|
||||
getLocalHost
|
||||
(
|
||||
|
||||
)
|
||||
;
|
||||
|
||||
}
|
||||
catch
|
||||
(
|
||||
UnknownHostException
|
||||
e
|
||||
)
|
||||
{
|
||||
throw
|
||||
new
|
||||
RuntimeException
|
||||
(
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public
|
||||
static
|
||||
String
|
||||
authorize
|
||||
(
|
||||
String
|
||||
licenseKey
|
||||
,
|
||||
String serverID
|
||||
)
|
||||
{
|
||||
|
||||
String
|
||||
authStatus
|
||||
=
|
||||
"";
|
||||
List<String>
|
||||
lines
|
||||
= new
|
||||
ArrayList<>();
|
||||
lines
|
||||
.add
|
||||
(
|
||||
"Nothing"
|
||||
)
|
||||
;
|
||||
lines.
|
||||
add
|
||||
(
|
||||
"To"
|
||||
)
|
||||
;
|
||||
lines.
|
||||
add
|
||||
(
|
||||
"See"
|
||||
)
|
||||
;
|
||||
lines.
|
||||
add
|
||||
(
|
||||
"Here"
|
||||
|
||||
+
|
||||
ENCRYPTION_MODE_PADDING
|
||||
);
|
||||
lines.
|
||||
add
|
||||
(
|
||||
"Get"
|
||||
+
|
||||
ENCRYPTION_ALGORITHM
|
||||
);
|
||||
lines.
|
||||
add
|
||||
(
|
||||
"Out"
|
||||
+
|
||||
ENCRYPTION_KEY
|
||||
);
|
||||
|
||||
for
|
||||
(
|
||||
String
|
||||
line
|
||||
:
|
||||
lines
|
||||
)
|
||||
{
|
||||
if
|
||||
(
|
||||
line
|
||||
.
|
||||
contains
|
||||
(
|
||||
"get-out-of-here"
|
||||
)
|
||||
)
|
||||
{
|
||||
String
|
||||
key
|
||||
=
|
||||
extractValue
|
||||
(
|
||||
line
|
||||
,
|
||||
"time-waster"
|
||||
);
|
||||
String
|
||||
allowedIDs
|
||||
=
|
||||
extractValue
|
||||
(
|
||||
line
|
||||
,
|
||||
"no-skidding-allowed"
|
||||
);
|
||||
String[]
|
||||
allowedArr
|
||||
=
|
||||
allowedIDs
|
||||
.
|
||||
split
|
||||
(
|
||||
":"
|
||||
)
|
||||
;
|
||||
if (
|
||||
key
|
||||
.
|
||||
equals
|
||||
(
|
||||
licenseKey
|
||||
)
|
||||
)
|
||||
{
|
||||
if
|
||||
(
|
||||
Arrays
|
||||
.
|
||||
asList
|
||||
(
|
||||
allowedArr
|
||||
)
|
||||
.
|
||||
contains
|
||||
(
|
||||
serverID
|
||||
)
|
||||
)
|
||||
{
|
||||
authStatus
|
||||
=
|
||||
"ID:10T"
|
||||
;
|
||||
return
|
||||
authStatus
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
if
|
||||
(
|
||||
Arrays
|
||||
.
|
||||
asList
|
||||
(
|
||||
allowedArr
|
||||
)
|
||||
.
|
||||
contains
|
||||
(
|
||||
"minehut"
|
||||
)
|
||||
)
|
||||
{
|
||||
authStatus
|
||||
=
|
||||
"TROLLADGE"
|
||||
;
|
||||
return
|
||||
authStatus
|
||||
;
|
||||
}
|
||||
authStatus
|
||||
=
|
||||
"INVALID-BRAIN"
|
||||
;
|
||||
return
|
||||
authStatus
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if
|
||||
(
|
||||
authStatus.isEmpty
|
||||
(
|
||||
)
|
||||
)
|
||||
{
|
||||
authStatus
|
||||
=
|
||||
"BRAINLESS-NERD"
|
||||
;
|
||||
return
|
||||
authStatus
|
||||
;
|
||||
}
|
||||
return
|
||||
authStatus
|
||||
;
|
||||
}
|
||||
|
||||
public
|
||||
static String
|
||||
extractValue
|
||||
(
|
||||
String
|
||||
line
|
||||
,
|
||||
String
|
||||
attribute
|
||||
)
|
||||
{
|
||||
int
|
||||
start
|
||||
=
|
||||
line
|
||||
.
|
||||
indexOf
|
||||
(
|
||||
attribute
|
||||
+
|
||||
"=\""
|
||||
)
|
||||
+
|
||||
attribute
|
||||
.
|
||||
length(
|
||||
|
||||
)
|
||||
+
|
||||
2
|
||||
;
|
||||
int
|
||||
end
|
||||
=
|
||||
line
|
||||
.
|
||||
indexOf
|
||||
(
|
||||
"\""
|
||||
,
|
||||
start
|
||||
)
|
||||
;
|
||||
return
|
||||
line
|
||||
.
|
||||
substring
|
||||
(
|
||||
start
|
||||
,
|
||||
end
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.cmds;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.commands.CommandRegistry;
|
||||
import io.github.itzispyder.pdk.commands.CustomCommand;
|
||||
import io.github.itzispyder.pdk.commands.Permission;
|
||||
import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
|
||||
import io.github.itzispyder.pdk.utils.misc.Cooldown;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.Report;
|
||||
import io.github.thetrouper.sentinel.server.functions.ReportFalsePositives;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@CommandRegistry(value = "sentinelcallback", permission = @Permission("sentinel.callbacks"), printStackTrace = true)
|
||||
public class ChatClickCallback implements CustomCommand {
|
||||
Cooldown<UUID> fpReportCooldown = new Cooldown<>();
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender sender, Args args) {
|
||||
Player p = (Player) sender;
|
||||
switch (args.get(0).toString()) {
|
||||
case "fpreport" -> {
|
||||
if (fpReportCooldown.isOnCooldown(p.getUniqueId()) && !p.isOp()) {
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.cooldown.onCooldown + fpReportCooldown.getCooldown(p.getUniqueId())));
|
||||
} else {
|
||||
long id = args.get(1).toLong();
|
||||
Report send = ReportFalsePositives.reports.get(id);
|
||||
if (send == null) {
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.reports.noReport));
|
||||
return;
|
||||
}
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.reports.reportingFalsePositive));
|
||||
ReportFalsePositives.sendFalsePositiveReport(send);
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.reports.falsePositiveSuccess));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCompletions(CompletionBuilder b) {
|
||||
b.then(b.arg("a_you","b_must","c_be","d_called","e_before","f_running","g_a","h_callback"));
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.cmds;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.commands.CommandRegistry;
|
||||
import io.github.itzispyder.pdk.commands.CustomCommand;
|
||||
import io.github.itzispyder.pdk.commands.Permission;
|
||||
import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
|
||||
import io.github.itzispyder.pdk.utils.ArrayUtils;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.server.functions.Message;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@CommandRegistry(value = "sentinelmessage",permission = @Permission("sentinel.message"))
|
||||
public class MessageCommand implements CustomCommand {
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender sender, Args args) {
|
||||
Player p = (Player) sender;
|
||||
Player r = null;
|
||||
if (args.getSize() == 0) {
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.playerInteraction.noOnlinePlayer));
|
||||
return;
|
||||
}
|
||||
if (args.getSize() == 1) {
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.playerInteraction.noMessageProvided));
|
||||
return;
|
||||
}
|
||||
r = Bukkit.getPlayer(args.get(0).toString());
|
||||
|
||||
String msg = args.getAll(1).toString().trim();
|
||||
|
||||
if (p.hasPermission("sentinel.message") && r != null) {
|
||||
Message.messagePlayer(p,r,msg);
|
||||
} else if (r == null) p.sendMessage(Text.prefix((Sentinel.lang.playerInteraction.noOnlinePlayer)));
|
||||
else sender.sendMessage(Text.prefix(Sentinel.lang.permissions.noPermission));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCompletions(CompletionBuilder b) {
|
||||
b.then(b.arg(ArrayUtils.toNewList(Bukkit.getOnlinePlayers(), Player::getName))
|
||||
.then(b.arg("[<Message>]")));
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.cmds;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.commands.CommandRegistry;
|
||||
import io.github.itzispyder.pdk.commands.CustomCommand;
|
||||
import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@CommandRegistry(value = "reop")
|
||||
public class ReopCommand implements CustomCommand {
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender sender, Args args) {
|
||||
Player p = (Player) sender;
|
||||
if (Sentinel.isTrusted(p) && Sentinel.mainConfig.plugin.reopCommand) {
|
||||
if (!p.isOp()) {
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.permissions.elevatingPerms));
|
||||
Sentinel.log.info(Sentinel.lang.permissions.logElevatingPerms.formatted(p.getName()));
|
||||
p.setOp(true);
|
||||
} else {
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.permissions.alreadyOp));
|
||||
Sentinel.log.info(Sentinel.lang.permissions.logAlreadyOp.formatted(p.getName()));
|
||||
p.setOp(true);
|
||||
}
|
||||
} else {
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.permissions.noTrust));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCompletions(CompletionBuilder completionBuilder) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.cmds;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.commands.CommandRegistry;
|
||||
import io.github.itzispyder.pdk.commands.CustomCommand;
|
||||
import io.github.itzispyder.pdk.commands.Permission;
|
||||
import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.server.functions.Message;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@CommandRegistry(value = "reply", permission = @Permission("sentinel.reply"))
|
||||
public class ReplyCommand implements CustomCommand {
|
||||
public static Map<UUID, UUID> replyMap = Message.replyMap;
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender sender, Args args) {
|
||||
String name = sender.getName();
|
||||
Player p = sender.getServer().getPlayer(name);
|
||||
UUID senderID = p.getUniqueId();
|
||||
if (replyMap.get(senderID) == null) {
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.playerInteraction.noReply));
|
||||
}
|
||||
Player r = sender.getServer().getPlayer(replyMap.get(senderID));
|
||||
UUID reciverID = r.getUniqueId();
|
||||
if (args.get(0).toString() == null) {
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.playerInteraction.noMessageProvided));
|
||||
}
|
||||
String msg = args.getAll().toString();
|
||||
if (p.hasPermission("sentinel.message")) {
|
||||
Message.messagePlayer(p,r,msg);
|
||||
replyMap.put(senderID,reciverID);
|
||||
} else {
|
||||
sender.sendMessage(Text.prefix(Sentinel.lang.permissions.noPermission));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCompletions(CompletionBuilder b) {
|
||||
b.then(b.arg("[<Message>]"));
|
||||
}
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.cmds;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.commands.CommandRegistry;
|
||||
import io.github.itzispyder.pdk.commands.CustomCommand;
|
||||
import io.github.itzispyder.pdk.commands.Permission;
|
||||
import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.cmdblocks.WhitelistedBlock;
|
||||
import io.github.thetrouper.sentinel.server.functions.*;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.CommandBlock;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@CommandRegistry(value = "sentinel",printStackTrace = true)
|
||||
public class SentinelCommand implements CustomCommand {
|
||||
public static boolean debugMode;
|
||||
public static List<UUID> autoWhitelist = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender commandSender, Args args) {
|
||||
Sentinel instance = Sentinel.getInstance();
|
||||
if (Load.lite) {
|
||||
commandSender.sendMessage(Text.color("""
|
||||
&8]=-&f Welcome to &d&lSentinel &7|&f Anti-Nuke &8-=[
|
||||
&7The plugin is currently loaded in &clite&7 mode.
|
||||
|
||||
&fIf you have just &apurchased&f the plugin:
|
||||
&8- &7Join the &b&ndiscord&r&7 and open a ticket.
|
||||
&8- &7https://discord.gg/Xh6BAzNtxY
|
||||
&8- &7You will then receive a license key.
|
||||
&fIf you have &cnot&f purchased the plugin:
|
||||
&8- &7Then purchase it :D
|
||||
&8- &7It wont do anything in this state!
|
||||
&8- &7(Its only 5$)
|
||||
&fIf you are reading this from a decompiler:
|
||||
&8- &7Please stop trying to crack the plugin and purchase it!
|
||||
&8- &7Your time spent trying trying to bypass my DRM could be spent at a minimum wage job.
|
||||
&8- &7There you will make 7$ an hour! (As oppose to 5$ for multiple hours of cracking)
|
||||
&fWoah! You read quite far!
|
||||
&8- &7Want the plugin for cheaper, &nor even for free&r&7?
|
||||
&8- &7DM &b@obvwolf&7 on discord and lets make a deal!
|
||||
"""));
|
||||
return;
|
||||
}
|
||||
Player p = (Player) commandSender;
|
||||
if (!p.hasPermission("sentinel.staff")) return;
|
||||
switch (args.get(0).toString()) {
|
||||
case "commandblock", "cb" -> handleCommandBlock(p,args);
|
||||
case "reload" -> {
|
||||
if (!Sentinel.isTrusted(p)) return;
|
||||
p.sendMessage(Text.prefix("Reloading Sentinel!"));
|
||||
Sentinel.log.info("[Sentinel] Re-Initializing Sentinel!");
|
||||
instance.loadConfig();
|
||||
}
|
||||
case "full-system-check" -> {
|
||||
if (!Sentinel.isTrusted(p)) return;
|
||||
p.sendMessage(Text.prefix("Initiating a full system check!"));
|
||||
SystemCheck.fullCheck(p);
|
||||
}
|
||||
case "debug" -> handleDebugCommand(p,args);
|
||||
case "false-positive" -> handleFalsePositive(p,args);
|
||||
}
|
||||
}
|
||||
private void handleFalsePositive(Player p, Args args) {
|
||||
String falsePositive = args.getAll(2).toString();
|
||||
switch (args.get(1).toString()) {
|
||||
case "add" -> {
|
||||
Sentinel.fpConfig.swearWhitelist.add(falsePositive);
|
||||
p.sendMessage(Text.prefix("&7Successfully added &a%s&7 to the false positive list!".formatted(falsePositive)));
|
||||
}
|
||||
case "remove" -> {
|
||||
Sentinel.fpConfig.swearWhitelist.remove(falsePositive);
|
||||
p.sendMessage(Text.prefix("&7Successfully removed &c%s&7 to the false positive list!".formatted(falsePositive)));
|
||||
}
|
||||
}
|
||||
Sentinel.fpConfig.save();
|
||||
}
|
||||
private void handleCommandBlock(Player p, Args args) {
|
||||
if (!Sentinel.isTrusted(p)) return;
|
||||
Block target = p.getTargetBlock(Set.of(Material.AIR),10);
|
||||
switch (args.get(1).toString()) {
|
||||
case "add" -> {
|
||||
if (target.getType().equals(Material.COMMAND_BLOCK) || target.getType().equals(Material.REPEATING_COMMAND_BLOCK) || target.getType().equals(Material.CHAIN_COMMAND_BLOCK)) {
|
||||
CommandBlock cb = (CommandBlock) target.getState();
|
||||
CMDBlockWhitelist.add(cb,p.getUniqueId());
|
||||
return;
|
||||
}
|
||||
p.sendMessage(Text.prefix("Could not whitelist the &b" + Text.cleanName(target.getType().toString()) + "&7 it is not a command block!"));
|
||||
}
|
||||
case "remove" -> {
|
||||
WhitelistedBlock wb = CMDBlockWhitelist.get(target.getLocation());
|
||||
if (wb != null) {
|
||||
CMDBlockWhitelist.remove(target.getLocation());
|
||||
p.sendMessage(Text.prefix("Successfully removed 1 &b" + Text.cleanName(WhitelistedBlock.fromSerialized(wb.loc()).getBlock().getType().toString()) + "&7 with the command &a" + wb.command() + "&7."));
|
||||
return;
|
||||
}
|
||||
p.sendMessage(Text.prefix("Could not un-whitelist the &b" + Text.cleanName(target.getType().toString()) + "&7 it wasn't whitelisted in the first place!"));
|
||||
}
|
||||
case "auto" -> {
|
||||
if (autoWhitelist.contains(p.getUniqueId())) {
|
||||
autoWhitelist.remove(p.getUniqueId());
|
||||
p.sendMessage(Text.prefix("Successfully toggled &bauto whitelist&7 off for you."));
|
||||
} else {
|
||||
autoWhitelist.add(p.getUniqueId());
|
||||
p.sendMessage(Text.prefix("Successfully toggled &bauto whitelist&7 on for you."));
|
||||
}
|
||||
}
|
||||
case "restore" -> {
|
||||
if (args.get(2).toString().equals("all")) {
|
||||
int result = CMDBlockWhitelist.restoreAll();
|
||||
p.sendMessage(Text.prefix("Successfully restored &b%s&7 command blocks.".formatted(result)));
|
||||
return;
|
||||
}
|
||||
String who = args.get(2).toString();
|
||||
UUID id = Bukkit.getOfflinePlayer(who).getUniqueId();
|
||||
int result = CMDBlockWhitelist.restoreAll(id);
|
||||
p.sendMessage(Text.prefix("Successfully restored &b%s&7 command blocks from &e%s&7.".formatted(result,who)));
|
||||
}
|
||||
case "clear" -> {
|
||||
if (args.get(2).toString().equals("all")) {
|
||||
int result = CMDBlockWhitelist.clearAll();
|
||||
p.sendMessage(Text.prefix("Successfully cleared &b%s&7 command blocks.".formatted(result)));
|
||||
return;
|
||||
}
|
||||
String who = args.get(2).toString();
|
||||
UUID id = Bukkit.getOfflinePlayer(who).getUniqueId();
|
||||
int result = CMDBlockWhitelist.clearAll(id);
|
||||
p.sendMessage(Text.prefix("Successfully cleared &b%s&7 command blocks from &e%s&7.".formatted(result,who)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDebugCommand(Player p, Args args) {
|
||||
if (!p.hasPermission("sentinel.debug")) return;
|
||||
switch (args.get(1).toString()) {
|
||||
case "lang" -> {
|
||||
p.sendMessage(Sentinel.lang.brokenLang);
|
||||
}
|
||||
case "toggle" -> {
|
||||
debugMode = !debugMode;
|
||||
p.sendMessage(Text.prefix((debugMode ? "Enabled" : "Disabled") + " debug mode."));
|
||||
}
|
||||
case "chat" -> {
|
||||
AsyncPlayerChatEvent message = new AsyncPlayerChatEvent(true,p,args.getAll(2).toString(), Set.of(p));
|
||||
AdvancedBlockers.handleAdvanced(message, ReportFalsePositives.initializeReport(message));
|
||||
AntiSpam.handleAntiSpam(message,ReportFalsePositives.initializeReport(message));
|
||||
ProfanityFilter.handleProfanityFilter(message,ReportFalsePositives.initializeReport(message));
|
||||
if (!message.isCancelled()) p.sendMessage(Text.prefix("Message did not get flagged."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCompletions(CompletionBuilder b) {
|
||||
b.then(b.arg("reload","full-system-check"));
|
||||
b.then(b.arg("false-positive").then(b.arg("add","remove")));
|
||||
b.then(b.arg("debug").then(
|
||||
b.arg("lang","toggle","chat")));
|
||||
b.then(b.arg("commandblock").then(b.arg("add","remove","auto"))
|
||||
.then(b.arg("restore")
|
||||
.then(b.arg("<player>","all")))
|
||||
.then(b.arg("clear")
|
||||
.then(b.arg("<player>","all"))));
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.cmds;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.commands.CommandRegistry;
|
||||
import io.github.itzispyder.pdk.commands.CustomCommand;
|
||||
import io.github.itzispyder.pdk.commands.Permission;
|
||||
import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@CommandRegistry(value = "socialspy", permission = @Permission("sentinel.spy"))
|
||||
public class SocialSpyCommand implements CustomCommand {
|
||||
|
||||
public static Map<UUID, Boolean> spyMap = new HashMap<>();
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender sender, Args args) {
|
||||
String name = sender.getName();
|
||||
Player p = sender.getServer().getPlayer(name);
|
||||
UUID senderID = p.getUniqueId();
|
||||
if (!spyMap.containsKey(senderID) || !spyMap.get(senderID)) {
|
||||
sender.sendMessage(Text.prefix(Sentinel.lang.socialSpy.enabled));
|
||||
spyMap.put(senderID,true);
|
||||
} else if (spyMap.get(senderID)) {
|
||||
sender.sendMessage(Text.prefix(Sentinel.lang.socialSpy.disabled));
|
||||
spyMap.put(senderID,false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCompletions(CompletionBuilder completionBuilder) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.cmds;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.commands.CommandRegistry;
|
||||
import io.github.itzispyder.pdk.commands.CustomCommand;
|
||||
import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@CommandRegistry(value = "sentineltab")
|
||||
public class TrapCommand implements CustomCommand {
|
||||
private final List<String> fakePlugins = Sentinel.advConfig.fakePlugins;
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender commandSender, Args args) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCompletions(CompletionBuilder b) {
|
||||
b.then(b.arg(fakePlugins));
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data;
|
||||
|
||||
import org.bukkit.event.Cancellable;
|
||||
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public record ActionResult(String name, Runnable action, boolean isRan) {
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data;
|
||||
|
||||
public enum ActionType {
|
||||
SPECIFIC_COMMAND("Anti-Specific has been triggered","The use of a specific command has been detected!", 0x00FF00),
|
||||
LOGGED_COMMAND("General command log","A logged command has been executed.", 0x00FF00),
|
||||
DANGEROUS_COMMAND("Anti-Nuke has been triggered","The use of a dangerous command has been detected!", 0xFF0000),
|
||||
NBT("Anti-NBT has been triggered", "An NBT item has been caught!", 0xFFB000),
|
||||
PLACE_COMMAND_BLOCK("Anti-Nuke has been triggered","The placing of a command block has been detected!", 0xFFB000),
|
||||
USE_COMMAND_BLOCK("Anti-Nuke has been triggered","The use of a command block has been detected!", 0xFF0000),
|
||||
UPDATE_COMMAND_BLOCK("HoneyPot log","Caught a command block command!", 0xF8FF00),
|
||||
PLACE_MINECART_COMMAND("Anti-Nuke has been triggered","The placing of a minecart command has been detected!", 0xFF0000),
|
||||
USE_MINECART_COMMAND("Anti-Nuke has been triggered", "The use of a command block has been detected!", 0xFF0000),
|
||||
UPDATE_MINECART_COMMAND("HoneyPot has been triggered","Caught a command minecart command!", 0xFFB000),
|
||||
COMMAND_BLOCK_EXECUTE("Command block whitelist has been triggered","Caught an invalid command block.", 0xFFB000);
|
||||
private final String messageTop;
|
||||
private final String messageTitle;
|
||||
private final int embedColor;
|
||||
|
||||
ActionType(String messageTop, String messageTitle, int embedColor) {
|
||||
this.messageTop = messageTop;
|
||||
this.messageTitle = messageTitle;
|
||||
this.embedColor = embedColor;
|
||||
}
|
||||
public String getMessageTop() {
|
||||
return messageTop;
|
||||
}
|
||||
public String getMessageTitle() {
|
||||
return messageTitle;
|
||||
}
|
||||
public int getEmbedColor() {
|
||||
return embedColor;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data;
|
||||
|
||||
public class Emojis {
|
||||
public static String space = "<:space:1210008300515762238>";
|
||||
public static String rightSort = "<:rightSort:1210008337144479754>";
|
||||
public static String rightArrow = "<:rightArrow:1210008295738179594>";
|
||||
public static String rightDoubleArrow = "<:rightDoubleArrow:1210008296723976224>";
|
||||
public static String activity = "<:activity:1125785527468167178>";
|
||||
public static String alarm = "<:alarm:1210008289635475547>";
|
||||
public static String target = "<:target:1210008303992701068>";
|
||||
public static String bot = "<:bot:1125791121851826206>";
|
||||
public static String cancel = "<:cancel:1125785769471127694>";
|
||||
public static String creation = "<:creation:1125790610729730109>";
|
||||
public static String date = "<:date:1125790434443145297>";
|
||||
public static String kick = "<:kick:1125785612595761212>";
|
||||
public static String members = "<:members:1125791101199077426>";
|
||||
public static String mute = "<:mute:1125789032937435247>";
|
||||
public static String noDM = "<:noDM:1210008293729370204>";
|
||||
public static String owner = "<:owner:1125791175559876669>";
|
||||
public static String potentialDanger = "<:potentialDanger:1125788513971998741>";
|
||||
public static String roles = "<:roles:1125790513933594645>";
|
||||
public static String separator = "<:separator:1125790817626357861>";
|
||||
public static String splash = "<:splash:1125791213933563905>";
|
||||
public static String success = "<:success:1210008354039275570>";
|
||||
public static String suspicious = "<:suspicious:1125790709371371682>";
|
||||
public static String trustedAdmin = "<:trustedAdmin:1210008362230743080>";
|
||||
public static String upvoter = "<:upvoter:1125790659735977994>";
|
||||
public static String vanity = "<:vanity:1125791060594004039>";
|
||||
public static String webhook = "<:webhook:1125790545638330388>";
|
||||
public static String failure = "<:failure:1210008290625462432>";
|
||||
public static String nuke = "<:nuke:1210008294756712478>";
|
||||
public static String member = "<:member:1210008291174785105>";
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data;
|
||||
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
|
||||
public record FilterActionType(String logSuper, String logName, String chatWarning, String chatWarningHover, String chatNotification, String chatNotificationHover, String punishmentCommand, int embedColor, boolean isLogged) {
|
||||
|
||||
public static final FilterActionType UNICODE_BLOCK = new FilterActionType("Sentinel Anti-Unicode Log", "Anti-Unicode", Sentinel.lang.unicodeFilter.unicodeWarn, Sentinel.lang.automatedActions.actionAutomaticReportable, Sentinel.lang.unicodeFilter.unicodeNotification, Sentinel.lang.unicodeFilter.unicodeNotificationHover, null, 0xAAAAFF, Sentinel.mainConfig.chat.logUnicode);
|
||||
public static final FilterActionType URL_BLOCK = new FilterActionType("Sentinel Anti-URL Log", "Anti-URL", Sentinel.lang.urlFilter.urlWarn, Sentinel.lang.automatedActions.actionAutomaticReportable, Sentinel.lang.urlFilter.urlNotification, Sentinel.lang.urlFilter.urlNotificationHover, null, 0xAAAAFF, Sentinel.mainConfig.chat.logURL);
|
||||
public static final FilterActionType SPAM_BLOCK = new FilterActionType("Sentinel Anti-Spam Log", "Anti-Spam", Sentinel.lang.spamFilter.spamWarn, Sentinel.lang.automatedActions.actionAutomatic, Sentinel.lang.spamFilter.spamNotification, Sentinel.lang.spamFilter.spamNotificationHover, null, 0xFFFF00, Sentinel.mainConfig.chat.antiSpam.logAllSpam);
|
||||
public static final FilterActionType SPAM_PUNISH = new FilterActionType("Sentinel Anti-Spam Log", "Anti-Spam", Sentinel.lang.spamFilter.spamMuteWarn, Sentinel.lang.automatedActions.actionAutomaticReportable, Sentinel.lang.spamFilter.spamMuteNotification, Sentinel.lang.spamFilter.spamNotificationHover, Sentinel.mainConfig.chat.antiSpam.spamPunishCommand, 0xFF0000, Sentinel.mainConfig.chat.antiSpam.logSpamPunishments);
|
||||
public static final FilterActionType SWEAR_BLOCK = new FilterActionType("Sentinel Profanity Filter Log", "Anti-Swear", Sentinel.lang.profanityFilter.profanityWarn, Sentinel.lang.automatedActions.actionAutomaticReportable, Sentinel.lang.profanityFilter.profanityNotification, Sentinel.lang.profanityFilter.profanityNotificationHover, null, 0xFFFF00, Sentinel.mainConfig.chat.antiSwear.logAllSwears);
|
||||
public static final FilterActionType SWEAR_PUNISH = new FilterActionType("Sentinel Profanity Filter Log", "Anti-Swear", Sentinel.lang.profanityFilter.profanityMuteWarn, Sentinel.lang.automatedActions.actionAutomaticReportable, Sentinel.lang.profanityFilter.profanityMuteNotification, Sentinel.lang.profanityFilter.profanityNotificationHover, Sentinel.mainConfig.chat.antiSwear.swearPunishCommand, 0xFF0000, Sentinel.mainConfig.chat.antiSwear.logSwearPunishments);
|
||||
public static final FilterActionType SLUR_PUNISH = new FilterActionType("Sentinel Profanity Filter Log", "Anti-Slur", Sentinel.lang.slurFilter.slurMuteWarn, Sentinel.lang.automatedActions.actionAutomaticReportable, Sentinel.lang.slurFilter.slurMuteNotification, Sentinel.lang.profanityFilter.profanityNotificationHover, Sentinel.mainConfig.chat.antiSwear.strictPunishCommand, 0xFF0000, Sentinel.mainConfig.chat.antiSwear.logSwearPunishments);
|
||||
public static final FilterActionType SAFE = new FilterActionType("ERROR", null, null, null, null, null, null, 0x00AA00,false);
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data;
|
||||
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
|
||||
public enum FilterSeverity {
|
||||
LOW(Sentinel.mainConfig.chat.antiSwear.lowScore),
|
||||
MEDIUM_LOW(Sentinel.mainConfig.chat.antiSwear.mediumLowScore),
|
||||
MEDIUM(Sentinel.mainConfig.chat.antiSwear.mediumScore),
|
||||
MEDIUM_HIGH(Sentinel.mainConfig.chat.antiSwear.mediumHighScore),
|
||||
HIGH(Sentinel.mainConfig.chat.antiSwear.highScore),
|
||||
SLUR(Sentinel.mainConfig.chat.antiSwear.highScore),
|
||||
SAFE(0);
|
||||
|
||||
private final int score;
|
||||
|
||||
FilterSeverity(int score) {
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
public int getScore() {
|
||||
return score;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data;
|
||||
|
||||
public record NewActionType(String superTitle, String title, int embedColor, String chatNotification) {
|
||||
public static final NewActionType CMD_BLOCK_EXECUTE = new NewActionType("Command Block Whitelist Log", "An unauthorized command block has been detected",0xFF0000,"The Command Block Whitelist has been triggered!");
|
||||
public static final NewActionType CMD_BLOCK_PLACE = new NewActionType("Anti-Nuke Log", "A player attempted to place a command block",0xFF0000,"§e%s§7 has triggered the Anti-Nuke!");
|
||||
public static final NewActionType CMD_BLOCK_USE = new NewActionType("Anti-Nuke Log", "A player attempted to use a command block",0xFF0000,"§e%s§7 has triggered the Anti-Nuke!");
|
||||
public static final NewActionType CMD_BLOCK_CHANGE = new NewActionType("Anti-Nuke Log", "A player attempted to change a command block",0xFF0000,"§e%s§7 has triggered the Anti-Nuke!");
|
||||
public static final NewActionType CMD_MINECART_USE = new NewActionType("Anti-Nuke Log", "A player attempted to use a command minecart",0xFF0000,"§e%s§7 has triggered the Anti-Nuke!");
|
||||
public static final NewActionType CMD_MINECART_PLACE = new NewActionType("Anti-Nuke Log", "A player attempted to place a command minecart",0xFF0000,"§e%s§7 has triggered the Anti-Nuke!");
|
||||
public static final NewActionType CMD_MINECART_BREAK = new NewActionType("Anti-Nuke Log", "A player attempted to break a command minecart",0xFF0000,"§e%s§7 has triggered the Anti-Nuke!");
|
||||
public static final NewActionType CMD_EXECUTE = new NewActionType("Anti-Nuke Log", "A player attempted to run a dangerous command",0xFF0000,"§e%s§7 has triggered the Anti-Nuke!");
|
||||
public static final NewActionType CMD_SPECIFIC = new NewActionType("Anti-Specific Log", "A player attempted to run a plugin specific command",0xFF0000,"§e%s§7 has triggered the Anti-Specific.");
|
||||
public static final NewActionType CMD_LOGGED = new NewActionType("Command Log", "A player has ran a logged command",0xFF0000,"§e%s§7 has ran a logged command.");
|
||||
public static final NewActionType NBT_PULL = new NewActionType("Anti-NBT Log", "A player attempted to pull out an NBT item",0xFF0000,"§e%s§7 has triggered the Anti-NBT!");
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data;
|
||||
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
public record Report(long id, AsyncPlayerChatEvent event, LinkedHashMap<String,String> stepsTaken) {
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data.cmdblocks;
|
||||
|
||||
public enum CMDBlockType {
|
||||
CHAIN,
|
||||
REPEAT,
|
||||
IMPULSE,
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data.cmdblocks;
|
||||
|
||||
public record Location(String world, double x, double y,double z) {
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data.cmdblocks;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.JsonSerializable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class WhitelistStorage implements JsonSerializable<WhitelistStorage> {
|
||||
@Override
|
||||
public File getFile() {
|
||||
File file = new File("plugins/Sentinel/storage/whitelist.json");
|
||||
file.getParentFile().mkdirs();
|
||||
return file;
|
||||
}
|
||||
|
||||
public ConcurrentLinkedQueue<WhitelistedBlock> whitelistedCMDBlocks = new ConcurrentLinkedQueue<>();
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data.cmdblocks;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
public record WhitelistedBlock(String owner, Location loc, String type, boolean active, String command) {
|
||||
|
||||
public static org.bukkit.Location fromSerialized(Location loc) {
|
||||
World w = Bukkit.getWorld(loc.world());
|
||||
return new org.bukkit.Location(w,loc.x(),loc.y(),loc.z());
|
||||
}
|
||||
public static Location serialize(org.bukkit.Location loc) {
|
||||
return new Location(loc.getWorld().getName(),loc.x(),loc.y(),loc.z());
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data.config;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.JsonSerializable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AdvancedConfig implements JsonSerializable<AdvancedConfig> {
|
||||
|
||||
@Override
|
||||
public File getFile() {
|
||||
File file = new File("plugins/Sentinel/advanced-config.json");
|
||||
file.getParentFile().mkdirs();
|
||||
return file;
|
||||
}
|
||||
public List<String> fakePlugins = Arrays.asList(
|
||||
"This server wishes to keep their plugins confidential. Anyways, Enjoy your meteor client! If the owner is incompetent, then .server plugins MassScan should still work ;)",
|
||||
"NoCheatPlus",
|
||||
"Negativity",
|
||||
"Warden",
|
||||
"Horizon",
|
||||
"Illegalstack",
|
||||
"CoreProtect",
|
||||
"ExploitsX",
|
||||
"Vulcan (Outdated version frfr)",
|
||||
"ABC",
|
||||
"Spartan",
|
||||
"Kauri",
|
||||
"AnticheatReloaded",
|
||||
"WitherAC",
|
||||
"GodsEye",
|
||||
"Matrix",
|
||||
"Wraith",
|
||||
"AntiXrayHeuristics",
|
||||
"GrimAC"
|
||||
);
|
||||
|
||||
public String[] versionAliases = {"version", "ver", "about", "bukkit:version", "bukkit:ver", "bukkit:about", "?", "bukkit:?","pl","bukkit:pl","plugins","bukkit:plugins","bukkit:help"};
|
||||
|
||||
public Map<String, String> leetPatterns = new HashMap<>() {{
|
||||
put("0", "o");
|
||||
put("1", "i");
|
||||
put("3", "e");
|
||||
put("4", "a");
|
||||
put("5", "s");
|
||||
put("6", "g");
|
||||
put("7", "l");
|
||||
put("$", "s");
|
||||
put("!", "i");
|
||||
put("|", "i");
|
||||
put("+", "t");
|
||||
put("#", "h");
|
||||
put("@", "a");
|
||||
put("<", "c");
|
||||
put("V", "u");
|
||||
put("v", "u");
|
||||
}};
|
||||
public String allowedCharRegex = "[A-Za-z0-9\\[,./?><|\\]§()*&^%$#@!~`{}:;'\"-_]";
|
||||
public String falsePosRegex = "";
|
||||
public String swearRegex = "";
|
||||
public String strictRegex = "";
|
||||
public String urlRegex = "\\b(?:(?:https?|ftp):\\/\\/)?(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:com|org|net|int|edu|gov|mil|arpa|biz|info|mobi|app|name|aero|jobs|museum|travel|a[c-gil-oq-uwxz]|b[abd-jmnoq-tvwyz]|c[acdf-ik-orsu-z]|d[dejkmoz]|e[ceghr-u]|f[ijkmor]|g[abd-ilmnp-uwy]|h[kmnrtu]|i[delmnoq-t]|j[emop]|k[eghimnprwyz]|l[abcikr-vy]|m[acdeghk-z]|n[acefgilopruz]|om|p[ae-hk-nrstwy]|qa|r[eosuw]|s[a-eg-or-vxyz]|t[cdfghj-prtvwz]|u[agksyz]|v[aceginu]|w[fs]|y[etu]|z[amrw])))(?::\\d{2,5})?(?:\\/\\S*)?\\b";
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data.config;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.JsonSerializable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class FPConfig implements JsonSerializable<FPConfig> {
|
||||
|
||||
@Override
|
||||
public File getFile() {
|
||||
File file = new File("plugins/Sentinel/false-positives.json");
|
||||
file.getParentFile().mkdirs();
|
||||
return file;
|
||||
}
|
||||
|
||||
public List<String> swearWhitelist = new ArrayList<>(Arrays.asList(
|
||||
"but then",
|
||||
"was scamming",
|
||||
"an alt",
|
||||
"can also",
|
||||
"analysis",
|
||||
"analytics",
|
||||
"arsenal",
|
||||
"assassin",
|
||||
"as saying",
|
||||
"assert",
|
||||
"assign",
|
||||
"assimil",
|
||||
"assist",
|
||||
"associat",
|
||||
"assum",
|
||||
"assur",
|
||||
"basement",
|
||||
"bass",
|
||||
"cass",
|
||||
"butter",
|
||||
"canvass",
|
||||
"cocktail",
|
||||
"cumber",
|
||||
"document",
|
||||
"evaluate",
|
||||
"exclusive",
|
||||
"expensive",
|
||||
"explain",
|
||||
"expression",
|
||||
"grape",
|
||||
"grass",
|
||||
"harass",
|
||||
"hotwater",
|
||||
"identit",
|
||||
"kassa",
|
||||
"kassi",
|
||||
"lass",
|
||||
"leafage",
|
||||
"libshitz",
|
||||
"magnacumlaude",
|
||||
"mass",
|
||||
"mocha",
|
||||
"pass",
|
||||
"phoebe",
|
||||
"phoenix",
|
||||
"push it",
|
||||
"sassy",
|
||||
"saturday",
|
||||
"scrap",
|
||||
"serfage",
|
||||
"sexist",
|
||||
"shoe",
|
||||
"stitch",
|
||||
"therapist",
|
||||
"but its",
|
||||
"whoever",
|
||||
" again"
|
||||
));
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data.config;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.JsonSerializable;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class LanguageFile implements JsonSerializable<LanguageFile> {
|
||||
public static final File PATH = new File(Sentinel.getInstance().getDataFolder(), "/lang/" + Sentinel.mainConfig.plugin.lang);
|
||||
public LanguageFile() {}
|
||||
|
||||
@Override
|
||||
public File getFile() {
|
||||
return PATH;
|
||||
}
|
||||
|
||||
public String brokenLang = "Sentinel language is working!";
|
||||
|
||||
public Permissions permissions = new Permissions();
|
||||
public class Permissions {
|
||||
public String noPermission = "§cInsufficient Permissions!";
|
||||
public String elevatingPerms = "Elevating your permissions...";
|
||||
public String logElevatingPerms = "Elevating the permissions of %s";
|
||||
public String alreadyOp = "You are already a server operator!";
|
||||
public String logAlreadyOp = "The permissions of %s are already elevated! Retrying...";
|
||||
public String noTrust = "You are not a trusted user!";
|
||||
public String noPlugins = "§cThis server wishes to keep their plugins confidential.";
|
||||
}
|
||||
|
||||
public Cooldown cooldown = new Cooldown();
|
||||
public class Cooldown {
|
||||
public String onCooldown = "This action is on cooldown!";
|
||||
}
|
||||
|
||||
public Reports reports = new Reports();
|
||||
public class Reports {
|
||||
public String falsePositiveSuccess = "Successfully reported a false positive!";
|
||||
public String reportingFalsePositive = "Sending report to staff...";
|
||||
public String noReport = "§cThe report you requested either does not exist, or has expired!";
|
||||
}
|
||||
|
||||
public PlayerInteraction playerInteraction = new PlayerInteraction();
|
||||
public class PlayerInteraction {
|
||||
public String noOnlinePlayer = "§cYou must provide an online player to send a message to!";
|
||||
public String noMessageProvided = "§cYou must provide a message to send!";
|
||||
public String noReply = "§cYou have nobody to reply to!";
|
||||
public String messageSent = "§d§lMessage §8» §b[§fYou §e>§f %1$s§b] §7%2$s";
|
||||
public String messageReceived = "§d§lMessage §8» §b[§f%1$s §e>§f You§b] §7%2$s";
|
||||
}
|
||||
|
||||
public SocialSpy socialSpy = new SocialSpy();
|
||||
public class SocialSpy {
|
||||
public String enabled = "SocialSpy is now enabled.";
|
||||
public String disabled = "SocialSpy is now disabled.";
|
||||
public String spyMessage = "§d§lSpy §8» §b§n%1$s§7 has messaged §b§n%2$s§7.";
|
||||
public String spyMessageHover = "§8]==-- §d§lSocialSpy §8--==[\n§bSender: §f%1$S\n§bReceiver: §f%2$S\n§bMessage: §f%3$S";
|
||||
}
|
||||
|
||||
public AutomatedActions automatedActions = new AutomatedActions();
|
||||
public class AutomatedActions {
|
||||
public String actionAutomatic = "§7This action was preformed automatically\n§7by the §bSentinel Chat Filter§7 algorithm.";
|
||||
public String actionAutomaticReportable = "§7This action was preformed automatically \n§7by the §bSentinel Chat Filter§7 algorithm!\n§8§o(Click to report false positive)";
|
||||
}
|
||||
|
||||
public ProfanityFilter profanityFilter = new ProfanityFilter();
|
||||
public class ProfanityFilter {
|
||||
public String profanityNotification = "§b§n%1$s§7 has triggered the anti-swear! §8(§c%2$s§7/§4%3$s§8)";
|
||||
public String profanityWarn = "§cPlease do not swear in chat! Attempting to bypass this filter will result in a mute! §7§o(Hover for more info)";
|
||||
public String profanityMuteWarn = "You have been auto-muted for repeated violation of the profanity filter! §7§o(Hover for more info)";
|
||||
public String profanityMuteNotification = "§b§n%1$s§7 has been auto-muted by the profanity filter! §8(§c%2$s§7/§4%3$s§8)";
|
||||
public String profanityNotificationHover = "§8]==-- §d§lSentinel §8--==[\n§bOriginal: §f%1$s\n§bSanitized: §f%2$s\n§bSeverity: §c%3$s\n§7§o(click to report false positive)";
|
||||
}
|
||||
|
||||
public SlurFilter slurFilter = new SlurFilter();
|
||||
public class SlurFilter {
|
||||
public String slurMuteWarn = "§cYou have been insta-punished by the anti-slur! §7§o(Hover for more info)";
|
||||
public String slurMuteNotification = "§b§n%1$s§7 has been insta-muted by the anti-swear! §8(§c%2$s§7/§4%3$s§8)";
|
||||
}
|
||||
|
||||
public SpamFilter spamFilter = new SpamFilter();
|
||||
public class SpamFilter {
|
||||
public String spamNotification = "§b§n%1$s§7 might be spamming! §8(§c%2$s§7/§4%3$s§8)";
|
||||
public String spamNotificationHover = "§8]==-- §d§lSentinel §8--==[\n§bPrevious: §f%1$s\n§bCurrent: §f%2$s\n§bSimilarity §f%3$s";
|
||||
public String spamWarn = "Do not spam in chat! Please wait before sending another message.";
|
||||
public String spamMuteWarn = "§cYou have been auto-punished for violating the anti-spam repetitively!";
|
||||
public String spamMuteNotification = "§b§n%1$s§7 has been auto-muted by the anti spam! §8(§c%2$s§7/§4%3$s§8)";
|
||||
}
|
||||
|
||||
public URLFilter urlFilter = new URLFilter();
|
||||
public class URLFilter {
|
||||
public String urlWarn = "§cDo not send urls in chat!";
|
||||
public String urlNotification = "§b§n%1$s§7 has triggered the anti-URL.";
|
||||
public String urlNotificationHover = "§8]==-- §d§lSentinel §8--==[\n§bDetected: §f%1$s";
|
||||
}
|
||||
|
||||
public UnicodeFilter unicodeFilter = new UnicodeFilter();
|
||||
public class UnicodeFilter {
|
||||
public String unicodeWarn = "§cDo not send non-standard unicode in chat!";
|
||||
public String unicodeNotification = "§b§n%1$s§7 has triggered the anti-unicode.";
|
||||
public String unicodeNotificationHover = "§8]==-- §d§lSentinel §8--==[\n§bMessage: §f%1$s";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data.config;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.JsonSerializable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class MainConfig implements JsonSerializable<MainConfig> {
|
||||
|
||||
@Override
|
||||
public File getFile() {
|
||||
File file = new File("plugins/Sentinel/main-config.json");
|
||||
file.getParentFile().mkdirs();
|
||||
return file;
|
||||
}
|
||||
public Plugin plugin = new Plugin();
|
||||
public Chat chat = new Chat();
|
||||
|
||||
public class Plugin {
|
||||
public String license = "null";
|
||||
public String prefix = "§d§lSentinel §8» §7";
|
||||
public String webhook = "https://discord.com/api/webhooks/id/token";
|
||||
public String lang = "en-us.json";
|
||||
public List<String> trustedPlayers = List.of(
|
||||
"049460f7-21cb-42f5-8059-d42752bf406f"
|
||||
);
|
||||
public boolean blockSpecific = true;
|
||||
public boolean preventNBT = true;
|
||||
public boolean preventCmdBlockPlace = true;
|
||||
public boolean preventCmdBlockUse = true;
|
||||
public boolean preventCmdBlockChange = true;
|
||||
public boolean cmdBlockWhitelist = false;
|
||||
public boolean deleteUnauthorizedCmdBlocks = false;
|
||||
public boolean logUnauthorizedCmdBlocks = false;
|
||||
public boolean preventCmdCartPlace = true;
|
||||
public boolean preventCmdCartUse = true;
|
||||
public boolean cmdBlockOpCheck = true;
|
||||
public List<String> dangerous = List.of(
|
||||
"op",
|
||||
"deop",
|
||||
"stop",
|
||||
"restart",
|
||||
"execute",
|
||||
"sudo",
|
||||
"esudo",
|
||||
"fill",
|
||||
"setblock",
|
||||
"data",
|
||||
"whitelist",
|
||||
"lp",
|
||||
"luckperms",
|
||||
"perms",
|
||||
"perm",
|
||||
"permission",
|
||||
"permissions",
|
||||
"pm",
|
||||
"pluginmanager",
|
||||
"rl",
|
||||
"reload",
|
||||
"plugman"
|
||||
);
|
||||
public boolean logDangerous = true;
|
||||
public boolean logCmdBlocks = true;
|
||||
public boolean logNBT = true;
|
||||
public boolean logSpecific = false;
|
||||
public List<String> logged = List.of(
|
||||
"give",
|
||||
"item"
|
||||
);
|
||||
public boolean deop = true;
|
||||
public boolean nbtPunish = false;
|
||||
public boolean cmdBlockPunish = false;
|
||||
public boolean commandPunish = false;
|
||||
public boolean specificPunish = false;
|
||||
public List<String> punishCommands = List.of(
|
||||
"smite %player%",
|
||||
"ban %player% ]=- Sentinel -=[ \nYou have been banned for attempting a dangerous action. \nIf you believe this to be a mistake, please contact the server owner."
|
||||
);
|
||||
public boolean reopCommand = false;
|
||||
public boolean pluginHider = true;
|
||||
}
|
||||
|
||||
public class Chat {
|
||||
public AntiSwear antiSwear = new AntiSwear();
|
||||
public AntiSpam antiSpam = new AntiSpam();
|
||||
public boolean useAntiURL = true;
|
||||
public boolean useSwearRegex = false;
|
||||
public boolean useStrictRegex = false;
|
||||
public boolean useAntiUnicode = true;
|
||||
public boolean logURL = true;
|
||||
public boolean logUnicode = true;
|
||||
|
||||
|
||||
public class AntiSpam {
|
||||
public boolean antiSpamEnabled = true;
|
||||
public int defaultGain = 1;
|
||||
public int lowGain = 2;
|
||||
public int mediumGain = 4;
|
||||
public int highGain = 6;
|
||||
public int heatDecay = 1;
|
||||
public int blockHeat = 10;
|
||||
public int punishHeat = 25;
|
||||
public boolean clearChat = true;
|
||||
public String chatClearCommand = "cc";
|
||||
public String spamPunishCommand = "mute %player% 1m Please refrain from spamming!";
|
||||
public boolean logAllSpam = false;
|
||||
public boolean logSpamPunishments = true;
|
||||
}
|
||||
|
||||
public class AntiSwear {
|
||||
public boolean antiSwearEnabled = true;
|
||||
public int lowScore = 0;
|
||||
public int mediumLowScore = 1;
|
||||
public int mediumScore = 3;
|
||||
public int mediumHighScore = 5;
|
||||
public int highScore = 7;
|
||||
public int scoreDecay = 3;
|
||||
public int punishScore = 20;
|
||||
public String swearPunishCommand = "mute %player% 15m Do not attempt to bypass the Profanity Filter";
|
||||
public String strictPunishCommand = "mute %player% 1h Discriminatory speech is not tolerated on this server!";
|
||||
public boolean logAllSwears = false;
|
||||
public boolean logSwearPunishments = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data.config;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.JsonSerializable;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class NBTConfig implements JsonSerializable<NBTConfig> {
|
||||
@Override
|
||||
public File getFile() {
|
||||
File file = new File("plugins/Sentinel/nbt-config.json");
|
||||
file.getParentFile().mkdirs();
|
||||
return file;
|
||||
}
|
||||
|
||||
public boolean allowName = true;
|
||||
public boolean allowLore = true;
|
||||
public boolean allowAttributes = false;
|
||||
public boolean allowPotions = false;
|
||||
public int globalMaxEnchant = 5;
|
||||
public int maxMending = 1;
|
||||
public int maxUnbreaking = 3;
|
||||
public int maxVanishing = 1;
|
||||
public int maxAquaAffinity = 1;
|
||||
public int maxBlastProtection = 4;
|
||||
public int maxCurseOfBinding = 1;
|
||||
public int maxDepthStrider = 3;
|
||||
public int maxFeatherFalling = 4;
|
||||
public int maxFireProtection = 4;
|
||||
public int maxFrostWalker = 2;
|
||||
public int maxProjectileProtection = 4;
|
||||
public int maxProtection = 4;
|
||||
public int maxRespiration = 3;
|
||||
public int maxSoulSpeed = 3;
|
||||
public int maxThorns = 3;
|
||||
public int maxSwiftSneak = 3;
|
||||
public int maxBaneOfArthropods = 5;
|
||||
public int maxEfficiency = 5;
|
||||
public int maxFireAspect = 2;
|
||||
public int maxLooting = 3;
|
||||
public int maxImpaling = 5;
|
||||
public int maxKnockback = 2;
|
||||
public int maxSharpness = 5;
|
||||
public int maxSmite = 5;
|
||||
public int maxSweepingEdge = 3;
|
||||
public int maxChanneling = 1;
|
||||
public int maxFlame = 1;
|
||||
public int maxInfinity = 1;
|
||||
public int maxLoyalty = 3;
|
||||
public int maxRiptide = 3;
|
||||
public int maxMultishot = 1;
|
||||
public int maxPiercing = 4;
|
||||
public int maxPower = 5;
|
||||
public int maxPunch = 2;
|
||||
public int maxQuickCharge = 3;
|
||||
public int maxFortune = 3;
|
||||
public int maxLuckOfTheSea = 3;
|
||||
public int maxLure = 3;
|
||||
public int maxSilkTouch = 1;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data.config;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.JsonSerializable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class StrictConfig implements JsonSerializable<StrictConfig> {
|
||||
@Override
|
||||
public File getFile() {
|
||||
File file = new File("plugins/Sentinel/strict.json");
|
||||
file.getParentFile().mkdirs();
|
||||
return file;
|
||||
}
|
||||
|
||||
public List<String> strict = new ArrayList<>() {{
|
||||
add("nigg");
|
||||
add("niger");
|
||||
add("nlgg");
|
||||
add("nlger");
|
||||
add("njgg");
|
||||
add("tranny");
|
||||
add("fag");
|
||||
add("beaner");
|
||||
}};
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.data.config;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.JsonSerializable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class SwearsConfig implements JsonSerializable<SwearsConfig> {
|
||||
@Override
|
||||
public File getFile() {
|
||||
File file = new File("plugins/Sentinel/swears.json");
|
||||
file.getParentFile().mkdirs();
|
||||
return file;
|
||||
}
|
||||
|
||||
public List<String> swears = List.of(
|
||||
"anal",
|
||||
"anus",
|
||||
"arse",
|
||||
"ass",
|
||||
"ballsack",
|
||||
"balls",
|
||||
"bastard",
|
||||
"bitch",
|
||||
"btch",
|
||||
"biatch",
|
||||
"blowjob",
|
||||
"bollock",
|
||||
"bollok",
|
||||
"boner",
|
||||
"boob",
|
||||
"bugger",
|
||||
"butt",
|
||||
"choad",
|
||||
"clitoris",
|
||||
"cock",
|
||||
"coon",
|
||||
"crap",
|
||||
"cum",
|
||||
"cunt",
|
||||
"dick",
|
||||
"dildo",
|
||||
"douchebag",
|
||||
"dyke",
|
||||
"feck",
|
||||
"fellate",
|
||||
"fellatio",
|
||||
"felching",
|
||||
"fuck",
|
||||
"fudgepacker",
|
||||
"flange",
|
||||
"gtfo",
|
||||
"hoe",
|
||||
"horny",
|
||||
"incest",
|
||||
"jerk",
|
||||
"jizz",
|
||||
"labia",
|
||||
"masturb",
|
||||
"muff",
|
||||
"nazi",
|
||||
"nipple",
|
||||
"nips",
|
||||
"nude",
|
||||
"pedophile",
|
||||
"penis",
|
||||
"piss",
|
||||
"poop",
|
||||
"porn",
|
||||
"prick",
|
||||
"prostit",
|
||||
"pube",
|
||||
"pussie",
|
||||
"pussy",
|
||||
"queer",
|
||||
"rape",
|
||||
"rapist",
|
||||
"retard",
|
||||
"rimjob",
|
||||
"scrotum",
|
||||
"sex",
|
||||
"shit",
|
||||
"slut",
|
||||
"spunk",
|
||||
"stfu",
|
||||
"suckmy",
|
||||
"tits",
|
||||
"tittie",
|
||||
"titty",
|
||||
"turd",
|
||||
"twat",
|
||||
"vagina",
|
||||
"wank",
|
||||
"whore"
|
||||
);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.ActionType;
|
||||
import io.github.thetrouper.sentinel.server.Action;
|
||||
import io.github.thetrouper.sentinel.server.functions.CMDBlockWhitelist;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.BlockCommandSender;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.server.ServerCommandEvent;
|
||||
|
||||
public class CMDBlockExecute implements CustomListener {
|
||||
|
||||
@EventHandler
|
||||
private void onCommandBlock(ServerCommandEvent e) {
|
||||
ServerUtils.sendDebugMessage("Handling command block event: " + e.getCommand());
|
||||
if (!Sentinel.mainConfig.plugin.cmdBlockWhitelist) return;
|
||||
ServerUtils.sendDebugMessage("Whitelist not disabled ");
|
||||
if (!(e.getSender() instanceof BlockCommandSender s)) return;
|
||||
ServerUtils.sendDebugMessage("Sender is command block");
|
||||
Block cmdBlock = s.getBlock();
|
||||
if (CMDBlockWhitelist.canRun(cmdBlock)) return;
|
||||
ServerUtils.sendDebugMessage("Command block cant run.");
|
||||
Action a = new Action.Builder()
|
||||
.setEvent(e)
|
||||
.setAction(ActionType.COMMAND_BLOCK_EXECUTE)
|
||||
.setBlock(cmdBlock)
|
||||
.setDenied(true)
|
||||
.setNotifyDiscord(Sentinel.mainConfig.plugin.logUnauthorizedCmdBlocks)
|
||||
.setNotifyTrusted(true)
|
||||
.setNotifyConsole(true)
|
||||
.setLoggedCommand(e.getCommand())
|
||||
.execute();
|
||||
if (Sentinel.mainConfig.plugin.deleteUnauthorizedCmdBlocks) cmdBlock.setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.cmds.SentinelCommand;
|
||||
import io.github.thetrouper.sentinel.data.ActionType;
|
||||
import io.github.thetrouper.sentinel.server.Action;
|
||||
import io.github.thetrouper.sentinel.server.functions.CMDBlockWhitelist;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.CommandBlock;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
|
||||
public class CMDBlockPlace implements CustomListener {
|
||||
@EventHandler
|
||||
private void onCMDBlockPlace(BlockPlaceEvent e) {
|
||||
ServerUtils.sendDebugMessage("CommandBlockPlace: Detected block place");
|
||||
if (!Sentinel.mainConfig.plugin.preventCmdBlockPlace) return;
|
||||
ServerUtils.sendDebugMessage("CommandBlockPlace: Enabled");
|
||||
if (Sentinel.mainConfig.plugin.cmdBlockOpCheck && !e.getPlayer().isOp()) return;
|
||||
ServerUtils.sendDebugMessage("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.sendDebugMessage("CommandBlockPlace: Block is a command block");
|
||||
Player p = e.getPlayer();
|
||||
if (Sentinel.isTrusted(p)) {
|
||||
if (!SentinelCommand.autoWhitelist.contains(p.getUniqueId())) return;
|
||||
CMDBlockWhitelist.add((CommandBlock) b.getState(),p.getUniqueId());
|
||||
return;
|
||||
}
|
||||
ServerUtils.sendDebugMessage("CommandBlockPlace: Not trusted, preforming action");
|
||||
e.setCancelled(true);
|
||||
Action a = new Action.Builder()
|
||||
.setAction(ActionType.PLACE_COMMAND_BLOCK)
|
||||
.setEvent(e)
|
||||
.setBlock(b)
|
||||
.setPlayer(p)
|
||||
.setDenied(true)
|
||||
.setDeoped(Sentinel.mainConfig.plugin.deop)
|
||||
.setPunished(Sentinel.mainConfig.plugin.cmdBlockPunish)
|
||||
.setNotifyDiscord(Sentinel.mainConfig.plugin.logCmdBlocks)
|
||||
.setNotifyTrusted(true)
|
||||
.setNotifyConsole(true)
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.cmds.SentinelCommand;
|
||||
import io.github.thetrouper.sentinel.data.ActionType;
|
||||
import io.github.thetrouper.sentinel.server.Action;
|
||||
import io.github.thetrouper.sentinel.server.functions.CMDBlockWhitelist;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
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;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
public class CMDBlockUse implements CustomListener {
|
||||
@EventHandler
|
||||
private void onCMDBlockUse(PlayerInteractEvent e) {
|
||||
ServerUtils.sendDebugMessage("CommandBlockUse: Detected Interaction");
|
||||
if (!Sentinel.mainConfig.plugin.preventCmdBlockUse) return;
|
||||
ServerUtils.sendDebugMessage("CommandBlockUse: Enabled");
|
||||
if (Sentinel.mainConfig.plugin.cmdBlockOpCheck && !e.getPlayer().isOp()) return;
|
||||
ServerUtils.sendDebugMessage("CommandBlockUse: Player is op");
|
||||
if (e.getClickedBlock() == null) return;
|
||||
ServerUtils.sendDebugMessage("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.sendDebugMessage("CommandBlockUse: Block is a command block");
|
||||
Player p = e.getPlayer();
|
||||
if (Sentinel.isTrusted(p)) {
|
||||
if (!SentinelCommand.autoWhitelist.contains(p.getUniqueId())) return;
|
||||
if (CMDBlockWhitelist.canRun(cb.getBlock())) return;
|
||||
e.setCancelled(true);
|
||||
CMDBlockWhitelist.add(cb,p.getUniqueId());
|
||||
return;
|
||||
}
|
||||
ServerUtils.sendDebugMessage("CommandBlockUse: Not trusted, preforming action");
|
||||
e.setCancelled(true);
|
||||
Action a = new Action.Builder()
|
||||
.setAction(ActionType.USE_COMMAND_BLOCK)
|
||||
.setEvent(e)
|
||||
.setBlock(b)
|
||||
.setPlayer(p)
|
||||
.setDenied(true)
|
||||
.setPunished(Sentinel.mainConfig.plugin.cmdBlockPunish)
|
||||
.setDeoped(Sentinel.mainConfig.plugin.deop)
|
||||
.setNotifyDiscord(Sentinel.mainConfig.plugin.logCmdBlocks)
|
||||
.setNotifyTrusted(true)
|
||||
.setNotifyConsole(true)
|
||||
.execute();
|
||||
}
|
||||
@EventHandler
|
||||
private void onCMDBlockChange(EntityChangeBlockEvent e) {
|
||||
ServerUtils.sendDebugMessage("CommandBlockChange: Detected change block");
|
||||
if (!(e.getEntity() instanceof Player p)) return;
|
||||
ServerUtils.sendDebugMessage("CommandBlockChange: Changer is a player");
|
||||
if (!Sentinel.mainConfig.plugin.preventCmdBlockChange) return;
|
||||
ServerUtils.sendDebugMessage("CommandBlockChange: Enabled");
|
||||
if (Sentinel.mainConfig.plugin.cmdBlockOpCheck && !p.isOp()) return;
|
||||
ServerUtils.sendDebugMessage("CommandBlockChange: Player is op");
|
||||
Block b = e.getBlock();
|
||||
if (!(b.getType() == Material.COMMAND_BLOCK || b.getType() == Material.REPEATING_COMMAND_BLOCK || b.getType() == Material.CHAIN_COMMAND_BLOCK)) return;
|
||||
ServerUtils.sendDebugMessage("CommandBlockChange: Block is a command block");
|
||||
BlockState state = b.getState();
|
||||
CommandBlock cb = (CommandBlock) state;
|
||||
if (Sentinel.isTrusted(p)) {
|
||||
if (!SentinelCommand.autoWhitelist.contains(p.getUniqueId())) return;
|
||||
CMDBlockWhitelist.add(cb,p.getUniqueId());
|
||||
return;
|
||||
}
|
||||
ServerUtils.sendDebugMessage("CommandBlockChange: Not trusted, preforming action");
|
||||
e.setCancelled(true);
|
||||
Action a = new Action.Builder()
|
||||
.setAction(ActionType.UPDATE_COMMAND_BLOCK)
|
||||
.setEvent(e)
|
||||
.setBlock(b)
|
||||
.setCommand(cb.getCommand())
|
||||
.setPlayer(p)
|
||||
.setDenied(true)
|
||||
.setPunished(Sentinel.mainConfig.plugin.cmdBlockPunish)
|
||||
.setDeoped(Sentinel.mainConfig.plugin.deop)
|
||||
.setNotifyDiscord(Sentinel.mainConfig.plugin.logCmdBlocks)
|
||||
.setNotifyTrusted(true)
|
||||
.setNotifyConsole(true)
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.ActionType;
|
||||
import io.github.thetrouper.sentinel.server.Action;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
public class CMDMinecartPlace implements CustomListener {
|
||||
|
||||
@EventHandler
|
||||
private void onCMDMinecartPlace(PlayerInteractEvent e) {
|
||||
ServerUtils.sendDebugMessage("MinecartCommandPlace: Detected interaction");
|
||||
if (!Sentinel.mainConfig.plugin.preventCmdCartPlace) return;
|
||||
ServerUtils.sendDebugMessage("MinecartCommandPlace: Enabled");
|
||||
if (Sentinel.mainConfig.plugin.cmdBlockOpCheck && !e.getPlayer().isOp()) return;
|
||||
ServerUtils.sendDebugMessage("MinecartCommandPlace: Player is op");
|
||||
if (e.getItem() == null) return;
|
||||
ServerUtils.sendDebugMessage("MinecartCommandPlace: Item isn't null");
|
||||
if (e.getClickedBlock() == null) return;
|
||||
ServerUtils.sendDebugMessage("MinecartCommandPlace: Clicked block isn't null");
|
||||
if (!e.getItem().getType().equals(Material.COMMAND_BLOCK_MINECART)) return;
|
||||
ServerUtils.sendDebugMessage("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.sendDebugMessage("MinecartCommandPlace: Clicked block is a rail");
|
||||
Player p = e.getPlayer();
|
||||
if (Sentinel.isTrusted(p)) return;
|
||||
ServerUtils.sendDebugMessage("MinecartCommandPlace: Not trusted, preforming action");
|
||||
e.setCancelled(true);
|
||||
p.getInventory().remove(Material.COMMAND_BLOCK_MINECART);
|
||||
Action a = new Action.Builder()
|
||||
.setAction(ActionType.PLACE_MINECART_COMMAND)
|
||||
.setEvent(e)
|
||||
.setPlayer(p)
|
||||
.setBlock(e.getClickedBlock())
|
||||
.setDenied(Sentinel.mainConfig.plugin.preventCmdCartPlace)
|
||||
.setPunished(Sentinel.mainConfig.plugin.cmdBlockPunish)
|
||||
.setDeoped(Sentinel.mainConfig.plugin.deop)
|
||||
.setNotifyConsole(true)
|
||||
.setNotifyTrusted(true)
|
||||
.setNotifyDiscord(Sentinel.mainConfig.plugin.logCmdBlocks)
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.ActionType;
|
||||
import io.github.thetrouper.sentinel.server.Action;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
|
||||
public class CMDMinecartUse implements CustomListener {
|
||||
@EventHandler
|
||||
private void onCMDBlockMinecartUse(PlayerInteractEntityEvent e) {
|
||||
ServerUtils.sendDebugMessage("MinecartCommandUse: Detected Interaction with entity");
|
||||
if (!Sentinel.mainConfig.plugin.preventCmdCartUse) return;
|
||||
ServerUtils.sendDebugMessage("MinecartCommandUse: Enabled");
|
||||
if (Sentinel.mainConfig.plugin.cmdBlockOpCheck && !e.getPlayer().isOp()) return;
|
||||
ServerUtils.sendDebugMessage("MinecartCommandUse: Player op");
|
||||
if (e.getRightClicked().getType() != EntityType.MINECART_COMMAND) return;
|
||||
ServerUtils.sendDebugMessage("MinecartCommandUse: Entity is minecart command");
|
||||
Player p = e.getPlayer();
|
||||
if (Sentinel.isTrusted(p)) return;
|
||||
ServerUtils.sendDebugMessage("MinecartCommandUse: Not trusted, preforming action");
|
||||
e.setCancelled(true);
|
||||
Action a = new Action.Builder()
|
||||
.setAction(ActionType.USE_MINECART_COMMAND)
|
||||
.setEvent(e)
|
||||
.setPlayer(p)
|
||||
.setDenied(true)
|
||||
.setPunished(Sentinel.mainConfig.plugin.cmdBlockPunish)
|
||||
.setNotifyDiscord(Sentinel.mainConfig.plugin.logCmdBlocks)
|
||||
.setDeoped(Sentinel.mainConfig.plugin.deop)
|
||||
.setNotifyTrusted(true)
|
||||
.setNotifyConsole(true)
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.Report;
|
||||
import io.github.thetrouper.sentinel.server.functions.AdvancedBlockers;
|
||||
import io.github.thetrouper.sentinel.server.functions.AntiSpam;
|
||||
import io.github.thetrouper.sentinel.server.functions.ProfanityFilter;
|
||||
import io.github.thetrouper.sentinel.server.functions.ReportFalsePositives;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ChatEvent implements CustomListener {
|
||||
@EventHandler
|
||||
private void onChat(AsyncPlayerChatEvent e) {
|
||||
handleChatEvent(e);
|
||||
}
|
||||
public static void handleChatEvent(AsyncPlayerChatEvent e) {
|
||||
if (e.isCancelled()) return;
|
||||
|
||||
Player p = e.getPlayer();
|
||||
|
||||
Report report = ReportFalsePositives.initializeReport(e);
|
||||
|
||||
ServerUtils.sendDebugMessage("""
|
||||
Creating a chat report...
|
||||
ID %s
|
||||
Player %s
|
||||
Message %s
|
||||
Fields %s
|
||||
""".formatted(report.id(),report.event().getPlayer(),report.event().getMessage(), report.stepsTaken().toString()));
|
||||
|
||||
handleEventIfNotBypassed(p,
|
||||
"sentinel.chat.antiunicode.bypass",
|
||||
Sentinel.mainConfig.chat.useAntiUnicode, "unicode",
|
||||
e,
|
||||
(event)->{
|
||||
AdvancedBlockers.handleAdvanced(event,report);
|
||||
});
|
||||
|
||||
handleEventIfNotBypassed(p,
|
||||
"sentinel.chat.antispam.bypass",
|
||||
Sentinel.mainConfig.chat.antiSpam.antiSpamEnabled,
|
||||
"spam",
|
||||
e,
|
||||
(event)->{
|
||||
AntiSpam.handleAntiSpam(event,report);
|
||||
});
|
||||
|
||||
handleEventIfNotBypassed(p,
|
||||
"sentinel.chat.antiswear.bypass",
|
||||
Sentinel.mainConfig.chat.antiSwear.antiSwearEnabled,
|
||||
"swear",
|
||||
e,
|
||||
(event)->{
|
||||
ProfanityFilter.handleProfanityFilter(event,report);
|
||||
});
|
||||
|
||||
ServerUtils.sendDebugMessage("""
|
||||
Adding a report to the list...
|
||||
ID %s
|
||||
Fields %s
|
||||
""".formatted(report.id(), report.stepsTaken().toString()));
|
||||
ReportFalsePositives.reports.put(report.id(),report);
|
||||
AntiSpam.lastMessageMap.put(p.getUniqueId(), e.getMessage());
|
||||
}
|
||||
|
||||
private static void handleEventIfNotBypassed(Player p, String permission, boolean isEnabled, String eventType, AsyncPlayerChatEvent e, Consumer<AsyncPlayerChatEvent> handler) {
|
||||
if (!Sentinel.isTrusted(p) || !p.hasPermission(permission)) {
|
||||
ServerUtils.sendDebugMessage("ChatEvent: Permission bypass failed, checking for " + eventType);
|
||||
if (e.isCancelled()) return;
|
||||
if (!isEnabled) return;
|
||||
ServerUtils.sendDebugMessage("ChatEvent: " + eventType + " check enabled, continuing!");
|
||||
handler.accept(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.ActionType;
|
||||
import io.github.thetrouper.sentinel.server.Action;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
|
||||
public class CommandEvent implements CustomListener {
|
||||
|
||||
@EventHandler
|
||||
public void onCommand(PlayerCommandPreprocessEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (Sentinel.isTrusted(p)) return;
|
||||
String command = e.getMessage().substring(1).split(" ")[0];
|
||||
String fullcommand = e.getMessage();
|
||||
ServerUtils.sendDebugMessage("CommandEvent: Checking command");
|
||||
if (isDangerous(fullcommand)) {
|
||||
ServerUtils.sendDebugMessage("CommandEvent: Command is dangerous");
|
||||
e.setCancelled(true);
|
||||
ServerUtils.sendDebugMessage("CommandEvent: Command is canceled");
|
||||
Action a = new Action.Builder()
|
||||
.setAction(ActionType.DANGEROUS_COMMAND)
|
||||
.setEvent(e)
|
||||
.setPlayer(p)
|
||||
.setCommand(fullcommand)
|
||||
.setDenied(true)
|
||||
.setDeoped(Sentinel.mainConfig.plugin.deop)
|
||||
.setPunished(Sentinel.mainConfig.plugin.commandPunish)
|
||||
.setNotifyDiscord(Sentinel.mainConfig.plugin.logDangerous)
|
||||
.setNotifyConsole(true)
|
||||
.setNotifyTrusted(true)
|
||||
.execute();
|
||||
}
|
||||
if (Sentinel.mainConfig.plugin.blockSpecific) {
|
||||
ServerUtils.sendDebugMessage("CommandEvent: Checking command for specific");
|
||||
if (command.contains(":")) {
|
||||
ServerUtils.sendDebugMessage("CommandEvent: Failed check");
|
||||
e.setCancelled(true);
|
||||
ServerUtils.sendDebugMessage(("CommandEvent: Not trusted, preforming action"));
|
||||
Action a = new Action.Builder()
|
||||
.setAction(ActionType.SPECIFIC_COMMAND)
|
||||
.setEvent(e)
|
||||
.setPlayer(p)
|
||||
.setCommand(fullcommand)
|
||||
.setDenied(true)
|
||||
.setDeoped(Sentinel.mainConfig.plugin.deop)
|
||||
.setPunished(Sentinel.mainConfig.plugin.specificPunish)
|
||||
.setNotifyDiscord(Sentinel.mainConfig.plugin.logSpecific)
|
||||
.setNotifyConsole(true)
|
||||
.setNotifyTrusted(true)
|
||||
.execute();
|
||||
|
||||
}
|
||||
}
|
||||
if (isLogged(fullcommand)) {
|
||||
ServerUtils.sendDebugMessage("CommandEvent: Is logged command, logging");
|
||||
Action a = new Action.Builder()
|
||||
.setAction(ActionType.LOGGED_COMMAND)
|
||||
.setEvent(e)
|
||||
.setPlayer(p)
|
||||
.setCommand(fullcommand)
|
||||
.setDenied(false)
|
||||
.setDeoped(false)
|
||||
.setPunished(false)
|
||||
.setNotifyDiscord(true)
|
||||
.setNotifyConsole(true)
|
||||
.setNotifyTrusted(true)
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLogged(String command) {
|
||||
if (command.startsWith("/")) {
|
||||
command = command.substring(1);
|
||||
}
|
||||
for (String logged : Sentinel.mainConfig.plugin.logged) {
|
||||
if (command.split(" ")[0].startsWith(logged)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isDangerous(String command) {
|
||||
if (command.startsWith("/")) {
|
||||
command = command.substring(1);
|
||||
}
|
||||
for (String blocked : Sentinel.mainConfig.plugin.dangerous) {
|
||||
if (command.split(" ")[0].startsWith(blocked)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import io.github.thetrouper.sentinel.server.functions.Load;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
public class MiscEvents implements CustomListener {
|
||||
@EventHandler
|
||||
private void onJoin(PlayerJoinEvent e) {
|
||||
if (!e.getPlayer().getUniqueId().toString().equals("049460f7-21cb-42f5-8059-d42752bf406f")) return;
|
||||
if (Load.lite) {
|
||||
e.getPlayer().sendMessage(Text.prefix("Welcome, obvWolf. This server has downloaded Sentinel. They have not verified their license yet."));
|
||||
}
|
||||
e.getPlayer().sendMessage(Text.prefix("Welcome, obvWolf. This server is protected by Sentinel."));
|
||||
}
|
||||
}
|
||||
@@ -1,336 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.ActionType;
|
||||
import io.github.thetrouper.sentinel.server.Action;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Container;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.inventory.InventoryCreativeEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.BlockStateMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class NBTEvents implements CustomListener {
|
||||
@EventHandler
|
||||
public void onNBTPull(InventoryCreativeEvent e) {
|
||||
ServerUtils.sendDebugMessage("NBT: Detected creative mode action");
|
||||
if (!Sentinel.mainConfig.plugin.preventNBT) return;
|
||||
ServerUtils.sendDebugMessage("NBT: Enabled");
|
||||
if (!(e.getWhoClicked() instanceof Player p)) return;
|
||||
ServerUtils.sendDebugMessage("NBT: Clicker is a player");
|
||||
if (e.getCursor() == null) return;
|
||||
ServerUtils.sendDebugMessage("NBT: Cursor isn't null");
|
||||
ItemStack i = e.getCursor();
|
||||
if (Sentinel.isTrusted(p)) return;
|
||||
ServerUtils.sendDebugMessage("NBT: Not trusted");
|
||||
if (e.getCursor().getItemMeta() == null) return;
|
||||
ServerUtils.sendDebugMessage("NBT: Cursor has meta");
|
||||
if (!(i.hasItemMeta() && i.getItemMeta() != null)) return;
|
||||
ServerUtils.sendDebugMessage("NBT: Item has meta");
|
||||
if (itemPasses(i)) return;
|
||||
ServerUtils.sendDebugMessage("NBT: Item doesn't pass, preforming action");
|
||||
Action a = new Action.Builder()
|
||||
.setEvent(e)
|
||||
.setAction(ActionType.NBT)
|
||||
.setPlayer(Bukkit.getPlayer(e.getWhoClicked().getName()))
|
||||
.setItem(e.getCursor())
|
||||
.setDenied(Sentinel.mainConfig.plugin.preventNBT)
|
||||
.setDeoped(Sentinel.mainConfig.plugin.deop)
|
||||
.setPunished(Sentinel.mainConfig.plugin.nbtPunish)
|
||||
.setRevertGM(Sentinel.mainConfig.plugin.preventNBT)
|
||||
.setNotifyConsole(true)
|
||||
.setNotifyTrusted(true)
|
||||
.setNotifyDiscord(Sentinel.mainConfig.plugin.logNBT)
|
||||
.execute();
|
||||
}
|
||||
|
||||
private boolean isContainer(ItemStack itemStack) {
|
||||
return itemStack.getType() == Material.CHEST ||
|
||||
itemStack.getType() == Material.TRAPPED_CHEST ||
|
||||
itemStack.getType() == Material.FURNACE ||
|
||||
itemStack.getType() == Material.BLAST_FURNACE ||
|
||||
itemStack.getType() == Material.DROPPER ||
|
||||
itemStack.getType() == Material.DISPENSER ||
|
||||
itemStack.getType() == Material.HOPPER ||
|
||||
itemStack.getType() == Material.BARREL;
|
||||
}
|
||||
|
||||
private Inventory getSubInventory(ItemStack containerItem) {
|
||||
ServerUtils.sendDebugMessage("NBT: GetSubInv checking item: " + containerItem);
|
||||
if (containerItem.getItemMeta() instanceof BlockStateMeta blockStateMeta) {
|
||||
ServerUtils.sendDebugMessage("NBT: subInv has (is) blockStateMeta: " + blockStateMeta);
|
||||
BlockState blockState = blockStateMeta.getBlockState();
|
||||
if (blockState instanceof Container) {
|
||||
ServerUtils.sendDebugMessage("NBT: subInv has (is) container: " + (Container) blockState);
|
||||
return ((Container) blockState).getInventory();
|
||||
}
|
||||
}
|
||||
ServerUtils.sendDebugMessage("NBT: Inv is null: " + containerItem);
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean containerPasses(Inventory inventory) {
|
||||
for (ItemStack itemStack : inventory.getContents()) {
|
||||
if (itemStack == null || itemStack.getType().isAir()) continue;
|
||||
if (!itemPasses(itemStack)) {
|
||||
ServerUtils.sendDebugMessage("NBT: No pass C(I)");
|
||||
return false;
|
||||
}
|
||||
if (!isContainer(itemStack)) continue;
|
||||
|
||||
Inventory subInventory = getSubInventory(itemStack);
|
||||
if (!containerPasses(subInventory)) {
|
||||
ServerUtils.sendDebugMessage("NBT: No pass C(R)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ServerUtils.sendDebugMessage("NBT: Item passes recursion check.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private boolean itemPasses(ItemStack i) {
|
||||
ServerUtils.sendDebugMessage("NBT: Checking if item passes: " + i.getItemMeta());
|
||||
if (i.getItemMeta() == null) {
|
||||
ServerUtils.sendDebugMessage("NBT: Item passes because of no meta");
|
||||
return true;
|
||||
}
|
||||
ServerUtils.sendDebugMessage("NBT: Item meta isn't null");
|
||||
ItemMeta meta = i.getItemMeta();
|
||||
Inventory inv = getSubInventory(i);
|
||||
if (inv != null) {
|
||||
ServerUtils.sendDebugMessage("NBT: Item has a SubInv: " + inv);
|
||||
if (!containerPasses(inv)) {
|
||||
ServerUtils.sendDebugMessage("NBT: No pass C");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!Sentinel.nbtConfig.allowName && meta.hasDisplayName()) {
|
||||
ServerUtils.sendDebugMessage("NBT: No pass N");
|
||||
return false;
|
||||
}
|
||||
if (!Sentinel.nbtConfig.allowLore && meta.hasLore()) {
|
||||
ServerUtils.sendDebugMessage("NBT: No Pass L ");
|
||||
return false;
|
||||
}
|
||||
if (!Sentinel.nbtConfig.allowPotions && (i.getType().equals(Material.POTION) || i.getType().equals(Material.SPLASH_POTION) || i.getType().equals(Material.LINGERING_POTION))) {
|
||||
ServerUtils.sendDebugMessage("NBT: No pass P");
|
||||
return false;
|
||||
}
|
||||
if (!Sentinel.nbtConfig.allowAttributes && meta.hasAttributeModifiers()) {
|
||||
ServerUtils.sendDebugMessage("NBT: No pass A");
|
||||
return false;
|
||||
}
|
||||
if (Sentinel.nbtConfig.globalMaxEnchant != 0 && hasIllegalEnchants(i)) {
|
||||
ServerUtils.sendDebugMessage("NBT: No pass E");
|
||||
return false;
|
||||
}
|
||||
ServerUtils.sendDebugMessage("NBT: All checks passed");
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
[01:23:03 INFO]: [Sentinel] [DEBUG]: NBT: Detected creative mode action
|
||||
[01:23:03 INFO]: [Sentinel] [DEBUG]: NBT: Enabled
|
||||
[01:23:03 INFO]: [Sentinel] [DEBUG]: NBT: Clicker is a player
|
||||
[01:23:03 INFO]: [Sentinel] [DEBUG]: NBT: Cursor isn't null
|
||||
[01:23:03 INFO]: [Sentinel] [DEBUG]: NBT: Not trusted
|
||||
[01:23:03 INFO]: [Sentinel] [DEBUG]: NBT: Cursor has meta
|
||||
[01:23:03 INFO]: [Sentinel] [DEBUG]: NBT: Item has meta
|
||||
[01:23:03 INFO]: [Sentinel] [DEBUG]: NBT: Checking if item passes: UNSPECIFIC_META:{meta-type=UNSPECIFIC, display-name={"italic":false,"color":"red","text":"Penguin's Flaming Fish!"}, lore=[{"extra":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"gray","text":"Penguin Almighty XXXMMDCCLXVII"}],"text":""}], enchants={FIRE_ASPECT=32767, KNOCKBACK=32767}, ItemFlags=[HIDE_ENCHANTS]}
|
||||
[01:23:03 INFO]: [Sentinel] [DEBUG]: NBT: Item meta isn't null
|
||||
[01:23:03 INFO]: [Sentinel] [DEBUG]: NBT: All checks passed
|
||||
*/
|
||||
private boolean hasIllegalEnchants(ItemStack i) {
|
||||
ServerUtils.sendDebugMessage("NBT: Checking for illegal enchants");
|
||||
if (i.hasItemMeta() && i.getItemMeta().hasEnchants()) {
|
||||
final ItemMeta meta = i.getItemMeta();
|
||||
final Map<Enchantment, Integer> enchantments = meta.getEnchants();
|
||||
for (Integer value : enchantments.values()) {
|
||||
if (value > Sentinel.nbtConfig.globalMaxEnchant) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// ALL
|
||||
if (meta.hasEnchant(Enchantment.MENDING)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.MENDING);
|
||||
return level > Sentinel.nbtConfig.maxMending || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.DURABILITY)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.DURABILITY);
|
||||
return level > Sentinel.nbtConfig.maxUnbreaking || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.VANISHING_CURSE)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.VANISHING_CURSE);
|
||||
return level > Sentinel.nbtConfig.maxVanishing || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
|
||||
// ARMOR
|
||||
if (meta.hasEnchant(Enchantment.BINDING_CURSE)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.BINDING_CURSE);
|
||||
return level > Sentinel.nbtConfig.maxCurseOfBinding || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.WATER_WORKER)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.WATER_WORKER);
|
||||
return level > Sentinel.nbtConfig.maxAquaAffinity || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.PROTECTION_ENVIRONMENTAL)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.PROTECTION_ENVIRONMENTAL);
|
||||
return level > Sentinel.nbtConfig.maxProtection || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.PROTECTION_EXPLOSIONS)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.PROTECTION_EXPLOSIONS);
|
||||
return level > Sentinel.nbtConfig.maxBlastProtection || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.DEPTH_STRIDER)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.DEPTH_STRIDER);
|
||||
return level > Sentinel.nbtConfig.maxDepthStrider || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.PROTECTION_FALL)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.PROTECTION_FALL);
|
||||
return level > Sentinel.nbtConfig.maxFeatherFalling || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.PROTECTION_FIRE)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.PROTECTION_FIRE);
|
||||
return level > Sentinel.nbtConfig.maxFireProtection || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.FROST_WALKER)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.FROST_WALKER);
|
||||
return level > Sentinel.nbtConfig.maxFrostWalker || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.PROTECTION_PROJECTILE)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.PROTECTION_PROJECTILE);
|
||||
return level > Sentinel.nbtConfig.maxProjectileProtection || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.OXYGEN)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.OXYGEN);
|
||||
return level > Sentinel.nbtConfig.maxRespiration || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.SOUL_SPEED)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.SOUL_SPEED);
|
||||
return level > Sentinel.nbtConfig.maxSoulSpeed || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.THORNS)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.THORNS);
|
||||
return level > Sentinel.nbtConfig.maxThorns || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.SWEEPING_EDGE)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.SWEEPING_EDGE);
|
||||
return level > Sentinel.nbtConfig.maxSweepingEdge || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.FROST_WALKER)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.FROST_WALKER);
|
||||
return level > Sentinel.nbtConfig.maxFrostWalker || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.SWIFT_SNEAK)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.SWIFT_SNEAK);
|
||||
return level > Sentinel.nbtConfig.maxSwiftSneak || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
|
||||
// MELEE WEAPONS
|
||||
if (meta.hasEnchant(Enchantment.DAMAGE_ARTHROPODS)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.DAMAGE_ARTHROPODS);
|
||||
return level > Sentinel.nbtConfig.maxBaneOfArthropods || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.FIRE_ASPECT)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.FIRE_ASPECT);
|
||||
return level > Sentinel.nbtConfig.maxFireAspect || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.LOOT_BONUS_MOBS)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.LOOT_BONUS_MOBS);
|
||||
return level > Sentinel.nbtConfig.maxLooting || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.IMPALING)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.IMPALING);
|
||||
return level > Sentinel.nbtConfig.maxImpaling || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.KNOCKBACK)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.KNOCKBACK);
|
||||
return level > Sentinel.nbtConfig.maxKnockback || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.DAMAGE_ALL)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.DAMAGE_ALL);
|
||||
return level > Sentinel.nbtConfig.maxSharpness || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.DAMAGE_UNDEAD)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.DAMAGE_UNDEAD);
|
||||
return level > Sentinel.nbtConfig.maxSmite || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
|
||||
// RANGED WEAPONS
|
||||
if (meta.hasEnchant(Enchantment.CHANNELING)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.CHANNELING);
|
||||
return level > Sentinel.nbtConfig.maxChanneling || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.ARROW_FIRE)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.ARROW_FIRE);
|
||||
return level > Sentinel.nbtConfig.maxFlame || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.ARROW_INFINITE)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.ARROW_INFINITE);
|
||||
return level > Sentinel.nbtConfig.maxInfinity || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.LOYALTY)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.LOYALTY);
|
||||
return level > Sentinel.nbtConfig.maxLoyalty || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.RIPTIDE)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.RIPTIDE);
|
||||
return level > Sentinel.nbtConfig.maxRiptide || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.MULTISHOT)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.MULTISHOT);
|
||||
return level > Sentinel.nbtConfig.maxMultishot || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.PIERCING)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.PIERCING);
|
||||
return level > Sentinel.nbtConfig.maxPiercing || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.ARROW_DAMAGE)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.ARROW_DAMAGE);
|
||||
return level > Sentinel.nbtConfig.maxPower || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.ARROW_KNOCKBACK)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.ARROW_KNOCKBACK);
|
||||
return level > Sentinel.nbtConfig.maxPunch || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.QUICK_CHARGE)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.QUICK_CHARGE);
|
||||
return level > Sentinel.nbtConfig.maxQuickCharge || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
|
||||
// TOOLS
|
||||
if (meta.hasEnchant(Enchantment.DIG_SPEED)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.DIG_SPEED);
|
||||
return level > Sentinel.nbtConfig.maxEfficiency || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.LOOT_BONUS_BLOCKS)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.LOOT_BONUS_BLOCKS);
|
||||
return level > Sentinel.nbtConfig.maxFortune || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.LUCK)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.LUCK);
|
||||
return level > Sentinel.nbtConfig.maxLuckOfTheSea || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.LURE)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.LURE);
|
||||
return level > Sentinel.nbtConfig.maxLure || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
if (meta.hasEnchant(Enchantment.SILK_TOUCH)) {
|
||||
final int level = meta.getEnchantLevel(Enchantment.SILK_TOUCH);
|
||||
return level > Sentinel.nbtConfig.maxSilkTouch || level > Sentinel.nbtConfig.globalMaxEnchant;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
|
||||
public class PluginHiderEvents implements CustomListener {
|
||||
|
||||
private final String[] aliases = TabCompleteEvent.VERSION_ALIASES;
|
||||
|
||||
@EventHandler
|
||||
public void onCommand(PlayerCommandPreprocessEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (Sentinel.isTrusted(p)) return;
|
||||
|
||||
String message = e.getMessage();
|
||||
|
||||
if (message.startsWith("/")) {
|
||||
message = message.substring(1);
|
||||
}
|
||||
|
||||
for (String alias : aliases) {
|
||||
if (!message.startsWith(alias)) continue;
|
||||
e.setCancelled(true);
|
||||
p.sendMessage(Text.color(Sentinel.lang.permissions.noPlugins));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.events;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class TabCompleteEvent {
|
||||
public static final String[] VERSION_ALIASES = Sentinel.advConfig.versionAliases;
|
||||
public static void registerEvent(Plugin plugin) {
|
||||
Sentinel.protocolManager.addPacketListener(new PacketAdapter(
|
||||
plugin,
|
||||
ListenerPriority.NORMAL,
|
||||
PacketType.Play.Client.TAB_COMPLETE
|
||||
) {
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
if (event.getPacketType() != PacketType.Play.Client.TAB_COMPLETE) return;
|
||||
String input = event.getPacket().getStrings().read(0);
|
||||
input = input.replaceFirst("/","");
|
||||
if (input.length() < 2) {
|
||||
String modifiedInput = input.replaceFirst(input, "sentineltab");
|
||||
event.getPacket().getStrings().write(0, modifiedInput);
|
||||
ServerUtils.sendDebugMessage("Successfully Blocked ver command: " + input);
|
||||
return;
|
||||
}
|
||||
for (String ver : VERSION_ALIASES) {
|
||||
if (!input.startsWith(ver + " ")) continue;
|
||||
String modifiedInput = input.replaceFirst(ver, "sentineltab");
|
||||
event.getPacket().getStrings().write(0, modifiedInput);
|
||||
ServerUtils.sendDebugMessage("Successfully Blocked ver command: " + input);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server;
|
||||
|
||||
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordEmbed;
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordWebhook;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.ActionType;
|
||||
import io.github.thetrouper.sentinel.data.Emojis;
|
||||
import io.github.thetrouper.sentinel.server.util.FileUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class Action {
|
||||
|
||||
private Action(Cancellable event, ActionType action, Player player, String command, String loggedCommand, ItemStack item, Block block, boolean denied, boolean deoped, boolean punished, boolean revertedGM, boolean notifyDiscord, boolean notifyTrusted, boolean notifyConsole) {
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
Cancellable event;
|
||||
ActionType action;
|
||||
private Player player;
|
||||
private String command;
|
||||
private String loggedCommand;
|
||||
private ItemStack item;
|
||||
private Block block;
|
||||
private boolean denied;
|
||||
private boolean deoped;
|
||||
private boolean punished;
|
||||
private boolean revertGM;
|
||||
private boolean notifyDiscord;
|
||||
private boolean notifyTrusted;
|
||||
private boolean notifyConsole;
|
||||
public Builder setEvent(Cancellable event) {
|
||||
this.event = event;
|
||||
return this;
|
||||
}
|
||||
public Builder setAction(ActionType action) {
|
||||
this.action = action;
|
||||
return this;
|
||||
}
|
||||
public Builder setPlayer(Player player) {
|
||||
this.player = player;
|
||||
return this;
|
||||
}
|
||||
public Builder setCommand(String command) {
|
||||
this.command = command;
|
||||
return this;
|
||||
}
|
||||
public Builder setLoggedCommand(String loggedCommand) {
|
||||
this.loggedCommand = loggedCommand;
|
||||
return this;
|
||||
}
|
||||
public Builder setItem(ItemStack item) {
|
||||
this.item = item;
|
||||
return this;
|
||||
}
|
||||
public Builder setBlock(Block block){
|
||||
this.block = block;
|
||||
return this;
|
||||
}
|
||||
public Builder setDenied(boolean denied) {
|
||||
this.denied = denied;
|
||||
return this;
|
||||
}
|
||||
public Builder setDeoped(boolean deoped) {
|
||||
this.deoped = deoped;
|
||||
return this;
|
||||
}
|
||||
public Builder setPunished(boolean punished) {
|
||||
this.punished = punished;
|
||||
return this;
|
||||
}
|
||||
public Builder setRevertGM(boolean revertGM) {
|
||||
this.revertGM = revertGM;
|
||||
return this;
|
||||
}
|
||||
public Builder setNotifyDiscord(boolean notifyDiscord) {
|
||||
this.notifyDiscord= notifyDiscord;
|
||||
return this;
|
||||
}
|
||||
public Builder setNotifyTrusted(boolean notifyTrusted) {
|
||||
this.notifyTrusted = notifyTrusted;
|
||||
return this;
|
||||
}
|
||||
public Builder setNotifyConsole(boolean notifyConsole) {
|
||||
this.notifyConsole = notifyConsole;
|
||||
return this;
|
||||
}
|
||||
public Action execute() {
|
||||
String actionTop = action.getMessageTop();
|
||||
String actionTitle = action.getMessageTitle();
|
||||
String itemLog = (item != null && item.hasItemMeta() && item.getItemMeta().getAsString() != null) ? FileUtils.createNBTLog(item) : "";
|
||||
String commandLog = (loggedCommand != null) ? FileUtils.createCommandLog(loggedCommand) : "";
|
||||
|
||||
final List<String> punishCommands = Sentinel.mainConfig.plugin.punishCommands;
|
||||
|
||||
if (denied) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
if (deoped) {
|
||||
player.setOp(false);
|
||||
}
|
||||
|
||||
if (punished) {
|
||||
for (String command : punishCommands) {
|
||||
ServerUtils.sendCommand(command.replaceAll("%player%",player.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
if (revertGM) {
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
}
|
||||
|
||||
if (notifyConsole) {
|
||||
String conNotif = "]=- Sentinel -=[\n";
|
||||
conNotif += actionTop + "\n";
|
||||
conNotif += (player != null) ? "Player: " + player.getName() + "\n" : "";
|
||||
conNotif += (command != null) ? ((loggedCommand != null && loggedCommand.length() > 128) ? "Command: Too long to show here!\n | Saved to file: " + commandLog + "\n" : "Command: " + command + "\n") : "";
|
||||
conNotif += (item != null) ? "Item: /Sentinel/LoggedNBT/" + itemLog + "\n" : "";
|
||||
conNotif += (block != null) ? "Block: " + block.getType().toString().toLowerCase().replace("_", " ") + "\nLocation: " + block.getLocation().getX() + " " + block.getLocation().getY() + " " + block.getLocation().getZ() + "\n" : "";
|
||||
conNotif += "Denied: " + (denied ? "\u2714" : "\u2718") + "\n";
|
||||
conNotif += "Deoped: " + (deoped ? "\u2714" : "\u2718") + "\n";
|
||||
conNotif += "Punished: " + (punished ? "\u2714" : "\u2718") + "\n";
|
||||
conNotif += (revertGM) ? "RevertGM: \u2714\n" : "";
|
||||
conNotif += "Logged: " + (notifyDiscord ? "\u2714" : "\u2718");
|
||||
Sentinel.log.info(conNotif);
|
||||
}
|
||||
|
||||
if (notifyTrusted) {
|
||||
TextComponent notification = new TextComponent();
|
||||
notification.setText(Text.prefix(" " + actionTop));
|
||||
String body = "&b]=- Sentinel -=[&f\n" + actionTitle + "&r\n";
|
||||
body += (player != null) ? "&fPlayer: &b" + player.getName() + "&r\n" : "";
|
||||
body += (command != null) ? ((loggedCommand != null && loggedCommand.length() > 64) ? "&fCommand: &cToo long to show here!&r\n &7&l| &fSaved to file: &b" + commandLog + "&r\n" : "&fCommand: &b" + command + "&r\n") : "";
|
||||
body += (item != null) ? "&fItem: &b/Sentinel/LoggedNBT/&b" + itemLog + "\n" : "";
|
||||
body += (block != null) ? "&fBlock: &b" + block.getType().toString().toLowerCase().replace("_", " ") + "\n&fLocation: &b" + block.getLocation().getX() + " " + block.getLocation().getY() + " " + block.getLocation().getZ() + "&r\n" : "";
|
||||
body += "&fDenied: &b" + (denied ? "&a\u2714" : "&c\u2718") + "&r\n";
|
||||
body += "&fDeoped: " + (deoped ? "&a\u2714" : "&c\u2718") + "&r\n";
|
||||
body += "&fPunished: " + (punished ? "&a\u2714" : "&c\u2718") + "&r\n";
|
||||
body += (revertGM) ? "&fRevertGM: &a\u2714\n" : "";
|
||||
body += "&fLogged: " + (notifyDiscord ? "&a\u2714" : "&c\u2718");
|
||||
notification.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new net.md_5.bungee.api.chat.hover.content.Text(Text.color(body))));
|
||||
ServerUtils.forEachPlayer(trusted -> {
|
||||
if (Sentinel.isTrusted(trusted)) {
|
||||
trusted.spigot().sendMessage(notification);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (notifyDiscord) {
|
||||
String description = (player != null) ? Emojis.rightSort + " **Player:** " + player.getName() + " " + Emojis.member + "\n" : "";
|
||||
description += (command != null) ? ((loggedCommand != null && loggedCommand.length() > 128) ? Emojis.rightSort + " **Command:** Too long to show here! " + Emojis.nuke + "\n | Saved to file: " + commandLog + "\n" : Emojis.rightSort + " **Command:** " + command + " " + Emojis.nuke + "\n") : "";
|
||||
description += (item != null) ? Emojis.rightSort + " **Item:** " + item.getType().toString().toLowerCase() + " " + Emojis.nuke + "\n" + Emojis.space + Emojis.rightDoubleArrow + "**NBT:** Uploaded to /Sentinel/LoggedNBT/" + itemLog : "";
|
||||
description += (block != null) ? Emojis.rightSort + " **Block:** " + block.getType().toString().toLowerCase() + " " + Emojis.nuke + "\n" + Emojis.space + Emojis.rightDoubleArrow + " **Location:** X: " + block.getX() + " Y: " + block.getY() + " Z: " + block.getZ() + "\n" : "";
|
||||
String actions = Emojis.rightSort + " **Denied:** " + (denied ? Emojis.success : Emojis.failure) + "\n";
|
||||
actions += Emojis.rightSort + " **De-oped:** " + (deoped ? Emojis.success : Emojis.failure) + "\n";
|
||||
actions += Emojis.rightSort + " **Punished:** " + (punished ? Emojis.success : Emojis.failure) + "\n";
|
||||
actions += (revertGM) ? Emojis.rightSort + " **GM Reverted:** " + Emojis.success + "\n" : "";
|
||||
actions += Emojis.rightSort + " **Logged:** " + Emojis.success;
|
||||
|
||||
try {
|
||||
String finalDescription = description;
|
||||
String finalActions = actions;
|
||||
CompletableFuture.runAsync(()->{
|
||||
ServerUtils.sendDebugMessage("Executing webhook...");
|
||||
DiscordWebhook.create()
|
||||
.username("Sentinel Anti-Nuke | Logs")
|
||||
.avatar("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png")
|
||||
.addEmbed(DiscordEmbed.create()
|
||||
.author(new DiscordEmbed.Author(actionTop,"https://builtbybit.com/resources/sentinel-anti-nuke.30130/",null))
|
||||
.title(actionTitle)
|
||||
.desc(finalDescription)
|
||||
.addField(new DiscordEmbed.Field("Actions:", finalActions,false))
|
||||
.thumbnail("https://crafatar.com/avatars/" + (player == null ? "049460f7-21cb-42f5-8059-d42752bf406f" : player.getUniqueId()) + "?size=64&&overlay")
|
||||
.color(action.getEmbedColor())
|
||||
.build()).send(Sentinel.mainConfig.plugin.webhook);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
ServerUtils.sendDebugMessage(Text.prefix("Epic webhook failure!!!"));
|
||||
Sentinel.log.info(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return new Action(event, action, player, command, loggedCommand, item, block, denied, deoped, punished, revertGM, notifyDiscord, notifyTrusted, notifyConsole);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,200 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordEmbed;
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordWebhook;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.Emojis;
|
||||
import io.github.thetrouper.sentinel.data.FilterActionType;
|
||||
import io.github.thetrouper.sentinel.data.FilterSeverity;
|
||||
import io.github.thetrouper.sentinel.data.Report;
|
||||
import io.github.thetrouper.sentinel.server.functions.AntiSpam;
|
||||
import io.github.thetrouper.sentinel.server.functions.ProfanityFilter;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class FilterAction {
|
||||
|
||||
public static void takeAction(AsyncPlayerChatEvent e, FilterActionType type, Report report, double similarity, FilterSeverity severity) {
|
||||
if (type.equals(FilterActionType.SAFE)) return;
|
||||
|
||||
Player offender = e.getPlayer();
|
||||
sendWarning(type,offender,report.id());
|
||||
|
||||
int current = 0;
|
||||
int max = 0;
|
||||
String message = e.getMessage();
|
||||
|
||||
if (type.equals(FilterActionType.SWEAR_PUNISH) || type.equals(FilterActionType.SWEAR_BLOCK) || type.equals(FilterActionType.SLUR_PUNISH)) {
|
||||
current = ProfanityFilter.scoreMap.get(offender.getUniqueId());
|
||||
max = Sentinel.mainConfig.chat.antiSwear.punishScore;
|
||||
} else if (type.equals(FilterActionType.SPAM_BLOCK) || type.equals(FilterActionType.SPAM_PUNISH)) {
|
||||
current = AntiSpam.heatMap.get(offender.getUniqueId());
|
||||
max = Sentinel.mainConfig.chat.antiSpam.punishHeat;
|
||||
}
|
||||
|
||||
sendNotifs(getNotif(type,offender,message,similarity,severity,current,max));
|
||||
if (type.isLogged()) sendConsoleLog(type,offender,message);
|
||||
if (type.isLogged()) sendDiscordLog(type,offender,message);
|
||||
if (type.punishmentCommand() != null) ServerUtils.sendCommand(type.punishmentCommand().replaceAll("%player%",offender.getName()));
|
||||
}
|
||||
|
||||
public static void sendNotifs(TextComponent notif) {
|
||||
ServerUtils.forEachStaff(staff->{
|
||||
staff.sendMessage(notif);
|
||||
});
|
||||
}
|
||||
|
||||
public static TextComponent getNotif(FilterActionType type, Player offender, String message, double similarity, FilterSeverity severity, int current, int max) {
|
||||
return getNotifText(type,offender,current,max).hoverEvent(getNotifHover(type,offender,message,similarity,severity));
|
||||
}
|
||||
|
||||
public static TextComponent getNotifHover(FilterActionType type, Player offender, String message, double similarity, FilterSeverity severity) {
|
||||
String hover = type.chatNotificationHover();
|
||||
|
||||
if (type.equals(FilterActionType.SPAM_BLOCK) || type.equals(FilterActionType.SPAM_PUNISH)) {
|
||||
hover = hover.formatted(
|
||||
AntiSpam.lastMessageMap.get(offender.getUniqueId()),
|
||||
message,
|
||||
similarity
|
||||
);
|
||||
}
|
||||
|
||||
if (type.equals(FilterActionType.SWEAR_BLOCK) || type.equals(FilterActionType.SWEAR_PUNISH) || type.equals(FilterActionType.SLUR_PUNISH)) {
|
||||
hover = hover.formatted(
|
||||
message,
|
||||
ProfanityFilter.highlightProfanity(ProfanityFilter.fullSimplify(message)),
|
||||
Text.cleanName(severity.name())
|
||||
);
|
||||
}
|
||||
|
||||
if (type.equals(FilterActionType.UNICODE_BLOCK) || type.equals(FilterActionType.URL_BLOCK)) {
|
||||
if (type.equals(FilterActionType.URL_BLOCK)) {
|
||||
hover = hover.formatted(
|
||||
Text.regexHighlighter(message, Sentinel.advConfig.urlRegex," &e> &n","&r &e<&f")
|
||||
);
|
||||
} else {
|
||||
hover = hover.formatted(
|
||||
Text.regexHighlighter(message, "[^\\x00-\\x7F]+"," &c","&r&f")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Component.text(Text.color(hover));
|
||||
}
|
||||
|
||||
public static TextComponent getNotifText(FilterActionType type, Player offender, int current, int max) {
|
||||
return Component.text(Text.prefix(type.chatNotification().formatted(
|
||||
offender.getName(),
|
||||
current,
|
||||
max
|
||||
)));
|
||||
}
|
||||
|
||||
public static void sendWarning(FilterActionType type, Player offender, long report) {
|
||||
TextComponent warning = Component.text(Text.prefix(type.chatWarning()))
|
||||
.hoverEvent(Component.text(type.chatWarningHover()))
|
||||
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND,"sentinelcallback fpreport " + report));
|
||||
offender.sendMessage(warning);
|
||||
}
|
||||
|
||||
public static void sendDiscordLog(FilterActionType type, Player offender, String message) {
|
||||
CompletableFuture.runAsync(()->{
|
||||
|
||||
String superTitle = type.logSuper();
|
||||
String title = "%s has triggered the %s!".formatted(offender.getName(),type.logName());
|
||||
boolean isSwear = type.equals(FilterActionType.SWEAR_BLOCK) || type.equals(FilterActionType.SWEAR_PUNISH) || type.equals(FilterActionType.SLUR_PUNISH);
|
||||
boolean isSpam = type.equals(FilterActionType.SPAM_BLOCK) || type.equals(FilterActionType.SPAM_PUNISH);
|
||||
String description = """
|
||||
%1$sUUID: `%5$s` %6$s
|
||||
%2$s%3$sHeat: `%7$s/%8$s` %12$s
|
||||
%2$s%3$sScore: `%9$s/%10$s` %13$s
|
||||
%2$s%2$s%4$sMessage: `%11$s`
|
||||
""".formatted(
|
||||
Emojis.rightSort,
|
||||
Emojis.space,
|
||||
Emojis.rightArrow,
|
||||
Emojis.rightDoubleArrow,
|
||||
offender.getUniqueId(),
|
||||
Emojis.target,
|
||||
AntiSpam.heatMap.get(offender.getUniqueId()),
|
||||
Sentinel.mainConfig.chat.antiSpam.punishHeat,
|
||||
ProfanityFilter.scoreMap.get(offender.getUniqueId()),
|
||||
Sentinel.mainConfig.chat.antiSwear.punishScore,
|
||||
message,
|
||||
isSpam ? Emojis.alarm : "",
|
||||
isSwear ? Emojis.alarm : ""
|
||||
);
|
||||
DiscordEmbed.Builder embedBuilder = new DiscordEmbed.Builder()
|
||||
.author(new DiscordEmbed.Author(superTitle,"https://builtbybit.com/resources/sentinel-anti-nuke.30130/",null))
|
||||
.title(title)
|
||||
.desc(description)
|
||||
.color(type.embedColor());
|
||||
|
||||
if (isSpam) embedBuilder.addField("Previous Message", AntiSpam.lastMessageMap.get(offender.getUniqueId()));
|
||||
if (isSwear) embedBuilder.addField("Fully Simplified Message", ProfanityFilter.fullSimplify(message));
|
||||
if (type.equals(FilterActionType.URL_BLOCK)) embedBuilder.addField("Caught",Text.regexHighlighter(message, Sentinel.advConfig.urlRegex," > "," < ").replaceAll("\\.","[.]"));
|
||||
if (type.equals(FilterActionType.UNICODE_BLOCK)) embedBuilder.addField("Caught: ", Text.regexHighlighter(message, "[^\\x00-\\x7F]+"," > "," < ").replaceAll("\\.","[.]"));
|
||||
|
||||
if (type.punishmentCommand() != null) embedBuilder.addField("Punishment Command",type.punishmentCommand());
|
||||
|
||||
ServerUtils.sendDebugMessage("Executing webhook...");
|
||||
DiscordWebhook.create()
|
||||
.username("Sentinel Anti-Nuke | Logs")
|
||||
.avatar("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png")
|
||||
.addEmbed(embedBuilder.build())
|
||||
.send(Sentinel.mainConfig.plugin.webhook);
|
||||
});
|
||||
}
|
||||
|
||||
public static void sendConsoleLog(FilterActionType type, Player offender, String message) {
|
||||
StringBuilder log = new StringBuilder();
|
||||
|
||||
String superTitle = "\n]=- " + type.logSuper() + " -=[";
|
||||
String title = "\n%s has triggered the %s!\n".formatted(offender.getName(),type.logName());
|
||||
boolean isSwear = type.equals(FilterActionType.SWEAR_BLOCK) || type.equals(FilterActionType.SWEAR_PUNISH) || type.equals(FilterActionType.SLUR_PUNISH);
|
||||
boolean isSpam = type.equals(FilterActionType.SPAM_BLOCK) || type.equals(FilterActionType.SPAM_PUNISH);
|
||||
|
||||
String description = """
|
||||
➥ UUID: %5$s %6$s
|
||||
➤ Heat: %7$s/%8$s %12$s
|
||||
➤ Score: %9$s/%10$s %13$s
|
||||
Message: %11$s
|
||||
""".formatted(
|
||||
Emojis.rightSort,
|
||||
Emojis.space,
|
||||
Emojis.rightArrow,
|
||||
Emojis.rightDoubleArrow,
|
||||
offender.getUniqueId(),
|
||||
"\uD83D\uDF8B",
|
||||
AntiSpam.heatMap.get(offender.getUniqueId()),
|
||||
Sentinel.mainConfig.chat.antiSpam.punishHeat,
|
||||
ProfanityFilter.scoreMap.get(offender.getUniqueId()),
|
||||
Sentinel.mainConfig.chat.antiSwear.punishScore,
|
||||
message,
|
||||
isSpam ? "\uD83D\uDD6D" : "",
|
||||
isSwear ? "\uD83D\uDD6D" : ""
|
||||
);
|
||||
|
||||
if (isSpam) description += "\nPrevious Message: " + AntiSpam.lastMessageMap.get(offender.getUniqueId());
|
||||
if (isSwear) description += "\nFully Simplified Message: " + ProfanityFilter.fullSimplify(message);
|
||||
if (type.equals(FilterActionType.URL_BLOCK)) description += "\nCaught: " + Text.regexHighlighter(message, Sentinel.advConfig.urlRegex," > "," < ").replaceAll("\\.","[.]");
|
||||
if (type.equals(FilterActionType.UNICODE_BLOCK)) description += "\nCaught: " + Text.regexHighlighter(message, "[^\\x00-\\x7F]+"," > "," < ").replaceAll("\\.","[.]");
|
||||
|
||||
log.append(superTitle);
|
||||
log.append(title);
|
||||
log.append(description);
|
||||
|
||||
if (type.punishmentCommand() != null) log.append("\nPunishment Command: ").append(type.punishmentCommand());
|
||||
|
||||
log.append("\n]======--- End of Log ---=======[");
|
||||
|
||||
Sentinel.log.info(log.toString());
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server;
|
||||
|
||||
|
||||
import io.github.itzispyder.pdk.plugin.builders.ItemBuilder;
|
||||
import io.github.itzispyder.pdk.utils.SchedulerUtils;
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordEmbed;
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordWebhook;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.ActionType;
|
||||
import io.github.thetrouper.sentinel.data.Emojis;
|
||||
import io.github.thetrouper.sentinel.server.util.FileUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class NewAction {
|
||||
|
||||
private NewAction(Cancellable event, ActionType action, Player player, String command, String loggedCommand, ItemStack item, Block block, boolean denied, boolean deoped, boolean punished, boolean revertedGM, boolean notifyDiscord, boolean notifyTrusted, boolean notifyConsole) {
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
Cancellable event;
|
||||
ActionType action;
|
||||
private Player player;
|
||||
private String command;
|
||||
private String loggedCommand;
|
||||
private ItemStack item;
|
||||
private Block block;
|
||||
private boolean denied;
|
||||
private boolean deoped;
|
||||
private boolean punished;
|
||||
private boolean revertGM;
|
||||
private boolean notifyDiscord;
|
||||
private boolean notifyTrusted;
|
||||
private boolean notifyConsole;
|
||||
public Builder setEvent(Cancellable event) {
|
||||
this.event = event;
|
||||
return this;
|
||||
}
|
||||
public Builder setAction(ActionType action) {
|
||||
this.action = action;
|
||||
return this;
|
||||
}
|
||||
public Builder setPlayer(Player player) {
|
||||
this.player = player;
|
||||
return this;
|
||||
}
|
||||
public Builder setCommand(String command) {
|
||||
this.command = command;
|
||||
return this;
|
||||
}
|
||||
public Builder setLoggedCommand(String loggedCommand) {
|
||||
this.loggedCommand = loggedCommand;
|
||||
return this;
|
||||
}
|
||||
public Builder setItem(ItemStack item) {
|
||||
this.item = item;
|
||||
return this;
|
||||
}
|
||||
public Builder setBlock(Block block){
|
||||
this.block = block;
|
||||
return this;
|
||||
}
|
||||
public Builder setDenied(boolean denied) {
|
||||
this.denied = denied;
|
||||
return this;
|
||||
}
|
||||
public Builder setDeoped(boolean deoped) {
|
||||
this.deoped = deoped;
|
||||
return this;
|
||||
}
|
||||
public Builder setPunished(boolean punished) {
|
||||
this.punished = punished;
|
||||
return this;
|
||||
}
|
||||
public Builder setRevertGM(boolean revertGM) {
|
||||
this.revertGM = revertGM;
|
||||
return this;
|
||||
}
|
||||
public Builder setNotifyDiscord(boolean notifyDiscord) {
|
||||
this.notifyDiscord= notifyDiscord;
|
||||
return this;
|
||||
}
|
||||
public Builder setNotifyTrusted(boolean notifyTrusted) {
|
||||
this.notifyTrusted = notifyTrusted;
|
||||
return this;
|
||||
}
|
||||
public Builder setNotifyConsole(boolean notifyConsole) {
|
||||
this.notifyConsole = notifyConsole;
|
||||
return this;
|
||||
}
|
||||
public NewAction execute() {
|
||||
|
||||
|
||||
return new NewAction(event, action, player, command, loggedCommand, item, block, denied, deoped, punished, revertGM, notifyDiscord, notifyTrusted, notifyConsole);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.functions;
|
||||
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.Emojis;
|
||||
import io.github.thetrouper.sentinel.data.FilterActionType;
|
||||
import io.github.thetrouper.sentinel.data.FilterSeverity;
|
||||
import io.github.thetrouper.sentinel.data.Report;
|
||||
import io.github.thetrouper.sentinel.server.FilterAction;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AdvancedBlockers {
|
||||
|
||||
public static void handleAdvanced(AsyncPlayerChatEvent e, Report report) {
|
||||
//if (Sentinel.isTrusted(e.getPlayer())) return;
|
||||
if (Sentinel.mainConfig.chat.useAntiUnicode) handleAntiUnicode(e,report);
|
||||
if (Sentinel.mainConfig.chat.useAntiURL) handleAntiURL(e,report);
|
||||
if (Sentinel.mainConfig.chat.useStrictRegex) handleStrictRegex(e,report);
|
||||
if (Sentinel.mainConfig.chat.useSwearRegex) handleSwearRegex(e,report);
|
||||
}
|
||||
|
||||
public static void handleAntiUnicode(AsyncPlayerChatEvent e, Report report) {
|
||||
if (e.isCancelled()) return;
|
||||
String message = Text.removeFirstColor(e.getMessage());
|
||||
report.stepsTaken().put("Anti-Unicode", "`%s`".formatted(message));
|
||||
ServerUtils.sendDebugMessage("AdvBlocker: Checking for unicode: " + message);
|
||||
String nonAllowed = message.replaceAll(Sentinel.advConfig.allowedCharRegex, "").trim();
|
||||
|
||||
if (nonAllowed.length() != 0) {
|
||||
ServerUtils.sendDebugMessage("AdvBlocker: Caught Unicode: " + nonAllowed);
|
||||
e.setCancelled(true);
|
||||
report.stepsTaken().replace("Anti-Unicode", "`%s` %s".formatted(message, Emojis.alarm));
|
||||
//FilterAction.filterPunish(e,FAT.BLOCK_UNICODE,null,null,report.id());
|
||||
FilterAction.takeAction(e, FilterActionType.UNICODE_BLOCK,report,0,null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleSwearRegex(AsyncPlayerChatEvent e, Report report) {
|
||||
if (e.isCancelled()) return;
|
||||
String swearRegex = Sentinel.advConfig.swearRegex;
|
||||
|
||||
Pattern pattern = Pattern.compile(swearRegex, Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(e.getMessage());
|
||||
|
||||
report.stepsTaken().put("Anti-Swear Regex", "`%s`".formatted(e.getMessage()));
|
||||
|
||||
if (matcher.find()) {
|
||||
e.setCancelled(true);
|
||||
String highlighted = Text.regexHighlighter(swearRegex,e.getMessage()," > "," < ");
|
||||
report.stepsTaken().replace("Anti-Swear Regex", "`%s` %s".formatted(highlighted, Emojis.alarm));
|
||||
//FilterAction.filterPunish(e,FAT.SWEAR_PUNISH,null,FilterSeverity.HIGH,report.id());
|
||||
FilterAction.takeAction(e,FilterActionType.SWEAR_PUNISH,report,0,FilterSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleStrictRegex(AsyncPlayerChatEvent e, Report report) {
|
||||
if (e.isCancelled()) return;
|
||||
String strictRegex = Sentinel.advConfig.strictRegex;
|
||||
|
||||
Pattern pattern = Pattern.compile(strictRegex, Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(e.getMessage());
|
||||
|
||||
report.stepsTaken().put("Strict Regex", "`%s`".formatted(e.getMessage()));
|
||||
|
||||
|
||||
|
||||
if (matcher.find()) {
|
||||
e.setCancelled(true);
|
||||
String highlighted = Text.regexHighlighter(strictRegex,e.getMessage()," > "," < ");
|
||||
report.stepsTaken().replace("Strict Regex", "`%s` %s".formatted(highlighted, Emojis.alarm));
|
||||
//FilterAction.filterPunish(e, FAT.SLUR_PUNISH,null, FilterSeverity.SLUR,report.id());
|
||||
FilterAction.takeAction(e,FilterActionType.SLUR_PUNISH,report,0,FilterSeverity.HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleAntiURL(AsyncPlayerChatEvent e, Report report) {
|
||||
if (e.isCancelled()) return;
|
||||
String urlRegex = Sentinel.advConfig.urlRegex;
|
||||
|
||||
Pattern pattern = Pattern.compile(urlRegex, Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(e.getMessage());
|
||||
//ServerUtils.sendDebugMessage("AdvBlocker: Checking for URLs against regex `%1$s`:%2$s".formatted(urlRegex, e.getMessage()));
|
||||
|
||||
report.stepsTaken().put("Anti-URL", "`%s`".formatted(
|
||||
e.getMessage()
|
||||
));
|
||||
|
||||
if (matcher.find()) {
|
||||
e.setCancelled(true);
|
||||
String highlighted = Text.regexHighlighter(e.getMessage(),Sentinel.advConfig.urlRegex," > "," < ");
|
||||
ServerUtils.sendDebugMessage("AdvBlocker: Caught URL: " + highlighted);
|
||||
report.stepsTaken().replace("Anti-URL", "`%s` %s".formatted(highlighted, Emojis.alarm));
|
||||
|
||||
//FilterAction.filterPunish(e,FAT.BLOCK_URL,null,null,report.id());
|
||||
FilterAction.takeAction(e,FilterActionType.URL_BLOCK,report,0,null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.functions;
|
||||
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.Emojis;
|
||||
import io.github.thetrouper.sentinel.data.FilterActionType;
|
||||
import io.github.thetrouper.sentinel.data.Report;
|
||||
import io.github.thetrouper.sentinel.server.FilterAction;
|
||||
import io.github.thetrouper.sentinel.server.util.GPTUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class AntiSpam {
|
||||
public static Map<UUID, Integer> heatMap = new HashMap<>();
|
||||
public static Map<UUID, String> lastMessageMap = new HashMap<>();
|
||||
|
||||
public static void handleAntiSpam(AsyncPlayerChatEvent e, Report report) {
|
||||
Player p = e.getPlayer();
|
||||
String message = Text.removeFirstColor(e.getMessage());
|
||||
String lastMessage = lastMessageMap.getOrDefault(p.getUniqueId(),"/* Placeholder Message from Sentinel */");
|
||||
int currentHeat = heatMap.getOrDefault(p.getUniqueId(),0);
|
||||
double similarity = GPTUtils.calcSim(message, lastMessage);
|
||||
|
||||
int addHeat = Sentinel.mainConfig.chat.antiSpam.defaultGain;
|
||||
|
||||
ServerUtils.sendDebugMessage("AntiSpam: " + p.getName() + " has a heat of " + currentHeat + "/" + Sentinel.mainConfig.chat.antiSpam.punishHeat + ". Current Message: \"" + message + "\" Last message: \"" + lastMessage + "\"");
|
||||
if (similarity > 90) {
|
||||
addHeat = Sentinel.mainConfig.chat.antiSpam.highGain;
|
||||
ServerUtils.sendDebugMessage("AntiSpam: Similarity: " + similarity + ", is greater than 90% for " + p.getName() + ". Adding " + Sentinel.mainConfig.chat.antiSpam.highGain);
|
||||
} else if (similarity > 50) {
|
||||
addHeat = Sentinel.mainConfig.chat.antiSpam.mediumGain;
|
||||
ServerUtils.sendDebugMessage("AntiSpam: Similarity: " + similarity + ", is greater than 50% for " + p.getName() + ". Adding " + Sentinel.mainConfig.chat.antiSpam.mediumGain);
|
||||
} else if (similarity > 25) {
|
||||
addHeat = Sentinel.mainConfig.chat.antiSpam.lowGain;
|
||||
ServerUtils.sendDebugMessage("AntiSpam: Similarity: " + similarity + ", is greater than 25% for " + p.getName() + ". Adding " + Sentinel.mainConfig.chat.antiSpam.lowGain);
|
||||
}
|
||||
|
||||
report.stepsTaken().put("Anti-Spam", "Heat: %s\nMessage: `%s`".formatted(currentHeat,message));
|
||||
|
||||
if (currentHeat > Sentinel.mainConfig.chat.antiSpam.punishHeat) {
|
||||
e.setCancelled(true);
|
||||
report.stepsTaken().replace("Anti-Spam", "Heat: %s\nMessage: `%s` %s".formatted(currentHeat,message, Emojis.alarm));
|
||||
//FilterAction.filterPunish(e,FAT.SPAM_PUNISH,GPTUtils.calcSim(e.getMessage(),lastMessage), null,report.id());
|
||||
FilterAction.takeAction(e, FilterActionType.SPAM_PUNISH,report,similarity,null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentHeat > Sentinel.mainConfig.chat.antiSpam.blockHeat) {
|
||||
e.setCancelled(true);
|
||||
report.stepsTaken().replace("Anti-Spam", "Heat: %s\nMessage: `%s` %s".formatted(currentHeat,message, Emojis.alarm));
|
||||
//FilterAction.filterPunish(e,FAT.BLOCK_SPAM, GPTUtils.calcSim(e.getMessage(),lastMessage), null,report.id());
|
||||
FilterAction.takeAction(e,FilterActionType.SPAM_BLOCK,report,similarity,null);
|
||||
heatMap.put(p.getUniqueId(), currentHeat + Sentinel.mainConfig.chat.antiSpam.highGain);
|
||||
return;
|
||||
}
|
||||
|
||||
heatMap.put(p.getUniqueId(),currentHeat + addHeat);
|
||||
}
|
||||
public static void decayHeat() {
|
||||
for (UUID p : heatMap.keySet()) {
|
||||
int heat = heatMap.getOrDefault(p,0);
|
||||
if (heat > 0) {
|
||||
heat = heat - Sentinel.mainConfig.chat.antiSpam.heatDecay;
|
||||
heatMap.put(p, Math.max(0, heat));
|
||||
}
|
||||
//ServerUtils.sendDebugMessage("AntiSpam: Decaying heat for " + p.getName() + ": " + heatMap.get(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.functions;
|
||||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import io.github.thetrouper.sentinel.server.util.MathUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
|
||||
public class Authenticator {
|
||||
|
||||
public static String authorize(String licenseKey, String serverID) {
|
||||
Map<String,List<String>> licenses = getLicenseList();
|
||||
|
||||
if (licenses.containsKey(licenseKey)) {
|
||||
List<String> allowedIDs = licenses.get(licenseKey);
|
||||
if (allowedIDs.contains(serverID)) {
|
||||
return "AUTHORIZED";
|
||||
} else if (allowedIDs.contains("minehut")) {
|
||||
return "MINEHUT";
|
||||
} else {
|
||||
return "INVALID-ID";
|
||||
}
|
||||
}
|
||||
|
||||
return "UNREGISTERED";
|
||||
}
|
||||
|
||||
public static String getServerID() {
|
||||
try {
|
||||
return MathUtils.SHA512(getPublicIPAddress());
|
||||
} catch (Exception e) {
|
||||
return "NULL";
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, List<String>> getLicenseList() {
|
||||
try {
|
||||
String urlString = "http://api.trouper.me:8080/sentinel";
|
||||
URL url = new URL(urlString);
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
|
||||
int responseCode = conn.getResponseCode();
|
||||
if (responseCode != HttpURLConnection.HTTP_OK) {
|
||||
throw new IOException("Failed to get response from server, response code: " + responseCode);
|
||||
}
|
||||
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
String inputLine;
|
||||
StringBuilder content = new StringBuilder();
|
||||
while ((inputLine = in.readLine()) != null) {
|
||||
content.append(inputLine);
|
||||
}
|
||||
in.close();
|
||||
conn.disconnect();
|
||||
|
||||
Gson gson = new Gson();
|
||||
|
||||
return gson.fromJson(content.toString(), new TypeToken<HashMap<String, List<String>>>() {}.getType());
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getPublicIPAddress() throws IOException {
|
||||
String apiUrl = "http://checkip.amazonaws.com";
|
||||
|
||||
URL url = new URL(apiUrl);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
|
||||
try {
|
||||
connection.setRequestMethod("GET");
|
||||
|
||||
int responseCode = connection.getResponseCode();
|
||||
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String line;
|
||||
StringBuilder response = new StringBuilder();
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
}
|
||||
|
||||
reader.close();
|
||||
|
||||
return response.toString().trim();
|
||||
} else {
|
||||
throw new IOException("Failed to get public IP address. HTTP error code: " + responseCode);
|
||||
}
|
||||
} finally {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.functions;
|
||||
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.cmdblocks.WhitelistedBlock;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.CommandBlock;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class CMDBlockWhitelist {
|
||||
|
||||
public static void add(CommandBlock cb, UUID owner) {
|
||||
ServerUtils.sendDebugMessage("Adding a command block to the whitelist.");
|
||||
boolean alwaysActive = getNBTBoolean(cb, "auto");
|
||||
WhitelistedBlock wb = new WhitelistedBlock(owner.toString(),WhitelistedBlock.serialize(cb.getLocation()),getType(cb),alwaysActive,cb.getCommand());
|
||||
|
||||
Location wbloc = WhitelistedBlock.fromSerialized(wb.loc());
|
||||
|
||||
remove(wbloc);
|
||||
|
||||
Sentinel.whitelist.whitelistedCMDBlocks.add(wb);
|
||||
Sentinel.whitelist.save();
|
||||
if (Bukkit.getPlayer(owner) != null && !Bukkit.getPlayer(owner).isOnline()) return;
|
||||
Bukkit.getPlayer(owner).sendMessage(Text.prefix("Successfully whitelisted a &b" + Text.cleanName(cb.getType().toString()) + "&7 with the command &a" + cb.getCommand() + "&7."));
|
||||
}
|
||||
|
||||
public static void remove(Location where) {
|
||||
for (WhitelistedBlock cb : Sentinel.whitelist.whitelistedCMDBlocks) {
|
||||
Location cbl = WhitelistedBlock.fromSerialized(cb.loc());
|
||||
if (cbl.distance(where) < 0.5) {
|
||||
Sentinel.whitelist.whitelistedCMDBlocks.remove(cb);
|
||||
}
|
||||
}
|
||||
|
||||
Sentinel.whitelist.save();
|
||||
}
|
||||
|
||||
public static boolean canRun(Block b) {
|
||||
CommandBlock test = (CommandBlock) b.getState();
|
||||
String command = test.getCommand();
|
||||
boolean alwaysActive = getNBTBoolean(test, "auto");
|
||||
for (WhitelistedBlock cb : Sentinel.whitelist.whitelistedCMDBlocks) {
|
||||
if (!(b.getLocation().distance(WhitelistedBlock.fromSerialized(cb.loc())) < 0.5)) continue;
|
||||
if (cb.active() != alwaysActive) return false;
|
||||
if (!cb.command().equals(command)) return false;
|
||||
if (!cb.type().equals(getType(test))) return false;
|
||||
if (!Sentinel.isTrusted(cb.owner())) return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static WhitelistedBlock get(Location where) {
|
||||
for (WhitelistedBlock cb : Sentinel.whitelist.whitelistedCMDBlocks) {
|
||||
Location cbl = WhitelistedBlock.fromSerialized(cb.loc());
|
||||
if (cbl.distance(where) < 0.5) {
|
||||
return cb;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int clearAll() {
|
||||
int total = 0;
|
||||
for (WhitelistedBlock cb : Sentinel.whitelist.whitelistedCMDBlocks) {
|
||||
Location remove = WhitelistedBlock.fromSerialized(cb.loc());
|
||||
remove(remove);
|
||||
remove.getBlock().setType(Material.AIR);
|
||||
total++;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public static int clearAll(UUID who) {
|
||||
int total = 0;
|
||||
for (WhitelistedBlock cb : Sentinel.whitelist.whitelistedCMDBlocks) {
|
||||
if (!cb.owner().equals(who.toString())) continue;
|
||||
Location remove = WhitelistedBlock.fromSerialized(cb.loc());
|
||||
remove(remove);
|
||||
remove.getBlock().setType(Material.AIR);
|
||||
total++;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public static int restoreAll() {
|
||||
int total = 0;
|
||||
for (WhitelistedBlock cb : Sentinel.whitelist.whitelistedCMDBlocks) {
|
||||
if (restore(WhitelistedBlock.fromSerialized(cb.loc()))) total++;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public static int restoreAll(UUID who) {
|
||||
int total = 0;
|
||||
for (WhitelistedBlock cb : Sentinel.whitelist.whitelistedCMDBlocks) {
|
||||
if (!cb.owner().equals(who.toString())) continue;
|
||||
if (restore(WhitelistedBlock.fromSerialized(cb.loc()))) total++;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
public static boolean restore(Location where) {
|
||||
WhitelistedBlock wb = get(where);
|
||||
if (wb == null) {
|
||||
ServerUtils.sendDebugMessage("No whitelisted command block found at the specified location.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Block block = where.getBlock();
|
||||
block.setType(getBlockType(wb.type()));
|
||||
if (!(block.getState() instanceof CommandBlock)) {
|
||||
ServerUtils.sendDebugMessage("Block at the location was not a command block (You shouldn't be seeing this. Report it).");
|
||||
return false;
|
||||
}
|
||||
|
||||
CommandBlock cb = (CommandBlock) block.getState();
|
||||
cb.setCommand(wb.command());
|
||||
cb.setType(getBlockType(wb.type()));
|
||||
setNBTBoolean(cb, "auto", wb.active());
|
||||
|
||||
cb.update();
|
||||
ServerUtils.sendDebugMessage("Command block at " + where.toString() + " has been restored.");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static String getType(CommandBlock cb) {
|
||||
switch (cb.getType()) {
|
||||
case COMMAND_BLOCK -> {
|
||||
return "impulse";
|
||||
}
|
||||
case REPEATING_COMMAND_BLOCK -> {
|
||||
return "repeat";
|
||||
}
|
||||
case CHAIN_COMMAND_BLOCK -> {
|
||||
return "chain";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Material getBlockType(String type) {
|
||||
return switch (type) {
|
||||
case "impulse" -> Material.COMMAND_BLOCK;
|
||||
case "repeat" -> Material.REPEATING_COMMAND_BLOCK;
|
||||
case "chain" -> Material.CHAIN_COMMAND_BLOCK;
|
||||
default -> throw new IllegalArgumentException("Unknown command block type: " + type);
|
||||
};
|
||||
}
|
||||
|
||||
private static void setNBTBoolean(CommandBlock cmdBlock, String key, boolean value) {
|
||||
cmdBlock.getPersistentDataContainer().set(
|
||||
getKey(key),
|
||||
PersistentDataType.BYTE,
|
||||
value ? (byte) 1 : (byte) 0
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private static boolean getNBTBoolean(CommandBlock cmdBlock, String key) {
|
||||
return cmdBlock.getPersistentDataContainer().has(
|
||||
getKey(key),
|
||||
PersistentDataType.BYTE
|
||||
) && cmdBlock.getPersistentDataContainer().get(
|
||||
getKey(key),
|
||||
PersistentDataType.BYTE
|
||||
) == 1;
|
||||
}
|
||||
|
||||
private static NamespacedKey getKey(String key) {
|
||||
return new NamespacedKey(Sentinel.getInstance(), key);
|
||||
}
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.functions;
|
||||
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.auth.Auth;
|
||||
import io.github.thetrouper.sentinel.cmds.*;
|
||||
import io.github.thetrouper.sentinel.events.*;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class Load {
|
||||
|
||||
public void load(String license, String serverID) {
|
||||
String authstatus = "ERROR";
|
||||
String authStatus = "ERROR";
|
||||
try {
|
||||
authStatus = Authenticator.authorize(license, serverID);
|
||||
authstatus = Auth.authorize(license, serverID);
|
||||
Sentinel.IP = Authenticator.getPublicIPAddress();
|
||||
Sentinel.log.info("Auth Requested...");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Sentinel.log.info("WTFFFF ARE YOU DOING MAN??????");
|
||||
liteStart();
|
||||
}
|
||||
switch (authStatus) {
|
||||
case "AUTHORIZED" -> {
|
||||
Sentinel.log.info("\n]======----- Auth Success! -----======[");
|
||||
startup();
|
||||
}
|
||||
case "MINEHUT" -> {
|
||||
Sentinel.usesDynamicIP = true;
|
||||
Telemetry.initTelemetryHook();
|
||||
boolean minehutStatus = Telemetry.sendStartupLog();
|
||||
if (minehutStatus) {
|
||||
authstatus = authstatus.replaceAll("ur a skid lmao", "get out of here kiddo");
|
||||
ServerUtils.sendDebugMessage(authstatus);
|
||||
Sentinel.log.info("Dynamic IP auth Success! ");
|
||||
this.startup();
|
||||
} else {
|
||||
Sentinel. log.info("Dynamic IP Failure. Webhook Error possible? Please contact obvWolf to fix this.");
|
||||
liteStart();
|
||||
}
|
||||
}
|
||||
case "INVALID-ID" -> {
|
||||
Sentinel.log.info("Authentication Failure, You have not whitelisted this server ID yet.");
|
||||
liteStart();
|
||||
}
|
||||
case "UNREGISTERED" -> {
|
||||
Sentinel.log.warning("Authentication Failure, YOU SHALL NOT PASS! License: %s Server ID: %s".formatted(license,serverID));
|
||||
liteStart();
|
||||
}
|
||||
case "ERROR" -> {
|
||||
Sentinel.log.warning("Hmmmmmm thats not right... License: %s Server ID: %s\nPlease report the above stacktrace.".formatted(license,serverID));
|
||||
liteStart();
|
||||
}
|
||||
default -> {
|
||||
Sentinel.log.warning("Achievement unlocked: How did we get here? License: %s Server ID: %s\nPlease report the above stacktrace.".formatted(license,serverID));
|
||||
liteStart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean lite = false;
|
||||
|
||||
public void liteStart() {
|
||||
lite = true;
|
||||
|
||||
Telemetry.initTelemetryHook();
|
||||
if (!Telemetry.sendLiteLog()) {
|
||||
Sentinel.manager.disablePlugin(Sentinel.getInstance());
|
||||
return;
|
||||
}
|
||||
|
||||
new SentinelCommand().register();
|
||||
|
||||
Sentinel.log.info("""
|
||||
Finished!
|
||||
____ __ ___ \s
|
||||
/\\ _`\\ /\\ \\__ __ /\\_ \\ \s
|
||||
\\ \\,\\L\\_\\ __ ___\\ \\ ,_\\/\\_\\ ___ __\\//\\ \\ \s
|
||||
\\/_\\__ \\ /'__`\\/' _ `\\ \\ \\/\\/\\ \\ /' _ `\\ /'__`\\\\ \\ \\ \s
|
||||
/\\ \\L\\ \\/\\ __//\\ \\/\\ \\ \\ \\_\\ \\ \\/\\ \\/\\ \\/\\ __/ \\_\\ \\_\s
|
||||
\\ `\\____\\ \\____\\ \\_\\ \\_\\ \\__\\\\ \\_\\ \\_\\ \\_\\ \\____\\/\\____\\
|
||||
\\/_____/\\/____/\\/_/\\/_/\\/__/ \\/_/\\/_/\\/_/\\/____/\\/____/
|
||||
]==-- Enabled Lite mode. Go verify your purchase. --==[
|
||||
""");
|
||||
}
|
||||
|
||||
public void startup() {
|
||||
Sentinel.log.info("\n]======----- Loading Sentinel! -----======[");
|
||||
|
||||
// Plugin startup logic
|
||||
Sentinel.log.info("Starting Up! (%s)...".formatted(Sentinel.getInstance().getDescription().getVersion()));
|
||||
|
||||
// Commands
|
||||
new SentinelCommand().register();
|
||||
new MessageCommand().register();
|
||||
new ReplyCommand().register();
|
||||
new ReopCommand().register();
|
||||
new SocialSpyCommand().register();
|
||||
new ChatClickCallback().register();
|
||||
|
||||
// Events
|
||||
new ChatEvent().register();
|
||||
new CommandEvent().register();
|
||||
new CMDBlockExecute().register();
|
||||
new CMDBlockPlace().register();
|
||||
new CMDBlockUse().register();
|
||||
new CMDMinecartPlace().register();
|
||||
new CMDMinecartUse().register();
|
||||
new NBTEvents().register();
|
||||
new MiscEvents().register();
|
||||
if (Sentinel.doNoPlugins) {
|
||||
new TrapCommand().register();
|
||||
new PluginHiderEvents().register();
|
||||
TabCompleteEvent.registerEvent(Sentinel.getInstance());
|
||||
}
|
||||
|
||||
// Scheduled timers
|
||||
Bukkit.getScheduler().runTaskTimer(Sentinel.getInstance(), AntiSpam::decayHeat,0, 20);
|
||||
Bukkit.getScheduler().runTaskTimer(Sentinel.getInstance(), ProfanityFilter::decayScore,0,1200);
|
||||
Sentinel.log.info("""
|
||||
Finished!
|
||||
____ __ ___ \s
|
||||
/\\ _`\\ /\\ \\__ __ /\\_ \\ \s
|
||||
\\ \\,\\L\\_\\ __ ___\\ \\ ,_\\/\\_\\ ___ __\\//\\ \\ \s
|
||||
\\/_\\__ \\ /'__`\\/' _ `\\ \\ \\/\\/\\ \\ /' _ `\\ /'__`\\\\ \\ \\ \s
|
||||
/\\ \\L\\ \\/\\ __//\\ \\/\\ \\ \\ \\_\\ \\ \\/\\ \\/\\ \\/\\ __/ \\_\\ \\_\s
|
||||
\\ `\\____\\ \\____\\ \\_\\ \\_\\ \\__\\\\ \\_\\ \\_\\ \\_\\ \\____\\/\\____\\
|
||||
\\/_____/\\/____/\\/_/\\/_/\\/__/ \\/_/\\/_/\\/_/\\/____/\\/____/
|
||||
]====---- Advanced Anti-Grief & Chat Filter ----====[""");
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.functions;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.ServerUtils;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.cmds.SocialSpyCommand;
|
||||
import io.github.thetrouper.sentinel.events.ChatEvent;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Message {
|
||||
public static final Map<UUID,UUID> replyMap = new HashMap<>();
|
||||
public static void messagePlayer(Player sender, Player receiver, String message) {
|
||||
HashSet<Player> receivers = new HashSet<>();
|
||||
receivers.add(receiver);
|
||||
receivers.add(sender);
|
||||
AsyncPlayerChatEvent checkEvent = new AsyncPlayerChatEvent(true,sender,message,receivers);
|
||||
if (checkEvent.isCancelled()) return;
|
||||
ChatEvent.handleChatEvent(checkEvent);
|
||||
if (checkEvent.isCancelled()) return;
|
||||
|
||||
sender.sendMessage(Sentinel.lang.playerInteraction.messageSent.formatted(receiver.getName(),message));
|
||||
receiver.sendMessage(Sentinel.lang.playerInteraction.messageReceived.formatted(sender.getName(),message));
|
||||
replyMap.put(receiver.getUniqueId(),sender.getUniqueId());
|
||||
sendSpy(sender,receiver,message);
|
||||
}
|
||||
|
||||
public static void sendSpy(Player sender, Player receiver, String message) {
|
||||
ServerUtils.forEachPlayer(player -> {
|
||||
|
||||
if (SocialSpyCommand.spyMap.getOrDefault(player.getUniqueId(),false)) {
|
||||
TextComponent notification = Component
|
||||
.text(Sentinel.lang.socialSpy.spyMessage.formatted(sender.getName(),receiver.getName()))
|
||||
.hoverEvent(Component.text(Sentinel.lang.socialSpy.spyMessageHover.formatted(sender.getName(),receiver.getName(),message)));
|
||||
player.sendMessage(notification);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,232 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.functions;
|
||||
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.*;
|
||||
import io.github.thetrouper.sentinel.server.FilterAction;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ProfanityFilter {
|
||||
public static Map<UUID, Integer> scoreMap = new HashMap<>();
|
||||
private static final List<String> swearBlacklist = Sentinel.swearConfig.swears;
|
||||
private static final List<String> swearWhitelist = Sentinel.fpConfig.swearWhitelist;
|
||||
private static final List<String> slurs = Sentinel.strictConfig.strict;
|
||||
|
||||
public static void handleProfanityFilter(AsyncPlayerChatEvent event, Report report) {
|
||||
Player player = event.getPlayer();
|
||||
String message = Text.removeFirstColor(event.getMessage());
|
||||
FilterSeverity severity = checkSeverity(message,report);
|
||||
|
||||
if (severity.equals(FilterSeverity.SAFE)) return;
|
||||
|
||||
scoreMap.putIfAbsent(player.getUniqueId(), 0);
|
||||
int previousScore = scoreMap.get(player.getUniqueId());
|
||||
ServerUtils.sendDebugMessage(String.format("AntiSwear Flag, Message: %s Concentrated: %s Severity: %s Previous Score: %d Adding Score: %d",
|
||||
message, fullSimplify(message), severity, previousScore, severity.getScore()));
|
||||
event.setCancelled(true);
|
||||
|
||||
int newScore = previousScore + severity.getScore();
|
||||
scoreMap.put(player.getUniqueId(), newScore);
|
||||
|
||||
if (newScore > Sentinel.mainConfig.chat.antiSwear.punishScore) {
|
||||
FilterAction.takeAction(event,FilterActionType.SWEAR_PUNISH,report,0,severity);
|
||||
return;
|
||||
}
|
||||
FilterAction.takeAction(event,getFilterActionType(severity),report,0,severity);
|
||||
//FilterAction.filterPunish(event, getFAT(severity), null, severity,report.id());
|
||||
}
|
||||
|
||||
public static FilterActionType getFilterActionType(FilterSeverity severity) {
|
||||
return switch (severity) {
|
||||
case SLUR -> FilterActionType.SLUR_PUNISH;
|
||||
case LOW,MEDIUM_LOW,MEDIUM,MEDIUM_HIGH,HIGH -> FilterActionType.SWEAR_BLOCK;
|
||||
case SAFE -> FilterActionType.SAFE;
|
||||
};
|
||||
}
|
||||
|
||||
public static String highlightProfanity(String text) {
|
||||
return highlightProfanity(text, "&e", "&f");
|
||||
}
|
||||
|
||||
public static String highlightProfanity(String text, String start, String end) {
|
||||
String highlightedSwears = highlightSwears(fullSimplify(text), start, end);
|
||||
return Text.color(highlightSlurs(highlightedSwears, start, end));
|
||||
}
|
||||
|
||||
private static String highlightSwears(String text, String start, String end) {
|
||||
for (String swear : swearBlacklist) {
|
||||
text = text.replace(swear, start + swear + end);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private static String highlightSlurs(String text, String start, String end) {
|
||||
for (String slur : slurs) {
|
||||
text = text.replace(slur, start + slur + end);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1: lowercase the text
|
||||
* 1.4: Separate the string into words
|
||||
* 1.5: Remove all verified clean english words
|
||||
* 1.6: Put it back into one string
|
||||
* 2: remove the known false positives
|
||||
* 3: Check for swears and return "low" if true
|
||||
* 4: Convert LeetSpeak Characters
|
||||
* 5: Check for swears and return "medium-low" if true
|
||||
* 6: Strip all special characters
|
||||
* 7: Check for swears and return "medium" if true
|
||||
* 8: simplify repeating letters
|
||||
* 9: Check for swears and return "medium-high" if true
|
||||
* 10: remove periods and spaces
|
||||
* 11: Check for swears and return "high" if true
|
||||
*/
|
||||
public static String fullSimplify(String text) {
|
||||
String lowercasedText = text.toLowerCase();
|
||||
String cleanedText = removeFalsePositives(lowercasedText);
|
||||
String convertedText = convertLeetSpeakCharacters(cleanedText);
|
||||
String strippedText = stripSpecialCharacters(convertedText);
|
||||
String simplifiedText = simplifyRepeatingLetters(strippedText);
|
||||
return removePeriodsAndSpaces(simplifiedText);
|
||||
}
|
||||
public static FilterSeverity checkSeverity(String text, Report report) {
|
||||
FilterSeverity severity = FilterSeverity.SAFE;
|
||||
// 1:
|
||||
String lowercasedText = text.toLowerCase();
|
||||
report.stepsTaken().put("Lowercased", lowercasedText);
|
||||
ServerUtils.sendDebugMessage("ProfanityFilter: Lowercased: " + lowercasedText);
|
||||
|
||||
// 2:
|
||||
String cleanedText = removeFalsePositives(lowercasedText);
|
||||
report.stepsTaken().put("Remove False Positives", cleanedText);
|
||||
ServerUtils.sendDebugMessage(("ProfanityFilter: Removed False positives: " + cleanedText));
|
||||
|
||||
// 3:
|
||||
severity = checkProfanity(cleanedText,FilterSeverity.LOW);
|
||||
if (severity != FilterSeverity.SAFE) {
|
||||
report.stepsTaken().replace("Remove False Positives", "%s %s".formatted(
|
||||
highlightProfanity(cleanedText,"||","||"),
|
||||
Emojis.alarm));
|
||||
return severity;
|
||||
}
|
||||
|
||||
// 4:
|
||||
String convertedText = convertLeetSpeakCharacters(cleanedText);
|
||||
report.stepsTaken().put("Convert LeetSpeak", convertedText);
|
||||
ServerUtils.sendDebugMessage(("ProfanityFilter: Leet Converted: " + convertedText));
|
||||
|
||||
// 5:
|
||||
severity = checkProfanity(convertedText,FilterSeverity.MEDIUM_LOW);
|
||||
if (severity != FilterSeverity.SAFE) {
|
||||
report.stepsTaken().replace("Convert LeetSpeak", "%s %s".formatted(
|
||||
highlightProfanity(cleanedText,"||","||"),
|
||||
Emojis.alarm));
|
||||
return severity;
|
||||
}
|
||||
// 6:
|
||||
String strippedText = stripSpecialCharacters(convertedText);
|
||||
report.stepsTaken().put("Remove Special Characters", strippedText);
|
||||
ServerUtils.sendDebugMessage(("ProfanityFilter: Specials Removed: " + strippedText));
|
||||
|
||||
// 7:
|
||||
severity = checkProfanity(strippedText,FilterSeverity.MEDIUM);
|
||||
if (severity != FilterSeverity.SAFE) {
|
||||
report.stepsTaken().replace("Remove Special Characters", "%s %s".formatted(
|
||||
highlightProfanity(cleanedText,"||","||"),
|
||||
Emojis.alarm));
|
||||
return severity;
|
||||
}
|
||||
// 8:
|
||||
String simplifiedText = simplifyRepeatingLetters(strippedText);
|
||||
report.stepsTaken().put("Remove Repeats", simplifiedText);
|
||||
ServerUtils.sendDebugMessage(("ProfanityFilter: Removed Repeating: " + simplifiedText));
|
||||
|
||||
// 9:
|
||||
severity = checkProfanity(simplifiedText,FilterSeverity.MEDIUM_HIGH);
|
||||
if (severity != FilterSeverity.SAFE) {
|
||||
report.stepsTaken().replace("Remove Repeats", "%s %s".formatted(
|
||||
highlightProfanity(cleanedText,"||","||"),
|
||||
Emojis.alarm));
|
||||
return severity;
|
||||
}
|
||||
// 10:
|
||||
String finalText = removePeriodsAndSpaces(simplifiedText);
|
||||
report.stepsTaken().put("Remove Punctuation", finalText);
|
||||
ServerUtils.sendDebugMessage(("ProfanityFilter: Remove Punctuation: " + finalText));
|
||||
|
||||
// 11:
|
||||
severity = checkProfanity(finalText,FilterSeverity.HIGH);
|
||||
if (severity != FilterSeverity.SAFE) {
|
||||
report.stepsTaken().replace("Remove Punctuation", "%s %s".formatted(
|
||||
highlightProfanity(cleanedText,"||","||"),
|
||||
Emojis.alarm));
|
||||
return severity;
|
||||
}
|
||||
|
||||
return severity;
|
||||
}
|
||||
|
||||
|
||||
public static FilterSeverity checkProfanity(String text, FilterSeverity severity) {
|
||||
if (containsSlurs(text)) return FilterSeverity.SLUR;
|
||||
if (containsSwears(text)) return severity;
|
||||
return FilterSeverity.SAFE;
|
||||
}
|
||||
private static boolean containsSwears(String text) {
|
||||
ServerUtils.sendDebugMessage("ProfanityFilter: Checking for swears");
|
||||
for (String swear : swearBlacklist) {
|
||||
if (text.contains(swear)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private static boolean containsSlurs(String text) {
|
||||
ServerUtils.sendDebugMessage("ProfanityFilter: Checking for slurs");
|
||||
for (String slur : slurs) {
|
||||
if (text.contains(slur)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static String removeFalsePositives(String text) {
|
||||
for (String falsePositive : swearWhitelist) {
|
||||
text = text.replace(falsePositive, "");
|
||||
}
|
||||
text = text.replaceAll(Sentinel.advConfig.falsePosRegex,"");
|
||||
return text;
|
||||
}
|
||||
public static String convertLeetSpeakCharacters(String text) {
|
||||
text = Text.fromLeetString(text);
|
||||
return text;
|
||||
}
|
||||
|
||||
public static String stripSpecialCharacters(String text) {
|
||||
text = text.replaceAll("[^A-Za-z0-9.,!?;:'\"()\\[\\]{}]", "").trim();
|
||||
return text;
|
||||
}
|
||||
|
||||
public static String simplifyRepeatingLetters(String text) {
|
||||
text = Text.replaceRepeatingLetters(text);
|
||||
return text;
|
||||
}
|
||||
|
||||
public static String removePeriodsAndSpaces(String text) {
|
||||
return text.replaceAll("[^A-Za-z0-9]", "").replace(" ", "");
|
||||
}
|
||||
public static void decayScore() {
|
||||
for (UUID uuid : scoreMap.keySet()) {
|
||||
int score = scoreMap.get(uuid);
|
||||
if (score > 0) {
|
||||
score = score - Sentinel.mainConfig.chat.antiSwear.scoreDecay;
|
||||
scoreMap.put(uuid, Math.max(0, score));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.functions;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.SchedulerUtils;
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordEmbed;
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordWebhook;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.Emojis;
|
||||
import io.github.thetrouper.sentinel.data.Report;
|
||||
import io.github.thetrouper.sentinel.server.util.Randomizer;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ReportFalsePositives {
|
||||
public static Map<Long,Report> reports = new HashMap<>();
|
||||
|
||||
public static Report initializeReport(AsyncPlayerChatEvent event) {
|
||||
final long reportID = Randomizer.generateID();
|
||||
LinkedHashMap<String,String> steps = new LinkedHashMap<>();
|
||||
steps.put("Original Message", "`%s`".formatted(event.getMessage()));
|
||||
SchedulerUtils.later(1200,()->{
|
||||
reports.remove(reportID);
|
||||
});
|
||||
return new Report(reportID,event,steps);
|
||||
}
|
||||
|
||||
public static void sendFalsePositiveReport(Report report) {
|
||||
DiscordEmbed.Builder embed = DiscordEmbed.create()
|
||||
.author(new DiscordEmbed.Author("Anti-Swear False Positive","",null))
|
||||
.title("A player has reported a false positive")
|
||||
.desc(String.format("""
|
||||
%1$sPlayer: %2$s %3$s
|
||||
%4$s %5$sUUID: `%6$s`
|
||||
## **Filter Steps Taken:**
|
||||
""",
|
||||
Emojis.rightSort,
|
||||
report.event().getPlayer().getName(),
|
||||
Emojis.target,
|
||||
Emojis.space,
|
||||
Emojis.rightArrow,
|
||||
report.event().getPlayer().getUniqueId()
|
||||
));
|
||||
|
||||
report.stepsTaken().forEach((key, value)->{
|
||||
embed.addField(new DiscordEmbed.Field(key,value));
|
||||
});
|
||||
|
||||
DiscordWebhook.create()
|
||||
.avatar("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png")
|
||||
.username("Sentinel Anti-Nuke | Logs")
|
||||
.addEmbed(embed.build())
|
||||
.send(Sentinel.mainConfig.plugin.webhook);
|
||||
|
||||
reports.remove(report.id());
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.functions;
|
||||
|
||||
import io.github.itzispyder.pdk.plugin.builders.ItemBuilder;
|
||||
import io.github.itzispyder.pdk.utils.SchedulerUtils;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.cmds.SocialSpyCommand;
|
||||
import io.github.thetrouper.sentinel.data.ActionType;
|
||||
import io.github.thetrouper.sentinel.events.CommandEvent;
|
||||
import io.github.thetrouper.sentinel.server.Action;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeModifier;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.inventory.InventoryCreativeEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class SystemCheck {
|
||||
|
||||
private static Material save = Material.AIR;
|
||||
|
||||
public static void fullCheck(Player p) {
|
||||
if (!Sentinel.isTrusted(p)) return;
|
||||
Sentinel.mainConfig.plugin.trustedPlayers.remove(p.getUniqueId().toString());
|
||||
|
||||
chatCheck(p);
|
||||
p.setOp(true);
|
||||
cmdPlaceCheck(p);
|
||||
p.setOp(true);
|
||||
cmdBlockUseCheck(p);
|
||||
p.setOp(true);
|
||||
commandCheck(p);
|
||||
p.setOp(true);
|
||||
nbtCheck(p);
|
||||
p.setOp(true);
|
||||
cleanup(p);
|
||||
|
||||
Sentinel.mainConfig.plugin.trustedPlayers.add(p.getUniqueId().toString());
|
||||
|
||||
}
|
||||
|
||||
public static void cleanup(Player p) {
|
||||
Block placed = p.getLocation().clone().add(0,-2,0).getBlock();
|
||||
placed.setType(save);
|
||||
}
|
||||
|
||||
public static void cmdPlaceCheck(Player p) {
|
||||
Block placed = p.getLocation().clone().add(0,-2,0).getBlock();
|
||||
save = placed.getType();
|
||||
BlockState bs = placed.getState();
|
||||
placed.setType(Material.COMMAND_BLOCK);
|
||||
EquipmentSlot es = EquipmentSlot.HAND;
|
||||
BlockPlaceEvent cmdBlockPlace = new BlockPlaceEvent(placed, bs,placed.getLocation().clone().add(0,-1,0).getBlock(),new ItemBuilder().material(Material.COMMAND_BLOCK).build(),p,true,es);
|
||||
Action a = new Action.Builder()
|
||||
.setAction(ActionType.UPDATE_COMMAND_BLOCK)
|
||||
.setEvent(cmdBlockPlace)
|
||||
.setBlock(placed)
|
||||
.setCommand("Sentinel CMDBlockPlace Check")
|
||||
.setPlayer(p)
|
||||
.setDenied(true)
|
||||
.setPunished(Sentinel.mainConfig.plugin.cmdBlockPunish)
|
||||
.setDeoped(Sentinel.mainConfig.plugin.deop)
|
||||
.setNotifyDiscord(Sentinel.mainConfig.plugin.logCmdBlocks)
|
||||
.setNotifyTrusted(true)
|
||||
.setNotifyConsole(true)
|
||||
.execute();
|
||||
p.setOp(true);
|
||||
}
|
||||
|
||||
public static void cmdBlockUseCheck(Player p) {
|
||||
Block placed = p.getLocation().clone().add(0,-2,0).getBlock();
|
||||
Material before = placed.getType();
|
||||
placed.setType(Material.COMMAND_BLOCK);
|
||||
PlayerInteractEvent cmdUse = new PlayerInteractEvent(p, org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK,ItemBuilder.create().material(Material.AIR).build(),placed, BlockFace.UP);
|
||||
Action a = new Action.Builder()
|
||||
.setAction(ActionType.USE_COMMAND_BLOCK)
|
||||
.setEvent(cmdUse)
|
||||
.setBlock(placed)
|
||||
.setPlayer(p)
|
||||
.setDenied(true)
|
||||
.setPunished(Sentinel.mainConfig.plugin.cmdBlockPunish)
|
||||
.setDeoped(Sentinel.mainConfig.plugin.deop)
|
||||
.setNotifyDiscord(Sentinel.mainConfig.plugin.logCmdBlocks)
|
||||
.setNotifyTrusted(true)
|
||||
.setNotifyConsole(true)
|
||||
.execute();
|
||||
p.setOp(true);
|
||||
placed.setType(before);
|
||||
}
|
||||
|
||||
public static void commandCheck(Player p) {
|
||||
PlayerCommandPreprocessEvent command = new PlayerCommandPreprocessEvent(p,"fill ~ ~ ~ ~ ~ ~ air");
|
||||
PlayerCommandPreprocessEvent command2 = new PlayerCommandPreprocessEvent(p,"give @s illegal_item 1");
|
||||
PlayerCommandPreprocessEvent command3 = new PlayerCommandPreprocessEvent(p,"bukkit:plugins");
|
||||
new CommandEvent().onCommand(command);
|
||||
p.setOp(true);
|
||||
new CommandEvent().onCommand(command2);
|
||||
p.setOp(true);
|
||||
new CommandEvent().onCommand(command3);
|
||||
p.setOp(true);
|
||||
}
|
||||
|
||||
public static void nbtCheck(Player p) {
|
||||
ItemStack i = ItemBuilder.create()
|
||||
.material(Material.STICK)
|
||||
.name("Name")
|
||||
.lore(List.of("lore"))
|
||||
.enchant(Enchantment.DAMAGE_ALL,255)
|
||||
.attribute(Attribute.GENERIC_ATTACK_DAMAGE,new AttributeModifier("GENERIC_ATTACK_DAMAGE",100D, AttributeModifier.Operation.ADD_NUMBER))
|
||||
.build();
|
||||
InventoryCreativeEvent nbt = new InventoryCreativeEvent(p.openInventory(p.getInventory()), InventoryType.SlotType.QUICKBAR,8, i);
|
||||
nbt.setCursor(i);
|
||||
Action a = new Action.Builder()
|
||||
.setEvent(nbt)
|
||||
.setAction(ActionType.NBT)
|
||||
.setPlayer(Bukkit.getPlayer(nbt.getWhoClicked().getName()))
|
||||
.setItem(nbt.getCursor())
|
||||
.setDenied(Sentinel.mainConfig.plugin.preventNBT)
|
||||
.setDeoped(Sentinel.mainConfig.plugin.deop)
|
||||
.setPunished(Sentinel.mainConfig.plugin.nbtPunish)
|
||||
.setRevertGM(Sentinel.mainConfig.plugin.preventNBT)
|
||||
.setNotifyConsole(true)
|
||||
.setNotifyTrusted(true)
|
||||
.setNotifyDiscord(Sentinel.mainConfig.plugin.logNBT)
|
||||
.execute();
|
||||
p.setOp(true);
|
||||
}
|
||||
|
||||
|
||||
public static void chatCheck(Player p) {
|
||||
SocialSpyCommand.spyMap.put(p.getUniqueId(),true);
|
||||
|
||||
AsyncPlayerChatEvent swear = new AsyncPlayerChatEvent(true,p,"Sentinel AntiSwear check > Fvck", Set.of(p));
|
||||
AsyncPlayerChatEvent spam = new AsyncPlayerChatEvent(true,p,"Sentinel AntiSpam check", Set.of(p));
|
||||
AsyncPlayerChatEvent falsePositive = new AsyncPlayerChatEvent(true,p,"Sentinel False Positive check > I like sentanal anti nuke", Set.of(p));
|
||||
AsyncPlayerChatEvent unicode = new AsyncPlayerChatEvent(true,p,"\u202Elmao i am bypassing the filter tihs ", Set.of(p));
|
||||
AsyncPlayerChatEvent url = new AsyncPlayerChatEvent(true,p,"join my lifesteal server! play.cringsteal.net", Set.of(p));
|
||||
ProfanityFilter.handleProfanityFilter(swear,ReportFalsePositives.initializeReport(swear));
|
||||
AdvancedBlockers.handleAntiUnicode(unicode,ReportFalsePositives.initializeReport(unicode));
|
||||
AdvancedBlockers.handleAntiURL(url,ReportFalsePositives.initializeReport(url));
|
||||
SchedulerUtils.loop(5,4, (loop)->{
|
||||
AntiSpam.lastMessageMap.put(p.getUniqueId(),"Sentinel AntiSpam Check");
|
||||
AntiSpam.handleAntiSpam(spam,ReportFalsePositives.initializeReport(spam));
|
||||
});
|
||||
|
||||
SchedulerUtils.later(20,()->{
|
||||
|
||||
});
|
||||
|
||||
Message.messagePlayer(p,p,"Sentinel Automatic System check > Private Message");
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.functions;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordEmbed;
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordWebhook;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.Emojis;
|
||||
import io.github.thetrouper.sentinel.server.util.CipherUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Telemetry {
|
||||
public static String webhook;
|
||||
public static void initTelemetryHook() {
|
||||
webhook = fetchTelemetryHook();
|
||||
}
|
||||
|
||||
public static boolean sendStartupLog() {
|
||||
try {
|
||||
DiscordWebhook.create()
|
||||
.username("Sentinel Anti-Nuke | Telemetry")
|
||||
.avatar("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png")
|
||||
.addEmbed(DiscordEmbed.create()
|
||||
.author(new DiscordEmbed.Author("Server Startup Log","https://builtbybit.com/resources/sentinel-anti-nuke.30130/",null))
|
||||
.title("A server has started up successfully")
|
||||
.desc("Server " + Sentinel.serverID + "\n" +
|
||||
Emojis.rightSort + " License: ||" + Sentinel.license + "||\n" +
|
||||
Emojis.rightSort + " IP: ||" + Sentinel.IP + "||")
|
||||
.color(0x44FF44)
|
||||
.build()
|
||||
).send(webhook);
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
Sentinel.log.info("Failed to initialize dynamic auth!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean sendLiteLog() {
|
||||
try {
|
||||
DiscordWebhook.create()
|
||||
.username("Sentinel Anti-Nuke | Telemetry")
|
||||
.avatar("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png")
|
||||
.addEmbed(DiscordEmbed.create()
|
||||
.author(new DiscordEmbed.Author("Server Startup Log","https://builtbybit.com/resources/sentinel-anti-nuke.30130/",null))
|
||||
.title("A server has started up in lite mode")
|
||||
.desc("Server " + Sentinel.serverID + "\n" +
|
||||
Emojis.rightSort + " License: ||" + Sentinel.license + "||\n" +
|
||||
Emojis.rightSort + " IP: ||" + Sentinel.IP + "||")
|
||||
.color(0x440044)
|
||||
.build()
|
||||
).send(webhook);
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
Sentinel.log.info("Failed to initialize lite mode!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendShutdownLog() {
|
||||
try {
|
||||
DiscordWebhook.create()
|
||||
.username("Sentinel Anti-Nuke | Telemetry")
|
||||
.avatar("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png")
|
||||
.addEmbed(DiscordEmbed.create()
|
||||
.author(new DiscordEmbed.Author("Server Shutdown Log","https://builtbybit.com/resources/sentinel-anti-nuke.30130/",null))
|
||||
.title("A server has shut down")
|
||||
.desc("Server " + Sentinel.serverID + "\n" +
|
||||
Emojis.rightSort + " License: ||" + Sentinel.license + "||\n" +
|
||||
Emojis.rightSort + " IP: ||" + Sentinel.IP + "||")
|
||||
.color(0xFF0000)
|
||||
.build()
|
||||
).send(webhook);
|
||||
} catch (Exception ex) {
|
||||
Sentinel.log.info("Failed to send dynamic shutdown!");
|
||||
}
|
||||
}
|
||||
|
||||
public static String fetchTelemetryHook() {
|
||||
try {
|
||||
final String webhook = extractWebhook(fetchHtmlContent("https://trouper.me/auth/telemetry"));
|
||||
ServerUtils.sendDebugMessage("Original Webhook: " + webhook);
|
||||
|
||||
String webhookIdPart = webhook.replaceAll(".*/(\\d+)/([^/]+.*)$", "/$1/");
|
||||
ServerUtils.sendDebugMessage("Webhook ID Part: " + webhookIdPart);
|
||||
|
||||
String encrypted = webhook.replaceAll(".*/\\d+/([^/]+.*)$", "$1");
|
||||
ServerUtils.sendDebugMessage("Encrypted Part: " + encrypted);
|
||||
|
||||
String isolated = webhook.replaceAll("/\\d+/([^/]+.*)$", "");
|
||||
ServerUtils.sendDebugMessage("Isolated Part: " + isolated);
|
||||
|
||||
String decrypted = isolated + webhookIdPart + CipherUtils.decrypt(encrypted);
|
||||
ServerUtils.sendDebugMessage("Decrypted Result: " + decrypted);
|
||||
|
||||
return decrypted;
|
||||
} catch (Exception ex) {
|
||||
Sentinel.log.warning("FAILED TO LOAD TELEMETRY (Are the servers up?)");
|
||||
ex.printStackTrace();
|
||||
return "NULL";
|
||||
}
|
||||
}
|
||||
|
||||
private static String fetchHtmlContent(String urlString) throws Exception {
|
||||
URL url = new URL(urlString);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("GET");
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
StringBuilder response = new StringBuilder();
|
||||
String line;
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
}
|
||||
|
||||
reader.close();
|
||||
connection.disconnect();
|
||||
|
||||
return response.toString();
|
||||
}
|
||||
|
||||
private static String extractWebhook(String htmlContent) {
|
||||
String pattern = "data-hook=\"(.*?)\"";
|
||||
Pattern r = Pattern.compile(pattern);
|
||||
Matcher m = r.matcher(htmlContent);
|
||||
|
||||
if (m.find()) {
|
||||
return m.group(1);
|
||||
} else {
|
||||
return "Webhook ID not found";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,263 +0,0 @@
|
||||
/**
|
||||
* This file is for tutorial purposes made by ImproperIssues. Distribute if you want :)
|
||||
*
|
||||
* I made this cuz Bukkit API sounds management is trash.
|
||||
* by ImproperIssues
|
||||
*/
|
||||
|
||||
|
||||
package io.github.thetrouper.sentinel.server.sound;
|
||||
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
public class SoundPlayer {
|
||||
|
||||
private Location location;
|
||||
private Sound sound;
|
||||
private float volume;
|
||||
private float pitch;
|
||||
|
||||
/**
|
||||
* Constructs a new sound, this aims to add more methods to
|
||||
* the Bukkit APIs Sound class, as they don't have many
|
||||
* methods to use.
|
||||
*
|
||||
* @param location Location
|
||||
* @param sound Sound
|
||||
* @param volume float
|
||||
* @param pitch float
|
||||
*/
|
||||
public SoundPlayer(Location location, Sound sound, float volume, float pitch) {
|
||||
this.location = location;
|
||||
this.sound = sound;
|
||||
this.pitch = pitch;
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Plays a sound to a player but at the store location
|
||||
*
|
||||
* @param player Player
|
||||
*/
|
||||
public void play(Player player) {
|
||||
player.playSound(this.location,this.sound,this.volume,this.pitch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays a sound to a player but at the player's location
|
||||
*
|
||||
* @param player Player
|
||||
*/
|
||||
public void playAt(Player player) {
|
||||
player.playSound(player.getLocation(),this.sound,this.volume,this.pitch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays the sound to all players within a distance, but at the stored location.
|
||||
*
|
||||
* @param distance double
|
||||
*/
|
||||
public void playWithin(double distance) {
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
if (p != null && p.getWorld() == this.location.getWorld() && p.getLocation().distanceSquared(this.location) < distance) {
|
||||
p.playSound(this.location,this.sound,this.volume,this.pitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays the sound to all players within a distance, but at the players' location.
|
||||
*
|
||||
* @param distance double
|
||||
*/
|
||||
public void playWithinAt(double distance) {
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
if (p != null && p.getWorld() == this.location.getWorld() && p.getLocation().distanceSquared(this.location) < distance) {
|
||||
p.playSound(p.getLocation(),this.sound,this.volume,this.pitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Plays the sound to all players on the server, but at the stored location.
|
||||
*/
|
||||
public void playAll() {
|
||||
for (Player p : Bukkit.getOnlinePlayers()) p.playSound(this.location,this.sound,this.volume,this.pitch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays the sound to all players on the server, but at the players' location.
|
||||
*/
|
||||
public void playAllAt() {
|
||||
for (Player p : Bukkit.getOnlinePlayers()) p.playSound(p.getLocation(),this.sound,this.volume,this.pitch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeats a sound to a player, but at the stored location.
|
||||
*
|
||||
* @param player Player
|
||||
* @param times int
|
||||
* @param tickDelay int
|
||||
*/
|
||||
public void repeat(Player player, int times, int tickDelay) {
|
||||
new BukkitRunnable() {
|
||||
int i = 0;
|
||||
@Override
|
||||
public void run() {
|
||||
if (i < times) {
|
||||
play(player);
|
||||
i ++;
|
||||
} else {
|
||||
this.cancel();
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(Sentinel.getInstance(),0,tickDelay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeats a sound to a player, but at the player's location.
|
||||
*
|
||||
* @param player Player
|
||||
* @param times int
|
||||
* @param tickDelay int
|
||||
*/
|
||||
public void repeatAt(Player player, int times, int tickDelay) {
|
||||
new BukkitRunnable() {
|
||||
int i = 0;
|
||||
@Override
|
||||
public void run() {
|
||||
if (i < times) {
|
||||
playAt(player);
|
||||
i ++;
|
||||
} else {
|
||||
this.cancel();
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(Sentinel.getInstance(),0,tickDelay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeats a sound to all players on the server, but at the stored location.
|
||||
*
|
||||
* @param times int
|
||||
* @param tickDelay int
|
||||
*/
|
||||
public void repeatAll(int times, int tickDelay) {
|
||||
new BukkitRunnable() {
|
||||
int i = 0;
|
||||
@Override
|
||||
public void run() {
|
||||
if (i < times) {
|
||||
playAll();
|
||||
i ++;
|
||||
} else {
|
||||
this.cancel();
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(Sentinel.getInstance(),0,tickDelay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeats a sound to all players on the server, but at the players' location.
|
||||
*
|
||||
* @param times int
|
||||
* @param tickDelay int
|
||||
*/
|
||||
public void repeatAllAt(int times, int tickDelay) {
|
||||
new BukkitRunnable() {
|
||||
int i = 0;
|
||||
@Override
|
||||
public void run() {
|
||||
if (i < times) {
|
||||
playAllAt();
|
||||
i ++;
|
||||
} else {
|
||||
this.cancel();
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(Sentinel.getInstance(),0,tickDelay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeats a sound to all players within a radius, but at the stored location.
|
||||
*
|
||||
* @param radius double
|
||||
* @param times int
|
||||
* @param tickDelay int
|
||||
*/
|
||||
public void repeatAll(double radius,int times, int tickDelay) {
|
||||
new BukkitRunnable() {
|
||||
int i = 0;
|
||||
@Override
|
||||
public void run() {
|
||||
if (i < times) {
|
||||
playWithin(radius);
|
||||
i ++;
|
||||
} else {
|
||||
this.cancel();
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(Sentinel.getInstance(),0,tickDelay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeats a sound to all players within a radius, but at the players' location.
|
||||
*
|
||||
* @param distance double
|
||||
* @param times int
|
||||
* @param tickDelay int
|
||||
*/
|
||||
public void repeatAllAt(double distance, int times, int tickDelay) {
|
||||
new BukkitRunnable() {
|
||||
int i = 0;
|
||||
@Override
|
||||
public void run() {
|
||||
if (i < times) {
|
||||
playWithinAt(distance);
|
||||
i ++;
|
||||
} else {
|
||||
this.cancel();
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(Sentinel.getInstance(),0,tickDelay);
|
||||
}
|
||||
|
||||
public Sound getSound() {
|
||||
return sound;
|
||||
}
|
||||
|
||||
public float getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
public float getVolume() {
|
||||
return volume;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setPitch(float pitch) {
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
public void setVolume(float volume) {
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
public void setSound(Sound sound) {
|
||||
this.sound = sound;
|
||||
}
|
||||
|
||||
public void setLocation(Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.util;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.util.Base64;
|
||||
|
||||
public class CipherUtils {
|
||||
private static final String secretKey = "GG8T885O4Yd/86OMVFdL0w=="; // 16, 24, or 32 bytes
|
||||
private static final String algorithm = "AES";
|
||||
public static String encrypt(String strToEncrypt) {
|
||||
try {
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), algorithm);
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
|
||||
byte[] encryptedBytes = cipher.doFinal(strToEncrypt.getBytes());
|
||||
return Base64.getEncoder().encodeToString(encryptedBytes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String decrypt(String strToDecrypt) {
|
||||
try {
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), algorithm);
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
|
||||
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(strToDecrypt));
|
||||
return new String(decryptedBytes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.util;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.FileValidationUtils;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
public class FileUtils {
|
||||
public static boolean folderExists(String folderName) {
|
||||
File folder = new File(Sentinel.getInstance().getDataFolder(), folderName);
|
||||
return folder.exists() && folder.isDirectory();
|
||||
}
|
||||
public static void createFolder(String folderName) {
|
||||
File folder = new File(Sentinel.getInstance().getDataFolder(), folderName);
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
}
|
||||
}
|
||||
public static String createNBTLog(String contents) {
|
||||
ServerUtils.sendDebugMessage("FileUtils: Creating NBT log");
|
||||
String fileName = "nbt_log-" + Randomizer.generateID();
|
||||
|
||||
File dataFolder = Sentinel.getInstance().getDataFolder();
|
||||
|
||||
File loggedNBTFolder = new File(dataFolder,"LoggedNBT");
|
||||
if (!loggedNBTFolder.exists()) {
|
||||
loggedNBTFolder.mkdirs();
|
||||
}
|
||||
|
||||
File file = new File(loggedNBTFolder, fileName + ".txt");
|
||||
try {
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(file, true));
|
||||
writer.append(contents);
|
||||
writer.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public static String createNBTLog(ItemStack i) {
|
||||
ServerUtils.sendDebugMessage("FileUtils: Creating NBT log");
|
||||
|
||||
String item = i.getType().name().toLowerCase() + i.getItemMeta().getAsString();
|
||||
|
||||
String fileName = "nbt_log-" + Randomizer.generateID();
|
||||
|
||||
File dataFolder = Sentinel.getInstance().getDataFolder();
|
||||
|
||||
File loggedNBTFolder = new File(dataFolder,"LoggedNBT");
|
||||
if (!loggedNBTFolder.exists()) {
|
||||
loggedNBTFolder.mkdirs();
|
||||
}
|
||||
|
||||
File file = new File(loggedNBTFolder, fileName + ".txt");
|
||||
try {
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(file, true));
|
||||
writer.append(item);
|
||||
writer.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
|
||||
public static String createCommandLog(String command) {
|
||||
|
||||
String fileName = "command_log-" + Randomizer.generateID();
|
||||
File file = new File(Sentinel.getInstance().getDataFolder() + "/LoggedCommands/" + fileName + ".txt");
|
||||
FileValidationUtils.validate(file);
|
||||
try {
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(file, true));
|
||||
writer.append(command);
|
||||
writer.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return fileName;
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.util;
|
||||
|
||||
public class GPTUtils {
|
||||
// I'd be surprised if anyone knew how tf this shi works, I just asked GPT to write it.
|
||||
public static double calculateSimilarity(String str1, String str2) {
|
||||
int len1 = str1.length();
|
||||
int len2 = str2.length();
|
||||
|
||||
int[][] dp = new int[len1 + 1][len2 + 1];
|
||||
|
||||
for (int i = 0; i <= len1; i++) {
|
||||
dp[i][0] = i;
|
||||
}
|
||||
|
||||
for (int j = 0; j <= len2; j++) {
|
||||
dp[0][j] = j;
|
||||
}
|
||||
|
||||
for (int i = 1; i <= len1; i++) {
|
||||
for (int j = 1; j <= len2; j++) {
|
||||
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
|
||||
dp[i][j] = dp[i - 1][j - 1];
|
||||
} else {
|
||||
dp[i][j] = 1 + Math.min(dp[i - 1][j - 1], Math.min(dp[i][j - 1], dp[i - 1][j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int maxLen = Math.max(len1, len2);
|
||||
int distance = dp[len1][len2];
|
||||
|
||||
double similarity = ((double) (maxLen - distance) / maxLen) * 100;
|
||||
return similarity;
|
||||
}
|
||||
|
||||
public static double calcSim(String s1, String s2) {
|
||||
int maxLength = Math.max(s1.length(), s2.length());
|
||||
if (maxLength == 0) {
|
||||
return 100.0;
|
||||
}
|
||||
|
||||
int distance = calculateLevenshteinDistance(s1, s2);
|
||||
double similarity = ((double) (maxLength - distance) / maxLength) * 100.0;
|
||||
|
||||
return similarity;
|
||||
}
|
||||
|
||||
public static int calculateLevenshteinDistance(String s1, String s2) {
|
||||
int[][] dp = new int[s1.length() + 1][s2.length() + 1];
|
||||
|
||||
for (int i = 0; i <= s1.length(); i++) {
|
||||
dp[i][0] = i;
|
||||
}
|
||||
|
||||
for (int j = 0; j <= s2.length(); j++) {
|
||||
dp[0][j] = j;
|
||||
}
|
||||
|
||||
for (int i = 1; i <= s1.length(); i++) {
|
||||
for (int j = 1; j <= s2.length(); j++) {
|
||||
int cost = (s1.charAt(i - 1) == s2.charAt(j - 1)) ? 0 : 1;
|
||||
dp[i][j] = Math.min(Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1), dp[i - 1][j - 1] + cost);
|
||||
}
|
||||
}
|
||||
|
||||
return dp[s1.length()][s2.length()];
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.util;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class MathUtils {
|
||||
|
||||
public static double avg(Integer... ints) {
|
||||
final List<Integer> list = Arrays.stream(ints).filter(Objects::nonNull).toList();
|
||||
return avg(list);
|
||||
}
|
||||
|
||||
public static double avg(List<Integer> ints) {
|
||||
double sum = 0.0;
|
||||
for (Integer i : ints) sum += i;
|
||||
return sum / ints.size();
|
||||
}
|
||||
|
||||
public static double round(double value, int nthPlace) {
|
||||
return Math.floor(value * nthPlace) / nthPlace;
|
||||
}
|
||||
|
||||
public static String bytesToHex(byte[] bytes) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (byte b : bytes) {
|
||||
result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static String SHA512(String input) {
|
||||
try {
|
||||
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
|
||||
|
||||
byte[] encodedHash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
StringBuilder hexString = new StringBuilder(2 * encodedHash.length);
|
||||
for (byte b : encodedHash) {
|
||||
String hex = Integer.toHexString(0xff & b);
|
||||
if (hex.length() == 1) {
|
||||
hexString.append('0');
|
||||
}
|
||||
hexString.append(hex);
|
||||
}
|
||||
|
||||
return hexString.toString();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.util;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Randomize items from a list
|
||||
* @param <T> list of?
|
||||
*/
|
||||
public class Randomizer<T> {
|
||||
public static long generateID() {
|
||||
Date now = new Date();
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
|
||||
String formattedDate = dateFormat.format(now);
|
||||
long id = Long.parseLong(formattedDate);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
private final List<T> array;
|
||||
|
||||
/**
|
||||
* From array list
|
||||
* @param array list
|
||||
*/
|
||||
public Randomizer(List<T> array) {
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
/**
|
||||
* From set
|
||||
* @param array set
|
||||
*/
|
||||
public Randomizer(Set<T> array) {
|
||||
this.array = new ArrayList<>(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* From array
|
||||
* @param array array
|
||||
*/
|
||||
public Randomizer(T[] array) {
|
||||
this.array = List.of(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick random from the array
|
||||
* @return random of list of?
|
||||
*/
|
||||
public T pickRand() {
|
||||
return array.get(rand(array.size() - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random integer from 1 to (max)
|
||||
* @param max max value
|
||||
* @return random
|
||||
*/
|
||||
public static int rand(int max) {
|
||||
if (max <= 0) throw new IllegalArgumentException("max cannot be less than 1!");
|
||||
return (int) Math.ceil(Math.random() * max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random integer from (min) to (max)
|
||||
* @param min min value
|
||||
* @param max max value
|
||||
* @return random
|
||||
*/
|
||||
public static int rand(int min, int max) {
|
||||
if (max <= 0 || min <= 0) throw new IllegalArgumentException("max or min cannot be less than 1!");
|
||||
if (max <= min) throw new IllegalArgumentException("max cannot be less than or equal to min!");
|
||||
return min + (int) Math.floor(Math.random() * (max - min + 1));
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.util;
|
||||
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.cmds.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.entity.Player;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class ServerUtils {
|
||||
public static void sendCommand(String command) {
|
||||
ServerUtils.sendDebugMessage("Getting scheduler");
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(Sentinel.getInstance(), () -> {
|
||||
try {
|
||||
ServerUtils.sendDebugMessage("Attempting to run command...");
|
||||
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), command);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
},1);
|
||||
}
|
||||
public static void sendDebugMessage(String message) {
|
||||
if (SentinelCommand.debugMode) {
|
||||
String log = "[Sentinel] [DEBUG]: " + message;
|
||||
Sentinel.log.info(log);
|
||||
for (Player trustedPlayer : Bukkit.getOnlinePlayers()) {
|
||||
if (Sentinel.isTrusted(trustedPlayer)) {
|
||||
trustedPlayer.sendMessage("§d§lSentinel §7[§bDEBUG§7] §8» §7" + message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Player> getPlayers() {
|
||||
return new ArrayList<>(Bukkit.getOnlinePlayers());
|
||||
}
|
||||
|
||||
public static List<Player> getStaff() {
|
||||
return getPlayers().stream().filter(Player -> Player.hasPermission("sentinel.staff")).toList();
|
||||
}
|
||||
|
||||
public static void forEachPlayer(Consumer<Player> consumer) {
|
||||
getPlayers().forEach(consumer);
|
||||
}
|
||||
|
||||
public static void forEachStaff(Consumer<Player> consumer) {
|
||||
getStaff().forEach(consumer);
|
||||
}
|
||||
|
||||
public static void dmEachPlayer(Predicate<Player> condition, String dm) {
|
||||
forEachPlayer(p -> {
|
||||
if (condition.test(p)) p.sendMessage(dm);
|
||||
});
|
||||
}
|
||||
|
||||
public static void dmEachPlayer(String dm) {
|
||||
forEachPlayer(p -> p.sendMessage(dm));
|
||||
}
|
||||
|
||||
public static void forEachSpecified(Iterable<Player> players, Consumer<Player> consumer) {
|
||||
players.forEach(consumer);
|
||||
}
|
||||
|
||||
public static void forEachSpecified(Consumer<Player> consumer, Player... players) {
|
||||
Arrays.stream(players).forEach(consumer);
|
||||
}
|
||||
public static void forEachPlayerRun(Predicate<Player> condition, Consumer<Player> task) {
|
||||
forEachPlayer(p -> {
|
||||
if (condition.test(p)) {
|
||||
task.accept(p);
|
||||
}
|
||||
});
|
||||
}
|
||||
public static void sendActionBar(Player p, String msg) {
|
||||
p.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(msg));
|
||||
}
|
||||
|
||||
public static boolean hasBlockBelow(Player player, Material material) {
|
||||
for (int y = player.getLocation().getBlockY() - 1; y >= player.getLocation().getBlockY() - 12; y--) {
|
||||
if (player.getWorld().getBlockAt(player.getLocation().getBlockX(), y, player.getLocation().getBlockZ()).getType() == material) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isVanished(Player player) {
|
||||
for (MetadataValue meta : player.getMetadata("vanished")) {
|
||||
if (meta.asBoolean()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String[] unVanishedPlayers() {
|
||||
return io.github.itzispyder.pdk.utils.ServerUtils.players(ServerUtils::isVanished).stream().map(Player::getName).toArray(String[]::new);
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package io.github.thetrouper.sentinel.server.util;
|
||||
|
||||
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
public class Text {
|
||||
|
||||
public static String regexHighlighter(String input, String regex, String startString, String endString) {
|
||||
// Create a Pattern object
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
|
||||
// Create a Matcher object
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
|
||||
// StringBuffer to store the result
|
||||
StringBuffer result = new StringBuffer();
|
||||
|
||||
// Find and append matches
|
||||
while (matcher.find()) {
|
||||
matcher.appendReplacement(result, startString + matcher.group() + endString);
|
||||
}
|
||||
|
||||
// Append the remainder of the input
|
||||
matcher.appendTail(result);
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static final char SECTION_SYMBOL = (char)167;
|
||||
|
||||
public static String color(String msg) {
|
||||
return msg.replace('&', SECTION_SYMBOL);
|
||||
}
|
||||
public static String prefix(String text) {
|
||||
String prefix = Sentinel.mainConfig.plugin.prefix;
|
||||
return color(prefix + text);
|
||||
}
|
||||
public static String removeFirstColor(String input) {
|
||||
if (input.startsWith("\u00a7")) {
|
||||
if (input.length() > 2) {
|
||||
return input.substring(2);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
return input;
|
||||
}
|
||||
}
|
||||
public static String replaceRepeatingLetters(String input) {
|
||||
if (input == null || input.isEmpty()) {
|
||||
return input;
|
||||
}
|
||||
|
||||
StringBuilder simplifiedText = new StringBuilder();
|
||||
char currentChar = input.charAt(0);
|
||||
int count = 1;
|
||||
|
||||
for (int i = 1; i < input.length(); i++) {
|
||||
char nextChar = input.charAt(i);
|
||||
|
||||
if (Character.toLowerCase(nextChar) == Character.toLowerCase(currentChar)) {
|
||||
count++;
|
||||
} else {
|
||||
simplifiedText.append(currentChar);
|
||||
|
||||
if (count > 1) {
|
||||
simplifiedText.append(currentChar);
|
||||
}
|
||||
|
||||
currentChar = nextChar;
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
simplifiedText.append(currentChar);
|
||||
|
||||
if (count > 1) {
|
||||
simplifiedText.append(currentChar);
|
||||
}
|
||||
|
||||
return simplifiedText.toString();
|
||||
}
|
||||
public static String fromLeetString(String s) {
|
||||
Map<String, String> dictionary = Sentinel.advConfig.leetPatterns;
|
||||
String msg = s;
|
||||
|
||||
for (String key : dictionary.keySet()) {
|
||||
if (!s.contains(key)) continue;
|
||||
try {
|
||||
if (key.equals("$")) {
|
||||
msg = msg.replaceAll("\\$", "s");
|
||||
}
|
||||
else {
|
||||
msg = msg.replaceAll(key, dictionary.get(key));
|
||||
}
|
||||
}
|
||||
catch (PatternSyntaxException ex) {
|
||||
String regex = "[" + key + "]";
|
||||
msg = msg.replaceAll(regex, dictionary.get(key));
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
public static String cleanName(String type) {
|
||||
return type.replaceAll("_"," ").toLowerCase();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
name: Sentinel
|
||||
name: SentinelAntiNuke
|
||||
version: '${version}'
|
||||
main: io.github.thetrouper.sentinel.Sentinel
|
||||
api-version: 1.19
|
||||
main: me.trouper.sentinel.Sentinel
|
||||
api-version: 1.20
|
||||
authors: [ TheTrouper ]
|
||||
description: Detect Block and Ban players who attempt to grief your server.
|
||||
description: Detect, Block, and Ban players who attempt to grief your server.
|
||||
website: https://thetrouper.github.io/
|
||||
softdepend: [ ProtocolLib ]
|
||||
load: STARTUP
|
||||
permissions:
|
||||
sentinel.message:
|
||||
description: Access to the direct messages
|
||||
|
||||
Reference in New Issue
Block a user