Skip to content

Commit

Permalink
Remove invalid chunk entities for 1.20.5 clients
Browse files Browse the repository at this point in the history
Fixes #3804
  • Loading branch information
kennytv committed May 14, 2024
1 parent 7e268a6 commit 2d41eb5
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
Expand Down Expand Up @@ -137,10 +139,27 @@ public void registerPackets() {
blockRewriter.registerBlockChange(ClientboundPackets1_20_3.BLOCK_CHANGE);
blockRewriter.registerVarLongMultiBlockChange1_20(ClientboundPackets1_20_3.MULTI_BLOCK_CHANGE);
blockRewriter.registerEffect(ClientboundPackets1_20_3.EFFECT, 1010, 2001);
blockRewriter.registerChunkData1_19(ClientboundPackets1_20_3.CHUNK_DATA, ChunkType1_20_2::new, (user, blockEntity) -> updateBlockEntityTag(user, null, blockEntity.tag()));
protocol.registerClientbound(ClientboundPackets1_20_3.CHUNK_DATA, wrapper -> {
final Chunk chunk = blockRewriter.handleChunk1_19(wrapper, ChunkType1_20_2::new);
for (int i = 0; i < chunk.blockEntities().size(); i++) {
final BlockEntity blockEntity = chunk.blockEntities().get(i);
if (isUnknownBlockEntity(blockEntity.typeId())) {
// The client no longer ignores unknown block entities
chunk.blockEntities().remove(i--);
continue;
}

updateBlockEntityTag(wrapper.user(), null, blockEntity.tag());
}
});
protocol.registerClientbound(ClientboundPackets1_20_3.BLOCK_ENTITY_DATA, wrapper -> {
wrapper.passthrough(Type.POSITION1_14); // Position
wrapper.passthrough(Type.VAR_INT); // Block entity type

final int typeId = wrapper.passthrough(Type.VAR_INT);
if (isUnknownBlockEntity(typeId)) {
wrapper.cancel();
return;
}

CompoundTag tag = wrapper.read(Type.COMPOUND_TAG);
if (tag != null) {
Expand Down Expand Up @@ -1346,6 +1365,10 @@ private void addBlockEntityId(final CompoundTag tag, final String id) {
}
}

private boolean isUnknownBlockEntity(final int id) {
return id < 0 || id > 42;
}

private void updateBlockEntityTag(final UserConnection connection, @Nullable final StructuredDataContainer data, final CompoundTag tag) {
if (tag == null) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
Expand Down Expand Up @@ -186,28 +187,18 @@ public void registerChunkData1_19(C packetType, ChunkTypeSupplier chunkTypeSuppl

public PacketHandler chunkDataHandler1_19(ChunkTypeSupplier chunkTypeSupplier, @Nullable BiConsumer<UserConnection, BlockEntity> blockEntityHandler) {
return wrapper -> {
final EntityTracker tracker = protocol.getEntityRewriter().tracker(wrapper.user());
Preconditions.checkArgument(tracker.biomesSent() != -1, "Biome count not set");
Preconditions.checkArgument(tracker.currentWorldSectionHeight() != -1, "Section height not set");
final Type<Chunk> chunkType = chunkTypeSupplier.supply(tracker.currentWorldSectionHeight(),
MathUtil.ceilLog2(protocol.getMappingData().getBlockStateMappings().mappedSize()),
MathUtil.ceilLog2(tracker.biomesSent()));
final Chunk chunk = wrapper.passthrough(chunkType);
for (final ChunkSection section : chunk.getSections()) {
final DataPalette blockPalette = section.palette(PaletteType.BLOCKS);
for (int i = 0; i < blockPalette.size(); i++) {
final int id = blockPalette.idByIndex(i);
blockPalette.setIdByIndex(i, protocol.getMappingData().getNewBlockStateId(id));
}
}

final Chunk chunk = handleChunk1_19(wrapper, chunkTypeSupplier);
final Mappings blockEntityMappings = protocol.getMappingData().getBlockEntityMappings();
if (blockEntityMappings != null || blockEntityHandler != null) {
List<BlockEntity> blockEntities = chunk.blockEntities();
final List<BlockEntity> blockEntities = chunk.blockEntities();
for (int i = 0; i < blockEntities.size(); i++) {
final BlockEntity blockEntity = blockEntities.get(i);
if (blockEntityMappings != null) {
blockEntities.set(i, blockEntity.withTypeId(blockEntityMappings.getNewIdOrDefault(blockEntity.typeId(), blockEntity.typeId())));
final int id = blockEntity.typeId();
final int mappedId = blockEntityMappings.getNewIdOrDefault(id, id);
if (id != mappedId) {
blockEntities.set(i, blockEntity.withTypeId(mappedId));
}
}

if (blockEntityHandler != null && blockEntity.tag() != null) {
Expand All @@ -218,6 +209,24 @@ public PacketHandler chunkDataHandler1_19(ChunkTypeSupplier chunkTypeSupplier, @
};
}

public Chunk handleChunk1_19(PacketWrapper wrapper, ChunkTypeSupplier chunkTypeSupplier) throws Exception {
final EntityTracker tracker = protocol.getEntityRewriter().tracker(wrapper.user());
Preconditions.checkArgument(tracker.biomesSent() != -1, "Biome count not set");
Preconditions.checkArgument(tracker.currentWorldSectionHeight() != -1, "Section height not set");
final Type<Chunk> chunkType = chunkTypeSupplier.supply(tracker.currentWorldSectionHeight(),
MathUtil.ceilLog2(protocol.getMappingData().getBlockStateMappings().mappedSize()),
MathUtil.ceilLog2(tracker.biomesSent()));
final Chunk chunk = wrapper.passthrough(chunkType);
for (final ChunkSection section : chunk.getSections()) {
final DataPalette blockPalette = section.palette(PaletteType.BLOCKS);
for (int i = 0; i < blockPalette.size(); i++) {
final int id = blockPalette.idByIndex(i);
blockPalette.setIdByIndex(i, protocol.getMappingData().getNewBlockStateId(id));
}
}
return chunk;
}

public void registerBlockEntityData(C packetType) {
registerBlockEntityData(packetType, null);
}
Expand Down

0 comments on commit 2d41eb5

Please sign in to comment.