From 29b92e4ee174b25e39599663dfc74eee7b2357e8 Mon Sep 17 00:00:00 2001 From: C-H716 <1536152356@qq.com> Date: Tue, 2 Sep 2025 02:36:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E4=B8=BA=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E7=AB=AF=E5=90=91=E7=9B=AE=E6=A0=87=E7=8E=A9=E5=AE=B6?= =?UTF-8?q?=E5=8F=91=E9=80=81=E6=A0=B7=E6=9D=BF=E9=AB=98=E4=BA=AE=E5=8C=85?= =?UTF-8?q?=EF=BC=8C=E7=A7=BB=E9=99=A4=E5=85=A8=E5=B1=80=E9=AB=98=E4=BA=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/ClientPatternHighlightStore.java | 34 ++++++++++++++ .../ae2/client/gui/AEBaseScreenMixin.java | 17 ++++--- .../client/gui/PatternProviderCloseMixin.java | 4 +- .../CraftingMonitorOpenProviderC2SPacket.java | 8 +++- .../extendedae_plus/network/ModNetwork.java | 6 +++ .../network/SetPatternHighlightS2CPacket.java | 45 +++++++++++++++++++ 6 files changed, 104 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/extendedae_plus/content/ClientPatternHighlightStore.java create mode 100644 src/main/java/com/extendedae_plus/network/SetPatternHighlightS2CPacket.java diff --git a/src/main/java/com/extendedae_plus/content/ClientPatternHighlightStore.java b/src/main/java/com/extendedae_plus/content/ClientPatternHighlightStore.java new file mode 100644 index 0000000..2e9f0c4 --- /dev/null +++ b/src/main/java/com/extendedae_plus/content/ClientPatternHighlightStore.java @@ -0,0 +1,34 @@ +package com.extendedae_plus.content; + +import appeng.api.stacks.AEKey; +import appeng.api.crafting.IPatternDetails; +import appeng.client.gui.me.patternaccess.PatternContainerRecord; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * 客户端本地的高亮存储,仅作用于接收该客户端。 + * 使用 AEKey 作为标识,渲染时可通过 AEKey 与本地解码的 IPatternDetails 比对。 + */ +public final class ClientPatternHighlightStore { + private static final Set HIGHLIGHTS = Collections.synchronizedSet(new HashSet<>()); + + private ClientPatternHighlightStore() {} + + public static void setHighlight(AEKey key, boolean highlight) { + if (key == null) return; + if (highlight) HIGHLIGHTS.add(key); + else HIGHLIGHTS.remove(key); + } + + public static boolean hasHighlight(AEKey key) { + if (key == null) return false; + return HIGHLIGHTS.contains(key); + } + + public static void clearAll() { HIGHLIGHTS.clear(); } +} + + 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 0e857dc..0fcb7bd 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 @@ -13,7 +13,7 @@ import appeng.client.gui.style.Text; import appeng.client.gui.style.TextAlignment; import appeng.menu.slot.AppEngSlot; import com.extendedae_plus.api.ExPatternPageAccessor; -import com.extendedae_plus.content.PatternHighlightStore; +import com.extendedae_plus.content.ClientPatternHighlightStore; import com.extendedae_plus.network.CraftingMonitorJumpC2SPacket; import com.extendedae_plus.network.CraftingMonitorOpenProviderC2SPacket; import com.extendedae_plus.network.ModNetwork; @@ -182,11 +182,16 @@ public abstract class AEBaseScreenMixin { try { var details = PatternDetailsHelper.decodePattern(itemStack, Minecraft.getInstance().level, false); - if (PatternHighlightStore.getHighlight(details)) { - try { - GuiUtil.drawSlotRainbowHighlight(guiGraphics, s.x, s.y); - } catch (Throwable ignored) {} - } + try { + if (details != null && details.getOutputs() != null && details.getOutputs().length > 0) { + AEKey key = details.getOutputs()[0].what(); + if (key != null && ClientPatternHighlightStore.hasHighlight(key)) { + try { + GuiUtil.drawSlotRainbowHighlight(guiGraphics, s.x, s.y); + } catch (Throwable ignored) {} + } + } + } catch (Throwable ignore) {} } catch (Throwable ignore) {} } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderCloseMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderCloseMixin.java index eed7a29..767e888 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderCloseMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderCloseMixin.java @@ -1,7 +1,7 @@ package com.extendedae_plus.mixin.ae2.client.gui; import appeng.client.gui.implementations.PatternProviderScreen; -import com.extendedae_plus.content.PatternHighlightStore; +import com.extendedae_plus.content.ClientPatternHighlightStore; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.world.inventory.AbstractContainerMenu; import org.spongepowered.asm.mixin.Mixin; @@ -20,7 +20,7 @@ public class PatternProviderCloseMixin { private void onRemoved(CallbackInfo ci) { try { if (((Object) this) instanceof PatternProviderScreen) { - PatternHighlightStore.clearAll(); + ClientPatternHighlightStore.clearAll(); } } catch (Throwable ignored) { } diff --git a/src/main/java/com/extendedae_plus/network/CraftingMonitorOpenProviderC2SPacket.java b/src/main/java/com/extendedae_plus/network/CraftingMonitorOpenProviderC2SPacket.java index 20bfabf..c3a258e 100644 --- a/src/main/java/com/extendedae_plus/network/CraftingMonitorOpenProviderC2SPacket.java +++ b/src/main/java/com/extendedae_plus/network/CraftingMonitorOpenProviderC2SPacket.java @@ -94,6 +94,12 @@ public class CraftingMonitorOpenProviderC2SPacket { // 直接打开供应器自身的 UI(调用 Host 默认方法) try { + // 告知目标玩家客户端高亮该 AEKey(避免全局服务端状态污染) + try { + AEKey key = pattern.getOutputs()[0].what(); + ModNetwork.CHANNEL.sendTo(new SetPatternHighlightS2CPacket(key, true), player.connection.connection, net.minecraftforge.network.NetworkDirection.PLAY_TO_CLIENT); + } catch (Throwable t) {} + // 部件与方块实体分别选择定位器 if (host instanceof AEBasePart part) { host.openMenu(player, MenuLocators.forPart(part)); @@ -101,8 +107,6 @@ public class CraftingMonitorOpenProviderC2SPacket { host.openMenu(player, MenuLocators.forBlockEntity(pbe)); } - PatternHighlightStore.setHighlight(pattern, true); - context.setPacketHandled(true); return; } catch (Throwable t) { diff --git a/src/main/java/com/extendedae_plus/network/ModNetwork.java b/src/main/java/com/extendedae_plus/network/ModNetwork.java index a869cfe..8b4599c 100644 --- a/src/main/java/com/extendedae_plus/network/ModNetwork.java +++ b/src/main/java/com/extendedae_plus/network/ModNetwork.java @@ -60,6 +60,12 @@ public class ModNetwork { .consumerNetworkThread(ProvidersListS2CPacket::handle) .add(); + CHANNEL.messageBuilder(SetPatternHighlightS2CPacket.class, nextId(), NetworkDirection.PLAY_TO_CLIENT) + .encoder(SetPatternHighlightS2CPacket::encode) + .decoder(SetPatternHighlightS2CPacket::decode) + .consumerNetworkThread(SetPatternHighlightS2CPacket::handle) + .add(); + CHANNEL.messageBuilder(ToggleAdvancedBlockingC2SPacket.class, nextId(), NetworkDirection.PLAY_TO_SERVER) .encoder(ToggleAdvancedBlockingC2SPacket::encode) .decoder(ToggleAdvancedBlockingC2SPacket::decode) diff --git a/src/main/java/com/extendedae_plus/network/SetPatternHighlightS2CPacket.java b/src/main/java/com/extendedae_plus/network/SetPatternHighlightS2CPacket.java new file mode 100644 index 0000000..6da5fda --- /dev/null +++ b/src/main/java/com/extendedae_plus/network/SetPatternHighlightS2CPacket.java @@ -0,0 +1,45 @@ +package com.extendedae_plus.network; + +import appeng.api.stacks.AEKey; +import com.extendedae_plus.content.ClientPatternHighlightStore; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraftforge.network.NetworkEvent; + +import java.util.function.Supplier; + +/** + * S2C: 指示客户端对某个 AEKey 的样板进行高亮/取消高亮(仅作用于接收该包的客户端) + */ +public class SetPatternHighlightS2CPacket { + private final AEKey key; + private final boolean highlight; + + public SetPatternHighlightS2CPacket(AEKey key, boolean highlight) { + this.key = key; + this.highlight = highlight; + } + + public static void encode(SetPatternHighlightS2CPacket msg, FriendlyByteBuf buf) { + AEKey.writeKey(buf, msg.key); + buf.writeBoolean(msg.highlight); + } + + public static SetPatternHighlightS2CPacket decode(FriendlyByteBuf buf) { + AEKey key = AEKey.readKey(buf); + boolean h = buf.readBoolean(); + return new SetPatternHighlightS2CPacket(key, h); + } + + public static void handle(SetPatternHighlightS2CPacket msg, Supplier ctxSupplier) { + var ctx = ctxSupplier.get(); + ctx.enqueueWork(() -> { + try { + ClientPatternHighlightStore.setHighlight(msg.key, msg.highlight); + } catch (Throwable ignored) { + } + }); + ctx.setPacketHandled(true); + } +} + +