docs: 更新 README 添加潜影盒和末影箱功能说明

This commit is contained in:
Coldsmile_7
2026-04-15 01:20:05 +08:00
parent cc07647551
commit 2364ddee97
3 changed files with 22 additions and 93 deletions

View File

@@ -1,8 +1,11 @@
package cn.infstar.essentialsC.commands;
import cn.infstar.essentialsC.EssentialsC;
import org.bukkit.entity.Player;
/**
* 末影箱命令 - 参考 EssentialsX 实现
* 直接打开玩家的末影箱,确保数据安全
*/
public class EnderChestCommand extends BaseCommand {
public EnderChestCommand() {
@@ -11,18 +14,9 @@ public class EnderChestCommand extends BaseCommand {
@Override
protected boolean execute(Player player, String[] args) {
EssentialsC plugin = EssentialsC.getInstance();
// 如果启用了 ProtocolLib使用自定义标题
if (plugin.isProtocolLibEnabled()) {
// 从配置读取标题
String title = plugin.getConfig().getString("enderchest.title", "&5随身末影箱");
// 标记下一个打开的 inventory 需要修改标题
plugin.getInventoryTitleListener().markForTitleChange(player, title);
}
// 直接打开玩家的末影箱(参考 EssentialsX 实现)
// 直接打开玩家的末影箱EssentialsX 方式)
// 优点100% 安全,不会吞物品或刷物品
// 缺点:标题显示为 "Ender Chest"(由客户端语言决定)
player.openInventory(player.getEnderChest());
return true;
}

View File

@@ -1,77 +0,0 @@
package cn.infstar.essentialsC.listeners;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* 使用 ProtocolLib 修改 Inventory 标题
* 通过拦截 OPEN_WINDOW 数据包实现自定义标题
*/
public class InventoryTitleListener extends PacketAdapter {
// 存储需要修改标题的玩家和对应的新标题
private final Map<UUID, String> pendingTitleChanges = new HashMap<>();
public InventoryTitleListener(Plugin plugin) {
super(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.OPEN_WINDOW);
}
/**
* 标记玩家需要修改下一个打开的 inventory 标题
* @param player 玩家
* @param title 新标题(支持颜色代码)
*/
public void markForTitleChange(Player player, String title) {
pendingTitleChanges.put(player.getUniqueId(), title);
}
@Override
public void onPacketSending(PacketEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
// 检查该玩家是否有待处理的标题修改
String newTitle = pendingTitleChanges.remove(playerId);
if (newTitle == null) {
return;
}
try {
PacketContainer packet = event.getPacket();
// Paper 1.21+ 使用 WrappedChatComponent 作为标题
// 将颜色代码 & 转换为 §
String formattedTitle = newTitle.replace('&', '§');
// 创建聊天组件
WrappedChatComponent titleComponent = WrappedChatComponent.fromText(formattedTitle);
// 修改数据包中的标题字段
// 在 1.21+ 中标题是第二个字段索引1
packet.getChatComponents().write(0, titleComponent);
} catch (Exception e) {
// 如果修改失败,记录错误但不影响正常流程
Bukkit.getLogger().warning("[EssentialsC] 修改 inventory 标题失败: " + e.getMessage());
}
}
/**
* 清理所有待处理的标题修改(防止内存泄漏)
*/
public void cleanup() {
pendingTitleChanges.clear();
}
}