Encapsulate floodgate hooks

Related #619
Related #620
This commit is contained in:
games647
2021-10-05 15:35:43 +02:00
parent 11c91e6428
commit a3bf875976
9 changed files with 157 additions and 107 deletions

View File

@ -35,6 +35,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.hooks.FloodgateService;
import com.github.games647.fastlogin.core.shared.FastLoginCore; import com.github.games647.fastlogin.core.shared.FastLoginCore;
import com.github.games647.fastlogin.core.shared.PlatformPlugin; import com.github.games647.fastlogin.core.shared.PlatformPlugin;
@ -42,7 +43,6 @@ import io.papermc.lib.PaperLib;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -69,6 +69,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
private BungeeManager bungeeManager; private BungeeManager bungeeManager;
private final BukkitScheduler scheduler; private final BukkitScheduler scheduler;
private FastLoginCore<Player, CommandSender, FastLoginBukkit> core; private FastLoginCore<Player, CommandSender, FastLoginBukkit> core;
private FloodgateService floodgateService;
private PremiumPlaceholder premiumPlaceholder; private PremiumPlaceholder premiumPlaceholder;
@ -88,13 +89,10 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
setEnabled(false); setEnabled(false);
return; return;
} }
// Check Floodgate config values if (!initializeFloodgate()) {
if (!isValidFloodgateConfigString("autoLoginFloodgate") setEnabled(false);
|| !isValidFloodgateConfigString("allowFloodgateNameConflict")) { }
setEnabled(false);
return;
}
bungeeManager = new BungeeManager(this); bungeeManager = new BungeeManager(this);
bungeeManager.initialize(); bungeeManager.initialize();
@ -146,6 +144,20 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
dependencyWarnings(); dependencyWarnings();
} }
private boolean initializeFloodgate() {
if (getServer().getPluginManager().getPlugin("Floodgate") != null) {
floodgateService = new FloodgateService(core);
}
// Check Floodgate config values
if (!floodgateService.isValidFloodgateConfigString("autoLoginFloodgate")
|| !floodgateService.isValidFloodgateConfigString("allowFloodgateNameConflict")) {
return false;
}
return true;
}
@Override @Override
public void onDisable() { public void onDisable() {
loginSession.clear(); loginSession.clear();
@ -251,30 +263,6 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
receiver.sendMessage(message); receiver.sendMessage(message);
} }
/**
* Checks if a config entry (related to Floodgate) is valid. <br>
* Writes to Log if the value is invalid.
* <p>
* This should be used for:
* <ul>
* <li>allowFloodgateNameConflict
* <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"
*/
private 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")) {
logger.error("Invalid value detected for {} in FastLogin/config.yml.", key);
return false;
}
return true;
}
/** /**
* Checks if a plugin is installed on the server * Checks if a plugin is installed on the server
* @param name the name of the plugin * @param name the name of the plugin
@ -286,6 +274,11 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
return Bukkit.getServer().getPluginManager().getPlugin(name) != null; return Bukkit.getServer().getPluginManager().getPlugin(name) != null;
} }
@Override
public FloodgateService getFloodgateService() {
return floodgateService;
}
/** /**
* Send warning messages to log if incompatible plugins are used * Send warning messages to log if incompatible plugins are used
*/ */

View File

