diff --git a/build/generated/sources/modMetadata/META-INF/neoforge.mods.toml b/build/generated/sources/modMetadata/META-INF/neoforge.mods.toml index 4eba2b3..85db319 100644 --- a/build/generated/sources/modMetadata/META-INF/neoforge.mods.toml +++ b/build/generated/sources/modMetadata/META-INF/neoforge.mods.toml @@ -5,30 +5,24 @@ # Find more information on toml format here: https://github.com/toml-lang/toml # The name of the mod loader type to load - for regular FML @Mod mods it should be javafml -modLoader="javafml" #mandatory +modLoader = "javafml" #mandatory # A version range to match for said mod loader - for regular FML @Mod it will be the FML version. This is currently 2. -loaderVersion="[1,)" #mandatory +loaderVersion = "[1,)" #mandatory # The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. # Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. -license="All Rights Reserved" +license = "LGPL-3.0-or-later" # A URL to refer people to when problems occur with this mod -#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional # A list of mods - how many allowed here is determined by the individual mod loader -[[mods]] #mandatory - -# The modid of the mod -modId="extendedae_plus" #mandatory - -# The version number of the mod -version="1.21.1-1.4.3" #mandatory - -# A display name for the mod -displayName="ExtendedAE-Plus" #mandatory - +[[mods]] +modId = "extendedae_plus" +version = "1.21.1-1.4.3" +displayName = "ExtendedAE-Plus" +issueTrackerURL = "https://github.com/GaLicn/ExtendedAE_Plus/issues" +displayURL = "https://github.com/GaLicn/ExtendedAE_Plus" # A URL to query for updates for this mod. See the JSON update specification https://docs.neoforged.net/docs/misc/updatechecker/ #updateJSONURL="https://change.me.example.invalid/updates.json" #optional @@ -42,15 +36,14 @@ displayName="ExtendedAE-Plus" #mandatory #credits="" #optional # A text field displayed in the mod UI -authors="YourNameHere, OtherNameHere" #optional +authors = "GaLi, C-H716" #optional # The description text for the mod (multi line!) (#mandatory) -description='''Example mod description. -Newline characters can be used and will be replaced properly.''' +description = '''Add more practical features and auxiliary operations to the Applied Energistics 2 mod''' # The [[mixins]] block allows you to declare your mixin config to FML so that it gets loaded. [[mixins]] -config="extendedae_plus.mixins.json" +config = "extendedae_plus.mixins.json" # The [[accessTransformers]] block allows you to declare where your AT file is. # If this block is omitted, a fallback attempt will be made to load an AT from META-INF/accesstransformer.cfg @@ -61,40 +54,40 @@ config="extendedae_plus.mixins.json" # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. [[dependencies.extendedae_plus]] #optional - # the modid of the dependency - modId="neoforge" #mandatory - # The type of the dependency. Can be one of "required", "optional", "incompatible" or "discouraged" (case insensitive). - # 'required' requires the mod to exist, 'optional' does not - # 'incompatible' will prevent the game from loading when the mod exists, and 'discouraged' will show a warning - type="required" #mandatory - # Optional field describing why the dependency is required or why it is incompatible - # reason="..." - # The version range of the dependency - versionRange="[21.1.1,)" #mandatory - # An ordering relationship for the dependency. - # BEFORE - This mod is loaded BEFORE the dependency - # AFTER - This mod is loaded AFTER the dependency - ordering="NONE" - # Side this dependency is applied on - BOTH, CLIENT, or SERVER - side="BOTH" +# the modid of the dependency +modId = "neoforge" #mandatory +# The type of the dependency. Can be one of "required", "optional", "incompatible" or "discouraged" (case insensitive). +# 'required' requires the mod to exist, 'optional' does not +# 'incompatible' will prevent the game from loading when the mod exists, and 'discouraged' will show a warning +type = "required" #mandatory +# Optional field describing why the dependency is required or why it is incompatible +# reason="..." +# The version range of the dependency +versionRange = "[21.1.1,)" #mandatory +# An ordering relationship for the dependency. +# BEFORE - This mod is loaded BEFORE the dependency +# AFTER - This mod is loaded AFTER the dependency +ordering = "NONE" +# Side this dependency is applied on - BOTH, CLIENT, or SERVER +side = "BOTH" # Here's another dependency [[dependencies.extendedae_plus]] - modId="minecraft" - type="required" - # This version range declares a minimum of the current minecraft version up to but not including the next major version - versionRange="[1.21.1]" - ordering="NONE" - side="BOTH" +modId = "minecraft" +type = "required" +# This version range declares a minimum of the current minecraft version up to but not including the next major version +versionRange = "[1.21.1]" +ordering = "NONE" +side = "BOTH" # Require ExtendedAE (ExtendedAE-1.21-2.2.21-neoforge) to be present [[dependencies.extendedae_plus]] - modId="extendedae" - type="required" - # Use a permissive range to tolerate upstream version string variations (e.g. 1.21-2.2.21-neoforge) - versionRange="*" - ordering="AFTER" - side="BOTH" +modId = "extendedae" +type = "required" +# Use a permissive range to tolerate upstream version string variations (e.g. 1.21-2.2.21-neoforge) +versionRange = "*" +ordering = "AFTER" +side = "BOTH" # Features are specific properties of the game environment, that you may want to declare you require. This example declares # that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't diff --git a/gradle.properties b/gradle.properties index 7c01284..95445da 100644 --- a/gradle.properties +++ b/gradle.properties @@ -30,7 +30,7 @@ mod_id=extendedae_plus # The human-readable display name for the mod. mod_name=ExtendedAE-Plus # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. -mod_license=All Rights Reserved +mod_license=LGPL-3.0-or-later # The mod version. See https://semver.org/ mod_version=1.21.1-1.4.3 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. @@ -38,9 +38,9 @@ mod_version=1.21.1-1.4.3 # See https://maven.apache.org/guides/mini/guide-naming-conventions.html mod_group_id=com.extendedae_plus # The authors of the mod. This is a simple text string that is used for display purposes in the mod list. -mod_authors=YourNameHere, OtherNameHere +mod_authors=GaLi, C-H716 # The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list. -mod_description=Example mod description.\nNewline characters can be used and will be replaced properly. +mod_description=Add more practical features and auxiliary operations to the Applied Energistics 2 mod ## UI item explorer selection (emi | rei | jei) # Default to 'emi' per request; you can override by running with -Puse_Xei=rei or -Puse_Xei=jei diff --git a/src/main/java/com/extendedae_plus/Config.java b/src/main/java/com/extendedae_plus/Config.java deleted file mode 100644 index 044ba3b..0000000 --- a/src/main/java/com/extendedae_plus/Config.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.extendedae_plus; - -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Item; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.fml.event.config.ModConfigEvent; -import net.neoforged.neoforge.common.ModConfigSpec; - -// An example config class. This is not required, but it's a good idea to have one to keep your config organized. -// Demonstrates how to use Neo's config APIs -public class Config { - private static final ModConfigSpec.Builder BUILDER = new ModConfigSpec.Builder(); - - public static final ModConfigSpec.BooleanValue LOG_DIRT_BLOCK = BUILDER - .comment("Whether to log the dirt block on common setup") - .define("logDirtBlock", true); - - public static final ModConfigSpec.IntValue MAGIC_NUMBER = BUILDER - .comment("A magic number") - .defineInRange("magicNumber", 42, 0, Integer.MAX_VALUE); - - public static final ModConfigSpec.ConfigValue MAGIC_NUMBER_INTRODUCTION = BUILDER - .comment("What you want the introduction message to be for the magic number") - .define("magicNumberIntroduction", "The magic number is... "); - - // a list of strings that are treated as resource locations for items - public static final ModConfigSpec.ConfigValue> ITEM_STRINGS = BUILDER - .comment("A list of items to log on common setup.") - .defineListAllowEmpty("items", List.of("minecraft:iron_ingot"), () -> "", Config::validateItemName); - - static final ModConfigSpec SPEC = BUILDER.build(); - - private static boolean validateItemName(final Object obj) { - return obj instanceof String itemName && BuiltInRegistries.ITEM.containsKey(ResourceLocation.parse(itemName)); - } -} diff --git a/src/main/java/com/extendedae_plus/ExtendedAEPlus.java b/src/main/java/com/extendedae_plus/ExtendedAEPlus.java index be31b74..b912c1a 100644 --- a/src/main/java/com/extendedae_plus/ExtendedAEPlus.java +++ b/src/main/java/com/extendedae_plus/ExtendedAEPlus.java @@ -6,8 +6,8 @@ import appeng.api.storage.StorageCells; import appeng.block.AEBaseEntityBlock; import appeng.blockentity.crafting.CraftingBlockEntity; import appeng.items.parts.PartModelsHelper; -import com.extendedae_plus.ae.api.storage.InfinityBigIntegerCellHandler; import com.extendedae_plus.api.ids.EAPComponents; +import com.extendedae_plus.api.storage.InfinityBigIntegerCellHandler; import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.init.*; import com.extendedae_plus.util.storage.InfinityStorageManager; @@ -37,6 +37,10 @@ public class ExtendedAEPlus { // Directly reference a slf4j logger public static final Logger LOGGER = LogUtils.getLogger(); // 移除 MDK 示例注册,改为使用实际模组的方块/物品/创造物品栏注册见 ModBlocks、ModItems、ModCreativeTabs + @Nullable + private static InfinityStorageManager storageManager; + @Nullable + private static MinecraftServer storageManagerServer; // The constructor for the mod class is the first code that is run when your mod is loaded. // FML will recognize some parameter types like IEventBus or ModContainer and pass them in automatically. @@ -74,6 +78,23 @@ public class ExtendedAEPlus { return ResourceLocation.fromNamespaceAndPath(MODID, path); } + private static void onServerStarted(ServerStartedEvent event) { + storageManagerServer = event.getServer(); + storageManager = InfinityStorageManager.getInstance(event.getServer()); + } + + private static void onServerStopped(ServerStoppedEvent event) { + if (storageManagerServer == event.getServer()) { + storageManagerServer = null; + storageManager = null; + } + } + + @Nullable + public static InfinityStorageManager currentStorageManager() { + return storageManager; + } + private void commonSetup(FMLCommonSetupEvent event) { // Some common setup code LOGGER.info("HELLO FROM COMMON SETUP"); @@ -93,7 +114,7 @@ public class ExtendedAEPlus { ModItems.ENTITY_TICKER_PART_ITEM.get().getPartClass().asSubclass(IPart.class) ) ); - + // 注册自定义 AE2 MenuLocator(用于 Curios 槽位打开菜单) try { appeng.menu.locator.MenuLocators.register( @@ -136,29 +157,6 @@ public class ExtendedAEPlus { }); } - @Nullable - private static InfinityStorageManager storageManager; - - @Nullable - private static MinecraftServer storageManagerServer; - - private static void onServerStarted(ServerStartedEvent event) { - storageManagerServer = event.getServer(); - storageManager = InfinityStorageManager.getInstance(event.getServer()); - } - - private static void onServerStopped(ServerStoppedEvent event) { - if (storageManagerServer == event.getServer()) { - storageManagerServer = null; - storageManager = null; - } - } - - @Nullable - public static InfinityStorageManager currentStorageManager() { - return storageManager; - } - // You can use SubscribeEvent and let the Event Bus discover methods to call @SubscribeEvent public void onServerStarting(ServerStartingEvent event) { diff --git a/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java b/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java index 1ec0691..1899796 100644 --- a/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java +++ b/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java @@ -9,12 +9,12 @@ import com.extendedae_plus.ae.parts.EntitySpeedTickerPart; import com.extendedae_plus.ae.screen.EntitySpeedTickerScreen; import com.extendedae_plus.api.config.EAPSettings; import com.extendedae_plus.config.ModConfigs; -import com.extendedae_plus.init.ModItems; import com.extendedae_plus.init.ModMenuTypes; import com.extendedae_plus.util.entitySpeed.ConfigParsingUtils; import com.extendedae_plus.util.entitySpeed.PowerUtils; import it.unimi.dsi.fastutil.shorts.ShortSet; import net.minecraft.client.Minecraft; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.Slot; import net.minecraft.world.level.block.entity.BlockEntity; @@ -23,25 +23,20 @@ import net.minecraft.world.level.block.entity.BlockEntity; * 实体加速器菜单,负责管理客户端与服务端的数据同步,处理加速卡、能量卡和目标方块的状态。 */ public class EntitySpeedTickerMenu extends UpgradeableMenu { - @GuiSync(716) public YesNo accelerate; // 是否启用加速 - @GuiSync(717) public YesNo redstoneControl; // 是否启用红石控制 - private int entitySpeedCardCount; // 已安装的实体加速卡数量 - @GuiSync(719) public int energyCardCount; // 已安装的能量卡数量 - @GuiSync(720) public int effectiveSpeed = 1; // 当前生效的加速倍率 - @GuiSync(721) public double multiplier = 1.0; // 目标方块的配置倍率 - @GuiSync(722) public boolean targetBlacklisted = false; // 目标方块是否在黑名单中 - @GuiSync(723) public YesNo networkEnergySufficient; // 网络能量是否充足 + private final EntitySpeedTickerPart logic; + @GuiSync(716) public int energyCardCount; // 已安装的能量卡数量 + @GuiSync(717) public int effectiveSpeed = 1; // 当前生效的加速倍率 + @GuiSync(718) public double multiplier = 1.0; // 目标方块的配置倍率 + @GuiSync(719) public boolean targetBlacklisted = false; // 目标方块是否在黑名单中 + @GuiSync(720) public YesNo networkEnergySufficient; // 网络能量是否充足 + @GuiSync(721) private YesNo accelerate; // 是否启用加速 + @GuiSync(722) private YesNo redstoneControl; // 是否启用红石控制 - protected final EntitySpeedTickerPart logic; - - @Override - protected void loadSettingsFromHost(IConfigManager cm) { - // 不需要模糊模式 - } /** * 构造函数,初始化菜单并绑定部件。 - * @param id 菜单ID - * @param ip 玩家背包 + * + * @param id 菜单ID + * @param ip 玩家背包 * @param host 关联的实体加速器部件 */ public EntitySpeedTickerMenu(int id, Inventory ip, EntitySpeedTickerPart host) { @@ -49,32 +44,34 @@ public class EntitySpeedTickerMenu extends UpgradeableMenuCrazy AE2 Addons启发 */ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTickable, MenuProvider, IUpgradeableObject { - public static final ResourceLocation MODEL_BASE = ResourceLocation.fromNamespaceAndPath( + private static final ResourceLocation MODEL_BASE = ResourceLocation.fromNamespaceAndPath( ExtendedAEPlus.MODID, "part/entity_speed_ticker_part"); @PartModels - public static final PartModel MODELS_OFF; + private static final PartModel MODELS_OFF; @PartModels - public static final PartModel MODELS_ON; + private static final PartModel MODELS_ON; @PartModels - public static final PartModel MODELS_HAS_CHANNEL; + private static final PartModel MODELS_HAS_CHANNEL; static { MODELS_OFF = new PartModel(MODEL_BASE, ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "part/entity_speed_ticker_off")); @@ -70,10 +74,9 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka MODELS_HAS_CHANNEL = new PartModel(MODEL_BASE, ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "part/entity_speed_ticker_has_channel")); } - private final IConfigManager configManager; public EntitySpeedTickerMenu menu; // 当前打开的菜单实例 - private YesNo networkEnergySufficient; // 网络能量是否充足 - private YesNo redstoneState = YesNo.UNDECIDED; + private YesNo networkEnergySufficient = YesNo.YES; // 网络能量是否充足 + /** * 构造函数,初始化部件并设置网络节点属性。 * @@ -85,40 +88,66 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka .setFlags(GridFlags.REQUIRE_CHANNEL) .setIdlePowerUsage(1) .addService(IGridTickable.class, this); - configManager = IConfigManager.builder(this::configChanged) - .registerSetting(EAPSettings.ACCELERATE, YesNo.NO) - .registerSetting(EAPSettings.REDSTONE_CONTROL, YesNo.YES) - .build(); } - private void configChanged(IConfigManager manager, Setting setting) { - this.saveChanges(); - } - - public void saveChanges() { - getHost().markForSave(); - } - - public boolean isAccelerate() { - return this.configManager.getSetting(EAPSettings.ACCELERATE) == YesNo.YES; - } - - public boolean isRedstoneControl() { - return this.configManager.getSetting(EAPSettings.REDSTONE_CONTROL) == YesNo.YES; - } - - public boolean isNetworkEnergySufficient() { - return this.networkEnergySufficient == YesNo.YES; + @Override + protected void registerSettings(IConfigManagerBuilder builder) { + super.registerSettings(builder); + builder.registerSetting(EAPSettings.ACCELERATE, YesNo.YES); // 默认开启加速 + builder.registerSetting(EAPSettings.REDSTONE_CONTROL, YesNo.NO); // 默认忽略红石信号 } /** - * 更新网络能量充足状态并通知菜单。 + * 获取可用的升级卡槽数量 * - * @param sufficient 是否能量充足 + * @return 升级卡槽数量 */ - private void setNetworkEnergySufficient(boolean sufficient) { - this.networkEnergySufficient = sufficient ? YesNo.YES : YesNo.NO; - saveChanges(); + @Override + protected int getUpgradeSlots() { + return 8; + } + + // 判断当前是否应该休眠 + @Override + protected boolean isSleeping() { + // 主开关没开 → 休眠 + if (this.getConfigManager().getSetting(EAPSettings.ACCELERATE) != YesNo.YES) { + return true; + } + + // 没开红石控制 → 一直工作 + if (this.getConfigManager().getSetting(EAPSettings.REDSTONE_CONTROL) != YesNo.YES) { + return false; + } + + // 开启了红石控制 → 必须有红石信号才工作 + return !this.getHost().hasRedstone(); // 没信号 → 休眠 + } + + @Override + protected void onSettingChanged(IConfigManager manager, Setting setting) { + // 每次玩家在 GUI 里点任何按钮(包括加速开关、红石控制开关)都会进来这里 + this.getMainNode().ifPresent((grid, node) -> { + if (this.isSleeping()) { + grid.getTickManager().sleepDevice(node); + } else { + grid.getTickManager().wakeDevice(node); + } + }); + } + + @Override + public void onNeighborChanged(BlockGetter level, BlockPos pos, BlockPos neighbor) { + // 只关心红石控制开启的情况下 + if (this.getConfigManager().getSetting(EAPSettings.REDSTONE_CONTROL) == YesNo.YES) { + this.getMainNode().ifPresent((grid, node) -> { + if (this.getHost().hasRedstone()) { + grid.getTickManager().wakeDevice(node); // 有信号 → 立刻唤醒 + } else { + grid.getTickManager().sleepDevice(node); // 没信号 → 立刻休眠 + } + }); + } } /** @@ -130,7 +159,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka */ @Override public final boolean onUseWithoutItem(Player player, Vec3 pos) { - if (!isClientSide()) { + if (!this.isClientSide()) { MenuOpener.open(ModMenuTypes.ENTITY_TICKER_MENU.get(), player, MenuLocators.forPart(this)); } return true; @@ -159,8 +188,30 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka */ @Override public void getBoxes(IPartCollisionHelper bch) { - bch.addBox(2, 2, 14, 14, 14, 16); - bch.addBox(5, 5, 12, 11, 11, 14); + bch.addBox(3, 3, 14, 13, 13, 16); + bch.addBox(5, 5, 11, 11, 11, 14); + } + + public void saveChanges() { + this.getHost().markForSave(); + } + + private boolean isAccelerate() { + return this.getConfigManager().getSetting(EAPSettings.ACCELERATE) == YesNo.YES; + } + + public boolean isNetworkEnergySufficient() { + return this.networkEnergySufficient == YesNo.YES; + } + + /** + * 更新网络能量充足状态并通知菜单。 + * + * @param sufficient 是否能量充足 + */ + private void setNetworkEnergySufficient(boolean sufficient) { + this.networkEnergySufficient = sufficient ? YesNo.YES : YesNo.NO; + this.saveChanges(); } /** @@ -172,7 +223,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka @Override public TickingRequest getTickingRequest(IGridNode iGridNode) { // 每 1 tick 执行一次 - return new TickingRequest(1, 1, false); + return new TickingRequest(1, 1, this.isSleeping()); } /** @@ -184,23 +235,24 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka */ @Override public TickRateModulation tickingRequest(IGridNode iGridNode, int ticksSinceLastCall) { - // 如果部件的加速开关被关闭,则不进行加速(提前返回) - if (!isAccelerate()) { + if (!this.isAccelerate()) { return TickRateModulation.IDLE; } - // 检查红石控制 - if (isRedstoneControl() && !getRedstoneState()) { - // 如果启用了红石控制且没有红石信号,则不执行加速 - return TickRateModulation.IDLE; + if (this.isSleeping()) { + return TickRateModulation.SLEEP; } // 获取目标方块实体(本部件朝向的方块) - BlockEntity target = getLevel().getBlockEntity(getBlockEntity().getBlockPos().relative(getSide())); + BlockEntity target = this.getLevel().getBlockEntity( + this.getBlockEntity().getBlockPos().relative(this.getSide()) + ); // 仅在目标存在且部件处于激活状态时执行加速 - if (target != null && isActive()) { - ticker(target); + if (target == null || !this.isActive()) { + return TickRateModulation.IDLE; } + + this.ticker(target); return TickRateModulation.IDLE; } @@ -211,7 +263,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka * @param 方块实体类型 */ private void ticker(@NotNull T blockEntity) { - if (!isValidForTicking()) { + if (!this.isValidForTicking()) { return; } @@ -220,22 +272,22 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka return; } - BlockEntityTicker ticker = getTicker(blockEntity); + BlockEntityTicker ticker = this.getTicker(blockEntity); if (ticker == null) { return; } - int speed = calculateSpeed(); + int speed = this.calculateSpeed(); if (speed <= 0) { return; } - double requiredPower = calculateRequiredPower(speed, blockId); - if (!extractPower(requiredPower)) { + double requiredPower = this.calculateRequiredPower(speed, blockId); + if (!this.extractPower(requiredPower)) { return; } - performTicks(blockEntity, ticker, speed); + this.performTicks(blockEntity, ticker, speed); } /** @@ -244,7 +296,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka * @return 是否可以执行 tick */ private boolean isValidForTicking() { - return getGridNode() != null && getMainNode() != null && getMainNode().getGrid() != null; + return this.getGridNode() != null && this.getMainNode() != null && this.getMainNode().getGrid() != null; } /** @@ -254,8 +306,8 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka * @return ticker 或 null */ private BlockEntityTicker getTicker(T blockEntity) { - return getLevel().getBlockState(blockEntity.getBlockPos()) - .getTicker(getLevel(), (BlockEntityType) blockEntity.getType()); + return this.getLevel().getBlockState(blockEntity.getBlockPos()) + .getTicker(this.getLevel(), (BlockEntityType) blockEntity.getType()); } /** @@ -264,9 +316,9 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka * @return 生效的加速倍率 */ private int calculateSpeed() { - int entitySpeedCardCount = getUpgrades().getInstalledUpgrades(ModItems.ENTITY_SPEED_CARD.get()); + int entitySpeedCardCount = this.getUpgrades().getInstalledUpgrades(ModItems.ENTITY_SPEED_CARD.get()); if (entitySpeedCardCount <= 0) return 0; - return (int) PowerUtils.computeProductWithCap(getUpgrades(), 8); + return (int) PowerUtils.computeProductWithCap(this.getUpgrades(), 8); } /** @@ -277,7 +329,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka * @return 所需能量 */ private double calculateRequiredPower(int speed, String blockId) { - int energyCardCount = getUpgrades().getInstalledUpgrades(AEItems.ENERGY_CARD); + int energyCardCount = this.getUpgrades().getInstalledUpgrades(AEItems.ENERGY_CARD); double multiplier = ConfigParsingUtils.getMultiplierForBlock(blockId, ModConfigs.ENTITY_TICKER_MULTIPLIERS.get()); return PowerUtils.computeFinalPowerForProduct(speed, energyCardCount) * multiplier; } @@ -289,15 +341,15 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka * @return 是否成功提取足够能量 */ private boolean extractPower(double requiredPower) { - IEnergyService energyService = getMainNode().getGrid().getEnergyService(); - MEStorage storage = getMainNode().getGrid().getStorageService().getInventory(); + IEnergyService energyService = this.getMainNode().getGrid().getEnergyService(); + MEStorage storage = this.getMainNode().getGrid().getStorageService().getInventory(); IActionSource source = IActionSource.ofMachine(this); boolean appFluxLoaded = ModList.get().isLoaded("appflux"); boolean preferDiskEnergy = appFluxLoaded && ModConfigs.PRIORITIZE_DISK_ENERGY.get(); // 如果 appflux 存在且优先磁盘能量,尝试提取 FE 能量 if (appFluxLoaded && preferDiskEnergy) { - if (tryExtractFE(energyService, storage, requiredPower, source)) { + if (this.tryExtractFE(energyService, storage, requiredPower, source)) { return true; } } @@ -307,21 +359,21 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka if (simulated >= requiredPower) { double extracted = energyService.extractAEPower(requiredPower, Actionable.MODULATE, PowerMultiplier.CONFIG); boolean sufficient = extracted >= requiredPower; - setNetworkEnergySufficient(sufficient); + this.setNetworkEnergySufficient(sufficient); return sufficient; } - setNetworkEnergySufficient(false); + this.setNetworkEnergySufficient(false); // 如果 appflux 存在且优先 AE 能量,尝试提取 FE 能量作为备用 if (appFluxLoaded && !preferDiskEnergy) { - return tryExtractFE(energyService, storage, requiredPower, source); + return this.tryExtractFE(energyService, storage, requiredPower, source); } return false; } private boolean tryExtractFE(IEnergyService energyService, MEStorage storage, double requiredPower, IActionSource source) { try { - Class helperClass = Class.forName("com.extendedae_plus.util.FluxEnergyHelper"); + Class helperClass = Class.forName("com.extendedae_plus.util.entitySpeed.FluxEnergyHelper"); Method extractMethod = helperClass.getMethod( "extractFE", IEnergyService.class, @@ -332,13 +384,13 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka long feRequired = (long) requiredPower << 1; // 1 AE = 2 FE long feExtracted = (long) extractMethod.invoke(null, energyService, storage, feRequired, source); if (feExtracted >= feRequired) { - setNetworkEnergySufficient(true); + this.setNetworkEnergySufficient(true); return true; } } catch (Exception e) { // 如果反射失败,视为 FE 不可用 } - setNetworkEnergySufficient(false); + this.setNetworkEnergySufficient(false); return false; } @@ -354,12 +406,41 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka int speed) { // 执行 speed-1 次额外 tick(原生 tick 已包含 1 次) for (int i = 0; i < speed - 1; i++) { - ticker.tick( - blockEntity.getLevel(), - blockEntity.getBlockPos(), - blockEntity.getBlockState(), - blockEntity - ); + try { + ticker.tick( + blockEntity.getLevel(), + blockEntity.getBlockPos(), + blockEntity.getBlockState(), + blockEntity + ); + } catch (IllegalStateException e) { + // 捕获随机数生成器的多线程访问异常 + // 这通常发生在某些模组(如 Thermal)的机器使用随机数时 + // 由于加速导致在同一tick内多次访问随机数生成器而触发 ThreadingDetector + if (e.getMessage() != null && e.getMessage().contains("LegacyRandomSource")) { + // 记录警告并停止当前加速循环,避免崩溃 + ExtendedAELogger.LOGGER.warn( + "检测到方块实体 {} 在位置 {} 的随机数访问冲突,已停止本次加速以避免崩溃。" + + "建议将此方块类型添加到配置黑名单中。", + blockEntity.getType().toString(), + blockEntity.getBlockPos() + ); + break; // 停止后续的加速 tick + } else { + // 如果是其他类型的 IllegalStateException,继续抛出 + throw e; + } + } catch (Exception e) { + // 捕获其他可能的异常,防止崩溃 + ExtendedAELogger.LOGGER.error( + "在加速方块实体 {} 位置 {} 时发生错误: {}", + blockEntity.getType().toString(), + blockEntity.getBlockPos(), + e.getMessage(), + e + ); + break; // 停止后续的加速 tick + } } } @@ -397,46 +478,4 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka @NotNull Player player) { return new EntitySpeedTickerMenu(containerId, playerInventory, this); } - - /** - * 获取可用的升级卡槽数量 - * - * @return 升级卡槽数量 - */ - @Override - protected int getUpgradeSlots() { - return 8; - } - - /** - * 当升级卡数量发生变化时调用,通知菜单更新 - */ - @Override - public void upgradesChanged() { - if (this.menu != null) { - // 使用 AE2 风格:当升级发生变化时让菜单广播变化(槽/数据会被同步),客户端会基于槽内容重新计算并刷新界面 - this.menu.broadcastChanges(); - } - } - - public IConfigManager getConfigManager() { - return this.configManager; - } - - // 获取红石信号状态 - private boolean getRedstoneState() { - // 每次调用都更新红石状态,确保及时性 - updateRedstoneState(); - return redstoneState == YesNo.YES; - } - - // 更新红石信号状态 - private void updateRedstoneState() { - var be = this.getHost().getBlockEntity(); - if (be != null && be.getLevel() != null) { - redstoneState = be.getLevel().hasNeighborSignal(be.getBlockPos()) - ? YesNo.YES - : YesNo.NO; - } - } } \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/ae/screen/EntitySpeedTickerScreen.java b/src/main/java/com/extendedae_plus/ae/screen/EntitySpeedTickerScreen.java index 834b616..60ebc50 100644 --- a/src/main/java/com/extendedae_plus/ae/screen/EntitySpeedTickerScreen.java +++ b/src/main/java/com/extendedae_plus/ae/screen/EntitySpeedTickerScreen.java @@ -11,16 +11,13 @@ import com.extendedae_plus.api.config.EAPSettings; import com.extendedae_plus.client.gui.widgets.EAPServerSettingToggleButton; import com.extendedae_plus.client.gui.widgets.EAPSettingToggleButton; import com.extendedae_plus.util.entitySpeed.PowerUtils; -import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.player.Inventory; -import java.util.HashMap; -import java.util.Map; - public class EntitySpeedTickerScreen extends UpgradeableScreen { private final EAPSettingToggleButton accelerateButton; // 加速开关按钮 private final EAPSettingToggleButton redstoneControlButton; // 加速开关按钮 + private final TextUpdater textUpdater = new TextUpdater(); /** * 构造函数,初始化界面和控件。 @@ -37,7 +34,7 @@ public class EntitySpeedTickerScreen extends UpgradeableScreen(EAPSettings.ACCELERATE, YesNo.NO); + this.accelerateButton = new EAPServerSettingToggleButton<>(EAPSettings.ACCELERATE, YesNo.YES); this.addToLeftToolbar(this.accelerateButton); this.redstoneControlButton = new EAPServerSettingToggleButton<>(EAPSettings.REDSTONE_CONTROL, YesNo.NO); @@ -54,47 +51,55 @@ public class EntitySpeedTickerScreen extends UpgradeableScreen textContents = new HashMap<>(); - if (this.getMenu().targetBlacklisted) { - // 黑名单禁用时的默认显示 - textContents.put("enable", Component.translatable("screen.extendedae_plus.entity_speed_ticker.enable")); - textContents.put("speed", Component.translatable("screen.extendedae_plus.entity_speed_ticker.speed", 0)); - textContents.put("energy", Component.translatable("screen.extendedae_plus.entity_speed_ticker.energy", Platform.formatPower(0.0, false))); - textContents.put("power_ratio", Component.translatable("screen.extendedae_plus.entity_speed_ticker.power_ratio", PowerUtils.formatPercentage(0.0))); - textContents.put("multiplier", Component.translatable("screen.extendedae_plus.entity_speed_ticker.multiplier", String.format("%.2fx", 0.0))); - } else { - // 正常状态下显示实际数据 - int energyCardCount = this.getMenu().energyCardCount; - double multiplier = this.getMenu().multiplier; - int effectiveSpeed = this.getMenu().effectiveSpeed; - double finalPower = PowerUtils.computeFinalPowerForProduct(effectiveSpeed, energyCardCount); - double remainingRatio = PowerUtils.getRemainingRatio(energyCardCount); - - textContents.put("enable", this.getMenu().networkEnergySufficient == YesNo.YES ? null : - Component.translatable("screen.extendedae_plus.entity_speed_ticker.warning_network_energy_insufficient")); - textContents.put("speed", Component.translatable("screen.extendedae_plus.entity_speed_ticker.speed", effectiveSpeed)); - textContents.put("energy", Component.translatable("screen.extendedae_plus.entity_speed_ticker.energy", Platform.formatPower(finalPower, false))); - textContents.put("power_ratio", Component.translatable("screen.extendedae_plus.entity_speed_ticker.power_ratio", PowerUtils.formatPercentage(remainingRatio))); - textContents.put("multiplier", Component.translatable("screen.extendedae_plus.entity_speed_ticker.multiplier", String.format("%.2fx", multiplier))); + private class TextUpdater { + void update() { + if (EntitySpeedTickerScreen.this.menu.targetBlacklisted) { + this.updateBlacklist(); + } else { + this.updateNormal(); + } + } + + private void updateBlacklist() { + this.set("enable", this.translatable("enable")); + this.set("speed", this.translatable("speed", 0)); + this.set("energy", this.translatable("energy", Platform.formatPower(0, false))); + this.set("power_ratio", this.translatable("power_ratio", PowerUtils.formatPercentage(0.0))); + this.set("multiplier", this.translatable("multiplier", "0.00x")); + } + + private void updateNormal() { + int energyCardCount = EntitySpeedTickerScreen.this.menu.energyCardCount; + double multiplier = EntitySpeedTickerScreen.this.menu.multiplier; + int effectiveSpeed = EntitySpeedTickerScreen.this.menu.effectiveSpeed; + double finalPower = PowerUtils.computeFinalPowerForProduct(effectiveSpeed, energyCardCount); + double powerRatio = PowerUtils.getRemainingRatio(energyCardCount); + + this.set("enable", EntitySpeedTickerScreen.this.menu.networkEnergySufficient == YesNo.YES + ? null + : this.translatable("warning_network_energy_insufficient")); + + this.set("speed", this.translatable("speed", effectiveSpeed)); + this.set("energy", this.translatable("energy", Platform.formatPower(finalPower, false))); + this.set("power_ratio", this.translatable("power_ratio", PowerUtils.formatPercentage(powerRatio))); + this.set("multiplier", this.translatable("multiplier", String.format("%.2fx", multiplier))); + } + + private Component translatable(String key, Object... args) { + return Component.translatable("screen.extendedae_plus.entity_speed_ticker." + key, args); + } + + private void set(String id, Component c) { + EntitySpeedTickerScreen.this.setTextContent(id, c); } - textContents.forEach(this::setTextContent); } } \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/wireless/IWirelessEndpoint.java b/src/main/java/com/extendedae_plus/ae/wireless/IWirelessEndpoint.java similarity index 94% rename from src/main/java/com/extendedae_plus/wireless/IWirelessEndpoint.java rename to src/main/java/com/extendedae_plus/ae/wireless/IWirelessEndpoint.java index 15a991b..d21ebae 100644 --- a/src/main/java/com/extendedae_plus/wireless/IWirelessEndpoint.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/IWirelessEndpoint.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.wireless; +package com.extendedae_plus.ae.wireless; import appeng.api.networking.IGridNode; import net.minecraft.core.BlockPos; diff --git a/src/main/java/com/extendedae_plus/wireless/WirelessMasterLink.java b/src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterLink.java similarity index 62% rename from src/main/java/com/extendedae_plus/wireless/WirelessMasterLink.java rename to src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterLink.java index 6bf58ec..75e1b9e 100644 --- a/src/main/java/com/extendedae_plus/wireless/WirelessMasterLink.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterLink.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.wireless; +package com.extendedae_plus.ae.wireless; import net.minecraft.server.level.ServerLevel; import org.jetbrains.annotations.Nullable; @@ -24,13 +24,13 @@ public class WirelessMasterLink { this.placerId = placerId; } - public long getFrequency() { return frequency; } + public long getFrequency() {return this.frequency;} public void setFrequency(long frequency) { // 如果频率发生变化,先撤销旧频率的注册 if (this.frequency != frequency) { - if (registered) { - unregister(); + if (this.registered) { + this.unregister(); } this.frequency = frequency; } @@ -38,35 +38,35 @@ public class WirelessMasterLink { // 频率未变的情况下也要校正注册状态: // - 当从"从端"切回"主端"时,registered 可能为 false,需要重新注册; // - 当频率为 0 或端点被移除时,确保处于未注册。 - if (frequency != 0L && !host.isEndpointRemoved()) { - if (!registered) { - register(); + if (frequency != 0L && !this.host.isEndpointRemoved()) { + if (!this.registered) { + this.register(); } } else { - if (registered) { - unregister(); + if (this.registered) { + this.unregister(); } } } public boolean register() { - ServerLevel level = host.getServerLevel(); - if (level == null || frequency == 0L) return false; + ServerLevel level = this.host.getServerLevel(); + if (level == null || this.frequency == 0L) return false; // placerId可以为null(公共收发器模式) - boolean ok = WirelessMasterRegistry.register(level, frequency, placerId, host); + boolean ok = WirelessMasterRegistry.register(level, this.frequency, this.placerId, this.host); this.registered = ok; return ok; } - public void unregister() { - ServerLevel level = host.getServerLevel(); - if (!registered || level == null || frequency == 0L) return; + private void unregister() { + ServerLevel level = this.host.getServerLevel(); + if (!this.registered || level == null || this.frequency == 0L) return; // placerId可以为null(公共收发器模式) - WirelessMasterRegistry.unregister(level, frequency, placerId, host); - registered = false; + WirelessMasterRegistry.unregister(level, this.frequency, this.placerId, this.host); + this.registered = false; } public void onUnloadOrRemove() { - unregister(); + this.unregister(); } } diff --git a/src/main/java/com/extendedae_plus/wireless/WirelessMasterRegistry.java b/src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterRegistry.java similarity index 89% rename from src/main/java/com/extendedae_plus/wireless/WirelessMasterRegistry.java rename to src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterRegistry.java index 7d26771..40525b4 100644 --- a/src/main/java/com/extendedae_plus/wireless/WirelessMasterRegistry.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterRegistry.java @@ -1,7 +1,7 @@ -package com.extendedae_plus.wireless; +package com.extendedae_plus.ae.wireless; import com.extendedae_plus.config.ModConfigs; -import com.extendedae_plus.util.WirelessTeamUtil; +import com.extendedae_plus.util.wireless.WirelessTeamUtil; import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; @@ -20,15 +20,14 @@ import java.util.UUID; * 公共模式:placerId为null时使用公共UUID,所有人都能访问(向下兼容旧版本)。 */ public final class WirelessMasterRegistry { - private WirelessMasterRegistry() {} - private static final Map> MASTERS = new HashMap<>(); - /** * 公共收发器UUID(用于没有设置所有者的收发器) * 所有placerId为null的收发器都使用这个UUID,实现公共访问 */ - public static final UUID PUBLIC_NETWORK_UUID = new UUID(0, 0); + private static final UUID PUBLIC_NETWORK_UUID = new UUID(0, 0); + + private WirelessMasterRegistry() {} public static synchronized boolean register(ServerLevel level, long frequency, @Nullable UUID placerId, IWirelessEndpoint endpoint) { Objects.requireNonNull(level, "level"); @@ -54,7 +53,7 @@ public final class WirelessMasterRegistry { return true; } - public static synchronized void unregister(ServerLevel level, long frequency, @Nullable UUID placerId, IWirelessEndpoint endpoint) { + static synchronized void unregister(ServerLevel level, long frequency, @Nullable UUID placerId, IWirelessEndpoint endpoint) { if (frequency == 0L || level == null) return; UUID ownerUUID = placerId != null @@ -100,9 +99,9 @@ public final class WirelessMasterRegistry { private record Key(@Nullable ResourceKey dim, long freq, UUID owner) { @Override public String toString() { - return (dim == null ? "*" : dim.location().toString()) - + "#" + freq - + "@" + owner; + return (this.dim == null ? "*" : this.dim.location().toString()) + + "#" + this.freq + + "@" + this.owner; } } } diff --git a/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java b/src/main/java/com/extendedae_plus/ae/wireless/WirelessSlaveLink.java similarity index 77% rename from src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java rename to src/main/java/com/extendedae_plus/ae/wireless/WirelessSlaveLink.java index da22fd9..fa7ea22 100644 --- a/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/WirelessSlaveLink.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.wireless; +package com.extendedae_plus.ae.wireless; import appeng.api.networking.GridHelper; import appeng.api.networking.IGridConnection; @@ -35,59 +35,59 @@ public class WirelessSlaveLink { this.placerId = placerId; } + public long getFrequency() { + return this.frequency; + } + public void setFrequency(long frequency) { if (this.frequency != frequency) { this.frequency = frequency; // 频率变更,立即尝试重连/断开 - updateStatus(); + this.updateStatus(); } } - public long getFrequency() { - return frequency; - } - public boolean isConnected() { - return !shutdown && connection.getConnection() != null; + return !this.shutdown && this.connection.getConnection() != null; } public double getDistance() { - return distance; + return this.distance; } /** * 建议在 BE 的 serverTick 或者频率/加载状态变化时调用。 */ public void updateStatus() { - if (host.isEndpointRemoved()) { - destroyConnection(); + if (this.host.isEndpointRemoved()) { + this.destroyConnection(); return; } - final ServerLevel level = host.getServerLevel(); - if (level == null || frequency == 0L) { - destroyConnection(); + final ServerLevel level = this.host.getServerLevel(); + if (level == null || this.frequency == 0L) { + this.destroyConnection(); return; } // placerId可以为null(公共收发器模式) - IWirelessEndpoint master = WirelessMasterRegistry.get(level, frequency, placerId); - shutdown = false; - distance = 0.0D; + IWirelessEndpoint master = WirelessMasterRegistry.get(level, this.frequency, this.placerId); + this.shutdown = false; + this.distance = 0.0D; boolean crossDim = ModConfigs.WIRELESS_CROSS_DIM_ENABLE.get(); if (master != null && !master.isEndpointRemoved() && (crossDim || master.getServerLevel() == level)) { if (!crossDim) { - distance = Math.sqrt(master.getBlockPos().distSqr(host.getBlockPos())); + this.distance = Math.sqrt(master.getBlockPos().distSqr(this.host.getBlockPos())); } double maxRange = ModConfigs.WIRELESS_MAX_RANGE.get(); - if (crossDim || distance <= maxRange) { + if (crossDim || this.distance <= maxRange) { // 保持/建立连接 try { - var current = connection.getConnection(); - IGridNode a = host.getGridNode(); // 从端 + var current = this.connection.getConnection(); + IGridNode a = this.host.getGridNode(); // 从端 IGridNode b = master.getGridNode(); // 主端 if (a == null || b == null) { - shutdown = true; + this.shutdown = true; } else { if (current != null) { // 如果已连且目标相同则维持 @@ -98,37 +98,37 @@ public class WirelessSlaveLink { } // 否则先断开,再重建 current.destroy(); - connection = new ConnectionWrapper(null); + this.connection = new ConnectionWrapper(null); } // AE2 侧是否已经存在连接(例如此前创建但 wrapper 丢失) - IGridConnection existing = findExistingConnection(a, b); + IGridConnection existing = this.findExistingConnection(a, b); if (existing != null) { - connection = new ConnectionWrapper(existing); + this.connection = new ConnectionWrapper(existing); return; } - connection = new ConnectionWrapper(GridHelper.createConnection(a, b)); + this.connection = new ConnectionWrapper(GridHelper.createConnection(a, b)); return; } } catch (IllegalStateException ex) { // 连接非法(如重复连接等)——落入重建/关闭逻辑 } } else { - shutdown = true; // 超出范围 + this.shutdown = true; // 超出范围 } } else { - shutdown = true; // 无主或主端不可用 + this.shutdown = true; // 无主或主端不可用 } // 需要关闭连接 - destroyConnection(); + this.destroyConnection(); } public void onUnloadOrRemove() { - destroyConnection(); + this.destroyConnection(); } private void destroyConnection() { - var current = connection.getConnection(); + var current = this.connection.getConnection(); if (current != null) { var a = current.a(); var b = current.b(); @@ -144,11 +144,11 @@ public class WirelessSlaveLink { b.getGrid().getTickManager().wakeDevice(b); } } catch (Throwable ignored) {} - connection.setConnection(null); + this.connection.setConnection(null); } else { // 兜底:如果 wrapper 已丢失,但 AE2 内仍有直连,则尝试查找并销毁 try { - IGridNode a = host.getGridNode(); + IGridNode a = this.host.getGridNode(); if (a != null) { for (IGridConnection gc : a.getConnections()) { // 我们创建的是非 in-world 直连 @@ -165,7 +165,7 @@ public class WirelessSlaveLink { } } catch (Throwable ignored) {} } - connection = new ConnectionWrapper(null); + this.connection = new ConnectionWrapper(null); } /** diff --git a/src/main/java/com/extendedae_plus/wireless/endpoint/GenericNodeEndpointImpl.java b/src/main/java/com/extendedae_plus/ae/wireless/endpoint/GenericNodeEndpointImpl.java similarity index 81% rename from src/main/java/com/extendedae_plus/wireless/endpoint/GenericNodeEndpointImpl.java rename to src/main/java/com/extendedae_plus/ae/wireless/endpoint/GenericNodeEndpointImpl.java index 84cd191..7280af3 100644 --- a/src/main/java/com/extendedae_plus/wireless/endpoint/GenericNodeEndpointImpl.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/endpoint/GenericNodeEndpointImpl.java @@ -1,7 +1,7 @@ -package com.extendedae_plus.wireless.endpoint; +package com.extendedae_plus.ae.wireless.endpoint; import appeng.api.networking.IGridNode; -import com.extendedae_plus.wireless.IWirelessEndpoint; +import com.extendedae_plus.ae.wireless.IWirelessEndpoint; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; @@ -24,7 +24,7 @@ public class GenericNodeEndpointImpl implements IWirelessEndpoint { @Override public ServerLevel getServerLevel() { - var be = blockEntitySupplier.get(); + var be = this.blockEntitySupplier.get(); if (be == null) return null; Level lvl = be.getLevel(); return (lvl instanceof ServerLevel) ? (ServerLevel) lvl : null; @@ -32,18 +32,18 @@ public class GenericNodeEndpointImpl implements IWirelessEndpoint { @Override public BlockPos getBlockPos() { - var be = blockEntitySupplier.get(); + var be = this.blockEntitySupplier.get(); return be != null ? be.getBlockPos() : BlockPos.ZERO; } @Override public IGridNode getGridNode() { - return nodeSupplier.get(); + return this.nodeSupplier.get(); } @Override public boolean isEndpointRemoved() { - var be = blockEntitySupplier.get(); + var be = this.blockEntitySupplier.get(); return be == null || be.isRemoved(); } } diff --git a/src/main/java/com/extendedae_plus/wireless/endpoint/InterfaceNodeEndpointImpl.java b/src/main/java/com/extendedae_plus/ae/wireless/endpoint/InterfaceNodeEndpointImpl.java similarity index 81% rename from src/main/java/com/extendedae_plus/wireless/endpoint/InterfaceNodeEndpointImpl.java rename to src/main/java/com/extendedae_plus/ae/wireless/endpoint/InterfaceNodeEndpointImpl.java index 6736f4c..c98e656 100644 --- a/src/main/java/com/extendedae_plus/wireless/endpoint/InterfaceNodeEndpointImpl.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/endpoint/InterfaceNodeEndpointImpl.java @@ -1,8 +1,8 @@ -package com.extendedae_plus.wireless.endpoint; +package com.extendedae_plus.ae.wireless.endpoint; import appeng.api.networking.IGridNode; import appeng.helpers.InterfaceLogicHost; -import com.extendedae_plus.wireless.IWirelessEndpoint; +import com.extendedae_plus.ae.wireless.IWirelessEndpoint; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; @@ -24,7 +24,7 @@ public class InterfaceNodeEndpointImpl implements IWirelessEndpoint { @Override public ServerLevel getServerLevel() { - var be = host.getBlockEntity(); + var be = this.host.getBlockEntity(); if (be == null) return null; Level lvl = be.getLevel(); return (lvl instanceof ServerLevel) ? (ServerLevel) lvl : null; @@ -32,18 +32,18 @@ public class InterfaceNodeEndpointImpl implements IWirelessEndpoint { @Override public BlockPos getBlockPos() { - var be = host.getBlockEntity(); + var be = this.host.getBlockEntity(); return be != null ? be.getBlockPos() : BlockPos.ZERO; } @Override public IGridNode getGridNode() { - return nodeSupplier.get(); + return this.nodeSupplier.get(); } @Override public boolean isEndpointRemoved() { - var be = host.getBlockEntity(); + var be = this.host.getBlockEntity(); return be == null || be.isRemoved(); } } diff --git a/src/main/java/com/extendedae_plus/api/ExPatternButtonsAccessor.java b/src/main/java/com/extendedae_plus/api/IExPatternButton.java similarity index 88% rename from src/main/java/com/extendedae_plus/api/ExPatternButtonsAccessor.java rename to src/main/java/com/extendedae_plus/api/IExPatternButton.java index d97f448..f71052a 100644 --- a/src/main/java/com/extendedae_plus/api/ExPatternButtonsAccessor.java +++ b/src/main/java/com/extendedae_plus/api/IExPatternButton.java @@ -3,7 +3,7 @@ package com.extendedae_plus.api; /** * 由 {@code GuiExPatternProviderMixin} 实现,用于从通用的 Screen Mixin 中更新按钮布局。 */ -public interface ExPatternButtonsAccessor { +public interface IExPatternButton { /** * 在每帧调用以维护扩展样板供应器右侧按钮的可见性、重注册(窗口尺寸变化)与定位。 */ diff --git a/src/main/java/com/extendedae_plus/api/ExPatternPageAccessor.java b/src/main/java/com/extendedae_plus/api/IExPatternPage.java similarity index 83% rename from src/main/java/com/extendedae_plus/api/ExPatternPageAccessor.java rename to src/main/java/com/extendedae_plus/api/IExPatternPage.java index fca633f..676b9f3 100644 --- a/src/main/java/com/extendedae_plus/api/ExPatternPageAccessor.java +++ b/src/main/java/com/extendedae_plus/api/IExPatternPage.java @@ -3,6 +3,6 @@ package com.extendedae_plus.api; /** * 由 GuiExPatternProviderMixin 实现,用于在客户端侧提供当前页号,避免反射读取 AE2 内部字段失败。 */ -public interface ExPatternPageAccessor { +public interface IExPatternPage { int eap$getCurrentPage(); } diff --git a/src/main/java/com/extendedae_plus/util/IStyleAccessor.java b/src/main/java/com/extendedae_plus/api/IStyleAccessor.java similarity index 87% rename from src/main/java/com/extendedae_plus/util/IStyleAccessor.java rename to src/main/java/com/extendedae_plus/api/IStyleAccessor.java index 1b47c25..44a37c0 100644 --- a/src/main/java/com/extendedae_plus/util/IStyleAccessor.java +++ b/src/main/java/com/extendedae_plus/api/IStyleAccessor.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.util; +package com.extendedae_plus.api; import appeng.client.gui.style.Blitter; import appeng.client.gui.style.WidgetStyle; diff --git a/src/main/java/com/extendedae_plus/api/PatternProviderMenuAdvancedSync.java b/src/main/java/com/extendedae_plus/api/PatternProviderMenuAdvancedSync.java deleted file mode 100644 index f43f52c..0000000 --- a/src/main/java/com/extendedae_plus/api/PatternProviderMenuAdvancedSync.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.extendedae_plus.api; - -public interface PatternProviderMenuAdvancedSync { - boolean eap$getAdvancedBlockingSynced(); -} diff --git a/src/main/java/com/extendedae_plus/api/PatternProviderMenuDoublingSync.java b/src/main/java/com/extendedae_plus/api/PatternProviderMenuDoublingSync.java deleted file mode 100644 index a9d1492..0000000 --- a/src/main/java/com/extendedae_plus/api/PatternProviderMenuDoublingSync.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.extendedae_plus.api; - -public interface PatternProviderMenuDoublingSync { - boolean eap$getSmartDoublingSynced(); -} diff --git a/src/main/java/com/extendedae_plus/api/SmartDoublingAwarePattern.java b/src/main/java/com/extendedae_plus/api/SmartDoublingAwarePattern.java deleted file mode 100644 index 5c18658..0000000 --- a/src/main/java/com/extendedae_plus/api/SmartDoublingAwarePattern.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.extendedae_plus.api; - -public interface SmartDoublingAwarePattern { - boolean eap$allowScaling(); - void eap$setAllowScaling(boolean allow); -} diff --git a/src/main/java/com/extendedae_plus/api/AdvancedBlockingHolder.java b/src/main/java/com/extendedae_plus/api/advancedBlocking/IAdvancedBlocking.java similarity index 51% rename from src/main/java/com/extendedae_plus/api/AdvancedBlockingHolder.java rename to src/main/java/com/extendedae_plus/api/advancedBlocking/IAdvancedBlocking.java index 52b8aaa..962f11a 100644 --- a/src/main/java/com/extendedae_plus/api/AdvancedBlockingHolder.java +++ b/src/main/java/com/extendedae_plus/api/advancedBlocking/IAdvancedBlocking.java @@ -1,6 +1,6 @@ -package com.extendedae_plus.api; +package com.extendedae_plus.api.advancedBlocking; -public interface AdvancedBlockingHolder { +public interface IAdvancedBlocking { boolean eap$getAdvancedBlocking(); void eap$setAdvancedBlocking(boolean value); diff --git a/src/main/java/com/extendedae_plus/api/advancedBlocking/IPatternProviderMenuAdvancedSync.java b/src/main/java/com/extendedae_plus/api/advancedBlocking/IPatternProviderMenuAdvancedSync.java new file mode 100644 index 0000000..6c06afc --- /dev/null +++ b/src/main/java/com/extendedae_plus/api/advancedBlocking/IPatternProviderMenuAdvancedSync.java @@ -0,0 +1,5 @@ +package com.extendedae_plus.api.advancedBlocking; + +public interface IPatternProviderMenuAdvancedSync { + boolean eap$getAdvancedBlockingSynced(); +} diff --git a/src/main/java/com/extendedae_plus/bridge/CompatUpgradeProvider.java b/src/main/java/com/extendedae_plus/api/bridge/CompatUpgradeProvider.java similarity index 87% rename from src/main/java/com/extendedae_plus/bridge/CompatUpgradeProvider.java rename to src/main/java/com/extendedae_plus/api/bridge/CompatUpgradeProvider.java index a221c7e..15e4d26 100644 --- a/src/main/java/com/extendedae_plus/bridge/CompatUpgradeProvider.java +++ b/src/main/java/com/extendedae_plus/api/bridge/CompatUpgradeProvider.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.bridge; +package com.extendedae_plus.api.bridge; import appeng.api.upgrades.IUpgradeInventory; diff --git a/src/main/java/com/extendedae_plus/bridge/IUpgradableMenu.java b/src/main/java/com/extendedae_plus/api/bridge/IUpgradableMenu.java similarity index 89% rename from src/main/java/com/extendedae_plus/bridge/IUpgradableMenu.java rename to src/main/java/com/extendedae_plus/api/bridge/IUpgradableMenu.java index 63d56f6..b5cb950 100644 --- a/src/main/java/com/extendedae_plus/bridge/IUpgradableMenu.java +++ b/src/main/java/com/extendedae_plus/api/bridge/IUpgradableMenu.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.bridge; +package com.extendedae_plus.api.bridge; import appeng.menu.ToolboxMenu; diff --git a/src/main/java/com/extendedae_plus/bridge/InterfaceWirelessLinkBridge.java b/src/main/java/com/extendedae_plus/api/bridge/InterfaceWirelessLinkBridge.java similarity index 97% rename from src/main/java/com/extendedae_plus/bridge/InterfaceWirelessLinkBridge.java rename to src/main/java/com/extendedae_plus/api/bridge/InterfaceWirelessLinkBridge.java index a9be54b..efab742 100644 --- a/src/main/java/com/extendedae_plus/bridge/InterfaceWirelessLinkBridge.java +++ b/src/main/java/com/extendedae_plus/api/bridge/InterfaceWirelessLinkBridge.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.bridge; +package com.extendedae_plus.api.bridge; /** * 非 mixin 包下的桥接接口,供 mixin 进行 instanceof 检测和回调。 diff --git a/src/main/java/com/extendedae_plus/content/ScaledProcessingPattern.java b/src/main/java/com/extendedae_plus/api/crafting/ScaledProcessingPattern.java similarity index 87% rename from src/main/java/com/extendedae_plus/content/ScaledProcessingPattern.java rename to src/main/java/com/extendedae_plus/api/crafting/ScaledProcessingPattern.java index 353199a..6c3911d 100644 --- a/src/main/java/com/extendedae_plus/content/ScaledProcessingPattern.java +++ b/src/main/java/com/extendedae_plus/api/crafting/ScaledProcessingPattern.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.content; +package com.extendedae_plus.api.crafting; import appeng.api.crafting.IPatternDetails; import appeng.api.stacks.AEItemKey; @@ -46,54 +46,46 @@ public final class ScaledProcessingPattern implements IPatternDetails { /* -------------------- API 实现 -------------------- */ public AEProcessingPattern getOriginal() { - return original; + return this.original; } @Override public AEItemKey getDefinition() { - return definition; + return this.definition; } @Override public IInput[] getInputs() { - return inputs; - } - - @Override - public List getOutputs() { - return condensedOutputs; - } - - public List getSparseInputs() { - return sparseInputs; - } - - public List getSparseOutputs() { - return sparseOutputs; + return this.inputs; } @Override public GenericStack getPrimaryOutput() { - if (!condensedOutputs.isEmpty()) return condensedOutputs.get(0); - return original.getPrimaryOutput(); + if (!this.condensedOutputs.isEmpty()) return this.condensedOutputs.get(0); + return this.original.getPrimaryOutput(); + } + + @Override + public List getOutputs() { + return this.condensedOutputs; } @Override public boolean supportsPushInputsToExternalInventory() { - return original.supportsPushInputsToExternalInventory(); + return this.original.supportsPushInputsToExternalInventory(); } @Override public void pushInputsToExternalInventory(KeyCounter[] inputHolder, PatternInputSink inputSink) { // 保持和 AEProcessingPattern 一致,用 sparseInputs 驱动 - if (sparseInputs.size() == inputs.length) { + if (this.sparseInputs.size() == this.inputs.length) { IPatternDetails.super.pushInputsToExternalInventory(inputHolder, inputSink); } else { KeyCounter allInputs = new KeyCounter(); for (KeyCounter counter : inputHolder) { allInputs.addAll(counter); } - for (GenericStack sparseInput : sparseInputs) { + for (GenericStack sparseInput : this.sparseInputs) { if (sparseInput != null) { AEKey key = sparseInput.what(); long amount = sparseInput.amount(); @@ -109,6 +101,14 @@ public final class ScaledProcessingPattern implements IPatternDetails { } } + public List getSparseInputs() { + return this.sparseInputs; + } + + public List getSparseOutputs() { + return this.sparseOutputs; + } + /* -------------------- 缩放输入代理 -------------------- */ public static final class Input implements IPatternDetails.IInput { @@ -120,18 +120,22 @@ public final class ScaledProcessingPattern implements IPatternDetails { this.multiplier = multiplier; } + @Override public GenericStack[] getPossibleInputs() { return this.template; } + @Override public long getMultiplier() { return this.multiplier; } + @Override public boolean isValid(AEKey input, Level level) { return input.matches(this.template[0]); } + @Override public @Nullable AEKey getRemainingKey(AEKey template) { return null; } diff --git a/src/main/java/com/extendedae_plus/api/smartDoubling/ICraftingCalculationExt.java b/src/main/java/com/extendedae_plus/api/smartDoubling/ICraftingCalculationExt.java new file mode 100644 index 0000000..55c707a --- /dev/null +++ b/src/main/java/com/extendedae_plus/api/smartDoubling/ICraftingCalculationExt.java @@ -0,0 +1,7 @@ +package com.extendedae_plus.api.smartDoubling; + +import appeng.api.networking.IGrid; + +public interface ICraftingCalculationExt { + IGrid getGrid(); +} diff --git a/src/main/java/com/extendedae_plus/api/smartDoubling/IPatternProviderMenuDoublingSync.java b/src/main/java/com/extendedae_plus/api/smartDoubling/IPatternProviderMenuDoublingSync.java new file mode 100644 index 0000000..8160d05 --- /dev/null +++ b/src/main/java/com/extendedae_plus/api/smartDoubling/IPatternProviderMenuDoublingSync.java @@ -0,0 +1,5 @@ +package com.extendedae_plus.api.smartDoubling; + +public interface IPatternProviderMenuDoublingSync { + boolean eap$getSmartDoublingSynced(); +} diff --git a/src/main/java/com/extendedae_plus/api/SmartDoublingHolder.java b/src/main/java/com/extendedae_plus/api/smartDoubling/ISmartDoubling.java similarity index 51% rename from src/main/java/com/extendedae_plus/api/SmartDoublingHolder.java rename to src/main/java/com/extendedae_plus/api/smartDoubling/ISmartDoubling.java index b5af4ef..8e36f4e 100644 --- a/src/main/java/com/extendedae_plus/api/SmartDoublingHolder.java +++ b/src/main/java/com/extendedae_plus/api/smartDoubling/ISmartDoubling.java @@ -1,6 +1,6 @@ -package com.extendedae_plus.api; +package com.extendedae_plus.api.smartDoubling; -public interface SmartDoublingHolder { +public interface ISmartDoubling { boolean eap$getSmartDoubling(); void eap$setSmartDoubling(boolean value); } diff --git a/src/main/java/com/extendedae_plus/api/smartDoubling/ISmartDoublingAwarePattern.java b/src/main/java/com/extendedae_plus/api/smartDoubling/ISmartDoublingAwarePattern.java new file mode 100644 index 0000000..c62dc81 --- /dev/null +++ b/src/main/java/com/extendedae_plus/api/smartDoubling/ISmartDoublingAwarePattern.java @@ -0,0 +1,6 @@ +package com.extendedae_plus.api.smartDoubling; + +public interface ISmartDoublingAwarePattern { + boolean eap$allowScaling(); + void eap$setAllowScaling(boolean allow); +} diff --git a/src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellHandler.java b/src/main/java/com/extendedae_plus/api/storage/InfinityBigIntegerCellHandler.java similarity index 86% rename from src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellHandler.java rename to src/main/java/com/extendedae_plus/api/storage/InfinityBigIntegerCellHandler.java index 3b7aa46..22ac4bf 100644 --- a/src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellHandler.java +++ b/src/main/java/com/extendedae_plus/api/storage/InfinityBigIntegerCellHandler.java @@ -1,9 +1,9 @@ -package com.extendedae_plus.ae.api.storage; +package com.extendedae_plus.api.storage; import appeng.api.storage.cells.ICellHandler; import appeng.api.storage.cells.ISaveProvider; import com.extendedae_plus.ExtendedAEPlus; -import com.extendedae_plus.ae.items.InfinityBigIntegerCellItem; +import com.extendedae_plus.items.InfinityBigIntegerCellItem; import net.minecraft.world.item.ItemStack; public class InfinityBigIntegerCellHandler implements ICellHandler { diff --git a/src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellInventory.java b/src/main/java/com/extendedae_plus/api/storage/InfinityBigIntegerCellInventory.java similarity index 81% rename from src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellInventory.java rename to src/main/java/com/extendedae_plus/api/storage/InfinityBigIntegerCellInventory.java index f050184..56061b5 100644 --- a/src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellInventory.java +++ b/src/main/java/com/extendedae_plus/api/storage/InfinityBigIntegerCellInventory.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.ae.api.storage; +package com.extendedae_plus.api.storage; import appeng.api.config.Actionable; import appeng.api.networking.security.IActionSource; @@ -9,7 +9,7 @@ import appeng.api.storage.cells.CellState; import appeng.api.storage.cells.ISaveProvider; import appeng.api.storage.cells.StorageCell; import appeng.core.AELog; -import com.extendedae_plus.ae.items.InfinityBigIntegerCellItem; +import com.extendedae_plus.items.InfinityBigIntegerCellItem; import com.extendedae_plus.util.storage.InfinityConstants; import com.extendedae_plus.util.storage.InfinityDataStorage; import com.extendedae_plus.util.storage.InfinityStorageManager; @@ -51,10 +51,10 @@ public class InfinityBigIntegerCellInventory implements StorageCell { private boolean isPersisted = true; - public InfinityBigIntegerCellInventory(InfinityBigIntegerCellItem cell, - ItemStack stack, - ISaveProvider saveProvider, - @Nullable InfinityStorageManager storageManager) { + private InfinityBigIntegerCellInventory(InfinityBigIntegerCellItem cell, + ItemStack stack, + ISaveProvider saveProvider, + @Nullable InfinityStorageManager storageManager) { // 保存存储单元类型(InfinityBigIntegerCellItem 实例),用于访问磁盘属性 this.cell = cell; // 保存物品堆栈,表示磁盘本身,包含运行时的 NBT 数据 @@ -65,7 +65,7 @@ public class InfinityBigIntegerCellInventory implements StorageCell { this.AEKey2AmountsMap = null; this.storageManager = storageManager; // 初始化磁盘数据 - initData(); + this.initData(); } // 将 BigInteger 格式化为带单位的字符串,保留两位小数 @@ -87,9 +87,9 @@ public class InfinityBigIntegerCellInventory implements StorageCell { } // 静态方法,创建存储单元库存 - public static InfinityBigIntegerCellInventory createInventory(ItemStack stack, - ISaveProvider saveProvider, - @Nullable InfinityStorageManager storageManager) { + static InfinityBigIntegerCellInventory createInventory(ItemStack stack, + ISaveProvider saveProvider, + @Nullable InfinityStorageManager storageManager) { // 检查物品堆栈是否为空 Objects.requireNonNull(stack, "Cannot create cell inventory for null itemstack"); // 检查物品是否为 IDISKCellItem 类型 @@ -103,8 +103,8 @@ public class InfinityBigIntegerCellInventory implements StorageCell { // 获取磁盘的 InfinityDataStorage 数据 private InfinityDataStorage getCellStorage() { // 如果磁盘有 UUID,返回对应的 InfinityDataStorage - if (getUUID() != null && this.storageManager != null) { - return storageManager.getOrCreateCell(getUUID()); + if (this.getUUID() != null && this.storageManager != null) { + return this.storageManager.getOrCreateCell(this.getUUID()); } else { // 否则返回空的 InfinityDataStorage return InfinityDataStorage.EMPTY; @@ -114,18 +114,18 @@ public class InfinityBigIntegerCellInventory implements StorageCell { // 初始化磁盘数据 private void initData() { // 如果磁盘有 UUID,加载存储的物品数据 - if (hasUUID()) { - this.totalAEKeyType = getCellStorage().amounts.size(); - this.totalAEKey2Amounts = getCellStorage().itemCount.equals(BigInteger.ZERO) ? + if (this.hasUUID()) { + this.totalAEKeyType = this.getCellStorage().amounts.size(); + this.totalAEKey2Amounts = this.getCellStorage().itemCount.equals(BigInteger.ZERO) ? BigInteger.ZERO : - getCellStorage().itemCount; + this.getCellStorage().itemCount; } else { // 否则初始化为空 this.totalAEKeyType = 0; this.totalAEKey2Amounts = BigInteger.ZERO; // 加载物品数据 - getCellStoredMap(); + this.getCellStoredMap(); } } @@ -153,10 +153,10 @@ public class InfinityBigIntegerCellInventory implements StorageCell { return; if (this.totalAEKey2Amounts.equals(BigInteger.ZERO)) { - if (hasUUID()) { - this.storageManager.removeCell(getUUID()); + if (this.hasUUID()) { + this.storageManager.removeCell(this.getUUID()); // 从 DataComponents.CUSTOM_DATA 里移除对应字段 - CustomData data = self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY); + 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); @@ -164,9 +164,9 @@ public class InfinityBigIntegerCellInventory implements StorageCell { // backward compat tag.remove(InfinityConstants.INFINITY_CELL_ITEM_COUNT); - self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag)); + this.self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag)); - initData(); + this.initData(); } return; } @@ -192,9 +192,9 @@ public class InfinityBigIntegerCellInventory implements StorageCell { } if (keys.isEmpty()) { - this.storageManager.updateCell(getUUID(), new InfinityDataStorage()); + this.storageManager.updateCell(this.getUUID(), new InfinityDataStorage()); } else { - this.storageManager.modifyDisk(getUUID(), keys, amounts, itemCount); + this.storageManager.modifyDisk(this.getUUID(), keys, amounts, itemCount); } // 更新存储的物品种类数量 @@ -204,23 +204,17 @@ public class InfinityBigIntegerCellInventory implements StorageCell { // 将物品总数与种类数量存入物品堆栈的 NBT(用于快捷查看/tooltip),同时保留旧字段以兼容历史版本 // 写回 DataComponents.CUSTOM_DATA(替代 getOrCreateTag) - CompoundTag tag = self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag(); + 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()); - self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag)); + this.self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag)); // 标记数据已持久化 this.isPersisted = true; } - // 获取存储单元的描述(此处返回null,可自定义) - @Override - public Component getDescription() { - return null; - } - // 获取存储的物品总数 - public BigInteger getTotalAEKey2Amounts() { + private BigInteger getTotalAEKey2Amounts() { return this.totalAEKey2Amounts; } @@ -230,14 +224,14 @@ public class InfinityBigIntegerCellInventory implements StorageCell { } // 判断物品堆栈是否有UUID - public boolean hasUUID() { - CustomData data = self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY); + 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 = self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY); + CustomData data = this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY); if (!data.isEmpty() && data.copyTag().contains(InfinityConstants.INFINITY_CELL_UUID)) { return data.copyTag().getUUID(InfinityConstants.INFINITY_CELL_UUID); } @@ -246,40 +240,13 @@ public class InfinityBigIntegerCellInventory implements StorageCell { // 获取或初始化存储映射 private Object2ObjectMap getCellStoredMap() { - if (AEKey2AmountsMap == null) { - AEKey2AmountsMap = new Object2ObjectOpenHashMap<>(); + if (this.AEKey2AmountsMap == null) { + this.AEKey2AmountsMap = new Object2ObjectOpenHashMap<>(); this.loadCellStoredMap(); } - return AEKey2AmountsMap; + return this.AEKey2AmountsMap; } - // 获取所有可用的物品堆栈及其数量 - @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; - } - long delta = toSet - existing; - if (delta != 0) { - out.add(key, delta); - } - } - } - - // 从存储中加载物品映射 private void loadCellStoredMap() { if (this.storageManager == null) { @@ -287,10 +254,10 @@ public class InfinityBigIntegerCellInventory implements StorageCell { } boolean dataCorruption = false; - if (self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).isEmpty()) return; + if (this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).isEmpty()) return; - var keys = getCellStorage().keys; - var amounts = getCellStorage().amounts; + 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()); @@ -306,7 +273,7 @@ public class InfinityBigIntegerCellInventory implements StorageCell { if (amount.compareTo(BigInteger.ZERO) <= 0 || key == null) { dataCorruption = true; } else { - AEKey2AmountsMap.put(key, amount); + this.AEKey2AmountsMap.put(key, amount); } } if (dataCorruption) { @@ -351,9 +318,9 @@ public class InfinityBigIntegerCellInventory implements StorageCell { } // 如果没有 UUID,且服务器端存储管理器已就绪,则生成 UUID 并初始化存储 - if (storageManager != null && !this.hasUUID()) { + if (this.storageManager != null && !this.hasUUID()) { // 取出自定义 NBT(如果没有就返回空) - CustomData data = self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY); + CustomData data = this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY); CompoundTag tag = data.copyTag(); // 生成新的 UUID 并写入 @@ -361,13 +328,13 @@ public class InfinityBigIntegerCellInventory implements StorageCell { tag.putUUID(InfinityConstants.INFINITY_CELL_UUID, newUUID); // 回写到 ItemStack - self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag)); + this.self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag)); // 初始化存储 this.storageManager.getOrCreateCell(newUUID); // 加载已存储的映射 - loadCellStoredMap(); + this.loadCellStoredMap(); } // 获取当前物品数量 BigInteger currentAmount = this.getCellStoredMap().getOrDefault(what, BigInteger.ZERO); @@ -375,7 +342,7 @@ public class InfinityBigIntegerCellInventory implements StorageCell { if (mode == Actionable.MODULATE) { // 实际插入,更新数量并保存 BigInteger newAmount = currentAmount.add(BigInteger.valueOf(amount)); - getCellStoredMap().put(what, newAmount); + this.getCellStoredMap().put(what, newAmount); this.saveChanges(); } return amount; @@ -393,14 +360,14 @@ public class InfinityBigIntegerCellInventory implements StorageCell { // 如果提取数量大于等于当前数量 if (requested.compareTo(currentAmount) >= 0) { if (mode == Actionable.MODULATE) { - getCellStoredMap().remove(what); + 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) { - getCellStoredMap().put(what, currentAmount.subtract(requested)); + this.getCellStoredMap().put(what, currentAmount.subtract(requested)); this.saveChanges(); } return requested.longValue(); @@ -409,9 +376,41 @@ public class InfinityBigIntegerCellInventory implements StorageCell { return 0; } + // 获取所有可用的物品堆栈及其数量 + @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; + } + long delta = toSet - existing; + if (delta != 0) { + out.add(key, delta); + } + } + } + + // 获取存储单元的描述(此处返回null,可自定义) + @Override + public Component getDescription() { + return null; + } + // 获取存储单元内所有物品的总数量(格式化字符串) public String getTotalStorage() { // 使用缓存的 totalStored,避免每次全表扫描 - return formatBigInteger(totalAEKey2Amounts); + return formatBigInteger(this.totalAEKey2Amounts); } } diff --git a/src/main/java/com/extendedae_plus/client/ClientProxy.java b/src/main/java/com/extendedae_plus/client/ClientProxy.java index 39761f9..c65b771 100644 --- a/src/main/java/com/extendedae_plus/client/ClientProxy.java +++ b/src/main/java/com/extendedae_plus/client/ClientProxy.java @@ -3,13 +3,13 @@ package com.extendedae_plus.client; import appeng.client.render.crafting.CraftingCubeModel; import appeng.init.client.InitScreens; import com.extendedae_plus.ExtendedAEPlus; -import com.extendedae_plus.ae.definitions.upgrades.EntitySpeedCardItem; import com.extendedae_plus.ae.screen.EntitySpeedTickerScreen; import com.extendedae_plus.client.render.crafting.EPlusCraftingCubeModelProvider; import com.extendedae_plus.content.crafting.EPlusCraftingUnitType; import com.extendedae_plus.hooks.BuiltInModelHooks; import com.extendedae_plus.init.ModItems; import com.extendedae_plus.init.ModMenuTypes; +import com.extendedae_plus.items.materials.EntitySpeedCardItem; import net.minecraft.client.renderer.item.ItemProperties; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; @@ -21,10 +21,10 @@ import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent; */ @EventBusSubscriber(modid = ExtendedAEPlus.MODID, value = Dist.CLIENT) public final class ClientProxy { - private ClientProxy() {} - private static boolean REGISTERED = false; + private ClientProxy() {} + public static void init() { if (REGISTERED) return; REGISTERED = true; diff --git a/src/main/java/com/extendedae_plus/client/ChannelCardClientHandler.java b/src/main/java/com/extendedae_plus/client/event/ChannelCardClientHandler.java similarity index 97% rename from src/main/java/com/extendedae_plus/client/ChannelCardClientHandler.java rename to src/main/java/com/extendedae_plus/client/event/ChannelCardClientHandler.java index 10cb2c3..2872c97 100644 --- a/src/main/java/com/extendedae_plus/client/ChannelCardClientHandler.java +++ b/src/main/java/com/extendedae_plus/client/event/ChannelCardClientHandler.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.client; +package com.extendedae_plus.client.event; import com.extendedae_plus.ExtendedAEPlus; import com.extendedae_plus.init.ModItems; diff --git a/src/main/java/com/extendedae_plus/NewIcon.java b/src/main/java/com/extendedae_plus/client/gui/NewIcon.java similarity index 96% rename from src/main/java/com/extendedae_plus/NewIcon.java rename to src/main/java/com/extendedae_plus/client/gui/NewIcon.java index e8735ef..3c2ca4d 100644 --- a/src/main/java/com/extendedae_plus/NewIcon.java +++ b/src/main/java/com/extendedae_plus/client/gui/NewIcon.java @@ -1,22 +1,19 @@ -package com.extendedae_plus; +package com.extendedae_plus.client.gui; import appeng.client.gui.style.Blitter; import net.minecraft.resources.ResourceLocation; public class NewIcon { - @SuppressWarnings("all") - // 贴图当前存放于 assets/extendedae_plus/textures/gui/nicons.png - // 与 MODID (extendedaeplus) 不同,因此这里直接指定贴图所在命名空间 - private static final ResourceLocation TEXTURE = ResourceLocation.fromNamespaceAndPath("extendedae_plus", "textures/gui/nicons.png"); - - - public static final Blitter MULTIPLY2; public static final Blitter DIVIDE2; public static final Blitter MULTIPLY5; public static final Blitter DIVIDE5; public static final Blitter MULTIPLY10; public static final Blitter DIVIDE10; + @SuppressWarnings("all") + // 贴图当前存放于 assets/extendedae_plus/textures/gui/nicons.png + // 与 MODID (extendedaeplus) 不同,因此这里直接指定贴图所在命名空间 + private static final ResourceLocation TEXTURE = ResourceLocation.fromNamespaceAndPath("extendedae_plus", "textures/gui/nicons.png"); static { MULTIPLY2 = Blitter.texture(TEXTURE, 64, 64).src(32, 0, 16, 16); diff --git a/src/main/java/com/extendedae_plus/client/gui/PageLayoutContext.java b/src/main/java/com/extendedae_plus/client/gui/PageLayoutContext.java deleted file mode 100644 index 7cf88f0..0000000 --- a/src/main/java/com/extendedae_plus/client/gui/PageLayoutContext.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.extendedae_plus.client.gui; - -public final class PageLayoutContext { - private static final ThreadLocal ACTIVE = ThreadLocal.withInitial(() -> false); - private static final ThreadLocal CURRENT_PAGE = ThreadLocal.withInitial(() -> 0); - - private PageLayoutContext() {} - - public static void enable(int page) { - ACTIVE.set(true); - CURRENT_PAGE.set(page); - } - - public static void disable() { - ACTIVE.set(false); - } - - public static boolean isActive() { - Boolean b = ACTIVE.get(); - return b != null && b; - } - - public static int getCurrentPage() { - Integer i = CURRENT_PAGE.get(); - return i != null ? i : 0; - } - - public static void withPage(int page, Runnable action) { - enable(page); - try { - action.run(); - } finally { - disable(); - } - } -} diff --git a/src/main/java/com/extendedae_plus/client/ui/FrequencyInputScreen.java b/src/main/java/com/extendedae_plus/client/screen/FrequencyInputScreen.java similarity index 94% rename from src/main/java/com/extendedae_plus/client/ui/FrequencyInputScreen.java rename to src/main/java/com/extendedae_plus/client/screen/FrequencyInputScreen.java index e8385cd..f85c652 100644 --- a/src/main/java/com/extendedae_plus/client/ui/FrequencyInputScreen.java +++ b/src/main/java/com/extendedae_plus/client/screen/FrequencyInputScreen.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.client.ui; +package com.extendedae_plus.client.screen; import com.extendedae_plus.network.SetWirelessFrequencyC2SPacket; import net.minecraft.client.Minecraft; @@ -35,60 +35,17 @@ public class FrequencyInputScreen extends Screen { * @param pos 无线收发器的位置 * @param currentFrequency 当前频率 */ - public FrequencyInputScreen(BlockPos pos, long currentFrequency) { + private FrequencyInputScreen(BlockPos pos, long currentFrequency) { super(Component.translatable("gui.extendedae_plus.frequency_input.title")); this.pos = pos; this.currentFrequency = currentFrequency; } - @Override - protected void init() { - super.init(); - - // 计算居中位置 - int x = (this.width - WINDOW_WIDTH) / 2; - int y = (this.height - WINDOW_HEIGHT) / 2; - - // 创建输入框 - // API说明:EditBox构造函数参数:font, x, y, width, height, component - this.frequencyInput = new EditBox( - this.font, - x + 10, - y + 30, - WINDOW_WIDTH - 20, - 20, - Component.translatable("gui.extendedae_plus.frequency_input.field") - ); - - // 设置输入框属性 - this.frequencyInput.setMaxLength(19); // long类型最大19位数字 - this.frequencyInput.setValue(String.valueOf(currentFrequency)); - this.frequencyInput.setFilter(this::isValidInput); // 只允许数字和负号 - this.frequencyInput.setFocused(true); - - // 添加输入框到组件列表 - this.addRenderableWidget(this.frequencyInput); - - // 创建确认按钮 - // API说明:Button.builder方法在1.21.1中使用 - this.confirmButton = Button.builder( - Component.translatable("gui.extendedae_plus.frequency_input.confirm"), - button -> this.onConfirm() - ) - .bounds(x + 10, y + 55, 80, 20) - .build(); - - this.addRenderableWidget(this.confirmButton); - - // 创建取消按钮 - Button cancelButton = Button.builder( - Component.translatable("gui.extendedae_plus.frequency_input.cancel"), - button -> this.onClose() - ) - .bounds(x + 110, y + 55, 80, 20) - .build(); - - this.addRenderableWidget(cancelButton); + /** + * 静态工厂方法:打开频率输入界面 + */ + public static void open(BlockPos pos, long currentFrequency) { + Minecraft.getInstance().setScreen(new FrequencyInputScreen(pos, currentFrequency)); } /** @@ -110,9 +67,46 @@ public class FrequencyInputScreen extends Screen { } } + /** + * 渲染背景 + * + * API变化说明: + * - GuiGraphics替代了旧的PoseStack + BufferSource组合 + * - renderBackground方法签名在1.21.1中简化 + */ + @Override + public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { + // 渲染暗色背景 + super.render(guiGraphics, mouseX, mouseY, partialTick); + + // 计算窗口位置 + int x = (this.width - WINDOW_WIDTH) / 2; + int y = (this.height - WINDOW_HEIGHT) / 2; + + // 绘制窗口背景 + guiGraphics.fill(x, y, x + WINDOW_WIDTH, y + WINDOW_HEIGHT, 0xC0000000); + + // 绘制窗口边框 + guiGraphics.fill(x, y, x + WINDOW_WIDTH, y + 1, 0xFFFFFFFF); // 顶部 + guiGraphics.fill(x, y + WINDOW_HEIGHT - 1, x + WINDOW_WIDTH, y + WINDOW_HEIGHT, 0xFFFFFFFF); // 底部 + guiGraphics.fill(x, y, x + 1, y + WINDOW_HEIGHT, 0xFFFFFFFF); // 左侧 + guiGraphics.fill(x + WINDOW_WIDTH - 1, y, x + WINDOW_WIDTH, y + WINDOW_HEIGHT, 0xFFFFFFFF); // 右侧 + + // 绘制标题 + Component title = Component.translatable("gui.extendedae_plus.frequency_input.title"); + guiGraphics.drawString( + this.font, + title, + x + (WINDOW_WIDTH - this.font.width(title)) / 2, + y + 10, + 0xFFFFFFFF, + false + ); + } + /** * 按键处理:回车键确认,ESC键取消 - * + * * API说明:keyPressed方法在1.21.1中保持一致 */ @Override @@ -130,64 +124,54 @@ public class FrequencyInputScreen extends Screen { return super.keyPressed(keyCode, scanCode, modifiers); } - /** - * 渲染背景 - * - * API变化说明: - * - GuiGraphics替代了旧的PoseStack + BufferSource组合 - * - renderBackground方法签名在1.21.1中简化 - */ @Override - public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { - // 渲染暗色背景 - super.render(guiGraphics, mouseX, mouseY, partialTick); - - // 计算窗口位置 + protected void init() { + super.init(); + + // 计算居中位置 int x = (this.width - WINDOW_WIDTH) / 2; int y = (this.height - WINDOW_HEIGHT) / 2; - - // 绘制窗口背景 - guiGraphics.fill(x, y, x + WINDOW_WIDTH, y + WINDOW_HEIGHT, 0xC0000000); - - // 绘制窗口边框 - guiGraphics.fill(x, y, x + WINDOW_WIDTH, y + 1, 0xFFFFFFFF); // 顶部 - guiGraphics.fill(x, y + WINDOW_HEIGHT - 1, x + WINDOW_WIDTH, y + WINDOW_HEIGHT, 0xFFFFFFFF); // 底部 - guiGraphics.fill(x, y, x + 1, y + WINDOW_HEIGHT, 0xFFFFFFFF); // 左侧 - guiGraphics.fill(x + WINDOW_WIDTH - 1, y, x + WINDOW_WIDTH, y + WINDOW_HEIGHT, 0xFFFFFFFF); // 右侧 - - // 绘制标题 - Component title = Component.translatable("gui.extendedae_plus.frequency_input.title"); - guiGraphics.drawString( + + // 创建输入框 + // API说明:EditBox构造函数参数:font, x, y, width, height, component + this.frequencyInput = new EditBox( this.font, - title, - x + (WINDOW_WIDTH - this.font.width(title)) / 2, - y + 10, - 0xFFFFFFFF, - false + x + 10, + y + 30, + WINDOW_WIDTH - 20, + 20, + Component.translatable("gui.extendedae_plus.frequency_input.field") ); - } - - /** - * 确认按钮处理 - */ - private void onConfirm() { - String input = this.frequencyInput.getValue(); - if (input.isEmpty()) { - this.onClose(); - return; - } - - try { - long frequency = Long.parseLong(input); - - // 发送数据包到服务端 - // API说明:NeoForge使用PacketDistributor.sendToServer - PacketDistributor.sendToServer(new SetWirelessFrequencyC2SPacket(pos, frequency)); - - this.onClose(); - } catch (NumberFormatException e) { - // 输入无效,不做处理 - } + + // 设置输入框属性 + this.frequencyInput.setMaxLength(19); // long类型最大19位数字 + this.frequencyInput.setValue(String.valueOf(this.currentFrequency)); + this.frequencyInput.setFilter(this::isValidInput); // 只允许数字和负号 + this.frequencyInput.setFocused(true); + + // 添加输入框到组件列表 + this.addRenderableWidget(this.frequencyInput); + + // 创建确认按钮 + // API说明:Button.builder方法在1.21.1中使用 + this.confirmButton = Button.builder( + Component.translatable("gui.extendedae_plus.frequency_input.confirm"), + button -> this.onConfirm() + ) + .bounds(x + 10, y + 55, 80, 20) + .build(); + + this.addRenderableWidget(this.confirmButton); + + // 创建取消按钮 + Button cancelButton = Button.builder( + Component.translatable("gui.extendedae_plus.frequency_input.cancel"), + button -> this.onClose() + ) + .bounds(x + 110, y + 55, 80, 20) + .build(); + + this.addRenderableWidget(cancelButton); } /** @@ -200,10 +184,26 @@ public class FrequencyInputScreen extends Screen { } /** - * 静态工厂方法:打开频率输入界面 + * 确认按钮处理 */ - public static void open(BlockPos pos, long currentFrequency) { - Minecraft.getInstance().setScreen(new FrequencyInputScreen(pos, currentFrequency)); + private void onConfirm() { + String input = this.frequencyInput.getValue(); + if (input.isEmpty()) { + this.onClose(); + return; + } + + try { + long frequency = Long.parseLong(input); + + // 发送数据包到服务端 + // API说明:NeoForge使用PacketDistributor.sendToServer + PacketDistributor.sendToServer(new SetWirelessFrequencyC2SPacket(this.pos, frequency)); + + this.onClose(); + } catch (NumberFormatException e) { + // 输入无效,不做处理 + } } } diff --git a/src/main/java/com/extendedae_plus/client/ui/ProviderSelectScreen.java b/src/main/java/com/extendedae_plus/client/screen/ProviderSelectScreen.java similarity index 73% rename from src/main/java/com/extendedae_plus/client/ui/ProviderSelectScreen.java rename to src/main/java/com/extendedae_plus/client/screen/ProviderSelectScreen.java index f0704e0..39fcb85 100644 --- a/src/main/java/com/extendedae_plus/client/ui/ProviderSelectScreen.java +++ b/src/main/java/com/extendedae_plus/client/screen/ProviderSelectScreen.java @@ -1,6 +1,7 @@ -package com.extendedae_plus.client.ui; +package com.extendedae_plus.client.screen; import com.extendedae_plus.network.UploadEncodedPatternToProviderC2SPacket; +import com.extendedae_plus.util.uploadPattern.ExtendedAEPatternUploadUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.EditBox; @@ -14,35 +15,33 @@ import java.util.*; * 展示若干个可点击的供应器条目,点击后发送带 providerId 的上传请求。 */ public class ProviderSelectScreen extends Screen { + private static final int PAGE_SIZE = 6; + // 优先使用 JEC 的拼音匹配,否则回退到大小写不敏感子串匹配 + private static Boolean JEC_AVAILABLE = null; + private static java.lang.reflect.Method JEC_CONTAINS = null; private final Screen parent; // 原始数据 private final List ids; private final List names; private final List emptySlots; - // 分组后的数据(同名合并) private final List gIds = new ArrayList<>(); // 代表条目使用的 providerId:选择空位数最多的那个 private final List gNames = new ArrayList<>(); // 分组名(供应器名称) private final List gTotalSlots = new ArrayList<>(); // 该名称下供应器空位总和 private final List gCount = new ArrayList<>(); // 该名称下供应器数量 - // 过滤后的数据(由查询生成) private final List fIds = new ArrayList<>(); private final List fNames = new ArrayList<>(); private final List fTotalSlots = new ArrayList<>(); private final List fCount = new ArrayList<>(); - + private final List