package org.bukkit.permissions; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Level; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; /** * Base Permissible for use in any Permissible object via proxy or extension */ public class PermissibleBase implements Permissible { private ServerOperator opable = null; private Permissible parent = this; private final List attachments = new LinkedList(); private final Map permissions = new HashMap(); public PermissibleBase(ServerOperator opable) { this.opable = opable; if (opable instanceof Permissible) { this.parent = (Permissible)opable; } recalculatePermissions(); } public boolean isOp() { if (opable == null) { return false; } else { return opable.isOp(); } } public void setOp(boolean value) { if (opable == null) { throw new UnsupportedOperationException("Cannot change op value as no ServerOperator is set"); } else { opable.setOp(value); } } public boolean isPermissionSet(String name) { if (name == null) { throw new IllegalArgumentException("Permission name cannot be null"); } return permissions.containsKey(name.toLowerCase()); } public boolean isPermissionSet(Permission perm) { if (perm == null) { throw new IllegalArgumentException("Permission cannot be null"); } return isPermissionSet(perm.getName()); } public boolean hasPermission(String inName) { if (inName == null) { throw new IllegalArgumentException("Permission name cannot be null"); } String name = inName.toLowerCase(); if (isPermissionSet(name)) { return permissions.get(name).getValue(); } else { Permission perm = Bukkit.getServer().getPluginManager().getPermission(name); if (perm != null) { return perm.getDefault().getValue(isOp()); } else { return false; } } } public boolean hasPermission(Permission perm) { if (perm == null) { throw new IllegalArgumentException("Permission cannot be null"); } String name = perm.getName().toLowerCase(); if (isPermissionSet(name)) { return permissions.get(name).getValue(); } else if (perm != null) { return perm.getDefault().getValue(isOp()); } else { return false; } } public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { if (name == null) { throw new IllegalArgumentException("Permission name cannot be null"); } else if (plugin == null) { throw new IllegalArgumentException("Plugin cannot be null"); } else if (!plugin.isEnabled()) { throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled"); } PermissionAttachment result = addAttachment(plugin); result.setPermission(name, value); recalculatePermissions(); return result; } public PermissionAttachment addAttachment(Plugin plugin) { if (plugin == null) { throw new IllegalArgumentException("Plugin cannot be null"); } else if (!plugin.isEnabled()) { throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled"); } PermissionAttachment result = new PermissionAttachment(plugin, parent); attachments.add(result); recalculatePermissions(); return result; } public void removeAttachment(PermissionAttachment attachment) { if (attachment == null) { throw new IllegalArgumentException("Attachment cannot be null"); } if (attachments.contains(attachment)) { attachments.remove(attachment); PermissionRemovedExecutor ex = attachment.getRemovalCallback(); if (ex != null) { ex.attachmentRemoved(attachment); } recalculatePermissions(); } else { throw new IllegalArgumentException("Given attachment is not part of Permissible object " + parent); } } public void recalculatePermissions() { clearPermissions(); Set defaults = Bukkit.getServer().getPluginManager().getDefaultPermissions(isOp()); Bukkit.getServer().getPluginManager().subscribeToDefaultPerms(isOp(), parent); for (Permission perm : defaults) { String name = perm.getName().toLowerCase(); permissions.put(name, new PermissionAttachmentInfo(parent, name, null, true)); Bukkit.getServer().getPluginManager().subscribeToPermission(name, parent); calculateChildPermissions(perm.getChildren(), false, null); } for (PermissionAttachment attachment : attachments) { calculateChildPermissions(attachment.getPermissions(), false, attachment); } } private synchronized void clearPermissions() { Set perms = permissions.keySet(); for (String name : perms) { Bukkit.getServer().getPluginManager().unsubscribeFromPermission(name, parent); } Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(false, parent); Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(true, parent); permissions.clear(); } private void calculateChildPermissions(Map children, boolean invert, PermissionAttachment attachment) { Set keys = children.keySet(); for (String name : keys) { Permission perm = Bukkit.getServer().getPluginManager().getPermission(name); boolean value = children.get(name) ^ invert; String lname = name.toLowerCase(); permissions.put(lname, new PermissionAttachmentInfo(parent, lname, attachment, value)); Bukkit.getServer().getPluginManager().subscribeToPermission(name, parent); if (perm != null) { calculateChildPermissions(perm.getChildren(), !value, attachment); } } } public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { if (name == null) { throw new IllegalArgumentException("Permission name cannot be null"); } else if (plugin == null) { throw new IllegalArgumentException("Plugin cannot be null"); } else if (!plugin.isEnabled()) { throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled"); } PermissionAttachment result = addAttachment(plugin, ticks); if (result != null) { result.setPermission(name, value); } return result; } public PermissionAttachment addAttachment(Plugin plugin, int ticks) { if (plugin == null) { throw new IllegalArgumentException("Plugin cannot be null"); } else if (!plugin.isEnabled()) { throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled"); } PermissionAttachment result = addAttachment(plugin); if (Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new RemoveAttachmentRunnable(result), ticks) == -1) { Bukkit.getServer().getLogger().log(Level.WARNING, "Could not add PermissionAttachment to " + parent + " for plugin " + plugin.getDescription().getFullName() + ": Scheduler returned -1"); result.remove(); return null; } else { return result; } } public Set getEffectivePermissions() { return new HashSet(permissions.values()); } private class RemoveAttachmentRunnable implements Runnable { private PermissionAttachment attachment; public RemoveAttachmentRunnable(PermissionAttachment attachment) { this.attachment = attachment; } public void run() { attachment.remove(); } } }