Skip to content

Commit a3bf875

Browse files
author
games647
committed
Encapsulate floodgate hooks
Related #619 Related #620
1 parent 11c91e6 commit a3bf875

File tree

9 files changed

+157
-107
lines changed

9 files changed

+157
-107
lines changed

bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@
3535
import com.github.games647.fastlogin.bukkit.task.DelayedAuthHook;
3636
import com.github.games647.fastlogin.core.CommonUtil;
3737
import com.github.games647.fastlogin.core.PremiumStatus;
38+
import com.github.games647.fastlogin.core.hooks.FloodgateService;
3839
import com.github.games647.fastlogin.core.shared.FastLoginCore;
3940
import com.github.games647.fastlogin.core.shared.PlatformPlugin;
4041

4142
import io.papermc.lib.PaperLib;
4243

4344
import java.net.InetSocketAddress;
4445
import java.nio.file.Path;
45-
import java.util.Locale;
4646
import java.util.Map;
4747
import java.util.UUID;
4848
import java.util.concurrent.ConcurrentHashMap;
@@ -69,6 +69,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
6969
private BungeeManager bungeeManager;
7070
private final BukkitScheduler scheduler;
7171
private FastLoginCore<Player, CommandSender, FastLoginBukkit> core;
72+
private FloodgateService floodgateService;
7273

7374
private PremiumPlaceholder premiumPlaceholder;
7475

@@ -88,13 +89,10 @@ public void onEnable() {
8889
setEnabled(false);
8990
return;
9091
}
91-
92-
// Check Floodgate config values
93-
if (!isValidFloodgateConfigString("autoLoginFloodgate")
94-
|| !isValidFloodgateConfigString("allowFloodgateNameConflict")) {
95-
setEnabled(false);
96-
return;
97-
}
92+
93+
if (!initializeFloodgate()) {
94+
setEnabled(false);
95+
}
9896

9997
bungeeManager = new BungeeManager(this);
10098
bungeeManager.initialize();
@@ -146,6 +144,20 @@ public void onEnable() {
146144
dependencyWarnings();
147145
}
148146

