diff --git a/src/main/java/com/loki/lochat/LoChat.java b/src/main/java/com/loki/lochat/LoChat.java index 37041ff..93d79cb 100644 --- a/src/main/java/com/loki/lochat/LoChat.java +++ b/src/main/java/com/loki/lochat/LoChat.java @@ -28,6 +28,7 @@ public final class LoChat extends JavaPlugin { private EmojiManager emojiManager; private ChatColorManager chatColorManager; private CustomCommandManager customCommandManager; + private MuteManager muteManager; private GradientModule gradientModule; private com.loki.lochat.listeners.DisplayNameListener displayNameListener; @@ -50,6 +51,7 @@ public final class LoChat extends JavaPlugin { spyManager = new SpyManager(this); chatColorManager = new ChatColorManager(this); customCommandManager = new CustomCommandManager(this); + muteManager = new MuteManager(this); chatManager = new ChatManager(this); autoMessageManager = new AutoMessageManager(this); @@ -90,6 +92,9 @@ public final class LoChat extends JavaPlugin { if (chatColorManager != null) { chatColorManager.saveData(); } + if (muteManager != null) { + muteManager.saveData(); + } if (gradientModule != null) { gradientModule.shutdown(); } @@ -107,6 +112,8 @@ public final class LoChat extends JavaPlugin { getCommand("announce").setExecutor(new AnnounceCommand(this)); getCommand("chatspy").setExecutor(new ChatSpyCommand(this)); getCommand("clearchat").setExecutor(new ClearChatCommand(this)); + getCommand("mute").setExecutor(new MuteCommand(this)); + getCommand("unmute").setExecutor(new UnmuteCommand(this)); getCommand("chatcolor").setExecutor(new ChatColorCommand(this)); LoChatCommand loChatCommand = new LoChatCommand(this); @@ -195,6 +202,10 @@ public final class LoChat extends JavaPlugin { return customCommandManager; } + public MuteManager getMuteManager() { + return muteManager; + } + public com.loki.lochat.listeners.DisplayNameListener getDisplayNameListener() { return displayNameListener; } diff --git a/src/main/java/com/loki/lochat/commands/MuteCommand.java b/src/main/java/com/loki/lochat/commands/MuteCommand.java new file mode 100644 index 0000000..d840817 --- /dev/null +++ b/src/main/java/com/loki/lochat/commands/MuteCommand.java @@ -0,0 +1,122 @@ +package com.loki.lochat.commands; + +import com.loki.lochat.LoChat; +import com.loki.lochat.utils.ChatFormatter; +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.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class MuteCommand implements CommandExecutor, TabCompleter { + + private final LoChat plugin; + + public MuteCommand(LoChat plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if (!sender.hasPermission("chat.mute")) { + sender.sendMessage(ChatFormatter.parse(plugin.getMessageConfig().getNoPermission())); + return true; + } + + if (args.length < 2) { + sender.sendMessage(ChatFormatter.parse(plugin.getMessageConfig().getInvalidUsage("/mute <игрок> <время> [причина]"))); + sender.sendMessage(ChatFormatter.parse("Время: 1m, 1h, 1d, permanent")); + return true; + } + + String playerName = args[0]; + String timeStr = args[1]; + String reason = args.length > 2 ? String.join(" ", Arrays.copyOfRange(args, 2, args.length)) : "Нарушение правил чата"; + + Player target = Bukkit.getPlayer(playerName); + if (target == null) { + sender.sendMessage(ChatFormatter.parse(plugin.getMessageConfig().getPlayerNotFound())); + return true; + } + + // Парсим время + long duration = parseTime(timeStr); + if (duration == -1) { + sender.sendMessage(ChatFormatter.parse("Неверный формат времени! Используйте: 1m, 1h, 1d, permanent")); + return true; + } + + // Мутим игрока + plugin.getMuteManager().mutePlayer(target.getUniqueId(), duration, reason, sender.getName()); + + // Уведомления + String timeDisplay = duration == 0 ? "навсегда" : formatTime(duration); + sender.sendMessage(ChatFormatter.parse( + plugin.getMessageConfig().get("mute.muted", "{player}", target.getName(), "{time}", timeDisplay) + )); + + if (target.isOnline()) { + target.sendMessage(ChatFormatter.parse( + plugin.getMessageConfig().get("mute.you-muted", "{time}", timeDisplay) + )); + } + + return true; + } + + private long parseTime(String timeStr) { + if (timeStr.equalsIgnoreCase("permanent") || timeStr.equalsIgnoreCase("perm")) { + return 0; // 0 = permanent + } + + try { + char unit = timeStr.charAt(timeStr.length() - 1); + int amount = Integer.parseInt(timeStr.substring(0, timeStr.length() - 1)); + + return switch (unit) { + case 'm' -> amount * 60L * 1000L; // минуты + case 'h' -> amount * 60L * 60L * 1000L; // часы + case 'd' -> amount * 24L * 60L * 60L * 1000L; // дни + default -> -1; + }; + } catch (NumberFormatException | StringIndexOutOfBoundsException e) { + return -1; + } + } + + private String formatTime(long millis) { + long seconds = millis / 1000; + long minutes = seconds / 60; + long hours = minutes / 60; + long days = hours / 24; + + if (days > 0) return days + "д"; + if (hours > 0) return hours + "ч"; + if (minutes > 0) return minutes + "м"; + return seconds + "с"; + } + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { + if (args.length == 1) { + return Bukkit.getOnlinePlayers().stream() + .map(Player::getName) + .filter(name -> name.toLowerCase().startsWith(args[0].toLowerCase())) + .collect(Collectors.toList()); + } else if (args.length == 2) { + List times = Arrays.asList("1m", "5m", "10m", "30m", "1h", "2h", "6h", "12h", "1d", "3d", "7d", "permanent"); + return times.stream() + .filter(time -> time.toLowerCase().startsWith(args[1].toLowerCase())) + .collect(Collectors.toList()); + } + return new ArrayList<>(); + } +} \ No newline at end of file diff --git a/src/main/java/com/loki/lochat/commands/UnmuteCommand.java b/src/main/java/com/loki/lochat/commands/UnmuteCommand.java new file mode 100644 index 0000000..6132f54 --- /dev/null +++ b/src/main/java/com/loki/lochat/commands/UnmuteCommand.java @@ -0,0 +1,76 @@ +package com.loki.lochat.commands; + +import com.loki.lochat.LoChat; +import com.loki.lochat.utils.ChatFormatter; +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.List; +import java.util.stream.Collectors; + +public class UnmuteCommand implements CommandExecutor, TabCompleter { + + private final LoChat plugin; + + public UnmuteCommand(LoChat plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if (!sender.hasPermission("chat.mute")) { + sender.sendMessage(ChatFormatter.parse(plugin.getMessageConfig().getNoPermission())); + return true; + } + + if (args.length != 1) { + sender.sendMessage(ChatFormatter.parse(plugin.getMessageConfig().getInvalidUsage("/unmute <игрок>"))); + return true; + } + + String playerName = args[0]; + Player target = Bukkit.getPlayer(playerName); + if (target == null) { + sender.sendMessage(ChatFormatter.parse(plugin.getMessageConfig().getPlayerNotFound())); + return true; + } + + if (!plugin.getMuteManager().isMuted(target.getUniqueId())) { + sender.sendMessage(ChatFormatter.parse( + plugin.getMessageConfig().get("mute.not-muted", "{player}", target.getName()) + )); + return true; + } + + // Размучиваем + plugin.getMuteManager().unmutePlayer(target.getUniqueId()); + + // Уведомления + sender.sendMessage(ChatFormatter.parse( + plugin.getMessageConfig().get("mute.unmuted", "{player}", target.getName()) + )); + + if (target.isOnline()) { + target.sendMessage(ChatFormatter.parse("Вы были размучены!")); + } + + return true; + } + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { + if (args.length == 1) { + return Bukkit.getOnlinePlayers().stream() + .map(Player::getName) + .filter(name -> name.toLowerCase().startsWith(args[0].toLowerCase())) + .collect(Collectors.toList()); + } + return null; + } +} \ No newline at end of file diff --git a/src/main/java/com/loki/lochat/integrations/PlaceholderAPIHook.java b/src/main/java/com/loki/lochat/integrations/PlaceholderAPIHook.java index 00b5c50..dd8684f 100644 --- a/src/main/java/com/loki/lochat/integrations/PlaceholderAPIHook.java +++ b/src/main/java/com/loki/lochat/integrations/PlaceholderAPIHook.java @@ -57,6 +57,17 @@ public class PlaceholderAPIHook extends PlaceholderExpansion { } case "spy_enabled" -> String.valueOf(plugin.getSpyManager().isSpying(uuid)); + // Mute placeholders + case "muted" -> String.valueOf(plugin.getMuteManager().isMuted(uuid)); + case "mute_time" -> { + if (!plugin.getMuteManager().isMuted(uuid)) yield ""; + yield plugin.getMuteManager().formatRemainingTime(uuid); + } + case "mute_reason" -> { + var muteData = plugin.getMuteManager().getMuteData(uuid); + yield muteData != null ? muteData.reason : ""; + } + // Gradient placeholders (совместимость с LoPreff) case "gradient_full", "full" -> { Player onlinePlayer = player.getPlayer(); diff --git a/src/main/java/com/loki/lochat/listeners/ChatListener.java b/src/main/java/com/loki/lochat/listeners/ChatListener.java index 1e05447..758ca2c 100644 --- a/src/main/java/com/loki/lochat/listeners/ChatListener.java +++ b/src/main/java/com/loki/lochat/listeners/ChatListener.java @@ -34,6 +34,19 @@ public class ChatListener implements Listener { } private void processChat(Player player, String message) { + // Проверка мута + if (plugin.getMuteManager().isMuted(player.getUniqueId())) { + String timeLeft = plugin.getMuteManager().formatRemainingTime(player.getUniqueId()); + if (timeLeft.equals("навсегда")) { + player.sendMessage(ChatFormatter.parse(plugin.getMessageConfig().get("mute.permanent"))); + } else { + player.sendMessage(ChatFormatter.parse( + plugin.getMessageConfig().get("mute.you-muted", "{time}", timeLeft) + )); + } + return; + } + String globalSymbol = plugin.getConfigManager().getGlobalSymbol(); boolean isGlobal = message.startsWith(globalSymbol) && player.hasPermission("chat.global.use"); String chatType = isGlobal ? "global" : "local"; diff --git a/src/main/java/com/loki/lochat/managers/MuteManager.java b/src/main/java/com/loki/lochat/managers/MuteManager.java new file mode 100644 index 0000000..39b9e61 --- /dev/null +++ b/src/main/java/com/loki/lochat/managers/MuteManager.java @@ -0,0 +1,147 @@ +package com.loki.lochat.managers; + +import com.loki.lochat.LoChat; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class MuteManager { + + private final LoChat plugin; + private final Map mutedPlayers; + private File dataFile; + private FileConfiguration dataConfig; + + public MuteManager(LoChat plugin) { + this.plugin = plugin; + this.mutedPlayers = new HashMap<>(); + loadData(); + } + + private void loadData() { + dataFile = new File(plugin.getDataFolder(), "mutes.yml"); + if (!dataFile.exists()) { + try { + dataFile.createNewFile(); + } catch (IOException e) { + plugin.getLogger().severe("Не удалось создать файл mutes.yml: " + e.getMessage()); + } + } + + dataConfig = YamlConfiguration.loadConfiguration(dataFile); + + // Загружаем муты из файла + for (String key : dataConfig.getKeys(false)) { + try { + UUID uuid = UUID.fromString(key); + long expiry = dataConfig.getLong(key + ".expiry"); + String reason = dataConfig.getString(key + ".reason", "Нарушение правил"); + String mutedBy = dataConfig.getString(key + ".muted_by", "Система"); + + // Проверяем не истёк ли мут + if (expiry > 0 && System.currentTimeMillis() > expiry) { + dataConfig.set(key, null); + continue; + } + + mutedPlayers.put(uuid, new MuteData(expiry, reason, mutedBy)); + } catch (IllegalArgumentException ignored) { + // Неверный UUID, пропускаем + } + } + + saveData(); + } + + public void saveData() { + for (Map.Entry entry : mutedPlayers.entrySet()) { + String key = entry.getKey().toString(); + MuteData data = entry.getValue(); + + dataConfig.set(key + ".expiry", data.expiry); + dataConfig.set(key + ".reason", data.reason); + dataConfig.set(key + ".muted_by", data.mutedBy); + } + + try { + dataConfig.save(dataFile); + } catch (IOException e) { + plugin.getLogger().severe("Не удалось сохранить mutes.yml: " + e.getMessage()); + } + } + + public void mutePlayer(UUID playerId, long duration, String reason, String mutedBy) { + long expiry = duration == 0 ? 0 : System.currentTimeMillis() + duration; + mutedPlayers.put(playerId, new MuteData(expiry, reason, mutedBy)); + saveData(); + } + + public void unmutePlayer(UUID playerId) { + mutedPlayers.remove(playerId); + dataConfig.set(playerId.toString(), null); + saveData(); + } + + public boolean isMuted(UUID playerId) { + MuteData data = mutedPlayers.get(playerId); + if (data == null) return false; + + // Проверяем не истёк ли мут + if (data.expiry > 0 && System.currentTimeMillis() > data.expiry) { + unmutePlayer(playerId); + return false; + } + + return true; + } + + public MuteData getMuteData(UUID playerId) { + return mutedPlayers.get(playerId); + } + + public long getRemainingTime(UUID playerId) { + MuteData data = mutedPlayers.get(playerId); + if (data == null || data.expiry == 0) return 0; + + long remaining = data.expiry - System.currentTimeMillis(); + return Math.max(0, remaining); + } + + public String formatRemainingTime(UUID playerId) { + long remaining = getRemainingTime(playerId); + if (remaining == 0) { + MuteData data = getMuteData(playerId); + if (data != null && data.expiry == 0) { + return "навсегда"; + } + return "0с"; + } + + long seconds = remaining / 1000; + long minutes = seconds / 60; + long hours = minutes / 60; + long days = hours / 24; + + if (days > 0) return days + "д " + (hours % 24) + "ч"; + if (hours > 0) return hours + "ч " + (minutes % 60) + "м"; + if (minutes > 0) return minutes + "м " + (seconds % 60) + "с"; + return seconds + "с"; + } + + public static class MuteData { + public final long expiry; // 0 = permanent + public final String reason; + public final String mutedBy; + + public MuteData(long expiry, String reason, String mutedBy) { + this.expiry = expiry; + this.reason = reason; + this.mutedBy = mutedBy; + } + } +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 1f4c151..f880a12 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -40,19 +40,106 @@ mentions: sound: true sound-type: "BLOCK_NOTE_BLOCK_PLING" # Выделение при @ник - highlight: "@{player}" + highlight: "<#04CADF>@{player}" # Выделение когда твой ник написали (без @) - self-highlight: "{player}" + self-highlight: "<#04CADF>{player}" # Фильтр мата filter: enabled: true + # Регулярные выражения для обнаружения мата с обходами + patterns: + # Основные корни с вариациями + - "х\\s*у\\s*[йяёе]" # хуй, хуя, хуё, хуе + - "[хx]\\s*у\\s*[йяёе]" # латиница: xuй + - "п\\s*[иi]\\s*з\\s*д" # пизд, пiзд + - "п\\s*[иi]\\s*д\\s*[оа]\\s*р" # пидор, пидар + - "[еeё]\\s*б\\s*[аоуыи]" # ебать, ебут, ебал + - "б\\s*л\\s*я\\s*[тдь]" # блять, блядь + - "с\\s*у\\s*к\\s*[аи]" # сука, суки + - "м\\s*у\\s*д\\s*[аи]" # муда, муди + - "г\\s*а\\s*н\\s*д\\s*о\\s*н" # гандон + - "д\\s*р\\s*о\\s*ч" # дрочить + - "с\\s*с\\s*а\\s*т\\s*ь" # ссать + - "с\\s*р\\s*а\\s*т\\s*ь" # срать + - "ш\\s*м\\s*а\\s*р\\s*[аи]" # шмара + - "ч\\s*м\\s*[оы]" # чмо, чмы + - "г\\s*н\\s*и\\s*д\\s*[аы]" # гнида + + # Простые слова (для быстрой проверки) words: + # Основные - "хуй" - - "пизд" - - "блять" + - "хуя" + - "хуё" + - "хуе" + - "хуёк" + - "хуёчек" + - "хуесос" + - "хуеплёт" + - "пизда" + - "пизде" + - "пизду" + - "пиздец" + - "пиздюк" + - "пиздюшка" + - "пиздануть" + - "спиздить" + - "пиздоглазый" - "ебать" + - "ебал" + - "ебут" + - "ебись" + - "ебитесь" + - "ебашить" + - "уёбывать" + - "заёбывать" + - "ебашка" + - "ебанарот" + - "блять" + - "блядь" + - "блядина" - "сука" + - "суки" + - "сучка" + - "мудак" + - "мудила" + - "мудачок" + - "гандон" + - "гандоник" + - "пидор" + - "пидорас" + - "дрочить" + - "дрочка" + - "онанист" + - "ссать" + - "срать" + - "говно" + - "говнюк" + - "шмара" + - "шлюха" + - "проститутка" + - "чмо" + - "чмошник" + - "чмырь" + - "гнида" + - "тварь" + - "падла" + - "сволочь" + - "охуеть" + - "ахуеть" + - "нихуя" + - "кончепизд" + + # Обходы с символами + - "х*й" + - "п@зда" + - "б#ять" + - "хуй" + - "ebat" + - "pidar" + - "mudak" + action: "censor" # censor/block/warn replacement: "***" @@ -69,14 +156,14 @@ automessages: random: false formats: - announcement: "[ОБЪЯВЛЕНИЕ] " + announcement: "<#04CADF>[ОБЪЯВЛЕНИЕ] " # Настройки объявлений announcements: # Показывать title при объявлении show-title: true # Заголовок title - title-header: "ОБЪЯВЛЕНИЕ" + title-header: "<#04CADF>ОБЪЯВЛЕНИЕ" # Показывать actionbar при объявлении show-actionbar: true # Время показа title (в секундах) diff --git a/src/main/resources/gradient-messages.yml b/src/main/resources/gradient-messages.yml index f2f89f4..f415046 100644 --- a/src/main/resources/gradient-messages.yml +++ b/src/main/resources/gradient-messages.yml @@ -2,56 +2,56 @@ # Сообщения модуля градиентных ников # Общие -only-player: "§cЭта команда только для игроков!" -no-permission: "§cУ вас нет прав на это действие!" -player-not-found: "§cИгрок не найден!" -reload-success: "§aКонфигурация градиентов перезагружена!" -cooldown: "§cПодождите ещё {time} секунд!" +only-player: "<#04CADF>Эта команда только для игроков!" +no-permission: "<#04CADF>У вас нет прав на это действие!" +player-not-found: "<#04CADF>Игрок не найден!" +reload-success: "<#04CADF>Конфигурация градиентов перезагружена!" +cooldown: "<#04CADF>Подождите ещё {time} секунд!" # Цвета color-help: | - §e=== Команда /color === - §e/color <цвет1> [цвет2] ... §7— установить градиент - §e/color on §7— включить цвет - §e/color off §7— выключить цвет - §e/color reset §7— сбросить цвет - §e/color copy <игрок> §7— скопировать цвет - §7Пример: /color #FF0000 #00FF00 #0000FF -color-enabled: "§aЦвет ника включён!" -color-disabled: "§cЦвет ника выключен!" -color-reset: "§aЦвет ника сброшен!" -color-no-colors: "§cУ вас нет установленных цветов!" -color-success: "§aЦвет успешно установлен! Списано: {price} PP" -color-copy-usage: "§cИспользование: /color copy <игрок>" -color-copy-no-colors: "§cУ игрока {player} нет цветов!" -invalid-color: "§cНеверный формат цвета: {color}. Используйте #RRGGBB" -too-many-colors: "§cМаксимум {max} цветов!" -not-enough-colors: "§cМинимум {min} цветов!" -not-enough-points-color: "§cНедостаточно поинтов! Нужно: {price} PP" + <#04CADF>=== Команда /color === + <#04CADF>/color <цвет1> [цвет2] ... — установить градиент + <#04CADF>/color on — включить цвет + <#04CADF>/color off — выключить цвет + <#04CADF>/color reset — сбросить цвет + <#04CADF>/color copy <игрок> — скопировать цвет + Пример: /color #FF0000 #00FF00 #0000FF +color-enabled: "<#04CADF>Цвет ника включён!" +color-disabled: "<#04CADF>Цвет ника выключен!" +color-reset: "<#04CADF>Цвет ника сброшен!" +color-no-colors: "<#04CADF>У вас нет установленных цветов!" +color-success: "<#04CADF>Цвет успешно установлен! Списано: {price} PP" +color-copy-usage: "<#04CADF>Использование: /color copy <игрок>" +color-copy-no-colors: "<#04CADF>У игрока {player} нет цветов!" +invalid-color: "<#04CADF>Неверный формат цвета: {color}. Используйте #RRGGBB" +too-many-colors: "<#04CADF>Максимум {max} цветов!" +not-enough-colors: "<#04CADF>Минимум {min} цветов!" +not-enough-points-color: "<#04CADF>Недостаточно поинтов! Нужно: {price} PP" # Префикс prefix-help: | - §e=== Команда /prefix === - §e/prefix <текст> §7— установить префикс - §e/prefix on §7— включить префикс - §e/prefix off §7— выключить префикс - §e/prefix reset §7— сбросить префикс -prefix-enabled: "§aПрефикс включён!" -prefix-disabled: "§cПрефикс выключен!" -prefix-reset-success: "§aПрефикс сброшен!" -prefix-no-prefix: "§cУ вас нет установленного префикса!" -prefix-success: "§aПрефикс успешно установлен! Списано: {price} PP" -prefix-success-free: "§aПрефикс успешно изменён!" -prefix-no-colors: "§cПрефикс не может содержать цветовые коды!" -prefix-invalid-chars: "§cПрефикс содержит недопустимые символы!" -prefix-blacklisted: "§cЭтот префикс запрещён!" -prefix-too-long: "§cПрефикс слишком длинный! Максимум: {max} символов" -not-enough-points-prefix: "§cНедостаточно поинтов! Нужно: {price} PP" + <#04CADF>=== Команда /prefix === + <#04CADF>/prefix <текст> — установить префикс + <#04CADF>/prefix on — включить префикс + <#04CADF>/prefix off — выключить префикс + <#04CADF>/prefix reset — сбросить префикс +prefix-enabled: "<#04CADF>Префикс включён!" +prefix-disabled: "<#04CADF>Префикс выключен!" +prefix-reset-success: "<#04CADF>Префикс сброшен!" +prefix-no-prefix: "<#04CADF>У вас нет установленного префикса!" +prefix-success: "<#04CADF>Префикс успешно установлен! Списано: {price} PP" +prefix-success-free: "<#04CADF>Префикс успешно изменён!" +prefix-no-colors: "<#04CADF>Префикс не может содержать цветовые коды!" +prefix-invalid-chars: "<#04CADF>Префикс содержит недопустимые символы!" +prefix-blacklisted: "<#04CADF>Этот префикс запрещён!" +prefix-too-long: "<#04CADF>Префикс слишком длинный! Максимум: {max} символов" +not-enough-points-prefix: "<#04CADF>Недостаточно поинтов! Нужно: {price} PP" # Админ информация -info-header: "§e=== Информация об игроке {player} ===" -info-prefix: "§7Префикс: §f{prefix}" -info-prefix-enabled: "§7Префикс включён: §f{enabled}" -info-colors: "§7Цвета: §f{colors}" -info-color-enabled: "§7Цвет включён: §f{enabled}" -info-prefix-purchased: "§7Префикс куплен: §f{purchased}" +info-header: "<#04CADF>=== Информация об игроке {player} ===" +info-prefix: "Префикс: {prefix}" +info-prefix-enabled: "Префикс включён: {enabled}" +info-colors: "Цвета: {colors}" +info-color-enabled: "Цвет включён: {enabled}" +info-prefix-purchased: "Префикс куплен: {purchased}" diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml index 5b5adfd..15a8747 100644 --- a/src/main/resources/messages.yml +++ b/src/main/resources/messages.yml @@ -1,12 +1,12 @@ -prefix: "[LoChat]" +prefix: "<#04CADF>[LoChat]" global: - disabled: "Глобальный чат отключен" - toggled-on: "Глобальный чат включен" - toggled-off: "Глобальный чат отключен" + disabled: "<#04CADF>Глобальный чат отключен" + toggled-on: "<#04CADF>Глобальный чат включен" + toggled-off: "<#04CADF>Глобальный чат отключен" local: - no-players: "Рядом нет игроков" + no-players: "<#04CADF>Рядом нет игроков" pm: # Форматы личных сообщений @@ -20,42 +20,42 @@ pm: # Старые форматы (для совместимости) sent: "[PM] Ты → {player}: {message}" received: "[PM] {player} → Ты: {message}" - no-reply: "Некому ответить" - ignored: "Этот игрок вас игнорирует" - player-offline: "Игрок не в сети" - self: "Нельзя писать самому себе" + no-reply: "<#04CADF>Некому ответить" + ignored: "<#04CADF>Этот игрок вас игнорирует" + player-offline: "<#04CADF>Игрок не в сети" + self: "<#04CADF>Нельзя писать самому себе" ignore: - added: "Игрок {player} добавлен в игнор" - removed: "Игрок {player} убран из игнора" - already-ignored: "Игрок уже в игноре" - not-ignored: "Игрок не в игноре" - self: "Нельзя игнорировать себя" + added: "<#04CADF>Игрок {player} добавлен в игнор" + removed: "<#04CADF>Игрок {player} убран из игнора" + already-ignored: "<#04CADF>Игрок уже в игноре" + not-ignored: "<#04CADF>Игрок не в игноре" + self: "<#04CADF>Нельзя игнорировать себя" announce: - reloaded: "Конфигурация перезагружена" + reloaded: "<#04CADF>Конфигурация перезагружена" spy: - enabled: "Шпион режим включен" - disabled: "Шпион режим выключен" + enabled: "<#04CADF>Шпион режим включен" + disabled: "<#04CADF>Шпион режим выключен" format: "[SPY] {sender} → {receiver}: {message}" filter: - blocked: "Сообщение заблокировано (мат)" - warned: "Предупреждение: не используйте мат!" + blocked: "<#04CADF>Сообщение заблокировано (мат)" + warned: "<#04CADF>Предупреждение: не используйте мат!" cooldown: - wait: "Подождите {time} сек перед следующим сообщением" + wait: "<#04CADF>Подождите {time} сек перед следующим сообщением" antispam: - caps: "Слишком много заглавных букв!" - repeat: "Не повторяйте символы!" - similar: "Не отправляйте одинаковые сообщения!" + caps: "<#04CADF>Слишком много заглавных букв!" + repeat: "<#04CADF>Не повторяйте символы!" + similar: "<#04CADF>Не отправляйте одинаковые сообщения!" clearchat: - cleared: "Чат очищен администратором {player}" + cleared: "<#04CADF>Чат очищен администратором {player}" errors: - no-permission: "Нет прав!" - player-not-found: "Игрок не найден" - invalid-usage: "Использование: {usage}" + no-permission: "<#04CADF>Нет прав!" + player-not-found: "<#04CADF>Игрок не найден" + invalid-usage: "<#04CADF>Использование: {usage}" diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index a5d047c..e209661 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -72,6 +72,18 @@ commands: permission: chat.clear aliases: [cc, очиститьчат, сдуфксрфе, сс] + mute: + description: Mute player + usage: /mute