Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-11-03 14:50:30 +01:00
Cleanup Palette interface and read/write
Dieser Commit ist enthalten in:
Ursprung
eaa18f569a
Commit
c565f2c9c7
@ -37,7 +37,7 @@ public interface ChunkSection {
|
||||
|
||||
@Deprecated/*(forRemoval = true)*/
|
||||
default int getFlatBlock(int idx) {
|
||||
return palette(PaletteType.BLOCKS).value(idx);
|
||||
return palette(PaletteType.BLOCKS).idAt(idx);
|
||||
}
|
||||
|
||||
@Deprecated/*(forRemoval = true)*/
|
||||
@ -47,7 +47,7 @@ public interface ChunkSection {
|
||||
|
||||
@Deprecated/*(forRemoval = true)*/
|
||||
default void setFlatBlock(int idx, int id) {
|
||||
palette(PaletteType.BLOCKS).setValue(idx, id);
|
||||
palette(PaletteType.BLOCKS).setIdAt(idx, id);
|
||||
}
|
||||
|
||||
@Deprecated/*(forRemoval = true)*/
|
||||
@ -77,12 +77,12 @@ public interface ChunkSection {
|
||||
|
||||
@Deprecated/*(forRemoval = true)*/
|
||||
default void setPaletteIndex(int idx, int index) {
|
||||
palette(PaletteType.BLOCKS).setIndex(idx, index);
|
||||
palette(PaletteType.BLOCKS).setPaletteIndexAt(idx, index);
|
||||
}
|
||||
|
||||
@Deprecated/*(forRemoval = true)*/
|
||||
default int getPaletteIndex(int idx) {
|
||||
return palette(PaletteType.BLOCKS).index(idx);
|
||||
return palette(PaletteType.BLOCKS).paletteIndexAt(idx);
|
||||
}
|
||||
|
||||
@Deprecated/*(forRemoval = true)*/
|
||||
@ -92,22 +92,22 @@ public interface ChunkSection {
|
||||
|
||||
@Deprecated/*(forRemoval = true)*/
|
||||
default int getPaletteEntry(int index) {
|
||||
return palette(PaletteType.BLOCKS).entry(index);
|
||||
return palette(PaletteType.BLOCKS).idByIndex(index);
|
||||
}
|
||||
|
||||
@Deprecated/*(forRemoval = true)*/
|
||||
default void setPaletteEntry(int index, int id) {
|
||||
palette(PaletteType.BLOCKS).setEntry(index, id);
|
||||
palette(PaletteType.BLOCKS).setIdByIndex(index, id);
|
||||
}
|
||||
|
||||
@Deprecated/*(forRemoval = true)*/
|
||||
default void replacePaletteEntry(int oldId, int newId) {
|
||||
palette(PaletteType.BLOCKS).replaceEntry(oldId, newId);
|
||||
palette(PaletteType.BLOCKS).replaceId(oldId, newId);
|
||||
}
|
||||
|
||||
@Deprecated/*(forRemoval = true)*/
|
||||
default void addPaletteEntry(int id) {
|
||||
palette(PaletteType.BLOCKS).addEntry(id);
|
||||
palette(PaletteType.BLOCKS).addId(id);
|
||||
}
|
||||
|
||||
@Deprecated/*(forRemoval = true)*/
|
||||
@ -152,7 +152,7 @@ public interface ChunkSection {
|
||||
*/
|
||||
@Nullable DataPalette palette(PaletteType type);
|
||||
|
||||
void addPalette(DataPalette blockPalette);
|
||||
void addPalette(PaletteType type, DataPalette blockPalette);
|
||||
|
||||
void removePalette(PaletteType type);
|
||||
}
|
||||
|
@ -36,14 +36,14 @@ public class ChunkSectionImpl implements ChunkSection {
|
||||
}
|
||||
|
||||
public ChunkSectionImpl(final boolean holdsLight) {
|
||||
addPalette(new DataPaletteImpl(PaletteType.BLOCKS));
|
||||
addPalette(PaletteType.BLOCKS, new DataPaletteImpl());
|
||||
if (holdsLight) {
|
||||
this.light = new ChunkSectionLightImpl();
|
||||
}
|
||||
}
|
||||
|
||||
public ChunkSectionImpl(final boolean holdsLight, final int expectedPaletteLength) {
|
||||
addPalette(new DataPaletteImpl(PaletteType.BLOCKS, expectedPaletteLength));
|
||||
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(expectedPaletteLength));
|
||||
if (holdsLight) {
|
||||
this.light = new ChunkSectionLightImpl();
|
||||
}
|
||||
@ -75,8 +75,8 @@ public class ChunkSectionImpl implements ChunkSection {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPalette(final DataPalette palette) {
|
||||
palettes.put(palette.type(), palette);
|
||||
public void addPalette(final PaletteType type, final DataPalette palette) {
|
||||
palettes.put(type, palette);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,82 +25,93 @@ package com.viaversion.viaversion.api.minecraft.chunks;
|
||||
public interface DataPalette {
|
||||
|
||||
/**
|
||||
* Returns the block state of the given index.
|
||||
* Returns the value of the given chunk coordinate.
|
||||
*
|
||||
* @param idx block index within the section
|
||||
* @param sectionCoordinate block index within the section
|
||||
* @return block state of the given index
|
||||
*/
|
||||
int value(int idx);
|
||||
int idAt(int sectionCoordinate);
|
||||
|
||||
/**
|
||||
* Returns the block state of the section coordinate.
|
||||
* Returns the value of the section coordinate.
|
||||
*
|
||||
* @param x section x
|
||||
* @param y section y
|
||||
* @param z section z
|
||||
* @param sectionX section x
|
||||
* @param sectionY section y
|
||||
* @param sectionZ section z
|
||||
* @return block state of the given section coordinate
|
||||
*/
|
||||
default int value(final int x, final int y, final int z) {
|
||||
return value(ChunkSection.index(x, y, z));
|
||||
default int idAt(final int sectionX, final int sectionY, final int sectionZ) {
|
||||
return idAt(ChunkSection.index(sectionX, sectionY, sectionZ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a block state in the chunk section.
|
||||
* This method will not update non-air blocks count.
|
||||
* Set a value in the chunk section.
|
||||
* This method does not update non-air blocks count.
|
||||
*
|
||||
* @param idx block index within the section
|
||||
* @param id raw or flat id of the block state
|
||||
* @param sectionCoordinate block index within the section
|
||||
* @param id id value
|
||||
*/
|
||||
void setValue(int idx, int id);
|
||||
void setIdAt(int sectionCoordinate, int id);
|
||||
|
||||
/**
|
||||
* Set a block state in the chunk section.
|
||||
* This method will not update non-air blocks count.
|
||||
* Set a value in the chunk section.
|
||||
* This method does not update non-air blocks count.
|
||||
*
|
||||
* @param x section x
|
||||
* @param y section y
|
||||
* @param z section z
|
||||
* @param id raw or flat id of the block state
|
||||
* @param sectionX section x
|
||||
* @param sectionY section y
|
||||
* @param sectionZ section z
|
||||
* @param id id value
|
||||
*/
|
||||
default void setValue(final int x, final int y, final int z, final int id) {
|
||||
setValue(ChunkSection.index(x, y, z), id);
|
||||
default void setIdAt(final int sectionX, final int sectionY, final int sectionZ, final int id) {
|
||||
setIdAt(ChunkSection.index(sectionX, sectionY, sectionZ), id);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
default int rawDataBlock(final int x, final int y, final int z) {
|
||||
return value(x, y, z) >> 4;
|
||||
}
|
||||
|
||||
default int dataBlock(final int x, final int y, final int z) {
|
||||
return value(x, y, z) & 0xF;
|
||||
}
|
||||
|
||||
default void setDataBlock(final int x, final int y, final int z, final int type, final int data) {
|
||||
setValue(ChunkSection.index(x, y, z), type << 4 | (data & 0xF));
|
||||
}
|
||||
|
||||
default void setDataBlock(final int idx, final int type, final int data) {
|
||||
setValue(idx, type << 4 | (data & 0xF));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Sets a block to the given palette index.
|
||||
* Returns the id assigned to the given palette index.
|
||||
*
|
||||
* @param idx block index
|
||||
* @param index palette index
|
||||
* @return id assigned to the given palette index
|
||||
*/
|
||||
void setIndex(int idx, int index);
|
||||
int idByIndex(int index);
|
||||
|
||||
/**
|
||||
* Assigns an id assigned to the given palette index.
|
||||
*
|
||||
* @param index palette index
|
||||
* @param id id value
|
||||
*/
|
||||
void setIdByIndex(int index, int id);
|
||||
|
||||
/**
|
||||
* Returns the palette index of the given block index.
|
||||
*
|
||||
* @param idx block index
|
||||
* @param packedCoordinate block index
|
||||
* @return palette index of the given block index
|
||||
*/
|
||||
int index(int idx);
|
||||
int paletteIndexAt(int packedCoordinate);
|
||||
|
||||
/**
|
||||
* Sets the index of the given section coordinate.
|
||||
*
|
||||
* @param sectionCoordinate block index
|
||||
* @param index palette index
|
||||
*/
|
||||
void setPaletteIndexAt(int sectionCoordinate, int index);
|
||||
|
||||
/**
|
||||
* Adds a new id to the palette.
|
||||
*
|
||||
* @param id id value
|
||||
*/
|
||||
void addId(int id);
|
||||
|
||||
/**
|
||||
* Replaces an id in the palette.
|
||||
*
|
||||
* @param oldId old id
|
||||
* @param newId new id
|
||||
*/
|
||||
void replaceId(int oldId, int newId);
|
||||
|
||||
/**
|
||||
* Returns the size of the palette.
|
||||
@ -109,46 +120,8 @@ public interface DataPalette {
|
||||
*/
|
||||
int size();
|
||||
|
||||
/**
|
||||
* Returns the block state assigned to the given palette index.
|
||||
*
|
||||
* @param index palette index
|
||||
* @return block state assigned to the given palette index
|
||||
*/
|
||||
int entry(int index);
|
||||
|
||||
/**
|
||||
* Assigns a block state assigned to the given palette index.
|
||||
*
|
||||
* @param index palette index
|
||||
* @param id block state
|
||||
*/
|
||||
void setEntry(int index, int id);
|
||||
|
||||
/**
|
||||
* Replaces a block state in the palette.
|
||||
*
|
||||
* @param oldId old block state
|
||||
* @param newId new block state
|
||||
*/
|
||||
void replaceEntry(int oldId, int newId);
|
||||
|
||||
/**
|
||||
* Adds a new block state to the palette.
|
||||
*
|
||||
* @param id block state
|
||||
*/
|
||||
void addEntry(int id);
|
||||
|
||||
/**
|
||||
* Clears the palette.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Returns the type of data this palette holds.
|
||||
*
|
||||
* @return type of data this palette holds
|
||||
*/
|
||||
PaletteType type();
|
||||
}
|
||||
|
@ -32,18 +32,15 @@ public final class DataPaletteImpl implements DataPalette {
|
||||
private final IntList palette;
|
||||
private final Int2IntMap inversePalette;
|
||||
private final int[] values;
|
||||
private final PaletteType type;
|
||||
|
||||
public DataPaletteImpl(final PaletteType type) {
|
||||
this.type = type;
|
||||
public DataPaletteImpl() {
|
||||
this.values = new int[ChunkSection.SIZE];
|
||||
palette = new IntArrayList();
|
||||
inversePalette = new Int2IntOpenHashMap();
|
||||
inversePalette.defaultReturnValue(-1);
|
||||
}
|
||||
|
||||
public DataPaletteImpl(final PaletteType type, final int expectedPaletteLength) {
|
||||
this.type = type;
|
||||
public DataPaletteImpl(final int expectedPaletteLength) {
|
||||
this.values = new int[ChunkSection.SIZE];
|
||||
// Pre-size the palette array/map
|
||||
palette = new IntArrayList(expectedPaletteLength);
|
||||
@ -52,13 +49,13 @@ public final class DataPaletteImpl implements DataPalette {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int value(final int idx) {
|
||||
final int index = values[idx];
|
||||
public int idAt(final int sectionCoordinate) {
|
||||
final int index = values[sectionCoordinate];
|
||||
return palette.getInt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(final int idx, final int id) {
|
||||
public void setIdAt(final int sectionCoordinate, final int id) {
|
||||
int index = inversePalette.get(id);
|
||||
if (index == -1) {
|
||||
index = palette.size();
|
||||
@ -66,17 +63,17 @@ public final class DataPaletteImpl implements DataPalette {
|
||||
inversePalette.put(id, index);
|
||||
}
|
||||
|
||||
values[idx] = index;
|
||||
values[sectionCoordinate] = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int index(final int idx) {
|
||||
return values[idx];
|
||||
public int paletteIndexAt(final int packedCoordinate) {
|
||||
return values[packedCoordinate];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIndex(final int idx, final int index) {
|
||||
values[idx] = index;
|
||||
public void setPaletteIndexAt(final int sectionCoordinate, final int index) {
|
||||
values[sectionCoordinate] = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -85,12 +82,12 @@ public final class DataPaletteImpl implements DataPalette {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int entry(final int index) {
|
||||
public int idByIndex(final int index) {
|
||||
return palette.getInt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntry(final int index, final int id) {
|
||||
public void setIdByIndex(final int index, final int id) {
|
||||
final int oldId = palette.set(index, id);
|
||||
if (oldId == id) return;
|
||||
|
||||
@ -107,7 +104,7 @@ public final class DataPaletteImpl implements DataPalette {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceEntry(final int oldId, final int newId) {
|
||||
public void replaceId(final int oldId, final int newId) {
|
||||
final int index = inversePalette.remove(oldId);
|
||||
if (index == -1) return;
|
||||
|
||||
@ -120,7 +117,7 @@ public final class DataPaletteImpl implements DataPalette {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntry(final int id) {
|
||||
public void addId(final int id) {
|
||||
inversePalette.put(id, palette.size());
|
||||
palette.add(id);
|
||||
}
|
||||
@ -130,9 +127,4 @@ public final class DataPaletteImpl implements DataPalette {
|
||||
palette.clear();
|
||||
inversePalette.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaletteType type() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
@ -24,15 +24,11 @@ package com.viaversion.viaversion.api.type.types.version;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSectionImpl;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.DataPaletteImpl;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.util.CompactArrayUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class ChunkSectionType1_18 extends Type<ChunkSection> {
|
||||
private static final int GLOBAL_PALETTE = 15;
|
||||
public final class ChunkSectionType1_18 extends Type<ChunkSection> {
|
||||
|
||||
public ChunkSectionType1_18() {
|
||||
super("Chunk Section Type", ChunkSection.class);
|
||||
@ -42,100 +38,15 @@ public class ChunkSectionType1_18 extends Type<ChunkSection> {
|
||||
public ChunkSection read(final ByteBuf buffer) throws Exception {
|
||||
final ChunkSection chunkSection = new ChunkSectionImpl();
|
||||
chunkSection.setNonAirBlocksCount(buffer.readShort());
|
||||
chunkSection.addPalette(readPalette(buffer, PaletteType.BLOCKS));
|
||||
chunkSection.addPalette(readPalette(buffer, PaletteType.BIOMES));
|
||||
chunkSection.addPalette(PaletteType.BLOCKS, Types1_18.BLOCK_PALETTE_TYPE.read(buffer));
|
||||
chunkSection.addPalette(PaletteType.BIOMES, Types1_18.BIOME_PALETTE_TYPE.read(buffer));
|
||||
return chunkSection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final ChunkSection section) throws Exception {
|
||||
buffer.writeShort(section.getNonAirBlocksCount());
|
||||
writePalette(buffer, section.palette(PaletteType.BLOCKS));
|
||||
writePalette(buffer, section.palette(PaletteType.BIOMES));
|
||||
}
|
||||
|
||||
private DataPalette readPalette(final ByteBuf buffer, final PaletteType type) {
|
||||
int bitsPerValue = buffer.readByte();
|
||||
final int originalBitsPerValue = bitsPerValue;
|
||||
|
||||
if (bitsPerValue > type.highestBitsPerValue()) {
|
||||
bitsPerValue = GLOBAL_PALETTE;
|
||||
}
|
||||
|
||||
// Read palette
|
||||
final DataPaletteImpl palette;
|
||||
if (bitsPerValue == 0) {
|
||||
//TODO Create proper singleton palette Object
|
||||
palette = new DataPaletteImpl(type, 1);
|
||||
palette.addEntry(Type.VAR_INT.readPrimitive(buffer));
|
||||
Type.VAR_INT.readPrimitive(buffer); // 0 values length
|
||||
return palette;
|
||||
}
|
||||
|
||||
if (bitsPerValue != GLOBAL_PALETTE) {
|
||||
final int paletteLength = Type.VAR_INT.readPrimitive(buffer);
|
||||
palette = new DataPaletteImpl(type, paletteLength);
|
||||
for (int i = 0; i < paletteLength; i++) {
|
||||
palette.addEntry(Type.VAR_INT.readPrimitive(buffer));
|
||||
}
|
||||
} else {
|
||||
palette = new DataPaletteImpl(type);
|
||||
}
|
||||
|
||||
// Read values
|
||||
final long[] values = new long[Type.VAR_INT.readPrimitive(buffer)];
|
||||
if (values.length > 0) {
|
||||
final char valuesPerLong = (char) (64 / bitsPerValue);
|
||||
final int expectedLength = (ChunkSection.SIZE + valuesPerLong - 1) / valuesPerLong;
|
||||
if (values.length != expectedLength) {
|
||||
throw new IllegalStateException("Palette data length (" + values.length + ") does not match expected length (" + expectedLength + ")! bitsPerValue=" + bitsPerValue + ", originalBitsPerValue=" + originalBitsPerValue);
|
||||
}
|
||||
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = buffer.readLong();
|
||||
}
|
||||
CompactArrayUtil.iterateCompactArrayWithPadding(bitsPerValue, ChunkSection.SIZE, values,
|
||||
bitsPerValue == GLOBAL_PALETTE ? palette::setValue : palette::setIndex);
|
||||
}
|
||||
return palette;
|
||||
}
|
||||
|
||||
private void writePalette(final ByteBuf buffer, final DataPalette palette) {
|
||||
int bitsPerValue;
|
||||
if (palette.size() > 1) {
|
||||
bitsPerValue = palette.type() == PaletteType.BLOCKS ? 4 : 2; //TODO implement linear palette
|
||||
while (palette.size() > 1 << bitsPerValue) {
|
||||
bitsPerValue += 1;
|
||||
}
|
||||
|
||||
if (bitsPerValue > palette.type().highestBitsPerValue()) {
|
||||
bitsPerValue = GLOBAL_PALETTE;
|
||||
}
|
||||
} else {
|
||||
bitsPerValue = 0;
|
||||
}
|
||||
|
||||
buffer.writeByte(bitsPerValue);
|
||||
|
||||
if (bitsPerValue == 0) {
|
||||
// Write single value
|
||||
Type.VAR_INT.writePrimitive(buffer, palette.entry(0));
|
||||
Type.VAR_INT.writePrimitive(buffer, 0); // Empty values length
|
||||
return;
|
||||
}
|
||||
|
||||
if (bitsPerValue != GLOBAL_PALETTE) {
|
||||
// Write pallete
|
||||
Type.VAR_INT.writePrimitive(buffer, palette.size());
|
||||
for (int i = 0; i < palette.size(); i++) {
|
||||
Type.VAR_INT.writePrimitive(buffer, palette.entry(i));
|
||||
}
|
||||
}
|
||||
|
||||
final long[] data = CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, ChunkSection.SIZE, bitsPerValue == GLOBAL_PALETTE ? palette::value : palette::index);
|
||||
Type.VAR_INT.writePrimitive(buffer, data.length);
|
||||
for (final long l : data) {
|
||||
buffer.writeLong(l);
|
||||
}
|
||||
Types1_18.BLOCK_PALETTE_TYPE.write(buffer, section.palette(PaletteType.BLOCKS));
|
||||
Types1_18.BIOME_PALETTE_TYPE.write(buffer, section.palette(PaletteType.BIOMES));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2021 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.type.types.version;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.DataPaletteImpl;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
|
||||
import com.viaversion.viaversion.api.type.PartialType;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.util.CompactArrayUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public final class PaletteType1_18 extends PartialType<DataPalette, PaletteType> {
|
||||
private static final int GLOBAL_PALETTE = 15;
|
||||
|
||||
public PaletteType1_18(final PaletteType type) {
|
||||
super(type, DataPalette.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataPalette read(final ByteBuf buffer, final PaletteType type) throws Exception {
|
||||
int bitsPerValue = buffer.readByte();
|
||||
final int originalBitsPerValue = bitsPerValue;
|
||||
|
||||
if (bitsPerValue > type.highestBitsPerValue()) {
|
||||
bitsPerValue = GLOBAL_PALETTE;
|
||||
}
|
||||
|
||||
// Read palette
|
||||
final DataPaletteImpl palette;
|
||||
if (bitsPerValue == 0) {
|
||||
//TODO Create proper singleton palette Object
|
||||
palette = new DataPaletteImpl(1);
|
||||
palette.addId(Type.VAR_INT.readPrimitive(buffer));
|
||||
Type.VAR_INT.readPrimitive(buffer); // 0 values length
|
||||
return palette;
|
||||
}
|
||||
|
||||
if (bitsPerValue != GLOBAL_PALETTE) {
|
||||
final int paletteLength = Type.VAR_INT.readPrimitive(buffer);
|
||||
palette = new DataPaletteImpl(paletteLength);
|
||||
for (int i = 0; i < paletteLength; i++) {
|
||||
palette.addId(Type.VAR_INT.readPrimitive(buffer));
|
||||
}
|
||||
} else {
|
||||
palette = new DataPaletteImpl();
|
||||
}
|
||||
|
||||
// Read values
|
||||
final long[] values = new long[Type.VAR_INT.readPrimitive(buffer)];
|
||||
if (values.length > 0) {
|
||||
final char valuesPerLong = (char) (64 / bitsPerValue);
|
||||
final int expectedLength = (ChunkSection.SIZE + valuesPerLong - 1) / valuesPerLong;
|
||||
if (values.length != expectedLength) {
|
||||
throw new IllegalStateException("Palette data length (" + values.length + ") does not match expected length (" + expectedLength + ")! bitsPerValue=" + bitsPerValue + ", originalBitsPerValue=" + originalBitsPerValue);
|
||||
}
|
||||
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = buffer.readLong();
|
||||
}
|
||||
CompactArrayUtil.iterateCompactArrayWithPadding(bitsPerValue, ChunkSection.SIZE, values,
|
||||
bitsPerValue == GLOBAL_PALETTE ? palette::setIdAt : palette::setPaletteIndexAt);
|
||||
}
|
||||
return palette;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final PaletteType type, final DataPalette palette) throws Exception {
|
||||
int bitsPerValue;
|
||||
if (palette.size() > 1) {
|
||||
bitsPerValue = type == PaletteType.BLOCKS ? 4 : 2; //TODO implement linear palette
|
||||
while (palette.size() > 1 << bitsPerValue) {
|
||||
bitsPerValue += 1;
|
||||
}
|
||||
|
||||
if (bitsPerValue > type.highestBitsPerValue()) {
|
||||
bitsPerValue = GLOBAL_PALETTE;
|
||||
}
|
||||
} else {
|
||||
bitsPerValue = 0;
|
||||
}
|
||||
|
||||
buffer.writeByte(bitsPerValue);
|
||||
|
||||
if (bitsPerValue == 0) {
|
||||
// Write single value
|
||||
Type.VAR_INT.writePrimitive(buffer, palette.idByIndex(0));
|
||||
Type.VAR_INT.writePrimitive(buffer, 0); // Empty values length
|
||||
return;
|
||||
}
|
||||
|
||||
if (bitsPerValue != GLOBAL_PALETTE) {
|
||||
// Write pallete
|
||||
Type.VAR_INT.writePrimitive(buffer, palette.size());
|
||||
for (int i = 0; i < palette.size(); i++) {
|
||||
Type.VAR_INT.writePrimitive(buffer, palette.idByIndex(i));
|
||||
}
|
||||
}
|
||||
|
||||
final long[] data = CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, ChunkSection.SIZE, bitsPerValue == GLOBAL_PALETTE ? palette::idAt : palette::paletteIndexAt);
|
||||
Type.VAR_INT.writePrimitive(buffer, data.length);
|
||||
for (final long l : data) {
|
||||
buffer.writeLong(l);
|
||||
}
|
||||
}
|
||||
}
|
@ -24,10 +24,14 @@ package com.viaversion.viaversion.api.type.types.version;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
|
||||
public final class Types1_18 {
|
||||
|
||||
public static final Type<ChunkSection> CHUNK_SECTION = new ChunkSectionType1_18();
|
||||
public static final Type<BlockEntity> BLOCK_ENTITY = new BlockEntityType1_18();
|
||||
public static final Type<DataPalette> BLOCK_PALETTE_TYPE = new PaletteType1_18(PaletteType.BLOCKS);
|
||||
public static final Type<DataPalette> BIOME_PALETTE_TYPE = new PaletteType1_18(PaletteType.BIOMES);
|
||||
}
|
||||
|
@ -132,9 +132,9 @@ public final class WorldPackets {
|
||||
sections[i] = section;
|
||||
section.setNonAirBlocksCount(0);
|
||||
|
||||
final DataPaletteImpl blockPalette = new DataPaletteImpl(PaletteType.BLOCKS);
|
||||
blockPalette.addEntry(0);
|
||||
section.addPalette(blockPalette);
|
||||
final DataPaletteImpl blockPalette = new DataPaletteImpl();
|
||||
blockPalette.addId(0);
|
||||
section.addPalette(PaletteType.BLOCKS, blockPalette);
|
||||
} else {
|
||||
/*final DataPalette blockpalette = section.palette(PaletteType.BLOCKS);
|
||||
for (int j = 0; j < blockpalette.size(); j++) {
|
||||
@ -145,8 +145,8 @@ public final class WorldPackets {
|
||||
|
||||
// Fill biome palette
|
||||
//TODO Use single value palette if given the possibility
|
||||
final DataPaletteImpl biomePalette = new DataPaletteImpl(PaletteType.BIOMES);
|
||||
section.addPalette(biomePalette);
|
||||
final DataPaletteImpl biomePalette = new DataPaletteImpl();
|
||||
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 minX = (biomeIndex & HORIZONTAL_MASK) << 2;
|
||||
@ -155,7 +155,7 @@ public final class WorldPackets {
|
||||
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.setValue(x, y, z, biome);
|
||||
biomePalette.setIdAt(x, y, z, biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren