diff --git a/src/main/java/fr/xephi/authme/data/auth/PlayerAuth.java b/src/main/java/fr/xephi/authme/data/auth/PlayerAuth.java index 32bdc01b..4aebd88d 100644 --- a/src/main/java/fr/xephi/authme/data/auth/PlayerAuth.java +++ b/src/main/java/fr/xephi/authme/data/auth/PlayerAuth.java @@ -5,6 +5,7 @@ import org.bukkit.Location; import java.util.Objects; import java.util.Optional; +import java.util.UUID; import static com.google.common.base.Preconditions.checkNotNull; @@ -40,6 +41,7 @@ public class PlayerAuth { private String world; private float yaw; private float pitch; + private UUID uuid; /** * Hidden constructor. @@ -169,6 +171,14 @@ public class PlayerAuth { this.totpKey = totpKey; } + public UUID getUuid() { + return uuid; + } + + public void setUuid(UUID uuid) { + this.uuid = uuid; + } + @Override public boolean equals(Object obj) { if (!(obj instanceof PlayerAuth)) { @@ -193,7 +203,8 @@ public class PlayerAuth { + " ! LastLogin : " + lastLogin + " ! LastPosition : " + x + "," + y + "," + z + "," + world + " ! Email : " + email - + " ! Password : {" + password.getHash() + ", " + password.getSalt() + "}"; + + " ! Password : {" + password.getHash() + ", " + password.getSalt() + "}" + + " ! UUID : " + uuid; } public static Builder builder() { @@ -218,6 +229,7 @@ public class PlayerAuth { private String world; private float yaw; private float pitch; + private UUID uuid; /** * Creates a PlayerAuth object. @@ -243,6 +255,7 @@ public class PlayerAuth { auth.world = Optional.ofNullable(world).orElse("world"); auth.yaw = yaw; auth.pitch = pitch; + auth.uuid = uuid; return auth; } @@ -349,5 +362,10 @@ public class PlayerAuth { this.registrationDate = date; return this; } + + public Builder uuid(UUID uuid) { + this.uuid = uuid; + return this; + } } } diff --git a/src/main/java/fr/xephi/authme/datasource/AbstractSqlDataSource.java b/src/main/java/fr/xephi/authme/datasource/AbstractSqlDataSource.java index 0c40c479..06785168 100644 --- a/src/main/java/fr/xephi/authme/datasource/AbstractSqlDataSource.java +++ b/src/main/java/fr/xephi/authme/datasource/AbstractSqlDataSource.java @@ -53,7 +53,8 @@ public abstract class AbstractSqlDataSource implements DataSource { public boolean saveAuth(PlayerAuth auth) { return columnsHandler.insert(auth, AuthMeColumns.NAME, AuthMeColumns.NICK_NAME, AuthMeColumns.PASSWORD, AuthMeColumns.SALT, - AuthMeColumns.EMAIL, AuthMeColumns.REGISTRATION_DATE, AuthMeColumns.REGISTRATION_IP); + AuthMeColumns.EMAIL, AuthMeColumns.REGISTRATION_DATE, AuthMeColumns.REGISTRATION_IP, + AuthMeColumns.UUID); } @Override diff --git a/src/main/java/fr/xephi/authme/datasource/Columns.java b/src/main/java/fr/xephi/authme/datasource/Columns.java index 0d372a23..a604d0a4 100644 --- a/src/main/java/fr/xephi/authme/datasource/Columns.java +++ b/src/main/java/fr/xephi/authme/datasource/Columns.java @@ -30,6 +30,7 @@ public final class Columns { public final String HAS_SESSION; public final String REGISTRATION_DATE; public final String REGISTRATION_IP; + public final String PLAYER_UUID; public Columns(Settings settings) { NAME = settings.getProperty(DatabaseSettings.MYSQL_COL_NAME); @@ -52,6 +53,7 @@ public final class Columns { HAS_SESSION = settings.getProperty(DatabaseSettings.MYSQL_COL_HASSESSION); REGISTRATION_DATE = settings.getProperty(DatabaseSettings.MYSQL_COL_REGISTER_DATE); REGISTRATION_IP = settings.getProperty(DatabaseSettings.MYSQL_COL_REGISTER_IP); + PLAYER_UUID = settings.getProperty(DatabaseSettings.MYSQL_COL_PLAYER_UUID); } } diff --git a/src/main/java/fr/xephi/authme/datasource/MySQL.java b/src/main/java/fr/xephi/authme/datasource/MySQL.java index badeea14..570a23ce 100644 --- a/src/main/java/fr/xephi/authme/datasource/MySQL.java +++ b/src/main/java/fr/xephi/authme/datasource/MySQL.java @@ -11,6 +11,7 @@ import fr.xephi.authme.datasource.mysqlextensions.MySqlExtensionsFactory; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.HooksSettings; +import fr.xephi.authme.util.UuidUtils; import java.sql.Connection; import java.sql.DatabaseMetaData; @@ -23,6 +24,7 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.UUID; import static fr.xephi.authme.datasource.SqlDataSourceUtils.getNullableLong; import static fr.xephi.authme.datasource.SqlDataSourceUtils.logSqlException; @@ -264,6 +266,11 @@ public class MySQL extends AbstractSqlDataSource { st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.TOTP_KEY + " VARCHAR(16);"); } + + if (!col.PLAYER_UUID.isEmpty() && isColumnMissing(md, col.PLAYER_UUID)) { + st.executeUpdate("ALTER TABLE " + tableName + + " ADD COLUMN " + col.PLAYER_UUID + " VARCHAR(36)"); + } } ConsoleLogger.info("MySQL setup finished"); } @@ -454,6 +461,8 @@ public class MySQL extends AbstractSqlDataSource { private PlayerAuth buildAuthFromResultSet(ResultSet row) throws SQLException { String salt = col.SALT.isEmpty() ? null : row.getString(col.SALT); int group = col.GROUP.isEmpty() ? -1 : row.getInt(col.GROUP); + UUID uuid = col.PLAYER_UUID.isEmpty() + ? null : UuidUtils.parseUuidSafely(row.getString(col.PLAYER_UUID)); return PlayerAuth.builder() .name(row.getString(col.NAME)) .realName(row.getString(col.REAL_NAME)) @@ -471,6 +480,7 @@ public class MySQL extends AbstractSqlDataSource { .locZ(row.getDouble(col.LASTLOC_Z)) .locYaw(row.getFloat(col.LASTLOC_YAW)) .locPitch(row.getFloat(col.LASTLOC_PITCH)) + .uuid(uuid) .build(); } } diff --git a/src/main/java/fr/xephi/authme/datasource/PostgreSqlDataSource.java b/src/main/java/fr/xephi/authme/datasource/PostgreSqlDataSource.java index eaf869b8..62c26b64 100644 --- a/src/main/java/fr/xephi/authme/datasource/PostgreSqlDataSource.java +++ b/src/main/java/fr/xephi/authme/datasource/PostgreSqlDataSource.java @@ -241,6 +241,11 @@ public class PostgreSqlDataSource extends AbstractSqlDataSource { st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.TOTP_KEY + " VARCHAR(16);"); } + + if (!col.PLAYER_UUID.isEmpty() && isColumnMissing(md, col.PLAYER_UUID)) { + st.executeUpdate("ALTER TABLE " + tableName + + " ADD COLUMN " + col.PLAYER_UUID + " VARCHAR(36)"); + } } ConsoleLogger.info("PostgreSQL setup finished"); } diff --git a/src/main/java/fr/xephi/authme/datasource/SQLite.java b/src/main/java/fr/xephi/authme/datasource/SQLite.java index fe7260ec..b1b796e4 100644 --- a/src/main/java/fr/xephi/authme/datasource/SQLite.java +++ b/src/main/java/fr/xephi/authme/datasource/SQLite.java @@ -182,6 +182,11 @@ public class SQLite extends AbstractSqlDataSource { st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.TOTP_KEY + " VARCHAR(16);"); } + + if (!col.PLAYER_UUID.isEmpty() && isColumnMissing(md, col.PLAYER_UUID)) { + st.executeUpdate("ALTER TABLE " + tableName + + " ADD COLUMN " + col.PLAYER_UUID + " VARCHAR(36)"); + } } ConsoleLogger.info("SQLite Setup finished"); } diff --git a/src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumns.java b/src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumns.java index 5c235095..7c4d2e6a 100644 --- a/src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumns.java +++ b/src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumns.java @@ -3,6 +3,8 @@ package fr.xephi.authme.datasource.columnshandler; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.settings.properties.DatabaseSettings; +import java.util.UUID; + import static fr.xephi.authme.datasource.columnshandler.AuthMeColumnsFactory.ColumnOptions.DEFAULT_FOR_NULL; import static fr.xephi.authme.datasource.columnshandler.AuthMeColumnsFactory.ColumnOptions.OPTIONAL; import static fr.xephi.authme.datasource.columnshandler.AuthMeColumnsFactory.createDouble; @@ -46,6 +48,11 @@ public final class AuthMeColumns { public static final PlayerAuthColumn REGISTRATION_DATE = createLong( DatabaseSettings.MYSQL_COL_REGISTER_DATE, PlayerAuth::getRegistrationDate); + public static final PlayerAuthColumn UUID = createString( + DatabaseSettings.MYSQL_COL_PLAYER_UUID, + auth -> ( auth.getUuid() == null ? null : auth.getUuid().toString()), + OPTIONAL); + // -------- // Location columns // -------- @@ -76,7 +83,6 @@ public final class AuthMeColumns { public static final DataSourceColumn HAS_SESSION = createInteger( DatabaseSettings.MYSQL_COL_HASSESSION); - private AuthMeColumns() { } } diff --git a/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java b/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java index 4fd5fb34..d13f373c 100644 --- a/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java +++ b/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java @@ -7,6 +7,7 @@ import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.ConverterSettings; +import fr.xephi.authme.util.UuidUtils; import org.bukkit.command.CommandSender; import javax.inject.Inject; @@ -21,6 +22,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Optional; +import java.util.UUID; import static fr.xephi.authme.util.Utils.logAndSendMessage; @@ -119,6 +121,7 @@ public class LoginSecurityConverter implements Converter { .map(Timestamp::getTime).orElse(null); long regDate = Optional.ofNullable(resultSet.getDate("registration_date")) .map(Date::getTime).orElse(System.currentTimeMillis()); + UUID uuid = UuidUtils.parseUuidSafely(resultSet.getString("unique_user_id")); return PlayerAuth.builder() .name(name) .realName(name) @@ -132,6 +135,7 @@ public class LoginSecurityConverter implements Converter { .locWorld(resultSet.getString("world")) .locYaw(resultSet.getFloat("yaw")) .locPitch(resultSet.getFloat("pitch")) + .uuid(uuid) .build(); } diff --git a/src/main/java/fr/xephi/authme/process/register/executors/PlayerAuthBuilderHelper.java b/src/main/java/fr/xephi/authme/process/register/executors/PlayerAuthBuilderHelper.java index d8c6a5fc..a9717fdc 100644 --- a/src/main/java/fr/xephi/authme/process/register/executors/PlayerAuthBuilderHelper.java +++ b/src/main/java/fr/xephi/authme/process/register/executors/PlayerAuthBuilderHelper.java @@ -29,6 +29,7 @@ final class PlayerAuthBuilderHelper { .email(email) .registrationIp(PlayerUtils.getPlayerIp(player)) .registrationDate(System.currentTimeMillis()) + .uuid(player.getUniqueId()) .build(); } } diff --git a/src/main/java/fr/xephi/authme/settings/properties/DatabaseSettings.java b/src/main/java/fr/xephi/authme/settings/properties/DatabaseSettings.java index 83ed18e7..358d612f 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/DatabaseSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/DatabaseSettings.java @@ -129,6 +129,10 @@ public final class DatabaseSettings implements SettingsHolder { public static final Property MYSQL_COL_LASTLOC_PITCH = newProperty("DataSource.mySQLlastlocPitch", "pitch"); + @Comment("Column for storing players uuids (optional)") + public static final Property MYSQL_COL_PLAYER_UUID = + newProperty( "DataSource.mySQLPlayerUUID", "" ); + @Comment("Column for storing players groups") public static final Property MYSQL_COL_GROUP = newProperty("ExternalBoardOptions.mySQLColumnGroup", ""); diff --git a/src/main/java/fr/xephi/authme/util/UuidUtils.java b/src/main/java/fr/xephi/authme/util/UuidUtils.java new file mode 100644 index 00000000..4a2306af --- /dev/null +++ b/src/main/java/fr/xephi/authme/util/UuidUtils.java @@ -0,0 +1,27 @@ +package fr.xephi.authme.util; + +import java.util.UUID; + +/** + * Utility class for various operations on UUID. + */ +public final class UuidUtils { + + // Utility class + private UuidUtils() { + } + + /** + * Returns whether the given string as an UUID or null + * + * @param string the uuid to parse + * @return parsed UUID if succeed or null + */ + public static UUID parseUuidSafely(String string) { + try { + return UUID.fromString(string); + } catch (IllegalArgumentException | NullPointerException ex) { + return null; + } + } +}