From 5d773f1937f7deaf26e502cf9dcba59f66269f3d Mon Sep 17 00:00:00 2001 From: GaLi <3096147684@qq.com> Date: Fri, 27 Mar 2026 23:34:33 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BD=BF=E7=94=A8=E6=A0=87?= =?UTF-8?q?=E7=AD=BE=E6=97=A0=E7=BA=BF=E6=94=B6=E5=8F=91=E5=99=A8=E6=97=B6?= =?UTF-8?q?=E5=81=B6=E7=8E=B0=E9=80=80=E5=87=BA=E6=B8=B8=E6=88=8F=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E4=BF=9D=E5=AD=98=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/extendedae_plus/ExtendedAEPlus.java | 17 +++++++ .../ae/wireless/LabelLink.java | 49 +++++++++++++++++++ .../ae/wireless/LabelNetworkRegistry.java | 9 ++++ .../ae/wireless/WirelessMasterRegistry.java | 4 ++ ...LabeledWirelessTransceiverBlockEntity.java | 34 ++++++++++--- .../WirelessTransceiverBlockEntity.java | 24 +++++++++ 6 files changed, 131 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/extendedae_plus/ExtendedAEPlus.java b/src/main/java/com/extendedae_plus/ExtendedAEPlus.java index 69b66c9..4668daa 100644 --- a/src/main/java/com/extendedae_plus/ExtendedAEPlus.java +++ b/src/main/java/com/extendedae_plus/ExtendedAEPlus.java @@ -8,6 +8,8 @@ import appeng.blockentity.crafting.CraftingBlockEntity; import appeng.items.parts.PartModelsHelper; import com.extendedae_plus.api.ids.EAPComponents; import com.extendedae_plus.api.storage.InfinityBigIntegerCellHandler; +import com.extendedae_plus.ae.wireless.LabelNetworkRegistry; +import com.extendedae_plus.ae.wireless.WirelessMasterRegistry; import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.content.ae2.MirrorPatternProviderBlockEntity; import com.extendedae_plus.content.matrix.CrafterCorePlusBlockEntity; @@ -29,6 +31,7 @@ import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.server.ServerStartedEvent; import net.neoforged.neoforge.event.server.ServerStartingEvent; +import net.neoforged.neoforge.event.server.ServerStoppingEvent; import net.neoforged.neoforge.event.server.ServerStoppedEvent; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -42,6 +45,7 @@ public class ExtendedAEPlus { private static InfinityStorageManager storageManager; @Nullable private static MinecraftServer storageManagerServer; + private static volatile boolean serverStopping; public ExtendedAEPlus(IEventBus modEventBus, ModContainer modContainer) { modEventBus.addListener(this::commonSetup); @@ -60,6 +64,7 @@ public class ExtendedAEPlus { EAPComponents.DR.register(modEventBus); NeoForge.EVENT_BUS.register(this); NeoForge.EVENT_BUS.addListener(ExtendedAEPlus::onServerStarted); + NeoForge.EVENT_BUS.addListener(ExtendedAEPlus::onServerStopping); NeoForge.EVENT_BUS.addListener(ExtendedAEPlus::onServerStopped); // 注册配置:接入自定义的 ModConfigs modContainer.registerConfig(ModConfig.Type.COMMON, ModConfigs.COMMON_SPEC, "extendedae_plus-common.toml"); @@ -72,17 +77,29 @@ public class ExtendedAEPlus { } private static void onServerStarted(ServerStartedEvent event) { + serverStopping = false; storageManagerServer = event.getServer(); storageManager = InfinityStorageManager.getInstance(event.getServer()); } + private static void onServerStopping(ServerStoppingEvent event) { + serverStopping = true; + LabelNetworkRegistry.get(event.getServer()).shutdownAllVirtualNodes(); + WirelessMasterRegistry.clear(); + } + private static void onServerStopped(ServerStoppedEvent event) { + serverStopping = false; if (storageManagerServer == event.getServer()) { storageManagerServer = null; storageManager = null; } } + public static boolean isServerStopping() { + return serverStopping; + } + @Nullable public static InfinityStorageManager currentStorageManager() { return storageManager; diff --git a/src/main/java/com/extendedae_plus/ae/wireless/LabelLink.java b/src/main/java/com/extendedae_plus/ae/wireless/LabelLink.java index 18a975b..40c5b13 100644 --- a/src/main/java/com/extendedae_plus/ae/wireless/LabelLink.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/LabelLink.java @@ -1,6 +1,7 @@ package com.extendedae_plus.ae.wireless; import appeng.api.networking.GridHelper; +import appeng.api.networking.IGridConnection; import appeng.api.networking.IGridNode; import appeng.me.service.helpers.ConnectionWrapper; import net.minecraft.resources.ResourceKey; @@ -88,14 +89,62 @@ public class LabelLink { } public void onUnloadOrRemove() { + this.target = null; destroyConnection(); } private void destroyConnection() { var current = connection.getConnection(); if (current != null) { + 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 { + try { + IGridNode hostNode = this.host.getGridNode(); + IGridNode targetNode = this.target == null ? null : this.target.node(); + if (hostNode != null && targetNode != null) { + IGridConnection existing = this.findExistingConnection(hostNode, targetNode); + if (existing != null) { + existing.destroy(); + try { + if (hostNode.getGrid() != null) { + hostNode.getGrid().getTickManager().wakeDevice(hostNode); + } + } catch (Throwable ignored) {} + try { + if (targetNode.getGrid() != null) { + targetNode.getGrid().getTickManager().wakeDevice(targetNode); + } + } catch (Throwable ignored) {} + } + } + } catch (Throwable ignored) {} } } + + @Nullable + 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; + } } diff --git a/src/main/java/com/extendedae_plus/ae/wireless/LabelNetworkRegistry.java b/src/main/java/com/extendedae_plus/ae/wireless/LabelNetworkRegistry.java index 0fc5e55..809b9ec 100644 --- a/src/main/java/com/extendedae_plus/ae/wireless/LabelNetworkRegistry.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/LabelNetworkRegistry.java @@ -111,10 +111,19 @@ public class LabelNetworkRegistry extends SavedData { BlockPos pos = endpoint.getBlockPos(); for (LabelNetwork net : networks.values()) { net.endpoints.removeIf(ref -> ref.matches(dimKey, pos)); + if (net.endpoints.isEmpty()) { + net.destroyVirtualNode(); + } } setDirty(); } + public synchronized void shutdownAllVirtualNodes() { + for (LabelNetwork net : networks.values()) { + net.destroyVirtualNode(); + } + } + public synchronized LabelNetwork getNetwork(ServerLevel level, String rawLabel, @Nullable UUID placerId) { String label = normalizeLabel(rawLabel); if (label == null) return null; diff --git a/src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterRegistry.java b/src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterRegistry.java index 40525b4..e18dcd0 100644 --- a/src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterRegistry.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterRegistry.java @@ -85,6 +85,10 @@ public final class WirelessMasterRegistry { return ref == null ? null : ref.get(); } + public static synchronized void clear() { + MASTERS.clear(); + } + private static void cleanupIfCleared(Key key) { var ref = MASTERS.get(key); if (ref != null && ref.get() == null) { diff --git a/src/main/java/com/extendedae_plus/content/wireless/LabeledWirelessTransceiverBlockEntity.java b/src/main/java/com/extendedae_plus/content/wireless/LabeledWirelessTransceiverBlockEntity.java index 07c1ef7..c052754 100644 --- a/src/main/java/com/extendedae_plus/content/wireless/LabeledWirelessTransceiverBlockEntity.java +++ b/src/main/java/com/extendedae_plus/content/wireless/LabeledWirelessTransceiverBlockEntity.java @@ -8,6 +8,7 @@ import appeng.api.networking.IInWorldGridNodeHost; import appeng.api.networking.IManagedGridNode; import appeng.api.util.AECableType; import appeng.blockentity.AEBaseBlockEntity; +import com.extendedae_plus.ExtendedAEPlus; import com.extendedae_plus.ae.wireless.IWirelessEndpoint; import com.extendedae_plus.ae.wireless.LabelLink; import com.extendedae_plus.ae.wireless.LabelNetworkRegistry; @@ -194,25 +195,49 @@ public class LabeledWirelessTransceiverBlockEntity extends AEBaseBlockEntity imp } public void onRemoved() { + cleanupForRemoval(); + } + + @Override + public void onChunkUnloaded() { + cleanupForRemoval(); + super.onChunkUnloaded(); + } + + @Override + public void setRemoved() { + cleanupForRemoval(); + super.setRemoved(); + } + + private void cleanupForRemoval() { + if (this.beingRemoved) { + return; + } + this.beingRemoved = true; - labelLink.onUnloadOrRemove(); + this.labelLink.onUnloadOrRemove(); + ServerLevel sl = getServerLevel(); if (sl != null) { LabelNetworkRegistry.get(sl).unregister(this); } - if (managedNode != null) { - managedNode.destroy(); + + if (this.managedNode != null) { + this.managedNode.destroy(); } } public static void serverTick(Level level, BlockPos pos, BlockState state, LabeledWirelessTransceiverBlockEntity be) { if (!(level instanceof ServerLevel)) return; + if (ExtendedAEPlus.isServerStopping()) return; be.labelLink.updateStatus(); be.updateState(); } private void updateState() { if (this.level == null || this.level.isClientSide) return; + if (ExtendedAEPlus.isServerStopping()) return; if (this.beingRemoved || this.isRemoved()) return; BlockState currentState = this.getBlockState(); if (!(currentState.getBlock() instanceof LabeledWirelessTransceiverBlock)) { @@ -307,15 +332,12 @@ public class LabeledWirelessTransceiverBlockEntity extends AEBaseBlockEntity imp } @Override public void onStateChanged(LabeledWirelessTransceiverBlockEntity host, IGridNode node, State state) { - host.updateState(); } @Override public void onInWorldConnectionChanged(LabeledWirelessTransceiverBlockEntity host, IGridNode node) { - host.updateState(); } @Override public void onGridChanged(LabeledWirelessTransceiverBlockEntity host, IGridNode node) { - host.updateState(); } @Override public void onOwnerChanged(LabeledWirelessTransceiverBlockEntity host, IGridNode node) {} diff --git a/src/main/java/com/extendedae_plus/content/wireless/WirelessTransceiverBlockEntity.java b/src/main/java/com/extendedae_plus/content/wireless/WirelessTransceiverBlockEntity.java index 22d1c37..19196e7 100644 --- a/src/main/java/com/extendedae_plus/content/wireless/WirelessTransceiverBlockEntity.java +++ b/src/main/java/com/extendedae_plus/content/wireless/WirelessTransceiverBlockEntity.java @@ -42,6 +42,8 @@ public class WirelessTransceiverBlockEntity extends AEBaseBlockEntity implements @Nullable private String placerName; // 放置者名称,用于显示 + private boolean beingRemoved = false; + private WirelessMasterLink masterLink; private WirelessSlaveLink slaveLink; @@ -247,11 +249,33 @@ public class WirelessTransceiverBlockEntity extends AEBaseBlockEntity implements } void onRemoved() { + cleanupForRemoval(); + } + + @Override + public void onChunkUnloaded() { + cleanupForRemoval(); + super.onChunkUnloaded(); + } + + @Override + public void setRemoved() { + cleanupForRemoval(); + super.setRemoved(); + } + + private void cleanupForRemoval() { + if (this.beingRemoved) { + return; + } + + this.beingRemoved = true; if (this.masterMode) { this.masterLink.onUnloadOrRemove(); } else { this.slaveLink.onUnloadOrRemove(); } + if (this.managedNode != null) { this.managedNode.destroy(); }