Added support of detecting name changes (Fixes #18)

This commit is contained in:
games647
2016-06-01 14:42:48 +02:00
parent cb876a52bd
commit 51d0aefbf3
15 changed files with 186 additions and 49 deletions
@@ -46,9 +46,10 @@ public class Storage {
public void createTables() throws SQLException {
Connection con = null;
Statement createStmt = null;
try {
con = dataSource.getConnection();
Statement statement = con.createStatement();
createStmt = con.createStatement();
String createDataStmt = "CREATE TABLE IF NOT EXISTS " + PREMIUM_TABLE + " ("
+ "UserID INTEGER PRIMARY KEY AUTO_INCREMENT, "
+ "UUID CHAR(36), "
@@ -65,21 +66,23 @@ public class Storage {
createDataStmt = createDataStmt.replace("AUTO_INCREMENT", "AUTOINCREMENT");
}
statement.executeUpdate(createDataStmt);
createStmt.executeUpdate(createDataStmt);
} finally {
closeQuietly(con);
closeQuietly(createStmt);
}
}
public PlayerProfile loadProfile(String name) {
Connection con = null;
PreparedStatement loadStmt = null;
ResultSet resultSet = null;
try {
con = dataSource.getConnection();
PreparedStatement loadStatement = con.prepareStatement("SELECT * FROM " + PREMIUM_TABLE
+ " WHERE Name=? LIMIT 1");
loadStatement.setString(1, name);
loadStmt = con.prepareStatement("SELECT * FROM " + PREMIUM_TABLE + " WHERE Name=?");
loadStmt.setString(1, name);
ResultSet resultSet = loadStatement.executeQuery();
resultSet = loadStmt.executeQuery();
if (resultSet.next()) {
long userId = resultSet.getInt(1);
@@ -104,6 +107,39 @@ public class Storage {
core.getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);
} finally {
closeQuietly(con);
closeQuietly(loadStmt);
closeQuietly(resultSet);
}
return null;
}
public PlayerProfile loadProfile(UUID uuid) {
Connection con = null;
PreparedStatement loadStmt = null;
ResultSet resultSet = null;
try {
con = dataSource.getConnection();
loadStmt = con.prepareStatement("SELECT * FROM " + PREMIUM_TABLE + " WHERE UUID=?");
loadStmt.setString(1, uuid.toString().replace("-", ""));
resultSet = loadStmt.executeQuery();
if (resultSet.next()) {
long userId = resultSet.getInt(1);
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);
return playerProfile;
}
} catch (SQLException sqlEx) {
core.getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);
} finally {
closeQuietly(con);
closeQuietly(loadStmt);
closeQuietly(resultSet);
}
return null;
@@ -111,46 +147,69 @@ public class Storage {
public boolean save(PlayerProfile playerProfile) {
Connection con = null;
PreparedStatement updateStmt = null;
PreparedStatement saveStmt = null;
ResultSet generatedKeys = 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);
//User was authenticated with a premium authentication, so it's possible that the player is premium
if (uuid != null) {
updateStmt = con.prepareStatement("UPDATE " + PREMIUM_TABLE
+ " SET NAME=?, LastIp=?, LastLogin=CURRENT_TIMESTAMP"
+ " WHERE UUID=? AND PREMIUM=1");
if (uuid == null) {
saveStatement.setString(1, null);
} else {
saveStatement.setString(1, uuid.toString().replace("-", ""));
updateStmt.setString(1, playerProfile.getPlayerName());
updateStmt.setString(2, playerProfile.getLastIp());
updateStmt.setString(3, uuid.toString().replace("-", ""));
int affectedRows = updateStmt.executeUpdate();
if (affectedRows > 0) {
//username changed and we updated the existing database record
//so we don't need to run an insert
return true;
}
}
saveStatement.setString(2, playerProfile.getPlayerName());
saveStatement.setBoolean(3, playerProfile.isPremium());
saveStatement.setString(4, playerProfile.getLastIp());
saveStatement.execute();
saveStmt = con.prepareStatement("INSERT INTO " + PREMIUM_TABLE
+ " (UUID, Name, Premium, LastIp) VALUES (?, ?, ?, ?) "
, Statement.RETURN_GENERATED_KEYS);
ResultSet generatedKeys = saveStatement.getGeneratedKeys();
if (uuid == null) {
saveStmt.setString(1, null);
} else {
saveStmt.setString(1, uuid.toString().replace("-", ""));
}
saveStmt.setString(2, playerProfile.getPlayerName());
saveStmt.setBoolean(3, playerProfile.isPremium());
saveStmt.setString(4, playerProfile.getLastIp());
saveStmt.execute();
generatedKeys = saveStmt.getGeneratedKeys();
if (generatedKeys != null && generatedKeys.next()) {
playerProfile.setUserId(generatedKeys.getInt(1));
}
} else {
PreparedStatement saveStatement = con.prepareStatement("UPDATE " + PREMIUM_TABLE
saveStmt = con.prepareStatement("UPDATE " + PREMIUM_TABLE
+ " SET UUID=?, Name=?, Premium=?, LastIp=?, LastLogin=CURRENT_TIMESTAMP WHERE UserID=?");
if (uuid == null) {
saveStatement.setString(1, null);
saveStmt.setString(1, null);
} else {
saveStatement.setString(1, uuid.toString().replace("-", ""));
saveStmt.setString(1, uuid.toString().replace("-", ""));
}
saveStatement.setString(2, playerProfile.getPlayerName());
saveStatement.setBoolean(3, playerProfile.isPremium());
saveStatement.setString(4, playerProfile.getLastIp());
saveStmt.setString(2, playerProfile.getPlayerName());
saveStmt.setBoolean(3, playerProfile.isPremium());
saveStmt.setString(4, playerProfile.getLastIp());
saveStatement.setLong(5, playerProfile.getUserId());
saveStatement.execute();
saveStmt.setLong(5, playerProfile.getUserId());
saveStmt.execute();
}
return true;
@@ -158,6 +217,9 @@ public class Storage {
core.getLogger().log(Level.SEVERE, "Failed to save playerProfile", ex);
} finally {
closeQuietly(con);
closeQuietly(updateStmt);
closeQuietly(saveStmt);
closeQuietly(generatedKeys);
}
return false;
@@ -167,12 +229,12 @@ public class Storage {
dataSource.close();
}
private void closeQuietly(Connection con) {
if (con != null) {
private void closeQuietly(AutoCloseable closeable) {
if (closeable != null) {
try {
con.close();
} catch (SQLException sqlEx) {
core.getLogger().log(Level.SEVERE, "Failed to close connection", sqlEx);
closeable.close();
} catch (Exception closeEx) {
core.getLogger().log(Level.SEVERE, "Failed to close connection", closeEx);
}
}
}
+44
View File
@@ -40,6 +40,50 @@ autoRegister: false
# This feature requires Cauldron, Spigot or a fork of Spigot (PaperSpigot, TacoSpigot)
premiumUuid: false
# This will make an additional check (only for player names which are not in the database) against the mojang servers
# in order to get the premium UUID. If that premium UUID is in the database, we can assume on sucessful login that the
# player changed it's username and we just update the name in the database.
# Examples:
# #### Case 1
# nameChangeCheck = false ----- autoRegister = false
#
# Player logins as cracked until the player invoked the command /premium. Then we could override the existing database
# record.
#
# #### Case 2
#
# nameChangeCheck = true ----- autoRegister = false
#
# Connect the Mojang API and check what UUID the player has (UUID exists => Paid Minecraft account). If that UUID is in
# the database it's an **existing player** and FastLogin can **assume** the player is premium and changed the username.
# If it's not in the database, it's a new player and **could be a cracked player**. So we just use a offline mode
# authentication for this player.
#
# **Limitation**: Cracked players who uses the new username of a paid account cannot join the server if the database
# contains the old name. (Example: The owner of the paid account no longer plays on the server, but changed the username
# in the meanwhile).
#
# #### Case 3
#
# nameChangeCheck = false ----- autoRegister = true
#
# We will always request a premium authentication if the username is unknown to us, but is in use by a paid minecraft
# account. This means it's kind of a more aggressive check like nameChangeCheck = true and autoRegister = false, because
# it request a premium authentication which are completely new to us, that even the premium UUID is not in our database.
#
# **Limitation**: see below
#
# #### Case 4
#
# nameChangeCheck = true ----- autoRegister = true
#
# Based on autoRegister it checks if the player name is premium and login using a premium authentication. After that
# fastlogin receives the premium UUID and can update the database record.
#
# **Limitation from autoRegister**: New offline players who uses the username of an existing minecraft cannot join the
# server.
nameChangeCheck: false
# If your players have a premium account and a skin associated to their account, this plugin
# can download the data and set it to the online player.
#