diff --git a/README.md b/README.md index b79efdf..c95f74c 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ This plugin adds the support for [Velocity](https://velocitypowered.com/) to [AuthMeReloaded](https://github.com/AuthMe/AuthMeReloaded) ## Requirements -- Paper, Airplane or Purpur 1.16+ -- Velocity 3.0.1+ -- Java 16 +- Paper, Airplane or Purpur 1.13+ +- Velocity 3.1.1+ +- Java 11+ ## Setup 1. Download the latest release of the plugin [link](https://github.com/4drian3d/AuthMeVelocity/releases) diff --git a/pom.xml b/pom.xml index 48a002a..3eca90d 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.glyart.authmevelocity parent pom - 1.5.0 + 2.0.0 11 diff --git a/proxy/pom.xml b/proxy/pom.xml index c3f32ac..630adb5 100644 --- a/proxy/pom.xml +++ b/proxy/pom.xml @@ -5,7 +5,7 @@ parent com.glyart.authmevelocity - 1.5.0 + 2.0.0 4.0.0 @@ -34,11 +34,6 @@ 3.1.1 provided - - org.spongepowered - configurate-hocon - 4.1.2 - com.github.games647 fastlogin.velocity @@ -54,42 +49,6 @@ maven-jar-plugin 3.2.2 - - org.apache.maven.plugins - maven-shade-plugin - 3.3.1-SNAPSHOT - - - package - - shade - - - false - true - - - org.spongepowered - com.glyart.authmevelocity.libs.configurate - - - - - - - - - *:* - - META-INF/maven/ - META-INF/*.MF - - - - - - - diff --git a/proxy/src/main/java/com/glyart/authmevelocity/proxy/AuthMeVelocityPlugin.java b/proxy/src/main/java/com/glyart/authmevelocity/proxy/AuthMeVelocityPlugin.java index 4da6528..67c4603 100644 --- a/proxy/src/main/java/com/glyart/authmevelocity/proxy/AuthMeVelocityPlugin.java +++ b/proxy/src/main/java/com/glyart/authmevelocity/proxy/AuthMeVelocityPlugin.java @@ -5,18 +5,22 @@ import com.glyart.authmevelocity.proxy.listener.FastLoginListener; import com.glyart.authmevelocity.proxy.listener.PluginMessageListener; import com.glyart.authmevelocity.proxy.listener.ProxyListener; import com.google.inject.Inject; +import com.moandjiezana.toml.Toml; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; import com.velocitypowered.api.plugin.annotation.DataDirectory; import com.velocitypowered.api.proxy.ProxyServer; import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; -import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; import java.util.HashSet; +import java.util.Objects; import java.util.Set; import java.util.UUID; @@ -24,30 +28,32 @@ public class AuthMeVelocityPlugin { private final ProxyServer proxy; private final Logger logger; private final Path pluginDirectory; - private static AuthMeVelocityPlugin plugin; + private AuthmeVelocityAPI api; - protected static final Set loggedPlayers = Collections.synchronizedSet(new HashSet<>()); + protected final Set loggedPlayers = Collections.synchronizedSet(new HashSet<>()); @Inject public AuthMeVelocityPlugin(ProxyServer proxy, Logger logger, @DataDirectory Path dataDirectory) { - plugin = this; this.proxy = proxy; this.logger = logger; this.pluginDirectory = dataDirectory; } @Subscribe - public void onProxyInitialize(ProxyInitializeEvent event) { - AuthMeConfig.loadConfig(pluginDirectory, logger); - @NotNull var config = AuthMeConfig.getConfig(); - - proxy.getChannelRegistrar().register( - MinecraftChannelIdentifier.create("authmevelocity", "main")); - proxy.getEventManager().register(this, new ProxyListener(config)); - proxy.getEventManager().register(this, new PluginMessageListener(proxy, logger, config)); + public void onProxyInitialization(ProxyInitializeEvent event) { + Toml toml = this.loadConfig(pluginDirectory, logger); + if(toml == null){ + logger.warn("Failed to load config.toml. Shutting down."); + return; + } + AuthMeConfig config = Objects.requireNonNull(new AuthMeConfig(toml), "configuration cannot be null"); + this.api = new AuthmeVelocityAPI(this, config); + proxy.getChannelRegistrar().register(MinecraftChannelIdentifier.create("authmevelocity", "main")); + proxy.getEventManager().register(this, new ProxyListener(config, api, logger, proxy)); + proxy.getEventManager().register(this, new PluginMessageListener(proxy, logger, config, api)); if(proxy.getPluginManager().isLoaded("fastlogin")){ - proxy.getEventManager().register(this, new FastLoginListener(proxy)); + proxy.getEventManager().register(this, new FastLoginListener(proxy, api)); } logger.info("-- AuthMeVelocity enabled --"); @@ -61,7 +67,28 @@ public class AuthMeVelocityPlugin { return this.proxy; } - public static AuthMeVelocityPlugin getInstance(){ - return plugin; + public AuthmeVelocityAPI getAPI(){ + return this.api; + } + + private Toml loadConfig(Path path, Logger logger){ + if(!Files.exists(path)){ + try { + Files.createDirectory(path); + } catch(IOException e){ + logger.info("An error ocurred on configuration initialization: {}", e.getMessage()); + return null; + } + } + Path configPath = path.resolve("config.toml"); + if(!Files.exists(configPath)){ + try(InputStream in = this.getClass().getClassLoader().getResourceAsStream("config.toml")){ + Files.copy(in, configPath); + } catch(IOException e){ + logger.info("An error ocurred on configuration initialization: {}", e.getMessage()); + return null; + } + } + return new Toml().read(configPath.toFile()); } } diff --git a/proxy/src/main/java/com/glyart/authmevelocity/proxy/AuthmeVelocityAPI.java b/proxy/src/main/java/com/glyart/authmevelocity/proxy/AuthmeVelocityAPI.java index fd697e9..efb3182 100644 --- a/proxy/src/main/java/com/glyart/authmevelocity/proxy/AuthmeVelocityAPI.java +++ b/proxy/src/main/java/com/glyart/authmevelocity/proxy/AuthmeVelocityAPI.java @@ -1,5 +1,6 @@ package com.glyart.authmevelocity.proxy; +import java.util.Optional; import java.util.UUID; import java.util.function.Predicate; @@ -11,17 +12,23 @@ import com.velocitypowered.api.proxy.server.RegisteredServer; import org.jetbrains.annotations.NotNull; /** - * APi provided to interact with logged players + * API provided to interact with logged players */ -public class AuthmeVelocityAPI { +public final class AuthmeVelocityAPI { + private final AuthMeVelocityPlugin plugin; + private final AuthMeConfig config; + AuthmeVelocityAPI(AuthMeVelocityPlugin plugin, AuthMeConfig config){ + this.plugin = plugin; + this.config = config; + } /** * Check if the player is logged in or not * @param player the player * @return if the player is logged in or not */ - public static boolean isLogged(@NotNull Player player){ + public boolean isLogged(@NotNull Player player){ final UUID playerUUID = player.getUniqueId(); - return AuthMeVelocityPlugin.loggedPlayers.contains(playerUUID); + return plugin.loggedPlayers.contains(playerUUID); } /** @@ -29,9 +36,9 @@ public class AuthmeVelocityAPI { * @param player the new logged player * @return if the player was succesfully added */ - public static boolean addPlayer(@NotNull Player player){ + public boolean addPlayer(@NotNull Player player){ final UUID playerUUID = player.getUniqueId(); - return AuthMeVelocityPlugin.loggedPlayers.add(playerUUID); + return plugin.loggedPlayers.add(playerUUID); } /** @@ -39,20 +46,17 @@ public class AuthmeVelocityAPI { * @param player the unlogged player * @return if the player was succesfully removed */ - public static boolean removePlayer(@NotNull Player player){ + public boolean removePlayer(@NotNull Player player){ final UUID playerUUID = player.getUniqueId(); - return AuthMeVelocityPlugin.loggedPlayers.remove(playerUUID); + return plugin.loggedPlayers.remove(playerUUID); } /** * Removes players who meet the established condition * @param predicate the condition */ - public static void removePlayerIf(@NotNull Predicate predicate){ - AuthMeVelocityPlugin.loggedPlayers.stream() - .map(uuid -> AuthMeVelocityPlugin.getInstance().getProxy().getPlayer(uuid).orElseThrow()) - .filter(predicate) - .forEach(player -> AuthMeVelocityPlugin.loggedPlayers.remove(player.getUniqueId())); + public void removePlayerIf(@NotNull Predicate predicate){ + plugin.loggedPlayers.removeIf(uuid -> predicate.test(plugin.getProxy().getPlayer(uuid).orElseThrow())); } /** @@ -60,8 +64,8 @@ public class AuthmeVelocityAPI { * @param player the player * @return if the player is on a login server */ - public static boolean isInAuthServer(@NotNull Player player){ - var connection = player.getCurrentServer(); + public boolean isInAuthServer(@NotNull Player player){ + Optional connection = player.getCurrentServer(); return connection.isPresent() && isAuthServer(connection.get()); } @@ -70,8 +74,8 @@ public class AuthmeVelocityAPI { * @param server the server * @return if the server is a login server */ - public static boolean isAuthServer(@NotNull RegisteredServer server){ - return AuthMeConfig.getConfig().getAuthServers().contains(server.getServerInfo().getName()); + public boolean isAuthServer(@NotNull RegisteredServer server){ + return config.getAuthServers().contains(server.getServerInfo().getName()); } /** @@ -79,9 +83,16 @@ public class AuthmeVelocityAPI { * @param connection the connection * @return if the connection is made from a login server */ - public static boolean isAuthServer(@NotNull ServerConnection connection){ - return AuthMeConfig.getConfig().getAuthServers().contains(connection.getServerInfo().getName()); + public boolean isAuthServer(@NotNull ServerConnection connection){ + return config.getAuthServers().contains(connection.getServerInfo().getName()); } - private AuthmeVelocityAPI(){} + /** + * Checks if a string is an name of an auth server + * @param server the server name + * @return if the server is an auth serverr + */ + public boolean isAuthServer(@NotNull String server){ + return config.getAuthServers().contains(server); + } } diff --git a/proxy/src/main/java/com/glyart/authmevelocity/proxy/config/AuthMeConfig.java b/proxy/src/main/java/com/glyart/authmevelocity/proxy/config/AuthMeConfig.java index 8e898e0..87058ab 100644 --- a/proxy/src/main/java/com/glyart/authmevelocity/proxy/config/AuthMeConfig.java +++ b/proxy/src/main/java/com/glyart/authmevelocity/proxy/config/AuthMeConfig.java @@ -1,111 +1,79 @@ package com.glyart.authmevelocity.proxy.config; -import java.nio.file.Path; import java.util.List; +import java.util.Objects; import java.util.Set; +import com.moandjiezana.toml.Toml; + import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.spongepowered.configurate.CommentedConfigurationNode; -import org.spongepowered.configurate.ConfigurateException; -import org.spongepowered.configurate.hocon.HoconConfigurationLoader; -import org.spongepowered.configurate.objectmapping.ConfigSerializable; -import org.spongepowered.configurate.objectmapping.meta.Comment; -public class AuthMeConfig { - private static final String HEADER = "AuthmeVelocity Proxy\n\nOriginal Developer: xQuickGlare\nCurrent Developer: 4drian3d"; - private static final HoconConfigurationLoader.Builder configBuilder = HoconConfigurationLoader.builder() - .defaultOptions(opts -> opts - .shouldCopyDefaults(true) - .header(HEADER) - ); - public static void loadConfig(@NotNull Path path, @NotNull Logger logger){ - Path configPath = path.resolve("config.conf"); - final HoconConfigurationLoader loader = configBuilder - .path(configPath) - .build(); +public final class AuthMeConfig { + private final List authServers; + private final ServerOnLogin serverOnLogin; + private final Commands commands; + private final EnsureAuthServer ensure; - try { - final CommentedConfigurationNode node = loader.load(); - config = node.get(Config.class); - node.set(Config.class, config); - loader.save(node); - } catch (ConfigurateException exception){ - logger.error("Could not load configuration: {}", exception.getMessage()); - } + public AuthMeConfig(@NotNull Toml toml){ + this.authServers = Objects.requireNonNull(toml.getList("authServers"), "the list of auth servers is not available, please check your configuration for any failure"); + this.serverOnLogin = Objects.requireNonNull(toml.getTable("SendOnLogin"), "SendOnLogin options are not available, check your configuration").to(ServerOnLogin.class); + this.commands = Objects.requireNonNull(toml.getTable("Commands"), "Commands options are not available, check your configuration").to(Commands.class); + this.ensure = Objects.requireNonNull(toml.getTable("EnsureAuthServer"), "EnsureAuthServer options are not available, check your configuration").to(EnsureAuthServer.class); } - @ConfigSerializable - public static class Config { - - @Comment("List of login/registration servers") - private Set authservers = Set.of( - "auth1", - "auth2" - ); - - private Commands commands = new Commands(); - - private ServerOnLogin send = new ServerOnLogin(); - - public Set getAuthServers(){ - return this.authservers; - } - - public Commands getCommandsConfig(){ - return this.commands; - } - - public ServerOnLogin getToServerOptions(){ - return this.send; - } - } - @ConfigSerializable public static class ServerOnLogin { - @Comment("Send logged in players to another server?") - private boolean sendToServerOnLogin = false; - - @Comment("List of servers to send\nOne of these servers will be chosen at random") - private List teleportServers = List.of( - "lobby1", - "lobby2" - ); + private boolean sendToServerOnLogin; + private List teleportServers; public boolean sendToServer(){ return this.sendToServerOnLogin; } - public List getTeleportServers(){ + public @NotNull List getTeleportServers(){ return this.teleportServers; } } - @ConfigSerializable public static class Commands{ - @Comment("Sets the commands that users who have not yet logged in can execute") - private Set allowedCommands = Set.of( - "login", - "register", - "l", - "reg", - "email", - "captcha" - ); + private Set allowedCommands; + private String blockedCommandMessage; - @Comment("Sets the message to send in case a non-logged-in player executes an unauthorized command\nTo deactivate the message, leave it empty") - private String blockedCommandMessage = "&4You cannot execute commands if you are not logged in yet"; - - public Set getAllowedCommands(){ + public @NotNull Set getAllowedCommands(){ return this.allowedCommands; } - public String getBlockedMessage() { + public @NotNull String getBlockedMessage() { return this.blockedCommandMessage; } } - private static Config config; - public static Config getConfig(){ - return config; + + public static class EnsureAuthServer { + private boolean ensureFirstServerIsAuthServer; + private String disconnectMessage; + + public boolean ensureAuthServer(){ + return this.ensureFirstServerIsAuthServer; + } + + public @NotNull String getDisconnectMessage(){ + return this.disconnectMessage; + } + + } + + public @NotNull Commands getCommandsConfig(){ + return this.commands; + } + + public @NotNull ServerOnLogin getToServerOptions(){ + return this.serverOnLogin; + } + + public @NotNull EnsureAuthServer getEnsureOptions(){ + return this.ensure; + } + + public @NotNull List getAuthServers(){ + return this.authServers; } - private AuthMeConfig(){} } diff --git a/proxy/src/main/java/com/glyart/authmevelocity/proxy/config/ConfigUtils.java b/proxy/src/main/java/com/glyart/authmevelocity/proxy/config/ConfigUtils.java index 18c02d6..5090022 100644 --- a/proxy/src/main/java/com/glyart/authmevelocity/proxy/config/ConfigUtils.java +++ b/proxy/src/main/java/com/glyart/authmevelocity/proxy/config/ConfigUtils.java @@ -4,14 +4,12 @@ import com.velocitypowered.api.proxy.Player; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -public class ConfigUtils { - public static void sendBlockedMessage(Player player){ - var config = AuthMeConfig.getConfig(); +public final class ConfigUtils { + public static final LegacyComponentSerializer SERIALIZER = LegacyComponentSerializer.builder().character('&').hexColors().build(); + public static void sendBlockedMessage(Player player, AuthMeConfig config){ String blockedMessage = config.getCommandsConfig().getBlockedMessage(); if(!blockedMessage.isBlank()){ - player.sendMessage( - LegacyComponentSerializer.legacyAmpersand().deserialize( - blockedMessage)); + player.sendMessage(SERIALIZER.deserialize(blockedMessage)); } } private ConfigUtils(){} diff --git a/proxy/src/main/java/com/glyart/authmevelocity/proxy/event/PreSendOnLoginEvent.java b/proxy/src/main/java/com/glyart/authmevelocity/proxy/event/PreSendOnLoginEvent.java index 41672e8..90521e2 100644 --- a/proxy/src/main/java/com/glyart/authmevelocity/proxy/event/PreSendOnLoginEvent.java +++ b/proxy/src/main/java/com/glyart/authmevelocity/proxy/event/PreSendOnLoginEvent.java @@ -7,6 +7,8 @@ import com.velocitypowered.api.event.ResultedEvent.GenericResult; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.server.RegisteredServer; +import org.jetbrains.annotations.NotNull; + /** * Event to be executed just before sending a player to another server after login/registration. * Here you have the ability to deny the event. @@ -24,7 +26,7 @@ public final class PreSendOnLoginEvent implements ResultedEvent { * @param actualServer the server on which the player is located * @param serverToSend the server to which the player will be sent */ - public PreSendOnLoginEvent(Player player, RegisteredServer actualServer, RegisteredServer serverToSend){ + public PreSendOnLoginEvent(@NotNull Player player, @NotNull RegisteredServer actualServer, @NotNull RegisteredServer serverToSend){ this.player = player; this.actualserver = actualServer; this.serverToSend = serverToSend; @@ -34,7 +36,7 @@ public final class PreSendOnLoginEvent implements ResultedEvent { * Obtain the logged player * @return the player */ - public Player getPlayer(){ + public @NotNull Player getPlayer(){ return this.player; } @@ -42,7 +44,7 @@ public final class PreSendOnLoginEvent implements ResultedEvent { * Obtain the server on which the player is located * @return the actual server of the player */ - public RegisteredServer getActualServer(){ + public @NotNull RegisteredServer getActualServer(){ return this.actualserver; } @@ -50,7 +52,7 @@ public final class PreSendOnLoginEvent implements ResultedEvent { * Obtain the server to which the player will be sent * @return the server to send the player */ - public RegisteredServer getSendServer(){ + public @NotNull RegisteredServer getSendServer(){ return this.serverToSend; } @@ -58,7 +60,7 @@ public final class PreSendOnLoginEvent implements ResultedEvent { * Get the result of the event */ @Override - public GenericResult getResult() { + public @NotNull GenericResult getResult() { return this.result; } @@ -67,7 +69,7 @@ public final class PreSendOnLoginEvent implements ResultedEvent { * @param newresult the new result */ @Override - public void setResult(GenericResult newresult) { + public void setResult(@NotNull GenericResult newresult) { this.result = Objects.requireNonNull(newresult); } } diff --git a/proxy/src/main/java/com/glyart/authmevelocity/proxy/event/ProxyForcedUnregisterEvent.java b/proxy/src/main/java/com/glyart/authmevelocity/proxy/event/ProxyForcedUnregisterEvent.java new file mode 100644 index 0000000..6ac6c9f --- /dev/null +++ b/proxy/src/main/java/com/glyart/authmevelocity/proxy/event/ProxyForcedUnregisterEvent.java @@ -0,0 +1,17 @@ +package com.glyart.authmevelocity.proxy.event; + +import com.velocitypowered.api.proxy.Player; + +import org.jetbrains.annotations.Nullable; + +public class ProxyForcedUnregisterEvent { + private final Player player; + + public ProxyForcedUnregisterEvent(@Nullable Player player){ + this.player = player; + } + + public @Nullable Player getPlayer(){ + return this.player; + } +} diff --git a/proxy/src/main/java/com/glyart/authmevelocity/proxy/event/ProxyUnregisterEvent.java b/proxy/src/main/java/com/glyart/authmevelocity/proxy/event/ProxyUnregisterEvent.java new file mode 100644 index 0000000..beede3a --- /dev/null +++ b/proxy/src/main/java/com/glyart/authmevelocity/proxy/event/ProxyUnregisterEvent.java @@ -0,0 +1,17 @@ +package com.glyart.authmevelocity.proxy.event; + +import com.velocitypowered.api.proxy.Player; + +import org.jetbrains.annotations.NotNull; + +public class ProxyUnregisterEvent { + private final Player player; + + public ProxyUnregisterEvent(@NotNull Player player){ + this.player = player; + } + + public @NotNull Player getPlayer(){ + return this.player; + } +} diff --git a/proxy/src/main/java/com/glyart/authmevelocity/proxy/listener/FastLoginListener.java b/proxy/src/main/java/com/glyart/authmevelocity/proxy/listener/FastLoginListener.java index 4360252..70679c7 100644 --- a/proxy/src/main/java/com/glyart/authmevelocity/proxy/listener/FastLoginListener.java +++ b/proxy/src/main/java/com/glyart/authmevelocity/proxy/listener/FastLoginListener.java @@ -7,11 +7,13 @@ import com.velocitypowered.api.proxy.ProxyServer; public class FastLoginListener { private final ProxyServer server; - public FastLoginListener(ProxyServer server){ + private final AuthmeVelocityAPI api; + public FastLoginListener(ProxyServer server, AuthmeVelocityAPI api){ this.server = server; + this.api = api; } @Subscribe public void onAutoLogin(VelocityFastLoginAutoLoginEvent event){ - server.getPlayer(event.getProfile().getName()).ifPresent(AuthmeVelocityAPI::addPlayer); + server.getPlayer(event.getProfile().getName()).ifPresent(api::addPlayer); } } diff --git a/proxy/src/main/java/com/glyart/authmevelocity/proxy/listener/PluginMessageListener.java b/proxy/src/main/java/com/glyart/authmevelocity/proxy/listener/PluginMessageListener.java index 44e26b6..e3f48ef 100644 --- a/proxy/src/main/java/com/glyart/authmevelocity/proxy/listener/PluginMessageListener.java +++ b/proxy/src/main/java/com/glyart/authmevelocity/proxy/listener/PluginMessageListener.java @@ -6,9 +6,11 @@ import java.util.Random; import com.glyart.authmevelocity.proxy.AuthmeVelocityAPI; import com.glyart.authmevelocity.proxy.config.AuthMeConfig; import com.glyart.authmevelocity.proxy.event.PreSendOnLoginEvent; +import com.glyart.authmevelocity.proxy.event.ProxyForcedUnregisterEvent; import com.glyart.authmevelocity.proxy.event.ProxyLoginEvent; import com.glyart.authmevelocity.proxy.event.ProxyLogoutEvent; import com.glyart.authmevelocity.proxy.event.ProxyRegisterEvent; +import com.glyart.authmevelocity.proxy.event.ProxyUnregisterEvent; import com.google.common.io.ByteArrayDataInput; import com.velocitypowered.api.event.Continuation; import com.velocitypowered.api.event.Subscribe; @@ -19,19 +21,22 @@ import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.proxy.server.RegisteredServer; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; public class PluginMessageListener { private final ProxyServer proxy; private final Logger logger; private final Random rm; - private AuthMeConfig.Config config; + private final AuthMeConfig config; + private final AuthmeVelocityAPI api; - public PluginMessageListener(@NotNull ProxyServer proxy, @NotNull Logger logger, @NotNull AuthMeConfig.Config config) { + public PluginMessageListener(@NotNull ProxyServer proxy, @NotNull Logger logger, @NotNull AuthMeConfig config, AuthmeVelocityAPI api) { this.proxy = proxy; this.logger = logger; this.rm = new Random(); this.config = config; + this.api = api; } @Subscribe @@ -46,30 +51,36 @@ public class PluginMessageListener { ByteArrayDataInput input = event.dataAsDataStream(); final String sChannel = input.readUTF(); - final Player loggedPlayer = connection.getPlayer(); + final String playername = input.readUTF(); + final @Nullable Player loggedPlayer = proxy.getPlayer(playername).orElse(null); switch(sChannel){ case "LOGIN" : - if (AuthmeVelocityAPI.addPlayer(loggedPlayer)){ - createServerConnectionRequest(loggedPlayer, config, proxy, logger, connection); + if (loggedPlayer != null && api.addPlayer(loggedPlayer)){ + createServerConnectionRequest(loggedPlayer, proxy, logger, connection); } - continuation.resume(); break; case "LOGOUT": - if(AuthmeVelocityAPI.removePlayer(loggedPlayer)){ + if(loggedPlayer != null && api.removePlayer(loggedPlayer)){ proxy.getEventManager().fireAndForget(new ProxyLogoutEvent(loggedPlayer)); } - continuation.resume(); break; case "REGISTER": - proxy.getEventManager().fireAndForget(new ProxyRegisterEvent(loggedPlayer)); - continuation.resume(); + if(loggedPlayer != null) + proxy.getEventManager().fireAndForget(new ProxyRegisterEvent(loggedPlayer)); break; - - default: continuation.resume(); + case "UNREGISTER": + if(loggedPlayer != null) + proxy.getEventManager().fireAndForget(new ProxyUnregisterEvent(loggedPlayer)); + break; + case "FORCE_UNREGISTER": + proxy.getEventManager().fireAndForget(new ProxyForcedUnregisterEvent(loggedPlayer)); + break; + default: break; } + continuation.resume(); } - private void createServerConnectionRequest(Player loggedPlayer, AuthMeConfig.Config config, ProxyServer proxy, Logger logger, ServerConnection connection){ + private void createServerConnectionRequest(Player loggedPlayer, ProxyServer proxy, Logger logger, ServerConnection connection){ final RegisteredServer loginServer = loggedPlayer.getCurrentServer().orElse(connection).getServer(); proxy.getEventManager().fireAndForget(new ProxyLoginEvent(loggedPlayer)); if(config.getToServerOptions().sendToServer()){ diff --git a/proxy/src/main/java/com/glyart/authmevelocity/proxy/listener/ProxyListener.java b/proxy/src/main/java/com/glyart/authmevelocity/proxy/listener/ProxyListener.java index d67f60f..6cb963f 100644 --- a/proxy/src/main/java/com/glyart/authmevelocity/proxy/listener/ProxyListener.java +++ b/proxy/src/main/java/com/glyart/authmevelocity/proxy/listener/ProxyListener.java @@ -1,34 +1,48 @@ package com.glyart.authmevelocity.proxy.listener; +import java.util.Optional; + import com.glyart.authmevelocity.proxy.AuthmeVelocityAPI; import com.glyart.authmevelocity.proxy.config.AuthMeConfig; import com.glyart.authmevelocity.proxy.config.ConfigUtils; import com.glyart.authmevelocity.proxy.utils.AuthmeUtils; import com.velocitypowered.api.event.Continuation; import com.velocitypowered.api.event.EventTask; +import com.velocitypowered.api.event.PostOrder; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.command.CommandExecuteEvent; import com.velocitypowered.api.event.connection.DisconnectEvent; import com.velocitypowered.api.event.player.PlayerChatEvent; +import com.velocitypowered.api.event.player.PlayerChooseInitialServerEvent; import com.velocitypowered.api.event.player.ServerPreConnectEvent; import com.velocitypowered.api.event.player.TabCompleteEvent; import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; +import com.velocitypowered.api.proxy.server.RegisteredServer; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; -public class ProxyListener { - private AuthMeConfig.Config config; +public final class ProxyListener { + private final AuthMeConfig config; + private final AuthmeVelocityAPI api; + private final ProxyServer proxy; + private final Logger logger; - public ProxyListener(@NotNull AuthMeConfig.Config config) { + public ProxyListener(@NotNull AuthMeConfig config, AuthmeVelocityAPI api, Logger logger, ProxyServer proxy) { this.config = config; + this.api = api; + this.logger = logger; + this.proxy = proxy; } @Subscribe - public void onDisconnect(final DisconnectEvent event) { - AuthmeVelocityAPI.removePlayer(event.getPlayer()); + public EventTask onDisconnect(final DisconnectEvent event) { + return EventTask.async(() -> api.removePlayer(event.getPlayer())); } - @Subscribe + @Subscribe(order = PostOrder.FIRST) public void onCommandExecute(final CommandExecuteEvent event, Continuation continuation) { if (!(event.getCommandSource() instanceof Player)){ continuation.resume(); @@ -37,50 +51,82 @@ public class ProxyListener { Player player = ((Player)event.getCommandSource()); - if(AuthmeVelocityAPI.isLogged(player)){ + if(api.isLogged(player)){ continuation.resume(); return; } - if(AuthmeVelocityAPI.isInAuthServer(player)){ + if(api.isInAuthServer(player)){ String command = AuthmeUtils.getFirstArgument(event.getCommand()); if(!config.getCommandsConfig().getAllowedCommands().contains(command)){ - ConfigUtils.sendBlockedMessage(player); + ConfigUtils.sendBlockedMessage(player, config); event.setResult(CommandExecuteEvent.CommandResult.denied()); } } else { - ConfigUtils.sendBlockedMessage(player); + ConfigUtils.sendBlockedMessage(player, config); event.setResult(CommandExecuteEvent.CommandResult.denied()); } continuation.resume(); } - @Subscribe + @Subscribe(order = PostOrder.FIRST) public void onPlayerChat(final PlayerChatEvent event) { - if (!AuthmeVelocityAPI.isLogged(event.getPlayer())) { + if (!api.isLogged(event.getPlayer())) { event.setResult(PlayerChatEvent.ChatResult.denied()); } } @Subscribe public void onServerPreConnect(ServerPreConnectEvent event, Continuation continuation) { - if (AuthmeVelocityAPI.isLogged(event.getPlayer())){ + if (api.isLogged(event.getPlayer())){ continuation.resume(); return; } event.getResult().getServer().ifPresent(server -> { - if(!AuthmeVelocityAPI.isAuthServer(server)){ + if(!api.isAuthServer(server)){ event.setResult(ServerPreConnectEvent.ServerResult.denied()); } }); continuation.resume(); } - @Subscribe + @Subscribe(order = PostOrder.FIRST) public EventTask onTabComplete(TabCompleteEvent event){ - if (!AuthmeVelocityAPI.isLogged(event.getPlayer())){ - return EventTask.async(() -> event.getSuggestions().clear()); + return EventTask.async(() -> { + if (!api.isLogged(event.getPlayer())){ + event.getSuggestions().clear(); + } + }); + } + + @Subscribe(order = PostOrder.LATE) + public void onInitialServer(PlayerChooseInitialServerEvent event, Continuation continuation){ + if(!config.getEnsureOptions().ensureAuthServer()){ + continuation.resume(); + return; + } + Optional optionalSV = event.getInitialServer(); + if(optionalSV.isPresent() && api.isAuthServer(optionalSV.get())){ + continuation.resume(); + return; + } + @Nullable RegisteredServer server = getAvailableServer(); + if(server == null) { + continuation.resume(); + logger.error("Cannot send the player {} to an auth server", event.getPlayer().getUsername()); + event.getPlayer().disconnect(ConfigUtils.SERIALIZER.deserialize(config.getEnsureOptions().getDisconnectMessage())); + return; + } + event.setInitialServer(server); + continuation.resume(); + + } + + private @Nullable RegisteredServer getAvailableServer(){ + for(String sv : config.getAuthServers()){ + Optional opt = proxy.getServer(sv); + if(opt.isPresent()) return opt.get(); } return null; } diff --git a/proxy/src/main/resources/config.toml b/proxy/src/main/resources/config.toml new file mode 100644 index 0000000..3033678 --- /dev/null +++ b/proxy/src/main/resources/config.toml @@ -0,0 +1,29 @@ +# AuthmeVelocity Proxy +# Original Developer: xQuickGlare +# Actual Developer: 4drian3d + +# List of login/registration servers +authServers = ["auth1", "auth2"] + +[SendOnLogin] + # Send logged in players to another server? + sendToServerOnLogin = false + + # List of servers to send + # One of these servers will be chosen at random + teleportServers = ["lobby1", "lobby2"] + +[Commands] + # Sets the commands that users who have not yet logged in can execute + allowedCommands = ["login", "register", "l", "reg", "email", "captcha"] + + # Sets the message to send in case a non-logged-in player executes an unauthorized command + # To deactivate the message, leave it empty + blockedCommandMessage = "&4You cannot execute commands if you are not logged in yet" + +[EnsureAuthServer] + # Ensure that the first server to which players connect is an auth server + ensureFirstServerIsAuthServer = false + + # Message to be sent to the player in case no auth server is available + disconnectMessage = "&4You could not connect to a login server, please try again later" \ No newline at end of file diff --git a/spigot/pom.xml b/spigot/pom.xml index cd2da68..e12f54e 100644 --- a/spigot/pom.xml +++ b/spigot/pom.xml @@ -5,7 +5,7 @@ parent com.glyart.authmevelocity - 1.5.0 + 2.0.0 4.0.0 @@ -32,7 +32,7 @@ io.papermc.paper paper-api - 1.18-R0.1-SNAPSHOT + 1.18.1-R0.1-SNAPSHOT provided diff --git a/spigot/src/main/java/com/glyart/authmevelocity/spigot/AuthMeVelocityPlugin.java b/spigot/src/main/java/com/glyart/authmevelocity/spigot/AuthMeVelocityPlugin.java index 325413a..1b1bb27 100644 --- a/spigot/src/main/java/com/glyart/authmevelocity/spigot/AuthMeVelocityPlugin.java +++ b/spigot/src/main/java/com/glyart/authmevelocity/spigot/AuthMeVelocityPlugin.java @@ -3,6 +3,8 @@ package com.glyart.authmevelocity.spigot; import com.glyart.authmevelocity.spigot.listeners.AuthMeListener; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; + +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; @@ -14,13 +16,18 @@ public class AuthMeVelocityPlugin extends JavaPlugin { this.getServer().getMessenger().registerOutgoingPluginChannel(this, CHANNEL); this.getServer().getPluginManager().registerEvents(new AuthMeListener(this), this); - this.getLogger().info("AuthMeVelocity enabled."); + this.getSLF4JLogger().info("AuthMeVelocity enabled"); } - public void sendMessageToProxy(@NotNull final Player player, MessageType type) { + public void sendMessageToProxy(final Player player, @NotNull MessageType type, @NotNull String playername) { ByteArrayDataOutput out = ByteStreams.newDataOutput(); out.writeUTF(type.toString()); + out.writeUTF(playername); - player.sendPluginMessage(this, CHANNEL, out.toByteArray()); + if(player == null){ + Bukkit.getServer().sendPluginMessage(this, CHANNEL, out.toByteArray()); + } else { + player.sendPluginMessage(this, CHANNEL, out.toByteArray()); + } } } diff --git a/spigot/src/main/java/com/glyart/authmevelocity/spigot/MessageType.java b/spigot/src/main/java/com/glyart/authmevelocity/spigot/MessageType.java index 46455ee..52c054d 100644 --- a/spigot/src/main/java/com/glyart/authmevelocity/spigot/MessageType.java +++ b/spigot/src/main/java/com/glyart/authmevelocity/spigot/MessageType.java @@ -1,5 +1,5 @@ package com.glyart.authmevelocity.spigot; public enum MessageType { - LOGIN, REGISTER, LOGOUT + LOGIN, REGISTER, LOGOUT, FORCE_UNREGISTER, UNREGISTER; } diff --git a/spigot/src/main/java/com/glyart/authmevelocity/spigot/events/PreSendLoginEvent.java b/spigot/src/main/java/com/glyart/authmevelocity/spigot/events/PreSendLoginEvent.java index 8c13018..d993897 100644 --- a/spigot/src/main/java/com/glyart/authmevelocity/spigot/events/PreSendLoginEvent.java +++ b/spigot/src/main/java/com/glyart/authmevelocity/spigot/events/PreSendLoginEvent.java @@ -8,15 +8,15 @@ import org.jetbrains.annotations.NotNull; public class PreSendLoginEvent extends PlayerEvent implements Cancellable { private static final HandlerList HANDLERS = new HandlerList(); - private boolean isCancelled; + private boolean isCancelled = false; - public PreSendLoginEvent(@NotNull final Player player) { + public PreSendLoginEvent(@NotNull Player player) { super(player); } @Override public boolean isCancelled() { - return isCancelled; + return this.isCancelled; } @Override diff --git a/spigot/src/main/java/com/glyart/authmevelocity/spigot/listeners/AuthMeListener.java b/spigot/src/main/java/com/glyart/authmevelocity/spigot/listeners/AuthMeListener.java index 251c20e..96cfa31 100644 --- a/spigot/src/main/java/com/glyart/authmevelocity/spigot/listeners/AuthMeListener.java +++ b/spigot/src/main/java/com/glyart/authmevelocity/spigot/listeners/AuthMeListener.java @@ -7,6 +7,8 @@ import com.glyart.authmevelocity.spigot.events.PreSendLoginEvent; import fr.xephi.authme.events.LoginEvent; import fr.xephi.authme.events.LogoutEvent; import fr.xephi.authme.events.RegisterEvent; +import fr.xephi.authme.events.UnregisterByAdminEvent; +import fr.xephi.authme.events.UnregisterByPlayerEvent; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -21,21 +23,31 @@ public class AuthMeListener implements Listener { } @EventHandler(priority = EventPriority.HIGHEST) - public void onLogin(final LoginEvent event) { + public void onLogin(LoginEvent event) { final Player player = event.getPlayer(); PreSendLoginEvent preSendLoginEvent = new PreSendLoginEvent(player); - if(!preSendLoginEvent.callEvent()){ - plugin.sendMessageToProxy(player, MessageType.LOGIN); + if(preSendLoginEvent.callEvent()){ + plugin.sendMessageToProxy(player, MessageType.LOGIN, player.getName()); } } @EventHandler public void onRegister(RegisterEvent event){ - plugin.sendMessageToProxy(event.getPlayer(), MessageType.REGISTER); + plugin.sendMessageToProxy(event.getPlayer(), MessageType.REGISTER, event.getPlayer().getName()); } @EventHandler public void onLogout(LogoutEvent event){ - plugin.sendMessageToProxy(event.getPlayer(), MessageType.LOGOUT); + plugin.sendMessageToProxy(event.getPlayer(), MessageType.LOGOUT, event.getPlayer().getName()); + } + + @EventHandler + public void onUnRegister(UnregisterByPlayerEvent event){ + plugin.sendMessageToProxy(event.getPlayer(), MessageType.UNREGISTER, event.getPlayer().getName()); + } + + @EventHandler + public void onAdminUnRegister(UnregisterByAdminEvent event){ + plugin.sendMessageToProxy(event.getPlayer(), MessageType.FORCE_UNREGISTER, event.getPlayerName()); } } diff --git a/spigot/src/main/resources/plugin.yml b/spigot/src/main/resources/plugin.yml index 9941d43..db26376 100644 --- a/spigot/src/main/resources/plugin.yml +++ b/spigot/src/main/resources/plugin.yml @@ -1,6 +1,7 @@ name: AuthMeVelocity -author: xQuickGlare +authors: [xQuickGlare, 4drian3d] version: ${project.version} main: com.glyart.authmevelocity.spigot.AuthMeVelocityPlugin depend: [AuthMe] -api-version: 1.16 \ No newline at end of file +# pls, dont use outdated versions, use 1.16.5+ +api-version: 1.13 \ No newline at end of file