From c34dafe2a293ee9cae116d9024c7b2132be6201f Mon Sep 17 00:00:00 2001 From: Adrian <68704415+4drian3d@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:21:22 -0500 Subject: [PATCH] Implement ProtocolState API (#1224) * Implement ProtocolState API * Renamed method to #getProtocolState * Added sinceMinecraft javadoc tag * Fixed PreLoginEvent#getUniqueId documentation --- api/build.gradle.kts | 3 +- .../api/event/connection/PreLoginEvent.java | 5 +- .../api/network/ProtocolState.java | 52 +++++++++++++++++++ .../api/proxy/InboundConnection.java | 8 +++ .../com/velocitypowered/api/proxy/Player.java | 2 +- .../api/proxy/player/PlayerSettings.java | 1 + .../connection/client/ConnectedPlayer.java | 6 +++ .../client/HandshakeSessionHandler.java | 10 +++- .../client/InitialInboundConnection.java | 6 +++ .../client/LoginInboundConnection.java | 6 +++ .../proxy/protocol/StateRegistry.java | 16 ++++++ 11 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 api/src/main/java/com/velocitypowered/api/network/ProtocolState.java diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 56bb3c49c..aa6778fca 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -73,7 +73,8 @@ tasks { o.tags( "apiNote:a:API Note:", "implSpec:a:Implementation Requirements:", - "implNote:a:Implementation Note:" + "implNote:a:Implementation Note:", + "sinceMinecraft:a:Since Minecraft:" ) // Disable the crazy super-strict doclint tool in Java 8 diff --git a/api/src/main/java/com/velocitypowered/api/event/connection/PreLoginEvent.java b/api/src/main/java/com/velocitypowered/api/event/connection/PreLoginEvent.java index 6ac3f57e1..952cb091b 100644 --- a/api/src/main/java/com/velocitypowered/api/event/connection/PreLoginEvent.java +++ b/api/src/main/java/com/velocitypowered/api/event/connection/PreLoginEvent.java @@ -72,9 +72,12 @@ public final class PreLoginEvent implements ResultedEventThis value is {@code null} on 1.19.2 and lower, + * up to 1.20.1 it is optional and from 1.20.2 it will always be available.

* * @return the uuid + * @sinceMinecraft 1.19.3 */ public @Nullable UUID getUniqueId() { return uuid; diff --git a/api/src/main/java/com/velocitypowered/api/network/ProtocolState.java b/api/src/main/java/com/velocitypowered/api/network/ProtocolState.java new file mode 100644 index 000000000..f5df6fa59 --- /dev/null +++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolState.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2024 Velocity Contributors + * + * The Velocity API is licensed under the terms of the MIT License. For more details, + * reference the LICENSE file in the api top-level directory. + */ + +package com.velocitypowered.api.network; + +/** + * Representation of the state of the protocol + * in which a connection can be present. + * + * @since 3.3.0 + */ +public enum ProtocolState { + /** + * Initial connection State. + *

This status can be caused by a STATUS, LOGIN or TRANSFER intent.

+ * If the intent is LOGIN or TRANSFER, the next state will be {@link #LOGIN}, + * otherwise, it will go to the {@link #STATUS} state. + */ + HANDSHAKE, + /** + * Ping State of a connection. + *

Connections with the STATUS HandshakeIntent will pass through this state + * and be disconnected after it requests the ping from the server + * and the server responds with the respective ping.

+ */ + STATUS, + /** + * Authentication State of a connection. + *

At this moment the player is authenticating with the authentication servers.

+ */ + LOGIN, + /** + * Configuration State of a connection. + *

At this point the player allows the server to send information + * such as resource packs and plugin messages, at the same time the player + * will send his client brand and the respective plugin messages + * if it is a modded client.

+ * + * @sinceMinecraft 1.20.2 + */ + CONFIGURATION, + /** + * Game State of a connection. + *

In this state is where the whole game runs, the server is able to change + * the player's state to {@link #CONFIGURATION} as needed in versions 1.20.2 and higher.

+ */ + PLAY +} diff --git a/api/src/main/java/com/velocitypowered/api/proxy/InboundConnection.java b/api/src/main/java/com/velocitypowered/api/proxy/InboundConnection.java index e92c38bc7..224abbd6e 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/InboundConnection.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/InboundConnection.java @@ -7,6 +7,7 @@ package com.velocitypowered.api.proxy; +import com.velocitypowered.api.network.ProtocolState; import com.velocitypowered.api.network.ProtocolVersion; import java.net.InetSocketAddress; import java.util.Optional; @@ -43,4 +44,11 @@ public interface InboundConnection { * @return the protocol version the connection uses */ ProtocolVersion getProtocolVersion(); + + /** + * Returns the current protocol state of this connection. + * + * @return the protocol state of the connection + */ + ProtocolState getProtocolState(); } diff --git a/api/src/main/java/com/velocitypowered/api/proxy/Player.java b/api/src/main/java/com/velocitypowered/api/proxy/Player.java index eb41401b2..a73ff451b 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java @@ -190,7 +190,7 @@ public interface Player extends * * @param reason component with the reason */ - void disconnect(net.kyori.adventure.text.Component reason); + void disconnect(Component reason); /** * Sends chat input onto the players current server as if they typed it into the client chat box. diff --git a/api/src/main/java/com/velocitypowered/api/proxy/player/PlayerSettings.java b/api/src/main/java/com/velocitypowered/api/proxy/player/PlayerSettings.java index 4745eea17..320b1c203 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/player/PlayerSettings.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/player/PlayerSettings.java @@ -64,6 +64,7 @@ public interface PlayerSettings { * This feature was introduced in 1.18. * * @return whether or not the client explicitly allows listing. Always false on older clients. + * @sinceMinecraft 1.18 */ boolean isClientListingAllowed(); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java index 79ad81636..935a3c481 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java @@ -33,6 +33,7 @@ import com.velocitypowered.api.event.player.KickedFromServerEvent.ServerKickResu import com.velocitypowered.api.event.player.PlayerModInfoEvent; import com.velocitypowered.api.event.player.PlayerSettingsChangedEvent; import com.velocitypowered.api.event.player.ServerPreConnectEvent; +import com.velocitypowered.api.network.ProtocolState; import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.permission.PermissionFunction; import com.velocitypowered.api.permission.PermissionProvider; @@ -1170,6 +1171,11 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player, } } + @Override + public ProtocolState getProtocolState() { + return connection.getState().toProtocolState(); + } + private final class ConnectionRequestBuilderImpl implements ConnectionRequestBuilder { private final RegisteredServer toConnect; diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java index f1fc2d49f..5c5e928fe 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java @@ -20,6 +20,7 @@ package com.velocitypowered.proxy.connection.client; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.velocitypowered.api.event.connection.ConnectionHandshakeEvent; +import com.velocitypowered.api.network.ProtocolState; import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.config.PlayerInfoForwarding; @@ -247,9 +248,9 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler { @Override public String toString() { - boolean isPlayerAddressLoggingEnabled = connection.server.getConfiguration() + final boolean isPlayerAddressLoggingEnabled = connection.server.getConfiguration() .isPlayerAddressLoggingEnabled(); - String playerIp = + final String playerIp = isPlayerAddressLoggingEnabled ? this.getRemoteAddress().toString() : ""; return "[legacy connection] " + playerIp; @@ -259,5 +260,10 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler { public MinecraftConnection getConnection() { return connection; } + + @Override + public ProtocolState getProtocolState() { + return connection.getState().toProtocolState(); + } } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/InitialInboundConnection.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/InitialInboundConnection.java index 504368ca4..2441e2ac5 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/InitialInboundConnection.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/InitialInboundConnection.java @@ -17,6 +17,7 @@ package com.velocitypowered.proxy.connection.client; +import com.velocitypowered.api.network.ProtocolState; import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.proxy.InboundConnection; import com.velocitypowered.proxy.connection.MinecraftConnection; @@ -87,6 +88,11 @@ public final class InitialInboundConnection implements VelocityInboundConnection return connection; } + @Override + public ProtocolState getProtocolState() { + return connection.getState().toProtocolState(); + } + /** * Disconnects the connection from the server. * diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginInboundConnection.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginInboundConnection.java index 997cf4620..93064a790 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginInboundConnection.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginInboundConnection.java @@ -17,6 +17,7 @@ package com.velocitypowered.proxy.connection.client; +import com.velocitypowered.api.network.ProtocolState; import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.proxy.LoginPhaseConnection; import com.velocitypowered.api.proxy.crypto.IdentifiedKey; @@ -166,4 +167,9 @@ public class LoginInboundConnection implements LoginPhaseConnection, KeyIdentifi public IdentifiedKey getIdentifiedKey() { return playerKey; } + + @Override + public ProtocolState getProtocolState() { + return delegate.getProtocolState(); + } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java index 74fc26b0d..f53604a5a 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java @@ -45,6 +45,7 @@ import static com.velocitypowered.proxy.protocol.ProtocolUtils.Direction; import static com.velocitypowered.proxy.protocol.ProtocolUtils.Direction.CLIENTBOUND; import static com.velocitypowered.proxy.protocol.ProtocolUtils.Direction.SERVERBOUND; +import com.velocitypowered.api.network.ProtocolState; import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket; import com.velocitypowered.proxy.protocol.packet.BossBarPacket; @@ -623,6 +624,21 @@ public enum StateRegistry { return (direction == SERVERBOUND ? serverbound : clientbound).getProtocolRegistry(version); } + /** + * Gets the API representation of the StateRegistry. + * + * @return the API representation + */ + public ProtocolState toProtocolState() { + return switch (this) { + case HANDSHAKE -> ProtocolState.HANDSHAKE; + case STATUS -> ProtocolState.STATUS; + case LOGIN -> ProtocolState.LOGIN; + case CONFIG -> ProtocolState.CONFIGURATION; + case PLAY -> ProtocolState.PLAY; + }; + } + /** * Packet registry. */