3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-11-17 05:20:14 +01:00

feat: Implement RegisteredServer#ping(PingOptions) (#938)

Dieser Commit ist enthalten in:
Adrian 2023-01-26 00:33:07 -05:00 committet von GitHub
Ursprung f744b37ad5
Commit 8761d02def
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
4 geänderte Dateien mit 185 neuen und 8 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,159 @@
/*
* Copyright (C) 2018-2023 Velocity Contributors
*
* The Velocity API is licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in the api top-level directory.
*/
package com.velocitypowered.api.proxy.server;
import static com.google.common.base.Preconditions.checkNotNull;
import com.velocitypowered.api.network.ProtocolVersion;
import java.time.Duration;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import net.kyori.adventure.builder.AbstractBuilder;
import org.jetbrains.annotations.NotNull;
/**
* Contains the parameters used to ping a {@link RegisteredServer}.
* This class is immutable.
*
* @since 3.2.0
* @see RegisteredServer#ping(PingOptions)
*/
public final class PingOptions {
/**
* Default PingOptions.
*/
public static final PingOptions DEFAULT = PingOptions.builder().build();
private final ProtocolVersion protocolVersion;
private final long timeout;
private PingOptions(final Builder builder) {
this.protocolVersion = builder.protocolVersion;
this.timeout = builder.timeout;
}
/**
* The protocol version used to ping the server.
*
* @return the emulated Minecraft version
*/
public ProtocolVersion getProtocolVersion() {
return this.protocolVersion;
}
/**
* The maximum period of time to wait for a response from the remote server.
*
* @return the server ping timeout in milliseconds
*/
public long getTimeout() {
return this.timeout;
}
/**
* Create a new builder to assign values to a new PingOptions.
*
* @return a new {@link PingOptions.Builder}
*/
public static Builder builder() {
return new Builder();
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (!(o instanceof PingOptions)) {
return false;
}
final PingOptions other = (PingOptions) o;
return Objects.equals(this.protocolVersion, other.protocolVersion)
&& Objects.equals(this.timeout, other.timeout);
}
@Override
public int hashCode() {
return Objects.hash(this.protocolVersion, this.timeout);
}
@Override
public String toString() {
return "PingOptions{"
+ "protocolVersion=" + protocolVersion
+ ", timeout=" + timeout
+ '}';
}
/**
* A builder for {@link PingOptions} objects.
*
* @since 3.2.0
*/
public static final class Builder implements AbstractBuilder<PingOptions> {
private ProtocolVersion protocolVersion = ProtocolVersion.UNKNOWN;
private long timeout = 0;
private Builder() {
}
/**
* Sets the protocol with which the server is to be pinged.
*
* @param protocolVersion the specified protocol
* @return this builder
*/
public Builder version(final @NotNull ProtocolVersion protocolVersion) {
checkNotNull(protocolVersion, "protocolVersion cannot be null");
this.protocolVersion = protocolVersion;
return this;
}
/**
* Sets the maximum time to wait to get the required {@link ServerPing}.
*
* @param timeout the timeout duration
* A value of 0 means that the read-timeout value
* from the Velocity configuration will be used,
* while a negative value means that there will
* be no timeout.
* @return this builder
*/
public Builder timeout(final @NotNull Duration timeout) {
checkNotNull(timeout, "timeout cannot be null");
this.timeout = timeout.toMillis();
return this;
}
/**
* Sets the maximum time to wait to get the required {@link ServerPing}.
*
* @param time the timeout duration
* A value of 0 means that the read-timeout value
* from the Velocity configuration will be used,
* while a negative value means that there will
* be no timeout.
* @param timeunit the unit of time to be used to provide the timeout duration
* @return this builder
*/
public Builder timeout(final long time, final @NotNull TimeUnit timeunit) {
checkNotNull(timeunit, "timeunit cannot be null");
this.timeout = timeunit.toMillis(time);
return this;
}
/**
* Create a new {@link PingOptions} with the values of this Builder.
*
* @return a new PingOptions object
*/
@Override
public @NotNull PingOptions build() {
return new PingOptions(this);
}
}
}

Datei anzeigen

@ -40,4 +40,14 @@ public interface RegisteredServer extends ChannelMessageSink, Audience {
* @return the server ping result from the server * @return the server ping result from the server
*/ */
CompletableFuture<ServerPing> ping(); CompletableFuture<ServerPing> ping();
/**
* Attempts to ping the remote server and return the server list ping result
* according to the options provided.
*
* @param pingOptions the options provided for pinging the server
* @return the server ping result from the server
* @since 3.2.0
*/
CompletableFuture<ServerPing> ping(PingOptions pingOptions);
} }

Datei anzeigen

