From 1aba9a0f3b621d6bad1e4a5b3d84787895025509 Mon Sep 17 00:00:00 2001 From: games647 Date: Mon, 20 Jun 2016 14:12:29 +0200 Subject: [PATCH] Added us.mcapi.com as third-party APIs to workaround rate-limits (Fixes #27) --- CHANGELOG.md | 1 + .../fastlogin/bukkit/FastLoginBukkit.java | 4 +- .../fastlogin/bukkit/MojangApiBukkit.java | 11 ++++- .../fastlogin/bungee/FastLoginBungee.java | 4 +- .../fastlogin/bungee/McAPIProfile.java | 15 ++++++ .../fastlogin/bungee/MojangApiBungee.java | 10 +++- .../fastlogin/core/MojangApiConnector.java | 47 ++++++++++++++++++- core/src/main/resources/config.yml | 9 ++++ 8 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 bungee/src/main/java/com/github/games647/fastlogin/bungee/McAPIProfile.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 4381fe7d..bc5c8263 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ######1.7 * Added support for making requests to Mojang from different IPv4 addresses +* Added us.mcapi.com as third-party APIs to workaround rate-limits ######1.6.2 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 f76503b1..9808394c 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 @@ -67,7 +67,9 @@ public class FastLoginBukkit extends JavaPlugin { core.loadConfig(); core.loadMessages(); - core.setMojangApiConnector(new MojangApiBukkit(core, getConfig().getStringList("ip-addresses"))); + core.setMojangApiConnector(new MojangApiBukkit(core + , getConfig().getStringList("ip-addresses") + , getConfig().getBoolean("lookup-third-party"))); try { if (ClassUtil.isPresent("org.spigotmc.SpigotConfig")) { 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 7cd81e51..0de46498 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 @@ -19,8 +19,8 @@ public class MojangApiBukkit extends MojangApiConnector { //mojang api check to prove a player is logged in minecraft and made a join server request private static final String HAS_JOINED_URL = "https://sessionserver.mojang.com/session/minecraft/hasJoined?"; - public MojangApiBukkit(FastLoginCore plugin, List localAddresses) { - super(plugin, localAddresses); + public MojangApiBukkit(FastLoginCore plugin, List localAddresses, boolean apiLookup) { + super(plugin, localAddresses, apiLookup); } @Override @@ -70,4 +70,11 @@ public class MojangApiBukkit extends MojangApiConnector { String uuid = (String) userData.get("id"); return FastLoginCore.parseId(uuid); } + + @Override + protected UUID getUUIDFromJsonAPI(String json) { + JSONObject userData = (JSONObject) JSONValue.parse(json); + String uuid = (String) userData.get("uuid"); + return FastLoginCore.parseId(uuid); + } } 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 1f825639..e76d8ee7 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 @@ -48,7 +48,9 @@ public class FastLoginBungee extends Plugin { File configFile = new File(getDataFolder(), "config.yml"); config = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile); - loginCore.setMojangApiConnector(new MojangApiBungee(loginCore, config.getStringList("ip-addresses"))); + loginCore.setMojangApiConnector(new MojangApiBungee(loginCore + , config.getStringList("ip-addresses") + , config.getBoolean("lookup-third-party"))); String driver = config.getString("driver"); String host = config.getString("host", ""); diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/McAPIProfile.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/McAPIProfile.java new file mode 100644 index 00000000..c357aece --- /dev/null +++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/McAPIProfile.java @@ -0,0 +1,15 @@ +package com.github.games647.fastlogin.bungee; + +public class McAPIProfile { + + private String uuid; + private String name; + + public String getUuid() { + return uuid; + } + + public String getName() { + return name; + } +} 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 index 7f5db268..939b3370 100644 --- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/MojangApiBungee.java +++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/MojangApiBungee.java @@ -10,8 +10,8 @@ import net.md_5.bungee.BungeeCord; public class MojangApiBungee extends MojangApiConnector { - public MojangApiBungee(FastLoginCore plugin, List localAddresses) { - super(plugin, localAddresses); + public MojangApiBungee(FastLoginCore plugin, List localAddresses, boolean apiLookup) { + super(plugin, localAddresses, apiLookup); } @Override @@ -25,4 +25,10 @@ public class MojangApiBungee extends MojangApiConnector { //this is not needed in Bungee throw new UnsupportedOperationException("Not supported"); } + + @Override + protected UUID getUUIDFromJsonAPI(String json) { + McAPIProfile apiPlayer = BungeeCord.getInstance().gson.fromJson(json, McAPIProfile.class); + return FastLoginCore.parseId(apiPlayer.getUuid()); + } } diff --git a/core/src/main/java/com/github/games647/fastlogin/core/MojangApiConnector.java b/core/src/main/java/com/github/games647/fastlogin/core/MojangApiConnector.java index 8120ba2c..499b5fee 100644 --- a/core/src/main/java/com/github/games647/fastlogin/core/MojangApiConnector.java +++ b/core/src/main/java/com/github/games647/fastlogin/core/MojangApiConnector.java @@ -22,20 +22,27 @@ public abstract class MojangApiConnector { private static final int TIMEOUT = 1 * 1_000; private static final String USER_AGENT = "Premium-Checker"; + private static final String MCAPI_UUID_URL = "https://us.mc-api.net/v3/uuid/"; + //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; + //compile the pattern only on plugin enable -> and this have to be threadsafe private final Pattern playernameMatcher = Pattern.compile(VALID_PLAYERNAME); private final BalancedSSLFactory sslFactory; + private final boolean apiLookup; + private long lastRateLimit; protected final FastLoginCore plugin; - public MojangApiConnector(FastLoginCore plugin, List localAddresses) { + public MojangApiConnector(FastLoginCore plugin, List localAddresses, boolean apiLookup) { this.plugin = plugin; + this.apiLookup = apiLookup; if (localAddresses.isEmpty()) { this.sslFactory = null; @@ -68,6 +75,12 @@ public abstract class MojangApiConnector { //check if it's a valid playername if (playernameMatcher.matcher(playerName).matches()) { //only make a API call if the name is valid existing mojang account + + if (System.currentTimeMillis() - lastRateLimit < 1_000 * 60 * 10) { + plugin.getLogger().fine("STILL WAITING FOR RATE_LIMIT - TRYING Third-party API"); + return getUUIDFromAPI(playerName); + } + try { HttpsURLConnection connection = getConnection(UUID_LINK + playerName); if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { @@ -76,6 +89,10 @@ public abstract class MojangApiConnector { if (line != null && !line.equals("null")) { return getUUIDFromJson(line); } + } else if (connection.getResponseCode() == RATE_LIMIT_CODE) { + plugin.getLogger().info("RATE_LIMIT REACHED - TRYING SECOND API"); + lastRateLimit = System.currentTimeMillis(); + return getUUIDFromAPI(playerName); } //204 - no content for not found } catch (Exception ex) { @@ -87,10 +104,38 @@ public abstract class MojangApiConnector { return null; } + public UUID getUUIDFromAPI(String playerName) { + if (!playernameMatcher.matcher(playerName).matches()) { + return null; + } + + try { + HttpURLConnection httpConnection = (HttpURLConnection) new URL(MCAPI_UUID_URL + playerName).openConnection(); + httpConnection.addRequestProperty("Content-Type", "application/json"); + + if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) { + //cracked + return null; + } + + BufferedReader reader = new BufferedReader(new InputStreamReader(httpConnection.getInputStream())); + String line = reader.readLine(); + if (line != null && !line.equals("null")) { + return getUUIDFromAPI(playerName); + } + } catch (IOException iOException) { + plugin.getLogger().log(Level.SEVERE, "Tried converting name->uuid from third-party api", iOException); + } + + return null; + } + public abstract boolean hasJoinedServer(Object session, String serverId); protected abstract UUID getUUIDFromJson(String json); + protected abstract UUID getUUIDFromJsonAPI(String json); + protected HttpsURLConnection getConnection(String url) throws IOException { HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection(); connection.setConnectTimeout(TIMEOUT); diff --git a/core/src/main/resources/config.yml b/core/src/main/resources/config.yml index 354dfe7b..3f921b47 100644 --- a/core/src/main/resources/config.yml +++ b/core/src/main/resources/config.yml @@ -122,6 +122,15 @@ premium-warning: true # - 192-168-0-2 ip-addresses: [] +# This option exists because of the reason as the previous one. Once FastLogin hits the rate-limit it will make requests +# to a third-party API. In this case: https://us.mc-api.net - Please support them if you can +# +# For the next ten minutes FastLogin will make requests to this website. Once the ten minutes are expired FastLogin +# will make requests to Mojang again, because the rate-limit expired. (in order to reduce the load to the third-party-api) +# +# If you want to join the discussion visit this: https://github.com/games647/FastLogin/issues/27#issuecomment-226954350 +lookup-third-party: true + # Database configuration # Recommened is the use of MariaDB (a better version of MySQL)