From 8a93f6a116e423db0716938b7057417398b20da0 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 15 Jan 2022 20:29:00 -0500 Subject: [PATCH] Send the client render distance to the server Previously we've had discussions on if the render distance math should be tweaked like we do server -> client, but for now this is better than nothing and can be tweaked further in the future. --- .../network/session/GeyserSession.java | 2 +- .../geyser/session/GeyserSession.java | 33 +++++++++++-- .../BedrockRequestChunkRadiusTranslator.java | 47 +++++++++++++++++++ .../protocol/java/JavaLoginTranslator.java | 23 +++------ .../JavaSetChunkCacheRadiusTranslator.java | 2 +- .../org/geysermc/geyser/util/ChunkUtils.java | 2 +- 6 files changed, 87 insertions(+), 22 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestChunkRadiusTranslator.java diff --git a/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 932761d4b..85bfd583d 100644 --- a/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -64,7 +64,7 @@ public class GeyserSession { } public int getRenderDistance() { - return this.handle.getRenderDistance(); + return this.handle.getServerRenderDistance(); } public boolean isSentSpawnPacket() { 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 7ea65e49e..742a2e4a9 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -38,10 +38,14 @@ import com.github.steveice10.mc.protocol.data.ProtocolState; import com.github.steveice10.mc.protocol.data.UnexpectedEncryptionException; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.entity.player.HandPreference; import com.github.steveice10.mc.protocol.data.game.recipe.Recipe; +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.handshake.serverbound.ClientIntentionPacket; +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.login.serverbound.ServerboundCustomQueryPacket; @@ -245,7 +249,9 @@ public class GeyserSession implements GeyserConnection, CommandSender { @Setter private Vector2i lastChunkPosition = null; - private int renderDistance; + @Setter + private int clientRenderDistance = -1; + private int serverRenderDistance; // Exposed for GeyserConnect usage protected boolean sentSpawnPacket; @@ -1160,9 +1166,9 @@ public class GeyserSession implements GeyserConnection, CommandSender { return clientData.getLanguageCode(); } - public void setRenderDistance(int renderDistance) { + public void setServerRenderDistance(int renderDistance) { renderDistance = GenericMath.ceil(++renderDistance * MathUtils.SQRT_OF_TWO); //square to circle - this.renderDistance = renderDistance; + this.serverRenderDistance = renderDistance; ChunkRadiusUpdatedPacket chunkRadiusUpdatedPacket = new ChunkRadiusUpdatedPacket(); chunkRadiusUpdatedPacket.setRadius(renderDistance); @@ -1420,6 +1426,27 @@ public class GeyserSession implements GeyserConnection, CommandSender { sendUpstreamPacket(adventureSettingsPacket); } + private int getRenderDistance() { + if (clientRenderDistance != -1) { + // The client has sent a render distance + return clientRenderDistance; + } + return serverRenderDistance; + } + + // We need to send our skin parts to the server otherwise java sees us with no hat, jacket etc + private static final List SKIN_PARTS = Arrays.asList(SkinPart.values()); + + /** + * Send a packet to the server to indicate client render distance, locale, skin parts, and hand preference. + */ + public void sendJavaClientSettings() { + ServerboundClientInformationPacket clientSettingsPacket = new ServerboundClientInformationPacket(getLocale(), + getRenderDistance(), ChatVisibility.FULL, true, SKIN_PARTS, + HandPreference.RIGHT_HAND, false, true); + sendDownstreamPacket(clientSettingsPacket); + } + /** * Used for updating statistic values since we only get changes from the server * diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestChunkRadiusTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestChunkRadiusTranslator.java new file mode 100644 index 000000000..0a27f7b64 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestChunkRadiusTranslator.java @@ -0,0 +1,47 @@ +/* + * 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.bedrock; + +import com.nukkitx.protocol.bedrock.packet.RequestChunkRadiusPacket; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; + +/** + * Sent when the client updates its desired render distance. + */ +@Translator(packet = RequestChunkRadiusPacket.class) +public class BedrockRequestChunkRadiusTranslator extends PacketTranslator { + + @Override + public void translate(GeyserSession session, RequestChunkRadiusPacket packet) { + session.setClientRenderDistance(packet.getRadius()); + + if (session.isLoggedIn()) { + session.sendJavaClientSettings(); + } + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java index 8521640bb..14dc37e5d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java @@ -25,31 +25,25 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.entity.player.HandPreference; -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.packet.ingame.clientbound.ClientboundLoginPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientInformationPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCustomPayloadPacket; import com.nukkitx.protocol.bedrock.data.GameRuleData; import com.nukkitx.protocol.bedrock.data.PlayerPermission; -import com.nukkitx.protocol.bedrock.packet.*; -import org.geysermc.geyser.session.auth.AuthType; +import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket; +import com.nukkitx.protocol.bedrock.packet.GameRulesChangedPacket; +import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.auth.AuthType; +import org.geysermc.geyser.translator.level.BiomeTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; -import org.geysermc.geyser.translator.level.BiomeTranslator; import org.geysermc.geyser.util.ChunkUtils; import org.geysermc.geyser.util.DimensionUtils; import org.geysermc.geyser.util.PluginMessageUtils; -import java.util.Arrays; -import java.util.List; - @Translator(packet = ClientboundLoginPacket.class) public class JavaLoginTranslator extends PacketTranslator { - private static final List SKIN_PART_VALUES = Arrays.asList(SkinPart.values()); @Override public void translate(GeyserSession session, ClientboundLoginPacket packet) { @@ -99,13 +93,10 @@ public class JavaLoginTranslator extends PacketTranslator