Clarify pending logins methods

This commit is contained in:
games647
2024-05-11 11:15:13 +02:00
parent 33d3c751b9
commit f1b780c398
10 changed files with 43 additions and 26 deletions

View File

@ -36,6 +36,7 @@ import com.github.games647.fastlogin.bukkit.listener.protocolsupport.ProtocolSup
import com.github.games647.fastlogin.bukkit.task.DelayedAuthHook; import com.github.games647.fastlogin.bukkit.task.DelayedAuthHook;
import com.github.games647.fastlogin.core.CommonUtil; import com.github.games647.fastlogin.core.CommonUtil;
import com.github.games647.fastlogin.core.PremiumStatus; import com.github.games647.fastlogin.core.PremiumStatus;
import com.github.games647.fastlogin.core.antibot.AntiBotService;
import com.github.games647.fastlogin.core.hooks.bedrock.BedrockService; import com.github.games647.fastlogin.core.hooks.bedrock.BedrockService;
import com.github.games647.fastlogin.core.hooks.bedrock.FloodgateService; import com.github.games647.fastlogin.core.hooks.bedrock.FloodgateService;
import com.github.games647.fastlogin.core.hooks.bedrock.GeyserService; import com.github.games647.fastlogin.core.hooks.bedrock.GeyserService;
@ -53,6 +54,7 @@ import org.slf4j.Logger;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.Duration;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
@ -65,7 +67,10 @@ import java.util.concurrent.ConcurrentMap;
public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<CommandSender> { public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<CommandSender> {
//1 minutes should be enough as a timeout for bad internet connection (Server, Client and Mojang) //1 minutes should be enough as a timeout for bad internet connection (Server, Client and Mojang)
private final ConcurrentMap<String, BukkitLoginSession> loginSession = CommonUtil.buildCache(1, -1); private final ConcurrentMap<String, BukkitLoginSession> loginSession = CommonUtil.buildCache(
Duration.ofMinutes(1), -1
);
private final Map<UUID, PremiumStatus> premiumPlayers = new ConcurrentHashMap<>(); private final Map<UUID, PremiumStatus> premiumPlayers = new ConcurrentHashMap<>();
private final Logger logger; private final Logger logger;
@ -111,10 +116,11 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
return; return;
} }
AntiBotService antiBotService = core.getAntiBotService();
if (pluginManager.isPluginEnabled("ProtocolSupport")) { if (pluginManager.isPluginEnabled("ProtocolSupport")) {
pluginManager.registerEvents(new ProtocolSupportListener(this, core.getAntiBot()), this); pluginManager.registerEvents(new ProtocolSupportListener(this, antiBotService), this);
} else if (pluginManager.isPluginEnabled("ProtocolLib")) { } else if (pluginManager.isPluginEnabled("ProtocolLib")) {
ProtocolLibListener.register(this, core.getAntiBot(), core.getConfig().getBoolean("verifyClientKeys")); ProtocolLibListener.register(this, antiBotService, core.getConfig().getBoolean("verifyClientKeys"));
//if server is using paper - we need to set the skin at pre login anyway, so no need for this listener //if server is using paper - we need to set the skin at pre login anyway, so no need for this listener
if (!isPaper() && getConfig().getBoolean("forwardSkin")) { if (!isPaper() && getConfig().getBoolean("forwardSkin")) {
@ -137,9 +143,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
pluginManager.registerEvents(new PaperCacheListener(this), this); pluginManager.registerEvents(new PaperCacheListener(this), this);
} }
//register commands using a unique name registerCommands();
Optional.ofNullable(getCommand("premium")).ifPresent(c -> c.setExecutor(new PremiumCommand(this)));
Optional.ofNullable(getCommand("cracked")).ifPresent(c -> c.setExecutor(new CrackedCommand(this)));
if (pluginManager.isPluginEnabled("PlaceholderAPI")) { if (pluginManager.isPluginEnabled("PlaceholderAPI")) {
premiumPlaceholder = new PremiumPlaceholder(this); premiumPlaceholder = new PremiumPlaceholder(this);
@ -147,6 +151,12 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
} }
} }
private void registerCommands() {
//register commands using a unique name
Optional.ofNullable(getCommand("premium")).ifPresent(c -> c.setExecutor(new PremiumCommand(this)));
Optional.ofNullable(getCommand("cracked")).ifPresent(c -> c.setExecutor(new CrackedCommand(this)));
}
private boolean initializeFloodgate() { private boolean initializeFloodgate() {
if (getServer().getPluginManager().getPlugin("Geyser-Spigot") != null) { if (getServer().getPluginManager().getPlugin("Geyser-Spigot") != null) {
geyserService = new GeyserService(GeyserImpl.getInstance(), core); geyserService = new GeyserService(GeyserImpl.getInstance(), core);

View File

@ -97,7 +97,7 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
} }
String ip = player.getAddress().getAddress().getHostAddress(); String ip = player.getAddress().getAddress().getHostAddress();
core.getPendingLogin().put(ip + username, new Object()); core.addLoginAttempt(ip, username);
byte[] verify = source.getVerifyToken(); byte[] verify = source.getVerifyToken();
ClientPublicKey clientKey = source.getClientKey(); ClientPublicKey clientKey = source.getClientKey();

View File

@ -125,7 +125,7 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
source.enableOnlinemode(); source.enableOnlinemode();
String ip = source.getAddress().getAddress().getHostAddress(); String ip = source.getAddress().getAddress().getHostAddress();
plugin.getCore().getPendingLogin().put(ip + username, new Object()); plugin.getCore().addLoginAttempt(ip, username);
BukkitLoginSession playerSession = new BukkitLoginSession(username, registered, profile); BukkitLoginSession playerSession = new BukkitLoginSession(username, registered, profile);
plugin.putSession(source.getAddress(), playerSession); plugin.putSession(source.getAddress(), playerSession);

View File

@ -98,7 +98,7 @@ public class FastLoginBungee extends Plugin implements PlatformPlugin<CommandSen
//events //events
PluginManager pluginManager = getProxy().getPluginManager(); PluginManager pluginManager = getProxy().getPluginManager();
Listener connectListener = new ConnectListener(this, core.getAntiBot()); Listener connectListener = new ConnectListener(this, core.getAntiBotService());
pluginManager.registerListener(this, connectListener); pluginManager.registerListener(this, connectListener);
pluginManager.registerListener(this, new PluginMessageListener(this)); pluginManager.registerListener(this, new PluginMessageListener(this));

View File

@ -81,7 +81,7 @@ public class AsyncPremiumCheck extends JoinManagement<ProxiedPlayer, CommandSend
plugin.getSession().put(source.getConnection(), new BungeeLoginSession(username, registered, profile)); plugin.getSession().put(source.getConnection(), new BungeeLoginSession(username, registered, profile));
String ip = source.getAddress().getAddress().getHostAddress(); String ip = source.getAddress().getAddress().getHostAddress();
plugin.getCore().getPendingLogin().put(ip + username, new Object()); plugin.getCore().addLoginAttempt(ip, username);
} }
@Override @Override