@ -29,6 +29,7 @@ import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit; import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.bukkit.task.FloodgateAuthTask; import com.github.games647.fastlogin.bukkit.task.FloodgateAuthTask;
import com.github.games647.fastlogin.bukkit.task.ForceLoginTask; import com.github.games647.fastlogin.bukkit.task.ForceLoginTask;
import com.github.games647.fastlogin.core.hooks.FloodgateService;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -38,9 +39,8 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result; import org.bukkit.event.player.PlayerLoginEvent.Result;
import org.geysermc.floodgate.api.FloodgateApi;
import org.geysermc.floodgate.api.player.FloodgatePlayer;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.geysermc.floodgate.api.player.FloodgatePlayer;
/** /**
* This listener tells authentication plugins if the player has a premium account and we checked it successfully. So the * This listener tells authentication plugins if the player has a premium account and we checked it successfully. So the
@ -69,37 +69,38 @@ public class ConnectionListener implements Listener {
Player player = joinEvent.getPlayer(); Player player = joinEvent.getPlayer();
Bukkit.getScheduler().runTaskLater(plugin, () -> { Bukkit.getScheduler().runTaskLater(plugin, () -> {
// session exists so the player is ready for force login delayForceLogin(player);
// cases: Paper (firing BungeeCord message before PlayerJoinEvent) or not running BungeeCord and already
// having the login session from the login process
BukkitLoginSession session = plugin.getSession(player.getAddress());
boolean isFloodgateLogin = false;
if (Bukkit.getServer().getPluginManager().isPluginEnabled("floodgate")) {
FloodgatePlayer floodgatePlayer = FloodgateApi.getInstance().getPlayer(player.getUniqueId());
if (floodgatePlayer != null) {
isFloodgateLogin = true;
Runnable floodgateAuthTask = new FloodgateAuthTask(plugin.getCore(), player, floodgatePlayer);
Bukkit.getScheduler().runTaskAsynchronously(plugin, floodgateAuthTask);
}
}
if (!isFloodgateLogin) {
if (session == null) {
String sessionId = plugin.getSessionId(player.getAddress());
plugin.getLog().info("No on-going login session for player: {} with ID {}", player, sessionId);
} else {
Runnable forceLoginTask = new ForceLoginTask(plugin.getCore(), player, session);
Bukkit.getScheduler().runTaskAsynchronously(plugin, forceLoginTask);
}
}
plugin.getBungeeManager().markJoinEventFired(player);
// delay the login process to let auth plugins initialize the player // delay the login process to let auth plugins initialize the player
// Magic number however as there is no direct event from those plugins // Magic number however as there is no direct event from those plugins
}, DELAY_LOGIN); }, DELAY_LOGIN);
} }
private void delayForceLogin(Player player) {
// session exists so the player is ready for force login
// cases: Paper (firing BungeeCord message before PlayerJoinEvent) or not running BungeeCord and already
// having the login session from the login process
BukkitLoginSession session = plugin.getSession(player.getAddress());
FloodgateService floodgateService = plugin.getFloodgateService();
if (floodgateService != null) {
FloodgatePlayer floodgatePlayer = floodgateService.getFloodgatePlayer(player.getUniqueId());
if (floodgatePlayer != null) {
Runnable floodgateAuthTask = new FloodgateAuthTask(plugin.getCore(), player, floodgatePlayer);
Bukkit.getScheduler().runTaskAsynchronously(plugin, floodgateAuthTask);
return;
}
}
if (session == null) {
String sessionId = plugin.getSessionId(player.getAddress());
plugin.getLog().info("No on-going login session for player: {} with ID {}", player, sessionId);
} else {
Runnable forceLoginTask = new ForceLoginTask(plugin.getCore(), player, session);
Bukkit.getScheduler().runTaskAsynchronously(plugin, forceLoginTask);
}
plugin.getBungeeManager().markJoinEventFired(player);
}
@EventHandler @EventHandler
public void onPlayerQuit(PlayerQuitEvent quitEvent) { public void onPlayerQuit(PlayerQuitEvent quitEvent) {
Player player = quitEvent.getPlayer(); Player player = quitEvent.getPlayer();

View File

@ -54,7 +54,7 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
public NameCheckTask(FastLoginBukkit plugin, Random random, Player player, PacketEvent packetEvent, public NameCheckTask(FastLoginBukkit plugin, Random random, Player player, PacketEvent packetEvent,
String username, PublicKey publicKey) { String username, PublicKey publicKey) {
super(plugin.getCore(), plugin.getCore().getAuthPluginHook()); super(plugin.getCore(), plugin.getCore().getAuthPluginHook(), plugin.getCore().getFloodgateService());
this.plugin = plugin; this.plugin = plugin;
this.packetEvent = packetEvent; this.packetEvent = packetEvent;

View File

@ -33,6 +33,7 @@ import com.github.games647.fastlogin.bungee.task.FloodgateAuthTask;
import com.github.games647.fastlogin.bungee.task.ForceLoginTask; import com.github.games647.fastlogin.bungee.task.ForceLoginTask;
import com.github.games647.fastlogin.core.RateLimiter; import com.github.games647.fastlogin.core.RateLimiter;
import com.github.games647.fastlogin.core.StoredProfile; import com.github.games647.fastlogin.core.StoredProfile;
import com.github.games647.fastlogin.core.hooks.FloodgateService;
import com.github.games647.fastlogin.core.shared.LoginSession; import com.github.games647.fastlogin.core.shared.LoginSession;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
@ -56,7 +57,6 @@ import net.md_5.bungee.connection.LoginResult.Property;
import net.md_5.bungee.event.EventHandler; import net.md_5.bungee.event.EventHandler;
import net.md_5.bungee.event.EventPriority; import net.md_5.bungee.event.EventPriority;
import org.geysermc.floodgate.api.FloodgateApi;
import org.geysermc.floodgate.api.player.FloodgatePlayer; import org.geysermc.floodgate.api.player.FloodgatePlayer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -184,8 +184,9 @@ public class ConnectListener implements Listener {
ProxiedPlayer player = serverConnectedEvent.getPlayer(); ProxiedPlayer player = serverConnectedEvent.getPlayer();
Server server = serverConnectedEvent.getServer(); Server server = serverConnectedEvent.getServer();
if (plugin.isPluginInstalled("floodgate")) { FloodgateService floodgateService = plugin.getFloodgateService();
FloodgatePlayer floodgatePlayer = FloodgateApi.getInstance().getPlayer(player.getUniqueId()); if (floodgateService != null) {
FloodgatePlayer floodgatePlayer = floodgateService.getFloodgatePlayer(player.getUniqueId());
if (floodgatePlayer != null) { if (floodgatePlayer != null) {
Runnable floodgateAuthTask = new FloodgateAuthTask(plugin.getCore(), player, floodgatePlayer, server); Runnable floodgateAuthTask = new FloodgateAuthTask(plugin.getCore(), player, floodgatePlayer, server);
plugin.getScheduler().runAsync(floodgateAuthTask); plugin.getScheduler().runAsync(floodgateAuthTask);

View File

@ -29,6 +29,7 @@ import com.github.games647.fastlogin.bungee.BungeeLoginSession;
import com.github.games647.fastlogin.bungee.FastLoginBungee; import com.github.games647.fastlogin.bungee.FastLoginBungee;
import com.github.games647.fastlogin.bungee.task.AsyncToggleMessage; import com.github.games647.fastlogin.bungee.task.AsyncToggleMessage;
import com.github.games647.fastlogin.core.StoredProfile; import com.github.games647.fastlogin.core.StoredProfile;
import com.github.games647.fastlogin.core.hooks.FloodgateService;
import com.github.games647.fastlogin.core.message.ChangePremiumMessage; import com.github.games647.fastlogin.core.message.ChangePremiumMessage;
import com.github.games647.fastlogin.core.message.NamespaceKey; import com.github.games647.fastlogin.core.message.NamespaceKey;
import com.github.games647.fastlogin.core.message.SuccessMessage; import com.github.games647.fastlogin.core.message.SuccessMessage;
@ -36,9 +37,6 @@ import com.github.games647.fastlogin.core.shared.FastLoginCore;
import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import org.geysermc.floodgate.api.FloodgateApi;
import org.geysermc.floodgate.api.player.FloodgatePlayer;
import java.util.Arrays; import java.util.Arrays;
import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.CommandSender;
@ -118,13 +116,15 @@ public class PluginMessageListener implements Listener {
} }
private void onSuccessMessage(ProxiedPlayer forPlayer) { private void onSuccessMessage(ProxiedPlayer forPlayer) {
//check if player is using Floodgate boolean shouldPersist = forPlayer.getPendingConnection().isOnlineMode();
FloodgatePlayer floodgatePlayer = null;
if (plugin.isPluginInstalled("floodgate")) { FloodgateService floodgateService = plugin.getFloodgateService();
floodgatePlayer = FloodgateApi.getInstance().getPlayer(forPlayer.getUniqueId()); if (!shouldPersist && floodgateService != null) {
// always save floodgate players to lock this username
shouldPersist = floodgateService.isFloodgatePlayer(forPlayer.getUniqueId());
} }
if (forPlayer.getPendingConnection().isOnlineMode() || floodgatePlayer != null){ if (shouldPersist) {
//bukkit module successfully received and force logged in the user //bukkit module successfully received and force logged in the user
//update only on success to prevent corrupt data //update only on success to prevent corrupt data
BungeeLoginSession loginSession = plugin.getSession().get(forPlayer.getPendingConnection()); BungeeLoginSession loginSession = plugin.getSession().get(forPlayer.getPendingConnection());

View File

@ -27,23 +27,56 @@ package com.github.games647.fastlogin.core.hooks;
import com.github.games647.craftapi.model.Profile; import com.github.games647.craftapi.model.Profile;
import com.github.games647.craftapi.resolver.RateLimitException; import com.github.games647.craftapi.resolver.RateLimitException;
import com.github.games647.fastlogin.core.StoredProfile;
import com.github.games647.fastlogin.core.shared.FastLoginCore; import com.github.games647.fastlogin.core.shared.FastLoginCore;
import com.github.games647.fastlogin.core.shared.LoginSource; import com.github.games647.fastlogin.core.shared.LoginSource;
import java.io.IOException; import java.io.IOException;
import java.util.Locale;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
import org.geysermc.floodgate.api.FloodgateApi; import org.geysermc.floodgate.api.FloodgateApi;
import org.geysermc.floodgate.api.player.FloodgatePlayer; import org.geysermc.floodgate.api.player.FloodgatePlayer;
public class FloodgateHook<P extends C, C, S extends LoginSource> { public class FloodgateService {
private final FastLoginCore<P, C, ?> core; private final FastLoginCore<?, ?, ?> core;
public FloodgateHook(FastLoginCore<P, C, ?> core) { public FloodgateService(FastLoginCore<?, ?, ?> core) {
this.core = core; this.core = core;
} }
/**
* Checks if a config entry (related to Floodgate) is valid. <br>
* Writes to Log if the value is invalid.
* <p>
* This should be used for:
* <ul>
* <li>allowFloodgateNameConflict
* <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")) {
core.getPlugin().getLog().error("Invalid value detected for {} in FastLogin/config.yml.", key);
return false;
}
return true;
}
public boolean isUsernameForbidden(StoredProfile profile) {
String playerPrefix = FloodgateApi.getInstance().getPlayerPrefix();
return profile.getName().startsWith(playerPrefix) && !playerPrefix.isEmpty();
}
/** /**
* Check if the player's name conflicts an existing Java player's name, and * Check if the player's name conflicts an existing Java player's name, and
* kick them if it does * kick them if it does
@ -55,10 +88,10 @@ public class FloodgateHook<P extends C, C, S extends LoginSource> {
String allowConflict = core.getConfig().get("allowFloodgateNameConflict").toString().toLowerCase(); String allowConflict = core.getConfig().get("allowFloodgateNameConflict").toString().toLowerCase();
// check if the Bedrock player is linked to a Java account // check if the Bedrock player is linked to a Java account
boolean isLinked = ((FloodgatePlayer) floodgatePlayer).getLinkedPlayer() != null; boolean isLinked = floodgatePlayer.getLinkedPlayer() != null;
if (allowConflict.equals("false") if ("false".equals(allowConflict)
|| allowConflict.equals("linked") && !isLinked) { || "linked".equals(allowConflict) && !isLinked) {
// check for conflicting Premium Java name // check for conflicting Premium Java name
Optional<Profile> premiumUUID = Optional.empty(); Optional<Profile> premiumUUID = Optional.empty();
@ -66,13 +99,13 @@ public class FloodgateHook<P extends C, C, S extends LoginSource> {
premiumUUID = core.getResolver().findProfile(username); premiumUUID = core.getResolver().findProfile(username);
} catch (IOException | RateLimitException e) { } catch (IOException | RateLimitException e) {
core.getPlugin().getLog().error( core.getPlugin().getLog().error(
"Could not check wether Floodgate Player {}'s name conflicts a premium Java player's name.", "Could not check whether Floodgate Player {}'s name conflicts a premium Java player's name.",
username); username);
try { try {
source.kick("Could not check if your name conflicts an existing premium Java account's name.\n" source.kick("Could not check if your name conflicts an existing premium Java account's name.\n"
+ "This is usually a serverside error."); + "This is usually a serverside error.");
} catch (Exception e1) { } catch (Exception ex) {
core.getPlugin().getLog().error("Could not kick Player {}", username); core.getPlugin().getLog().error("Could not kick Player {}", username, ex);
} }
} }
@ -81,8 +114,8 @@ public class FloodgateHook<P extends C, C, S extends LoginSource> {
username); username);
try { try {
source.kick("Your name conflicts an existing premium Java account's name"); source.kick("Your name conflicts an existing premium Java account's name");
} catch (Exception e) { } catch (Exception ex) {
core.getPlugin().getLog().error("Could not kick Player {}", username); core.getPlugin().getLog().error("Could not kick Player {}", username, ex);
} }
} }
} else { } else {
@ -99,14 +132,25 @@ public class FloodgateHook<P extends C, C, S extends LoginSource> {
* @return FloodgatePlayer if found, null otherwise * @return FloodgatePlayer if found, null otherwise
*/ */
public FloodgatePlayer getFloodgatePlayer(String username) { public FloodgatePlayer getFloodgatePlayer(String username) {
if (core.getPlugin().isPluginInstalled("floodgate")) { for (FloodgatePlayer floodgatePlayer : FloodgateApi.getInstance().getPlayers()) {
for (FloodgatePlayer floodgatePlayer : FloodgateApi.getInstance().getPlayers()) { if (floodgatePlayer.getUsername().equals(username)) {
if (floodgatePlayer.getUsername().equals(username)) { return floodgatePlayer;
return floodgatePlayer;
}
} }
} }
return null; return null;
} }
public FloodgatePlayer getFloodgatePlayer(UUID uuid) {
return FloodgateApi.getInstance().getPlayer(uuid);
}
public boolean isFloodgatePlayer(UUID uuid) {
return getFloodgatePlayer(uuid) != null;
}
public boolean isFloodgateConnection(String username) {
return getFloodgatePlayer(username) != null;
}
} }

