33批二十四次修正:restoreInventory从DB备份恢复背包前先拆超大打包箱(修登录自愈被DB备份炸弹覆盖照样被踢)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
// ==================== 内部工具 ====================
|
||||
|
||||
@@ -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]);
|
||||
|
||||
Reference in New Issue
Block a user