diff --git a/src/main/java/com/gmail/nossr50/database/DatabaseManager.java b/src/main/java/com/gmail/nossr50/database/DatabaseManager.java index 5d99fde64..021f0d0aa 100644 --- a/src/main/java/com/gmail/nossr50/database/DatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/DatabaseManager.java @@ -67,7 +67,7 @@ public interface DatabaseManager { * * @param playerName The name of the player to be added to the database */ - public void newUser(String playerName); + public void newUser(String playerName, String uuid); /** * Load a player from the database. diff --git a/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java b/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java index 7cd35d99e..ba3561402 100644 --- a/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java @@ -14,6 +14,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.UUID; import org.bukkit.OfflinePlayer; @@ -271,6 +272,8 @@ public final class FlatfileDatabaseManager implements DatabaseManager { writer.append(mobHealthbarType == null ? Config.getInstance().getMobHealthbarDefault().toString() : mobHealthbarType.toString()).append(":"); writer.append(profile.getSkillLevel(SkillType.ALCHEMY)).append(":"); writer.append(profile.getSkillXpLevel(SkillType.ALCHEMY)).append(":"); + UUID uuid = profile.getUniqueId(); + writer.append(uuid == null ? "" : uuid.toString()).append(":"); writer.append("\r\n"); } } @@ -313,7 +316,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager { return skills; } - public void newUser(String playerName) { + public void newUser(String playerName, String uuid) { BufferedWriter out = null; synchronized (fileWritingLock) { try { @@ -362,7 +365,8 @@ public final class FlatfileDatabaseManager implements DatabaseManager { out.append(Config.getInstance().getMobHealthbarDefault().toString()).append(":"); // Mob Healthbar HUD out.append("0:"); // Alchemy out.append("0:"); // AlchemyXp - + out.append(uuid).append(":"); // UUID + // Add more in the same format as the line above out.newLine(); @@ -376,7 +380,12 @@ public final class FlatfileDatabaseManager implements DatabaseManager { } } + @Deprecated public PlayerProfile loadPlayerProfile(String playerName, boolean create) { + return loadPlayerProfile(playerName, "", create); + } + + public PlayerProfile loadPlayerProfile(String playerName, String uuid, boolean create) { BufferedReader in = null; String usersFilePath = mcMMO.getUsersFilePath(); @@ -399,7 +408,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager { // Didn't find the player, create a new one if (create) { - newUser(playerName); + newUser(playerName, uuid); return new PlayerProfile(playerName, true); } } @@ -645,7 +654,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager { } // If they're valid, rewrite them to the file. - if (character.length == 41) { + if (character.length == 42) { writer.append(line).append("\r\n"); continue; } @@ -699,6 +708,14 @@ public final class FlatfileDatabaseManager implements DatabaseManager { oldVersion = "1.4.08"; } } + if (character.length <= 41) { + // Addition of UUIDs + // Version 1.5.01 + newLine.append(":"); + if (oldVersion == null) { + oldVersion = "1.5.01"; + } + } // Remove any blanks that shouldn't be there, and validate the other fields String[] newCharacter = newLine.toString().split(":"); @@ -869,7 +886,15 @@ public final class FlatfileDatabaseManager implements DatabaseManager { mobHealthbarType = Config.getInstance().getMobHealthbarDefault(); } - return new PlayerProfile(character[0], skills, skillsXp, skillsDATS, mobHealthbarType); + UUID uuid; + try { + uuid = UUID.fromString(character[41]); + } + catch (Exception e) { + uuid = null; + } + + return new PlayerProfile(character[0], uuid, skills, skillsXp, skillsDATS, mobHealthbarType); } private Map getSkillMapFromLine(String[] character) { diff --git a/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java b/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java index 84e3027f5..8315184f0 100644 --- a/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java @@ -13,6 +13,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.UUID; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.config.Config; @@ -123,7 +124,7 @@ public final class SQLDatabaseManager implements DatabaseManager { int userId = readId(profile.getPlayerName()); if (userId == -1) { - newUser(profile.getPlayerName()); + newUser(profile.getPlayerName(), profile.getUniqueId().toString()); userId = readId(profile.getPlayerName()); if (userId == -1) { return false; @@ -132,6 +133,7 @@ public final class SQLDatabaseManager implements DatabaseManager { boolean success = true; MobHealthbarType mobHealthbarType = profile.getMobHealthbarType(); + success &= saveUniqueId(userId, profile.getUniqueId().toString()); success &= saveLogin(userId, ((int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR))); success &= saveHuds(userId, (mobHealthbarType == null ? Config.getInstance().getMobHealthbarDefault().toString() : mobHealthbarType.toString())); success &= saveLongs( @@ -317,7 +319,7 @@ public final class SQLDatabaseManager implements DatabaseManager { return skills; } - public void newUser(String playerName) { + public void newUser(String playerName, String uuid) { if (!checkConnected()) { return; } @@ -325,9 +327,10 @@ public final class SQLDatabaseManager implements DatabaseManager { PreparedStatement statement = null; try { - statement = connection.prepareStatement("INSERT INTO " + tablePrefix + "users (user, lastlogin) VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS); + statement = connection.prepareStatement("INSERT INTO " + tablePrefix + "users (user, uuid, lastlogin) VALUES (?, ?, ?)", Statement.RETURN_GENERATED_KEYS); statement.setString(1, playerName); - statement.setLong(2, System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR); + statement.setString(2, uuid); + statement.setLong(3, System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR); statement.execute(); int id = readId(playerName); @@ -348,11 +351,12 @@ public final class SQLDatabaseManager implements DatabaseManager { } } + @Deprecated public PlayerProfile loadPlayerProfile(String playerName, boolean create) { - return loadPlayerProfile(playerName, create, true); + return loadPlayerProfile(playerName, "", create, true); } - private PlayerProfile loadPlayerProfile(String playerName, boolean create, boolean retry) { + private PlayerProfile loadPlayerProfile(String playerName, String uuid, boolean create, boolean retry) { if (!checkConnected()) { return new PlayerProfile(playerName, false); // return fake profile if not connected } @@ -365,7 +369,7 @@ public final class SQLDatabaseManager implements DatabaseManager { + "s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, s.alchemy, " + "e.taming, e.mining, e.repair, e.woodcutting, e.unarmed, e.herbalism, e.excavation, e.archery, e.swords, e.axes, e.acrobatics, e.fishing, e.alchemy, " + "c.taming, c.mining, c.repair, c.woodcutting, c.unarmed, c.herbalism, c.excavation, c.archery, c.swords, c.axes, c.acrobatics, c.blast_mining, " - + "h.mobhealthbar " + + "h.mobhealthbar, u.uuid " + "FROM " + tablePrefix + "users u " + "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " + "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " @@ -415,8 +419,8 @@ public final class SQLDatabaseManager implements DatabaseManager { if (id == -1) { // There is no such user if (create) { - newUser(playerName); - return loadPlayerProfile(playerName, false, false); + newUser(playerName, uuid); + return loadPlayerProfile(playerName, uuid, false, false); } // Return unloaded profile if can't create @@ -425,7 +429,7 @@ public final class SQLDatabaseManager implements DatabaseManager { // There is such a user writeMissingRows(id); // Retry, and abort on re-failure - return loadPlayerProfile(playerName, create, false); + return loadPlayerProfile(playerName, uuid, create, false); } public void convertUsers(DatabaseManager destination) { @@ -651,6 +655,7 @@ public final class SQLDatabaseManager implements DatabaseManager { write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "users` (" + "`id` int(10) unsigned NOT NULL AUTO_INCREMENT," + "`user` varchar(40) NOT NULL," + + "`uuid` varchar(40) NOT NULL," + "`lastlogin` int(32) unsigned NOT NULL," + "PRIMARY KEY (`id`)," + "UNIQUE KEY `user` (`user`)) DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;"); @@ -853,6 +858,10 @@ public final class SQLDatabaseManager implements DatabaseManager { } break; + case ADD_UUIDS: + write("ALTER TABLE `" + tablePrefix + "users` ADD `uuid` varchar(50) NOT NULL DEFAULT '';"); + return; + default: break; @@ -1166,6 +1175,32 @@ public final class SQLDatabaseManager implements DatabaseManager { return id; } + private boolean saveUniqueId(int id, String uuid) { + PreparedStatement statement = null; + + try { + statement = connection.prepareStatement("UPDATE " + tablePrefix + "users SET uuid = ? WHERE id = ?"); + statement.setString(1, uuid); + statement.setInt(2, id); + statement.execute(); + return true; + } + catch (SQLException ex) { + printErrors(ex); + return false; + } + finally { + if (statement != null) { + try { + statement.close(); + } + catch (SQLException e) { + // Ignore + } + } + } + } + private boolean saveLogin(int id, long login) { PreparedStatement statement = null; @@ -1223,6 +1258,7 @@ public final class SQLDatabaseManager implements DatabaseManager { Map skillsXp = new HashMap(); // Skill & XP Map skillsDATS = new HashMap(); // Ability & Cooldown MobHealthbarType mobHealthbarType; + UUID uuid = null; final int OFFSET_SKILLS = 0; // TODO update these numbers when the query changes (a new skill is added) final int OFFSET_XP = 13; @@ -1277,7 +1313,13 @@ public final class SQLDatabaseManager implements DatabaseManager { mobHealthbarType = Config.getInstance().getMobHealthbarDefault(); } - return new PlayerProfile(playerName, skills, skillsXp, skillsDATS, mobHealthbarType); + try { + UUID.fromString(result.getString(OFFSET_OTHER + 3)); + } + catch (Exception e) { + } + + return new PlayerProfile(playerName, uuid, skills, skillsXp, skillsDATS, mobHealthbarType); } private void printErrors(SQLException ex) { diff --git a/src/main/java/com/gmail/nossr50/datatypes/database/UpgradeType.java b/src/main/java/com/gmail/nossr50/datatypes/database/UpgradeType.java index 1f901e68a..0d85067df 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/database/UpgradeType.java +++ b/src/main/java/com/gmail/nossr50/datatypes/database/UpgradeType.java @@ -7,5 +7,6 @@ public enum UpgradeType { ADD_MOB_HEALTHBARS, DROP_SQL_PARTY_NAMES, DROP_SPOUT, - ADD_ALCHEMY; + ADD_ALCHEMY, + ADD_UUIDS; } diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java index aa05c978c..e9dce3e6e 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java @@ -101,6 +101,10 @@ public class McMMOPlayer { party = PartyManager.getPlayerParty(playerName); ptpRecord = new PartyTeleportRecord(); + if (!player.getUniqueId().equals(profile.getUniqueId())) { + profile.setUniqueId(player.getUniqueId()); + } + /* * I'm using this method because it makes code shorter and safer (we don't have to add all SkillTypes manually), * but I actually have no idea about the performance impact, if there is any. diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java index 7d1a3941f..1905b773d 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java @@ -3,6 +3,7 @@ package com.gmail.nossr50.datatypes.player; import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.UUID; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.config.Config; @@ -19,6 +20,7 @@ import com.google.common.collect.ImmutableMap; public class PlayerProfile { private final String playerName; + private UUID uuid; private boolean loaded; private volatile boolean changed; @@ -50,8 +52,9 @@ public class PlayerProfile { this.loaded = isLoaded; } - public PlayerProfile(String playerName, Map levelData, Map xpData, Map cooldownData, MobHealthbarType mobHealthbarType) { + public PlayerProfile(String playerName, UUID uuid, Map levelData, Map xpData, Map cooldownData, MobHealthbarType mobHealthbarType) { this.playerName = playerName; + this.uuid = uuid; this.mobHealthbarType = mobHealthbarType; skills.putAll(levelData); @@ -71,7 +74,7 @@ public class PlayerProfile { } // TODO should this part be synchronized? - PlayerProfile profileCopy = new PlayerProfile(playerName, ImmutableMap.copyOf(skills), ImmutableMap.copyOf(skillsXp), ImmutableMap.copyOf(abilityDATS), mobHealthbarType); + PlayerProfile profileCopy = new PlayerProfile(playerName, uuid, ImmutableMap.copyOf(skills), ImmutableMap.copyOf(skillsXp), ImmutableMap.copyOf(abilityDATS), mobHealthbarType); changed = !mcMMO.getDatabaseManager().saveUser(profileCopy); if (changed) { @@ -83,6 +86,16 @@ public class PlayerProfile { return playerName; } + public UUID getUniqueId() { + return uuid; + } + + public void setUniqueId(UUID uuid) { + changed = true; + + this.uuid = uuid; + } + public boolean isLoaded() { return loaded; }