修复PVP加入崩溃 + 合并小票潜影盒(兼容中文标签)

1. /pvp join 崩溃(NoSuchMethodError: WorldCreator.keepSpawnInMemory):
   运行时 Paper API 已移除 WorldCreator.keepSpawnInMemory(boolean),
   移除该 Creator 调用,改由 reapplyWorldRules 的 World.setKeepSpawnInMemory(false)
   (稳定方法)控制出生点区块不常驻,避免同步加载卡主线程,且不再抛 NoSuchMethodError。

2. 收银台不打包(塞背包)仍给小票潜影盒:
   PHP(api/shop.php)推送小票时 settlement 误传中文标签(塞背包(环保单)/潜影盒打包),
   导致 Java give_receipt_book 的 equals('backpack') 守卫不匹配而仍然单独发书。
   修复:PHP 改传原始代码($settlement);Java 守卫同时兼容原始代码与中文标签
   (含'潜影盒'/'背包'即拦截),双保险——两种结算模式均不再单独发放小票潜影盒
   (打包:小票已在商品盒内;不打包:跳过发书)。
This commit is contained in:
2026-07-08 17:34:04 +08:00
parent 8b03ff4dcb
commit dec41c7b67
2 changed files with 10 additions and 7 deletions
@@ -265,11 +265,10 @@ public class PVPArenaManager implements Listener {
creator.environment(World.Environment.NORMAL);
creator.type(WorldType.NORMAL);
creator.seed(seed);
// ★ 关键:不把出生点区块常驻内存。否则 Bukkit.createWorld 会同步加载出生点周边
// 区块(~10 区块半径),主线程被占用数秒 → Watchdog 卡死。设为 false 后 createWorld
// 仅初始化世界、不加载出生点区块(毫秒级);区块由 preGenerateSpawnChunks 异步预生成,
// 玩家传送时按需加载单个区块(极快),主线程全程不阻塞。
creator.keepSpawnInMemory(false);
// ★ 注意:运行时 Paper API 已移除 WorldCreator.keepSpawnInMemory(boolean)
// (NoSuchMethodError),故【不在 Creator 上设置】出生点常驻。
// 出生点区块是否常驻内存由 reapplyWorldRules 的 World.setKeepSpawnInMemory(false)
// 控制——设为 false 可避免 Bukkit.createWorld 强制同步加载出生点区块导致主线程卡死。
plugin.getLogger().info("[PVP] 新建随机世界名=" + pvpWorldName + ", 种子=" + seed + " (确保每次地形不同)");
// ★ 使用 Bukkit.createWorld() 而非 creator.createWorld():
+6 -2
View File
@@ -3970,12 +3970,16 @@ public class WebManager {
break;
}
// ★ 2026-07-08 合并发货修复:
// ★ 2026-07-08 合并发货修复(兼容原始代码/中文标签两种推送值):
// PHP 推送的 settlement 可能是原始代码(shulker/backpack),
// 也可能是中文标签(潜影盒打包 / 塞背包(环保单)),两种都需拦截。
// 打包(潜影盒)模式:小票已通过 handleBuyCart 的 addBookToShulker 塞入【商品潜影盒】内,
// 此处若再单独发放"小票潜影盒"会导致玩家拿到两个潜影盒(商品+小票 / 仅小票)。
// 不打包(塞背包)模式:按需求跳过发放小票书。
// 因此两种结算模式下都【不再单独发放小票潜影盒】,直接标记已处理避免反复拉取。
if ("shulker".equals(settlementMode) || "backpack".equals(settlementMode)) {
boolean isShulker = "shulker".equals(settlementMode) || settlementMode.contains("潜影盒");
boolean isBackpack = "backpack".equals(settlementMode) || settlementMode.contains("背包");
if (isShulker || isBackpack) {
plugin.getLogger().info("[小票书] 结算模式=" + settlementMode
+ ",小票已并入商品潜影盒(打包)或在背包模式跳过,不再单独发放小票潜影盒 (玩家=" + bookPlayer + ")");
applied = true;