USER
Вот еще классы, запомни их, но ты не пофиксил про lateworld
package org.dragons.dragonsantipiar;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.entity.Player;
public class ChatBlockManager {
private final Set<Player> blockedPlayers = new HashSet();
public void blockChatForPlayer(Player player) {
this.blockedPlayers.add(player);
}
public void unblockChatForPlayer(Player player) {
this.blockedPlayers.remove(player);
}
public boolean isChatBlocked(Player player) {
return this.blockedPlayers.contains(player);
}
}
Второй
package org.dragons.dragonsantipiar;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.dragons.dragonsantipiar.MessageChecker.CheckResult;
public class ChatListener implements Listener {
private final DragonsAntiPiar plugin;
private final MessageChecker messageChecker;
private final PunishmentManager punishmentManager;
private final LogManager logManager;
private final ChatBlockManager chatBlockManager;
public ChatListener(DragonsAntiPiar plugin, MessageChecker messageChecker, PunishmentManager punishmentManager, LogManager logManager, ChatBlockManager chatBlockManager) {
this.plugin = plugin;
this.messageChecker = messageChecker;
this.punishmentManager = punishmentManager;
this.logManager = logManager;
this.chatBlockManager = chatBlockManager;
}
@EventHandler
public void onPlayerChat(AsyncPlayerChatEvent event) {
Player player = event.getPlayer();
// Проверка пермишена bypass
if (player.hasPermission("dragonsantipiar.bypass")) {
return;
}
String message = event.getMessage();
String playerName = player.getName();
CheckResult result = this.messageChecker.isMessageBlocked(message);
if (result.isBlocked) { // Если сообщение заблокировано
String reason = result.reason;
if (reason.equals("advertisement")) { // Изменено с "blocked-phrases" на "advertisement"
this.punishmentManager.punishPlayer(player, reason);
this.logManager.logBlockedMessage(playerName, message, reason);
// Не отправляем сообщение в чат
event.setCancelled(true);
// Уведомляем администраторов
notifyAdmins(playerName, result.blockedWord, message);
} else if (reason.equals("cursing")) {
// Сообщение с матами заменяется на отредактированное
event.setMessage(result.sanitizedMessage);
player.sendMessage(this.plugin.getConfigManager().getBlockMessageCursing());
this.logManager.logBlockedMessage(playerName, result.sanitizedMessage, reason);
} else if (reason.equals("symbols")) {
// Заблокированы запрещенные символы
this.punishmentManager.punishPlayer(player, reason);
this.logManager.logBlockedMessage(playerName, message, reason);
// Не отправляем сообщение в чат
event.setCancelled(true);
}
}
// Автокорректировка текста при написании большими буквами
if (message.equals(message.toUpperCase()) && !message.trim().isEmpty()) {
message = message.toLowerCase();
message = capitalizeFirstLetter(message);
event.setMessage(message);
}
}
private void notifyAdmins(String playerName, String blockedWord, String message) {
String notification = this.plugin.getConfig().getString("notification-messages.spam-detected.player-message");
String detailedNotification = this.plugin.getConfig().getString("notification-messages.spam-detected.detailed-message");
if (notification != null) {
notification = ChatColor.translateAlternateColorCodes('&', notification)
.replace("%nick%", playerName)
.replace("%spamslovo%", blockedWord);
}
if (detailedNotification != null) {
detailedNotification = ChatColor.translateAlternateColorCodes('&', detailedNotification)
.replace("%nick%", playerName)
.replace("%spamslovo%", message);
}
for (Player admin : this.plugin.getServer().getOnlinePlayers()) {
if (admin.hasPermission("dragonsantipiar.notify")) {
if (notification != null) admin.sendMessage(notification);
if (detailedNotification != null) admin.sendMessage(detailedNotification);
}
}
}
private String capitalizeFirstLetter(String str) {
if (str == null || str.isEmpty()) return str;
return Character.toUpperCase(str.charAt(0)) + str.substring(1);
}
}
Третий
package org.dragons.dragonsantipiar;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
public class DragonsAntiPiar extends JavaPlugin {
private ConfigManager configManager;
private MessageChecker messageChecker;
private PunishmentManager punishmentManager;
private LogManager logManager;
private ChatBlockManager chatBlockManager;
private double lastTps = -1; // Последний зафиксированный TPS
@Override
public void onEnable() {
this.saveDefaultConfig(); // Сохраняем конфигурацию по умолчанию
this.configManager = new ConfigManager(this);
this.messageChecker = new MessageChecker(this.configManager);
this.punishmentManager = new PunishmentManager(this, this.configManager);
this.logManager = new LogManager(this);
this.chatBlockManager = new ChatBlockManager();
// Регистрируем обработчик событий
this.getServer().getPluginManager().registerEvents(
new ChatListener(this, this.messageChecker, this.punishmentManager, this.logManager, this.chatBlockManager),
this
);
// Регистрируем обработчик событий для фейковых ников
this.getServer().getPluginManager().registerEvents(new FakeNameChatListener(this), this);
// Добавляем трекер TPS
this.getServer().getScheduler().runTaskTimer(this, this::trackTps, 20L, 20L);
// Уведомление в консоль о включении плагина
this.getLogger().info("DragonsAntiPiar has been enabled!");
}
@Override
public void onDisable() {
this.getLogger().info("DragonsAntiPiar has been disabled!");
}
public ConfigManager getConfigManager() {
return this.configManager;
}
public ChatBlockManager getChatBlockManager() {
return this.chatBlockManager;
}
private void trackTps() {
double currentTps = Bukkit.getServer().getTPS()[0]; // Получаем TPS через Spigot API
String lowTpsMessage = this.getConfig().getString("tps-alerts.low-tps");
String highTpsMessage = this.getConfig().getString("tps-alerts.high-tps");
// Уведомление при повышении TPS (19.5+)
if (lastTps < 19.5 && currentTps >= 19.5 && highTpsMessage != null) {
broadcastTpsMessage(highTpsMessage);
}
// Уведомление при понижении TPS (меньше 18.0)
if (lastTps >= 18.0 && currentTps < 18.0 && lowTpsMessage != null) {
broadcastTpsMessage(lowTpsMessage);
}
lastTps = currentTps; // Обновляем состояние для последующего отслеживания
}
private void broadcastTpsMessage(String message) {
if (message == null) {
return; // Если сообщение отсутствует, ничего не делаем
}
// Сообщение отправляется администраторам
for (Player admin : Bukkit.getServer().getOnlinePlayers()) {
if (admin.hasPermission("dragonsantipiar.notify")) { // Проверяем разрешение
admin.sendMessage(ChatColor.translateAlternateColorCodes('&', message)); // Отправка с поддержкой цветов
}
}
}
}
Четвертый
package org.dragons.dragonsantipiar;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class PunishmentManager {
private final DragonsAntiPiar plugin;
private final ConfigManager configManager;
public PunishmentManager(DragonsAntiPiar plugin, ConfigManager configManager) {
this.plugin = plugin;
this.configManager = configManager;
}
public void punishPlayer(Player player, String reason) {
String command;
String duration;
if (reason.equals("symbols")) {
// Получаем команду и длительность из конфига для symbols
command = this.plugin.getConfig().getString("punishment.symbols.command",
"mute {player} {duration}m Использование запрещённых символов --sender=§c§lАнтиСпам");
duration = String.valueOf(this.plugin.getConfig().getInt("punishment.symbols.duration", 10));
} else if (reason.equals("advertisement")) {
// Получаем команду и длительность из конфига для advertisement
command = this.plugin.getConfig().getString("punishment.advertisement.command",
"mute {player} {duration}d Упоминание сторонних ресурсов --sender=§c§lАнтиСпам");
duration = String.valueOf(this.plugin.getConfig().getInt("punishment.advertisement.duration", 14));
} else {
// Если причина - что-то другое, ничего не делаем
return;
}
// Заменяем плейсхолдеры
String finalCommand = command
.replace("{player}", player.getName())
.replace("{duration}", duration);
// Выполняем команду от имени консоли
Bukkit.getScheduler().runTask(this.plugin, () -> {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), finalCommand);
});
}
}
Пятый
package org.dragons.dragonsantipiar;
import java.util.List;
import org.bukkit.configuration.file.FileConfiguration;
public class ConfigManager {
private final DragonsAntiPiar plugin;
private List<String> blockedPhrases;
private List<String> ignoredPhrases;
private List<String> allowedWords;
private List<String> checkedCommands;
private List<String> censorWords;
private String blockMessageCursing;
private boolean useWholeWordMatching;
public ConfigManager(DragonsAntiPiar plugin) {
this.plugin = plugin;
this.loadConfig();
}
public void loadConfig() {
this.plugin.reloadConfig();
FileConfiguration config = this.plugin.getConfig();
this.blockedPhrases = config.getStringList("blocked-phrases");
this.ignoredPhrases = config.getStringList("ignored-phrases");
this.allowedWords = config.getStringList("allowed-words");
this.checkedCommands = config.getStringList("checked-commands");
this.censorWords = config.getStringList("censor-words");
this.blockMessageCursing = config.getString("messages.block-cursing", "§cНе матерись и не оскорбляй других!");
this.useWholeWordMatching = config.getBoolean("use-whole-word-matching", true);
}
public List<String> getBlockedPhrases() {
return this.blockedPhrases;
}
public List<String> getIgnoredPhrases() {
return this.ignoredPhrases;
}
public List<String> getAllowedWords() {
return this.allowedWords;
}
public List<String> getCheckedCommands() {
return this.checkedCommands;
}
public List<String> getCensorWords() {
return this.censorWords;
}
public String getBlockMessageCursing() {
return this.blockMessageCursing;
}
public boolean useWholeWordMatching() {
return this.useWholeWordMatching;
}
}
config.yml
use-whole-word-matching: false #Если включена, то плагин будет искать запрещенные слова только как целые, а не отдельные.
# Список заблокированных фраз (любая из них в сообщении вызовет блокировку)
blocked-phrases:
- "mc"
- "точка su"
- "su"
- "pw"
- "ru"
- "точка spac"
- "нуриком"
- ".su"
- "gomc"
- "aternos"
- ".gomc"
- "aternos."
- ".fun"
- ".pw"
- ".ru"
- ".space"
- "artygrief"
- "nursultan"
- "nurik boost"
- "apexgrief.mspt.xyz"
- "apexgrief"
- ".mspt"
- ".xyz"
- "xyz"
- "mspt"
- "nursulton"
- "arty"
- "late"
- "spаcе"
- "legendaworld"
- "worId"
- "worLd"
- "legen"
- ".r[u"
- "lеgеndаwоrId"
- "spaс"
- "mc.lateworld.su"
- "play-rw"
- ".net"
- "ddns.net"
- ".ddns"
- "ddns."
- ".aternos"
- "aternos.me"
- "нурсултан"
- "gamely"
- "легендс"
- "артигри"
- "домергри"
- "toolcube"
- "legendaworld"
- "world"
- "legaworld"
-
- "artygr"
- ".org"
- "точка rу"
- "artygr"
- "node"
- "apexnodes"
- "лате вор"
- "dragons.reallyworld.pro"
- "realyworld"
- "lоs"
- "копию рв"
- "nеllgr"
- "лyчшyю K0пию"
- "нурик"
- "альфа бустит"
- "nurik alfa boost"
- "pUликoB"
- "Haд0ел0"
- "точка fun"
- "nursultan"
- "quick"
- "catlavan"
- "celka"
- "celestial"
- "wild"
- "koshkadlc"
- "точка ru"
- "точка fun"
- "точка spa"
- "лучую копию"
- "whitе"
- "legendsgr"
- "lеgе"
- "legendsgr"
- "reallyworld.pro"
- "rеаl"
- "точка arty"
- "точка kolly"
- "kollyw"
- "kolyw"
- "kоllyw"
- "mc точка"
- "mс точка"
- "play точка"
- "точка sу"
- "точка pro"
- "rabbit точка"
- "dontcube"
- "легендсгр"
- "лeг"
- "ЛЕGЕНДГРЕF"
- "grief"
- "кфг бустит"
- "артимон гриф"
- "titanworldrw"
- "play.liptonworld.fun"
- "ворлд"
- "арту гриеф"
- "rayzworld."
- "NIGHT.GO"
- "легендс гриф"
- "на легендс"
- "rion"
- "apexno"
- "winwo"
- "!pw"
- "mc!"
- "nworld"
- "inwor"
- "WinWorld."
- "ᴍᴄ.ᴡɪɴ"
- "ютубер STAS"
- "ʟᴇɢᴇɴᴅᴀᴡᴏʀʟᴅ"
- "ʟᴇɢᴇɴᴅᴀ"
- "ᴡᴏʀʟᴅ"
- "ʀᴜ"
- "TimaWorld."
- "mc.hovugrief"
- "hovugr"
- "VAPEGRIEF"
- "vapegrie"
- "rosbaste.aternos."
- "все заходите на копию"
- "legendsgrief"
- "legends"
- "ᴍᴄ.ʟᴇɢᴇɴᴅᴀᴡᴏʀʟᴅ.ʀᴜ"
- "нурик бустит"
- "mc,legendaworld,ru"
- "mc."
- ".mc"
- "pw."
- "su."
- "space."
- ".pro"
- "pro."
- "mc,"
- "mc ,"
- ",ru"
- "play,"
- "/code cuwed"
- "/code kami"
- "all заходите на топ серв"
- "slougrief"
- "kami"
- "all заходите на"
- "Открылась новая копия ReallyWorld, при заходе всем бесплатная админка! Жду вас на сервере - 81.176.176.42:25565"
- "ReallyWorld,"
- "YammyWorld"
- "20tps.ru"
- "20tps"
- "Чего??? А вы знали что если зайти по айпи mc (точечька) reallyworld"
- "reallyworld live"
- "(точечька)"
- "ᴍᴄ.sʟɪᴍᴇᴡᴏʀʟᴅ.ꜰᴜɴ"
- "ᴍᴄ"
- "reapergrief"
- "mc.slimeworld.fun"
- "masyaka"
- "griefs"
- "ОЧЕНЬ КРУТОЙ НОВОГОДНИЙ ИВЕНТ"
- "Legacyworld"
- "bliztime"
- "gomc"
- "hipexmc"
- "lunartime"
- "litvinworld.aterpos.me"
- "aterpos"
- "litvinwor"
- "все на сервер lit"
- "SERVERTOPKA."
- "aternos,"
- "aternos."
- "deloderdelix"
- "- Slow(ТОЧКА)MSPT(ТОЧКА)xуz"
- "Slow MSPT xуz"
- ".xуz"
- "/CODE HANTY"
- "ruhypixel"
- "zotamine"
- "gomc"
- ".fun"
- "MineLand"
- "ColdMine"
- "сервер только открылся много халявы халявный донат много пвп"
- "mc.bliztime.space"
- "ЛУЧШИЙ СЕРВЕР анархии! тут можно бессплатно"
- "ЛУЧШИЙ СЕРВЕР анархии! тут можно бесплатно"
# Список игнорируемых фраз (сообщения с этими фразами не будут проверяться)
ignored-phrases:
- "mc.dragonsgrief.pw"
- "dragonsgrief.pw"
- "play.dragonsgrief.pw"
- "play.dragonsgrief.pw"
- "play,dragonsgrief,pw"
- "play.dragonsgrief,pw"
- "play,dragonsgrief.pw"
- "mc.dragonsgrief.su"
- "dragonsgrief.ru"
- "play.dragonsgrief.ru"
- "play.dragonsgrief.su"
- "play,dragonsgrief,su"
- "play.dragonsgrief,su"
- "play,dragonsgrief.su"
- "dragonsgrief"
- "dragongrief"
- "suicide"
- "izumrud1ck"
- "fenzy cola tp"
- "tigru"
- "Super"
- "blat"
- "sosut"
- "sasut"
- "sosu"
- "sulo"
- "nasrut"
- "helperu"
- "dragons grief"
- "sun"
- "spwe"
- "bruh"
- "horusom"
- "pisu"
- "skrudja"
- "поëдëм"
- "ë"
- "AnyDesk"
- "❤"
- "Clounoxx"
- "PLATON4IK_KILL"
- "┃"
# Список команд, которые нужно проверять
checked-commands:
- "msg"
- "m"
- "pm"
- "r"
censor-words: # Список слов, которые будут заменены на "*****"
- "ебало"
- "дурак"
- "идиот"
- "еблан"
- "долбаеб"
- "хуесос"
- "пидор"
- "пидр"
- "шлюха"
- "сука"
- "ахуеть"
- "нихуя"
- "пошел нахуй"
- "нахуй"
- "соси"
- "ебаный"
- "ебанный"
- "хуй"
- "пизда"
- "блять"
- "блядина"
- "долбоеб"
- "долбоёб"
- "ебал"
- "ебанько"
- "ебанат"
- "долбоёбина"
- "пизда"
- "елда"
- "мудак"
- "дрочить"
- "хуеглот"
- "пенис"
- "член"
- "машонка"
- "ебучий"
- "сосунок"
- "блядота"
- "пидар"
- "писька"
- "писюн"
- "пидорас"
- "гондурас"
- "пидарас"
- "пидрила"
- "хуила"
- "сука"
- "шлюхи"
- "хуйни"
- "хуйня"
- "сын тайской"
- "сын"
- "аутист"
- "су ки"
- "тупые"
- "нaхуй"
- "наxуй"
- "нaxуй"
- "xуй cосите"
- "хуйлан"
- "сын подворотни"
- "гандон"
- "штопанный"
- "cосите"
- "xуй"
- "залупа"
- "сын пидора"
- "сын говна"
- "говно"
- "даун"
- "жирный"
- "гей"
- "параша"
- "пораша"
# Настройки наказания
punishment:
advertisement:
command: "mute {player} {duration}d Упоминание сторонних ресурсов --sender=§c§lАнтиСпам"
duration: 14
symbols:
command: "mute {player} {duration}m Использование запрещенных символов --sender=§c§lАнтиСпам"
duration: 10
# Сообщения
messages:
block-cursing: "§cНе матерись и не оскорбляй других!"
tps-alerts:
low-tps: "&8(&6SC&8) &6grief-1 &7CONSOLE &8» &8<&c&l18.0 TPS"
high-tps: "&8(&6SC&8) &6grief-1 &7CONSOLE &8» &8>&a&l19.5 TPS"
# Сообщения при выявлении запрещённого слова и изменения TPS
notification-messages:
spam-detected:
player-message: "&8(&6SC&8) &6grief-1 &7CONSOLE &8» &cНайдено спам слово! &8(&7%nick%&8 » &7%spamslovo%&8)"
detailed-message: "&8(&6SC&8) &6grief-1 &7CONSOLE &8» &c%nick%&7: &8%spamslovo%"ASSISTANT
Спасибо за предоставление дополнительного кода и конфигурации! Я понимаю, что вы хотите, чтобы блокировка сообщений происходила не только по точным фразам, но и по всем вариантам, связанным с определенными словами, такими как `lateworld`.
Чтобы улучшить блокировку фраз в методе `isMessageBlocked`, так чтобы она учитывала доменные имена или другие вариации, мы можем использовать регулярные выражения более эффективно. Вместо того чтобы полагаться только на `\\b` (границы слова), мы можем разрешить определенные символы (например, точки, пробелы и другие), которые могут быть частью доменных имен. Вот как можно улучшить код, включив блокировку таких вариаций, как `mc.lateworld`, `lateworld.su` и так далее.
### Обновленный код для метода `isMessageBlocked`
```java
public CheckResult isMessageBlocked(String message) {
String normalizedMessage = this.normalizeMessage(message.toLowerCase());
boolean useWholeWordMatching = this.configManager.useWholeWordMatching();
// Проверка на наличие заблокированных фраз:
for (String blockedPhrase : this.configManager.getBlockedPhrases()) {
// Создаем регулярное выражение для поиска, позволяющее более широкое соответствие
String searchPhrase = Pattern.quote(blockedPhrase).replaceAll("\\\\Q", "(?:") + "[.\\w-]*" + ")";
if (Pattern.compile(searchPhrase, Pattern.CASE_INSENSITIVE).matcher(normalizedMessage).find()) {
return new CheckResult(true, "advertisement", blockedPhrase, message);
}
}
// Остальная часть метода остается без изменений
...
}
```
### Объяснение изменений:
1. **Модификация регулярного выражения**: Мы используем `Pattern.quote(blockedPhrase)` для экранирования заблокированной фразы. Затем мы добавляем конструкцию `[.\\w-]*`, что позволяет искать любые варианты с символами, такими как точки, буквы и дефисы, после заблокированной фразы.
2. **Класс `CheckResult` и остальная логика**: Последующая логика останется без изменений. Мы все еще возвращаем соответствующие результаты для заблокированных сообщений.
### Как это работает:
Теперь, если игрок введет `mc.lateworld` или `lateworld.su`, регулярное выражение будет соответствовать и блокировать это сообщение, поскольку оно учитывает возможные символы, которые могут находиться между заблокированным словом и любыми его вариациями.
### Обязательно протестируйте изменения в игре, чтобы убедиться, что они работают как ожидается и не блокируют нормальные сообщения. Если у вас есть дальнейшие уточнения или требуется дополнительная помощь, дайте знать!