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

修复区块包

This commit is contained in:
XiaoMoMi
2025-04-26 16:36:29 +08:00
parent f929ac1e3b
commit 4da72b140f
4 changed files with 27 additions and 78 deletions

View File

@@ -91,7 +91,7 @@ Given the extensive and intricate nature of plugin configurations, a modular tem
The plugin enables model inheritance and texture overrides through configuration, while supporting [all item models](https://misode.github.io/assets/item/) from version 1.21.4 onward. It incorporates a version migration system that automatically downgrades 1.21.4+ item models to legacy formats with maximum backward compatibility.
### Breaking Changes You Have to Know & Possible Incompatibility with Other Plugins
- CraftEngine injects into PalettedContainer to ensure efficient storage and synchronization of plugin block data. This may cause conflicts with some other plugins that modify the palette. When analyzing server performance using Spark, palette operation overhead will be attributed to the CraftEngine plugin in the profiling results..
- CraftEngine injects into PalettedContainer to ensure efficient storage and synchronization of plugin block data. This may cause conflicts with some other plugins that modify the palette. When analyzing server performance using Spark, palette operation overhead will be attributed to the CraftEngine plugin in the profiling results.
- CraftEngine injects into FurnaceBlockEntity to modify its recipe fetching logic.
- CraftEngine uses real server-side blocks, any plugin relying on Bukkit's Material class will fail to correctly identify custom block types. The proper approach is to use alternatives like BlockState#getBlock (mojmap) instead of the Material class.
- CraftEngine implements 0-tick collision entities by extending certain Minecraft entities, ensuring hard collision works correctly on the server side (e.g., making a pig stand on a chair). However, some anti-cheat plugins do not check entity AABB (Axis-Aligned Bounding Box) properly when detecting player movement, which may lead to false flags.

View File

@@ -124,7 +124,7 @@ public final class CraftEngineBlocks {
}
/**
* Removes a block from the world if it's a custom one
* Removes a block from the world if it's custom
*
* @param block block to remove
* @return success or not
@@ -136,7 +136,7 @@ public final class CraftEngineBlocks {
}
/**
* Removes a block from the world if it's a custom one
* Removes a block from the world if it's custom
*
* @param block block to remove
* @param applyPhysics whether to apply physics
@@ -150,7 +150,7 @@ public final class CraftEngineBlocks {
}
/**
* Removes a block from the world if it's a custom one
* Removes a block from the world if it's custom
*
* @param block block to remove
* @param player player who breaks the block
@@ -193,7 +193,7 @@ public final class CraftEngineBlocks {
}
/**
* Checks if a block is a custom one
* Checks if a block is custom
*
* @param block block
* @return is custom block or not
@@ -236,7 +236,7 @@ public final class CraftEngineBlocks {
* @return bukkit block data
*/
@NotNull
public static BlockData createBukkitBlockData(@NotNull ImmutableBlockState blockState) {
public static BlockData getBukkitBlockData(@NotNull ImmutableBlockState blockState) {
return BlockStateUtils.fromBlockData(blockState.customBlockState().handle());
}
}

View File

@@ -2,6 +2,8 @@ package net.momirealms.craftengine.bukkit.api;
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager;
import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture;
import net.momirealms.craftengine.bukkit.nms.CollisionEntity;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
@@ -122,6 +124,17 @@ public final class CraftEngineFurniture {
return furnitureId != null;
}
/**
* Check if an entity is a collision entity
*
* @param entity entity to check
* @return is collision entity or not
*/
public static boolean isCollisionEntity(@NotNull Entity entity) {
Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(entity);
return nmsEntity instanceof CollisionEntity;
}
/**
* Check if an entity is a seat
*

View File

@@ -43,6 +43,7 @@ import net.momirealms.craftengine.core.world.chunk.PalettedContainer;
import net.momirealms.craftengine.core.world.chunk.packet.BlockEntityData;
import net.momirealms.craftengine.core.world.chunk.packet.MCSection;
import net.momirealms.craftengine.core.world.collision.AABB;
import net.momirealms.sparrow.nbt.NBT;
import net.momirealms.sparrow.nbt.Tag;
import org.bukkit.*;
import org.bukkit.block.Block;
@@ -97,77 +98,11 @@ public class PacketConsumers {
try {
BukkitServerPlayer player = (BukkitServerPlayer) user;
FriendlyByteBuf buf = event.getBuffer();
// 我不明白为什么1.20~1.20.1会出问题貌似是readNbt的问题
if (!VersionHelper.isVersionNewerThan1_20_2()) {
Object packet = FastNMS.INSTANCE.constructor$ClientboundLevelChunkWithLightPacket(buf);
if (user.clientModEnabled()) {
Object chunkData = FastNMS.INSTANCE.field$ClientboundLevelChunkWithLightPacket$chunkData(packet);
byte[] buffer = FastNMS.INSTANCE.field$ClientboundLevelChunkPacketData$buffer(chunkData);
ByteBuf byteBuf = Unpooled.copiedBuffer(buffer);
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(byteBuf);
FriendlyByteBuf newBuf = new FriendlyByteBuf(Unpooled.buffer());
for (int i = 0, count = player.clientSideSectionCount(); i < count; i++) {
try {
MCSection mcSection = new MCSection(BLOCK_LIST, BIOME_LIST);
mcSection.readPacket(friendlyByteBuf);
PalettedContainer<Integer> container = mcSection.blockStateContainer();
Palette<Integer> palette = container.data().palette();
if (palette.canRemap()) {
palette.remap(PacketConsumers::remapMOD);
} else {
for (int j = 0; j < 4096; j++) {
int state = container.get(j);
int newState = remapMOD(state);
if (newState != state) {
container.set(j, newState);
}
}
}
mcSection.writePacket(newBuf);
} catch (Exception e) {
break;
}
}
Reflections.field$ClientboundLevelChunkPacketData$buffer.set(chunkData, newBuf.array());
} else {
Object chunkData = FastNMS.INSTANCE.field$ClientboundLevelChunkWithLightPacket$chunkData(packet);
byte[] buffer = FastNMS.INSTANCE.field$ClientboundLevelChunkPacketData$buffer(chunkData);
ByteBuf byteBuf = Unpooled.copiedBuffer(buffer);
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(byteBuf);
FriendlyByteBuf newBuf = new FriendlyByteBuf(Unpooled.buffer());
for (int i = 0, count = player.clientSideSectionCount(); i < count; i++) {
try {
MCSection mcSection = new MCSection(BLOCK_LIST, BIOME_LIST);
mcSection.readPacket(friendlyByteBuf);
PalettedContainer<Integer> container = mcSection.blockStateContainer();
Palette<Integer> palette = container.data().palette();
if (palette.canRemap()) {
palette.remap(PacketConsumers::remap);
} else {
for (int j = 0; j < 4096; j++) {
int state = container.get(j);
int newState = remap(state);
if (newState != state) {
container.set(j, newState);
}
}
}
mcSection.writePacket(newBuf);
} catch (Exception e) {
break;
}
}
Reflections.field$ClientboundLevelChunkPacketData$buffer.set(chunkData, newBuf.array());
}
buf.clear();
buf.writeVarInt(event.packetID());
FastNMS.INSTANCE.method$ClientboundLevelChunkWithLightPacket$write(packet, buf);
event.setChanged(true);
return;
}
// 这里是正片
int chunkX = buf.readInt();
int chunkZ = buf.readInt();
boolean named = !VersionHelper.isVersionNewerThan1_20_2();
// ClientboundLevelChunkPacketData
int heightmapsCount = 0;
Map<Integer, long[]> heightmapsMap = new HashMap<>();
@@ -180,8 +115,9 @@ public class PacketConsumers {
heightmapsMap.put(key, value);
}
} else {
heightmaps = buf.readNbt(false);
heightmaps = buf.readNbt(named);
}
int varInt = buf.readVarInt();
byte[] buffer = new byte[varInt];
buf.readBytes(buffer);
@@ -191,7 +127,7 @@ public class PacketConsumers {
byte packedXZ = buf.readByte();
short y = buf.readShort();
int type = buf.readVarInt();
Tag tag = buf.readNbt(false);
Tag tag = buf.readNbt(named);
BlockEntityData blockEntityData = new BlockEntityData(packedXZ, y, type, tag);
blockEntitiesData.add(blockEntityData);
}
@@ -269,7 +205,7 @@ public class PacketConsumers {
buf.writeLongArray(entry.getValue());
}
} else {
buf.writeNbt(heightmaps, false);
buf.writeNbt(heightmaps, named);
}
buf.writeVarInt(buffer.length);
buf.writeBytes(buffer);
@@ -278,7 +214,7 @@ public class PacketConsumers {
buf.writeByte(blockEntityData.packedXZ());
buf.writeShort(blockEntityData.y());
buf.writeVarInt(blockEntityData.type());
buf.writeNbt(blockEntityData.tag(), false);
buf.writeNbt(blockEntityData.tag(), named);
}
buf.writeBitSet(skyYMask);
buf.writeBitSet(blockYMask);