IgnoreChat.java v1.0
玩家可通过命令或点击屏蔽/解除他人,屏蔽后看不到对方发言和私聊,支持持久化和聊天栏点击。
命令列表
- /pb屏蔽或解除屏蔽某玩家
package com.scriptirc.ignorechat;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.CommandExecutor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.scheduler.BukkitRunnable;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.TextComponent;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* @pluginName IgnoreChat
* @author A2whatever33
* @version 1.0
* @description 玩家可通过命令或点击屏蔽/解除他人,屏蔽后看不到对方发言和私聊,支持持久化和聊天栏点击。
* [command]/pb|屏蔽或解除屏蔽某玩家[/command]
*/
public class IgnoreChatPlugin extends JavaPlugin implements Listener {
// 存储每个玩家屏蔽的玩家名集合(用UUID字符串,防止重名)
private Map<UUID, Set<UUID>> ignoreMap = new HashMap<>();
private File ignoreFile;
private FileConfiguration ignoreConfig;
@Override
public void onEnable() {
// 注册事件监听
Bukkit.getPluginManager().registerEvents(this, this);
// 注册命令
this.getCommand("pb").setExecutor(this);
// 加载屏蔽名单
loadIgnoreList();
getLogger().info("IgnoreChat 插件已启用!");
}
@Override
public void onDisable() {
saveIgnoreList();
getLogger().info("IgnoreChat 插件已关闭!");
}
// 加载屏蔽名单
private void loadIgnoreList() {
ignoreFile = new File(getDataFolder(), "IgnoreList.yml");
if (!ignoreFile.exists()) {
ignoreFile.getParentFile().mkdirs();
try {
ignoreFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
ignoreConfig = YamlConfiguration.loadConfiguration(ignoreFile);
ignoreMap.clear();
for (String uuidStr : ignoreConfig.getKeys(false)) {
List<String> list = ignoreConfig.getStringList(uuidStr);
Set<UUID> set = new HashSet<>();
for (String s : list) {
try {
set.add(UUID.fromString(s));
} catch (Exception ignored) {}
}
ignoreMap.put(UUID.fromString(uuidStr), set);
}
}
// 保存屏蔽名单
private void saveIgnoreList() {
for (Map.Entry<UUID, Set<UUID>> entry : ignoreMap.entrySet()) {
List<String> list = new ArrayList<>();
for (UUID uuid : entry.getValue()) {
list.add(uuid.toString());
}
ignoreConfig.set(entry.getKey().toString(), list);
}
try {
ignoreConfig.save(ignoreFile);
} catch (IOException e) {
e.printStackTrace();
}
}
// 聊天事件:移除被屏蔽者
@EventHandler
public void onChat(AsyncPlayerChatEvent event) {
Player sender = event.getPlayer();
// 构造带点击的玩家名
TextComponent name = new TextComponent(sender.getDisplayName());
name.setColor(net.md_5.bungee.api.ChatColor.YELLOW);
name.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/pb " + sender.getName()));
// 替换聊天格式
event.setFormat("%s: %s");
// 遍历收件人,移除屏蔽了sender的玩家
Iterator<Player> it = event.getRecipients().iterator();
while (it.hasNext()) {
Player p = it.next();
if (isIgnored(p.getUniqueId(), sender.getUniqueId())) {
it.remove();
}
}
// 发送带点击的名字(仅给未屏蔽sender的玩家)
for (Player p : event.getRecipients()) {
TextComponent msg = new TextComponent("");
msg.addExtra(name);
msg.addExtra(new TextComponent(ChatColor.WHITE + ": " + event.getMessage()));
p.spigot().sendMessage(msg);
}
// 阻止原始消息广播
event.setCancelled(true);
}
// 私聊命令拦截(支持/msg /tell /w等)
@EventHandler
public void onCommandPreprocess(PlayerCommandPreprocessEvent event) {
String msg = event.getMessage().toLowerCase();
Player sender = event.getPlayer();
String[] args = msg.split(" ");
if (args.length < 2) return;
String cmd = args[0].replace("/", "");
if (cmd.equals("msg") || cmd.equals("tell") || cmd.equals("w")) {
Player target = Bukkit.getPlayerExact(args[1]);
if (target != null && isIgnored(target.getUniqueId(), sender.getUniqueId())) {
sender.sendMessage(ChatColor.RED + "你已被该玩家屏蔽,无法发送私聊。");
event.setCancelled(true);
}
}
}
// /pb <player> 命令实现
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (!(sender instanceof Player)) {
sender.sendMessage("该命令只能由玩家执行。");
return true;
}
Player player = (Player) sender;
if (args.length != 1) {
player.sendMessage(ChatColor.YELLOW + "用法: /pb <玩家名>");
return true;
}
Player target = Bukkit.getPlayerExact(args[0]);
if (target == null) {
player.sendMessage(ChatColor.RED + "玩家未在线。");
return true;
}
if (target.getUniqueId().equals(player.getUniqueId())) {
player.sendMessage(ChatColor.RED + "不能屏蔽自己。");
return true;
}
Set<UUID> set = ignoreMap.computeIfAbsent(player.getUniqueId(), k -> new HashSet<>());
if (set.contains(target.getUniqueId())) {
set.remove(target.getUniqueId());
player.sendMessage(ChatColor.GREEN + "已解除对 " + target.getName() + " 的屏蔽。");
} else {
set.add(target.getUniqueId());
player.sendMessage(ChatColor.GREEN + "已屏蔽 " + target.getName() + " 的发言和私聊。");
}
saveIgnoreList();
return true;
}
// 玩家上线/下线时自动加载/保存数据
@EventHandler
public void onJoin(PlayerJoinEvent event) {
// 可选:未来扩展
}
@EventHandler
public void onQuit(PlayerQuitEvent event) {
saveIgnoreList();
}
// 判断p1是否屏蔽了p2
private boolean isIgnored(UUID p1, UUID p2) {
Set<UUID> set = ignoreMap.get(p1);
return set != null && set.contains(p2);
}
}