Major mute system overhaul
Commands: - /mute <nick> [time] [-s] [reason] - mute player - /unmute <nick> [-s] - unmute player - /mutelist - list active mutes - /mutehistory <nick> - player mute history - /muteblame <moderator> - mutes issued by moderator Features: - Configurable messages with placeholders (%player%, %operator%, %duration%, %reason%) - Duration permissions: lochat.mute.dur.<time> (10m, 30m, 1h, 6h, 12h, 1d, 3d, 7d, 14d, 30d, perm) - Silent mute: -s flag (requires lochat.mute.silent) - See silent mutes: lochat.mute.see-silent - Default reason configurable (default: Нету.) - Auto-use max allowed duration if not specified - All settings in config.yml under 'mute' section
This commit is contained in:
parent
d92799613e
commit
b74fa21272
9 changed files with 502 additions and 98 deletions
|
|
@ -126,6 +126,10 @@ public final class LoChat extends JavaPlugin {
|
|||
MuteHistoryCommand muteHistoryCommand = new MuteHistoryCommand(this);
|
||||
getCommand("lmutehistory").setExecutor(muteHistoryCommand);
|
||||
getCommand("lmutehistory").setTabCompleter(muteHistoryCommand);
|
||||
|
||||
MuteBlameCommand muteBlameCommand = new MuteBlameCommand(this);
|
||||
getCommand("lmuteblame").setExecutor(muteBlameCommand);
|
||||
getCommand("lmuteblame").setTabCompleter(muteBlameCommand);
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
|
|
|
|||
113
src/main/java/com/loki/lochat/commands/MuteBlameCommand.java
Normal file
113
src/main/java/com/loki/lochat/commands/MuteBlameCommand.java
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
package com.loki.lochat.commands;
|
||||
|
||||
import com.loki.lochat.LoChat;
|
||||
import com.loki.lochat.managers.MuteManager;
|
||||
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.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Команда /muteblame <модератор> - история выдачи мутов модератором
|
||||
*/
|
||||
public class MuteBlameCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
private final LoChat plugin;
|
||||
private final SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm");
|
||||
|
||||
public MuteBlameCommand(LoChat plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command,
|
||||
@NotNull String label, @NotNull String[] args) {
|
||||
if (!sender.hasPermission("lochat.muteblame")) {
|
||||
sender.sendMessage(plugin.getMessageConfig().getComponent("errors.no-permission"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length < 1) {
|
||||
sender.sendMessage("§cИспользование: /muteblame <модератор>");
|
||||
return true;
|
||||
}
|
||||
|
||||
String operatorName = args[0];
|
||||
List<MuteManager.MuteHistoryEntry> mutes = plugin.getMuteManager().getMutesByOperator(operatorName);
|
||||
|
||||
if (mutes.isEmpty()) {
|
||||
sender.sendMessage("§aМодератор §e" + operatorName + " §aне выдавал мутов");
|
||||
return true;
|
||||
}
|
||||
|
||||
sender.sendMessage("§6§l=== Муты выданные " + operatorName + " (" + mutes.size() + ") ===");
|
||||
|
||||
int index = 1;
|
||||
for (MuteManager.MuteHistoryEntry entry : mutes) {
|
||||
// Статус
|
||||
String status;
|
||||
if (entry.unmuted) {
|
||||
status = "§aРазмучен";
|
||||
} else {
|
||||
if (entry.isPermanent()) {
|
||||
status = "§cАктивен (навсегда)";
|
||||
} else {
|
||||
long endTime = entry.mutedAt + entry.duration;
|
||||
if (System.currentTimeMillis() > endTime) {
|
||||
status = "§7Истёк";
|
||||
} else {
|
||||
long remaining = endTime - System.currentTimeMillis();
|
||||
status = "§cАктивен (" + plugin.getMuteManager().formatTime(remaining) + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String durationStr = entry.isPermanent() ? "Навсегда" : plugin.getMuteManager().formatTime(entry.duration);
|
||||
String playerName = entry.playerName != null ? entry.playerName : "???";
|
||||
|
||||
sender.sendMessage("§7" + index + ". §f" + playerName + " §7- " + status);
|
||||
sender.sendMessage(" §7Дата: §f" + dateFormat.format(new Date(entry.mutedAt)));
|
||||
sender.sendMessage(" §7Длительность: §f" + durationStr);
|
||||
sender.sendMessage(" §7Причина: §f" + (entry.reason != null ? entry.reason : "Не указана"));
|
||||
|
||||
if (entry.unmuted && entry.unmutedBy != null) {
|
||||
sender.sendMessage(" §7Размутил: §f" + entry.unmutedBy);
|
||||
}
|
||||
|
||||
index++;
|
||||
|
||||
if (index > 15) {
|
||||
sender.sendMessage("§7... и ещё " + (mutes.size() - 15) + " записей");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
|
||||
@NotNull String alias, @NotNull String[] args) {
|
||||
List<String> completions = new ArrayList<>();
|
||||
|
||||
if (args.length == 1) {
|
||||
String prefix = args[0].toLowerCase();
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (player.getName().toLowerCase().startsWith(prefix)) {
|
||||
completions.add(player.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return completions;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
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;
|
||||
|
|
@ -14,7 +15,8 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Команда /lmute nick time [-s] причина
|
||||
* Команда /mute nick [time] [-s] [причина]
|
||||
* Поддержка -s в любом месте до причины
|
||||
*/
|
||||
public class MuteCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
|
|
@ -32,109 +34,161 @@ public class MuteCommand implements CommandExecutor, TabCompleter {
|
|||
return true;
|
||||
}
|
||||
|
||||
// /lmute nick time [-s] причина
|
||||
if (args.length < 2) {
|
||||
sender.sendMessage("§cИспользование: /lmute <ник> <время> [-s] [причина]");
|
||||
sender.sendMessage("§7Время: 1d, 2h, 30m, 60s или 0 для перманентного");
|
||||
if (args.length < 1) {
|
||||
sender.sendMessage("§cИспользование: /mute <ник> [время] [-s] [причина]");
|
||||
sender.sendMessage("§7Время: 1d, 2h, 30m, 60s или 0/perm для перманентного");
|
||||
sender.sendMessage("§7-s - тихий мут (требует право lochat.mute.silent)");
|
||||
return true;
|
||||
}
|
||||
|
||||
String targetName = args[0];
|
||||
String timeStr = args[1];
|
||||
|
||||
// Парсим время
|
||||
long duration = plugin.getMuteManager().parseTime(timeStr);
|
||||
if (duration < 0) {
|
||||
sender.sendMessage("§cНеверный формат времени! Используйте: 1d, 2h, 30m, 60s");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Проверяем флаг -s (silent) и собираем причину
|
||||
// Парсим аргументы
|
||||
String targetName = null;
|
||||
String timeStr = null;
|
||||
boolean silent = false;
|
||||
StringBuilder reasonBuilder = new StringBuilder();
|
||||
|
||||
for (int i = 2; i < args.length; i++) {
|
||||
if (args[i].equalsIgnoreCase("-s")) {
|
||||
for (String arg : args) {
|
||||
if (arg.equalsIgnoreCase("-s")) {
|
||||
silent = true;
|
||||
} else if (targetName == null) {
|
||||
targetName = arg;
|
||||
} else if (timeStr == null && isTimeFormat(arg)) {
|
||||
timeStr = arg;
|
||||
} else {
|
||||
if (reasonBuilder.length() > 0) reasonBuilder.append(" ");
|
||||
reasonBuilder.append(args[i]);
|
||||
reasonBuilder.append(arg);
|
||||
}
|
||||
}
|
||||
|
||||
String reason = reasonBuilder.length() > 0 ? reasonBuilder.toString() : "Не указана";
|
||||
// Проверка права на тихий мут
|
||||
if (silent && !sender.hasPermission("lochat.mute.silent")) {
|
||||
sender.sendMessage("§cУ вас нет права на тихий мут!");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ищем игрока (онлайн или оффлайн)
|
||||
// Получаем настройки из конфига
|
||||
String defaultReason = plugin.getConfigManager().getString("mute.default-reason", "Нету.");
|
||||
String defaultDuration = plugin.getConfigManager().getString("mute.default-duration", "7d");
|
||||
|
||||
String reason = reasonBuilder.length() > 0 ? reasonBuilder.toString() : defaultReason;
|
||||
|
||||
// Определяем длительность
|
||||
long duration;
|
||||
if (timeStr == null || timeStr.isEmpty()) {
|
||||
// Используем максимальное доступное время из прав
|
||||
if (sender instanceof Player player) {
|
||||
duration = plugin.getMuteManager().getMaxDuration(player);
|
||||
if (duration == -1) {
|
||||
// Нет прав на длительность - используем дефолт
|
||||
duration = plugin.getMuteManager().parseTime(defaultDuration);
|
||||
}
|
||||
} else {
|
||||
duration = 0; // Консоль = перманентный
|
||||
}
|
||||
} else if (timeStr.equalsIgnoreCase("perm") || timeStr.equals("0")) {
|
||||
duration = 0; // Перманентный
|
||||
} else {
|
||||
duration = plugin.getMuteManager().parseTime(timeStr);
|
||||
if (duration < 0) {
|
||||
sender.sendMessage("§cНеверный формат времени! Используйте: 1d, 2h, 30m, 60s, perm");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Проверяем право на длительность
|
||||
if (sender instanceof Player player) {
|
||||
if (!plugin.getMuteManager().canMuteForDuration(player, duration)) {
|
||||
long maxDur = plugin.getMuteManager().getMaxDuration(player);
|
||||
String maxStr = maxDur == 0 ? "перманентный" : plugin.getMuteManager().formatTime(maxDur);
|
||||
sender.sendMessage("§cВы не можете мутить на такой срок! Максимум: " + maxStr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Ищем игрока
|
||||
Player target = Bukkit.getPlayer(targetName);
|
||||
String finalTargetName = targetName;
|
||||
java.util.UUID targetUUID;
|
||||
|
||||
if (target == null) {
|
||||
// Пробуем найти оффлайн игрока
|
||||
@SuppressWarnings("deprecation")
|
||||
var offlinePlayer = Bukkit.getOfflinePlayer(targetName);
|
||||
if (!offlinePlayer.hasPlayedBefore() && !offlinePlayer.isOnline()) {
|
||||
sender.sendMessage(plugin.getMessageConfig().getComponent("errors.player-not-found"));
|
||||
return true;
|
||||
}
|
||||
targetUUID = offlinePlayer.getUniqueId();
|
||||
finalTargetName = offlinePlayer.getName() != null ? offlinePlayer.getName() : targetName;
|
||||
} else {
|
||||
targetUUID = target.getUniqueId();
|
||||
finalTargetName = target.getName();
|
||||
|
||||
// Мутим оффлайн игрока
|
||||
String offlineName = offlinePlayer.getName() != null ? offlinePlayer.getName() : targetName;
|
||||
plugin.getMuteManager().mute(offlinePlayer.getUniqueId(), offlineName, duration, reason, sender.getName());
|
||||
|
||||
String timeDisplay = duration == 0 ? "навсегда" : plugin.getMuteManager().formatTime(duration);
|
||||
sender.sendMessage("§aИгрок §e" + targetName + " §aзамучен на §e" + timeDisplay);
|
||||
sender.sendMessage("§7Причина: §f" + reason);
|
||||
|
||||
if (!silent) {
|
||||
Bukkit.broadcast(plugin.getMessageConfig().getComponent("mute.muted",
|
||||
"{player}", targetName, "{time}", timeDisplay));
|
||||
// Проверка на себя
|
||||
if (sender instanceof Player && ((Player) sender).getUniqueId().equals(targetUUID)) {
|
||||
sender.sendMessage("§cВы не можете замутить себя!");
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Проверяем, не пытается ли замутить себя
|
||||
if (sender instanceof Player && ((Player) sender).getUniqueId().equals(target.getUniqueId())) {
|
||||
sender.sendMessage("§cВы не можете замутить себя!");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Проверяем, не замучен ли уже
|
||||
if (plugin.getMuteManager().isMuted(target.getUniqueId())) {
|
||||
if (plugin.getMuteManager().isMuted(targetUUID)) {
|
||||
sender.sendMessage("§cИгрок уже замучен!");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Мутим игрока
|
||||
plugin.getMuteManager().mute(target.getUniqueId(), target.getName(), duration, reason, sender.getName());
|
||||
String operatorName = sender.getName();
|
||||
plugin.getMuteManager().mute(targetUUID, finalTargetName, duration, reason, operatorName);
|
||||
|
||||
String timeDisplay = duration == 0 ? "навсегда" : plugin.getMuteManager().formatTime(duration);
|
||||
|
||||
// Уведомляем отправителя
|
||||
sender.sendMessage("§aИгрок §e" + target.getName() + " §aзамучен на §e" + timeDisplay);
|
||||
sender.sendMessage("§aИгрок §e" + finalTargetName + " §aзамучен на §e" + timeDisplay);
|
||||
sender.sendMessage("§7Причина: §f" + reason);
|
||||
|
||||
// Уведомляем замученного
|
||||
if (duration == 0) {
|
||||
target.sendMessage(plugin.getMessageConfig().getComponent("mute.permanent"));
|
||||
} else {
|
||||
target.sendMessage(plugin.getMessageConfig().getComponent("mute.you-muted",
|
||||
"{time}", timeDisplay));
|
||||
// Уведомляем замученного (если онлайн)
|
||||
if (target != null) {
|
||||
String msgKey = duration == 0 ? "mute.messages.you-muted-permanent" : "mute.messages.you-muted";
|
||||
String msg = plugin.getConfigManager().getString(msgKey,
|
||||
duration == 0 ? "§cВы замучены навсегда! Причина: %reason%" : "§cВы замучены на %duration%! Причина: %reason%");
|
||||
msg = plugin.getMuteManager().formatMessage(msg, finalTargetName, operatorName, timeDisplay, reason);
|
||||
target.sendMessage(ChatFormatter.parse(msg));
|
||||
}
|
||||
|
||||
// Broadcast если не silent
|
||||
if (!silent) {
|
||||
Bukkit.broadcast(plugin.getMessageConfig().getComponent("mute.muted",
|
||||
"{player}", target.getName(), "{time}", timeDisplay));
|
||||
// Broadcast
|
||||
if (silent) {
|
||||
// Тихий мут - только тем кто видит
|
||||
String silentMsg = plugin.getConfigManager().getString("mute.messages.silent-muted",
|
||||
"§8[Тихо] §c%player% §7замучен на §c%duration% §7(%operator%). Причина: %reason%");
|
||||
silentMsg = plugin.getMuteManager().formatMessage(silentMsg, finalTargetName, operatorName, timeDisplay, reason);
|
||||
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
if (p.hasPermission("lochat.mute.see-silent")) {
|
||||
p.sendMessage(ChatFormatter.parse(silentMsg));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Обычный broadcast
|
||||
String broadcastMsg = plugin.getConfigManager().getString("mute.messages.muted",
|
||||
"§c%player% §7был замучен на §c%duration% §7модератором §c%operator%§7. Причина: §c%reason%");
|
||||
broadcastMsg = plugin.getMuteManager().formatMessage(broadcastMsg, finalTargetName, operatorName, timeDisplay, reason);
|
||||
Bukkit.broadcast(ChatFormatter.parse(broadcastMsg));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isTimeFormat(String str) {
|
||||
if (str.equalsIgnoreCase("perm")) return true;
|
||||
return str.matches("\\d+[dhms]?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
|
||||
@NotNull String alias, @NotNull String[] args) {
|
||||
List<String> completions = new ArrayList<>();
|
||||
|
||||
if (args.length == 1) {
|
||||
// Ники игроков
|
||||
String prefix = args[0].toLowerCase();
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (player.getName().toLowerCase().startsWith(prefix)) {
|
||||
|
|
@ -142,7 +196,6 @@ public class MuteCommand implements CommandExecutor, TabCompleter {
|
|||
}
|
||||
}
|
||||
} else if (args.length == 2) {
|
||||
// Время
|
||||
completions.add("10m");
|
||||
completions.add("30m");
|
||||
completions.add("1h");
|
||||
|
|
@ -151,7 +204,8 @@ public class MuteCommand implements CommandExecutor, TabCompleter {
|
|||
completions.add("1d");
|
||||
completions.add("7d");
|
||||
completions.add("30d");
|
||||
completions.add("0");
|
||||
completions.add("perm");
|
||||
completions.add("-s");
|
||||
} else if (args.length == 3) {
|
||||
completions.add("-s");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
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;
|
||||
|
|
@ -14,7 +15,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Команда /lunmute nick [-s]
|
||||
* Команда /unmute nick [-s]
|
||||
*/
|
||||
public class UnmuteCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
|
|
@ -33,46 +34,74 @@ public class UnmuteCommand implements CommandExecutor, TabCompleter {
|
|||
}
|
||||
|
||||
if (args.length < 1) {
|
||||
sender.sendMessage("§cИспользование: /lunmute <ник> [-s]");
|
||||
sender.sendMessage("§cИспользование: /unmute <ник> [-s]");
|
||||
return true;
|
||||
}
|
||||
|
||||
String targetName = args[0];
|
||||
boolean silent = args.length > 1 && args[1].equalsIgnoreCase("-s");
|
||||
// Парсим аргументы
|
||||
String targetName = null;
|
||||
boolean silent = false;
|
||||
|
||||
for (String arg : args) {
|
||||
if (arg.equalsIgnoreCase("-s")) {
|
||||
silent = true;
|
||||
} else if (targetName == null) {
|
||||
targetName = arg;
|
||||
}
|
||||
}
|
||||
|
||||
// Проверка права на тихий размут
|
||||
if (silent && !sender.hasPermission("lochat.mute.silent")) {
|
||||
sender.sendMessage("§cУ вас нет права на тихий размут!");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ищем игрока
|
||||
Player target = Bukkit.getPlayer(targetName);
|
||||
String finalTargetName = targetName;
|
||||
java.util.UUID targetUUID;
|
||||
|
||||
if (target == null) {
|
||||
// Пробуем найти оффлайн игрока
|
||||
@SuppressWarnings("deprecation")
|
||||
var offlinePlayer = Bukkit.getOfflinePlayer(targetName);
|
||||
if (!offlinePlayer.hasPlayedBefore() && !offlinePlayer.isOnline()) {
|
||||
sender.sendMessage(plugin.getMessageConfig().getComponent("errors.player-not-found"));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Размучиваем оффлайн игрока
|
||||
if (plugin.getMuteManager().unmute(offlinePlayer.getUniqueId(), sender.getName())) {
|
||||
sender.sendMessage("§aИгрок §e" + targetName + " §aразмучен");
|
||||
|
||||
if (!silent) {
|
||||
Bukkit.broadcast(plugin.getMessageConfig().getComponent("mute.unmuted",
|
||||
"{player}", targetName));
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("§cИгрок не замучен!");
|
||||
}
|
||||
return true;
|
||||
targetUUID = offlinePlayer.getUniqueId();
|
||||
finalTargetName = offlinePlayer.getName() != null ? offlinePlayer.getName() : targetName;
|
||||
} else {
|
||||
targetUUID = target.getUniqueId();
|
||||
finalTargetName = target.getName();
|
||||
}
|
||||
|
||||
// Размучиваем онлайн игрока
|
||||
if (plugin.getMuteManager().unmute(target.getUniqueId(), sender.getName())) {
|
||||
sender.sendMessage("§aИгрок §e" + target.getName() + " §aразмучен");
|
||||
target.sendMessage("§aВы были размучены!");
|
||||
String operatorName = sender.getName();
|
||||
|
||||
if (!silent) {
|
||||
Bukkit.broadcast(plugin.getMessageConfig().getComponent("mute.unmuted",
|
||||
"{player}", target.getName()));
|
||||
// Размучиваем
|
||||
if (plugin.getMuteManager().unmute(targetUUID, operatorName)) {
|
||||
sender.sendMessage("§aИгрок §e" + finalTargetName + " §aразмучен");
|
||||
|
||||
// Уведомляем игрока (если онлайн)
|
||||
if (target != null) {
|
||||
target.sendMessage("§aВы были размучены!");
|
||||
}
|
||||
|
||||
// Broadcast
|
||||
if (silent) {
|
||||
String silentMsg = plugin.getConfigManager().getString("mute.messages.silent-unmuted",
|
||||
"§8[Тихо] §a%player% §7размучен (%operator%)");
|
||||
silentMsg = plugin.getMuteManager().formatMessage(silentMsg, finalTargetName, operatorName, null, null);
|
||||
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
if (p.hasPermission("lochat.mute.see-silent")) {
|
||||
p.sendMessage(ChatFormatter.parse(silentMsg));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String broadcastMsg = plugin.getConfigManager().getString("mute.messages.unmuted",
|
||||
"§a%player% §7был размучен модератором §a%operator%");
|
||||
broadcastMsg = plugin.getMuteManager().formatMessage(broadcastMsg, finalTargetName, operatorName, null, null);
|
||||
Bukkit.broadcast(ChatFormatter.parse(broadcastMsg));
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("§cИгрок не замучен!");
|
||||
|
|
|
|||
|
|
@ -92,6 +92,41 @@ public class ConfigManager {
|
|||
this.config = plugin.getConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить строку из конфига с дефолтным значением
|
||||
*/
|
||||
public String getString(String path, String defaultValue) {
|
||||
return config.getString(path, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить строку из конфига
|
||||
*/
|
||||
public String getString(String path) {
|
||||
return config.getString(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить int из конфига
|
||||
*/
|
||||
public int getInt(String path, int defaultValue) {
|
||||
return config.getInt(path, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить boolean из конфига
|
||||
*/
|
||||
public boolean getBoolean(String path, boolean defaultValue) {
|
||||
return config.getBoolean(path, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить список строк из конфига
|
||||
*/
|
||||
public List<String> getStringList(String path) {
|
||||
return config.getStringList(path);
|
||||
}
|
||||
|
||||
// Global chat
|
||||
public boolean isGlobalEnabled() {
|
||||
return config.getBoolean("chat.global.enabled", true);
|
||||
|
|
|
|||
|
|
@ -41,14 +41,18 @@ public class ChatListener implements Listener {
|
|||
if (plugin.getMuteManager().isMuted(player.getUniqueId())) {
|
||||
var muteData = plugin.getMuteManager().getMuteData(player.getUniqueId());
|
||||
if (muteData != null) {
|
||||
String msg;
|
||||
if (muteData.isPermanent()) {
|
||||
player.sendMessage(plugin.getMessageConfig().getComponent("mute.permanent"));
|
||||
msg = plugin.getConfigManager().getString("mute.messages.cannot-chat-permanent",
|
||||
"§cВы замучены навсегда!");
|
||||
} else {
|
||||
long remaining = plugin.getMuteManager().getRemainingTime(player.getUniqueId());
|
||||
String timeStr = plugin.getMuteManager().formatTime(remaining);
|
||||
player.sendMessage(plugin.getMessageConfig().getComponent("mute.you-muted",
|
||||
"{time}", timeStr));
|
||||
msg = plugin.getConfigManager().getString("mute.messages.cannot-chat",
|
||||
"§cВы замучены! Осталось: %duration%");
|
||||
msg = msg.replace("%duration%", timeStr);
|
||||
}
|
||||
player.sendMessage(com.loki.lochat.utils.ChatFormatter.parse(msg));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -315,6 +315,74 @@ public class MuteManager {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить историю мутов выданных модератором
|
||||
*/
|
||||
public List<MuteHistoryEntry> getMutesByOperator(String operatorName) {
|
||||
List<MuteHistoryEntry> result = new ArrayList<>();
|
||||
for (List<MuteHistoryEntry> playerHistory : history.values()) {
|
||||
for (MuteHistoryEntry entry : playerHistory) {
|
||||
if (entry.mutedBy != null && entry.mutedBy.equalsIgnoreCase(operatorName)) {
|
||||
result.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Сортируем по дате (новые первые)
|
||||
result.sort((a, b) -> Long.compare(b.mutedAt, a.mutedAt));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить максимальную доступную длительность для игрока
|
||||
* @param player игрок (модератор)
|
||||
* @return длительность в миллисекундах, 0 = перманентный, -1 = нет прав
|
||||
*/
|
||||
public long getMaxDuration(org.bukkit.entity.Player player) {
|
||||
if (player.hasPermission("lochat.mute.dur.perm")) {
|
||||
return 0; // Перманентный
|
||||
}
|
||||
|
||||
// Проверяем права от большего к меньшему
|
||||
String[] durations = {"30d", "14d", "7d", "3d", "1d", "12h", "6h", "1h", "30m", "10m"};
|
||||
for (String dur : durations) {
|
||||
if (player.hasPermission("lochat.mute.dur." + dur)) {
|
||||
return parseTime(dur);
|
||||
}
|
||||
}
|
||||
|
||||
return -1; // Нет прав
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверить, может ли игрок выдать мут на указанную длительность
|
||||
*/
|
||||
public boolean canMuteForDuration(org.bukkit.entity.Player player, long duration) {
|
||||
if (player.hasPermission("lochat.mute.dur.perm")) {
|
||||
return true; // Может всё
|
||||
}
|
||||
|
||||
if (duration == 0) {
|
||||
return false; // Перманентный мут требует lochat.mute.dur.perm
|
||||
}
|
||||
|
||||
long maxDuration = getMaxDuration(player);
|
||||
if (maxDuration == -1) return false;
|
||||
if (maxDuration == 0) return true; // Перманентный = может всё
|
||||
|
||||
return duration <= maxDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Форматировать сообщение с плейсхолдерами
|
||||
*/
|
||||
public String formatMessage(String message, String player, String operator, String duration, String reason) {
|
||||
return message
|
||||
.replace("%player%", player != null ? player : "")
|
||||
.replace("%operator%", operator != null ? operator : "")
|
||||
.replace("%duration%", duration != null ? duration : "")
|
||||
.replace("%reason%", reason != null ? reason : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Данные о муте
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -175,3 +175,53 @@ announcements:
|
|||
show-actionbar: true
|
||||
# Время показа title (в секундах)
|
||||
title-duration: 3
|
||||
|
||||
# ========================================
|
||||
# Система мутов
|
||||
# ========================================
|
||||
mute:
|
||||
# Сообщения с плейсхолдерами:
|
||||
# %duration% - время мута
|
||||
# %reason% - причина
|
||||
# %player% - замученный игрок
|
||||
# %operator% - модератор (чистый ник без префикса и цвета)
|
||||
|
||||
messages:
|
||||
# Сообщение при муте (broadcast)
|
||||
muted: "&#FF6B6B%player% 󅒐был замучен на &#FF6B6B%duration% 󅒐модератором &#FF6B6B%operator%󅒐. Причина: &#FF6B6B%reason%"
|
||||
# Сообщение при размуте (broadcast)
|
||||
unmuted: "BCB77%player% 󅒐был размучен модератором BCB77%operator%"
|
||||
# Сообщение замученному игроку
|
||||
you-muted: "&#FF6B6BВы замучены на %duration%! Причина: %reason%"
|
||||
# Сообщение при перманентном муте
|
||||
you-muted-permanent: "&#FF6B6BВы замучены навсегда! Причина: %reason%"
|
||||
# Сообщение при попытке написать в чат
|
||||
cannot-chat: "&#FF6B6BВы замучены! Осталось: %duration%"
|
||||
cannot-chat-permanent: "&#FF6B6BВы замучены навсегда!"
|
||||
# Тихий мут (только для тех кто видит)
|
||||
silent-muted: "󅒐[Тихо] &#FF6B6B%player% 󅒐замучен на &#FF6B6B%duration% 󅒐(%operator%). Причина: %reason%"
|
||||
silent-unmuted: "󅒐[Тихо] BCB77%player% 󅒐размучен (%operator%)"
|
||||
|
||||
# Причина по умолчанию если не указана
|
||||
default-reason: "Нету."
|
||||
|
||||
# Максимальное время мута по умолчанию (если не указано время)
|
||||
# Используется наивысшее доступное время из прав игрока
|
||||
# Формат: 1d, 7d, 30d, perm (перманентный)
|
||||
default-duration: "7d"
|
||||
|
||||
# Доступные длительности для прав lochat.mute.dur.<время>
|
||||
# Игрок с правом lochat.mute.dur.7d может мутить максимум на 7 дней
|
||||
# lochat.mute.dur.perm - может мутить навсегда
|
||||
durations:
|
||||
- "10m"
|
||||
- "30m"
|
||||
- "1h"
|
||||
- "6h"
|
||||
- "12h"
|
||||
- "1d"
|
||||
- "3d"
|
||||
- "7d"
|
||||
- "14d"
|
||||
- "30d"
|
||||
- "perm"
|
||||
|
|
|
|||
|
|
@ -99,27 +99,33 @@ commands:
|
|||
|
||||
lmute:
|
||||
description: Mute a player
|
||||
usage: /lmute <player> <time> [-s] [reason]
|
||||
usage: /lmute <player> [time] [-s] [reason]
|
||||
permission: lochat.mute
|
||||
aliases: [дьгеу]
|
||||
aliases: [mute, мут, ьгеу]
|
||||
|
||||
lunmute:
|
||||
description: Unmute a player
|
||||
usage: /lunmute <player> [-s]
|
||||
permission: lochat.unmute
|
||||
aliases: [дгтьгеу]
|
||||
aliases: [unmute, размут, гтьгеу]
|
||||
|
||||
lmutelist:
|
||||
description: List all active mutes
|
||||
usage: /lmutelist
|
||||
permission: lochat.mutelist
|
||||
aliases: [дьгеудшые]
|
||||
aliases: [mutelist, мутлист, ьгеудшые]
|
||||
|
||||
lmutehistory:
|
||||
description: View mute history of a player
|
||||
usage: /lmutehistory <player>
|
||||
permission: lochat.mutehistory
|
||||
aliases: [дьгеершыещку]
|
||||
aliases: [mutehistory, мутистория, ьгеершыещку]
|
||||
|
||||
lmuteblame:
|
||||
description: View mutes issued by a moderator
|
||||
usage: /lmuteblame <moderator>
|
||||
permission: lochat.muteblame
|
||||
aliases: [muteblame, мутблейм, ьгеуидфьу]
|
||||
|
||||
permissions:
|
||||
chat.global.use:
|
||||
|
|
@ -172,3 +178,44 @@ permissions:
|
|||
default: op
|
||||
lochat.mutehistory:
|
||||
default: op
|
||||
lochat.muteblame:
|
||||
default: op
|
||||
lochat.mute.silent:
|
||||
description: Can use silent mute (-s flag)
|
||||
default: op
|
||||
lochat.mute.see-silent:
|
||||
description: Can see silent mute notifications
|
||||
default: op
|
||||
lochat.mute.dur.10m:
|
||||
description: Can mute for 10 minutes
|
||||
default: false
|
||||
lochat.mute.dur.30m:
|
||||
description: Can mute for 30 minutes
|
||||
default: false
|
||||
lochat.mute.dur.1h:
|
||||
description: Can mute for 1 hour
|
||||
default: false
|
||||
lochat.mute.dur.6h:
|
||||
description: Can mute for 6 hours
|
||||
default: false
|
||||
lochat.mute.dur.12h:
|
||||
description: Can mute for 12 hours
|
||||
default: false
|
||||
lochat.mute.dur.1d:
|
||||
description: Can mute for 1 day
|
||||
default: false
|
||||
lochat.mute.dur.3d:
|
||||
description: Can mute for 3 days
|
||||
default: false
|
||||
lochat.mute.dur.7d:
|
||||
description: Can mute for 7 days
|
||||
default: op
|
||||
lochat.mute.dur.14d:
|
||||
description: Can mute for 14 days
|
||||
default: false
|
||||
lochat.mute.dur.30d:
|
||||
description: Can mute for 30 days
|
||||
default: false
|
||||
lochat.mute.dur.perm:
|
||||
description: Can mute permanently
|
||||
default: op
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue