diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/storage/backend/legacy/LegacyStorage.java b/src/main/java/io/github/thebusybiscuit/slimefun4/storage/backend/legacy/LegacyStorage.java index 5b35e5e4cc..d7981a5466 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/storage/backend/legacy/LegacyStorage.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/storage/backend/legacy/LegacyStorage.java @@ -85,9 +85,15 @@ public void savePlayerData(@Nonnull UUID uuid, @Nonnull PlayerData data) { // Save research playerFile.setValue("rearches", null); - for (Research research : data.getResearches()) { - // Legacy data uses IDs - playerFile.setValue("researches." + research.getID(), true); + for (Research research : Slimefun.getRegistry().getResearches()) { + // Save the research if it's researched + if (data.getResearches().contains(research)) { + playerFile.setValue("researches." + research.getID(), true); + + // Remove the research if it's no longer researched + } else if (playerFile.contains("researches." + research.getID())) { + playerFile.setValue("researches." + research.getID(), null); + } } // Save backpacks diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java b/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java index 804f24306a..1859659999 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java @@ -62,6 +62,7 @@ public static void unload() throws IOException { FileUtils.deleteDirectory(new File("data-storage")); } + // Test simple loading and saving of player data @Test void testLoadingResearches() throws IOException { // Create a player file which we can load @@ -275,6 +276,102 @@ void testSavingWaypoints() throws InterruptedException { Assertions.assertEquals("world", waypoint.getLocation().getWorld().getName()); } + // Test realistic situations + @Test + void testResearchChanges() throws InterruptedException { + UUID uuid = UUID.randomUUID(); + File playerFile = new File("data-storage/Slimefun/Players/" + uuid + ".yml"); + + OfflinePlayer player = Bukkit.getOfflinePlayer(uuid); + PlayerProfile profile = TestUtilities.awaitProfile(player); + + // Unlock all researches + for (Research research : Slimefun.getRegistry().getResearches()) { + profile.setResearched(research, true); + } + + // Save the player data + LegacyStorage storage = new LegacyStorage(); + storage.savePlayerData(uuid, profile.getPlayerData()); + + // Assert the file exists and data is correct + Assertions.assertTrue(playerFile.exists()); + PlayerData assertion = storage.loadPlayerData(uuid); + Assertions.assertEquals(10, assertion.getResearches().size()); + for (int i = 0; i < 10; i++) { + Assertions.assertTrue(assertion.getResearches().contains(Slimefun.getRegistry().getResearches().get(i))); + } + + // Now let's change the data and save it again + profile.setResearched(Slimefun.getRegistry().getResearches().get(3), false); + + // Save the player data + storage.savePlayerData(uuid, profile.getPlayerData()); + + // Assert the file exists and data is correct + Assertions.assertTrue(playerFile.exists()); + System.out.println("update assertion"); + assertion = storage.loadPlayerData(uuid); + Assertions.assertEquals(9, assertion.getResearches().size()); + for (int i = 0; i < 10; i++) { + if (i != 3) { + Assertions.assertTrue(assertion.getResearches().contains(Slimefun.getRegistry().getResearches().get(i))); + } + } + } + + // Test realistic situations - when we fix the serialization issue + // @Test + // void testBackpackChanges() throws InterruptedException {} + + @Test + void testWaypointChanges() throws InterruptedException { + // Create mock world + World world = server.createWorld(WorldCreator.name("world").environment(Environment.NORMAL)); + + // Create a player file which we can load + UUID uuid = UUID.randomUUID(); + File playerFile = new File("data-storage/Slimefun/Players/" + uuid + ".yml"); + + OfflinePlayer player = Bukkit.getOfflinePlayer(uuid); + PlayerProfile profile = TestUtilities.awaitProfile(player); + + profile.addWaypoint(new Waypoint( + player.getUniqueId(), + "test", + new Location(world, 1, 2, 3, 4, 5), + ChatColor.GREEN + "Test waypoint" + )); + + Waypoint test2 = new Waypoint( + player.getUniqueId(), + "test2", + new Location(world, 10, 20, 30, 40, 50), + ChatColor.GREEN + "Test 2 waypoint" + ); + profile.addWaypoint(test2); + + // Save the player data + LegacyStorage storage = new LegacyStorage(); + storage.savePlayerData(uuid, profile.getPlayerData()); + + // Assert the file exists and data is correct + Assertions.assertTrue(playerFile.exists()); + PlayerData assertion = storage.loadPlayerData(uuid); + Assertions.assertEquals(2, assertion.getWaypoints().size()); + + // Remove one + profile.removeWaypoint(test2); + + // Save the player data + storage.savePlayerData(uuid, profile.getPlayerData()); + + // Assert the file exists and data is correct + Assertions.assertTrue(playerFile.exists()); + assertion = storage.loadPlayerData(uuid); + Assertions.assertEquals(1, assertion.getWaypoints().size()); + } + // Utils private static void setupResearches() { for (int i = 0; i < 10; i++) {