Skip to content

Commit

Permalink
Try v9 again
Browse files Browse the repository at this point in the history
Signed-off-by: Joshua Castle <[email protected]>
  • Loading branch information
Kas-tle committed Oct 27, 2023
1 parent e9edc8b commit 3bc6d16
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,20 @@

public class GeyserChunkSection {

// Temporary reversion to v8 as it reduces the frequnecy of https://github.com/GeyserMC/Geyser/issues/4240
// This does not fully resolve the issue so a better solution is still needed
private static final int CHUNK_SECTION_VERSION = 8;
// As of at least 1.19.80
private static final int CHUNK_SECTION_VERSION = 9;

private final BlockStorage[] storage;
// Counts up from 00 for y >= 0 and down from FF for y < 0
private final int subChunkIndex;

public GeyserChunkSection(int airBlockId) {
this(new BlockStorage[]{new BlockStorage(airBlockId), new BlockStorage(airBlockId)});
public GeyserChunkSection(int airBlockId, int subChunkIndex) {
this(new BlockStorage[]{new BlockStorage(airBlockId), new BlockStorage(airBlockId)}, subChunkIndex);
}

public GeyserChunkSection(BlockStorage[] storage) {
public GeyserChunkSection(BlockStorage[] storage, int subChunkIndex) {
this.storage = storage;
this.subChunkIndex = subChunkIndex;
}

public int getFullBlock(int x, int y, int z, int layer) {
Expand All @@ -60,6 +62,7 @@ public void writeToNetwork(ByteBuf buffer) {
buffer.writeByte(CHUNK_SECTION_VERSION);
buffer.writeByte(this.storage.length);
// Required for chunk version 9+
buffer.writeByte(this.subChunkIndex);
for (BlockStorage blockStorage : this.storage) {
blockStorage.writeToNetwork(buffer);
}
Expand All @@ -86,12 +89,12 @@ public boolean isEmpty() {
return true;
}

public GeyserChunkSection copy() {
public GeyserChunkSection copy(int subChunkIndex) {
BlockStorage[] storage = new BlockStorage[this.storage.length];
for (int i = 0; i < storage.length; i++) {
storage[i] = this.storage[i].copy();
}
return new GeyserChunkSection(storage);
return new GeyserChunkSection(storage, subChunkIndex);
}

public static int blockPosition(int x, int y, int z) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@
import java.util.List;
import java.util.Map;

import static org.geysermc.geyser.util.ChunkUtils.SERIALIZED_CHUNK_DATA;
import static org.geysermc.geyser.util.ChunkUtils.indexYZXtoXZY;

@Translator(packet = ClientboundLevelChunkWithLightPacket.class)
Expand Down Expand Up @@ -120,13 +119,16 @@ public void translate(GeyserSession session, ClientboundLevelChunkWithLightPacke
ByteBuf in = Unpooled.wrappedBuffer(packet.getChunkData());
boolean extendedCollisionNextSection = false;
for (int sectionY = 0; sectionY < chunkSize; sectionY++) {

ChunkSection javaSection = session.getDownstream().getCodecHelper().readChunkSection(in, biomeGlobalPalette);
javaChunks[sectionY] = javaSection.getChunkData();
javaBiomes[sectionY] = javaSection.getBiomeData();
boolean extendedCollision = extendedCollisionNextSection;
boolean thisExtendedCollisionNextSection = false;

int bedrockSectionY = sectionY + (yOffset - (bedrockDimension.minY() >> 4));
int subChunkIndex = sectionY + (bedrockDimension.minY() >> 4);

if (bedrockSectionY < 0 || maxBedrockSectionY < bedrockSectionY) {
// Ignore this chunk section since it goes outside the bounds accepted by the Bedrock client
if (useExtendedCollisions) {
Expand Down Expand Up @@ -154,7 +156,7 @@ public void translate(GeyserSession session, ClientboundLevelChunkWithLightPacke
}

BlockStorage[] layers = new BlockStorage[]{ layer0 };
sections[bedrockSectionY] = new GeyserChunkSection(layers);
sections[bedrockSectionY] = new GeyserChunkSection(layers, subChunkIndex);
}
EXTENDED_COLLISIONS_STORAGE.get().clear();
extendedCollisionNextSection = false;
Expand All @@ -167,7 +169,7 @@ public void translate(GeyserSession session, ClientboundLevelChunkWithLightPacke

if (javaPalette instanceof GlobalPalette) {
// As this is the global palette, simply iterate through the whole chunk section once
GeyserChunkSection section = new GeyserChunkSection(session.getBlockMappings().getBedrockAir().getRuntimeId());
GeyserChunkSection section = new GeyserChunkSection(session.getBlockMappings().getBedrockAir().getRuntimeId(), subChunkIndex);
for (int yzx = 0; yzx < BlockStorage.SIZE; yzx++) {
int javaId = javaData.get(yzx);
int bedrockId = session.getBlockMappings().getBedrockBlockId(javaId);
Expand Down Expand Up @@ -217,9 +219,9 @@ public void translate(GeyserSession session, ClientboundLevelChunkWithLightPacke

if (BlockRegistries.WATERLOGGED.get().get(javaId)) {
BlockStorage waterlogged = new BlockStorage(SingletonBitArray.INSTANCE, IntLists.singleton(session.getBlockMappings().getBedrockWater().getRuntimeId()));
sections[bedrockSectionY] = new GeyserChunkSection(new BlockStorage[] {blockStorage, waterlogged});
sections[bedrockSectionY] = new GeyserChunkSection(new BlockStorage[] {blockStorage, waterlogged}, subChunkIndex);
} else {
sections[bedrockSectionY] = new GeyserChunkSection(new BlockStorage[] {blockStorage});
sections[bedrockSectionY] = new GeyserChunkSection(new BlockStorage[] {blockStorage}, subChunkIndex);
}
if (useExtendedCollisions) {
EXTENDED_COLLISIONS_STORAGE.get().clear();
Expand Down Expand Up @@ -378,7 +380,7 @@ public void translate(GeyserSession session, ClientboundLevelChunkWithLightPacke
layers = new BlockStorage[]{ layer0, new BlockStorage(BitArrayVersion.V1.createArray(BlockStorage.SIZE, layer1Data), layer1Palette) };
}

sections[bedrockSectionY] = new GeyserChunkSection(layers);
sections[bedrockSectionY] = new GeyserChunkSection(layers, subChunkIndex);
extendedCollisionNextSection = thisExtendedCollisionNextSection;
}

Expand All @@ -400,6 +402,9 @@ public void translate(GeyserSession session, ClientboundLevelChunkWithLightPacke
int y = blockEntity.getY();
int z = blockEntity.getZ(); // Relative to chunk

// chunk index 0-15 from y


// Get the Java block state ID from block entity position
DataPalette section = javaChunks[(y >> 4) - yOffset];
int blockState = section.get(x, y & 0xF, z);
Expand All @@ -426,13 +431,14 @@ public void translate(GeyserSession session, ClientboundLevelChunkWithLightPacke
BlockDefinition blockDefinition = SkullBlockEntityTranslator.translateSkull(session, tag, Vector3i.from(x + chunkBlockX, y, z + chunkBlockZ), blockState);
if (blockDefinition != null) {
int bedrockSectionY = (y >> 4) - (bedrockDimension.minY() >> 4);
int subChunkIndex = (y >> 4) + (bedrockDimension.minY() >> 4);
if (0 <= bedrockSectionY && bedrockSectionY < maxBedrockSectionY) {
// Custom skull is in a section accepted by Bedrock
GeyserChunkSection bedrockSection = sections[bedrockSectionY];
IntList palette = bedrockSection.getBlockStorageArray()[0].getPalette();
if (palette instanceof IntImmutableList || palette instanceof IntLists.Singleton) {
// TODO there has to be a better way to expand the palette .-.
bedrockSection = bedrockSection.copy();
bedrockSection = bedrockSection.copy(subChunkIndex);
sections[bedrockSectionY] = bedrockSection;
}
bedrockSection.setFullBlock(x, y & 0xF, z, 0, blockDefinition.getRuntimeId());
Expand All @@ -457,8 +463,6 @@ public void translate(GeyserSession session, ClientboundLevelChunkWithLightPacke
GeyserChunkSection section = sections[i];
if (section != null) {
size += section.estimateNetworkSize();
} else {
size += SERIALIZED_CHUNK_DATA.length;
}
}
size += ChunkUtils.EMPTY_BIOME_DATA.length * biomeCount;
Expand All @@ -471,9 +475,8 @@ public void translate(GeyserSession session, ClientboundLevelChunkWithLightPacke
GeyserChunkSection section = sections[i];
if (section != null) {
section.writeToNetwork(byteBuf);
} else {
byteBuf.writeBytes(SERIALIZED_CHUNK_DATA);
}
// We can ignore empty sections with subchunk v9
}

int dimensionOffset = bedrockDimension.minY() >> 4;
Expand Down
12 changes: 1 addition & 11 deletions core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,13 @@
@UtilityClass
public class ChunkUtils {
/**
* An empty subchunk.
* Empty biome data
*/
public static final byte[] SERIALIZED_CHUNK_DATA;
public static final byte[] EMPTY_BIOME_DATA;

static {
ByteBuf byteBuf = Unpooled.buffer();
try {
new GeyserChunkSection(new BlockStorage[0])
.writeToNetwork(byteBuf);
SERIALIZED_CHUNK_DATA = new byte[byteBuf.readableBytes()];
byteBuf.readBytes(SERIALIZED_CHUNK_DATA);
} finally {
byteBuf.release();
}

byteBuf = Unpooled.buffer();
try {
BlockStorage blockStorage = new BlockStorage(SingletonBitArray.INSTANCE, IntLists.singleton(0));
blockStorage.writeToNetwork(byteBuf);
Expand Down

0 comments on commit 3bc6d16

Please sign in to comment.