diff --git a/src/main/java/com/extendedae_plus/ExtendedAEPlus.java b/src/main/java/com/extendedae_plus/ExtendedAEPlus.java index 4c6e6a9..49f6e5e 100644 --- a/src/main/java/com/extendedae_plus/ExtendedAEPlus.java +++ b/src/main/java/com/extendedae_plus/ExtendedAEPlus.java @@ -7,6 +7,9 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.config.ModConfig; import com.extendedae_plus.config.ModConfigs; +import com.extendedae_plus.init.ModBlocks; +import com.extendedae_plus.init.ModBlockEntities; +import com.extendedae_plus.init.ModItems; /** * ExtendedAE Plus 主mod类 @@ -22,6 +25,11 @@ public class ExtendedAEPlus { // 注册mod初始化事件 modEventBus.addListener(this::commonSetup); + // 注册方块与方块实体 + ModBlocks.BLOCKS.register(modEventBus); + ModBlockEntities.BLOCK_ENTITY_TYPES.register(modEventBus); + ModItems.ITEMS.register(modEventBus); + // 注册到Forge事件总线 MinecraftForge.EVENT_BUS.register(this); diff --git a/src/main/java/com/extendedae_plus/config/ModConfigs.java b/src/main/java/com/extendedae_plus/config/ModConfigs.java index ffa23ad..0592099 100644 --- a/src/main/java/com/extendedae_plus/config/ModConfigs.java +++ b/src/main/java/com/extendedae_plus/config/ModConfigs.java @@ -5,6 +5,7 @@ import net.minecraftforge.common.ForgeConfigSpec; public final class ModConfigs { public static final ForgeConfigSpec COMMON_SPEC; public static final ForgeConfigSpec.IntValue PAGE_MULTIPLIER; + public static final ForgeConfigSpec.DoubleValue WIRELESS_MAX_RANGE; static { ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder(); @@ -15,6 +16,14 @@ public final class ModConfigs { "基础为36,每页仍显示36格,倍率会增加总页数/总容量。", "建议范围 1-16") .defineInRange("pageMultiplier", 1, 1, 64); + + // 无线收发器:最大连接距离(单位:方块)。 + // 一对多从端连接主端时,将以该值作为范围限制。 + WIRELESS_MAX_RANGE = builder + .comment( + "无线收发器最大连接距离(单位:方块)", + "从端与主端的直线距离需小于等于该值才会建立连接。") + .defineInRange("wirelessMaxRange", 256.0D, 1.0D, 4096.0D); builder.pop(); COMMON_SPEC = builder.build(); } diff --git a/src/main/java/com/extendedae_plus/content/wireless/WirelessTransceiverBlock.java b/src/main/java/com/extendedae_plus/content/wireless/WirelessTransceiverBlock.java new file mode 100644 index 0000000..83d7221 --- /dev/null +++ b/src/main/java/com/extendedae_plus/content/wireless/WirelessTransceiverBlock.java @@ -0,0 +1,70 @@ +package com.extendedae_plus.content.wireless; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import org.jetbrains.annotations.Nullable; +import com.extendedae_plus.init.ModBlockEntities; + +public class WirelessTransceiverBlock extends Block implements EntityBlock { + public WirelessTransceiverBlock(Properties props) { + super(props); + } + + @Override + public @Nullable BlockEntity newBlockEntity(BlockPos pos, BlockState state) { + return new WirelessTransceiverBlockEntity(pos, state); + } + + @Override + public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { + if (level.isClientSide) { + return InteractionResult.SUCCESS; + } + BlockEntity be = level.getBlockEntity(pos); + if (be instanceof WirelessTransceiverBlockEntity te) { + boolean sneaking = player.isShiftKeyDown(); + if (sneaking) { + // 简单演示:Shift+右键 频率+1 + long f = te.getFrequency(); + te.setFrequency(f + 1); + player.displayClientMessage(net.minecraft.network.chat.Component.literal("Freq: " + te.getFrequency()), true); + } else { + te.setMasterMode(!te.isMasterMode()); + player.displayClientMessage(net.minecraft.network.chat.Component.literal(te.isMasterMode() ? "Mode: MASTER" : "Mode: SLAVE"), true); + } + return InteractionResult.CONSUME; + } + return InteractionResult.PASS; + } + + @Override + public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) { + if (!state.is(newState.getBlock())) { + BlockEntity be = level.getBlockEntity(pos); + if (be instanceof WirelessTransceiverBlockEntity te) { + te.onRemoved(); + } + } + super.onRemove(state, level, pos, newState, isMoving); + } + + @Override + public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType type) { + if (level.isClientSide) return null; + return type == ModBlockEntities.WIRELESS_TRANSCEIVER_BE.get() + ? (lvl, pos, st, be) -> WirelessTransceiverBlockEntity.serverTick(lvl, pos, st, (WirelessTransceiverBlockEntity) be) + : null; + } +} diff --git a/src/main/java/com/extendedae_plus/content/wireless/WirelessTransceiverBlockEntity.java b/src/main/java/com/extendedae_plus/content/wireless/WirelessTransceiverBlockEntity.java new file mode 100644 index 0000000..0c1d0a1 --- /dev/null +++ b/src/main/java/com/extendedae_plus/content/wireless/WirelessTransceiverBlockEntity.java @@ -0,0 +1,200 @@ +package com.extendedae_plus.content.wireless; + +import appeng.api.networking.GridHelper; +import appeng.api.networking.IGridNode; +import appeng.api.networking.IGridNodeListener; +import appeng.api.networking.IManagedGridNode; +import appeng.api.networking.IInWorldGridNodeHost; +import com.extendedae_plus.wireless.IWirelessEndpoint; +import com.extendedae_plus.wireless.WirelessMasterLink; +import com.extendedae_plus.wireless.WirelessSlaveLink; +import com.extendedae_plus.init.ModBlockEntities; +import com.extendedae_plus.init.ModItems; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.core.Direction; +import org.jetbrains.annotations.Nullable; +import java.util.EnumSet; + +/** + * 无线收发器方块实体(骨架): + * - 主/从模式切换; + * - 频率设置; + * - 集成 AE2 节点; + * - 集成无线主/从逻辑。 + * + * 注意:本类不包含注册常量,需在你的注册系统中完成 BlockEntityType 的创建与绑定。 + */ +public class WirelessTransceiverBlockEntity extends BlockEntity implements IWirelessEndpoint, IInWorldGridNodeHost { + + private IManagedGridNode managedNode; + + private long frequency = 0L; + private boolean masterMode = true; + + private WirelessMasterLink masterLink; + private WirelessSlaveLink slaveLink; + + public WirelessTransceiverBlockEntity(BlockPos pos, BlockState state) { + super(ModBlockEntities.WIRELESS_TRANSCEIVER_BE.get(), pos, state); + // 创建 AE2 管理节点 + this.managedNode = GridHelper.createManagedNode(this, NodeListener.INSTANCE); + this.managedNode.setIdlePowerUsage(1.0); // 可按需调整基础待机功耗 + this.managedNode.setTagName("wireless_node"); + this.managedNode.setInWorldNode(true); + this.managedNode.setExposedOnSides(EnumSet.allOf(Direction.class)); + // 可见表示,方便在 AE2 界面中识别(可选) + this.managedNode.setVisualRepresentation(ModItems.WIRELESS_TRANSCEIVER.get().getDefaultInstance()); + // 初始化无线逻辑 + this.masterLink = new WirelessMasterLink(this); + this.slaveLink = new WirelessSlaveLink(this); + } + + /* ===================== IInWorldGridNodeHost ===================== */ + @Override + public @Nullable IGridNode getGridNode(Direction dir) { + return getGridNode(); + } + + /* ===================== IWirelessEndpoint ===================== */ + @Override + public ServerLevel getServerLevel() { + Level lvl = super.getLevel(); + return lvl instanceof ServerLevel sl ? sl : null; + } + + @Override + public BlockPos getBlockPos() { + return this.worldPosition; + } + + @Override + public IGridNode getGridNode() { + return managedNode == null ? null : managedNode.getNode(); + } + + @Override + public boolean isEndpointRemoved() { + return super.isRemoved(); + } + + /* ===================== 公共方法(交互调用) ===================== */ + public long getFrequency() { + return frequency; + } + + public void setFrequency(long frequency) { + if (this.frequency == frequency) return; + this.frequency = frequency; + if (isMasterMode()) { + masterLink.setFrequency(frequency); + } else { + slaveLink.setFrequency(frequency); + } + setChanged(); + } + + public boolean isMasterMode() { + return masterMode; + } + + public void setMasterMode(boolean masterMode) { + if (this.masterMode == masterMode) return; + // 切换前清理原模式状态 + if (this.masterMode) { + masterLink.onUnloadOrRemove(); + } else { + slaveLink.onUnloadOrRemove(); + } + this.masterMode = masterMode; + // 切换后应用频率 + if (this.masterMode) { + masterLink.setFrequency(frequency); + } else { + slaveLink.setFrequency(frequency); + } + setChanged(); + } + + public void onRemoved() { + if (this.masterMode) { + masterLink.onUnloadOrRemove(); + } else { + slaveLink.onUnloadOrRemove(); + } + if (managedNode != null) { + managedNode.destroy(); + } + } + + /* ===================== Tick ===================== */ + public static void serverTick(Level level, BlockPos pos, BlockState state, WirelessTransceiverBlockEntity be) { + if (!(level instanceof ServerLevel)) return; + if (!be.masterMode) { + // 从端需要周期检查与维护连接 + be.slaveLink.updateStatus(); + } + } + + @Override + public void onLoad() { + super.onLoad(); + // 仅服务端创建节点 + ServerLevel sl = getServerLevel(); + if (sl == null) return; + // 在首个 tick 创建,以保证区块已就绪 + GridHelper.onFirstTick(this, be -> { + be.managedNode.create(be.getLevel(), be.getBlockPos()); + }); + } + + /* ===================== NBT ===================== */ + @Override + protected void saveAdditional(CompoundTag tag) { + super.saveAdditional(tag); + tag.putLong("frequency", frequency); + tag.putBoolean("master", masterMode); + if (managedNode != null) { + managedNode.saveToNBT(tag); + } + } + + @Override + public void load(CompoundTag tag) { + super.load(tag); + this.frequency = tag.getLong("frequency"); + this.masterMode = tag.getBoolean("master"); + if (managedNode != null) { + managedNode.loadFromNBT(tag); + } + // 应用到链接器 + if (masterMode) { + masterLink.setFrequency(frequency); + } else { + slaveLink.setFrequency(frequency); + } + } + + /* ===================== AE2 节点监听 ===================== */ + enum NodeListener implements IGridNodeListener { + INSTANCE; + @Override + public void onSaveChanges(WirelessTransceiverBlockEntity host, IGridNode node) { + host.setChanged(); + } + @Override + public void onStateChanged(WirelessTransceiverBlockEntity host, IGridNode node, State state) { + // 可在此响应 POWER/CHANNEL 等变化,刷新显示等 + } + @Override + public void onInWorldConnectionChanged(WirelessTransceiverBlockEntity host, IGridNode node) {} + @Override + public void onGridChanged(WirelessTransceiverBlockEntity host, IGridNode node) {} + @Override + public void onOwnerChanged(WirelessTransceiverBlockEntity host, IGridNode node) {} + } +} diff --git a/src/main/java/com/extendedae_plus/init/ModBlockEntities.java b/src/main/java/com/extendedae_plus/init/ModBlockEntities.java new file mode 100644 index 0000000..a82eb16 --- /dev/null +++ b/src/main/java/com/extendedae_plus/init/ModBlockEntities.java @@ -0,0 +1,20 @@ +package com.extendedae_plus.init; + +import com.extendedae_plus.ExtendedAEPlus; +import com.extendedae_plus.content.wireless.WirelessTransceiverBlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; + +public final class ModBlockEntities { + private ModBlockEntities() {} + + public static final DeferredRegister> BLOCK_ENTITY_TYPES = + DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, ExtendedAEPlus.MODID); + + public static final RegistryObject> WIRELESS_TRANSCEIVER_BE = + BLOCK_ENTITY_TYPES.register("wireless_transceiver", + () -> BlockEntityType.Builder.of(WirelessTransceiverBlockEntity::new, + ModBlocks.WIRELESS_TRANSCEIVER.get()).build(null)); +} diff --git a/src/main/java/com/extendedae_plus/init/ModBlocks.java b/src/main/java/com/extendedae_plus/init/ModBlocks.java new file mode 100644 index 0000000..d972cab --- /dev/null +++ b/src/main/java/com/extendedae_plus/init/ModBlocks.java @@ -0,0 +1,21 @@ +package com.extendedae_plus.init; + +import com.extendedae_plus.ExtendedAEPlus; +import com.extendedae_plus.content.wireless.WirelessTransceiverBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.material.MapColor; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; + +public final class ModBlocks { + private ModBlocks() {} + + public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, ExtendedAEPlus.MODID); + + public static final RegistryObject WIRELESS_TRANSCEIVER = BLOCKS.register( + "wireless_transceiver", + () -> new WirelessTransceiverBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).strength(2.0F, 6.0F)) + ); +} diff --git a/src/main/java/com/extendedae_plus/init/ModItems.java b/src/main/java/com/extendedae_plus/init/ModItems.java new file mode 100644 index 0000000..da6d880 --- /dev/null +++ b/src/main/java/com/extendedae_plus/init/ModItems.java @@ -0,0 +1,20 @@ +package com.extendedae_plus.init; + +import com.extendedae_plus.ExtendedAEPlus; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; + +public final class ModItems { + private ModItems() {} + + public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, ExtendedAEPlus.MODID); + + public static final RegistryObject WIRELESS_TRANSCEIVER = ITEMS.register( + "wireless_transceiver", + () -> new BlockItem(ModBlocks.WIRELESS_TRANSCEIVER.get(), new Item.Properties()) + ); +} diff --git a/src/main/java/com/extendedae_plus/wireless/IWirelessEndpoint.java b/src/main/java/com/extendedae_plus/wireless/IWirelessEndpoint.java new file mode 100644 index 0000000..15a991b --- /dev/null +++ b/src/main/java/com/extendedae_plus/wireless/IWirelessEndpoint.java @@ -0,0 +1,24 @@ +package com.extendedae_plus.wireless; + +import appeng.api.networking.IGridNode; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; + +/** + * 无线端点最小接口。 + * 你的无线收发器方块实体需实现该接口, + * 以便无线逻辑能够获取世界、位置与 AE2 节点。 + */ +public interface IWirelessEndpoint { + /** 返回方块所在的服务端世界(避免与 BlockEntity#getLevel 冲突) */ + ServerLevel getServerLevel(); + + /** 返回方块位置 */ + BlockPos getBlockPos(); + + /** 返回可用于 AE2 连接的节点(通常为主节点) */ + IGridNode getGridNode(); + + /** 是否已移除/销毁(端点视角),用于在卸载或破坏时停止连接 */ + boolean isEndpointRemoved(); +} diff --git a/src/main/java/com/extendedae_plus/wireless/WirelessMasterLink.java b/src/main/java/com/extendedae_plus/wireless/WirelessMasterLink.java new file mode 100644 index 0000000..8205c01 --- /dev/null +++ b/src/main/java/com/extendedae_plus/wireless/WirelessMasterLink.java @@ -0,0 +1,51 @@ +package com.extendedae_plus.wireless; + +import net.minecraft.server.level.ServerLevel; + +/** + * 主收发器端逻辑:负责在频率变化/加载时向注册中心登记唯一主端,卸载时反注册。 + * 方块实体应在合适的生命周期中调用 register/unregister。 + */ +public class WirelessMasterLink { + private final IWirelessEndpoint host; + private long frequency; // 0 为未设置 + private boolean registered; + + public WirelessMasterLink(IWirelessEndpoint host) { + this.host = host; + } + + public long getFrequency() { return frequency; } + + public void setFrequency(long frequency) { + if (this.frequency == frequency) return; + // 先反注册旧频率 + if (registered) { + unregister(); + } + this.frequency = frequency; + // 再尝试注册新频率 + if (frequency != 0L && !host.isEndpointRemoved()) { + register(); + } + } + + public boolean register() { + ServerLevel level = host.getServerLevel(); + if (level == null || frequency == 0L) return false; + boolean ok = WirelessMasterRegistry.register(level, frequency, host); + this.registered = ok; + return ok; + } + + public void unregister() { + ServerLevel level = host.getServerLevel(); + if (!registered || level == null || frequency == 0L) return; + WirelessMasterRegistry.unregister(level, frequency, host); + registered = false; + } + + public void onUnloadOrRemove() { + unregister(); + } +} diff --git a/src/main/java/com/extendedae_plus/wireless/WirelessMasterRegistry.java b/src/main/java/com/extendedae_plus/wireless/WirelessMasterRegistry.java new file mode 100644 index 0000000..3add7b7 --- /dev/null +++ b/src/main/java/com/extendedae_plus/wireless/WirelessMasterRegistry.java @@ -0,0 +1,67 @@ +package com.extendedae_plus.wireless; + +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; + +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * 无线主端注册中心:按 维度 + 频率 唯一注册一个主收发器端点。 + * 从端通过本注册中心按频率查找主端,实现一对多连接。 + */ +public final class WirelessMasterRegistry { + private WirelessMasterRegistry() {} + + private static final Map> MASTERS = new HashMap<>(); + + public static synchronized boolean register(ServerLevel level, long frequency, IWirelessEndpoint endpoint) { + Objects.requireNonNull(level, "level"); + Objects.requireNonNull(endpoint, "endpoint"); + if (frequency == 0L) return false; + final Key key = new Key(level.dimension(), frequency); + cleanupIfCleared(key); + var existing = MASTERS.get(key); + var existingVal = existing == null ? null : existing.get(); + if (existingVal != null && !existingVal.isEndpointRemoved()) { + // 同维度同频率已经有主端 + return false; + } + MASTERS.put(key, new WeakReference<>(endpoint)); + return true; + } + + public static synchronized void unregister(ServerLevel level, long frequency, IWirelessEndpoint endpoint) { + if (frequency == 0L || level == null) return; + final Key key = new Key(level.dimension(), frequency); + var ref = MASTERS.get(key); + if (ref != null) { + var cur = ref.get(); + if (cur == null || cur == endpoint) { + MASTERS.remove(key); + } + } + } + + public static synchronized IWirelessEndpoint get(ServerLevel level, long frequency) { + if (frequency == 0L || level == null) return null; + final Key key = new Key(level.dimension(), frequency); + cleanupIfCleared(key); + var ref = MASTERS.get(key); + return ref == null ? null : ref.get(); + } + + private static void cleanupIfCleared(Key key) { + var ref = MASTERS.get(key); + if (ref != null && ref.get() == null) { + MASTERS.remove(key); + } + } + + private record Key(ResourceKey dim, long freq) { + @Override public String toString() { return dim.location() + "#" + freq; } + } +} diff --git a/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java b/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java new file mode 100644 index 0000000..1cebbc6 --- /dev/null +++ b/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java @@ -0,0 +1,119 @@ +package com.extendedae_plus.wireless; + +import appeng.api.networking.GridHelper; +import appeng.api.networking.IGridNode; +import appeng.me.service.helpers.ConnectionWrapper; +import com.extendedae_plus.config.ModConfigs; +import net.minecraft.server.level.ServerLevel; + +import java.util.Objects; + +/** + * 从收发器连接器: + * - 通过频率查找同维度主收发器; + * - 校验距离(<= ModConfigs.WIRELESS_MAX_RANGE); + * - 动态创建/销毁 AE2 连接(GridConnection),实现“一主多从”。 + */ +public class WirelessSlaveLink { + private final IWirelessEndpoint host; + private long frequency; // 0 未设置 + + private ConnectionWrapper connection = new ConnectionWrapper(null); + private boolean shutdown = true; + private double distance; + + public WirelessSlaveLink(IWirelessEndpoint host) { + this.host = Objects.requireNonNull(host); + } + + public void setFrequency(long frequency) { + if (this.frequency != frequency) { + this.frequency = frequency; + // 频率变更,立即尝试重连/断开 + updateStatus(); + } + } + + public long getFrequency() { + return frequency; + } + + public boolean isConnected() { + return !shutdown && connection.getConnection() != null; + } + + public double getDistance() { + return distance; + } + + /** + * 建议在 BE 的 serverTick 或者频率/加载状态变化时调用。 + */ + public void updateStatus() { + if (host.isEndpointRemoved()) { + destroyConnection(); + return; + } + final ServerLevel level = host.getServerLevel(); + if (level == null || frequency == 0L) { + destroyConnection(); + return; + } + + IWirelessEndpoint master = WirelessMasterRegistry.get(level, frequency); + shutdown = false; + distance = 0.0D; + + if (master != null && !master.isEndpointRemoved() && master.getServerLevel() == level) { + distance = Math.sqrt(master.getBlockPos().distSqr(host.getBlockPos())); + double maxRange = ModConfigs.WIRELESS_MAX_RANGE.get(); + if (distance <= maxRange) { + // 保持/建立连接 + try { + var current = connection.getConnection(); + IGridNode a = host.getGridNode(); // 从端 + IGridNode b = master.getGridNode(); // 主端 + if (a == null || b == null) { + shutdown = true; + } else { + if (current != null) { + // 如果已连且目标相同则维持 + var ca = current.a(); + var cb = current.b(); + if ((ca == a || cb == a) && (ca == b || cb == b)) { + return; // 连接已正确 + } + // 否则先断开,再重建 + current.destroy(); + connection = new ConnectionWrapper(null); + } + connection = new ConnectionWrapper(GridHelper.createConnection(a, b)); + return; + } + } catch (IllegalStateException ignore) { + // 连接非法(如重复连接等)——落入重建/关闭逻辑 + } + } else { + shutdown = true; // 超出范围 + } + } else { + shutdown = true; // 无主或主端不可用/不同维度 + } + + // 需要关闭连接 + destroyConnection(); + } + + public void onUnloadOrRemove() { + destroyConnection(); + } + + private void destroyConnection() { + var current = connection.getConnection(); + if (current != null) { + current.destroy(); + connection.setConnection(null); + } + connection = new ConnectionWrapper(null); + } +} diff --git a/src/main/resources/assets/extendedae_plus/blockstates/wireless_transceiver.json b/src/main/resources/assets/extendedae_plus/blockstates/wireless_transceiver.json new file mode 100644 index 0000000..7dedc1a --- /dev/null +++ b/src/main/resources/assets/extendedae_plus/blockstates/wireless_transceiver.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "extendedae_plus:block/wireless_transceiver" } + } +} 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 eaa356e..a3f6e55 100644 --- a/src/main/resources/assets/extendedae_plus/lang/zh_cn.json +++ b/src/main/resources/assets/extendedae_plus/lang/zh_cn.json @@ -2,5 +2,7 @@ "gui.expatternprovider.toggle_slots": "切换槽位显示", "gui.expatternprovider.hide_slots": "隐藏槽位", "gui.expatternprovider.show_slots": "显示槽位", - "gui.expatternprovider.clear_selection": "取消选择" -} \ No newline at end of file + "gui.expatternprovider.clear_selection": "取消选择", + "block.extendedae_plus.wireless_transceiver": "无线收发器", + "item.extendedae_plus.wireless_transceiver": "无线收发器" +} \ No newline at end of file diff --git a/src/main/resources/assets/extendedae_plus/models/block/wireless_transceiver.json b/src/main/resources/assets/extendedae_plus/models/block/wireless_transceiver.json new file mode 100644 index 0000000..9c23dd0 --- /dev/null +++ b/src/main/resources/assets/extendedae_plus/models/block/wireless_transceiver.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "minecraft:block/iron_block" + } +} diff --git a/src/main/resources/assets/extendedae_plus/models/item/wireless_transceiver.json b/src/main/resources/assets/extendedae_plus/models/item/wireless_transceiver.json new file mode 100644 index 0000000..3cc9cde --- /dev/null +++ b/src/main/resources/assets/extendedae_plus/models/item/wireless_transceiver.json @@ -0,0 +1,3 @@ +{ + "parent": "extendedae_plus:block/wireless_transceiver" +} diff --git a/src/main/resources/data/extendedae_plus/loot_tables/blocks/wireless_transceiver.json b/src/main/resources/data/extendedae_plus/loot_tables/blocks/wireless_transceiver.json new file mode 100644 index 0000000..190f7ec --- /dev/null +++ b/src/main/resources/data/extendedae_plus/loot_tables/blocks/wireless_transceiver.json @@ -0,0 +1,14 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "extendedae_plus:wireless_transceiver" + } + ] + } + ] +}