From 9f8b73d22acd5234c465a0b3ba9fd5ec28369f96 Mon Sep 17 00:00:00 2001 From: Kevin Schulte Date: Wed, 15 Jan 2025 10:56:21 +0100 Subject: [PATCH 1/2] change to packet events --- bungeeguard-spigot/pom.xml | 6 +- .../spigot/BungeeGuardBackendPlugin.java | 35 +++- .../PacketEventsHandshakeListener.java | 92 +++++++++++ .../listener/ProtocolHandshakeListener.java | 152 ------------------ .../src/main/resources/plugin.yml | 2 +- pom.xml | 8 +- 6 files changed, 130 insertions(+), 165 deletions(-) create mode 100644 bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/listener/PacketEventsHandshakeListener.java delete mode 100644 bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/listener/ProtocolHandshakeListener.java diff --git a/bungeeguard-spigot/pom.xml b/bungeeguard-spigot/pom.xml index 0836b82..4f586ac 100644 --- a/bungeeguard-spigot/pom.xml +++ b/bungeeguard-spigot/pom.xml @@ -38,9 +38,9 @@ provided - com.comphenix.protocol - ProtocolLib - 5.0.0-SNAPSHOT + com.github.retrooper + packetevents-spigot + 2.7.0 provided diff --git a/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/BungeeGuardBackendPlugin.java b/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/BungeeGuardBackendPlugin.java index ef3ae2a..d5cda56 100644 --- a/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/BungeeGuardBackendPlugin.java +++ b/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/BungeeGuardBackendPlugin.java @@ -25,10 +25,11 @@ package me.lucko.bungeeguard.spigot; +import com.github.retrooper.packetevents.PacketEvents; import me.lucko.bungeeguard.backend.BungeeGuardBackend; import me.lucko.bungeeguard.backend.TokenStore; +import me.lucko.bungeeguard.spigot.listener.PacketEventsHandshakeListener; import me.lucko.bungeeguard.spigot.listener.PaperHandshakeListener; -import me.lucko.bungeeguard.spigot.listener.ProtocolHandshakeListener; import org.bukkit.ChatColor; import org.bukkit.command.Command; @@ -46,10 +47,19 @@ */ public class BungeeGuardBackendPlugin extends JavaPlugin implements BungeeGuardBackend { + private static BungeeGuardBackendPlugin instance; + private TokenStore tokenStore; + @Override + public void onLoad() { + PacketEvents.getAPI().load(); + } + @Override public void onEnable() { + instance = this; + saveDefaultConfig(); this.tokenStore = new TokenStore(this); this.tokenStore.load(); @@ -71,11 +81,13 @@ public void onEnable() { PaperHandshakeListener listener = new PaperHandshakeListener(this, this.tokenStore); getServer().getPluginManager().registerEvents(listener, this); - } else if (hasProtocolLib()) { - getLogger().info("Using ProtocolLib to listen for connections."); + } else if (hasPacketEvents()) { + getLogger().info("Using PacketEvents to listen for connections."); + + PacketEvents.getAPI().init(); - ProtocolHandshakeListener listener = new ProtocolHandshakeListener(this, this.tokenStore); - listener.registerAdapter(this); + PacketEventsHandshakeListener listener = new PacketEventsHandshakeListener(this, this.tokenStore); + listener.registerListener(this); } else { getLogger().severe("------------------------------------------------------------"); @@ -92,6 +104,10 @@ public void onEnable() { } } + public static BungeeGuardBackendPlugin getInstance() { + return instance; + } + @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { if (!(sender instanceof ConsoleCommandSender)) { @@ -110,6 +126,11 @@ public boolean onCommand(CommandSender sender, Command command, String label, St return true; } + @Override + public void onDisable() { + PacketEvents.getAPI().terminate(); + } + @Override public String getMessage(String key) { return ChatColor.translateAlternateColorCodes('&', getConfig().getString(key)); @@ -128,8 +149,8 @@ private static boolean isPaperServer() { return classExists("com.destroystokyo.paper.PaperConfig"); } - private boolean hasProtocolLib() { - return getServer().getPluginManager().getPlugin("ProtocolLib") != null; + private boolean hasPacketEvents() { + return getServer().getPluginManager().getPlugin("packetevents") != null; } private static boolean classExists(String className) { diff --git a/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/listener/PacketEventsHandshakeListener.java b/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/listener/PacketEventsHandshakeListener.java new file mode 100644 index 0000000..a0df8c6 --- /dev/null +++ b/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/listener/PacketEventsHandshakeListener.java @@ -0,0 +1,92 @@ +package me.lucko.bungeeguard.spigot.listener; + +import com.github.retrooper.packetevents.PacketEvents; +import com.github.retrooper.packetevents.event.PacketListener; +import com.github.retrooper.packetevents.event.PacketListenerPriority; +import com.github.retrooper.packetevents.event.PacketReceiveEvent; +import com.github.retrooper.packetevents.wrapper.handshaking.client.WrapperHandshakingClientHandshake; +import me.lucko.bungeeguard.backend.BungeeGuardBackend; +import me.lucko.bungeeguard.backend.TokenStore; +import me.lucko.bungeeguard.backend.listener.AbstractHandshakeListener; +import me.lucko.bungeeguard.spigot.BungeeCordHandshake; +import me.lucko.bungeeguard.spigot.BungeeGuardBackendPlugin; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import java.net.InetSocketAddress; +import java.util.logging.Level; + +/** + * A handshake listener using PacketEvents. + */ +public class PacketEventsHandshakeListener extends AbstractHandshakeListener { + + private static final int HANDSHAKE_PACKET_ID = 0x00; // ID for Handshake packets + + public PacketEventsHandshakeListener(BungeeGuardBackend plugin, TokenStore tokenStore) { + super(plugin, tokenStore); + } + + public void registerListener(Plugin plugin) { + PacketEvents.getAPI().getEventManager().registerListener(new HandshakeListener(), PacketListenerPriority.HIGHEST); + } + + private final class HandshakeListener implements PacketListener { + + @Override + public void onPacketReceive(PacketReceiveEvent event) { + if (event.getPacketId() != HANDSHAKE_PACKET_ID) { + return; + } + + Player player = event.getPlayer(); + + WrapperHandshakingClientHandshake wrapperHandshakingClientHandshake = new WrapperHandshakingClientHandshake(event); + int protocolState = wrapperHandshakingClientHandshake.readInt(); + if (protocolState != 2) { + return; + } + + String handshake = wrapperHandshakingClientHandshake.readString(0); + BungeeCordHandshake decoded = BungeeCordHandshake.decodeAndVerify(handshake, PacketEventsHandshakeListener.this.tokenStore); + + if (decoded instanceof BungeeCordHandshake.Fail) { + String ip = "null"; + InetSocketAddress address = player.getAddress(); + if (address != null) { + ip = address.getHostString(); + if (ip.length() > 15) { + ip = BungeeCordHandshake.encodeBase64(ip); + } + } + BungeeCordHandshake.Fail fail = (BungeeCordHandshake.Fail) decoded; + BungeeGuardBackendPlugin.getInstance().getLogger().warning("Denying connection from " + ip + " - " + fail.describeConnection() + " - reason: " + fail.reason().name()); + + String kickMessage; + if (fail.reason() == BungeeCordHandshake.Fail.Reason.INVALID_HANDSHAKE) { + kickMessage = PacketEventsHandshakeListener.this.noDataKickMessage; + } else { + kickMessage = PacketEventsHandshakeListener.this.invalidTokenKickMessage; + } + + try { + closeConnection(player, kickMessage); + } catch (Exception e) { + BungeeGuardBackendPlugin.getInstance().getLogger().log(Level.SEVERE, "An error occurred while closing connection for " + player, e); + } + + // Prevent further processing by modifying the packet + wrapperHandshakingClientHandshake.writeString("null"); + return; + } + + // Successfully decoded and verified the handshake + BungeeCordHandshake.Success data = (BungeeCordHandshake.Success) decoded; + wrapperHandshakingClientHandshake.writeString(data.encode()); + } + } + + private static void closeConnection(Player player, String kickMessage) { + player.kickPlayer(kickMessage); + } +} diff --git a/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/listener/ProtocolHandshakeListener.java b/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/listener/ProtocolHandshakeListener.java deleted file mode 100644 index 8006659..0000000 --- a/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/listener/ProtocolHandshakeListener.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * This file is part of BungeeGuard, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) 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 me.lucko.bungeeguard.spigot.listener; - -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.events.ListenerPriority; -import com.comphenix.protocol.events.PacketAdapter; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.events.PacketEvent; -import com.comphenix.protocol.injector.temporary.MinimalInjector; -import com.comphenix.protocol.injector.temporary.TemporaryPlayerFactory; -import com.comphenix.protocol.wrappers.WrappedChatComponent; - -import me.lucko.bungeeguard.backend.BungeeGuardBackend; -import me.lucko.bungeeguard.backend.TokenStore; -import me.lucko.bungeeguard.backend.listener.AbstractHandshakeListener; -import me.lucko.bungeeguard.spigot.BungeeCordHandshake; -import me.lucko.bungeeguard.spigot.LegacyProtocolKick; - -import net.md_5.bungee.api.chat.TextComponent; -import net.md_5.bungee.chat.ComponentSerializer; - -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; - -import java.net.InetSocketAddress; -import java.util.logging.Level; - -/** - * A handshake listener using ProtocolLib. - */ -public class ProtocolHandshakeListener extends AbstractHandshakeListener { - static boolean isLegacyProtocolLib = false; // Before 5.x series. - - public ProtocolHandshakeListener(BungeeGuardBackend plugin, TokenStore tokenStore) { - super(plugin, tokenStore); - } - - public void registerAdapter(Plugin plugin) { - ProtocolLibrary.getProtocolManager().addPacketListener(new Adapter(plugin)); - } - - private final class Adapter extends PacketAdapter { - - Adapter(Plugin plugin) { - super(plugin, ListenerPriority.LOWEST, PacketType.Handshake.Client.SET_PROTOCOL); - try { - Class.forName("com.comphenix.protocol.injector.temporary.MinimalInjector"); - plugin.getLogger().info("Using modern (v5) ProtocolLib adapter."); - } catch (ClassNotFoundException e) { - plugin.getLogger().info("Using legacy (v4) ProtocolLib adapter."); - isLegacyProtocolLib = true; - } - } - - @Override - public void onPacketReceiving(PacketEvent event) { - PacketContainer packet = event.getPacket(); - - // only handle the LOGIN phase - PacketType.Protocol state = packet.getProtocols().read(0); - if (state != PacketType.Protocol.LOGIN) { - return; - } - - String handshake = packet.getStrings().read(0); - BungeeCordHandshake decoded = BungeeCordHandshake.decodeAndVerify(handshake, ProtocolHandshakeListener.this.tokenStore); - - if (decoded instanceof BungeeCordHandshake.Fail) { - String ip = "null"; - Player player = event.getPlayer(); - InetSocketAddress address = player.getAddress(); - if (address != null) { - ip = address.getHostString(); - if (ip.length() > 15) { - ip = BungeeCordHandshake.encodeBase64(ip); - } - } - BungeeCordHandshake.Fail fail = (BungeeCordHandshake.Fail) decoded; - this.plugin.getLogger().warning("Denying connection from " + ip + " - " + fail.describeConnection() + " - reason: " + fail.reason().name()); - - String kickMessage; - if (fail.reason() == BungeeCordHandshake.Fail.Reason.INVALID_HANDSHAKE) { - kickMessage = ProtocolHandshakeListener.this.noDataKickMessage; - } else { - kickMessage = ProtocolHandshakeListener.this.invalidTokenKickMessage; - } - - try { - closeConnection(player, kickMessage); - } catch (Exception e) { - this.plugin.getLogger().log(Level.SEVERE, "An error occurred while closing connection for " + player, e); - } - - // just in-case the connection didn't close, screw up the hostname - // so Spigot can't pick up anything that might've been spoofed in nms.HandshakeListener - packet.getStrings().write(0, "null"); - - return; - } - - // great, handshake was decoded and verified successfully. - // we can re-encode the handshake now so Spigot can pick up the spoofed stuff. - BungeeCordHandshake.Success data = (BungeeCordHandshake.Success) decoded; - packet.getStrings().write(0, data.encode()); - } - } - - private static void closeConnection(Player player, String kickMessage) throws Exception { - WrappedChatComponent component = WrappedChatComponent.fromJson(ComponentSerializer.toString(TextComponent.fromLegacyText(kickMessage))); - - PacketContainer packet = new PacketContainer(PacketType.Login.Server.DISCONNECT); - packet.getModifier().writeDefaults(); - packet.getChatComponents().write(0, component); - - // send custom disconnect message to client - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); - - if (isLegacyProtocolLib) { - LegacyProtocolKick.kick(player); - } else { - // call PlayerConnection#disconnect to ensure the underlying socket is closed - MinimalInjector injector = TemporaryPlayerFactory.getInjectorFromPlayer(player); - injector.disconnect(""); - } - } - -} diff --git a/bungeeguard-spigot/src/main/resources/plugin.yml b/bungeeguard-spigot/src/main/resources/plugin.yml index 99024ed..03265fb 100644 --- a/bungeeguard-spigot/src/main/resources/plugin.yml +++ b/bungeeguard-spigot/src/main/resources/plugin.yml @@ -5,7 +5,7 @@ author: Luck load: STARTUP main: me.lucko.bungeeguard.spigot.BungeeGuardBackendPlugin -softdepend: [ProtocolLib] +softdepend: [packetevents] api-version: 1.13 folia-supported: true diff --git a/pom.xml b/pom.xml index 714f3df..040bd88 100644 --- a/pom.xml +++ b/pom.xml @@ -44,8 +44,12 @@ https://repo.papermc.io/repository/maven-public/ - luck-repo - https://repo.lucko.me/ + codemc-releases + https://repo.codemc.io/repository/maven-releases/ + + + codemc-snapshots + https://repo.codemc.io/repository/maven-snapshots/ From d56df3ef5bb5d0d766429cc444d6df4cd040d76c Mon Sep 17 00:00:00 2001 From: Kevin Schulte Date: Wed, 15 Jan 2025 11:01:49 +0100 Subject: [PATCH 2/2] change to packet events --- .../lucko/bungeeguard/spigot/BungeeGuardBackendPlugin.java | 2 +- .../spigot/listener/PacketEventsHandshakeListener.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/BungeeGuardBackendPlugin.java b/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/BungeeGuardBackendPlugin.java index d5cda56..8709797 100644 --- a/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/BungeeGuardBackendPlugin.java +++ b/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/BungeeGuardBackendPlugin.java @@ -87,7 +87,7 @@ public void onEnable() { PacketEvents.getAPI().init(); PacketEventsHandshakeListener listener = new PacketEventsHandshakeListener(this, this.tokenStore); - listener.registerListener(this); + listener.registerListener(); } else { getLogger().severe("------------------------------------------------------------"); diff --git a/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/listener/PacketEventsHandshakeListener.java b/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/listener/PacketEventsHandshakeListener.java index a0df8c6..b97d750 100644 --- a/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/listener/PacketEventsHandshakeListener.java +++ b/bungeeguard-spigot/src/main/java/me/lucko/bungeeguard/spigot/listener/PacketEventsHandshakeListener.java @@ -27,7 +27,7 @@ public PacketEventsHandshakeListener(BungeeGuardBackend plugin, TokenStore token super(plugin, tokenStore); } - public void registerListener(Plugin plugin) { + public void registerListener() { PacketEvents.getAPI().getEventManager().registerListener(new HandshakeListener(), PacketListenerPriority.HIGHEST); } @@ -42,8 +42,7 @@ public void onPacketReceive(PacketReceiveEvent event) { Player player = event.getPlayer(); WrapperHandshakingClientHandshake wrapperHandshakingClientHandshake = new WrapperHandshakingClientHandshake(event); - int protocolState = wrapperHandshakingClientHandshake.readInt(); - if (protocolState != 2) { + if (!wrapperHandshakingClientHandshake.getIntention().equals(WrapperHandshakingClientHandshake.ConnectionIntention.LOGIN)) { return; }