9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-30 04:19:27 +00:00

refactor(network): 重写 1.21.5+ 版本容器点击处理

This commit is contained in:
jhqwqmc
2025-08-04 20:04:46 +08:00
parent 23f566cbf0
commit 437b1bc991
4 changed files with 37 additions and 56 deletions

View File

@@ -169,6 +169,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
registerNMSPacketConsumer(PacketConsumers.FINISH_CONFIGURATION, NetworkReflections.clazz$ClientboundFinishConfigurationPacket);
registerNMSPacketConsumer(PacketConsumers.LOGIN_FINISHED, NetworkReflections.clazz$ClientboundLoginFinishedPacket);
registerNMSPacketConsumer(PacketConsumers.UPDATE_TAGS, NetworkReflections.clazz$ClientboundUpdateTagsPacket);
registerNMSPacketConsumer(PacketConsumers.CONTAINER_CLICK_1_21_5, VersionHelper.isOrAbove1_21_5() ? NetworkReflections.clazz$ServerboundContainerClickPacket : null);
registerS2CByteBufPacketConsumer(PacketConsumers.LEVEL_CHUNK_WITH_LIGHT, this.packetIds.clientboundLevelChunkWithLightPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket());
registerS2CByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket());
@@ -198,7 +199,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
registerS2CByteBufPacketConsumer(PacketConsumers.SET_EQUIPMENT, this.packetIds.clientboundSetEquipmentPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.SET_PLAYER_INVENTORY_1_21_2, this.packetIds.clientboundSetPlayerInventoryPacket());
registerC2SByteBufPacketConsumer(PacketConsumers.SET_CREATIVE_MODE_SLOT, this.packetIds.serverboundSetCreativeModeSlotPacket());
registerC2SByteBufPacketConsumer(VersionHelper.isOrAbove1_21_5() ? PacketConsumers.CONTAINER_CLICK_1_21_5 : PacketConsumers.CONTAINER_CLICK_1_20, this.packetIds.serverboundContainerClickPacket());
registerC2SByteBufPacketConsumer(PacketConsumers.CONTAINER_CLICK_1_20, VersionHelper.isOrAbove1_21_5() ? -1 : this.packetIds.serverboundContainerClickPacket());
registerC2SByteBufPacketConsumer(PacketConsumers.INTERACT_ENTITY, this.packetIds.serverboundInteractPacket());
}

View File

@@ -2237,63 +2237,34 @@ public class PacketConsumers {
}
};
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> CONTAINER_CLICK_1_21_5 = (user, event) -> {
// 因为不能走编码器只能替换对象
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> CONTAINER_CLICK_1_21_5 = (user, event, packet) -> {
try {
FriendlyByteBuf buf = event.getBuffer();
boolean changed = false;
Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
Object inventory = FastNMS.INSTANCE.method$Player$getInventory(user.serverPlayer());
int containerId = buf.readContainerId();
int stateId = buf.readVarInt();
short slotNum = buf.readShort();
byte buttonNum = buf.readByte();
int clickType = buf.readVarInt();
int i = buf.readVarInt();
Int2ObjectMap<Object> changedSlots = new Int2ObjectOpenHashMap<>(i);
for (int j = 0; j < i; ++j) {
int k = buf.readShort();
Object hashedStack = FastNMS.INSTANCE.method$StreamDecoder$decode(NetworkReflections.instance$HashedStack$STREAM_CODEC, friendlyBuf);
Object serverSideItemStack = FastNMS.INSTANCE.method$Container$getItem(inventory, k);
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(serverSideItemStack).clone(), ((net.momirealms.craftengine.core.entity.player.Player) user));
if (optional.isPresent()) {
Object clientSideItemStack = FastNMS.INSTANCE.field$CraftItemStack$handle(optional.get());
boolean isSync = FastNMS.INSTANCE.method$HashedStack$matches(hashedStack, clientSideItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator());
if (isSync) {
changed = true;
hashedStack = FastNMS.INSTANCE.method$HashedStack$create(serverSideItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator());
}
}
changedSlots.put(k, hashedStack);
var player = (net.momirealms.craftengine.core.entity.player.Player) user;
int containerId = FastNMS.INSTANCE.field$ServerboundContainerClickPacket$containerId(packet);
int stateId = FastNMS.INSTANCE.field$ServerboundContainerClickPacket$stateId(packet);
short slotNum = FastNMS.INSTANCE.field$ServerboundContainerClickPacket$slotNum(packet);
byte buttonNum = FastNMS.INSTANCE.field$ServerboundContainerClickPacket$buttonNum(packet);
Object clickType = FastNMS.INSTANCE.field$ServerboundContainerClickPacket$clickType(packet);
@SuppressWarnings("unchecked")
Int2ObjectMap<Object> changedSlots = FastNMS.INSTANCE.field$ServerboundContainerClickPacket$changedSlots(packet);
Int2ObjectMap<Object> newChangedSlots = new Int2ObjectOpenHashMap<>();
for (Int2ObjectMap.Entry<Object> entry : changedSlots.int2ObjectEntrySet()) {
Object hashedStack = entry.getValue();
if (!NetworkReflections.clazz$HashedStack$ActualItem.isInstance(hashedStack)) continue;
Object item = FastNMS.INSTANCE.method$ActualItem$item(hashedStack);
int count = FastNMS.INSTANCE.method$ActualItem$count(hashedStack);
Object components = FastNMS.INSTANCE.method$ActualItem$components(hashedStack);
newChangedSlots.put(entry.getIntKey(), FastNMS.INSTANCE.constructor$InjectedHashedStack(item, count, components, player));
}
Object carriedHashedStack = FastNMS.INSTANCE.method$StreamDecoder$decode(NetworkReflections.instance$HashedStack$STREAM_CODEC, friendlyBuf);
Object containerMenu = FastNMS.INSTANCE.field$Player$containerMenu(user.serverPlayer());
Object serverSideCarriedItemStack = FastNMS.INSTANCE.method$AbstractContainerMenu$getCarried(containerMenu);
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(serverSideCarriedItemStack).clone(), ((net.momirealms.craftengine.core.entity.player.Player) user));
if (optional.isPresent()) {
Object clientSideCarriedItemStack = FastNMS.INSTANCE.field$CraftItemStack$handle(optional.get());
boolean isSync = FastNMS.INSTANCE.method$HashedStack$matches(carriedHashedStack, clientSideCarriedItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator());
if (isSync) {
changed = true;
carriedHashedStack = FastNMS.INSTANCE.method$HashedStack$create(serverSideCarriedItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator());
}
}
if (changed) {
event.setChanged(true);
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeContainerId(containerId);
buf.writeVarInt(stateId);
buf.writeShort(slotNum);
buf.writeByte(buttonNum);
buf.writeVarInt(clickType);
buf.writeVarInt(changedSlots.size());
Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
changedSlots.forEach((k, v) -> {
buf.writeShort(k);
FastNMS.INSTANCE.method$StreamEncoder$encode(NetworkReflections.instance$HashedStack$STREAM_CODEC, newFriendlyBuf, v);
});
FastNMS.INSTANCE.method$StreamEncoder$encode(NetworkReflections.instance$HashedStack$STREAM_CODEC, newFriendlyBuf, carriedHashedStack);
Object carriedItem = FastNMS.INSTANCE.field$ServerboundContainerClickPacket$carriedItem(packet);
if (NetworkReflections.clazz$HashedStack$ActualItem.isInstance(carriedItem)) {
Object item = FastNMS.INSTANCE.method$ActualItem$item(carriedItem);
int count = FastNMS.INSTANCE.method$ActualItem$count(carriedItem);
Object components = FastNMS.INSTANCE.method$ActualItem$components(carriedItem);
carriedItem = FastNMS.INSTANCE.constructor$InjectedHashedStack(item, count, components, player);
}
event.replacePacket(FastNMS.INSTANCE.constructor$ServerboundContainerClickPacket(containerId, stateId, slotNum, buttonNum, clickType, newChangedSlots, carriedItem));
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ServerboundContainerClickPacket", e);
}

View File

@@ -1646,4 +1646,13 @@ public final class NetworkReflections {
public static final Constructor<?> constructor$UnknownPayload = Optional.ofNullable(clazz$UnknownPayload)
.map(ReflectionUtils::getTheOnlyConstructor)
.orElse(null);
// 1.21.5+
public static final Class<?> clazz$HashedStack$ActualItem = MiscUtils.requireNonNullIf(
BukkitReflectionUtils.findReobfOrMojmapClass(
"network.HashedStack$a",
"network.HashedStack$ActualItem"
),
VersionHelper.isOrAbove1_21_5()
);
}