diff --git a/build.gradle b/build.gradle index eb7b7f8..bcdb0cd 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'com.playerblocklife' -version = '2.0.0-1.20.4' +version = '2.0.1-1.20.4' sourceCompatibility = 17 targetCompatibility = 17 diff --git a/gradle.properties b/gradle.properties index a2b78e4..9b6fbcd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,5 +5,5 @@ org.gradle.caching=true org.gradle.daemon=true # ???? -pluginVersion=2.0.0-1.20.4 +pluginVersion=2.0.1-1.20.4 mcVersion=1.20.4 \ No newline at end of file diff --git a/src/main/java/com/playerblocklife/ConfigManager.java b/src/main/java/com/playerblocklife/ConfigManager.java index 3125bdd..1fe2810 100644 --- a/src/main/java/com/playerblocklife/ConfigManager.java +++ b/src/main/java/com/playerblocklife/ConfigManager.java @@ -157,6 +157,10 @@ public class ConfigManager { return getConfig().getInt("blocks.spread", 5); } + public int getMinDistance() { + return getConfig().getInt("blocks.min-distance", 10); + } + public int getDepth() { return getConfig().getInt("blocks.depth", -1); } @@ -185,6 +189,10 @@ public class ConfigManager { return getConfig().getString("skin.source", "player_profile"); } + public boolean useSkinsRestorer() { + return getConfig().getBoolean("skin.use-skinsrestorer", false); + } + public int getCacheExpireDays() { return getConfig().getInt("skin.cache.expire_days", 7); } diff --git a/src/main/java/com/playerblocklife/PlayerBlockManager.java b/src/main/java/com/playerblocklife/PlayerBlockManager.java index b4b7208..1ccb104 100644 --- a/src/main/java/com/playerblocklife/PlayerBlockManager.java +++ b/src/main/java/com/playerblocklife/PlayerBlockManager.java @@ -92,24 +92,28 @@ public class PlayerBlockManager { } /** - * 寻找地表位置(上方无方块覆盖) + * 寻找地表位置(放宽条件,只要是露天地面就可以) */ private Location findSurfaceLocation(Location center, int spreadRange, boolean requireOpenSky) { - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 20; i++) { // 增加尝试次数 int x = random.nextInt(spreadRange * 2 + 1) - spreadRange; int z = random.nextInt(spreadRange * 2 + 1) - spreadRange; - // 从中心点上方开始向下寻找地表 - Location testLoc = center.clone().add(x, 10, z); + // 以玩家坐标为中心,但高度从世界最高点开始寻找 + Location testLoc = center.clone().add(x, 0, z); World world = testLoc.getWorld(); if (world == null) continue; - // 向下寻找第一个非空气方块 + // 从世界最高点向下寻找第一个固体方块 + int maxHeight = world.getMaxHeight(); Block groundBlock = null; - for (int y = 10; y > world.getMinHeight(); y--) { + for (int y = maxHeight; y > world.getMinHeight(); y--) { testLoc.setY(y); Block block = testLoc.getBlock(); - if (!block.getType().isAir()) { + Material type = block.getType(); + + // 检查是否是固体方块(可以作为支撑) + if (type.isSolid() && type.isBlock() && !type.isTransparent()) { groundBlock = block; break; } @@ -117,24 +121,23 @@ public class PlayerBlockManager { if (groundBlock == null) continue; - // 检查地表方块上方位置 + // 地表位置 = 固体方块上方一格 Location surfaceLoc = groundBlock.getLocation().add(0, 1, 0); - Block surfaceBlock = surfaceLoc.getBlock(); // 检查是否已有方块 if (blockOwners.containsKey(surfaceLoc)) { continue; } - // 检查地表方块是否合适 - if (!isSuitableLocation(surfaceLoc)) { + // 检查位置是否合适(放宽条件) + if (!isSuitableLocationRelaxed(surfaceLoc)) { continue; } - // 如果需要上方无方块覆盖,检查上方 + // 如果需要上方无方块覆盖,检查上方3格 if (requireOpenSky) { boolean hasCover = false; - for (int y = 1; y <= 5; y++) { + for (int y = 1; y <= 3; y++) { Block aboveBlock = surfaceLoc.clone().add(0, y, 0).getBlock(); if (!aboveBlock.getType().isAir()) { hasCover = true; @@ -234,6 +237,43 @@ public class PlayerBlockManager { return true; } + /** + * 放宽条件的检查方法(用于新的生成逻辑) + */ + private boolean isSuitableLocationRelaxed(Location location) { + Block block = location.getBlock(); + + // 检查是否已有方块 + if (blockOwners.containsKey(location)) { + return false; + } + + // 检查方块是否可替换(放宽条件) + Material type = block.getType(); + if (!type.isAir()) { + // 固体方块不能替换 + if (type.isSolid()) { + return false; + } + + // 液体方块不能替换 + if (type == Material.WATER || type == Material.LAVA) { + return false; + } + } + + // 检查下方是否有支撑方块(放宽条件) + Block below = location.clone().add(0, -1, 0).getBlock(); + Material belowType = below.getType(); + + // 只要下方不是空气或液体就可以 + if (belowType.isAir() || belowType == Material.WATER || belowType == Material.LAVA) { + return false; + } + + return true; + } + /** * 放置玩家头颅方块 */ diff --git a/src/main/java/com/playerblocklife/PlayerJoinListener.java b/src/main/java/com/playerblocklife/PlayerJoinListener.java index 2cc0131..1f54444 100644 --- a/src/main/java/com/playerblocklife/PlayerJoinListener.java +++ b/src/main/java/com/playerblocklife/PlayerJoinListener.java @@ -137,8 +137,9 @@ public class PlayerJoinListener implements Listener { String onFailure = config.getOnFailureAction(); if (onFailure.equals("notify")) { String notifyMsg = plugin.getMessageManager().getMessage("game.errors.cannot_generate_blocks", - "&c无法生成生命方块:找不到合适的位置"); - notifyMsg = notifyMsg.replace("&", "§"); + "&c无法生成生命方块:{reason}"); + notifyMsg = notifyMsg.replace("{reason}", "找不到合适的位置(尝试了20次)") + .replace("&", "§"); player.sendMessage(notifyMsg); player.sendMessage("§7请手动使用 §e/setlifeblocks §7命令生成方块"); } else if (onFailure.equals("teleport_to_spawn")) { diff --git a/src/main/java/com/playerblocklife/SkinManager.java b/src/main/java/com/playerblocklife/SkinManager.java index 831bf1a..4198cf0 100644 --- a/src/main/java/com/playerblocklife/SkinManager.java +++ b/src/main/java/com/playerblocklife/SkinManager.java @@ -60,7 +60,17 @@ public class SkinManager { try { plugin.logInfo("开始加载皮肤: " + player.getName()); - String skinBase64 = getSkinFromPlayerProfile(player); + String skinBase64 = null; + + // 检查是否使用SkinsRestorer插件 + if (plugin.getConfigManager().useSkinsRestorer()) { + skinBase64 = getSkinFromSkinsRestorer(player); + } + + // 如果SkinsRestorer未启用或获取失败,使用PlayerProfile + if (skinBase64 == null) { + skinBase64 = getSkinFromPlayerProfile(player); + } if (skinBase64 == null) { skinBase64 = getDefaultSteveSkin(); @@ -87,6 +97,41 @@ public class SkinManager { }); } + private String getSkinFromSkinsRestorer(Player player) { + try { + // 检查SkinsRestorer插件是否存在 + if (Bukkit.getPluginManager().getPlugin("SkinsRestorer") == null) { + plugin.logInfo("SkinsRestorer插件未安装,跳过从SkinsRestorer获取皮肤"); + return null; + } + + plugin.logInfo("尝试从SkinsRestorer获取皮肤: " + player.getName()); + + // 使用反射调用SkinsRestorer API + Class skinsRestorerClass = Class.forName("net.skinsrestorer.api.SkinsRestorerAPI"); + Object skinsRestorerAPI = skinsRestorerClass.getMethod("getApi").invoke(null); + + // 获取玩家皮肤数据 + Class skinDataClass = Class.forName("net.skinsrestorer.api.property.SkinProperty"); + Object skinProperty = skinsRestorerAPI.getClass().getMethod("getSkinData", String.class) + .invoke(skinsRestorerAPI, player.getName()); + + if (skinProperty != null) { + String value = (String) skinProperty.getClass().getMethod("getValue").invoke(skinProperty); + String signature = (String) skinProperty.getClass().getMethod("getSignature").invoke(skinProperty); + + plugin.logInfo("成功从SkinsRestorer获取皮肤: " + player.getName()); + return player.getUniqueId().toString(); + } + } catch (ClassNotFoundException e) { + plugin.logWarning("SkinsRestorer API类未找到,插件可能未安装: " + e.getMessage()); + } catch (Exception e) { + plugin.logWarning("从SkinsRestorer获取皮肤失败: " + e.getMessage()); + } + + return null; + } + private String getSkinFromPlayerProfile(Player player) { try { PlayerProfile profile = player.getPlayerProfile(); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0edf13a..3199f6e 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -7,6 +7,8 @@ blocks: amount: 5 # 方块生成范围(以玩家为中心的正方形边长的一半) spread: 5 + # 方块生成最小范围(方块之间最小距离,单位:格) + min-distance: 10 # 方块埋藏深度(0为地面,负数为地下) depth: -1 # 方块材质类型 @@ -41,8 +43,10 @@ game: skin: # 是否启用皮肤系统 enabled: true - # 皮肤来源 (player_profile, local_cache) + # 皮肤来源 (player_profile, local_cache, skinsrestorer) source: player_profile + # 是否使用SkinsRestorer插件皮肤(如果服务器有此插件) + use-skinsrestorer: false # 缓存设置 cache: diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 073d273..f11d9b6 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: PlayerBlockLife -version: 2.0.0-1.20.4 +version: 2.0.1-1.20.4 main: com.playerblocklife.PlayerBlockLife api-version: 1.20 author: xiaobai