改用自己的网络包
This commit is contained in:
parent
53945a8247
commit
1d193d1674
|
|
@ -10,6 +10,8 @@ import appeng.client.gui.widgets.AETextField;
|
|||
import appeng.client.gui.widgets.IconButton;
|
||||
import appeng.menu.AEBaseMenu;
|
||||
import com.glodblock.github.extendedae.client.gui.GuiExPatternTerminal;
|
||||
import com.extendedae_plus.network.ModNetwork;
|
||||
import com.extendedae_plus.network.OpenProviderUiC2SPacket;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
|
|
@ -22,6 +24,7 @@ import net.minecraft.world.inventory.Slot;
|
|||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Pseudo;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
|
@ -264,25 +267,22 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<AEBaseMenu>
|
|||
faceOrd = ((Direction) face).ordinal();
|
||||
}
|
||||
|
||||
// 发送 CGenericPacket("open_ui", [posLong, dim, face])
|
||||
// 发送我们自己的 C2S 包:OpenProviderUiC2SPacket
|
||||
try {
|
||||
Class<?> EPPNetworkHandlerClass = Class.forName("com.glodblock.github.extendedae.network.EPPNetworkHandler");
|
||||
Object handlerInstance = EPPNetworkHandlerClass.getField("INSTANCE").get(null);
|
||||
|
||||
Class<?> packetClass = Class.forName("com.glodblock.github.glodium.network.packet.CGenericPacket");
|
||||
Constructor<?> constructor = packetClass.getConstructor(String.class, Object[].class);
|
||||
Object packet = constructor.newInstance("open_ui", new Object[]{posLong, dimStr, faceOrd});
|
||||
|
||||
Class<?> iMessage = Class.forName("com.glodblock.github.glodium.network.packet.IMessage");
|
||||
Method sendToServer = EPPNetworkHandlerClass.getMethod("sendToServer", iMessage);
|
||||
|
||||
sendToServer.invoke(handlerInstance, packet);
|
||||
if (this.minecraft != null && this.minecraft.player != null) {
|
||||
EAP_LOGGER.debug("[EPlus] Sent open_ui packet: pos={}, dim={}, face={}", posLong, dimStr, faceOrd);
|
||||
this.minecraft.player.displayClientMessage(Component.literal("↗ 正在请求打开供应器界面..."), true);
|
||||
}
|
||||
ModNetwork.CHANNEL.sendToServer(new OpenProviderUiC2SPacket(
|
||||
posLong,
|
||||
new ResourceLocation(dimStr),
|
||||
faceOrd
|
||||
));
|
||||
if (this.minecraft != null && this.minecraft.player != null) {
|
||||
EAP_LOGGER.info("[EPlus] Sent OpenProviderUiC2SPacket: pos={}, dim={}, face={}", posLong, dimStr, faceOrd);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
if (this.minecraft != null && this.minecraft.player != null) {
|
||||
this.minecraft.player.displayClientMessage(Component.literal("❌ ExtendedAE Plus: 网络模块不可用,无法发送打开UI请求"), true);
|
||||
this.minecraft.player.displayClientMessage(Component.literal("❌ ExtendedAE Plus: 发送打开UI请求失败"), true);
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,12 @@ public class ModNetwork {
|
|||
private static int id = 0;
|
||||
|
||||
public static void register() {
|
||||
CHANNEL.messageBuilder(OpenProviderUiC2SPacket.class, nextId(), NetworkDirection.PLAY_TO_SERVER)
|
||||
.encoder(OpenProviderUiC2SPacket::encode)
|
||||
.decoder(OpenProviderUiC2SPacket::decode)
|
||||
.consumerNetworkThread(OpenProviderUiC2SPacket::handle)
|
||||
.add();
|
||||
|
||||
CHANNEL.messageBuilder(PickFromWirelessC2SPacket.class, nextId(), NetworkDirection.PLAY_TO_SERVER)
|
||||
.encoder(PickFromWirelessC2SPacket::encode)
|
||||
.decoder(PickFromWirelessC2SPacket::decode)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,149 @@
|
|||
package com.extendedae_plus.network;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
public class OpenProviderUiC2SPacket {
|
||||
private final long posLong;
|
||||
private final ResourceLocation dimId;
|
||||
private final int faceOrd; // 目前保留,若目标需要可用
|
||||
|
||||
public OpenProviderUiC2SPacket(long posLong, ResourceLocation dimId, int faceOrd) {
|
||||
this.posLong = posLong;
|
||||
this.dimId = dimId;
|
||||
this.faceOrd = faceOrd;
|
||||
}
|
||||
|
||||
public static void encode(OpenProviderUiC2SPacket msg, FriendlyByteBuf buf) {
|
||||
buf.writeLong(msg.posLong);
|
||||
buf.writeResourceLocation(msg.dimId);
|
||||
buf.writeVarInt(msg.faceOrd);
|
||||
}
|
||||
|
||||
public static OpenProviderUiC2SPacket decode(FriendlyByteBuf buf) {
|
||||
long posLong = buf.readLong();
|
||||
ResourceLocation dimId = buf.readResourceLocation();
|
||||
int faceOrd = buf.readVarInt();
|
||||
return new OpenProviderUiC2SPacket(posLong, dimId, faceOrd);
|
||||
|
||||
}
|
||||
|
||||
public static void handle(OpenProviderUiC2SPacket msg, Supplier<NetworkEvent.Context> ctx) {
|
||||
NetworkEvent.Context context = ctx.get();
|
||||
context.enqueueWork(() -> {
|
||||
ServerPlayer player = context.getSender();
|
||||
if (player == null) return;
|
||||
Logger logger = LogManager.getLogger("ExtendedAE_Plus");
|
||||
|
||||
// 校验维度与方块
|
||||
ResourceKey<Level> levelKey = ResourceKey.create(Registries.DIMENSION, msg.dimId);
|
||||
ServerLevel level = player.server.getLevel(levelKey);
|
||||
if (level == null) {
|
||||
logger.warn("[EPlus] OpenProviderUiC2SPacket: invalid dimension {}", msg.dimId);
|
||||
player.displayClientMessage(net.minecraft.network.chat.Component.literal("❌ 维度无效:" + msg.dimId), true);
|
||||
return; // 无效维度
|
||||
}
|
||||
|
||||
BlockPos pos = BlockPos.of(msg.posLong);
|
||||
if (!level.isLoaded(pos)) {
|
||||
logger.warn("[EPlus] OpenProviderUiC2SPacket: chunk not loaded at {} in {}", pos, msg.dimId);
|
||||
player.displayClientMessage(net.minecraft.network.chat.Component.literal("❌ 区块未加载:" + pos.toShortString()), true);
|
||||
return; // 区块未加载
|
||||
}
|
||||
|
||||
var be = level.getBlockEntity(pos);
|
||||
var stateAtPos = level.getBlockState(pos);
|
||||
|
||||
// 目标通常是供应器所面对/连接的“相邻方块”,优先尝试邻居
|
||||
Direction[] tries = (msg.faceOrd >= 0 && msg.faceOrd < Direction.values().length)
|
||||
? new Direction[]{Direction.values()[msg.faceOrd]}
|
||||
: Direction.values();
|
||||
|
||||
for (Direction dir : tries) {
|
||||
BlockPos targetPos = pos.relative(dir);
|
||||
BlockEntity tbe = level.getBlockEntity(targetPos);
|
||||
if (tbe instanceof MenuProvider provider) {
|
||||
NetworkHooks.openScreen(player, provider, targetPos);
|
||||
logger.debug("[EPlus] OpenProviderUiC2SPacket: opened BE MenuProvider at {} (neighbor via {})", targetPos, dir);
|
||||
return;
|
||||
}
|
||||
var tstate = level.getBlockState(targetPos);
|
||||
MenuProvider provider2 = tstate.getMenuProvider(level, targetPos);
|
||||
if (provider2 != null) {
|
||||
NetworkHooks.openScreen(player, provider2, targetPos);
|
||||
logger.debug("[EPlus] OpenProviderUiC2SPacket: opened State MenuProvider at {} (neighbor via {})", targetPos, dir);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果邻居也未提供 MenuProvider,则兜底:尽量模拟一次徒手右键相邻方块
|
||||
boolean anyHandEmpty = player.getMainHandItem().isEmpty() || player.getOffhandItem().isEmpty();
|
||||
if (anyHandEmpty) {
|
||||
InteractionHand hand = player.getMainHandItem().isEmpty() ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND;
|
||||
if (msg.faceOrd >= 0 && msg.faceOrd < Direction.values().length) {
|
||||
Direction dir = Direction.values()[msg.faceOrd];
|
||||
BlockPos targetPos = pos.relative(dir);
|
||||
var state2 = level.getBlockState(targetPos);
|
||||
var hit = new BlockHitResult(Vec3.atCenterOf(targetPos), dir.getOpposite(), targetPos, false);
|
||||
InteractionResult r = state2.use(level, player, hand, hit);
|
||||
logger.debug("[EPlus] OpenProviderUiC2SPacket: fallback(use) at {} hit {} (via {}), result={}", targetPos, dir.getOpposite(), dir, r);
|
||||
if (r.consumesAction()) {
|
||||
player.displayClientMessage(net.minecraft.network.chat.Component.literal("✅ 已尝试模拟右键交互: " + r), true);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// 无明确朝向:优先挑选有方块实体的邻居,否则挑选非空气方块
|
||||
Direction chosen = null;
|
||||
for (Direction d : Direction.values()) {
|
||||
if (level.getBlockEntity(pos.relative(d)) != null) { chosen = d; break; }
|
||||
}
|
||||
if (chosen == null) {
|
||||
for (Direction d : Direction.values()) {
|
||||
if (!level.getBlockState(pos.relative(d)).isAir()) { chosen = d; break; }
|
||||
}
|
||||
}
|
||||
if (chosen != null) {
|
||||
BlockPos targetPos = pos.relative(chosen);
|
||||
var state2 = level.getBlockState(targetPos);
|
||||
var hit = new BlockHitResult(Vec3.atCenterOf(targetPos), chosen.getOpposite(), targetPos, false);
|
||||
InteractionResult r = state2.use(level, player, hand, hit);
|
||||
logger.debug("[EPlus] OpenProviderUiC2SPacket: fallback(use) at {} hit {} (auto via {}), result={}", targetPos, chosen.getOpposite(), chosen, r);
|
||||
if (r.consumesAction()) {
|
||||
player.displayClientMessage(net.minecraft.network.chat.Component.literal("✅ 已尝试模拟右键交互: " + r), true);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
logger.debug("[EPlus] OpenProviderUiC2SPacket: no neighbor candidate for fallback (faceOrd<0)");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.debug("[EPlus] OpenProviderUiC2SPacket: skip fallback(use) because both hands occupied");
|
||||
}
|
||||
|
||||
// 若走到这里,说明未能打开界面
|
||||
logger.warn("[EPlus] OpenProviderUiC2SPacket: No MenuProvider around {} (BE={}, Block={})", pos,
|
||||
be == null ? "null" : be.getClass().getName(), stateAtPos.getBlock().getClass().getName());
|
||||
player.displayClientMessage(net.minecraft.network.chat.Component.literal("❌ 未找到可打开的相邻界面"), true);
|
||||
});
|
||||
context.setPacketHandled(true);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user