MuteManager

MuteManager.java v1.0
支持禁言、解禁、禁言列表、自动解禁、权限分级、数据持久化、指令补全的高性能禁言插件
作者: ScriptircAI

命令列表

  • mute禁言玩家
  • unmute解除禁言
  • mutelist查看禁言记录

权限列表

  • mutemanager.admin禁言管理权限(禁言/解禁/查看他人禁言)
package com.example.mutemanager;

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 java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;

/**
 * @pluginName MuteManager
 * @author ScriptircAI
 * @version 1.0
 * @description 支持禁言、解禁、禁言列表、自动解禁、权限分级、数据持久化、指令补全的高性能禁言插件
 * [command]mute|禁言玩家[/command]
 * [command]unmute|解除禁言[/command]
 * [command]mutelist|查看禁言记录[/command]
 * [Permission]mutemanager.admin|禁言管理权限(禁言/解禁/查看他人禁言)[/Permission]
 */
public class MuteManager extends JavaPlugin implements TabCompleter {
    // 内存缓存禁言信息,key为玩家名
    private final Map<String, MuteRecord> muteMap = new ConcurrentHashMap<>();
    private File muteFile;
    private FileConfiguration muteConfig;

    @Override
    public void onEnable() {
        // 初始化配置文件
        initConfig();
        // 加载禁言数据
        loadMuteData();
        // 启动自动解禁任务
        startAutoUnmuteTask();
        // 注册指令补全
        getCommand("mute").setTabCompleter(this);
        getCommand("unmute").setTabCompleter(this);
        getCommand("mutelist").setTabCompleter(this);
        getLogger().info("MuteManager 启动成功!");
    }

    @Override
    public void onDisable() {
        saveMuteData();
        getLogger().info("MuteManager 已关闭,禁言数据已保存。");
    }

    // 初始化配置文件
    private void initConfig() {
        muteFile = new File(getDataFolder(), "mutes.yml");
        if (!muteFile.exists()) {
            try {
                getDataFolder().mkdirs();
                muteFile.createNewFile();
            } catch (IOException e) {
                getLogger().warning("无法创建mutes.yml: " + e.getMessage());
            }
        }
        muteConfig = YamlConfiguration.loadConfiguration(muteFile);
    }

    // 加载禁言数据到内存
    private void loadMuteData() {
        muteMap.clear();
        if (muteConfig.contains("mutes")) {
            for (String player : muteConfig.getConfigurationSection("mutes").getKeys(false)) {
                long endTime = muteConfig.getLong("mutes." + player + ".endTime");
                String reason = muteConfig.getString("mutes." + player + ".reason", "无");
                String operator = muteConfig.getString("mutes." + player + ".operator", "未知");
                long startTime = muteConfig.getLong("mutes." + player + ".startTime", 0);
                muteMap.put(player.toLowerCase(), new MuteRecord(player, reason, operator, startTime, endTime));
            }
        }
    }

    // 保存禁言数据到文件
    private void saveMuteData() {
        muteConfig.set("mutes", null);
        for (MuteRecord record : muteMap.values()) {
            String path = "mutes." + record.player;
            muteConfig.set(path + ".reason", record.reason);
            muteConfig.set(path + ".operator", record.operator);
            muteConfig.set(path + ".startTime", record.startTime);
            muteConfig.set(path + ".endTime", record.endTime);
        }
        try {
            muteConfig.save(muteFile);
        } catch (IOException e) {
            getLogger().warning("保存mutes.yml失败: " + e.getMessage());
        }
    }

    // 自动解禁任务,每分钟检查一次
    private void startAutoUnmuteTask() {
        new BukkitRunnable() {
            @Override
            public void run() {
                long now = System.currentTimeMillis();
                List<String> toUnmute = new ArrayList<>();
                for (MuteRecord record : muteMap.values()) {
                    if (record.endTime > 0 && record.endTime <= now) {
                        toUnmute.add(record.player.toLowerCase());
                    }
                }
                for (String player : toUnmute) {
                    muteMap.remove(player);
                    Player p = Bukkit.getPlayerExact(player);
                    if (p != null && p.isOnline()) {
                        p.sendMessage(ChatColor.GREEN + "你的禁言已自动解除!");
                    }
                }
                if (!toUnmute.isEmpty()) saveMuteData();
            }
        }.runTaskTimer(this, 20L, 1200L); // 1分钟
    }

    // 判断玩家是否被禁言
    private boolean isMuted(String player) {
        MuteRecord record = muteMap.get(player.toLowerCase());
        if (record == null) return false;
        if (record.endTime > 0 && record.endTime < System.currentTimeMillis()) {
            muteMap.remove(player.toLowerCase());
            saveMuteData();
            return false;
        }
        return true;
    }

    // 解析时长字符串(如1d2h30m)为毫秒
    private long parseDuration(String timeStr) {
        long total = 0;
        StringBuilder num = new StringBuilder();
        for (char c : timeStr.toCharArray()) {
            if (Character.isDigit(c)) {
                num.append(c);
            } else {
                int n = num.length() > 0 ? Integer.parseInt(num.toString()) : 0;
                switch (c) {
                    case 'd': total += n * 86400000L; break;
                    case 'h': total += n * 3600000L; break;
                    case 'm': total += n * 60000L; break;
                    case 's': total += n * 1000L; break;
                }
                num.setLength(0);
            }
        }
        return total;
    }

