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

Allow running Velocity without any servers.

This is a niche setup, however if your network is 100% dynamically configured, this is a handy feature to have available.

To support this functionality, a new PlayerChooseInitialServerEvent event was added to allow the initial server to connect to be changed as desired.
Dieser Commit ist enthalten in:
Andrew Steinborn 2019-11-16 23:17:09 -05:00
Ursprung e12f970684
Commit d2b8271eb4
4 geänderte Dateien mit 106 neuen und 71 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,51 @@
package com.velocitypowered.api.event.player;
import com.google.common.base.Preconditions;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import java.util.Optional;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Fired when a player has finished connecting to the proxy and we need to choose the first server
* to connect to.
*/
public class PlayerChooseInitialServerEvent {
private final Player player;
private @Nullable RegisteredServer initialServer;
/**
* Constructs a PlayerChooseInitialServerEvent.
* @param player the player that was connected
* @param initialServer the initial server selected, may be {@code null}
*/
public PlayerChooseInitialServerEvent(Player player, @Nullable RegisteredServer initialServer) {
this.player = Preconditions.checkNotNull(player, "player");
this.initialServer = initialServer;
}
public Player getPlayer() {
return player;
}
public Optional<RegisteredServer> getInitialServer() {
return Optional.ofNullable(initialServer);
}
/**
* Sets the new initial server.
* @param server the initial server the player should connect to
*/
public void setInitialServer(RegisteredServer server) {
this.initialServer = server;
}
@Override
public String toString() {
return "PlayerChooseInitialServerEvent{"
+ "player=" + player
+ ", initialServer=" + initialServer
+ '}';
}
}

Datei anzeigen

@ -192,12 +192,7 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi
} }
if (servers.getServers().isEmpty()) { if (servers.getServers().isEmpty()) {
logger.error("You have no servers configured. :("); logger.warn("You don't have any servers configured.");
valid = false;
} else {
if (servers.getAttemptConnectionOrder().isEmpty()) {
logger.error("No fallback servers are configured!");
valid = false;
} }
for (Map.Entry<String, String> entry : servers.getServers().entrySet()) { for (Map.Entry<String, String> entry : servers.getServers().entrySet()) {
@ -230,7 +225,6 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi
} }
} }
} }
}
try { try {
getMotdComponent(); getMotdComponent();

Datei anzeigen

@ -417,17 +417,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
return; return;
} }
if (connectedServer == null) { boolean kickedFromCurrent = connectedServer == null || connectedServer.getServer().equals(rs);
Optional<RegisteredServer> nextServer = getNextServerToTry(rs);
if (nextServer.isPresent()) {
// There can't be any connection in flight now.
resetInFlightConnection();
createConnectionRequest(nextServer.get()).fireAndForget();
} else {
disconnect(friendlyReason);
}
} else {
boolean kickedFromCurrent = connectedServer.getServer().equals(rs);
ServerKickResult result; ServerKickResult result;
if (kickedFromCurrent) { if (kickedFromCurrent) {
Optional<RegisteredServer> next = getNextServerToTry(rs); Optional<RegisteredServer> next = getNextServerToTry(rs);
@ -444,7 +434,6 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
!kickedFromCurrent, result); !kickedFromCurrent, result);
handleKickEvent(originalEvent, friendlyReason); handleKickEvent(originalEvent, friendlyReason);
} }
}
private void handleKickEvent(KickedFromServerEvent originalEvent, Component friendlyReason) { private void handleKickEvent(KickedFromServerEvent originalEvent, Component friendlyReason) {
server.getEventManager().fire(originalEvent) server.getEventManager().fire(originalEvent)

Datei anzeigen

@ -1,24 +1,21 @@
package com.velocitypowered.proxy.connection.client; package com.velocitypowered.proxy.connection.client;
import static com.google.common.net.UrlEscapers.urlFormParameterEscaper; import static com.google.common.net.UrlEscapers.urlFormParameterEscaper;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_13;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8;
import static com.velocitypowered.proxy.VelocityServer.GSON; import static com.velocitypowered.proxy.VelocityServer.GSON;
import static com.velocitypowered.proxy.connection.VelocityConstants.EMPTY_BYTE_ARRAY; import static com.velocitypowered.proxy.connection.VelocityConstants.EMPTY_BYTE_ARRAY;
import static com.velocitypowered.proxy.connection.VelocityConstants.VELOCITY_IP_FORWARDING_CHANNEL;
import static com.velocitypowered.proxy.util.EncryptionUtils.decryptRsa; import static com.velocitypowered.proxy.util.EncryptionUtils.decryptRsa;
import static com.velocitypowered.proxy.util.EncryptionUtils.generateServerId; import static com.velocitypowered.proxy.util.EncryptionUtils.generateServerId;
import static org.asynchttpclient.Dsl.asyncHttpClient; import static org.asynchttpclient.Dsl.asyncHttpClient;
import static org.asynchttpclient.Dsl.config;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.net.UrlEscapers;
import com.velocitypowered.api.event.connection.LoginEvent; import com.velocitypowered.api.event.connection.LoginEvent;
import com.velocitypowered.api.event.connection.PostLoginEvent; import com.velocitypowered.api.event.connection.PostLoginEvent;
import com.velocitypowered.api.event.connection.PreLoginEvent; import com.velocitypowered.api.event.connection.PreLoginEvent;
import com.velocitypowered.api.event.connection.PreLoginEvent.PreLoginComponentResult; import com.velocitypowered.api.event.connection.PreLoginEvent.PreLoginComponentResult;
import com.velocitypowered.api.event.permission.PermissionsSetupEvent; import com.velocitypowered.api.event.permission.PermissionsSetupEvent;
import com.velocitypowered.api.event.player.GameProfileRequestEvent; import com.velocitypowered.api.event.player.GameProfileRequestEvent;
import com.velocitypowered.api.event.player.PlayerChooseInitialServerEvent;
import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.util.GameProfile; import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.VelocityServer;
@ -29,17 +26,12 @@ import com.velocitypowered.proxy.protocol.StateRegistry;
import com.velocitypowered.proxy.protocol.packet.Disconnect; import com.velocitypowered.proxy.protocol.packet.Disconnect;
import com.velocitypowered.proxy.protocol.packet.EncryptionRequest; import com.velocitypowered.proxy.protocol.packet.EncryptionRequest;
import com.velocitypowered.proxy.protocol.packet.EncryptionResponse; import com.velocitypowered.proxy.protocol.packet.EncryptionResponse;
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
import com.velocitypowered.proxy.protocol.packet.ServerLogin; import com.velocitypowered.proxy.protocol.packet.ServerLogin;
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess; import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
import com.velocitypowered.proxy.protocol.packet.SetCompression; import com.velocitypowered.proxy.protocol.packet.SetCompression;
import com.velocitypowered.proxy.util.VelocityMessages; import com.velocitypowered.proxy.util.VelocityMessages;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.security.KeyPair; import java.security.KeyPair;
import java.util.Arrays; import java.util.Arrays;
@ -50,7 +42,6 @@ import java.util.concurrent.ThreadLocalRandom;
import net.kyori.text.Component; import net.kyori.text.Component;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.asynchttpclient.Dsl;
import org.asynchttpclient.ListenableFuture; import org.asynchttpclient.ListenableFuture;
import org.asynchttpclient.Response; import org.asynchttpclient.Response;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@ -231,12 +222,6 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
} }
private void finishLogin(ConnectedPlayer player) { private void finishLogin(ConnectedPlayer player) {
Optional<RegisteredServer> toTry = player.getNextServerToTry();
if (!toTry.isPresent()) {
player.disconnect(VelocityMessages.NO_AVAILABLE_SERVERS);
return;
}
int threshold = server.getConfiguration().getCompressionThreshold(); int threshold = server.getConfiguration().getCompressionThreshold();
if (threshold >= 0 && mcConnection.getProtocolVersion().compareTo(MINECRAFT_1_8) >= 0) { if (threshold >= 0 && mcConnection.getProtocolVersion().compareTo(MINECRAFT_1_8) >= 0) {
mcConnection.write(new SetCompression(threshold)); mcConnection.write(new SetCompression(threshold));
@ -269,11 +254,27 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
mcConnection.setSessionHandler(new InitialConnectSessionHandler(player)); mcConnection.setSessionHandler(new InitialConnectSessionHandler(player));
server.getEventManager().fire(new PostLoginEvent(player)) server.getEventManager().fire(new PostLoginEvent(player))
.thenRun(() -> player.createConnectionRequest(toTry.get()).fireAndForget()); .thenRun(() -> connectToInitialServer(player));
} }
}, mcConnection.eventLoop()); }, mcConnection.eventLoop());
} }
private void connectToInitialServer(ConnectedPlayer player) {
Optional<RegisteredServer> initialFromConfig = player.getNextServerToTry();
PlayerChooseInitialServerEvent event = new PlayerChooseInitialServerEvent(player,
initialFromConfig.orElse(null));
server.getEventManager().fire(event)
.thenRunAsync(() -> {
Optional<RegisteredServer> toTry = event.getInitialServer();
if (!toTry.isPresent()) {
player.disconnect(VelocityMessages.NO_AVAILABLE_SERVERS);
return;
}
player.createConnectionRequest(toTry.get()).fireAndForget();
}, mcConnection.eventLoop());
}
@Override @Override
public void handleUnknown(ByteBuf buf) { public void handleUnknown(ByteBuf buf) {
mcConnection.close(); mcConnection.close();