13
0
geforkt von Mirrors/Velocity

Consistently display disconnects.

Dieser Commit ist enthalten in:
Andrew Steinborn 2018-12-29 11:46:54 -05:00
Ursprung 256978fc15
Commit 10c440af83
6 geänderte Dateien mit 67 neuen und 47 gelöschten Zeilen

Datei anzeigen

@ -24,6 +24,7 @@ import com.velocitypowered.proxy.protocol.netty.MinecraftCompressDecoder;
import com.velocitypowered.proxy.protocol.netty.MinecraftCompressEncoder;
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder;
import com.velocitypowered.proxy.protocol.packet.Disconnect;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
@ -58,6 +59,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
private @Nullable MinecraftConnectionAssociation association;
private final VelocityServer server;
private ConnectionType connectionType = ConnectionTypes.UNDETERMINED;
private boolean knownDisconnect = false;
/**
* Initializes a new {@link MinecraftConnection} instance.
@ -88,7 +90,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
sessionHandler.disconnected();
}
if (association != null) {
if (association != null && !knownDisconnect) {
logger.info("{} has disconnected", association);
}
}
@ -191,6 +193,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
*/
public void closeWith(Object msg) {
if (channel.isActive()) {
knownDisconnect = true;
channel.writeAndFlush(msg).addListener(ChannelFutureListener.CLOSE);
}
}

Datei anzeigen

