From b86ac6867ac2a51c8300143b519896f687380725 Mon Sep 17 00:00:00 2001 From: GaLi <3096147684@qq.com> Date: Thu, 26 Mar 2026 17:45:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=A2=91=E9=81=93=E5=8D=A1?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PatternProviderLogicCompatMixin.java | 83 ++++++++---------- .../InterfaceLogicChannelCardMixin.java | 38 +++------ .../helpers/InterfaceLogicTickerMixin.java | 9 +- .../PatternProviderLogicUpgradesMixin.java | 5 +- .../PatternProviderLogicTickerMixin.java | 5 +- .../automation/IOBusPartChannelCardMixin.java | 56 ++++++------ .../StorageBusPartChannelCardMixin.java | 56 ++++++------ .../util/wireless/ChannelCardLinkHelper.java | 85 +++++++++++++++++++ 8 files changed, 209 insertions(+), 128 deletions(-) create mode 100644 src/main/java/com/extendedae_plus/util/wireless/ChannelCardLinkHelper.java diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java index 225a7ce..87bc318 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java @@ -9,6 +9,7 @@ import appeng.api.stacks.KeyCounter; import appeng.api.upgrades.IUpgradeInventory; import appeng.api.upgrades.IUpgradeableObject; import appeng.api.upgrades.UpgradeInventories; +import appeng.blockentity.AEBaseBlockEntity; import appeng.helpers.patternprovider.PatternProviderLogic; import appeng.helpers.patternprovider.PatternProviderLogicHost; import appeng.me.cluster.implementations.CraftingCPUCluster; @@ -20,11 +21,11 @@ import com.extendedae_plus.api.bridge.PatternProviderLogicUpgradeCompatBridge; import com.extendedae_plus.compat.PatternProviderLogicVirtualCompatBridge; import com.extendedae_plus.compat.UpgradeSlotCompat; import com.extendedae_plus.init.ModItems; -import com.extendedae_plus.items.materials.ChannelCardItem; import com.extendedae_plus.mixin.ae2.accessor.CraftingCpuLogicAccessor; import com.extendedae_plus.mixin.ae2.accessor.ExecutingCraftingJobAccessor; import com.extendedae_plus.mixin.appflux.accessor.PatternProviderLogicAppfluxAccessor; import com.extendedae_plus.util.ExtendedAELogger; +import com.extendedae_plus.util.wireless.ChannelCardLinkHelper; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -102,7 +103,7 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr @Unique private void eap$compatOnUpgradesChanged() { try { - this.host.saveChanges(); + this.eap$compatNotifyHostChanged(); this.eap$compatLastChannel = -1; this.eap$compatLastOwner = null; this.eap$compatHasInitialized = false; @@ -191,7 +192,11 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr @Override public void eap$updateWirelessLink() { if (this.eap$compatLink != null) { + boolean wasConnected = this.eap$compatLink.isConnected(); this.eap$compatLink.updateStatus(); + if (wasConnected != this.eap$compatLink.isConnected()) { + this.eap$compatNotifyHostChanged(); + } } } @@ -239,21 +244,10 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr if (this.host.getBlockEntity() == null || this.host.getBlockEntity().getLevel() == null || this.host.getBlockEntity().getLevel().isClientSide) { return false; } - // 未初始化:需要继续tick直到初始化完成 - if (!this.eap$compatHasInitialized) { - return true; - } - // 有频道卡但链接未连上:保持tick - IUpgradeInventory upgrades = this.eap$compatGetEffectiveUpgrades(); - if (upgrades != null && this.eap$hasChannelCard(upgrades)) { - if (this.eap$compatLink == null || !this.eap$compatLink.isConnected()) { - return true; - } - } - // 链接存在但未连接:保持tick - if (this.eap$compatLink != null && !this.eap$compatLink.isConnected()) { - return true; - } + return ChannelCardLinkHelper.shouldKeepTicking( + this.eap$compatGetEffectiveUpgrades(), + this.eap$compatLink, + this.eap$compatHasInitialized); } catch (Throwable ignored) { } return false; @@ -300,34 +294,20 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr } } - if (upgrades != null) { - for (ItemStack stack : upgrades) { - if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) { - channel = ChannelCardItem.getChannel(stack); - owner = ChannelCardItem.getOwnerUUID(stack); - if (owner == null) { - owner = this.eap$getFallbackOwner(); - } - found = true; - break; - } - } + var boundChannel = ChannelCardLinkHelper.findBoundChannel(upgrades, this::eap$getFallbackOwner); + if (boundChannel != null) { + channel = boundChannel.channel(); + owner = boundChannel.owner(); + found = true; } if (!found) { this.eap$compatSyncVirtualCraftingState(); - if (this.eap$compatLink != null) { - this.eap$compatLink.setPlacerId(null); - this.eap$compatLink.setFrequency(0L); - this.eap$compatLink.updateStatus(); - } + ChannelCardLinkHelper.disconnect(this.eap$compatLink); this.eap$compatLastChannel = 0L; this.eap$compatLastOwner = null; this.eap$compatHasInitialized = true; - try { - this.host.saveChanges(); - } catch (Throwable ignored) { - } + this.eap$compatNotifyHostChanged(); // 唤醒节点,加速 AE2 感知到连接断开 this.mainNode.ifPresent((grid, node) -> { try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {} @@ -348,9 +328,8 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr return; } - boolean sameOwner = (this.eap$compatLastOwner == null && owner == null) - || (this.eap$compatLastOwner != null && this.eap$compatLastOwner.equals(owner)); - if (this.eap$compatLink != null && this.eap$compatLastChannel == channel && sameOwner) { + if (this.eap$compatLink != null + && ChannelCardLinkHelper.sameTarget(this.eap$compatLastChannel, this.eap$compatLastOwner, boundChannel)) { if (this.eap$compatLink.isConnected()) { this.eap$compatHasInitialized = true; } @@ -367,10 +346,7 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr this.eap$compatLink.updateStatus(); this.eap$compatLastChannel = channel; // 记录当前频道 this.eap$compatLastOwner = owner; - try { - this.host.saveChanges(); - } catch (Throwable ignored) { - } + this.eap$compatNotifyHostChanged(); this.mainNode.ifPresent((grid, node) -> { try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {} }); @@ -399,10 +375,25 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr return null; } + @Unique + private void eap$compatNotifyHostChanged() { + try { + this.host.saveChanges(); + } catch (Throwable ignored) { + } + + try { + if (this.host.getBlockEntity() instanceof AEBaseBlockEntity blockEntity) { + blockEntity.markForUpdate(); + } + } catch (Throwable ignored) { + } + } + // CompatUpgradeProvider 实现:仅在未安装 appflux 时由我们提供升级槽 @Unique private boolean eap$hasChannelCard(IUpgradeInventory inventory) { - return this.eap$compatInventoryContains(inventory, ModItems.CHANNEL_CARD.get()); + return ChannelCardLinkHelper.hasChannelCard(inventory); } /** diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelCardMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelCardMixin.java index 51a3eac..6d080cf 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelCardMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelCardMixin.java @@ -6,9 +6,7 @@ import appeng.helpers.InterfaceLogicHost; import com.extendedae_plus.ae.wireless.WirelessSlaveLink; import com.extendedae_plus.ae.wireless.endpoint.InterfaceNodeEndpointImpl; import com.extendedae_plus.api.bridge.InterfaceWirelessLinkBridge; -import com.extendedae_plus.init.ModItems; -import com.extendedae_plus.items.materials.ChannelCardItem; -import net.minecraft.world.item.ItemStack; +import com.extendedae_plus.util.wireless.ChannelCardLinkHelper; import java.util.UUID; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -118,6 +116,11 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles this.eap$hasInitialized = initialized; } + @Override + public boolean eap$shouldKeepTicking() { + return ChannelCardLinkHelper.shouldKeepTicking(this.getUpgrades(), this.eap$link, this.eap$hasInitialized); + } + @Override @Unique public void eap$initializeChannelLink() { @@ -137,28 +140,14 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles } try { - long channel = 0L; - boolean found = false; - UUID owner = null; - for (ItemStack stack : this.getUpgrades()) { - if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) { - channel = ChannelCardItem.getChannel(stack); - owner = ChannelCardItem.getOwnerUUID(stack); - if (owner == null) { - owner = this.eap$getFallbackOwner(); - } - found = true; - break; - } - } + var boundChannel = ChannelCardLinkHelper.findBoundChannel(this.getUpgrades(), this::eap$getFallbackOwner); + long channel = boundChannel != null ? boundChannel.channel() : 0L; + boolean found = boundChannel != null; + UUID owner = boundChannel != null ? boundChannel.owner() : null; if (!found) { // 无频道卡:断开并视为初始化完成 - if (this.eap$link != null) { - this.eap$link.setPlacerId(null); - this.eap$link.setFrequency(0L); - this.eap$link.updateStatus(); - } + ChannelCardLinkHelper.disconnect(this.eap$link); this.eap$hasInitialized = true; this.eap$lastChannel = 0L; this.eap$lastOwner = null; @@ -176,9 +165,8 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles return; } - boolean sameOwner = (this.eap$lastOwner == null && owner == null) - || (this.eap$lastOwner != null && this.eap$lastOwner.equals(owner)); - if (this.eap$link != null && this.eap$lastChannel == channel && sameOwner) { + if (this.eap$link != null + && ChannelCardLinkHelper.sameTarget(this.eap$lastChannel, this.eap$lastOwner, boundChannel)) { this.eap$hasInitialized = this.eap$link.isConnected(); return; } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicTickerMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicTickerMixin.java index 28bdc5a..85e0b8a 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicTickerMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicTickerMixin.java @@ -1,5 +1,6 @@ package com.extendedae_plus.mixin.ae2.helpers; +import appeng.api.networking.ticking.TickRateModulation; import appeng.helpers.InterfaceLogic; import com.extendedae_plus.api.bridge.InterfaceWirelessLinkBridge; import org.spongepowered.asm.mixin.Final; @@ -32,11 +33,17 @@ public abstract class InterfaceLogicTickerMixin { } } - @Inject(method = "tickingRequest", at = @At("TAIL"), remap = false) + @Inject(method = "tickingRequest", at = @At("TAIL"), remap = false, cancellable = true) private void eap$tickTail(appeng.api.networking.IGridNode node, int ticksSinceLastCall, CallbackInfoReturnable cir) { + if (node != null && node.getLevel() != null && node.getLevel().isClientSide) { + return; + } if (this.this$0 instanceof InterfaceWirelessLinkBridge bridge) { bridge.eap$updateWirelessLink(); + if (bridge.eap$shouldKeepTicking() && cir.getReturnValue() == TickRateModulation.SLEEP) { + cir.setReturnValue(TickRateModulation.SLOWER); + } } } } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicUpgradesMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicUpgradesMixin.java index 6fc73ef..6a1e2d1 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicUpgradesMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicUpgradesMixin.java @@ -6,6 +6,7 @@ import appeng.api.upgrades.UpgradeInventories; import appeng.helpers.patternprovider.PatternProviderLogic; import appeng.helpers.patternprovider.PatternProviderLogicHost; import com.extendedae_plus.api.bridge.PatternProviderLogicAppfluxBridge; +import com.extendedae_plus.api.bridge.PatternProviderLogicUpgradeCompatBridge; import com.extendedae_plus.compat.UpgradeSlotCompat; import com.extendedae_plus.mixin.appflux.accessor.PatternProviderLogicAppfluxAccessor; import com.extendedae_plus.util.ExtendedAELogger; @@ -113,10 +114,10 @@ public abstract class PatternProviderLogicUpgradesMixin implements PatternProvid this.host.saveChanges(); try { ((PatternProviderLogicAppfluxAccessor) (Object) this).eap$invokeAppfluxUpgradesChanged(); - return; } catch (Throwable ignored) { } - if ((Object) this instanceof com.extendedae_plus.api.bridge.PatternProviderLogicUpgradeCompatBridge bridge) { + + if ((Object) this instanceof PatternProviderLogicUpgradeCompatBridge bridge) { bridge.eap$onCompatUpgradesChangedHook(); } } catch (Throwable t) { diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/patternprovider/PatternProviderLogicTickerMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/patternprovider/PatternProviderLogicTickerMixin.java index 97b8438..74d240e 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/patternprovider/PatternProviderLogicTickerMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/patternprovider/PatternProviderLogicTickerMixin.java @@ -1,6 +1,7 @@ package com.extendedae_plus.mixin.ae2.helpers.patternprovider; import appeng.helpers.patternprovider.PatternProviderLogic; +import appeng.api.networking.ticking.TickRateModulation; import com.extendedae_plus.api.bridge.InterfaceWirelessLinkBridge; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -41,8 +42,8 @@ public abstract class PatternProviderLogicTickerMixin { } if (this.this$0 instanceof InterfaceWirelessLinkBridge bridge) { bridge.eap$updateWirelessLink(); - if (bridge.eap$shouldKeepTicking()) { - cir.setReturnValue(appeng.api.networking.ticking.TickRateModulation.SLOWER); + if (bridge.eap$shouldKeepTicking() && cir.getReturnValue() == TickRateModulation.SLEEP) { + cir.setReturnValue(TickRateModulation.SLOWER); } } } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartChannelCardMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartChannelCardMixin.java index 1d9480f..01337ee 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartChannelCardMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartChannelCardMixin.java @@ -1,15 +1,15 @@ package com.extendedae_plus.mixin.ae2.parts.automation; import appeng.api.networking.security.IActionHost; +import appeng.api.networking.ticking.TickRateModulation; import appeng.api.upgrades.IUpgradeInventory; import appeng.api.upgrades.IUpgradeableObject; import appeng.parts.automation.IOBusPart; import com.extendedae_plus.ae.wireless.WirelessSlaveLink; import com.extendedae_plus.ae.wireless.endpoint.GenericNodeEndpointImpl; import com.extendedae_plus.api.bridge.InterfaceWirelessLinkBridge; -import com.extendedae_plus.init.ModItems; -import com.extendedae_plus.items.materials.ChannelCardItem; import com.extendedae_plus.util.ExtendedAELogger; +import com.extendedae_plus.util.wireless.ChannelCardLinkHelper; import net.minecraft.nbt.CompoundTag; import java.util.UUID; import org.spongepowered.asm.mixin.Mixin; @@ -17,6 +17,7 @@ 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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; /** * 给 AE2 的 I/O 总线注入频道卡联动:在升级变更时读取频道并更新无线链接。 @@ -56,6 +57,19 @@ public abstract class IOBusPartChannelCardMixin implements InterfaceWirelessLink } } + @Inject(method = "tickingRequest", at = @At("TAIL"), cancellable = true) + private void eap$afterTick(appeng.api.networking.IGridNode node, int ticksSinceLastCall, + CallbackInfoReturnable cir) { + if (((appeng.parts.AEBasePart) (Object) this).isClientSide()) { + return; + } + + this.eap$updateWirelessLink(); + if (this.eap$shouldKeepTicking() && cir.getReturnValue() == TickRateModulation.SLEEP) { + cir.setReturnValue(TickRateModulation.SLOWER); + } + } + @Inject(method = "readFromNBT", at = @At("TAIL")) private void eap$afterReadFromNBT(CompoundTag extra, net.minecraft.core.HolderLookup.Provider registries, CallbackInfo ci) { // 从NBT加载时重置频道缓存和tick初始化标志 @@ -86,6 +100,11 @@ public abstract class IOBusPartChannelCardMixin implements InterfaceWirelessLink this.eap$clientConnected = connected; } + @Override + public boolean eap$shouldKeepTicking() { + return ChannelCardLinkHelper.shouldKeepTicking(this.getUpgrades(), this.eap$link, this.eap$hasTickInitialized); + } + @Override @Unique public void eap$initializeChannelLink() { @@ -96,25 +115,14 @@ public abstract class IOBusPartChannelCardMixin implements InterfaceWirelessLink try { IUpgradeInventory inv = this.getUpgrades(); - long channel = 0L; - boolean found = false; - UUID owner = null; - for (var stack : inv) { - if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) { - channel = ChannelCardItem.getChannel(stack); - owner = ChannelCardItem.getOwnerUUID(stack); - if (owner == null) { - owner = this.eap$getFallbackOwner(); - } - found = true; - break; - } - } + var boundChannel = ChannelCardLinkHelper.findBoundChannel(inv, this::eap$getFallbackOwner); + long channel = boundChannel != null ? boundChannel.channel() : 0L; + boolean found = boundChannel != null; + UUID owner = boundChannel != null ? boundChannel.owner() : null; // 频道没有变化则跳过 - boolean sameOwner = (this.eap$lastOwner == null && owner == null) - || (this.eap$lastOwner != null && this.eap$lastOwner.equals(owner)); - if (this.eap$link != null && this.eap$lastChannel == channel && sameOwner) { + if (this.eap$link != null + && ChannelCardLinkHelper.sameTarget(this.eap$lastChannel, this.eap$lastOwner, boundChannel)) { return; } this.eap$lastChannel = channel; @@ -122,13 +130,9 @@ public abstract class IOBusPartChannelCardMixin implements InterfaceWirelessLink if (!found) { // 无频道卡则断开 - if (this.eap$link != null) { - this.eap$link.setPlacerId(null); - this.eap$link.setFrequency(0L); - this.eap$link.updateStatus(); - // 立即通知客户端状态变化(断开连接无需延迟) - ((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate(); - } + ChannelCardLinkHelper.disconnect(this.eap$link); + // 立即通知客户端状态变化(断开连接无需延迟) + ((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate(); this.eap$lastChannel = 0L; this.eap$lastOwner = null; return; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartChannelCardMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartChannelCardMixin.java index 0f489a4..29a2c60 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartChannelCardMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartChannelCardMixin.java @@ -2,15 +2,15 @@ package com.extendedae_plus.mixin.ae2.parts.storagebus; import appeng.api.networking.IGridNodeListener; import appeng.api.networking.security.IActionHost; +import appeng.api.networking.ticking.TickRateModulation; import appeng.api.upgrades.IUpgradeInventory; import appeng.api.upgrades.IUpgradeableObject; import appeng.parts.storagebus.StorageBusPart; import com.extendedae_plus.ae.wireless.WirelessSlaveLink; import com.extendedae_plus.ae.wireless.endpoint.GenericNodeEndpointImpl; import com.extendedae_plus.api.bridge.InterfaceWirelessLinkBridge; -import com.extendedae_plus.init.ModItems; -import com.extendedae_plus.items.materials.ChannelCardItem; import com.extendedae_plus.util.ExtendedAELogger; +import com.extendedae_plus.util.wireless.ChannelCardLinkHelper; import net.minecraft.nbt.CompoundTag; import java.util.UUID; import org.spongepowered.asm.mixin.Mixin; @@ -18,6 +18,7 @@ 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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; /** * 给 AE2 的存储总线注入频道卡联动:在升级变更时读取频道并更新无线链接。 @@ -63,6 +64,19 @@ public abstract class StorageBusPartChannelCardMixin implements InterfaceWireles } } + @Inject(method = "tickingRequest", at = @At("TAIL"), cancellable = true) + private void eap$afterTick(appeng.api.networking.IGridNode node, int ticksSinceLastCall, + CallbackInfoReturnable cir) { + if (((appeng.parts.AEBasePart) (Object) this).isClientSide()) { + return; + } + + this.eap$updateWirelessLink(); + if (this.eap$shouldKeepTicking() && cir.getReturnValue() == TickRateModulation.SLEEP) { + cir.setReturnValue(TickRateModulation.SLOWER); + } + } + @Override public void eap$updateWirelessLink() { if (this.eap$link != null) { @@ -84,6 +98,11 @@ public abstract class StorageBusPartChannelCardMixin implements InterfaceWireles this.eap$clientConnected = connected; } + @Override + public boolean eap$shouldKeepTicking() { + return ChannelCardLinkHelper.shouldKeepTicking(this.getUpgrades(), this.eap$link, true); + } + @Override @Unique public void eap$initializeChannelLink() { @@ -94,38 +113,23 @@ public abstract class StorageBusPartChannelCardMixin implements InterfaceWireles try { IUpgradeInventory inv = this.getUpgrades(); - long channel = 0L; - boolean found = false; - UUID owner = null; - for (var stack : inv) { - if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) { - channel = ChannelCardItem.getChannel(stack); - owner = ChannelCardItem.getOwnerUUID(stack); - if (owner == null) { - owner = this.eap$getFallbackOwner(); - } - found = true; - break; - } - } + var boundChannel = ChannelCardLinkHelper.findBoundChannel(inv, this::eap$getFallbackOwner); + long channel = boundChannel != null ? boundChannel.channel() : 0L; + boolean found = boundChannel != null; + UUID owner = boundChannel != null ? boundChannel.owner() : null; // 频道没有变化则跳过 - boolean sameOwner = (this.eap$lastOwner == null && owner == null) - || (this.eap$lastOwner != null && this.eap$lastOwner.equals(owner)); - if (this.eap$link != null && this.eap$lastChannel == channel && sameOwner) { + if (this.eap$link != null + && ChannelCardLinkHelper.sameTarget(this.eap$lastChannel, this.eap$lastOwner, boundChannel)) { return; } this.eap$lastChannel = channel; if (!found) { - if (this.eap$link != null) { - this.eap$link.setPlacerId(null); - this.eap$link.setFrequency(0L); - this.eap$link.updateStatus(); - // 通知客户端状态变化 - ((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate(); - } + ChannelCardLinkHelper.disconnect(this.eap$link); + // 通知客户端状态变化 + ((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate(); this.eap$lastChannel = 0L; this.eap$lastOwner = null; return; diff --git a/src/main/java/com/extendedae_plus/util/wireless/ChannelCardLinkHelper.java b/src/main/java/com/extendedae_plus/util/wireless/ChannelCardLinkHelper.java new file mode 100644 index 0000000..ee317d5 --- /dev/null +++ b/src/main/java/com/extendedae_plus/util/wireless/ChannelCardLinkHelper.java @@ -0,0 +1,85 @@ +package com.extendedae_plus.util.wireless; + +import appeng.api.upgrades.IUpgradeInventory; +import com.extendedae_plus.ae.wireless.WirelessSlaveLink; +import com.extendedae_plus.init.ModItems; +import com.extendedae_plus.items.materials.ChannelCardItem; +import java.util.Objects; +import java.util.UUID; +import java.util.function.Supplier; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +/** + * 统一处理频道卡升级槽扫描与无线从端保活判定,避免各宿主实现漂移。 + */ +public final class ChannelCardLinkHelper { + + private ChannelCardLinkHelper() { + } + + public record BoundChannel(long channel, @Nullable UUID owner) { + } + + @Nullable + public static BoundChannel findBoundChannel(@Nullable IUpgradeInventory upgrades, Supplier fallbackOwner) { + if (upgrades == null) { + return null; + } + + for (ItemStack stack : upgrades) { + if (stack.isEmpty() || stack.getItem() != ModItems.CHANNEL_CARD.get()) { + continue; + } + + UUID owner = ChannelCardItem.getOwnerUUID(stack); + if (owner == null) { + owner = fallbackOwner.get(); + } + + return new BoundChannel(ChannelCardItem.getChannel(stack), owner); + } + + return null; + } + + public static boolean hasChannelCard(@Nullable IUpgradeInventory upgrades) { + if (upgrades == null) { + return false; + } + + for (ItemStack stack : upgrades) { + if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) { + return true; + } + } + + return false; + } + + public static boolean sameTarget(long lastChannel, @Nullable UUID lastOwner, @Nullable BoundChannel boundChannel) { + return boundChannel != null + && lastChannel == boundChannel.channel() + && Objects.equals(lastOwner, boundChannel.owner()); + } + + public static boolean hasActiveLink(@Nullable WirelessSlaveLink link) { + return link != null && (link.getFrequency() != 0L || link.isConnected()); + } + + public static boolean shouldKeepTicking(@Nullable IUpgradeInventory upgrades, + @Nullable WirelessSlaveLink link, + boolean initialized) { + return !initialized || hasChannelCard(upgrades) || hasActiveLink(link); + } + + public static void disconnect(@Nullable WirelessSlaveLink link) { + if (link == null) { + return; + } + + link.setPlacerId(null); + link.setFrequency(0L); + link.updateStatus(); + } +}