This commit is contained in:
yaohunya 2025-07-19 11:51:25 +08:00
parent 32631e6c59
commit 6ddd6866c0
5 changed files with 153 additions and 1 deletions

View File

@ -14,13 +14,26 @@ import java.util.HashMap;
public class PlayerData { public class PlayerData {
/**
* 玩家数据类用于管理玩家的邮件数据
*/
private File file; private File file;
private FileConfiguration config; private FileConfiguration config;
/**
* 玩家名称用于标识和加载玩家数据
*/
private String playerName; private String playerName;
/**
* 存储邮件的HashMap键为邮件过期时间值为邮件物品堆
*/
private HashMap<Long, ItemStack> stackHashMap = new HashMap<>(); private HashMap<Long, ItemStack> stackHashMap = new HashMap<>();
/**
* 构造函数初始化玩家数据
* @param playerName 玩家名称
*/
public PlayerData(String playerName) { public PlayerData(String playerName) {
this.playerName = playerName; this.playerName = playerName;
this.file = new File("plugins/AuData/MailData",playerName+".yml"); this.file = new File("plugins/AuData/MailData",playerName+".yml");
@ -33,6 +46,9 @@ public class PlayerData {
loadMailStack(); loadMailStack();
} }
/**
* 加载邮件数据从配置文件到HashMap
*/
private void loadMailStack(){ private void loadMailStack(){
ConfigurationSection section = config.getConfigurationSection("MailData"); ConfigurationSection section = config.getConfigurationSection("MailData");
if(section == null){ if(section == null){
@ -45,6 +61,9 @@ public class PlayerData {
} }
} }
/**
* 保存邮件数据从HashMap到配置文件
*/
public void saveMailStack(){ public void saveMailStack(){
config.set("MailData",null); config.set("MailData",null);
if(!stackHashMap.isEmpty()) { if(!stackHashMap.isEmpty()) {
@ -64,26 +83,51 @@ public class PlayerData {
} }
} }
/**
* 获取存储邮件的HashMap
* @return 存储邮件的HashMap
*/
public HashMap<Long, ItemStack> getStackHashMap() { public HashMap<Long, ItemStack> getStackHashMap() {
return stackHashMap; return stackHashMap;
} }
/**
* 获取玩家邮件的数量
* @return 邮件数量
*/
public int getMailAmount(){ public int getMailAmount(){
return stackHashMap.size(); return stackHashMap.size();
} }
/**
* 重置玩家邮件数据清空所有邮件
*/
public void resetMailData(){ public void resetMailData(){
stackHashMap.clear(); stackHashMap.clear();
} }
/**
* 根据过期时间获取邮件物品堆
* @param expiryTime 邮件过期时间
* @return 邮件物品堆
*/
public ItemStack getMailStack(long expiryTime){ public ItemStack getMailStack(long expiryTime){
return stackHashMap.get(expiryTime); return stackHashMap.get(expiryTime);
} }
/**
* 根据过期时间移除邮件
* @param expiryTime 邮件过期时间
*/
public void removeMailStack(long expiryTime){ public void removeMailStack(long expiryTime){
stackHashMap.remove(expiryTime); stackHashMap.remove(expiryTime);
} }
/**
* 添加邮件到玩家数据中
* @param expiryTime 邮件过期时间
* @param stack 邮件物品堆
*/
public void addMailStack(long expiryTime,ItemStack stack){ public void addMailStack(long expiryTime,ItemStack stack){
stackHashMap.put(expiryTime,stack); stackHashMap.put(expiryTime,stack);
} }

View File

@ -24,26 +24,46 @@ public class MailGui {
private static String invTitle = LangUtil.player_mail_title; private static String invTitle = LangUtil.player_mail_title;
/**
* 打开玩家的邮件界面
* 此方法负责创建并显示一个包含玩家邮件物品的界面
* 它从玩家数据中获取邮件物品并将它们显示在一个 inventory背包视图中
*
* @param player 要打开邮件界面的玩家对象
*/
public static void openGui(Player player){ public static void openGui(Player player){
// 获取玩家名称
String playerName = player.getName(); String playerName = player.getName();
// 获取玩家数据管理器实例
PlayerManager playerManager = MailMain.getPlayerManager(); PlayerManager playerManager = MailMain.getPlayerManager();
// 根据玩家名称获取对应的玩家数据
PlayerData playerData = playerManager.getPlayerData(playerName); PlayerData playerData = playerManager.getPlayerData(playerName);
// 创建一个大小为45格标题为invTitle的背包视图
Inventory inv = Bukkit.createInventory(null,45,invTitle); Inventory inv = Bukkit.createInventory(null,45,invTitle);
// 获取玩家邮件物品的HashMap其中键为物品的唯一标识值为物品堆
HashMap<Long, ItemStack> stackHashMap = playerData.getStackHashMap(); HashMap<Long, ItemStack> stackHashMap = playerData.getStackHashMap();
// 如果邮件物品不为空则遍历HashMap并将所有邮件物品添加到背包视图中
if(!stackHashMap.isEmpty()){ if(!stackHashMap.isEmpty()){
for (Long key : stackHashMap.keySet()){ for (Long key : stackHashMap.keySet()){
// 获取当前遍历到的物品堆
ItemStack itemStack = stackHashMap.get(key); ItemStack itemStack = stackHashMap.get(key);
// 使用NBT技术为物品添加唯一的标识键
NbtItem nbtItem = new NbtItem(itemStack); NbtItem nbtItem = new NbtItem(itemStack);
nbtItem.setLong("itemKey",key); nbtItem.setLong("itemKey",key);
// 将带有唯一标识的物品添加到背包视图中
inv.addItem(nbtItem.getItem()); inv.addItem(nbtItem.getItem());
} }
} }
// 创建一个玻璃物品堆用于填充背包视图的底部起装饰和分隔作用
ItemStack glass = DemonAPI.glass(15,"§7[§a■□■§7]"); ItemStack glass = DemonAPI.glass(15,"§7[§a■□■§7]");
// 将玻璃物品堆放置在背包视图的36到44格中共9格
for (int i = 36; i < 45; i++){ for (int i = 36; i < 45; i++){
inv.setItem(i, glass); inv.setItem(i, glass);
} }
// 在背包视图的第40格放置一个信息物品堆提供额外的功能或信息
inv.setItem(40,infoStack()); inv.setItem(40,infoStack());
// 最后将填充好的背包视图展示给玩家
player.openInventory(inv); player.openInventory(inv);
} }

View File

@ -29,11 +29,23 @@ public class ToMailGui implements Listener {
private static String invTitle = "管理员发件箱 - "; private static String invTitle = "管理员发件箱 - ";
/**
* 打开邮件发送界面
* 此方法为玩家打开一个用于发送邮件的界面界面中可以放置物品以便发送给指定的收件人
*
* @param player 发送邮件的玩家
* @param addressee 邮件的收件人
*/
public static void openGui(Player player,String addressee){ public static void openGui(Player player,String addressee){
// 创建一个45格的背包界面标题包含收件人的名字
Inventory inv = Bukkit.createInventory(null,45,invTitle+addressee); Inventory inv = Bukkit.createInventory(null,45,invTitle+addressee);
// 获取玩家管理器实例
PlayerManager playerManager = MailMain.getPlayerManager(); PlayerManager playerManager = MailMain.getPlayerManager();
// 根据收件人名字获取其玩家数据
PlayerData playerData = playerManager.getPlayerData(addressee); PlayerData playerData = playerManager.getPlayerData(addressee);
// 获取收件人存储的物品哈希映射包含物品和其对应的唯一键值
HashMap<Long, ItemStack> stackHashMap = playerData.getStackHashMap(); HashMap<Long, ItemStack> stackHashMap = playerData.getStackHashMap();
// 如果哈希映射不为空则遍历所有物品并设置每个物品的NBT数据然后添加到界面中
if(!stackHashMap.isEmpty()){ if(!stackHashMap.isEmpty()){
for (Long key : stackHashMap.keySet()){ for (Long key : stackHashMap.keySet()){
ItemStack itemStack = stackHashMap.get(key); ItemStack itemStack = stackHashMap.get(key);
@ -42,43 +54,67 @@ public class ToMailGui implements Listener {
inv.addItem(nbtItem.getItem()); inv.addItem(nbtItem.getItem());
} }
} }
// 在界面的底部填充玻璃物品作为界面的一部分起装饰作用
for (int i=36;i<45;i++){ for (int i=36;i<45;i++){
inv.setItem(i, DemonAPI.glass(15,"§7[§a■□■§7]")); inv.setItem(i, DemonAPI.glass(15,"§7[§a■□■§7]"));
} }
// 创建一个雪球物品用于确认发货操作并设置其显示名称和NBT数据
ItemStack stack = new ItemStack(Material.SNOW_BALL); ItemStack stack = new ItemStack(Material.SNOW_BALL);
ItemMeta meta = stack.getItemMeta(); ItemMeta meta = stack.getItemMeta();
meta.setDisplayName("§6§l确认发货"); meta.setDisplayName("§6§l确认发货");
stack.setItemMeta(meta); stack.setItemMeta(meta);
NbtItem nbtItem = new NbtItem(stack); NbtItem nbtItem = new NbtItem(stack);
nbtItem.setString("addressee",addressee); nbtItem.setString("addressee",addressee);
// 将确认发货的雪球物品放置在界面的特定位置
inv.setItem(40,nbtItem.getItem()); inv.setItem(40,nbtItem.getItem());
// 打开界面供玩家进行操作
player.openInventory(inv); player.openInventory(inv);
} }
/**
* 处理玩家点击背包事件的函数
* 该函数主要目的是在特定的背包界面中处理玩家点击特定位置时的操作
*
* @param e 玩家点击背包事件对象包含事件相关数据如点击位置背包信息等
*/
@EventHandler @EventHandler
public void onClick(InventoryClickEvent e){ public void onClick(InventoryClickEvent e){
// 获取玩家点击的原始槽位
int rawSlot = e.getRawSlot(); int rawSlot = e.getRawSlot();
// 获取点击背包的玩家并转换为Player对象
Player player = (Player) e.getWhoClicked(); Player player = (Player) e.getWhoClicked();
// 获取玩家名称
String playerName = player.getName(); String playerName = player.getName();
// 获取被点击的背包
Inventory inv = e.getInventory(); Inventory inv = e.getInventory();
// 检查背包标题是否包含特定的标题以确定是否是目标背包界面
if(e.getView().getTitle().contains(invTitle)){ if(e.getView().getTitle().contains(invTitle)){
// 当点击位置在特定范围内时执行以下操作
if(rawSlot >= 36 && rawSlot <= 44) { if(rawSlot >= 36 && rawSlot <= 44) {
// 取消默认的点击事件
e.setCancelled(true); e.setCancelled(true);
// 如果点击的位置是特定位置则执行邮件发送操作
if(rawSlot == 40){ if(rawSlot == 40){
// 使用NBT库获取当前物品的特定标签值
NbtItem nbtItem = new NbtItem(e.getCurrentItem()); NbtItem nbtItem = new NbtItem(e.getCurrentItem());
String addressee = nbtItem.getString("addressee"); String addressee = nbtItem.getString("addressee");
// 获取玩家管理器和目标玩家的数据
PlayerManager playerManager = MailMain.getPlayerManager(); PlayerManager playerManager = MailMain.getPlayerManager();
PlayerData playerData = playerManager.getPlayerData(addressee); PlayerData playerData = playerManager.getPlayerData(addressee);
// 重置目标玩家的邮件数据
playerData.resetMailData(); playerData.resetMailData();
// 创建一个缓存背包用于临时存储物品
Inventory cacheInv = Bukkit.createInventory(null, 27, "这是一个缓存虚拟器"); Inventory cacheInv = Bukkit.createInventory(null, 27, "这是一个缓存虚拟器");
// 将当前背包中的物品转移到缓存背包中
for (int i = 0; i < 36; i++) { for (int i = 0; i < 36; i++) {
ItemStack item = inv.getItem(i); ItemStack item = inv.getItem(i);
if (!DemonAPI.itemIsNull(item)) { if (!DemonAPI.itemIsNull(item)) {
cacheInv.addItem(item); cacheInv.addItem(item);
} }
} }
// 初始化物品数量计数器
int amount = 0; int amount = 0;
// 遍历缓存背包中的物品执行发送邮件的操作
for (int slot = 0; slot < 27; slot++){ for (int slot = 0; slot < 27; slot++){
ItemStack stack = cacheInv.getItem(slot); ItemStack stack = cacheInv.getItem(slot);
if (!DemonAPI.itemIsNull(stack)) { if (!DemonAPI.itemIsNull(stack)) {
@ -86,6 +122,7 @@ public class ToMailGui implements Listener {
amount += stack.getAmount(); amount += stack.getAmount();
} }
} }
// 根据发送的物品数量给予玩家反馈
if(amount >= 1) { if(amount >= 1) {
playerData.saveMailStack(); playerData.saveMailStack();
player.closeInventory(); player.closeInventory();

View File

@ -20,23 +20,47 @@ public class PlayerListener implements Listener {
plugin.getServer().getPluginManager().registerEvents(this,plugin); plugin.getServer().getPluginManager().registerEvents(this,plugin);
} }
/**
* 当玩家更换世界时触发的事件处理方法
* 此方法检查玩家是否有未读邮件并在有未读邮件时提醒玩家
*
* @param e 玩家更换世界事件对象包含事件相关信息
*/
@EventHandler @EventHandler
public void onjoin(PlayerChangedWorldEvent e){ public void onjoin(PlayerChangedWorldEvent e){
// 获取事件涉及的玩家对象
Player p = e.getPlayer(); Player p = e.getPlayer();
// 获取玩家的名称
String playerName = p.getName(); String playerName = p.getName();
// 获取玩家数据管理器实例
PlayerManager playerManager = MailMain.getPlayerManager(); PlayerManager playerManager = MailMain.getPlayerManager();
// 根据玩家名称获取玩家数据对象
PlayerData playerData = playerManager.getPlayerData(playerName); PlayerData playerData = playerManager.getPlayerData(playerName);
// 获取玩家未读邮件的数量
int amountMail = playerData.getMailAmount(); int amountMail = playerData.getMailAmount();
// 如果玩家有未读邮件调用OpenMail方法发送提示信息
if(amountMail >= 1){ if(amountMail >= 1){
OpenMail(p, LangUtil.notice_player.replace("{amount}",String.valueOf(amountMail))); OpenMail(p, LangUtil.notice_player.replace("{amount}",String.valueOf(amountMail)));
} }
} }
/**
* 发送带有点击事件的邮件提示信息给指定玩家
* 此方法构造一个TextComponent对象包含邮件提示信息和点击事件发送给玩家
*
* @param player 接收提示信息的玩家对象
* @param message 提示信息文本
*/
public static void OpenMail (Player player,String message) { public static void OpenMail (Player player,String message) {
// 创建文本组件对象用于显示提示信息
TextComponent Click = new TextComponent(message); TextComponent Click = new TextComponent(message);
// 设置文本组件的悬停事件当鼠标悬停时显示特定文本
Click.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("§e点击打开邮箱").create())); Click.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("§e点击打开邮箱").create()));
// 设置文本组件的点击事件当点击文本时执行特定命令
Click.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/dpmail open")); Click.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/dpmail open"));
// 发送带有事件的提示信息给指定玩家
player.spigot().sendMessage(Click); player.spigot().sendMessage(Click);
} }
} }

View File

@ -7,30 +7,57 @@ import org.bukkit.entity.Player;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/**
* 玩家管理器类用于管理所有玩家的数据
*/
public class PlayerManager { public class PlayerManager {
// 存储所有玩家数据的映射表键为玩家名称值为玩家数据对象
private Map<String, PlayerData> playerDataMap = new HashMap<>(); private Map<String, PlayerData> playerDataMap = new HashMap<>();
/**
* 构造函数初始化在线玩家数据
*/
public PlayerManager(){ public PlayerManager(){
// 遍历当前所有在线玩家
for (Player player : Bukkit.getOnlinePlayers()){ for (Player player : Bukkit.getOnlinePlayers()){
// 仅处理等级达到50级以上的玩家
if(player.getLevel() >= 50){ if(player.getLevel() >= 50){
// 获取玩家名称
String playerName = player.getName(); String playerName = player.getName();
// 创建玩家数据对象
PlayerData playerData = new PlayerData(playerName); PlayerData playerData = new PlayerData(playerName);
// 将玩家数据添加到映射表中
playerDataMap.put(playerName, playerData); playerDataMap.put(playerName, playerData);
} }
} }
} }
/**
* 获取玩家数据如果玩家数据不存在则创建新的玩家数据对象
*
* @param playerName 玩家名称
* @return 玩家数据对象
*/
public PlayerData getPlayerData(String playerName){ public PlayerData getPlayerData(String playerName){
// 检查映射表中是否存在指定玩家的数据
if(!playerDataMap.containsKey(playerName)) { if(!playerDataMap.containsKey(playerName)) {
// 如果不存在创建新的玩家数据对象
PlayerData playerData = new PlayerData(playerName); PlayerData playerData = new PlayerData(playerName);
// 将新的玩家数据对象添加到映射表中
playerDataMap.put(playerName, playerData); playerDataMap.put(playerName, playerData);
} }
// 返回玩家数据对象
return playerDataMap.get(playerName); return playerDataMap.get(playerName);
} }
/**
* 保存所有玩家的数据
*/
public void saveAllPlayerData(){ public void saveAllPlayerData(){
// 遍历所有玩家数据
for (PlayerData playerData : playerDataMap.values()){ for (PlayerData playerData : playerDataMap.values()){
// 保存每个玩家的邮件栈数据
playerData.saveMailStack(); playerData.saveMailStack();
} }
} }