limboPlayer = getLimboOrLogError(player, "reset tasks");
limboPlayer.ifPresent(limbo -> {
- taskManager.registerTimeoutTask(player, limbo);
+ taskManager.registerTimeoutTask(player, limbo, LimboMessageType.LOG_IN);
taskManager.registerMessageTask(player, limbo, LimboMessageType.LOG_IN);
});
authGroupHandler.setGroup(player, limboPlayer.orElse(null), AuthGroupType.REGISTERED_UNAUTHENTICATED);
@@ -294,4 +311,4 @@ public void restoreEntities(Player player) {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/fr/xephi/authme/data/limbo/LimboServiceHelper.java b/authme-core/src/main/java/fr/xephi/authme/data/limbo/LimboServiceHelper.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/data/limbo/LimboServiceHelper.java
rename to authme-core/src/main/java/fr/xephi/authme/data/limbo/LimboServiceHelper.java
diff --git a/src/main/java/fr/xephi/authme/data/limbo/UserGroup.java b/authme-core/src/main/java/fr/xephi/authme/data/limbo/UserGroup.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/data/limbo/UserGroup.java
rename to authme-core/src/main/java/fr/xephi/authme/data/limbo/UserGroup.java
diff --git a/src/main/java/fr/xephi/authme/data/limbo/WalkFlySpeedRestoreType.java b/authme-core/src/main/java/fr/xephi/authme/data/limbo/WalkFlySpeedRestoreType.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/data/limbo/WalkFlySpeedRestoreType.java
rename to authme-core/src/main/java/fr/xephi/authme/data/limbo/WalkFlySpeedRestoreType.java
diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/DistributedFilesPersistenceHandler.java b/authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/DistributedFilesPersistenceHandler.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/data/limbo/persistence/DistributedFilesPersistenceHandler.java
rename to authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/DistributedFilesPersistenceHandler.java
diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/IndividualFilesPersistenceHandler.java b/authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/IndividualFilesPersistenceHandler.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/data/limbo/persistence/IndividualFilesPersistenceHandler.java
rename to authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/IndividualFilesPersistenceHandler.java
diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPersistence.java b/authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPersistence.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPersistence.java
rename to authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPersistence.java
diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPersistenceHandler.java b/authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPersistenceHandler.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPersistenceHandler.java
rename to authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPersistenceHandler.java
diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPersistenceType.java b/authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPersistenceType.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPersistenceType.java
rename to authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPersistenceType.java
diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPlayerDeserializer.java b/authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPlayerDeserializer.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPlayerDeserializer.java
rename to authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPlayerDeserializer.java
diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPlayerSerializer.java b/authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPlayerSerializer.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPlayerSerializer.java
rename to authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/LimboPlayerSerializer.java
diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/NoOpPersistenceHandler.java b/authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/NoOpPersistenceHandler.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/data/limbo/persistence/NoOpPersistenceHandler.java
rename to authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/NoOpPersistenceHandler.java
diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/SegmentNameBuilder.java b/authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/SegmentNameBuilder.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/data/limbo/persistence/SegmentNameBuilder.java
rename to authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/SegmentNameBuilder.java
diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/SegmentSize.java b/authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/SegmentSize.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/data/limbo/persistence/SegmentSize.java
rename to authme-core/src/main/java/fr/xephi/authme/data/limbo/persistence/SegmentSize.java
diff --git a/src/main/java/fr/xephi/authme/datasource/AbstractSqlDataSource.java b/authme-core/src/main/java/fr/xephi/authme/datasource/AbstractSqlDataSource.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/AbstractSqlDataSource.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/AbstractSqlDataSource.java
diff --git a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java b/authme-core/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/CacheDataSource.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java
diff --git a/src/main/java/fr/xephi/authme/datasource/Columns.java b/authme-core/src/main/java/fr/xephi/authme/datasource/Columns.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/Columns.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/Columns.java
diff --git a/src/main/java/fr/xephi/authme/datasource/DataSource.java b/authme-core/src/main/java/fr/xephi/authme/datasource/DataSource.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/DataSource.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/DataSource.java
diff --git a/src/main/java/fr/xephi/authme/datasource/DataSourceType.java b/authme-core/src/main/java/fr/xephi/authme/datasource/DataSourceType.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/DataSourceType.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/DataSourceType.java
diff --git a/src/main/java/fr/xephi/authme/datasource/MariaDB.java b/authme-core/src/main/java/fr/xephi/authme/datasource/MariaDB.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/MariaDB.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/MariaDB.java
diff --git a/src/main/java/fr/xephi/authme/datasource/MySQL.java b/authme-core/src/main/java/fr/xephi/authme/datasource/MySQL.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/MySQL.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/MySQL.java
diff --git a/src/main/java/fr/xephi/authme/datasource/MySqlMigrater.java b/authme-core/src/main/java/fr/xephi/authme/datasource/MySqlMigrater.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/MySqlMigrater.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/MySqlMigrater.java
diff --git a/src/main/java/fr/xephi/authme/datasource/PostgreSqlDataSource.java b/authme-core/src/main/java/fr/xephi/authme/datasource/PostgreSqlDataSource.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/PostgreSqlDataSource.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/PostgreSqlDataSource.java
diff --git a/src/main/java/fr/xephi/authme/datasource/SQLite.java b/authme-core/src/main/java/fr/xephi/authme/datasource/SQLite.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/SQLite.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/SQLite.java
diff --git a/src/main/java/fr/xephi/authme/datasource/SqLiteMigrater.java b/authme-core/src/main/java/fr/xephi/authme/datasource/SqLiteMigrater.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/SqLiteMigrater.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/SqLiteMigrater.java
diff --git a/src/main/java/fr/xephi/authme/datasource/SqlDataSourceUtils.java b/authme-core/src/main/java/fr/xephi/authme/datasource/SqlDataSourceUtils.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/SqlDataSourceUtils.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/SqlDataSourceUtils.java
diff --git a/src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumns.java b/authme-core/src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumns.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumns.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumns.java
diff --git a/src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumnsFactory.java b/authme-core/src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumnsFactory.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumnsFactory.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumnsFactory.java
diff --git a/src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumnsHandler.java b/authme-core/src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumnsHandler.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumnsHandler.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/columnshandler/AuthMeColumnsHandler.java
diff --git a/src/main/java/fr/xephi/authme/datasource/columnshandler/ColumnContext.java b/authme-core/src/main/java/fr/xephi/authme/datasource/columnshandler/ColumnContext.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/columnshandler/ColumnContext.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/columnshandler/ColumnContext.java
diff --git a/src/main/java/fr/xephi/authme/datasource/columnshandler/DataSourceColumn.java b/authme-core/src/main/java/fr/xephi/authme/datasource/columnshandler/DataSourceColumn.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/columnshandler/DataSourceColumn.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/columnshandler/DataSourceColumn.java
diff --git a/src/main/java/fr/xephi/authme/datasource/columnshandler/PlayerAuthColumn.java b/authme-core/src/main/java/fr/xephi/authme/datasource/columnshandler/PlayerAuthColumn.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/columnshandler/PlayerAuthColumn.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/columnshandler/PlayerAuthColumn.java
diff --git a/src/main/java/fr/xephi/authme/datasource/converter/AbstractDataSourceConverter.java b/authme-core/src/main/java/fr/xephi/authme/datasource/converter/AbstractDataSourceConverter.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/converter/AbstractDataSourceConverter.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/converter/AbstractDataSourceConverter.java
diff --git a/authme-core/src/main/java/fr/xephi/authme/datasource/converter/AuthPlusConverter.java b/authme-core/src/main/java/fr/xephi/authme/datasource/converter/AuthPlusConverter.java
new file mode 100644
index 0000000000..e2dcd31843
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/datasource/converter/AuthPlusConverter.java
@@ -0,0 +1,105 @@
+package fr.xephi.authme.datasource.converter;
+
+import fr.xephi.authme.ConsoleLogger;
+import fr.xephi.authme.data.auth.PlayerAuth;
+import fr.xephi.authme.datasource.DataSource;
+import fr.xephi.authme.initialization.DataFolder;
+import fr.xephi.authme.output.ConsoleLoggerFactory;
+import org.bukkit.Bukkit;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import javax.inject.Inject;
+import java.io.File;
+import java.util.Locale;
+import java.util.Set;
+import java.util.UUID;
+
+import static fr.xephi.authme.util.Utils.logAndSendMessage;
+
+/**
+ * Converts data from Auth+ to AuthMe.
+ *
+ * Auth+ stores accounts in {@code plugins/Auth/players.yml} as UUID keys with a nested {@code hash} field
+ * using PBKDF2-HmacSHA256 (Base64-encoded salt and hash). Set {@code passwordHash: PBKDF2BASE64} in
+ * AuthMe's config before running this converter.
+ */
+public class AuthPlusConverter implements Converter {
+
+ private final ConsoleLogger logger = ConsoleLoggerFactory.get(AuthPlusConverter.class);
+ private final DataSource dataSource;
+ private final File authPlusFile;
+
+ @Inject
+ AuthPlusConverter(@DataFolder File dataFolder, DataSource dataSource) {
+ this.dataSource = dataSource;
+ this.authPlusFile = new File(dataFolder.getParentFile(), "Auth/players.yml");
+ }
+
+ @Override
+ public void execute(CommandSender sender) {
+ if (!authPlusFile.exists()) {
+ sender.sendMessage("The file '" + authPlusFile.getPath() + "' does not exist");
+ return;
+ }
+
+ YamlConfiguration config = YamlConfiguration.loadConfiguration(authPlusFile);
+ Set keys = config.getKeys(false);
+
+ long successCount = 0;
+ long skippedCount = 0;
+ for (String uuidStr : keys) {
+ String hash = config.getString(uuidStr + ".hash");
+ if (hash == null || hash.isEmpty()) {
+ logger.warning("No hash found for UUID '" + uuidStr + "', skipping");
+ continue;
+ }
+
+ UUID uuid;
+ try {
+ uuid = UUID.fromString(uuidStr);
+ } catch (IllegalArgumentException e) {
+ logger.warning("Invalid UUID '" + uuidStr + "', skipping");
+ continue;
+ }
+
+ String name = resolveName(uuid);
+ if (name == null) {
+ logger.warning("Could not resolve name for UUID '" + uuidStr + "', skipping");
+ continue;
+ }
+
+ String lowercaseName = name.toLowerCase(Locale.ROOT);
+ if (dataSource.isAuthAvailable(lowercaseName)) {
+ ++skippedCount;
+ continue;
+ }
+
+ PlayerAuth auth = PlayerAuth.builder()
+ .name(lowercaseName)
+ .realName(name)
+ .uuid(uuid)
+ .password(hash, null)
+ .build();
+ dataSource.saveAuth(auth);
+ ++successCount;
+ }
+
+ logAndSendMessage(sender, "Auth+ conversion: " + successCount + " account(s) imported, "
+ + skippedCount + " skipped (already exist)");
+ }
+
+ private String resolveName(UUID uuid) {
+ try {
+ return Bukkit.getOfflinePlayer(uuid).getName();
+ } catch (Exception | NoSuchMethodError e) {
+ for (OfflinePlayer op : Bukkit.getOfflinePlayers()) {
+ if (uuid.equals(op.getUniqueId())) {
+ return op.getName();
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/datasource/converter/Converter.java b/authme-core/src/main/java/fr/xephi/authme/datasource/converter/Converter.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/converter/Converter.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/converter/Converter.java
diff --git a/src/main/java/fr/xephi/authme/datasource/converter/CrazyLoginConverter.java b/authme-core/src/main/java/fr/xephi/authme/datasource/converter/CrazyLoginConverter.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/converter/CrazyLoginConverter.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/converter/CrazyLoginConverter.java
diff --git a/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java b/authme-core/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java
diff --git a/src/main/java/fr/xephi/authme/datasource/converter/MySqlToSqlite.java b/authme-core/src/main/java/fr/xephi/authme/datasource/converter/MySqlToSqlite.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/converter/MySqlToSqlite.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/converter/MySqlToSqlite.java
diff --git a/src/main/java/fr/xephi/authme/datasource/converter/RakamakConverter.java b/authme-core/src/main/java/fr/xephi/authme/datasource/converter/RakamakConverter.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/converter/RakamakConverter.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/converter/RakamakConverter.java
diff --git a/src/main/java/fr/xephi/authme/datasource/converter/RoyalAuthConverter.java b/authme-core/src/main/java/fr/xephi/authme/datasource/converter/RoyalAuthConverter.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/converter/RoyalAuthConverter.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/converter/RoyalAuthConverter.java
diff --git a/src/main/java/fr/xephi/authme/datasource/converter/SqliteToSql.java b/authme-core/src/main/java/fr/xephi/authme/datasource/converter/SqliteToSql.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/converter/SqliteToSql.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/converter/SqliteToSql.java
diff --git a/src/main/java/fr/xephi/authme/datasource/converter/VAuthConverter.java b/authme-core/src/main/java/fr/xephi/authme/datasource/converter/VAuthConverter.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/converter/VAuthConverter.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/converter/VAuthConverter.java
diff --git a/src/main/java/fr/xephi/authme/datasource/mysqlextensions/Ipb4Extension.java b/authme-core/src/main/java/fr/xephi/authme/datasource/mysqlextensions/Ipb4Extension.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/mysqlextensions/Ipb4Extension.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/mysqlextensions/Ipb4Extension.java
diff --git a/src/main/java/fr/xephi/authme/datasource/mysqlextensions/MySqlExtension.java b/authme-core/src/main/java/fr/xephi/authme/datasource/mysqlextensions/MySqlExtension.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/mysqlextensions/MySqlExtension.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/mysqlextensions/MySqlExtension.java
diff --git a/src/main/java/fr/xephi/authme/datasource/mysqlextensions/MySqlExtensionsFactory.java b/authme-core/src/main/java/fr/xephi/authme/datasource/mysqlextensions/MySqlExtensionsFactory.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/mysqlextensions/MySqlExtensionsFactory.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/mysqlextensions/MySqlExtensionsFactory.java
diff --git a/src/main/java/fr/xephi/authme/datasource/mysqlextensions/NoOpExtension.java b/authme-core/src/main/java/fr/xephi/authme/datasource/mysqlextensions/NoOpExtension.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/mysqlextensions/NoOpExtension.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/mysqlextensions/NoOpExtension.java
diff --git a/src/main/java/fr/xephi/authme/datasource/mysqlextensions/PhpBbExtension.java b/authme-core/src/main/java/fr/xephi/authme/datasource/mysqlextensions/PhpBbExtension.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/mysqlextensions/PhpBbExtension.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/mysqlextensions/PhpBbExtension.java
diff --git a/src/main/java/fr/xephi/authme/datasource/mysqlextensions/WordpressExtension.java b/authme-core/src/main/java/fr/xephi/authme/datasource/mysqlextensions/WordpressExtension.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/mysqlextensions/WordpressExtension.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/mysqlextensions/WordpressExtension.java
diff --git a/src/main/java/fr/xephi/authme/datasource/mysqlextensions/XfBcryptExtension.java b/authme-core/src/main/java/fr/xephi/authme/datasource/mysqlextensions/XfBcryptExtension.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/datasource/mysqlextensions/XfBcryptExtension.java
rename to authme-core/src/main/java/fr/xephi/authme/datasource/mysqlextensions/XfBcryptExtension.java
diff --git a/src/main/java/fr/xephi/authme/events/AbstractTeleportEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/AbstractTeleportEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/AbstractTeleportEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/AbstractTeleportEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/AbstractUnregisterEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/AbstractUnregisterEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/AbstractUnregisterEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/AbstractUnregisterEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreRegisterEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreRegisterEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/AuthMeAsyncPreRegisterEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreRegisterEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/AuthMeTeleportEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/AuthMeTeleportEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/AuthMeTeleportEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/AuthMeTeleportEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/CustomEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/CustomEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/CustomEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/CustomEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/EmailChangedEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/EmailChangedEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/EmailChangedEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/EmailChangedEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/FailedLoginEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/FailedLoginEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/FailedLoginEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/FailedLoginEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/FirstSpawnTeleportEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/FirstSpawnTeleportEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/FirstSpawnTeleportEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/FirstSpawnTeleportEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/LoginEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/LoginEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/LoginEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/LoginEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/LogoutEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/LogoutEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/LogoutEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/LogoutEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/PasswordEncryptionEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/PasswordEncryptionEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/PasswordEncryptionEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/PasswordEncryptionEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/ProtectInventoryEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/ProtectInventoryEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/ProtectInventoryEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/ProtectInventoryEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/RegisterEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/RegisterEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/RegisterEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/RegisterEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/RestoreInventoryEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/RestoreInventoryEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/RestoreInventoryEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/RestoreInventoryEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/RestoreSessionEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/RestoreSessionEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/RestoreSessionEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/RestoreSessionEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/SpawnTeleportEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/SpawnTeleportEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/SpawnTeleportEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/SpawnTeleportEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/UnregisterByAdminEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/UnregisterByAdminEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/UnregisterByAdminEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/UnregisterByAdminEvent.java
diff --git a/src/main/java/fr/xephi/authme/events/UnregisterByPlayerEvent.java b/authme-core/src/main/java/fr/xephi/authme/events/UnregisterByPlayerEvent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/events/UnregisterByPlayerEvent.java
rename to authme-core/src/main/java/fr/xephi/authme/events/UnregisterByPlayerEvent.java
diff --git a/src/main/java/fr/xephi/authme/initialization/DataFolder.java b/authme-core/src/main/java/fr/xephi/authme/initialization/DataFolder.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/initialization/DataFolder.java
rename to authme-core/src/main/java/fr/xephi/authme/initialization/DataFolder.java
diff --git a/src/main/java/fr/xephi/authme/initialization/DataSourceProvider.java b/authme-core/src/main/java/fr/xephi/authme/initialization/DataSourceProvider.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/initialization/DataSourceProvider.java
rename to authme-core/src/main/java/fr/xephi/authme/initialization/DataSourceProvider.java
diff --git a/src/main/java/fr/xephi/authme/initialization/HasCleanup.java b/authme-core/src/main/java/fr/xephi/authme/initialization/HasCleanup.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/initialization/HasCleanup.java
rename to authme-core/src/main/java/fr/xephi/authme/initialization/HasCleanup.java
diff --git a/src/main/java/fr/xephi/authme/initialization/OnShutdownPlayerSaver.java b/authme-core/src/main/java/fr/xephi/authme/initialization/OnShutdownPlayerSaver.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/initialization/OnShutdownPlayerSaver.java
rename to authme-core/src/main/java/fr/xephi/authme/initialization/OnShutdownPlayerSaver.java
diff --git a/src/main/java/fr/xephi/authme/initialization/OnStartupTasks.java b/authme-core/src/main/java/fr/xephi/authme/initialization/OnStartupTasks.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/initialization/OnStartupTasks.java
rename to authme-core/src/main/java/fr/xephi/authme/initialization/OnStartupTasks.java
diff --git a/src/main/java/fr/xephi/authme/initialization/Reloadable.java b/authme-core/src/main/java/fr/xephi/authme/initialization/Reloadable.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/initialization/Reloadable.java
rename to authme-core/src/main/java/fr/xephi/authme/initialization/Reloadable.java
diff --git a/src/main/java/fr/xephi/authme/initialization/SettingsDependent.java b/authme-core/src/main/java/fr/xephi/authme/initialization/SettingsDependent.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/initialization/SettingsDependent.java
rename to authme-core/src/main/java/fr/xephi/authme/initialization/SettingsDependent.java
diff --git a/src/main/java/fr/xephi/authme/initialization/SettingsProvider.java b/authme-core/src/main/java/fr/xephi/authme/initialization/SettingsProvider.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/initialization/SettingsProvider.java
rename to authme-core/src/main/java/fr/xephi/authme/initialization/SettingsProvider.java
diff --git a/src/main/java/fr/xephi/authme/initialization/TaskCloser.java b/authme-core/src/main/java/fr/xephi/authme/initialization/TaskCloser.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/initialization/TaskCloser.java
rename to authme-core/src/main/java/fr/xephi/authme/initialization/TaskCloser.java
diff --git a/src/main/java/fr/xephi/authme/listener/BlockListener.java b/authme-core/src/main/java/fr/xephi/authme/listener/BlockListener.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/listener/BlockListener.java
rename to authme-core/src/main/java/fr/xephi/authme/listener/BlockListener.java
diff --git a/src/main/java/fr/xephi/authme/listener/EntityListener.java b/authme-core/src/main/java/fr/xephi/authme/listener/EntityListener.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/listener/EntityListener.java
rename to authme-core/src/main/java/fr/xephi/authme/listener/EntityListener.java
diff --git a/src/main/java/fr/xephi/authme/listener/FailedVerificationException.java b/authme-core/src/main/java/fr/xephi/authme/listener/FailedVerificationException.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/listener/FailedVerificationException.java
rename to authme-core/src/main/java/fr/xephi/authme/listener/FailedVerificationException.java
diff --git a/src/main/java/fr/xephi/authme/listener/ListenerService.java b/authme-core/src/main/java/fr/xephi/authme/listener/ListenerService.java
similarity index 98%
rename from src/main/java/fr/xephi/authme/listener/ListenerService.java
rename to authme-core/src/main/java/fr/xephi/authme/listener/ListenerService.java
index d283f3e4e5..0ace8ebd78 100644
--- a/src/main/java/fr/xephi/authme/listener/ListenerService.java
+++ b/authme-core/src/main/java/fr/xephi/authme/listener/ListenerService.java
@@ -17,7 +17,7 @@
/**
* Service class for the AuthMe listeners to determine whether an event should be canceled.
*/
-class ListenerService implements SettingsDependent {
+public class ListenerService implements SettingsDependent {
private final DataSource dataSource;
private final PlayerCache playerCache;
diff --git a/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java b/authme-core/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java
similarity index 88%
rename from src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java
rename to authme-core/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java
index 7ed12f31e8..bec01cde82 100644
--- a/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java
+++ b/authme-core/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java
@@ -80,7 +80,7 @@ public void checkNameRestrictions(String name, InetAddress address) throws Faile
if (!validationService.fulfillsNameRestrictions(name, address)) {
if (settings.getProperty(RestrictionSettings.BAN_UNKNOWN_IP)) {
String ip = address.getHostAddress();
- bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> server.banIP(ip));
+ bukkitService.runOnGlobalRegion(() -> server.banIP(ip));
}
throw new FailedVerificationException(MessageKey.NOT_OWNER_ERROR);
}
@@ -142,32 +142,47 @@ public void checkIsValidName(String name) throws FailedVerificationException {
* further), false if the player is not refused
*/
public boolean refusePlayerForFullServer(PlayerLoginEvent event) {
- final Player player = event.getPlayer();
if (event.getResult() != PlayerLoginEvent.Result.KICK_FULL) {
// Server is not full, no need to do anything
return false;
- } else if (!permissionsManager.hasPermission(player, PlayerStatePermission.IS_VIP)) {
- // Server is full and player is NOT VIP; set kick message and proceed with kick
- event.setKickMessage(messages.retrieveSingle(player, MessageKey.KICK_FULL_SERVER));
- return true;
}
- // Server is full and player is VIP; attempt to kick a non-VIP player to make room
- Collection onlinePlayers = bukkitService.getOnlinePlayers();
- if (onlinePlayers.size() < server.getMaxPlayers()) {
+ String kickMessage = getServerFullKickMessageIfDenied(event.getPlayer().getName());
+ if (kickMessage == null) {
event.allow();
return false;
}
+
+ event.setKickMessage(kickMessage);
+ return true;
+ }
+
+ /**
+ * Handles the case of a full server for the given player name. If the user may join, {@code null}
+ * is returned and the caller should allow the connection. Otherwise the returned message should be
+ * used as the kick reason.
+ *
+ * @param playerName the joining player name
+ * @return the kick message if access should be denied, or null if the player may join
+ */
+ public String getServerFullKickMessageIfDenied(String playerName) {
+ if (!permissionsManager.hasPermissionOffline(playerName, PlayerStatePermission.IS_VIP)) {
+ return messages.retrieveSingle(playerName, MessageKey.KICK_FULL_SERVER);
+ }
+
+ Collection onlinePlayers = bukkitService.getOnlinePlayers();
+ if (onlinePlayers.size() < server.getMaxPlayers()) {
+ return null;
+ }
+
Player nonVipPlayer = generateKickPlayer(onlinePlayers);
if (nonVipPlayer != null) {
- nonVipPlayer.kickPlayer(messages.retrieveSingle(player, MessageKey.KICK_FOR_VIP));
- event.allow();
- return false;
- } else {
- logger.info("VIP player " + player.getName() + " tried to join, but the server was full");
- event.setKickMessage(messages.retrieveSingle(player, MessageKey.KICK_FULL_SERVER));
- return true;
+ nonVipPlayer.kickPlayer(messages.retrieveSingle(playerName, MessageKey.KICK_FOR_VIP));
+ return null;
}
+
+ logger.info("VIP player " + playerName + " tried to join, but the server was full");
+ return messages.retrieveSingle(playerName, MessageKey.KICK_FULL_SERVER);
}
/**
diff --git a/src/main/java/fr/xephi/authme/listener/PlayerListener.java b/authme-core/src/main/java/fr/xephi/authme/listener/PlayerListener.java
similarity index 87%
rename from src/main/java/fr/xephi/authme/listener/PlayerListener.java
rename to authme-core/src/main/java/fr/xephi/authme/listener/PlayerListener.java
index d9b1c70a0d..4a461ad847 100644
--- a/src/main/java/fr/xephi/authme/listener/PlayerListener.java
+++ b/authme-core/src/main/java/fr/xephi/authme/listener/PlayerListener.java
@@ -15,6 +15,9 @@
import fr.xephi.authme.service.TeleportationService;
import fr.xephi.authme.service.ValidationService;
import fr.xephi.authme.settings.Settings;
+import fr.xephi.authme.platform.ChatAdapter;
+import fr.xephi.authme.platform.PlatformAdapter;
+import fr.xephi.authme.platform.TeleportAdapter;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
@@ -29,6 +32,7 @@
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.SignChangeEvent;
+import org.bukkit.event.entity.EntityAirChangeEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
@@ -48,11 +52,13 @@
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerMoveEvent;
-import org.bukkit.event.player.PlayerPickupItemEvent;
+import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerShearEntityEvent;
+import org.bukkit.event.player.PlayerSwapHandItemsEvent;
import org.bukkit.inventory.InventoryView;
+import org.spigotmc.event.player.PlayerSpawnLocationEvent;
import javax.inject.Inject;
import java.util.Locale;
@@ -98,6 +104,12 @@ public class PlayerListener implements Listener {
private QuickCommandsProtectionManager quickCommandsProtectionManager;
@Inject
private LimboService limboService;
+ @Inject
+ private ChatAdapter chatAdapter;
+ @Inject
+ private TeleportAdapter teleportAdapter;
+ @Inject
+ private PlatformAdapter platformAdapter;
// Lowest priority to apply fast protection checks
@EventHandler(priority = EventPriority.LOWEST)
@@ -167,6 +179,10 @@ public void onAsyncPlayerPreLoginEventHighest(AsyncPlayerPreLoginEvent event) {
@EventHandler(priority = EventPriority.LOW)
public void onPlayerLogin(PlayerLoginEvent event) {
+ if (!platformAdapter.shouldHandlePlayerLoginEvent()) {
+ return;
+ }
+
final Player player = event.getPlayer();
final String name = player.getName();
@@ -189,7 +205,7 @@ public void onPlayerLogin(PlayerLoginEvent event) {
public void onPlayerJoin(PlayerJoinEvent event) {
final Player player = event.getPlayer();
- if (!PlayerListener19Spigot.isPlayerSpawnLocationEventCalled()) {
+ if (!SpawnLocationTracker.isEventCalled()) {
teleportationService.teleportOnJoin(player);
}
@@ -202,6 +218,21 @@ public void onPlayerJoin(PlayerJoinEvent event) {
teleportationService.teleportNewPlayerToFirstSpawn(player);
}
+ @EventHandler(priority = EventPriority.HIGH)
+ public void onPlayerSpawn(PlayerSpawnLocationEvent event) {
+ if (!platformAdapter.shouldHandlePlayerSpawnLocationEvent()) {
+ return;
+ }
+
+ SpawnLocationTracker.markEventCalled();
+ final Player player = event.getPlayer();
+
+ Location customSpawnLocation = teleportationService.prepareOnJoinSpawnLocation(player, event.getSpawnLocation());
+ if (customSpawnLocation != null) {
+ event.setSpawnLocation(customSpawnLocation);
+ }
+ }
+
@EventHandler(priority = EventPriority.HIGH) // HIGH as EssentialsX listens at HIGHEST
public void onJoinMessage(PlayerJoinEvent event) {
final Player player = event.getPlayer();
@@ -285,7 +316,7 @@ public void onPlayerKick(PlayerKickEvent event) {
// Note #831: Especially for offline CraftBukkit, we need to catch players being kicked because of
// "logged in from another location" and to cancel their kick
if (settings.getProperty(RestrictionSettings.FORCE_SINGLE_SESSION)
- && event.getReason().contains("You logged in from another location")) {
+ && chatAdapter.getKickReason(event).contains("You logged in from another location")) {
event.setCancelled(true);
return;
}
@@ -392,25 +423,28 @@ public void onPlayerMove(PlayerMoveEvent event) {
Location spawn = spawnLoader.getSpawnLocation(player);
if (spawn != null && spawn.getWorld() != null) {
if (!player.getWorld().equals(spawn.getWorld())) {
- player.teleport(spawn);
+ teleportAdapter.teleportPlayer(player, spawn);
} else if (spawn.distance(player.getLocation()) > settings.getProperty(ALLOWED_MOVEMENT_RADIUS)) {
- player.teleport(spawn);
+ teleportAdapter.teleportPlayer(player, spawn);
}
}
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerRespawn(PlayerRespawnEvent event) {
- if (settings.getProperty(RestrictionSettings.NO_TELEPORT)) {
- return;
- }
+ Player player = event.getPlayer();
if (!listenerService.shouldCancelEvent(event)) {
return;
}
- Location spawn = spawnLoader.getSpawnLocation(event.getPlayer());
- if (spawn != null && spawn.getWorld() != null) {
- event.setRespawnLocation(spawn);
+ if (!settings.getProperty(RestrictionSettings.NO_TELEPORT)) {
+ Location spawn = spawnLoader.getPlayerRespawnLocationOrSpawn(player);
+ if (spawn != null && spawn.getWorld() != null) {
+ event.setRespawnLocation(spawn);
+ }
}
+ // Bukkit sends a fresh PlayerAbilities packet on respawn that resets walk/fly speed,
+ // overriding the restriction set during join. Re-apply one tick later.
+ bukkitService.runTaskLater(player, () -> limboService.reapplyLimboRestrictions(player), 1L);
}
/*
@@ -459,6 +493,13 @@ public void onPlayerFish(PlayerFishEvent event) {
}
}
+ @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
+ public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {
+ if (listenerService.shouldCancelEvent(event)) {
+ event.setCancelled(true);
+ }
+ }
+
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerBedEnter(PlayerBedEnterEvent event) {
if (listenerService.shouldCancelEvent(event)) {
@@ -486,8 +527,11 @@ public void onSignChange(SignChangeEvent event) {
*/
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
- public void onPlayerPickupItem(PlayerPickupItemEvent event) {
- if (listenerService.shouldCancelEvent(event)) {
+ public void onPlayerPickupItem(EntityPickupItemEvent event) {
+ if (!(event.getEntity() instanceof Player)) {
+ return;
+ }
+ if (listenerService.shouldCancelEvent((Player) event.getEntity())) {
event.setCancelled(true);
}
}
@@ -499,6 +543,13 @@ public void onPlayerDropItem(PlayerDropItemEvent event) {
}
}
+ @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
+ public void onPlayerAirChange(EntityAirChangeEvent event) {
+ if (listenerService.shouldCancelEvent(event)) {
+ event.setCancelled(true);
+ }
+ }
+
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerHeldItem(PlayerItemHeldEvent event) {
if (listenerService.shouldCancelEvent(event)) {
@@ -533,7 +584,7 @@ public void onPlayerInventoryOpen(InventoryOpenEvent event) {
* @note little hack cause InventoryOpenEvent cannot be cancelled for
* real, cause no packet is sent to server by client for the main inv
*/
- bukkitService.scheduleSyncDelayedTask(player::closeInventory, 1);
+ bukkitService.scheduleSyncDelayedTask((Player) player, player::closeInventory, 1);
}
}
diff --git a/src/main/java/fr/xephi/authme/listener/ServerListener.java b/authme-core/src/main/java/fr/xephi/authme/listener/ServerListener.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/listener/ServerListener.java
rename to authme-core/src/main/java/fr/xephi/authme/listener/ServerListener.java
diff --git a/authme-core/src/main/java/fr/xephi/authme/listener/SpawnLocationTracker.java b/authme-core/src/main/java/fr/xephi/authme/listener/SpawnLocationTracker.java
new file mode 100644
index 0000000000..640c3887ac
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/listener/SpawnLocationTracker.java
@@ -0,0 +1,22 @@
+package fr.xephi.authme.listener;
+
+/**
+ * Tracks whether a platform-specific spawn location event has been fired for the current
+ * server session. Used to determine whether the spawn teleport fallback in
+ * {@link PlayerListener} is needed.
+ */
+public final class SpawnLocationTracker {
+
+ private static volatile boolean eventCalled = false;
+
+ private SpawnLocationTracker() {
+ }
+
+ public static void markEventCalled() {
+ eventCalled = true;
+ }
+
+ public static boolean isEventCalled() {
+ return eventCalled;
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/listener/protocollib/InventoryPacketAdapter.java b/authme-core/src/main/java/fr/xephi/authme/listener/protocollib/InventoryPacketAdapter.java
similarity index 90%
rename from src/main/java/fr/xephi/authme/listener/protocollib/InventoryPacketAdapter.java
rename to authme-core/src/main/java/fr/xephi/authme/listener/protocollib/InventoryPacketAdapter.java
index fb8234092d..384a055433 100644
--- a/src/main/java/fr/xephi/authme/listener/protocollib/InventoryPacketAdapter.java
+++ b/authme-core/src/main/java/fr/xephi/authme/listener/protocollib/InventoryPacketAdapter.java
@@ -103,15 +103,8 @@ public void sendBlankInventoryPacket(Player player) {
ItemStack[] blankInventory = new ItemStack[inventorySize];
Arrays.fill(blankInventory, new ItemStack(Material.AIR));
- //old minecraft versions
- StructureModifier itemArrayModifier = inventoryPacket.getItemArrayModifier();
- if (itemArrayModifier.size() > 0) {
- itemArrayModifier.write(0, blankInventory);
- } else {
- //minecraft versions above 1.11
- StructureModifier> itemListModifier = inventoryPacket.getItemListModifier();
- itemListModifier.write(0, Arrays.asList(blankInventory));
- }
+ StructureModifier> itemListModifier = inventoryPacket.getItemListModifier();
+ itemListModifier.write(0, Arrays.asList(blankInventory));
try {
protocolManager.sendServerPacket(player, inventoryPacket, false);
diff --git a/src/main/java/fr/xephi/authme/listener/protocollib/ProtocolLibService.java b/authme-core/src/main/java/fr/xephi/authme/listener/protocollib/ProtocolLibService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/listener/protocollib/ProtocolLibService.java
rename to authme-core/src/main/java/fr/xephi/authme/listener/protocollib/ProtocolLibService.java
diff --git a/src/main/java/fr/xephi/authme/listener/protocollib/TabCompletePacketAdapter.java b/authme-core/src/main/java/fr/xephi/authme/listener/protocollib/TabCompletePacketAdapter.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/listener/protocollib/TabCompletePacketAdapter.java
rename to authme-core/src/main/java/fr/xephi/authme/listener/protocollib/TabCompletePacketAdapter.java
diff --git a/src/main/java/fr/xephi/authme/mail/EmailService.java b/authme-core/src/main/java/fr/xephi/authme/mail/EmailService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/mail/EmailService.java
rename to authme-core/src/main/java/fr/xephi/authme/mail/EmailService.java
diff --git a/src/main/java/fr/xephi/authme/mail/ImageGenerator.java b/authme-core/src/main/java/fr/xephi/authme/mail/ImageGenerator.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/mail/ImageGenerator.java
rename to authme-core/src/main/java/fr/xephi/authme/mail/ImageGenerator.java
diff --git a/src/main/java/fr/xephi/authme/mail/OAuth2Provider.java b/authme-core/src/main/java/fr/xephi/authme/mail/OAuth2Provider.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/mail/OAuth2Provider.java
rename to authme-core/src/main/java/fr/xephi/authme/mail/OAuth2Provider.java
diff --git a/src/main/java/fr/xephi/authme/mail/OAuth2SaslClient.java b/authme-core/src/main/java/fr/xephi/authme/mail/OAuth2SaslClient.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/mail/OAuth2SaslClient.java
rename to authme-core/src/main/java/fr/xephi/authme/mail/OAuth2SaslClient.java
diff --git a/src/main/java/fr/xephi/authme/mail/OAuth2SaslClientFactory.java b/authme-core/src/main/java/fr/xephi/authme/mail/OAuth2SaslClientFactory.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/mail/OAuth2SaslClientFactory.java
rename to authme-core/src/main/java/fr/xephi/authme/mail/OAuth2SaslClientFactory.java
diff --git a/src/main/java/fr/xephi/authme/mail/SendMailSsl.java b/authme-core/src/main/java/fr/xephi/authme/mail/SendMailSsl.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/mail/SendMailSsl.java
rename to authme-core/src/main/java/fr/xephi/authme/mail/SendMailSsl.java
diff --git a/src/main/java/fr/xephi/authme/message/AbstractMessageFileHandler.java b/authme-core/src/main/java/fr/xephi/authme/message/AbstractMessageFileHandler.java
similarity index 71%
rename from src/main/java/fr/xephi/authme/message/AbstractMessageFileHandler.java
rename to authme-core/src/main/java/fr/xephi/authme/message/AbstractMessageFileHandler.java
index 5e6fc2210d..6f797e0f08 100644
--- a/src/main/java/fr/xephi/authme/message/AbstractMessageFileHandler.java
+++ b/authme-core/src/main/java/fr/xephi/authme/message/AbstractMessageFileHandler.java
@@ -14,6 +14,7 @@
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.io.File;
+import java.util.concurrent.ConcurrentHashMap;
import static fr.xephi.authme.message.MessagePathHelper.DEFAULT_LANGUAGE;
@@ -22,6 +23,8 @@
*/
public abstract class AbstractMessageFileHandler implements Reloadable {
+ private static final FileConfiguration UNAVAILABLE = new YamlConfiguration();
+
private final ConsoleLogger logger = ConsoleLoggerFactory.get(AbstractMessageFileHandler.class);
@DataFolder
@@ -34,6 +37,7 @@ public abstract class AbstractMessageFileHandler implements Reloadable {
private String filename;
private FileConfiguration configuration;
private final String defaultFile;
+ private final ConcurrentHashMap languageCache = new ConcurrentHashMap<>();
protected AbstractMessageFileHandler() {
this.defaultFile = createFilePath(DEFAULT_LANGUAGE);
@@ -46,6 +50,7 @@ public void reload() {
filename = createFilePath(language);
File messagesFile = initializeFile(filename);
configuration = YamlConfiguration.loadConfiguration(messagesFile);
+ languageCache.clear();
}
protected String getLanguage() {
@@ -94,6 +99,35 @@ public String getMessageIfExists(String key) {
return configuration.getString(key);
}
+ /**
+ * Returns the message for the given key in the requested language, falling back to the
+ * server-configured language if the requested language is unavailable or missing the key.
+ *
+ * @param key the key to retrieve the message for
+ * @param language the AuthMe language code (e.g. {@code "fr"}), or {@code null} to use the server default
+ * @return the message
+ */
+ public String getMessage(String key, String language) {
+ if (language == null || language.equals(getLanguage())) {
+ return getMessage(key);
+ }
+ FileConfiguration config = languageCache.computeIfAbsent(language, this::loadLanguageConfiguration);
+ if (config == UNAVAILABLE) {
+ return getMessage(key);
+ }
+ String message = config.getString(key);
+ return message != null ? message : getMessage(key);
+ }
+
+ private FileConfiguration loadLanguageConfiguration(String language) {
+ String filePath = createFilePath(language);
+ File file = new File(dataFolder, filePath);
+ if (!file.exists() && FileUtils.getResourceFromJar(filePath) != null) {
+ FileUtils.copyFileFromResource(file, filePath);
+ }
+ return file.exists() ? YamlConfiguration.loadConfiguration(file) : UNAVAILABLE;
+ }
+
/**
* Creates the path to the messages file for the given language code.
*
diff --git a/src/main/java/fr/xephi/authme/message/HelpMessagesFileHandler.java b/authme-core/src/main/java/fr/xephi/authme/message/HelpMessagesFileHandler.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/message/HelpMessagesFileHandler.java
rename to authme-core/src/main/java/fr/xephi/authme/message/HelpMessagesFileHandler.java
diff --git a/src/main/java/fr/xephi/authme/message/MessageKey.java b/authme-core/src/main/java/fr/xephi/authme/message/MessageKey.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/message/MessageKey.java
rename to authme-core/src/main/java/fr/xephi/authme/message/MessageKey.java
diff --git a/src/main/java/fr/xephi/authme/message/MessagePathHelper.java b/authme-core/src/main/java/fr/xephi/authme/message/MessagePathHelper.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/message/MessagePathHelper.java
rename to authme-core/src/main/java/fr/xephi/authme/message/MessagePathHelper.java
diff --git a/src/main/java/fr/xephi/authme/message/Messages.java b/authme-core/src/main/java/fr/xephi/authme/message/Messages.java
similarity index 78%
rename from src/main/java/fr/xephi/authme/message/Messages.java
rename to authme-core/src/main/java/fr/xephi/authme/message/Messages.java
index 2305de332a..82d25772d2 100644
--- a/src/main/java/fr/xephi/authme/message/Messages.java
+++ b/authme-core/src/main/java/fr/xephi/authme/message/Messages.java
@@ -4,6 +4,9 @@
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.mail.EmailService;
+import fr.xephi.authme.service.BukkitService;
+import fr.xephi.authme.settings.Settings;
+import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.util.expiring.Duration;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@@ -41,14 +44,22 @@ public class Messages {
private final ConsoleLogger logger = ConsoleLoggerFactory.get(EmailService.class);
- private MessagesFileHandler messagesFileHandler;
+ private final BukkitService bukkitService;
+ private final MessagesFileHandler messagesFileHandler;
+ private final Settings settings;
/*
* Constructor.
*/
@Inject
- Messages(MessagesFileHandler messagesFileHandler) {
+ Messages(MessagesFileHandler messagesFileHandler, BukkitService bukkitService, Settings settings) {
this.messagesFileHandler = messagesFileHandler;
+ this.bukkitService = bukkitService;
+ this.settings = settings;
+ }
+
+ Messages(MessagesFileHandler messagesFileHandler) {
+ this(messagesFileHandler, null, null);
}
/**
@@ -58,10 +69,12 @@ public class Messages {
* @param key The key of the message to send
*/
public void send(CommandSender sender, MessageKey key) {
- String[] lines = retrieve(key, sender);
- for (String line : lines) {
- sender.sendMessage(line);
- }
+ runOnSenderThread(sender, () -> {
+ String[] lines = retrieve(key, sender);
+ for (String line : lines) {
+ sender.sendMessage(line);
+ }
+ });
}
/**
@@ -74,10 +87,12 @@ public void send(CommandSender sender, MessageKey key) {
* @param replacements The replacements to apply for the tags
*/
public void send(CommandSender sender, MessageKey key, String... replacements) {
- String message = retrieveSingle(sender, key, replacements);
- for (String line : message.split("\n")) {
- sender.sendMessage(line);
- }
+ runOnSenderThread(sender, () -> {
+ String message = retrieveSingle(sender, key, replacements);
+ for (String line : message.split("\n")) {
+ sender.sendMessage(line);
+ }
+ });
}
/**
@@ -120,12 +135,21 @@ public String formatDuration(Duration duration) {
* @return The message from the file
*/
private String retrieveMessage(MessageKey key, CommandSender sender) {
- String message = messagesFileHandler.getMessage(key.getKey());
- String displayName = sender.getName();
- if (sender instanceof Player) {
- displayName = ((Player) sender).getDisplayName();
+ String message;
+ String displayName;
+ if (sender instanceof Player player) {
+ displayName = player.getDisplayName();
+ if (settings != null && settings.getProperty(PluginSettings.PER_PLAYER_LOCALE)) {
+ String language = PlayerLocaleResolver.toLanguageCode(player.getLocale());
+ message = messagesFileHandler.getMessage(key.getKey(), language);
+ } else {
+ message = messagesFileHandler.getMessage(key.getKey());
+ }
+ } else {
+ message = messagesFileHandler.getMessage(key.getKey());
+ displayName = sender.getName();
}
-
+
return ChatColor.translateAlternateColorCodes('&', message)
.replace(NEWLINE_TAG, "\n")
.replace(USERNAME_TAG, sender.getName())
@@ -193,4 +217,12 @@ public String retrieveSingle(String name, MessageKey key, String... replacements
}
return message;
}
+
+ private void runOnSenderThread(CommandSender sender, Runnable action) {
+ if (sender instanceof Player player && bukkitService != null) {
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player, action);
+ } else {
+ action.run();
+ }
+ }
}
diff --git a/src/main/java/fr/xephi/authme/message/MessagesFileHandler.java b/authme-core/src/main/java/fr/xephi/authme/message/MessagesFileHandler.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/message/MessagesFileHandler.java
rename to authme-core/src/main/java/fr/xephi/authme/message/MessagesFileHandler.java
diff --git a/authme-core/src/main/java/fr/xephi/authme/message/PlayerLocaleResolver.java b/authme-core/src/main/java/fr/xephi/authme/message/PlayerLocaleResolver.java
new file mode 100644
index 0000000000..91fc2f031b
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/message/PlayerLocaleResolver.java
@@ -0,0 +1,42 @@
+package fr.xephi.authme.message;
+
+import java.util.Map;
+
+/**
+ * Maps Minecraft client locale strings (e.g. {@code "fr_fr"}) to AuthMe language codes (e.g. {@code "fr"}).
+ */
+public final class PlayerLocaleResolver {
+
+ // Minecraft locales whose language code alone is not enough to pick the right AuthMe file
+ private static final Map LOCALE_OVERRIDES = Map.of(
+ "pt_br", "br",
+ "zh_cn", "zhcn",
+ "zh_tw", "zhtw",
+ "zh_hk", "zhhk"
+ );
+
+ private PlayerLocaleResolver() {
+ }
+
+ /**
+ * Converts a Minecraft client locale string to an AuthMe language code.
+ *
+ * Returns {@code null} for blank input; the caller is expected to fall back to the
+ * server-configured language in that case.
+ *
+ * @param minecraftLocale the locale reported by {@link org.bukkit.entity.Player#getLocale()} (e.g. {@code "fr_fr"})
+ * @return the matching AuthMe language code, or {@code null} if the input is blank
+ */
+ public static String toLanguageCode(String minecraftLocale) {
+ if (minecraftLocale == null || minecraftLocale.isBlank()) {
+ return null;
+ }
+ String locale = minecraftLocale.toLowerCase();
+ String override = LOCALE_OVERRIDES.get(locale);
+ if (override != null) {
+ return override;
+ }
+ int underscore = locale.indexOf('_');
+ return underscore > 0 ? locale.substring(0, underscore) : locale;
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/message/updater/JarMessageSource.java b/authme-core/src/main/java/fr/xephi/authme/message/updater/JarMessageSource.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/message/updater/JarMessageSource.java
rename to authme-core/src/main/java/fr/xephi/authme/message/updater/JarMessageSource.java
diff --git a/src/main/java/fr/xephi/authme/message/updater/MessageKeyConfigurationData.java b/authme-core/src/main/java/fr/xephi/authme/message/updater/MessageKeyConfigurationData.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/message/updater/MessageKeyConfigurationData.java
rename to authme-core/src/main/java/fr/xephi/authme/message/updater/MessageKeyConfigurationData.java
diff --git a/src/main/java/fr/xephi/authme/message/updater/MessageMigraterPropertyReader.java b/authme-core/src/main/java/fr/xephi/authme/message/updater/MessageMigraterPropertyReader.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/message/updater/MessageMigraterPropertyReader.java
rename to authme-core/src/main/java/fr/xephi/authme/message/updater/MessageMigraterPropertyReader.java
diff --git a/src/main/java/fr/xephi/authme/message/updater/MessageUpdater.java b/authme-core/src/main/java/fr/xephi/authme/message/updater/MessageUpdater.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/message/updater/MessageUpdater.java
rename to authme-core/src/main/java/fr/xephi/authme/message/updater/MessageUpdater.java
diff --git a/src/main/java/fr/xephi/authme/message/updater/MigraterYamlFileResource.java b/authme-core/src/main/java/fr/xephi/authme/message/updater/MigraterYamlFileResource.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/message/updater/MigraterYamlFileResource.java
rename to authme-core/src/main/java/fr/xephi/authme/message/updater/MigraterYamlFileResource.java
diff --git a/src/main/java/fr/xephi/authme/message/updater/OldMessageKeysMigrater.java b/authme-core/src/main/java/fr/xephi/authme/message/updater/OldMessageKeysMigrater.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/message/updater/OldMessageKeysMigrater.java
rename to authme-core/src/main/java/fr/xephi/authme/message/updater/OldMessageKeysMigrater.java
diff --git a/src/main/java/fr/xephi/authme/output/ConsoleFilter.java b/authme-core/src/main/java/fr/xephi/authme/output/ConsoleFilter.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/output/ConsoleFilter.java
rename to authme-core/src/main/java/fr/xephi/authme/output/ConsoleFilter.java
diff --git a/src/main/java/fr/xephi/authme/output/ConsoleLoggerFactory.java b/authme-core/src/main/java/fr/xephi/authme/output/ConsoleLoggerFactory.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/output/ConsoleLoggerFactory.java
rename to authme-core/src/main/java/fr/xephi/authme/output/ConsoleLoggerFactory.java
diff --git a/src/main/java/fr/xephi/authme/output/Log4JFilter.java b/authme-core/src/main/java/fr/xephi/authme/output/Log4JFilter.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/output/Log4JFilter.java
rename to authme-core/src/main/java/fr/xephi/authme/output/Log4JFilter.java
diff --git a/src/main/java/fr/xephi/authme/output/LogFilterHelper.java b/authme-core/src/main/java/fr/xephi/authme/output/LogFilterHelper.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/output/LogFilterHelper.java
rename to authme-core/src/main/java/fr/xephi/authme/output/LogFilterHelper.java
diff --git a/src/main/java/fr/xephi/authme/output/LogLevel.java b/authme-core/src/main/java/fr/xephi/authme/output/LogLevel.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/output/LogLevel.java
rename to authme-core/src/main/java/fr/xephi/authme/output/LogLevel.java
diff --git a/src/main/java/fr/xephi/authme/permission/AdminPermission.java b/authme-core/src/main/java/fr/xephi/authme/permission/AdminPermission.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/AdminPermission.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/AdminPermission.java
diff --git a/src/main/java/fr/xephi/authme/permission/DebugSectionPermissions.java b/authme-core/src/main/java/fr/xephi/authme/permission/DebugSectionPermissions.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/DebugSectionPermissions.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/DebugSectionPermissions.java
diff --git a/src/main/java/fr/xephi/authme/permission/DefaultPermission.java b/authme-core/src/main/java/fr/xephi/authme/permission/DefaultPermission.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/DefaultPermission.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/DefaultPermission.java
diff --git a/src/main/java/fr/xephi/authme/permission/PermissionNode.java b/authme-core/src/main/java/fr/xephi/authme/permission/PermissionNode.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/PermissionNode.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/PermissionNode.java
diff --git a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java b/authme-core/src/main/java/fr/xephi/authme/permission/PermissionsManager.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/PermissionsManager.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/PermissionsManager.java
diff --git a/src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java b/authme-core/src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java
diff --git a/src/main/java/fr/xephi/authme/permission/PlayerPermission.java b/authme-core/src/main/java/fr/xephi/authme/permission/PlayerPermission.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/PlayerPermission.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/PlayerPermission.java
diff --git a/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java b/authme-core/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java
diff --git a/src/main/java/fr/xephi/authme/permission/handlers/LuckPermGroup.java b/authme-core/src/main/java/fr/xephi/authme/permission/handlers/LuckPermGroup.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/handlers/LuckPermGroup.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/handlers/LuckPermGroup.java
diff --git a/src/main/java/fr/xephi/authme/permission/handlers/LuckPermsHandler.java b/authme-core/src/main/java/fr/xephi/authme/permission/handlers/LuckPermsHandler.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/handlers/LuckPermsHandler.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/handlers/LuckPermsHandler.java
diff --git a/src/main/java/fr/xephi/authme/permission/handlers/PermissionHandler.java b/authme-core/src/main/java/fr/xephi/authme/permission/handlers/PermissionHandler.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/handlers/PermissionHandler.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/handlers/PermissionHandler.java
diff --git a/src/main/java/fr/xephi/authme/permission/handlers/PermissionHandlerException.java b/authme-core/src/main/java/fr/xephi/authme/permission/handlers/PermissionHandlerException.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/handlers/PermissionHandlerException.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/handlers/PermissionHandlerException.java
diff --git a/src/main/java/fr/xephi/authme/permission/handlers/PermissionLoadUserException.java b/authme-core/src/main/java/fr/xephi/authme/permission/handlers/PermissionLoadUserException.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/handlers/PermissionLoadUserException.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/handlers/PermissionLoadUserException.java
diff --git a/src/main/java/fr/xephi/authme/permission/handlers/PermissionsExHandler.java b/authme-core/src/main/java/fr/xephi/authme/permission/handlers/PermissionsExHandler.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/handlers/PermissionsExHandler.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/handlers/PermissionsExHandler.java
diff --git a/src/main/java/fr/xephi/authme/permission/handlers/VaultHandler.java b/authme-core/src/main/java/fr/xephi/authme/permission/handlers/VaultHandler.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/handlers/VaultHandler.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/handlers/VaultHandler.java
diff --git a/src/main/java/fr/xephi/authme/permission/handlers/ZPermissionsHandler.java b/authme-core/src/main/java/fr/xephi/authme/permission/handlers/ZPermissionsHandler.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/permission/handlers/ZPermissionsHandler.java
rename to authme-core/src/main/java/fr/xephi/authme/permission/handlers/ZPermissionsHandler.java
diff --git a/authme-core/src/main/java/fr/xephi/authme/platform/AbstractSpigotPlatformAdapter.java b/authme-core/src/main/java/fr/xephi/authme/platform/AbstractSpigotPlatformAdapter.java
new file mode 100644
index 0000000000..209411871a
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/platform/AbstractSpigotPlatformAdapter.java
@@ -0,0 +1,83 @@
+package fr.xephi.authme.platform;
+
+import fr.xephi.authme.AuthMe;
+import fr.xephi.authme.service.CancellableTask;
+import fr.xephi.authme.util.Utils;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
+import org.bukkit.scheduler.BukkitTask;
+
+/**
+ * Base implementation of {@link PlatformAdapter} for all Spigot versions.
+ * Uses synchronous (blocking) teleport via the Bukkit API.
+ */
+public abstract class AbstractSpigotPlatformAdapter implements PlatformAdapter {
+
+ @Override
+ public void teleportPlayer(Player player, Location location) {
+ player.teleport(location);
+ }
+
+ @Override
+ public Location getPlayerRespawnLocation(Player player) {
+ return player.getBedSpawnLocation();
+ }
+
+ @Override
+ public boolean isOwnedByCurrentThread(Entity entity) {
+ return Bukkit.isPrimaryThread();
+ }
+
+ @Override
+ public boolean isGlobalThread() {
+ return Bukkit.isPrimaryThread();
+ }
+
+ @Override
+ public void runOnEntityThread(AuthMe plugin, Entity entity, Runnable task) {
+ Bukkit.getScheduler().runTask(plugin, task);
+ }
+
+ @Override
+ public CancellableTask runDelayedOnEntityThread(AuthMe plugin, Entity entity, Runnable task, long delay) {
+ return wrapTask(Bukkit.getScheduler().runTaskLater(plugin, task, delay));
+ }
+
+ @Override
+ public CancellableTask runAtFixedRateOnEntityThread(AuthMe plugin, Entity entity, Runnable task,
+ long delay, long period) {
+ BukkitRunnable bukkitRunnable = new BukkitRunnable() {
+ @Override
+ public void run() {
+ task.run();
+ }
+ };
+ return wrapTask(bukkitRunnable.runTaskTimer(plugin, delay, period));
+ }
+
+ @Override
+ public void runOnGlobalThread(AuthMe plugin, Runnable task) {
+ Bukkit.getScheduler().runTask(plugin, task);
+ }
+
+ @Override
+ public CancellableTask runDelayedOnGlobalThread(AuthMe plugin, Runnable task, long delay) {
+ return wrapTask(Bukkit.getScheduler().runTaskLater(plugin, task, delay));
+ }
+
+ protected final String getCompatibilityError(String errorMessage, String... requiredClasses) {
+ for (String className : requiredClasses) {
+ if (!Utils.isClassLoaded(className)) {
+ return errorMessage;
+ }
+ }
+ return null;
+ }
+
+ private static CancellableTask wrapTask(BukkitTask task) {
+ return task::cancel;
+ }
+}
diff --git a/authme-core/src/main/java/fr/xephi/authme/platform/ChatAdapter.java b/authme-core/src/main/java/fr/xephi/authme/platform/ChatAdapter.java
new file mode 100644
index 0000000000..5510afaf43
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/platform/ChatAdapter.java
@@ -0,0 +1,14 @@
+package fr.xephi.authme.platform;
+
+import org.bukkit.event.player.PlayerKickEvent;
+
+/**
+ * Platform-specific chat and kick behavior.
+ * Paper 1.21+ overrides {@link #getKickReason} to use the Adventure API.
+ */
+public interface ChatAdapter {
+
+ default String getKickReason(PlayerKickEvent event) {
+ return event.getReason();
+ }
+}
diff --git a/authme-core/src/main/java/fr/xephi/authme/platform/CommandRegistrationAdapter.java b/authme-core/src/main/java/fr/xephi/authme/platform/CommandRegistrationAdapter.java
new file mode 100644
index 0000000000..49d80d251a
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/platform/CommandRegistrationAdapter.java
@@ -0,0 +1,25 @@
+package fr.xephi.authme.platform;
+
+import fr.xephi.authme.AuthMe;
+import fr.xephi.authme.command.CommandDescription;
+import fr.xephi.authme.command.CommandHandler;
+
+import java.util.Collection;
+
+/**
+ * Allows a platform module to register commands using platform-specific APIs.
+ */
+public interface CommandRegistrationAdapter {
+
+ /**
+ * Registers commands for the current platform.
+ *
+ * @param plugin the plugin instance
+ * @param commandHandler the shared AuthMe command handler
+ * @param commands the base command descriptions
+ */
+ default void registerCommands(AuthMe plugin, CommandHandler commandHandler,
+ Collection commands) {
+ // Default no-op: platforms without a dedicated command API continue using plugin.yml + onCommand.
+ }
+}
diff --git a/authme-core/src/main/java/fr/xephi/authme/platform/DialogAdapter.java b/authme-core/src/main/java/fr/xephi/authme/platform/DialogAdapter.java
new file mode 100644
index 0000000000..f673d8f5eb
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/platform/DialogAdapter.java
@@ -0,0 +1,39 @@
+package fr.xephi.authme.platform;
+
+import fr.xephi.authme.process.register.RegisterSecondaryArgument;
+import fr.xephi.authme.process.register.RegistrationType;
+import org.bukkit.entity.Player;
+
+/**
+ * Platform adapter for showing graphical dialog UIs to players on supported platforms (1.21.6+).
+ * The default implementation is a no-op (dialog not supported).
+ */
+public interface DialogAdapter {
+
+ /**
+ * Returns whether this platform supports showing dialog UIs.
+ *
+ * @return true if dialog UI is supported, false otherwise
+ */
+ default boolean isDialogSupported() {
+ return false;
+ }
+
+ /**
+ * Shows the login dialog to the given player.
+ *
+ * @param player the player to show the dialog to
+ */
+ default void showLoginDialog(Player player) {
+ }
+
+ /**
+ * Shows the register dialog to the given player.
+ *
+ * @param player the player to show the dialog to
+ * @param type the registration type (password or email)
+ * @param secondArg the secondary argument type for registration
+ */
+ default void showRegisterDialog(Player player, RegistrationType type, RegisterSecondaryArgument secondArg) {
+ }
+}
diff --git a/authme-core/src/main/java/fr/xephi/authme/platform/EventRegistrationAdapter.java b/authme-core/src/main/java/fr/xephi/authme/platform/EventRegistrationAdapter.java
new file mode 100644
index 0000000000..782bfa6b6d
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/platform/EventRegistrationAdapter.java
@@ -0,0 +1,16 @@
+package fr.xephi.authme.platform;
+
+import org.bukkit.event.Listener;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Supplies version-specific listeners to register at startup, in addition to the core set.
+ */
+public interface EventRegistrationAdapter {
+
+ default List> getAdditionalListeners() {
+ return Collections.emptyList();
+ }
+}
diff --git a/authme-core/src/main/java/fr/xephi/authme/platform/PlatformAdapter.java b/authme-core/src/main/java/fr/xephi/authme/platform/PlatformAdapter.java
new file mode 100644
index 0000000000..4b44810063
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/platform/PlatformAdapter.java
@@ -0,0 +1,47 @@
+package fr.xephi.authme.platform;
+
+/**
+ * Combines all platform-specific behavior. Implementations are provided by each version
+ * module via ServiceLoader and registered as {@link TeleportAdapter}, {@link ChatAdapter},
+ * {@link EventRegistrationAdapter}, {@link SchedulingAdapter}, and
+ * {@link CommandRegistrationAdapter} in the DI container.
+ */
+public interface PlatformAdapter extends TeleportAdapter, ChatAdapter, EventRegistrationAdapter,
+ DialogAdapter, CommandRegistrationAdapter, SchedulingAdapter {
+
+ /**
+ * Returns a short identifier for logging, e.g. "spigot-legacy", "spigot-1.20", "paper-1.21".
+ */
+ String getPlatformName();
+
+ /**
+ * Returns an error message if this platform adapter does not support the current server,
+ * or null if the server is compatible.
+ *
+ * @return the compatibility error message, or null if compatible
+ */
+ default String getCompatibilityError() {
+ return null;
+ }
+
+ /**
+ * Returns whether the core {@link org.bukkit.event.player.PlayerLoginEvent} listener should be active.
+ * Paper-derived platforms disable it in favor of newer, split login validation events.
+ *
+ * @return true if the legacy PlayerLoginEvent listener should run
+ */
+ default boolean shouldHandlePlayerLoginEvent() {
+ return true;
+ }
+
+ /**
+ * Returns whether the core Spigot {@link org.spigotmc.event.player.PlayerSpawnLocationEvent}
+ * listener should be active. Paper-derived platforms disable it in favor of their async
+ * spawn-location event.
+ *
+ * @return true if the legacy PlayerSpawnLocationEvent listener should run
+ */
+ default boolean shouldHandlePlayerSpawnLocationEvent() {
+ return true;
+ }
+}
diff --git a/authme-core/src/main/java/fr/xephi/authme/platform/SchedulingAdapter.java b/authme-core/src/main/java/fr/xephi/authme/platform/SchedulingAdapter.java
new file mode 100644
index 0000000000..8bf54a5a5c
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/platform/SchedulingAdapter.java
@@ -0,0 +1,74 @@
+package fr.xephi.authme.platform;
+
+import fr.xephi.authme.AuthMe;
+import fr.xephi.authme.service.CancellableTask;
+import org.bukkit.entity.Entity;
+
+/**
+ * Platform-specific task scheduling bridge used by {@link fr.xephi.authme.service.BukkitService}.
+ * Implementations map AuthMe's global and entity-owned task concepts to the appropriate
+ * scheduler model of the running server platform.
+ */
+public interface SchedulingAdapter {
+
+ /**
+ * @param entity the entity that would own the task
+ * @return true if the current thread may already safely interact with the entity
+ */
+ boolean isOwnedByCurrentThread(Entity entity);
+
+ /**
+ * @return true if the current thread may already safely perform global server work
+ */
+ boolean isGlobalThread();
+
+ /**
+ * Runs a task on the owning thread of the given entity.
+ *
+ * @param plugin the plugin scheduling the task
+ * @param entity the entity that owns the execution context
+ * @param task the task to run
+ */
+ void runOnEntityThread(AuthMe plugin, Entity entity, Runnable task);
+
+ /**
+ * Runs a delayed task on the owning thread of the given entity.
+ *
+ * @param plugin the plugin scheduling the task
+ * @param entity the entity that owns the execution context
+ * @param task the task to run
+ * @param delay the delay in ticks
+ * @return the scheduled task handle
+ */
+ CancellableTask runDelayedOnEntityThread(AuthMe plugin, Entity entity, Runnable task, long delay);
+
+ /**
+ * Runs a repeating task on the owning thread of the given entity.
+ *
+ * @param plugin the plugin scheduling the task
+ * @param entity the entity that owns the execution context
+ * @param task the task to run
+ * @param delay the initial delay in ticks
+ * @param period the repeat period in ticks
+ * @return the scheduled task handle
+ */
+ CancellableTask runAtFixedRateOnEntityThread(AuthMe plugin, Entity entity, Runnable task, long delay, long period);
+
+ /**
+ * Runs a task on the platform's global execution context.
+ *
+ * @param plugin the plugin scheduling the task
+ * @param task the task to run
+ */
+ void runOnGlobalThread(AuthMe plugin, Runnable task);
+
+ /**
+ * Runs a delayed task on the platform's global execution context.
+ *
+ * @param plugin the plugin scheduling the task
+ * @param task the task to run
+ * @param delay the delay in ticks
+ * @return the scheduled task handle
+ */
+ CancellableTask runDelayedOnGlobalThread(AuthMe plugin, Runnable task, long delay);
+}
diff --git a/authme-core/src/main/java/fr/xephi/authme/platform/TeleportAdapter.java b/authme-core/src/main/java/fr/xephi/authme/platform/TeleportAdapter.java
new file mode 100644
index 0000000000..b72f9046f2
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/platform/TeleportAdapter.java
@@ -0,0 +1,24 @@
+package fr.xephi.authme.platform;
+
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+
+/**
+ * Platform-specific teleportation behavior.
+ * May be asynchronous on platforms that support it (e.g. Paper).
+ */
+public interface TeleportAdapter {
+
+ void teleportPlayer(Player player, Location location);
+
+ /**
+ * Returns the platform-appropriate respawn location for the player, or null if there is no valid respawn point.
+ *
+ * Legacy platforms only expose bed spawn directly, while newer APIs can provide the server's full respawn target
+ * (bed, respawn anchor, world spawn logic, etc.).
+ *
+ * @param player the player
+ * @return the respawn location, or null if none is available
+ */
+ Location getPlayerRespawnLocation(Player player);
+}
diff --git a/src/main/java/fr/xephi/authme/process/AsynchronousProcess.java b/authme-core/src/main/java/fr/xephi/authme/process/AsynchronousProcess.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/AsynchronousProcess.java
rename to authme-core/src/main/java/fr/xephi/authme/process/AsynchronousProcess.java
diff --git a/src/main/java/fr/xephi/authme/process/Management.java b/authme-core/src/main/java/fr/xephi/authme/process/Management.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/Management.java
rename to authme-core/src/main/java/fr/xephi/authme/process/Management.java
diff --git a/src/main/java/fr/xephi/authme/process/SyncProcessManager.java b/authme-core/src/main/java/fr/xephi/authme/process/SyncProcessManager.java
similarity index 74%
rename from src/main/java/fr/xephi/authme/process/SyncProcessManager.java
rename to authme-core/src/main/java/fr/xephi/authme/process/SyncProcessManager.java
index 0fdfdde3de..47a1cbf502 100644
--- a/src/main/java/fr/xephi/authme/process/SyncProcessManager.java
+++ b/authme-core/src/main/java/fr/xephi/authme/process/SyncProcessManager.java
@@ -37,26 +37,26 @@ public class SyncProcessManager {
public void processSyncEmailRegister(Player player) {
- runTask(() -> processSyncEmailRegister.processEmailRegister(player));
+ runTask(player, () -> processSyncEmailRegister.processEmailRegister(player));
}
public void processSyncPasswordRegister(Player player) {
- runTask(() -> processSyncPasswordRegister.processPasswordRegister(player));
+ runTask(player, () -> processSyncPasswordRegister.processPasswordRegister(player));
}
public void processSyncPlayerLogout(Player player) {
- runTask(() -> processSyncPlayerLogout.processSyncLogout(player));
+ runTask(player, () -> processSyncPlayerLogout.processSyncLogout(player));
}
public void processSyncPlayerLogin(Player player, boolean isFirstLogin, List authsWithSameIp) {
- runTask(() -> processSyncPlayerLogin.processPlayerLogin(player, isFirstLogin, authsWithSameIp));
+ runTask(player, () -> processSyncPlayerLogin.processPlayerLogin(player, isFirstLogin, authsWithSameIp));
}
public void processSyncPlayerQuit(Player player, boolean wasLoggedIn) {
- runTask(() -> processSyncPlayerQuit.processSyncQuit(player, wasLoggedIn));
+ runTask(player, () -> processSyncPlayerQuit.processSyncQuit(player, wasLoggedIn));
}
- private void runTask(Runnable runnable) {
- bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(runnable);
+ private void runTask(Player player, Runnable runnable) {
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player, runnable);
}
}
diff --git a/src/main/java/fr/xephi/authme/process/SynchronousProcess.java b/authme-core/src/main/java/fr/xephi/authme/process/SynchronousProcess.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/SynchronousProcess.java
rename to authme-core/src/main/java/fr/xephi/authme/process/SynchronousProcess.java
diff --git a/src/main/java/fr/xephi/authme/process/changepassword/AsyncChangePassword.java b/authme-core/src/main/java/fr/xephi/authme/process/changepassword/AsyncChangePassword.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/changepassword/AsyncChangePassword.java
rename to authme-core/src/main/java/fr/xephi/authme/process/changepassword/AsyncChangePassword.java
diff --git a/src/main/java/fr/xephi/authme/process/email/AsyncAddEmail.java b/authme-core/src/main/java/fr/xephi/authme/process/email/AsyncAddEmail.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/email/AsyncAddEmail.java
rename to authme-core/src/main/java/fr/xephi/authme/process/email/AsyncAddEmail.java
diff --git a/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java b/authme-core/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java
rename to authme-core/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java
diff --git a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java b/authme-core/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java
similarity index 84%
rename from src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java
rename to authme-core/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java
index d60ce4e831..ef45bdb122 100644
--- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java
+++ b/authme-core/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java
@@ -8,8 +8,11 @@
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.permission.PlayerStatePermission;
+import fr.xephi.authme.platform.DialogAdapter;
import fr.xephi.authme.process.AsynchronousProcess;
import fr.xephi.authme.process.login.AsynchronousLogin;
+import fr.xephi.authme.process.register.RegisterSecondaryArgument;
+import fr.xephi.authme.process.register.RegistrationType;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.service.PluginHookService;
@@ -80,6 +83,9 @@ public class AsynchronousJoin implements AsynchronousProcess {
@Inject
private ProxySessionManager proxySessionManager;
+ @Inject
+ private DialogAdapter dialogAdapter;
+
AsynchronousJoin() {
}
@@ -104,7 +110,7 @@ public void processJoin(Player player) {
if (service.getProperty(RestrictionSettings.FORCE_SURVIVAL_MODE)
&& player.getGameMode() != GameMode.SURVIVAL
&& !service.hasPermission(player, PlayerStatePermission.BYPASS_FORCE_SURVIVAL)) {
- bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> player.setGameMode(GameMode.SURVIVAL));
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player, () -> player.setGameMode(GameMode.SURVIVAL));
}
if (service.getProperty(HooksSettings.DISABLE_SOCIAL_SPY)) {
@@ -123,7 +129,7 @@ public void processJoin(Player player) {
ProtectInventoryEvent ev = bukkitService.createAndCallEvent(
isAsync -> new ProtectInventoryEvent(player, isAsync));
if (ev.isCancelled()) {
- player.updateInventory();
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player, player::updateInventory);
logger.fine("ProtectInventoryEvent has been cancelled for " + player.getName() + "...");
}
}
@@ -132,14 +138,14 @@ public void processJoin(Player player) {
if (sessionService.canResumeSession(player)) {
service.send(player, MessageKey.SESSION_RECONNECTION);
// Run commands
- bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player,
() -> commandManager.runCommandsOnSessionLogin(player));
bukkitService.runTaskOptionallyAsync(() -> asynchronousLogin.forceLogin(player));
return;
} else if (proxySessionManager.shouldResumeSession(name)) {
service.send(player, MessageKey.SESSION_RECONNECTION);
// Run commands
- bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player,
() -> commandManager.runCommandsOnSessionLogin(player));
bukkitService.runTaskOptionallyAsync(() -> asynchronousLogin.forceLogin(player));
logger.info("The user " + player.getName() + " has been automatically logged in, "
@@ -147,7 +153,7 @@ public void processJoin(Player player) {
return;
}
} else if (!service.getProperty(RegistrationSettings.FORCE)) {
- bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> {
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player, () -> {
welcomeMessageConfiguration.sendWelcomeMessage(player);
});
@@ -156,7 +162,7 @@ public void processJoin(Player player) {
if (bungeeSender.isEnabled()) {
// As described at https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/
// "Keep in mind that you can't send plugin messages directly after a player joins."
- bukkitService.scheduleSyncDelayedTask(() ->
+ bukkitService.scheduleSyncDelayedTask(player, () ->
bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGIN), 5L);
}
return;
@@ -166,12 +172,11 @@ public void processJoin(Player player) {
}
private void handlePlayerWithUnmetNameRestriction(Player player, String ip) {
- bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> {
- player.kickPlayer(service.retrieveSingleMessage(player, MessageKey.NOT_OWNER_ERROR));
- if (service.getProperty(RestrictionSettings.BAN_UNKNOWN_IP)) {
- server.banIP(ip);
- }
- });
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player,
+ () -> player.kickPlayer(service.retrieveSingleMessage(player, MessageKey.NOT_OWNER_ERROR)));
+ if (service.getProperty(RestrictionSettings.BAN_UNKNOWN_IP)) {
+ bukkitService.runOnGlobalRegion(() -> server.banIP(ip));
+ }
}
/**
@@ -182,9 +187,11 @@ private void handlePlayerWithUnmetNameRestriction(Player player, String ip) {
* @param isAuthAvailable true if the player is registered, false otherwise
*/
private void processJoinSync(Player player, boolean isAuthAvailable) {
- int registrationTimeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
+ int registrationTimeout = service.getProperty(
+ isAuthAvailable ? RestrictionSettings.LOGIN_TIMEOUT : RestrictionSettings.REGISTER_TIMEOUT
+ ) * TICKS_PER_SECOND;
- bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> {
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player, () -> {
limboService.createLimboPlayer(player, isAuthAvailable);
player.setNoDamageTicks(registrationTimeout);
@@ -197,6 +204,15 @@ private void processJoinSync(Player player, boolean isAuthAvailable) {
player.addPotionEffect(bukkitService.createBlindnessEffect(blindTimeOut));
}
commandManager.runCommandsOnJoin(player);
+ if (service.getProperty(RegistrationSettings.USE_DIALOG_UI) && dialogAdapter.isDialogSupported()) {
+ if (isAuthAvailable) {
+ dialogAdapter.showLoginDialog(player);
+ } else {
+ dialogAdapter.showRegisterDialog(player,
+ service.getProperty(RegistrationSettings.REGISTRATION_TYPE),
+ service.getProperty(RegistrationSettings.REGISTER_SECOND_ARGUMENT));
+ }
+ }
});
}
@@ -215,7 +231,7 @@ private boolean validatePlayerCountForIp(Player player, String ip) {
&& !InternetProtocolUtils.isLoopbackAddress(ip)
&& countOnlinePlayersByIp(ip) > service.getProperty(RestrictionSettings.MAX_JOIN_PER_IP)) {
- bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player,
() -> player.kickPlayer(service.retrieveSingleMessage(player, MessageKey.SAME_IP_ONLINE)));
return false;
}
diff --git a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java b/authme-core/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java
similarity index 99%
rename from src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java
rename to authme-core/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java
index 3e9f5fd74c..8fca24a505 100644
--- a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java
+++ b/authme-core/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java
@@ -243,7 +243,7 @@ private void handleWrongPassword(Player player, PlayerAuth auth, String ip) {
if (tempbanManager.shouldTempban(ip)) {
tempbanManager.tempbanPlayer(player);
} else if (service.getProperty(RestrictionSettings.KICK_ON_WRONG_PASSWORD)) {
- bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player,
() -> player.kickPlayer(service.retrieveSingleMessage(player, MessageKey.WRONG_PASSWORD)));
} else {
service.send(player, MessageKey.WRONG_PASSWORD);
@@ -304,7 +304,7 @@ public void performLogin(Player player, PlayerAuth auth) {
if (bungeeSender.isEnabled()) {
// As described at https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/
// "Keep in mind that you can't send plugin messages directly after a player joins."
- bukkitService.scheduleSyncDelayedTask(() ->
+ bukkitService.scheduleSyncDelayedTask(player, () ->
bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGIN), 5L);
}
diff --git a/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java b/authme-core/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java
similarity index 98%
rename from src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java
rename to authme-core/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java
index 73b142be92..a7bd09d1c7 100644
--- a/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java
+++ b/authme-core/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java
@@ -99,6 +99,7 @@ public void processPlayerLogin(Player player, boolean isFirstLogin, List
}
teleportationService.teleportOnLogin(player, auth, limbo);
+ teleportationService.clearOriginalJoinLocation(name);
// We can now display the join message (if delayed)
joinMessageService.sendMessage(name);
diff --git a/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java b/authme-core/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java
rename to authme-core/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java
diff --git a/src/main/java/fr/xephi/authme/process/logout/ProcessSyncPlayerLogout.java b/authme-core/src/main/java/fr/xephi/authme/process/logout/ProcessSyncPlayerLogout.java
similarity index 98%
rename from src/main/java/fr/xephi/authme/process/logout/ProcessSyncPlayerLogout.java
rename to authme-core/src/main/java/fr/xephi/authme/process/logout/ProcessSyncPlayerLogout.java
index 96865e21c3..680be22021 100644
--- a/src/main/java/fr/xephi/authme/process/logout/ProcessSyncPlayerLogout.java
+++ b/authme-core/src/main/java/fr/xephi/authme/process/logout/ProcessSyncPlayerLogout.java
@@ -72,7 +72,7 @@ private void applyLogoutEffect(Player player) {
// Apply Blindness effect
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
- int timeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
+ int timeout = service.getProperty(RestrictionSettings.LOGIN_TIMEOUT) * TICKS_PER_SECOND;
player.addPotionEffect(bukkitService.createBlindnessEffect(timeout));
}
diff --git a/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java b/authme-core/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java
similarity index 94%
rename from src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java
rename to authme-core/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java
index f4b1d3250d..8022ed0318 100644
--- a/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java
+++ b/authme-core/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java
@@ -9,6 +9,7 @@
import fr.xephi.authme.process.SyncProcessManager;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.service.SessionService;
+import fr.xephi.authme.service.TeleportationService;
import fr.xephi.authme.service.ValidationService;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.properties.PluginSettings;
@@ -52,6 +53,9 @@ public class AsynchronousQuit implements AsynchronousProcess {
@Inject
private SessionService sessionService;
+ @Inject
+ private TeleportationService teleportationService;
+
AsynchronousQuit() {
}
@@ -65,6 +69,7 @@ public void processQuit(Player player) {
return;
}
String name = player.getName().toLowerCase(Locale.ROOT);
+ teleportationService.clearOriginalJoinLocation(name);
boolean wasLoggedIn = playerCache.isAuthenticated(name);
if (wasLoggedIn) {
diff --git a/src/main/java/fr/xephi/authme/process/quit/ProcessSyncPlayerQuit.java b/authme-core/src/main/java/fr/xephi/authme/process/quit/ProcessSyncPlayerQuit.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/quit/ProcessSyncPlayerQuit.java
rename to authme-core/src/main/java/fr/xephi/authme/process/quit/ProcessSyncPlayerQuit.java
diff --git a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java b/authme-core/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/AsyncRegister.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java
diff --git a/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java b/authme-core/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java
diff --git a/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java b/authme-core/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java
diff --git a/src/main/java/fr/xephi/authme/process/register/RegisterSecondaryArgument.java b/authme-core/src/main/java/fr/xephi/authme/process/register/RegisterSecondaryArgument.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/RegisterSecondaryArgument.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/RegisterSecondaryArgument.java
diff --git a/src/main/java/fr/xephi/authme/process/register/RegistrationType.java b/authme-core/src/main/java/fr/xephi/authme/process/register/RegistrationType.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/RegistrationType.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/RegistrationType.java
diff --git a/src/main/java/fr/xephi/authme/process/register/executors/AbstractPasswordRegisterExecutor.java b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/AbstractPasswordRegisterExecutor.java
similarity index 96%
rename from src/main/java/fr/xephi/authme/process/register/executors/AbstractPasswordRegisterExecutor.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/executors/AbstractPasswordRegisterExecutor.java
index 179aa59df8..0913558fb0 100644
--- a/src/main/java/fr/xephi/authme/process/register/executors/AbstractPasswordRegisterExecutor.java
+++ b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/AbstractPasswordRegisterExecutor.java
@@ -91,7 +91,8 @@ public void executePostPersistAction(P params) {
if (commonService.getProperty(PluginSettings.USE_ASYNC_TASKS)) {
bukkitService.runTaskAsynchronously(() -> asynchronousLogin.forceLogin(player));
} else {
- bukkitService.scheduleSyncDelayedTask(() -> asynchronousLogin.forceLogin(player), SYNC_LOGIN_DELAY);
+ bukkitService.scheduleSyncDelayedTask(player,
+ () -> asynchronousLogin.forceLogin(player), SYNC_LOGIN_DELAY);
}
}
syncProcessManager.processSyncPasswordRegister(player);
diff --git a/src/main/java/fr/xephi/authme/process/register/executors/AbstractPasswordRegisterParams.java b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/AbstractPasswordRegisterParams.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/executors/AbstractPasswordRegisterParams.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/executors/AbstractPasswordRegisterParams.java
diff --git a/src/main/java/fr/xephi/authme/process/register/executors/ApiPasswordRegisterExecutor.java b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/ApiPasswordRegisterExecutor.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/executors/ApiPasswordRegisterExecutor.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/executors/ApiPasswordRegisterExecutor.java
diff --git a/src/main/java/fr/xephi/authme/process/register/executors/ApiPasswordRegisterParams.java b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/ApiPasswordRegisterParams.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/executors/ApiPasswordRegisterParams.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/executors/ApiPasswordRegisterParams.java
diff --git a/src/main/java/fr/xephi/authme/process/register/executors/EmailRegisterExecutor.java b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/EmailRegisterExecutor.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/executors/EmailRegisterExecutor.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/executors/EmailRegisterExecutor.java
diff --git a/src/main/java/fr/xephi/authme/process/register/executors/EmailRegisterParams.java b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/EmailRegisterParams.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/executors/EmailRegisterParams.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/executors/EmailRegisterParams.java
diff --git a/src/main/java/fr/xephi/authme/process/register/executors/PasswordRegisterExecutor.java b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/PasswordRegisterExecutor.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/executors/PasswordRegisterExecutor.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/executors/PasswordRegisterExecutor.java
diff --git a/src/main/java/fr/xephi/authme/process/register/executors/PasswordRegisterParams.java b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/PasswordRegisterParams.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/executors/PasswordRegisterParams.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/executors/PasswordRegisterParams.java
diff --git a/src/main/java/fr/xephi/authme/process/register/executors/PlayerAuthBuilderHelper.java b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/PlayerAuthBuilderHelper.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/executors/PlayerAuthBuilderHelper.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/executors/PlayerAuthBuilderHelper.java
diff --git a/src/main/java/fr/xephi/authme/process/register/executors/RegistrationExecutor.java b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/RegistrationExecutor.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/executors/RegistrationExecutor.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/executors/RegistrationExecutor.java
diff --git a/src/main/java/fr/xephi/authme/process/register/executors/RegistrationMethod.java b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/RegistrationMethod.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/executors/RegistrationMethod.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/executors/RegistrationMethod.java
diff --git a/src/main/java/fr/xephi/authme/process/register/executors/RegistrationParameters.java b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/RegistrationParameters.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/executors/RegistrationParameters.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/executors/RegistrationParameters.java
diff --git a/src/main/java/fr/xephi/authme/process/register/executors/TwoFactorRegisterExecutor.java b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/TwoFactorRegisterExecutor.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/executors/TwoFactorRegisterExecutor.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/executors/TwoFactorRegisterExecutor.java
diff --git a/src/main/java/fr/xephi/authme/process/register/executors/TwoFactorRegisterParams.java b/authme-core/src/main/java/fr/xephi/authme/process/register/executors/TwoFactorRegisterParams.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/process/register/executors/TwoFactorRegisterParams.java
rename to authme-core/src/main/java/fr/xephi/authme/process/register/executors/TwoFactorRegisterParams.java
diff --git a/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java b/authme-core/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java
similarity index 93%
rename from src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java
rename to authme-core/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java
index 5d37c8ad6c..9da45221cd 100644
--- a/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java
+++ b/authme-core/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java
@@ -116,7 +116,8 @@ public void adminUnregister(CommandSender initiator, String name, Player player)
*/
private void performPostUnregisterActions(String name, Player player) {
if (player != null && playerCache.isAuthenticated(name)) {
- bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGOUT);
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player,
+ () -> bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGOUT));
}
playerCache.removePlayer(name);
@@ -125,13 +126,13 @@ private void performPostUnregisterActions(String name, Player player) {
if (player == null || !player.isOnline()) {
return;
}
- bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() ->
- commandManager.runCommandsOnUnregister(player));
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player,
+ () -> commandManager.runCommandsOnUnregister(player));
if (service.getProperty(RegistrationSettings.FORCE)) {
teleportationService.teleportOnJoin(player);
- bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> {
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player, () -> {
limboService.createLimboPlayer(player, false);
applyBlindEffect(player);
});
@@ -141,7 +142,7 @@ private void performPostUnregisterActions(String name, Player player) {
private void applyBlindEffect(Player player) {
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
- int timeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
+ int timeout = service.getProperty(RestrictionSettings.REGISTER_TIMEOUT) * TICKS_PER_SECOND;
player.addPotionEffect(bukkitService.createBlindnessEffect(timeout));
}
}
diff --git a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java b/authme-core/src/main/java/fr/xephi/authme/security/HashAlgorithm.java
similarity index 97%
rename from src/main/java/fr/xephi/authme/security/HashAlgorithm.java
rename to authme-core/src/main/java/fr/xephi/authme/security/HashAlgorithm.java
index 8f75e0b75c..6725404c37 100644
--- a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java
+++ b/authme-core/src/main/java/fr/xephi/authme/security/HashAlgorithm.java
@@ -18,6 +18,7 @@ public enum HashAlgorithm {
MD5VB(fr.xephi.authme.security.crypts.Md5vB.class),
MYBB(fr.xephi.authme.security.crypts.MyBB.class),
PBKDF2(fr.xephi.authme.security.crypts.Pbkdf2.class),
+ PBKDF2BASE64(fr.xephi.authme.security.crypts.Pbkdf2Base64.class),
PBKDF2DJANGO(fr.xephi.authme.security.crypts.Pbkdf2Django.class),
PHPBB(fr.xephi.authme.security.crypts.PhpBB.class),
PHPFUSION(fr.xephi.authme.security.crypts.PhpFusion.class),
diff --git a/src/main/java/fr/xephi/authme/security/HashUtils.java b/authme-core/src/main/java/fr/xephi/authme/security/HashUtils.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/HashUtils.java
rename to authme-core/src/main/java/fr/xephi/authme/security/HashUtils.java
diff --git a/src/main/java/fr/xephi/authme/security/MessageDigestAlgorithm.java b/authme-core/src/main/java/fr/xephi/authme/security/MessageDigestAlgorithm.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/MessageDigestAlgorithm.java
rename to authme-core/src/main/java/fr/xephi/authme/security/MessageDigestAlgorithm.java
diff --git a/src/main/java/fr/xephi/authme/security/PasswordSecurity.java b/authme-core/src/main/java/fr/xephi/authme/security/PasswordSecurity.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/PasswordSecurity.java
rename to authme-core/src/main/java/fr/xephi/authme/security/PasswordSecurity.java
diff --git a/authme-core/src/main/java/fr/xephi/authme/security/crypts/AbstractPbkdf2.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/AbstractPbkdf2.java
new file mode 100644
index 0000000000..4f8217b5a2
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/security/crypts/AbstractPbkdf2.java
@@ -0,0 +1,26 @@
+package fr.xephi.authme.security.crypts;
+
+import de.rtner.security.auth.spi.PBKDF2Engine;
+import de.rtner.security.auth.spi.PBKDF2Parameters;
+import fr.xephi.authme.settings.Settings;
+import fr.xephi.authme.settings.properties.SecuritySettings;
+
+public abstract class AbstractPbkdf2 extends HexSaltedMethod {
+
+ protected final int numberOfRounds;
+
+ protected AbstractPbkdf2(Settings settings, int defaultRounds) {
+ int configured = settings.getProperty(SecuritySettings.PBKDF2_NUMBER_OF_ROUNDS);
+ this.numberOfRounds = configured > 0 ? configured : defaultRounds;
+ }
+
+ protected byte[] deriveKey(String password, byte[] saltBytes, int iterations, int keyLength) {
+ PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "UTF-8", saltBytes, iterations);
+ return new PBKDF2Engine(params).deriveKey(password, keyLength);
+ }
+
+ protected boolean verifyKey(String password, byte[] saltBytes, int iterations, byte[] expectedKey) {
+ PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "UTF-8", saltBytes, iterations, expectedKey);
+ return new PBKDF2Engine(params).verifyKey(password);
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Argon2.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Argon2.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Argon2.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Argon2.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/BCrypt.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/BCrypt.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/BCrypt.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/BCrypt.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/BCrypt2y.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/BCrypt2y.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/BCrypt2y.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/BCrypt2y.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/BCryptBasedHash.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/BCryptBasedHash.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/BCryptBasedHash.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/BCryptBasedHash.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/BCryptHasher.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/BCryptHasher.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/BCryptHasher.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/BCryptHasher.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/CmwCrypt.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/CmwCrypt.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/CmwCrypt.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/CmwCrypt.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/CrazyCrypt1.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/CrazyCrypt1.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/CrazyCrypt1.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/CrazyCrypt1.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/DoubleMd5.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/DoubleMd5.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/DoubleMd5.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/DoubleMd5.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/EncryptionMethod.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/EncryptionMethod.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/EncryptionMethod.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/EncryptionMethod.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/HashedPassword.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/HashedPassword.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/HashedPassword.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/HashedPassword.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/HexSaltedMethod.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/HexSaltedMethod.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/HexSaltedMethod.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/HexSaltedMethod.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Ipb3.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Ipb3.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Ipb3.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Ipb3.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Ipb4.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Ipb4.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Ipb4.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Ipb4.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Joomla.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Joomla.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Joomla.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Joomla.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Md5.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Md5.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Md5.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Md5.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Md5vB.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Md5vB.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Md5vB.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Md5vB.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/MyBB.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/MyBB.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/MyBB.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/MyBB.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java
similarity index 54%
rename from src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java
index c79647ab79..2be6ad1560 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java
+++ b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java
@@ -2,37 +2,29 @@
import com.google.common.primitives.Ints;
import de.rtner.misc.BinTools;
-import de.rtner.security.auth.spi.PBKDF2Engine;
-import de.rtner.security.auth.spi.PBKDF2Parameters;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.Usage;
import fr.xephi.authme.settings.Settings;
-import fr.xephi.authme.settings.properties.SecuritySettings;
import javax.inject.Inject;
@Recommendation(Usage.RECOMMENDED)
-public class Pbkdf2 extends HexSaltedMethod {
+public class Pbkdf2 extends AbstractPbkdf2 {
private static final int DEFAULT_ROUNDS = 10_000;
private final ConsoleLogger logger = ConsoleLoggerFactory.get(Pbkdf2.class);
- private int numberOfRounds;
@Inject
Pbkdf2(Settings settings) {
- int configuredRounds = settings.getProperty(SecuritySettings.PBKDF2_NUMBER_OF_ROUNDS);
- this.numberOfRounds = configuredRounds > 0 ? configuredRounds : DEFAULT_ROUNDS;
+ super(settings, DEFAULT_ROUNDS);
}
@Override
public String computeHash(String password, String salt, String name) {
- String result = "pbkdf2_sha256$" + numberOfRounds + "$" + salt + "$";
- PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "UTF-8", salt.getBytes(), numberOfRounds);
- PBKDF2Engine engine = new PBKDF2Engine(params);
-
- return result + BinTools.bin2hex(engine.deriveKey(password, 64));
+ return "pbkdf2_sha256$" + numberOfRounds + "$" + salt + "$"
+ + BinTools.bin2hex(deriveKey(password, salt.getBytes(), numberOfRounds, 64));
}
@Override
@@ -46,12 +38,7 @@ public boolean comparePassword(String password, HashedPassword hashedPassword, S
logger.warning("Cannot read number of rounds for Pbkdf2: '" + line[1] + "'");
return false;
}
-
- String salt = line[2];
- byte[] derivedKey = BinTools.hex2bin(line[3]);
- PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "UTF-8", salt.getBytes(), iterations, derivedKey);
- PBKDF2Engine engine = new PBKDF2Engine(params);
- return engine.verifyKey(password);
+ return verifyKey(password, line[2].getBytes(), iterations, BinTools.hex2bin(line[3]));
}
@Override
diff --git a/authme-core/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Base64.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Base64.java
new file mode 100644
index 0000000000..d865566493
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Base64.java
@@ -0,0 +1,66 @@
+package fr.xephi.authme.security.crypts;
+
+import com.google.common.primitives.Ints;
+import fr.xephi.authme.ConsoleLogger;
+import fr.xephi.authme.output.ConsoleLoggerFactory;
+import fr.xephi.authme.security.crypts.description.Recommendation;
+import fr.xephi.authme.security.crypts.description.Usage;
+import fr.xephi.authme.settings.Settings;
+
+import javax.inject.Inject;
+import java.security.SecureRandom;
+import java.util.Base64;
+
+/**
+ * PBKDF2-HmacSHA256 with Base64-encoded salt and hash.
+ * Format: {@code pbkdf2$$$}
+ */
+@Recommendation(Usage.RECOMMENDED)
+public class Pbkdf2Base64 extends AbstractPbkdf2 {
+
+ private static final int DEFAULT_ROUNDS = 120_000;
+ private static final int SALT_BYTES = 16;
+ private static final int HASH_BYTES = 32;
+
+ private final ConsoleLogger logger = ConsoleLoggerFactory.get(Pbkdf2Base64.class);
+
+ @Inject
+ Pbkdf2Base64(Settings settings) {
+ super(settings, DEFAULT_ROUNDS);
+ }
+
+ @Override
+ public String computeHash(String password, String salt, String name) {
+ byte[] saltBytes = Base64.getDecoder().decode(salt);
+ byte[] hash = deriveKey(password, saltBytes, numberOfRounds, HASH_BYTES);
+ return "pbkdf2$" + numberOfRounds + "$" + salt + "$" + Base64.getEncoder().encodeToString(hash);
+ }
+
+ @Override
+ public boolean comparePassword(String password, HashedPassword hashedPassword, String unusedName) {
+ String[] parts = hashedPassword.getHash().split("\\$");
+ if (parts.length != 4) {
+ return false;
+ }
+ Integer iterations = Ints.tryParse(parts[1]);
+ if (iterations == null) {
+ logger.warning("Cannot read number of rounds for Pbkdf2Base64: '" + parts[1] + "'");
+ return false;
+ }
+ byte[] saltBytes = Base64.getDecoder().decode(parts[2]);
+ byte[] expectedKey = Base64.getDecoder().decode(parts[3]);
+ return verifyKey(password, saltBytes, iterations, expectedKey);
+ }
+
+ @Override
+ public String generateSalt() {
+ byte[] salt = new byte[SALT_BYTES];
+ new SecureRandom().nextBytes(salt);
+ return Base64.getEncoder().encodeToString(salt);
+ }
+
+ @Override
+ public int getSaltLength() {
+ return SALT_BYTES;
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/PhpBB.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/PhpBB.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/PhpBB.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/PhpBB.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/PhpFusion.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/PhpFusion.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/PhpFusion.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/PhpFusion.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/RoyalAuth.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/RoyalAuth.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/RoyalAuth.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/RoyalAuth.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Salted2Md5.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Salted2Md5.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Salted2Md5.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Salted2Md5.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/SaltedSha512.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/SaltedSha512.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/SaltedSha512.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/SaltedSha512.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/SeparateSaltMethod.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/SeparateSaltMethod.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/SeparateSaltMethod.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/SeparateSaltMethod.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Sha1.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Sha1.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Sha1.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Sha1.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Sha256.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Sha256.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Sha256.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Sha256.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Sha512.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Sha512.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Sha512.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Sha512.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Smf.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Smf.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Smf.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Smf.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/TwoFactor.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/TwoFactor.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/TwoFactor.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/TwoFactor.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/UnsaltedMethod.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/UnsaltedMethod.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/UnsaltedMethod.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/UnsaltedMethod.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/UsernameSaltMethod.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/UsernameSaltMethod.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/UsernameSaltMethod.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/UsernameSaltMethod.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Wbb3.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Wbb3.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Wbb3.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Wbb3.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Wbb4.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Wbb4.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Wbb4.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Wbb4.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/Wordpress.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/Wordpress.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/Wordpress.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/Wordpress.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/XfBCrypt.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/XfBCrypt.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/XfBCrypt.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/XfBCrypt.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/description/AsciiRestricted.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/description/AsciiRestricted.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/description/AsciiRestricted.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/description/AsciiRestricted.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/description/HasSalt.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/description/HasSalt.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/description/HasSalt.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/description/HasSalt.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/description/Recommendation.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/description/Recommendation.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/description/Recommendation.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/description/Recommendation.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/description/SaltType.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/description/SaltType.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/description/SaltType.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/description/SaltType.java
diff --git a/src/main/java/fr/xephi/authme/security/crypts/description/Usage.java b/authme-core/src/main/java/fr/xephi/authme/security/crypts/description/Usage.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/crypts/description/Usage.java
rename to authme-core/src/main/java/fr/xephi/authme/security/crypts/description/Usage.java
diff --git a/src/main/java/fr/xephi/authme/security/totp/GenerateTotpService.java b/authme-core/src/main/java/fr/xephi/authme/security/totp/GenerateTotpService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/totp/GenerateTotpService.java
rename to authme-core/src/main/java/fr/xephi/authme/security/totp/GenerateTotpService.java
diff --git a/src/main/java/fr/xephi/authme/security/totp/TotpAuthenticator.java b/authme-core/src/main/java/fr/xephi/authme/security/totp/TotpAuthenticator.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/security/totp/TotpAuthenticator.java
rename to authme-core/src/main/java/fr/xephi/authme/security/totp/TotpAuthenticator.java
diff --git a/src/main/java/fr/xephi/authme/service/AntiBotService.java b/authme-core/src/main/java/fr/xephi/authme/service/AntiBotService.java
similarity index 83%
rename from src/main/java/fr/xephi/authme/service/AntiBotService.java
rename to authme-core/src/main/java/fr/xephi/authme/service/AntiBotService.java
index abe987b701..6bcf536603 100644
--- a/src/main/java/fr/xephi/authme/service/AntiBotService.java
+++ b/authme-core/src/main/java/fr/xephi/authme/service/AntiBotService.java
@@ -8,7 +8,7 @@
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.ProtectionSettings;
import fr.xephi.authme.util.AtomicIntervalCounter;
-import org.bukkit.scheduler.BukkitTask;
+import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.util.Locale;
@@ -32,7 +32,7 @@ public class AntiBotService implements SettingsDependent {
// Service status
private AntiBotStatus antiBotStatus;
private boolean startup;
- private BukkitTask disableTask;
+ private CancellableTask disableTask;
private AtomicIntervalCounter flaggedCounter;
@Inject
@@ -73,7 +73,7 @@ public void reload(Settings settings) {
// Delay the schedule on first start
if (startup) {
int delay = settings.getProperty(ProtectionSettings.ANTIBOT_DELAY);
- bukkitService.scheduleSyncDelayedTask(enableTask, delay * TICKS_PER_SECOND);
+ bukkitService.runTaskLaterOnGlobalRegion(enableTask, delay * TICKS_PER_SECOND);
startup = false;
} else {
enableTask.run();
@@ -91,14 +91,9 @@ private void startProtection() {
disableTask.cancel();
}
// Schedule auto-disable
- disableTask = bukkitService.runTaskLater(this::stopProtection, duration * TICKS_PER_MINUTE);
+ disableTask = bukkitService.runTaskLaterOnGlobalRegion(this::stopProtection, duration * TICKS_PER_MINUTE);
antiBotStatus = AntiBotStatus.ACTIVE;
- bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> {
- // Inform admins
- bukkitService.getOnlinePlayers().stream()
- .filter(player -> permissionsManager.hasPermission(player, AdminPermission.ANTIBOT_MESSAGES))
- .forEach(player -> messages.send(player, MessageKey.ANTIBOT_AUTO_ENABLED_MESSAGE));
- });
+ notifyAdmins(MessageKey.ANTIBOT_AUTO_ENABLED_MESSAGE);
}
/**
@@ -119,10 +114,7 @@ private void stopProtection() {
disableTask = null;
// Inform admins
- String durationString = Integer.toString(duration);
- bukkitService.getOnlinePlayers().stream()
- .filter(player -> permissionsManager.hasPermission(player, AdminPermission.ANTIBOT_MESSAGES))
- .forEach(player -> messages.send(player, MessageKey.ANTIBOT_AUTO_DISABLED_MESSAGE, durationString));
+ notifyAdmins(MessageKey.ANTIBOT_AUTO_DISABLED_MESSAGE, Integer.toString(duration));
}
/**
@@ -190,6 +182,21 @@ public void addPlayerKick(String name) {
antibotKicked.addIfAbsent(name.toLowerCase(Locale.ROOT));
}
+ private void notifyAdmins(MessageKey key, String... args) {
+ bukkitService.runOnGlobalRegion(() -> {
+ Object[] players = bukkitService.getOnlinePlayers().toArray();
+ for (Object onlinePlayer : players) {
+ if (onlinePlayer instanceof Player player) {
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player, () -> {
+ if (permissionsManager.hasPermission(player, AdminPermission.ANTIBOT_MESSAGES)) {
+ messages.send(player, key, args);
+ }
+ });
+ }
+ }
+ });
+ }
+
public enum AntiBotStatus {
LISTENING,
DISABLED,
diff --git a/src/main/java/fr/xephi/authme/service/BackupService.java b/authme-core/src/main/java/fr/xephi/authme/service/BackupService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/BackupService.java
rename to authme-core/src/main/java/fr/xephi/authme/service/BackupService.java
diff --git a/src/main/java/fr/xephi/authme/service/BukkitService.java b/authme-core/src/main/java/fr/xephi/authme/service/BukkitService.java
similarity index 73%
rename from src/main/java/fr/xephi/authme/service/BukkitService.java
rename to authme-core/src/main/java/fr/xephi/authme/service/BukkitService.java
index 8864a902ef..8690ddd302 100644
--- a/src/main/java/fr/xephi/authme/service/BukkitService.java
+++ b/authme-core/src/main/java/fr/xephi/authme/service/BukkitService.java
@@ -2,15 +2,18 @@
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.initialization.SettingsDependent;
+import fr.xephi.authme.platform.SchedulingAdapter;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
import org.bukkit.BanEntry;
import org.bukkit.BanList;
import org.bukkit.Bukkit;
+import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.potion.PotionEffect;
@@ -20,10 +23,13 @@
import javax.inject.Inject;
import java.util.Collection;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
import java.util.Date;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
+import java.util.function.Supplier;
/**
* Service for operations requiring the Bukkit API, such as for scheduling.
@@ -36,11 +42,13 @@ public class BukkitService implements SettingsDependent {
public static final int TICKS_PER_MINUTE = 60 * TICKS_PER_SECOND;
private final AuthMe authMe;
+ private final SchedulingAdapter schedulingAdapter;
private boolean useAsyncTasks;
@Inject
- BukkitService(AuthMe authMe, Settings settings) {
+ BukkitService(AuthMe authMe, Settings settings, SchedulingAdapter schedulingAdapter) {
this.authMe = authMe;
+ this.schedulingAdapter = schedulingAdapter;
reload(settings);
}
@@ -69,6 +77,31 @@ public int scheduleSyncDelayedTask(Runnable task, long delay) {
return Bukkit.getScheduler().scheduleSyncDelayedTask(authMe, task, delay);
}
+ /**
+ * Schedules a task on the owning thread of the given entity.
+ *
+ * @param entity the entity whose scheduler should own the task
+ * @param task the task to run
+ */
+ public void scheduleSyncTaskFromOptionallyAsyncTask(Entity entity, Runnable task) {
+ if (schedulingAdapter.isOwnedByCurrentThread(entity)) {
+ task.run();
+ return;
+ }
+ schedulingAdapter.runOnEntityThread(authMe, entity, task);
+ }
+
+ /**
+ * Schedules a delayed task on the owning thread of the given entity.
+ *
+ * @param entity the entity whose scheduler should own the task
+ * @param task the task to run
+ * @param delay the delay in ticks
+ */
+ public void scheduleSyncDelayedTask(Entity entity, Runnable task, long delay) {
+ runTaskLater(entity, task, delay);
+ }
+
/**
* Schedules a synchronous task if we are currently on a async thread; if not, it runs the task immediately.
* Use this when {@link #runTaskOptionallyAsync(Runnable) optionally asynchronous tasks} have to
@@ -77,10 +110,50 @@ public int scheduleSyncDelayedTask(Runnable task, long delay) {
* @param task the task to be run
*/
public void scheduleSyncTaskFromOptionallyAsyncTask(Runnable task) {
- if (Bukkit.isPrimaryThread()) {
+ if (schedulingAdapter.isGlobalThread()) {
task.run();
} else {
- scheduleSyncDelayedTask(task);
+ runOnGlobalRegion(task);
+ }
+ }
+
+ /**
+ * Runs the given supplier on the main thread if necessary and returns its result.
+ *
+ * @param supplier the supplier to run
+ * @param the return type
+ * @return the supplier's result
+ */
+ public T callSyncMethodFromOptionallyAsyncTask(Supplier supplier) {
+ if (schedulingAdapter.isGlobalThread()) {
+ return supplier.get();
+ }
+
+ CompletableFuture future = new CompletableFuture<>();
+ runOnGlobalRegion(() -> {
+ try {
+ future.complete(supplier.get());
+ } catch (RuntimeException e) {
+ future.completeExceptionally(e);
+ } catch (Error e) {
+ future.completeExceptionally(e);
+ }
+ });
+
+ try {
+ return future.get();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new IllegalStateException("Interrupted while waiting for sync task", e);
+ } catch (ExecutionException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof RuntimeException) {
+ throw (RuntimeException) cause;
+ }
+ if (cause instanceof Error) {
+ throw (Error) cause;
+ }
+ throw new IllegalStateException("Unexpected exception while waiting for sync task", cause);
}
}
@@ -110,6 +183,18 @@ public BukkitTask runTaskLater(Runnable task, long delay) {
return Bukkit.getScheduler().runTaskLater(authMe, task, delay);
}
+ /**
+ * Schedules a delayed task on the owning thread of the given entity.
+ *
+ * @param entity the entity whose scheduler should own the task
+ * @param task the task to run
+ * @param delay the delay in ticks
+ * @return the scheduled task handle
+ */
+ public CancellableTask runTaskLater(Entity entity, Runnable task, long delay) {
+ return schedulingAdapter.runDelayedOnEntityThread(authMe, entity, task, delay);
+ }
+
/**
* Schedules this task to run asynchronously or immediately executes it based on
* AuthMe's configuration.
@@ -173,6 +258,43 @@ public BukkitTask runTaskTimer(BukkitRunnable task, long delay, long period) {
return task.runTaskTimer(authMe, delay, period);
}
+ /**
+ * Schedules a repeating task on the owning thread of the given entity.
+ *
+ * @param entity the entity whose scheduler should own the task
+ * @param task the task to schedule
+ * @param delay the initial delay in ticks
+ * @param period the repeat period in ticks
+ * @return the scheduled task handle
+ */
+ public CancellableTask runTaskTimer(Entity entity, Runnable task, long delay, long period) {
+ return schedulingAdapter.runAtFixedRateOnEntityThread(authMe, entity, task, delay, period);
+ }
+
+ /**
+ * Schedules a task on the global region.
+ *
+ * @param task the task to run
+ */
+ public void runOnGlobalRegion(Runnable task) {
+ if (schedulingAdapter.isGlobalThread()) {
+ task.run();
+ return;
+ }
+ schedulingAdapter.runOnGlobalThread(authMe, task);
+ }
+
+ /**
+ * Schedules a delayed task on the global region.
+ *
+ * @param task the task to run
+ * @param delay the delay in ticks
+ * @return the scheduled task handle
+ */
+ public CancellableTask runTaskLaterOnGlobalRegion(Runnable task, long delay) {
+ return schedulingAdapter.runDelayedOnGlobalThread(authMe, task, delay);
+ }
+
/**
* Broadcast a message to all players.
*
diff --git a/authme-core/src/main/java/fr/xephi/authme/service/CancellableTask.java b/authme-core/src/main/java/fr/xephi/authme/service/CancellableTask.java
new file mode 100644
index 0000000000..46a6342fab
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/service/CancellableTask.java
@@ -0,0 +1,7 @@
+package fr.xephi.authme.service;
+
+@FunctionalInterface
+public interface CancellableTask {
+
+ void cancel();
+}
diff --git a/src/main/java/fr/xephi/authme/service/CommonService.java b/authme-core/src/main/java/fr/xephi/authme/service/CommonService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/CommonService.java
rename to authme-core/src/main/java/fr/xephi/authme/service/CommonService.java
diff --git a/src/main/java/fr/xephi/authme/service/GeoIpService.java b/authme-core/src/main/java/fr/xephi/authme/service/GeoIpService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/GeoIpService.java
rename to authme-core/src/main/java/fr/xephi/authme/service/GeoIpService.java
diff --git a/src/main/java/fr/xephi/authme/service/HelpTranslationGenerator.java b/authme-core/src/main/java/fr/xephi/authme/service/HelpTranslationGenerator.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/HelpTranslationGenerator.java
rename to authme-core/src/main/java/fr/xephi/authme/service/HelpTranslationGenerator.java
diff --git a/src/main/java/fr/xephi/authme/service/JoinMessageService.java b/authme-core/src/main/java/fr/xephi/authme/service/JoinMessageService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/JoinMessageService.java
rename to authme-core/src/main/java/fr/xephi/authme/service/JoinMessageService.java
diff --git a/src/main/java/fr/xephi/authme/service/MigrationService.java b/authme-core/src/main/java/fr/xephi/authme/service/MigrationService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/MigrationService.java
rename to authme-core/src/main/java/fr/xephi/authme/service/MigrationService.java
diff --git a/src/main/java/fr/xephi/authme/service/PasswordRecoveryService.java b/authme-core/src/main/java/fr/xephi/authme/service/PasswordRecoveryService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/PasswordRecoveryService.java
rename to authme-core/src/main/java/fr/xephi/authme/service/PasswordRecoveryService.java
diff --git a/src/main/java/fr/xephi/authme/service/PluginHookService.java b/authme-core/src/main/java/fr/xephi/authme/service/PluginHookService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/PluginHookService.java
rename to authme-core/src/main/java/fr/xephi/authme/service/PluginHookService.java
diff --git a/src/main/java/fr/xephi/authme/service/RecoveryCodeService.java b/authme-core/src/main/java/fr/xephi/authme/service/RecoveryCodeService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/RecoveryCodeService.java
rename to authme-core/src/main/java/fr/xephi/authme/service/RecoveryCodeService.java
diff --git a/src/main/java/fr/xephi/authme/service/SessionService.java b/authme-core/src/main/java/fr/xephi/authme/service/SessionService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/SessionService.java
rename to authme-core/src/main/java/fr/xephi/authme/service/SessionService.java
diff --git a/src/main/java/fr/xephi/authme/service/SessionState.java b/authme-core/src/main/java/fr/xephi/authme/service/SessionState.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/SessionState.java
rename to authme-core/src/main/java/fr/xephi/authme/service/SessionState.java
diff --git a/authme-core/src/main/java/fr/xephi/authme/service/TeleportationService.java b/authme-core/src/main/java/fr/xephi/authme/service/TeleportationService.java
new file mode 100644
index 0000000000..84c3837787
--- /dev/null
+++ b/authme-core/src/main/java/fr/xephi/authme/service/TeleportationService.java
@@ -0,0 +1,402 @@
+package fr.xephi.authme.service;
+
+import fr.xephi.authme.ConsoleLogger;
+import fr.xephi.authme.data.auth.PlayerAuth;
+import fr.xephi.authme.data.auth.PlayerCache;
+import fr.xephi.authme.data.limbo.LimboPlayer;
+import fr.xephi.authme.datasource.DataSource;
+import fr.xephi.authme.events.AbstractTeleportEvent;
+import fr.xephi.authme.events.AuthMeTeleportEvent;
+import fr.xephi.authme.events.FirstSpawnTeleportEvent;
+import fr.xephi.authme.events.SpawnTeleportEvent;
+import fr.xephi.authme.initialization.Reloadable;
+import fr.xephi.authme.output.ConsoleLoggerFactory;
+import fr.xephi.authme.platform.TeleportAdapter;
+import fr.xephi.authme.settings.Settings;
+import fr.xephi.authme.settings.SpawnLoader;
+import fr.xephi.authme.settings.properties.RegistrationSettings;
+import fr.xephi.authme.settings.properties.RestrictionSettings;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static fr.xephi.authme.settings.properties.RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN;
+
+/**
+ * Handles teleportation (placement of player to spawn).
+ */
+public class TeleportationService implements Reloadable {
+
+ private final ConsoleLogger logger = ConsoleLoggerFactory.get(TeleportationService.class);
+
+ @Inject
+ private Settings settings;
+
+ @Inject
+ private BukkitService bukkitService;
+
+ @Inject
+ private SpawnLoader spawnLoader;
+
+ @Inject
+ private PlayerCache playerCache;
+
+ @Inject
+ private DataSource dataSource;
+
+ @Inject
+ private TeleportAdapter teleportAdapter;
+
+ private Set spawnOnLoginWorlds;
+ private final ConcurrentHashMap preloadedAuthStatus = new ConcurrentHashMap<>();
+ private final ConcurrentHashMap originalJoinLocations = new ConcurrentHashMap<>();
+
+ TeleportationService() {
+ }
+
+ @PostConstruct
+ @Override
+ public void reload() {
+ // Use a Set for better performance with #contains()
+ spawnOnLoginWorlds = new HashSet<>(settings.getProperty(RestrictionSettings.FORCE_SPAWN_ON_WORLDS));
+ }
+
+ /**
+ * Teleports the player according to the settings when he joins.
+ *
+ * @param player the player to process
+ */
+ public void teleportOnJoin(final Player player) {
+ if (!settings.getProperty(RestrictionSettings.NO_TELEPORT)
+ && settings.getProperty(TELEPORT_UNAUTHED_TO_SPAWN)
+ && !isUnregisteredWithOptionalAuth(player.getName())) {
+ logger.debug("Teleport on join for player `{0}`", player.getName());
+ teleportToSpawn(player, playerCache.isAuthenticated(player.getName()));
+ }
+ }
+
+ /**
+ * Returns the player's custom on join location.
+ *
+ * @param player the player to process
+ *
+ * @return the custom spawn location, null if the player should spawn at the original location
+ */
+ public Location prepareOnJoinSpawnLocation(final Player player) {
+ return prepareOnJoinSpawnLocation(player, null);
+ }
+
+ /**
+ * Returns the player's custom on join location and stores the original spawn location for later restoration.
+ *
+ * @param player the player to process
+ * @param originalLocation the server-selected spawn location before AuthMe modifies it
+ * @return the custom spawn location, null if the player should spawn at the original location
+ */
+ public Location prepareOnJoinSpawnLocation(final Player player, final Location originalLocation) {
+ rememberOriginalJoinLocation(player.getName(), originalLocation);
+ if (shouldApplyOnJoinSpawnLocation(player.getName())) {
+ final Location location = spawnLoader.getSpawnLocation(player);
+
+ SpawnTeleportEvent event = new SpawnTeleportEvent(player, location,
+ playerCache.isAuthenticated(player.getName()));
+ bukkitService.callEvent(event);
+ if (!isEventValid(event)) {
+ return null;
+ }
+
+ logger.debug("Returning custom location for join event for player `{0}`", player.getName());
+ return event.getTo();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the player's custom on join location without requiring a {@link Player} instance.
+ * Intended for platform hooks that run before the player object is available.
+ *
+ * @param playerName the player's name
+ * @param world the world the player is about to join in
+ * @return the custom spawn location, null if the player should spawn at the original location
+ */
+ public Location prepareOnJoinSpawnLocation(String playerName, World world) {
+ return prepareOnJoinSpawnLocationInternal(playerName, world);
+ }
+
+ /**
+ * Returns the player's custom on join location without requiring a {@link Player} instance and stores the
+ * original spawn location for later restoration.
+ *
+ * @param playerName the player's name
+ * @param originalLocation the server-selected spawn location before AuthMe modifies it
+ * @return the custom spawn location, null if the player should spawn at the original location
+ */
+ public Location prepareOnJoinSpawnLocation(String playerName, Location originalLocation) {
+ rememberOriginalJoinLocation(playerName, originalLocation);
+ return prepareOnJoinSpawnLocationInternal(playerName,
+ originalLocation == null ? null : originalLocation.getWorld());
+ }
+
+ private Location prepareOnJoinSpawnLocationInternal(String playerName, World world) {
+ if (!shouldApplyOnJoinSpawnLocation(playerName) || world == null) {
+ return null;
+ }
+
+ logger.debug("Returning custom location for async join event for player `{0}`", playerName);
+ return spawnLoader.getSpawnLocation(world);
+ }
+
+ /**
+ * Teleports the player to the first spawn if he is new and the first spawn is configured.
+ *
+ * @param player the player to process
+ */
+ public void teleportNewPlayerToFirstSpawn(final Player player) {
+ if (settings.getProperty(RestrictionSettings.NO_TELEPORT)) {
+ return;
+ }
+
+ Location firstSpawn = spawnLoader.getFirstSpawn();
+ if (firstSpawn == null) {
+ return;
+ }
+
+ if (!player.hasPlayedBefore() || !dataSource.isAuthAvailable(player.getName())) {
+ logger.debug("Attempting to teleport player `{0}` to first spawn", player.getName());
+ performTeleportation(player, new FirstSpawnTeleportEvent(player, firstSpawn));
+ }
+ }
+
+ /**
+ * Teleports the player according to the settings after having successfully logged in.
+ *
+ * @param player the player
+ * @param auth corresponding PlayerAuth object
+ * @param limbo corresponding LimboPlayer object
+ */
+ public void teleportOnLogin(final Player player, PlayerAuth auth, LimboPlayer limbo) {
+ if (settings.getProperty(RestrictionSettings.NO_TELEPORT)) {
+ return;
+ }
+
+ // #856: If LimboPlayer comes from a persisted file, the Location might be null
+ Location joinLocation = limbo != null && limbo.getLocation() != null
+ ? limbo.getLocation()
+ : peekOriginalJoinLocation(player.getName());
+ String worldName = (joinLocation != null && joinLocation.getWorld() != null)
+ ? joinLocation.getWorld().getName()
+ : null;
+
+ // The world in LimboPlayer is from where the player comes, before any teleportation by AuthMe
+ if (mustForceSpawnAfterLogin(worldName)) {
+ logger.debug("Teleporting `{0}` to spawn because of 'force-spawn after login'", player.getName());
+ teleportToSpawn(player, true);
+ } else if (settings.getProperty(TELEPORT_UNAUTHED_TO_SPAWN)) {
+ if (settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
+ Location location = buildLocationFromAuth(player, auth);
+ if (shouldUseJoinLocationAsFallback(auth, joinLocation)) {
+ logger.debug("Teleporting `{0}` after login, based on the remembered join location",
+ player.getName());
+ location = joinLocation;
+ } else {
+ logger.debug("Teleporting `{0}` after login, based on the player auth", player.getName());
+ }
+ if (hasSamePositionAndWorld(location, player.getLocation())) {
+ logger.debug("Skipping teleport of `{0}` after login because the player is already there",
+ player.getName());
+ return;
+ }
+ teleportBackFromSpawn(player, location);
+ } else if (joinLocation != null) {
+ logger.debug("Teleporting `{0}` after login, based on the remembered join location", player.getName());
+ teleportBackFromSpawn(player, joinLocation);
+ }
+ }
+ }
+
+ /**
+ * Caches the player's registration status from the async pre-login event to avoid a blocking
+ * DB call on the main thread later. Must be cleared with {@link #clearPreloadedAuthStatus}.
+ *
+ * @param name the player name (case-insensitive)
+ * @param isRegistered whether the player has an account
+ */
+ public void preloadAuthStatus(String name, boolean isRegistered) {
+ String normalizedName = normalizePlayerName(name);
+ if (normalizedName != null) {
+ preloadedAuthStatus.put(normalizedName, isRegistered);
+ }
+ }
+
+ /**
+ * Clears the pre-loaded registration status for the given player after it has been consumed.
+ *
+ * @param name the player name
+ */
+ public void clearPreloadedAuthStatus(String name) {
+ String normalizedName = normalizePlayerName(name);
+ if (normalizedName != null) {
+ preloadedAuthStatus.remove(normalizedName);
+ }
+ }
+
+ /**
+ * Stores the server-selected join location before AuthMe redirects the player to its configured spawn.
+ *
+ * @param name the player name
+ * @param location the original join location
+ */
+ public void rememberOriginalJoinLocation(String name, Location location) {
+ String normalizedName = normalizePlayerName(name);
+ if (normalizedName == null) {
+ return;
+ }
+ if (location == null || location.getWorld() == null) {
+ clearOriginalJoinLocation(normalizedName);
+ return;
+ }
+ originalJoinLocations.put(normalizedName, location.clone());
+ }
+
+ /**
+ * Returns the remembered original join location without consuming it.
+ *
+ * @param name the player name
+ * @return the remembered location, or null if none exists
+ */
+ public Location peekOriginalJoinLocation(String name) {
+ String normalizedName = normalizePlayerName(name);
+ return normalizedName == null ? null : originalJoinLocations.get(normalizedName);
+ }
+
+ /**
+ * Returns and clears the remembered original join location for the player.
+ *
+ * @param name the player name
+ * @param fallback the location to return if no join location was remembered
+ * @return the remembered location, or the fallback if absent
+ */
+ public Location consumeOriginalJoinLocation(String name, Location fallback) {
+ String normalizedName = normalizePlayerName(name);
+ if (normalizedName == null) {
+ return fallback;
+ }
+ Location location = originalJoinLocations.remove(normalizedName);
+ return location != null ? location : fallback;
+ }
+
+ /**
+ * Clears the remembered original join location for the given player.
+ *
+ * @param name the player name
+ */
+ public void clearOriginalJoinLocation(String name) {
+ String normalizedName = normalizePlayerName(name);
+ if (normalizedName != null) {
+ originalJoinLocations.remove(normalizedName);
+ }
+ }
+
+ private boolean shouldApplyOnJoinSpawnLocation(String playerName) {
+ return !settings.getProperty(RestrictionSettings.NO_TELEPORT)
+ && settings.getProperty(TELEPORT_UNAUTHED_TO_SPAWN)
+ && !isUnregisteredWithOptionalAuth(playerName);
+ }
+
+ private boolean isUnregisteredWithOptionalAuth(String playerName) {
+ if (settings.getProperty(RegistrationSettings.FORCE)) {
+ return false;
+ }
+ String key = normalizePlayerName(playerName);
+ if (key == null) {
+ return false;
+ }
+ Boolean cached = preloadedAuthStatus.get(key);
+ boolean isRegistered = cached != null ? cached : dataSource.isAuthAvailable(playerName);
+ return !isRegistered;
+ }
+
+ private boolean mustForceSpawnAfterLogin(String worldName) {
+ return worldName != null && settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)
+ && spawnOnLoginWorlds.contains(worldName);
+ }
+
+ private static boolean shouldUseJoinLocationAsFallback(PlayerAuth auth, Location joinLocation) {
+ return joinLocation != null
+ && hasDefaultStoredQuitLocation(auth)
+ && !matchesStoredQuitLocation(auth, joinLocation);
+ }
+
+ private Location buildLocationFromAuth(Player player, PlayerAuth auth) {
+ World world = bukkitService.getWorld(auth.getWorld());
+ if (world == null) {
+ world = player.getWorld();
+ }
+ return new Location(world, auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ(),
+ auth.getYaw(), auth.getPitch());
+ }
+
+ private static boolean hasDefaultStoredQuitLocation(PlayerAuth auth) {
+ return auth != null
+ && Double.compare(auth.getQuitLocX(), 0.0) == 0
+ && Double.compare(auth.getQuitLocY(), 0.0) == 0
+ && Double.compare(auth.getQuitLocZ(), 0.0) == 0
+ && "world".equals(auth.getWorld());
+ }
+
+ private static boolean matchesStoredQuitLocation(PlayerAuth auth, Location location) {
+ return location != null && location.getWorld() != null
+ && Double.compare(auth.getQuitLocX(), location.getX()) == 0
+ && Double.compare(auth.getQuitLocY(), location.getY()) == 0
+ && Double.compare(auth.getQuitLocZ(), location.getZ()) == 0
+ && auth.getWorld().equals(location.getWorld().getName());
+ }
+
+ private static String normalizePlayerName(String name) {
+ return name == null ? null : name.toLowerCase(Locale.ROOT);
+ }
+
+ private static boolean hasSamePositionAndWorld(Location first, Location second) {
+ return first != null && second != null
+ && Double.compare(first.getX(), second.getX()) == 0
+ && Double.compare(first.getY(), second.getY()) == 0
+ && Double.compare(first.getZ(), second.getZ()) == 0
+ && first.getWorld() == second.getWorld();
+ }
+
+ private void teleportBackFromSpawn(final Player player, final Location location) {
+ performTeleportation(player, new AuthMeTeleportEvent(player, location));
+ }
+
+ private void teleportToSpawn(final Player player, final boolean isAuthenticated) {
+ final Location spawnLoc = spawnLoader.getSpawnLocation(player);
+ performTeleportation(player, new SpawnTeleportEvent(player, spawnLoc, isAuthenticated));
+ }
+
+ /**
+ * Emits the teleportation event and performs teleportation according to it (potentially modified
+ * by external listeners). Note that no teleportation is performed if the event's location is empty.
+ *
+ * @param player the player to teleport
+ * @param event the event to emit and according to which to teleport
+ */
+ private void performTeleportation(final Player player, final AbstractTeleportEvent event) {
+ bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(player, () -> {
+ bukkitService.callEvent(event);
+ if (player.isOnline() && isEventValid(event)) {
+ teleportAdapter.teleportPlayer(player, event.getTo());
+ }
+ });
+ }
+
+ private static boolean isEventValid(AbstractTeleportEvent event) {
+ return !event.isCancelled() && event.getTo() != null && event.getTo().getWorld() != null;
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/service/ValidationService.java b/authme-core/src/main/java/fr/xephi/authme/service/ValidationService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/ValidationService.java
rename to authme-core/src/main/java/fr/xephi/authme/service/ValidationService.java
diff --git a/src/main/java/fr/xephi/authme/service/bungeecord/BungeeReceiver.java b/authme-core/src/main/java/fr/xephi/authme/service/bungeecord/BungeeReceiver.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/bungeecord/BungeeReceiver.java
rename to authme-core/src/main/java/fr/xephi/authme/service/bungeecord/BungeeReceiver.java
diff --git a/src/main/java/fr/xephi/authme/service/bungeecord/BungeeSender.java b/authme-core/src/main/java/fr/xephi/authme/service/bungeecord/BungeeSender.java
similarity index 98%
rename from src/main/java/fr/xephi/authme/service/bungeecord/BungeeSender.java
rename to authme-core/src/main/java/fr/xephi/authme/service/bungeecord/BungeeSender.java
index 3d43605bba..b57c946332 100644
--- a/src/main/java/fr/xephi/authme/service/bungeecord/BungeeSender.java
+++ b/authme-core/src/main/java/fr/xephi/authme/service/bungeecord/BungeeSender.java
@@ -85,7 +85,7 @@ public void connectPlayerOnLogin(Player player) {
return;
}
// Add a small delay, just in case...
- bukkitService.scheduleSyncDelayedTask(() ->
+ bukkitService.scheduleSyncDelayedTask(player, () ->
sendBungeecordMessage(player, "Connect", destinationServerOnLogin), 10L);
}
diff --git a/src/main/java/fr/xephi/authme/service/bungeecord/MessageType.java b/authme-core/src/main/java/fr/xephi/authme/service/bungeecord/MessageType.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/bungeecord/MessageType.java
rename to authme-core/src/main/java/fr/xephi/authme/service/bungeecord/MessageType.java
diff --git a/src/main/java/fr/xephi/authme/service/yaml/YamlFileResourceProvider.java b/authme-core/src/main/java/fr/xephi/authme/service/yaml/YamlFileResourceProvider.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/yaml/YamlFileResourceProvider.java
rename to authme-core/src/main/java/fr/xephi/authme/service/yaml/YamlFileResourceProvider.java
diff --git a/src/main/java/fr/xephi/authme/service/yaml/YamlParseException.java b/authme-core/src/main/java/fr/xephi/authme/service/yaml/YamlParseException.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/service/yaml/YamlParseException.java
rename to authme-core/src/main/java/fr/xephi/authme/service/yaml/YamlParseException.java
diff --git a/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java b/authme-core/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/EnumSetProperty.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java
diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/authme-core/src/main/java/fr/xephi/authme/settings/Settings.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/Settings.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/Settings.java
diff --git a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java b/authme-core/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java
similarity index 91%
rename from src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java
index fe035a8b20..34e5b5c5ff 100644
--- a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java
+++ b/authme-core/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java
@@ -36,6 +36,8 @@
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS;
import static fr.xephi.authme.settings.properties.RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN;
import static fr.xephi.authme.settings.properties.RestrictionSettings.FORCE_SPAWN_ON_WORLDS;
+import static fr.xephi.authme.settings.properties.RestrictionSettings.LOGIN_TIMEOUT;
+import static fr.xephi.authme.settings.properties.RestrictionSettings.REGISTER_TIMEOUT;
/**
* Service for verifying that the configuration is up-to-date.
@@ -89,9 +91,39 @@ protected boolean performMigrations(PropertyReader reader, ConfigurationData con
| mergeAndMovePermissionGroupSettings(reader, configurationData)
| moveDeprecatedHashAlgorithmIntoLegacySection(reader, configurationData)
| moveSaltColumnConfigWithOtherColumnConfigs(reader, configurationData)
+ | migrateTimeoutToLoginAndRegisterTimeout(reader, configurationData)
|| hasDeprecatedProperties(reader);
}
+ /**
+ * Migrates the old combined {@code settings.restrictions.timeout} to the separate
+ * {@code loginTimeout} and {@code registerTimeout} settings, preserving the user's value.
+ *
+ * @param reader The property reader
+ * @param configData Configuration data
+ * @return True if a migration has been performed, false otherwise
+ */
+ private static boolean migrateTimeoutToLoginAndRegisterTimeout(PropertyReader reader,
+ ConfigurationData configData) {
+ Property oldTimeout = newProperty("settings.restrictions.timeout", 30);
+ PropertyValue oldValue = oldTimeout.determineValue(reader);
+ if (!oldValue.isValidInResource()) {
+ return false;
+ }
+ boolean changed = false;
+ if (!reader.contains(LOGIN_TIMEOUT.getPath())) {
+ logger.info("Migrating 'settings.restrictions.timeout' to '" + LOGIN_TIMEOUT.getPath() + "'");
+ configData.setValue(LOGIN_TIMEOUT, oldValue.getValue());
+ changed = true;
+ }
+ if (!reader.contains(REGISTER_TIMEOUT.getPath())) {
+ logger.info("Migrating 'settings.restrictions.timeout' to '" + REGISTER_TIMEOUT.getPath() + "'");
+ configData.setValue(REGISTER_TIMEOUT, oldValue.getValue());
+ changed = true;
+ }
+ return changed;
+ }
+
private static boolean hasDeprecatedProperties(PropertyReader reader) {
String[] deprecatedProperties = {
"Converter.Rakamak.newPasswordHash", "Hooks.chestshop", "Hooks.legacyChestshop", "Hooks.notifications",
@@ -101,7 +133,8 @@ private static boolean hasDeprecatedProperties(PropertyReader reader) {
"settings.restrictions.keepCollisionsDisabled", "settings.forceCommands", "settings.forceCommandsAsConsole",
"settings.forceRegisterCommands", "settings.forceRegisterCommandsAsConsole",
"settings.sessions.sessionExpireOnIpChange", "settings.restrictions.otherAccountsCmd",
- "settings.restrictions.otherAccountsCmdThreshold, DataSource.mySQLDriverClassName"};
+ "settings.restrictions.otherAccountsCmdThreshold, DataSource.mySQLDriverClassName",
+ "settings.restrictions.timeout"};
for (String deprecatedPath : deprecatedProperties) {
if (reader.contains(deprecatedPath)) {
return true;
diff --git a/src/main/java/fr/xephi/authme/settings/SettingsWarner.java b/authme-core/src/main/java/fr/xephi/authme/settings/SettingsWarner.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/SettingsWarner.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/SettingsWarner.java
diff --git a/src/main/java/fr/xephi/authme/settings/SpawnLoader.java b/authme-core/src/main/java/fr/xephi/authme/settings/SpawnLoader.java
similarity index 86%
rename from src/main/java/fr/xephi/authme/settings/SpawnLoader.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/SpawnLoader.java
index 47e9711de2..4fe2d0d8af 100644
--- a/src/main/java/fr/xephi/authme/settings/SpawnLoader.java
+++ b/authme-core/src/main/java/fr/xephi/authme/settings/SpawnLoader.java
@@ -4,6 +4,7 @@
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.output.ConsoleLoggerFactory;
+import fr.xephi.authme.platform.TeleportAdapter;
import fr.xephi.authme.service.PluginHookService;
import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
@@ -36,6 +37,7 @@ public class SpawnLoader implements Reloadable {
private final File authMeConfigurationFile;
private final Settings settings;
private final PluginHookService pluginHookService;
+ private final TeleportAdapter teleportAdapter;
private FileConfiguration authMeConfiguration;
private String[] spawnPriority;
private Location essentialsSpawn;
@@ -47,14 +49,17 @@ public class SpawnLoader implements Reloadable {
* @param pluginFolder The AuthMe data folder
* @param settings The setting instance
* @param pluginHookService The plugin hooks instance
+ * @param teleportAdapter The platform-specific teleport adapter
*/
@Inject
- SpawnLoader(@DataFolder File pluginFolder, Settings settings, PluginHookService pluginHookService) {
+ SpawnLoader(@DataFolder File pluginFolder, Settings settings, PluginHookService pluginHookService,
+ TeleportAdapter teleportAdapter) {
File spawnFile = new File(pluginFolder, "spawn.yml");
FileUtils.copyFileFromResource(spawnFile, "spawn.yml");
this.authMeConfigurationFile = spawnFile;
this.settings = settings;
this.pluginHookService = pluginHookService;
+ this.teleportAdapter = teleportAdapter;
reload();
}
@@ -171,11 +176,25 @@ public void unloadCmiSpawn() {
* @see RestrictionSettings#SPAWN_PRIORITY
*/
public Location getSpawnLocation(Player player) {
- if (player == null || player.getWorld() == null) {
+ if (player == null) {
+ return null;
+ }
+ return getSpawnLocation(player.getWorld());
+ }
+
+ /**
+ * Return the spawn location for the given world. The source of the spawn location varies
+ * depending on the spawn priority setting.
+ *
+ * @param world The world to retrieve the spawn point for
+ *
+ * @return The spawn location, or the default spawn location upon failure
+ */
+ public Location getSpawnLocation(World world) {
+ if (world == null) {
return null;
}
- World world = player.getWorld();
Location spawnLoc = null;
for (String priority : spawnPriority) {
switch (priority.toLowerCase(Locale.ROOT).trim()) {
@@ -222,13 +241,16 @@ public Location getSpawnLocation(Player player) {
}
/**
- * Checks if a given location is a valid spawn point [!= (0,0,0)].
+ * Checks if a given location is a valid spawn point [!= null && != (0,0,0)].
*
* @param location The location to check
*
* @return True upon success, false otherwise
*/
private boolean isValidSpawnPoint(Location location) {
+ if (location == null) {
+ return false;
+ }
if (location.getX() == 0 && location.getY() == 0 && location.getZ() == 0) {
return false;
}
@@ -275,11 +297,30 @@ private boolean saveAuthMeConfig() {
*/
public Location getPlayerLocationOrSpawn(Player player) {
if (player.getHealth() <= 0.0) {
- return getSpawnLocation(player);
+ return getPlayerRespawnLocationOrSpawn(player);
}
return player.getLocation();
}
+ /**
+ * Return the player's effective respawn location if available, or the configured spawn location as fallback.
+ *
+ * We need this extra check for players who die and disconnect before actually respawning: in that case we want
+ * to preserve the server's real respawn target instead of collapsing everything back to AuthMe's configured spawn.
+ * The version-specific API call lives in {@link TeleportAdapter}: legacy builds use bed spawn, newer builds can
+ * use {@code Player#getRespawnLocation()} directly.
+ *
+ * @param player player to retrieve
+ * @return the player's respawn location if available, otherwise the configured spawn
+ */
+ public Location getPlayerRespawnLocationOrSpawn(Player player) {
+ Location respawnLocation = teleportAdapter.getPlayerRespawnLocation(player);
+ if (respawnLocation != null && respawnLocation.getWorld() != null) {
+ return respawnLocation;
+ }
+ return getSpawnLocation(player);
+ }
+
/**
* Build a {@link Location} object from the given path in the file configuration.
*
diff --git a/src/main/java/fr/xephi/authme/settings/WelcomeMessageConfiguration.java b/authme-core/src/main/java/fr/xephi/authme/settings/WelcomeMessageConfiguration.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/WelcomeMessageConfiguration.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/WelcomeMessageConfiguration.java
diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/Command.java b/authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/Command.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/commandconfig/Command.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/Command.java
diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java b/authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java
diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java b/authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java
similarity index 98%
rename from src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java
index 1018da0a8e..2aa3203122 100644
--- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java
+++ b/authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java
@@ -129,7 +129,7 @@ private void executeCommands(Player player, List commands
if (predicate.test(cmd)) {
long delay = cmd.getDelay();
if (delay > 0) {
- bukkitService.scheduleSyncDelayedTask(() -> dispatchCommand(player, cmd), delay);
+ bukkitService.scheduleSyncDelayedTask(player, () -> dispatchCommand(player, cmd), delay);
} else {
dispatchCommand(player, cmd);
}
diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandMigrationService.java b/authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/CommandMigrationService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/commandconfig/CommandMigrationService.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/CommandMigrationService.java
diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java b/authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java
diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/Executor.java b/authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/Executor.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/commandconfig/Executor.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/Executor.java
diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/OnLoginCommand.java b/authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/OnLoginCommand.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/commandconfig/OnLoginCommand.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/commandconfig/OnLoginCommand.java
diff --git a/src/main/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetriever.java b/authme-core/src/main/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetriever.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetriever.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetriever.java
diff --git a/src/main/java/fr/xephi/authme/settings/properties/BackupSettings.java b/authme-core/src/main/java/fr/xephi/authme/settings/properties/BackupSettings.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/properties/BackupSettings.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/properties/BackupSettings.java
diff --git a/src/main/java/fr/xephi/authme/settings/properties/ConverterSettings.java b/authme-core/src/main/java/fr/xephi/authme/settings/properties/ConverterSettings.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/properties/ConverterSettings.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/properties/ConverterSettings.java
diff --git a/src/main/java/fr/xephi/authme/settings/properties/DatabaseSettings.java b/authme-core/src/main/java/fr/xephi/authme/settings/properties/DatabaseSettings.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/properties/DatabaseSettings.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/properties/DatabaseSettings.java
diff --git a/src/main/java/fr/xephi/authme/settings/properties/EmailSettings.java b/authme-core/src/main/java/fr/xephi/authme/settings/properties/EmailSettings.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/properties/EmailSettings.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/properties/EmailSettings.java
diff --git a/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java b/authme-core/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java
diff --git a/src/main/java/fr/xephi/authme/settings/properties/LimboSettings.java b/authme-core/src/main/java/fr/xephi/authme/settings/properties/LimboSettings.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/properties/LimboSettings.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/properties/LimboSettings.java
diff --git a/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java b/authme-core/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java
similarity index 77%
rename from src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java
index 99e31757d9..884021ca48 100644
--- a/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java
+++ b/authme-core/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java
@@ -34,6 +34,14 @@ public final class PluginSettings implements SettingsHolder {
public static final Property MESSAGES_LANGUAGE =
newProperty("settings.messagesLanguage", "en");
+ @Comment({
+ "When enabled, messages are sent to each player in their client language,",
+ "falling back to messagesLanguage if their locale is unavailable.",
+ "Disable this if you want all players to receive messages in the same language."
+ })
+ public static final Property PER_PLAYER_LOCALE =
+ newProperty("settings.perPlayerLocale", true);
+
@Comment({
"Enables switching a player to defined permission groups before they log in.",
"See below for a detailed explanation."
@@ -76,8 +84,14 @@ public final class PluginSettings implements SettingsHolder {
newProperty(LogLevel.class, "settings.logLevel", LogLevel.FINE);
@Comment({
- "By default we schedule async tasks when talking to the database. If you want",
- "typical communication with the database to happen synchronously, set this to false"
+ "Whether to run authentication work (password hashing, database queries) on async threads.",
+ "When true (strongly recommended), all CPU-intensive and I/O-bound operations — including",
+ "password hashing and database access — are offloaded from the main server thread, keeping",
+ "the server responsive during login and registration.",
+ "Setting this to false forces all of that work onto the main thread, which will cause",
+ "noticeable lag spikes on every login or registration attempt, especially with slow",
+ "algorithms (Argon2, BCrypt) or a remote database. Only set this to false if you have",
+ "a specific technical reason — it is not recommended under any normal circumstances."
})
public static final Property USE_ASYNC_TASKS =
newProperty("settings.useAsyncTasks", true);
diff --git a/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java b/authme-core/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java
diff --git a/src/main/java/fr/xephi/authme/settings/properties/PurgeSettings.java b/authme-core/src/main/java/fr/xephi/authme/settings/properties/PurgeSettings.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/properties/PurgeSettings.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/properties/PurgeSettings.java
diff --git a/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java b/authme-core/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java
similarity index 93%
rename from src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java
index daefe92cf6..3c74b5c27b 100644
--- a/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java
+++ b/authme-core/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java
@@ -107,6 +107,13 @@ public final class RegistrationSettings implements SettingsHolder {
public static final Property PREVENT_OTHER_CASE =
newProperty("settings.preventOtherCase", true);
+ @Comment({
+ "Show a graphical dialog UI for login/register instead of chat messages.",
+ "Requires Minecraft 1.21.6+ on Spigot, or 1.21.11+ on Paper.",
+ "On older server versions, this option is automatically ignored."})
+ public static final Property USE_DIALOG_UI =
+ newProperty("settings.registration.useDialogUi", true);
+
private RegistrationSettings() {
}
diff --git a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java b/authme-core/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java
similarity index 95%
rename from src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java
index 8794ba4473..96cf8fda7e 100644
--- a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java
+++ b/authme-core/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java
@@ -111,10 +111,16 @@ public final class RestrictionSettings implements SettingsHolder {
newProperty("settings.restrictions.allowMovement", false);
@Comment({
- "After how many seconds should players who fail to login or register",
- "be kicked? Set to 0 to disable."})
- public static final Property TIMEOUT =
- newProperty("settings.restrictions.timeout", 30);
+ "After how many seconds should players who fail to login be kicked?",
+ "Set to 0 to disable."})
+ public static final Property LOGIN_TIMEOUT =
+ newProperty("settings.restrictions.loginTimeout", 30);
+
+ @Comment({
+ "After how many seconds should players who fail to register be kicked?",
+ "Set to 0 to disable."})
+ public static final Property REGISTER_TIMEOUT =
+ newProperty("settings.restrictions.registerTimeout", 30);
@Comment("Regex pattern of allowed characters in the player name.")
public static final Property ALLOWED_NICKNAME_CHARACTERS =
diff --git a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java b/authme-core/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java
rename to authme-core/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java
diff --git a/src/main/java/fr/xephi/authme/task/CleanupTask.java b/authme-core/src/main/java/fr/xephi/authme/task/CleanupTask.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/task/CleanupTask.java
rename to authme-core/src/main/java/fr/xephi/authme/task/CleanupTask.java
diff --git a/src/main/java/fr/xephi/authme/task/MessageTask.java b/authme-core/src/main/java/fr/xephi/authme/task/MessageTask.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/task/MessageTask.java
rename to authme-core/src/main/java/fr/xephi/authme/task/MessageTask.java
diff --git a/src/main/java/fr/xephi/authme/task/TimeoutTask.java b/authme-core/src/main/java/fr/xephi/authme/task/TimeoutTask.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/task/TimeoutTask.java
rename to authme-core/src/main/java/fr/xephi/authme/task/TimeoutTask.java
diff --git a/src/main/java/fr/xephi/authme/task/purge/PurgeExecutor.java b/authme-core/src/main/java/fr/xephi/authme/task/purge/PurgeExecutor.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/task/purge/PurgeExecutor.java
rename to authme-core/src/main/java/fr/xephi/authme/task/purge/PurgeExecutor.java
diff --git a/src/main/java/fr/xephi/authme/task/purge/PurgeService.java b/authme-core/src/main/java/fr/xephi/authme/task/purge/PurgeService.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/task/purge/PurgeService.java
rename to authme-core/src/main/java/fr/xephi/authme/task/purge/PurgeService.java
diff --git a/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java b/authme-core/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/task/purge/PurgeTask.java
rename to authme-core/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java
diff --git a/src/main/java/fr/xephi/authme/util/AtomicIntervalCounter.java b/authme-core/src/main/java/fr/xephi/authme/util/AtomicIntervalCounter.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/AtomicIntervalCounter.java
rename to authme-core/src/main/java/fr/xephi/authme/util/AtomicIntervalCounter.java
diff --git a/src/main/java/fr/xephi/authme/util/ExceptionUtils.java b/authme-core/src/main/java/fr/xephi/authme/util/ExceptionUtils.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/ExceptionUtils.java
rename to authme-core/src/main/java/fr/xephi/authme/util/ExceptionUtils.java
diff --git a/src/main/java/fr/xephi/authme/util/FileUtils.java b/authme-core/src/main/java/fr/xephi/authme/util/FileUtils.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/FileUtils.java
rename to authme-core/src/main/java/fr/xephi/authme/util/FileUtils.java
diff --git a/src/main/java/fr/xephi/authme/util/InternetProtocolUtils.java b/authme-core/src/main/java/fr/xephi/authme/util/InternetProtocolUtils.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/InternetProtocolUtils.java
rename to authme-core/src/main/java/fr/xephi/authme/util/InternetProtocolUtils.java
diff --git a/src/main/java/fr/xephi/authme/util/PlayerUtils.java b/authme-core/src/main/java/fr/xephi/authme/util/PlayerUtils.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/PlayerUtils.java
rename to authme-core/src/main/java/fr/xephi/authme/util/PlayerUtils.java
diff --git a/src/main/java/fr/xephi/authme/util/RandomStringUtils.java b/authme-core/src/main/java/fr/xephi/authme/util/RandomStringUtils.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/RandomStringUtils.java
rename to authme-core/src/main/java/fr/xephi/authme/util/RandomStringUtils.java
diff --git a/src/main/java/fr/xephi/authme/util/StringUtils.java b/authme-core/src/main/java/fr/xephi/authme/util/StringUtils.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/StringUtils.java
rename to authme-core/src/main/java/fr/xephi/authme/util/StringUtils.java
diff --git a/src/main/java/fr/xephi/authme/util/Utils.java b/authme-core/src/main/java/fr/xephi/authme/util/Utils.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/Utils.java
rename to authme-core/src/main/java/fr/xephi/authme/util/Utils.java
diff --git a/src/main/java/fr/xephi/authme/util/UuidUtils.java b/authme-core/src/main/java/fr/xephi/authme/util/UuidUtils.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/UuidUtils.java
rename to authme-core/src/main/java/fr/xephi/authme/util/UuidUtils.java
diff --git a/src/main/java/fr/xephi/authme/util/expiring/Duration.java b/authme-core/src/main/java/fr/xephi/authme/util/expiring/Duration.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/expiring/Duration.java
rename to authme-core/src/main/java/fr/xephi/authme/util/expiring/Duration.java
diff --git a/src/main/java/fr/xephi/authme/util/expiring/ExpiringMap.java b/authme-core/src/main/java/fr/xephi/authme/util/expiring/ExpiringMap.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/expiring/ExpiringMap.java
rename to authme-core/src/main/java/fr/xephi/authme/util/expiring/ExpiringMap.java
diff --git a/src/main/java/fr/xephi/authme/util/expiring/ExpiringSet.java b/authme-core/src/main/java/fr/xephi/authme/util/expiring/ExpiringSet.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/expiring/ExpiringSet.java
rename to authme-core/src/main/java/fr/xephi/authme/util/expiring/ExpiringSet.java
diff --git a/src/main/java/fr/xephi/authme/util/expiring/TimedCounter.java b/authme-core/src/main/java/fr/xephi/authme/util/expiring/TimedCounter.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/expiring/TimedCounter.java
rename to authme-core/src/main/java/fr/xephi/authme/util/expiring/TimedCounter.java
diff --git a/src/main/java/fr/xephi/authme/util/lazytags/DependentTag.java b/authme-core/src/main/java/fr/xephi/authme/util/lazytags/DependentTag.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/lazytags/DependentTag.java
rename to authme-core/src/main/java/fr/xephi/authme/util/lazytags/DependentTag.java
diff --git a/src/main/java/fr/xephi/authme/util/lazytags/SimpleTag.java b/authme-core/src/main/java/fr/xephi/authme/util/lazytags/SimpleTag.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/lazytags/SimpleTag.java
rename to authme-core/src/main/java/fr/xephi/authme/util/lazytags/SimpleTag.java
diff --git a/src/main/java/fr/xephi/authme/util/lazytags/Tag.java b/authme-core/src/main/java/fr/xephi/authme/util/lazytags/Tag.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/lazytags/Tag.java
rename to authme-core/src/main/java/fr/xephi/authme/util/lazytags/Tag.java
diff --git a/src/main/java/fr/xephi/authme/util/lazytags/TagBuilder.java b/authme-core/src/main/java/fr/xephi/authme/util/lazytags/TagBuilder.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/lazytags/TagBuilder.java
rename to authme-core/src/main/java/fr/xephi/authme/util/lazytags/TagBuilder.java
diff --git a/src/main/java/fr/xephi/authme/util/lazytags/TagReplacer.java b/authme-core/src/main/java/fr/xephi/authme/util/lazytags/TagReplacer.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/lazytags/TagReplacer.java
rename to authme-core/src/main/java/fr/xephi/authme/util/lazytags/TagReplacer.java
diff --git a/src/main/java/fr/xephi/authme/util/lazytags/WrappedTagReplacer.java b/authme-core/src/main/java/fr/xephi/authme/util/lazytags/WrappedTagReplacer.java
similarity index 100%
rename from src/main/java/fr/xephi/authme/util/lazytags/WrappedTagReplacer.java
rename to authme-core/src/main/java/fr/xephi/authme/util/lazytags/WrappedTagReplacer.java
diff --git a/src/main/resources/commands.yml b/authme-core/src/main/resources/commands.yml
similarity index 99%
rename from src/main/resources/commands.yml
rename to authme-core/src/main/resources/commands.yml
index 6afd5a6005..63ae7c2a19 100644
--- a/src/main/resources/commands.yml
+++ b/authme-core/src/main/resources/commands.yml
@@ -1,4 +1,3 @@
-
# This configuration file allows you to execute commands on various events.
# Supported placeholders in commands:
# %p is replaced with the player name.
@@ -40,16 +39,16 @@
# command: 'say Uh oh! %p has many alt accounts!'
# executor: CONSOLE
# ifNumberOfAccountsAtLeast: 5
-# Commands to run for players logging in whose 'last login date' was empty
-onFirstLogin: {}
onJoin: {}
onLogin: {}
+onSessionLogin: {}
+# Commands to run for players logging in whose 'last login date' was empty
+onFirstLogin: {}
+onRegister: {}
+# Commands to run whenever a player is unregistered (by himself, or by an admin)
+onUnregister: {}
# These commands are called whenever a logged in player uses /logout or quits.
# The commands are not run if a player that was not logged in quits the server.
# Note: if your server crashes, these commands won't be run, so don't rely on them to undo
# 'onLogin' commands that would be dangerous for non-logged in players to have!
onLogout: {}
-onRegister: {}
-onSessionLogin: {}
-# Commands to run whenever a player is unregistered (by himself, or by an admin)
-onUnregister: {}
\ No newline at end of file
diff --git a/src/main/resources/email.html b/authme-core/src/main/resources/email.html
similarity index 100%
rename from src/main/resources/email.html
rename to authme-core/src/main/resources/email.html
diff --git a/src/main/resources/messages/help_bg.yml b/authme-core/src/main/resources/messages/help_bg.yml
similarity index 100%
rename from src/main/resources/messages/help_bg.yml
rename to authme-core/src/main/resources/messages/help_bg.yml
diff --git a/src/main/resources/messages/help_br.yml b/authme-core/src/main/resources/messages/help_br.yml
similarity index 100%
rename from src/main/resources/messages/help_br.yml
rename to authme-core/src/main/resources/messages/help_br.yml
diff --git a/src/main/resources/messages/help_cz.yml b/authme-core/src/main/resources/messages/help_cz.yml
similarity index 100%
rename from src/main/resources/messages/help_cz.yml
rename to authme-core/src/main/resources/messages/help_cz.yml
diff --git a/src/main/resources/messages/help_de.yml b/authme-core/src/main/resources/messages/help_de.yml
similarity index 100%
rename from src/main/resources/messages/help_de.yml
rename to authme-core/src/main/resources/messages/help_de.yml
diff --git a/src/main/resources/messages/help_en.yml b/authme-core/src/main/resources/messages/help_en.yml
similarity index 100%
rename from src/main/resources/messages/help_en.yml
rename to authme-core/src/main/resources/messages/help_en.yml
diff --git a/src/main/resources/messages/help_eo.yml b/authme-core/src/main/resources/messages/help_eo.yml
similarity index 100%
rename from src/main/resources/messages/help_eo.yml
rename to authme-core/src/main/resources/messages/help_eo.yml
diff --git a/src/main/resources/messages/help_es.yml b/authme-core/src/main/resources/messages/help_es.yml
similarity index 100%
rename from src/main/resources/messages/help_es.yml
rename to authme-core/src/main/resources/messages/help_es.yml
diff --git a/src/main/resources/messages/help_et.yml b/authme-core/src/main/resources/messages/help_et.yml
similarity index 100%
rename from src/main/resources/messages/help_et.yml
rename to authme-core/src/main/resources/messages/help_et.yml
diff --git a/src/main/resources/messages/help_eu.yml b/authme-core/src/main/resources/messages/help_eu.yml
similarity index 100%
rename from src/main/resources/messages/help_eu.yml
rename to authme-core/src/main/resources/messages/help_eu.yml
diff --git a/src/main/resources/messages/help_fr.yml b/authme-core/src/main/resources/messages/help_fr.yml
similarity index 100%
rename from src/main/resources/messages/help_fr.yml
rename to authme-core/src/main/resources/messages/help_fr.yml
diff --git a/src/main/resources/messages/help_hu.yml b/authme-core/src/main/resources/messages/help_hu.yml
similarity index 100%
rename from src/main/resources/messages/help_hu.yml
rename to authme-core/src/main/resources/messages/help_hu.yml
diff --git a/src/main/resources/messages/help_it.yml b/authme-core/src/main/resources/messages/help_it.yml
similarity index 100%
rename from src/main/resources/messages/help_it.yml
rename to authme-core/src/main/resources/messages/help_it.yml
diff --git a/src/main/resources/messages/help_ja.yml b/authme-core/src/main/resources/messages/help_ja.yml
similarity index 100%
rename from src/main/resources/messages/help_ja.yml
rename to authme-core/src/main/resources/messages/help_ja.yml
diff --git a/src/main/resources/messages/help_ko.yml b/authme-core/src/main/resources/messages/help_ko.yml
similarity index 100%
rename from src/main/resources/messages/help_ko.yml
rename to authme-core/src/main/resources/messages/help_ko.yml
diff --git a/src/main/resources/messages/help_lt.yml b/authme-core/src/main/resources/messages/help_lt.yml
similarity index 100%
rename from src/main/resources/messages/help_lt.yml
rename to authme-core/src/main/resources/messages/help_lt.yml
diff --git a/src/main/resources/messages/help_nl.yml b/authme-core/src/main/resources/messages/help_nl.yml
similarity index 100%
rename from src/main/resources/messages/help_nl.yml
rename to authme-core/src/main/resources/messages/help_nl.yml
diff --git a/src/main/resources/messages/help_pl.yml b/authme-core/src/main/resources/messages/help_pl.yml
similarity index 100%
rename from src/main/resources/messages/help_pl.yml
rename to authme-core/src/main/resources/messages/help_pl.yml
diff --git a/src/main/resources/messages/help_pt.yml b/authme-core/src/main/resources/messages/help_pt.yml
similarity index 100%
rename from src/main/resources/messages/help_pt.yml
rename to authme-core/src/main/resources/messages/help_pt.yml
diff --git a/src/main/resources/messages/help_ro.yml b/authme-core/src/main/resources/messages/help_ro.yml
similarity index 100%
rename from src/main/resources/messages/help_ro.yml
rename to authme-core/src/main/resources/messages/help_ro.yml
diff --git a/src/main/resources/messages/help_ru.yml b/authme-core/src/main/resources/messages/help_ru.yml
similarity index 100%
rename from src/main/resources/messages/help_ru.yml
rename to authme-core/src/main/resources/messages/help_ru.yml
diff --git a/src/main/resources/messages/help_si.yml b/authme-core/src/main/resources/messages/help_si.yml
similarity index 100%
rename from src/main/resources/messages/help_si.yml
rename to authme-core/src/main/resources/messages/help_si.yml
diff --git a/src/main/resources/messages/help_sr.yml b/authme-core/src/main/resources/messages/help_sr.yml
similarity index 100%
rename from src/main/resources/messages/help_sr.yml
rename to authme-core/src/main/resources/messages/help_sr.yml
diff --git a/src/main/resources/messages/help_vn.yml b/authme-core/src/main/resources/messages/help_vn.yml
similarity index 100%
rename from src/main/resources/messages/help_vn.yml
rename to authme-core/src/main/resources/messages/help_vn.yml
diff --git a/src/main/resources/messages/help_zhcn.yml b/authme-core/src/main/resources/messages/help_zhcn.yml
similarity index 100%
rename from src/main/resources/messages/help_zhcn.yml
rename to authme-core/src/main/resources/messages/help_zhcn.yml
diff --git a/src/main/resources/messages/help_zhhk.yml b/authme-core/src/main/resources/messages/help_zhhk.yml
similarity index 100%
rename from src/main/resources/messages/help_zhhk.yml
rename to authme-core/src/main/resources/messages/help_zhhk.yml
diff --git a/src/main/resources/messages/help_zhtw.yml b/authme-core/src/main/resources/messages/help_zhtw.yml
similarity index 100%
rename from src/main/resources/messages/help_zhtw.yml
rename to authme-core/src/main/resources/messages/help_zhtw.yml
diff --git a/src/main/resources/messages/messages_bg.yml b/authme-core/src/main/resources/messages/messages_bg.yml
similarity index 100%
rename from src/main/resources/messages/messages_bg.yml
rename to authme-core/src/main/resources/messages/messages_bg.yml
diff --git a/src/main/resources/messages/messages_br.yml b/authme-core/src/main/resources/messages/messages_br.yml
similarity index 100%
rename from src/main/resources/messages/messages_br.yml
rename to authme-core/src/main/resources/messages/messages_br.yml
diff --git a/src/main/resources/messages/messages_cz.yml b/authme-core/src/main/resources/messages/messages_cz.yml
similarity index 100%
rename from src/main/resources/messages/messages_cz.yml
rename to authme-core/src/main/resources/messages/messages_cz.yml
diff --git a/src/main/resources/messages/messages_de.yml b/authme-core/src/main/resources/messages/messages_de.yml
similarity index 100%
rename from src/main/resources/messages/messages_de.yml
rename to authme-core/src/main/resources/messages/messages_de.yml
diff --git a/src/main/resources/messages/messages_en.yml b/authme-core/src/main/resources/messages/messages_en.yml
similarity index 100%
rename from src/main/resources/messages/messages_en.yml
rename to authme-core/src/main/resources/messages/messages_en.yml
diff --git a/src/main/resources/messages/messages_eo.yml b/authme-core/src/main/resources/messages/messages_eo.yml
similarity index 100%
rename from src/main/resources/messages/messages_eo.yml
rename to authme-core/src/main/resources/messages/messages_eo.yml
diff --git a/src/main/resources/messages/messages_es.yml b/authme-core/src/main/resources/messages/messages_es.yml
similarity index 100%
rename from src/main/resources/messages/messages_es.yml
rename to authme-core/src/main/resources/messages/messages_es.yml
diff --git a/src/main/resources/messages/messages_et.yml b/authme-core/src/main/resources/messages/messages_et.yml
similarity index 100%
rename from src/main/resources/messages/messages_et.yml
rename to authme-core/src/main/resources/messages/messages_et.yml
diff --git a/src/main/resources/messages/messages_eu.yml b/authme-core/src/main/resources/messages/messages_eu.yml
similarity index 100%
rename from src/main/resources/messages/messages_eu.yml
rename to authme-core/src/main/resources/messages/messages_eu.yml
diff --git a/src/main/resources/messages/messages_fi.yml b/authme-core/src/main/resources/messages/messages_fi.yml
similarity index 100%
rename from src/main/resources/messages/messages_fi.yml
rename to authme-core/src/main/resources/messages/messages_fi.yml
diff --git a/src/main/resources/messages/messages_fr.yml b/authme-core/src/main/resources/messages/messages_fr.yml
similarity index 100%
rename from src/main/resources/messages/messages_fr.yml
rename to authme-core/src/main/resources/messages/messages_fr.yml
diff --git a/src/main/resources/messages/messages_gl.yml b/authme-core/src/main/resources/messages/messages_gl.yml
similarity index 100%
rename from src/main/resources/messages/messages_gl.yml
rename to authme-core/src/main/resources/messages/messages_gl.yml
diff --git a/src/main/resources/messages/messages_hu.yml b/authme-core/src/main/resources/messages/messages_hu.yml
similarity index 100%
rename from src/main/resources/messages/messages_hu.yml
rename to authme-core/src/main/resources/messages/messages_hu.yml
diff --git a/src/main/resources/messages/messages_id.yml b/authme-core/src/main/resources/messages/messages_id.yml
similarity index 100%
rename from src/main/resources/messages/messages_id.yml
rename to authme-core/src/main/resources/messages/messages_id.yml
diff --git a/src/main/resources/messages/messages_it.yml b/authme-core/src/main/resources/messages/messages_it.yml
similarity index 100%
rename from src/main/resources/messages/messages_it.yml
rename to authme-core/src/main/resources/messages/messages_it.yml
diff --git a/src/main/resources/messages/messages_ja.yml b/authme-core/src/main/resources/messages/messages_ja.yml
similarity index 100%
rename from src/main/resources/messages/messages_ja.yml
rename to authme-core/src/main/resources/messages/messages_ja.yml
diff --git a/src/main/resources/messages/messages_ko.yml b/authme-core/src/main/resources/messages/messages_ko.yml
similarity index 100%
rename from src/main/resources/messages/messages_ko.yml
rename to authme-core/src/main/resources/messages/messages_ko.yml
diff --git a/src/main/resources/messages/messages_lt.yml b/authme-core/src/main/resources/messages/messages_lt.yml
similarity index 100%
rename from src/main/resources/messages/messages_lt.yml
rename to authme-core/src/main/resources/messages/messages_lt.yml
diff --git a/src/main/resources/messages/messages_nl.yml b/authme-core/src/main/resources/messages/messages_nl.yml
similarity index 100%
rename from src/main/resources/messages/messages_nl.yml
rename to authme-core/src/main/resources/messages/messages_nl.yml
diff --git a/src/main/resources/messages/messages_pl.yml b/authme-core/src/main/resources/messages/messages_pl.yml
similarity index 100%
rename from src/main/resources/messages/messages_pl.yml
rename to authme-core/src/main/resources/messages/messages_pl.yml
diff --git a/src/main/resources/messages/messages_pt.yml b/authme-core/src/main/resources/messages/messages_pt.yml
similarity index 100%
rename from src/main/resources/messages/messages_pt.yml
rename to authme-core/src/main/resources/messages/messages_pt.yml
diff --git a/src/main/resources/messages/messages_ro.yml b/authme-core/src/main/resources/messages/messages_ro.yml
similarity index 100%
rename from src/main/resources/messages/messages_ro.yml
rename to authme-core/src/main/resources/messages/messages_ro.yml
diff --git a/src/main/resources/messages/messages_ru.yml b/authme-core/src/main/resources/messages/messages_ru.yml
similarity index 100%
rename from src/main/resources/messages/messages_ru.yml
rename to authme-core/src/main/resources/messages/messages_ru.yml
diff --git a/src/main/resources/messages/messages_si.yml b/authme-core/src/main/resources/messages/messages_si.yml
similarity index 100%
rename from src/main/resources/messages/messages_si.yml
rename to authme-core/src/main/resources/messages/messages_si.yml
diff --git a/src/main/resources/messages/messages_sk.yml b/authme-core/src/main/resources/messages/messages_sk.yml
similarity index 100%
rename from src/main/resources/messages/messages_sk.yml
rename to authme-core/src/main/resources/messages/messages_sk.yml
diff --git a/src/main/resources/messages/messages_sr.yml b/authme-core/src/main/resources/messages/messages_sr.yml
similarity index 100%
rename from src/main/resources/messages/messages_sr.yml
rename to authme-core/src/main/resources/messages/messages_sr.yml
diff --git a/src/main/resources/messages/messages_tr.yml b/authme-core/src/main/resources/messages/messages_tr.yml
similarity index 100%
rename from src/main/resources/messages/messages_tr.yml
rename to authme-core/src/main/resources/messages/messages_tr.yml
diff --git a/src/main/resources/messages/messages_uk.yml b/authme-core/src/main/resources/messages/messages_uk.yml
similarity index 100%
rename from src/main/resources/messages/messages_uk.yml
rename to authme-core/src/main/resources/messages/messages_uk.yml
diff --git a/src/main/resources/messages/messages_vn.yml b/authme-core/src/main/resources/messages/messages_vn.yml
similarity index 100%
rename from src/main/resources/messages/messages_vn.yml
rename to authme-core/src/main/resources/messages/messages_vn.yml
diff --git a/src/main/resources/messages/messages_zhcn.yml b/authme-core/src/main/resources/messages/messages_zhcn.yml
similarity index 100%
rename from src/main/resources/messages/messages_zhcn.yml
rename to authme-core/src/main/resources/messages/messages_zhcn.yml
diff --git a/src/main/resources/messages/messages_zhhk.yml b/authme-core/src/main/resources/messages/messages_zhhk.yml
similarity index 100%
rename from src/main/resources/messages/messages_zhhk.yml
rename to authme-core/src/main/resources/messages/messages_zhhk.yml
diff --git a/src/main/resources/messages/messages_zhmc.yml b/authme-core/src/main/resources/messages/messages_zhmc.yml
similarity index 100%
rename from src/main/resources/messages/messages_zhmc.yml
rename to authme-core/src/main/resources/messages/messages_zhmc.yml
diff --git a/src/main/resources/messages/messages_zhtw.yml b/authme-core/src/main/resources/messages/messages_zhtw.yml
similarity index 100%
rename from src/main/resources/messages/messages_zhtw.yml
rename to authme-core/src/main/resources/messages/messages_zhtw.yml
diff --git a/src/main/resources/otheraccounts.yml b/authme-core/src/main/resources/otheraccounts.yml
similarity index 100%
rename from src/main/resources/otheraccounts.yml
rename to authme-core/src/main/resources/otheraccounts.yml
diff --git a/src/main/resources/players.yml b/authme-core/src/main/resources/players.yml
similarity index 100%
rename from src/main/resources/players.yml
rename to authme-core/src/main/resources/players.yml
diff --git a/src/main/resources/plugin.yml b/authme-core/src/main/resources/plugin.yml
similarity index 100%
rename from src/main/resources/plugin.yml
rename to authme-core/src/main/resources/plugin.yml
index 59ee6a764c..2e027f3400 100644
--- a/src/main/resources/plugin.yml
+++ b/authme-core/src/main/resources/plugin.yml
@@ -198,12 +198,12 @@ permissions:
authme.allowmultipleaccounts:
description: Permission to be able to register multiple accounts.
default: op
- authme.bypassbungeesend:
- description: Permission node to bypass BungeeCord server teleportation.
- default: false
authme.bypassantibot:
description: Permission node to bypass AntiBot protection.
default: op
+ authme.bypassbungeesend:
+ description: Permission node to bypass BungeeCord server teleportation.
+ default: false
authme.bypasscountrycheck:
description: Permission to bypass the GeoIp country code check.
default: false
diff --git a/src/main/resources/recovery_code_email.html b/authme-core/src/main/resources/recovery_code_email.html
similarity index 100%
rename from src/main/resources/recovery_code_email.html
rename to authme-core/src/main/resources/recovery_code_email.html
diff --git a/src/main/resources/spawn.yml b/authme-core/src/main/resources/spawn.yml
similarity index 100%
rename from src/main/resources/spawn.yml
rename to authme-core/src/main/resources/spawn.yml
diff --git a/src/main/resources/verification_code_email.html b/authme-core/src/main/resources/verification_code_email.html
similarity index 100%
rename from src/main/resources/verification_code_email.html
rename to authme-core/src/main/resources/verification_code_email.html
diff --git a/src/main/resources/welcome.txt b/authme-core/src/main/resources/welcome.txt
similarity index 100%
rename from src/main/resources/welcome.txt
rename to authme-core/src/main/resources/welcome.txt
diff --git a/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java b/authme-core/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java
similarity index 80%
rename from src/test/java/fr/xephi/authme/AuthMeInitializationTest.java
rename to authme-core/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java
index f1fd62597a..0e2aaaea3f 100644
--- a/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import ch.jalu.configme.resource.PropertyReader;
import ch.jalu.configme.resource.PropertyResource;
import ch.jalu.injector.Injector;
@@ -10,6 +14,12 @@
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.listener.BlockListener;
+import fr.xephi.authme.platform.ChatAdapter;
+import fr.xephi.authme.platform.DialogAdapter;
+import fr.xephi.authme.platform.EventRegistrationAdapter;
+import fr.xephi.authme.platform.PlatformAdapter;
+import fr.xephi.authme.platform.SchedulingAdapter;
+import fr.xephi.authme.platform.TeleportAdapter;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.process.login.ProcessSyncPlayerLogin;
@@ -25,13 +35,10 @@
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPluginLoader;
import org.bukkit.scheduler.BukkitScheduler;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import fr.xephi.authme.TempFolder;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.io.File;
import java.io.IOException;
@@ -52,7 +59,8 @@
* Integration test verifying that all services can be initialized in {@link AuthMe}
* with the {@link Injector}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class AuthMeInitializationTest {
@Mock
@@ -63,11 +71,9 @@ public class AuthMeInitializationTest {
private AuthMe authMe;
private File dataFolder;
+ public TempFolder temporaryFolder = new TempFolder();
- @Rule
- public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
- @Before
+ @BeforeEach
public void initAuthMe() throws IOException {
dataFolder = temporaryFolder.newFolder();
File settingsFile = new File(dataFolder, "config.yml");
@@ -77,7 +83,6 @@ public void initAuthMe() throws IOException {
// Mock / wire various Bukkit components
ReflectionTestUtils.setField(Bukkit.class, null, "server", server);
- given(server.getPluginManager()).willReturn(pluginManager);
// PluginDescriptionFile is final: need to create a sample one
PluginDescriptionFile descriptionFile = new PluginDescriptionFile(
@@ -100,6 +105,7 @@ public void shouldInitializeAllServices() {
Injector injector = new InjectorBuilder()
.addDefaultHandlers("fr.xephi.authme")
.create();
+ given(server.getPluginManager()).willReturn(pluginManager);
injector.provide(DataFolder.class, dataFolder);
injector.register(Server.class, server);
injector.register(PluginManager.class, pluginManager);
@@ -108,6 +114,14 @@ public void shouldInitializeAllServices() {
injector.register(Settings.class, settings);
injector.register(DataSource.class, mock(DataSource.class));
injector.register(BukkitService.class, mock(BukkitService.class));
+ PlatformAdapter platformAdapter = mock(PlatformAdapter.class);
+ given(platformAdapter.getAdditionalListeners()).willReturn(Collections.emptyList());
+ injector.register(PlatformAdapter.class, platformAdapter);
+ injector.register(TeleportAdapter.class, platformAdapter);
+ injector.register(ChatAdapter.class, platformAdapter);
+ injector.register(EventRegistrationAdapter.class, platformAdapter);
+ injector.register(SchedulingAdapter.class, platformAdapter);
+ injector.register(DialogAdapter.class, platformAdapter);
// when
authMe.instantiateServices(injector);
@@ -143,3 +157,5 @@ public void shouldHandlePrematureShutdownGracefully() {
verify(scheduler).getActiveWorkers(); // via TaskCloser
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/AuthMeMatchers.java b/authme-core/src/test/java/fr/xephi/authme/AuthMeMatchers.java
similarity index 100%
rename from src/test/java/fr/xephi/authme/AuthMeMatchers.java
rename to authme-core/src/test/java/fr/xephi/authme/AuthMeMatchers.java
diff --git a/src/test/java/fr/xephi/authme/ClassCollector.java b/authme-core/src/test/java/fr/xephi/authme/ClassCollector.java
similarity index 100%
rename from src/test/java/fr/xephi/authme/ClassCollector.java
rename to authme-core/src/test/java/fr/xephi/authme/ClassCollector.java
diff --git a/src/test/java/fr/xephi/authme/ClassesConsistencyTest.java b/authme-core/src/test/java/fr/xephi/authme/ClassesConsistencyTest.java
similarity index 96%
rename from src/test/java/fr/xephi/authme/ClassesConsistencyTest.java
rename to authme-core/src/test/java/fr/xephi/authme/ClassesConsistencyTest.java
index cbabf8f4c5..4ac728d406 100644
--- a/src/test/java/fr/xephi/authme/ClassesConsistencyTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/ClassesConsistencyTest.java
@@ -11,13 +11,14 @@
import fr.xephi.authme.datasource.columnshandler.DataSourceColumn;
import fr.xephi.authme.datasource.columnshandler.PlayerAuthColumn;
import fr.xephi.authme.datasource.mysqlextensions.MySqlExtension;
+import fr.xephi.authme.security.crypts.AbstractPbkdf2;
import fr.xephi.authme.initialization.HasCleanup;
import fr.xephi.authme.process.register.executors.RegistrationMethod;
import fr.xephi.authme.util.expiring.ExpiringMap;
import fr.xephi.authme.util.expiring.ExpiringSet;
import fr.xephi.authme.util.expiring.TimedCounter;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import java.io.File;
import java.lang.reflect.Field;
@@ -35,7 +36,7 @@
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.fail;
/**
* Contains consistency tests across all AuthMe classes.
@@ -62,6 +63,7 @@ int.class, long.class, float.class, String.class, File.class, Enum.class, collec
/** Classes excluded from the field visibility test. */
private static final Set> CLASSES_EXCLUDED_FROM_VISIBILITY_TEST = ImmutableSet.of(
+ AbstractPbkdf2.class, // has immutable protected fields used by all children
MySqlExtension.class, // has immutable protected fields used by all children
AbstractSqlDataSource.class, // protected members for inheritance
Columns.class, // uses non-static String constants, which is safe
@@ -172,3 +174,4 @@ private static Class> collectionsUnmodifiableList() {
return Collections.unmodifiableList(new ArrayList<>()).getClass();
}
}
+
diff --git a/src/test/java/fr/xephi/authme/CodeClimateConfigTest.java b/authme-core/src/test/java/fr/xephi/authme/CodeClimateConfigTest.java
similarity index 89%
rename from src/test/java/fr/xephi/authme/CodeClimateConfigTest.java
rename to authme-core/src/test/java/fr/xephi/authme/CodeClimateConfigTest.java
index 669d10b306..da556005a6 100644
--- a/src/test/java/fr/xephi/authme/CodeClimateConfigTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/CodeClimateConfigTest.java
@@ -2,7 +2,7 @@
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.List;
@@ -11,14 +11,14 @@
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.fail;
/**
* Consistency test for the CodeClimate configuration file.
*/
public class CodeClimateConfigTest {
- private static final String CONFIG_FILE = ".codeclimate.yml";
+ private static final String CONFIG_FILE = "../.codeclimate.yml";
@Test
public void shouldHaveExistingClassesInExclusions() {
@@ -42,3 +42,4 @@ private static void removeTestsExclusionOrThrow(List excludePaths) {
wasRemoved, equalTo(true));
}
}
+
diff --git a/src/test/java/fr/xephi/authme/ConsoleLoggerTest.java b/authme-core/src/test/java/fr/xephi/authme/ConsoleLoggerTest.java
similarity index 90%
rename from src/test/java/fr/xephi/authme/ConsoleLoggerTest.java
rename to authme-core/src/test/java/fr/xephi/authme/ConsoleLoggerTest.java
index 19a64df2d5..80c2052436 100644
--- a/src/test/java/fr/xephi/authme/ConsoleLoggerTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/ConsoleLoggerTest.java
@@ -1,18 +1,19 @@
package fr.xephi.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.output.LogLevel;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import fr.xephi.authme.TempFolder;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.io.File;
import java.io.FileWriter;
@@ -32,6 +33,7 @@
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -40,20 +42,19 @@
/**
* Test for {@link ConsoleLogger}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class ConsoleLoggerTest {
private ConsoleLogger consoleLogger;
@Mock
private Logger logger;
-
- @Rule
- public TemporaryFolder temporaryFolder = new TemporaryFolder();
+ public TempFolder temporaryFolder = new TempFolder();
private File logFile;
- @Before
+ @BeforeEach
public void setMockLogger() throws IOException {
File folder = temporaryFolder.newFolder();
File logFile = new File(folder, "authme.log");
@@ -65,7 +66,7 @@ public void setMockLogger() throws IOException {
this.consoleLogger = new ConsoleLogger("test");
}
- @After
+ @AfterEach
public void closeFileHandlers() {
ConsoleLogger.closeFileWriter();
}
@@ -75,7 +76,7 @@ public void closeFileHandlers() {
* is that we no longer enable logging to a file as the log file we've supplied will no longer
* be around after this test class has finished.
*/
- @AfterClass
+ @AfterAll
public static void resetConsoleToDefault() {
ConsoleLogger.initializeSharedSettings(newSettings(false, LogLevel.INFO));
}
@@ -207,8 +208,8 @@ public void shouldHandleExceptionOnFileWriterClose() throws IOException {
private static Settings newSettings(boolean logToFile, LogLevel logLevel) {
Settings settings = mock(Settings.class);
- given(settings.getProperty(SecuritySettings.USE_LOGGING)).willReturn(logToFile);
- given(settings.getProperty(PluginSettings.LOG_LEVEL)).willReturn(logLevel);
+ lenient().when(settings.getProperty(SecuritySettings.USE_LOGGING)).thenReturn(logToFile);
+ lenient().when(settings.getProperty(PluginSettings.LOG_LEVEL)).thenReturn(logLevel);
return settings;
}
@@ -225,3 +226,5 @@ public String toString() {
}
}
}
+
+
diff --git a/authme-core/src/test/java/fr/xephi/authme/DelayedInjectionExtension.java b/authme-core/src/test/java/fr/xephi/authme/DelayedInjectionExtension.java
new file mode 100644
index 0000000000..7793fd87cd
--- /dev/null
+++ b/authme-core/src/test/java/fr/xephi/authme/DelayedInjectionExtension.java
@@ -0,0 +1,205 @@
+package fr.xephi.authme;
+
+import ch.jalu.injector.Injector;
+import ch.jalu.injector.InjectorBuilder;
+import ch.jalu.injector.context.ResolutionContext;
+import ch.jalu.injector.exceptions.InjectorException;
+import ch.jalu.injector.handlers.Handler;
+import ch.jalu.injector.handlers.instantiation.Resolution;
+import ch.jalu.injector.handlers.instantiation.SimpleResolution;
+import ch.jalu.injector.handlers.postconstruct.PostConstructMethodInvoker;
+import ch.jalu.injector.testing.BeforeInjecting;
+import ch.jalu.injector.testing.InjectDelayed;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
+import javax.inject.Inject;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * JUnit 5 equivalent of Jalu Injector's DelayedInjectionRunner.
+ */
+public class DelayedInjectionExtension implements BeforeEachCallback, AfterEachCallback {
+
+ private static final ExtensionContext.Namespace NAMESPACE =
+ ExtensionContext.Namespace.create(DelayedInjectionExtension.class);
+
+ @Override
+ public void beforeEach(ExtensionContext context) throws Exception {
+ Object testInstance = context.getRequiredTestInstance();
+ AutoCloseable mocks = MockitoAnnotations.openMocks(testInstance);
+ context.getStore(NAMESPACE).put(testInstance, mocks);
+
+ invokeBeforeInjectingMethods(testInstance);
+ injectDelayedFields(testInstance);
+ }
+
+ @Override
+ public void afterEach(ExtensionContext context) throws Exception {
+ Object testInstance = context.getRequiredTestInstance();
+ AutoCloseable mocks = context.getStore(NAMESPACE).remove(testInstance, AutoCloseable.class);
+ if (mocks != null) {
+ mocks.close();
+ }
+ }
+
+ private static void invokeBeforeInjectingMethods(Object testInstance) throws ReflectiveOperationException {
+ for (Method method : getAnnotatedMethods(testInstance.getClass(), BeforeInjecting.class)) {
+ method.setAccessible(true);
+ method.invoke(testInstance);
+ }
+ }
+
+ private static void injectDelayedFields(Object testInstance) throws ReflectiveOperationException {
+ List delayedFields = getAnnotatedFields(testInstance.getClass(), InjectDelayed.class);
+ if (delayedFields.isEmpty()) {
+ return;
+ }
+
+ Injector injector = new InjectorBuilder()
+ .addHandlers(
+ new TestAnnotationResolver(testInstance.getClass(), testInstance),
+ new MockDependencyHandler(testInstance.getClass(), testInstance, delayedFields),
+ new PostConstructMethodInvoker())
+ .addHandlers(InjectorBuilder.createInstantiationProviders(""))
+ .create();
+
+ for (Field field : delayedFields) {
+ field.setAccessible(true);
+ if (field.get(testInstance) != null) {
+ throw new IllegalStateException("Field with @InjectDelayed must be null on startup. Field '"
+ + field.getName() + "' is not null");
+ }
+ field.set(testInstance, injector.getSingleton(field.getType()));
+ }
+ }
+
+ private static List getAnnotatedMethods(Class> type, Class extends Annotation> annotationType) {
+ List methods = new ArrayList<>();
+ Class> current = type;
+ while (current != null && current != Object.class) {
+ for (Method method : current.getDeclaredMethods()) {
+ if (method.isAnnotationPresent(annotationType)) {
+ methods.add(0, method);
+ }
+ }
+ current = current.getSuperclass();
+ }
+ return methods;
+ }
+
+ private static List getAnnotatedFields(Class> type, Class extends Annotation> annotationType) {
+ List fields = new ArrayList<>();
+ Class> current = type;
+ while (current != null && current != Object.class) {
+ for (Field field : current.getDeclaredFields()) {
+ if (field.isAnnotationPresent(annotationType)) {
+ fields.add(field);
+ }
+ }
+ current = current.getSuperclass();
+ }
+ return fields;
+ }
+
+ private static final class MockDependencyHandler implements Handler {
+
+ private final Class> testClass;
+ private final Object target;
+ private final Set> fieldsToInject;
+
+ private boolean areMocksRegistered;
+
+ private MockDependencyHandler(Class> testClass, Object target, List delayedFields) {
+ this.testClass = testClass;
+ this.target = target;
+ this.fieldsToInject = new HashSet<>();
+ for (Field field : delayedFields) {
+ fieldsToInject.add(field.getType());
+ }
+ }
+
+ @Override
+ public Resolution> resolve(ResolutionContext context) throws IllegalAccessException {
+ Injector injector = context.getInjector();
+ if (!areMocksRegistered) {
+ registerAllMocks(injector);
+ areMocksRegistered = true;
+ }
+
+ Class> requestedType = context.getIdentifier().getTypeAsClass();
+ Object existingObject = injector.getIfAvailable(requestedType);
+ if (existingObject != null) {
+ return new SimpleResolution<>(existingObject);
+ }
+ if (fieldsToInject.contains(requestedType)) {
+ return null;
+ }
+ throw new InjectorException("No mock found for '" + requestedType
+ + "'. All dependencies of @InjectDelayed must be provided as @Mock or @InjectDelayed fields");
+ }
+
+ private void registerAllMocks(Injector injector) throws IllegalAccessException {
+ for (Field field : getAnnotatedFields(testClass, Mock.class)) {
+ field.setAccessible(true);
+ registerMock(injector, field, field.get(target));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void registerMock(Injector injector, Field field, Object mock) {
+ injector.register((Class super T>) field.getType(), (T) mock);
+ }
+ }
+
+ private static final class TestAnnotationResolver implements Handler {
+
+ private static final Set> IGNORED_ANNOTATIONS = Set.of(
+ Inject.class, org.mockito.InjectMocks.class, Mock.class, Spy.class, InjectDelayed.class);
+
+ private final Class> testClass;
+ private final Object target;
+
+ private TestAnnotationResolver(Class> testClass, Object target) {
+ this.testClass = testClass;
+ this.target = target;
+ }
+
+ @Override
+ public Resolution> resolve(ResolutionContext context) throws IllegalAccessException {
+ Class> requestedType = context.getIdentifier().getTypeAsClass();
+ for (Annotation annotation : context.getIdentifier().getAnnotations()) {
+ Object resolvedValue = resolveByAnnotation(annotation.annotationType(), requestedType);
+ if (resolvedValue != null) {
+ return new SimpleResolution<>(resolvedValue);
+ }
+ }
+ return null;
+ }
+
+ private Object resolveByAnnotation(Class extends Annotation> annotationType, Class> requestedType)
+ throws IllegalAccessException {
+ if (IGNORED_ANNOTATIONS.contains(annotationType)) {
+ return null;
+ }
+
+ for (Field field : getAnnotatedFields(testClass, annotationType)) {
+ if (requestedType.isAssignableFrom(field.getType())) {
+ field.setAccessible(true);
+ return field.get(target);
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/src/test/java/fr/xephi/authme/IsEqualByReflectionMatcher.java b/authme-core/src/test/java/fr/xephi/authme/IsEqualByReflectionMatcher.java
similarity index 98%
rename from src/test/java/fr/xephi/authme/IsEqualByReflectionMatcher.java
rename to authme-core/src/test/java/fr/xephi/authme/IsEqualByReflectionMatcher.java
index 2acf5ee708..b45f0e9982 100644
--- a/src/test/java/fr/xephi/authme/IsEqualByReflectionMatcher.java
+++ b/authme-core/src/test/java/fr/xephi/authme/IsEqualByReflectionMatcher.java
@@ -10,7 +10,7 @@
import java.util.List;
import java.util.Objects;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.fail;
/**
* Matcher which checks with reflection that all fields have the same value.
diff --git a/src/test/java/fr/xephi/authme/ReflectionTestUtils.java b/authme-core/src/test/java/fr/xephi/authme/ReflectionTestUtils.java
similarity index 100%
rename from src/test/java/fr/xephi/authme/ReflectionTestUtils.java
rename to authme-core/src/test/java/fr/xephi/authme/ReflectionTestUtils.java
diff --git a/authme-core/src/test/java/fr/xephi/authme/TempFolder.java b/authme-core/src/test/java/fr/xephi/authme/TempFolder.java
new file mode 100644
index 0000000000..9ff91a1546
--- /dev/null
+++ b/authme-core/src/test/java/fr/xephi/authme/TempFolder.java
@@ -0,0 +1,38 @@
+package fr.xephi.authme;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+
+/**
+ * Minimal test helper replacing JUnit 4's TemporaryFolder rule.
+ */
+public class TempFolder {
+
+ private final File root;
+
+ public TempFolder() {
+ try {
+ root = Files.createTempDirectory("authme-tests-").toFile();
+ root.deleteOnExit();
+ } catch (IOException e) {
+ throw new IllegalStateException("Could not create temporary folder", e);
+ }
+ }
+
+ public File newFolder() throws IOException {
+ File folder = Files.createTempDirectory(root.toPath(), "folder-").toFile();
+ folder.deleteOnExit();
+ return folder;
+ }
+
+ public File newFile() throws IOException {
+ File file = Files.createTempFile(root.toPath(), "file-", ".tmp").toFile();
+ file.deleteOnExit();
+ return file;
+ }
+
+ public File getRoot() {
+ return root;
+ }
+}
diff --git a/src/test/java/fr/xephi/authme/TestHelper.java b/authme-core/src/test/java/fr/xephi/authme/TestHelper.java
similarity index 96%
rename from src/test/java/fr/xephi/authme/TestHelper.java
rename to authme-core/src/test/java/fr/xephi/authme/TestHelper.java
index ad50c5119b..11fd5ab35c 100644
--- a/src/test/java/fr/xephi/authme/TestHelper.java
+++ b/authme-core/src/test/java/fr/xephi/authme/TestHelper.java
@@ -18,6 +18,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.lenient;
/**
* AuthMe test utilities.
@@ -102,7 +103,7 @@ public static void mockIpAddressToPlayer(Player player, String ip) {
try {
InetAddress inetAddress = InetAddress.getByName(ip);
InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, 8093);
- given(player.getAddress()).willReturn(inetSocketAddress);
+ lenient().when(player.getAddress()).thenReturn(inetSocketAddress);
} catch (UnknownHostException e) {
throw new IllegalStateException("Invalid IP address: " + ip, e);
}
diff --git a/src/test/java/fr/xephi/authme/api/v3/AuthMeApiTest.java b/authme-core/src/test/java/fr/xephi/authme/api/v3/AuthMeApiTest.java
similarity index 97%
rename from src/test/java/fr/xephi/authme/api/v3/AuthMeApiTest.java
rename to authme-core/src/test/java/fr/xephi/authme/api/v3/AuthMeApiTest.java
index b52f7908b1..e276559ea1 100644
--- a/src/test/java/fr/xephi/authme/api/v3/AuthMeApiTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/api/v3/AuthMeApiTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.api.v3;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ReflectionTestUtils;
import fr.xephi.authme.data.auth.PlayerAuth;
@@ -17,12 +21,11 @@
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.time.Instant;
import java.util.Arrays;
@@ -51,7 +54,8 @@
/**
* Test for {@link AuthMeApi}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class AuthMeApiTest {
@InjectMocks
@@ -71,6 +75,8 @@ public class AuthMeApiTest {
private AuthMe authMe;
@Mock
private GeoIpService geoIpService;
+ @Captor
+ private ArgumentCaptor authCaptor;
@Test
public void shouldReturnInstanceOrNull() {
@@ -467,7 +473,6 @@ public void shouldRegisterPlayer() {
// then
assertThat(result, equalTo(true));
verify(passwordSecurity).computeHash(password, name.toLowerCase(Locale.ROOT));
- ArgumentCaptor authCaptor = ArgumentCaptor.forClass(PlayerAuth.class);
verify(dataSource).saveAuth(authCaptor.capture());
assertThat(authCaptor.getValue().getNickname(), equalTo(name.toLowerCase(Locale.ROOT)));
assertThat(authCaptor.getValue().getRealName(), equalTo(name));
@@ -556,3 +561,5 @@ private static Player mockPlayerWithName(String name) {
return player;
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/api/v3/AuthMePlayerImplTest.java b/authme-core/src/test/java/fr/xephi/authme/api/v3/AuthMePlayerImplTest.java
similarity index 98%
rename from src/test/java/fr/xephi/authme/api/v3/AuthMePlayerImplTest.java
rename to authme-core/src/test/java/fr/xephi/authme/api/v3/AuthMePlayerImplTest.java
index aa8b50c953..50e98e5a7a 100644
--- a/src/test/java/fr/xephi/authme/api/v3/AuthMePlayerImplTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/api/v3/AuthMePlayerImplTest.java
@@ -4,7 +4,7 @@
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import java.time.Instant;
import java.util.Optional;
@@ -93,3 +93,4 @@ protected boolean matchesSafely(Optional item) {
};
}
}
+
diff --git a/src/test/java/fr/xephi/authme/command/CommandConsistencyTest.java b/authme-core/src/test/java/fr/xephi/authme/command/CommandConsistencyTest.java
similarity index 98%
rename from src/test/java/fr/xephi/authme/command/CommandConsistencyTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/CommandConsistencyTest.java
index fc3b3aeee7..4233c38748 100644
--- a/src/test/java/fr/xephi/authme/command/CommandConsistencyTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/CommandConsistencyTest.java
@@ -3,7 +3,7 @@
import org.bukkit.configuration.MemorySection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Collection;
@@ -82,3 +82,4 @@ private static Map> getLabelsFromPluginFile() {
}
}
+
diff --git a/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java b/authme-core/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java
similarity index 90%
rename from src/test/java/fr/xephi/authme/command/CommandHandlerTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java
index 81b0733af3..60abe4e35d 100644
--- a/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import ch.jalu.injector.factory.Factory;
import com.google.common.collect.Sets;
import fr.xephi.authme.command.TestCommandsUtil.TestLoginCommand;
@@ -10,13 +14,12 @@
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.permission.PermissionsManager;
import org.bukkit.command.CommandSender;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
-import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import java.util.Collections;
@@ -47,7 +50,8 @@
// Justification: It's more readable to use asList() everywhere in the test when we often generated two lists where one
// often consists of only one element, e.g. myMethod(asList("authme"), asList("my", "args"), ...)
@SuppressWarnings("ArraysAsListWithZeroOrOneArgument")
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class CommandHandlerTest {
private CommandHandler handler;
@@ -62,10 +66,12 @@ public class CommandHandlerTest {
private Messages messages;
@Mock
private HelpProvider helpProvider;
+ @Captor
+ private ArgumentCaptor cmdCaptor;
private Map, ExecutableCommand> mockedCommands = new HashMap<>();
- @Before
+ @BeforeEach
@SuppressWarnings("unchecked")
public void initializeCommandMapper() {
given(commandMapper.getCommandClasses()).willReturn(Sets.newHashSet(
@@ -123,6 +129,25 @@ public void shouldCallMappedCommandWithArgs() {
verify(sender, never()).sendMessage(anyString());
}
+ @Test
+ public void shouldCallMappedCommandWithPreSplitParts() {
+ // given
+ CommandSender sender = mock(CommandSender.class);
+ CommandDescription command = mock(CommandDescription.class);
+ doReturn(TestLoginCommand.class).when(command).getExecutableCommand();
+ given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyList()))
+ .willReturn(new FoundCommandResult(command, asList("Authme", "Login"), asList("myPass"), 0.0, SUCCESS));
+
+ // when
+ handler.processCommand(sender, asList("Authme", "Login", "myPass"));
+
+ // then
+ ExecutableCommand executableCommand = mockedCommands.get(TestLoginCommand.class);
+ verify(commandMapper).mapPartsToCommand(sender, asList("Authme", "Login", "myPass"));
+ verify(executableCommand).executeCommand(sender, asList("myPass"));
+ verify(sender, never()).sendMessage(anyString());
+ }
+
@Test
public void shouldNotCallExecutableCommandIfNoPermission() {
// given
@@ -246,7 +271,6 @@ public void shouldNotCallExecutableForUnknownLabelAndHaveSuggestion() {
verify(commandMapper).mapPartsToCommand(sender, asList("unreg", "testPlayer"));
verify(command, never()).getExecutableCommand();
verify(messages).send(sender, MessageKey.UNKNOWN_COMMAND);
- ArgumentCaptor cmdCaptor = ArgumentCaptor.forClass(String.class);
verify(messages).send(eq(sender), eq(MessageKey.COMMAND_DID_YOU_MEAN), cmdCaptor.capture());
assertThat(cmdCaptor.getValue(), containsString("test_cmd"));
verify(messages).send(eq(sender), eq(MessageKey.COMMAND_SEE_HELP), anyString());
@@ -297,3 +321,5 @@ public void shouldStripWhitespace() {
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java b/authme-core/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java
similarity index 98%
rename from src/test/java/fr/xephi/authme/command/CommandInitializerTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java
index 2110e2d660..b388949b8c 100644
--- a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java
@@ -1,8 +1,8 @@
package fr.xephi.authme.command;
import fr.xephi.authme.util.StringUtils;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Collection;
@@ -18,7 +18,7 @@
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.fail;
/**
* Test for {@link CommandInitializer} to guarantee the integrity of the defined commands.
@@ -33,7 +33,7 @@ public class CommandInitializerTest {
private static Collection commands;
- @BeforeClass
+ @BeforeAll
public static void initializeCommandCollection() {
CommandInitializer commandInitializer = new CommandInitializer();
commands = commandInitializer.getCommands();
@@ -281,3 +281,4 @@ private static List getAbsoluteLabels(CommandDescription command) {
}
}
+
diff --git a/src/test/java/fr/xephi/authme/command/CommandMapperTest.java b/authme-core/src/test/java/fr/xephi/authme/command/CommandMapperTest.java
similarity index 98%
rename from src/test/java/fr/xephi/authme/command/CommandMapperTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/CommandMapperTest.java
index 4311d709cf..610a29618f 100644
--- a/src/test/java/fr/xephi/authme/command/CommandMapperTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/CommandMapperTest.java
@@ -1,7 +1,8 @@
package fr.xephi.authme.command;
+import org.junit.jupiter.api.extension.ExtendWith;
+import fr.xephi.authme.DelayedInjectionExtension;
import ch.jalu.injector.testing.BeforeInjecting;
-import ch.jalu.injector.testing.DelayedInjectionRunner;
import ch.jalu.injector.testing.InjectDelayed;
import fr.xephi.authme.command.TestCommandsUtil.TestLoginCommand;
import fr.xephi.authme.command.TestCommandsUtil.TestRegisterCommand;
@@ -10,9 +11,8 @@
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsManager;
import org.bukkit.command.CommandSender;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import java.util.List;
@@ -37,7 +37,7 @@
/**
* Test for {@link CommandMapper}.
*/
-@RunWith(DelayedInjectionRunner.class)
+@ExtendWith(DelayedInjectionExtension.class)
public class CommandMapperTest {
private static List commands;
@@ -51,7 +51,7 @@ public class CommandMapperTest {
@Mock
private CommandInitializer commandInitializer;
- @BeforeClass
+ @BeforeAll
public static void setUpCommandHandler() {
commands = TestCommandsUtil.generateCommands();
}
@@ -317,3 +317,5 @@ public void shouldReturnExecutableCommandClasses() {
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/CommandUtilsTest.java b/authme-core/src/test/java/fr/xephi/authme/command/CommandUtilsTest.java
similarity index 68%
rename from src/test/java/fr/xephi/authme/command/CommandUtilsTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/CommandUtilsTest.java
index bd5a18d8a7..684b35e901 100644
--- a/src/test/java/fr/xephi/authme/command/CommandUtilsTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/CommandUtilsTest.java
@@ -1,8 +1,8 @@
package fr.xephi.authme.command;
import org.bukkit.ChatColor;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.Collection;
@@ -19,7 +19,7 @@ public class CommandUtilsTest {
private static Collection commands;
- @BeforeClass
+ @BeforeAll
public static void setUpTestCommands() {
commands = Collections.unmodifiableCollection(TestCommandsUtil.generateCommands());
}
@@ -122,12 +122,78 @@ public void shouldFormatCommandWithOptionalArgument() {
assertThat(result, equalTo(ChatColor.WHITE + "/email" + ChatColor.YELLOW + " [player]"));
}
+ @Test
+ public void shouldReturnEmptyListForNullInput() {
+ assertSplitInput(null);
+ }
+
+ @Test
+ public void shouldReturnEmptyListForBlankInput() {
+ assertSplitInput(" \t \n ");
+ }
+
+ @Test
+ public void shouldReturnEmptyListForSlashOnlyInput() {
+ assertSplitInput("/");
+ }
+
+ @Test
+ public void shouldReturnEmptyListForSlashWithOnlyWhitespace() {
+ assertSplitInput("/ \t ");
+ }
+
+ @Test
+ public void shouldSplitSingleCommandWithoutLeadingSlash() {
+ assertSplitInput("authme", "authme");
+ }
+
+ @Test
+ public void shouldSplitSingleCommandWithLeadingSlash() {
+ assertSplitInput("/authme", "authme");
+ }
+
+ @Test
+ public void shouldTrimInputBeforeRemovingLeadingSlash() {
+ assertSplitInput(" /authme register ", "authme", "register");
+ }
+
+ @Test
+ public void shouldIgnoreRepeatedWhitespaceBetweenParts() {
+ assertSplitInput("/authme register player password",
+ "authme", "register", "player", "password");
+ }
+
+ @Test
+ public void shouldSplitTabsAndNewlinesAsWhitespace() {
+ assertSplitInput("/authme\tregister\nplayer\r\npassword",
+ "authme", "register", "player", "password");
+ }
+
+ @Test
+ public void shouldSupportSlashSeparatedByWhitespaceFromCommand() {
+ assertSplitInput("/ authme register", "authme", "register");
+ }
+
+ @Test
+ public void shouldPreserveAdditionalLeadingSlashInFirstPart() {
+ assertSplitInput("//authme register", "/authme", "register");
+ }
+
+ @Test
+ public void shouldPreserveNonEmptySpecialCharactersInsideParts() {
+ assertSplitInput("/login p@ss-word_123", "login", "p@ss-word_123");
+ }
+
private static void checkArgumentCount(CommandDescription command, int expectedMin, int expectedMax) {
assertThat(CommandUtils.getMinNumberOfArguments(command), equalTo(expectedMin));
assertThat(CommandUtils.getMaxNumberOfArguments(command), equalTo(expectedMax));
}
+ private static void assertSplitInput(String input, String... expectedParts) {
+ assertThat(CommandUtils.splitInput(input), equalTo(Arrays.asList(expectedParts)));
+ }
+
private static CommandDescription.CommandBuilder getBuilderForArgsTest() {
return CommandDescription.builder()
.labels("authme", "auth")
@@ -136,3 +202,4 @@ private static CommandDescription.CommandBuilder getBuilderForArgsTest() {
.executableCommand(ExecutableCommand.class);
}
}
+
diff --git a/src/test/java/fr/xephi/authme/command/PlayerCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/PlayerCommandTest.java
similarity index 89%
rename from src/test/java/fr/xephi/authme/command/PlayerCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/PlayerCommandTest.java
index 4b0aff5ab8..01e01e0565 100644
--- a/src/test/java/fr/xephi/authme/command/PlayerCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/PlayerCommandTest.java
@@ -1,14 +1,16 @@
package fr.xephi.authme.command;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Collections;
@@ -22,7 +24,8 @@
/**
* Test for {@link PlayerCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class PlayerCommandTest {
@Mock
@@ -90,3 +93,5 @@ public String getAlternativeCommand() {
}
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/TestCommandsUtil.java b/authme-core/src/test/java/fr/xephi/authme/command/TestCommandsUtil.java
similarity index 100%
rename from src/test/java/fr/xephi/authme/command/TestCommandsUtil.java
rename to authme-core/src/test/java/fr/xephi/authme/command/TestCommandsUtil.java
diff --git a/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java
similarity index 94%
rename from src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java
index 9e40a4c62b..1ebf8d5d0d 100644
--- a/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java
@@ -1,17 +1,20 @@
package fr.xephi.authme.command.executable;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandMapper;
import fr.xephi.authme.command.FoundCommandResult;
import fr.xephi.authme.command.help.HelpProvider;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
import java.util.List;
@@ -39,7 +42,8 @@
/**
* Test for {@link HelpCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class HelpCommandTest {
@InjectMocks
@@ -50,6 +54,8 @@ public class HelpCommandTest {
@Mock
private HelpProvider helpProvider;
+ @Captor
+ private ArgumentCaptor captor;
@Test
public void shouldHandleMissingBaseCommand() {
@@ -81,7 +87,6 @@ public void shouldHandleWrongCommandWithSuggestion() {
command.executeCommand(sender, arguments);
// then
- ArgumentCaptor captor = ArgumentCaptor.forClass(String.class);
verify(sender).sendMessage(captor.capture());
assertThat(removeColors(captor.getValue()), containsString("Assuming /authme register"));
verify(helpProvider).outputHelp(sender, foundCommandResult, HelpProvider.ALL_OPTIONS);
@@ -99,7 +104,6 @@ public void shouldHandleWrongCommandWithoutSuggestion() {
command.executeCommand(sender, arguments);
// then
- ArgumentCaptor captor = ArgumentCaptor.forClass(String.class);
verify(sender).sendMessage(captor.capture());
assertThat(removeColors(captor.getValue()), containsString("Unknown command"));
verifyNoInteractions(helpProvider);
@@ -161,3 +165,5 @@ private static String removeColors(String str) {
return str;
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java
similarity index 93%
rename from src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java
index dcc058b8fa..77afcf066c 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java
@@ -1,17 +1,20 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.CommonService;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Collections;
@@ -30,7 +33,8 @@
/**
* Test for {@link AccountsCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class AccountsCommandTest {
@InjectMocks
@@ -41,6 +45,8 @@ public class AccountsCommandTest {
private DataSource dataSource;
@Mock
private BukkitService bukkitService;
+ @Captor
+ private ArgumentCaptor captor;
@Test
public void shouldGetAccountsOfCurrentUser() {
@@ -57,7 +63,6 @@ public void shouldGetAccountsOfCurrentUser() {
// then
verify(service).send(eq(sender), eq(MessageKey.ACCOUNTS_OWNED_SELF), eq("2"));
- ArgumentCaptor captor = ArgumentCaptor.forClass(String.class);
verify(sender).sendMessage(captor.capture());
assertThat(captor.getValue(), containsString("Toaster, Pester"));
}
@@ -160,7 +165,6 @@ public void shouldReturnAccountListForIpQuery() {
// then
verify(service).send(eq(sender), eq(MessageKey.ACCOUNTS_OWNED_OTHER), eq("98.76.41.122"), eq("3"));
- ArgumentCaptor captor = ArgumentCaptor.forClass(String.class);
verify(sender).sendMessage(captor.capture());
assertThat(captor.getValue(), containsString("Tester, Lester, Taster"));
}
@@ -172,3 +176,5 @@ private static PlayerAuth authWithIp(String ip) {
.build();
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/AuthMeCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/AuthMeCommandTest.java
similarity index 72%
rename from src/test/java/fr/xephi/authme/command/executable/authme/AuthMeCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/AuthMeCommandTest.java
index 303be56fef..d1957916c5 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/AuthMeCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/AuthMeCommandTest.java
@@ -2,8 +2,13 @@
import fr.xephi.authme.command.ExecutableCommand;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
import java.util.Collections;
@@ -16,7 +21,11 @@
/**
* Test for {@link AuthMeCommand}.
*/
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class AuthMeCommandTest {
+ @Captor
+ private ArgumentCaptor messagesCaptor;
@Test
public void shouldDisplayInformation() {
@@ -28,9 +37,9 @@ public void shouldDisplayInformation() {
command.executeCommand(sender, Collections.emptyList());
// then
- ArgumentCaptor messagesCaptor = ArgumentCaptor.forClass(String.class);
verify(sender, times(3)).sendMessage(messagesCaptor.capture());
assertThat(messagesCaptor.getAllValues().get(1), containsString("/authme help"));
assertThat(messagesCaptor.getAllValues().get(2), containsString("/authme about"));
}
}
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/BackupCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/BackupCommandTest.java
similarity index 72%
rename from src/test/java/fr/xephi/authme/command/executable/authme/BackupCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/BackupCommandTest.java
index 2e1e0b5e82..5b9c62a9ea 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/BackupCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/BackupCommandTest.java
@@ -1,12 +1,14 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.service.BackupService;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -16,7 +18,8 @@
/**
* Test for {@link BackupCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class BackupCommandTest {
@InjectMocks
@@ -37,3 +40,5 @@ public void shouldStartBackup() {
verify(backupService).doBackup(BackupService.BackupCause.COMMAND, sender);
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ChangePasswordAdminCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/ChangePasswordAdminCommandTest.java
similarity index 87%
rename from src/test/java/fr/xephi/authme/command/executable/authme/ChangePasswordAdminCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/ChangePasswordAdminCommandTest.java
index 8e1a608155..35c36ba569 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/ChangePasswordAdminCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/ChangePasswordAdminCommandTest.java
@@ -1,16 +1,18 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.service.ValidationService;
import fr.xephi.authme.service.ValidationService.ValidationResult;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
@@ -22,7 +24,8 @@
/**
* Test for {@link ChangePasswordAdminCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class ChangePasswordAdminCommandTest {
@InjectMocks
@@ -71,3 +74,5 @@ public void shouldSendErrorToCommandSender() {
verifyNoInteractions(management);
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java
similarity index 93%
rename from src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java
index aeae96ab66..a15e06e762 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import ch.jalu.injector.factory.Factory;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.datasource.converter.Converter;
@@ -8,12 +12,10 @@
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.command.CommandSender;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
import java.util.HashSet;
@@ -37,7 +39,8 @@
/**
* Test for {@link ConverterCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class ConverterCommandTest {
@InjectMocks
@@ -52,7 +55,7 @@ public class ConverterCommandTest {
@Mock
private Factory converterFactory;
- @BeforeClass
+ @BeforeAll
public static void initLogger() {
TestHelper.setupLogger();
}
@@ -147,3 +150,5 @@ private T createMockReturnedByInjector(Class clazz) {
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/FirstSpawnCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/FirstSpawnCommandTest.java
similarity index 84%
rename from src/test/java/fr/xephi/authme/command/executable/authme/FirstSpawnCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/FirstSpawnCommandTest.java
index 97c1e1ea6c..d14ec23114 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/FirstSpawnCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/FirstSpawnCommandTest.java
@@ -1,15 +1,17 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.settings.SpawnLoader;
import org.bukkit.Location;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -23,7 +25,8 @@
/**
* Test for {@link FirstSpawnCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class FirstSpawnCommandTest {
@InjectMocks
@@ -64,3 +67,5 @@ public void shouldHandleMissingFirstSpawn() {
verify(player, never()).teleport(any(Location.class));
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java
similarity index 93%
rename from src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java
index fccf98687d..c839c53a42 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.permission.PermissionsManager;
@@ -8,11 +12,9 @@
import fr.xephi.authme.service.BukkitService;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -25,7 +27,8 @@
/**
* Test for {@link ForceLoginCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class ForceLoginCommandTest {
@InjectMocks
@@ -137,3 +140,5 @@ private static Player mockPlayer(boolean isOnline) {
return player;
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java
similarity index 84%
rename from src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java
index e55defafda..07eff3be2b 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java
@@ -1,15 +1,17 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import ch.jalu.datasourcecolumns.data.DataSourceValueImpl;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.CommonService;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -21,7 +23,8 @@
/**
* Test for {@link GetEmailCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class GetEmailCommandTest {
@InjectMocks
@@ -62,3 +65,5 @@ public void shouldReturnEmail() {
verify(service).send(eq(sender), eq(MessageKey.ADMIN_EMAIL_SHOW), eq(user), eq(email));
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/GetIpCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/GetIpCommandTest.java
similarity index 92%
rename from src/test/java/fr/xephi/authme/command/executable/authme/GetIpCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/GetIpCommandTest.java
index 8fe65e90b6..03e7fe2317 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/GetIpCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/GetIpCommandTest.java
@@ -1,16 +1,18 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.service.BukkitService;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -26,7 +28,8 @@
/**
* Test for {@link GetIpCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class GetIpCommandTest {
@InjectMocks
@@ -104,3 +107,5 @@ private static Player mockPlayer(String name, String ip) {
return player;
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/LastLoginCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/LastLoginCommandTest.java
similarity index 92%
rename from src/test/java/fr/xephi/authme/command/executable/authme/LastLoginCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/LastLoginCommandTest.java
index 402b933aca..89d2e325ed 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/LastLoginCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/LastLoginCommandTest.java
@@ -1,16 +1,19 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.CommonService;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
import java.util.Date;
@@ -26,7 +29,8 @@
/**
* Test for {@link LastLoginCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class LastLoginCommandTest {
private static final long HOUR_IN_MSEC = 3600 * 1000;
@@ -40,6 +44,8 @@ public class LastLoginCommandTest {
@Mock
private CommonService service;
+ @Captor
+ private ArgumentCaptor captor;
@Test
@@ -74,7 +80,6 @@ public void shouldDisplayLastLoginOfUser() {
// then
verify(dataSource).getAuth(player);
- ArgumentCaptor captor = ArgumentCaptor.forClass(String.class);
verify(sender, times(3)).sendMessage(captor.capture());
String lastLoginString = new Date(lastLogin).toString();
assertThat(captor.getAllValues().get(0),
@@ -102,7 +107,6 @@ public void shouldDisplayLastLoginOfCommandSender() {
// then
verify(dataSource).getAuth(name);
- ArgumentCaptor captor = ArgumentCaptor.forClass(String.class);
verify(sender, times(3)).sendMessage(captor.capture());
String lastLoginString = new Date(lastLogin).toString();
assertThat(captor.getAllValues().get(0),
@@ -127,9 +131,10 @@ public void shouldHandleNullLastLoginDate() {
// then
verify(dataSource).getAuth(name);
- ArgumentCaptor captor = ArgumentCaptor.forClass(String.class);
verify(sender, times(2)).sendMessage(captor.capture());
assertThat(captor.getAllValues().get(0), allOf(containsString(name), containsString("never")));
assertThat(captor.getAllValues().get(1), containsString("123.45.67.89"));
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommandTest.java
similarity index 88%
rename from src/test/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommandTest.java
index 7c675bc07a..74b79b9248 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommandTest.java
@@ -1,14 +1,16 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.task.purge.PurgeService;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
import java.util.HashSet;
@@ -26,7 +28,8 @@
/**
* Test for {@link PurgeBannedPlayersCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class PurgeBannedPlayersCommandTest {
@InjectMocks
@@ -73,3 +76,5 @@ private static Set asLowerCaseSet(String... items) {
return result;
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/PurgeCommandTest.java
similarity index 86%
rename from src/test/java/fr/xephi/authme/command/executable/authme/PurgeCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/PurgeCommandTest.java
index 5d8d8d89e8..3cf8f241ca 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/PurgeCommandTest.java
@@ -1,13 +1,16 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.task.purge.PurgeService;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Calendar;
import java.util.Collections;
@@ -25,7 +28,8 @@
/**
* Test for {@link PurgeCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class PurgeCommandTest {
@InjectMocks
@@ -33,6 +37,8 @@ public class PurgeCommandTest {
@Mock
private PurgeService purgeService;
+ @Captor
+ private ArgumentCaptor captor;
@Test
public void shouldHandleInvalidNumber() {
@@ -72,7 +78,6 @@ public void shouldForwardToService() {
command.executeCommand(sender, Collections.singletonList(interval));
// then
- ArgumentCaptor captor = ArgumentCaptor.forClass(Long.class);
verify(purgeService).runPurge(eq(sender), captor.capture());
// Check the timestamp with a certain tolerance
@@ -87,3 +92,5 @@ private static void assertIsCloseTo(long value1, long value2, long tolerance) {
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java
similarity index 91%
rename from src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java
index 57bb21e26b..cb291b4bac 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java
@@ -1,16 +1,18 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.service.bungeecord.BungeeSender;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Collections;
@@ -24,7 +26,8 @@
/**
* Test for {@link PurgeLastPositionCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class PurgeLastPositionCommandTest {
@InjectMocks
@@ -116,3 +119,5 @@ private static void verifyPositionWasReset(PlayerAuth auth) {
verify(auth).setWorld("world");
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/PurgePlayerCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/PurgePlayerCommandTest.java
similarity index 90%
rename from src/test/java/fr/xephi/authme/command/executable/authme/PurgePlayerCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/PurgePlayerCommandTest.java
index cf48d2a394..5ccdf94d49 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/PurgePlayerCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/PurgePlayerCommandTest.java
@@ -1,15 +1,17 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.task.purge.PurgeExecutor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Locale;
@@ -27,7 +29,8 @@
/**
* Test for {@link PurgePlayerCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class PurgePlayerCommandTest {
@InjectMocks
@@ -92,3 +95,5 @@ public void shouldExecutePurgeOfRegisteredPlayer() {
verify(purgeExecutor).executePurge(singletonList(player), singletonList(name.toLowerCase(Locale.ROOT)));
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/RecentPlayersCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/RecentPlayersCommandTest.java
similarity index 90%
rename from src/test/java/fr/xephi/authme/command/executable/authme/RecentPlayersCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/RecentPlayersCommandTest.java
index 30ee0e72e2..a39ae352fe 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/RecentPlayersCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/RecentPlayersCommandTest.java
@@ -1,14 +1,16 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
-import org.mockito.junit.MockitoJUnitRunner;
import java.time.ZoneId;
import java.util.Arrays;
@@ -25,7 +27,8 @@
/**
* Test for {@link RecentPlayersCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class RecentPlayersCommandTest {
@InjectMocks
@@ -85,3 +88,5 @@ public void shouldHandlePlayerWithNullLastLogin() {
verify(sender).sendMessage(argThat(equalToIgnoringCase("- silvah777 (11:15 PM, 09 Nov with IP 22.11.22.33)")));
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java
similarity index 94%
rename from src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java
index 9a465d53ae..8e2281e231 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
@@ -12,13 +16,12 @@
import fr.xephi.authme.service.ValidationService.ValidationResult;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Locale;
@@ -36,7 +39,8 @@
/**
* Test for {@link RegisterAdminCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class RegisterAdminCommandTest {
@InjectMocks
@@ -56,8 +60,10 @@ public class RegisterAdminCommandTest {
@Mock
private ValidationService validationService;
+ @Captor
+ private ArgumentCaptor captor;
- @BeforeClass
+ @BeforeAll
public static void setUpLogger() {
TestHelper.setupLogger();
}
@@ -118,7 +124,6 @@ public void shouldHandleSavingError() {
// then
verify(validationService).validatePassword(password, user);
verify(commandService).send(sender, MessageKey.ERROR);
- ArgumentCaptor captor = ArgumentCaptor.forClass(PlayerAuth.class);
verify(dataSource).saveAuth(captor.capture());
assertAuthHasInfo(captor.getValue(), user, hashedPassword);
}
@@ -143,7 +148,6 @@ public void shouldRegisterOfflinePlayer() {
// then
verify(validationService).validatePassword(password, user);
verify(commandService).send(sender, MessageKey.REGISTER_SUCCESS);
- ArgumentCaptor captor = ArgumentCaptor.forClass(PlayerAuth.class);
verify(dataSource).saveAuth(captor.capture());
assertAuthHasInfo(captor.getValue(), user, hashedPassword);
}
@@ -172,7 +176,6 @@ public void shouldRegisterOnlinePlayer() {
// then
verify(validationService).validatePassword(password, user);
verify(commandService).send(sender, MessageKey.REGISTER_SUCCESS);
- ArgumentCaptor captor = ArgumentCaptor.forClass(PlayerAuth.class);
verify(dataSource).saveAuth(captor.capture());
assertAuthHasInfo(captor.getValue(), user, hashedPassword);
verify(player).kickPlayer(kickForAdminRegister);
@@ -184,3 +187,5 @@ private void assertAuthHasInfo(PlayerAuth auth, String name, HashedPassword hash
assertThat(auth.getPassword(), equalTo(hashedPassword));
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java
similarity index 92%
rename from src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java
index 227f1a2630..7261005fb7 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.authme;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import ch.jalu.injector.factory.SingletonStore;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.TestHelper;
@@ -16,13 +20,11 @@
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.command.CommandSender;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Collections;
@@ -36,7 +38,8 @@
/**
* Test for {@link ReloadCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class ReloadCommandTest {
@InjectMocks
@@ -63,12 +66,12 @@ public class ReloadCommandTest {
@Mock
private SingletonStore settingsDependentStore;
- @BeforeClass
+ @BeforeAll
public static void setUpLogger() {
TestHelper.setupLogger();
}
- @Before
+ @BeforeEach
public void setDefaultSettings() {
// Mock properties retrieved by ConsoleLogger
given(settings.getProperty(PluginSettings.LOG_LEVEL)).willReturn(LogLevel.INFO);
@@ -144,3 +147,5 @@ private void verifyReloadingCalls(List reloadables, List singletonStore;
+ @Captor
+ private ArgumentCaptor stringCaptor;
- @Before
+ @BeforeEach
public void setUpLimboCacheMap() {
Map limboMap = new HashMap<>();
limboMap.put("test", mock(LimboPlayer.class));
@@ -83,7 +89,6 @@ public void shouldOutputStatistics() {
dataStatistics.execute(sender, Collections.emptyList());
// then
- ArgumentCaptor stringCaptor = ArgumentCaptor.forClass(String.class);
verify(sender, atLeastOnce()).sendMessage(stringCaptor.capture());
assertThat(stringCaptor.getAllValues(), containsInAnyOrder(
ChatColor.BLUE + "AuthMe statistics",
@@ -109,7 +114,6 @@ public void shouldOutputCachedDataSourceStatistics() {
dataStatistics.execute(sender, Collections.emptyList());
// then
- ArgumentCaptor stringCaptor = ArgumentCaptor.forClass(String.class);
verify(sender, atLeastOnce()).sendMessage(stringCaptor.capture());
assertThat(stringCaptor.getAllValues(), hasItem("Cached PlayerAuth objects: 11"));
}
@@ -119,3 +123,5 @@ private static List mockListOfSize(Class mockClass, int size) {
return Collections.nCopies(size, mock);
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugCommandTest.java
similarity index 93%
rename from src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugCommandTest.java
index a92a065754..67b6daa36b 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugCommandTest.java
@@ -1,18 +1,21 @@
package fr.xephi.authme.command.executable.authme.debug;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import ch.jalu.injector.factory.Factory;
import fr.xephi.authme.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsManager;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
@@ -41,7 +44,8 @@
/**
* Test for {@link DebugCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class DebugCommandTest {
/**
@@ -59,8 +63,10 @@ public class DebugCommandTest {
@Mock
private PermissionsManager permissionsManager;
+ @Captor
+ private ArgumentCaptor strCaptor;
- @Before
+ @BeforeEach
@SuppressWarnings("unchecked")
public void initFactory() {
given(debugSectionFactory.newInstance(any(Class.class))).willAnswer(
@@ -86,7 +92,6 @@ public void shouldListAllAvailableDebugSections() {
verify(debugSectionFactory, atLeast(MIN_DEBUG_SECTIONS)).newInstance(any(Class.class));
verify(permissionsManager, atLeast(MIN_DEBUG_SECTIONS)).hasPermission(eq(sender), any(DebugSectionPermissions.class));
- ArgumentCaptor strCaptor = ArgumentCaptor.forClass(String.class);
verify(sender, times(4)).sendMessage(strCaptor.capture());
assertThat(strCaptor.getAllValues(), contains(
equalTo(ChatColor.BLUE + "AuthMe debug utils"),
@@ -108,7 +113,6 @@ public void shouldNotListAnyDebugSection() {
verify(debugSectionFactory, atLeast(MIN_DEBUG_SECTIONS)).newInstance(any(Class.class));
verify(permissionsManager, atLeast(MIN_DEBUG_SECTIONS)).hasPermission(eq(sender), any(DebugSectionPermissions.class));
- ArgumentCaptor strCaptor = ArgumentCaptor.forClass(String.class);
verify(sender, times(3)).sendMessage(strCaptor.capture());
assertThat(strCaptor.getAllValues(), contains(
equalTo(ChatColor.BLUE + "AuthMe debug utils"),
@@ -156,3 +160,5 @@ public void shouldNotRunSectionForMissingPermission() {
verify(sender).sendMessage(argThat(containsString("You don't have permission")));
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugSectionConsistencyTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugSectionConsistencyTest.java
similarity index 94%
rename from src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugSectionConsistencyTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugSectionConsistencyTest.java
index 26286237b9..511f0f6143 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugSectionConsistencyTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugSectionConsistencyTest.java
@@ -2,8 +2,8 @@
import fr.xephi.authme.ClassCollector;
import fr.xephi.authme.TestHelper;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import java.lang.reflect.Modifier;
import java.util.HashSet;
@@ -14,7 +14,7 @@
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.fail;
/**
* Consistency tests for {@link DebugSection} implementors.
@@ -24,7 +24,7 @@ public class DebugSectionConsistencyTest {
private static List> debugClasses;
private static List debugSections;
- @BeforeClass
+ @BeforeAll
public static void collectClasses() {
// TODO ljacqu 20171021: Improve ClassCollector (pass pkg by class, improve #getInstancesOfType's instantiation)
ClassCollector classCollector = new ClassCollector(
@@ -70,3 +70,4 @@ private static DebugSection instantiate(Class extends DebugSection> clazz) {
}
}
}
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugSectionUtilsTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugSectionUtilsTest.java
similarity index 97%
rename from src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugSectionUtilsTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugSectionUtilsTest.java
index 7f4d556afa..638b943b19 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugSectionUtilsTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugSectionUtilsTest.java
@@ -8,8 +8,8 @@
import fr.xephi.authme.datasource.CacheDataSource;
import fr.xephi.authme.datasource.DataSource;
import org.bukkit.Location;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import java.util.HashMap;
import java.util.Map;
@@ -26,7 +26,7 @@
*/
public class DebugSectionUtilsTest {
- @Before
+ @BeforeEach
public void initMockLogger() {
TestHelper.setupLogger();
}
@@ -123,3 +123,4 @@ public void shouldCastOrReturnNull() {
assertThat(DebugSectionUtils.castToTypeOrNull(5, Integer.class), equalTo(5));
}
}
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionCheckerTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionCheckerTest.java
similarity index 89%
rename from src/test/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionCheckerTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionCheckerTest.java
index 6d5dc18d42..52c73b0b37 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionCheckerTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionCheckerTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.authme.debug;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.ClassCollector;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.permission.AdminPermission;
@@ -8,12 +12,11 @@
import fr.xephi.authme.service.BukkitService;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.List;
import java.util.stream.Collectors;
@@ -33,7 +36,8 @@
/**
* Test for {@link HasPermissionChecker}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class HasPermissionCheckerTest {
@InjectMocks
@@ -44,6 +48,8 @@ public class HasPermissionCheckerTest {
@Mock
private BukkitService bukkitService;
+ @Captor
+ private ArgumentCaptor msgCaptor;
@Test
public void shouldListAllPermissionNodeClasses() {
@@ -67,7 +73,6 @@ public void shouldShowUsageInfo() {
hasPermissionChecker.execute(sender, emptyList());
// then
- ArgumentCaptor msgCaptor = ArgumentCaptor.forClass(String.class);
verify(sender, atLeast(2)).sendMessage(msgCaptor.capture());
assertThat(
msgCaptor.getAllValues().stream().anyMatch(msg -> msg.contains("/authme debug perm bobby my.perm.node")),
@@ -94,3 +99,5 @@ public void shouldShowSuccessfulTestWithRegularPlayer() {
+ "' has permission '" + permission.getNode() + "'")));
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/debug/MySqlDefaultChangerColumnsTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/MySqlDefaultChangerColumnsTest.java
similarity index 96%
rename from src/test/java/fr/xephi/authme/command/executable/authme/debug/MySqlDefaultChangerColumnsTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/MySqlDefaultChangerColumnsTest.java
index 99027e44e4..798df206c7 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/debug/MySqlDefaultChangerColumnsTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/MySqlDefaultChangerColumnsTest.java
@@ -1,13 +1,13 @@
package fr.xephi.authme.command.executable.authme.debug;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import java.util.HashSet;
import java.util.Set;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.fail;
/**
* Consistency test for {@link MySqlDefaultChanger.Columns} enum.
@@ -67,3 +67,4 @@ private void verifyHasSameDefaultValueInNotNullDefinition(MySqlDefaultChanger.Co
}
}
}
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/debug/MySqlDefaultChangerTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/MySqlDefaultChangerTest.java
similarity index 89%
rename from src/test/java/fr/xephi/authme/command/executable/authme/debug/MySqlDefaultChangerTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/MySqlDefaultChangerTest.java
index 98ec5fba6a..f8d814b760 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/debug/MySqlDefaultChangerTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/MySqlDefaultChangerTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.authme.debug;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import com.zaxxer.hikari.HikariDataSource;
import fr.xephi.authme.ReflectionTestUtils;
import fr.xephi.authme.TestHelper;
@@ -9,11 +13,9 @@
import fr.xephi.authme.datasource.MySQL;
import fr.xephi.authme.datasource.SqlDataSourceTestUtil;
import fr.xephi.authme.settings.Settings;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.sql.Connection;
import java.sql.SQLException;
@@ -29,13 +31,14 @@
/**
* Test for {@link MySqlDefaultChanger}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class MySqlDefaultChangerTest {
@Mock
private Settings settings;
- @BeforeClass
+ @BeforeAll
public static void setUpLogger() {
TestHelper.setupLogger();
}
@@ -96,3 +99,5 @@ private MySqlDefaultChanger createDefaultChanger(DataSource dataSource) {
return defaultChanger;
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/debug/PlayerAuthViewerTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/PlayerAuthViewerTest.java
similarity index 90%
rename from src/test/java/fr/xephi/authme/command/executable/authme/debug/PlayerAuthViewerTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/PlayerAuthViewerTest.java
index 3b34f308b0..3372116df8 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/debug/PlayerAuthViewerTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/authme/debug/PlayerAuthViewerTest.java
@@ -1,14 +1,17 @@
package fr.xephi.authme.command.executable.authme.debug;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -24,7 +27,8 @@
/**
* Test for {@link PlayerAuthViewer}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class PlayerAuthViewerTest {
@InjectMocks
@@ -32,6 +36,8 @@ public class PlayerAuthViewerTest {
@Mock
private DataSource dataSource;
+ @Captor
+ private ArgumentCaptor textCaptor;
@Test
public void shouldMakeExample() {
@@ -73,7 +79,6 @@ public void shouldDisplayAuthInfo() {
authViewer.execute(sender, Collections.singletonList("George"));
// then
- ArgumentCaptor textCaptor = ArgumentCaptor.forClass(String.class);
verify(sender, atLeastOnce()).sendMessage(textCaptor.capture());
assertThat(textCaptor.getAllValues(), hasItem(containsString("Player george / George")));
assertThat(textCaptor.getAllValues(), hasItem(containsString("Registration: 2005-03-18T")));
@@ -95,7 +100,6 @@ public void shouldHandleCornerCases() {
authViewer.execute(sender, Collections.singletonList("Tar"));
// then
- ArgumentCaptor textCaptor = ArgumentCaptor.forClass(String.class);
verify(sender, atLeastOnce()).sendMessage(textCaptor.capture());
assertThat(textCaptor.getAllValues(), hasItem(containsString("Player tar / Player")));
assertThat(textCaptor.getAllValues(), hasItem(containsString("Registration: Not available (0)")));
@@ -104,3 +108,5 @@ public void shouldHandleCornerCases() {
assertThat(textCaptor.getAllValues(), hasItem(containsString("TOTP code (partial): ''")));
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java
similarity index 95%
rename from src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java
index 9f47dfae3e..25b2f3a7ec 100644
--- a/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.captcha;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.data.captcha.LoginCaptchaManager;
import fr.xephi.authme.data.captcha.RegistrationCaptchaManager;
@@ -8,11 +12,9 @@
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.CommonService;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -25,7 +27,8 @@
/**
* Test for {@link CaptchaCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class CaptchaCommandTest {
@InjectMocks
@@ -188,3 +191,5 @@ private static Player mockPlayerWithName(String name) {
return player;
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java
similarity index 93%
rename from src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java
index d60a743312..a7bcbe44c9 100644
--- a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.changepassword;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.data.VerificationCodeManager;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.message.MessageKey;
@@ -11,11 +15,9 @@
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Collections;
@@ -35,7 +37,8 @@
/**
* Test for {@link ChangePasswordCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class ChangePasswordCommandTest {
@InjectMocks
@@ -132,3 +135,5 @@ private Player initPlayerWithName(String name, boolean loggedIn) {
return player;
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java
similarity index 87%
rename from src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java
index da067d8146..f262901b69 100644
--- a/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.email;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.process.Management;
@@ -7,11 +11,9 @@
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Collections;
@@ -25,7 +27,8 @@
/**
* Test for {@link AddEmailCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class AddEmailCommandTest {
@InjectMocks
@@ -85,3 +88,5 @@ public void shouldDefineArgumentMismatchMessage() {
assertThat(command.getArgumentsMismatchMessage(), equalTo(MessageKey.USAGE_ADD_EMAIL));
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java
similarity index 90%
rename from src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java
index 9b2e7e0e7b..baa379f4e5 100644
--- a/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.email;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.data.VerificationCodeManager;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
@@ -8,11 +12,9 @@
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Collections;
@@ -28,7 +30,8 @@
/**
* Test for {@link ChangeEmailCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class ChangeEmailCommandTest {
@InjectMocks
@@ -101,3 +104,5 @@ private Player initPlayerWithName(String name) {
return player;
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/email/EmailBaseCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/email/EmailBaseCommandTest.java
similarity index 81%
rename from src/test/java/fr/xephi/authme/command/executable/email/EmailBaseCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/email/EmailBaseCommandTest.java
index 7ca0aff9c0..ddeef1b93a 100644
--- a/src/test/java/fr/xephi/authme/command/executable/email/EmailBaseCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/email/EmailBaseCommandTest.java
@@ -1,14 +1,16 @@
package fr.xephi.authme.command.executable.email;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.command.CommandMapper;
import fr.xephi.authme.command.FoundCommandResult;
import fr.xephi.authme.command.help.HelpProvider;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -21,7 +23,8 @@
/**
* Test for {@link EmailBaseCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class EmailBaseCommandTest {
@InjectMocks
@@ -47,3 +50,5 @@ public void shouldDisplayHelp() {
verify(helpProvider).outputHelp(sender, result, HelpProvider.SHOW_CHILDREN);
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/email/EmailSetPasswordCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/email/EmailSetPasswordCommandTest.java
similarity index 90%
rename from src/test/java/fr/xephi/authme/command/executable/email/EmailSetPasswordCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/email/EmailSetPasswordCommandTest.java
index a0338492e6..5b87821dc4 100644
--- a/src/test/java/fr/xephi/authme/command/executable/email/EmailSetPasswordCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/email/EmailSetPasswordCommandTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.email;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.message.MessageKey;
@@ -9,12 +13,10 @@
import fr.xephi.authme.service.PasswordRecoveryService;
import fr.xephi.authme.service.ValidationService;
import org.bukkit.entity.Player;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -26,7 +28,8 @@
/**
* Tests for {@link EmailSetPasswordCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class EmailSetPasswordCommandTest {
@InjectMocks
@@ -47,7 +50,7 @@ public class EmailSetPasswordCommandTest {
@Mock
private ValidationService validationService;
- @BeforeClass
+ @BeforeAll
public static void setUpLogger() {
TestHelper.setupLogger();
}
@@ -106,3 +109,5 @@ public void shouldDoNothingCantChangePass() {
verify(commonService).send(player, MessageKey.CHANGE_PASSWORD_EXPIRED);
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/email/ProcessCodeCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/email/ProcessCodeCommandTest.java
similarity index 89%
rename from src/test/java/fr/xephi/authme/command/executable/email/ProcessCodeCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/email/ProcessCodeCommandTest.java
index b5790cc44e..fe79e59da0 100644
--- a/src/test/java/fr/xephi/authme/command/executable/email/ProcessCodeCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/email/ProcessCodeCommandTest.java
@@ -1,15 +1,17 @@
package fr.xephi.authme.command.executable.email;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.service.PasswordRecoveryService;
import fr.xephi.authme.service.RecoveryCodeService;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -21,7 +23,8 @@
/**
* Tests for {@link ProcessCodeCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class ProcessCodeCommandTest {
@InjectMocks
@@ -90,3 +93,5 @@ public void shouldProcessCorrectCode() {
verify(codeService).removeCode(name);
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java
similarity index 97%
rename from src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java
index 78fa79813c..63b837660b 100644
--- a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java
@@ -1,8 +1,9 @@
package fr.xephi.authme.command.executable.email;
+import org.junit.jupiter.api.extension.ExtendWith;
+import fr.xephi.authme.DelayedInjectionExtension;
import ch.jalu.datasourcecolumns.data.DataSourceValueImpl;
import ch.jalu.injector.testing.BeforeInjecting;
-import ch.jalu.injector.testing.DelayedInjectionRunner;
import ch.jalu.injector.testing.InjectDelayed;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.auth.PlayerCache;
@@ -17,9 +18,8 @@
import fr.xephi.authme.service.RecoveryCodeService;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.entity.Player;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import java.util.Collections;
@@ -38,7 +38,7 @@
/**
* Test for {@link RecoverEmailCommand}.
*/
-@RunWith(DelayedInjectionRunner.class)
+@ExtendWith(DelayedInjectionExtension.class)
public class RecoverEmailCommandTest {
private static final String DEFAULT_EMAIL = "your@email.com";
@@ -73,7 +73,7 @@ public class RecoverEmailCommandTest {
@Mock
private Messages messages;
- @BeforeClass
+ @BeforeAll
public static void initLogger() {
TestHelper.setupLogger();
}
@@ -229,3 +229,5 @@ public void shouldDefineArgumentMismatchMessage() {
assertThat(command.getArgumentsMismatchMessage(), equalTo(MessageKey.USAGE_RECOVER_EMAIL));
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/email/ShowEmailCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/email/ShowEmailCommandTest.java
similarity index 89%
rename from src/test/java/fr/xephi/authme/command/executable/email/ShowEmailCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/email/ShowEmailCommandTest.java
index 36e106ede0..2e39276649 100644
--- a/src/test/java/fr/xephi/authme/command/executable/email/ShowEmailCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/email/ShowEmailCommandTest.java
@@ -1,16 +1,18 @@
package fr.xephi.authme.command.executable.email;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -21,7 +23,8 @@
/**
* Test for {@link ShowEmailCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class ShowEmailCommandTest {
private static final String CURRENT_EMAIL = "my.email@example.com";
@@ -93,3 +96,5 @@ private static PlayerAuth newAuthWithNoEmail() {
.build();
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java
similarity index 85%
rename from src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java
index 163dde2181..70f7a6d8d9 100644
--- a/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java
@@ -1,16 +1,18 @@
package fr.xephi.authme.command.executable.login;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.process.Management;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -25,7 +27,8 @@
/**
* Test for {@link LoginCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class LoginCommandTest {
@InjectMocks
@@ -69,3 +72,5 @@ public void shouldDefineArgumentMismatchMessage() {
assertThat(command.getArgumentsMismatchMessage(), equalTo(MessageKey.USAGE_LOGIN));
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java
similarity index 83%
rename from src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java
index 55cdd877c8..13dd4e59b9 100644
--- a/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java
@@ -1,16 +1,18 @@
package fr.xephi.authme.command.executable.logout;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.process.Management;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.ArrayList;
import java.util.Collections;
@@ -24,7 +26,8 @@
/**
* Test for {@link LogoutCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class LogoutCommandTest {
@InjectMocks
@@ -63,3 +66,5 @@ public void shouldCallManagementForPlayerCaller() {
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java
similarity index 93%
rename from src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java
index a0c3058845..e643ae396f 100644
--- a/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.register;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.captcha.RegistrationCaptchaManager;
import fr.xephi.authme.mail.EmailService;
@@ -20,13 +24,11 @@
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Collections;
@@ -36,6 +38,7 @@
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
@@ -44,7 +47,8 @@
/**
* Test for {@link RegisterCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class RegisterCommandTest {
@InjectMocks
@@ -68,16 +72,17 @@ public class RegisterCommandTest {
@Mock
private RegistrationCaptchaManager registrationCaptchaManager;
- @BeforeClass
+ @BeforeAll
public static void setup() {
TestHelper.setupLogger();
}
- @Before
+ @BeforeEach
public void linkMocksAndProvideSettingDefaults() {
- given(commonService.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(HashAlgorithm.BCRYPT);
- given(commonService.getProperty(RegistrationSettings.REGISTRATION_TYPE)).willReturn(RegistrationType.PASSWORD);
- given(commonService.getProperty(RegistrationSettings.REGISTER_SECOND_ARGUMENT)).willReturn(RegisterSecondaryArgument.NONE);
+ lenient().when(commonService.getProperty(SecuritySettings.PASSWORD_HASH)).thenReturn(HashAlgorithm.BCRYPT);
+ lenient().when(commonService.getProperty(RegistrationSettings.REGISTRATION_TYPE)).thenReturn(RegistrationType.PASSWORD);
+ lenient().when(commonService.getProperty(RegistrationSettings.REGISTER_SECOND_ARGUMENT))
+ .thenReturn(RegisterSecondaryArgument.NONE);
}
@Test
@@ -334,3 +339,5 @@ private static Player mockPlayerWithName(String name) {
return player;
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/totp/AddTotpCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/totp/AddTotpCommandTest.java
similarity index 90%
rename from src/test/java/fr/xephi/authme/command/executable/totp/AddTotpCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/totp/AddTotpCommandTest.java
index 598200c584..9897e02313 100644
--- a/src/test/java/fr/xephi/authme/command/executable/totp/AddTotpCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/totp/AddTotpCommandTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.totp;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.message.MessageKey;
@@ -7,11 +11,9 @@
import fr.xephi.authme.security.totp.GenerateTotpService;
import fr.xephi.authme.security.totp.TotpAuthenticator.TotpGenerationResult;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -23,7 +25,8 @@
/**
* Test for {@link AddTotpCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class AddTotpCommandTest {
@InjectMocks
@@ -91,3 +94,5 @@ private static Player mockPlayerWithName(String name) {
return player;
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/totp/ConfirmTotpCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/totp/ConfirmTotpCommandTest.java
similarity index 94%
rename from src/test/java/fr/xephi/authme/command/executable/totp/ConfirmTotpCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/totp/ConfirmTotpCommandTest.java
index d3d3d025c2..6a80ffd77d 100644
--- a/src/test/java/fr/xephi/authme/command/executable/totp/ConfirmTotpCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/totp/ConfirmTotpCommandTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.totp;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache;
@@ -9,12 +13,10 @@
import fr.xephi.authme.security.totp.GenerateTotpService;
import fr.xephi.authme.security.totp.TotpAuthenticator.TotpGenerationResult;
import org.bukkit.entity.Player;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -32,7 +34,8 @@
/**
* Test for {@link ConfirmTotpCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class ConfirmTotpCommandTest {
@InjectMocks
@@ -47,7 +50,7 @@ public class ConfirmTotpCommandTest {
@Mock
private Messages messages;
- @BeforeClass
+ @BeforeAll
public static void setUpLogger() {
TestHelper.setupLogger();
}
@@ -156,3 +159,5 @@ public void shouldHandleMissingAuthAccount() {
verify(messages).send(player, MessageKey.NOT_LOGGED_IN);
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/totp/RemoveTotpCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/totp/RemoveTotpCommandTest.java
similarity index 93%
rename from src/test/java/fr/xephi/authme/command/executable/totp/RemoveTotpCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/totp/RemoveTotpCommandTest.java
index d0ae8f3410..82db90351f 100644
--- a/src/test/java/fr/xephi/authme/command/executable/totp/RemoveTotpCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/totp/RemoveTotpCommandTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.totp;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache;
@@ -8,12 +12,10 @@
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.security.totp.TotpAuthenticator;
import org.bukkit.entity.Player;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import static java.util.Collections.singletonList;
import static org.hamcrest.Matchers.nullValue;
@@ -27,7 +29,8 @@
/**
* Test for {@link RemoveTotpCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class RemoveTotpCommandTest {
@InjectMocks
@@ -42,7 +45,7 @@ public class RemoveTotpCommandTest {
@Mock
private Messages messages;
- @BeforeClass
+ @BeforeAll
public static void setUpLogger() {
TestHelper.setupLogger();
}
@@ -147,3 +150,5 @@ public void shouldHandleNonLoggedInUser() {
verify(playerCache, only()).getAuth(name);
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/totp/TotpBaseCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/totp/TotpBaseCommandTest.java
similarity index 80%
rename from src/test/java/fr/xephi/authme/command/executable/totp/TotpBaseCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/totp/TotpBaseCommandTest.java
index 0e279f6874..1a0e194aab 100644
--- a/src/test/java/fr/xephi/authme/command/executable/totp/TotpBaseCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/totp/TotpBaseCommandTest.java
@@ -1,14 +1,16 @@
package fr.xephi.authme.command.executable.totp;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.command.CommandMapper;
import fr.xephi.authme.command.FoundCommandResult;
import fr.xephi.authme.command.help.HelpProvider;
import org.bukkit.command.CommandSender;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -19,7 +21,8 @@
/**
* Test for {@link TotpBaseCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class TotpBaseCommandTest {
@InjectMocks
@@ -45,3 +48,5 @@ public void shouldOutputHelp() {
verify(helpProvider).outputHelp(sender, mappingResult, HelpProvider.SHOW_CHILDREN);
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java
similarity index 92%
rename from src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java
index 7667b375cc..0c8385a6e8 100644
--- a/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.command.executable.unregister;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.data.VerificationCodeManager;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.message.MessageKey;
@@ -8,11 +12,9 @@
import fr.xephi.authme.service.CommonService;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -28,7 +30,8 @@
/**
* Test for {@link UnregisterCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class UnregisterCommandTest {
@InjectMocks
@@ -124,3 +127,5 @@ public void shouldDefineArgumentMismatchMessage() {
assertThat(command.getArgumentsMismatchMessage(), equalTo(MessageKey.USAGE_UNREGISTER));
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/executable/verification/VerificationCommandTest.java b/authme-core/src/test/java/fr/xephi/authme/command/executable/verification/VerificationCommandTest.java
similarity index 93%
rename from src/test/java/fr/xephi/authme/command/executable/verification/VerificationCommandTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/executable/verification/VerificationCommandTest.java
index 80ae565b7f..f0618c62ab 100644
--- a/src/test/java/fr/xephi/authme/command/executable/verification/VerificationCommandTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/executable/verification/VerificationCommandTest.java
@@ -1,16 +1,18 @@
package fr.xephi.authme.command.executable.verification;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.VerificationCodeManager;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.CommonService;
import org.bukkit.entity.Player;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -23,7 +25,8 @@
/**
* Test for {@link VerificationCommand}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class VerificationCommandTest {
@InjectMocks
@@ -35,7 +38,7 @@ public class VerificationCommandTest {
@Mock
private VerificationCodeManager codeManager;
- @BeforeClass
+ @BeforeAll
public static void setUpLogger() {
TestHelper.setupLogger();
}
@@ -166,3 +169,5 @@ private static Player mockPlayerWithName(String name) {
return player;
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/help/HelpMessageAndHelpSectionConsistencyTest.java b/authme-core/src/test/java/fr/xephi/authme/command/help/HelpMessageAndHelpSectionConsistencyTest.java
similarity index 93%
rename from src/test/java/fr/xephi/authme/command/help/HelpMessageAndHelpSectionConsistencyTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/help/HelpMessageAndHelpSectionConsistencyTest.java
index 30eddba19d..1dd2b8df2d 100644
--- a/src/test/java/fr/xephi/authme/command/help/HelpMessageAndHelpSectionConsistencyTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/help/HelpMessageAndHelpSectionConsistencyTest.java
@@ -1,14 +1,14 @@
package fr.xephi.authme.command.help;
import fr.xephi.authme.util.StringUtils;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import java.util.HashSet;
import java.util.Set;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.fail;
/**
* Test for enums {@link HelpMessage} and {@link HelpSection}.
@@ -37,3 +37,4 @@ public void shouldHaveUniqueNonEmptyKeys() {
}
}
}
+
diff --git a/src/test/java/fr/xephi/authme/command/help/HelpMessagesConsistencyTest.java b/authme-core/src/test/java/fr/xephi/authme/command/help/HelpMessagesConsistencyTest.java
similarity index 99%
rename from src/test/java/fr/xephi/authme/command/help/HelpMessagesConsistencyTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/help/HelpMessagesConsistencyTest.java
index b91be4e6ad..0e9cfb3982 100644
--- a/src/test/java/fr/xephi/authme/command/help/HelpMessagesConsistencyTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/help/HelpMessagesConsistencyTest.java
@@ -9,7 +9,7 @@
import org.bukkit.configuration.MemorySection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.Collection;
@@ -95,3 +95,4 @@ private static CommandDescription getAuthMeRegisterDescription() {
.findFirst().get();
}
}
+
diff --git a/src/test/java/fr/xephi/authme/command/help/HelpMessagesServiceTest.java b/authme-core/src/test/java/fr/xephi/authme/command/help/HelpMessagesServiceTest.java
similarity index 96%
rename from src/test/java/fr/xephi/authme/command/help/HelpMessagesServiceTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/help/HelpMessagesServiceTest.java
index 3c3f267ce7..62b5fe9fdb 100644
--- a/src/test/java/fr/xephi/authme/command/help/HelpMessagesServiceTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/help/HelpMessagesServiceTest.java
@@ -11,10 +11,9 @@
import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import fr.xephi.authme.TempFolder;
import java.io.File;
import java.io.IOException;
@@ -37,12 +36,10 @@ public class HelpMessagesServiceTest {
private static final Collection COMMANDS = TestCommandsUtil.generateCommands();
private HelpMessagesService helpMessagesService;
-
- @Rule
- public TemporaryFolder temporaryFolder = new TemporaryFolder();
+ public TempFolder temporaryFolder = new TempFolder();
private File dataFolder;
- @Before
+ @BeforeEach
public void initializeHandler() throws IOException {
dataFolder = temporaryFolder.newFolder();
new File(dataFolder, "messages").mkdirs();
@@ -158,3 +155,5 @@ private HelpMessagesFileHandler createMessagesFileHandler() {
return messagesFileHandler;
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/command/help/HelpProviderTest.java b/authme-core/src/test/java/fr/xephi/authme/command/help/HelpProviderTest.java
similarity index 97%
rename from src/test/java/fr/xephi/authme/command/help/HelpProviderTest.java
rename to authme-core/src/test/java/fr/xephi/authme/command/help/HelpProviderTest.java
index d1d1755361..c42aecec47 100644
--- a/src/test/java/fr/xephi/authme/command/help/HelpProviderTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/command/help/HelpProviderTest.java
@@ -1,7 +1,8 @@
package fr.xephi.authme.command.help;
+import org.junit.jupiter.api.extension.ExtendWith;
+import fr.xephi.authme.DelayedInjectionExtension;
import ch.jalu.injector.testing.BeforeInjecting;
-import ch.jalu.injector.testing.DelayedInjectionRunner;
import ch.jalu.injector.testing.InjectDelayed;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.FoundCommandResult;
@@ -12,12 +13,12 @@
import fr.xephi.authme.permission.PermissionsManager;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.internal.stubbing.answers.ReturnsArgumentAt;
+import static org.mockito.AdditionalAnswers.returnsFirstArg;
import java.util.Arrays;
import java.util.Collection;
@@ -51,7 +52,7 @@
/**
* Test for {@link HelpProvider}.
*/
-@RunWith(DelayedInjectionRunner.class)
+@ExtendWith(DelayedInjectionExtension.class)
public class HelpProviderTest {
private static Collection commands;
@@ -64,8 +65,10 @@ public class HelpProviderTest {
private HelpMessagesService helpMessagesService;
@Mock
private CommandSender sender;
+ @Captor
+ private ArgumentCaptor captor;
- @BeforeClass
+ @BeforeAll
public static void setUpCommands() {
commands = TestCommandsUtil.generateCommands();
}
@@ -437,15 +440,14 @@ private static String removeColors(String str) {
return str;
}
- private static List getLines(CommandSender sender) {
- ArgumentCaptor captor = ArgumentCaptor.forClass(String.class);
+ private List getLines(CommandSender sender) {
verify(sender, atLeastOnce()).sendMessage(captor.capture());
return captor.getAllValues().stream().map(s -> removeColors(s)).collect(Collectors.toList());
}
private static void setDefaultHelpMessages(HelpMessagesService helpMessagesService) {
given(helpMessagesService.buildLocalizedDescription(any(CommandDescription.class)))
- .willAnswer(new ReturnsArgumentAt(0));
+ .willAnswer(returnsFirstArg());
for (HelpMessage key : HelpMessage.values()) {
String text = key.name().replace("_", " ").toLowerCase(Locale.ROOT);
given(helpMessagesService.getMessage(key))
@@ -464,3 +466,5 @@ private static void setDefaultHelpMessages(HelpMessagesService helpMessagesServi
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/data/QuickCommandsProtectionManagerTest.java b/authme-core/src/test/java/fr/xephi/authme/data/QuickCommandsProtectionManagerTest.java
similarity index 88%
rename from src/test/java/fr/xephi/authme/data/QuickCommandsProtectionManagerTest.java
rename to authme-core/src/test/java/fr/xephi/authme/data/QuickCommandsProtectionManagerTest.java
index f46bbce126..9352d060f9 100644
--- a/src/test/java/fr/xephi/authme/data/QuickCommandsProtectionManagerTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/data/QuickCommandsProtectionManagerTest.java
@@ -1,14 +1,16 @@
package fr.xephi.authme.data;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.ProtectionSettings;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -18,7 +20,8 @@
/**
* Test for {@link QuickCommandsProtectionManager}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class QuickCommandsProtectionManagerTest {
@Mock
@@ -78,3 +81,5 @@ private static Player mockPlayerWithName(String name) {
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/data/TempbanManagerTest.java b/authme-core/src/test/java/fr/xephi/authme/data/TempbanManagerTest.java
similarity index 91%
rename from src/test/java/fr/xephi/authme/data/TempbanManagerTest.java
rename to authme-core/src/test/java/fr/xephi/authme/data/TempbanManagerTest.java
index ce5c977480..652f04664e 100644
--- a/src/test/java/fr/xephi/authme/data/TempbanManagerTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/data/TempbanManagerTest.java
@@ -1,5 +1,9 @@
package fr.xephi.authme.data;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.ReflectionTestUtils;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.message.MessageKey;
@@ -9,17 +13,18 @@
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.expiring.TimedCounter;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
+import static fr.xephi.authme.service.BukkitServiceTestHelper.setBukkitServiceToRunOnGlobalRegion;
+import static fr.xephi.authme.service.BukkitServiceTestHelper.setBukkitServiceToScheduleSyncTaskFromOptionallyAsyncTask;
import static fr.xephi.authme.service.BukkitServiceTestHelper.setBukkitServiceToScheduleSyncDelayedTask;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
@@ -34,7 +39,8 @@
/**
* Test for {@link TempbanManager}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class TempbanManagerTest {
private static final long DATE_TOLERANCE_MILLISECONDS = 200L;
@@ -45,6 +51,8 @@ public class TempbanManagerTest {
@Mock
private Messages messages;
+ @Captor
+ private ArgumentCaptor captor;
@Test
public void shouldAddCounts() {
@@ -152,14 +160,14 @@ public void shouldBanPlayerIp() {
given(messages.retrieveSingle(player, MessageKey.TEMPBAN_MAX_LOGINS)).willReturn(banReason);
Settings settings = mockSettings(2, 100, "");
TempbanManager manager = new TempbanManager(bukkitService, messages, settings);
- setBukkitServiceToScheduleSyncDelayedTask(bukkitService);
+ setBukkitServiceToRunOnGlobalRegion(bukkitService);
+ setBukkitServiceToScheduleSyncTaskFromOptionallyAsyncTask(bukkitService);
// when
manager.tempbanPlayer(player);
// then
verify(player).kickPlayer(banReason);
- ArgumentCaptor captor = ArgumentCaptor.forClass(Date.class);
verify(bukkitService).banIp(eq(ip), eq(banReason), captor.capture(), eq("AuthMe"));
// Compute the expected expiration date and check that the actual date is within the difference tolerance
@@ -179,7 +187,7 @@ public void shouldBanPlayerIpCustom() {
String banCommand = "banip %ip% 15d IP ban too many logins";
Settings settings = mockSettings(2, 100, banCommand);
TempbanManager manager = new TempbanManager(bukkitService, messages, settings);
- setBukkitServiceToScheduleSyncDelayedTask(bukkitService);
+ setBukkitServiceToRunOnGlobalRegion(bukkitService);
// when
manager.tempbanPlayer(player);
@@ -201,7 +209,8 @@ public void shouldResetCountAfterBan() {
manager.increaseCount(ip, "user");
manager.increaseCount(ip, "name2");
manager.increaseCount(ip, "user");
- setBukkitServiceToScheduleSyncDelayedTask(bukkitService);
+ setBukkitServiceToRunOnGlobalRegion(bukkitService);
+ setBukkitServiceToScheduleSyncTaskFromOptionallyAsyncTask(bukkitService);
// when
manager.tempbanPlayer(player);
@@ -263,3 +272,5 @@ private static TimedCounter mockCounter() {
return mock(TimedCounter.class);
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/data/VerificationCodeManagerTest.java b/authme-core/src/test/java/fr/xephi/authme/data/VerificationCodeManagerTest.java
similarity index 71%
rename from src/test/java/fr/xephi/authme/data/VerificationCodeManagerTest.java
rename to authme-core/src/test/java/fr/xephi/authme/data/VerificationCodeManagerTest.java
index 7486a895e2..55ebe1d4bd 100644
--- a/src/test/java/fr/xephi/authme/data/VerificationCodeManagerTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/data/VerificationCodeManagerTest.java
@@ -9,24 +9,35 @@
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.entity.Player;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import static fr.xephi.authme.service.BukkitServiceTestHelper.setBukkitServiceToRunTaskAsynchronously;
-import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.only;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
/**
* Test for {@link VerificationCodeManager}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class VerificationCodeManagerTest {
@Mock
@@ -44,7 +55,10 @@ public class VerificationCodeManagerTest {
@Mock
private BukkitService bukkitService;
- @Before
+ @Captor
+ private ArgumentCaptor runnableCaptor;
+
+ @BeforeEach
public void setUpBasicBehavior() {
given(emailService.hasAllInformation()).willReturn(true);
given(settings.getProperty(SecuritySettings.VERIFICATION_CODE_EXPIRATION_MINUTES)).willReturn(1);
@@ -111,6 +125,7 @@ public void shouldGenerateCode() {
String player = "ILoveTests";
String email = "ilovetests@test.com";
given(dataSource.getEmail(player)).willReturn(DataSourceValueImpl.of(email));
+ setBukkitServiceToRunTaskAsynchronously(bukkitService);
VerificationCodeManager codeManager1 = createCodeManager();
VerificationCodeManager codeManager2 = createCodeManager();
codeManager2.codeExistOrGenerateNew(player);
@@ -130,6 +145,7 @@ public void shouldRequireCode() {
String player = "ILoveTests";
String email = "ilovetests@test.com";
given(dataSource.getEmail(player)).willReturn(DataSourceValueImpl.of(email));
+ setBukkitServiceToRunTaskAsynchronously(bukkitService);
VerificationCodeManager codeManager1 = createCodeManager();
VerificationCodeManager codeManager2 = createCodeManager();
codeManager2.codeExistOrGenerateNew(player);
@@ -150,6 +166,7 @@ public void shouldVerifyCode() {
String code = "193458";
String email = "ilovetests@test.com";
given(dataSource.getEmail(player)).willReturn(DataSourceValueImpl.of(email));
+ setBukkitServiceToRunTaskAsynchronously(bukkitService);
VerificationCodeManager codeManager1 = createCodeManager();
VerificationCodeManager codeManager2 = createCodeManager();
codeManager1.codeExistOrGenerateNew(player);
@@ -163,6 +180,45 @@ public void shouldVerifyCode() {
assertThat(test2, equalTo(false));
}
+ @Test
+ public void shouldLookupEmailOnlyInAsyncTask() {
+ // given
+ String player = "ILoveTests";
+ String email = "ilovetests@test.com";
+ VerificationCodeManager codeManager = createCodeManager();
+
+ // when
+ codeManager.codeExistOrGenerateNew(player);
+
+ // then
+ verify(bukkitService).runTaskAsynchronously(runnableCaptor.capture());
+ verifyNoInteractions(dataSource);
+ verify(emailService, only()).hasAllInformation();
+
+ given(dataSource.getEmail(player)).willReturn(DataSourceValueImpl.of(email));
+ runnableCaptor.getValue().run();
+
+ assertThat(codeManager.hasCode(player), equalTo(true));
+ verify(dataSource).getEmail(player);
+ verify(emailService).sendVerificationMail(eq(player), eq(email), anyString());
+ }
+
+ @Test
+ public void shouldNotScheduleDuplicateCodeGenerationWhilePending() {
+ // given
+ String player = "ILoveTests";
+ VerificationCodeManager codeManager = createCodeManager();
+
+ // when
+ codeManager.codeExistOrGenerateNew(player);
+ codeManager.codeExistOrGenerateNew(player);
+
+ // then
+ verify(bukkitService, times(1)).runTaskAsynchronously(any(Runnable.class));
+ verifyNoInteractions(dataSource);
+ verify(emailService, only()).hasAllInformation();
+ }
+
private VerificationCodeManager createCodeManager() {
return new VerificationCodeManager(settings, dataSource, emailService, permissionsManager, bukkitService);
}
@@ -173,3 +229,5 @@ private static Player mockPlayerWithName(String name) {
return player;
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/data/auth/PlayerAuthTest.java b/authme-core/src/test/java/fr/xephi/authme/data/auth/PlayerAuthTest.java
similarity index 95%
rename from src/test/java/fr/xephi/authme/data/auth/PlayerAuthTest.java
rename to authme-core/src/test/java/fr/xephi/authme/data/auth/PlayerAuthTest.java
index 360abdc986..292674ac22 100644
--- a/src/test/java/fr/xephi/authme/data/auth/PlayerAuthTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/data/auth/PlayerAuthTest.java
@@ -1,11 +1,11 @@
package fr.xephi.authme.data.auth;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.fail;
/**
* Test for {@link PlayerAuth} and its builder.
@@ -67,3 +67,4 @@ public void shouldCreatePlayerAuthWithNullValues() {
assertThat(auth.getPitch(), equalTo(123.004f));
}
}
+
diff --git a/src/test/java/fr/xephi/authme/data/captcha/LoginCaptchaManagerTest.java b/authme-core/src/test/java/fr/xephi/authme/data/captcha/LoginCaptchaManagerTest.java
similarity index 99%
rename from src/test/java/fr/xephi/authme/data/captcha/LoginCaptchaManagerTest.java
rename to authme-core/src/test/java/fr/xephi/authme/data/captcha/LoginCaptchaManagerTest.java
index c313fc571b..19d09171c3 100644
--- a/src/test/java/fr/xephi/authme/data/captcha/LoginCaptchaManagerTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/data/captcha/LoginCaptchaManagerTest.java
@@ -5,7 +5,7 @@
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.expiring.TimedCounter;
import org.bukkit.entity.Player;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import java.util.Locale;
@@ -172,3 +172,4 @@ private static void assertHasCount(LoginCaptchaManager manager, String player, I
assertThat(playerCounts.get(player.toLowerCase(Locale.ROOT)), equalTo(count));
}
}
+
diff --git a/src/test/java/fr/xephi/authme/data/captcha/RegistrationCaptchaManagerTest.java b/authme-core/src/test/java/fr/xephi/authme/data/captcha/RegistrationCaptchaManagerTest.java
similarity index 99%
rename from src/test/java/fr/xephi/authme/data/captcha/RegistrationCaptchaManagerTest.java
rename to authme-core/src/test/java/fr/xephi/authme/data/captcha/RegistrationCaptchaManagerTest.java
index 07aeaf0b8b..b532a05f6a 100644
--- a/src/test/java/fr/xephi/authme/data/captcha/RegistrationCaptchaManagerTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/data/captcha/RegistrationCaptchaManagerTest.java
@@ -5,7 +5,7 @@
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.expiring.ExpiringMap;
import org.bukkit.entity.Player;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import static fr.xephi.authme.AuthMeMatchers.stringWithLength;
import static org.hamcrest.Matchers.equalTo;
@@ -91,3 +91,4 @@ private static ExpiringMap getCodeMap(RegistrationCaptchaManager
return ReflectionTestUtils.getFieldValue(CaptchaCodeStorage.class, captchaStorage, "captchaCodes");
}
}
+
diff --git a/src/test/java/fr/xephi/authme/data/limbo/AllowFlightRestoreTypeTest.java b/authme-core/src/test/java/fr/xephi/authme/data/limbo/AllowFlightRestoreTypeTest.java
similarity index 98%
rename from src/test/java/fr/xephi/authme/data/limbo/AllowFlightRestoreTypeTest.java
rename to authme-core/src/test/java/fr/xephi/authme/data/limbo/AllowFlightRestoreTypeTest.java
index eb7ee38936..ac0b55aba2 100644
--- a/src/test/java/fr/xephi/authme/data/limbo/AllowFlightRestoreTypeTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/data/limbo/AllowFlightRestoreTypeTest.java
@@ -1,7 +1,7 @@
package fr.xephi.authme.data.limbo;
import org.bukkit.entity.Player;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
@@ -107,3 +107,4 @@ private static LimboPlayer newLimboWithAllowFlight(boolean allowFlight) {
return limbo;
}
}
+
diff --git a/src/test/java/fr/xephi/authme/data/limbo/LimboPlayerMatchers.java b/authme-core/src/test/java/fr/xephi/authme/data/limbo/LimboPlayerMatchers.java
similarity index 100%
rename from src/test/java/fr/xephi/authme/data/limbo/LimboPlayerMatchers.java
rename to authme-core/src/test/java/fr/xephi/authme/data/limbo/LimboPlayerMatchers.java
diff --git a/src/test/java/fr/xephi/authme/data/limbo/LimboPlayerTaskManagerTest.java b/authme-core/src/test/java/fr/xephi/authme/data/limbo/LimboPlayerTaskManagerTest.java
similarity index 67%
rename from src/test/java/fr/xephi/authme/data/limbo/LimboPlayerTaskManagerTest.java
rename to authme-core/src/test/java/fr/xephi/authme/data/limbo/LimboPlayerTaskManagerTest.java
index fdc82abe6b..0143ab626d 100644
--- a/src/test/java/fr/xephi/authme/data/limbo/LimboPlayerTaskManagerTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/data/limbo/LimboPlayerTaskManagerTest.java
@@ -1,24 +1,26 @@
package fr.xephi.authme.data.limbo;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.data.captcha.RegistrationCaptchaManager;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.service.BukkitService;
+import fr.xephi.authme.service.CancellableTask;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask;
import org.bukkit.entity.Player;
-import org.bukkit.scheduler.BukkitTask;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -39,7 +41,8 @@
/**
* Test for {@link LimboPlayerTaskManager}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class LimboPlayerTaskManagerTest {
@InjectMocks
@@ -60,7 +63,7 @@ public class LimboPlayerTaskManagerTest {
@Mock
private RegistrationCaptchaManager registrationCaptchaManager;
- @BeforeClass
+ @BeforeAll
public static void setupLogger() {
TestHelper.setupLogger();
}
@@ -74,14 +77,16 @@ public void shouldRegisterMessageTask() {
given(messages.retrieveSingle(player, key)).willReturn("Please register!");
int interval = 12;
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(interval);
+ given(bukkitService.runTaskTimer(eq(player), any(MessageTask.class), anyLong(), anyLong()))
+ .willReturn(mock(CancellableTask.class));
// when
limboPlayerTaskManager.registerMessageTask(player, limboPlayer, LimboMessageType.REGISTER);
// then
- verify(limboPlayer).setMessageTask(any(MessageTask.class));
+ verify(limboPlayer).setMessageTask(any(MessageTask.class), any(CancellableTask.class));
verify(messages).retrieveSingle(player, key);
- verify(bukkitService).runTaskTimer(
+ verify(bukkitService).runTaskTimer(eq(player),
any(MessageTask.class), eq(2L * TICKS_PER_SECOND), eq((long) interval * TICKS_PER_SECOND));
}
@@ -145,32 +150,64 @@ public void shouldInitializeMessageTaskWithCaptchaMessage() {
}
@Test
- public void shouldRegisterTimeoutTask() {
+ public void shouldRegisterLoginTimeoutTask() {
// given
Player player = mock(Player.class);
LimboPlayer limboPlayer = mock(LimboPlayer.class);
- given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(30);
- BukkitTask bukkitTask = mock(BukkitTask.class);
- given(bukkitService.runTaskLater(any(TimeoutTask.class), anyLong())).willReturn(bukkitTask);
+ given(settings.getProperty(RestrictionSettings.LOGIN_TIMEOUT)).willReturn(30);
+ CancellableTask bukkitTask = mock(CancellableTask.class);
+ given(bukkitService.runTaskLater(eq(player), any(TimeoutTask.class), anyLong())).willReturn(bukkitTask);
// when
- limboPlayerTaskManager.registerTimeoutTask(player, limboPlayer);
+ limboPlayerTaskManager.registerTimeoutTask(player, limboPlayer, LimboMessageType.LOG_IN);
// then
verify(limboPlayer).setTimeoutTask(bukkitTask);
- verify(bukkitService).runTaskLater(any(TimeoutTask.class), eq(600L)); // 30 * TICKS_PER_SECOND
+ verify(bukkitService).runTaskLater(eq(player), any(TimeoutTask.class), eq(600L)); // 30 * TICKS_PER_SECOND
verify(messages).retrieveSingle(player, MessageKey.LOGIN_TIMEOUT_ERROR);
}
@Test
- public void shouldNotRegisterTimeoutTaskForZeroTimeout() {
+ public void shouldRegisterRegisterTimeoutTask() {
// given
Player player = mock(Player.class);
LimboPlayer limboPlayer = mock(LimboPlayer.class);
- given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(0);
+ given(settings.getProperty(RestrictionSettings.REGISTER_TIMEOUT)).willReturn(60);
+ CancellableTask bukkitTask = mock(CancellableTask.class);
+ given(bukkitService.runTaskLater(eq(player), any(TimeoutTask.class), anyLong())).willReturn(bukkitTask);
// when
- limboPlayerTaskManager.registerTimeoutTask(player, limboPlayer);
+ limboPlayerTaskManager.registerTimeoutTask(player, limboPlayer, LimboMessageType.REGISTER);
+
+ // then
+ verify(limboPlayer).setTimeoutTask(bukkitTask);
+ verify(bukkitService).runTaskLater(eq(player), any(TimeoutTask.class), eq(1200L)); // 60 * TICKS_PER_SECOND
+ verify(messages).retrieveSingle(player, MessageKey.LOGIN_TIMEOUT_ERROR);
+ }
+
+ @Test
+ public void shouldNotRegisterTimeoutTaskForZeroLoginTimeout() {
+ // given
+ Player player = mock(Player.class);
+ LimboPlayer limboPlayer = mock(LimboPlayer.class);
+ given(settings.getProperty(RestrictionSettings.LOGIN_TIMEOUT)).willReturn(0);
+
+ // when
+ limboPlayerTaskManager.registerTimeoutTask(player, limboPlayer, LimboMessageType.LOG_IN);
+
+ // then
+ verifyNoInteractions(limboPlayer, bukkitService);
+ }
+
+ @Test
+ public void shouldNotRegisterTimeoutTaskForZeroRegisterTimeout() {
+ // given
+ Player player = mock(Player.class);
+ LimboPlayer limboPlayer = mock(LimboPlayer.class);
+ given(settings.getProperty(RestrictionSettings.REGISTER_TIMEOUT)).willReturn(0);
+
+ // when
+ limboPlayerTaskManager.registerTimeoutTask(player, limboPlayer, LimboMessageType.REGISTER);
// then
verifyNoInteractions(limboPlayer, bukkitService);
@@ -181,20 +218,22 @@ public void shouldCancelExistingTimeoutTask() {
// given
Player player = mock(Player.class);
LimboPlayer limboPlayer = new LimboPlayer(null, false, Collections.emptyList(), true, 0.3f, 0.1f);
- BukkitTask existingTask = mock(BukkitTask.class);
+ CancellableTask existingTask = mock(CancellableTask.class);
limboPlayer.setTimeoutTask(existingTask);
- given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(18);
- BukkitTask bukkitTask = mock(BukkitTask.class);
- given(bukkitService.runTaskLater(any(TimeoutTask.class), anyLong())).willReturn(bukkitTask);
+ given(settings.getProperty(RestrictionSettings.LOGIN_TIMEOUT)).willReturn(18);
+ CancellableTask bukkitTask = mock(CancellableTask.class);
+ given(bukkitService.runTaskLater(eq(player), any(TimeoutTask.class), anyLong())).willReturn(bukkitTask);
// when
- limboPlayerTaskManager.registerTimeoutTask(player, limboPlayer);
+ limboPlayerTaskManager.registerTimeoutTask(player, limboPlayer, LimboMessageType.LOG_IN);
// then
verify(existingTask).cancel();
assertThat(limboPlayer.getTimeoutTask(), equalTo(bukkitTask));
- verify(bukkitService).runTaskLater(any(TimeoutTask.class), eq(360L)); // 18 * TICKS_PER_SECOND
+ verify(bukkitService).runTaskLater(eq(player), any(TimeoutTask.class), eq(360L)); // 18 * TICKS_PER_SECOND
verify(messages).retrieveSingle(player, MessageKey.LOGIN_TIMEOUT_ERROR);
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/data/limbo/LimboServiceHelperTest.java b/authme-core/src/test/java/fr/xephi/authme/data/limbo/LimboServiceHelperTest.java
similarity index 89%
rename from src/test/java/fr/xephi/authme/data/limbo/LimboServiceHelperTest.java
rename to authme-core/src/test/java/fr/xephi/authme/data/limbo/LimboServiceHelperTest.java
index f5c3fc21e5..da0278675d 100644
--- a/src/test/java/fr/xephi/authme/data/limbo/LimboServiceHelperTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/data/limbo/LimboServiceHelperTest.java
@@ -1,12 +1,14 @@
package fr.xephi.authme.data.limbo;
+import org.mockito.quality.Strictness;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
import fr.xephi.authme.TestHelper;
import org.bukkit.Location;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
-import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
@@ -22,13 +24,14 @@
*
* Note: some methods are tested directly where they are used via {@link LimboServiceTest}.
*/
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.WARN)
public class LimboServiceHelperTest {
@InjectMocks
private LimboServiceHelper limboServiceHelper;
- @BeforeClass
+ @BeforeAll
public static void initLogger() {
TestHelper.setupLogger();
}
@@ -91,3 +94,5 @@ public void shouldHandleNullInputs() {
assertThat(result3, nullValue());
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/data/limbo/LimboServiceTest.java b/authme-core/src/test/java/fr/xephi/authme/data/limbo/LimboServiceTest.java
similarity index 85%
rename from src/test/java/fr/xephi/authme/data/limbo/LimboServiceTest.java
rename to authme-core/src/test/java/fr/xephi/authme/data/limbo/LimboServiceTest.java
index aadab82b41..4117d6994e 100644
--- a/src/test/java/fr/xephi/authme/data/limbo/LimboServiceTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/data/limbo/LimboServiceTest.java
@@ -1,21 +1,22 @@
package fr.xephi.authme.data.limbo;
-import ch.jalu.injector.testing.DelayedInjectionRunner;
+import org.junit.jupiter.api.extension.ExtendWith;
+import fr.xephi.authme.DelayedInjectionExtension;
import ch.jalu.injector.testing.InjectDelayed;
import fr.xephi.authme.ReflectionTestUtils;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.limbo.persistence.LimboPersistence;
import fr.xephi.authme.permission.PermissionsManager;
+import fr.xephi.authme.service.TeleportationService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.properties.LimboSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import org.bukkit.Location;
import org.bukkit.entity.Player;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
@@ -29,6 +30,7 @@
import static org.hamcrest.Matchers.sameInstance;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
@@ -39,7 +41,7 @@
/**
* Test for {@link LimboService}, and {@link LimboServiceHelper}.
*/
-@RunWith(DelayedInjectionRunner.class)
+@ExtendWith(DelayedInjectionExtension.class)
public class LimboServiceTest {
@InjectDelayed
@@ -66,14 +68,19 @@ public class LimboServiceTest {
@Mock
private AuthGroupHandler authGroupHandler;
- @BeforeClass
+ @Mock
+ private TeleportationService teleportationService;
+
+ @BeforeAll
public static void initLogger() {
TestHelper.setupLogger();
}
- @Before
+ @BeforeEach
public void mockSettings() {
given(settings.getProperty(RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT)).willReturn(false);
+ given(teleportationService.consumeOriginalJoinLocation(anyString(), any()))
+ .willAnswer(invocation -> invocation.getArgument(1));
}
@Test
@@ -91,7 +98,7 @@ public void shouldCreateLimboPlayer() {
// then
verify(taskManager).registerMessageTask(eq(player), any(LimboPlayer.class), eq(LimboMessageType.LOG_IN));
- verify(taskManager).registerTimeoutTask(eq(player), any(LimboPlayer.class));
+ verify(taskManager).registerTimeoutTask(eq(player), any(LimboPlayer.class), eq(LimboMessageType.LOG_IN));
verify(player).setAllowFlight(false);
verify(player).setFlySpeed(0.0f);
verify(player).setWalkSpeed(0.0f);
@@ -122,7 +129,7 @@ public void shouldNotKeepOpStatusForUnregisteredPlayer() {
// then
verify(taskManager).registerMessageTask(eq(player), any(LimboPlayer.class), eq(LimboMessageType.REGISTER));
- verify(taskManager).registerTimeoutTask(eq(player), any(LimboPlayer.class));
+ verify(taskManager).registerTimeoutTask(eq(player), any(LimboPlayer.class), eq(LimboMessageType.REGISTER));
verify(permissionsManager, only()).hasGroupSupport();
verify(player).setAllowFlight(false);
verify(player).setFlySpeed(0.0f);
@@ -158,6 +165,25 @@ public void shouldClearTasksOnAlreadyExistingLimbo() {
assertThat(newLimbo, not(sameInstance(existingLimbo)));
}
+ @Test
+ public void shouldUseRememberedJoinLocationWhenCreatingLimboPlayer() {
+ // given
+ Player player = newPlayer("Bobby", true, 0.3f, false, 0.2f);
+ Location fallbackLocation = mock(Location.class);
+ Location rememberedJoinLocation = mock(Location.class);
+ given(spawnLoader.getPlayerLocationOrSpawn(player)).willReturn(fallbackLocation);
+ given(teleportationService.consumeOriginalJoinLocation("bobby", fallbackLocation))
+ .willReturn(rememberedJoinLocation);
+ given(permissionsManager.hasGroupSupport()).willReturn(false);
+ given(settings.getProperty(LimboSettings.RESTORE_ALLOW_FLIGHT)).willReturn(AllowFlightRestoreType.ENABLE);
+
+ // when
+ limboService.createLimboPlayer(player, true);
+
+ // then
+ assertThat(limboService.getLimboPlayer("Bobby").getLocation(), equalTo(rememberedJoinLocation));
+ }
+
@Test
public void shouldRestoreData() {
// given
@@ -226,7 +252,7 @@ public void shouldReplaceTasks() {
limboService.replaceTasksAfterRegistration(player);
// then
- verify(taskManager).registerTimeoutTask(player, limbo);
+ verify(taskManager).registerTimeoutTask(player, limbo, LimboMessageType.LOG_IN);
verify(taskManager).registerMessageTask(player, limbo, LimboMessageType.LOG_IN);
verify(authGroupHandler).setGroup(player, limbo, AuthGroupType.REGISTERED_UNAUTHENTICATED);
}
@@ -268,3 +294,5 @@ private Map getLimboMap() {
return ReflectionTestUtils.getFieldValue(LimboService.class, limboService, "entries");
}
}
+
+
diff --git a/src/test/java/fr/xephi/authme/data/limbo/WalkFlySpeedRestoreTypeTest.java b/authme-core/src/test/java/fr/xephi/authme/data/limbo/WalkFlySpeedRestoreTypeTest.java
similarity index 84%
rename from src/test/java/fr/xephi/authme/data/limbo/WalkFlySpeedRestoreTypeTest.java
rename to authme-core/src/test/java/fr/xephi/authme/data/limbo/WalkFlySpeedRestoreTypeTest.java
index f8aa2719c7..c348c377c8 100644
--- a/src/test/java/fr/xephi/authme/data/limbo/WalkFlySpeedRestoreTypeTest.java
+++ b/authme-core/src/test/java/fr/xephi/authme/data/limbo/WalkFlySpeedRestoreTypeTest.java
@@ -1,13 +1,11 @@
package fr.xephi.authme.data.limbo;
import org.bukkit.entity.Player;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
import java.util.Arrays;
import java.util.List;
-import java.util.stream.Collectors;
import static fr.xephi.authme.data.limbo.LimboPlayer.DEFAULT_FLY_SPEED;
import static fr.xephi.authme.data.limbo.LimboPlayer.DEFAULT_WALK_SPEED;
@@ -22,17 +20,11 @@
/**
* Test for {@link WalkFlySpeedRestoreType}.
*/
-@RunWith(Parameterized.class)
public class WalkFlySpeedRestoreTypeTest {
- private final TestParameters parameters;
-
- public WalkFlySpeedRestoreTypeTest(TestParameters parameters) {
- this.parameters = parameters;
- }
-
- @Test
- public void shouldRestoreToExpectedValue() {
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("buildParams")
+ public void shouldRestoreToExpectedValue(TestParameters parameters) {
// given
LimboPlayer limbo = mock(LimboPlayer.class);
given(limbo.getWalkSpeed()).willReturn(parameters.givenLimboWalkSpeed);
@@ -50,10 +42,10 @@ public void shouldRestoreToExpectedValue() {
verify(player).setWalkSpeed(parameters.expectedWalkSpeed);
verify(player).setFlySpeed(parameters.expectedFlySpeed);
}
+
- @Parameterized.Parameters(name = "{0}")
- public static List