diff --git a/src/main/java/com/extendedae_plus/api/upload/IPatternEncodingShiftUploadSync.java b/src/main/java/com/extendedae_plus/api/upload/IPatternEncodingShiftUploadSync.java new file mode 100644 index 0000000..a11d784 --- /dev/null +++ b/src/main/java/com/extendedae_plus/api/upload/IPatternEncodingShiftUploadSync.java @@ -0,0 +1,13 @@ +package com.extendedae_plus.api.upload; + +public interface IPatternEncodingShiftUploadSync { + /** + * 由客户端发送的编码指令附带的 Shift 状态。 + */ + void eap$clientSetShiftUpload(boolean shiftDown); + + /** + * 服务器在处理 encode() 时消费该标记,并在读取后自动复位。 + */ + boolean eap$consumeShiftUploadFlag(); +} diff --git a/src/main/java/com/extendedae_plus/init/ModNetwork.java b/src/main/java/com/extendedae_plus/init/ModNetwork.java index 2b35201..234e388 100644 --- a/src/main/java/com/extendedae_plus/init/ModNetwork.java +++ b/src/main/java/com/extendedae_plus/init/ModNetwork.java @@ -7,6 +7,7 @@ import com.extendedae_plus.network.crafting.CraftingMonitorOpenProviderC2SPacket import com.extendedae_plus.network.crafting.OpenCraftFromJeiC2SPacket; import com.extendedae_plus.network.meInterface.InterfaceAdjustConfigAmountC2SPacket; import com.extendedae_plus.network.provider.*; +import com.extendedae_plus.network.upload.EncodeWithShiftFlagC2SPacket; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkDirection; import net.minecraftforge.network.NetworkRegistry; @@ -48,6 +49,12 @@ public final class ModNetwork { .consumerNetworkThread(PullFromJeiOrCraftC2SPacket::handle) .add(); + CHANNEL.messageBuilder(EncodeWithShiftFlagC2SPacket.class, nextId(), NetworkDirection.PLAY_TO_SERVER) + .encoder(EncodeWithShiftFlagC2SPacket::encode) + .decoder(EncodeWithShiftFlagC2SPacket::decode) + .consumerNetworkThread(EncodeWithShiftFlagC2SPacket::handle) + .add(); + CHANNEL.messageBuilder(UploadEncodedPatternToProviderC2SPacket.class, nextId(), NetworkDirection.PLAY_TO_SERVER) .encoder(UploadEncodedPatternToProviderC2SPacket::encode) .decoder(UploadEncodedPatternToProviderC2SPacket::decode) 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 67ab693..770a89e 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 @@ -1,24 +1,29 @@ package com.extendedae_plus.mixin.ae2.client.gui; +import appeng.api.config.ActionItems; import appeng.client.gui.Icon; import appeng.client.gui.me.items.PatternEncodingTermScreen; import appeng.client.gui.style.ScreenStyle; import appeng.client.gui.style.WidgetStyle; +import appeng.client.gui.widgets.ActionButton; import appeng.client.gui.widgets.IconButton; import com.extendedae_plus.init.ModNetwork; import com.extendedae_plus.mixin.ae2.accessor.AEBaseScreenAccessor; import com.extendedae_plus.mixin.minecraft.accessor.AbstractContainerScreenAccessor; import com.extendedae_plus.mixin.minecraft.accessor.ScreenAccessor; import com.extendedae_plus.network.provider.RequestProvidersListC2SPacket; +import com.extendedae_plus.network.upload.EncodeWithShiftFlagC2SPacket; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.renderer.Rect2i; import net.minecraft.network.chat.Component; import org.spongepowered.asm.mixin.Mixin; 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.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** @@ -32,6 +37,15 @@ public abstract class PatternEncodingTermScreenMixin { @Unique private IconButton eap$uploadBtn; + @ModifyVariable(method = "", at = @At(value = "STORE"), ordinal = 0) + private ActionButton eap$wrapEncodeButton(ActionButton original) { + return new ActionButton(ActionItems.ENCODE, act -> { + ModNetwork.CHANNEL.sendToServer(new EncodeWithShiftFlagC2SPacket(Screen.hasShiftDown())); + var screen = (PatternEncodingTermScreen) (Object) this; + screen.getMenu().encode(); + }); + } + // 只创建按钮 @Inject(method = "", at = @At("TAIL")) private void eap$createUploadButton(CallbackInfo ci) { 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 2018545..cbaed55 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 @@ -4,6 +4,7 @@ import appeng.api.crafting.PatternDetailsHelper; import appeng.menu.me.items.PatternEncodingTermMenu; import appeng.menu.slot.RestrictedInputSlot; import appeng.parts.encoding.EncodingMode; +import com.extendedae_plus.api.upload.IPatternEncodingShiftUploadSync; import com.extendedae_plus.util.uploadPattern.MatrixUploadUtil; import com.glodblock.github.glodium.network.packet.sync.IActionHolder; import com.glodblock.github.glodium.network.packet.sync.Paras; @@ -27,7 +28,7 @@ import java.util.function.Consumer; * 注册动作 "upload_to_matrix":仅上传“合成图样”到 ExtendedAE 装配矩阵。 */ @Mixin(PatternEncodingTermMenu.class) -public abstract class ContainerPatternEncodingTermMenuMixin implements IActionHolder { +public abstract class ContainerPatternEncodingTermMenuMixin implements IActionHolder, IPatternEncodingShiftUploadSync { @Unique private final Map> eap$actions = createHolder(); @@ -35,6 +36,9 @@ public abstract class ContainerPatternEncodingTermMenuMixin implements IActionHo @Unique private Player epp$player; + @Unique + private boolean eap$pendingShiftUpload; + @Shadow(remap = false) private RestrictedInputSlot encodedPatternSlot; @@ -73,6 +77,20 @@ public abstract class ContainerPatternEncodingTermMenuMixin implements IActionHo // 不再注册任何上传相关动作 } + @Unique + @Override + public void eap$clientSetShiftUpload(boolean shiftDown) { + this.eap$pendingShiftUpload = shiftDown; + } + + @Unique + @Override + public boolean eap$consumeShiftUploadFlag() { + boolean flag = this.eap$pendingShiftUpload; + this.eap$pendingShiftUpload = false; + return flag; + } + @NotNull @Override public Map> getActionMap() { @@ -86,6 +104,9 @@ public abstract class ContainerPatternEncodingTermMenuMixin implements IActionHo if (!(this.epp$player instanceof ServerPlayer sp)) { return; // 仅服务器执行 } + if (!this.eap$consumeShiftUploadFlag()) { + return; // 未按下 Shift,不自动上传 + } var menu = (PatternEncodingTermMenu) (Object) this; if (menu.getMode() != EncodingMode.CRAFTING && menu.getMode() != EncodingMode.SMITHING_TABLE diff --git a/src/main/java/com/extendedae_plus/network/upload/EncodeWithShiftFlagC2SPacket.java b/src/main/java/com/extendedae_plus/network/upload/EncodeWithShiftFlagC2SPacket.java new file mode 100644 index 0000000..c736561 --- /dev/null +++ b/src/main/java/com/extendedae_plus/network/upload/EncodeWithShiftFlagC2SPacket.java @@ -0,0 +1,38 @@ +package com.extendedae_plus.network.upload; + +import appeng.menu.me.items.PatternEncodingTermMenu; +import com.extendedae_plus.api.upload.IPatternEncodingShiftUploadSync; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.network.NetworkEvent; + +import java.util.function.Supplier; + +/** + * 客户端在点击编码按钮时发送一次,携带当前是否按下 Shift。 + */ +public record EncodeWithShiftFlagC2SPacket(boolean shiftDown) { + + public static void encode(EncodeWithShiftFlagC2SPacket msg, FriendlyByteBuf buf) { + buf.writeBoolean(msg.shiftDown()); + } + + public static EncodeWithShiftFlagC2SPacket decode(FriendlyByteBuf buf) { + return new EncodeWithShiftFlagC2SPacket(buf.readBoolean()); + } + + public static void handle(EncodeWithShiftFlagC2SPacket msg, Supplier ctxSupplier) { + var ctx = ctxSupplier.get(); + ctx.enqueueWork(() -> { + ServerPlayer player = ctx.getSender(); + if (player == null) { + return; + } + if (player.containerMenu instanceof PatternEncodingTermMenu menu + && menu instanceof IPatternEncodingShiftUploadSync sync) { + sync.eap$clientSetShiftUpload(msg.shiftDown()); + } + }); + ctx.setPacketHandled(true); + } +}