Skip to content

Commit 77f8a23

Browse files
Reintroduce custom global palette BPE for DataPalettes, but this time smarter
1 parent 96f7061 commit 77f8a23

4 files changed

Lines changed: 39 additions & 76 deletions

File tree

protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftTypes.java

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,7 +1332,7 @@ public static void writeSlotDisplay(ByteBuf buf, SlotDisplay display) {
13321332
}
13331333
}
13341334

1335-
public static DataPalette readDataPalette(ByteBuf buf, PaletteType paletteType) {
1335+
public static DataPalette readDataPalette(ByteBuf buf, PaletteType paletteType, int registrySize) {
13361336
int bitsPerEntry = buf.readByte() & 0xFF;
13371337
Palette palette = MinecraftTypes.readPalette(buf, paletteType, bitsPerEntry);
13381338
BitStorage storage;
@@ -1343,15 +1343,7 @@ public static DataPalette readDataPalette(ByteBuf buf, PaletteType paletteType)
13431343
MinecraftTypes.readFixedSizeLongArray(buf, storage.getData());
13441344
}
13451345

1346-
return new DataPalette(palette, storage, paletteType);
1347-
}
1348-
1349-
/**
1350-
* @deprecated globalPaletteBits is no longer in use, use {@link #readDataPalette(ByteBuf, PaletteType)} instead.
1351-
*/
1352-
@Deprecated(forRemoval = true)
1353-
public static DataPalette readDataPalette(ByteBuf buf, PaletteType paletteType, int globalPaletteBits) {
1354-
return MinecraftTypes.readDataPalette(buf, paletteType);
1346+
return DataPalette.create(palette, storage, paletteType, registrySize);
13551347
}
13561348

13571349
public static void writeDataPalette(ByteBuf buf, DataPalette palette) {
@@ -1388,22 +1380,14 @@ private static Palette readPalette(ByteBuf buf, PaletteType paletteType, int bit
13881380
}
13891381
}
13901382

