Share Floodgate name conflict check between Protocol Plugins

Added a shared class for Floodgate name conflict checking that can be used by both ProtocolLib and ProtocolSupport

Rebased on Sat May 22 11:42:08 2021 +0200
Added access modifier to "FastLoginBukkit plugin;" in FloodgateHook.java

Rebased on Sat May 22 11:42:08 2021 +0200
Initialize FloogateHook in ProtocolLib's class
This commit is contained in:
Smart123s
2021-05-22 11:42:08 +02:00
parent 119b9cb000
commit 1f3cd5fa5b
3 changed files with 102 additions and 22 deletions

View File

@ -0,0 +1,81 @@
package com.github.games647.fastlogin.bukkit.hook.floodgate;
import java.io.IOException;
import java.util.Optional;
import org.bukkit.Bukkit;
import org.geysermc.floodgate.api.FloodgateApi;
import org.geysermc.floodgate.api.player.FloodgatePlayer;
import com.github.games647.craftapi.model.Profile;
import com.github.games647.craftapi.resolver.RateLimitException;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.core.shared.LoginSource;
public class FloodgateHook {
private final FastLoginBukkit plugin;
public FloodgateHook(FastLoginBukkit plugin) {
this.plugin = plugin;
}
/**
* Check if the player's name conflict's an existing Java player's name, and
* kick them if it does
*
* @param core the FastLoginCore
* @param username the name of the player
* @param source an instance of LoginSource
* @param plugin the FastLoginBukkit plugin
*/
public void checkNameConflict(String username, LoginSource source, FloodgatePlayer floodgatePlayer) {
String allowConflict = plugin.getCore().getConfig().get("allowFloodgateNameConflict").toString().toLowerCase();
if (allowConflict.equals("false")) {
// check for conflicting Premium Java name
Optional<Profile> premiumUUID = Optional.empty();
try {
premiumUUID = plugin.getCore().getResolver().findProfile(username);
} catch (IOException | RateLimitException e) {
e.printStackTrace();
plugin.getLog().error(
"Could not check wether Floodgate Player {}'s name conflits a premium Java player's name.",
username);
}
if (premiumUUID.isPresent()) {
plugin.getLog().info("Bedrock Player {}'s name conflits an existing Java Premium Player's name",
username);
try {
source.kick("Your name conflits an existing Java Premium Player's name");
} catch (Exception e) {
e.printStackTrace();
plugin.getLog().error("Could not kick Player {}", username);
}
}
} else {
plugin.getLog().info("Skipping name conflict checking for player {}", username);
}
}
/**
* The FloodgateApi does not support querying players by name, so this function
* iterates over every online FloodgatePlayer and checks if the requested
* username can be found
*
* @param username the name of the player
* @return FloodgatePlayer if found, null otherwise
*/
public FloodgatePlayer getFloodgatePlayer(String username) {
if (Bukkit.getServer().getPluginManager().isPluginEnabled("floodgate")) {
for (FloodgatePlayer floodgatePlayer : FloodgateApi.getInstance().getPlayers()) {
if (floodgatePlayer.getUsername().equals(username)) {
return floodgatePlayer;
}
}
}
return null;
}
}

View File

@ -30,6 +30,7 @@ import com.comphenix.protocol.events.PacketEvent;
import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.bukkit.event.BukkitFastLoginPreLoginEvent;
import com.github.games647.fastlogin.bukkit.hook.floodgate.FloodgateHook;
import com.github.games647.fastlogin.core.StoredProfile;
import com.github.games647.fastlogin.core.shared.JoinManagement;
import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent;
@ -37,10 +38,8 @@ import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent;
import java.security.PublicKey;
import java.util.Random;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.geysermc.floodgate.api.FloodgateApi;
import org.geysermc.floodgate.api.player.FloodgatePlayer;
public class NameCheckTask extends JoinManagement<Player, CommandSender, ProtocolLibLoginSource>
@ -55,8 +54,10 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
private final Player player;
private final String username;
private final FloodgateHook floodgateHook;
public NameCheckTask(FastLoginBukkit plugin, PacketEvent packetEvent, Random random,
Player player, String username, PublicKey publicKey) {
Player player, String username, PublicKey publicKey, FloodgateHook floodgateHook) {
super(plugin.getCore(), plugin.getCore().getAuthPluginHook());
this.plugin = plugin;
@ -65,18 +66,23 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
this.random = random;
this.player = player;
this.username = username;
this.floodgateHook = floodgateHook;
}
@Override
public void run() {
try {
// check if the player is connecting through Geyser
if (!plugin.getCore().getConfig().get("allowFloodgateNameConflict").toString().equalsIgnoreCase("false")
&& getFloodgatePlayer(username) != null) {
plugin.getLog().info("Skipping name conflict checking for player {}", username);
return;
ProtocolLibLoginSource source = new ProtocolLibLoginSource(packetEvent, player, random, publicKey);
//check if the player is connecting through Floodgate
FloodgatePlayer floodgatePlayer = floodgateHook.getFloodgatePlayer(username);
if (floodgatePlayer != null) {
floodgateHook.checkNameConflict(username, source, floodgatePlayer);
} else {
//do Java login tasks
super.onLogin(username, source);
}
super.onLogin(username, new ProtocolLibLoginSource(packetEvent, player, random, publicKey));
} finally {
ProtocolLibrary.getProtocolManager().getAsynchronousManager().signalPacketTransmission(packetEvent);
}
@ -120,16 +126,5 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
BukkitLoginSession loginSession = new BukkitLoginSession(username, profile);
plugin.putSession(player.getAddress(), loginSession);
}
private static FloodgatePlayer getFloodgatePlayer(String username) {
if (Bukkit.getServer().getPluginManager().isPluginEnabled("floodgate")) {
// the Floodgate API requires UUID, which is inaccessible at NameCheckTask.java
for (FloodgatePlayer floodgatePlayer : FloodgateApi.getInstance().getPlayers()) {
if (floodgatePlayer.getUsername().equals(username)) {
return floodgatePlayer;
}
}
}
return null;
}
}

View File

@ -31,6 +31,7 @@ import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.bukkit.hook.floodgate.FloodgateHook;
import com.github.games647.fastlogin.core.RateLimiter;
import java.security.KeyPair;
@ -49,6 +50,7 @@ public class ProtocolLibListener extends PacketAdapter {
private final SecureRandom random = new SecureRandom();
private final KeyPair keyPair = EncryptionUtil.generateKeyPair();
private final RateLimiter rateLimiter;
private final FloodgateHook floodgateHook;
public ProtocolLibListener(FastLoginBukkit plugin, RateLimiter rateLimiter) {
//run async in order to not block the server, because we are making api calls to Mojang
@ -59,6 +61,7 @@ public class ProtocolLibListener extends PacketAdapter {
this.plugin = plugin;
this.rateLimiter = rateLimiter;
this.floodgateHook = new FloodgateHook(plugin);
}
public static void register(FastLoginBukkit plugin, RateLimiter rateLimiter) {
@ -113,7 +116,8 @@ public class ProtocolLibListener extends PacketAdapter {
plugin.getLog().trace("GameProfile {} with {} connecting", sessionKey, username);
packetEvent.getAsyncMarker().incrementProcessingDelay();
Runnable nameCheckTask = new NameCheckTask(plugin, packetEvent, random, player, username, keyPair.getPublic());
Runnable nameCheckTask = new NameCheckTask(plugin, packetEvent, random, player, username, keyPair.getPublic(),
floodgateHook);
plugin.getScheduler().runAsync(nameCheckTask);
}
}