View File

@ -27,13 +27,13 @@ package com.github.games647.fastlogin.core.shared;
import com.github.games647.craftapi.resolver.MojangResolver; import com.github.games647.craftapi.resolver.MojangResolver;
import com.github.games647.craftapi.resolver.http.RotatingProxySelector; import com.github.games647.craftapi.resolver.http.RotatingProxySelector;
import com.github.games647.fastlogin.core.storage.MySQLStorage;
import com.github.games647.fastlogin.core.storage.SQLStorage;
import com.github.games647.fastlogin.core.CommonUtil; import com.github.games647.fastlogin.core.CommonUtil;
import com.github.games647.fastlogin.core.RateLimiter; import com.github.games647.fastlogin.core.RateLimiter;
import com.github.games647.fastlogin.core.hooks.AuthPlugin; import com.github.games647.fastlogin.core.hooks.AuthPlugin;
import com.github.games647.fastlogin.core.hooks.DefaultPasswordGenerator; import com.github.games647.fastlogin.core.hooks.DefaultPasswordGenerator;
import com.github.games647.fastlogin.core.hooks.PasswordGenerator; import com.github.games647.fastlogin.core.hooks.PasswordGenerator;
import com.github.games647.fastlogin.core.storage.MySQLStorage;
import com.github.games647.fastlogin.core.storage.SQLStorage;
import com.github.games647.fastlogin.core.storage.SQLiteStorage; import com.github.games647.fastlogin.core.storage.SQLiteStorage;
import com.google.common.net.HostAndPort; import com.google.common.net.HostAndPort;
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariConfig;

