Replace handshake listener with bungeecord config reader

This commit is contained in:
games647
2016-04-05 11:40:23 +02:00
parent 2885daf8b9
commit 77f0184899
12 changed files with 48 additions and 95 deletions
@@ -6,14 +6,13 @@ import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.utility.SafeCacheBuilder;
import com.github.games647.fastlogin.bukkit.commands.CrackedCommand;
import com.github.games647.fastlogin.bukkit.commands.PremiumCommand;
import com.github.games647.fastlogin.bukkit.hooks.BukkitAuthPlugin;
import com.github.games647.fastlogin.bukkit.listener.BukkitJoinListener;
import com.github.games647.fastlogin.bukkit.listener.BungeeCordListener;
import com.github.games647.fastlogin.bukkit.listener.EncryptionPacketListener;
import com.github.games647.fastlogin.bukkit.listener.HandshakePacketListener;
import com.github.games647.fastlogin.bukkit.listener.ProtcolSupportListener;
import com.github.games647.fastlogin.bukkit.listener.ProtocolSupportListener;
import com.github.games647.fastlogin.bukkit.listener.StartPacketListener;
import com.google.common.cache.CacheLoader;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Sets;
import com.google.common.reflect.ClassPath;
@@ -25,9 +24,9 @@ import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import org.apache.commons.lang.RandomStringUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import com.github.games647.fastlogin.bukkit.hooks.BukkitAuthPlugin;
/**
* This plugin checks if a player has a paid account and if so tries to skip offline mode authentication.
@@ -40,8 +39,7 @@ public class FastLoginBukkit extends JavaPlugin {
//we need a thread-safe set because we access it async in the packet listener
private final Set<String> enabledPremium = Sets.newConcurrentHashSet();
//player=fake player created by Protocollib | this mapmaker creates a concurrent map with weak keys
private final ConcurrentMap<Player, Object> bungeeCordUsers = new MapMaker().weakKeys().makeMap();
private final boolean bungeeCord = Bukkit.spigot().getConfig().getBoolean("bungeecord");
//this map is thread-safe for async access (Packet Listener)
//SafeCacheBuilder is used in order to be version independent
@@ -64,19 +62,20 @@ public class FastLoginBukkit extends JavaPlugin {
@Override
public void onEnable() {
saveDefaultConfig();
if (getServer().getOnlineMode() || !registerHooks()) {
if (getServer().getOnlineMode()) {
//we need to require offline to prevent a session request for a offline player
getLogger().severe("Server have to be in offline mode and have an auth plugin installed");
getLogger().severe("Server have to be in offline mode");
setEnabled(false);
return;
}
registerHooks();
//register listeners on success
if (getServer().getPluginManager().isPluginEnabled("ProtocolSupport")) {
getServer().getPluginManager().registerEvents(new ProtcolSupportListener(this), this);
getServer().getPluginManager().registerEvents(new ProtocolSupportListener(this), this);
} else {
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
protocolManager.addPacketListener(new HandshakePacketListener(this));
//we are performing HTTP request on these so run it async (seperate from the Netty IO threads)
AsynchronousManager asynchronousManager = protocolManager.getAsynchronousManager();
@@ -100,7 +99,6 @@ public class FastLoginBukkit extends JavaPlugin {
//clean up
session.clear();
enabledPremium.clear();
bungeeCordUsers.clear();
//remove old blacklists
for (Player player : getServer().getOnlinePlayers()) {
@@ -122,18 +120,6 @@ public class FastLoginBukkit extends JavaPlugin {
return session;
}
/**
* Gets a concurrent map with weak keys for all bungeecord users which could be detected. It's mapped by a fake
* instance of player created by Protocollib and a non-null raw object.
*
* Represents a similar set collection
*
* @return
*/
public ConcurrentMap<Player, Object> getBungeeCordUsers() {
return bungeeCordUsers;
}
/**
* Gets the server KeyPair. This is used to encrypt or decrypt traffic between the client and server
*
@@ -197,13 +183,14 @@ public class FastLoginBukkit extends JavaPlugin {
if (authPluginHook == null) {
//run this check for exceptions (errors) and not found plugins
getLogger().warning("No support offline Auth plugin found. ");
getLogger().warning("Disabling this plugin...");
setEnabled(false);
return false;
}
authPlugin = authPluginHook;
return true;
}
public boolean isBungee() {
return bungeeCord;
}
}
@@ -51,7 +51,8 @@ public class BukkitJoinListener implements Listener {
public void run() {
if (player.isOnline()) {
//remove the bungeecord identifier
String id = '/' + player.getAddress().getAddress().getHostAddress() + ':' + player.getAddress().getPort();
String id = '/' + player.getAddress().getAddress().getHostAddress() + ':'
+ player.getAddress().getPort();
PlayerSession session = plugin.getSessions().get(id);
//blacklist this target player for BungeeCord Id brute force attacks
@@ -67,7 +67,6 @@ public class BungeeCordListener implements PluginMessageListener {
//put it only if the user doesn't has a session open
//so that the player have to send the bungeecord packet and cannot skip the verification then
plugin.getSessions().putIfAbsent(checkedPlayer.getAddress().toString(), playerSession);
} else {
//blacklist target for the current login
@@ -1,54 +0,0 @@
package com.github.games647.fastlogin.bukkit.listener;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Protocol;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import java.util.logging.Level;
/**
* Listens to incoming handshake packets.
*
* As BungeeCord sends additional information on the Handshake, we can detect it and check so if the player is coming
* from a BungeeCord instance. IpForward has to be activated in the BungeeCord config to send these extra information.
*
* Packet information: http://wiki.vg/Protocol#Handshake
*
* Int=Protocol version String=connecting server address (and additional information from BungeeCord) int=server port
* int=next state
*/
public class HandshakePacketListener extends PacketAdapter {
//hides the inherit Plugin plugin field, but we need a more detailed type than just Plugin
private final FastLoginBukkit plugin;
public HandshakePacketListener(FastLoginBukkit plugin) {
//run async in order to not block the server, because we are making api calls to Mojang
super(params(plugin, PacketType.Handshake.Client.SET_PROTOCOL).optionAsync());
this.plugin = plugin;
}
@Override
public void onPacketReceiving(PacketEvent packetEvent) {
PacketContainer packet = packetEvent.getPacket();
Protocol nextProtocol = packet.getProtocols().read(0);
//we don't want to listen for server ping.
if (nextProtocol == Protocol.LOGIN) {
//here are the information written separated by a space
String hostname = packet.getStrings().read(0);
//https://hub.spigotmc.org/stash/projects/SPIGOT/repos/spigot/browse/CraftBukkit-Patches/0055-BungeeCord-Support.patch
String[] split = hostname.split("\00");
if (split.length == 3 || split.length == 4) {
plugin.getLogger().log(Level.FINER, "Detected BungeeCord for {0}", hostname);
//object = because there are no concurrent sets with weak keys
plugin.getBungeeCordUsers().put(packetEvent.getPlayer(), new Object());
}
}
}
}
@@ -12,11 +12,11 @@ import org.bukkit.event.Listener;
import protocolsupport.api.events.PlayerLoginStartEvent;
import protocolsupport.api.events.PlayerPropertiesResolveEvent;
public class ProtcolSupportListener implements Listener {
public class ProtocolSupportListener implements Listener {
protected final FastLoginBukkit plugin;
public ProtcolSupportListener(FastLoginBukkit plugin) {
public ProtocolSupportListener(FastLoginBukkit plugin) {
this.plugin = plugin;
}
@@ -72,7 +72,7 @@ public class StartPacketListener extends PacketAdapter {
String username = packet.getGameProfiles().read(0).getName();
plugin.getLogger().log(Level.FINER, "Player {0} with {1} connecting to the server"
, new Object[]{sessionKey, username});
if (!plugin.getBungeeCordUsers().containsKey(player)) {
if (!plugin.isBungee()) {
BukkitAuthPlugin authPlugin = plugin.getAuthPlugin();
if (plugin.getEnabledPremium().contains(username)) {
enablePremiumLogin(username, sessionKey, player, packetEvent, true);