From 6ddd6866c0cecea3a08ddac8b6579e240f125668 Mon Sep 17 00:00:00 2001 From: yaohunya <1763917516@qq.com> Date: Sat, 19 Jul 2025 11:51:25 +0800 Subject: [PATCH] 2.0.0 --- .../yaohun/playermail/data/PlayerData.java | 44 +++++++++++++++++++ .../com/yaohun/playermail/gui/MailGui.java | 20 +++++++++ .../com/yaohun/playermail/gui/ToMailGui.java | 39 +++++++++++++++- .../playermail/listener/PlayerListener.java | 24 ++++++++++ .../playermail/manage/PlayerManager.java | 27 ++++++++++++ 5 files changed, 153 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/yaohun/playermail/data/PlayerData.java b/src/main/java/com/yaohun/playermail/data/PlayerData.java index cf599e7..1570385 100644 --- a/src/main/java/com/yaohun/playermail/data/PlayerData.java +++ b/src/main/java/com/yaohun/playermail/data/PlayerData.java @@ -14,13 +14,26 @@ import java.util.HashMap; public class PlayerData { + /** + * 玩家数据类,用于管理玩家的邮件数据 + */ private File file; private FileConfiguration config; + /** + * 玩家名称,用于标识和加载玩家数据 + */ private String playerName; + /** + * 存储邮件的HashMap,键为邮件过期时间,值为邮件物品堆 + */ private HashMap stackHashMap = new HashMap<>(); + /** + * 构造函数,初始化玩家数据 + * @param playerName 玩家名称 + */ public PlayerData(String playerName) { this.playerName = playerName; this.file = new File("plugins/AuData/MailData",playerName+".yml"); @@ -33,6 +46,9 @@ public class PlayerData { loadMailStack(); } + /** + * 加载邮件数据从配置文件到HashMap + */ private void loadMailStack(){ ConfigurationSection section = config.getConfigurationSection("MailData"); if(section == null){ @@ -45,6 +61,9 @@ public class PlayerData { } } + /** + * 保存邮件数据从HashMap到配置文件 + */ public void saveMailStack(){ config.set("MailData",null); if(!stackHashMap.isEmpty()) { @@ -64,26 +83,51 @@ public class PlayerData { } } + /** + * 获取存储邮件的HashMap + * @return 存储邮件的HashMap + */ public HashMap getStackHashMap() { return stackHashMap; } + /** + * 获取玩家邮件的数量 + * @return 邮件数量 + */ public int getMailAmount(){ return stackHashMap.size(); } + /** + * 重置玩家邮件数据,清空所有邮件 + */ public void resetMailData(){ stackHashMap.clear(); } + /** + * 根据过期时间获取邮件物品堆 + * @param expiryTime 邮件过期时间 + * @return 邮件物品堆 + */ public ItemStack getMailStack(long expiryTime){ return stackHashMap.get(expiryTime); } + /** + * 根据过期时间移除邮件 + * @param expiryTime 邮件过期时间 + */ public void removeMailStack(long expiryTime){ stackHashMap.remove(expiryTime); } + /** + * 添加邮件到玩家数据中 + * @param expiryTime 邮件过期时间 + * @param stack 邮件物品堆 + */ public void addMailStack(long expiryTime,ItemStack stack){ stackHashMap.put(expiryTime,stack); } diff --git a/src/main/java/com/yaohun/playermail/gui/MailGui.java b/src/main/java/com/yaohun/playermail/gui/MailGui.java index 5c621c4..42dbb19 100644 --- a/src/main/java/com/yaohun/playermail/gui/MailGui.java +++ b/src/main/java/com/yaohun/playermail/gui/MailGui.java @@ -24,26 +24,46 @@ public class MailGui { private static String invTitle = LangUtil.player_mail_title; + /** + * 打开玩家的邮件界面 + * 此方法负责创建并显示一个包含玩家邮件物品的界面 + * 它从玩家数据中获取邮件物品,并将它们显示在一个 inventory(背包)视图中 + * + * @param player 要打开邮件界面的玩家对象 + */ public static void openGui(Player player){ + // 获取玩家名称 String playerName = player.getName(); + // 获取玩家数据管理器实例 PlayerManager playerManager = MailMain.getPlayerManager(); + // 根据玩家名称获取对应的玩家数据 PlayerData playerData = playerManager.getPlayerData(playerName); + // 创建一个大小为45格,标题为invTitle的背包视图 Inventory inv = Bukkit.createInventory(null,45,invTitle); + // 获取玩家邮件物品的HashMap,其中键为物品的唯一标识,值为物品堆 HashMap stackHashMap = playerData.getStackHashMap(); + // 如果邮件物品不为空,则遍历HashMap并将所有邮件物品添加到背包视图中 if(!stackHashMap.isEmpty()){ for (Long key : stackHashMap.keySet()){ + // 获取当前遍历到的物品堆 ItemStack itemStack = stackHashMap.get(key); + // 使用NBT技术为物品添加唯一的标识键 NbtItem nbtItem = new NbtItem(itemStack); nbtItem.setLong("itemKey",key); + // 将带有唯一标识的物品添加到背包视图中 inv.addItem(nbtItem.getItem()); } } + // 创建一个玻璃物品堆,用于填充背包视图的底部,起装饰和分隔作用 ItemStack glass = DemonAPI.glass(15,"§7[§a■□■§7]"); + // 将玻璃物品堆放置在背包视图的36到44格中,共9格 for (int i = 36; i < 45; i++){ inv.setItem(i, glass); } + // 在背包视图的第40格放置一个信息物品堆,提供额外的功能或信息 inv.setItem(40,infoStack()); + // 最后,将填充好的背包视图展示给玩家 player.openInventory(inv); } diff --git a/src/main/java/com/yaohun/playermail/gui/ToMailGui.java b/src/main/java/com/yaohun/playermail/gui/ToMailGui.java index d2ba919..74a92f3 100644 --- a/src/main/java/com/yaohun/playermail/gui/ToMailGui.java +++ b/src/main/java/com/yaohun/playermail/gui/ToMailGui.java @@ -29,11 +29,23 @@ public class ToMailGui implements Listener { private static String invTitle = "管理员发件箱 - "; + /** + * 打开邮件发送界面 + * 此方法为玩家打开一个用于发送邮件的界面,界面中可以放置物品,以便发送给指定的收件人 + * + * @param player 发送邮件的玩家 + * @param addressee 邮件的收件人 + */ public static void openGui(Player player,String addressee){ + // 创建一个45格的背包界面,标题包含收件人的名字 Inventory inv = Bukkit.createInventory(null,45,invTitle+addressee); + // 获取玩家管理器实例 PlayerManager playerManager = MailMain.getPlayerManager(); + // 根据收件人名字获取其玩家数据 PlayerData playerData = playerManager.getPlayerData(addressee); + // 获取收件人存储的物品哈希映射,包含物品和其对应的唯一键值 HashMap stackHashMap = playerData.getStackHashMap(); + // 如果哈希映射不为空,则遍历所有物品,并设置每个物品的NBT数据,然后添加到界面中 if(!stackHashMap.isEmpty()){ for (Long key : stackHashMap.keySet()){ ItemStack itemStack = stackHashMap.get(key); @@ -42,43 +54,67 @@ public class ToMailGui implements Listener { inv.addItem(nbtItem.getItem()); } } + // 在界面的底部填充玻璃物品,作为界面的一部分,起装饰作用 for (int i=36;i<45;i++){ inv.setItem(i, DemonAPI.glass(15,"§7[§a■□■§7]")); } + // 创建一个雪球物品,用于确认发货操作,并设置其显示名称和NBT数据 ItemStack stack = new ItemStack(Material.SNOW_BALL); ItemMeta meta = stack.getItemMeta(); meta.setDisplayName("§6§l确认发货"); stack.setItemMeta(meta); NbtItem nbtItem = new NbtItem(stack); nbtItem.setString("addressee",addressee); + // 将确认发货的雪球物品放置在界面的特定位置 inv.setItem(40,nbtItem.getItem()); + // 打开界面供玩家进行操作 player.openInventory(inv); } + /** + * 处理玩家点击背包事件的函数 + * 该函数主要目的是在特定的背包界面中,处理玩家点击特定位置时的操作 + * + * @param e 玩家点击背包事件对象,包含事件相关数据,如点击位置、背包信息等 + */ @EventHandler public void onClick(InventoryClickEvent e){ + // 获取玩家点击的原始槽位 int rawSlot = e.getRawSlot(); + // 获取点击背包的玩家,并转换为Player对象 Player player = (Player) e.getWhoClicked(); + // 获取玩家名称 String playerName = player.getName(); + // 获取被点击的背包 Inventory inv = e.getInventory(); + // 检查背包标题是否包含特定的标题,以确定是否是目标背包界面 if(e.getView().getTitle().contains(invTitle)){ + // 当点击位置在特定范围内时,执行以下操作 if(rawSlot >= 36 && rawSlot <= 44) { + // 取消默认的点击事件 e.setCancelled(true); + // 如果点击的位置是特定位置,则执行邮件发送操作 if(rawSlot == 40){ + // 使用NBT库获取当前物品的特定标签值 NbtItem nbtItem = new NbtItem(e.getCurrentItem()); String addressee = nbtItem.getString("addressee"); + // 获取玩家管理器和目标玩家的数据 PlayerManager playerManager = MailMain.getPlayerManager(); PlayerData playerData = playerManager.getPlayerData(addressee); + // 重置目标玩家的邮件数据 playerData.resetMailData(); - + // 创建一个缓存背包,用于临时存储物品 Inventory cacheInv = Bukkit.createInventory(null, 27, "这是一个缓存虚拟器"); + // 将当前背包中的物品转移到缓存背包中 for (int i = 0; i < 36; i++) { ItemStack item = inv.getItem(i); if (!DemonAPI.itemIsNull(item)) { cacheInv.addItem(item); } } + // 初始化物品数量计数器 int amount = 0; + // 遍历缓存背包中的物品,执行发送邮件的操作 for (int slot = 0; slot < 27; slot++){ ItemStack stack = cacheInv.getItem(slot); if (!DemonAPI.itemIsNull(stack)) { @@ -86,6 +122,7 @@ public class ToMailGui implements Listener { amount += stack.getAmount(); } } + // 根据发送的物品数量,给予玩家反馈 if(amount >= 1) { playerData.saveMailStack(); player.closeInventory(); diff --git a/src/main/java/com/yaohun/playermail/listener/PlayerListener.java b/src/main/java/com/yaohun/playermail/listener/PlayerListener.java index a3dbfeb..40120be 100644 --- a/src/main/java/com/yaohun/playermail/listener/PlayerListener.java +++ b/src/main/java/com/yaohun/playermail/listener/PlayerListener.java @@ -20,23 +20,47 @@ public class PlayerListener implements Listener { plugin.getServer().getPluginManager().registerEvents(this,plugin); } + /** + * 当玩家更换世界时触发的事件处理方法 + * 此方法检查玩家是否有未读邮件,并在有未读邮件时提醒玩家 + * + * @param e 玩家更换世界事件对象,包含事件相关信息 + */ @EventHandler public void onjoin(PlayerChangedWorldEvent e){ + // 获取事件涉及的玩家对象 Player p = e.getPlayer(); + // 获取玩家的名称 String playerName = p.getName(); + // 获取玩家数据管理器实例 PlayerManager playerManager = MailMain.getPlayerManager(); + // 根据玩家名称获取玩家数据对象 PlayerData playerData = playerManager.getPlayerData(playerName); + // 获取玩家未读邮件的数量 int amountMail = playerData.getMailAmount(); + // 如果玩家有未读邮件,调用OpenMail方法发送提示信息 if(amountMail >= 1){ OpenMail(p, LangUtil.notice_player.replace("{amount}",String.valueOf(amountMail))); } } + /** + * 发送带有点击事件的邮件提示信息给指定玩家 + * 此方法构造一个TextComponent对象,包含邮件提示信息和点击事件,发送给玩家 + * + * @param player 接收提示信息的玩家对象 + * @param message 提示信息文本 + */ public static void OpenMail (Player player,String message) { + // 创建文本组件对象,用于显示提示信息 TextComponent Click = new TextComponent(message); + // 设置文本组件的悬停事件,当鼠标悬停时显示特定文本 Click.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("§e点击打开邮箱").create())); + // 设置文本组件的点击事件,当点击文本时执行特定命令 Click.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/dpmail open")); + // 发送带有事件的提示信息给指定玩家 player.spigot().sendMessage(Click); } + } diff --git a/src/main/java/com/yaohun/playermail/manage/PlayerManager.java b/src/main/java/com/yaohun/playermail/manage/PlayerManager.java index e68dcbd..3937771 100644 --- a/src/main/java/com/yaohun/playermail/manage/PlayerManager.java +++ b/src/main/java/com/yaohun/playermail/manage/PlayerManager.java @@ -7,30 +7,57 @@ import org.bukkit.entity.Player; import java.util.HashMap; import java.util.Map; +/** + * 玩家管理器类,用于管理所有玩家的数据 + */ public class PlayerManager { + // 存储所有玩家数据的映射表,键为玩家名称,值为玩家数据对象 private Map playerDataMap = new HashMap<>(); + /** + * 构造函数,初始化在线玩家数据 + */ public PlayerManager(){ + // 遍历当前所有在线玩家 for (Player player : Bukkit.getOnlinePlayers()){ + // 仅处理等级达到50级以上的玩家 if(player.getLevel() >= 50){ + // 获取玩家名称 String playerName = player.getName(); + // 创建玩家数据对象 PlayerData playerData = new PlayerData(playerName); + // 将玩家数据添加到映射表中 playerDataMap.put(playerName, playerData); } } } + /** + * 获取玩家数据,如果玩家数据不存在,则创建新的玩家数据对象 + * + * @param playerName 玩家名称 + * @return 玩家数据对象 + */ public PlayerData getPlayerData(String playerName){ + // 检查映射表中是否存在指定玩家的数据 if(!playerDataMap.containsKey(playerName)) { + // 如果不存在,创建新的玩家数据对象 PlayerData playerData = new PlayerData(playerName); + // 将新的玩家数据对象添加到映射表中 playerDataMap.put(playerName, playerData); } + // 返回玩家数据对象 return playerDataMap.get(playerName); } + /** + * 保存所有玩家的数据 + */ public void saveAllPlayerData(){ + // 遍历所有玩家数据 for (PlayerData playerData : playerDataMap.values()){ + // 保存每个玩家的邮件栈数据 playerData.saveMailStack(); } }