NBT log FINALLLYYYY completed :OOOOOO (Don't know why it logs twice still)
This commit is contained in:
@@ -2,8 +2,8 @@ plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'io.github.thetrouper'
|
||||
version = '0.0.2'
|
||||
group = project.group
|
||||
version = project.version
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@@ -18,7 +18,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
||||
compileOnly "org.spigotmc:spigot-api:${project.mc_version}-R0.1-SNAPSHOT"
|
||||
}
|
||||
|
||||
def targetJavaVersion = 16
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
# Plugin
|
||||
group = 'io.github.thetrouper'
|
||||
version = 0.0.3
|
||||
|
||||
# Minecraft
|
||||
mc_version = 1.19.4
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -67,6 +68,7 @@ public final class Sentinel extends JavaPlugin {
|
||||
|
||||
// Scheduled timers
|
||||
Bukkit.getScheduler().runTaskTimer(this, AntiSpam::decayHeat,0, 20);
|
||||
Bukkit.getScheduler().runTaskTimer(this, ProfanityFilter::decayScore,0,1200);
|
||||
log.info("\n" +
|
||||
" ____ __ ___ \n" +
|
||||
"/\\ _`\\ /\\ \\__ __ /\\_ \\ \n" +
|
||||
@@ -86,7 +88,9 @@ public final class Sentinel extends JavaPlugin {
|
||||
// Plugin shutdown logic
|
||||
log.info("Sentinel has disabled! (" + getDescription().getVersion() + ") Your server is now no longer protected!");
|
||||
}
|
||||
|
||||
public static File getDF() {
|
||||
return getInstance().getDataFolder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player is trusted.
|
||||
|
||||
@@ -4,15 +4,18 @@
|
||||
|
||||
package io.github.thetrouper.sentinel.commands;
|
||||
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.Config;
|
||||
import io.github.thetrouper.sentinel.discord.WebhookSender;
|
||||
import io.github.thetrouper.sentinel.exceptions.CmdExHandler;
|
||||
import io.github.thetrouper.sentinel.server.functions.AntiSpam;
|
||||
import io.github.thetrouper.sentinel.server.util.FileUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.TextUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.*;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -35,7 +38,6 @@ public class InfoCommand implements TabExecutor {
|
||||
case "webhooktest" -> {
|
||||
sender.sendMessage(TextUtils.prefix("Testing the webhook..."));
|
||||
WebhookSender.sendEmbedWarning(sender.getName(), "/sentinel webhooktest",true,true,false);
|
||||
WebhookSender.sendHelloWorldEmbed();
|
||||
}
|
||||
case "checkheat" -> {
|
||||
sender.sendMessage(TextUtils.prefix("Your heat is §e" + AntiSpam.heatMap.get(sender).toString()));
|
||||
@@ -44,6 +46,16 @@ public class InfoCommand implements TabExecutor {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "say " + " ]=- Sentinel Anti-Grief -=[ You have been banned for attempting a dangerous command. Contact an administrator if you believe this to be a mistake.");
|
||||
ServerUtils.sendCommand("say test complete!");
|
||||
}
|
||||
case "pastebintest" -> {
|
||||
WebhookSender.sendTestEmbed();
|
||||
}
|
||||
case "filetest" -> {
|
||||
sender.sendMessage(TextUtils.prefix("testing file stuff"));
|
||||
if (!FileUtils.folderExists("/LoggedNBT")) {
|
||||
FileUtils.createFolder("/LoggedNBT");
|
||||
}
|
||||
FileUtils.createNBTLog("{[IDFK MINECRAFT NBT LMAO]}; [][]\\ima just fill this with text to test it. ()()() ||||| &^%$#@!@#$%^&*(){}|:\"\"<><>");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
@@ -61,7 +73,9 @@ public class InfoCommand implements TabExecutor {
|
||||
"debugmode",
|
||||
"webhooktest",
|
||||
"checkheat",
|
||||
"dispatchtest"
|
||||
"dispatchtest",
|
||||
"pastebintest",
|
||||
"filetest"
|
||||
}).build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ public abstract class Config {
|
||||
}
|
||||
}
|
||||
public static String webhook;
|
||||
public static String pbapikey;
|
||||
public static List<String> trustedPlayers;
|
||||
public static boolean blockSpecificCommands;
|
||||
public static boolean preventNBT;
|
||||
@@ -49,6 +50,8 @@ public abstract class Config {
|
||||
public static int blockHeat;
|
||||
public static int punishHeat;
|
||||
public static String punishSpamCommand;
|
||||
public static String clearChatCommand;
|
||||
public static boolean clearChat;
|
||||
public static boolean logSpam;
|
||||
public static boolean antiSwearEnabled;
|
||||
public static int lowScore;
|
||||
@@ -60,6 +63,7 @@ public abstract class Config {
|
||||
public static String swearPunishCommand;
|
||||
public static boolean slurInstaPunish;
|
||||
public static String slurPunishCommand;
|
||||
public static Integer scoreDecay;
|
||||
public static List<String> swearWhitelist;
|
||||
public static List<String> swearBlacklist;
|
||||
public static List<String> slurs;
|
||||
@@ -71,6 +75,7 @@ public abstract class Config {
|
||||
Sentinel.prefix = config.getString("config.plugin.prefix");
|
||||
// antiNuke
|
||||
webhook = config.getString("config.plugin.webhook");
|
||||
pbapikey = config.getString("config.plugin.pbapikey");
|
||||
trustedPlayers = config.getStringList("config.plugin.trusted");
|
||||
blockSpecificCommands = config.getBoolean("config.plugin.block-specific");
|
||||
preventNBT = config.getBoolean("config.plugin.prevent-nbt");
|
||||
@@ -93,23 +98,27 @@ public abstract class Config {
|
||||
blockHeat = config.getInt("config.chat.anti-spam.block-heat");
|
||||
punishHeat = config.getInt("config.chat.anti-spam.punish-heat");
|
||||
punishSpamCommand = config.getString("config.chat.anti-spam.punish-command");
|
||||
clearChat = config.getBoolean("config.chat.anti-spam.clear-chat");
|
||||
clearChatCommand = config.getString("config.chat.anti-spam.clear-chat-command");
|
||||
logSpam = config.getBoolean("config.chat.anti-swear.log-swear");
|
||||
// antiSwear
|
||||
antiSwearEnabled = config.getBoolean("config.chat.anti-swear.enabled");
|
||||
lowScore = config.getInt("config.chat.anti-swear.low-gain");
|
||||
mediumLowScore = config.getInt("config.chat.anti-swear.medium-low-gain");
|
||||
mediumScore = config.getInt("config.chat.anti-swear.medium-gain");
|
||||
mediumHighScore = config.getInt("config.chat.anti-swear.medium-high-gain");
|
||||
highScore = config.getInt("config.chat.anti-swear.high-gain");
|
||||
lowScore = config.getInt("config.chat.anti-swear.low-score");
|
||||
mediumLowScore = config.getInt("config.chat.anti-swear.medium-low-score");
|
||||
mediumScore = config.getInt("config.chat.anti-swear.medium-score");
|
||||
mediumHighScore = config.getInt("config.chat.anti-swear.medium-high-score");
|
||||
highScore = config.getInt("config.chat.anti-swear.high-score");
|
||||
punishScore = config.getInt("config.chat.anti-swear.punish-score");
|
||||
swearPunishCommand = config.getString("config.chat.anti-swear.punish-command");
|
||||
slurInstaPunish = config.getBoolean("config.chat.anti-swear.slur-insta-punish");
|
||||
slurPunishCommand = config.getString("config.chat.anti-swear.slur-command");
|
||||
scoreDecay = config.getInt("config.chat.anti-swear.score-decay");
|
||||
swearWhitelist = config.getStringList("config.chat.anti-swear.whitelisted");
|
||||
swearBlacklist = config.getStringList("config.chat.anti-swear.blacklisted");
|
||||
slurs = config.getStringList("config.chat.anti-swear.slurs");
|
||||
leetPatterns = loadLeetPatterns();
|
||||
logSwear = config.getBoolean("config.chat.anti-swear.log-swear");
|
||||
|
||||
}
|
||||
private static Map<String, String> loadLeetPatterns() {
|
||||
Map<String, String> dictionary = new HashMap<>();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.github.thetrouper.sentinel.data;
|
||||
|
||||
public class Emojis {
|
||||
public static String space = "<:space:1125871914334818446>";
|
||||
public static String rightSort = "<:rightSort:1125785837255270520>";
|
||||
public static String arrowRight = "<:arrowRight:1125785471520354304>";
|
||||
public static String rightDoubleArrow = "<:rightDoubleArrow:1125785800353783868>";
|
||||
|
||||
@@ -2,10 +2,10 @@ package io.github.thetrouper.sentinel.discord;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.awt.Color;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Array;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -23,6 +23,7 @@ public class DiscordWebhook {
|
||||
private String avatarUrl;
|
||||
private boolean tts;
|
||||
private List<EmbedObject> embeds = new ArrayList<>();
|
||||
private List<Attachment> attachments = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructs a new DiscordWebhook instance
|
||||
@@ -53,9 +54,13 @@ public class DiscordWebhook {
|
||||
this.embeds.add(embed);
|
||||
}
|
||||
|
||||
public void addAttachment(String filename, String content) {
|
||||
attachments.add(new Attachment(filename, content));
|
||||
}
|
||||
|
||||
public void execute() throws IOException {
|
||||
if (this.content == null && this.embeds.isEmpty()) {
|
||||
throw new IllegalArgumentException("Set content or add at least one EmbedObject");
|
||||
if (this.content == null && this.embeds.isEmpty() && this.attachments.isEmpty()) {
|
||||
throw new IllegalArgumentException("Set content, add at least one EmbedObject, or add an attachment");
|
||||
}
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
@@ -139,6 +144,19 @@ public class DiscordWebhook {
|
||||
json.put("embeds", embedObjects.toArray());
|
||||
}
|
||||
|
||||
if (!this.attachments.isEmpty()) {
|
||||
List<JSONObject> attachmentObjects = new ArrayList<>();
|
||||
|
||||
for (Attachment attachment : this.attachments) {
|
||||
JSONObject attachmentObject = new JSONObject();
|
||||
attachmentObject.put("name", attachment.getFilename());
|
||||
attachmentObject.put("content", attachment.getContent());
|
||||
attachmentObjects.add(attachmentObject);
|
||||
}
|
||||
|
||||
json.put("attachments", attachmentObjects.toArray());
|
||||
}
|
||||
|
||||
URL url = new URL(this.url);
|
||||
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
|
||||
connection.addRequestProperty("Content-Type", "application/json");
|
||||
@@ -339,6 +357,24 @@ public class DiscordWebhook {
|
||||
}
|
||||
}
|
||||
|
||||
private class Attachment {
|
||||
private String filename;
|
||||
private String content;
|
||||
|
||||
private Attachment(String filename, String content) {
|
||||
this.filename = filename;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
private String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
private String getContent() {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
private class JSONObject {
|
||||
|
||||
private final HashMap<String, Object> map = new HashMap<>();
|
||||
|
||||
@@ -1,40 +1,125 @@
|
||||
package io.github.thetrouper.sentinel.discord;
|
||||
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.commands.InfoCommand;
|
||||
import io.github.thetrouper.sentinel.data.Config;
|
||||
import io.github.thetrouper.sentinel.data.Emojis;
|
||||
import io.github.thetrouper.sentinel.discord.DiscordWebhook;
|
||||
import io.github.thetrouper.sentinel.server.functions.ProfanityFilter;
|
||||
import io.github.thetrouper.sentinel.server.util.FileUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.TextUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class WebhookSender {
|
||||
|
||||
public static void sendHelloWorldEmbed() {
|
||||
public static void sendTestEmbed() {
|
||||
String webhookUrl = Config.webhook;
|
||||
|
||||
// Create a new DiscordWebhook instance
|
||||
DiscordWebhook webhook = new DiscordWebhook(webhookUrl);
|
||||
|
||||
// Create an EmbedObject and set its properties
|
||||
DiscordWebhook.EmbedObject embed = new DiscordWebhook.EmbedObject()
|
||||
.setDescription("Hello, World!")
|
||||
.setAuthor("Test Success!", "", "")
|
||||
.setDescription("eeeee")
|
||||
.setColor(Color.GREEN);
|
||||
|
||||
// Add the EmbedObject to the webhook
|
||||
webhook.addEmbed(embed);
|
||||
|
||||
webhook.addAttachment("text.txt","Text Here hehehehaw!");
|
||||
try {
|
||||
// Execute the webhook
|
||||
webhook.execute();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendSpamLog(Player player, String message1, String message2, int finalHeat, boolean chatCleared) {
|
||||
ServerUtils.sendDebugMessage("Creating spamLog Webhook...");
|
||||
DiscordWebhook webhook = new DiscordWebhook(Config.webhook);
|
||||
webhook.setAvatarUrl("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png");
|
||||
webhook.setUsername("Sentinel Anti-Nuke | Logs");
|
||||
DiscordWebhook.EmbedObject embed = new DiscordWebhook.EmbedObject()
|
||||
.setAuthor("Anti-Spam Punishment","","")
|
||||
.setTitle("Punish Report:")
|
||||
.setDescription(
|
||||
Emojis.rightSort + "Player: " + player.getName() + " " + Emojis.target + "\\n" +
|
||||
Emojis.space + Emojis.arrowRight + "Heat: `" + finalHeat + "/" + Config.punishHeat + "`\\n" +
|
||||
Emojis.space + Emojis.arrowRight + "UUID: `" + player.getUniqueId() + "`\\n" +
|
||||
Emojis.rightSort + "Executed: " + Config.punishSpamCommand + " " + Emojis.mute + "\\n" +
|
||||
Emojis.space + Emojis.arrowRight + "Chat Cleared: " + successOrFail(chatCleared) + "\\n"
|
||||
)
|
||||
.addField("Previous Message", "||" + message1 + "|| " + Emojis.activity, false)
|
||||
.addField("Current Message", "||" + message2 + "|| " + Emojis.alarm, false)
|
||||
.setColor(Color.RED)
|
||||
.setThumbnail("https://crafatar.com/avatars/" + player.getUniqueId() + "?size=64&&overlay");
|
||||
webhook.addEmbed(embed);
|
||||
try {
|
||||
ServerUtils.sendDebugMessage("Executing webhook...");
|
||||
webhook.execute();
|
||||
} catch (IOException e) {
|
||||
ServerUtils.sendDebugMessage(TextUtils.prefix("Epic webhook failure!!!"));
|
||||
Sentinel.log.info(e.toString());
|
||||
}
|
||||
}
|
||||
public static void sendSwearLog(Player player, String message, int finalScore) {
|
||||
ServerUtils.sendDebugMessage("Creating swearLog Webhook...");
|
||||
DiscordWebhook webhook = new DiscordWebhook(Config.webhook);
|
||||
webhook.setAvatarUrl("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png");
|
||||
webhook.setUsername("Sentinel Anti-Nuke | Logs");
|
||||
DiscordWebhook.EmbedObject embed = new DiscordWebhook.EmbedObject()
|
||||
.setAuthor("Anti-Swear Punishment","","")
|
||||
.setTitle("Punish Report:")
|
||||
.setDescription(
|
||||
Emojis.rightSort + "Player: " + player.getName() + " " + Emojis.target + "\\n" +
|
||||
Emojis.space + Emojis.arrowRight + "Score: `" + finalScore + "/" + Config.punishScore + "`\\n" +
|
||||
Emojis.space + Emojis.arrowRight + "UUID: `" + player.getUniqueId() + "`\\n" +
|
||||
Emojis.rightSort + "Executed: " + Config.swearPunishCommand + " " + Emojis.mute + "\\n"
|
||||
)
|
||||
.addField("Original Message", "||" + message + "|| " + Emojis.alarm, false)
|
||||
.addField("Sanitized Message", ProfanityFilter.highlightProfanity(message,"||", "||") + " " + Emojis.noDM, false)
|
||||
.setColor(Color.orange)
|
||||
.setThumbnail("https://crafatar.com/avatars/" + player.getUniqueId() + "?size=64&&overlay");
|
||||
webhook.addEmbed(embed);
|
||||
try {
|
||||
ServerUtils.sendDebugMessage("Executing webhook...");
|
||||
webhook.execute();
|
||||
} catch (IOException e) {
|
||||
ServerUtils.sendDebugMessage(TextUtils.prefix("Epic webhook failure!!!"));
|
||||
Sentinel.log.info(e.toString());
|
||||
}
|
||||
}
|
||||
public static void sendSlurLog(Player player, String message, int finalScore) {
|
||||
ServerUtils.sendDebugMessage("Creating swearLog Webhook...");
|
||||
DiscordWebhook webhook = new DiscordWebhook(Config.webhook);
|
||||
webhook.setAvatarUrl("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png");
|
||||
webhook.setUsername("Sentinel Anti-Nuke | Logs");
|
||||
DiscordWebhook.EmbedObject embed = new DiscordWebhook.EmbedObject()
|
||||
.setAuthor("Anti-Slur Punishment","","")
|
||||
.setTitle(player.getName() + " has triggered the anti-slur!")
|
||||
.setDescription(
|
||||
Emojis.rightSort + "Player: " + player.getName() + " " + Emojis.target + "\\n" +
|
||||
Emojis.space + Emojis.arrowRight + "Score: `" + finalScore + "/" + Config.punishScore + "`\\n" +
|
||||
Emojis.space + Emojis.arrowRight + "UUID: `" + player.getUniqueId() + "`\\n" +
|
||||
Emojis.rightSort + "Executed: " + Config.slurPunishCommand + " " + Emojis.mute + "\\n"
|
||||
)
|
||||
.addField("Original Message", "||" + message + "|| " + Emojis.alarm, false)
|
||||
.addField("Sanitized Message", ProfanityFilter.highlightProfanity(message,"||", "||") + " " + Emojis.noDM, false)
|
||||
.setColor(Color.orange)
|
||||
.setThumbnail("https://crafatar.com/avatars/" + player.getUniqueId() + "?size=64&&overlay");
|
||||
webhook.addEmbed(embed);
|
||||
try {
|
||||
ServerUtils.sendDebugMessage("Executing webhook...");
|
||||
webhook.execute();
|
||||
} catch (IOException e) {
|
||||
ServerUtils.sendDebugMessage(TextUtils.prefix("Epic webhook failure!!!"));
|
||||
Sentinel.log.info(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,11 +134,11 @@ public class WebhookSender {
|
||||
public static void sendEmbedWarning(String player, String command, boolean denied, boolean removedOp, boolean banned) {
|
||||
ServerUtils.sendDebugMessage("Creating Command Webhook...");
|
||||
final String description =
|
||||
Emojis.arrowRight + " **Player:** " + player + " " + Emojis.member + "\\n" +
|
||||
Emojis.arrowRight + " **Command:** " + command + " " + Emojis.nuke + "\\n" +
|
||||
Emojis.arrowRight + " **Denied:** " + successOrFail(denied) + "\\n" +
|
||||
Emojis.arrowRight + " **Removed OP:** " + successOrFail(removedOp) + "\\n" +
|
||||
Emojis.arrowRight + " **Banned:** " + successOrFail(banned) + "\\n";
|
||||
Emojis.rightSort + " **Player:** " + player + " " + Emojis.member + "\\n" +
|
||||
Emojis.rightSort + " **Command:** " + command + " " + Emojis.nuke + "\\n" +
|
||||
Emojis.rightSort + " **Denied:** " + successOrFail(denied) + "\\n" +
|
||||
Emojis.rightSort + " **Removed OP:** " + successOrFail(removedOp) + "\\n" +
|
||||
Emojis.rightSort + " **Banned:** " + successOrFail(banned) + "\\n";
|
||||
|
||||
DiscordWebhook webhook = new DiscordWebhook(Config.webhook);
|
||||
webhook.setAvatarUrl("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png");
|
||||
@@ -75,11 +160,11 @@ public class WebhookSender {
|
||||
public static void sendEmbedWarning(String player, Block b, boolean denied, boolean removedOp, boolean banned) {
|
||||
ServerUtils.sendDebugMessage("Creating Block Webhook...");
|
||||
final String description =
|
||||
Emojis.arrowRight + " **Player:** " + player + " " + Emojis.member + "\\n" +
|
||||
Emojis.arrowRight + " **Block:** " + b.getType() + " " + Emojis.nuke + "\\n" +
|
||||
Emojis.arrowRight + " **Denied:** " + successOrFail(denied) + "\\n" +
|
||||
Emojis.arrowRight + " **Removed OP:** " + successOrFail(removedOp) + "\\n" +
|
||||
Emojis.arrowRight + " **Banned:** " + successOrFail(banned) + "\\n";
|
||||
Emojis.rightSort + " **Player:** " + player + " " + Emojis.member + "\\n" +
|
||||
Emojis.rightSort + " **Block:** " + b.getType() + " " + Emojis.nuke + "\\n" +
|
||||
Emojis.rightSort + " **Denied:** " + successOrFail(denied) + "\\n" +
|
||||
Emojis.rightSort + " **Removed OP:** " + successOrFail(removedOp) + "\\n" +
|
||||
Emojis.rightSort + " **Banned:** " + successOrFail(banned) + "\\n";
|
||||
|
||||
DiscordWebhook webhook = new DiscordWebhook(Config.webhook);
|
||||
webhook.setAvatarUrl("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png");
|
||||
@@ -100,13 +185,15 @@ public class WebhookSender {
|
||||
|
||||
}
|
||||
public static void sendEmbedWarning(String player, ItemStack item, boolean denied, boolean removedOp, boolean banned) {
|
||||
Bukkit.getScheduler().runTaskLater(Sentinel.getInstance(),() -> {
|
||||
ServerUtils.sendDebugMessage("Creating Webhook...");
|
||||
final String description =
|
||||
Emojis.arrowRight + " **Player:** " + player + " " + Emojis.member + "\\n" +
|
||||
Emojis.arrowRight + " **Item:** " + item.getType() + " " + Emojis.nuke + "\\n" +
|
||||
Emojis.arrowRight + " **Denied:** " + successOrFail(denied) + "\\n" +
|
||||
Emojis.arrowRight + " **Removed OP:** " + successOrFail(removedOp) + "\\n" +
|
||||
Emojis.arrowRight + " **Banned:** " + successOrFail(banned) + "\\n";
|
||||
Emojis.rightSort + " **Player:** " + player + " " + Emojis.member + "\\n" +
|
||||
Emojis.rightSort + " **Item:** " + item.getType().toString().toLowerCase() + " " + Emojis.nuke + "\\n" +
|
||||
Emojis.space + Emojis.rightDoubleArrow + "**NBT:** Uploaded to /Sentinel/LoggedNBT/" + FileUtils.createNBTLog(item.getItemMeta().getAsString()) + " \\n" +
|
||||
Emojis.rightSort + " **Denied:** " + successOrFail(denied) + "\\n" +
|
||||
Emojis.rightSort + " **Removed OP:** " + successOrFail(removedOp) + "\\n" +
|
||||
Emojis.rightSort + " **Banned:** " + successOrFail(banned) + "\\n";
|
||||
|
||||
DiscordWebhook webhook = new DiscordWebhook(Config.webhook);
|
||||
webhook.setAvatarUrl("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png");
|
||||
@@ -124,5 +211,6 @@ public class WebhookSender {
|
||||
ServerUtils.sendDebugMessage(TextUtils.prefix("Epic webhook failure!!!"));
|
||||
Sentinel.log.info(e.toString());
|
||||
}
|
||||
},10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.github.thetrouper.sentinel.events;
|
||||
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.Config;
|
||||
import io.github.thetrouper.sentinel.server.functions.AntiSpam;
|
||||
import io.github.thetrouper.sentinel.server.functions.ProfanityFilter;
|
||||
@@ -11,7 +12,7 @@ public class ChatEvent implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public static void onChat(AsyncPlayerChatEvent e) {
|
||||
if (Config.antiSwearEnabled) ProfanityFilter.handleProfanityFilter(e);
|
||||
if (Config.antiSpamEnabled) AntiSpam.handleAntiSpam(e);
|
||||
if (!Sentinel.isTrusted(e.getPlayer()) || !e.getPlayer().hasPermission("sentinel.chat.antiswear.bypass")) if (Config.antiSwearEnabled) ProfanityFilter.handleProfanityFilter(e);
|
||||
if (!Sentinel.isTrusted(e.getPlayer()) || !e.getPlayer().hasPermission("sentinel.chat.antispam.bypass")) if (Config.antiSpamEnabled) AntiSpam.handleAntiSpam(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.github.thetrouper.sentinel.server.functions;
|
||||
|
||||
import io.github.thetrouper.sentinel.data.Config;
|
||||
import io.github.thetrouper.sentinel.discord.WebhookSender;
|
||||
import io.github.thetrouper.sentinel.server.util.GPTUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.TextUtils;
|
||||
@@ -34,9 +35,11 @@ public class AntiSpam {
|
||||
punishSpam(p,message, lastMessageMap.get(p));
|
||||
return;
|
||||
}
|
||||
|
||||
if (heatMap.get(p) > Config.blockHeat) {
|
||||
e.setCancelled(true);
|
||||
alertSpam(p, message, lastMessageMap.get(p));
|
||||
heatMap.put(p, heatMap.get(p) + Config.highGain);
|
||||
return;
|
||||
}
|
||||
if (lastMessageMap.containsKey(p)) {
|
||||
@@ -61,7 +64,10 @@ public class AntiSpam {
|
||||
public static void alertSpam(Player p, String message1, String message2) {
|
||||
TextComponent text = new TextComponent();
|
||||
p.sendMessage(TextUtils.prefix("Do not spam in chat! Please wait before sending another message."));
|
||||
String hover = TextUtils.color("&bPrevious: &f" + message2 + "\n&bCurrent: &f" + message1 + "\n&bSimilarity &f" + GPTUtils.calculateSimilarity(message1,message2 + "%"));
|
||||
String hover = TextUtils.color("§8]==-- §d§lSentinel §8--==[" +
|
||||
"\n&bPrevious: &f" + message2 +
|
||||
"\n&bCurrent: &f" + message1 +
|
||||
"\n&bSimilarity &f" + GPTUtils.calculateSimilarity(message1,message2 + "%"));
|
||||
text.setText(TextUtils.prefix(TextUtils.color
|
||||
("&b&n" + p.getName() + "&7 might be spamming! &8(&c" + heatMap.get(p) + "&7/&4" + Config.punishHeat + "&8)")));
|
||||
text.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(hover)));
|
||||
@@ -70,6 +76,11 @@ public class AntiSpam {
|
||||
});
|
||||
}
|
||||
public static void punishSpam(Player player, String message1, String message2) {
|
||||
boolean chatCleared = false;
|
||||
if (Config.clearChat) {
|
||||
ServerUtils.sendCommand(Config.clearChatCommand);
|
||||
chatCleared = true;
|
||||
}
|
||||
ServerUtils.sendCommand(Config.punishSpamCommand.replace("%player%", player.getName()));
|
||||
player.sendMessage(TextUtils.prefix(TextUtils.color("&cYou have been auto-punished for violating the anti-spam repetitively!")));
|
||||
TextComponent text = new TextComponent();
|
||||
@@ -78,5 +89,6 @@ public class AntiSpam {
|
||||
ServerUtils.forEachStaff(staff -> {
|
||||
staff.spigot().sendMessage(text);
|
||||
});
|
||||
if (Config.logSpam) WebhookSender.sendSpamLog(player,message1,message2,heatMap.get(player),chatCleared);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.github.thetrouper.sentinel.server.functions;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.data.Config;
|
||||
import io.github.thetrouper.sentinel.discord.WebhookSender;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.TextUtils;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
@@ -27,36 +28,44 @@ public class ProfanityFilter {
|
||||
String message = e.getMessage();
|
||||
if (!scoreMap.containsKey(p)) scoreMap.put(p, 0);
|
||||
if (scoreMap.get(p) > Config.punishScore) punishSwear(p,highlightProfanity(message),message);
|
||||
switch (ProfanityFilter.checkSeverity(message)) {
|
||||
String severity = ProfanityFilter.checkSeverity(message);
|
||||
switch (severity) {
|
||||
case "low" -> {
|
||||
e.setCancelled(true);
|
||||
ServerUtils.sendDebugMessage("AntiSwear Flag, Message: " + message + " Concentrated: " + fullSimplify(message) + " Severity: " + severity + " Previous Score: " + scoreMap.get(p) +" Adding Score: " + Config.lowScore);
|
||||
scoreMap.put(p, scoreMap.get(p) + Config.lowScore);
|
||||
e.setCancelled(true);
|
||||
p.sendMessage(TextUtils.prefix("§cPlease do not swear in chat! Attempting to bypass this filter will result in a mute!"));
|
||||
blockSwear(p,highlightProfanity(message),message,severity);
|
||||
}
|
||||
case "medium-low" -> {
|
||||
e.setCancelled(true);
|
||||
ServerUtils.sendDebugMessage("AntiSwear Flag, Message: " + message + " Concentrated: " + fullSimplify(message) + " Severity: " + severity + " Previous Score: " + scoreMap.get(p) +" Adding Score: " + Config.mediumLowScore);
|
||||
scoreMap.put(p, scoreMap.get(p) + Config.mediumLowScore);
|
||||
blockSwear(p,highlightProfanity(message),message);
|
||||
e.setCancelled(true);
|
||||
blockSwear(p,highlightProfanity(message),message,severity);
|
||||
}
|
||||
case "medium" -> {
|
||||
e.setCancelled(true);
|
||||
ServerUtils.sendDebugMessage("AntiSwear Flag, Message: " + message + " Concentrated: " + fullSimplify(message) + " Severity: " + severity + " Previous Score: " + scoreMap.get(p) +" Adding Score: " + Config.mediumScore);
|
||||
scoreMap.put(p, scoreMap.get(p) + Config.mediumScore);
|
||||
blockSwear(p,highlightProfanity(message),message);
|
||||
e.setCancelled(true);
|
||||
blockSwear(p,highlightProfanity(message),message,severity);
|
||||
}
|
||||
case "medium-high" -> {
|
||||
e.setCancelled(true);
|
||||
ServerUtils.sendDebugMessage("AntiSwear Flag, Message: " + message + " Concentrated: " + fullSimplify(message) + " Severity: " + severity + " Previous Score: " + scoreMap.get(p) +" Adding Score: " + Config.mediumHighScore);
|
||||
scoreMap.put(p, scoreMap.get(p) + Config.mediumHighScore);
|
||||
blockSwear(p,highlightProfanity(message),message);
|
||||
e.setCancelled(true);
|
||||
blockSwear(p,highlightProfanity(message),message,severity);
|
||||
}
|
||||
case "high" -> {
|
||||
e.setCancelled(true);
|
||||
ServerUtils.sendDebugMessage("AntiSwear Flag, Message: " + message + " Concentrated: " + fullSimplify(message) + " Severity: " + severity + " Previous Score: " + scoreMap.get(p) +" Adding Score: " + Config.highScore);
|
||||
scoreMap.put(p, scoreMap.get(p) + Config.highScore);
|
||||
blockSwear(p,highlightProfanity(message),message);
|
||||
e.setCancelled(true);
|
||||
blockSwear(p,highlightProfanity(message),message,severity);
|
||||
}
|
||||
case "slur" -> {
|
||||
// Insta-Punish
|
||||
e.setCancelled(true);
|
||||
ServerUtils.sendDebugMessage("AntiSwear Flag, Message: " + message + " Concentrated: " + fullSimplify(message) + " Severity: " + severity + " Previous Score: " + scoreMap.get(p) +" Adding Score: " + Config.highScore);
|
||||
scoreMap.put(p, scoreMap.get(p) + Config.highScore);
|
||||
e.setCancelled(true);
|
||||
punishSlur(p,highlightProfanity(message),message);
|
||||
}
|
||||
}
|
||||
@@ -74,6 +83,7 @@ public class ProfanityFilter {
|
||||
ServerUtils.forEachStaff(staff -> {
|
||||
staff.spigot().sendMessage(text);
|
||||
});
|
||||
if (Config.logSwear) WebhookSender.sendSwearLog(player,origMessage,scoreMap.get(player));
|
||||
}
|
||||
public static void punishSlur(Player player, String highlightedMSG, String origMessage) {
|
||||
if (!Config.slurInstaPunish) return;
|
||||
@@ -89,10 +99,11 @@ public class ProfanityFilter {
|
||||
ServerUtils.forEachStaff(staff -> {
|
||||
staff.spigot().sendMessage(text);
|
||||
});
|
||||
if (Config.logSwear) WebhookSender.sendSlurLog(player,origMessage,scoreMap.get(player));
|
||||
}
|
||||
public static void blockSwear(Player player, String highlightedMSG, String origMessage) {
|
||||
public static void blockSwear(Player player, String highlightedMSG, String origMessage, String severity) {
|
||||
player.sendMessage(TextUtils.prefix(TextUtils.color("&cPlease do not swear in chat! Attempting to bypass this filter will result in a mute!")));
|
||||
String hover = TextUtils.color("&bOriginal: &f" + origMessage + "\n&bSanitized: &f" + highlightedMSG + "\n&7&o(click to copy)");
|
||||
String hover = TextUtils.color("&bOriginal: &f" + origMessage + "\n&bSanitized: &f" + highlightedMSG + "\n&bSeverity" + severity + "\n&7&o(click to copy)");
|
||||
TextComponent text = new TextComponent();
|
||||
text.setText(TextUtils.prefix(TextUtils.color
|
||||
("&b&n" + player.getName() + "&7 has triggered the anti-swear! &8(&c" + scoreMap.get(player) + "&7/&4" + Config.punishScore + "&8)")));
|
||||
@@ -105,9 +116,13 @@ public class ProfanityFilter {
|
||||
}
|
||||
|
||||
public static String highlightProfanity(String text) {
|
||||
String lowercasedText = text.toLowerCase();
|
||||
String highlightedSwears = highlightSwears(lowercasedText, "§c", "§f");
|
||||
String highlightedText = highlightSlurs(highlightedSwears, "§e", "§f");
|
||||
String highlightedSwears = highlightSwears(fullSimplify(text), "§e", "§f");
|
||||
String highlightedText = highlightSlurs(highlightedSwears, "§c", "§f");
|
||||
return highlightedText;
|
||||
}
|
||||
public static String highlightProfanity(String text, String start, String end) {
|
||||
String highlightedSwears = highlightSwears(fullSimplify(text), start, end);
|
||||
String highlightedText = highlightSlurs(highlightedSwears, start, end);
|
||||
return highlightedText;
|
||||
}
|
||||
|
||||
@@ -140,6 +155,15 @@ public class ProfanityFilter {
|
||||
* 10: remove periods and spaces
|
||||
* 11: Check for swears and return "high" if true
|
||||
*/
|
||||
public static String fullSimplify(String text) {
|
||||
String lowercasedText = text.toLowerCase();
|
||||
String cleanedText = removeFalsePositives(lowercasedText);
|
||||
String convertedText = convertLeetSpeakCharacters(cleanedText);
|
||||
String strippedText = stripSpecialCharacters(convertedText);
|
||||
String simplifiedText = simplifyRepeatingLetters(strippedText);
|
||||
String finalText = removePeriodsAndSpaces(simplifiedText);
|
||||
return finalText;
|
||||
}
|
||||
public static String checkSeverity(String text) {
|
||||
// 1:
|
||||
String lowercasedText = text.toLowerCase();
|
||||
@@ -220,4 +244,13 @@ public class ProfanityFilter {
|
||||
private static String removePeriodsAndSpaces(String text) {
|
||||
return text.replace(".", "").replace(" ", "");
|
||||
}
|
||||
public static void decayScore() {
|
||||
for (Player p : scoreMap.keySet()) {
|
||||
int score = scoreMap.get(p);
|
||||
if (score > 0) {
|
||||
score = score - Config.scoreDecay;
|
||||
scoreMap.put(p, Math.max(0, score));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package io.github.thetrouper.sentinel.server.util;
|
||||
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.time.*;
|
||||
import java.util.Random;
|
||||
|
||||
public class FileUtils {
|
||||
public static boolean folderExists(String folderName) {
|
||||
File folder = new File(Sentinel.getDF(), folderName);
|
||||
return folder.exists() && folder.isDirectory();
|
||||
}
|
||||
public static void createFolder(String folderName) {
|
||||
File folder = new File(Sentinel.getDF(), folderName);
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
}
|
||||
}
|
||||
public static String createNBTLog(String contents) {
|
||||
String fileName = "nbt_log-" + Randomizer.generateID();
|
||||
File file = new File(Sentinel.getDF() + "/LoggedNBT/" + 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;
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,22 @@ package io.github.thetrouper.sentinel.server.util;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@ config :
|
||||
# Anti-Nuke Setup (Do this first)
|
||||
# --------------------------------
|
||||
prefix: "§d§lSentinel §8» §7" # Prefix of the plugin. Line below is the discord webhook for logs to be sent to
|
||||
webhook: "https://discord.com/api/webhooks/1124908469842096211/7NGOeFvtmxQ4n0_hSvbqhZUjnzRHIicLpHKETYU92n9JaLUPPsueBSn7w4wUfAnhjlLF"
|
||||
webhook: "https://discord.com/api/webhooks/1126363806147289088/UfWz9jdmXpZ4f2kqqsKK6mx4NmZyknhHNzGuAHYSx30iSLCPwqf66AiToZn2rItAmAym"
|
||||
pbapikey: "Sar3RgGOxMhps71H3JDWKPeCaMIDbS_g" # Put your pastebin.com API key here (they are free), if you wish for NBT logs to work
|
||||
trusted: # List the UUIDs of players who are trusted, will bypass the plugin and be immune to logs and are able to re-op themeselves
|
||||
- "049460f7-21cb-42f5-8059-d42752bf406f" # obvWolf
|
||||
block-specific: true # Defaulted true | Weather or not to block ALL plugin specific commands from non-trusted members (EX: minecraft:ban) these will not be logged.
|
||||
@@ -53,31 +54,183 @@ config :
|
||||
high-gain: 6 # Default 6 | Heat gained for >90% similarity
|
||||
heat-decay: 1 # Default 1 | Heat lost every second
|
||||
block-heat: 10 # Default 10 | The heat required to block the message
|
||||
punish-heat: 15 # Default 15 | The heat required to punish the player
|
||||
punish-heat: 25 # Default 25 | The heat required to punish the player
|
||||
clear-chat: true # Default true | will run the clear chat command before a spam punishment
|
||||
chat-clear-command: "cc" # Default cc | Command for if "clear-chat" is enabled
|
||||
punish-command: "mute %player% 1m Please refrain from spamming!" # (Use %player% for the player's name placeholder)
|
||||
log-spam: true # Default true | logs spam punishments to the webhook
|
||||
anti-swear:
|
||||
enabled: true # Default true | Enables/disables the entire anti-swear
|
||||
low-score: 0 # Default 0 | How much score should you gain for not attempting a bypass
|
||||
medium-low-score: 0 # Default 0 | How much score should you gain for "bad "bypass attempt
|
||||
medium-score: 1 # Default 1 | How much score should you gain for "ok" bypass attempt
|
||||
medium-high-score: 3 # Default 3 | How much score should you gain for "good" bypass attempt
|
||||
high-score: 5 # Default 5 | How much score should be gained for "extreme" attempt to bypass
|
||||
medium-low-score: 1 # Default 1 | How much score should you gain for "bad "bypass attempt
|
||||
medium-score: 3 # Default 3 | How much score should you gain for "ok" bypass attempt
|
||||
medium-high-score: 5 # Default 5 | How much score should you gain for "good" bypass attempt
|
||||
high-score: 7 # Default 7 | How much score should be gained for "extreme" attempt to bypass
|
||||
score-decay: 3 # Default 3 | Rate at which score is lost every minute
|
||||
punish-score: 20 # Default 20 | how much score is required to get punished
|
||||
slur-insta-punish: true # Default true | Should players get insta punished for any words on the "slurs" list?
|
||||
punish-command: "mute %player% 15m Please refrain from excessive use of profanity!"
|
||||
punish-command: "mute %player% 15m Do not attempt to bypass the Profanity Filter"
|
||||
slur-command: "mute %player% 1h Discriminatory speech is not tolerated on this server!"
|
||||
log-swear: true # Default true | Logs swear punishments to the webhook
|
||||
whitelisted: # List known false positives here
|
||||
- glass
|
||||
blacklisted: # list all the swears you wish to blacklist here
|
||||
whitelisted:
|
||||
- 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
|
||||
- hot water
|
||||
- identit
|
||||
- kassa
|
||||
- kassi
|
||||
- lass
|
||||
- leafage
|
||||
- libshitz
|
||||
- magnacumlaude
|
||||
- mass
|
||||
- mocha
|
||||
- pass
|
||||
- phoebe
|
||||
- phoenix
|
||||
- push it
|
||||
- sassy
|
||||
- saturday
|
||||
- scrap
|
||||
- serfage
|
||||
- sexist
|
||||
- shoe
|
||||
- stitch
|
||||
- therapist
|
||||
blacklisted:
|
||||
- anal
|
||||
- anus
|
||||
- arse
|
||||
- ass
|
||||
slurs: # List slurs here that you wish to insta-punish for attempting
|
||||
- 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
|
||||
slurs:
|
||||
- nigg
|
||||
- niger
|
||||
- nlgg
|
||||
- nlger
|
||||
- njgg
|
||||
- tranny
|
||||
- fag
|
||||
- beaner
|
||||
leet-patterns:
|
||||
'0': o
|
||||
'1': i
|
||||
'3': e
|
||||
'4': a
|
||||
'5': s
|
||||
'6': g
|
||||
'7': l
|
||||
$: s
|
||||
'!': i
|
||||
'|': i
|
||||
+: t
|
||||
'#': h
|
||||
'@': a
|
||||
<: c
|
||||
V: u
|
||||
v: u
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: Sentinel
|
||||
version: '${version}'
|
||||
main: io.github.thetrouper.sentinel.Sentinel
|
||||
api-version: 1.17
|
||||
api-version: 1.19
|
||||
authors: [ TheTrouper ]
|
||||
description: Detect Block and Ban players who attempt to grief your server.
|
||||
website: https://thetrouper.github.io/
|
||||
|
||||
Reference in New Issue
Block a user