MuteManager.java v1.0
支持禁言、解禁、禁言列表、自动解禁、权限分级、数据持久化、指令补全的高性能禁言插件
命令列表
- mute禁言玩家
- unmute解除禁言
- mutelist查看禁言记录
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;
}
}
}