IgnoreChat

IgnoreChat.java v1.0
玩家可通过命令或点击屏蔽/解除他人,屏蔽后看不到对方发言和私聊,支持持久化和聊天栏点击。
作者: A2whatever33

命令列表

  • /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);
    }
}

上一篇: ExpShopMenu下一篇: FirstJoinCommand

举报内容

意见反馈