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

perf(network): 优化数据包的处理逻辑

This commit is contained in:
jhqwqmc
2025-03-24 17:34:00 +08:00
parent 1d40e29991
commit ebf0cd4dea

View File

@@ -55,44 +55,73 @@ public class PacketConsumers {
BIOME_LIST = new IntIdentityList(RegistryUtils.currentBiomeRegistrySize());
}
public static int remap(int stateId, NetWorkUser user) {
int remapId = mappings[stateId];
if (remapId == stateId) return stateId;
if (user.usingClientMod() && !BlockStateUtils.isVanillaBlock(stateId)) return stateId;
return remapId;
public static int remap(int stateId) {
return mappings[stateId];
}
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> LEVEL_CHUNK_WITH_LIGHT = (user, event, packet) -> {
try {
BukkitServerPlayer player = (BukkitServerPlayer) user;
Object chunkData = Reflections.field$ClientboundLevelChunkWithLightPacket$chunkData.get(packet);
byte[] buffer = (byte[]) Reflections.field$ClientboundLevelChunkPacketData$buffer.get(chunkData);
ByteBuf buf = Unpooled.copiedBuffer(buffer);
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(buf);
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(stateId -> remap(stateId, user));
} else {
for (int j = 0; j < 4096; j ++) {
int state = container.get(j);
int newState = remap(state, user);
if (newState != state) {
container.set(j, newState);
if (!user.usingClientMod()) {
BukkitServerPlayer player = (BukkitServerPlayer) user;
Object chunkData = Reflections.field$ClientboundLevelChunkWithLightPacket$chunkData.get(packet);
byte[] buffer = (byte[]) Reflections.field$ClientboundLevelChunkPacketData$buffer.get(chunkData);
ByteBuf buf = Unpooled.copiedBuffer(buffer);
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(buf);
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;
}
mcSection.writePacket(newBuf);
} catch (Exception e) {
break;
}
Reflections.field$ClientboundLevelChunkPacketData$buffer.set(chunkData, newBuf.array());
} else {
BukkitServerPlayer player = (BukkitServerPlayer) user;
Object chunkData = Reflections.field$ClientboundLevelChunkWithLightPacket$chunkData.get(packet);
byte[] buffer = (byte[]) Reflections.field$ClientboundLevelChunkPacketData$buffer.get(chunkData);
ByteBuf buf = Unpooled.copiedBuffer(buffer);
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(buf);
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(state -> BlockStateUtils.isVanillaBlock(state) ? remap(state) : state);
} else {
for (int j = 0; j < 4096; j++) {
int state = container.get(j);
int newState = BlockStateUtils.isVanillaBlock(state) ? remap(state) : state;
if (newState != state) {
container.set(j, newState);
}
}
}
mcSection.writePacket(newBuf);
} catch (Exception e) {
break;
}
}
Reflections.field$ClientboundLevelChunkPacketData$buffer.set(chunkData, newBuf.array());
}
Reflections.field$ClientboundLevelChunkPacketData$buffer.set(chunkData, newBuf.array());
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundLevelChunkWithLightPacket", e);
}
@@ -100,24 +129,46 @@ public class PacketConsumers {
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> SECTION_BLOCK_UPDATE = (user, event) -> {
try {
FriendlyByteBuf buf = event.getBuffer();
long pos = buf.readLong();
int blocks = buf.readVarInt();
short[] positions = new short[blocks];
int[] states = new int[blocks];
for (int i = 0; i < blocks; i++) {
long k = buf.readVarLong();
positions[i] = (short) ((int) (k & 4095L));
states[i] = remap((int) (k >>> 12), user);
if (!user.usingClientMod()) {
FriendlyByteBuf buf = event.getBuffer();
long pos = buf.readLong();
int blocks = buf.readVarInt();
short[] positions = new short[blocks];
int[] states = new int[blocks];
for (int i = 0; i < blocks; i++) {
long k = buf.readVarLong();
positions[i] = (short) ((int) (k & 4095L));
states[i] = remap((int) (k >>> 12));
}
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeLong(pos);
buf.writeVarInt(blocks);
for (int i = 0; i < blocks; i++) {
buf.writeVarLong((long) states[i] << 12 | positions[i]);
}
event.setChanged(true);
} else {
FriendlyByteBuf buf = event.getBuffer();
long pos = buf.readLong();
int blocks = buf.readVarInt();
short[] positions = new short[blocks];
int[] states = new int[blocks];
for (int i = 0; i < blocks; i++) {
long k = buf.readVarLong();
positions[i] = (short) ((int) (k & 4095L));
int stateId = (int) (k >>> 12);
states[i] = BlockStateUtils.isVanillaBlock(stateId) ? remap(stateId) : stateId;
}
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeLong(pos);
buf.writeVarInt(blocks);
for (int i = 0; i < blocks; i++) {
buf.writeVarLong((long) states[i] << 12 | positions[i]);
}
event.setChanged(true);
}
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeLong(pos);
buf.writeVarInt(blocks);
for (int i = 0; i < blocks; i ++) {
buf.writeVarLong((long) states[i] << 12 | positions[i]);
}
event.setChanged(true);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundSectionBlocksUpdatePacket", e);
}
@@ -128,7 +179,10 @@ public class PacketConsumers {
FriendlyByteBuf buf = event.getBuffer();
BlockPos pos = buf.readBlockPos(buf);
int before = buf.readVarInt();
int state = remap(before, user);
if (user.usingClientMod() && !BlockStateUtils.isVanillaBlock(before)) {
return;
}
int state = remap(before);
if (state == before) {
return;
}
@@ -150,7 +204,7 @@ public class PacketConsumers {
BlockPos blockPos = buf.readBlockPos(buf);
int state = buf.readInt();
boolean global = buf.readBoolean();
int newState = remap(state, user);
int newState = remap(state);
if (newState == state) {
return;
}
@@ -184,7 +238,7 @@ public class PacketConsumers {
if (!Reflections.clazz$BlockParticleOption.isInstance(option)) return;
Object blockState = Reflections.field$BlockParticleOption$blockState.get(option);
int id = BlockStateUtils.blockStateToId(blockState);
int remapped = remap(id, user);
int remapped = remap(id);
if (remapped == id) return;
Reflections.field$BlockParticleOption$blockState.set(option, BlockStateUtils.idToBlockState(remapped));
event.setChanged(true);
@@ -526,7 +580,7 @@ public class PacketConsumers {
// Falling blocks
if (entityType == Reflections.instance$EntityType$FALLING_BLOCK) {
int data = Reflections.field$ClientboundAddEntityPacket$data.getInt(packet);
int remapped = remap(data, user);
int remapped = remap(data);
if (remapped != data) {
Reflections.field$ClientboundAddEntityPacket$data.set(packet, remapped);
}