完善注释(添加文档注释),添加skinsrestorer皮肤加载支持功能(未经完整测试)

This commit is contained in:
xiaobai
2026-02-14 19:56:16 +08:00
parent b268a74eeb
commit 8c68028924
9 changed files with 540 additions and 59 deletions

View File

@@ -18,6 +18,34 @@ import java.io.FileWriter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* 玩家方块管理器 - 负责管理玩家生命方块的核心组件
*
* <p>主要职责:
* <ul>
* <li>生成和放置玩家生命方块</li>
* <li>管理方块位置和所有者映射关系</li>
* <li>处理方块破坏和恢复逻辑</li>
* <li>提供方块数据持久化存储</li>
* <li>支持方块位置查询和验证</li>
* <li>与SkinManager协同工作确保方块正确显示玩家皮肤</li>
* </ul>
*
* <p><b>SkinsRestorer集成特性</b>
* <ul>
* <li>通过SkinManager获取SkinsRestorer提供的玩家皮肤纹理</li>
* <li>确保离线服务器上的方块显示正确的自定义皮肤</li>
* <li>支持异步皮肤加载,避免方块放置阻塞</li>
* <li>提供皮肤加载状态检查,确保皮肤就绪后再放置方块</li>
* </ul>
* </p>
*
* <p>使用并发安全的数据结构确保多线程环境下的数据一致性。</p>
*
* @author xiaobai
* @version 2.1.0
* @since 1.0.0
*/
public class PlayerBlockManager {
private final PlayerBlockLife plugin;
private final SkinManager skinManager;
@@ -47,7 +75,36 @@ public class PlayerBlockManager {
}
/**
* 为玩家生成生命方块(新方法,支持自动生成)
* 为玩家生成指定数量的生命方块
*
* <p>此方法负责生成玩家的生命方块,包括以下步骤:
* <ol>
* <li>检查玩家是否已有生命方块</li>
* <li>验证玩家皮肤是否已从SkinsRestorer或其他来源加载完成</li>
* <li>在指定范围内寻找合适的放置位置</li>
* <li>放置带有玩家皮肤纹理的玩家头颅方块</li>
* <li>记录方块位置和所有者关系</li>
* <li>保存数据并返回生成结果</li>
* </ol>
* </p>
*
* <p><b>皮肤加载检查:</b>
* <ul>
* <li>调用skinManager.isSkinLoaded()检查皮肤是否就绪</li>
* <li>如果皮肤未加载,方块生成将失败</li>
* <li>确保离线服务器通过SkinsRestorer获取的皮肤能正确应用</li>
* <li>避免放置默认Steve皮肤的方块</li>
* </ul>
* </p>
*
* @param player 目标玩家
* @param blockAmount 要生成的方块数量
* @param spreadRange 生成范围(以玩家为中心的正方形边长的一半)
* @param requireOpenSky 是否需要开阔天空(上方无方块覆盖)
* @param maxAttempts 寻找合适位置的最大尝试次数
* @return 生成成功返回true失败返回false
* @see SkinManager#isSkinLoaded(UUID)
* @see SkinManager#getSkinFromSkinsRestorer(Player)
*/
public boolean generateLifeBlocksForPlayer(Player player, int blockAmount, int spreadRange, boolean requireOpenSky, int maxAttempts) {
UUID playerId = player.getUniqueId();
@@ -276,6 +333,13 @@ public class PlayerBlockManager {
/**
* 放置玩家头颅方块
*
* <p>使用SkinManager创建带有正确皮肤的玩家头颅方块支持离线服务器皮肤显示。</p>
*
* @param location 放置位置
* @param playerId 玩家UUID
* @param playerName 玩家名称
* @return 放置成功返回true失败返回false
*/
private boolean placePlayerHead(Location location, UUID playerId, String playerName) {
try {
@@ -286,15 +350,37 @@ public class PlayerBlockManager {
return false;
}
// 检查玩家皮肤是否已加载
if (!skinManager.isSkinLoaded(playerId)) {
plugin.logWarning("玩家 " + playerName + " 的皮肤未加载,无法放置头颅方块");
return false;
}
// 设置方块为玩家头颅
block.setType(Material.PLAYER_HEAD);
// 获取并设置头颅数据
Skull skullState = (Skull) block.getState();
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerId);
// 设置头颅所有者
skullState.setOwningPlayer(offlinePlayer);
// 使用SkinManager创建玩家头颅物品然后应用到方块上
ItemStack headItem = skinManager.createPlayerHead(playerId, playerName);
SkullMeta itemMeta = (SkullMeta) headItem.getItemMeta();
if (itemMeta != null) {
// 获取物品的玩家档案并应用到方块上
org.bukkit.profile.PlayerProfile profile = itemMeta.getPlayerProfile();
if (profile != null) {
skullState.setOwnerProfile(profile);
} else {
// 如果无法获取档案,回退到使用离线玩家
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerId);
skullState.setOwningPlayer(offlinePlayer);
}
} else {
// 如果物品元数据为空,使用离线玩家
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerId);
skullState.setOwningPlayer(offlinePlayer);
}
// 设置朝向(随机方向)
BlockData blockData = block.getBlockData();
@@ -308,6 +394,7 @@ public class PlayerBlockManager {
// 更新方块
skullState.update(true, false);
plugin.logInfo("成功放置玩家头颅方块: " + playerName + "" + location);
return true;
} catch (Exception e) {
plugin.logError("放置玩家头颅失败: " + location, e);