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 0f38590..d062e2e 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 @@ -1,6 +1,7 @@ package com.extendedae_plus.mixin.ae2.compat; import appeng.api.networking.IManagedGridNode; +import appeng.api.networking.IGridConnection; import appeng.api.networking.security.IActionSource; import appeng.api.upgrades.IUpgradeInventory; import appeng.api.upgrades.IUpgradeableObject; @@ -282,6 +283,24 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr eap$compatLastChannel = 0L; eap$compatHasInitialized = true; try { host.saveChanges(); } catch (Throwable ignored) {} + // 唤醒节点,加速 AE2 感知到连接断开 + mainNode.ifPresent((grid, node) -> { + try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {} + // 兜底:如仍存在针对无线主端的直连(非 in-world),强制销毁 + try { + for (IGridConnection gc : node.getConnections()) { + if (gc != null && !gc.isInWorld()) { + var other = gc.getOtherSide(node); + if (other != null && other.getOwner() instanceof com.extendedae_plus.wireless.IWirelessEndpoint) { + ExtendedAELogger.LOGGER.debug("[样板供应器] 兜底销毁残留无线直连: {} -> {}", node, other); + gc.destroy(); + try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored2) {} + try { if (other.getGrid() != null) { other.getGrid().getTickManager().wakeDevice(other); } } catch (Throwable ignored2) {} + } + } + } + } catch (Throwable ignored2) {} + }); return; } diff --git a/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java b/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java index 134d014..3157025 100644 --- a/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java +++ b/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java @@ -1,6 +1,7 @@ package com.extendedae_plus.wireless; import appeng.api.networking.GridHelper; +import appeng.api.networking.IGridConnection; import appeng.api.networking.IGridNode; import appeng.me.service.helpers.ConnectionWrapper; import com.extendedae_plus.config.ModConfigs; @@ -99,6 +100,13 @@ public class WirelessSlaveLink { current.destroy(); connection = new ConnectionWrapper(null); } + // AE2 侧是否已经存在连接(例如此前创建但 wrapper 丢失) + IGridConnection existing = findExistingConnection(a, b); + if (existing != null) { + ExtendedAELogger.LOGGER.debug("[无线] 复用已存在的连接: {}", existing); + connection = new ConnectionWrapper(existing); + return; + } ExtendedAELogger.LOGGER.debug("[无线] 创建连接: a={}, b={}", a, b); connection = new ConnectionWrapper(GridHelper.createConnection(a, b)); ExtendedAELogger.LOGGER.debug("[无线] 连接创建完成: {}", connection.getConnection()); @@ -128,9 +136,60 @@ public class WirelessSlaveLink { private void destroyConnection() { var current = connection.getConnection(); if (current != null) { + ExtendedAELogger.LOGGER.debug("[无线] 销毁连接: {}", current); + var a = current.a(); + var b = current.b(); + // 先销毁连接,再唤醒两端节点,使其尽快感知到状态变化 current.destroy(); + try { + if (a != null && a.getGrid() != null) { + a.getGrid().getTickManager().wakeDevice(a); + } + } catch (Throwable ignored) {} + try { + if (b != null && b.getGrid() != null) { + b.getGrid().getTickManager().wakeDevice(b); + } + } catch (Throwable ignored) {} connection.setConnection(null); + } else { + // 兜底:如果 wrapper 已丢失,但 AE2 内仍有直连,则尝试查找并销毁 + try { + IGridNode a = host.getGridNode(); + if (a != null) { + for (IGridConnection gc : a.getConnections()) { + // 我们创建的是非 in-world 直连 + if (gc != null && !gc.isInWorld()) { + IGridNode other = gc.getOtherSide(a); + Object owner = other != null ? other.getOwner() : null; + if (owner instanceof IWirelessEndpoint) { + ExtendedAELogger.LOGGER.debug("[无线] 兜底销毁直连: {} -> {}", a, other); + gc.destroy(); + try { if (a.getGrid() != null) { a.getGrid().getTickManager().wakeDevice(a); } } catch (Throwable ignored) {} + try { if (other != null && other.getGrid() != null) { other.getGrid().getTickManager().wakeDevice(other); } } catch (Throwable ignored) {} + } + } + } + } + } catch (Throwable ignored) {} } connection = new ConnectionWrapper(null); } + + /** + * 在 AE2 中查找 a 与 b 之间是否已经有连接存在(用于复用,避免重复创建异常)。 + */ + private IGridConnection findExistingConnection(IGridNode a, IGridNode b) { + try { + for (IGridConnection gc : a.getConnections()) { + var ga = gc.a(); + var gb = gc.b(); + if ((ga == a || gb == a) && (ga == b || gb == b)) { + return gc; + } + } + } catch (Throwable ignored) {} + return null; + } } +