ItemShow.java v1.3
聊天展示手中物品,鼠标悬停查看详情,统一展示,支持展示冷却,冷却时间可在配置中自定义
命令列表
- 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;
}
}