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; 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.Chunk;
import net.minestom.server.instance.block.Block;
import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; 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; import org.jetbrains.annotations.NotNull;
public class MultiBlockChangePacket implements ServerPacket { public class MultiBlockChangePacket implements ServerPacket {
public int chunkX; public int chunkX;
public int chunkZ; public int chunkZ;
public int section; public int section;
//TODO this is important prob if we add a light api //TODO this is important prob if we add a light api
public boolean suppressLightUpdates = true; public boolean suppressLightUpdates = true;
public BlockChange[] blockChanges = new BlockChange[0]; public BlockEntry[] blockChanges = new BlockEntry[0];
public MultiBlockChangePacket() { public MultiBlockChangePacket() {
} }
@Override @Override
public void write(@NotNull BinaryWriter writer) { 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); writer.writeBoolean(suppressLightUpdates);
if (blockChanges != null) { writer.writeArray(blockChanges);
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);
}
} }
@Override @Override
public void read(@NotNull BinaryReader reader) { public void read(@NotNull BinaryReader reader) {
long chunkIndexWithSection = reader.readLong(); final long chunkIndexWithSection = reader.readLong();
chunkX = ChunkUtils.getChunkXFromChunkIndexWithSection(chunkIndexWithSection); this.chunkX = (int) ((chunkIndexWithSection >> 42) & 4194303L);
chunkZ = ChunkUtils.getChunkZFromChunkIndexWithSection(chunkIndexWithSection); this.chunkZ = (int) ((chunkIndexWithSection >> 20) & 4194303L);
section = ChunkUtils.getSectionFromChunkIndexWithSection(chunkIndexWithSection); this.section = (int) (chunkIndexWithSection & 1048575L);
suppressLightUpdates = reader.readBoolean(); this.suppressLightUpdates = reader.readBoolean();
int blockChangeCount = reader.readVarInt(); final int blockChangeCount = reader.readVarInt();
blockChanges = new BlockChange[blockChangeCount]; this.blockChanges = new BlockEntry[blockChangeCount];
for (int i = 0; i < blockChangeCount; i++) { for (int i = 0; i < blockChangeCount; i++) {
BlockChange change = new BlockChange(); final long encodedChange = reader.readVarLong();
long encodedChange = reader.readVarLong(); final short localPos = (short) (encodedChange & 0x0F_FF);
short localPos = (short) (encodedChange & 0x0F_FF); final int x = (localPos >> 8) % Chunk.CHUNK_SIZE_X;
change.positionX = getXFromLocalBlockPosAsShort(localPos); final int y = localPos & 0xF;
change.positionY = getYFromLocalBlockPosAsShort(localPos); final int z = (localPos >> 4) % Chunk.CHUNK_SIZE_Z;
change.positionZ = getZFromLocalBlockPosAsShort(localPos); final Block block = Block.fromStateId((short) (encodedChange >> 12));
blockChanges[i] = new BlockEntry(new Vec(x, y, z), block);
change.newBlockId = (int) (encodedChange >> 12);
blockChanges[i] = change;
} }
} }
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 @Override
public int getId() { public int getId() {
return ServerPacketIdentifier.MULTI_BLOCK_CHANGE; return ServerPacketIdentifier.MULTI_BLOCK_CHANGE;
} }
public static class BlockChange { public static final class BlockEntry implements Writeable {
public int positionX; private final Vec chunkPosition;
public int positionY; public final Block block;
public int positionZ;
public int newBlockId;
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()); 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. * Converts a chunk index to its chunk X position.
* *
@ -231,25 +223,4 @@ public final class ChunkUtils {
public static int blockIndexToChunkPositionZ(int index) { public static int blockIndexToChunkPositionZ(int index) {
return (index >> 28) & 0xF; // 28-32 bits 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);
}
} }