diff --git a/.gitignore b/.gitignore
index 6864fd06..be7173a9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,4 +45,5 @@ gradle-app.setting
# Project module targets
bukkit/target
universal/target
-bungee/target
\ No newline at end of file
+bungee/target
+core/target
\ No newline at end of file
diff --git a/bukkit/pom.xml b/bukkit/pom.xml
index fb77afb6..7e69439c 100644
--- a/bukkit/pom.xml
+++ b/bukkit/pom.xml
@@ -5,7 +5,7 @@
com.github.games647
fastlogin
- 1.3.1
+ 1.4
../pom.xml
@@ -53,6 +53,13 @@
+
+ com.github.games647
+ fastlogin.core
+ ${project.version}
+ provided
+
+
org.spigotmc
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BukkitCore.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BukkitCore.java
new file mode 100644
index 00000000..318a68d2
--- /dev/null
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BukkitCore.java
@@ -0,0 +1,57 @@
+package com.github.games647.fastlogin.bukkit;
+
+import com.comphenix.protocol.utility.SafeCacheBuilder;
+import com.github.games647.fastlogin.core.FastLoginCore;
+import com.github.games647.fastlogin.core.PlayerProfile;
+import com.google.common.cache.CacheLoader;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
+import java.io.File;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
+
+public class BukkitCore extends FastLoginCore {
+
+ private final FastLoginBukkit plugin;
+
+ public BukkitCore(FastLoginBukkit plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public File getDataFolder() {
+ return plugin.getDataFolder();
+ }
+
+ @Override
+ public Logger getLogger() {
+ return plugin.getLogger();
+ }
+
+ @Override
+ public ConcurrentMap buildCache() {
+ return SafeCacheBuilder
+ .newBuilder()
+ .concurrencyLevel(20)
+ .expireAfterAccess(30, TimeUnit.MINUTES)
+ .build(new CacheLoader() {
+ @Override
+ public PlayerProfile load(String key) throws Exception {
+ //should be fetched manually
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ });
+ }
+
+ @Override
+ public ThreadFactory getThreadFactory() {
+ String pluginName = plugin.getName();
+ return new ThreadFactoryBuilder()
+ .setNameFormat(pluginName + " Database Pool Thread #%1$d")
+ //Hikari create daemons by default
+ .setDaemon(true)
+ .build();
+ }
+}
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/DelayedAuthHook.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/DelayedAuthHook.java
new file mode 100644
index 00000000..e89fc6e3
--- /dev/null
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/DelayedAuthHook.java
@@ -0,0 +1,70 @@
+package com.github.games647.fastlogin.bukkit;
+
+import com.github.games647.fastlogin.bukkit.hooks.AuthMeHook;
+import com.github.games647.fastlogin.bukkit.hooks.BukkitAuthPlugin;
+import com.github.games647.fastlogin.bukkit.hooks.CrazyLoginHook;
+import com.github.games647.fastlogin.bukkit.hooks.LogItHook;
+import com.github.games647.fastlogin.bukkit.hooks.LoginSecurityHook;
+import com.github.games647.fastlogin.bukkit.hooks.UltraAuthHook;
+import com.github.games647.fastlogin.bukkit.hooks.xAuthHook;
+import com.google.common.collect.Lists;
+
+import java.util.List;
+import java.util.logging.Level;
+
+import org.bukkit.Bukkit;
+
+public class DelayedAuthHook implements Runnable {
+
+ private final FastLoginBukkit plugin;
+
+ public DelayedAuthHook(FastLoginBukkit plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public void run() {
+ boolean hookFound = registerHooks();
+ if (plugin.isBungeeCord()) {
+ plugin.getLogger().info("BungeeCord setting detected. No auth plugin is required");
+ } else if (!hookFound) {
+ plugin.getLogger().warning("No auth plugin were found by this plugin "
+ + "(other plugins could hook into this after the intialization of this plugin)"
+ + "and bungeecord is deactivated. "
+ + "Either one or both of the checks have to pass in order to use this plugin");
+ }
+ }
+
+ private boolean registerHooks() {
+ BukkitAuthPlugin authPluginHook = null;
+ try {
+ List> supportedHooks = Lists.newArrayList(AuthMeHook.class
+ , CrazyLoginHook.class, LogItHook.class, LoginSecurityHook.class, UltraAuthHook.class
+ , xAuthHook.class);
+ for (Class extends BukkitAuthPlugin> clazz : supportedHooks) {
+ String pluginName = clazz.getSimpleName().replace("Hook", "");
+ //uses only member classes which uses AuthPlugin interface (skip interfaces)
+ if (Bukkit.getServer().getPluginManager().getPlugin(pluginName) != null) {
+ //check only for enabled plugins. A single plugin could be disabled by plugin managers
+ authPluginHook = clazz.newInstance();
+ plugin.getLogger().log(Level.INFO, "Hooking into auth plugin: {0}", pluginName);
+ break;
+ }
+ }
+ } catch (InstantiationException | IllegalAccessException ex) {
+ plugin.getLogger().log(Level.SEVERE, "Couldn't load the integration class", ex);
+ }
+
+ if (authPluginHook == null) {
+ //run this check for exceptions (errors) and not found plugins
+ plugin.getLogger().warning("No support offline Auth plugin found. ");
+ return false;
+ }
+
+ if (plugin.getAuthPlugin() != null) {
+ plugin.setAuthPluginHook(authPluginHook);
+ }
+
+ return true;
+ }
+}
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 82935595..1c9c383d 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
@@ -7,29 +7,19 @@ import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.utility.SafeCacheBuilder;
import com.github.games647.fastlogin.bukkit.commands.CrackedCommand;
import com.github.games647.fastlogin.bukkit.commands.PremiumCommand;
-import com.github.games647.fastlogin.bukkit.hooks.AuthMeHook;
import com.github.games647.fastlogin.bukkit.hooks.BukkitAuthPlugin;
-import com.github.games647.fastlogin.bukkit.hooks.CrazyLoginHook;
-import com.github.games647.fastlogin.bukkit.hooks.LogItHook;
-import com.github.games647.fastlogin.bukkit.hooks.LoginSecurityHook;
-import com.github.games647.fastlogin.bukkit.hooks.UltraAuthHook;
-import com.github.games647.fastlogin.bukkit.hooks.xAuthHook;
import com.github.games647.fastlogin.bukkit.listener.BukkitJoinListener;
import com.github.games647.fastlogin.bukkit.listener.BungeeCordListener;
-import com.github.games647.fastlogin.bukkit.listener.EncryptionPacketListener;
import com.github.games647.fastlogin.bukkit.listener.ProtocolSupportListener;
-import com.github.games647.fastlogin.bukkit.listener.StartPacketListener;
+import com.github.games647.fastlogin.bukkit.listener.packet.EncryptionPacketListener;
+import com.github.games647.fastlogin.bukkit.listener.packet.StartPacketListener;
+import com.github.games647.fastlogin.core.FastLoginCore;
import com.google.common.cache.CacheLoader;
-import com.google.common.collect.Lists;
import java.security.KeyPair;
-import java.sql.SQLException;
-import java.util.List;
-import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
-import java.util.logging.Logger;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
@@ -41,19 +31,11 @@ public class FastLoginBukkit extends JavaPlugin {
private static final int WORKER_THREADS = 5;
- public static UUID parseId(String withoutDashes) {
- return UUID.fromString(withoutDashes.substring(0, 8)
- + "-" + withoutDashes.substring(8, 12)
- + "-" + withoutDashes.substring(12, 16)
- + "-" + withoutDashes.substring(16, 20)
- + "-" + withoutDashes.substring(20, 32));
- }
-
//provide a immutable key pair to be thread safe | used for encrypting and decrypting traffic
private final KeyPair keyPair = EncryptionUtil.generateKeyPair();
- protected boolean bungeeCord;
- private Storage storage;
+ private boolean bungeeCord;
+ private final FastLoginCore core = new BukkitCore(this);
private boolean serverStarted;
//this map is thread-safe for async access (Packet Listener)
@@ -72,11 +54,12 @@ public class FastLoginBukkit extends JavaPlugin {
});
private BukkitAuthPlugin authPlugin;
- private final MojangApiConnector mojangApiConnector = new MojangApiConnector(this);
private PasswordGenerator passwordGenerator = new DefaultPasswordGenerator();
@Override
public void onEnable() {
+ core.setMojangApiConnector(new MojangApiBukkit(core));
+
try {
if (ClassUtil.isPresent("org.spigotmc.SpigotConfig")) {
bungeeCord = Class.forName("org.spigotmc.SpigotConfig").getDeclaredField("bungee").getBoolean(null);
@@ -111,11 +94,7 @@ public class FastLoginBukkit extends JavaPlugin {
String username = getConfig().getString("username", "");
String password = getConfig().getString("password", "");
- this.storage = new Storage(this, driver, host, port, database, username, password);
- try {
- storage.createTables();
- } catch (SQLException sqlEx) {
- getLogger().log(Level.SEVERE, "Failed to create database tables. Disabling plugin...", sqlEx);
+ if (!core.setupDatabase(driver, host, port, database, username, password)) {
setEnabled(false);
return;
}
@@ -137,20 +116,7 @@ public class FastLoginBukkit extends JavaPlugin {
}
//delay dependency setup because we load the plugin very early where plugins are initialized yet
- getServer().getScheduler().runTask(this, new Runnable() {
- @Override
- public void run() {
- boolean hookFound = registerHooks();
- if (bungeeCord) {
- getLogger().info("BungeeCord setting detected. No auth plugin is required");
- } else if (!hookFound) {
- getLogger().warning("No auth plugin were found by this plugin "
- + "(other plugins could hook into this after the intialization of this plugin)"
- + "and bungeecord is deactivated. "
- + "Either one or both of the checks have to pass in order to use this plugin");
- }
- }
- });
+ getServer().getScheduler().runTask(this, new DelayedAuthHook(this));
getServer().getPluginManager().registerEvents(new BukkitJoinListener(this), this);
@@ -169,11 +135,15 @@ public class FastLoginBukkit extends JavaPlugin {
player.removeMetadata(getName(), this);
}
- if (storage != null) {
- storage.close();
+ if (core != null) {
+ core.close();
}
}
+ public FastLoginCore getCore() {
+ return core;
+ }
+
public String generateStringPassword(Player player) {
return passwordGenerator.getRandomPassword(player);
}
@@ -201,10 +171,6 @@ public class FastLoginBukkit extends JavaPlugin {
return keyPair;
}
- public Storage getStorage() {
- return storage;
- }
-
/**
* Gets the auth plugin hook in order to interact with the plugins. This can be null if no supporting auth plugin
* was found.
@@ -216,7 +182,7 @@ public class FastLoginBukkit extends JavaPlugin {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
- Logger.getLogger(FastLoginBukkit.class.getName()).log(Level.SEVERE, null, ex);
+ getLogger().log(Level.SEVERE, null, ex);
}
}
@@ -227,45 +193,6 @@ public class FastLoginBukkit extends JavaPlugin {
this.authPlugin = authPlugin;
}
- /**
- * Gets the a connection in order to access important features from the Mojang API.
- *
- * @return the connector instance
- */
- public MojangApiConnector getApiConnector() {
- return mojangApiConnector;
- }
-
- private boolean registerHooks() {
- BukkitAuthPlugin authPluginHook = null;
- try {
- List> supportedHooks = Lists.newArrayList(AuthMeHook.class
- , CrazyLoginHook.class, LogItHook.class, LoginSecurityHook.class, UltraAuthHook.class
- , xAuthHook.class);
- for (Class extends BukkitAuthPlugin> clazz : supportedHooks) {
- String pluginName = clazz.getSimpleName().replace("Hook", "");
- //uses only member classes which uses AuthPlugin interface (skip interfaces)
- if (getServer().getPluginManager().getPlugin(pluginName) != null) {
- //check only for enabled plugins. A single plugin could be disabled by plugin managers
- authPluginHook = clazz.newInstance();
- getLogger().log(Level.INFO, "Hooking into auth plugin: {0}", pluginName);
- break;
- }
- }
- } catch (InstantiationException | IllegalAccessException ex) {
- getLogger().log(Level.SEVERE, "Couldn't load the integration class", ex);
- }
-
- if (authPluginHook == null) {
- //run this check for exceptions (errors) and not found plugins
- getLogger().warning("No support offline Auth plugin found. ");
- return false;
- }
-
- authPlugin = authPluginHook;
- return true;
- }
-
public boolean isBungeeCord() {
return bungeeCord;
}
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/ForceLoginTask.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/ForceLoginTask.java
index f131aff0..d5c0b86a 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/ForceLoginTask.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/ForceLoginTask.java
@@ -1,6 +1,8 @@
package com.github.games647.fastlogin.bukkit;
import com.github.games647.fastlogin.bukkit.hooks.BukkitAuthPlugin;
+import com.github.games647.fastlogin.core.PlayerProfile;
+import com.github.games647.fastlogin.core.Storage;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
@@ -35,7 +37,7 @@ public class ForceLoginTask implements Runnable {
BukkitAuthPlugin authPlugin = plugin.getAuthPlugin();
- Storage storage = plugin.getStorage();
+ Storage storage = plugin.getCore().getStorage();
PlayerProfile playerProfile = null;
if (storage != null) {
playerProfile = storage.getProfile(player.getName(), false);
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
new file mode 100644
index 00000000..c1e4873d
--- /dev/null
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/MojangApiBukkit.java
@@ -0,0 +1,73 @@
+package com.github.games647.fastlogin.bukkit;
+
+import com.comphenix.protocol.wrappers.WrappedSignedProperty;
+import com.github.games647.fastlogin.core.FastLoginCore;
+import com.github.games647.fastlogin.core.MojangApiConnector;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.util.UUID;
+import java.util.logging.Level;
+
+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
+ private static final String HAS_JOINED_URL = "https://sessionserver.mojang.com/session/minecraft/hasJoined?";
+
+ public MojangApiBukkit(FastLoginCore plugin) {
+ super(plugin);
+ }
+
+ @Override
+ public boolean hasJoinedServer(Object session, String serverId) {
+ if (!(session instanceof PlayerSession)) {
+ return false;
+ }
+
+ PlayerSession playerSession = (PlayerSession) session;
+ try {
+ String url = HAS_JOINED_URL + "username=" + playerSession.getUsername() + "&serverId=" + serverId;
+ HttpURLConnection conn = getConnection(url);
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+ String line = reader.readLine();
+ if (line != null && !line.equals("null")) {
+ //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));
+
+ JSONArray properties = (JSONArray) userData.get("properties");
+ JSONObject skinProperty = (JSONObject) properties.get(0);
+
+ String propertyName = (String) skinProperty.get("name");
+ if (propertyName.equals("textures")) {
+ String skinValue = (String) skinProperty.get("value");
+ String signature = (String) skinProperty.get("signature");
+ playerSession.setSkin(WrappedSignedProperty.fromValues(propertyName, skinValue, signature));
+ }
+
+ return true;
+ }
+ } catch (Exception ex) {
+ //catch not only ioexceptions also parse and NPE on unexpected json format
+ plugin.getLogger().log(Level.WARNING, "Failed to verify session", ex);
+ }
+
+ //this connection doesn't need to be closed. So can make use of keep alive in java
+ return false;
+ }
+
+ @Override
+ protected UUID getUUIDFromJson(String json) {
+ JSONObject userData = (JSONObject) JSONValue.parse(json);
+ String uuid = (String) userData.get("id");
+ return FastLoginCore.parseId(uuid);
+ }
+}
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/MojangApiConnector.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/MojangApiConnector.java
deleted file mode 100644
index 8eb4c206..00000000
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/MojangApiConnector.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package com.github.games647.fastlogin.bukkit;
-
-import com.comphenix.protocol.wrappers.WrappedSignedProperty;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.UUID;
-import java.util.logging.Level;
-import java.util.regex.Pattern;
-
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-import org.json.simple.JSONValue;
-
-public class MojangApiConnector {
-
- //http connection, read timeout and user agent for a connection to mojang api servers
- private static final int TIMEOUT = 1 * 1_000;
- private static final String USER_AGENT = "Premium-Checker";
-
- //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?";
-
- //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}$";
-
- //compile the pattern only on plugin enable -> and this have to be threadsafe
- private final Pattern playernameMatcher = Pattern.compile(VALID_PLAYERNAME);
-
- private final FastLoginBukkit plugin;
-
- public MojangApiConnector(FastLoginBukkit plugin) {
- this.plugin = plugin;
- }
-
- /**
- *
- * @param playerName
- * @return null on non-premium
- */
- public UUID getPremiumUUID(String playerName) {
- //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
- try {
- HttpURLConnection connection = getConnection(UUID_LINK + playerName);
- if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
- BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
- String line = reader.readLine();
- if (line != null && !line.equals("null")) {
- JSONObject userData = (JSONObject) JSONValue.parseWithException(line);
- String uuid = (String) userData.get("id");
- return parseId(uuid);
- }
- }
- //204 - no content for not found
- } catch (Exception ex) {
- plugin.getLogger().log(Level.SEVERE, "Failed to check if player has a paid account", ex);
- }
- //this connection doesn't need to be closed. So can make use of keep alive in java
- }
-
- return null;
- }
-
- public boolean hasJoinedServer(PlayerSession session, String serverId) {
- try {
- String url = HAS_JOINED_URL + "username=" + session.getUsername() + "&serverId=" + serverId;
- HttpURLConnection conn = getConnection(url);
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
- String line = reader.readLine();
- if (line != null && !line.equals("null")) {
- //validate parsing
- //http://wiki.vg/Protocol_Encryption#Server
- JSONObject userData = (JSONObject) JSONValue.parseWithException(line);
- String uuid = (String) userData.get("id");
- session.setUuid(parseId(uuid));
-
- JSONArray properties = (JSONArray) userData.get("properties");
- JSONObject skinProperty = (JSONObject) properties.get(0);
-
- String propertyName = (String) skinProperty.get("name");
- if (propertyName.equals("textures")) {
- String skinValue = (String) skinProperty.get("value");
- String signature = (String) skinProperty.get("signature");
- session.setSkin(WrappedSignedProperty.fromValues(propertyName, skinValue, signature));
- }
-
- return true;
- }
- } catch (Exception ex) {
- //catch not only ioexceptions also parse and NPE on unexpected json format
- plugin.getLogger().log(Level.WARNING, "Failed to verify session", ex);
- }
-
- //this connection doesn't need to be closed. So can make use of keep alive in java
- return false;
- }
-
- private UUID parseId(String withoutDashes) {
- return UUID.fromString(withoutDashes.substring(0, 8)
- + "-" + withoutDashes.substring(8, 12)
- + "-" + withoutDashes.substring(12, 16)
- + "-" + withoutDashes.substring(16, 20)
- + "-" + withoutDashes.substring(20, 32));
- }
-
- private HttpURLConnection getConnection(String url) throws IOException {
- HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
- connection.setConnectTimeout(TIMEOUT);
- connection.setReadTimeout(TIMEOUT);
- //the new Mojang API just uses json as response
- connection.setRequestProperty("Content-Type", "application/json");
- connection.setRequestProperty("User-Agent", USER_AGENT);
-
- return connection;
- }
-}
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/PlayerProfile.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/PlayerProfile.java
deleted file mode 100644
index b7de0de2..00000000
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/PlayerProfile.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.github.games647.fastlogin.bukkit;
-
-import java.util.UUID;
-
-public class PlayerProfile {
-
- private final String playerName;
-
- private long userId;
-
- private UUID uuid;
- private boolean premium;
- private String lastIp;
- private long lastLogin;
-
- public PlayerProfile(long userId, UUID uuid, String playerName, boolean premium
- , String lastIp, long lastLogin) {
- this.userId = userId;
- this.uuid = uuid;
- this.playerName = playerName;
- this.premium = premium;
- this.lastIp = lastIp;
- this.lastLogin = lastLogin;
- }
-
- public PlayerProfile(UUID uuid, String playerName, boolean premium, String lastIp) {
- this.userId = -1;
-
- this.uuid = uuid;
- this.playerName = playerName;
- this.premium = premium;
- this.lastIp = lastIp;
- }
-
- public String getPlayerName() {
- return playerName;
- }
-
- public synchronized long getUserId() {
- return userId;
- }
-
- protected synchronized void setUserId(long generatedId) {
- this.userId = generatedId;
- }
-
- public synchronized UUID getUuid() {
- return uuid;
- }
-
- public synchronized void setUuid(UUID uuid) {
- this.uuid = uuid;
- }
-
- public synchronized boolean isPremium() {
- return premium;
- }
-
- public synchronized void setPremium(boolean premium) {
- this.premium = premium;
- }
-
- public synchronized String getLastIp() {
- return lastIp;
- }
-
- public synchronized void setLastIp(String lastIp) {
- this.lastIp = lastIp;
- }
-
- public synchronized long getLastLogin() {
- return lastLogin;
- }
-
- public synchronized void setLastLogin(long lastLogin) {
- this.lastLogin = lastLogin;
- }
-}
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/commands/CrackedCommand.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/commands/CrackedCommand.java
index eb02804d..9f93c148 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/commands/CrackedCommand.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/commands/CrackedCommand.java
@@ -1,7 +1,7 @@
package com.github.games647.fastlogin.bukkit.commands;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
-import com.github.games647.fastlogin.bukkit.PlayerProfile;
+import com.github.games647.fastlogin.core.PlayerProfile;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
@@ -34,7 +34,7 @@ public class CrackedCommand implements CommandExecutor {
sender.sendMessage(ChatColor.YELLOW + "Sending request...");
} else {
//todo: load async if it's not in the cache anymore
- final PlayerProfile profile = plugin.getStorage().getProfile(sender.getName(), true);
+ final PlayerProfile profile = plugin.getCore().getStorage().getProfile(sender.getName(), true);
if (profile.isPremium()) {
sender.sendMessage(ChatColor.DARK_GREEN + "Removed from the list of premium players");
profile.setPremium(false);
@@ -42,7 +42,7 @@ public class CrackedCommand implements CommandExecutor {
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
- plugin.getStorage().save(profile);
+ plugin.getCore().getStorage().save(profile);
}
});
} else {
@@ -62,7 +62,7 @@ public class CrackedCommand implements CommandExecutor {
sender.sendMessage(ChatColor.YELLOW + "Sending request for player " + args[0] + "...");
} else {
//todo: load async if it's not in the cache anymore
- final PlayerProfile profile = plugin.getStorage().getProfile(args[0], true);
+ final PlayerProfile profile = plugin.getCore().getStorage().getProfile(args[0], true);
if (profile == null) {
sender.sendMessage(ChatColor.DARK_RED + "Player not in the database");
return true;
@@ -75,7 +75,7 @@ public class CrackedCommand implements CommandExecutor {
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
- plugin.getStorage().save(profile);
+ plugin.getCore().getStorage().save(profile);
}
});
} else {
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/commands/PremiumCommand.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/commands/PremiumCommand.java
index 8835747f..a25234a0 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/commands/PremiumCommand.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/commands/PremiumCommand.java
@@ -1,7 +1,7 @@
package com.github.games647.fastlogin.bukkit.commands;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
-import com.github.games647.fastlogin.bukkit.PlayerProfile;
+import com.github.games647.fastlogin.core.PlayerProfile;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
@@ -39,7 +39,7 @@ public class PremiumCommand implements CommandExecutor {
sender.sendMessage(ChatColor.YELLOW + "Sending request...");
} else {
// //todo: load async if it's not in the cache anymore
- final PlayerProfile profile = plugin.getStorage().getProfile(sender.getName(), true);
+ final PlayerProfile profile = plugin.getCore().getStorage().getProfile(sender.getName(), true);
if (profile.isPremium()) {
sender.sendMessage(ChatColor.DARK_RED + "You are already on the premium list");
} else {
@@ -48,7 +48,7 @@ public class PremiumCommand implements CommandExecutor {
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
- plugin.getStorage().save(profile);
+ plugin.getCore().getStorage().save(profile);
}
});
@@ -68,7 +68,7 @@ public class PremiumCommand implements CommandExecutor {
sender.sendMessage(ChatColor.YELLOW + "Sending request...");
} else {
//todo: load async if it's not in the cache anymore
- final PlayerProfile profile = plugin.getStorage().getProfile(args[0], true);
+ final PlayerProfile profile = plugin.getCore().getStorage().getProfile(args[0], true);
if (profile == null) {
sender.sendMessage(ChatColor.DARK_RED + "Player not in the database");
return true;
@@ -82,7 +82,7 @@ public class PremiumCommand implements CommandExecutor {
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
- plugin.getStorage().save(profile);
+ plugin.getCore().getStorage().save(profile);
}
});
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/AuthMeHook.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/AuthMeHook.java
index 5248007c..97aa8f05 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/AuthMeHook.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/AuthMeHook.java
@@ -30,9 +30,7 @@ public class AuthMeHook implements BukkitAuthPlugin {
} else {
API.forceLogin(player);
}
-
- //commented because the operation above is performed async -> race conditions
-// return NewAPI.getInstance().isAuthenticated(player);
+
return true;
}
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BukkitJoinListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BukkitJoinListener.java
index 8f2a8889..e83c7138 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BukkitJoinListener.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BukkitJoinListener.java
@@ -41,7 +41,6 @@ public class BukkitJoinListener implements Listener {
public void onPlayerJoin(PlayerJoinEvent joinEvent) {
Player player = joinEvent.getPlayer();
- //removing the session because we now use it
PlayerSession session = plugin.getSessions().get(player.getAddress().toString());
if (session != null && plugin.getConfig().getBoolean("forwardSkin")) {
WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player);
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ProtocolSupportListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ProtocolSupportListener.java
index 0519ed31..8a39fab1 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ProtocolSupportListener.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ProtocolSupportListener.java
@@ -1,9 +1,9 @@
package com.github.games647.fastlogin.bukkit.listener;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
-import com.github.games647.fastlogin.bukkit.PlayerProfile;
import com.github.games647.fastlogin.bukkit.PlayerSession;
import com.github.games647.fastlogin.bukkit.hooks.BukkitAuthPlugin;
+import com.github.games647.fastlogin.core.PlayerProfile;
import java.net.InetSocketAddress;
import java.util.UUID;
@@ -40,7 +40,7 @@ public class ProtocolSupportListener implements Listener {
return;
}
- PlayerProfile playerProfile = plugin.getStorage().getProfile(username, true);
+ PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(username, true);
if (playerProfile != null) {
if (playerProfile.isPremium()) {
if (playerProfile.getUserId() != -1) {
@@ -50,7 +50,7 @@ public class ProtocolSupportListener implements Listener {
//user not exists in the db
try {
if (plugin.getConfig().getBoolean("autoRegister") && !authPlugin.isRegistered(username)) {
- UUID premiumUUID = plugin.getApiConnector().getPremiumUUID(username);
+ UUID premiumUUID = plugin.getCore().getMojangApiConnector().getPremiumUUID(username);
if (premiumUUID != null) {
plugin.getLogger().log(Level.FINER, "Player {0} uses a premium username", username);
startPremiumSession(username, loginStartEvent, false);
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/EncryptionPacketListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/packet/EncryptionPacketListener.java
similarity index 98%
rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/EncryptionPacketListener.java
rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/packet/EncryptionPacketListener.java
index 7e9702d9..b1cabb94 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/EncryptionPacketListener.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/packet/EncryptionPacketListener.java
@@ -1,4 +1,4 @@
-package com.github.games647.fastlogin.bukkit.listener;
+package com.github.games647.fastlogin.bukkit.listener.packet;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolManager;
@@ -71,7 +71,6 @@ public class EncryptionPacketListener extends PacketAdapter {
*/
@Override
public void onPacketReceiving(PacketEvent packetEvent) {
- System.out.println("ENCRYPTION REQUEST");
Player player = packetEvent.getPlayer();
//the player name is unknown to ProtocolLib (so getName() doesn't work) - now uses ip:port as key
@@ -102,7 +101,7 @@ public class EncryptionPacketListener extends PacketAdapter {
String serverId = (new BigInteger(serverIdHash)).toString(16);
String username = session.getUsername();
- if (plugin.getApiConnector().hasJoinedServer(session, serverId)) {
+ if (plugin.getCore().getMojangApiConnector().hasJoinedServer(session, serverId)) {
plugin.getLogger().log(Level.FINE, "Player {0} has a verified premium account", username);
session.setVerified(true);
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/StartPacketListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/packet/StartPacketListener.java
similarity index 95%
rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/StartPacketListener.java
rename to bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/packet/StartPacketListener.java
index 65377a1c..03b8bb03 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/StartPacketListener.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/packet/StartPacketListener.java
@@ -1,4 +1,4 @@
-package com.github.games647.fastlogin.bukkit.listener;
+package com.github.games647.fastlogin.bukkit.listener.packet;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolManager;
@@ -6,7 +6,7 @@ import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
-import com.github.games647.fastlogin.bukkit.PlayerProfile;
+import com.github.games647.fastlogin.core.PlayerProfile;
import com.github.games647.fastlogin.bukkit.PlayerSession;
import com.github.games647.fastlogin.bukkit.hooks.BukkitAuthPlugin;
@@ -83,7 +83,7 @@ public class StartPacketListener extends PacketAdapter {
return;
}
- PlayerProfile playerProfile = plugin.getStorage().getProfile(username, true);
+ PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(username, true);
if (playerProfile != null) {
if (playerProfile.isPremium()) {
if (playerProfile.getUserId() != -1) {
@@ -93,7 +93,7 @@ public class StartPacketListener extends PacketAdapter {
//user not exists in the db
try {
if (plugin.getConfig().getBoolean("autoRegister") && !authPlugin.isRegistered(username)) {
- UUID premiumUUID = plugin.getApiConnector().getPremiumUUID(username);
+ UUID premiumUUID = plugin.getCore().getMojangApiConnector().getPremiumUUID(username);
if (premiumUUID != null) {
plugin.getLogger().log(Level.FINER, "Player {0} uses a premium username", username);
enablePremiumLogin(username, sessionKey, player, packetEvent, false);
diff --git a/bungee/pom.xml b/bungee/pom.xml
index 85af835b..026aa400 100644
--- a/bungee/pom.xml
+++ b/bungee/pom.xml
@@ -5,7 +5,7 @@
com.github.games647
fastlogin
- 1.3.1
+ 1.4
../pom.xml
@@ -37,6 +37,13 @@
+
+ ${project.groupId}
+ fastlogin.core
+ ${project.version}
+ provided
+
+
net.md-5
bungeecord-proxy
diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/AsyncPremiumCheck.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/AsyncPremiumCheck.java
new file mode 100644
index 00000000..2bff5fa4
--- /dev/null
+++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/AsyncPremiumCheck.java
@@ -0,0 +1,52 @@
+package com.github.games647.fastlogin.bungee;
+
+import com.github.games647.fastlogin.bungee.FastLoginBungee;
+import com.github.games647.fastlogin.bungee.hooks.BungeeAuthPlugin;
+import com.github.games647.fastlogin.core.PlayerProfile;
+import java.util.UUID;
+import java.util.logging.Level;
+import net.md_5.bungee.api.connection.PendingConnection;
+import net.md_5.bungee.api.event.PreLoginEvent;
+
+public class AsyncPremiumCheck implements Runnable {
+
+ private final FastLoginBungee plugin;
+ private final PreLoginEvent preLoginEvent;
+
+ public AsyncPremiumCheck(FastLoginBungee plugin, PreLoginEvent preLoginEvent) {
+ this.plugin = plugin;
+ this.preLoginEvent = preLoginEvent;
+ }
+
+ @Override
+ public void run() {
+ PendingConnection connection = preLoginEvent.getConnection();
+ String username = connection.getName();
+ try {
+ PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(username, true);
+ if (playerProfile != null) {
+ if (playerProfile.isPremium()) {
+ if (playerProfile.getUserId() != -1) {
+ connection.setOnlineMode(true);
+ }
+ } else if (playerProfile.getUserId() == -1) {
+ //user not exists in the db
+ BungeeAuthPlugin authPlugin = plugin.getBungeeAuthPlugin();
+ if (plugin.getConfiguration().getBoolean("autoRegister")
+ && (authPlugin == null || !authPlugin.isRegistered(username))) {
+ UUID premiumUUID = plugin.getCore().getMojangApiConnector().getPremiumUUID(username);
+ if (premiumUUID != null) {
+ plugin.getLogger().log(Level.FINER, "Player {0} uses a premium username", username);
+ connection.setOnlineMode(true);
+ plugin.getPendingAutoRegister().put(connection, new Object());
+ }
+ }
+ }
+ }
+ } catch (Exception ex) {
+ plugin.getLogger().log(Level.SEVERE, "Failed to check premium state", ex);
+ } finally {
+ preLoginEvent.completeIntent(plugin);
+ }
+ }
+}
diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/BungeeCore.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/BungeeCore.java
new file mode 100644
index 00000000..7e7719d3
--- /dev/null
+++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/BungeeCore.java
@@ -0,0 +1,52 @@
+package com.github.games647.fastlogin.bungee;
+
+import com.github.games647.fastlogin.core.FastLoginCore;
+import com.github.games647.fastlogin.core.PlayerProfile;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
+import java.io.File;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
+
+import net.md_5.bungee.api.scheduler.GroupedThreadFactory;
+
+public class BungeeCore extends FastLoginCore {
+
+ private final FastLoginBungee plugin;
+
+ public BungeeCore(FastLoginBungee plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public File getDataFolder() {
+ return plugin.getDataFolder();
+ }
+
+ @Override
+ public Logger getLogger() {
+ return plugin.getLogger();
+ }
+
+ @Override
+ public ConcurrentMap buildCache() {
+ return CacheBuilder
+ .newBuilder()
+ .concurrencyLevel(20)
+ .expireAfterAccess(30, TimeUnit.MINUTES)
+ .build().asMap();
+ }
+
+ @Override
+ public ThreadFactory getThreadFactory() {
+ String pluginName = plugin.getDescription().getName();
+ return new ThreadFactoryBuilder()
+ .setNameFormat(pluginName + " Database Pool Thread #%1$d")
+ //Hikari create daemons by default
+ .setDaemon(true)
+ .setThreadFactory(new GroupedThreadFactory(plugin, pluginName)).build();
+ }
+}
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 600b238e..4f8c0543 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
@@ -1,9 +1,10 @@
package com.github.games647.fastlogin.bungee;
-import com.github.games647.fastlogin.bungee.listener.PlayerConnectionListener;
import com.github.games647.fastlogin.bungee.hooks.BungeeAuthHook;
import com.github.games647.fastlogin.bungee.hooks.BungeeAuthPlugin;
+import com.github.games647.fastlogin.bungee.listener.PlayerConnectionListener;
import com.github.games647.fastlogin.bungee.listener.PluginMessageListener;
+import com.github.games647.fastlogin.core.FastLoginCore;
import com.google.common.cache.CacheBuilder;
import java.io.File;
@@ -11,12 +12,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.Random;
-import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
-import net.md_5.bungee.Util;
import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.config.Configuration;
@@ -28,16 +27,11 @@ import net.md_5.bungee.config.YamlConfiguration;
*/
public class FastLoginBungee extends Plugin {
- private static final char[] CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+ private static final char[] PASSWORD_CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
.toCharArray();
- public static UUID parseId(String withoutDashes) {
- return Util.getUUID(withoutDashes);
- }
-
+ private final FastLoginCore loginCore = new BungeeCore(this);
private BungeeAuthPlugin bungeeAuthPlugin;
- private final MojangApiConnector mojangApiConnector = new MojangApiConnector(this);
- private Storage storage;
private Configuration configuration;
private final Random random = new Random();
@@ -49,6 +43,8 @@ public class FastLoginBungee extends Plugin {
@Override
public void onEnable() {
+ loginCore.setMojangApiConnector(new MojangApiBungee(loginCore));
+
if (!getDataFolder().exists()) {
getDataFolder().mkdir();
}
@@ -72,14 +68,9 @@ public class FastLoginBungee extends Plugin {
String username = configuration.getString("username", "");
String password = configuration.getString("password", "");
- storage = new Storage(this, driver, host, port, database, username, password);
- try {
- storage.createTables();
- } catch (Exception ex) {
- getLogger().log(Level.SEVERE, "Failed to setup database. Disabling plugin...", ex);
+ if (!loginCore.setupDatabase(driver, host, port, database, username, password)) {
return;
}
-
} catch (IOException ioExc) {
getLogger().log(Level.SEVERE, "Error loading config. Disabling plugin...", ioExc);
return;
@@ -98,7 +89,7 @@ public class FastLoginBungee extends Plugin {
public String generateStringPassword() {
StringBuilder generatedPassword = new StringBuilder(8);
for (int i = 1; i <= 8; i++) {
- generatedPassword.append(CHARACTERS[random.nextInt(CHARACTERS.length - 1)]);
+ generatedPassword.append(PASSWORD_CHARACTERS[random.nextInt(PASSWORD_CHARACTERS.length - 1)]);
}
return generatedPassword.toString();
@@ -106,23 +97,21 @@ public class FastLoginBungee extends Plugin {
@Override
public void onDisable() {
- if (storage != null) {
- storage.close();
- }
+ loginCore.close();
+ }
+
+ public FastLoginCore getCore() {
+ return loginCore;
+ }
+
+ public void setAuthPluginHook(BungeeAuthPlugin authPlugin) {
+ this.bungeeAuthPlugin = authPlugin;
}
public Configuration getConfiguration() {
return configuration;
}
- public Storage getStorage() {
- return storage;
- }
-
- public MojangApiConnector getMojangApiConnector() {
- return mojangApiConnector;
- }
-
public ConcurrentMap getPendingAutoRegister() {
return pendingAutoRegister;
}
diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/ForceLoginTask.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/ForceLoginTask.java
index d66d21cf..2f619003 100644
--- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/ForceLoginTask.java
+++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/ForceLoginTask.java
@@ -1,5 +1,6 @@
package com.github.games647.fastlogin.bungee;
+import com.github.games647.fastlogin.core.PlayerProfile;
import com.github.games647.fastlogin.bungee.hooks.BungeeAuthPlugin;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
@@ -23,7 +24,7 @@ public class ForceLoginTask implements Runnable {
@Override
public void run() {
- PlayerProfile playerProfile = plugin.getStorage().getProfile(player.getName(), false);
+ PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(player.getName(), false);
//force login only on success
if (player.getPendingConnection().isOnlineMode()) {
@@ -46,7 +47,7 @@ public class ForceLoginTask implements Runnable {
//cracked player
//update only on success to prevent corrupt data
playerProfile.setPremium(false);
- plugin.getStorage().save(playerProfile);
+ plugin.getCore().getStorage().save(playerProfile);
}
}
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
new file mode 100644
index 00000000..39bdeb9c
--- /dev/null
+++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/MojangApiBungee.java
@@ -0,0 +1,27 @@
+package com.github.games647.fastlogin.bungee;
+
+import com.github.games647.fastlogin.core.FastLoginCore;
+import com.github.games647.fastlogin.core.MojangApiConnector;
+
+import java.util.UUID;
+
+import net.md_5.bungee.BungeeCord;
+
+public class MojangApiBungee extends MojangApiConnector {
+
+ public MojangApiBungee(FastLoginCore plugin) {
+ super(plugin);
+ }
+
+ @Override
+ protected UUID getUUIDFromJson(String json) {
+ MojangPlayer mojangPlayer = BungeeCord.getInstance().gson.fromJson(json, MojangPlayer.class);
+ return FastLoginCore.parseId(mojangPlayer.getId());
+ }
+
+ @Override
+ public boolean hasJoinedServer(Object session, String serverId) {
+ //this is not needed in Bungee
+ throw new UnsupportedOperationException("Not supported");
+ }
+}
diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/Storage.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/Storage.java
deleted file mode 100644
index 7e66700a..00000000
--- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/Storage.java
+++ /dev/null
@@ -1,211 +0,0 @@
-package com.github.games647.fastlogin.bungee;
-
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import com.zaxxer.hikari.HikariConfig;
-import com.zaxxer.hikari.HikariDataSource;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
-import net.md_5.bungee.api.scheduler.GroupedThreadFactory;
-
-public class Storage {
-
- private static final String PREMIUM_TABLE = "premium";
-
- private final ConcurrentMap profileCache = CacheBuilder
- .newBuilder()
- .concurrencyLevel(20)
- .expireAfterAccess(30, TimeUnit.MINUTES)
- .build(new CacheLoader() {
- @Override
- public PlayerProfile load(String key) throws Exception {
- //should be fetched manually
- throw new UnsupportedOperationException("Not supported yet.");
- }
- }).asMap();
-
- private final HikariDataSource dataSource;
- private final FastLoginBungee plugin;
-
- public Storage(FastLoginBungee plugin, String driver, String host, int port, String databasePath
- , String user, String pass) {
- this.plugin = plugin;
-
- HikariConfig databaseConfig = new HikariConfig();
- databaseConfig.setUsername(user);
- databaseConfig.setPassword(pass);
- databaseConfig.setDriverClassName(driver);
- String pluginName = plugin.getDescription().getName();
-
- //set a custom thread factory to remove BungeeCord warning about different threads
- databaseConfig.setThreadFactory(new ThreadFactoryBuilder()
- .setNameFormat(pluginName + " Database Pool Thread #%1$d")
- //Hikari create daemons by default
- .setDaemon(true)
- .setThreadFactory(new GroupedThreadFactory(plugin, pluginName)).build());
-
- databasePath = databasePath.replace("{pluginDir}", plugin.getDataFolder().getAbsolutePath());
-
- String jdbcUrl = "jdbc:";
- if (driver.contains("sqlite")) {
- jdbcUrl += "sqlite" + "://" + databasePath;
- databaseConfig.setConnectionTestQuery("SELECT 1");
- } else {
- jdbcUrl += "mysql" + "://" + host + ':' + port + '/' + databasePath;
- }
-
- databaseConfig.setJdbcUrl(jdbcUrl);
- this.dataSource = new HikariDataSource(databaseConfig);
- }
-
- public void createTables() throws SQLException {
- Connection con = null;
- try {
- con = dataSource.getConnection();
- Statement statement = con.createStatement();
- String createDataStmt = "CREATE TABLE IF NOT EXISTS " + PREMIUM_TABLE + " ("
- + "`UserID` INTEGER PRIMARY KEY AUTO_INCREMENT, "
- + "`UUID` CHAR(36), "
- + "`Name` VARCHAR(16) NOT NULL, "
- + "`Premium` BOOLEAN NOT NULL, "
- + "`LastIp` VARCHAR(255) NOT NULL, "
- + "`LastLogin` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "
- + "UNIQUE (`UUID`), "
- //the premium shouldn't steal the cracked account by changing the name
- + "UNIQUE (`Name`) "
- + ")";
-
- if (dataSource.getJdbcUrl().contains("sqlite")) {
- createDataStmt = createDataStmt.replace("AUTO_INCREMENT", "AUTOINCREMENT");
- }
-
- statement.executeUpdate(createDataStmt);
- } finally {
- closeQuietly(con);
- }
- }
-
- public PlayerProfile getProfile(String name, boolean fetch) {
- if (profileCache.containsKey(name)) {
- return profileCache.get(name);
- } else if (fetch) {
- Connection con = null;
- try {
- con = dataSource.getConnection();
- PreparedStatement loadStatement = con.prepareStatement("SELECT * FROM " + PREMIUM_TABLE
- + " WHERE `Name`=? LIMIT 1");
- loadStatement.setString(1, name);
-
- ResultSet resultSet = loadStatement.executeQuery();
- if (resultSet.next()) {
- long userId = resultSet.getInt(1);
-
- String unparsedUUID = resultSet.getString(2);
- UUID uuid;
- if (unparsedUUID == null) {
- uuid = null;
- } else {
- uuid = FastLoginBungee.parseId(unparsedUUID);
- }
-
-// String name = resultSet.getString(3);
- boolean premium = resultSet.getBoolean(4);
- String lastIp = resultSet.getString(5);
- long lastLogin = resultSet.getTimestamp(6).getTime();
- PlayerProfile playerProfile = new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
- profileCache.put(name, playerProfile);
- return playerProfile;
- } else {
- PlayerProfile crackedProfile = new PlayerProfile(null, name, false, "");
- profileCache.put(name, crackedProfile);
- return crackedProfile;
- }
- } catch (SQLException sqlEx) {
- plugin.getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);
- } finally {
- closeQuietly(con);
- }
- }
-
- return null;
- }
-
- public boolean save(PlayerProfile playerProfile) {
- Connection con = null;
- try {
- con = dataSource.getConnection();
-
- UUID uuid = playerProfile.getUuid();
-
- if (playerProfile.getUserId() == -1) {
- PreparedStatement saveStatement = con.prepareStatement("INSERT INTO " + PREMIUM_TABLE
- + " (UUID, Name, Premium, LastIp) VALUES (?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
-
- if (uuid == null) {
- saveStatement.setString(1, null);
- } else {
- saveStatement.setString(1, uuid.toString().replace("-", ""));
- }
-
- saveStatement.setString(2, playerProfile.getPlayerName());
- saveStatement.setBoolean(3, playerProfile.isPremium());
- saveStatement.setString(4, playerProfile.getLastIp());
- saveStatement.execute();
-
- ResultSet generatedKeys = saveStatement.getGeneratedKeys();
- if (generatedKeys != null && generatedKeys.next()) {
- playerProfile.setUserId(generatedKeys.getInt(1));
- }
- } else {
- PreparedStatement saveStatement = con.prepareStatement("UPDATE " + PREMIUM_TABLE
- + " SET UUID=?, Name=?, Premium=?, LastIp=?, LastLogin=CURRENT_TIMESTAMP WHERE UserID=?");
-
- if (uuid == null) {
- saveStatement.setString(1, null);
- } else {
- saveStatement.setString(1, uuid.toString().replace("-", ""));
- }
-
- saveStatement.setString(2, playerProfile.getPlayerName());
- saveStatement.setBoolean(3, playerProfile.isPremium());
- saveStatement.setString(4, playerProfile.getLastIp());
-// saveStatement.setTimestamp(5, new Timestamp(playerProfile.getLastLogin()));
-
- saveStatement.setLong(5, playerProfile.getUserId());
- saveStatement.execute();
- }
-
- return true;
- } catch (SQLException ex) {
- plugin.getLogger().log(Level.SEVERE, "Failed to save playerProfile", ex);
- } finally {
- closeQuietly(con);
- }
-
- return false;
- }
-
- public void close() {
- dataSource.close();
- profileCache.clear();
- }
-
- private void closeQuietly(Connection con) {
- if (con != null) {
- try {
- con.close();
- } catch (SQLException sqlEx) {
- plugin.getLogger().log(Level.SEVERE, "Failed to close connection", sqlEx);
- }
- }
- }
-}
diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/AsyncStatusMessage.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/AsyncStatusMessage.java
new file mode 100644
index 00000000..6ee6726c
--- /dev/null
+++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/AsyncStatusMessage.java
@@ -0,0 +1,72 @@
+package com.github.games647.fastlogin.bungee.listener;
+
+import com.github.games647.fastlogin.bungee.FastLoginBungee;
+import com.github.games647.fastlogin.core.PlayerProfile;
+
+import net.md_5.bungee.api.ChatColor;
+import net.md_5.bungee.api.chat.TextComponent;
+import net.md_5.bungee.api.connection.ProxiedPlayer;
+
+public class AsyncStatusMessage implements Runnable {
+
+ private final FastLoginBungee plugin;
+ private final ProxiedPlayer fromPlayer;
+ private final String targetPlayer;
+ private final boolean toPremium;
+
+ public AsyncStatusMessage(FastLoginBungee plugin, ProxiedPlayer fromPlayer, String targetPlayer, boolean toPremium) {
+ this.plugin = plugin;
+ this.fromPlayer = fromPlayer;
+ this.targetPlayer = targetPlayer;
+ this.toPremium = toPremium;
+ }
+
+ @Override
+ public void run() {
+ if (toPremium) {
+ activatePremium();
+ } else {
+ turnOffPremium();
+ }
+ }
+
+ private void turnOffPremium() {
+ PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(targetPlayer, true);
+ if (!playerProfile.isPremium()) {
+ if (fromPlayer.isConnected()) {
+ TextComponent textComponent = new TextComponent("You are not in the premium list");
+ textComponent.setColor(ChatColor.DARK_RED);
+ fromPlayer.sendMessage(textComponent);
+ }
+
+ return;
+ }
+
+ playerProfile.setPremium(false);
+ playerProfile.setUuid(null);
+ plugin.getCore().getStorage().save(playerProfile);
+ TextComponent textComponent = new TextComponent("Removed to the list of premium players");
+ textComponent.setColor(ChatColor.DARK_GREEN);
+ fromPlayer.sendMessage(textComponent);
+ }
+
+ private void activatePremium() {
+ PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(targetPlayer, true);
+ if (playerProfile.isPremium()) {
+ if (fromPlayer.isConnected()) {
+ TextComponent textComponent = new TextComponent("You are already on the premium list");
+ textComponent.setColor(ChatColor.DARK_RED);
+ fromPlayer.sendMessage(textComponent);
+ }
+
+ return;
+ }
+
+ playerProfile.setPremium(true);
+ //todo: set uuid
+ plugin.getCore().getStorage().save(playerProfile);
+ TextComponent textComponent = new TextComponent("Added to the list of premium players");
+ textComponent.setColor(ChatColor.DARK_GREEN);
+ fromPlayer.sendMessage(textComponent);
+ }
+}
diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/PlayerConnectionListener.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/PlayerConnectionListener.java
index 47bcd62b..3f0e9c0b 100644
--- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/PlayerConnectionListener.java
+++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/PlayerConnectionListener.java
@@ -1,9 +1,9 @@
package com.github.games647.fastlogin.bungee.listener;
+import com.github.games647.fastlogin.bungee.AsyncPremiumCheck;
import com.github.games647.fastlogin.bungee.FastLoginBungee;
import com.github.games647.fastlogin.bungee.ForceLoginTask;
-import com.github.games647.fastlogin.bungee.PlayerProfile;
-import com.github.games647.fastlogin.bungee.hooks.BungeeAuthPlugin;
+import com.github.games647.fastlogin.core.PlayerProfile;
import com.google.common.base.Charsets;
import java.lang.reflect.Field;
@@ -36,45 +36,13 @@ public class PlayerConnectionListener implements Listener {
}
@EventHandler
- public void onPreLogin(final PreLoginEvent preLoginEvent) {
+ public void onPreLogin(PreLoginEvent preLoginEvent) {
if (preLoginEvent.isCancelled()) {
return;
}
preLoginEvent.registerIntent(plugin);
- ProxyServer.getInstance().getScheduler().runAsync(plugin, new Runnable() {
- @Override
- public void run() {
- PendingConnection connection = preLoginEvent.getConnection();
- String username = connection.getName();
- try {
- PlayerProfile playerProfile = plugin.getStorage().getProfile(username, true);
- if (playerProfile != null) {
- if (playerProfile.isPremium()) {
- if (playerProfile.getUserId() != -1) {
- connection.setOnlineMode(true);
- }
- } else if (playerProfile.getUserId() == -1) {
- //user not exists in the db
- BungeeAuthPlugin authPlugin = plugin.getBungeeAuthPlugin();
- if (plugin.getConfiguration().getBoolean("autoRegister")
- && (authPlugin == null || !authPlugin.isRegistered(username))) {
- UUID premiumUUID = plugin.getMojangApiConnector().getPremiumUUID(username);
- if (premiumUUID != null) {
- plugin.getLogger().log(Level.FINER, "Player {0} uses a premium username", username);
- connection.setOnlineMode(true);
- plugin.getPendingAutoRegister().put(connection, new Object());
- }
- }
- }
- }
- } catch (Exception ex) {
- plugin.getLogger().log(Level.SEVERE, "Failed to check premium state", ex);
- } finally {
- preLoginEvent.completeIntent(plugin);
- }
- }
- });
+ ProxyServer.getInstance().getScheduler().runAsync(plugin, new AsyncPremiumCheck(plugin, preLoginEvent));
}
@EventHandler
@@ -83,7 +51,7 @@ public class PlayerConnectionListener implements Listener {
PendingConnection connection = player.getPendingConnection();
String username = connection.getName();
if (connection.isOnlineMode()) {
- PlayerProfile playerProfile = plugin.getStorage().getProfile(player.getName(), false);
+ PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(player.getName(), false);
playerProfile.setUuid(player.getUniqueId());
//bungeecord will do this automatically so override it on disabled option
@@ -92,12 +60,11 @@ public class PlayerConnectionListener implements Listener {
try {
UUID offlineUUID = UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(Charsets.UTF_8));
+ //bungeecord doesn't support overriding the premium uuid
+ //so we have to do it with reflection
Field idField = initialHandler.getClass().getDeclaredField("uniqueId");
idField.setAccessible(true);
idField.set(connection, offlineUUID);
-
- //bungeecord doesn't support overriding the premium uuid
-// connection.setUniqueId(offlineUUID);
} catch (NoSuchFieldException | IllegalAccessException ex) {
plugin.getLogger().log(Level.SEVERE, "Failed to set offline uuid", ex);
}
diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/PluginMessageListener.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/PluginMessageListener.java
index 17e01906..e8989729 100644
--- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/PluginMessageListener.java
+++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/listener/PluginMessageListener.java
@@ -1,13 +1,11 @@
package com.github.games647.fastlogin.bungee.listener;
import com.github.games647.fastlogin.bungee.FastLoginBungee;
-import com.github.games647.fastlogin.bungee.PlayerProfile;
+import com.github.games647.fastlogin.core.PlayerProfile;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
-import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.ProxyServer;
-import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.connection.Server;
import net.md_5.bungee.api.event.PluginMessageEvent;
@@ -44,66 +42,25 @@ public class PluginMessageListener implements Listener {
ByteArrayDataInput dataInput = ByteStreams.newDataInput(data);
String subchannel = dataInput.readUTF();
- final ProxiedPlayer forPlayer = (ProxiedPlayer) pluginMessageEvent.getReceiver();
+ ProxiedPlayer fromPlayer = (ProxiedPlayer) pluginMessageEvent.getReceiver();
if ("ON".equals(subchannel)) {
- final String playerName = dataInput.readUTF();
+ String playerName = dataInput.readUTF();
- ProxyServer.getInstance().getScheduler().runAsync(plugin, new Runnable() {
- @Override
- public void run() {
- PlayerProfile playerProfile = plugin.getStorage().getProfile(playerName, true);
- if (playerProfile.isPremium()) {
- if (forPlayer.isConnected()) {
- TextComponent textComponent = new TextComponent("You are already on the premium list");
- textComponent.setColor(ChatColor.DARK_RED);
- forPlayer.sendMessage(textComponent);
- }
-
- return;
- }
-
- playerProfile.setPremium(true);
- //todo: set uuid
- plugin.getStorage().save(playerProfile);
- TextComponent textComponent = new TextComponent("Added to the list of premium players");
- textComponent.setColor(ChatColor.DARK_GREEN);
- forPlayer.sendMessage(textComponent);
- }
- });
+ AsyncStatusMessage task = new AsyncStatusMessage(plugin, fromPlayer, playerName, true);
+ ProxyServer.getInstance().getScheduler().runAsync(plugin, task);
} else if ("OFF".equals(subchannel)) {
- final String playerName = dataInput.readUTF();
+ String playerName = dataInput.readUTF();
- ProxyServer.getInstance().getScheduler().runAsync(plugin, new Runnable() {
- @Override
- public void run() {
- PlayerProfile playerProfile = plugin.getStorage().getProfile(playerName, true);
- if (!playerProfile.isPremium()) {
- if (forPlayer.isConnected()) {
- TextComponent textComponent = new TextComponent("You are not in the premium list");
- textComponent.setColor(ChatColor.DARK_RED);
- forPlayer.sendMessage(textComponent);
- }
-
- return;
- }
-
- playerProfile.setPremium(false);
- playerProfile.setUuid(null);
- plugin.getStorage().save(playerProfile);
- TextComponent textComponent = new TextComponent("Removed to the list of premium players");
- textComponent.setColor(ChatColor.DARK_GREEN);
- forPlayer.sendMessage(textComponent);
- }
- });
+ AsyncStatusMessage task = new AsyncStatusMessage(plugin, fromPlayer, playerName, false);
+ ProxyServer.getInstance().getScheduler().runAsync(plugin, task);
} else if ("SUCCESS".equals(subchannel)) {
- if (forPlayer.getPendingConnection().isOnlineMode()) {
+ if (fromPlayer.getPendingConnection().isOnlineMode()) {
//bukkit module successfully received and force logged in the user
//update only on success to prevent corrupt data
- PlayerProfile playerProfile = plugin.getStorage().getProfile(forPlayer.getName(), false);
+ PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(fromPlayer.getName(), false);
playerProfile.setPremium(true);
//we override this in the loginevent
-// playerProfile.setUuid(forPlayer.getUniqueId());
- plugin.getStorage().save(playerProfile);
+ plugin.getCore().getStorage().save(playerProfile);
}
}
}
diff --git a/core/pom.xml b/core/pom.xml
new file mode 100644
index 00000000..0c6e7e84
--- /dev/null
+++ b/core/pom.xml
@@ -0,0 +1,32 @@
+
+ 4.0.0
+
+
+ com.github.games647
+ fastlogin
+ 1.4
+ ../pom.xml
+
+
+ fastlogin.core
+ jar
+
+ FastLoginCore
+
+
+
+
+ com.zaxxer
+ HikariCP
+ 2.4.6
+
+
+
+
+ org.slf4j
+ slf4j-jdk14
+ 1.7.21
+
+
+
diff --git a/core/src/main/java/com/github/games647/fastlogin/core/FastLoginCore.java b/core/src/main/java/com/github/games647/fastlogin/core/FastLoginCore.java
new file mode 100644
index 00000000..9b595139
--- /dev/null
+++ b/core/src/main/java/com/github/games647/fastlogin/core/FastLoginCore.java
@@ -0,0 +1,59 @@
+package com.github.games647.fastlogin.core;
+
+import java.io.File;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ThreadFactory;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public abstract class FastLoginCore {
+
+ public static UUID parseId(String withoutDashes) {
+ return UUID.fromString(withoutDashes.substring(0, 8)
+ + "-" + withoutDashes.substring(8, 12)
+ + "-" + withoutDashes.substring(12, 16)
+ + "-" + withoutDashes.substring(16, 20)
+ + "-" + withoutDashes.substring(20, 32));
+ }
+
+ private MojangApiConnector mojangApiConnector;
+ private Storage storage;
+
+ public void setMojangApiConnector(MojangApiConnector mojangApiConnector) {
+ this.mojangApiConnector = mojangApiConnector;
+ }
+
+ public MojangApiConnector getMojangApiConnector() {
+ return mojangApiConnector;
+ }
+
+ public Storage getStorage() {
+ return storage;
+ }
+
+ public abstract File getDataFolder();
+
+ public abstract Logger getLogger();
+
+ public abstract ConcurrentMap buildCache();
+
+ public abstract ThreadFactory getThreadFactory();
+
+ public boolean setupDatabase(String driver, String host, int port, String database, String user, String password) {
+ storage = new Storage(this, driver, host, port, database, user, password);
+ try {
+ storage.createTables();
+ return true;
+ } catch (Exception ex) {
+ getLogger().log(Level.SEVERE, "Failed to setup database. Disabling plugin...", ex);
+ return false;
+ }
+ }
+
+ public void close() {
+ if (storage != null) {
+ storage.close();
+ }
+ }
+}
diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/MojangApiConnector.java b/core/src/main/java/com/github/games647/fastlogin/core/MojangApiConnector.java
similarity index 74%
rename from bungee/src/main/java/com/github/games647/fastlogin/bungee/MojangApiConnector.java
rename to core/src/main/java/com/github/games647/fastlogin/core/MojangApiConnector.java
index 7d55b15b..7f84a9fc 100644
--- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/MojangApiConnector.java
+++ b/core/src/main/java/com/github/games647/fastlogin/core/MojangApiConnector.java
@@ -1,6 +1,4 @@
-package com.github.games647.fastlogin.bungee;
-
-import com.google.gson.Gson;
+package com.github.games647.fastlogin.core;
import java.io.BufferedReader;
import java.io.IOException;
@@ -11,17 +9,12 @@ import java.util.UUID;
import java.util.logging.Level;
import java.util.regex.Pattern;
-import net.md_5.bungee.BungeeCord;
-
-public class MojangApiConnector {
+public abstract class MojangApiConnector {
//http connection, read timeout and user agent for a connection to mojang api servers
private static final int TIMEOUT = 1 * 1_000;
private static final String USER_AGENT = "Premium-Checker";
- //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?";
-
//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_
@@ -30,11 +23,9 @@ public 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 FastLoginBungee plugin;
+ protected final FastLoginCore plugin;
- private final Gson gson = new Gson();
-
- public MojangApiConnector(FastLoginBungee plugin) {
+ public MojangApiConnector(FastLoginCore plugin) {
this.plugin = plugin;
}
@@ -53,8 +44,7 @@ public class MojangApiConnector {
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = reader.readLine();
if (line != null && !line.equals("null")) {
- MojangPlayer mojangPlayer = BungeeCord.getInstance().gson.fromJson(line, MojangPlayer.class);
- return FastLoginBungee.parseId(mojangPlayer.getId());
+ return getUUIDFromJson(line);
}
}
//204 - no content for not found
@@ -67,10 +57,14 @@ public class MojangApiConnector {
return null;
}
- private HttpURLConnection getConnection(String url) throws IOException {
+ public abstract boolean hasJoinedServer(Object session, String serverId);
+
+ protected abstract UUID getUUIDFromJson(String json);
+
+ protected HttpURLConnection getConnection(String url) throws IOException {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setConnectTimeout(TIMEOUT);
- connection.setReadTimeout(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);
diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/PlayerProfile.java b/core/src/main/java/com/github/games647/fastlogin/core/PlayerProfile.java
similarity index 93%
rename from bungee/src/main/java/com/github/games647/fastlogin/bungee/PlayerProfile.java
rename to core/src/main/java/com/github/games647/fastlogin/core/PlayerProfile.java
index af578218..1db2bcb6 100644
--- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/PlayerProfile.java
+++ b/core/src/main/java/com/github/games647/fastlogin/core/PlayerProfile.java
@@ -1,4 +1,4 @@
-package com.github.games647.fastlogin.bungee;
+package com.github.games647.fastlogin.core;
import java.util.UUID;
@@ -40,7 +40,7 @@ public class PlayerProfile {
return userId;
}
- protected synchronized void setUserId(long generatedId) {
+ public synchronized void setUserId(long generatedId) {
this.userId = generatedId;
}
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/Storage.java b/core/src/main/java/com/github/games647/fastlogin/core/Storage.java
similarity index 83%
rename from bukkit/src/main/java/com/github/games647/fastlogin/bukkit/Storage.java
rename to core/src/main/java/com/github/games647/fastlogin/core/Storage.java
index d76e5cbf..b14d0c48 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/Storage.java
+++ b/core/src/main/java/com/github/games647/fastlogin/core/Storage.java
@@ -1,7 +1,5 @@
-package com.github.games647.fastlogin.bukkit;
+package com.github.games647.fastlogin.core;
-import com.comphenix.protocol.utility.SafeCacheBuilder;
-import com.google.common.cache.CacheLoader;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
@@ -12,38 +10,28 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
public class Storage {
private static final String PREMIUM_TABLE = "premium";
- private final ConcurrentMap profileCache = SafeCacheBuilder
- .newBuilder()
- .concurrencyLevel(20)
- .expireAfterAccess(30, TimeUnit.MINUTES)
- .build(new CacheLoader() {
- @Override
- public PlayerProfile load(String key) throws Exception {
- //should be fetched manually
- throw new UnsupportedOperationException("Not supported yet.");
- }
- });
-
+ private final FastLoginCore core;
+ private final ConcurrentMap profileCache;
private final HikariDataSource dataSource;
- private final FastLoginBukkit plugin;
- public Storage(FastLoginBukkit plugin, String driver, String host, int port, String databasePath
+ public Storage(FastLoginCore core, String driver, String host, int port, String databasePath
, String user, String pass) {
- this.plugin = plugin;
+ this.core = core;
+ this.profileCache = core.buildCache();
HikariConfig databaseConfig = new HikariConfig();
databaseConfig.setUsername(user);
databaseConfig.setPassword(pass);
databaseConfig.setDriverClassName(driver);
+ databaseConfig.setThreadFactory(core.getThreadFactory());
- databasePath = databasePath.replace("{pluginDir}", plugin.getDataFolder().getAbsolutePath());
+ databasePath = databasePath.replace("{pluginDir}", core.getDataFolder().getAbsolutePath());
String jdbcUrl = "jdbc:";
if (driver.contains("sqlite")) {
@@ -104,7 +92,7 @@ public class Storage {
if (unparsedUUID == null) {
uuid = null;
} else {
- uuid = FastLoginBukkit.parseId(unparsedUUID);
+ uuid = FastLoginCore.parseId(unparsedUUID);
}
// String name = resultSet.getString(3);
@@ -120,7 +108,7 @@ public class Storage {
return crackedProfile;
}
} catch (SQLException sqlEx) {
- plugin.getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);
+ core.getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);
} finally {
closeQuietly(con);
}
@@ -176,7 +164,7 @@ public class Storage {
return true;
} catch (SQLException ex) {
- plugin.getLogger().log(Level.SEVERE, "Failed to save playerProfile", ex);
+ core.getLogger().log(Level.SEVERE, "Failed to save playerProfile", ex);
} finally {
closeQuietly(con);
}
@@ -194,7 +182,7 @@ public class Storage {
try {
con.close();
} catch (SQLException sqlEx) {
- plugin.getLogger().log(Level.SEVERE, "Failed to close connection", sqlEx);
+ core.getLogger().log(Level.SEVERE, "Failed to close connection", sqlEx);
}
}
}
diff --git a/bukkit/src/main/resources/config.yml b/core/src/main/resources/config.yml
similarity index 97%
rename from bukkit/src/main/resources/config.yml
rename to core/src/main/resources/config.yml
index 279df83b..38996455 100644
--- a/bukkit/src/main/resources/config.yml
+++ b/core/src/main/resources/config.yml
@@ -3,7 +3,7 @@
# Source code: https://github.com/games647/FastLogin
#
# You can access the newest config here:
-# https://github.com/games647/FastLogin/blob/master/bukkit/src/main/resources/config.yml
+# https://github.com/games647/FastLogin/blob/master/core/src/main/resources/config.yml
# Request a premium login without forcing the player to type a command
#
diff --git a/core/src/main/resources/messages.yml b/core/src/main/resources/messages.yml
new file mode 100644
index 00000000..34662b1f
--- /dev/null
+++ b/core/src/main/resources/messages.yml
@@ -0,0 +1,18 @@
+# FastLogin localization
+# Project site: https://www.spigotmc.org/resources/fastlogin.14153
+# Source code: https://github.com/games647/FastLogin
+#
+# You can access the newest locale here:
+# https://github.com/games647/FastLogin/blob/master/core/src/main/resources/messages.yml
+
+# ========= Shared (BungeeCord an Bukkit) ============
+
+
+
+# ========= Bukkit only ================================
+
+
+
+# ========= Bungee only ================================
+
+
diff --git a/pom.xml b/pom.xml
index ae394f0f..0f9302de 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
pom
FastLogin
- 1.3.1
+ 1.4
2015
https://www.spigotmc.org/resources/fastlogin.14153/
@@ -22,6 +22,7 @@
+ core
bukkit
bungee
universal
@@ -83,20 +84,4 @@
-
-
-
-
- com.zaxxer
- HikariCP
- 2.4.6
-
-
-
-
- org.slf4j
- slf4j-jdk14
- 1.7.21
-
-
diff --git a/universal/pom.xml b/universal/pom.xml
index 1d962491..79c0552e 100644
--- a/universal/pom.xml
+++ b/universal/pom.xml
@@ -5,7 +5,7 @@
com.github.games647
fastlogin
- 1.3.1
+ 1.4
../pom.xml
@@ -47,6 +47,12 @@
+
+ ${project.groupId}
+ fastlogin.core
+ ${project.version}
+
+
${project.groupId}
fastlogin.bukkit