3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-11-20 06:50:09 +01:00

Merge branch 'master' of https://github.com/GeyserMC/Geyser into server-inventory

Dieser Commit ist enthalten in:
Camotoy 2021-03-09 14:45:04 -05:00
Commit ded00dfd97
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 7EEFB66FE798081F
45 geänderte Dateien mit 472 neuen und 266 gelöschten Zeilen

4
Jenkinsfile vendored
Datei anzeigen

@ -35,8 +35,8 @@ pipeline {
rtMavenResolver( rtMavenResolver(
id: "maven-resolver", id: "maven-resolver",
serverId: "opencollab-artifactory", serverId: "opencollab-artifactory",
releaseRepo: "release", releaseRepo: "maven-deploy-release",
snapshotRepo: "snapshot" snapshotRepo: "maven-deploy-snapshot"
) )
rtMavenRun( rtMavenRun(
pom: 'pom.xml', pom: 'pom.xml',

Datei anzeigen

@ -18,7 +18,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have now joined us here! Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have now joined us here!
### Currently supporting Minecraft Bedrock v1.16.100 - v1.16.201 and Minecraft Java v1.16.4 - v1.16.5. ### Currently supporting Minecraft Bedrock v1.16.100 - v1.16.210 and Minecraft Java v1.16.4 - v1.16.5.
## Setting Up ## Setting Up
Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser. Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser.

Datei anzeigen

@ -53,11 +53,11 @@ public class GeyserSpigotBlockPlaceListener implements Listener {
placeBlockSoundPacket.setPosition(Vector3f.from(event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ())); placeBlockSoundPacket.setPosition(Vector3f.from(event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ()));
placeBlockSoundPacket.setBabySound(false); placeBlockSoundPacket.setBabySound(false);
if (worldManager.isLegacy()) { if (worldManager.isLegacy()) {
placeBlockSoundPacket.setExtraData(BlockTranslator.getBedrockBlockId(worldManager.getBlockAt(session, placeBlockSoundPacket.setExtraData(session.getBlockTranslator().getBedrockBlockId(worldManager.getBlockAt(session,
event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ()))); event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ())));
} else { } else {
String javaBlockId = event.getBlockPlaced().getBlockData().getAsString(); String javaBlockId = event.getBlockPlaced().getBlockData().getAsString();
placeBlockSoundPacket.setExtraData(BlockTranslator.getBedrockBlockId(BlockTranslator.getJavaIdBlockMap().getOrDefault(javaBlockId, BlockTranslator.JAVA_AIR_ID))); placeBlockSoundPacket.setExtraData(session.getBlockTranslator().getBedrockBlockId(BlockTranslator.getJavaIdBlockMap().getOrDefault(javaBlockId, BlockTranslator.JAVA_AIR_ID)));
} }
placeBlockSoundPacket.setIdentifier(":"); placeBlockSoundPacket.setIdentifier(":");
session.sendUpstreamPacket(placeBlockSoundPacket); session.sendUpstreamPacket(placeBlockSoundPacket);

Datei anzeigen

@ -31,7 +31,7 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.CloudburstMC.Protocol</groupId> <groupId>com.github.CloudburstMC.Protocol</groupId>
<artifactId>bedrock-v422</artifactId> <artifactId>bedrock-v428</artifactId>
<version>42da92f</version> <version>42da92f</version>
<scope>compile</scope> <scope>compile</scope>
<exclusions> <exclusions>

Datei anzeigen

@ -31,7 +31,6 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.network.translators.chat.MessageTranslator; import org.geysermc.connector.network.translators.chat.MessageTranslator;
public class CommandBlockMinecartEntity extends DefaultBlockMinecartEntity { public class CommandBlockMinecartEntity extends DefaultBlockMinecartEntity {
@ -60,8 +59,8 @@ public class CommandBlockMinecartEntity extends DefaultBlockMinecartEntity {
* By default, the command block shown is purple on Bedrock, which does not match Java Edition's orange. * By default, the command block shown is purple on Bedrock, which does not match Java Edition's orange.
*/ */
@Override @Override
public void updateDefaultBlockMetadata() { public void updateDefaultBlockMetadata(GeyserSession session) {
metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.BEDROCK_RUNTIME_COMMAND_BLOCK_ID); metadata.put(EntityData.DISPLAY_ITEM, session.getBlockTranslator().getBedrockRuntimeCommandBlockId());
metadata.put(EntityData.DISPLAY_OFFSET, 6); metadata.put(EntityData.DISPLAY_OFFSET, 6);
} }
} }

Datei anzeigen

@ -30,7 +30,6 @@ import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
/** /**
* This class is used as a base for minecarts with a default block to display like furnaces and spawners * This class is used as a base for minecarts with a default block to display like furnaces and spawners
@ -44,10 +43,15 @@ public class DefaultBlockMinecartEntity extends MinecartEntity {
public DefaultBlockMinecartEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { public DefaultBlockMinecartEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
super(entityId, geyserId, entityType, position, motion, rotation); super(entityId, geyserId, entityType, position, motion, rotation);
updateDefaultBlockMetadata();
metadata.put(EntityData.CUSTOM_DISPLAY, (byte) 1); metadata.put(EntityData.CUSTOM_DISPLAY, (byte) 1);
} }
@Override
public void spawnEntity(GeyserSession session) {
updateDefaultBlockMetadata(session);
super.spawnEntity(session);
}
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
@ -56,7 +60,7 @@ public class DefaultBlockMinecartEntity extends MinecartEntity {
customBlock = (int) entityMetadata.getValue(); customBlock = (int) entityMetadata.getValue();
if (showCustomBlock) { if (showCustomBlock) {
metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.getBedrockBlockId(customBlock)); metadata.put(EntityData.DISPLAY_ITEM, session.getBlockTranslator().getBedrockBlockId(customBlock));
} }
} }
@ -73,16 +77,16 @@ public class DefaultBlockMinecartEntity extends MinecartEntity {
if (entityMetadata.getId() == 12) { if (entityMetadata.getId() == 12) {
if ((boolean) entityMetadata.getValue()) { if ((boolean) entityMetadata.getValue()) {
showCustomBlock = true; showCustomBlock = true;
metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.getBedrockBlockId(customBlock)); metadata.put(EntityData.DISPLAY_ITEM, session.getBlockTranslator().getBedrockBlockId(customBlock));
metadata.put(EntityData.DISPLAY_OFFSET, customBlockOffset); metadata.put(EntityData.DISPLAY_OFFSET, customBlockOffset);
} else { } else {
showCustomBlock = false; showCustomBlock = false;
updateDefaultBlockMetadata(); updateDefaultBlockMetadata(session);
} }
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);
} }
public void updateDefaultBlockMetadata() { } public void updateDefaultBlockMetadata(GeyserSession session) { }
} }

Datei anzeigen

@ -31,14 +31,19 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
public class FallingBlockEntity extends Entity { public class FallingBlockEntity extends Entity {
private final int javaId;
public FallingBlockEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, int javaId) { public FallingBlockEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, int javaId) {
super(entityId, geyserId, entityType, position, motion, rotation); super(entityId, geyserId, entityType, position, motion, rotation);
this.javaId = javaId;
}
this.metadata.put(EntityData.VARIANT, BlockTranslator.getBedrockBlockId(javaId)); @Override
public void spawnEntity(GeyserSession session) {
this.metadata.put(EntityData.VARIANT, session.getBlockTranslator().getBedrockBlockId(javaId));
super.spawnEntity(session);
} }
@Override @Override

Datei anzeigen

@ -44,15 +44,15 @@ public class FurnaceMinecartEntity extends DefaultBlockMinecartEntity {
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 13 && !showCustomBlock) { if (entityMetadata.getId() == 13 && !showCustomBlock) {
hasFuel = (boolean) entityMetadata.getValue(); hasFuel = (boolean) entityMetadata.getValue();
updateDefaultBlockMetadata(); updateDefaultBlockMetadata(session);
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);
} }
@Override @Override
public void updateDefaultBlockMetadata() { public void updateDefaultBlockMetadata(GeyserSession session) {
metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.getBedrockBlockId(hasFuel ? BlockTranslator.JAVA_RUNTIME_FURNACE_LIT_ID : BlockTranslator.JAVA_RUNTIME_FURNACE_ID)); metadata.put(EntityData.DISPLAY_ITEM, session.getBlockTranslator().getBedrockBlockId(hasFuel ? BlockTranslator.JAVA_RUNTIME_FURNACE_LIT_ID : BlockTranslator.JAVA_RUNTIME_FURNACE_ID));
metadata.put(EntityData.DISPLAY_OFFSET, 6); metadata.put(EntityData.DISPLAY_OFFSET, 6);
} }
} }

Datei anzeigen

@ -40,7 +40,6 @@ import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.network.translators.item.ItemRegistry; import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -49,15 +48,19 @@ import java.util.concurrent.TimeUnit;
*/ */
public class ItemFrameEntity extends Entity { public class ItemFrameEntity extends Entity {
/**
* Used to construct the block entity tag on spawning.
*/
private final HangingDirection direction;
/** /**
* Used for getting the Bedrock block position. * Used for getting the Bedrock block position.
* Blocks deal with integers whereas entities deal with floats. * Blocks deal with integers whereas entities deal with floats.
*/ */
private final Vector3i bedrockPosition; private Vector3i bedrockPosition;
/** /**
* Specific block 'state' we are emulating in Bedrock. * Specific block 'state' we are emulating in Bedrock.
*/ */
private final int bedrockRuntimeId; private int bedrockRuntimeId;
/** /**
* Rotation of item in frame. * Rotation of item in frame.
*/ */
@ -69,19 +72,21 @@ public class ItemFrameEntity extends Entity {
public ItemFrameEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, HangingDirection direction) { public ItemFrameEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, HangingDirection direction) {
super(entityId, geyserId, entityType, position, motion, rotation); super(entityId, geyserId, entityType, position, motion, rotation);
NbtMapBuilder blockBuilder = NbtMap.builder() this.direction = direction;
.putString("name", "minecraft:frame")
.putInt("version", BlockTranslator.getBlockStateVersion());
blockBuilder.put("states", NbtMap.builder()
.putInt("facing_direction", direction.ordinal())
.putByte("item_frame_map_bit", (byte) 0)
.build());
bedrockRuntimeId = BlockTranslator.getItemFrame(blockBuilder.build());
bedrockPosition = Vector3i.from(position.getFloorX(), position.getFloorY(), position.getFloorZ());
} }
@Override @Override
public void spawnEntity(GeyserSession session) { public void spawnEntity(GeyserSession session) {
NbtMapBuilder blockBuilder = NbtMap.builder()
.putString("name", "minecraft:frame")
.putInt("version", session.getBlockTranslator().getBlockStateVersion());
blockBuilder.put("states", NbtMap.builder()
.putInt("facing_direction", direction.ordinal())
.putByte("item_frame_map_bit", (byte) 0)
.build());
bedrockRuntimeId = session.getBlockTranslator().getItemFrame(blockBuilder.build());
bedrockPosition = Vector3i.from(position.getFloorX(), position.getFloorY(), position.getFloorZ());
session.getItemFrameCache().put(bedrockPosition, entityId); session.getItemFrameCache().put(bedrockPosition, entityId);
// Delay is required, or else loading in frames on chunk load is sketchy at best // Delay is required, or else loading in frames on chunk load is sketchy at best
session.getConnector().getGeneralThreadPool().schedule(() -> { session.getConnector().getGeneralThreadPool().schedule(() -> {
@ -136,7 +141,7 @@ public class ItemFrameEntity extends Entity {
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
updateBlockPacket.setDataLayer(0); updateBlockPacket.setDataLayer(0);
updateBlockPacket.setBlockPosition(bedrockPosition); updateBlockPacket.setBlockPosition(bedrockPosition);
updateBlockPacket.setRuntimeId(BlockTranslator.BEDROCK_AIR_ID); updateBlockPacket.setRuntimeId(session.getBlockTranslator().getBedrockAirId());
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY);
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK);
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS);

Datei anzeigen

@ -30,7 +30,6 @@ import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
public class MinecartEntity extends Entity { public class MinecartEntity extends Entity {
@ -58,7 +57,7 @@ public class MinecartEntity extends Entity {
if (!(this instanceof DefaultBlockMinecartEntity)) { // Handled in the DefaultBlockMinecartEntity class if (!(this instanceof DefaultBlockMinecartEntity)) { // Handled in the DefaultBlockMinecartEntity class
// Custom block // Custom block
if (entityMetadata.getId() == 10) { if (entityMetadata.getId() == 10) {
metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.getBedrockBlockId((int) entityMetadata.getValue())); metadata.put(EntityData.DISPLAY_ITEM, session.getBlockTranslator().getBedrockBlockId((int) entityMetadata.getValue()));
} }
// Custom block offset // Custom block offset

Datei anzeigen

@ -28,6 +28,7 @@ package org.geysermc.connector.entity;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.BlockTranslator;
public class SpawnerMinecartEntity extends DefaultBlockMinecartEntity { public class SpawnerMinecartEntity extends DefaultBlockMinecartEntity {
@ -37,8 +38,8 @@ public class SpawnerMinecartEntity extends DefaultBlockMinecartEntity {
} }
@Override @Override
public void updateDefaultBlockMetadata() { public void updateDefaultBlockMetadata(GeyserSession session) {
metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.getBedrockBlockId(BlockTranslator.JAVA_RUNTIME_SPAWNER_ID)); metadata.put(EntityData.DISPLAY_ITEM, session.getBlockTranslator().getBedrockBlockId(BlockTranslator.JAVA_RUNTIME_SPAWNER_ID));
metadata.put(EntityData.DISPLAY_OFFSET, 6); metadata.put(EntityData.DISPLAY_OFFSET, 6);
} }
} }

Datei anzeigen

@ -33,7 +33,6 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.LevelSoundEvent2Packet; import com.nukkitx.protocol.bedrock.packet.LevelSoundEvent2Packet;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
public class EndermanEntity extends MonsterEntity { public class EndermanEntity extends MonsterEntity {
@ -45,7 +44,7 @@ public class EndermanEntity extends MonsterEntity {
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
// Held block // Held block
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 15) {
metadata.put(EntityData.CARRIED_BLOCK, BlockTranslator.getBedrockBlockId((int) entityMetadata.getValue())); metadata.put(EntityData.CARRIED_BLOCK, session.getBlockTranslator().getBedrockBlockId((int) entityMetadata.getValue()));
} }
// "Is screaming" - controls sound // "Is screaming" - controls sound
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 16) {

Datei anzeigen

@ -28,6 +28,7 @@ package org.geysermc.connector.network;
import com.nukkitx.protocol.bedrock.BedrockPacketCodec; import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
import com.nukkitx.protocol.bedrock.v419.Bedrock_v419; import com.nukkitx.protocol.bedrock.v419.Bedrock_v419;
import com.nukkitx.protocol.bedrock.v422.Bedrock_v422; import com.nukkitx.protocol.bedrock.v422.Bedrock_v422;
import com.nukkitx.protocol.bedrock.v428.Bedrock_v428;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -40,9 +41,7 @@ public class BedrockProtocol {
* Default Bedrock codec that should act as a fallback. Should represent the latest available * Default Bedrock codec that should act as a fallback. Should represent the latest available
* release of the game that Geyser supports. * release of the game that Geyser supports.
*/ */
public static final BedrockPacketCodec DEFAULT_BEDROCK_CODEC = Bedrock_v422.V422_CODEC.toBuilder() public static final BedrockPacketCodec DEFAULT_BEDROCK_CODEC = Bedrock_v428.V428_CODEC;
.minecraftVersion("1.16.201")
.build();
/** /**
* A list of all supported Bedrock versions that can join Geyser * A list of all supported Bedrock versions that can join Geyser
*/ */
@ -52,9 +51,10 @@ public class BedrockProtocol {
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v419.V419_CODEC.toBuilder() SUPPORTED_BEDROCK_CODECS.add(Bedrock_v419.V419_CODEC.toBuilder()
.minecraftVersion("1.16.100/1.16.101") // We change this as 1.16.100.60 is a beta .minecraftVersion("1.16.100/1.16.101") // We change this as 1.16.100.60 is a beta
.build()); .build());
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder() SUPPORTED_BEDROCK_CODECS.add(Bedrock_v422.V422_CODEC.toBuilder()
.minecraftVersion("1.16.200/1.16.201") .minecraftVersion("1.16.200/1.16.201")
.build()); .build());
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
} }
/** /**

Datei anzeigen

@ -26,15 +26,18 @@
package org.geysermc.connector.network; package org.geysermc.connector.network;
import com.nukkitx.protocol.bedrock.BedrockPacket; import com.nukkitx.protocol.bedrock.BedrockPacket;
import com.nukkitx.protocol.bedrock.data.ResourcePackType;
import com.nukkitx.protocol.bedrock.BedrockPacketCodec; import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
import com.nukkitx.protocol.bedrock.data.ResourcePackType;
import com.nukkitx.protocol.bedrock.packet.*; import com.nukkitx.protocol.bedrock.packet.*;
import com.nukkitx.protocol.bedrock.v428.Bedrock_v428;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.common.AuthType; import org.geysermc.connector.common.AuthType;
import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.configuration.GeyserConfiguration;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.session.cache.AdvancementsCache; import org.geysermc.connector.network.session.cache.AdvancementsCache;
import org.geysermc.connector.network.translators.PacketTranslatorRegistry; import org.geysermc.connector.network.translators.PacketTranslatorRegistry;
import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_100;
import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210;
import org.geysermc.connector.utils.*; import org.geysermc.connector.utils.*;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -68,6 +71,10 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
session.getUpstream().getSession().setPacketCodec(packetCodec); session.getUpstream().getSession().setPacketCodec(packetCodec);
// Set the block translation based off of version
session.setBlockTranslator(packetCodec.getProtocolVersion() >= Bedrock_v428.V428_CODEC.getProtocolVersion()
? BlockTranslator1_16_210.INSTANCE : BlockTranslator1_16_100.INSTANCE);
LoginEncryptionUtils.encryptPlayerConnection(connector, session, loginPacket); LoginEncryptionUtils.encryptPlayerConnection(connector, session, loginPacket);
PlayStatusPacket playStatus = new PlayStatusPacket(); PlayStatusPacket playStatus = new PlayStatusPacket();

Datei anzeigen

@ -92,6 +92,7 @@ import org.geysermc.connector.network.translators.chat.MessageTranslator;
import org.geysermc.connector.network.translators.collision.CollisionManager; import org.geysermc.connector.network.translators.collision.CollisionManager;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
import org.geysermc.connector.network.translators.item.ItemRegistry; import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.skin.SkinManager; import org.geysermc.connector.skin.SkinManager;
import org.geysermc.connector.utils.*; import org.geysermc.connector.utils.*;
import org.geysermc.floodgate.util.BedrockData; import org.geysermc.floodgate.util.BedrockData;
@ -162,6 +163,12 @@ public class GeyserSession implements CommandSender {
*/ */
private final CollisionManager collisionManager; private final CollisionManager collisionManager;
/**
* Stores the block translations for this specific version.
*/
@Setter
private BlockTranslator blockTranslator;
private final Map<Vector3i, SkullPlayerEntity> skullCache = new ConcurrentHashMap<>(); private final Map<Vector3i, SkullPlayerEntity> skullCache = new ConcurrentHashMap<>();
private final Long2ObjectMap<ClientboundMapItemDataPacket> storedMaps = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>()); private final Long2ObjectMap<ClientboundMapItemDataPacket> storedMaps = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>());

Datei anzeigen

@ -127,7 +127,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
} }
// Bedrock sends block interact code for a Java entity so we send entity code back to Java // Bedrock sends block interact code for a Java entity so we send entity code back to Java
if (BlockTranslator.isItemFrame(packet.getBlockRuntimeId()) && if (session.getBlockTranslator().isItemFrame(packet.getBlockRuntimeId()) &&
session.getEntityCache().getEntityByJavaId(ItemFrameEntity.getItemFrameEntityId(session, packet.getBlockPosition())) != null) { session.getEntityCache().getEntityByJavaId(ItemFrameEntity.getItemFrameEntityId(session, packet.getBlockPosition())) != null) {
Vector3f vector = packet.getClickPosition(); Vector3f vector = packet.getClickPosition();
ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) ItemFrameEntity.getItemFrameEntityId(session, packet.getBlockPosition()), ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) ItemFrameEntity.getItemFrameEntityId(session, packet.getBlockPosition()),
@ -211,7 +211,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
if (packet.getActions().isEmpty()) { if (packet.getActions().isEmpty()) {
if (session.getOpPermissionLevel() >= 2 && session.getGameMode() == GameMode.CREATIVE) { if (session.getOpPermissionLevel() >= 2 && session.getGameMode() == GameMode.CREATIVE) {
// Otherwise insufficient permissions // Otherwise insufficient permissions
int blockState = BlockTranslator.getJavaBlockState(packet.getBlockRuntimeId()); int blockState = session.getBlockTranslator().getJavaBlockState(packet.getBlockRuntimeId());
String blockName = BlockTranslator.getJavaIdBlockMap().inverse().getOrDefault(blockState, ""); String blockName = BlockTranslator.getJavaIdBlockMap().inverse().getOrDefault(blockState, "");
// In the future this can be used for structure blocks too, however not all elements // In the future this can be used for structure blocks too, however not all elements
// are available in each GUI // are available in each GUI
@ -271,7 +271,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
LevelEventPacket blockBreakPacket = new LevelEventPacket(); LevelEventPacket blockBreakPacket = new LevelEventPacket();
blockBreakPacket.setType(LevelEventType.PARTICLE_DESTROY_BLOCK); blockBreakPacket.setType(LevelEventType.PARTICLE_DESTROY_BLOCK);
blockBreakPacket.setPosition(packet.getBlockPosition().toFloat()); blockBreakPacket.setPosition(packet.getBlockPosition().toFloat());
blockBreakPacket.setData(BlockTranslator.getBedrockBlockId(blockState)); blockBreakPacket.setData(session.getBlockTranslator().getBedrockBlockId(blockState));
session.sendUpstreamPacket(blockBreakPacket); session.sendUpstreamPacket(blockBreakPacket);
session.setBreakingBlock(BlockTranslator.JAVA_AIR_ID); session.setBreakingBlock(BlockTranslator.JAVA_AIR_ID);
@ -356,14 +356,14 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
updateBlockPacket.setDataLayer(0); updateBlockPacket.setDataLayer(0);
updateBlockPacket.setBlockPosition(blockPos); updateBlockPacket.setBlockPosition(blockPos);
updateBlockPacket.setRuntimeId(BlockTranslator.getBedrockBlockId(javaBlockState)); updateBlockPacket.setRuntimeId(session.getBlockTranslator().getBedrockBlockId(javaBlockState));
updateBlockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY); updateBlockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY);
session.sendUpstreamPacket(updateBlockPacket); session.sendUpstreamPacket(updateBlockPacket);
UpdateBlockPacket updateWaterPacket = new UpdateBlockPacket(); UpdateBlockPacket updateWaterPacket = new UpdateBlockPacket();
updateWaterPacket.setDataLayer(1); updateWaterPacket.setDataLayer(1);
updateWaterPacket.setBlockPosition(blockPos); updateWaterPacket.setBlockPosition(blockPos);
updateWaterPacket.setRuntimeId(BlockTranslator.isWaterlogged(javaBlockState) ? BlockTranslator.BEDROCK_WATER_ID : BlockTranslator.BEDROCK_AIR_ID); updateWaterPacket.setRuntimeId(BlockTranslator.isWaterlogged(javaBlockState) ? session.getBlockTranslator().getBedrockWaterId() : session.getBlockTranslator().getBedrockAirId());
updateWaterPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY); updateWaterPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY);
session.sendUpstreamPacket(updateWaterPacket); session.sendUpstreamPacket(updateWaterPacket);

Datei anzeigen

@ -32,6 +32,8 @@ import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.utils.SettingsUtils; import org.geysermc.connector.utils.SettingsUtils;
import java.util.concurrent.TimeUnit;
@Translator(packet = ServerSettingsRequestPacket.class) @Translator(packet = ServerSettingsRequestPacket.class)
public class BedrockServerSettingsRequestTranslator extends PacketTranslator<ServerSettingsRequestPacket> { public class BedrockServerSettingsRequestTranslator extends PacketTranslator<ServerSettingsRequestPacket> {
@ -39,9 +41,12 @@ public class BedrockServerSettingsRequestTranslator extends PacketTranslator<Ser
public void translate(ServerSettingsRequestPacket packet, GeyserSession session) { public void translate(ServerSettingsRequestPacket packet, GeyserSession session) {
SettingsUtils.buildForm(session); SettingsUtils.buildForm(session);
// Fixes https://bugs.mojang.com/browse/MCPE-94012 because of the delay
session.getConnector().getGeneralThreadPool().schedule(() -> {
ServerSettingsResponsePacket serverSettingsResponsePacket = new ServerSettingsResponsePacket(); ServerSettingsResponsePacket serverSettingsResponsePacket = new ServerSettingsResponsePacket();
serverSettingsResponsePacket.setFormData(session.getSettingsForm().getJSONData()); serverSettingsResponsePacket.setFormData(session.getSettingsForm().getJSONData());
serverSettingsResponsePacket.setFormId(SettingsUtils.SETTINGS_FORM_ID); serverSettingsResponsePacket.setFormId(SettingsUtils.SETTINGS_FORM_ID);
session.sendUpstreamPacket(serverSettingsResponsePacket); session.sendUpstreamPacket(serverSettingsResponsePacket);
}, 1, TimeUnit.SECONDS);
} }
} }

Datei anzeigen

@ -179,7 +179,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
} }
LevelEventPacket continueBreakPacket = new LevelEventPacket(); LevelEventPacket continueBreakPacket = new LevelEventPacket();
continueBreakPacket.setType(LevelEventType.PARTICLE_CRACK_BLOCK); continueBreakPacket.setType(LevelEventType.PARTICLE_CRACK_BLOCK);
continueBreakPacket.setData((BlockTranslator.getBedrockBlockId(session.getBreakingBlock())) | (packet.getFace() << 24)); continueBreakPacket.setData((session.getBlockTranslator().getBedrockBlockId(session.getBreakingBlock())) | (packet.getFace() << 24));
continueBreakPacket.setPosition(vector.toFloat()); continueBreakPacket.setPosition(vector.toFloat());
session.sendUpstreamPacket(continueBreakPacket); session.sendUpstreamPacket(continueBreakPacket);
break; break;

Datei anzeigen

@ -93,7 +93,7 @@ public class BlockInventoryHolder extends InventoryHolder {
UpdateBlockPacket blockPacket = new UpdateBlockPacket(); UpdateBlockPacket blockPacket = new UpdateBlockPacket();
blockPacket.setDataLayer(0); blockPacket.setDataLayer(0);
blockPacket.setBlockPosition(position); blockPacket.setBlockPosition(position);
blockPacket.setRuntimeId(BlockTranslator.getBedrockBlockId(defaultJavaBlockState)); blockPacket.setRuntimeId(session.getBlockTranslator().getBedrockBlockId(defaultJavaBlockState));
blockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY); blockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY);
session.sendUpstreamPacket(blockPacket); session.sendUpstreamPacket(blockPacket);
inventory.setHolderPosition(position); inventory.setHolderPosition(position);
@ -148,7 +148,7 @@ public class BlockInventoryHolder extends InventoryHolder {
UpdateBlockPacket blockPacket = new UpdateBlockPacket(); UpdateBlockPacket blockPacket = new UpdateBlockPacket();
blockPacket.setDataLayer(0); blockPacket.setDataLayer(0);
blockPacket.setBlockPosition(holderPos); blockPacket.setBlockPosition(holderPos);
blockPacket.setRuntimeId(BlockTranslator.getBedrockBlockId(realBlock)); blockPacket.setRuntimeId(session.getBlockTranslator().getBedrockBlockId(realBlock));
blockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY); blockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY);
session.sendUpstreamPacket(blockPacket); session.sendUpstreamPacket(blockPacket);
} }

