Cleanup MultiBlockChangePacket

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2021-09-14 08:14:14 +02:00
parent 2d3daf2504
commit 7737d0e5b3
2 changed files with 43 additions and 82 deletions

View File

@ -1,93 +1,83 @@
package net.minestom.server.network.packet.server.play;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.block.Block;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.binary.Writeable;
import org.jetbrains.annotations.NotNull;
public class MultiBlockChangePacket implements ServerPacket {
public int chunkX;
public int chunkZ;
public int section;
//TODO this is important prob if we add a light api
public boolean suppressLightUpdates = true;
public BlockChange[] blockChanges = new BlockChange[0];
public BlockEntry[] blockChanges = new BlockEntry[0];
public MultiBlockChangePacket() {
}
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeLong(ChunkUtils.getChunkIndexWithSection(chunkX, chunkZ, section));
writer.writeLong(((long) (chunkX & 0x3FFFFF) << 42) | (section & 0xFFFFF) | ((long) (chunkZ & 0x3FFFFF) << 20));
writer.writeBoolean(suppressLightUpdates);
if (blockChanges != null) {
final int length = blockChanges.length;
writer.writeVarInt(length);
for (final BlockChange blockChange : blockChanges) {
writer.writeVarLong((long) blockChange.newBlockId << 12 | getLocalBlockPosAsShort(blockChange.positionX, blockChange.positionY, blockChange.positionZ));
}
} else {
writer.writeVarInt(0);
}
writer.writeArray(blockChanges);
}
@Override
public void read(@NotNull BinaryReader reader) {
long chunkIndexWithSection = reader.readLong();
chunkX = ChunkUtils.getChunkXFromChunkIndexWithSection(chunkIndexWithSection);
chunkZ = ChunkUtils.getChunkZFromChunkIndexWithSection(chunkIndexWithSection);
section = ChunkUtils.getSectionFromChunkIndexWithSection(chunkIndexWithSection);
final long chunkIndexWithSection = reader.readLong();
this.chunkX = (int) ((chunkIndexWithSection >> 42) & 4194303L);
this.chunkZ = (int) ((chunkIndexWithSection >> 20) & 4194303L);
this.section = (int) (chunkIndexWithSection & 1048575L);
suppressLightUpdates = reader.readBoolean();
this.suppressLightUpdates = reader.readBoolean();
int blockChangeCount = reader.readVarInt();
blockChanges = new BlockChange[blockChangeCount];
final int blockChangeCount = reader.readVarInt();
this.blockChanges = new BlockEntry[blockChangeCount];
for (int i = 0; i < blockChangeCount; i++) {
BlockChange change = new BlockChange();
long encodedChange = reader.readVarLong();
short localPos = (short) (encodedChange & 0x0F_FF);
change.positionX = getXFromLocalBlockPosAsShort(localPos);
change.positionY = getYFromLocalBlockPosAsShort(localPos);
change.positionZ = getZFromLocalBlockPosAsShort(localPos);
change.newBlockId = (int) (encodedChange >> 12);
blockChanges[i] = change;
final long encodedChange = reader.readVarLong();
final short localPos = (short) (encodedChange & 0x0F_FF);
final int x = (localPos >> 8) % Chunk.CHUNK_SIZE_X;
final int y = localPos & 0xF;
final int z = (localPos >> 4) % Chunk.CHUNK_SIZE_Z;
final Block block = Block.fromStateId((short) (encodedChange >> 12));
blockChanges[i] = new BlockEntry(new Vec(x, y, z), block);
}
}
public static short getLocalBlockPosAsShort(int x, int y, int z) {
x = x % Chunk.CHUNK_SIZE_X;
y = y % 16;
z = z % Chunk.CHUNK_SIZE_Z;
return (short) (x << 8 | z << 4 | y);
}
public static int getXFromLocalBlockPosAsShort(short localPos) {
return (localPos >> 8) % Chunk.CHUNK_SIZE_X;
}
public static int getZFromLocalBlockPosAsShort(short localPos) {
return (localPos >> 4) % Chunk.CHUNK_SIZE_Z;
}
public static int getYFromLocalBlockPosAsShort(short localPos) {
return localPos & 0xF;
}
@Override
public int getId() {
return ServerPacketIdentifier.MULTI_BLOCK_CHANGE;
}
public static class BlockChange {
public int positionX;
public int positionY;
public int positionZ;
public int newBlockId;
public static final class BlockEntry implements Writeable {
private final Vec chunkPosition;
public final Block block;
public BlockEntry(Vec chunkPosition, Block block) {
this.chunkPosition = chunkPosition;
this.block = block;
}
public Vec chunkPosition() {
return chunkPosition;
}
public Block block() {
return block;
}
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeVarLong((long) block.stateId() << 12 |
((long) chunkPosition.blockX() << 8 |
(long) chunkPosition.blockZ() << 4 |
chunkPosition.blockY()));
}
}
}

View File

@ -115,14 +115,6 @@ public final class ChunkUtils {
return getChunkIndex(chunk.getChunkX(), chunk.getChunkZ());
}
public static long getChunkIndexWithSection(int chunkX, int chunkZ, int section) {
long l = 0L;
l |= ((long) chunkX & 4194303L) << 42;
l |= ((long) section & 1048575L);
l |= ((long) chunkZ & 4194303L) << 20;
return l;
}
/**
* Converts a chunk index to its chunk X position.
*
@ -231,25 +223,4 @@ public final class ChunkUtils {
public static int blockIndexToChunkPositionZ(int index) {
return (index >> 28) & 0xF; // 28-32 bits
}
/**
* Returns the section, from a chunk index encoded with {@link #getChunkIndexWithSection(int, int, int)}
*/
public static int getSectionFromChunkIndexWithSection(long index) {
return (int) (index & 1048575L);
}
/**
* Returns the chunk X, from a chunk index encoded with {@link #getChunkIndexWithSection(int, int, int)}
*/
public static int getChunkXFromChunkIndexWithSection(long index) {
return (int) ((index >> 42) & 4194303L);
}
/**
* Returns the chunk Z, from a chunk index encoded with {@link #getChunkIndexWithSection(int, int, int)}
*/
public static int getChunkZFromChunkIndexWithSection(long index) {
return (int) ((index >> 20) & 4194303L);
}
}