diff --git a/CHANGELOG.md b/CHANGELOG.md
index d9a39781..4381fe7d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+######1.7
+
+* Added support for making requests to Mojang from different IPv4 addresses
+
+######1.6.2
+
+* Fixed support for new LoginSecurity version
+
######1.6.1
* Fix message typo in BungeeCord which created a NPE if premium-warning is activated
diff --git a/bukkit/pom.xml b/bukkit/pom.xml
index ea988e89..b36ebd4a 100644
--- a/bukkit/pom.xml
+++ b/bukkit/pom.xml
@@ -5,7 +5,7 @@
com.github.games647
fastlogin
- 1.6.1
+ 1.7
../pom.xml
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 8ee57796..f76503b1 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
@@ -64,11 +64,11 @@ public class FastLoginBukkit extends JavaPlugin {
@Override
public void onEnable() {
- core.setMojangApiConnector(new MojangApiBukkit(core));
-
core.loadConfig();
core.loadMessages();
+ core.setMojangApiConnector(new MojangApiBukkit(core, getConfig().getStringList("ip-addresses")));
+
try {
if (ClassUtil.isPresent("org.spigotmc.SpigotConfig")) {
bungeeCord = Class.forName("org.spigotmc.SpigotConfig").getDeclaredField("bungee").getBoolean(null);
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 8bd54754..7cd81e51 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
@@ -6,6 +6,7 @@ import com.github.games647.fastlogin.core.MojangApiConnector;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
+import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
@@ -18,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) {
- super(plugin);
+ public MojangApiBukkit(FastLoginCore plugin, List localAddresses) {
+ super(plugin, localAddresses);
}
@Override
diff --git a/bungee/pom.xml b/bungee/pom.xml
index 46cb30c9..64437079 100644
--- a/bungee/pom.xml
+++ b/bungee/pom.xml
@@ -5,7 +5,7 @@
com.github.games647
fastlogin
- 1.6.1
+ 1.7
../pom.xml
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 d845d78d..1f825639 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
@@ -32,7 +32,7 @@ public class FastLoginBungee extends Plugin {
private final FastLoginCore loginCore = new BungeeCore(this);
private BungeeAuthPlugin bungeeAuthPlugin;
- private Configuration configuration;
+ private Configuration config;
private final Random random = new Random();
private final Set pendingConfirms = Sets.newHashSet();
@@ -41,22 +41,22 @@ public class FastLoginBungee extends Plugin {
@Override
public void onEnable() {
- loginCore.setMojangApiConnector(new MojangApiBungee(loginCore));
-
loginCore.loadConfig();
loginCore.loadMessages();
try {
File configFile = new File(getDataFolder(), "config.yml");
- configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
+ config = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
- String driver = configuration.getString("driver");
- String host = configuration.getString("host", "");
- int port = configuration.getInt("port", 3306);
- String database = configuration.getString("database");
+ loginCore.setMojangApiConnector(new MojangApiBungee(loginCore, config.getStringList("ip-addresses")));
- String username = configuration.getString("username", "");
- String password = configuration.getString("password", "");
+ String driver = config.getString("driver");
+ String host = config.getString("host", "");
+ int port = config.getInt("port", 3306);
+ String database = config.getString("database");
+
+ String username = config.getString("username", "");
+ String password = config.getString("password", "");
if (!loginCore.setupDatabase(driver, host, port, database, username, password)) {
return;
}
@@ -98,7 +98,7 @@ public class FastLoginBungee extends Plugin {
}
public Configuration getConfig() {
- return configuration;
+ return config;
}
public ConcurrentMap getSession() {
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 39bdeb9c..7f5db268 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
@@ -3,14 +3,15 @@ package com.github.games647.fastlogin.bungee;
import com.github.games647.fastlogin.core.FastLoginCore;
import com.github.games647.fastlogin.core.MojangApiConnector;
+import java.util.List;
import java.util.UUID;
import net.md_5.bungee.BungeeCord;
public class MojangApiBungee extends MojangApiConnector {
- public MojangApiBungee(FastLoginCore plugin) {
- super(plugin);
+ public MojangApiBungee(FastLoginCore plugin, List localAddresses) {
+ super(plugin, localAddresses);
}
@Override
diff --git a/core/pom.xml b/core/pom.xml
index e4621c1b..a790dea3 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -5,7 +5,7 @@
com.github.games647
fastlogin
- 1.6.1
+ 1.7
../pom.xml
diff --git a/core/src/main/java/com/github/games647/fastlogin/core/BalancedSSLFactory.java b/core/src/main/java/com/github/games647/fastlogin/core/BalancedSSLFactory.java
new file mode 100644
index 00000000..61e55a0f
--- /dev/null
+++ b/core/src/main/java/com/github/games647/fastlogin/core/BalancedSSLFactory.java
@@ -0,0 +1,80 @@
+package com.github.games647.fastlogin.core;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.net.ssl.SSLSocketFactory;
+
+public class BalancedSSLFactory extends SSLSocketFactory {
+
+ private final SSLSocketFactory oldFactory;
+
+ //in order to be thread-safe
+ private final List localAddresses;
+
+ private final Object lock = new Object();
+
+ private int id;
+
+ public BalancedSSLFactory(SSLSocketFactory oldFactory, Set localAddresses) {
+ this.oldFactory = oldFactory;
+ this.localAddresses = new ArrayList<>(localAddresses);
+ }
+
+ @Override
+ public String[] getDefaultCipherSuites() {
+ return oldFactory.getDefaultCipherSuites();
+ }
+
+ @Override
+ public String[] getSupportedCipherSuites() {
+ return oldFactory.getSupportedCipherSuites();
+ }
+
+ @Override
+ public Socket createSocket(Socket socket, String host, int port, boolean autoclose) throws IOException {
+ return oldFactory.createSocket(host, port, getNextLocalAddress(), 0);
+ }
+
+ @Override
+ public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
+ return oldFactory.createSocket(host, port, getNextLocalAddress(), 0);
+ }
+
+ @Override
+ public Socket createSocket(String host, int port, InetAddress localAddress, int localPort)
+ throws IOException, UnknownHostException {
+ //default
+ return oldFactory.createSocket(host, port, localAddress, localPort);
+ }
+
+ @Override
+ public Socket createSocket(InetAddress host, int port) throws IOException {
+ return oldFactory.createSocket(host, port, getNextLocalAddress(), 0);
+ }
+
+ @Override
+ public Socket createSocket(InetAddress host, int port, InetAddress local, int localPort) throws IOException {
+ //Default
+ return oldFactory.createSocket(host, port, local, localPort);
+ }
+
+ private InetAddress getNextLocalAddress() {
+ int next;
+ synchronized (lock) {
+ next = id;
+ id++;
+ if (next == Integer.MAX_VALUE) {
+ id = 0;
+ }
+ }
+
+ int index = next % localAddresses.size();
+ return localAddresses.get(index);
+ }
+}
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 7f84a9fc..8120ba2c 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
@@ -4,11 +4,18 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
+import java.net.InetAddress;
import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.regex.Pattern;
+import javax.net.ssl.HttpsURLConnection;
+
public abstract class MojangApiConnector {
//http connection, read timeout and user agent for a connection to mojang api servers
@@ -23,10 +30,33 @@ public abstract class MojangApiConnector {
//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;
+
protected final FastLoginCore plugin;
- public MojangApiConnector(FastLoginCore plugin) {
+ public MojangApiConnector(FastLoginCore plugin, List localAddresses) {
this.plugin = plugin;
+
+ if (localAddresses.isEmpty()) {
+ this.sslFactory = null;
+ } else {
+ Set addresses = new HashSet<>();
+ for (String localAddress : localAddresses) {
+ try {
+ InetAddress address = InetAddress.getByName(localAddress);
+ if (!address.isAnyLocalAddress()) {
+ plugin.getLogger().log(Level.WARNING, "Submitted IP-Address is not local", address);
+ continue;
+ }
+
+ addresses.add(address);
+ } catch (UnknownHostException ex) {
+ plugin.getLogger().log(Level.SEVERE, "IP-Address is unknown to us", ex);
+ }
+ }
+
+ this.sslFactory = new BalancedSSLFactory(HttpsURLConnection.getDefaultSSLSocketFactory(), addresses);
+ }
}
/**
@@ -39,7 +69,7 @@ public abstract class MojangApiConnector {
if (playernameMatcher.matcher(playerName).matches()) {
//only make a API call if the name is valid existing mojang account
try {
- HttpURLConnection connection = getConnection(UUID_LINK + playerName);
+ HttpsURLConnection connection = getConnection(UUID_LINK + playerName);
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = reader.readLine();
@@ -61,14 +91,18 @@ public abstract class MojangApiConnector {
protected abstract UUID getUUIDFromJson(String json);
- protected HttpURLConnection getConnection(String url) throws IOException {
- HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
+ protected HttpsURLConnection getConnection(String url) throws IOException {
+ HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
connection.setConnectTimeout(TIMEOUT);
connection.setReadTimeout(2 * TIMEOUT);
//the new Mojang API just uses json as response
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("User-Agent", USER_AGENT);
+ if (sslFactory != null) {
+ connection.setSSLSocketFactory(sslFactory);
+ }
+
return connection;
}
}
diff --git a/core/src/main/resources/config.yml b/core/src/main/resources/config.yml
index d5a0b819..354dfe7b 100644
--- a/core/src/main/resources/config.yml
+++ b/core/src/main/resources/config.yml
@@ -106,6 +106,22 @@ forwardSkin: true
# If they still want to invoke the command, they have to invoke /premium again
premium-warning: true
+# If you have autoRegister or nameChangeCheck enabled, you could be rate-limited by Mojang.
+# The requests of the both options will be only made by FastLogin if the username is unknown to the server
+# You are allowed to make 600 requests per 10-minutes (60 per minute)
+# If you own a big server this value could be too low
+# Once the limit is reached, new players are always logged in as cracked until the rate-limit is expired.
+# (to the next ten minutes)
+#
+# The limit is IP-wide. If you have multiple IPv4-Addreses you specify them here. FastLogin will then use it in rotating
+# order --> 5 different IP-addreses 5 * 600 per 10 minutes
+# If this list is empty only the default one will be used
+#
+# Lists are created like this:
+#ip-addresses:
+# - 192-168-0-2
+ip-addresses: []
+
# Database configuration
# Recommened is the use of MariaDB (a better version of MySQL)
diff --git a/pom.xml b/pom.xml
index 12bdba06..b7421785 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
pom
FastLogin
- 1.6.1
+ 1.7
2015
https://www.spigotmc.org/resources/fastlogin.14153/
diff --git a/universal/pom.xml b/universal/pom.xml
index 131a8d25..44f982c1 100644
--- a/universal/pom.xml
+++ b/universal/pom.xml
@@ -5,7 +5,7 @@
com.github.games647
fastlogin
- 1.6.1
+ 1.7
../pom.xml