1391-
public static ChunkSection readChunkSection(ByteBuf buf) {
1383+
public static ChunkSection readChunkSection(ByteBuf buf, int blockStateRegistrySize, int biomeRegistrySize) {
13921384
int blockCount = buf.readShort();
13931385

1394-
DataPalette chunkPalette = MinecraftTypes.readDataPalette(buf, PaletteType.CHUNK);
1395-
DataPalette biomePalette = MinecraftTypes.readDataPalette(buf, PaletteType.BIOME);
1386+
DataPalette chunkPalette = MinecraftTypes.readDataPalette(buf, PaletteType.CHUNK, blockStateRegistrySize);
1387+
DataPalette biomePalette = MinecraftTypes.readDataPalette(buf, PaletteType.BIOME, biomeRegistrySize);
13961388
return new ChunkSection(blockCount, chunkPalette, biomePalette);
13971389
}
13981390

1399-
/**
1400-
* @deprecated globalBiomePaletteBits is no longer in use, use {@link #readChunkSection(ByteBuf)} instead.
1401-
*/
1402-
@Deprecated(forRemoval = true)
1403-
public static ChunkSection readChunkSection(ByteBuf buf, int globalBiomePaletteBits) {
1404-
return MinecraftTypes.readChunkSection(buf);
1405-
}
1406-
14071391
public static void writeChunkSection(ByteBuf buf, ChunkSection section) {
14081392
buf.writeShort(section.getBlockCount());
14091393
MinecraftTypes.writeDataPalette(buf, section.getChunkData());

protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/chunk/ChunkSection.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ public class ChunkSection {
2121
@Getter
2222
private @NonNull DataPalette biomeData;
2323

24-
public ChunkSection() {
25-
this(0, DataPalette.createForChunk(), DataPalette.createForBiome());
24+
public ChunkSection(int blockStateRegistrySize, int biomeRegistrySize) {
25+
this(0, DataPalette.createForChunk(blockStateRegistrySize), DataPalette.createForBiome(biomeRegistrySize));
2626
}
2727

2828
public ChunkSection(ChunkSection original) {

protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/chunk/DataPalette.java

Lines changed: 23 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package org.geysermc.mcprotocollib.protocol.data.game.chunk;
22

3-
import lombok.AllArgsConstructor;
43
import lombok.EqualsAndHashCode;
54
import lombok.Getter;
65
import lombok.NonNull;
7-
import lombok.Setter;
86
import lombok.ToString;
97
import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.GlobalPalette;
108
import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.ListPalette;
@@ -14,72 +12,44 @@
1412
import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.SingletonPalette;
1513

1614
@Getter
17-
@Setter
18-
@AllArgsConstructor
1915
@EqualsAndHashCode
2016
@ToString
2117
public class DataPalette {
22-
23-
/*
24-
* @deprecated globalPaletteBits is no longer in use.
25-
*/
26-
@Deprecated(forRemoval = true)
27-
public static final int GLOBAL_PALETTE_BITS_PER_ENTRY = 14;
18+
private static final double LOG_2 = Math.log(2.0);
2819

2920
private @NonNull Palette palette;
3021
private BitStorage storage;
3122
private final PaletteType paletteType;
23+
private final int globalPaletteBitsPerEntry;
3224

33-
/*
34-
* @deprecated globalPaletteBits is no longer in use, use {@link #DataPalette(Palette, BitStorage, PaletteType)} instead.
35-
*/
36-
@Deprecated(forRemoval = true)
37-
public DataPalette(@NonNull Palette palette, BitStorage storage, PaletteType paletteType, int globalPaletteBits) {
38-
this(palette, storage, paletteType);
25+
private DataPalette(@NonNull Palette palette, BitStorage storage, PaletteType paletteType, int globalPaletteBitsPerEntry) {
26+
this.palette = palette;
27+
this.storage = storage;
28+
this.paletteType = paletteType;
29+
this.globalPaletteBitsPerEntry = globalPaletteBitsPerEntry;
3930
}
4031

4132
public DataPalette(DataPalette original) {
42-
this(original.palette.copy(), original.storage == null ? null : new BitStorage(original.storage), original.paletteType);
33+
this(original.palette.copy(), original.storage == null ? null : new BitStorage(original.storage), original.paletteType, original.globalPaletteBitsPerEntry);
4334
}
4435

45-
public static DataPalette createForChunk() {
46-
return createEmpty(PaletteType.CHUNK);
36+
public static DataPalette createForChunk(int blockStateRegistrySize) {
37+
return createEmpty(PaletteType.CHUNK, blockStateRegistrySize);
4738
}
4839

49-
/*
50-
* @deprecated globalPaletteBits is no longer in use, use {@link #createForChunk()} instead.
51-
*/
52-
@Deprecated(forRemoval = true)
53-
public static DataPalette createForChunk(int globalPaletteBits) {
54-
return createForChunk();
55-
}
56-
57-
/*
58-
* @deprecated globalPaletteBits is no longer in use, use {@link #createForBiome()} instead.
59-
*/
60-
@Deprecated(forRemoval = true)
61-
public static DataPalette createForBiome(int globalPaletteBits) {
62-
return createForBiome();
40+
public static DataPalette createForBiome(int biomeRegistrySize) {
41+
return createEmpty(PaletteType.BIOME, biomeRegistrySize);
6342
}
6443

65-
public static DataPalette createForBiome() {
66-
return createEmpty(PaletteType.BIOME);
44+
public static DataPalette createEmpty(PaletteType paletteType, int registrySize) {
45+
return create(new ListPalette(paletteType.getMinBitsPerEntry()),
46+
new BitStorage(paletteType.getMinBitsPerEntry(), paletteType.getStorageSize()), paletteType, registrySize);
6747
}
6848

69-
public static DataPalette createEmpty(PaletteType paletteType) {
70-
return new DataPalette(new ListPalette(paletteType.getMinBitsPerEntry()),
71-
new BitStorage(paletteType.getMinBitsPerEntry(), paletteType.getStorageSize()), paletteType);
49+
public static DataPalette create(@NonNull Palette palette, BitStorage storage, PaletteType paletteType, int registrySize) {
50+
return new DataPalette(palette, storage, paletteType, calculateBitsPerEntry(registrySize));
7251
}
7352

74-
/*
75-
* @deprecated globalPaletteBits is no longer in use, use {@link #createEmpty(PaletteType)} instead.
76-
*/
77-
@Deprecated(forRemoval = true)
78-
public static DataPalette createEmpty(PaletteType paletteType, int globalPaletteBits) {
79-
return createEmpty(paletteType);
80-
}
81-
82-
8353
public int get(int x, int y, int z) {
8454
if (storage != null) {
8555
int id = this.storage.get(index(x, y, z));
@@ -115,7 +85,7 @@ private int sanitizeBitsPerEntry(int bitsPerEntry) {
11585
if (bitsPerEntry <= this.paletteType.getMaxBitsPerEntry()) {
11686
return Math.max(this.paletteType.getMinBitsPerEntry(), bitsPerEntry);
11787
} else {
118-
return GLOBAL_PALETTE_BITS_PER_ENTRY;
88+
return globalPaletteBitsPerEntry;
11989
}
12090
}
12191

@@ -149,4 +119,9 @@ private static Palette createPalette(int bitsPerEntry, PaletteType paletteType)
149119
private int index(int x, int y, int z) {
150120
return y << paletteType.getMaxBitsPerEntry() | z << paletteType.getMinBitsPerEntry() | x;
151121
}
122+
123+
private static int calculateBitsPerEntry(int registrySize) {
124+
// Mojmap uses Mth.ceillog2
125+
return (int) Math.ceil(Math.log(registrySize) / LOG_2);
126+
}
152127
}

protocol/src/test/java/org/geysermc/mcprotocollib/protocol/data/ChunkTest.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,24 @@
1919
import static org.junit.jupiter.api.Assertions.assertNotEquals;
2020

2121
public class ChunkTest {
22+
// Arbitrary registry size values
23+
private static final int BLOCK_STATE_REGISTRY_SIZE = 1000;
24+
private static final int BIOME_REGISTRY_SIZE = 100;
25+
2226
private static final Logger log = LoggerFactory.getLogger(ChunkTest.class);
2327
private final List<ChunkSection> chunkSectionsToTest = new ArrayList<>();
2428

2529
@BeforeEach
2630
public void setup() {
27-
chunkSectionsToTest.add(new ChunkSection());
31+
chunkSectionsToTest.add(new ChunkSection(BLOCK_STATE_REGISTRY_SIZE, BIOME_REGISTRY_SIZE));
2832

29-
ChunkSection section = new ChunkSection();
33+
ChunkSection section = new ChunkSection(BLOCK_STATE_REGISTRY_SIZE, BIOME_REGISTRY_SIZE);
3034
section.setBlock(0, 0, 0, 10);
3135
chunkSectionsToTest.add(section);
3236

3337
SingletonPalette singletonPalette = new SingletonPalette(20);
34-
DataPalette dataPalette = new DataPalette(singletonPalette, null, PaletteType.CHUNK);
35-
DataPalette biomePalette = new DataPalette(singletonPalette, null, PaletteType.BIOME);
38+
DataPalette dataPalette = DataPalette.create(singletonPalette, null, PaletteType.CHUNK, BLOCK_STATE_REGISTRY_SIZE);
39+
DataPalette biomePalette = DataPalette.create(singletonPalette, null, PaletteType.BIOME, BIOME_REGISTRY_SIZE);
3640
section = new ChunkSection(4096, dataPalette, biomePalette);
3741
chunkSectionsToTest.add(section);
3842
}
@@ -44,7 +48,7 @@ public void testChunkSectionEncoding() {
4448
MinecraftTypes.writeChunkSection(buf, section);
4549
ChunkSection decoded;
4650
try {
47-
decoded = MinecraftTypes.readChunkSection(buf);
51+
decoded = MinecraftTypes.readChunkSection(buf, BLOCK_STATE_REGISTRY_SIZE, BIOME_REGISTRY_SIZE);
4852
} catch (Exception e) {
4953
log.error(section.toString(), e);
5054
throw e;

0 commit comments

Comments
 (0)