diff --git a/CHANGELOG.md b/CHANGELOG.md index a96540af..6dbef751 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,9 +16,11 @@ ## Removed +Dropped some features listed below. Please contact us if you still need them + * Dropped Java support < 11 * Removed configuration option to add multiple outgoing IPv4 towards Mojang - * Was this really used? +* Dropped support for ProtocolSupport seems to unsupported [...] A lot of changes diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BukkitLoginSession.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BukkitLoginSession.java index 8194e4e1..72b4b72f 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BukkitLoginSession.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BukkitLoginSession.java @@ -26,7 +26,7 @@ package com.github.games647.fastlogin.bukkit; import com.github.games647.craftapi.model.skin.SkinProperty; -import com.github.games647.fastlogin.bukkit.listener.protocollib.packet.ClientPublicKey; +import com.github.games647.fastlogin.bukkit.auth.protocollib.packet.ClientPublicKey; import com.github.games647.fastlogin.core.shared.LoginSession; import com.github.games647.fastlogin.core.storage.StoredProfile; import org.jetbrains.annotations.Nullable; diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java index 2f58615d..99a59c61 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java @@ -25,23 +25,21 @@ */ package com.github.games647.fastlogin.bukkit; -import com.comphenix.protocol.ProtocolLibrary; +import com.github.games647.fastlogin.bukkit.auth.AuthenticationBackend; +import com.github.games647.fastlogin.bukkit.auth.ConnectionListener; +import com.github.games647.fastlogin.bukkit.auth.protocollib.ProtocolAuthentication; +import com.github.games647.fastlogin.bukkit.auth.proxy.ProxyAuthentication; import com.github.games647.fastlogin.bukkit.command.CrackedCommand; import com.github.games647.fastlogin.bukkit.command.PremiumCommand; -import com.github.games647.fastlogin.bukkit.listener.ConnectionListener; -import com.github.games647.fastlogin.bukkit.listener.PaperCacheListener; -import com.github.games647.fastlogin.bukkit.listener.protocollib.ProtocolLibListener; -import com.github.games647.fastlogin.bukkit.listener.protocollib.SkinApplyListener; -import com.github.games647.fastlogin.bukkit.listener.protocolsupport.ProtocolSupportListener; -import com.github.games647.fastlogin.bukkit.task.DelayedAuthHook; +import com.github.games647.fastlogin.bukkit.hook.DelayedAuthHook; import com.github.games647.fastlogin.core.CommonUtil; import com.github.games647.fastlogin.core.PremiumStatus; -import com.github.games647.fastlogin.core.antibot.AntiBotService; 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.GeyserService; import com.github.games647.fastlogin.core.shared.FastLoginCore; import com.github.games647.fastlogin.core.shared.PlatformPlugin; +import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -71,18 +69,26 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin premiumPlayers = new ConcurrentHashMap<>(); private final Logger logger; - private boolean serverStarted; - private BungeeManager bungeeManager; private final BukkitScheduler scheduler; + + @Getter private FastLoginCore core; + + @Getter private FloodgateService floodgateService; private GeyserService geyserService; private PremiumPlaceholder premiumPlaceholder; + private AuthenticationBackend backend; + + @Getter + private boolean initialized; + public FastLoginBukkit() { this.logger = CommonUtil.initializeLoggerService(getLogger()); this.scheduler = new BukkitScheduler(this, logger); @@ -104,51 +110,42 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin getCore() { - return core; } /** @@ -232,10 +217,6 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin getPremiumPlayers() { - return premiumPlayers; - } - /** * Fetches the premium status of an online player. * {@snippet : @@ -263,24 +244,6 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin> isClassAvailable(String clazzName) { - try { - return Optional.of(Class.forName(clazzName)); - } catch (ClassNotFoundException e) { - return Optional.empty(); - } - } } diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolLoginSource.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/AuthenticationBackend.java similarity index 52% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolLoginSource.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/AuthenticationBackend.java index d7f8b494..63ed92cb 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolLoginSource.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/AuthenticationBackend.java @@ -23,44 +23,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit.listener.protocolsupport; +package com.github.games647.fastlogin.bukkit.auth; -import com.github.games647.fastlogin.core.shared.LoginSource; -import protocolsupport.api.events.PlayerLoginStartEvent; +import org.bukkit.plugin.PluginManager; -import java.net.InetSocketAddress; +public interface AuthenticationBackend { -public class ProtocolLoginSource implements LoginSource { + boolean isAvailable(); - private final PlayerLoginStartEvent loginStartEvent; + void init(PluginManager pluginManager); - public ProtocolLoginSource(PlayerLoginStartEvent loginStartEvent) { - this.loginStartEvent = loginStartEvent; - } - - @Override - public void enableOnlinemode() { - loginStartEvent.setOnlineMode(true); - } - - @Override - public void kick(String message) { - loginStartEvent.denyLogin(message); - } - - @Override - public InetSocketAddress getAddress() { - return loginStartEvent.getConnection().getRawAddress(); - } - - public PlayerLoginStartEvent getLoginStartEvent() { - return loginStartEvent; - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + '{' - + "loginStartEvent=" + loginStartEvent - + '}'; - } + void stop(); } diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ConnectionListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/ConnectionListener.java similarity index 81% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ConnectionListener.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/ConnectionListener.java index 2bacbc5d..45579241 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ConnectionListener.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/ConnectionListener.java @@ -23,23 +23,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit.listener; +package com.github.games647.fastlogin.bukkit.auth; import com.github.games647.fastlogin.bukkit.BukkitLoginSession; import com.github.games647.fastlogin.bukkit.FastLoginBukkit; -import com.github.games647.fastlogin.bukkit.task.FloodgateAuthTask; -import com.github.games647.fastlogin.bukkit.task.ForceLoginTask; import com.github.games647.fastlogin.core.hooks.bedrock.FloodgateService; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerLoginEvent; -import org.bukkit.event.player.PlayerLoginEvent.Result; import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.metadata.Metadatable; import org.geysermc.floodgate.api.player.FloodgatePlayer; /** @@ -56,14 +50,6 @@ public class ConnectionListener implements Listener { this.plugin = plugin; } - @EventHandler(priority = EventPriority.LOWEST) - public void onPlayerLogin(PlayerLoginEvent loginEvent) { - removeBlockedStatus(loginEvent.getPlayer()); - if (loginEvent.getResult() == Result.ALLOWED && !plugin.isServerFullyStarted()) { - loginEvent.disallow(Result.KICK_OTHER, plugin.getCore().getMessage("not-started")); - } - } - @EventHandler(ignoreCancelled = true) public void onPlayerJoin(PlayerJoinEvent joinEvent) { Player player = joinEvent.getPlayer(); @@ -102,21 +88,13 @@ public class ConnectionListener implements Listener { Runnable forceLoginTask = new ForceLoginTask(plugin.getCore(), player, session); Bukkit.getScheduler().runTaskAsynchronously(plugin, forceLoginTask); } - - plugin.getBungeeManager().markJoinEventFired(player); } @EventHandler public void onPlayerQuit(PlayerQuitEvent quitEvent) { Player player = quitEvent.getPlayer(); - removeBlockedStatus(player); plugin.getCore().getPendingConfirms().remove(player.getUniqueId()); plugin.getPremiumPlayers().remove(player.getUniqueId()); - plugin.getBungeeManager().cleanup(player); - } - - private void removeBlockedStatus(Metadatable player) { - player.removeMetadata(plugin.getName(), plugin); } } diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/task/FloodgateAuthTask.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/FloodgateAuthTask.java similarity index 98% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/task/FloodgateAuthTask.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/FloodgateAuthTask.java index 64d2977a..d11ac2ea 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/task/FloodgateAuthTask.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/FloodgateAuthTask.java @@ -23,7 +23,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit.task; +package com.github.games647.fastlogin.bukkit.auth; import com.github.games647.fastlogin.bukkit.BukkitLoginSession; import com.github.games647.fastlogin.bukkit.FastLoginBukkit; diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/task/ForceLoginTask.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/ForceLoginTask.java similarity index 98% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/task/ForceLoginTask.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/ForceLoginTask.java index e5daaf55..b300c6ae 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/task/ForceLoginTask.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/ForceLoginTask.java @@ -23,7 +23,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit.task; +package com.github.games647.fastlogin.bukkit.auth; import com.github.games647.fastlogin.bukkit.BukkitLoginSession; import com.github.games647.fastlogin.bukkit.FastLoginBukkit; diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/InetUtils.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/InetUtils.java similarity index 98% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/InetUtils.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/InetUtils.java index 24cf053c..3d3bdf9f 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/InetUtils.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/InetUtils.java @@ -23,7 +23,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit; +package com.github.games647.fastlogin.bukkit.auth; import java.net.InetAddress; diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/LocalAuthentication.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/LocalAuthentication.java new file mode 100644 index 00000000..0fa2ebd4 --- /dev/null +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/LocalAuthentication.java @@ -0,0 +1,70 @@ +/* + * SPDX-License-Identifier: MIT + * + * The MIT License (MIT) + * + * Copyright (c) 2015-2024 games647 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.bukkit.auth; + +import com.github.games647.fastlogin.bukkit.FastLoginBukkit; +import com.github.games647.fastlogin.bukkit.auth.protocollib.SkinApplyListener; +import org.bukkit.plugin.PluginManager; + +import java.util.Optional; + +public abstract class LocalAuthentication implements AuthenticationBackend { + + protected final FastLoginBukkit plugin; + + protected LocalAuthentication(FastLoginBukkit plugin) { + this.plugin = plugin; + } + + @Override + public void init(PluginManager pluginManager) { + if (!plugin.getCore().setupDatabase()) { + plugin.setEnabled(false); + return; + } + + // if server is using paper - we need to add one more listener to correct the user cache usage + if (isPaper()) { + pluginManager.registerEvents(new PaperCacheListener(this), this); + } else if (plugin.getConfig().getBoolean("forwardSkin")) { + //if server is using paper - we need to set the skin at pre login anyway, so no need for this listener + pluginManager.registerEvents(new SkinApplyListener(plugin), plugin); + } + } + + private boolean isPaper() { + return isClassAvailable("com.destroystokyo.paper.PaperConfig").isPresent() + || isClassAvailable("io.papermc.paper.configuration.Configuration").isPresent(); + } + + private Optional> isClassAvailable(String clazzName) { + try { + return Optional.of(Class.forName(clazzName)); + } catch (ClassNotFoundException e) { + return Optional.empty(); + } + } +} diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/PaperCacheListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/PaperCacheListener.java similarity index 98% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/PaperCacheListener.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/PaperCacheListener.java index acc9c124..ceae9fdd 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/PaperCacheListener.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/PaperCacheListener.java @@ -23,7 +23,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit.listener; +package com.github.games647.fastlogin.bukkit.auth; import com.destroystokyo.paper.profile.ProfileProperty; import com.github.games647.craftapi.model.skin.Textures; diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/EncryptionUtil.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/EncryptionUtil.java index f1228885..c0d853c2 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/EncryptionUtil.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/EncryptionUtil.java @@ -23,10 +23,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit.listener.protocollib; +package com.github.games647.fastlogin.bukkit.auth.protocollib; import com.github.games647.fastlogin.bukkit.FastLoginBukkit; -import com.github.games647.fastlogin.bukkit.listener.protocollib.packet.ClientPublicKey; +import com.github.games647.fastlogin.bukkit.auth.protocollib.packet.ClientPublicKey; import com.google.common.hash.Hasher; import com.google.common.hash.Hashing; import com.google.common.io.Resources; @@ -58,8 +58,8 @@ import java.time.Instant; import java.util.Arrays; import java.util.Base64; import java.util.Base64.Encoder; +import java.util.Random; import java.util.UUID; -import java.util.random.RandomGenerator; /** * Encryption and decryption minecraft util for connection between servers diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/NameCheckTask.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/NameCheckTask.java similarity index 96% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/NameCheckTask.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/NameCheckTask.java index 05c23e62..06d700e2 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/NameCheckTask.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/NameCheckTask.java @@ -23,14 +23,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit.listener.protocollib; +package com.github.games647.fastlogin.bukkit.auth.protocollib; import com.comphenix.protocol.ProtocolLibrary; 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.auth.protocollib.packet.ClientPublicKey; import com.github.games647.fastlogin.bukkit.event.BukkitFastLoginPreLoginEvent; -import com.github.games647.fastlogin.bukkit.listener.protocollib.packet.ClientPublicKey; import com.github.games647.fastlogin.core.shared.JoinManagement; import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent; import com.github.games647.fastlogin.core.storage.StoredProfile; diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/ProtocolAuthentication.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/ProtocolAuthentication.java new file mode 100644 index 00000000..768b33f4 --- /dev/null +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/ProtocolAuthentication.java @@ -0,0 +1,72 @@ +/* + * SPDX-License-Identifier: MIT + * + * The MIT License (MIT) + * + * Copyright (c) 2015-2024 games647 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.bukkit.auth.protocollib; + +import com.comphenix.protocol.ProtocolLibrary; +import com.github.games647.fastlogin.bukkit.FastLoginBukkit; +import com.github.games647.fastlogin.bukkit.auth.LocalAuthentication; +import com.github.games647.fastlogin.core.antibot.AntiBotService; +import com.github.games647.fastlogin.core.shared.FastLoginCore; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.plugin.PluginManager; + +public class ProtocolAuthentication extends LocalAuthentication implements Listener { + + public ProtocolAuthentication(FastLoginBukkit plugin) { + super(plugin); + } + + @Override + public boolean isAvailable() { + return plugin.getServer().getPluginManager().isPluginEnabled("ProtocolLib"); + } + + @Override + public void init(PluginManager pluginManager) { + pluginManager.registerEvents(this, plugin); + + FastLoginCore core = plugin.getCore(); + AntiBotService antiBotService = core.getAntiBotService(); + ProtocolLibListener.register(plugin, antiBotService, core.getConfig().getBoolean("verifyClientKeys")); + } + + @Override + public void stop() { + ProtocolLibrary.getProtocolManager().getAsynchronousManager().unregisterAsyncHandlers(plugin); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerLogin(PlayerLoginEvent loginEvent) { + if (loginEvent.getResult() == PlayerLoginEvent.Result.ALLOWED && !plugin.isInitialized()) { + loginEvent.disallow(PlayerLoginEvent.Result.KICK_OTHER, plugin.getCore().getMessage("not-started")); + } + } +} diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/ProtocolLibListener.java similarity index 99% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibListener.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/ProtocolLibListener.java index c781b80e..d24e87de 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibListener.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/ProtocolLibListener.java @@ -23,7 +23,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit.listener.protocollib; +package com.github.games647.fastlogin.bukkit.auth.protocollib; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; @@ -42,7 +42,7 @@ import com.comphenix.protocol.wrappers.Converters; import com.comphenix.protocol.wrappers.WrappedGameProfile; import com.github.games647.fastlogin.bukkit.BukkitLoginSession; import com.github.games647.fastlogin.bukkit.FastLoginBukkit; -import com.github.games647.fastlogin.bukkit.listener.protocollib.packet.ClientPublicKey; +import com.github.games647.fastlogin.bukkit.auth.protocollib.packet.ClientPublicKey; import com.github.games647.fastlogin.core.antibot.AntiBotService; import com.github.games647.fastlogin.core.antibot.AntiBotService.Action; import com.mojang.datafixers.util.Either; diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibLoginSource.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/ProtocolLibLoginSource.java similarity index 96% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibLoginSource.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/ProtocolLibLoginSource.java index f32f3fa4..258d2300 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ProtocolLibLoginSource.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/ProtocolLibLoginSource.java @@ -23,14 +23,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit.listener.protocollib; +package com.github.games647.fastlogin.bukkit.auth.protocollib; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.wrappers.WrappedChatComponent; -import com.github.games647.fastlogin.bukkit.listener.protocollib.packet.ClientPublicKey; +import com.github.games647.fastlogin.bukkit.auth.protocollib.packet.ClientPublicKey; import com.github.games647.fastlogin.core.shared.LoginSource; import org.bukkit.entity.Player; diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/SkinApplyListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/SkinApplyListener.java similarity index 97% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/SkinApplyListener.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/SkinApplyListener.java index f3960672..49f906f8 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/SkinApplyListener.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/SkinApplyListener.java @@ -23,7 +23,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit.listener.protocollib; +package com.github.games647.fastlogin.bukkit.auth.protocollib; import com.comphenix.protocol.wrappers.WrappedGameProfile; import com.comphenix.protocol.wrappers.WrappedSignedProperty; diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/VerifyResponseTask.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/VerifyResponseTask.java similarity index 98% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/VerifyResponseTask.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/VerifyResponseTask.java index 55f3b960..46647c2a 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/VerifyResponseTask.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/VerifyResponseTask.java @@ -23,7 +23,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit.listener.protocollib; +package com.github.games647.fastlogin.bukkit.auth.protocollib; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; @@ -47,8 +47,8 @@ import com.github.games647.craftapi.model.skin.SkinProperty; import com.github.games647.craftapi.resolver.MojangResolver; import com.github.games647.fastlogin.bukkit.BukkitLoginSession; import com.github.games647.fastlogin.bukkit.FastLoginBukkit; -import com.github.games647.fastlogin.bukkit.InetUtils; -import com.github.games647.fastlogin.bukkit.listener.protocollib.packet.ClientPublicKey; +import com.github.games647.fastlogin.bukkit.auth.InetUtils; +import com.github.games647.fastlogin.bukkit.auth.protocollib.packet.ClientPublicKey; import lombok.val; import org.bukkit.entity.Player; diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/packet/ClientPublicKey.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/packet/ClientPublicKey.java similarity index 96% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/packet/ClientPublicKey.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/packet/ClientPublicKey.java index 1ea95d42..7e259149 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocollib/packet/ClientPublicKey.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/protocollib/packet/ClientPublicKey.java @@ -23,7 +23,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit.listener.protocollib.packet; +package com.github.games647.fastlogin.bukkit.auth.protocollib.packet; import lombok.Value; import lombok.experimental.Accessors; diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/proxy/ProxyAuthentication.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/proxy/ProxyAuthentication.java new file mode 100644 index 00000000..ca5c0e34 --- /dev/null +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/proxy/ProxyAuthentication.java @@ -0,0 +1,141 @@ +/* + * SPDX-License-Identifier: MIT + * + * The MIT License (MIT) + * + * Copyright (c) 2015-2024 games647 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.bukkit.auth.proxy; + +import com.github.games647.fastlogin.bukkit.FastLoginBukkit; +import com.github.games647.fastlogin.bukkit.auth.AuthenticationBackend; +import com.github.games647.fastlogin.core.message.LoginActionMessage; +import com.github.games647.fastlogin.core.message.NamespaceKey; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.plugin.PluginManager; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; + +import static com.github.games647.fastlogin.core.message.ChangePremiumMessage.CHANGE_CHANNEL; +import static com.github.games647.fastlogin.core.message.SuccessMessage.SUCCESS_CHANNEL; + +public class ProxyAuthentication implements AuthenticationBackend { + + private final FastLoginBukkit plugin; + private ProxyVerifier verifier; + + public ProxyAuthentication(FastLoginBukkit plugin) { + this.plugin = plugin; + } + + + @Override + public boolean isAvailable() { + return detectProxy(); + } + + @Override + public void init(PluginManager pluginManager) { + verifier = new ProxyVerifier(plugin); + verifier.loadSecrets(); + + registerPluginChannels(); + + pluginManager.registerEvents(new ProxyConnectionListener(plugin, verifier), plugin); + + plugin.getLog().info("Found enabled proxy configuration"); + plugin.getLog().info("Remember to follow the proxy guide to complete your setup"); + } + + private void registerPluginChannels() { + Server server = Bukkit.getServer(); + + // check for incoming messages from the bungeecord version of this plugin + String groupId = plugin.getName(); + String forceChannel = NamespaceKey.getCombined(groupId, LoginActionMessage.FORCE_CHANNEL); + server.getMessenger().registerIncomingPluginChannel(plugin, forceChannel, new ProxyListener(plugin, verifier)); + + // outgoing + String successChannel = new NamespaceKey(groupId, SUCCESS_CHANNEL).getCombinedName(); + String changeChannel = new NamespaceKey(groupId, CHANGE_CHANNEL).getCombinedName(); + server.getMessenger().registerOutgoingPluginChannel(plugin, successChannel); + server.getMessenger().registerOutgoingPluginChannel(plugin, changeChannel); + } + + @Override + public void stop() { + if (verifier != null) { + verifier.cleanup(); + } + } + + private boolean detectProxy() { + try { + if (isProxySupported("org.spigotmc.SpigotConfig", "bungee")) { + return true; + } + } catch (ClassNotFoundException classNotFoundException) { + // leave stacktrace for class not found out + plugin.getLog().warn("Cannot check for BungeeCord support: {}", classNotFoundException.getMessage()); + } catch (NoSuchFieldException | IllegalAccessException ex) { + plugin.getLog().warn("Cannot check for BungeeCord support", ex); + } + + try { + return isVelocityEnabled(); + } catch (ClassNotFoundException classNotFoundException) { + plugin.getLog().warn("Cannot check for Velocity support in Paper: {}", classNotFoundException.getMessage()); + } catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) { + plugin.getLog().warn("Cannot check for Velocity support in Paper", ex); + } + + return false; + } + + private boolean isProxySupported(String className, String fieldName) + throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { + return Class.forName(className).getDeclaredField(fieldName).getBoolean(null); + } + + private boolean isVelocityEnabled() + throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException, ClassNotFoundException, + NoSuchMethodException, InvocationTargetException { + try { + Class globalConfig = Class.forName("io.papermc.paper.configuration.GlobalConfiguration"); + Object global = globalConfig.getDeclaredMethod("get").invoke(null); + Object proxiesConfiguration = global.getClass().getDeclaredField("proxies").get(global); + + Field velocitySectionField = proxiesConfiguration.getClass().getDeclaredField("velocity"); + Object velocityConfig = velocitySectionField.get(proxiesConfiguration); + + return velocityConfig.getClass().getDeclaredField("enabled").getBoolean(velocityConfig); + } catch (ClassNotFoundException classNotFoundException) { + // try again using the older Paper configuration, because the old class file still exists in newer versions + if (isProxySupported("com.destroystokyo.paper.PaperConfig", "velocitySupport")) { + return true; + } + } + + return false; + } +} diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/proxy/ProxyConnectionListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/proxy/ProxyConnectionListener.java new file mode 100644 index 00000000..40ae9a9f --- /dev/null +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/proxy/ProxyConnectionListener.java @@ -0,0 +1,114 @@ +/* + * SPDX-License-Identifier: MIT + * + * The MIT License (MIT) + * + * Copyright (c) 2015-2024 games647 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.bukkit.auth.proxy; + +import com.github.games647.fastlogin.bukkit.BukkitLoginSession; +import com.github.games647.fastlogin.bukkit.FastLoginBukkit; +import com.github.games647.fastlogin.bukkit.auth.FloodgateAuthTask; +import com.github.games647.fastlogin.bukkit.auth.ForceLoginTask; +import com.github.games647.fastlogin.core.hooks.bedrock.FloodgateService; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.metadata.Metadatable; +import org.geysermc.floodgate.api.player.FloodgatePlayer; + +public class ProxyConnectionListener implements Listener { + + private static final long DELAY_LOGIN = 20L / 2; + + private final FastLoginBukkit plugin; + private final ProxyVerifier verifier; + + public ProxyConnectionListener(FastLoginBukkit plugin, ProxyVerifier verifier) { + this.plugin = plugin; + this.verifier = verifier; + } + + private void removeBlockedStatus(Metadatable player) { + player.removeMetadata(plugin.getName(), plugin); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerLogin(PlayerLoginEvent loginEvent) { + removeBlockedStatus(loginEvent.getPlayer()); + } + + @EventHandler(ignoreCancelled = true) + public void onPlayerJoin(PlayerJoinEvent joinEvent) { + Player player = joinEvent.getPlayer(); + + Bukkit.getScheduler().runTaskLater(plugin, () -> { + delayForceLogin(player); + // delay the login process to let auth plugins initialize the player + // Magic number however as there is no direct event from those plugins + }, 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.spigot().getRawAddress()); + + if (session == null) { + // Floodgate players usually don't have a session at this point + // exception: if force login by bungee message had been delayed + FloodgateService floodgateService = plugin.getFloodgateService(); + if (floodgateService != null) { + FloodgatePlayer floodgatePlayer = floodgateService.getBedrockPlayer(player.getUniqueId()); + if (floodgatePlayer != null) { + Runnable floodgateAuthTask = new FloodgateAuthTask(plugin.getCore(), player, floodgatePlayer); + Bukkit.getScheduler().runTaskAsynchronously(plugin, floodgateAuthTask); + return; + } + } + + String sessionId = plugin.getSessionId(player.spigot().getRawAddress()); + plugin.getLog().info("No on-going login session for player: {} with ID {}. ", player, sessionId); + plugin.getLog().info("Setups using Minecraft proxies will start delayed " + + "when the command from the proxy is received"); + } else { + Runnable forceLoginTask = new ForceLoginTask(plugin.getCore(), player, session); + Bukkit.getScheduler().runTaskAsynchronously(plugin, forceLoginTask); + } + + verifier.markJoinEventFired(player); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent quitEvent) { + Player player = quitEvent.getPlayer(); + + removeBlockedStatus(player); + verifier.cleanup(player); + } +} diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BungeeListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/proxy/ProxyListener.java similarity index 92% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BungeeListener.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/proxy/ProxyListener.java index 14cc9fa7..69884d33 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BungeeListener.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/proxy/ProxyListener.java @@ -23,11 +23,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit.listener; +package com.github.games647.fastlogin.bukkit.auth.proxy; import com.github.games647.fastlogin.bukkit.BukkitLoginSession; import com.github.games647.fastlogin.bukkit.FastLoginBukkit; -import com.github.games647.fastlogin.bukkit.task.ForceLoginTask; +import com.github.games647.fastlogin.bukkit.auth.ForceLoginTask; import com.github.games647.fastlogin.core.PremiumStatus; import com.github.games647.fastlogin.core.hooks.AuthPlugin; import com.github.games647.fastlogin.core.message.LoginActionMessage; @@ -47,12 +47,14 @@ import java.util.UUID; * This class also receives the plugin message from the bungeecord version of this plugin in order to get notified if * the connection is in online mode. */ -public class BungeeListener implements PluginMessageListener { +public class ProxyListener implements PluginMessageListener { private final FastLoginBukkit plugin; + private final ProxyVerifier verifier; - public BungeeListener(FastLoginBukkit plugin) { + public ProxyListener(FastLoginBukkit plugin, ProxyVerifier verifier) { this.plugin = plugin; + this.verifier = verifier; } @Override @@ -79,7 +81,7 @@ public class BungeeListener implements PluginMessageListener { plugin.getLog().warn("Received message {} from a blocked player {}", loginMessage, targetPlayer); } else { UUID sourceId = loginMessage.getProxyId(); - if (plugin.getBungeeManager().isProxyAllowed(sourceId)) { + if (verifier.isProxyAllowed(sourceId)) { readMessage(targetPlayer, loginMessage); } else { plugin.getLog().warn("Received proxy id: {} that doesn't exist in the proxy file", sourceId); @@ -127,7 +129,7 @@ public class BungeeListener implements PluginMessageListener { plugin.putSession(player.spigot().getRawAddress(), session); // only start a new login task if the join event fired earlier. This event then didn't - boolean result = plugin.getBungeeManager().didJoinEventFired(player); + boolean result = verifier.didJoinEventFired(player); plugin.getLog().info("Delaying force login until join event fired?: {}", result); if (result) { Runnable forceLoginTask = new ForceLoginTask(plugin.getCore(), player, session); diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BungeeManager.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/proxy/ProxyVerifier.java similarity index 53% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BungeeManager.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/proxy/ProxyVerifier.java index c1a46275..be760b96 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BungeeManager.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/auth/proxy/ProxyVerifier.java @@ -23,22 +23,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit; +package com.github.games647.fastlogin.bukkit.auth.proxy; -import com.github.games647.fastlogin.bukkit.listener.BungeeListener; +import com.github.games647.fastlogin.bukkit.FastLoginBukkit; import com.github.games647.fastlogin.core.message.ChannelMessage; -import com.github.games647.fastlogin.core.message.LoginActionMessage; import com.github.games647.fastlogin.core.message.NamespaceKey; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import org.bukkit.Bukkit; -import org.bukkit.Server; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageRecipient; import java.io.IOException; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; @@ -48,11 +44,9 @@ import java.util.Set; import java.util.UUID; import java.util.stream.Stream; -import static com.github.games647.fastlogin.core.message.ChangePremiumMessage.CHANGE_CHANNEL; -import static com.github.games647.fastlogin.core.message.SuccessMessage.SUCCESS_CHANNEL; import static java.util.stream.Collectors.toSet; -public class BungeeManager { +public class ProxyVerifier { private static final String LEGACY_FILE_NAME = "proxy-whitelist.txt"; private static final String FILE_NAME = "allowed-proxies.txt"; @@ -61,11 +55,10 @@ public class BungeeManager { private Set proxyIds; private final FastLoginBukkit plugin; - private boolean enabled; private final Collection firedJoinEvents = new HashSet<>(); - public BungeeManager(FastLoginBukkit plugin) { + public ProxyVerifier(FastLoginBukkit plugin) { this.plugin = plugin; } @@ -84,92 +77,13 @@ public class BungeeManager { } } - public boolean isEnabled() { - return enabled; - } - - public void initialize() { - enabled = detectProxy(); - - if (enabled) { - proxyIds = loadBungeeCordIds(); - if (proxyIds.isEmpty()) { - plugin.getLog().info("No valid IDs found. Minecraft proxy support cannot work in the current state"); - } - - registerPluginChannels(); - plugin.getLog().info("Found enabled proxy configuration"); - plugin.getLog().info("Remember to follow the proxy guide to complete your setup"); - } else { - plugin.getLog().warn("Disabling Minecraft proxy configuration. Assuming direct connections from now on."); + public void loadSecrets() { + proxyIds = loadBungeeCordIds(); + if (proxyIds.isEmpty()) { + plugin.getLog().info("No valid IDs found. Minecraft proxy support cannot work in the current state"); } } - private boolean isProxySupported(String className, String fieldName) - throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { - return Class.forName(className).getDeclaredField(fieldName).getBoolean(null); - } - - private boolean isVelocityEnabled() - throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException, ClassNotFoundException, - NoSuchMethodException, InvocationTargetException { - try { - Class globalConfig = Class.forName("io.papermc.paper.configuration.GlobalConfiguration"); - Object global = globalConfig.getDeclaredMethod("get").invoke(null); - Object proxiesConfiguration = global.getClass().getDeclaredField("proxies").get(global); - - Field velocitySectionField = proxiesConfiguration.getClass().getDeclaredField("velocity"); - Object velocityConfig = velocitySectionField.get(proxiesConfiguration); - - return velocityConfig.getClass().getDeclaredField("enabled").getBoolean(velocityConfig); - } catch (ClassNotFoundException classNotFoundException) { - // try again using the older Paper configuration, because the old class file still exists in newer versions - if (isProxySupported("com.destroystokyo.paper.PaperConfig", "velocitySupport")) { - return true; - } - } - - return false; - } - - private boolean detectProxy() { - try { - if (isProxySupported("org.spigotmc.SpigotConfig", "bungee")) { - return true; - } - } catch (ClassNotFoundException classNotFoundException) { - // leave stacktrace for class not found out - plugin.getLog().warn("Cannot check for BungeeCord support: {}", classNotFoundException.getMessage()); - } catch (NoSuchFieldException | IllegalAccessException ex) { - plugin.getLog().warn("Cannot check for BungeeCord support", ex); - } - - try { - return isVelocityEnabled(); - } catch (ClassNotFoundException classNotFoundException) { - plugin.getLog().warn("Cannot check for Velocity support in Paper: {}", classNotFoundException.getMessage()); - } catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) { - plugin.getLog().warn("Cannot check for Velocity support in Paper", ex); - } - - return false; - } - - private void registerPluginChannels() { - Server server = Bukkit.getServer(); - - // check for incoming messages from the bungeecord version of this plugin - String groupId = plugin.getName(); - String forceChannel = NamespaceKey.getCombined(groupId, LoginActionMessage.FORCE_CHANNEL); - server.getMessenger().registerIncomingPluginChannel(plugin, forceChannel, new BungeeListener(plugin)); - - // outgoing - String successChannel = new NamespaceKey(groupId, SUCCESS_CHANNEL).getCombinedName(); - String changeChannel = new NamespaceKey(groupId, CHANGE_CHANNEL).getCombinedName(); - server.getMessenger().registerOutgoingPluginChannel(plugin, successChannel); - server.getMessenger().registerOutgoingPluginChannel(plugin, changeChannel); - } - private Set loadBungeeCordIds() { Path proxiesFile = plugin.getPluginFolder().resolve(FILE_NAME); Path legacyFile = plugin.getPluginFolder().resolve(LEGACY_FILE_NAME); diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/task/DelayedAuthHook.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hook/DelayedAuthHook.java similarity index 79% rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/task/DelayedAuthHook.java rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hook/DelayedAuthHook.java index 510fa614..b2abb3fd 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/task/DelayedAuthHook.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hook/DelayedAuthHook.java @@ -23,15 +23,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.github.games647.fastlogin.bukkit.task; +package com.github.games647.fastlogin.bukkit.hook; import com.github.games647.fastlogin.bukkit.FastLoginBukkit; -import com.github.games647.fastlogin.bukkit.hook.AuthMeHook; -import com.github.games647.fastlogin.bukkit.hook.CrazyLoginHook; -import com.github.games647.fastlogin.bukkit.hook.LogItHook; -import com.github.games647.fastlogin.bukkit.hook.LoginSecurityHook; -import com.github.games647.fastlogin.bukkit.hook.UltraAuthHook; -import com.github.games647.fastlogin.bukkit.hook.XAuthHook; import com.github.games647.fastlogin.core.hooks.AuthPlugin; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -51,19 +45,7 @@ public class DelayedAuthHook implements Runnable { @Override public void run() { - boolean hookFound = isHookFound(); - if (plugin.getBungeeManager().isEnabled()) { - plugin.getLog().info("BungeeCord setting detected. No auth plugin is required"); - } else if (!hookFound) { - plugin.getLog().warn("No auth plugin were found by this plugin " - + "(other plugins could hook into this after the initialization of this plugin)" - + "and BungeeCord is deactivated. " - + "Either one or both of the checks have to pass in order to use this plugin"); - } - - if (hookFound) { - plugin.markInitialized(); - } + plugin.setInitialized(isHookFound()); } private boolean isHookFound() { diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolSupportListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolSupportListener.java deleted file mode 100644 index 5e513945..00000000 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolSupportListener.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * - * The MIT License (MIT) - * - * Copyright (c) 2015-2024 games647 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.bukkit.listener.protocolsupport; - -import com.github.games647.craftapi.UUIDAdapter; -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.core.antibot.AntiBotService; -import com.github.games647.fastlogin.core.antibot.AntiBotService.Action; -import com.github.games647.fastlogin.core.shared.JoinManagement; -import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent; -import com.github.games647.fastlogin.core.storage.StoredProfile; -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; - -import java.net.InetSocketAddress; -import java.util.Optional; - -public class ProtocolSupportListener extends JoinManagement - implements Listener { - - private final FastLoginBukkit plugin; - private final AntiBotService antiBotService; - - public ProtocolSupportListener(FastLoginBukkit plugin, AntiBotService antiBotService) { - super(plugin.getCore(), plugin.getCore().getAuthPluginHook(), plugin.getBedrockService()); - - this.plugin = plugin; - this.antiBotService = antiBotService; - } - - @EventHandler - public void onLoginStart(PlayerLoginStartEvent loginStartEvent) { - if (loginStartEvent.isLoginDenied() || plugin.getCore().getAuthPluginHook() == null) { - return; - } - - String username = loginStartEvent.getConnection().getProfile().getName(); - InetSocketAddress address = loginStartEvent.getConnection().getRawAddress(); - plugin.getLog().info("Incoming login request for {} from {}", username, address); - - Action action = antiBotService.onIncomingConnection(address, username); - switch (action) { - case Ignore: - // just ignore - return; - case Block: - String message = plugin.getCore().getMessage("kick-antibot"); - loginStartEvent.denyLogin(message); - break; - case Continue: - default: - //remove old data every time on a new login in order to keep the session only for one person - plugin.removeSession(address); - - ProtocolLoginSource source = new ProtocolLoginSource(loginStartEvent); - super.onLogin(username, source); - break; - } - } - - @EventHandler - public void onConnectionClosed(ConnectionCloseEvent closeEvent) { - InetSocketAddress address = closeEvent.getConnection().getRawAddress(); - plugin.removeSession(address); - } - - @EventHandler - public void onPropertiesResolve(PlayerProfileCompleteEvent profileCompleteEvent) { - InetSocketAddress address = profileCompleteEvent.getConnection().getRawAddress(); - - BukkitLoginSession session = plugin.getSession(address); - - if (session != null && profileCompleteEvent.getConnection().getProfile().isOnlineMode()) { - session.setVerifiedPremium(true); - - if (!plugin.getConfig().getBoolean("premiumUuid")) { - String username = Optional.ofNullable(profileCompleteEvent.getForcedName()) - .orElse(profileCompleteEvent.getConnection().getProfile().getName()); - profileCompleteEvent.setForcedUUID(UUIDAdapter.generateOfflineId(username)); - } - } - } - - @Override - public FastLoginPreLoginEvent callFastLoginPreLoginEvent(String username, ProtocolLoginSource source, - StoredProfile profile) { - BukkitFastLoginPreLoginEvent event = new BukkitFastLoginPreLoginEvent(username, source, profile); - plugin.getServer().getPluginManager().callEvent(event); - return event; - } - - @Override - public void requestPremiumLogin(ProtocolLoginSource source, StoredProfile profile, String username, - boolean registered) { - source.enableOnlinemode(); - - String ip = source.getAddress().getAddress().getHostAddress(); - plugin.getCore().addLoginAttempt(ip, username); - - BukkitLoginSession playerSession = new BukkitLoginSession(username, registered, profile); - plugin.putSession(source.getAddress(), playerSession); - } - - @Override - public void startCrackedSession(ProtocolLoginSource source, StoredProfile profile, String username) { - BukkitLoginSession loginSession = new BukkitLoginSession(username, profile); - plugin.putSession(source.getAddress(), loginSession); - } -} diff --git a/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/listener/protocollib/EncryptionUtilTest.java b/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/listener/protocollib/EncryptionUtilTest.java index 148e88c5..9255c25c 100644 --- a/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/listener/protocollib/EncryptionUtilTest.java +++ b/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/listener/protocollib/EncryptionUtilTest.java @@ -25,8 +25,9 @@ */ package com.github.games647.fastlogin.bukkit.listener.protocollib; +import com.github.games647.fastlogin.bukkit.auth.protocollib.packet.ClientPublicKey; +import com.github.games647.fastlogin.bukkit.auth.protocollib.protocollib.EncryptionUtil; import com.github.games647.fastlogin.bukkit.listener.protocollib.SignatureTestData.SignatureData; -import com.github.games647.fastlogin.bukkit.listener.protocollib.packet.ClientPublicKey; import com.google.common.hash.Hashing; import lombok.val; import org.junit.jupiter.api.Test; diff --git a/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ResourceLoader.java b/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ResourceLoader.java index 32e1dd0d..2f90bbc7 100644 --- a/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ResourceLoader.java +++ b/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/listener/protocollib/ResourceLoader.java @@ -25,7 +25,7 @@ */ package com.github.games647.fastlogin.bukkit.listener.protocollib; -import com.github.games647.fastlogin.bukkit.listener.protocollib.packet.ClientPublicKey; +import com.github.games647.fastlogin.bukkit.auth.protocollib.packet.ClientPublicKey; import com.google.common.io.Resources; import com.google.gson.Gson; import com.google.gson.JsonObject; diff --git a/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/task/DelayedAuthHookTest.java b/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/task/DelayedAuthHookTest.java index a829a4dd..4ac5ce55 100644 --- a/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/task/DelayedAuthHookTest.java +++ b/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/task/DelayedAuthHookTest.java @@ -25,6 +25,7 @@ */ package com.github.games647.fastlogin.bukkit.task; +import com.github.games647.fastlogin.bukkit.hook.DelayedAuthHook; import com.github.games647.fastlogin.core.hooks.AuthPlugin; import lombok.val; import org.bukkit.entity.Player;