Datei anzeigen

@ -82,8 +82,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
Vector3i position = session.getPlayerEntity().getPosition().toInt().add(Vector3i.UP); Vector3i position = session.getPlayerEntity().getPosition().toInt().add(Vector3i.UP);
Vector3i pairPosition = position.add(Vector3i.UNIT_X); Vector3i pairPosition = position.add(Vector3i.UNIT_X);
int bedrockBlockId = session.getBlockTranslator().getBedrockBlockId(defaultJavaBlockState);
int bedrockBlockId = BlockTranslator.getBedrockBlockId(defaultJavaBlockState);
UpdateBlockPacket blockPacket = new UpdateBlockPacket(); UpdateBlockPacket blockPacket = new UpdateBlockPacket();
blockPacket.setDataLayer(0); blockPacket.setDataLayer(0);
@ -155,7 +154,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
UpdateBlockPacket blockPacket = new UpdateBlockPacket(); UpdateBlockPacket blockPacket = new UpdateBlockPacket();
blockPacket.setDataLayer(0); blockPacket.setDataLayer(0);
blockPacket.setBlockPosition(holderPos); blockPacket.setBlockPosition(holderPos);
blockPacket.setRuntimeId(BlockTranslator.getBedrockBlockId(realBlock)); blockPacket.setRuntimeId(session.getBlockTranslator().getBedrockBlockId(realBlock));
session.sendUpstreamPacket(blockPacket); session.sendUpstreamPacket(blockPacket);
holderPos = holderPos.add(Vector3i.UNIT_X); holderPos = holderPos.add(Vector3i.UNIT_X);
@ -163,7 +162,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
blockPacket = new UpdateBlockPacket(); blockPacket = new UpdateBlockPacket();
blockPacket.setDataLayer(0); blockPacket.setDataLayer(0);
blockPacket.setBlockPosition(holderPos); blockPacket.setBlockPosition(holderPos);
blockPacket.setRuntimeId(BlockTranslator.getBedrockBlockId(realBlock)); blockPacket.setRuntimeId(session.getBlockTranslator().getBedrockBlockId(realBlock));
session.sendUpstreamPacket(blockPacket); session.sendUpstreamPacket(blockPacket);
} }
} }

Datei anzeigen

@ -38,7 +38,6 @@ import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.ItemRemapper;
import org.geysermc.connector.network.translators.chat.MessageTranslator; import org.geysermc.connector.network.translators.chat.MessageTranslator;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.LanguageUtils; import org.geysermc.connector.utils.LanguageUtils;
import org.reflections.Reflections; import org.reflections.Reflections;
@ -164,8 +163,8 @@ public abstract class ItemTranslator {
String[] canBreak = new String[0]; String[] canBreak = new String[0];
ListTag canPlaceOn = nbt.get("CanPlaceOn"); ListTag canPlaceOn = nbt.get("CanPlaceOn");
String[] canPlace = new String[0]; String[] canPlace = new String[0];
canBreak = getCanModify(canDestroy, canBreak); canBreak = getCanModify(session, canDestroy, canBreak);
canPlace = getCanModify(canPlaceOn, canPlace); canPlace = getCanModify(session, canPlaceOn, canPlace);
itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), itemData.getTag(), canPlace, canBreak); itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), itemData.getTag(), canPlace, canBreak);
} }
@ -175,11 +174,12 @@ public abstract class ItemTranslator {
/** /**
* Translates the Java NBT of canDestroy and canPlaceOn to its Bedrock counterparts. * Translates the Java NBT of canDestroy and canPlaceOn to its Bedrock counterparts.
* In Java, this is treated as normal NBT, but in Bedrock, these arguments are extra parts of the item data itself. * In Java, this is treated as normal NBT, but in Bedrock, these arguments are extra parts of the item data itself.
*
* @param canModifyJava the list of items in Java * @param canModifyJava the list of items in Java
* @param canModifyBedrock the empty list of items in Bedrock * @param canModifyBedrock the empty list of items in Bedrock
* @return the new list of items in Bedrock * @return the new list of items in Bedrock
*/ */
private static String[] getCanModify(ListTag canModifyJava, String[] canModifyBedrock) { private static String[] getCanModify(GeyserSession session, ListTag canModifyJava, String[] canModifyBedrock) {
if (canModifyJava != null && canModifyJava.size() > 0) { if (canModifyJava != null && canModifyJava.size() > 0) {
canModifyBedrock = new String[canModifyJava.size()]; canModifyBedrock = new String[canModifyJava.size()];
for (int i = 0; i < canModifyBedrock.length; i++) { for (int i = 0; i < canModifyBedrock.length; i++) {
@ -189,7 +189,7 @@ public abstract class ItemTranslator {
if (!block.startsWith("minecraft:")) block = "minecraft:" + block; if (!block.startsWith("minecraft:")) block = "minecraft:" + block;
// Get the Bedrock identifier of the item and replace it. // Get the Bedrock identifier of the item and replace it.
// This will unfortunately be limited - for example, beds and banners will be translated weirdly // This will unfortunately be limited - for example, beds and banners will be translated weirdly
canModifyBedrock[i] = BlockTranslator.getBedrockBlockIdentifier(block).replace("minecraft:", ""); canModifyBedrock[i] = session.getBlockTranslator().getBedrockBlockIdentifier(block).replace("minecraft:", "");
} }
} }
return canModifyBedrock; return canModifyBedrock;

Datei anzeigen

@ -84,7 +84,7 @@ public class JavaBlockChangeTranslator extends PacketTranslator<ServerBlockChang
placeBlockSoundPacket.setSound(SoundEvent.PLACE); placeBlockSoundPacket.setSound(SoundEvent.PLACE);
placeBlockSoundPacket.setPosition(lastPlacePos.toFloat()); placeBlockSoundPacket.setPosition(lastPlacePos.toFloat());
placeBlockSoundPacket.setBabySound(false); placeBlockSoundPacket.setBabySound(false);
placeBlockSoundPacket.setExtraData(BlockTranslator.getBedrockBlockId(packet.getRecord().getBlock())); placeBlockSoundPacket.setExtraData(session.getBlockTranslator().getBedrockBlockId(packet.getRecord().getBlock()));
placeBlockSoundPacket.setIdentifier(":"); placeBlockSoundPacket.setIdentifier(":");
session.sendUpstreamPacket(placeBlockSoundPacket); session.sendUpstreamPacket(placeBlockSoundPacket);
session.setLastBlockPlacePosition(null); session.setLastBlockPlacePosition(null);

Datei anzeigen

@ -90,7 +90,7 @@ public class JavaChunkDataTranslator extends PacketTranslator<ServerChunkDataPac
int size = 0; int size = 0;
for (int i = 0; i < sectionCount; i++) { for (int i = 0; i < sectionCount; i++) {
ChunkSection section = sections[i]; ChunkSection section = sections[i];
size += (section != null ? section : ChunkUtils.EMPTY_SECTION).estimateNetworkSize(); size += (section != null ? section : session.getBlockTranslator().getEmptyChunkSection()).estimateNetworkSize();
} }
size += 256; // Biomes size += 256; // Biomes
size += 1; // Border blocks size += 1; // Border blocks
@ -103,7 +103,7 @@ public class JavaChunkDataTranslator extends PacketTranslator<ServerChunkDataPac
try { try {
for (int i = 0; i < sectionCount; i++) { for (int i = 0; i < sectionCount; i++) {
ChunkSection section = sections[i]; ChunkSection section = sections[i];
(section != null ? section : ChunkUtils.EMPTY_SECTION).writeToNetwork(byteBuf); (section != null ? section : session.getBlockTranslator().getEmptyChunkSection()).writeToNetwork(byteBuf);
} }
byteBuf.writeBytes(BiomeTranslator.toBedrockBiome(mergedColumn.getBiomeData())); // Biomes - 256 bytes byteBuf.writeBytes(BiomeTranslator.toBedrockBiome(mergedColumn.getBiomeData())); // Biomes - 256 bytes

Datei anzeigen

@ -83,7 +83,7 @@ public class JavaPlayBuiltinSoundTranslator extends PacketTranslator<ServerPlayB
soundPacket.setExtraData(soundMapping.getExtraData() + (int)(Math.round((Math.log10(packet.getPitch()) / Math.log10(2)) * 12)) + 12); soundPacket.setExtraData(soundMapping.getExtraData() + (int)(Math.round((Math.log10(packet.getPitch()) / Math.log10(2)) * 12)) + 12);
} else if (sound == SoundEvent.PLACE && soundMapping.getExtraData() == -1) { } else if (sound == SoundEvent.PLACE && soundMapping.getExtraData() == -1) {
if (!soundMapping.getIdentifier().equals(":")) { if (!soundMapping.getIdentifier().equals(":")) {
soundPacket.setExtraData(BlockTranslator.getBedrockBlockId(BlockTranslator.getJavaBlockState(soundMapping.getIdentifier()))); soundPacket.setExtraData(session.getBlockTranslator().getBedrockBlockId(BlockTranslator.getJavaBlockState(soundMapping.getIdentifier())));
} else { } else {
session.getConnector().getLogger().debug("PLACE sound mapping identifier was invalid! Please report: " + packet.toString()); session.getConnector().getLogger().debug("PLACE sound mapping identifier was invalid! Please report: " + packet.toString());
} }

Datei anzeigen

@ -25,7 +25,6 @@
package org.geysermc.connector.network.translators.java.world; package org.geysermc.connector.network.translators.java.world;
import com.github.steveice10.mc.protocol.data.game.world.effect.ParticleEffect;
import com.github.steveice10.mc.protocol.data.game.world.effect.*; import com.github.steveice10.mc.protocol.data.game.world.effect.*;
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerPlayEffectPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerPlayEffectPacket;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
@ -38,7 +37,6 @@ import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.network.translators.effect.Effect; import org.geysermc.connector.network.translators.effect.Effect;
import org.geysermc.connector.network.translators.effect.EffectRegistry; import org.geysermc.connector.network.translators.effect.EffectRegistry;
import org.geysermc.connector.utils.LocaleUtils; import org.geysermc.connector.utils.LocaleUtils;
@ -205,7 +203,7 @@ public class JavaPlayEffectTranslator extends PacketTranslator<ServerPlayEffectP
effectPacket.setType(LevelEventType.PARTICLE_DESTROY_BLOCK); effectPacket.setType(LevelEventType.PARTICLE_DESTROY_BLOCK);
BreakBlockEffectData breakBlockEffectData = (BreakBlockEffectData) packet.getData(); BreakBlockEffectData breakBlockEffectData = (BreakBlockEffectData) packet.getData();
effectPacket.setData(BlockTranslator.getBedrockBlockId(breakBlockEffectData.getBlockState())); effectPacket.setData(session.getBlockTranslator().getBedrockBlockId(breakBlockEffectData.getBlockState()));
break; break;
} }
case BREAK_SPLASH_POTION: { case BREAK_SPLASH_POTION: {

Datei anzeigen

@ -26,20 +26,21 @@
package org.geysermc.connector.network.translators.java.world; package org.geysermc.connector.network.translators.java.world;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.github.steveice10.mc.protocol.data.game.world.particle.*; import com.github.steveice10.mc.protocol.data.game.world.particle.BlockParticleData;
import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.github.steveice10.mc.protocol.data.game.world.particle.DustParticleData;
import com.github.steveice10.mc.protocol.data.game.world.particle.FallingDustParticleData;
import com.github.steveice10.mc.protocol.data.game.world.particle.ItemParticleData;
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerSpawnParticlePacket;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.data.LevelEventType;
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
import com.nukkitx.protocol.bedrock.packet.SpawnParticleEffectPacket; import com.nukkitx.protocol.bedrock.packet.SpawnParticleEffectPacket;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerSpawnParticlePacket;
import com.nukkitx.math.vector.Vector3f;
import org.geysermc.connector.network.translators.effect.EffectRegistry; import org.geysermc.connector.network.translators.effect.EffectRegistry;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.utils.DimensionUtils; import org.geysermc.connector.utils.DimensionUtils;
@Translator(packet = ServerSpawnParticlePacket.class) @Translator(packet = ServerSpawnParticlePacket.class)
@ -52,14 +53,14 @@ public class JavaSpawnParticleTranslator extends PacketTranslator<ServerSpawnPar
case BLOCK: case BLOCK:
particle.setType(LevelEventType.PARTICLE_DESTROY_BLOCK_NO_SOUND); particle.setType(LevelEventType.PARTICLE_DESTROY_BLOCK_NO_SOUND);
particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ()));
particle.setData(BlockTranslator.getBedrockBlockId(((BlockParticleData) packet.getParticle().getData()).getBlockState())); particle.setData(session.getBlockTranslator().getBedrockBlockId(((BlockParticleData) packet.getParticle().getData()).getBlockState()));
session.sendUpstreamPacket(particle); session.sendUpstreamPacket(particle);
break; break;
case FALLING_DUST: case FALLING_DUST:
//In fact, FallingDustParticle should have data like DustParticle, //In fact, FallingDustParticle should have data like DustParticle,
//but in MCProtocol, its data is BlockState(1). //but in MCProtocol, its data is BlockState(1).
particle.setType(LevelEventType.PARTICLE_FALLING_DUST); particle.setType(LevelEventType.PARTICLE_FALLING_DUST);
particle.setData(BlockTranslator.getBedrockBlockId(((FallingDustParticleData)packet.getParticle().getData()).getBlockState())); particle.setData(session.getBlockTranslator().getBedrockBlockId(((FallingDustParticleData)packet.getParticle().getData()).getBlockState()));
particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ()));
session.sendUpstreamPacket(particle); session.sendUpstreamPacket(particle);
break; break;

Datei anzeigen

@ -44,7 +44,6 @@ import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.network.translators.item.ItemRegistry; import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -146,7 +145,7 @@ public class JavaTradeListTranslator extends PacketTranslator<ServerTradeListPac
builder.put("tag", tag); builder.put("tag", tag);
} }
NbtMap blockTag = BlockTranslator.getBedrockBlockNbt(itemEntry.getJavaIdentifier()); NbtMap blockTag = session.getBlockTranslator().getBedrockBlockNbt(itemEntry.getJavaIdentifier());
if (blockTag != null) { if (blockTag != null) {
// This fixes certain blocks being unable to stack after grabbing one // This fixes certain blocks being unable to stack after grabbing one
builder.putCompound("Block", blockTag); builder.putCompound("Block", blockTag);

Datei anzeigen

@ -44,7 +44,7 @@ public class GrassPathInteractionHandler implements BlockSoundInteractionHandler
levelSoundEventPacket.setRelativeVolumeDisabled(false); levelSoundEventPacket.setRelativeVolumeDisabled(false);
levelSoundEventPacket.setIdentifier(":"); levelSoundEventPacket.setIdentifier(":");
levelSoundEventPacket.setSound(SoundEvent.ITEM_USE_ON); levelSoundEventPacket.setSound(SoundEvent.ITEM_USE_ON);
levelSoundEventPacket.setExtraData(BlockTranslator.getBedrockBlockId(BlockTranslator.getJavaBlockState(identifier))); levelSoundEventPacket.setExtraData(session.getBlockTranslator().getBedrockBlockId(BlockTranslator.getJavaBlockState(identifier)));
session.sendUpstreamPacket(levelSoundEventPacket); session.sendUpstreamPacket(levelSoundEventPacket);
} }
} }

Datei anzeigen

@ -44,7 +44,7 @@ public class HoeInteractionHandler implements BlockSoundInteractionHandler {
levelSoundEventPacket.setRelativeVolumeDisabled(false); levelSoundEventPacket.setRelativeVolumeDisabled(false);
levelSoundEventPacket.setIdentifier(":"); levelSoundEventPacket.setIdentifier(":");
levelSoundEventPacket.setSound(SoundEvent.ITEM_USE_ON); levelSoundEventPacket.setSound(SoundEvent.ITEM_USE_ON);
levelSoundEventPacket.setExtraData(BlockTranslator.getBedrockBlockId(BlockTranslator.getJavaBlockState(identifier))); levelSoundEventPacket.setExtraData(session.getBlockTranslator().getBedrockBlockId(BlockTranslator.getJavaBlockState(identifier)));
session.sendUpstreamPacket(levelSoundEventPacket); session.sendUpstreamPacket(levelSoundEventPacket);
} }
} }

Datei anzeigen

@ -26,10 +26,8 @@
package org.geysermc.connector.network.translators.world.block; package org.geysermc.connector.network.translators.world.block;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.nukkitx.nbt.NbtMap;
import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.ints.*;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
@ -41,7 +39,6 @@ public class BlockStateValues {
private static final Int2ByteMap COMMAND_BLOCK_VALUES = new Int2ByteOpenHashMap(); private static final Int2ByteMap COMMAND_BLOCK_VALUES = new Int2ByteOpenHashMap();
private static final Int2ObjectMap<DoubleChestValue> DOUBLE_CHEST_VALUES = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<DoubleChestValue> DOUBLE_CHEST_VALUES = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<String> FLOWER_POT_VALUES = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<String> FLOWER_POT_VALUES = new Int2ObjectOpenHashMap<>();
private static final Map<String, NbtMap> FLOWER_POT_BLOCKS = new HashMap<>();
private static final Int2BooleanMap LECTERN_BOOK_STATES = new Int2BooleanOpenHashMap(); private static final Int2BooleanMap LECTERN_BOOK_STATES = new Int2BooleanOpenHashMap();
private static final Int2IntMap NOTEBLOCK_PITCHES = new Int2IntOpenHashMap(); private static final Int2IntMap NOTEBLOCK_PITCHES = new Int2IntOpenHashMap();
private static final Int2BooleanMap IS_STICKY_PISTON = new Int2BooleanOpenHashMap(); private static final Int2BooleanMap IS_STICKY_PISTON = new Int2BooleanOpenHashMap();
@ -202,15 +199,6 @@ public class BlockStateValues {
return FLOWER_POT_VALUES; return FLOWER_POT_VALUES;
} }
/**
* Get the map of contained flower pot plants to Bedrock CompoundTag
*
* @return Map of flower pot blocks.
*/
public static Map<String, NbtMap> getFlowerPotBlocks() {
return FLOWER_POT_BLOCKS;
}
public static Int2BooleanMap getLecternBookStates() { public static Int2BooleanMap getLecternBookStates() {
return LECTERN_BOOK_STATES; return LECTERN_BOOK_STATES;
} }

Datei anzeigen

@ -34,16 +34,20 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import lombok.Getter;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.translators.world.chunk.ChunkSection;
import org.geysermc.connector.network.translators.world.chunk.EmptyChunkProvider;
import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.FileUtils;
import org.reflections.Reflections;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.zip.GZIPInputStream;
public class BlockTranslator { public abstract class BlockTranslator {
/** /**
* The Java block runtime ID of air * The Java block runtime ID of air
*/ */
@ -51,11 +55,11 @@ public class BlockTranslator {
/** /**
* The Bedrock block runtime ID of air * The Bedrock block runtime ID of air
*/ */
public static final int BEDROCK_AIR_ID; private final int bedrockAirId;
public static final int BEDROCK_WATER_ID; private final int bedrockWaterId;
private static final Int2IntMap JAVA_TO_BEDROCK_BLOCK_MAP = new Int2IntOpenHashMap(); private final Int2IntMap javaToBedrockBlockMap = new Int2IntOpenHashMap();
private static final Int2IntMap BEDROCK_TO_JAVA_BLOCK_MAP = new Int2IntOpenHashMap(); private final Int2IntMap bedrockToJavaBlockMap = new Int2IntOpenHashMap();
/** /**
* Stores a list of differences in block identifiers. * Stores a list of differences in block identifiers.
* Items will not be added to this list if the key and value is the same. * Items will not be added to this list if the key and value is the same.
@ -63,7 +67,8 @@ public class BlockTranslator {
private static final Object2ObjectMap<String, String> JAVA_TO_BEDROCK_IDENTIFIERS = new Object2ObjectOpenHashMap<>(); private static final Object2ObjectMap<String, String> JAVA_TO_BEDROCK_IDENTIFIERS = new Object2ObjectOpenHashMap<>();
private static final BiMap<String, Integer> JAVA_ID_BLOCK_MAP = HashBiMap.create(); private static final BiMap<String, Integer> JAVA_ID_BLOCK_MAP = HashBiMap.create();
private static final IntSet WATERLOGGED = new IntOpenHashSet(); private static final IntSet WATERLOGGED = new IntOpenHashSet();
private static final Object2IntMap<NbtMap> ITEM_FRAMES = new Object2IntOpenHashMap<>(); private final Object2IntMap<NbtMap> itemFrames = new Object2IntOpenHashMap<>();
private final Map<String, NbtMap> flowerPotBlocks = new HashMap<>();
// Bedrock carpet ID, used in LlamaEntity.java for decoration // Bedrock carpet ID, used in LlamaEntity.java for decoration
public static final int CARPET = 171; public static final int CARPET = 171;
@ -85,7 +90,10 @@ public class BlockTranslator {
/** /**
* Runtime command block ID, used for fixing command block minecart appearances * Runtime command block ID, used for fixing command block minecart appearances
*/ */
public static final int BEDROCK_RUNTIME_COMMAND_BLOCK_ID; @Getter
private final int bedrockRuntimeCommandBlockId;
private final EmptyChunkProvider emptyChunkProvider;
/** /**
* A list of all Java runtime wool IDs, for use with block breaking math and shears * A list of all Java runtime wool IDs, for use with block breaking math and shears
@ -102,67 +110,34 @@ public class BlockTranslator {
* Contains a map of Java blocks to their respective Bedrock block tag, if the Java identifier is different from Bedrock. * Contains a map of Java blocks to their respective Bedrock block tag, if the Java identifier is different from Bedrock.
* Required to fix villager trades with these blocks. * Required to fix villager trades with these blocks.
*/ */
private static final Map<String, NbtMap> JAVA_IDENTIFIER_TO_BEDROCK_TAG; private final Map<String, NbtMap> javaIdentifierToBedrockTag;
private static final int BLOCK_STATE_VERSION = 17825808; private static final int BLOCK_STATE_VERSION = 17825808;
/**
* Stores the raw blocks JSON until it is no longer needed.
*/
public static JsonNode BLOCKS_JSON;
static { static {
/* Load block palette */ InputStream stream = FileUtils.getResource("mappings/blocks.json");
InputStream stream = FileUtils.getResource("bedrock/blockpalette.nbt");
NbtList<NbtMap> blocksTag;
try (NBTInputStream nbtInputStream = new NBTInputStream(new DataInputStream(stream))) {
NbtMap blockPalette = (NbtMap) nbtInputStream.readTag();
blocksTag = (NbtList<NbtMap>) blockPalette.getList("blocks", NbtType.COMPOUND);
} catch (Exception e) {
throw new AssertionError("Unable to get blocks from runtime block states", e);
}
JAVA_IDENTIFIER_TO_BEDROCK_TAG = new Object2ObjectOpenHashMap<>();
// New since 1.16.100 - find the block runtime ID by the order given to us in the block palette,
// as we no longer send a block palette
Object2IntMap<NbtMap> blockStateOrderedMap = new Object2IntOpenHashMap<>(blocksTag.size());
for (int i = 0; i < blocksTag.size(); i++) {
NbtMap tag = blocksTag.get(i);
NbtMap blockTag = tag.getCompound("block");
if (blockStateOrderedMap.containsKey(blockTag)) {
throw new AssertionError("Duplicate block states in Bedrock palette");
}
blockStateOrderedMap.put(blockTag, i);
}
stream = FileUtils.getResource("mappings/blocks.json");
JsonNode blocks;
try { try {
blocks = GeyserConnector.JSON_MAPPER.readTree(stream); BLOCKS_JSON = GeyserConnector.JSON_MAPPER.readTree(stream);
} catch (Exception e) { } catch (Exception e) {
throw new AssertionError("Unable to load Java block mappings", e); throw new AssertionError("Unable to load Java block mappings", e);
} }
Reflections ref = GeyserConnector.getInstance().useXmlReflections() ? FileUtils.getReflections("org.geysermc.connector.network.translators.world.block.entity")
: new Reflections("org.geysermc.connector.network.translators.world.block.entity");
int waterRuntimeId = -1;
int javaRuntimeId = -1; int javaRuntimeId = -1;
int airRuntimeId = -1;
int cobwebRuntimeId = -1; int cobwebRuntimeId = -1;
int commandBlockRuntimeId = -1;
int furnaceRuntimeId = -1; int furnaceRuntimeId = -1;
int furnaceLitRuntimeId = -1; int furnaceLitRuntimeId = -1;
int spawnerRuntimeId = -1; int spawnerRuntimeId = -1;
int uniqueJavaId = -1; int uniqueJavaId = -1;
Iterator<Map.Entry<String, JsonNode>> blocksIterator = blocks.fields(); Iterator<Map.Entry<String, JsonNode>> blocksIterator = BLOCKS_JSON.fields();
while (blocksIterator.hasNext()) { while (blocksIterator.hasNext()) {
javaRuntimeId++; javaRuntimeId++;
Map.Entry<String, JsonNode> entry = blocksIterator.next(); Map.Entry<String, JsonNode> entry = blocksIterator.next();
String javaId = entry.getKey(); String javaId = entry.getKey();
NbtMap blockTag = buildBedrockState(entry.getValue());
int bedrockRuntimeId = blockStateOrderedMap.getOrDefault(blockTag, -1);
if (bedrockRuntimeId == -1) {
throw new RuntimeException("Unable to find " + javaId + " Bedrock runtime ID!");
}
// TODO fix this, (no block should have a null hardness) // TODO fix this, (no block should have a null hardness)
JsonNode hardnessNode = entry.getValue().get("block_hardness"); JsonNode hardnessNode = entry.getValue().get("block_hardness");
@ -198,52 +173,22 @@ public class BlockTranslator {
String cleanJavaIdentifier = entry.getKey().split("\\[")[0]; String cleanJavaIdentifier = entry.getKey().split("\\[")[0];
String bedrockIdentifier = entry.getValue().get("bedrock_identifier").asText(); String bedrockIdentifier = entry.getValue().get("bedrock_identifier").asText();
boolean javaIdentifierSameAsBedrock = cleanJavaIdentifier.equals(bedrockIdentifier);
if (!JAVA_ID_TO_JAVA_IDENTIFIER_MAP.containsValue(cleanJavaIdentifier)) { if (!JAVA_ID_TO_JAVA_IDENTIFIER_MAP.containsValue(cleanJavaIdentifier)) {
uniqueJavaId++; uniqueJavaId++;
JAVA_ID_TO_JAVA_IDENTIFIER_MAP.put(uniqueJavaId, cleanJavaIdentifier); JAVA_ID_TO_JAVA_IDENTIFIER_MAP.put(uniqueJavaId, cleanJavaIdentifier);
if (!javaIdentifierSameAsBedrock) {
JAVA_IDENTIFIER_TO_BEDROCK_TAG.put(cleanJavaIdentifier, blockTag);
}
} }
if (!javaIdentifierSameAsBedrock) { // Keeping this here since this is currently unchanged between versions
if (!cleanJavaIdentifier.equals(bedrockIdentifier)) {
JAVA_TO_BEDROCK_IDENTIFIERS.put(cleanJavaIdentifier, bedrockIdentifier); JAVA_TO_BEDROCK_IDENTIFIERS.put(cleanJavaIdentifier, bedrockIdentifier);
} }
// Get the tag needed for non-empty flower pots if (javaId.contains("wool")) {
if (entry.getValue().get("pottable") != null) {
BlockStateValues.getFlowerPotBlocks().put(cleanJavaIdentifier, buildBedrockState(entry.getValue()));
}
if ("minecraft:water[level=0]".equals(javaId)) {
waterRuntimeId = bedrockRuntimeId;
}
boolean waterlogged = entry.getKey().contains("waterlogged=true")
|| javaId.contains("minecraft:bubble_column") || javaId.contains("minecraft:kelp") || javaId.contains("seagrass");
if (waterlogged) {
BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId | 1 << 31, javaRuntimeId);
WATERLOGGED.add(javaRuntimeId);
} else {
BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId, javaRuntimeId);
}
JAVA_TO_BEDROCK_BLOCK_MAP.put(javaRuntimeId, bedrockRuntimeId);
if (bedrockIdentifier.equals("minecraft:air")) {
airRuntimeId = bedrockRuntimeId;
} else if (javaId.contains("wool")) {
JAVA_RUNTIME_WOOL_IDS.add(javaRuntimeId); JAVA_RUNTIME_WOOL_IDS.add(javaRuntimeId);
} else if (javaId.contains("cobweb")) { } else if (javaId.contains("cobweb")) {
cobwebRuntimeId = javaRuntimeId; cobwebRuntimeId = javaRuntimeId;
} else if (javaId.equals("minecraft:command_block[conditional=false,facing=north]")) {
commandBlockRuntimeId = bedrockRuntimeId;
} else if (javaId.startsWith("minecraft:furnace[facing=north")) { } else if (javaId.startsWith("minecraft:furnace[facing=north")) {
if (javaId.contains("lit=true")) { if (javaId.contains("lit=true")) {
furnaceLitRuntimeId = javaRuntimeId; furnaceLitRuntimeId = javaRuntimeId;
@ -261,11 +206,6 @@ public class BlockTranslator {
} }
JAVA_RUNTIME_COBWEB_ID = cobwebRuntimeId; JAVA_RUNTIME_COBWEB_ID = cobwebRuntimeId;
if (commandBlockRuntimeId == -1) {
throw new AssertionError("Unable to find command block in palette");
}
BEDROCK_RUNTIME_COMMAND_BLOCK_ID = commandBlockRuntimeId;
if (furnaceRuntimeId == -1) { if (furnaceRuntimeId == -1) {
throw new AssertionError("Unable to find furnace in palette"); throw new AssertionError("Unable to find furnace in palette");
} }
@ -281,35 +221,123 @@ public class BlockTranslator {
} }
JAVA_RUNTIME_SPAWNER_ID = spawnerRuntimeId; JAVA_RUNTIME_SPAWNER_ID = spawnerRuntimeId;
BlockTranslator1_16_100.init();
BlockTranslator1_16_210.init();
BLOCKS_JSON = null; // We no longer require this so let it garbage collect away
}
public BlockTranslator(String paletteFile) {
/* Load block palette */
InputStream stream = FileUtils.getResource(paletteFile);
NbtList<NbtMap> blocksTag;
try (NBTInputStream nbtInputStream = new NBTInputStream(new DataInputStream(new GZIPInputStream(stream)))) {
NbtMap blockPalette = (NbtMap) nbtInputStream.readTag();
blocksTag = (NbtList<NbtMap>) blockPalette.getList("blocks", NbtType.COMPOUND);
} catch (Exception e) {
throw new AssertionError("Unable to get blocks from runtime block states", e);
}
javaIdentifierToBedrockTag = new Object2ObjectOpenHashMap<>();
// New since 1.16.100 - find the block runtime ID by the order given to us in the block palette,
// as we no longer send a block palette
Object2IntMap<NbtMap> blockStateOrderedMap = new Object2IntOpenHashMap<>(blocksTag.size());
for (int i = 0; i < blocksTag.size(); i++) {
NbtMap tag = blocksTag.get(i);
if (blockStateOrderedMap.containsKey(tag)) {
throw new AssertionError("Duplicate block states in Bedrock palette: " + tag);
}
blockStateOrderedMap.put(tag, i);
}
int airRuntimeId = -1;
int commandBlockRuntimeId = -1;
int javaRuntimeId = -1;
int waterRuntimeId = -1;
Iterator<Map.Entry<String, JsonNode>> blocksIterator = BLOCKS_JSON.fields();
while (blocksIterator.hasNext()) {
javaRuntimeId++;
Map.Entry<String, JsonNode> entry = blocksIterator.next();
String javaId = entry.getKey();
NbtMap blockTag = buildBedrockState(entry.getValue());
int bedrockRuntimeId = blockStateOrderedMap.getOrDefault(blockTag, -1);
if (bedrockRuntimeId == -1) {
throw new RuntimeException("Unable to find " + javaId + " Bedrock runtime ID! Built compound tag: \n" + blockTag);
}
switch (javaId) {
case "minecraft:air":
airRuntimeId = bedrockRuntimeId;
break;
case "minecraft:water[level=0]":
waterRuntimeId = bedrockRuntimeId;
break;
case "minecraft:command_block[conditional=false,facing=north]":
commandBlockRuntimeId = bedrockRuntimeId;
break;
}
boolean waterlogged = entry.getKey().contains("waterlogged=true")
|| javaId.contains("minecraft:bubble_column") || javaId.contains("minecraft:kelp") || javaId.contains("seagrass");
if (waterlogged) {
bedrockToJavaBlockMap.putIfAbsent(bedrockRuntimeId | 1 << 31, javaRuntimeId);
WATERLOGGED.add(javaRuntimeId);
} else {
bedrockToJavaBlockMap.putIfAbsent(bedrockRuntimeId, javaRuntimeId);
}
String cleanJavaIdentifier = entry.getKey().split("\\[")[0];
// Get the tag needed for non-empty flower pots
if (entry.getValue().get("pottable") != null) {
flowerPotBlocks.put(cleanJavaIdentifier, blockTag);
}
if (!cleanJavaIdentifier.equals(entry.getValue().get("bedrock_identifier").asText())) {
javaIdentifierToBedrockTag.put(cleanJavaIdentifier, blockTag);
}
javaToBedrockBlockMap.put(javaRuntimeId, bedrockRuntimeId);
}
if (commandBlockRuntimeId == -1) {
throw new AssertionError("Unable to find command block in palette");
}
bedrockRuntimeCommandBlockId = commandBlockRuntimeId;
if (waterRuntimeId == -1) { if (waterRuntimeId == -1) {
throw new AssertionError("Unable to find water in palette"); throw new AssertionError("Unable to find water in palette");
} }
BEDROCK_WATER_ID = waterRuntimeId; bedrockWaterId = waterRuntimeId;
if (airRuntimeId == -1) { if (airRuntimeId == -1) {
throw new AssertionError("Unable to find air in palette"); throw new AssertionError("Unable to find air in palette");
} }
BEDROCK_AIR_ID = airRuntimeId; bedrockAirId = airRuntimeId;
// Loop around again to find all item frame runtime IDs // Loop around again to find all item frame runtime IDs
for (Object2IntMap.Entry<NbtMap> entry : blockStateOrderedMap.object2IntEntrySet()) { for (Object2IntMap.Entry<NbtMap> entry : blockStateOrderedMap.object2IntEntrySet()) {
if (entry.getKey().getString("name").equals("minecraft:frame")) { if (entry.getKey().getString("name").equals("minecraft:frame")) {
ITEM_FRAMES.put(entry.getKey(), entry.getIntValue()); itemFrames.put(entry.getKey(), entry.getIntValue());
}
} }
} }
private BlockTranslator() { this.emptyChunkProvider = new EmptyChunkProvider(bedrockAirId);
} }
public static void init() { public static void init() {
// no-op // no-op
} }
private static NbtMap buildBedrockState(JsonNode node) { private NbtMap buildBedrockState(JsonNode node) {
NbtMapBuilder tagBuilder = NbtMap.builder(); NbtMapBuilder tagBuilder = NbtMap.builder();
tagBuilder.putString("name", node.get("bedrock_identifier").textValue()) String bedrockIdentifier = node.get("bedrock_identifier").textValue();
.putInt("version", BlockTranslator.BLOCK_STATE_VERSION); tagBuilder.putString("name", bedrockIdentifier)
.putInt("version", getBlockStateVersion());
NbtMapBuilder statesBuilder = NbtMap.builder(); NbtMapBuilder statesBuilder = NbtMap.builder();
@ -332,36 +360,67 @@ public class BlockTranslator {
} }
} }
} }
tagBuilder.put("states", statesBuilder.build()); tagBuilder.put("states", adjustBlockStateForVersion(bedrockIdentifier, statesBuilder).build());
return tagBuilder.build(); return tagBuilder.build();
} }
public static int getBedrockBlockId(int state) { /**
return JAVA_TO_BEDROCK_BLOCK_MAP.get(state); * @return an adjusted state list, if necessary, that converts Geyser's new mapping to Bedrock's older version
* of the mapping.
*/
protected NbtMapBuilder adjustBlockStateForVersion(String bedrockIdentifier, NbtMapBuilder statesBuilder) {
return statesBuilder;
} }
public static int getJavaBlockState(int bedrockId) { public int getBedrockBlockId(int state) {
return BEDROCK_TO_JAVA_BLOCK_MAP.get(bedrockId); return javaToBedrockBlockMap.get(state);
}
public int getJavaBlockState(int bedrockId) {
return bedrockToJavaBlockMap.get(bedrockId);
} }
/** /**
* @param javaIdentifier the Java identifier of the block to search for * @param javaIdentifier the Java identifier of the block to search for
* @return the Bedrock identifier if different, or else the Java identifier * @return the Bedrock identifier if different, or else the Java identifier
*/ */
public static String getBedrockBlockIdentifier(String javaIdentifier) { public String getBedrockBlockIdentifier(String javaIdentifier) {
return JAVA_TO_BEDROCK_IDENTIFIERS.getOrDefault(javaIdentifier, javaIdentifier); return JAVA_TO_BEDROCK_IDENTIFIERS.getOrDefault(javaIdentifier, javaIdentifier);
} }
public static int getItemFrame(NbtMap tag) { public int getItemFrame(NbtMap tag) {
return ITEM_FRAMES.getOrDefault(tag, -1); return itemFrames.getOrDefault(tag, -1);
} }
public static boolean isItemFrame(int bedrockBlockRuntimeId) { public boolean isItemFrame(int bedrockBlockRuntimeId) {
return ITEM_FRAMES.values().contains(bedrockBlockRuntimeId); return itemFrames.values().contains(bedrockBlockRuntimeId);
} }
public static int getBlockStateVersion() { /**
return BLOCK_STATE_VERSION; * Get the map of contained flower pot plants to Bedrock CompoundTag
*
* @return Map of flower pot blocks.
*/
public Map<String, NbtMap> getFlowerPotBlocks() {
return flowerPotBlocks;
}
public int getBedrockAirId() {
return bedrockAirId;
}
public int getBedrockWaterId() {
return bedrockWaterId;
}
public abstract int getBlockStateVersion();
public byte[] getEmptyChunkData() {
return emptyChunkProvider.getEmptyLevelChunkData();
}
public ChunkSection getEmptyChunkSection() {
return emptyChunkProvider.getEmptySection();
} }
/** /**
@ -380,10 +439,6 @@ public class BlockTranslator {
return JAVA_ID_BLOCK_MAP; return JAVA_ID_BLOCK_MAP;
} }
public static int getJavaWaterloggedState(int bedrockId) {
return BEDROCK_TO_JAVA_BLOCK_MAP.get(1 << 31 | bedrockId);
}
/** /**
* Get the item a Java client would receive when pressing * Get the item a Java client would receive when pressing
* the Pick Block key on a specific Java block state. * the Pick Block key on a specific Java block state.
@ -411,7 +466,7 @@ public class BlockTranslator {
* *
* @return the block tag of the block name mapped from Java to Bedrock. * @return the block tag of the block name mapped from Java to Bedrock.
*/ */
public static NbtMap getBedrockBlockNbt(String cleanJavaIdentifier) { public NbtMap getBedrockBlockNbt(String cleanJavaIdentifier) {
return JAVA_IDENTIFIER_TO_BEDROCK_TAG.get(cleanJavaIdentifier); return javaIdentifierToBedrockTag.get(cleanJavaIdentifier);
} }
} }

Datei anzeigen

@ -0,0 +1,59 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.connector.network.translators.world.block;
import com.google.common.collect.ImmutableSet;
import com.nukkitx.nbt.NbtMapBuilder;
import java.util.Set;
public class BlockTranslator1_16_100 extends BlockTranslator {
private static final Set<String> CORRECTED_STATES = ImmutableSet.of("minecraft:stripped_warped_stem",
"minecraft:stripped_warped_hyphae", "minecraft:stripped_crimson_stem", "minecraft:stripped_crimson_hyphae");
public static final BlockTranslator1_16_100 INSTANCE = new BlockTranslator1_16_100();
public BlockTranslator1_16_100() {
super("bedrock/blockpalette.1_16_100.nbt");
}
@Override
public int getBlockStateVersion() {
return 17825808;
}
@Override
protected NbtMapBuilder adjustBlockStateForVersion(String bedrockIdentifier, NbtMapBuilder statesBuilder) {
if (CORRECTED_STATES.contains(bedrockIdentifier)) {
statesBuilder.putInt("deprecated", 0);
}
return super.adjustBlockStateForVersion(bedrockIdentifier, statesBuilder);
}
public static void init() {
// no-op
}
}

Datei anzeigen

@ -0,0 +1,43 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.connector.network.translators.world.block;
public class BlockTranslator1_16_210 extends BlockTranslator {
public static final BlockTranslator1_16_210 INSTANCE = new BlockTranslator1_16_210();
public BlockTranslator1_16_210() {
super("bedrock/blockpalette.1_16_210.nbt");
}
@Override
public int getBlockStateVersion() {
return 17879555;
}
public static void init() {
// no-op
}
}

