mirror of
https://github.com/TuxCoding/FastLogin.git
synced 2025-07-29 18:27:36 +02:00
Add support for multiple bungeecords (Fixes #19)
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -46,4 +46,4 @@ gradle-app.setting
|
||||
bukkit/target
|
||||
universal/target
|
||||
bungee/target
|
||||
core/target
|
||||
core/target
|
||||
|
@ -1,3 +1,8 @@
|
||||
######1.4
|
||||
|
||||
* Added Bungee setAuthPlugin method
|
||||
* Multiple BungeeCord support
|
||||
|
||||
######1.3.1
|
||||
|
||||
* Prevent thread create violation in BungeeCord
|
||||
@ -127,4 +132,4 @@
|
||||
* Added better error handling
|
||||
|
||||
#####0.1
|
||||
* First release
|
||||
* First release
|
||||
|
@ -1,15 +1,10 @@
|
||||
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 {
|
||||
@ -30,21 +25,6 @@ public class BukkitCore extends FastLoginCore {
|
||||
return plugin.getLogger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConcurrentMap<String, PlayerProfile> buildCache() {
|
||||
return SafeCacheBuilder
|
||||
.<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.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThreadFactory getThreadFactory() {
|
||||
String pluginName = plugin.getName();
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.github.games647.fastlogin.bukkit;
|
||||
|
||||
import com.comphenix.protocol.wrappers.WrappedSignedProperty;
|
||||
import com.github.games647.fastlogin.core.LoginSession;
|
||||
import com.github.games647.fastlogin.core.PlayerProfile;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@ -11,33 +13,32 @@ import org.apache.commons.lang.ArrayUtils;
|
||||
*
|
||||
* This session is invalid if the player disconnects or the login was successful
|
||||
*/
|
||||
public class PlayerSession {
|
||||
public class BukkitLoginSession extends LoginSession {
|
||||
|
||||
private final String username;
|
||||
private final String serverId;
|
||||
private final byte[] verifyToken;
|
||||
|
||||
private UUID uuid;
|
||||
private WrappedSignedProperty skinProperty;
|
||||
private boolean verified;
|
||||
private boolean registered;
|
||||
|
||||
public PlayerSession(String username, String serverId, byte[] verifyToken) {
|
||||
this.username = username;
|
||||
public BukkitLoginSession(String username, String serverId, byte[] verifyToken, boolean registered
|
||||
, PlayerProfile profile) {
|
||||
super(username, registered, profile);
|
||||
|
||||
this.serverId = serverId;
|
||||
this.verifyToken = ArrayUtils.clone(verifyToken);
|
||||
}
|
||||
|
||||
public PlayerSession(String username) {
|
||||
this(username, "", ArrayUtils.EMPTY_BYTE_ARRAY);
|
||||
//available for bungeecord
|
||||
public BukkitLoginSession(String username, boolean registered) {
|
||||
this(username, "", ArrayUtils.EMPTY_BYTE_ARRAY, registered, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the random generated server id. This makes sure the request
|
||||
* sent from the client is just for this server.
|
||||
* Gets the random generated server id. This makes sure the request sent from the client is just for this server.
|
||||
*
|
||||
* See this for details
|
||||
* http://www.sk89q.com/2011/09/minecraft-name-spoofing-exploit/
|
||||
* See this for details http://www.sk89q.com/2011/09/minecraft-name-spoofing-exploit/
|
||||
*
|
||||
* Empty if it's a BungeeCord connection
|
||||
*
|
||||
@ -58,15 +59,6 @@ public class PlayerSession {
|
||||
return ArrayUtils.clone(verifyToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the username the player sent to the server
|
||||
*
|
||||
* @return the client sent username
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the premium skin of this player
|
||||
*
|
||||
@ -86,26 +78,7 @@ public class PlayerSession {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the account of this player already exists
|
||||
*
|
||||
* @param registered whether the account exists
|
||||
*/
|
||||
public synchronized void setRegistered(boolean registered) {
|
||||
this.registered = registered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the account of this player already exists.
|
||||
*
|
||||
* @return whether the account exists
|
||||
*/
|
||||
public synchronized boolean needsRegistration() {
|
||||
return !registered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the player has a premium (paid account) account
|
||||
* and valid session
|
||||
* Sets whether the player has a premium (paid account) account and valid session
|
||||
*
|
||||
* @param verified whether the player has valid session
|
||||
*/
|
||||
@ -122,7 +95,6 @@ public class PlayerSession {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the online UUID if it's fetched
|
||||
*
|
||||
@ -133,8 +105,7 @@ public class PlayerSession {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the player has a premium (paid account) account
|
||||
* and valid session
|
||||
* Get whether the player has a premium (paid account) account and valid session
|
||||
*
|
||||
* @return whether the player has a valid session
|
||||
*/
|
@ -40,14 +40,14 @@ public class FastLoginBukkit extends JavaPlugin {
|
||||
|
||||
//this map is thread-safe for async access (Packet Listener)
|
||||
//SafeCacheBuilder is used in order to be version independent
|
||||
private final ConcurrentMap<String, PlayerSession> session = SafeCacheBuilder.<String, PlayerSession>newBuilder()
|
||||
private final ConcurrentMap<String, BukkitLoginSession> session = SafeCacheBuilder.<String, BukkitLoginSession>newBuilder()
|
||||
//2 minutes should be enough as a timeout for bad internet connection (Server, Client and Mojang)
|
||||
.expireAfterWrite(1, TimeUnit.MINUTES)
|
||||
//mapped by ip:port -> PlayerSession
|
||||
.build(new CacheLoader<String, PlayerSession>() {
|
||||
.build(new CacheLoader<String, BukkitLoginSession>() {
|
||||
|
||||
@Override
|
||||
public PlayerSession load(String key) throws Exception {
|
||||
public BukkitLoginSession load(String key) throws Exception {
|
||||
//A key should be inserted manually on start packet
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
@ -158,7 +158,7 @@ public class FastLoginBukkit extends JavaPlugin {
|
||||
*
|
||||
* @return a thread-safe session map
|
||||
*/
|
||||
public ConcurrentMap<String, PlayerSession> getSessions() {
|
||||
public ConcurrentMap<String, BukkitLoginSession> getSessions() {
|
||||
return session;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ import org.bukkit.entity.Player;
|
||||
|
||||
public class ForceLoginTask implements Runnable {
|
||||
|
||||
protected final FastLoginBukkit plugin;
|
||||
private final FastLoginBukkit plugin;
|
||||
protected final Player player;
|
||||
|
||||
public ForceLoginTask(FastLoginBukkit plugin, Player player) {
|
||||
@ -33,14 +33,12 @@ public class ForceLoginTask implements Runnable {
|
||||
|
||||
//remove the bungeecord identifier if there is ones
|
||||
String id = '/' + player.getAddress().getAddress().getHostAddress() + ':' + player.getAddress().getPort();
|
||||
PlayerSession session = plugin.getSessions().get(id);
|
||||
|
||||
BukkitAuthPlugin authPlugin = plugin.getAuthPlugin();
|
||||
BukkitLoginSession session = plugin.getSessions().remove(id);
|
||||
|
||||
Storage storage = plugin.getCore().getStorage();
|
||||
PlayerProfile playerProfile = null;
|
||||
if (storage != null) {
|
||||
playerProfile = storage.getProfile(player.getName(), false);
|
||||
if (session != null) {
|
||||
playerProfile = session.getProfile();
|
||||
}
|
||||
|
||||
if (session == null) {
|
||||
@ -53,6 +51,7 @@ public class ForceLoginTask implements Runnable {
|
||||
//check if it's the same player as we checked before
|
||||
} else if (player.getName().equals(session.getUsername())) {
|
||||
//premium player
|
||||
BukkitAuthPlugin authPlugin = plugin.getAuthPlugin();
|
||||
if (authPlugin == null) {
|
||||
//maybe only bungeecord plugin
|
||||
sendSuccessNotification();
|
||||
|
@ -25,11 +25,11 @@ public class MojangApiBukkit extends MojangApiConnector {
|
||||
|
||||
@Override
|
||||
public boolean hasJoinedServer(Object session, String serverId) {
|
||||
if (!(session instanceof PlayerSession)) {
|
||||
if (!(session instanceof BukkitLoginSession)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PlayerSession playerSession = (PlayerSession) session;
|
||||
BukkitLoginSession playerSession = (BukkitLoginSession) session;
|
||||
try {
|
||||
String url = HAS_JOINED_URL + "username=" + playerSession.getUsername() + "&serverId=" + serverId;
|
||||
HttpURLConnection conn = getConnection(url);
|
||||
|
@ -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.getCore().getStorage().getProfile(sender.getName(), true);
|
||||
final PlayerProfile profile = plugin.getCore().getStorage().loadProfile(sender.getName());
|
||||
if (profile.isPremium()) {
|
||||
sender.sendMessage(ChatColor.DARK_GREEN + "Removed from the list of premium players");
|
||||
profile.setPremium(false);
|
||||
@ -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.getCore().getStorage().getProfile(args[0], true);
|
||||
final PlayerProfile profile = plugin.getCore().getStorage().loadProfile(args[0]);
|
||||
if (profile == null) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Player not in the database");
|
||||
return true;
|
||||
|
@ -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.getCore().getStorage().getProfile(sender.getName(), true);
|
||||
final PlayerProfile profile = plugin.getCore().getStorage().loadProfile(sender.getName());
|
||||
if (profile.isPremium()) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "You are already on the premium list");
|
||||
} else {
|
||||
@ -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.getCore().getStorage().getProfile(args[0], true);
|
||||
final PlayerProfile profile = plugin.getCore().getStorage().loadProfile(args[0]);
|
||||
if (profile == null) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + "Player not in the database");
|
||||
return true;
|
||||
|
@ -4,7 +4,7 @@ import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
import com.comphenix.protocol.wrappers.WrappedSignedProperty;
|
||||
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
|
||||
import com.github.games647.fastlogin.bukkit.ForceLoginTask;
|
||||
import com.github.games647.fastlogin.bukkit.PlayerSession;
|
||||
import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -14,7 +14,6 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent.Result;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
/**
|
||||
* This listener tells authentication plugins if the player has a premium account and we checked it successfully. So the
|
||||
@ -41,7 +40,7 @@ public class BukkitJoinListener implements Listener {
|
||||
public void onPlayerJoin(PlayerJoinEvent joinEvent) {
|
||||
Player player = joinEvent.getPlayer();
|
||||
|
||||
PlayerSession session = plugin.getSessions().get(player.getAddress().toString());
|
||||
BukkitLoginSession session = plugin.getSessions().get(player.getAddress().toString());
|
||||
if (session != null && plugin.getConfig().getBoolean("forwardSkin")) {
|
||||
WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player);
|
||||
WrappedSignedProperty skin = session.getSkin();
|
||||
@ -55,12 +54,4 @@ public class BukkitJoinListener implements Listener {
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, new ForceLoginTask(plugin, player), DELAY_LOGIN);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent quitEvent) {
|
||||
Player player = quitEvent.getPlayer();
|
||||
|
||||
//prevent memory leaks
|
||||
player.removeMetadata(plugin.getName(), plugin);
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,18 @@ package com.github.games647.fastlogin.bukkit.listener;
|
||||
|
||||
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
|
||||
import com.github.games647.fastlogin.bukkit.ForceLoginTask;
|
||||
import com.github.games647.fastlogin.bukkit.PlayerSession;
|
||||
import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
|
||||
import com.github.games647.fastlogin.bukkit.hooks.BukkitAuthPlugin;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.io.Files;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@ -31,11 +34,11 @@ public class BungeeCordListener implements PluginMessageListener {
|
||||
|
||||
protected final FastLoginBukkit plugin;
|
||||
//null if whitelist is empty so bungeecord support is disabled
|
||||
private final UUID proxyId;
|
||||
private final Set<UUID> proxyIds;
|
||||
|
||||
public BungeeCordListener(FastLoginBukkit plugin) {
|
||||
this.plugin = plugin;
|
||||
this.proxyId = loadBungeeCordId();
|
||||
this.proxyIds = loadBungeeCordIds();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -65,17 +68,14 @@ public class BungeeCordListener implements PluginMessageListener {
|
||||
plugin.getLogger().log(Level.FINEST, "Received proxy id {0} from {1}", new Object[]{sourceId, player});
|
||||
|
||||
//fail if BungeeCord support is disabled (id = null)
|
||||
if (sourceId.equals(proxyId)) {
|
||||
final PlayerSession playerSession = new PlayerSession(playerName);
|
||||
if (proxyIds.contains(sourceId)) {
|
||||
final String id = '/' + checkedPlayer.getAddress().getAddress().getHostAddress() + ':'
|
||||
+ checkedPlayer.getAddress().getPort();
|
||||
if ("AUTO_LOGIN".equalsIgnoreCase(subchannel)) {
|
||||
BukkitLoginSession playerSession = new BukkitLoginSession(playerName, true);
|
||||
playerSession.setVerified(true);
|
||||
playerSession.setRegistered(true);
|
||||
plugin.getSessions().put(id, playerSession);
|
||||
} else if ("AUTO_REGISTER".equalsIgnoreCase(subchannel)) {
|
||||
playerSession.setVerified(true);
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -83,6 +83,8 @@ public class BungeeCordListener implements PluginMessageListener {
|
||||
try {
|
||||
//we need to check if the player is registered on Bukkit too
|
||||
if (authPlugin != null && !authPlugin.isRegistered(playerName)) {
|
||||
BukkitLoginSession playerSession = new BukkitLoginSession(playerName, false);
|
||||
playerSession.setVerified(true);
|
||||
plugin.getSessions().put(id, playerSession);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
@ -97,7 +99,7 @@ public class BungeeCordListener implements PluginMessageListener {
|
||||
}
|
||||
}
|
||||
|
||||
public UUID loadBungeeCordId() {
|
||||
public Set<UUID> loadBungeeCordIds() {
|
||||
File whitelistFile = new File(plugin.getDataFolder(), FILE_NAME);
|
||||
//create a new folder if it doesn't exist. Fail silently otherwise
|
||||
whitelistFile.getParentFile().mkdir();
|
||||
@ -106,9 +108,16 @@ public class BungeeCordListener implements PluginMessageListener {
|
||||
whitelistFile.createNewFile();
|
||||
}
|
||||
|
||||
String firstLine = Files.readFirstLine(whitelistFile, Charsets.UTF_8);
|
||||
if (firstLine != null && !firstLine.isEmpty()) {
|
||||
return UUID.fromString(firstLine.trim());
|
||||
Set<UUID> ids = Sets.newHashSet();
|
||||
|
||||
List<String> lines = Files.readLines(whitelistFile, Charsets.UTF_8);
|
||||
for (String line : lines) {
|
||||
if (line == null || line.trim().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
UUID uuid = UUID.fromString(line.trim());
|
||||
ids.add(uuid);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Failed to create file for Proxy whitelist", ex);
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.github.games647.fastlogin.bukkit.listener;
|
||||
|
||||
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
|
||||
import com.github.games647.fastlogin.bukkit.PlayerSession;
|
||||
import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
|
||||
import com.github.games647.fastlogin.bukkit.hooks.BukkitAuthPlugin;
|
||||
import com.github.games647.fastlogin.core.PlayerProfile;
|
||||
|
||||
@ -33,18 +33,18 @@ public class ProtocolSupportListener implements Listener {
|
||||
String username = loginStartEvent.getName();
|
||||
|
||||
//remove old data every time on a new login in order to keep the session only for one person
|
||||
plugin.getSessions().remove(username);
|
||||
plugin.getSessions().remove(loginStartEvent.getAddress().toString());
|
||||
|
||||
BukkitAuthPlugin authPlugin = plugin.getAuthPlugin();
|
||||
if (authPlugin == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(username, true);
|
||||
PlayerProfile playerProfile = plugin.getCore().getStorage().loadProfile(username);
|
||||
if (playerProfile != null) {
|
||||
if (playerProfile.isPremium()) {
|
||||
if (playerProfile.getUserId() != -1) {
|
||||
startPremiumSession(username, loginStartEvent, true);
|
||||
startPremiumSession(username, loginStartEvent, true, playerProfile);
|
||||
}
|
||||
} else if (playerProfile.getUserId() == -1) {
|
||||
//user not exists in the db
|
||||
@ -53,7 +53,7 @@ public class ProtocolSupportListener implements Listener {
|
||||
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);
|
||||
startPremiumSession(username, loginStartEvent, false, playerProfile);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
@ -68,19 +68,19 @@ public class ProtocolSupportListener implements Listener {
|
||||
//skin was resolved -> premium player
|
||||
if (propertiesResolveEvent.hasProperty("textures")) {
|
||||
InetSocketAddress address = propertiesResolveEvent.getAddress();
|
||||
PlayerSession session = plugin.getSessions().get(address.toString());
|
||||
BukkitLoginSession session = plugin.getSessions().get(address.toString());
|
||||
if (session != null) {
|
||||
session.setVerified(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startPremiumSession(String playerName, PlayerLoginStartEvent loginStartEvent, boolean registered) {
|
||||
private void startPremiumSession(String playerName, PlayerLoginStartEvent loginStartEvent, boolean registered
|
||||
, PlayerProfile playerProfile) {
|
||||
loginStartEvent.setOnlineMode(true);
|
||||
InetSocketAddress address = loginStartEvent.getAddress();
|
||||
|
||||
PlayerSession playerSession = new PlayerSession(playerName, null, null);
|
||||
playerSession.setRegistered(registered);
|
||||
BukkitLoginSession playerSession = new BukkitLoginSession(playerName, null, null, registered, playerProfile);
|
||||
plugin.getSessions().put(address.toString(), playerSession);
|
||||
if (plugin.getConfig().getBoolean("premiumUuid")) {
|
||||
loginStartEvent.setUseOnlineModeUUID(true);
|
||||
|
@ -11,7 +11,7 @@ import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
import com.github.games647.fastlogin.bukkit.EncryptionUtil;
|
||||
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
|
||||
import com.github.games647.fastlogin.bukkit.PlayerSession;
|
||||
import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -73,13 +73,10 @@ public class EncryptionPacketListener extends PacketAdapter {
|
||||
public void onPacketReceiving(PacketEvent packetEvent) {
|
||||
Player player = packetEvent.getPlayer();
|
||||
|
||||
//the player name is unknown to ProtocolLib (so getName() doesn't work) - now uses ip:port as key
|
||||
String uniqueSessionKey = player.getAddress().toString();
|
||||
PlayerSession session = plugin.getSessions().get(uniqueSessionKey);
|
||||
BukkitLoginSession session = plugin.getSessions().get(player.getAddress().toString());
|
||||
if (session == null) {
|
||||
disconnect(packetEvent, "Invalid request", Level.FINE
|
||||
, "Player {0} tried to send encryption response at invalid state"
|
||||
, player.getAddress());
|
||||
, "Player {0} tried to send encryption response at invalid state", player.getAddress());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -118,7 +115,7 @@ public class EncryptionPacketListener extends PacketAdapter {
|
||||
packetEvent.setCancelled(true);
|
||||
}
|
||||
|
||||
private void setPremiumUUID(PlayerSession session, Player player) {
|
||||
private void setPremiumUUID(BukkitLoginSession session, Player player) {
|
||||
UUID uuid = session.getUuid();
|
||||
if (plugin.getConfig().getBoolean("premiumUuid") && uuid != null) {
|
||||
try {
|
||||
@ -132,7 +129,7 @@ public class EncryptionPacketListener extends PacketAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkVerifyToken(PlayerSession session, PrivateKey privateKey, PacketEvent packetEvent) {
|
||||
private boolean checkVerifyToken(BukkitLoginSession session, PrivateKey privateKey, PacketEvent packetEvent) {
|
||||
byte[] requestVerify = session.getVerifyToken();
|
||||
//encrypted verify token
|
||||
byte[] responseVerify = packetEvent.getPacket().getByteArrays().read(1);
|
||||
|
@ -6,9 +6,9 @@ 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.core.PlayerProfile;
|
||||
import com.github.games647.fastlogin.bukkit.PlayerSession;
|
||||
import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
|
||||
import com.github.games647.fastlogin.bukkit.hooks.BukkitAuthPlugin;
|
||||
import com.github.games647.fastlogin.core.PlayerProfile;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.PublicKey;
|
||||
@ -83,20 +83,20 @@ public class StartPacketListener extends PacketAdapter {
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(username, true);
|
||||
if (playerProfile != null) {
|
||||
if (playerProfile.isPremium()) {
|
||||
if (playerProfile.getUserId() != -1) {
|
||||
enablePremiumLogin(username, sessionKey, player, packetEvent, true);
|
||||
PlayerProfile profile = plugin.getCore().getStorage().loadProfile(username);
|
||||
if (profile != null) {
|
||||
if (profile.isPremium()) {
|
||||
if (profile.getUserId() != -1) {
|
||||
enablePremiumLogin(username, profile, sessionKey, player, packetEvent, true);
|
||||
}
|
||||
} else if (playerProfile.getUserId() == -1) {
|
||||
} else if (profile.getUserId() == -1) {
|
||||
//user not exists in the db
|
||||
try {
|
||||
if (plugin.getConfig().getBoolean("autoRegister") && !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);
|
||||
enablePremiumLogin(username, sessionKey, player, packetEvent, false);
|
||||
enablePremiumLogin(username, profile, sessionKey, player, packetEvent, false);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
@ -108,8 +108,8 @@ public class StartPacketListener extends PacketAdapter {
|
||||
|
||||
//minecraft server implementation
|
||||
//https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/LoginListener.java#L161
|
||||
private void enablePremiumLogin(String username, String sessionKey, Player player, PacketEvent packetEvent
|
||||
, boolean registered) {
|
||||
private void enablePremiumLogin(String username, PlayerProfile profile, String sessionKey, Player player
|
||||
, PacketEvent packetEvent, boolean registered) {
|
||||
//randomized server id to make sure the request is for our server
|
||||
//this could be relevant http://www.sk89q.com/2011/09/minecraft-name-spoofing-exploit/
|
||||
String serverId = Long.toString(random.nextLong(), 16);
|
||||
@ -120,8 +120,8 @@ public class StartPacketListener extends PacketAdapter {
|
||||
|
||||
boolean success = sentEncryptionRequest(player, serverId, verifyToken);
|
||||
if (success) {
|
||||
PlayerSession playerSession = new PlayerSession(username, serverId, verifyToken);
|
||||
playerSession.setRegistered(registered);
|
||||
BukkitLoginSession playerSession = new BukkitLoginSession(username, serverId
|
||||
, verifyToken, registered, profile);
|
||||
plugin.getSessions().put(sessionKey, playerSession);
|
||||
//cancel only if the player has a paid account otherwise login as normal offline player
|
||||
packetEvent.setCancelled(true);
|
||||
|
@ -2,9 +2,12 @@ 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.LoginSession;
|
||||
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;
|
||||
|
||||
@ -21,15 +24,18 @@ public class AsyncPremiumCheck implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
PendingConnection connection = preLoginEvent.getConnection();
|
||||
plugin.getSession().remove(connection);
|
||||
|
||||
String username = connection.getName();
|
||||
try {
|
||||
PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(username, true);
|
||||
if (playerProfile != null) {
|
||||
if (playerProfile.isPremium()) {
|
||||
if (playerProfile.getUserId() != -1) {
|
||||
PlayerProfile profile = plugin.getCore().getStorage().loadProfile(username);
|
||||
if (profile != null) {
|
||||
if (profile.isPremium()) {
|
||||
if (profile.getUserId() != -1) {
|
||||
plugin.getSession().put(connection, new LoginSession(username, true, profile));
|
||||
connection.setOnlineMode(true);
|
||||
}
|
||||
} else if (playerProfile.getUserId() == -1) {
|
||||
} else if (profile.getUserId() == -1) {
|
||||
//user not exists in the db
|
||||
BungeeAuthPlugin authPlugin = plugin.getBungeeAuthPlugin();
|
||||
if (plugin.getConfiguration().getBoolean("autoRegister")
|
||||
@ -38,7 +44,7 @@ public class AsyncPremiumCheck implements Runnable {
|
||||
if (premiumUUID != null) {
|
||||
plugin.getLogger().log(Level.FINER, "Player {0} uses a premium username", username);
|
||||
connection.setOnlineMode(true);
|
||||
plugin.getPendingAutoRegister().put(connection, new Object());
|
||||
plugin.getSession().put(connection, new LoginSession(username, false, profile));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,10 @@
|
||||
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;
|
||||
@ -31,15 +27,6 @@ public class BungeeCore extends FastLoginCore {
|
||||
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();
|
||||
|
@ -5,6 +5,7 @@ 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.github.games647.fastlogin.core.LoginSession;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
import java.io.File;
|
||||
@ -41,6 +42,11 @@ public class FastLoginBungee extends Plugin {
|
||||
.expireAfterWrite(1, TimeUnit.MINUTES)
|
||||
.<PendingConnection, Object>build().asMap();
|
||||
|
||||
private final ConcurrentMap<PendingConnection, LoginSession> session = CacheBuilder
|
||||
.newBuilder()
|
||||
.expireAfterWrite(1, TimeUnit.MINUTES)
|
||||
.<PendingConnection, LoginSession>build().asMap();
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
loginCore.setMojangApiConnector(new MojangApiBungee(loginCore));
|
||||
@ -112,8 +118,8 @@ public class FastLoginBungee extends Plugin {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public ConcurrentMap<PendingConnection, Object> getPendingAutoRegister() {
|
||||
return pendingAutoRegister;
|
||||
public ConcurrentMap<PendingConnection, LoginSession> getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,11 +1,13 @@
|
||||
package com.github.games647.fastlogin.bungee;
|
||||
|
||||
import com.github.games647.fastlogin.core.PlayerProfile;
|
||||
import com.github.games647.fastlogin.bungee.hooks.BungeeAuthPlugin;
|
||||
import com.github.games647.fastlogin.core.LoginSession;
|
||||
import com.github.games647.fastlogin.core.PlayerProfile;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import java.util.UUID;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.connection.Server;
|
||||
@ -24,17 +26,19 @@ public class ForceLoginTask implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(player.getName(), false);
|
||||
PendingConnection pendingConnection = player.getPendingConnection();
|
||||
LoginSession session = plugin.getSession().remove(pendingConnection);
|
||||
PlayerProfile playerProfile = session.getProfile();
|
||||
|
||||
//force login only on success
|
||||
if (player.getPendingConnection().isOnlineMode()) {
|
||||
boolean autoRegister = plugin.getPendingAutoRegister().remove(player.getPendingConnection()) != null;
|
||||
if (pendingConnection.isOnlineMode()) {
|
||||
boolean autoRegister = session.needsRegistration();
|
||||
|
||||
BungeeAuthPlugin authPlugin = plugin.getBungeeAuthPlugin();
|
||||
if (authPlugin == null) {
|
||||
sendBukkitLoginNotification(autoRegister);
|
||||
} else if (player.isConnected()) {
|
||||
if (autoRegister) {
|
||||
if (session.needsRegistration()) {
|
||||
String password = plugin.generateStringPassword();
|
||||
if (authPlugin.forceRegister(player, password)) {
|
||||
sendBukkitLoginNotification(autoRegister);
|
||||
|
@ -14,7 +14,8 @@ public class AsyncStatusMessage implements Runnable {
|
||||
private final String targetPlayer;
|
||||
private final boolean toPremium;
|
||||
|
||||
public AsyncStatusMessage(FastLoginBungee plugin, ProxiedPlayer fromPlayer, String targetPlayer, boolean toPremium) {
|
||||
public AsyncStatusMessage(FastLoginBungee plugin, ProxiedPlayer fromPlayer, String targetPlayer
|
||||
, boolean toPremium) {
|
||||
this.plugin = plugin;
|
||||
this.fromPlayer = fromPlayer;
|
||||
this.targetPlayer = targetPlayer;
|
||||
@ -31,7 +32,7 @@ public class AsyncStatusMessage implements Runnable {
|
||||
}
|
||||
|
||||
private void turnOffPremium() {
|
||||
PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(targetPlayer, true);
|
||||
PlayerProfile playerProfile = plugin.getCore().getStorage().loadProfile(targetPlayer);
|
||||
if (!playerProfile.isPremium()) {
|
||||
if (fromPlayer.isConnected()) {
|
||||
TextComponent textComponent = new TextComponent("You are not in the premium list");
|
||||
@ -51,7 +52,7 @@ public class AsyncStatusMessage implements Runnable {
|
||||
}
|
||||
|
||||
private void activatePremium() {
|
||||
PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(targetPlayer, true);
|
||||
PlayerProfile playerProfile = plugin.getCore().getStorage().loadProfile(targetPlayer);
|
||||
if (playerProfile.isPremium()) {
|
||||
if (fromPlayer.isConnected()) {
|
||||
TextComponent textComponent = new TextComponent("You are already on the premium list");
|
||||
@ -63,7 +64,6 @@ public class AsyncStatusMessage implements Runnable {
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -3,6 +3,7 @@ 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.core.LoginSession;
|
||||
import com.github.games647.fastlogin.core.PlayerProfile;
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
@ -51,7 +52,8 @@ public class PlayerConnectionListener implements Listener {
|
||||
PendingConnection connection = player.getPendingConnection();
|
||||
String username = connection.getName();
|
||||
if (connection.isOnlineMode()) {
|
||||
PlayerProfile playerProfile = plugin.getCore().getStorage().getProfile(player.getName(), false);
|
||||
LoginSession session = plugin.getSession().get(connection);
|
||||
PlayerProfile playerProfile = session.getProfile();
|
||||
playerProfile.setUuid(player.getUniqueId());
|
||||
|
||||
//bungeecord will do this automatically so override it on disabled option
|
||||
|
@ -57,7 +57,7 @@ public class PluginMessageListener implements Listener {
|
||||
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.getCore().getStorage().getProfile(fromPlayer.getName(), false);
|
||||
PlayerProfile playerProfile = plugin.getCore().getStorage().loadProfile(fromPlayer.getName());
|
||||
playerProfile.setPremium(true);
|
||||
//we override this in the loginevent
|
||||
plugin.getCore().getStorage().save(playerProfile);
|
||||
|
@ -2,7 +2,6 @@ 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;
|
||||
@ -36,8 +35,6 @@ public abstract class FastLoginCore {
|
||||
|
||||
public abstract Logger getLogger();
|
||||
|
||||
public abstract ConcurrentMap<String, PlayerProfile> buildCache();
|
||||
|
||||
public abstract ThreadFactory getThreadFactory();
|
||||
|
||||
public boolean setupDatabase(String driver, String host, int port, String database, String user, String password) {
|
||||
|
@ -0,0 +1,26 @@
|
||||
package com.github.games647.fastlogin.core;
|
||||
|
||||
public class LoginSession {
|
||||
|
||||
private final String username;
|
||||
private final boolean registered;
|
||||
private final PlayerProfile profile;
|
||||
|
||||
public LoginSession(String username, boolean registered, PlayerProfile profile) {
|
||||
this.username = username;
|
||||
this.registered = registered;
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public boolean needsRegistration() {
|
||||
return !registered;
|
||||
}
|
||||
|
||||
public PlayerProfile getProfile() {
|
||||
return profile;
|
||||
}
|
||||
}
|
@ -9,7 +9,6 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class Storage {
|
||||
@ -17,13 +16,11 @@ public class Storage {
|
||||
private static final String PREMIUM_TABLE = "premium";
|
||||
|
||||
private final FastLoginCore core;
|
||||
private final ConcurrentMap<String, PlayerProfile> profileCache;
|
||||
private final HikariDataSource dataSource;
|
||||
|
||||
public Storage(FastLoginCore core, String driver, String host, int port, String databasePath
|
||||
, String user, String pass) {
|
||||
this.core = core;
|
||||
this.profileCache = core.buildCache();
|
||||
|
||||
HikariConfig databaseConfig = new HikariConfig();
|
||||
databaseConfig.setUsername(user);
|
||||
@ -33,6 +30,8 @@ public class Storage {
|
||||
|
||||
databasePath = databasePath.replace("{pluginDir}", core.getDataFolder().getAbsolutePath());
|
||||
|
||||
databaseConfig.setThreadFactory(core.getThreadFactory());
|
||||
|
||||
String jdbcUrl = "jdbc:";
|
||||
if (driver.contains("sqlite")) {
|
||||
jdbcUrl += "sqlite" + "://" + databasePath;
|
||||
@ -51,15 +50,15 @@ public class Storage {
|
||||
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`), "
|
||||
+ "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`) "
|
||||
+ "UNIQUE (Name) "
|
||||
+ ")";
|
||||
|
||||
if (dataSource.getJdbcUrl().contains("sqlite")) {
|
||||
@ -72,46 +71,39 @@ public class Storage {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
public PlayerProfile loadProfile(String name) {
|
||||
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);
|
||||
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 = FastLoginCore.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;
|
||||
String unparsedUUID = resultSet.getString(2);
|
||||
UUID uuid;
|
||||
if (unparsedUUID == null) {
|
||||
uuid = null;
|
||||
} else {
|
||||
PlayerProfile crackedProfile = new PlayerProfile(null, name, false, "");
|
||||
profileCache.put(name, crackedProfile);
|
||||
return crackedProfile;
|
||||
uuid = FastLoginCore.parseId(unparsedUUID);
|
||||
}
|
||||
} catch (SQLException sqlEx) {
|
||||
core.getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);
|
||||
} finally {
|
||||
closeQuietly(con);
|
||||
|
||||
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);
|
||||
return playerProfile;
|
||||
} else {
|
||||
PlayerProfile crackedProfile = new PlayerProfile(null, name, false, "");
|
||||
return crackedProfile;
|
||||
}
|
||||
} catch (SQLException sqlEx) {
|
||||
core.getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);
|
||||
} finally {
|
||||
closeQuietly(con);
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -156,7 +148,6 @@ public class Storage {
|
||||
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();
|
||||
@ -174,7 +165,6 @@ public class Storage {
|
||||
|
||||
public void close() {
|
||||
dataSource.close();
|
||||
profileCache.clear();
|
||||
}
|
||||
|
||||
private void closeQuietly(Connection con) {
|
||||
|
Reference in New Issue
Block a user