Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-26 00:00:28 +01:00
Merge pull request #1491 from creeper123123321/abstraction
deduplicate minecraft compact array code/decode
Dieser Commit ist enthalten in:
Commit
a8d0a4dd14
@ -3,6 +3,7 @@ package us.myles.ViaVersion.api.type.types.version;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
||||||
import us.myles.ViaVersion.api.type.Type;
|
import us.myles.ViaVersion.api.type.Type;
|
||||||
|
import us.myles.ViaVersion.util.CompactArrayUtil;
|
||||||
|
|
||||||
public class ChunkSectionType1_13 extends Type<ChunkSection> {
|
public class ChunkSectionType1_13 extends Type<ChunkSection> {
|
||||||
private static final int GLOBAL_PALETTE = 14;
|
private static final int GLOBAL_PALETTE = 14;
|
||||||
@ -23,8 +24,6 @@ public class ChunkSectionType1_13 extends Type<ChunkSection> {
|
|||||||
bitsPerBlock = GLOBAL_PALETTE;
|
bitsPerBlock = GLOBAL_PALETTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
long maxEntryValue = (1L << bitsPerBlock) - 1;
|
|
||||||
|
|
||||||
int paletteLength = bitsPerBlock == GLOBAL_PALETTE ? 0 : Type.VAR_INT.read(buffer);
|
int paletteLength = bitsPerBlock == GLOBAL_PALETTE ? 0 : Type.VAR_INT.read(buffer);
|
||||||
// Read palette
|
// Read palette
|
||||||
chunkSection.clearPalette();
|
chunkSection.clearPalette();
|
||||||
@ -43,25 +42,8 @@ public class ChunkSectionType1_13 extends Type<ChunkSection> {
|
|||||||
for (int i = 0; i < blockData.length; i++) {
|
for (int i = 0; i < blockData.length; i++) {
|
||||||
blockData[i] = buffer.readLong();
|
blockData[i] = buffer.readLong();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < ChunkSection.SIZE; i++) {
|
CompactArrayUtil.iterateCompactArray(bitsPerBlock, ChunkSection.SIZE, blockData,
|
||||||
int bitIndex = i * bitsPerBlock;
|
bitsPerBlock == GLOBAL_PALETTE ? chunkSection::setFlatBlock : chunkSection::setPaletteIndex);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return chunkSection;
|
return chunkSection;
|
||||||
@ -78,7 +60,6 @@ public class ChunkSectionType1_13 extends Type<ChunkSection> {
|
|||||||
bitsPerBlock = GLOBAL_PALETTE;
|
bitsPerBlock = GLOBAL_PALETTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
long maxEntryValue = (1L << bitsPerBlock) - 1;
|
|
||||||
buffer.writeByte(bitsPerBlock);
|
buffer.writeByte(bitsPerBlock);
|
||||||
|
|
||||||
// Write pallet (or not)
|
// Write pallet (or not)
|
||||||
@ -89,21 +70,9 @@ public class ChunkSectionType1_13 extends Type<ChunkSection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int length = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0);
|
long[] data = CompactArrayUtil.createCompactArray(bitsPerBlock, ChunkSection.SIZE,
|
||||||
Type.VAR_INT.write(buffer, length);
|
bitsPerBlock == GLOBAL_PALETTE ? chunkSection::getFlatBlock : chunkSection::getPaletteIndex);
|
||||||
long[] data = new long[length];
|
Type.VAR_INT.write(buffer, data.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (long l : data) {
|
for (long l : data) {
|
||||||
buffer.writeLong(l);
|
buffer.writeLong(l);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package us.myles.ViaVersion.api.type.types.version;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
||||||
import us.myles.ViaVersion.api.type.Type;
|
import us.myles.ViaVersion.api.type.Type;
|
||||||
|
import us.myles.ViaVersion.util.CompactArrayUtil;
|
||||||
|
|
||||||
public class ChunkSectionType1_9 extends Type<ChunkSection> {
|
public class ChunkSectionType1_9 extends Type<ChunkSection> {
|
||||||
private static final int GLOBAL_PALETTE = 13;
|
private static final int GLOBAL_PALETTE = 13;
|
||||||
@ -18,7 +19,6 @@ public class ChunkSectionType1_9 extends Type<ChunkSection> {
|
|||||||
// Reaad bits per block
|
// Reaad bits per block
|
||||||
int bitsPerBlock = buffer.readUnsignedByte();
|
int bitsPerBlock = buffer.readUnsignedByte();
|
||||||
int originalBitsPerBlock = bitsPerBlock;
|
int originalBitsPerBlock = bitsPerBlock;
|
||||||
long maxEntryValue = (1L << bitsPerBlock) - 1;
|
|
||||||
|
|
||||||
if (bitsPerBlock == 0) {
|
if (bitsPerBlock == 0) {
|
||||||
bitsPerBlock = GLOBAL_PALETTE;
|
bitsPerBlock = GLOBAL_PALETTE;
|
||||||
@ -51,25 +51,9 @@ public class ChunkSectionType1_9 extends Type<ChunkSection> {
|
|||||||
for (int i = 0; i < blockData.length; i++) {
|
for (int i = 0; i < blockData.length; i++) {
|
||||||
blockData[i] = buffer.readLong();
|
blockData[i] = buffer.readLong();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < ChunkSection.SIZE; i++) {
|
CompactArrayUtil.iterateCompactArray(bitsPerBlock, ChunkSection.SIZE, blockData,
|
||||||
int bitIndex = i * bitsPerBlock;
|
bitsPerBlock == GLOBAL_PALETTE ? chunkSection::setFlatBlock
|
||||||
int startIndex = bitIndex / 64;
|
: chunkSection::setPaletteIndex);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return chunkSection;
|
return chunkSection;
|
||||||
@ -99,21 +83,9 @@ public class ChunkSectionType1_9 extends Type<ChunkSection> {
|
|||||||
Type.VAR_INT.write(buffer, 0);
|
Type.VAR_INT.write(buffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int length = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0);
|
long[] data = CompactArrayUtil.createCompactArray(bitsPerBlock, ChunkSection.SIZE,
|
||||||
Type.VAR_INT.write(buffer, length);
|
bitsPerBlock == GLOBAL_PALETTE ? chunkSection::getFlatBlock : chunkSection::getPaletteIndex);
|
||||||
long[] data = new long[length];
|
Type.VAR_INT.write(buffer, data.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (long l : data) {
|
for (long l : data) {
|
||||||
buffer.writeLong(l);
|
buffer.writeLong(l);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
|||||||
import com.github.steveice10.opennbt.tag.builtin.LongArrayTag;
|
import com.github.steveice10.opennbt.tag.builtin.LongArrayTag;
|
||||||
import us.myles.ViaVersion.api.PacketWrapper;
|
import us.myles.ViaVersion.api.PacketWrapper;
|
||||||
import us.myles.ViaVersion.api.Via;
|
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.entities.Entity1_14Types;
|
||||||
import us.myles.ViaVersion.api.minecraft.BlockChangeRecord;
|
import us.myles.ViaVersion.api.minecraft.BlockChangeRecord;
|
||||||
import us.myles.ViaVersion.api.minecraft.BlockFace;
|
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.api.type.Type;
|
||||||
import us.myles.ViaVersion.packets.State;
|
import us.myles.ViaVersion.packets.State;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types.Chunk1_13Type;
|
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.Protocol1_14To1_13_2;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData;
|
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.storage.EntityTracker1_14;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.types.Chunk1_14Type;
|
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.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||||
|
import us.myles.ViaVersion.util.CompactArrayUtil;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@ -435,26 +435,7 @@ public class WorldPackets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static long[] encodeHeightMap(int[] heightMap) {
|
private static long[] encodeHeightMap(int[] heightMap) {
|
||||||
final int bitsPerBlock = 9;
|
return CompactArrayUtil.createCompactArray(9, heightMap.length, i -> heightMap[i]);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setNonFullLight(Chunk chunk, ChunkSection section, int ySection, int x, int y, int z) {
|
private static void setNonFullLight(Chunk chunk, ChunkSection section, int ySection, int x, int y, int z) {
|
||||||
|
6
common/src/main/java/us/myles/ViaVersion/util/BiIntConsumer.java
Normale Datei
6
common/src/main/java/us/myles/ViaVersion/util/BiIntConsumer.java
Normale Datei
@ -0,0 +1,6 @@
|
|||||||
|
package us.myles.ViaVersion.util;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface BiIntConsumer {
|
||||||
|
void consume(int i1, int i2);
|
||||||
|
}
|
45
common/src/main/java/us/myles/ViaVersion/util/CompactArrayUtil.java
Normale Datei
45
common/src/main/java/us/myles/ViaVersion/util/CompactArrayUtil.java
Normale Datei
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren