trim: moderation → mute only

- remove ban/warn commands: BanCommand (/lban), UnbanCommand (/lunban),
  WarnCommand (/warn), SilentWarnCommand (silentwarn) and empty ban/warn dirs
- plugin.yml: remove commands lban/lunban/warn/silentwarn and
  permissions lochat.ban/lochat.unban/lochat.warn/lochat.warn.silent/
  lochat.warn.notify/lochat.bypass.warn/lochat.bypass.ban/lochat.ban.override;
  remove LibertyBans from softdepend
- remove registration in CommandManager and PluginInitializer
  (LibertyBansHook, ModerationListener)
- delete PunishmentService api+impl, BanRecord/WarnEntry models,
  ModerationListener, LibertyBansHook; strip ServiceRegistry/PluginInitializer/
  LoChat reload and PlayerInfoCommand (warn/ban sections)
- config: remove moderation.default-ban-reason/ban-kick-message from
  config.yml, ban/warn keys from config/messages.yml, escalation header
  Punishment->Mute in mute.yml
- MessagesConfig.java: remove ban/warn getters (keep mute)
- README: remove /lban /warn rows, update features to mute-only
- preserve /lmute /lunmute /lmutelist /lmuteblame, MuteService, mute.yml,
  mutes.json format and HIGHEST chat handler
This commit is contained in:
loki5512344 2026-09-20 16:44:39 +02:00
parent 7f513a7104
commit 83e980d1bb
Signed by: boba
GPG key ID: 253067914055423B
22 changed files with 7 additions and 1030 deletions

View file

@ -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) {
}
}
}
// Геттеры

View file

@ -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<WarnEntry> 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();
}

View file

@ -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));

View file

@ -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<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
@NotNull String alias, @NotNull String[] args) {
List<String> 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;
}
}

View file

@ -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Использование: &#7858E9/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<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
@NotNull String alias, @NotNull String[] args) {
List<String> 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;
}
}

View file

@ -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<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
@NotNull String alias, @NotNull String[] args) {
List<String> 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;
}
}

View file

@ -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<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
@NotNull String alias, @NotNull String[] args) {
List<String> 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;
}
}

View file

@ -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("&#9878C9⚡ &fГрадиент: " + plugin.getGradientModule().getFormattedName(target)));
}
int warns = punishmentService.getWarnCount(uuid);
Msg.send(sender, ChatFormatter.parse("&#CF6679⚠ &fВарнов всего: &#7858E9" + warns));
List<WarnEntry> 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 + "&#9878C9• &7" + formatTime(t) + " &#B798A8от &#7858E9" + w.moderator + "&#9878C9: &f" + reason));
}
BanRecord ban = punishmentService.getActiveBan(uuid);
if (ban != null) {
String until = ban.isPermanent()
? "&#CF6679навсегда"
: "&#7858E9" + 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("&#9878C9🚫 &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<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
@NotNull String alias, @NotNull String[] args) {

View file

@ -157,7 +157,7 @@ public class MessagesConfig extends BaseConfig {
return getConfig().getString("ignore.ignore_list_header", "&#B798A8Игнорируемые игроки&#9878C9:");
}
// ── Модерация (варны / баны) ────────────────────────────────────────────────
// ── Модерация ────────────────────────────────────────────────────────────────
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 "<gradient:#FF5555:#8B0000><bold>═══════ ДОСТУП ЗАПРЕЩЁН ═══════</bold></gradient>\n"
+ "<gray>Вы заблокированы на этом сервере.</gray>\n"
+ "<white>Причина: <gradient:#7858E9:#B798A8>{reason}</gradient></white>\n"
+ "<gray>Модератор: <white>{moderator}</white></gray>\n"
+ "<gray>Срок: <#7858E9>{duration}</#7858E9></gray>\n"
+ "<gradient:#FF5555:#8B0000><bold>════════════════════════</bold></gradient>";
}
public String getWarnReceived() {
return getConfig().getString("moderation.warn_received", "&#CF6679⚠ Вам выдано предупреждение! &#B798A8Причина: &#7858E9{reason}");
}
public String getWarnStaffConfirm() {
return getConfig().getString("moderation.warn_staff_confirm", "&#9878C9Игроку &#7858E9{player} &#9878C9выдан"
+ "варн. &#B798A8Причина: &#7858E9{reason}");
}
public String getSilentWarnStaff() {
return getConfig().getString("moderation.silent_warn_staff",
"&#B798A8[&#9878C9ТИХИЙ ВАРН&#B798A8] &#7858E9{player}&#9878C9: &#B798A8{reason}");
}
public String getBanUsage() {
return getConfig().getString("moderation.ban_usage", "&#B798A8Использование: &#7858E9/lban <ник> [время|perm] [причина]");
}
public String getBanConfirm() {
return getConfig().getString("moderation.ban_confirm", "&#9878C9Игрок &#7858E9{player} &#9878C9забанен."
+ "&#B798A8Срок: &#7858E9{duration}");
}
public String getUnbanConfirm() {
return getConfig().getString("moderation.unban_confirm", "&#9878C9Бан снят с &#7858E9{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Использование: &#7858E9/warn <ник> [причина]");
}
public String getSilentWarnUsage() {
return getConfig().getString("moderation.silent_warn_usage", "&#B798A8Использование: &#7858E9/silentwarn <ник> [причина]");
}
}

View file

@ -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()) {

View file

@ -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) {

View file

@ -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 <T> void register(Class<T> serviceClass, T implementation) {

View file

@ -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<UUID, List<WarnEntry>> warns = new ConcurrentHashMap<>();
private final Map<UUID, BanRecord> 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<WarnEntry> getWarns(UUID uuid) {
List<WarnEntry> list = warns.get(uuid);
if (list == null) {
return List.of();
}
synchronized (list) {
return List.copyOf(list);
}
}
@Override
public int getWarnCount(UUID uuid) {
List<WarnEntry> 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<UUID, List<WarnEntry>> e : warns.entrySet()) {
List<WarnEntry> list = e.getValue();
synchronized (list) {
snap.getWarns().put(e.getKey().toString(), new ArrayList<>(list));
}
}
for (Map.Entry<UUID, BanRecord> 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<String, List<WarnEntry>> 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<String, BanRecord> 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<String, List<WarnEntry>> warns = new HashMap<>();
private Map<String, BanRecord> bans = new HashMap<>();
Map<String, List<WarnEntry>> getWarns() {
return warns;
}
Map<String, BanRecord> getBans() {
return bans;
}
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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)));
}
}