From d7543884a547886e11806776d001e9fd7f1e3471 Mon Sep 17 00:00:00 2001 From: Jordan Date: Tue, 10 May 2022 09:10:59 +0100 Subject: [PATCH] Check cached bukkit player is the same as the current player online (#1732) * Check cached bukkit player is the same as the current player online - If plugins do silly things like teleport, deop (anything that requires a perm-recheck) (anything that ultimately requires a BukkitPlayer at some point) then the retention of metadata by the server (as it's stored based on a string value indescriminate of player a player relogging) means that a BukkitPlayer caching an old player object will be kept, cached and retrieved by FAWE. Adding a simple memory-based equality check when the player rejoins, and then "invaliding" (redoing) the cache if the players are not equal, fixes this. - Fixes #1730 * Address comments * Add comment explaining reference equality check to code --- .../com/sk89q/worldedit/bukkit/WorldEditListener.java | 10 +++++++++- .../com/sk89q/worldedit/bukkit/WorldEditPlugin.java | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditListener.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditListener.java index abdd4c16f..06f8f81ed 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditListener.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditListener.java @@ -86,7 +86,15 @@ public class WorldEditListener implements Listener { return; } - Player player = plugin.wrapPlayer(event.getPlayer()); + BukkitPlayer player = plugin.wrapPlayer(event.getPlayer()); + //If plugins do silly things like teleport, deop (anything that requires a perm-recheck) (anything that ultimately + // requires a BukkitPlayer at some point) then the retention of metadata by the server (as it's stored based on a + // string value indescriminate of player a player relogging) means that a BukkitPlayer caching an old player object + // will be kept, cached and retrieved by FAWE. Adding a simple memory-based equality check when the player rejoins, + // and then "invaliding" (redoing) the cache if the players are not equal, fixes this. + if (player.getPlayer() != event.getPlayer()) { + player = plugin.reCachePlayer(event.getPlayer()); + } LocalSession session; if ((session = WorldEdit.getInstance().getSessionManager().getIfPresent(player)) != null) { session.loadDefaults(player, true); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java index d5605137a..f35891656 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java @@ -573,6 +573,14 @@ public class WorldEditPlugin extends JavaPlugin { } return (BukkitPlayer) meta.get(0).value(); } + + BukkitPlayer reCachePlayer(Player player) { + synchronized (player) { + BukkitPlayer wePlayer = new BukkitPlayer(this, player); + player.setMetadata("WE", new FixedMetadataValue(this, wePlayer)); + return wePlayer; + } + } //FAWE end public Actor wrapCommandSender(CommandSender sender) {