From 044a0c39f7fdc2a295d5c66757b37d106d48a21d Mon Sep 17 00:00:00 2001 From: GaLicn <133291877+GaLicn@users.noreply.github.com> Date: Thu, 11 Dec 2025 20:59:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E7=A1=80=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ae/wireless/LabelNetworkRegistry.java | 40 +++++++++++----- .../LabeledWirelessTransceiverScreen.java | 37 ++++++++++++++- .../LabeledWirelessTransceiverComponents.java | 45 ++++++++++++++++++ .../LabeledWirelessTransceiverProvider.java | 46 +++++++++++++++++++ .../jade/WirelessTransceiverJadePlugin.java | 4 ++ .../network/LabelNetworkActionC2SPacket.java | 10 +++- .../assets/extendedae_plus/lang/en_us.json | 2 + .../assets/extendedae_plus/lang/zh_cn.json | 2 + 8 files changed, 172 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/extendedae_plus/integration/jade/LabeledWirelessTransceiverComponents.java create mode 100644 src/main/java/com/extendedae_plus/integration/jade/LabeledWirelessTransceiverProvider.java 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 953be4d..116e286 100644 --- a/src/main/java/com/extendedae_plus/ae/wireless/LabelNetworkRegistry.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/LabelNetworkRegistry.java @@ -105,24 +105,17 @@ public class LabelNetworkRegistry extends SavedData { } /** - * 注销端点;若网络无端点则清理。 + * 注销端点;不再自动删除网络,网络的移除需显式调用 removeNetwork。 */ public synchronized void unregister(IWirelessEndpoint endpoint) { ServerLevel level = endpoint.getServerLevel(); if (level == null) return; ResourceKey dimKey = ModConfig.INSTANCE.wirelessCrossDimEnable ? null : level.dimension(); BlockPos pos = endpoint.getBlockPos(); - Iterator> it = networks.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - LabelNetwork net = entry.getValue(); + for (LabelNetwork net : networks.values()) { net.endpoints.removeIf(ref -> ref.matches(dimKey, pos)); - if (net.endpoints.isEmpty()) { - net.destroyVirtualNode(); - it.remove(); - setDirty(); - } } + setDirty(); } public synchronized LabelNetwork getNetwork(ServerLevel level, String rawLabel, @Nullable UUID placerId) { @@ -134,6 +127,24 @@ public class LabelNetworkRegistry extends SavedData { return networks.get(key); } + /** + * 显式删除一个网络(销毁虚拟节点),仅在 UI “删除” 时调用。 + */ + public synchronized boolean removeNetwork(ServerLevel level, String rawLabel, @Nullable UUID placerId) { + String label = normalizeLabel(rawLabel); + if (label == null) return false; + UUID owner = placerId == null ? WirelessMasterRegistry.PUBLIC_NETWORK_UUID : WirelessTeamUtil.getNetworkOwnerUUID(level, placerId); + ResourceKey dimKey = ModConfig.INSTANCE.wirelessCrossDimEnable ? null : level.dimension(); + Key key = new Key(dimKey, label, owner); + LabelNetwork net = networks.remove(key); + if (net != null) { + net.destroyVirtualNode(); + setDirty(); + return true; + } + return false; + } + /** * 获取当前玩家所属网络列表(按标签排序)。 */ @@ -147,7 +158,7 @@ public class LabelNetworkRegistry extends SavedData { if (!Objects.equals(key.dim(), dimKey)) continue; list.add(new LabelNetworkSnapshot(key.label(), entry.getValue().channel())); } - list.sort(Comparator.comparing(LabelNetworkSnapshot::label)); + list.sort(Comparator.comparingLong(LabelNetworkSnapshot::channel)); return list; } @@ -190,7 +201,12 @@ public class LabelNetworkRegistry extends SavedData { } private long allocateChannel() { - return nextChannel++; + // 全局递增,不复用历史频道,从 1_000_000 起 + if (nextChannel < CHANNEL_START) { + nextChannel = CHANNEL_START; + } + long ch = nextChannel++; + return ch; } /* 内部类型 */ diff --git a/src/main/java/com/extendedae_plus/client/screen/LabeledWirelessTransceiverScreen.java b/src/main/java/com/extendedae_plus/client/screen/LabeledWirelessTransceiverScreen.java index b4f0948..4ab11c5 100644 --- a/src/main/java/com/extendedae_plus/client/screen/LabeledWirelessTransceiverScreen.java +++ b/src/main/java/com/extendedae_plus/client/screen/LabeledWirelessTransceiverScreen.java @@ -54,6 +54,7 @@ public class LabeledWirelessTransceiverScreen extends AbstractContainerScreen filtered = new ArrayList<>(); private int scrollOffset = 0; private int selectedIndex = -1; + private String lastSelectedLabel = ""; private String currentLabel = ""; private long currentChannel = 0L; @@ -153,6 +154,7 @@ public class LabeledWirelessTransceiverScreen extends AbstractContainerScreen= 0 && idx < filtered.size()) { selectedIndex = idx; + lastSelectedLabel = filtered.get(idx).label(); } return true; } @@ -245,6 +247,7 @@ public class LabeledWirelessTransceiverScreen extends AbstractContainerScreen list, String currentLabel, long currentChannel) { + String prevSelected = getSelectedLabel(); this.entries.clear(); for (LabelNetworkRegistry.LabelNetworkSnapshot s : list) { this.entries.add(new LabelEntry(s.label(), s.channel())); } this.currentLabel = currentLabel == null ? "" : currentLabel; this.currentChannel = currentChannel; + if (prevSelected != null && !prevSelected.isEmpty()) { + this.lastSelectedLabel = prevSelected; + } else if (this.currentLabel != null && !this.currentLabel.isEmpty()) { + this.lastSelectedLabel = this.currentLabel; + } else { + this.lastSelectedLabel = ""; + } applyFilter(); } @@ -329,4 +353,15 @@ public class LabeledWirelessTransceiverScreen extends AbstractContainerScreen= scrollOffset + VISIBLE_ROWS) { + scrollOffset = Math.min(maxOffset, targetRow - VISIBLE_ROWS + 1); + } + } } diff --git a/src/main/java/com/extendedae_plus/integration/jade/LabeledWirelessTransceiverComponents.java b/src/main/java/com/extendedae_plus/integration/jade/LabeledWirelessTransceiverComponents.java new file mode 100644 index 0000000..dbb667b --- /dev/null +++ b/src/main/java/com/extendedae_plus/integration/jade/LabeledWirelessTransceiverComponents.java @@ -0,0 +1,45 @@ +package com.extendedae_plus.integration.jade; + +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import snownee.jade.api.BlockAccessor; +import snownee.jade.api.IBlockComponentProvider; +import snownee.jade.api.ITooltip; +import snownee.jade.api.config.IPluginConfig; + +public enum LabeledWirelessTransceiverComponents implements IBlockComponentProvider { + LABEL_AND_CHANNEL("labeled_wireless_component") { + @Override + protected void add(BlockAccessor accessor, ITooltip tooltip, IPluginConfig config, net.minecraft.nbt.CompoundTag data) { + String label = data.contains("label") ? data.getString("label") : ""; + long channel = data.contains("channel") ? data.getLong("channel") : 0L; + tooltip.add(Component.translatable("extendedae_plus.jade.label", label.isEmpty() ? "-" : label)); + tooltip.add(Component.translatable("extendedae_plus.jade.frequency", channel)); + + if (data.contains("networkUsable")) { + boolean online = data.getBoolean("networkUsable"); + tooltip.add(Component.translatable(online ? "extendedae_plus.jade.online" : "extendedae_plus.jade.offline")); + } + } + }; + + private final ResourceLocation uid; + + LabeledWirelessTransceiverComponents(String name) { + this.uid = new ResourceLocation("extendedae_plus", name); + } + + @Override + public ResourceLocation getUid() { + return uid; + } + + @Override + public void appendTooltip(ITooltip tooltip, BlockAccessor accessor, IPluginConfig config) { + if (accessor.getServerData() != null) { + add(accessor, tooltip, config, accessor.getServerData()); + } + } + + protected abstract void add(BlockAccessor accessor, ITooltip tooltip, IPluginConfig config, net.minecraft.nbt.CompoundTag data); +} diff --git a/src/main/java/com/extendedae_plus/integration/jade/LabeledWirelessTransceiverProvider.java b/src/main/java/com/extendedae_plus/integration/jade/LabeledWirelessTransceiverProvider.java new file mode 100644 index 0000000..dd58fef --- /dev/null +++ b/src/main/java/com/extendedae_plus/integration/jade/LabeledWirelessTransceiverProvider.java @@ -0,0 +1,46 @@ +package com.extendedae_plus.integration.jade; + +import appeng.api.networking.IGrid; +import appeng.api.networking.IGridNode; +import com.extendedae_plus.content.wireless.LabeledWirelessTransceiverBlockEntity; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import snownee.jade.api.BlockAccessor; +import snownee.jade.api.IServerDataProvider; + +/** + * 标签无线收发器:服务端数据同步。 + * 仅包含标签名、频道、网络在线状态。 + */ +public enum LabeledWirelessTransceiverProvider implements IServerDataProvider { + INSTANCE; + + private static final ResourceLocation UID = new ResourceLocation("extendedae_plus", "labeled_wireless_info"); + + @Override + public ResourceLocation getUid() { + return UID; + } + + @Override + public void appendServerData(CompoundTag data, BlockAccessor accessor) { + if (!(accessor.getBlockEntity() instanceof LabeledWirelessTransceiverBlockEntity be)) return; + String label = be.getLabelForDisplay(); + if (label != null) { + data.putString("label", label); + } + data.putLong("channel", be.getFrequency()); + + IGridNode node = be.getGridNode(); + IGrid grid = node == null ? null : node.getGrid(); + boolean networkUsable = false; + if (grid != null) { + try { + networkUsable = grid.getEnergyService().isNetworkPowered(); + } catch (Throwable ignored) { + networkUsable = false; + } + } + data.putBoolean("networkUsable", networkUsable); + } +} diff --git a/src/main/java/com/extendedae_plus/integration/jade/WirelessTransceiverJadePlugin.java b/src/main/java/com/extendedae_plus/integration/jade/WirelessTransceiverJadePlugin.java index 34159cd..1888e81 100644 --- a/src/main/java/com/extendedae_plus/integration/jade/WirelessTransceiverJadePlugin.java +++ b/src/main/java/com/extendedae_plus/integration/jade/WirelessTransceiverJadePlugin.java @@ -2,6 +2,8 @@ package com.extendedae_plus.integration.jade; import com.extendedae_plus.content.wireless.WirelessTransceiverBlock; import com.extendedae_plus.content.wireless.WirelessTransceiverBlockEntity; +import com.extendedae_plus.content.wireless.LabeledWirelessTransceiverBlock; +import com.extendedae_plus.content.wireless.LabeledWirelessTransceiverBlockEntity; import snownee.jade.api.IWailaClientRegistration; import snownee.jade.api.IWailaCommonRegistration; import snownee.jade.api.IWailaPlugin; @@ -14,6 +16,7 @@ public class WirelessTransceiverJadePlugin implements IWailaPlugin { public void register(IWailaCommonRegistration registration) { // 注册服务端数据提供者(用于同步数据) registration.registerBlockDataProvider(WirelessTransceiverProvider.INSTANCE, WirelessTransceiverBlockEntity.class); + registration.registerBlockDataProvider(com.extendedae_plus.integration.jade.LabeledWirelessTransceiverProvider.INSTANCE, LabeledWirelessTransceiverBlockEntity.class); } @Override @@ -22,5 +25,6 @@ public class WirelessTransceiverJadePlugin implements IWailaPlugin { for (var component : WirelessTransceiverJadePluginComponents.values()) { registration.registerBlockComponent(component, WirelessTransceiverBlock.class); } + registration.registerBlockComponent(com.extendedae_plus.integration.jade.LabeledWirelessTransceiverComponents.LABEL_AND_CHANNEL, LabeledWirelessTransceiverBlock.class); } } \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/network/LabelNetworkActionC2SPacket.java b/src/main/java/com/extendedae_plus/network/LabelNetworkActionC2SPacket.java index 2fbf67e..8e5a8e2 100644 --- a/src/main/java/com/extendedae_plus/network/LabelNetworkActionC2SPacket.java +++ b/src/main/java/com/extendedae_plus/network/LabelNetworkActionC2SPacket.java @@ -52,7 +52,15 @@ public class LabelNetworkActionC2SPacket { switch (packet.action) { case SET -> te.applyLabel(packet.label); - case DELETE, DISCONNECT -> te.clearLabel(); + case DELETE -> { + String target = packet.label == null || packet.label.isEmpty() ? te.getLabelForDisplay() : packet.label; + if (target != null && !target.isEmpty()) { + com.extendedae_plus.ae.wireless.LabelNetworkRegistry.get(level) + .removeNetwork(level, target, te.getPlacerId()); + } + te.clearLabel(); + } + case DISCONNECT -> te.clearLabel(); } }); ctx.get().setPacketHandled(true); diff --git a/src/main/resources/assets/extendedae_plus/lang/en_us.json b/src/main/resources/assets/extendedae_plus/lang/en_us.json index 7a4440b..72c6c3e 100644 --- a/src/main/resources/assets/extendedae_plus/lang/en_us.json +++ b/src/main/resources/assets/extendedae_plus/lang/en_us.json @@ -215,10 +215,12 @@ "extendedae_plus.jade.unlocked": "Unlocked", "extendedae_plus.jade.online": "Device Online", "extendedae_plus.jade.offline": "Device Offline", + "extendedae_plus.jade.label": "Label: %s", "extendedae_plus.jade.channels": "Channels: %s", "extendedae_plus.jade.channels_of": "Channels: %s/%s", "extendedae_plus.jade.owner": "Owner: %s", "extendedae_plus.jade.owner.public": "Owner: Public", + "config.jade.plugin_extendedae_plus.labeled_wireless_component": "Labeled Wireless Info", "extendedae_plus.command.server_side_only": "This command must be run on server side", "extendedae_plus.command.storage_manager_not_initialized": "InfinityStorageManager is not initialized", diff --git a/src/main/resources/assets/extendedae_plus/lang/zh_cn.json b/src/main/resources/assets/extendedae_plus/lang/zh_cn.json index c8dc70e..ac5e5a1 100644 --- a/src/main/resources/assets/extendedae_plus/lang/zh_cn.json +++ b/src/main/resources/assets/extendedae_plus/lang/zh_cn.json @@ -214,10 +214,12 @@ "extendedae_plus.jade.unlocked": "未锁定", "extendedae_plus.jade.online": "设备在线", "extendedae_plus.jade.offline": "设备离线", + "extendedae_plus.jade.label": "标签: %s", "extendedae_plus.jade.channels": "频道: %s", "extendedae_plus.jade.channels_of": "频道: %s/%s", "extendedae_plus.jade.owner": "所有者: %s", "extendedae_plus.jade.owner.public": "所有者: 公共", + "config.jade.plugin_extendedae_plus.labeled_wireless_component": "标签无线收发器信息", "extendedae_plus.command.server_side_only": "此命令必须在服务器端执行", "extendedae_plus.command.storage_manager_not_initialized": "InfinityStorageManager未初始化",