From 319253d6f91bd4900b50b667914ec57fb67fb3fe Mon Sep 17 00:00:00 2001 From: GaLicn <3096147684@qq.com> Date: Tue, 12 Aug 2025 22:39:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=89=93=E5=BC=80=E6=A0=B7?= =?UTF-8?q?=E6=9D=BF=E7=BC=96=E7=A0=81=E7=BB=88=E7=AB=AF=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=A1=AB=E5=85=85=E6=A0=B7=E6=9D=BF=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle.properties | 2 +- .../mixin/PatternEncodingTermMenuMixin.java | 159 ++++++++++++++++++ .../mixin/accessor/MEStorageMenuAccessor.java | 24 +++ .../resources/extendedae_plus.mixins.json | 4 +- 4 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/extendedae_plus/mixin/PatternEncodingTermMenuMixin.java create mode 100644 src/main/java/com/extendedae_plus/mixin/accessor/MEStorageMenuAccessor.java diff --git a/gradle.properties b/gradle.properties index 03ffbb7..47e1b47 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1G loom.platform = forge # Mod properties -mod_version = 1.1.3 +mod_version = 1.1.4 maven_group = com.extendedae_plus archives_name = extendedae_plus diff --git a/src/main/java/com/extendedae_plus/mixin/PatternEncodingTermMenuMixin.java b/src/main/java/com/extendedae_plus/mixin/PatternEncodingTermMenuMixin.java new file mode 100644 index 0000000..d17f475 --- /dev/null +++ b/src/main/java/com/extendedae_plus/mixin/PatternEncodingTermMenuMixin.java @@ -0,0 +1,159 @@ +package com.extendedae_plus.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.MenuType; + +import appeng.api.inventories.InternalInventory; +import appeng.api.networking.energy.IEnergySource; +import appeng.api.storage.MEStorage; +import appeng.api.storage.StorageHelper; +import appeng.api.stacks.AEItemKey; +import appeng.api.stacks.AEKey; +import appeng.core.definitions.AEItems; +import appeng.helpers.IPatternTerminalMenuHost; +import appeng.menu.me.items.PatternEncodingTermMenu; +import appeng.api.networking.security.IActionSource; +import appeng.menu.slot.RestrictedInputSlot; +import appeng.menu.me.common.MEStorageMenu; +import com.extendedae_plus.mixin.accessor.MEStorageMenuAccessor; + +@Mixin(PatternEncodingTermMenu.class) +public abstract class PatternEncodingTermMenuMixin { + + // 防止重复执行 + @org.spongepowered.asm.mixin.Unique + private boolean extendedae_plus$blankAutoFilled = false; + + @Shadow + private RestrictedInputSlot blankPatternSlot; + + @org.spongepowered.asm.mixin.Unique + private void extendedae_plus$tryFill(IPatternTerminalMenuHost host, Inventory ip) { + try { + var self = (PatternEncodingTermMenu) (Object) this; + var player = ip.player; + // 仅在服务器端执行 + if (ip.player.level().isClientSide()) { + return; + } + // 必须可与网络交互 + var acc = (MEStorageMenuAccessor) (Object) ((MEStorageMenu) self); + MEStorage storage = acc.getStorage(); + IEnergySource power = acc.getPowerSource(); + boolean hasPower = acc.getHasPower(); + boolean canInteract = storage != null && power != null && hasPower; // 等价于 canInteractWithGrid() + if (!canInteract) { + return; + } + if (storage == null || power == null) { + return; + } + + InternalInventory blankInv = host.getLogic().getBlankPatternInv(); + 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()); + if (space <= 0) { + return; // 已满,无需填充 + } + + AEKey blankKey = AEItemKey.of(AEItems.BLANK_PATTERN.asItem()); + long extracted = StorageHelper.poweredExtraction(power, storage, blankKey, space, + self.getActionSource()); + if (extracted <= 0) { + return; // 网络无可用空白样板 + } + + int toInsert = (int) Math.min(extracted, space); + var stackInSlot = this.blankPatternSlot.getItem(); + if (stackInSlot.isEmpty()) { + this.blankPatternSlot.set(AEItems.BLANK_PATTERN.stack(toInsert)); + } else { + stackInSlot.grow(toInsert); + this.blankPatternSlot.set(stackInSlot); + } + long leftover = extracted - toInsert; + if (leftover > 0) { + StorageHelper.poweredInsert(power, storage, blankKey, leftover, self.getActionSource()); + } + } catch (Throwable t) { + // swallow errors to avoid noisy logs in production + } + } + + @Inject(method = "(Lnet/minecraft/world/inventory/MenuType;ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/IPatternTerminalMenuHost;Z)V", + at = @At("TAIL")) + private void extendedae_plus$autoFillBlankPattern(MenuType menuType, int id, Inventory ip, + IPatternTerminalMenuHost host, boolean bindInventory, + CallbackInfo ci) { + extendedae_plus$tryFill(host, ip); + } + + @Inject(method = "(ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/IPatternTerminalMenuHost;)V", + at = @At("TAIL")) + private void extendedae_plus$autoFillCtor3(int id, Inventory ip, IPatternTerminalMenuHost host, CallbackInfo ci) { + extendedae_plus$tryFill(host, ip); + } + + // 在首次 broadcastChanges 后再尝试一次,避免构造时网络未激活 + @Inject(method = "broadcastChanges", at = @At("TAIL")) + private void extendedae_plus$retryFillAfterPower(CallbackInfo ci) { + if (this.extendedae_plus$blankAutoFilled) { + return; + } + // 仅在服务器端执行 + var self = (PatternEncodingTermMenu) (Object) this; + var player = self.getPlayerInventory().player; + var acc = (MEStorageMenuAccessor) (Object) ((MEStorageMenu) self); + MEStorage storage = acc.getStorage(); + IEnergySource power = acc.getPowerSource(); + boolean hasPower = acc.getHasPower(); + if (player.level().isClientSide()) { + return; + } + boolean canInteract = storage != null && power != null && hasPower; + if (!canInteract) { + return; + } + // 通过 host 获取 blankPatternInv + var host = ((IPatternTerminalMenuHost) self.getTarget()); + InternalInventory blankInv = host.getLogic().getBlankPatternInv(); + 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()); + if (space <= 0) { + this.extendedae_plus$blankAutoFilled = true; + return; + } + + AEKey blankKey = AEItemKey.of(AEItems.BLANK_PATTERN.asItem()); + long extracted = StorageHelper.poweredExtraction(power, storage, blankKey, space, + self.getActionSource()); + if (extracted <= 0) { + return; + } + int toInsert = (int) Math.min(extracted, space); + var stackInSlot = this.blankPatternSlot.getItem(); + if (stackInSlot.isEmpty()) { + this.blankPatternSlot.set(AEItems.BLANK_PATTERN.stack(toInsert)); + } else { + stackInSlot.grow(toInsert); + this.blankPatternSlot.set(stackInSlot); + } + long leftover = extracted - toInsert; + if (leftover > 0) { + StorageHelper.poweredInsert(power, storage, blankKey, leftover, self.getActionSource()); + } + this.extendedae_plus$blankAutoFilled = true; + } +} diff --git a/src/main/java/com/extendedae_plus/mixin/accessor/MEStorageMenuAccessor.java b/src/main/java/com/extendedae_plus/mixin/accessor/MEStorageMenuAccessor.java new file mode 100644 index 0000000..fc8cbe9 --- /dev/null +++ b/src/main/java/com/extendedae_plus/mixin/accessor/MEStorageMenuAccessor.java @@ -0,0 +1,24 @@ +package com.extendedae_plus.mixin.accessor; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import org.jetbrains.annotations.Nullable; + +import appeng.api.networking.energy.IEnergySource; +import appeng.api.storage.MEStorage; +import appeng.menu.me.common.MEStorageMenu; + +@Mixin(MEStorageMenu.class) +public interface MEStorageMenuAccessor { + @Accessor("storage") + @Nullable + MEStorage getStorage(); + + @Accessor("powerSource") + @Nullable + IEnergySource getPowerSource(); + + @Accessor("hasPower") + boolean getHasPower(); +} diff --git a/src/main/resources/extendedae_plus.mixins.json b/src/main/resources/extendedae_plus.mixins.json index cd29762..5116de5 100644 --- a/src/main/resources/extendedae_plus.mixins.json +++ b/src/main/resources/extendedae_plus.mixins.json @@ -15,7 +15,9 @@ "ContainerWirelessExPatternTerminalMixin", "ContainerUWirelessExPatternTerminalMixin", "TileExPatternProviderMixin", - "PartExPatternProviderMixin" + "PartExPatternProviderMixin", + "PatternEncodingTermMenuMixin", + "accessor.MEStorageMenuAccessor" ], "injectors": { "defaultRequire": 1