Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1332,7 +1332,7 @@ public static void writeSlotDisplay(ByteBuf buf, SlotDisplay display) {
}
}

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

return new DataPalette(palette, storage, paletteType);
}

/**
* @deprecated globalPaletteBits is no longer in use, use {@link #readDataPalette(ByteBuf, PaletteType)} instead.
*/
@Deprecated(forRemoval = true)
public static DataPalette readDataPalette(ByteBuf buf, PaletteType paletteType, int globalPaletteBits) {
return MinecraftTypes.readDataPalette(buf, paletteType);
return DataPalette.create(palette, storage, paletteType, registrySize);
}

public static void writeDataPalette(ByteBuf buf, DataPalette palette) {
Expand Down Expand Up @@ -1388,25 +1380,17 @@ private static Palette readPalette(ByteBuf buf, PaletteType paletteType, int bit
}
}

public static ChunkSection readChunkSection(ByteBuf buf) {
public static ChunkSection readChunkSection(ByteBuf buf, int blockStateRegistrySize, int biomeRegistrySize) {
int blockCount = buf.readShort();

DataPalette chunkPalette = MinecraftTypes.readDataPalette(buf, PaletteType.CHUNK);
DataPalette biomePalette = MinecraftTypes.readDataPalette(buf, PaletteType.BIOME);
return new ChunkSection(blockCount, chunkPalette, biomePalette);
}

/**
* @deprecated globalBiomePaletteBits is no longer in use, use {@link #readChunkSection(ByteBuf)} instead.
*/
@Deprecated(forRemoval = true)
public static ChunkSection readChunkSection(ByteBuf buf, int globalBiomePaletteBits) {
return MinecraftTypes.readChunkSection(buf);
DataPalette blockStatePalette = MinecraftTypes.readDataPalette(buf, PaletteType.BLOCK_STATE, blockStateRegistrySize);
DataPalette biomePalette = MinecraftTypes.readDataPalette(buf, PaletteType.BIOME, biomeRegistrySize);
return new ChunkSection(blockCount, blockStatePalette, biomePalette);
}

public static void writeChunkSection(ByteBuf buf, ChunkSection section) {
buf.writeShort(section.getBlockCount());
MinecraftTypes.writeDataPalette(buf, section.getChunkData());
MinecraftTypes.writeDataPalette(buf, section.getBlockData());
MinecraftTypes.writeDataPalette(buf, section.getBiomeData());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,24 @@ public class ChunkSection {
private static final int AIR = 0;

private int blockCount;
private @NonNull DataPalette chunkData;
private @NonNull DataPalette blockData;
@Getter
private @NonNull DataPalette biomeData;

public ChunkSection() {
this(0, DataPalette.createForChunk(), DataPalette.createForBiome());
public ChunkSection(int initialBlockState, int blockStateRegistrySize, int initialBiome, int biomeRegistrySize) {
this(0, DataPalette.createForBlockState(initialBlockState, blockStateRegistrySize), DataPalette.createForBiome(initialBiome, biomeRegistrySize));
}

public ChunkSection(ChunkSection original) {
this(original.blockCount, new DataPalette(original.chunkData), new DataPalette(original.biomeData));
this(original.blockCount, new DataPalette(original.blockData), new DataPalette(original.biomeData));
}

public int getBlock(int x, int y, int z) {
return this.chunkData.get(x, y, z);
return this.blockData.get(x, y, z);
}

public void setBlock(int x, int y, int z, int state) {
int curr = this.chunkData.set(x, y, z, state);
int curr = this.blockData.set(x, y, z, state);
if (state != AIR && curr == AIR) {
this.blockCount++;
} else if (state == AIR && curr != AIR) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package org.geysermc.mcprotocollib.protocol.data.game.chunk;

import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.ToString;
import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.GlobalPalette;
import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.ListPalette;
Expand All @@ -14,72 +12,43 @@
import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.SingletonPalette;

@Getter
@Setter
@AllArgsConstructor
@EqualsAndHashCode
@ToString
public class DataPalette {

/*
* @deprecated globalPaletteBits is no longer in use.
*/
@Deprecated(forRemoval = true)
public static final int GLOBAL_PALETTE_BITS_PER_ENTRY = 14;
private static final double LOG_2 = Math.log(2.0);

private @NonNull Palette palette;
private BitStorage storage;
private final PaletteType paletteType;
private final int globalPaletteBitsPerEntry;

/*
* @deprecated globalPaletteBits is no longer in use, use {@link #DataPalette(Palette, BitStorage, PaletteType)} instead.
*/
@Deprecated(forRemoval = true)
public DataPalette(@NonNull Palette palette, BitStorage storage, PaletteType paletteType, int globalPaletteBits) {
this(palette, storage, paletteType);
private DataPalette(@NonNull Palette palette, BitStorage storage, PaletteType paletteType, int globalPaletteBitsPerEntry) {
this.palette = palette;
this.storage = storage;
this.paletteType = paletteType;
this.globalPaletteBitsPerEntry = globalPaletteBitsPerEntry;
}

public DataPalette(DataPalette original) {
this(original.palette.copy(), original.storage == null ? null : new BitStorage(original.storage), original.paletteType);
this(original.palette.copy(), original.storage == null ? null : new BitStorage(original.storage), original.paletteType, original.globalPaletteBitsPerEntry);
}

public static DataPalette createForChunk() {
return createEmpty(PaletteType.CHUNK);
public static DataPalette createForBlockState(int initialState, int blockStateRegistrySize) {
return createEmpty(PaletteType.BLOCK_STATE, initialState, blockStateRegistrySize);
}

/*
* @deprecated globalPaletteBits is no longer in use, use {@link #createForChunk()} instead.
*/
@Deprecated(forRemoval = true)
public static DataPalette createForChunk(int globalPaletteBits) {
return createForChunk();
}

/*
* @deprecated globalPaletteBits is no longer in use, use {@link #createForBiome()} instead.
*/
@Deprecated(forRemoval = true)
public static DataPalette createForBiome(int globalPaletteBits) {
return createForBiome();
public static DataPalette createForBiome(int initialBiome, int biomeRegistrySize) {
return createEmpty(PaletteType.BIOME, initialBiome, biomeRegistrySize);
}

public static DataPalette createForBiome() {
return createEmpty(PaletteType.BIOME);
public static DataPalette createEmpty(PaletteType paletteType, int initial, int registrySize) {
return create(new SingletonPalette(initial), null, paletteType, registrySize);
}

public static DataPalette createEmpty(PaletteType paletteType) {
return new DataPalette(new ListPalette(paletteType.getMinBitsPerEntry()),
new BitStorage(paletteType.getMinBitsPerEntry(), paletteType.getStorageSize()), paletteType);
public static DataPalette create(@NonNull Palette palette, BitStorage storage, PaletteType paletteType, int registrySize) {
return new DataPalette(palette, storage, paletteType, calculateBitsPerEntry(registrySize));
}

/*
* @deprecated globalPaletteBits is no longer in use, use {@link #createEmpty(PaletteType)} instead.
*/
@Deprecated(forRemoval = true)
public static DataPalette createEmpty(PaletteType paletteType, int globalPaletteBits) {
return createEmpty(paletteType);
}


public int get(int x, int y, int z) {
if (storage != null) {
int id = this.storage.get(index(x, y, z));
Expand Down Expand Up @@ -115,7 +84,7 @@ private int sanitizeBitsPerEntry(int bitsPerEntry) {
if (bitsPerEntry <= this.paletteType.getMaxBitsPerEntry()) {
return Math.max(this.paletteType.getMinBitsPerEntry(), bitsPerEntry);
} else {
return GLOBAL_PALETTE_BITS_PER_ENTRY;
return globalPaletteBitsPerEntry;
}
}

Expand Down Expand Up @@ -149,4 +118,9 @@ private static Palette createPalette(int bitsPerEntry, PaletteType paletteType)
private int index(int x, int y, int z) {
return y << paletteType.getMaxBitsPerEntry() | z << paletteType.getMinBitsPerEntry() | x;
}

private static int calculateBitsPerEntry(int registrySize) {
// Mojmap uses Mth.ceillog2
return (int) Math.ceil(Math.log(registrySize) / LOG_2);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
@Getter
public enum PaletteType {
BIOME(1, 3, 64),
CHUNK(4, 8, 4096);
BLOCK_STATE(4, 8, 4096);

private final int minBitsPerEntry;
private final int maxBitsPerEntry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,25 @@
import static org.junit.jupiter.api.Assertions.assertNotEquals;

public class ChunkTest {
// Arbitrary registry size values
private static final int BLOCK_STATE_REGISTRY_SIZE = 1000;
private static final int BIOME_REGISTRY_SIZE = 100;

private static final Logger log = LoggerFactory.getLogger(ChunkTest.class);
private final List<ChunkSection> chunkSectionsToTest = new ArrayList<>();

@BeforeEach
public void setup() {
chunkSectionsToTest.add(new ChunkSection());
chunkSectionsToTest.add(new ChunkSection(420, BLOCK_STATE_REGISTRY_SIZE, 42, BIOME_REGISTRY_SIZE));

ChunkSection section = new ChunkSection();
ChunkSection section = new ChunkSection(20, BLOCK_STATE_REGISTRY_SIZE, 35, BIOME_REGISTRY_SIZE);
section.setBlock(0, 0, 0, 10);
chunkSectionsToTest.add(section);

SingletonPalette singletonPalette = new SingletonPalette(20);
DataPalette dataPalette = new DataPalette(singletonPalette, null, PaletteType.CHUNK);
DataPalette biomePalette = new DataPalette(singletonPalette, null, PaletteType.BIOME);
section = new ChunkSection(4096, dataPalette, biomePalette);
DataPalette blockPalette = DataPalette.create(singletonPalette, null, PaletteType.BLOCK_STATE, BLOCK_STATE_REGISTRY_SIZE);
DataPalette biomePalette = DataPalette.create(singletonPalette, null, PaletteType.BIOME, BIOME_REGISTRY_SIZE);
section = new ChunkSection(4096, blockPalette, biomePalette);
chunkSectionsToTest.add(section);
}

Expand All @@ -44,7 +48,7 @@ public void testChunkSectionEncoding() {
MinecraftTypes.writeChunkSection(buf, section);
ChunkSection decoded;
try {
decoded = MinecraftTypes.readChunkSection(buf);
decoded = MinecraftTypes.readChunkSection(buf, BLOCK_STATE_REGISTRY_SIZE, BIOME_REGISTRY_SIZE);
} catch (Exception e) {
log.error(section.toString(), e);
throw e;
Expand Down
Loading