Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bukkit/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,8 @@
<groupId>io.netty</groupId>
<artifactId>netty-transport</artifactId>
<version>${nettyVersion}</version>
<scope>test</scope>
</dependency>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>io.netty</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
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.ManualNameChange;
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;
Expand Down Expand Up @@ -119,10 +118,6 @@ public void onEnable() {
} else if (pluginManager.isPluginEnabled("ProtocolLib")) {
ProtocolLibListener.register(this, core.getAntiBot(), core.getConfig().getBoolean("verifyClientKeys"));

if (isPluginInstalled("floodgate")) {
printFloodgateWarning();
}

//if server is using paper - we need to set the skin at pre login anyway, so no need for this listener
if (!PaperLib.isPaper() && getConfig().getBoolean("forwardSkin")) {
pluginManager.registerEvents(new SkinApplyListener(this), this);
Expand Down Expand Up @@ -152,23 +147,6 @@ public void onEnable() {
premiumPlaceholder = new PremiumPlaceholder(this);
premiumPlaceholder.register();
}

dependencyWarnings();
}

private void printFloodgateWarning() {
if (getConfig().getBoolean("floodgatePrefixWorkaround")) {
ManualNameChange.register(this, floodgateService);
logger.info("Floodgate prefix injection workaround has been enabled.");
logger.info("If you have problems joining the server, try disabling it in the configuration.");
} else {
logger.warn("We have detected that you are running FastLogin alongside Floodgate and ProtocolLib.");
logger.warn("Currently there is an issue with FastLogin that prevents Floodgate name prefixes from "
+ "showing up when it is together used with ProtocolLib.");
logger.warn("If you would like to use Floodgate name prefixes, you can enable an experimental "
+ "workaround by changing the value 'floodgatePrefixWorkaround' to true in config.yml.");
logger.warn("For more information visit https://github.com/games647/FastLogin/issues/493");
}
}

private boolean initializeFloodgate() {
Expand Down Expand Up @@ -326,18 +304,4 @@ public BedrockService<?> getBedrockService() {
}
return geyserService;
}

/**
* Send warning messages to log if incompatible plugins are used
*/
private void dependencyWarnings() {
if (isPluginInstalled("floodgate-bukkit")) {
logger.warn("We have detected that you are running Floodgate 1.0 which is not supported by the Bukkit "
+ "version of FastLogin.");
logger.warn("If you would like to use FastLogin with Floodgate, you can download development builds of "
+ "Floodgate 2.0 from https://ci.opencollab.dev/job/GeyserMC/job/Floodgate/job/dev%252F2.0/");
logger.warn("Don't forget to update Geyser to a supported version as well from "
+ "https://ci.opencollab.dev/job/GeyserMC/job/Geyser/job/floodgate-2.0/");
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.injector.PacketFilterManager;
import com.comphenix.protocol.injector.player.PlayerInjectionHandler;
import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.comphenix.protocol.wrappers.BukkitConverters;
Expand All @@ -42,6 +44,7 @@
import com.github.games647.fastlogin.core.antibot.AntiBotService.Action;
import com.mojang.datafixers.util.Either;

import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.security.InvalidKeyException;
import java.security.KeyPair;
Expand All @@ -58,15 +61,20 @@
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.util.AttributeKey;
import lombok.val;
import org.bukkit.entity.Player;
import org.geysermc.floodgate.api.player.FloodgatePlayer;

import static com.comphenix.protocol.PacketType.Login.Client.ENCRYPTION_BEGIN;
import static com.comphenix.protocol.PacketType.Login.Client.START;

public class ProtocolLibListener extends PacketAdapter {

private final FastLoginBukkit plugin;
private final PlayerInjectionHandler handler;

//just create a new once on plugin enable. This used for verify token generation
private final SecureRandom random = new SecureRandom();
Expand All @@ -85,6 +93,7 @@ public ProtocolLibListener(FastLoginBukkit plugin, AntiBotService antiBotService
this.plugin = plugin;
this.antiBotService = antiBotService;
this.verifyClientKeys = verifyClientKeys;
this.handler = getHandler();
}

public static void register(FastLoginBukkit plugin, AntiBotService antiBotService, boolean verifyClientKeys) {
Expand All @@ -109,6 +118,15 @@ public void onPacketReceiving(PacketEvent packetEvent) {
Player sender = packetEvent.getPlayer();
PacketType packetType = packetEvent.getPacketType();
if (packetType == START) {

if (plugin.getFloodgateService() != null) {
boolean success = processFloodgateTasks(packetEvent);
// don't continue execution if the player was kicked by Floodgate
if (!success) {
return;
}
}

PacketContainer packet = packetEvent.getPacket();

InetSocketAddress address = sender.getAddress();
Expand Down Expand Up @@ -201,11 +219,6 @@ private void onLoginStart(PacketEvent packetEvent, Player player, String usernam
//remove old data every time on a new login in order to keep the session only for one person
plugin.removeSession(player.getAddress());

if (packetEvent.getPacket().getMeta("original_name").isPresent()) {
//username has been injected by ManualNameChange.java
username = (String) packetEvent.getPacket().getMeta("original_name").get();
}

PacketContainer packet = packetEvent.getPacket();
val profileKey = packet.getOptionals(BukkitConverters.getWrappedPublicKeyDataConverter())
.optionRead(0);
Expand Down Expand Up @@ -254,4 +267,65 @@ private String getUsername(PacketContainer packet) {
//player.getName() won't work at this state
return profile.getName();
}

private static PlayerInjectionHandler getHandler() {
try {
PacketFilterManager manager = (PacketFilterManager) ProtocolLibrary.getProtocolManager();
Field f = manager.getClass().getDeclaredField("playerInjectionHandler");
f.setAccessible(true);
PlayerInjectionHandler handler = (PlayerInjectionHandler) f.get(manager);
f.setAccessible(false);
return handler;
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}

private FloodgatePlayer getFloodgatePlayer(Player player) {
Channel channel = handler.getChannel(player);
AttributeKey<FloodgatePlayer> floodgateAttribute = AttributeKey.valueOf("floodgate-player");
return channel.attr(floodgateAttribute).get();
}

/**
* Reimplementation of the tasks injected Floodgate in ProtocolLib that are not run due to a bug
* @see <a href="https://github.com/GeyserMC/Floodgate/issues/143">Issue Floodgate#143</a>
* @see <a href="https://github.com/GeyserMC/Floodgate/blob/5d5713ed9e9eeab0f4abdaa9cf5cd8619dc1909b/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java#L121-L175">Floodgate/SpigotDataHandler</a>
* @param packetEvent the PacketEvent that won't be processed by Floodgate
* @return false if the player was kicked
*/
private boolean processFloodgateTasks(PacketEvent packetEvent) {
PacketContainer packet = packetEvent.getPacket();
Player player = packetEvent.getPlayer();
FloodgatePlayer floodgatePlayer = getFloodgatePlayer(player);
if (floodgatePlayer == null) {
return true;
}

// kick the player, if necessary
Channel channel = handler.getChannel(packetEvent.getPlayer());
AttributeKey<String> kickMessageAttribute = AttributeKey.valueOf("floodgate-kick-message");
String kickMessage = channel.attr(kickMessageAttribute).get();
if (kickMessage != null) {
player.kickPlayer(kickMessage);
return false;
}

// add prefix
String username = floodgatePlayer.getCorrectUsername();
if (packet.getGameProfiles().size() > 0) {
packet.getGameProfiles().write(0,
new WrappedGameProfile(floodgatePlayer.getCorrectUniqueId(), username));
} else {
packet.getStrings().write(0, username);
}

// remove real Floodgate data handler
ChannelHandler floodgateHandler = channel.pipeline().get("floodgate_data_handler");
channel.pipeline().remove(floodgateHandler);

return true;
}
}
1 change: 1 addition & 0 deletions checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
<module name="LineLength">
<property name="max" value="120"/>
<property name="fileExtensions" value="java"/>
<property name="ignorePattern" value="^ *\* *@see.+$"/>
</module>

<!-- Checks for whitespace -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,23 +99,11 @@ public boolean performChecks(String username, LoginSource source) {
* 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
* <br>
* <i>Falls back to non-prefixed name checks, if ProtocolLib is installed</i>
*
* @param prefixedUsername the name of the player with the prefix appended
* @return FloodgatePlayer if found, null otherwise
*/
public FloodgatePlayer getBedrockPlayer(String prefixedUsername) {
//prefixes are broken with ProtocolLib, so fall back to name checks without prefixes
//this should be removed if #493 gets fixed
if (core.getPlugin().isPluginInstalled("ProtocolLib")) {
for (FloodgatePlayer floodgatePlayer : floodgate.getPlayers()) {
if (floodgatePlayer.getUsername().equals(prefixedUsername)) {
return floodgatePlayer;
}
}
return null;
}
for (FloodgatePlayer floodgatePlayer : floodgate.getPlayers()) {
if (floodgatePlayer.getCorrectUsername().equals(prefixedUsername)) {
return floodgatePlayer;
Expand Down
10 changes: 0 additions & 10 deletions core/src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,6 @@ autoLoginFloodgate: false
#
# To prevent conflicts from two different players having the same name, it is highly recommended using a
# 'username-prefix' in floodgate/config.yml
# Note: 'username-prefix' is currently broken when used with FastLogin and ProtocolLib.
# A solution to this is to enable 'floodgatePrefixWorkaround' below.
#
# Possible values:
# false: Kick Bedrock players, if they are using an existing Premium Java account's name
Expand All @@ -264,14 +262,6 @@ allowFloodgateNameConflict: false
# Enabling this might lead to people gaining unauthorized access to other's accounts!
autoRegisterFloodgate: false

# Make FastLogin inject the Floodgate name prefixes, instead of Floodgate.
# This can fix prefixes, if you are using Floodgate alongside ProtocolLib.
# If either of those plugins are not installed, this option will have no effect.
# For more information visit: https://github.com/games647/FastLogin/issues/493
# !!!!!!!! WARNING: FLOODGATE SUPPORT IS AN EXPERIMENTAL FEATURE !!!!!!!!
# Enabling this might lead to people gaining unauthorized access to other's accounts!
floodgatePrefixWorkaround: false

# This option resembles the vanilla configuration option 'enforce-secure-profile' in the 'server.properties' file.
# It verifies if the incoming cryptographic key in the login request from the player is signed by Mojang. This key
# is necessary for servers where you or other in-game players want to verify that a chat message sent and signed by
Expand Down