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 {
/**
* 玩家数据类用于管理玩家的邮件数据
*/
private File file;
private FileConfiguration config;
/**
* 玩家名称用于标识和加载玩家数据
*/
private String playerName;
/**
* 存储邮件的HashMap键为邮件过期时间值为邮件物品堆
*/
private HashMap<Long, ItemStack> 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<Long, ItemStack> 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);
}

View File

@ -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<Long, ItemStack> 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);
}

View File

@ -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<Long, ItemStack> 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();

View File

@ -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);
}
}

View File

@ -7,30 +7,57 @@ import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
/**
* 玩家管理器类用于管理所有玩家的数据
*/
public class PlayerManager {
// 存储所有玩家数据的映射表键为玩家名称值为玩家数据对象
private Map<String, PlayerData> 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();
}
}