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) { public void setSessionHandler(MinecraftSessionHandler sessionHandler) {
this.sessionHandler = sessionHandler; this.sessionHandler = sessionHandler;
sessionHandler.activated();
} }
private void ensureOpen() { private void ensureOpen() {

Datei anzeigen

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

Datei anzeigen

@ -19,7 +19,7 @@ public class PlaySessionHandler implements MinecraftSessionHandler {
@Override @Override
public void handle(MinecraftPacket packet) { public void handle(MinecraftPacket packet) {
if (packet instanceof Ping) { 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); connection.getChannel().write(packet);
} else if (packet instanceof Disconnect) { } else if (packet instanceof Disconnect) {
// The server wants to disconnect us. TODO fallback handling // The server wants to disconnect us. TODO fallback handling

Datei anzeigen

@ -72,6 +72,7 @@ public class ServerConnection {
handshake.setPort(serverInfo.getAddress().getPort()); handshake.setPort(serverInfo.getAddress().getPort());
channel.write(handshake); channel.write(handshake);
channel.setProtocolVersion(proxyPlayer.getConnection().getProtocolVersion());
channel.setState(StateRegistry.LOGIN); channel.setState(StateRegistry.LOGIN);
// 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.protocol.packets.Ping;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import io.netty.buffer.ByteBuf; 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 { public class PlaySessionHandler implements MinecraftSessionHandler {
private final ConnectedPlayer player; private final ConnectedPlayer player;
private ScheduledFuture<?> pingTask;
private long lastPing = -1;
public PlaySessionHandler(ConnectedPlayer player) { public PlaySessionHandler(ConnectedPlayer player) {
this.player = 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 @Override
public void handle(MinecraftPacket packet) { public void handle(MinecraftPacket packet) {
if (packet instanceof Ping) { if (packet instanceof Ping) {
// Handle the ping. Ping ping = (Ping) packet;
player.getConnection().write(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; return;
} }
// If we don't want to handle this packet, just forward it on. // If we don't want to handle this packet, just forward it on.
player.getConnectedServer().getChannel().write(packet); player.getConnectedServer().getChannel().write(packet);
} }
@ -32,5 +56,10 @@ public class PlaySessionHandler implements MinecraftSessionHandler {
@Override @Override
public void disconnected() { public void disconnected() {
player.getConnectedServer().disconnect(); player.getConnectedServer().disconnect();
if (pingTask != null && !pingTask.isCancelled()) {
pingTask.cancel(false);
pingTask = null;
}
} }
} }