Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-11-08 17:20:24 +01:00
Fix biome palette writing
Co-authored-by: Gerrygames <gecam59@gmail.com>
Dieser Commit ist enthalten in:
Ursprung
3feff8e751
Commit
e744214ad6
@ -31,6 +31,11 @@ public interface ChunkSection {
|
|||||||
*/
|
*/
|
||||||
int SIZE = 16 * 16 * 16; // width * depth * height
|
int SIZE = 16 * 16 * 16; // width * depth * height
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Size (dimensions) of biomes in a chunks section.
|
||||||
|
*/
|
||||||
|
int BIOME_SIZE = 4 * 4 * 4;
|
||||||
|
|
||||||
static int index(int x, int y, int z) {
|
static int index(int x, int y, int z) {
|
||||||
return y << 8 | z << 4 | x;
|
return y << 8 | z << 4 | x;
|
||||||
}
|
}
|
||||||
|
@ -36,14 +36,14 @@ public class ChunkSectionImpl implements ChunkSection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ChunkSectionImpl(final boolean holdsLight) {
|
public ChunkSectionImpl(final boolean holdsLight) {
|
||||||
addPalette(PaletteType.BLOCKS, new DataPaletteImpl());
|
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE));
|
||||||
if (holdsLight) {
|
if (holdsLight) {
|
||||||
this.light = new ChunkSectionLightImpl();
|
this.light = new ChunkSectionLightImpl();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkSectionImpl(final boolean holdsLight, final int expectedPaletteLength) {
|
public ChunkSectionImpl(final boolean holdsLight, final int expectedPaletteLength) {
|
||||||
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(expectedPaletteLength));
|
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE, expectedPaletteLength));
|
||||||
if (holdsLight) {
|
if (holdsLight) {
|
||||||
this.light = new ChunkSectionLightImpl();
|
this.light = new ChunkSectionLightImpl();
|
||||||
}
|
}
|
||||||
|
@ -24,11 +24,21 @@ package com.viaversion.viaversion.api.minecraft.chunks;
|
|||||||
|
|
||||||
public interface DataPalette {
|
public interface DataPalette {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the packet section index of the given coordinates.
|
||||||
|
*
|
||||||
|
* @param x x
|
||||||
|
* @param y y
|
||||||
|
* @param z z
|
||||||
|
* @return packed section index of the given coordinates
|
||||||
|
*/
|
||||||
|
int index(final int x, final int y, final int z);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the given chunk coordinate.
|
* Returns the value of the given chunk coordinate.
|
||||||
*
|
*
|
||||||
* @param sectionCoordinate block index within the section
|
* @param sectionCoordinate section index within the section
|
||||||
* @return block state of the given index
|
* @return section state of the given index
|
||||||
*/
|
*/
|
||||||
int idAt(int sectionCoordinate);
|
int idAt(int sectionCoordinate);
|
||||||
|
|
||||||
@ -38,17 +48,17 @@ public interface DataPalette {
|
|||||||
* @param sectionX section x
|
* @param sectionX section x
|
||||||
* @param sectionY section y
|
* @param sectionY section y
|
||||||
* @param sectionZ section z
|
* @param sectionZ section z
|
||||||
* @return block state of the given section coordinate
|
* @return id of the given section coordinate
|
||||||
*/
|
*/
|
||||||
default int idAt(final int sectionX, final int sectionY, final int sectionZ) {
|
default int idAt(final int sectionX, final int sectionY, final int sectionZ) {
|
||||||
return idAt(ChunkSection.index(sectionX, sectionY, sectionZ));
|
return idAt(index(sectionX, sectionY, sectionZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a value in the chunk section.
|
* Set a value in the chunk section.
|
||||||
* This method does not update non-air blocks count.
|
* This method does not update non-air blocks count.
|
||||||
*
|
*
|
||||||
* @param sectionCoordinate block index within the section
|
* @param sectionCoordinate section index within the section
|
||||||
* @param id id value
|
* @param id id value
|
||||||
*/
|
*/
|
||||||
void setIdAt(int sectionCoordinate, int id);
|
void setIdAt(int sectionCoordinate, int id);
|
||||||
@ -63,7 +73,7 @@ public interface DataPalette {
|
|||||||
* @param id id value
|
* @param id id value
|
||||||
*/
|
*/
|
||||||
default void setIdAt(final int sectionX, final int sectionY, final int sectionZ, final int id) {
|
default void setIdAt(final int sectionX, final int sectionY, final int sectionZ, final int id) {
|
||||||
setIdAt(ChunkSection.index(sectionX, sectionY, sectionZ), id);
|
setIdAt(index(sectionX, sectionY, sectionZ), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,17 +93,17 @@ public interface DataPalette {
|
|||||||
void setIdByIndex(int index, int id);
|
void setIdByIndex(int index, int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the palette index of the given block index.
|
* Returns the palette index of the given section index.
|
||||||
*
|
*
|
||||||
* @param packedCoordinate block index
|
* @param packedCoordinate section index
|
||||||
* @return palette index of the given block index
|
* @return palette index of the given section index
|
||||||
*/
|
*/
|
||||||
int paletteIndexAt(int packedCoordinate);
|
int paletteIndexAt(int packedCoordinate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the index of the given section coordinate.
|
* Sets the index of the given section coordinate.
|
||||||
*
|
*
|
||||||
* @param sectionCoordinate block index
|
* @param sectionCoordinate section index
|
||||||
* @param index palette index
|
* @param index palette index
|
||||||
*/
|
*/
|
||||||
void setPaletteIndexAt(int sectionCoordinate, int index);
|
void setPaletteIndexAt(int sectionCoordinate, int index);
|
||||||
|
@ -32,22 +32,26 @@ public final class DataPaletteImpl implements DataPalette {
|
|||||||
private final IntList palette;
|
private final IntList palette;
|
||||||
private final Int2IntMap inversePalette;
|
private final Int2IntMap inversePalette;
|
||||||
private final int[] values;
|
private final int[] values;
|
||||||
|
private final int sizeBits;
|
||||||
|
|
||||||
public DataPaletteImpl() {
|
public DataPaletteImpl(final int valuesLength) {
|
||||||
this.values = new int[ChunkSection.SIZE];
|
this(valuesLength, 8);
|
||||||
palette = new IntArrayList();
|
|
||||||
inversePalette = new Int2IntOpenHashMap();
|
|
||||||
inversePalette.defaultReturnValue(-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataPaletteImpl(final int expectedPaletteLength) {
|
public DataPaletteImpl(final int valuesLength, final int expectedPaletteLength) {
|
||||||
this.values = new int[ChunkSection.SIZE];
|
this.values = new int[valuesLength];
|
||||||
|
sizeBits = Integer.numberOfTrailingZeros(valuesLength) / 3;
|
||||||
// Pre-size the palette array/map
|
// Pre-size the palette array/map
|
||||||
palette = new IntArrayList(expectedPaletteLength);
|
palette = new IntArrayList(expectedPaletteLength);
|
||||||
inversePalette = new Int2IntOpenHashMap(expectedPaletteLength);
|
inversePalette = new Int2IntOpenHashMap(expectedPaletteLength);
|
||||||
inversePalette.defaultReturnValue(-1);
|
inversePalette.defaultReturnValue(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int index(final int x, final int y, final int z) {
|
||||||
|
return (y << this.sizeBits | z) << this.sizeBits | x;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int idAt(final int sectionCoordinate) {
|
public int idAt(final int sectionCoordinate) {
|
||||||
final int index = values[sectionCoordinate];
|
final int index = values[sectionCoordinate];
|
||||||
|
@ -24,18 +24,18 @@ package com.viaversion.viaversion.api.minecraft.chunks;
|
|||||||
|
|
||||||
public enum PaletteType {
|
public enum PaletteType {
|
||||||
BLOCKS(ChunkSection.SIZE, 8),
|
BLOCKS(ChunkSection.SIZE, 8),
|
||||||
BIOMES(4 * 4 * 4, 2);
|
BIOMES(ChunkSection.BIOME_SIZE, 2);
|
||||||
|
|
||||||
private final int maxSize;
|
private final int size;
|
||||||
private final int highestBitsPerValue;
|
private final int highestBitsPerValue;
|
||||||
|
|
||||||
PaletteType(final int maxSize, final int highestBitsPerValue) {
|
PaletteType(final int size, final int highestBitsPerValue) {
|
||||||
this.maxSize = maxSize;
|
this.size = size;
|
||||||
this.highestBitsPerValue = highestBitsPerValue;
|
this.highestBitsPerValue = highestBitsPerValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int maxSize() {
|
public int size() {
|
||||||
return maxSize;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int highestBitsPerValue() {
|
public int highestBitsPerValue() {
|
||||||
|
@ -52,7 +52,7 @@ public final class PaletteType1_18 extends Type<DataPalette> {
|
|||||||
final DataPaletteImpl palette;
|
final DataPaletteImpl palette;
|
||||||
if (bitsPerValue == 0) {
|
if (bitsPerValue == 0) {
|
||||||
//TODO Create proper singleton palette Object
|
//TODO Create proper singleton palette Object
|
||||||
palette = new DataPaletteImpl(1);
|
palette = new DataPaletteImpl(type.size(), 1);
|
||||||
palette.addId(Type.VAR_INT.readPrimitive(buffer));
|
palette.addId(Type.VAR_INT.readPrimitive(buffer));
|
||||||
Type.VAR_INT.readPrimitive(buffer); // 0 values length
|
Type.VAR_INT.readPrimitive(buffer); // 0 values length
|
||||||
return palette;
|
return palette;
|
||||||
@ -60,19 +60,19 @@ public final class PaletteType1_18 extends Type<DataPalette> {
|
|||||||
|
|
||||||
if (bitsPerValue != globalPaletteBits) {
|
if (bitsPerValue != globalPaletteBits) {
|
||||||
final int paletteLength = Type.VAR_INT.readPrimitive(buffer);
|
final int paletteLength = Type.VAR_INT.readPrimitive(buffer);
|
||||||
palette = new DataPaletteImpl(paletteLength);
|
palette = new DataPaletteImpl(type.size(), paletteLength);
|
||||||
for (int i = 0; i < paletteLength; i++) {
|
for (int i = 0; i < paletteLength; i++) {
|
||||||
palette.addId(Type.VAR_INT.readPrimitive(buffer));
|
palette.addId(Type.VAR_INT.readPrimitive(buffer));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
palette = new DataPaletteImpl();
|
palette = new DataPaletteImpl(type.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read values
|
// Read values
|
||||||
final long[] values = new long[Type.VAR_INT.readPrimitive(buffer)];
|
final long[] values = new long[Type.VAR_INT.readPrimitive(buffer)];
|
||||||
if (values.length > 0) {
|
if (values.length > 0) {
|
||||||
final char valuesPerLong = (char) (64 / bitsPerValue);
|
final char valuesPerLong = (char) (64 / bitsPerValue);
|
||||||
final int expectedLength = (type.maxSize() + valuesPerLong - 1) / valuesPerLong;
|
final int expectedLength = (type.size() + valuesPerLong - 1) / valuesPerLong;
|
||||||
if (values.length != expectedLength) {
|
if (values.length != expectedLength) {
|
||||||
throw new IllegalStateException("Palette data length (" + values.length + ") does not match expected length (" + expectedLength + ")! bitsPerValue=" + bitsPerValue + ", originalBitsPerValue=" + originalBitsPerValue);
|
throw new IllegalStateException("Palette data length (" + values.length + ") does not match expected length (" + expectedLength + ")! bitsPerValue=" + bitsPerValue + ", originalBitsPerValue=" + originalBitsPerValue);
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ public final class PaletteType1_18 extends Type<DataPalette> {
|
|||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
values[i] = buffer.readLong();
|
values[i] = buffer.readLong();
|
||||||
}
|
}
|
||||||
CompactArrayUtil.iterateCompactArrayWithPadding(bitsPerValue, type.maxSize(), values,
|
CompactArrayUtil.iterateCompactArrayWithPadding(bitsPerValue, type.size(), values,
|
||||||
bitsPerValue == globalPaletteBits ? palette::setIdAt : palette::setPaletteIndexAt);
|
bitsPerValue == globalPaletteBits ? palette::setIdAt : palette::setPaletteIndexAt);
|
||||||
}
|
}
|
||||||
return palette;
|
return palette;
|
||||||
@ -120,7 +120,7 @@ public final class PaletteType1_18 extends Type<DataPalette> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final long[] data = CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, type.maxSize(), bitsPerValue == globalPaletteBits ? palette::idAt : palette::paletteIndexAt);
|
final long[] data = CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, type.size(), bitsPerValue == globalPaletteBits ? palette::idAt : palette::paletteIndexAt);
|
||||||
Type.VAR_INT.writePrimitive(buffer, data.length);
|
Type.VAR_INT.writePrimitive(buffer, data.length);
|
||||||
for (final long l : data) {
|
for (final long l : data) {
|
||||||
buffer.writeLong(l);
|
buffer.writeLong(l);
|
||||||
|
@ -47,7 +47,6 @@ public final class WorldPackets {
|
|||||||
|
|
||||||
private static final int WIDTH_BITS = 2;
|
private static final int WIDTH_BITS = 2;
|
||||||
private static final int HORIZONTAL_MASK = 3;
|
private static final int HORIZONTAL_MASK = 3;
|
||||||
private static final int BIOMES_PER_CHUNK = 4 * 4 * 4;
|
|
||||||
|
|
||||||
public static void register(final Protocol1_18To1_17_1 protocol) {
|
public static void register(final Protocol1_18To1_17_1 protocol) {
|
||||||
protocol.registerClientbound(ClientboundPackets1_17_1.BLOCK_ENTITY_DATA, new PacketRemapper() {
|
protocol.registerClientbound(ClientboundPackets1_17_1.BLOCK_ENTITY_DATA, new PacketRemapper() {
|
||||||
@ -137,7 +136,7 @@ public final class WorldPackets {
|
|||||||
sections[i] = section;
|
sections[i] = section;
|
||||||
section.setNonAirBlocksCount(0);
|
section.setNonAirBlocksCount(0);
|
||||||
|
|
||||||
final DataPaletteImpl blockPalette = new DataPaletteImpl();
|
final DataPaletteImpl blockPalette = new DataPaletteImpl(ChunkSection.SIZE);
|
||||||
blockPalette.addId(0);
|
blockPalette.addId(0);
|
||||||
section.addPalette(PaletteType.BLOCKS, blockPalette);
|
section.addPalette(PaletteType.BLOCKS, blockPalette);
|
||||||
} else {
|
} else {
|
||||||
@ -149,20 +148,12 @@ public final class WorldPackets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fill biome palette
|
// Fill biome palette
|
||||||
final DataPaletteImpl biomePalette = new DataPaletteImpl();
|
final DataPaletteImpl biomePalette = new DataPaletteImpl(ChunkSection.BIOME_SIZE);
|
||||||
section.addPalette(PaletteType.BIOMES, biomePalette);
|
section.addPalette(PaletteType.BIOMES, biomePalette);
|
||||||
for (int biomeIndex = i * BIOMES_PER_CHUNK; biomeIndex < (i * BIOMES_PER_CHUNK) + BIOMES_PER_CHUNK; biomeIndex++) {
|
|
||||||
final int biome = biomeData[biomeIndex];
|
final int offset = i * ChunkSection.BIOME_SIZE;
|
||||||
final int minX = (biomeIndex & HORIZONTAL_MASK) << 2;
|
for (int biomeIndex = 0; biomeIndex < ChunkSection.BIOME_SIZE; biomeIndex++) {
|
||||||
final int minY = ((biomeIndex >> WIDTH_BITS + WIDTH_BITS) << 2) & 15;
|
biomePalette.setIdAt(biomeIndex, biomeData[offset + biomeIndex]);
|
||||||
final int minZ = (biomeIndex >> WIDTH_BITS & HORIZONTAL_MASK) << 2;
|
|
||||||
for (int x = minX; x < minX + 4; x++) {
|
|
||||||
for (int y = minY; y < minY + 4; y++) {
|
|
||||||
for (int z = minZ; z < minZ + 4; z++) {
|
|
||||||
biomePalette.setIdAt(x, y, z, biome);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren