diff --git a/README.md b/README.md index a94914db1..ed53e5fe5 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,9 @@ Geyser is a bridge between Minecraft: Bedrock Edition and Minecraft: Java Editio ## What is Geyser? Geyser is a proxy, bridging the gap between Minecraft: Bedrock Edition and Minecraft: Java Edition servers. -The ultimate goal of this project is to allow Minecraft: Bedrock Edition users to join Minecraft: Java Edition servers as seamlessly as possible. +The ultimate goal of this project is to allow Minecraft: Bedrock Edition users to join Minecraft: Java Edition servers as seamlessly as possible. **Please note, this project is still a work in progress and should not be used on production. Expect bugs!** -### Please note, this project is still a work in progress and should not be used on production. Expect bugs! +### Currently supporting Minecraft Bedrock v1.14.X and Minecraft Java v1.15.2. ## Setting Up Please note, Geyser is **not** (currently) a plugin. Watch the video below or take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set it up. @@ -35,7 +35,6 @@ Please note, Geyser is **not** (currently) a plugin. Watch the video below or ta - Block Particles - Block Entities ([`block-entities`](https://github.com/GeyserMC/Geyser/tree/block-entities)) - Some Entity Flags -- Proper Movement - Support to be Ran as a Plugin ([`plugin`](https://github.com/GeyserMC/Geyser/tree/plugin)) ## Compiling diff --git a/connector/pom.xml b/connector/pom.xml index c61311590..ee0680d9c 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -67,7 +67,7 @@ com.nukkitx.protocol bedrock-v389 - 2.4.4 + 2.5.1 compile diff --git a/connector/src/main/java/org/geysermc/connector/entity/Entity.java b/connector/src/main/java/org/geysermc/connector/entity/Entity.java index 47b398748..6907f489b 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -30,7 +30,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; import com.github.steveice10.mc.protocol.data.message.TextMessage; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityDataDictionary; +import com.nukkitx.protocol.bedrock.data.EntityDataMap; import com.nukkitx.protocol.bedrock.data.EntityFlag; import com.nukkitx.protocol.bedrock.data.EntityFlags; import com.nukkitx.protocol.bedrock.packet.*; @@ -65,7 +65,6 @@ public class Entity { protected Vector3f rotation; protected float scale = 1; - protected boolean movePending; protected EntityType entityType; @@ -73,20 +72,20 @@ public class Entity { protected LongSet passengers = new LongOpenHashSet(); protected Map attributes = new HashMap<>(); - protected EntityDataDictionary metadata = new EntityDataDictionary(); + protected EntityDataMap metadata = new EntityDataMap(); public Entity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { this.entityId = entityId; this.geyserId = geyserId; this.entityType = entityType; - this.position = position; this.motion = motion; this.rotation = rotation; this.valid = false; - this.movePending = false; this.dimension = 0; + setPosition(position); + metadata.put(EntityData.SCALE, 1f); metadata.put(EntityData.MAX_AIR, (short) 400); metadata.put(EntityData.AIR, (short) 0); @@ -132,28 +131,45 @@ public class Entity { return true; } - public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch) { - moveRelative(relX, relY, relZ, Vector3f.from(yaw, pitch, yaw)); + public void moveRelative(GeyserSession session, double relX, double relY, double relZ, float yaw, float pitch, boolean isOnGround) { + moveRelative(session, relX, relY, relZ, Vector3f.from(yaw, pitch, yaw), isOnGround); } - public void moveRelative(double relX, double relY, double relZ, Vector3f rotation) { + public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) { setRotation(rotation); this.position = Vector3f.from(position.getX() + relX, position.getY() + relY, position.getZ() + relZ); - this.movePending = true; + + MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket(); + moveEntityPacket.setRuntimeEntityId(geyserId); + moveEntityPacket.setPosition(position); + moveEntityPacket.setRotation(getBedrockRotation()); + moveEntityPacket.setOnGround(isOnGround); + moveEntityPacket.setTeleported(false); + + session.getUpstream().sendPacket(moveEntityPacket); } - public void moveAbsolute(Vector3f position, float yaw, float pitch) { - moveAbsolute(position, Vector3f.from(yaw, pitch, yaw)); + public void moveAbsolute(GeyserSession session, Vector3f position, float yaw, float pitch, boolean isOnGround) { + moveAbsolute(session, position, Vector3f.from(yaw, pitch, yaw), isOnGround); } - public void moveAbsolute(Vector3f position, Vector3f rotation) { + public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround) { setPosition(position); setRotation(rotation); - this.movePending = true; + MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket(); + moveEntityPacket.setRuntimeEntityId(geyserId); + moveEntityPacket.setPosition(position); + moveEntityPacket.setRotation(getBedrockRotation()); + moveEntityPacket.setOnGround(isOnGround); + moveEntityPacket.setTeleported(false); + + session.getUpstream().sendPacket(moveEntityPacket); } public void updateBedrockAttributes(GeyserSession session) { + if (!valid) return; + List attributes = new ArrayList<>(); for (Map.Entry entry : this.attributes.entrySet()) { if (!entry.getValue().getType().isBedrockAttribute()) @@ -180,7 +196,7 @@ public class Entity { metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80); // metadata.getFlags().setFlag(EntityFlag.INVISIBLE, (xd & 0x20) == 0x20); if ((xd & 0x20) == 0x20) - metadata.put(EntityData.SCALE, 0.01f); + metadata.put(EntityData.SCALE, 0.0f); else metadata.put(EntityData.SCALE, scale); } @@ -191,7 +207,8 @@ public class Entity { metadata.put(EntityData.NAMETAG, MessageUtils.getBedrockMessage(name)); break; case 3: // is custom name visible - metadata.put(EntityData.ALWAYS_SHOW_NAMETAG, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0)); + if (!this.is(PlayerEntity.class)) + metadata.put(EntityData.ALWAYS_SHOW_NAMETAG, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0)); break; case 4: // silent metadata.getFlags().setFlag(EntityFlag.SILENT, (boolean) entityMetadata.getValue()); @@ -201,20 +218,18 @@ public class Entity { break; } + updateBedrockMetadata(session); + } + + public void updateBedrockMetadata(GeyserSession session) { + if (!valid) return; + SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); entityDataPacket.setRuntimeEntityId(geyserId); entityDataPacket.getMetadata().putAll(metadata); session.getUpstream().sendPacket(entityDataPacket); } - public void setPosition(Vector3f position) { - if (is(PlayerEntity.class)) { - this.position = position.add(0, entityType.getOffset(), 0); - return; - } - this.position = position; - } - /** * x = Pitch, y = HeadYaw, z = Yaw */ diff --git a/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java b/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java index 50d097db2..bbe72f996 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java @@ -27,6 +27,7 @@ package org.geysermc.connector.entity; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.ContainerId; import com.nukkitx.protocol.bedrock.data.EntityData; import com.nukkitx.protocol.bedrock.data.ItemData; import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket; @@ -42,11 +43,12 @@ import org.geysermc.connector.network.session.GeyserSession; @Setter public class LivingEntity extends Entity { - protected ItemData helmet; - protected ItemData chestplate; - protected ItemData leggings; - protected ItemData boots; - protected ItemData hand = ItemData.of(0, (short) 0, 0); + protected ItemData helmet = ItemData.AIR; + protected ItemData chestplate = ItemData.AIR; + protected ItemData leggings = ItemData.AIR; + protected ItemData boots = ItemData.AIR; + protected ItemData hand = ItemData.AIR; + protected ItemData offHand = ItemData.AIR; public LivingEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); @@ -80,11 +82,22 @@ public class LivingEntity extends Entity { armorEquipmentPacket.setLeggings(leggings); armorEquipmentPacket.setBoots(boots); - MobEquipmentPacket mobEquipmentPacket = new MobEquipmentPacket(); - mobEquipmentPacket.setRuntimeEntityId(geyserId); - mobEquipmentPacket.setItem(hand); + MobEquipmentPacket handPacket = new MobEquipmentPacket(); + handPacket.setRuntimeEntityId(geyserId); + handPacket.setItem(hand); + handPacket.setHotbarSlot(-1); + handPacket.setInventorySlot(0); + handPacket.setContainerId(ContainerId.INVENTORY); + + MobEquipmentPacket offHandPacket = new MobEquipmentPacket(); + offHandPacket.setRuntimeEntityId(geyserId); + offHandPacket.setItem(offHand); + offHandPacket.setHotbarSlot(-1); + offHandPacket.setInventorySlot(0); + offHandPacket.setContainerId(ContainerId.OFFHAND); session.getUpstream().sendPacket(armorEquipmentPacket); - session.getUpstream().sendPacket(mobEquipmentPacket); + session.getUpstream().sendPacket(handPacket); + session.getUpstream().sendPacket(offHandPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java index 67dc08941..49af65546 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java @@ -27,7 +27,10 @@ package org.geysermc.connector.entity; import com.github.steveice10.mc.auth.data.GameProfile; import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.CommandPermission; +import com.nukkitx.protocol.bedrock.data.PlayerPermission; import com.nukkitx.protocol.bedrock.packet.AddPlayerPacket; +import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; import com.nukkitx.protocol.bedrock.packet.PlayerListPacket; import lombok.Getter; import lombok.Setter; @@ -74,24 +77,24 @@ public class PlayerEntity extends LivingEntity { addPlayerPacket.setRotation(getBedrockRotation()); addPlayerPacket.setMotion(motion); addPlayerPacket.setHand(hand); - addPlayerPacket.setPlayerFlags(0); - addPlayerPacket.setCommandPermission(0); - addPlayerPacket.setWorldFlags(0); - addPlayerPacket.setPlayerPermission(0); - addPlayerPacket.setCustomFlags(0); + addPlayerPacket.getAdventureSettings().setCommandPermission(CommandPermission.NORMAL); + addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.VISITOR); addPlayerPacket.setDeviceId(""); addPlayerPacket.setPlatformChatId(""); - addPlayerPacket.getMetadata().putAll(getMetadata()); + addPlayerPacket.getMetadata().putAll(metadata); valid = true; session.getUpstream().sendPacket(addPlayerPacket); + + updateEquipment(session); + updateBedrockAttributes(session); } public void sendPlayer(GeyserSession session) { if (getLastSkinUpdate() == -1) { if (playerList) { PlayerListPacket playerList = new PlayerListPacket(); - playerList.setType(PlayerListPacket.Type.ADD); + playerList.setAction(PlayerListPacket.Action.ADD); playerList.getEntries().add(SkinUtils.buildDefaultEntry(profile, geyserId)); session.getUpstream().sendPacket(playerList); } @@ -107,10 +110,44 @@ public class PlayerEntity extends LivingEntity { // remove from playerlist if player isn't on playerlist Geyser.getGeneralThreadPool().execute(() -> { PlayerListPacket playerList = new PlayerListPacket(); - playerList.setType(PlayerListPacket.Type.REMOVE); + playerList.setAction(PlayerListPacket.Action.REMOVE); playerList.getEntries().add(new PlayerListPacket.Entry(uuid)); session.getUpstream().sendPacket(playerList); }); } } + + @Override + public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround) { + setPosition(position); + setRotation(rotation); + + MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); + movePlayerPacket.setRuntimeEntityId(geyserId); + movePlayerPacket.setPosition(this.position); + movePlayerPacket.setRotation(getBedrockRotation()); + movePlayerPacket.setOnGround(isOnGround); + movePlayerPacket.setMode(MovePlayerPacket.Mode.NORMAL); + + session.getUpstream().sendPacket(movePlayerPacket); + } + + @Override + public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) { + setRotation(rotation); + this.position = Vector3f.from(position.getX() + relX, position.getY() + relY, position.getZ() + relZ); + + MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); + movePlayerPacket.setRuntimeEntityId(geyserId); + movePlayerPacket.setPosition(position); + movePlayerPacket.setRotation(getBedrockRotation()); + movePlayerPacket.setOnGround(isOnGround); + movePlayerPacket.setMode(MovePlayerPacket.Mode.NORMAL); + session.getUpstream().sendPacket(movePlayerPacket); + } + + @Override + public void setPosition(Vector3f position) { + this.position = position.add(0, entityType.getOffset(), 0); + } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java index 3279b2983..1beb8ab8f 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java @@ -43,7 +43,7 @@ public class ArmorStandEntity extends LivingEntity { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { if (entityMetadata.getType() == MetadataType.BYTE) { byte xd = (byte) entityMetadata.getValue(); - if((xd & 0x01) == 0x01) { + if ((xd & 0x01) == 0x01 && (metadata.get(EntityData.SCALE) != null && !metadata.get(EntityData.SCALE).equals(0.0f))) { metadata.put(EntityData.SCALE, .55f); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/LoggingPacketHandler.java b/connector/src/main/java/org/geysermc/connector/network/LoggingPacketHandler.java index 313e7adcf..91b3ebd40 100644 --- a/connector/src/main/java/org/geysermc/connector/network/LoggingPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/LoggingPacketHandler.java @@ -192,11 +192,6 @@ public class LoggingPacketHandler implements BedrockPacketHandler { return defaultHandler(packet); } - @Override - public boolean handle(LevelSoundEvent3Packet packet) { - return defaultHandler(packet); - } - @Override public boolean handle(MapInfoRequestPacket packet) { return defaultHandler(packet); diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 1a71a0919..439676707 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -37,17 +37,17 @@ import com.github.steveice10.packetlib.event.session.PacketReceivedEvent; import com.github.steveice10.packetlib.event.session.SessionAdapter; import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.tcp.TcpSessionFactory; +import com.nukkitx.math.GenericMath; +import com.nukkitx.math.TrigMath; import com.nukkitx.math.vector.Vector2f; -import com.nukkitx.math.vector.Vector2i; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3i; -import com.nukkitx.nbt.NbtUtils; -import com.nukkitx.nbt.stream.NBTInputStream; import com.nukkitx.nbt.tag.CompoundTag; import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.data.ContainerId; import com.nukkitx.protocol.bedrock.data.GamePublishSetting; -import com.nukkitx.protocol.bedrock.data.GameRule; +import com.nukkitx.protocol.bedrock.data.GameRuleData; +import com.nukkitx.protocol.bedrock.data.PlayerPermission; import com.nukkitx.protocol.bedrock.packet.*; import lombok.Getter; import lombok.Setter; @@ -56,7 +56,6 @@ import org.geysermc.api.RemoteServer; import org.geysermc.api.session.AuthData; import org.geysermc.api.window.FormWindow; import org.geysermc.connector.GeyserConnector; -import org.geysermc.connector.console.GeyserLogger; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.inventory.PlayerInventory; import org.geysermc.connector.network.session.cache.*; @@ -65,9 +64,9 @@ import org.geysermc.connector.network.translators.block.BlockTranslator; import org.geysermc.connector.utils.ChunkUtils; import org.geysermc.connector.utils.Toolbox; -import java.io.InputStream; import java.net.InetSocketAddress; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; @Getter public class GeyserSession implements Player { @@ -89,9 +88,6 @@ public class GeyserSession implements Player { private DataCache javaPacketCache; - @Setter - private Vector2i lastChunkPosition = null; - @Setter private int renderDistance; private boolean loggedIn; @@ -104,6 +100,13 @@ public class GeyserSession implements Player { @Setter private GameMode gameMode = GameMode.SURVIVAL; + private final AtomicInteger pendingDimSwitches = new AtomicInteger(0); + @Setter + private boolean sprinting; + + @Setter + private boolean jumping; + @Setter private boolean switchingDimension = false; private boolean manyDimPackets = false; @@ -136,6 +139,10 @@ public class GeyserSession implements Player { public void connect(RemoteServer remoteServer) { startGame(); this.remoteServer = remoteServer; + if (!(connector.getConfig().getRemote().getAuthType().hashCode() == "online".hashCode())) { + connector.getLogger().info("Attempting to login using offline mode... authentication is disabled."); + authenticate(authenticationData.getName()); + } ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false); @@ -279,6 +286,16 @@ public class GeyserSession implements Player { windowCache.showWindow(window, id); } + public void setRenderDistance(int renderDistance) { + renderDistance = GenericMath.ceil(++renderDistance * TrigMath.SQRT_OF_TWO); //square to circle + if (renderDistance > 32) renderDistance = 32; // <3 u ViaVersion but I don't like crashing clients x) + this.renderDistance = renderDistance; + + ChunkRadiusUpdatedPacket chunkRadiusUpdatedPacket = new ChunkRadiusUpdatedPacket(); + chunkRadiusUpdatedPacket.setRadius(renderDistance); + upstream.sendPacket(chunkRadiusUpdatedPacket); + } + @Override public InetSocketAddress getSocketAddress() { return this.upstream.getAddress(); @@ -310,7 +327,7 @@ public class GeyserSession implements Player { startGamePacket.setLightningLevel(0); startGamePacket.setMultiplayerGame(true); startGamePacket.setBroadcastingToLan(true); - startGamePacket.getGamerules().add(new GameRule<>("showcoordinates", true)); + startGamePacket.getGamerules().add(new GameRuleData<>("showcoordinates", true)); startGamePacket.setPlatformBroadcastMode(GamePublishSetting.PUBLIC); startGamePacket.setXblBroadcastMode(GamePublishSetting.PUBLIC); startGamePacket.setCommandsEnabled(true); @@ -318,7 +335,7 @@ public class GeyserSession implements Player { startGamePacket.setBonusChestEnabled(false); startGamePacket.setStartingWithMap(false); startGamePacket.setTrustingPlayers(true); - startGamePacket.setDefaultPlayerPermission(1); + startGamePacket.setDefaultPlayerPermission(PlayerPermission.OPERATOR); startGamePacket.setServerChunkTickRange(4); startGamePacket.setBehaviorPackLocked(false); startGamePacket.setResourcePackLocked(false); diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java index cba6b7b65..bbd714e2f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java @@ -55,10 +55,13 @@ public class EntityCache { } public void spawnEntity(Entity entity) { - entity.moveAbsolute(entity.getPosition(), entity.getRotation().getX(), entity.getRotation().getY()); + cacheEntity(entity); + entity.spawnEntity(session); + } + + public void cacheEntity(Entity entity) { entityIdTranslations.put(entity.getEntityId(), entity.getGeyserId()); entities.put(entity.getGeyserId(), entity); - entity.spawnEntity(session); } public boolean removeEntity(Entity entity, boolean force) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java index f996581d2..93d07891e 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java @@ -128,8 +128,7 @@ public class TranslatorsInit { Registry.registerJava(ServerPlayerActionAckPacket.class, new JavaPlayerActionAckTranslator()); Registry.registerJava(ServerPlayerChangeHeldItemPacket.class, new JavaPlayerChangeHeldItemTranslator()); - // FIXME: This translator messes with allowing flight in creative mode. Will need to be addressed later - // Registry.registerJava(ServerPlayerAbilitiesPacket.class, new JavaPlayerAbilitiesTranslator()); + Registry.registerJava(ServerPlayerAbilitiesPacket.class, new JavaPlayerAbilitiesTranslator()); Registry.registerJava(ServerNotifyClientPacket.class, new JavaNotifyClientTranslator()); Registry.registerJava(ServerChunkDataPacket.class, new JavaChunkDataTranslator()); @@ -149,6 +148,9 @@ public class TranslatorsInit { Registry.registerJava(ServerConfirmTransactionPacket.class, new JavaConfirmTransactionTranslator()); Registry.registerJava(ServerWindowPropertyPacket.class, new JavaWindowPropertyTranslator()); + Registry.registerJava(ServerUpdateViewPositionPacket.class, new JavaUpdateViewPositionTranslator()); + Registry.registerJava(ServerUpdateViewDistancePacket.class, new JavaUpdateViewDistanceTranslator()); + Registry.registerBedrock(AnimatePacket.class, new BedrockAnimateTranslator()); Registry.registerBedrock(CommandRequestPacket.class, new BedrockCommandRequestTranslator()); Registry.registerBedrock(InventoryTransactionPacket.class, new BedrockInventoryTransactionTranslator()); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java index 56e573c69..98a580ee3 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java @@ -40,6 +40,8 @@ import org.geysermc.connector.entity.Entity; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; +import java.util.concurrent.TimeUnit; + public class BedrockActionTranslator extends PacketTranslator { @Override @@ -56,6 +58,14 @@ public class BedrockActionTranslator extends PacketTranslator { + session.setJumping(false); + }, 1, TimeUnit.SECONDS); break; } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java index 67d398f6f..ab73e9bb1 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java @@ -44,12 +44,12 @@ public class BedrockInteractTranslator extends PacketTranslator return; switch (packet.getAction()) { - case 1: + case INTERACT: ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), InteractAction.INTERACT, Hand.MAIN_HAND); session.getDownstream().getSession().send(interactPacket); break; - case 2: + case DAMAGE: ClientPlayerInteractEntityPacket attackPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), InteractAction.ATTACK, Hand.MAIN_HAND); session.getDownstream().getSession().send(attackPacket); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMovePlayerTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMovePlayerTranslator.java index 37b517d30..15374c6d6 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMovePlayerTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMovePlayerTranslator.java @@ -26,6 +26,7 @@ package org.geysermc.connector.network.translators.bedrock; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPositionRotationPacket; +import com.nukkitx.math.GenericMath; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket; import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; @@ -42,7 +43,7 @@ public class BedrockMovePlayerTranslator extends PacketTranslator 0) return; if (!session.getUpstream().isInitialized()) { MoveEntityAbsolutePacket moveEntityBack = new MoveEntityAbsolutePacket(); @@ -62,16 +63,15 @@ public class BedrockMovePlayerTranslator extends PacketTranslator { @Override public void translate(RespawnPacket packet, GeyserSession session) { - if (packet.getSpawnState() == RespawnPacket.State.CLIENT_READY) { + if (packet.getState() == RespawnPacket.State.CLIENT_READY) { RespawnPacket respawnPacket = new RespawnPacket(); respawnPacket.setRuntimeEntityId(0); respawnPacket.setPosition(Vector3f.ZERO); - respawnPacket.setSpawnState(RespawnPacket.State.SERVER_SEARCHING); + respawnPacket.setState(RespawnPacket.State.SERVER_SEARCHING); session.getUpstream().sendPacket(respawnPacket); ClientRequestPacket javaRespawnPacket = new ClientRequestPacket(ClientRequest.RESPAWN); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java index 970808b62..2e1c4ffe1 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java @@ -67,7 +67,7 @@ public class BlockTranslator { Map blockStateMap = new HashMap<>(); for (CompoundTag tag : blocksTag.getValue()) { - if (blockStateMap.putIfAbsent(tag.getAsCompound("block"), tag) != null) { + if (blockStateMap.putIfAbsent(tag.getCompound("block"), tag) != null) { throw new AssertionError("Duplicate block states in Bedrock palette"); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaBossBarTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaBossBarTranslator.java index c918c0d5b..bfde6f74c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaBossBarTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaBossBarTranslator.java @@ -46,7 +46,7 @@ public class JavaBossBarTranslator extends PacketTranslator long entityId = session.getEntityCache().addBossBar(packet.getUuid()); addBossEntity(session, entityId); - bossEventPacket.setType(BossEventPacket.Type.SHOW); + bossEventPacket.setAction(BossEventPacket.Action.SHOW); bossEventPacket.setBossUniqueEntityId(entityId); bossEventPacket.setTitle(MessageUtils.getBedrockMessage(packet.getTitle())); bossEventPacket.setHealthPercentage(packet.getHealth()); @@ -55,15 +55,15 @@ public class JavaBossBarTranslator extends PacketTranslator bossEventPacket.setDarkenSky(0); break; case UPDATE_TITLE: - bossEventPacket.setType(BossEventPacket.Type.TITLE); + bossEventPacket.setAction(BossEventPacket.Action.TITLE); bossEventPacket.setTitle(MessageUtils.getBedrockMessage(packet.getTitle())); break; case UPDATE_HEALTH: - bossEventPacket.setType(BossEventPacket.Type.HEALTH_PERCENTAGE); + bossEventPacket.setAction(BossEventPacket.Action.HEALTH_PERCENTAGE); bossEventPacket.setHealthPercentage(packet.getHealth()); break; case REMOVE: - bossEventPacket.setType(BossEventPacket.Type.HIDE); + bossEventPacket.setAction(BossEventPacket.Action.HIDE); removeBossEntity(session, session.getEntityCache().removeBossBar(packet.getUuid())); break; case UPDATE_STYLE: diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java index 97cf35e5c..51758011e 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java @@ -27,10 +27,12 @@ package org.geysermc.connector.network.translators.java; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket; +import com.nukkitx.protocol.bedrock.data.PlayerPermission; import com.nukkitx.protocol.bedrock.packet.*; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.utils.ChunkUtils; import org.geysermc.connector.utils.DimensionUtils; public class JavaJoinGameTranslator extends PacketTranslator { @@ -42,7 +44,7 @@ public class JavaJoinGameTranslator extends PacketTranslator 32) session.setRenderDistance(32); // <3 u ViaVersion but I don't like crashing clients x) - - ChunkRadiusUpdatedPacket chunkRadiusPacket = new ChunkRadiusUpdatedPacket(); - chunkRadiusPacket.setRadius(session.getRenderDistance()); - session.getUpstream().sendPacket(chunkRadiusPacket); + session.setRenderDistance(packet.getViewDistance()); if (DimensionUtils.javaToBedrock(packet.getDimension()) != entity.getDimension()) { - DimensionUtils.switchDimension(session, packet.getDimension(), false); + ChunkUtils.sendEmptyChunks(session, entity.getPosition().toInt(), 3, true); + DimensionUtils.switchDimension(session, packet.getDimension()); } } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java index a029fcfac..0cc7156a7 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java @@ -53,14 +53,15 @@ public class JavaRespawnTranslator extends PacketTranslator session.setGameMode(packet.getGamemode()); if (entity.getDimension() != DimensionUtils.javaToBedrock(packet.getDimension())) { - DimensionUtils.switchDimension(session, packet.getDimension(), false); + DimensionUtils.switchDimension(session, packet.getDimension()); } else { - // Handled in JavaPlayerPositionRotationTranslator - session.setSpawned(false); if (session.isManyDimPackets()) { //reloading world int fakeDim = entity.getDimension() == 0 ? -1 : 0; - DimensionUtils.switchDimension(session, fakeDim, true); - DimensionUtils.switchDimension(session, packet.getDimension(), false); + DimensionUtils.switchDimension(session, fakeDim); + DimensionUtils.switchDimension(session, packet.getDimension()); + } else { + // Handled in JavaPlayerPositionRotationTranslator + session.setSpawned(false); } } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java index 1262664d1..5efe8e4e3 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java @@ -70,7 +70,7 @@ public class JavaEntityEquipmentTranslator extends PacketTranslator { @Override @@ -42,7 +46,7 @@ public class JavaPlayerAbilitiesTranslator extends PacketTranslator playerFlags = new HashSet<>(); + playerFlags.add(AdventureSettingsPacket.Flag.AUTO_JUMP); + if (packet.isCanFly()) + playerFlags.add(AdventureSettingsPacket.Flag.MAY_FLY); - playerFlags = setPlayerFlag(0x20, true, playerFlags); // auto jump - playerFlags = setPlayerFlag(0x40, packet.isCanFly(), playerFlags); // can fly - playerFlags = setPlayerFlag(0x200, packet.isFlying(), playerFlags); // is flying + if (packet.isFlying()) + playerFlags.add(AdventureSettingsPacket.Flag.FLYING); AdventureSettingsPacket adventureSettingsPacket = new AdventureSettingsPacket(); - adventureSettingsPacket.setPlayerPermission(1); + adventureSettingsPacket.setPlayerPermission(PlayerPermission.OPERATOR); adventureSettingsPacket.setUniqueEntityId(entity.getGeyserId()); - adventureSettingsPacket.setPlayerFlags(playerFlags); + adventureSettingsPacket.getFlags().addAll(playerFlags); session.getUpstream().sendPacket(adventureSettingsPacket); } - - private int setPlayerFlag(int flag, boolean value, int playerFlags) { - if (value) { - return playerFlags | flag; - } else { - return playerFlags & ~flag; - } - } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerListEntryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerListEntryTranslator.java index c39a95dbf..48f20dbdd 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerListEntryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerListEntryTranslator.java @@ -41,7 +41,7 @@ public class JavaPlayerListEntryTranslator extends PacketTranslator 1.5 || (yDis < 1.45 || yDis > (session.isJumping() ? 4.3 : (session.isSprinting() ? 2.5 : 1.9))) || zDis > 1.5) { + entity.moveAbsolute(session, Vector3f.from(packet.getX(), packet.getY(), packet.getZ()), packet.getYaw(), packet.getPitch(), true); + } + } ClientTeleportConfirmPacket teleportConfirmPacket = new ClientTeleportConfirmPacket(packet.getTeleportId()); session.getDownstream().getSession().send(teleportConfirmPacket); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnPlayerTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnPlayerTranslator.java index 7dea34ecd..1e1518685 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnPlayerTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnPlayerTranslator.java @@ -50,6 +50,7 @@ public class JavaSpawnPlayerTranslator extends PacketTranslator { - Vector2i chunkPos = session.getLastChunkPosition(); - Vector3f position = session.getPlayerEntity().getPosition(); - Vector2i newChunkPos = Vector2i.from(position.getFloorX() >> 4, position.getFloorZ() >> 4); - - if (chunkPos == null || !chunkPos.equals(newChunkPos)) { - NetworkChunkPublisherUpdatePacket chunkPublisherUpdatePacket = new NetworkChunkPublisherUpdatePacket(); - chunkPublisherUpdatePacket.setPosition(position.toInt()); - chunkPublisherUpdatePacket.setRadius(session.getRenderDistance() << 4); - session.getUpstream().sendPacket(chunkPublisherUpdatePacket); - - session.setLastChunkPosition(newChunkPos); - } - try { - ChunkUtils.ChunkData chunkData = ChunkUtils.translateToBedrock(packet.getColumn()); - ByteBuf byteBuf = Unpooled.buffer(32); - ChunkSection[] sections = chunkData.sections; + if (packet.getColumn().getBiomeData() != null) { //Full chunk + ChunkUtils.ChunkData chunkData = ChunkUtils.translateToBedrock(packet.getColumn()); + ByteBuf byteBuf = Unpooled.buffer(32); + ChunkSection[] sections = chunkData.sections; - int sectionCount = sections.length - 1; - while (sectionCount >= 0 && sections[sectionCount].isEmpty()) { - sectionCount--; + int sectionCount = sections.length - 1; + while (sectionCount >= 0 && sections[sectionCount].isEmpty()) { + sectionCount--; + } + sectionCount++; + + for (int i = 0; i < sectionCount; i++) { + ChunkSection section = chunkData.sections[i]; + section.writeToNetwork(byteBuf); + } + + byte[] bedrockBiome = BiomeTranslator.toBedrockBiome(packet.getColumn().getBiomeData()); + + byteBuf.writeBytes(bedrockBiome); // Biomes - 256 bytes + byteBuf.writeByte(0); // Border blocks - Edu edition only + VarInts.writeUnsignedInt(byteBuf, 0); // extra data length, 0 for now + + byte[] payload = new byte[byteBuf.writerIndex()]; + byteBuf.readBytes(payload); + + LevelChunkPacket levelChunkPacket = new LevelChunkPacket(); + levelChunkPacket.setSubChunksLength(sectionCount); + levelChunkPacket.setCachingEnabled(false); + levelChunkPacket.setChunkX(packet.getColumn().getX()); + levelChunkPacket.setChunkZ(packet.getColumn().getZ()); + levelChunkPacket.setData(payload); + session.getUpstream().sendPacket(levelChunkPacket); + } else { + final int xOffset = packet.getColumn().getX() << 4; + final int zOffset = packet.getColumn().getZ() << 4; + Chunk[] chunks = packet.getColumn().getChunks(); + for (int i = 0; i < chunks.length; i++) { + Chunk chunk = chunks[i]; + if (chunk == null) continue; + final int yOffset = i * 16; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + BlockState blockState = chunk.get(x, y, z); + Vector3i pos = Vector3i.from( + x + xOffset, + y + yOffset, + z + zOffset); + ChunkUtils.updateBlock(session, blockState, pos); + } + } + } + } } - sectionCount++; - - for (int i = 0; i < sectionCount; i++) { - ChunkSection section = chunkData.sections[i]; - section.writeToNetwork(byteBuf); - } - - byte[] bedrockBiome = BiomeTranslator.toBedrockBiome(packet.getColumn().getBiomeData()); - - byteBuf.writeBytes(bedrockBiome); // Biomes - 256 bytes - byteBuf.writeByte(0); // Border blocks - Edu edition only - VarInts.writeUnsignedInt(byteBuf, 0); // extra data length, 0 for now - - byte[] payload = new byte[byteBuf.writerIndex()]; - byteBuf.readBytes(payload); - - LevelChunkPacket levelChunkPacket = new LevelChunkPacket(); - levelChunkPacket.setSubChunksLength(sectionCount); - levelChunkPacket.setCachingEnabled(false); - levelChunkPacket.setChunkX(packet.getColumn().getX()); - levelChunkPacket.setChunkZ(packet.getColumn().getZ()); - levelChunkPacket.setData(payload); - session.getUpstream().sendPacket(levelChunkPacket); } catch (Exception ex) { ex.printStackTrace(); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java index da2e8a153..490a66437 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java @@ -31,13 +31,17 @@ import com.github.steveice10.mc.protocol.data.game.world.notify.EnterCreditsValu import com.github.steveice10.mc.protocol.packet.ingame.client.ClientRequestPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerNotifyClientPacket; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityDataDictionary; +import com.nukkitx.protocol.bedrock.data.EntityDataMap; import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.data.PlayerPermission; import com.nukkitx.protocol.bedrock.packet.*; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; +import java.util.HashSet; +import java.util.Set; import java.util.concurrent.ThreadLocalRandom; public class JavaNotifyClientTranslator extends PacketTranslator { @@ -51,27 +55,34 @@ public class JavaNotifyClientTranslator extends PacketTranslator playerFlags = new HashSet<>(); GameMode gameMode = (GameMode) packet.getValue(); - playerFlags = setPlayerFlag(0x01, gameMode == GameMode.ADVENTURE, playerFlags); // world immutable - playerFlags = setPlayerFlag(0x20, true, playerFlags); // auto jump - playerFlags = setPlayerFlag(0x40, gameMode == GameMode.CREATIVE || gameMode == GameMode.SPECTATOR, playerFlags); // can fly - playerFlags = setPlayerFlag(0x80, gameMode == GameMode.SPECTATOR, playerFlags); // no clip - playerFlags = setPlayerFlag(0x200, gameMode == GameMode.SPECTATOR, playerFlags); // is flying + if (gameMode == GameMode.ADVENTURE) + playerFlags.add(AdventureSettingsPacket.Flag.IMMUTABLE_WORLD); + + if (gameMode == GameMode.CREATIVE) + playerFlags.add(AdventureSettingsPacket.Flag.MAY_FLY); + + if (gameMode == GameMode.SPECTATOR) { + playerFlags.add(AdventureSettingsPacket.Flag.MAY_FLY); + playerFlags.add(AdventureSettingsPacket.Flag.NO_CLIP); + playerFlags.add(AdventureSettingsPacket.Flag.FLYING); + } + + playerFlags.add(AdventureSettingsPacket.Flag.AUTO_JUMP); SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket(); playerGameTypePacket.setGamemode(gameMode.ordinal()); @@ -79,12 +90,12 @@ public class JavaNotifyClientTranslator extends PacketTranslator { + + @Override + public void translate(ServerUpdateViewDistancePacket packet, GeyserSession session) { + session.setRenderDistance(packet.getViewDistance()); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateViewPositionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateViewPositionTranslator.java new file mode 100644 index 000000000..ebe9062fa --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateViewPositionTranslator.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019-2020 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.java.world; + +import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateViewPositionPacket; +import com.nukkitx.math.vector.Vector3i; +import com.nukkitx.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; + +public class JavaUpdateViewPositionTranslator extends PacketTranslator { + + @Override + public void translate(ServerUpdateViewPositionPacket packet, GeyserSession session) { + NetworkChunkPublisherUpdatePacket chunkPublisherUpdatePacket = new NetworkChunkPublisherUpdatePacket(); + chunkPublisherUpdatePacket.setPosition(Vector3i.from(packet.getChunkX() << 4, 0, packet.getChunkZ() << 4)); + chunkPublisherUpdatePacket.setRadius(session.getRenderDistance() << 4); + session.getUpstream().sendPacket(chunkPublisherUpdatePacket); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java index 6c55c5ea8..1a6296c02 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java @@ -31,7 +31,6 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket; -import com.nukkitx.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.TranslatorsInit; @@ -76,19 +75,23 @@ public class ChunkUtils { } public static void updateBlock(GeyserSession session, BlockState blockState, Position position) { - int blockId = BlockTranslator.getBedrockBlockId(blockState); Vector3i pos = Vector3i.from(position.getX(), position.getY(), position.getZ()); + updateBlock(session, blockState, pos); + } + + public static void updateBlock(GeyserSession session, BlockState blockState, Vector3i position) { + int blockId = BlockTranslator.getBedrockBlockId(blockState); UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); updateBlockPacket.setDataLayer(0); - updateBlockPacket.setBlockPosition(pos); + updateBlockPacket.setBlockPosition(position); updateBlockPacket.setRuntimeId(blockId); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); session.getUpstream().sendPacket(updateBlockPacket); UpdateBlockPacket waterPacket = new UpdateBlockPacket(); waterPacket.setDataLayer(1); - waterPacket.setBlockPosition(pos); + waterPacket.setBlockPosition(position); if (BlockTranslator.isWaterlogged(blockState)) { waterPacket.setRuntimeId(BEDROCK_WATER_ID); } else { @@ -100,11 +103,6 @@ public class ChunkUtils { public static void sendEmptyChunks(GeyserSession session, Vector3i position, int radius, boolean forceUpdate) { int chunkX = position.getX() >> 4; int chunkZ = position.getZ() >> 4; - NetworkChunkPublisherUpdatePacket chunkPublisherUpdatePacket = new NetworkChunkPublisherUpdatePacket(); - chunkPublisherUpdatePacket.setPosition(position); - chunkPublisherUpdatePacket.setRadius(radius + 1 << 4); - session.getUpstream().sendPacket(chunkPublisherUpdatePacket); - session.setLastChunkPosition(null); for (int x = -radius; x <= radius; x++) { for (int z = -radius; z <= radius; z++) { LevelChunkPacket data = new LevelChunkPacket(); @@ -119,7 +117,7 @@ public class ChunkUtils { Vector3i pos = Vector3i.from(chunkX + x << 4, 80, chunkZ + z << 4); UpdateBlockPacket blockPacket = new UpdateBlockPacket(); blockPacket.setBlockPosition(pos); - blockPacket.setDataLayer(1); + blockPacket.setDataLayer(0); blockPacket.setRuntimeId(1); session.getUpstream().sendPacket(blockPacket); } diff --git a/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java b/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java index 81f528238..c7ecaafb4 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java @@ -31,14 +31,18 @@ import org.geysermc.connector.entity.Entity; import org.geysermc.connector.network.session.GeyserSession; public class DimensionUtils { - public static void switchDimension(GeyserSession session, int javaDimension, boolean fake) { + public static void switchDimension(GeyserSession session, int javaDimension) { int bedrockDimension = javaToBedrock(javaDimension); Entity player = session.getPlayerEntity(); if (bedrockDimension == player.getDimension()) return; - Vector3i pos = Vector3i.from(0, Short.MAX_VALUE, 0); session.getEntityCache().removeAllEntities(); + if (session.getPendingDimSwitches().getAndIncrement() > 0) { + ChunkUtils.sendEmptyChunks(session, player.getPosition().toInt(), 3, true); + } + + Vector3i pos = Vector3i.from(0, Short.MAX_VALUE, 0); ChangeDimensionPacket changeDimensionPacket = new ChangeDimensionPacket(); changeDimensionPacket.setDimension(bedrockDimension); @@ -46,19 +50,14 @@ public class DimensionUtils { changeDimensionPacket.setPosition(pos.toFloat()); session.getUpstream().sendPacket(changeDimensionPacket); player.setDimension(bedrockDimension); + player.setPosition(pos.toFloat()); + session.setSpawned(false); //let java server handle portal travel sound StopSoundPacket stopSoundPacket = new StopSoundPacket(); stopSoundPacket.setStoppingAllSound(true); stopSoundPacket.setSoundName(""); session.getUpstream().sendPacket(stopSoundPacket); - - if (fake) { - ChunkUtils.sendEmptyChunks(session, pos, 2, true); - } - - session.setSpawned(false); - session.setSwitchingDimension(true); } public static int javaToBedrock(int javaDimension) { diff --git a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java index 3d833f7c1..ef5bc9d9d 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java @@ -165,12 +165,12 @@ public class SkinUtils { ); PlayerListPacket playerRemovePacket = new PlayerListPacket(); - playerRemovePacket.setType(PlayerListPacket.Type.REMOVE); + playerRemovePacket.setAction(PlayerListPacket.Action.REMOVE); playerRemovePacket.getEntries().add(updatedEntry); session.getUpstream().sendPacket(playerRemovePacket); PlayerListPacket playerAddPacket = new PlayerListPacket(); - playerAddPacket.setType(PlayerListPacket.Type.ADD); + playerAddPacket.setAction(PlayerListPacket.Action.ADD); playerAddPacket.getEntries().add(updatedEntry); session.getUpstream().sendPacket(playerAddPacket); } diff --git a/connector/src/main/java/org/geysermc/connector/world/chunk/ChunkPosition.java b/connector/src/main/java/org/geysermc/connector/world/chunk/ChunkPosition.java index 8582817e2..a59b2031e 100644 --- a/connector/src/main/java/org/geysermc/connector/world/chunk/ChunkPosition.java +++ b/connector/src/main/java/org/geysermc/connector/world/chunk/ChunkPosition.java @@ -27,6 +27,7 @@ package org.geysermc.connector.world.chunk; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -35,6 +36,7 @@ import java.util.Objects; @Getter @Setter @AllArgsConstructor +@EqualsAndHashCode public class ChunkPosition { private int x;