ItemShow

ItemShow.java v1.3
聊天展示手中物品,鼠标悬停查看详情,统一展示,支持展示冷却,冷却时间可在配置中自定义
作者: ScriptIrc Engine

命令列表

  • reloaditemshow重载ItemShow插件配置
package com.yourdomain.itemshow;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.hover.content.Text;

import java.io.File;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @pluginName ItemShow
 * @author ScriptIrc Engine
 * @version 1.3
 * @description 聊天展示手中物品,鼠标悬停查看详情,统一展示,支持展示冷却,冷却时间可在配置中自定义
 * [command]reloaditemshow|重载ItemShow插件配置[/command]
 */
public class ItemShowPlugin extends JavaPlugin implements Listener {
    private String triggerWord;
    private String displayFormat;
    private long cooldownMillis; // 冷却时间(毫秒)
    private FileConfiguration config;

    // 用于记录玩家上一次展示时间
    private Map<UUID, Long> lastShowTime = new ConcurrentHashMap<>();

    @Override
    public void onEnable() {
        getServer().getPluginManager().registerEvents(this, this);
        initConfig();
        getLogger().info("ItemShow插件已启用!");
    }

    @Override
    public void onDisable() {
        getLogger().info("ItemShow插件已关闭!");
        lastShowTime.clear();
    }

    // 初始化并读取配置
    private void initConfig() {
        File configFile = new File(getDataFolder(), "config.yml");
        if (!configFile.exists()) {
            getDataFolder().mkdirs();
            getConfig().set("trigger", "[手中物品]");
            getConfig().set("display_format", "&f玩家&6{name}&f展示了手中物品: &a[{item}]&f x{amount}");
            getConfig().set("cooldown", 5); // 默认冷却5秒
            saveConfig();
        }
        reloadConfig();
        config = getConfig();
        triggerWord = config.getString("trigger", "[手中物品]");
        displayFormat = config.getString("display_format", "&f玩家&6{name}&f展示了手中物品: &a[{item}]&f x{amount}");
        long seconds = config.getLong("cooldown", 5);
        cooldownMillis = seconds * 1000;
    }

    // 核心聊天监听逻辑
    @EventHandler
    public void onChat(AsyncPlayerChatEvent event) {
        Player player = event.getPlayer();
        UUID uuid = player.getUniqueId();
        String message = event.getMessage();

        // 判断是否含触发关键字
        if (!message.contains(triggerWord)) return;

        // 冷却校验
        long now = System.currentTimeMillis();
        long last = lastShowTime.getOrDefault(uuid, 0L);
        long left = (last + cooldownMillis) - now;
        if (left > 0) {
            // 冷却中,通知玩家剩余时间
            long sec = (left + 999) / 1000;
            player.sendMessage(ChatColor.RED + "展示冷却中,还需等待 " + sec + " 秒!");
            event.setCancelled(true); // 不允许展示
            return;
        }

        // 已通过冷却检测,刷新展示时间
        lastShowTime.put(uuid, now);

        // 获取玩家手中物品信息
        ItemStack item = player.getInventory().getItemInMainHand();
        String itemName;
        if (item == null || item.getType() == Material.AIR) {
            itemName = "无物品";
        } else if (item.hasItemMeta() && item.getItemMeta().hasDisplayName()) {
            itemName = item.getItemMeta().getDisplayName();
        } else {
            itemName = item.getType().name();
        }
        int amount = (item == null ? 0 : item.getAmount());

        // 构建展示文本
        String displayMsg = ChatColor.translateAlternateColorCodes('&', displayFormat
                .replace("{name}", player.getName())
                .replace("{item}", itemName)
                .replace("{amount}", String.valueOf(amount)));

        // 构建Hover文本,附详细物品信息
        StringBuilder hover = new StringBuilder();
        hover.append(ChatColor.YELLOW).append("物品名: ").append(itemName).append("\n");
        hover.append(ChatColor.GREEN).append("数量: ").append(amount).append("\n");
        if (item != null && item.hasItemMeta()) {
            ItemMeta meta = item.getItemMeta();
            // 附魔列表
            Map<Enchantment, Integer> enchants = meta.getEnchants();
            if (!enchants.isEmpty()) {
                hover.append(ChatColor.AQUA + "附魔:\n");
                for (Map.Entry<Enchantment, Integer> entry : enchants.entrySet()) {
                    hover.append(" - ").append(entry.getKey().getKey().getKey())
                            .append(":").append(entry.getValue()).append("\n");
                }
            }
            // Lore文本
            if (meta.hasLore()) {
                hover.append(ChatColor.LIGHT_PURPLE + "描述:\n");
                for (String lore : meta.getLore()) {
                    hover.append("   ").append(ChatColor.GRAY).append(lore).append("\n");
                }
            }
        }

        // 只替换一次关键词为展示组件
        int idx = message.indexOf(triggerWord);
        String before = message.substring(0, idx);
        String after = message.substring(idx + triggerWord.length());

        ComponentBuilder cb = new ComponentBuilder();
        cb.append(ChatColor.translateAlternateColorCodes('&', before));
        TextComponent itemShow = new TextComponent(displayMsg);
        itemShow.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(hover.toString().trim())));
        cb.append(itemShow);
        cb.append(ChatColor.translateAlternateColorCodes('&', after));

        // 取消原消息并广播新构造的JSON消息
        event.setCancelled(true);
        for (Player p : Bukkit.getOnlinePlayers()) {
            p.spigot().sendMessage(cb.create());
        }
    }

    // 支持插件命令重载冷却与其他配置
    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (label.equalsIgnoreCase("reloaditemshow")) {
            reloadConfig();
            config = getConfig();
            triggerWord = config.getString("trigger", "[手中物品]");
            displayFormat = config.getString("display_format", "&f玩家&6{name}&f展示了手中物品: &a[{item}]&f x{amount}");
            long seconds = config.getLong("cooldown", 5);
            cooldownMillis = seconds * 1000;
            sender.sendMessage(ChatColor.GREEN + "ItemShow 配置已重载!");
            return true;
        }
        return false;
    }
}

上一篇: MenuBackpack

举报内容

意见反馈