From 7cede708754fc7fbe86bdc379203be27847ab709 Mon Sep 17 00:00:00 2001
From: RootBeer
Date: Mon, 26 Jan 2026 00:17:01 -0500
Subject: [PATCH 1/7] Bump various dependencies, including requirements for
checkstyle
---
api/build.gradle.kts | 9 +-
.../plugin/ap/PluginAnnotationProcessor.java | 9 +
.../ap/SerializedPluginDescription.java | 74 ++++++++
.../api/command/CommandSource.java | 30 ++--
.../api/command/VelocityBrigadierMessage.java | 6 +
.../api/event/Continuation.java | 4 +-
.../api/event/EventHandler.java | 16 ++
.../api/event/EventManager.java | 1 +
.../velocitypowered/api/event/PostOrder.java | 29 +++-
.../api/event/ResultedEvent.java | 35 ++++
.../event/command/CommandExecuteEvent.java | 14 ++
.../command/PlayerAvailableCommandsEvent.java | 10 ++
.../connection/ConnectionHandshakeEvent.java | 16 ++
.../api/event/connection/DisconnectEvent.java | 44 ++++-
.../api/event/connection/LoginEvent.java | 10 ++
.../event/connection/PluginMessageEvent.java | 41 +++++
.../api/event/connection/PostLoginEvent.java | 10 ++
.../api/event/connection/PreLoginEvent.java | 26 +++
.../event/connection/PreTransferEvent.java | 37 ++++
.../permission/PermissionsSetupEvent.java | 16 ++
.../api/event/player/CookieReceiveEvent.java | 25 +++
.../api/event/player/CookieRequestEvent.java | 15 ++
.../api/event/player/CookieStoreEvent.java | 27 +++
.../event/player/GameProfileRequestEvent.java | 21 ++-
.../event/player/KickedFromServerEvent.java | 22 +++
.../player/PlayerChannelRegisterEvent.java | 16 ++
.../player/PlayerChannelUnregisterEvent.java | 20 +++
.../api/event/player/PlayerChatEvent.java | 15 ++
.../PlayerChooseInitialServerEvent.java | 10 ++
.../event/player/PlayerClientBrandEvent.java | 16 +-
.../api/event/player/PlayerModInfoEvent.java | 16 ++
.../player/PlayerResourcePackStatusEvent.java | 10 ++
.../player/PlayerSettingsChangedEvent.java | 16 ++
.../event/player/ServerConnectedEvent.java | 15 ++
.../player/ServerLoginPluginMessageEvent.java | 26 +++
.../event/player/ServerPostConnectEvent.java | 7 +
.../event/player/ServerPreConnectEvent.java | 5 +
.../player/ServerResourcePackRemoveEvent.java | 3 +
.../player/ServerResourcePackSendEvent.java | 21 +++
.../PlayerConfigurationEvent.java | 1 +
.../PlayerEnterConfigurationEvent.java | 3 +-
.../PlayerEnteredConfigurationEvent.java | 1 +
.../PlayerFinishConfigurationEvent.java | 3 +-
.../PlayerFinishedConfigurationEvent.java | 1 +
.../api/event/proxy/ListenerBoundEvent.java | 16 ++
.../api/event/proxy/ListenerCloseEvent.java | 16 ++
.../api/event/proxy/ProxyInitializeEvent.java | 6 +
.../api/event/proxy/ProxyPingEvent.java | 6 +
.../event/proxy/ProxyPreShutdownEvent.java | 6 +
.../api/event/proxy/ProxyReloadEvent.java | 6 +
.../api/event/proxy/ProxyShutdownEvent.java | 6 +
.../proxy/server/ServerRegisteredEvent.java | 6 +
.../proxy/server/ServerUnregisteredEvent.java | 6 +
.../api/network/HandshakeIntent.java | 17 ++
.../api/network/ListenerType.java | 6 +
.../api/network/ProtocolState.java | 5 +
.../api/network/ProtocolVersion.java | 162 +++++++++++++++++-
.../api/permission/Tristate.java | 2 +-
.../api/plugin/InvalidPluginException.java | 19 ++
.../api/plugin/PluginDescription.java | 6 +
.../com/velocitypowered/api/proxy/Player.java | 25 +--
.../api/proxy/crypto/IdentifiedKey.java | 23 ++-
.../api/proxy/crypto/KeySigned.java | 2 +-
.../messages/LegacyChannelIdentifier.java | 5 +
.../messages/MinecraftChannelIdentifier.java | 15 ++
.../api/proxy/player/PlayerSettings.java | 24 +++
.../api/proxy/player/ResourcePackInfo.java | 7 +-
.../api/proxy/player/SkinParts.java | 40 +++++
.../api/proxy/player/TabListEntry.java | 3 +
.../api/proxy/server/QueryResponse.java | 18 +-
.../api/proxy/server/ServerInfo.java | 18 +-
.../api/proxy/server/ServerPing.java | 129 +++++++++++++-
.../velocitypowered/api/util/GameProfile.java | 15 ++
.../com/velocitypowered/api/util/ModInfo.java | 24 +++
.../api/util/ProxyVersion.java | 15 ++
.../velocitypowered/api/util/ServerLink.java | 32 ++++
gradle/libs.versions.toml | 8 +-
.../natives/util/MoreByteBufUtils.java | 4 +-
.../velocitypowered/proxy/VelocityServer.java | 2 +-
.../handler/ModernResourcePackHandler.java | 2 +-
.../handler/ResourcePackHandler.java | 1 +
.../proxy/event/VelocityEventManager.java | 62 +++----
.../proxy/protocol/ProtocolUtils.java | 6 +-
.../src/main/resources/default-velocity.toml | 2 +-
84 files changed, 1415 insertions(+), 110 deletions(-)
diff --git a/api/build.gradle.kts b/api/build.gradle.kts
index 268a8197ba..5e503f6a84 100644
--- a/api/build.gradle.kts
+++ b/api/build.gradle.kts
@@ -24,7 +24,7 @@ dependencies {
api(libs.guava)
// DEPRECATED: Will be removed in Velocity Polymer
- api("com.moandjiezana.toml:toml4j:0.7.2")
+ api("io.hotmoka:toml4j:0.7.3")
api(platform(libs.adventure.bom))
api("net.kyori:adventure-api")
@@ -55,8 +55,6 @@ tasks {
}
}
withType {
- exclude("com/velocitypowered/api/plugin/ap/**")
-
val o = options as StandardJavadocDocletOptions
o.encoding = "UTF-8"
o.source = "21"
@@ -66,7 +64,7 @@ tasks {
"https://www.javadocs.dev/org.slf4j/slf4j-api/${libs.slf4j.get().version}/",
"https://guava.dev/releases/${libs.guava.get().version}/api/docs/",
"https://google.github.io/guice/api-docs/${libs.guice.get().version}/javadoc/",
- "https://docs.oracle.com/en/java/javase/17/docs/api/",
+ "https://docs.oracle.com/en/java/javase/21/docs/api/",
"https://jd.advntr.dev/api/${libs.adventure.bom.get().version}/",
"https://jd.advntr.dev/text-minimessage/${libs.adventure.bom.get().version}/",
"https://jd.advntr.dev/key/${libs.adventure.bom.get().version}/",
@@ -79,8 +77,5 @@ tasks {
"implNote:a:Implementation Note:",
"sinceMinecraft:a:Since Minecraft:"
)
-
- // Disable the crazy super-strict doclint tool in Java 8
- o.addStringOption("Xdoclint:none", "-quiet")
}
}
diff --git a/api/src/ap/java/com/velocitypowered/api/plugin/ap/PluginAnnotationProcessor.java b/api/src/ap/java/com/velocitypowered/api/plugin/ap/PluginAnnotationProcessor.java
index b44f284787..6424d34e01 100644
--- a/api/src/ap/java/com/velocitypowered/api/plugin/ap/PluginAnnotationProcessor.java
+++ b/api/src/ap/java/com/velocitypowered/api/plugin/ap/PluginAnnotationProcessor.java
@@ -36,6 +36,15 @@
@SupportedAnnotationTypes({"com.velocitypowered.api.plugin.Plugin"})
public class PluginAnnotationProcessor extends AbstractProcessor {
+ /**
+ * Creates a new {@code PluginAnnotationProcessor}.
+ *
+ * The processor is instantiated by the Java compiler and initialized via
+ * {@link #init(ProcessingEnvironment)}.
+ */
+ public PluginAnnotationProcessor() {
+ }
+
private ProcessingEnvironment environment;
private String pluginClassFound;
private boolean warnedAboutMultiplePlugins;
diff --git a/api/src/ap/java/com/velocitypowered/api/plugin/ap/SerializedPluginDescription.java b/api/src/ap/java/com/velocitypowered/api/plugin/ap/SerializedPluginDescription.java
index b712d8967d..b8a35ec95e 100644
--- a/api/src/ap/java/com/velocitypowered/api/plugin/ap/SerializedPluginDescription.java
+++ b/api/src/ap/java/com/velocitypowered/api/plugin/ap/SerializedPluginDescription.java
@@ -24,7 +24,19 @@
*/
public final class SerializedPluginDescription {
+ /**
+ * The string pattern used to validate plugin IDs.
+ *
+ * Plugin IDs must start with a lowercase letter and may contain lowercase letters,
+ * digits, hyphens, and underscores. The total length must not exceed 64 characters.
+ */
public static final String ID_PATTERN_STRING = "[a-z][a-z0-9-_]{0,63}";
+ /**
+ * The compiled pattern used to validate plugin IDs.
+ *
+ * Plugin IDs must start with a lowercase letter and may contain lowercase letters,
+ * digits, hyphens, and underscores. The total length must not exceed 64 characters.
+ */
public static final Pattern ID_PATTERN = Pattern.compile(ID_PATTERN_STRING);
// @Nullable is used here to make GSON skip these in the serialized file
@@ -64,34 +76,78 @@ static SerializedPluginDescription from(Plugin plugin, String qualifiedName) {
.collect(Collectors.toList()), dependencies, qualifiedName);
}
+ /**
+ * Gets the ID of the plugin this dependency refers to.
+ *
+ * @return the plugin ID
+ */
public String getId() {
return id;
}
+ /**
+ * Gets the human-readable name of the plugin.
+ *
+ * @return the plugin's name, or {@code null} if not specified
+ */
public @Nullable String getName() {
return name;
}
+ /**
+ * Gets the version string of the plugin.
+ *
+ * @return the plugin version, or {@code null} if not specified
+ */
public @Nullable String getVersion() {
return version;
}
+ /**
+ * Gets the plugin's description, typically a short summary of its functionality.
+ *
+ * @return the description, or {@code null} if not specified
+ */
public @Nullable String getDescription() {
return description;
}
+ /**
+ * Gets the website URL for the plugin.
+ *
+ * This is often used to link to documentation, support, or the plugin's homepage.
+ *
+ * @return the plugin URL, or {@code null} if not specified
+ */
public @Nullable String getUrl() {
return url;
}
+ /**
+ * Gets the list of authors who contributed to the plugin.
+ *
+ * @return an immutable list of authors; empty if none were specified
+ */
public List getAuthors() {
return authors == null ? ImmutableList.of() : authors;
}
+ /**
+ * Gets the list of declared dependencies for the plugin.
+ *
+ * Dependencies may be required or optional and describe other plugins, this one depends.
+ *
+ * @return an immutable list of plugin dependencies
+ */
public List getDependencies() {
return dependencies == null ? ImmutableList.of() : dependencies;
}
+ /**
+ * Gets the fully qualified name of the plugin's main class.
+ *
+ * @return the main class name
+ */
public String getMain() {
return main;
}
@@ -142,15 +198,33 @@ public static final class Dependency {
private final String id;
private final boolean optional;
+ /**
+ * Constructs a new dependency class.
+ *
+ * @param id the ID of the dependent plugin
+ * @param optional whether the dependency is optional
+ */
public Dependency(String id, boolean optional) {
this.id = id;
this.optional = optional;
}
+ /**
+ * Gets the ID of the plugin this dependency refers to.
+ *
+ * @return the plugin ID
+ */
public String getId() {
return id;
}
+ /**
+ * Indicates whether this dependency is optional.
+ *
+ * Optional dependencies are not required for the plugin to load.
+ *
+ * @return {@code true} if the dependency is optional; {@code false} otherwise
+ */
public boolean isOptional() {
return optional;
}
diff --git a/api/src/main/java/com/velocitypowered/api/command/CommandSource.java b/api/src/main/java/com/velocitypowered/api/command/CommandSource.java
index 3cc0392515..24d5272dab 100644
--- a/api/src/main/java/com/velocitypowered/api/command/CommandSource.java
+++ b/api/src/main/java/com/velocitypowered/api/command/CommandSource.java
@@ -25,20 +25,20 @@ public interface CommandSource extends Audience, PermissionSubject {
* @param message MiniMessage content
* @see MiniMessage docs
* for more information on the format.
- **/
+ */
default void sendRichMessage(final @NotNull String message) {
this.sendMessage(MiniMessage.miniMessage().deserialize(message, this));
}
/**
- * Sends a message with the MiniMessage format to this source.
- *
- * @param message MiniMessage content
- * @param resolvers resolvers to use
- * @see MiniMessage docs
- * and MiniMessage Placeholders docs
- * for more information on the format.
- **/
+ * Sends a message with the MiniMessage format to this source.
+ *
+ * @param message MiniMessage content
+ * @param resolvers resolvers to use
+ * @see MiniMessage docs
+ * and MiniMessage Placeholders docs
+ * for more information on the format.
+ */
default void sendRichMessage(
final @NotNull String message,
final @NotNull TagResolver @NotNull... resolvers
@@ -47,13 +47,13 @@ default void sendRichMessage(
}
/**
- * Sends a plain message to this source.
- *
- * @param message plain message
- * @apiNote This method will not apply any form of parse to the text provided,
- * however, it is recommended not to use legacy color codes as this is a deprecated format
+ * Sends a plain message to this source.
+ *
+ * @param message plain message
+ * @apiNote This method will not apply any form of parse to the text provided,
+ * however, it is recommended not to use legacy color codes as this is a deprecated format
* and not recommended.
- */
+ */
default void sendPlainMessage(final @NotNull String message) {
this.sendMessage(Component.text(message));
}
diff --git a/api/src/main/java/com/velocitypowered/api/command/VelocityBrigadierMessage.java b/api/src/main/java/com/velocitypowered/api/command/VelocityBrigadierMessage.java
index 0ae69591ef..bd6415c30d 100644
--- a/api/src/main/java/com/velocitypowered/api/command/VelocityBrigadierMessage.java
+++ b/api/src/main/java/com/velocitypowered/api/command/VelocityBrigadierMessage.java
@@ -20,6 +20,12 @@
*/
public final class VelocityBrigadierMessage implements Message, ComponentLike {
+ /**
+ * Creates a new {@link VelocityBrigadierMessage} using the given {@link Component} as the message.
+ *
+ * @param message the component to use as the tooltip message
+ * @return a new instance of {@link VelocityBrigadierMessage}
+ */
public static VelocityBrigadierMessage tooltip(Component message) {
return new VelocityBrigadierMessage(message);
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/Continuation.java b/api/src/main/java/com/velocitypowered/api/event/Continuation.java
index 30672ef606..5c17bf7b5f 100644
--- a/api/src/main/java/com/velocitypowered/api/event/Continuation.java
+++ b/api/src/main/java/com/velocitypowered/api/event/Continuation.java
@@ -20,6 +20,8 @@ public interface Continuation {
/**
* Resumes the continuation after the executed task failed.
+ *
+ * @param exception the {@link Throwable} that caused the failure
*/
void resumeWithException(Throwable exception);
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/velocitypowered/api/event/EventHandler.java b/api/src/main/java/com/velocitypowered/api/event/EventHandler.java
index 3f0a1aa0c3..ca8b164b32 100644
--- a/api/src/main/java/com/velocitypowered/api/event/EventHandler.java
+++ b/api/src/main/java/com/velocitypowered/api/event/EventHandler.java
@@ -13,12 +13,28 @@
* Represents an interface to perform direct dispatch of an event. This makes integration easier to
* achieve with platforms such as RxJava. While this interface can be used to implement an awaiting
* event handler, {@link AwaitingEventExecutor} provides a more idiomatic means to doing so.
+ *
+ * @param the event type this handler accepts
*/
@FunctionalInterface
public interface EventHandler {
+ /**
+ * Executes this handler synchronously with the given event.
+ *
+ * @param event the event to handle
+ */
void execute(E event);
+ /**
+ * Executes this handler asynchronously with the given event.
+ *
+ * If asynchronous handling is not implemented, the event is executed synchronously
+ * and this method returns {@code null}.
+ *
+ * @param event the event to handle
+ * @return an {@link EventTask} representing the async task, or {@code null} if not async
+ */
default @Nullable EventTask executeAsync(E event) {
execute(event);
return null;
diff --git a/api/src/main/java/com/velocitypowered/api/event/EventManager.java b/api/src/main/java/com/velocitypowered/api/event/EventManager.java
index ed11986c17..b8d604cf8e 100644
--- a/api/src/main/java/com/velocitypowered/api/event/EventManager.java
+++ b/api/src/main/java/com/velocitypowered/api/event/EventManager.java
@@ -73,6 +73,7 @@ void register(Object plugin, Class eventClass, short postOrder,
* servicing connections while a plugin handles a potentially long-running operation such as a
* database query.
*
+ * @param the event type
* @param event the event to fire
* @return a {@link CompletableFuture} representing the posted event
*/
diff --git a/api/src/main/java/com/velocitypowered/api/event/PostOrder.java b/api/src/main/java/com/velocitypowered/api/event/PostOrder.java
index 98fa2e86f5..21b418cb56 100644
--- a/api/src/main/java/com/velocitypowered/api/event/PostOrder.java
+++ b/api/src/main/java/com/velocitypowered/api/event/PostOrder.java
@@ -12,7 +12,34 @@
*/
public enum PostOrder {
- FIRST, EARLY, NORMAL, LATE, LAST,
+ /**
+ * Indicates the listener should be invoked first, before any other listener.
+ * This order is suitable for listeners that must handle the event before others.
+ */
+ FIRST,
+ /**
+ * Indicates the listener should be invoked early, but after listeners with {@link #FIRST}.
+ * This order is suitable for handling the event before most other listeners.
+ */
+ EARLY,
+ /**
+ * Indicates the listener should be invoked in the normal order of execution.
+ * This is the default and most commonly used order.
+ */
+ NORMAL,
+ /**
+ * Indicates the listener should be invoked later in the execution order,
+ * after listeners with {@link #NORMAL}.
+ * This order is suitable for listeners that should observe the results of
+ * earlier listeners.
+ */
+ LATE,
+ /**
+ * Indicates the listener should be invoked last, after all other listeners.
+ * This order is suitable for listeners that should run only after all others
+ * have completed handling the event.
+ */
+ LAST,
/**
* Previously used to specify that {@link Subscribe#priority()} should be used.
diff --git a/api/src/main/java/com/velocitypowered/api/event/ResultedEvent.java b/api/src/main/java/com/velocitypowered/api/event/ResultedEvent.java
index 0aafd05831..d2a338601f 100644
--- a/api/src/main/java/com/velocitypowered/api/event/ResultedEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/ResultedEvent.java
@@ -15,6 +15,8 @@
/**
* Indicates an event that has a result attached to it.
+ *
+ * @param the type of result associated with the event
*/
public interface ResultedEvent {
@@ -70,10 +72,20 @@ public String toString() {
return status ? "allowed" : "denied";
}
+ /**
+ * Returns a result indicating the event is allowed to proceed.
+ *
+ * @return an allowed {@link GenericResult}
+ */
public static GenericResult allowed() {
return ALLOWED;
}
+ /**
+ * Returns a result indicating the event is denied.
+ *
+ * @return a denied {@link GenericResult}
+ */
public static GenericResult denied() {
return DENIED;
}
@@ -89,6 +101,12 @@ final class ComponentResult implements Result {
private final boolean status;
private final @Nullable Component reason;
+ /**
+ * Represents an allowed or denied result that may include a denial reason.
+ *
+ * @param status whether the result is allowed
+ * @param reason the component explaining why the result was denied, or {@code null}
+ */
protected ComponentResult(boolean status, @Nullable Component reason) {
this.status = status;
this.reason = reason;
@@ -99,6 +117,11 @@ public boolean isAllowed() {
return status;
}
+ /**
+ * Returns the denial reason component, if present.
+ *
+ * @return an {@link Optional} containing the reason component if the result is denied
+ */
public Optional getReasonComponent() {
return Optional.ofNullable(reason);
}
@@ -114,10 +137,22 @@ public String toString() {
return "denied";
}
+ /**
+ * Returns a result indicating the event is allowed to proceed.
+ *
+ * @return an allowed {@link ComponentResult}
+ */
public static ComponentResult allowed() {
return ALLOWED;
}
+ /**
+ * Returns a result indicating the event is denied, with the given reason component.
+ *
+ * @param reason the denial reason to show
+ * @return a denied {@link ComponentResult}
+ * @throws NullPointerException if the reason is null
+ */
public static ComponentResult denied(Component reason) {
Preconditions.checkNotNull(reason, "reason");
return new ComponentResult(false, reason);
diff --git a/api/src/main/java/com/velocitypowered/api/event/command/CommandExecuteEvent.java b/api/src/main/java/com/velocitypowered/api/event/command/CommandExecuteEvent.java
index 7ed704fc0a..6daa62a825 100644
--- a/api/src/main/java/com/velocitypowered/api/event/command/CommandExecuteEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/command/CommandExecuteEvent.java
@@ -106,6 +106,8 @@ public String toString() {
/**
* Represents information about a command invocation, including its signed state and source.
*
+ * @param signedState the signed state of the command
+ * @param source the source of the command invocation
* @since 3.4.0
*/
public record InvocationInfo(SignedState signedState, Source source) {
@@ -191,10 +193,22 @@ private CommandResult(final boolean status, final boolean forward, final @Nullab
this.command = command;
}
+ /**
+ * Returns the command to be executed, if it was overridden.
+ *
+ * @return an {@link Optional} containing the new command string (without leading slash),
+ * or empty if no override is present
+ */
public Optional getCommand() {
return Optional.ofNullable(command);
}
+ /**
+ * Indicates whether this command should be forwarded directly to the backend server
+ * instead of being processed by the proxy.
+ *
+ * @return {@code true} if the command should be forwarded to the server, {@code false} otherwise
+ */
public boolean isForwardToServer() {
return forward;
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/command/PlayerAvailableCommandsEvent.java b/api/src/main/java/com/velocitypowered/api/event/command/PlayerAvailableCommandsEvent.java
index d00cffac67..265fbdda90 100644
--- a/api/src/main/java/com/velocitypowered/api/event/command/PlayerAvailableCommandsEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/command/PlayerAvailableCommandsEvent.java
@@ -37,10 +37,20 @@ public PlayerAvailableCommandsEvent(Player player,
this.rootNode = checkNotNull(rootNode, "rootNode");
}
+ /**
+ * Gets the player that the available commands are being sent to.
+ *
+ * @return the targeted player
+ */
public Player getPlayer() {
return player;
}
+ /**
+ * Gets the root command node that represents the available commands.
+ *
+ * @return the Brigadier root command node
+ */
public RootCommandNode> getRootNode() {
return rootNode;
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/connection/ConnectionHandshakeEvent.java b/api/src/main/java/com/velocitypowered/api/event/connection/ConnectionHandshakeEvent.java
index e344b6c504..d3ddc0e37c 100644
--- a/api/src/main/java/com/velocitypowered/api/event/connection/ConnectionHandshakeEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/connection/ConnectionHandshakeEvent.java
@@ -21,6 +21,12 @@ public final class ConnectionHandshakeEvent {
private final InboundConnection connection;
private final HandshakeIntent intent;
+ /**
+ * Constructs a new {@link ConnectionHandshakeEvent}.
+ *
+ * @param connection the inbound connection from the client
+ * @param intent the intent of the handshake (e.g., login or status)
+ */
public ConnectionHandshakeEvent(InboundConnection connection, HandshakeIntent intent) {
this.connection = Preconditions.checkNotNull(connection, "connection");
this.intent = Preconditions.checkNotNull(intent, "intent");
@@ -39,10 +45,20 @@ public ConnectionHandshakeEvent(InboundConnection connection) {
this.intent = HandshakeIntent.LOGIN;
}
+ /**
+ * Returns the inbound connection associated with this handshake.
+ *
+ * @return the connection
+ */
public InboundConnection getConnection() {
return connection;
}
+ /**
+ * Returns the {@link HandshakeIntent} associated with this connection handshake.
+ *
+ * @return the intent of the handshake
+ */
public HandshakeIntent getIntent() {
return this.intent;
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/connection/DisconnectEvent.java b/api/src/main/java/com/velocitypowered/api/event/connection/DisconnectEvent.java
index bec7b74562..4a2dba4fd3 100644
--- a/api/src/main/java/com/velocitypowered/api/event/connection/DisconnectEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/connection/DisconnectEvent.java
@@ -17,12 +17,10 @@
* Operations on the provided player, aside from basic data retrieval operations, may behave in
* undefined ways.
*
- *
- * Velocity typically fires this event asynchronously and does not wait for a response. However,
- * it will wait for all {@link DisconnectEvent}s for every player on the proxy to fire
- * successfully before the proxy shuts down. This event is the sole exception to the
- * {@link AwaitingEvent} contract.
- *
+ * Velocity typically fires this event asynchronously and does not wait for a response. However,
+ * it will wait for all {@link DisconnectEvent}s for every player on the proxy to fire
+ * successfully before the proxy shuts down. This event is the sole exception to the
+ * {@link AwaitingEvent} contract.
*/
@AwaitingEvent
public final class DisconnectEvent {
@@ -30,15 +28,31 @@ public final class DisconnectEvent {
private final Player player;
private final LoginStatus loginStatus;
+ /**
+ * Creates a new {@link DisconnectEvent}.
+ *
+ * @param player the player who disconnected
+ * @param loginStatus the status of the player's login at the time of disconnection
+ */
public DisconnectEvent(Player player, LoginStatus loginStatus) {
this.player = Preconditions.checkNotNull(player, "player");
this.loginStatus = Preconditions.checkNotNull(loginStatus, "loginStatus");
}
+ /**
+ * Returns the player who disconnected.
+ *
+ * @return the player
+ */
public Player getPlayer() {
return player;
}
+ /**
+ * Returns the login status of the player at the time of disconnection.
+ *
+ * @return the login status
+ */
public LoginStatus getLoginStatus() {
return loginStatus;
}
@@ -56,11 +70,29 @@ public String toString() {
*/
public enum LoginStatus {
+ /**
+ * The player completed a successful login to the proxy.
+ */
SUCCESSFUL_LOGIN,
+ /**
+ * The player was disconnected because another login with the same UUID occurred.
+ */
CONFLICTING_LOGIN,
+ /**
+ * The player voluntarily disconnected before completing the login.
+ */
CANCELLED_BY_USER,
+ /**
+ * The proxy disconnected the player before login completed.
+ */
CANCELLED_BY_PROXY,
+ /**
+ * The player disconnected on their own, but only after starting the login and before completing it.
+ */
CANCELLED_BY_USER_BEFORE_COMPLETE,
+ /**
+ * The player disconnected before joining the initial backend server.
+ */
PRE_SERVER_JOIN
}
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/connection/LoginEvent.java b/api/src/main/java/com/velocitypowered/api/event/connection/LoginEvent.java
index 494088972c..3ec0126497 100644
--- a/api/src/main/java/com/velocitypowered/api/event/connection/LoginEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/connection/LoginEvent.java
@@ -24,11 +24,21 @@ public final class LoginEvent 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.
*
@@ -129,14 +140,29 @@ public boolean isAllowed() {
return result != Result.DISALLOWED;
}
+ /**
+ * Gets the reason component shown to the player if the connection is denied.
+ *
+ * @return the reason as a {@link net.kyori.adventure.text.Component}, or empty if not denied
+ */
public Optional getReasonComponent() {
return Optional.ofNullable(reason);
}
+ /**
+ * Checks if this result explicitly forces online mode for the connection.
+ *
+ * @return true if online mode is forced
+ */
public boolean isOnlineModeAllowed() {
return result == Result.FORCE_ONLINE;
}
+ /**
+ * Checks if this result explicitly forces offline mode for the connection.
+ *
+ * @return true if offline mode is forced
+ */
public boolean isForceOfflineMode() {
return result == Result.FORCE_OFFLINE;
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/connection/PreTransferEvent.java b/api/src/main/java/com/velocitypowered/api/event/connection/PreTransferEvent.java
index 584ab0052d..37e96a7d1a 100644
--- a/api/src/main/java/com/velocitypowered/api/event/connection/PreTransferEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/connection/PreTransferEvent.java
@@ -28,15 +28,31 @@ public final class PreTransferEvent implements ResultedEvent channels;
+ /**
+ * Constructs a new PlayerChannelRegisterEvent.
+ *
+ * @param player the player who sent the plugin message
+ * @param channels the list of channels the player is registering
+ */
public PlayerChannelRegisterEvent(Player player, List channels) {
this.player = Preconditions.checkNotNull(player, "player");
this.channels = Preconditions.checkNotNull(channels, "channels");
}
+ /**
+ * Gets the player who sent the plugin message to register channels.
+ *
+ * @return the player involved in this event
+ */
public Player getPlayer() {
return player;
}
+ /**
+ * Gets the list of {@link ChannelIdentifier}s that the player registered.
+ *
+ * @return the list of registered channels
+ */
public List getChannels() {
return channels;
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/PlayerChannelUnregisterEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/PlayerChannelUnregisterEvent.java
index 86eeb2bc91..69e59da07c 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/PlayerChannelUnregisterEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/PlayerChannelUnregisterEvent.java
@@ -21,15 +21,35 @@ public final class PlayerChannelUnregisterEvent {
private final Player player;
private final List channels;
+ /**
+ * Constructs a new {@link PlayerChannelUnregisterEvent}.
+ *
+ * @param player the player that sent the unregister message
+ * @param channels the list of {@link ChannelIdentifier}s being unregistered
+ * @throws NullPointerException if {@code player} or {@code channels} is {@code null}
+ */
public PlayerChannelUnregisterEvent(Player player, List channels) {
this.player = Preconditions.checkNotNull(player, "player");
this.channels = Preconditions.checkNotNull(channels, "channels");
}
+ /**
+ * Gets the {@link Player} who sent the unregister message.
+ *
+ * @return the player involved in this event
+ */
public Player getPlayer() {
return player;
}
+ /**
+ * Gets the list of {@link ChannelIdentifier}s that the player has unregistered.
+ *
+ * These identifiers correspond to the plugin message channels that the client has
+ * indicated it will no longer use.
+ *
+ * @return the list of unregistered channels
+ */
public List getChannels() {
return channels;
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/PlayerChatEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/PlayerChatEvent.java
index dd1fae29b4..6548cf6027 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/PlayerChatEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/PlayerChatEvent.java
@@ -38,10 +38,20 @@ public PlayerChatEvent(Player player, String message) {
this.result = ChatResult.allowed();
}
+ /**
+ * Gets the player who sent the chat message.
+ *
+ * @return the player who sent the message
+ */
public Player getPlayer() {
return player;
}
+ /**
+ * Gets the (possibly modified) chat message to be sent.
+ *
+ * @return an {@link Optional} containing the message, or empty if none
+ */
public String getMessage() {
return message;
}
@@ -88,6 +98,11 @@ private ChatResult(boolean status, @Nullable String message) {
this.message = message;
}
+ /**
+ * Gets the (possibly modified) chat message to be sent.
+ *
+ * @return an {@link Optional} containing the message, or empty if none
+ */
public Optional getMessage() {
return Optional.ofNullable(message);
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/PlayerChooseInitialServerEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/PlayerChooseInitialServerEvent.java
index 73d41ecdcd..587d374a01 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/PlayerChooseInitialServerEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/PlayerChooseInitialServerEvent.java
@@ -37,10 +37,20 @@ public PlayerChooseInitialServerEvent(Player player, @Nullable RegisteredServer
this.initialServer = initialServer;
}
+ /**
+ * Gets the player who is choosing the initial server.
+ *
+ * @return the connected player
+ */
public Player getPlayer() {
return player;
}
+ /**
+ * Gets the initial server the player will connect to.
+ *
+ * @return an {@link Optional} containing the selected server, or empty if none was set
+ */
public Optional getInitialServer() {
return Optional.ofNullable(initialServer);
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/PlayerClientBrandEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/PlayerClientBrandEvent.java
index 268d5b6a19..0a45093fc9 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/PlayerClientBrandEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/PlayerClientBrandEvent.java
@@ -29,10 +29,20 @@ public PlayerClientBrandEvent(Player player, String brand) {
this.brand = Preconditions.checkNotNull(brand);
}
+ /**
+ * Gets the player who sent the client brand.
+ *
+ * @return the player
+ */
public Player getPlayer() {
return player;
}
+ /**
+ * Gets the brand string sent by the client.
+ *
+ * @return the client brand
+ */
public String getBrand() {
return brand;
}
@@ -40,9 +50,9 @@ public String getBrand() {
@Override
public String toString() {
return "PlayerClientBrandEvent{"
- + "player=" + player
- + ", brand='" + brand + '\''
- + '}';
+ + "player=" + player
+ + ", brand='" + brand + '\''
+ + '}';
}
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/PlayerModInfoEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/PlayerModInfoEvent.java
index eb0b413363..377b8b452a 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/PlayerModInfoEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/PlayerModInfoEvent.java
@@ -21,15 +21,31 @@ public final class PlayerModInfoEvent {
private final Player player;
private final ModInfo modInfo;
+ /**
+ * Constructs a new {@code PlayerModInfoEvent}.
+ *
+ * @param player the player sending their mod list
+ * @param modInfo the mod list information
+ */
public PlayerModInfoEvent(Player player, ModInfo modInfo) {
this.player = Preconditions.checkNotNull(player, "player");
this.modInfo = Preconditions.checkNotNull(modInfo, "modInfo");
}
+ /**
+ * Returns the player who sent their mod list.
+ *
+ * @return the player
+ */
public Player getPlayer() {
return player;
}
+ /**
+ * Returns the mod information sent by the player.
+ *
+ * @return the mod information
+ */
public ModInfo getModInfo() {
return modInfo;
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/PlayerResourcePackStatusEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/PlayerResourcePackStatusEvent.java
index d212666b71..9e3f59f292 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/PlayerResourcePackStatusEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/PlayerResourcePackStatusEvent.java
@@ -33,6 +33,8 @@ public class PlayerResourcePackStatusEvent {
/**
* Instantiates this event.
*
+ * @param player the player affected by the status update
+ * @param status the status of the resource pack
* @deprecated Use {@link PlayerResourcePackStatusEvent#PlayerResourcePackStatusEvent
* (Player, UUID, Status, ResourcePackInfo)} instead.
*/
@@ -44,6 +46,9 @@ public PlayerResourcePackStatusEvent(Player player, Status status) {
/**
* Instantiates this event.
*
+ * @param player the player affected by the status update
+ * @param status the status of the resource pack
+ * @param packInfo the resource pack metadata
* @deprecated Use {@link PlayerResourcePackStatusEvent#PlayerResourcePackStatusEvent
* (Player, UUID, Status, ResourcePackInfo)} instead.
*/
@@ -54,6 +59,11 @@ public PlayerResourcePackStatusEvent(Player player, Status status, ResourcePackI
/**
* Instantiates this event.
+ *
+ * @param player the player affected by the status update
+ * @param packId the unique ID of the resource pack
+ * @param status the status of the resource pack
+ * @param packInfo the resource pack metadata
*/
public PlayerResourcePackStatusEvent(
Player player, UUID packId, Status status, ResourcePackInfo packInfo) {
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/PlayerSettingsChangedEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/PlayerSettingsChangedEvent.java
index cd1bd01c22..542633c72b 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/PlayerSettingsChangedEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/PlayerSettingsChangedEvent.java
@@ -22,15 +22,31 @@ public final class PlayerSettingsChangedEvent {
private final Player player;
private final PlayerSettings playerSettings;
+ /**
+ * Constructs a new PlayerSettingsChangedEvent.
+ *
+ * @param player the player who changed settings
+ * @param playerSettings the new settings sent by the client
+ */
public PlayerSettingsChangedEvent(Player player, PlayerSettings playerSettings) {
this.player = Preconditions.checkNotNull(player, "player");
this.playerSettings = Preconditions.checkNotNull(playerSettings, "playerSettings");
}
+ /**
+ * Returns the player whose settings changed.
+ *
+ * @return the player
+ */
public Player getPlayer() {
return player;
}
+ /**
+ * Returns the new client settings sent by the player.
+ *
+ * @return the updated player settings
+ */
public PlayerSettings getPlayerSettings() {
return playerSettings;
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/ServerConnectedEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/ServerConnectedEvent.java
index ac4452a0a8..48e9858733 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/ServerConnectedEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/ServerConnectedEvent.java
@@ -45,14 +45,29 @@ public ServerConnectedEvent(Player player, RegisteredServer server,
this.previousServer = previousServer;
}
+ /**
+ * Returns the player involved in this event.
+ *
+ * @return the {@link Player} who connected
+ */
public Player getPlayer() {
return player;
}
+ /**
+ * Returns the server the player successfully connected to.
+ *
+ * @return the {@link RegisteredServer} the player connected to
+ */
public RegisteredServer getServer() {
return server;
}
+ /**
+ * Returns the server the player was previously connected to, if any.
+ *
+ * @return an {@link Optional} of the previous {@link RegisteredServer}, or empty if none
+ */
public Optional getPreviousServer() {
return Optional.ofNullable(previousServer);
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/ServerLoginPluginMessageEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/ServerLoginPluginMessageEvent.java
index 9597e02afa..d790d97548 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/ServerLoginPluginMessageEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/ServerLoginPluginMessageEvent.java
@@ -63,10 +63,20 @@ public void setResult(ResponseResult result) {
this.result = checkNotNull(result, "result");
}
+ /**
+ * Gets the connection from which the login plugin message was received.
+ *
+ * @return the server connection
+ */
public ServerConnection getConnection() {
return connection;
}
+ /**
+ * Gets the identifier of the channel this login plugin message was sent on.
+ *
+ * @return the channel identifier
+ */
public ChannelIdentifier getIdentifier() {
return identifier;
}
@@ -100,6 +110,11 @@ public ByteArrayDataInput contentsAsDataStream() {
return ByteStreams.newDataInput(contents);
}
+ /**
+ * Gets the sequence ID of the plugin message sent by the server.
+ *
+ * @return the sequence ID
+ */
public int getSequenceId() {
return sequenceId;
}
@@ -146,10 +161,21 @@ public byte[] getResponse() {
return response.clone();
}
+ /**
+ * Returns a result indicating that this login plugin message was not handled by the proxy.
+ *
+ * @return the unknown response result
+ */
public static ResponseResult unknown() {
return UNKNOWN;
}
+ /**
+ * Returns a result with a reply to the server's login plugin message.
+ *
+ * @param response the response bytes to send
+ * @return a response result containing the response data
+ */
public static ResponseResult reply(byte[] response) {
checkNotNull(response, "response");
return new ResponseResult(response);
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/ServerPostConnectEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/ServerPostConnectEvent.java
index 95e70a49f3..cb751dd71a 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/ServerPostConnectEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/ServerPostConnectEvent.java
@@ -21,6 +21,13 @@ public class ServerPostConnectEvent {
private final Player player;
private final RegisteredServer previousServer;
+ /**
+ * Constructs a new {@link ServerPostConnectEvent}.
+ *
+ * @param player the player that connected to the server
+ * @param previousServer the server the player was previously connected to, or {@code null}
+ * if the player had not been connected to a server before
+ */
public ServerPostConnectEvent(Player player,
@Nullable RegisteredServer previousServer) {
this.player = Preconditions.checkNotNull(player, "player");
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/ServerPreConnectEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/ServerPreConnectEvent.java
index 98bcb60d3a..593a824e5b 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/ServerPreConnectEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/ServerPreConnectEvent.java
@@ -126,6 +126,11 @@ public boolean isAllowed() {
return server != null;
}
+ /**
+ * Returns the server the player will be connected to if the result is allowed.
+ *
+ * @return the server to connect to, or an empty Optional if the connection is denied
+ */
public Optional getServer() {
return Optional.ofNullable(server);
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/ServerResourcePackRemoveEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/ServerResourcePackRemoveEvent.java
index 96d1bb8e52..52901cf4bb 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/ServerResourcePackRemoveEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/ServerResourcePackRemoveEvent.java
@@ -29,6 +29,9 @@ public class ServerResourcePackRemoveEvent implements ResultedEventVelocity will wait for this event before continuing/ending the configuration state.
*
* @param player The player who can be configured.
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerEnterConfigurationEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerEnterConfigurationEvent.java
index 05d6c2af02..97a2ded0e0 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerEnterConfigurationEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerEnterConfigurationEvent.java
@@ -15,8 +15,9 @@
/**
* This event is executed when a player is about to enter the configuration state.
* It is not called for the initial configuration of a player after login.
+ *
* Velocity will wait for this event before asking the client to enter configuration state.
- * However due to backend server being unable to keep the connection alive during state changes,
+ * However, due to backend server being unable to keep the connection alive during state changes,
* Velocity will only wait for a maximum of 5 seconds.
*
* @param player The player who is about to enter configuration state.
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerEnteredConfigurationEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerEnteredConfigurationEvent.java
index c16777066c..6560f7bc43 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerEnteredConfigurationEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerEnteredConfigurationEvent.java
@@ -14,6 +14,7 @@
/**
* This event is executed when a player has entered the configuration state.
+ *
* From this moment on, until the {@link PlayerFinishedConfigurationEvent} is executed,
* the {@linkplain Player#getProtocolState()} method is guaranteed
* to return {@link ProtocolState#CONFIGURATION}.
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerFinishConfigurationEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerFinishConfigurationEvent.java
index 50df5a8abe..1cd3f2833c 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerFinishConfigurationEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerFinishConfigurationEvent.java
@@ -14,8 +14,9 @@
/**
* This event is executed when a player is about to finish the configuration state.
+ *
* Velocity will wait for this event before asking the client to finish the configuration state.
- * However due to backend server being unable to keep the connection alive during state changes,
+ * However, due to backend server being unable to keep the connection alive during state changes,
* Velocity will only wait for a maximum of 5 seconds. If you need to hold a player in configuration
* state, use the {@link PlayerConfigurationEvent}.
*
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerFinishedConfigurationEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerFinishedConfigurationEvent.java
index 517f119cfe..994a1d4111 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerFinishedConfigurationEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerFinishedConfigurationEvent.java
@@ -14,6 +14,7 @@
/**
* This event is executed when a player has finished the configuration state.
+ *
* From this moment on, the {@link Player#getProtocolState()} method
* will return {@link ProtocolState#PLAY}.
*
diff --git a/api/src/main/java/com/velocitypowered/api/event/proxy/ListenerBoundEvent.java b/api/src/main/java/com/velocitypowered/api/event/proxy/ListenerBoundEvent.java
index 662e403db7..1824a69c8d 100644
--- a/api/src/main/java/com/velocitypowered/api/event/proxy/ListenerBoundEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/proxy/ListenerBoundEvent.java
@@ -19,15 +19,31 @@ public final class ListenerBoundEvent {
private final InetSocketAddress address;
private final ListenerType listenerType;
+ /**
+ * Constructs a new {@link ListenerBoundEvent}.
+ *
+ * @param address the socket address the listener is bound to
+ * @param listenerType the type of listener that was bound
+ */
public ListenerBoundEvent(InetSocketAddress address, ListenerType listenerType) {
this.address = Preconditions.checkNotNull(address, "address");
this.listenerType = Preconditions.checkNotNull(listenerType, "listenerType");
}
+ /**
+ * Returns the socket address the listener is bound to.
+ *
+ * @return the bound socket address
+ */
public InetSocketAddress getAddress() {
return address;
}
+ /**
+ * Returns the type of listener that was bound.
+ *
+ * @return the listener type
+ */
public ListenerType getListenerType() {
return listenerType;
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/proxy/ListenerCloseEvent.java b/api/src/main/java/com/velocitypowered/api/event/proxy/ListenerCloseEvent.java
index c2551a3598..da8c61d624 100644
--- a/api/src/main/java/com/velocitypowered/api/event/proxy/ListenerCloseEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/proxy/ListenerCloseEvent.java
@@ -19,15 +19,31 @@ public final class ListenerCloseEvent {
private final InetSocketAddress address;
private final ListenerType listenerType;
+ /**
+ * Constructs a new {@link ListenerCloseEvent}.
+ *
+ * @param address the socket address the listener was bound to
+ * @param listenerType the type of listener being closed
+ */
public ListenerCloseEvent(InetSocketAddress address, ListenerType listenerType) {
this.address = Preconditions.checkNotNull(address, "address");
this.listenerType = Preconditions.checkNotNull(listenerType, "listenerType");
}
+ /**
+ * Returns the socket address the listener was bound to.
+ *
+ * @return the bound socket address
+ */
public InetSocketAddress getAddress() {
return address;
}
+ /**
+ * Returns the type of listener being closed.
+ *
+ * @return the listener type
+ */
public ListenerType getListenerType() {
return listenerType;
}
diff --git a/api/src/main/java/com/velocitypowered/api/event/proxy/ProxyInitializeEvent.java b/api/src/main/java/com/velocitypowered/api/event/proxy/ProxyInitializeEvent.java
index d01ce190d5..7e19f0e1a5 100644
--- a/api/src/main/java/com/velocitypowered/api/event/proxy/ProxyInitializeEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/proxy/ProxyInitializeEvent.java
@@ -17,6 +17,12 @@
@AwaitingEvent
public final class ProxyInitializeEvent {
+ /**
+ * Creates a new {@code ProxyInitializeEvent}.
+ */
+ public ProxyInitializeEvent() {
+ }
+
@Override
public String toString() {
return "ProxyInitializeEvent";
diff --git a/api/src/main/java/com/velocitypowered/api/event/proxy/ProxyPingEvent.java b/api/src/main/java/com/velocitypowered/api/event/proxy/ProxyPingEvent.java
index 635554366b..14d4088498 100644
--- a/api/src/main/java/com/velocitypowered/api/event/proxy/ProxyPingEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/proxy/ProxyPingEvent.java
@@ -28,6 +28,12 @@ public final class ProxyPingEvent implements ResultedEventThis status can be caused by a {@link HandshakeIntent#STATUS},
* {@link HandshakeIntent#LOGIN} or {@link HandshakeIntent#TRANSFER} intent.
* If the intent is LOGIN or TRANSFER, the next state will be {@link #LOGIN},
@@ -24,6 +25,7 @@ public enum ProtocolState {
HANDSHAKE,
/**
* Ping State of a connection.
+ *
* Connections with the {@link HandshakeIntent#STATUS} intent will pass through this state
* and be disconnected after it requests the ping from the server
* and the server responds with the respective ping.
@@ -31,11 +33,13 @@ public enum ProtocolState {
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
@@ -46,6 +50,7 @@ public enum ProtocolState {
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.
*/
diff --git a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
index e803c30240..c3eba7657e 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -21,6 +21,9 @@
* Represents each Minecraft protocol version.
*/
public enum ProtocolVersion implements Ordered {
+ /**
+ * Represents an unknown protocol version.
+ */
UNKNOWN(-1, "Unknown") {
@Override
public boolean isUnknown() {
@@ -32,6 +35,9 @@ public boolean isSupported() {
return false;
}
},
+ /**
+ * Represents legacy protocol versions before 1.7.
+ */
LEGACY(-2, "Legacy") {
@Override
public boolean isLegacy() {
@@ -43,57 +49,201 @@ public boolean isSupported() {
return false;
}
},
- MINECRAFT_1_7_2(4,
- "1.7.2", "1.7.3", "1.7.4", "1.7.5"),
- MINECRAFT_1_7_6(5,
- "1.7.6", "1.7.7", "1.7.8", "1.7.9", "1.7.10"),
- MINECRAFT_1_8(47,
- "1.8", "1.8.1", "1.8.2", "1.8.3", "1.8.4", "1.8.5", "1.8.6", "1.8.7", "1.8.8", "1.8.9"),
+ /**
+ * Minecraft 1.7.2 to 1.7.5.
+ */
+ MINECRAFT_1_7_2(4, "1.7.2", "1.7.3", "1.7.4", "1.7.5"),
+ /**
+ * Minecraft 1.7.6 to 1.7.10.
+ */
+ MINECRAFT_1_7_6(5, "1.7.6", "1.7.7", "1.7.8", "1.7.9", "1.7.10"),
+ /**
+ * Minecraft 1.8 to 1.8.9.
+ */
+ MINECRAFT_1_8(47, "1.8", "1.8.1", "1.8.2", "1.8.3", "1.8.4", "1.8.5", "1.8.6", "1.8.7", "1.8.8", "1.8.9"),
+ /**
+ * Minecraft 1.9.
+ */
MINECRAFT_1_9(107, "1.9"),
+ /**
+ * Minecraft 1.9.1.
+ */
MINECRAFT_1_9_1(108, "1.9.1"),
+ /**
+ * Minecraft 1.9.2.
+ */
MINECRAFT_1_9_2(109, "1.9.2"),
+ /**
+ * Minecraft 1.9.3 to 1.9.4.
+ */
MINECRAFT_1_9_4(110, "1.9.3", "1.9.4"),
+ /**
+ * Minecraft 1.10 to 1.10.2.
+ */
MINECRAFT_1_10(210, "1.10", "1.10.1", "1.10.2"),
+ /**
+ * Minecraft 1.11.
+ */
MINECRAFT_1_11(315, "1.11"),
+ /**
+ * Minecraft 1.11.1 to 1.11.2.
+ */
MINECRAFT_1_11_1(316, "1.11.1", "1.11.2"),
+ /**
+ * Minecraft 1.12.
+ */
MINECRAFT_1_12(335, "1.12"),
+ /**
+ * Minecraft 1.12.1.
+ */
MINECRAFT_1_12_1(338, "1.12.1"),
+ /**
+ * Minecraft 1.12.2.
+ */
MINECRAFT_1_12_2(340, "1.12.2"),
+ /**
+ * Minecraft 1.13.
+ */
MINECRAFT_1_13(393, "1.13"),
+ /**
+ * Minecraft 1.13.1.
+ */
MINECRAFT_1_13_1(401, "1.13.1"),
+ /**
+ * Minecraft 1.13.2.
+ */
MINECRAFT_1_13_2(404, "1.13.2"),
+ /**
+ * Minecraft 1.14.
+ */
MINECRAFT_1_14(477, "1.14"),
+ /**
+ * Minecraft 1.14.1.
+ */
MINECRAFT_1_14_1(480, "1.14.1"),
+ /**
+ * Minecraft 1.14.2.
+ */
MINECRAFT_1_14_2(485, "1.14.2"),
+ /**
+ * Minecraft 1.14.3.
+ */
MINECRAFT_1_14_3(490, "1.14.3"),
+ /**
+ * Minecraft 1.14.4.
+ */
MINECRAFT_1_14_4(498, "1.14.4"),
+ /**
+ * Minecraft 1.15.
+ */
MINECRAFT_1_15(573, "1.15"),
+ /**
+ * Minecraft 1.15.1.
+ */
MINECRAFT_1_15_1(575, "1.15.1"),
+ /**
+ * Minecraft 1.15.2.
+ */
MINECRAFT_1_15_2(578, "1.15.2"),
+ /**
+ * Minecraft 1.16.
+ */
MINECRAFT_1_16(735, "1.16"),
+ /**
+ * Minecraft 1.16.1.
+ */
MINECRAFT_1_16_1(736, "1.16.1"),
+ /**
+ * Minecraft 1.16.2.
+ */
MINECRAFT_1_16_2(751, "1.16.2"),
+ /**
+ * Minecraft 1.16.3.
+ */
MINECRAFT_1_16_3(753, "1.16.3"),
+ /**
+ * Minecraft 1.16.4 to 1.16.5.
+ */
MINECRAFT_1_16_4(754, "1.16.4", "1.16.5"),
+ /**
+ * Minecraft 1.17.
+ */
MINECRAFT_1_17(755, "1.17"),
+ /**
+ * Minecraft 1.17.1.
+ */
MINECRAFT_1_17_1(756, "1.17.1"),
+ /**
+ * Minecraft 1.18 to 1.18.1.
+ */
MINECRAFT_1_18(757, "1.18", "1.18.1"),
+ /**
+ * Minecraft 1.18.2.
+ */
MINECRAFT_1_18_2(758, "1.18.2"),
+ /**
+ * Minecraft 1.19.
+ */
MINECRAFT_1_19(759, "1.19"),
+ /**
+ * Minecraft 1.19.1 to 1.19.2.
+ */
MINECRAFT_1_19_1(760, "1.19.1", "1.19.2"),
+ /**
+ * Minecraft 1.19.3.
+ */
MINECRAFT_1_19_3(761, "1.19.3"),
+ /**
+ * Minecraft 1.19.4.
+ */
MINECRAFT_1_19_4(762, "1.19.4"),
+ /**
+ * Minecraft 1.20 to 1.20.1.
+ */
MINECRAFT_1_20(763, "1.20", "1.20.1"),
+ /**
+ * Minecraft 1.20.2.
+ */
MINECRAFT_1_20_2(764, "1.20.2"),
+ /**
+ * Minecraft 1.20.3 to 1.20.4.
+ */
MINECRAFT_1_20_3(765, "1.20.3", "1.20.4"),
+ /**
+ * Minecraft 1.20.5 to 1.20.6.
+ */
MINECRAFT_1_20_5(766, "1.20.5", "1.20.6"),
+ /**
+ * Minecraft 1.21 to 1.21.1.
+ */
MINECRAFT_1_21(767, "1.21", "1.21.1"),
+ /**
+ * Minecraft 1.21.2 to 1.21.3.
+ */
MINECRAFT_1_21_2(768, "1.21.2", "1.21.3"),
+ /**
+ * Minecraft 1.21.4.
+ */
MINECRAFT_1_21_4(769, "1.21.4"),
+ /**
+ * Minecraft 1.21.5.
+ */
MINECRAFT_1_21_5(770, "1.21.5"),
+ /**
+ * Minecraft 1.21.6.
+ */
MINECRAFT_1_21_6(771, "1.21.6"),
+ /**
+ * Minecraft 1.21.7 to 1.21.8.
+ */
MINECRAFT_1_21_7(772, "1.21.7", "1.21.8"),
+ /**
+ * Minecraft 1.21.9 to 1.21.10.
+ */
MINECRAFT_1_21_9(773, "1.21.9", "1.21.10"),
+ /**
+ * Minecraft 1.21.11.
+ */
MINECRAFT_1_21_11(774, "1.21.11");
private static final int SNAPSHOT_BIT = 30;
diff --git a/api/src/main/java/com/velocitypowered/api/permission/Tristate.java b/api/src/main/java/com/velocitypowered/api/permission/Tristate.java
index ddbe26a866..02f6924b78 100644
--- a/api/src/main/java/com/velocitypowered/api/permission/Tristate.java
+++ b/api/src/main/java/com/velocitypowered/api/permission/Tristate.java
@@ -15,7 +15,7 @@
* Represents three different states of a setting.
*
* Possible values:
- *
+ *
*
* - {@link #TRUE} - a positive setting
* - {@link #FALSE} - a negative (negated) setting
diff --git a/api/src/main/java/com/velocitypowered/api/plugin/InvalidPluginException.java b/api/src/main/java/com/velocitypowered/api/plugin/InvalidPluginException.java
index 1882d26404..bee2a26d5e 100644
--- a/api/src/main/java/com/velocitypowered/api/plugin/InvalidPluginException.java
+++ b/api/src/main/java/com/velocitypowered/api/plugin/InvalidPluginException.java
@@ -12,18 +12,37 @@
*/
public class InvalidPluginException extends Exception {
+ /**
+ * Creates a new exception with no detail message.
+ */
public InvalidPluginException() {
super();
}
+ /**
+ * Creates a new exception with the specified detail message.
+ *
+ * @param message the detail message
+ */
public InvalidPluginException(String message) {
super(message);
}
+ /**
+ * Creates a new exception with the specified detail message and cause.
+ *
+ * @param message the detail message
+ * @param cause the cause of the exception
+ */
public InvalidPluginException(String message, Throwable cause) {
super(message, cause);
}
+ /**
+ * Creates a new exception with the specified cause.
+ *
+ * @param cause the cause of the exception
+ */
public InvalidPluginException(Throwable cause) {
super(cause);
}
diff --git a/api/src/main/java/com/velocitypowered/api/plugin/PluginDescription.java b/api/src/main/java/com/velocitypowered/api/plugin/PluginDescription.java
index 540b54ea5e..cbf9b48700 100644
--- a/api/src/main/java/com/velocitypowered/api/plugin/PluginDescription.java
+++ b/api/src/main/java/com/velocitypowered/api/plugin/PluginDescription.java
@@ -96,6 +96,12 @@ default Collection getDependencies() {
return ImmutableSet.of();
}
+ /**
+ * Gets a specific dependency of the {@link Plugin} by its ID.
+ *
+ * @param id the ID of the dependency to look up
+ * @return an {@link Optional} containing the matching {@link PluginDependency}, or empty if not found
+ */
default Optional getDependency(String id) {
return Optional.empty();
}
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 efe21cd746..456f654170 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java
@@ -150,6 +150,8 @@ public interface Player extends
/**
* Returns the player's game profile.
+ *
+ * @return the player's profile
*/
GameProfile getGameProfile();
@@ -242,10 +244,10 @@ default void clearHeaderAndFooter() {
* Gets the {@link ResourcePackInfo} of the currently applied
* resource-pack or null if none.
*
- * Note that since 1.20.3 it is no longer recommended to use
+ *
Note that since 1.20.3 it is no longer recommended to use
* this method as it will only return the last applied
* resource pack. To get all applied resource packs, use
- * {@link #getAppliedResourcePacks()} instead.
+ * {@link #getAppliedResourcePacks()} instead.
*
* @return the applied resource pack or null if none.
*/
@@ -258,10 +260,10 @@ default void clearHeaderAndFooter() {
* the user is currently downloading or is currently
* prompted to install or null if none.
*
- * Note that since 1.20.3 it is no longer recommended to use
+ *
Note that since 1.20.3 it is no longer recommended to use
* this method as it will only return the last pending
* resource pack. To get all pending resource packs, use
- * {@link #getPendingResourcePacks()} instead.
+ * {@link #getPendingResourcePacks()} instead.
*
* @return the pending resource pack or null if none
*/
@@ -313,6 +315,7 @@ default void clearHeaderAndFooter() {
/**
* {@inheritDoc}
+ *
* Note that this method does not send a plugin message to the server the player
* is connected to. You should only use this method if you are trying to communicate
* with a mod that is installed on the player's client.
@@ -336,7 +339,6 @@ default void clearHeaderAndFooter() {
Component.text(getUsername()))));
}
-
/**
* Gets the player's client brand.
*
@@ -384,12 +386,11 @@ default void clearHeaderAndFooter() {
/**
* {@inheritDoc}
*
- *
* @apiNote This method is not currently implemented in Velocity
* and will not perform any actions.
* @see #playSound(Sound, Sound.Emitter)
* @see
- * Unsupported Adventure Operations
+ * Unsupported Adventure Operations
*/
@Override
default void playSound(@NotNull Sound sound) {
@@ -402,7 +403,7 @@ default void playSound(@NotNull Sound sound) {
* and will not perform any actions.
* @see #playSound(Sound, Sound.Emitter)
* @see
- * Unsupported Adventure Operations
+ * Unsupported Adventure Operations
*/
@Override
default void playSound(@NotNull Sound sound, double x, double y, double z) {
@@ -445,7 +446,7 @@ default void stopSound(@NotNull SoundStop stop) {
* and will not perform any actions.
*
* @see
- * Unsupported Adventure Operations
+ * Unsupported Adventure Operations
*/
@Override
default void openBook(@NotNull Book book) {
@@ -458,7 +459,7 @@ default void openBook(@NotNull Book book) {
* and will not perform any actions.
*
* @see
- * Unsupported Adventure Operations
+ * Unsupported Adventure Operations
*/
@Override
default void showDialog(@NotNull DialogLike dialog) {
@@ -471,7 +472,7 @@ default void showDialog(@NotNull DialogLike dialog) {
* and will not perform any actions.
*
* @see
- * Unsupported Adventure Operations
+ * Unsupported Adventure Operations
*/
@Override
default void closeDialog() {
@@ -521,4 +522,4 @@ default void closeDialog() {
* @sinceMinecraft 1.21
*/
void setServerLinks(@NotNull List links);
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/crypto/IdentifiedKey.java b/api/src/main/java/com/velocitypowered/api/proxy/crypto/IdentifiedKey.java
index d2a6cc94e3..b6c0112127 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/crypto/IdentifiedKey.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/crypto/IdentifiedKey.java
@@ -28,7 +28,6 @@ public interface IdentifiedKey extends KeySigned {
*/
PublicKey getSignedPublicKey();
-
/**
* Validates a signature against this public key.
*
@@ -59,7 +58,15 @@ public interface IdentifiedKey extends KeySigned {
* The different versions of player keys, per Minecraft version.
*/
enum Revision implements Ordered {
+ /**
+ * Represents the original key revision introduced in Minecraft 1.19.
+ * Keys are not tied to a specific player identity.
+ */
GENERIC_V1(ImmutableSet.of(), ImmutableSet.of(ProtocolVersion.MINECRAFT_1_19)),
+ /**
+ * Represents the key revision introduced in Minecraft 1.19.1.
+ * Keys are cryptographically linked to player identities.
+ */
LINKED_V2(ImmutableSet.of(), ImmutableSet.of(ProtocolVersion.MINECRAFT_1_19_1));
final Set backwardsCompatibleTo;
@@ -69,11 +76,21 @@ enum Revision implements Ordered {
this.backwardsCompatibleTo = backwardsCompatibleTo;
this.applicableTo = applicableTo;
}
-
+
+ /**
+ * Returns the set of revisions that this revision is backwards-compatible with.
+ *
+ * @return a set of compatible earlier revisions
+ */
public Set getBackwardsCompatibleTo() {
return backwardsCompatibleTo;
}
-
+
+ /**
+ * Returns the set of Minecraft protocol versions this revision applies to.
+ *
+ * @return a set of applicable protocol versions
+ */
public Set getApplicableTo() {
return applicableTo;
}
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/crypto/KeySigned.java b/api/src/main/java/com/velocitypowered/api/proxy/crypto/KeySigned.java
index 8ad64c1811..83fd402f5f 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/crypto/KeySigned.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/crypto/KeySigned.java
@@ -34,7 +34,6 @@ public interface KeySigned {
*/
Instant getExpiryTemporal();
-
/**
* Check if the signature has expired.
*
@@ -56,6 +55,7 @@ default boolean hasExpired() {
* Validates the signature, expiry temporal and key against the
* signer public key. Note: This will **not** check for
* expiry. You can check for expiry with {@link KeySigned#hasExpired()}.
+ *
* DOES NOT WORK YET FOR MESSAGES AND COMMANDS!
* Addendum: Does not work for 1.19.1 until the user has authenticated.
*
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/messages/LegacyChannelIdentifier.java b/api/src/main/java/com/velocitypowered/api/proxy/messages/LegacyChannelIdentifier.java
index 9da9a7b4aa..eafb484f4f 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/messages/LegacyChannelIdentifier.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/messages/LegacyChannelIdentifier.java
@@ -31,6 +31,11 @@ public LegacyChannelIdentifier(String name) {
this.name = name;
}
+ /**
+ * Returns the name of this legacy plugin message channel.
+ *
+ * @return the channel name
+ */
public String getName() {
return name;
}
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/messages/MinecraftChannelIdentifier.java b/api/src/main/java/com/velocitypowered/api/proxy/messages/MinecraftChannelIdentifier.java
index a271a414d4..92f8ef9fee 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/messages/MinecraftChannelIdentifier.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/messages/MinecraftChannelIdentifier.java
@@ -84,14 +84,29 @@ public static MinecraftChannelIdentifier from(Key key) {
return create(key.namespace(), key.value());
}
+ /**
+ * Returns the namespace of this channel identifier.
+ *
+ * @return the namespace string (e.g., {@code minecraft})
+ */
public String getNamespace() {
return namespace;
}
+ /**
+ * Returns the name of the channel within its namespace.
+ *
+ * @return the channel name string
+ */
public String getName() {
return name;
}
+ /**
+ * Converts this channel identifier to a {@link Key} object.
+ *
+ * @return a {@link Key} representing this identifier
+ */
public Key asKey() {
return Key.key(namespace, name);
}
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 416cbf154e..91cca964f2 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
@@ -86,8 +86,17 @@ public interface PlayerSettings {
* The client's current chat display mode.
*/
enum ChatMode {
+ /**
+ * Chat is fully visible.
+ */
SHOWN,
+ /**
+ * Only command messages are shown.
+ */
COMMANDS_ONLY,
+ /**
+ * Chat is completely hidden.
+ */
HIDDEN
}
@@ -95,7 +104,13 @@ enum ChatMode {
* The player's selected dominant hand.
*/
enum MainHand {
+ /**
+ * This scope defines the left hand.
+ */
LEFT,
+ /**
+ * This scope defines the right hand.
+ */
RIGHT
}
@@ -103,8 +118,17 @@ enum MainHand {
* The client's current "Particles" option state.
*/
enum ParticleStatus {
+ /**
+ * All particles are shown.
+ */
ALL,
+ /**
+ * A reduced number of particles are shown.
+ */
DECREASED,
+ /**
+ * Minimal particle effects are shown.
+ */
MINIMAL
}
}
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/player/ResourcePackInfo.java b/api/src/main/java/com/velocitypowered/api/proxy/player/ResourcePackInfo.java
index 82937685ab..7e620185a0 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/player/ResourcePackInfo.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/player/ResourcePackInfo.java
@@ -87,7 +87,6 @@ public interface ResourcePackInfo extends ResourcePackRequestLike {
/**
* Returns a copy of this {@link ResourcePackInfo} instance as a builder, using the new URL.
- *
* It is not guaranteed that
* {@code resourcePackInfo.asBuilder(resourcePackInfo.getUrl()).build().equals(resourcePackInfo)}
* is true, because the {@link ResourcePackInfo#getOrigin()} and
@@ -108,6 +107,7 @@ interface Builder {
* Sets the id of the resource pack.
*
* @param id the id the resource-pack
+ * @return this builder instance
*/
Builder setId(UUID id);
@@ -128,6 +128,7 @@ interface Builder {
* the player will be disconnected from the network
*
* @param shouldForce whether or not to force the client to accept the resource pack
+ * @return this builder instance
*/
Builder setShouldForce(boolean shouldForce);
@@ -140,6 +141,7 @@ interface Builder {
* before downloading.
*
* @param hash the SHA-1 hash of the resource-pack
+ * @return this builder instance
*/
Builder setHash(@Nullable byte[] hash);
@@ -148,6 +150,7 @@ interface Builder {
* This will only display if the client version is 1.17 or newer.
*
* @param prompt the component to display
+ * @return this builder instance
*/
Builder setPrompt(@Nullable Component prompt);
@@ -174,4 +177,4 @@ enum Origin {
*/
PLUGIN_ON_PROXY
}
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/player/SkinParts.java b/api/src/main/java/com/velocitypowered/api/proxy/player/SkinParts.java
index 1a5030feb6..893553417a 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/player/SkinParts.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/player/SkinParts.java
@@ -17,34 +17,74 @@ public final class SkinParts {
private final byte bitmask;
+ /**
+ * Constructs a new SkinParts object with the provided bitmask.
+ *
+ * @param skinBitmask the bitmask representing which skin parts are enabled
+ */
public SkinParts(byte skinBitmask) {
this.bitmask = skinBitmask;
}
+ /**
+ * Returns whether the player has a cape enabled.
+ *
+ * @return true if the cape is enabled, false otherwise
+ */
public boolean hasCape() {
return (bitmask & 1) == 1;
}
+ /**
+ * Returns whether the player has a jacket enabled.
+ *
+ * @return true if the jacket is enabled, false otherwise
+ */
public boolean hasJacket() {
return ((bitmask >> 1) & 1) == 1;
}
+ /**
+ * Returns whether the player has a left sleeve enabled.
+ *
+ * @return true if the left sleeve is enabled, false otherwise
+ */
public boolean hasLeftSleeve() {
return ((bitmask >> 2) & 1) == 1;
}
+ /**
+ * Returns whether the player has a right sleeve enabled.
+ *
+ * @return true if the right sleeve is enabled, false otherwise
+ */
public boolean hasRightSleeve() {
return ((bitmask >> 3) & 1) == 1;
}
+ /**
+ * Returns whether the player has their left pants enabled.
+ *
+ * @return true if the left pants are enabled, false otherwise
+ */
public boolean hasLeftPants() {
return ((bitmask >> 4) & 1) == 1;
}
+ /**
+ * Returns whether the player has their right pants enabled.
+ *
+ * @return true if the right pants are enabled, false otherwise
+ */
public boolean hasRightPants() {
return ((bitmask >> 5) & 1) == 1;
}
+ /**
+ * Returns whether the player has a hat enabled.
+ *
+ * @return true if the hat is enabled, false otherwise
+ */
public boolean hasHat() {
return ((bitmask >> 6) & 1) == 1;
}
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/player/TabListEntry.java b/api/src/main/java/com/velocitypowered/api/proxy/player/TabListEntry.java
index aea45287fc..57a42392d3 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/player/TabListEntry.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/player/TabListEntry.java
@@ -237,8 +237,11 @@ public Builder profile(GameProfile profile) {
/**
* Sets the {@link IdentifiedKey} of the {@link TabListEntry}.
+ *
* This only works for players currently not connected to this proxy.
+ *
* For any player currently connected to this proxy this will be filled automatically.
+ *
* Will ignore mismatching key revisions data.
*
* @param chatSession session to set
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/server/QueryResponse.java b/api/src/main/java/com/velocitypowered/api/proxy/server/QueryResponse.java
index 6c794bf4c4..c51765f805 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/server/QueryResponse.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/server/QueryResponse.java
@@ -147,7 +147,6 @@ public Collection getPlugins() {
return plugins;
}
-
/**
* Creates a new {@link Builder} instance from data represented by this response, so that you
* may create a new {@link QueryResponse} with new data. It is guaranteed that
@@ -434,14 +433,31 @@ public static final class PluginInformation {
this.version = version;
}
+ /**
+ * Gets the name of the plugin.
+ *
+ * @return the plugin name
+ */
public String getName() {
return name;
}
+ /**
+ * Gets the version of the plugin, if available.
+ *
+ * @return an {@link Optional} containing the version if present
+ */
public Optional getVersion() {
return Optional.ofNullable(version);
}
+ /**
+ * Creates a new {@link PluginInformation} instance with the given name and version.
+ *
+ * @param name the name of the plugin
+ * @param version the version of the plugin (nullable)
+ * @return a new {@link PluginInformation} instance
+ */
public static PluginInformation of(String name, @Nullable String version) {
return new PluginInformation(name, version);
}
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/server/ServerInfo.java b/api/src/main/java/com/velocitypowered/api/proxy/server/ServerInfo.java
index fd686297ee..9546a66200 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/server/ServerInfo.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/server/ServerInfo.java
@@ -32,11 +32,21 @@ public ServerInfo(String name, InetSocketAddress address) {
this.address = Preconditions.checkNotNull(address, "address");
}
- public final String getName() {
+ /**
+ * Gets the name of the server.
+ *
+ * @return the name of the server
+ */
+ public String getName() {
return name;
}
- public final InetSocketAddress getAddress() {
+ /**
+ * Gets the network address of the server.
+ *
+ * @return the {@link InetSocketAddress} of the server
+ */
+ public InetSocketAddress getAddress() {
return address;
}
@@ -49,7 +59,7 @@ public String toString() {
}
@Override
- public final boolean equals(@Nullable Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
}
@@ -62,7 +72,7 @@ public final boolean equals(@Nullable Object o) {
}
@Override
- public final int hashCode() {
+ public int hashCode() {
return Objects.hash(name, address);
}
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/server/ServerPing.java b/api/src/main/java/com/velocitypowered/api/proxy/server/ServerPing.java
index eb86f93ea1..4743d05e98 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/server/ServerPing.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/server/ServerPing.java
@@ -22,7 +22,6 @@
import net.kyori.adventure.text.Component;
import org.jspecify.annotations.Nullable;
-
/**
* Represents a 1.7 and above server list ping response. This class is immutable.
*/
@@ -34,6 +33,14 @@ public final class ServerPing {
private final @Nullable Favicon favicon;
private final @Nullable ModInfo modinfo;
+ /**
+ * Constructs an initial ServerPing instance.
+ *
+ * @param version the version of the server
+ * @param players the players on the server, or {@code null} if not shown
+ * @param description the MOTD for the server
+ * @param favicon the server's favicon, or {@code null} if not set
+ */
public ServerPing(Version version, @Nullable Players players,
net.kyori.adventure.text.Component description, @Nullable Favicon favicon) {
this(version, players, description, favicon, ModInfo.DEFAULT);
@@ -58,23 +65,48 @@ public ServerPing(Version version, @Nullable Players players,
this.modinfo = modinfo;
}
+ /**
+ * Gets the version shown to the client during the ping.
+ *
+ * @return the version
+ */
public Version getVersion() {
return version;
}
+ /**
+ * Gets the player information shown to the client.
+ *
+ * @return the player information, or empty if not shown
+ */
public Optional getPlayers() {
return Optional.ofNullable(players);
}
+ /**
+ * Gets the description (MOTD) component shown in the ping response.
+ *
+ * @return the description component
+ */
@Nullable
public Component getDescriptionComponent() {
return description;
}
+ /**
+ * Gets the favicon sent to the client.
+ *
+ * @return the favicon, or empty if not present
+ */
public Optional getFavicon() {
return Optional.ofNullable(favicon);
}
+ /**
+ * Gets the mod info sent to the client.
+ *
+ * @return the mod info, or empty if not present
+ */
public Optional getModinfo() {
return Optional.ofNullable(modinfo);
}
@@ -139,6 +171,11 @@ public Builder asBuilder() {
return builder;
}
+ /**
+ * Creates a new {@link Builder} for constructing a {@link ServerPing}.
+ *
+ * @return a new ServerPing builder
+ */
public static Builder builder() {
return new Builder();
}
@@ -346,34 +383,74 @@ public ServerPing build() {
description, favicon, nullOutModinfo ? null : new ModInfo(modType, mods));
}
+ /**
+ * Gets the version currently set in the builder.
+ *
+ * @return the version
+ */
public Version getVersion() {
return version;
}
+ /**
+ * Gets the number of players online.
+ *
+ * @return the online player count
+ */
public int getOnlinePlayers() {
return onlinePlayers;
}
+ /**
+ * Gets the maximum player capacity.
+ *
+ * @return the max player count
+ */
public int getMaximumPlayers() {
return maximumPlayers;
}
+ /**
+ * Gets the sample players shown in the ping.
+ *
+ * @return the sample player list
+ */
public List getSamplePlayers() {
return samplePlayers;
}
+ /**
+ * Gets the description component currently set in the builder.
+ *
+ * @return the server description, or empty if unset
+ */
public Optional getDescriptionComponent() {
return Optional.ofNullable(description);
}
+ /**
+ * Gets the favicon currently set in the builder.
+ *
+ * @return the favicon, or empty if none
+ */
public Optional getFavicon() {
return Optional.ofNullable(favicon);
}
+ /**
+ * Gets the type of mod loader (e.g., "FML").
+ *
+ * @return the mod type string
+ */
public String getModType() {
return modType;
}
+ /**
+ * Gets the list of mods reported in the ping.
+ *
+ * @return the mod list
+ */
public List getMods() {
return mods;
}
@@ -417,10 +494,20 @@ public Version(int protocol, String name) {
this.name = Preconditions.checkNotNull(name, "name");
}
+ /**
+ * Gets the protocol number associated with the server version.
+ *
+ * @return the protocol version number
+ */
public int getProtocol() {
return protocol;
}
+ /**
+ * Gets the legacy string name of the sample player.
+ *
+ * @return the player name
+ */
public String getName() {
return name;
}
@@ -474,14 +561,29 @@ public Players(int online, int max, List sample) {
this.sample = ImmutableList.copyOf(sample);
}
+ /**
+ * Gets the number of online players.
+ *
+ * @return the number of online players
+ */
public int getOnline() {
return online;
}
+ /**
+ * Gets the maximum number of players the server claims it can hold.
+ *
+ * @return the maximum number of players
+ */
public int getMax() {
return max;
}
+ /**
+ * Gets a sample list of online players.
+ *
+ * @return the sample players
+ */
public List getSample() {
return sample == null ? ImmutableList.of() : sample;
}
@@ -519,22 +621,47 @@ public int hashCode() {
*/
public static final class SamplePlayer {
+ /**
+ * A constant representing an anonymous sample player with a null UUID and generic name.
+ */
public static final SamplePlayer ANONYMOUS = new SamplePlayer(
"Anonymous Player",
new UUID(0L, 0L)
);
+ /**
+ * The legacy string name of the player.
+ */
private final String name;
+ /**
+ * The unique identifier (UUID) of the player.
+ */
private final UUID id;
+ /**
+ * Constructs a SamplePlayer from a {@link Component}-based name.
+ *
+ * @param name the name of the player as a {@link Component}
+ * @param id the UUID of the player
+ */
public SamplePlayer(String name, UUID id) {
this.name = name;
this.id = id;
}
+ /**
+ * Gets the legacy string name of the sample player.
+ *
+ * @return the player name
+ */
public String getName() {
return name;
}
+ /**
+ * Gets the UUID of the sample player.
+ *
+ * @return the player UUID
+ */
public UUID getId() {
return id;
}
diff --git a/api/src/main/java/com/velocitypowered/api/util/GameProfile.java b/api/src/main/java/com/velocitypowered/api/util/GameProfile.java
index 27c4213802..e918c8e9e5 100644
--- a/api/src/main/java/com/velocitypowered/api/util/GameProfile.java
+++ b/api/src/main/java/com/velocitypowered/api/util/GameProfile.java
@@ -200,14 +200,29 @@ public Property(String name, String value, String signature) {
this.signature = Preconditions.checkNotNull(signature, "signature");
}
+ /**
+ * Returns the name of this property.
+ *
+ * @return the property name
+ */
public String getName() {
return name;
}
+ /**
+ * Returns the value of this property.
+ *
+ * @return the property value
+ */
public String getValue() {
return value;
}
+ /**
+ * Returns the Mojang-provided signature for this property.
+ *
+ * @return the property signature
+ */
public String getSignature() {
return signature;
}
diff --git a/api/src/main/java/com/velocitypowered/api/util/ModInfo.java b/api/src/main/java/com/velocitypowered/api/util/ModInfo.java
index cfc522891a..d5e252fa44 100644
--- a/api/src/main/java/com/velocitypowered/api/util/ModInfo.java
+++ b/api/src/main/java/com/velocitypowered/api/util/ModInfo.java
@@ -18,6 +18,10 @@
*/
public final class ModInfo {
+ /**
+ * The default mod info used when no mods are present.
+ * Typically used for Forge-compatible connections that require a placeholder.
+ */
public static final ModInfo DEFAULT = new ModInfo("FML", ImmutableList.of());
private final String type;
@@ -34,10 +38,20 @@ public ModInfo(String type, List modList) {
this.modList = ImmutableList.copyOf(modList);
}
+ /**
+ * Returns the Forge mod list type (e.g., "FML").
+ *
+ * @return the mod list type
+ */
public String getType() {
return type;
}
+ /**
+ * Returns an immutable list of all mods in this mod list.
+ *
+ * @return the list of mods
+ */
public List getMods() {
return modList;
}
@@ -89,10 +103,20 @@ public Mod(String id, String version) {
Preconditions.checkArgument(version.length() < 128, "mod version is too long");
}
+ /**
+ * Returns the mod ID (identifier string).
+ *
+ * @return the mod ID
+ */
public String getId() {
return id;
}
+ /**
+ * Returns the mod version string.
+ *
+ * @return the mod version
+ */
public String getVersion() {
return version;
}
diff --git a/api/src/main/java/com/velocitypowered/api/util/ProxyVersion.java b/api/src/main/java/com/velocitypowered/api/util/ProxyVersion.java
index abc3a14aad..303fbd0f85 100644
--- a/api/src/main/java/com/velocitypowered/api/util/ProxyVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/util/ProxyVersion.java
@@ -33,14 +33,29 @@ public ProxyVersion(String name, String vendor, String version) {
this.version = Preconditions.checkNotNull(version, "version");
}
+ /**
+ * Gets the name of the proxy implementation.
+ *
+ * @return the name of the proxy
+ */
public String getName() {
return name;
}
+ /**
+ * Gets the vendor of the proxy implementation.
+ *
+ * @return the vendor of the proxy
+ */
public String getVendor() {
return vendor;
}
+ /**
+ * Gets the version of the proxy implementation.
+ *
+ * @return the version of the proxy
+ */
public String getVersion() {
return version;
}
diff --git a/api/src/main/java/com/velocitypowered/api/util/ServerLink.java b/api/src/main/java/com/velocitypowered/api/util/ServerLink.java
index 9eb04a9801..484833fe81 100644
--- a/api/src/main/java/com/velocitypowered/api/util/ServerLink.java
+++ b/api/src/main/java/com/velocitypowered/api/util/ServerLink.java
@@ -38,6 +38,7 @@ private ServerLink(Type type, String url) {
*
* @param label a custom component label to display
* @param link the URL to open when clicked
+ * @return a {@link ServerLink} instance with the given label and URL
*/
public static ServerLink serverLink(Component label, String link) {
return new ServerLink(label, link);
@@ -48,6 +49,7 @@ public static ServerLink serverLink(Component label, String link) {
*
* @param type the {@link Type built-in type} of link
* @param link the URL to open when clicked
+ * @return a {@link ServerLink} instance with the given type and URL
*/
public static ServerLink serverLink(Type type, String link) {
return new ServerLink(type, link);
@@ -86,15 +88,45 @@ public URI getUrl() {
* @apiNote {@link Type#BUG_REPORT} links are shown on the connection error screen
*/
public enum Type {
+ /**
+ * A link to report bugs related to the server or gameplay.
+ */
BUG_REPORT,
+ /**
+ * A link to the server's community guidelines or rules.
+ */
COMMUNITY_GUIDELINES,
+ /**
+ * A link to the server’s support or help desk.
+ */
SUPPORT,
+ /**
+ * A link showing the current server or service status.
+ */
STATUS,
+ /**
+ * A link to provide feedback to the server staff or developers.
+ */
FEEDBACK,
+ /**
+ * A link to the server’s community hub or Discord.
+ */
COMMUNITY,
+ /**
+ * A link to the server's main website.
+ */
WEBSITE,
+ /**
+ * A link to the server's forums.
+ */
FORUMS,
+ /**
+ * A link to server or game-related news.
+ */
NEWS,
+ /**
+ * A link to announcements from the server team.
+ */
ANNOUNCEMENTS
}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 7be8d4698e..b8a22e770b 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -3,7 +3,7 @@ configurate3 = "3.7.3"
configurate4 = "4.2.0"
flare = "2.0.1"
log4j = "2.25.3"
-netty = "4.2.7.Final"
+netty = "4.2.9.Final"
[plugins]
fill = "io.papermc.fill.gradle:1.0.10"
@@ -21,7 +21,7 @@ brigadier = "com.velocitypowered:velocity-brigadier:1.0.0-SNAPSHOT"
bstats = "org.bstats:bstats-base:3.1.0"
caffeine = "com.github.ben-manes.caffeine:caffeine:3.2.3"
checker-qual = "org.checkerframework:checker-qual:3.53.0"
-checkstyle = "com.puppycrawl.tools:checkstyle:10.9.3"
+checkstyle = "com.puppycrawl.tools:checkstyle:13.0.0"
completablefutures = "com.spotify:completable-futures:0.3.6"
configurate3-hocon = { module = "org.spongepowered:configurate-hocon", version.ref = "configurate3" }
configurate3-yaml = { module = "org.spongepowered:configurate-yaml", version.ref = "configurate3" }
@@ -30,12 +30,12 @@ configurate4-hocon = { module = "org.spongepowered:configurate-hocon", version.r
configurate4-yaml = { module = "org.spongepowered:configurate-yaml", version.ref = "configurate4" }
configurate4-gson = { module = "org.spongepowered:configurate-gson", version.ref = "configurate4" }
disruptor = "com.lmax:disruptor:4.0.0"
-fastutil = "it.unimi.dsi:fastutil:8.5.15"
+fastutil = "it.unimi.dsi:fastutil:8.5.18"
flare-core = { module = "space.vectrix.flare:flare", version.ref = "flare" }
flare-fastutil = { module = "space.vectrix.flare:flare-fastutil", version.ref = "flare" }
jline = "org.jline:jline-terminal-jansi:3.30.6"
jopt = "net.sf.jopt-simple:jopt-simple:5.0.4"
-junit = "org.junit.jupiter:junit-jupiter:5.14.2"
+junit = "org.junit.jupiter:junit-jupiter:6.0.2"
jspecify = "org.jspecify:jspecify:1.0.0"
kyori-ansi = "net.kyori:ansi:1.1.1"
guava = "com.google.guava:guava:33.5.0-jre"
diff --git a/native/src/main/java/com/velocitypowered/natives/util/MoreByteBufUtils.java b/native/src/main/java/com/velocitypowered/natives/util/MoreByteBufUtils.java
index 13f4f0c570..886f20818b 100644
--- a/native/src/main/java/com/velocitypowered/natives/util/MoreByteBufUtils.java
+++ b/native/src/main/java/com/velocitypowered/natives/util/MoreByteBufUtils.java
@@ -54,8 +54,8 @@ private static boolean isCompatible(Native nativeStuff, ByteBuf buf) {
BufferPreference preferred = nativeStuff.preferredBufferType();
return switch (preferred) {
case DIRECT_PREFERRED, HEAP_PREFERRED ->
- // The native prefers this type, but doesn't strictly require we provide it.
- true;
+ // The native prefers this type, but doesn't strictly require we provide it.
+ true;
case DIRECT_REQUIRED -> buf.hasMemoryAddress();
case HEAP_REQUIRED -> buf.hasArray();
};
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java
index 95f10bcbb0..f44cb99e60 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java
@@ -650,7 +650,7 @@ public void shutdown(boolean explicitExit, Component reason) {
}
/**
- * Calls {@link #shutdown(boolean, Component)} with the default reason "Proxy shutting down."
+ * Calls {@link #shutdown(boolean, Component)} with the default reason "Proxy shutting down.".
*
* @param explicitExit whether the user explicitly shut down the proxy
*/
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/handler/ModernResourcePackHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/handler/ModernResourcePackHandler.java
index f0fd5e084c..3bef8a4ba2 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/handler/ModernResourcePackHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/handler/ModernResourcePackHandler.java
@@ -37,7 +37,7 @@
import org.jetbrains.annotations.Nullable;
/**
- * Modern (Minecraft 1.20.3+) ResourcePackHandler
+ * Modern (Minecraft 1.20.3+) ResourcePackHandler.
*/
public final class ModernResourcePackHandler extends ResourcePackHandler {
private final ListMultimap outstandingResourcePacks =
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/handler/ResourcePackHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/handler/ResourcePackHandler.java
index b384388534..dc04b912c2 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/handler/ResourcePackHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/handler/ResourcePackHandler.java
@@ -118,6 +118,7 @@ protected void sendResourcePackRequestPacket(final @NotNull ResourcePackInfo que
/**
* Processes a client response to a sent resource-pack.
+ *
* Cases in which no action will be taken:
*
*
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/event/VelocityEventManager.java b/proxy/src/main/java/com/velocitypowered/proxy/event/VelocityEventManager.java
index 9d54b2d073..7037ee2ae2 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/event/VelocityEventManager.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/event/VelocityEventManager.java
@@ -545,6 +545,36 @@ private void fire(final @Nullable CompletableFuture future,
}
}
+ private void fire(final @Nullable CompletableFuture future, final E event,
+ final int offset, final boolean currentlyAsync, final HandlerRegistration[] registrations) {
+ for (int i = offset; i < registrations.length; i++) {
+ final HandlerRegistration registration = registrations[i];
+ try {
+ final EventTask eventTask = registration.handler.executeAsync(event);
+ if (eventTask == null) {
+ continue;
+ }
+ final ContinuationTask continuationTask = new ContinuationTask<>(eventTask,
+ registrations, future, event, i, currentlyAsync);
+ if (currentlyAsync || !eventTask.requiresAsync()) {
+ if (continuationTask.execute()) {
+ continue;
+ }
+ } else {
+ registration.plugin.getExecutorService().execute(continuationTask);
+ }
+ // fire will continue in another thread once the async task is
+ // executed and the continuation is resumed
+ return;
+ } catch (final Throwable t) {
+ logHandlerException(registration, t);
+ }
+ }
+ if (future != null) {
+ future.complete(event);
+ }
+ }
+
private static final int TASK_STATE_DEFAULT = 0;
private static final int TASK_STATE_EXECUTING = 1;
private static final int TASK_STATE_CONTINUE_IMMEDIATELY = 2;
@@ -669,40 +699,10 @@ public void resumeWithException(final Throwable exception) {
}
}
- private void fire(final @Nullable CompletableFuture future, final E event,
- final int offset, final boolean currentlyAsync, final HandlerRegistration[] registrations) {
- for (int i = offset; i < registrations.length; i++) {
- final HandlerRegistration registration = registrations[i];
- try {
- final EventTask eventTask = registration.handler.executeAsync(event);
- if (eventTask == null) {
- continue;
- }
- final ContinuationTask continuationTask = new ContinuationTask<>(eventTask,
- registrations, future, event, i, currentlyAsync);
- if (currentlyAsync || !eventTask.requiresAsync()) {
- if (continuationTask.execute()) {
- continue;
- }
- } else {
- registration.plugin.getExecutorService().execute(continuationTask);
- }
- // fire will continue in another thread once the async task is
- // executed and the continuation is resumed
- return;
- } catch (final Throwable t) {
- logHandlerException(registration, t);
- }
- }
- if (future != null) {
- future.complete(event);
- }
- }
-
private static void logHandlerException(
final HandlerRegistration registration, final Throwable t) {
final PluginDescription pluginDescription = registration.plugin.getDescription();
logger.error("Couldn't pass {} to {} {}", registration.eventType.getSimpleName(),
pluginDescription.getId(), pluginDescription.getVersion().orElse(""), t);
}
-}
\ No newline at end of file
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java
index efc0ed177b..093256d0c0 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java
@@ -633,7 +633,7 @@ public static List readProperties(ByteBuf buf) {
private static final int FORGE_MAX_ARRAY_LENGTH = Integer.MAX_VALUE & 0x1FFF9A;
/**
- * Reads an byte array for legacy version 1.7 from the specified {@code buf}
+ * Reads an byte array for legacy version 1.7 from the specified {@code buf}.
*
* @param buf the buffer to read from
* @return the read byte array
@@ -671,7 +671,7 @@ public static ByteBuf readRetainedByteBufSlice17(ByteBuf buf) {
}
/**
- * Writes an byte array for legacy version 1.7 to the specified {@code buf}
+ * Writes an byte array for legacy version 1.7 to the specified {@code buf}.
*
* @param b array
* @param buf buf
@@ -695,7 +695,7 @@ public static void writeByteArray17(byte[] b, ByteBuf buf, boolean allowExtended
}
/**
- * Writes an {@link ByteBuf} for legacy version 1.7 to the specified {@code buf}
+ * Writes an {@link ByteBuf} for legacy version 1.7 to the specified {@code buf}.
*
* @param b array
* @param buf buf
diff --git a/proxy/src/main/resources/default-velocity.toml b/proxy/src/main/resources/default-velocity.toml
index 4d71e589b9..28de529782 100644
--- a/proxy/src/main/resources/default-velocity.toml
+++ b/proxy/src/main/resources/default-velocity.toml
@@ -42,7 +42,7 @@ forwarding-secret-file = "forwarding.secret"
# Announce whether or not your server supports Forge. If you run a modded server, we
# suggest turning this on.
-#
+#
# If your network runs one modpack consistently, consider using ping-passthrough = "mods"
# instead for a nicer display in the server list.
announce-forge = false
From 8050fdf09e4145cfbf6fc017045cd429d3fd8163 Mon Sep 17 00:00:00 2001
From: RootBeer
Date: Mon, 26 Jan 2026 04:33:54 -0500
Subject: [PATCH 2/7] Make all packet-oriented classes require checkstyle for
synchronization of maintenance
---
proxy/build.gradle.kts | 17 ++-
.../packet/AvailableCommandsPacket.java | 7 +
.../proxy/protocol/packet/BossBarPacket.java | 88 +++++++++---
.../packet/BundleDelimiterPacket.java | 8 ++
.../protocol/packet/ClientSettingsPacket.java | 33 ++++-
.../ClientboundCookieRequestPacket.java | 5 +
.../packet/ClientboundSoundEntityPacket.java | 32 +++--
.../packet/ClientboundStopSoundPacket.java | 12 +-
.../packet/ClientboundStoreCookiePacket.java | 5 +
.../protocol/packet/DialogClearPacket.java | 7 +
.../protocol/packet/DialogShowPacket.java | 7 +
.../protocol/packet/DisconnectPacket.java | 26 +++-
.../packet/EncryptionRequestPacket.java | 6 +
.../packet/EncryptionResponsePacket.java | 19 ++-
.../protocol/packet/HandshakePacket.java | 10 +-
.../packet/HeaderAndFooterPacket.java | 8 +-
.../proxy/protocol/packet/JoinGamePacket.java | 30 ++--
.../protocol/packet/KeepAlivePacket.java | 5 +
.../protocol/packet/LegacyDisconnect.java | 20 ++-
.../packet/LegacyHandshakePacket.java | 5 +
.../protocol/packet/LegacyPingPacket.java | 5 +
.../packet/LegacyPlayerListItemPacket.java | 48 +++++--
.../packet/LoginAcknowledgedPacket.java | 9 +-
.../packet/LoginPluginMessagePacket.java | 17 +++
.../packet/LoginPluginResponsePacket.java | 11 ++
.../protocol/packet/PingIdentifyPacket.java | 3 +
.../protocol/packet/PluginMessagePacket.java | 12 +-
.../packet/RemovePlayerInfoPacket.java | 4 +
.../packet/RemoveResourcePackPacket.java | 6 +-
.../packet/ResourcePackRequestPacket.java | 26 ++--
.../packet/ResourcePackResponsePacket.java | 32 +++--
.../proxy/protocol/packet/RespawnPacket.java | 26 ++++
.../protocol/packet/ServerDataPacket.java | 15 +-
.../protocol/packet/ServerLoginPacket.java | 31 ++++-
.../packet/ServerLoginSuccessPacket.java | 16 +++
.../ServerboundCookieResponsePacket.java | 5 +
.../ServerboundCustomClickActionPacket.java | 6 +
.../protocol/packet/SetCompressionPacket.java | 4 +
.../protocol/packet/StatusPingPacket.java | 4 +
.../protocol/packet/StatusRequestPacket.java | 4 +-
.../protocol/packet/StatusResponsePacket.java | 9 ++
.../packet/TabCompleteRequestPacket.java | 9 ++
.../packet/TabCompleteResponsePacket.java | 6 +
.../proxy/protocol/packet/TransferPacket.java | 14 ++
.../packet/UpsertPlayerInfoPacket.java | 31 +++--
.../packet/brigadier/ArgumentIdentifier.java | 19 ++-
.../brigadier/ArgumentPropertyRegistry.java | 16 ++-
.../brigadier/ArgumentPropertySerializer.java | 10 ++
.../packet/brigadier/ModArgumentProperty.java | 11 ++
.../RegistryIdArgumentSerializer.java | 10 ++
.../packet/brigadier/RegistryKeyArgument.java | 9 ++
.../brigadier/RegistryKeyArgumentList.java | 29 ++++
.../RegistryKeyArgumentSerializer.java | 6 +
.../brigadier/TimeArgumentSerializer.java | 6 +
.../chat/ChatAcknowledgementPacket.java | 73 +++++-----
.../protocol/packet/chat/ChatHandler.java | 16 +++
.../proxy/protocol/packet/chat/ChatQueue.java | 45 +++++-
.../protocol/packet/chat/ChatTimeKeeper.java | 17 +++
.../proxy/protocol/packet/chat/ChatType.java | 8 +-
.../protocol/packet/chat/CommandHandler.java | 66 +++++++--
.../protocol/packet/chat/ComponentHolder.java | 131 ++++++++++++++----
.../packet/chat/LastSeenMessages.java | 34 ++++-
.../chat/PlayerChatCompletionPacket.java | 8 ++
.../chat/RateLimitedCommandHandler.java | 59 ++++----
.../packet/chat/RemoteChatSession.java | 5 +
.../packet/chat/SystemChatPacket.java | 7 +-
.../chat/builder/ChatBuilderFactory.java | 11 ++
.../packet/chat/builder/ChatBuilderV2.java | 7 +
.../packet/chat/keyed/KeyedChatBuilder.java | 6 +
.../packet/chat/keyed/KeyedChatHandler.java | 25 ++++
.../chat/keyed/KeyedCommandHandler.java | 16 ++-
.../chat/keyed/KeyedPlayerChatPacket.java | 7 +
.../chat/keyed/KeyedPlayerCommandPacket.java | 7 +
.../packet/chat/legacy/LegacyChatBuilder.java | 7 +
.../packet/chat/legacy/LegacyChatHandler.java | 7 +
.../packet/chat/legacy/LegacyChatPacket.java | 7 +
.../chat/legacy/LegacyCommandHandler.java | 17 ++-
.../chat/session/SessionChatBuilder.java | 7 +
.../chat/session/SessionChatHandler.java | 10 +-
.../chat/session/SessionCommandHandler.java | 16 ++-
.../chat/session/SessionPlayerChatPacket.java | 16 +++
.../session/SessionPlayerCommandPacket.java | 90 +++++++++---
.../session/UnsignedPlayerCommandPacket.java | 13 +-
.../packet/config/ActiveFeaturesPacket.java | 7 +
.../ClientboundCustomReportDetailsPacket.java | 60 ++++----
.../config/ClientboundServerLinksPacket.java | 103 ++++++++------
.../config/CodeOfConductAcceptPacket.java | 6 +
.../packet/config/CodeOfConductPacket.java | 7 +
.../packet/config/FinishedUpdatePacket.java | 9 +-
.../packet/config/KnownPacksPacket.java | 93 ++++++++-----
.../packet/config/RegistrySyncPacket.java | 12 ++
.../packet/config/StartUpdatePacket.java | 12 +-
.../packet/config/TagsUpdatePacket.java | 10 +-
.../LegacyMinecraftPingVersion.java | 10 ++
.../packet/title/GenericTitlePacket.java | 20 ++-
.../packet/title/LegacyTitlePacket.java | 14 +-
.../packet/title/TitleActionbarPacket.java | 10 ++
.../packet/title/TitleClearPacket.java | 9 ++
.../packet/title/TitleSubtitlePacket.java | 9 ++
.../packet/title/TitleTextPacket.java | 9 ++
.../packet/title/TitleTimesPacket.java | 9 ++
101 files changed, 1578 insertions(+), 388 deletions(-)
diff --git a/proxy/build.gradle.kts b/proxy/build.gradle.kts
index 599baba1ce..5929692c5e 100644
--- a/proxy/build.gradle.kts
+++ b/proxy/build.gradle.kts
@@ -14,10 +14,6 @@ application {
}
tasks {
- withType {
- exclude("**/com/velocitypowered/proxy/protocol/packet/**")
- }
-
jar {
manifest {
attributes["Implementation-Title"] = "Velocity"
@@ -33,7 +29,7 @@ tasks {
transform(Log4j2PluginsCacheFileTransformer::class.java)
- // Exclude all the collection types we don"t intend to use
+ // Exclude all the collection types we don't intend to use
exclude("it/unimi/dsi/fastutil/booleans/**")
exclude("it/unimi/dsi/fastutil/bytes/**")
exclude("it/unimi/dsi/fastutil/chars/**")
@@ -42,7 +38,7 @@ tasks {
exclude("it/unimi/dsi/fastutil/longs/**")
exclude("it/unimi/dsi/fastutil/shorts/**")
- // Exclude the fastutil IO utilities - we don"t use them.
+ // Exclude the fastutil IO utilities - we don't use them.
exclude("it/unimi/dsi/fastutil/io/**")
// Exclude most of the int types - Object2IntMap have a values() method that returns an
@@ -112,6 +108,15 @@ tasks {
workingDir = file("run").also(File::mkdirs)
standardInput = System.`in` // Doesn't work?
}
+
+ withType().configureEach {
+ options.compilerArgs.addAll(
+ listOf(
+ "-Alog4j.graalvm.groupId=${project.group}",
+ "-Alog4j.graalvm.artifactId=${project.name}"
+ )
+ )
+ }
}
val projectVersion = version as String
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/AvailableCommandsPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/AvailableCommandsPacket.java
index 2746b23f4e..23cebf6103 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/AvailableCommandsPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/AvailableCommandsPacket.java
@@ -53,6 +53,13 @@
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a packet that contains the list of available commands, implementing {@link MinecraftPacket}.
+ *
+ * The {@code AvailableCommandsPacket} is responsible for transmitting the set of commands
+ * that a player can execute. It provides the necessary information about available commands
+ * within the current session or game state.
+ */
public class AvailableCommandsPacket implements MinecraftPacket {
private static final Command PLACEHOLDER_COMMAND = source -> 0;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/BossBarPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/BossBarPacket.java
index d7748efffe..06cbd8619e 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/BossBarPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/BossBarPacket.java
@@ -29,6 +29,10 @@
import net.kyori.adventure.bossbar.BossBar;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a packet used to manage boss bars.
+ * This packet can add, remove, or update a boss bar.
+ */
public class BossBarPacket implements MinecraftPacket {
private static final Enum2IntMap COLORS_TO_PROTOCOL =
@@ -70,6 +74,14 @@ public class BossBarPacket implements MinecraftPacket {
private int overlay;
private short flags;
+ /**
+ * Creates a packet to add a new boss bar.
+ *
+ * @param id the UUID of the boss bar
+ * @param bar the {@link BossBar} instance
+ * @param name the {@link ComponentHolder} containing the boss bar's name
+ * @return a {@link BossBarPacket} to add a boss bar
+ */
public static BossBarPacket createAddPacket(
final UUID id,
final BossBar bar,
@@ -86,6 +98,13 @@ public static BossBarPacket createAddPacket(
return packet;
}
+ /**
+ * Creates a packet to remove an existing boss bar.
+ *
+ * @param id the UUID of the boss bar to remove
+ * @param bar the {@link BossBar} instance
+ * @return a {@link BossBarPacket} to remove a boss bar
+ */
public static BossBarPacket createRemovePacket(final UUID id, final BossBar bar) {
final BossBarPacket packet = new BossBarPacket();
packet.setUuid(id);
@@ -93,6 +112,13 @@ public static BossBarPacket createRemovePacket(final UUID id, final BossBar bar)
return packet;
}
+ /**
+ * Creates a packet to update the progress (percentage) of the boss bar.
+ *
+ * @param id the UUID of the boss bar
+ * @param bar the {@link BossBar} instance
+ * @return a {@link BossBarPacket} to update the boss bar's progress
+ */
public static BossBarPacket createUpdateProgressPacket(final UUID id, final BossBar bar) {
final BossBarPacket packet = new BossBarPacket();
packet.setUuid(id);
@@ -101,6 +127,14 @@ public static BossBarPacket createUpdateProgressPacket(final UUID id, final Boss
return packet;
}
+ /**
+ * Creates a packet to update the name of the boss bar.
+ *
+ * @param id the UUID of the boss bar
+ * @param bar the {@link BossBar} instance
+ * @param name the {@link ComponentHolder} containing the boss bar's new name
+ * @return a {@link BossBarPacket} to update the boss bar's name
+ */
public static BossBarPacket createUpdateNamePacket(
final UUID id,
final BossBar bar,
@@ -113,6 +147,13 @@ public static BossBarPacket createUpdateNamePacket(
return packet;
}
+ /**
+ * Creates a packet to update the style (color and overlay) of the boss bar.
+ *
+ * @param id the UUID of the boss bar
+ * @param bar the {@link BossBar} instance
+ * @return a {@link BossBarPacket} to update the boss bar's style
+ */
public static BossBarPacket createUpdateStylePacket(final UUID id, final BossBar bar) {
final BossBarPacket packet = new BossBarPacket();
packet.setUuid(id);
@@ -122,6 +163,13 @@ public static BossBarPacket createUpdateStylePacket(final UUID id, final BossBar
return packet;
}
+ /**
+ * Creates a packet to update the properties of the boss bar.
+ *
+ * @param id the UUID of the boss bar
+ * @param bar the {@link BossBar} instance
+ * @return a {@link BossBarPacket} to update the boss bar's properties
+ */
public static BossBarPacket createUpdatePropertiesPacket(final UUID id, final BossBar bar) {
final BossBarPacket packet = new BossBarPacket();
packet.setUuid(id);
@@ -130,6 +178,12 @@ public static BossBarPacket createUpdatePropertiesPacket(final UUID id, final Bo
return packet;
}
+ /**
+ * Retrieves the UUID of the boss bar.
+ *
+ * @return the UUID of the boss bar
+ * @throws IllegalStateException if the UUID has not been set
+ */
public UUID getUuid() {
if (uuid == null) {
throw new IllegalStateException("No boss bar UUID specified");
@@ -214,7 +268,8 @@ public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi
this.overlay = ProtocolUtils.readVarInt(buf);
this.flags = buf.readUnsignedByte();
}
- case REMOVE -> {}
+ case REMOVE -> {
+ }
case UPDATE_PERCENT -> this.percent = buf.readFloat();
case UPDATE_NAME -> this.name = ComponentHolder.read(buf, version);
case UPDATE_STYLE -> {
@@ -235,22 +290,23 @@ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi
ProtocolUtils.writeVarInt(buf, action);
switch (action) {
case ADD -> {
- if (name == null) {
- throw new IllegalStateException("No name specified!");
- }
- name.write(buf);
- buf.writeFloat(percent);
- ProtocolUtils.writeVarInt(buf, color);
- ProtocolUtils.writeVarInt(buf, overlay);
- buf.writeByte(flags);
+ if (name == null) {
+ throw new IllegalStateException("No name specified!");
+ }
+ name.write(buf);
+ buf.writeFloat(percent);
+ ProtocolUtils.writeVarInt(buf, color);
+ ProtocolUtils.writeVarInt(buf, overlay);
+ buf.writeByte(flags);
+ }
+ case REMOVE -> {
}
- case REMOVE -> {}
case UPDATE_PERCENT -> buf.writeFloat(percent);
case UPDATE_NAME -> {
- if (name == null) {
- throw new IllegalStateException("No name specified!");
- }
- name.write(buf);
+ if (name == null) {
+ throw new IllegalStateException("No name specified!");
+ }
+ name.write(buf);
}
case UPDATE_STYLE -> {
ProtocolUtils.writeVarInt(buf, color);
@@ -264,7 +320,7 @@ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi
private static byte serializeFlags(Set flags) {
byte val = 0x0;
for (BossBar.Flag flag : flags) {
- val |= FLAG_BITS_TO_PROTOCOL.get(flag);
+ val |= (byte) FLAG_BITS_TO_PROTOCOL.get(flag);
}
return val;
}
@@ -273,4 +329,4 @@ private static byte serializeFlags(Set flags) {
public boolean handle(MinecraftSessionHandler handler) {
return handler.handle(this);
}
-}
\ No newline at end of file
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/BundleDelimiterPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/BundleDelimiterPacket.java
index 4da691c763..5c6827f31a 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/BundleDelimiterPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/BundleDelimiterPacket.java
@@ -23,6 +23,14 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents a packet used as a delimiter for bundling multiple packets together.
+ * The {@code BundleDelimiterPacket} marks the beginning or end of a packet bundle,
+ * allowing the server and client to process groups of packets as a single logical unit.
+ *
+ * This packet is typically used to signal the start or end of a packet sequence that
+ * are sent together, enabling efficient transmission and processing of related data.
+ */
public final class BundleDelimiterPacket implements MinecraftPacket {
public static final BundleDelimiterPacket INSTANCE = new BundleDelimiterPacket();
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientSettingsPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientSettingsPacket.java
index 39e6fde02c..743fb2bac9 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientSettingsPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientSettingsPacket.java
@@ -23,9 +23,13 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
import java.util.Objects;
-
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents the client settings packet in Minecraft, which is sent by the client
+ * to the server to communicate its settings such as locale, view distance, chat preferences,
+ * skin customization, and other client-side configurations.
+ */
public class ClientSettingsPacket implements MinecraftPacket {
private @Nullable String locale;
private byte viewDistance;
@@ -41,6 +45,19 @@ public class ClientSettingsPacket implements MinecraftPacket {
public ClientSettingsPacket() {
}
+ /**
+ * Constructs a new {@code ClientSettingsPacket} with the specified settings.
+ *
+ * @param locale the client's locale setting
+ * @param viewDistance the view distance
+ * @param chatVisibility the client's chat visibility setting
+ * @param chatColors whether chat colors are enabled
+ * @param skinParts the customization for skin parts
+ * @param mainHand the client's main hand preference
+ * @param textFilteringEnabled whether text filtering is enabled
+ * @param clientListingAllowed whether the client allows listing
+ * @param particleStatus whether particles are enabled
+ */
public ClientSettingsPacket(String locale, byte viewDistance, int chatVisibility, boolean chatColors,
short skinParts, int mainHand, boolean textFilteringEnabled, boolean clientListingAllowed,
int particleStatus) {
@@ -55,6 +72,12 @@ public ClientSettingsPacket(String locale, byte viewDistance, int chatVisibility
this.particleStatus = particleStatus;
}
+ /**
+ * Gets the client's locale.
+ *
+ * @return the locale
+ * @throws IllegalStateException if no locale is specified
+ */
public String getLocale() {
if (locale == null) {
throw new IllegalStateException("No locale specified");
@@ -132,10 +155,10 @@ public void setParticleStatus(int particleStatus) {
@Override
public String toString() {
- return "ClientSettings{" + "locale='" + locale + '\'' + ", viewDistance=" + viewDistance +
- ", chatVisibility=" + chatVisibility + ", chatColors=" + chatColors + ", skinParts=" +
- skinParts + ", mainHand=" + mainHand + ", chatFilteringEnabled=" + textFilteringEnabled +
- ", clientListingAllowed=" + clientListingAllowed + ", particleStatus=" + particleStatus + '}';
+ return "ClientSettings{" + "locale='" + locale + '\'' + ", viewDistance=" + viewDistance
+ + ", chatVisibility=" + chatVisibility + ", chatColors=" + chatColors + ", skinParts="
+ + skinParts + ", mainHand=" + mainHand + ", chatFilteringEnabled=" + textFilteringEnabled
+ + ", clientListingAllowed=" + clientListingAllowed + ", particleStatus=" + particleStatus + '}';
}
@Override
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundCookieRequestPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundCookieRequestPacket.java
index fd558b29ca..0e7c2a7a00 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundCookieRequestPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundCookieRequestPacket.java
@@ -25,6 +25,11 @@
import io.netty.buffer.ByteBuf;
import net.kyori.adventure.key.Key;
+/**
+ * Represents a packet sent from the server to the client to request cookies.
+ * This packet can be used to initiate a request for cookie-related data from the client,
+ * typically for authentication or tracking purposes.
+ */
public class ClientboundCookieRequestPacket implements MinecraftPacket {
private Key key;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundSoundEntityPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundSoundEntityPacket.java
index 459f143010..be81201c96 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundSoundEntityPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundSoundEntityPacket.java
@@ -22,11 +22,16 @@
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+import java.util.Random;
import net.kyori.adventure.sound.Sound;
import org.jetbrains.annotations.Nullable;
-import java.util.Random;
-
+/**
+ * A clientbound packet that instructs the client to play a sound tied to an entity.
+ *
+ * This is sent by the server when a sound should be played at the location of a
+ * specific entity, with optional fixed range and seed.
+ */
public class ClientboundSoundEntityPacket implements MinecraftPacket {
private static final Random SEEDS_RANDOM = new Random();
@@ -35,8 +40,16 @@ public class ClientboundSoundEntityPacket implements MinecraftPacket {
private @Nullable Float fixedRange;
private int emitterEntityId;
- public ClientboundSoundEntityPacket() {}
+ public ClientboundSoundEntityPacket() {
+ }
+ /**
+ * Constructs a new sound entity packet.
+ *
+ * @param sound the sound to play
+ * @param fixedRange the fixed attenuation range, or {@code null} to use the default
+ * @param emitterEntityId the entity ID of the sound emitter
+ */
public ClientboundSoundEntityPacket(Sound sound, @Nullable Float fixedRange, int emitterEntityId) {
this.sound = sound;
this.fixedRange = fixedRange;
@@ -55,18 +68,19 @@ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi
ProtocolUtils.writeMinimalKey(buf, sound.name());
buf.writeBoolean(fixedRange != null);
- if (fixedRange != null)
+ if (fixedRange != null) {
buf.writeFloat(fixedRange);
- ProtocolUtils.writeSoundSource(buf, protocolVersion, sound.source());
+ ProtocolUtils.writeSoundSource(buf, protocolVersion, sound.source());
- ProtocolUtils.writeVarInt(buf, emitterEntityId);
+ ProtocolUtils.writeVarInt(buf, emitterEntityId);
- buf.writeFloat(sound.volume());
+ buf.writeFloat(sound.volume());
- buf.writeFloat(sound.pitch());
+ buf.writeFloat(sound.pitch());
- buf.writeLong(sound.seed().orElse(SEEDS_RANDOM.nextLong()));
+ buf.writeLong(sound.seed().orElse(SEEDS_RANDOM.nextLong()));
+ }
}
@Override
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundStopSoundPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundStopSoundPacket.java
index 3e085d38f7..ecf14c5aa2 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundStopSoundPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundStopSoundPacket.java
@@ -22,18 +22,24 @@
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+import javax.annotation.Nullable;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.sound.SoundStop;
-import javax.annotation.Nullable;
-
+/**
+ * A clientbound packet instructing the client to stop one or more sounds.
+ *
+ * This packet supports specifying a {@link Sound.Source}, a {@link Key} sound identifier,
+ * or both together. If neither is specified, the client will stop all currently playing sounds.
+ */
public class ClientboundStopSoundPacket implements MinecraftPacket {
private @Nullable Sound.Source source;
private @Nullable Key soundName;
- public ClientboundStopSoundPacket() {}
+ public ClientboundStopSoundPacket() {
+ }
public ClientboundStopSoundPacket(SoundStop soundStop) {
this(soundStop.source(), soundStop.sound());
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundStoreCookiePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundStoreCookiePacket.java
index 7823b55841..e551473ac2 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundStoreCookiePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundStoreCookiePacket.java
@@ -25,6 +25,11 @@
import io.netty.buffer.ByteBuf;
import net.kyori.adventure.key.Key;
+/**
+ * Represents a packet sent from the server to the client to store a cookie.
+ * This packet can be used to send cookie-related data from the server to be stored or processed
+ * by the client.
+ */
public class ClientboundStoreCookiePacket implements MinecraftPacket {
private Key key;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/DialogClearPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/DialogClearPacket.java
index 4188abfdb9..e64e1ada2d 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/DialogClearPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/DialogClearPacket.java
@@ -23,6 +23,13 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents the packet sent by the server to the client to clear any
+ * currently displayed configuration dialog.
+ *
+ * This packet is used during the configuration phase (1.21.6+) to
+ * instruct the client to dismiss an active dialog window.
+ */
public class DialogClearPacket implements MinecraftPacket {
public static final DialogClearPacket INSTANCE = new DialogClearPacket();
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/DialogShowPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/DialogShowPacket.java
index 67d4b8f82a..21a69cc216 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/DialogShowPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/DialogShowPacket.java
@@ -27,6 +27,13 @@
import net.kyori.adventure.nbt.BinaryTag;
import net.kyori.adventure.nbt.BinaryTagIO;
+/**
+ * Represents the packet sent by the server to the client to display a configuration dialog
+ * during the configuration phase in Minecraft 1.21.6+.
+ *
+ * This packet is only relevant in the CONFIG and PLAY states. If the ID is {@code 0},
+ * a dialog is to be shown and the accompanying {@link BinaryTag} contains its data.
+ */
public class DialogShowPacket implements MinecraftPacket {
private final StateRegistry state;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/DisconnectPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/DisconnectPacket.java
index dd16cb61ed..7074e8fd25 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/DisconnectPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/DisconnectPacket.java
@@ -28,6 +28,12 @@
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a packet sent by the server to disconnect the client. This packet contains
+ * a reason for the disconnection, which is sent to the client and displayed to the player.
+ * The packet can be sent in different states (e.g., login, play), which affects how the
+ * reason is processed.
+ */
public class DisconnectPacket implements MinecraftPacket {
private @Nullable ComponentHolder reason;
@@ -42,6 +48,12 @@ private DisconnectPacket(StateRegistry state, ComponentHolder reason) {
this.reason = Preconditions.checkNotNull(reason, "reason");
}
+ /**
+ * Retrieves the reason for the disconnection, which will be sent to the client.
+ *
+ * @return the reason for the disconnection as a {@link ComponentHolder}
+ * @throws IllegalStateException if no reason is specified
+ */
public ComponentHolder getReason() {
if (reason == null) {
throw new IllegalStateException("No reason specified");
@@ -62,8 +74,8 @@ public String toString() {
@Override
public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
- reason = ComponentHolder.read(buf, state == StateRegistry.LOGIN
- ? ProtocolVersion.MINECRAFT_1_20_2 : version);
+ reason = ComponentHolder.read(buf, state == StateRegistry.LOGIN
+ ? ProtocolVersion.MINECRAFT_1_20_2 : version);
}
@Override
@@ -76,9 +88,17 @@ public boolean handle(MinecraftSessionHandler handler) {
return handler.handle(this);
}
+ /**
+ * Creates a new {@code DisconnectPacket} with the specified reason and version.
+ *
+ * @param component the component explaining the disconnection reason
+ * @param version the protocol version in use
+ * @param state the state in which the disconnection occurs
+ * @return the created {@code DisconnectPacket}
+ */
public static DisconnectPacket create(Component component, ProtocolVersion version, StateRegistry state) {
Preconditions.checkNotNull(component, "component");
return new DisconnectPacket(state, new ComponentHolder(state == StateRegistry.LOGIN
? ProtocolVersion.MINECRAFT_1_20_2 : version, component));
}
-}
\ No newline at end of file
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/EncryptionRequestPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/EncryptionRequestPacket.java
index 422d5e117c..66af05e066 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/EncryptionRequestPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/EncryptionRequestPacket.java
@@ -26,6 +26,12 @@
import io.netty.buffer.ByteBuf;
import java.util.Arrays;
+/**
+ * Represents the encryption request packet in Minecraft, which is sent by the server
+ * during the encryption handshake process. This packet is used to initiate secure
+ * communication by providing the client with the server's public key and a verified token.
+ * The client must respond with the encrypted shared secret and verify token.
+ */
public class EncryptionRequestPacket implements MinecraftPacket {
private String serverId = "";
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/EncryptionResponsePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/EncryptionResponsePacket.java
index fedb67a5e3..eed2ab1f4a 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/EncryptionResponsePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/EncryptionResponsePacket.java
@@ -26,10 +26,18 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
import com.velocitypowered.proxy.util.except.QuietDecoderException;
import io.netty.buffer.ByteBuf;
-import org.checkerframework.checker.nullness.qual.Nullable;
-
import java.util.Arrays;
+import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents the encryption response packet in Minecraft, which is sent by the client
+ * during the encryption handshake process. This packet contains the shared secret
+ * and verifies the token used to establish secure communication between the client
+ * and the server.
+ *
+ * The packet structure varies depending on the Minecraft protocol version, with additional
+ * fields such as a salt being present in versions 1.19 and above.
+ */
public class EncryptionResponsePacket implements MinecraftPacket {
private static final QuietDecoderException NO_SALT = new QuietDecoderException(
@@ -47,6 +55,13 @@ public byte[] getVerifyToken() {
return verifyToken.clone();
}
+ /**
+ * Retrieves the salt used in the encryption response. The salt is introduced in
+ * Minecraft version 1.19 and is optional in certain protocol versions.
+ *
+ * @return the salt used in the encryption response
+ * @throws QuietDecoderException if the salt is not present
+ */
public long getSalt() {
if (salt == null) {
throw NO_SALT;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HandshakePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HandshakePacket.java
index 88cb3688bd..5deaf395fc 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HandshakePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HandshakePacket.java
@@ -27,6 +27,12 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents a handshake packet in Minecraft, which is used during the initial connection process.
+ * This packet contains information such as the protocol version, server address, port, and the intent
+ * of the handshake (e.g., login or status request). This packet is crucial for establishing a connection
+ * between the client and the server.
+ */
public class HandshakePacket implements MinecraftPacket {
// This size was chosen to ensure Forge clients can still connect even with very long hostnames.
@@ -110,13 +116,13 @@ public boolean handle(MinecraftSessionHandler handler) {
@Override
public int decodeExpectedMinLength(ByteBuf buf, ProtocolUtils.Direction direction,
- ProtocolVersion version) {
+ ProtocolVersion version) {
return 7;
}
@Override
public int decodeExpectedMaxLength(ByteBuf buf, ProtocolUtils.Direction direction,
- ProtocolVersion version) {
+ ProtocolVersion version) {
return 9 + (MAXIMUM_HOSTNAME_LENGTH * 3);
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooterPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooterPacket.java
index 339d026f8f..55eb3ebce5 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooterPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooterPacket.java
@@ -26,6 +26,10 @@
import io.netty.buffer.ByteBuf;
import net.kyori.adventure.text.Component;
+/**
+ * Represents a packet that contains both the header and footer for the player list screen (tab list) in Minecraft.
+ * This packet allows the server to set or update the header and footer text that is displayed on the client's tab list.
+ */
public class HeaderAndFooterPacket implements MinecraftPacket {
private final ComponentHolder header;
@@ -67,11 +71,11 @@ public boolean handle(MinecraftSessionHandler handler) {
public static HeaderAndFooterPacket create(Component header,
Component footer, ProtocolVersion protocolVersion) {
return new HeaderAndFooterPacket(new ComponentHolder(protocolVersion, header),
- new ComponentHolder(protocolVersion, footer));
+ new ComponentHolder(protocolVersion, footer));
}
public static HeaderAndFooterPacket reset(ProtocolVersion version) {
ComponentHolder empty = new ComponentHolder(version, Component.empty());
return new HeaderAndFooterPacket(empty, empty);
}
-}
\ No newline at end of file
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/JoinGamePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/JoinGamePacket.java
index 787d858ebf..81ac98aeb4 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/JoinGamePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/JoinGamePacket.java
@@ -21,13 +21,19 @@
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.connection.registry.DimensionInfo;
-import com.velocitypowered.proxy.protocol.*;
+import com.velocitypowered.proxy.protocol.MinecraftPacket;
+import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.Pair;
import net.kyori.adventure.nbt.BinaryTagIO;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a packet sent to the client when they successfully join a game in Minecraft.
+ * This packet contains all the necessary information to initialize the client state,
+ * including the player's entity ID, game mode, dimension, world settings, and more.
+ */
public class JoinGamePacket implements MinecraftPacket {
private static final BinaryTagIO.Reader JOINGAME_READER = BinaryTagIO.reader(4 * 1024 * 1024);
@@ -204,17 +210,17 @@ public CompoundBinaryTag getRegistry() {
@Override
public String toString() {
- return "JoinGame{" + "entityId=" + entityId + ", gamemode=" + gamemode + ", dimension=" +
- dimension + ", partialHashedSeed=" + partialHashedSeed + ", difficulty=" + difficulty +
- ", isHardcore=" + isHardcore + ", maxPlayers=" + maxPlayers + ", levelType='" + levelType +
- '\'' + ", viewDistance=" + viewDistance + ", reducedDebugInfo=" + reducedDebugInfo +
- ", showRespawnScreen=" + showRespawnScreen + ", doLimitedCrafting=" + doLimitedCrafting +
- ", levelNames=" + levelNames + ", registry='" + registry + '\'' + ", dimensionInfo='" +
- dimensionInfo + '\'' + ", currentDimensionData='" + currentDimensionData + '\'' +
- ", previousGamemode=" + previousGamemode + ", simulationDistance=" + simulationDistance +
- ", lastDeathPosition='" + lastDeathPosition + '\'' + ", portalCooldown=" + portalCooldown +
- ", seaLevel=" + seaLevel +
- '}';
+ return "JoinGame{" + "entityId=" + entityId + ", gamemode=" + gamemode + ", dimension="
+ + dimension + ", partialHashedSeed=" + partialHashedSeed + ", difficulty=" + difficulty
+ + ", isHardcore=" + isHardcore + ", maxPlayers=" + maxPlayers + ", levelType='" + levelType
+ + '\'' + ", viewDistance=" + viewDistance + ", reducedDebugInfo=" + reducedDebugInfo
+ + ", showRespawnScreen=" + showRespawnScreen + ", doLimitedCrafting=" + doLimitedCrafting
+ + ", levelNames=" + levelNames + ", registry='" + registry + '\'' + ", dimensionInfo='"
+ + dimensionInfo + '\'' + ", currentDimensionData='" + currentDimensionData + '\''
+ + ", previousGamemode=" + previousGamemode + ", simulationDistance=" + simulationDistance
+ + ", lastDeathPosition='" + lastDeathPosition + '\'' + ", portalCooldown=" + portalCooldown
+ + ", seaLevel=" + seaLevel
+ + '}';
}
@Override
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/KeepAlivePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/KeepAlivePacket.java
index a44e50eeaa..3ae2d89d30 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/KeepAlivePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/KeepAlivePacket.java
@@ -23,6 +23,11 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents a KeepAlive packet in Minecraft. This packet is used to ensure that the connection
+ * between the client and the server shall still be active by sending a randomly generated ID that
+ * the client must respond to.
+ */
public class KeepAlivePacket implements MinecraftPacket {
private long randomId;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyDisconnect.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyDisconnect.java
index e8f8deef29..952dfe28dc 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyDisconnect.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyDisconnect.java
@@ -25,7 +25,13 @@
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
-@SuppressWarnings("checkstyle:MissingJavadocType")
+/**
+ * Represents a legacy disconnect packet that contains a reason for disconnection.
+ * This class is used to convert modern server ping responses into the legacy format,
+ * which is compatible with older Minecraft versions.
+ *
+ * @param reason the string reason for disconnection
+ */
public record LegacyDisconnect(String reason) {
private static final ServerPing.Players FAKE_PLAYERS = new ServerPing.Players(0, 0,
@@ -46,17 +52,17 @@ public static LegacyDisconnect fromServerPing(ServerPing response,
return switch (version) {
case MINECRAFT_1_3 ->
- // Minecraft 1.3 and below use the section symbol as a delimiter. Accordingly, we must
- // remove all section symbols, along with fetching just the first line of an (unformatted)
- // MOTD.
- new LegacyDisconnect(String.join(LEGACY_COLOR_CODE,
+ // Minecraft 1.3 and below use the section symbol as a delimiter. Accordingly, we must
+ // remove all section symbols, along with fetching just the first line of an (unformatted)
+ // MOTD.
+ new LegacyDisconnect(String.join(LEGACY_COLOR_CODE,
cleanSectionSymbol(getFirstLine(PlainTextComponentSerializer.plainText().serialize(
response.getDescriptionComponent()))),
Integer.toString(players.getOnline()),
Integer.toString(players.getMax())));
case MINECRAFT_1_4, MINECRAFT_1_6 ->
- // Minecraft 1.4-1.6 provide support for more fields, and additionally support color codes.
- new LegacyDisconnect(String.join("\0",
+ // Minecraft 1.4-1.6 provide support for more fields, and additionally support color codes.
+ new LegacyDisconnect(String.join("\0",
LEGACY_COLOR_CODE + "1",
Integer.toString(response.getVersion().getProtocol()),
response.getVersion().getName(),
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyHandshakePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyHandshakePacket.java
index 38483ed864..8a9aba2700 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyHandshakePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyHandshakePacket.java
@@ -23,6 +23,11 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents a legacy handshake packet in Minecraft, which is typically used
+ * during the initial connection process for older versions of the Minecraft protocol.
+ * This class currently does not support decoding of the handshake packet.
+ */
public class LegacyHandshakePacket implements MinecraftPacket {
@Override
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyPingPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyPingPacket.java
index 656d3222b2..c81c47221e 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyPingPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyPingPacket.java
@@ -26,6 +26,11 @@
import java.net.InetSocketAddress;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a legacy ping packet in Minecraft, commonly used in the server list ping process.
+ * This packet handles compatibility with older Minecraft versions and contains information
+ * such as the ping protocol version and optionally a virtual host address.
+ */
public class LegacyPingPacket implements MinecraftPacket {
private final LegacyMinecraftPingVersion version;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyPlayerListItemPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyPlayerListItemPacket.java
index 9dbe9cbcb8..cdffabccce 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyPlayerListItemPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LegacyPlayerListItemPacket.java
@@ -33,6 +33,10 @@
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a legacy player list item packet, which is used to modify the player list in a Minecraft client.
+ * The packet can add, remove, or update player entries (e.g., updating gamemode, latency, or display names).
+ */
public class LegacyPlayerListItemPacket implements MinecraftPacket {
public static final int ADD_PLAYER = 0;
@@ -76,16 +80,16 @@ public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi
item.setLatency(ProtocolUtils.readVarInt(buf));
item.setDisplayName(readOptionalComponent(buf, version));
if (version.noLessThan(ProtocolVersion.MINECRAFT_1_19)) {
- if (buf.readBoolean()) {
- item.setPlayerKey(ProtocolUtils.readPlayerKey(version, buf));
- }
+ if (buf.readBoolean()) {
+ item.setPlayerKey(ProtocolUtils.readPlayerKey(version, buf));
+ }
}
}
case UPDATE_GAMEMODE -> item.setGameMode(ProtocolUtils.readVarInt(buf));
case UPDATE_LATENCY -> item.setLatency(ProtocolUtils.readVarInt(buf));
case UPDATE_DISPLAY_NAME -> item.setDisplayName(readOptionalComponent(buf, version));
case REMOVE_PLAYER -> {
- //Do nothing, all that is needed is the uuid
+ // Do nothing, all that is needed is the uuid
}
default -> throw new UnsupportedOperationException("Unknown action " + action);
}
@@ -107,6 +111,17 @@ public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi
return null;
}
+ /**
+ * Encodes this packet's contents into the given {@link ByteBuf}.
+ *
+ * This method serializes the packet data based on the current protocol version.
+ * Subclasses overriding this method should preserve compatibility with legacy
+ * and modern formats as needed.
+ *
+ * @param buf the buffer to write to
+ * @param direction the direction of the packet (clientbound or serverbound)
+ * @param version the Minecraft protocol version
+ */
@Override
public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
if (version.noLessThan(ProtocolVersion.MINECRAFT_1_8)) {
@@ -125,12 +140,12 @@ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi
ProtocolUtils.writeVarInt(buf, item.getLatency());
writeDisplayName(buf, item.getDisplayName(), version);
if (version.noLessThan(ProtocolVersion.MINECRAFT_1_19)) {
- if (item.getPlayerKey() != null) {
- buf.writeBoolean(true);
- ProtocolUtils.writePlayerKey(buf, item.getPlayerKey());
- } else {
- buf.writeBoolean(false);
- }
+ if (item.getPlayerKey() != null) {
+ buf.writeBoolean(true);
+ ProtocolUtils.writePlayerKey(buf, item.getPlayerKey());
+ } else {
+ buf.writeBoolean(false);
+ }
}
}
case UPDATE_GAMEMODE -> ProtocolUtils.writeVarInt(buf, item.getGameMode());
@@ -172,6 +187,10 @@ private void writeDisplayName(ByteBuf buf, @Nullable Component displayName,
}
}
+ /**
+ * Represents an individual item in the player list, containing the player's details such as UUID, name,
+ * game mode, latency, and optionally a display name and player key.
+ */
public static class Item {
private final UUID uuid;
@@ -190,6 +209,15 @@ public Item(UUID uuid) {
this.uuid = uuid;
}
+ /**
+ * Creates an {@link Item} instance from a {@link TabListEntry}.
+ * This method extracts relevant data from the {@link TabListEntry} such as
+ * the player's profile ID, name, properties, latency, game mode, player key,
+ * and display name, and uses them to populate a new {@code Item}.
+ *
+ * @param entry the {@link TabListEntry} from which to extract data
+ * @return an {@link Item} populated with data from the {@link TabListEntry}
+ */
public static Item from(TabListEntry entry) {
return new Item(entry.getProfile().getId())
.setName(entry.getProfile().getName())
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginAcknowledgedPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginAcknowledgedPacket.java
index 16cf519b0b..15bbb2c343 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginAcknowledgedPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginAcknowledgedPacket.java
@@ -23,6 +23,13 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents a packet that acknowledges a successful login, implementing {@link MinecraftPacket}.
+ *
+ * The {@code LoginAcknowledgedPacket} is sent by the server to confirm that the player's login
+ * process has been successfully completed. It signals the transition from the login phase to the
+ * game or session phase.
+ */
public class LoginAcknowledgedPacket implements MinecraftPacket {
@Override
@@ -37,7 +44,7 @@ public void encode(ByteBuf buf, ProtocolUtils.Direction direction,
@Override
public int decodeExpectedMaxLength(ByteBuf buf, ProtocolUtils.Direction direction,
- ProtocolVersion version) {
+ ProtocolVersion version) {
return 0;
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginMessagePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginMessagePacket.java
index 2fa82e922c..5833ea036a 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginMessagePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginMessagePacket.java
@@ -27,6 +27,10 @@
import io.netty.buffer.Unpooled;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a login plugin message packet sent during the login phase. This packet allows custom
+ * plugin messages to be sent from the server to the client before login is complete.
+ */
public class LoginPluginMessagePacket extends DeferredByteBufHolder implements MinecraftPacket {
private int id;
@@ -36,6 +40,13 @@ public LoginPluginMessagePacket() {
super(null);
}
+ /**
+ * Constructs a new {@code LoginPluginMessagePacket} with the specified ID, channel, and data buffer.
+ *
+ * @param id the plugin message ID
+ * @param channel the channel name, or {@code null} if not specified
+ * @param data the data buffer
+ */
public LoginPluginMessagePacket(int id, @Nullable String channel, ByteBuf data) {
super(data);
this.id = id;
@@ -46,6 +57,12 @@ public int getId() {
return id;
}
+ /**
+ * Gets the plugin message channel.
+ *
+ * @return the channel name
+ * @throws IllegalStateException if the channel is not specified
+ */
public String getChannel() {
if (channel == null) {
throw new IllegalStateException("Channel is not specified!");
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginResponsePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginResponsePacket.java
index e7d9443dca..1a8c10664f 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginResponsePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginResponsePacket.java
@@ -27,6 +27,10 @@
import io.netty.buffer.Unpooled;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
+/**
+ * Represents the response packet to a plugin message sent during the login phase.
+ * The packet contains the plugin message ID, a success flag, and any additional data.
+ */
public class LoginPluginResponsePacket extends DeferredByteBufHolder implements MinecraftPacket {
private int id;
@@ -36,6 +40,13 @@ public LoginPluginResponsePacket() {
super(Unpooled.EMPTY_BUFFER);
}
+ /**
+ * Constructs a new {@code LoginPluginResponsePacket} with the specified ID, success status, and data buffer.
+ *
+ * @param id the plugin message ID
+ * @param success {@code true} if the plugin message was successful, {@code false} otherwise
+ * @param buf the data buffer
+ */
public LoginPluginResponsePacket(int id, boolean success, @MonotonicNonNull ByteBuf buf) {
super(buf);
this.id = id;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/PingIdentifyPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/PingIdentifyPacket.java
index 27c1351d5e..7d870dcf6f 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/PingIdentifyPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/PingIdentifyPacket.java
@@ -23,6 +23,9 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents a packet used for ping identification with a unique ID.
+ */
public class PingIdentifyPacket implements MinecraftPacket {
private int id;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/PluginMessagePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/PluginMessagePacket.java
index ecf2887fd9..bb8abf578d 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/PluginMessagePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/PluginMessagePacket.java
@@ -29,6 +29,10 @@
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a plugin message packet, which allows for custom communication between
+ * a Minecraft server and a client via custom channels.
+ */
public class PluginMessagePacket extends DeferredByteBufHolder implements MinecraftPacket {
private @Nullable String channel;
@@ -43,6 +47,12 @@ public PluginMessagePacket(String channel,
this.channel = channel;
}
+ /**
+ * Gets the channel for this plugin message.
+ *
+ * @return the channel name
+ * @throws IllegalStateException if the channel is not set
+ */
public String getChannel() {
if (channel == null) {
throw new IllegalStateException("Channel is not specified.");
@@ -73,7 +83,6 @@ public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi
} else {
this.replace(ProtocolUtils.readRetainedByteBufSlice17(buf));
}
-
}
@Override
@@ -97,7 +106,6 @@ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi
} else {
ProtocolUtils.writeByteBuf17(content(), buf, true); // True for Forge support
}
-
}
@Override
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/RemovePlayerInfoPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/RemovePlayerInfoPacket.java
index 90ab387178..255769d875 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/RemovePlayerInfoPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/RemovePlayerInfoPacket.java
@@ -27,6 +27,10 @@
import java.util.Collection;
import java.util.UUID;
+/**
+ * Represents a packet sent to remove player information from the player list.
+ * The packet contains a collection of {@link UUID}s representing the profiles to be removed.
+ */
public class RemovePlayerInfoPacket implements MinecraftPacket {
private Collection profilesToRemove;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/RemoveResourcePackPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/RemoveResourcePackPacket.java
index d003a0a951..8d6ef276c4 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/RemoveResourcePackPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/RemoveResourcePackPacket.java
@@ -25,6 +25,10 @@
import io.netty.buffer.ByteBuf;
import java.util.UUID;
+/**
+ * Represents a packet sent to remove a previously applied resource pack from the client.
+ * The packet contains an optional UUID that identifies the resource pack to be removed.
+ */
public class RemoveResourcePackPacket implements MinecraftPacket {
private UUID id;
@@ -60,4 +64,4 @@ public void encode(ByteBuf buf, Direction direction, ProtocolVersion protocolVer
public boolean handle(MinecraftSessionHandler handler) {
return handler.handle(this);
}
-}
\ No newline at end of file
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackRequestPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackRequestPacket.java
index a0f86aed11..b5e7e63fee 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackRequestPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackRequestPacket.java
@@ -33,6 +33,10 @@
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a resource pack request packet sent by the server to prompt the client to download a resource pack.
+ * The packet includes the resource pack URL, SHA1 hash, and optional prompt.
+ */
public class ResourcePackRequestPacket implements MinecraftPacket {
private @MonotonicNonNull UUID id; // 1.20.3+
@@ -124,6 +128,12 @@ public void encode(ByteBuf buf, Direction direction, ProtocolVersion protocolVer
}
}
+ /**
+ * Converts this packet into a {@link VelocityResourcePackInfo} object, which contains the information
+ * about the resource pack being requested.
+ *
+ * @return a {@code VelocityResourcePackInfo} representing the resource pack information
+ */
public VelocityResourcePackInfo toServerPromptedPack() {
final ResourcePackInfo.Builder builder =
new VelocityResourcePackInfo.BuilderImpl(Preconditions.checkNotNull(url))
@@ -145,12 +155,12 @@ public boolean handle(MinecraftSessionHandler handler) {
@Override
public String toString() {
- return "ResourcePackRequestPacket{" +
- "id=" + id +
- ", url='" + url + '\'' +
- ", hash='" + hash + '\'' +
- ", isRequired=" + isRequired +
- ", prompt=" + prompt +
- '}';
+ return "ResourcePackRequestPacket{"
+ + "id=" + id
+ + ", url='" + url + '\''
+ + ", hash='" + hash + '\''
+ + ", isRequired=" + isRequired
+ + ", prompt=" + prompt
+ + '}';
}
-}
\ No newline at end of file
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackResponsePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackResponsePacket.java
index 020c3530de..de5d08828e 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackResponsePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackResponsePacket.java
@@ -24,10 +24,13 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
import io.netty.buffer.ByteBuf;
-import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
-
import java.util.UUID;
+import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
+/**
+ * Represents the response packet sent by the client after receiving a resource pack request from the server.
+ * The packet contains information about the client's response, including the resource pack status.
+ */
public class ResourcePackResponsePacket implements MinecraftPacket {
private UUID id;
@@ -37,12 +40,25 @@ public class ResourcePackResponsePacket implements MinecraftPacket {
public ResourcePackResponsePacket() {
}
+ /**
+ * Constructs a new {@code ResourcePackResponsePacket} with the specified parameters.
+ *
+ * @param id the unique identifier for the response
+ * @param hash the hash of the resource pack
+ * @param status the status of the resource pack
+ */
public ResourcePackResponsePacket(UUID id, String hash, @MonotonicNonNull Status status) {
this.id = id;
this.hash = hash;
this.status = status;
}
+ /**
+ * Gets the status of the resource pack response.
+ *
+ * @return the status of the response
+ * @throws IllegalStateException if the packet has not been deserialized yet
+ */
public Status getStatus() {
if (status == null) {
throw new IllegalStateException("Packet not yet deserialized");
@@ -87,10 +103,10 @@ public boolean handle(MinecraftSessionHandler handler) {
@Override
public String toString() {
- return "ResourcePackResponsePacket{" +
- "id=" + id +
- ", hash='" + hash + '\'' +
- ", status=" + status +
- '}';
+ return "ResourcePackResponsePacket{"
+ + "id=" + id
+ + ", hash='" + hash + '\''
+ + ", status=" + status
+ + '}';
}
-}
\ No newline at end of file
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/RespawnPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/RespawnPacket.java
index fd9c8ca772..2e13fcad30 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/RespawnPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/RespawnPacket.java
@@ -28,6 +28,10 @@
import net.kyori.adventure.nbt.CompoundBinaryTag;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a respawn packet sent by the server when the player changes dimensions or respawns.
+ * The packet contains information about the new dimension, difficulty, gamemode, and more.
+ */
public class RespawnPacket implements MinecraftPacket {
private int dimension;
@@ -46,6 +50,22 @@ public class RespawnPacket implements MinecraftPacket {
public RespawnPacket() {
}
+ /**
+ * Constructs a new {@code RespawnPacket} with the specified parameters.
+ *
+ * @param dimension the dimension the player is respawning or teleporting to
+ * @param partialHashedSeed the partial hashed seed
+ * @param difficulty the difficulty of the server
+ * @param gamemode the player's current gamemode
+ * @param levelType the type of level (e.g., "default", "flat")
+ * @param dataToKeep a byte flag indicating whether certain data should be kept
+ * @param dimensionInfo additional information about the dimension (for 1.16-1.16.1)
+ * @param previousGamemode the player's previous gamemode
+ * @param currentDimensionData data about the current dimension (for 1.16.2+)
+ * @param lastDeathPosition optional last death position (for 1.19+)
+ * @param portalCooldown the cooldown for portal usage (for 1.20+)
+ * @param seaLevel a determinable spawn point for a user (for 1.21.2+)
+ */
public RespawnPacket(int dimension, long partialHashedSeed, short difficulty, short gamemode,
String levelType, byte dataToKeep, DimensionInfo dimensionInfo,
short previousGamemode, CompoundBinaryTag currentDimensionData,
@@ -65,6 +85,12 @@ public RespawnPacket(int dimension, long partialHashedSeed, short difficulty, sh
this.seaLevel = seaLevel;
}
+ /**
+ * Creates a new {@code RespawnPacket} from a {@link JoinGamePacket}.
+ *
+ * @param joinGame the {@code JoinGamePacket} to use
+ * @return a new {@code RespawnPacket} based on the provided {@code JoinGamePacket}
+ */
public static RespawnPacket fromJoinGame(JoinGamePacket joinGame) {
return new RespawnPacket(joinGame.getDimension(), joinGame.getPartialHashedSeed(),
joinGame.getDifficulty(), joinGame.getGamemode(), joinGame.getLevelType(),
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerDataPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerDataPacket.java
index 325a3c9dfe..e1430aae3c 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerDataPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerDataPacket.java
@@ -25,10 +25,14 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import io.netty.buffer.ByteBuf;
-import org.jetbrains.annotations.Nullable;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
+import org.jetbrains.annotations.Nullable;
+/**
+ * Represents the server data packet sent from the server to the client, which contains information
+ * such as the server description, favicon, and secure chat enforcement status.
+ */
public class ServerDataPacket implements MinecraftPacket {
private @Nullable ComponentHolder description;
@@ -38,6 +42,13 @@ public class ServerDataPacket implements MinecraftPacket {
public ServerDataPacket() {
}
+ /**
+ * Constructs a new {@code ServerDataPacket} with the given server description, favicon, and secure chat enforcement status.
+ *
+ * @param description the server description (maybe null)
+ * @param favicon the server favicon (maybe null)
+ * @param secureChatEnforced whether secure chat is enforced (for versions 1.19.1 to 1.20.5)
+ */
public ServerDataPacket(@Nullable ComponentHolder description, @Nullable Favicon favicon,
boolean secureChatEnforced) {
this.description = description;
@@ -127,4 +138,4 @@ public void setSecureChatEnforced(boolean secureChatEnforced) {
public int encodeSizeHint(Direction direction, ProtocolVersion version) {
return 8 * 1024;
}
-}
\ No newline at end of file
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginPacket.java
index 65693cd815..8c8bec60b9 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginPacket.java
@@ -29,6 +29,11 @@
import java.util.UUID;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents the packet sent from the client to the server during the login phase.
+ * This packet contains the player's username, optionally a cryptographic key for
+ * authentication, and the holder UUID depending on the Minecraft protocol version.
+ */
public class ServerLoginPacket implements MinecraftPacket {
private static final QuietDecoderException EMPTY_USERNAME = new QuietDecoderException(
@@ -41,17 +46,35 @@ public class ServerLoginPacket implements MinecraftPacket {
public ServerLoginPacket() {
}
+ /**
+ * Constructs a {@code ServerLoginPacket} with a username and optional player key.
+ *
+ * @param username the player's username
+ * @param playerKey the player's cryptographic key, or {@code null} if not present
+ */
public ServerLoginPacket(String username, @Nullable IdentifiedKey playerKey) {
this.username = Preconditions.checkNotNull(username, "username");
this.playerKey = playerKey;
}
+ /**
+ * Constructs a new {@code ServerLoginPacket} with the specified username and holder UUID.
+ *
+ * @param username the player's username
+ * @param holderUuid the holder UUID (optional)
+ */
public ServerLoginPacket(String username, @Nullable UUID holderUuid) {
this.username = Preconditions.checkNotNull(username, "username");
this.holderUuid = holderUuid;
this.playerKey = null;
}
+ /**
+ * Gets the player's username from the login packet.
+ *
+ * @return the player's username
+ * @throws IllegalStateException if the username is not specified
+ */
public String getUsername() {
if (username == null) {
throw new IllegalStateException("No username found!");
@@ -74,10 +97,10 @@ public void setPlayerKey(IdentifiedKey playerKey) {
@Override
public String toString() {
return "ServerLogin{"
- + "username='" + username + '\''
- + "playerKey='" + playerKey + '\''
- + "holderUUID='" + holderUuid + '\''
- + '}';
+ + "username='" + username + '\''
+ + "playerKey='" + playerKey + '\''
+ + "holderUUID='" + holderUuid + '\''
+ + '}';
}
@Override
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginSuccessPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginSuccessPacket.java
index 322cd9b195..86893cc088 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginSuccessPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginSuccessPacket.java
@@ -30,6 +30,10 @@
import java.util.UUID;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents the packet sent from the server to the client to indicate successful login.
+ * This packet contains the player's UUID, username, and properties associated with their profile.
+ */
public class ServerLoginSuccessPacket implements MinecraftPacket {
private @Nullable UUID uuid;
@@ -38,6 +42,12 @@ public class ServerLoginSuccessPacket implements MinecraftPacket {
private static final boolean strictErrorHandling = VelocityProperties
.readBoolean("velocity.strictErrorHandling", true);
+ /**
+ * Gets the player's UUID from the login success packet.
+ *
+ * @return the player's UUID
+ * @throws IllegalStateException if the UUID is not specified
+ */
public UUID getUuid() {
if (uuid == null) {
throw new IllegalStateException("No UUID specified!");
@@ -49,6 +59,12 @@ public void setUuid(UUID uuid) {
this.uuid = uuid;
}
+ /**
+ * Gets the player's username from the login success packet.
+ *
+ * @return the player's username
+ * @throws IllegalStateException if the username is not specified
+ */
public String getUsername() {
if (username == null) {
throw new IllegalStateException("No username specified!");
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerboundCookieResponsePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerboundCookieResponsePacket.java
index bee12b8024..2191ae0935 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerboundCookieResponsePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerboundCookieResponsePacket.java
@@ -26,6 +26,11 @@
import net.kyori.adventure.key.Key;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a server-bound packet sent by the client containing a key and an optional payload.
+ * This packet is typically used for exchanging metadata or other information between the client
+ * and server.
+ */
public class ServerboundCookieResponsePacket implements MinecraftPacket {
private Key key;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerboundCustomClickActionPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerboundCustomClickActionPacket.java
index 6b846c2343..9b5665fce0 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerboundCustomClickActionPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerboundCustomClickActionPacket.java
@@ -25,6 +25,12 @@
import com.velocitypowered.proxy.protocol.util.DeferredByteBufHolder;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents a serverbound packet carrying an opaque custom click action payload.
+ *
+ * The payload is retained as-is and forwarded to the session handler without
+ * interpretation by the proxy.
+ */
public class ServerboundCustomClickActionPacket extends DeferredByteBufHolder implements MinecraftPacket {
public ServerboundCustomClickActionPacket() {
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/SetCompressionPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/SetCompressionPacket.java
index 6710bf85d8..7bba564571 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/SetCompressionPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/SetCompressionPacket.java
@@ -23,6 +23,10 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents a packet that sets the compression threshold for network communication.
+ * When the size of a packet exceeds the threshold, the packet will be compressed.
+ */
public class SetCompressionPacket implements MinecraftPacket {
private int threshold;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusPingPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusPingPacket.java
index 302367044a..554e879389 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusPingPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusPingPacket.java
@@ -24,6 +24,10 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents a status ping packet sent by the client to the server, which is used to measure the latency
+ * between the client and server.
+ */
public class StatusPingPacket implements MinecraftPacket {
private long randomId;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusRequestPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusRequestPacket.java
index 870d99093f..cbf901cf39 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusRequestPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusRequestPacket.java
@@ -24,12 +24,14 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents a status request packet sent by the client to the server to request the server's status.
+ */
public class StatusRequestPacket implements MinecraftPacket {
public static final StatusRequestPacket INSTANCE = new StatusRequestPacket();
private StatusRequestPacket() {
-
}
@Override
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusResponsePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusResponsePacket.java
index 20fada4bc7..08dcb3dba6 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusResponsePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusResponsePacket.java
@@ -25,6 +25,9 @@
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a status response packet sent from the server to the client.
+ */
public class StatusResponsePacket implements MinecraftPacket {
private @Nullable CharSequence status;
@@ -36,6 +39,12 @@ public StatusResponsePacket(CharSequence status) {
this.status = status;
}
+ /**
+ * Gets the status message from the packet.
+ *
+ * @return the status message as a {@link String}
+ * @throws IllegalStateException if the status is not specified
+ */
public String getStatus() {
if (status == null) {
throw new IllegalStateException("Status is not specified");
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TabCompleteRequestPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TabCompleteRequestPacket.java
index dda4695bbc..5bdbcc6b16 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TabCompleteRequestPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TabCompleteRequestPacket.java
@@ -29,6 +29,9 @@
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a packet sent by the client when a tab-completion request is initiated.
+ */
public class TabCompleteRequestPacket implements MinecraftPacket {
private static final int VANILLA_MAX_TAB_COMPLETE_LEN = 2048;
@@ -39,6 +42,12 @@ public class TabCompleteRequestPacket implements MinecraftPacket {
private boolean hasPosition;
private long position;
+ /**
+ * Gets the command string to be completed.
+ *
+ * @return the command string
+ * @throws IllegalStateException if the command is not set
+ */
public String getCommand() {
if (command == null) {
throw new IllegalStateException("Command is not specified");
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TabCompleteResponsePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TabCompleteResponsePacket.java
index a22fff0bdb..dddad82fc9 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TabCompleteResponsePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TabCompleteResponsePacket.java
@@ -30,6 +30,9 @@
import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents the packet used to send tab-completion suggestions to the client.
+ */
public class TabCompleteResponsePacket implements MinecraftPacket {
private int transactionId;
@@ -122,6 +125,9 @@ public boolean handle(MinecraftSessionHandler handler) {
return handler.handle(this);
}
+ /**
+ * Represents an individual tab-completion suggestion (offer) sent to the client.
+ */
public static class Offer implements Comparable {
private final String text;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TransferPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TransferPacket.java
index b5a74e49f2..6f94c6c9f2 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TransferPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TransferPacket.java
@@ -25,6 +25,9 @@
import java.net.InetSocketAddress;
import org.jetbrains.annotations.Nullable;
+/**
+ * Represents a packet used to transfer a player to another server.
+ */
public class TransferPacket implements MinecraftPacket {
private String host;
private int port;
@@ -32,11 +35,22 @@ public class TransferPacket implements MinecraftPacket {
public TransferPacket() {
}
+ /**
+ * Constructs a {@code TransferPacket} with the specified host and port.
+ *
+ * @param host the hostname of the destination server
+ * @param port the port of the destination server
+ */
public TransferPacket(final String host, final int port) {
this.host = host;
this.port = port;
}
+ /**
+ * Gets the {@link InetSocketAddress} representing the transfer address.
+ *
+ * @return the {@code InetSocketAddress}, or {@code null} if the host is not set
+ */
@Nullable
public InetSocketAddress address() {
if (host == null) {
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/UpsertPlayerInfoPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/UpsertPlayerInfoPacket.java
index 9ef40ef092..b86b8bd126 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/UpsertPlayerInfoPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/UpsertPlayerInfoPacket.java
@@ -34,6 +34,9 @@
import java.util.UUID;
import org.jetbrains.annotations.Nullable;
+/**
+ * Represents the packet for updating or inserting player information.
+ */
public class UpsertPlayerInfoPacket implements MinecraftPacket {
private static final Action[] ALL_ACTIONS = Action.class.getEnumConstants();
@@ -133,6 +136,9 @@ public boolean handle(MinecraftSessionHandler handler) {
return handler.handle(this);
}
+ /**
+ * Represents the possible actions in the player info packet.
+ */
public enum Action {
ADD_PLAYER((ignored, buf, info) -> { // read
info.profile = new GameProfile(
@@ -213,6 +219,9 @@ private interface Write {
}
}
+ /**
+ * Represents an entry in the player info packet.
+ */
public static class Entry {
private final UUID profileId;
@@ -303,16 +312,16 @@ public void setChatSession(@Nullable RemoteChatSession chatSession) {
@Override
public String toString() {
- return "Entry{" +
- "profileId=" + profileId +
- ", profile=" + profile +
- ", listed=" + listed +
- ", latency=" + latency +
- ", gameMode=" + gameMode +
- ", displayName=" + displayName +
- ", listOrder=" + listOrder +
- ", chatSession=" + chatSession +
- '}';
+ return "Entry{"
+ + "profileId=" + profileId
+ + ", profile=" + profile
+ + ", listed=" + listed
+ + ", latency=" + latency
+ + ", gameMode=" + gameMode
+ + ", displayName=" + displayName
+ + ", listOrder=" + listOrder
+ + ", chatSession=" + chatSession
+ + '}';
}
}
-}
\ No newline at end of file
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentIdentifier.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentIdentifier.java
index 6441f6f775..fe43f5d0c6 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentIdentifier.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentIdentifier.java
@@ -24,6 +24,14 @@
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents an identifier for a Brigadier command argument, mapping the argument to
+ * different protocol versions.
+ *
+ * The {@code ArgumentIdentifier} is responsible for holding an identifier string for
+ * an argument and a map that associates protocol versions with their respective IDs.
+ * It ensures that the protocol version is compatible with the Minecraft 1.19 protocol or later.
+ */
public class ArgumentIdentifier {
private final String identifier;
@@ -37,8 +45,8 @@ private ArgumentIdentifier(String identifier, VersionSet... versions) {
Map temp = new HashMap<>();
ProtocolVersion previous = null;
- for (int i = 0; i < versions.length; i++) {
- VersionSet current = Preconditions.checkNotNull(versions[i]);
+ for (VersionSet version : versions) {
+ VersionSet current = Preconditions.checkNotNull(version);
Preconditions.checkArgument(
current.getVersion().noLessThan(ProtocolVersion.MINECRAFT_1_19),
@@ -60,9 +68,9 @@ private ArgumentIdentifier(String identifier, VersionSet... versions) {
@Override
public String toString() {
- return "ArgumentIdentifier{" +
- "identifier='" + identifier + '\'' +
- '}';
+ return "ArgumentIdentifier{"
+ + "identifier='" + identifier + '\''
+ + '}';
}
public String getIdentifier() {
@@ -101,7 +109,6 @@ public int getId() {
public ProtocolVersion getVersion() {
return version;
}
-
}
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertyRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertyRegistry.java
index 203ab375cf..ba7ab86b3b 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertyRegistry.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertyRegistry.java
@@ -45,11 +45,18 @@
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
-import org.jetbrains.annotations.NotNull;
-
import java.util.HashMap;
import java.util.Map;
+import org.jetbrains.annotations.NotNull;
+/**
+ * The {@code ArgumentPropertyRegistry} is responsible for managing the registration and
+ * retrieval of argument properties used in command parsing and execution.
+ *
+ * This class functions as a registry, allowing different argument properties to be registered
+ * and later retrieved or used when processing commands within the system. The properties
+ * might be tied to argument types, validation rules, or transformations.
+ */
public class ArgumentPropertyRegistry {
private ArgumentPropertyRegistry() {
@@ -145,7 +152,6 @@ public static void writeIdentifier(ByteBuf buf, ArgumentIdentifier identifier,
} else {
ProtocolUtils.writeString(buf, identifier.getIdentifier());
}
-
}
/**
@@ -272,7 +278,7 @@ public void serialize(BoolArgumentType object, ByteBuf buf,
empty(id("minecraft:heightmap", mapSet(MINECRAFT_1_21_6, 51), mapSet(MINECRAFT_1_21_5, 50), mapSet(MINECRAFT_1_20_3, 49),
mapSet(MINECRAFT_1_19_4, 47))); // 1.19.4
- empty(id("minecraft:uuid", mapSet(MINECRAFT_1_21_6, 56), mapSet(MINECRAFT_1_21_5, 54),mapSet(MINECRAFT_1_20_5, 53), mapSet(MINECRAFT_1_20_3, 48),
+ empty(id("minecraft:uuid", mapSet(MINECRAFT_1_21_6, 56), mapSet(MINECRAFT_1_21_5, 54), mapSet(MINECRAFT_1_20_5, 53), mapSet(MINECRAFT_1_20_3, 48),
mapSet(MINECRAFT_1_19_4, 48), mapSet(MINECRAFT_1_19, 47))); // added in 1.16
empty(id("minecraft:loot_table", mapSet(MINECRAFT_1_21_6, 52), mapSet(MINECRAFT_1_21_5, 51), mapSet(MINECRAFT_1_20_5, 50)));
@@ -287,4 +293,4 @@ public void serialize(BoolArgumentType object, ByteBuf buf,
empty(id("minecraft:nbt")); // No longer in 1.19+
}
-}
\ No newline at end of file
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertySerializer.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertySerializer.java
index 25dcfd76c9..3649fec115 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertySerializer.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertySerializer.java
@@ -21,6 +21,16 @@
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * The {@code ArgumentPropertySerializer} interface defines a contract for serializing and
+ * deserializing argument properties to and from a specific format.
+ *
+ * This interface allows implementations to convert argument properties into a serialized form,
+ * which can later be deserialized and restored to their original form. This is particularly useful
+ * for persisting command argument configurations or sending them across a network.
+ *
+ * @param the type of the argument property being serialized
+ */
public interface ArgumentPropertySerializer {
@Nullable T deserialize(ByteBuf buf, ProtocolVersion protocolVersion);
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ModArgumentProperty.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ModArgumentProperty.java
index 15416f8611..950f378415 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ModArgumentProperty.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ModArgumentProperty.java
@@ -28,6 +28,17 @@
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
+/**
+ * Represents a mod-specific argument type with custom binary data attached.
+ *
+ * This class allows external mods or extensions to define their own command argument
+ * types, identified by a namespaced {@link ArgumentIdentifier} and accompanied by
+ * serialized {@link ByteBuf} data.
+ *
+ * Note: This type is not parseable or suggestible through Brigadier and exists primarily
+ * to preserve compatibility with extended command metadata during serialization and
+ * deserialization.
+ */
public class ModArgumentProperty implements ArgumentType {
private final ArgumentIdentifier identifier;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryIdArgumentSerializer.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryIdArgumentSerializer.java
index 5e8e1daf12..eff680c43c 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryIdArgumentSerializer.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryIdArgumentSerializer.java
@@ -21,6 +21,16 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * The {@code RegistryIdArgumentSerializer} handles serialization and deserialization
+ * of integer-based registry ID arguments.
+ *
+ * This serializer is used for command arguments that refer to elements in Minecraft
+ * registries (e.g., items, entities, dimensions) by their numerical registry ID.
+ *
+ * Values are encoded as variable-length integers using {@link ProtocolUtils}
+ * for compact transmission.
+ */
public class RegistryIdArgumentSerializer implements ArgumentPropertySerializer {
static final RegistryIdArgumentSerializer REGISTRY_ID = new RegistryIdArgumentSerializer();
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryKeyArgument.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryKeyArgument.java
index 6d55b246fc..1c554e2179 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryKeyArgument.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryKeyArgument.java
@@ -28,6 +28,15 @@
import java.util.List;
import java.util.concurrent.CompletableFuture;
+/**
+ * Represents a Brigadier {@link ArgumentType} for registry keys, which are typically
+ * namespaced resource locations (e.g., {@code minecraft:diamond_sword}).
+ *
+ * This argument type reads an unquoted string from input and treats it as a raw registry
+ * key. It does not validate the format or resolve the key against a known registry.
+ *
+ * Examples include simple strings, namespaced keys, or numeric-like identifiers.
+ */
public class RegistryKeyArgument implements ArgumentType {
private static final List EXAMPLES = Arrays.asList("foo", "foo:bar", "012");
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryKeyArgumentList.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryKeyArgumentList.java
index 2bf5f34514..86fe95f1db 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryKeyArgumentList.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryKeyArgumentList.java
@@ -21,14 +21,25 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents a list of {@link RegistryKeyArgument} objects.
+ *
+ * Used to manage and store multiple registry key arguments.
+ */
public final class RegistryKeyArgumentList {
+ /**
+ * Represents a registry key argument that can either be a resource or a tag.
+ */
public static class ResourceOrTag extends RegistryKeyArgument {
public ResourceOrTag(String identifier) {
super(identifier);
}
+ /**
+ * Serializer for {@link ResourceOrTag}.
+ */
public static class Serializer implements ArgumentPropertySerializer {
static final ResourceOrTag.Serializer REGISTRY = new ResourceOrTag.Serializer();
@@ -45,12 +56,18 @@ public void serialize(ResourceOrTag object, ByteBuf buf, ProtocolVersion protoco
}
}
+ /**
+ * Represents a registry key argument specifically for a resource or tag key.
+ */
public static class ResourceOrTagKey extends RegistryKeyArgument {
public ResourceOrTagKey(String identifier) {
super(identifier);
}
+ /**
+ * Serializer for {@link ResourceOrTagKey}.
+ */
public static class Serializer implements ArgumentPropertySerializer {
static final ResourceOrTagKey.Serializer REGISTRY = new ResourceOrTagKey.Serializer();
@@ -67,12 +84,18 @@ public void serialize(ResourceOrTagKey object, ByteBuf buf, ProtocolVersion prot
}
}
+ /**
+ * Represents a registry key argument for a resource.
+ */
public static class ResourceSelector extends RegistryKeyArgument {
public ResourceSelector(String identifier) {
super(identifier);
}
+ /**
+ * Serializer for {@link ResourceSelector}.
+ */
public static class Serializer implements ArgumentPropertySerializer {
static final ResourceSelector.Serializer REGISTRY = new ResourceSelector.Serializer();
@@ -89,12 +112,18 @@ public void serialize(ResourceSelector object, ByteBuf buf, ProtocolVersion prot
}
}
+ /**
+ * Represents a registry key argument for a resource key.
+ */
public static class ResourceKey extends RegistryKeyArgument {
public ResourceKey(String identifier) {
super(identifier);
}
+ /**
+ * Serializer for {@link ResourceKey}.
+ */
public static class Serializer implements ArgumentPropertySerializer {
static final ResourceKey.Serializer REGISTRY = new ResourceKey.Serializer();
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryKeyArgumentSerializer.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryKeyArgumentSerializer.java
index 6ada6157b4..e2562c8534 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryKeyArgumentSerializer.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/RegistryKeyArgumentSerializer.java
@@ -21,6 +21,12 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * Serializer for {@link RegistryKeyArgument} objects.
+ *
+ * This class handles the serialization and deserialization of {@code RegistryKeyArgument}
+ * objects to and from a {@link ByteBuf} using the specified {@link ProtocolVersion}.
+ */
public class RegistryKeyArgumentSerializer implements
ArgumentPropertySerializer {
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/TimeArgumentSerializer.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/TimeArgumentSerializer.java
index b026e8cc1f..5e4d9cedee 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/TimeArgumentSerializer.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/TimeArgumentSerializer.java
@@ -20,6 +20,12 @@
import com.velocitypowered.api.network.ProtocolVersion;
import io.netty.buffer.ByteBuf;
+/**
+ * Serializer for time-based arguments represented as {@link Integer}.
+ *
+ * This class handles the serialization and deserialization of time-related arguments,
+ * converting them to and from an {@link Integer} format.
+ */
public class TimeArgumentSerializer implements ArgumentPropertySerializer {
static final TimeArgumentSerializer TIME = new TimeArgumentSerializer();
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatAcknowledgementPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatAcknowledgementPacket.java
index b0718090e9..c27c7199f5 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatAcknowledgementPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatAcknowledgementPacket.java
@@ -23,39 +23,44 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents a packet sent to acknowledge the receipt of a chat message.
+ * This packet is used to confirm that a player or client has received and processed
+ * a chat message from the server.
+ */
public class ChatAcknowledgementPacket implements MinecraftPacket {
- int offset;
-
- public ChatAcknowledgementPacket(int offset) {
- this.offset = offset;
- }
-
- public ChatAcknowledgementPacket() {
- }
-
- @Override
- public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
- offset = ProtocolUtils.readVarInt(buf);
- }
-
- @Override
- public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
- ProtocolUtils.writeVarInt(buf, offset);
- }
-
- @Override
- public boolean handle(MinecraftSessionHandler handler) {
- return handler.handle(this);
- }
-
- @Override
- public String toString() {
- return "ChatAcknowledgement{" +
- "offset=" + offset +
- '}';
- }
-
- public int offset() {
- return offset;
- }
+ int offset;
+
+ public ChatAcknowledgementPacket(int offset) {
+ this.offset = offset;
+ }
+
+ public ChatAcknowledgementPacket() {
+ }
+
+ @Override
+ public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
+ offset = ProtocolUtils.readVarInt(buf);
+ }
+
+ @Override
+ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
+ ProtocolUtils.writeVarInt(buf, offset);
+ }
+
+ @Override
+ public boolean handle(MinecraftSessionHandler handler) {
+ return handler.handle(this);
+ }
+
+ @Override
+ public String toString() {
+ return "ChatAcknowledgement{"
+ + "offset=" + offset
+ + '}';
+ }
+
+ public int offset() {
+ return offset;
+ }
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatHandler.java
index 0cd2f44afe..af67506b30 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatHandler.java
@@ -19,12 +19,28 @@
import com.velocitypowered.proxy.protocol.MinecraftPacket;
+/**
+ * Represents a handler for processing chat-related packets in the game.
+ * This interface is generic and can handle different types of Minecraft packets that
+ * extend {@link MinecraftPacket}.
+ *
+ * @param the type of packet that this chat handler processes, which must
+ * extend {@link MinecraftPacket}
+ */
public interface ChatHandler {
Class packetClass();
void handlePlayerChatInternal(T packet);
+ /**
+ * Handles a player chat event represented by the given {@link MinecraftPacket}.
+ * This default method provides a basic mechanism for processing chat-related packets that
+ * involve player messages.
+ *
+ * @param packet the {@link MinecraftPacket} representing the player chat event to handle
+ * @return {@code true} if the chat event was successfully handled, {@code false} otherwise
+ */
default boolean handlePlayerChat(MinecraftPacket packet) {
if (packetClass().isInstance(packet)) {
handlePlayerChatInternal(packetClass().cast(packet));
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatQueue.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatQueue.java
index 14a563368f..0869ab99a6 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatQueue.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatQueue.java
@@ -21,12 +21,12 @@
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import io.netty.channel.ChannelFuture;
-import org.checkerframework.checker.nullness.qual.Nullable;
import java.time.Instant;
import java.util.BitSet;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
+import org.checkerframework.checker.nullness.qual.Nullable;
/**
* A precisely ordered queue which allows for outside entries into the ordered queue through
@@ -79,7 +79,8 @@ private void queueTask(Task task) {
* @param timestamp the new {@link Instant} timestamp of this packet to update the internal chat state.
* @param lastSeenMessages the new {@link LastSeenMessages} last seen messages to update the internal chat state.
*/
- public void queuePacket(Function> nextPacket, @Nullable Instant timestamp, @Nullable LastSeenMessages lastSeenMessages) {
+ public void queuePacket(Function> nextPacket, @Nullable Instant timestamp,
+ @Nullable LastSeenMessages lastSeenMessages) {
queueTask((chatState, smc) -> {
LastSeenMessages newLastSeenMessages = chatState.updateFromMessage(timestamp, lastSeenMessages);
return nextPacket.apply(newLastSeenMessages).thenCompose(packet -> writePacket(packet, smc));
@@ -100,6 +101,12 @@ public void queuePacket(Function packe
});
}
+ /**
+ * Handles the acknowledgement of a chat message or event by processing the given offset.
+ * This method is typically called when a chat message or command is acknowledged by the client or server.
+ *
+ * @param offset the offset representing the specific message or event being acknowledged
+ */
public void handleAcknowledgement(int offset) {
queueTask((chatState, smc) -> {
int ackCountToForward = chatState.accumulateAckCount(offset);
@@ -138,16 +145,16 @@ private interface Task {
* - If we last forwarded a chat or command packet from the client, we have a known 'last seen' that we can
* reuse.
* - If we last forwarded a {@link ChatAcknowledgementPacket}, the previous 'last seen' cannot be reused. We
- * cannot predict an up-to-date 'last seen', as we do not know which messages the client actually saw.
+ * cannot predict an up to date 'last seen', as we do not know which messages the client actually saw.
* - Therefore, we need to hold back any acknowledgement packets so that we can continue to reuse the last valid
* 'last seen' state.
* - However, there is a limit to the number of messages that can remain unacknowledged on the server.
* - To address this, we know that if the client has moved its 'last seen' window far enough, we can fill in the
- * gap with dummy 'last seen', and it will never be checked.
+ * gap with stub 'last seen', and it will never be checked.
*
*
- * Note that this is effectively unused for 1.20.5+ clients, as commands without any signature do not send 'last seen'
- * updates.
+ * Note that this is effectively unused for 1.20.5+ clients, as commands without any signature do not send 'last seen'
+ * updates.
*/
public static class ChatState {
private static final int MINIMUM_DELAYED_ACK_COUNT = LastSeenMessages.WINDOW_SIZE;
@@ -160,6 +167,17 @@ public static class ChatState {
private ChatState() {
}
+ /**
+ * Updates the state of the {@link LastSeenMessages} and the timestamp based on a new message or event.
+ * This method processes the given timestamp and last seen messages to ensure the internal state is up to date.
+ * - If the provided {@link Instant} is not null, it updates the last known timestamp.
+ * - If the provided {@link LastSeenMessages} is not null, it flushes any delayed acknowledgements and updates the
+ * internal acknowledged messages, returning an adjusted {@link LastSeenMessages} with the offset applied.
+ *
+ * @param timestamp the optional {@link Instant} representing the new timestamp for the message or event
+ * @param lastSeenMessages the optional {@link LastSeenMessages} representing the last seen messages by the player
+ * @return the updated {@link LastSeenMessages} with the applied offset, or {@code null} if no updates were made
+ */
@Nullable
public LastSeenMessages updateFromMessage(@Nullable Instant timestamp, @Nullable LastSeenMessages lastSeenMessages) {
if (timestamp != null) {
@@ -174,6 +192,16 @@ public LastSeenMessages updateFromMessage(@Nullable Instant timestamp, @Nullable
return null;
}
+ /**
+ * Accumulates the given acknowledgement count and determines if enough acknowledgements have been gathered to forward.
+ * - Adds the provided `ackCount` to the current delayed acknowledgement count.
+ * - If the accumulated acknowledgements exceed the {@link LastSeenMessages#WINDOW_SIZE}, the method resets the delayed
+ * acknowledgement count and returns the number of acknowledgements that should be forwarded.
+ * - If the threshold is not met, the method returns 0, indicating that no acknowledgements need to be forwarded yet.
+ *
+ * @param ackCount the number of acknowledgements to add to the accumulated count
+ * @return the number of acknowledgements that should be forwarded, or 0 if the threshold has not been reached
+ */
public int accumulateAckCount(int ackCount) {
int delayedAckCount = this.delayedAckCount.addAndGet(ackCount);
int ackCountToForward = delayedAckCount - MINIMUM_DELAYED_ACK_COUNT;
@@ -186,6 +214,11 @@ public int accumulateAckCount(int ackCount) {
return 0;
}
+ /**
+ * Creates a snapshot of the current {@link LastSeenMessages} state.
+ *
+ * @return a new {@link LastSeenMessages} representing the current view
+ */
public LastSeenMessages createLastSeen() {
return new LastSeenMessages(0, lastSeenMessages, (byte) 0);
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatTimeKeeper.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatTimeKeeper.java
index 94fc535678..9409a86f5b 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatTimeKeeper.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatTimeKeeper.java
@@ -19,6 +19,11 @@
import java.time.Instant;
+/**
+ * Manages the timing and duration of chat messages within the game.
+ * The {@code ChatTimeKeeper} class tracks when chat messages are sent and provides mechanisms
+ * to determine how long a message has been displayed or to manage message expiration.
+ */
public class ChatTimeKeeper {
private Instant lastTimestamp;
@@ -27,6 +32,18 @@ public ChatTimeKeeper() {
this.lastTimestamp = Instant.MIN;
}
+ /**
+ * Updates the internal timestamp of the chat message or session.
+ * This method checks if the provided {@link Instant} is before the current stored timestamp.
+ * If it is, the internal timestamp is updated, and the method returns {@code false} to
+ * indicate that the update was not successful.
+ * If the provided {@link Instant} is valid, the timestamp is updated,
+ * and the method may return {@code true}.
+ *
+ * @param instant the {@link Instant} representing the new timestamp to update
+ * @return {@code true} if the timestamp was successfully updated, {@code false}
+ * if the provided instant is before the current timestamp
+ */
public boolean update(Instant instant) {
if (instant.isBefore(this.lastTimestamp)) {
this.lastTimestamp = instant;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatType.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatType.java
index 66e4e98841..047066159c 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatType.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ChatType.java
@@ -17,6 +17,12 @@
package com.velocitypowered.proxy.protocol.packet.chat;
+/**
+ * Represents different types of chat messages in the game, defining how a message should be
+ * handled and displayed.
+ * This enum categorizes various chat message types such as system messages, player chat,
+ * or game info.
+ */
public enum ChatType {
CHAT((byte) 0),
SYSTEM((byte) 1),
@@ -31,4 +37,4 @@ public enum ChatType {
public byte getId() {
return raw;
}
-}
\ No newline at end of file
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/CommandHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/CommandHandler.java
index 8e39d78a30..31cd85c377 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/CommandHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/CommandHandler.java
@@ -31,6 +31,14 @@
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a handler for processing commands associated with specific types of Minecraft packets.
+ * This interface is generic and allows for handling different packet types that extend
+ * {@link MinecraftPacket}.
+ *
+ * @param the type of packet that this handler is responsible for, which
+ * must extend {@link MinecraftPacket}
+ */
public interface CommandHandler {
Logger logger = LogManager.getLogger(CommandHandler.class);
@@ -39,6 +47,14 @@ public interface CommandHandler {
void handlePlayerCommandInternal(T packet);
+ /**
+ * Handles a player command associated with a given {@link MinecraftPacket}.
+ * This default method provides a mechanism for processing commands related to player
+ * actions within the game.
+ *
+ * @param packet the {@link MinecraftPacket} representing the player command to be handled
+ * @return {@code true} if the command was successfully handled, {@code false} otherwise
+ */
default boolean handlePlayerCommand(MinecraftPacket packet) {
if (packetClass().isInstance(packet)) {
handlePlayerCommandInternal(packetClass().cast(packet));
@@ -54,25 +70,45 @@ default CompletableFuture runCommand(VelocityServer server,
.thenApply(hasRunPacketFunction);
}
+ /**
+ * Queues the result of a player command for execution, managing the future result of the command.
+ * This method is designed to interact with the {@link VelocityServer}
+ * and {@link ConnectedPlayer} to
+ * handle the process of command execution, queuing, and response handling.
+ *
+ * @param server the {@link VelocityServer} instance responsible for managing the
+ * command execution
+ * @param player the {@link ConnectedPlayer} who initiated the command
+ * @param futurePacketCreator a {@link BiFunction} that creates a future packet based on
+ * the {@link CommandExecuteEvent}
+ * and {@link LastSeenMessages}, which will be used for sending
+ * a command result
+ * @param message the command message that the player sent
+ * @param timestamp the {@link Instant} when the command was executed
+ * @param lastSeenMessages the {@link LastSeenMessages} object containing the messages last
+ * seen by the player,
+ * or {@code null} if not applicable
+ * @param invocationInfo signing metadata for the event dispatch
+ */
default void queueCommandResult(VelocityServer server, ConnectedPlayer player,
BiFunction> futurePacketCreator,
String message, Instant timestamp, @Nullable LastSeenMessages lastSeenMessages,
CommandExecuteEvent.InvocationInfo invocationInfo) {
- CompletableFuture eventFuture = server.getCommandManager().callCommandEvent(player, message,
- invocationInfo);
- player.getChatQueue().queuePacket(
+ CompletableFuture eventFuture = server.getCommandManager().callCommandEvent(player, message,
+ invocationInfo);
+ player.getChatQueue().queuePacket(
newLastSeenMessages -> eventFuture
- .thenComposeAsync(event -> futurePacketCreator.apply(event, newLastSeenMessages))
- .thenApply(pkt -> {
- if (server.getConfiguration().isLogCommandExecutions()) {
- logger.info("{} -> executed command /{}", player, message);
- }
- return pkt;
- }).exceptionally(e -> {
- logger.info("Exception occurred while running command for {}", player.getUsername(), e);
- player.sendMessage(
- Component.translatable("velocity.command.generic-error", NamedTextColor.RED));
- return null;
- }), timestamp, lastSeenMessages);
+ .thenComposeAsync(event -> futurePacketCreator.apply(event, newLastSeenMessages))
+ .thenApply(pkt -> {
+ if (server.getConfiguration().isLogCommandExecutions()) {
+ logger.info("{} -> executed command /{}", player, message);
+ }
+ return pkt;
+ }).exceptionally(e -> {
+ logger.info("Exception occurred while running command for {}", player.getUsername(), e);
+ player.sendMessage(
+ Component.translatable("velocity.command.generic-error", NamedTextColor.RED));
+ return null;
+ }), timestamp, lastSeenMessages);
}
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ComponentHolder.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ComponentHolder.java
index 0b00332607..087756e1cd 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ComponentHolder.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ComponentHolder.java
@@ -25,6 +25,9 @@
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
import net.kyori.adventure.nbt.BinaryTag;
import net.kyori.adventure.nbt.BinaryTagIO;
import net.kyori.adventure.nbt.BinaryTagType;
@@ -47,10 +50,12 @@
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
+/**
+ * Represents a holder for components used in chat or other text-based data in the Minecraft
+ * protocol.
+ * This class supports various formats including JSON and NBT (Named Binary Tag) for storing and
+ * transmitting text components.
+ */
public class ComponentHolder {
private static final Logger logger = LogManager.getLogger(ComponentHolder.class);
public static final int DEFAULT_MAX_STRING_SIZE = 262143;
@@ -75,6 +80,14 @@ public ComponentHolder(ProtocolVersion version, BinaryTag binaryTag) {
this.binaryTag = binaryTag;
}
+ /**
+ * Retrieves the {@link Component} stored in this {@link ComponentHolder}.
+ * If the component is not yet initialized, it will attempt to deserialize it from either
+ * the JSON or NBT representation, depending on which is available.
+ *
+ * @return the {@link Component} stored in this holder
+ * @throws IllegalStateException if both the JSON and binary representations fail to deserialize
+ */
public Component getComponent() {
if (component == null) {
if (json != null) {
@@ -95,6 +108,13 @@ public Component getComponent() {
return component;
}
+ /**
+ * Retrieves the JSON representation of the {@link Component} stored in this
+ * {@link ComponentHolder}.
+ * If the JSON string is not yet initialized, it will serialize the component into a JSON string.
+ *
+ * @return the JSON string representing the {@link Component}
+ */
public String getJson() {
if (json == null) {
json = ProtocolUtils.getJsonChatSerializer(version).serialize(getComponent());
@@ -102,6 +122,14 @@ public String getJson() {
return json;
}
+ /**
+ * Retrieves the NBT (Named Binary Tag) representation of the {@link Component} stored in this
+ * {@link ComponentHolder}.
+ * If the NBT tag is not yet initialized, it will serialize the component into an NBT
+ * representation.
+ *
+ * @return the {@link BinaryTag} representing the {@link Component}
+ */
public BinaryTag getBinaryTag() {
if (binaryTag == null) {
// TODO: replace this with adventure-text-serializer-nbt
@@ -110,6 +138,16 @@ public BinaryTag getBinaryTag() {
return binaryTag;
}
+ /**
+ * Serializes a {@link JsonElement} into a {@link BinaryTag} format.
+ * This method converts JSON primitives (numbers, strings, booleans) and complex structures
+ * (arrays, objects)
+ * into their corresponding NBT representations.
+ *
+ * @param json the {@link JsonElement} to be serialized into a {@link BinaryTag}
+ * @return the {@link BinaryTag} representing the serialized JSON element
+ * @throws IllegalArgumentException if the JSON element is of an unsupported or unknown type
+ */
public static BinaryTag serialize(JsonElement json) {
if (json instanceof JsonPrimitive jsonPrimitive) {
if (jsonPrimitive.isNumber()) {
@@ -162,36 +200,40 @@ public static BinaryTag serialize(JsonElement json) {
}
switch (listType.id()) {
- case 1://BinaryTagTypes.BYTE:
+ case 1 -> { // BinaryTagTypes.BYTE:
byte[] bytes = new byte[jsonArray.size()];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = jsonArray.get(i).getAsNumber().byteValue();
}
return ByteArrayBinaryTag.byteArrayBinaryTag(bytes);
- case 3://BinaryTagTypes.INT:
+ }
+ case 3 -> { // BinaryTagTypes.INT:
int[] ints = new int[jsonArray.size()];
for (int i = 0; i < ints.length; i++) {
ints[i] = jsonArray.get(i).getAsNumber().intValue();
}
return IntArrayBinaryTag.intArrayBinaryTag(ints);
- case 4://BinaryTagTypes.LONG:
+ }
+ case 4 -> { // BinaryTagTypes.LONG:
long[] longs = new long[jsonArray.size()];
for (int i = 0; i < longs.length; i++) {
longs[i] = jsonArray.get(i).getAsNumber().longValue();
}
return LongArrayBinaryTag.longArrayBinaryTag(longs);
- case 10://BinaryTagTypes.COMPOUND:
- tagItems.replaceAll(tag -> {
- if (tag.type() == BinaryTagTypes.COMPOUND) {
- return tag;
- } else {
- return CompoundBinaryTag.builder().put("", tag).build();
- }
- });
- break;
+ }
+ case 10 -> // BinaryTagTypes.COMPOUND:
+ tagItems.replaceAll(tag -> {
+ if (tag.type() == BinaryTagTypes.COMPOUND) {
+ return tag;
+ } else {
+ return CompoundBinaryTag.builder().put("", tag).build();
+ }
+ });
+ default -> {
+ }
}
return ListBinaryTag.listBinaryTag(listType, tagItems);
@@ -200,21 +242,30 @@ public static BinaryTag serialize(JsonElement json) {
return EndBinaryTag.endBinaryTag();
}
+ /**
+ * Deserializes a {@link BinaryTag} into a {@link JsonElement}.
+ * This method converts NBT (Named Binary Tag) data into its corresponding JSON representation,
+ * including handling of primitive types, arrays, and compound structures.
+ *
+ * @param tag the {@link BinaryTag} to be deserialized into a {@link JsonElement}
+ * @return the {@link JsonElement} representing the deserialized NBT data
+ * @throws IllegalArgumentException if the NBT tag type is unsupported or unknown
+ */
public static JsonElement deserialize(BinaryTag tag) {
return switch (tag.type().id()) {
- //BinaryTagTypes.BYTE
+ // BinaryTagTypes.BYTE
case 1 -> new JsonPrimitive(((ByteBinaryTag) tag).value());
- //BinaryTagTypes.SHORT
+ // BinaryTagTypes.SHORT
case 2 -> new JsonPrimitive(((ShortBinaryTag) tag).value());
- //BinaryTagTypes.INT:
+ // BinaryTagTypes.INT:
case 3 -> new JsonPrimitive(((IntBinaryTag) tag).value());
- //BinaryTagTypes.LONG:
+ // BinaryTagTypes.LONG:
case 4 -> new JsonPrimitive(((LongBinaryTag) tag).value());
- //BinaryTagTypes.FLOAT:
+ // BinaryTagTypes.FLOAT:
case 5 -> new JsonPrimitive(((FloatBinaryTag) tag).value());
- //BinaryTagTypes.DOUBLE:
+ // BinaryTagTypes.DOUBLE:
case 6 -> new JsonPrimitive(((DoubleBinaryTag) tag).value());
- //BinaryTagTypes.BYTE_ARRAY:
+ // BinaryTagTypes.BYTE_ARRAY:
case 7 -> {
byte[] byteArray = ((ByteArrayBinaryTag) tag).value();
@@ -225,9 +276,9 @@ public static JsonElement deserialize(BinaryTag tag) {
yield jsonByteArray;
}
- //BinaryTagTypes.STRING:
+ // BinaryTagTypes.STRING:
case 8 -> new JsonPrimitive(((StringBinaryTag) tag).value());
- //BinaryTagTypes.LIST:
+ // BinaryTagTypes.LIST:
case 9 -> {
ListBinaryTag items = (ListBinaryTag) tag;
JsonArray jsonList = new JsonArray(items.size());
@@ -238,7 +289,7 @@ public static JsonElement deserialize(BinaryTag tag) {
yield jsonList;
}
- //BinaryTagTypes.COMPOUND:
+ // BinaryTagTypes.COMPOUND:
case 10 -> {
CompoundBinaryTag compound = (CompoundBinaryTag) tag;
JsonObject jsonObject = new JsonObject();
@@ -254,7 +305,7 @@ public static JsonElement deserialize(BinaryTag tag) {
yield jsonObject;
}
- //BinaryTagTypes.INT_ARRAY:
+ // BinaryTagTypes.INT_ARRAY:
case 11 -> {
int[] intArray = ((IntArrayBinaryTag) tag).value();
@@ -265,7 +316,7 @@ public static JsonElement deserialize(BinaryTag tag) {
yield jsonIntArray;
}
- //BinaryTagTypes.LONG_ARRAY:
+ // BinaryTagTypes.LONG_ARRAY:
case 12 -> {
long[] longArray = ((LongArrayBinaryTag) tag).value();
@@ -280,6 +331,19 @@ public static JsonElement deserialize(BinaryTag tag) {
};
}
+ /**
+ * Reads a {@link ComponentHolder} from the provided {@link ByteBuf} using the specified
+ * {@link ProtocolVersion}.
+ * This method deserializes a component from either its binary (NBT) or JSON representation,
+ * depending on the protocol version.
+ * - For Minecraft versions 1.20.3 and later, it reads a binary tag.
+ * - For Minecraft versions 1.13 and later, it reads a JSON string with a size limit.
+ * - For earlier versions, it reads a standard JSON string.
+ *
+ * @param buf the {@link ByteBuf} containing the serialized component data
+ * @param version the {@link ProtocolVersion} indicating how the component should be deserialized
+ * @return a {@link ComponentHolder} containing the deserialized component
+ */
public static ComponentHolder read(ByteBuf buf, ProtocolVersion version) {
if (version.noLessThan(ProtocolVersion.MINECRAFT_1_20_3)) {
return new ComponentHolder(version,
@@ -291,6 +355,15 @@ public static ComponentHolder read(ByteBuf buf, ProtocolVersion version) {
}
}
+ /**
+ * Writes the {@link ComponentHolder}'s data to the provided {@link ByteBuf}.
+ * This method serializes the component into either its binary (NBT) or JSON representation
+ * based on the protocol version.
+ * - For Minecraft versions 1.20.3 and later, it writes the component as a binary tag (NBT).
+ * - For earlier versions, it writes the component as a JSON string.
+ *
+ * @param buf the {@link ByteBuf} where the component data will be written
+ */
public void write(ByteBuf buf) {
if (version.noLessThan(ProtocolVersion.MINECRAFT_1_20_3)) {
ProtocolUtils.writeBinaryTag(buf, version, getBinaryTag());
@@ -298,4 +371,4 @@ public void write(ByteBuf buf) {
ProtocolUtils.writeString(buf, getJson());
}
}
-}
\ No newline at end of file
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/LastSeenMessages.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/LastSeenMessages.java
index c03e5f8c3f..8f41a6c832 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/LastSeenMessages.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/LastSeenMessages.java
@@ -23,6 +23,10 @@
import java.util.Arrays;
import java.util.BitSet;
+/**
+ * Represents a collection of the last seen messages by a player or client.
+ * This class tracks the recent chat messages that the player has viewed.
+ */
public class LastSeenMessages {
public static final int WINDOW_SIZE = 20;
@@ -35,12 +39,26 @@ public LastSeenMessages() {
this(0, new BitSet(), (byte) 0);
}
+ /**
+ * Creates a new {@link LastSeenMessages} instance with the specified offset, acknowledged messages, and checksum.
+ *
+ * @param offset the starting index of the message window
+ * @param acknowledged a BitSet representing which messages have been acknowledged
+ * @param checksum the checksum for the message window data
+ */
public LastSeenMessages(int offset, BitSet acknowledged, byte checksum) {
this.offset = offset;
this.acknowledged = acknowledged;
this.checksum = checksum;
}
+ /**
+ * Constructs a new {@link LastSeenMessages} instance by decoding data from the provided
+ * {@link ByteBuf}.
+ *
+ * @param buf the buffer containing the serialized last seen messages data
+ * @param protocolVersion the protocol version (determines if checksum is written)
+ */
public LastSeenMessages(ByteBuf buf, ProtocolVersion protocolVersion) {
this.offset = ProtocolUtils.readVarInt(buf);
@@ -53,6 +71,12 @@ public LastSeenMessages(ByteBuf buf, ProtocolVersion protocolVersion) {
}
}
+ /**
+ * Encodes this {@link LastSeenMessages} instance into the provided {@link ByteBuf}.
+ *
+ * @param buf the buffer to write the data to
+ * @param protocolVersion the protocol version used for encoding
+ */
public void encode(ByteBuf buf, ProtocolVersion protocolVersion) {
ProtocolUtils.writeVarInt(buf, offset);
buf.writeBytes(Arrays.copyOf(acknowledged.toByteArray(), DIV_FLOOR));
@@ -75,10 +99,10 @@ public LastSeenMessages offset(final int offset) {
@Override
public String toString() {
- return "LastSeenMessages{" +
- "offset=" + offset +
- ", acknowledged=" + acknowledged +
- ", checksum=" + checksum +
- '}';
+ return "LastSeenMessages{"
+ + "offset=" + offset
+ + ", acknowledged=" + acknowledged
+ + ", checksum=" + checksum
+ + '}';
}
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/PlayerChatCompletionPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/PlayerChatCompletionPacket.java
index d07b798a52..41b6f6cbf3 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/PlayerChatCompletionPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/PlayerChatCompletionPacket.java
@@ -23,6 +23,11 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents a packet sent between the server and client to handle chat completion suggestions.
+ * This packet allows the server to send chat message completions or suggestions to the client,
+ * helping users complete commands or chat messages.
+ */
public class PlayerChatCompletionPacket implements MinecraftPacket {
private String[] completions;
@@ -71,6 +76,9 @@ public boolean handle(MinecraftSessionHandler handler) {
return handler.handle(this);
}
+ /**
+ * Represents the different actions that can be taken with chat completions.
+ */
public enum Action {
ADD,
REMOVE,
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/RateLimitedCommandHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/RateLimitedCommandHandler.java
index e582364359..8ec1f5b22d 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/RateLimitedCommandHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/RateLimitedCommandHandler.java
@@ -22,37 +22,46 @@
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import net.kyori.adventure.text.Component;
+/**
+ * Abstract base class for handling rate-limited player command packets.
+ *
+ * Subclasses should implement {@link #handlePlayerCommandInternal(MinecraftPacket)} to define
+ * how individual command packets are processed. Rate limiting is enforced to prevent abuse.
+ *
+ * @param the type of {@link MinecraftPacket} this handler processes
+ */
public abstract class RateLimitedCommandHandler implements CommandHandler {
- private final Player player;
- private final VelocityServer velocityServer;
+ private final Player player;
+ private final VelocityServer velocityServer;
- private int failedAttempts;
+ private int failedAttempts;
- protected RateLimitedCommandHandler(Player player, VelocityServer velocityServer) {
- this.player = player;
- this.velocityServer = velocityServer;
- }
+ protected RateLimitedCommandHandler(Player player, VelocityServer velocityServer) {
+ this.player = player;
+ this.velocityServer = velocityServer;
+ }
- @Override
- public boolean handlePlayerCommand(MinecraftPacket packet) {
- if (packetClass().isInstance(packet)) {
- if (!velocityServer.getCommandRateLimiter().attempt(player.getUniqueId())) {
- if (velocityServer.getConfiguration().isKickOnCommandRateLimit() && failedAttempts++ >= velocityServer.getConfiguration().getKickAfterRateLimitedCommands()) {
- player.disconnect(Component.translatable("velocity.kick.command-rate-limit"));
- }
-
- if (velocityServer.getConfiguration().isForwardCommandsIfRateLimited()) {
- return false; // Send the packet to the server
- }
- } else {
- failedAttempts = 0;
- }
-
- handlePlayerCommandInternal(packetClass().cast(packet));
- return true;
+ @Override
+ public boolean handlePlayerCommand(MinecraftPacket packet) {
+ if (packetClass().isInstance(packet)) {
+ if (!velocityServer.getCommandRateLimiter().attempt(player.getUniqueId())) {
+ if (velocityServer.getConfiguration().isKickOnCommandRateLimit() && failedAttempts++
+ >= velocityServer.getConfiguration().getKickAfterRateLimitedCommands()) {
+ player.disconnect(Component.translatable("velocity.kick.command-rate-limit"));
}
- return false;
+ if (velocityServer.getConfiguration().isForwardCommandsIfRateLimited()) {
+ return false; // Send the packet to the server
+ }
+ } else {
+ failedAttempts = 0;
+ }
+
+ handlePlayerCommandInternal(packetClass().cast(packet));
+ return true;
}
+
+ return false;
+ }
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/RemoteChatSession.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/RemoteChatSession.java
index 9dd5950a97..13421cfbc6 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/RemoteChatSession.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/RemoteChatSession.java
@@ -26,6 +26,11 @@
import java.util.UUID;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a remote chat session that implements the {@link ChatSession} interface.
+ * This session is used for handling chat interactions that occur remotely, typically between
+ * a client and server, allowing for communication and session tracking.
+ */
public class RemoteChatSession implements ChatSession {
private final @Nullable UUID sessionId;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/SystemChatPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/SystemChatPacket.java
index 1a26affda4..a15aac01f9 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/SystemChatPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/SystemChatPacket.java
@@ -23,6 +23,11 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * Represents a packet sent from the server to the client to display system chat messages.
+ * This packet handles the communication of messages that are not player-generated, but instead
+ * come from the system or server itself.
+ */
public class SystemChatPacket implements MinecraftPacket {
public SystemChatPacket() {
@@ -47,7 +52,7 @@ public ComponentHolder getComponent() {
@Override
public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
component = ComponentHolder.read(buf, version);
- if (version.noLessThan(ProtocolVersion.MINECRAFT_1_19_1)){
+ if (version.noLessThan(ProtocolVersion.MINECRAFT_1_19_1)) {
type = buf.readBoolean() ? ChatType.GAME_INFO : ChatType.SYSTEM;
} else {
type = ChatType.values()[ProtocolUtils.readVarInt(buf)];
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/builder/ChatBuilderFactory.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/builder/ChatBuilderFactory.java
index b0d2f12af0..ac889a52b4 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/builder/ChatBuilderFactory.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/builder/ChatBuilderFactory.java
@@ -23,11 +23,22 @@
import com.velocitypowered.proxy.protocol.packet.chat.session.SessionChatBuilder;
import java.util.function.Function;
+/**
+ * Factory class for creating instances of chat builders.
+ *
+ * The {@code ChatBuilderFactory} is responsible for providing various builder instances
+ * used to construct chat-related components, such as messages, chat formats, or text components.
+ */
public class ChatBuilderFactory {
private final ProtocolVersion version;
private final Function builderFunction;
+ /**
+ * Creates a new {@code ChatBuilderFactory} for the specified protocol version.
+ *
+ * @param version the protocol version to be used by the chat builder factory
+ */
public ChatBuilderFactory(ProtocolVersion version) {
this.version = version;
if (version.noLessThan(ProtocolVersion.MINECRAFT_1_19_3)) {
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/builder/ChatBuilderV2.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/builder/ChatBuilderV2.java
index 9ac0286460..18cea35a2c 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/builder/ChatBuilderV2.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/builder/ChatBuilderV2.java
@@ -28,6 +28,13 @@
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * An abstract class for building chat components in version 2 of the chat system.
+ *
+ * The {@code ChatBuilderV2} class provides the foundation for creating and formatting
+ * chat components, allowing subclasses to implement specific behaviors for constructing
+ * chat messages or text components.
+ */
public abstract class ChatBuilderV2 {
protected final ProtocolVersion version;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedChatBuilder.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedChatBuilder.java
index d654c619c7..b8cd4f79d3 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedChatBuilder.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedChatBuilder.java
@@ -26,6 +26,12 @@
import com.velocitypowered.proxy.protocol.packet.chat.builder.ChatBuilderV2;
import net.kyori.adventure.text.Component;
+/**
+ * A concrete implementation of {@link ChatBuilderV2} that uses keys to build chat components.
+ *
+ * The {@code KeyedChatBuilder} class extends the functionality of {@link ChatBuilderV2} by allowing
+ * chat components to be built using specific keys, enabling dynamic message construction.
+ */
public class KeyedChatBuilder extends ChatBuilderV2 {
public KeyedChatBuilder(ProtocolVersion version) {
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedChatHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedChatHandler.java
index f8fc906abb..edc2268bcc 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedChatHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedChatHandler.java
@@ -30,6 +30,13 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+/**
+ * A handler for processing chat components based on specific keys.
+ *
+ * The {@code KeyedChatHandler} class is responsible for managing chat interactions or
+ * messages that keys identify. It implements the required interface or class
+ * to handle key-based chat processing.
+ */
public class KeyedChatHandler implements
com.velocitypowered.proxy.protocol.packet.chat.ChatHandler {
@@ -48,6 +55,15 @@ public Class packetClass() {
return KeyedPlayerChatPacket.class;
}
+ /**
+ * Logs an error and disconnects the player when a plugin attempts to cancel a signed chat message.
+ *
+ * This method handles the invalid behavior of canceling signed chat messages, which is no longer allowed
+ * starting from Minecraft version 1.19.1.
+ *
+ * @param logger the logger used to log the error
+ * @param player the player to disconnect due to the illegal action
+ */
public static void invalidCancel(Logger logger, ConnectedPlayer player) {
logger.fatal("A plugin tried to cancel a signed chat message."
+ " This is no longer possible in 1.19.1 and newer. "
@@ -56,6 +72,15 @@ public static void invalidCancel(Logger logger, ConnectedPlayer player) {
+ "Contact your network administrator."));
}
+ /**
+ * Logs an error and disconnects the player when a plugin attempts to modify a signed chat message.
+ *
+ * This method handles the invalid behavior of modifying signed chat messages, which is no longer allowed
+ * starting from Minecraft version 1.19.1.
+ *
+ * @param logger the logger used to log the error
+ * @param player the player to disconnect due to the illegal action
+ */
public static void invalidChange(Logger logger, ConnectedPlayer player) {
logger.fatal("A plugin tried to change a signed chat message. "
+ "This is no longer possible in 1.19.1 and newer. "
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedCommandHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedCommandHandler.java
index b10332f026..1be3ddddc5 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedCommandHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedCommandHandler.java
@@ -26,11 +26,24 @@
import java.util.concurrent.CompletableFuture;
import net.kyori.adventure.text.Component;
+/**
+ * Handles keyed player commands by implementing {@link RateLimitedCommandHandler}.
+ *
+ * The {@code KeyedCommandHandler} processes commands that are sent using
+ * {@link KeyedPlayerCommandPacket}. It provides the necessary logic for handling
+ * and executing commands associated with specific keys.
+ */
public class KeyedCommandHandler extends RateLimitedCommandHandler {
private final ConnectedPlayer player;
private final VelocityServer server;
+ /**
+ * Constructs a new {@code KeyedCommandHandler}.
+ *
+ * @param player the player sending the command
+ * @param server the proxy server instance
+ */
public KeyedCommandHandler(ConnectedPlayer player, VelocityServer server) {
super(player, server);
this.player = player;
@@ -112,6 +125,7 @@ public void handlePlayerCommandInternal(KeyedPlayerCommandPacket packet) {
}
return null;
});
- }, packet.getCommand(), packet.getTimestamp(), null, new CommandExecuteEvent.InvocationInfo(CommandExecuteEvent.SignedState.UNSUPPORTED, CommandExecuteEvent.Source.PLAYER));
+ }, packet.getCommand(), packet.getTimestamp(), null, new CommandExecuteEvent.InvocationInfo(
+ CommandExecuteEvent.SignedState.UNSUPPORTED, CommandExecuteEvent.Source.PLAYER));
}
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedPlayerChatPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedPlayerChatPacket.java
index 74fa88f5a5..bd62ad368b 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedPlayerChatPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedPlayerChatPacket.java
@@ -29,6 +29,13 @@
import java.time.Instant;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a player chat packet with support for message signing and preview.
+ *
+ * The {@code KeyedPlayerChatPacket} handles player chat messages, supporting signed previews,
+ * message signatures, and previous message validation. It includes fields for tracking message
+ * signatures and handling expired messages.
+ */
public class KeyedPlayerChatPacket implements MinecraftPacket {
private String message;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedPlayerCommandPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedPlayerCommandPacket.java
index 0bb43ec8e9..9978243f5c 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedPlayerCommandPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedPlayerCommandPacket.java
@@ -35,6 +35,13 @@
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a player command packet with support for keyed commands.
+ *
+ * The {@code KeyedPlayerCommandPacket} handles player commands sent to the server,
+ * allowing for command execution based on specific keys. This packet can include additional
+ * information such as arguments and key-based identifiers for the command.
+ */
public class KeyedPlayerCommandPacket implements MinecraftPacket {
private static final int MAX_NUM_ARGUMENTS = 8;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatBuilder.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatBuilder.java
index 77df43bb42..f61661e277 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatBuilder.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatBuilder.java
@@ -25,6 +25,13 @@
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component;
+/**
+ * A concrete implementation of {@link ChatBuilderV2} for handling legacy chat formats.
+ *
+ * The {@code LegacyChatBuilder} is designed to support and build chat components
+ * using legacy chat formatting, such as the formats used in earlier versions of Minecraft.
+ * It extends the functionality of {@link ChatBuilderV2} to cater to older chat systems.
+ */
public class LegacyChatBuilder extends ChatBuilderV2 {
public LegacyChatBuilder(ProtocolVersion version) {
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatHandler.java
index b7a641ca98..71dc842af7 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatHandler.java
@@ -23,6 +23,13 @@
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.protocol.packet.chat.ChatHandler;
+/**
+ * A handler for processing legacy chat packets, implementing {@link ChatHandler}.
+ *
+ * The {@code LegacyChatHandler} is responsible for handling and processing chat messages
+ * sent using {@link LegacyChatPacket}. This class provides the necessary logic for
+ * processing chat data using legacy Minecraft chat formats.
+ */
public class LegacyChatHandler implements ChatHandler {
private final VelocityServer server;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatPacket.java
index 80b239d53b..b00fb1654f 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatPacket.java
@@ -25,6 +25,13 @@
import java.util.UUID;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a legacy chat packet used in older versions of Minecraft.
+ *
+ * The {@code LegacyChatPacket} is responsible for holding and transmitting chat messages
+ * in the format used by legacy versions of Minecraft. It implements {@link MinecraftPacket}
+ * to ensure compatibility with the packet-handling system.
+ */
public class LegacyChatPacket implements MinecraftPacket {
public static final byte CHAT_TYPE = (byte) 0;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyCommandHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyCommandHandler.java
index 4f88ee34a6..3d5a7f5f88 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyCommandHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyCommandHandler.java
@@ -21,15 +21,27 @@
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.protocol.packet.chat.RateLimitedCommandHandler;
-
import java.time.Instant;
import java.util.concurrent.CompletableFuture;
+/**
+ * A handler for processing legacy commands, implementing {@link RateLimitedCommandHandler}.
+ *
+ * The {@code LegacyCommandHandler} processes and handles command packets that are sent
+ * using {@link LegacyChatPacket}. It provides the necessary logic to support legacy
+ * command formats and ensure compatibility with older Minecraft versions.
+ */
public class LegacyCommandHandler extends RateLimitedCommandHandler {
private final ConnectedPlayer player;
private final VelocityServer server;
+ /**
+ * Constructs a new {@code LegacyCommandHandler} for handling legacy command packets.
+ *
+ * @param player the connected player issuing the command
+ * @param server the Velocity server instance
+ */
public LegacyCommandHandler(ConnectedPlayer player, VelocityServer server) {
super(player, server);
this.player = player;
@@ -64,6 +76,7 @@ public void handlePlayerCommandInternal(LegacyChatPacket packet) {
}
return null;
});
- }, command, Instant.now(), null, new CommandExecuteEvent.InvocationInfo(CommandExecuteEvent.SignedState.UNSUPPORTED, CommandExecuteEvent.Source.PLAYER));
+ }, command, Instant.now(), null, new CommandExecuteEvent.InvocationInfo(
+ CommandExecuteEvent.SignedState.UNSUPPORTED, CommandExecuteEvent.Source.PLAYER));
}
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionChatBuilder.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionChatBuilder.java
index eb74123fc7..8c9078a10d 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionChatBuilder.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionChatBuilder.java
@@ -26,6 +26,13 @@
import com.velocitypowered.proxy.protocol.packet.chat.builder.ChatBuilderV2;
import net.kyori.adventure.text.Component;
+/**
+ * A concrete implementation of {@link ChatBuilderV2} for handling session-based chat messages.
+ *
+ * The {@code SessionChatBuilder} is designed to build chat components that are specific to
+ * a player's session, allowing customization and context-specific formatting of chat messages
+ * within the current session.
+ */
public class SessionChatBuilder extends ChatBuilderV2 {
public SessionChatBuilder(ProtocolVersion version) {
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionChatHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionChatHandler.java
index 74b5747f92..621564a1ad 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionChatHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionChatHandler.java
@@ -26,11 +26,17 @@
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.protocol.packet.chat.ChatHandler;
import com.velocitypowered.proxy.protocol.packet.chat.ChatQueue;
+import java.util.concurrent.CompletableFuture;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import java.util.concurrent.CompletableFuture;
-
+/**
+ * A handler for processing session-based chat packets, implementing {@link ChatHandler}.
+ *
+ * The {@code SessionChatHandler} processes and handles chat messages sent during a player's
+ * session using {@link SessionPlayerChatPacket}. It provides the logic for handling session-specific
+ * chat messages, ensuring the correct context and formatting within the session.
+ */
public class SessionChatHandler implements ChatHandler {
private static final Logger logger = LogManager.getLogger(SessionChatHandler.class);
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionCommandHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionCommandHandler.java
index 6978f8ee26..83d10b5d3c 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionCommandHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionCommandHandler.java
@@ -22,17 +22,29 @@
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.packet.chat.ChatAcknowledgementPacket;
-import java.util.concurrent.CompletableFuture;
-
import com.velocitypowered.proxy.protocol.packet.chat.RateLimitedCommandHandler;
+import java.util.concurrent.CompletableFuture;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * A handler for processing session-based commands, implementing {@link RateLimitedCommandHandler}.
+ *
+ * The {@code SessionCommandHandler} is responsible for handling commands that are specific
+ * to a player's session, using {@link SessionPlayerCommandPacket}. It provides logic to
+ * process commands that are tied to the context of the current session.
+ */
public class SessionCommandHandler extends RateLimitedCommandHandler {
private final ConnectedPlayer player;
private final VelocityServer server;
+ /**
+ * Constructs a new {@link SessionCommandHandler} for the specified player and server.
+ *
+ * @param player the connected player associated with this handler
+ * @param server the Velocity server instance
+ */
public SessionCommandHandler(ConnectedPlayer player, VelocityServer server) {
super(player, server);
this.player = player;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionPlayerChatPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionPlayerChatPacket.java
index 8a00452c6c..4a63665c23 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionPlayerChatPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionPlayerChatPacket.java
@@ -25,6 +25,13 @@
import io.netty.buffer.ByteBuf;
import java.time.Instant;
+/**
+ * Represents a player chat packet specific to a session, implementing {@link MinecraftPacket}.
+ *
+ * The {@code SessionPlayerChatPacket} handles chat messages sent by a player during a session,
+ * and may include session-specific context, such as timestamps, message formatting, or other
+ * relevant session data.
+ */
public class SessionPlayerChatPacket implements MinecraftPacket {
protected String message;
@@ -100,6 +107,15 @@ protected static byte[] readMessageSignature(ByteBuf buf) {
return signature;
}
+ /**
+ * Creates a new {@code SessionPlayerChatPacket} with the specified last-seen messages.
+ *
+ * This method constructs a new {@code SessionPlayerChatPacket} instance that retains the
+ * current packet's properties, while updating the last seen messages.
+ *
+ * @param lastSeenMessages the last seen messages to associate with the new packet
+ * @return a new {@code SessionPlayerChatPacket} with the updated last seen messages
+ */
public SessionPlayerChatPacket withLastSeenMessages(LastSeenMessages lastSeenMessages) {
SessionPlayerChatPacket packet = new SessionPlayerChatPacket();
packet.message = message;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionPlayerCommandPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionPlayerCommandPacket.java
index f4ea3a1e2d..8a7ddd0dc1 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionPlayerCommandPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionPlayerCommandPacket.java
@@ -26,11 +26,17 @@
import com.velocitypowered.proxy.protocol.packet.chat.LastSeenMessages;
import com.velocitypowered.proxy.util.except.QuietDecoderException;
import io.netty.buffer.ByteBuf;
-import org.checkerframework.checker.nullness.qual.Nullable;
-
import java.time.Instant;
import java.util.List;
+import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents a packet that handles player commands in a Minecraft session.
+ *
+ * This packet contains information about the player's command, timestamp,
+ * salt, argument signatures, and last seen messages for verification and
+ * processing.
+ */
public class SessionPlayerCommandPacket implements MinecraftPacket {
protected String command;
@@ -71,7 +77,8 @@ public boolean isSigned() {
}
public CommandExecuteEvent.SignedState getEventSignedState() {
- return !this.argumentSignatures.isEmpty() ? CommandExecuteEvent.SignedState.SIGNED_WITH_ARGS : CommandExecuteEvent.SignedState.SIGNED_WITHOUT_ARGS;
+ return !this.argumentSignatures.isEmpty() ? CommandExecuteEvent.SignedState.SIGNED_WITH_ARGS
+ : CommandExecuteEvent.SignedState.SIGNED_WITHOUT_ARGS;
}
@Override
@@ -81,15 +88,26 @@ public boolean handle(MinecraftSessionHandler handler) {
@Override
public String toString() {
- return "SessionPlayerCommand{" +
- "command='" + command + '\'' +
- ", timeStamp=" + timeStamp +
- ", salt=" + salt +
- ", argumentSignatures=" + argumentSignatures +
- ", lastSeenMessages=" + lastSeenMessages +
- '}';
+ return "SessionPlayerCommand{"
+ + "command='" + command + '\''
+ + ", timeStamp=" + timeStamp
+ + ", salt=" + salt
+ + ", argumentSignatures=" + argumentSignatures
+ + ", lastSeenMessages=" + lastSeenMessages
+ + '}';
}
+ /**
+ * Returns a new instance of {@code SessionPlayerCommandPacket} with the specified
+ * {@code LastSeenMessages}.
+ *
+ * If {@code lastSeenMessages} is null, it creates an {@code UnsignedPlayerCommandPacket}
+ * instead. Otherwise, it creates a new {@code SessionPlayerCommandPacket} with the
+ * provided {@code lastSeenMessages}.
+ *
+ * @param lastSeenMessages the last seen messages to include in the packet, may be {@code null}
+ * @return a new instance of {@code SessionPlayerCommandPacket} or {@code UnsignedPlayerCommandPacket}
+ */
public SessionPlayerCommandPacket withLastSeenMessages(@Nullable LastSeenMessages lastSeenMessages) {
if (lastSeenMessages == null) {
UnsignedPlayerCommandPacket packet = new UnsignedPlayerCommandPacket();
@@ -105,6 +123,12 @@ public SessionPlayerCommandPacket withLastSeenMessages(@Nullable LastSeenMessage
return packet;
}
+ /**
+ * Represents a collection of argument signatures for commands.
+ *
+ * This class is responsible for handling the encoding and decoding of
+ * argument signatures associated with a player command in a Minecraft session.
+ */
public static class ArgumentSignatures {
private final List entries;
@@ -113,6 +137,16 @@ public ArgumentSignatures() {
this.entries = List.of();
}
+ /**
+ * Constructs an {@code ArgumentSignatures} instance by decoding the signatures
+ * from the provided {@code ByteBuf}.
+ *
+ * This constructor reads the argument signatures from the buffer and ensures
+ * that the number of signatures does not exceed the allowed limit.
+ *
+ * @param buf the {@code ByteBuf} to decode the argument signatures from
+ * @throws QuietDecoderException if the number of argument signatures exceeds the allowed limit
+ */
public ArgumentSignatures(ByteBuf buf) {
int size = ProtocolUtils.readVarInt(buf);
if (size > 8) {
@@ -130,20 +164,44 @@ public boolean isEmpty() {
return this.entries.isEmpty();
}
+ /**
+ * Encodes the argument signatures into the provided {@code ByteBuf}.
+ *
+ * This method writes the number of argument signatures and each signature's
+ * details into the buffer for transmission.
+ *
+ * @param buf the {@code ByteBuf} to encode the argument signatures into
+ */
public void encode(ByteBuf buf) {
ProtocolUtils.writeVarInt(buf, entries.size());
for (ArgumentSignature entry : entries) {
entry.encode(buf);
}
}
+
+ /**
+ * Returns a string representation of this {@code ArgumentSignatures} instance.
+ *
+ * The output includes a list of individual {@link ArgumentSignature} entries
+ * attached to this command packet.
+ *
+ * @return a human-readable string describing the argument signatures
+ */
@Override
public String toString() {
- return "ArgumentSignatures{" +
- "entries=" + entries +
- '}';
+ return "ArgumentSignatures{"
+ + "entries=" + entries
+ + '}';
}
}
+ /**
+ * Represents a single argument signature associated with a command.
+ *
+ * This class is responsible for handling the encoding and decoding of
+ * individual argument signatures, which consist of a name and a signature
+ * (byte array).
+ */
public static class ArgumentSignature {
private final String name;
@@ -161,9 +219,9 @@ public void encode(ByteBuf buf) {
@Override
public String toString() {
- return "ArgumentSignature{" +
- "name='" + name + '\'' +
- '}';
+ return "ArgumentSignature{"
+ + "name='" + name + '\''
+ + '}';
}
}
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/UnsignedPlayerCommandPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/UnsignedPlayerCommandPacket.java
index 915f0cfbc7..1953b07f0c 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/UnsignedPlayerCommandPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/UnsignedPlayerCommandPacket.java
@@ -24,6 +24,13 @@
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * Represents an unsigned player command packet, extending {@link SessionPlayerCommandPacket}.
+ *
+ * The {@code UnsignedPlayerCommandPacket} is used to handle player commands that are not
+ * signed. It inherits session-specific behavior from {@link SessionPlayerCommandPacket}
+ * while indicating that the command is unsigned.
+ */
public class UnsignedPlayerCommandPacket extends SessionPlayerCommandPacket {
@Override
@@ -52,8 +59,8 @@ public CommandExecuteEvent.SignedState getEventSignedState() {
@Override
public String toString() {
- return "UnsignedPlayerCommandPacket{" +
- "command='" + command + '\'' +
- '}';
+ return "UnsignedPlayerCommandPacket{"
+ + "command='" + command + '\''
+ + '}';
}
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/ActiveFeaturesPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/ActiveFeaturesPacket.java
index 79c94b641b..50052654f3 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/ActiveFeaturesPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/ActiveFeaturesPacket.java
@@ -24,6 +24,13 @@
import io.netty.buffer.ByteBuf;
import net.kyori.adventure.key.Key;
+/**
+ * The {@code ActiveFeaturesPacket} class represents a packet that communicates the currently
+ * active features between the client and server in the Minecraft protocol.
+ *
+ * This packet is used to inform the client about which features are enabled or active,
+ * potentially based on server configurations or gameplay states.
+ */
public class ActiveFeaturesPacket implements MinecraftPacket {
private Key[] activeFeatures;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/ClientboundCustomReportDetailsPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/ClientboundCustomReportDetailsPacket.java
index 6a3618cb73..a9b415e9c8 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/ClientboundCustomReportDetailsPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/ClientboundCustomReportDetailsPacket.java
@@ -25,43 +25,47 @@
import java.util.HashMap;
import java.util.Map;
+/**
+ * Represents a packet sent from the server to the client, containing custom report details.
+ * This packet carries a map of key-value pairs, where each key and value are strings.
+ */
public class ClientboundCustomReportDetailsPacket implements MinecraftPacket {
- private Map details;
+ private Map details;
- public ClientboundCustomReportDetailsPacket() {
- }
+ public ClientboundCustomReportDetailsPacket() {
+ }
- public ClientboundCustomReportDetailsPacket(Map details) {
- this.details = details;
- }
+ public ClientboundCustomReportDetailsPacket(Map details) {
+ this.details = details;
+ }
- @Override
- public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
- int detailsCount = ProtocolUtils.readVarInt(buf);
+ @Override
+ public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
+ int detailsCount = ProtocolUtils.readVarInt(buf);
- this.details = new HashMap<>(detailsCount);
- for (int i = 0; i < detailsCount; i++) {
- details.put(ProtocolUtils.readString(buf), ProtocolUtils.readString(buf));
- }
+ this.details = new HashMap<>(detailsCount);
+ for (int i = 0; i < detailsCount; i++) {
+ details.put(ProtocolUtils.readString(buf), ProtocolUtils.readString(buf));
}
+ }
- @Override
- public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
- ProtocolUtils.writeVarInt(buf, details.size());
+ @Override
+ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
+ ProtocolUtils.writeVarInt(buf, details.size());
- details.forEach((key, detail) -> {
- ProtocolUtils.writeString(buf, key);
- ProtocolUtils.writeString(buf, detail);
- });
- }
+ details.forEach((key, detail) -> {
+ ProtocolUtils.writeString(buf, key);
+ ProtocolUtils.writeString(buf, detail);
+ });
+ }
- @Override
- public boolean handle(MinecraftSessionHandler handler) {
- return handler.handle(this);
- }
+ @Override
+ public boolean handle(MinecraftSessionHandler handler) {
+ return handler.handle(this);
+ }
- public Map getDetails() {
- return details;
- }
+ public Map getDetails() {
+ return details;
+ }
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/ClientboundServerLinksPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/ClientboundServerLinksPacket.java
index d37866d86a..58b531c27c 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/ClientboundServerLinksPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/ClientboundServerLinksPacket.java
@@ -18,7 +18,6 @@
package com.velocitypowered.proxy.protocol.packet.config;
import com.velocitypowered.api.network.ProtocolVersion;
-import com.velocitypowered.api.util.ServerLink;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
@@ -27,64 +26,78 @@
import java.util.ArrayList;
import java.util.List;
+/**
+ * Represents a packet sent from the server to the client, containing server-related links.
+ * This packet carries a list of links (e.g., URLs or other resources) associated with the server.
+ */
public class ClientboundServerLinksPacket implements MinecraftPacket {
- private List serverLinks;
+ private List serverLinks;
- public ClientboundServerLinksPacket() {
- }
+ public ClientboundServerLinksPacket() {
+ }
- public ClientboundServerLinksPacket(List serverLinks) {
- this.serverLinks = serverLinks;
- }
+ public ClientboundServerLinksPacket(List serverLinks) {
+ this.serverLinks = serverLinks;
+ }
- @Override
- public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
- int linksCount = ProtocolUtils.readVarInt(buf);
+ @Override
+ public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
+ int linksCount = ProtocolUtils.readVarInt(buf);
- this.serverLinks = new ArrayList<>(linksCount);
- for (int i = 0; i < linksCount; i++) {
- serverLinks.add(ServerLink.read(buf, version));
- }
+ this.serverLinks = new ArrayList<>(linksCount);
+ for (int i = 0; i < linksCount; i++) {
+ serverLinks.add(ServerLink.read(buf, version));
}
+ }
- @Override
- public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
- ProtocolUtils.writeVarInt(buf, serverLinks.size());
+ @Override
+ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
+ ProtocolUtils.writeVarInt(buf, serverLinks.size());
- for (ServerLink serverLink : serverLinks) {
- serverLink.write(buf);
- }
+ for (ServerLink serverLink : serverLinks) {
+ serverLink.write(buf);
}
+ }
- @Override
- public boolean handle(MinecraftSessionHandler handler) {
- return handler.handle(this);
- }
+ @Override
+ public boolean handle(MinecraftSessionHandler handler) {
+ return handler.handle(this);
+ }
- public List getServerLinks() {
- return serverLinks;
- }
+ public List getServerLinks() {
+ return serverLinks;
+ }
- public record ServerLink(int id, ComponentHolder displayName, String url) {
+ /**
+ * Represents a link to a server with an ID, display name, and URL.
+ *
+ * This record holds the server's identification number, a display name
+ * encapsulated in a {@code ComponentHolder}, and the server's URL as a string.
+ *
+ * @param id the unique identifier for the server
+ * @param displayName the display name of the server, represented by a {@code ComponentHolder}
+ * @param url the URL of the server
+ */
+ public record ServerLink(int id, ComponentHolder displayName, String url) {
- private static ServerLink read(ByteBuf buf, ProtocolVersion version) {
- if (buf.readBoolean()) {
- return new ServerLink(ProtocolUtils.readVarInt(buf), null, ProtocolUtils.readString(buf));
- } else {
- return new ServerLink(-1, ComponentHolder.read(buf, version), ProtocolUtils.readString(buf));
- }
- }
+ private static ServerLink read(ByteBuf buf, ProtocolVersion version) {
+ if (buf.readBoolean()) {
+ return new ServerLink(ProtocolUtils.readVarInt(buf), null, ProtocolUtils.readString(buf));
+ } else {
+ return new ServerLink(-1, ComponentHolder.read(buf, version), ProtocolUtils.readString(buf));
+ }
+ }
- private void write(ByteBuf buf) {
- if (id >= 0) {
- buf.writeBoolean(true);
- ProtocolUtils.writeVarInt(buf, id);
- } else {
- buf.writeBoolean(false);
- displayName.write(buf);
- }
- ProtocolUtils.writeString(buf, url);
- }
+ private void write(ByteBuf buf) {
+ if (id >= 0) {
+ buf.writeBoolean(true);
+ ProtocolUtils.writeVarInt(buf, id);
+ } else {
+ buf.writeBoolean(false);
+ displayName.write(buf);
+ }
+ ProtocolUtils.writeString(buf, url);
}
+ }
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductAcceptPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductAcceptPacket.java
index e9811f9fc2..07ca9c4bda 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductAcceptPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductAcceptPacket.java
@@ -23,6 +23,12 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
import io.netty.buffer.ByteBuf;
+/**
+ * A client-to-server packet indicating the player has accepted the server's
+ * code of conduct during the configuration stage.
+ *
+ * This packet has no payload and is represented as a singleton.
+ */
public class CodeOfConductAcceptPacket implements MinecraftPacket {
public static final CodeOfConductAcceptPacket INSTANCE = new CodeOfConductAcceptPacket();
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductPacket.java
index 41433307ef..11f934ebf1 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductPacket.java
@@ -24,6 +24,13 @@
import com.velocitypowered.proxy.protocol.util.DeferredByteBufHolder;
import io.netty.buffer.ByteBuf;
+/**
+ * The {@code FinishedUpdatePacket} class represents a packet that signals the completion
+ * of an update process between the client and server in the Minecraft protocol.
+ *
+ * This packet is used to indicate that the client has finished receiving and processing
+ * an update, ensuring that further operations can proceed.
+ */
public class CodeOfConductPacket extends DeferredByteBufHolder implements MinecraftPacket {
public CodeOfConductPacket() {
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/FinishedUpdatePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/FinishedUpdatePacket.java
index 20d40fd4be..5a2afea5d1 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/FinishedUpdatePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/FinishedUpdatePacket.java
@@ -23,6 +23,13 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * The {@code FinishedUpdatePacket} class represents a packet that signals the completion
+ * of an update process between the client and server in the Minecraft protocol.
+ *
+ * This packet is used to indicate that the client has finished receiving and processing
+ * an update, ensuring that further operations can proceed.
+ */
public class FinishedUpdatePacket implements MinecraftPacket {
public static final FinishedUpdatePacket INSTANCE = new FinishedUpdatePacket();
@@ -41,7 +48,7 @@ public void encode(ByteBuf buf, ProtocolUtils.Direction direction,
@Override
public int decodeExpectedMaxLength(ByteBuf buf, ProtocolUtils.Direction direction,
- ProtocolVersion version) {
+ ProtocolVersion version) {
return 0;
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/KnownPacksPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/KnownPacksPacket.java
index b3fb0de4fb..08e90baf92 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/KnownPacksPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/KnownPacksPacket.java
@@ -24,55 +24,74 @@
import com.velocitypowered.proxy.util.except.QuietDecoderException;
import io.netty.buffer.ByteBuf;
+/**
+ * The {@code KnownPacksPacket} class represents a packet that handles the synchronization
+ * of known resource packs between the client and server in the Minecraft protocol.
+ *
+ * This packet contains a list of {@link KnownPack} instances, each representing a resource
+ * pack with a namespace, identifier, and version. It allows the server to inform the client
+ * about available resource packs.
+ */
public class KnownPacksPacket implements MinecraftPacket {
- private static final int MAX_LENGTH_PACKS = Integer.getInteger("velocity.max-known-packs", 64);
- private static final QuietDecoderException TOO_MANY_PACKS =
- new QuietDecoderException("too many known packs");
+ private static final int MAX_LENGTH_PACKS = Integer.getInteger("velocity.max-known-packs", 64);
+ private static final QuietDecoderException TOO_MANY_PACKS =
+ new QuietDecoderException("too many known packs");
- private KnownPack[] packs;
+ private KnownPack[] packs;
- @Override
- public void decode(ByteBuf buf, ProtocolUtils.Direction direction,
- ProtocolVersion protocolVersion) {
- final int packCount = ProtocolUtils.readVarInt(buf);
- if (direction == ProtocolUtils.Direction.SERVERBOUND && packCount > MAX_LENGTH_PACKS) {
- throw TOO_MANY_PACKS;
- }
-
- final KnownPack[] packs = new KnownPack[packCount];
+ @Override
+ public void decode(ByteBuf buf, ProtocolUtils.Direction direction,
+ ProtocolVersion protocolVersion) {
+ final int packCount = ProtocolUtils.readVarInt(buf);
+ if (direction == ProtocolUtils.Direction.SERVERBOUND && packCount > MAX_LENGTH_PACKS) {
+ throw TOO_MANY_PACKS;
+ }
- for (int i = 0; i < packCount; i++) {
- packs[i] = KnownPack.read(buf);
- }
+ final KnownPack[] packs = new KnownPack[packCount];
- this.packs = packs;
+ for (int i = 0; i < packCount; i++) {
+ packs[i] = KnownPack.read(buf);
}
- @Override
- public void encode(ByteBuf buf, ProtocolUtils.Direction direction,
- ProtocolVersion protocolVersion) {
- ProtocolUtils.writeVarInt(buf, packs.length);
+ this.packs = packs;
+ }
- for (KnownPack pack : packs) {
- pack.write(buf);
- }
- }
+ @Override
+ public void encode(ByteBuf buf, ProtocolUtils.Direction direction,
+ ProtocolVersion protocolVersion) {
+ ProtocolUtils.writeVarInt(buf, packs.length);
- @Override
- public boolean handle(MinecraftSessionHandler handler) {
- return handler.handle(this);
+ for (KnownPack pack : packs) {
+ pack.write(buf);
}
+ }
+
+ @Override
+ public boolean handle(MinecraftSessionHandler handler) {
+ return handler.handle(this);
+ }
- public record KnownPack(String namespace, String id, String version) {
- private static KnownPack read(ByteBuf buf) {
- return new KnownPack(ProtocolUtils.readString(buf), ProtocolUtils.readString(buf), ProtocolUtils.readString(buf));
- }
+ /**
+ * The {@code KnownPack} record represents a known resource pack with a namespace,
+ * identifier, and version in the Minecraft protocol.
+ *
+ * It encapsulates the information needed to identify a resource pack, typically used
+ * for managing or synchronizing resource packs between the client and server.
+ *
+ * @param namespace the namespace of the resource pack (e.g., "minecraft" or a mod name)
+ * @param id the unique identifier of the resource pack within the namespace
+ * @param version the version of the resource pack
+ */
+ public record KnownPack(String namespace, String id, String version) {
+ private static KnownPack read(ByteBuf buf) {
+ return new KnownPack(ProtocolUtils.readString(buf), ProtocolUtils.readString(buf), ProtocolUtils.readString(buf));
+ }
- private void write(ByteBuf buf) {
- ProtocolUtils.writeString(buf, namespace);
- ProtocolUtils.writeString(buf, id);
- ProtocolUtils.writeString(buf, version);
- }
+ private void write(ByteBuf buf) {
+ ProtocolUtils.writeString(buf, namespace);
+ ProtocolUtils.writeString(buf, id);
+ ProtocolUtils.writeString(buf, version);
}
+ }
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/RegistrySyncPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/RegistrySyncPacket.java
index 2d9ed230e6..e7dc200ea9 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/RegistrySyncPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/RegistrySyncPacket.java
@@ -25,6 +25,18 @@
import com.velocitypowered.proxy.protocol.util.DeferredByteBufHolder;
import io.netty.buffer.ByteBuf;
+/**
+ * The {@code RegistrySyncPacket} class is responsible for synchronizing registry data
+ * between the server and client in Minecraft.
+ *
+ * This packet is used to ensure that the client has the same registry information as
+ * the server, covering aspects like blocks, items, entities, and other game elements
+ * that are part of Minecraft's internal registries.
+ *
+ * It extends the {@link DeferredByteBufHolder} class to handle deferred buffering
+ * operations for potentially large sets of registry data, which may include
+ * complex serialization processes.
+ */
public class RegistrySyncPacket extends DeferredByteBufHolder implements MinecraftPacket {
public RegistrySyncPacket() {
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/StartUpdatePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/StartUpdatePacket.java
index d41265ce56..8820c025fc 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/StartUpdatePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/StartUpdatePacket.java
@@ -23,6 +23,16 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * The {@code StartUpdatePacket} class represents a packet that signals the
+ * start of an update process in the Minecraft protocol.
+ *
+ * This packet may be used to notify the client or server that a certain update
+ * process, such as data synchronization or gameplay changes, is about to begin.
+ *
+ * Its specific use depends on the version and context of the update,
+ * typically handled in the Minecraft networking layer.
+ */
public class StartUpdatePacket implements MinecraftPacket {
public static final StartUpdatePacket INSTANCE = new StartUpdatePacket();
@@ -41,7 +51,7 @@ public void encode(ByteBuf buf, ProtocolUtils.Direction direction,
@Override
public int decodeExpectedMaxLength(ByteBuf buf, ProtocolUtils.Direction direction,
- ProtocolVersion version) {
+ ProtocolVersion version) {
return 0;
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/TagsUpdatePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/TagsUpdatePacket.java
index c0cf414e0c..5e0f9777f5 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/TagsUpdatePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/TagsUpdatePacket.java
@@ -24,9 +24,17 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
import io.netty.buffer.ByteBuf;
-
import java.util.Map;
+/**
+ * The {@code TagsUpdatePacket} class represents a packet sent to update the tags
+ * used by the Minecraft client. Tags are used in various parts of the game to group
+ * blocks, items, entities, and other objects under common categories.
+ *
+ * This packet is typically sent to clients when they join a server or when
+ * the server needs to update the list of tags for the client, ensuring that
+ * the client has the most up-to-date tag information.
+ */
public class TagsUpdatePacket implements MinecraftPacket {
private Map> tags;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/legacyping/LegacyMinecraftPingVersion.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/legacyping/LegacyMinecraftPingVersion.java
index d5ef296a41..cad0069180 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/legacyping/LegacyMinecraftPingVersion.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/legacyping/LegacyMinecraftPingVersion.java
@@ -17,6 +17,16 @@
package com.velocitypowered.proxy.protocol.packet.legacyping;
+/**
+ * The {@code LegacyMinecraftPingVersion} enum represents the various protocol versions
+ * used by older Minecraft clients during the server ping process.
+ *
+ * This enum is used to distinguish between the different legacy versions of Minecraft
+ * that have unique ping formats, ensuring compatibility with those older clients.
+ *
+ * Each constant in this enum corresponds to a specific version of Minecraft that
+ * requires a legacy server ping format.
+ */
public enum LegacyMinecraftPingVersion {
MINECRAFT_1_3,
MINECRAFT_1_4,
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/GenericTitlePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/GenericTitlePacket.java
index 8641173e74..d8c0e8d76f 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/GenericTitlePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/GenericTitlePacket.java
@@ -23,8 +23,21 @@
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import io.netty.buffer.ByteBuf;
+/**
+ * The {@code GenericTitlePacket} class serves as the base class for all title-related packets
+ * in Minecraft. This class provides common functionality and properties for handling title, subtitle,
+ * action bar, and timing-related packets.
+ *
+ * Subclasses of {@code GenericTitlePacket} implement specific behavior for different types of title
+ * packets, such as titles, subtitles, and action bars.
+ */
public abstract class GenericTitlePacket implements MinecraftPacket {
+ /**
+ * The {@code ActionType} enum represents the different actions that can be performed with a title packet.
+ * Each action corresponds to a specific type of title operation, such as setting a title or subtitle,
+ * updating timing information, or resetting and hiding titles.
+ */
public enum ActionType {
SET_TITLE(0),
SET_SUBTITLE(1),
@@ -45,7 +58,6 @@ public int getAction(ProtocolVersion version) {
}
}
-
private ActionType action;
protected void setAction(ActionType action) {
@@ -88,10 +100,9 @@ public void setFadeOut(int fadeOut) {
throw new UnsupportedOperationException("Invalid function for this TitlePacket ActionType");
}
-
@Override
public final void decode(ByteBuf buf, ProtocolUtils.Direction direction,
- ProtocolVersion version) {
+ ProtocolVersion version) {
throw new UnsupportedOperationException(); // encode only
}
@@ -103,7 +114,7 @@ public final void decode(ByteBuf buf, ProtocolUtils.Direction direction,
* @return GenericTitlePacket instance that follows the invoker type/version
*/
public static GenericTitlePacket constructTitlePacket(ActionType type, ProtocolVersion version) {
- GenericTitlePacket packet = null;
+ GenericTitlePacket packet;
if (version.noLessThan(ProtocolVersion.MINECRAFT_1_17)) {
packet = switch (type) {
case SET_ACTION_BAR -> new TitleActionbarPacket();
@@ -111,7 +122,6 @@ public static GenericTitlePacket constructTitlePacket(ActionType type, ProtocolV
case SET_TIMES -> new TitleTimesPacket();
case SET_TITLE -> new TitleTextPacket();
case HIDE, RESET -> new TitleClearPacket();
- default -> throw new IllegalArgumentException("Invalid ActionType");
};
} else {
packet = new LegacyTitlePacket();
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/LegacyTitlePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/LegacyTitlePacket.java
index ebae8a9e5b..5b5b8b0f96 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/LegacyTitlePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/LegacyTitlePacket.java
@@ -24,6 +24,16 @@
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * The {@code LegacyTitlePacket} class represents a packet that handles title-related functionality
+ * for older versions of Minecraft where title handling differs.
+ *
+ * This packet is used to send title and subtitle information using legacy methods for clients
+ * that do not support the newer title packet format.
+ *
+ * It extends the {@link GenericTitlePacket}, inheriting basic title properties but is specifically
+ * focused on legacy title implementations.
+ */
public class LegacyTitlePacket extends GenericTitlePacket {
private @Nullable ComponentHolder component;
@@ -51,10 +61,10 @@ && getAction() == ActionType.SET_ACTION_BAR) {
buf.writeInt(stay);
buf.writeInt(fadeOut);
}
- case HIDE, RESET -> {}
+ case HIDE, RESET -> {
+ }
default -> throw new UnsupportedOperationException("Unknown action " + getAction());
}
-
}
@Override
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleActionbarPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleActionbarPacket.java
index f34983eaf9..5fb3c9a8bc 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleActionbarPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleActionbarPacket.java
@@ -23,6 +23,16 @@
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import io.netty.buffer.ByteBuf;
+/**
+ * The {@code TitleActionbarPacket} class represents a packet that handles the content of an action bar
+ * displayed to the player in Minecraft.
+ *
+ * This packet is used to send the text that appears in the action bar, which is a separate text line
+ * displayed above the hotbar on the player's screen.
+ *
+ * It extends the {@link GenericTitlePacket}, inheriting basic title properties and focusing on
+ * the content of the action bar.
+ */
public class TitleActionbarPacket extends GenericTitlePacket {
private ComponentHolder component;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleClearPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleClearPacket.java
index 1b3489691f..077ca5944a 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleClearPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleClearPacket.java
@@ -22,6 +22,15 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * The {@code TitleClearPacket} class represents a packet that handles the clearing or removal of a title
+ * from the player's screen in Minecraft.
+ *
+ * This packet is used to instruct the client to clear any currently displayed title and subtitle.
+ *
+ * It extends the {@link GenericTitlePacket}, inheriting basic title properties but is specifically
+ * focused on clearing the title display.
+ */
public class TitleClearPacket extends GenericTitlePacket {
public TitleClearPacket() {
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleSubtitlePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleSubtitlePacket.java
index 0f375ae20a..3f44f3e958 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleSubtitlePacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleSubtitlePacket.java
@@ -23,6 +23,15 @@
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import io.netty.buffer.ByteBuf;
+/**
+ * The {@code TitleSubtitlePacket} class represents a packet that handles the subtitle content for a title
+ * displayed to the player in Minecraft.
+ *
+ * This packet is used to send the subtitle text that appears below the main title on the player's screen.
+ *
+ * It extends the {@link GenericTitlePacket}, inheriting basic title properties and focusing
+ * on the subtitle content of the title.
+ */
public class TitleSubtitlePacket extends GenericTitlePacket {
private ComponentHolder component;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTextPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTextPacket.java
index ae75f5d618..171790755d 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTextPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTextPacket.java
@@ -23,6 +23,15 @@
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import io.netty.buffer.ByteBuf;
+/**
+ * The {@code TitleTextPacket} class represents a packet that handles the text content for a title
+ * displayed to the player in Minecraft.
+ *
+ * This packet is used to send the main title text to be displayed on the player's screen.
+ *
+ * It extends the {@link GenericTitlePacket}, inheriting basic title properties and focusing
+ * on the specific text content of the title.
+ */
public class TitleTextPacket extends GenericTitlePacket {
private ComponentHolder component;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTimesPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTimesPacket.java
index 8764a12fab..5b737af49e 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTimesPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTimesPacket.java
@@ -22,6 +22,15 @@
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
+/**
+ * The {@code TitleTimesPacket} class represents a packet that handles the timing settings for a title in
+ * Minecraft, such as fade-in, stay, and fade-out durations.
+ *
+ * This packet is used to set the timing properties for a title displayed to the player.
+ *
+ * It extends the {@link GenericTitlePacket} to inherit basic title properties and adds specific timing
+ * controls for the title display.
+ */
public class TitleTimesPacket extends GenericTitlePacket {
private int fadeIn;
From 5957c067f5a13f35a7fbda01dcbc793cee33fe13 Mon Sep 17 00:00:00 2001
From: RootBeer
Date: Mon, 26 Jan 2026 04:57:26 -0500
Subject: [PATCH 3/7] Resolve minor catch that has not been handled
---
.../proxy/protocol/packet/chat/legacy/LegacyChatPacket.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatPacket.java
index cbe1e61374..942dc6cad5 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyChatPacket.java
@@ -52,6 +52,7 @@ private static int getMaxServerboundMessageLength() {
try {
return Integer.parseInt(value.trim());
} catch (final NumberFormatException e) {
+ // Exception has been handled
}
}
return 100;
From 24ee3ff2c0e850a6692a3dbee603e97866daa050 Mon Sep 17 00:00:00 2001
From: RootBeer
Date: Mon, 26 Jan 2026 13:26:43 -0500
Subject: [PATCH 4/7] Apply suggested replacements
---
.../proxy/protocol/packet/chat/RateLimitedCommandHandler.java | 4 ++--
.../proxy/protocol/packet/chat/keyed/KeyedCommandHandler.java | 4 ++--
.../protocol/packet/chat/legacy/LegacyCommandHandler.java | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/RateLimitedCommandHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/RateLimitedCommandHandler.java
index 8ec1f5b22d..4bddf35fab 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/RateLimitedCommandHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/RateLimitedCommandHandler.java
@@ -46,8 +46,8 @@ protected RateLimitedCommandHandler(Player player, VelocityServer velocityServer
public boolean handlePlayerCommand(MinecraftPacket packet) {
if (packetClass().isInstance(packet)) {
if (!velocityServer.getCommandRateLimiter().attempt(player.getUniqueId())) {
- if (velocityServer.getConfiguration().isKickOnCommandRateLimit() && failedAttempts++
- >= velocityServer.getConfiguration().getKickAfterRateLimitedCommands()) {
+ if (velocityServer.getConfiguration().isKickOnCommandRateLimit()
+ && failedAttempts++ >= velocityServer.getConfiguration().getKickAfterRateLimitedCommands()) {
player.disconnect(Component.translatable("velocity.kick.command-rate-limit"));
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedCommandHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedCommandHandler.java
index 1be3ddddc5..e52f4c9a6f 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedCommandHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/keyed/KeyedCommandHandler.java
@@ -125,7 +125,7 @@ public void handlePlayerCommandInternal(KeyedPlayerCommandPacket packet) {
}
return null;
});
- }, packet.getCommand(), packet.getTimestamp(), null, new CommandExecuteEvent.InvocationInfo(
- CommandExecuteEvent.SignedState.UNSUPPORTED, CommandExecuteEvent.Source.PLAYER));
+ }, packet.getCommand(), packet.getTimestamp(), null, new CommandExecuteEvent.InvocationInfo(CommandExecuteEvent.SignedState.UNSUPPORTED,
+ CommandExecuteEvent.Source.PLAYER));
}
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyCommandHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyCommandHandler.java
index 3d5a7f5f88..68ff4f4551 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyCommandHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/legacy/LegacyCommandHandler.java
@@ -76,7 +76,7 @@ public void handlePlayerCommandInternal(LegacyChatPacket packet) {
}
return null;
});
- }, command, Instant.now(), null, new CommandExecuteEvent.InvocationInfo(
- CommandExecuteEvent.SignedState.UNSUPPORTED, CommandExecuteEvent.Source.PLAYER));
+ }, command, Instant.now(), null, new CommandExecuteEvent.InvocationInfo(CommandExecuteEvent.SignedState.UNSUPPORTED,
+ CommandExecuteEvent.Source.PLAYER));
}
}
From 9c6a1b0e9fde0061251b1b73dba157a3733b5676 Mon Sep 17 00:00:00 2001
From: RootBeer
Date: Tue, 27 Jan 2026 12:37:42 -0500
Subject: [PATCH 5/7] Remove deprecated inclusion of GraalVM
---
proxy/build.gradle.kts | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/proxy/build.gradle.kts b/proxy/build.gradle.kts
index 5929692c5e..2fb40773c0 100644
--- a/proxy/build.gradle.kts
+++ b/proxy/build.gradle.kts
@@ -108,15 +108,6 @@ tasks {
workingDir = file("run").also(File::mkdirs)
standardInput = System.`in` // Doesn't work?
}
-
- withType().configureEach {
- options.compilerArgs.addAll(
- listOf(
- "-Alog4j.graalvm.groupId=${project.group}",
- "-Alog4j.graalvm.artifactId=${project.name}"
- )
- )
- }
}
val projectVersion = version as String
From fc4e3c860f5d7ff479a0690a1f55f033c5979ebb Mon Sep 17 00:00:00 2001
From: RootBeer
Date: Tue, 27 Jan 2026 14:35:57 -0500
Subject: [PATCH 6/7] Resolve codestyle/mistakes
---
.../velocitypowered/api/proxy/server/ServerPing.java | 8 ++++----
.../packet/ClientboundSoundEntityPacket.java | 12 ++++++------
.../protocol/packet/config/CodeOfConductPacket.java | 9 +++++----
3 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/server/ServerPing.java b/api/src/main/java/com/velocitypowered/api/proxy/server/ServerPing.java
index 4743d05e98..98ca3b752d 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/server/ServerPing.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/server/ServerPing.java
@@ -504,9 +504,9 @@ public int getProtocol() {
}
/**
- * Gets the legacy string name of the sample player.
+ * Gets the user-facing name of the server version.
*
- * @return the player name
+ * @return the version name
*/
public String getName() {
return name;
@@ -638,9 +638,9 @@ public static final class SamplePlayer {
private final UUID id;
/**
- * Constructs a SamplePlayer from a {@link Component}-based name.
+ * Constructs a SamplePlayer with the given name and UUID.
*
- * @param name the name of the player as a {@link Component}
+ * @param name the name of the player
* @param id the UUID of the player
*/
public SamplePlayer(String name, UUID id) {
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundSoundEntityPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundSoundEntityPacket.java
index be81201c96..9ccebf3b03 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundSoundEntityPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientboundSoundEntityPacket.java
@@ -70,17 +70,17 @@ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi
buf.writeBoolean(fixedRange != null);
if (fixedRange != null) {
buf.writeFloat(fixedRange);
+ }
- ProtocolUtils.writeSoundSource(buf, protocolVersion, sound.source());
+ ProtocolUtils.writeSoundSource(buf, protocolVersion, sound.source());
- ProtocolUtils.writeVarInt(buf, emitterEntityId);
+ ProtocolUtils.writeVarInt(buf, emitterEntityId);
- buf.writeFloat(sound.volume());
+ buf.writeFloat(sound.volume());
- buf.writeFloat(sound.pitch());
+ buf.writeFloat(sound.pitch());
- buf.writeLong(sound.seed().orElse(SEEDS_RANDOM.nextLong()));
- }
+ buf.writeLong(sound.seed().orElse(SEEDS_RANDOM.nextLong()));
}
@Override
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductPacket.java
index 11f934ebf1..37fdd92691 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductPacket.java
@@ -25,11 +25,12 @@
import io.netty.buffer.ByteBuf;
/**
- * The {@code FinishedUpdatePacket} class represents a packet that signals the completion
- * of an update process between the client and server in the Minecraft protocol.
+ * A server-to-client packet containing the server's code of conduct.
*
- * This packet is used to indicate that the client has finished receiving and processing
- * an update, ensuring that further operations can proceed.
+ * This packet is sent during the configuration stage to present the
+ * server-defined conduct rules to the client. The client may later
+ * respond with a {@link CodeOfConductAcceptPacket} to indicate
+ * acceptance.
*/
public class CodeOfConductPacket extends DeferredByteBufHolder implements MinecraftPacket {
From db7849c4add4e882d544336ee10d31117b0e074a Mon Sep 17 00:00:00 2001
From: RootBeer
Date: Tue, 27 Jan 2026 18:07:19 -0500
Subject: [PATCH 7/7] Bump spotless (again). Might as well include this in here
since it appears significant
---
gradle/libs.versions.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index b8a22e770b..5ad83ecc4d 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -8,7 +8,7 @@ netty = "4.2.9.Final"
[plugins]
fill = "io.papermc.fill.gradle:1.0.10"
shadow = "com.gradleup.shadow:9.3.1"
-spotless = "com.diffplug.spotless:8.2.0"
+spotless = "com.diffplug.spotless:8.2.1"
[libraries]
adventure-bom = "net.kyori:adventure-bom:4.26.1"