mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-11-23 02:25:19 +01:00
deduplicate minecraft compact array code/decode
This commit is contained in:
parent
28b7f6febc
commit
005c91eb4d
@ -3,6 +3,7 @@ package us.myles.ViaVersion.api.type.types.version;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.util.CompactArrayUtil;
|
||||
|
||||
public class ChunkSectionType1_13 extends Type<ChunkSection> {
|
||||
private static final int GLOBAL_PALETTE = 14;
|
||||
@ -23,8 +24,6 @@ public class ChunkSectionType1_13 extends Type<ChunkSection> {
|
||||
bitsPerBlock = GLOBAL_PALETTE;
|
||||
}
|
||||
|
||||
long maxEntryValue = (1L << bitsPerBlock) - 1;
|
||||
|
||||
int paletteLength = bitsPerBlock == GLOBAL_PALETTE ? 0 : Type.VAR_INT.read(buffer);
|
||||
// Read palette
|
||||
chunkSection.clearPalette();
|
||||
@ -43,25 +42,9 @@ public class ChunkSectionType1_13 extends Type<ChunkSection> {
|
||||
for (int i = 0; i < blockData.length; i++) {
|
||||
blockData[i] = buffer.readLong();
|
||||
}
|
||||
for (int i = 0; i < ChunkSection.SIZE; i++) {
|
||||
int bitIndex = i * bitsPerBlock;
|
||||
int startIndex = bitIndex / 64;
|
||||
int endIndex = ((i + 1) * bitsPerBlock - 1) / 64;
|
||||
int startBitSubIndex = bitIndex % 64;
|
||||
int val;
|
||||
if (startIndex == endIndex) {
|
||||
val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue);
|
||||
} else {
|
||||
int endBitSubIndex = 64 - startBitSubIndex;
|
||||
val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue);
|
||||
}
|
||||
|
||||
if (bitsPerBlock == GLOBAL_PALETTE) {
|
||||
chunkSection.setFlatBlock(i, val);
|
||||
} else {
|
||||
chunkSection.setPaletteIndex(i, val);
|
||||
}
|
||||
}
|
||||
CompactArrayUtil.iterateCompactArray(bitsPerBlock, ChunkSection.SIZE, blockData,
|
||||
bitsPerBlock == GLOBAL_PALETTE ? (i, val) -> chunkSection.setBlock(i, val >> 4, val & 0xF)
|
||||
: chunkSection::setPaletteIndex);
|
||||
}
|
||||
|
||||
return chunkSection;
|
||||
@ -78,7 +61,6 @@ public class ChunkSectionType1_13 extends Type<ChunkSection> {
|
||||
bitsPerBlock = GLOBAL_PALETTE;
|
||||
}
|
||||
|
||||
long maxEntryValue = (1L << bitsPerBlock) - 1;
|
||||
buffer.writeByte(bitsPerBlock);
|
||||
|
||||
// Write pallet (or not)
|
||||
@ -89,21 +71,9 @@ public class ChunkSectionType1_13 extends Type<ChunkSection> {
|
||||
}
|
||||
}
|
||||
|
||||
int length = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0);
|
||||
Type.VAR_INT.write(buffer, length);
|
||||
long[] data = new long[length];
|
||||
for (int index = 0; index < ChunkSection.SIZE; index++) {
|
||||
int value = bitsPerBlock == GLOBAL_PALETTE ? chunkSection.getFlatBlock(index) : chunkSection.getPaletteIndex(index);
|
||||
int bitIndex = index * bitsPerBlock;
|
||||
int startIndex = bitIndex / 64;
|
||||
int endIndex = ((index + 1) * bitsPerBlock - 1) / 64;
|
||||
int startBitSubIndex = bitIndex % 64;
|
||||
data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex;
|
||||
if (startIndex != endIndex) {
|
||||
int endBitSubIndex = 64 - startBitSubIndex;
|
||||
data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex;
|
||||
}
|
||||
}
|
||||
long[] data = CompactArrayUtil.createCompactArray(bitsPerBlock, ChunkSection.SIZE,
|
||||
bitsPerBlock == GLOBAL_PALETTE ? chunkSection::getFlatBlock : chunkSection::getPaletteIndex);
|
||||
Type.VAR_INT.write(buffer, data.length);
|
||||
for (long l : data) {
|
||||
buffer.writeLong(l);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package us.myles.ViaVersion.api.type.types.version;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.util.CompactArrayUtil;
|
||||
|
||||
public class ChunkSectionType1_9 extends Type<ChunkSection> {
|
||||
private static final int GLOBAL_PALETTE = 13;
|
||||
@ -18,7 +19,6 @@ public class ChunkSectionType1_9 extends Type<ChunkSection> {
|
||||
// Reaad bits per block
|
||||
int bitsPerBlock = buffer.readUnsignedByte();
|
||||
int originalBitsPerBlock = bitsPerBlock;
|
||||
long maxEntryValue = (1L << bitsPerBlock) - 1;
|
||||
|
||||
if (bitsPerBlock == 0) {
|
||||
bitsPerBlock = GLOBAL_PALETTE;
|
||||
@ -51,25 +51,9 @@ public class ChunkSectionType1_9 extends Type<ChunkSection> {
|
||||
for (int i = 0; i < blockData.length; i++) {
|
||||
blockData[i] = buffer.readLong();
|
||||
}
|
||||
for (int i = 0; i < ChunkSection.SIZE; i++) {
|
||||
int bitIndex = i * bitsPerBlock;
|
||||
int startIndex = bitIndex / 64;
|
||||
int endIndex = ((i + 1) * bitsPerBlock - 1) / 64;
|
||||
int startBitSubIndex = bitIndex % 64;
|
||||
int val;
|
||||
if (startIndex == endIndex) {
|
||||
val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue);
|
||||
} else {
|
||||
int endBitSubIndex = 64 - startBitSubIndex;
|
||||
val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue);
|
||||
}
|
||||
|
||||
if (bitsPerBlock == GLOBAL_PALETTE) {
|
||||
chunkSection.setBlock(i, val >> 4, val & 0xF);
|
||||
} else {
|
||||
chunkSection.setPaletteIndex(i, val);
|
||||
}
|
||||
}
|
||||
CompactArrayUtil.iterateCompactArray(bitsPerBlock, ChunkSection.SIZE, blockData,
|
||||
bitsPerBlock == GLOBAL_PALETTE ? (i, val) -> chunkSection.setBlock(i, val >> 4, val & 0xF)
|
||||
: chunkSection::setPaletteIndex);
|
||||
}
|
||||
|
||||
return chunkSection;
|
||||
@ -99,21 +83,9 @@ public class ChunkSectionType1_9 extends Type<ChunkSection> {
|
||||
Type.VAR_INT.write(buffer, 0);
|
||||
}
|
||||
|
||||
int length = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0);
|
||||
Type.VAR_INT.write(buffer, length);
|
||||
long[] data = new long[length];
|
||||
for (int index = 0; index < ChunkSection.SIZE; index++) {
|
||||
int value = bitsPerBlock == GLOBAL_PALETTE ? chunkSection.getFlatBlock(index) : chunkSection.getPaletteIndex(index);
|
||||
int bitIndex = index * bitsPerBlock;
|
||||
int startIndex = bitIndex / 64;
|
||||
int endIndex = ((index + 1) * bitsPerBlock - 1) / 64;
|
||||
int startBitSubIndex = bitIndex % 64;
|
||||
data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex;
|
||||
if (startIndex != endIndex) {
|
||||
int endBitSubIndex = 64 - startBitSubIndex;
|
||||
data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex;
|
||||
}
|
||||
}
|
||||
long[] data = CompactArrayUtil.createCompactArray(bitsPerBlock, ChunkSection.SIZE,
|
||||
bitsPerBlock == GLOBAL_PALETTE ? chunkSection::getFlatBlock : chunkSection::getPaletteIndex);
|
||||
Type.VAR_INT.write(buffer, data.length);
|
||||
for (long l : data) {
|
||||
buffer.writeLong(l);
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.LongArrayTag;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.entities.Entity1_14Types;
|
||||
import us.myles.ViaVersion.api.minecraft.BlockChangeRecord;
|
||||
import us.myles.ViaVersion.api.minecraft.BlockFace;
|
||||
@ -18,12 +17,13 @@ import us.myles.ViaVersion.api.remapper.ValueCreator;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types.Chunk1_13Type;
|
||||
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.metadata.MetadataRewriter1_14To1_13_2;
|
||||
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.Protocol1_14To1_13_2;
|
||||
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData;
|
||||
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.metadata.MetadataRewriter1_14To1_13_2;
|
||||
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.storage.EntityTracker1_14;
|
||||
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.types.Chunk1_14Type;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||
import us.myles.ViaVersion.util.CompactArrayUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@ -435,26 +435,7 @@ public class WorldPackets {
|
||||
}
|
||||
|
||||
private static long[] encodeHeightMap(int[] heightMap) {
|
||||
final int bitsPerBlock = 9;
|
||||
long maxEntryValue = (1L << bitsPerBlock) - 1;
|
||||
|
||||
int length = (int) Math.ceil(heightMap.length * bitsPerBlock / 64.0);
|
||||
long[] data = new long[length];
|
||||
|
||||
for (int index = 0; index < heightMap.length; index++) {
|
||||
int value = heightMap[index];
|
||||
int bitIndex = index * 9;
|
||||
int startIndex = bitIndex / 64;
|
||||
int endIndex = ((index + 1) * bitsPerBlock - 1) / 64;
|
||||
int startBitSubIndex = bitIndex % 64;
|
||||
data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex;
|
||||
if (startIndex != endIndex) {
|
||||
int endBitSubIndex = 64 - startBitSubIndex;
|
||||
data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
return CompactArrayUtil.createCompactArray(9, heightMap.length, i -> heightMap[i]);
|
||||
}
|
||||
|
||||
private static void setNonFullLight(Chunk chunk, ChunkSection section, int ySection, int x, int y, int z) {
|
||||
|
@ -0,0 +1,6 @@
|
||||
package us.myles.ViaVersion.util;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BiIntConsumer {
|
||||
void consume(int i1, int i2);
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package us.myles.ViaVersion.util;
|
||||
|
||||
import java.util.function.IntToLongFunction;
|
||||
|
||||
public class CompactArrayUtil {
|
||||
private CompactArrayUtil() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public static long[] createCompactArray(int bitsPerEntry, int entries, IntToLongFunction valueGetter) {
|
||||
long maxEntryValue = (1L << bitsPerEntry) - 1;
|
||||
long[] data = new long[(int) Math.ceil(entries * bitsPerEntry / 64.0)];
|
||||
for (int index = 0; index < entries; index++) {
|
||||
long value = valueGetter.applyAsLong(index);
|
||||
int bitIndex = index * bitsPerEntry;
|
||||
int startIndex = bitIndex / 64;
|
||||
int endIndex = ((index + 1) * bitsPerEntry - 1) / 64;
|
||||
int startBitSubIndex = bitIndex % 64;
|
||||
data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | (value & maxEntryValue) << startBitSubIndex;
|
||||
if (startIndex != endIndex) {
|
||||
int endBitSubIndex = 64 - startBitSubIndex;
|
||||
data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | (value & maxEntryValue) >> endBitSubIndex;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public static void iterateCompactArray(int bitsPerEntry, int entries, long[] data, BiIntConsumer consumer) {
|
||||
long maxEntryValue = (1L << bitsPerEntry) - 1;
|
||||
for (int i = 0; i < entries; i++) {
|
||||
int bitIndex = i * bitsPerEntry;
|
||||
int startIndex = bitIndex / 64;
|
||||
int endIndex = ((i + 1) * bitsPerEntry - 1) / 64;
|
||||
int startBitSubIndex = bitIndex % 64;
|
||||
int val;
|
||||
if (startIndex == endIndex) {
|
||||
val = (int) (data[startIndex] >>> startBitSubIndex & maxEntryValue);
|
||||
} else {
|
||||
int endBitSubIndex = 64 - startBitSubIndex;
|
||||
val = (int) ((data[startIndex] >>> startBitSubIndex | data[endIndex] << endBitSubIndex) & maxEntryValue);
|
||||
}
|
||||
consumer.consume(i, val);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user