diff --git a/src/main/java/com/extendedae_plus/ExtendedAEPlus.java b/src/main/java/com/extendedae_plus/ExtendedAEPlus.java
index 5a6277c..6670527 100644
--- a/src/main/java/com/extendedae_plus/ExtendedAEPlus.java
+++ b/src/main/java/com/extendedae_plus/ExtendedAEPlus.java
@@ -1,18 +1,13 @@
package com.extendedae_plus;
-import appeng.api.storage.StorageCells;
import appeng.block.AEBaseEntityBlock;
import appeng.blockentity.crafting.CraftingBlockEntity;
-import com.extendedae_plus.ae.api.storage.InfinityBigIntegerCellHandler;
-import com.extendedae_plus.ae.api.storage.InfinityBigIntegerCellInventory;
import com.extendedae_plus.config.ModConfigs;
import com.extendedae_plus.init.*;
import com.extendedae_plus.network.ModNetwork;
-import com.extendedae_plus.util.storage.InfinityStorageManager;
import com.mojang.logging.LogUtils;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
-import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.Blocks;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.bus.api.SubscribeEvent;
@@ -21,7 +16,6 @@ import net.neoforged.fml.common.Mod;
import net.neoforged.fml.config.ModConfig;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.neoforge.common.NeoForge;
-import net.neoforged.neoforge.event.level.LevelEvent;
import net.neoforged.neoforge.event.server.ServerStartingEvent;
import org.slf4j.Logger;
@@ -56,10 +50,6 @@ public class ExtendedAEPlus {
// Note that this is necessary if and only if we want *this* class (ExtendedAEPlus) to respond directly to events.
// Do not add this line if there are no @SubscribeEvent-annotated functions in this class, like onServerStarting() below.
NeoForge.EVENT_BUS.register(this);
- NeoForge.EVENT_BUS.addListener(ExtendedAEPlus::onLevelLoad);
-
- NeoForge.EVENT_BUS.addListener(InfinityBigIntegerCellInventory::onServerTick);
- NeoForge.EVENT_BUS.addListener(InfinityBigIntegerCellInventory::onServerStopping);
// 注册配置:接入自定义的 ModConfigs
modContainer.registerConfig(ModConfig.Type.COMMON, ModConfigs.COMMON_SPEC);
@@ -75,7 +65,7 @@ public class ExtendedAEPlus {
LOGGER.info("HELLO FROM COMMON SETUP");
// 示例日志,避免引用不存在的模板 Config 字段
LOGGER.info("DIRT BLOCK >> {}", BuiltInRegistries.BLOCK.getKey(Blocks.DIRT));
- StorageCells.addCellHandler(InfinityBigIntegerCellHandler.INSTANCE);
+
// 绑定 AE2 的 CraftingBlockEntity 到本模组的自定义加速器方块,避免 AEBaseEntityBlock.blockEntityType 为空
event.enqueueWork(() -> {
try {
@@ -120,13 +110,5 @@ public class ExtendedAEPlus {
// Do something when the server starts
LOGGER.info("HELLO from server starting");
}
-
-
- // 在世界加载时注册/加载 SavedData
- private static void onLevelLoad(LevelEvent.Load event) {
- if (event.getLevel() instanceof ServerLevel serverLevel) {
- InfinityStorageManager.getForLevel(serverLevel);
- }
- }
}
diff --git a/src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellHandler.java b/src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellHandler.java
deleted file mode 100644
index bc7c29c..0000000
--- a/src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellHandler.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.extendedae_plus.ae.api.storage;
-
-import appeng.api.storage.cells.ICellHandler;
-import appeng.api.storage.cells.ISaveProvider;
-import com.extendedae_plus.ae.items.InfinityBigIntegerCellItem;
-import net.minecraft.world.item.ItemStack;
-
-/**
- * InfinityBigIntegerCellHandler
- *
- * 该类实现 AE2 的 ICellHandler,用于:
- * - 判定某个 ItemStack 是否为本 mod 的 Infinity 存储单元
- * - 在 AE2 请求访问或创建存储单元时,创建并返回对应的 StorageCell 实例
- */
-public class InfinityBigIntegerCellHandler implements ICellHandler {
-
- /** Handler 单例,供注册与调用使用 */
- public static final InfinityBigIntegerCellHandler INSTANCE = new InfinityBigIntegerCellHandler();
-
- /**
- * 判断给定的 ItemStack 是否为 InfinityBigIntegerCell
- */
- @Override
- public boolean isCell(ItemStack is) {
- return is.getItem() instanceof InfinityBigIntegerCellItem;
- }
-
- /**
- * 在 AE2 需要访问或创建存储单元时返回对应的 InfinityBigIntegerCellInventory(StorageCell 实现)。
- * 参数 container 为 AE2 提供的保存回调(ISaveProvider),当 cell 需要持久化时会调用它。
- */
- @Override
- public InfinityBigIntegerCellInventory getCellInventory(ItemStack is, ISaveProvider container) {
- return InfinityBigIntegerCellInventory.createInventory(is, container);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellInventory.java b/src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellInventory.java
deleted file mode 100644
index b7e3e14..0000000
--- a/src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellInventory.java
+++ /dev/null
@@ -1,435 +0,0 @@
-package com.extendedae_plus.ae.api.storage;
-
-import appeng.api.config.Actionable;
-import appeng.api.networking.security.IActionSource;
-import appeng.api.stacks.AEItemKey;
-import appeng.api.stacks.AEKey;
-import appeng.api.stacks.KeyCounter;
-import appeng.api.storage.cells.CellState;
-import appeng.api.storage.cells.ISaveProvider;
-import appeng.api.storage.cells.StorageCell;
-import com.extendedae_plus.ae.items.InfinityBigIntegerCellItem;
-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 net.minecraft.core.HolderLookup;
-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;
-import net.neoforged.neoforge.event.server.ServerStoppingEvent;
-import net.neoforged.neoforge.event.tick.ServerTickEvent;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.math.RoundingMode;
-import java.text.DecimalFormat;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-/**
- * InfinityBigIntegerCellInventory
- *
- * 本类实现 AE2 的 StorageCell,表示单个 Infinity 存储单元的运行时数据与行为。
- * 主要职责:
- * - 在内存中维护条目映射 (AEKey -> BigInteger 数量)
- * - 提供插入/提取/列举/持久化等操作的实现
- * - 通过 UUID 将 ItemStack 与世界级的 SavedData 关联以实现持久化
- *
- * 重要字段:
- * - stack: 关联的 ItemStack,NB T 中保存 UUID 与缓存信息
- * - container: AE2 提供的保存回调 (ISaveProvider),用于合并与触发持久化
- * - storedMap: 延迟初始化的内存映射,减少未使用时内存占用
- * - totalStored: 缓存的总数量 (BigInteger),避免频繁全表扫描
- * - isPersisted: 标记内存状态是否已同步到持久层
- */
-public class InfinityBigIntegerCellInventory implements StorageCell {
-
- // 待持久化队列(用于 debounce:在服务器 tick 中合并持久化)
- private static final ConcurrentLinkedQueue PENDING_PERSIST = new ConcurrentLinkedQueue<>();
- // 数字格式化对象,保留两位小数(复用以减少对象分配)
- private static final DecimalFormat DF = new DecimalFormat("#.##");
-
- // 关联的 ItemStack(含可能的 uuid NBT)
- private final ItemStack stack;
- // AE2 提供的保存提供者,用于在容器中批量保存时触发回调
- private final ISaveProvider container;
- // 内存中的键-数量映射(使用 BigInteger 支持超长数量,延迟初始化)
- private Object2ObjectMap storedMap = null;
- // 标记是否已持久化到 SavedData
- private boolean isPersisted = true;
- // 缓存的总存储量,避免每次调用进行全表扫描
- private BigInteger totalStored = BigInteger.ZERO;
-
- /**
- * 私有构造器:通过 createInventory 工厂方法调用
- *
- * @param stack 关联的物品堆
- * @param saveProvider AE2 的保存回调(可为 null)
- */
- private InfinityBigIntegerCellInventory(ItemStack stack, ISaveProvider saveProvider) {
- this.stack = stack;
- container = saveProvider;
- // 不在构造时创建 storedMap,推迟到实际访问或首次写入时初始化
- this.storedMap = null;
- }
-
- // 创建存储单元库存实例的静态方法
- static InfinityBigIntegerCellInventory createInventory(ItemStack stack, ISaveProvider saveProvider) {
- if (stack.getItem() instanceof InfinityBigIntegerCellItem) {
- return new InfinityBigIntegerCellInventory(stack, saveProvider);
- }
- return null;
- }
-
- // 获取全局存储实例
- private static InfinityStorageManager getStorageInstance() {
- return InfinityStorageManager.INSTANCE;
- }
-
- // 服务器 tick 回调:合并并执行待持久化项
- public static void onServerTick(ServerTickEvent.Post event) {
- // NeoForge 提供 Pre/Post 子类以区分阶段,Post 对应原来的 Phase.END
- InfinityBigIntegerCellInventory inv;
- // 处理本次 tick 中的全部待持久化项
- while ((inv = PENDING_PERSIST.poll()) != null) {
- try {
- if (!inv.isPersisted) {
- inv.persist();
- }
- } catch (Throwable ignored) {
- // 忽略单项错误,继续处理其余队列
- }
- }
- }
-
- // 在服务器停止时被调用,立即强制持久化队列中的所有实例
- public static void onServerStopping(ServerStoppingEvent event) {
- InfinityBigIntegerCellInventory inv;
- while ((inv = PENDING_PERSIST.poll()) != null) {
- try {
- if (!inv.isPersisted) {
- inv.persist();
- }
- } catch (Throwable ignored) {
- // 忽略单项错误,继续尝试持久化其它实例
- }
- }
- // 额外尝试将全局存储管理器标记为脏以确保 SavedData 被写回(在单人模式下可能直接由系统触发)
- try {
- var stor = getStorageInstance();
- if (stor != null) stor.setDirty();
- } catch (Throwable ignored) {
- }
- }
-
- // 将 BigInteger 格式化为带单位的字符串,保留两位小数
- public static String formatBigInteger(BigInteger number) {
- // 使用局部 DF(非线程安全),但 Minecraft 通常在主线程运行
- BigDecimal bd = new BigDecimal(number);
- BigDecimal thousand = new BigDecimal(1000);
- String[] units = new String[]{"", "K", "M", "G", "T", "P", "E", "Z", "Y"};
- int idx = 0;
- while (bd.compareTo(thousand) >= 0 && idx < units.length - 1) {
- bd = bd.divide(thousand, 2, RoundingMode.HALF_UP);
- idx++;
- }
- if (idx == 0) {
- return bd.setScale(0, RoundingMode.DOWN).toPlainString();
- }
- return DF.format(bd.doubleValue()) + units[idx];
- }
-
- // 获取当前存储单元的数据存储对象
- private InfinityDataStorage getCellStorage() {
- if (this.getUUID() == null) {
- // 如果没有UUID,返回空存储
- return InfinityDataStorage.EMPTY;
- } else {
- // 否则获取或创建对应UUID的存储
- return getStorageInstance().getOrCreateCell(getUUID());
- }
- }
-
- // 获取存储单元状态(空/非空)
- @Override
- public CellState getStatus() {
- if (this.getCellStoredMap().isEmpty()) {
- return CellState.EMPTY;
- }
- return CellState.NOT_EMPTY;
- }
-
- // 获取存储单元的待机能耗
- @Override
- public double getIdleDrain() {
- return 512;
- }
-
- // 获取存储单元的描述(此处返回null,可自定义)
- @Override
- public Component getDescription() {
- return null;
- }
-
- // 判断物品堆栈是否有UUID
- public boolean hasUUID() {
- CustomData customData = stack.get(DataComponents.CUSTOM_DATA);
- if (customData == null) return false;
- CompoundTag tag = customData.copyTag();
- return tag != null && tag.contains("uuid");
- }
-
- // 获取物品堆栈的UUID
- public UUID getUUID() {
- CustomData customData = stack.get(DataComponents.CUSTOM_DATA);
- if (customData == null) return null;
- CompoundTag tag = customData.copyTag();
- if (tag != null && tag.contains("uuid")) {
- return tag.getUUID("uuid");
- }
- return null;
- }
-
- // 获取或初始化存储映射
- private Object2ObjectMap getCellStoredMap() {
- if (storedMap == null) {
- storedMap = new Object2ObjectOpenHashMap<>();
- this.loadCellStoredMap();
- }
- return storedMap;
- }
-
- // 从存储中加载物品映射
- private void loadCellStoredMap() {
- boolean corruptedTag = false; // 标记数据是否损坏
- if (!this.hasUUID()) return;
-
- ListTag keys = this.getCellStorage().keys;
- ListTag amounts = this.getCellStorage().amounts;
-
- int len = Math.min(keys.size(), amounts.size());
-
- HolderLookup.Provider registries = getStorageInstance().getRegistries();
-
- for (int i = 0; i < len; i++) {
- AEKey key = AEKey.fromTagGeneric(registries,keys.getCompound(i));
- CompoundTag amtTag = amounts.getCompound(i);
- try {
- BigInteger amount;
- if (amtTag.contains("l")) {
- long v = amtTag.getLong("l");
- amount = BigInteger.valueOf(v);
- } else if (amtTag.contains("s")) {
- amount = new BigInteger(amtTag.getString("s"));
- } else {
- corruptedTag = true;
- continue;
- }
- if (amount.compareTo(BigInteger.ZERO) <= 0 || key == null) {
- corruptedTag = true;
- } else {
- // storedMap 已在 getCellStoredMap() 中初始化,直接使用字段以避免额外方法开销
- storedMap.put(key, amount);
- // 更新缓存的总数
- totalStored = totalStored.add(amount);
- }
- } catch (NumberFormatException ex) {
- corruptedTag = true;
- }
- }
- // 如果有损坏,保存修正后的数据
- if (corruptedTag) {
- this.saveChanges();
- }
- }
-
- // 标记数据需要保存,并通知容器或直接持久化
- private void saveChanges() {
- // 标记为未持久化,交由容器或延迟任务合并写入以减少 I/O
- isPersisted = false;
- if (container != null) {
- // 当存在容器时,优先让容器统一处理持久化
- container.saveChanges();
- } else {
- // 如果没有容器,入队等待服务器 tick 在主线程统一持久化,避免频繁 I/O
- if (!PENDING_PERSIST.contains(this)) {
- PENDING_PERSIST.offer(this);
- }
- }
- }
-
- // 获取所有可用的物品堆栈及其数量
- @Override
- public void getAvailableStacks(KeyCounter out) {
- BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE);
- Object2ObjectMap map = getCellStoredMap();
- for (Object2ObjectMap.Entry entry : map.object2ObjectEntrySet()) {
- AEKey key = entry.getKey();
- BigInteger value = entry.getValue();
-
- // 当前 KeyCounter 中已有的值(long)
- long existing = out.get(key);
-
- // 将 existing 与当前 value 做 BigInteger 累加并饱和到 Long.MAX_VALUE
- BigInteger sum = BigInteger.valueOf(existing).add(value);
- long toSet = sum.compareTo(maxLong) > 0 ? Long.MAX_VALUE : sum.longValue();
-
- // KeyCounter 没有 set(key,long) 的统一接口暴露(只有 add/remove),所以先移除已存在的值再设置。
- // 为避免读取-写入竞争,我们计算出要新增的 delta 并调用 add(key, delta)
- if (existing == Long.MAX_VALUE) {
- // 已经饱和,无需再添加
- continue;
- }
- long delta;
- if (toSet == Long.MAX_VALUE) {
- delta = Long.MAX_VALUE - existing;
- } else {
- delta = toSet - existing;
- }
- if (delta != 0) {
- out.add(key, delta);
- }
- }
- }
-
- // 持久化存储单元数据到全局存储
- @Override
- public void persist() {
- if (this.isPersisted)
- return;
- Object2ObjectMap map = this.getCellStoredMap();
- if (map.isEmpty()) {
- // 如果存储为空,移除UUID和全局存储中的数据
- if (this.hasUUID()) {
- getStorageInstance().removeCell(getUUID());
- // 从 CustomData 中移除缓存字段
- try {
- CustomData.update(DataComponents.CUSTOM_DATA, stack, tag -> {
- tag.remove("uuid");
- tag.remove("total");
- });
- } catch (Throwable ignored) {
- }
- }
- return;
- }
- // 构建要保存的Key和数量列表(混合表示:long 或 string)
- ListTag amountTags = new ListTag();
- ListTag keys = new ListTag();
- for (Object2ObjectMap.Entry entry : map.object2ObjectEntrySet()) {
- BigInteger amount = entry.getValue();
- if (amount.compareTo(BigInteger.ZERO) > 0) {
- keys.add(entry.getKey().toTagGeneric(getStorageInstance().getRegistries()));
- CompoundTag amt = new CompoundTag();
- if (amount.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) <= 0) {
- amt.putLong("l", amount.longValue());
- } else {
- amt.putString("s", amount.toString());
- }
- amountTags.add(amt);
- }
- }
- // 如果没有Key,更新为空存储,否则保存数据
- if (keys.isEmpty()) {
- getStorageInstance().updateCell(this.getUUID(), new InfinityDataStorage());
- } else {
- // amounts 现在为 CompoundTag 列表
- getStorageInstance().modifyCell(this.getUUID(), keys, amountTags);
- }
- // 将缓存的 totalStored 同步到 ItemStack 的 CustomData(优先使用 long)
- try {
- CustomData.update(DataComponents.CUSTOM_DATA, stack, tag -> {
- if (totalStored.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) <= 0) {
- tag.putLong("total", totalStored.longValue());
- } else {
- tag.putString("total", totalStored.toString());
- }
- // 将当前已存储的不同物品种类数缓存到 CustomData(键名: "types"),用于客户端 tooltip 显示
- int typesCount = this.getCellStoredMap().size();
- tag.putInt("types", typesCount);
- });
- } catch (Throwable ignored) {
- }
- isPersisted = true;
- }
-
- // 插入物品到存储单元
- @Override
- public long insert(AEKey what, long amount, Actionable mode, IActionSource source) {
- // 数量为0或类型不匹配直接返回
- if (amount == 0)
- return 0;
- // 不允许存储无限单元自身
- if (what instanceof AEItemKey itemKey && itemKey.getItem() instanceof InfinityBigIntegerCellItem)
- return 0;
- // 如果没有UUID,生成UUID并初始化存储
- if (!this.hasUUID()) {
- UUID id = UUID.randomUUID();
- try {
- CustomData.update(DataComponents.CUSTOM_DATA, stack, tag -> tag.putUUID("uuid", id));
- } catch (Throwable ignored) {
- }
- getStorageInstance().getOrCreateCell(getUUID());
- // 确保 storedMap 初始化并从持久层加载数据
- this.getCellStoredMap();
- }
- Object2ObjectMap map = this.getCellStoredMap();
- BigInteger currentAmount = map.getOrDefault(what, BigInteger.ZERO);
- if (mode == Actionable.MODULATE) {
- // 实际插入,更新数量并保存
- BigInteger newAmount = currentAmount.add(BigInteger.valueOf(amount));
- map.put(what, newAmount);
- // 更新 cached total
- totalStored = totalStored.add(BigInteger.valueOf(amount));
- this.saveChanges();
- }
- return amount;
- }
-
- // 从存储单元提取物品
- @Override
- public long extract(AEKey what, long amount, Actionable mode, IActionSource source) {
- Object2ObjectMap map = this.getCellStoredMap();
- BigInteger currentAmount = map.getOrDefault(what, BigInteger.ZERO);
- if (currentAmount.compareTo(BigInteger.ZERO) > 0) {
- BigInteger requested = BigInteger.valueOf(amount);
- if (currentAmount.compareTo(requested) <= 0) {
- // 提取全部
- long ret;
- if (currentAmount.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
- ret = Long.MAX_VALUE;
- } else {
- ret = currentAmount.longValue();
- }
- if (mode == Actionable.MODULATE) {
- map.remove(what);
- // 更新 cached total
- // 如果 currentAmount 大于 Long.MAX_VALUE,totalStored 减去 currentAmount 会保留大整数
- totalStored = totalStored.subtract(currentAmount);
- this.saveChanges();
- }
- return ret;
- } else {
- // 提取部分
- if (mode == Actionable.MODULATE) {
- map.put(what, currentAmount.subtract(requested));
- // 更新 cached total
- totalStored = totalStored.subtract(requested);
- this.saveChanges();
- }
- return amount;
- }
- }
- return 0;
- }
-
- // 获取存储单元内所有物品的总数量(格式化字符串)
- public String getTotalStorage() {
- // 使用缓存的 totalStored,避免每次全表扫描
- return formatBigInteger(totalStored);
- }
-}
diff --git a/src/main/java/com/extendedae_plus/ae/items/InfinityBigIntegerCellItem.java b/src/main/java/com/extendedae_plus/ae/items/InfinityBigIntegerCellItem.java
deleted file mode 100644
index 7002ba9..0000000
--- a/src/main/java/com/extendedae_plus/ae/items/InfinityBigIntegerCellItem.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.extendedae_plus.ae.items;
-
-import com.extendedae_plus.ae.api.storage.InfinityBigIntegerCellInventory;
-import com.google.common.base.Preconditions;
-import net.minecraft.ChatFormatting;
-import net.minecraft.core.component.DataComponents;
-import net.minecraft.nbt.CompoundTag;
-import net.minecraft.nbt.LongTag;
-import net.minecraft.nbt.Tag;
-import net.minecraft.network.chat.Component;
-import net.minecraft.world.item.Item;
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.TooltipFlag;
-import net.minecraft.world.item.component.CustomData;
-import org.jetbrains.annotations.NotNull;
-
-import java.math.BigInteger;
-import java.util.List;
-
-public class InfinityBigIntegerCellItem extends Item {
-
- public InfinityBigIntegerCellItem() {
- super(new Properties().stacksTo(1).fireResistant());
- }
-
- @Override
- public void appendHoverText(ItemStack stack,
- @NotNull TooltipContext context,
- List tooltip,
- @NotNull TooltipFlag tooltipFlag) {
- tooltip.add(Component.translatable("tooltip.extendedae_plus.infinity_biginteger_cell.summon1"));
- tooltip.add(Component.translatable("tooltip.extendedae_plus.infinity_biginteger_cell.summon2"));
-
- Preconditions.checkArgument(stack.getItem() == this);
- CustomData customData = stack.get(DataComponents.CUSTOM_DATA);
- if (customData != null) {
- CompoundTag tag = customData.copyTag();
-
- if (tag != null && tag.contains("uuid")) {
- String uuidStr = tag.getUUID("uuid").toString();
- tooltip.add(
- Component.literal("UUID: ")
- .withStyle(ChatFormatting.GRAY)
- .append(Component.literal(uuidStr).withStyle(ChatFormatting.YELLOW))
- );
-
- if (tag.contains("types")) {
- try {
- int types = tag.getInt("types");
- tooltip.add(
- Component.literal("Types: ")
- .withStyle(ChatFormatting.GRAY)
- .append(Component.literal(String.valueOf(types)).withStyle(ChatFormatting.GREEN))
- );
- } catch (Exception ignored) {
- }
- }
-
- if (tag.contains("total")) {
- BigInteger total = BigInteger.ZERO;
- Tag t = tag.get("total");
- try {
- if (t instanceof LongTag) {
- total = BigInteger.valueOf(tag.getLong("total"));
- } else {
- String s = tag.getString("total");
- total = new BigInteger(s);
- }
- } catch (Exception ignored) {
- }
- String formatted = InfinityBigIntegerCellInventory.formatBigInteger(total);
- tooltip.add(
- Component.literal("Byte: ")
- .withStyle(ChatFormatting.GRAY)
- .append(Component.literal(formatted).withStyle(ChatFormatting.AQUA))
- );
- }
- }
- }
- }
-}
diff --git a/src/main/java/com/extendedae_plus/init/ModCreativeTabs.java b/src/main/java/com/extendedae_plus/init/ModCreativeTabs.java
index 2846159..f07a83b 100644
--- a/src/main/java/com/extendedae_plus/init/ModCreativeTabs.java
+++ b/src/main/java/com/extendedae_plus/init/ModCreativeTabs.java
@@ -27,7 +27,7 @@ public final class ModCreativeTabs {
output.accept(ModItems.ACCELERATOR_256x.get());
output.accept(ModItems.ACCELERATOR_1024x.get());
- output.accept(ModItems.INFINITY_BIGINTEGER_CELL_ITEM.get());
+// output.accept(ModItems.INFINITY_BIGINTEGER_CELL_ITEM.get());
})
.build());
}
diff --git a/src/main/java/com/extendedae_plus/init/ModItems.java b/src/main/java/com/extendedae_plus/init/ModItems.java
index 113ec98..71a6220 100644
--- a/src/main/java/com/extendedae_plus/init/ModItems.java
+++ b/src/main/java/com/extendedae_plus/init/ModItems.java
@@ -1,7 +1,6 @@
package com.extendedae_plus.init;
import com.extendedae_plus.ExtendedAEPlus;
-import com.extendedae_plus.ae.items.InfinityBigIntegerCellItem;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.neoforged.neoforge.registries.DeferredItem;
@@ -48,8 +47,8 @@ public final class ModItems {
() -> new BlockItem(ModBlocks.ACCELERATOR_1024x.get(), new Item.Properties())
);
- public static final DeferredItem- INFINITY_BIGINTEGER_CELL_ITEM = ITEMS.register(
- "infinity_biginteger_cell", InfinityBigIntegerCellItem::new
- );
+// public static final DeferredItem
- INFINITY_BIGINTEGER_CELL_ITEM = ITEMS.register(
+// "infinity_biginteger_cell", InfinityBigIntegerCellItem::new
+// );
}
diff --git a/src/main/java/com/extendedae_plus/util/storage/InfinityDataStorage.java b/src/main/java/com/extendedae_plus/util/storage/InfinityDataStorage.java
deleted file mode 100644
index 4ef9036..0000000
--- a/src/main/java/com/extendedae_plus/util/storage/InfinityDataStorage.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.extendedae_plus.util.storage;
-
-import net.minecraft.nbt.CompoundTag;
-import net.minecraft.nbt.ListTag;
-import net.minecraft.nbt.Tag;
-
-/**
- * InfinityDataStorage
- *
- * 表示单个 UUID 对应的持久化数据容器,直接映射到世界存档中的一项记录。
- * 数据结构说明:
- * - keys: 存放序列化后的 AEKey(每项为 CompoundTag),用于标识不同的存储条目
- * - amounts: 与 keys 一一对应的数量列表(每项为 CompoundTag),采用混合表示:
- * - 当数量能放入 long 时,CompoundTag 包含键 "l" 存放 long 值
- * - 当数量超出 long 时,CompoundTag 包含键 "s" 存放 BigInteger 的字符串形式
- *
- * 该类提供将内存数据与 NBT 之间互转的辅助方法,供 `SavedData` 在世界保存/加载时调用。
- */
-public class InfinityDataStorage {
-
- /** 空实例(表示没有数据) */
- public static final InfinityDataStorage EMPTY = new InfinityDataStorage();
-
- /** 序列化的键列表(NBT ListTag,元素为 CompoundTag) */
- public ListTag keys;
- /**
- * 与 keys 对应的数量列表(NBT ListTag,元素为 CompoundTag):
- * - 若数量能放入 long,则 CompoundTag 包含键 "l"(long)
- * - 否则包含键 "s"(String) 存放 BigInteger 的字符串形式
- */
- public ListTag amounts;
-
- public InfinityDataStorage() {
- this(new ListTag(), new ListTag());
- }
-
- private InfinityDataStorage(ListTag keys, ListTag amounts) {
- this.keys = keys;
- this.amounts = amounts;
- }
-
- /**
- * 将当前数据封装为 CompoundTag 以写入存档
- */
- public CompoundTag serializeNBT() {
- CompoundTag nbt = new CompoundTag();
- nbt.put("keys", keys);
- nbt.put("amounts", amounts);
- return nbt;
- }
-
- /**
- * 从存档读取数据并构造实例
- */
- public static InfinityDataStorage loadFromNBT(CompoundTag nbt) {
- ListTag stackKeys = nbt.getList("keys", Tag.TAG_COMPOUND);
- // amounts 以 CompoundTag 列表存储,每个 CompoundTag 内含 long 或 String
- ListTag stackAmounts = nbt.getList("amounts", Tag.TAG_COMPOUND);
- return new InfinityDataStorage(stackKeys, stackAmounts);
- }
-}
diff --git a/src/main/java/com/extendedae_plus/util/storage/InfinityStorageManager.java b/src/main/java/com/extendedae_plus/util/storage/InfinityStorageManager.java
deleted file mode 100644
index ea48942..0000000
--- a/src/main/java/com/extendedae_plus/util/storage/InfinityStorageManager.java
+++ /dev/null
@@ -1,166 +0,0 @@
-package com.extendedae_plus.util.storage;
-
-import net.minecraft.core.HolderLookup;
-import net.minecraft.nbt.CompoundTag;
-import net.minecraft.nbt.ListTag;
-import net.minecraft.server.MinecraftServer;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.world.level.saveddata.SavedData;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.lang.ref.WeakReference;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-/**
- * InfinityStorageManager
- *
- * 世界级别的持久化容器,集中管理所有 InfinityBigInteger 存储单元的序列化数据。
- * 功能要点:
- * - 在世界加载时从存档恢复所有 cell 的数据
- * - 提供按 UUID 获取/创建单个 cell 的数据容器
- * - 在世界保存时将内存数据打包为 NBT 写回存档
- */
-public class InfinityStorageManager extends SavedData {
- private static final Factory FACTORY = new Factory<>(InfinityStorageManager::new, InfinityStorageManager::readNbt);
-
- /**
- * SavedData 文件名常量
- */
- public static final String FILE_NAME = "eap_infinity_biginteger_cells";
- /**
- * 全局单例实例(在世界加载时由 InfiniteBigIntegerStorageCell.onLevelLoad 填充)
- */
- public static InfinityStorageManager INSTANCE = null;
- /**
- * UUID -> 数据 的内存映射
- */
- private final Map cells;
-
- @Nullable
- private WeakReference registries;
-
- public InfinityStorageManager() {
- this.cells = new HashMap<>();
- setDirty();
- }
-
- public InfinityStorageManager(Map cells) {
- this.cells = cells;
- setDirty();
- }
-
- /**
- * 从 NBT 构造:用于在世界加载时从存档恢复数据
- */
- public InfinityStorageManager(CompoundTag nbt) {
- this.cells = new HashMap<>();
- ListTag cellList = nbt.getList("list", CompoundTag.TAG_COMPOUND);
- for (int i = 0; i < cellList.size(); i++) {
- CompoundTag cell = cellList.getCompound(i);
- cells.put(cell.getUUID("uuid"), InfinityDataStorage.loadFromNBT(cell.getCompound("data")));
- }
- setDirty();
- }
-
- /**
- * 根据给定的 ServerLevel 获取或创建该世界对应的 SavedData 实例并缓存到 INSTANCE
- */
- public static InfinityStorageManager getForLevel(ServerLevel level) {
- if (INSTANCE == null && level != null) {
- INSTANCE = level.getDataStorage().computeIfAbsent(FACTORY, FILE_NAME);
- INSTANCE.registries = new WeakReference<>(level.registryAccess());
- }
- return INSTANCE;
- }
-
- public HolderLookup.Provider getRegistries() {
- var r = this.registries;
- if (r == null) {
- throw new IllegalStateException("StorageManager was not initialized properly.");
- }
-
- var registries = r.get();
- if (registries == null) {
- throw new IllegalStateException("Using a StorageManager whose server was already closed");
- }
-
- return registries;
- }
-
- @Override
- public @NotNull CompoundTag save(@NotNull CompoundTag nbt, HolderLookup.@NotNull Provider registries) {
- // 将内存中的所有 cell 序列化为一个 ListTag
- ListTag cellList = new ListTag();
- for (Map.Entry entry : cells.entrySet()) {
- CompoundTag cell = new CompoundTag();
- cell.putUUID("uuid", entry.getKey());
- cell.put("data", entry.getValue().serializeNBT());
- cellList.add(cell);
- }
- nbt.put("list", cellList);
- return nbt;
- }
-
- /**
- * 更新或添加某个 UUID 对应的数据并标记为脏(需要保存)
- */
- public void updateCell(UUID uuid, InfinityDataStorage infinityDataStorage) {
- cells.put(uuid, infinityDataStorage);
- setDirty();
- }
-
- /**
- * 获取或创建某个 UUID 对应的数据容器
- */
- public InfinityDataStorage getOrCreateCell(UUID uuid) {
- if (!cells.containsKey(uuid)) {
- updateCell(uuid, new InfinityDataStorage());
- }
- return cells.get(uuid);
- }
-
- /**
- * 修改某个 UUID 对应的键与数量列表并保存(新的签名,stackAmounts 为 ListTag 字符串列表)
- */
- public void modifyCell(UUID cellID, ListTag stackKeys, ListTag stackAmounts) {
- InfinityDataStorage cellToModify = getOrCreateCell(cellID);
- if (stackKeys != null && stackAmounts != null) {
- cellToModify.keys = stackKeys;
- cellToModify.amounts = stackAmounts;
- }
- updateCell(cellID, cellToModify);
- }
-
- /**
- * 删除某个 UUID 的持久化记录并标记为脏
- */
- public void removeCell(UUID uuid) {
- cells.remove(uuid);
- setDirty();
- }
-
- public static InfinityStorageManager readNbt(CompoundTag nbt, HolderLookup.Provider registries) {
- Map cell = new HashMap<>();
- ListTag diskList = nbt.getList("list", CompoundTag.TAG_COMPOUND);
- for (int i = 0; i < diskList.size(); i++) {
- CompoundTag disk = diskList.getCompound(i);
- cell.put(disk.getUUID("uuid"), InfinityDataStorage.loadFromNBT(disk.getCompound("data")));
- }
- return new InfinityStorageManager(cell);
- }
-
- public static InfinityStorageManager getInstance(MinecraftServer server) {
- ServerLevel world = server.getLevel(ServerLevel.OVERWORLD);
- InfinityStorageManager manager = null;
- if (world != null) {
- manager = world.getDataStorage().computeIfAbsent(FACTORY, FILE_NAME);
- }
- if (manager != null) {
- manager.registries = new WeakReference<>(server.registryAccess());
- }
- return manager;
- }
-}