diff --git a/Changelog.txt b/Changelog.txt index c11aa9f27..8a704c845 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -5,6 +5,8 @@ Version 2.1.189 Rewrote how FlatFileDatabase verifies data integrity (API) Added com.gmail.nossr50.database.DatabaseManager.loadPlayerProfile(org.bukkit.OfflinePlayer) (API) Deprecated com.gmail.nossr50.database.DatabaseManager.loadPlayerProfile(java.util.UUID, java.lang.String) + (API) Removed com.gmail.nossr50.database.DatabaseManager.newUser(java.lang.String, java.util.UUID) + (API) Added Added unit tests for FlatFileDatabaseManager (see notes) Fixed a bug where FlatFileDatabaseManager didn't properly upgrade older database entries to the newest schema The setting to disable the mcMMO user block tracker has been moved from our "hidden config" to persistent_data.yml diff --git a/pom.xml b/pom.xml index c39db8f41..231bd7f4b 100755 --- a/pom.xml +++ b/pom.xml @@ -220,6 +220,12 @@ + + com.github.seeseemelk + MockBukkit-v1.16 + 0.25.0 + test + co.aikar acf-bukkit diff --git a/src/main/java/com/gmail/nossr50/database/DatabaseManager.java b/src/main/java/com/gmail/nossr50/database/DatabaseManager.java index 914a35aa2..3f9ac7a77 100644 --- a/src/main/java/com/gmail/nossr50/database/DatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/DatabaseManager.java @@ -76,11 +76,11 @@ public interface DatabaseManager { /** * Add a new user to the database. - * - * @param playerName The name of the player to be added to the database + * @param playerName The name of the player to be added to the database * @param uuid The uuid of the player to be added to the database + * @return */ - void newUser(String playerName, UUID uuid); + @NotNull PlayerProfile newUser(String playerName, UUID uuid); @NotNull PlayerProfile newUser(@NotNull Player player); @@ -101,11 +101,13 @@ public interface DatabaseManager { * Load a player from the database. * @param uuid The uuid of the player to load from the database * @return The player's data, or an unloaded PlayerProfile if not found - * @deprecated Use {@link DatabaseManager#loadPlayerProfile(org.bukkit.OfflinePlayer)} if possible + * @deprecated Use {@link DatabaseManager#loadPlayerProfile(org.bukkit.OfflinePlayer)} or {@link DatabaseManager#loadPlayerProfile(java.util.UUID)} if possible */ @Deprecated @NotNull PlayerProfile loadPlayerProfile(@NotNull UUID uuid, @Nullable String playerName); + @NotNull PlayerProfile loadPlayerProfile(@NotNull UUID uuid); + /** * Get all users currently stored in 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 97c77aeb5..8d4f8ea30 100644 --- a/src/main/java/com/gmail/nossr50/database/FlatFileDatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/FlatFileDatabaseManager.java @@ -31,7 +31,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager { private final @NotNull Logger logger; private final long purgeTime; private final int startingLevel; - private boolean testing; + private final boolean testing; private final long UPDATE_WAIT_TIME = 600000L; // 10 minutes private final @NotNull File usersFile; @@ -97,6 +97,8 @@ public final class FlatFileDatabaseManager implements DatabaseManager { logger.info("Detected "+flatFileDataFlags.size() + " data entries which need correction."); } } + + updateLeaderboards(); } } @@ -193,29 +195,31 @@ public final class FlatFileDatabaseManager implements DatabaseManager { String name = character[USERNAME_INDEX]; long lastPlayed = 0; boolean rewrite = false; + try { - lastPlayed = Long.parseLong(character[37]) * Misc.TIME_CONVERSION_FACTOR; - } - catch (NumberFormatException e) { + lastPlayed = Long.parseLong(character[OVERHAUL_LAST_LOGIN]); + } catch (NumberFormatException e) { e.printStackTrace(); } - if (lastPlayed == 0) { + + if (lastPlayed == -1) { OfflinePlayer player = mcMMO.p.getServer().getOfflinePlayer(name); - lastPlayed = player.getLastPlayed(); - rewrite = true; + + if(player.getLastPlayed() != 0) { + lastPlayed = player.getLastPlayed(); + rewrite = true; + } } if (currentTime - lastPlayed > purgeTime) { removedPlayers++; - } - else { + } else { if (rewrite) { // Rewrite their data with a valid time - character[37] = Long.toString(lastPlayed); + character[OVERHAUL_LAST_LOGIN] = Long.toString(lastPlayed); String newLine = org.apache.commons.lang.StringUtils.join(character, ":"); writer.append(newLine).append("\r\n"); - } - else { + } else { writer.append(line).append("\r\n"); } } @@ -421,51 +425,52 @@ public final class FlatFileDatabaseManager implements DatabaseManager { } } - private void writeUserToLine(PlayerProfile profile, @NotNull String playerName, @Nullable UUID uuid, StringBuilder writer) { + public void writeUserToLine(@NotNull PlayerProfile profile, @NotNull String playerName, @Nullable UUID uuid, @NotNull Appendable writer) throws IOException { writer.append(playerName).append(":"); - writer.append(profile.getSkillLevel(PrimarySkillType.MINING)).append(":"); - writer.append(":"); - writer.append(":"); - writer.append(profile.getSkillXpLevel(PrimarySkillType.MINING)).append(":"); - writer.append(profile.getSkillLevel(PrimarySkillType.WOODCUTTING)).append(":"); - writer.append(profile.getSkillXpLevel(PrimarySkillType.WOODCUTTING)).append(":"); - writer.append(profile.getSkillLevel(PrimarySkillType.REPAIR)).append(":"); - writer.append(profile.getSkillLevel(PrimarySkillType.UNARMED)).append(":"); - writer.append(profile.getSkillLevel(PrimarySkillType.HERBALISM)).append(":"); - writer.append(profile.getSkillLevel(PrimarySkillType.EXCAVATION)).append(":"); - writer.append(profile.getSkillLevel(PrimarySkillType.ARCHERY)).append(":"); - writer.append(profile.getSkillLevel(PrimarySkillType.SWORDS)).append(":"); - writer.append(profile.getSkillLevel(PrimarySkillType.AXES)).append(":"); - writer.append(profile.getSkillLevel(PrimarySkillType.ACROBATICS)).append(":"); - writer.append(profile.getSkillXpLevel(PrimarySkillType.REPAIR)).append(":"); - writer.append(profile.getSkillXpLevel(PrimarySkillType.UNARMED)).append(":"); - writer.append(profile.getSkillXpLevel(PrimarySkillType.HERBALISM)).append(":"); - writer.append(profile.getSkillXpLevel(PrimarySkillType.EXCAVATION)).append(":"); - writer.append(profile.getSkillXpLevel(PrimarySkillType.ARCHERY)).append(":"); - writer.append(profile.getSkillXpLevel(PrimarySkillType.SWORDS)).append(":"); - writer.append(profile.getSkillXpLevel(PrimarySkillType.AXES)).append(":"); - writer.append(profile.getSkillXpLevel(PrimarySkillType.ACROBATICS)).append(":"); - writer.append(":"); - writer.append(profile.getSkillLevel(PrimarySkillType.TAMING)).append(":"); - writer.append(profile.getSkillXpLevel(PrimarySkillType.TAMING)).append(":"); - writer.append((int) profile.getAbilityDATS(SuperAbilityType.BERSERK)).append(":"); - writer.append((int) profile.getAbilityDATS(SuperAbilityType.GIGA_DRILL_BREAKER)).append(":"); - writer.append((int) profile.getAbilityDATS(SuperAbilityType.TREE_FELLER)).append(":"); - writer.append((int) profile.getAbilityDATS(SuperAbilityType.GREEN_TERRA)).append(":"); - writer.append((int) profile.getAbilityDATS(SuperAbilityType.SERRATED_STRIKES)).append(":"); - writer.append((int) profile.getAbilityDATS(SuperAbilityType.SKULL_SPLITTER)).append(":"); - writer.append((int) profile.getAbilityDATS(SuperAbilityType.SUPER_BREAKER)).append(":"); - writer.append(":"); - writer.append(profile.getSkillLevel(PrimarySkillType.FISHING)).append(":"); - writer.append(profile.getSkillXpLevel(PrimarySkillType.FISHING)).append(":"); - writer.append((int) profile.getAbilityDATS(SuperAbilityType.BLAST_MINING)).append(":"); - writer.append(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR).append(":"); + writer.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.MINING))).append(":"); + writer.append(IGNORED).append(":"); + writer.append(IGNORED).append(":"); + writer.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.MINING))).append(":"); + writer.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.WOODCUTTING))).append(":"); + writer.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.WOODCUTTING))).append(":"); + writer.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.REPAIR))).append(":"); + writer.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.UNARMED))).append(":"); + writer.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.HERBALISM))).append(":"); + writer.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.EXCAVATION))).append(":"); + writer.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.ARCHERY))).append(":"); + writer.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.SWORDS))).append(":"); + writer.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.AXES))).append(":"); + writer.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.ACROBATICS))).append(":"); + writer.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.REPAIR))).append(":"); + writer.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.UNARMED))).append(":"); + writer.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.HERBALISM))).append(":"); + writer.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.EXCAVATION))).append(":"); + writer.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.ARCHERY))).append(":"); + writer.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.SWORDS))).append(":"); + writer.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.AXES))).append(":"); + writer.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.ACROBATICS))).append(":"); + writer.append(IGNORED).append(":"); + writer.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.TAMING))).append(":"); + writer.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.TAMING))).append(":"); + writer.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.BERSERK))).append(":"); + writer.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.GIGA_DRILL_BREAKER))).append(":"); + writer.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.TREE_FELLER))).append(":"); + writer.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.GREEN_TERRA))).append(":"); + writer.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.SERRATED_STRIKES))).append(":"); + writer.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.SKULL_SPLITTER))).append(":"); + writer.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.SUPER_BREAKER))).append(":"); + writer.append(IGNORED).append(":"); + writer.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.FISHING))).append(":"); + writer.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.FISHING))).append(":"); + writer.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.BLAST_MINING))).append(":"); + writer.append(IGNORED).append(":"); //Legacy last login writer.append(IGNORED).append(":"); //mob health bar - writer.append(profile.getSkillLevel(PrimarySkillType.ALCHEMY)).append(":"); - writer.append(profile.getSkillXpLevel(PrimarySkillType.ALCHEMY)).append(":"); + writer.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.ALCHEMY))).append(":"); + writer.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.ALCHEMY))).append(":"); writer.append(uuid != null ? uuid.toString() : "NULL").append(":"); - writer.append(profile.getScoreboardTipsShown()).append(":"); - writer.append(profile.getUniqueData(UniqueDataType.CHIMAERA_WING_DATS)).append(":"); + writer.append(String.valueOf(profile.getScoreboardTipsShown())).append(":"); + writer.append(String.valueOf(profile.getUniqueData(UniqueDataType.CHIMAERA_WING_DATS))).append(":"); + writer.append(String.valueOf(profile.getLastLogin())).append(":"); //overhaul last login writer.append("\r\n"); } @@ -498,81 +503,21 @@ public final class FlatFileDatabaseManager implements DatabaseManager { } public @NotNull PlayerProfile newUser(@NotNull Player player) { - newUser(player.getName(), player.getUniqueId()); - return new PlayerProfile(player.getName(), player.getUniqueId(), true); + return new PlayerProfile(player.getName(), player.getUniqueId(), true, startingLevel); } - public void newUser(String playerName, UUID uuid) { - BufferedWriter out = null; + public @NotNull PlayerProfile newUser(@NotNull String playerName, @NotNull UUID uuid) { + PlayerProfile playerProfile = new PlayerProfile(playerName, uuid, true, startingLevel); + synchronized (fileWritingLock) { - try { - // Open the file to write the player - out = new BufferedWriter(new FileWriter(usersFilePath, true)); - - String startingLevelStr = startingLevel + ":"; - - // Add the player to the end - out.append(playerName).append(":"); - out.append(startingLevelStr); // Mining - out.append(":"); - out.append(":"); - out.append("0:"); // Xp - out.append(startingLevelStr); // Woodcutting - out.append("0:"); // WoodCuttingXp - out.append(startingLevelStr); // Repair - out.append(startingLevelStr); // Unarmed - out.append(startingLevelStr); // Herbalism - out.append(startingLevelStr); // Excavation - out.append(startingLevelStr); // Archery - out.append(startingLevelStr); // Swords - out.append(startingLevelStr); // Axes - out.append(startingLevelStr); // Acrobatics - out.append("0:"); // RepairXp - out.append("0:"); // UnarmedXp - out.append("0:"); // HerbalismXp - out.append("0:"); // ExcavationXp - out.append("0:"); // ArcheryXp - out.append("0:"); // SwordsXp - out.append("0:"); // AxesXp - out.append("0:"); // AcrobaticsXp - out.append(":"); - out.append(startingLevelStr); // Taming - out.append("0:"); // TamingXp - out.append("0:"); // DATS - out.append("0:"); // DATS - out.append("0:"); // DATS - out.append("0:"); // DATS - out.append("0:"); // DATS - out.append("0:"); // DATS - out.append("0:"); // DATS - out.append(":"); - out.append(startingLevelStr); // Fishing - out.append("0:"); // FishingXp - out.append("0:"); // Blast Mining - out.append(String.valueOf(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR)).append(":"); // LastLogin - out.append(IGNORED).append(":"); // Mob Healthbar HUD - out.append(startingLevelStr); // Alchemy - out.append("0:"); // AlchemyXp - out.append(uuid != null ? uuid.toString() : "NULL").append(":"); // UUID - out.append("0:"); // Scoreboard tips shown - // Add more in the same format as the line above - - out.newLine(); - } - catch (Exception e) { + try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(usersFilePath, true))) { + writeUserToLine(playerProfile, playerName, uuid, bufferedWriter); + } catch (Exception e) { e.printStackTrace(); } - finally { - if (out != null) { - try { - out.close(); - } - catch (IOException e) { - // Ignore - } - } - } } + + return playerProfile; } public @NotNull PlayerProfile loadPlayerProfile(@NotNull OfflinePlayer offlinePlayer) { @@ -587,6 +532,10 @@ public final class FlatFileDatabaseManager implements DatabaseManager { return loadPlayerByUUID(uuid, playerName, false); } + public @NotNull PlayerProfile loadPlayerProfile(@NotNull UUID uuid) { + return loadPlayerByUUID(uuid, null, false); + } + private @NotNull PlayerProfile loadPlayerByUUID(@NotNull UUID uuid, @Nullable String playerName, boolean isOnline) { BufferedReader in = null; @@ -700,7 +649,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager { } //Return a new blank profile - return new PlayerProfile(playerName, null); + return new PlayerProfile(playerName, new UUID(0, 0), startingLevel); } private @NotNull PlayerProfile grabUnloadedProfile(@NotNull UUID uuid, @Nullable String playerName) { @@ -708,7 +657,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager { playerName = ""; //No name for you boy! } - return new PlayerProfile(playerName, uuid); + return new PlayerProfile(playerName, uuid, 0); } public void convertUsers(DatabaseManager destination) { @@ -731,8 +680,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager { try { destination.saveUser(loadFromLine(character)); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } convertedUsers++; diff --git a/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java b/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java index 6599e707c..01c14ed16 100644 --- a/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java @@ -1,6 +1,7 @@ package com.gmail.nossr50.database; import com.gmail.nossr50.api.exceptions.InvalidSkillException; +import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.datatypes.MobHealthbarType; import com.gmail.nossr50.datatypes.database.DatabaseType; import com.gmail.nossr50.datatypes.database.PlayerStat; @@ -491,19 +492,19 @@ public final class SQLDatabaseManager implements DatabaseManager { return skills; } - public void newUser(String playerName, UUID uuid) { + public @NotNull PlayerProfile newUser(String playerName, UUID uuid) { Connection connection = null; try { connection = getConnection(PoolIdentifier.MISC); newUser(connection, playerName, uuid); - } - catch (SQLException ex) { + } catch (SQLException ex) { printErrors(ex); - } - finally { + } finally { tryClose(connection); } + + return new PlayerProfile(playerName, uuid, true, mcMMO.p.getAdvancedConfig().getStartingLevel()); } @Override @@ -513,7 +514,7 @@ public final class SQLDatabaseManager implements DatabaseManager { int id = newUser(connection, player.getName(), player.getUniqueId()); if (id == -1) { - return new PlayerProfile(player.getName(), player.getUniqueId(), false); + return new PlayerProfile(player.getName(), player.getUniqueId(), false, mcMMO.p.getAdvancedConfig().getStartingLevel()); } else { return loadPlayerProfile(player.getUniqueId(), player.getName()); } @@ -521,7 +522,7 @@ public final class SQLDatabaseManager implements DatabaseManager { e.printStackTrace(); } - return new PlayerProfile(player.getName(), player.getUniqueId(), false); + return new PlayerProfile(player.getName(), player.getUniqueId(), false, mcMMO.p.getAdvancedConfig().getStartingLevel()); } private int newUser(Connection connection, String playerName, UUID uuid) { @@ -567,7 +568,7 @@ public final class SQLDatabaseManager implements DatabaseManager { return loadPlayerFromDB(null, playerName); } catch (RuntimeException e) { e.printStackTrace(); - return new PlayerProfile(playerName, false); + return new PlayerProfile(playerName, false, mcMMO.p.getAdvancedConfig().getStartingLevel()); } } @@ -575,6 +576,12 @@ public final class SQLDatabaseManager implements DatabaseManager { return loadPlayerFromDB(uuid, playerName); } + @Override + public @NotNull PlayerProfile loadPlayerProfile(@NotNull UUID uuid) { + return loadPlayerFromDB(uuid, null); + } + + private PlayerProfile loadPlayerFromDB(@Nullable UUID uuid, @Nullable String playerName) throws RuntimeException { if(uuid == null && playerName == null) { throw new RuntimeException("Error looking up player, both UUID and playerName are null and one must not be."); @@ -590,7 +597,7 @@ public final class SQLDatabaseManager implements DatabaseManager { if (id == -1) { // There is no such user - return new PlayerProfile(playerName, false); + return new PlayerProfile(playerName, mcMMO.p.getAdvancedConfig().getStartingLevel()); } // There is such a user writeMissingRows(connection, id); @@ -659,7 +666,7 @@ public final class SQLDatabaseManager implements DatabaseManager { } //Return empty profile - return new PlayerProfile(playerName, false); + return new PlayerProfile(playerName, mcMMO.p.getAdvancedConfig().getStartingLevel()); } public void convertUsers(DatabaseManager destination) { 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 1295a6d05..81d2d8417 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java @@ -43,11 +43,13 @@ public class PlayerProfile { private final Map rollingSkillsXp = new EnumMap(PrimarySkillType.class); @Deprecated - public PlayerProfile(String playerName) { - this(playerName, null); + //TODO: Add deprecated constructor w/o startinglevel + public PlayerProfile(String playerName, int startingLevel) { + this(playerName, null, startingLevel); } - public PlayerProfile(String playerName, UUID uuid) { + //TODO: Add deprecated constructor w/o startinglevel + public PlayerProfile(String playerName, UUID uuid, int startingLevel) { this.uuid = uuid; this.playerName = playerName; @@ -58,9 +60,7 @@ public class PlayerProfile { } for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS) { - int startingLvl = mcMMO.p != null ? mcMMO.p.getAdvancedConfig().getStartingLevel() : 0; //TODO: Setup the mock since this was to avoid setting up a mock in a test - - skills.put(primarySkillType, startingLvl); + skills.put(primarySkillType, startingLevel); skillsXp.put(primarySkillType, 0F); } @@ -70,13 +70,13 @@ public class PlayerProfile { } @Deprecated - public PlayerProfile(@NotNull String playerName, boolean isLoaded) { - this(playerName); + public PlayerProfile(@NotNull String playerName, boolean isLoaded, int startingLvl) { + this(playerName, startingLvl); this.loaded = isLoaded; } - public PlayerProfile(@NotNull String playerName, UUID uuid, boolean isLoaded) { - this(playerName, uuid); + public PlayerProfile(@NotNull String playerName, UUID uuid, boolean isLoaded, int startingLvl) { + this(playerName, uuid, startingLvl); this.loaded = isLoaded; } @@ -167,6 +167,10 @@ public class PlayerProfile { return lastLogin; } + public void updateLastLogin() { + this.lastLogin = System.currentTimeMillis(); + } + public String getPlayerName() { return playerName; } diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index 69982d932..5e08bc34e 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -59,8 +59,10 @@ import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.plugin.java.JavaPluginLoader; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -168,6 +170,13 @@ public class mcMMO extends JavaPlugin { p = this; } + + protected mcMMO(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) + { + super(loader, description, dataFolder, file); + } + + /** * Things to be run when the plugin is enabled. */ diff --git a/src/main/java/com/gmail/nossr50/runnables/player/PlayerProfileLoadingTask.java b/src/main/java/com/gmail/nossr50/runnables/player/PlayerProfileLoadingTask.java index 5dccb2cf1..95c0ddc71 100644 --- a/src/main/java/com/gmail/nossr50/runnables/player/PlayerProfileLoadingTask.java +++ b/src/main/java/com/gmail/nossr50/runnables/player/PlayerProfileLoadingTask.java @@ -92,6 +92,8 @@ public class PlayerProfileLoadingTask extends BukkitRunnable { return; } + mcMMOPlayer.getProfile().updateLastLogin(); + mcMMOPlayer.setupPartyData(); UserManager.track(mcMMOPlayer); mcMMOPlayer.actualizeRespawnATS(); diff --git a/src/main/java/com/gmail/nossr50/util/commands/CommandUtils.java b/src/main/java/com/gmail/nossr50/util/commands/CommandUtils.java index d40403ddd..cda34dd8b 100644 --- a/src/main/java/com/gmail/nossr50/util/commands/CommandUtils.java +++ b/src/main/java/com/gmail/nossr50/util/commands/CommandUtils.java @@ -86,7 +86,7 @@ public final class CommandUtils { return true; } - PlayerProfile profile = new PlayerProfile(playerName, false); + PlayerProfile profile = new PlayerProfile(playerName, false, 0); if (unloadedProfile(sender, profile)) { return false; diff --git a/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java b/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java index 48a1481b7..71f5de649 100644 --- a/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java +++ b/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java @@ -6,14 +6,20 @@ import com.gmail.nossr50.datatypes.player.PlayerProfile; import com.gmail.nossr50.datatypes.player.UniqueDataType; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.SuperAbilityType; +import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask; import com.gmail.nossr50.util.skills.SkillTools; import com.google.common.io.Files; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; import org.powermock.modules.junit4.PowerMockRunner; import java.io.*; @@ -26,9 +32,10 @@ import static org.junit.Assert.*; //TODO: Test update leaderboards -@RunWith(PowerMockRunner.class) public class FlatFileDatabaseManagerTest { + public mcMMO plugin; + public static final @NotNull String TEST_FILE_NAME = "test.mcmmo.users"; public static final @NotNull String BAD_FILE_LINE_ONE = "mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:"; public static final @NotNull String BAD_DATA_FILE_LINE_TWENTY_THREE = "nossr51:baddata:::baddata:baddata:640:baddata:1000:1000:1000:baddata:baddata:baddata:baddata:16:0:500:20273:0:0:0:0::1000:0:0:baddata:1593543012:0:0:0:0::1000:0:0:baddata:IGNORED:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1:0:"; @@ -137,7 +144,7 @@ public class FlatFileDatabaseManagerTest { //Make a Profile to save and check to see if it worked UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3"); String playerName = "nossr50"; - PlayerProfile testProfile = new PlayerProfile(playerName, uuid); + PlayerProfile testProfile = new PlayerProfile(playerName, uuid, 0); //The above profile should be "zero" initialized //Save the zero version and see if it looks correct @@ -208,6 +215,56 @@ public class FlatFileDatabaseManagerTest { testHealthyDataProfileValues(playerName, uuid, profile); } + @Test + public void testNewUser() { + //We will test that new user values line up with our expectations + UUID uuid = new UUID(0, 1); + String playerName = "nossr50"; + + int newUserTestStartingLvl = 1337; + db = new FlatFileDatabaseManager(new File(tempDir.getPath() + File.separator + TEST_FILE_NAME), logger, PURGE_TIME, newUserTestStartingLvl, true); + db.checkFileHealthAndStructure(); + + PlayerProfile playerProfile = db.newUser(playerName, uuid); + + assertTrue(playerProfile.isLoaded()); + assertEquals(playerName, playerProfile.getPlayerName()); + assertEquals(uuid, playerProfile.getUniqueId()); + + PlayerProfile retrievedFromDisk = db.loadPlayerProfile(uuid); + assertTrue(retrievedFromDisk.isLoaded()); + assertEquals(playerName, retrievedFromDisk.getPlayerName()); + assertEquals(uuid, retrievedFromDisk.getUniqueId()); + + //Checking a new user for being "zero" initialized + checkNewUserValues(playerProfile, newUserTestStartingLvl); + checkNewUserValues(retrievedFromDisk, newUserTestStartingLvl); + + //TODO: Should we do any dupe checking? Probably not needed as it would be caught on the next load + db.newUser("disco", new UUID(3, 3)); + db.newUser("dingus", new UUID(3, 4)); + db.newUser("duped_dingus", new UUID(3, 4)); + } + + private void checkNewUserValues(@NotNull PlayerProfile playerProfile, int startingLevel) { + //Checking a new user for being zero initialized + for(PrimarySkillType primarySkillType : PrimarySkillType.values()) { + if(SkillTools.isChildSkill(primarySkillType)) + continue; + + assertEquals(startingLevel, playerProfile.getSkillLevel(primarySkillType)); + assertEquals(0, playerProfile.getSkillXpLevelRaw(primarySkillType), 0); + } + + for(SuperAbilityType superAbilityType : SuperAbilityType.values()) { + assertEquals(0, playerProfile.getAbilityDATS(superAbilityType)); + } + + assertTrue(playerProfile.getLastLogin() > 0); + assertEquals(playerProfile.getChimaerWingDATS(), 0); + assertEquals(playerProfile.getScoreboardTipsShown(), 0); + } + @Test public void testLoadByUUID() { File dbFile = prepareDatabaseTestResource(DB_HEALTHY);