优化吞噬盘性能

This commit is contained in:
GaLi 2026-04-17 18:25:01 +08:00
parent c23893b926
commit edb452eb38
3 changed files with 206 additions and 253 deletions

View File

@ -10,7 +10,6 @@ import appeng.api.storage.cells.CellState;
import appeng.api.storage.cells.ISaveProvider;
import appeng.api.storage.cells.StorageCell;
import appeng.api.upgrades.IUpgradeInventory;
import appeng.core.AELog;
import appeng.core.definitions.AEItems;
import appeng.util.ConfigInventory;
import appeng.util.prioritylist.IPartitionList;
@ -19,10 +18,9 @@ import com.extendedae_plus.util.storage.InfinityConstants;
import com.extendedae_plus.util.storage.InfinityDataStorage;
import com.extendedae_plus.util.storage.InfinityStorageManager;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.CustomData;
@ -48,29 +46,22 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
private final ISaveProvider container;
private final IPartitionList partitionList;
private final IncludeExclude partitionListMode;
// 存储物品键和数量的映射
private Object2ObjectMap<AEKey, BigInteger> AEKey2AmountsMap;
// 存储的物品种类数量
private int totalAEKeyType;
// 存储的物品总数
private BigInteger totalAEKey2Amounts = BigInteger.ZERO;
// 标记是否已持久化到 SavedData
// 仅用于控制 ItemStack 摘要字段是否需要刷新
private boolean isPersisted = true;
private InfinityBigIntegerCellInventory(InfinityBigIntegerCellItem cell,
ItemStack stack,
ISaveProvider saveProvider,
@Nullable InfinityStorageManager storageManager) {
// 保存存储单元类型InfinityBigIntegerCellItem 实例用于访问磁盘属性
this.cell = cell;
// 保存物品堆栈表示磁盘本身包含运行时的 NBT 数据
this.self = stack;
// 保存提供者用于触发数据保存
this.container = saveProvider;
// 初始化 storedAmounts null延迟加载物品数据
this.AEKey2AmountsMap = null;
this.storageManager = storageManager;
var builder = IPartitionList.builder();
var upgrades = this.getUpgradesInventory();
var config = this.getConfigInventory();
@ -82,13 +73,11 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
builder.addAll(config.keySet());
this.partitionListMode = hasInverter ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST;
this.partitionList = builder.build();
// 初始化磁盘数据
this.initData();
}
// BigInteger 格式化为带单位的字符串保留两位小数
public static String formatBigInteger(BigInteger number) {
// 使用方法局部的 DecimalFormat避免静态共享的非线程安全问题
java.text.DecimalFormat df = new java.text.DecimalFormat("#.##");
BigDecimal bd = new BigDecimal(number);
BigDecimal thousand = new BigDecimal(1000);
@ -104,151 +93,151 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
return df.format(bd.doubleValue()) + units[idx];
}
// 静态方法创建存储单元库存
static InfinityBigIntegerCellInventory createInventory(ItemStack stack,
ISaveProvider saveProvider,
@Nullable InfinityStorageManager storageManager) {
// 检查物品堆栈是否为空
Objects.requireNonNull(stack, "Cannot create cell inventory for null itemstack");
// 检查物品是否为 IDISKCellItem 类型
if (!(stack.getItem() instanceof InfinityBigIntegerCellItem cell)) {
return null;
}
// 创建并返回新的 DISKCellInventory 实例
return new InfinityBigIntegerCellInventory(cell, stack, saveProvider, storageManager);
}
// 获取磁盘的 InfinityDataStorage 数据
private InfinityDataStorage getCellStorage() {
// 如果磁盘有 UUID返回对应的 InfinityDataStorage
if (this.getUUID() != null && this.storageManager != null) {
return this.storageManager.getOrCreateCell(this.getUUID());
} else {
// 否则返回空的 InfinityDataStorage
return InfinityDataStorage.EMPTY;
@Nullable
private InfinityDataStorage getExistingCellStorage() {
UUID uuid = this.getUUID();
if (uuid == null || this.storageManager == null || !this.storageManager.hasUUID(uuid)) {
return null;
}
return this.storageManager.getOrCreateCell(uuid);
}
// 初始化磁盘数据
private void initData() {
// 如果磁盘有 UUID加载存储的物品数据
if (this.hasUUID()) {
this.totalAEKeyType = this.getCellStorage().amounts.size();
this.totalAEKey2Amounts = this.getCellStorage().itemCount.equals(BigInteger.ZERO) ?
BigInteger.ZERO :
this.getCellStorage().itemCount;
@Nullable
private InfinityDataStorage getWritableCellStorage() {
if (this.storageManager == null) {
return null;
}
UUID uuid = this.getUUID();
if (uuid == null) {
uuid = this.assignNewUUID();
}
return this.storageManager.getOrCreateCell(uuid);
}
private void initData() {
this.refreshCachedStateFromStorage();
}
private void refreshCachedStateFromStorage() {
var cellStorage = this.getExistingCellStorage();
if (cellStorage != null) {
this.totalAEKeyType = cellStorage.amounts.size();
this.totalAEKey2Amounts = cellStorage.itemCount == null ? BigInteger.ZERO : cellStorage.itemCount;
} else {
// 否则初始化为空
this.totalAEKeyType = 0;
this.totalAEKey2Amounts = BigInteger.ZERO;
// 加载物品数据
this.getCellStoredMap();
}
}
// 获取存储单元的状态部分填充
@Override
public CellState getStatus() {
// 如果没有存储任何物品返回空状态
this.refreshCachedStateFromStorage();
if (this.getTotalAEKey2Amounts().equals(BigInteger.ZERO)) {
return CellState.EMPTY;
}
// 否则返回满状态
return CellState.NOT_EMPTY;
}
// 获取存储单元的待机能耗
@Override
public double getIdleDrain() {
return 512;
}
// 持久化存储单元数据到全局存储
@Override
public void persist() {
if (this.isPersisted || this.storageManager == null)
return;
if (this.totalAEKey2Amounts.equals(BigInteger.ZERO)) {
if (this.hasUUID()) {
this.storageManager.removeCell(this.getUUID());
// DataComponents.CUSTOM_DATA 里移除对应字段
CustomData data = this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
CompoundTag tag = data.copyTag();
tag.remove(InfinityConstants.INFINITY_CELL_UUID);
tag.remove(InfinityConstants.INFINITY_ITEM_TOTAL);
tag.remove(InfinityConstants.INFINITY_ITEM_TYPES);
// backward compat
tag.remove(InfinityConstants.INFINITY_CELL_ITEM_COUNT);
this.self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
this.isPersisted = true;
this.initData();
}
this.refreshCachedStateFromStorage();
if (this.isPersisted) {
return;
}
// 创建物品键列表
ListTag keys = new ListTag();
// 创建物品数量列表
ListTag amounts = new ListTag();
// 初始化物品总数
BigInteger itemCount = BigInteger.ZERO;
for (var entry : this.AEKey2AmountsMap.object2ObjectEntrySet()) {
BigInteger amount = entry.getValue();
// 如果数量大于 0添加到键和数量列表
if (amount.compareTo(BigInteger.ZERO) > 0) {
keys.add(entry.getKey().toTagGeneric(this.storageManager.getRegistries()));
CompoundTag amountTag = new CompoundTag();
amountTag.putByteArray("value", amount.toByteArray());
amounts.add(amountTag);
itemCount = itemCount.add(amount);
}
}
if (keys.isEmpty()) {
this.storageManager.updateCell(this.getUUID(), new InfinityDataStorage());
} else {
this.storageManager.modifyDisk(this.getUUID(), keys, amounts, itemCount);
}
// 更新存储的物品种类数量
this.totalAEKeyType = this.AEKey2AmountsMap.size();
// 更新存储的物品总数
this.totalAEKey2Amounts = itemCount;
// 将物品总数与种类数量存入物品堆栈的 NBT用于快捷查看tooltip同时保留旧字段以兼容历史版本
// 写回 DataComponents.CUSTOM_DATA替代 getOrCreateTag
CompoundTag tag = this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
tag.putByteArray(InfinityConstants.INFINITY_ITEM_TOTAL, itemCount.toByteArray());
tag.putInt(InfinityConstants.INFINITY_ITEM_TYPES, this.totalAEKeyType);
tag.putByteArray(InfinityConstants.INFINITY_CELL_ITEM_COUNT, itemCount.toByteArray());
if (this.totalAEKey2Amounts.equals(BigInteger.ZERO)) {
tag.remove(InfinityConstants.INFINITY_ITEM_TOTAL);
tag.remove(InfinityConstants.INFINITY_ITEM_TYPES);
// backward compat
tag.remove(InfinityConstants.INFINITY_CELL_ITEM_COUNT);
} else {
byte[] itemCountBytes = this.totalAEKey2Amounts.toByteArray();
tag.putByteArray(InfinityConstants.INFINITY_ITEM_TOTAL, itemCountBytes);
tag.putInt(InfinityConstants.INFINITY_ITEM_TYPES, this.totalAEKeyType);
tag.putByteArray(InfinityConstants.INFINITY_CELL_ITEM_COUNT, itemCountBytes);
}
this.self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
// 标记数据已持久化
this.isPersisted = true;
}
private void clearCellData() {
UUID uuid = this.getUUID();
if (uuid != null && this.storageManager != null && this.storageManager.hasUUID(uuid)) {
this.storageManager.removeCell(uuid);
}
this.totalAEKeyType = 0;
this.totalAEKey2Amounts = BigInteger.ZERO;
CompoundTag tag = this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
tag.remove(InfinityConstants.INFINITY_CELL_UUID);
tag.remove(InfinityConstants.INFINITY_ITEM_TOTAL);
tag.remove(InfinityConstants.INFINITY_ITEM_TYPES);
// backward compat
tag.remove(InfinityConstants.INFINITY_CELL_ITEM_COUNT);
this.self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
this.isPersisted = true;
if (this.container != null) {
this.container.saveChanges();
}
}
private void saveChanges() {
this.isPersisted = false;
if (this.storageManager != null) {
this.storageManager.setDirty();
}
if (this.container != null) {
this.container.saveChanges();
} else {
this.persist();
}
}
private UUID assignNewUUID() {
CustomData data = this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
CompoundTag tag = data.copyTag();
UUID newUUID = UUID.randomUUID();
tag.putUUID(InfinityConstants.INFINITY_CELL_UUID, newUUID);
this.self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
return newUUID;
}
// 获取存储的物品总数
private BigInteger getTotalAEKey2Amounts() {
return this.totalAEKey2Amounts;
}
// 获取存储的物品种类数量
public int getTotalAEKeyType() {
this.refreshCachedStateFromStorage();
return this.totalAEKeyType;
}
// 判断物品堆栈是否有UUID
private boolean hasUUID() {
CustomData data = this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
return !data.isEmpty() && data.copyTag().contains(InfinityConstants.INFINITY_CELL_UUID);
}
// 获取物品堆栈的UUID
public UUID getUUID() {
CustomData data = this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
if (!data.isEmpty() && data.copyTag().contains(InfinityConstants.INFINITY_CELL_UUID)) {
@ -257,68 +246,12 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
return null;
}
// 获取或初始化存储映射
private Object2ObjectMap<AEKey, BigInteger> getCellStoredMap() {
if (this.AEKey2AmountsMap == null) {
this.AEKey2AmountsMap = new Object2ObjectOpenHashMap<>();
this.loadCellStoredMap();
}
return this.AEKey2AmountsMap;
}
// 从存储中加载物品映射
private void loadCellStoredMap() {
if (this.storageManager == null) {
return;
}
boolean dataCorruption = false;
if (this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).isEmpty()) return;
var keys = this.getCellStorage().keys;
var amounts = this.getCellStorage().amounts;
// 数据损坏
if (keys.size() != amounts.size()) {
AELog.warn("Loading storage cell with mismatched amounts/tags: %d != %d", amounts.size(), keys.size());
}
var registries = this.storageManager.getRegistries();
// 遍历数量和键加载到 AEKey2AmountsMap
for (int i = 0; i < amounts.size(); i++) {
AEKey key = AEKey.fromTagGeneric(registries,keys.getCompound(i));
BigInteger amount = new BigInteger(amounts.getCompound(i).getByteArray("value"));
// 检查数据是否损坏
if (amount.compareTo(BigInteger.ZERO) <= 0 || key == null) {
dataCorruption = true;
} else {
this.AEKey2AmountsMap.put(key, amount);
}
}
if (dataCorruption) {
this.saveChanges();
}
}
// 标记数据需要保存并通知容器或直接持久化
private void saveChanges() {
// 更新存储的物品种类数量
this.totalAEKeyType = this.AEKey2AmountsMap.size();
// 重置物品总数
this.totalAEKey2Amounts = BigInteger.ZERO;
// 计算物品总数
for (BigInteger AEKey2Amounts : this.AEKey2AmountsMap.values()) {
this.totalAEKey2Amounts = this.totalAEKey2Amounts.add(AEKey2Amounts);
}
// 标记数据未持久化
this.isPersisted = false;
// 如果有保存提供者通知保存
if (this.container != null) {
this.container.saveChanges();
} else {
// 否则立即持久化
this.persist();
var cellStorage = this.getExistingCellStorage();
if (cellStorage == null) {
return Object2ObjectMaps.emptyMap();
}
return cellStorage.amounts;
}
private ConfigInventory getConfigInventory() {
@ -333,99 +266,98 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
return this.cell.getFuzzyMode(this.self);
}
// 插入物品到存储单元
@Override
public long insert(AEKey what, long amount, Actionable mode, IActionSource source) {
// 数量为0或类型不匹配直接返回
if (amount == 0) {
return 0;
}
if (this.storageManager == null) {
return 0;
}
if (!this.partitionList.matchesFilter(what, this.partitionListMode)) {
return 0;
}
// 不允许存储无限单元自身
if (what instanceof AEItemKey itemKey &&
itemKey.getItem() instanceof InfinityBigIntegerCellItem &&
itemKey.get(DataComponents.CUSTOM_DATA) != null
) {
itemKey.get(DataComponents.CUSTOM_DATA) != null) {
return 0;
}
// 如果没有 UUID且服务器端存储管理器已就绪则生成 UUID 并初始化存储
if (this.storageManager != null && !this.hasUUID()) {
// 取出自定义 NBT如果没有就返回空
CustomData data = this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
CompoundTag tag = data.copyTag();
// 生成新的 UUID 并写入
UUID newUUID = UUID.randomUUID();
tag.putUUID(InfinityConstants.INFINITY_CELL_UUID, newUUID);
// 回写到 ItemStack
this.self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
// 初始化存储
this.storageManager.getOrCreateCell(newUUID);
// 加载已存储的映射
this.loadCellStoredMap();
var cellStorage = this.getWritableCellStorage();
if (cellStorage == null) {
return 0;
}
// 获取当前物品数量
BigInteger currentAmount = this.getCellStoredMap().getOrDefault(what, BigInteger.ZERO);
BigInteger currentAmount = cellStorage.amounts.getOrDefault(what, BigInteger.ZERO);
if (mode == Actionable.MODULATE) {
// 实际插入更新数量并保存
BigInteger newAmount = currentAmount.add(BigInteger.valueOf(amount));
this.getCellStoredMap().put(what, newAmount);
BigInteger delta = BigInteger.valueOf(amount);
if (currentAmount.equals(BigInteger.ZERO)) {
this.totalAEKeyType++;
}
BigInteger newAmount = currentAmount.add(delta);
cellStorage.amounts.put(what, newAmount);
this.totalAEKey2Amounts = this.totalAEKey2Amounts.add(delta);
cellStorage.itemCount = this.totalAEKey2Amounts;
this.saveChanges();
}
return amount;
}
// 从存储单元提取物品
@Override
public long extract(AEKey what, long amount, Actionable mode, IActionSource source) {
BigInteger currentAmount = this.getCellStoredMap().getOrDefault(what, BigInteger.ZERO);
// 如果有物品可提取
if (currentAmount.compareTo(BigInteger.ZERO) > 0) {
BigInteger requested = BigInteger.valueOf(amount);
// 如果提取数量大于等于当前数量
if (requested.compareTo(currentAmount) >= 0) {
if (mode == Actionable.MODULATE) {
this.getCellStoredMap().remove(what);
this.saveChanges();
}
return currentAmount.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0 ? Long.MAX_VALUE : currentAmount.longValue();
} else {
// 提取部分数量
if (mode == Actionable.MODULATE) {
this.getCellStoredMap().put(what, currentAmount.subtract(requested));
this.saveChanges();
}
return requested.longValue();
}
if (this.storageManager == null) {
return 0;
}
return 0;
var cellStorage = this.getExistingCellStorage();
if (cellStorage == null) {
return 0;
}
BigInteger currentAmount = cellStorage.amounts.getOrDefault(what, BigInteger.ZERO);
if (currentAmount.compareTo(BigInteger.ZERO) <= 0) {
return 0;
}
BigInteger requested = BigInteger.valueOf(amount);
if (requested.compareTo(currentAmount) >= 0) {
if (mode == Actionable.MODULATE) {
cellStorage.amounts.remove(what);
this.totalAEKeyType--;
this.totalAEKey2Amounts = this.totalAEKey2Amounts.subtract(currentAmount);
cellStorage.itemCount = this.totalAEKey2Amounts;
if (cellStorage.amounts.isEmpty()) {
this.clearCellData();
} else {
this.saveChanges();
}
}
return currentAmount.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0 ? Long.MAX_VALUE : currentAmount.longValue();
}
if (mode == Actionable.MODULATE) {
BigInteger newAmount = currentAmount.subtract(requested);
cellStorage.amounts.put(what, newAmount);
this.totalAEKey2Amounts = this.totalAEKey2Amounts.subtract(requested);
cellStorage.itemCount = this.totalAEKey2Amounts;
this.saveChanges();
}
return requested.longValue();
}
// 获取所有可用的物品堆栈及其数量
@Override
public void getAvailableStacks(KeyCounter out) {
BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE);
if (this.getCellStoredMap() == null) return;
for (var entry : this.getCellStoredMap().object2ObjectEntrySet()) {
AEKey key = entry.getKey();
BigInteger value = entry.getValue();
// 获取 KeyCounter 中已有的值
long existing = out.get(key);
// 计算总和并限制到 Long.MAX_VALUE
BigInteger sum = BigInteger.valueOf(existing).add(value);
long toSet = sum.compareTo(maxLong) > 0 ? Long.MAX_VALUE : sum.longValue();
// 更新 KeyCounter
if (existing == Long.MAX_VALUE) {
continue;
}
@ -436,15 +368,13 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
}
}
// 获取存储单元的描述此处返回null可自定义
@Override
public Component getDescription() {
return this.self.getHoverName();
}
// 获取存储单元内所有物品的总数量格式化字符串
public String getTotalStorage() {
// 使用缓存的 totalStored避免每次全表扫描
this.refreshCachedStateFromStorage();
return formatBigInteger(this.totalAEKey2Amounts);
}
}

View File

@ -1,5 +1,10 @@
package com.extendedae_plus.util.storage;
import appeng.api.stacks.AEKey;
import appeng.core.AELog;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
@ -13,36 +18,66 @@ public class InfinityDataStorage {
// 定义一个静态常量 EMPTY表示一个空的 DataStorage 实例用于默认或占位场景
public static final InfinityDataStorage EMPTY = new InfinityDataStorage();
public ListTag keys;
public ListTag amounts;
// 运行时权威数据结构避免在高频路径上反复构造和拆解 NBT
public final Object2ObjectMap<AEKey, BigInteger> amounts;
// 存储磁盘中物品的总数使用 BigInteger 支持大容量
public BigInteger itemCount;
public InfinityDataStorage() {
this(new ListTag(), new ListTag(), BigInteger.ZERO);
this(new Object2ObjectOpenHashMap<>(), BigInteger.ZERO);
}
private InfinityDataStorage(ListTag keys, ListTag amounts, BigInteger itemCount) {
this.keys = keys;
private InfinityDataStorage(Object2ObjectMap<AEKey, BigInteger> amounts, BigInteger itemCount) {
this.amounts = amounts;
this.itemCount = itemCount;
}
// DataStorage 数据序列化为 NBT 格式
public CompoundTag serializeNBT() {
// DataStorage 数据序列化为 NBT 格式保持旧版字段结构兼容
public CompoundTag serializeNBT(HolderLookup.Provider registries) {
CompoundTag nbt = new CompoundTag();
ListTag keys = new ListTag();
ListTag amountsTag = new ListTag();
for (var entry : this.amounts.object2ObjectEntrySet()) {
BigInteger amount = entry.getValue();
if (amount == null || amount.compareTo(BigInteger.ZERO) <= 0) {
continue;
}
keys.add(entry.getKey().toTagGeneric(registries));
CompoundTag amountTag = new CompoundTag();
amountTag.putByteArray("value", amount.toByteArray());
amountsTag.add(amountTag);
}
nbt.put(InfinityConstants.INFINITY_CELL_KEYS, keys);
nbt.put(InfinityConstants.INFINITY_CELL_AMOUNTS, amounts);
nbt.putByteArray(InfinityConstants.INFINITY_CELL_ITEM_COUNT, itemCount.toByteArray());
nbt.put(InfinityConstants.INFINITY_CELL_AMOUNTS, amountsTag);
nbt.putByteArray(InfinityConstants.INFINITY_CELL_ITEM_COUNT, this.itemCount.toByteArray());
return nbt;
}
// NBT 数据反序列化创建 DataStorage 实例
public static InfinityDataStorage loadFromNBT(CompoundTag nbt) {
// NBT 数据反序列化创建 DataStorage 实例兼容旧版列表式存档结构
public static InfinityDataStorage loadFromNBT(CompoundTag nbt, HolderLookup.Provider registries) {
ListTag keys = nbt.getList(InfinityConstants.INFINITY_CELL_KEYS, ListTag.TAG_COMPOUND);
ListTag amounts = nbt.getList(InfinityConstants.INFINITY_CELL_AMOUNTS, ListTag.TAG_COMPOUND);
BigInteger itemCount = new BigInteger(nbt.getByteArray(InfinityConstants.INFINITY_CELL_ITEM_COUNT));
// 使用加载的数据创建新的 DataStorage 实例
return new InfinityDataStorage(keys, amounts, itemCount);
if (keys.size() != amounts.size()) {
AELog.warn("Loading storage cell with mismatched amounts/tags: %d != %d", amounts.size(), keys.size());
}
Object2ObjectMap<AEKey, BigInteger> storedAmounts = new Object2ObjectOpenHashMap<>();
BigInteger computedItemCount = BigInteger.ZERO;
int limit = Math.min(keys.size(), amounts.size());
for (int i = 0; i < limit; i++) {
AEKey key = AEKey.fromTagGeneric(registries, keys.getCompound(i));
BigInteger amount = new BigInteger(amounts.getCompound(i).getByteArray("value"));
if (key == null || amount.compareTo(BigInteger.ZERO) <= 0) {
continue;
}
storedAmounts.put(key, amount);
computedItemCount = computedItemCount.add(amount);
}
return new InfinityDataStorage(storedAmounts, computedItemCount);
}
}

View File

@ -9,7 +9,6 @@ import net.minecraft.world.level.saveddata.SavedData;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.math.BigInteger;
import java.util.*;
/**
@ -55,7 +54,10 @@ public class InfinityStorageManager extends SavedData {
// 获取当前索引的 CompoundTag表示单个磁盘的数据
CompoundTag cell = cellList.getCompound(i);
// CompoundTag 中读取 UUID DataStorage 数据并存入 cells 映射
cells.put(cell.getUUID(InfinityConstants.INFINITY_CELL_UUID), InfinityDataStorage.loadFromNBT(cell.getCompound(InfinityConstants.INFINITY_CELL_DATA)));
cells.put(
cell.getUUID(InfinityConstants.INFINITY_CELL_UUID),
InfinityDataStorage.loadFromNBT(cell.getCompound(InfinityConstants.INFINITY_CELL_DATA), registries)
);
}
// 使用加载的 cells 数据创建新的 StorageManager 实例
return new InfinityStorageManager(cells);
@ -69,7 +71,7 @@ public class InfinityStorageManager extends SavedData {
for (Map.Entry<UUID, InfinityDataStorage> entry : cells.entrySet()) {
CompoundTag cell = new CompoundTag();
cell.putUUID(InfinityConstants.INFINITY_CELL_UUID, entry.getKey());
cell.put(InfinityConstants.INFINITY_CELL_DATA, entry.getValue().serializeNBT());
cell.put(InfinityConstants.INFINITY_CELL_DATA, entry.getValue().serializeNBT(provider));
cellList.add(cell);
}
nbt.put(InfinityConstants.INFINITY_CELL_LIST, cellList);
@ -113,20 +115,6 @@ public class InfinityStorageManager extends SavedData {
return cells.get(uuid);
}
// 修改指定 UUID 的磁盘数据包括堆栈键数量和总项目数
public void modifyDisk(UUID uuid, ListTag keys, ListTag amounts, BigInteger itemCount) {
// 获取或创建指定 UUID DataStorage 对象
InfinityDataStorage cellToModify = getOrCreateCell(uuid);
if (keys != null && amounts != null) {
cellToModify.keys = keys;
cellToModify.amounts = amounts;
}
// 更新 DataStorage itemCount 字段
cellToModify.itemCount = itemCount;
// 将修改后的 DataStorage 对象更新到 cells 映射
updateCell(uuid, cellToModify);
}
public static InfinityStorageManager getInstance(MinecraftServer server) {
ServerLevel world = server.getLevel(ServerLevel.OVERWORLD);