diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPermissionAttachmentManager.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPermissionAttachmentManager.java new file mode 100644 index 000000000..5c9461032 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPermissionAttachmentManager.java @@ -0,0 +1,58 @@ +package com.sk89q.worldedit.bukkit; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import org.bukkit.entity.Player; +import org.bukkit.permissions.PermissionAttachment; + +public class BukkitPermissionAttachmentManager { + + private final WorldEditPlugin plugin; + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + private final Map attachments = new HashMap(); + + public BukkitPermissionAttachmentManager(WorldEditPlugin plugin) { + this.plugin = plugin; + } + + public synchronized PermissionAttachment addAttachment(Player p) { + PermissionAttachment attach; + + //try find attachment + lock.readLock().lock(); + try { + attach = attachments.get(p); + } finally { + lock.readLock().unlock(); + } + + if (attach == null) { + lock.writeLock().lock(); + try { + //check again - do not remove this + attach = attachments.get(p); + if (attach == null) { + attach = p.addAttachment(plugin); + attachments.put(p, attach); + } + } finally { + lock.writeLock().unlock(); + } + } + return attach; + } + + public void removeAttachment(Player p) { + PermissionAttachment attach; + lock.writeLock().lock(); + try { + attach = attachments.remove(p); + } finally { + lock.writeLock().unlock(); + } + if (attach != null) { + p.removeAttachment(attach); + } + } +} diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index 8a84d5d94..e67a4f80d 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -67,26 +67,27 @@ import java.util.HashMap; import java.util.Map; import java.util.Locale; import java.util.UUID; +import java.util.concurrent.locks.ReentrantReadWriteLock; import javax.annotation.Nullable; public class BukkitPlayer extends AbstractPlayerActor { - private Player player; - private WorldEditPlugin plugin; - private PermissionAttachment permAttachment; + private final Player player; + private final WorldEditPlugin plugin; + private final PermissionAttachment permAttachment; public BukkitPlayer(Player player) { super(getExistingMap(WorldEditPlugin.getInstance(), player)); this.plugin = WorldEditPlugin.getInstance(); this.player = player; - this.permAttachment = player.addAttachment(plugin); + this.permAttachment = plugin.getPermissionAttachmentManager().addAttachment(player); } public BukkitPlayer(WorldEditPlugin plugin, Player player) { this.plugin = plugin; this.player = player; - this.permAttachment = player.addAttachment(plugin); + this.permAttachment = plugin.getPermissionAttachmentManager().addAttachment(player); if (Settings.IMP.CLIPBOARD.USE_DISK) { loadClipboardFromDisk(); } @@ -402,7 +403,7 @@ public class BukkitPlayer extends AbstractPlayerActor { @Override public void unregister() { player.removeMetadata("WE", WorldEditPlugin.getInstance()); + plugin.getPermissionAttachmentManager().removeAttachment(player); super.unregister(); } - } 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 10f4ef2b5..b1f476616 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 @@ -112,6 +112,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter private BukkitImplAdapter bukkitAdapter; private BukkitServerInterface server; private BukkitConfiguration config; + private BukkitPermissionAttachmentManager permissionAttachmentManager; @Override public void onLoad() { @@ -125,6 +126,8 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter // Setup platform server = new BukkitServerInterface(this, getServer()); worldEdit.getPlatformManager().register(server); + + permissionAttachmentManager = new BukkitPermissionAttachmentManager(this); Path delChunks = Paths.get(getDataFolder().getPath(), DELCHUNKS_FILE_NAME); if (Files.exists(delChunks)) { @@ -480,6 +483,15 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter public PermissionsResolverManager getPermissionsResolver() { return PermissionsResolverManager.getInstance(); } + + /** + * Get the permissions resolver in use. + * + * @return the permissions resolver + */ + public BukkitPermissionAttachmentManager getPermissionAttachmentManager() { + return permissionAttachmentManager; + } /** * Used to wrap a Bukkit Player as a WorldEdit Player.