diff --git a/src/main/java/com/gmail/nossr50/commands/database/ConvertDatabaseCommand.java b/src/main/java/com/gmail/nossr50/commands/database/ConvertDatabaseCommand.java index 2bcea962c..cdaf43234 100644 --- a/src/main/java/com/gmail/nossr50/commands/database/ConvertDatabaseCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/database/ConvertDatabaseCommand.java @@ -3,13 +3,10 @@ package com.gmail.nossr50.commands.database; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.database.DatabaseManager; import com.gmail.nossr50.database.DatabaseManagerFactory; import com.gmail.nossr50.datatypes.database.DatabaseType; -import com.gmail.nossr50.datatypes.player.PlayerProfile; import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.runnables.database.DatabaseConversionTask; import com.gmail.nossr50.util.player.UserManager; @@ -52,17 +49,6 @@ public class ConvertDatabaseCommand implements CommandExecutor { sender.sendMessage(LocaleLoader.getString("Commands.mcconvert.Database.Start", previousType.toString(), newType.toString())); UserManager.saveAll(); - UserManager.clearAll(); - - for (Player player : mcMMO.p.getServer().getOnlinePlayers()) { - PlayerProfile profile = oldDatabase.loadPlayerProfile(player.getName(), false); - - if (profile.isLoaded()) { - mcMMO.getDatabaseManager().saveUser(profile); - } - - UserManager.addUser(player); - } new DatabaseConversionTask(oldDatabase, sender, previousType.toString(), newType.toString()).runTaskAsynchronously(mcMMO.p); return true; diff --git a/src/main/java/com/gmail/nossr50/database/DatabaseManager.java b/src/main/java/com/gmail/nossr50/database/DatabaseManager.java index 11f17a6b9..f2d2a1344 100644 --- a/src/main/java/com/gmail/nossr50/database/DatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/DatabaseManager.java @@ -21,7 +21,8 @@ public interface DatabaseManager { public void purgePowerlessUsers(); /** - * Purge users who haven't logged on in over a certain time frame from the database. + * Purge users who haven't logged on in over a certain time frame from the + * database. */ public void purgeOldUsers(); @@ -42,13 +43,13 @@ public interface DatabaseManager { public boolean saveUser(PlayerProfile profile); /** - * Retrieve leaderboard info. - * - * @param skillName The skill to retrieve info on - * @param pageNumber Which page in the leaderboards to retrieve - * @param statsPerPage The number of stats per page - * @return the requested leaderboard information - */ + * Retrieve leaderboard info. + * + * @param skillName The skill to retrieve info on + * @param pageNumber Which page in the leaderboards to retrieve + * @param statsPerPage The number of stats per page + * @return the requested leaderboard information + */ public List readLeaderboard(SkillType skill, int pageNumber, int statsPerPage); /** @@ -74,9 +75,9 @@ public interface DatabaseManager { * * @param playerName The name of the player to load from the database * @param createNew Whether to create a new record if the player is not - * found + * found * @return The player's data, or an unloaded PlayerProfile if not found - * and createNew is false + * and createNew is false */ public PlayerProfile loadPlayerProfile(String playerName, boolean createNew); @@ -96,9 +97,17 @@ public interface DatabaseManager { public void convertUsers(DatabaseManager destination); /** - * Retrieve the type of database in use. Custom databases should return CUSTOM. + * Retrieve the type of database in use. Custom databases should return + * CUSTOM. * * @return The type of database */ public DatabaseType getDatabaseType(); + + /** + * Used for database conversion. If this is set to true, profiles may not + * be loaded from the database. This method will be called before and + * after database imports. + */ + public void setLoadingDisabled(boolean state); } diff --git a/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java b/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java index 0484a394e..0446d4683 100644 --- a/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java @@ -35,6 +35,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager { private final long UPDATE_WAIT_TIME = 600000L; // 10 minutes private final File usersFile; private static final Object fileWritingLock = new Object(); + private volatile boolean converting = false; protected FlatfileDatabaseManager() { usersFile = new File(mcMMO.getUsersFilePath()); @@ -42,6 +43,10 @@ public final class FlatfileDatabaseManager implements DatabaseManager { updateLeaderboards(); } + public void setLoadingDisabled(boolean state) { + converting = state; + } + public void purgePowerlessUsers() { int purgedUsers = 0; @@ -369,6 +374,10 @@ public final class FlatfileDatabaseManager implements DatabaseManager { } public PlayerProfile loadPlayerProfile(String playerName, boolean create) { + if (converting) { + return new PlayerProfile(playerName, false); + } + BufferedReader in = null; String usersFilePath = mcMMO.getUsersFilePath(); diff --git a/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java b/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java index f7683616c..3e80efa6b 100644 --- a/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java @@ -49,12 +49,19 @@ public final class SQLDatabaseManager implements DatabaseManager { // How many connection attempts have failed private int reconnectAttempt = 0; + // If we're importing users, do not allow creation of profiles + private volatile boolean converting = false; + protected SQLDatabaseManager() { checkStructure(); new SQLDatabaseKeepaliveTask(this).runTaskTimerAsynchronously(mcMMO.p, 10, 60L * 60 * Misc.TICK_CONVERSION_FACTOR); } + public void setLoadingDisabled(boolean state) { + converting = state; + } + public void purgePowerlessUsers() { if (!checkConnected()) { return; @@ -346,12 +353,16 @@ public final class SQLDatabaseManager implements DatabaseManager { } public PlayerProfile loadPlayerProfile(String playerName, boolean create) { + if (converting) { + return new PlayerProfile(playerName, false); // return unloaded profile during database conversion + } + return loadPlayerProfile(playerName, create, true); } private PlayerProfile loadPlayerProfile(String playerName, boolean create, boolean retry) { if (!checkConnected()) { - return new PlayerProfile(playerName, false); // return fake profile if not connected + return new PlayerProfile(playerName, false); // return unloaded profile if not connected } PreparedStatement statement = null; diff --git a/src/main/java/com/gmail/nossr50/runnables/database/DatabaseConversionTask.java b/src/main/java/com/gmail/nossr50/runnables/database/DatabaseConversionTask.java index 362fb8044..284c879b8 100644 --- a/src/main/java/com/gmail/nossr50/runnables/database/DatabaseConversionTask.java +++ b/src/main/java/com/gmail/nossr50/runnables/database/DatabaseConversionTask.java @@ -1,11 +1,14 @@ package com.gmail.nossr50.runnables.database; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.database.DatabaseManager; +import com.gmail.nossr50.datatypes.player.PlayerProfile; import com.gmail.nossr50.locale.LocaleLoader; +import com.gmail.nossr50.util.player.UserManager; public class DatabaseConversionTask extends BukkitRunnable { private final DatabaseManager sourceDatabase; @@ -20,12 +23,24 @@ public class DatabaseConversionTask extends BukkitRunnable { @Override public void run() { - sourceDatabase.convertUsers(mcMMO.getDatabaseManager()); + try { + sourceDatabase.setLoadingDisabled(true); + sourceDatabase.convertUsers(mcMMO.getDatabaseManager()); + } + finally { + sourceDatabase.setLoadingDisabled(false); + } mcMMO.p.getServer().getScheduler().runTask(mcMMO.p, new Runnable() { @Override public void run() { sender.sendMessage(message); + + // Reload all users from the new database + UserManager.clearAll(); + for (Player player : mcMMO.p.getServer().getOnlinePlayers()) { + UserManager.addUser(player); + } } }); }