diff --git a/connector/pom.xml b/connector/pom.xml index f52713ce..26ec0c4e 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -109,9 +109,9 @@ compile - com.github.GeyserMC + com.github.steveice10 mcprotocollib - e4a3aa636a + 976c2d0f89 compile 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 300877f8..5225632c 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 @@ -28,6 +28,7 @@ package org.geysermc.connector.network.session; import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.auth.exception.request.InvalidCredentialsException; import com.github.steveice10.mc.auth.exception.request.RequestException; +import com.github.steveice10.mc.protocol.MinecraftConstants; import com.github.steveice10.mc.protocol.MinecraftProtocol; import com.github.steveice10.mc.protocol.data.SubProtocol; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; @@ -117,8 +118,6 @@ public class GeyserSession implements CommandSender { */ private final Object2LongMap itemFrameCache = new Object2LongOpenHashMap<>(); - private DataCache javaPacketCache; - @Setter private Vector2i lastChunkPosition = null; private int renderDistance; @@ -176,6 +175,12 @@ public class GeyserSession implements CommandSender { @Setter private long lastWindowCloseTime = 0; + /** + * Saves the timestamp of the last keep alive packet + */ + @Setter + private long lastKeepAliveTimestamp = 0; + @Setter private VillagerTrade[] villagerTrades; @Setter @@ -276,8 +281,6 @@ public class GeyserSession implements CommandSender { this.playerEntity = new PlayerEntity(new GameProfile(UUID.randomUUID(), "unknown"), 1, 1, Vector3f.ZERO, Vector3f.ZERO, Vector3f.ZERO); this.inventory = new PlayerInventory(); - this.javaPacketCache = new DataCache<>(); - this.spawned = false; this.loggedIn = false; @@ -384,6 +387,8 @@ public class GeyserSession implements CommandSender { } downstream = new Client(remoteServer.getAddress(), remoteServer.getPort(), protocol, new TcpSessionFactory()); + // Let Geyser handle sending the keep alive + downstream.getSession().setFlag(MinecraftConstants.AUTOMATIC_KEEP_ALIVE_MANAGEMENT, false); downstream.getSession().addListener(new SessionAdapter() { @Override public void packetSending(PacketSendingEvent event) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java index c4386481..6517f498 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java @@ -25,7 +25,6 @@ package org.geysermc.connector.network.translators; -import com.github.steveice10.mc.protocol.packet.ingame.server.ServerKeepAlivePacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerPlayerListDataPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateLightPacket; import com.github.steveice10.packetlib.packet.Packet; @@ -75,7 +74,6 @@ public class PacketTranslatorRegistry { } } - IGNORED_PACKETS.add(ServerKeepAlivePacket.class); // Handled by MCProtocolLib IGNORED_PACKETS.add(ServerUpdateLightPacket.class); // Light is handled on Bedrock for us IGNORED_PACKETS.add(ServerPlayerListDataPacket.class); // Cant be implemented in bedrock } diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/DataCache.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockNetworkStackLatencyTranslator.java similarity index 54% rename from connector/src/main/java/org/geysermc/connector/network/session/cache/DataCache.java rename to connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockNetworkStackLatencyTranslator.java index 4b2af963..d480b526 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/cache/DataCache.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockNetworkStackLatencyTranslator.java @@ -23,15 +23,24 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.network.session.cache; +package org.geysermc.connector.network.translators.bedrock; -import lombok.Getter; +import com.github.steveice10.mc.protocol.packet.ingame.client.ClientKeepAlivePacket; +import com.nukkitx.protocol.bedrock.packet.NetworkStackLatencyPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.network.translators.Translator; -import java.util.HashMap; -import java.util.Map; +/** + * Used to send the keep alive packet back to the server + */ +@Translator(packet = NetworkStackLatencyPacket.class) +public class BedrockNetworkStackLatencyTranslator extends PacketTranslator { -public class DataCache { - - @Getter - private Map cachedValues = new HashMap(); + @Override + public void translate(NetworkStackLatencyPacket packet, GeyserSession session) { + // The client sends a timestamp back but it's rounded and therefore unreliable when we need the exact number + ClientKeepAlivePacket keepAlivePacket = new ClientKeepAlivePacket(session.getLastKeepAliveTimestamp()); + session.sendDownstreamPacket(keepAlivePacket); + } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaKeepAliveTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaKeepAliveTranslator.java new file mode 100644 index 00000000..1dd156e4 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaKeepAliveTranslator.java @@ -0,0 +1,48 @@ +/* + * 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; + +import com.github.steveice10.mc.protocol.packet.ingame.server.ServerKeepAlivePacket; +import com.nukkitx.protocol.bedrock.packet.NetworkStackLatencyPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.network.translators.Translator; + +/** + * Used to forward the keep alive packet to the client in order to get back a reliable ping. + */ +@Translator(packet = ServerKeepAlivePacket.class) +public class JavaKeepAliveTranslator extends PacketTranslator { + + @Override + public void translate(ServerKeepAlivePacket packet, GeyserSession session) { + session.setLastKeepAliveTimestamp(packet.getPingId()); + NetworkStackLatencyPacket latencyPacket = new NetworkStackLatencyPacket(); + latencyPacket.setFromServer(true); + latencyPacket.setTimestamp(packet.getPingId()); + session.sendUpstreamPacket(latencyPacket); + } +}