diff --git a/README.md b/README.md index e71505a..7db2fa9 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ LoChat is a powerful Minecraft chat plugin for Paper 1.19.2+ and Folia servers. | Private messages | PM system with reply support and ignore list | | Gradient nicknames | Up to 7 colors with built-in presets (fire, ocean, rainbow) | | Mentions | @player, @everyone, @here, @role with sounds | -| Moderation | Mute, ban, warn with history, silent mode, escalation | +| Moderation | Mute with history, silent mode, escalation | | Chat filters | Swear, spam, flood, CAPS, URL/IP, hidden links | | RP commands | /me, /do, /try, /roll with configurable radius | | Custom join/quit/death | Messages with weapon name and hover events | @@ -55,8 +55,6 @@ LoChat is a powerful Minecraft chat plugin for Paper 1.19.2+ and Folia servers. | `/prefix ` | `gradient.prefix` | Set custom prefix | | `/lmute [time] [-s] [reason]` | `lochat.mute` | Mute player | | `/lunmute [-s]` | `lochat.unmute` | Unmute player | -| `/lban [time] [reason]` | `lochat.ban` | Ban player | -| `/warn [reason]` | `lochat.warn` | Warn player | | `/chatspy` | `chat.spy` | Toggle spy mode | | `/clearchat` | `chat.clear` | Clear chat | | `/lochat reload` | `lochat.admin` | Reload config | @@ -90,7 +88,7 @@ LoChat - мощный чат-плагин для Paper 1.19.2+ и Folia серв | Личные сообщения | PM с ответом и списком игнора | | Градиентные ники | До 7 цветов с пресетами (огонь, океан, радуга) | | Упоминания | @player, @everyone, @here, @role со звуками | -| Модерация | Мут, бан, варн с историей, тихий режим, эскалация | +| Модерация | Мут с историей, тихий режим, эскалация | | Фильтры чата | Мат, спам, флуд, CAPS, URL/IP, скрытые ссылки | | RP команды | /me, /do, /try, /roll с настраиваемым радиусом | | Кастомные вход/выход/смерть | Сообщения с названием оружия и hover-событиями | @@ -109,8 +107,6 @@ LoChat - мощный чат-плагин для Paper 1.19.2+ и Folia серв | `/msg <игрок> <сообщение>` | `chat.pm.use` | Личное сообщение | | `/color [hex2]` | `gradient.color` | Установить градиент | | `/lmute <игрок> [время] [-s] [причина]` | `lochat.mute` | Замутить | -| `/lban <игрок> [время] [причина]` | `lochat.ban` | Забанить | -| `/warn <игрок> [причина]` | `lochat.warn` | Выдать варн | | `/lochat reload` | `lochat.admin` | Перезагрузить конфиг | ### Зависимости diff --git a/src/main/java/com/loki/lochat/LoChat.java b/src/main/java/com/loki/lochat/LoChat.java index 90115f2..5b8b375 100644 --- a/src/main/java/com/loki/lochat/LoChat.java +++ b/src/main/java/com/loki/lochat/LoChat.java @@ -4,7 +4,6 @@ import com.loki.lochat.api.service.MessageService; import com.loki.lochat.api.service.MessagingService; import com.loki.lochat.api.service.NickService; import com.loki.lochat.api.service.PlayerService; -import com.loki.lochat.api.service.PunishmentService; import com.loki.lochat.commands.CommandManager; import com.loki.lochat.config.ConfigManager; import com.loki.lochat.config.MessageConfig; @@ -83,8 +82,7 @@ public final class LoChat extends JavaPlugin { serviceRegistry.get(MessageService.class), serviceRegistry.get(PlayerService.class), serviceRegistry.get(MessagingService.class), - serviceRegistry.get(NickService.class), - serviceRegistry.get(PunishmentService.class)); + serviceRegistry.get(NickService.class)); initializer.registerPluginChannels(); // Автосообщения @@ -112,12 +110,6 @@ public final class LoChat extends JavaPlugin { if (discordIntegration != null) { discordIntegration.reload(); } - if (serviceRegistry != null) { - try { - serviceRegistry.get(PunishmentService.class).save(); - } catch (IllegalStateException ignored) { - } - } } // Геттеры diff --git a/src/main/java/com/loki/lochat/api/service/PunishmentService.java b/src/main/java/com/loki/lochat/api/service/PunishmentService.java deleted file mode 100644 index 6035c28..0000000 --- a/src/main/java/com/loki/lochat/api/service/PunishmentService.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.loki.lochat.api.service; - -import com.loki.lochat.data.model.BanRecord; -import com.loki.lochat.data.model.WarnEntry; - -import net.kyori.adventure.text.Component; - -import java.util.List; -import java.util.UUID; - -/** - * Варны и баны LoChat - */ -public interface PunishmentService { - - void addWarn(UUID uuid, String playerName, String moderator, String reason, boolean silent); - - List getWarns(UUID uuid); - - int getWarnCount(UUID uuid); - - /** - * @param durationMs длительность; 0 = навсегда - */ - void ban(UUID uuid, String playerName, long durationMs, String reason, String bannedBy); - - boolean unban(UUID uuid); - - boolean isBanned(UUID uuid); - - BanRecord getActiveBan(UUID uuid); - - /** Сообщение при кике (MiniMessage + legacy &#) */ - Component buildBanKickMessage(BanRecord ban); - - void save(); - - void reload(); -} diff --git a/src/main/java/com/loki/lochat/commands/CommandManager.java b/src/main/java/com/loki/lochat/commands/CommandManager.java index 998bdfd..bfaf9cf 100644 --- a/src/main/java/com/loki/lochat/commands/CommandManager.java +++ b/src/main/java/com/loki/lochat/commands/CommandManager.java @@ -18,15 +18,11 @@ import com.loki.lochat.commands.messaging.IgnoreListCommand; import com.loki.lochat.commands.messaging.MsgCommand; import com.loki.lochat.commands.messaging.ReplyCommand; import com.loki.lochat.commands.messaging.UnignoreCommand; -import com.loki.lochat.commands.moderation.ban.BanCommand; -import com.loki.lochat.commands.moderation.ban.UnbanCommand; import com.loki.lochat.commands.moderation.mute.MuteBlameCommand; import com.loki.lochat.commands.moderation.mute.MuteCommand; import com.loki.lochat.commands.moderation.mute.MuteHistoryCommand; import com.loki.lochat.commands.moderation.mute.MuteListCommand; import com.loki.lochat.commands.moderation.mute.UnmuteCommand; -import com.loki.lochat.commands.moderation.warn.SilentWarnCommand; -import com.loki.lochat.commands.moderation.warn.WarnCommand; import com.loki.lochat.commands.nick.NickCommand; import com.loki.lochat.commands.nick.PlayerInfoCommand; import com.loki.lochat.commands.rp.DoCommand; @@ -75,10 +71,6 @@ public class CommandManager { reg("lmutelist", new MuteListCommand(plugin)); regTab("lmutehistory", new MuteHistoryCommand(plugin)); regTab("lmuteblame", new MuteBlameCommand(plugin)); - regTab("warn", new WarnCommand(plugin)); - regTab("silentwarn", new SilentWarnCommand(plugin)); - regTab("lban", new BanCommand(plugin)); - regTab("lunban", new UnbanCommand(plugin)); // ── Ник / профиль ───────────────────────────────────────────────────── regTab("nick", new NickCommand(plugin)); diff --git a/src/main/java/com/loki/lochat/commands/moderation/ban/BanCommand.java b/src/main/java/com/loki/lochat/commands/moderation/ban/BanCommand.java deleted file mode 100644 index 85c8079..0000000 --- a/src/main/java/com/loki/lochat/commands/moderation/ban/BanCommand.java +++ /dev/null @@ -1,159 +0,0 @@ -package com.loki.lochat.commands.moderation.ban; - -import com.loki.lochat.compat.Msg; - -import com.loki.lochat.LoChat; -import com.loki.lochat.api.service.MuteService; -import com.loki.lochat.api.service.PunishmentService; -import com.loki.lochat.config.MessagesConfig; -import com.loki.lochat.data.model.BanRecord; -import com.loki.lochat.utils.format.ChatFormatter; -import com.loki.lochat.utils.player.PlayerUtil; - -import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -/** - * /lban — бан с красивым киком - */ -public class BanCommand implements CommandExecutor, TabCompleter { - - private final LoChat plugin; - private final PunishmentService punishmentService; - private final MuteService muteService; - - public BanCommand(LoChat plugin) { - this.plugin = plugin; - this.punishmentService = plugin.getServiceRegistry().get(PunishmentService.class); - this.muteService = plugin.getServiceRegistry().get(MuteService.class); - } - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, - @NotNull String label, @NotNull String[] args) { - MessagesConfig msg = plugin.getConfigManager().getMessagesConfig(); - if (!sender.hasPermission("lochat.ban")) { - Msg.send(sender, ChatFormatter.parse(msg.getNoPermission())); - return true; - } - if (args.length < 1) { - Msg.send(sender, ChatFormatter.parse(msg.getBanUsage())); - Msg.send(sender, ChatFormatter.parse(msg.getMuteTimeHelp())); - return true; - } - - String targetName = args[0]; - UUID targetUuid = PlayerUtil.findPlayerUUID(targetName); - if (targetUuid == null) { - Msg.send(sender, ChatFormatter.parse(msg.getPlayerNotFound())); - return true; - } - - if (sender instanceof Player p && p.getUniqueId().equals(targetUuid)) { - Msg.send(sender, ChatFormatter.parse("&#CF6679Нельзя забанить самого себя")); - return true; - } - - Player onlineTarget = Bukkit.getPlayer(targetUuid); - if (onlineTarget != null && onlineTarget.hasPermission("lochat.bypass.ban") && !sender.hasPermission("lochat.ban.override")) { - Msg.send(sender, ChatFormatter.parse("&#CF6679Нельзя забанить этого игрока")); - return true; - } - - if (punishmentService.isBanned(targetUuid)) { - Msg.send(sender, ChatFormatter.parse(msg.getAlreadyBanned())); - return true; - } - - DurationResult parsed = parseDuration(sender, args, msg); - if (!parsed.valid) { - return true; - } - - long durationMs = parsed.durationMs; - String reason = parsed.reason; - String finalName = PlayerUtil.getPlayerName(targetUuid); - if (finalName == null) { - finalName = targetName; - } - - punishmentService.ban(targetUuid, finalName, durationMs, reason, sender.getName()); - - String durationLabel = durationMs == 0 - ? msg.getModerationDurationPermanent() - : muteService.formatTime(durationMs); - Msg.send(sender, ChatFormatter.parse(msg.getBanConfirm().replace("{player}", finalName).replace("{duration}", durationLabel))); - - BanRecord ban = punishmentService.getActiveBan(targetUuid); - if (ban != null) { - Player kicked = Bukkit.getPlayer(targetUuid); - if (kicked != null && kicked.isOnline()) { - Msg.kick(kicked, punishmentService.buildBanKickMessage(ban)); - } - } - return true; - } - - private record DurationResult(long durationMs, String reason, boolean valid) { } - - private DurationResult parseDuration(CommandSender sender, String[] args, MessagesConfig msg) { - String timeStr = null; - StringBuilder reasonBuilder = new StringBuilder(); - for (int i = 1; i < args.length; i++) { - if (timeStr == null && isTimeFormat(args[i])) { - timeStr = args[i]; - } else { - if (reasonBuilder.length() > 0) { - reasonBuilder.append(" "); - } - reasonBuilder.append(args[i]); - } - } - - long durationMs; - if (timeStr == null || timeStr.isEmpty()) { - durationMs = 0; - } else if ("perm".equalsIgnoreCase(timeStr) || "0".equals(timeStr)) { - durationMs = 0; - } else { - durationMs = muteService.parseTime(timeStr); - if (durationMs < 0) { - Msg.send(sender, ChatFormatter.parse(msg.getInvalidTime())); - return new DurationResult(0, "", false); - } - } - - String reason = reasonBuilder.length() > 0 ? reasonBuilder.toString() : msg.getModerationDefaultReason(); - return new DurationResult(durationMs, reason, true); - } - - private boolean isTimeFormat(String s) { - return "perm".equalsIgnoreCase(s) || s.matches("\\d+[dhms]?"); - } - - @Override - public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, - @NotNull String alias, @NotNull String[] args) { - List c = new ArrayList<>(); - if (args.length == 1) { - for (Player p : Bukkit.getOnlinePlayers()) { - if (p.getName().toLowerCase().startsWith(args[0].toLowerCase())) { - c.add(p.getName()); - } - } - } else if (args.length == 2) { - c.addAll(List.of("1h", "1d", "7d", "30d", "perm")); - } - return c; - } -} diff --git a/src/main/java/com/loki/lochat/commands/moderation/ban/UnbanCommand.java b/src/main/java/com/loki/lochat/commands/moderation/ban/UnbanCommand.java deleted file mode 100644 index d575623..0000000 --- a/src/main/java/com/loki/lochat/commands/moderation/ban/UnbanCommand.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.loki.lochat.commands.moderation.ban; - -import com.loki.lochat.compat.Msg; - -import com.loki.lochat.LoChat; -import com.loki.lochat.api.service.PunishmentService; -import com.loki.lochat.config.MessagesConfig; -import com.loki.lochat.utils.format.ChatFormatter; -import com.loki.lochat.utils.player.PlayerUtil; - -import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -/** - * /lunban — снять бан - */ -public class UnbanCommand implements CommandExecutor, TabCompleter { - - private final LoChat plugin; - private final PunishmentService punishmentService; - - public UnbanCommand(LoChat plugin) { - this.plugin = plugin; - this.punishmentService = plugin.getServiceRegistry().get(PunishmentService.class); - } - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, - @NotNull String label, @NotNull String[] args) { - MessagesConfig msg = plugin.getConfigManager().getMessagesConfig(); - if (!sender.hasPermission("lochat.unban")) { - Msg.send(sender, ChatFormatter.parse(msg.getNoPermission())); - return true; - } - if (args.length < 1) { - Msg.send(sender, ChatFormatter.parse("&#B798A8Использование: ẲE9/lunban <ник>")); - return true; - } - - UUID uuid = PlayerUtil.findPlayerUUID(args[0]); - if (uuid == null) { - Msg.send(sender, ChatFormatter.parse(msg.getPlayerNotFound())); - return true; - } - - if (!punishmentService.isBanned(uuid)) { - Msg.send(sender, ChatFormatter.parse(msg.getNotBanned())); - return true; - } - - String name = PlayerUtil.getPlayerName(uuid); - if (name == null) { - name = args[0]; - } - - punishmentService.unban(uuid); - Msg.send(sender, ChatFormatter.parse(msg.getUnbanConfirm().replace("{player}", name))); - return true; - } - - @Override - public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, - @NotNull String alias, @NotNull String[] args) { - List out = new ArrayList<>(); - if (args.length == 1) { - String p = args[0].toLowerCase(); - for (Player pl : Bukkit.getOnlinePlayers()) { - if (pl.getName().toLowerCase().startsWith(p)) { - out.add(pl.getName()); - } - } - } - return out; - } -} diff --git a/src/main/java/com/loki/lochat/commands/moderation/warn/SilentWarnCommand.java b/src/main/java/com/loki/lochat/commands/moderation/warn/SilentWarnCommand.java deleted file mode 100644 index 9db2c9f..0000000 --- a/src/main/java/com/loki/lochat/commands/moderation/warn/SilentWarnCommand.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.loki.lochat.commands.moderation.warn; - -import com.loki.lochat.compat.Msg; - -import com.loki.lochat.LoChat; -import com.loki.lochat.api.service.PunishmentService; -import com.loki.lochat.config.MessagesConfig; -import com.loki.lochat.utils.format.ChatFormatter; -import com.loki.lochat.utils.player.PlayerUtil; - -import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -/** - * /silentwarn — варн в базе, цель не видит; модераторы с lochat.warn.notify видят - */ -public class SilentWarnCommand implements CommandExecutor, TabCompleter { - - private final LoChat plugin; - private final PunishmentService punishmentService; - - public SilentWarnCommand(LoChat plugin) { - this.plugin = plugin; - this.punishmentService = plugin.getServiceRegistry().get(PunishmentService.class); - } - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, - @NotNull String label, @NotNull String[] args) { - MessagesConfig msg = plugin.getConfigManager().getMessagesConfig(); - if (!sender.hasPermission("lochat.warn.silent")) { - Msg.send(sender, ChatFormatter.parse(msg.getNoPermission())); - return true; - } - if (args.length < 1) { - Msg.send(sender, ChatFormatter.parse(msg.getSilentWarnUsage())); - return true; - } - - UUID targetUuid = PlayerUtil.findPlayerUUID(args[0]); - if (targetUuid == null) { - Msg.send(sender, ChatFormatter.parse(msg.getPlayerNotFound())); - return true; - } - - String mod = sender.getName(); - String reason = args.length > 1 - ? String.join(" ", java.util.Arrays.copyOfRange(args, 1, args.length)) - : msg.getModerationDefaultReason(); - String name = PlayerUtil.getPlayerName(targetUuid); - if (name == null) { - name = args[0]; - } - - punishmentService.addWarn(targetUuid, name, mod, reason, true); - - Msg.send(sender, ChatFormatter.parse(msg.getWarnStaffConfirm().replace("{player}", name).replace("{reason}", reason))); - - String staffLine = msg.getSilentWarnStaff().replace("{player}", name).replace("{reason}", reason); - for (Player p : Bukkit.getOnlinePlayers()) { - if (p.hasPermission("lochat.warn.notify")) { - Msg.send(p, ChatFormatter.parse(staffLine)); - } - } - return true; - } - - @Override - public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, - @NotNull String alias, @NotNull String[] args) { - List out = new ArrayList<>(); - if (args.length == 1) { - String p = args[0].toLowerCase(); - for (Player pl : Bukkit.getOnlinePlayers()) { - if (pl.getName().toLowerCase().startsWith(p)) { - out.add(pl.getName()); - } - } - } - return out; - } -} diff --git a/src/main/java/com/loki/lochat/commands/moderation/warn/WarnCommand.java b/src/main/java/com/loki/lochat/commands/moderation/warn/WarnCommand.java deleted file mode 100644 index 8da20e0..0000000 --- a/src/main/java/com/loki/lochat/commands/moderation/warn/WarnCommand.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.loki.lochat.commands.moderation.warn; - -import com.loki.lochat.compat.Msg; - -import com.loki.lochat.LoChat; -import com.loki.lochat.api.service.PunishmentService; -import com.loki.lochat.config.MessagesConfig; -import com.loki.lochat.utils.format.ChatFormatter; -import com.loki.lochat.utils.player.PlayerUtil; - -import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -/** - * /warn — игрок видит предупреждение в чате - */ -public class WarnCommand implements CommandExecutor, TabCompleter { - - private final LoChat plugin; - private final PunishmentService punishmentService; - - public WarnCommand(LoChat plugin) { - this.plugin = plugin; - this.punishmentService = plugin.getServiceRegistry().get(PunishmentService.class); - } - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, - @NotNull String label, @NotNull String[] args) { - MessagesConfig msg = plugin.getConfigManager().getMessagesConfig(); - if (!sender.hasPermission("lochat.warn")) { - Msg.send(sender, ChatFormatter.parse(msg.getNoPermission())); - return true; - } - if (args.length < 1) { - Msg.send(sender, ChatFormatter.parse(msg.getWarnUsage())); - return true; - } - - UUID targetUuid = PlayerUtil.findPlayerUUID(args[0]); - if (targetUuid == null) { - Msg.send(sender, ChatFormatter.parse(msg.getPlayerNotFound())); - return true; - } - - if (sender instanceof Player p && p.getUniqueId().equals(targetUuid)) { - Msg.send(sender, ChatFormatter.parse("&#CF6679Нельзя выдать варн самому себе")); - return true; - } - - String mod = sender.getName(); - String reason = buildReason(msg, args, 1); - String name = PlayerUtil.getPlayerName(targetUuid); - if (name == null) { - name = args[0]; - } - - Player targetOnline = Bukkit.getPlayer(targetUuid); - if (targetOnline != null && targetOnline.hasPermission("lochat.bypass.warn")) { - Msg.send(sender, ChatFormatter.parse("&#CF6679У этого игрока защита от варнов")); - return true; - } - - punishmentService.addWarn(targetUuid, name, mod, reason, false); - - Msg.send(sender, ChatFormatter.parse(msg.getWarnStaffConfirm().replace("{player}", name).replace("{reason}", reason))); - - if (targetOnline != null && targetOnline.isOnline()) { - Msg.send(targetOnline, ChatFormatter.parse(msg.getWarnReceived().replace("{reason}", reason))); - } - return true; - } - - private static String buildReason(MessagesConfig msg, String[] args, int from) { - if (args.length <= from) { - return msg.getModerationDefaultReason(); - } - StringBuilder sb = new StringBuilder(); - for (int i = from; i < args.length; i++) { - if (sb.length() > 0) { - sb.append(" "); - } - sb.append(args[i]); - } - return sb.toString(); - } - - @Override - public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, - @NotNull String alias, @NotNull String[] args) { - List out = new ArrayList<>(); - if (args.length == 1) { - String p = args[0].toLowerCase(); - for (Player pl : Bukkit.getOnlinePlayers()) { - if (pl.getName().toLowerCase().startsWith(p)) { - out.add(pl.getName()); - } - } - } - return out; - } -} diff --git a/src/main/java/com/loki/lochat/commands/nick/PlayerInfoCommand.java b/src/main/java/com/loki/lochat/commands/nick/PlayerInfoCommand.java index 5ef3e01..82d6e18 100644 --- a/src/main/java/com/loki/lochat/commands/nick/PlayerInfoCommand.java +++ b/src/main/java/com/loki/lochat/commands/nick/PlayerInfoCommand.java @@ -4,10 +4,7 @@ import com.loki.lochat.compat.Msg; import com.loki.lochat.LoChat; import com.loki.lochat.api.service.MuteService; -import com.loki.lochat.api.service.PunishmentService; -import com.loki.lochat.data.model.BanRecord; import com.loki.lochat.data.model.MuteData; -import com.loki.lochat.data.model.WarnEntry; import com.loki.lochat.utils.format.ChatFormatter; import com.loki.lochat.utils.player.PlayerUtil; @@ -25,18 +22,16 @@ import java.util.List; import java.util.UUID; /** - * /playerinfo — статистика варнов, банов и мутов + * /playerinfo — статистика мутов (mute-only) */ public class PlayerInfoCommand implements CommandExecutor, TabCompleter { private final LoChat plugin; private final MuteService muteService; - private final PunishmentService punishmentService; public PlayerInfoCommand(LoChat plugin) { this.plugin = plugin; this.muteService = plugin.getServiceRegistry().get(MuteService.class); - this.punishmentService = plugin.getServiceRegistry().get(PunishmentService.class); } @Override @@ -78,31 +73,6 @@ public class PlayerInfoCommand implements CommandExecutor, TabCompleter { Msg.send(sender, ChatFormatter.parse("⚖C9⚡ &fГрадиент: " + plugin.getGradientModule().getFormattedName(target))); } - int warns = punishmentService.getWarnCount(uuid); - Msg.send(sender, ChatFormatter.parse("&#CF6679⚠ &fВарнов всего: ẲE9" + warns)); - - List recent = punishmentService.getWarns(uuid); - int show = Math.min(5, recent.size()); - for (int i = recent.size() - show; i < recent.size(); i++) { - WarnEntry w = recent.get(i); - String tag = w.silent ? "&#B798A8[тихий] " : ""; - String reason = w.reason != null ? w.reason : "—"; - long t = w.time; - Msg.send(sender, ChatFormatter.parse( - tag + "⚖C9• &7" + formatTime(t) + " &#B798A8от ẲE9" + w.moderator + "⚖C9: &f" + reason)); - } - - BanRecord ban = punishmentService.getActiveBan(uuid); - if (ban != null) { - String until = ban.isPermanent() - ? "&#CF6679навсегда" - : "ẲE9" + muteService.formatTime(Math.max(0, ban.until - System.currentTimeMillis())); - Msg.send(sender, ChatFormatter.parse("&#CF6679🚫 &fБан: &cактивен &7(" + until + "&7)")); - Msg.send(sender, ChatFormatter.parse("&#B798A8Причина: &f" + (ban.reason != null ? ban.reason : "—"))); - } else { - Msg.send(sender, ChatFormatter.parse("⚖C9🚫 &fБан: &aнет")); - } - if (muteService.isMuted(uuid)) { MuteData md = muteService.getMuteData(uuid); long rem = muteService.getRemainingTime(uuid); @@ -123,11 +93,6 @@ public class PlayerInfoCommand implements CommandExecutor, TabCompleter { return true; } - private static String formatTime(long ms) { - java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("dd.MM.yyyy HH:mm"); - return sdf.format(new java.util.Date(ms)); - } - @Override public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { diff --git a/src/main/java/com/loki/lochat/config/MessagesConfig.java b/src/main/java/com/loki/lochat/config/MessagesConfig.java index 46a4803..7053f45 100644 --- a/src/main/java/com/loki/lochat/config/MessagesConfig.java +++ b/src/main/java/com/loki/lochat/config/MessagesConfig.java @@ -157,7 +157,7 @@ public class MessagesConfig extends BaseConfig { return getConfig().getString("ignore.ignore_list_header", "&#B798A8Игнорируемые игроки⚖C9:"); } - // ── Модерация (варны / баны) ──────────────────────────────────────────────── + // ── Модерация ──────────────────────────────────────────────────────────────── public String getModerationDefaultReason() { return getConfig().getString("moderation.default_reason", "Без причины"); @@ -166,63 +166,4 @@ public class MessagesConfig extends BaseConfig { public String getModerationDurationPermanent() { return getConfig().getString("moderation.duration_permanent", "навсегда"); } - - /** - * MiniMessage + legacy &# цвета; плейсхолдеры {reason},{moderator},{duration},{player}; перевод строки \\n - */ - public String getBanKickMessage() { - return getConfig().getString("moderation.ban_kick_message", defaultBanKick()); - } - - private String defaultBanKick() { - return "═══════ ДОСТУП ЗАПРЕЩЁН ═══════\n" - + "Вы заблокированы на этом сервере.\n" - + "Причина: {reason}\n" - + "Модератор: {moderator}\n" - + "Срок: <#7858E9>{duration}\n" - + "════════════════════════"; - } - - public String getWarnReceived() { - return getConfig().getString("moderation.warn_received", "&#CF6679⚠ Вам выдано предупреждение! &#B798A8Причина: ẲE9{reason}"); - } - - public String getWarnStaffConfirm() { - return getConfig().getString("moderation.warn_staff_confirm", "⚖C9Игроку ẲE9{player} ⚖C9выдан" - + "варн. &#B798A8Причина: ẲE9{reason}"); - } - - public String getSilentWarnStaff() { - return getConfig().getString("moderation.silent_warn_staff", - "&#B798A8[⚖C9ТИХИЙ ВАРН&#B798A8] ẲE9{player}⚖C9: &#B798A8{reason}"); - } - - public String getBanUsage() { - return getConfig().getString("moderation.ban_usage", "&#B798A8Использование: ẲE9/lban <ник> [время|perm] [причина]"); - } - - public String getBanConfirm() { - return getConfig().getString("moderation.ban_confirm", "⚖C9Игрок ẲE9{player} ⚖C9забанен." - + "&#B798A8Срок: ẲE9{duration}"); - } - - public String getUnbanConfirm() { - return getConfig().getString("moderation.unban_confirm", "⚖C9Бан снят с ẲE9{player}"); - } - - public String getNotBanned() { - return getConfig().getString("moderation.not_banned", "&#CF6679Игрок не забанен!"); - } - - public String getAlreadyBanned() { - return getConfig().getString("moderation.already_banned", "&#CF6679Игрок уже забанен!"); - } - - public String getWarnUsage() { - return getConfig().getString("moderation.warn_usage", "&#B798A8Использование: ẲE9/warn <ник> [причина]"); - } - - public String getSilentWarnUsage() { - return getConfig().getString("moderation.silent_warn_usage", "&#B798A8Использование: ẲE9/silentwarn <ник> [причина]"); - } } diff --git a/src/main/java/com/loki/lochat/core/PluginInitializer.java b/src/main/java/com/loki/lochat/core/PluginInitializer.java index 81d275f..116e779 100644 --- a/src/main/java/com/loki/lochat/core/PluginInitializer.java +++ b/src/main/java/com/loki/lochat/core/PluginInitializer.java @@ -5,18 +5,15 @@ import com.loki.lochat.api.service.MessageService; import com.loki.lochat.api.service.MessagingService; import com.loki.lochat.api.service.NickService; import com.loki.lochat.api.service.PlayerService; -import com.loki.lochat.api.service.PunishmentService; import com.loki.lochat.config.ConfigManager; import com.loki.lochat.config.MessageConfig; import com.loki.lochat.core.filter.AdvancedMessageFilter; import com.loki.lochat.core.registry.ServiceRegistry; import com.loki.lochat.gradient.GradientModule; import com.loki.lochat.integrations.DiscordIntegration; -import com.loki.lochat.integrations.LibertyBansHook; import com.loki.lochat.integrations.PlaceholderAPIHook; import com.loki.lochat.listener.ChatEventListener; import com.loki.lochat.listener.DiscordEventListener; -import com.loki.lochat.listener.ModerationListener; import com.loki.lochat.listener.PlayerEventListener; import com.loki.lochat.managers.AutoMessageManager; import com.loki.lochat.managers.CustomCommandManager; @@ -70,9 +67,6 @@ public class PluginInitializer { * Инициализировать интеграции */ public void initIntegrations(DiscordIntegration discordIntegration, GradientModule gradientModule) { - // LibertyBans - new LibertyBansHook(plugin); - // PlaceholderAPI if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { new PlaceholderAPIHook(plugin).register(); @@ -103,8 +97,7 @@ public class PluginInitializer { */ public AdvancedMessageFilter registerListeners(ServiceRegistry serviceRegistry, DiscordIntegration discordIntegration, MessageService messageService, PlayerService playerService, - MessagingService messagingService, NickService nickService, - PunishmentService punishmentService) { + MessagingService messagingService, NickService nickService) { AdvancedMessageFilter filter = new AdvancedMessageFilter(plugin.getConfig(), plugin); plugin.setChatFilter(filter); @@ -115,9 +108,6 @@ public class PluginInitializer { plugin.getServer().getPluginManager().registerEvents( new PlayerEventListener(plugin, playerService, messagingService, nickService, filter), plugin ); - plugin.getServer().getPluginManager().registerEvents( - new ModerationListener(punishmentService), plugin - ); // Discord listener if (discordIntegration.isEnabled()) { diff --git a/src/main/java/com/loki/lochat/core/PluginShutdown.java b/src/main/java/com/loki/lochat/core/PluginShutdown.java index ed76d09..02a7837 100644 --- a/src/main/java/com/loki/lochat/core/PluginShutdown.java +++ b/src/main/java/com/loki/lochat/core/PluginShutdown.java @@ -5,7 +5,6 @@ import com.loki.lochat.api.service.MessagingService; import com.loki.lochat.api.service.MuteService; import com.loki.lochat.api.service.NickService; import com.loki.lochat.api.service.PlayerService; -import com.loki.lochat.api.service.PunishmentService; import com.loki.lochat.core.registry.ServiceRegistry; import com.loki.lochat.gradient.GradientModule; import com.loki.lochat.integrations.DiscordIntegration; @@ -82,11 +81,6 @@ public class PluginShutdown { muteService.save(); } - PunishmentService punishmentService = serviceRegistry.get(PunishmentService.class); - if (punishmentService != null) { - punishmentService.save(); - } - // Ники NickService nickService = serviceRegistry.get(NickService.class); if (nickService != null) { diff --git a/src/main/java/com/loki/lochat/core/registry/ServiceRegistry.java b/src/main/java/com/loki/lochat/core/registry/ServiceRegistry.java index 7f3ca47..4b9cfb4 100644 --- a/src/main/java/com/loki/lochat/core/registry/ServiceRegistry.java +++ b/src/main/java/com/loki/lochat/core/registry/ServiceRegistry.java @@ -9,7 +9,6 @@ import com.loki.lochat.api.service.MessagingService; import com.loki.lochat.api.service.MuteService; import com.loki.lochat.api.service.NickService; import com.loki.lochat.api.service.PlayerService; -import com.loki.lochat.api.service.PunishmentService; import com.loki.lochat.api.service.pm.PrivateMessageService; import com.loki.lochat.config.ConfigManager; import com.loki.lochat.config.MessageConfig; @@ -20,7 +19,6 @@ import com.loki.lochat.core.service.MentionServiceImpl; import com.loki.lochat.core.service.MessageServiceImpl; import com.loki.lochat.core.service.NickServiceImpl; import com.loki.lochat.core.service.PlayerServiceImpl; -import com.loki.lochat.core.service.PunishmentServiceImpl; import com.loki.lochat.core.service.messaging.PrivateMessageServiceImpl; import org.bukkit.plugin.java.JavaPlugin; @@ -64,7 +62,6 @@ public class ServiceRegistry { register(MentionService.class, new MentionServiceImpl(configManager)); register(NickService.class, new NickServiceImpl(plugin)); - register(PunishmentService.class, new PunishmentServiceImpl(plugin, configManager.getMessagesConfig())); } public void register(Class serviceClass, T implementation) { diff --git a/src/main/java/com/loki/lochat/core/service/PunishmentServiceImpl.java b/src/main/java/com/loki/lochat/core/service/PunishmentServiceImpl.java deleted file mode 100644 index ba33009..0000000 --- a/src/main/java/com/loki/lochat/core/service/PunishmentServiceImpl.java +++ /dev/null @@ -1,199 +0,0 @@ -package com.loki.lochat.core.service; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.loki.lochat.api.service.PunishmentService; -import com.loki.lochat.config.MessagesConfig; -import com.loki.lochat.data.model.BanRecord; -import com.loki.lochat.data.model.WarnEntry; -import com.loki.lochat.utils.format.ChatFormatter; -import com.loki.lochat.utils.format.TimeFormatter; -import com.loki.lochat.utils.persistence.FilePersistence; -import com.loki.lochat.utils.platform.FoliaUtil; - -import net.kyori.adventure.text.Component; - -import org.bukkit.plugin.java.JavaPlugin; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Варны и баны в punishments.json - */ -public class PunishmentServiceImpl implements PunishmentService { - - private final JavaPlugin plugin; - private final MessagesConfig messages; - private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); - - private final Map> warns = new ConcurrentHashMap<>(); - private final Map bans = new ConcurrentHashMap<>(); - - public PunishmentServiceImpl(JavaPlugin plugin, MessagesConfig messagesConfig) { - this.plugin = plugin; - this.messages = messagesConfig; - load(); - } - - @Override - public void addWarn(UUID uuid, String playerName, String moderator, String reason, boolean silent) { - WarnEntry entry = new WarnEntry(System.currentTimeMillis(), moderator, reason, silent); - warns.computeIfAbsent(uuid, k -> Collections.synchronizedList(new ArrayList<>())).add(entry); - saveAsync(); - } - - @Override - public List getWarns(UUID uuid) { - List list = warns.get(uuid); - if (list == null) { - return List.of(); - } - synchronized (list) { - return List.copyOf(list); - } - } - - @Override - public int getWarnCount(UUID uuid) { - List list = warns.get(uuid); - return list == null ? 0 : list.size(); - } - - @Override - public void ban(UUID uuid, String playerName, long durationMs, String reason, String bannedBy) { - long until = durationMs <= 0 ? 0 : System.currentTimeMillis() + durationMs; - BanRecord record = new BanRecord(uuid, playerName, reason, bannedBy, until, System.currentTimeMillis()); - bans.put(uuid, record); - saveAsync(); - } - - @Override - public boolean unban(UUID uuid) { - BanRecord removed = bans.remove(uuid); - if (removed != null) { - saveAsync(); - return true; - } - return false; - } - - @Override - public boolean isBanned(UUID uuid) { - BanRecord b = bans.get(uuid); - if (b == null) { - return false; - } - if (b.isPermanent()) { - return true; - } - if (b.isExpired()) { - bans.remove(uuid, b); - return false; - } - return true; - } - - @Override - public BanRecord getActiveBan(UUID uuid) { - if (!isBanned(uuid)) { - return null; - } - return bans.get(uuid); - } - - @Override - public Component buildBanKickMessage(BanRecord ban) { - String reason = ban.reason != null ? ban.reason : messages.getModerationDefaultReason(); - String mod = ban.bannedBy != null ? ban.bannedBy : "?"; - String duration; - if (ban.isPermanent()) { - duration = messages.getModerationDurationPermanent(); - } else { - long left = Math.max(0, ban.until - System.currentTimeMillis()); - duration = TimeFormatter.format(left); - } - String template = messages.getBanKickMessage(); - String filled = template - .replace("{reason}", reason) - .replace("{moderator}", mod) - .replace("{duration}", duration) - .replace("{player}", ban.playerName != null ? ban.playerName : "?"); - return ChatFormatter.parse(filled); - } - - @Override - public void save() { - PunishmentSnapshot snap = new PunishmentSnapshot(); - for (Map.Entry> e : warns.entrySet()) { - List list = e.getValue(); - synchronized (list) { - snap.getWarns().put(e.getKey().toString(), new ArrayList<>(list)); - } - } - for (Map.Entry e : bans.entrySet()) { - snap.getBans().put(e.getKey().toString(), e.getValue()); - } - FilePersistence.saveJson(plugin, "punishments.json", snap, gson); - } - - @Override - public void reload() { - warns.clear(); - bans.clear(); - load(); - } - - private void saveAsync() { - FoliaUtil.runAsync(plugin, this::save); - } - - private void load() { - PunishmentSnapshot snap = FilePersistence.loadJson(plugin, "punishments.json", PunishmentSnapshot.class, gson); - if (snap == null) { - return; - } - if (snap.getWarns() != null) { - for (Map.Entry> e : snap.getWarns().entrySet()) { - try { - warns.put(UUID.fromString(e.getKey()), Collections.synchronizedList(new ArrayList<>(e.getValue()))); - } catch (IllegalArgumentException ignored) { - } - } - } - if (snap.getBans() != null) { - for (Map.Entry e : snap.getBans().entrySet()) { - try { - UUID id = UUID.fromString(e.getKey()); - BanRecord br = e.getValue(); - if (br != null) { - br.uuid = id; - if (!br.isPermanent() && br.isExpired()) { - continue; - } - bans.put(id, br); - } - } catch (IllegalArgumentException ignored) { - } - } - } - } - - private static class PunishmentSnapshot { - private Map> warns = new HashMap<>(); - private Map bans = new HashMap<>(); - - Map> getWarns() { - return warns; - } - - Map getBans() { - return bans; - } - } -} diff --git a/src/main/java/com/loki/lochat/data/model/BanRecord.java b/src/main/java/com/loki/lochat/data/model/BanRecord.java deleted file mode 100644 index f5471b6..0000000 --- a/src/main/java/com/loki/lochat/data/model/BanRecord.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.loki.lochat.data.model; - -import java.util.UUID; - -/** - * Активная блокировка - */ -public class BanRecord { - public UUID uuid; - public String playerName; - public String reason; - public String bannedBy; - /** 0 = перманент; иначе timestamp окончания бана */ - public long until; - public long createdAt; - - public BanRecord() { - } - - public BanRecord(UUID uuid, String playerName, String reason, String bannedBy, long until, long createdAt) { - this.uuid = uuid; - this.playerName = playerName; - this.reason = reason; - this.bannedBy = bannedBy; - this.until = until; - this.createdAt = createdAt; - } - - public boolean isPermanent() { - return until == 0; - } - - public boolean isExpired() { - if (isPermanent()) { - return false; - } - return System.currentTimeMillis() >= until; - } -} diff --git a/src/main/java/com/loki/lochat/data/model/WarnEntry.java b/src/main/java/com/loki/lochat/data/model/WarnEntry.java deleted file mode 100644 index 1858d08..0000000 --- a/src/main/java/com/loki/lochat/data/model/WarnEntry.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.loki.lochat.data.model; - -/** - * Запись о варне (для JSON) - */ -public class WarnEntry { - public long time; - public String moderator; - public String reason; - public boolean silent; - - public WarnEntry() { - } - - public WarnEntry(long time, String moderator, String reason, boolean silent) { - this.time = time; - this.moderator = moderator; - this.reason = reason; - this.silent = silent; - } -} diff --git a/src/main/java/com/loki/lochat/integrations/LibertyBansHook.java b/src/main/java/com/loki/lochat/integrations/LibertyBansHook.java deleted file mode 100644 index 6dc52ee..0000000 --- a/src/main/java/com/loki/lochat/integrations/LibertyBansHook.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.loki.lochat.integrations; - -import com.loki.lochat.LoChat; -import com.loki.lochat.api.service.MuteService; - -import org.bukkit.entity.Player; - -/** - * Заглушка для совместимости с LibertyBans - * Теперь используется встроенная система мутов LoChat - */ -public class LibertyBansHook { - - private final MuteService muteService; - - public LibertyBansHook(LoChat plugin) { - this.muteService = plugin.getServiceRegistry().get(MuteService.class); - - // Проверяем наличие LibertyBans - if (plugin.getServer().getPluginManager().getPlugin("LibertyBans") != null) { - plugin.getLogger().info("LibertyBans обнаружен. Используйте встроенную систему мутов LoChat (/lmute, /lunmute)"); - } - } - - /** - * Проверяет, замучен ли игрок через встроенную систему LoChat - */ - public boolean isMuted(Player player) { - return muteService.isMuted(player.getUniqueId()); - } - - public boolean isEnabled() { - return true; // Всегда используем встроенную систему - } - - public boolean isPluginPresent() { - return true; - } -} diff --git a/src/main/java/com/loki/lochat/listener/ModerationListener.java b/src/main/java/com/loki/lochat/listener/ModerationListener.java deleted file mode 100644 index 3b4f260..0000000 --- a/src/main/java/com/loki/lochat/listener/ModerationListener.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.loki.lochat.listener; - -import com.loki.lochat.api.service.PunishmentService; -import com.loki.lochat.compat.Msg; -import com.loki.lochat.data.model.BanRecord; - -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.AsyncPlayerPreLoginEvent; - -/** - * Блокировка входа забаненным игрокам - */ -public class ModerationListener implements Listener { - - private final PunishmentService punishmentService; - - public ModerationListener(PunishmentService punishmentService) { - this.punishmentService = punishmentService; - } - - @EventHandler(priority = EventPriority.LOWEST) - public void onPreLogin(AsyncPlayerPreLoginEvent event) { - if (!punishmentService.isBanned(event.getUniqueId())) { - return; - } - BanRecord ban = punishmentService.getActiveBan(event.getUniqueId()); - if (ban == null) { - return; - } - event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_BANNED, Msg.legacy(punishmentService.buildBanKickMessage(ban))); - } -} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index fedea1f..5e79e5d 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -171,9 +171,7 @@ filters: moderation: default-mute-duration: "7d" default-mute-reason: "No reason specified" - default-ban-reason: "No reason specified" voice-mute-console-command: "" - ban-kick-message: "&cYou have been banned!\n&7Reason: &f{reason}" # ── Sounds ───────────────────────────────────────────────────────────────────── diff --git a/src/main/resources/config/messages.yml b/src/main/resources/config/messages.yml index f7ff89a..0221640 100644 --- a/src/main/resources/config/messages.yml +++ b/src/main/resources/config/messages.yml @@ -106,18 +106,3 @@ general: moderation: default-reason: "No reason specified" duration-permanent: "permanent" - warn-received: "&6\u26A0 &cYou received a warning! &7Reason: &f{reason}" - warn-staff-confirm: "&aPlayer &f{player} &awarned. &7Reason: &f{reason}" - silent-warn-staff: "&8[&7SILENT&8] &f{player}&7: &7{reason}" - ban-usage: "&cUsage: &f/lban [time|perm] [reason]" - ban-confirm: "&aPlayer &f{player} &abanned. &7Duration: &f{duration}" - unban-confirm: "&aBan lifted for &f{player}" - not-banned: "&cPlayer is not banned!" - already-banned: "&cPlayer is already banned!" - warn-usage: "&cUsage: &f/warn [reason]" - silent-warn-usage: "&cUsage: &f/silentwarn [reason]" - ban-kick-message: | - You are banned from this server. - Reason: {reason} - Moderator: {moderator} - Duration: {duration} diff --git a/src/main/resources/config/mute.yml b/src/main/resources/config/mute.yml index 848fbc6..0226dec 100644 --- a/src/main/resources/config/mute.yml +++ b/src/main/resources/config/mute.yml @@ -132,7 +132,7 @@ auto-mute: duration: "1h" reason: "Auto-mute: advertising" -# ── Punishment Escalation ────────────────────────────────────────────────────── +# ── Mute Escalation ────────────────────────────────────────────────────────────── escalation: enabled: true @@ -238,11 +238,6 @@ features: - "say" - "tell" - warnings: - enabled: true - max-warnings: 3 - reset-time: 3600 - appeals: enabled: false command: "/appeal" diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 82393c9..4ae43bb 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -9,7 +9,6 @@ softdepend: - PlaceholderAPI - PlayerPoints - LuckPerms - - LibertyBans - SkinsRestorer commands: @@ -163,30 +162,6 @@ commands: permission: lochat.muteblame aliases: [ muteblame, мутблейм, ьгеуидфьу ] - warn: - description: Warn a player (visible to them) - usage: /warn [reason] - permission: lochat.warn - aliases: [ w, варн ] - - silentwarn: - description: Silent warn (logged; staff with lochat.warn.notify see) - usage: /silentwarn [reason] - permission: lochat.warn.silent - aliases: [ siw ] - - lban: - description: Ban a player - usage: /lban [time|perm] [reason] - permission: lochat.ban - aliases: [ ban, бан ] - - lunban: - description: Unban a player - usage: /lunban - permission: lochat.unban - aliases: [ unban, разбан ] - playerinfo: description: Player info and moderation stats usage: /playerinfo @@ -393,30 +368,6 @@ permissions: description: Can use /appeal command default: true - lochat.warn: - description: Issue a visible warning - default: op - lochat.warn.silent: - description: Issue a silent warning - default: op - lochat.warn.notify: - description: See silent warn notifications - default: op - lochat.ban: - description: Ban players - default: op - lochat.ban.override: - description: Ban players with lochat.bypass.ban - default: op - lochat.unban: - description: Unban players - default: op - lochat.bypass.warn: - description: Immune to /warn - default: false - lochat.bypass.ban: - description: Immune to /lban (unless staff has lochat.ban.override) - default: false lochat.playerinfo: description: View player moderation stats default: op