View File

@ -32,8 +32,8 @@ import org.slf4j.jul.JDK14LoggerAdapter;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.time.Duration;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level; import java.util.logging.Level;
public final class CommonUtil { public final class CommonUtil {
@ -41,11 +41,11 @@ public final class CommonUtil {
private static final char COLOR_CHAR = '&'; private static final char COLOR_CHAR = '&';
private static final char TRANSLATED_CHAR = '§'; private static final char TRANSLATED_CHAR = '§';
public static <K, V> ConcurrentMap<K, V> buildCache(int expireAfterWrite, int maxSize) { public static <K, V> ConcurrentMap<K, V> buildCache(Duration expireAfterWrite, int maxSize) {
CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder(); CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder();
if (expireAfterWrite > 0) { if (expireAfterWrite != null) {
builder.expireAfterWrite(expireAfterWrite, TimeUnit.MINUTES); builder.expireAfterWrite(expireAfterWrite);
} }
if (maxSize > 0) { if (maxSize > 0) {

View File

@ -55,6 +55,7 @@ import java.net.Proxy.Type;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.Duration;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
@ -78,7 +79,10 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
private static final long MAX_EXPIRE_RATE = 1_000_000; private static final long MAX_EXPIRE_RATE = 1_000_000;
private final Map<String, String> localeMessages = new ConcurrentHashMap<>(); private final Map<String, String> localeMessages = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Object> pendingLogin = CommonUtil.buildCache(5, -1); private final ConcurrentMap<String, Object> pendingLogin = CommonUtil.buildCache(
Duration.ofMinutes(5), -1
);
private final Collection<UUID> pendingConfirms = new HashSet<>(); private final Collection<UUID> pendingConfirms = new HashSet<>();
private final T plugin; private final T plugin;
@ -272,8 +276,16 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
this.passwordGenerator = passwordGenerator; this.passwordGenerator = passwordGenerator;
} }
public ConcurrentMap<String, Object> getPendingLogin() { public void addLoginAttempt(String ip, String username) {
return pendingLogin; pendingLogin.put(ip + username, new Object());
}
public boolean hasFailedLogin(String ip, String username) {
if (!config.get("secondAttemptCracked", false)) {
return false;
}
return pendingLogin.remove(ip + username) != null;
} }
public Collection<UUID> getPendingConfirms() { public Collection<UUID> getPendingConfirms() {
@ -284,7 +296,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
return authPlugin; return authPlugin;
} }
public AntiBotService getAntiBot() { public AntiBotService getAntiBotService() {
return antiBot; return antiBot;
} }

View File

@ -48,8 +48,6 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
} }
public void onLogin(String username, S source) { public void onLogin(String username, S source) {
core.getPlugin().getLog().info("Handling player {}", username);
//check if the player is connecting through Bedrock Edition //check if the player is connecting through Bedrock Edition
if (bedrockService != null && bedrockService.isBedrockConnection(username)) { if (bedrockService != null && bedrockService.isBedrockConnection(username)) {
//perform Bedrock specific checks and skip Java checks if no longer needed //perform Bedrock specific checks and skip Java checks if no longer needed
@ -59,7 +57,6 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
} }
StoredProfile profile = core.getStorage().loadProfile(username); StoredProfile profile = core.getStorage().loadProfile(username);
//can't be a premium Java player, if it's not saved in the database //can't be a premium Java player, if it's not saved in the database
if (profile == null) { if (profile == null) {
return; return;
@ -78,7 +75,6 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
} }
callFastLoginPreLoginEvent(username, source, profile); callFastLoginPreLoginEvent(username, source, profile);
Configuration config = core.getConfig(); Configuration config = core.getConfig();
String ip = source.getAddress().getAddress().getHostAddress(); String ip = source.getAddress().getAddress().getHostAddress();
@ -94,7 +90,7 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
} }
} }
} else { } else {
if (core.getPendingLogin().remove(ip + username) != null && config.get("secondAttemptCracked", false)) { if (core.hasFailedLogin(ip, username)) {
core.getPlugin().getLog().info("Second attempt login -> cracked {}", username); core.getPlugin().getLog().info("Second attempt login -> cracked {}", username);
//first login request failed so make a cracked session //first login request failed so make a cracked session
@ -124,7 +120,6 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
+ " server issued more than 600 Name -> UUID requests within 10 minutes. After those 10" + " server issued more than 600 Name -> UUID requests within 10 minutes. After those 10"
+ " minutes we can make requests again.", username); + " minutes we can make requests again.", username);
} catch (Exception ex) { } catch (Exception ex) {
core.getPlugin().getLog().error("Failed to check premium state for {}", username, ex);
core.getPlugin().getLog().error("Failed to check premium state of {}", username, ex); core.getPlugin().getLog().error("Failed to check premium state of {}", username, ex);
} }
} }

View File

@ -109,7 +109,7 @@ public class FastLoginVelocity implements PlatformPlugin<CommandSource> {
geyserService = new GeyserService(GeyserImpl.getInstance(), core); geyserService = new GeyserService(GeyserImpl.getInstance(), core);
} }
server.getEventManager().register(this, new ConnectListener(this, core.getAntiBot())); server.getEventManager().register(this, new ConnectListener(this, core.getAntiBotService()));
server.getEventManager().register(this, new PluginMessageListener(this)); server.getEventManager().register(this, new PluginMessageListener(this));
ChannelRegistrar channelRegistry = server.getChannelRegistrar(); ChannelRegistrar channelRegistry = server.getChannelRegistrar();

View File

@ -85,7 +85,7 @@ public class AsyncPremiumCheck extends JoinManagement<Player, CommandSource, Vel
plugin.getSession().put(source.getConnection().getRemoteAddress(), session); plugin.getSession().put(source.getConnection().getRemoteAddress(), session);
String ip = source.getAddress().getAddress().getHostAddress(); String ip = source.getAddress().getAddress().getHostAddress();
plugin.getCore().getPendingLogin().put(ip + username, new Object()); plugin.getCore().addLoginAttempt(ip, username);
} }
@Override @Override