mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-11-26 03:55:28 +01:00
Read/write palette based on block/biome size variables
This commit is contained in:
parent
c5e27b89af
commit
73093c0ff2
@ -116,6 +116,11 @@ public class IntArrayMappings implements Mappings {
|
|||||||
oldToNew[id] = newId;
|
oldToNew[id] = newId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return oldToNew.length;
|
||||||
|
}
|
||||||
|
|
||||||
public int[] getOldToNew() {
|
public int[] getOldToNew() {
|
||||||
return oldToNew;
|
return oldToNew;
|
||||||
}
|
}
|
||||||
|
@ -40,4 +40,6 @@ public interface Mappings {
|
|||||||
* @throws IndexOutOfBoundsException if the unmapped id is invalid
|
* @throws IndexOutOfBoundsException if the unmapped id is invalid
|
||||||
*/
|
*/
|
||||||
void setNewId(int id, int newId);
|
void setNewId(int id, int newId);
|
||||||
|
|
||||||
|
int size();
|
||||||
}
|
}
|
||||||
|
@ -147,4 +147,8 @@ public interface EntityTracker {
|
|||||||
* @param currentWorld name of the current world
|
* @param currentWorld name of the current world
|
||||||
*/
|
*/
|
||||||
void setCurrentWorld(String currentWorld);
|
void setCurrentWorld(String currentWorld);
|
||||||
|
|
||||||
|
int biomesSent();
|
||||||
|
|
||||||
|
void setBiomesSent(int biomesSent);
|
||||||
}
|
}
|
||||||
|
@ -23,15 +23,21 @@
|
|||||||
package com.viaversion.viaversion.api.minecraft.chunks;
|
package com.viaversion.viaversion.api.minecraft.chunks;
|
||||||
|
|
||||||
public enum PaletteType {
|
public enum PaletteType {
|
||||||
BLOCKS(8),
|
BLOCKS(ChunkSection.SIZE, 8),
|
||||||
BIOMES(2);
|
BIOMES(4 * 4 * 4, 2);
|
||||||
|
|
||||||
|
private final int maxSize;
|
||||||
private final int highestBitsPerValue;
|
private final int highestBitsPerValue;
|
||||||
|
|
||||||
PaletteType(final int highestBitsPerValue) {
|
PaletteType(final int maxSize, final int highestBitsPerValue) {
|
||||||
|
this.maxSize = maxSize;
|
||||||
this.highestBitsPerValue = highestBitsPerValue;
|
this.highestBitsPerValue = highestBitsPerValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int maxSize() {
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
public int highestBitsPerValue() {
|
public int highestBitsPerValue() {
|
||||||
return highestBitsPerValue;
|
return highestBitsPerValue;
|
||||||
}
|
}
|
||||||
|
@ -30,23 +30,28 @@ import io.netty.buffer.ByteBuf;
|
|||||||
|
|
||||||
public final class ChunkSectionType1_18 extends Type<ChunkSection> {
|
public final class ChunkSectionType1_18 extends Type<ChunkSection> {
|
||||||
|
|
||||||
public ChunkSectionType1_18() {
|
private final PaletteType1_18 blockPaletteType;
|
||||||
|
private final PaletteType1_18 biomePaletteType;
|
||||||
|
|
||||||
|
public ChunkSectionType1_18(final int globalPaletteBlockBits, final int globalPaletteBiomeBits) {
|
||||||
super("Chunk Section Type", ChunkSection.class);
|
super("Chunk Section Type", ChunkSection.class);
|
||||||
|
this.blockPaletteType = new PaletteType1_18(PaletteType.BLOCKS, globalPaletteBlockBits);
|
||||||
|
this.biomePaletteType = new PaletteType1_18(PaletteType.BIOMES, globalPaletteBiomeBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChunkSection read(final ByteBuf buffer) throws Exception {
|
public ChunkSection read(final ByteBuf buffer) throws Exception {
|
||||||
final ChunkSection chunkSection = new ChunkSectionImpl();
|
final ChunkSection chunkSection = new ChunkSectionImpl();
|
||||||
chunkSection.setNonAirBlocksCount(buffer.readShort());
|
chunkSection.setNonAirBlocksCount(buffer.readShort());
|
||||||
chunkSection.addPalette(PaletteType.BLOCKS, Types1_18.BLOCK_PALETTE_TYPE.read(buffer));
|
chunkSection.addPalette(PaletteType.BLOCKS, blockPaletteType.read(buffer));
|
||||||
chunkSection.addPalette(PaletteType.BIOMES, Types1_18.BIOME_PALETTE_TYPE.read(buffer));
|
chunkSection.addPalette(PaletteType.BIOMES, biomePaletteType.read(buffer));
|
||||||
return chunkSection;
|
return chunkSection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(final ByteBuf buffer, final ChunkSection section) throws Exception {
|
public void write(final ByteBuf buffer, final ChunkSection section) throws Exception {
|
||||||
buffer.writeShort(section.getNonAirBlocksCount());
|
buffer.writeShort(section.getNonAirBlocksCount());
|
||||||
Types1_18.BLOCK_PALETTE_TYPE.write(buffer, section.palette(PaletteType.BLOCKS));
|
blockPaletteType.write(buffer, section.palette(PaletteType.BLOCKS));
|
||||||
Types1_18.BIOME_PALETTE_TYPE.write(buffer, section.palette(PaletteType.BIOMES));
|
biomePaletteType.write(buffer, section.palette(PaletteType.BIOMES));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,29 +22,30 @@
|
|||||||
*/
|
*/
|
||||||
package com.viaversion.viaversion.api.type.types.version;
|
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.DataPalette;
|
||||||
import com.viaversion.viaversion.api.minecraft.chunks.DataPaletteImpl;
|
import com.viaversion.viaversion.api.minecraft.chunks.DataPaletteImpl;
|
||||||
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
|
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.api.type.Type;
|
||||||
import com.viaversion.viaversion.util.CompactArrayUtil;
|
import com.viaversion.viaversion.util.CompactArrayUtil;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
public final class PaletteType1_18 extends PartialType<DataPalette, PaletteType> {
|
public final class PaletteType1_18 extends Type<DataPalette> {
|
||||||
private static final int GLOBAL_PALETTE = 15;
|
private final int globalPaletteBits;
|
||||||
|
private final PaletteType type;
|
||||||
|
|
||||||
public PaletteType1_18(final PaletteType type) {
|
public PaletteType1_18(final PaletteType type, final int globalPaletteBits) {
|
||||||
super(type, DataPalette.class);
|
super(DataPalette.class);
|
||||||
|
this.globalPaletteBits = globalPaletteBits;
|
||||||
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataPalette read(final ByteBuf buffer, final PaletteType type) throws Exception {
|
public DataPalette read(final ByteBuf buffer) throws Exception {
|
||||||
int bitsPerValue = buffer.readByte();
|
int bitsPerValue = buffer.readByte();
|
||||||
final int originalBitsPerValue = bitsPerValue;
|
final int originalBitsPerValue = bitsPerValue;
|
||||||
|
|
||||||
if (bitsPerValue > type.highestBitsPerValue()) {
|
if (bitsPerValue > type.highestBitsPerValue()) {
|
||||||
bitsPerValue = GLOBAL_PALETTE;
|
bitsPerValue = globalPaletteBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read palette
|
// Read palette
|
||||||
@ -57,7 +58,7 @@ public final class PaletteType1_18 extends PartialType<DataPalette, PaletteType>
|
|||||||
return palette;
|
return palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitsPerValue != GLOBAL_PALETTE) {
|
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(paletteLength);
|
||||||
for (int i = 0; i < paletteLength; i++) {
|
for (int i = 0; i < paletteLength; i++) {
|
||||||
@ -71,7 +72,7 @@ public final class PaletteType1_18 extends PartialType<DataPalette, PaletteType>
|
|||||||
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 = (ChunkSection.SIZE + valuesPerLong - 1) / valuesPerLong;
|
final int expectedLength = (type.maxSize() + 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);
|
||||||
}
|
}
|
||||||
@ -79,14 +80,14 @@ public final class PaletteType1_18 extends PartialType<DataPalette, PaletteType>
|
|||||||
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, ChunkSection.SIZE, values,
|
CompactArrayUtil.iterateCompactArrayWithPadding(bitsPerValue, type.maxSize(), values,
|
||||||
bitsPerValue == GLOBAL_PALETTE ? palette::setIdAt : palette::setPaletteIndexAt);
|
bitsPerValue == globalPaletteBits ? palette::setIdAt : palette::setPaletteIndexAt);
|
||||||
}
|
}
|
||||||
return palette;
|
return palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(final ByteBuf buffer, final PaletteType type, final DataPalette palette) throws Exception {
|
public void write(final ByteBuf buffer, final DataPalette palette) throws Exception {
|
||||||
int bitsPerValue;
|
int bitsPerValue;
|
||||||
if (palette.size() > 1) {
|
if (palette.size() > 1) {
|
||||||
// 1, 2, and 3 bit linear palettes can't be read by the client
|
// 1, 2, and 3 bit linear palettes can't be read by the client
|
||||||
@ -96,7 +97,7 @@ public final class PaletteType1_18 extends PartialType<DataPalette, PaletteType>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bitsPerValue > type.highestBitsPerValue()) {
|
if (bitsPerValue > type.highestBitsPerValue()) {
|
||||||
bitsPerValue = GLOBAL_PALETTE;
|
bitsPerValue = globalPaletteBits;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bitsPerValue = 0;
|
bitsPerValue = 0;
|
||||||
@ -111,7 +112,7 @@ public final class PaletteType1_18 extends PartialType<DataPalette, PaletteType>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitsPerValue != GLOBAL_PALETTE) {
|
if (bitsPerValue != globalPaletteBits) {
|
||||||
// Write pallete
|
// Write pallete
|
||||||
Type.VAR_INT.writePrimitive(buffer, palette.size());
|
Type.VAR_INT.writePrimitive(buffer, palette.size());
|
||||||
for (int i = 0; i < palette.size(); i++) {
|
for (int i = 0; i < palette.size(); i++) {
|
||||||
@ -119,7 +120,7 @@ public final class PaletteType1_18 extends PartialType<DataPalette, PaletteType>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final long[] data = CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, ChunkSection.SIZE, bitsPerValue == GLOBAL_PALETTE ? palette::idAt : palette::paletteIndexAt);
|
final long[] data = CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, type.maxSize(), 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);
|
||||||
|
@ -30,8 +30,5 @@ import com.viaversion.viaversion.api.type.Type;
|
|||||||
|
|
||||||
public final class Types1_18 {
|
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<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);
|
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis
|
|||||||
private int currentWorldSectionHeight = 16;
|
private int currentWorldSectionHeight = 16;
|
||||||
private int currentMinY;
|
private int currentMinY;
|
||||||
private String currentWorld;
|
private String currentWorld;
|
||||||
|
private int biomesSent = -1;
|
||||||
|
|
||||||
public EntityTrackerBase(UserConnection connection, @Nullable EntityType playerType) {
|
public EntityTrackerBase(UserConnection connection, @Nullable EntityType playerType) {
|
||||||
this(connection, playerType, false);
|
this(connection, playerType, false);
|
||||||
@ -147,4 +148,14 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis
|
|||||||
public void setCurrentWorld(final String currentWorld) {
|
public void setCurrentWorld(final String currentWorld) {
|
||||||
this.currentWorld = currentWorld;
|
this.currentWorld = currentWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int biomesSent() {
|
||||||
|
return biomesSent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBiomesSent(int biomesSent) {
|
||||||
|
this.biomesSent = biomesSent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ public final class EntityPackets extends EntityRewriter<Protocol1_18To1_17_1> {
|
|||||||
map(Type.NBT); // Current dimension data
|
map(Type.NBT); // Current dimension data
|
||||||
map(Type.STRING); // World
|
map(Type.STRING); // World
|
||||||
handler(worldDataTrackerHandler(1));
|
handler(worldDataTrackerHandler(1));
|
||||||
|
handler(biomeSizeTracker());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.BlockEntityIds;
|
|||||||
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.Protocol1_18To1_17_1;
|
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.Protocol1_18To1_17_1;
|
||||||
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.storage.ChunkLightStorage;
|
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.storage.ChunkLightStorage;
|
||||||
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.types.Chunk1_18Type;
|
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.types.Chunk1_18Type;
|
||||||
|
import com.viaversion.viaversion.util.MathUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -166,7 +167,9 @@ public final class WorldPackets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final Chunk chunk = new Chunk1_18(oldChunk.getX(), oldChunk.getZ(), oldChunk.getSections(), oldChunk.getHeightMap(), blockEntities);
|
final Chunk chunk = new Chunk1_18(oldChunk.getX(), oldChunk.getZ(), oldChunk.getSections(), oldChunk.getHeightMap(), blockEntities);
|
||||||
wrapper.write(new Chunk1_18Type(tracker.currentWorldSectionHeight()), chunk);
|
wrapper.write(new Chunk1_18Type(tracker.currentWorldSectionHeight(),
|
||||||
|
MathUtil.ceilLog2(protocol.getMappingData().getBlockStateMappings().size()),
|
||||||
|
MathUtil.ceilLog2(tracker.biomesSent())), chunk);
|
||||||
|
|
||||||
// Get and remove light stored, there's only full chunk packets //TODO Only get, not remove if we find out people re-send full chunk packets without re-sending light
|
// Get and remove light stored, there's only full chunk packets //TODO Only get, not remove if we find out people re-send full chunk packets without re-sending light
|
||||||
final ChunkLightStorage lightStorage = wrapper.user().get(ChunkLightStorage.class);
|
final ChunkLightStorage lightStorage = wrapper.user().get(ChunkLightStorage.class);
|
||||||
|
@ -19,12 +19,14 @@ package com.viaversion.viaversion.protocols.protocol1_18to1_17_1.types;
|
|||||||
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.viaversion.viaversion.api.Via;
|
||||||
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
|
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
|
||||||
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
|
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
|
||||||
import com.viaversion.viaversion.api.minecraft.chunks.Chunk1_18;
|
import com.viaversion.viaversion.api.minecraft.chunks.Chunk1_18;
|
||||||
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
|
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
|
||||||
import com.viaversion.viaversion.api.type.Type;
|
import com.viaversion.viaversion.api.type.Type;
|
||||||
import com.viaversion.viaversion.api.type.types.minecraft.BaseChunkType;
|
import com.viaversion.viaversion.api.type.types.minecraft.BaseChunkType;
|
||||||
|
import com.viaversion.viaversion.api.type.types.version.ChunkSectionType1_18;
|
||||||
import com.viaversion.viaversion.api.type.types.version.Types1_18;
|
import com.viaversion.viaversion.api.type.types.version.Types1_18;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
@ -32,11 +34,13 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public final class Chunk1_18Type extends Type<Chunk> {
|
public final class Chunk1_18Type extends Type<Chunk> {
|
||||||
|
private final ChunkSectionType1_18 sectionType;
|
||||||
private final int ySectionCount;
|
private final int ySectionCount;
|
||||||
|
|
||||||
public Chunk1_18Type(final int ySectionCount) {
|
public Chunk1_18Type(final int ySectionCount, final int globalPaletteBlockBits, final int globalPaletteBiomeBits) {
|
||||||
super(Chunk.class);
|
super(Chunk.class);
|
||||||
Preconditions.checkArgument(ySectionCount > 0);
|
Preconditions.checkArgument(ySectionCount > 0);
|
||||||
|
this.sectionType = new ChunkSectionType1_18(globalPaletteBlockBits, globalPaletteBiomeBits);
|
||||||
this.ySectionCount = ySectionCount;
|
this.ySectionCount = ySectionCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,9 +55,12 @@ public final class Chunk1_18Type extends Type<Chunk> {
|
|||||||
final ChunkSection[] sections = new ChunkSection[ySectionCount];
|
final ChunkSection[] sections = new ChunkSection[ySectionCount];
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < ySectionCount; i++) {
|
for (int i = 0; i < ySectionCount; i++) {
|
||||||
sections[i] = Types1_18.CHUNK_SECTION.read(sectionsBuf);
|
sections[i] = sectionType.read(sectionsBuf);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
if (sectionsBuf.readableBytes() > 0) {
|
||||||
|
Via.getPlatform().getLogger().warning("Found " + sectionsBuf.readableBytes() + " more bytes than expected while reading the chunk: " + chunkX + "/" + chunkZ);
|
||||||
|
}
|
||||||
sectionsBuf.release();
|
sectionsBuf.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +83,7 @@ public final class Chunk1_18Type extends Type<Chunk> {
|
|||||||
final ByteBuf sectionBuffer = buffer.alloc().buffer();
|
final ByteBuf sectionBuffer = buffer.alloc().buffer();
|
||||||
try {
|
try {
|
||||||
for (final ChunkSection section : chunk.getSections()) {
|
for (final ChunkSection section : chunk.getSections()) {
|
||||||
Types1_18.CHUNK_SECTION.write(sectionBuffer, section);
|
sectionType.write(sectionBuffer, section);
|
||||||
}
|
}
|
||||||
sectionBuffer.readerIndex(0);
|
sectionBuffer.readerIndex(0);
|
||||||
Type.VAR_INT.writePrimitive(buffer, sectionBuffer.readableBytes());
|
Type.VAR_INT.writePrimitive(buffer, sectionBuffer.readableBytes());
|
||||||
|
@ -19,6 +19,7 @@ package com.viaversion.viaversion.rewriter;
|
|||||||
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.viaversion.viaversion.api.Via;
|
import com.viaversion.viaversion.api.Via;
|
||||||
@ -397,6 +398,15 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PacketHandler biomeSizeTracker() {
|
||||||
|
return wrapper -> {
|
||||||
|
final CompoundTag registry = wrapper.get(Type.NBT, 0);
|
||||||
|
final CompoundTag biomeRegistry = registry.get("minecraft:worldgen/biome");
|
||||||
|
final ListTag biomes = biomeRegistry.get("value");
|
||||||
|
tracker(wrapper.user()).setBiomesSent(biomes.size());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Sub 1.14.1 methods
|
// Sub 1.14.1 methods
|
||||||
|
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||||
|
* Copyright (C) 2016-2021 ViaVersion and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.viaversion.viaversion.util;
|
||||||
|
|
||||||
|
public final class MathUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primitive method to return the ceiled log to the base of 2 for the given number.
|
||||||
|
*
|
||||||
|
* @param i number to ceillog
|
||||||
|
* @return ceiled log2 of the given number
|
||||||
|
*/
|
||||||
|
public static int ceilLog2(final int i) {
|
||||||
|
int j = 1;
|
||||||
|
int k = 0;
|
||||||
|
while (j < i) {
|
||||||
|
j *= 2;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user