mirror of
https://github.com/GeyserMC/MCProtocolLib.git
synced 2024-11-14 19:34:58 -05:00
Implement proper biome palette reading
This commit is contained in:
parent
a4267d0fe8
commit
a22d016a8e
5 changed files with 54 additions and 37 deletions
|
@ -1,5 +1,6 @@
|
|||
package com.github.steveice10.mc.protocol.data.game.chunk;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.chunk.palette.PaletteType;
|
||||
import com.github.steveice10.packetlib.io.NetInput;
|
||||
import com.github.steveice10.packetlib.io.NetOutput;
|
||||
import lombok.*;
|
||||
|
@ -11,8 +12,6 @@ import java.io.IOException;
|
|||
@AllArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
public class ChunkSection {
|
||||
private static final int MAX_PALETTE_BITS_PER_ENTRY = 8;
|
||||
private static final int MAX_BIOME_BITS_PER_ENTRY = 2;
|
||||
|
||||
private static final int AIR = 0;
|
||||
|
||||
|
@ -22,18 +21,18 @@ public class ChunkSection {
|
|||
private @NonNull DataPalette biomeData;
|
||||
|
||||
public ChunkSection() {
|
||||
this(0, DataPalette.createForChunk(), DataPalette.createForBiome());
|
||||
this(0, DataPalette.createForChunk(), DataPalette.createForBiome(4));
|
||||
}
|
||||
|
||||
public static ChunkSection read(NetInput in) throws IOException {
|
||||
public static ChunkSection read(NetInput in, int globalBiomePaletteBits) throws IOException {
|
||||
int blockCount = in.readShort();
|
||||
|
||||
DataPalette chunkPalette = DataPalette.read(in, MAX_PALETTE_BITS_PER_ENTRY, DataPalette.CHUNK_SIZE);
|
||||
DataPalette biomePalette = DataPalette.read(in, MAX_BIOME_BITS_PER_ENTRY, DataPalette.BIOME_SIZE);
|
||||
DataPalette chunkPalette = DataPalette.read(in, PaletteType.CHUNK, DataPalette.GLOBAL_PALETTE_BITS_PER_ENTRY);
|
||||
DataPalette biomePalette = DataPalette.read(in, PaletteType.BIOME, globalBiomePaletteBits);
|
||||
return new ChunkSection(blockCount, chunkPalette, biomePalette);
|
||||
}
|
||||
|
||||
public static void write(NetOutput out, ChunkSection section) throws IOException {
|
||||
public static void write(NetOutput out, ChunkSection section, int globalBiomePaletteBits) throws IOException {
|
||||
out.writeShort(section.blockCount);
|
||||
DataPalette.write(out, section.chunkData);
|
||||
DataPalette.write(out, section.biomeData);
|
||||
|
|
|
@ -13,43 +13,44 @@ import java.io.IOException;
|
|||
@EqualsAndHashCode
|
||||
@ToString
|
||||
public class DataPalette {
|
||||
static final int BIOME_SIZE = 64;
|
||||
static final int CHUNK_SIZE = 4096;
|
||||
private static final int MAX_BIOME_BITS_PER_ENTRY = 2;
|
||||
private static final int MIN_PALETTE_BITS_PER_ENTRY = 4;
|
||||
private static final int MAX_PALETTE_BITS_PER_ENTRY = 8;
|
||||
private static final int GLOBAL_PALETTE_BITS_PER_ENTRY = 14;
|
||||
public static final int GLOBAL_PALETTE_BITS_PER_ENTRY = 14;
|
||||
|
||||
private @NonNull Palette palette;
|
||||
private BitStorage storage;
|
||||
private final int maxBitsForType;
|
||||
private final int maxStorageSize;
|
||||
private final PaletteType paletteType;
|
||||
private final int globalPaletteBits;
|
||||
|
||||
public static DataPalette createForChunk() {
|
||||
return createEmpty(MAX_PALETTE_BITS_PER_ENTRY, CHUNK_SIZE);
|
||||
return createForChunk(GLOBAL_PALETTE_BITS_PER_ENTRY);
|
||||
}
|
||||
|
||||
public static DataPalette createForBiome() {
|
||||
return createEmpty(MAX_BIOME_BITS_PER_ENTRY, BIOME_SIZE);
|
||||
|
||||
public static DataPalette createForChunk(int globalPaletteBits) {
|
||||
return createEmpty(PaletteType.CHUNK, globalPaletteBits);
|
||||
}
|
||||
|
||||
public static DataPalette createEmpty(int maxBitsForType, int maxStorageSize) {
|
||||
public static DataPalette createForBiome(int globalPaletteBits) {
|
||||
return createEmpty(PaletteType.BIOME, globalPaletteBits);
|
||||
}
|
||||
|
||||
public static DataPalette createEmpty(PaletteType paletteType, int globalPaletteBits) {
|
||||
return new DataPalette(new ListPalette(MIN_PALETTE_BITS_PER_ENTRY),
|
||||
new BitStorage(MIN_PALETTE_BITS_PER_ENTRY, maxBitsForType), maxBitsForType, maxStorageSize);
|
||||
new BitStorage(MIN_PALETTE_BITS_PER_ENTRY, paletteType.getMaxBitsPerEntry()), paletteType, globalPaletteBits);
|
||||
}
|
||||
|
||||
public static DataPalette read(NetInput in, int maxBitsForType, int maxSizeForType) throws IOException {
|
||||
public static DataPalette read(NetInput in, PaletteType paletteType, int globalPaletteBits) throws IOException {
|
||||
int bitsPerEntry = in.readByte();
|
||||
Palette palette = readPalette(bitsPerEntry, maxBitsForType, in);
|
||||
Palette palette = readPalette(bitsPerEntry, paletteType.getMaxBitsPerEntry(), in);
|
||||
BitStorage storage;
|
||||
if (!(palette instanceof SingletonPalette)) {
|
||||
storage = new BitStorage(bitsPerEntry, maxSizeForType, in.readLongs(in.readVarInt()));
|
||||
storage = new BitStorage(bitsPerEntry, paletteType.getStorageSize(), in.readLongs(in.readVarInt()));
|
||||
} else {
|
||||
in.readVarInt();
|
||||
storage = null;
|
||||
}
|
||||
|
||||
return new DataPalette(palette, storage, maxBitsForType, maxSizeForType);
|
||||
return new DataPalette(palette, storage, paletteType, globalPaletteBits);
|
||||
}
|
||||
|
||||
public static void write(NetOutput out, DataPalette palette) throws IOException {
|
||||
|
@ -116,7 +117,7 @@ public class DataPalette {
|
|||
}
|
||||
|
||||
private int sanitizeBitsPerEntry(int bitsPerEntry) {
|
||||
if (bitsPerEntry <= MAX_PALETTE_BITS_PER_ENTRY) {
|
||||
if (bitsPerEntry <= paletteType.getMaxBitsPerEntry()) {
|
||||
return Math.max(MIN_PALETTE_BITS_PER_ENTRY, bitsPerEntry);
|
||||
} else {
|
||||
return GLOBAL_PALETTE_BITS_PER_ENTRY;
|
||||
|
@ -128,25 +129,25 @@ public class DataPalette {
|
|||
BitStorage oldData = this.storage;
|
||||
|
||||
int bitsPerEntry = sanitizeBitsPerEntry(oldPalette instanceof SingletonPalette ? 1 : oldData.getBitsPerEntry() + 1);
|
||||
this.palette = createPalette(bitsPerEntry);
|
||||
this.storage = new BitStorage(bitsPerEntry, maxStorageSize);
|
||||
this.palette = createPalette(bitsPerEntry, paletteType.getMaxBitsPerEntry());
|
||||
this.storage = new BitStorage(bitsPerEntry, paletteType.getStorageSize());
|
||||
|
||||
if (oldPalette instanceof SingletonPalette) {
|
||||
for (int i = 0; i < maxStorageSize; i++) {
|
||||
for (int i = 0; i < paletteType.getStorageSize(); i++) {
|
||||
// TODO necessary?
|
||||
this.storage.set(i, 0);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < maxStorageSize; i++) {
|
||||
for (int i = 0; i < paletteType.getStorageSize(); i++) {
|
||||
this.storage.set(i, this.palette.stateToId(oldPalette.idToState(oldData.get(i))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Palette createPalette(int bitsPerEntry) {
|
||||
private static Palette createPalette(int bitsPerEntry, int maxBitsPerEntry) {
|
||||
if (bitsPerEntry <= MIN_PALETTE_BITS_PER_ENTRY) {
|
||||
return new ListPalette(bitsPerEntry);
|
||||
} else if (bitsPerEntry <= MAX_PALETTE_BITS_PER_ENTRY) {
|
||||
} else if (bitsPerEntry <= maxBitsPerEntry) {
|
||||
return new MapPalette(bitsPerEntry);
|
||||
} else {
|
||||
return new GlobalPalette();
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package com.github.steveice10.mc.protocol.data.game.chunk.palette;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum PaletteType {
|
||||
BIOME(3, 64),
|
||||
CHUNK(8, 4096);
|
||||
|
||||
private final int maxBitsPerEntry;
|
||||
private final int storageSize;
|
||||
|
||||
PaletteType(int maxBitsPerEntry, int storageSize) {
|
||||
this.maxBitsPerEntry = maxBitsPerEntry;
|
||||
this.storageSize = storageSize;
|
||||
}
|
||||
}
|
|
@ -3,9 +3,8 @@ package com.github.steveice10.mc.protocol.data.game.level.particle;
|
|||
public enum ParticleType {
|
||||
AMBIENT_ENTITY_EFFECT,
|
||||
ANGRY_VILLAGER,
|
||||
BARRIER,
|
||||
LIGHT,
|
||||
BLOCK,
|
||||
BLOCK_MARKER,
|
||||
BUBBLE,
|
||||
CLOUD,
|
||||
CRIT,
|
||||
|
@ -30,7 +29,7 @@ public enum ParticleType {
|
|||
FIREWORK,
|
||||
FISHING,
|
||||
FLAME,
|
||||
SOUL_FLAME,
|
||||
SOUL_FIRE_FLAME,
|
||||
SOUL,
|
||||
FLASH,
|
||||
HAPPY_VILLAGER,
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.github.steveice10.mc.protocol.data;
|
|||
|
||||
import com.github.steveice10.mc.protocol.data.game.chunk.ChunkSection;
|
||||
import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette;
|
||||
import com.github.steveice10.mc.protocol.data.game.chunk.palette.PaletteType;
|
||||
import com.github.steveice10.mc.protocol.data.game.chunk.palette.SingletonPalette;
|
||||
import com.github.steveice10.packetlib.io.stream.StreamNetInput;
|
||||
import com.github.steveice10.packetlib.io.stream.StreamNetOutput;
|
||||
|
@ -27,8 +28,8 @@ public class ChunkTest {
|
|||
chunkSectionsToTest.add(section);
|
||||
|
||||
SingletonPalette singletonPalette = new SingletonPalette(20);
|
||||
DataPalette dataPalette = new DataPalette(singletonPalette, null, 8, 4096);
|
||||
DataPalette biomePalette = new DataPalette(singletonPalette, null, 2, 64);
|
||||
DataPalette dataPalette = new DataPalette(singletonPalette, null, PaletteType.CHUNK, DataPalette.GLOBAL_PALETTE_BITS_PER_ENTRY);
|
||||
DataPalette biomePalette = new DataPalette(singletonPalette, null, PaletteType.BIOME, 4);
|
||||
section = new ChunkSection(4096, dataPalette, biomePalette);
|
||||
chunkSectionsToTest.add(section);
|
||||
}
|
||||
|
@ -38,11 +39,11 @@ public class ChunkTest {
|
|||
for (ChunkSection section : chunkSectionsToTest) {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
StreamNetOutput out = new StreamNetOutput(stream);
|
||||
ChunkSection.write(out, section);
|
||||
ChunkSection.write(out, section, 4);
|
||||
StreamNetInput in = new StreamNetInput(new ByteArrayInputStream(stream.toByteArray()));
|
||||
ChunkSection decoded;
|
||||
try {
|
||||
decoded = ChunkSection.read(in);
|
||||
decoded = ChunkSection.read(in, 4);
|
||||
} catch (Exception e) {
|
||||
System.out.println(section);
|
||||
e.printStackTrace();
|
||||
|
|
Loading…
Reference in a new issue