forked from TuxCoding/FastLogin
Merge pull request #709 from Smart123s/feature/floodgate/newdb
Differentiate Floodgate players in database
This commit is contained in:
@ -220,6 +220,14 @@
|
|||||||
<property name="optional" value="true"/>
|
<property name="optional" value="true"/>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
|
<!-- Suppress filters via comments -->
|
||||||
|
<!-- https://stackoverflow.com/a/4023351/9767089 -->
|
||||||
|
<module name="SuppressionCommentFilter">
|
||||||
|
<property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)"/>
|
||||||
|
<property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)"/>
|
||||||
|
<property name="checkFormat" value="$1"/>
|
||||||
|
</module>
|
||||||
|
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
</module>
|
</module>
|
||||||
|
@ -80,6 +80,40 @@ public abstract class FloodgateManagement<P extends C, C, L extends LoginSession
|
|||||||
}
|
}
|
||||||
|
|
||||||
profile = core.getStorage().loadProfile(username);
|
profile = core.getStorage().loadProfile(username);
|
||||||
|
|
||||||
|
if (profile.isSaved()) {
|
||||||
|
if (profile.isFloodgateMigrated()) {
|
||||||
|
if (profile.getFloodgate() == FloodgateState.TRUE && isLinked) {
|
||||||
|
core.getPlugin().getLog()
|
||||||
|
.info("Player {} is already stored by FastLogin as a non-linked Bedrock Edition player",
|
||||||
|
username);
|
||||||
|
return;
|
||||||
|
} else if (profile.getFloodgate() == FloodgateState.FALSE && isLinked) {
|
||||||
|
profile.setFloodgate(FloodgateState.LINKED);
|
||||||
|
core.getPlugin().getLog().info(
|
||||||
|
"Player {} will be changed from a Java player to a linked Floodgate player",
|
||||||
|
username);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isLinked) {
|
||||||
|
profile.setFloodgate(FloodgateState.LINKED);
|
||||||
|
core.getPlugin().getLog().info(
|
||||||
|
"Player {} will be migrated to the v2 database schema as a linked Floodgate user",
|
||||||
|
username);
|
||||||
|
} else {
|
||||||
|
profile.setFloodgate(FloodgateState.TRUE);
|
||||||
|
core.getPlugin().getLog().info(
|
||||||
|
"Player {} will be migrated to the v2 database schema as a Floodgate user", username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isLinked) {
|
||||||
|
profile.setFloodgate(FloodgateState.LINKED);
|
||||||
|
} else {
|
||||||
|
profile.setFloodgate(FloodgateState.TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AuthPlugin<P> authPlugin = core.getAuthPluginHook();
|
AuthPlugin<P> authPlugin = core.getAuthPluginHook();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -119,13 +153,17 @@ public abstract class FloodgateManagement<P extends C, C, L extends LoginSession
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// defer auto registration, if it's not enabled in the config
|
||||||
if (!isRegistered && !isAutoAuthAllowed(autoRegisterFloodgate)) {
|
if (!isRegistered && !isAutoAuthAllowed(autoRegisterFloodgate)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//logging in from bedrock for a second time threw an error with UUID
|
// stop the auto login procedure, if the current connection's parameters don't match the one stored in our
|
||||||
if (profile == null) {
|
// database
|
||||||
profile = new StoredProfile(getUUID(player), username, true, getAddress(player).toString());
|
// ex. we stored a LINKED account, but the current connection is not linked
|
||||||
|
if ((profile.getFloodgate() == FloodgateState.LINKED && !isLinked)
|
||||||
|
|| (profile.getFloodgate() == FloodgateState.TRUE && isLinked)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//start Bukkit/Bungee specific tasks
|
//start Bukkit/Bungee specific tasks
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2023 games647 and contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.github.games647.fastlogin.core.shared;
|
||||||
|
|
||||||
|
public enum FloodgateState {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purely Java profile
|
||||||
|
*/
|
||||||
|
FALSE(0),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purely Bedrock profile
|
||||||
|
*/
|
||||||
|
TRUE(1),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bedrock profile is bidirectional associated with the Java Mojang profile.
|
||||||
|
*/
|
||||||
|
LINKED(2),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data before floodgate database migration. Floodgate state is unknown.
|
||||||
|
*/
|
||||||
|
NOT_MIGRATED(3);
|
||||||
|
|
||||||
|
private int value;
|
||||||
|
|
||||||
|
FloodgateState(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a number to FloodgateState
|
||||||
|
* <ol start="0">
|
||||||
|
* <li>False</li>
|
||||||
|
* <li>True</li>
|
||||||
|
* <li>Linked</li>
|
||||||
|
* <li>Not Migrated</li>
|
||||||
|
* </ol>
|
||||||
|
* @param num the number, most likely loaded from the database
|
||||||
|
* @return FloodgateStatus on success, null otherwise
|
||||||
|
*/
|
||||||
|
public static FloodgateState fromInt(int num) {
|
||||||
|
// using Enum.values()[i] is expensive as per https://stackoverflow.com/a/8762387/9767089
|
||||||
|
switch (num) {
|
||||||
|
case 0:
|
||||||
|
return FloodgateState.FALSE;
|
||||||
|
case 1:
|
||||||
|
return FloodgateState.TRUE;
|
||||||
|
case 2:
|
||||||
|
return FloodgateState.LINKED;
|
||||||
|
case 3:
|
||||||
|
return FloodgateState.NOT_MIGRATED;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -49,17 +49,32 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
|
|||||||
|
|
||||||
public void onLogin(String username, S source) {
|
public void onLogin(String username, S source) {
|
||||||
core.getPlugin().getLog().info("Handling player {}", username);
|
core.getPlugin().getLog().info("Handling player {}", username);
|
||||||
|
|
||||||
|
//check if the player is connecting through Bedrock Edition
|
||||||
|
if (bedrockService != null && bedrockService.isBedrockConnection(username)) {
|
||||||
|
//perform Bedrock specific checks and skip Java checks if no longer needed
|
||||||
|
if (bedrockService.performChecks(username, source)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StoredProfile profile = core.getStorage().loadProfile(username);
|
StoredProfile profile = core.getStorage().loadProfile(username);
|
||||||
|
|
||||||
|
//can't be a premium Java player, if it's not saved in the database
|
||||||
if (profile == null) {
|
if (profile == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if the player is connecting through Bedrock Edition
|
if (profile.isFloodgateMigrated()) {
|
||||||
if (bedrockService != null && bedrockService.isBedrockConnection(username)) {
|
if (profile.getFloodgate() == FloodgateState.TRUE) {
|
||||||
//perform Bedrock specific checks and skip Java checks, if they are not needed
|
// migrated and enabled floodgate player, however the above bedrocks fails, so the current connection
|
||||||
if (bedrockService.performChecks(username, source)) {
|
// isn't premium
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
profile.setFloodgate(FloodgateState.FALSE);
|
||||||
|
core.getPlugin().getLog().info(
|
||||||
|
"Player {} will be migrated to the v2 database schema as a JAVA user", username);
|
||||||
}
|
}
|
||||||
|
|
||||||
callFastLoginPreLoginEvent(username, source, profile);
|
callFastLoginPreLoginEvent(username, source, profile);
|
||||||
@ -139,6 +154,12 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
|
|||||||
if (core.getConfig().get("nameChangeCheck", false)) {
|
if (core.getConfig().get("nameChangeCheck", false)) {
|
||||||
StoredProfile storedProfile = core.getStorage().loadProfile(profile.getId());
|
StoredProfile storedProfile = core.getStorage().loadProfile(profile.getId());
|
||||||
if (storedProfile != null) {
|
if (storedProfile != null) {
|
||||||
|
if (storedProfile.getFloodgate() == FloodgateState.TRUE) {
|
||||||
|
core.getPlugin().getLog()
|
||||||
|
.info("Player {} is already stored by FastLogin as a Bedrock Edition player.", username);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//uuid exists in the database
|
//uuid exists in the database
|
||||||
core.getPlugin().getLog().info("GameProfile {} changed it's username", profile);
|
core.getPlugin().getLog().info("GameProfile {} changed it's username", profile);
|
||||||
|
|
||||||
|
@ -26,11 +26,13 @@
|
|||||||
package com.github.games647.fastlogin.core.storage;
|
package com.github.games647.fastlogin.core.storage;
|
||||||
|
|
||||||
import com.github.games647.craftapi.UUIDAdapter;
|
import com.github.games647.craftapi.UUIDAdapter;
|
||||||
|
import com.github.games647.fastlogin.core.shared.FloodgateState;
|
||||||
import com.zaxxer.hikari.HikariConfig;
|
import com.zaxxer.hikari.HikariConfig;
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@ -56,13 +58,19 @@ public abstract class SQLStorage implements AuthStorage {
|
|||||||
+ "UNIQUE (`Name`) "
|
+ "UNIQUE (`Name`) "
|
||||||
+ ')';
|
+ ')';
|
||||||
|
|
||||||
protected static final String LOAD_BY_NAME = "SELECT * FROM `" + PREMIUM_TABLE + "` WHERE `Name`=? LIMIT 1";
|
protected static final String ADD_FLOODGATE_COLUMN_STMT = "ALTER TABLE `" + PREMIUM_TABLE
|
||||||
protected static final String LOAD_BY_UUID = "SELECT * FROM `" + PREMIUM_TABLE + "` WHERE `UUID`=? LIMIT 1";
|
+ "` ADD COLUMN `Floodgate` INTEGER(3)";
|
||||||
|
|
||||||
|
protected static final String LOAD_BY_NAME = "SELECT * FROM `" + PREMIUM_TABLE
|
||||||
|
+ "` WHERE `Name`=? LIMIT 1";
|
||||||
|
protected static final String LOAD_BY_UUID = "SELECT * FROM `" + PREMIUM_TABLE
|
||||||
|
+ "` WHERE `UUID`=? LIMIT 1";
|
||||||
protected static final String INSERT_PROFILE = "INSERT INTO `" + PREMIUM_TABLE
|
protected static final String INSERT_PROFILE = "INSERT INTO `" + PREMIUM_TABLE
|
||||||
+ "` (`UUID`, `Name`, `Premium`, `LastIp`) " + "VALUES (?, ?, ?, ?) ";
|
+ "` (`UUID`, `Name`, `Premium`, `Floodgate`, `LastIp`) " + "VALUES (?, ?, ?, ?, ?) ";
|
||||||
// limit not necessary here, because it's unique
|
// limit not necessary here, because it's unique
|
||||||
protected static final String UPDATE_PROFILE = "UPDATE `" + PREMIUM_TABLE
|
protected static final String UPDATE_PROFILE = "UPDATE `" + PREMIUM_TABLE
|
||||||
+ "` SET `UUID`=?, `Name`=?, `Premium`=?, `LastIp`=?, `LastLogin`=CURRENT_TIMESTAMP WHERE `UserID`=?";
|
+ "` SET `UUID`=?, `Name`=?, `Premium`=?, `Floodgate`=?, `LastIp`=?, "
|
||||||
|
+ "`LastLogin`=CURRENT_TIMESTAMP WHERE `UserID`=?";
|
||||||
|
|
||||||
protected final Logger log;
|
protected final Logger log;
|
||||||
protected final HikariDataSource dataSource;
|
protected final HikariDataSource dataSource;
|
||||||
@ -81,11 +89,23 @@ public abstract class SQLStorage implements AuthStorage {
|
|||||||
// choose surrogate PK(ID), because UUID can be null for offline players
|
// choose surrogate PK(ID), because UUID can be null for offline players
|
||||||
// if UUID is always Premium UUID we would have to update offline player entries on insert
|
// if UUID is always Premium UUID we would have to update offline player entries on insert
|
||||||
// name cannot be PK, because it can be changed for premium players
|
// name cannot be PK, because it can be changed for premium players
|
||||||
|
|
||||||
//todo: add unique uuid index usage
|
//todo: add unique uuid index usage
|
||||||
try (Connection con = dataSource.getConnection();
|
try (Connection con = dataSource.getConnection();
|
||||||
Statement createStmt = con.createStatement()) {
|
Statement stmt = con.createStatement()) {
|
||||||
createStmt.executeUpdate(CREATE_TABLE_STMT);
|
stmt.executeUpdate(getCreateTableStmt());
|
||||||
|
|
||||||
|
// add Floodgate column
|
||||||
|
DatabaseMetaData md = con.getMetaData();
|
||||||
|
if (isColumnMissing(md, "Floodgate")) {
|
||||||
|
stmt.executeUpdate(ADD_FLOODGATE_COLUMN_STMT);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isColumnMissing(DatabaseMetaData metaData, String columnName) throws SQLException {
|
||||||
|
try (ResultSet rs = metaData.getColumns(null, null, PREMIUM_TABLE, columnName)) {
|
||||||
|
return !rs.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +117,8 @@ public abstract class SQLStorage implements AuthStorage {
|
|||||||
loadStmt.setString(1, name);
|
loadStmt.setString(1, name);
|
||||||
|
|
||||||
try (ResultSet resultSet = loadStmt.executeQuery()) {
|
try (ResultSet resultSet = loadStmt.executeQuery()) {
|
||||||
return parseResult(resultSet).orElseGet(() -> new StoredProfile(null, name, false, ""));
|
return parseResult(resultSet).orElseGet(() -> new StoredProfile(null, name, false,
|
||||||
|
FloodgateState.FALSE, ""));
|
||||||
}
|
}
|
||||||
} catch (SQLException sqlEx) {
|
} catch (SQLException sqlEx) {
|
||||||
log.error("Failed to query profile: {}", name, sqlEx);
|
log.error("Failed to query profile: {}", name, sqlEx);
|
||||||
@ -124,15 +145,25 @@ public abstract class SQLStorage implements AuthStorage {
|
|||||||
|
|
||||||
private Optional<StoredProfile> parseResult(ResultSet resultSet) throws SQLException {
|
private Optional<StoredProfile> parseResult(ResultSet resultSet) throws SQLException {
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
long userId = resultSet.getInt(1);
|
long userId = resultSet.getInt("UserID");
|
||||||
|
|
||||||
UUID uuid = Optional.ofNullable(resultSet.getString(2)).map(UUIDAdapter::parseId).orElse(null);
|
UUID uuid = Optional.ofNullable(resultSet.getString("UUID")).map(UUIDAdapter::parseId).orElse(null);
|
||||||
|
|
||||||
String name = resultSet.getString(3);
|
String name = resultSet.getString("Name");
|
||||||
boolean premium = resultSet.getBoolean(4);
|
boolean premium = resultSet.getBoolean("Premium");
|
||||||
String lastIp = resultSet.getString(5);
|
int floodgateNum = resultSet.getInt("Floodgate");
|
||||||
Instant lastLogin = resultSet.getTimestamp(6).toInstant();
|
FloodgateState floodgate;
|
||||||
return Optional.of(new StoredProfile(userId, uuid, name, premium, lastIp, lastLogin));
|
|
||||||
|
// if the player wasn't migrated to the new database format
|
||||||
|
if (resultSet.wasNull()) {
|
||||||
|
floodgate = FloodgateState.NOT_MIGRATED;
|
||||||
|
} else {
|
||||||
|
floodgate = FloodgateState.fromInt(floodgateNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
String lastIp = resultSet.getString("LastIp");
|
||||||
|
Instant lastLogin = resultSet.getTimestamp("LastLogin").toInstant();
|
||||||
|
return Optional.of(new StoredProfile(userId, uuid, name, premium, floodgate, lastIp, lastLogin));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
@ -150,9 +181,10 @@ public abstract class SQLStorage implements AuthStorage {
|
|||||||
saveStmt.setString(1, uuid);
|
saveStmt.setString(1, uuid);
|
||||||
saveStmt.setString(2, playerProfile.getName());
|
saveStmt.setString(2, playerProfile.getName());
|
||||||
saveStmt.setBoolean(3, playerProfile.isPremium());
|
saveStmt.setBoolean(3, playerProfile.isPremium());
|
||||||
saveStmt.setString(4, playerProfile.getLastIp());
|
saveStmt.setInt(4, playerProfile.getFloodgate().getValue());
|
||||||
|
saveStmt.setString(5, playerProfile.getLastIp());
|
||||||
|
|
||||||
saveStmt.setLong(5, playerProfile.getRowId());
|
saveStmt.setLong(6, playerProfile.getRowId());
|
||||||
saveStmt.execute();
|
saveStmt.execute();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -161,7 +193,9 @@ public abstract class SQLStorage implements AuthStorage {
|
|||||||
|
|
||||||
saveStmt.setString(2, playerProfile.getName());
|
saveStmt.setString(2, playerProfile.getName());
|
||||||
saveStmt.setBoolean(3, playerProfile.isPremium());
|
saveStmt.setBoolean(3, playerProfile.isPremium());
|
||||||
saveStmt.setString(4, playerProfile.getLastIp());
|
saveStmt.setBoolean(3, playerProfile.isPremium());
|
||||||
|
saveStmt.setInt(4, playerProfile.getFloodgate().getValue());
|
||||||
|
saveStmt.setString(5, playerProfile.getLastIp());
|
||||||
|
|
||||||
saveStmt.execute();
|
saveStmt.execute();
|
||||||
try (ResultSet generatedKeys = saveStmt.getGeneratedKeys()) {
|
try (ResultSet generatedKeys = saveStmt.getGeneratedKeys()) {
|
||||||
@ -179,6 +213,14 @@ public abstract class SQLStorage implements AuthStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SQLite has a slightly different syntax, so this will be overridden by SQLiteStorage
|
||||||
|
* @return An SQL Statement to create the `premium` table
|
||||||
|
*/
|
||||||
|
protected String getCreateTableStmt() {
|
||||||
|
return CREATE_TABLE_STMT;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
dataSource.close();
|
dataSource.close();
|
||||||
|
@ -31,15 +31,23 @@ import org.sqlite.JDBC;
|
|||||||
import org.sqlite.SQLiteConfig;
|
import org.sqlite.SQLiteConfig;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
public class SQLiteStorage extends SQLStorage {
|
public class SQLiteStorage extends SQLStorage {
|
||||||
|
|
||||||
|
protected static final String CREATE_TABLE_STMT = "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, "
|
||||||
|
//the premium shouldn't steal the cracked account by changing the name
|
||||||
|
+ "UNIQUE (`Name`) "
|
||||||
|
+ ')';
|
||||||
|
|
||||||
private static final String SQLITE_DRIVER = "org.sqlite.SQLiteDataSource";
|
private static final String SQLITE_DRIVER = "org.sqlite.SQLiteDataSource";
|
||||||
private final Lock lock = new ReentrantLock();
|
private final Lock lock = new ReentrantLock();
|
||||||
|
|
||||||
@ -103,12 +111,9 @@ public class SQLiteStorage extends SQLStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createTables() throws SQLException {
|
protected String getCreateTableStmt() {
|
||||||
try (Connection con = dataSource.getConnection();
|
// SQLite has a different syntax for auto increment
|
||||||
Statement createStmt = con.createStatement()) {
|
return CREATE_TABLE_STMT.replace("AUTO_INCREMENT", "AUTOINCREMENT");
|
||||||
// SQLite has a different syntax for auto increment
|
|
||||||
createStmt.executeUpdate(CREATE_TABLE_STMT.replace("AUTO_INCREMENT", "AUTOINCREMENT"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String replacePathVariables(Path dataFolder, String input) {
|
private static String replacePathVariables(Path dataFolder, String input) {
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
package com.github.games647.fastlogin.core.storage;
|
package com.github.games647.fastlogin.core.storage;
|
||||||
|
|
||||||
import com.github.games647.craftapi.model.Profile;
|
import com.github.games647.craftapi.model.Profile;
|
||||||
|
import com.github.games647.fastlogin.core.shared.FloodgateState;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -39,20 +40,28 @@ public class StoredProfile extends Profile {
|
|||||||
private final ReentrantLock saveLock = new ReentrantLock();
|
private final ReentrantLock saveLock = new ReentrantLock();
|
||||||
|
|
||||||
private boolean premium;
|
private boolean premium;
|
||||||
|
private FloodgateState floodgate;
|
||||||
private String lastIp;
|
private String lastIp;
|
||||||
private Instant lastLogin;
|
private Instant lastLogin;
|
||||||
|
|
||||||
public StoredProfile(long rowId, UUID uuid, String playerName, boolean premium, String lastIp, Instant lastLogin) {
|
public StoredProfile(long rowId, UUID uuid, String playerName, boolean premium, FloodgateState floodgate,
|
||||||
|
String lastIp, Instant lastLogin) {
|
||||||
super(uuid, playerName);
|
super(uuid, playerName);
|
||||||
|
|
||||||
this.rowId = rowId;
|
this.rowId = rowId;
|
||||||
this.premium = premium;
|
this.premium = premium;
|
||||||
|
this.floodgate = floodgate;
|
||||||
this.lastIp = lastIp;
|
this.lastIp = lastIp;
|
||||||
this.lastLogin = lastLogin;
|
this.lastLogin = lastLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StoredProfile(UUID uuid, String playerName, boolean premium, FloodgateState isFloodgate, String lastIp) {
|
||||||
|
this(-1, uuid, playerName, premium, isFloodgate, lastIp, Instant.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public StoredProfile(UUID uuid, String playerName, boolean premium, String lastIp) {
|
public StoredProfile(UUID uuid, String playerName, boolean premium, String lastIp) {
|
||||||
this(-1, uuid, playerName, premium, lastIp, Instant.now());
|
this(-1, uuid, playerName, premium, FloodgateState.FALSE, lastIp, Instant.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReentrantLock getSaveLock() {
|
public ReentrantLock getSaveLock() {
|
||||||
@ -96,6 +105,18 @@ public class StoredProfile extends Profile {
|
|||||||
this.premium = premium;
|
this.premium = premium;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized FloodgateState getFloodgate() {
|
||||||
|
return floodgate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean isFloodgateMigrated() {
|
||||||
|
return floodgate != FloodgateState.NOT_MIGRATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void setFloodgate(FloodgateState floodgate) {
|
||||||
|
this.floodgate = floodgate;
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized String getLastIp() {
|
public synchronized String getLastIp() {
|
||||||
return lastIp;
|
return lastIp;
|
||||||
}
|
}
|
||||||
@ -128,7 +149,7 @@ public class StoredProfile extends Profile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return rowId == that.rowId && premium == that.premium
|
return rowId == that.rowId && premium == that.premium
|
||||||
&& Objects.equals(lastIp, that.lastIp) && lastLogin.equals(that.lastLogin);
|
&& Objects.equals(lastIp, that.lastIp) && lastLogin.equals(that.lastLogin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -141,6 +162,7 @@ public class StoredProfile extends Profile {
|
|||||||
return this.getClass().getSimpleName() + '{'
|
return this.getClass().getSimpleName() + '{'
|
||||||
+ "rowId=" + rowId
|
+ "rowId=" + rowId
|
||||||
+ ", premium=" + premium
|
+ ", premium=" + premium
|
||||||
|
+ ", floodgate=" + floodgate
|
||||||
+ ", lastIp='" + lastIp + '\''
|
+ ", lastIp='" + lastIp + '\''
|
||||||
+ ", lastLogin=" + lastLogin
|
+ ", lastLogin=" + lastLogin
|
||||||
+ "} " + super.toString();
|
+ "} " + super.toString();
|
||||||
|
Reference in New Issue
Block a user