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 b0f99953..1b349bd9 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 @@ -9,7 +9,7 @@ import com.github.games647.fastlogin.bukkit.listener.protocollib.ProtocolLibList import com.github.games647.fastlogin.bukkit.listener.protocolsupport.ProtocolSupportListener; import com.github.games647.fastlogin.bukkit.tasks.DelayedAuthHook; import com.github.games647.fastlogin.core.shared.FastLoginCore; -import com.github.games647.fastlogin.core.shared.MojangApiConnector; +import com.github.games647.fastlogin.core.mojang.MojangApiConnector; import com.github.games647.fastlogin.core.shared.PlatformPlugin; import com.google.common.collect.Iterables; import com.google.common.io.ByteArrayDataOutput; diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/MojangApiBukkit.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/MojangApiBukkit.java index 7e5ee766..989b6bb4 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/MojangApiBukkit.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/MojangApiBukkit.java @@ -1,8 +1,10 @@ package com.github.games647.fastlogin.bukkit; +import com.github.games647.fastlogin.core.mojang.MojangApiConnector; +import com.github.games647.fastlogin.core.mojang.SkinProperties; +import com.github.games647.fastlogin.core.mojang.VerificationReply; import com.github.games647.fastlogin.core.shared.FastLoginCore; import com.github.games647.fastlogin.core.shared.LoginSession; -import com.github.games647.fastlogin.core.shared.MojangApiConnector; import java.io.BufferedReader; import java.io.InputStreamReader; @@ -14,10 +16,6 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.JSONValue; - public class MojangApiBukkit extends MojangApiConnector { //mojang api check to prove a player is logged in minecraft and made a join server request @@ -42,26 +40,23 @@ public class MojangApiBukkit extends MojangApiConnector { HttpURLConnection conn = getConnection(url); try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) { - String line = reader.readLine(); - if (line != null && !"null".equals(line)) { - //validate parsing - //http://wiki.vg/Protocol_Encryption#Server - JSONObject userData = (JSONObject) JSONValue.parseWithException(line); - String uuid = (String) userData.get("id"); - playerSession.setUuid(FastLoginCore.parseId(uuid)); + //validate parsing + //http://wiki.vg/Protocol_Encryption#Server + VerificationReply verification = gson.fromJson(reader, VerificationReply.class); - JSONArray properties = (JSONArray) userData.get("properties"); - JSONObject skinProperty = (JSONObject) properties.get(0); + String uuid = verification.getId(); + playerSession.setUuid(FastLoginCore.parseId(uuid)); - String propertyName = (String) skinProperty.get("name"); - if ("textures".equals(propertyName)) { - String skinValue = (String) skinProperty.get("value"); - String signature = (String) skinProperty.get("signature"); - playerSession.setSkin(skinValue, signature); - } + SkinProperties[] properties = verification.getProperties(); + if (properties != null && properties.length > 0) { + SkinProperties skinProperty = properties[0]; - return true; + String skinValue = skinProperty.getValue(); + String signature = skinProperty.getSignature(); + playerSession.setSkin(skinValue, signature); } + + return true; } } catch (Exception ex) { //catch not only io-exceptions also parse and NPE on unexpected json format @@ -71,24 +66,4 @@ public class MojangApiBukkit extends MojangApiConnector { //this connection doesn't need to be closed. So can make use of keep alive in java return false; } - - @Override - protected String getUUIDFromJson(String json) { - boolean isArray = json.startsWith("["); - - JSONObject mojangPlayer; - if (isArray) { - JSONArray array = (JSONArray) JSONValue.parse(json); - mojangPlayer = (JSONObject) array.get(0); - } else { - mojangPlayer = (JSONObject) JSONValue.parse(json); - } - - String uuid = (String) mojangPlayer.get("id"); - if ("null".equals(uuid)) { - return null; - } - - return uuid; - } } diff --git a/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/EncryptionUtilTest.java b/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/EncryptionUtilTest.java index 543477cf..7f6bf149 100644 --- a/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/EncryptionUtilTest.java +++ b/bukkit/src/test/java/com/github/games647/fastlogin/bukkit/EncryptionUtilTest.java @@ -15,7 +15,7 @@ public class EncryptionUtilTest { byte[] token = EncryptionUtil.generateVerifyToken(random); assertNotNull(token); - assertEquals(token.length, 4); + assertEquals(4, token.length); } // @Test diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/FastLoginBungee.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/FastLoginBungee.java index 09077799..93ac7ea1 100644 --- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/FastLoginBungee.java +++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/FastLoginBungee.java @@ -4,7 +4,7 @@ import com.github.games647.fastlogin.bungee.hooks.BungeeAuthHook; import com.github.games647.fastlogin.bungee.listener.ConnectionListener; import com.github.games647.fastlogin.bungee.listener.PluginMessageListener; import com.github.games647.fastlogin.core.shared.FastLoginCore; -import com.github.games647.fastlogin.core.shared.MojangApiConnector; +import com.github.games647.fastlogin.core.mojang.MojangApiConnector; import com.github.games647.fastlogin.core.shared.PlatformPlugin; import com.google.common.collect.Maps; @@ -111,6 +111,6 @@ public class FastLoginBungee extends Plugin implements PlatformPlugin addresses, int requests , Map proxies) { - return new MojangApiBungee(logger, addresses, requests, proxies); + return new MojangApiConnector(logger, addresses, requests, proxies); } } diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/MojangApiBungee.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/MojangApiBungee.java deleted file mode 100644 index 339afa2e..00000000 --- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/MojangApiBungee.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.github.games647.fastlogin.bungee; - -import com.github.games647.fastlogin.core.shared.LoginSession; -import com.github.games647.fastlogin.core.shared.MojangApiConnector; - -import java.net.InetSocketAddress; -import java.util.Collection; -import java.util.Map; -import java.util.logging.Logger; - -import net.md_5.bungee.BungeeCord; - -public class MojangApiBungee extends MojangApiConnector { - - public MojangApiBungee(Logger logger, Collection localAddresses, int rateLimit - , Map proxies) { - super(logger, localAddresses, rateLimit, proxies); - } - - @Override - protected String getUUIDFromJson(String json) { - boolean isArray = json.startsWith("["); - - MojangPlayer mojangPlayer; - if (isArray) { - mojangPlayer = BungeeCord.getInstance().gson.fromJson(json, MojangPlayer[].class)[0]; - } else { - mojangPlayer = BungeeCord.getInstance().gson.fromJson(json, MojangPlayer.class); - } - - String id = mojangPlayer.getId(); - if ("null".equals(id)) { - return null; - } - - return id; - } - - @Override - public boolean hasJoinedServer(LoginSession session, String serverId, InetSocketAddress ip) { - //this is not needed in Bungee - throw new UnsupportedOperationException("Not supported"); - } -} diff --git a/core/pom.xml b/core/pom.xml index 2b0a9f2f..bc07e2c6 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -35,5 +35,12 @@ 10.0.1 provided + + + com.google.code.gson + gson + 2.2.4 + provided + diff --git a/core/src/main/java/com/github/games647/fastlogin/core/shared/MojangApiConnector.java b/core/src/main/java/com/github/games647/fastlogin/core/mojang/MojangApiConnector.java similarity index 83% rename from core/src/main/java/com/github/games647/fastlogin/core/shared/MojangApiConnector.java rename to core/src/main/java/com/github/games647/fastlogin/core/mojang/MojangApiConnector.java index b2cbed7a..302df883 100644 --- a/core/src/main/java/com/github/games647/fastlogin/core/shared/MojangApiConnector.java +++ b/core/src/main/java/com/github/games647/fastlogin/core/mojang/MojangApiConnector.java @@ -1,9 +1,12 @@ -package com.github.games647.fastlogin.core.shared; +package com.github.games647.fastlogin.core.mojang; import com.github.games647.fastlogin.core.BalancedSSLFactory; +import com.github.games647.fastlogin.core.shared.FastLoginCore; +import com.github.games647.fastlogin.core.shared.LoginSession; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import com.google.gson.Gson; import java.io.BufferedReader; import java.io.IOException; @@ -22,14 +25,13 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.UUID; -import java.util.concurrent.ConcurrentMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; import javax.net.ssl.HttpsURLConnection; -public abstract class MojangApiConnector { +public class MojangApiConnector { //http connection, read timeout and user agent for a connection to mojang api servers private static final int TIMEOUT = 3 * 1_000; @@ -37,20 +39,20 @@ public abstract class MojangApiConnector { //only premium (paid account) users have a uuid from here private static final String UUID_LINK = "https://api.mojang.com/users/profiles/minecraft/"; - //this includes a-zA-Z1-9_ - private static final String VALID_PLAYERNAME = "^\\w{2,16}$"; private static final int RATE_LIMIT_CODE = 429; + //this includes a-zA-Z1-9_ //compile the pattern only on plugin enable -> and this have to be thread-safe - private final Pattern nameMatcher = Pattern.compile(VALID_PLAYERNAME); + private final Pattern validNameMatcher = Pattern.compile("^\\w{2,16}$"); private final Iterator proxies; - private final ConcurrentMap requests = FastLoginCore.buildCache(10, -1); + private final Map requests = FastLoginCore.buildCache(10, -1); private final BalancedSSLFactory sslFactory; private final int rateLimit; private long lastRateLimit; + protected final Gson gson = new Gson(); protected final Logger logger; public MojangApiConnector(Logger logger, Collection localAddresses, int rateLimit @@ -71,7 +73,7 @@ public abstract class MojangApiConnector { * @return null on non-premium */ public UUID getPremiumUUID(String playerName) { - if (!nameMatcher.matcher(playerName).matches()) { + if (!validNameMatcher.matcher(playerName).matches()) { //check if it's a valid player name return null; } @@ -113,9 +115,28 @@ public abstract class MojangApiConnector { return null; } - public abstract boolean hasJoinedServer(LoginSession session, String serverId, InetSocketAddress ip); + public boolean hasJoinedServer(LoginSession session, String serverId, InetSocketAddress ip) { + //only available in Spigot and not in BungeeCord + return false; + } - protected abstract String getUUIDFromJson(String json); + private String getUUIDFromJson(String json) { + boolean isArray = json.startsWith("["); + + Player mojangPlayer; + if (isArray) { + mojangPlayer = gson.fromJson(json, Player[].class)[0]; + } else { + mojangPlayer = gson.fromJson(json, Player.class); + } + + String id = mojangPlayer.getId(); + if ("null".equals(id)) { + return null; + } + + return id; + } protected HttpsURLConnection getConnection(String url, Proxy proxy) throws IOException { HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection(proxy); diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/MojangPlayer.java b/core/src/main/java/com/github/games647/fastlogin/core/mojang/Player.java similarity index 68% rename from bungee/src/main/java/com/github/games647/fastlogin/bungee/MojangPlayer.java rename to core/src/main/java/com/github/games647/fastlogin/core/mojang/Player.java index d028c43c..25656ad4 100644 --- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/MojangPlayer.java +++ b/core/src/main/java/com/github/games647/fastlogin/core/mojang/Player.java @@ -1,6 +1,6 @@ -package com.github.games647.fastlogin.bungee; +package com.github.games647.fastlogin.core.mojang; -public class MojangPlayer { +public class Player { private String id; private String name; diff --git a/core/src/main/java/com/github/games647/fastlogin/core/mojang/SkinProperties.java b/core/src/main/java/com/github/games647/fastlogin/core/mojang/SkinProperties.java new file mode 100644 index 00000000..95c606fd --- /dev/null +++ b/core/src/main/java/com/github/games647/fastlogin/core/mojang/SkinProperties.java @@ -0,0 +1,20 @@ +package com.github.games647.fastlogin.core.mojang; + +public class SkinProperties { + + private String name; + private String value; + private String signature; + + public String getName() { + return name; + } + + public String getValue() { + return value; + } + + public String getSignature() { + return signature; + } +} diff --git a/core/src/main/java/com/github/games647/fastlogin/core/mojang/VerificationReply.java b/core/src/main/java/com/github/games647/fastlogin/core/mojang/VerificationReply.java new file mode 100644 index 00000000..d147d4c0 --- /dev/null +++ b/core/src/main/java/com/github/games647/fastlogin/core/mojang/VerificationReply.java @@ -0,0 +1,20 @@ +package com.github.games647.fastlogin.core.mojang; + +public class VerificationReply { + + private String id; + private String name; + private SkinProperties[] properties; + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public SkinProperties[] getProperties() { + return properties; + } +} diff --git a/core/src/main/java/com/github/games647/fastlogin/core/shared/FastLoginCore.java b/core/src/main/java/com/github/games647/fastlogin/core/shared/FastLoginCore.java index 4961fb7f..1f149edc 100644 --- a/core/src/main/java/com/github/games647/fastlogin/core/shared/FastLoginCore.java +++ b/core/src/main/java/com/github/games647/fastlogin/core/shared/FastLoginCore.java @@ -6,6 +6,7 @@ import com.github.games647.fastlogin.core.SharedConfig; import com.github.games647.fastlogin.core.hooks.AuthPlugin; import com.github.games647.fastlogin.core.hooks.DefaultPasswordGenerator; import com.github.games647.fastlogin.core.hooks.PasswordGenerator; +import com.github.games647.fastlogin.core.mojang.MojangApiConnector; import com.google.common.cache.CacheLoader; import com.google.common.collect.Lists; import com.google.common.collect.Sets; diff --git a/core/src/main/java/com/github/games647/fastlogin/core/shared/PlatformPlugin.java b/core/src/main/java/com/github/games647/fastlogin/core/shared/PlatformPlugin.java index 45c84a5c..fc7b6ef3 100644 --- a/core/src/main/java/com/github/games647/fastlogin/core/shared/PlatformPlugin.java +++ b/core/src/main/java/com/github/games647/fastlogin/core/shared/PlatformPlugin.java @@ -1,5 +1,7 @@ package com.github.games647.fastlogin.core.shared; +import com.github.games647.fastlogin.core.mojang.MojangApiConnector; + import java.io.File; import java.io.Reader; import java.util.List;