@ -20,6 +20,7 @@ package com.velocitypowered.proxy.connection.util;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.spotify.futures.CompletableFutures; import com.spotify.futures.CompletableFutures;
import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.server.PingOptions;
import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerPing; import com.velocitypowered.api.proxy.server.ServerPing;
import com.velocitypowered.api.util.ModInfo; import com.velocitypowered.api.util.ModInfo;
@ -64,11 +65,12 @@ public class ServerListPingHandler {
List<CompletableFuture<ServerPing>> pings = new ArrayList<>(); List<CompletableFuture<ServerPing>> pings = new ArrayList<>();
for (String s : servers) { for (String s : servers) {
Optional<RegisteredServer> rs = server.getServer(s); Optional<RegisteredServer> rs = server.getServer(s);
if (!rs.isPresent()) { if (rs.isEmpty()) {
continue; continue;
} }
VelocityRegisteredServer vrs = (VelocityRegisteredServer) rs.get(); VelocityRegisteredServer vrs = (VelocityRegisteredServer) rs.get();
pings.add(vrs.ping(connection.getConnection().eventLoop(), responseProtocolVersion)); pings.add(vrs.ping(connection.getConnection().eventLoop(), PingOptions.builder()
.version(responseProtocolVersion).build()));
} }
if (pings.isEmpty()) { if (pings.isEmpty()) {
return CompletableFuture.completedFuture(fallback); return CompletableFuture.completedFuture(fallback);

Datei anzeigen

@ -26,9 +26,9 @@ import static com.velocitypowered.proxy.network.Connections.READ_TIMEOUT;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.messages.ChannelIdentifier; import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
import com.velocitypowered.api.proxy.server.PingOptions;
import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerInfo; import com.velocitypowered.api.proxy.server.ServerInfo;
import com.velocitypowered.api.proxy.server.ServerPing; import com.velocitypowered.api.proxy.server.ServerPing;
@ -83,9 +83,14 @@ public class VelocityRegisteredServer implements RegisteredServer, ForwardingAud
return ImmutableList.copyOf(players.values()); return ImmutableList.copyOf(players.values());
} }
@Override
public CompletableFuture<ServerPing> ping(PingOptions pingOptions) {
return ping(null, pingOptions);
}
@Override @Override
public CompletableFuture<ServerPing> ping() { public CompletableFuture<ServerPing> ping() {
return ping(null, ProtocolVersion.UNKNOWN); return ping(null, PingOptions.DEFAULT);
} }
/** /**
@ -93,10 +98,10 @@ public class VelocityRegisteredServer implements RegisteredServer, ForwardingAud
* {@code version}. * {@code version}.
* *
* @param loop the event loop to use * @param loop the event loop to use
* @param version the version to report * @param pingOptions the options to apply to this ping
* @return the server list ping response * @return the server list ping response
*/ */
public CompletableFuture<ServerPing> ping(@Nullable EventLoop loop, ProtocolVersion version) { public CompletableFuture<ServerPing> ping(@Nullable EventLoop loop, PingOptions pingOptions) {
if (server == null) { if (server == null) {
throw new IllegalStateException("No Velocity proxy instance available"); throw new IllegalStateException("No Velocity proxy instance available");
} }
@ -108,7 +113,8 @@ public class VelocityRegisteredServer implements RegisteredServer, ForwardingAud
ch.pipeline() ch.pipeline()
.addLast(FRAME_DECODER, new MinecraftVarintFrameDecoder()) .addLast(FRAME_DECODER, new MinecraftVarintFrameDecoder())
.addLast(READ_TIMEOUT, .addLast(READ_TIMEOUT,
new ReadTimeoutHandler(server.getConfiguration().getReadTimeout(), new ReadTimeoutHandler(pingOptions.getTimeout() == 0
? server.getConfiguration().getReadTimeout() : pingOptions.getTimeout(),
TimeUnit.MILLISECONDS)) TimeUnit.MILLISECONDS))
.addLast(FRAME_ENCODER, MinecraftVarintLengthEncoder.INSTANCE) .addLast(FRAME_ENCODER, MinecraftVarintLengthEncoder.INSTANCE)
.addLast(MINECRAFT_DECODER, .addLast(MINECRAFT_DECODER,
@ -124,7 +130,7 @@ public class VelocityRegisteredServer implements RegisteredServer, ForwardingAud
if (future.isSuccess()) { if (future.isSuccess()) {
MinecraftConnection conn = future.channel().pipeline().get(MinecraftConnection.class); MinecraftConnection conn = future.channel().pipeline().get(MinecraftConnection.class);
conn.setSessionHandler(new PingSessionHandler( conn.setSessionHandler(new PingSessionHandler(
pingFuture, VelocityRegisteredServer.this, conn, version)); pingFuture, VelocityRegisteredServer.this, conn, pingOptions.getProtocolVersion()));
} else { } else {
pingFuture.completeExceptionally(future.cause()); pingFuture.completeExceptionally(future.cause());
} }