Implement proper biome palette reading probably

With thanks to @kennytv for the magic required to get global palette bits.
This commit is contained in:
Camotoy 2021-11-19 19:11:36 -05:00
parent 27ce6c4b36
commit 66d578eadc
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
6 changed files with 29 additions and 3 deletions

View file

@ -695,6 +695,7 @@ public final class EntityDefinitions {
.type(EntityType.WITCH)
.height(1.8f).width(0.6f)
.offset(1.62f)
.addTranslator(null) // Using item
.build();
}
@ -792,8 +793,12 @@ public final class EntityDefinitions {
TURTLE = EntityDefinition.inherited(TurtleEntity::new, ageableEntityBase)
.type(EntityType.TURTLE)
.height(0.4f).width(1.2f)
.addTranslator(null) // Home position
.addTranslator(MetadataType.BOOLEAN, TurtleEntity::setPregnant)
.addTranslator(MetadataType.BOOLEAN, TurtleEntity::setLayingEgg)
.addTranslator(null) // Travel position
.addTranslator(null) // Going home
.addTranslator(null) // Travelling
.build();
EntityDefinition<AbstractMerchantEntity> abstractVillagerEntityBase = EntityDefinition.inherited(AbstractMerchantEntity::new, ageableEntityBase)

View file

@ -204,6 +204,11 @@ public class GeyserSession implements CommandSender {
private final Map<Vector3i, SkullPlayerEntity> skullCache = new Object2ObjectOpenHashMap<>();
private final Long2ObjectMap<ClientboundMapItemDataPacket> storedMaps = new Long2ObjectOpenHashMap<>();
/**
* Required to decode biomes correctly.
*/
@Setter
private int biomeGlobalPalette;
/**
* Stores the map between Java and Bedrock biome network IDs.
*/

View file

@ -85,6 +85,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
// Ensure that, if the player is using lower world heights, the position is not offset
int yOffset = session.getChunkCache().getChunkMinY();
int chunkSize = session.getChunkCache().getChunkHeightY();
int biomeGlobalPalette = session.getBiomeGlobalPalette();
// Temporarily stores compound tags of Bedrock-only block entities
List<NbtMap> bedrockOnlyBlockEntities = new ArrayList<>();
@ -105,7 +106,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
try {
NetInput in = new StreamNetInput(new ByteArrayInputStream(packet.getChunkData()));
for (int sectionY = 0; sectionY < chunkSize; sectionY++) {
ChunkSection javaSection = ChunkSection.read(in);
ChunkSection javaSection = ChunkSection.read(in, biomeGlobalPalette);
javaChunks[sectionY] = javaSection.getChunkData();
javaBiomes[sectionY] = javaSection.getBiomeData();
@ -266,7 +267,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
bedrockBlockEntities[blockEntityCount] = blockEntityTranslator.getBlockEntityTag(type, x + chunkBlockX, y, z + chunkBlockZ, tag, blockState);
// Check for custom skulls
if (session.getPreferencesCache().showCustomSkulls() && tag != null && tag.contains("SkullOwner")) {
if (session.getPreferencesCache().showCustomSkulls() && type == BlockEntityType.SKULL && tag != null && tag.contains("SkullOwner")) {
SkullBlockEntityTranslator.spawnPlayer(session, tag, x + chunkBlockX, y, z + chunkBlockZ, blockState);
}
blockEntityCount++;

View file

@ -35,6 +35,7 @@ import org.geysermc.connector.network.translators.world.chunk.BlockStorage;
import org.geysermc.connector.network.translators.world.chunk.GeyserChunkSection;
import org.geysermc.connector.network.translators.world.chunk.bitarray.SingletonBitArray;
import org.geysermc.connector.registry.Registries;
import org.geysermc.connector.utils.MathUtils;
import java.util.Arrays;
@ -49,6 +50,7 @@ public class BiomeTranslator {
CompoundTag worldGen = codec.get("minecraft:worldgen/biome");
ListTag serverBiomes = worldGen.get("value");
session.setBiomeGlobalPalette(MathUtils.getGlobalPaletteForSize(serverBiomes.size()));
for (Tag tag : serverBiomes) {
CompoundTag biomeTag = (CompoundTag) tag;

View file

@ -29,6 +29,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.github.steveice10.mc.protocol.data.game.level.particle.ParticleType;
import com.nukkitx.protocol.bedrock.data.LevelEventType;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.registry.type.ParticleMapping;
import java.util.Iterator;
@ -49,9 +50,14 @@ public class ParticleTypesRegistryLoader extends EffectRegistryLoader<Map<Partic
try {
while (particlesIterator.hasNext()) {
Map.Entry<String, JsonNode> entry = particlesIterator.next();
String key = entry.getKey().toUpperCase(Locale.ROOT);
JsonNode bedrockId = entry.getValue().get("bedrockId");
JsonNode eventType = entry.getValue().get("eventType");
particles.put(ParticleType.valueOf(entry.getKey().toUpperCase(Locale.ROOT)), new ParticleMapping(
if (eventType == null && bedrockId == null) {
GeyserConnector.getInstance().getLogger().debug("Skipping particle mapping " + key + " because no Bedrock equivalent exists.");
continue;
}
particles.put(ParticleType.valueOf(key), new ParticleMapping(
eventType == null ? null : LevelEventType.valueOf(eventType.asText().toUpperCase(Locale.ROOT)),
bedrockId == null ? null : bedrockId.asText())
);

View file

@ -105,4 +105,11 @@ public class MathUtils {
public static long chunkPositionToLong(int x, int z) {
return ((x & 0xFFFFFFFFL) << 32L) | (z & 0xFFFFFFFFL);
}
/**
* @return the bits per entry used when this number is the maximum amount of entries.
*/
public static int getGlobalPaletteForSize(int size) {
return 32 - Integer.numberOfLeadingZeros(size - 1);
}
}