Commit Graph

44 Commits

Author SHA1 Message Date
games647
a65a5f3020 Make ignore states more verbose in Velocity 2024-02-13 16:54:23 +01:00
games647
cd3cfef6d4 Do not encapsulate the task twice in Velocity 2024-02-13 16:54:22 +01:00
games647
dbf5ae2fae [Velocity] Fix plugin resuming event processing if login is not handled
This causes login timeouts if this plugin doesn't handle the login for
cases like:

* Anti-Bot is triggered
* Another plugin already denied the login

Fixes #1146
2024-01-23 13:59:49 +01:00
games647
159a6ed37c Add JavaDoc snippets and tiny reformats 2023-08-31 12:08:40 +02:00
games647
b48dfed709 Add NPE check on velocity for logins 2023-08-31 12:08:40 +02:00
xrh0905
31cbb2ff11 Add floodgate support
Based on: https://github.com/games647/FastLogin/pull/649

Solve hooks not found

Add defination of floodgateservice

Geyser API
2023-08-31 12:04:23 +02:00
games647
a182976207 Update license date 2023-04-13 12:00:07 +02:00
games647
477ec06d55 Encapsulate storage implementation 2023-04-12 11:30:07 +02:00
games647
e5d61101ae Typo fixes 2023-04-11 10:36:42 +02:00
games647
423bfa2275 Re-enable force checkstyle check 2022-07-11 13:00:15 +02:00
games647
752600f0e2 Fix code formatting according to checkstyle config 2022-07-11 12:14:31 +02:00
games647
7c8de84a34 Bump dependencies 2022-07-06 17:08:57 +02:00
games647
1c528fb9cb Clean up
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BungeeManager.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BungeeManager.java
index 49ff879..7149238 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BungeeManager.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BungeeManager.java
@@ -36,6 +36,7 @@ import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
@@ -62,7 +63,7 @@ public class BungeeManager {
     private final FastLoginBukkit plugin;
     private boolean enabled;

-    private final Set<UUID> firedJoinEvents = new HashSet<>();
+    private final Collection<UUID> firedJoinEvents = new HashSet<>();

     public BungeeManager(FastLoginBukkit plugin) {
         this.plugin = plugin;
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/command/CrackedCommand.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/command/CrackedCommand.java
index a6ac9b7..6153338 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/command/CrackedCommand.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/command/CrackedCommand.java
@@ -44,7 +44,7 @@ public class CrackedCommand extends ToggleCommand {
     @Override
     public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
         if (args.length == 0) {
-            onCrackedSelf(sender, command, args);
+            onCrackedSelf(sender);
         } else {
             onCrackedOther(sender, command, args);
         }
@@ -52,7 +52,7 @@ public class CrackedCommand extends ToggleCommand {
         return true;
     }

-    private void onCrackedSelf(CommandSender sender, Command cmd, String[] args) {
+    private void onCrackedSelf(CommandSender sender) {
         if (isConsole(sender)) {
             return;
         }
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/command/PremiumCommand.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/command/PremiumCommand.java
index 26b6d31..9f1ef98 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/command/PremiumCommand.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/command/PremiumCommand.java
@@ -51,7 +51,7 @@ public class PremiumCommand extends ToggleCommand {
     @Override
     public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
         if (args.length == 0) {
-            onPremiumSelf(sender, command, args);
+            onPremiumSelf(sender);
         } else {
             onPremiumOther(sender, command, args);
         }
@@ -59,7 +59,7 @@ public class PremiumCommand extends ToggleCommand {
         return true;
     }

-    private void onPremiumSelf(CommandSender sender, Command cmd, String[] args) {
+    private void onPremiumSelf(CommandSender sender) {
         if (isConsole(sender)) {
             return;
         }
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/event/BukkitFastLoginAutoLoginEvent.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/event/BukkitFastLoginAutoLoginEvent.java
index 8c61330..6412c6d 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/event/BukkitFastLoginAutoLoginEvent.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/event/BukkitFastLoginAutoLoginEvent.java
@@ -28,6 +28,7 @@ package com.github.games647.fastlogin.bukkit.event;
 import com.github.games647.fastlogin.core.StoredProfile;
 import com.github.games647.fastlogin.core.shared.LoginSession;
 import com.github.games647.fastlogin.core.shared.event.FastLoginAutoLoginEvent;
+
 import org.bukkit.event.Cancellable;
 import org.bukkit.event.Event;
 import org.bukkit.event.HandlerList;
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/event/BukkitFastLoginPreLoginEvent.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/event/BukkitFastLoginPreLoginEvent.java
index 6b2edfc..5bf6df9 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/event/BukkitFastLoginPreLoginEvent.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/event/BukkitFastLoginPreLoginEvent.java
@@ -28,6 +28,7 @@ package com.github.games647.fastlogin.bukkit.event;
 import com.github.games647.fastlogin.core.StoredProfile;
 import com.github.games647.fastlogin.core.shared.LoginSource;
 import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent;
+
 import org.bukkit.event.Event;
 import org.bukkit.event.HandlerList;
 import org.jetbrains.annotations.NotNull;
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/event/BukkitFastLoginPremiumToggleEvent.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/event/BukkitFastLoginPremiumToggleEvent.java
index 146efb0..0904826 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/event/BukkitFastLoginPremiumToggleEvent.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/event/BukkitFastLoginPremiumToggleEvent.java
@@ -27,6 +27,7 @@ package com.github.games647.fastlogin.bukkit.event;

 import com.github.games647.fastlogin.core.StoredProfile;
 import com.github.games647.fastlogin.core.shared.event.FastLoginPremiumToggleEvent;
+
 import org.bukkit.event.Event;
 import org.bukkit.event.HandlerList;
 import org.jetbrains.annotations.NotNull;
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hook/AuthMeHook.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hook/AuthMeHook.java
index fecfb73..45d5a5f 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hook/AuthMeHook.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hook/AuthMeHook.java
@@ -28,18 +28,20 @@ package com.github.games647.fastlogin.bukkit.hook;
 import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
 import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
 import com.github.games647.fastlogin.core.hooks.AuthPlugin;
+
 import fr.xephi.authme.api.v3.AuthMeApi;
 import fr.xephi.authme.events.RestoreSessionEvent;
 import fr.xephi.authme.process.Management;
 import fr.xephi.authme.process.register.executors.ApiPasswordRegisterParams;
 import fr.xephi.authme.process.register.executors.RegistrationMethod;
+
+import java.lang.reflect.Field;
+
 import org.bukkit.entity.Player;
 import org.bukkit.event.EventHandler;
 import org.bukkit.event.EventPriority;
 import org.bukkit.event.Listener;

-import java.lang.reflect.Field;
-
 /**
  * GitHub: <a href="https://github.com/Xephi/AuthMeReloaded/">...</a>
  * <p>
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/PaperCacheListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/PaperCacheListener.java
index e444ed9..44ff6ea 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/PaperCacheListener.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/PaperCacheListener.java
@@ -29,6 +29,7 @@ import com.destroystokyo.paper.profile.ProfileProperty;
 import com.github.games647.craftapi.model.skin.Textures;
 import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
 import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
+
 import org.bukkit.event.EventHandler;
 import org.bukkit.event.EventPriority;
 import org.bukkit.event.Listener;
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ManualNameChange.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ManualNameChange.java
index cdf3999..2a36e88 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ManualNameChange.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ManualNameChange.java
@@ -25,6 +25,7 @@
  */
 package com.github.games647.fastlogin.bukkit.listener.protocollib;

+import com.comphenix.protocol.ProtocolLibrary;
 import com.comphenix.protocol.events.PacketAdapter;
 import com.comphenix.protocol.events.PacketContainer;
 import com.comphenix.protocol.events.PacketEvent;
@@ -36,8 +37,6 @@ import org.geysermc.floodgate.api.FloodgateApi;

 import static com.comphenix.protocol.PacketType.Login.Client.START;

-import com.comphenix.protocol.ProtocolLibrary;
-
 /**
  * Manually inject Floodgate player name prefixes.
  * <br>
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/NameCheckTask.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/NameCheckTask.java
index 485c065..d3b38ea 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/NameCheckTask.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/NameCheckTask.java
@@ -49,7 +49,7 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco

     private final FastLoginBukkit plugin;
     private final PacketEvent packetEvent;
-    private final PublicKey publicKey;
+    private final PublicKey serverKey;

     private final Random random;

@@ -57,12 +57,12 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
     private final String username;

     public NameCheckTask(FastLoginBukkit plugin, Random random, Player player, PacketEvent packetEvent,
-                         String username, PublicKey publicKey) {
+                         String username, PublicKey serverKey) {
         super(plugin.getCore(), plugin.getCore().getAuthPluginHook(), plugin.getBedrockService());

         this.plugin = plugin;
         this.packetEvent = packetEvent;
-        this.publicKey = publicKey;
+        this.serverKey = serverKey;
         this.random = random;
         this.player = player;
         this.username = username;
@@ -71,9 +71,9 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
     @Override
     public void run() {
         try {
-            Optional<WrappedProfileKeyData> publicKey = packetEvent.getPacket().getOptionals(BukkitConverters.getWrappedPublicKeyDataConverter()).read(0);
+            Optional<WrappedProfileKeyData> clientKey = packetEvent.getPacket().getOptionals(BukkitConverters.getWrappedPublicKeyDataConverter()).read(0);

-            super.onLogin(username, new ProtocolLibLoginSource(player, random, publicKey.get(), this.publicKey));
+            super.onLogin(username, new ProtocolLibLoginSource(player, random, clientKey.get(), serverKey));
         } finally {
             ProtocolLibrary.getProtocolManager().getAsynchronousManager().signalPacketTransmission(packetEvent);
         }
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibListener.java
index 55a8f33..89d855d 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibListener.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibListener.java
@@ -127,7 +127,7 @@ public class ProtocolLibListener extends PacketAdapter {
         }
     }

-    private Boolean isFastLoginPacket(PacketEvent packetEvent) {
+    private boolean isFastLoginPacket(PacketEvent packetEvent) {
         return packetEvent.getPacket().getMeta(SOURCE_META_KEY)
                 .map(val -> val.equals(plugin.getName()))
                 .orElse(false);
@@ -146,7 +146,7 @@ public class ProtocolLibListener extends PacketAdapter {
             long salt = FuzzyReflection.getFieldValue(signatureData, Long.TYPE, true);
             byte[] signature = FuzzyReflection.getFieldValue(signatureData, byte[].class, true);

-            PublicKey publicKey = session.getClientPublicKey().getKey();
+            PublicKey publicKey = session.getClientPublicKey().key();
             try {
                 if (EncryptionUtil.verifySignedNonce(session.getVerifyToken(), publicKey, salt, signature)) {
                     packetEvent.getAsyncMarker().incrementProcessingDelay();
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibLoginSource.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibLoginSource.java
index d87b602..d4c1130 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibLoginSource.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibLoginSource.java
@@ -33,7 +33,6 @@ import com.comphenix.protocol.wrappers.WrappedChatComponent;
 import com.comphenix.protocol.wrappers.WrappedProfilePublicKey.WrappedProfileKeyData;
 import com.github.games647.fastlogin.core.shared.LoginSource;

-import java.lang.reflect.InvocationTargetException;
 import java.net.InetSocketAddress;
 import java.security.PublicKey;
 import java.util.Arrays;
@@ -64,7 +63,7 @@ class ProtocolLibLoginSource implements LoginSource {
     }

     @Override
-    public void enableOnlinemode() throws InvocationTargetException {
+    public void enableOnlinemode() {
         verifyToken = EncryptionUtil.generateVerifyToken(random);

         /*
@@ -92,7 +91,7 @@ class ProtocolLibLoginSource implements LoginSource {
     }

     @Override
-    public void kick(String message) throws InvocationTargetException {
+    public void kick(String message) {
         ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();

         PacketContainer kickPacket = new PacketContainer(DISCONNECT);
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/SkinApplyListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/SkinApplyListener.java
index 7d43835..3d4a807 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/SkinApplyListener.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/SkinApplyListener.java
@@ -34,6 +34,9 @@ import com.comphenix.protocol.wrappers.WrappedSignedProperty;
 import com.github.games647.craftapi.model.skin.Textures;
 import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
 import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
+
+import java.lang.reflect.InvocationTargetException;
+
 import org.bukkit.entity.Player;
 import org.bukkit.event.EventHandler;
 import org.bukkit.event.EventPriority;
@@ -41,8 +44,6 @@ import org.bukkit.event.Listener;
 import org.bukkit.event.player.PlayerLoginEvent;
 import org.bukkit.event.player.PlayerLoginEvent.Result;

-import java.lang.reflect.InvocationTargetException;
-
 public class SkinApplyListener implements Listener {

     private static final Class<?> GAME_PROFILE = MinecraftReflection.getGameProfileClass();
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/task/FloodgateAuthTask.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/task/FloodgateAuthTask.java
index acb3597..ef9fed0 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/task/FloodgateAuthTask.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/task/FloodgateAuthTask.java
@@ -25,6 +25,11 @@
  */
 package com.github.games647.fastlogin.bukkit.task;

+import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
+import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
+import com.github.games647.fastlogin.core.shared.FastLoginCore;
+import com.github.games647.fastlogin.core.shared.FloodgateManagement;
+
 import java.net.InetSocketAddress;
 import java.util.UUID;

@@ -33,11 +38,6 @@ import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 import org.geysermc.floodgate.api.player.FloodgatePlayer;

-import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
-import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
-import com.github.games647.fastlogin.core.shared.FastLoginCore;
-import com.github.games647.fastlogin.core.shared.FloodgateManagement;
-
 public class FloodgateAuthTask extends FloodgateManagement<Player, CommandSender, BukkitLoginSession, FastLoginBukkit> {

     public FloodgateAuthTask(FastLoginCore<Player, CommandSender, FastLoginBukkit> core, Player player, FloodgatePlayer floodgatePlayer) {
diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/event/BungeeFastLoginAutoLoginEvent.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/event/BungeeFastLoginAutoLoginEvent.java
index 365a198..6503ff9 100644
--- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/event/BungeeFastLoginAutoLoginEvent.java
+++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/event/BungeeFastLoginAutoLoginEvent.java
@@ -28,6 +28,7 @@ package com.github.games647.fastlogin.bungee.event;
 import com.github.games647.fastlogin.core.StoredProfile;
 import com.github.games647.fastlogin.core.shared.LoginSession;
 import com.github.games647.fastlogin.core.shared.event.FastLoginAutoLoginEvent;
+
 import net.md_5.bungee.api.plugin.Cancellable;
 import net.md_5.bungee.api.plugin.Event;

diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/event/BungeeFastLoginPreLoginEvent.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/event/BungeeFastLoginPreLoginEvent.java
index b350763..2128cab 100644
--- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/event/BungeeFastLoginPreLoginEvent.java
+++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/event/BungeeFastLoginPreLoginEvent.java
@@ -28,6 +28,7 @@ package com.github.games647.fastlogin.bungee.event;
 import com.github.games647.fastlogin.core.StoredProfile;
 import com.github.games647.fastlogin.core.shared.LoginSource;
 import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent;
+
 import net.md_5.bungee.api.plugin.Event;

 public class BungeeFastLoginPreLoginEvent extends Event implements FastLoginPreLoginEvent {
diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/task/AsyncToggleMessage.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/task/AsyncToggleMessage.java
index 98c384c..2965855 100644
--- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/task/AsyncToggleMessage.java
+++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/task/AsyncToggleMessage.java
@@ -29,8 +29,8 @@ import com.github.games647.fastlogin.bungee.FastLoginBungee;
 import com.github.games647.fastlogin.bungee.event.BungeeFastLoginPremiumToggleEvent;
 import com.github.games647.fastlogin.core.StoredProfile;
 import com.github.games647.fastlogin.core.shared.FastLoginCore;
-
 import com.github.games647.fastlogin.core.shared.event.FastLoginPremiumToggleEvent.PremiumToggleReason;
+
 import net.md_5.bungee.api.CommandSender;
 import net.md_5.bungee.api.ProxyServer;
 import net.md_5.bungee.api.chat.TextComponent;
diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/task/FloodgateAuthTask.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/task/FloodgateAuthTask.java
index 72719cf..5133198 100644
--- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/task/FloodgateAuthTask.java
+++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/task/FloodgateAuthTask.java
@@ -25,19 +25,19 @@
  */
 package com.github.games647.fastlogin.bungee.task;

+import com.github.games647.fastlogin.bungee.BungeeLoginSession;
+import com.github.games647.fastlogin.bungee.FastLoginBungee;
+import com.github.games647.fastlogin.core.shared.FastLoginCore;
+import com.github.games647.fastlogin.core.shared.FloodgateManagement;
+
 import java.net.InetSocketAddress;
 import java.util.UUID;

-import org.geysermc.floodgate.api.player.FloodgatePlayer;
-
 import net.md_5.bungee.api.CommandSender;
 import net.md_5.bungee.api.connection.ProxiedPlayer;
 import net.md_5.bungee.api.connection.Server;

-import com.github.games647.fastlogin.bungee.BungeeLoginSession;
-import com.github.games647.fastlogin.bungee.FastLoginBungee;
-import com.github.games647.fastlogin.core.shared.FastLoginCore;
-import com.github.games647.fastlogin.core.shared.FloodgateManagement;
+import org.geysermc.floodgate.api.player.FloodgatePlayer;

 public class FloodgateAuthTask
         extends FloodgateManagement<ProxiedPlayer, CommandSender, BungeeLoginSession, FastLoginBungee> {
diff --git a/core/src/main/java/com/github/games647/fastlogin/core/hooks/DefaultPasswordGenerator.java b/core/src/main/java/com/github/games647/fastlogin/core/hooks/DefaultPasswordGenerator.java
index b6802a6..9caadef 100644
--- a/core/src/main/java/com/github/games647/fastlogin/core/hooks/DefaultPasswordGenerator.java
+++ b/core/src/main/java/com/github/games647/fastlogin/core/hooks/DefaultPasswordGenerator.java
@@ -26,7 +26,7 @@
 package com.github.games647.fastlogin.core.hooks;

 import java.security.SecureRandom;
-import java.util.Random;
+import java.util.random.RandomGenerator;
 import java.util.stream.IntStream;

 public class DefaultPasswordGenerator<P> implements PasswordGenerator<P> {
@@ -35,7 +35,7 @@ public class DefaultPasswordGenerator<P> implements PasswordGenerator<P> {
     private static final char[] PASSWORD_CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
             .toCharArray();

-    private final Random random = new SecureRandom();
+    private final RandomGenerator random = new SecureRandom();

     @Override
     public String getRandomPassword(P player) {
diff --git a/core/src/main/java/com/github/games647/fastlogin/core/hooks/bedrock/FloodgateService.java b/core/src/main/java/com/github/games647/fastlogin/core/hooks/bedrock/FloodgateService.java
index 7e6a1c2..1b555f1 100644
--- a/core/src/main/java/com/github/games647/fastlogin/core/hooks/bedrock/FloodgateService.java
+++ b/core/src/main/java/com/github/games647/fastlogin/core/hooks/bedrock/FloodgateService.java
@@ -54,14 +54,13 @@ public class FloodgateService extends BedrockService<FloodgatePlayer> {
      * <li>autoLoginFloodgate
      * <li>autoRegisterFloodgate
      * </ul>
-     * </p>
      *
      * @param key the key of the entry in config.yml
      * @return <b>true</b> if the entry's value is "true", "false", or "linked"
      */
     public boolean isValidFloodgateConfigString(String key) {
         String value = core.getConfig().get(key).toString().toLowerCase(Locale.ENGLISH);
-        if (!value.equals("true") && !value.equals("linked") && !value.equals("false") && !value.equals("no-conflict")) {
+        if (!"true".equals(value) && !"linked".equals(value) && !"false".equals(value) && !"no-conflict".equals(value)) {
             core.getPlugin().getLog().error("Invalid value detected for {} in FastLogin/config.yml.", key);
             return false;
         }
@@ -87,7 +86,7 @@ public class FloodgateService extends BedrockService<FloodgatePlayer> {
         } else {
             core.getPlugin().getLog().info("Skipping name conflict checking for player {}", username);
         }
-
+
         //Floodgate users don't need Java specific checks
         return true;
     }
@@ -98,7 +97,7 @@ public class FloodgateService extends BedrockService<FloodgatePlayer> {
      * username can be found
      * <br>
      * <i>Falls back to non-prefixed name checks, if ProtocolLib is installed</i>
-     *
+     *
      * @param prefixedUsername the name of the player with the prefix appended
      * @return FloodgatePlayer if found, null otherwise
      */
diff --git a/core/src/main/java/com/github/games647/fastlogin/core/shared/ForceLoginManagement.java b/core/src/main/java/com/github/games647/fastlogin/core/shared/ForceLoginManagement.java
index c8c7bea..873a855 100644
--- a/core/src/main/java/com/github/games647/fastlogin/core/shared/ForceLoginManagement.java
+++ b/core/src/main/java/com/github/games647/fastlogin/core/shared/ForceLoginManagement.java
@@ -25,10 +25,10 @@
  */
 package com.github.games647.fastlogin.core.shared;

-import com.github.games647.fastlogin.core.storage.SQLStorage;
 import com.github.games647.fastlogin.core.StoredProfile;
 import com.github.games647.fastlogin.core.hooks.AuthPlugin;
 import com.github.games647.fastlogin.core.shared.event.FastLoginAutoLoginEvent;
+import com.github.games647.fastlogin.core.storage.SQLStorage;

 public abstract class ForceLoginManagement<P extends C, C, L extends LoginSession, T extends PlatformPlugin<C>>
         implements Runnable {
diff --git a/core/src/test/java/com/github/games647/fastlogin/core/TickingRateLimiterTest.java b/core/src/test/java/com/github/games647/fastlogin/core/TickingRateLimiterTest.java
index 3f753cd..34f196a 100644
--- a/core/src/test/java/com/github/games647/fastlogin/core/TickingRateLimiterTest.java
+++ b/core/src/test/java/com/github/games647/fastlogin/core/TickingRateLimiterTest.java
@@ -32,8 +32,8 @@ import java.util.concurrent.TimeUnit;

 import org.junit.Test;

-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;

 public class TickingRateLimiterTest {

@@ -43,7 +43,7 @@ public class TickingRateLimiterTest {
      * Always expired
      */
     @Test
-    public void allowExpire() throws InterruptedException {
+    public void allowExpire() {
         int size = 3;

         FakeTicker ticker = new FakeTicker(5_000_000L);
@@ -51,17 +51,17 @@ public class TickingRateLimiterTest {
         // run twice the size to fill it first and then test it
         TickingRateLimiter rateLimiter = new TickingRateLimiter(ticker, size, 0);
         for (int i = 0; i < size; i++) {
-            assertTrue("Filling up", rateLimiter.tryAcquire());
+            assertThat("Filling up", rateLimiter.tryAcquire(), is(true));
         }

         for (int i = 0; i < size; i++) {
             ticker.add(Duration.ofSeconds(1));
-            assertTrue("Should be expired", rateLimiter.tryAcquire());
+            assertThat("Should be expired", rateLimiter.tryAcquire(), is(true));
         }
     }

     @Test
-    public void allowExpireNegative() throws InterruptedException {
+    public void allowExpireNegative() {
         int size = 3;

         FakeTicker ticker = new FakeTicker(-5_000_000L);
@@ -69,12 +69,12 @@ public class TickingRateLimiterTest {
         // run twice the size to fill it first and then test it
         TickingRateLimiter rateLimiter = new TickingRateLimiter(ticker, size, 0);
         for (int i = 0; i < size; i++) {
-            assertTrue("Filling up", rateLimiter.tryAcquire());
+            assertThat("Filling up", rateLimiter.tryAcquire(), is(true));
         }

         for (int i = 0; i < size; i++) {
             ticker.add(Duration.ofSeconds(1));
-            assertTrue("Should be expired", rateLimiter.tryAcquire());
+            assertThat("Should be expired", rateLimiter.tryAcquire(), is(true));
         }
     }

@@ -90,10 +90,10 @@ public class TickingRateLimiterTest {
         // fill the size
         TickingRateLimiter rateLimiter = new TickingRateLimiter(ticker, size, TimeUnit.SECONDS.toMillis(30));
         for (int i = 0; i < size; i++) {
-            assertTrue("Filling up", rateLimiter.tryAcquire());
+            assertThat("Filling up", rateLimiter.tryAcquire(), is(true));
         }

-        assertFalse("Should be full and no entry should be expired", rateLimiter.tryAcquire());
+        assertThat("Should be full and no entry should be expired", rateLimiter.tryAcquire(), is(false));
     }

     /**
@@ -108,51 +108,51 @@ public class TickingRateLimiterTest {
         // fill the size
         TickingRateLimiter rateLimiter = new TickingRateLimiter(ticker, size, TimeUnit.SECONDS.toMillis(30));
         for (int i = 0; i < size; i++) {
-            assertTrue("Filling up", rateLimiter.tryAcquire());
+            assertThat("Filling up", rateLimiter.tryAcquire(), is(true));
         }

-        assertFalse("Should be full and no entry should be expired", rateLimiter.tryAcquire());
+        assertThat("Should be full and no entry should be expired", rateLimiter.tryAcquire(), is(false));
     }

     /**
      * Blocked attempts shouldn't replace existing ones.
      */
     @Test
-    public void blockedNotAdded() throws InterruptedException {
+    public void blockedNotAdded() {
         FakeTicker ticker = new FakeTicker(5_000_000L);

         // fill the size - 100ms should be reasonable high
         TickingRateLimiter rateLimiter = new TickingRateLimiter(ticker, 1, 100);
-        assertTrue("Filling up", rateLimiter.tryAcquire());
+        assertThat("Filling up", rateLimiter.tryAcquire(), is(true));

         ticker.add(Duration.ofMillis(50));

         // still is full - should fail
-        assertFalse("Expired too early", rateLimiter.tryAcquire());
+        assertThat("Expired too early", rateLimiter.tryAcquire(), is(false));

         // wait the remaining time and add a threshold, because
         ticker.add(Duration.ofMillis(50));
-        assertTrue("Request not released", rateLimiter.tryAcquire());
+        assertThat("Request not released", rateLimiter.tryAcquire(), is(true));
     }

     /**
      * Blocked attempts shouldn't replace existing ones.
      */
     @Test
-    public void blockedNotAddedNegative() throws InterruptedException {
+    public void blockedNotAddedNegative() {
         FakeTicker ticker = new FakeTicker(-5_000_000L);

         // fill the size - 100ms should be reasonable high
         TickingRateLimiter rateLimiter = new TickingRateLimiter(ticker, 1, 100);
-        assertTrue("Filling up", rateLimiter.tryAcquire());
+        assertThat("Filling up", rateLimiter.tryAcquire(), is(true));

         ticker.add(Duration.ofMillis(50));

         // still is full - should fail
-        assertFalse("Expired too early", rateLimiter.tryAcquire());
+        assertThat("Expired too early", rateLimiter.tryAcquire(), is(false));

         // wait the remaining time and add a threshold, because
         ticker.add(Duration.ofMillis(50));
-        assertTrue("Request not released", rateLimiter.tryAcquire());
+        assertThat("Request not released", rateLimiter.tryAcquire(), is(true));
     }
 }
diff --git a/velocity/src/main/java/com/github/games647/fastlogin/velocity/listener/ConnectListener.java b/velocity/src/main/java/com/github/games647/fastlogin/velocity/listener/ConnectListener.java
index 33c8c31..902fb03 100644
--- a/velocity/src/main/java/com/github/games647/fastlogin/velocity/listener/ConnectListener.java
+++ b/velocity/src/main/java/com/github/games647/fastlogin/velocity/listener/ConnectListener.java
@@ -45,9 +45,11 @@ import com.velocitypowered.api.proxy.InboundConnection;
 import com.velocitypowered.api.proxy.Player;
 import com.velocitypowered.api.proxy.server.RegisteredServer;
 import com.velocitypowered.api.util.GameProfile;
+import com.velocitypowered.api.util.GameProfile.Property;

 import java.net.InetSocketAddress;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
@@ -121,7 +123,7 @@ public class ConnectListener {
         }
     }

-    private List<GameProfile.Property> removeSkin(List<GameProfile.Property> oldProperties) {
+    private List<GameProfile.Property> removeSkin(Collection<Property> oldProperties) {
         List<GameProfile.Property> newProperties = new ArrayList<>(oldProperties.size() - 1);
         for (GameProfile.Property property : oldProperties) {
             if (!"textures".equals(property.getName()))
diff --git a/velocity/src/main/java/com/github/games647/fastlogin/velocity/task/AsyncToggleMessage.java b/velocity/src/main/java/com/github/games647/fastlogin/velocity/task/AsyncToggleMessage.java
index 12444fc..8dc7d1c 100644
--- a/velocity/src/main/java/com/github/games647/fastlogin/velocity/task/AsyncToggleMessage.java
+++ b/velocity/src/main/java/com/github/games647/fastlogin/velocity/task/AsyncToggleMessage.java
@@ -32,6 +32,7 @@ import com.github.games647.fastlogin.velocity.FastLoginVelocity;
 import com.github.games647.fastlogin.velocity.event.VelocityFastLoginPremiumToggleEvent;
 import com.velocitypowered.api.command.CommandSource;
 import com.velocitypowered.api.proxy.Player;
+
 import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;

 public class AsyncToggleMessage implements Runnable {
2022-06-28 18:34:23 +02:00
games647
b041a89209 Typo fixes 2022-06-28 18:34:23 +02:00
games647
7cab5993b7 Add license
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java
index ab4ceed..9c2fa3a 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java
@@ -114,9 +114,9 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
             }

             if (pluginManager.isPluginEnabled("ProtocolSupport")) {
-                pluginManager.registerEvents(new ProtocolSupportListener(this, core.getRateLimiter()), this);
+                pluginManager.registerEvents(new ProtocolSupportListener(this, core.getAntiBot()), this);
             } else if (pluginManager.isPluginEnabled("ProtocolLib")) {
-                ProtocolLibListener.register(this, core.getRateLimiter());
+                ProtocolLibListener.register(this, core.getAntiBot());

                 if (isPluginInstalled("floodgate")) {
                     if (getConfig().getBoolean("floodgatePrefixWorkaround")){
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibListener.java
index 8b3d601..3c161b7 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibListener.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibListener.java
@@ -31,8 +31,10 @@ import com.comphenix.protocol.events.PacketAdapter;
 import com.comphenix.protocol.events.PacketContainer;
 import com.comphenix.protocol.events.PacketEvent;
 import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
-import com.github.games647.fastlogin.core.RateLimiter;
+import com.github.games647.fastlogin.core.antibot.AntiBotService;
+import com.github.games647.fastlogin.core.antibot.AntiBotService.Action;

+import java.net.InetSocketAddress;
 import java.security.KeyPair;
 import java.security.SecureRandom;

@@ -50,9 +52,9 @@ public class ProtocolLibListener extends PacketAdapter {
     //just create a new once on plugin enable. This used for verify token generation
     private final SecureRandom random = new SecureRandom();
     private final KeyPair keyPair = EncryptionUtil.generateKeyPair();
-    private final RateLimiter rateLimiter;
+    private final AntiBotService antiBotService;

-    public ProtocolLibListener(FastLoginBukkit plugin, RateLimiter rateLimiter) {
+    public ProtocolLibListener(FastLoginBukkit plugin, AntiBotService antiBotService) {
         //run async in order to not block the server, because we are making api calls to Mojang
         super(params()
                 .plugin(plugin)
@@ -60,15 +62,15 @@ public class ProtocolLibListener extends PacketAdapter {
                 .optionAsync());

         this.plugin = plugin;
-        this.rateLimiter = rateLimiter;
+        this.antiBotService = antiBotService;
     }

-    public static void register(FastLoginBukkit plugin, RateLimiter rateLimiter) {
+    public static void register(FastLoginBukkit plugin, AntiBotService antiBotService) {
         // they will be created with a static builder, because otherwise it will throw a NoClassDefFoundError
         // TODO: make synchronous processing, but do web or database requests async
         ProtocolLibrary.getProtocolManager()
                 .getAsynchronousManager()
-                .registerAsyncHandler(new ProtocolLibListener(plugin, rateLimiter))
+                .registerAsyncHandler(new ProtocolLibListener(plugin, antiBotService))
                 .start();
     }

@@ -88,12 +90,26 @@ public class ProtocolLibListener extends PacketAdapter {
         Player sender = packetEvent.getPlayer();
         PacketType packetType = packetEvent.getPacketType();
         if (packetType == START) {
-            if (!rateLimiter.tryAcquire()) {
-                plugin.getLog().warn("Simple Anti-Bot join limit - Ignoring {}", sender);
-                return;
+            PacketContainer packet = packetEvent.getPacket();
+
+            InetSocketAddress address = sender.getAddress();
+            String username = packet.getGameProfiles().read(0).getName();
+
+            Action action = antiBotService.onIncomingConnection(address, username);
+            switch (action) {
+                case Ignore:
+                    // just ignore
+                    return;
+                case Block:
+                    String message = plugin.getCore().getMessage("kick-antibot");
+                    sender.kickPlayer(message);
+                    break;
+                case Continue:
+                default:
+                    //player.getName() won't work at this state
+                    onLogin(packetEvent, sender, username);
+                    break;
             }
-
-            onLogin(packetEvent, sender);
         } else {
             onEncryptionBegin(packetEvent, sender);
         }
@@ -113,18 +129,13 @@ public class ProtocolLibListener extends PacketAdapter {
         plugin.getScheduler().runAsync(verifyTask);
     }

-    private void onLogin(PacketEvent packetEvent, Player player) {
+    private void onLogin(PacketEvent packetEvent, Player player, String username) {
         //this includes ip:port. Should be unique for an incoming login request with a timeout of 2 minutes
         String sessionKey = player.getAddress().toString();

         //remove old data every time on a new login in order to keep the session only for one person
         plugin.removeSession(player.getAddress());

-        //player.getName() won't work at this state
-        PacketContainer packet = packetEvent.getPacket();
-
-        String username = packet.getGameProfiles().read(0).getName();
-
         if (packetEvent.getPacket().getMeta("original_name").isPresent()) {
             //username has been injected by ManualNameChange.java
             username = (String) packetEvent.getPacket().getMeta("original_name").get();
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolSupportListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolSupportListener.java
index 608078c..ce84824 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolSupportListener.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolSupportListener.java
@@ -29,8 +29,9 @@ import com.github.games647.craftapi.UUIDAdapter;
 import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
 import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
 import com.github.games647.fastlogin.bukkit.event.BukkitFastLoginPreLoginEvent;
-import com.github.games647.fastlogin.core.RateLimiter;
 import com.github.games647.fastlogin.core.StoredProfile;
+import com.github.games647.fastlogin.core.antibot.AntiBotService;
+import com.github.games647.fastlogin.core.antibot.AntiBotService.Action;
 import com.github.games647.fastlogin.core.shared.JoinManagement;
 import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent;

@@ -49,13 +50,13 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
         implements Listener {

     private final FastLoginBukkit plugin;
-    private final RateLimiter rateLimiter;
+    private final AntiBotService antiBotService;

-    public ProtocolSupportListener(FastLoginBukkit plugin, RateLimiter rateLimiter) {
+    public ProtocolSupportListener(FastLoginBukkit plugin, AntiBotService antiBotService) {
         super(plugin.getCore(), plugin.getCore().getAuthPluginHook(), plugin.getBedrockService());

         this.plugin = plugin;
-        this.rateLimiter = rateLimiter;
+        this.antiBotService = antiBotService;
     }

     @EventHandler
@@ -64,19 +65,28 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
             return;
         }

-        if (!rateLimiter.tryAcquire()) {
-            plugin.getLog().warn("Simple Anti-Bot join limit - Ignoring {}", loginStartEvent.getConnection());
-            return;
-        }
-
         String username = loginStartEvent.getConnection().getProfile().getName();
         InetSocketAddress address = loginStartEvent.getAddress();
-
-        //remove old data every time on a new login in order to keep the session only for one person
-        plugin.removeSession(address);
-
-        ProtocolLoginSource source = new ProtocolLoginSource(loginStartEvent);
-        super.onLogin(username, source);
+        plugin.getLog().info("Incoming login request for {} from {}", username, address);
+
+        Action action = antiBotService.onIncomingConnection(address, username);
+        switch (action) {
+            case Ignore:
+                // just ignore
+                return;
+            case Block:
+                String message = plugin.getCore().getMessage("kick-antibot");
+                loginStartEvent.denyLogin(message);
+                break;
+            case Continue:
+            default:
+                //remove old data every time on a new login in order to keep the session only for one person
+                plugin.removeSession(address);
+
+                ProtocolLoginSource source = new ProtocolLoginSource(loginStartEvent);
+                super.onLogin(username, source);
+                break;
+        }
     }

     @EventHandler
diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/ConnectListener.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/ConnectListener.java
index a8c894d..ddd7e97 100644
--- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/ConnectListener.java
+++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/ConnectListener.java
@@ -32,7 +32,8 @@ import com.github.games647.fastlogin.bungee.task.AsyncPremiumCheck;
 import com.github.games647.fastlogin.bungee.task.FloodgateAuthTask;
 import com.github.games647.fastlogin.bungee.task.ForceLoginTask;
 import com.github.games647.fastlogin.core.StoredProfile;
-import com.github.games647.fastlogin.core.antibot.RateLimiter;
+import com.github.games647.fastlogin.core.antibot.AntiBotService;
+import com.github.games647.fastlogin.core.antibot.AntiBotService.Action;
 import com.github.games647.fastlogin.core.hooks.bedrock.FloodgateService;
 import com.github.games647.fastlogin.core.shared.LoginSession;
 import com.google.common.base.Throwables;
@@ -41,8 +42,10 @@ import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.reflect.Field;
+import java.net.InetSocketAddress;
 import java.util.UUID;

+import net.md_5.bungee.api.chat.TextComponent;
 import net.md_5.bungee.api.connection.PendingConnection;
 import net.md_5.bungee.api.connection.ProxiedPlayer;
 import net.md_5.bungee.api.connection.Server;
@@ -92,12 +95,12 @@ public class ConnectListener implements Listener {
     }

     private final FastLoginBungee plugin;
-    private final RateLimiter rateLimiter;
+    private final AntiBotService antiBotService;
     private final Property[] emptyProperties = {};

-    public ConnectListener(FastLoginBungee plugin, RateLimiter rateLimiter) {
+    public ConnectListener(FastLoginBungee plugin, AntiBotService antiBotService) {
         this.plugin = plugin;
-        this.rateLimiter = rateLimiter;
+        this.antiBotService = antiBotService;
     }

     @EventHandler
@@ -107,17 +110,28 @@ public class ConnectListener implements Listener {
             return;
         }

-        if (!rateLimiter.tryAcquire()) {
-            plugin.getLog().warn("Simple Anti-Bot join limit - Ignoring {}", connection);
-            return;
-        }
-
+        InetSocketAddress address = preLoginEvent.getConnection().getAddress();
         String username = connection.getName();
+
         plugin.getLog().info("Incoming login request for {} from {}", username, connection.getSocketAddress());

-        preLoginEvent.registerIntent(plugin);
-        Runnable asyncPremiumCheck = new AsyncPremiumCheck(plugin, preLoginEvent, connection, username);
-        plugin.getScheduler().runAsync(asyncPremiumCheck);
+        Action action = antiBotService.onIncomingConnection(address, username);
+        switch (action) {
+            case Ignore:
+                // just ignore
+                return;
+            case Block:
+                String message = plugin.getCore().getMessage("kick-antibot");
+                preLoginEvent.setCancelReason(TextComponent.fromLegacyText(message));
+                preLoginEvent.setCancelled(true);
+                break;
+            case Continue:
+            default:
+                preLoginEvent.registerIntent(plugin);
+                Runnable asyncPremiumCheck = new AsyncPremiumCheck(plugin, preLoginEvent, connection, username);
+                plugin.getScheduler().runAsync(asyncPremiumCheck);
+                break;
+        }
     }

     @EventHandler(priority = EventPriority.LOWEST)
@@ -140,7 +154,7 @@ public class ConnectListener implements Listener {
             StoredProfile playerProfile = session.getProfile();
             playerProfile.setId(verifiedUUID);

-            // bungeecord will do this automatically so override it on disabled option
+            // BungeeCord will do this automatically so override it on disabled option
             if (uniqueIdSetter != null) {
                 InitialHandler initialHandler = (InitialHandler) connection;

diff --git a/core/src/main/java/com/github/games647/fastlogin/core/mojang/MojangApiConnector.java b/core/src/main/java/com/github/games647/fastlogin/core/antibot/AntiBotService.java
similarity index 57%
rename from core/src/main/java/com/github/games647/fastlogin/core/mojang/MojangApiConnector.java
rename to core/src/main/java/com/github/games647/fastlogin/core/antibot/AntiBotService.java
index 4321d6f..2848335 100644
--- a/core/src/main/java/com/github/games647/fastlogin/core/mojang/MojangApiConnector.java
+++ b/core/src/main/java/com/github/games647/fastlogin/core/antibot/AntiBotService.java
@@ -23,3 +23,40 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
+package com.github.games647.fastlogin.core.antibot;
+
+import java.net.InetSocketAddress;
+
+import org.slf4j.Logger;
+
+public class AntiBotService {
+
+    private final Logger logger;
+
+    private final RateLimiter rateLimiter;
+    private final Action limitReachedAction;
+
+    public AntiBotService(Logger logger, RateLimiter rateLimiter, Action limitReachedAction) {
+        this.logger = logger;
+
+        this.rateLimiter = rateLimiter;
+        this.limitReachedAction = limitReachedAction;
+    }
+
+    public Action onIncomingConnection(InetSocketAddress clientAddress, String username) {
+        if (!rateLimiter.tryAcquire()) {
+            logger.warn("Anti-Bot join limit - Ignoring {}", clientAddress);
+            return limitReachedAction;
+        }
+
+        return Action.Continue;
+    }
+
+    public enum Action {
+        Ignore,
+
+        Block,
+
+        Continue;
+    }
+}
diff --git a/core/src/main/java/com/github/games647/fastlogin/core/mojang/ProxyAgnosticMojangResolver.java b/core/src/main/java/com/github/games647/fastlogin/core/antibot/ProxyAgnosticMojangResolver.java
similarity index 100%
rename from core/src/main/java/com/github/games647/fastlogin/core/mojang/ProxyAgnosticMojangResolver.java
rename to core/src/main/java/com/github/games647/fastlogin/core/antibot/ProxyAgnosticMojangResolver.java
diff --git a/core/src/main/java/com/github/games647/fastlogin/core/RateLimiter.java b/core/src/main/java/com/github/games647/fastlogin/core/antibot/RateLimiter.java
similarity index 96%
rename from core/src/main/java/com/github/games647/fastlogin/core/RateLimiter.java
rename to core/src/main/java/com/github/games647/fastlogin/core/antibot/RateLimiter.java
index 3ec2f75..b791ca5 100644
--- a/core/src/main/java/com/github/games647/fastlogin/core/RateLimiter.java
+++ b/core/src/main/java/com/github/games647/fastlogin/core/antibot/RateLimiter.java
@@ -23,7 +23,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-package com.github.games647.fastlogin.core;
+package com.github.games647.fastlogin.core.antibot;

 @FunctionalInterface
 public interface RateLimiter {
diff --git a/core/src/main/java/com/github/games647/fastlogin/core/TickingRateLimiter.java b/core/src/main/java/com/github/games647/fastlogin/core/antibot/TickingRateLimiter.java
similarity index 98%
rename from core/src/main/java/com/github/games647/fastlogin/core/TickingRateLimiter.java
rename to core/src/main/java/com/github/games647/fastlogin/core/antibot/TickingRateLimiter.java
index 6064229..ced7da1 100644
--- a/core/src/main/java/com/github/games647/fastlogin/core/TickingRateLimiter.java
+++ b/core/src/main/java/com/github/games647/fastlogin/core/antibot/TickingRateLimiter.java
@@ -23,7 +23,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-package com.github.games647.fastlogin.core;
+package com.github.games647.fastlogin.core.antibot;

 import com.google.common.base.Ticker;

diff --git a/core/src/main/java/com/github/games647/fastlogin/core/mojang/UUIDTypeAdapter.java b/core/src/main/java/com/github/games647/fastlogin/core/mojang/UUIDTypeAdapter.java
deleted file mode 100644
index 4321d6f..0000000
--- a/core/src/main/java/com/github/games647/fastlogin/core/mojang/UUIDTypeAdapter.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * SPDX-License-Identifier: MIT
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2015-2022 games647 and contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
diff --git a/core/src/main/java/com/github/games647/fastlogin/core/shared/FastLoginCore.java b/core/src/main/java/com/github/games647/fastlogin/core/shared/FastLoginCore.java
index 9e2a49a..474a8e2 100644
--- a/core/src/main/java/com/github/games647/fastlogin/core/shared/FastLoginCore.java
+++ b/core/src/main/java/com/github/games647/fastlogin/core/shared/FastLoginCore.java
@@ -28,8 +28,10 @@ package com.github.games647.fastlogin.core.shared;
 import com.github.games647.craftapi.resolver.MojangResolver;
 import com.github.games647.craftapi.resolver.http.RotatingProxySelector;
 import com.github.games647.fastlogin.core.CommonUtil;
-import com.github.games647.fastlogin.core.RateLimiter;
-import com.github.games647.fastlogin.core.TickingRateLimiter;
+import com.github.games647.fastlogin.core.antibot.AntiBotService;
+import com.github.games647.fastlogin.core.antibot.AntiBotService.Action;
+import com.github.games647.fastlogin.core.antibot.RateLimiter;
+import com.github.games647.fastlogin.core.antibot.TickingRateLimiter;
 import com.github.games647.fastlogin.core.hooks.AuthPlugin;
 import com.github.games647.fastlogin.core.hooks.DefaultPasswordGenerator;
 import com.github.games647.fastlogin.core.hooks.PasswordGenerator;
@@ -88,7 +90,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {

     private Configuration config;
     private SQLStorage storage;
-    private RateLimiter rateLimiter;
+    private AntiBotService antiBot;
     private PasswordGenerator<P> passwordGenerator = new DefaultPasswordGenerator<>();
     private AuthPlugin<P> authPlugin;

@@ -122,7 +124,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
         // Initialize the resolver based on the config parameter
         this.resolver = this.config.getBoolean("useProxyAgnosticResolver", false) ? new ProxyAgnosticMojangResolver() : new MojangResolver();

-        rateLimiter = createRateLimiter(config.getSection("anti-bot"));
+        antiBot = createAntiBotService(config.getSection("anti-bot"));
         Set<Proxy> proxies = config.getStringList("proxies")
                 .stream()
                 .map(HostAndPort::fromString)
@@ -144,20 +146,34 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
         resolver.setOutgoingAddresses(addresses);
     }

-    private RateLimiter createRateLimiter(Configuration botSection) {
-        boolean enabled = botSection.getBoolean("enabled", true);
-        if (!enabled) {
+    private AntiBotService createAntiBotService(Configuration botSection) {
+        RateLimiter rateLimiter;
+        if (botSection.getBoolean("enabled", true)) {
+            int maxCon = botSection.getInt("connections", 200);
+            long expireTime = botSection.getLong("expire", 5) * 60 * 1_000L;
+            if (expireTime > MAX_EXPIRE_RATE) {
+                expireTime = MAX_EXPIRE_RATE;
+            }
+
+            rateLimiter = new TickingRateLimiter(Ticker.systemTicker(), maxCon, expireTime);
+        } else {
             // no-op rate limiter
-            return () -> true;
+            rateLimiter = () -> true;
         }

-        int maxCon = botSection.getInt("connections", 200);
-        long expireTime = botSection.getLong("expire", 5) * 60 * 1_000L;
-        if (expireTime > MAX_EXPIRE_RATE) {
-            expireTime = MAX_EXPIRE_RATE;
+        Action action = Action.Ignore;
+        switch (botSection.getString("action", "ignore")) {
+            case "ignore":
+                action = Action.Ignore;
+                break;
+            case "block":
+                action = Action.Block;
+                break;
+            default:
+                plugin.getLog().warn("Invalid anti bot action - defaulting to ignore");
         }

-        return new TickingRateLimiter(Ticker.systemTicker(), maxCon, expireTime);
+        return new AntiBotService(plugin.getLog(), rateLimiter, action);
     }

     private Configuration loadFile(String fileName) throws IOException {
@@ -285,8 +301,8 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
         return authPlugin;
     }

-    public RateLimiter getRateLimiter() {
-        return rateLimiter;
+    public AntiBotService getAntiBot() {
+        return antiBot;
     }

     public void setAuthPluginHook(AuthPlugin<P> authPlugin) {
diff --git a/core/src/main/resources/config.yml b/core/src/main/resources/config.yml
index 1b0905d..3a2ab7a 100644
--- a/core/src/main/resources/config.yml
+++ b/core/src/main/resources/config.yml
@@ -20,6 +20,9 @@ anti-bot:
   connections: 600
   # Amount of minutes after the first connection got inserted will expire and made available
   expire: 10
+  # Action - Which action should be performed when the bucket is full (too many connections)
+  # Allowed values are: 'ignore' (FastLogin drops handling the player) or 'block' (block this incoming connection)
+  action: 'ignore'

 # Request a premium login without forcing the player to type a command
 #
diff --git a/core/src/main/resources/messages.yml b/core/src/main/resources/messages.yml
index 8b315ba..33cadaa 100644
--- a/core/src/main/resources/messages.yml
+++ b/core/src/main/resources/messages.yml
@@ -48,6 +48,9 @@ not-premium-other: '&4Player is not in the premium list'
 # Admin wanted to change the premium of a user that isn't known to the plugin
 player-unknown: '&4Player not in the database'

+# Player kicked from anti bot feature
+kick-antibot: '&4Please wait a moment!'
+
 # ========= Bukkit/Spigot ================

 # The user skipped the authentication, because it was a premium player
diff --git a/core/src/test/java/com/github/games647/fastlogin/core/TickingRateLimiterTest.java b/core/src/test/java/com/github/games647/fastlogin/core/TickingRateLimiterTest.java
index 2c04b6e..3f753cd 100644
--- a/core/src/test/java/com/github/games647/fastlogin/core/TickingRateLimiterTest.java
+++ b/core/src/test/java/com/github/games647/fastlogin/core/TickingRateLimiterTest.java
@@ -25,6 +25,8 @@
  */
 package com.github.games647.fastlogin.core;

+import com.github.games647.fastlogin.core.antibot.TickingRateLimiter;
+
 import java.time.Duration;
 import java.util.concurrent.TimeUnit;

diff --git a/velocity/src/main/java/com/github/games647/fastlogin/velocity/listener/ConnectListener.java b/velocity/src/main/java/com/github/games647/fastlogin/velocity/listener/ConnectListener.java
index 2b51bd2..33c8c31 100644
--- a/velocity/src/main/java/com/github/games647/fastlogin/velocity/listener/ConnectListener.java
+++ b/velocity/src/main/java/com/github/games647/fastlogin/velocity/listener/ConnectListener.java
@@ -27,7 +27,8 @@ package com.github.games647.fastlogin.velocity.listener;

 import com.github.games647.craftapi.UUIDAdapter;
 import com.github.games647.fastlogin.core.StoredProfile;
-import com.github.games647.fastlogin.core.antibot.RateLimiter;
+import com.github.games647.fastlogin.core.antibot.AntiBotService;
+import com.github.games647.fastlogin.core.antibot.AntiBotService.Action;
 import com.github.games647.fastlogin.core.shared.LoginSession;
 import com.github.games647.fastlogin.velocity.FastLoginVelocity;
 import com.github.games647.fastlogin.velocity.VelocityLoginSession;
@@ -37,6 +38,7 @@ import com.velocitypowered.api.event.Continuation;
 import com.velocitypowered.api.event.Subscribe;
 import com.velocitypowered.api.event.connection.DisconnectEvent;
 import com.velocitypowered.api.event.connection.PreLoginEvent;
+import com.velocitypowered.api.event.connection.PreLoginEvent.PreLoginComponentResult;
 import com.velocitypowered.api.event.player.GameProfileRequestEvent;
 import com.velocitypowered.api.event.player.ServerConnectedEvent;
 import com.velocitypowered.api.proxy.InboundConnection;
@@ -44,19 +46,23 @@ import com.velocitypowered.api.proxy.Player;
 import com.velocitypowered.api.proxy.server.RegisteredServer;
 import com.velocitypowered.api.util.GameProfile;

+import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;

+import net.kyori.adventure.text.TextComponent;
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
+
 public class ConnectListener {

     private final FastLoginVelocity plugin;
-    private final RateLimiter rateLimiter;
+    private final AntiBotService antiBotService;

-    public ConnectListener(FastLoginVelocity plugin, RateLimiter rateLimiter) {
+    public ConnectListener(FastLoginVelocity plugin, AntiBotService antiBotService) {
         this.plugin = plugin;
-        this.rateLimiter = rateLimiter;
+        this.antiBotService = antiBotService;
     }

     @Subscribe
@@ -66,16 +72,28 @@ public class ConnectListener {
         }

         InboundConnection connection = preLoginEvent.getConnection();
-        if (!rateLimiter.tryAcquire()) {
-            plugin.getLog().warn("Simple Anti-Bot join limit - Ignoring {}", connection);
-            return;
-        }
-
         String username = preLoginEvent.getUsername();
-        plugin.getLog().info("Incoming login request for {} from {}", username, connection.getRemoteAddress());
-
-        Runnable asyncPremiumCheck = new AsyncPremiumCheck(plugin, connection, username, continuation, preLoginEvent);
-        plugin.getScheduler().runAsync(asyncPremiumCheck);
+        InetSocketAddress address = connection.getRemoteAddress();
+        plugin.getLog().info("Incoming login request for {} from {}", username, address);
+
+        Action action = antiBotService.onIncomingConnection(address, username);
+        switch (action) {
+            case Ignore:
+                // just ignore
+                return;
+            case Block:
+                String message = plugin.getCore().getMessage("kick-antibot");
+                TextComponent messageParsed = LegacyComponentSerializer.legacyAmpersand().deserialize(message);
+
+                PreLoginComponentResult reason = PreLoginComponentResult.denied(messageParsed);
+                preLoginEvent.setResult(reason);
+                break;
+            case Continue:
+            default:
+                Runnable asyncPremiumCheck = new AsyncPremiumCheck(plugin, connection, username, continuation, preLoginEvent);
+                plugin.getScheduler().runAsync(asyncPremiumCheck);
+                break;
+        }
     }

     @Subscribe
2022-06-18 18:09:31 +02:00
games647
10785b32ac Fix anti bot reading the correct values 2022-06-18 18:08:40 +02:00
games647
18bd778b7e General minor code clean up and typo fixes 2022-06-18 16:09:44 +02:00
games647
9d2c346235 Use platform scheduler to reuse threads between plugins
The platforms usually use a caching thread executor. It makes to use
this executor to reuse threads as they are expensive to create.
2022-03-30 16:02:51 +02:00
Smart123s
a856356c49 Update license headers to 02db104
Done using `mvn license:format`
2022-03-13 10:08:57 +01:00
games647
52d778afb1 Clean up 2022-01-14 12:52:46 +01:00
Smart123s
fcd2aa95f0 Use BedrockService in JoinManagement
Since the code only needs to interact with Geyser, if Floodgate is not
installed, and perform similar things with both, it's reasonable, to
merge their code.
This commit breaks premium checking with `auth-type=online` in Geyser
2021-11-28 13:44:57 +01:00
Smart123s
f76c7bd62f Create generalized BedrockService class 2021-11-28 13:44:57 +01:00
Smart123s
f570474fa3 Detect Geyser connections at packet level
It is possible to use Geyser without Floodgate by configuring Geyser to
use auth-type= 'online' or 'offline'. In that scenario, floodgateService
will be either unavailable or empty.
2021-11-28 13:44:57 +01:00
Smart123s
3ee6cb2ada Create stub GeyserService
The FloodgateService and GeyserService classes are not merged,
because Geyser can work without Floodgate.
Added Geyser as 'softdepends' in plugin.yml and bungee.yml
to make it load before FastLogin.
Also made Floodgate a soft dependency in bungee.yml.
2021-11-28 13:44:56 +01:00
games647
28480a0f01 Add floodgate service to Bungee 2021-10-05 15:42:40 +02:00
games647
37ac04c8ed Reformat 2021-09-22 12:13:33 +02:00
juanmuscaria
c458bd383a Only remove the texture property from the player profile if forwardSkin is disabled 2021-09-17 10:00:45 -03:00
juanmuscaria
64fbbf759f Actually handle proxy shutdown this time 2021-09-17 09:45:09 -03:00
juanmuscaria
310ef4068c Make PROXY_ID_fILE static 2021-09-17 09:37:50 -03:00
juanmuscaria
bc4d9857b4 Ops, printing exception directly 2021-09-17 09:36:51 -03:00
juanmuscaria
d0491d44ec Remove left over assertion 2021-09-17 09:35:07 -03:00
juanmuscaria
68a783bd40 Use path directly for loading the proxy uuid 2021-09-16 13:25:35 -03:00
juanmuscaria
352702eae4 Some code formatting and cleanup 2021-09-15 20:08:03 -03:00
juanmuscaria
b6dfa4802a Removed old FIXME and added a new TODO 2021-09-15 19:58:29 -03:00
juanmuscaria
fc226e1010 Moved LoginEvent logic to GameProfileRequestEvent. Allow overwriting online mode uuid and support for forwardSkin. Added one second delay for login command. 2021-09-15 19:58:29 -03:00
juanmuscaria
4befb35af9 Added a way to generate or use a predefined proxy uuid. 2021-09-15 19:58:29 -03:00
juanmuscaria
01632ec125 Cleanup unused imports 2021-09-15 15:44:51 -03:00
juanmuscaria
268c70bc51 Use org.slf4j.Logger directly 2021-09-15 13:54:28 -03:00
juanmuscaria
6e318ba9bb Use logger for exceptions 2021-09-14 12:26:52 -03:00
juanmuscaria
89d03bcc6b I missed that there was an alternative for bungee in the documentation 2021-09-14 12:22:22 -03:00
juanmuscaria
502b16a0e7 Fill all plugin metadata properly. 2021-09-14 12:12:04 -03:00
juanmuscaria
0e7d8a595d Added missing license header for some classes. 2021-09-14 11:36:26 -03:00
juanmuscaria
7178ea4587 Seems like this is generated automatically. 2021-09-13 21:29:56 -03:00
juanmuscaria
e639e29dee Partial velocity support. 2021-09-13 21:24:46 -03:00