3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-09-29 06:30:16 +02:00

Remove essentially all use of Java Optionals from the API

Also fix extended handshake event handling
Dieser Commit ist enthalten in:
Andrew Steinborn 2021-05-12 12:33:55 -04:00
Ursprung 6fcef41146
Commit 00cc636d6a
76 geänderte Dateien mit 478 neuen und 427 gelöschten Zeilen

Datei anzeigen

@ -9,7 +9,6 @@ package com.velocitypowered.api.event;
import com.google.common.base.Preconditions;
import java.util.Objects;
import java.util.Optional;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -85,34 +84,30 @@ public interface ResultedEvent<R extends ResultedEvent.Result> {
*/
final class ComponentResult implements Result {
private static final ComponentResult ALLOWED = new ComponentResult(true, null);
private static final ComponentResult ALLOWED = new ComponentResult(null);
private final boolean status;
private final @Nullable Component reason;
protected ComponentResult(boolean status, @Nullable Component reason) {
this.status = status;
protected ComponentResult(@Nullable Component reason) {
this.reason = reason;
}
@Override
public boolean isAllowed() {
return status;
return reason == null;
}
public Optional<Component> reason() {
return Optional.ofNullable(reason);
public @Nullable Component reason() {
return reason;
}
@Override
public String toString() {
if (status) {
if (reason == null) {
return "allowed";
}
if (reason != null) {
} else {
return "denied: " + PlainComponentSerializer.plain().serialize(reason);
}
return "denied";
}
public static ComponentResult allowed() {
@ -121,7 +116,7 @@ public interface ResultedEvent<R extends ResultedEvent.Result> {
public static ComponentResult denied(Component reason) {
Preconditions.checkNotNull(reason, "reason");
return new ComponentResult(false, reason);
return new ComponentResult(reason);
}
@Override
@ -133,12 +128,12 @@ public interface ResultedEvent<R extends ResultedEvent.Result> {
return false;
}
ComponentResult that = (ComponentResult) o;
return status == that.status && Objects.equals(reason, that.reason);
return Objects.equals(reason, that.reason);
}
@Override
public int hashCode() {
return Objects.hash(status, reason);
return Objects.hash(reason);
}
}
}

Datei anzeigen

@ -12,7 +12,6 @@ import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.event.ResultedEvent;
import com.velocitypowered.api.event.command.CommandExecuteEvent.CommandResult;
import java.util.Objects;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -45,8 +44,8 @@ public interface CommandExecuteEvent extends ResultedEvent<CommandResult> {
this.command = command;
}
public Optional<String> modifiedCommand() {
return Optional.ofNullable(command);
public @Nullable String modifiedCommand() {
return command;
}
public boolean isForwardToServer() {

Datei anzeigen

@ -34,7 +34,7 @@ public final class GameProfileRequestEventImpl implements GameProfileRequestEven
boolean onlineMode) {
this.connection = Preconditions.checkNotNull(connection, "connection");
this.originalProfile = Preconditions.checkNotNull(originalProfile, "originalProfile");
this.username = originalProfile.getName();
this.username = originalProfile.name();
this.onlineMode = onlineMode;
}

Datei anzeigen

@ -12,7 +12,6 @@ import com.velocitypowered.api.event.ResultedEvent;
import com.velocitypowered.api.proxy.connection.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.util.Objects;
import java.util.Optional;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -34,7 +33,7 @@ public interface KickedFromServerEvent extends
*
* @return the server kicked the player from the server
*/
Optional<Component> serverKickReason();
@Nullable Component serverKickReason();
/**
* Returns whether or not the player got kicked while connecting to another server.

Datei anzeigen

@ -10,7 +10,6 @@ package com.velocitypowered.api.event.player;
import com.google.common.base.Preconditions;
import com.velocitypowered.api.proxy.connection.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;
@ -72,8 +71,8 @@ public final class KickedFromServerEventImpl implements KickedFromServerEvent {
* @return the server kicked the player from the server
*/
@Override
public Optional<Component> serverKickReason() {
return Optional.ofNullable(originalReason);
public @Nullable Component serverKickReason() {
return originalReason;
}
/**

Datei anzeigen

@ -9,7 +9,7 @@ package com.velocitypowered.api.event.player;
import com.velocitypowered.api.proxy.connection.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Fired when a player has finished connecting to the proxy and we need to choose the first server
@ -19,7 +19,7 @@ public interface PlayerChooseInitialServerEvent {
Player player();
Optional<RegisteredServer> initialServer();
@Nullable RegisteredServer initialServer();
/**
* Sets the new initial server.

Datei anzeigen

@ -10,7 +10,6 @@ package com.velocitypowered.api.event.player;
import com.google.common.base.Preconditions;
import com.velocitypowered.api.proxy.connection.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
@ -38,8 +37,8 @@ public class PlayerChooseInitialServerEventImpl implements PlayerChooseInitialSe
}
@Override
public Optional<RegisteredServer> initialServer() {
return Optional.ofNullable(initialServer);
public @Nullable RegisteredServer initialServer() {
return initialServer;
}
/**
@ -47,7 +46,7 @@ public class PlayerChooseInitialServerEventImpl implements PlayerChooseInitialSe
* @param server the initial server the player should connect to
*/
@Override
public void setInitialServer(RegisteredServer server) {
public void setInitialServer(@Nullable RegisteredServer server) {
this.initialServer = server;
}

Datei anzeigen

@ -9,7 +9,7 @@ package com.velocitypowered.api.event.player;
import com.velocitypowered.api.proxy.connection.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* This event is fired once the player has successfully connected to the target server and the
@ -21,5 +21,5 @@ public interface ServerConnectedEvent {
RegisteredServer target();
Optional<RegisteredServer> previousServer();
@Nullable RegisteredServer previousServer();
}

Datei anzeigen

@ -10,7 +10,6 @@ package com.velocitypowered.api.event.player;
import com.google.common.base.Preconditions;
import com.velocitypowered.api.proxy.connection.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
@ -47,8 +46,8 @@ public final class ServerConnectedEventImpl implements ServerConnectedEvent {
}
@Override
public Optional<RegisteredServer> previousServer() {
return Optional.ofNullable(previousServer);
public @Nullable RegisteredServer previousServer() {
return previousServer;
}
@Override

Datei anzeigen

@ -14,7 +14,6 @@ import com.velocitypowered.api.proxy.player.ConnectionRequestBuilder;
import com.velocitypowered.api.proxy.player.ConnectionRequestBuilder.Status;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.util.Objects;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
@ -60,8 +59,8 @@ public interface ServerPreConnectEvent extends ResultedEvent<ServerPreConnectEve
return target != null;
}
public Optional<RegisteredServer> target() {
return Optional.ofNullable(target);
public @Nullable RegisteredServer target() {
return target;
}
@Override

Datei anzeigen

@ -13,8 +13,8 @@ import com.velocitypowered.api.plugin.meta.PluginDependency;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.regex.Pattern;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Represents metadata for a specific version of a plugin.
@ -39,41 +39,41 @@ public interface PluginDescription {
/**
* Gets the name of the {@link Plugin} within this container.
*
* @return an {@link Optional} with the plugin name, may be empty
* @return a String with the plugin name or the plugin ID
* @see Plugin#name()
*/
default Optional<String> name() {
return Optional.empty();
default String name() {
return id();
}
/**
* Gets the version of the {@link Plugin} within this container.
*
* @return an {@link Optional} with the plugin version, may be empty
* @return a String with the plugin version, may be null
* @see Plugin#version()
*/
default Optional<String> version() {
return Optional.empty();
default @Nullable String version() {
return null;
}
/**
* Gets the description of the {@link Plugin} within this container.
*
* @return an {@link Optional} with the plugin description, may be empty
* @return a String with the plugin description, may be null
* @see Plugin#description()
*/
default Optional<String> description() {
return Optional.empty();
default @Nullable String description() {
return null;
}
/**
* Gets the url or website of the {@link Plugin} within this container.
*
* @return an {@link Optional} with the plugin url, may be empty
* @return an String with the plugin url, may be null
* @see Plugin#url()
*/
default Optional<String> url() {
return Optional.empty();
default @Nullable String url() {
return null;
}
/**
@ -96,16 +96,16 @@ public interface PluginDescription {
return ImmutableSet.of();
}
default Optional<PluginDependency> getDependency(String id) {
return Optional.empty();
default @Nullable PluginDependency getDependency(String id) {
return null;
}
/**
* Returns the file path the plugin was loaded from.
*
* @return the path the plugin was loaded from or {@link Optional#empty()} if unknown
* @return the path the plugin was loaded from or {@code null} if unknown
*/
default Optional<Path> file() {
return Optional.empty();
default @Nullable Path file() {
return null;
}
}

Datei anzeigen

@ -7,9 +7,11 @@
package com.velocitypowered.api.plugin;
import static java.util.Objects.requireNonNull;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Manages plugins loaded on the proxy. This manager can retrieve {@link PluginContainer}s from
@ -24,7 +26,7 @@ public interface PluginManager {
* @param instance the instance
* @return the container
*/
Optional<PluginContainer> fromInstance(Object instance);
@Nullable PluginContainer fromInstance(Object instance);
/**
* Retrieves a {@link PluginContainer} based on its ID.
@ -32,7 +34,7 @@ public interface PluginManager {
* @param id the plugin ID
* @return the plugin, if available
*/
Optional<PluginContainer> getPlugin(String id);
@Nullable PluginContainer getPlugin(String id);
/**
* Gets a {@link Collection} of all {@link PluginContainer}s.
@ -57,4 +59,13 @@ public interface PluginManager {
* @throws UnsupportedOperationException if the operation is not applicable to this plugin
*/
void addToClasspath(Object plugin, Path path);
default PluginContainer ensurePluginContainer(Object plugin) {
requireNonNull(plugin, "plugin");
PluginContainer container = fromInstance(plugin);
if (container == null) {
throw new IllegalArgumentException("Specified plugin is not loaded");
}
return container;
}
}

Datei anzeigen

@ -12,7 +12,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.emptyToNull;
import java.util.Objects;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
@ -43,17 +42,17 @@ public final class PluginDependency {
*
* @return the plugin ID
*/
public String getId() {
public String id() {
return id;
}
/**
* Returns the version this {@link PluginDependency} should match.
*
* @return an {@link Optional} with the plugin version, may be empty
* @return a String with the plugin version, may be {@code null}
*/
public Optional<String> getVersion() {
return Optional.ofNullable(version);
public @Nullable String version() {
return version;
}
/**
@ -61,7 +60,7 @@ public final class PluginDependency {
*
* @return true if dependency is optional
*/
public boolean isOptional() {
public boolean optional() {
return optional;
}

Datei anzeigen

@ -19,12 +19,11 @@ import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerInfo;
import com.velocitypowered.api.scheduler.Scheduler;
import com.velocitypowered.api.util.ProxyVersion;
import java.net.SocketAddress;
import java.util.Collection;
import java.util.Optional;
import java.util.UUID;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Provides an interface to a Minecraft server proxy.
@ -48,17 +47,17 @@ public interface ProxyServer extends Audience {
* is case-insensitive.
*
* @param username the username to search for
* @return an {@link Optional} with the player, which may be empty
* @return the player instance, if connected, else {@code null}
*/
Optional<Player> getPlayer(String username);
@Nullable Player player(String username);
/**
* Retrieves the player currently connected to this proxy by their Minecraft UUID.
*
* @param uuid the UUID
* @return an {@link Optional} with the player, which may be empty
* @return the player instance, if connected, else {@code null}
*/
Optional<Player> getPlayer(UUID uuid);
@Nullable Player player(UUID uuid);
/**
* Retrieves all players currently connected to this proxy. This call may or may not be a snapshot
@ -82,7 +81,7 @@ public interface ProxyServer extends Audience {
* @param name the name of the server
* @return the registered server, which may be empty
*/
Optional<RegisteredServer> server(String name);
@Nullable RegisteredServer server(String name);
/**
* Retrieves all {@link RegisteredServer}s registered with this proxy.

Datei anzeigen

@ -11,7 +11,7 @@ import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.util.Favicon;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Exposes certain proxy configuration information that plugins may use.
@ -126,7 +126,7 @@ public interface ProxyConfig {
*
* @return optional favicon
*/
Optional<Favicon> getFavicon();
@Nullable Favicon getFavicon();
/**
* Get whether this proxy displays that it supports Forge/FML.

Datei anzeigen

@ -10,7 +10,7 @@ package com.velocitypowered.api.proxy.connection;
import com.velocitypowered.api.network.ProtocolVersion;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Represents an incoming connection to the proxy.
@ -29,7 +29,7 @@ public interface InboundConnection {
*
* @return the hostname from the client
*/
Optional<InetSocketAddress> connectedHostname();
@Nullable InetSocketAddress connectedHostname();
/**
* Determine whether or not the player remains online.

Datei anzeigen

@ -19,10 +19,10 @@ import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.api.util.ModInfo;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import net.kyori.adventure.identity.Identified;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Represents a player who is connected to the proxy.
@ -47,9 +47,10 @@ public interface Player extends CommandSource, Identified, InboundConnection,
/**
* Returns the server that the player is currently connected to.
*
* @return an {@link Optional} the server that the player is connected to, which may be empty
* @return the server that the player is connected to, which could be {@code null} if no
* connection was made yet (or the player is switching servers)
*/
Optional<ServerConnection> connectedServer();
@Nullable ServerConnection connectedServer();
/**
* Returns the player's client settings.
@ -61,9 +62,9 @@ public interface Player extends CommandSource, Identified, InboundConnection,
/**
* Returns the player's mod info if they have a modded client.
*
* @return an {@link Optional} the mod info. which may be empty
* @return an the mod info. which may be {@code null} if no info is available
*/
Optional<ModInfo> modInfo();
@Nullable ModInfo modInfo();
/**
* Returns the current player's ping.

Datei anzeigen

@ -9,9 +9,9 @@ package com.velocitypowered.api.proxy.player;
import com.velocitypowered.api.proxy.connection.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Provides a fluent interface to send a connection request to another server on the proxy. A
@ -76,7 +76,7 @@ public interface ConnectionRequestBuilder {
*
* @return the reason why the user could not connect to the server
*/
Optional<Component> failureReason();
@Nullable Component failureReason();
/**
* Returns the server we actually tried to connect to.

Datei anzeigen

@ -10,7 +10,6 @@ package com.velocitypowered.api.proxy.player;
import com.velocitypowered.api.proxy.connection.Player;
import com.velocitypowered.api.util.GameProfile;
import java.util.Collection;
import java.util.Optional;
import java.util.UUID;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -45,10 +44,9 @@ public interface TabList {
* the specified {@link UUID}.
*
* @param uuid of the entry
* @return {@link Optional} containing the removed {@link TabListEntry} if present, otherwise
* {@link Optional#empty()}
* @return the removed {@link TabListEntry} if present, otherwise {@code null}
*/
Optional<TabListEntry> removeEntry(UUID uuid);
@Nullable TabListEntry removeEntry(UUID uuid);
/**
* Determines if the specified entry exists in the tab list.

Datei anzeigen

@ -8,7 +8,6 @@
package com.velocitypowered.api.proxy.player;
import com.velocitypowered.api.util.GameProfile;
import java.util.Optional;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -34,18 +33,17 @@ public interface TabListEntry {
GameProfile gameProfile();
/**
* Returns {@link Optional} text {@link Component}, which if present is the text
* Returns an optional text {@link Component}, which if present is the text
* displayed for {@code this} entry in the {@link TabList}, otherwise
* {@link GameProfile#getName()} is shown.
* {@link GameProfile#name()} is shown.
*
* @return {@link Optional} text {@link Component} of name displayed in the tab
* list
* @return text {@link Component} of name displayed in the tab list
*/
Optional<Component> displayName();
@Nullable Component displayName();
/**
* Sets the text {@link Component} to be displayed for {@code this} {@link TabListEntry}. If
* {@code null}, {@link GameProfile#getName()} will be shown.
* {@code null}, {@link GameProfile#name()} will be shown.
*
* @param displayName to show in the {@link TabList} for {@code this} entry
* @return {@code this}, for chaining

Datei anzeigen

@ -18,7 +18,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -423,8 +422,8 @@ public final class QueryResponse {
return name;
}
public Optional<String> getVersion() {
return Optional.ofNullable(version);
public @Nullable String getVersion() {
return version;
}
public static PluginInformation of(String name, @Nullable String version) {

Datei anzeigen

@ -16,7 +16,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -60,20 +59,20 @@ public final class ServerPing {
return version;
}
public Optional<Players> players() {
return Optional.ofNullable(players);
public @Nullable Players players() {
return players;
}
public Component description() {
return description;
}
public Optional<Favicon> favicon() {
return Optional.ofNullable(favicon);
public @Nullable Favicon favicon() {
return favicon;
}
public Optional<ModInfo> modInfo() {
return Optional.ofNullable(modinfo);
public @Nullable ModInfo modInfo() {
return modinfo;
}
@Override
@ -271,12 +270,12 @@ public final class ServerPing {
return samplePlayers;
}
public Optional<Component> getDescription() {
return Optional.ofNullable(description);
public @Nullable Component getDescription() {
return description;
}
public Optional<Favicon> getFavicon() {
return Optional.ofNullable(favicon);
public @Nullable Favicon getFavicon() {
return favicon;
}
public String getModType() {

Datei anzeigen

@ -11,11 +11,15 @@ import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.UUID;
import net.kyori.adventure.identity.Identified;
import net.kyori.adventure.identity.Identity;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.jetbrains.annotations.NotNull;
/**
* Represents a Mojang game profile. This class is immutable.
*/
public final class GameProfile {
public final class GameProfile implements Identified, Identity {
private final UUID id;
private final String undashedId;
@ -55,7 +59,7 @@ public final class GameProfile {
* Returns the undashed, Mojang-style UUID.
* @return the undashed UUID
*/
public String getUndashedId() {
public String undashedId() {
return undashedId;
}
@ -63,7 +67,8 @@ public final class GameProfile {
* Returns the UUID associated with this game profile.
* @return the UUID
*/
public UUID getId() {
@Override
public @NotNull UUID uuid() {
return id;
}
@ -71,7 +76,7 @@ public final class GameProfile {
* Returns the username associated with this profile.
* @return the username
*/
public String getName() {
public String name() {
return name;
}
@ -79,7 +84,7 @@ public final class GameProfile {
* Returns an immutable list of profile properties associated with this profile.
* @return the properties associated with this profile
*/
public List<Property> getProperties() {
public List<Property> properties() {
return properties;
}
@ -89,7 +94,7 @@ public final class GameProfile {
* @param id the new unique id
* @return the new {@code GameProfile}
*/
public GameProfile withId(UUID id) {
public GameProfile withUuid(UUID id) {
return new GameProfile(Preconditions.checkNotNull(id, "id"), UuidUtils.toUndashed(id),
this.name, this.properties);
}
@ -172,6 +177,11 @@ public final class GameProfile {
+ '}';
}
@Override
public @NonNull Identity identity() {
return this;
}
/**
* Represents a Mojang profile property. Just like {@link GameProfile}, this class is immutable.
*/
@ -193,15 +203,15 @@ public final class GameProfile {
this.signature = Preconditions.checkNotNull(signature, "signature");
}
public String getName() {
public String name() {
return name;
}
public String getValue() {
public String value() {
return value;
}
public String getSignature() {
public String signature() {
return signature;
}

Datei anzeigen

@ -333,7 +333,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
eventManager.registerInternally(plugin, instance.get());
} catch (Exception e) {
logger.error("Unable to register plugin listener for {}",
plugin.description().name().orElse(plugin.description().id()), e);
MoreObjects.firstNonNull(plugin.description().name(), plugin.description().id()), e);
}
}
}
@ -373,18 +373,18 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
for (Map.Entry<String, String> entry : newConfiguration.getServers().entrySet()) {
ServerInfo newInfo =
new ServerInfo(entry.getKey(), AddressUtil.parseAddress(entry.getValue()));
Optional<RegisteredServer> rs = servers.getServer(entry.getKey());
if (!rs.isPresent()) {
RegisteredServer rs = servers.getServer(entry.getKey());
if (rs == null) {
servers.register(newInfo);
} else if (!rs.get().serverInfo().equals(newInfo)) {
for (Player player : rs.get().connectedPlayers()) {
} else if (!rs.serverInfo().equals(newInfo)) {
for (Player player : rs.connectedPlayers()) {
if (!(player instanceof ConnectedPlayer)) {
throw new IllegalStateException("ConnectedPlayer not found for player " + player
+ " in server " + rs.get().serverInfo().name());
+ " in server " + rs.serverInfo().name());
}
evacuate.add((ConnectedPlayer) player);
}
servers.unregister(rs.get().serverInfo());
servers.unregister(rs.serverInfo());
servers.register(newInfo);
}
}
@ -393,9 +393,9 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
if (!evacuate.isEmpty()) {
CountDownLatch latch = new CountDownLatch(evacuate.size());
for (ConnectedPlayer player : evacuate) {
Optional<RegisteredServer> next = player.getNextServerToTry();
if (next.isPresent()) {
player.createConnectionRequest(next.get()).connectWithIndication()
RegisteredServer next = player.getNextServerToTry();
if (next != null) {
player.createConnectionRequest(next).connectWithIndication()
.whenComplete((success, ex) -> {
if (ex != null || success == null || !success) {
player.disconnect(Component.text("Your server has been changed, but we could "
@ -613,15 +613,15 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
}
@Override
public Optional<Player> getPlayer(String username) {
public @Nullable Player player(String username) {
Preconditions.checkNotNull(username, "username");
return Optional.ofNullable(connectionsByName.get(username.toLowerCase(Locale.US)));
return connectionsByName.get(username.toLowerCase(Locale.US));
}
@Override
public Optional<Player> getPlayer(UUID uuid) {
public @Nullable Player player(UUID uuid) {
Preconditions.checkNotNull(uuid, "uuid");
return Optional.ofNullable(connectionsByUuid.get(uuid));
return connectionsByUuid.get(uuid);
}
@Override
@ -653,7 +653,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
}
@Override
public Optional<RegisteredServer> server(String name) {
public @Nullable RegisteredServer server(String name) {
return servers.getServer(name);
}

Datei anzeigen

@ -17,6 +17,7 @@
package com.velocitypowered.proxy.command;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.mojang.brigadier.CommandDispatcher;
@ -164,7 +165,8 @@ public class VelocityCommandManager implements CommandManager {
if (commandResult.isForwardToServer() || !commandResult.isAllowed()) {
return false;
}
return executeImmediately0(source, commandResult.modifiedCommand().orElse(event.rawCommand()));
return executeImmediately0(source,
MoreObjects.firstNonNull(commandResult.modifiedCommand(), event.rawCommand()));
}, eventManager.getAsyncExecutor());
}

Datei anzeigen

@ -33,7 +33,6 @@ import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.connection.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.util.List;
import java.util.Optional;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
@ -92,13 +91,13 @@ public class GlistCommand {
}
sendTotalProxyCount(source);
} else {
Optional<RegisteredServer> registeredServer = server.server(serverName);
if (!registeredServer.isPresent()) {
RegisteredServer registeredServer = server.server(serverName);
if (registeredServer == null) {
source.sendMessage(Identity.nil(),
CommandMessages.SERVER_DOES_NOT_EXIST.args(Component.text(serverName)));
return -1;
}
sendServerPlayers(source, registeredServer.get(), false);
sendServerPlayers(source, registeredServer, false);
}
return 1;
}

Datei anzeigen

@ -62,21 +62,22 @@ public class ServerCommand implements SimpleCommand {
if (args.length == 1) {
// Trying to connect to a server.
String serverName = args[0];
Optional<RegisteredServer> toConnect = server.server(serverName);
if (!toConnect.isPresent()) {
RegisteredServer toConnect = server.server(serverName);
if (toConnect == null) {
player.sendMessage(Identity.nil(), CommandMessages.SERVER_DOES_NOT_EXIST
.args(Component.text(serverName)));
return;
}
player.createConnectionRequest(toConnect.get()).fireAndForget();
player.createConnectionRequest(toConnect).fireAndForget();
} else {
outputServerInformation(player);
}
}
private void outputServerInformation(Player executor) {
String currentServer = executor.connectedServer().map(ServerConnection::serverInfo)
String currentServer = Optional.ofNullable(executor.connectedServer())
.map(ServerConnection::serverInfo)
.map(ServerInfo::name).orElse("<unknown>");
executor.sendMessage(Identity.nil(), Component.translatable(
"velocity.command.server-current-server",

Datei anzeigen

@ -44,7 +44,6 @@ import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component;
@ -295,17 +294,17 @@ public class VelocityCommand implements SimpleCommand {
}
private TextComponent componentForPlugin(PluginDescription description) {
String pluginInfo = description.name().orElse(description.id())
+ description.version().map(v -> " " + v).orElse("");
String pluginInfo = description.name();
TextComponent.Builder hoverText = Component.text().content(pluginInfo);
description.url().ifPresent(url -> {
String pluginUrl = description.url();
if (pluginUrl != null) {
hoverText.append(Component.newline());
hoverText.append(Component.translatable(
"velocity.command.plugin-tooltip-website",
Component.text(url)));
});
Component.text(pluginUrl)));
}
if (!description.authors().isEmpty()) {
hoverText.append(Component.newline());
if (description.authors().size() == 1) {
@ -319,11 +318,13 @@ public class VelocityCommand implements SimpleCommand {
);
}
}
description.description().ifPresent(pdesc -> {
String humanDescription = description.description();
if (humanDescription != null) {
hoverText.append(Component.newline());
hoverText.append(Component.newline());
hoverText.append(Component.text(pdesc));
});
hoverText.append(Component.text(humanDescription));
}
return Component.text(description.id(), NamedTextColor.GRAY)
.hoverEvent(HoverEvent.showText(hoverText.build()));

Datei anzeigen

@ -44,7 +44,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
@ -315,8 +314,8 @@ public class VelocityConfiguration implements ProxyConfig {
}
@Override
public Optional<Favicon> getFavicon() {
return Optional.ofNullable(favicon);
public @Nullable Favicon getFavicon() {
return favicon;
}
@Override

Datei anzeigen

@ -179,7 +179,8 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|| sessionHandler instanceof HandshakeSessionHandler
|| sessionHandler instanceof StatusSessionHandler;
boolean isQuietDecoderException = cause instanceof QuietDecoderException;
boolean willLog = !isQuietDecoderException && !frontlineHandler;
boolean willLog = MinecraftDecoder.DEBUG
|| (!isQuietDecoderException && !frontlineHandler);
if (willLog) {
logger.error("{}: exception encountered in {}", association, sessionHandler, cause);
} else {

Datei anzeigen

@ -37,7 +37,6 @@ import io.netty.buffer.Unpooled;
import io.netty.channel.unix.DomainSocketAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Optional;
import java.util.StringJoiner;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.key.Key;
@ -69,18 +68,20 @@ public class BungeeCordMessageResponder {
private void processConnect(ByteBufDataInput in) {
String serverName = in.readUTF();
proxy.server(serverName).ifPresent(server -> player.createConnectionRequest(server)
.fireAndForget());
RegisteredServer server = proxy.server(serverName);
if (server != null) {
player.createConnectionRequest(server).fireAndForget();
}
}
private void processConnectOther(ByteBufDataInput in) {
String playerName = in.readUTF();
String serverName = in.readUTF();
Optional<Player> referencedPlayer = proxy.getPlayer(playerName);
Optional<RegisteredServer> referencedServer = proxy.server(serverName);
if (referencedPlayer.isPresent() && referencedServer.isPresent()) {
referencedPlayer.get().createConnectionRequest(referencedServer.get()).fireAndForget();
Player referencedPlayer = proxy.player(playerName);
RegisteredServer referencedServer = proxy.server(serverName);
if (referencedPlayer != null && referencedServer != null) {
referencedPlayer.createConnectionRequest(referencedServer).fireAndForget();
}
}
@ -111,12 +112,13 @@ public class BungeeCordMessageResponder {
out.writeUTF("ALL");
out.writeInt(proxy.countConnectedPlayers());
} else {
proxy.server(target).ifPresent(rs -> {
int playersOnServer = rs.connectedPlayers().size();
RegisteredServer referencedServer = proxy.server(target);
if (referencedServer != null) {
int playersOnServer = referencedServer.connectedPlayers().size();
out.writeUTF("PlayerCount");
out.writeUTF(rs.serverInfo().name());
out.writeUTF(referencedServer.serverInfo().name());
out.writeInt(playersOnServer);
});
}
}
if (buf.isReadable()) {
@ -141,16 +143,17 @@ public class BungeeCordMessageResponder {
}
out.writeUTF(joiner.toString());
} else {
proxy.server(target).ifPresent(info -> {
RegisteredServer referencedServer = proxy.server(target);
if (referencedServer != null) {
out.writeUTF("PlayerList");
out.writeUTF(info.serverInfo().name());
out.writeUTF(referencedServer.serverInfo().name());
StringJoiner joiner = new StringJoiner(", ");
for (Player online : info.connectedPlayers()) {
for (Player online : referencedServer.connectedPlayers()) {
joiner.add(online.username());
}
out.writeUTF(joiner.toString());
});
}
}
if (buf.isReadable()) {
@ -191,8 +194,10 @@ public class BungeeCordMessageResponder {
if (target.equals("ALL")) {
proxy.sendMessage(Identity.nil(), messageComponent);
} else {
proxy.getPlayer(target).ifPresent(player -> player.sendMessage(Identity.nil(),
messageComponent));
Player player = proxy.player(target);
if (player != null) {
player.sendMessage(Identity.nil(), messageComponent);
}
}
}
@ -217,7 +222,8 @@ public class BungeeCordMessageResponder {
}
private void processUuidOther(ByteBufDataInput in) {
proxy.getPlayer(in.readUTF()).ifPresent(player -> {
Player player = proxy.player(in.readUTF());
if (player != null) {
ByteBuf buf = Unpooled.buffer();
ByteBufDataOutput out = new ByteBufDataOutput(buf);
@ -226,11 +232,12 @@ public class BungeeCordMessageResponder {
out.writeUTF(UuidUtils.toUndashed(player.id()));
sendResponseOnConnection(buf);
});
}
}
private void processIpOther(ByteBufDataInput in) {
proxy.getPlayer(in.readUTF()).ifPresent(player -> {
Player player = proxy.player(in.readUTF());
if (player != null) {
ByteBuf buf = Unpooled.buffer();
ByteBufDataOutput out = new ByteBufDataOutput(buf);
@ -247,11 +254,12 @@ public class BungeeCordMessageResponder {
}
sendResponseOnConnection(buf);
});
}
}
private void processServerIp(ByteBufDataInput in) {
proxy.server(in.readUTF()).ifPresent(info -> {
RegisteredServer info = proxy.server(in.readUTF());
if (info != null) {
ByteBuf buf = Unpooled.buffer();
ByteBufDataOutput out = new ByteBufDataOutput(buf);
@ -268,21 +276,22 @@ public class BungeeCordMessageResponder {
}
sendResponseOnConnection(buf);
});
}
}
private void processKick(ByteBufDataInput in) {
proxy.getPlayer(in.readUTF()).ifPresent(player -> {
Player player = proxy.player(in.readUTF());
if (player != null) {
String kickReason = in.readUTF();
player.disconnect(LegacyComponentSerializer.legacySection().deserialize(kickReason));
});
}
}
private void processForwardToPlayer(ByteBufDataInput in) {
Optional<Player> player = proxy.getPlayer(in.readUTF());
if (player.isPresent()) {
Player player = proxy.player(in.readUTF());
if (player != null) {
ByteBuf toForward = in.unwrap().copy();
sendServerResponse((ConnectedPlayer) player.get(), toForward);
sendServerResponse((ConnectedPlayer) player, toForward);
}
}
@ -299,9 +308,9 @@ public class BungeeCordMessageResponder {
toForward.release();
}
} else {
Optional<RegisteredServer> server = proxy.server(target);
if (server.isPresent()) {
((VelocityRegisteredServer) server.get()).sendPluginMessage(CHANNEL, toForward);
RegisteredServer server = proxy.server(target);
if (server != null) {
((VelocityRegisteredServer) server).sendPluginMessage(CHANNEL, toForward);
} else {
toForward.release();
}

Datei anzeigen

@ -168,9 +168,9 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
try {
ProtocolUtils.writeVarInt(forwarded, VelocityConstants.FORWARDING_VERSION);
ProtocolUtils.writeString(forwarded, address);
ProtocolUtils.writeUuid(forwarded, profile.getId());
ProtocolUtils.writeString(forwarded, profile.getName());
ProtocolUtils.writeProperties(forwarded, profile.getProperties());
ProtocolUtils.writeUuid(forwarded, profile.uuid());
ProtocolUtils.writeString(forwarded, profile.name());
ProtocolUtils.writeProperties(forwarded, profile.properties());
SecretKey key = new SecretKeySpec(hmacSecret, "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");

Datei anzeigen

@ -119,7 +119,8 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
}
private String playerConnectedHostname() {
return proxyPlayer.connectedHostname().map(InetSocketAddress::getHostString).orElse("");
InetSocketAddress vhost = proxyPlayer.connectedHostname();
return vhost == null ? "" : vhost.getHostString();
}
private String createLegacyForwardingAddress(UnaryOperator<List<Property>> propertiesTransform) {
@ -135,10 +136,10 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
.append('\0')
.append(((InetSocketAddress) proxyPlayer.remoteAddress()).getHostString())
.append('\0')
.append(proxyPlayer.gameProfile().getUndashedId())
.append(proxyPlayer.gameProfile().undashedId())
.append('\0');
GENERAL_GSON
.toJson(propertiesTransform.apply(proxyPlayer.gameProfile().getProperties()), data);
.toJson(propertiesTransform.apply(proxyPlayer.gameProfile().properties()), data);
return data.toString();
}
@ -233,7 +234,7 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
@Override
public String toString() {
return "[server connection] " + proxyPlayer.gameProfile().getName() + " -> "
return "[server connection] " + proxyPlayer.gameProfile().name() + " -> "
+ registeredServer.serverInfo().name();
}

Datei anzeigen

@ -22,6 +22,7 @@ import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8;
import static com.velocitypowered.proxy.network.PluginMessageUtil.constructChannelsPacket;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.velocitypowered.api.event.command.CommandExecuteEvent.CommandResult;
import com.velocitypowered.api.event.connection.PluginMessageEvent;
@ -65,7 +66,6 @@ import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
@ -598,7 +598,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
}
MinecraftConnection smc = player.ensureAndGetCurrentServer().ensureConnected();
String commandToRun = result.modifiedCommand().orElse(originalCommand);
String commandToRun = MoreObjects.firstNonNull(result.modifiedCommand(), originalCommand);
if (result.isForwardToServer()) {
return CompletableFuture.runAsync(() -> smc.write(new ServerboundChatPacket("/"
+ commandToRun)), smc.eventLoop());

Datei anzeigen

@ -81,7 +81,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
@ -162,17 +161,17 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
@Override
public String username() {
return profile.getName();
return profile.name();
}
@Override
public UUID id() {
return profile.getId();
return profile.uuid();
}
@Override
public Optional<ServerConnection> connectedServer() {
return Optional.ofNullable(connectedServer);
public @Nullable ServerConnection connectedServer() {
return connectedServer;
}
/**
@ -222,8 +221,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
}
@Override
public Optional<ModInfo> modInfo() {
return Optional.ofNullable(modInfo);
public @Nullable ModInfo modInfo() {
return modInfo;
}
public void setModInfo(ModInfo modInfo) {
@ -237,8 +236,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
}
@Override
public Optional<InetSocketAddress> connectedHostname() {
return Optional.ofNullable(virtualHost);
public @Nullable InetSocketAddress connectedHostname() {
return virtualHost;
}
void setPermissionFunction(PermissionFunction permissionFunction) {
@ -509,9 +508,12 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
boolean kickedFromCurrent = connectedServer == null || connectedServer.target().equals(rs);
ServerKickResult result;
if (kickedFromCurrent) {
Optional<RegisteredServer> next = getNextServerToTry(rs);
result = next.map(RedirectPlayer::create)
.orElseGet(() -> DisconnectPlayer.create(friendlyReason));
RegisteredServer next = getNextServerToTry(rs);
if (next == null) {
result = DisconnectPlayer.create(friendlyReason);
} else {
result = RedirectPlayer.create(next);
}
} else {
// If we were kicked by going to another server, the connection should not be in flight
if (connectionInFlight != null && connectionInFlight.target().equals(rs)) {
@ -562,11 +564,12 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
case CONNECTION_IN_PROGRESS:
// Fatal case
case CONNECTION_CANCELLED:
disconnect(status.failureReason().orElse(res.message()));
disconnect(status.failureReason() != null ? status.failureReason()
: res.message());
break;
case SERVER_DISCONNECTED:
Component reason = status.failureReason()
.orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR);
Component reason = status.failureReason() != null ? status.failureReason()
: ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR;
handleConnectionException(res.getServer(), ClientboundDisconnectPacket.create(reason,
protocolVersion()), ((Impl) status).isSafe());
break;
@ -601,7 +604,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
*
* @return the next server to try
*/
public Optional<RegisteredServer> getNextServerToTry() {
public @Nullable RegisteredServer getNextServerToTry() {
return this.getNextServerToTry(null);
}
@ -613,11 +616,10 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
*
* @return the next server to try
*/
private Optional<RegisteredServer> getNextServerToTry(@Nullable RegisteredServer current) {
private @Nullable RegisteredServer getNextServerToTry(@Nullable RegisteredServer current) {
if (serversToTry == null) {
String virtualHostStr = connectedHostname().map(InetSocketAddress::getHostString)
.orElse("")
.toLowerCase(Locale.ROOT);
InetSocketAddress vhost = connectedHostname();
String virtualHostStr = vhost == null ? "" : vhost.getHostString().toLowerCase(Locale.ROOT);
serversToTry = server.configuration().getForcedHosts().getOrDefault(virtualHostStr,
Collections.emptyList());
}
@ -637,7 +639,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
tryIndex = i;
return server.server(toTryName);
}
return Optional.empty();
return null;
}
private static boolean hasSameName(RegisteredServer server, String name) {
@ -684,15 +686,15 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
connectedServer.disconnect();
}
Optional<Player> connectedPlayer = server.getPlayer(this.id());
Player connectedPlayer = server.player(this.id());
server.unregisterConnection(this);
DisconnectEventImpl.LoginStatus status;
if (connectedPlayer.isPresent()) {
if (!connectedPlayer.get().connectedServer().isPresent()) {
if (connectedPlayer != null) {
if (connectedPlayer.connectedServer() != null) {
status = LoginStatus.PRE_SERVER_JOIN;
} else {
status = connectedPlayer.get() == this ? LoginStatus.SUCCESSFUL_LOGIN
status = connectedPlayer == this ? LoginStatus.SUCCESSFUL_LOGIN
: LoginStatus.CONFLICTING_LOGIN;
}
} else {
@ -716,7 +718,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
@Override
public String toString() {
return "[connected player] " + profile.getName() + " (" + remoteAddress() + ")";
return "[connected player] " + profile.name() + " (" + remoteAddress() + ")";
}
@Override
@ -847,45 +849,44 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
return toConnect;
}
private Optional<ConnectionRequestBuilder.Status> checkServer(RegisteredServer server) {
private ConnectionRequestBuilder.@Nullable Status checkServer(RegisteredServer server) {
Preconditions.checkArgument(server instanceof VelocityRegisteredServer,
"Not a valid Velocity server.");
if (connectionInFlight != null || (connectedServer != null
&& !connectedServer.hasCompletedJoin())) {
return Optional.of(ConnectionRequestBuilder.Status.CONNECTION_IN_PROGRESS);
return ConnectionRequestBuilder.Status.CONNECTION_IN_PROGRESS;
}
if (connectedServer != null && connectedServer.target().equals(server)) {
return Optional.of(ALREADY_CONNECTED);
return ALREADY_CONNECTED;
}
return Optional.empty();
return null;
}
private CompletableFuture<Optional<Status>> getInitialStatus() {
private CompletableFuture<ConnectionRequestBuilder.Status> getInitialStatus() {
return CompletableFuture.supplyAsync(() -> checkServer(toConnect), connection.eventLoop());
}
private CompletableFuture<Impl> internalConnect() {
return this.getInitialStatus()
.thenCompose(initialCheck -> {
if (initialCheck.isPresent()) {
return completedFuture(plainResult(initialCheck.get(), toConnect));
if (initialCheck != null) {
return completedFuture(plainResult(initialCheck, toConnect));
}
ServerPreConnectEvent event = new ServerPreConnectEventImpl(ConnectedPlayer.this,
toConnect);
return server.eventManager().fire(event)
.thenComposeAsync(newEvent -> {
Optional<RegisteredServer> newDest = newEvent.result().target();
if (!newDest.isPresent()) {
RegisteredServer realDestination = newEvent.result().target();
if (realDestination == null) {
return completedFuture(
plainResult(ConnectionRequestBuilder.Status.CONNECTION_CANCELLED, toConnect)
);
}
RegisteredServer realDestination = newDest.get();
Optional<ConnectionRequestBuilder.Status> check = checkServer(realDestination);
if (check.isPresent()) {
return completedFuture(plainResult(check.get(), realDestination));
ConnectionRequestBuilder.Status secondCheck = checkServer(realDestination);
if (secondCheck != null) {
return completedFuture(plainResult(secondCheck, realDestination));
}
VelocityRegisteredServer vrs = (VelocityRegisteredServer) realDestination;
@ -945,8 +946,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
// Ignored; the plugin probably already handled this.
break;
case SERVER_DISCONNECTED:
Component reason = status.failureReason()
.orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR);
Component reason = status.failureReason() != null ? status.failureReason()
: ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR;
handleConnectionException(toConnect, ClientboundDisconnectPacket.create(reason,
protocolVersion()), status.isSafe());
break;

Datei anzeigen

@ -40,7 +40,6 @@ import io.netty.buffer.ByteBuf;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Objects;
import java.util.Optional;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.apache.logging.log4j.LogManager;
@ -88,11 +87,11 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
LOGGER.error("{} provided invalid protocol {}", ic, handshake.getNextStatus());
connection.close(true);
} else {
connection.setState(nextState);
connection.setProtocolVersion(handshake.getProtocolVersion());
connection.setAssociation(ic);
if (nextState == ProtocolStates.STATUS) {
connection.setState(nextState);
connection.setSessionHandler(new StatusSessionHandler(server, connection, ic));
} else if (nextState == ProtocolStates.LOGIN) {
this.handleLogin(handshake, ic);
@ -134,12 +133,15 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
}
connection.setAutoReading(false);
connection.setState(ProtocolStates.LOGIN);
server.eventManager().fire(new ConnectionHandshakeEventImpl(ic, handshake.getServerAddress()))
.thenAcceptAsync(event -> {
connection.setAutoReading(true);
if (connection.isClosed()) {
return;
}
if (!event.result().isAllowed()) {
ic.disconnectQuietly(event.result().reason().get());
ic.disconnectQuietly(event.result().reason());
} else {
// if the handshake is changed, propagate the change
if (!event.currentHostname().equals(event.originalHostname())) {
@ -161,6 +163,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
}
connection.setSessionHandler(new LoginSessionHandler(server, connection, ic));
connection.setAutoReading(true);
}
}, connection.eventLoop());
}
@ -234,8 +237,8 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
}
@Override
public Optional<InetSocketAddress> connectedHostname() {
return Optional.ofNullable(ping.getVhost());
public @Nullable InetSocketAddress connectedHostname() {
return ping.getVhost();
}
@Override

Datei anzeigen

@ -27,8 +27,6 @@ import com.velocitypowered.proxy.network.packet.serverbound.ServerboundHandshake
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.kyori.adventure.translation.GlobalTranslator;
@ -58,8 +56,8 @@ public final class InitialInboundConnection implements InboundConnection,
}
@Override
public Optional<InetSocketAddress> connectedHostname() {
return Optional.of(InetSocketAddress.createUnresolved(cleanedHostname, handshake.getPort()));
public @Nullable InetSocketAddress connectedHostname() {
return InetSocketAddress.createUnresolved(cleanedHostname, handshake.getPort());
}
@Override

Datei anzeigen

@ -59,7 +59,6 @@ import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@ -194,10 +193,10 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
}
ComponentResult result = event.result();
Optional<Component> disconnectReason = result.reason();
if (disconnectReason.isPresent()) {
Component disconnectReason = result.reason();
if (disconnectReason != null) {
// The component is guaranteed to be provided if the connection was denied.
inbound.disconnect(disconnectReason.get());
inbound.disconnect(disconnectReason);
return;
}
@ -242,7 +241,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
// Initiate a regular connection and move over to it.
ConnectedPlayer player = new ConnectedPlayer(server, profileEvent.gameProfile(),
mcConnection, inbound.connectedHostname().orElse(null), onlineMode);
mcConnection, inbound.connectedHostname(), onlineMode);
this.connectedPlayer = player;
if (!server.canRegisterConnection(player)) {
player.disconnect0(Component.translatable("velocity.error.already-connected-proxy",
@ -302,9 +301,9 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
return;
}
Optional<Component> reason = event.result().reason();
if (reason.isPresent()) {
player.disconnect0(reason.get(), true);
Component denialReason = event.result().reason();
if (denialReason != null) {
player.disconnect0(denialReason, true);
} else {
if (!server.registerConnection(player)) {
player.disconnect0(Component.translatable("velocity.error.already-connected-proxy"),
@ -328,19 +327,19 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
}
private CompletableFuture<Void> connectToInitialServer(ConnectedPlayer player) {
Optional<RegisteredServer> initialFromConfig = player.getNextServerToTry();
RegisteredServer initialFromConfig = player.getNextServerToTry();
PlayerChooseInitialServerEvent event = new PlayerChooseInitialServerEventImpl(player,
initialFromConfig.orElse(null));
initialFromConfig);
return server.eventManager().fire(event)
.thenRunAsync(() -> {
Optional<RegisteredServer> toTry = event.initialServer();
if (!toTry.isPresent()) {
RegisteredServer toTry = event.initialServer();
if (toTry == null) {
player.disconnect0(Component.translatable("velocity.error.no-available-servers",
NamedTextColor.RED), true);
return;
}
player.createConnectionRequest(toTry.get()).fireAndForget();
player.createConnectionRequest(toTry).fireAndForget();
}, mcConnection.eventLoop());
}

Datei anzeigen

@ -43,7 +43,6 @@ import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -82,7 +81,7 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
new ServerPing.Players(server.countConnectedPlayers(), configuration.getShowMaxPlayers(),
ImmutableList.of()),
configuration.getMotd(),
configuration.getFavicon().orElse(null),
configuration.getFavicon(),
configuration.isAnnounceForge() ? ModInfo.DEFAULT : null
);
}
@ -92,11 +91,11 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
ServerPing fallback = constructLocalPing(pingingVersion);
List<CompletableFuture<ServerPing>> pings = new ArrayList<>();
for (String s : servers) {
Optional<RegisteredServer> rs = server.server(s);
if (!rs.isPresent()) {
RegisteredServer rs = server.server(s);
if (rs == null) {
continue;
}
VelocityRegisteredServer vrs = (VelocityRegisteredServer) rs.get();
VelocityRegisteredServer vrs = (VelocityRegisteredServer) rs;
pings.add(vrs.ping(connection.eventLoop(), pingingVersion));
}
if (pings.isEmpty()) {
@ -124,9 +123,9 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
if (response == fallback) {
continue;
}
Optional<ModInfo> modInfo = response.modInfo();
if (modInfo.isPresent()) {
return fallback.asBuilder().mods(modInfo.get()).build();
ModInfo modInfo = response.modInfo();
if (modInfo != null) {
return fallback.asBuilder().mods(modInfo).build();
}
}
return fallback;
@ -145,10 +144,10 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
return new ServerPing(
fallback.version(),
fallback.players().orElse(null),
fallback.players(),
response.description(),
fallback.favicon().orElse(null),
response.modInfo().orElse(null)
fallback.favicon(),
response.modInfo()
);
}
return fallback;
@ -168,9 +167,8 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
if (passthrough == PingPassthroughMode.DISABLED) {
return CompletableFuture.completedFuture(constructLocalPing(shownVersion));
} else {
String virtualHostStr = inbound.connectedHostname().map(InetSocketAddress::getHostString)
.map(str -> str.toLowerCase(Locale.ROOT))
.orElse("");
InetSocketAddress vhost = inbound.connectedHostname();
String virtualHostStr = vhost == null ? "" : vhost.getHostString().toLowerCase(Locale.ROOT);
List<String> serversToTry = server.configuration().getForcedHosts().getOrDefault(
virtualHostStr, server.configuration().getAttemptConnectionOrder());
return attemptPingPassthrough(configuration.getPingPassthrough(), serversToTry, shownVersion);

Datei anzeigen

@ -93,7 +93,7 @@ public enum LegacyForgeHandshakeClientPhase implements ClientConnectionPhase {
AbstractPluginMessagePacket<?> message,
MinecraftConnection backendConn) {
// Read the mod list if we haven't already.
if (!player.modInfo().isPresent()) {
if (player.modInfo() == null) {
List<ModInfo.Mod> mods = LegacyForgeUtil.readModList(message);
if (!mods.isEmpty()) {
player.setModInfo(new ModInfo("FML", mods));

Datei anzeigen

@ -21,7 +21,6 @@ import com.velocitypowered.api.proxy.player.ConnectionRequestBuilder;
import com.velocitypowered.api.proxy.player.ConnectionRequestBuilder.Status;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
import java.util.Optional;
import javax.annotation.Nullable;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
@ -89,8 +88,8 @@ public class ConnectionRequestResults {
}
@Override
public Optional<Component> failureReason() {
return Optional.ofNullable(component);
public @Nullable Component failureReason() {
return component;
}
@Override

Datei anzeigen

@ -290,12 +290,6 @@ public class VelocityEventManager implements EventManager {
}
}
private PluginContainer ensurePlugin(final Object plugin) {
requireNonNull(plugin, "plugin");
return pluginManager.fromInstance(plugin)
.orElseThrow(() -> new IllegalArgumentException("Specified plugin is not loaded"));
}
private void register(final List<HandlerRegistration> registrations) {
lock.writeLock().lock();
try {
@ -315,7 +309,7 @@ public class VelocityEventManager implements EventManager {
@Override
public void register(final Object plugin, final Object listener) {
requireNonNull(listener, "listener");
final PluginContainer pluginContainer = ensurePlugin(plugin);
final PluginContainer pluginContainer = pluginManager.ensurePluginContainer(plugin);
if (plugin == listener) {
throw new IllegalArgumentException("The plugin main instance is automatically registered.");
}
@ -326,7 +320,7 @@ public class VelocityEventManager implements EventManager {
@SuppressWarnings("unchecked")
public <E> void register(final Object plugin, final Class<E> eventClass,
final short order, final EventHandler<E> handler) {
final PluginContainer pluginContainer = ensurePlugin(plugin);
final PluginContainer pluginContainer = pluginManager.ensurePluginContainer(plugin);
requireNonNull(eventClass, "eventClass");
requireNonNull(handler, "handler");
@ -360,13 +354,13 @@ public class VelocityEventManager implements EventManager {
@Override
public void unregisterListeners(final Object plugin) {
final PluginContainer pluginContainer = ensurePlugin(plugin);
final PluginContainer pluginContainer = pluginManager.ensurePluginContainer(plugin);
unregisterIf(registration -> registration.plugin == pluginContainer);
}
@Override
public void unregisterListener(final Object plugin, final Object handler) {
final PluginContainer pluginContainer = ensurePlugin(plugin);
final PluginContainer pluginContainer = pluginManager.ensurePluginContainer(plugin);
requireNonNull(handler, "handler");
unregisterIf(registration ->
registration.plugin == pluginContainer && registration.handler == handler);

Datei anzeigen

@ -355,9 +355,9 @@ public enum ProtocolUtils {
public static void writeProperties(ByteBuf buf, List<GameProfile.Property> properties) {
writeVarInt(buf, properties.size());
for (GameProfile.Property property : properties) {
writeString(buf, property.getName());
writeString(buf, property.getValue());
String signature = property.getSignature();
writeString(buf, property.name());
writeString(buf, property.value());
String signature = property.signature();
if (signature != null && !signature.isEmpty()) {
buf.writeBoolean(true);
writeString(buf, signature);

Datei anzeigen

@ -17,6 +17,7 @@
package com.velocitypowered.proxy.network;
import static com.velocitypowered.proxy.network.HandlerNames.FLOW_HANDLER;
import static com.velocitypowered.proxy.network.HandlerNames.FRAME_DECODER;
import static com.velocitypowered.proxy.network.HandlerNames.FRAME_ENCODER;
import static com.velocitypowered.proxy.network.HandlerNames.LEGACY_PING_DECODER;
@ -29,6 +30,7 @@ import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.connection.MinecraftConnection;
import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler;
import com.velocitypowered.proxy.network.packet.PacketDirection;
import com.velocitypowered.proxy.network.pipeline.AutoReadHolderHandler;
import com.velocitypowered.proxy.network.pipeline.LegacyPingDecoder;
import com.velocitypowered.proxy.network.pipeline.LegacyPingEncoder;
import com.velocitypowered.proxy.network.pipeline.MinecraftDecoder;
@ -61,7 +63,8 @@ public class ServerChannelInitializer extends ChannelInitializer<Channel> {
.addLast(LEGACY_PING_ENCODER, LegacyPingEncoder.INSTANCE)
.addLast(FRAME_ENCODER, MinecraftVarintLengthEncoder.INSTANCE)
.addLast(MINECRAFT_DECODER, new MinecraftDecoder(PacketDirection.SERVERBOUND))
.addLast(MINECRAFT_ENCODER, new MinecraftEncoder(PacketDirection.CLIENTBOUND));
.addLast(MINECRAFT_ENCODER, new MinecraftEncoder(PacketDirection.CLIENTBOUND))
.addLast(FLOW_HANDLER, new AutoReadHolderHandler());
final MinecraftConnection connection = new MinecraftConnection(ch, this.server);
connection.setSessionHandler(new HandshakeSessionHandler(connection, this.server));

Datei anzeigen

@ -20,7 +20,6 @@ package com.velocitypowered.proxy.network.packet;
import com.google.common.base.MoreObjects;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.network.ProtocolUtils;
import io.netty.buffer.ByteBuf;
import java.util.function.LongFunction;
public abstract class AbstractKeepAlivePacket implements Packet {

Datei anzeigen

@ -18,8 +18,6 @@
package com.velocitypowered.proxy.network.packet;
import com.google.common.base.MoreObjects;
import com.velocitypowered.api.network.ProtocolVersion;
import io.netty.buffer.ByteBuf;
import java.util.function.LongFunction;
public abstract class AbstractStatusPingPacket implements Packet {

Datei anzeigen

@ -22,13 +22,10 @@ import com.google.common.base.Preconditions;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.network.ProtocolUtils;
import com.velocitypowered.proxy.network.packet.Packet;
import com.velocitypowered.proxy.network.packet.PacketDirection;
import com.velocitypowered.proxy.network.packet.PacketHandler;
import com.velocitypowered.proxy.network.packet.PacketReader;
import com.velocitypowered.proxy.network.packet.PacketWriter;
import io.netty.buffer.ByteBuf;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable;
public class ClientboundDisconnectPacket implements Packet {
public static final PacketReader<ClientboundDisconnectPacket> DECODER = (buf, version) ->

Datei anzeigen

@ -21,13 +21,10 @@ import static com.velocitypowered.proxy.network.ProtocolUtils.writeString;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.network.ProtocolUtils;
import com.velocitypowered.proxy.network.packet.Packet;
import com.velocitypowered.proxy.network.packet.PacketHandler;
import com.velocitypowered.proxy.network.packet.PacketReader;
import com.velocitypowered.proxy.network.packet.PacketWriter;
import io.netty.buffer.ByteBuf;
public class ClientboundHeaderAndFooterPacket implements Packet {
public static final PacketReader<ClientboundHeaderAndFooterPacket> DECODER = PacketReader.unsupported();

Datei anzeigen

@ -205,12 +205,12 @@ public class ClientboundPlayerListItemPacket implements Packet {
}
public static Item from(TabListEntry entry) {
return new Item(entry.gameProfile().getId())
.setName(entry.gameProfile().getName())
.setProperties(entry.gameProfile().getProperties())
return new Item(entry.gameProfile().uuid())
.setName(entry.gameProfile().name())
.setProperties(entry.gameProfile().properties())
.setLatency(entry.ping())
.setGameMode(entry.gameMode())
.setDisplayName(entry.displayName().orElse(null));
.setDisplayName(entry.displayName());
}
public @Nullable UUID getUuid() {

Datei anzeigen

@ -18,13 +18,11 @@
package com.velocitypowered.proxy.network.packet.clientbound;
import com.google.common.base.MoreObjects;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.network.ProtocolUtils;
import com.velocitypowered.proxy.network.packet.Packet;
import com.velocitypowered.proxy.network.packet.PacketHandler;
import com.velocitypowered.proxy.network.packet.PacketReader;
import com.velocitypowered.proxy.network.packet.PacketWriter;
import io.netty.buffer.ByteBuf;
import java.util.Objects;
public class ClientboundResourcePackRequestPacket implements Packet {

Datei anzeigen

@ -25,7 +25,6 @@ import com.velocitypowered.proxy.network.packet.Packet;
import com.velocitypowered.proxy.network.packet.PacketHandler;
import com.velocitypowered.proxy.network.packet.PacketReader;
import com.velocitypowered.proxy.network.packet.PacketWriter;
import io.netty.buffer.ByteBuf;
import java.util.Objects;
import java.util.UUID;

Datei anzeigen

@ -45,7 +45,10 @@ public class LegacyDisconnectPacket implements LegacyPacket {
*/
public static LegacyDisconnectPacket fromServerPing(ServerPing response,
LegacyMinecraftPingVersion version) {
Players players = response.players().orElse(FAKE_PLAYERS);
Players players = response.players();
if (players == null) {
players = FAKE_PLAYERS;
}
switch (version) {
case MINECRAFT_1_3:

Datei anzeigen

@ -24,7 +24,6 @@ import com.velocitypowered.proxy.network.packet.Packet;
import com.velocitypowered.proxy.network.packet.PacketHandler;
import com.velocitypowered.proxy.network.packet.PacketReader;
import com.velocitypowered.proxy.network.packet.PacketWriter;
import io.netty.buffer.ByteBuf;
public class ServerboundHandshakePacket implements Packet {
public static final PacketReader<ServerboundHandshakePacket> DECODER = (buf, version) -> {

Datei anzeigen

@ -43,7 +43,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
@ -203,8 +202,8 @@ public class GS4QueryHandler extends SimpleChannelInboundHandler<DatagramPacket>
List<QueryResponse.PluginInformation> result = new ArrayList<>();
for (PluginContainer plugin : server.pluginManager().plugins()) {
PluginDescription description = plugin.description();
result.add(QueryResponse.PluginInformation.of(description.name()
.orElse(description.id()), description.version().orElse(null)));
result.add(QueryResponse.PluginInformation.of(description.name(),
description.version()));
}
return result;
}
@ -272,8 +271,10 @@ public class GS4QueryHandler extends SimpleChannelInboundHandler<DatagramPacket>
while (iterator.hasNext()) {
QueryResponse.PluginInformation info = iterator.next();
pluginsString.append(info.getName());
Optional<String> version = info.getVersion();
version.ifPresent(s -> pluginsString.append(' ').append(s));
String version = info.getVersion();
if (version != null) {
pluginsString.append(' ').append(version);
}
if (iterator.hasNext()) {
pluginsString.append(';').append(' ');
}

Datei anzeigen

@ -73,11 +73,11 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
int originalReaderIndex = buf.readerIndex();
int packetId = ProtocolUtils.readVarInt(buf);
Packet packet = null;
Packet packet;
try {
packet = this.registry.readPacket(packetId, buf, this.version);
} catch (Exception e) {
throw handleDecodeFailure(e, packet, packetId); // TODO: packet is always null
throw handleDecodeFailure(e, packetId);
}
if (packet == null) {
buf.readerIndex(originalReaderIndex);
@ -85,7 +85,7 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
} else {
try {
if (buf.isReadable()) {
throw handleOverflow(packet, buf.readerIndex(), buf.writerIndex());
throw handleOverflow(packetId, buf.readerIndex(), buf.writerIndex());
}
ctx.fireChannelRead(packet);
} finally {
@ -94,39 +94,43 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
}
}
private void doLengthSanityChecks(ByteBuf buf, Packet packet) throws Exception {
// TODO: Reimplement this
private void doLengthSanityChecks(ByteBuf buf, int packetId, Packet packet) throws Exception {
int expectedMinLen = packet.expectedMinLength(buf, direction, version);
int expectedMaxLen = packet.expectedMaxLength(buf, direction, version);
if (expectedMaxLen != -1 && buf.readableBytes() > expectedMaxLen) {
throw handleOverflow(packet, expectedMaxLen, buf.readableBytes());
throw handleOverflow(packetId, expectedMaxLen, buf.readableBytes());
}
if (buf.readableBytes() < expectedMinLen) {
throw handleUnderflow(packet, expectedMaxLen, buf.readableBytes());
throw handleUnderflow(packetId, expectedMaxLen, buf.readableBytes());
}
}
private Exception handleOverflow(Packet packet, int expected, int actual) {
private Exception handleOverflow(int packetId, int expected, int actual) {
if (DEBUG) {
return new CorruptedFrameException("Packet sent for " + packet.getClass() + " was too "
Class<? extends Packet> packetClass = this.registry.lookupPacket(packetId);
return new CorruptedFrameException("Packet sent for " + packetClass + " was too "
+ "big (expected " + expected + " bytes, got " + actual + " bytes)");
} else {
return DECODE_FAILED;
}
}
private Exception handleUnderflow(Packet packet, int expected, int actual) {
private Exception handleUnderflow(int packetId, int expected, int actual) {
if (DEBUG) {
return new CorruptedFrameException("Packet sent for " + packet.getClass() + " was too "
Class<? extends Packet> packetClass = this.registry.lookupPacket(packetId);
return new CorruptedFrameException("Packet sent for " + packetClass + " was too "
+ "small (expected " + expected + " bytes, got " + actual + " bytes)");
} else {
return DECODE_FAILED;
}
}
private Exception handleDecodeFailure(Exception cause, Packet packet, int packetId) {
private Exception handleDecodeFailure(Exception cause, int packetId) {
if (DEBUG) {
Class<? extends Packet> packetClass = this.registry.lookupPacket(packetId);
return new CorruptedFrameException(
"Error decoding " + packet.getClass() + " " + getExtraConnectionDetail(packetId), cause);
"Error decoding " + packetClass + " " + getExtraConnectionDetail(packetId), cause);
} else {
return DECODE_FAILED;
}

Datei anzeigen

@ -36,7 +36,7 @@ public class DensePacketRegistryMap implements PacketRegistryMap {
private final PacketReader<?>[] readersById;
private final PacketWriter[] writersByClass;
private final Class<?>[] classesById;
private final Class<?>[] classesByKey;
private final int[] idsByKey;
public DensePacketRegistryMap(Int2ObjectMap<PacketMapping<?>> mappings) {
@ -44,7 +44,7 @@ public class DensePacketRegistryMap implements PacketRegistryMap {
this.readersById = new PacketReader[size];
this.writersByClass = new PacketWriter[size * 2];
this.classesById = new Class[size * 2];
this.classesByKey = new Class[size * 2];
this.idsByKey = new int[size * 2];
for (PacketMapping<?> value : mappings.values()) {
@ -56,41 +56,41 @@ public class DensePacketRegistryMap implements PacketRegistryMap {
private void place(int packetId, Class<?> key, PacketWriter<?> value) {
int bucket = findEmpty(key);
this.writersByClass[bucket] = value;
this.classesById[bucket] = key;
this.classesByKey[bucket] = key;
this.idsByKey[bucket] = packetId;
}
private int findEmpty(Class<?> key) {
int start = key.hashCode() % this.classesById.length;
int start = key.hashCode() % this.classesByKey.length;
int index = start;
for (;;) {
if (this.classesById[index] == null || this.classesById[index].equals(key)) {
if (this.classesByKey[index] == null || this.classesByKey[index].equals(key)) {
// It's available, so no chance that this value exists anywhere in the map.
return index;
}
if ((index = (index + 1) % this.classesById.length) == start) {
if ((index = (index + 1) % this.classesByKey.length) == start) {
return -1;
}
}
}
private int index(Class<?> key) {
int start = key.hashCode() % this.classesById.length;
int start = key.hashCode() % this.classesByKey.length;
int index = start;
for (;;) {
if (this.classesById[index] == null) {
if (this.classesByKey[index] == null) {
// It's available, so no chance that this value exists anywhere in the map.
return -1;
}
if (key.equals(this.classesById[index])) {
if (key.equals(this.classesByKey[index])) {
return index;
}
// Conflict, keep probing ...
if ((index = (index + 1) % this.classesById.length) == start) {
if ((index = (index + 1) % this.classesByKey.length) == start) {
return -1;
}
}
@ -119,4 +119,14 @@ public class DensePacketRegistryMap implements PacketRegistryMap {
}
}
@Override
public @Nullable Class<? extends Packet> lookupPacket(int id) {
for (int bucket = 0; bucket < this.idsByKey.length; bucket++) {
if (this.idsByKey[bucket] == id) {
return (Class<? extends Packet>) this.classesByKey[bucket];
}
}
return null;
}
}

Datei anzeigen

@ -42,4 +42,9 @@ public class EmptyPacketRegistryMap implements PacketRegistryMap {
packet.getClass().getName(), version
));
}
@Override
public @Nullable Class<? extends Packet> lookupPacket(int id) {
return null;
}
}

Datei anzeigen

@ -26,4 +26,6 @@ public interface PacketRegistryMap {
@Nullable Packet readPacket(final int id, ByteBuf buf, ProtocolVersion version);
<P extends Packet> void writePacket(P packet, ByteBuf buf, ProtocolVersion version);
@Nullable Class<? extends Packet> lookupPacket(final int id);
}

Datei anzeigen

@ -27,6 +27,7 @@ import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap.Entry;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -81,4 +82,14 @@ public class RegularPacketRegistryMap implements PacketRegistryMap {
ProtocolUtils.writeVarInt(buf, packetId);
writer.write(buf, packet, version);
}
@Override
public @Nullable Class<? extends Packet> lookupPacket(int id) {
for (Entry<Class<?>> entry : this.classesById.object2IntEntrySet()) {
if (entry.getIntValue() == id) {
return (Class<? extends Packet>) entry.getKey();
}
}
return null;
}
}

Datei anzeigen

@ -462,6 +462,17 @@ class PlayPacketRegistry implements ProtocolRegistry {
//noinspection unchecked
encoder.write(buf, packet, version);
}
@Override
public @Nullable Class<? extends Packet> lookupPacket(int id) {
for (Object2IntMap.Entry<Class<? extends Packet>> entry : this.packetClassToId
.object2IntEntrySet()) {
if (entry.getIntValue() == id) {
return entry.getKey();
}
}
return null;
}
}
}

Datei anzeigen

@ -51,9 +51,9 @@ public final class GameProfileSerializer implements JsonSerializer<GameProfile>,
@Override
public JsonElement serialize(GameProfile src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject obj = new JsonObject();
obj.add("id", new JsonPrimitive(src.getUndashedId()));
obj.add("name", new JsonPrimitive(src.getName()));
obj.add("properties", context.serialize(src.getProperties(), propertyList));
obj.add("id", new JsonPrimitive(src.undashedId()));
obj.add("name", new JsonPrimitive(src.name()));
obj.add("properties", context.serialize(src.properties(), propertyList));
return obj;
}
}

Datei anzeigen

@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Joiner;
import com.google.common.base.MoreObjects;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.google.inject.name.Names;
@ -52,6 +53,7 @@ import java.util.Optional;
import java.util.Set;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.Nullable;
public class VelocityPluginManager implements PluginManager {
@ -110,9 +112,9 @@ public class VelocityPluginManager implements PluginManager {
for (PluginDescription candidate : sortedPlugins) {
// Verify dependencies
for (PluginDependency dependency : candidate.dependencies()) {
if (!dependency.isOptional() && !loadedPluginsById.contains(dependency.getId())) {
if (!dependency.optional() && !loadedPluginsById.contains(dependency.id())) {
logger.error("Can't load plugin {} due to missing dependency {}", candidate.id(),
dependency.getId());
dependency.id());
continue pluginLoad;
}
}
@ -154,27 +156,27 @@ public class VelocityPluginManager implements PluginManager {
continue;
}
logger.info("Loaded plugin {} {} by {}", description.id(), description.version()
.orElse("<UNKNOWN>"), Joiner.on(", ").join(description.authors()));
logger.info("Loaded plugin {} {} by {}", description.id(), MoreObjects.firstNonNull(
description.version(), "<UNKNOWN>"), Joiner.on(", ").join(description.authors()));
registerPlugin(container);
}
}
@Override
public Optional<PluginContainer> fromInstance(Object instance) {
public @Nullable PluginContainer fromInstance(Object instance) {
checkNotNull(instance, "instance");
if (instance instanceof PluginContainer) {
return Optional.of((PluginContainer) instance);
return (PluginContainer) instance;
}
return Optional.ofNullable(pluginInstances.get(instance));
return pluginInstances.get(instance);
}
@Override
public Optional<PluginContainer> getPlugin(String id) {
public @Nullable PluginContainer getPlugin(String id) {
checkNotNull(id, "id");
return Optional.ofNullable(plugins.get(id));
return plugins.get(id);
}
@Override
@ -191,9 +193,12 @@ public class VelocityPluginManager implements PluginManager {
public void addToClasspath(Object plugin, Path path) {
checkNotNull(plugin, "instance");
checkNotNull(path, "path");
Optional<PluginContainer> optContainer = fromInstance(plugin);
checkArgument(optContainer.isPresent(), "plugin is not loaded");
Optional<?> optInstance = optContainer.get().instance();
PluginContainer optContainer = fromInstance(plugin);
if (optContainer == null) {
throw new IllegalArgumentException("plugin is not loaded");
}
Optional<?> optInstance = optContainer.instance();
checkArgument(optInstance.isPresent(), "plugin has no instance");
ClassLoader pluginClassloader = optInstance.get().getClass().getClassLoader();

Datei anzeigen

@ -28,7 +28,6 @@ import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.Nullable;
public class VelocityPluginDescription implements PluginDescription {
@ -62,7 +61,7 @@ public class VelocityPluginDescription implements PluginDescription {
this.description = Strings.emptyToNull(description);
this.url = Strings.emptyToNull(url);
this.authors = authors == null ? ImmutableList.of() : ImmutableList.copyOf(authors);
this.dependencies = Maps.uniqueIndex(dependencies, d -> d == null ? null : d.getId());
this.dependencies = Maps.uniqueIndex(dependencies, d -> d == null ? null : d.id());
this.source = source;
}
@ -72,23 +71,23 @@ public class VelocityPluginDescription implements PluginDescription {
}
@Override
public Optional<String> name() {
return Optional.ofNullable(name);
public String name() {
return name == null ? id : name;
}
@Override
public Optional<String> version() {
return Optional.ofNullable(version);
public @Nullable String version() {
return version;
}
@Override
public Optional<String> description() {
return Optional.ofNullable(description);
public @Nullable String description() {
return description;
}
@Override
public Optional<String> url() {
return Optional.ofNullable(url);
public @Nullable String url() {
return url;
}
@Override
@ -102,13 +101,13 @@ public class VelocityPluginDescription implements PluginDescription {
}
@Override
public Optional<PluginDependency> getDependency(String id) {
return Optional.ofNullable(dependencies.get(id));
public @Nullable PluginDependency getDependency(String id) {
return dependencies.get(id);
}
@Override
public Optional<Path> file() {
return Optional.ofNullable(source);
public @Nullable Path file() {
return source;
}
@Override

Datei anzeigen

@ -78,7 +78,10 @@ public class JavaPluginLoader implements PluginLoader {
throw new IllegalArgumentException("Description provided isn't of the Java plugin loader");
}
URL pluginJarUrl = source.file().get().toUri().toURL();
Path jarFilePath = source.file();
assert jarFilePath != null;
URL pluginJarUrl = jarFilePath.toUri().toURL();
PluginClassLoader loader = AccessController.doPrivileged(
(PrivilegedAction<PluginClassLoader>) () -> new PluginClassLoader(new URL[]{pluginJarUrl}));
loader.addToClassloaders();
@ -97,9 +100,9 @@ public class JavaPluginLoader implements PluginLoader {
}
JavaVelocityPluginDescription javaDescription = (JavaVelocityPluginDescription) description;
Optional<Path> source = javaDescription.file();
Path source = javaDescription.file();
if (!source.isPresent()) {
if (source == null) {
throw new IllegalArgumentException("No path in plugin description");
}
@ -184,13 +187,13 @@ public class JavaPluginLoader implements PluginLoader {
Class mainClass) {
return new JavaVelocityPluginDescription(
description.id(),
description.name().orElse(null),
description.version().orElse(null),
description.description().orElse(null),
description.url().orElse(null),
description.name(),
description.version(),
description.description(),
description.url(),
description.authors(),
description.dependencies(),
description.file().orElse(null),
description.file(),
mainClass
);
}

Datei anzeigen

@ -63,7 +63,7 @@ public class PluginDependencyUtils {
graph.addNode(description);
for (PluginDependency dependency : description.dependencies()) {
PluginDescription in = candidateMap.get(dependency.getId());
PluginDescription in = candidateMap.get(dependency.id());
if (in != null) {
graph.putEdge(description, in);

Datei anzeigen

@ -24,6 +24,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.velocitypowered.api.plugin.PluginDescription;
import com.velocitypowered.api.plugin.PluginManager;
import com.velocitypowered.api.scheduler.ScheduledTask;
import com.velocitypowered.api.scheduler.Scheduler;
@ -66,7 +67,7 @@ public class VelocityScheduler implements Scheduler {
public TaskBuilder buildTask(Object plugin, Runnable runnable) {
checkNotNull(plugin, "plugin");
checkNotNull(runnable, "runnable");
checkArgument(pluginManager.fromInstance(plugin).isPresent(), "plugin is not registered");
checkArgument(pluginManager.fromInstance(plugin) != null, "plugin is not registered");
return new TaskBuilderImpl(plugin, runnable);
}
@ -205,12 +206,10 @@ public class VelocityScheduler implements Scheduler {
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
} else {
String friendlyPluginName = pluginManager.fromInstance(plugin)
.map(container -> container.description().name()
.orElse(container.description().id()))
.orElse("UNKNOWN");
Log.logger.error("Exception in task {} by plugin {}", runnable, friendlyPluginName,
e);
PluginDescription description = pluginManager.ensurePluginContainer(plugin)
.description();
Log.logger.error("Exception in task {} by plugin {}", runnable,
description.name(), e);
}
} finally {
if (repeat == 0) {

Datei anzeigen

@ -25,7 +25,6 @@ import com.velocitypowered.proxy.VelocityServer;
import java.util.Collection;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -44,10 +43,10 @@ public class ServerMap {
* @param name the name to look up
* @return the server, if it exists
*/
public Optional<RegisteredServer> getServer(String name) {
public @Nullable RegisteredServer getServer(String name) {
Preconditions.checkNotNull(name, "server");
String lowerName = name.toLowerCase(Locale.US);
return Optional.ofNullable(servers.get(lowerName));
return servers.get(lowerName);
}
public Collection<RegisteredServer> getAllServers() {

Datei anzeigen

@ -31,7 +31,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import net.kyori.adventure.text.Component;
@ -75,18 +74,18 @@ public class VelocityTabList implements TabList {
Preconditions.checkNotNull(entry, "entry");
Preconditions.checkArgument(entry.parent().equals(this),
"The provided entry was not created by this tab list");
Preconditions.checkArgument(!entries.containsKey(entry.gameProfile().getId()),
Preconditions.checkArgument(!entries.containsKey(entry.gameProfile().uuid()),
"this TabList already contains an entry with the same uuid");
Preconditions.checkArgument(entry instanceof VelocityTabListEntry,
"Not a Velocity tab list entry");
connection.write(new ClientboundPlayerListItemPacket(ClientboundPlayerListItemPacket.ADD_PLAYER,
Collections.singletonList(ClientboundPlayerListItemPacket.Item.from(entry))));
entries.put(entry.gameProfile().getId(), (VelocityTabListEntry) entry);
entries.put(entry.gameProfile().uuid(), (VelocityTabListEntry) entry);
}
@Override
public Optional<TabListEntry> removeEntry(UUID uuid) {
public @Nullable TabListEntry removeEntry(UUID uuid) {
Preconditions.checkNotNull(uuid, "uuid");
TabListEntry entry = entries.remove(uuid);
@ -97,7 +96,7 @@ public class VelocityTabList implements TabList {
));
}
return Optional.ofNullable(entry);
return entry;
}
@Override
@ -202,7 +201,7 @@ public class VelocityTabList implements TabList {
}
void updateEntry(int action, TabListEntry entry) {
if (entries.containsKey(entry.gameProfile().getId())) {
if (entries.containsKey(entry.gameProfile().uuid())) {
connection.write(new ClientboundPlayerListItemPacket(action,
Collections.singletonList(ClientboundPlayerListItemPacket.Item.from(entry))));
}

Datei anzeigen

@ -21,7 +21,6 @@ import com.velocitypowered.api.proxy.player.TabList;
import com.velocitypowered.api.proxy.player.TabListEntry;
import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPlayerListItemPacket;
import java.util.Optional;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -53,8 +52,8 @@ public class VelocityTabListEntry implements TabListEntry {
}
@Override
public Optional<Component> displayName() {
return Optional.ofNullable(displayName);
public @Nullable Component displayName() {
return displayName;
}
@Override

Datei anzeigen

@ -31,7 +31,7 @@ public class VelocityTabListEntryLegacy extends VelocityTabListEntry {
@Override
public TabListEntry setDisplayName(@Nullable Component displayName) {
parent().removeEntry(gameProfile().getId()); // We have to remove first if updating
parent().removeEntry(gameProfile().uuid()); // We have to remove first if updating
return super.setDisplayName(displayName);
}
}

Datei anzeigen

@ -25,7 +25,6 @@ import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPlayerLis
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPlayerListItemPacket.Item;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import net.kyori.adventure.text.Component;
@ -50,13 +49,15 @@ public class VelocityTabListLegacy extends VelocityTabList {
@Override
public void addEntry(TabListEntry entry) {
super.addEntry(entry);
nameMapping.put(entry.gameProfile().getName(), entry.gameProfile().getId());
nameMapping.put(entry.gameProfile().name(), entry.gameProfile().uuid());
}
@Override
public Optional<TabListEntry> removeEntry(UUID uuid) {
Optional<TabListEntry> entry = super.removeEntry(uuid);
entry.map(TabListEntry::gameProfile).map(GameProfile::getName).ifPresent(nameMapping::remove);
public @Nullable TabListEntry removeEntry(UUID uuid) {
TabListEntry entry = super.removeEntry(uuid);
if (entry != null) {
nameMapping.remove(entry.gameProfile().name());
}
return entry;
}
@ -108,7 +109,7 @@ public class VelocityTabListLegacy extends VelocityTabList {
@Override
void updateEntry(int action, TabListEntry entry) {
if (entries.containsKey(entry.gameProfile().getId())) {
if (entries.containsKey(entry.gameProfile().uuid())) {
switch (action) {
case ClientboundPlayerListItemPacket.UPDATE_LATENCY:
case ClientboundPlayerListItemPacket.UPDATE_DISPLAY_NAME: // Add here because we

Datei anzeigen

@ -59,11 +59,11 @@ public enum InformationUtils {
PluginDescription desc = plugin.description();
JsonObject current = new JsonObject();
current.addProperty("id", desc.id());
if (desc.name().isPresent()) {
current.addProperty("name", desc.name().get());
}
if (desc.version().isPresent()) {
current.addProperty("version", desc.version().get());
current.addProperty("name", desc.name());
String version = desc.version();
if (version != null) {
current.addProperty("version", version);
}
if (!desc.authors().isEmpty()) {
JsonArray authorsArray = new JsonArray();
@ -72,16 +72,19 @@ public enum InformationUtils {
}
current.add("authors", authorsArray);
}
if (desc.description().isPresent()) {
current.addProperty("description", desc.description().get());
String humanDesc = desc.description();
if (humanDesc != null) {
current.addProperty("description", humanDesc);
}
if (desc.url().isPresent()) {
current.addProperty("url", desc.url().get());
String url = desc.url();
if (url != null) {
current.addProperty("url", url);
}
if (!desc.dependencies().isEmpty()) {
JsonArray dependencies = new JsonArray();
for (PluginDependency dependency : desc.dependencies()) {
dependencies.add(dependency.getId());
dependencies.add(dependency.id());
}
current.add("dependencies", dependencies);
}

Datei anzeigen

@ -19,7 +19,6 @@ package com.velocitypowered.proxy.util.bossbar;
import com.google.common.collect.MapMaker;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.connection.Player;
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.network.ProtocolUtils;
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundBossBarPacket;

Datei anzeigen

@ -22,20 +22,20 @@ import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.plugin.PluginManager;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.Nullable;
public class MockPluginManager implements PluginManager {
public static final PluginManager INSTANCE = new MockPluginManager();
@Override
public Optional<PluginContainer> fromInstance(final Object instance) {
return Optional.empty();
public @Nullable PluginContainer fromInstance(final Object instance) {
return null;
}
@Override
public Optional<PluginContainer> getPlugin(final String id) {
return Optional.empty();
public @Nullable PluginContainer getPlugin(final String id) {
return null;
}
@Override

Datei anzeigen

@ -25,6 +25,7 @@ import java.nio.file.Path;
import java.util.Collection;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
public class FakePluginManager implements PluginManager {
@ -35,25 +36,25 @@ public class FakePluginManager implements PluginManager {
private static final PluginContainer PC_B = new FakePluginContainer("b", PLUGIN_B);
@Override
public @NonNull Optional<PluginContainer> fromInstance(@NonNull Object instance) {
public @Nullable PluginContainer fromInstance(@NonNull Object instance) {
if (instance == PLUGIN_A) {
return Optional.of(PC_A);
return PC_A;
} else if (instance == PLUGIN_B) {
return Optional.of(PC_B);
return PC_B;
} else {
return Optional.empty();
return null;
}
}
@Override
public @NonNull Optional<PluginContainer> getPlugin(@NonNull String id) {
public @Nullable PluginContainer getPlugin(@NonNull String id) {
switch (id) {
case "a":
return Optional.of(PC_A);
return PC_A;
case "b":
return Optional.of(PC_B);
return PC_B;
default:
return Optional.empty();
return null;
}
}

Datei anzeigen

@ -25,7 +25,6 @@ import com.velocitypowered.api.proxy.server.ServerInfo;
import com.velocitypowered.proxy.server.ServerMap;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Optional;
import org.junit.jupiter.api.Test;
class ServerMapTest {
@ -39,9 +38,9 @@ class ServerMapTest {
ServerInfo info = new ServerInfo("TestServer", TEST_ADDRESS);
RegisteredServer connection = map.register(info);
assertEquals(Optional.of(connection), map.getServer("TestServer"));
assertEquals(Optional.of(connection), map.getServer("testserver"));
assertEquals(Optional.of(connection), map.getServer("TESTSERVER"));
assertEquals(connection, map.getServer("TestServer"));
assertEquals(connection, map.getServer("testserver"));
assertEquals(connection, map.getServer("TESTSERVER"));
}
@Test