feat: add mute/unmute commands with MuteManager
This commit is contained in:
parent
55c965603f
commit
c4d2768423
27 changed files with 559 additions and 2352 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
122
src/main/java/com/loki/lochat/commands/MuteCommand.java
Normal file
122
src/main/java/com/loki/lochat/commands/MuteCommand.java
Normal file
|
|
@ -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("<gray>Время: 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("<red>Неверный формат времени! Используйте: 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<String> 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<String> 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<>();
|
||||
}
|
||||
}
|
||||
76
src/main/java/com/loki/lochat/commands/UnmuteCommand.java
Normal file
76
src/main/java/com/loki/lochat/commands/UnmuteCommand.java
Normal file
|
|
@ -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("<green>Вы были размучены!"));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<String> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
147
src/main/java/com/loki/lochat/managers/MuteManager.java
Normal file
147
src/main/java/com/loki/lochat/managers/MuteManager.java
Normal file
|
|
@ -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<UUID, MuteData> 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<UUID, MuteData> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -40,19 +40,106 @@ mentions:
|
|||
sound: true
|
||||
sound-type: "BLOCK_NOTE_BLOCK_PLING"
|
||||
# Выделение при @ник
|
||||
highlight: "<yellow>@{player}</yellow>"
|
||||
highlight: "<#04CADF>@{player}</#04CADF>"
|
||||
# Выделение когда твой ник написали (без @)
|
||||
self-highlight: "<gold><bold>{player}</bold></gold>"
|
||||
self-highlight: "<#04CADF>{player}</#04CADF>"
|
||||
|
||||
# Фильтр мата
|
||||
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: "<gold>[ОБЪЯВЛЕНИЕ]</gold> <message>"
|
||||
announcement: "<#04CADF>[ОБЪЯВЛЕНИЕ]</#04CADF> <message>"
|
||||
|
||||
# Настройки объявлений
|
||||
announcements:
|
||||
# Показывать title при объявлении
|
||||
show-title: true
|
||||
# Заголовок title
|
||||
title-header: "<gold>ОБЪЯВЛЕНИЕ</gold>"
|
||||
title-header: "<#04CADF>ОБЪЯВЛЕНИЕ</#04CADF>"
|
||||
# Показывать actionbar при объявлении
|
||||
show-actionbar: true
|
||||
# Время показа title (в секундах)
|
||||
|
|
|
|||
|
|
@ -2,56 +2,56 @@
|
|||
# Сообщения модуля градиентных ников
|
||||
|
||||
# Общие
|
||||
only-player: "§cЭта команда только для игроков!"
|
||||
no-permission: "§cУ вас нет прав на это действие!"
|
||||
player-not-found: "§cИгрок не найден!"
|
||||
reload-success: "§aКонфигурация градиентов перезагружена!"
|
||||
cooldown: "§cПодождите ещё {time} секунд!"
|
||||
only-player: "<#04CADF>Эта команда только для игроков!</#04CADF>"
|
||||
no-permission: "<#04CADF>У вас нет прав на это действие!</#04CADF>"
|
||||
player-not-found: "<#04CADF>Игрок не найден!</#04CADF>"
|
||||
reload-success: "<#04CADF>Конфигурация градиентов перезагружена!</#04CADF>"
|
||||
cooldown: "<#04CADF>Подождите ещё {time} секунд!</#04CADF>"
|
||||
|
||||
# Цвета
|
||||
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>
|
||||
<#04CADF>/color <цвет1> [цвет2] ... <gray>— установить градиент</gray>
|
||||
<#04CADF>/color on <gray>— включить цвет</gray>
|
||||
<#04CADF>/color off <gray>— выключить цвет</gray>
|
||||
<#04CADF>/color reset <gray>— сбросить цвет</gray>
|
||||
<#04CADF>/color copy <игрок> <gray>— скопировать цвет</gray>
|
||||
<gray>Пример: /color #FF0000 #00FF00 #0000FF</gray>
|
||||
color-enabled: "<#04CADF>Цвет ника включён!</#04CADF>"
|
||||
color-disabled: "<#04CADF>Цвет ника выключен!</#04CADF>"
|
||||
color-reset: "<#04CADF>Цвет ника сброшен!</#04CADF>"
|
||||
color-no-colors: "<#04CADF>У вас нет установленных цветов!</#04CADF>"
|
||||
color-success: "<#04CADF>Цвет успешно установлен! Списано: {price} PP</#04CADF>"
|
||||
color-copy-usage: "<#04CADF>Использование: /color copy <игрок></#04CADF>"
|
||||
color-copy-no-colors: "<#04CADF>У игрока {player} нет цветов!</#04CADF>"
|
||||
invalid-color: "<#04CADF>Неверный формат цвета: {color}. Используйте #RRGGBB</#04CADF>"
|
||||
too-many-colors: "<#04CADF>Максимум {max} цветов!</#04CADF>"
|
||||
not-enough-colors: "<#04CADF>Минимум {min} цветов!</#04CADF>"
|
||||
not-enough-points-color: "<#04CADF>Недостаточно поинтов! Нужно: {price} PP</#04CADF>"
|
||||
|
||||
# Префикс
|
||||
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>
|
||||
<#04CADF>/prefix <текст> <gray>— установить префикс</gray>
|
||||
<#04CADF>/prefix on <gray>— включить префикс</gray>
|
||||
<#04CADF>/prefix off <gray>— выключить префикс</gray>
|
||||
<#04CADF>/prefix reset <gray>— сбросить префикс</gray>
|
||||
prefix-enabled: "<#04CADF>Префикс включён!</#04CADF>"
|
||||
prefix-disabled: "<#04CADF>Префикс выключен!</#04CADF>"
|
||||
prefix-reset-success: "<#04CADF>Префикс сброшен!</#04CADF>"
|
||||
prefix-no-prefix: "<#04CADF>У вас нет установленного префикса!</#04CADF>"
|
||||
prefix-success: "<#04CADF>Префикс успешно установлен! Списано: {price} PP</#04CADF>"
|
||||
prefix-success-free: "<#04CADF>Префикс успешно изменён!</#04CADF>"
|
||||
prefix-no-colors: "<#04CADF>Префикс не может содержать цветовые коды!</#04CADF>"
|
||||
prefix-invalid-chars: "<#04CADF>Префикс содержит недопустимые символы!</#04CADF>"
|
||||
prefix-blacklisted: "<#04CADF>Этот префикс запрещён!</#04CADF>"
|
||||
prefix-too-long: "<#04CADF>Префикс слишком длинный! Максимум: {max} символов</#04CADF>"
|
||||
not-enough-points-prefix: "<#04CADF>Недостаточно поинтов! Нужно: {price} PP</#04CADF>"
|
||||
|
||||
# Админ информация
|
||||
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} ===</#04CADF>"
|
||||
info-prefix: "<gray>Префикс: <white>{prefix}</white></gray>"
|
||||
info-prefix-enabled: "<gray>Префикс включён: <white>{enabled}</white></gray>"
|
||||
info-colors: "<gray>Цвета: <white>{colors}</white></gray>"
|
||||
info-color-enabled: "<gray>Цвет включён: <white>{enabled}</white></gray>"
|
||||
info-prefix-purchased: "<gray>Префикс куплен: <white>{purchased}</white></gray>"
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
prefix: "<gold>[LoChat]</gold>"
|
||||
prefix: "<#04CADF>[LoChat]</#04CADF>"
|
||||
|
||||
global:
|
||||
disabled: "<red>Глобальный чат отключен</red>"
|
||||
toggled-on: "<green>Глобальный чат включен</green>"
|
||||
toggled-off: "<red>Глобальный чат отключен</red>"
|
||||
disabled: "<#04CADF>Глобальный чат отключен</#04CADF>"
|
||||
toggled-on: "<#04CADF>Глобальный чат включен</#04CADF>"
|
||||
toggled-off: "<#04CADF>Глобальный чат отключен</#04CADF>"
|
||||
|
||||
local:
|
||||
no-players: "<red>Рядом нет игроков</red>"
|
||||
no-players: "<#04CADF>Рядом нет игроков</#04CADF>"
|
||||
|
||||
pm:
|
||||
# Форматы личных сообщений
|
||||
|
|
@ -20,42 +20,42 @@ pm:
|
|||
# Старые форматы (для совместимости)
|
||||
sent: "<gray>[PM] Ты → {player}: {message}</gray>"
|
||||
received: "<gray>[PM] {player} → Ты: {message}</gray>"
|
||||
no-reply: "<red>Некому ответить</red>"
|
||||
ignored: "<red>Этот игрок вас игнорирует</red>"
|
||||
player-offline: "<red>Игрок не в сети</red>"
|
||||
self: "<red>Нельзя писать самому себе</red>"
|
||||
no-reply: "<#04CADF>Некому ответить</#04CADF>"
|
||||
ignored: "<#04CADF>Этот игрок вас игнорирует</#04CADF>"
|
||||
player-offline: "<#04CADF>Игрок не в сети</#04CADF>"
|
||||
self: "<#04CADF>Нельзя писать самому себе</#04CADF>"
|
||||
|
||||
ignore:
|
||||
added: "<green>Игрок {player} добавлен в игнор</green>"
|
||||
removed: "<green>Игрок {player} убран из игнора</green>"
|
||||
already-ignored: "<red>Игрок уже в игноре</red>"
|
||||
not-ignored: "<red>Игрок не в игноре</red>"
|
||||
self: "<red>Нельзя игнорировать себя</red>"
|
||||
added: "<#04CADF>Игрок {player} добавлен в игнор</#04CADF>"
|
||||
removed: "<#04CADF>Игрок {player} убран из игнора</#04CADF>"
|
||||
already-ignored: "<#04CADF>Игрок уже в игноре</#04CADF>"
|
||||
not-ignored: "<#04CADF>Игрок не в игноре</#04CADF>"
|
||||
self: "<#04CADF>Нельзя игнорировать себя</#04CADF>"
|
||||
|
||||
announce:
|
||||
reloaded: "<green>Конфигурация перезагружена</green>"
|
||||
reloaded: "<#04CADF>Конфигурация перезагружена</#04CADF>"
|
||||
|
||||
spy:
|
||||
enabled: "<green>Шпион режим включен</green>"
|
||||
disabled: "<red>Шпион режим выключен</red>"
|
||||
enabled: "<#04CADF>Шпион режим включен</#04CADF>"
|
||||
disabled: "<#04CADF>Шпион режим выключен</#04CADF>"
|
||||
format: "<gray>[SPY] {sender} → {receiver}: {message}</gray>"
|
||||
|
||||
filter:
|
||||
blocked: "<red>Сообщение заблокировано (мат)</red>"
|
||||
warned: "<yellow>Предупреждение: не используйте мат!</yellow>"
|
||||
blocked: "<#04CADF>Сообщение заблокировано (мат)</#04CADF>"
|
||||
warned: "<#04CADF>Предупреждение: не используйте мат!</#04CADF>"
|
||||
|
||||
cooldown:
|
||||
wait: "<red>Подождите {time} сек перед следующим сообщением</red>"
|
||||
wait: "<#04CADF>Подождите {time} сек перед следующим сообщением</#04CADF>"
|
||||
|
||||
antispam:
|
||||
caps: "<red>Слишком много заглавных букв!</red>"
|
||||
repeat: "<red>Не повторяйте символы!</red>"
|
||||
similar: "<red>Не отправляйте одинаковые сообщения!</red>"
|
||||
caps: "<#04CADF>Слишком много заглавных букв!</#04CADF>"
|
||||
repeat: "<#04CADF>Не повторяйте символы!</#04CADF>"
|
||||
similar: "<#04CADF>Не отправляйте одинаковые сообщения!</#04CADF>"
|
||||
|
||||
clearchat:
|
||||
cleared: "<green>Чат очищен администратором {player}</green>"
|
||||
cleared: "<#04CADF>Чат очищен администратором {player}</#04CADF>"
|
||||
|
||||
errors:
|
||||
no-permission: "<red>Нет прав!</red>"
|
||||
player-not-found: "<red>Игрок не найден</red>"
|
||||
invalid-usage: "<red>Использование: {usage}</red>"
|
||||
no-permission: "<#04CADF>Нет прав!</#04CADF>"
|
||||
player-not-found: "<#04CADF>Игрок не найден</#04CADF>"
|
||||
invalid-usage: "<#04CADF>Использование: {usage}</#04CADF>"
|
||||
|
|
|
|||
|
|
@ -72,6 +72,18 @@ commands:
|
|||
permission: chat.clear
|
||||
aliases: [cc, очиститьчат, сдуфксрфе, сс]
|
||||
|
||||
mute:
|
||||
description: Mute player
|
||||
usage: /mute <player> <time> [reason]
|
||||
permission: chat.mute
|
||||
aliases: [мут, ьгеу]
|
||||
|
||||
unmute:
|
||||
description: Unmute player
|
||||
usage: /unmute <player>
|
||||
permission: chat.mute
|
||||
aliases: [размут, гтьгеу]
|
||||
|
||||
chatcolor:
|
||||
description: Set chat color
|
||||
usage: /chatcolor <color>
|
||||
|
|
@ -125,6 +137,8 @@ permissions:
|
|||
default: op
|
||||
chat.clear:
|
||||
default: op
|
||||
chat.mute:
|
||||
default: op
|
||||
chat.bypass.cooldown:
|
||||
default: op
|
||||
chat.bypass.filter:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue