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:
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user