diff options
Diffstat (limited to 'src/main/java/net/elytrium/limboauth')
13 files changed, 344 insertions, 213 deletions
diff --git a/src/main/java/net/elytrium/limboauth/LimboAuth.java b/src/main/java/net/elytrium/limboauth/LimboAuth.java index f8e3755..1a3b6ca 100644 --- a/src/main/java/net/elytrium/limboauth/LimboAuth.java +++ b/src/main/java/net/elytrium/limboauth/LimboAuth.java @@ -65,6 +65,7 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; +import java.util.function.Function; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -97,7 +98,6 @@ import net.elytrium.limboauth.floodgate.FloodgateApiHolder; import net.elytrium.limboauth.handler.AuthSessionHandler; import net.elytrium.limboauth.listener.AuthListener; import net.elytrium.limboauth.model.RegisteredPlayer; -import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.ComponentSerializer; import net.kyori.adventure.title.Title; @@ -464,12 +464,12 @@ public class LimboAuth { public void cacheAuthUser(Player player) { String username = player.getUsername(); String lowercaseUsername = username.toLowerCase(Locale.ROOT); - this.cachedAuthChecks.remove(lowercaseUsername); this.cachedAuthChecks.put(lowercaseUsername, new CachedSessionUser(System.currentTimeMillis(), player.getRemoteAddress().getAddress(), username)); } public void removePlayerFromCache(String username) { this.cachedAuthChecks.remove(username.toLowerCase(Locale.ROOT)); + this.premiumCache.remove(username.toLowerCase(Locale.ROOT)); } public boolean needAuth(Player player) { @@ -486,87 +486,88 @@ public class LimboAuth { public void authPlayer(Player player) { boolean isFloodgate = !Settings.IMP.MAIN.FLOODGATE_NEED_AUTH && this.floodgateApi.isFloodgatePlayer(player.getUniqueId()); String nickname = player.getUsername(); - if (this.nicknameValidationPattern.matcher((isFloodgate) ? nickname.substring(this.floodgateApi.getPrefixLength()) : nickname).matches()) { - RegisteredPlayer registeredPlayer = AuthSessionHandler.fetchInfo(this.playerDao, nickname); + if (!this.nicknameValidationPattern.matcher((isFloodgate) ? nickname.substring(this.floodgateApi.getPrefixLength()) : nickname).matches()) { + player.disconnect(this.nicknameInvalidKick); + return; + } - boolean onlineMode = player.isOnlineMode(); - TaskEvent.Result result = TaskEvent.Result.NORMAL; + RegisteredPlayer registeredPlayer = AuthSessionHandler.fetchInfo(this.playerDao, nickname); - if (onlineMode || isFloodgate) { - if (registeredPlayer == null || registeredPlayer.getHash().isEmpty()) { - RegisteredPlayer nicknameRegisteredPlayer = registeredPlayer; - registeredPlayer = AuthSessionHandler.fetchInfo(this.playerDao, player.getUniqueId()); - - if (nicknameRegisteredPlayer != null && registeredPlayer == null && nicknameRegisteredPlayer.getHash().isEmpty()) { - registeredPlayer = nicknameRegisteredPlayer; - registeredPlayer.setPremiumUuid(player.getUniqueId().toString()); - try { - this.playerDao.update(registeredPlayer); - } catch (SQLException e) { - e.printStackTrace(); - } + boolean onlineMode = player.isOnlineMode(); + TaskEvent.Result result = TaskEvent.Result.NORMAL; + + if (onlineMode || isFloodgate) { + if (registeredPlayer == null || registeredPlayer.getHash().isEmpty()) { + RegisteredPlayer nicknameRegisteredPlayer = registeredPlayer; + registeredPlayer = AuthSessionHandler.fetchInfo(this.playerDao, player.getUniqueId()); + + if (nicknameRegisteredPlayer != null && registeredPlayer == null && nicknameRegisteredPlayer.getHash().isEmpty()) { + registeredPlayer = nicknameRegisteredPlayer; + registeredPlayer.setPremiumUuid(player.getUniqueId().toString()); + try { + this.playerDao.update(registeredPlayer); + } catch (SQLException e) { + e.printStackTrace(); } + } - if (nicknameRegisteredPlayer == null && registeredPlayer == null && Settings.IMP.MAIN.SAVE_PREMIUM_ACCOUNTS) { - registeredPlayer = new RegisteredPlayer( - nickname, - nickname.toLowerCase(Locale.ROOT), - "", - player.getRemoteAddress().getAddress().getHostAddress(), - "", - System.currentTimeMillis(), - player.getUniqueId().toString(), - player.getUniqueId().toString() - ); - - try { - this.playerDao.create(registeredPlayer); - } catch (SQLException e) { - e.printStackTrace(); - } + if (nicknameRegisteredPlayer == null && registeredPlayer == null && Settings.IMP.MAIN.SAVE_PREMIUM_ACCOUNTS) { + registeredPlayer = new RegisteredPlayer( + nickname, + nickname.toLowerCase(Locale.ROOT), + "", + player.getRemoteAddress().getAddress().getHostAddress(), + "", + System.currentTimeMillis(), + player.getUniqueId().toString(), + player.getUniqueId().toString() + ); + + try { + this.playerDao.create(registeredPlayer); + } catch (SQLException e) { + e.printStackTrace(); } + } - if (registeredPlayer == null || registeredPlayer.getHash().isEmpty()) { - // Due to the current connection state, which is set to LOGIN there, we cannot send the packets. - // We need to wait for the PLAY connection state to set. - this.postLoginTasks.put(player.getUniqueId(), () -> { - if (onlineMode) { - if (this.loginPremium != null) { - player.sendMessage(this.loginPremium, MessageType.SYSTEM); - } - if (this.loginPremiumTitle != null) { - player.showTitle(this.loginPremiumTitle); - } - } else { - if (this.loginFloodgate != null) { - player.sendMessage(this.loginFloodgate, MessageType.SYSTEM); - } - if (this.loginFloodgateTitle != null) { - player.showTitle(this.loginFloodgateTitle); - } + if (registeredPlayer == null || registeredPlayer.getHash().isEmpty()) { + // Due to the current connection state, which is set to LOGIN there, we cannot send the packets. + // We need to wait for the PLAY connection state to set. + this.postLoginTasks.put(player.getUniqueId(), () -> { + if (onlineMode) { + if (this.loginPremium != null) { + player.sendMessage(this.loginPremium); + } + if (this.loginPremiumTitle != null) { + player.showTitle(this.loginPremiumTitle); + } + } else { + if (this.loginFloodgate != null) { + player.sendMessage(this.loginFloodgate); + } + if (this.loginFloodgateTitle != null) { + player.showTitle(this.loginFloodgateTitle); } - }); + } + }); - result = TaskEvent.Result.BYPASS; - } + result = TaskEvent.Result.BYPASS; } } + } - EventManager eventManager = this.server.getEventManager(); - if (registeredPlayer == null) { - if (Settings.IMP.MAIN.DISABLE_REGISTRATIONS) { - player.disconnect(this.registrationsDisabledKick); - return; - } - - Consumer<TaskEvent> eventConsumer = (event) -> this.sendPlayer(event, null); - eventManager.fire(new PreRegisterEvent(eventConsumer, result, player)).thenAcceptAsync(eventConsumer); - } else { - Consumer<TaskEvent> eventConsumer = (event) -> this.sendPlayer(event, ((PreAuthorizationEvent) event).getPlayerInfo()); - eventManager.fire(new PreAuthorizationEvent(eventConsumer, result, player, registeredPlayer)).thenAcceptAsync(eventConsumer); + EventManager eventManager = this.server.getEventManager(); + if (registeredPlayer == null) { + if (Settings.IMP.MAIN.DISABLE_REGISTRATIONS) { + player.disconnect(this.registrationsDisabledKick); + return; } + + Consumer<TaskEvent> eventConsumer = (event) -> this.sendPlayer(event, null); + eventManager.fire(new PreRegisterEvent(eventConsumer, result, player)).thenAcceptAsync(eventConsumer); } else { - player.disconnect(this.nicknameInvalidKick); + Consumer<TaskEvent> eventConsumer = (event) -> this.sendPlayer(event, ((PreAuthorizationEvent) event).getPlayerInfo()); + eventManager.fire(new PreAuthorizationEvent(eventConsumer, result, player, registeredPlayer)).thenAcceptAsync(eventConsumer); } } @@ -598,9 +599,8 @@ public class LimboAuth { } } - private boolean validateScheme(String json, List<String> scheme) { + private boolean validateScheme(JsonObject object, List<String> scheme) { if (!scheme.isEmpty()) { - JsonObject object = (JsonObject) JsonParser.parseString(json); for (String field : scheme) { if (!object.has(field)) { return false; @@ -611,16 +611,11 @@ public class LimboAuth { return true; } - public boolean isPremiumExternal(String nickname) { - String lowercaseNickname = nickname.toLowerCase(Locale.ROOT); - if (this.premiumCache.containsKey(lowercaseNickname)) { - return this.premiumCache.get(lowercaseNickname).isPremium(); - } - + public PremiumResponse isPremiumExternal(String nickname) { try { HttpResponse<String> response = this.client.send( HttpRequest.newBuilder() - .uri(URI.create(String.format(Settings.IMP.MAIN.ISPREMIUM_AUTH_URL, URLEncoder.encode(lowercaseNickname, StandardCharsets.UTF_8)))) + .uri(URI.create(String.format(Settings.IMP.MAIN.ISPREMIUM_AUTH_URL, URLEncoder.encode(nickname, StandardCharsets.UTF_8)))) .build(), HttpResponse.BodyHandlers.ofString() ); @@ -628,59 +623,150 @@ public class LimboAuth { int statusCode = response.statusCode(); if (statusCode == Settings.IMP.MAIN.STATUS_CODE_RATE_LIMIT) { - return Settings.IMP.MAIN.ON_RATE_LIMIT_PREMIUM; + return new PremiumResponse(PremiumState.RATE_LIMIT); } + JsonObject jsonObject = (JsonObject) JsonParser.parseString(response.body()); + if (statusCode == Settings.IMP.MAIN.STATUS_CODE_USER_EXISTS - && this.validateScheme(response.body(), Settings.IMP.MAIN.USER_EXISTS_JSON_VALIDATOR_FIELDS)) { - this.premiumCache.put(lowercaseNickname, new CachedPremiumUser(System.currentTimeMillis(), true)); - return true; + && this.validateScheme(jsonObject, Settings.IMP.MAIN.USER_EXISTS_JSON_VALIDATOR_FIELDS)) { + return new PremiumResponse(PremiumState.PREMIUM, jsonObject.get(Settings.IMP.MAIN.JSON_UUID_FIELD).getAsString()); } if (statusCode == Settings.IMP.MAIN.STATUS_CODE_USER_NOT_EXISTS - && this.validateScheme(response.body(), Settings.IMP.MAIN.USER_NOT_EXISTS_JSON_VALIDATOR_FIELDS)) { - this.premiumCache.put(lowercaseNickname, new CachedPremiumUser(System.currentTimeMillis(), false)); - return false; + && this.validateScheme(jsonObject, Settings.IMP.MAIN.USER_NOT_EXISTS_JSON_VALIDATOR_FIELDS)) { + return new PremiumResponse(PremiumState.CRACKED); } - return Settings.IMP.MAIN.ON_SERVER_ERROR_PREMIUM; + return new PremiumResponse(PremiumState.ERROR); } catch (IOException | InterruptedException e) { LOGGER.error("Unable to authenticate with Mojang.", e); + return new PremiumResponse(PremiumState.ERROR); + } + } + + public PremiumResponse isPremiumInternal(String nickname) { + try { + QueryBuilder<RegisteredPlayer, String> crackedCountQuery = this.playerDao.queryBuilder(); + crackedCountQuery.where() + .eq(RegisteredPlayer.LOWERCASE_NICKNAME_FIELD, nickname) + .and() + .ne(RegisteredPlayer.HASH_FIELD, ""); + crackedCountQuery.setCountOf(true); + + QueryBuilder<RegisteredPlayer, String> premiumCountQuery = this.playerDao.queryBuilder(); + premiumCountQuery.where() + .eq(RegisteredPlayer.LOWERCASE_NICKNAME_FIELD, nickname) + .and() + .eq(RegisteredPlayer.HASH_FIELD, ""); + premiumCountQuery.setCountOf(true); + + if (this.playerDao.countOf(crackedCountQuery.prepare()) != 0) { + return new PremiumResponse(PremiumState.CRACKED); + } + + if (this.playerDao.countOf(premiumCountQuery.prepare()) != 0) { + return new PremiumResponse(PremiumState.PREMIUM); + } + + return new PremiumResponse(PremiumState.UNKNOWN); + } catch (SQLException e) { + LOGGER.error("Unable to check if account is premium.", e); + return new PremiumResponse(PremiumState.ERROR); + } + } + + public boolean isPremiumUuid(UUID uuid) { + try { + QueryBuilder<RegisteredPlayer, String> premiumCountQuery = this.playerDao.queryBuilder(); + premiumCountQuery.where() + .eq(RegisteredPlayer.PREMIUM_UUID_FIELD, uuid.toString()) + .and() + .eq(RegisteredPlayer.HASH_FIELD, ""); + premiumCountQuery.setCountOf(true); + + return this.playerDao.countOf(premiumCountQuery.prepare()) != 0; + } catch (SQLException e) { + LOGGER.error("Unable to check if account is premium.", e); + return false; + } + } + + @SafeVarargs + private boolean checkIsPremiumAndCache(String nickname, Function<String, PremiumResponse>... functions) { + String lowercaseNickname = nickname.toLowerCase(Locale.ROOT); + if (this.premiumCache.containsKey(lowercaseNickname)) { + return this.premiumCache.get(lowercaseNickname).isPremium(); + } + + boolean premium = false; + boolean unknown = false; + boolean wasRateLimited = false; + boolean wasError = false; + UUID uuid = null; + + for (Function<String, PremiumResponse> function : functions) { + PremiumResponse check = function.apply(lowercaseNickname); + if (check.getUuid() != null) { + uuid = check.getUuid(); + } + + switch (check.getState()) { + case CRACKED: { + this.premiumCache.put(lowercaseNickname, new CachedPremiumUser(System.currentTimeMillis(), false)); + return false; + } + case PREMIUM: { + premium = true; + break; + } + case UNKNOWN: { + unknown = true; + break; + } + case RATE_LIMIT: { + wasRateLimited = true; + break; + } + default: + case ERROR: { + wasError = true; + break; + } + } + } + + if (wasRateLimited && unknown || wasRateLimited && wasError) { + return Settings.IMP.MAIN.ON_RATE_LIMIT_PREMIUM; + } + + if (wasError && unknown || !premium) { return Settings.IMP.MAIN.ON_SERVER_ERROR_PREMIUM; } + + if (unknown) { + if (uuid != null && this.isPremiumUuid(uuid)) { + this.premiumCache.put(lowercaseNickname, new CachedPremiumUser(System.currentTimeMillis(), true)); + return true; + } + + if (Settings.IMP.MAIN.ONLINE_MODE_NEED_AUTH) { + return false; + } + } + + this.premiumCache.put(lowercaseNickname, new CachedPremiumUser(System.currentTimeMillis(), true)); + return true; } public boolean isPremium(String nickname) { if (Settings.IMP.MAIN.FORCE_OFFLINE_MODE) { return false; } else { - try { - if (this.isPremiumExternal(nickname)) { - QueryBuilder<RegisteredPlayer, String> premiumRegisteredQuery = this.playerDao.queryBuilder(); - premiumRegisteredQuery.where() - .eq("LOWERCASENICKNAME", nickname.toLowerCase(Locale.ROOT)) - .and() - .ne("HASH", ""); - premiumRegisteredQuery.setCountOf(true); - - QueryBuilder<RegisteredPlayer, String> premiumUnregisteredQuery = this.playerDao.queryBuilder(); - premiumUnregisteredQuery.where() - .eq("LOWERCASENICKNAME", nickname.toLowerCase(Locale.ROOT)) - .and() - .eq("HASH", ""); - premiumUnregisteredQuery.setCountOf(true); - - if (Settings.IMP.MAIN.ONLINE_MODE_NEED_AUTH) { - return this.playerDao.countOf(premiumRegisteredQuery.prepare()) == 0 && this.playerDao.countOf(premiumUnregisteredQuery.prepare()) != 0; - } else { - return this.playerDao.countOf(premiumRegisteredQuery.prepare()) == 0; - } - } else { - return false; - } - } catch (Exception e) { - LOGGER.error("Unable to authenticate with Mojang.", e); - return Settings.IMP.MAIN.ON_RATE_LIMIT_PREMIUM; + if (Settings.IMP.MAIN.CHECK_PREMIUM_PRIORITY_INTERNAL) { + return checkIsPremiumAndCache(nickname, this::isPremiumInternal, this::isPremiumExternal); + } else { + return checkIsPremiumAndCache(nickname, this::isPremiumExternal, this::isPremiumInternal); } } } @@ -764,16 +850,57 @@ public class LimboAuth { private static class CachedPremiumUser extends CachedUser { - private final boolean isPremium; + private final boolean premium; - public CachedPremiumUser(long checkTime, boolean isPremium) { + public CachedPremiumUser(long checkTime, boolean premium) { super(checkTime); - this.isPremium = isPremium; + this.premium = premium; } public boolean isPremium() { - return this.isPremium; + return this.premium; + } + } + + public static class PremiumResponse { + + private final PremiumState state; + private final UUID uuid; + + public PremiumResponse(PremiumState state) { + this.state = state; + this.uuid = null; } + + public PremiumResponse(PremiumState state, UUID uuid) { + this.state = state; + this.uuid = uuid; + } + + public PremiumResponse(PremiumState state, String uuid) { + this.state = state; + if (uuid.contains("-")) { + this.uuid = UUID.fromString(uuid); + } else { + this.uuid = new UUID(Long.parseUnsignedLong(uuid.substring(0, 16), 16), Long.parseUnsignedLong(uuid.substring(16), 16)); + } + } + + public PremiumState getState() { + return this.state; + } + + public UUID getUuid() { + return this.uuid; + } + } + + public enum PremiumState { + PREMIUM(), + CRACKED(), + UNKNOWN(), + RATE_LIMIT(), + ERROR() } } diff --git a/src/main/java/net/elytrium/limboauth/Settings.java b/src/main/java/net/elytrium/limboauth/Settings.java index 4a31e9a..f8733ad 100644 --- a/src/main/java/net/elytrium/limboauth/Settings.java +++ b/src/main/java/net/elytrium/limboauth/Settings.java @@ -66,6 +66,8 @@ public class Settings extends YamlConfig { public boolean FORCE_OFFLINE_MODE = false; @Comment("Forces all players to get offline uuid") public boolean FORCE_OFFLINE_UUID = false; + @Comment("If enabled, the plugin will firstly check whether the player is premium through the local database, and secondly through Mojang API.") + public boolean CHECK_PREMIUM_PRIORITY_INTERNAL = true; @Comment("Delay in milliseconds before sending auth-confirming titles and messages to the player. (login-premium-title, login-floodgate, etc.)") public int PREMIUM_AND_FLOODGATE_MESSAGES_DELAY = 1250; @Comment({ @@ -168,6 +170,7 @@ public class Settings extends YamlConfig { "Set this parameter to [], to disable JSON scheme validation" }) public List<String> USER_EXISTS_JSON_VALIDATOR_FIELDS = List.of("name", "id"); + public String JSON_UUID_FIELD = "id"; public List<String> USER_NOT_EXISTS_JSON_VALIDATOR_FIELDS = List.of(); @Comment({ diff --git a/src/main/java/net/elytrium/limboauth/command/ChangePasswordCommand.java b/src/main/java/net/elytrium/limboauth/command/ChangePasswordCommand.java index 53280ec..c58448e 100644 --- a/src/main/java/net/elytrium/limboauth/command/ChangePasswordCommand.java +++ b/src/main/java/net/elytrium/limboauth/command/ChangePasswordCommand.java @@ -29,7 +29,6 @@ import net.elytrium.limboauth.LimboAuth; import net.elytrium.limboauth.Settings; import net.elytrium.limboauth.handler.AuthSessionHandler; import net.elytrium.limboauth.model.RegisteredPlayer; -import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.text.Component; public class ChangePasswordCommand implements SimpleCommand { @@ -69,32 +68,32 @@ public class ChangePasswordCommand implements SimpleCommand { if (this.needOldPass) { RegisteredPlayer player = AuthSessionHandler.fetchInfo(this.playerDao, ((Player) source).getUsername()); if (player == null) { - source.sendMessage(this.notRegistered, MessageType.SYSTEM); + source.sendMessage(this.notRegistered); return; } else if (player.getHash().isEmpty()) { - source.sendMessage(this.crackedCommand, MessageType.SYSTEM); + source.sendMessage(this.crackedCommand); } else if (!AuthSessionHandler.checkPassword(args[0], player, this.playerDao)) { - source.sendMessage(this.wrongPassword, MessageType.SYSTEM); + source.sendMessage(this.wrongPassword); return; } } try { UpdateBuilder<RegisteredPlayer, String> updateBuilder = this.playerDao.updateBuilder(); - updateBuilder.where().eq("NICKNAME", ((Player) source).getUsername()); - updateBuilder.updateColumnValue("HASH", AuthSessionHandler.genHash(this.needOldPass ? args[1] : args[0])); + updateBuilder.where().eq(RegisteredPlayer.NICKNAME_FIELD, ((Player) source).getUsername()); + updateBuilder.updateColumnValue(RegisteredPlayer.HASH_FIELD, AuthSessionHandler.genHash(this.needOldPass ? args[1] : args[0])); updateBuilder.update(); - source.sendMessage(this.successful, MessageType.SYSTEM); + source.sendMessage(this.successful); } catch (SQLException e) { - source.sendMessage(this.errorOccurred, MessageType.SYSTEM); + source.sendMessage(this.errorOccurred); e.printStackTrace(); } } else { - source.sendMessage(this.usage, MessageType.SYSTEM); + source.sendMessage(this.usage); } } else { - source.sendMessage(this.notPlayer, MessageType.SYSTEM); + source.sendMessage(this.notPlayer); } } diff --git a/src/main/java/net/elytrium/limboauth/command/DestroySessionCommand.java b/src/main/java/net/elytrium/limboauth/command/DestroySessionCommand.java index 53f460f..95e002c 100644 --- a/src/main/java/net/elytrium/limboauth/command/DestroySessionCommand.java +++ b/src/main/java/net/elytrium/limboauth/command/DestroySessionCommand.java @@ -24,7 +24,6 @@ import com.velocitypowered.api.proxy.Player; import net.elytrium.java.commons.mc.serialization.Serializer; import net.elytrium.limboauth.LimboAuth; import net.elytrium.limboauth.Settings; -import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.text.Component; public class DestroySessionCommand implements SimpleCommand { @@ -48,9 +47,9 @@ public class DestroySessionCommand implements SimpleCommand { if (source instanceof Player) { this.plugin.removePlayerFromCache(((Player) source).getUsername()); - source.sendMessage(this.successful, MessageType.SYSTEM); + source.sendMessage(this.successful); } else { - source.sendMessage(this.notPlayer, MessageType.SYSTEM); + source.sendMessage(this.notPlayer); } } diff --git a/src/main/java/net/elytrium/limboauth/command/ForceChangePasswordCommand.java b/src/main/java/net/elytrium/limboauth/command/ForceChangePasswordCommand.java index 6704650..1186856 100644 --- a/src/main/java/net/elytrium/limboauth/command/ForceChangePasswordCommand.java +++ b/src/main/java/net/elytrium/limboauth/command/ForceChangePasswordCommand.java @@ -32,7 +32,6 @@ import net.elytrium.limboauth.LimboAuth; import net.elytrium.limboauth.Settings; import net.elytrium.limboauth.handler.AuthSessionHandler; import net.elytrium.limboauth.model.RegisteredPlayer; -import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.text.Component; public class ForceChangePasswordCommand implements SimpleCommand { @@ -72,20 +71,20 @@ public class ForceChangePasswordCommand implements SimpleCommand { Serializer serializer = LimboAuth.getSerializer(); try { UpdateBuilder<RegisteredPlayer, String> updateBuilder = this.playerDao.updateBuilder(); - updateBuilder.where().eq("LOWERCASENICKNAME", nickname.toLowerCase(Locale.ROOT)); - updateBuilder.updateColumnValue("HASH", AuthSessionHandler.genHash(newPassword)); + updateBuilder.where().eq(RegisteredPlayer.LOWERCASE_NICKNAME_FIELD, nickname.toLowerCase(Locale.ROOT)); + updateBuilder.updateColumnValue(RegisteredPlayer.HASH_FIELD, AuthSessionHandler.genHash(newPassword)); updateBuilder.update(); this.server.getPlayer(nickname) - .ifPresent(player -> player.sendMessage(serializer.deserialize(MessageFormat.format(this.message, newPassword)), MessageType.SYSTEM)); + .ifPresent(player -> player.sendMessage(serializer.deserialize(MessageFormat.format(this.message, newPassword)))); - source.sendMessage(serializer.deserialize(MessageFormat.format(this.successful, nickname)), MessageType.SYSTEM); + source.sendMessage(serializer.deserialize(MessageFormat.format(this.successful, nickname))); } catch (SQLException e) { - source.sendMessage(serializer.deserialize(MessageFormat.format(this.notSuccessful, nickname)), MessageType.SYSTEM); + source.sendMessage(serializer.deserialize(MessageFormat.format(this.notSuccessful, nickname))); e.printStackTrace(); } } else { - source.sendMessage(this.usage, MessageType.SYSTEM); + source.sendMessage(this.usage); } } diff --git a/src/main/java/net/elytrium/limboauth/command/ForceUnregisterCommand.java b/src/main/java/net/elytrium/limboauth/command/ForceUnregisterCommand.java index f065d25..2fd12ca 100644 --- a/src/main/java/net/elytrium/limboauth/command/ForceUnregisterCommand.java +++ b/src/main/java/net/elytrium/limboauth/command/ForceUnregisterCommand.java @@ -30,7 +30,6 @@ import net.elytrium.java.commons.mc.velocity.commands.SuggestUtils; import net.elytrium.limboauth.LimboAuth; import net.elytrium.limboauth.Settings; import net.elytrium.limboauth.model.RegisteredPlayer; -import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.text.Component; public class ForceUnregisterCommand implements SimpleCommand { @@ -74,13 +73,13 @@ public class ForceUnregisterCommand implements SimpleCommand { this.playerDao.deleteById(playerNick.toLowerCase(Locale.ROOT)); this.plugin.removePlayerFromCache(playerNick); this.server.getPlayer(playerNick).ifPresent(player -> player.disconnect(this.kick)); - source.sendMessage(serializer.deserialize(MessageFormat.format(this.successful, playerNick)), MessageType.SYSTEM); + source.sendMessage(serializer.deserialize(MessageFormat.format(this.successful, playerNick))); } catch (SQLException e) { - source.sendMessage(serializer.deserialize(MessageFormat.format(this.notSuccessful, playerNick)), MessageType.SYSTEM); + source.sendMessage(serializer.deserialize(MessageFormat.format(this.notSuccessful, playerNick))); e.printStackTrace(); } } else { - source.sendMessage(this.usage, MessageType.SYSTEM); + source.sendMessage(this.usage); } } diff --git a/src/main/java/net/elytrium/limboauth/command/LimboAuthCommand.java b/src/main/java/net/elytrium/limboauth/command/LimboAuthCommand.java index ff31023..6d4a24c 100644 --- a/src/main/java/net/elytrium/limboauth/command/LimboAuthCommand.java +++ b/src/main/java/net/elytrium/limboauth/command/LimboAuthCommand.java @@ -26,7 +26,6 @@ import java.util.stream.Collectors; import net.elytrium.java.commons.mc.serialization.Serializer; import net.elytrium.limboauth.LimboAuth; import net.elytrium.limboauth.Settings; -import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -103,10 +102,10 @@ public class LimboAuthCommand implements SimpleCommand { if (command.equalsIgnoreCase("reload") && source.hasPermission("limboauth.admin.reload")) { try { this.plugin.reload(); - source.sendMessage(serializer.deserialize(Settings.IMP.MAIN.STRINGS.RELOAD), MessageType.SYSTEM); + source.sendMessage(serializer.deserialize(Settings.IMP.MAIN.STRINGS.RELOAD)); } catch (Exception e) { e.printStackTrace(); - source.sendMessage(serializer.deserialize(Settings.IMP.MAIN.STRINGS.RELOAD_FAILED), MessageType.SYSTEM); + source.sendMessage(serializer.deserialize(Settings.IMP.MAIN.STRINGS.RELOAD_FAILED)); } return; @@ -144,16 +143,16 @@ public class LimboAuthCommand implements SimpleCommand { private void showHelp(CommandSource source) { for (Component component : HELP_MESSAGE) { - source.sendMessage(component, MessageType.SYSTEM); + source.sendMessage(component); } List<Map.Entry<String, Component>> availableSubcommands = SUBCOMMANDS.entrySet().stream() .filter(command -> source.hasPermission("limboauth.admin." + command.getKey())) .collect(Collectors.toList()); if (availableSubcommands.size() > 0) { - source.sendMessage(AVAILABLE_SUBCOMMANDS_MESSAGE, MessageType.SYSTEM); - availableSubcommands.forEach(command -> source.sendMessage(command.getValue(), MessageType.SYSTEM)); + source.sendMessage(AVAILABLE_SUBCOMMANDS_MESSAGE); + availableSubcommands.forEach(command -> source.sendMessage(command.getValue())); } else { - source.sendMessage(NO_AVAILABLE_SUBCOMMANDS_MESSAGE, MessageType.SYSTEM); + source.sendMessage(NO_AVAILABLE_SUBCOMMANDS_MESSAGE); } } } diff --git a/src/main/java/net/elytrium/limboauth/command/PremiumCommand.java b/src/main/java/net/elytrium/limboauth/command/PremiumCommand.java index cc73652..f4063d7 100644 --- a/src/main/java/net/elytrium/limboauth/command/PremiumCommand.java +++ b/src/main/java/net/elytrium/limboauth/command/PremiumCommand.java @@ -23,12 +23,12 @@ import com.velocitypowered.api.command.SimpleCommand; import com.velocitypowered.api.permission.Tristate; import com.velocitypowered.api.proxy.Player; import java.sql.SQLException; +import java.util.Locale; import net.elytrium.java.commons.mc.serialization.Serializer; import net.elytrium.limboauth.LimboAuth; import net.elytrium.limboauth.Settings; import net.elytrium.limboauth.handler.AuthSessionHandler; import net.elytrium.limboauth.model.RegisteredPlayer; -import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.text.Component; public class PremiumCommand implements SimpleCommand { @@ -73,34 +73,34 @@ public class PremiumCommand implements SimpleCommand { String username = ((Player) source).getUsername(); RegisteredPlayer player = AuthSessionHandler.fetchInfo(this.playerDao, username); if (player == null) { - source.sendMessage(this.notRegistered, MessageType.SYSTEM); + source.sendMessage(this.notRegistered); } else if (player.getHash().isEmpty()) { - source.sendMessage(this.alreadyPremium, MessageType.SYSTEM); + source.sendMessage(this.alreadyPremium); } else if (AuthSessionHandler.checkPassword(args[0], player, this.playerDao)) { - if (this.plugin.isPremiumExternal(username)) { + if (this.plugin.isPremiumExternal(username.toLowerCase(Locale.ROOT)).getState() == LimboAuth.PremiumState.PREMIUM) { try { player.setHash(""); this.playerDao.update(player); this.plugin.removePlayerFromCache(username); ((Player) source).disconnect(this.successful); } catch (SQLException e) { - source.sendMessage(this.errorOccurred, MessageType.SYSTEM); + source.sendMessage(this.errorOccurred); e.printStackTrace(); } } else { - source.sendMessage(this.notPremium, MessageType.SYSTEM); + source.sendMessage(this.notPremium); } } else { - source.sendMessage(this.wrongPassword, MessageType.SYSTEM); + source.sendMessage(this.wrongPassword); } return; } } - source.sendMessage(this.usage, MessageType.SYSTEM); + source.sendMessage(this.usage); } else { - source.sendMessage(this.notPlayer, MessageType.SYSTEM); + source.sendMessage(this.notPlayer); } } diff --git a/src/main/java/net/elytrium/limboauth/command/TotpCommand.java b/src/main/java/net/elytrium/limboauth/command/TotpCommand.java index 7609020..0ad71f5 100644 --- a/src/main/java/net/elytrium/limboauth/command/TotpCommand.java +++ b/src/main/java/net/elytrium/limboauth/command/TotpCommand.java @@ -36,7 +36,6 @@ import net.elytrium.limboauth.LimboAuth; import net.elytrium.limboauth.Settings; import net.elytrium.limboauth.handler.AuthSessionHandler; import net.elytrium.limboauth.model.RegisteredPlayer; -import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.ClickEvent; @@ -95,7 +94,7 @@ public class TotpCommand implements SimpleCommand { if (source instanceof Player) { if (args.length == 0) { - source.sendMessage(this.usage, MessageType.SYSTEM); + source.sendMessage(this.usage); } else { String username = ((Player) source).getUsername(); @@ -105,32 +104,32 @@ public class TotpCommand implements SimpleCommand { if (this.needPassword ? args.length == 2 : args.length == 1) { playerInfo = AuthSessionHandler.fetchInfo(this.playerDao, username); if (playerInfo == null) { - source.sendMessage(this.notRegistered, MessageType.SYSTEM); + source.sendMessage(this.notRegistered); return; } else if (playerInfo.getHash().isEmpty()) { - source.sendMessage(this.crackedCommand, MessageType.SYSTEM); + source.sendMessage(this.crackedCommand); return; } else if (this.needPassword && !AuthSessionHandler.checkPassword(args[1], playerInfo, this.playerDao)) { - source.sendMessage(this.wrongPassword, MessageType.SYSTEM); + source.sendMessage(this.wrongPassword); return; } if (!playerInfo.getTotpToken().isEmpty()) { - source.sendMessage(this.alreadyEnabled, MessageType.SYSTEM); + source.sendMessage(this.alreadyEnabled); return; } String secret = this.secretGenerator.generate(); try { updateBuilder = this.playerDao.updateBuilder(); - updateBuilder.where().eq("NICKNAME", username); - updateBuilder.updateColumnValue("TOTPTOKEN", secret); + updateBuilder.where().eq(RegisteredPlayer.NICKNAME_FIELD, username); + updateBuilder.updateColumnValue(RegisteredPlayer.TOTP_TOKEN_FIELD, secret); updateBuilder.update(); } catch (SQLException e) { - source.sendMessage(this.errorOccurred, MessageType.SYSTEM); + source.sendMessage(this.errorOccurred); e.printStackTrace(); } - source.sendMessage(this.successful, MessageType.SYSTEM); + source.sendMessage(this.successful); QrData data = new QrData.Builder() .label(username) @@ -138,50 +137,50 @@ public class TotpCommand implements SimpleCommand { .issuer(this.issuer) .build(); String qrUrl = this.qrGeneratorUrl.replace("{data}", URLEncoder.encode(data.getUri(), StandardCharsets.UTF_8)); - source.sendMessage(this.qr.clickEvent(ClickEvent.openUrl(qrUrl)), MessageType.SYSTEM); + source.sendMessage(this.qr.clickEvent(ClickEvent.openUrl(qrUrl))); Serializer serializer = LimboAuth.getSerializer(); source.sendMessage(serializer.deserialize(MessageFormat.format(this.token, secret)) - .clickEvent(ClickEvent.copyToClipboard(secret)), MessageType.SYSTEM); + .clickEvent(ClickEvent.copyToClipboard(secret))); String codes = String.join(", ", this.codesGenerator.generateCodes(this.recoveryCodesAmount)); source.sendMessage(serializer.deserialize(MessageFormat.format(this.recovery, codes)) - .clickEvent(ClickEvent.copyToClipboard(codes)), MessageType.SYSTEM); + .clickEvent(ClickEvent.copyToClipboard(codes))); } else { - source.sendMessage(this.usage, MessageType.SYSTEM); + source.sendMessage(this.usage); } } else if (args[0].equalsIgnoreCase("disable")) { if (args.length == 2) { playerInfo = AuthSessionHandler.fetchInfo(this.playerDao, username); if (playerInfo == null) { - source.sendMessage(this.notRegistered, MessageType.SYSTEM); + source.sendMessage(this.notRegistered); return; } if (AuthSessionHandler.getTotpCodeVerifier().isValidCode(playerInfo.getTotpToken(), args[1])) { try { updateBuilder = this.playerDao.updateBuilder(); - updateBuilder.where().eq("NICKNAME", username); - updateBuilder.updateColumnValue("TOTPTOKEN", ""); + updateBuilder.where().eq(RegisteredPlayer.NICKNAME_FIELD, username); + updateBuilder.updateColumnValue(RegisteredPlayer.TOTP_TOKEN_FIELD, ""); updateBuilder.update(); - source.sendMessage(this.disabled, MessageType.SYSTEM); + source.sendMessage(this.disabled); } catch (SQLException e) { - source.sendMessage(this.errorOccurred, MessageType.SYSTEM); + source.sendMessage(this.errorOccurred); e.printStackTrace(); } } else { - source.sendMessage(this.wrong, MessageType.SYSTEM); + source.sendMessage(this.wrong); } } else { - source.sendMessage(this.usage, MessageType.SYSTEM); + source.sendMessage(this.usage); } } else { - source.sendMessage(this.usage, MessageType.SYSTEM); + source.sendMessage(this.usage); } } } else { - source.sendMessage(this.notPlayer, MessageType.SYSTEM); + source.sendMessage(this.notPlayer); } } diff --git a/src/main/java/net/elytrium/limboauth/command/UnregisterCommand.java b/src/main/java/net/elytrium/limboauth/command/UnregisterCommand.java index b5ab2a0..b6c11ff 100644 --- a/src/main/java/net/elytrium/limboauth/command/UnregisterCommand.java +++ b/src/main/java/net/elytrium/limboauth/command/UnregisterCommand.java @@ -30,7 +30,6 @@ import net.elytrium.limboauth.Settings; import net.elytrium.limboauth.event.AuthUnregisterEvent; import net.elytrium.limboauth.handler.AuthSessionHandler; import net.elytrium.limboauth.model.RegisteredPlayer; -import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.text.Component; public class UnregisterCommand implements SimpleCommand { @@ -73,9 +72,9 @@ public class UnregisterCommand implements SimpleCommand { String username = ((Player) source).getUsername(); RegisteredPlayer player = AuthSessionHandler.fetchInfo(this.playerDao, username); if (player == null) { - source.sendMessage(this.notRegistered, MessageType.SYSTEM); + source.sendMessage(this.notRegistered); } else if (player.getHash().isEmpty()) { - source.sendMessage(this.crackedCommand, MessageType.SYSTEM); + source.sendMessage(this.crackedCommand); } else if (AuthSessionHandler.checkPassword(args[0], player, this.playerDao)) { try { this.plugin.getServer().getEventManager().fireAndForget(new AuthUnregisterEvent(username)); @@ -83,20 +82,20 @@ public class UnregisterCommand implements SimpleCommand { this.plugin.removePlayerFromCache(username); ((Player) source).disconnect(this.successful); } catch (SQLException e) { - source.sendMessage(this.errorOccurred, MessageType.SYSTEM); + source.sendMessage(this.errorOccurred); e.printStackTrace(); } } else { - source.sendMessage(this.wrongPassword, MessageType.SYSTEM); + source.sendMessage(this.wrongPassword); } return; } } - source.sendMessage(this.usage, MessageType.SYSTEM); + source.sendMessage(this.usage); } else { - source.sendMessage(this.notPlayer, MessageType.SYSTEM); + source.sendMessage(this.notPlayer); } } diff --git a/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java b/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java index 6f4b27e..c8e8f89 100644 --- a/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java +++ b/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java @@ -44,7 +44,6 @@ import net.elytrium.limboauth.event.PostRegisterEvent; import net.elytrium.limboauth.event.TaskEvent; import net.elytrium.limboauth.migration.MigrationHash; import net.elytrium.limboauth.model.RegisteredPlayer; -import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.text.Component; import net.kyori.adventure.title.Title; @@ -126,7 +125,7 @@ public class AuthSessionHandler implements LimboSessionHandler { if (this.playerInfo == null) { try { - List<RegisteredPlayer> alreadyRegistered = this.playerDao.queryForEq("IP", this.ip); + List<RegisteredPlayer> alreadyRegistered = this.playerDao.queryForEq(RegisteredPlayer.IP_FIELD, this.ip); if (alreadyRegistered != null) { int sizeOfValidRegistrations = alreadyRegistered.size(); if (Settings.IMP.MAIN.IP_LIMIT_VALID_TIME > 0) { @@ -208,7 +207,7 @@ public class AuthSessionHandler implements LimboSessionHandler { this.proxyPlayer.disconnect(databaseErrorKick); } - this.proxyPlayer.sendMessage(registerSuccessful, MessageType.SYSTEM); + this.proxyPlayer.sendMessage(registerSuccessful); if (registerSuccessfulTitle != null) { this.proxyPlayer.showTitle(registerSuccessfulTitle); } @@ -232,7 +231,7 @@ public class AuthSessionHandler implements LimboSessionHandler { this.sendMessage(true); } } else if (--this.attempts != 0) { - this.proxyPlayer.sendMessage(loginWrongPassword[this.attempts - 1], MessageType.SYSTEM); + this.proxyPlayer.sendMessage(loginWrongPassword[this.attempts - 1]); } else { this.proxyPlayer.disconnect(loginWrongPasswordKick); } @@ -260,17 +259,17 @@ public class AuthSessionHandler implements LimboSessionHandler { private void sendMessage(boolean sendTitle) { if (this.totpState) { - this.proxyPlayer.sendMessage(totp, MessageType.SYSTEM); + this.proxyPlayer.sendMessage(totp); if (sendTitle && totpTitle != null) { this.proxyPlayer.showTitle(totpTitle); } } else if (this.playerInfo == null) { - this.proxyPlayer.sendMessage(register, MessageType.SYSTEM); + this.proxyPlayer.sendMessage(register); if (sendTitle && registerTitle != null) { this.proxyPlayer.showTitle(registerTitle); } } else { - this.proxyPlayer.sendMessage(login[this.attempts - 1], MessageType.SYSTEM); + this.proxyPlayer.sendMessage(login[this.attempts - 1]); if (sendTitle && loginTitle != null) { this.proxyPlayer.showTitle(loginTitle); } @@ -289,7 +288,7 @@ public class AuthSessionHandler implements LimboSessionHandler { if (!Settings.IMP.MAIN.REGISTER_NEED_REPEAT_PASSWORD || args[1].equals(args[2])) { return true; } else { - this.proxyPlayer.sendMessage(registerDifferentPasswords, MessageType.SYSTEM); + this.proxyPlayer.sendMessage(registerDifferentPasswords); return false; } } @@ -297,10 +296,10 @@ public class AuthSessionHandler implements LimboSessionHandler { private boolean checkPasswordLength(String password) { int length = password.length(); if (length > Settings.IMP.MAIN.MAX_PASSWORD_LENGTH) { - this.proxyPlayer.sendMessage(registerPasswordTooLong, MessageType.SYSTEM); + this.proxyPlayer.sendMessage(registerPasswordTooLong); return false; } else if (length < Settings.IMP.MAIN.MIN_PASSWORD_LENGTH) { - this.proxyPlayer.sendMessage(registerPasswordTooShort, MessageType.SYSTEM); + this.proxyPlayer.sendMessage(registerPasswordTooShort); return false; } else { return true; @@ -309,7 +308,7 @@ public class AuthSessionHandler implements LimboSessionHandler { private boolean checkPasswordStrength(String password) { if (Settings.IMP.MAIN.CHECK_PASSWORD_STRENGTH && this.plugin.getUnsafePasswords().contains(password)) { - this.proxyPlayer.sendMessage(registerPasswordUnsafe, MessageType.SYSTEM); + this.proxyPlayer.sendMessage(registerPasswordUnsafe); return false; } else { return true; @@ -317,7 +316,7 @@ public class AuthSessionHandler implements LimboSessionHandler { } private void finishLogin() { - this.proxyPlayer.sendMessage(loginSuccessful, MessageType.SYSTEM); + this.proxyPlayer.sendMessage(loginSuccessful); if (loginSuccessfulTitle != null) { this.proxyPlayer.showTitle(loginSuccessfulTitle); } @@ -447,7 +446,7 @@ public class AuthSessionHandler implements LimboSessionHandler { public static RegisteredPlayer fetchInfo(Dao<RegisteredPlayer, String> playerDao, UUID uuid) { List<RegisteredPlayer> playerList = null; try { - playerList = playerDao.queryForEq("PREMIUMUUID", uuid.toString()); + playerList = playerDao.queryForEq(RegisteredPlayer.PREMIUM_UUID_FIELD, uuid.toString()); } catch (SQLException e) { e.printStackTrace(); } @@ -458,7 +457,7 @@ public class AuthSessionHandler implements LimboSessionHandler { public static RegisteredPlayer fetchInfo(Dao<RegisteredPlayer, String> playerDao, String nickname) { List<RegisteredPlayer> playerList = null; try { - playerList = playerDao.queryForEq("LOWERCASENICKNAME", nickname.toLowerCase(Locale.ROOT)); + playerList = playerDao.queryForEq(RegisteredPlayer.LOWERCASE_NICKNAME_FIELD, nickname.toLowerCase(Locale.ROOT)); } catch (SQLException e) { e.printStackTrace(); } diff --git a/src/main/java/net/elytrium/limboauth/listener/AuthListener.java b/src/main/java/net/elytrium/limboauth/listener/AuthListener.java index 2529e80..a96a88d 100644 --- a/src/main/java/net/elytrium/limboauth/listener/AuthListener.java +++ b/src/main/java/net/elytrium/limboauth/listener/AuthListener.java @@ -76,7 +76,7 @@ public class AuthListener { @Subscribe public void onLoginLimboRegister(LoginLimboRegisterEvent event) { if (this.plugin.needAuth(event.getPlayer())) { - event.addCallback(() -> this.plugin.authPlayer(event.getPlayer())); + event.addOnJoinCallback(() -> this.plugin.authPlayer(event.getPlayer())); } } @@ -109,8 +109,8 @@ public class AuthListener { } else if (event.isOnlineMode()) { try { UpdateBuilder<RegisteredPlayer, String> updateBuilder = this.playerDao.updateBuilder(); - updateBuilder.where().eq("NICKNAME", event.getUsername()); - updateBuilder.updateColumnValue("HASH", ""); + updateBuilder.where().eq(RegisteredPlayer.NICKNAME_FIELD, event.getUsername()); + updateBuilder.updateColumnValue(RegisteredPlayer.HASH_FIELD, ""); updateBuilder.update(); } catch (SQLException e) { e.printStackTrace(); diff --git a/src/main/java/net/elytrium/limboauth/model/RegisteredPlayer.java b/src/main/java/net/elytrium/limboauth/model/RegisteredPlayer.java index b54f9b8..4827d92 100644 --- a/src/main/java/net/elytrium/limboauth/model/RegisteredPlayer.java +++ b/src/main/java/net/elytrium/limboauth/model/RegisteredPlayer.java @@ -23,28 +23,37 @@ import com.j256.ormlite.table.DatabaseTable; @DatabaseTable(tableName = "AUTH") public class RegisteredPlayer { - @DatabaseField(canBeNull = false, columnName = "NICKNAME") + public static final String NICKNAME_FIELD = "NICKNAME"; + public static final String LOWERCASE_NICKNAME_FIELD = "LOWERCASENICKNAME"; + public static final String HASH_FIELD = "HASH"; + public static final String IP_FIELD = "IP"; + public static final String TOTP_TOKEN_FIELD = "TOTPTOKEN"; + public static final String REG_DATE_FIELD = "REGDATE"; + public static final String UUID_FIELD = "UUID"; + public static final String PREMIUM_UUID_FIELD = "PREMIUMUUID"; + + @DatabaseField(canBeNull = false, columnName = NICKNAME_FIELD) private String nickname; - @DatabaseField(id = true, columnName = "LOWERCASENICKNAME") + @DatabaseField(id = true, columnName = LOWERCASE_NICKNAME_FIELD) private String lowercaseNickname; - @DatabaseField(canBeNull = false, columnName = "HASH") + @DatabaseField(canBeNull = false, columnName = HASH_FIELD) private String hash; - @DatabaseField(columnName = "IP") + @DatabaseField(columnName = IP_FIELD) private String ip; - @DatabaseField(columnName = "TOTPTOKEN") + @DatabaseField(columnName = TOTP_TOKEN_FIELD) private String totpToken; - @DatabaseField(columnName = "REGDATE") + @DatabaseField(columnName = REG_DATE_FIELD) private Long regDate; - @DatabaseField(columnName = "UUID") + @DatabaseField(columnName = UUID_FIELD) private String uuid; - @DatabaseField(columnName = "PREMIUMUUID") + @DatabaseField(columnName = RegisteredPlayer.PREMIUM_UUID_FIELD) private String premiumUuid; public RegisteredPlayer(String nickname, String lowercaseNickname, |