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:
127
src/main/java/me/trouper/sentinel/Sentinel.java
Normal file
127
src/main/java/me/trouper/sentinel/Sentinel.java
Normal file
@@ -0,0 +1,127 @@
|
||||
package me.trouper.sentinel;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import io.github.itzispyder.pdk.PDK;
|
||||
import io.github.itzispyder.pdk.utils.misc.config.JsonSerializable;
|
||||
import me.trouper.sentinel.data.WhitelistStorage;
|
||||
import me.trouper.sentinel.data.config.*;
|
||||
import me.trouper.sentinel.data.config.lang.LanguageFile;
|
||||
import me.trouper.sentinel.startup.Auth;
|
||||
import me.trouper.sentinel.startup.Load;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public final class Sentinel extends JavaPlugin {
|
||||
|
||||
private static final File dataFolder = new File("plugins/SentinelAntiNuke");
|
||||
public static final Logger log = Bukkit.getLogger();
|
||||
private static Sentinel instance;
|
||||
private static final File violationcfg = new File(Sentinel .dataFolder(),"/violation-config.json");
|
||||
private static final File cfgfile = new File(Sentinel.dataFolder(),"/main-config.json");
|
||||
private static final File nbtcfg = new File(Sentinel.dataFolder(), "/nbt-config.json");
|
||||
private static final File strctcfg = new File(Sentinel.dataFolder(), "/strict.json");
|
||||
private static final File swrcfg = new File(Sentinel.dataFolder(), "/swears.json");
|
||||
private static final File fpcfg = new File(Sentinel.dataFolder(), "/false-positives.json");
|
||||
private static final File advcfg = new File(Sentinel.dataFolder(), "/advanced-config.json");
|
||||
private static final File cmdWhitelist = new File(Sentinel.dataFolder(), "/storage/whitelist.json");
|
||||
|
||||
public static ViolationConfig violationConfig = JsonSerializable.load(violationcfg, ViolationConfig.class, new ViolationConfig());
|
||||
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 File us;
|
||||
|
||||
public static ProtocolManager protocolManager;
|
||||
public static boolean doNoPlugins = false;
|
||||
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
log.info("\n]======------ Pre-load started! ------======[");
|
||||
|
||||
PDK.init(this);
|
||||
instance = this;
|
||||
us = getFile();
|
||||
|
||||
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 attempt to hide your plugins through Bukkit's systems, although it may not catch everything.");
|
||||
}
|
||||
|
||||
log.info("Language Status: (%s)".formatted(lang.brokenLang));
|
||||
|
||||
log.info("Initializing Server ID...");
|
||||
|
||||
String serverID = Auth.getServerID();
|
||||
String license = Sentinel.mainConfig.plugin.license;
|
||||
String nonce = Auth.getNonce();
|
||||
int port = Auth.getPort();
|
||||
|
||||
log.info("Pre-load finished!\n]====---- Requesting Authentication ----====[ \n- License Key: %s\n- Server ID: %s\n- Nonce: %s\n".formatted(license,serverID,nonce));
|
||||
|
||||
Load.load(license,serverID);
|
||||
}
|
||||
|
||||
public static 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());
|
||||
violationConfig = JsonSerializable.load(violationcfg,ViolationConfig.class,new ViolationConfig());
|
||||
|
||||
|
||||
// Save
|
||||
mainConfig.save();
|
||||
advConfig.save();
|
||||
fpConfig.save();
|
||||
strictConfig.save();
|
||||
swearConfig.save();
|
||||
nbtConfig.save();
|
||||
violationConfig.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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
// Plugin shutdown logic
|
||||
log.info("Sentinel has disabled! (%s) Your server is now no longer protected!".formatted(getDescription().getVersion()));
|
||||
}
|
||||
|
||||
public static Sentinel getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static File dataFolder() {
|
||||
return dataFolder;
|
||||
}
|
||||
|
||||
}
|
||||
33
src/main/java/me/trouper/sentinel/data/Emojis.java
Normal file
33
src/main/java/me/trouper/sentinel/data/Emojis.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package me.trouper.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>";
|
||||
}
|
||||
20
src/main/java/me/trouper/sentinel/data/WhitelistStorage.java
Normal file
20
src/main/java/me/trouper/sentinel/data/WhitelistStorage.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package me.trouper.sentinel.data;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.config.JsonSerializable;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.types.WhitelistedBlock;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class WhitelistStorage implements JsonSerializable<WhitelistStorage> {
|
||||
@Override
|
||||
public File getFile() {
|
||||
File file = new File(Sentinel.dataFolder(), "/storage/whitelist.json");
|
||||
file.getParentFile().mkdirs();
|
||||
return file;
|
||||
}
|
||||
|
||||
public ConcurrentLinkedQueue<WhitelistedBlock> whitelistedCMDBlocks = new ConcurrentLinkedQueue<>();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package me.trouper.sentinel.data.config;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.config.JsonSerializable;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
|
||||
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> {
|
||||
public static String nonce = "%%__NONCE__%%";
|
||||
|
||||
@Override
|
||||
public File getFile() {
|
||||
File file = new File(Sentinel.dataFolder(), "/advanced-config.json");
|
||||
file.getParentFile().mkdirs();
|
||||
return file;
|
||||
}
|
||||
public List<String> fakePlugins = Arrays.asList(
|
||||
"nocheatplus",
|
||||
"negativity",
|
||||
"warden",
|
||||
"horizon",
|
||||
"illegalstack",
|
||||
"coreprotect",
|
||||
"exploitsx",
|
||||
"vulcan",
|
||||
"abc",
|
||||
"spartan",
|
||||
"kauri",
|
||||
"anticheatreloaded",
|
||||
"witherac",
|
||||
"godseye",
|
||||
"matrix",
|
||||
"wraith",
|
||||
"antixrayheuristics",
|
||||
"grimac"
|
||||
);
|
||||
|
||||
public List<String> versionAliases = List.of(
|
||||
"version",
|
||||
"bukkit:version",
|
||||
"ver",
|
||||
"bukkit:ver",
|
||||
"about",
|
||||
"bukkit:about",
|
||||
"?",
|
||||
"bukkit:?",
|
||||
"pl",
|
||||
"bukkit:pl",
|
||||
"plugins",
|
||||
"bukkit:plugins",
|
||||
"help",
|
||||
"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("8","ate");
|
||||
put("$", "s");
|
||||
put("!", "i");
|
||||
put("|_|","u");
|
||||
put("|", "i");
|
||||
put("+", "t");
|
||||
put("#", "h");
|
||||
put("@", "a");
|
||||
put("<", "c");
|
||||
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";
|
||||
}
|
||||
79
src/main/java/me/trouper/sentinel/data/config/FPConfig.java
Normal file
79
src/main/java/me/trouper/sentinel/data/config/FPConfig.java
Normal file
@@ -0,0 +1,79 @@
|
||||
package me.trouper.sentinel.data.config;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.config.JsonSerializable;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
|
||||
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(Sentinel.dataFolder(), "/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"
|
||||
));
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package me.trouper.sentinel.data.config;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.config.JsonSerializable;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class MainConfig implements JsonSerializable<MainConfig> {
|
||||
|
||||
public static String user = "%%__USER__%%";
|
||||
public static String username = "%%__USERNAME__%%";
|
||||
|
||||
@Override
|
||||
public File getFile() {
|
||||
File file = new File(Sentinel.dataFolder(), "/main-config.json");
|
||||
file.getParentFile().mkdirs();
|
||||
return file;
|
||||
}
|
||||
public Plugin plugin = new Plugin();
|
||||
public Chat chat = new Chat();
|
||||
public boolean debugMode = false;
|
||||
|
||||
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 reopCommand = false;
|
||||
public boolean pluginHider = true;
|
||||
public String identifier = "My Server (Edit in main-config.json)";
|
||||
}
|
||||
|
||||
public class Chat {
|
||||
public AntiSwear swearFilter = new AntiSwear();
|
||||
public AntiSpam spamFilter = new AntiSpam();
|
||||
public boolean useAntiURL = true;
|
||||
public boolean useSwearRegex = false;
|
||||
public boolean useStrictRegex = false;
|
||||
public boolean useAntiUnicode = true;
|
||||
|
||||
|
||||
public class AntiSpam {
|
||||
public boolean enabled = true;
|
||||
public int defaultGain = 1;
|
||||
public int lowGain = 2;
|
||||
public int mediumGain = 4;
|
||||
public int highGain = 6;
|
||||
public int heatDecay = 1;
|
||||
public int blockSimilarity = 99;
|
||||
public int blockHeat = 10;
|
||||
public int punishHeat = 25;
|
||||
public List<String> punishCommands = List.of(
|
||||
"clearchat",
|
||||
"mute %player% 1m Please refrain from spamming!"
|
||||
);
|
||||
}
|
||||
|
||||
public class AntiSwear {
|
||||
public boolean enabled = true;
|
||||
public int lowScore = 0;
|
||||
public int mediumLowScore = 1;
|
||||
public int mediumScore = 3;
|
||||
public int mediumHighScore = 5;
|
||||
public int highScore = 7;
|
||||
public int regexScore = 4;
|
||||
public int scoreDecay = 3;
|
||||
public int punishScore = 20;
|
||||
public List<String> swearPunishCommands = List.of(
|
||||
"mute %player% 15m Do not attempt to bypass the Profanity Filter"
|
||||
);
|
||||
public List<String> strictPunishCommands = List.of(
|
||||
"mute %player% 1h Discriminatory speech is not tolerated on this server!"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
60
src/main/java/me/trouper/sentinel/data/config/NBTConfig.java
Normal file
60
src/main/java/me/trouper/sentinel/data/config/NBTConfig.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package me.trouper.sentinel.data.config;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.config.JsonSerializable;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class NBTConfig implements JsonSerializable<NBTConfig> {
|
||||
@Override
|
||||
public File getFile() {
|
||||
File file = new File(Sentinel.dataFolder(), "/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;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package me.trouper.sentinel.data.config;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.config.JsonSerializable;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
|
||||
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(Sentinel.dataFolder(), "/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");
|
||||
}};
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package me.trouper.sentinel.data.config;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.config.JsonSerializable;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class SwearsConfig implements JsonSerializable<SwearsConfig> {
|
||||
@Override
|
||||
public File getFile() {
|
||||
File file = new File(Sentinel.dataFolder(), "/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"
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
package me.trouper.sentinel.data.config;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.config.JsonSerializable;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.startup.Load;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ViolationConfig implements JsonSerializable<SwearsConfig> {
|
||||
@Override
|
||||
public File getFile() {
|
||||
File file = new File(Sentinel.dataFolder(), "/violation-config.json");
|
||||
file.getParentFile().mkdirs();
|
||||
return file;
|
||||
}
|
||||
|
||||
public CommandBlockEdit commandBlockEdit = new CommandBlockEdit();
|
||||
public CommandBlockExecute commandBlockExecute = new CommandBlockExecute();
|
||||
public CommandBlockMinecartPlace commandBlockMinecartPlace = new CommandBlockMinecartPlace();
|
||||
public CommandBlockMinecartUse commandBlockMinecartUse = new CommandBlockMinecartUse();
|
||||
public CommandBlockPlace commandBlockPlace = new CommandBlockPlace();
|
||||
public CommandBlockUse commandBlockUse = new CommandBlockUse();
|
||||
public CommandExecute commandExecute = new CommandExecute();
|
||||
public CreativeHotbarAction creativeHotbarAction = new CreativeHotbarAction();
|
||||
|
||||
|
||||
public class CommandBlockEdit {
|
||||
public boolean enabled = true;
|
||||
public boolean deop = true;
|
||||
public boolean logToDiscord = true;
|
||||
public boolean punish = false;
|
||||
public List<String> punishmentCommands = List.of(
|
||||
"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 class CommandBlockMinecartPlace {
|
||||
public boolean enabled = true;
|
||||
public boolean deop = true;
|
||||
public boolean logToDiscord = true;
|
||||
public boolean punish = false;
|
||||
public List<String> punishmentCommands = List.of(
|
||||
"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 class CommandBlockMinecartUse {
|
||||
public boolean enabled = true;
|
||||
public boolean deop = true;
|
||||
public boolean logToDiscord = true;
|
||||
public boolean punish = false;
|
||||
public List<String> punishmentCommands = List.of(
|
||||
"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 class CommandBlockPlace {
|
||||
public boolean enabled = true;
|
||||
public boolean deop = true;
|
||||
public boolean logToDiscord = true;
|
||||
public boolean punish = false;
|
||||
public List<String> punishmentCommands = List.of(
|
||||
"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 class CommandBlockUse {
|
||||
public boolean enabled = true;
|
||||
public boolean deop = true;
|
||||
public boolean logToDiscord = true;
|
||||
public boolean punish = false;
|
||||
public List<String> punishmentCommands = List.of(
|
||||
"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 class CreativeHotbarAction {
|
||||
public boolean enabled = true;
|
||||
public boolean deop = true;
|
||||
public boolean logToDiscord = true;
|
||||
public boolean punish = false;
|
||||
public List<String> punishmentCommands = List.of(
|
||||
"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 class CommandExecute {
|
||||
public Dangerous dangerous = new Dangerous();
|
||||
public Logged logged = new Logged();
|
||||
public Specific specific = new Specific();
|
||||
public class Dangerous {
|
||||
public boolean enabled = true;
|
||||
public List<String> commands = 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 deop = true;
|
||||
public boolean logToDiscord = true;
|
||||
public boolean punish = false;
|
||||
public List<String> punishmentCommands = List.of(
|
||||
"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 class Logged {
|
||||
public boolean enabled = true;
|
||||
public List<String> commands = List.of(
|
||||
"give",
|
||||
"item"
|
||||
);
|
||||
public boolean logToDiscord = true;
|
||||
}
|
||||
public class Specific {
|
||||
public boolean enabled = true;
|
||||
public boolean logToDiscord = false;
|
||||
public boolean punish = false;
|
||||
public List<String> punishmentCommands = List.of(
|
||||
"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 class CommandBlockExecute {
|
||||
public boolean enabled = true;
|
||||
public boolean destroyBlock = false;
|
||||
public boolean attemptRestore = true;
|
||||
public boolean logToDiscord = false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
package me.trouper.sentinel.data.config.lang;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.misc.config.JsonSerializable;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class LanguageFile implements JsonSerializable<LanguageFile> {
|
||||
public static final File PATH = new File(Sentinel.dataFolder(), "/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 actionAutomaticReportable = "§7This action was preformed automatically \n§7by the §bSentinel Chat Filter§7 algorithm!\n§8§o(Click to report false positive)";
|
||||
}
|
||||
|
||||
public Violations violations = new Violations();
|
||||
public class Violations {
|
||||
public Chat chat = new Chat();
|
||||
public class Chat {
|
||||
public Profanity profanity = new Profanity();
|
||||
public class Profanity {
|
||||
public String prevent = "has been prevented from swearing.";
|
||||
public String autoPunish = "has been auto-punished for swearing.";
|
||||
public String preventWarning = "Do not use profanity in chat. Any attempt to bypass this filter will be detected, and you will be punished.";
|
||||
public String autoPunishWarning = "&cYou have been auto-punished for attempting to bypass the profanity filter!";
|
||||
|
||||
public String treeTitle = "The Profanity Filter has been triggered.";
|
||||
public String playerInfoTitle = "Player: %s";
|
||||
public String uuid = "UUID";
|
||||
public String score = "Score";
|
||||
|
||||
public String reportInfoTitle = "Anti-Swear Detection";
|
||||
public String originalMessage = "Original Message";
|
||||
public String processedMessage = "Processed Message";
|
||||
public String severity = "Severity";
|
||||
|
||||
public String actionTitle = "Actions";
|
||||
public String blockAction = "Blocked the message";
|
||||
public String commandAction = "Executed Punishment Commands";
|
||||
}
|
||||
|
||||
public Regex regex = new Regex();
|
||||
public class Regex {
|
||||
public String autoPunish = "has been auto-punished for slurs. (Regex)";
|
||||
public String regexTrigger = "has triggered a regex blocker.";
|
||||
|
||||
public String urlBlockName = "URL Regex Blocker";
|
||||
public String urlBlockMessage = "Your message has been withheld. Do not link to websites.";
|
||||
|
||||
public String unicodeBlockName = "Unicode Regex Blocker";
|
||||
public String unicodeBlockMessage = "Your message has been withheld. Please only use characters found on your keyboard.";
|
||||
|
||||
public String swearBlockName = "Swear Regex Blocker";
|
||||
public String swearBlockMessage = "Your message has been withheld for containing blocked words.";
|
||||
|
||||
public String strictBlockName = "Strict Regex Blocker";
|
||||
public String strictBlockMessage = "Your message has been withheld for containing slurs.";
|
||||
|
||||
public String treeTitle = "A Regex Filter has been triggered.";
|
||||
public String playerInfoTitle = "Player: %s";
|
||||
public String uuid = "UUID";
|
||||
public String score = "Score";
|
||||
|
||||
public String reportInfoTitle = "%s Detection";
|
||||
public String originalMessage = "Original Message";
|
||||
public String flaggedMessage = "Flagged Message";
|
||||
|
||||
public String actionTitle = "Actions";
|
||||
public String blockAction = "Blocked the message";
|
||||
public String commandAction = "Executed Punishment Commands";
|
||||
}
|
||||
|
||||
public Spam spam = new Spam();
|
||||
public class Spam {
|
||||
public String autoPunish = "has been auto-punished for spamming.";
|
||||
public String spamWarning = "might be spamming!";
|
||||
public String preventWarning = "Do not spam in chat! Please wait before sending another message.";
|
||||
public String autoPunishWarning = "&cYou have been auto-punished for violating the anti-spam repetitively!";
|
||||
|
||||
public String treeTitle = "The Anti-Spam has been triggered.";
|
||||
public String playerInfoTitle = "Player: %s";
|
||||
public String uuid = "UUID";
|
||||
public String heat = "Heat";
|
||||
|
||||
public String reportInfoTitle = "Anti-Spam Detection";
|
||||
public String previousMessage = "Previous Message";
|
||||
public String currentMessage = "Current Message";
|
||||
public String similarity = "Similarity";
|
||||
|
||||
public String actionTitle = "Actions";
|
||||
public String blockAction = "Blocked the message";
|
||||
public String commandAction = "Executed Punishment Commands";
|
||||
}
|
||||
}
|
||||
public CommandBlockEdit commandBlockEdit = new CommandBlockEdit();
|
||||
public class CommandBlockEdit {
|
||||
public String playerAttemptEdit = "A player has attempted to edit a command block!";
|
||||
public String playerInfoTitle = "Player: %s";
|
||||
public String uuid = "UUID";
|
||||
public String location = "Location";
|
||||
public String violationInfoTitle = "Command Block Edit Info";
|
||||
public String blockLocation = "Block Location";
|
||||
public String insertedCommand = "Inserted Command";
|
||||
}
|
||||
|
||||
public CommandBlockExecute commandBlockExecute = new CommandBlockExecute();
|
||||
public class CommandBlockExecute {
|
||||
public String commandBlockWhitelistTripped = "Command block whitelist has been tripped.";
|
||||
public String actionsTitle = "Actions";
|
||||
public String commandBlockInfoTitle = "Command Block Info";
|
||||
public String blockLocation = "Block Location";
|
||||
public String executedCommand = "Executed Command";
|
||||
public String destroyedBlock = "Destroyed block";
|
||||
public String preventExecution = "Prevented Execution";
|
||||
public String restore = "Restore";
|
||||
public String restoreSuccess = "Success";
|
||||
public String restoreFailure = "Failure";
|
||||
public String loggedToDiscord = "Logged to Discord";
|
||||
}
|
||||
|
||||
public CommandBlockMinecartPlace commandBlockMinecartPlace = new CommandBlockMinecartPlace();
|
||||
public class CommandBlockMinecartPlace {
|
||||
public String detectionChat = "&b&n%s&r &7has attempted to place a command block minecart.";
|
||||
public String detectionTree = "A player has attempted to place a command block minecart!";
|
||||
public String playerInfoTitle = "Player: %s";
|
||||
public String uuid = "UUID";
|
||||
public String location = "Location";
|
||||
public String blockLocation = "Block Location";
|
||||
public String minecartPlaceInfoTitle = "Minecart Place Info";
|
||||
public String locationFormat = "X: %s Y: %s Z: %s";
|
||||
public String blockLocationFormat = "World: %s X: %s Y: %s Z: %s";
|
||||
}
|
||||
|
||||
public CommandBlockMinecartUse commandBlockMinecartUse = new CommandBlockMinecartUse();
|
||||
public class CommandBlockMinecartUse {
|
||||
public String detectionChat = "&b&n%s&r &7has attempted to use a command block minecart.";
|
||||
public String detectionTree = "A player has attempted to use a command block minecart!";
|
||||
public String playerInfoTitle = "Player: %s";
|
||||
public String uuid = "UUID";
|
||||
public String location = "Location";
|
||||
public String cartLocation = "Cart Location";
|
||||
public String minecartUseInfoTitle = "Minecart Use Info";
|
||||
public String locationFormat = "X: %s Y: %s Z: %s";
|
||||
public String cartLocationFormat = "World: %s X: %s Y: %s Z: %s";
|
||||
}
|
||||
|
||||
public CommandBlockPlace commandBlockPlace = new CommandBlockPlace();
|
||||
public class CommandBlockPlace {
|
||||
public String detectionChat = "&b&n%s&r &7has attempted to place a command block.";
|
||||
public String detectionTree = "A player has attempted to place a command block!";
|
||||
public String playerInfoTitle = "Player: %s";
|
||||
public String uuid = "UUID";
|
||||
public String location = "Location";
|
||||
public String blockLocation = "Block Location";
|
||||
public String commandBlockEditInfoTitle = "Command Block Edit Info";
|
||||
public String locationFormat = "X: %s Y: %s Z: %s";
|
||||
public String blockLocationFormat = "World: %s X: %s Y: %s Z: %s";
|
||||
public String insertedCommand = "Inserted Command";
|
||||
public String insertedCommandUploadedTo = "Inserted Command Uploaded to";
|
||||
}
|
||||
|
||||
public CommandBlockUse commandBlockUse = new CommandBlockUse();
|
||||
public class CommandBlockUse {
|
||||
public String detectionChat = "&b&n%s&r &7has attempted to use a command block.";
|
||||
public String detectionTree = "A player has attempted to use a command block!";
|
||||
public String playerInfoTitle = "Player: %s";
|
||||
public String uuid = "UUID";
|
||||
public String location = "Location";
|
||||
public String blockLocation = "Block Location";
|
||||
public String commandBlockUseInfoTitle = "Command Block Use Info";
|
||||
public String locationFormat = "X: %s Y: %s Z: %s";
|
||||
public String blockLocationFormat = "World: %s X: %s Y: %s Z: %s";
|
||||
public String commandInside = "Command Inside";
|
||||
public String commandUploadedTo = "Command Uploaded to";
|
||||
}
|
||||
|
||||
public CommandExecute commandExecute = new CommandExecute();
|
||||
public class CommandExecute {
|
||||
public String specificCommandDetection = "A player has attempted to run a specific command.";
|
||||
public String dangerousCommandDetection = "A player has attempted to run a dangerous command.";
|
||||
public String loggedCommandDetection = "A player has ran a logged command.";
|
||||
public String playerInfoTitle = "Player: %s";
|
||||
public String uuid = "UUID";
|
||||
public String location = "Location";
|
||||
public String commandField = "Command";
|
||||
public String commandUploadedTo = "Command Uploaded to";
|
||||
public String violationInfoTitle = "Violation Info";
|
||||
public String locationFormat = "X: %s Y: %s Z: %s";
|
||||
public String specificCommandViolation = "&b&n%s&r &7has attempted to run a specific command.";
|
||||
public String dangerousCommandViolation = "&b&n%s&r &7has attempted to run a dangerous command.";
|
||||
public String loggedCommandViolation = "&b&n%s&r &7has ran a logged command.";
|
||||
}
|
||||
|
||||
public CreativeHotbar creativeHotbar = new CreativeHotbar();
|
||||
public class CreativeHotbar {
|
||||
public String nbtAttemptDetection = "A player has attempted to grab an NBT item!";
|
||||
public String playerInfoTitle = "Player: %s";
|
||||
public String uuid = "UUID";
|
||||
public String location = "Location";
|
||||
public String locationFormat = "X: %s Y: %s Z: %s";
|
||||
public String itemType = "Type";
|
||||
public String nbtUpload = "NBT Upload";
|
||||
public String itemInfoTitle = "Item Info";
|
||||
public String nbtAttemptViolation = "&b&n%s&r &7has attempted to grab an NBT item.";
|
||||
}
|
||||
|
||||
public ViolationMessages violationMessages = new ViolationMessages();
|
||||
public class ViolationMessages {
|
||||
public String actions = "Actions";
|
||||
public String eventCancelled = "Canceled Event";
|
||||
public String punishmentCommandsExecuted = "Executed Punishment Commands";
|
||||
public String userOpStripped = "Stripped user's OP";
|
||||
public String loggedToDiscord = "Logged to Discord";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package me.trouper.sentinel.data.types;
|
||||
|
||||
public enum CMDBlockType {
|
||||
CHAIN,
|
||||
REPEAT,
|
||||
IMPULSE,
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package me.trouper.sentinel.data.types;
|
||||
|
||||
public record Location(String world, double x, double y,double z) {
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package me.trouper.sentinel.data.types;
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package me.trouper.sentinel.server.commands;
|
||||
|
||||
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 me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.FalsePositiveReporting;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.Report;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.command.Command;
|
||||
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 CallbackCommand implements CustomCommand {
|
||||
|
||||
Cooldown<UUID> fpReportCooldown = new Cooldown<>();
|
||||
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender sender, Command command, String s, 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 report = FalsePositiveReporting.reports.get(id);
|
||||
if (report == null) {
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.reports.noReport));
|
||||
return;
|
||||
}
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.reports.reportingFalsePositive));
|
||||
FalsePositiveReporting.sendReport(p,report);
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.reports.falsePositiveSuccess));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCompletions(CommandSender sender, Command command, String s, CompletionBuilder b) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package me.trouper.sentinel.server.commands;
|
||||
|
||||
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 me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.Message;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@CommandRegistry(value = "sentinelmessage",permission = @Permission("sentinel.message"))
|
||||
public class MessageCommand implements CustomCommand {
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender sender, Command command, String s, 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(CommandSender commandSender, Command command, String s, CompletionBuilder b) {
|
||||
List<String> players = new ArrayList<>();
|
||||
Bukkit.getOnlinePlayers().forEach(
|
||||
player -> {
|
||||
players.add(player.getName());
|
||||
}
|
||||
);
|
||||
b.then(b.arg(players)
|
||||
.then(b.arg("[<Message>]")));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package me.trouper.sentinel.server.commands;
|
||||
|
||||
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 me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.utils.PlayerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@CommandRegistry(value = "reop")
|
||||
public class ReopCommand implements CustomCommand {
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender sender, Command command, String s, Args args) {
|
||||
Player p = (Player) sender;
|
||||
if (PlayerUtils.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(CommandSender commandSender, Command command, String s, CompletionBuilder completionBuilder) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package me.trouper.sentinel.server.commands;
|
||||
|
||||
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 me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.Message;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.command.Command;
|
||||
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, Command command, String s, 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(CommandSender commandSender, Command command, String s, CompletionBuilder b) {
|
||||
b.then(b.arg("[<Message>]"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
package me.trouper.sentinel.server.commands;
|
||||
|
||||
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 me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.regex.AntiRegex;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.profanity.AntiProfanity;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.spam.AntiSpam;
|
||||
import me.trouper.sentinel.data.config.MainConfig;
|
||||
import me.trouper.sentinel.server.functions.CBWhitelistManager;
|
||||
import me.trouper.sentinel.data.types.WhitelistedBlock;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.startup.Auth;
|
||||
import me.trouper.sentinel.startup.Load;
|
||||
import me.trouper.sentinel.utils.PlayerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import me.trouper.sentinel.utils.trees.ConsoleFormatter;
|
||||
import me.trouper.sentinel.utils.trees.EmbedFormatter;
|
||||
import me.trouper.sentinel.utils.trees.Node;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.CommandBlock;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@CommandRegistry(value = "sentinel",permission = @Permission("sentinel.staff"),printStackTrace = true)
|
||||
public class SentinelCommand implements CustomCommand {
|
||||
|
||||
public static String liteMode = Text.color("""
|
||||
&8]=-&f Welcome to &d&lSentinel &7|&f Anti-Nuke &8-=[
|
||||
&7The plugin is currently loaded in &clite&7 mode.
|
||||
|
||||
&7Your License Key is &a%s&7.
|
||||
&7Your server ID is &6%s&7.
|
||||
&7You are &6%s&7.
|
||||
|
||||
&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!
|
||||
""".formatted(Auth.getLicenseKey(),Auth.getServerID(), MainConfig.username));
|
||||
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender sender, Command command, String s, Args args) {
|
||||
if (Load.lite) {
|
||||
if (!args.isEmpty() && args.get(0).toString().equals("reload")) {
|
||||
if (!(sender instanceof ConsoleCommandSender) && !PlayerUtils.isTrusted((Player) sender)) {
|
||||
sender.sendMessage(Text.prefix(Sentinel.lang.permissions.noTrust));
|
||||
return;
|
||||
}
|
||||
Sentinel.log.info("Sentinel is now Reloading the config.");
|
||||
sender.sendMessage(Text.prefix("Reloading the config."));
|
||||
Sentinel.loadConfig();
|
||||
String serverID = Auth.getServerID();
|
||||
String license = Sentinel.mainConfig.plugin.license;
|
||||
String nonce = Auth.getNonce();
|
||||
Auth.getPort();
|
||||
|
||||
Sentinel.log.info("\n]====---- Requesting Authentication ----====[ \n- License Key: %s\n- Server ID: %s\n- Nonce: %s\n".formatted(license, serverID, nonce));
|
||||
if (Auth.canLoad()) {
|
||||
Load.startup(false);
|
||||
return;
|
||||
}
|
||||
Sentinel.log.info("Re-authentication Failed.");
|
||||
} else {
|
||||
sender.sendMessage(liteMode);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (args.getSize() > 0 == args.get(0).toString().equals("reload")) {
|
||||
if (sender instanceof Player p) {
|
||||
if (!PlayerUtils.isTrusted(p)) {
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.permissions.noTrust));
|
||||
return;
|
||||
}
|
||||
}
|
||||
Sentinel.log.info("Sentinel is now Reloading the config.");
|
||||
sender.sendMessage(Text.prefix("Reloading the config."));
|
||||
Sentinel.loadConfig();
|
||||
}
|
||||
Player p = (Player) sender;
|
||||
if (!p.hasPermission("sentinel.staff")) return;
|
||||
switch (args.get(0).toString()) {
|
||||
case "config" -> {
|
||||
if (!PlayerUtils.isTrusted(p)) return;
|
||||
if (!MainGUI.verify(p)) return;
|
||||
p.openInventory(new MainGUI().home.getInventory());
|
||||
}
|
||||
case "commandblock", "cb" -> handleCommandBlock(p,args);
|
||||
case "debug" -> handleDebugCommand(p,args);
|
||||
case "false-positive" -> handleFalsePositive(p,args);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCompletions(CommandSender commandSender, Command command, String s, CompletionBuilder b) {
|
||||
b.then(b.arg("config"));
|
||||
b.then(b.arg("reload"));
|
||||
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","cb").then(b.arg("add","remove","auto"))
|
||||
.then(b.arg("restore")
|
||||
.then(b.arg("<player>","all")))
|
||||
.then(b.arg("clear")
|
||||
.then(b.arg("<player>","all"))));
|
||||
}
|
||||
|
||||
private void handleFalsePositive(Player p, Args args) {
|
||||
if (!p.hasPermission("sentinel.chat.antiswear.edit")) {
|
||||
p.sendMessage(Sentinel.lang.permissions.noPermission);
|
||||
return;
|
||||
}
|
||||
String falsePositive = args.getAll(2).toString();
|
||||
Node root = new Node("Sentinel");
|
||||
root.addTextLine("False Positive Management Log");
|
||||
Node info = new Node("Info");
|
||||
info.addKeyValue("User",p.getName());
|
||||
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)));
|
||||
info.addKeyValue("Action","Add");
|
||||
}
|
||||
case "remove" -> {
|
||||
Sentinel.fpConfig.swearWhitelist.remove(falsePositive);
|
||||
p.sendMessage(Text.prefix("&7Successfully removed &c%s&7 from the false positive list!".formatted(falsePositive)));
|
||||
info.addKeyValue("Action","Remove");
|
||||
}
|
||||
}
|
||||
info.addKeyValue("False Positive Edited", falsePositive);
|
||||
root.addChild(info);
|
||||
Sentinel.fpConfig.save();
|
||||
Sentinel.log.info(ConsoleFormatter.format(root));
|
||||
EmbedFormatter.sendEmbed(EmbedFormatter.format(root));
|
||||
}
|
||||
|
||||
private void handleCommandBlock(Player p, Args args) {
|
||||
if (!PlayerUtils.isTrusted(p)) {
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.permissions.noTrust));
|
||||
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();
|
||||
CBWhitelistManager.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 = CBWhitelistManager.get(target.getLocation());
|
||||
if (wb != null) {
|
||||
CBWhitelistManager.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 (CBWhitelistManager.autoWhitelist.contains(p.getUniqueId())) {
|
||||
CBWhitelistManager.autoWhitelist.remove(p.getUniqueId());
|
||||
p.sendMessage(Text.prefix("Successfully toggled &bauto whitelist&7 off for you."));
|
||||
} else {
|
||||
CBWhitelistManager.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 = CBWhitelistManager.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 = CBWhitelistManager.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 = CBWhitelistManager.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 = CBWhitelistManager.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 (!PlayerUtils.isTrusted(p)) {
|
||||
p.sendMessage(Text.prefix(Sentinel.lang.permissions.noTrust));
|
||||
return;
|
||||
}
|
||||
switch (args.get(1).toString()) {
|
||||
case "lang" -> {
|
||||
p.sendMessage(Sentinel.lang.brokenLang);
|
||||
}
|
||||
case "toggle" -> {
|
||||
Sentinel.mainConfig.debugMode = !Sentinel.mainConfig.debugMode ;
|
||||
p.sendMessage(Text.prefix((Sentinel.mainConfig.debugMode ? "Enabled" : "Disabled") + " debug mode."));
|
||||
Sentinel.mainConfig.save();
|
||||
}
|
||||
case "chat" -> {
|
||||
AsyncPlayerChatEvent message = new AsyncPlayerChatEvent(true,p,args.getAll(2).toString(), Set.of(p));
|
||||
AntiRegex.handleRegex(message);
|
||||
AntiSpam.handleAntiSpam(message);
|
||||
AntiProfanity.handleProfanityFilter(message);
|
||||
if (!message.isCancelled()) p.sendMessage(Text.prefix("Message did not get flagged."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package me.trouper.sentinel.server.commands;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.commands.CustomCommand;
|
||||
import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SocialSpyCommand implements CustomCommand {
|
||||
public static Map<UUID, Boolean> spyMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender sender, Command command, String s, 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(CommandSender commandSender, Command command, String s, CompletionBuilder completionBuilder) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package me.trouper.sentinel.server.commands;
|
||||
|
||||
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 me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@CommandRegistry(value = "sentineltab")
|
||||
public class TrapCommand implements CustomCommand {
|
||||
|
||||
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender commandSender, Command command, String s, Args args) {
|
||||
commandSender.sendMessage(Component.text(Text.prefix("https://www.youtube.com/watch?v=4F4qzPbcFiA")).clickEvent(ClickEvent.openUrl("https://www.youtube.com/watch?v=4F4qzPbcFiA")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCompletions(CommandSender commandSender, Command command, String s, CompletionBuilder b) {
|
||||
ServerUtils.verbose("Listing the fake plugins: %s".formatted(Sentinel.advConfig.fakePlugins));
|
||||
b.then(b.arg(Sentinel.advConfig.fakePlugins));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package me.trouper.sentinel.server.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.CBWhitelistManager;
|
||||
import me.trouper.sentinel.utils.trees.Node;
|
||||
import me.trouper.sentinel.utils.PlayerUtils;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.server.functions.ViolationController;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.CommandBlock;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||
|
||||
public class CBEditEvent implements CustomListener {
|
||||
|
||||
@EventHandler
|
||||
private void onCMDBlockChange(EntityChangeBlockEvent e) {
|
||||
ServerUtils.verbose("CommandBlockChange: Detected the event");
|
||||
if (!Sentinel.violationConfig.commandBlockEdit.enabled) return;
|
||||
ServerUtils.verbose("CommandBlockChange: Enabled");
|
||||
if (!(e.getEntity() instanceof Player p)) return;
|
||||
ServerUtils.verbose("CommandBlockChange: Changer is a player");
|
||||
Block b = e.getBlock();
|
||||
if (!(b.getType() == Material.COMMAND_BLOCK || b.getType() == Material.REPEATING_COMMAND_BLOCK || b.getType() == Material.CHAIN_COMMAND_BLOCK))
|
||||
return;
|
||||
ServerUtils.verbose("CommandBlockChange: Block is a command block");
|
||||
BlockState state = b.getState();
|
||||
CommandBlock cb = (CommandBlock) state;
|
||||
if (PlayerUtils.isTrusted(p)) {
|
||||
if (!CBWhitelistManager.autoWhitelist.contains(p.getUniqueId())) return;
|
||||
CBWhitelistManager.add(cb, p.getUniqueId());
|
||||
return;
|
||||
}
|
||||
ServerUtils.verbose("CommandBlockChange: Not trusted, performing action");
|
||||
e.setCancelled(true);
|
||||
|
||||
Node root = getLog(p, cb);
|
||||
|
||||
ViolationController.handleViolation(
|
||||
"&b&n%s&r &7%s".formatted(p.getName(), Sentinel.lang.violations.commandBlockEdit.playerAttemptEdit),
|
||||
Sentinel.violationConfig.commandBlockEdit.punish,
|
||||
Sentinel.violationConfig.commandBlockEdit.deop,
|
||||
Sentinel.violationConfig.commandBlockEdit.logToDiscord,
|
||||
p,
|
||||
Sentinel.violationConfig.commandBlockEdit.punishmentCommands,
|
||||
root
|
||||
);
|
||||
}
|
||||
|
||||
private static Node getLog(Player p, CommandBlock cb) {
|
||||
Node root = new Node("Sentinel");
|
||||
root.addTextLine(Sentinel.lang.violations.commandBlockEdit.playerAttemptEdit);
|
||||
|
||||
Node playerInfo = new Node(Sentinel.lang.violations.commandBlockEdit.playerInfoTitle.formatted(p.getName()));
|
||||
playerInfo.addKeyValue(Sentinel.lang.violations.commandBlockEdit.uuid, p.getUniqueId().toString());
|
||||
playerInfo.addField(Sentinel.lang.violations.commandBlockEdit.location, "X: %s Y: %s Z: %s".formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
|
||||
root.addChild(playerInfo);
|
||||
|
||||
Node violationInfo = new Node(Sentinel.lang.violations.commandBlockEdit.violationInfoTitle);
|
||||
violationInfo.addField(Sentinel.lang.violations.commandBlockEdit.blockLocation,"World: %s X: %s Y: %s Z: %s".formatted(cb.getWorld().getName(), cb.getX(), cb.getY(), cb.getZ()));
|
||||
violationInfo.addField(Sentinel.lang.violations.commandBlockEdit.insertedCommand, cb.getCommand());
|
||||
root.addChild(violationInfo);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package me.trouper.sentinel.server.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.CBWhitelistManager;
|
||||
import me.trouper.sentinel.utils.trees.ConsoleFormatter;
|
||||
import me.trouper.sentinel.utils.trees.EmbedFormatter;
|
||||
import me.trouper.sentinel.utils.trees.HoverFormatter;
|
||||
import me.trouper.sentinel.utils.trees.Node;
|
||||
import me.trouper.sentinel.utils.FileUtils;
|
||||
import me.trouper.sentinel.utils.PlayerUtils;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.CommandBlock;
|
||||
import org.bukkit.command.BlockCommandSender;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.server.ServerCommandEvent;
|
||||
|
||||
public class CBExecuteEvent implements CustomListener {
|
||||
@EventHandler
|
||||
private void commandBlockExecute(ServerCommandEvent e) {
|
||||
|
||||
//ServerUtils.verbose("Handling command block event: " + e.getCommand());
|
||||
if (!Sentinel.violationConfig.commandBlockExecute.enabled) return;
|
||||
//ServerUtils.verbose("Whitelist not disabled ");
|
||||
if (!(e.getSender() instanceof BlockCommandSender s)) return;
|
||||
//ServerUtils.verbose("Sender is command block");
|
||||
Block cmdBlock = s.getBlock();
|
||||
if (CBWhitelistManager.canRun(cmdBlock)) return;
|
||||
ServerUtils.verbose("Command block can't run.");
|
||||
|
||||
CommandBlock cb = (CommandBlock) cmdBlock.getState();
|
||||
|
||||
Node log = getLog(cb);
|
||||
Node actions = new Node(Sentinel.lang.violations.commandBlockExecute.actionsTitle);
|
||||
|
||||
e.setCancelled(true);
|
||||
actions.addTextLine(Sentinel.lang.violations.commandBlockExecute.preventExecution);
|
||||
|
||||
if (Sentinel.violationConfig.commandBlockExecute.destroyBlock) {
|
||||
cmdBlock.setType(Material.AIR);
|
||||
actions.addTextLine(Sentinel.lang.violations.commandBlockExecute.destroyedBlock);
|
||||
}
|
||||
|
||||
if (Sentinel.violationConfig.commandBlockExecute.attemptRestore) {
|
||||
boolean restored = CBWhitelistManager.restore(cmdBlock.getLocation());
|
||||
actions.addKeyValue(Sentinel.lang.violations.commandBlockExecute.restore, restored ? Sentinel.lang.violations.commandBlockExecute.restoreSuccess : Sentinel.lang.violations.commandBlockExecute.restoreFailure);
|
||||
}
|
||||
|
||||
if (Sentinel.violationConfig.commandBlockExecute.logToDiscord) actions.addTextLine(Sentinel.lang.violations.commandBlockExecute.loggedToDiscord);
|
||||
log.addChild(actions);
|
||||
|
||||
if (Sentinel.violationConfig.commandBlockExecute.logToDiscord) {
|
||||
EmbedFormatter.sendEmbed(EmbedFormatter.format(log));
|
||||
}
|
||||
|
||||
ServerUtils.forEachPlayer(trusted -> {
|
||||
if (PlayerUtils.isTrusted(trusted)) {
|
||||
trusted.sendMessage(Component.text(Text.prefix("The command block whitelist has been tripped!")).hoverEvent(Component.text(HoverFormatter.format(log)).asHoverEvent()));
|
||||
}
|
||||
});
|
||||
|
||||
Sentinel.log.info(ConsoleFormatter.format(log));
|
||||
}
|
||||
|
||||
private static Node getLog(CommandBlock cb) {
|
||||
Node root = new Node("Sentinel");
|
||||
root.addTextLine(Sentinel.lang.violations.commandBlockExecute.commandBlockWhitelistTripped);
|
||||
|
||||
Node violationInfo = new Node(Sentinel.lang.violations.commandBlockExecute.commandBlockInfoTitle);
|
||||
violationInfo.addField(Sentinel.lang.violations.commandBlockExecute.blockLocation,"World: %s X: %s Y: %s Z: %s".formatted(cb.getWorld().getName(), cb.getX(), cb.getY(), cb.getZ()));
|
||||
String command = cb.getCommand();
|
||||
if (command.length() <= 128) {
|
||||
violationInfo.addField(Sentinel.lang.violations.commandBlockExecute.executedCommand, command);
|
||||
} else {
|
||||
violationInfo.addKeyValue(Sentinel.lang.violations.commandBlockExecute.executedCommand, FileUtils.createCommandLog(command));
|
||||
}
|
||||
root.addChild(violationInfo);
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package me.trouper.sentinel.server.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.utils.trees.Node;
|
||||
import me.trouper.sentinel.utils.PlayerUtils;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.server.functions.ViolationController;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
public class CBMCPlaceEvent implements CustomListener {
|
||||
|
||||
@EventHandler
|
||||
private void onCMDMinecartPlace(PlayerInteractEvent e) {
|
||||
//ServerUtils.verbose("MinecartCommandPlace: Detected interaction");
|
||||
if (!Sentinel.violationConfig.commandBlockMinecartPlace.enabled) return;
|
||||
ServerUtils.verbose("MinecartCommandPlace: Check is enabled");
|
||||
if (!e.getPlayer().isOp()) return;
|
||||
ServerUtils.verbose("MinecartCommandPlace: Player is op");
|
||||
if (e.getItem() == null) return;
|
||||
ServerUtils.verbose("MinecartCommandPlace: Item isn't null");
|
||||
if (e.getClickedBlock() == null) return;
|
||||
ServerUtils.verbose("MinecartCommandPlace: Clicked block isn't null");
|
||||
if (!e.getItem().getType().equals(Material.COMMAND_BLOCK_MINECART)) return;
|
||||
ServerUtils.verbose("MinecartCommandPlace: Item is a minecart command");
|
||||
if (!(e.getClickedBlock().getType() == Material.RAIL || e.getClickedBlock().getType() == Material.POWERED_RAIL || e.getClickedBlock().getType() == Material.ACTIVATOR_RAIL || e.getClickedBlock().getType() == Material.DETECTOR_RAIL)) return;
|
||||
ServerUtils.verbose("MinecartCommandPlace: Clicked block is a rail");
|
||||
Player p = e.getPlayer();
|
||||
if (PlayerUtils.isTrusted(p)) return;
|
||||
ServerUtils.verbose("MinecartCommandPlace: Not trusted, preforming action");
|
||||
|
||||
e.setCancelled(true);
|
||||
p.getInventory().remove(Material.COMMAND_BLOCK_MINECART);
|
||||
|
||||
Node log = getLog(p, e.getClickedBlock());
|
||||
|
||||
ViolationController.handleViolation(
|
||||
Sentinel.lang.violations.commandBlockMinecartPlace.detectionChat.formatted(p.getName()),
|
||||
Sentinel.violationConfig.commandBlockMinecartPlace.punish,
|
||||
Sentinel.violationConfig.commandBlockMinecartPlace.deop,
|
||||
Sentinel.violationConfig.commandBlockMinecartPlace.logToDiscord,
|
||||
p,
|
||||
Sentinel.violationConfig.commandBlockMinecartPlace.punishmentCommands,
|
||||
log
|
||||
);
|
||||
}
|
||||
|
||||
private static Node getLog(Player p, Block cb) {
|
||||
Node root = new Node("Sentinel");
|
||||
root.addTextLine(Sentinel.lang.violations.commandBlockMinecartPlace.detectionTree);
|
||||
|
||||
Node playerInfo = new Node(Sentinel.lang.violations.commandBlockMinecartPlace.playerInfoTitle.formatted(p.getName()));
|
||||
playerInfo.addKeyValue(Sentinel.lang.violations.commandBlockMinecartPlace.uuid, p.getUniqueId().toString());
|
||||
playerInfo.addField(Sentinel.lang.violations.commandBlockMinecartPlace.location, Sentinel.lang.violations.commandBlockMinecartPlace.locationFormat.formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
|
||||
root.addChild(playerInfo);
|
||||
|
||||
Node violationInfo = new Node(Sentinel.lang.violations.commandBlockMinecartPlace.minecartPlaceInfoTitle);
|
||||
violationInfo.addField(Sentinel.lang.violations.commandBlockMinecartPlace.blockLocation, Sentinel.lang.violations.commandBlockMinecartPlace.blockLocationFormat.formatted(cb.getWorld().getName(), cb.getX(), cb.getY(), cb.getZ()));
|
||||
root.addChild(violationInfo);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package me.trouper.sentinel.server.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.utils.trees.Node;
|
||||
import me.trouper.sentinel.utils.PlayerUtils;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.server.functions.ViolationController;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
|
||||
public class CBMCUseEvent implements CustomListener {
|
||||
|
||||
@EventHandler
|
||||
private void onCMDBlockMinecartUse(PlayerInteractEntityEvent e) {
|
||||
//ServerUtils.verbose("MinecartCommandUse: Detected Interaction with entity");
|
||||
if (!Sentinel.violationConfig.commandBlockMinecartUse.enabled) return;
|
||||
ServerUtils.verbose("MinecartCommandUse: Enabled");
|
||||
if (!e.getPlayer().isOp()) return;
|
||||
ServerUtils.verbose("MinecartCommandUse: Player op");
|
||||
if (e.getRightClicked().getType() != EntityType.COMMAND_BLOCK_MINECART) return;
|
||||
ServerUtils.verbose("MinecartCommandUse: Entity is minecart command");
|
||||
Player p = e.getPlayer();
|
||||
if (PlayerUtils.isTrusted(p)) return;
|
||||
ServerUtils.verbose("MinecartCommandUse: Not trusted, performing action");
|
||||
e.setCancelled(true);
|
||||
|
||||
Node log = getLog(p, e.getRightClicked());
|
||||
|
||||
ViolationController.handleViolation(
|
||||
Sentinel.lang.violations.commandBlockMinecartUse.detectionChat.formatted(p.getName()),
|
||||
Sentinel.violationConfig.commandBlockMinecartUse.punish,
|
||||
Sentinel.violationConfig.commandBlockMinecartUse.deop,
|
||||
Sentinel.violationConfig.commandBlockMinecartUse.logToDiscord,
|
||||
p,
|
||||
Sentinel.violationConfig.commandBlockMinecartUse.punishmentCommands,
|
||||
log
|
||||
);
|
||||
}
|
||||
|
||||
private static Node getLog(Player p, Entity e) {
|
||||
Node root = new Node("Sentinel");
|
||||
root.addTextLine(Sentinel.lang.violations.commandBlockMinecartUse.detectionTree);
|
||||
|
||||
Node playerInfo = new Node(Sentinel.lang.violations.commandBlockMinecartUse.playerInfoTitle.formatted(p.getName()));
|
||||
playerInfo.addKeyValue(Sentinel.lang.violations.commandBlockMinecartUse.uuid, p.getUniqueId().toString());
|
||||
playerInfo.addField(Sentinel.lang.violations.commandBlockMinecartUse.location, Sentinel.lang.violations.commandBlockMinecartUse.locationFormat.formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
|
||||
root.addChild(playerInfo);
|
||||
|
||||
Node violationInfo = new Node(Sentinel.lang.violations.commandBlockMinecartUse.minecartUseInfoTitle);
|
||||
violationInfo.addField(Sentinel.lang.violations.commandBlockMinecartUse.cartLocation, Sentinel.lang.violations.commandBlockMinecartUse.cartLocationFormat.formatted(e.getWorld().getName(), e.getX(), e.getY(), e.getZ()));
|
||||
root.addChild(violationInfo);
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package me.trouper.sentinel.server.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.CBWhitelistManager;
|
||||
import me.trouper.sentinel.utils.trees.Node;
|
||||
import me.trouper.sentinel.utils.FileUtils;
|
||||
import me.trouper.sentinel.utils.PlayerUtils;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.server.functions.ViolationController;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.CommandBlock;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
|
||||
public class CBPlaceEvent implements CustomListener {
|
||||
|
||||
@EventHandler
|
||||
private void onCMDBlockPlace(BlockPlaceEvent e) {
|
||||
//ServerUtils.verbose("CommandBlockPlace: Detected block place");
|
||||
if (!Sentinel.violationConfig.commandBlockPlace.enabled) return;
|
||||
ServerUtils.verbose("CommandBlockPlace: Enabled");
|
||||
if (!e.getPlayer().isOp()) return;
|
||||
ServerUtils.verbose("CommandBlockPlace: Player is operator");
|
||||
Block b = e.getBlockPlaced();
|
||||
if (!(b.getType().equals(Material.COMMAND_BLOCK) ||
|
||||
b.getType().equals(Material.REPEATING_COMMAND_BLOCK) ||
|
||||
b.getType().equals(Material.CHAIN_COMMAND_BLOCK))) return;
|
||||
ServerUtils.verbose("CommandBlockPlace: Block is a command block");
|
||||
Player p = e.getPlayer();
|
||||
if (PlayerUtils.isTrusted(p)) {
|
||||
if (!CBWhitelistManager.autoWhitelist.contains(p.getUniqueId())) return;
|
||||
CBWhitelistManager.add((CommandBlock) b.getState(), p.getUniqueId());
|
||||
return;
|
||||
}
|
||||
ServerUtils.verbose("CommandBlockPlace: Not trusted, performing action");
|
||||
e.setCancelled(true);
|
||||
|
||||
Node log = getLog(p, (CommandBlock) b.getState());
|
||||
|
||||
ViolationController.handleViolation(
|
||||
Sentinel.lang.violations.commandBlockPlace.detectionChat.formatted(p.getName()),
|
||||
Sentinel.violationConfig.commandBlockPlace.punish,
|
||||
Sentinel.violationConfig.commandBlockPlace.deop,
|
||||
Sentinel.violationConfig.commandBlockPlace.logToDiscord,
|
||||
p,
|
||||
Sentinel.violationConfig.commandBlockPlace.punishmentCommands,
|
||||
log
|
||||
);
|
||||
}
|
||||
|
||||
private static Node getLog(Player p, CommandBlock cb) {
|
||||
Node root = new Node("Sentinel");
|
||||
root.addTextLine(Sentinel.lang.violations.commandBlockPlace.detectionTree);
|
||||
|
||||
Node playerInfo = new Node(Sentinel.lang.violations.commandBlockPlace.playerInfoTitle.formatted(p.getName()));
|
||||
playerInfo.addKeyValue(Sentinel.lang.violations.commandBlockPlace.uuid, p.getUniqueId().toString());
|
||||
playerInfo.addField(Sentinel.lang.violations.commandBlockPlace.location, Sentinel.lang.violations.commandBlockPlace.locationFormat.formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
|
||||
root.addChild(playerInfo);
|
||||
|
||||
Node violationInfo = new Node(Sentinel.lang.violations.commandBlockPlace.commandBlockEditInfoTitle);
|
||||
violationInfo.addField(Sentinel.lang.violations.commandBlockPlace.blockLocation, Sentinel.lang.violations.commandBlockPlace.blockLocationFormat.formatted(cb.getWorld().getName(), cb.getX(), cb.getY(), cb.getZ()));
|
||||
String command = cb.getCommand();
|
||||
if (command.length() <= 128) {
|
||||
violationInfo.addField(Sentinel.lang.violations.commandBlockPlace.insertedCommand, command);
|
||||
} else {
|
||||
violationInfo.addKeyValue(Sentinel.lang.violations.commandBlockPlace.insertedCommandUploadedTo, FileUtils.createCommandLog(command));
|
||||
}
|
||||
root.addChild(violationInfo);
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package me.trouper.sentinel.server.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.CBWhitelistManager;
|
||||
import me.trouper.sentinel.utils.trees.Node;
|
||||
import me.trouper.sentinel.utils.FileUtils;
|
||||
import me.trouper.sentinel.utils.PlayerUtils;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.server.functions.ViolationController;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.CommandBlock;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
public class CBUseEvent implements CustomListener {
|
||||
|
||||
@EventHandler
|
||||
private void onCMDBlockUse(PlayerInteractEvent e) {
|
||||
//ServerUtils.verbose("CommandBlockUse: Detected Interaction");
|
||||
if (!Sentinel.violationConfig.commandBlockUse.enabled) return;
|
||||
ServerUtils.verbose("CommandBlockUse: Enabled");
|
||||
if (!e.getPlayer().isOp()) return;
|
||||
ServerUtils.verbose("CommandBlockUse: Player is op");
|
||||
if (e.getClickedBlock() == null) return;
|
||||
ServerUtils.verbose("CommandBlockUse: Block isn't null");
|
||||
Block b = e.getClickedBlock();
|
||||
if (!(b.getType() == Material.COMMAND_BLOCK || b.getType() == Material.REPEATING_COMMAND_BLOCK || b.getType() == Material.CHAIN_COMMAND_BLOCK)) return;
|
||||
CommandBlock cb = (CommandBlock) b.getState();
|
||||
ServerUtils.verbose("CommandBlockUse: Block is a command block");
|
||||
Player p = e.getPlayer();
|
||||
if (PlayerUtils.isTrusted(p)) {
|
||||
if (!CBWhitelistManager.autoWhitelist.contains(p.getUniqueId())) return;
|
||||
if (CBWhitelistManager.canRun(cb.getBlock())) return;
|
||||
e.setCancelled(true);
|
||||
CBWhitelistManager.add(cb, p.getUniqueId());
|
||||
return;
|
||||
}
|
||||
ServerUtils.verbose("CommandBlockUse: Not trusted, performing action");
|
||||
e.setCancelled(true);
|
||||
|
||||
Node log = getLog(p, (CommandBlock) b.getState());
|
||||
|
||||
ViolationController.handleViolation(
|
||||
Sentinel.lang.violations.commandBlockUse.detectionChat.formatted(p.getName()),
|
||||
Sentinel.violationConfig.commandBlockUse.punish,
|
||||
Sentinel.violationConfig.commandBlockUse.deop,
|
||||
Sentinel.violationConfig.commandBlockUse.logToDiscord,
|
||||
p,
|
||||
Sentinel.violationConfig.commandBlockUse.punishmentCommands,
|
||||
log
|
||||
);
|
||||
}
|
||||
|
||||
private static Node getLog(Player p, CommandBlock cb) {
|
||||
Node root = new Node("Sentinel");
|
||||
root.addTextLine(Sentinel.lang.violations.commandBlockUse.detectionTree);
|
||||
|
||||
Node playerInfo = new Node(Sentinel.lang.violations.commandBlockUse.playerInfoTitle.formatted(p.getName()));
|
||||
playerInfo.addKeyValue(Sentinel.lang.violations.commandBlockUse.uuid, p.getUniqueId().toString());
|
||||
playerInfo.addField(Sentinel.lang.violations.commandBlockUse.location, Sentinel.lang.violations.commandBlockUse.locationFormat.formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
|
||||
root.addChild(playerInfo);
|
||||
|
||||
Node violationInfo = new Node(Sentinel.lang.violations.commandBlockUse.commandBlockUseInfoTitle);
|
||||
violationInfo.addField(Sentinel.lang.violations.commandBlockUse.blockLocation, Sentinel.lang.violations.commandBlockUse.blockLocationFormat.formatted(cb.getWorld().getName(), cb.getX(), cb.getY(), cb.getZ()));
|
||||
String command = cb.getCommand();
|
||||
if (command.length() <= 128) {
|
||||
violationInfo.addField(Sentinel.lang.violations.commandBlockUse.commandInside, command);
|
||||
} else {
|
||||
violationInfo.addKeyValue(Sentinel.lang.violations.commandBlockUse.commandUploadedTo, FileUtils.createCommandLog(command));
|
||||
}
|
||||
root.addChild(violationInfo);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
100
src/main/java/me/trouper/sentinel/server/events/ChatEvent.java
Normal file
100
src/main/java/me/trouper/sentinel/server/events/ChatEvent.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package me.trouper.sentinel.server.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import io.github.itzispyder.pdk.utils.SchedulerUtils;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.regex.AntiRegex;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.profanity.AntiProfanity;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.spam.AntiSpam;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.chat.ProfanityFilterGUI;
|
||||
import me.trouper.sentinel.server.gui.config.chat.RegexFilterGUI;
|
||||
import me.trouper.sentinel.server.gui.config.chat.SpamFilterGUI;
|
||||
import me.trouper.sentinel.server.gui.config.nuke.checks.*;
|
||||
import me.trouper.sentinel.server.gui.config.nuke.checks.command.DangerousCMDGUI;
|
||||
import me.trouper.sentinel.server.gui.config.nuke.checks.command.LoggedCMDGUI;
|
||||
import me.trouper.sentinel.server.gui.config.nuke.checks.command.SpecificCMDGUI;
|
||||
import me.trouper.sentinel.utils.PlayerUtils;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ChatEvent implements CustomListener {
|
||||
|
||||
@EventHandler
|
||||
private void onChat(AsyncPlayerChatEvent e) {
|
||||
ServerUtils.verbose("Chat event sanity check:\n Canceled %s".formatted(e.isCancelled()));
|
||||
handleEvent(e);
|
||||
}
|
||||
|
||||
public static void handleEvent(AsyncPlayerChatEvent e) {
|
||||
if (e.isCancelled()) return;
|
||||
if (PlayerUtils.isTrusted(e.getPlayer().getUniqueId().toString())) {
|
||||
if (MainGUI.awaitingCallback.contains(e.getPlayer().getUniqueId())) {
|
||||
ServerUtils.verbose("Attempting to cancel events for callback!");
|
||||
e.setCancelled(true);
|
||||
MainGUI.awaitingCallback.remove(e.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
ServerUtils.verbose("Handling Chat Event for callbacks");
|
||||
SchedulerUtils.later(0,()->{
|
||||
RegexFilterGUI.updater.invokeCallbacks(e);
|
||||
ProfanityFilterGUI.updater.invokeCallbacks(e);
|
||||
SpamFilterGUI.updater.invokeCallbacks(e);
|
||||
DangerousCMDGUI.updater.invokeCallbacks(e);
|
||||
LoggedCMDGUI.updater.invokeCallbacks(e);
|
||||
SpecificCMDGUI.updater.invokeCallbacks(e);
|
||||
CBEditGUI.updater.invokeCallbacks(e);
|
||||
CBMCPlaceGUI.updater.invokeCallbacks(e);
|
||||
CBMCUseGUI.updater.invokeCallbacks(e);
|
||||
CBPlaceGUI.updater.invokeCallbacks(e);
|
||||
CBUseGUI.updater.invokeCallbacks(e);
|
||||
HotbarActionGUI.updater.invokeCallbacks(e);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
Player p = e.getPlayer();
|
||||
|
||||
ServerUtils.verbose("Chat event start after trust check:\n Canceled %s".formatted(e.isCancelled()));
|
||||
|
||||
handle(p,
|
||||
"sentinel.chat.regex.bypass",
|
||||
Sentinel.mainConfig.chat.useAntiUnicode, "unicode",
|
||||
e,
|
||||
AntiRegex::handleRegex);
|
||||
|
||||
ServerUtils.verbose("Chat event middle after regex:\n Canceled %s".formatted(e.isCancelled()));
|
||||
|
||||
handle(p,
|
||||
"sentinel.chat.spam.bypass",
|
||||
Sentinel.mainConfig.chat.spamFilter.enabled,
|
||||
"spam",
|
||||
e,
|
||||
AntiSpam::handleAntiSpam);
|
||||
|
||||
ServerUtils.verbose("Chat event middle after spam:\n Canceled %s".formatted(e.isCancelled()));
|
||||
|
||||
handle(p,
|
||||
"sentinel.chat.swear.bypass",
|
||||
Sentinel.mainConfig.chat.swearFilter.enabled,
|
||||
"swear",
|
||||
e,
|
||||
AntiProfanity::handleProfanityFilter);
|
||||
|
||||
ServerUtils.verbose("Chat event ending after swear:\n Canceled %s".formatted(e.isCancelled()));
|
||||
}
|
||||
|
||||
private static void handle(Player p, String permission, boolean isEnabled, String eventType, AsyncPlayerChatEvent e, Consumer<AsyncPlayerChatEvent> handler) {
|
||||
ServerUtils.verbose("Handeling a chat filter:\n Canceled %s\nType: %s".formatted(e.isCancelled(),eventType));
|
||||
if (e.isCancelled()) return;
|
||||
if (p.hasPermission(permission)) return;
|
||||
ServerUtils.verbose("ChatEvent: Permission bypass failed, checking for " + eventType);
|
||||
if (!isEnabled) return;
|
||||
ServerUtils.verbose("ChatEvent: " + eventType + " check enabled, continuing!");
|
||||
handler.accept(e);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package me.trouper.sentinel.server.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.utils.trees.Node;
|
||||
import me.trouper.sentinel.utils.FileUtils;
|
||||
import me.trouper.sentinel.utils.PlayerUtils;
|
||||
import me.trouper.sentinel.server.functions.ViolationController;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class CommandExecuteEvent implements CustomListener {
|
||||
@EventHandler
|
||||
private void onCommand(PlayerCommandPreprocessEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (PlayerUtils.isTrusted(p)) return;
|
||||
String label = e.getMessage().substring(1).split(" ")[0];
|
||||
String args = e.getMessage();
|
||||
|
||||
Set<String> status = getCommandStatus(label);
|
||||
|
||||
if (status.contains("SPECIFIC") && Sentinel.violationConfig.commandExecute.specific.enabled) {
|
||||
e.setCancelled(true);
|
||||
Node log = getLog(p, args, "specific");
|
||||
ViolationController.handleViolation(
|
||||
Sentinel.lang.violations.commandExecute.specificCommandViolation.formatted(p.getName()),
|
||||
Sentinel.violationConfig.commandExecute.specific.punish,
|
||||
false,
|
||||
Sentinel.violationConfig.commandExecute.specific.logToDiscord,
|
||||
p,
|
||||
Sentinel.violationConfig.commandExecute.specific.punishmentCommands,
|
||||
log
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (status.contains("DANGEROUS") && Sentinel.violationConfig.commandExecute.dangerous.enabled) {
|
||||
e.setCancelled(true);
|
||||
Node log = getLog(p, args, "dangerous");
|
||||
ViolationController.handleViolation(
|
||||
Sentinel.lang.violations.commandExecute.dangerousCommandViolation.formatted(p.getName()),
|
||||
Sentinel.violationConfig.commandExecute.dangerous.punish,
|
||||
Sentinel.violationConfig.commandExecute.dangerous.deop,
|
||||
Sentinel.violationConfig.commandExecute.dangerous.logToDiscord,
|
||||
p,
|
||||
Sentinel.violationConfig.commandExecute.dangerous.punishmentCommands,
|
||||
log
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (status.contains("LOGGED") && Sentinel.violationConfig.commandExecute.logged.enabled) {
|
||||
Node log = getLog(p, args, "logged");
|
||||
ViolationController.handleViolation(
|
||||
Sentinel.lang.violations.commandExecute.loggedCommandViolation.formatted(p.getName()),
|
||||
false,
|
||||
false,
|
||||
Sentinel.violationConfig.commandExecute.logged.logToDiscord,
|
||||
p,
|
||||
null,
|
||||
log
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<String> getCommandStatus(String label) {
|
||||
Set<String> commandTypes = new HashSet<>();
|
||||
|
||||
if (label.startsWith("/")) {
|
||||
label = label.substring(1);
|
||||
}
|
||||
|
||||
if (label.contains(":")) {
|
||||
commandTypes.add("SPECIFIC");
|
||||
}
|
||||
|
||||
for (String loggedCommand : Sentinel.violationConfig.commandExecute.logged.commands) {
|
||||
if (loggedCommand.equals(label)) commandTypes.add("LOGGED");
|
||||
}
|
||||
|
||||
for (String dangerousCommand : Sentinel.violationConfig.commandExecute.dangerous.commands) {
|
||||
if (dangerousCommand.equals(label)) commandTypes.add("DANGEROUS");
|
||||
}
|
||||
|
||||
return commandTypes;
|
||||
}
|
||||
|
||||
private Node getLog(Player p, String command, String status) {
|
||||
Node root = new Node("Sentinel");
|
||||
root.addTextLine(Sentinel.lang.violations.commandExecute.specificCommandDetection.formatted(status));
|
||||
|
||||
Node playerInfo = new Node(Sentinel.lang.violations.commandExecute.playerInfoTitle.formatted(p.getName()));
|
||||
playerInfo.addKeyValue(Sentinel.lang.violations.commandExecute.uuid, p.getUniqueId().toString());
|
||||
playerInfo.addField(Sentinel.lang.violations.commandExecute.location, Sentinel.lang.violations.commandExecute.locationFormat.formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
|
||||
root.addChild(playerInfo);
|
||||
|
||||
Node violationInfo = new Node(Sentinel.lang.violations.commandExecute.violationInfoTitle);
|
||||
if (command.length() <= 128) {
|
||||
violationInfo.addField(Sentinel.lang.violations.commandExecute.commandField, command);
|
||||
} else {
|
||||
violationInfo.addKeyValue(Sentinel.lang.violations.commandExecute.commandUploadedTo, FileUtils.createCommandLog(command));
|
||||
}
|
||||
root.addChild(violationInfo);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package me.trouper.sentinel.server.events;
|
||||
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.ViolationController;
|
||||
import me.trouper.sentinel.utils.trees.Node;
|
||||
import me.trouper.sentinel.utils.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.inventory.InventoryCreativeEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class CreativeHotbarEvent implements CustomListener {
|
||||
|
||||
@EventHandler
|
||||
private void onNBTPull(InventoryCreativeEvent e) {
|
||||
//ServerUtils.verbose("NBT: Detected creative mode action");
|
||||
if (!Sentinel.violationConfig.creativeHotbarAction.enabled) return;
|
||||
ServerUtils.verbose("NBT: Enabled");
|
||||
if (!(e.getWhoClicked() instanceof Player p)) return;
|
||||
ServerUtils.verbose("NBT: Clicker is a player");
|
||||
if (e.getCursor() == null) return; // Well it through an exception during testing, so it isn't always false!
|
||||
ServerUtils.verbose("NBT: Cursor isn't null");
|
||||
ItemStack i = e.getCursor();
|
||||
if (PlayerUtils.isTrusted(p)) return;
|
||||
ServerUtils.verbose("NBT: Not trusted");
|
||||
if (e.getCursor().getItemMeta() == null) return;
|
||||
ServerUtils.verbose("NBT: Cursor has meta");
|
||||
if (!(i.hasItemMeta() && i.getItemMeta() != null)) return;
|
||||
ServerUtils.verbose("NBT: Item has meta");
|
||||
if (ItemUtils.itemPasses(i)) return;
|
||||
ServerUtils.verbose("NBT: Item doesn't pass, performing action");
|
||||
e.setCancelled(true);
|
||||
Node root = getLog(p, i);
|
||||
|
||||
ViolationController.handleViolation(
|
||||
Sentinel.lang.violations.creativeHotbar.nbtAttemptViolation.formatted(p.getName()),
|
||||
Sentinel.violationConfig.creativeHotbarAction.punish,
|
||||
Sentinel.violationConfig.creativeHotbarAction.deop,
|
||||
Sentinel.violationConfig.creativeHotbarAction.logToDiscord,
|
||||
p,
|
||||
Sentinel.violationConfig.creativeHotbarAction.punishmentCommands,
|
||||
root
|
||||
);
|
||||
}
|
||||
|
||||
private static Node getLog(Player p, ItemStack item) {
|
||||
Node root = new Node("Sentinel");
|
||||
root.addTextLine(Sentinel.lang.violations.creativeHotbar.nbtAttemptDetection);
|
||||
|
||||
Node playerInfo = new Node(Sentinel.lang.violations.creativeHotbar.playerInfoTitle.formatted(p.getName()));
|
||||
playerInfo.addKeyValue(Sentinel.lang.violations.creativeHotbar.uuid, p.getUniqueId().toString());
|
||||
playerInfo.addField(Sentinel.lang.violations.creativeHotbar.location, Sentinel.lang.violations.creativeHotbar.locationFormat.formatted(Math.round(p.getX()), Math.round(p.getY()), Math.round(p.getZ())));
|
||||
root.addChild(playerInfo);
|
||||
|
||||
Node violationInfo = new Node(Sentinel.lang.violations.creativeHotbar.itemInfoTitle);
|
||||
violationInfo.addKeyValue(Sentinel.lang.violations.creativeHotbar.itemType, item.getType().toString());
|
||||
violationInfo.addField(Sentinel.lang.violations.creativeHotbar.nbtUpload, FileUtils.createNBTLog(item));
|
||||
root.addChild(violationInfo);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package me.trouper.sentinel.server.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.itzispyder.pdk.events.CustomListener;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.utils.PlayerUtils;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.player.PlayerCommandSendEvent;
|
||||
import org.bukkit.event.server.TabCompleteEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PluginCloakingEvents implements CustomListener {
|
||||
|
||||
@EventHandler
|
||||
public void onCommand(PlayerCommandPreprocessEvent e) {
|
||||
if (!Sentinel.doNoPlugins) return;
|
||||
Player p = e.getPlayer();
|
||||
if (PlayerUtils.isTrusted(p)) return;
|
||||
|
||||
String message = e.getMessage();
|
||||
|
||||
if (message.startsWith("/")) {
|
||||
message = message.substring(1);
|
||||
}
|
||||
|
||||
for (String alias : Sentinel.advConfig.versionAliases) {
|
||||
if (!message.startsWith(alias)) continue;
|
||||
e.setCancelled(true);
|
||||
p.sendMessage(Text.color(Sentinel.lang.permissions.noPlugins));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onTabComplete(PlayerCommandSendEvent e) {
|
||||
if (!Sentinel.doNoPlugins) return;
|
||||
Player p = e.getPlayer();
|
||||
if (PlayerUtils.isTrusted(p)) return;
|
||||
|
||||
List<String> commands = e.getCommands().stream().toList();
|
||||
for (String command : commands) {
|
||||
if (command.contains(":")) {
|
||||
e.getCommands().remove(command);
|
||||
continue;
|
||||
}
|
||||
if (Sentinel.advConfig.versionAliases.contains(command)) {
|
||||
e.getCommands().remove(command);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//ServerUtils.verbose("Removed all the plugin specific commands form the listing. It now contains %s".formatted(e.getCommands().stream().toList().toString()));
|
||||
for (String fakePlugin : Sentinel.advConfig.fakePlugins) {
|
||||
e.getCommands().add(fakePlugin + ":" + fakePlugin);
|
||||
}
|
||||
//ServerUtils.verbose("Added the fake plugins, now it contains this: %s".formatted(e.getCommands().stream().toList().toString()));
|
||||
}
|
||||
|
||||
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 (!Sentinel.doNoPlugins) return;
|
||||
if (PlayerUtils.isTrusted(event.getPlayer())) return;
|
||||
ServerUtils.verbose("Type: §b%s§7 Index 0: §b%s§7".formatted(
|
||||
event.getPacket().getType(),
|
||||
event.getPacket().getStrings().read(0)
|
||||
));
|
||||
|
||||
String command = event.getPacket().getStrings().read(0);
|
||||
if (command.startsWith("/")) command = command.replaceFirst("/","");
|
||||
ServerUtils.verbose("Command is " + command);
|
||||
for (String alias : Sentinel.advConfig.versionAliases) {
|
||||
alias = alias.trim();
|
||||
command = command.trim();
|
||||
if (alias.equals(command) || command.startsWith(alias)) {
|
||||
ServerUtils.verbose("Caught a command we can replace: %s".formatted(command));
|
||||
event.getPacket().getStrings().write(0,"/sentineltab ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Sentinel.protocolManager.addPacketListener(new PacketAdapter(
|
||||
plugin,
|
||||
ListenerPriority.NORMAL,
|
||||
PacketType.Play.Server.COMMANDS
|
||||
) {
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
if (PlayerUtils.isTrusted(event.getPlayer())) return;
|
||||
ServerUtils.verbose("Index 0: §b%s§7".formatted(
|
||||
event.getPacket().getStrings().read(0)
|
||||
));
|
||||
event.setCancelled(true);
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
String input = event.getPacket().getStrings().read(0);
|
||||
if (input == null || input.isEmpty()) return;
|
||||
|
||||
input = input.replaceFirst("/", "");
|
||||
if (input.length() < 2) {
|
||||
event.getPacket().getStrings().write(0, "sentineltab");
|
||||
ServerUtils.verbose("Successfully Blocked ver command: " + input);
|
||||
return;
|
||||
}
|
||||
|
||||
for (String ver : Sentinel.advConfig.versionAliases) {
|
||||
if (!input.startsWith(ver + " ")) continue;
|
||||
String modifiedInput = input.replaceFirst(ver, "sentineltab");
|
||||
event.getPacket().getStrings().write(0, modifiedInput);
|
||||
ServerUtils.verbose("Successfully Blocked ver command: " + input);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package me.trouper.sentinel.server.functions;
|
||||
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.types.WhitelistedBlock;
|
||||
import me.trouper.sentinel.utils.PlayerUtils;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.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.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CBWhitelistManager {
|
||||
|
||||
public static Set<UUID> autoWhitelist = new HashSet<>();
|
||||
|
||||
public static void add(CommandBlock cb, UUID owner) {
|
||||
ServerUtils.verbose("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;
|
||||
return PlayerUtils.isTrusted(cb.owner());
|
||||
}
|
||||
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.verbose("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.verbose("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.verbose("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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package me.trouper.sentinel.server.functions;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.ServerUtils;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.commands.SocialSpyCommand;
|
||||
import me.trouper.sentinel.server.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.handleEvent(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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package me.trouper.sentinel.server.functions;
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
50
src/main/java/me/trouper/sentinel/server/functions/ViolationController.java
Executable file
50
src/main/java/me/trouper/sentinel/server/functions/ViolationController.java
Executable file
@@ -0,0 +1,50 @@
|
||||
package me.trouper.sentinel.server.functions;
|
||||
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.utils.trees.ConsoleFormatter;
|
||||
import me.trouper.sentinel.utils.trees.EmbedFormatter;
|
||||
import me.trouper.sentinel.utils.trees.HoverFormatter;
|
||||
import me.trouper.sentinel.utils.trees.Node;
|
||||
import me.trouper.sentinel.utils.PlayerUtils;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ViolationController {
|
||||
|
||||
|
||||
public static void handleViolation(String message, boolean punish, boolean deopUser, boolean logToDiscord, Player perp, List<String> punishCommands, Node tree) {
|
||||
Node actions = new Node(Sentinel.lang.violations.violationMessages.actions);
|
||||
actions.addTextLine(Sentinel.lang.violations.violationMessages.eventCancelled);
|
||||
|
||||
if (punish) {
|
||||
for (String punishCommand : punishCommands) {
|
||||
ServerUtils.sendCommand(punishCommand.replaceAll("%player%", perp.getName()));
|
||||
}
|
||||
actions.addTextLine(Sentinel.lang.violations.violationMessages.punishmentCommandsExecuted);
|
||||
}
|
||||
|
||||
if (deopUser) {
|
||||
perp.setOp(false);
|
||||
actions.addTextLine(Sentinel.lang.violations.violationMessages.userOpStripped);
|
||||
}
|
||||
|
||||
if (logToDiscord) actions.addTextLine(Sentinel.lang.violations.violationMessages.loggedToDiscord);
|
||||
tree.addChild(actions);
|
||||
|
||||
if (logToDiscord) {
|
||||
EmbedFormatter.sendEmbed(EmbedFormatter.format(tree));
|
||||
}
|
||||
|
||||
ServerUtils.forEachPlayer(trusted -> {
|
||||
if (PlayerUtils.isTrusted(trusted)) {
|
||||
trusted.sendMessage(Component.text(Text.prefix(message)).hoverEvent(Component.text(HoverFormatter.format(tree)).asHoverEvent()));
|
||||
}
|
||||
});
|
||||
|
||||
Sentinel.log.info(ConsoleFormatter.format(tree));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package me.trouper.sentinel.server.functions.chatfilter;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.SchedulerUtils;
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordEmbed;
|
||||
import me.trouper.sentinel.data.Emojis;
|
||||
import me.trouper.sentinel.utils.trees.EmbedFormatter;
|
||||
import me.trouper.sentinel.server.functions.Randomizer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class FalsePositiveReporting {
|
||||
public static Map<Long, Report> reports = new HashMap<>();
|
||||
|
||||
public static Report initializeReport(String message) {
|
||||
final long reportID = Randomizer.generateID();
|
||||
LinkedHashMap<String,String> steps = new LinkedHashMap<>();
|
||||
steps.put("Original Message", "`%s`".formatted(message));
|
||||
|
||||
SchedulerUtils.later(1200,()->{
|
||||
reports.remove(reportID);
|
||||
});
|
||||
return new Report(reportID,message,steps);
|
||||
}
|
||||
|
||||
public static void sendReport(Player sender, 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,
|
||||
sender.getName(),
|
||||
Emojis.target,
|
||||
Emojis.space,
|
||||
Emojis.rightArrow,
|
||||
sender.getUniqueId()
|
||||
));
|
||||
|
||||
report.getStepsTaken().forEach((key, value)->{
|
||||
embed.addField(new DiscordEmbed.Field(key,value));
|
||||
});
|
||||
|
||||
EmbedFormatter.sendEmbed(embed.build());
|
||||
|
||||
reports.remove(report.getId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package me.trouper.sentinel.server.functions.chatfilter;
|
||||
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.profanity.Severity;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
|
||||
public class FilterHelpers {
|
||||
|
||||
public static Severity checkSlur(String text, Severity backup) {
|
||||
if (containsSlurs(text)) return Severity.SLUR;
|
||||
if (containsSwears(text)) return backup;
|
||||
return Severity.SAFE;
|
||||
}
|
||||
|
||||
public static boolean containsSwears(String text) {
|
||||
ServerUtils.verbose("ProfanityFilter: Checking for swears");
|
||||
for (String swear : Sentinel.swearConfig.swears) {
|
||||
if (text.contains(swear)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean containsSlurs(String text) {
|
||||
ServerUtils.verbose("ProfanityFilter: Checking for slurs");
|
||||
for (String slur : Sentinel.strictConfig.strict) {
|
||||
if (text.contains(slur)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String removeFalsePositives(String text) {
|
||||
for (String falsePositive : Sentinel.fpConfig.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 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 : Sentinel.swearConfig.swears) {
|
||||
text = text.replace(swear, start + swear + end);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private static String highlightSlurs(String text, String start, String end) {
|
||||
for (String slur : Sentinel.strictConfig.strict) {
|
||||
text = text.replace(slur, start + slur + end);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public static String fullSimplify(String text) {
|
||||
String lowercasedText = text.toLowerCase();
|
||||
String cleanedText = FilterHelpers.removeFalsePositives(lowercasedText);
|
||||
String convertedText = FilterHelpers.convertLeetSpeakCharacters(cleanedText);
|
||||
String strippedText = FilterHelpers.stripSpecialCharacters(convertedText);
|
||||
String simplifiedText = FilterHelpers.simplifyRepeatingLetters(strippedText);
|
||||
return FilterHelpers.removePeriodsAndSpaces(simplifiedText);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package me.trouper.sentinel.server.functions.chatfilter;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
public class Report {
|
||||
private long id;
|
||||
private String original;
|
||||
private LinkedHashMap<String,String> stepsTaken;
|
||||
|
||||
|
||||
public Report(long id, String original, LinkedHashMap<String, String> stepsTaken) {
|
||||
this.id = id;
|
||||
this.original = original;
|
||||
this.stepsTaken = stepsTaken;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getOriginal() {
|
||||
return original;
|
||||
}
|
||||
|
||||
public void setOriginal(String original) {
|
||||
this.original = original;
|
||||
}
|
||||
|
||||
public LinkedHashMap<String, String> getStepsTaken() {
|
||||
return stepsTaken;
|
||||
}
|
||||
|
||||
public void setStepsTaken(LinkedHashMap<String, String> stepsTaken) {
|
||||
this.stepsTaken = stepsTaken;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package me.trouper.sentinel.server.functions.chatfilter.profanity;
|
||||
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
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 AntiProfanity {
|
||||
public static Map<UUID, Integer> scoreMap = new HashMap<>();
|
||||
|
||||
public static void handleProfanityFilter(AsyncPlayerChatEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
ServerUtils.verbose("Anti Profanity Opening: Event is canceled.");
|
||||
}
|
||||
Player player = event.getPlayer();
|
||||
ProfanityResponse response = ProfanityResponse.generate(event);
|
||||
Severity severity = response.getSeverity();
|
||||
ServerUtils.verbose("Response came back, uncertain null.");
|
||||
if (severity == null) return;
|
||||
ServerUtils.verbose("Not null, its severity is " + severity);
|
||||
if (severity.equals(Severity.SAFE)) return;
|
||||
ServerUtils.verbose("Not null or safe, canceling event");
|
||||
event.setCancelled(true);
|
||||
|
||||
scoreMap.putIfAbsent(player.getUniqueId(), 0);
|
||||
int previousScore = scoreMap.get(player.getUniqueId());
|
||||
|
||||
int newScore = previousScore + severity.getScore();
|
||||
scoreMap.put(player.getUniqueId(), newScore);
|
||||
|
||||
if (newScore > Sentinel.mainConfig.chat.swearFilter.punishScore || Severity.SLUR.equals(severity)) {
|
||||
response.setPunished(true);
|
||||
ProfanityAction.run(response);
|
||||
return;
|
||||
}
|
||||
|
||||
ProfanityAction.run(response);
|
||||
}
|
||||
|
||||
public static void decayScore() {
|
||||
for (UUID uuid : scoreMap.keySet()) {
|
||||
int score = scoreMap.get(uuid);
|
||||
if (score > 0) {
|
||||
score = score - Sentinel.mainConfig.chat.swearFilter.scoreDecay;
|
||||
scoreMap.put(uuid, Math.max(0, score));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package me.trouper.sentinel.server.functions.chatfilter.profanity;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordEmbed;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.FalsePositiveReporting;
|
||||
import me.trouper.sentinel.utils.trees.ConsoleFormatter;
|
||||
import me.trouper.sentinel.utils.trees.EmbedFormatter;
|
||||
import me.trouper.sentinel.utils.trees.HoverFormatter;
|
||||
import me.trouper.sentinel.utils.trees.Node;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
|
||||
public class ProfanityAction {
|
||||
public static void run(ProfanityResponse response) {
|
||||
FalsePositiveReporting.reports.put(response.getReport().getId(),response.getReport());
|
||||
Node tree = getTree(response);
|
||||
|
||||
if (response.isPunished()) {
|
||||
punish(response);
|
||||
discordNotification(tree);
|
||||
}
|
||||
staffWarning(response,tree);
|
||||
playerWarning(response);
|
||||
consoleLog(tree);
|
||||
}
|
||||
|
||||
public static void punish(ProfanityResponse response) {
|
||||
if (response.getSeverity().equals(Severity.SLUR)) {
|
||||
for (String slurCommand : Sentinel.mainConfig.chat.swearFilter.strictPunishCommands) {
|
||||
ServerUtils.sendCommand(slurCommand.replaceAll("%player%", response.getEvent().getPlayer().getName()));
|
||||
}
|
||||
}
|
||||
for (String swearCommand : Sentinel.mainConfig.chat.swearFilter.swearPunishCommands) {
|
||||
ServerUtils.sendCommand(swearCommand.replaceAll("%player%", response.getEvent().getPlayer().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
public static void staffWarning(ProfanityResponse report, Node tree) {
|
||||
String messageText = Text.prefix("&b&n%s&r &7%s &8(&4%s&7/&c%s&8)".formatted(
|
||||
report.getEvent().getPlayer().getName(),
|
||||
report.isPunished() ? Sentinel.lang.violations.chat.profanity.autoPunish : Sentinel.lang.violations.chat.profanity.prevent,
|
||||
AntiProfanity.scoreMap.getOrDefault(report.getEvent().getPlayer().getUniqueId(), 0),
|
||||
Sentinel.mainConfig.chat.swearFilter.punishScore
|
||||
));
|
||||
String hoverText = HoverFormatter.format(tree);
|
||||
|
||||
ServerUtils.forEachStaff(player -> player.sendMessage(Component.text(messageText).hoverEvent(Component.text(hoverText).asHoverEvent())));
|
||||
}
|
||||
|
||||
public static void playerWarning(ProfanityResponse response) {
|
||||
String message = Text.prefix(!response.isPunished() ? Sentinel.lang.violations.chat.profanity.preventWarning : Sentinel.lang.violations.chat.profanity.autoPunishWarning);
|
||||
String hoverText = Sentinel.lang.automatedActions.actionAutomaticReportable;
|
||||
String command = "/sentinelcallback fpreport %s".formatted(response.getReport().getId());
|
||||
response.getEvent().getPlayer().sendMessage(Component.text(message)
|
||||
.hoverEvent(Component.text(hoverText).asHoverEvent())
|
||||
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND,command)));
|
||||
}
|
||||
|
||||
public static void consoleLog(Node tree) {
|
||||
Sentinel.log.info(ConsoleFormatter.format(tree));
|
||||
}
|
||||
|
||||
public static void discordNotification(Node tree) {
|
||||
DiscordEmbed embed = EmbedFormatter.format(tree);
|
||||
EmbedFormatter.sendEmbed(embed);
|
||||
}
|
||||
|
||||
private static Node getTree(ProfanityResponse response) {
|
||||
Node root = new Node("Sentinel");
|
||||
root.addTextLine(Sentinel.lang.violations.chat.profanity.treeTitle);
|
||||
|
||||
Node playerInfo = new Node(Sentinel.lang.violations.chat.profanity.playerInfoTitle.formatted(response.getEvent().getPlayer().getName()));
|
||||
playerInfo.addKeyValue(Sentinel.lang.violations.chat.profanity.uuid, response.getEvent().getPlayer().getUniqueId().toString());
|
||||
playerInfo.addKeyValue(Sentinel.lang.violations.chat.profanity.score, "%s/%s".formatted(AntiProfanity.scoreMap.getOrDefault(response.getEvent().getPlayer().getUniqueId(),0),Sentinel.mainConfig.chat.swearFilter.punishScore));
|
||||
root.addChild(playerInfo);
|
||||
|
||||
Node reportInfo = new Node(Sentinel.lang.violations.chat.profanity.reportInfoTitle);
|
||||
reportInfo.addField(Sentinel.lang.violations.chat.profanity.originalMessage, response.getOriginalMessage());
|
||||
reportInfo.addField(Sentinel.lang.violations.chat.profanity.processedMessage, response.getProcessedMessage());
|
||||
reportInfo.addKeyValue(Sentinel.lang.violations.chat.profanity.severity, response.getSeverity().toString());
|
||||
root.addChild(reportInfo);
|
||||
|
||||
Node actions = new Node(Sentinel.lang.violations.chat.profanity.actionTitle);
|
||||
actions.addTextLine(Sentinel.lang.violations.chat.profanity.blockAction);
|
||||
if (response.isPunished()) actions.addTextLine(Sentinel.lang.violations.chat.profanity.commandAction);
|
||||
root.addChild(actions);
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
package me.trouper.sentinel.server.functions.chatfilter.profanity;
|
||||
|
||||
import me.trouper.sentinel.server.functions.chatfilter.FalsePositiveReporting;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.FilterHelpers;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.Report;
|
||||
import me.trouper.sentinel.data.Emojis;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
public class ProfanityResponse {
|
||||
|
||||
private AsyncPlayerChatEvent event;
|
||||
private String originalMessage;
|
||||
private String processedMessage;
|
||||
private Report report;
|
||||
private Severity severity;
|
||||
private boolean punished;
|
||||
|
||||
public ProfanityResponse(AsyncPlayerChatEvent event, String originalMessage, String processedMessage, Report report, Severity severity, boolean punished) {
|
||||
this.event = event;
|
||||
this.originalMessage = originalMessage;
|
||||
this.processedMessage = processedMessage;
|
||||
this.report = report;
|
||||
this.severity = severity;
|
||||
this.punished = punished;
|
||||
}
|
||||
|
||||
public AsyncPlayerChatEvent getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
public void setEvent(AsyncPlayerChatEvent event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public String getOriginalMessage() {
|
||||
return originalMessage;
|
||||
}
|
||||
|
||||
public void setOriginalMessage(String originalMessage) {
|
||||
this.originalMessage = originalMessage;
|
||||
}
|
||||
|
||||
public String getProcessedMessage() {
|
||||
return processedMessage;
|
||||
}
|
||||
|
||||
public void setProcessedMessage(String processedMessage) {
|
||||
this.processedMessage = processedMessage;
|
||||
}
|
||||
|
||||
public Report getReport() {
|
||||
return report;
|
||||
}
|
||||
|
||||
public void setReport(Report report) {
|
||||
this.report = report;
|
||||
}
|
||||
|
||||
public Severity getSeverity() {
|
||||
return severity;
|
||||
}
|
||||
|
||||
public void setSeverity(Severity severity) {
|
||||
this.severity = severity;
|
||||
}
|
||||
|
||||
public boolean isPunished() {
|
||||
return punished;
|
||||
}
|
||||
|
||||
public void setPunished(boolean punished) {
|
||||
this.punished = punished;
|
||||
}
|
||||
|
||||
public static ProfanityResponse generate(AsyncPlayerChatEvent e) {
|
||||
if (e.isCancelled()) {
|
||||
ServerUtils.verbose("Profanity response opening Event is canceled.");
|
||||
}
|
||||
Report report = FalsePositiveReporting.initializeReport(e.getMessage());
|
||||
Severity severity = Severity.SAFE;
|
||||
|
||||
ProfanityResponse response = new ProfanityResponse(e,e.getMessage(),null,report,severity,false);
|
||||
|
||||
String text = Text.removeFirstColor(e.getMessage());
|
||||
response.setOriginalMessage(text);
|
||||
|
||||
// 1:
|
||||
String lowercasedText = text.toLowerCase();
|
||||
response.getReport().getStepsTaken().put("Lowercased", lowercasedText);
|
||||
response.setProcessedMessage(FilterHelpers.highlightProfanity(lowercasedText,"<hs>", "<he>"));
|
||||
ServerUtils.verbose("ProfanityFilter: Lowercased: " + lowercasedText);
|
||||
|
||||
|
||||
// 2:
|
||||
String cleanedText = FilterHelpers.removeFalsePositives(lowercasedText);
|
||||
response.getReport().getStepsTaken().put("Remove False Positives", cleanedText);
|
||||
response.setProcessedMessage(FilterHelpers.highlightProfanity(cleanedText,"<hs>", "<he>"));
|
||||
ServerUtils.verbose(("ProfanityFilter: Removed False positives: " + cleanedText));
|
||||
|
||||
response.setSeverity(FilterHelpers.checkSlur(cleanedText, Severity.LOW));
|
||||
if (response.getSeverity() != Severity.SAFE) {
|
||||
response.getReport().getStepsTaken().replace("Remove False Positives", "%s %s".formatted(
|
||||
FilterHelpers.highlightProfanity(cleanedText,"||","||"),
|
||||
Emojis.alarm));
|
||||
return response;
|
||||
}
|
||||
|
||||
// 4:
|
||||
String convertedText = FilterHelpers.convertLeetSpeakCharacters(cleanedText);
|
||||
response.getReport().getStepsTaken().put("Convert LeetSpeak", convertedText);
|
||||
response.setProcessedMessage(FilterHelpers.highlightProfanity(convertedText,"<hs>", "<he>"));
|
||||
ServerUtils.verbose(("ProfanityFilter: Leet Converted: " + convertedText));
|
||||
|
||||
response.setSeverity(FilterHelpers.checkSlur(convertedText, Severity.MEDIUM_LOW));
|
||||
if (response.getSeverity() != Severity.SAFE) {
|
||||
response.getReport().getStepsTaken().replace("Convert LeetSpeak", "%s %s".formatted(
|
||||
FilterHelpers.highlightProfanity(cleanedText,"||","||"),
|
||||
Emojis.alarm));
|
||||
return response;
|
||||
}
|
||||
|
||||
// 6:
|
||||
String strippedText = FilterHelpers.stripSpecialCharacters(convertedText);
|
||||
response.getReport().getStepsTaken().put("Remove Special Characters", strippedText);
|
||||
response.setProcessedMessage(FilterHelpers.highlightProfanity(strippedText,"<hs>", "<he>"));
|
||||
ServerUtils.verbose(("ProfanityFilter: Specials Removed: " + strippedText));
|
||||
|
||||
response.setSeverity(FilterHelpers.checkSlur(strippedText, Severity.MEDIUM));
|
||||
if (response.getSeverity() != Severity.SAFE) {
|
||||
response.getReport().getStepsTaken().replace("Remove Special Characters", "%s %s".formatted(
|
||||
FilterHelpers.highlightProfanity(cleanedText,"||","||"),
|
||||
Emojis.alarm));
|
||||
return response;
|
||||
}
|
||||
|
||||
// 8:
|
||||
String simplifiedText = FilterHelpers.simplifyRepeatingLetters(strippedText);
|
||||
response.getReport().getStepsTaken().put("Remove Repeats", simplifiedText);
|
||||
response.setProcessedMessage(FilterHelpers.highlightProfanity(simplifiedText,"<hs>", "<he>"));
|
||||
ServerUtils.verbose(("ProfanityFilter: Removed Repeating: " + simplifiedText));
|
||||
|
||||
response.setSeverity(FilterHelpers.checkSlur(simplifiedText, Severity.MEDIUM_HIGH));
|
||||
if (response.getSeverity() != Severity.SAFE) {
|
||||
response.getReport().getStepsTaken().replace("Remove Repeats", "%s %s".formatted(
|
||||
FilterHelpers.highlightProfanity(cleanedText,"||","||"),
|
||||
Emojis.alarm));
|
||||
return response;
|
||||
}
|
||||
|
||||
// 10:
|
||||
String finalText = FilterHelpers.removePeriodsAndSpaces(simplifiedText);
|
||||
response.getReport().getStepsTaken().put("Remove Punctuation", finalText);
|
||||
response.setProcessedMessage(FilterHelpers.highlightProfanity(finalText,"<hs>", "<he>"));
|
||||
ServerUtils.verbose(("ProfanityFilter: Remove Punctuation: " + finalText));
|
||||
|
||||
response.setSeverity(FilterHelpers.checkSlur(finalText, Severity.HIGH));
|
||||
if (response.getSeverity() != Severity.SAFE) {
|
||||
response.getReport().getStepsTaken().replace("Remove Punctuation", "%s %s".formatted(
|
||||
FilterHelpers.highlightProfanity(cleanedText,"||","||"),
|
||||
Emojis.alarm));
|
||||
}
|
||||
|
||||
ServerUtils.verbose(("ProfanityFilter: Finished " + finalText));
|
||||
if (e.isCancelled()) {
|
||||
ServerUtils.verbose("Profanity response closing: Event is canceled.");
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package me.trouper.sentinel.server.functions.chatfilter.profanity;
|
||||
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
|
||||
public enum Severity {
|
||||
LOW(Sentinel.mainConfig.chat.swearFilter.lowScore),
|
||||
MEDIUM_LOW(Sentinel.mainConfig.chat.swearFilter.mediumLowScore),
|
||||
MEDIUM(Sentinel.mainConfig.chat.swearFilter.mediumScore),
|
||||
MEDIUM_HIGH(Sentinel.mainConfig.chat.swearFilter.mediumHighScore),
|
||||
HIGH(Sentinel.mainConfig.chat.swearFilter.highScore),
|
||||
REGEX(Sentinel.mainConfig.chat.swearFilter.regexScore),
|
||||
SLUR(Sentinel.mainConfig.chat.swearFilter.highScore),
|
||||
SAFE(0);
|
||||
|
||||
private final int score;
|
||||
|
||||
Severity(int score) {
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
public int getScore() {
|
||||
return score;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.trouper.sentinel.server.functions.chatfilter.regex;
|
||||
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
public class AntiRegex {
|
||||
public static void handleRegex(AsyncPlayerChatEvent e) {
|
||||
if (e.isCancelled()) {
|
||||
ServerUtils.verbose("Regex Filter opening Event is canceled.");
|
||||
}
|
||||
ServerUtils.verbose("Handeling advanced");
|
||||
RegexResponse response = RegexResponse.generate(e);
|
||||
ServerUtils.verbose("Response got back");
|
||||
if (response.getFlagType() == null) return;
|
||||
ServerUtils.verbose("Detection happened");
|
||||
e.setCancelled(true);
|
||||
RegexAction.run(response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package me.trouper.sentinel.server.functions.chatfilter.regex;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordEmbed;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.FalsePositiveReporting;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.profanity.AntiProfanity;
|
||||
import me.trouper.sentinel.utils.trees.ConsoleFormatter;
|
||||
import me.trouper.sentinel.utils.trees.EmbedFormatter;
|
||||
import me.trouper.sentinel.utils.trees.HoverFormatter;
|
||||
import me.trouper.sentinel.utils.trees.Node;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
|
||||
public class RegexAction {
|
||||
public static void run(RegexResponse response) {
|
||||
FalsePositiveReporting.reports.put(response.getReport().getId(),response.getReport());
|
||||
Node tree = getTree(response);
|
||||
|
||||
if (response.isPunished()) {
|
||||
punish(response);
|
||||
discordNotification(tree);
|
||||
}
|
||||
staffWarning(response,tree);
|
||||
playerWarning(response);
|
||||
consoleLog(tree);
|
||||
}
|
||||
|
||||
public static void punish(RegexResponse response) {
|
||||
if (response.getFlagType().equals(RegexFlagType.STRICT_BLOCK)) {
|
||||
for (String slurCommand : Sentinel.mainConfig.chat.swearFilter.strictPunishCommands) {
|
||||
ServerUtils.sendCommand(slurCommand.replaceAll("%player%", response.getEvent().getPlayer().getName()));
|
||||
}
|
||||
}
|
||||
for (String swearCommand : Sentinel.mainConfig.chat.swearFilter.swearPunishCommands) {
|
||||
ServerUtils.sendCommand(swearCommand.replaceAll("%player%", response.getEvent().getPlayer().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
public static void staffWarning(RegexResponse report, Node tree) {
|
||||
String messageText = Text.prefix("&b&n%s&r &7%s".formatted(
|
||||
report.getEvent().getPlayer().getName(),
|
||||
report.isPunished() ? Sentinel.lang.violations.chat.regex.autoPunish : Sentinel.lang.violations.chat.regex.regexTrigger
|
||||
));
|
||||
String hoverText = HoverFormatter.format(tree);
|
||||
|
||||
ServerUtils.forEachStaff(player -> player.sendMessage(Component.text(messageText).hoverEvent(Component.text(hoverText).asHoverEvent())));
|
||||
}
|
||||
|
||||
public static void playerWarning(RegexResponse response) {
|
||||
String message = Text.prefix(response.getFlagType().getBlockMessage()) ;
|
||||
String hoverText = Sentinel.lang.automatedActions.actionAutomaticReportable;
|
||||
String command = "/sentinelcallback fpreport %s".formatted(response.getReport().getId());
|
||||
response.getEvent().getPlayer().sendMessage(Component.text(message)
|
||||
.hoverEvent(Component.text(hoverText).asHoverEvent())
|
||||
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND,command)));
|
||||
}
|
||||
|
||||
public static void consoleLog(Node tree) {
|
||||
Sentinel.log.info(ConsoleFormatter.format(tree));
|
||||
}
|
||||
|
||||
public static void discordNotification(Node tree) {
|
||||
DiscordEmbed embed = EmbedFormatter.format(tree);
|
||||
EmbedFormatter.sendEmbed(embed);
|
||||
}
|
||||
|
||||
private static Node getTree(RegexResponse response) {
|
||||
Node root = new Node("Sentinel");
|
||||
root.addTextLine(Sentinel.lang.violations.chat.regex.treeTitle);
|
||||
|
||||
Node playerInfo = new Node(Sentinel.lang.violations.chat.regex.playerInfoTitle.formatted(response.getEvent().getPlayer().getName()));
|
||||
playerInfo.addKeyValue(Sentinel.lang.violations.chat.regex.uuid, response.getEvent().getPlayer().getUniqueId().toString());
|
||||
playerInfo.addKeyValue(Sentinel.lang.violations.chat.regex.score, "%s".formatted(AntiProfanity.scoreMap.get(response.getEvent().getPlayer().getUniqueId())));
|
||||
root.addChild(playerInfo);
|
||||
|
||||
Node reportInfo = new Node(Sentinel.lang.violations.chat.regex.reportInfoTitle.formatted(response.getFlagType().getName()));
|
||||
reportInfo.addField(Sentinel.lang.violations.chat.regex.originalMessage, response.getOriginalMessage());
|
||||
reportInfo.addField(Sentinel.lang.violations.chat.regex.flaggedMessage, response.getHighlightedMessage());
|
||||
root.addChild(reportInfo);
|
||||
|
||||
Node actions = new Node(Sentinel.lang.violations.chat.regex.actionTitle);
|
||||
actions.addTextLine(Sentinel.lang.violations.chat.regex.blockAction);
|
||||
if (response.isPunished()) actions.addTextLine(Sentinel.lang.violations.chat.regex.commandAction);
|
||||
root.addChild(actions);
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package me.trouper.sentinel.server.functions.chatfilter.regex;
|
||||
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
|
||||
public enum RegexFlagType {
|
||||
URL_BLOCK(Sentinel.lang.violations.chat.regex.urlBlockName, Sentinel.lang.violations.chat.regex.urlBlockMessage),
|
||||
UNICODE_BLOCK(Sentinel.lang.violations.chat.regex.unicodeBlockName, Sentinel.lang.violations.chat.regex.unicodeBlockMessage),
|
||||
SWEAR_BLOCK(Sentinel.lang.violations.chat.regex.swearBlockName, Sentinel.lang.violations.chat.regex.swearBlockMessage),
|
||||
STRICT_BLOCK(Sentinel.lang.violations.chat.regex.strictBlockName, Sentinel.lang.violations.chat.regex.strictBlockMessage);
|
||||
|
||||
|
||||
|
||||
private String name;
|
||||
private String blockMessage;
|
||||
|
||||
RegexFlagType(String name, String blockMessage) {
|
||||
|
||||
}
|
||||
|
||||
public String getBlockMessage() {
|
||||
return blockMessage;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
package me.trouper.sentinel.server.functions.chatfilter.regex;
|
||||
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.FalsePositiveReporting;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.Report;
|
||||
import me.trouper.sentinel.data.Emojis;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class RegexResponse {
|
||||
private AsyncPlayerChatEvent event;
|
||||
private String originalMessage;
|
||||
private String highlightedMessage;
|
||||
private RegexFlagType flagType;
|
||||
private Report report;
|
||||
private boolean isPunished;
|
||||
|
||||
public RegexResponse(AsyncPlayerChatEvent event, String originalMessage, String highlightedMessage, RegexFlagType flagType, Report report, boolean isPunished) {
|
||||
this.event = event;
|
||||
this.originalMessage = originalMessage;
|
||||
this.highlightedMessage = highlightedMessage;
|
||||
this.flagType = flagType;
|
||||
this.report = report;
|
||||
this.isPunished = isPunished;
|
||||
}
|
||||
|
||||
public AsyncPlayerChatEvent getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
public void setEvent(AsyncPlayerChatEvent event) {
|
||||
this.event = event;
|
||||
}
|
||||
public String getOriginalMessage() {
|
||||
return originalMessage;
|
||||
}
|
||||
|
||||
public void setOriginalMessage(String originalMessage) {
|
||||
this.originalMessage = originalMessage;
|
||||
}
|
||||
|
||||
public String getHighlightedMessage() {
|
||||
return highlightedMessage;
|
||||
}
|
||||
|
||||
public void setHighlightedMessage(String highlightedMessage) {
|
||||
this.highlightedMessage = highlightedMessage;
|
||||
}
|
||||
|
||||
public RegexFlagType getFlagType() {
|
||||
return flagType;
|
||||
}
|
||||
|
||||
public void setFlagType(RegexFlagType flagType) {
|
||||
this.flagType = flagType;
|
||||
}
|
||||
|
||||
public Report getReport() {
|
||||
return report;
|
||||
}
|
||||
|
||||
public void setReport(Report report) {
|
||||
this.report = report;
|
||||
}
|
||||
|
||||
public boolean isPunished() {
|
||||
return isPunished;
|
||||
}
|
||||
|
||||
public void setPunished(boolean punished) {
|
||||
isPunished = punished;
|
||||
}
|
||||
|
||||
|
||||
public static RegexResponse generate(AsyncPlayerChatEvent e) {
|
||||
if (e.isCancelled()) {
|
||||
ServerUtils.verbose("Regex response opening Event is canceled.");
|
||||
}
|
||||
Report report = FalsePositiveReporting.initializeReport(e.getMessage());
|
||||
RegexResponse response = new RegexResponse(e,e.getMessage(),null,null,report,false);
|
||||
|
||||
String unicode = handleAntiUnicode(e,response.getReport());
|
||||
String url = handleAntiURL(e,response.getReport());
|
||||
String strict = handleStrictRegex(e,response.getReport());
|
||||
String swear = handleSwearRegex(e,response.getReport());
|
||||
ServerUtils.verbose("All filters have ran without thread error");
|
||||
if (Sentinel.mainConfig.chat.useAntiUnicode && handleAntiUnicode(e,report) != null) {
|
||||
response.setHighlightedMessage(unicode);
|
||||
response.setFlagType(RegexFlagType.UNICODE_BLOCK);
|
||||
return response;
|
||||
}
|
||||
if (Sentinel.mainConfig.chat.useAntiURL && handleAntiURL(e,report) != null) {
|
||||
response.setHighlightedMessage(url);
|
||||
response.setFlagType(RegexFlagType.URL_BLOCK);
|
||||
return response;
|
||||
}
|
||||
if (Sentinel.mainConfig.chat.useStrictRegex && handleStrictRegex(e,report) != null) {
|
||||
response.setHighlightedMessage(strict);
|
||||
response.setFlagType(RegexFlagType.STRICT_BLOCK);
|
||||
return response;
|
||||
}
|
||||
if (Sentinel.mainConfig.chat.useSwearRegex && handleSwearRegex(e,report) != null) {
|
||||
response.setPunished(true);
|
||||
response.setHighlightedMessage(swear);
|
||||
response.setFlagType(RegexFlagType.SWEAR_BLOCK);
|
||||
return response;
|
||||
}
|
||||
ServerUtils.verbose("Nothing caught, returning the blank response");
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
public static String handleAntiUnicode(AsyncPlayerChatEvent e, Report report) {
|
||||
String message = Text.removeFirstColor(e.getMessage());
|
||||
report.getStepsTaken().put("Anti-Unicode", "`%s`".formatted(message));
|
||||
ServerUtils.verbose("AdvBlocker: Checking for unicode: " + message);
|
||||
String nonAllowed = message.replaceAll(Sentinel.advConfig.allowedCharRegex, "").trim();
|
||||
|
||||
if (!nonAllowed.isEmpty()) {
|
||||
ServerUtils.verbose("AdvBlocker: Caught Unicode: " + nonAllowed);
|
||||
report.getStepsTaken().replace("Anti-Unicode", "`%s` %s".formatted(message, Emojis.alarm));
|
||||
return Text.regexHighlighter(message,Sentinel.advConfig.allowedCharRegex," > ", " < ");
|
||||
}
|
||||
ServerUtils.verbose("Nothing caught, returning null");
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String handleSwearRegex(AsyncPlayerChatEvent e, Report report) {
|
||||
String swearRegex = Sentinel.advConfig.swearRegex;
|
||||
|
||||
Pattern pattern = Pattern.compile(swearRegex, Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(e.getMessage());
|
||||
|
||||
report.getStepsTaken().put("Anti-Swear Regex", "`%s`".formatted(e.getMessage()));
|
||||
|
||||
if (matcher.find()) {
|
||||
String highlighted = Text.regexHighlighter(swearRegex,e.getMessage()," > "," < ");
|
||||
report.getStepsTaken().replace("Anti-Swear Regex", "`%s` %s".formatted(highlighted, Emojis.alarm));
|
||||
return highlighted;
|
||||
}
|
||||
ServerUtils.verbose("Nothing caught, returning null");
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String handleStrictRegex(AsyncPlayerChatEvent e, Report report) {
|
||||
String strictRegex = Sentinel.advConfig.strictRegex;
|
||||
|
||||
Pattern pattern = Pattern.compile(strictRegex, Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(e.getMessage());
|
||||
|
||||
report.getStepsTaken().put("Strict Regex", "`%s`".formatted(e.getMessage()));
|
||||
|
||||
|
||||
|
||||
if (matcher.find()) {
|
||||
String highlighted = Text.regexHighlighter(strictRegex,e.getMessage()," > "," < ");
|
||||
report.getStepsTaken().replace("Strict Regex", "`%s` %s".formatted(highlighted, Emojis.alarm));
|
||||
return highlighted;
|
||||
}
|
||||
ServerUtils.verbose("Nothing caught, returning null");
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String handleAntiURL(AsyncPlayerChatEvent e, Report report) {
|
||||
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.getStepsTaken().put("Anti-URL", "`%s`".formatted(
|
||||
e.getMessage()
|
||||
));
|
||||
|
||||
if (matcher.find()) {
|
||||
String highlighted = Text.regexHighlighter(e.getMessage(),Sentinel.advConfig.urlRegex," > "," < ");
|
||||
ServerUtils.verbose("AdvBlocker: Caught URL: " + highlighted);
|
||||
report.getStepsTaken().replace("Anti-URL", "`%s` %s".formatted(highlighted, Emojis.alarm));
|
||||
return highlighted;
|
||||
}
|
||||
ServerUtils.verbose("Nothing caught, returning null");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package me.trouper.sentinel.server.functions.chatfilter.spam;
|
||||
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.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) {
|
||||
if (e.isCancelled()) {
|
||||
ServerUtils.verbose("Anti Spam Opening: Event is canceled.");
|
||||
}
|
||||
Player p = e.getPlayer();
|
||||
String message = Text.removeFirstColor(e.getMessage());
|
||||
int currentHeat = heatMap.getOrDefault(p.getUniqueId(),0);
|
||||
|
||||
SpamResponse response = SpamResponse.generate(e);
|
||||
lastMessageMap.put(e.getPlayer().getUniqueId(), e.getMessage());
|
||||
|
||||
int addHeat = response.getHeatAdded();
|
||||
|
||||
ServerUtils.verbose("AntiSpam responded");
|
||||
response.getReport().getStepsTaken().put("Response came back", "Heat to add: %s".formatted(addHeat));
|
||||
|
||||
if (currentHeat > Sentinel.mainConfig.chat.spamFilter.punishHeat) {
|
||||
e.setCancelled(true);
|
||||
response.getReport().getStepsTaken().put("Punished user", "Their final heat was %s".formatted(currentHeat));
|
||||
response.setPunished(true);
|
||||
SpamAction.run(response);
|
||||
heatMap.put(p.getUniqueId(), currentHeat + addHeat);
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentHeat > Sentinel.mainConfig.chat.spamFilter.blockHeat) {
|
||||
e.setCancelled(true);
|
||||
response.getReport().getStepsTaken().put("Blocked message", "Their heat is %s".formatted(currentHeat));
|
||||
SpamAction.run(response);
|
||||
heatMap.put(p.getUniqueId(), currentHeat + addHeat);
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.getSimilarity() > Sentinel.mainConfig.chat.spamFilter.blockSimilarity) {
|
||||
e.setCancelled(true);
|
||||
response.getReport().getStepsTaken().put("Blocked message", "The similarity was too high! %s".formatted(response.getSimilarity()));
|
||||
SpamAction.run(response);
|
||||
heatMap.put(p.getUniqueId(), currentHeat + addHeat);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.isCancelled()) {
|
||||
ServerUtils.verbose("Anti spam closing: Event is canceled.");
|
||||
}
|
||||
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.spamFilter.heatDecay;
|
||||
heatMap.put(p, Math.max(0, heat));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package me.trouper.sentinel.server.functions.chatfilter.spam;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordEmbed;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.FalsePositiveReporting;
|
||||
import me.trouper.sentinel.utils.trees.ConsoleFormatter;
|
||||
import me.trouper.sentinel.utils.trees.EmbedFormatter;
|
||||
import me.trouper.sentinel.utils.trees.HoverFormatter;
|
||||
import me.trouper.sentinel.utils.trees.Node;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
|
||||
public class SpamAction {
|
||||
|
||||
public static void run(SpamResponse response) {
|
||||
FalsePositiveReporting.reports.put(response.getReport().getId(),response.getReport());
|
||||
Node tree = getTree(response);
|
||||
|
||||
if (response.isPunished()) {
|
||||
punish(response);
|
||||
discordNotification(tree);
|
||||
}
|
||||
staffWarning(response,tree);
|
||||
playerWarning(response);
|
||||
consoleLog(tree);
|
||||
|
||||
}
|
||||
|
||||
public static void punish(SpamResponse response) {
|
||||
for (String spamPunishCommand : Sentinel.mainConfig.chat.spamFilter.punishCommands) {
|
||||
ServerUtils.sendCommand(spamPunishCommand.replaceAll("%player%", response.getEvent().getPlayer().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
public static void staffWarning(SpamResponse report, Node tree) {
|
||||
String messageText = Text.prefix("&b&n%s&r &7%s &8(&4%s&7/&c%s&8)".formatted(
|
||||
report.getEvent().getPlayer().getName(),
|
||||
report.isPunished() ? Sentinel.lang.violations.chat.spam.autoPunish : Sentinel.lang.violations.chat.spam.spamWarning,
|
||||
AntiSpam.heatMap.get(report.getEvent().getPlayer().getUniqueId()),
|
||||
Sentinel.mainConfig.chat.spamFilter.punishHeat
|
||||
));
|
||||
String hoverText = HoverFormatter.format(tree);
|
||||
|
||||
ServerUtils.forEachStaff(player -> player.sendMessage(Component.text(messageText).hoverEvent(Component.text(hoverText).asHoverEvent())));
|
||||
}
|
||||
|
||||
public static void playerWarning(SpamResponse response) {
|
||||
String message = Text.prefix(!response.isPunished() ? Sentinel.lang.violations.chat.spam.preventWarning : Sentinel.lang.violations.chat.spam.autoPunishWarning) ;
|
||||
String hoverText = Sentinel.lang.automatedActions.actionAutomaticReportable;
|
||||
String command = "/sentinelcallback fpreport %s".formatted(response.getReport().getId());
|
||||
response.getEvent().getPlayer().sendMessage(Component.text(message)
|
||||
.hoverEvent(Component.text(hoverText).asHoverEvent())
|
||||
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND,command)));
|
||||
}
|
||||
|
||||
public static void consoleLog(Node tree) {
|
||||
Sentinel.log.info(ConsoleFormatter.format(tree));
|
||||
}
|
||||
|
||||
public static void discordNotification(Node tree) {
|
||||
DiscordEmbed embed = EmbedFormatter.format(tree);
|
||||
EmbedFormatter.sendEmbed(embed);
|
||||
}
|
||||
|
||||
private static Node getTree(SpamResponse response) {
|
||||
Node root = new Node("Sentinel");
|
||||
root.addTextLine(Sentinel.lang.violations.chat.spam.treeTitle);
|
||||
|
||||
Node playerInfo = new Node(Sentinel.lang.violations.chat.spam.playerInfoTitle.formatted(response.getEvent().getPlayer().getName()));
|
||||
playerInfo.addKeyValue(Sentinel.lang.violations.chat.spam.uuid, response.getEvent().getPlayer().getUniqueId().toString());
|
||||
playerInfo.addKeyValue(Sentinel.lang.violations.chat.spam.heat, "%s/%s".formatted(AntiSpam.heatMap.get(response.getEvent().getPlayer().getUniqueId()),Sentinel.mainConfig.chat.spamFilter.punishHeat));
|
||||
root.addChild(playerInfo);
|
||||
|
||||
Node reportInfo = new Node(Sentinel.lang.violations.chat.spam.reportInfoTitle);
|
||||
reportInfo.addField(Sentinel.lang.violations.chat.spam.previousMessage, response.getPreviousMessage());
|
||||
reportInfo.addField(Sentinel.lang.violations.chat.spam.currentMessage, response.getCurrentMessage());
|
||||
reportInfo.addKeyValue(Sentinel.lang.violations.chat.spam.similarity, "%s/%s".formatted((int) Math.round(response.getSimilarity()),Sentinel.mainConfig.chat.spamFilter.blockSimilarity));
|
||||
root.addChild(reportInfo);
|
||||
|
||||
Node actions = new Node(Sentinel.lang.violations.chat.spam.actionTitle);
|
||||
actions.addTextLine(Sentinel.lang.violations.chat.spam.blockAction);
|
||||
if (response.isPunished()) actions.addTextLine(Sentinel.lang.violations.chat.spam.commandAction);
|
||||
root.addChild(actions);
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package me.trouper.sentinel.server.functions.chatfilter.spam;
|
||||
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.FalsePositiveReporting;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.Report;
|
||||
import me.trouper.sentinel.utils.MathUtils;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import static me.trouper.sentinel.server.functions.chatfilter.spam.AntiSpam.lastMessageMap;
|
||||
|
||||
public class SpamResponse {
|
||||
private AsyncPlayerChatEvent event;
|
||||
private String currentMessage;
|
||||
private String previousMessage;
|
||||
private double similarity;
|
||||
private int heatAdded;
|
||||
private Report report;
|
||||
private boolean punished;
|
||||
|
||||
public SpamResponse(AsyncPlayerChatEvent event, String currentMessage, String previousMessage, double similarity, int heatAdded, Report report, boolean punished) {
|
||||
this.event = event;
|
||||
this.currentMessage = currentMessage;
|
||||
this.previousMessage = previousMessage;
|
||||
this.similarity = similarity;
|
||||
this.heatAdded = heatAdded;
|
||||
this.report = report;
|
||||
this.punished = punished;
|
||||
}
|
||||
|
||||
public static SpamResponse generate(AsyncPlayerChatEvent e) {
|
||||
if (e.isCancelled()) {
|
||||
ServerUtils.verbose("Spam response opening: Event is canceled.");
|
||||
}
|
||||
Report report = FalsePositiveReporting.initializeReport(e.getMessage());
|
||||
|
||||
String message = Text.removeFirstColor(e.getMessage());
|
||||
String previousMessage = lastMessageMap.getOrDefault(e.getPlayer().getUniqueId(),"/* Placeholder Message from Sentinel */");
|
||||
|
||||
SpamResponse response = new SpamResponse(e,e.getMessage(),previousMessage,0,0,report,false);
|
||||
|
||||
|
||||
double similarity = MathUtils.calcSim(message, previousMessage);
|
||||
response.setSimilarity(similarity);
|
||||
report.getStepsTaken().put("Calculated Similarity: ","%s".formatted(similarity));
|
||||
|
||||
int addHeat = Sentinel.mainConfig.chat.spamFilter.defaultGain;
|
||||
if (similarity > Sentinel.mainConfig.chat.spamFilter.blockSimilarity) {
|
||||
addHeat = Sentinel.mainConfig.chat.spamFilter.highGain;
|
||||
response.getReport().getStepsTaken().put("Similarity is greater than %s%%".formatted(Sentinel.mainConfig.chat.spamFilter.blockSimilarity), "That is %s heat. (Auto-Block due to configured value)".formatted(addHeat));
|
||||
response.setHeatAdded(addHeat);
|
||||
return response;
|
||||
} else if (similarity > 90) {
|
||||
addHeat = Sentinel.mainConfig.chat.spamFilter.highGain;
|
||||
response.getReport().getStepsTaken().put("Similarity is greater than 90%", "That is %s heat.".formatted(addHeat));
|
||||
response.setHeatAdded(addHeat);
|
||||
return response;
|
||||
} else if (similarity > 50) {
|
||||
addHeat = Sentinel.mainConfig.chat.spamFilter.mediumGain;
|
||||
response.getReport().getStepsTaken().put("Similarity is greater than 50%", "That is %s heat.".formatted(addHeat));
|
||||
response.setHeatAdded(addHeat);
|
||||
return response;
|
||||
} else if (similarity > 25) {
|
||||
response.getReport().getStepsTaken().put("Similarity is greater than 25%", "That is %s heat.".formatted(addHeat));
|
||||
addHeat = Sentinel.mainConfig.chat.spamFilter.lowGain;
|
||||
response.setHeatAdded(addHeat);
|
||||
return response;
|
||||
}
|
||||
|
||||
report.getStepsTaken().put("Similarity is less than 25%", "That is %s heat.".formatted(addHeat));
|
||||
response.setHeatAdded(addHeat);
|
||||
if (e.isCancelled()) {
|
||||
ServerUtils.verbose("Spam Response Closing: Event is canceled.");
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
public AsyncPlayerChatEvent getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
public void setEvent(AsyncPlayerChatEvent event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public String getCurrentMessage() {
|
||||
return currentMessage;
|
||||
}
|
||||
|
||||
public void setCurrentMessage(String currentMessage) {
|
||||
this.currentMessage = currentMessage;
|
||||
}
|
||||
|
||||
public String getPreviousMessage() {
|
||||
return previousMessage;
|
||||
}
|
||||
|
||||
public void setPreviousMessage(String previousMessage) {
|
||||
this.previousMessage = previousMessage;
|
||||
}
|
||||
|
||||
public double getSimilarity() {
|
||||
return similarity;
|
||||
}
|
||||
|
||||
public void setSimilarity(double similarity) {
|
||||
this.similarity = similarity;
|
||||
}
|
||||
|
||||
public int getHeatAdded() {
|
||||
return heatAdded;
|
||||
}
|
||||
|
||||
public void setHeatAdded(int heatAdded) {
|
||||
this.heatAdded = heatAdded;
|
||||
}
|
||||
|
||||
public Report getReport() {
|
||||
return report;
|
||||
}
|
||||
|
||||
public void setReport(Report report) {
|
||||
this.report = report;
|
||||
}
|
||||
|
||||
public boolean isPunished() {
|
||||
return punished;
|
||||
}
|
||||
|
||||
public void setPunished(boolean punished) {
|
||||
this.punished = punished;
|
||||
}
|
||||
}
|
||||
38
src/main/java/me/trouper/sentinel/server/gui/ConfigGUI.java
Normal file
38
src/main/java/me/trouper/sentinel/server/gui/ConfigGUI.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package me.trouper.sentinel.server.gui;
|
||||
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import me.trouper.sentinel.server.gui.config.AntiNukeGUI;
|
||||
import me.trouper.sentinel.server.gui.config.ChatGUI;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
public class ConfigGUI {
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 Config Home"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(12, Items.ANTI_NUKE_CONFIG,e->{
|
||||
e.getWhoClicked().openInventory(new AntiNukeGUI().home.getInventory());
|
||||
})
|
||||
.define(14,Items.CHAT_CONFIG,e->{
|
||||
e.getWhoClicked().openInventory(new ChatGUI().home.getInventory());
|
||||
})
|
||||
.define(26,Items.BACK,e->{
|
||||
e.getWhoClicked().openInventory(new MainGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
MainGUI.verify((Player) e.getWhoClicked());
|
||||
}
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
}
|
||||
}
|
||||
226
src/main/java/me/trouper/sentinel/server/gui/Items.java
Normal file
226
src/main/java/me/trouper/sentinel/server/gui/Items.java
Normal file
@@ -0,0 +1,226 @@
|
||||
package me.trouper.sentinel.server.gui;
|
||||
|
||||
import io.github.itzispyder.pdk.plugin.builders.ItemBuilder;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.startup.Auth;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class Items {
|
||||
|
||||
public static final ItemStack BLANK = ItemBuilder.create()
|
||||
.material(Material.LIGHT_GRAY_STAINED_GLASS_PANE)
|
||||
.name(Text.color("&7"))
|
||||
.build();
|
||||
|
||||
public static final ItemStack GREEN = ItemBuilder.create()
|
||||
.material(Material.LIME_STAINED_GLASS_PANE)
|
||||
.name(Text.color("&7"))
|
||||
.build();
|
||||
|
||||
public static final ItemStack RED = ItemBuilder.create()
|
||||
.material(Material.RED_STAINED_GLASS_PANE)
|
||||
.name(Text.color("&7"))
|
||||
.build();
|
||||
|
||||
public static final ItemStack BACK = ItemBuilder.create()
|
||||
.material(Material.ARROW)
|
||||
.name(Text.color("&cBack"))
|
||||
.lore(Text.color("&8&l➥&7 Return to the previous page"))
|
||||
.build();
|
||||
|
||||
public static final ItemStack CREDITS = ItemBuilder.create()
|
||||
.material(Material.SHIELD)
|
||||
.name(Text.color("&6&lSentinel &8&l|&f Anti-Nuke"))
|
||||
.lore(" ")
|
||||
.lore(Text.color("&bVersion&7: &f%s".formatted(Sentinel.getInstance().getDescription().getVersion())))
|
||||
.lore(Text.color("&bLicensed to&7: &f%s".formatted(Auth.getNonce())))
|
||||
.lore(" ")
|
||||
.lore(Text.color("&e&nAuthor(s)&r&e: &e%s").formatted(Sentinel.getInstance().getDescription().getAuthors()))
|
||||
.enchant(Enchantment.PROTECTION,64)
|
||||
.flag(ItemFlag.HIDE_ENCHANTS)
|
||||
.build();
|
||||
|
||||
public static final ItemStack CONFIG = ItemBuilder.create()
|
||||
.material(Material.PISTON)
|
||||
.name(Text.color("&6&lEdit Config"))
|
||||
.lore(Text.color("&8&l➥&7 Click this if you hate JSON."))
|
||||
.enchant(Enchantment.PROTECTION,64)
|
||||
.flag(ItemFlag.HIDE_ENCHANTS)
|
||||
.build();
|
||||
|
||||
public static final ItemStack CHAT_CONFIG = ItemBuilder.create()
|
||||
.material(Material.HOPPER)
|
||||
.name(Text.color("&bChat Config"))
|
||||
.lore(Text.color("&8&l➥&7 Spam Filter"))
|
||||
.lore(Text.color("&8&l➥&7 Profanity Filter"))
|
||||
.lore(Text.color("&8&l➥&7 Regex Filters"))
|
||||
.enchant(Enchantment.PROTECTION,64)
|
||||
.flag(ItemFlag.HIDE_ENCHANTS)
|
||||
.build();
|
||||
|
||||
public static final ItemStack ANTI_NUKE_CONFIG = ItemBuilder.create()
|
||||
.material(Material.TNT)
|
||||
.name(Text.color("&cAnti-Nuke Config"))
|
||||
.lore(Text.color("&8&l➥&7 Command Block Whitelist"))
|
||||
.lore(Text.color("&8&l➥&7 Command Block editing"))
|
||||
.lore(Text.color("&8&l➥&7 Command Block placing"))
|
||||
.lore(Text.color("&8&l➥&7 Command Block using"))
|
||||
.lore(Text.color("&8&l➥&7 Command Block Minecart placing"))
|
||||
.lore(Text.color("&8&l➥&7 Command Block Minecart using"))
|
||||
.lore(Text.color("&8&l➥&7 Creative Hotbar Items"))
|
||||
.enchant(Enchantment.PROTECTION,64)
|
||||
.flag(ItemFlag.HIDE_ENCHANTS)
|
||||
.build();
|
||||
|
||||
public static ItemStack configItem(String valueName, Material material, String description) {
|
||||
ServerUtils.verbose("Items#configItem: Creating a config item:\n Value Name -> %s\nMaterial in use -> %s".formatted(valueName,material.toString()));
|
||||
|
||||
List<String> desc = Arrays.stream(description.split("\n")).toList();
|
||||
|
||||
ItemBuilder item = ItemBuilder.create();
|
||||
item.material(material);
|
||||
item.name(Text.color("&6%s".formatted(valueName)));
|
||||
for (String s : desc) {
|
||||
item.lore(Text.color("&e%s".formatted(s)));
|
||||
}
|
||||
item.lore(Text.color("&8&l➥&7 Click to set a &nnew&r&7 value."));
|
||||
item.lore(Text.color("&8&l➥&7 Current Value: &b_ORIGINAL_"));
|
||||
|
||||
return item.build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static ItemStack stringListItem(Iterable<String> values, Material material, String valueName, String description) {
|
||||
ServerUtils.verbose("Items#stringListItem: Creating a config item:\n Value Name -> %s\nMaterial in use -> %s".formatted(valueName,material.toString()));
|
||||
ItemBuilder itemBuilder = ItemBuilder.create();
|
||||
itemBuilder.material(material);
|
||||
itemBuilder.name(Text.color("&6%s".formatted(valueName)));
|
||||
List<String> desc = Arrays.stream(description.split("\n")).toList();
|
||||
for (String s : desc) {
|
||||
itemBuilder.lore(Text.color("&e%s".formatted(s)));
|
||||
}
|
||||
itemBuilder.lore(Text.color("&8&l➥&7 Left-Click to add a new value."));
|
||||
itemBuilder.lore(Text.color("&8&l➥&7 Right-Click to clear values."));
|
||||
itemBuilder.lore(Text.color("&8&l➥&7 Current Values: "));
|
||||
itemBuilder.flag(ItemFlag.HIDE_ATTRIBUTES);
|
||||
|
||||
for (String value : values) {
|
||||
itemBuilder.lore(Text.color("&9 - &b%s".formatted(value)));
|
||||
}
|
||||
|
||||
return itemBuilder.build();
|
||||
}
|
||||
|
||||
public static ItemStack stringItem(String originalValue, ItemStack originalItem) {
|
||||
ServerUtils.verbose("Items#stringItem Creating a string item:\n Value -> %s".formatted(originalValue));
|
||||
|
||||
if (originalItem == null || !originalItem.hasItemMeta()) return originalItem;
|
||||
ItemMeta meta = originalItem.getItemMeta();
|
||||
if (meta == null || !meta.hasLore()) return originalItem;
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore == null) return originalItem;
|
||||
|
||||
for (int i = 0; i < lore.size(); i++) {
|
||||
String line = lore.get(i);
|
||||
ServerUtils.verbose("Items#stringItem Looping through lore line: %s/%s".formatted(i,lore.size()));
|
||||
if (line.contains("_ORIGINAL_")) {
|
||||
try {
|
||||
ServerUtils.verbose("Items#stringItem Found a lore on line %s, making replacement value".formatted(i));
|
||||
String replace = line.replace("_ORIGINAL_", originalValue);
|
||||
ServerUtils.verbose("Items#stringItem After replacement -> %s".formatted(replace));
|
||||
lore.set(i,replace);
|
||||
ServerUtils.verbose("Items#stringItem Just replaced line %s -> %s".formatted(i,lore.get(i)));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
ServerUtils.verbose("Items#stringItem end of loop %s. continue?".formatted(i));
|
||||
}
|
||||
|
||||
ServerUtils.verbose("Items#stringItem Broke out of loop, setting the lore");
|
||||
meta.setLore(lore);
|
||||
ServerUtils.verbose("Items#stringItem Setting the meta");
|
||||
originalItem.setItemMeta(meta);
|
||||
ServerUtils.verbose("Items#stringItem Returning the item");
|
||||
return originalItem;
|
||||
}
|
||||
|
||||
public static ItemStack booleanItem(boolean originalValue, ItemStack originalItem) {
|
||||
ServerUtils.verbose("Items#booleanItem Creating a string item:\n Value -> %s".formatted(originalValue));
|
||||
|
||||
if (originalItem == null || !originalItem.hasItemMeta()) return originalItem;
|
||||
ItemMeta meta = originalItem.getItemMeta();
|
||||
if (meta == null || !meta.hasLore()) return originalItem;
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore == null) return originalItem;
|
||||
|
||||
for (int i = 0; i < lore.size(); i++) {
|
||||
String line = lore.get(i);
|
||||
ServerUtils.verbose("Items#booleanItem Looping through lore line: %s/%s".formatted(i,lore.size()));
|
||||
if (line.contains("_ORIGINAL_")) {
|
||||
try {
|
||||
ServerUtils.verbose("Items#booleanItem Found a lore on line %s, making replacement value".formatted(i));
|
||||
String replace = line.replace("_ORIGINAL_", "" + originalValue);
|
||||
ServerUtils.verbose("Items#booleanItem After replacement -> %s".formatted(replace));
|
||||
lore.set(i,replace);
|
||||
ServerUtils.verbose("Items#booleanItem Just replaced line %s -> %s".formatted(i,lore.get(i)));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
ServerUtils.verbose("Items#booleanItem end of loop %s. continue?".formatted(i));
|
||||
}
|
||||
|
||||
ServerUtils.verbose("Items#booleanItem Broke out of loop, setting the lore");
|
||||
meta.setLore(lore);
|
||||
ServerUtils.verbose("Items#booleanItem Setting the meta");
|
||||
originalItem.setItemMeta(meta);
|
||||
ServerUtils.verbose("Items#booleanItem Returning the item");
|
||||
return originalItem;
|
||||
}
|
||||
|
||||
public static ItemStack intItem(int originalValue, ItemStack originalItem) {
|
||||
ServerUtils.verbose("Items#intitem Creating a string item:\n Value -> %s".formatted(originalValue));
|
||||
|
||||
if (originalItem == null || !originalItem.hasItemMeta()) return originalItem;
|
||||
ItemMeta meta = originalItem.getItemMeta();
|
||||
if (meta == null || !meta.hasLore()) return originalItem;
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore == null) return originalItem;
|
||||
|
||||
for (int i = 0; i < lore.size(); i++) {
|
||||
String line = lore.get(i);
|
||||
ServerUtils.verbose("Items#intitem Looping through lore line: %s/%s".formatted(i,lore.size()));
|
||||
if (line.contains("_ORIGINAL_")) {
|
||||
try {
|
||||
ServerUtils.verbose("Items#intitem Found a lore on line %s, making replacement value".formatted(i));
|
||||
String replace = line.replace("_ORIGINAL_", "" + originalValue);
|
||||
ServerUtils.verbose("Items#intitem After replacement -> %s".formatted(replace));
|
||||
lore.set(i,replace);
|
||||
ServerUtils.verbose("Items#intitem Just replaced line %s -> %s".formatted(i,lore.get(i)));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
ServerUtils.verbose("Items#intitem end of loop %s. continue?".formatted(i));
|
||||
}
|
||||
|
||||
ServerUtils.verbose("Items#intitem Broke out of loop, setting the lore");
|
||||
meta.setLore(lore);
|
||||
ServerUtils.verbose("Items#intitem Setting the meta");
|
||||
originalItem.setItemMeta(meta);
|
||||
ServerUtils.verbose("Items#intitem Returning the item");
|
||||
return originalItem;
|
||||
}
|
||||
}
|
||||
50
src/main/java/me/trouper/sentinel/server/gui/MainGUI.java
Normal file
50
src/main/java/me/trouper/sentinel/server/gui/MainGUI.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package me.trouper.sentinel.server.gui;
|
||||
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.utils.PlayerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MainGUI {
|
||||
|
||||
public static Set<UUID> awaitingCallback = new HashSet<>();
|
||||
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 Home"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(12,Items.CREDITS)
|
||||
.define(14,Items.CONFIG,this::openConfig)
|
||||
.build();
|
||||
|
||||
private void openConfig(InventoryClickEvent e) {
|
||||
e.getWhoClicked().openInventory(new ConfigGUI().home.getInventory());
|
||||
}
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
verify((Player) e.getWhoClicked());
|
||||
}
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean verify(Player p) {
|
||||
if (PlayerUtils.isTrusted(p)) return true;
|
||||
Sentinel.log.info("WARNING: %s has just attempted to use the GUI without authorization. This has been prevented by Sentinel, as we are NOT Vulcan AntiCheat.");
|
||||
p.closeInventory();
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package me.trouper.sentinel.server.gui.config;
|
||||
|
||||
import io.github.itzispyder.pdk.plugin.builders.ItemBuilder;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import me.trouper.sentinel.server.gui.ConfigGUI;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.nuke.CommandGUI;
|
||||
import me.trouper.sentinel.server.gui.config.nuke.checks.*;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class AntiNukeGUI {
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 Choose a check"))
|
||||
.size(54)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(53, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new ConfigGUI().home.getInventory());
|
||||
})
|
||||
.define(10,COMMAND_BLOCK_WHITELIST, e->{
|
||||
e.getWhoClicked().openInventory(new CBExecuteGUI().home.getInventory());
|
||||
})
|
||||
.define(12,COMMAND_BLOCK_PLACE, e->{
|
||||
e.getWhoClicked().openInventory(new CBPlaceGUI().home.getInventory());
|
||||
})
|
||||
.define(14,COMMAND_BLOCK_USE, e->{
|
||||
e.getWhoClicked().openInventory(new CBUseGUI().home.getInventory());
|
||||
})
|
||||
.define(16,COMMAND_BLOCK_EDITING, e->{
|
||||
e.getWhoClicked().openInventory(new CBEditGUI().home.getInventory());
|
||||
})
|
||||
.define(37,COMMAND_BLOCK_MINECART_USE, e->{
|
||||
e.getWhoClicked().openInventory(new CBMCUseGUI().home.getInventory());
|
||||
})
|
||||
.define(39,COMMAND_BLOCK_MINECART_PLACE, e->{
|
||||
e.getWhoClicked().openInventory(new CBMCPlaceGUI().home.getInventory());
|
||||
})
|
||||
.define(41,COMMAND_EXECUTE, e->{
|
||||
e.getWhoClicked().openInventory(new CommandGUI().home.getInventory());
|
||||
})
|
||||
.define(43,HOTBAR_ACTION, e->{
|
||||
e.getWhoClicked().openInventory(new HotbarActionGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
MainGUI.verify((Player) e.getWhoClicked());
|
||||
}
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
}
|
||||
|
||||
private static final ItemStack COMMAND_BLOCK_EDITING = ItemBuilder.create()
|
||||
.material(Material.DEBUG_STICK)
|
||||
.name(Text.color("&bCommand Block Editing"))
|
||||
.lore(Text.color("&8&l➥&7 Modify this check"))
|
||||
.build();
|
||||
|
||||
private static final ItemStack COMMAND_BLOCK_WHITELIST = ItemBuilder.create()
|
||||
.material(Material.EMERALD)
|
||||
.name(Text.color("&bCommand Block Whitelist"))
|
||||
.lore(Text.color("&8&l➥&7 Modify this check"))
|
||||
.build();
|
||||
|
||||
private static final ItemStack COMMAND_BLOCK_MINECART_PLACE = ItemBuilder.create()
|
||||
.material(Material.RAIL)
|
||||
.name(Text.color("&bCommand Block Minecart Placing"))
|
||||
.lore(Text.color("&8&l➥&7 Modify this check"))
|
||||
.build();
|
||||
|
||||
private static final ItemStack COMMAND_BLOCK_MINECART_USE = ItemBuilder.create()
|
||||
.material(Material.COMMAND_BLOCK_MINECART)
|
||||
.name(Text.color("&bCommand Block Minecart Using"))
|
||||
.lore(Text.color("&8&l➥&7 Modify this check"))
|
||||
.build();
|
||||
|
||||
private static final ItemStack COMMAND_BLOCK_PLACE = ItemBuilder.create()
|
||||
.material(Material.CHAIN_COMMAND_BLOCK)
|
||||
.name(Text.color("&bCommand Block Placing"))
|
||||
.lore(Text.color("&8&l➥&7 Modify this check"))
|
||||
.build();
|
||||
|
||||
private static final ItemStack COMMAND_BLOCK_USE = ItemBuilder.create()
|
||||
.material(Material.REPEATING_COMMAND_BLOCK)
|
||||
.name(Text.color("&bCommand Block Using"))
|
||||
.lore(Text.color("&8&l➥&7 Modify this check"))
|
||||
.build();
|
||||
|
||||
private static final ItemStack COMMAND_EXECUTE = ItemBuilder.create()
|
||||
.material(Material.SPYGLASS)
|
||||
.name(Text.color("&bCommand Execution"))
|
||||
.lore(Text.color("&8&l➥&7 Dangerous Commands"))
|
||||
.lore(Text.color("&8&l➥&7 Logged Commands"))
|
||||
.lore(Text.color("&8&l➥&7 Specific Commands"))
|
||||
.build();
|
||||
|
||||
private static final ItemStack HOTBAR_ACTION = ItemBuilder.create()
|
||||
.material(Material.DIAMOND_SWORD)
|
||||
.name(Text.color("&bNBT Items"))
|
||||
.lore(Text.color("&8&l➥&7 Modify this check"))
|
||||
.build();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package me.trouper.sentinel.server.gui.config;
|
||||
|
||||
import io.github.itzispyder.pdk.plugin.builders.ItemBuilder;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import me.trouper.sentinel.server.gui.ConfigGUI;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.chat.ProfanityFilterGUI;
|
||||
import me.trouper.sentinel.server.gui.config.chat.RegexFilterGUI;
|
||||
import me.trouper.sentinel.server.gui.config.chat.SpamFilterGUI;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class ChatGUI {
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 Edit a Filter"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(11,REGEX_FILTERS,e->{
|
||||
ServerUtils.verbose("ChatGUI#home Redirecting to RegexFilterGUI");
|
||||
e.getWhoClicked().openInventory(new RegexFilterGUI().home.getInventory());
|
||||
})
|
||||
.define(13,PROFANITY_FILTER,e->{
|
||||
e.getWhoClicked().openInventory(new ProfanityFilterGUI().home.getInventory());
|
||||
})
|
||||
.define(15,SPAM_FILTER,e->{
|
||||
e.getWhoClicked().openInventory(new SpamFilterGUI().home.getInventory());
|
||||
})
|
||||
.define(26,Items.BACK,e->{
|
||||
e.getWhoClicked().openInventory(new ConfigGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
MainGUI.verify((Player) e.getWhoClicked());
|
||||
}
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
}
|
||||
|
||||
private static final ItemStack PROFANITY_FILTER = ItemBuilder.create()
|
||||
.material(Material.COAL)
|
||||
.name(Text.color("&bProfanity Filter"))
|
||||
.lore(Text.color("&8&l➥&7 Edit Score Settings"))
|
||||
.build();
|
||||
|
||||
private static final ItemStack SPAM_FILTER = ItemBuilder.create()
|
||||
.material(Material.PORKCHOP)
|
||||
.name(Text.color("&bSpam Filter"))
|
||||
.lore(Text.color("&8&l➥&7 Edit Heat Settings"))
|
||||
.build();
|
||||
|
||||
private static final ItemStack REGEX_FILTERS = ItemBuilder.create()
|
||||
.material(Material.DISPENSER)
|
||||
.name(Text.color("&bRegex Filters"))
|
||||
.lore(Text.color("&8&l➥&7 URL Blocker"))
|
||||
.lore(Text.color("&8&l➥&7 Unicode Whitelist"))
|
||||
.lore(Text.color("&8&l➥&7 Swear Regex"))
|
||||
.lore(Text.color("&8&l➥&7 Spam Regex"))
|
||||
.lore(Text.color("&8&l➥&7 False Positive Regex"))
|
||||
.build();
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package me.trouper.sentinel.server.gui.config.chat;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import io.github.itzispyder.pdk.utils.misc.config.ConfigUpdater;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.config.MainConfig;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.ChatGUI;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class ProfanityFilterGUI {
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 Editing Profanity Filter"))
|
||||
.size(54)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(53, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new ChatGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
try {
|
||||
ServerUtils.verbose("ProfanityFilterGUI#blankPage Starting");
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
ServerUtils.verbose("ProfanityFilterGUI#blankPage Page now blank");
|
||||
ItemStack top = Items.RED;
|
||||
if (Sentinel.mainConfig.chat.swearFilter.enabled) {
|
||||
top = Items.GREEN;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
inv.setItem(i,top);
|
||||
}
|
||||
ServerUtils.verbose("ProfanityFilterGUI#blankPage Adding GUI Items");
|
||||
|
||||
inv.setItem(53,Items.BACK);
|
||||
inv.setItem(4,Items.booleanItem(Sentinel.mainConfig.chat.swearFilter.enabled, Items.configItem("Profanity Filter Toggle",Material.CLOCK,"Enable or Disable the whole Profanity filter")));
|
||||
inv.setItem(10,Items.intItem(Sentinel.mainConfig.chat.swearFilter.lowScore, Items.configItem("Low Score Gain", Material.WHITE_WOOL, "How much score will be added if the player \ndid not attempt to bypass the filter.")));
|
||||
inv.setItem(19,Items.intItem(Sentinel.mainConfig.chat.swearFilter.mediumLowScore, Items.configItem("Medium-Low Score Gain", Material.LIME_WOOL, "How much score will be added if the player \nused l33t speak to attempt a bypass")));
|
||||
inv.setItem(28,Items.intItem(Sentinel.mainConfig.chat.swearFilter.mediumScore, Items.configItem("Medium Score Gain", Material.YELLOW_WOOL, "How much score will be added if the player \nused sp/ecia|l characters to attempt a bypass")));
|
||||
inv.setItem(37,Items.intItem(Sentinel.mainConfig.chat.swearFilter.mediumHighScore, Items.configItem("Medium-High Score Gain", Material.ORANGE_WOOL, "How much score will be added if the player \nused reeeeeeepeating letters to attempt a bypass")));
|
||||
inv.setItem(46,Items.intItem(Sentinel.mainConfig.chat.swearFilter.highScore, Items.configItem("High Score Gain", Material.RED_WOOL, "How much score will be added if the player \nused pun. ctua, tion or spaces to attempt a bypass")));
|
||||
inv.setItem(29,Items.intItem(Sentinel.mainConfig.chat.swearFilter.regexScore, Items.configItem("Regex Score Gain", Material.DISPENSER, "How much score will be added if the player \nmatched the regex setting throughout \nthe processing of the message")));
|
||||
inv.setItem(22,Items.intItem(Sentinel.mainConfig.chat.swearFilter.punishScore, Items.configItem("Punish Score", Material.IRON_BARS, "If the player's score is above this \nthe punishment commands will be ran.")));
|
||||
inv.setItem(33,Items.intItem(Sentinel.mainConfig.chat.swearFilter.scoreDecay, Items.configItem("Score Decay", Material.DEAD_BUBBLE_CORAL_BLOCK, "How much score players will loose each minute.")));
|
||||
inv.setItem(31,Items.stringListItem(Sentinel.mainConfig.chat.swearFilter.swearPunishCommands,Material.WOODEN_AXE, "Default Punishment Commands", "%player% will be replaced with the offender's name"));
|
||||
inv.setItem(40,Items.stringListItem(Sentinel.mainConfig.chat.swearFilter.strictPunishCommands,Material.DIAMOND_AXE, "Strict Punishment Commands", "If words from the strict words list are flagged, \nthis list will be ran instead \n%player% will be replaced with the offender's name"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
if (!MainGUI.verify((Player) e.getWhoClicked())) return;
|
||||
switch (e.getSlot()) {
|
||||
case 4 -> {
|
||||
Sentinel.mainConfig.chat.swearFilter.enabled = !Sentinel.mainConfig.chat.swearFilter.enabled;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.mainConfig.save();
|
||||
}
|
||||
|
||||
case 10 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.swearFilter.lowScore = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.swearFilter.lowScore);
|
||||
case 19 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.swearFilter.mediumLowScore = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.swearFilter.mediumLowScore);
|
||||
case 28 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.swearFilter.mediumScore = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.swearFilter.mediumScore);
|
||||
case 37 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.swearFilter.mediumHighScore = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.swearFilter.mediumHighScore);
|
||||
case 46 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.swearFilter.highScore = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.swearFilter.highScore);
|
||||
case 29 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.swearFilter.regexScore = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.swearFilter.regexScore);
|
||||
case 22 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.swearFilter.punishScore = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.swearFilter.punishScore);
|
||||
case 33 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.swearFilter.scoreDecay = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.swearFilter.scoreDecay);
|
||||
|
||||
case 31 -> {
|
||||
if (e.isLeftClick()) {
|
||||
queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> {
|
||||
cfg.chat.swearFilter.swearPunishCommands.add(args.getAll().toString());
|
||||
},"" + Sentinel.mainConfig.chat.swearFilter.swearPunishCommands);
|
||||
return;
|
||||
}
|
||||
Sentinel.mainConfig.chat.swearFilter.swearPunishCommands.clear();
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.mainConfig.save();
|
||||
|
||||
}
|
||||
case 40 -> {
|
||||
if (e.isLeftClick()) {
|
||||
queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> {
|
||||
cfg.chat.swearFilter.strictPunishCommands.add(args.getAll().toString());
|
||||
},"" + Sentinel.mainConfig.chat.swearFilter.strictPunishCommands);
|
||||
return;
|
||||
}
|
||||
Sentinel.mainConfig.chat.swearFilter.strictPunishCommands.clear();
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.mainConfig.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ConfigUpdater<AsyncPlayerChatEvent, MainConfig> updater = new ConfigUpdater<>(Sentinel.mainConfig);
|
||||
|
||||
private void queuePlayer(Player player, BiConsumer<MainConfig, Args> action, String currentValue) {
|
||||
MainGUI.awaitingCallback.add(player.getUniqueId());
|
||||
player.closeInventory();
|
||||
updater.queuePlayer(player, 20*60, (e)->{
|
||||
e.setCancelled(true);
|
||||
ServerUtils.verbose("Supplying the message: \"%s\". Canceled? %s".formatted(e.getMessage(),e.isCancelled()));
|
||||
return e.getMessage();
|
||||
}, (cfg, newValue) -> {
|
||||
action.accept(cfg,new Args(newValue.split("\\s+")));
|
||||
cfg.save();
|
||||
player.sendMessage(Text.prefix("Value updated successfully"));
|
||||
player.openInventory(home.getInventory());
|
||||
});
|
||||
player.sendMessage(Component.text(Text.prefix("Enter the new value in chat. The value is currently set to &b%s&7. (Click to insert)".formatted(currentValue))).clickEvent(ClickEvent.suggestCommand(currentValue)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package me.trouper.sentinel.server.gui.config.chat;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.events.CustomListener;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import io.github.itzispyder.pdk.utils.SchedulerUtils;
|
||||
import io.github.itzispyder.pdk.utils.misc.config.ConfigUpdater;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.config.AdvancedConfig;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.ChatGUI;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class RegexFilterGUI implements CustomListener {
|
||||
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 Edit a Chat Filter"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(26, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new ChatGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
|
||||
inv.setItem(26,Items.BACK);
|
||||
ServerUtils.verbose("RegexFilterGUI#blankPage Setting up page");
|
||||
inv.setItem(11, Items.stringItem(Sentinel.advConfig.allowedCharRegex, Items.configItem("Unicode Whitelist", Material.FEATHER, "The regex defining what characters \nare allowed to be used in chat.")));
|
||||
ServerUtils.verbose("RegexFilterGUI#blankPage Finished with Unicode Whitelist");
|
||||
inv.setItem(12, Items.stringItem(Sentinel.advConfig.falsePosRegex, Items.configItem("False Positive Regex", Material.EMERALD, "This regex will be replaced with \nan empty string before profanity filter \nprocessing begins.")));
|
||||
ServerUtils.verbose("RegexFilterGUI#blankPage Finished with False Positive Regex");
|
||||
inv.setItem(13, Items.stringItem(Sentinel.advConfig.swearRegex, Items.configItem("Swear Regex", Material.ROTTEN_FLESH, "If anything matches to this regex, \nthe profanity filter will immediately flag it.")));
|
||||
ServerUtils.verbose("RegexFilterGUI#blankPage Finished with Swear Regex");
|
||||
inv.setItem(14, Items.stringItem(Sentinel.advConfig.strictRegex, Items.configItem("Strict Regex", Material.LEAD, "If anything matches to this regex, the profanity \nfilter will immediately flag it as a slur.")));
|
||||
ServerUtils.verbose("RegexFilterGUI#blankPage Finished with Strict Regex");
|
||||
inv.setItem(15, Items.stringItem(Sentinel.advConfig.urlRegex, Items.configItem("URL Blocker", Material.CHAIN, "If anything matches to this regex, it will get \nflagged as a URL.")));
|
||||
ServerUtils.verbose("RegexFilterGUI#blankPage Done Setting up page (Finished URL Blocker)");
|
||||
}
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
if (!MainGUI.verify((Player) e.getWhoClicked())) return;
|
||||
SchedulerUtils.later(0,()->{
|
||||
switch (e.getSlot()) {
|
||||
case 11 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.allowedCharRegex = args.getAll().toString(),Sentinel.advConfig.allowedCharRegex);
|
||||
case 12 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.falsePosRegex = args.getAll().toString(),Sentinel.advConfig.falsePosRegex);
|
||||
case 13 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.swearRegex = args.getAll().toString(),Sentinel.advConfig.swearRegex);
|
||||
case 14 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.strictRegex = args.getAll().toString(),Sentinel.advConfig.strictRegex);
|
||||
case 15 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.urlRegex = args.getAll().toString(),Sentinel.advConfig.urlRegex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static ConfigUpdater<AsyncPlayerChatEvent, AdvancedConfig> updater = new ConfigUpdater<>(Sentinel.advConfig);
|
||||
|
||||
private void queuePlayer(Player player, BiConsumer<AdvancedConfig, Args> action, String currentValue) {
|
||||
MainGUI.awaitingCallback.add(player.getUniqueId());
|
||||
player.closeInventory();
|
||||
updater.queuePlayer(player, 20*60, (e)->{
|
||||
e.setCancelled(true);
|
||||
ServerUtils.verbose("Supplying the message: \"%s\". Canceled? %s".formatted(e.getMessage(),e.isCancelled()));
|
||||
return e.getMessage();
|
||||
}, (cfg, newValue) -> {
|
||||
action.accept(cfg,new Args(newValue.split("\\s+")));
|
||||
cfg.save();
|
||||
player.sendMessage(Text.prefix("Value updated successfully"));
|
||||
player.openInventory(home.getInventory());
|
||||
});
|
||||
player.sendMessage(Component.text(Text.prefix("Enter the new value in chat. The value is currently set to &b%s&7. (Click to insert)".formatted(currentValue))).clickEvent(ClickEvent.suggestCommand(currentValue)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package me.trouper.sentinel.server.gui.config.chat;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import io.github.itzispyder.pdk.utils.misc.config.ConfigUpdater;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.config.MainConfig;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.ChatGUI;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class SpamFilterGUI {
|
||||
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 Editing Spam Filter"))
|
||||
.size(54)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(53, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new ChatGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
|
||||
ItemStack top = Items.RED;
|
||||
if (Sentinel.mainConfig.chat.spamFilter.enabled) {
|
||||
top = Items.GREEN;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
inv.setItem(i,top);
|
||||
}
|
||||
|
||||
inv.setItem(53,Items.BACK);
|
||||
inv.setItem(4,Items.booleanItem(Sentinel.mainConfig.chat.spamFilter.enabled, Items.configItem("Spam Filter Toggle", Material.CLOCK, "Enable or disable the whole Spam Filter")));
|
||||
inv.setItem(10,Items.intItem(Sentinel.mainConfig.chat.spamFilter.defaultGain, Items.configItem("Default Heat Gain", Material.BUCKET, "How much heat will be added to each message.")));
|
||||
inv.setItem(19,Items.intItem(Sentinel.mainConfig.chat.spamFilter.lowGain, Items.configItem("Low Heat Gain", Material.WATER_BUCKET, "Extra heat to be added if the \nmessage is greater than 25% similar \nto their previous message.")));
|
||||
inv.setItem(28,Items.intItem(Sentinel.mainConfig.chat.spamFilter.mediumGain, Items.configItem("Medium Heat Gain", Material.COD_BUCKET, "Extra heat to be added if the \nmessage is greater than 50% similar \nto their previous message.")));
|
||||
inv.setItem(37,Items.intItem(Sentinel.mainConfig.chat.spamFilter.highGain, Items.configItem("High Heat Gain", Material.PUFFERFISH_BUCKET, "Extra heat to be added if the \nmessage is greater than 90% similar \nto their previous message.")));
|
||||
inv.setItem(46,Items.intItem(Sentinel.mainConfig.chat.spamFilter.blockHeat, Items.configItem("Block Heat", Material.BARRIER, "If the player's heat is above this \nthen their message will be blocked and \nflagged as spam.")));
|
||||
inv.setItem(21,Items.intItem(Sentinel.mainConfig.chat.spamFilter.blockSimilarity, Items.configItem("Block Similarity", Material.BARRIER, "If the message's similarity is above \nthis, it will get automatically blocked \nand flagged as spam.")));
|
||||
inv.setItem(23,Items.intItem(Sentinel.mainConfig.chat.spamFilter.punishHeat, Items.configItem("Punish Heat", Material.IRON_BARS, "If the player's heat is above this \nthe punishment commands will be ran.")));
|
||||
inv.setItem(25,Items.intItem(Sentinel.mainConfig.chat.spamFilter.heatDecay, Items.configItem("Heat Decay", Material.DEAD_BUBBLE_CORAL_BLOCK, "How much heat players will loose each second.")));
|
||||
inv.setItem(32,Items.stringListItem(Sentinel.mainConfig.chat.spamFilter.punishCommands,Material.DIAMOND_AXE, "Punishment Commands", "%player% will be replaced with the offender's name"));
|
||||
}
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
if (!MainGUI.verify((Player) e.getWhoClicked())) return;
|
||||
blankPage(e.getInventory());
|
||||
|
||||
switch (e.getSlot()) {
|
||||
case 4 -> {
|
||||
Sentinel.mainConfig.chat.spamFilter.enabled = !Sentinel.mainConfig.chat.spamFilter.enabled;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.mainConfig.save();
|
||||
}
|
||||
|
||||
case 10 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.spamFilter.defaultGain = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.spamFilter.defaultGain);
|
||||
case 19 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.spamFilter.lowGain = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.spamFilter.lowGain);
|
||||
case 28 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.spamFilter.mediumGain = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.spamFilter.mediumGain);
|
||||
case 37 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.spamFilter.highGain = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.spamFilter.highGain);
|
||||
case 46 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.spamFilter.blockHeat = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.spamFilter.blockHeat);
|
||||
case 21 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.spamFilter.blockSimilarity = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.spamFilter.blockSimilarity);
|
||||
case 23 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.spamFilter.punishHeat = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.spamFilter.punishHeat);
|
||||
case 25 -> queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> cfg.chat.spamFilter.heatDecay = args.getAll().toInt(),"" + Sentinel.mainConfig.chat.spamFilter.heatDecay);
|
||||
|
||||
case 32 -> {
|
||||
if (e.isLeftClick()) {
|
||||
queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> {
|
||||
cfg.chat.spamFilter.punishCommands.add(args.getAll().toString());
|
||||
},"" + Sentinel.mainConfig.chat.spamFilter.punishCommands);
|
||||
return;
|
||||
}
|
||||
Sentinel.mainConfig.chat.spamFilter.punishCommands.clear();
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.mainConfig.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ConfigUpdater<AsyncPlayerChatEvent, MainConfig> updater = new ConfigUpdater<>(Sentinel.mainConfig);
|
||||
|
||||
private void queuePlayer(Player player, BiConsumer<MainConfig, Args> action, String currentValue) {
|
||||
MainGUI.awaitingCallback.add(player.getUniqueId());
|
||||
player.closeInventory();
|
||||
updater.queuePlayer(player, 20*60, (e)->{
|
||||
e.setCancelled(true);
|
||||
ServerUtils.verbose("Supplying the message: \"%s\". Canceled? %s".formatted(e.getMessage(),e.isCancelled()));
|
||||
return e.getMessage();
|
||||
}, (cfg, newValue) -> {
|
||||
action.accept(cfg,new Args(newValue.split("\\s+")));
|
||||
cfg.save();
|
||||
player.sendMessage(Text.prefix("Value updated successfully"));
|
||||
player.openInventory(home.getInventory());
|
||||
});
|
||||
player.sendMessage(Component.text(Text.prefix("Enter the new value in chat. The value is currently set to &b%s&7. (Click to insert)".formatted(currentValue))).clickEvent(ClickEvent.suggestCommand(currentValue)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package me.trouper.sentinel.server.gui.config.nuke;
|
||||
|
||||
import io.github.itzispyder.pdk.plugin.builders.ItemBuilder;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.AntiNukeGUI;
|
||||
import me.trouper.sentinel.server.gui.config.nuke.checks.command.DangerousCMDGUI;
|
||||
import me.trouper.sentinel.server.gui.config.nuke.checks.command.LoggedCMDGUI;
|
||||
import me.trouper.sentinel.server.gui.config.nuke.checks.command.SpecificCMDGUI;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class CommandGUI {
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 Choose a check"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(26, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new AntiNukeGUI().home.getInventory());
|
||||
})
|
||||
.define(11,SPECIFIC, e->{
|
||||
e.getWhoClicked().openInventory(new SpecificCMDGUI().home.getInventory());
|
||||
})
|
||||
.define(13,LOGGED, e->{
|
||||
e.getWhoClicked().openInventory(new LoggedCMDGUI().home.getInventory());
|
||||
})
|
||||
.define(15,DANGEROUS, e->{
|
||||
e.getWhoClicked().openInventory(new DangerousCMDGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
MainGUI.verify((Player) e.getWhoClicked());
|
||||
}
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
}
|
||||
|
||||
private static final ItemStack SPECIFIC = ItemBuilder.create()
|
||||
.material(Material.SPECTRAL_ARROW)
|
||||
.name(Text.color("&bSpecific Commands"))
|
||||
.lore(Text.color("&8&l➥&7 Modify this check"))
|
||||
.build();
|
||||
|
||||
private static final ItemStack LOGGED = ItemBuilder.create()
|
||||
.material(Material.SPYGLASS)
|
||||
.name(Text.color("&bLogged Commands"))
|
||||
.lore(Text.color("&8&l➥&7 Modify this check"))
|
||||
|
||||
.build();
|
||||
|
||||
private static final ItemStack DANGEROUS = ItemBuilder.create()
|
||||
.material(Material.TNT)
|
||||
.name(Text.color("&bDangerous Commands"))
|
||||
.lore(Text.color("&8&l➥&7 Modify this check"))
|
||||
.build();
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package me.trouper.sentinel.server.gui.config.nuke.checks;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import io.github.itzispyder.pdk.utils.misc.config.ConfigUpdater;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.config.ViolationConfig;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.AntiNukeGUI;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class CBEditGUI {
|
||||
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 CB Edit Check"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(26, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new AntiNukeGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
|
||||
ItemStack ring = Items.RED;
|
||||
if (Sentinel.violationConfig.commandBlockEdit.enabled) {
|
||||
ring = Items.GREEN;
|
||||
}
|
||||
|
||||
List<Integer> ringList = List.of(3,4,5,12,14,21,22,23);
|
||||
|
||||
for (Integer i : ringList) {
|
||||
inv.setItem(i,ring);
|
||||
}
|
||||
|
||||
inv.setItem(26,Items.BACK);
|
||||
inv.setItem(13,Items.booleanItem(Sentinel.violationConfig.commandBlockEdit.enabled,Items.configItem("Check Toggle",Material.CLOCK,"Enable/Disable this check entirely")));
|
||||
inv.setItem(2,Items.booleanItem(Sentinel.violationConfig.commandBlockEdit.deop,Items.configItem("De-Op",Material.END_CRYSTAL,"Remove the user's operator privileges")));
|
||||
inv.setItem(20,Items.booleanItem(Sentinel.violationConfig.commandBlockEdit.logToDiscord,Items.configItem("Log",Material.OAK_LOG,"If this check will produce a log to discord")));
|
||||
inv.setItem(6,Items.booleanItem(Sentinel.violationConfig.commandBlockEdit.punish,Items.configItem("Punish",Material.REDSTONE_TORCH,"Run the punishment commands")));
|
||||
inv.setItem(24,Items.stringListItem(Sentinel.violationConfig.commandBlockEdit.punishmentCommands,Material.DIAMOND_AXE,"Punishment Commands","Commands that will be ran \nif this check is flagged."));
|
||||
}
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
if (!MainGUI.verify((Player) e.getWhoClicked())) return;
|
||||
switch (e.getSlot()) {
|
||||
case 13 -> {
|
||||
Sentinel.violationConfig.commandBlockEdit.enabled = !Sentinel.violationConfig.commandBlockEdit.enabled;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 2 -> {
|
||||
Sentinel.violationConfig.commandBlockEdit.deop = !Sentinel.violationConfig.commandBlockEdit.deop;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 20 -> {
|
||||
Sentinel.violationConfig.commandBlockEdit.logToDiscord = !Sentinel.violationConfig.commandBlockEdit.logToDiscord;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 6 -> {
|
||||
Sentinel.violationConfig.commandBlockEdit.punish = !Sentinel.violationConfig.commandBlockEdit.punish;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
case 24 -> {
|
||||
if (e.isLeftClick()) {
|
||||
queuePlayer((Player) e.getWhoClicked(), (cfg, args) -> {
|
||||
cfg.commandBlockEdit.punishmentCommands.add(args.getAll().toString());
|
||||
},"" + Sentinel.violationConfig.commandBlockEdit.punishmentCommands);
|
||||
return;
|
||||
}
|
||||
Sentinel.violationConfig.commandBlockEdit.punishmentCommands.clear();
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static ConfigUpdater<AsyncPlayerChatEvent, ViolationConfig> updater = new ConfigUpdater<>(Sentinel.violationConfig);
|
||||
private void queuePlayer(Player player, BiConsumer<ViolationConfig, Args> action, String currentValue) {
|
||||
MainGUI.awaitingCallback.add(player.getUniqueId());
|
||||
player.closeInventory();
|
||||
updater.queuePlayer(player, 20*60, (e)->{
|
||||
e.setCancelled(true);
|
||||
ServerUtils.verbose("Supplying the message: \"%s\". Canceled? %s".formatted(e.getMessage(),e.isCancelled()));
|
||||
return e.getMessage();
|
||||
}, (cfg, newValue) -> {
|
||||
action.accept(cfg,new Args(newValue.split("\\s+")));
|
||||
cfg.save();
|
||||
player.sendMessage(Text.prefix("Value updated successfully"));
|
||||
player.openInventory(home.getInventory());
|
||||
});
|
||||
player.sendMessage(Component.text(Text.prefix("Enter the new value in chat. The value is currently set to &b%s&7. (Click to insert)".formatted(currentValue))).clickEvent(ClickEvent.suggestCommand(currentValue)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package me.trouper.sentinel.server.gui.config.nuke.checks;
|
||||
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.AntiNukeGUI;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class CBExecuteGUI {
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 CB Whitelist"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(26, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new AntiNukeGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
|
||||
ItemStack top = Items.RED;
|
||||
if (Sentinel.violationConfig.commandBlockExecute.enabled) {
|
||||
top = Items.GREEN;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
inv.setItem(i,top);
|
||||
}
|
||||
|
||||
inv.setItem(26,Items.BACK);
|
||||
inv.setItem(4,Items.booleanItem(Sentinel.violationConfig.commandBlockExecute.enabled,Items.configItem("Check Toggle", Material.CLOCK,"Enable/Disable this check entirely")));
|
||||
inv.setItem(11,Items.booleanItem(Sentinel.violationConfig.commandBlockExecute.destroyBlock,Items.configItem("Destroy",Material.NETHERITE_PICKAXE,"Destroy the offending command-block")));
|
||||
inv.setItem(13,Items.booleanItem(Sentinel.violationConfig.commandBlockExecute.attemptRestore,Items.configItem("Restore",Material.COMMAND_BLOCK,"Attempt to restore the block if a \nwhitelisted one exists at the location")));
|
||||
inv.setItem(15,Items.booleanItem(Sentinel.violationConfig.commandBlockExecute.logToDiscord,Items.configItem("Log",Material.OAK_LOG,"If this check will produce a log to discord")));
|
||||
}
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
if (!MainGUI.verify((Player) e.getWhoClicked())) return;
|
||||
switch (e.getSlot()) {
|
||||
case 4 -> {
|
||||
Sentinel.violationConfig.commandBlockExecute.enabled = !Sentinel.violationConfig.commandBlockExecute.enabled;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 11 -> {
|
||||
Sentinel.violationConfig.commandBlockExecute.destroyBlock = !Sentinel.violationConfig.commandBlockExecute.destroyBlock;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 13 -> {
|
||||
Sentinel.violationConfig.commandBlockExecute.attemptRestore = !Sentinel.violationConfig.commandBlockExecute.attemptRestore;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 15 -> {
|
||||
Sentinel.violationConfig.commandBlockExecute.logToDiscord = !Sentinel.violationConfig.commandBlockExecute.logToDiscord;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
package me.trouper.sentinel.server.gui.config.nuke.checks;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import io.github.itzispyder.pdk.utils.misc.config.ConfigUpdater;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.config.ViolationConfig;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.AntiNukeGUI;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class CBMCPlaceGUI {
|
||||
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 CB MC Place Check"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(26, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new AntiNukeGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
|
||||
ItemStack ring = Items.RED;
|
||||
if (Sentinel.violationConfig.commandBlockMinecartPlace.enabled) {
|
||||
ring = Items.GREEN;
|
||||
}
|
||||
|
||||
List<Integer> ringList = List.of(3,4,5,12,14,21,22,23);
|
||||
|
||||
for (Integer i : ringList) {
|
||||
inv.setItem(i,ring);
|
||||
}
|
||||
|
||||
inv.setItem(26,Items.BACK);
|
||||
inv.setItem(13,Items.booleanItem(Sentinel.violationConfig.commandBlockMinecartPlace.enabled,Items.configItem("Check Toggle",Material.CLOCK,"Enable/Disable this check entirely")));
|
||||
inv.setItem(2,Items.booleanItem(Sentinel.violationConfig.commandBlockMinecartPlace.deop,Items.configItem("De-Op",Material.END_CRYSTAL,"Remove the user's operator privileges")));
|
||||
inv.setItem(20,Items.booleanItem(Sentinel.violationConfig.commandBlockMinecartPlace.logToDiscord,Items.configItem("Log",Material.OAK_LOG,"If this check will produce a log to discord")));
|
||||
inv.setItem(6,Items.booleanItem(Sentinel.violationConfig.commandBlockMinecartPlace.punish,Items.configItem("Punish",Material.REDSTONE_TORCH,"Run the punishment commands")));
|
||||
inv.setItem(24,Items.stringListItem(Sentinel.violationConfig.commandBlockMinecartPlace.punishmentCommands,Material.DIAMOND_AXE,"Punishment Commands","Commands that will be ran \nif this check is flagged."));
|
||||
}
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
if (!MainGUI.verify((Player) e.getWhoClicked())) return;
|
||||
switch (e.getSlot()) {
|
||||
case 13 -> {
|
||||
Sentinel.violationConfig.commandBlockMinecartPlace.enabled = !Sentinel.violationConfig.commandBlockMinecartPlace.enabled;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 2 -> {
|
||||
Sentinel.violationConfig.commandBlockMinecartPlace.deop = !Sentinel.violationConfig.commandBlockMinecartPlace.deop;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 20 -> {
|
||||
Sentinel.violationConfig.commandBlockMinecartPlace.logToDiscord = !Sentinel.violationConfig.commandBlockMinecartPlace.logToDiscord;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 6 -> {
|
||||
Sentinel.violationConfig.commandBlockMinecartPlace.punish = !Sentinel.violationConfig.commandBlockMinecartPlace.punish;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
case 24 -> {
|
||||
if (e.isLeftClick()) {
|
||||
queuePlayer((Player) e.getWhoClicked(), (cfg, args) -> {
|
||||
cfg.commandBlockMinecartPlace.punishmentCommands.add(args.getAll().toString());
|
||||
},"" + Sentinel.violationConfig.commandBlockMinecartPlace.punishmentCommands);
|
||||
return;
|
||||
}
|
||||
Sentinel.violationConfig.commandBlockMinecartPlace.punishmentCommands.clear();
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static ConfigUpdater<AsyncPlayerChatEvent, ViolationConfig> updater = new ConfigUpdater<>(Sentinel.violationConfig);
|
||||
private void queuePlayer(Player player, BiConsumer<ViolationConfig, Args> action, String currentValue) {
|
||||
MainGUI.awaitingCallback.add(player.getUniqueId());
|
||||
player.closeInventory();
|
||||
updater.queuePlayer(player, 20*60, (e)->{
|
||||
e.setCancelled(true);
|
||||
ServerUtils.verbose("Supplying the message: \"%s\". Canceled? %s".formatted(e.getMessage(),e.isCancelled()));
|
||||
return e.getMessage();
|
||||
}, (cfg, newValue) -> {
|
||||
action.accept(cfg,new Args(newValue.split("\\s+")));
|
||||
cfg.save();
|
||||
player.sendMessage(Text.prefix("Value updated successfully"));
|
||||
player.openInventory(home.getInventory());
|
||||
});
|
||||
player.sendMessage(Component.text(Text.prefix("Enter the new value in chat. The value is currently set to &b%s&7. (Click to insert)".formatted(currentValue))).clickEvent(ClickEvent.suggestCommand(currentValue)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package me.trouper.sentinel.server.gui.config.nuke.checks;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import io.github.itzispyder.pdk.utils.misc.config.ConfigUpdater;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.config.ViolationConfig;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.AntiNukeGUI;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class CBMCUseGUI {
|
||||
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 CB MC Use Check"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(26, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new AntiNukeGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
|
||||
ItemStack ring = Items.RED;
|
||||
if (Sentinel.violationConfig.commandBlockMinecartUse.enabled) {
|
||||
ring = Items.GREEN;
|
||||
}
|
||||
|
||||
List<Integer> ringList = List.of(3,4,5,12,14,21,22,23);
|
||||
|
||||
for (Integer i : ringList) {
|
||||
inv.setItem(i,ring);
|
||||
}
|
||||
|
||||
inv.setItem(26,Items.BACK);
|
||||
inv.setItem(13,Items.booleanItem(Sentinel.violationConfig.commandBlockMinecartUse.enabled,Items.configItem("Check Toggle",Material.CLOCK,"Enable/Disable this check entirely")));
|
||||
inv.setItem(2,Items.booleanItem(Sentinel.violationConfig.commandBlockMinecartUse.deop,Items.configItem("De-Op",Material.END_CRYSTAL,"Remove the user's operator privileges")));
|
||||
inv.setItem(20,Items.booleanItem(Sentinel.violationConfig.commandBlockMinecartUse.logToDiscord,Items.configItem("Log",Material.OAK_LOG,"If this check will produce a log to discord")));
|
||||
inv.setItem(6,Items.booleanItem(Sentinel.violationConfig.commandBlockMinecartUse.punish,Items.configItem("Punish",Material.REDSTONE_TORCH,"Run the punishment commands")));
|
||||
inv.setItem(24,Items.stringListItem(Sentinel.violationConfig.commandBlockMinecartUse.punishmentCommands,Material.DIAMOND_AXE,"Punishment Commands","Commands that will be ran \nif this check is flagged."));
|
||||
}
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
if (!MainGUI.verify((Player) e.getWhoClicked())) return;
|
||||
switch (e.getSlot()) {
|
||||
case 13 -> {
|
||||
Sentinel.violationConfig.commandBlockMinecartUse.enabled = !Sentinel.violationConfig.commandBlockMinecartUse.enabled;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 2 -> {
|
||||
Sentinel.violationConfig.commandBlockMinecartUse.deop = !Sentinel.violationConfig.commandBlockMinecartUse.deop;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 20 -> {
|
||||
Sentinel.violationConfig.commandBlockMinecartUse.logToDiscord = !Sentinel.violationConfig.commandBlockMinecartUse.logToDiscord;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 6 -> {
|
||||
Sentinel.violationConfig.commandBlockMinecartUse.punish = !Sentinel.violationConfig.commandBlockMinecartUse.punish;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
case 24 -> {
|
||||
if (e.isLeftClick()) {
|
||||
queuePlayer((Player) e.getWhoClicked(), (cfg, args) -> {
|
||||
cfg.commandBlockMinecartUse.punishmentCommands.add(args.getAll().toString());
|
||||
},"" + Sentinel.violationConfig.commandBlockMinecartUse.punishmentCommands);
|
||||
return;
|
||||
}
|
||||
Sentinel.violationConfig.commandBlockMinecartUse.punishmentCommands.clear();
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static ConfigUpdater<AsyncPlayerChatEvent, ViolationConfig> updater = new ConfigUpdater<>(Sentinel.violationConfig);
|
||||
|
||||
private void queuePlayer(Player player, BiConsumer<ViolationConfig, Args> action, String currentValue) {
|
||||
MainGUI.awaitingCallback.add(player.getUniqueId());
|
||||
player.closeInventory();
|
||||
updater.queuePlayer(player, 20*60,(e)->{
|
||||
e.setCancelled(true);
|
||||
ServerUtils.verbose("Supplying the message: \"%s\". Canceled? %s".formatted(e.getMessage(),e.isCancelled()));
|
||||
return e.getMessage();
|
||||
}, (cfg, newValue) -> {
|
||||
action.accept(cfg,new Args(newValue.split("\\s+")));
|
||||
cfg.save();
|
||||
player.sendMessage(Text.prefix("Value updated successfully"));
|
||||
player.openInventory(home.getInventory());
|
||||
});
|
||||
player.sendMessage(Component.text(Text.prefix("Enter the new value in chat. The value is currently set to &b%s&7. (Click to insert)".formatted(currentValue))).clickEvent(ClickEvent.suggestCommand(currentValue)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package me.trouper.sentinel.server.gui.config.nuke.checks;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import io.github.itzispyder.pdk.utils.misc.config.ConfigUpdater;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.config.ViolationConfig;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.AntiNukeGUI;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class CBPlaceGUI {
|
||||
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 CB Place Check"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(26, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new AntiNukeGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
|
||||
ItemStack ring = Items.RED;
|
||||
if (Sentinel.violationConfig.commandBlockPlace.enabled) {
|
||||
ring = Items.GREEN;
|
||||
}
|
||||
|
||||
List<Integer> ringList = List.of(3,4,5,12,14,21,22,23);
|
||||
|
||||
for (Integer i : ringList) {
|
||||
inv.setItem(i,ring);
|
||||
}
|
||||
|
||||
inv.setItem(26,Items.BACK);
|
||||
inv.setItem(13,Items.booleanItem(Sentinel.violationConfig.commandBlockPlace.enabled,Items.configItem("Check Toggle",Material.CLOCK,"Enable/Disable this check entirely")));
|
||||
inv.setItem(2,Items.booleanItem(Sentinel.violationConfig.commandBlockPlace.deop,Items.configItem("De-Op",Material.END_CRYSTAL,"Remove the user's operator privileges")));
|
||||
inv.setItem(20,Items.booleanItem(Sentinel.violationConfig.commandBlockPlace.logToDiscord,Items.configItem("Log",Material.OAK_LOG,"If this check will produce a log to discord")));
|
||||
inv.setItem(6,Items.booleanItem(Sentinel.violationConfig.commandBlockPlace.punish,Items.configItem("Punish",Material.REDSTONE_TORCH,"Run the punishment commands")));
|
||||
inv.setItem(24,Items.stringListItem(Sentinel.violationConfig.commandBlockPlace.punishmentCommands,Material.DIAMOND_AXE,"Punishment Commands","Commands that will be ran \nif this check is flagged."));
|
||||
}
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
if (!MainGUI.verify((Player) e.getWhoClicked())) return;
|
||||
switch (e.getSlot()) {
|
||||
case 13 -> {
|
||||
Sentinel.violationConfig.commandBlockPlace.enabled = !Sentinel.violationConfig.commandBlockPlace.enabled;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 2 -> {
|
||||
Sentinel.violationConfig.commandBlockPlace.deop = !Sentinel.violationConfig.commandBlockPlace.deop;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 20 -> {
|
||||
Sentinel.violationConfig.commandBlockPlace.logToDiscord = !Sentinel.violationConfig.commandBlockPlace.logToDiscord;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 6 -> {
|
||||
Sentinel.violationConfig.commandBlockPlace.punish = !Sentinel.violationConfig.commandBlockPlace.punish;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
case 24 -> {
|
||||
if (e.isLeftClick()) {
|
||||
queuePlayer((Player) e.getWhoClicked(), (cfg, args) -> {
|
||||
cfg.commandBlockPlace.punishmentCommands.add(args.getAll().toString());
|
||||
},"" + Sentinel.violationConfig.commandBlockPlace.punishmentCommands);
|
||||
return;
|
||||
}
|
||||
Sentinel.violationConfig.commandBlockPlace.punishmentCommands.clear();
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static ConfigUpdater<AsyncPlayerChatEvent, ViolationConfig> updater = new ConfigUpdater<>(Sentinel.violationConfig);
|
||||
|
||||
private void queuePlayer(Player player, BiConsumer<ViolationConfig, Args> action, String currentValue) {
|
||||
MainGUI.awaitingCallback.add(player.getUniqueId());
|
||||
player.closeInventory();
|
||||
updater.queuePlayer(player, 20*60, (e)->{
|
||||
e.setCancelled(true);
|
||||
ServerUtils.verbose("Supplying the message: \"%s\". Canceled? %s".formatted(e.getMessage(),e.isCancelled()));
|
||||
return e.getMessage();
|
||||
}, (cfg, newValue) -> {
|
||||
action.accept(cfg,new Args(newValue.split("\\s+")));
|
||||
cfg.save();
|
||||
player.sendMessage(Text.prefix("Value updated successfully"));
|
||||
player.openInventory(home.getInventory());
|
||||
});
|
||||
player.sendMessage(Component.text(Text.prefix("Enter the new value in chat. The value is currently set to &b%s&7. (Click to insert)".formatted(currentValue))).clickEvent(ClickEvent.suggestCommand(currentValue)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package me.trouper.sentinel.server.gui.config.nuke.checks;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import io.github.itzispyder.pdk.utils.misc.config.ConfigUpdater;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.config.ViolationConfig;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.AntiNukeGUI;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class CBUseGUI {
|
||||
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 CB Use Check"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(26, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new AntiNukeGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
|
||||
ItemStack ring = Items.RED;
|
||||
if (Sentinel.violationConfig.commandBlockUse.enabled) {
|
||||
ring = Items.GREEN;
|
||||
}
|
||||
|
||||
List<Integer> ringList = List.of(3,4,5,12,14,21,22,23);
|
||||
|
||||
for (Integer i : ringList) {
|
||||
inv.setItem(i,ring);
|
||||
}
|
||||
|
||||
inv.setItem(26,Items.BACK);
|
||||
inv.setItem(13,Items.booleanItem(Sentinel.violationConfig.commandBlockUse.enabled,Items.configItem("Check Toggle",Material.CLOCK,"Enable/Disable this check entirely")));
|
||||
inv.setItem(2,Items.booleanItem(Sentinel.violationConfig.commandBlockUse.deop,Items.configItem("De-Op",Material.END_CRYSTAL,"Remove the user's operator privileges")));
|
||||
inv.setItem(20,Items.booleanItem(Sentinel.violationConfig.commandBlockUse.logToDiscord,Items.configItem("Log",Material.OAK_LOG,"If this check will produce a log to discord")));
|
||||
inv.setItem(6,Items.booleanItem(Sentinel.violationConfig.commandBlockUse.punish,Items.configItem("Punish",Material.REDSTONE_TORCH,"Run the punishment commands")));
|
||||
inv.setItem(24,Items.stringListItem(Sentinel.violationConfig.commandBlockUse.punishmentCommands,Material.DIAMOND_AXE,"Punishment Commands","Commands that will be ran \nif this check is flagged."));
|
||||
}
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
if (!MainGUI.verify((Player) e.getWhoClicked())) return;
|
||||
switch (e.getSlot()) {
|
||||
case 13 -> {
|
||||
Sentinel.violationConfig.commandBlockUse.enabled = !Sentinel.violationConfig.commandBlockUse.enabled;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 2 -> {
|
||||
Sentinel.violationConfig.commandBlockUse.deop = !Sentinel.violationConfig.commandBlockUse.deop;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 20 -> {
|
||||
Sentinel.violationConfig.commandBlockUse.logToDiscord = !Sentinel.violationConfig.commandBlockUse.logToDiscord;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 6 -> {
|
||||
Sentinel.violationConfig.commandBlockUse.punish = !Sentinel.violationConfig.commandBlockUse.punish;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
case 24 -> {
|
||||
if (e.isLeftClick()) {
|
||||
queuePlayer((Player) e.getWhoClicked(), (cfg, args) -> {
|
||||
cfg.commandBlockUse.punishmentCommands.add(args.getAll().toString());
|
||||
},"" + Sentinel.violationConfig.commandBlockUse.punishmentCommands);
|
||||
return;
|
||||
}
|
||||
Sentinel.violationConfig.commandBlockUse.punishmentCommands.clear();
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static ConfigUpdater<AsyncPlayerChatEvent, ViolationConfig> updater = new ConfigUpdater<>(Sentinel.violationConfig);
|
||||
|
||||
private void queuePlayer(Player player, BiConsumer<ViolationConfig, Args> action, String currentValue) {
|
||||
MainGUI.awaitingCallback.add(player.getUniqueId());
|
||||
player.closeInventory();
|
||||
updater.queuePlayer(player, 20*60, (e)->{
|
||||
e.setCancelled(true);
|
||||
ServerUtils.verbose("Supplying the message: \"%s\". Canceled? %s".formatted(e.getMessage(),e.isCancelled()));
|
||||
return e.getMessage();
|
||||
}, (cfg, newValue) -> {
|
||||
action.accept(cfg,new Args(newValue.split("\\s+")));
|
||||
cfg.save();
|
||||
player.sendMessage(Text.prefix("Value updated successfully"));
|
||||
player.openInventory(home.getInventory());
|
||||
});
|
||||
player.sendMessage(Component.text(Text.prefix("Enter the new value in chat. The value is currently set to &b%s&7. (Click to insert)".formatted(currentValue))).clickEvent(ClickEvent.suggestCommand(currentValue)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package me.trouper.sentinel.server.gui.config.nuke.checks;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import io.github.itzispyder.pdk.utils.misc.config.ConfigUpdater;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.config.ViolationConfig;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.AntiNukeGUI;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class HotbarActionGUI {
|
||||
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 Creative Hotbar Check"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this:: mainClick)
|
||||
.define(26, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new AntiNukeGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
|
||||
ItemStack ring = Items.RED;
|
||||
if (Sentinel.violationConfig.creativeHotbarAction.enabled) {
|
||||
ring = Items.GREEN;
|
||||
}
|
||||
|
||||
List<Integer> ringList = List.of(3,4,5,12,14,21,22,23);
|
||||
|
||||
for (Integer i : ringList) {
|
||||
inv.setItem(i,ring);
|
||||
}
|
||||
|
||||
inv.setItem(26,Items.BACK);
|
||||
inv.setItem(13,Items.booleanItem(Sentinel.violationConfig.creativeHotbarAction.enabled,Items.configItem("Check Toggle",Material.CLOCK,"Enable/Disable this check entirely")));
|
||||
inv.setItem(2,Items.booleanItem(Sentinel.violationConfig.creativeHotbarAction.deop,Items.configItem("De-Op",Material.END_CRYSTAL,"Remove the user's operator privileges")));
|
||||
inv.setItem(20,Items.booleanItem(Sentinel.violationConfig.creativeHotbarAction.logToDiscord,Items.configItem("Log",Material.OAK_LOG,"If this check will produce a log to discord")));
|
||||
inv.setItem(6,Items.booleanItem(Sentinel.violationConfig.creativeHotbarAction.punish,Items.configItem("Punish",Material.REDSTONE_TORCH,"Run the punishment commands")));
|
||||
inv.setItem(24,Items.stringListItem(Sentinel.violationConfig.creativeHotbarAction.punishmentCommands,Material.DIAMOND_AXE,"Punishment Commands","Commands that will be ran \nif this check is flagged."));
|
||||
}
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
if (!MainGUI.verify((Player) e.getWhoClicked())) return;
|
||||
|
||||
switch (e.getSlot()) {
|
||||
case 13 -> {
|
||||
Sentinel.violationConfig.creativeHotbarAction.enabled = !Sentinel.violationConfig.creativeHotbarAction.enabled;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 2 -> {
|
||||
Sentinel.violationConfig.creativeHotbarAction.deop = !Sentinel.violationConfig.creativeHotbarAction.deop;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 20 -> {
|
||||
Sentinel.violationConfig.creativeHotbarAction.logToDiscord = !Sentinel.violationConfig.creativeHotbarAction.logToDiscord;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 6 -> {
|
||||
Sentinel.violationConfig.creativeHotbarAction.punish = !Sentinel.violationConfig.creativeHotbarAction.punish;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
case 24 -> {
|
||||
if (e.isLeftClick()) {
|
||||
queuePlayer((Player) e.getWhoClicked(), (cfg, args) -> {
|
||||
cfg.creativeHotbarAction.punishmentCommands.add(args.getAll().toString());
|
||||
},"" + Sentinel.violationConfig.creativeHotbarAction.punishmentCommands);
|
||||
return;
|
||||
}
|
||||
Sentinel.violationConfig.creativeHotbarAction.punishmentCommands.clear();
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static ConfigUpdater<AsyncPlayerChatEvent, ViolationConfig> updater = new ConfigUpdater<>(Sentinel.violationConfig);
|
||||
|
||||
private void queuePlayer(Player player, BiConsumer<ViolationConfig, Args> action, String currentValue) {
|
||||
MainGUI.awaitingCallback.add(player.getUniqueId());
|
||||
player.closeInventory();
|
||||
updater.queuePlayer(player, 20*60, (e)->{
|
||||
e.setCancelled(true);
|
||||
ServerUtils.verbose("Supplying the message: \"%s\". Canceled? %s".formatted(e.getMessage(),e.isCancelled()));
|
||||
return e.getMessage();
|
||||
}, (cfg, newValue) -> {
|
||||
action.accept(cfg,new Args(newValue.split("\\s+")));
|
||||
cfg.save();
|
||||
player.sendMessage(Text.prefix("Value updated successfully"));
|
||||
player.openInventory(home.getInventory());
|
||||
});
|
||||
player.sendMessage(Component.text(Text.prefix("Enter the new value in chat. The value is currently set to &b%s&7. (Click to insert)".formatted(currentValue))).clickEvent(ClickEvent.suggestCommand(currentValue)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package me.trouper.sentinel.server.gui.config.nuke.checks.command;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import io.github.itzispyder.pdk.utils.misc.config.ConfigUpdater;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.config.ViolationConfig;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.nuke.CommandGUI;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class DangerousCMDGUI {
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 Dangerous Command Check"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(26, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new CommandGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
|
||||
ItemStack ring = Items.RED;
|
||||
if (Sentinel.violationConfig.commandExecute.dangerous.enabled) {
|
||||
ring = Items.GREEN;
|
||||
}
|
||||
|
||||
List<Integer> ringList = List.of(3,4,5,12,14,21,23);
|
||||
|
||||
for (Integer i : ringList) {
|
||||
inv.setItem(i,ring);
|
||||
}
|
||||
|
||||
inv.setItem(26,Items.BACK);
|
||||
inv.setItem(13,Items.booleanItem(Sentinel.violationConfig.commandExecute.dangerous.enabled,Items.configItem("Check Toggle",Material.CLOCK,"Enable/Disable this check entirely")));
|
||||
inv.setItem(2,Items.booleanItem(Sentinel.violationConfig.commandExecute.dangerous.deop,Items.configItem("De-Op",Material.END_CRYSTAL,"Remove the user's operator privileges")));
|
||||
inv.setItem(20,Items.booleanItem(Sentinel.violationConfig.commandExecute.dangerous.logToDiscord,Items.configItem("Log",Material.OAK_LOG,"If this check will produce a log to discord")));
|
||||
inv.setItem(6,Items.booleanItem(Sentinel.violationConfig.commandExecute.dangerous.punish,Items.configItem("Punish",Material.REDSTONE_TORCH,"Run the punishment commands")));
|
||||
inv.setItem(24,Items.stringListItem(Sentinel.violationConfig.commandExecute.dangerous.punishmentCommands,Material.DIAMOND_AXE,"Punishment Commands","Commands that will be ran \nif this check is flagged."));
|
||||
inv.setItem(22,Items.stringListItem(Sentinel.violationConfig.commandExecute.dangerous.commands,Material.CRIMSON_HANGING_SIGN,"Commands","Commands that will flag this check."));
|
||||
}
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
if (!MainGUI.verify((Player) e.getWhoClicked())) return;
|
||||
switch (e.getSlot()) {
|
||||
case 13 -> {
|
||||
Sentinel.violationConfig.commandExecute.dangerous.enabled = !Sentinel.violationConfig.commandExecute.dangerous.enabled;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 2 -> {
|
||||
Sentinel.violationConfig.commandExecute.dangerous.deop = !Sentinel.violationConfig.commandExecute.dangerous.deop;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 20 -> {
|
||||
Sentinel.violationConfig.commandExecute.dangerous.logToDiscord = !Sentinel.violationConfig.commandExecute.dangerous.logToDiscord;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 6 -> {
|
||||
Sentinel.violationConfig.commandExecute.dangerous.punish = !Sentinel.violationConfig.commandExecute.dangerous.punish;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
case 24 -> {
|
||||
if (e.isLeftClick()) {
|
||||
queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> {
|
||||
cfg.commandExecute.dangerous.punishmentCommands.add(args.getAll().toString());
|
||||
},"" + Sentinel.violationConfig.commandExecute.dangerous.punishmentCommands);
|
||||
return;
|
||||
}
|
||||
Sentinel.violationConfig.commandExecute.dangerous.punishmentCommands.clear();
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
case 22 -> {
|
||||
if (e.isLeftClick()) {
|
||||
queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> {
|
||||
cfg.commandExecute.dangerous.commands.add(args.getAll().toString());
|
||||
},"" + Sentinel.violationConfig.commandExecute.dangerous.commands);
|
||||
return;
|
||||
}
|
||||
Sentinel.violationConfig.commandExecute.dangerous.commands.clear();
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static ConfigUpdater<AsyncPlayerChatEvent, ViolationConfig> updater = new ConfigUpdater<>(Sentinel.violationConfig);
|
||||
|
||||
private void queuePlayer(Player player, BiConsumer<ViolationConfig, Args> action, String currentValue) {
|
||||
MainGUI.awaitingCallback.add(player.getUniqueId());
|
||||
player.closeInventory();
|
||||
updater.queuePlayer(player, 20*60, (e)->{
|
||||
e.setCancelled(true);
|
||||
ServerUtils.verbose("Supplying the message: \"%s\". Canceled? %s".formatted(e.getMessage(),e.isCancelled()));
|
||||
return e.getMessage();
|
||||
}, (cfg, newValue) -> {
|
||||
action.accept(cfg,new Args(newValue.split("\\s+")));
|
||||
cfg.save();
|
||||
player.sendMessage(Text.prefix("Value updated successfully"));
|
||||
player.openInventory(home.getInventory());
|
||||
});
|
||||
player.sendMessage(Component.text(Text.prefix("Enter the new value in chat. The value is currently set to &b%s&7. (Click to insert)".formatted(currentValue))).clickEvent(ClickEvent.suggestCommand(currentValue)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package me.trouper.sentinel.server.gui.config.nuke.checks.command;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import io.github.itzispyder.pdk.utils.misc.config.ConfigUpdater;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.config.ViolationConfig;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.nuke.CommandGUI;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class LoggedCMDGUI {
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 Logged Command Check"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(26, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new CommandGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
|
||||
ItemStack ring = Items.RED;
|
||||
if (Sentinel.violationConfig.commandExecute.logged.enabled) {
|
||||
ring = Items.GREEN;
|
||||
}
|
||||
|
||||
List<Integer> ringList = List.of(3,4,5,12,14,21,22,23);
|
||||
|
||||
for (Integer i : ringList) {
|
||||
inv.setItem(i,ring);
|
||||
}
|
||||
|
||||
inv.setItem(26,Items.BACK);
|
||||
inv.setItem(13,Items.booleanItem(Sentinel.violationConfig.commandExecute.logged.enabled,Items.configItem("Check Toggle",Material.CLOCK,"Enable/Disable this check entirely")));
|
||||
inv.setItem(11,Items.booleanItem(Sentinel.violationConfig.commandExecute.logged.logToDiscord,Items.configItem("Log to Discord",Material.OAK_LOG,"If this check will log to discord")));
|
||||
inv.setItem(15,Items.stringListItem(Sentinel.violationConfig.commandExecute.logged.commands,Material.CRIMSON_HANGING_SIGN,"Commands","Commands that will flag this check"));
|
||||
}
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
if (!MainGUI.verify((Player) e.getWhoClicked())) return;
|
||||
switch (e.getSlot()) {
|
||||
case 13 -> {
|
||||
Sentinel.violationConfig.commandExecute.logged.enabled = !Sentinel.violationConfig.commandExecute.logged.enabled;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 11 -> {
|
||||
Sentinel.violationConfig.commandExecute.logged.logToDiscord = !Sentinel.violationConfig.commandExecute.logged.logToDiscord;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 15 -> {
|
||||
if (e.isLeftClick()) {
|
||||
queuePlayer((Player) e.getWhoClicked(), (cfg,args) -> {
|
||||
cfg.commandExecute.logged.commands.add(args.getAll().toString());
|
||||
},"" + Sentinel.violationConfig.commandExecute.logged.commands);
|
||||
return;
|
||||
}
|
||||
Sentinel.violationConfig.commandExecute.logged.commands.clear();
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ConfigUpdater<AsyncPlayerChatEvent, ViolationConfig> updater = new ConfigUpdater<>(Sentinel.violationConfig);
|
||||
private void queuePlayer(Player player, BiConsumer<ViolationConfig, Args> action, String currentValue) {
|
||||
MainGUI.awaitingCallback.add(player.getUniqueId());
|
||||
player.closeInventory();
|
||||
updater.queuePlayer(player, 20*60, (e)->{
|
||||
e.setCancelled(true);
|
||||
ServerUtils.verbose("Supplying the message: \"%s\". Canceled? %s".formatted(e.getMessage(),e.isCancelled()));
|
||||
return e.getMessage();
|
||||
}, (cfg, newValue) -> {
|
||||
action.accept(cfg,new Args(newValue.split("\\s+")));
|
||||
cfg.save();
|
||||
player.sendMessage(Text.prefix("Value updated successfully"));
|
||||
player.openInventory(home.getInventory());
|
||||
});
|
||||
player.sendMessage(Component.text(Text.prefix("Enter the new value in chat. The value is currently set to &b%s&7. (Click to insert)".formatted(currentValue))).clickEvent(ClickEvent.suggestCommand(currentValue)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package me.trouper.sentinel.server.gui.config.nuke.checks.command;
|
||||
|
||||
import io.github.itzispyder.pdk.commands.Args;
|
||||
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
|
||||
import io.github.itzispyder.pdk.utils.misc.config.ConfigUpdater;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.config.ViolationConfig;
|
||||
import me.trouper.sentinel.server.gui.Items;
|
||||
import me.trouper.sentinel.server.gui.MainGUI;
|
||||
import me.trouper.sentinel.server.gui.config.nuke.CommandGUI;
|
||||
import me.trouper.sentinel.utils.ServerUtils;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class SpecificCMDGUI {
|
||||
public final CustomGui home = CustomGui.create()
|
||||
.title(Text.color("&6&lSentinel &8»&0 Specific Command Check"))
|
||||
.size(27)
|
||||
.onDefine(this::blankPage)
|
||||
.defineMain(this::mainClick)
|
||||
.define(26, Items.BACK, e->{
|
||||
e.getWhoClicked().openInventory(new CommandGUI().home.getInventory());
|
||||
})
|
||||
.build();
|
||||
|
||||
private void blankPage(Inventory inv) {
|
||||
for (int i = 0; i < inv.getSize(); i++) {
|
||||
inv.setItem(i,Items.BLANK);
|
||||
}
|
||||
|
||||
ItemStack top = Items.RED;
|
||||
if (Sentinel.violationConfig.commandExecute.specific.enabled) {
|
||||
top = Items.GREEN;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
inv.setItem(i,top);
|
||||
}
|
||||
|
||||
inv.setItem(26,Items.BACK);
|
||||
inv.setItem(4,Items.booleanItem(Sentinel.violationConfig.commandExecute.specific.enabled,Items.configItem("Check Toggle", Material.CLOCK,"Enable/Disable this check entirely")));
|
||||
inv.setItem(11,Items.booleanItem(Sentinel.violationConfig.commandExecute.specific.punish,Items.configItem("Punish",Material.REDSTONE_TORCH,"If this check will run the punishment commands")));
|
||||
inv.setItem(13,Items.booleanItem(Sentinel.violationConfig.commandExecute.specific.logToDiscord,Items.configItem("Log",Material.OAK_LOG,"If this check will produce a log to discord")));
|
||||
inv.setItem(15,Items.stringListItem(Sentinel.violationConfig.commandExecute.specific.punishmentCommands,Material.DIAMOND_AXE,"Commands","Commands that will flag this check"));
|
||||
}
|
||||
|
||||
private void mainClick(InventoryClickEvent e) {
|
||||
e.setCancelled(true);
|
||||
if (!MainGUI.verify((Player) e.getWhoClicked())) return;
|
||||
switch (e.getSlot()) {
|
||||
case 4 -> {
|
||||
Sentinel.violationConfig.commandExecute.specific.enabled = !Sentinel.violationConfig.commandExecute.specific.enabled;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 13 -> {
|
||||
Sentinel.violationConfig.commandExecute.specific.logToDiscord = !Sentinel.violationConfig.commandExecute.specific.logToDiscord;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
case 11 -> {
|
||||
Sentinel.violationConfig.commandExecute.specific.punish = !Sentinel.violationConfig.commandExecute.specific.punish;
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
|
||||
case 15 -> {
|
||||
if (e.isLeftClick()) {
|
||||
queuePlayer((Player) e.getWhoClicked(), (cfg, args) -> {
|
||||
cfg.commandExecute.specific.punishmentCommands.add(args.getAll().toString());
|
||||
},"" + Sentinel.violationConfig.commandExecute.specific.punishmentCommands);
|
||||
return;
|
||||
}
|
||||
Sentinel.violationConfig.commandExecute.specific.punishmentCommands.clear();
|
||||
blankPage(e.getInventory());
|
||||
Sentinel.violationConfig.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static ConfigUpdater<AsyncPlayerChatEvent, ViolationConfig> updater = new ConfigUpdater<>(Sentinel.violationConfig);
|
||||
|
||||
private void queuePlayer(Player player, BiConsumer<ViolationConfig, Args> action, String currentValue) {
|
||||
MainGUI.awaitingCallback.add(player.getUniqueId());
|
||||
player.closeInventory();
|
||||
updater.queuePlayer(player, 20*60, (e)->{
|
||||
e.setCancelled(true);
|
||||
ServerUtils.verbose("Supplying the message: \"%s\". Canceled? %s".formatted(e.getMessage(),e.isCancelled()));
|
||||
return e.getMessage();
|
||||
}, (cfg, newValue) -> {
|
||||
action.accept(cfg,new Args(newValue.split("\\s+")));
|
||||
cfg.save();
|
||||
player.sendMessage(Text.prefix("Value updated successfully"));
|
||||
player.openInventory(home.getInventory());
|
||||
});
|
||||
player.sendMessage(Component.text(Text.prefix("Enter the new value in chat. The value is currently set to &b%s&7. (Click to insert)".formatted(currentValue))).clickEvent(ClickEvent.suggestCommand(currentValue)));
|
||||
}
|
||||
}
|
||||
81
src/main/java/me/trouper/sentinel/startup/AntiPiracy.java
Normal file
81
src/main/java/me/trouper/sentinel/startup/AntiPiracy.java
Normal file
@@ -0,0 +1,81 @@
|
||||
package me.trouper.sentinel.startup;
|
||||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.utils.CipherUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class AntiPiracy {
|
||||
|
||||
public static boolean sailTheSevenSeas() {
|
||||
Sentinel.log.info("Docking Vesel");
|
||||
File sentinel = Sentinel.us;
|
||||
Sentinel.log.info("Obtaining Gold");
|
||||
String hash = CipherUtils.getFileHash(sentinel);
|
||||
Sentinel.log.info("Checking for fake coin");
|
||||
if (hash == null) {
|
||||
Sentinel.log.info("Counterfeiter!");
|
||||
return true;
|
||||
}
|
||||
|
||||
Set<String> allowedHashes = getHashList();
|
||||
if (allowedHashes == null || allowedHashes.isEmpty()) {
|
||||
Sentinel.log.info("No Booty?");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (allowedHashes.contains(hash)) {
|
||||
Sentinel.log.info("Checkpoint 1 Complete");
|
||||
return false;
|
||||
} else {
|
||||
Sentinel.log.info("Well,");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Set<String> getHashList() {
|
||||
Sentinel.log.info("Initializing East India Protocol");
|
||||
try {
|
||||
String urlString = "http://api.trouper.me:8080/sentinel-hashes";
|
||||
URL url = new URL(urlString);
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
Sentinel.log.info("Bargaining with merchants");
|
||||
|
||||
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();
|
||||
|
||||
Sentinel.log.info("Counting Coins");
|
||||
Gson gson = new Gson();
|
||||
|
||||
return gson.fromJson(content.toString(), new TypeToken<Set<String>>() {}.getType());
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
153
src/main/java/me/trouper/sentinel/startup/Auth.java
Normal file
153
src/main/java/me/trouper/sentinel/startup/Auth.java
Normal file
@@ -0,0 +1,153 @@
|
||||
package me.trouper.sentinel.startup;
|
||||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.config.AdvancedConfig;
|
||||
import me.trouper.sentinel.utils.MathUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Auth {
|
||||
|
||||
public static String serverID = "NULL";
|
||||
public static String licenseKey = "NULL";
|
||||
public static String nonce = "NULL";
|
||||
public static String ip = "NULL";
|
||||
public static int port = 0;
|
||||
|
||||
public static boolean canLoad() {
|
||||
switch (authorize()) {
|
||||
case "AUTHORIZED" -> {
|
||||
return true;
|
||||
}
|
||||
case "MINEHUT" -> {
|
||||
boolean minehutStatus = Telemetry.initTelemetryHook() && Telemetry.report("Dynamic IP server has initialized.","Successful \"Auth\".");
|
||||
if (minehutStatus) {
|
||||
Sentinel.log.info("Dynamic IP auth Success!");
|
||||
return true;
|
||||
} else {
|
||||
Sentinel. log.info("Dynamic IP Failure. Webhook Error possible? Please contact obvWolf to fix this.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String authorize() {
|
||||
Map<String, List<String>> licenses = getLicenseList();
|
||||
if (licenses == null) return "ERROR";
|
||||
|
||||
if (licenses.containsKey(getLicenseKey())) {
|
||||
List<String> allowedIDs = licenses.get(getLicenseKey());
|
||||
if (allowedIDs.contains(serverID)) {
|
||||
return "AUTHORIZED";
|
||||
} else if (allowedIDs.contains("minehut")) {
|
||||
return "MINEHUT";
|
||||
} else {
|
||||
return "INVALID-ID";
|
||||
}
|
||||
}
|
||||
|
||||
return "UNREGISTERED";
|
||||
}
|
||||
|
||||
public static String getServerID() {
|
||||
if (serverID == null || "NULL".equalsIgnoreCase(serverID)) {
|
||||
try {
|
||||
serverID = MathUtils.SHA256(getPublicIPAddress() + getPort());
|
||||
return serverID;
|
||||
} catch (Exception e) {
|
||||
return MathUtils.SHA256(getNonce() + getPort());
|
||||
}
|
||||
}
|
||||
return serverID;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
ip = response.toString().trim();
|
||||
|
||||
return ip;
|
||||
} else {
|
||||
throw new IOException("Failed to get public IP address. HTTP error code: " + responseCode);
|
||||
}
|
||||
} finally {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public static int getPort() {
|
||||
port = Bukkit.getPort();
|
||||
return port;
|
||||
}
|
||||
|
||||
public static String getNonce() {
|
||||
if (nonce == null || nonce.equals("NULL")) nonce = MathUtils.MD5(AdvancedConfig.nonce);
|
||||
return nonce;
|
||||
}
|
||||
|
||||
public static String getLicenseKey() {
|
||||
licenseKey = Sentinel.mainConfig.plugin.license;
|
||||
return licenseKey;
|
||||
}
|
||||
}
|
||||
135
src/main/java/me/trouper/sentinel/startup/Load.java
Normal file
135
src/main/java/me/trouper/sentinel/startup/Load.java
Normal file
@@ -0,0 +1,135 @@
|
||||
package me.trouper.sentinel.startup;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.SchedulerUtils;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.profanity.AntiProfanity;
|
||||
import me.trouper.sentinel.server.functions.chatfilter.spam.AntiSpam;
|
||||
import me.trouper.sentinel.server.commands.*;
|
||||
import me.trouper.sentinel.server.events.*;
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class Load {
|
||||
|
||||
public static boolean lite = false;
|
||||
|
||||
public static void load(String license, String serverID) {
|
||||
/*if (AntiPiracy.sailTheSevenSeas()) {
|
||||
Sentinel.log.info("That's Aught to be the worst pirate I've ever seen...");
|
||||
Sentinel.log.warning("Your Sentinel distribution is illegal. Its DistroID is %s. It is not valid in the online registry.".formatted(CipherUtils.getFileHash(Sentinel.us)));
|
||||
liteStart("Failed Distribution Check (Modified Jar?)");
|
||||
return;
|
||||
}*/
|
||||
try {
|
||||
Sentinel.log.info("Auth Requested...");
|
||||
switch (Auth.authorize()) {
|
||||
case "AUTHORIZED" -> {
|
||||
Sentinel.log.info("\n]======----- Auth Success! -----======[");
|
||||
startup(true);
|
||||
}
|
||||
case "MINEHUT" -> {
|
||||
boolean minehutStatus = Telemetry.initTelemetryHook() && Telemetry.report("Dynamic IP server has initialized.","Successful \"Auth\".");
|
||||
if (minehutStatus) {
|
||||
Sentinel.log.info("Dynamic IP auth Success!");
|
||||
startup(true);
|
||||
} else {
|
||||
Sentinel. log.info("Dynamic IP Failure. Webhook Error possible? Please contact obvWolf to fix this.");
|
||||
liteStart("How is this even possible?");
|
||||
}
|
||||
}
|
||||
case "INVALID-ID" -> {
|
||||
Sentinel.log.info("Authentication Failure, You have not whitelisted this server ID yet.");
|
||||
liteStart("They have not whitelisted their server ID yet. (License exists, no ID)");
|
||||
}
|
||||
case "UNREGISTERED" -> {
|
||||
Sentinel.log.warning("Authentication Failure, YOU SHALL NOT PASS! License: %s Server ID: %s".formatted(license,serverID));
|
||||
liteStart("They do not have a license key");
|
||||
}
|
||||
case "ERROR" -> {
|
||||
Sentinel.log.warning("Hmmmmmm thats not right... License: %s Server ID: %s\nPlease report the above stacktrace.".formatted(license,serverID));
|
||||
liteStart("An expected error occurred which prevented them from launching");
|
||||
}
|
||||
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("An unexpected error occured which prevented them from launching");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Sentinel.log.info("WTFFFF ARE YOU DOING MAN??????");
|
||||
liteStart("An exception was thrown, then caught.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void liteStart(String reason) {
|
||||
lite = true;
|
||||
Telemetry.initTelemetryHook();
|
||||
Telemetry.report("Server has launched in lite mode",reason);
|
||||
|
||||
new SentinelCommand().register();
|
||||
|
||||
Sentinel.log.info("""
|
||||
Finished!
|
||||
____ __ ___ \s
|
||||
/\\ _`\\ /\\ \\__ __ /\\_ \\ \s
|
||||
\\ \\,\\L\\_\\ __ ___\\ \\ ,_\\/\\_\\ ___ __\\//\\ \\ \s
|
||||
\\/_\\__ \\ /'__`\\/' _ `\\ \\ \\/\\/\\ \\ /' _ `\\ /'__`\\\\ \\ \\ \s
|
||||
/\\ \\L\\ \\/\\ __//\\ \\/\\ \\ \\ \\_\\ \\ \\/\\ \\/\\ \\/\\ __/ \\_\\ \\_\s
|
||||
\\ `\\____\\ \\____\\ \\_\\ \\_\\ \\__\\\\ \\_\\ \\_\\ \\_\\ \\____\\/\\____\\
|
||||
\\/_____/\\/____/\\/_/\\/_/\\/__/ \\/_/\\/_/\\/_/\\/____/\\/____/
|
||||
]==-- Enabled Lite mode. Go verify your purchase. --==[
|
||||
""");
|
||||
|
||||
|
||||
SchedulerUtils.repeat(20*30,()->{
|
||||
if (lite) {
|
||||
Sentinel.log.info(Text.removeColors(SentinelCommand.liteMode));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void startup(boolean coldStart) {
|
||||
Sentinel.log.info("\n]======----- Loading Sentinel! -----======[");
|
||||
lite = false;
|
||||
|
||||
// Plugin startup logic
|
||||
Sentinel.log.info("Starting Up! (%s)...".formatted(Sentinel.getInstance().getDescription().getVersion()));
|
||||
|
||||
// Commands
|
||||
if (coldStart) new SentinelCommand().register();
|
||||
new MessageCommand().register();
|
||||
new ReplyCommand().register();
|
||||
new ReopCommand().register();
|
||||
new CallbackCommand().register();
|
||||
|
||||
// Events
|
||||
new CBEditEvent().register();
|
||||
new CBExecuteEvent().register();
|
||||
new CBMCPlaceEvent().register();
|
||||
new CBMCUseEvent().register();
|
||||
new CBPlaceEvent().register();
|
||||
new CBUseEvent().register();
|
||||
new ChatEvent().register();
|
||||
new CommandExecuteEvent().register();
|
||||
new CreativeHotbarEvent().register();
|
||||
new TrapCommand().register();
|
||||
new PluginCloakingEvents().register();
|
||||
if (Sentinel.doNoPlugins) {
|
||||
PluginCloakingEvents.registerEvent(Sentinel.getInstance());
|
||||
}
|
||||
|
||||
// Scheduled timers
|
||||
Bukkit.getScheduler().runTaskTimer(Sentinel.getInstance(), AntiSpam::decayHeat,0, 20);
|
||||
Bukkit.getScheduler().runTaskTimer(Sentinel.getInstance(), AntiProfanity::decayScore,0,1200);
|
||||
Sentinel.log.info("""
|
||||
Finished!
|
||||
____ __ ___ \s
|
||||
/\\ _`\\ /\\ \\__ __ /\\_ \\ \s
|
||||
\\ \\,\\L\\_\\ __ ___\\ \\ ,_\\/\\_\\ ___ __\\//\\ \\ \s
|
||||
\\/_\\__ \\ /'__`\\/' _ `\\ \\ \\/\\/\\ \\ /' _ `\\ /'__`\\\\ \\ \\ \s
|
||||
/\\ \\L\\ \\/\\ __//\\ \\/\\ \\ \\ \\_\\ \\ \\/\\ \\/\\ \\/\\ __/ \\_\\ \\_\s
|
||||
\\ `\\____\\ \\____\\ \\_\\ \\_\\ \\__\\\\ \\_\\ \\_\\ \\_\\ \\____\\/\\____\\
|
||||
\\/_____/\\/____/\\/_/\\/_/\\/__/ \\/_/\\/_/\\/_/\\/____/\\/____/
|
||||
]====---- Advanced Anti-Grief & Chat Filter ----====[""");
|
||||
}
|
||||
}
|
||||
124
src/main/java/me/trouper/sentinel/startup/Telemetry.java
Normal file
124
src/main/java/me/trouper/sentinel/startup/Telemetry.java
Normal file
@@ -0,0 +1,124 @@
|
||||
package me.trouper.sentinel.startup;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordEmbed;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.config.MainConfig;
|
||||
import me.trouper.sentinel.utils.trees.EmbedFormatter;
|
||||
import me.trouper.sentinel.utils.CipherUtils;
|
||||
|
||||
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 boolean initTelemetryHook() {
|
||||
webhook = fetchTelemetryHook();
|
||||
return !webhook.equals("NULL");
|
||||
}
|
||||
|
||||
public static boolean report(String title, String reason) {
|
||||
int port = Auth.getPort();
|
||||
DiscordEmbed embed = new DiscordEmbed.Builder()
|
||||
.color(0xFF0000)
|
||||
.author("Sentinel Startup Log")
|
||||
.title(title)
|
||||
.desc("""
|
||||
**__License Info__**
|
||||
License: `%s`
|
||||
Nonce: `%s`
|
||||
File Hash: `%s`
|
||||
Purchaser: `%s` | `%s`
|
||||
|
||||
**__Server Info__**
|
||||
ID: `%s`
|
||||
Address: `%s`
|
||||
Port: `%s`
|
||||
|
||||
**__Extra Info__**
|
||||
%s
|
||||
""".formatted(
|
||||
Auth.getLicenseKey(),
|
||||
Auth.getNonce(),
|
||||
CipherUtils.getFileHash(Sentinel.us),
|
||||
MainConfig.username,
|
||||
MainConfig.user,
|
||||
Auth.getServerID(),
|
||||
Auth.ip,
|
||||
port,
|
||||
reason
|
||||
)).build();
|
||||
|
||||
try {
|
||||
EmbedFormatter.sendEmbed(embed,webhook);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static String fetchTelemetryHook() {
|
||||
if (webhook == null || "NULL".equals(webhook)) {
|
||||
try {
|
||||
final String webhook = extractWebhook(fetchHtmlContent("https://trouper.me/auth/telemetry"));
|
||||
// ServerUtils.verbose("Original Webhook: " + webhook);
|
||||
|
||||
String webhookIdPart = webhook.replaceAll(".*/(\\d+)/([^/]+.*)$", "/$1/");
|
||||
// ServerUtils.verbose("Webhook ID Part: " + webhookIdPart);
|
||||
|
||||
String encrypted = webhook.replaceAll(".*/\\d+/([^/]+.*)$", "$1");
|
||||
// ServerUtils.verbose("Encrypted Part: " + encrypted);
|
||||
|
||||
String isolated = webhook.replaceAll("/\\d+/([^/]+.*)$", "");
|
||||
//ServerUtils.verbose("Isolated Part: " + isolated);
|
||||
|
||||
String decrypted = isolated + webhookIdPart + CipherUtils.decrypt(encrypted);
|
||||
//ServerUtils.verbose("Decrypted Result: " + decrypted);
|
||||
|
||||
return decrypted;
|
||||
} catch (Exception ex) {
|
||||
Sentinel.log.warning("FAILED TO LOAD TELEMETRY (Are the servers up?)");
|
||||
ex.printStackTrace();
|
||||
return "NULL";
|
||||
}
|
||||
}
|
||||
return webhook;
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
||||
}
|
||||
75
src/main/java/me/trouper/sentinel/utils/CipherUtils.java
Normal file
75
src/main/java/me/trouper/sentinel/utils/CipherUtils.java
Normal file
@@ -0,0 +1,75 @@
|
||||
package me.trouper.sentinel.utils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
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;
|
||||
}
|
||||
|
||||
public static String getFileHash(File file) {
|
||||
try {
|
||||
// Create a MessageDigest instance for SHA-256
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
|
||||
// Read the file's content
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
byte[] byteArray = new byte[1024];
|
||||
int bytesRead;
|
||||
|
||||
// Update the MessageDigest with the file's data
|
||||
while ((bytesRead = fis.read(byteArray)) != -1) {
|
||||
digest.update(byteArray, 0, bytesRead);
|
||||
}
|
||||
|
||||
fis.close();
|
||||
|
||||
// Get the hash's bytes
|
||||
byte[] hashBytes = digest.digest();
|
||||
|
||||
// Convert the hash's bytes to a hex string
|
||||
StringBuilder hexString = new StringBuilder();
|
||||
for (byte b : hashBytes) {
|
||||
String hex = Integer.toHexString(0xff & b);
|
||||
if (hex.length() == 1) hexString.append('0');
|
||||
hexString.append(hex);
|
||||
}
|
||||
|
||||
return hexString.toString();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
104
src/main/java/me/trouper/sentinel/utils/FileUtils.java
Normal file
104
src/main/java/me/trouper/sentinel/utils/FileUtils.java
Normal file
@@ -0,0 +1,104 @@
|
||||
package me.trouper.sentinel.utils;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.FileValidationUtils;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.server.functions.Randomizer;
|
||||
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.dataFolder(), folderName);
|
||||
return folder.exists() && folder.isDirectory();
|
||||
}
|
||||
|
||||
public static void createFolder(String folderName) {
|
||||
File folder = new File(Sentinel.dataFolder(), folderName);
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public static String createNBTLog(String contents) {
|
||||
ServerUtils.verbose("FileUtils: Creating NBT log");
|
||||
String fileName = "nbt_log-" + Randomizer.generateID();
|
||||
|
||||
File dataFolder = Sentinel.dataFolder();
|
||||
|
||||
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.verbose("FileUtils: Creating NBT log");
|
||||
|
||||
String item = i.getType().name().toLowerCase() + i.getItemMeta().getAsString();
|
||||
|
||||
String fileName = "nbt_log-" + Randomizer.generateID();
|
||||
|
||||
File dataFolder = Sentinel.dataFolder();
|
||||
|
||||
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.dataFolder() + "/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;
|
||||
}
|
||||
}
|
||||
306
src/main/java/me/trouper/sentinel/utils/ItemUtils.java
Normal file
306
src/main/java/me/trouper/sentinel/utils/ItemUtils.java
Normal file
@@ -0,0 +1,306 @@
|
||||
package me.trouper.sentinel.utils;
|
||||
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Container;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
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;
|
||||
|
||||
import static org.bukkit.enchantments.Enchantment.MENDING;
|
||||
|
||||
public class ItemUtils {
|
||||
|
||||
public static 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;
|
||||
}
|
||||
|
||||
public static Inventory getSubInventory(ItemStack containerItem) {
|
||||
ServerUtils.verbose("NBT: GetSubInv checking item: " + containerItem);
|
||||
if (containerItem.getItemMeta() instanceof BlockStateMeta blockStateMeta) {
|
||||
ServerUtils.verbose("NBT: subInv has (is) blockStateMeta: " + blockStateMeta);
|
||||
BlockState blockState = blockStateMeta.getBlockState();
|
||||
if (blockState instanceof Container) {
|
||||
ServerUtils.verbose("NBT: subInv has (is) container: " + (Container) blockState);
|
||||
return ((Container) blockState).getInventory();
|
||||
}
|
||||
}
|
||||
ServerUtils.verbose("NBT: Inv is null: " + containerItem);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean containerPasses(Inventory inventory) {
|
||||
for (ItemStack itemStack : inventory.getContents()) {
|
||||
if (itemStack == null || itemStack.getType().isAir()) continue;
|
||||
if (!itemPasses(itemStack)) {
|
||||
ServerUtils.verbose("NBT: No pass C(I)");
|
||||
return false;
|
||||
}
|
||||
if (!isContainer(itemStack)) continue;
|
||||
|
||||
Inventory subInventory = getSubInventory(itemStack);
|
||||
if (!containerPasses(subInventory)) {
|
||||
ServerUtils.verbose("NBT: No pass C(R)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ServerUtils.verbose("NBT: Item passes recursion check.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static boolean itemPasses(ItemStack i) {
|
||||
ServerUtils.verbose("NBT: Checking if item passes: " + i.getItemMeta());
|
||||
if (i.getItemMeta() == null) {
|
||||
ServerUtils.verbose("NBT: Item passes because of no meta");
|
||||
return true;
|
||||
}
|
||||
ServerUtils.verbose("NBT: Item meta isn't null");
|
||||
ItemMeta meta = i.getItemMeta();
|
||||
Inventory inv = getSubInventory(i);
|
||||
if (inv != null) {
|
||||
ServerUtils.verbose("NBT: Item has a SubInv: " + inv);
|
||||
if (!containerPasses(inv)) {
|
||||
ServerUtils.verbose("NBT: No pass C");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!Sentinel.nbtConfig.allowName && meta.hasDisplayName()) {
|
||||
ServerUtils.verbose("NBT: No pass N");
|
||||
return false;
|
||||
}
|
||||
if (!Sentinel.nbtConfig.allowLore && meta.hasLore()) {
|
||||
ServerUtils.verbose("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.verbose("NBT: No pass P");
|
||||
return false;
|
||||
}
|
||||
if (!Sentinel.nbtConfig.allowAttributes && meta.hasAttributeModifiers()) {
|
||||
ServerUtils.verbose("NBT: No pass A");
|
||||
return false;
|
||||
}
|
||||
if (Sentinel.nbtConfig.globalMaxEnchant != 0 && hasIllegalEnchants(i)) {
|
||||
ServerUtils.verbose("NBT: No pass E");
|
||||
return false;
|
||||
}
|
||||
ServerUtils.verbose("NBT: All checks passed");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean hasIllegalEnchants(ItemStack i) {
|
||||
ServerUtils.verbose("NBT: Checking for illegal enchants");
|
||||
|
||||
if (i.hasItemMeta() && i.getItemMeta().hasEnchants()) {
|
||||
final ItemMeta meta = i.getItemMeta();
|
||||
final Map<Enchantment, Integer> enchantments = meta.getEnchants();
|
||||
|
||||
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
||||
Enchantment enchantment = entry.getKey();
|
||||
int level = entry.getValue();
|
||||
|
||||
if (level > Sentinel.nbtConfig.globalMaxEnchant || isOverLimit(enchantment, level)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isOverLimit(Enchantment enchantment, int level) {
|
||||
int maxLevel = Sentinel.nbtConfig.globalMaxEnchant; // Default to global max enchant
|
||||
|
||||
|
||||
// Old code here
|
||||
if (enchantment.equals(MENDING)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxMending;
|
||||
} else if (enchantment.equals(Enchantment.UNBREAKING)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxUnbreaking;
|
||||
} else if (enchantment.equals(Enchantment.VANISHING_CURSE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxVanishing;
|
||||
} else if (enchantment.equals(Enchantment.BINDING_CURSE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxCurseOfBinding;
|
||||
} else if (enchantment.equals(Enchantment.AQUA_AFFINITY)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxAquaAffinity;
|
||||
} else if (enchantment.equals(Enchantment.PROTECTION)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxProtection;
|
||||
} else if (enchantment.equals(Enchantment.BLAST_PROTECTION)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxBlastProtection;
|
||||
} else if (enchantment.equals(Enchantment.DEPTH_STRIDER)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxDepthStrider;
|
||||
} else if (enchantment.equals(Enchantment.FEATHER_FALLING)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxFeatherFalling;
|
||||
} else if (enchantment.equals(Enchantment.FIRE_PROTECTION)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxFireProtection;
|
||||
} else if (enchantment.equals(Enchantment.FROST_WALKER)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxFrostWalker;
|
||||
} else if (enchantment.equals(Enchantment.PROJECTILE_PROTECTION)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxProjectileProtection;
|
||||
} else if (enchantment.equals(Enchantment.RESPIRATION)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxRespiration;
|
||||
} else if (enchantment.equals(Enchantment.SOUL_SPEED)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxSoulSpeed;
|
||||
} else if (enchantment.equals(Enchantment.THORNS)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxThorns;
|
||||
} else if (enchantment.equals(Enchantment.SWEEPING_EDGE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxSweepingEdge;
|
||||
} else if (enchantment.equals(Enchantment.SWIFT_SNEAK)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxSwiftSneak;
|
||||
} else if (enchantment.equals(Enchantment.BANE_OF_ARTHROPODS)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxBaneOfArthropods;
|
||||
} else if (enchantment.equals(Enchantment.FIRE_ASPECT)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxFireAspect;
|
||||
} else if (enchantment.equals(Enchantment.LOOTING)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxLooting;
|
||||
} else if (enchantment.equals(Enchantment.IMPALING)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxImpaling;
|
||||
} else if (enchantment.equals(Enchantment.KNOCKBACK)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxKnockback;
|
||||
} else if (enchantment.equals(Enchantment.SHARPNESS)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxSharpness;
|
||||
} else if (enchantment.equals(Enchantment.SMITE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxSmite;
|
||||
} else if (enchantment.equals(Enchantment.CHANNELING)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxChanneling;
|
||||
} else if (enchantment.equals(Enchantment.FLAME)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxFlame;
|
||||
} else if (enchantment.equals(Enchantment.INFINITY)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxInfinity;
|
||||
} else if (enchantment.equals(Enchantment.LOYALTY)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxLoyalty;
|
||||
} else if (enchantment.equals(Enchantment.RIPTIDE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxRiptide;
|
||||
} else if (enchantment.equals(Enchantment.MULTISHOT)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxMultishot;
|
||||
} else if (enchantment.equals(Enchantment.PIERCING)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxPiercing;
|
||||
} else if (enchantment.equals(Enchantment.POWER)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxPower;
|
||||
} else if (enchantment.equals(Enchantment.PUNCH)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxPunch;
|
||||
} else if (enchantment.equals(Enchantment.QUICK_CHARGE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxQuickCharge;
|
||||
} else if (enchantment.equals(Enchantment.EFFICIENCY)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxEfficiency;
|
||||
} else if (enchantment.equals(Enchantment.FORTUNE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxFortune;
|
||||
} else if (enchantment.equals(Enchantment.LUCK_OF_THE_SEA)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxLuckOfTheSea;
|
||||
} else if (enchantment.equals(Enchantment.LURE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxLure;
|
||||
} else if (enchantment.equals(Enchantment.SILK_TOUCH)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxSilkTouch;
|
||||
}
|
||||
|
||||
return level > maxLevel;
|
||||
}
|
||||
|
||||
/*
|
||||
public static boolean isOverLimit(Enchantment enchantment, int level) {
|
||||
int maxLevel = Sentinel.nbtConfig.globalMaxEnchant; // Default to global max enchant
|
||||
|
||||
// New code here
|
||||
switch (enchantment.getKey().getKey()) {
|
||||
case "mending" -> maxLevel = Sentinel.nbtConfig.maxMending;
|
||||
case "unbreaking" -> maxLevel = Sentinel.nbtConfig.maxUnbreaking;
|
||||
}
|
||||
|
||||
|
||||
// Old code here
|
||||
if (enchantment.equals(MENDING)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxMending;
|
||||
} else if (enchantment.equals(Enchantment.UNBREAKING)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxUnbreaking;
|
||||
} else if (enchantment.equals(Enchantment.VANISHING_CURSE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxVanishing;
|
||||
} else if (enchantment.equals(Enchantment.BINDING_CURSE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxCurseOfBinding;
|
||||
} else if (enchantment.equals(Enchantment.AQUA_AFFINITY)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxAquaAffinity;
|
||||
} else if (enchantment.equals(Enchantment.PROTECTION)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxProtection;
|
||||
} else if (enchantment.equals(Enchantment.BLAST_PROTECTION)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxBlastProtection;
|
||||
} else if (enchantment.equals(Enchantment.DEPTH_STRIDER)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxDepthStrider;
|
||||
} else if (enchantment.equals(Enchantment.FEATHER_FALLING)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxFeatherFalling;
|
||||
} else if (enchantment.equals(Enchantment.FIRE_PROTECTION)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxFireProtection;
|
||||
} else if (enchantment.equals(Enchantment.FROST_WALKER)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxFrostWalker;
|
||||
} else if (enchantment.equals(Enchantment.PROJECTILE_PROTECTION)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxProjectileProtection;
|
||||
} else if (enchantment.equals(Enchantment.RESPIRATION)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxRespiration;
|
||||
} else if (enchantment.equals(Enchantment.SOUL_SPEED)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxSoulSpeed;
|
||||
} else if (enchantment.equals(Enchantment.THORNS)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxThorns;
|
||||
} else if (enchantment.equals(Enchantment.SWEEPING_EDGE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxSweepingEdge;
|
||||
} else if (enchantment.equals(Enchantment.SWIFT_SNEAK)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxSwiftSneak;
|
||||
} else if (enchantment.equals(Enchantment.BANE_OF_ARTHROPODS)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxBaneOfArthropods;
|
||||
} else if (enchantment.equals(Enchantment.FIRE_ASPECT)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxFireAspect;
|
||||
} else if (enchantment.equals(Enchantment.LOOTING)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxLooting;
|
||||
} else if (enchantment.equals(Enchantment.IMPALING)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxImpaling;
|
||||
} else if (enchantment.equals(Enchantment.KNOCKBACK)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxKnockback;
|
||||
} else if (enchantment.equals(Enchantment.SHARPNESS)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxSharpness;
|
||||
} else if (enchantment.equals(Enchantment.SMITE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxSmite;
|
||||
} else if (enchantment.equals(Enchantment.CHANNELING)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxChanneling;
|
||||
} else if (enchantment.equals(Enchantment.FLAME)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxFlame;
|
||||
} else if (enchantment.equals(Enchantment.INFINITY)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxInfinity;
|
||||
} else if (enchantment.equals(Enchantment.LOYALTY)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxLoyalty;
|
||||
} else if (enchantment.equals(Enchantment.RIPTIDE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxRiptide;
|
||||
} else if (enchantment.equals(Enchantment.MULTISHOT)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxMultishot;
|
||||
} else if (enchantment.equals(Enchantment.PIERCING)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxPiercing;
|
||||
} else if (enchantment.equals(Enchantment.POWER)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxPower;
|
||||
} else if (enchantment.equals(Enchantment.PUNCH)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxPunch;
|
||||
} else if (enchantment.equals(Enchantment.QUICK_CHARGE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxQuickCharge;
|
||||
} else if (enchantment.equals(Enchantment.EFFICIENCY)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxEfficiency;
|
||||
} else if (enchantment.equals(Enchantment.FORTUNE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxFortune;
|
||||
} else if (enchantment.equals(Enchantment.LUCK_OF_THE_SEA)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxLuckOfTheSea;
|
||||
} else if (enchantment.equals(Enchantment.LURE)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxLure;
|
||||
} else if (enchantment.equals(Enchantment.SILK_TOUCH)) {
|
||||
maxLevel = Sentinel.nbtConfig.maxSilkTouch;
|
||||
}
|
||||
|
||||
return level > maxLevel;
|
||||
}
|
||||
*/
|
||||
}
|
||||
115
src/main/java/me/trouper/sentinel/utils/MathUtils.java
Normal file
115
src/main/java/me/trouper/sentinel/utils/MathUtils.java
Normal file
@@ -0,0 +1,115 @@
|
||||
package me.trouper.sentinel.utils;
|
||||
|
||||
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 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 SHA256(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;
|
||||
}
|
||||
}
|
||||
|
||||
public static String MD5(String input) {
|
||||
try {
|
||||
|
||||
MessageDigest digest = MessageDigest.getInstance("MD5");
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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()];
|
||||
}
|
||||
}
|
||||
14
src/main/java/me/trouper/sentinel/utils/PlayerUtils.java
Normal file
14
src/main/java/me/trouper/sentinel/utils/PlayerUtils.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package me.trouper.sentinel.utils;
|
||||
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PlayerUtils {
|
||||
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);
|
||||
}
|
||||
}
|
||||
105
src/main/java/me/trouper/sentinel/utils/ServerUtils.java
Normal file
105
src/main/java/me/trouper/sentinel/utils/ServerUtils.java
Normal file
@@ -0,0 +1,105 @@
|
||||
package me.trouper.sentinel.utils;
|
||||
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
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.verbose("Getting scheduler");
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(Sentinel.getInstance(), () -> {
|
||||
try {
|
||||
ServerUtils.verbose("Attempting to run command...");
|
||||
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), command);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
},1);
|
||||
}
|
||||
|
||||
public static void verbose(String message) {
|
||||
if (Sentinel.mainConfig.debugMode) {
|
||||
String log = "[Sentinel] [DEBUG]: " + message;
|
||||
Sentinel.log.info(log);
|
||||
for (Player trustedPlayer : Bukkit.getOnlinePlayers()) {
|
||||
if (PlayerUtils.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);
|
||||
}
|
||||
}
|
||||
115
src/main/java/me/trouper/sentinel/utils/Text.java
Normal file
115
src/main/java/me/trouper/sentinel/utils/Text.java
Normal file
@@ -0,0 +1,115 @@
|
||||
package me.trouper.sentinel.utils;
|
||||
|
||||
|
||||
import me.trouper.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 removeColors(String input) {
|
||||
return input.replaceAll("§[0-9a-fr]", "");
|
||||
}
|
||||
|
||||
public static String regexHighlighter(String input, String regex, String startString, String endString) {
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
|
||||
StringBuffer result = new StringBuffer();
|
||||
|
||||
while (matcher.find()) {
|
||||
matcher.appendReplacement(result, startString + matcher.group() + endString);
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package me.trouper.sentinel.utils.trees;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ConsoleFormatter {
|
||||
|
||||
public static String format(Node node) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
formatNode(sb, node, 0);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static void formatNode(StringBuilder sb, Node node, int level) {
|
||||
if (level == 0) {
|
||||
sb.append("]==-- ").append(node.title).append(" --==[\n");
|
||||
} else {
|
||||
sb.append(node.title).append("\n");
|
||||
}
|
||||
|
||||
for (String text : node.texts) {
|
||||
text = text.replace("<hs>"," > ");
|
||||
text = text.replace("<he>"," < ");
|
||||
if (level == 0) {
|
||||
sb.append(text).append("\n");
|
||||
} else {
|
||||
sb.append(" ➥ ").append(text).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry : node.values.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
key = key.replace("<hs>"," > ");
|
||||
key = key.replace("<he>"," < ");
|
||||
value = value.replace("<hs>"," > ");
|
||||
value = value.replace("<he>"," < ");
|
||||
if (level == 0) {
|
||||
sb.append(key).append(": ").append(value).append("\n");
|
||||
} else {
|
||||
sb.append(" ➥ ").append(key).append(": ").append(value).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry : node.fields.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
key = key.replace("<hs>"," > ");
|
||||
key = key.replace("<he>"," < ");
|
||||
value = value.replace("<hs>"," > ");
|
||||
value = value.replace("<he>"," < ");
|
||||
if (level == 0) {
|
||||
sb.append(key).append(":\n ").append(value).append("\n");
|
||||
} else {
|
||||
sb.append(" ➥ ").append(key).append(":\n ").append(value).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (Node child : node.children) {
|
||||
formatNode(sb, child, level + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package me.trouper.sentinel.utils.trees;
|
||||
|
||||
import io.github.itzispyder.pdk.utils.SchedulerUtils;
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordEmbed;
|
||||
import io.github.itzispyder.pdk.utils.discord.DiscordWebhook;
|
||||
import me.trouper.sentinel.Sentinel;
|
||||
import me.trouper.sentinel.data.Emojis;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class EmbedFormatter {
|
||||
|
||||
public static void sendEmbed(DiscordEmbed embed) {
|
||||
sendEmbed(embed,Sentinel.mainConfig.plugin.webhook);
|
||||
}
|
||||
|
||||
public static boolean sendEmbed(DiscordEmbed embed, String spec) {
|
||||
DiscordWebhook webhook = new DiscordWebhook("Sentinel Anti-Nuke Webhook Logger", "https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/1epkvziv.png","", false, embed);
|
||||
AtomicBoolean success = new AtomicBoolean(false);
|
||||
SchedulerUtils.later(0,()->{
|
||||
try {
|
||||
webhook.send(spec);
|
||||
} catch (IOException e) {
|
||||
Sentinel.log.warning(e.getMessage());
|
||||
success.set(false);
|
||||
return;
|
||||
}
|
||||
success.set(true);
|
||||
});
|
||||
return success.get();
|
||||
}
|
||||
|
||||
public static DiscordEmbed format(Node node) {
|
||||
DiscordEmbed.Builder eb = new DiscordEmbed.Builder();
|
||||
StringBuilder desc = new StringBuilder();
|
||||
|
||||
formatNode(eb, node, desc,0);
|
||||
eb.color(0xFFAB4D);
|
||||
return eb.desc(desc.toString()).build();
|
||||
}
|
||||
|
||||
private static void formatNode(DiscordEmbed.Builder eb, Node node, StringBuilder desc, int level) {
|
||||
eb.author("Sentinel | Anti-Nuke","https://trouper.me/sentinel",null);
|
||||
if (level == 0) {
|
||||
eb.title("Incoming from server: %s".formatted(Sentinel.mainConfig.plugin.identifier));
|
||||
} else {
|
||||
desc.repeat(Emojis.space,level - 1).append("**").append(node.title).append("**\n");
|
||||
}
|
||||
|
||||
for (String text : node.texts) {
|
||||
text = text.replace("<hs>"," > ");
|
||||
text = text.replace("<he>"," < ");
|
||||
if (level == 0) {
|
||||
desc.append(text).append("\n");
|
||||
} else {
|
||||
desc.repeat(Emojis.space,level - 1).append(Emojis.rightSort).append(text).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry : node.values.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
key = key.replace("<hs>"," > ");
|
||||
key = key.replace("<he>"," < ");
|
||||
value = value.replace("<hs>"," > ");
|
||||
value = value.replace("<he>"," < ");
|
||||
if (level == 0) {
|
||||
desc.append(key).append(": `").append(value).append("`\n");
|
||||
} else {
|
||||
desc.repeat(Emojis.space,level - 1).append(Emojis.rightSort).append(key).append(": `").append(value).append("`\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry : node.fields.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
key = key.replace("<hs>"," > ");
|
||||
key = key.replace("<he>"," < ");
|
||||
value = value.replace("<hs>"," > ");
|
||||
value = value.replace("<he>"," < ");
|
||||
if (level == 0) {
|
||||
desc.append("**").append(key).append("**:\n `").append(value).append("`\n");
|
||||
} else {
|
||||
desc.repeat(Emojis.space,level - 1).append(Emojis.rightArrow).append("**").append(key).append("**:\n `").append(value).append("`\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (Node child : node.children) {
|
||||
formatNode(eb, child, desc,level + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package me.trouper.sentinel.utils.trees;
|
||||
|
||||
import me.trouper.sentinel.utils.Text;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class HoverFormatter {
|
||||
|
||||
public static String format(Node node) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
formatNode(sb, node, 0);
|
||||
return Text.color(sb.toString());
|
||||
}
|
||||
|
||||
private static void formatNode(StringBuilder sb, Node node, int level) {
|
||||
if (level == 0) {
|
||||
//sb.append("B3B3B]򊆘=򯅳=C8C8C-&#A7A7A7- &6&l").append(node.title).append("&r &#A7A7A7-C8C8C-򯅳=򊆘=B3B3B[\n");
|
||||
sb.append("&8]==-- &6&l").append(node.title).append("&r &8--==[\n&r");
|
||||
} else {
|
||||
sb.append("&f&l").append(node.title).append("\n");
|
||||
}
|
||||
|
||||
for (String text : node.texts) {
|
||||
text = text.replace("<hs>","&e&n");
|
||||
text = text.replace("<he>","&r&b");
|
||||
if (level == 0) {
|
||||
sb.append("&7").append(text).append("\n");
|
||||
} else {
|
||||
sb.append(" &8&l➥&r &7").append(text).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry : node.values.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
key = key.replace("<hs>","&e&n");
|
||||
key = key.replace("<he>","&r&b");
|
||||
value = value.replace("<hs>","&e&n");
|
||||
value = value.replace("<he>","&r&b");
|
||||
if (level == 0) {
|
||||
sb.append("&7").append(key).append("&8: &b").append(value).append("\n&r");
|
||||
} else {
|
||||
sb.append(" &8&l➥&r &7").append(key).append("&8: &b").append(value).append("\n&r");
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry : node.fields.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
key = key.replace("<hs>","&e&n");
|
||||
key = key.replace("<he>","&r&b");
|
||||
value = value.replace("<hs>","&e&n");
|
||||
value = value.replace("<he>","&r&b");
|
||||
if (level == 0) {
|
||||
sb.append("&7").append(key).append("&8:\n&b ").append(value).append("\n&r");
|
||||
} else {
|
||||
sb.append(" &8&l➥&r &7").append(key).append("&8:\n &b ").append(value).append("\n&r");
|
||||
}
|
||||
}
|
||||
|
||||
for (Node child : node.children) {
|
||||
formatNode(sb, child, level + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
39
src/main/java/me/trouper/sentinel/utils/trees/Node.java
Normal file
39
src/main/java/me/trouper/sentinel/utils/trees/Node.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package me.trouper.sentinel.utils.trees;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Node {
|
||||
String title;
|
||||
List<String> texts;
|
||||
Map<String, String> values;
|
||||
Map<String, String> fields;
|
||||
List<Node> children;
|
||||
|
||||
public Node(String title) {
|
||||
this.title = title;
|
||||
this.texts = new ArrayList<>();
|
||||
this.values = new HashMap<>();
|
||||
this.fields = new HashMap<>();
|
||||
this.children = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addTextLine(String text) {
|
||||
this.texts.add(text);
|
||||
}
|
||||
|
||||
public void addKeyValue(String name, String value) {
|
||||
this.values.put(name, value);
|
||||
}
|
||||
|
||||
public void addField(String title, String value) {
|
||||
this.fields.put(title,value);
|
||||
}
|
||||
|
||||
public void addChild(Node child) {
|
||||
this.children.add(child);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user