package net.minecraft.network.protocol.game; import it.unimi.dsi.fastutil.shorts.ShortIterator; import it.unimi.dsi.fastutil.shorts.ShortSet; import java.util.function.BiConsumer; import net.minecraft.core.BlockPos; import net.minecraft.core.SectionPos; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.PacketType; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunkSection; public class ClientboundSectionBlocksUpdatePacket implements Packet { public static final StreamCodec STREAM_CODEC = Packet.codec( ClientboundSectionBlocksUpdatePacket::write, ClientboundSectionBlocksUpdatePacket::new ); private static final int POS_IN_SECTION_BITS = 12; private final SectionPos sectionPos; private final short[] positions; private final BlockState[] states; public ClientboundSectionBlocksUpdatePacket(SectionPos sectionPos, ShortSet positions, LevelChunkSection section) { this.sectionPos = sectionPos; int i = positions.size(); this.positions = new short[i]; this.states = new BlockState[i]; int j = 0; for (ShortIterator var6 = positions.iterator(); var6.hasNext(); j++) { short s = (Short)var6.next(); this.positions[j] = s; this.states[j] = section.getBlockState(SectionPos.sectionRelativeX(s), SectionPos.sectionRelativeY(s), SectionPos.sectionRelativeZ(s)); } } private ClientboundSectionBlocksUpdatePacket(FriendlyByteBuf buffer) { this.sectionPos = SectionPos.of(buffer.readLong()); int i = buffer.readVarInt(); this.positions = new short[i]; this.states = new BlockState[i]; for (int j = 0; j < i; j++) { long l = buffer.readVarLong(); this.positions[j] = (short)(l & 4095L); this.states[j] = Block.BLOCK_STATE_REGISTRY.byId((int)(l >>> 12)); } } /** * Writes the raw packet data to the data stream. */ private void write(FriendlyByteBuf buffer) { buffer.writeLong(this.sectionPos.asLong()); buffer.writeVarInt(this.positions.length); for (int i = 0; i < this.positions.length; i++) { buffer.writeVarLong((long)Block.getId(this.states[i]) << 12 | this.positions[i]); } } @Override public PacketType type() { return GamePacketTypes.CLIENTBOUND_SECTION_BLOCKS_UPDATE; } /** * Passes this Packet on to the NetHandler for processing. */ public void handle(ClientGamePacketListener handler) { handler.handleChunkBlocksUpdate(this); } public void runUpdates(BiConsumer consumer) { BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); for (int i = 0; i < this.positions.length; i++) { short s = this.positions[i]; mutableBlockPos.set(this.sectionPos.relativeToBlockX(s), this.sectionPos.relativeToBlockY(s), this.sectionPos.relativeToBlockZ(s)); consumer.accept(mutableBlockPos, this.states[i]); } } }