From c2cd99c82939f19ffaf6310e4b84458b70c550fc Mon Sep 17 00:00:00 2001 From: Konicai <71294714+Konicai@users.noreply.github.com> Date: Fri, 29 Sep 2023 17:14:49 -0400 Subject: [PATCH] Support Java 1.20.2 (#4112) * Initial pass for 1.20.2, compiling * Remove unused level events * handle null GameProfile in ClientboundPlayerInfoUpdatePacket * Handle level events BRUSH_BLOCK_COMPLETE and EGG_CRACK * Account for null tag in DecoratedPotBlockEntityTranslator * Explicitly show that 1.20.31 is supported --- README.md | 2 +- .../java/org/geysermc/geyser/GeyserImpl.java | 1 - .../geyser/level/GeyserAdvancement.java | 5 -- .../geysermc/geyser/network/GameProtocol.java | 8 ++- .../registry/PacketTranslatorRegistry.java | 4 +- .../geyser/session/GeyserSession.java | 14 ++-- .../geyser/session/cache/TagCache.java | 5 +- .../DecoratedPotBlockEntityTranslator.java | 4 ++ .../BedrockNetworkStackLatencyTranslator.java | 2 +- .../java/JavaCustomPayloadTranslator.java | 4 +- .../java/JavaCustomQueryTranslator.java | 4 +- .../java/JavaDisconnectTranslator.java | 2 +- .../java/JavaGameProfileTranslator.java | 9 +++ .../java/JavaKeepAliveTranslator.java | 2 +- .../protocol/java/JavaLoginTranslator.java | 57 +++------------ .../protocol/java/JavaPingTranslator.java | 4 +- .../java/JavaRegistryDataTranslator.java | 67 +++++++++++++++++ .../protocol/java/JavaRespawnTranslator.java | 14 ++-- .../java/JavaUpdateTagsTranslator.java | 2 +- .../entity/JavaUpdateMobEffectTranslator.java | 3 +- .../JavaPlayerInfoUpdateTranslator.java | 31 +++++--- .../entity/spawn/JavaAddEntityTranslator.java | 38 +++++++++- .../entity/spawn/JavaAddPlayerTranslator.java | 72 ------------------- .../JavaChunkBatchFinishedTranslator.java | 44 ++++++++++++ .../java/level/JavaLevelEventTranslator.java | 6 ++ .../geyser/util/PluginMessageUtils.java | 2 +- core/src/main/resources/mappings | 2 +- gradle/libs.versions.toml | 2 +- 28 files changed, 243 insertions(+), 167 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java delete mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddPlayerTranslator.java create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaChunkBatchFinishedTranslator.java diff --git a/README.md b/README.md index 7f9f6fe9e..d78386687 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,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 joined us here! -### Currently supporting Minecraft Bedrock 1.20.0 - 1.20.30 and Minecraft Java 1.20/1.20.1. +### Currently supporting Minecraft Bedrock 1.20.0 - 1.20.31 and Minecraft Java 1.20/1.20.1. ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index d13836e9a..4a5f16bfa 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -71,7 +71,6 @@ import org.geysermc.geyser.level.WorldManager; import org.geysermc.geyser.network.netty.GeyserServer; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; -import org.geysermc.geyser.registry.loader.RegistryLoaders; import org.geysermc.geyser.scoreboard.ScoreboardUpdater; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.PendingMicrosoftAuthentication; diff --git a/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java b/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java index fc3c86dd4..936248afe 100644 --- a/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java +++ b/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java @@ -52,11 +52,6 @@ public class GeyserAdvancement { return this.advancement.getId(); } - @NonNull - public List getCriteria() { - return this.advancement.getCriteria(); - } - @NonNull public List> getRequirements() { return this.advancement.getRequirements(); diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index 63cce329c..fb9684f77 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -46,7 +46,9 @@ public final class GameProtocol { * Default Bedrock codec that should act as a fallback. Should represent the latest available * release of the game that Geyser supports. */ - public static final BedrockCodec DEFAULT_BEDROCK_CODEC = Bedrock_v618.CODEC; + public static final BedrockCodec DEFAULT_BEDROCK_CODEC = Bedrock_v618.CODEC.toBuilder() + .minecraftVersion("1.20.31") + .build(); /** * A list of all supported Bedrock versions that can join Geyser @@ -66,7 +68,9 @@ public final class GameProtocol { SUPPORTED_BEDROCK_CODECS.add(Bedrock_v594.CODEC.toBuilder() .minecraftVersion("1.20.10/1.20.15") .build()); - SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC); + SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder() + .minecraftVersion("1.20.30/1.20.31") + .build()); } /** diff --git a/core/src/main/java/org/geysermc/geyser/registry/PacketTranslatorRegistry.java b/core/src/main/java/org/geysermc/geyser/registry/PacketTranslatorRegistry.java index 61999d4f6..e37f8aa64 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/PacketTranslatorRegistry.java +++ b/core/src/main/java/org/geysermc/geyser/registry/PacketTranslatorRegistry.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.registry; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundDelimiterPacket; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundTabListPacket; +import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundChunkBatchStartPacket; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLightUpdatePacket; import io.netty.channel.EventLoop; import org.geysermc.geyser.GeyserImpl; @@ -43,9 +44,10 @@ public class PacketTranslatorRegistry extends AbstractMappedRegistry> IGNORED_PACKETS = Collections.newSetFromMap(new IdentityHashMap<>()); static { + IGNORED_PACKETS.add(ClientboundChunkBatchStartPacket.class); // we don't track chunk batch sizes/periods + IGNORED_PACKETS.add(ClientboundDelimiterPacket.class); // Not implemented, spams logs IGNORED_PACKETS.add(ClientboundLightUpdatePacket.class); // Light is handled on Bedrock for us IGNORED_PACKETS.add(ClientboundTabListPacket.class); // Cant be implemented in Bedrock - IGNORED_PACKETS.add(ClientboundDelimiterPacket.class); // Not implemented, spams logs } protected PacketTranslatorRegistry() { diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index f7d362e0d..5c9725fae 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -45,15 +45,15 @@ import com.github.steveice10.mc.protocol.data.game.setting.ChatVisibility; import com.github.steveice10.mc.protocol.data.game.setting.SkinPart; import com.github.steveice10.mc.protocol.data.game.statistic.CustomStatistic; import com.github.steveice10.mc.protocol.data.game.statistic.Statistic; +import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundClientInformationPacket; import com.github.steveice10.mc.protocol.packet.handshake.serverbound.ClientIntentionPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientInformationPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket; -import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryPacket; +import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket; import com.github.steveice10.packetlib.BuiltinFlags; import com.github.steveice10.packetlib.Session; import com.github.steveice10.packetlib.event.session.ConnectedEvent; @@ -292,7 +292,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { private Vector2i lastChunkPosition = null; @Setter private int clientRenderDistance = -1; - private int serverRenderDistance; + private int serverRenderDistance = -1; // Exposed for GeyserConnect usage protected boolean sentSpawnPacket; @@ -1665,7 +1665,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { } private void sendDownstreamPacket0(Packet packet) { - if (protocol.getState().equals(ProtocolState.GAME) || packet.getClass() == ServerboundCustomQueryPacket.class) { + ProtocolState state = protocol.getState(); + if (state == ProtocolState.GAME || state == ProtocolState.CONFIGURATION || packet.getClass() == ServerboundCustomQueryAnswerPacket.class) { downstream.sendPacket(packet); } else { geyser.getLogger().debug("Tried to send downstream packet " + packet.getClass().getSimpleName() + " before connected to the server"); @@ -1824,8 +1825,11 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { if (clientRenderDistance != -1) { // The client has sent a render distance return clientRenderDistance; + } else if (serverRenderDistance != -1) { + // only known once ClientboundLoginPacket is received + return serverRenderDistance; } - return serverRenderDistance; + return 2; // unfortunate default until we got more info } // We need to send our skin parts to the server otherwise java sees us with no hat, jacket etc diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java index ab1dfbe2b..5acfc1f09 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java @@ -25,9 +25,10 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundUpdateTagsPacket; +import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntLists; +import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.type.Item; @@ -112,7 +113,7 @@ public class TagCache { } } - private IntList load(int[] tags) { + private IntList load(int @Nullable[] tags) { if (tags == null) { return IntLists.EMPTY_LIST; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java index e60342b27..1774d9c76 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java @@ -41,6 +41,10 @@ public class DecoratedPotBlockEntityTranslator extends BlockEntityTranslator { @Override public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { + if (tag == null) { + return; + } + // exact same format if (tag.get("sherds") instanceof ListTag sherds) { List translated = new ArrayList<>(4); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockNetworkStackLatencyTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockNetworkStackLatencyTranslator.java index 1ccd5ced9..412a97e3a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockNetworkStackLatencyTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockNetworkStackLatencyTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundKeepAlivePacket; +import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundKeepAlivePacket; import org.cloudburstmc.protocol.bedrock.data.AttributeData; import org.cloudburstmc.protocol.bedrock.packet.NetworkStackLatencyPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomPayloadTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomPayloadTranslator.java index cf5cfa198..2a7202b0c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomPayloadTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomPayloadTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundCustomPayloadPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCustomPayloadPacket; +import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundCustomPayloadPacket; +import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; import com.google.common.base.Charsets; import org.cloudburstmc.protocol.bedrock.packet.TransferPacket; import org.cloudburstmc.protocol.bedrock.packet.UnknownPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomQueryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomQueryTranslator.java index 89df63898..0eaef91f1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomQueryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomQueryTranslator.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.translator.protocol.java; import com.github.steveice10.mc.protocol.packet.login.clientbound.ClientboundCustomQueryPacket; -import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryPacket; +import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -41,7 +41,7 @@ public class JavaCustomQueryTranslator extends PacketTranslator CONFIGURATION + */ @Translator(packet = ClientboundGameProfilePacket.class) public class JavaGameProfileTranslator extends PacketTranslator { @@ -65,5 +70,9 @@ public class JavaGameProfileTranslator extends PacketTranslator { @@ -64,42 +55,22 @@ public class JavaLoginTranslator extends PacketTranslator dimensions = session.getDimensions(); - dimensions.clear(); - - JavaDimension.load(packet.getRegistry(), dimensions); - - Int2ObjectMap chatTypes = session.getChatTypes(); - chatTypes.clear(); - for (CompoundTag tag : JavaCodecUtil.iterateAsTag(packet.getRegistry().get("minecraft:chat_type"))) { - // The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. - int id = ((IntTag) tag.get("id")).getValue(); - CompoundTag element = tag.get("element"); - CompoundTag chat = element.get("chat"); - TextDecoration textDecoration = null; - if (chat != null) { - textDecoration = new TextDecoration(chat); - } - chatTypes.put(id, textDecoration); - } + PlayerSpawnInfo spawnInfo = packet.getCommonPlayerSpawnInfo(); // If the player is already initialized and a join game packet is sent, they // are swapping servers if (session.isSpawned()) { - String fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), packet.getDimension()); + String fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), spawnInfo.getDimension()); DimensionUtils.switchDimension(session, fakeDim); session.getWorldCache().removeScoreboard(); } - session.setWorldName(packet.getWorldName()); + session.setWorldName(spawnInfo.getWorldName()); session.setLevels(packet.getWorldNames()); - BiomeTranslator.loadServerBiomes(session, packet.getRegistry()); - session.getTagCache().clear(); + session.setGameMode(spawnInfo.getGameMode()); - session.setGameMode(packet.getGameMode()); - - String newDimension = packet.getDimension(); + String newDimension = spawnInfo.getDimension(); boolean needsSpawnPacket = !session.isSentSpawnPacket(); if (needsSpawnPacket) { @@ -114,11 +85,11 @@ public class JavaLoginTranslator extends PacketTranslator { + + @Override + public void translate(GeyserSession session, ClientboundRegistryDataPacket packet) { + Map dimensions = session.getDimensions(); + dimensions.clear(); + JavaDimension.load(packet.getRegistry(), dimensions); + + Int2ObjectMap chatTypes = session.getChatTypes(); + chatTypes.clear(); + for (CompoundTag tag : JavaCodecUtil.iterateAsTag(packet.getRegistry().get("minecraft:chat_type"))) { + // The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. + int id = ((IntTag) tag.get("id")).getValue(); + CompoundTag element = tag.get("element"); + CompoundTag chat = element.get("chat"); + TextDecoration textDecoration = null; + if (chat != null) { + textDecoration = new TextDecoration(chat); + } + chatTypes.put(id, textDecoration); + } + + BiomeTranslator.loadServerBiomes(session, packet.getRegistry()); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java index 71f5dc8fc..fb7536b19 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; +import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerSpawnInfo; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundRespawnPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; @@ -46,6 +47,7 @@ public class JavaRespawnTranslator extends PacketTranslator { @@ -50,13 +52,24 @@ public class JavaPlayerInfoUpdateTranslator extends PacketTranslator definition = Registries.ENTITY_DEFINITIONS.get(packet.getType()); + if (definition == null) { + session.getGeyser().getLogger().warning("Could not find an entity definition with type " + packet.getType()); + return; + } + Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ()); Vector3f motion = Vector3f.from(packet.getMotionX(), packet.getMotionY(), packet.getMotionZ()); float yaw = packet.getYaw(); float pitch = packet.getPitch(); float headYaw = packet.getHeadYaw(); - EntityDefinition definition = Registries.ENTITY_DEFINITIONS.get(packet.getType()); - if (definition == null) { - session.getGeyser().getLogger().warning("Could not find an entity definition with type " + packet.getType()); + if (packet.getType() == EntityType.PLAYER) { + + PlayerEntity entity; + if (packet.getUuid().equals(session.getPlayerEntity().getUuid())) { + // Server is sending a fake version of the current player + entity = new PlayerEntity(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), + session.getPlayerEntity().getUuid(), position, motion, yaw, pitch, headYaw, session.getPlayerEntity().getUsername(), + session.getPlayerEntity().getTexturesProperty()); + } else { + entity = session.getEntityCache().getPlayerEntity(packet.getUuid()); + if (entity == null) { + GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.entity.player.failed_list", packet.getUuid())); + return; + } + + entity.setEntityId(packet.getEntityId()); + entity.setPosition(position); + entity.setYaw(yaw); + entity.setPitch(pitch); + entity.setHeadYaw(headYaw); + entity.setMotion(motion); + } + session.getEntityCache().cacheEntity(entity); + + entity.sendPlayer(); + SkinManager.requestAndHandleSkinAndCape(entity, session, null); return; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddPlayerTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddPlayerTranslator.java deleted file mode 100644 index 20a5f8213..000000000 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddPlayerTranslator.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2019-2022 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.geyser.translator.protocol.java.entity.spawn; - -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddPlayerPacket; -import org.cloudburstmc.math.vector.Vector3f; -import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.entity.type.player.PlayerEntity; -import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.skin.SkinManager; -import org.geysermc.geyser.text.GeyserLocale; -import org.geysermc.geyser.translator.protocol.PacketTranslator; -import org.geysermc.geyser.translator.protocol.Translator; - -@Translator(packet = ClientboundAddPlayerPacket.class) -public class JavaAddPlayerTranslator extends PacketTranslator { - - @Override - public void translate(GeyserSession session, ClientboundAddPlayerPacket packet) { - Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ()); - float yaw = packet.getYaw(); - float pitch = packet.getPitch(); - float headYaw = packet.getYaw(); - - PlayerEntity entity; - if (packet.getUuid().equals(session.getPlayerEntity().getUuid())) { - // Server is sending a fake version of the current player - entity = new PlayerEntity(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), - session.getPlayerEntity().getUuid(), position, Vector3f.ZERO, yaw, pitch, headYaw, session.getPlayerEntity().getUsername(), - session.getPlayerEntity().getTexturesProperty()); - } else { - entity = session.getEntityCache().getPlayerEntity(packet.getUuid()); - if (entity == null) { - GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.entity.player.failed_list", packet.getUuid())); - return; - } - - entity.setEntityId(packet.getEntityId()); - entity.setPosition(position); - entity.setYaw(yaw); - entity.setPitch(pitch); - entity.setHeadYaw(headYaw); - } - session.getEntityCache().cacheEntity(entity); - - entity.sendPlayer(); - SkinManager.requestAndHandleSkinAndCape(entity, session, null); - } -} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaChunkBatchFinishedTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaChunkBatchFinishedTranslator.java new file mode 100644 index 000000000..67f56111a --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaChunkBatchFinishedTranslator.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019-2023 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.geyser.translator.protocol.java.level; + +import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundChunkBatchFinishedPacket; +import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundChunkBatchReceivedPacket; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; + +@Translator(packet = ClientboundChunkBatchFinishedPacket.class) +public class JavaChunkBatchFinishedTranslator extends PacketTranslator { + + @Override + public void translate(GeyserSession session, ClientboundChunkBatchFinishedPacket packet) { + // server just sent a batch of LevelChunkWithLightPackets + // the vanilla client uses a ChunkBatchSizeCalculator to calculate the desiredChunksPerTick, + // but currently we just send an arbitrary value. server clamps the value between 0.01 and 64. + session.sendDownstreamPacket(new ServerboundChunkBatchReceivedPacket(20)); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java index d59b40b8f..aecb304db 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java @@ -31,6 +31,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.Clientb import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.protocol.bedrock.data.ParticleType; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelEventGenericPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; @@ -103,6 +104,10 @@ public class JavaLevelEventTranslator extends PacketTranslator { + effectPacket.setType(ParticleType.BRUSH_DUST); + session.playSoundEvent(SoundEvent.BRUSH_COMPLETED, pos); // todo 1.20.2 verify this + } case COMPOSTER -> { effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_CROP_GROWTH); @@ -224,6 +229,7 @@ public class JavaLevelEventTranslator extends PacketTranslator effectPacket.setType(ParticleType.VILLAGER_HAPPY); // both the lil green sparkle case ENDERDRAGON_FIREBALL_EXPLODE -> { effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EYE_OF_ENDER_DEATH); // TODO diff --git a/core/src/main/java/org/geysermc/geyser/util/PluginMessageUtils.java b/core/src/main/java/org/geysermc/geyser/util/PluginMessageUtils.java index 032dd2af7..f6b91388f 100644 --- a/core/src/main/java/org/geysermc/geyser/util/PluginMessageUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/PluginMessageUtils.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCustomPayloadPacket; +import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; import com.google.common.base.Charsets; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 587220aaf..31ce17e12 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 587220aafb55e80f2a70d6eac2d4b89dc0a005bd +Subproject commit 31ce17e12e991bd841270b99f461641093f42564 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3e19eea95..f654255fa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ protocol-connection = "3.0.0.Beta1-20230908.171156-105" raknet = "1.0.0.CR1-20230703.195238-9" blockstateupdater="1.20.30-20230918.203831-4" mcauthlib = "d9d773e" -mcprotocollib = "1.20-2-20230827.192136-1" +mcprotocollib = "1.20.2-1-20230926.224810-3" adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2"