Skip to content

Commit b1037d4

Browse files
committed
Support persistent chunk sections for client caching
1 parent 0272ca7 commit b1037d4

3 files changed

Lines changed: 33 additions & 18 deletions

File tree

core/src/main/java/org/geysermc/geyser/level/chunk/BlockStorage.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,18 @@
2626
package org.geysermc.geyser.level.chunk;
2727

2828
import io.netty.buffer.ByteBuf;
29+
import io.netty.buffer.ByteBufOutputStream;
2930
import it.unimi.dsi.fastutil.ints.IntArrayList;
3031
import it.unimi.dsi.fastutil.ints.IntList;
3132
import lombok.Getter;
33+
import org.cloudburstmc.nbt.NBTOutputStream;
34+
import org.cloudburstmc.nbt.NbtUtils;
3235
import org.cloudburstmc.protocol.common.util.VarInts;
3336
import org.geysermc.geyser.level.chunk.bitarray.BitArray;
3437
import org.geysermc.geyser.level.chunk.bitarray.BitArrayVersion;
38+
import org.geysermc.geyser.registry.type.BlockMappings;
3539

40+
import java.io.IOException;
3641
import java.util.function.IntConsumer;
3742

3843
@Getter
@@ -82,6 +87,20 @@ public void writeToNetwork(ByteBuf buffer) {
8287
palette.forEach((IntConsumer) id -> VarInts.writeInt(buffer, id));
8388
}
8489

90+
public void writeToNetwork(ByteBuf buffer, BlockMappings blockMappings) throws IOException {
91+
buffer.writeByte(getPaletteHeader(bitArray.getVersion(), false));
92+
93+
for (int word : bitArray.getWords()) {
94+
buffer.writeIntLE(word);
95+
}
96+
97+
bitArray.writeSizeToNetwork(buffer, palette.size());
98+
NBTOutputStream nbtStream = NbtUtils.createNetworkWriter(new ByteBufOutputStream(buffer));
99+
for (int id : palette) {
100+
nbtStream.writeTag(blockMappings.getDefinition(id));
101+
}
102+
}
103+
85104
public int estimateNetworkSize() {
86105
int size = 1; // Palette header
87106
size += this.bitArray.getWords().length * 4;
@@ -134,4 +153,4 @@ public boolean isEmpty() {
134153
public BlockStorage copy() {
135154
return new BlockStorage(this.bitArray.copy(), new IntArrayList(this.palette));
136155
}
137-
}
156+
}

core/src/main/java/org/geysermc/geyser/level/chunk/GeyserChunkSection.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727

2828
import io.netty.buffer.ByteBuf;
2929
import org.cloudburstmc.protocol.common.util.Preconditions;
30+
import org.geysermc.geyser.registry.type.BlockMappings;
31+
32+
import java.io.IOException;
3033

3134
public class GeyserChunkSection {
3235

@@ -68,6 +71,16 @@ public void writeToNetwork(ByteBuf buffer) {
6871
}
6972
}
7073

74+
public void writeToNetwork(ByteBuf buffer, BlockMappings blockMappings) throws IOException {
75+
buffer.writeByte(CHUNK_SECTION_VERSION);
76+
buffer.writeByte(this.storage.length);
77+
// Required for chunk version 9+
78+
buffer.writeByte(this.subChunkIndex);
79+
for (BlockStorage blockStorage : this.storage) {
80+
blockStorage.writeToNetwork(buffer, blockMappings);
81+
}
82+
}
83+
7184
public int estimateNetworkSize() {
7285
int size = 2; // Version + storage count
7386
for (BlockStorage blockStorage : this.storage) {

core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import org.geysermc.geyser.level.block.Blocks;
4242
import org.geysermc.geyser.level.block.type.BlockState;
4343
import org.geysermc.geyser.level.chunk.BlockStorage;
44-
import org.geysermc.geyser.level.chunk.GeyserChunkSection;
4544
import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray;
4645
import org.geysermc.geyser.session.GeyserSession;
4746
import org.geysermc.geyser.session.cache.registry.JavaRegistries;
@@ -56,28 +55,12 @@ public class ChunkUtils {
5655

5756
public static final byte[] EMPTY_BIOME_DATA;
5857
public static final BlockStorage[] EMPTY_BLOCK_STORAGE;
59-
public static final int EMPTY_CHUNK_SECTION_SIZE;
6058
private static final ConcurrentHashMap<Integer, byte[]> EMPTY_CHUNK_PAYLOAD_CACHE = new ConcurrentHashMap<>(3);
6159

6260
static {
6361
EMPTY_BLOCK_STORAGE = new BlockStorage[0];
6462

6563
ByteBuf byteBuf = Unpooled.buffer();
66-
try {
67-
new GeyserChunkSection(EMPTY_BLOCK_STORAGE, 0)
68-
.writeToNetwork(byteBuf);
69-
70-
byte[] emptyChunkData = new byte[byteBuf.readableBytes()];
71-
byteBuf.readBytes(emptyChunkData);
72-
73-
EMPTY_CHUNK_SECTION_SIZE = emptyChunkData.length;
74-
75-
emptyChunkData = null;
76-
} finally {
77-
byteBuf.release();
78-
}
79-
80-
byteBuf = Unpooled.buffer();
8164
try {
8265
BlockStorage blockStorage = new BlockStorage(SingletonBitArray.INSTANCE, IntLists.singleton(0));
8366
blockStorage.writeToNetwork(byteBuf);

0 commit comments

Comments
 (0)