Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-24 15:20:35 +01:00
Implement RegisteredServer#ping()
Dieser Commit ist enthalten in:
Ursprung
1f8152c3a5
Commit
291069af80
@ -99,8 +99,6 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
if (association != null) {
|
||||
logger.error("{}: exception encountered", association, cause);
|
||||
} else {
|
||||
logger.error("{} encountered an exception", ctx.channel().remoteAddress(), cause);
|
||||
}
|
||||
|
||||
ctx.close();
|
||||
|
@ -8,13 +8,31 @@ import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintFrameDecoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintLengthEncoder;
|
||||
import com.velocitypowered.proxy.server.ping.PingSessionHandler;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import static com.velocitypowered.proxy.network.Connections.*;
|
||||
import static com.velocitypowered.proxy.network.Connections.HANDLER;
|
||||
import static com.velocitypowered.proxy.network.Connections.MINECRAFT_ENCODER;
|
||||
|
||||
public class VelocityRegisteredServer implements RegisteredServer {
|
||||
private final VelocityServer server;
|
||||
private final ServerInfo serverInfo;
|
||||
@ -43,9 +61,36 @@ public class VelocityRegisteredServer implements RegisteredServer {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<ServerPing> ping() {
|
||||
CompletableFuture<ServerPing> p = new CompletableFuture<>();
|
||||
p.completeExceptionally(new UnsupportedOperationException("Not currently implemented."));
|
||||
return p;
|
||||
CompletableFuture<ServerPing> pingFuture = new CompletableFuture<>();
|
||||
server.initializeGenericBootstrap()
|
||||
.handler(new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
protected void initChannel(Channel ch) throws Exception {
|
||||
ch.pipeline()
|
||||
.addLast(READ_TIMEOUT, new ReadTimeoutHandler(server.getConfiguration().getReadTimeout(), TimeUnit.SECONDS))
|
||||
.addLast(FRAME_DECODER, new MinecraftVarintFrameDecoder())
|
||||
.addLast(FRAME_ENCODER, MinecraftVarintLengthEncoder.INSTANCE)
|
||||
.addLast(MINECRAFT_DECODER, new MinecraftDecoder(ProtocolConstants.Direction.CLIENTBOUND))
|
||||
.addLast(MINECRAFT_ENCODER, new MinecraftEncoder(ProtocolConstants.Direction.SERVERBOUND));
|
||||
|
||||
MinecraftConnection connection = new MinecraftConnection(ch, server);
|
||||
connection.setState(StateRegistry.HANDSHAKE);
|
||||
ch.pipeline().addLast(HANDLER, connection);
|
||||
}
|
||||
})
|
||||
.connect(serverInfo.getAddress())
|
||||
.addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (future.isSuccess()) {
|
||||
MinecraftConnection conn = future.channel().pipeline().get(MinecraftConnection.class);
|
||||
conn.setSessionHandler(new PingSessionHandler(pingFuture, VelocityRegisteredServer.this, conn));
|
||||
} else {
|
||||
pingFuture.completeExceptionally(future.cause());
|
||||
}
|
||||
}
|
||||
});
|
||||
return pingFuture;
|
||||
}
|
||||
|
||||
public void addPlayer(ConnectedPlayer player) {
|
||||
|
@ -0,0 +1,67 @@
|
||||
package com.velocitypowered.proxy.server.ping;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.packet.Handshake;
|
||||
import com.velocitypowered.proxy.protocol.packet.StatusRequest;
|
||||
import com.velocitypowered.proxy.protocol.packet.StatusResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class PingSessionHandler implements MinecraftSessionHandler {
|
||||
private final CompletableFuture<ServerPing> result;
|
||||
private final RegisteredServer server;
|
||||
private final MinecraftConnection connection;
|
||||
private boolean completed = false;
|
||||
|
||||
public PingSessionHandler(CompletableFuture<ServerPing> result, RegisteredServer server, MinecraftConnection connection) {
|
||||
this.result = result;
|
||||
this.server = server;
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activated() {
|
||||
Handshake handshake = new Handshake();
|
||||
handshake.setNextStatus(StateRegistry.STATUS_ID);
|
||||
handshake.setServerAddress(server.getServerInfo().getAddress().getHostString());
|
||||
handshake.setPort(server.getServerInfo().getAddress().getPort());
|
||||
handshake.setProtocolVersion(ProtocolConstants.MINIMUM_GENERIC_VERSION);
|
||||
connection.write(handshake);
|
||||
|
||||
connection.setState(StateRegistry.STATUS);
|
||||
connection.write(new StatusRequest());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(MinecraftPacket packet) {
|
||||
Preconditions.checkState(packet instanceof StatusResponse, "Did not get status response back from connection");
|
||||
|
||||
// All good!
|
||||
completed = true;
|
||||
connection.close();
|
||||
|
||||
ServerPing ping = VelocityServer.GSON.fromJson(((StatusResponse) packet).getStatus(), ServerPing.class);
|
||||
result.complete(ping);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected() {
|
||||
if (!completed) {
|
||||
result.completeExceptionally(new IOException("Unexpectedly disconnected from remote server"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exception(Throwable throwable) {
|
||||
result.completeExceptionally(throwable);
|
||||
}
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren