feat: Improved server connection selection
Now the selection mode of the server to send the player to is configurable resolves #40
This commit is contained in:
parent
327b3394f1
commit
6775b8080e
@ -3,6 +3,8 @@ package me.adrianed.authmevelocity.common.configuration;
|
||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
||||
|
||||
import me.adrianed.authmevelocity.common.enums.SendMode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ConfigSerializable
|
||||
@ -13,6 +15,12 @@ public class ProxyConfiguration {
|
||||
return this.debug;
|
||||
}
|
||||
|
||||
@Comment("")
|
||||
private int randomAttempts = 5;
|
||||
public int randomAttempts() {
|
||||
return this.randomAttempts;
|
||||
}
|
||||
|
||||
@Comment("List of login/registration servers")
|
||||
private List<String> authServers = List.of("auth1", "auth2");
|
||||
public List<String> authServers() {
|
||||
@ -41,6 +49,17 @@ public class ProxyConfiguration {
|
||||
public boolean ensureFirstServerIsAuthServer() {
|
||||
return this.ensureAuthServer;
|
||||
}
|
||||
|
||||
@Comment("""
|
||||
SendMode
|
||||
TO_FIRST |
|
||||
TO_EMPTIEST_SERVE |
|
||||
RANDOM |
|
||||
""")
|
||||
private SendMode sendMode = SendMode.RANDOM;
|
||||
public SendMode sendMode() {
|
||||
return this.sendMode;
|
||||
}
|
||||
}
|
||||
|
||||
@ConfigSerializable
|
||||
@ -59,6 +78,18 @@ public class ProxyConfiguration {
|
||||
public List<String> teleportServers() {
|
||||
return this.teleportServers;
|
||||
}
|
||||
|
||||
// TODO: Improve comments
|
||||
@Comment("""
|
||||
SendMode
|
||||
TO_FIRST |
|
||||
TO_EMPTIEST_SERVE |
|
||||
RANDOM |
|
||||
""")
|
||||
private SendMode sendMode = SendMode.RANDOM;
|
||||
public SendMode sendMode() {
|
||||
return this.sendMode;
|
||||
}
|
||||
}
|
||||
|
||||
@ConfigSerializable
|
||||
@ -80,4 +111,5 @@ public class ProxyConfiguration {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package me.adrianed.authmevelocity.common.enums;
|
||||
|
||||
public enum SendMode {
|
||||
TO_FIRST,
|
||||
TO_EMPTIEST_SERVER,
|
||||
RANDOM;
|
||||
}
|
@ -2,7 +2,6 @@ package me.adrianed.authmevelocity.velocity.listener;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
@ -18,6 +17,7 @@ import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
|
||||
import me.adrianed.authmevelocity.velocity.AuthMeVelocityPlugin;
|
||||
import me.adrianed.authmevelocity.velocity.utils.AuthmeUtils;
|
||||
|
||||
public class ConnectListener {
|
||||
private final ProxyServer proxy;
|
||||
@ -44,12 +44,14 @@ public class ConnectListener {
|
||||
plugin.logDebug("PlayerChooseInitialServerEvent | Player is in auth server");
|
||||
return;
|
||||
}
|
||||
var config = plugin.config().get();
|
||||
var server = AuthmeUtils.serverToSend(
|
||||
config.ensureAuthServer().sendMode(), proxy, config.authServers(), config.randomAttempts());
|
||||
|
||||
@Nullable RegisteredServer server = getAvailableServer();
|
||||
// Velocity takes over in case the initial server is not present
|
||||
event.setInitialServer(server);
|
||||
event.setInitialServer(server.object());
|
||||
continuation.resume();
|
||||
if (server == null) {
|
||||
if (server.isEmpty()) {
|
||||
plugin.logDebug("PlayerChooseInitialServerEvent | Null server");
|
||||
logger.error("Cannot send the player {} to an auth server", event.getPlayer().getUsername());
|
||||
}
|
||||
@ -82,13 +84,4 @@ public class ConnectListener {
|
||||
sv.sendPluginMessage(AuthMeVelocityPlugin.AUTHMEVELOCITY_CHANNEL, buf.toByteArray()));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Implement #40
|
||||
private @Nullable RegisteredServer getAvailableServer() {
|
||||
for(String sv : plugin.config().get().authServers()){
|
||||
Optional<RegisteredServer> opt = proxy.getServer(sv);
|
||||
if (opt.isPresent()) return opt.get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
package me.adrianed.authmevelocity.velocity.listener;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Locale;
|
||||
|
||||
import me.adrianed.authmevelocity.api.velocity.event.PreSendOnLoginEvent;
|
||||
@ -14,8 +12,6 @@ import me.adrianed.authmevelocity.common.MessageType;
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.velocitypowered.api.event.Continuation;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.ResultedEvent.GenericResult;
|
||||
import com.velocitypowered.api.proxy.ConnectionRequestBuilder.Result;
|
||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
@ -23,6 +19,7 @@ import com.velocitypowered.api.proxy.ServerConnection;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
|
||||
import me.adrianed.authmevelocity.velocity.AuthMeVelocityPlugin;
|
||||
import me.adrianed.authmevelocity.velocity.utils.AuthmeUtils;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -31,13 +28,11 @@ import org.slf4j.Logger;
|
||||
public class PluginMessageListener {
|
||||
private final ProxyServer proxy;
|
||||
private final Logger logger;
|
||||
private final Random rm;
|
||||
private final AuthMeVelocityPlugin plugin;
|
||||
|
||||
public PluginMessageListener(@NotNull ProxyServer proxy, @NotNull Logger logger, AuthMeVelocityPlugin plugin) {
|
||||
this.proxy = proxy;
|
||||
this.logger = logger;
|
||||
this.rm = new Random();
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@ -52,7 +47,7 @@ public class PluginMessageListener {
|
||||
return;
|
||||
}
|
||||
|
||||
final ServerConnection connection = ((ServerConnection)event.getSource());
|
||||
final ServerConnection connection = (ServerConnection) event.getSource();
|
||||
|
||||
event.setResult(PluginMessageEvent.ForwardResult.handled());
|
||||
|
||||
@ -108,32 +103,35 @@ public class PluginMessageListener {
|
||||
}
|
||||
|
||||
final RegisteredServer loginServer = player.getCurrentServer().orElse(connection).getServer();
|
||||
final String randomServer = this.getRandomServer();
|
||||
|
||||
proxy.getServer(randomServer).ifPresentOrElse(server ->
|
||||
proxy.getEventManager().fire(new PreSendOnLoginEvent(player, loginServer, server))
|
||||
.thenApply(PreSendOnLoginEvent::getResult)
|
||||
.thenApply(GenericResult::isAllowed)
|
||||
.thenAcceptAsync(allowed -> {
|
||||
if (!allowed.booleanValue()) {
|
||||
var config = plugin.config().get();
|
||||
|
||||
var toSend = AuthmeUtils.serverToSend(
|
||||
config.sendOnLogin().sendMode(), proxy, config.authServers(), config.randomAttempts());
|
||||
|
||||
if (toSend.isEmpty()) {
|
||||
if (toSend.string() != null) {
|
||||
logger.warn("The server {} does not exist", toSend.string());
|
||||
} else {
|
||||
logger.warn("There is not valid server to send");
|
||||
}
|
||||
return;
|
||||
}
|
||||
player.createConnectionRequest(server)
|
||||
|
||||
proxy.getEventManager().fire(new PreSendOnLoginEvent(player, loginServer, toSend.object()))
|
||||
.thenAccept(event -> {
|
||||
if (!event.getResult().isAllowed()) {
|
||||
return;
|
||||
}
|
||||
player.createConnectionRequest(event.getResult().server())
|
||||
.connect()
|
||||
.thenApply(Result::isSuccessful)
|
||||
.thenAcceptAsync(result -> {
|
||||
if(!result.booleanValue()) {
|
||||
if (!result.isSuccessful()) {
|
||||
logger.info("Unable to connect the player {} to the server {}",
|
||||
player.getUsername(),
|
||||
server.getServerInfo().getName());
|
||||
result.getAttemptedConnection().getServerInfo().getName());
|
||||
}
|
||||
});
|
||||
})
|
||||
, () -> logger.warn("The server {} does not exist", randomServer));
|
||||
}
|
||||
|
||||
private String getRandomServer() {
|
||||
final List<String> serverList = plugin.config().get().sendOnLogin().teleportServers();
|
||||
return serverList.get(rm.nextInt(serverList.size()));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,17 @@
|
||||
package me.adrianed.authmevelocity.velocity.utils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
|
||||
import me.adrianed.authmevelocity.common.enums.SendMode;
|
||||
|
||||
public class AuthmeUtils {
|
||||
//Origin: https://github.com/4drian3d/ChatRegulator/blob/main/src/main/java/me/dreamerzero/chatregulator/utils/CommandUtils.java#L71
|
||||
/**
|
||||
@ -18,5 +26,55 @@ public class AuthmeUtils {
|
||||
}
|
||||
return string.substring(0, index);
|
||||
}
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
public static Pair<RegisteredServer> serverToSend(SendMode sendMode, ProxyServer proxy, List<String> servers, int attempts) {
|
||||
return switch(sendMode) {
|
||||
case TO_FIRST -> {
|
||||
Optional<RegisteredServer> sv;
|
||||
for (final String st : servers) {
|
||||
sv = proxy.getServer(st);
|
||||
if (sv.isPresent()) yield Pair.of(st, sv.get());
|
||||
}
|
||||
yield Pair.of(null, null);
|
||||
}
|
||||
case TO_EMPTIEST_SERVER -> {
|
||||
RegisteredServer emptiest = null;
|
||||
Optional<RegisteredServer> optional = Optional.empty();
|
||||
for (final String st : servers) {
|
||||
optional = proxy.getServer(st);
|
||||
if (optional.isPresent()) {
|
||||
RegisteredServer actualsv = optional.get();
|
||||
int actualConnected = actualsv.getPlayersConnected().size();
|
||||
if (actualConnected == 0) {
|
||||
yield Pair.of(st, actualsv);
|
||||
}
|
||||
if (emptiest == null || actualConnected < emptiest.getPlayersConnected().size()) {
|
||||
emptiest = actualsv;
|
||||
}
|
||||
}
|
||||
}
|
||||
yield Pair.of(optional.map(sv -> sv.getServerInfo().getName()).orElse(null), emptiest);
|
||||
}
|
||||
case RANDOM -> {
|
||||
Optional<RegisteredServer> server;
|
||||
if (servers.size() == 1) {
|
||||
server = proxy.getServer(servers.get(0));
|
||||
if (server.isPresent()) {
|
||||
yield Pair.of(server.get().getServerInfo().getName(), server.get());
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < attempts; i++) {
|
||||
int value = RANDOM.nextInt(servers.size());
|
||||
server = proxy.getServer(servers.get(value));
|
||||
if (server.isPresent()) {
|
||||
yield Pair.of(server.get().getServerInfo().getName(), server.get());
|
||||
}
|
||||
}
|
||||
yield Pair.of(null, null);
|
||||
}
|
||||
};
|
||||
}
|
||||
private AuthmeUtils() {}
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
package me.adrianed.authmevelocity.velocity.utils;
|
||||
|
||||
public record Pair<O>(String string, O object) {
|
||||
public boolean isPresent() {
|
||||
return this.object != null;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return object == null;
|
||||
}
|
||||
|
||||
public static <O> Pair<O> of(String string, O object) {
|
||||
return new Pair<>(string, object);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user