forked from TuxCoding/FastLogin
Clean up project structure
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<String, PlayerProfile> buildCache() {
|
||||
return CacheBuilder
|
||||
.newBuilder()
|
||||
.concurrencyLevel(20)
|
||||
.expireAfterAccess(30, TimeUnit.MINUTES)
|
||||
.<String, PlayerProfile>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();
|
||||
}
|
||||
}
|
||||
@@ -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<PendingConnection, Object> getPendingAutoRegister() {
|
||||
return pendingAutoRegister;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
package com.github.games647.fastlogin.bungee;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
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 net.md_5.bungee.BungeeCord;
|
||||
|
||||
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 FastLoginBungee plugin;
|
||||
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
public MojangApiConnector(FastLoginBungee 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")) {
|
||||
MojangPlayer mojangPlayer = BungeeCord.getInstance().gson.fromJson(line, MojangPlayer.class);
|
||||
return FastLoginBungee.parseId(mojangPlayer.getId());
|
||||
}
|
||||
}
|
||||
//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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package com.github.games647.fastlogin.bungee;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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<String, PlayerProfile> profileCache = CacheBuilder
|
||||
.<String, PlayerProfile>newBuilder()
|
||||
.concurrencyLevel(20)
|
||||
.expireAfterAccess(30, TimeUnit.MINUTES)
|
||||
.build(new CacheLoader<String, PlayerProfile>() {
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+72
@@ -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);
|
||||
}
|
||||
}
|
||||
+7
-40
@@ -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);
|
||||
}
|
||||
|
||||
+11
-54
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user