改用自己的网络包
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.client.gui.widgets.IconButton;
|
||||||
import appeng.menu.AEBaseMenu;
|
import appeng.menu.AEBaseMenu;
|
||||||
import com.glodblock.github.extendedae.client.gui.GuiExPatternTerminal;
|
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.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
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.world.item.ItemStack;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Pseudo;
|
import org.spongepowered.asm.mixin.Pseudo;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
@ -264,25 +267,22 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<AEBaseMenu>
|
||||||
faceOrd = ((Direction) face).ordinal();
|
faceOrd = ((Direction) face).ordinal();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送 CGenericPacket("open_ui", [posLong, dim, face])
|
// 发送我们自己的 C2S 包:OpenProviderUiC2SPacket
|
||||||
try {
|
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) {
|
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) {
|
} catch (Throwable t) {
|
||||||
if (this.minecraft != null && this.minecraft.player != null) {
|
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) {
|
} catch (Throwable t) {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,12 @@ public class ModNetwork {
|
||||||
private static int id = 0;
|
private static int id = 0;
|
||||||
|
|
||||||
public static void register() {
|
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)
|
CHANNEL.messageBuilder(PickFromWirelessC2SPacket.class, nextId(), NetworkDirection.PLAY_TO_SERVER)
|
||||||
.encoder(PickFromWirelessC2SPacket::encode)
|
.encoder(PickFromWirelessC2SPacket::encode)
|
||||||
.decoder(PickFromWirelessC2SPacket::decode)
|
.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