minecraft-src/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
2025-07-04 01:41:11 +03:00

85 lines
3 KiB
Java

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<ClientGamePacketListener> {
public static final StreamCodec<FriendlyByteBuf, ClientboundSectionBlocksUpdatePacket> 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<ClientboundSectionBlocksUpdatePacket> 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<BlockPos, BlockState> 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]);
}
}
}