9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-30 20:39:10 +00:00

Merge remote-tracking branch 'upstream/dev' into dev

# Conflicts:
#	bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java
This commit is contained in:
jhqwqmc
2025-05-31 16:30:10 +08:00
7 changed files with 113 additions and 66 deletions

View File

@@ -123,15 +123,17 @@ templates#models#2d:
type: "minecraft:condition"
property: minecraft:broken
on-false:
template: default:model/generated
arguments:
model: "{model}"
texture: "{texture}"
path: "{model}"
generation:
parent: "minecraft:item/generated"
textures:
"layer0": "{texture}"
on-true:
template: default:model/generated
arguments:
model: "{broken_model}"
texture: "{broken_texture}"
path: "{broken_model}"
generation:
parent: "minecraft:item/generated"
textures:
"layer0": "{broken_texture}"
# template: default:model/simplified_elytra
# arguments:
# path: [model/texture]_path
@@ -140,8 +142,8 @@ templates#models#2d:
template: default:model/elytra
arguments:
model: "{path}"
broken_model: "{broken_path}"
texture: "{path}"
broken_model: "{broken_path}"
broken_texture: "{broken_path}"
# shield

View File

@@ -156,7 +156,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
registerNMSPacketConsumer(PacketConsumers.USE_ITEM_ON, Reflections.clazz$ServerboundUseItemOnPacket);
registerNMSPacketConsumer(PacketConsumers.PICK_ITEM_FROM_BLOCK, Reflections.clazz$ServerboundPickItemFromBlockPacket);
registerNMSPacketConsumer(PacketConsumers.SET_CREATIVE_SLOT, Reflections.clazz$ServerboundSetCreativeModeSlotPacket);
registerNMSPacketConsumer(PacketConsumers.ADD_ENTITY, Reflections.clazz$ClientboundAddEntityPacket);
registerNMSPacketConsumer(PacketConsumers.LOGIN, Reflections.clazz$ClientboundLoginPacket);
registerNMSPacketConsumer(PacketConsumers.RESPAWN, Reflections.clazz$ClientboundRespawnPacket);
registerNMSPacketConsumer(PacketConsumers.INTERACT_ENTITY, Reflections.clazz$ServerboundInteractPacket);
@@ -560,9 +559,20 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
}
if (byteBuf.isReadable()) {
list.add(byteBuf.retain());
} else {
throw CancelPacketException.INSTANCE;
}
}
@SuppressWarnings("deprecation")
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (ExceptionUtils.hasException(cause, CancelPacketException.INSTANCE)) {
return;
}
super.exceptionCaught(ctx, cause);
}
private boolean handleCompression(ChannelHandlerContext ctx, ByteBuf buffer) {
if (this.handledCompression) return false;
int compressIndex = ctx.pipeline().names().indexOf("compress");

View File

@@ -0,0 +1,6 @@
package net.momirealms.craftengine.bukkit.plugin.network;
public class CancelPacketException extends RuntimeException {
public static final CancelPacketException INSTANCE = new CancelPacketException();
}

View File

@@ -117,34 +117,62 @@ public class PacketConsumers {
buf.writeShort(za);
}
};
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$TRIDENT$registryId] = (user, event) -> {
FriendlyByteBuf buf = event.getBuffer();
int id = buf.readVarInt();
BukkitProjectileManager.instance().projectileByEntityId(id).ifPresent(customProjectile -> {
ProjectilePacketHandler handler = new ProjectilePacketHandler(customProjectile, id);
handler.convertAddCustomProjectilePacket(buf, event);
user.entityPacketHandlers().put(id, handler);
});
};
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$BLOCK_DISPLAY$registryId] = simpleAddEntityHandler(BlockDisplayPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$TEXT_DISPLAY$registryId] = simpleAddEntityHandler(TextDisplayPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$ARMOR_STAND$registryId] = simpleAddEntityHandler(ArmorStandPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$ITEM_DISPLAY$registryId] = simpleAddEntityHandler(ItemDisplayPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$FIREBALL$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$EYE_OF_ENDER$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$FIREWORK_ROCKET$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$ITEM$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$ITEM_FRAME$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$GLOW_ITEM_FRAME$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$SMALL_FIREBALL$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$EGG$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$ENDER_PEARL$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$EXPERIENCE_BOTTLE$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$SNOWBALL$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$POTION$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$FIREBALL$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$EYE_OF_ENDER$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$FIREWORK_ROCKET$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$SMALL_FIREBALL$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$EGG$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$ENDER_PEARL$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$EXPERIENCE_BOTTLE$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$SNOWBALL$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$POTION$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$TRIDENT$registryId] = createOptionalCustomProjectileEntityHandler();
if (VersionHelper.isOrAbove1_20_5()) {
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$OMINOUS_ITEM_SPAWNER$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
}
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$ITEM_DISPLAY$registryId] = (user, event) -> {
FriendlyByteBuf buf = event.getBuffer();
int id = buf.readVarInt();
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(id);
if (furniture != null) {
user.entityPacketHandlers().put(id, new FurniturePacketHandler(furniture.fakeEntityIds()));
user.sendPacket(furniture.spawnPacket((Player) user.platformPlayer()), false);
if (Config.hideBaseEntity() && !furniture.hasExternalModel()) {
event.setCancelled(true);
}
}
};
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$INTERACTION$registryId] = (user, event) -> {
if (BukkitFurnitureManager.NMS_COLLISION_ENTITY_TYPE != Reflections.instance$EntityType$INTERACTION) return;
FriendlyByteBuf buf = event.getBuffer();
int id = buf.readVarInt();
// Cancel collider entity packet
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(id);
if (furniture != null) {
event.setCancelled(true);
user.entityPacketHandlers().put(id, FurnitureCollisionPacketHandler.INSTANCE);
}
};
ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$OAK_BOAT$registryId] = (user, event) -> {
if (BukkitFurnitureManager.NMS_COLLISION_ENTITY_TYPE != Reflections.instance$EntityType$OAK_BOAT) return;
FriendlyByteBuf buf = event.getBuffer();
int id = buf.readVarInt();
// Cancel collider entity packet
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(id);
if (furniture != null) {
event.setCancelled(true);
user.entityPacketHandlers().put(id, FurnitureCollisionPacketHandler.INSTANCE);
}
};
}
private static BukkitNetworkManager.Handlers simpleAddEntityHandler(EntityPacketHandler handler) {
@@ -154,6 +182,20 @@ public class PacketConsumers {
};
}
private static BukkitNetworkManager.Handlers createOptionalCustomProjectileEntityHandler() {
return (user, event) -> {
FriendlyByteBuf buf = event.getBuffer();
int id = buf.readVarInt();
BukkitProjectileManager.instance().projectileByEntityId(id).ifPresentOrElse(customProjectile -> {
ProjectilePacketHandler handler = new ProjectilePacketHandler(customProjectile, id);
handler.convertAddCustomProjectilePacket(buf, event);
user.entityPacketHandlers().put(id, handler);
}, () -> {
user.entityPacketHandlers().put(id, CommonItemPacketHandler.INSTANCE);
});
};
}
public static void initBlocks(Map<Integer, Integer> map, int registrySize) {
mappings = new int[registrySize];
for (int i = 0; i < registrySize; i++) {
@@ -1233,13 +1275,13 @@ public class PacketConsumers {
if (!user.isOnline()) return;
BukkitServerPlayer player = (BukkitServerPlayer) user;
if (VersionHelper.isFolia()) {
BukkitCraftEngine.instance().scheduler().sync().run(() -> {
player.platformPlayer().getScheduler().run(BukkitCraftEngine.instance().bootstrap(), (t) -> {
try {
handleSetCreativeSlotPacketOnMainThread(player, packet);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ServerboundSetCreativeModeSlotPacket", e);
}
}, (World) player.world().platformWorld(), (MCUtils.fastFloor(player.x())) >> 4, (MCUtils.fastFloor(player.z())) >> 4);
}, () -> {});
} else {
handleSetCreativeSlotPacketOnMainThread(player, packet);
}
@@ -1371,16 +1413,13 @@ public class PacketConsumers {
Player player = (Player) user.platformPlayer();
if (player == null) return;
if (VersionHelper.isFolia()) {
Location location = player.getLocation();
int x = location.getBlockX();
int z = location.getBlockZ();
BukkitCraftEngine.instance().scheduler().sync().run(() -> {
player.getScheduler().run(BukkitCraftEngine.instance().bootstrap(), (t) -> {
try {
handlePickItemFromEntityOnMainThread(player, furniture);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ServerboundPickItemFromEntityPacket", e);
}
}, player.getWorld(), x >> 4, z >> 4);
}, () -> {});
} else {
BukkitCraftEngine.instance().scheduler().sync().run(() -> {
try {
@@ -1430,33 +1469,6 @@ public class PacketConsumers {
}
};
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> ADD_ENTITY = (user, event, packet) -> {
try {
Object entityType = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$type(packet);
int entityId = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$entityId(packet);
if (entityType == Reflections.instance$EntityType$ITEM_DISPLAY) {
// Furniture
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entityId);
if (furniture != null) {
user.entityPacketHandlers().computeIfAbsent(entityId, k -> new FurniturePacketHandler(furniture.fakeEntityIds()));
user.sendPacket(furniture.spawnPacket((Player) user.platformPlayer()), false);
if (Config.hideBaseEntity() && !furniture.hasExternalModel()) {
event.setCancelled(true);
}
}
} else if (entityType == BukkitFurnitureManager.NMS_COLLISION_ENTITY_TYPE) {
// Cancel collider entity packet
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entityId);
if (furniture != null) {
event.setCancelled(true);
user.entityPacketHandlers().put(entityId, FurnitureCollisionPacketHandler.INSTANCE);
}
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundAddEntityPacket", e);
}
};
// 1.21.2+
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> SYNC_ENTITY_POSITION = (user, event, packet) -> {
try {
@@ -2110,7 +2122,6 @@ public class PacketConsumers {
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> SET_CREATIVE_MODE_SLOT = (user, event) -> {
try {
if (!(user instanceof BukkitServerPlayer serverPlayer)) return;
FriendlyByteBuf buf = event.getBuffer();
Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
short slotNum = buf.readShort();
@@ -2136,7 +2147,6 @@ public class PacketConsumers {
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> CONTAINER_CLICK_1_20 = (user, event) -> {
try {
if (VersionHelper.isOrAbove1_21_5()) return; // 1.21.5+需要其他办法解决同步问题
if (!(user instanceof BukkitServerPlayer serverPlayer)) return;
FriendlyByteBuf buf = event.getBuffer();
boolean changed = false;
Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);

View File

@@ -302,7 +302,7 @@ public class BukkitServerPlayer extends Player {
dataPayload = Reflections.constructor$DiscardedPayload.newInstance(channelKey, Unpooled.wrappedBuffer(data));
}
Object responsePacket = Reflections.constructor$ClientboundCustomPayloadPacket.newInstance(dataPayload);
this.sendPacket(responsePacket, true);
this.nettyChannel().writeAndFlush(responsePacket, true);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to send custom payload to " + name(), e);
}
@@ -313,7 +313,7 @@ public class BukkitServerPlayer extends Player {
try {
Object reason = ComponentUtils.adventureToMinecraft(message);
Object kickPacket = Reflections.constructor$ClientboundDisconnectPacket.newInstance(reason);
this.sendPacket(kickPacket, true);
this.nettyChannel().writeAndFlush(kickPacket, true);
this.nettyChannel().disconnect();
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to kick " + name(), e);

View File

@@ -6485,6 +6485,8 @@ public class Reflections {
ReflectionUtils.getMethod(clazz$Registry, int.class, Object.class)
);
public static final int instance$EntityType$OAK_BOAT$registryId;
public static final int instance$EntityType$INTERACTION$registryId;
public static final int instance$EntityType$BLOCK_DISPLAY$registryId;
public static final int instance$EntityType$ITEM_DISPLAY$registryId;
public static final int instance$EntityType$TEXT_DISPLAY$registryId;
@@ -6507,6 +6509,8 @@ public class Reflections {
static {
try {
instance$EntityType$OAK_BOAT$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$OAK_BOAT);
instance$EntityType$INTERACTION$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$INTERACTION);
instance$EntityType$BLOCK_DISPLAY$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$BLOCK_DISPLAY);
instance$EntityType$ITEM_DISPLAY$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$ITEM_DISPLAY);
instance$EntityType$TEXT_DISPLAY$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$TEXT_DISPLAY);

View File

@@ -0,0 +1,15 @@
package net.momirealms.craftengine.core.util;
public final class ExceptionUtils {
private ExceptionUtils() {}
public static boolean hasException(Throwable t, Exception e) {
while (t != null) {
if (t == e) {
return true;
}
t = t.getCause();
}
return false;
}
}