View File

@ -29,26 +29,25 @@ import com.github.games647.craftapi.model.Profile;
import com.github.games647.craftapi.resolver.RateLimitException; import com.github.games647.craftapi.resolver.RateLimitException;
import com.github.games647.fastlogin.core.StoredProfile; import com.github.games647.fastlogin.core.StoredProfile;
import com.github.games647.fastlogin.core.hooks.AuthPlugin; import com.github.games647.fastlogin.core.hooks.AuthPlugin;
import com.github.games647.fastlogin.core.hooks.FloodgateHook; import com.github.games647.fastlogin.core.hooks.FloodgateService;
import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent; import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent;
import java.util.Optional; import java.util.Optional;
import org.geysermc.floodgate.api.FloodgateApi;
import org.geysermc.floodgate.api.player.FloodgatePlayer;
import net.md_5.bungee.config.Configuration; import net.md_5.bungee.config.Configuration;
import org.geysermc.floodgate.api.player.FloodgatePlayer;
public abstract class JoinManagement<P extends C, C, S extends LoginSource> { public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
protected final FastLoginCore<P, C, ?> core; protected final FastLoginCore<P, C, ?> core;
protected final AuthPlugin<P> authHook; protected final AuthPlugin<P> authHook;
private final FloodgateHook<P, C, ?> floodgateHook; private final FloodgateService floodgateService;
public JoinManagement(FastLoginCore<P, C, ?> core, AuthPlugin<P> authHook) { public JoinManagement(FastLoginCore<P, C, ?> core, AuthPlugin<P> authHook, FloodgateService floodService) {
this.core = core; this.core = core;
this.authHook = authHook; this.authHook = authHook;
this.floodgateHook = new FloodgateHook<>(core); this.floodgateService = floodService;
} }
public void onLogin(String username, S source) { public void onLogin(String username, S source) {
@ -59,12 +58,14 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
} }
//check if the player is connecting through Floodgate //check if the player is connecting through Floodgate
FloodgatePlayer floodgatePlayer = floodgateHook.getFloodgatePlayer(username); if (floodgateService != null) {
if (floodgateService.isFloodgateConnection(username)) {
if (floodgatePlayer != null) { floodgateService.checkFloodgateNameConflict(username, source, floodgatePlayer);
floodgateHook.checkFloodgateNameConflict(username, source, floodgatePlayer); // skip flow for any floodgate player
return; return;
}
} }
callFastLoginPreLoginEvent(username, source, profile); callFastLoginPreLoginEvent(username, source, profile);
Configuration config = core.getConfig(); Configuration config = core.getConfig();
@ -77,12 +78,9 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
core.getPlugin().getLog().info("Requesting premium login for registered player: {}", username); core.getPlugin().getLog().info("Requesting premium login for registered player: {}", username);
requestPremiumLogin(source, profile, username, true); requestPremiumLogin(source, profile, username, true);
} else { } else {
if (profile.getName().startsWith(FloodgateApi.getInstance().getPlayerPrefix())&&!FloodgateApi.getInstance().getPlayerPrefix().isEmpty()) { if (isValidUsername(source, profile)) {
core.getPlugin().getLog().info("Floodgate Prefix detected on cracked player"); startCrackedSession(source, profile, username);
source.kick("Your username contains illegal characters");
return;
} }
startCrackedSession(source, profile, username);
} }
} else { } else {
if (core.getPendingLogin().remove(ip + username) != null && config.get("secondAttemptCracked", false)) { if (core.getPendingLogin().remove(ip + username) != null && config.get("secondAttemptCracked", false)) {
@ -120,6 +118,16 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
} }
} }
protected boolean isValidUsername(LoginSource source, StoredProfile profile) throws Exception {
if (floodgateService != null && floodgateService.isUsernameForbidden(profile)) {
core.getPlugin().getLog().info("Floodgate Prefix detected on cracked player");
source.kick("Your username contains illegal characters");
return false;
}
return true;
}
private boolean checkPremiumName(S source, String username, StoredProfile profile) throws Exception { private boolean checkPremiumName(S source, String username, StoredProfile profile) throws Exception {
core.getPlugin().getLog().info("GameProfile {} uses a premium username", username); core.getPlugin().getLog().info("GameProfile {} uses a premium username", username);
if (core.getConfig().get("autoRegister", false) && (authHook == null || !authHook.isRegistered(username))) { if (core.getConfig().get("autoRegister", false) && (authHook == null || !authHook.isRegistered(username))) {

View File

@ -26,6 +26,7 @@
package com.github.games647.fastlogin.core.shared; package com.github.games647.fastlogin.core.shared;
import com.github.games647.fastlogin.core.AsyncScheduler; import com.github.games647.fastlogin.core.AsyncScheduler;
import com.github.games647.fastlogin.core.hooks.FloodgateService;
import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.nio.file.Path; import java.nio.file.Path;
@ -53,6 +54,8 @@ public interface PlatformPlugin<C> {
} }
} }
FloodgateService getFloodgateService();
default ThreadFactory getThreadFactory() { default ThreadFactory getThreadFactory() {
return new ThreadFactoryBuilder() return new ThreadFactoryBuilder()
.setNameFormat(getName() + " Pool Thread #%1$d") .setNameFormat(getName() + " Pool Thread #%1$d")