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.core.CommonUtil;
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.FloodgateService;
import com.github.games647.fastlogin.core.hooks.bedrock.GeyserService;
@ -53,6 +54,7 @@ import org.slf4j.Logger;
import java.net.InetSocketAddress;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
@ -65,7 +67,10 @@ import java.util.concurrent.ConcurrentMap;
public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<CommandSender> {
//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 Logger logger;
@ -111,10 +116,11 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
return;
}
AntiBotService antiBotService = core.getAntiBotService();
if (pluginManager.isPluginEnabled("ProtocolSupport")) {
pluginManager.registerEvents(new ProtocolSupportListener(this, core.getAntiBot()), this);
pluginManager.registerEvents(new ProtocolSupportListener(this, antiBotService), this);
} 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 (!isPaper() && getConfig().getBoolean("forwardSkin")) {
@ -137,9 +143,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
pluginManager.registerEvents(new PaperCacheListener(this), this);
}
//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)));
registerCommands();
if (pluginManager.isPluginEnabled("PlaceholderAPI")) {
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() {
if (getServer().getPluginManager().getPlugin("Geyser-Spigot") != null) {
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();
core.getPendingLogin().put(ip + username, new Object());
core.addLoginAttempt(ip, username);
byte[] verify = source.getVerifyToken();
ClientPublicKey clientKey = source.getClientKey();

View File

@ -125,7 +125,7 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
source.enableOnlinemode();
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);
plugin.putSession(source.getAddress(), playerSession);

View File

@ -98,7 +98,7 @@ public class FastLoginBungee extends Plugin implements PlatformPlugin<CommandSen
//events
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, 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));
String ip = source.getAddress().getAddress().getHostAddress();
plugin.getCore().getPendingLogin().put(ip + username, new Object());
plugin.getCore().addLoginAttempt(ip, username);
}
@Override

View File

@ -32,8 +32,8 @@ import org.slf4j.jul.JDK14LoggerAdapter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.time.Duration;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
public final class CommonUtil {
@ -41,11 +41,11 @@ public final class CommonUtil {
private static final char COLOR_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();
if (expireAfterWrite > 0) {
builder.expireAfterWrite(expireAfterWrite, TimeUnit.MINUTES);
if (expireAfterWrite != null) {
builder.expireAfterWrite(expireAfterWrite);
}
if (maxSize > 0) {

View File

@ -55,6 +55,7 @@ import java.net.Proxy.Type;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Collection;
import java.util.HashSet;
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 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 T plugin;
@ -272,8 +276,16 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
this.passwordGenerator = passwordGenerator;
}
public ConcurrentMap<String, Object> getPendingLogin() {
return pendingLogin;
public void addLoginAttempt(String ip, String username) {
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() {
@ -284,7 +296,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
return authPlugin;
}
public AntiBotService getAntiBot() {
public AntiBotService getAntiBotService() {
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) {
core.getPlugin().getLog().info("Handling player {}", username);
//check if the player is connecting through Bedrock Edition
if (bedrockService != null && bedrockService.isBedrockConnection(username)) {
//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);
//can't be a premium Java player, if it's not saved in the database
if (profile == null) {
return;
@ -78,7 +75,6 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
}
callFastLoginPreLoginEvent(username, source, profile);
Configuration config = core.getConfig();
String ip = source.getAddress().getAddress().getHostAddress();
@ -94,7 +90,7 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
}
}
} 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);
//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"
+ " minutes we can make requests again.", username);
} 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);
}
}

View File

@ -109,7 +109,7 @@ public class FastLoginVelocity implements PlatformPlugin<CommandSource> {
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));
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);
String ip = source.getAddress().getAddress().getHostAddress();
plugin.getCore().getPendingLogin().put(ip + username, new Object());
plugin.getCore().addLoginAttempt(ip, username);
}
@Override