147+
private boolean initializeFloodgate() {
148+
if (getServer().getPluginManager().getPlugin("Floodgate") != null) {
149+
floodgateService = new FloodgateService(core);
150+
}
151+
152+
// Check Floodgate config values
153+
if (!floodgateService.isValidFloodgateConfigString("autoLoginFloodgate")
154+
|| !floodgateService.isValidFloodgateConfigString("allowFloodgateNameConflict")) {
155+
return false;
156+
}
157+
158+
return true;
159+
}
160+
149161
@Override
150162
public void onDisable() {
151163
loginSession.clear();
@@ -251,30 +263,6 @@ public void sendMessage(CommandSender receiver, String message) {
251263
receiver.sendMessage(message);
252264
}
253265

254-
/**
255-
* Checks if a config entry (related to Floodgate) is valid. <br>
256-
* Writes to Log if the value is invalid.
257-
* <p>
258-
* This should be used for:
259-
* <ul>
260-
* <li>allowFloodgateNameConflict
261-
* <li>autoLoginFloodgate
262-
* <li>autoRegisterFloodgate
263-
* </ul>
264-
* </p>
265-
*
266-
* @param key the key of the entry in config.yml
267-
* @return <b>true</b> if the entry's value is "true", "false", or "linked"
268-
*/
269-
private boolean isValidFloodgateConfigString(String key) {
270-
String value = core.getConfig().get(key).toString().toLowerCase(Locale.ENGLISH);
271-
if (!value.equals("true") && !value.equals("linked") && !value.equals("false") && !value.equals("no-conflict")) {
272-
logger.error("Invalid value detected for {} in FastLogin/config.yml.", key);
273-
return false;
274-
}
275-
return true;
276-
}
277-
278266
/**
279267
* Checks if a plugin is installed on the server
280268
* @param name the name of the plugin
@@ -286,6 +274,11 @@ public boolean isPluginInstalled(String name) {
286274
return Bukkit.getServer().getPluginManager().getPlugin(name) != null;
287275
}
288276

277+
@Override
278+
public FloodgateService getFloodgateService() {
279+
return floodgateService;
280+
}
281+
289282
/**
290283
* Send warning messages to log if incompatible plugins are used
291284
*/

bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ConnectionListener.java

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
3030
import com.github.games647.fastlogin.bukkit.task.FloodgateAuthTask;
3131
import com.github.games647.fastlogin.bukkit.task.ForceLoginTask;
32+
import com.github.games647.fastlogin.core.hooks.FloodgateService;
3233

3334
import org.bukkit.Bukkit;
3435
import org.bukkit.entity.Player;
@@ -38,9 +39,8 @@
3839
import org.bukkit.event.player.PlayerJoinEvent;
3940
import org.bukkit.event.player.PlayerLoginEvent;
4041
import org.bukkit.event.player.PlayerLoginEvent.Result;
41-
import org.geysermc.floodgate.api.FloodgateApi;
42-
import org.geysermc.floodgate.api.player.FloodgatePlayer;
4342
import org.bukkit.event.player.PlayerQuitEvent;
43+
import org.geysermc.floodgate.api.player.FloodgatePlayer;
4444

4545
/**
4646
* This listener tells authentication plugins if the player has a premium account and we checked it successfully. So the
@@ -69,37 +69,38 @@ public void onPlayerJoin(PlayerJoinEvent joinEvent) {
6969
Player player = joinEvent.getPlayer();
7070

7171
Bukkit.getScheduler().runTaskLater(plugin, () -> {
72-
// session exists so the player is ready for force login
73-
// cases: Paper (firing BungeeCord message before PlayerJoinEvent) or not running BungeeCord and already
74-
// having the login session from the login process
75-
BukkitLoginSession session = plugin.getSession(player.getAddress());
76-
77-
boolean isFloodgateLogin = false;
78-
if (Bukkit.getServer().getPluginManager().isPluginEnabled("floodgate")) {
79-
FloodgatePlayer floodgatePlayer = FloodgateApi.getInstance().getPlayer(player.getUniqueId());
80-
if (floodgatePlayer != null) {
81-
isFloodgateLogin = true;
82-
Runnable floodgateAuthTask = new FloodgateAuthTask(plugin.getCore(), player, floodgatePlayer);
83-
Bukkit.getScheduler().runTaskAsynchronously(plugin, floodgateAuthTask);
84-
}
85-
}
86-
87-
if (!isFloodgateLogin) {
88-
if (session == null) {
89-
String sessionId = plugin.getSessionId(player.getAddress());
90-
plugin.getLog().info("No on-going login session for player: {} with ID {}", player, sessionId);
91-
} else {
92-
Runnable forceLoginTask = new ForceLoginTask(plugin.getCore(), player, session);
93-
Bukkit.getScheduler().runTaskAsynchronously(plugin, forceLoginTask);
94-
}
95-
}
96-
97-
plugin.getBungeeManager().markJoinEventFired(player);
72+
delayForceLogin(player);
9873
// delay the login process to let auth plugins initialize the player
9974
// Magic number however as there is no direct event from those plugins
10075
}, DELAY_LOGIN);
10176
}
10277

78+
private void delayForceLogin(Player player) {
79+
// session exists so the player is ready for force login
80+
// cases: Paper (firing BungeeCord message before PlayerJoinEvent) or not running BungeeCord and already
81+
// having the login session from the login process
82+
BukkitLoginSession session = plugin.getSession(player.getAddress());
83+
FloodgateService floodgateService = plugin.getFloodgateService();
84+
if (floodgateService != null) {
85+
FloodgatePlayer floodgatePlayer = floodgateService.getFloodgatePlayer(player.getUniqueId());
86+
if (floodgatePlayer != null) {
87+
Runnable floodgateAuthTask = new FloodgateAuthTask(plugin.getCore(), player, floodgatePlayer);
88+
Bukkit.getScheduler().runTaskAsynchronously(plugin, floodgateAuthTask);
89+
return;
90+
}
91+
}
92+
93+
if (session == null) {
94+
String sessionId = plugin.getSessionId(player.getAddress());
95+
plugin.getLog().info("No on-going login session for player: {} with ID {}", player, sessionId);
96+
} else {
97+
Runnable forceLoginTask = new ForceLoginTask(plugin.getCore(), player, session);
98+
Bukkit.getScheduler().runTaskAsynchronously(plugin, forceLoginTask);
99+
}
100+
101+
plugin.getBungeeManager().markJoinEventFired(player);
102+
}
103+
103104
@EventHandler
104105
public void onPlayerQuit(PlayerQuitEvent quitEvent) {
105106
Player player = quitEvent.getPlayer();

bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/NameCheckTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
5454

5555
public NameCheckTask(FastLoginBukkit plugin, Random random, Player player, PacketEvent packetEvent,
5656
String username, PublicKey publicKey) {
57-
super(plugin.getCore(), plugin.getCore().getAuthPluginHook());
57+
super(plugin.getCore(), plugin.getCore().getAuthPluginHook(), plugin.getCore().getFloodgateService());
5858

5959
this.plugin = plugin;
6060
this.packetEvent = packetEvent;

bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/ConnectListener.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import com.github.games647.fastlogin.bungee.task.ForceLoginTask;
3434
import com.github.games647.fastlogin.core.RateLimiter;
3535
import com.github.games647.fastlogin.core.StoredProfile;
36+
import com.github.games647.fastlogin.core.hooks.FloodgateService;
3637
import com.github.games647.fastlogin.core.shared.LoginSession;
3738
import com.google.common.base.Throwables;
3839

@@ -56,7 +57,6 @@
5657
import net.md_5.bungee.event.EventHandler;
5758
import net.md_5.bungee.event.EventPriority;
5859

59-
import org.geysermc.floodgate.api.FloodgateApi;
6060
import org.geysermc.floodgate.api.player.FloodgatePlayer;
6161
import org.slf4j.Logger;
6262
import org.slf4j.LoggerFactory;
@@ -184,8 +184,9 @@ public void onServerConnected(ServerConnectedEvent serverConnectedEvent) {
184184
ProxiedPlayer player = serverConnectedEvent.getPlayer();
185185
Server server = serverConnectedEvent.getServer();
186186

187-
if (plugin.isPluginInstalled("floodgate")) {
188-
FloodgatePlayer floodgatePlayer = FloodgateApi.getInstance().getPlayer(player.getUniqueId());
187+
FloodgateService floodgateService = plugin.getFloodgateService();
188+
if (floodgateService != null) {
189+
FloodgatePlayer floodgatePlayer = floodgateService.getFloodgatePlayer(player.getUniqueId());
189190
if (floodgatePlayer != null) {
190191
Runnable floodgateAuthTask = new FloodgateAuthTask(plugin.getCore(), player, floodgatePlayer, server);
191192
plugin.getScheduler().runAsync(floodgateAuthTask);

bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/PluginMessageListener.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,14 @@
2929
import com.github.games647.fastlogin.bungee.FastLoginBungee;
3030
import com.github.games647.fastlogin.bungee.task.AsyncToggleMessage;
3131
import com.github.games647.fastlogin.core.StoredProfile;
32+
import com.github.games647.fastlogin.core.hooks.FloodgateService;
3233
import com.github.games647.fastlogin.core.message.ChangePremiumMessage;
3334
import com.github.games647.fastlogin.core.message.NamespaceKey;
3435
import com.github.games647.fastlogin.core.message.SuccessMessage;
3536
import com.github.games647.fastlogin.core.shared.FastLoginCore;
3637
import com.google.common.io.ByteArrayDataInput;
3738
import com.google.common.io.ByteStreams;
3839

39-
import org.geysermc.floodgate.api.FloodgateApi;
40-
import org.geysermc.floodgate.api.player.FloodgatePlayer;
41-
4240
import java.util.Arrays;
4341

4442
import net.md_5.bungee.api.CommandSender;
@@ -118,13 +116,15 @@ private void readMessage(ProxiedPlayer forPlayer, String channel, byte[] data) {
118116
}
119117

120118
private void onSuccessMessage(ProxiedPlayer forPlayer) {
121-
//check if player is using Floodgate
122-
FloodgatePlayer floodgatePlayer = null;
123-
if (plugin.isPluginInstalled("floodgate")) {
124-
floodgatePlayer = FloodgateApi.getInstance().getPlayer(forPlayer.getUniqueId());
119+
boolean shouldPersist = forPlayer.getPendingConnection().isOnlineMode();
120+
121+
FloodgateService floodgateService = plugin.getFloodgateService();
122+
if (!shouldPersist && floodgateService != null) {
123+
// always save floodgate players to lock this username
124+
shouldPersist = floodgateService.isFloodgatePlayer(forPlayer.getUniqueId());
125125
}
126126

127-
if (forPlayer.getPendingConnection().isOnlineMode() || floodgatePlayer != null){
127+
if (shouldPersist) {
128128
//bukkit module successfully received and force logged in the user
129129
//update only on success to prevent corrupt data
130130
BungeeLoginSession loginSession = plugin.getSession().get(forPlayer.getPendingConnection());

core/src/main/java/com/github/games647/fastlogin/core/hooks/FloodgateHook.java renamed to core/src/main/java/com/github/games647/fastlogin/core/hooks/FloodgateService.java

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,56 @@
2727

2828
import com.github.games647.craftapi.model.Profile;
2929
import com.github.games647.craftapi.resolver.RateLimitException;
30+
import com.github.games647.fastlogin.core.StoredProfile;
3031
import com.github.games647.fastlogin.core.shared.FastLoginCore;
3132
import com.github.games647.fastlogin.core.shared.LoginSource;
3233

3334
import java.io.IOException;
35+
import java.util.Locale;
3436
import java.util.Optional;
37+
import java.util.UUID;
3538

3639
import org.geysermc.floodgate.api.FloodgateApi;
3740
import org.geysermc.floodgate.api.player.FloodgatePlayer;
3841

39-
public class FloodgateHook<P extends C, C, S extends LoginSource> {
42+
public class FloodgateService {
4043

41-
private final FastLoginCore<P, C, ?> core;
44+
private final FastLoginCore<?, ?, ?> core;
4245

43-
public FloodgateHook(FastLoginCore<P, C, ?> core) {
46+
public FloodgateService(FastLoginCore<?, ?, ?> core) {
4447
this.core = core;
4548
}
4649

50+
/**
51+
* Checks if a config entry (related to Floodgate) is valid. <br>
52+
* Writes to Log if the value is invalid.
53+
* <p>
54+
* This should be used for:
55+
* <ul>
56+
* <li>allowFloodgateNameConflict
57+
* <li>autoLoginFloodgate
58+
* <li>autoRegisterFloodgate
59+
* </ul>
60+
* </p>
61+
*
62+
* @param key the key of the entry in config.yml
63+
* @return <b>true</b> if the entry's value is "true", "false", or "linked"
64+
*/
65+
public boolean isValidFloodgateConfigString(String key) {
66+
String value = core.getConfig().get(key).toString().toLowerCase(Locale.ENGLISH);
67+
if (!value.equals("true") && !value.equals("linked") && !value.equals("false") && !value.equals("no-conflict")) {
68+
core.getPlugin().getLog().error("Invalid value detected for {} in FastLogin/config.yml.", key);
69+
return false;
70+
}
71+
72+
return true;
73+
}
74+
75+
public boolean isUsernameForbidden(StoredProfile profile) {
76+
String playerPrefix = FloodgateApi.getInstance().getPlayerPrefix();
77+
return profile.getName().startsWith(playerPrefix) && !playerPrefix.isEmpty();
78+
}
79+
4780
/**
4881
* Check if the player's name conflicts an existing Java player's name, and
4982
* kick them if it does
@@ -55,24 +88,24 @@ public void checkFloodgateNameConflict(String username, LoginSource source, Floo
5588
String allowConflict = core.getConfig().get("allowFloodgateNameConflict").toString().toLowerCase();
5689

5790
// check if the Bedrock player is linked to a Java account
58-
boolean isLinked = ((FloodgatePlayer) floodgatePlayer).getLinkedPlayer() != null;
91+
boolean isLinked = floodgatePlayer.getLinkedPlayer() != null;
5992

60-
if (allowConflict.equals("false")
61-
|| allowConflict.equals("linked") && !isLinked) {
93+
if ("false".equals(allowConflict)
94+
|| "linked".equals(allowConflict) && !isLinked) {
6295

6396
// check for conflicting Premium Java name
6497
Optional<Profile> premiumUUID = Optional.empty();
6598
try {
6699
premiumUUID = core.getResolver().findProfile(username);
67100
} catch (IOException | RateLimitException e) {
68101
core.getPlugin().getLog().error(
69-
"Could not check wether Floodgate Player {}'s name conflicts a premium Java player's name.",
102+
"Could not check whether Floodgate Player {}'s name conflicts a premium Java player's name.",
70103
username);
71104
try {
72105
source.kick("Could not check if your name conflicts an existing premium Java account's name.\n"
73106
+ "This is usually a serverside error.");
74-
} catch (Exception e1) {
75-
core.getPlugin().getLog().error("Could not kick Player {}", username);
107+
} catch (Exception ex) {
108+
core.getPlugin().getLog().error("Could not kick Player {}", username, ex);
76109
}
77110
}
78111

@@ -81,8 +114,8 @@ public void checkFloodgateNameConflict(String username, LoginSource source, Floo
81114
username);
82115
try {
83116
source.kick("Your name conflicts an existing premium Java account's name");
84-
} catch (Exception e) {
85-
core.getPlugin().getLog().error("Could not kick Player {}", username);
117+
} catch (Exception ex) {
118+
core.getPlugin().getLog().error("Could not kick Player {}", username, ex);
86119
}
87120
}
88121
} else {
@@ -99,14 +132,25 @@ public void checkFloodgateNameConflict(String username, LoginSource source, Floo
99132
* @return FloodgatePlayer if found, null otherwise
100133
*/
101134
public FloodgatePlayer getFloodgatePlayer(String username) {
102-
if (core.getPlugin().isPluginInstalled("floodgate")) {
103-
for (FloodgatePlayer floodgatePlayer : FloodgateApi.getInstance().getPlayers()) {
104-
if (floodgatePlayer.getUsername().equals(username)) {
105-
return floodgatePlayer;
106-
}
135+
for (FloodgatePlayer floodgatePlayer : FloodgateApi.getInstance().getPlayers()) {
136+
if (floodgatePlayer.getUsername().equals(username)) {
137+
return floodgatePlayer;
107138
}
108139
}
109140

110141
return null;
111142
}
143+
144+
public FloodgatePlayer getFloodgatePlayer(UUID uuid) {
145+
return FloodgateApi.getInstance().getPlayer(uuid);
146+
}
147+
148+
public boolean isFloodgatePlayer(UUID uuid) {
149+
return getFloodgatePlayer(uuid) != null;
150+
}
151+
152+
public boolean isFloodgateConnection(String username) {
153+
return getFloodgatePlayer(username) != null;
154+
155+
}
112156
}

0 commit comments

Comments
 (0)