diff --git a/pom.xml b/pom.xml
index fd994681a..94c8b48ee 100644
--- a/pom.xml
+++ b/pom.xml
@@ -376,13 +376,19 @@
compile
true
-
+
org.xerial
sqlite-jdbc
3.8.11.2
test
+
+ com.h2database
+ h2
+ 1.4.191
+ test
+
diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java
index e37f5a49d..bdc1b73e4 100644
--- a/src/main/java/fr/xephi/authme/AuthMe.java
+++ b/src/main/java/fr/xephi/authme/AuthMe.java
@@ -743,25 +743,9 @@ public class AuthMe extends JavaPlugin {
}
// Return the spawn location of a player
+ @Deprecated
public Location getSpawnLocation(Player player) {
- World world = player.getWorld();
- String[] spawnPriority = Settings.spawnPriority.split(",");
- Location spawnLoc = world.getSpawnLocation();
- for (int i = spawnPriority.length - 1; i >= 0; i--) {
- String s = spawnPriority[i];
- if (s.equalsIgnoreCase("default") && getDefaultSpawn(world) != null)
- spawnLoc = getDefaultSpawn(world);
- if (s.equalsIgnoreCase("multiverse") && getMultiverseSpawn(world) != null)
- spawnLoc = getMultiverseSpawn(world);
- if (s.equalsIgnoreCase("essentials") && getEssentialsSpawn() != null)
- spawnLoc = getEssentialsSpawn();
- if (s.equalsIgnoreCase("authme") && getAuthMeSpawn(player) != null)
- spawnLoc = getAuthMeSpawn(player);
- }
- if (spawnLoc == null) {
- spawnLoc = world.getSpawnLocation();
- }
- return spawnLoc;
+ return Spawn.getInstance().getSpawnLocation(player);
}
// Return the default spawn point of a world
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java
index 3dce54e17..0c7adf2ff 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java
@@ -5,6 +5,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.output.MessageKey;
+import fr.xephi.authme.settings.Spawn;
import org.bukkit.command.CommandSender;
import java.util.List;
@@ -20,6 +21,7 @@ public class ReloadCommand implements ExecutableCommand {
try {
commandService.getSettings().reload();
commandService.reloadMessages(commandService.getSettings().getMessagesFile());
+ Spawn.reload();
// TODO #432: We should not reload only certain plugin entities but actually reinitialize all elements,
// i.e. here in the future we might not have setupDatabase() but Authme.onEnable(), maybe after
// a call to some destructor method
diff --git a/src/main/java/fr/xephi/authme/datasource/MySQL.java b/src/main/java/fr/xephi/authme/datasource/MySQL.java
index a2f43c7e1..99ba7247e 100644
--- a/src/main/java/fr/xephi/authme/datasource/MySQL.java
+++ b/src/main/java/fr/xephi/authme/datasource/MySQL.java
@@ -22,7 +22,6 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
-import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
@@ -82,6 +81,19 @@ public class MySQL implements DataSource {
}
}
+ MySQL(NewSetting settings, HikariDataSource hikariDataSource) {
+ this.host = settings.getProperty(DatabaseSettings.MYSQL_HOST);
+ this.port = settings.getProperty(DatabaseSettings.MYSQL_PORT);
+ this.username = settings.getProperty(DatabaseSettings.MYSQL_USERNAME);
+ this.password = settings.getProperty(DatabaseSettings.MYSQL_PASSWORD);
+ this.database = settings.getProperty(DatabaseSettings.MYSQL_DATABASE);
+ this.tableName = settings.getProperty(DatabaseSettings.MYSQL_TABLE);
+ this.columnOthers = settings.getProperty(HooksSettings.MYSQL_OTHER_USERNAME_COLS);
+ this.col = new Columns(settings);
+ this.hashAlgorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH);
+ ds = hikariDataSource;
+ }
+
private synchronized void setConnectionArguments() throws RuntimeException {
ds = new HikariDataSource();
ds.setPoolName("AuthMeMYSQLPool");
@@ -131,7 +143,7 @@ public class MySQL implements DataSource {
+ col.REAL_NAME + " VARCHAR(255) NOT NULL,"
+ col.PASSWORD + " VARCHAR(255) NOT NULL,"
+ col.IP + " VARCHAR(40) NOT NULL DEFAULT '127.0.0.1',"
- + col.LAST_LOGIN + " TIMESTAMP NOT NULL DEFAULT current_timestamp,"
+ + col.LAST_LOGIN + " BIGINT NOT NULL DEFAULT 0,"
+ col.LASTLOC_X + " DOUBLE NOT NULL DEFAULT '0.0',"
+ col.LASTLOC_Y + " DOUBLE NOT NULL DEFAULT '0.0',"
+ col.LASTLOC_Z + " DOUBLE NOT NULL DEFAULT '0.0',"
@@ -182,9 +194,9 @@ public class MySQL implements DataSource {
rs = md.getColumns(null, null, tableName, col.LAST_LOGIN);
if (!rs.next()) {
st.executeUpdate("ALTER TABLE " + tableName
- + " ADD COLUMN " + col.LAST_LOGIN + " TIMESTAMP NOT NULL DEFAULT current_timestamp;");
+ + " ADD COLUMN " + col.LAST_LOGIN + " BIGINT NOT NULL DEFAULT 0;");
} else {
- migrateLastLoginColumnToTimestamp(con, rs);
+ migrateLastLoginColumnToBigInt(con, rs);
}
rs.close();
@@ -320,7 +332,7 @@ public class MySQL implements DataSource {
pst.setString(1, auth.getNickname());
pst.setString(2, auth.getPassword().getHash());
pst.setString(3, auth.getIp());
- pst.setTimestamp(4, new Timestamp(auth.getLastLogin()));
+ pst.setLong(4, auth.getLastLogin());
pst.setString(5, auth.getRealName());
pst.setString(6, auth.getEmail());
if (useSalt) {
@@ -572,7 +584,7 @@ public class MySQL implements DataSource {
+ col.IP + "=?, " + col.LAST_LOGIN + "=?, " + col.REAL_NAME + "=? WHERE " + col.NAME + "=?;";
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
pst.setString(1, auth.getIp());
- pst.setTimestamp(2, new Timestamp(auth.getLastLogin()));
+ pst.setLong(2, auth.getLastLogin());
pst.setString(3, auth.getRealName());
pst.setString(4, auth.getNickname());
pst.executeUpdate();
@@ -925,7 +937,7 @@ public class MySQL implements DataSource {
.name(row.getString(col.NAME))
.realName(row.getString(col.REAL_NAME))
.password(row.getString(col.PASSWORD), salt)
- .lastLogin(safeGetTimestamp(row))
+ .lastLogin(row.getLong(col.LAST_LOGIN))
.ip(row.getString(col.IP))
.locWorld(row.getString(col.LASTLOC_WORLD))
.locX(row.getDouble(col.LASTLOC_X))
@@ -937,24 +949,15 @@ public class MySQL implements DataSource {
}
/**
- * Retrieve the last login timestamp in a safe way.
+ * Check if the lastlogin column is of type timestamp and, if so, revert it to the bigint format.
*
- * @param row The ResultSet to read
- * @return The timestamp (as number of milliseconds since 1970-01-01 00:00:00 GMT)
+ * @param con Connection to the database
+ * @param rs ResultSet containing meta data for the lastlogin column
*/
- private long safeGetTimestamp(ResultSet row) {
- try {
- return row.getTimestamp(col.LAST_LOGIN).getTime();
- } catch (SQLException e) {
- ConsoleLogger.logException("Could not get timestamp from resultSet. Defaulting to current time", e);
- }
- return System.currentTimeMillis();
- }
-
- private void migrateLastLoginColumnToTimestamp(Connection con, ResultSet rs) throws SQLException {
+ private void migrateLastLoginColumnToBigInt(Connection con, ResultSet rs) throws SQLException {
final int columnType = rs.getInt("DATA_TYPE");
- if (columnType == Types.BIGINT) {
- ConsoleLogger.info("Migrating lastlogin column from bigint to timestamp");
+ if (columnType == Types.TIMESTAMP) {
+ ConsoleLogger.info("Migrating lastlogin column from timestamp to bigint");
final String lastLoginOld = col.LAST_LOGIN + "_old";
// Rename lastlogin to lastlogin_old
@@ -965,12 +968,12 @@ public class MySQL implements DataSource {
// Create lastlogin column
sql = String.format("ALTER TABLE %s ADD COLUMN %s "
- + "TIMESTAMP NOT NULL DEFAULT current_timestamp AFTER %s",
+ + "BIGINT NOT NULL DEFAULT 0 AFTER %s",
tableName, col.LAST_LOGIN, col.IP);
con.prepareStatement(sql).execute();
// Set values of lastlogin based on lastlogin_old
- sql = String.format("UPDATE %s SET %s = FROM_UNIXTIME(%s)",
+ sql = String.format("UPDATE %s SET %s = UNIX_TIMESTAMP(%s)",
tableName, col.LAST_LOGIN, lastLoginOld);
con.prepareStatement(sql).execute();
@@ -978,7 +981,7 @@ public class MySQL implements DataSource {
sql = String.format("ALTER TABLE %s DROP COLUMN %s",
tableName, lastLoginOld);
con.prepareStatement(sql).execute();
- ConsoleLogger.info("Finished migration of lastlogin (bigint to timestamp)");
+ ConsoleLogger.info("Finished migration of lastlogin (timestamp to bigint)");
}
}
diff --git a/src/main/java/fr/xephi/authme/datasource/SQLite.java b/src/main/java/fr/xephi/authme/datasource/SQLite.java
index 787b6b0c5..f7f18b324 100644
--- a/src/main/java/fr/xephi/authme/datasource/SQLite.java
+++ b/src/main/java/fr/xephi/authme/datasource/SQLite.java
@@ -48,18 +48,11 @@ public class SQLite implements DataSource {
}
@VisibleForTesting
- SQLite(NewSetting settings, Connection connection, boolean executeSetup) {
+ SQLite(NewSetting settings, Connection connection) {
this.database = settings.getProperty(DatabaseSettings.MYSQL_DATABASE);
this.tableName = settings.getProperty(DatabaseSettings.MYSQL_TABLE);
this.col = new Columns(settings);
this.con = connection;
- if (executeSetup) {
- try {
- setup();
- } catch (SQLException e) {
- throw new IllegalStateException(e);
- }
- }
}
private synchronized void connect() throws ClassNotFoundException, SQLException {
@@ -357,7 +350,8 @@ public class SQLite implements DataSource {
@Override
public synchronized void close() {
try {
- con.close();
+ if (con != null && !con.isClosed())
+ con.close();
} catch (SQLException ex) {
logSqlException(ex);
}
diff --git a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java
index 56918026c..d563f33c0 100644
--- a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java
+++ b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java
@@ -17,7 +17,6 @@ import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.GeoLiteAPI;
import fr.xephi.authme.util.Utils;
import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@@ -243,9 +242,7 @@ public class AuthMePlayerListener implements Listener {
String realName = auth.getRealName();
if (!realName.isEmpty() && !realName.equals("Player") && !realName.equals(event.getName())) {
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
- // TODO: Add a message like : MessageKey.INVALID_NAME_CASE
- event.setKickMessage("You should join using username: " + ChatColor.AQUA + realName +
- ChatColor.RESET + "\nnot: " + ChatColor.RED + event.getName());
+ event.setKickMessage(m.retrieveSingle(MessageKey.INVALID_NAME_CASE, realName, event.getName()));
return;
}
if (realName.isEmpty() || realName.equals("Player")) {
diff --git a/src/main/java/fr/xephi/authme/output/MessageKey.java b/src/main/java/fr/xephi/authme/output/MessageKey.java
index d5e601207..45cdc0bef 100644
--- a/src/main/java/fr/xephi/authme/output/MessageKey.java
+++ b/src/main/java/fr/xephi/authme/output/MessageKey.java
@@ -127,7 +127,9 @@ public enum MessageKey {
TWO_FACTOR_CREATE("two_factor_create", "%code", "%url"),
- NOT_OWNER_ERROR("not_owner_error");
+ NOT_OWNER_ERROR("not_owner_error"),
+
+ INVALID_NAME_CASE("invalid_name_case", "%valid", "%invalid");
private String key;
private String[] tags;
diff --git a/src/main/java/fr/xephi/authme/output/Messages.java b/src/main/java/fr/xephi/authme/output/Messages.java
index 5afba4726..9ea87f448 100644
--- a/src/main/java/fr/xephi/authme/output/Messages.java
+++ b/src/main/java/fr/xephi/authme/output/Messages.java
@@ -55,17 +55,7 @@ public class Messages {
* @param replacements The replacements to apply for the tags
*/
public void send(CommandSender sender, MessageKey key, String... replacements) {
- String message = retrieveSingle(key);
- String[] tags = key.getTags();
- if (replacements.length == tags.length) {
- for (int i = 0; i < tags.length; ++i) {
- message = message.replace(tags[i], replacements[i]);
- }
- } else {
- ConsoleLogger.showError("Invalid number of replacements for message key '" + key + "'");
- send(sender, key);
- }
-
+ String message = retrieveSingle(key, replacements);
for (String line : message.split("\n")) {
sender.sendMessage(line);
}
@@ -99,6 +89,27 @@ public class Messages {
return StringUtils.join("\n", retrieve(key));
}
+ /**
+ * Retrieve the given message code with the given tag replacements. Note that this method
+ * logs an error if the number of supplied replacements doesn't correspond to the number of tags
+ * the message key contains.
+ *
+ * @param key The key of the message to send
+ * @param replacements The replacements to apply for the tags
+ */
+ public String retrieveSingle(MessageKey key, String... replacements) {
+ String message = retrieveSingle(key);
+ String[] tags = key.getTags();
+ if (replacements.length == tags.length) {
+ for (int i = 0; i < tags.length; ++i) {
+ message = message.replace(tags[i], replacements[i]);
+ }
+ } else {
+ ConsoleLogger.showError("Invalid number of replacements for message key '" + key + "'");
+ }
+ return message;
+ }
+
/**
* Reload the messages manager.
*
diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java
index 7ba3b3b18..8e5bf2c9e 100644
--- a/src/main/java/fr/xephi/authme/settings/Settings.java
+++ b/src/main/java/fr/xephi/authme/settings/Settings.java
@@ -5,6 +5,7 @@ import fr.xephi.authme.datasource.DataSourceType;
import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.settings.domain.Property;
import fr.xephi.authme.settings.properties.DatabaseSettings;
+import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
@@ -176,7 +177,7 @@ public final class Settings {
emailRegistration = configFile.getBoolean("settings.registration.enableEmailRegistrationSystem", false);
saltLength = configFile.getInt("settings.security.doubleMD5SaltLength", 8);
getmaxRegPerEmail = configFile.getInt("Email.maxRegPerEmail", 1);
- multiverse = configFile.getBoolean("Hooks.multiverse", true);
+ multiverse = load(HooksSettings.MULTIVERSE);
bungee = configFile.getBoolean("Hooks.bungeecord", false);
getForcedWorlds = configFile.getStringList("settings.restrictions.ForceSpawnOnTheseWorlds");
banUnsafeIp = configFile.getBoolean("settings.restrictions.banUnsafedIP", false);
@@ -213,7 +214,7 @@ public final class Settings {
broadcastWelcomeMessage = configFile.getBoolean("settings.broadcastWelcomeMessage", false);
forceRegKick = configFile.getBoolean("settings.registration.forceKickAfterRegister", false);
forceRegLogin = configFile.getBoolean("settings.registration.forceLoginAfterRegister", false);
- spawnPriority = configFile.getString("settings.restrictions.spawnPriority", "authme,essentials,multiverse,default");
+ spawnPriority = load(RestrictionSettings.SPAWN_PRIORITY);
getMaxLoginPerIp = configFile.getInt("settings.restrictions.maxLoginPerIp", 0);
getMaxJoinPerIp = configFile.getInt("settings.restrictions.maxJoinPerIp", 0);
checkVeryGames = configFile.getBoolean("VeryGames.enableIpCheck", false);
diff --git a/src/main/java/fr/xephi/authme/settings/Spawn.java b/src/main/java/fr/xephi/authme/settings/Spawn.java
index 4c20b2960..275a8d0e0 100644
--- a/src/main/java/fr/xephi/authme/settings/Spawn.java
+++ b/src/main/java/fr/xephi/authme/settings/Spawn.java
@@ -1,7 +1,14 @@
package fr.xephi.authme.settings;
+import com.onarandombox.MultiverseCore.api.MVWorldManager;
+import fr.xephi.authme.AuthMe;
+import fr.xephi.authme.ConsoleLogger;
+import fr.xephi.authme.cache.auth.PlayerCache;
+import fr.xephi.authme.util.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
import java.io.File;
@@ -12,13 +19,17 @@ import java.io.File;
public class Spawn extends CustomConfiguration {
private static Spawn spawn;
+ private static String[] spawnPriority;
- public Spawn() {
- super(new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "spawn.yml"));
- spawn = this;
- load();
- save();
- saveDefault();
+ private Spawn() {
+ super(new File(Settings.PLUGIN_FOLDER, "spawn.yml"));
+ reload();
+ }
+
+ public static void reload() {
+ getInstance().load();
+ getInstance().save();
+ spawnPriority = Settings.spawnPriority.split(",");
}
/**
@@ -33,111 +44,108 @@ public class Spawn extends CustomConfiguration {
return spawn;
}
- private void saveDefault() {
- if (!contains("spawn")) {
- set("spawn.world", "");
- set("spawn.x", "");
- set("spawn.y", "");
- set("spawn.z", "");
- set("spawn.yaw", "");
- set("spawn.pitch", "");
- save();
- }
- if (!contains("firstspawn")) {
- set("firstspawn.world", "");
- set("firstspawn.x", "");
- set("firstspawn.y", "");
- set("firstspawn.z", "");
- set("firstspawn.yaw", "");
- set("firstspawn.pitch", "");
- save();
- }
- }
-
- /**
- * Method setSpawn.
- *
- * @param location Location
- *
- * @return boolean
- */
public boolean setSpawn(Location location) {
- try {
- set("spawn.world", location.getWorld().getName());
- set("spawn.x", location.getX());
- set("spawn.y", location.getY());
- set("spawn.z", location.getZ());
- set("spawn.yaw", location.getYaw());
- set("spawn.pitch", location.getPitch());
- save();
- return true;
- } catch (NullPointerException npe) {
+ if (location == null || location.getWorld() == null) {
return false;
}
+ set("spawn.world", location.getWorld().getName());
+ set("spawn.x", location.getX());
+ set("spawn.y", location.getY());
+ set("spawn.z", location.getZ());
+ set("spawn.yaw", location.getYaw());
+ set("spawn.pitch", location.getPitch());
+ save();
+ return true;
}
- /**
- * Method setFirstSpawn.
- *
- * @param location Location
- *
- * @return boolean
- */
public boolean setFirstSpawn(Location location) {
- try {
- set("firstspawn.world", location.getWorld().getName());
- set("firstspawn.x", location.getX());
- set("firstspawn.y", location.getY());
- set("firstspawn.z", location.getZ());
- set("firstspawn.yaw", location.getYaw());
- set("firstspawn.pitch", location.getPitch());
- save();
- return true;
- } catch (NullPointerException npe) {
+ if (location == null || location.getWorld() == null) {
return false;
}
+ set("firstspawn.world", location.getWorld().getName());
+ set("firstspawn.x", location.getX());
+ set("firstspawn.y", location.getY());
+ set("firstspawn.z", location.getZ());
+ set("firstspawn.yaw", location.getYaw());
+ set("firstspawn.pitch", location.getPitch());
+ save();
+ return true;
}
- /**
- * Method getLocation.
- *
- * @return Location
- */
- @Deprecated
- public Location getLocation() {
- return getSpawn();
- }
-
- /**
- * Method getSpawn.
- *
- * @return Location
- */
public Location getSpawn() {
try {
- if (this.getString("spawn.world").isEmpty() || this.getString("spawn.world").equals(""))
+ String worldName = getString("spawn.world");
+ World world = Bukkit.getWorld(worldName);
+ if (StringUtils.isEmpty(worldName) || world == null) {
return null;
- Location location = new Location(Bukkit.getWorld(this.getString("spawn.world")), this.getDouble("spawn.x"), this.getDouble("spawn.y"), this.getDouble("spawn.z"), Float.parseFloat(this.getString("spawn.yaw")), Float.parseFloat(this.getString("spawn.pitch")));
- return location;
- } catch (NullPointerException | NumberFormatException npe) {
+ }
+ return new Location(world, getDouble("spawn.x"), getDouble("spawn.y"), getDouble("spawn.z"),
+ Float.parseFloat(getString("spawn.yaw")), Float.parseFloat(getString("spawn.pitch")));
+ } catch (NumberFormatException e) {
+ ConsoleLogger.writeStackTrace(e);
return null;
}
}
- /**
- * Method getFirstSpawn.
- *
- * @return Location
- */
public Location getFirstSpawn() {
try {
- if (this.getString("firstspawn.world").isEmpty() || this.getString("firstspawn.world").equals(""))
+ String worldName;
+ World world;
+ if (StringUtils.isEmpty(worldName = getString("firstspawn.world")) ||
+ (world = Bukkit.getWorld(worldName)) == null) {
return null;
- Location location = new Location(Bukkit.getWorld(this.getString("firstspawn.world")), this.getDouble("firstspawn.x"), this.getDouble("firstspawn.y"), this.getDouble("firstspawn.z"), Float.parseFloat(this.getString("firstspawn.yaw")), Float.parseFloat(this.getString("firstspawn.pitch")));
- return location;
- } catch (NullPointerException | NumberFormatException npe) {
+ }
+ return new Location(world, getDouble("firstspawn.x"), getDouble("firstspawn.y"), getDouble("firstspawn.z"),
+ Float.parseFloat(getString("firstspawn.yaw")), Float.parseFloat(getString("firstspawn.pitch")));
+ } catch (NumberFormatException e) {
+ ConsoleLogger.writeStackTrace(e);
return null;
}
}
+ // Return the spawn location of a player
+ public Location getSpawnLocation(Player player) {
+ AuthMe plugin = AuthMe.getInstance();
+ if (plugin == null || player == null || player.getWorld() == null) {
+ return null;
+ }
+
+ World world = player.getWorld();
+ Location spawnLoc = null;
+ for (String priority : spawnPriority) {
+ switch (priority.toLowerCase()) {
+ case "default":
+ if (world.getSpawnLocation() != null) {
+ spawnLoc = world.getSpawnLocation();
+ }
+ break;
+ case "multiverse":
+ if (Settings.multiverse && plugin.multiverse != null) {
+ MVWorldManager manager = plugin.multiverse.getMVWorldManager();
+ if (manager.isMVWorld(world)) {
+ spawnLoc = manager.getMVWorld(world).getSpawnLocation();
+ }
+ }
+ break;
+ case "essentials":
+ spawnLoc = plugin.essentialsSpawn;
+ break;
+ case "authme":
+ String playerNameLower = player.getName().toLowerCase();
+ if (PlayerCache.getInstance().isAuthenticated(playerNameLower)) {
+ spawnLoc = getSpawn();
+ } else if ((getFirstSpawn() != null) && (!player.hasPlayedBefore() ||
+ (!plugin.getDataSource().isAuthAvailable(playerNameLower)))) {
+ spawnLoc = getFirstSpawn();
+ } else {
+ spawnLoc = getSpawn();
+ }
+ break;
+ }
+ if (spawnLoc != null) {
+ return spawnLoc;
+ }
+ }
+ return world.getSpawnLocation(); // return default location
+ }
}
diff --git a/src/main/resources/messages/messages_bg.yml b/src/main/resources/messages/messages_bg.yml
index 4370c00b7..94e32f38f 100644
--- a/src/main/resources/messages/messages_bg.yml
+++ b/src/main/resources/messages/messages_bg.yml
@@ -58,6 +58,7 @@ antibot_auto_disabled: '[AuthMe] AntiBotMod автоматично изключ
# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO invalid_session: '&cYour IP has been changed and your session data has expired!'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_br.yml b/src/main/resources/messages/messages_br.yml
index dfaab23dd..246627773 100644
--- a/src/main/resources/messages/messages_br.yml
+++ b/src/main/resources/messages/messages_br.yml
@@ -44,7 +44,7 @@ usage_captcha: '&3Para logar você deve resolver o captcha, por favor use o coma
wrong_captcha: '&cCaptcha inválido, por favor escreva "/captcha THE_CAPTCHA"'
valid_captcha: '&2Código do captcha correto!'
kick_forvip: '&3Um vip entrou no servidor!'
-kick_fullserver: '&4Servidor esta cheio! Para entrar mesmo cheio compre vip no site www.site.com.br'
+kick_fullserver: '&4Servidor esta cheio, tente outra vez mais tarde'
usage_email_add: '&cUse: /email add '
usage_email_change: '&cUse: /email change '
usage_email_recovery: '&cUse: /email recovery '
@@ -56,10 +56,10 @@ email_confirm: '&cPor favor confirme o email!'
email_changed: '&2Email mudado com sucesso!'
email_send: '&2Email de recuperação enviado com sucesso! !'
email_exists: '&cUm email de recuperação já foi enviado! Você pode reenviar outro usando o comando:'
-country_banned: '&4Seu país foi banido do servidor! Your country is banned from this server!'
+country_banned: '&4Seu país foi banido do servidor!'
antibot_auto_enabled: '&4[AntiBotService] AntiBot ativado devido ao grande número de conexões!'
antibot_auto_disabled: '&2[AntiBotService] AntiBot desativado após %m minutos!'
-# TODO two_factor_create: Missing tag %url
-two_factor_create: '&2Seu código secreto é %code'
-# TODO email_already_used: '&4The email address is already being used'
-# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
+two_factor_create: '&2Seu código secreto é %code. Você pode escanear ele daqui %url'
+email_already_used: '&4Este endereço de email já está em uso'
+not_owner_error: 'Você não é o dono desta conta. Por favor, tente outro nome!'
+invalid_name_case: 'Você deve entrar usando %valid, não %invalid.'
diff --git a/src/main/resources/messages/messages_cz.yml b/src/main/resources/messages/messages_cz.yml
index d56a6d423..580a12bc8 100644
--- a/src/main/resources/messages/messages_cz.yml
+++ b/src/main/resources/messages/messages_cz.yml
@@ -58,5 +58,6 @@ antibot_auto_disabled: '[AuthMe] AntiBotMod automaticky ukoncen po %m minutach,
# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_de.yml b/src/main/resources/messages/messages_de.yml
index eb62ce309..942460ac0 100644
--- a/src/main/resources/messages/messages_de.yml
+++ b/src/main/resources/messages/messages_de.yml
@@ -60,4 +60,5 @@ kick_antibot: 'AntiBotMod ist aktiviert! Bitte warte einige Minuten, bevor du di
# TODO two_factor_create: Missing tag %url
two_factor_create: '&2Dein geheimer Code ist %code'
# TODO email_already_used: '&4The email address is already being used'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_en.yml b/src/main/resources/messages/messages_en.yml
index 0b7c96bfb..64aa90993 100644
--- a/src/main/resources/messages/messages_en.yml
+++ b/src/main/resources/messages/messages_en.yml
@@ -60,3 +60,4 @@ antibot_auto_disabled: '&2[AntiBotService] AntiBot disabled disabled after %m mi
email_already_used: '&4The email address is already being used'
two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
not_owner_error: 'You are not the owner of this account. Please try another name!'
+invalid_name_case: 'You should join using username %valid, not %invalid.'
diff --git a/src/main/resources/messages/messages_es.yml b/src/main/resources/messages/messages_es.yml
index 6fd0dbc19..df415952a 100644
--- a/src/main/resources/messages/messages_es.yml
+++ b/src/main/resources/messages/messages_es.yml
@@ -59,5 +59,6 @@ antibot_auto_disabled: '[AuthMe] AntiBotMod desactivado automáticamente luego d
# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_eu.yml b/src/main/resources/messages/messages_eu.yml
index bddf751d7..b490aeebf 100644
--- a/src/main/resources/messages/messages_eu.yml
+++ b/src/main/resources/messages/messages_eu.yml
@@ -52,6 +52,7 @@ country_banned: '[AuthMe] Zure herrialdea blokeatuta dago zerbitzari honetan'
# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO antibot_auto_enabled: '&4[AntiBotService] AntiBot enabled due to the huge number of connections!'
# TODO invalid_session: '&cYour IP has been changed and your session data has expired!'
# TODO wrong_captcha: '&cWrong captcha, please type "/captcha THE_CAPTCHA" into the chat!'
diff --git a/src/main/resources/messages/messages_fi.yml b/src/main/resources/messages/messages_fi.yml
index 2e26e512d..80e6cd4fd 100644
--- a/src/main/resources/messages/messages_fi.yml
+++ b/src/main/resources/messages/messages_fi.yml
@@ -55,6 +55,7 @@ email_send: '[AuthMe] Palautus sähköposti lähetetty!'
# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO country_banned: '&4Your country is banned from this server!'
# TODO antibot_auto_enabled: '&4[AntiBotService] AntiBot enabled due to the huge number of connections!'
# TODO antibot_auto_disabled: '&2[AntiBotService] AntiBot disabled disabled after %m minutes!'
diff --git a/src/main/resources/messages/messages_fr.yml b/src/main/resources/messages/messages_fr.yml
index 31a944714..153cceb47 100644
--- a/src/main/resources/messages/messages_fr.yml
+++ b/src/main/resources/messages/messages_fr.yml
@@ -61,4 +61,5 @@ email_exists: '&cUn email de restauration a déjà été envoyé ! Vous pouvez l
# TODO two_factor_create: Missing tag %url
two_factor_create: '&2Votre code secret est %code'
# TODO email_already_used: '&4The email address is already being used'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_gl.yml b/src/main/resources/messages/messages_gl.yml
index 3dfeb88d3..1562e3a31 100644
--- a/src/main/resources/messages/messages_gl.yml
+++ b/src/main/resources/messages/messages_gl.yml
@@ -60,5 +60,6 @@ antibot_auto_disabled: '[AuthMe] AntiBotMod desactivouse automáticamente despo
# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_hu.yml b/src/main/resources/messages/messages_hu.yml
index 504364546..b3f228825 100644
--- a/src/main/resources/messages/messages_hu.yml
+++ b/src/main/resources/messages/messages_hu.yml
@@ -58,5 +58,6 @@ antibot_auto_enabled: '&4[AntiBot] Az AntiBot védelem bekapcsolt a nagy számú
antibot_auto_disabled: '&2[AntiBot] Az AntiBot kikapcsol %m múlva!'
kick_antibot: 'Az AntiBot védelem bekapcsolva! Kérünk várj pár másodpercet a csatlakozáshoz.'
# TODO email_already_used: '&4The email address is already being used'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_id.yml b/src/main/resources/messages/messages_id.yml
index 528357560..24e6a35b7 100644
--- a/src/main/resources/messages/messages_id.yml
+++ b/src/main/resources/messages/messages_id.yml
@@ -55,6 +55,7 @@ antibot_auto_enabled: '&4[AntiBotService] AntiBot diaktifkan dikarenakan banyak
antibot_auto_disabled: '&2[AntiBotService] AntiBot dimatikan setelah %m menit!'
# TODO email_already_used: '&4The email address is already being used'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO country_banned: '&4Your country is banned from this server!'
# TODO usage_unreg: '&cUsage: /unregister '
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
diff --git a/src/main/resources/messages/messages_it.yml b/src/main/resources/messages/messages_it.yml
index abc943fc4..e7c77c898 100644
--- a/src/main/resources/messages/messages_it.yml
+++ b/src/main/resources/messages/messages_it.yml
@@ -60,4 +60,5 @@ antibot_auto_disabled: "Il servizio di AntiBot è stato automaticamente disabili
kick_antibot: 'Il servizio di AntiBot è attualmente attivo! Devi aspettare qualche minuto prima di poter entrare nel server.'
two_factor_create: '&2Il tuo codice segreto è: &f%code&n&2Puoi anche scannerizzare il codice QR da qui: &f%url'
# TODO email_already_used: '&4The email address is already being used'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_ko.yml b/src/main/resources/messages/messages_ko.yml
index 32ad61663..ab1223095 100644
--- a/src/main/resources/messages/messages_ko.yml
+++ b/src/main/resources/messages/messages_ko.yml
@@ -61,5 +61,6 @@ antibot_auto_disabled: '[AuthMe] 봇차단모드가 %m 분 후에 자동적으
# TODO password_error_nick: '&cYou can''t use your name as password, please choose another one...'
# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_lt.yml b/src/main/resources/messages/messages_lt.yml
index a432b62a9..fce26d1be 100644
--- a/src/main/resources/messages/messages_lt.yml
+++ b/src/main/resources/messages/messages_lt.yml
@@ -46,6 +46,7 @@ kick_fullserver: '&cServeris yra pilnas, Atsiprasome.'
# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
# TODO new_email_invalid: '&cInvalid new email, try again!'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO email_send: '&2Recovery email sent successfully! Please check your email inbox!'
# TODO usage_email_recovery: '&cUsage: /email recovery '
# TODO email_confirm: '&cPlease confirm your email address!'
diff --git a/src/main/resources/messages/messages_nl.yml b/src/main/resources/messages/messages_nl.yml
index bf662ce7c..a3159e488 100644
--- a/src/main/resources/messages/messages_nl.yml
+++ b/src/main/resources/messages/messages_nl.yml
@@ -59,5 +59,6 @@ kick_antibot: 'AntiBot is aangezet! Wacht alsjeblieft enkele minuten voor je met
two_factor_create: '&2Je geheime code is %code'
# TODO email_already_used: '&4The email address is already being used'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO reg_email_msg: '&3Please, register to the server with the command "/register "'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_pl.yml b/src/main/resources/messages/messages_pl.yml
index 506995bd5..c6cba56f4 100644
--- a/src/main/resources/messages/messages_pl.yml
+++ b/src/main/resources/messages/messages_pl.yml
@@ -55,6 +55,7 @@ email_send: '[AuthMe] Email z odzyskaniem wyslany!'
# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO country_banned: '&4Your country is banned from this server!'
# TODO antibot_auto_enabled: '&4[AntiBotService] AntiBot enabled due to the huge number of connections!'
# TODO antibot_auto_disabled: '&2[AntiBotService] AntiBot disabled disabled after %m minutes!'
diff --git a/src/main/resources/messages/messages_pt.yml b/src/main/resources/messages/messages_pt.yml
index 5b11aea6b..64428a525 100644
--- a/src/main/resources/messages/messages_pt.yml
+++ b/src/main/resources/messages/messages_pt.yml
@@ -59,5 +59,6 @@ antibot_auto_disabled: '[AuthMe] AntiBotMod desactivado automaticamente após %m
# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_ru.yml b/src/main/resources/messages/messages_ru.yml
index 3c34794e9..2b9dd640b 100644
--- a/src/main/resources/messages/messages_ru.yml
+++ b/src/main/resources/messages/messages_ru.yml
@@ -58,5 +58,6 @@ antibot_auto_disabled: '&a[AuthMe] AntiBot-режим автоматичски
# TODO email_already_used: '&4The email address is already being used'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_sk.yml b/src/main/resources/messages/messages_sk.yml
index 1366e2a95..77433f62c 100644
--- a/src/main/resources/messages/messages_sk.yml
+++ b/src/main/resources/messages/messages_sk.yml
@@ -38,28 +38,29 @@ name_len: '&cTvoje meno je velmi krátke alebo dlhé'
regex: '&cTvoje meno obsahuje zakázané znaky. Povolené znaky: REG_EX'
add_email: '&cPridaj svoj e-mail príkazom "/email add email zopakujEmail"'
recovery_email: '&cZabudol si heslo? Pouzi príkaz /email recovery '
-# TODO email_already_used: '&4The email address is already being used'
-# TODO password_error_nick: '&cYou can''t use your name as password, please choose another one...'
# TODO usage_email_change: '&cUsage: /email change '
-# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
+# TODO password_error_nick: '&cYou can''t use your name as password, please choose another one...'
+# TODO email_already_used: '&4The email address is already being used'
# TODO new_email_invalid: '&cInvalid new email, try again!'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
-# TODO email_send: '&2Recovery email sent successfully! Please check your email inbox!'
-# TODO email_confirm: '&cPlease confirm your email address!'
-# TODO usage_captcha: '&3To login you have to solve a captcha code, please use the command "/captcha "'
-# TODO usage_email_recovery: '&cUsage: /email recovery '
-# TODO email_changed: '&2Email address changed correctly!'
# TODO old_email_invalid: '&cInvalid old email, try again!'
+# TODO email_changed: '&2Email address changed correctly!'
# TODO antibot_auto_disabled: '&2[AntiBotService] AntiBot disabled disabled after %m minutes!'
-# TODO kick_fullserver: '&4The server is full, try again later!'
-# TODO email_added: '&2Email address successfully added to your account!'
-# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
# TODO country_banned: '&4Your country is banned from this server!'
-# TODO antibot_auto_enabled: '&4[AntiBotService] AntiBot enabled due to the huge number of connections!'
-# TODO email_invalid: '&cInvalid email address, try again!'
-# TODO kick_forvip: '&3A VIP player has joined the server when it was full!'
# TODO usage_email_add: '&cUsage: /email add '
# TODO wrong_captcha: '&cWrong captcha, please type "/captcha THE_CAPTCHA" into the chat!'
# TODO valid_captcha: '&2Captcha code solved correctly!'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
+# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
+# TODO email_send: '&2Recovery email sent successfully! Please check your email inbox!'
+# TODO usage_email_recovery: '&cUsage: /email recovery '
+# TODO usage_captcha: '&3To login you have to solve a captcha code, please use the command "/captcha "'
+# TODO email_confirm: '&cPlease confirm your email address!'
+# TODO kick_fullserver: '&4The server is full, try again later!'
+# TODO email_added: '&2Email address successfully added to your account!'
+# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO kick_forvip: '&3A VIP player has joined the server when it was full!'
+# TODO email_invalid: '&cInvalid email address, try again!'
+# TODO antibot_auto_enabled: '&4[AntiBotService] AntiBot enabled due to the huge number of connections!'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_tr.yml b/src/main/resources/messages/messages_tr.yml
index b3603929a..0e118de04 100644
--- a/src/main/resources/messages/messages_tr.yml
+++ b/src/main/resources/messages/messages_tr.yml
@@ -58,5 +58,6 @@ antibot_auto_disabled: '[AuthMe] AntiBotMode %m dakika sonra otomatik olarak isg
# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_uk.yml b/src/main/resources/messages/messages_uk.yml
index 6c5db173f..df5710f93 100644
--- a/src/main/resources/messages/messages_uk.yml
+++ b/src/main/resources/messages/messages_uk.yml
@@ -59,5 +59,6 @@ antibot_auto_disabled: '[AuthMe] AntiBotMod автоматично вимкну
# TODO email_already_used: '&4The email address is already being used'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_vn.yml b/src/main/resources/messages/messages_vn.yml
index 2df8588af..262b7b73b 100644
--- a/src/main/resources/messages/messages_vn.yml
+++ b/src/main/resources/messages/messages_vn.yml
@@ -59,5 +59,6 @@ antibot_auto_disabled: '[AuthMe] AntiBot tự huỷ kích hoạt sau %m phút, h
# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_zhcn.yml b/src/main/resources/messages/messages_zhcn.yml
index d1f71209b..3c7fa1a23 100644
--- a/src/main/resources/messages/messages_zhcn.yml
+++ b/src/main/resources/messages/messages_zhcn.yml
@@ -63,5 +63,6 @@ antibot_auto_disabled: '&8[&6用戶系統&8] 防止機械人程序檢查到不
# TODO email_already_used: '&4The email address is already being used'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_zhhk.yml b/src/main/resources/messages/messages_zhhk.yml
index e18f4109c..2eacb1f62 100644
--- a/src/main/resources/messages/messages_zhhk.yml
+++ b/src/main/resources/messages/messages_zhhk.yml
@@ -63,4 +63,5 @@ email_already_used: '&4邮箱已被使用'
kick_antibot: '[AuthMe] 防机器人程序已启用 !请稍等几分钟後才再次进入服务器'
email_exists: '&c恢复邮件已发送 ! 你可以丢弃它然後使用以下的指令来发送新的邮件:'
two_factor_create: '&2你的代码是 %code,你可以使用 %url 来扫描'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/main/resources/messages/messages_zhtw.yml b/src/main/resources/messages/messages_zhtw.yml
index 61ed5d88a..d31431f4b 100644
--- a/src/main/resources/messages/messages_zhtw.yml
+++ b/src/main/resources/messages/messages_zhtw.yml
@@ -63,5 +63,6 @@ antibot_auto_enabled: '&b【AuthMe】&6AntiBotMod已自動啟用!'
antibot_auto_disabled: '&b【AuthMe】&6AntiBotMod將會於 &c%m &6分鐘後自動關閉'
# TODO email_already_used: '&4The email address is already being used'
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
+# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
# TODO not_owner_error: 'You are not the owner of this account. Please try another name!'
\ No newline at end of file
diff --git a/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java b/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java
new file mode 100644
index 000000000..eedd781fd
--- /dev/null
+++ b/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java
@@ -0,0 +1,110 @@
+package fr.xephi.authme.datasource;
+
+import fr.xephi.authme.cache.auth.PlayerAuth;
+import fr.xephi.authme.security.crypts.HashedPassword;
+import org.junit.Test;
+
+import static fr.xephi.authme.datasource.AuthMeMatchers.equalToHash;
+import static fr.xephi.authme.datasource.AuthMeMatchers.hasAuthBasicData;
+import static fr.xephi.authme.datasource.AuthMeMatchers.hasAuthLocation;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Abstract class for data source integration tests.
+ */
+public abstract class AbstractDataSourceIntegrationTest {
+
+ protected abstract DataSource getDataSource();
+
+ @Test
+ public void shouldReturnIfAuthIsAvailableOrNot() {
+ // given
+ DataSource dataSource = getDataSource();
+
+ // when
+ boolean isBobbyAvailable = dataSource.isAuthAvailable("bobby");
+ boolean isChrisAvailable = dataSource.isAuthAvailable("chris");
+ boolean isUserAvailable = dataSource.isAuthAvailable("USER");
+
+ // then
+ assertThat(isBobbyAvailable, equalTo(true));
+ assertThat(isChrisAvailable, equalTo(false));
+ assertThat(isUserAvailable, equalTo(true));
+ }
+
+ @Test
+ public void shouldReturnPassword() {
+ // given
+ DataSource dataSource = getDataSource();
+
+ // when
+ HashedPassword bobbyPassword = dataSource.getPassword("bobby");
+ HashedPassword invalidPassword = dataSource.getPassword("doesNotExist");
+ HashedPassword userPassword = dataSource.getPassword("user");
+
+ // then
+ assertThat(bobbyPassword, equalToHash("$SHA$11aa0706173d7272$dbba966"));
+ assertThat(invalidPassword, nullValue());
+ assertThat(userPassword, equalToHash("b28c32f624a4eb161d6adc9acb5bfc5b", "f750ba32"));
+ }
+
+ @Test
+ public void shouldGetAuth() {
+ // given
+ DataSource dataSource = getDataSource();
+
+ // when
+ PlayerAuth invalidAuth = dataSource.getAuth("notInDB");
+ PlayerAuth bobbyAuth = dataSource.getAuth("Bobby");
+ PlayerAuth userAuth = dataSource.getAuth("user");
+
+ // then
+ assertThat(invalidAuth, nullValue());
+
+ assertThat(bobbyAuth, hasAuthBasicData("bobby", "Bobby", "your@email.com", "123.45.67.89"));
+ assertThat(bobbyAuth, hasAuthLocation(1.05, 2.1, 4.2, "world"));
+ assertThat(bobbyAuth.getLastLogin(), equalTo(1449136800L));
+ assertThat(bobbyAuth.getPassword(), equalToHash("$SHA$11aa0706173d7272$dbba966"));
+
+ assertThat(userAuth, hasAuthBasicData("user", "user", "user@example.org", "34.56.78.90"));
+ assertThat(userAuth, hasAuthLocation(124.1, 76.3, -127.8, "nether"));
+ assertThat(userAuth.getLastLogin(), equalTo(1453242857L));
+ assertThat(userAuth.getPassword(), equalToHash("b28c32f624a4eb161d6adc9acb5bfc5b", "f750ba32"));
+ }
+
+ @Test
+ public void shouldFindIfEmailExists() {
+ // given
+ DataSource dataSource = getDataSource();
+
+ // when
+ boolean isUserMailPresent = dataSource.isEmailStored("user@example.org");
+ boolean isUserMailPresentCaseInsensitive = dataSource.isEmailStored("user@example.ORG");
+ boolean isInvalidMailPresent = dataSource.isEmailStored("not-in-database@example.com");
+
+ // then
+ assertThat(isUserMailPresent, equalTo(true));
+ assertThat(isUserMailPresentCaseInsensitive, equalTo(true));
+ assertThat(isInvalidMailPresent, equalTo(false));
+ }
+
+ @Test
+ public void shouldCountAuthsByEmail() {
+ // given
+ DataSource dataSource = getDataSource();
+
+ // when
+ int userMailCount = dataSource.countAuthsByEmail("user@example.ORG");
+ int invalidMailCount = dataSource.countAuthsByEmail("not.in.db@example.com");
+ dataSource.saveAuth(PlayerAuth.builder().name("Test").email("user@EXAMPLE.org").build());
+ int newUserCount = dataSource.countAuthsByEmail("user@Example.org");
+
+ // then
+ assertThat(userMailCount, equalTo(1));
+ assertThat(invalidMailCount, equalTo(0));
+ assertThat(newUserCount, equalTo(2));
+ }
+
+}
diff --git a/src/test/java/fr/xephi/authme/datasource/MySqlIntegrationTest.java b/src/test/java/fr/xephi/authme/datasource/MySqlIntegrationTest.java
new file mode 100644
index 000000000..34a2a6afa
--- /dev/null
+++ b/src/test/java/fr/xephi/authme/datasource/MySqlIntegrationTest.java
@@ -0,0 +1,98 @@
+package fr.xephi.authme.datasource;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import fr.xephi.authme.ConsoleLoggerTestInitializer;
+import fr.xephi.authme.TestHelper;
+import fr.xephi.authme.settings.NewSetting;
+import fr.xephi.authme.settings.domain.Property;
+import fr.xephi.authme.settings.properties.DatabaseSettings;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * Integration test for {@link MySQL}.
+ */
+public class MySqlIntegrationTest extends AbstractDataSourceIntegrationTest {
+
+ /** Mock of a settings instance. */
+ private static NewSetting settings;
+ /** Collection of SQL statements to execute for initialization of a test. */
+ private static String[] sqlInitialize;
+ /** Connection to the H2 test database. */
+ private HikariDataSource hikariSource;
+
+ /**
+ * Set up the settings mock to return specific values for database settings and load {@link #sqlInitialize}.
+ */
+ @BeforeClass
+ public static void initializeSettings() throws IOException, ClassNotFoundException {
+ // Check that we have an H2 driver
+ Class.forName("org.h2.jdbcx.JdbcDataSource");
+
+ settings = mock(NewSetting.class);
+ when(settings.getProperty(any(Property.class))).thenAnswer(new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ return ((Property) invocation.getArguments()[0]).getDefaultValue();
+ }
+ });
+ set(DatabaseSettings.MYSQL_DATABASE, "h2_test");
+ set(DatabaseSettings.MYSQL_TABLE, "authme");
+ set(DatabaseSettings.MYSQL_COL_SALT, "salt");
+ ConsoleLoggerTestInitializer.setupLogger();
+
+ Path sqlInitFile = TestHelper.getJarPath("/datasource-integration/sql-initialize.sql");
+ sqlInitialize = new String(Files.readAllBytes(sqlInitFile)).split(";\\n");
+ }
+
+ @Before
+ public void initializeConnectionAndTable() throws SQLException {
+ silentClose(hikariSource);
+ HikariConfig config = new HikariConfig();
+ config.setDataSourceClassName("org.h2.jdbcx.JdbcDataSource");
+ config.setConnectionTestQuery("VALUES 1");
+ config.addDataSourceProperty("URL", "jdbc:h2:mem:test");
+ config.addDataSourceProperty("user", "sa");
+ config.addDataSourceProperty("password", "sa");
+ HikariDataSource ds = new HikariDataSource(config);
+ Connection connection = ds.getConnection();
+
+ try (Statement st = connection.createStatement()) {
+ st.execute("DROP TABLE IF EXISTS authme");
+ for (String statement : sqlInitialize) {
+ st.execute(statement);
+ }
+ }
+ hikariSource = ds;
+ }
+
+ @Override
+ protected DataSource getDataSource() {
+ return new MySQL(settings, hikariSource);
+ }
+
+ private static void set(Property property, T value) {
+ when(settings.getProperty(property)).thenReturn(value);
+ }
+
+ private static void silentClose(HikariDataSource con) {
+ if (con != null && !con.isClosed()) {
+ con.close();
+ }
+ }
+
+}
diff --git a/src/test/java/fr/xephi/authme/datasource/SQLiteIntegrationTest.java b/src/test/java/fr/xephi/authme/datasource/SQLiteIntegrationTest.java
index bf211b2e5..5c08b4790 100644
--- a/src/test/java/fr/xephi/authme/datasource/SQLiteIntegrationTest.java
+++ b/src/test/java/fr/xephi/authme/datasource/SQLiteIntegrationTest.java
@@ -2,14 +2,11 @@ package fr.xephi.authme.datasource;
import fr.xephi.authme.ConsoleLoggerTestInitializer;
import fr.xephi.authme.TestHelper;
-import fr.xephi.authme.cache.auth.PlayerAuth;
-import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.domain.Property;
import fr.xephi.authme.settings.properties.DatabaseSettings;
import org.junit.Before;
import org.junit.BeforeClass;
-import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@@ -21,12 +18,6 @@ import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
-import static fr.xephi.authme.datasource.AuthMeMatchers.equalToHash;
-import static fr.xephi.authme.datasource.AuthMeMatchers.hasAuthBasicData;
-import static fr.xephi.authme.datasource.AuthMeMatchers.hasAuthLocation;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -34,7 +25,7 @@ import static org.mockito.Mockito.when;
/**
* Integration test for {@link SQLite}.
*/
-public class SQLiteIntegrationTest {
+public class SQLiteIntegrationTest extends AbstractDataSourceIntegrationTest {
/** Mock of a settings instance. */
private static NewSetting settings;
@@ -63,7 +54,7 @@ public class SQLiteIntegrationTest {
set(DatabaseSettings.MYSQL_COL_SALT, "salt");
ConsoleLoggerTestInitializer.setupLogger();
- Path sqlInitFile = TestHelper.getJarPath("/datasource-integration/sqlite-initialize.sql");
+ Path sqlInitFile = TestHelper.getJarPath("/datasource-integration/sql-initialize.sql");
// Note ljacqu 20160221: It appears that we can only run one statement per Statement.execute() so we split
// the SQL file by ";\n" as to get the individual statements
sqlInitialize = new String(Files.readAllBytes(sqlInitFile)).split(";\\n");
@@ -82,93 +73,9 @@ public class SQLiteIntegrationTest {
con = connection;
}
- @Test
- public void shouldReturnIfAuthIsAvailableOrNot() {
- // given
- DataSource dataSource = new SQLite(settings, con, false);
-
- // when
- boolean isBobbyAvailable = dataSource.isAuthAvailable("bobby");
- boolean isChrisAvailable = dataSource.isAuthAvailable("chris");
- boolean isUserAvailable = dataSource.isAuthAvailable("USER");
-
- // then
- assertThat(isBobbyAvailable, equalTo(true));
- assertThat(isChrisAvailable, equalTo(false));
- assertThat(isUserAvailable, equalTo(true));
- }
-
- @Test
- public void shouldReturnPassword() {
- // given
- DataSource dataSource = new SQLite(settings, con, false);
-
- // when
- HashedPassword bobbyPassword = dataSource.getPassword("bobby");
- HashedPassword invalidPassword = dataSource.getPassword("doesNotExist");
- HashedPassword userPassword = dataSource.getPassword("user");
-
- // then
- assertThat(bobbyPassword, equalToHash("$SHA$11aa0706173d7272$dbba966"));
- assertThat(invalidPassword, nullValue());
- assertThat(userPassword, equalToHash("b28c32f624a4eb161d6adc9acb5bfc5b", "f750ba32"));
- }
-
- @Test
- public void shouldGetAuth() {
- // given
- DataSource dataSource = new SQLite(settings, con, false);
-
- // when
- PlayerAuth invalidAuth = dataSource.getAuth("notInDB");
- PlayerAuth bobbyAuth = dataSource.getAuth("Bobby");
- PlayerAuth userAuth = dataSource.getAuth("user");
-
- // then
- assertThat(invalidAuth, nullValue());
-
- assertThat(bobbyAuth, hasAuthBasicData("bobby", "Bobby", "your@email.com", "123.45.67.89"));
- assertThat(bobbyAuth, hasAuthLocation(1.05, 2.1, 4.2, "world"));
- assertThat(bobbyAuth.getLastLogin(), equalTo(1449136800L));
- assertThat(bobbyAuth.getPassword(), equalToHash("$SHA$11aa0706173d7272$dbba966"));
-
- assertThat(userAuth, hasAuthBasicData("user", "user", "user@example.org", "34.56.78.90"));
- assertThat(userAuth, hasAuthLocation(124.1, 76.3, -127.8, "nether"));
- assertThat(userAuth.getLastLogin(), equalTo(1453242857L));
- assertThat(userAuth.getPassword(), equalToHash("b28c32f624a4eb161d6adc9acb5bfc5b", "f750ba32"));
- }
-
- @Test
- public void shouldFindIfEmailExists() {
- // given
- DataSource dataSource = new SQLite(settings, con, false);
-
- // when
- boolean isUserMailPresent = dataSource.isEmailStored("user@example.org");
- boolean isUserMailPresentCaseInsensitive = dataSource.isEmailStored("user@example.ORG");
- boolean isInvalidMailPresent = dataSource.isEmailStored("not-in-database@example.com");
-
- // then
- assertThat(isUserMailPresent, equalTo(true));
- assertThat(isUserMailPresentCaseInsensitive, equalTo(true));
- assertThat(isInvalidMailPresent, equalTo(false));
- }
-
- @Test
- public void shouldCountAuthsByEmail() {
- // given
- DataSource dataSource = new SQLite(settings, con, false);
-
- // when
- int userMailCount = dataSource.countAuthsByEmail("user@example.ORG");
- int invalidMailCount = dataSource.countAuthsByEmail("not.in.db@example.com");
- dataSource.saveAuth(PlayerAuth.builder().name("Test").email("user@EXAMPLE.org").build());
- int newUserCount = dataSource.countAuthsByEmail("user@Example.org");
-
- // then
- assertThat(userMailCount, equalTo(1));
- assertThat(invalidMailCount, equalTo(0));
- assertThat(newUserCount, equalTo(2));
+ @Override
+ protected DataSource getDataSource() {
+ return new SQLite(settings, con);
}
private static void set(Property property, T value) {
@@ -186,6 +93,4 @@ public class SQLiteIntegrationTest {
}
}
}
-
-
}
diff --git a/src/test/java/fr/xephi/authme/output/MessagesIntegrationTest.java b/src/test/java/fr/xephi/authme/output/MessagesIntegrationTest.java
index 5ff79b9dd..399553657 100644
--- a/src/test/java/fr/xephi/authme/output/MessagesIntegrationTest.java
+++ b/src/test/java/fr/xephi/authme/output/MessagesIntegrationTest.java
@@ -266,4 +266,16 @@ public class MessagesIntegrationTest {
assertThat(messages.retrieveSingle(MessageKey.MUST_REGISTER_MESSAGE),
equalTo("Message from default file"));
}
+
+ @Test
+ public void shouldRetrieveMessageWithReplacements() {
+ // given
+ MessageKey key = MessageKey.CAPTCHA_WRONG_ERROR;
+
+ // when
+ String result = messages.retrieveSingle(key, "24680");
+
+ // then
+ assertThat(result, equalTo("Use /captcha 24680 to solve the captcha"));
+ }
}
diff --git a/src/test/resources/datasource-integration/sqlite-initialize.sql b/src/test/resources/datasource-integration/sql-initialize.sql
similarity index 100%
rename from src/test/resources/datasource-integration/sqlite-initialize.sql
rename to src/test/resources/datasource-integration/sql-initialize.sql