summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pom.xml7
-rw-r--r--src/main/java/org/bukkit/permissions/PermissibleBase.java17
-rw-r--r--src/main/java/org/bukkit/permissions/Permission.java65
-rw-r--r--src/main/java/org/bukkit/plugin/PluginManager.java84
-rw-r--r--src/main/java/org/bukkit/plugin/SimplePluginManager.java125
5 files changed, 282 insertions, 16 deletions
diff --git a/pom.xml b/pom.xml
index 72b2e44d..7e841f0b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -100,5 +100,12 @@
<type>jar</type>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava-collections</artifactId>
+ <version>r03</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/src/main/java/org/bukkit/permissions/PermissibleBase.java b/src/main/java/org/bukkit/permissions/PermissibleBase.java
index 950cfc8b..fe2b9e3b 100644
--- a/src/main/java/org/bukkit/permissions/PermissibleBase.java
+++ b/src/main/java/org/bukkit/permissions/PermissibleBase.java
@@ -154,12 +154,14 @@ public class PermissibleBase implements Permissible {
private synchronized void calculatePermissions() {
if (dirtyPermissions) {
- permissions.clear();
+ clearPermissions();
Set<Permission> defaults = Bukkit.getServer().getPluginManager().getDefaultPermissions(isOp());
+ Bukkit.getServer().getPluginManager().subscribeToDefaultPerms(isOp(), this);
for (Permission perm : defaults) {
String name = perm.getName().toLowerCase();
permissions.put(name, new PermissionAttachmentInfo(this, name, null, true));
+ Bukkit.getServer().getPluginManager().subscribeToPermission(name, this);
calculateChildPermissions(perm.getChildren(), false, null);
}
@@ -171,6 +173,18 @@ public class PermissibleBase implements Permissible {
}
}
+ private synchronized void clearPermissions() {
+ Set<String> perms = permissions.keySet();
+
+ for (String name : perms) {
+ Bukkit.getServer().getPluginManager().unsubscribeFromPermission(name, this);
+ }
+
+ Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(isOp(), this);
+
+ permissions.clear();
+ }
+
private void calculateChildPermissions(Map<String, Boolean> children, boolean invert, PermissionAttachment attachment) {
Set<String> keys = children.keySet();
@@ -180,6 +194,7 @@ public class PermissibleBase implements Permissible {
String lname = name.toLowerCase();
permissions.put(lname, new PermissionAttachmentInfo(this, lname, attachment, value));
+ Bukkit.getServer().getPluginManager().subscribeToPermission(name, this);
if (perm != null) {
calculateChildPermissions(perm.getChildren(), !value, attachment);
diff --git a/src/main/java/org/bukkit/permissions/Permission.java b/src/main/java/org/bukkit/permissions/Permission.java
index 5acbe220..ea6ade6b 100644
--- a/src/main/java/org/bukkit/permissions/Permission.java
+++ b/src/main/java/org/bukkit/permissions/Permission.java
@@ -5,6 +5,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import org.bukkit.Bukkit;
/**
* Represents a unique permission that may be attached to a {@link Permissible}
@@ -51,6 +52,8 @@ public class Permission {
if (children != null) {
this.children.putAll(children);
}
+
+ recalculatePermissibles();
}
/**
@@ -65,12 +68,12 @@ public class Permission {
/**
* Gets the children of this permission.
*
- * This is a copy and changes will not be saved.
+ * If you change this map in any form, you must call {@link #recalculatePermissibles()} to recalculate all {@link Permissible}s
*
* @return Permission children
*/
public Map<String, Boolean> getChildren() {
- return new LinkedHashMap<String, Boolean>(children);
+ return children;
}
/**
@@ -83,6 +86,23 @@ public class Permission {
}
/**
+ * Sets the default value of this permission.
+ *
+ * This will not be saved to disk, and is a temporary operation until the server reloads permissions.
+ * Changing this default will cause all {@link Permissible}s that contain this permission to recalculate their permissions
+ *
+ * @param value The new default to set
+ */
+ public void setDefault(PermissionDefault value) {
+ if (defaultValue == null) {
+ throw new IllegalArgumentException("Default value cannot be null");
+ }
+
+ defaultValue = value;
+ recalculatePermissibles();
+ }
+
+ /**
* Gets a brief description of this permission, if set
*
* @return Brief description of this permission
@@ -92,6 +112,47 @@ public class Permission {
}
/**
+ * Sets the description of this permission.
+ *
+ * This will not be saved to disk, and is a temporary operation until the server reloads permissions.
+ *
+ * @param value The new description to set
+ */
+ public void setDescription(String value) {
+ if (value == null) {
+ description = "";
+ } else {
+ description = value;
+ }
+ }
+
+ /**
+ * Gets a set containing every {@link Permissible} that has this permission.
+ *
+ * This set cannot be modified.
+ *
+ * @return Set containing permissibles with this permission
+ */
+ public Set<Permissible> getPermissibles() {
+ return Bukkit.getServer().getPluginManager().getPermissionSubscriptions(name);
+ }
+
+ /**
+ * Recalculates all {@link Permissible}s that contain this permission.
+ *
+ * This should be called after modifying the children, and is automatically called after modifying the default value
+ */
+ public void recalculatePermissibles() {
+ Set<Permissible> perms = getPermissibles();
+
+ Bukkit.getServer().getPluginManager().recalculatePermissionDefaults(this);
+
+ for (Permissible p : perms) {
+ p.recalculatePermissions();
+ }
+ }
+
+ /**
* Loads a Permission from a map of data, usually used from retrieval from a yaml file.
*
* The data may contain the following keys:
diff --git a/src/main/java/org/bukkit/plugin/PluginManager.java b/src/main/java/org/bukkit/plugin/PluginManager.java
index b445f180..f2c407d3 100644
--- a/src/main/java/org/bukkit/plugin/PluginManager.java
+++ b/src/main/java/org/bukkit/plugin/PluginManager.java
@@ -6,6 +6,7 @@ import java.util.Set;
import org.bukkit.event.Event;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.Listener;
+import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.Permission;
/**
@@ -153,9 +154,92 @@ public interface PluginManager {
public void addPermission(Permission perm);
/**
+ * Removes a {@link Permission} registration from this plugin manager.
+ *
+ * If the specified permission does not exist in this plugin manager, nothing will happen.
+ *
+ * Removing a permission registration will <b>not</b> remove the permission from any {@link Permissible}s that have it.
+ *
+ * @param perm Permission to remove
+ */
+ public void removePermission(Permission perm);
+
+ /**
+ * Removes a {@link Permission} registration from this plugin manager.
+ *
+ * If the specified permission does not exist in this plugin manager, nothing will happen.
+ *
+ * Removing a permission registration will <b>not</b> remove the permission from any {@link Permissible}s that have it.
+ *
+ * @param name Permission to remove
+ */
+ public void removePermission(String name);
+
+ /**
* Gets the default permissions for the given op status
*
* @param op Which set of default permissions to get
*/
public Set<Permission> getDefaultPermissions(boolean op);
+
+ /**
+ * Recalculates the defaults for the given {@link Permission}.
+ *
+ * This will have no effect if the specified permission is not registered here.
+ *
+ * @param perm Permission to recalculate
+ */
+ public void recalculatePermissionDefaults(Permission perm);
+
+ /**
+ * Subscribes the given Permissible for information about the requested Permission, by name.
+ *
+ * If the specified Permission changes in any form, the Permissible will be asked to recalculate.
+ *
+ * @param permission Permission to subscribe to
+ * @param permissible Permissible subscribing
+ */
+ public void subscribeToPermission(String permission, Permissible permissible);
+
+ /**
+ * Unsubscribes the given Permissible for information about the requested Permission, by name.
+ *
+ * @param permission Permission to unsubscribe from
+ * @param permissible Permissible subscribing
+ */
+ public void unsubscribeFromPermission(String permission, Permissible permissible);
+
+ /**
+ * Gets a set containing all subscribed {@link Permissible}s to the given permission, by name
+ *
+ * @param permission Permission to query for
+ * @return Set containing all subscribed permissions
+ */
+ public Set<Permissible> getPermissionSubscriptions(String permission);
+
+ /**
+ * Subscribes to the given Default permissions by operator status
+ *
+ * If the specified defaults change in any form, the Permissible will be asked to recalculate.
+ *
+ * @param op Default list to subscribe to
+ * @param permissible Permissible subscribing
+ */
+ public void subscribeToDefaultPerms(boolean op, Permissible permissible);
+
+ /**
+ * Unsubscribes from the given Default permissions by operator status
+ *
+ * @param op Default list to unsubscribe from
+ * @param permissible Permissible subscribing
+ */
+ public void unsubscribeFromDefaultPerms(boolean op, Permissible permissible);
+
+ /**
+ * Gets a set containing all subscribed {@link Permissible}s to the given default list, by op status
+ *
+ * @param op Default list to query for
+ * @return Set containing all subscribed permissions
+ */
+ public Set<Permissible> getDefaultPermSubscriptions(boolean op);
}
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
index eaf3b671..7f37d29e 100644
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
@@ -1,5 +1,7 @@
package org.bukkit.plugin;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.MapMaker;
import java.io.File;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
@@ -27,7 +29,9 @@ import org.bukkit.command.SimpleCommandMap;
import org.bukkit.event.Event;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.Listener;
+import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.Permission;
+import org.bukkit.permissions.PermissionDefault;
import org.bukkit.util.FileUtil;
@@ -44,6 +48,8 @@ public final class SimplePluginManager implements PluginManager {
private final SimpleCommandMap commandMap;
private final Map<String, Permission> permissions = new HashMap<String, Permission>();
private final Map<Boolean, Set<Permission>> defaultPerms = new LinkedHashMap<Boolean, Set<Permission>>();
+ private final Map<String, Map<Permissible, Boolean>> permSubs = new HashMap<String, Map<Permissible, Boolean>>();
+ private final Map<Boolean, Map<Permissible, Boolean>> defSubs = new HashMap<Boolean, Map<Permissible, Boolean>>();
private final Comparator<RegisteredListener> comparer = new Comparator<RegisteredListener>() {
public int compare(RegisteredListener i, RegisteredListener j) {
int result = i.getPriority().compareTo(j.getPriority());
@@ -418,24 +424,117 @@ public final class SimplePluginManager implements PluginManager {
}
permissions.put(name, perm);
+ calculatePermissionDefault(perm);
+ }
+
+ public Set<Permission> getDefaultPermissions(boolean op) {
+ return ImmutableSet.copyOf(defaultPerms.get(op));
+ }
+
+ public void removePermission(Permission perm) {
+ removePermission(perm.getName().toLowerCase());
+ }
+
+ public void removePermission(String name) {
+ permissions.remove(name);
+ }
+
+ public void recalculatePermissionDefaults(Permission perm) {
+ if (permissions.containsValue(perm)) {
+ defaultPerms.get(true).remove(perm);
+ defaultPerms.get(false).remove(perm);
+
+ calculatePermissionDefault(perm);
+ }
+ }
+ private void calculatePermissionDefault(Permission perm) {
if (!perm.getChildren().isEmpty()) {
- switch (perm.getDefault()) {
- case TRUE:
- defaultPerms.get(true).add(perm);
- defaultPerms.get(false).add(perm);
- break;
- case OP:
- defaultPerms.get(true).add(perm);
- break;
- case NOT_OP:
- defaultPerms.get(false).add(perm);
- break;
+ if ((perm.getDefault() == PermissionDefault.OP) || (perm.getDefault() == PermissionDefault.TRUE)) {
+ defaultPerms.get(true).add(perm);
+ dirtyPermissibles(true);
+ }
+ if ((perm.getDefault() == PermissionDefault.NOT_OP) || (perm.getDefault() == PermissionDefault.TRUE)) {
+ defaultPerms.get(false).add(perm);
+ dirtyPermissibles(false);
}
}
}
- public Set<Permission> getDefaultPermissions(boolean op) {
- return defaultPerms.get(op);
+ private void dirtyPermissibles(boolean op) {
+ Set<Permissible> permissibles = getDefaultPermSubscriptions(op);
+
+ for (Permissible p : permissibles) {
+ p.recalculatePermissions();
+ }
+ }
+
+ public void subscribeToPermission(String permission, Permissible permissible) {
+ String name = permission.toLowerCase();
+ Map<Permissible, Boolean> map = permSubs.get(name);
+
+ if (map == null) {
+ map = new MapMaker().weakKeys().makeMap();
+ permSubs.put(name, map);
+ }
+
+ map.put(permissible, true);
+ }
+
+ public void unsubscribeFromPermission(String permission, Permissible permissible) {
+ String name = permission.toLowerCase();
+ Map<Permissible, Boolean> map = permSubs.get(name);
+
+ if (map != null) {
+ map.remove(permissible);
+
+ if (map.isEmpty()) {
+ permSubs.remove(name);
+ }
+ }
+ }
+
+ public Set<Permissible> getPermissionSubscriptions(String permission) {
+ String name = permission.toLowerCase();
+ Map<Permissible, Boolean> map = permSubs.get(name);
+
+ if (map == null) {
+ return ImmutableSet.of();
+ } else {
+ return ImmutableSet.copyOf(map.keySet());
+ }
+ }
+
+ public void subscribeToDefaultPerms(boolean op, Permissible permissible) {
+ Map<Permissible, Boolean> map = defSubs.get(op);
+
+ if (map == null) {
+ map = new MapMaker().weakKeys().makeMap();
+ defSubs.put(op, map);
+ }
+
+ map.put(permissible, true);
+ }
+
+ public void unsubscribeFromDefaultPerms(boolean op, Permissible permissible) {
+ Map<Permissible, Boolean> map = defSubs.get(op);
+
+ if (map != null) {
+ map.remove(permissible);
+
+ if (map.isEmpty()) {
+ defSubs.remove(op);
+ }
+ }
+ }
+
+ public Set<Permissible> getDefaultPermSubscriptions(boolean op) {
+ Map<Permissible, Boolean> map = defSubs.get(op);
+
+ if (map == null) {
+ return ImmutableSet.of();
+ } else {
+ return ImmutableSet.copyOf(map.keySet());
+ }
}
}