diff --git a/build.gradle b/build.gradle index e8f03eb..29ff48c 100644 --- a/build.gradle +++ b/build.gradle @@ -135,21 +135,13 @@ sourceSets.main.java { // 允许 accessor include 'com/extendedae_plus/mixin/**/accessor/**' // 排除具体的非 accessor mixin 目录 - // AE2 相关非 accessor - exclude 'com/extendedae_plus/mixin/ae2/helpers/**' - exclude 'com/extendedae_plus/mixin/ae2/autopattern/**' - exclude 'com/extendedae_plus/mixin/ae2/client/**' - exclude 'com/extendedae_plus/mixin/ae2/menu/**' - exclude 'com/extendedae_plus/mixin/ae2/AEProcessingPatternMixin.java' - // 排除 ae2 根目录下的普通 mixin(保留 accessor 子目录) - exclude 'com/extendedae_plus/mixin/ae2/*.java' + // AE2 相关非 accessor(已启用,需要参与编译与运行) // 其他模块的非 accessor mixin exclude 'com/extendedae_plus/mixin/ae2WTlib/**' // 保留 mixin/jei/accessor,但排除其余 exclude 'com/extendedae_plus/mixin/jei/*.java' // 排除顶层 mixin 文件 exclude 'com/extendedae_plus/mixin/PickFromWirelessMixin.java' - exclude 'com/extendedae_plus/mixin/extendedae/**' } configurations { diff --git a/src/main/java/com/extendedae_plus/ExtendedAEPlus.java b/src/main/java/com/extendedae_plus/ExtendedAEPlus.java index 8067c15..57f9426 100644 --- a/src/main/java/com/extendedae_plus/ExtendedAEPlus.java +++ b/src/main/java/com/extendedae_plus/ExtendedAEPlus.java @@ -4,6 +4,7 @@ import org.slf4j.Logger; import com.mojang.logging.LogUtils; import com.extendedae_plus.config.ModConfigs; +import com.extendedae_plus.init.ModMenuTypes; import com.extendedae_plus.network.ModNetwork; import net.minecraft.resources.ResourceLocation; @@ -80,6 +81,8 @@ public class ExtendedAEPlus { ITEMS.register(modEventBus); // Register the Deferred Register to the mod event bus so tabs get registered CREATIVE_MODE_TABS.register(modEventBus); + // Register the Deferred Register to the mod event bus so menu types get registered + ModMenuTypes.MENUS.register(modEventBus); // Register ourselves for server and other game events we are interested in. // Note that this is necessary if and only if we want *this* class (ExtendedAEPlus) to respond directly to events. diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/EncodedPatternItemMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/EncodedPatternItemMixin.java index 1e56aab..79cf914 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/EncodedPatternItemMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/EncodedPatternItemMixin.java @@ -3,9 +3,10 @@ package com.extendedae_plus.mixin.ae2; import appeng.crafting.pattern.EncodedPatternItem; import com.extendedae_plus.config.ModConfigs; import net.minecraft.ChatFormatting; -import net.minecraft.nbt.CompoundTag; +import net.minecraft.core.component.DataComponents; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.CustomData; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; @@ -20,10 +21,13 @@ public class EncodedPatternItemMixin { // 客户端:在 HoverText 显示样板的编码玩家 @Inject(method = "appendHoverText", at = @At("TAIL")) public void epp$appendHoverText(ItemStack stack, Level level, List lines, TooltipFlag advancedTooltips, CallbackInfo ci){ - if (stack.hasTag() && ModConfigs.SHOW_ENCOD_PATTERN_PLAYER.get()) { - CompoundTag tag = stack.getOrCreateTag(); - String name = tag.getString("encodePlayer"); - lines.add(Component.translatable("extendedae_plus.pattern.hovertext.player", name).withStyle(ChatFormatting.GRAY)); + if (ModConfigs.SHOW_ENCOD_PATTERN_PLAYER.get()) { + var customData = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY); + var tag = customData.copyTag(); + if (tag.contains("encodePlayer")) { + String name = tag.getString("encodePlayer"); + lines.add(Component.translatable("extendedae_plus.pattern.hovertext.player", name).withStyle(ChatFormatting.GRAY)); + } } } } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/QuartzCuttingKnifeItemMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/QuartzCuttingKnifeItemMixin.java index e8ddd97..4c13b18 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/QuartzCuttingKnifeItemMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/QuartzCuttingKnifeItemMixin.java @@ -21,7 +21,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.fml.ModList; +import net.neoforged.fml.ModList; import org.lwjgl.glfw.GLFW; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java index b741be3..997afc1 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java @@ -28,6 +28,7 @@ import net.minecraft.client.renderer.Rect2i; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.contents.TranslatableContents; import net.minecraft.world.inventory.Slot; +import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -79,7 +80,7 @@ public abstract class AEBaseScreenMixin { try { LogUtils.getLogger().info("EAP: Send CraftingMonitorJumpC2SPacket: {}", key); } catch (Throwable ignored2) {} - ModNetwork.CHANNEL.sendToServer(new CraftingMonitorJumpC2SPacket(key)); + PacketDistributor.sendToServer(new CraftingMonitorJumpC2SPacket(key)); cir.setReturnValue(true); } catch (Throwable ignored) { } @@ -113,7 +114,7 @@ public abstract class AEBaseScreenMixin { try { LogUtils.getLogger().info("EAP: Send CraftingMonitorOpenProviderC2SPacket: {}", key); } catch (Throwable ignored2) {} - ModNetwork.CHANNEL.sendToServer(new CraftingMonitorOpenProviderC2SPacket(key)); + PacketDistributor.sendToServer(new CraftingMonitorOpenProviderC2SPacket(key)); cir.setReturnValue(true); } catch (Throwable ignored) { } @@ -183,10 +184,10 @@ public abstract class AEBaseScreenMixin { GuiUtil.drawAmountText(guiGraphics, font, amountText, appEngSlot.x, appEngSlot.y, 0.6f); try { - var details = PatternDetailsHelper.decodePattern(itemStack, Minecraft.getInstance().level, false); + var details = PatternDetailsHelper.decodePattern(itemStack, Minecraft.getInstance().level); try { - if (details != null && details.getOutputs() != null && details.getOutputs().length > 0) { - AEKey key = details.getOutputs()[0].what(); + if (details != null && details.getOutputs() != null && !details.getOutputs().isEmpty()) { + AEKey key = details.getOutputs().get(0).what(); if (key != null && ClientPatternHighlightStore.hasHighlight(key)) { try { GuiUtil.drawSlotRainbowHighlight(guiGraphics, s.x, s.y); diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternEncodingTermScreenMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternEncodingTermScreenMixin.java index 7119000..b3ee01d 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternEncodingTermScreenMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternEncodingTermScreenMixin.java @@ -15,6 +15,7 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Tooltip; import net.minecraft.client.renderer.Rect2i; import net.minecraft.network.chat.Component; +import net.neoforged.neoforge.network.PacketDistributor; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -40,7 +41,7 @@ public abstract class PatternEncodingTermScreenMixin { } // 复用已存在的按钮实例,避免重复创建 if (eap$uploadBtn == null) { - eap$uploadBtn = new IconButton(btn -> ModNetwork.CHANNEL + eap$uploadBtn = new IconButton(btn -> PacketDistributor .sendToServer(new com.extendedae_plus.network.RequestProvidersListC2SPacket())) { private final float eap$scale = 0.75f; // 约 12x12 diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/menu/ContainerPatternEncodingTermMenuMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/menu/ContainerPatternEncodingTermMenuMixin.java index c2a5b31..1245d59 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/menu/ContainerPatternEncodingTermMenuMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/menu/ContainerPatternEncodingTermMenuMixin.java @@ -5,12 +5,14 @@ import appeng.menu.me.items.PatternEncodingTermMenu; import appeng.menu.slot.RestrictedInputSlot; import appeng.parts.encoding.EncodingMode; import com.extendedae_plus.util.ExtendedAEPatternUploadUtil; +import com.glodblock.github.glodium.network.packet.sync.ActionMap; import com.glodblock.github.glodium.network.packet.sync.IActionHolder; -import com.glodblock.github.glodium.network.packet.sync.Paras; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.NotNull; +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.item.component.CustomData; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -30,7 +32,7 @@ import java.util.function.Consumer; public abstract class ContainerPatternEncodingTermMenuMixin implements IActionHolder { @Unique - private final Map> eap$actions = createHolder(); + private final ActionMap eap$actions = ActionMap.create(); @Unique private Player epp$player; @@ -75,7 +77,7 @@ public abstract class ContainerPatternEncodingTermMenuMixin implements IActionHo @NotNull @Override - public Map> getActionMap() { + public ActionMap getActionMap() { return this.eap$actions; } @@ -117,7 +119,11 @@ public abstract class ContainerPatternEncodingTermMenuMixin implements IActionHo @Inject(method = "encodePattern", at = @At("TAIL"), remap = false, cancellable = true) private void eap$writeEncodePlayerToPattern(CallbackInfoReturnable cir) { ItemStack itemStack = cir.getReturnValue(); - itemStack.getOrCreateTag().putString("encodePlayer", this.epp$player.getGameProfile().getName()); - cir.setReturnValue(itemStack); + if (itemStack != null && !itemStack.isEmpty()) { + CustomData.update(DataComponents.CUSTOM_DATA, itemStack, tag -> { + tag.putString("encodePlayer", this.epp$player.getGameProfile().getName()); + }); + cir.setReturnValue(itemStack); + } } } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/menu/MEStorageMenuMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/menu/MEStorageMenuMixin.java index f37c56e..49bb987 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/menu/MEStorageMenuMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/menu/MEStorageMenuMixin.java @@ -97,6 +97,9 @@ public abstract class MEStorageMenuMixin { } Setting typedSetting = (Setting) setting; T typedValue = (T) value; - client.registerSetting(typedSetting, typedValue); + // 仅当具体实现为 ConfigManager 时,才能调用 registerSetting + if (client instanceof appeng.util.ConfigManager cm) { + cm.registerSetting(typedSetting, typedValue); + } } } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternEncodingTermMenuMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternEncodingTermMenuMixin.java index a9cc70a..d36c85c 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternEncodingTermMenuMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternEncodingTermMenuMixin.java @@ -57,7 +57,7 @@ public abstract class PatternEncodingTermMenuMixin { var current = blankInv.getStackInSlot(0); int limit = blankInv.getSlotLimit(0); int space = Math.max(0, limit - current.getCount()); - space = Math.min(space, AEItems.BLANK_PATTERN.asItem().getMaxStackSize()); + space = Math.min(space, AEItems.BLANK_PATTERN.stack(1).getMaxStackSize()); if (space <= 0) { return; // 已满,无需填充 } @@ -126,7 +126,7 @@ public abstract class PatternEncodingTermMenuMixin { var current = blankInv.getStackInSlot(0); int limit = blankInv.getSlotLimit(0); int space = Math.max(0, limit - current.getCount()); - space = Math.min(space, AEItems.BLANK_PATTERN.asItem().getMaxStackSize()); + space = Math.min(space, AEItems.BLANK_PATTERN.stack(1).getMaxStackSize()); if (space <= 0) { this.eap$blankAutoFilled = true; return; diff --git a/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java b/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java index 167a183..028fcb9 100644 --- a/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java @@ -25,7 +25,7 @@ import java.lang.reflect.Method; import static com.extendedae_plus.util.ExtendedAELogger.LOGGER; -@Mixin(GuiExPatternProvider.class) +@Mixin(value = GuiExPatternProvider.class, remap = false) public abstract class GuiExPatternProviderMixin extends PatternProviderScreen implements ExPatternButtonsAccessor, com.extendedae_plus.api.ExPatternPageAccessor { @Unique diff --git a/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternTerminalMixin.java b/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternTerminalMixin.java index 302daba..cb9126d 100644 --- a/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternTerminalMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternTerminalMixin.java @@ -10,7 +10,6 @@ import appeng.client.gui.widgets.IconButton; import appeng.menu.AEBaseMenu; import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.mixin.extendedae.accessor.GuiExPatternTerminalAccessor; -import com.extendedae_plus.network.ModNetwork; import com.extendedae_plus.network.OpenProviderUiC2SPacket; import com.extendedae_plus.util.GuiUtil; import com.glodblock.github.extendedae.client.gui.GuiExPatternTerminal; @@ -28,6 +27,7 @@ import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; +import net.neoforged.neoforge.network.PacketDistributor; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.spongepowered.asm.mixin.Mixin; @@ -39,12 +39,16 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.util.Map; +import java.util.Set; +import java.util.HashMap; +import java.util.ArrayList; +import java.util.Collection; import java.lang.reflect.Constructor; import java.lang.reflect.Method; -import java.util.*; @Pseudo -@Mixin(value = GuiExPatternTerminal.class) +@Mixin(value = GuiExPatternTerminal.class, remap = false) public abstract class GuiExPatternTerminalMixin extends AEBaseScreen { @Unique @@ -187,7 +191,7 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen ArrayList rows = acc.getRows(); // 找到该分组对应的第一个 PatternContainerRecord - Class cls = GuiExPatternTerminal.class; + Class cls = this.getClass(); var byGroupField = cls.getDeclaredField("byGroup"); byGroupField.setAccessible(true); Object byGroup = byGroupField.get(this); // HashMultimap @@ -236,7 +240,7 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen try { var dimRl = net.minecraft.resources.ResourceLocation.parse(dimStr); if (dimRl != null) { - ModNetwork.CHANNEL.sendToServer(new OpenProviderUiC2SPacket( + PacketDistributor.sendToServer(new OpenProviderUiC2SPacket( posLong, dimRl, faceOrd @@ -258,8 +262,12 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen this.eap$currentlyChoicePatterProvider = -1; } - @Inject(method = "", at = @At("TAIL"), remap = false) - private void injectConstructor(CallbackInfo ci) { + @Inject(method = "(Lcom/glodblock/github/extendedae/container/ContainerExPatternTerminal;Lnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/network/chat/Component;Lappeng/client/gui/style/ScreenStyle;)V", at = @At("TAIL"), remap = false) + private void injectConstructor(com.glodblock.github.extendedae.container.ContainerExPatternTerminal menu, + Inventory playerInventory, + Component title, + ScreenStyle style, + CallbackInfo ci) { // 根据配置初始化默认显示/隐藏状态 try { this.eap$showSlots = ModConfigs.PATTERN_TERMINAL_SHOW_SLOTS_DEFAULT.get(); diff --git a/src/main/java/com/extendedae_plus/mixin/extendedae/common/PartExPatternProviderMixin.java b/src/main/java/com/extendedae_plus/mixin/extendedae/common/PartExPatternProviderMixin.java index d2077cf..1334add 100644 --- a/src/main/java/com/extendedae_plus/mixin/extendedae/common/PartExPatternProviderMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/extendedae/common/PartExPatternProviderMixin.java @@ -3,9 +3,11 @@ package com.extendedae_plus.mixin.extendedae.common; import com.extendedae_plus.config.ModConfigs; import com.glodblock.github.extendedae.common.parts.PartExPatternProvider; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; +@Pseudo @Mixin(value = PartExPatternProvider.class, priority = 3000, remap = false) public abstract class PartExPatternProviderMixin { diff --git a/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerExPatternProviderMixin.java b/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerExPatternProviderMixin.java index 94fe85a..a91cb09 100644 --- a/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerExPatternProviderMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerExPatternProviderMixin.java @@ -10,24 +10,22 @@ import appeng.menu.guisync.GuiSync; import appeng.menu.implementations.PatternProviderMenu; import appeng.menu.slot.AppEngSlot; import com.glodblock.github.extendedae.container.ContainerExPatternProvider; -import com.glodblock.github.glodium.network.packet.sync.IActionHolder; -import com.glodblock.github.glodium.network.packet.sync.Paras; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.Slot; import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.List; -import java.util.Map; -import java.util.function.Consumer; -@Mixin(value = ContainerExPatternProvider.class, priority = 3000) -public abstract class ContainerExPatternProviderMixin extends PatternProviderMenu implements IActionHolder { +@Pseudo +@Mixin(value = ContainerExPatternProvider.class, priority = 3000, remap = false) +public abstract class ContainerExPatternProviderMixin extends PatternProviderMenu { // 使用高位唯一ID,避免与其他模组在同一类上的 @GuiSync 冲突 @GuiSync(31415) @@ -40,8 +38,7 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen @Unique private static final int SLOTS_PER_PAGE = 36; // 每页显示36个槽位 - @Unique - private final Map> eap$actions = createHolder(); + // glodium IActionHolder 已移除,相关 actionMap 由专用网络包替代。 public ContainerExPatternProviderMixin(MenuType menuType, int id, Inventory playerInventory, PatternProviderLogicHost host) { super(menuType, id, playerInventory, host); @@ -72,18 +69,10 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen } } - @Inject(method = "", at = @At("TAIL")) - public void init(int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) { + @Inject(method = "(ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/patternprovider/PatternProviderLogicHost;)V", at = @At("TAIL"), remap = false, require = 0) + private void eap$initPages(int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) { int maxSlots = this.getSlots(SlotSemantics.ENCODED_PATTERN).size(); this.eap$maxPage = (maxSlots + SLOTS_PER_PAGE - 1) / SLOTS_PER_PAGE; - - // 注册通用动作(供 CGenericPacket 分发) - this.eap$actions.put("multiply2", p -> { eap$modifyPatterns(2, false); }); - this.eap$actions.put("divide2", p -> { eap$modifyPatterns(2, true); }); - this.eap$actions.put("multiply5", p -> { eap$modifyPatterns(5, false); }); - this.eap$actions.put("divide5", p -> { eap$modifyPatterns(5, true); }); - this.eap$actions.put("multiply10", p -> { eap$modifyPatterns(10, false);}); - this.eap$actions.put("divide10", p -> { eap$modifyPatterns(10, true); }); } @Unique @@ -102,15 +91,13 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen for (var slot : this.getSlots(SlotSemantics.ENCODED_PATTERN)) { var stack = slot.getItem(); if (stack.getItem() instanceof EncodedPatternItem pattern) { - var detail = pattern.decode(stack, this.getPlayer().level(), false); + var detail = PatternDetailsHelper.decodePattern(stack, this.getPlayer().level()); if (detail instanceof AEProcessingPattern process) { - var input = process.getSparseInputs(); - var output = process.getOutputs(); + var input = process.getSparseInputs(); // List + var output = process.getOutputs(); // List if (eap$checkModify(input, scale, div) && eap$checkModify(output, scale, div)) { - var mulInput = new GenericStack[input.length]; - var mulOutput = new GenericStack[output.length]; - eap$modifyStacks(input, mulInput, scale, div); - eap$modifyStacks(output, mulOutput, scale, div); + var mulInput = eap$modifyStacks(input, scale, div); + var mulOutput = eap$modifyStacks(output, scale, div); var newPattern = PatternDetailsHelper.encodeProcessingPattern(mulInput, mulOutput); slot.set(newPattern); } @@ -120,7 +107,7 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen } @Unique - private boolean eap$checkModify(GenericStack[] stacks, int scale, boolean div) { + private boolean eap$checkModify(java.util.List stacks, int scale, boolean div) { if (stacks == null) return false; if (div) { for (var stack : stacks) { @@ -145,22 +132,17 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen } @Unique - private void eap$modifyStacks(GenericStack[] src, GenericStack[] dst, int scale, boolean div) { - for (int i = 0; i < src.length; i++) { - var stack = src[i]; + private java.util.List eap$modifyStacks(java.util.List src, int scale, boolean div) { + var dst = new java.util.ArrayList(src.size()); + for (var stack : src) { if (stack != null) { long amt = stack.amount(); long newAmt = div ? (amt / scale) : (amt * scale); - dst[i] = new GenericStack(stack.what(), newAmt); + dst.add(new GenericStack(stack.what(), newAmt)); } else { - dst[i] = null; + dst.add(null); } } - } - - @NotNull - @Override - public Map> getActionMap() { - return this.eap$actions; + return dst; } } \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerExPatternTerminalMixin.java b/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerExPatternTerminalMixin.java index e824e45..35d5d57 100644 --- a/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerExPatternTerminalMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerExPatternTerminalMixin.java @@ -1,41 +1,21 @@ package com.extendedae_plus.mixin.extendedae.container; -import appeng.api.util.IConfigurableObject; +import appeng.api.storage.IPatternAccessTermMenuHost; import appeng.menu.guisync.GuiSync; -import com.extendedae_plus.util.ExtendedAEPatternUploadUtil; import com.glodblock.github.extendedae.container.ContainerExPatternTerminal; -import com.glodblock.github.glodium.network.packet.sync.IActionHolder; -import com.glodblock.github.glodium.network.packet.sync.Paras; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.MenuProvider; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.Vec3; -import net.minecraftforge.network.NetworkHooks; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Map; -import java.util.function.Consumer; - -@Mixin(ContainerExPatternTerminal.class) -public abstract class ContainerExPatternTerminalMixin implements IActionHolder { +@Pseudo +@Mixin(value = ContainerExPatternTerminal.class, remap = false) +public abstract class ContainerExPatternTerminalMixin { @GuiSync(25564) @Unique @@ -56,142 +36,15 @@ public abstract class ContainerExPatternTerminalMixin implements IActionHolder { this.eap$hidePatternSlots = !this.eap$hidePatternSlots; } - @Unique - private Map> eap$actions; - @Unique private Player epp$player; @Unique private static final Logger EAP_LOGGER = LogManager.getLogger("ExtendedAE_Plus"); - @Inject(method = "*", at = @At("TAIL")) - private void init(int id, net.minecraft.world.entity.player.Inventory playerInventory, IConfigurableObject host, CallbackInfo ci) { - if (this.eap$actions == null) { - this.eap$actions = createHolder(); - } + @Inject(method = "*", at = @At("TAIL"), remap = false) + private void init(int id, net.minecraft.world.entity.player.Inventory playerInventory, IPatternAccessTermMenuHost host, CallbackInfo ci) { this.epp$player = playerInventory.player; - // 注册上传动作:参数顺序必须与客户端 CGenericPacket 保持一致 - this.eap$actions.put("upload", p -> { - try { - Object o0 = p.get(0); - Object o1 = p.get(1); - int playerSlotIndex = (o0 instanceof Number) ? ((Number) o0).intValue() : Integer.parseInt(String.valueOf(o0)); - long providerId = (o1 instanceof Number) ? ((Number) o1).longValue() : Long.parseLong(String.valueOf(o1)); - var sp = (ServerPlayer) this.epp$player; - ExtendedAEPatternUploadUtil.uploadPatternToProvider(sp, playerSlotIndex, providerId); - } catch (Throwable ignored) { - } - }); - - // 注册打开UI动作:open_ui(posLong, dimensionId, faceOrdinal?) - this.eap$actions.put("open_ui", p -> { - try { - // 参数解析 - Object po = p.get(0); // BlockPos as long (BlockPos#asLong) - Object do0 = p.get(1); // Dimension id string (e.g., minecraft:overworld) - Object fo; - try { - fo = p.get(2); // Optional face ordinal - } catch (Throwable __ignored) { - fo = null; - } - - long posLong = (po instanceof Number) ? ((Number) po).longValue() : Long.parseLong(String.valueOf(po)); - String dimStr = String.valueOf(do0); - int faceOrd = -1; - if (fo != null) { - faceOrd = (fo instanceof Number) ? ((Number) fo).intValue() : Integer.parseInt(String.valueOf(fo)); - } - - BlockPos pos = BlockPos.of(posLong); - ResourceLocation dimId = ResourceLocation.tryParse(dimStr); - if (dimId == null) { - EAP_LOGGER.warn("[EPlus] open_ui: invalid dim '{}'", dimStr); - return; - } - ResourceKey dimKey = ResourceKey.create(Registries.DIMENSION, dimId); - - if (!(this.epp$player instanceof ServerPlayer sp)) { - EAP_LOGGER.warn("[EPlus] open_ui: not a ServerPlayer"); - return; - } - - ServerLevel level = sp.server.getLevel(dimKey); - if (level == null) { - EAP_LOGGER.warn("[EPlus] open_ui: level null for key {}", dimKey); - return; - } - - EAP_LOGGER.debug("[EPlus] open_ui: pos={}, dim={}, faceOrd={}", pos, dimKey.location(), faceOrd); - - // 目标应为供应器所面向/连接的相邻方块,而非供应器自身 - Direction[] tries = (faceOrd >= 0 && faceOrd < Direction.values().length) - ? new Direction[]{Direction.values()[faceOrd]} - : Direction.values(); - - // 1) 先尝试在相邻方块直接打开 MenuProvider - for (Direction dir : tries) { - BlockPos targetPos = pos.relative(dir); - BlockEntity be = level.getBlockEntity(targetPos); - if (be instanceof MenuProvider provider) { - NetworkHooks.openScreen(sp, provider, targetPos); - EAP_LOGGER.debug("[EPlus] open_ui: opened BE MenuProvider at {} (neighbor via {})", targetPos, dir); - return; - } - var state = level.getBlockState(targetPos); - MenuProvider provider = state.getMenuProvider(level, targetPos); - if (provider != null) { - NetworkHooks.openScreen(sp, provider, targetPos); - EAP_LOGGER.debug("[EPlus] open_ui: opened State MenuProvider at {} (neighbor via {})", targetPos, dir); - return; - } - } - - // 2) 兜底:为避免误触发放置/覆盖,仅在手上至少有一只手为空时,使用 BlockState.use 进行一次“徒手交互” - boolean hasFace = (faceOrd >= 0 && faceOrd < Direction.values().length); - boolean anyHandEmpty = sp.getMainHandItem().isEmpty() || sp.getOffhandItem().isEmpty(); - if (anyHandEmpty) { - InteractionHand hand = sp.getMainHandItem().isEmpty() ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND; - if (hasFace) { - Direction dir = Direction.values()[faceOrd]; - BlockPos targetPos = pos.relative(dir); - var state2 = level.getBlockState(targetPos); - var hit = new BlockHitResult(Vec3.atCenterOf(targetPos), dir.getOpposite(), targetPos, false); - InteractionResult r = state2.use(level, sp, hand, hit); - EAP_LOGGER.debug("[EPlus] open_ui: fallback(state.use) at {} hit {} (via {}), result={}", targetPos, dir.getOpposite(), dir, r); - } else { - // 无朝向:优先尝试有方块实体的邻居,否则尝试实心方块邻居,各只尝试一次 - Direction chosen = null; - for (Direction d : Direction.values()) { - if (level.getBlockEntity(pos.relative(d)) != null) { chosen = d; break; } - } - if (chosen == null) { - for (Direction d : Direction.values()) { - if (!level.getBlockState(pos.relative(d)).isAir()) { chosen = d; break; } - } - } - if (chosen != null) { - BlockPos targetPos = pos.relative(chosen); - var state2 = level.getBlockState(targetPos); - var hit = new BlockHitResult(Vec3.atCenterOf(targetPos), chosen.getOpposite(), targetPos, false); - InteractionResult r = state2.use(level, sp, hand, hit); - EAP_LOGGER.debug("[EPlus] open_ui: fallback(state.use) at {} hit {} (auto via {}), result={}", targetPos, chosen.getOpposite(), chosen, r); - } else { - EAP_LOGGER.debug("[EPlus] open_ui: no neighbor candidate for fallback (faceOrd<0)"); - } - } - } else { - EAP_LOGGER.debug("[EPlus] open_ui: skip fallback (hands occupied)"); - } - } catch (Throwable ignored) { - } - }); - } - - @NotNull - @Override - public Map> getActionMap() { - return this.eap$actions; + // glodium IActionHolder 已移除,此处逻辑改为使用专用网络包的途径,详见 network 包。 } } \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerWirelessExPatternTerminalMixin.java b/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerWirelessExPatternTerminalMixin.java index 4355a40..0ed00b5 100644 --- a/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerWirelessExPatternTerminalMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerWirelessExPatternTerminalMixin.java @@ -1,57 +1,25 @@ package com.extendedae_plus.mixin.extendedae.container; -import com.extendedae_plus.util.ExtendedAEPatternUploadUtil; -import com.glodblock.github.extendedae.common.me.itemhost.HostWirelessExPAT; -import com.glodblock.github.extendedae.container.ContainerWirelessExPAT; -import com.glodblock.github.glodium.network.packet.sync.IActionHolder; -import com.glodblock.github.glodium.network.packet.sync.Paras; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.player.Player; -import org.jetbrains.annotations.NotNull; +import com.glodblock.github.extendedae.xmod.wt.ContainerWirelessExPAT; +import com.glodblock.github.extendedae.xmod.wt.HostWirelessExPAT; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Pseudo; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Map; -import java.util.function.Consumer; - /** * 为无线样板访问终端容器注册通用动作(CGenericPacket 分发) */ @Pseudo -@Mixin(ContainerWirelessExPAT.class) -public abstract class ContainerWirelessExPatternTerminalMixin implements IActionHolder { +@Mixin(value = ContainerWirelessExPAT.class, remap = false) +public abstract class ContainerWirelessExPatternTerminalMixin { + // 1.21 版本中 ExtendedAE 不再使用 glodium IActionHolder。 + // 保留空混入以便后续需要时扩展。 - @Unique - private final Map> eap$actions = createHolder(); - - @Unique - private Player epp$player; - - // 明确目标构造签名:(int, Inventory, HostWirelessExPAT) - @Inject(method = "(ILnet/minecraft/world/entity/player/Inventory;Lcom/glodblock/github/extendedae/common/me/itemhost/HostWirelessExPAT;)V", at = @At("TAIL"), require = 0) - private void init(int id, net.minecraft.world.entity.player.Inventory playerInventory, HostWirelessExPAT host, CallbackInfo ci) { - this.epp$player = playerInventory.player; - // 注册上传动作:参数顺序必须与客户端 CGenericPacket 保持一致 - this.eap$actions.put("upload", p -> { - try { - Object o0 = p.get(0); - Object o1 = p.get(1); - int playerSlotIndex = (o0 instanceof Number) ? ((Number) o0).intValue() : Integer.parseInt(String.valueOf(o0)); - long providerId = (o1 instanceof Number) ? ((Number) o1).longValue() : Long.parseLong(String.valueOf(o1)); - var sp = (ServerPlayer) this.epp$player; - ExtendedAEPatternUploadUtil.uploadPatternToProvider(sp, playerSlotIndex, providerId); - } catch (Throwable ignored) { - } - }); - } - - @NotNull - @Override - public Map> getActionMap() { - return this.eap$actions; + // 构造方法注入(显式签名),与 ExtendedAE 源码保持一致 + @Inject(method = "(ILnet/minecraft/world/entity/player/Inventory;Lcom/glodblock/github/extendedae/xmod/wt/HostWirelessExPAT;)V", at = @At("TAIL"), require = 0, remap = false) + private void init$eap(int id, net.minecraft.world.entity.player.Inventory playerInventory, HostWirelessExPAT host, CallbackInfo ci) { + // no-op } } diff --git a/src/main/resources/extendedaeplus.mixins.json b/src/main/resources/extendedaeplus.mixins.json index cb17956..d1d6275 100644 --- a/src/main/resources/extendedaeplus.mixins.json +++ b/src/main/resources/extendedaeplus.mixins.json @@ -12,9 +12,18 @@ "ae2.helpers.PatternProviderLogicAdvancedMixin", "ae2.helpers.PatternProviderLogicDoublingMixin", "ae2.AEProcessingPatternMixin", - "extendedae.client.gui.GuiExPatternProviderMixin", + "ae2.autopattern.CraftingTreeNodeAccessor", - "ae2.autopattern.CraftingTreeProcessMixin" + "ae2.autopattern.CraftingTreeProcessMixin", + "extendedae.common.PartExPatternProviderMixin", + "extendedae.common.TileExPatternProviderMixin", + "extendedae.container.ContainerExPatternProviderMixin", + "extendedae.container.ContainerExPatternTerminalMixin", + "extendedae.container.ContainerWirelessExPatternTerminalMixin" + ], + "client": [ + + "extendedae.accessor.GuiExPatternTerminalAccessor" ], "injectors": { "defaultRequire": 1