    // 指令处理
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        if (cmd.getName().equalsIgnoreCase("mute")) {
            // /mute <玩家> <时长> <原因>
            if (!sender.hasPermission("mutemanager.admin")) {
                sender.sendMessage(ChatColor.RED + "你没有权限使用此命令。");
                return true;
            }
            if (args.length < 2) {
                sender.sendMessage(ChatColor.YELLOW + "用法: /mute <玩家> <时长> <原因>");
                sender.sendMessage(ChatColor.GRAY + "例: /mute Steve 1d2h30m 违规发言");
                return true;
            }
            String target = args[0];
            String timeStr = args[1];
            long duration = parseDuration(timeStr);
            if (duration <= 0) {
                sender.sendMessage(ChatColor.RED + "时长格式错误,请用如1d2h30m。");
                return true;
            }
            String reason = args.length >= 3 ? String.join(" ", Arrays.copyOfRange(args, 2, args.length)) : "无";
            long now = System.currentTimeMillis();
            long end = now + duration;
            muteMap.put(target.toLowerCase(), new MuteRecord(target, reason, sender.getName(), now, end));
            saveMuteData();
            sender.sendMessage(ChatColor.GREEN + "已禁言 " + target + ",时长: " + timeStr + ",原因: " + reason);
            Player p = Bukkit.getPlayerExact(target);
            if (p != null && p.isOnline()) {
                p.sendMessage(ChatColor.RED + "你已被禁言,时长: " + timeStr + ",原因: " + reason);
            }
            return true;
        }
        if (cmd.getName().equalsIgnoreCase("unmute")) {
            // /unmute <玩家>
            if (!sender.hasPermission("mutemanager.admin")) {
                sender.sendMessage(ChatColor.RED + "你没有权限使用此命令。");
                return true;
            }
            if (args.length < 1) {
                sender.sendMessage(ChatColor.YELLOW + "用法: /unmute <玩家>");
                return true;
            }
            String target = args[0];
            if (!isMuted(target)) {
                sender.sendMessage(ChatColor.YELLOW + target + " 当前未被禁言。");
                return true;
            }
            muteMap.remove(target.toLowerCase());
            saveMuteData();
            sender.sendMessage(ChatColor.GREEN + "已解除 " + target + " 的禁言。");
            Player p = Bukkit.getPlayerExact(target);
            if (p != null && p.isOnline()) {
                p.sendMessage(ChatColor.GREEN + "你的禁言已被管理员解除!");
            }
            return true;
        }
        if (cmd.getName().equalsIgnoreCase("mutelist")) {
            // /mutelist [玩家]
            if (args.length == 0) {
                // 玩家自己查自己
                if (sender instanceof Player) {
                    String name = sender.getName();
                    if (isMuted(name)) {
                        MuteRecord r = muteMap.get(name.toLowerCase());
                        sender.sendMessage(ChatColor.YELLOW + "你当前被禁言:");
                        sender.sendMessage(ChatColor.GRAY + "原因: " + r.reason);
                        sender.sendMessage(ChatColor.GRAY + "操作人: " + r.operator);
                        sender.sendMessage(ChatColor.GRAY + "到期: " + (r.endTime == 0 ? "永久" : new Date(r.endTime).toString()));
                    } else {
                        sender.sendMessage(ChatColor.GREEN + "你当前未被禁言。");
                    }
                } else {
                    sender.sendMessage(ChatColor.YELLOW + "控制台请指定玩家名: /mutelist <玩家>");
                }
                return true;
            } else {
                // 管理员查指定玩家
                if (!sender.hasPermission("mutemanager.admin")) {
                    sender.sendMessage(ChatColor.RED + "你没有权限查看他人禁言记录。");
                    return true;
                }
                String target = args[0];
                if (isMuted(target)) {
                    MuteRecord r = muteMap.get(target.toLowerCase());
                    sender.sendMessage(ChatColor.YELLOW + target + " 当前被禁言:");
                    sender.sendMessage(ChatColor.GRAY + "原因: " + r.reason);
                    sender.sendMessage(ChatColor.GRAY + "操作人: " + r.operator);
                    sender.sendMessage(ChatColor.GRAY + "到期: " + (r.endTime == 0 ? "永久" : new Date(r.endTime).toString()));
                } else {
                    sender.sendMessage(ChatColor.GREEN + target + " 当前未被禁言。");
                }
                return true;
            }
        }
        return false;
    }

    // 指令补全
    @Override
    public List<String> onTabComplete(CommandSender sender, Command cmd, String alias, String[] args) {
        if (cmd.getName().equalsIgnoreCase("mute")) {
            if (args.length == 1) {
                // 补全在线玩家名
                return Bukkit.getOnlinePlayers().stream().map(Player::getName)
                        .filter(n -> n.toLowerCase().startsWith(args[0].toLowerCase())).collect(Collectors.toList());
            }
            if (args.length == 2) {
                // 补全常用时长
                return Arrays.asList("10m", "1h", "1d", "7d");
            }
        }
        if (cmd.getName().equalsIgnoreCase("unmute")) {
            if (args.length == 1) {
                // 补全当前被禁言的玩家
                return muteMap.keySet().stream().filter(n -> n.startsWith(args[0].toLowerCase()))
                        .collect(Collectors.toList());
            }
        }
        if (cmd.getName().equalsIgnoreCase("mutelist")) {
            if (args.length == 1 && sender.hasPermission("mutemanager.admin")) {
                // 管理员补全被禁言玩家
                return muteMap.keySet().stream().filter(n -> n.startsWith(args[0].toLowerCase()))
                        .collect(Collectors.toList());
            }
        }
        return Collections.emptyList();
    }

    // 禁言记录数据结构
    private static class MuteRecord {
        String player;
        String reason;
        String operator;
        long startTime;
        long endTime;
        MuteRecord(String player, String reason, String operator, long startTime, long endTime) {
            this.player = player;
            this.reason = reason;
            this.operator = operator;
            this.startTime = startTime;
            this.endTime = endTime;
        }
    }
}

上一篇: Qiandao下一篇: CobbleOreGenerator

举报内容

意见反馈