mirror of
https://github.com/TuxCoding/FastLogin.git
synced 2025-07-29 18:27:36 +02:00
Thermos supports GSON so we could share the json parsing
This commit is contained in:
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ public class EncryptionUtilTest {
|
||||
byte[] token = EncryptionUtil.generateVerifyToken(random);
|
||||
|
||||
assertNotNull(token);
|
||||
assertEquals(token.length, 4);
|
||||
assertEquals(4, token.length);
|
||||
}
|
||||
|
||||
// @Test
|
||||
|
@ -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<CommandSen
|
||||
@Override
|
||||
public MojangApiConnector makeApiConnector(Logger logger, List<String> addresses, int requests
|
||||
, Map<String, Integer> proxies) {
|
||||
return new MojangApiBungee(logger, addresses, requests, proxies);
|
||||
return new MojangApiConnector(logger, addresses, requests, proxies);
|
||||
}
|
||||
}
|
||||
|
@ -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<String> localAddresses, int rateLimit
|
||||
, Map<String, Integer> 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");
|
||||
}
|
||||
}
|
@ -35,5 +35,12 @@
|
||||
<version>10.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.2.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -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<Proxy> proxies;
|
||||
private final ConcurrentMap<Object, Object> requests = FastLoginCore.buildCache(10, -1);
|
||||
private final Map<Object, Object> 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<String> 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);
|
@ -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;
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user