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
This commit is contained in:
Smart123s
2021-10-24 15:30:47 +02:00
committed by games647
parent f76c7bd62f
commit fcd2aa95f0
15 changed files with 94 additions and 73 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.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;
import com.github.games647.fastlogin.core.shared.FastLoginCore; import com.github.games647.fastlogin.core.shared.FastLoginCore;
@ -283,16 +284,22 @@ 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() { public FloodgateService getFloodgateService() {
return floodgateService; return floodgateService;
} }
@Override
public GeyserService getGeyserService() { public GeyserService getGeyserService() {
return geyserService; return geyserService;
} }
@Override
public BedrockService<?> getBedrockService() {
if (floodgateService != null) {
return floodgateService;
}
return geyserService;
}
/** /**
* Send warning messages to log if incompatible plugins are used * Send warning messages to log if incompatible plugins are used
*/ */

View File

@ -82,7 +82,7 @@ public class ConnectionListener implements Listener {
BukkitLoginSession session = plugin.getSession(player.getAddress()); BukkitLoginSession session = plugin.getSession(player.getAddress());
FloodgateService floodgateService = plugin.getFloodgateService(); FloodgateService floodgateService = plugin.getFloodgateService();
if (floodgateService != null) { if (floodgateService != null) {
FloodgatePlayer floodgatePlayer = floodgateService.getFloodgatePlayer(player.getUniqueId()); FloodgatePlayer floodgatePlayer = floodgateService.getBedrockPlayer(player.getUniqueId());
if (floodgatePlayer != null) { if (floodgatePlayer != null) {
Runnable floodgateAuthTask = new FloodgateAuthTask(plugin.getCore(), player, floodgatePlayer); Runnable floodgateAuthTask = new FloodgateAuthTask(plugin.getCore(), player, floodgatePlayer);
Bukkit.getScheduler().runTaskAsynchronously(plugin, floodgateAuthTask); Bukkit.getScheduler().runTaskAsynchronously(plugin, floodgateAuthTask);

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(), plugin.getFloodgateService(), plugin.getGeyserService()); super(plugin.getCore(), plugin.getCore().getAuthPluginHook(), plugin.getBedrockService());
this.plugin = plugin; this.plugin = plugin;
this.packetEvent = packetEvent; this.packetEvent = packetEvent;

View File

@ -53,8 +53,7 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
private final RateLimiter rateLimiter; private final RateLimiter rateLimiter;
public ProtocolSupportListener(FastLoginBukkit plugin, RateLimiter rateLimiter) { public ProtocolSupportListener(FastLoginBukkit plugin, RateLimiter rateLimiter) {
super(plugin.getCore(), plugin.getCore().getAuthPluginHook(), plugin.getFloodgateService(), super(plugin.getCore(), plugin.getCore().getAuthPluginHook(), plugin.getBedrockService());
plugin.getGeyserService());
this.plugin = plugin; this.plugin = plugin;
this.rateLimiter = rateLimiter; this.rateLimiter = rateLimiter;

View File

@ -33,6 +33,7 @@ import com.github.games647.fastlogin.bungee.listener.PluginMessageListener;
import com.github.games647.fastlogin.core.AsyncScheduler; import com.github.games647.fastlogin.core.AsyncScheduler;
import com.github.games647.fastlogin.core.CommonUtil; import com.github.games647.fastlogin.core.CommonUtil;
import com.github.games647.fastlogin.core.hooks.AuthPlugin; import com.github.games647.fastlogin.core.hooks.AuthPlugin;
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;
import com.github.games647.fastlogin.core.message.ChangePremiumMessage; import com.github.games647.fastlogin.core.message.ChangePremiumMessage;
@ -200,13 +201,19 @@ public class FastLoginBungee extends Plugin implements PlatformPlugin<CommandSen
return getProxy().getPluginManager().getPlugin(name) != null; return getProxy().getPluginManager().getPlugin(name) != null;
} }
@Override
public FloodgateService getFloodgateService() { public FloodgateService getFloodgateService() {
return floodgateService; return floodgateService;
} }
@Override
public GeyserService getGeyserService() { public GeyserService getGeyserService() {
return geyserService; return geyserService;
} }
@Override
public BedrockService<?> getBedrockService() {
if (floodgateService != null) {
return floodgateService;
}
return geyserService;
}
} }

View File

@ -186,7 +186,7 @@ public class ConnectListener implements Listener {
FloodgateService floodgateService = plugin.getFloodgateService(); FloodgateService floodgateService = plugin.getFloodgateService();
if (floodgateService != null) { if (floodgateService != null) {
FloodgatePlayer floodgatePlayer = floodgateService.getFloodgatePlayer(player.getUniqueId()); FloodgatePlayer floodgatePlayer = floodgateService.getBedrockPlayer(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

@ -121,7 +121,7 @@ public class PluginMessageListener implements Listener {
FloodgateService floodgateService = plugin.getFloodgateService(); FloodgateService floodgateService = plugin.getFloodgateService();
if (!shouldPersist && floodgateService != null) { if (!shouldPersist && floodgateService != null) {
// always save floodgate players to lock this username // always save floodgate players to lock this username
shouldPersist = floodgateService.isFloodgatePlayer(forPlayer.getUniqueId()); shouldPersist = floodgateService.isBedrockPlayer(forPlayer.getUniqueId());
} }
if (shouldPersist) { if (shouldPersist) {

View File

@ -49,8 +49,7 @@ public class AsyncPremiumCheck extends JoinManagement<ProxiedPlayer, CommandSend
public AsyncPremiumCheck(FastLoginBungee plugin, PreLoginEvent preLoginEvent, PendingConnection connection, public AsyncPremiumCheck(FastLoginBungee plugin, PreLoginEvent preLoginEvent, PendingConnection connection,
String username) { String username) {
super(plugin.getCore(), plugin.getCore().getAuthPluginHook(), plugin.getFloodgateService(), super(plugin.getCore(), plugin.getCore().getAuthPluginHook(), plugin.getBedrockService());
plugin.getGeyserService());
this.plugin = plugin; this.plugin = plugin;
this.preLoginEvent = preLoginEvent; this.preLoginEvent = preLoginEvent;

View File

@ -27,13 +27,18 @@ package com.github.games647.fastlogin.core.hooks.bedrock;
import java.io.IOException; import java.io.IOException;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
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;
public abstract class BedrockService { /**
* @param B is an instance of either FloodgatePlayer or GeyserSession
*/
public abstract class BedrockService<B> {
protected final FastLoginCore<?, ?, ?> core; protected final FastLoginCore<?, ?, ?> core;
protected final String allowConflict; protected final String allowConflict;
@ -79,4 +84,39 @@ public abstract class BedrockService {
} }
/**
* The Floodgate / Geyser API does not support querying players by name, so this function
* iterates over every online Bedrock Player and checks if the requested
* 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 Bedrock Player if found, null otherwise
*/
public B getBedrockPlayer(String prefixedUsername) {
return null;
}
public B getBedrockPlayer(UUID uuid) {
return null;
}
public boolean isBedrockPlayer(UUID uuid) {
return getBedrockPlayer(uuid) != null;
}
public boolean isBedrockConnection(String username) {
return getBedrockPlayer(username) != null;
}
/**
* Checks if a profile's name starts with the Floodgate prefix, if it's available
* @param profile profile of the conecting player
* @return true if the username is forbidden
*/
public boolean isUsernameForbidden(StoredProfile profile) {
return false;
}
} }

View File

@ -35,7 +35,7 @@ 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 FloodgateService extends BedrockService { public class FloodgateService extends BedrockService<FloodgatePlayer> {
private final FloodgateApi floodgate; private final FloodgateApi floodgate;
@ -69,6 +69,7 @@ public class FloodgateService extends BedrockService {
return true; return true;
} }
@Override
public boolean isUsernameForbidden(StoredProfile profile) { public boolean isUsernameForbidden(StoredProfile profile) {
String playerPrefix = FloodgateApi.getInstance().getPlayerPrefix(); String playerPrefix = FloodgateApi.getInstance().getPlayerPrefix();
return profile.getName().startsWith(playerPrefix) && !playerPrefix.isEmpty(); return profile.getName().startsWith(playerPrefix) && !playerPrefix.isEmpty();
@ -77,7 +78,7 @@ public class FloodgateService extends BedrockService {
@Override @Override
public void checkNameConflict(String username, LoginSource source) { public void checkNameConflict(String username, LoginSource source) {
// check if the Bedrock player is linked to a Java account // check if the Bedrock player is linked to a Java account
FloodgatePlayer floodgatePlayer = getFloodgatePlayer(username); FloodgatePlayer floodgatePlayer = getBedrockPlayer(username);
boolean isLinked = floodgatePlayer.getLinkedPlayer() != null; boolean isLinked = floodgatePlayer.getLinkedPlayer() != null;
if ("false".equals(allowConflict) if ("false".equals(allowConflict)
@ -98,7 +99,7 @@ public class FloodgateService extends BedrockService {
* @param prefixedUsername the name of the player with the prefix appended * @param prefixedUsername the name of the player with the prefix appended
* @return FloodgatePlayer if found, null otherwise * @return FloodgatePlayer if found, null otherwise
*/ */
public FloodgatePlayer getFloodgatePlayer(String prefixedUsername) { public FloodgatePlayer getBedrockPlayer(String prefixedUsername) {
//prefixes are broken with ProtocolLib, so fall back to name checks without prefixes //prefixes are broken with ProtocolLib, so fall back to name checks without prefixes
//this should be removed if #493 gets fixed //this should be removed if #493 gets fixed
if (core.getPlugin().isPluginInstalled("ProtocolLib")) { if (core.getPlugin().isPluginInstalled("ProtocolLib")) {
@ -118,15 +119,15 @@ public class FloodgateService extends BedrockService {
return null; return null;
} }
public FloodgatePlayer getFloodgatePlayer(UUID uuid) { public FloodgatePlayer getBedrockPlayer(UUID uuid) {
return FloodgateApi.getInstance().getPlayer(uuid); return FloodgateApi.getInstance().getPlayer(uuid);
} }
public boolean isFloodgatePlayer(UUID uuid) { public boolean isBedrockPlayer(UUID uuid) {
return getFloodgatePlayer(uuid) != null; return getBedrockPlayer(uuid) != null;
} }
public boolean isFloodgateConnection(String username) { public boolean isBedrockConnection(String username) {
return getFloodgatePlayer(username) != null; return getBedrockPlayer(username) != null;
} }
} }

View File

@ -33,7 +33,7 @@ import com.github.games647.fastlogin.core.shared.LoginSource;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
public class GeyserService extends BedrockService { public class GeyserService extends BedrockService<GeyserSession> {
private final GeyserConnector geyser; private final GeyserConnector geyser;
private final FastLoginCore<?, ?, ?> core; private final FastLoginCore<?, ?, ?> core;
@ -54,15 +54,8 @@ public class GeyserService extends BedrockService {
} }
} }
/** @Override
* The Geyser API does not support querying players by name, so this function public GeyserSession getBedrockPlayer(String username) {
* iterates over every online Geyser Player and checks if the requested
* username can be found
*
* @param username the name of the player
* @return GeyserSession if found, null otherwise
*/
public GeyserSession getGeyserPlayer(String username) {
for (GeyserSession gSess : geyser.getSessionManager().getSessions().values()) { for (GeyserSession gSess : geyser.getSessionManager().getSessions().values()) {
if (gSess.getName().equals(username)) { if (gSess.getName().equals(username)) {
return gSess; return gSess;
@ -72,15 +65,8 @@ public class GeyserService extends BedrockService {
return null; return null;
} }
public GeyserSession getGeyserPlayer(UUID uuid) { @Override
public GeyserSession getBedrockPlayer(UUID uuid) {
return geyser.getPlayerByUuid(uuid); return geyser.getPlayerByUuid(uuid);
} }
public boolean isGeyserPlayer(UUID uuid) {
return getGeyserPlayer(uuid) != null;
}
public boolean isGeyserConnection(String username) {
return getGeyserPlayer(username) != null;
}
} }

View File

@ -29,8 +29,7 @@ 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.bedrock.FloodgateService; import com.github.games647.fastlogin.core.hooks.bedrock.BedrockService;
import com.github.games647.fastlogin.core.hooks.bedrock.GeyserService;
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;
@ -41,15 +40,12 @@ 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 FloodgateService floodgateService; private final BedrockService<?> bedrockService;
private final GeyserService geyserService;
public JoinManagement(FastLoginCore<P, C, ?> core, AuthPlugin<P> authHook, FloodgateService floodService, public JoinManagement(FastLoginCore<P, C, ?> core, AuthPlugin<P> authHook, BedrockService<?> bedrockService) {
GeyserService geyserService) {
this.core = core; this.core = core;
this.authHook = authHook; this.authHook = authHook;
this.floodgateService = floodService; this.bedrockService = bedrockService;
this.geyserService = geyserService;
} }
public void onLogin(String username, S source) { public void onLogin(String username, S source) {
@ -59,18 +55,14 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
return; return;
} }
//check if the player is connecting through Floodgate //check if the player is connecting through Bedrock Edition
if (floodgateService != null) { if (bedrockService != null) {
if (floodgateService.isFloodgateConnection(username)) { if (bedrockService.isBedrockConnection(username)) {
floodgateService.checkNameConflict(username, source); bedrockService.checkNameConflict(username, source);
// skip flow for any floodgate player // skip flow for any Bedrock player
return; return;
} }
} }
//check if the player is connecting through Geyser (without Floodgate)
else if (geyserService != null && geyserService.isGeyserConnection(username)) {
}
callFastLoginPreLoginEvent(username, source, profile); callFastLoginPreLoginEvent(username, source, profile);
@ -125,7 +117,7 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
} }
protected boolean isValidUsername(LoginSource source, StoredProfile profile) throws Exception { protected boolean isValidUsername(LoginSource source, StoredProfile profile) throws Exception {
if (floodgateService != null && floodgateService.isUsernameForbidden(profile)) { if (bedrockService != null && bedrockService.isUsernameForbidden(profile)) {
core.getPlugin().getLog().info("Floodgate Prefix detected on cracked player"); core.getPlugin().getLog().info("Floodgate Prefix detected on cracked player");
source.kick("Your username contains illegal characters"); source.kick("Your username contains illegal characters");
return false; return false;

View File

@ -26,8 +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.bedrock.FloodgateService; import com.github.games647.fastlogin.core.hooks.bedrock.BedrockService;
import com.github.games647.fastlogin.core.hooks.bedrock.GeyserService;
import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.nio.file.Path; import java.nio.file.Path;
@ -55,9 +54,7 @@ public interface PlatformPlugin<C> {
} }
} }
FloodgateService getFloodgateService(); BedrockService<?> getBedrockService();
GeyserService getGeyserService();
default ThreadFactory getThreadFactory() { default ThreadFactory getThreadFactory() {
return new ThreadFactoryBuilder() return new ThreadFactoryBuilder()

View File

@ -26,8 +26,7 @@
package com.github.games647.fastlogin.velocity; package com.github.games647.fastlogin.velocity;
import com.github.games647.fastlogin.core.AsyncScheduler; import com.github.games647.fastlogin.core.AsyncScheduler;
import com.github.games647.fastlogin.core.hooks.bedrock.FloodgateService; import com.github.games647.fastlogin.core.hooks.bedrock.BedrockService;
import com.github.games647.fastlogin.core.hooks.bedrock.GeyserService;
import com.github.games647.fastlogin.core.message.ChangePremiumMessage; import com.github.games647.fastlogin.core.message.ChangePremiumMessage;
import com.github.games647.fastlogin.core.message.ChannelMessage; import com.github.games647.fastlogin.core.message.ChannelMessage;
import com.github.games647.fastlogin.core.message.SuccessMessage; import com.github.games647.fastlogin.core.message.SuccessMessage;
@ -141,12 +140,7 @@ public class FastLoginVelocity implements PlatformPlugin<CommandSource> {
} }
@Override @Override
public FloodgateService getFloodgateService() { public BedrockService<?> getBedrockService() {
return null;
}
@Override
public GeyserService getGeyserService() {
return null; return null;
} }

View File

@ -50,8 +50,7 @@ public class AsyncPremiumCheck extends JoinManagement<Player, CommandSource, Vel
private final InboundConnection connection; private final InboundConnection connection;
public AsyncPremiumCheck(FastLoginVelocity plugin, InboundConnection connection, String username, Continuation continuation, PreLoginEvent preLoginEvent) { public AsyncPremiumCheck(FastLoginVelocity plugin, InboundConnection connection, String username, Continuation continuation, PreLoginEvent preLoginEvent) {
super(plugin.getCore(), plugin.getCore().getAuthPluginHook(), plugin.getFloodgateService(), super(plugin.getCore(), plugin.getCore().getAuthPluginHook(), plugin.getBedrockService());
plugin.getGeyserService());
this.plugin = plugin; this.plugin = plugin;
this.connection = connection; this.connection = connection;
this.username = username; this.username = username;