13
0
geforkt von Mirrors/Velocity

Properly handle pings.

Dieser Commit ist enthalten in:
Andrew Steinborn 2018-07-26 14:50:42 -04:00
Ursprung a8df4c493e
Commit 80477f6a0e
5 geänderte Dateien mit 39 neuen und 4 gelöschten Zeilen

Datei anzeigen

@ -133,6 +133,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
public void setSessionHandler(MinecraftSessionHandler sessionHandler) {
this.sessionHandler = sessionHandler;
sessionHandler.activated();
}
private void ensureOpen() {

Datei anzeigen

@ -18,6 +18,10 @@ public interface MinecraftSessionHandler {
}
default void activated() {
}
default void exception(Throwable throwable) {
}

Datei anzeigen

@ -19,7 +19,7 @@ public class PlaySessionHandler implements MinecraftSessionHandler {
@Override
public void handle(MinecraftPacket packet) {
if (packet instanceof Ping) {
// Make sure to reply back to the server so it doesn't think we're gone.
// Forward onto the server
connection.getChannel().write(packet);
} else if (packet instanceof Disconnect) {
// The server wants to disconnect us. TODO fallback handling

Datei anzeigen

@ -72,6 +72,7 @@ public class ServerConnection {
handshake.setPort(serverInfo.getAddress().getPort());
channel.write(handshake);
channel.setProtocolVersion(proxyPlayer.getConnection().getProtocolVersion());
channel.setState(StateRegistry.LOGIN);
// Login

Datei anzeigen

@ -4,22 +4,46 @@ import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.packets.Ping;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import io.netty.buffer.ByteBuf;
import io.netty.channel.EventLoop;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
public class PlaySessionHandler implements MinecraftSessionHandler {
private final ConnectedPlayer player;
private ScheduledFuture<?> pingTask;
private long lastPing = -1;
public PlaySessionHandler(ConnectedPlayer player) {
this.player = player;
}
@Override
public void activated() {
EventLoop loop = player.getConnection().getChannel().eventLoop();
loop.scheduleAtFixedRate(this::ping, 5, 15, TimeUnit.SECONDS);
}
private void ping() {
long randomId = ThreadLocalRandom.current().nextLong();
lastPing = randomId;
Ping ping = new Ping();
ping.setRandomId(randomId);
player.getConnection().write(ping);
}
@Override
public void handle(MinecraftPacket packet) {
if (packet instanceof Ping) {
// Handle the ping.
player.getConnection().write(packet);
Ping ping = (Ping) packet;
if (ping.getRandomId() != lastPing) {
throw new IllegalStateException("Client sent invalid ping; expected " + lastPing + ", got " + ping.getRandomId());
}
// Do not forward the packet to the player's server, because we handle pings for all servers already.
return;
}
// If we don't want to handle this packet, just forward it on.
player.getConnectedServer().getChannel().write(packet);
}
@ -32,5 +56,10 @@ public class PlaySessionHandler implements MinecraftSessionHandler {
@Override
public void disconnected() {
player.getConnectedServer().disconnect();
if (pingTask != null && !pingTask.isCancelled()) {
pingTask.cancel(false);
pingTask = null;
}
}
}