diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java index 00cacd4cd..8dfc7414f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java @@ -394,12 +394,18 @@ public class PlayerProfile { loading.put(uuid, true); Slimefun.getThreadService().newThread(Slimefun.instance(), "PlayerProfile#get(" + uuid + ")", () -> { PlayerData data = Slimefun.getPlayerStorage().loadPlayerData(p.getUniqueId()); - loading.remove(uuid); AsyncProfileLoadEvent event = new AsyncProfileLoadEvent(new PlayerProfile(p, data)); Bukkit.getPluginManager().callEvent(event); Slimefun.getRegistry().getPlayerProfiles().put(uuid, event.getProfile()); + + // Make sure we call this after we put the PlayerProfile into the registry. + // Otherwise, we end up with a race condition where the profile is not in the map just _yet_ + // but the loading flag is gone and we can end up loading it a second time (and thus can dupe items) + // Fixes https://github.com/Slimefun/Slimefun4/issues/4130 + loading.remove(uuid); + callback.accept(event.getProfile()); }); @@ -434,10 +440,15 @@ public class PlayerProfile { // Should probably prevent multiple requests for the same profile in the future Slimefun.getThreadService().newThread(Slimefun.instance(), "PlayerProfile#request(" + uuid + ")", () -> { PlayerData data = Slimefun.getPlayerStorage().loadPlayerData(uuid); - loading.remove(uuid); PlayerProfile pp = new PlayerProfile(p, data); Slimefun.getRegistry().getPlayerProfiles().put(uuid, pp); + + // Make sure we call this after we put the PlayerProfile into the registry. + // Otherwise, we end up with a race condition where the profile is not in the map just _yet_ + // but the loading flag is gone and we can end up loading it a second time (and thus can dupe items) + // Fixes https://github.com/Slimefun/Slimefun4/issues/4130 + loading.remove(uuid); }); return false;