33批二十四次修正:restoreInventory从DB备份恢复背包前先拆超大打包箱(修登录自愈被DB备份炸弹覆盖照样被踢)
Check Source / check (push) Successful in 3s
Auto Release / build (push) Successful in 2m7s
Simple Test / test (push) Successful in 1s
Test Env / test (push) Successful in 1s

This commit is contained in:
youpaishidifu
2026-10-18 19:48:52 +08:00
parent 4cff8236b6
commit e67015f7a3
2 changed files with 46 additions and 16 deletions
+25 -16
View File
@@ -718,9 +718,30 @@ public class ChestCarryManager implements Listener {
/** 扫描并拆分超大 PDC 打包箱(背包/盔甲/副手/末影箱全覆盖)。 */
private void healOversizedInventory(Inventory inv, Player p) {
if (inv == null) return;
boolean changed = false;
List<ItemStack> toAdd = new ArrayList<>();
ItemStack[] contents = inv.getContents();
boolean changed = healOversizedArray(contents, toAdd);
if (changed) {
plugin.getLogger().info("[箱子搬运][登录自愈] 玩家 " + p.getName()
+ " 超大打包箱已自愈 (补出 " + toAdd.size() + " 箱)");
inv.setContents(contents);
for (ItemStack add : toAdd) {
HashMap<Integer, ItemStack> rem = inv.addItem(add);
if (!rem.isEmpty()) {
rem.values().forEach(x -> p.getWorld().dropItemNaturally(p.getLocation(), x));
}
}
}
}
/** ★ 33批二十四次修正:就地拆分 ItemStack[] 里的超大 PDC 打包箱(55000 字符上限),
* 拆出的多余箱进 extrasOut。供登录自愈与 Main.restoreInventory(DB 背包备份恢复)
* 共用——19:33:39 实锤:登录自愈清掉背包炸弹后,restoreInventory 又从 DB
* inventory_backups 把 109280 字节超大箱 setContents 塞回背包,
* container_set_slot 编码失败照样被踢。 */
public boolean healOversizedArray(ItemStack[] contents, List<ItemStack> extrasOut) {
if (contents == null) return false;
boolean changed = false;
for (int i = 0; i < contents.length; i++) {
ItemStack item = contents[i];
if (item == null || item.getType().isAir()) continue;
@@ -741,28 +762,16 @@ public class ChestCarryManager implements Listener {
List<ItemStack> split = buildPackedChestsSplit(Material.CHEST, halfName, items, false);
if (!split.isEmpty()) {
contents[i] = split.get(0);
for (int k = 1; k < split.size(); k++) {
toAdd.add(split.get(k));
}
plugin.getLogger().info("[箱子搬运][登录自愈] 玩家 " + p.getName()
+ " 超大打包箱已拆分为 " + split.size() + " 箱 (原PDC " + data.length() + " 字符)");
extrasOut.addAll(split.subList(1, split.size()));
} else {
contents[i] = null;
}
} catch (Exception ex) {
contents[i] = null;
plugin.getLogger().warning("[箱子搬运][登录自愈] 移除无法解析的超大打包箱: " + ex.getMessage());
}
}
if (changed) {
inv.setContents(contents);
for (ItemStack add : toAdd) {
HashMap<Integer, ItemStack> rem = inv.addItem(add);
if (!rem.isEmpty()) {
rem.values().forEach(x -> p.getWorld().dropItemNaturally(p.getLocation(), x));
}
plugin.getLogger().warning("[箱子搬运][超大箱自愈] 移除无法解析的超大打包箱: " + ex.getMessage());
}
}
return changed;
}
// ==================== 内部工具 ====================
+21
View File
@@ -2195,9 +2195,16 @@ public class Main extends JavaPlugin
try {
if (b != null && isValidBackup(b)) {
debugPrintBase64("恢复前", name, b[0]);
// ★ 33批二十四次修正:DB 背包备份里也可能存着旧超大打包箱
//(19:33:39 实锤:登录自愈清掉背包炸弹后,这里又从 DB 塞回来
// → container_set_slot 编码失败照样被踢)。先拆分再 setContents。
List<ItemStack> healExtras = new ArrayList<>();
boolean healedAny = false;
ItemStack[] contents =
InventorySerializer
.fromBase64(b[0]);
if (contents != null && chestCarryManager != null)
healedAny |= chestCarryManager.healOversizedArray(contents, healExtras);
if (contents != null)
p.getInventory()
.setContents(contents);
@@ -2205,6 +2212,8 @@ public class Main extends JavaPlugin
ItemStack[] armor =
InventorySerializer
.fromBase64(b[1]);
if (armor != null && chestCarryManager != null)
healedAny |= chestCarryManager.healOversizedArray(armor, healExtras);
if (armor != null)
p.getInventory()
.setArmorContents(
@@ -2214,11 +2223,23 @@ public class Main extends JavaPlugin
ItemStack[] extra =
InventorySerializer
.fromBase64(b[2]);
if (extra != null && chestCarryManager != null)
healedAny |= chestCarryManager.healOversizedArray(extra, healExtras);
if (extra != null)
p.getInventory()
.setExtraContents(
extra);
}
for (ItemStack healAdd : healExtras) {
HashMap<Integer, ItemStack> remH =
p.getInventory().addItem(healAdd);
if (!remH.isEmpty())
remH.values().forEach(x ->
p.getWorld().dropItemNaturally(p.getLocation(), x));
}
if (healedAny)
getLogger().info("[Sdf1_login] " + name
+ " DB背包备份中的超大打包箱已拆分修复");
int lv = Integer.parseInt(b[3]);
if (lv > 0) p.setLevel(lv);
double xp = Double.parseDouble(b[4]);