diff --git a/paper/build.gradle.kts b/paper/build.gradle.kts
index e72b7c1..a8bf9a2 100644
--- a/paper/build.gradle.kts
+++ b/paper/build.gradle.kts
@@ -32,7 +32,7 @@ dependencies {
tasks {
shadowJar {
- archiveFileName.set("AuthMeVelocity-Paper-${project.version}.jar")
+ archiveBaseName.set("AuthMeVelocity-Paper")
archiveClassifier.set("")
relocate("net.byteflux.libby", "io.github._4drian3d.authmevelocity.libs.libby")
diff --git a/paper/src/main/resources/paper-plugin.yml b/paper/src/main/resources/paper-plugin.yml
index 270131c..ffe73ba 100644
--- a/paper/src/main/resources/paper-plugin.yml
+++ b/paper/src/main/resources/paper-plugin.yml
@@ -1,6 +1,7 @@
name: AuthMeVelocity
version: '${version}'
main: io.github._4drian3d.authmevelocity.paper.AuthMeVelocityPlugin
+bootstrapper: io.github._4drian3d.authmevelocity.paper.AuthMeVelocityBootstrap
description: AuthMeReloaded Support for Velocity
authors:
- xQuickGlare
diff --git a/velocity/build.gradle.kts b/velocity/build.gradle.kts
index 15202b7..684f788 100644
--- a/velocity/build.gradle.kts
+++ b/velocity/build.gradle.kts
@@ -39,7 +39,7 @@ tasks {
shadowJar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
- archiveFileName.set("AuthMeVelocity-Proxy-${project.version}.jar")
+ archiveBaseName.set("AuthMeVelocity-Velocity")
archiveClassifier.set("")
relocate("org.bstats", "io.github._4drian3d.authmevelocity.libs.bstats")
diff --git a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/AuthMeVelocityPlugin.java b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/AuthMeVelocityPlugin.java
index 2b9f69e..0eca487 100644
--- a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/AuthMeVelocityPlugin.java
+++ b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/AuthMeVelocityPlugin.java
@@ -20,7 +20,6 @@ package io.github._4drian3d.authmevelocity.velocity;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.velocitypowered.api.command.CommandSource;
-import com.velocitypowered.api.event.EventManager;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.plugin.Dependency;
@@ -40,10 +39,16 @@ import io.github._4drian3d.authmevelocity.common.LibsManager;
import io.github._4drian3d.authmevelocity.common.configuration.ConfigurationContainer;
import io.github._4drian3d.authmevelocity.common.configuration.ProxyConfiguration;
import io.github._4drian3d.authmevelocity.velocity.commands.AuthMeCommand;
-import io.github._4drian3d.authmevelocity.velocity.listener.ConnectListener;
-import io.github._4drian3d.authmevelocity.velocity.listener.FastLoginListener;
-import io.github._4drian3d.authmevelocity.velocity.listener.PluginMessageListener;
-import io.github._4drian3d.authmevelocity.velocity.listener.ProxyListener;
+import io.github._4drian3d.authmevelocity.velocity.listener.Listener;
+import io.github._4drian3d.authmevelocity.velocity.listener.compat.FastLoginListener;
+import io.github._4drian3d.authmevelocity.velocity.listener.connection.DisconnectListener;
+import io.github._4drian3d.authmevelocity.velocity.listener.connection.InitialServerListener;
+import io.github._4drian3d.authmevelocity.velocity.listener.connection.PostConnectListener;
+import io.github._4drian3d.authmevelocity.velocity.listener.connection.PreConnectListener;
+import io.github._4drian3d.authmevelocity.velocity.listener.data.PluginMessageListener;
+import io.github._4drian3d.authmevelocity.velocity.listener.input.ChatListener;
+import io.github._4drian3d.authmevelocity.velocity.listener.input.CommandListener;
+import io.github._4drian3d.authmevelocity.velocity.listener.input.TabCompleteListener;
import net.byteflux.libby.VelocityLibraryManager;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bstats.charts.SimplePie;
@@ -84,8 +89,6 @@ public final class AuthMeVelocityPlugin implements AuthMeVelocityAPI {
@Inject
private ProxyServer proxy;
@Inject
- private EventManager eventManager;
- @Inject
private PluginManager pluginManager;
@Inject
private Logger logger;
@@ -123,17 +126,22 @@ public final class AuthMeVelocityPlugin implements AuthMeVelocityAPI {
proxy.getChannelRegistrar().register(MODERN_CHANNEL, LEGACY_CHANNEL);
Stream.of(
- ProxyListener.class,
- ConnectListener.class,
- PluginMessageListener.class
+ PluginMessageListener.class,
+ DisconnectListener.class,
+ InitialServerListener.class,
+ PostConnectListener.class,
+ PreConnectListener.class,
+ ChatListener.class,
+ CommandListener.class,
+ TabCompleteListener.class
).map(injector::getInstance)
- .forEach(listener -> eventManager.register(this, listener));
+ .forEach(Listener::register);
final boolean fastlogin = pluginManager.isLoaded("fastlogin");
metrics.addCustomChart(new SimplePie("fastlogin_compatibility", () -> Boolean.toString(fastlogin)));
if (fastlogin) {
logDebug("Register FastLogin compatibility");
- eventManager.register(this, injector.getInstance(FastLoginListener.class));
+ injector.getInstance(FastLoginListener.class).register();
}
final boolean miniplaceholders = pluginManager.isLoaded("miniplaceholders");
diff --git a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/ConnectListener.java b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/ConnectListener.java
deleted file mode 100644
index 57dcfc9..0000000
--- a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/ConnectListener.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2023 AuthMeVelocity Contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package io.github._4drian3d.authmevelocity.velocity.listener;
-
-import com.google.common.io.ByteArrayDataOutput;
-import com.google.common.io.ByteStreams;
-import com.google.inject.Inject;
-import com.velocitypowered.api.event.Continuation;
-import com.velocitypowered.api.event.PostOrder;
-import com.velocitypowered.api.event.Subscribe;
-import com.velocitypowered.api.event.player.PlayerChooseInitialServerEvent;
-import com.velocitypowered.api.event.player.ServerPostConnectEvent;
-import com.velocitypowered.api.event.player.ServerPreConnectEvent;
-import com.velocitypowered.api.proxy.Player;
-import com.velocitypowered.api.proxy.ProxyServer;
-import com.velocitypowered.api.proxy.ServerConnection;
-import com.velocitypowered.api.proxy.server.RegisteredServer;
-import io.github._4drian3d.authmevelocity.common.configuration.ProxyConfiguration;
-import io.github._4drian3d.authmevelocity.velocity.AuthMeVelocityPlugin;
-import io.github._4drian3d.authmevelocity.velocity.utils.AuthMeUtils;
-import io.github._4drian3d.authmevelocity.velocity.utils.Pair;
-import org.slf4j.Logger;
-
-import java.util.Optional;
-
-public final class ConnectListener {
- @Inject
- private ProxyServer proxy;
- @Inject
- private Logger logger;
- @Inject
- private AuthMeVelocityPlugin plugin;
-
- @Subscribe(order = PostOrder.LATE)
- public void onInitialServer(
- final PlayerChooseInitialServerEvent event,
- Continuation continuation
- ) {
- if (!plugin.config().get().ensureAuthServer().ensureFirstServerIsAuthServer()) {
- continuation.resume();
- plugin.logDebug("PlayerChooseInitialServerEvent | Not enabled");
- return;
- }
-
- final Optional optionalSV = event.getInitialServer();
- if (optionalSV.isPresent() && plugin.isAuthServer(optionalSV.get())) {
- continuation.resume();
- plugin.logDebug("PlayerChooseInitialServerEvent | Player is in auth server");
- return;
- }
- final ProxyConfiguration config = plugin.config().get();
- final Pair server = AuthMeUtils.serverToSend(
- config.ensureAuthServer().sendMode(), proxy, config.authServers(), config.advanced().randomAttempts());
-
- // Velocity takes over in case the initial server is not present
- event.setInitialServer(server.object());
- continuation.resume();
- if (server.isEmpty()) {
- plugin.logDebug("PlayerChooseInitialServerEvent | Null server");
- logger.error("Cannot send the player {} to an auth server", event.getPlayer().getUsername());
- }
- }
-
- @Subscribe
- public void onServerPreConnect(
- final ServerPreConnectEvent event,
- final Continuation continuation
- ) {
- if (plugin.isLogged(event.getPlayer())) {
- plugin.logDebug("ServerPreConnectEvent | Player already logged");
- continuation.resume();
- return;
- }
-
- final RegisteredServer server = event.getResult().getServer().orElse(null);
- if (server == null) {
- plugin.logDebug("ServerPreConnectEvent | Null Server");
- continuation.resume();
- return;
- }
- // this should be present, "event.getResult().isAllowed()" is the "isPresent" check
- if (!plugin.isAuthServer(server)) {
- plugin.logDebug("ServerPreConnectEvent | Server "+server.getServerInfo().getName()+" is not an auth server");
- event.setResult(ServerPreConnectEvent.ServerResult.denied());
- } else {
- plugin.logDebug("ServerPreConnectEvent | Server "+server.getServerInfo().getName()+" is an auth server");
- }
- continuation.resume();
- }
-
- @SuppressWarnings("UnstableApiUsage")
- @Subscribe
- public void onServerPostConnect(final ServerPostConnectEvent event) {
- final Player player = event.getPlayer();
-
- final boolean isLogged = plugin.isLogged(player);
- plugin.logDebug("ServerPostConnectEvent | Player "+player.getUsername()+" is logged: " + isLogged);
- final RegisteredServer server = player.getCurrentServer().map(ServerConnection::getServer).orElse(null);
- if (server == null) {
- plugin.logDebug("ServerPostConnectEvent | Player "+player.getUsername()+" is not in a server");
- return;
- }
- final boolean isInAuthServer = plugin.isInAuthServer(player);
- plugin.logDebug("ServerPostConnectEvent | Player "+player.getUsername()+" is in AuthServer: " + isInAuthServer);
-
- if (!(isLogged && isInAuthServer)) {
- return;
- }
-
- plugin.logDebug("ServerPostConnectEvent | Already logged player and connected to an Auth server");
- final ByteArrayDataOutput buf = ByteStreams.newDataOutput();
- buf.writeUTF("LOGIN");
-
- final byte[] byteArray = buf.toByteArray();
- plugin.logDebug("ServerPostConnectEvent | Sending LOGIN data");
- if (server.sendPluginMessage(AuthMeVelocityPlugin.MODERN_CHANNEL, byteArray)) {
- plugin.logDebug("ServerPostConnectEvent | Correctly send data");
- } else {
- plugin.logDebug("ServerPostConnectEvent | Failed to send data");
- }
- }
-}
diff --git a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/Listener.java b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/Listener.java
new file mode 100644
index 0000000..cecd96c
--- /dev/null
+++ b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/Listener.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 AuthMeVelocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package io.github._4drian3d.authmevelocity.velocity.listener;
+
+import com.velocitypowered.api.event.AwaitingEventExecutor;
+
+public interface Listener extends AwaitingEventExecutor {
+ void register();
+}
diff --git a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/PluginMessageListener.java b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/PluginMessageListener.java
deleted file mode 100644
index 4630ccf..0000000
--- a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/PluginMessageListener.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2023 AuthMeVelocity Contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package io.github._4drian3d.authmevelocity.velocity.listener;
-
-import com.google.common.io.ByteArrayDataInput;
-import com.google.inject.Inject;
-import com.velocitypowered.api.event.Continuation;
-import com.velocitypowered.api.event.EventManager;
-import com.velocitypowered.api.event.Subscribe;
-import com.velocitypowered.api.event.connection.PluginMessageEvent;
-import com.velocitypowered.api.proxy.Player;
-import com.velocitypowered.api.proxy.ProxyServer;
-import com.velocitypowered.api.proxy.ServerConnection;
-import com.velocitypowered.api.proxy.server.RegisteredServer;
-import io.github._4drian3d.authmevelocity.api.velocity.event.*;
-import io.github._4drian3d.authmevelocity.common.MessageType;
-import io.github._4drian3d.authmevelocity.common.configuration.ProxyConfiguration;
-import io.github._4drian3d.authmevelocity.velocity.AuthMeVelocityPlugin;
-import io.github._4drian3d.authmevelocity.velocity.utils.AuthMeUtils;
-import io.github._4drian3d.authmevelocity.velocity.utils.Pair;
-import org.jetbrains.annotations.Nullable;
-import org.slf4j.Logger;
-
-import java.util.Locale;
-
-public class PluginMessageListener {
- @Inject
- private ProxyServer proxy;
- @Inject
- private EventManager eventManager;
- @Inject
- private Logger logger;
- @Inject
- private AuthMeVelocityPlugin plugin;
-
- @Subscribe
- public void onPluginMessage(final PluginMessageEvent event, Continuation continuation) {
- final boolean cancelled = !event.getResult().isAllowed()
- || !(event.getSource() instanceof ServerConnection)
- || !(event.getIdentifier().equals(AuthMeVelocityPlugin.MODERN_CHANNEL)
- || event.getIdentifier().equals(AuthMeVelocityPlugin.LEGACY_CHANNEL));
- if (cancelled) {
- continuation.resume();
- plugin.logDebug("PluginMessageEvent | Not allowed");
- return;
- }
-
- final ServerConnection connection = (ServerConnection) event.getSource();
-
- event.setResult(PluginMessageEvent.ForwardResult.handled());
-
- final ByteArrayDataInput input = event.dataAsDataStream();
- final String message = input.readUTF();
- final MessageType type = MessageType.valueOf(
- message.toUpperCase(Locale.ROOT));
- final String name = input.readUTF();
- final @Nullable Player player = proxy.getPlayer(name).orElse(null);
-
- switch (type) {
- case LOGIN -> {
- plugin.logDebug("PluginMessageEvent | Login type");
- if (player != null && plugin.addPlayer(player)) {
- eventManager.fireAndForget(new ProxyLoginEvent(player));
- if (plugin.config().get().sendOnLogin().sendToServerOnLogin()) {
- this.createServerConnectionRequest(player, connection);
- }
- plugin.logDebug("PluginMessageEvent | Player not null");
- }
- }
- case LOGOUT -> {
- plugin.logDebug("PluginMessageEvent | Logout type");
- if (player != null && plugin.removePlayer(player)){
- eventManager.fireAndForget(new ProxyLogoutEvent(player));
- plugin.logDebug("PluginMessageEvent | Player not null");
- }
- }
- case REGISTER -> {
- plugin.logDebug("PluginMessageEvent | Register");
- if (player != null) {
- eventManager.fireAndForget(new ProxyRegisterEvent(player));
- plugin.logDebug("PluginMessageEvent | Player not null");
- }
- }
- case UNREGISTER -> {
- plugin.logDebug("PluginMessageEvent | Unregister type");
- if (player != null) {
- plugin.logDebug("PluginMessageEvent | Player not null");
- eventManager.fireAndForget(new ProxyUnregisterEvent(player));
- }
- }
- case FORCE_UNREGISTER -> {
- eventManager.fireAndForget(new ProxyForcedUnregisterEvent(player));
- plugin.logDebug("PluginMessageEvent | Forced Unregister type");
- }
-
- }
- continuation.resume();
- }
-
- private void createServerConnectionRequest(Player player, ServerConnection connection){
- final RegisteredServer loginServer = player.getCurrentServer().orElse(connection).getServer();
-
- final ProxyConfiguration config = plugin.config().get();
-
- final Pair toSend = AuthMeUtils.serverToSend(
- config.sendOnLogin().sendMode(), proxy, config.sendOnLogin().teleportServers(), config.advanced().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;
- }
-
- eventManager.fire(new PreSendOnLoginEvent(player, loginServer, toSend.object()))
- .thenAccept(event -> {
- if (!event.getResult().isAllowed()) {
- return;
- }
- player.createConnectionRequest(event.getResult().getServer())
- .connect()
- .thenAcceptAsync(result -> {
- if (!result.isSuccessful()) {
- logger.info("Unable to connect the player {} to the server {}",
- player.getUsername(),
- result.getAttemptedConnection().getServerInfo().getName());
- }
- });
- });
- }
-}
diff --git a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/ProxyListener.java b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/ProxyListener.java
deleted file mode 100644
index 8447e7c..0000000
--- a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/ProxyListener.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2023 AuthMeVelocity Contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package io.github._4drian3d.authmevelocity.velocity.listener;
-
-import com.google.inject.Inject;
-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.TabCompleteEvent;
-import com.velocitypowered.api.proxy.Player;
-import io.github._4drian3d.authmevelocity.velocity.AuthMeVelocityPlugin;
-import io.github._4drian3d.authmevelocity.velocity.utils.AuthMeUtils;
-import net.kyori.adventure.text.minimessage.MiniMessage;
-
-public final class ProxyListener {
- @Inject
- private AuthMeVelocityPlugin plugin;
-
- @Subscribe
- public EventTask onDisconnect(final DisconnectEvent event) {
- if (event.getLoginStatus() == DisconnectEvent.LoginStatus.CONFLICTING_LOGIN) {
- return null;
- }
-
- return EventTask.async(() -> plugin.removePlayer(event.getPlayer()));
- }
-
- @Subscribe(order = PostOrder.FIRST)
- public void onCommandExecute(final CommandExecuteEvent event, Continuation continuation) {
- if (!(event.getCommandSource() instanceof final Player player)){
- plugin.logDebug("CommandExecuteEvent | CommandSource is not a player");
- continuation.resume();
- return;
- }
-
- if (plugin.isLogged(player)) {
- plugin.logDebug("CommandExecuteEvent | Player is already logged");
- continuation.resume();
- return;
- }
-
- if (plugin.isInAuthServer(player)) {
- plugin.logDebug("CommandExecuteEvent | Player is in Auth Server");
- String command = AuthMeUtils.getFirstArgument(event.getCommand());
- if (!plugin.config().get().commands().allowedCommands().contains(command)) {
- plugin.logDebug("CommandExecuteEvent | Player executed an blocked command");
- sendBlockedMessage(player);
- event.setResult(CommandExecuteEvent.CommandResult.denied());
- }
- } else {
- plugin.logDebug("CommandExecuteEven | Player is not in auth server");
- sendBlockedMessage(player);
- event.setResult(CommandExecuteEvent.CommandResult.denied());
- }
- continuation.resume();
- }
-
- @Subscribe(order = PostOrder.FIRST)
- public void onPlayerChat(final PlayerChatEvent event, Continuation continuation) {
- if (plugin.isLogged(event.getPlayer())) {
- plugin.logDebug("PlayerChatEvent | Player is already logged");
- continuation.resume();
- return;
- }
-
- plugin.logDebug("PlayerChatEvent | Player is not logged");
-
- event.setResult(PlayerChatEvent.ChatResult.denied());
- continuation.resume();
- }
-
- @Subscribe(order = PostOrder.FIRST)
- public void onTabComplete(TabCompleteEvent event){
- if (plugin.isLogged(event.getPlayer())) {
- plugin.logDebug("TabCompleteEvent | Player is already logged");
- return;
- }
-
- final String command = event.getPartialMessage();
- for (final String allowed : plugin.config().get().commands().allowedCommands()) {
- if (allowed.startsWith(command)) {
- return;
- }
- }
-
- plugin.logDebug("TabCompleteEvent | Not allowed tab-completion");
- event.getSuggestions().clear();
- }
-
- void sendBlockedMessage(Player player){
- String blockedMessage = plugin.config().get().commands().blockedCommandMessage();
- if (!blockedMessage.isBlank()){
- player.sendMessage(MiniMessage.miniMessage().deserialize(blockedMessage));
- }
- }
-
-}
diff --git a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/FastLoginListener.java b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/compat/FastLoginListener.java
similarity index 58%
rename from velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/FastLoginListener.java
rename to velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/compat/FastLoginListener.java
index 7781575..28863c1 100644
--- a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/FastLoginListener.java
+++ b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/compat/FastLoginListener.java
@@ -15,23 +15,31 @@
* along with this program. If not, see .
*/
-package io.github._4drian3d.authmevelocity.velocity.listener;
+package io.github._4drian3d.authmevelocity.velocity.listener.compat;
import com.github.games647.fastlogin.velocity.event.VelocityFastLoginAutoLoginEvent;
import com.google.inject.Inject;
-import com.velocitypowered.api.event.Subscribe;
+import com.velocitypowered.api.event.EventTask;
import com.velocitypowered.api.proxy.ProxyServer;
import io.github._4drian3d.authmevelocity.velocity.AuthMeVelocityPlugin;
+import io.github._4drian3d.authmevelocity.velocity.listener.Listener;
-public class FastLoginListener {
+public final class FastLoginListener implements Listener {
@Inject
private ProxyServer proxy;
@Inject
private AuthMeVelocityPlugin plugin;
- @Subscribe
- public void onAutoLogin(VelocityFastLoginAutoLoginEvent event){
- plugin.logDebug("VelocityFastLoginAutoLoginEvent | Attempt to auto register player");
- proxy.getPlayer(event.getProfile().getName()).ifPresent(plugin::addPlayer);
+ @Override
+ public void register() {
+ proxy.getEventManager().register(plugin, VelocityFastLoginAutoLoginEvent.class, this);
+ }
+
+ @Override
+ public EventTask executeAsync(final VelocityFastLoginAutoLoginEvent event) {
+ return EventTask.async(() -> {
+ plugin.logDebug("VelocityFastLoginAutoLoginEvent | Attempt to auto register player");
+ proxy.getPlayer(event.getProfile().getName()).ifPresent(plugin::addPlayer);
+ });
}
}
diff --git a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/connection/DisconnectListener.java b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/connection/DisconnectListener.java
new file mode 100644
index 0000000..7029ff9
--- /dev/null
+++ b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/connection/DisconnectListener.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 AuthMeVelocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package io.github._4drian3d.authmevelocity.velocity.listener.connection;
+
+import com.google.inject.Inject;
+import com.velocitypowered.api.event.EventManager;
+import com.velocitypowered.api.event.EventTask;
+import com.velocitypowered.api.event.connection.DisconnectEvent;
+import io.github._4drian3d.authmevelocity.velocity.AuthMeVelocityPlugin;
+import io.github._4drian3d.authmevelocity.velocity.listener.Listener;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+public final class DisconnectListener implements Listener {
+ @Inject
+ private AuthMeVelocityPlugin plugin;
+ @Inject
+ private EventManager eventManager;
+
+ @Override
+ public void register() {
+ eventManager.register(plugin, DisconnectEvent.class, this);
+ }
+
+ @Override
+ public @Nullable EventTask executeAsync(final DisconnectEvent event) {
+ if (event.getLoginStatus() == DisconnectEvent.LoginStatus.CONFLICTING_LOGIN) {
+ return null;
+ }
+
+ return EventTask.async(() -> plugin.removePlayer(event.getPlayer()));
+ }
+}
diff --git a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/connection/InitialServerListener.java b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/connection/InitialServerListener.java
new file mode 100644
index 0000000..28150fb
--- /dev/null
+++ b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/connection/InitialServerListener.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 AuthMeVelocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package io.github._4drian3d.authmevelocity.velocity.listener.connection;
+
+import com.google.inject.Inject;
+import com.velocitypowered.api.event.EventManager;
+import com.velocitypowered.api.event.EventTask;
+import com.velocitypowered.api.event.PostOrder;
+import com.velocitypowered.api.event.player.PlayerChooseInitialServerEvent;
+import com.velocitypowered.api.proxy.ProxyServer;
+import com.velocitypowered.api.proxy.server.RegisteredServer;
+import io.github._4drian3d.authmevelocity.common.configuration.ProxyConfiguration;
+import io.github._4drian3d.authmevelocity.velocity.AuthMeVelocityPlugin;
+import io.github._4drian3d.authmevelocity.velocity.listener.Listener;
+import io.github._4drian3d.authmevelocity.velocity.utils.AuthMeUtils;
+import io.github._4drian3d.authmevelocity.velocity.utils.Pair;
+import org.slf4j.Logger;
+
+import java.util.Optional;
+
+public final class InitialServerListener implements Listener {
+ @Inject
+ private AuthMeVelocityPlugin plugin;
+ @Inject
+ private EventManager eventManager;
+ @Inject
+ private ProxyServer proxy;
+ @Inject
+ private Logger logger;
+
+ @Override
+ public void register() {
+ eventManager.register(plugin, PlayerChooseInitialServerEvent.class, PostOrder.LATE, this);
+ }
+
+ @Override
+ public EventTask executeAsync(final PlayerChooseInitialServerEvent event) {
+ return EventTask.withContinuation(continuation -> {
+ final ProxyConfiguration config = plugin.config().get();
+ if (!config.ensureAuthServer().ensureFirstServerIsAuthServer()) {
+ continuation.resume();
+ plugin.logDebug("PlayerChooseInitialServerEvent | Not enabled");
+ return;
+ }
+
+ final Optional optionalSV = event.getInitialServer();
+ if (optionalSV.isPresent() && plugin.isAuthServer(optionalSV.get())) {
+ continuation.resume();
+ plugin.logDebug("PlayerChooseInitialServerEvent | Player is in auth server");
+ return;
+ }
+
+ final Pair server = AuthMeUtils.serverToSend(
+ config.ensureAuthServer().sendMode(), proxy, config.authServers(), config.advanced().randomAttempts());
+
+ // Velocity takes over in case the initial server is not present
+ event.setInitialServer(server.object());
+ continuation.resume();
+ if (server.isEmpty()) {
+ plugin.logDebug("PlayerChooseInitialServerEvent | Null server");
+ logger.error("Cannot send the player {} to an auth server", event.getPlayer().getUsername());
+ }
+ });
+ }
+}
diff --git a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/connection/PostConnectListener.java b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/connection/PostConnectListener.java
new file mode 100644
index 0000000..8730b3d
--- /dev/null
+++ b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/connection/PostConnectListener.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2023 AuthMeVelocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package io.github._4drian3d.authmevelocity.velocity.listener.connection;
+
+import com.google.common.io.ByteArrayDataOutput;
+import com.google.common.io.ByteStreams;
+import com.google.inject.Inject;
+import com.velocitypowered.api.event.EventManager;
+import com.velocitypowered.api.event.EventTask;
+import com.velocitypowered.api.event.player.ServerPostConnectEvent;
+import com.velocitypowered.api.proxy.Player;
+import com.velocitypowered.api.proxy.ServerConnection;
+import com.velocitypowered.api.proxy.server.RegisteredServer;
+import io.github._4drian3d.authmevelocity.velocity.AuthMeVelocityPlugin;
+import io.github._4drian3d.authmevelocity.velocity.listener.Listener;
+
+public final class PostConnectListener implements Listener {
+ @Inject
+ private AuthMeVelocityPlugin plugin;
+ @Inject
+ private EventManager eventManager;
+
+ @Override
+ public void register() {
+ eventManager.register(plugin, ServerPostConnectEvent.class, this);
+ }
+
+ @Override
+ public EventTask executeAsync(final ServerPostConnectEvent event) {
+ return EventTask.async(() -> {
+ final Player player = event.getPlayer();
+
+ final boolean isLogged = plugin.isLogged(player);
+ plugin.logDebug("ServerPostConnectEvent | Player "+player.getUsername()+" is logged: " + isLogged);
+ final RegisteredServer server = player.getCurrentServer().map(ServerConnection::getServer).orElse(null);
+ if (server == null) {
+ plugin.logDebug("ServerPostConnectEvent | Player "+player.getUsername()+" is not in a server");
+ return;
+ }
+ final boolean isInAuthServer = plugin.isInAuthServer(player);
+ plugin.logDebug("ServerPostConnectEvent | Player "+player.getUsername()+" is in AuthServer: " + isInAuthServer);
+
+ if (!(isLogged && isInAuthServer)) {
+ return;
+ }
+
+ plugin.logDebug("ServerPostConnectEvent | Already logged player and connected to an Auth server");
+ final ByteArrayDataOutput buf = ByteStreams.newDataOutput();
+ buf.writeUTF("LOGIN");
+
+ final byte[] byteArray = buf.toByteArray();
+ plugin.logDebug("ServerPostConnectEvent | Sending LOGIN data");
+ if (server.sendPluginMessage(AuthMeVelocityPlugin.MODERN_CHANNEL, byteArray)) {
+ plugin.logDebug("ServerPostConnectEvent | Correctly send data");
+ } else {
+ plugin.logDebug("ServerPostConnectEvent | Failed to send data");
+ }
+ });
+ }
+}
diff --git a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/connection/PreConnectListener.java b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/connection/PreConnectListener.java
new file mode 100644
index 0000000..d055e57
--- /dev/null
+++ b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/connection/PreConnectListener.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 AuthMeVelocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package io.github._4drian3d.authmevelocity.velocity.listener.connection;
+
+import com.google.inject.Inject;
+import com.velocitypowered.api.event.EventManager;
+import com.velocitypowered.api.event.EventTask;
+import com.velocitypowered.api.event.player.ServerPreConnectEvent;
+import com.velocitypowered.api.proxy.server.RegisteredServer;
+import io.github._4drian3d.authmevelocity.velocity.AuthMeVelocityPlugin;
+import io.github._4drian3d.authmevelocity.velocity.listener.Listener;
+
+public final class PreConnectListener implements Listener {
+ @Inject
+ private AuthMeVelocityPlugin plugin;
+ @Inject
+ private EventManager eventManager;
+
+ @Override
+ public void register() {
+ eventManager.register(plugin, ServerPreConnectEvent.class, this);
+ }
+
+ @Override
+ public EventTask executeAsync(final ServerPreConnectEvent event) {
+ return EventTask.withContinuation(continuation -> {
+ if (plugin.isLogged(event.getPlayer())) {
+ plugin.logDebug("ServerPreConnectEvent | Player already logged");
+ continuation.resume();
+ return;
+ }
+
+ final RegisteredServer server = event.getResult().getServer().orElse(null);
+ if (server == null) {
+ plugin.logDebug("ServerPreConnectEvent | Null Server");
+ continuation.resume();
+ return;
+ }
+ // this should be present, "event.getResult().isAllowed()" is the "isPresent" check
+ if (!plugin.isAuthServer(server)) {
+ plugin.logDebug("ServerPreConnectEvent | Server "+server.getServerInfo().getName()+" is not an auth server");
+ event.setResult(ServerPreConnectEvent.ServerResult.denied());
+ } else {
+ plugin.logDebug("ServerPreConnectEvent | Server "+server.getServerInfo().getName()+" is an auth server");
+ }
+ continuation.resume();
+ });
+ }
+}
diff --git a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/data/PluginMessageListener.java b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/data/PluginMessageListener.java
new file mode 100644
index 0000000..093dc98
--- /dev/null
+++ b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/data/PluginMessageListener.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2023 AuthMeVelocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package io.github._4drian3d.authmevelocity.velocity.listener.data;
+
+import com.google.common.io.ByteArrayDataInput;
+import com.google.inject.Inject;
+import com.velocitypowered.api.event.EventManager;
+import com.velocitypowered.api.event.EventTask;
+import com.velocitypowered.api.event.connection.PluginMessageEvent;
+import com.velocitypowered.api.proxy.Player;
+import com.velocitypowered.api.proxy.ProxyServer;
+import com.velocitypowered.api.proxy.ServerConnection;
+import com.velocitypowered.api.proxy.server.RegisteredServer;
+import io.github._4drian3d.authmevelocity.api.velocity.event.*;
+import io.github._4drian3d.authmevelocity.common.MessageType;
+import io.github._4drian3d.authmevelocity.common.configuration.ProxyConfiguration;
+import io.github._4drian3d.authmevelocity.velocity.AuthMeVelocityPlugin;
+import io.github._4drian3d.authmevelocity.velocity.listener.Listener;
+import io.github._4drian3d.authmevelocity.velocity.utils.AuthMeUtils;
+import io.github._4drian3d.authmevelocity.velocity.utils.Pair;
+import net.kyori.adventure.util.Index;
+import org.slf4j.Logger;
+
+import java.util.Locale;
+
+public final class PluginMessageListener implements Listener {
+ private static final Index TYPES = Index.create(MessageType.class, Enum::toString);
+ @Inject
+ private ProxyServer proxy;
+ @Inject
+ private EventManager eventManager;
+ @Inject
+ private Logger logger;
+ @Inject
+ private AuthMeVelocityPlugin plugin;
+
+ @Override
+ public void register() {
+ eventManager.register(plugin, PluginMessageEvent.class, this);
+ }
+
+ @Override
+ public EventTask executeAsync(final PluginMessageEvent event) {
+ return EventTask.async(() -> {
+ final boolean cancelled = !event.getResult().isAllowed()
+ || !(event.getSource() instanceof ServerConnection)
+ || !(event.getIdentifier().equals(AuthMeVelocityPlugin.MODERN_CHANNEL)
+ || event.getIdentifier().equals(AuthMeVelocityPlugin.LEGACY_CHANNEL));
+ if (cancelled) {
+ plugin.logDebug("PluginMessageEvent | Not allowed");
+ return;
+ }
+
+ final ServerConnection connection = (ServerConnection) event.getSource();
+
+ event.setResult(PluginMessageEvent.ForwardResult.handled());
+
+ final ByteArrayDataInput input = event.dataAsDataStream();
+ final String message = input.readUTF();
+ final MessageType type = TYPES.valueOrThrow(message.toUpperCase(Locale.ROOT));
+ final String name = input.readUTF();
+ final Player player = proxy.getPlayer(name).orElse(null);
+
+ switch (type) {
+ case LOGIN -> {
+ plugin.logDebug("PluginMessageEvent | Login type");
+ if (player != null && plugin.addPlayer(player)) {
+ eventManager.fireAndForget(new ProxyLoginEvent(player));
+ if (plugin.config().get().sendOnLogin().sendToServerOnLogin()) {
+ this.createServerConnectionRequest(player, connection);
+ }
+ plugin.logDebug("PluginMessageEvent | Player not null");
+ }
+ }
+ case LOGOUT -> {
+ plugin.logDebug("PluginMessageEvent | Logout type");
+ if (player != null && plugin.removePlayer(player)){
+ eventManager.fireAndForget(new ProxyLogoutEvent(player));
+ plugin.logDebug("PluginMessageEvent | Player not null");
+ }
+ }
+ case REGISTER -> {
+ plugin.logDebug("PluginMessageEvent | Register");
+ if (player != null) {
+ eventManager.fireAndForget(new ProxyRegisterEvent(player));
+ plugin.logDebug("PluginMessageEvent | Player not null");
+ }
+ }
+ case UNREGISTER -> {
+ plugin.logDebug("PluginMessageEvent | Unregister type");
+ if (player != null) {
+ plugin.logDebug("PluginMessageEvent | Player not null");
+ eventManager.fireAndForget(new ProxyUnregisterEvent(player));
+ }
+ }
+ case FORCE_UNREGISTER -> {
+ eventManager.fireAndForget(new ProxyForcedUnregisterEvent(player));
+ plugin.logDebug("PluginMessageEvent | Forced Unregister type");
+ }
+
+ }
+ });
+ }
+
+ private void createServerConnectionRequest(final Player player, final ServerConnection connection){
+ final RegisteredServer loginServer = player.getCurrentServer().orElse(connection).getServer();
+
+ final ProxyConfiguration config = plugin.config().get();
+
+ final Pair toSend = AuthMeUtils.serverToSend(
+ config.sendOnLogin().sendMode(), proxy, config.sendOnLogin().teleportServers(), config.advanced().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;
+ }
+
+ eventManager.fire(new PreSendOnLoginEvent(player, loginServer, toSend.object()))
+ .thenAccept(event -> {
+ if (!event.getResult().isAllowed()) {
+ return;
+ }
+ player.createConnectionRequest(event.getResult().getServer())
+ .connect()
+ .thenAcceptAsync(result -> {
+ if (!result.isSuccessful()) {
+ logger.info("Unable to connect the player {} to the server {}",
+ player.getUsername(),
+ result.getAttemptedConnection().getServerInfo().getName());
+ }
+ });
+ });
+ }
+}
diff --git a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/input/ChatListener.java b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/input/ChatListener.java
new file mode 100644
index 0000000..5d20f4a
--- /dev/null
+++ b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/input/ChatListener.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 AuthMeVelocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package io.github._4drian3d.authmevelocity.velocity.listener.input;
+
+import com.google.inject.Inject;
+import com.velocitypowered.api.event.EventManager;
+import com.velocitypowered.api.event.EventTask;
+import com.velocitypowered.api.event.PostOrder;
+import com.velocitypowered.api.event.player.PlayerChatEvent;
+import io.github._4drian3d.authmevelocity.velocity.AuthMeVelocityPlugin;
+import io.github._4drian3d.authmevelocity.velocity.listener.Listener;
+
+public final class ChatListener implements Listener {
+ @Inject
+ private AuthMeVelocityPlugin plugin;
+ @Inject
+ private EventManager eventManager;
+
+ @Override
+ public void register() {
+ eventManager.register(plugin, PlayerChatEvent.class, PostOrder.FIRST, this);
+ }
+
+ @Override
+ public EventTask executeAsync(final PlayerChatEvent event) {
+ return EventTask.withContinuation(continuation -> {
+ if (plugin.isLogged(event.getPlayer())) {
+ plugin.logDebug("PlayerChatEvent | Player is already logged");
+ continuation.resume();
+ return;
+ }
+
+ plugin.logDebug("PlayerChatEvent | Player is not logged");
+
+ event.setResult(PlayerChatEvent.ChatResult.denied());
+ continuation.resume();
+ });
+ }
+}
diff --git a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/input/CommandListener.java b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/input/CommandListener.java
new file mode 100644
index 0000000..2590428
--- /dev/null
+++ b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/input/CommandListener.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 AuthMeVelocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package io.github._4drian3d.authmevelocity.velocity.listener.input;
+
+import com.google.inject.Inject;
+import com.velocitypowered.api.event.EventManager;
+import com.velocitypowered.api.event.EventTask;
+import com.velocitypowered.api.event.PostOrder;
+import com.velocitypowered.api.event.command.CommandExecuteEvent;
+import com.velocitypowered.api.proxy.Player;
+import io.github._4drian3d.authmevelocity.velocity.AuthMeVelocityPlugin;
+import io.github._4drian3d.authmevelocity.velocity.listener.Listener;
+import io.github._4drian3d.authmevelocity.velocity.utils.AuthMeUtils;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+
+public final class CommandListener implements Listener {
+ @Inject
+ private EventManager eventManager;
+ @Inject
+ private AuthMeVelocityPlugin plugin;
+
+ @Override
+ public void register() {
+ eventManager.register(plugin, CommandExecuteEvent.class, PostOrder.FIRST, this);
+ }
+
+ @Override
+ public EventTask executeAsync(final CommandExecuteEvent event) {
+ return EventTask.withContinuation(continuation -> {
+ if (!(event.getCommandSource() instanceof final Player player)) {
+ plugin.logDebug("CommandExecuteEvent | CommandSource is not a player");
+ continuation.resume();
+ return;
+ }
+
+ if (plugin.isLogged(player)) {
+ plugin.logDebug("CommandExecuteEvent | Player is already logged");
+ continuation.resume();
+ return;
+ }
+
+ if (plugin.isInAuthServer(player)) {
+ plugin.logDebug("CommandExecuteEvent | Player is in Auth Server");
+ final String command = AuthMeUtils.getFirstArgument(event.getCommand());
+ if (!plugin.config().get().commands().allowedCommands().contains(command)) {
+ plugin.logDebug("CommandExecuteEvent | Player executed an blocked command");
+ sendBlockedMessage(player);
+ event.setResult(CommandExecuteEvent.CommandResult.denied());
+ }
+ } else {
+ plugin.logDebug("CommandExecuteEven | Player is not in auth server");
+ sendBlockedMessage(player);
+ event.setResult(CommandExecuteEvent.CommandResult.denied());
+ }
+ continuation.resume();
+ });
+ }
+
+ private void sendBlockedMessage(Player player){
+ String blockedMessage = plugin.config().get().commands().blockedCommandMessage();
+ if (!blockedMessage.isBlank()){
+ player.sendMessage(MiniMessage.miniMessage().deserialize(blockedMessage));
+ }
+ }
+}
diff --git a/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/input/TabCompleteListener.java b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/input/TabCompleteListener.java
new file mode 100644
index 0000000..f5e267f
--- /dev/null
+++ b/velocity/src/main/java/io/github/_4drian3d/authmevelocity/velocity/listener/input/TabCompleteListener.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 AuthMeVelocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package io.github._4drian3d.authmevelocity.velocity.listener.input;
+
+import com.google.inject.Inject;
+import com.velocitypowered.api.event.EventManager;
+import com.velocitypowered.api.event.EventTask;
+import com.velocitypowered.api.event.PostOrder;
+import com.velocitypowered.api.event.player.TabCompleteEvent;
+import io.github._4drian3d.authmevelocity.velocity.AuthMeVelocityPlugin;
+import io.github._4drian3d.authmevelocity.velocity.listener.Listener;
+
+public class TabCompleteListener implements Listener {
+ @Inject
+ private AuthMeVelocityPlugin plugin;
+ @Inject
+ private EventManager eventManager;
+
+ @Override
+ public void register() {
+ eventManager.register(plugin, TabCompleteEvent.class, PostOrder.FIRST, this);
+ }
+
+ @Override
+ public EventTask executeAsync(final TabCompleteEvent event) {
+ return EventTask.async(() -> {
+ if (plugin.isLogged(event.getPlayer())) {
+ plugin.logDebug("TabCompleteEvent | Player is already logged");
+ return;
+ }
+
+ final String command = event.getPartialMessage();
+ for (final String allowed : plugin.config().get().commands().allowedCommands()) {
+ if (allowed.startsWith(command)) {
+ return;
+ }
+ }
+
+ plugin.logDebug("TabCompleteEvent | Not allowed tab-completion");
+ event.getSuggestions().clear();
+ });
+ }
+}