| 复制代码package com.example.muteplugin;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.configuration.file.FileConfiguration;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
 * @pluginName MuteManager
 * [url=home.php?mod=space&uid=85395]@Author[/url] Scriptirc
 * @version 1.0
 * @description 支持禁言、解禁、查看禁言列表,自动解禁并提醒,数据持久化,权限分明,指令补全
 * [command]mute|禁言玩家[/command]
 * [command]unmute|解禁玩家[/command]
 * [command]mutelist|查看禁言列表[/command]
 * [Permission]mute.admin|管理员禁言、解禁、查看所有禁言记录[/Permission]
 * [Permission]mute.self|玩家查看自己的禁言记录[/Permission]
 */
public class MuteManager extends JavaPlugin implements TabCompleter {
    // 存储禁言数据的Map,key为玩家UUID,value为禁言信息
    private Map<UUID, MuteInfo> muteMap = new HashMap<>();
    private File muteFile;
    private FileConfiguration muteConfig;
    @Override
    public void onEnable() {
        // 初始化配置文件
        loadMuteData();
        // 注册命令和补全
        getCommand("mute").setTabCompleter(this);
        getCommand("unmute").setTabCompleter(this);
        getCommand("mutelist").setTabCompleter(this);
        // 启动自动解禁检测任务
        startAutoUnmuteTask();
        getLogger().info("MuteManager 插件已启用");
    }
    @Override
    public void onDisable() {
        saveMuteData();
        getLogger().info("MuteManager 插件已禁用");
    }
    // 指令处理
    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (command.getName().equalsIgnoreCase("mute")) {
            return handleMute(sender, args);
        } else if (command.getName().equalsIgnoreCase("unmute")) {
            return handleUnmute(sender, args);
        } else if (command.getName().equalsIgnoreCase("mutelist")) {
            return handleMuteList(sender, args);
        }
        return false;
    }
    // 禁言命令实现
    private boolean handleMute(CommandSender sender, String[] args) {
        if (!sender.hasPermission("mute.admin")) {
            sender.sendMessage(ChatColor.RED + "你没有权限使用此命令。");
            return true;
        }
        if (args.length < 2) {
            sender.sendMessage(ChatColor.YELLOW + "/mute <玩家> <时长> <原因>");
            return true;
        }
        Player target = Bukkit.getPlayer(args[0]);
        if (target == null) {
            sender.sendMessage(ChatColor.RED + "玩家不存在或不在线。");
            return true;
        }
        long duration = parseDuration(args[1]);
        if (duration <= 0) {
            sender.sendMessage(ChatColor.RED + "时长格式错误,示例: 10m 1h 1d");
            return true;
        }
        String reason = args.length >= 3 ? String.join(" ", Arrays.copyOfRange(args, 2, args.length)) : "无";
        UUID uuid = target.getUniqueId();
        long endTime = System.currentTimeMillis() + duration;
        MuteInfo info = new MuteInfo(target.getName(), endTime, reason, sender.getName());
        muteMap.put(uuid, info);
        saveMuteData();
        sender.sendMessage(ChatColor.GREEN + "已禁言 " + target.getName() + ",时长: " + args[1] + ",原因: " + reason);
        target.sendMessage(ChatColor.RED + "你已被禁言,时长: " + args[1] + ",原因: " + reason);
        return true;
    }
    // 解禁命令实现
    private boolean handleUnmute(CommandSender sender, String[] args) {
        if (!sender.hasPermission("mute.admin")) {
            sender.sendMessage(ChatColor.RED + "你没有权限使用此命令。");
            return true;
        }
        if (args.length < 1) {
            sender.sendMessage(ChatColor.YELLOW + "/unmute <玩家>");
            return true;
        }
        OfflinePlayer target = Bukkit.getOfflinePlayer(args[0]);
        if (target == null || target.getName() == null) {
            sender.sendMessage(ChatColor.RED + "玩家不存在。");
            return true;
        }
        UUID uuid = target.getUniqueId();
        if (muteMap.containsKey(uuid)) {
            muteMap.remove(uuid);
            saveMuteData();
            sender.sendMessage(ChatColor.GREEN + "已解除 " + target.getName() + " 的禁言。");
            Player online = Bukkit.getPlayer(uuid);
            if (online != null) {
                online.sendMessage(ChatColor.GREEN + "你的禁言已被解除。");
            }
        } else {
            sender.sendMessage(ChatColor.YELLOW + "该玩家未被禁言。");
        }
        return true;
    }
    // 查看禁言列表命令实现
    private boolean handleMuteList(CommandSender sender, String[] args) {
        if (sender.hasPermission("mute.admin")) {
            // 管理员可查所有人或指定玩家
            if (args.length == 0) {
                sender.sendMessage(ChatColor.AQUA + "当前禁言列表:");
                for (MuteInfo info : muteMap.values()) {
                    sender.sendMessage(ChatColor.YELLOW + info.playerName + " | 剩余: " + formatRemain(info.endTime) + " | 原因: " + info.reason);
                }
            } else {
                OfflinePlayer target = Bukkit.getOfflinePlayer(args[0]);
                if (target == null || target.getName() == null) {
                    sender.sendMessage(ChatColor.RED + "玩家不存在。");
                    return true;
                }
                UUID uuid = target.getUniqueId();
                if (muteMap.containsKey(uuid)) {
                    MuteInfo info = muteMap.get(uuid);
                    sender.sendMessage(ChatColor.YELLOW + info.playerName + " | 剩余: " + formatRemain(info.endTime) + " | 原因: " + info.reason);
                } else {
                    sender.sendMessage(ChatColor.YELLOW + "该玩家未被禁言。");
                }
            }
        } else if (sender instanceof Player && sender.hasPermission("mute.self")) {
            Player player = (Player) sender;
            UUID uuid = player.getUniqueId();
            if (muteMap.containsKey(uuid)) {
                MuteInfo info = muteMap.get(uuid);
                sender.sendMessage(ChatColor.YELLOW + "你当前被禁言 | 剩余: " + formatRemain(info.endTime) + " | 原因: " + info.reason);
            } else {
                sender.sendMessage(ChatColor.GREEN + "你当前未被禁言。");
            }
        } else {
            sender.sendMessage(ChatColor.RED + "你没有权限查看禁言记录。");
        }
        return true;
    }
    // Tab补全实现
    @Override
    public List<String> onTabComplete(CommandSender sender, Command cmd, String label, String[] args) {
        if (cmd.getName().equalsIgnoreCase("mute")) {
            if (args.length == 1) {
                List<String> names = new ArrayList<>();
                for (Player p : Bukkit.getOnlinePlayers()) {
                    names.add(p.getName());
                }
                return names;
            } else if (args.length == 2) {
                return Arrays.asList("10m", "1h", "1d");
            }
        } else if (cmd.getName().equalsIgnoreCase("unmute")) {
            if (args.length == 1) {
                List<String> names = new ArrayList<>();
                for (UUID uuid : muteMap.keySet()) {
                    names.add(muteMap.get(uuid).playerName);
                }
                return names;
            }
        } else if (cmd.getName().equalsIgnoreCase("mutelist")) {
            if (args.length == 1 && sender.hasPermission("mute.admin")) {
                List<String> names = new ArrayList<>();
                for (MuteInfo info : muteMap.values()) {
                    names.add(info.playerName);
                }
                return names;
            }
        }
        return null;
    }
    // 聊天事件监听(禁止被禁言者发言)
    @org.bukkit.event.EventHandler
    public void onPlayerChat(org.bukkit.event.player.AsyncPlayerChatEvent event) {
        Player player = event.getPlayer();
        UUID uuid = player.getUniqueId();
        if (muteMap.containsKey(uuid)) {
            MuteInfo info = muteMap.get(uuid);
            if (System.currentTimeMillis() < info.endTime) {
                player.sendMessage(ChatColor.RED + "你已被禁言,剩余: " + formatRemain(info.endTime) + ",原因: " + info.reason);
                event.setCancelled(true);
            } else {
                // 到期自动解禁
                muteMap.remove(uuid);
                saveMuteData();
                player.sendMessage(ChatColor.GREEN + "你的禁言已自动解除。");
            }
        }
    }
    // 自动解禁定时任务
    private void startAutoUnmuteTask() {
        new BukkitRunnable() {
            @Override
            public void run() {
                long now = System.currentTimeMillis();
                Iterator<Map.Entry<UUID, MuteInfo>> it = muteMap.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry<UUID, MuteInfo> entry = it.next();
                    if (now >= entry.getValue().endTime) {
                        Player p = Bukkit.getPlayer(entry.getKey());
                        if (p != null && p.isOnline()) {
                            p.sendMessage(ChatColor.GREEN + "你的禁言已自动解除。");
                        }
                        it.remove();
                    }
                }
                saveMuteData();
            }
        }.runTaskTimer(this, 20L, 120L); // 每6秒检测一次
    }
    // 持久化禁言数据到配置文件
    private void saveMuteData() {
        if (muteConfig == null || muteFile == null) return;
        muteConfig.set("mutes", null);
        for (Map.Entry<UUID, MuteInfo> entry : muteMap.entrySet()) {
            String path = "mutes." + entry.getKey().toString();
            MuteInfo info = entry.getValue();
            muteConfig.set(path + ".name", info.playerName);
            muteConfig.set(path + ".endTime", info.endTime);
            muteConfig.set(path + ".reason", info.reason);
            muteConfig.set(path + ".by", info.by);
        }
        try {
            muteConfig.save(muteFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 加载禁言数据
    private void loadMuteData() {
        muteFile = new File(getDataFolder(), "mutes.yml");
        if (!muteFile.exists()) {
            muteFile.getParentFile().mkdirs();
            try { muteFile.createNewFile(); } catch (IOException ignored) {}
        }
        muteConfig = YamlConfiguration.loadConfiguration(muteFile);
        muteMap.clear();
        if (muteConfig.contains("mutes")) {
            for (String key : muteConfig.getConfigurationSection("mutes").getKeys(false)) {
                String name = muteConfig.getString("mutes." + key + ".name");
                long endTime = muteConfig.getLong("mutes." + key + ".endTime");
                String reason = muteConfig.getString("mutes." + key + ".reason");
                String by = muteConfig.getString("mutes." + key + ".by");
                muteMap.put(UUID.fromString(key), new MuteInfo(name, endTime, reason, by));
            }
        }
    }
    // 工具方法:解析时长字符串(如10m/1h/1d)为毫秒
    private long parseDuration(String input) {
        try {
            if (input.endsWith("m")) {
                return Integer.parseInt(input.replace("m", "")) * 60 * 1000L;
            } else if (input.endsWith("h")) {
                return Integer.parseInt(input.replace("h", "")) * 60 * 60 * 1000L;
            } else if (input.endsWith("d")) {
                return Integer.parseInt(input.replace("d", "")) * 24 * 60 * 60 * 1000L;
            }
        } catch (Exception ignored) {}
        return -1;
    }
    // 工具方法:格式化剩余时间
    private String formatRemain(long endTime) {
        long remain = endTime - System.currentTimeMillis();
        if (remain <= 0) return "已到期";
        long sec = remain / 1000;
        long min = sec / 60;
        long hour = min / 60;
        long day = hour / 24;
        if (day > 0) return day + "天";
        if (hour > 0) return hour + "小时";
        if (min > 0) return min + "分钟";
        return sec + "秒";
    }
    // 禁言信息结构体
    private static class MuteInfo {
        public String playerName;
        public long endTime;
        public String reason;
        public String by;
        public MuteInfo(String playerName, long endTime, String reason, String by) {
            this.playerName = playerName;
            this.endTime = endTime;
            this.reason = reason;
            this.by = by;
        }
    }
}
 |