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.ConfigSerializable;
|
||||||
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
||||||
|
|
||||||
|
import me.adrianed.authmevelocity.common.enums.SendMode;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
@ -13,6 +15,12 @@ public class ProxyConfiguration {
|
|||||||
return this.debug;
|
return this.debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Comment("")
|
||||||
|
private int randomAttempts = 5;
|
||||||
|
public int randomAttempts() {
|
||||||
|
return this.randomAttempts;
|
||||||
|
}
|
||||||
|
|
||||||
@Comment("List of login/registration servers")
|
@Comment("List of login/registration servers")
|
||||||
private List<String> authServers = List.of("auth1", "auth2");
|
private List<String> authServers = List.of("auth1", "auth2");
|
||||||
public List<String> authServers() {
|
public List<String> authServers() {
|
||||||
@ -41,6 +49,17 @@ public class ProxyConfiguration {
|
|||||||
public boolean ensureFirstServerIsAuthServer() {
|
public boolean ensureFirstServerIsAuthServer() {
|
||||||
return this.ensureAuthServer;
|
return this.ensureAuthServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Comment("""
|
||||||
|
SendMode
|
||||||
|
TO_FIRST |
|
||||||
|
TO_EMPTIEST_SERVE |
|
||||||
|
RANDOM |
|
||||||
|
""")
|
||||||
|
private SendMode sendMode = SendMode.RANDOM;
|
||||||
|
public SendMode sendMode() {
|
||||||
|
return this.sendMode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
@ -59,6 +78,18 @@ public class ProxyConfiguration {
|
|||||||
public List<String> teleportServers() {
|
public List<String> teleportServers() {
|
||||||
return this.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
|
@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 java.util.Optional;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import com.google.common.io.ByteArrayDataOutput;
|
import com.google.common.io.ByteArrayDataOutput;
|
||||||
@ -18,6 +17,7 @@ import com.velocitypowered.api.proxy.ProxyServer;
|
|||||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||||
|
|
||||||
import me.adrianed.authmevelocity.velocity.AuthMeVelocityPlugin;
|
import me.adrianed.authmevelocity.velocity.AuthMeVelocityPlugin;
|
||||||
|
import me.adrianed.authmevelocity.velocity.utils.AuthmeUtils;
|
||||||
|
|
||||||
public class ConnectListener {
|
public class ConnectListener {
|
||||||
private final ProxyServer proxy;
|
private final ProxyServer proxy;
|
||||||
@ -44,12 +44,14 @@ public class ConnectListener {
|
|||||||
plugin.logDebug("PlayerChooseInitialServerEvent | Player is in auth server");
|
plugin.logDebug("PlayerChooseInitialServerEvent | Player is in auth server");
|
||||||
return;
|
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
|
// Velocity takes over in case the initial server is not present
|
||||||
event.setInitialServer(server);
|
event.setInitialServer(server.object());
|
||||||
continuation.resume();
|
continuation.resume();
|
||||||
if (server == null) {
|
if (server.isEmpty()) {
|
||||||
plugin.logDebug("PlayerChooseInitialServerEvent | Null server");
|
plugin.logDebug("PlayerChooseInitialServerEvent | Null server");
|
||||||
logger.error("Cannot send the player {} to an auth server", event.getPlayer().getUsername());
|
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()));
|
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;
|
package me.adrianed.authmevelocity.velocity.listener;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import me.adrianed.authmevelocity.api.velocity.event.PreSendOnLoginEvent;
|
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.google.common.io.ByteArrayDataInput;
|
||||||
import com.velocitypowered.api.event.Continuation;
|
import com.velocitypowered.api.event.Continuation;
|
||||||
import com.velocitypowered.api.event.Subscribe;
|
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.event.connection.PluginMessageEvent;
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.proxy.ProxyServer;
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
@ -23,6 +19,7 @@ import com.velocitypowered.api.proxy.ServerConnection;
|
|||||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||||
|
|
||||||
import me.adrianed.authmevelocity.velocity.AuthMeVelocityPlugin;
|
import me.adrianed.authmevelocity.velocity.AuthMeVelocityPlugin;
|
||||||
|
import me.adrianed.authmevelocity.velocity.utils.AuthmeUtils;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@ -31,20 +28,18 @@ import org.slf4j.Logger;
|
|||||||
public class PluginMessageListener {
|
public class PluginMessageListener {
|
||||||
private final ProxyServer proxy;
|
private final ProxyServer proxy;
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
private final Random rm;
|
|
||||||
private final AuthMeVelocityPlugin plugin;
|
private final AuthMeVelocityPlugin plugin;
|
||||||
|
|
||||||
public PluginMessageListener(@NotNull ProxyServer proxy, @NotNull Logger logger, AuthMeVelocityPlugin plugin) {
|
public PluginMessageListener(@NotNull ProxyServer proxy, @NotNull Logger logger, AuthMeVelocityPlugin plugin) {
|
||||||
this.proxy = proxy;
|
this.proxy = proxy;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.rm = new Random();
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onPluginMessage(final PluginMessageEvent event, Continuation continuation) {
|
public void onPluginMessage(final PluginMessageEvent event, Continuation continuation) {
|
||||||
final boolean cancelled = !event.getResult().isAllowed()
|
final boolean cancelled = !event.getResult().isAllowed()
|
||||||
||!(event.getSource() instanceof ServerConnection)
|
|| !(event.getSource() instanceof ServerConnection)
|
||||||
|| !event.getIdentifier().equals(AuthMeVelocityPlugin.AUTHMEVELOCITY_CHANNEL);
|
|| !event.getIdentifier().equals(AuthMeVelocityPlugin.AUTHMEVELOCITY_CHANNEL);
|
||||||
if (cancelled) {
|
if (cancelled) {
|
||||||
continuation.resume();
|
continuation.resume();
|
||||||
@ -52,7 +47,7 @@ public class PluginMessageListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final ServerConnection connection = ((ServerConnection)event.getSource());
|
final ServerConnection connection = (ServerConnection) event.getSource();
|
||||||
|
|
||||||
event.setResult(PluginMessageEvent.ForwardResult.handled());
|
event.setResult(PluginMessageEvent.ForwardResult.handled());
|
||||||
|
|
||||||
@ -66,7 +61,7 @@ public class PluginMessageListener {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case LOGIN -> {
|
case LOGIN -> {
|
||||||
plugin.logDebug("PluginMessageEvent | Login type");
|
plugin.logDebug("PluginMessageEvent | Login type");
|
||||||
if (player != null && plugin.addPlayer(player)){
|
if (player != null && plugin.addPlayer(player)) {
|
||||||
proxy.getEventManager().fireAndForget(new ProxyLoginEvent(player));
|
proxy.getEventManager().fireAndForget(new ProxyLoginEvent(player));
|
||||||
this.createServerConnectionRequest(player, connection);
|
this.createServerConnectionRequest(player, connection);
|
||||||
plugin.logDebug("PluginMessageEvent | Player not null");
|
plugin.logDebug("PluginMessageEvent | Player not null");
|
||||||
@ -88,7 +83,7 @@ public class PluginMessageListener {
|
|||||||
}
|
}
|
||||||
case UNREGISTER -> {
|
case UNREGISTER -> {
|
||||||
plugin.logDebug("PluginMessageEvent | Unregister type");
|
plugin.logDebug("PluginMessageEvent | Unregister type");
|
||||||
if(player != null) {
|
if (player != null) {
|
||||||
plugin.logDebug("PluginMessageEvent | Player not null");
|
plugin.logDebug("PluginMessageEvent | Player not null");
|
||||||
proxy.getEventManager().fireAndForget(new ProxyUnregisterEvent(player));
|
proxy.getEventManager().fireAndForget(new ProxyUnregisterEvent(player));
|
||||||
}
|
}
|
||||||
@ -108,32 +103,35 @@ public class PluginMessageListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final RegisteredServer loginServer = player.getCurrentServer().orElse(connection).getServer();
|
final RegisteredServer loginServer = player.getCurrentServer().orElse(connection).getServer();
|
||||||
final String randomServer = this.getRandomServer();
|
|
||||||
|
|
||||||
proxy.getServer(randomServer).ifPresentOrElse(server ->
|
var config = plugin.config().get();
|
||||||
proxy.getEventManager().fire(new PreSendOnLoginEvent(player, loginServer, server))
|
|
||||||
.thenApply(PreSendOnLoginEvent::getResult)
|
var toSend = AuthmeUtils.serverToSend(
|
||||||
.thenApply(GenericResult::isAllowed)
|
config.sendOnLogin().sendMode(), proxy, config.authServers(), config.randomAttempts());
|
||||||
.thenAcceptAsync(allowed -> {
|
|
||||||
if (!allowed.booleanValue()) {
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy.getEventManager().fire(new PreSendOnLoginEvent(player, loginServer, toSend.object()))
|
||||||
|
.thenAccept(event -> {
|
||||||
|
if (!event.getResult().isAllowed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
player.createConnectionRequest(server)
|
player.createConnectionRequest(event.getResult().server())
|
||||||
.connect()
|
.connect()
|
||||||
.thenApply(Result::isSuccessful)
|
|
||||||
.thenAcceptAsync(result -> {
|
.thenAcceptAsync(result -> {
|
||||||
if(!result.booleanValue()) {
|
if (!result.isSuccessful()) {
|
||||||
logger.info("Unable to connect the player {} to the server {}",
|
logger.info("Unable to connect the player {} to the server {}",
|
||||||
player.getUsername(),
|
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;
|
package me.adrianed.authmevelocity.velocity.utils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
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 {
|
public class AuthmeUtils {
|
||||||
//Origin: https://github.com/4drian3d/ChatRegulator/blob/main/src/main/java/me/dreamerzero/chatregulator/utils/CommandUtils.java#L71
|
//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);
|
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() {}
|
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