3
0
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:
Myles 2019-10-24 21:49:31 +01:00 committet von GitHub
Commit a8d0a4dd14
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
5 geänderte Dateien mit 67 neuen und 94 gelöschten Zeilen

Datei anzeigen

@ -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);
} }

Datei anzeigen

@ -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);
} }

Datei anzeigen

@ -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) {

Datei anzeigen

@ -0,0 +1,6 @@
package us.myles.ViaVersion.util;
@FunctionalInterface
public interface BiIntConsumer {
void consume(int i1, int i2);
}

Datei anzeigen

@ -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);
}
}
}