diff --git a/src/main/java/fr/xephi/authme/AntiBot.java b/src/main/java/fr/xephi/authme/AntiBot.java index fcdb2206d..5670e90e9 100644 --- a/src/main/java/fr/xephi/authme/AntiBot.java +++ b/src/main/java/fr/xephi/authme/AntiBot.java @@ -1,5 +1,6 @@ package fr.xephi.authme; +import fr.xephi.authme.listener.AuthMePlayerListener; import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.Messages; import fr.xephi.authme.permission.PermissionsManager; @@ -12,6 +13,7 @@ import org.bukkit.entity.Player; import javax.inject.Inject; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import static fr.xephi.authme.util.BukkitService.TICKS_PER_MINUTE; import static fr.xephi.authme.util.BukkitService.TICKS_PER_SECOND; @@ -25,7 +27,8 @@ public class AntiBot { private final Messages messages; private final PermissionsManager permissionsManager; private final BukkitService bukkitService; - private final List antibotPlayers = new ArrayList<>(); + public final CopyOnWriteArrayList antibotKicked = new CopyOnWriteArrayList(); + private final CopyOnWriteArrayList antibotPlayers = new CopyOnWriteArrayList(); private AntiBotStatus antiBotStatus = AntiBotStatus.DISABLED; @Inject @@ -77,6 +80,7 @@ public class AntiBot { if (antiBotStatus == AntiBotStatus.ACTIVE) { antiBotStatus = AntiBotStatus.LISTENING; antibotPlayers.clear(); + antibotKicked.clear(); for (String s : messages.retrieve(MessageKey.ANTIBOT_AUTO_DISABLED_MESSAGE)) { bukkitService.broadcastMessage(s.replace("%m", Integer.toString(duration))); } diff --git a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java index 9ed45eccc..7e9fe611f 100644 --- a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java @@ -28,6 +28,7 @@ import fr.xephi.authme.util.ValidationService; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; +import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -58,7 +59,11 @@ import javax.inject.Inject; import java.util.Iterator; import java.util.Set; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.regex.Pattern; import static fr.xephi.authme.listener.ListenerService.shouldCancelEvent; @@ -73,6 +78,7 @@ public class AuthMePlayerListener implements Listener { public static final ConcurrentHashMap joinMessage = new ConcurrentHashMap<>(); public static final ConcurrentHashMap causeByAuthMe = new ConcurrentHashMap<>(); + @Inject private AuthMe plugin; @Inject @@ -239,7 +245,7 @@ public class AuthMePlayerListener implements Listener { player.setGameMode(GameMode.SURVIVAL); } - // Shedule login task so works after the prelogin + // Schedule login task so works after the prelogin // (Fix found by Koolaid5000) bukkitService.runTask(new Runnable() { @Override @@ -252,6 +258,23 @@ public class AuthMePlayerListener implements Listener { @EventHandler(priority = EventPriority.HIGHEST) public void onPreLogin(AsyncPlayerPreLoginEvent event) { PlayerAuth auth = dataSource.getAuth(event.getName()); + if (auth == null && antiBot.getAntiBotStatus() == AntiBotStatus.ACTIVE) { + event.setKickMessage(m.retrieveSingle(MessageKey.KICK_ANTIBOT)); + event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); + antiBot.antibotKicked.addIfAbsent(event.getName()); + return; + } + if (auth == null && settings.getProperty(RestrictionSettings.KICK_NON_REGISTERED)) { + event.setKickMessage(m.retrieveSingle(MessageKey.MUST_REGISTER_MESSAGE)); + event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); + return; + } + final String name = event.getName().toLowerCase(); + if (name.length() > settings.getProperty(RestrictionSettings.MAX_NICKNAME_LENGTH) || name.length() < settings.getProperty(RestrictionSettings.MIN_NICKNAME_LENGTH)) { + event.setKickMessage(m.retrieveSingle(MessageKey.INVALID_NAME_LENGTH)); + event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); + return; + } if (settings.getProperty(RegistrationSettings.PREVENT_OTHER_CASE) && auth != null && auth.getRealName() != null) { String realName = auth.getRealName(); if (!realName.isEmpty() && !"Player".equals(realName) && !realName.equals(event.getName())) { @@ -273,7 +296,6 @@ public class AuthMePlayerListener implements Listener { } } - final String name = event.getName().toLowerCase(); final Player player = bukkitService.getPlayerExact(name); // Check if forceSingleSession is set to true, so kick player that has // joined with same nick of online player @@ -331,6 +353,7 @@ public class AuthMePlayerListener implements Listener { if (antiBot.getAntiBotStatus() == AntiBotStatus.ACTIVE && !isAuthAvailable) { event.setKickMessage(m.retrieveSingle(MessageKey.KICK_ANTIBOT)); event.setResult(PlayerLoginEvent.Result.KICK_OTHER); + antiBot.antibotKicked.addIfAbsent(player.getName()); return; } @@ -375,6 +398,10 @@ public class AuthMePlayerListener implements Listener { event.setQuitMessage(null); } + if (antiBot.antibotKicked.contains(player.getName())) { + return; + } + management.performQuit(player, false); } @@ -392,6 +419,10 @@ public class AuthMePlayerListener implements Listener { return; } + if (antiBot.antibotKicked.contains(player.getName())) { + return; + } + plugin.getManagement().performQuit(player, true); } diff --git a/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java index c32245c49..312f3f514 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java @@ -28,11 +28,11 @@ public class ProtectionSettings implements SettingsClass { @Comment("Do we need to enable automatic antibot system?") public static final Property ENABLE_ANTIBOT = - newProperty("Protection.enableAntiBot", false); + newProperty("Protection.enableAntiBot", true); @Comment("Max number of players allowed to login in 5 secs before the AntiBot system is enabled automatically") public static final Property ANTIBOT_SENSIBILITY = - newProperty("Protection.antiBotSensibility", 5); + newProperty("Protection.antiBotSensibility", 10); @Comment("Duration in minutes of the antibot automatic system") public static final Property ANTIBOT_DURATION = diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 8ca9c27fd..3cb5f23fa 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -88,7 +88,7 @@ settings: # due to "Logged in from another Location" # This setting will prevent potetial security exploits. ForceSingleSession: true - ForceSpawnLocOnJoin: + ForceSpawnLocOnJoin: # If enabled, every player will be teleported to the world spawnpoint # after successful authentication. # The quit location of the player will be overwritten. @@ -97,7 +97,7 @@ settings: enabled: false # WorldNames where we need to force the spawn location # Case-sensitive! - worlds: + worlds: - 'world' - 'world_nether' - 'world_the_end' @@ -418,8 +418,8 @@ Protection: countriesBlacklist: - 'A1' # Do we need to enable automatic antibot system? - enableAntiBot: false + enableAntiBot: true # Max number of player allowed to login in 5 secs before enable AntiBot system automatically - antiBotSensibility: 5 + antiBotSensibility: 10 # Duration in minutes of the antibot automatic system antiBotDuration: 10