mirror of
https://github.com/TuxCoding/FastLogin.git
synced 2025-07-29 18:27:36 +02:00
Merge pull request #532 from Smart123s/fg-bk-ncshare
Share Floodgate name conflict check between Protocol Plugins
This commit is contained in:
@ -276,7 +276,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
|
||||
* @param name the name of the plugin
|
||||
* @return true if the plugin is installed
|
||||
*/
|
||||
private boolean isPluginInstalled(String name) {
|
||||
public boolean isPluginInstalled(String name) {
|
||||
//the plugin may be enabled after FastLogin, so isPluginEnabled()
|
||||
//won't work here
|
||||
return Bukkit.getServer().getPluginManager().getPlugin(name) != null;
|
||||
|
@ -37,11 +37,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>
|
||||
implements Runnable {
|
||||
@ -55,6 +52,7 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
|
||||
private final Player player;
|
||||
private final String username;
|
||||
|
||||
|
||||
public NameCheckTask(FastLoginBukkit plugin, PacketEvent packetEvent, Random random,
|
||||
Player player, String username, PublicKey publicKey) {
|
||||
super(plugin.getCore(), plugin.getCore().getAuthPluginHook());
|
||||
@ -70,12 +68,6 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
|
||||
@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;
|
||||
}
|
||||
super.onLogin(username, new ProtocolLibLoginSource(packetEvent, player, random, publicKey));
|
||||
} finally {
|
||||
ProtocolLibrary.getProtocolManager().getAsynchronousManager().signalPacketTransmission(packetEvent);
|
||||
@ -119,16 +111,4 @@ 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;
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import protocolsupport.api.events.ConnectionCloseEvent;
|
||||
import protocolsupport.api.events.PlayerLoginStartEvent;
|
||||
import protocolsupport.api.events.PlayerProfileCompleteEvent;
|
||||
@ -75,7 +76,8 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
|
||||
//remove old data every time on a new login in order to keep the session only for one person
|
||||
plugin.removeSession(address);
|
||||
|
||||
super.onLogin(username, new ProtocolLoginSource(loginStartEvent));
|
||||
ProtocolLoginSource source = new ProtocolLoginSource(loginStartEvent);
|
||||
super.onLogin(username, source);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -51,25 +51,10 @@ public class FloodgateAuthTask implements Runnable {
|
||||
plugin.getLog().info(
|
||||
"Player {} is connecting through Geyser Floodgate.",
|
||||
player.getName());
|
||||
String allowNameConflict = plugin.getCore().getConfig().get("allowFloodgateNameConflict").toString().toLowerCase();
|
||||
|
||||
// check if the Bedrock player is linked to a Java account
|
||||
boolean isLinked = floodgatePlayer.getLinkedPlayer() != null;
|
||||
if (allowNameConflict.equals("linked") && !isLinked) {
|
||||
plugin.getLog().info(
|
||||
"Bedrock Player {}'s name conflits an existing Java Premium Player's name",
|
||||
player.getName());
|
||||
|
||||
// kicking must be synchronous
|
||||
// https://www.spigotmc.org/threads/asynchronous-player-kick-problem.168580/
|
||||
Bukkit.getScheduler().runTask(plugin, new Runnable() {
|
||||
public void run() {
|
||||
player.kickPlayer("This name is allready in use by a Premium Java Player");
|
||||
}
|
||||
});
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
AuthPlugin<Player> authPlugin = plugin.getCore().getAuthPluginHook();
|
||||
|
||||
String autoLoginFloodgate = plugin.getCore().getConfig().get("autoLoginFloodgate").toString().toLowerCase();
|
||||
|
@ -50,6 +50,7 @@ import java.util.List;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import net.md_5.bungee.BungeeServerInfo;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
@ -187,4 +188,9 @@ public class FastLoginBungee extends Plugin implements PlatformPlugin<CommandSen
|
||||
public AsyncScheduler getScheduler() {
|
||||
return scheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPluginInstalled(String name) {
|
||||
return getProxy().getPluginManager().getPlugin(name) != null;
|
||||
}
|
||||
}
|
||||
|
13
core/pom.xml
13
core/pom.xml
@ -53,6 +53,11 @@
|
||||
<id>codemc-repo</id>
|
||||
<url>https://repo.codemc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
<!-- Floodgate -->
|
||||
<repository>
|
||||
<id>nukkitx-snapshot</id>
|
||||
<url>https://repo.nukkitx.com/maven-snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
@ -85,6 +90,14 @@
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!--Floodgate for Xbox Live Authentication-->
|
||||
<dependency>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--Common component for contacting the Mojang API-->
|
||||
<dependency>
|
||||
<groupId>com.github.games647</groupId>
|
||||
|
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015-2021 <Your name and contributors>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.github.games647.fastlogin.core.hooks;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.github.games647.craftapi.model.Profile;
|
||||
import com.github.games647.craftapi.resolver.RateLimitException;
|
||||
import com.github.games647.fastlogin.core.shared.FastLoginCore;
|
||||
import com.github.games647.fastlogin.core.shared.LoginSource;
|
||||
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
|
||||
public class FloodgateHook<P extends C, C, S extends LoginSource> {
|
||||
|
||||
private final FastLoginCore<P, C, ?> core;
|
||||
|
||||
public FloodgateHook(FastLoginCore<P, C, ?> core) {
|
||||
this.core = core;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the player's name conflicts an existing Java player's name, and
|
||||
* kick them if it does
|
||||
*
|
||||
* @param username the name of the player
|
||||
* @param source an instance of LoginSource
|
||||
*/
|
||||
public void checkFloodgateNameConflict(String username, LoginSource source, FloodgatePlayer floodgatePlayer) {
|
||||
String allowConflict = core.getConfig().get("allowFloodgateNameConflict").toString().toLowerCase();
|
||||
|
||||
// check if the Bedrock player is linked to a Java account
|
||||
boolean isLinked = ((FloodgatePlayer) floodgatePlayer).getLinkedPlayer() != null;
|
||||
|
||||
if (allowConflict.equals("false")
|
||||
|| allowConflict.equals("linked") && !isLinked) {
|
||||
|
||||
// check for conflicting Premium Java name
|
||||
Optional<Profile> premiumUUID = Optional.empty();
|
||||
try {
|
||||
premiumUUID = core.getResolver().findProfile(username);
|
||||
} catch (IOException | RateLimitException e) {
|
||||
core.getPlugin().getLog().error(
|
||||
"Could not check wether Floodgate Player {}'s name conflicts a premium Java player's name.",
|
||||
username);
|
||||
try {
|
||||
source.kick("Could not check if your name conflicts an existing Java Premium Player's name");
|
||||
} catch (Exception e1) {
|
||||
core.getPlugin().getLog().error("Could not kick Player {}", username);
|
||||
}
|
||||
}
|
||||
|
||||
if (premiumUUID.isPresent()) {
|
||||
core.getPlugin().getLog().info("Bedrock Player {}'s name conflicts an existing Java Premium Player's name",
|
||||
username);
|
||||
try {
|
||||
source.kick("Your name conflicts an existing Java Premium Player's name");
|
||||
} catch (Exception e) {
|
||||
core.getPlugin().getLog().error("Could not kick Player {}", username);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
core.getPlugin().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 (core.getPlugin().isPluginInstalled("floodgate")) {
|
||||
for (FloodgatePlayer floodgatePlayer : FloodgateApi.getInstance().getPlayers()) {
|
||||
if (floodgatePlayer.getUsername().equals(username)) {
|
||||
return floodgatePlayer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -29,20 +29,25 @@ import com.github.games647.craftapi.model.Profile;
|
||||
import com.github.games647.craftapi.resolver.RateLimitException;
|
||||
import com.github.games647.fastlogin.core.StoredProfile;
|
||||
import com.github.games647.fastlogin.core.hooks.AuthPlugin;
|
||||
import com.github.games647.fastlogin.core.hooks.FloodgateHook;
|
||||
import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
|
||||
import net.md_5.bungee.config.Configuration;
|
||||
|
||||
public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
|
||||
|
||||
protected final FastLoginCore<P, C, ?> core;
|
||||
protected final AuthPlugin<P> authHook;
|
||||
private final FloodgateHook<P, C, ?> floodgateHook;
|
||||
|
||||
public JoinManagement(FastLoginCore<P, C, ?> core, AuthPlugin<P> authHook) {
|
||||
this.core = core;
|
||||
this.authHook = authHook;
|
||||
this.floodgateHook = new FloodgateHook<>(core);
|
||||
}
|
||||
|
||||
public void onLogin(String username, S source) {
|
||||
@ -52,6 +57,13 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
|
||||
return;
|
||||
}
|
||||
|
||||
//check if the player is connecting through Floodgate
|
||||
FloodgatePlayer floodgatePlayer = floodgateHook.getFloodgatePlayer(username);
|
||||
|
||||
if (floodgatePlayer != null) {
|
||||
floodgateHook.checkFloodgateNameConflict(username, source, floodgatePlayer);
|
||||
return;
|
||||
}
|
||||
callFastLoginPreLoginEvent(username, source, profile);
|
||||
|
||||
Configuration config = core.getConfig();
|
||||
|
@ -45,6 +45,8 @@ public interface PlatformPlugin<C> {
|
||||
|
||||
AsyncScheduler getScheduler();
|
||||
|
||||
boolean isPluginInstalled(String name);
|
||||
|
||||
default void sendMultiLineMessage(C receiver, String message) {
|
||||
for (String line : message.split("%nl%")) {
|
||||
sendMessage(receiver, line);
|
||||
|
Reference in New Issue
Block a user