9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-29 03:49:15 +00:00

feat(network): 完善客户端侧物品数据处理

This commit is contained in:
jhqwqmc
2025-05-28 02:47:55 +08:00
parent 4adcadac8f
commit 2b8f103d4b
4 changed files with 42 additions and 10 deletions

View File

@@ -9,6 +9,7 @@ import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIdFinder;
import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIds1_20;
import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIds1_20_5;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
@@ -40,9 +41,8 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
private static BukkitNetworkManager instance;
private static final Map<Class<?>, TriConsumer<NetWorkUser, NMSPacketEvent, Object>> NMS_PACKET_HANDLERS = new HashMap<>();
// only for game stage for the moment
// todo 优化成 数组
private static final Map<Integer, BiConsumer<NetWorkUser, ByteBufPacketEvent>> S2C_BYTE_BUFFER_PACKET_HANDLERS = new HashMap<>();
private static final Map<Integer, BiConsumer<NetWorkUser, ByteBufPacketEvent>> C2S_BYTE_BUFFER_PACKET_HANDLERS = new HashMap<>();
private static BiConsumer<NetWorkUser, ByteBufPacketEvent>[] S2C_BYTE_BUFFER_PACKET_HANDLERS;
private static BiConsumer<NetWorkUser, ByteBufPacketEvent>[] C2S_BYTE_BUFFER_PACKET_HANDLERS;
private static void registerNMSPacketConsumer(final TriConsumer<NetWorkUser, NMSPacketEvent, Object> function, @Nullable Class<?> packet) {
if (packet == null) return;
@@ -51,12 +51,18 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
private static void registerS2CByteBufPacketConsumer(final BiConsumer<NetWorkUser, ByteBufPacketEvent> function, int id) {
if (id == -1) return;
S2C_BYTE_BUFFER_PACKET_HANDLERS.put(id, function);
if (id < 0 || id >= S2C_BYTE_BUFFER_PACKET_HANDLERS.length) {
throw new IllegalArgumentException("Invalid packet id: " + id);
}
S2C_BYTE_BUFFER_PACKET_HANDLERS[id] = function;
}
private static void registerC2SByteBufPacketConsumer(final BiConsumer<NetWorkUser, ByteBufPacketEvent> function, int id) {
if (id == -1) return;
C2S_BYTE_BUFFER_PACKET_HANDLERS.put(id, function);
if (id < 0 || id >= C2S_BYTE_BUFFER_PACKET_HANDLERS.length) {
throw new IllegalArgumentException("Invalid packet id: " + id);
}
C2S_BYTE_BUFFER_PACKET_HANDLERS[id] = function;
}
private final BiConsumer<Object, List<Object>> packetsConsumer;
@@ -81,8 +87,13 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
private static boolean hasModelEngine;
private static boolean hasViaVersion;
@SuppressWarnings("unchecked")
public BukkitNetworkManager(BukkitCraftEngine plugin) {
instance = this;
S2C_BYTE_BUFFER_PACKET_HANDLERS = new BiConsumer[PacketIdFinder.maxS2CPacketId() + 1];
C2S_BYTE_BUFFER_PACKET_HANDLERS = new BiConsumer[PacketIdFinder.maxC2SPacketId() + 1];
Arrays.fill(S2C_BYTE_BUFFER_PACKET_HANDLERS, (BiConsumer<NetWorkUser, ByteBufPacketEvent>) (user, event) -> {});
Arrays.fill(C2S_BYTE_BUFFER_PACKET_HANDLERS, (BiConsumer<NetWorkUser, ByteBufPacketEvent>) (user, event) -> {});
hasModelEngine = Bukkit.getPluginManager().getPlugin("ModelEngine") != null;
hasViaVersion = Bukkit.getPluginManager().getPlugin("ViaVersion") != null;
this.plugin = plugin;
@@ -647,13 +658,13 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
protected void handleS2CByteBufPacket(NetWorkUser user, ByteBufPacketEvent event) {
int packetID = event.packetID();
Optional.ofNullable(S2C_BYTE_BUFFER_PACKET_HANDLERS.get(packetID))
Optional.ofNullable(S2C_BYTE_BUFFER_PACKET_HANDLERS[packetID])
.ifPresent(function -> function.accept(user, event));
}
protected void handleC2SByteBufPacket(NetWorkUser user, ByteBufPacketEvent event) {
int packetID = event.packetID();
Optional.ofNullable(C2S_BYTE_BUFFER_PACKET_HANDLERS.get(packetID))
Optional.ofNullable(C2S_BYTE_BUFFER_PACKET_HANDLERS[packetID])
.ifPresent(function -> function.accept(user, event));
}

View File

@@ -2140,11 +2140,12 @@ public class PacketConsumers {
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$FriendlyByteBuf$writeItem(buf, v);
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, v);
});
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(buf, carriedItem);
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, carriedItem);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ServerboundContainerClickPacket", e);

View File

@@ -6,12 +6,15 @@ import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.VersionHelper;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class PacketIdFinder {
private static final Map<String, Map<String, Integer>> gamePacketIdsByName = new HashMap<>();
private static final Map<String, Map<Class<?>, Integer>> gamePacketIdsByClazz = new HashMap<>();
private static final int maxC2SPacketId;
private static final int maxS2CPacketId;
static {
try {
@@ -34,6 +37,23 @@ public class PacketIdFinder {
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to get packets", e);
}
maxS2CPacketId = calculateMaxId("clientbound");
maxC2SPacketId = calculateMaxId("serverbound");
}
private static int calculateMaxId(String direction) {
if (VersionHelper.isOrAbove1_20_5()) {
return gamePacketIdsByName.getOrDefault(direction, Collections.emptyMap()).size();
} else {
return gamePacketIdsByClazz.getOrDefault(direction, Collections.emptyMap()).size();
}
}
public static int maxC2SPacketId() {
return maxC2SPacketId;
}
public static int maxS2CPacketId() {
return maxS2CPacketId;
}
public static int clientboundByName(String packetName) {

View File

@@ -41,7 +41,7 @@ import java.util.function.Consumer;
import static java.util.Objects.requireNonNull;
@SuppressWarnings("unused")
@SuppressWarnings({"unused", "unchecked"})
public class Reflections {
public static void init() {