@ -235,6 +235,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
@Override
public void disconnect(Component reason) {
logger.info("{} has disconnected: {}", this, ComponentSerializers.LEGACY.serialize(reason));
connection.closeWith(Disconnect.create(reason));
}
@ -351,7 +352,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
if (nextServer.isPresent()) {
createConnectionRequest(nextServer.get()).fireAndForget();
} else {
connection.closeWith(Disconnect.create(friendlyReason));
disconnect(friendlyReason);
}
} else {
KickedFromServerEvent originalEvent = new KickedFromServerEvent(this, rs, kickReason,
@ -360,7 +361,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
.thenAcceptAsync(event -> {
if (event.getResult() instanceof DisconnectPlayer) {
DisconnectPlayer res = (DisconnectPlayer) event.getResult();
connection.closeWith(Disconnect.create(res.getReason()));
disconnect(res.getReason());
} else if (event.getResult() instanceof RedirectPlayer) {
RedirectPlayer res = (RedirectPlayer) event.getResult();
createConnectionRequest(res.getServer()).fireAndForget();
@ -369,11 +370,11 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
if (event.kickedDuringServerConnect()) {
sendMessage(res.getMessage());
} else {
connection.closeWith(Disconnect.create(res.getMessage()));
disconnect(res.getMessage());
}
} else {
// In case someone gets creative, assume we want to disconnect the player.
connection.closeWith(Disconnect.create(friendlyReason));
disconnect(friendlyReason);
}
}, connection.eventLoop());
}

Datei anzeigen

@ -4,9 +4,9 @@ import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.velocitypowered.api.event.connection.ConnectionHandshakeEvent;
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.InboundConnection;
import com.velocitypowered.api.proxy.server.ServerPing;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.config.PlayerInfoForwarding;
import com.velocitypowered.proxy.config.VelocityConfiguration;
@ -75,6 +75,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
public boolean handle(Handshake handshake) {
InitialInboundConnection ic = new InitialInboundConnection(connection,
cleanVhost(handshake.getServerAddress()), handshake);
connection.setAssociation(ic);
switch (handshake.getNextStatus()) {
case StateRegistry.STATUS_ID:
connection.setState(StateRegistry.STATUS);

Datei anzeigen

@ -3,11 +3,19 @@ package com.velocitypowered.proxy.connection.client;
import com.velocitypowered.api.proxy.InboundConnection;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.connection.MinecraftConnection;
import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation;
import com.velocitypowered.proxy.protocol.packet.Disconnect;
import com.velocitypowered.proxy.protocol.packet.Handshake;
import java.net.InetSocketAddress;
import java.util.Optional;
import net.kyori.text.Component;
import net.kyori.text.serializer.ComponentSerializers;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
class InitialInboundConnection implements InboundConnection {
class InitialInboundConnection implements InboundConnection, MinecraftConnectionAssociation {
private static final Logger logger = LogManager.getLogger(InitialInboundConnection.class);
private final MinecraftConnection connection;
private final String cleanedAddress;
@ -39,4 +47,14 @@ class InitialInboundConnection implements InboundConnection {
public ProtocolVersion getProtocolVersion() {
return connection.getProtocolVersion();
}
@Override
public String toString() {
return "[initial connection] " + connection.getRemoteAddress().toString();
}
public void disconnect(Component reason) {
logger.info("{} has disconnected: {}", this, ComponentSerializers.LEGACY.serialize(reason));
connection.closeWith(Disconnect.create(reason));
}
}

Datei anzeigen

@ -31,7 +31,6 @@ import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
import com.velocitypowered.proxy.protocol.packet.ServerLogin;
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
import com.velocitypowered.proxy.protocol.packet.SetCompression;
import com.velocitypowered.proxy.util.EncryptionUtils;
import com.velocitypowered.proxy.util.VelocityMessages;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
@ -57,26 +56,26 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
"https://sessionserver.mojang.com/session/minecraft/hasJoined?username=%s&serverId=%s&ip=%s";
private final VelocityServer server;
private final MinecraftConnection inbound;
private final InboundConnection apiInbound;
private final MinecraftConnection mcConnection;
private final InitialInboundConnection inbound;
private @MonotonicNonNull ServerLogin login;
private byte[] verify = EMPTY_BYTE_ARRAY;
private int playerInfoId;
private @MonotonicNonNull ConnectedPlayer connectedPlayer;
LoginSessionHandler(VelocityServer server, MinecraftConnection inbound,
InboundConnection apiInbound) {
LoginSessionHandler(VelocityServer server, MinecraftConnection mcConnection,
InitialInboundConnection inbound) {
this.server = Preconditions.checkNotNull(server, "server");
this.mcConnection = Preconditions.checkNotNull(mcConnection, "mcConnection");
this.inbound = Preconditions.checkNotNull(inbound, "inbound");
this.apiInbound = Preconditions.checkNotNull(apiInbound, "apiInbound");
}
@Override
public boolean handle(ServerLogin packet) {
this.login = packet;
if (inbound.getProtocolVersion().compareTo(MINECRAFT_1_13) >= 0) {
if (mcConnection.getProtocolVersion().compareTo(MINECRAFT_1_13) >= 0) {
playerInfoId = ThreadLocalRandom.current().nextInt();
inbound.write(new LoginPluginMessage(playerInfoId, VELOCITY_IP_FORWARDING_CHANNEL,
mcConnection.write(new LoginPluginMessage(playerInfoId, VELOCITY_IP_FORWARDING_CHANNEL,
Unpooled.EMPTY_BUFFER));
} else {
beginPreLogin();
@ -89,7 +88,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
if (packet.getId() == playerInfoId) {
if (packet.isSuccess()) {
// Uh oh, someone's trying to run Velocity behind Velocity. We don't want that happening.
inbound.closeWith(Disconnect.create(VelocityMessages.NO_PROXY_BEHIND_PROXY));
inbound.disconnect(VelocityMessages.NO_PROXY_BEHIND_PROXY);
} else {
// Proceed with the regular login process.
beginPreLogin();
@ -119,14 +118,14 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
byte[] decryptedSharedSecret = decryptRsa(serverKeyPair, packet.getSharedSecret());
String serverId = generateServerId(decryptedSharedSecret, serverKeyPair.getPublic());
String playerIp = ((InetSocketAddress) inbound.getRemoteAddress()).getHostString();
String playerIp = ((InetSocketAddress) mcConnection.getRemoteAddress()).getHostString();
String url = String.format(MOJANG_HASJOINED_URL,
UrlEscapers.urlFormParameterEscaper().escape(login.getUsername()), serverId,
UrlEscapers.urlFormParameterEscaper().escape(playerIp));
server.getHttpClient()
.get(new URL(url))
.thenAcceptAsync(profileResponse -> {
if (inbound.isClosed()) {
if (mcConnection.isClosed()) {
// The player disconnected after we authenticated them.
return;
}
@ -134,7 +133,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
// Go ahead and enable encryption. Once the client sends EncryptionResponse, encryption
// is enabled.
try {
inbound.enableEncryption(decryptedSharedSecret);
mcConnection.enableEncryption(decryptedSharedSecret);
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
@ -144,25 +143,23 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
initializePlayer(GSON.fromJson(profileResponse.getBody(), GameProfile.class), true);
} else if (profileResponse.getCode() == 204) {
// Apparently an offline-mode user logged onto this online-mode proxy.
logger.warn("An offline-mode client ({} from {}) tried to connect!",
login.getUsername(), playerIp);
inbound.closeWith(Disconnect.create(VelocityMessages.ONLINE_MODE_ONLY));
inbound.disconnect(VelocityMessages.ONLINE_MODE_ONLY);
} else {
// Something else went wrong
logger.error(
"Got an unexpected error code {} whilst contacting Mojang to log in {} ({})",
profileResponse.getCode(), login.getUsername(), playerIp);
inbound.close();
mcConnection.close();
}
}, inbound.eventLoop())
}, mcConnection.eventLoop())
.exceptionally(exception -> {
logger.error("Unable to enable encryption", exception);
inbound.close();
mcConnection.close();
return null;
});
} catch (GeneralSecurityException e) {
logger.error("Unable to enable encryption", e);
inbound.close();
mcConnection.close();
} catch (MalformedURLException e) {
throw new AssertionError(e);
}
@ -174,10 +171,10 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
if (login == null) {
throw new IllegalStateException("No ServerLogin packet received yet.");
}
PreLoginEvent event = new PreLoginEvent(apiInbound, login.getUsername());
PreLoginEvent event = new PreLoginEvent(inbound, login.getUsername());
server.getEventManager().fire(event)
.thenRunAsync(() -> {
if (inbound.isClosed()) {
if (mcConnection.isClosed()) {
// The player was disconnected
return;
}
@ -185,7 +182,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
Optional<Component> disconnectReason = result.getReason();
if (disconnectReason.isPresent()) {
// The component is guaranteed to be provided if the connection was denied.
inbound.closeWith(Disconnect.create(disconnectReason.get()));
mcConnection.closeWith(Disconnect.create(disconnectReason.get()));
return;
}
@ -194,11 +191,11 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
// Request encryption.
EncryptionRequest request = generateEncryptionRequest();
this.verify = Arrays.copyOf(request.getVerifyToken(), 4);
inbound.write(request);
mcConnection.write(request);
} else {
initializePlayer(GameProfile.forOfflinePlayer(login.getUsername()), false);
}
}, inbound.eventLoop());
}, mcConnection.eventLoop());
}
private EncryptionRequest generateEncryptionRequest() {
@ -213,15 +210,16 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
private void initializePlayer(GameProfile profile, boolean onlineMode) {
// Some connection types may need to alter the game profile.
profile = inbound.getType().addGameProfileTokensIfRequired(profile,
profile = mcConnection.getType().addGameProfileTokensIfRequired(profile,
server.getConfiguration().getPlayerInfoForwardingMode());
GameProfileRequestEvent profileRequestEvent = new GameProfileRequestEvent(apiInbound, profile,
GameProfileRequestEvent profileRequestEvent = new GameProfileRequestEvent(inbound, profile,
onlineMode);
server.getEventManager().fire(profileRequestEvent).thenCompose(profileEvent -> {
// Initiate a regular connection and move over to it.
ConnectedPlayer player = new ConnectedPlayer(server, profileEvent.getGameProfile(), inbound,
apiInbound.getVirtualHost().orElse(null));
ConnectedPlayer player = new ConnectedPlayer(server, profileEvent.getGameProfile(),
mcConnection,
inbound.getVirtualHost().orElse(null));
this.connectedPlayer = player;
if (!server.registerConnection(player)) {
@ -229,6 +227,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
return CompletableFuture.completedFuture(null);
}
logger.info("{} has connected", player);
return server.getEventManager()
.fire(new PermissionsSetupEvent(player, ConnectedPlayer.DEFAULT_PERMISSIONS))
.thenCompose(event -> {
@ -239,7 +239,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
})
// then complete the connection
.thenAcceptAsync(event -> {
if (inbound.isClosed()) {
if (mcConnection.isClosed()) {
// The player was disconnected
return;
}
@ -250,7 +250,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
} else {
finishLogin(player);
}
}, inbound.eventLoop());
}, mcConnection.eventLoop());
});
}
@ -264,27 +264,26 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
int threshold = server.getConfiguration().getCompressionThreshold();
if (threshold >= 0) {
inbound.write(new SetCompression(threshold));
inbound.setCompressionThreshold(threshold);
mcConnection.write(new SetCompression(threshold));
mcConnection.setCompressionThreshold(threshold);
}
ServerLoginSuccess success = new ServerLoginSuccess();
success.setUsername(player.getUsername());
success.setUuid(player.getUniqueId());
inbound.write(success);
mcConnection.write(success);
inbound.setAssociation(player);
inbound.setState(StateRegistry.PLAY);
mcConnection.setAssociation(player);
mcConnection.setState(StateRegistry.PLAY);
logger.info("{} has connected", player);
inbound.setSessionHandler(new InitialConnectSessionHandler(player));
mcConnection.setSessionHandler(new InitialConnectSessionHandler(player));
server.getEventManager().fire(new PostLoginEvent(player))
.thenRun(() -> player.createConnectionRequest(toTry.get()).fireAndForget());
}
@Override
public void handleUnknown(ByteBuf buf) {
throw new IllegalStateException("Unknown data " + ByteBufUtil.hexDump(buf));
mcConnection.close();
}
@Override

Datei anzeigen

@ -14,8 +14,6 @@ public class VelocityMessages {
.of("No available servers", TextColor.RED);
public static final Component ALREADY_CONNECTED = TextComponent
.of("You are already connected to this proxy!", TextColor.RED);
public static final Component INVALID_USERNAME = TextComponent
.of("Trying to login with invalid username", TextColor.RED);
private VelocityMessages() {
throw new AssertionError();