Fix NPE for skin apply in ProtocolLib mode (Related #182)

This commit is contained in:
games647 committed 2017-10-15 17:57:24 +02:00
1 parent 4858049c2a
commit 57eff4b3ec
18 files changed
+48 -39

No files matched your search

@@ -62,6 +62,7 @@ public class BukkitLoginSession extends LoginSession {
return ArrayUtils.clone(verifyToken);
}
//todo: this should be optional for players without a skin at all
public synchronized SkinProperties getSkinProperty() {
return skinProperty;
}
@@ -4,7 +4,7 @@ import com.github.games647.fastlogin.bukkit.commands.CrackedCommand;
import com.github.games647.fastlogin.bukkit.commands.PremiumCommand;
import com.github.games647.fastlogin.bukkit.listener.BungeeListener;
import com.github.games647.fastlogin.bukkit.listener.JoinListener;
import com.github.games647.fastlogin.bukkit.listener.protocollib.LoginSkinApplyListener;
import com.github.games647.fastlogin.bukkit.listener.protocollib.SkinApplyListener;
import com.github.games647.fastlogin.bukkit.listener.protocollib.ProtocolLibListener;
import com.github.games647.fastlogin.bukkit.listener.protocolsupport.ProtocolSupportListener;
import com.github.games647.fastlogin.bukkit.tasks.DelayedAuthHook;
@@ -70,7 +70,6 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
//check for incoming messages from the bungeecord version of this plugin
getServer().getMessenger().registerIncomingPluginChannel(this, getName(), new BungeeListener(this));
getServer().getMessenger().registerOutgoingPluginChannel(this, getName());
//register listeners on success
} else {
if (!core.setupDatabase()) {
setEnabled(false);
@@ -81,11 +80,10 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
getServer().getPluginManager().registerEvents(new ProtocolSupportListener(this), this);
} else if (getServer().getPluginManager().isPluginEnabled("ProtocolLib")) {
//they will be created with a static builder, because otherwise it will throw a
//java.lang.NoClassDefFoundError: com/comphenix/protocol/events/PacketListener if ProtocolSupport was
//only found
//NoClassDefFoundError: com/comphenix/protocol/events/PacketListener if only ProtocolSupport was found
ProtocolLibListener.register(this);
getServer().getPluginManager().registerEvents(new LoginSkinApplyListener(this), this);
getServer().getPluginManager().registerEvents(new SkinApplyListener(this), this);
} else {
logger.warn("Either ProtocolLib or ProtocolSupport have to be installed if you don't use BungeeCord");
}
@@ -7,10 +7,12 @@ import com.github.games647.fastlogin.core.shared.LoginSession;
import com.google.common.net.HostAndPort;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import org.slf4j.Logger;
@@ -36,7 +38,8 @@ public class MojangApiBukkit extends MojangApiConnector {
HttpURLConnection conn = getConnection(url);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
//validate parsing
//http://wiki.vg/Protocol_Encryption#Server
VerificationReply verification = gson.fromJson(reader, VerificationReply.class);
@@ -50,7 +53,7 @@ public class MojangApiBukkit extends MojangApiConnector {
return true;
}
} catch (Exception ex) {
} catch (IOException ex) {
//catch not only io-exceptions also parse and NPE on unexpected json format
logger.warn("Failed to verify session", ex);
}
@@ -36,7 +36,7 @@ public class CrackedCommand implements CommandExecutor {
plugin.getCore().sendLocaleMessage("remove-premium", sender);
profile.setPremium(false);
profile.setUUID(null);
profile.setUuid(null);
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
plugin.getCore().getStorage().save(profile);
});
@@ -14,6 +14,7 @@ import java.net.InetSocketAddress;
import java.security.PublicKey;
import java.util.Random;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.entity.Player;
import static com.comphenix.protocol.PacketType.Login.Server.DISCONNECT;
@@ -93,6 +94,6 @@ public class ProtocolLibLoginSource implements LoginSource {
}
public byte[] getVerifyToken() {
return verifyToken;
return ArrayUtils.clone(verifyToken);
}
}
@@ -19,15 +19,14 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result;
public class LoginSkinApplyListener implements Listener {
public class SkinApplyListener implements Listener {
private static final Class<?> GAME_PROFILE = MinecraftReflection.getGameProfileClass();
private static final MethodAccessor GET_PROPERTIES = Accessors.getMethodAccessor(GAME_PROFILE, "getProperties");
private final FastLoginBukkit plugin;
public LoginSkinApplyListener(FastLoginBukkit plugin) {
public SkinApplyListener(FastLoginBukkit plugin) {
this.plugin = plugin;
}
@@ -46,7 +45,10 @@ public class LoginSkinApplyListener implements Listener {
for (BukkitLoginSession session : plugin.getLoginSessions().values()) {
if (session.getUsername().equals(player.getName())) {
SkinProperties skinProperty = session.getSkinProperty();
applySkin(player, skinProperty.getValue(), skinProperty.getSignature());
if (skinProperty != null) {
applySkin(player, skinProperty.getValue(), skinProperty.getSignature());
}
break;
}
}
@@ -56,13 +58,13 @@ public class LoginSkinApplyListener implements Listener {
private void applySkin(Player player, String skinData, String signature) {
WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player);
if (skinData != null && signature != null) {
WrappedSignedProperty skin = WrappedSignedProperty.fromValues("textures", skinData, signature);
WrappedSignedProperty skin = WrappedSignedProperty.fromValues(SkinProperties.TEXTURE_KEY, skinData, signature);
try {
gameProfile.getProperties().put("textures", skin);
gameProfile.getProperties().put(SkinProperties.TEXTURE_KEY, skin);
} catch (ClassCastException castException) {
Object map = GET_PROPERTIES.invoke(gameProfile.getHandle());
try {
MethodUtils.invokeMethod(map, "put", new Object[]{"textures", skin.getHandle()});
MethodUtils.invokeMethod(map, "put", new Object[]{SkinProperties.TEXTURE_KEY, skin.getHandle()});
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
plugin.getLog().error("Error setting premium skin", ex);
}
@@ -41,7 +41,7 @@ public class VerifyResponseTask implements Runnable {
this.plugin = plugin;
this.packetEvent = packetEvent;
this.player = player;
this.sharedSecret = sharedSecret;
this.sharedSecret = Arrays.copyOf(sharedSecret, sharedSecret.length);
}
@Override
@@ -3,6 +3,7 @@ package com.github.games647.fastlogin.bukkit.listener.protocolsupport;
import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.core.PlayerProfile;
import com.github.games647.fastlogin.core.mojang.SkinProperties;
import com.github.games647.fastlogin.core.shared.JoinManagement;
import java.net.InetSocketAddress;
@@ -46,7 +47,7 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
BukkitLoginSession session = plugin.getLoginSessions().get(address.toString());
//skin was resolved -> premium player
if (propertiesResolveEvent.hasProperty("textures") && session != null) {
if (propertiesResolveEvent.hasProperty(SkinProperties.TEXTURE_KEY) && session != null) {
session.setVerified(true);
}
}
@@ -18,15 +18,17 @@ import org.bukkit.metadata.FixedMetadataValue;
public class ForceLoginTask extends ForceLoginManagement<Player, CommandSender, BukkitLoginSession, FastLoginBukkit> {
public ForceLoginTask(FastLoginCore<Player, CommandSender, FastLoginBukkit> core, Player player) {
super(core, player);
super(core, player, getSession(core.getPlugin(), player));
}
private static BukkitLoginSession getSession(FastLoginBukkit plugin, Player player) {
//remove the bungeecord identifier if there is ones
String id = '/' + player.getAddress().getAddress().getHostAddress() + ':' + player.getAddress().getPort();
return plugin.getLoginSessions().remove(id);
}
@Override
public void run() {
//remove the bungeecord identifier if there is ones
String id = '/' + player.getAddress().getAddress().getHostAddress() + ':' + player.getAddress().getPort();
session = core.getPlugin().getLoginSessions().remove(id);
//blacklist this target player for BungeeCord Id brute force attacks
FastLoginBukkit plugin = core.getPlugin();
player.setMetadata(core.getPlugin().getName(), new FixedMetadataValue(plugin, true));