Keep hidden block entities in chunks without their data
Hidden block entities were removed from chunk data, so the client did not render blocks like shulker boxes at all. They are now sent with empty data, hiding their contents but not the block itself.
This commit is contained in:
@@ -23,6 +23,7 @@ import de.steamwar.core.ProtocolUtils;
|
||||
import de.steamwar.techhider.AccessPrivilegeProvider.ForPlayer;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData;
|
||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
||||
import net.minecraft.util.SimpleBitStorage;
|
||||
@@ -31,6 +32,7 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.UnaryOperator;
|
||||
@@ -263,21 +265,30 @@ public class ChunkHider {
|
||||
private List<ClientboundLevelChunkPacketData.BlockEntityInfo> filterBlockEntities(ForPlayer access, List<ClientboundLevelChunkPacketData.BlockEntityInfo> blockEntities, int chunkX, int chunkZ) {
|
||||
int fourBitBitmask = 0b0000_1111;
|
||||
|
||||
return blockEntities.stream()
|
||||
.filter((blockEntityInfo) -> {
|
||||
BlockEntityType<?> type = blockEntityInfo.type;
|
||||
int packedXZ = blockEntityInfo.packedXZ;
|
||||
List<ClientboundLevelChunkPacketData.BlockEntityInfo> filtered = new ArrayList<>(blockEntities.size());
|
||||
for (ClientboundLevelChunkPacketData.BlockEntityInfo blockEntityInfo : blockEntities) {
|
||||
BlockEntityType<?> type = blockEntityInfo.type;
|
||||
int packedXZ = blockEntityInfo.packedXZ;
|
||||
|
||||
int localX = (packedXZ >> 4) & fourBitBitmask;
|
||||
int localZ = packedXZ & fourBitBitmask;
|
||||
int localX = (packedXZ >> 4) & fourBitBitmask;
|
||||
int localZ = packedXZ & fourBitBitmask;
|
||||
|
||||
int worldX = (chunkX * SECTION_SPAN_SIZE) + localX;
|
||||
int worldZ = (chunkZ * SECTION_SPAN_SIZE) + localZ;
|
||||
int worldX = (chunkX * SECTION_SPAN_SIZE) + localX;
|
||||
int worldZ = (chunkZ * SECTION_SPAN_SIZE) + localZ;
|
||||
|
||||
int worldY = blockEntityInfo.y;
|
||||
int worldY = blockEntityInfo.y;
|
||||
|
||||
return access.canAccessPosition(worldX, worldY, worldZ) && access.canAccessBlockEntity(worldX, worldY, worldZ, type);
|
||||
}).toList();
|
||||
// A hidden position is obfuscated as a whole
|
||||
if (!access.canAccessPosition(worldX, worldY, worldZ)) continue;
|
||||
|
||||
if (access.canAccessBlockEntity(worldX, worldY, worldZ, type)) {
|
||||
filtered.add(blockEntityInfo);
|
||||
} else {
|
||||
// Without its block entity, the client would not render blocks like shulker boxes, so only their data is hidden
|
||||
filtered.add(new ClientboundLevelChunkPacketData.BlockEntityInfo(packedXZ, worldY, type, new CompoundTag()));
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
|
||||
private void copyOverSectionBiomeData(ByteBuf oldData, ByteBuf newData) {
|
||||
|
||||
@@ -25,3 +25,4 @@ accessible class net/minecraft/network/protocol/game/ClientboundLevelChunkPacket
|
||||
accessible field net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData$BlockEntityInfo type Lnet/minecraft/world/level/block/entity/BlockEntityType;
|
||||
accessible field net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData$BlockEntityInfo packedXZ I
|
||||
accessible field net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData$BlockEntityInfo y I
|
||||
accessible method net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData$BlockEntityInfo <init> (IILnet/minecraft/world/level/block/entity/BlockEntityType;Lnet/minecraft/nbt/CompoundTag;)V
|
||||
|
||||
Reference in New Issue
Block a user