From 409ab7b118fe46cc57c33596a0933f4548ab8682 Mon Sep 17 00:00:00 2001 From: Adrian <68704415+4drian3d@users.noreply.github.com> Date: Fri, 23 Feb 2024 14:11:42 -0500 Subject: [PATCH] [ci skip] Add javadocs warnings about unsupported operations (#1250) * Document possible blank spaces in the command of the CommandExecuteEvent * Added Javadocs warning about unimplemented methods in Velocity * Improved KickedFromServerEvent documentation * Fixed `apiNote` javadoc generation --- api/build.gradle.kts | 6 ++ .../event/command/CommandExecuteEvent.java | 19 +++-- .../event/player/KickedFromServerEvent.java | 80 +++++++++++++------ .../com/velocitypowered/api/proxy/Player.java | 69 +++++++++++++++- .../connection/client/ConnectedPlayer.java | 6 +- .../LegacyResourcePackHandler.java | 2 +- .../resourcepack/ResourcePackHandler.java | 12 +-- .../netty/PlayPacketQueueHandler.java | 2 +- 8 files changed, 152 insertions(+), 44 deletions(-) diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 8f0dec6c..56bb3c49 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -70,6 +70,12 @@ tasks { "https://javadoc.io/doc/com.github.ben-manes.caffeine/caffeine" ) + o.tags( + "apiNote:a:API Note:", + "implSpec:a:Implementation Requirements:", + "implNote:a:Implementation Note:" + ) + // Disable the crazy super-strict doclint tool in Java 8 o.addStringOption("Xdoclint:none", "-quiet") } 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 29288265..65c9b901 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 @@ -39,6 +39,11 @@ public final class CommandExecuteEvent implements ResultedEvent { this.result = CommandResult.allowed(); } + /** + * Gets the source responsible for the execution of this command. + * + * @return the source executing the command + */ public CommandSource getCommandSource() { return commandSource; } @@ -47,6 +52,10 @@ public final class CommandExecuteEvent implements ResultedEvent { * Gets the original command being executed without the first slash. * * @return the original command being executed + * @apiNote Note that the player can provide a command that begins with spaces, + * but still be validly executed. For example, the command {@code / velocity info}, + * although not valid in the chat bar, will be executed as correctly as if + * the player had executed {@code /velocity info} */ public String getCommand() { return command; @@ -58,7 +67,7 @@ public final class CommandExecuteEvent implements ResultedEvent { } @Override - public void setResult(CommandResult result) { + public void setResult(final @NonNull CommandResult result) { this.result = Preconditions.checkNotNull(result, "result"); } @@ -80,11 +89,11 @@ public final class CommandExecuteEvent implements ResultedEvent { private static final CommandResult DENIED = new CommandResult(false, false, null); private static final CommandResult FORWARD_TO_SERVER = new CommandResult(false, true, null); - private @Nullable String command; + private final @Nullable String command; private final boolean status; private final boolean forward; - private CommandResult(boolean status, boolean forward, @Nullable String command) { + private CommandResult(final boolean status, final boolean forward, final @Nullable String command) { this.status = status; this.forward = forward; this.command = command; @@ -142,7 +151,7 @@ public final class CommandExecuteEvent implements ResultedEvent { * @param newCommand the command without first slash to use instead * @return a result with a new command being forwarded to server */ - public static CommandResult forwardToServer(@NonNull String newCommand) { + public static CommandResult forwardToServer(final @NonNull String newCommand) { Preconditions.checkNotNull(newCommand, "newCommand"); return new CommandResult(false, true, newCommand); } @@ -154,7 +163,7 @@ public final class CommandExecuteEvent implements ResultedEvent { * @param newCommand the command to use instead without first slash * @return a result with a new command */ - public static CommandResult command(@NonNull String newCommand) { + public static CommandResult command(final @NonNull String newCommand) { Preconditions.checkNotNull(newCommand, "newCommand"); return new CommandResult(true, false, newCommand); } diff --git a/api/src/main/java/com/velocitypowered/api/event/player/KickedFromServerEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/KickedFromServerEvent.java index a3dc567a..4f03a35d 100644 --- a/api/src/main/java/com/velocitypowered/api/event/player/KickedFromServerEvent.java +++ b/api/src/main/java/com/velocitypowered/api/event/player/KickedFromServerEvent.java @@ -13,6 +13,7 @@ import com.velocitypowered.api.event.annotation.AwaitingEvent; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.server.RegisteredServer; import java.util.Optional; +import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -29,7 +30,7 @@ public final class KickedFromServerEvent implements private final Player player; private final RegisteredServer server; - private final net.kyori.adventure.text.@Nullable Component originalReason; + private final @Nullable Component originalReason; private final boolean duringServerConnect; private ServerKickResult result; @@ -43,7 +44,7 @@ public final class KickedFromServerEvent implements * @param result the initial result */ public KickedFromServerEvent(Player player, RegisteredServer server, - net.kyori.adventure.text.@Nullable Component originalReason, + @Nullable Component originalReason, boolean duringServerConnect, ServerKickResult result) { this.player = Preconditions.checkNotNull(player, "player"); this.server = Preconditions.checkNotNull(server, "server"); @@ -53,24 +54,39 @@ public final class KickedFromServerEvent implements } @Override - public ServerKickResult getResult() { + public @NonNull ServerKickResult getResult() { return result; } @Override - public void setResult(@NonNull ServerKickResult result) { + public void setResult(final @NonNull ServerKickResult result) { this.result = Preconditions.checkNotNull(result, "result"); } - public Player getPlayer() { + /** + * The player who has been kicked out. + * + * @return the player affected + */ + public @NonNull Player getPlayer() { return player; } - public RegisteredServer getServer() { + /** + * The server from which the player has been kicked. + * + * @return the server the player disconnected from + */ + public @NonNull RegisteredServer getServer() { return server; } - public Optional getServerKickReason() { + /** + * The reason why the player was kicked, the server may or may not provide this reason. + * + * @return the reason for being kicked, optional + */ + public Optional getServerKickReason() { return Optional.ofNullable(originalReason); } @@ -98,7 +114,7 @@ public final class KickedFromServerEvent implements /** * Represents the base interface for {@link KickedFromServerEvent} results. */ - public interface ServerKickResult extends ResultedEvent.Result { + public sealed interface ServerKickResult extends ResultedEvent.Result { } @@ -107,9 +123,9 @@ public final class KickedFromServerEvent implements */ public static final class DisconnectPlayer implements ServerKickResult { - private final net.kyori.adventure.text.Component component; + private final Component component; - private DisconnectPlayer(net.kyori.adventure.text.Component component) { + private DisconnectPlayer(final Component component) { this.component = Preconditions.checkNotNull(component, "component"); } @@ -118,7 +134,7 @@ public final class KickedFromServerEvent implements return true; } - public net.kyori.adventure.text.Component getReasonComponent() { + public Component getReasonComponent() { return component; } @@ -128,9 +144,15 @@ public final class KickedFromServerEvent implements * @param reason the reason to use when disconnecting the player * @return the disconnect result */ - public static DisconnectPlayer create(net.kyori.adventure.text.Component reason) { + public static DisconnectPlayer create(Component reason) { return new DisconnectPlayer(reason); } + + @Override + public String toString() { + return "KickedFromServerEvent#DisconnectPlater{isAllowed=%s,component=%s}" + .formatted(isAllowed(), component); + } } /** @@ -138,11 +160,10 @@ public final class KickedFromServerEvent implements */ public static final class RedirectPlayer implements ServerKickResult { - private final net.kyori.adventure.text.Component message; + private final Component message; private final RegisteredServer server; - private RedirectPlayer(RegisteredServer server, - net.kyori.adventure.text.@Nullable Component message) { + private RedirectPlayer(final RegisteredServer server, final @Nullable Component message) { this.server = Preconditions.checkNotNull(server, "server"); this.message = message; } @@ -152,11 +173,11 @@ public final class KickedFromServerEvent implements return false; } - public RegisteredServer getServer() { + public @NonNull RegisteredServer getServer() { return server; } - public net.kyori.adventure.text.@Nullable Component getMessageComponent() { + public @Nullable Component getMessageComponent() { return message; } @@ -169,8 +190,7 @@ public final class KickedFromServerEvent implements * @param message the message will be sent to the player after redirecting * @return the redirect result */ - public static RedirectPlayer create(RegisteredServer server, - net.kyori.adventure.text.Component message) { + public static RedirectPlayer create(final @NonNull RegisteredServer server, final Component message) { return new RedirectPlayer(server, message); } @@ -181,9 +201,15 @@ public final class KickedFromServerEvent implements * @param server the server to send the player to * @return the redirect result */ - public static ServerKickResult create(RegisteredServer server) { + public static ServerKickResult create(final RegisteredServer server) { return new RedirectPlayer(server, null); } + + @Override + public String toString() { + return "KickedFromServerEvent#RedirectPlayer{isAllowed=%s,message=%s,server=%s}" + .formatted(isAllowed(), this.message, this.server); + } } /** @@ -193,9 +219,9 @@ public final class KickedFromServerEvent implements */ public static final class Notify implements ServerKickResult { - private final net.kyori.adventure.text.Component message; + private final Component message; - private Notify(net.kyori.adventure.text.Component message) { + private Notify(Component message) { this.message = Preconditions.checkNotNull(message, "message"); } @@ -204,7 +230,7 @@ public final class KickedFromServerEvent implements return false; } - public net.kyori.adventure.text.Component getMessageComponent() { + public Component getMessageComponent() { return message; } @@ -214,8 +240,14 @@ public final class KickedFromServerEvent implements * @param message the server to send the player to * @return the redirect result */ - public static Notify create(net.kyori.adventure.text.Component message) { + public static Notify create(final @NonNull Component message) { return new Notify(message); } + + @Override + public String toString() { + return "KickedFromServerEvent#Notify{isAllowed=%s,message=%s}" + .formatted(isAllowed(), message); + } } } 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 7e0c59bf..eb41401b 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java @@ -26,8 +26,11 @@ import java.util.Optional; import java.util.UUID; import java.util.function.UnaryOperator; import net.kyori.adventure.identity.Identified; +import net.kyori.adventure.inventory.Book; import net.kyori.adventure.key.Key; import net.kyori.adventure.key.Keyed; +import net.kyori.adventure.sound.Sound; +import net.kyori.adventure.sound.SoundStop; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.event.HoverEventSource; @@ -267,7 +270,7 @@ public interface Player extends * * @return collection of the applied resource packs. */ - Collection getAppliedResourcePacks(); + @NotNull Collection getAppliedResourcePacks(); /** * Gets the {@link ResourcePackInfo} of the resource packs @@ -276,7 +279,7 @@ public interface Player extends * * @return collection of the pending resource packs */ - Collection getPendingResourcePacks(); + @NotNull Collection getPendingResourcePacks(); /** * Note that this method does not send a plugin message to the server the player @@ -288,7 +291,7 @@ public interface Player extends * @inheritDoc */ @Override - boolean sendPluginMessage(ChannelIdentifier identifier, byte[] data); + boolean sendPluginMessage(@NotNull ChannelIdentifier identifier, byte @NotNull[] data); @Override default @NotNull Key key() { @@ -298,7 +301,7 @@ public interface Player extends @Override default @NotNull HoverEvent asHoverEvent( @NotNull UnaryOperator op) { - return HoverEvent.showEntity(op.apply(HoverEvent.ShowEntity.of(this, getUniqueId(), + return HoverEvent.showEntity(op.apply(HoverEvent.ShowEntity.showEntity(this, getUniqueId(), Component.text(getUsername())))); } @@ -310,6 +313,9 @@ public interface Player extends */ @Nullable String getClientBrand(); + // + // Custom Chat Completions API + // /** * Add custom chat completion suggestions shown to the player while typing a message. @@ -338,4 +344,59 @@ public interface Player extends * @param completions the completions to set */ void setCustomChatCompletions(@NotNull Collection completions); + + // + // Non Supported Adventure Operations + // TODO: Service API + // + + /** + * {@inheritDoc} + * + * This method is not currently implemented in Velocity + * and will not perform any actions. + */ + @Override + default void playSound(@NotNull Sound sound) { + } + + /** + * {@inheritDoc} + * + * This method is not currently implemented in Velocity + * and will not perform any actions. + */ + @Override + default void playSound(@NotNull Sound sound, double x, double y, double z) { + } + + /** + * {@inheritDoc} + * + * This method is not currently implemented in Velocity + * and will not perform any actions. + */ + @Override + default void playSound(@NotNull Sound sound, Sound.Emitter emitter) { + } + + /** + * {@inheritDoc} + * + * This method is not currently implemented in Velocity + * and will not perform any actions. + */ + @Override + default void stopSound(@NotNull SoundStop stop) { + } + + /** + * {@inheritDoc} + * + * This method is not currently implemented in Velocity + * and will not perform any actions. + */ + @Override + default void openBook(@NotNull Book book) { + } } \ No newline at end of file diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java index 599d6693..79ad8163 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java @@ -943,7 +943,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player, } @Override - public boolean sendPluginMessage(ChannelIdentifier identifier, byte[] data) { + public boolean sendPluginMessage(@NotNull ChannelIdentifier identifier, byte @NotNull [] data) { Preconditions.checkNotNull(identifier, "identifier"); Preconditions.checkNotNull(data, "data"); PluginMessagePacket message = new PluginMessagePacket(identifier.getId(), @@ -1099,12 +1099,12 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player, } @Override - public Collection getAppliedResourcePacks() { + public @NotNull Collection getAppliedResourcePacks() { return this.resourcePackHandler.getAppliedResourcePacks(); } @Override - public Collection getPendingResourcePacks() { + public @NotNull Collection getPendingResourcePacks() { return this.resourcePackHandler.getPendingResourcePacks(); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/LegacyResourcePackHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/LegacyResourcePackHandler.java index 2ad9c841..b2b80399 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/LegacyResourcePackHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/LegacyResourcePackHandler.java @@ -34,7 +34,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.jetbrains.annotations.NotNull; /** - * Legacy (Minecraft <1.17) ResourcePackHandler. + * Legacy (Minecraft <1.17) ResourcePackHandler. */ public sealed class LegacyResourcePackHandler extends ResourcePackHandler permits Legacy117ResourcePackHandler { diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/ResourcePackHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/ResourcePackHandler.java index e2160f8e..4e6e7250 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/ResourcePackHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/player/resourcepack/ResourcePackHandler.java @@ -117,27 +117,27 @@ public abstract sealed class ResourcePackHandler /** * Processes a client response to a sent resource-pack. - *
    *

    Cases in which no action will be taken:

    + *
      * - *
    • DOWNLOADED + *
    • DOWNLOADED *

      In this case the resource pack is downloaded and will be applied to the client, * no action is required in Velocity.

      * - *
    • INVALID_URL + *
    • INVALID_URL *

      In this case, the client has received a resource pack request * and the first check it performs is if the URL is valid, if not, * it will return this value

      * - *
    • FAILED_RELOAD + *
    • FAILED_RELOAD *

      In this case, when trying to reload the client's resources, * an error occurred while reloading a resource pack

      - *
    * - *
  • DECLINED + *
  • DECLINED *

    Only in modern versions, as the resource pack has already been rejected, * there is nothing to do, if the resource pack is required, * the client will be kicked out of the server.

    + *
* * @param bundle the resource pack response bundle */ diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/PlayPacketQueueHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/PlayPacketQueueHandler.java index 612de451..990985c2 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/PlayPacketQueueHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/PlayPacketQueueHandler.java @@ -46,7 +46,7 @@ public class PlayPacketQueueHandler extends ChannelDuplexHandler { private final Queue queue = PlatformDependent.newMpscQueue(); /** - * Provides registries for client & server bound packets. + * Provides registries for client & server bound packets. * * @param version the protocol version */