Datei anzeigen

@ -47,9 +47,9 @@ public interface BedrockOnlyBlockEntity {
* @param blockState Java BlockState of block. * @param blockState Java BlockState of block.
* @return Bedrock tag, or null if not a Bedrock-only Block Entity * @return Bedrock tag, or null if not a Bedrock-only Block Entity
*/ */
static NbtMap getTag(Vector3i position, int blockState) { static NbtMap getTag(GeyserSession session, Vector3i position, int blockState) {
if (FlowerPotBlockEntityTranslator.isFlowerBlock(blockState)) { if (FlowerPotBlockEntityTranslator.isFlowerBlock(blockState)) {
return FlowerPotBlockEntityTranslator.getTag(blockState, position); return FlowerPotBlockEntityTranslator.getTag(session, blockState, position);
} else if (PistonBlockEntityTranslator.isBlock(blockState)) { } else if (PistonBlockEntityTranslator.isBlock(blockState)) {
return PistonBlockEntityTranslator.getTag(blockState, position); return PistonBlockEntityTranslator.getTag(blockState, position);
} }

Datei anzeigen

@ -31,7 +31,6 @@ import com.nukkitx.nbt.NbtMapBuilder;
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.block.BlockStateValues; import org.geysermc.connector.network.translators.world.block.BlockStateValues;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.utils.BlockEntityUtils; import org.geysermc.connector.utils.BlockEntityUtils;
public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity, RequiresBlockState { public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity, RequiresBlockState {
@ -50,7 +49,7 @@ public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity, R
* @param position Bedrock position of flower pot. * @param position Bedrock position of flower pot.
* @return Bedrock tag of flower pot. * @return Bedrock tag of flower pot.
*/ */
public static NbtMap getTag(int blockState, Vector3i position) { public static NbtMap getTag(GeyserSession session, int blockState, Vector3i position) {
NbtMapBuilder tagBuilder = NbtMap.builder() NbtMapBuilder tagBuilder = NbtMap.builder()
.putInt("x", position.getX()) .putInt("x", position.getX())
.putInt("y", position.getY()) .putInt("y", position.getY())
@ -62,7 +61,7 @@ public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity, R
if (name != null) { if (name != null) {
// Get the Bedrock CompoundTag of the block. // Get the Bedrock CompoundTag of the block.
// This is where we need to store the *Java* name because Bedrock has six minecraft:sapling blocks with different block states. // This is where we need to store the *Java* name because Bedrock has six minecraft:sapling blocks with different block states.
NbtMap plant = BlockStateValues.getFlowerPotBlocks().get(name); NbtMap plant = session.getBlockTranslator().getFlowerPotBlocks().get(name);
if (plant != null) { if (plant != null) {
tagBuilder.put("PlantBlock", plant.toBuilder().build()); tagBuilder.put("PlantBlock", plant.toBuilder().build());
} }
@ -77,15 +76,16 @@ public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity, R
@Override @Override
public void updateBlock(GeyserSession session, int blockState, Vector3i position) { public void updateBlock(GeyserSession session, int blockState, Vector3i position) {
BlockEntityUtils.updateBlockEntity(session, getTag(blockState, position), position); NbtMap tag = getTag(session, blockState, position);
BlockEntityUtils.updateBlockEntity(session, tag, position);
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
updateBlockPacket.setDataLayer(0); updateBlockPacket.setDataLayer(0);
updateBlockPacket.setRuntimeId(BlockTranslator.getBedrockBlockId(blockState)); updateBlockPacket.setRuntimeId(session.getBlockTranslator().getBedrockBlockId(blockState));
updateBlockPacket.setBlockPosition(position); updateBlockPacket.setBlockPosition(position);
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS);
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK);
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY);
session.sendUpstreamPacket(updateBlockPacket); session.sendUpstreamPacket(updateBlockPacket);
BlockEntityUtils.updateBlockEntity(session, getTag(blockState, position), position); BlockEntityUtils.updateBlockEntity(session, tag, position);
} }
} }

Datei anzeigen

@ -30,7 +30,6 @@ import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
import lombok.Getter; import lombok.Getter;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.network.translators.world.chunk.bitarray.BitArray; import org.geysermc.connector.network.translators.world.chunk.bitarray.BitArray;
import org.geysermc.connector.network.translators.world.chunk.bitarray.BitArrayVersion; import org.geysermc.connector.network.translators.world.chunk.bitarray.BitArrayVersion;
@ -44,14 +43,14 @@ public class BlockStorage {
private final IntList palette; private final IntList palette;
private BitArray bitArray; private BitArray bitArray;
public BlockStorage() { public BlockStorage(int airBlockId) {
this(BitArrayVersion.V2); this(airBlockId, BitArrayVersion.V2);
} }
public BlockStorage(BitArrayVersion version) { public BlockStorage(int airBlockId, BitArrayVersion version) {
this.bitArray = version.createArray(SIZE); this.bitArray = version.createArray(SIZE);
this.palette = new IntArrayList(16); this.palette = new IntArrayList(16);
this.palette.add(BlockTranslator.BEDROCK_AIR_ID); // Air is at the start of every palette and controls what the default block is in second-layer non-air block spaces. this.palette.add(airBlockId); // Air is at the start of every palette and controls what the default block is in second-layer non-air block spaces.
} }
public BlockStorage(BitArray bitArray, IntList palette) { public BlockStorage(BitArray bitArray, IntList palette) {

Datei anzeigen

@ -34,8 +34,8 @@ public class ChunkSection {
private final BlockStorage[] storage; private final BlockStorage[] storage;
public ChunkSection() { public ChunkSection(int airBlockId) {
this(new BlockStorage[]{new BlockStorage(), new BlockStorage()}); this(new BlockStorage[]{new BlockStorage(airBlockId), new BlockStorage(airBlockId)});
} }
public ChunkSection(BlockStorage[] storage) { public ChunkSection(BlockStorage[] storage) {

Datei anzeigen

@ -0,0 +1,58 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.connector.network.translators.world.chunk;
import com.nukkitx.nbt.NBTOutputStream;
import com.nukkitx.nbt.NbtMap;
import com.nukkitx.nbt.NbtUtils;
import lombok.Getter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class EmptyChunkProvider {
@Getter
private final byte[] emptyLevelChunkData;
@Getter
private final ChunkSection emptySection;
public EmptyChunkProvider(int airId) {
BlockStorage emptyStorage = new BlockStorage(airId);
emptySection = new ChunkSection(new BlockStorage[]{emptyStorage});
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
outputStream.write(new byte[258]); // Biomes + Border Size + Extra Data Size
try (NBTOutputStream stream = NbtUtils.createNetworkWriter(outputStream)) {
stream.writeTag(NbtMap.EMPTY);
}
emptyLevelChunkData = outputStream.toByteArray();
} catch (IOException e) {
throw new AssertionError("Unable to generate empty level chunk data");
}
}
}

Datei anzeigen

@ -132,7 +132,7 @@ public class BlockUtils {
miningFatigueLevel = session.getEffectCache().getEffectLevel(Effect.SLOWER_DIG); miningFatigueLevel = session.getEffectCache().getEffectLevel(Effect.SLOWER_DIG);
boolean isInWater = session.getConnector().getConfig().isCacheChunks() boolean isInWater = session.getConnector().getConfig().isCacheChunks()
&& BlockTranslator.getBedrockBlockId(session.getConnector().getWorldManager().getBlockAt(session, session.getPlayerEntity().getPosition().toInt())) == BlockTranslator.BEDROCK_WATER_ID; && session.getBlockTranslator().getBedrockBlockId(session.getConnector().getWorldManager().getBlockAt(session, session.getPlayerEntity().getPosition().toInt())) == session.getBlockTranslator().getBedrockWaterId();
boolean insideOfWaterWithoutAquaAffinity = isInWater && boolean insideOfWaterWithoutAquaAffinity = isInWater &&
ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getNbt(), "minecraft:aqua_affinity") < 1; ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getNbt(), "minecraft:aqua_affinity") < 1;

Datei anzeigen

@ -36,9 +36,7 @@ import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag; import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.nukkitx.math.vector.Vector2i; import com.nukkitx.math.vector.Vector2i;
import com.nukkitx.math.vector.Vector3i; import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.nbt.NBTOutputStream;
import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtMap;
import com.nukkitx.nbt.NbtUtils;
import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket; import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket;
import com.nukkitx.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket; import com.nukkitx.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket;
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
@ -65,13 +63,11 @@ import org.geysermc.connector.network.translators.world.chunk.ChunkSection;
import org.geysermc.connector.network.translators.world.chunk.bitarray.BitArray; import org.geysermc.connector.network.translators.world.chunk.bitarray.BitArray;
import org.geysermc.connector.network.translators.world.chunk.bitarray.BitArrayVersion; import org.geysermc.connector.network.translators.world.chunk.bitarray.BitArrayVersion;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.BitSet; import java.util.BitSet;
import java.util.List; import java.util.List;
import static org.geysermc.connector.network.translators.world.block.BlockTranslator.*; import static org.geysermc.connector.network.translators.world.block.BlockTranslator.JAVA_AIR_ID;
@UtilityClass @UtilityClass
public class ChunkUtils { public class ChunkUtils {
@ -81,26 +77,6 @@ public class ChunkUtils {
*/ */
public static final Object2IntMap<Position> CACHED_BLOCK_ENTITIES = new Object2IntOpenHashMap<>(); public static final Object2IntMap<Position> CACHED_BLOCK_ENTITIES = new Object2IntOpenHashMap<>();
private static final NbtMap EMPTY_TAG = NbtMap.builder().build();
public static final byte[] EMPTY_LEVEL_CHUNK_DATA;
public static final BlockStorage EMPTY_STORAGE = new BlockStorage();
public static final ChunkSection EMPTY_SECTION = new ChunkSection(new BlockStorage[]{ EMPTY_STORAGE });
static {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
outputStream.write(new byte[258]); // Biomes + Border Size + Extra Data Size
try (NBTOutputStream stream = NbtUtils.createNetworkWriter(outputStream)) {
stream.writeTag(EMPTY_TAG);
}
EMPTY_LEVEL_CHUNK_DATA = outputStream.toByteArray();
} catch (IOException e) {
throw new AssertionError("Unable to generate empty level chunk data");
}
}
private static int indexYZXtoXZY(int yzx) { private static int indexYZXtoXZY(int yzx) {
return (yzx >> 8) | (yzx & 0x0F0) | ((yzx & 0x00F) << 8); return (yzx >> 8) | (yzx & 0x0F0) | ((yzx & 0x00F) << 8);
} }
@ -162,20 +138,20 @@ public class ChunkUtils {
if (javaPalette instanceof GlobalPalette) { if (javaPalette instanceof GlobalPalette) {
// As this is the global palette, simply iterate through the whole chunk section once // As this is the global palette, simply iterate through the whole chunk section once
ChunkSection section = new ChunkSection(); ChunkSection section = new ChunkSection(session.getBlockTranslator().getBedrockAirId());
for (int yzx = 0; yzx < BlockStorage.SIZE; yzx++) { for (int yzx = 0; yzx < BlockStorage.SIZE; yzx++) {
int javaId = javaData.get(yzx); int javaId = javaData.get(yzx);
int bedrockId = BlockTranslator.getBedrockBlockId(javaId); int bedrockId = session.getBlockTranslator().getBedrockBlockId(javaId);
int xzy = indexYZXtoXZY(yzx); int xzy = indexYZXtoXZY(yzx);
section.getBlockStorageArray()[0].setFullBlock(xzy, bedrockId); section.getBlockStorageArray()[0].setFullBlock(xzy, bedrockId);
if (BlockTranslator.isWaterlogged(javaId)) { if (BlockTranslator.isWaterlogged(javaId)) {
section.getBlockStorageArray()[1].setFullBlock(xzy, BEDROCK_WATER_ID); section.getBlockStorageArray()[1].setFullBlock(xzy, session.getBlockTranslator().getBedrockWaterId());
} }
// Check if block is piston or flower to see if we'll need to create additional block entities, as they're only block entities in Bedrock // Check if block is piston or flower to see if we'll need to create additional block entities, as they're only block entities in Bedrock
if (BlockStateValues.getFlowerPotValues().containsKey(javaId) || BlockStateValues.getPistonValues().containsKey(javaId)) { if (BlockStateValues.getFlowerPotValues().containsKey(javaId) || BlockStateValues.getPistonValues().containsKey(javaId)) {
bedrockOnlyBlockEntities.add(BedrockOnlyBlockEntity.getTag( bedrockOnlyBlockEntities.add(BedrockOnlyBlockEntity.getTag(session,
Vector3i.from((column.getX() << 4) + (yzx & 0xF), (sectionY << 4) + ((yzx >> 8) & 0xF), (column.getZ() << 4) + ((yzx >> 4) & 0xF)), Vector3i.from((column.getX() << 4) + (yzx & 0xF), (sectionY << 4) + ((yzx >> 8) & 0xF), (column.getZ() << 4) + ((yzx >> 4) & 0xF)),
javaId javaId
)); ));
@ -192,7 +168,7 @@ public class ChunkUtils {
// Iterate through palette and convert state IDs to Bedrock, doing some additional checks as we go // Iterate through palette and convert state IDs to Bedrock, doing some additional checks as we go
for (int i = 0; i < javaPalette.size(); i++) { for (int i = 0; i < javaPalette.size(); i++) {
int javaId = javaPalette.idToState(i); int javaId = javaPalette.idToState(i);
bedrockPalette.add(BlockTranslator.getBedrockBlockId(javaId)); bedrockPalette.add(session.getBlockTranslator().getBedrockBlockId(javaId));
if (BlockTranslator.isWaterlogged(javaId)) { if (BlockTranslator.isWaterlogged(javaId)) {
waterloggedPaletteIds.set(i); waterloggedPaletteIds.set(i);
@ -211,7 +187,7 @@ public class ChunkUtils {
for (int yzx = 0; yzx < BlockStorage.SIZE; yzx++) { for (int yzx = 0; yzx < BlockStorage.SIZE; yzx++) {
int paletteId = javaData.get(yzx); int paletteId = javaData.get(yzx);
if (pistonOrFlowerPaletteIds.get(paletteId)) { if (pistonOrFlowerPaletteIds.get(paletteId)) {
bedrockOnlyBlockEntities.add(BedrockOnlyBlockEntity.getTag( bedrockOnlyBlockEntities.add(BedrockOnlyBlockEntity.getTag(session,
Vector3i.from((column.getX() << 4) + (yzx & 0xF), (sectionY << 4) + ((yzx >> 8) & 0xF), (column.getZ() << 4) + ((yzx >> 4) & 0xF)), Vector3i.from((column.getX() << 4) + (yzx & 0xF), (sectionY << 4) + ((yzx >> 8) & 0xF), (column.getZ() << 4) + ((yzx >> 4) & 0xF)),
javaPalette.idToState(paletteId) javaPalette.idToState(paletteId)
)); ));
@ -248,8 +224,8 @@ public class ChunkUtils {
// V1 palette // V1 palette
IntList layer1Palette = new IntArrayList(2); IntList layer1Palette = new IntArrayList(2);
layer1Palette.add(BEDROCK_AIR_ID); // Air - see BlockStorage's constructor for more information layer1Palette.add(session.getBlockTranslator().getBedrockAirId()); // Air - see BlockStorage's constructor for more information
layer1Palette.add(BEDROCK_WATER_ID); layer1Palette.add(session.getBlockTranslator().getBedrockWaterId());
layers = new BlockStorage[]{ layer0, new BlockStorage(BitArrayVersion.V1.createArray(BlockStorage.SIZE, layer1Data), layer1Palette) }; layers = new BlockStorage[]{ layer0, new BlockStorage(BitArrayVersion.V1.createArray(BlockStorage.SIZE, layer1Data), layer1Palette) };
} }
@ -376,7 +352,7 @@ public class ChunkUtils {
skull.despawnEntity(session, position); skull.despawnEntity(session, position);
} }
int blockId = BlockTranslator.getBedrockBlockId(blockState); int blockId = session.getBlockTranslator().getBedrockBlockId(blockState);
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
updateBlockPacket.setDataLayer(0); updateBlockPacket.setDataLayer(0);
@ -390,9 +366,9 @@ public class ChunkUtils {
waterPacket.setDataLayer(1); waterPacket.setDataLayer(1);
waterPacket.setBlockPosition(position); waterPacket.setBlockPosition(position);
if (BlockTranslator.isWaterlogged(blockState)) { if (BlockTranslator.isWaterlogged(blockState)) {
waterPacket.setRuntimeId(BEDROCK_WATER_ID); waterPacket.setRuntimeId(session.getBlockTranslator().getBedrockWaterId());
} else { } else {
waterPacket.setRuntimeId(BEDROCK_AIR_ID); waterPacket.setRuntimeId(session.getBlockTranslator().getBedrockAirId());
} }
session.sendUpstreamPacket(waterPacket); session.sendUpstreamPacket(waterPacket);
@ -447,7 +423,7 @@ public class ChunkUtils {
data.setChunkX(chunkX + x); data.setChunkX(chunkX + x);
data.setChunkZ(chunkZ + z); data.setChunkZ(chunkZ + z);
data.setSubChunksLength(0); data.setSubChunksLength(0);
data.setData(EMPTY_LEVEL_CHUNK_DATA); data.setData(session.getBlockTranslator().getEmptyChunkData());
data.setCachingEnabled(false); data.setCachingEnabled(false);
session.sendUpstreamPacket(data); session.sendUpstreamPacket(data);

Binäre Datei nicht angezeigt.

Binäre Datei nicht angezeigt.

@ -1 +1 @@
Subproject commit bffb5617c1ecdacc10031c6ec36988a5f04cb5c6 Subproject commit 3d3b60de724f3f552f351c5f400269fde7598b67

@ -1 +1 @@
Subproject commit abadb6412c22f2f34eded7ea720e04e8bc7d0f22 Subproject commit 216e9008678a761b3885808f4f3d43000404381b