From 9c052b5178564969f1040626376963ae85a9d057 Mon Sep 17 00:00:00 2001 From: ElgarL Date: Wed, 18 Jan 2012 16:39:12 +0000 Subject: [PATCH] Better optimize assembling of a players permissions and allow the * node to populate all registered superperms. --- EssentialsGroupManager/src/Changelog.txt | 3 +- .../Tasks/BukkitPermsUpdateTask.java | 2 +- .../org/anjocaido/groupmanager/data/User.java | 10 +- .../permissions/AnjoPermissionsHandler.java | 132 ++++++++++-------- .../permissions/BukkitPermissions.java | 82 ++++++++--- .../PermissionsReaderInterface.java | 3 +- 6 files changed, 153 insertions(+), 79 deletions(-) diff --git a/EssentialsGroupManager/src/Changelog.txt b/EssentialsGroupManager/src/Changelog.txt index 741777748..d278aa127 100644 --- a/EssentialsGroupManager/src/Changelog.txt +++ b/EssentialsGroupManager/src/Changelog.txt @@ -104,4 +104,5 @@ v 1.8: - Removed '- bukkit.command' form the globalgroups permission nodes. v 1.9: - Optimize populating Bukkit perms so we no longer calculate the child nodes (Bukkit already does this). - - Added a tidy error message for invalid permission entries in GlobalGroups. \ No newline at end of file + - Added a tidy error message for invalid permission entries in GlobalGroups. + - Better optimize assembling of a players permissions and allow the * node to populate all registered superperms. \ No newline at end of file diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/Tasks/BukkitPermsUpdateTask.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/Tasks/BukkitPermsUpdateTask.java index 8788fc83b..f4b805c35 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/Tasks/BukkitPermsUpdateTask.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/Tasks/BukkitPermsUpdateTask.java @@ -18,7 +18,7 @@ public class BukkitPermsUpdateTask implements Runnable { public void run() { // Signal loaded and update BukkitPermissions. GroupManager.setLoaded(true); - //GroupManager.BukkitPermissions.collectPermissions(); + GroupManager.BukkitPermissions.collectPermissions(); GroupManager.BukkitPermissions.updateAllPlayers(); GroupManager.logger.info("Bukkit Permissions Updated!"); diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/User.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/User.java index 1f2be9875..d41f96b0d 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/User.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/User.java @@ -113,7 +113,7 @@ public class User extends DataUnit implements Cloneable { this.group = group; flagAsChanged(); if (GroupManager.isLoaded()) - if (GroupManager.BukkitPermissions.player_join = false) + if (!GroupManager.BukkitPermissions.isPlayer_join()) GroupManager.BukkitPermissions.updateAllPlayers(); } @@ -130,7 +130,7 @@ public class User extends DataUnit implements Cloneable { this.group = group.getName(); flagAsChanged(); if (GroupManager.isLoaded()) { - if (GroupManager.BukkitPermissions.player_join = false) + if (!GroupManager.BukkitPermissions.isPlayer_join()) GroupManager.BukkitPermissions.updateAllPlayers(); // Do we notify of the group change? @@ -159,7 +159,7 @@ public class User extends DataUnit implements Cloneable { subGroups.add(subGroup.getName()); flagAsChanged(); if (GroupManager.isLoaded()) { - if (GroupManager.BukkitPermissions.player_join = false) + if (!GroupManager.BukkitPermissions.isPlayer_join()) GroupManager.BukkitPermissions.updateAllPlayers(); GroupManagerEventHandler.callEvent(this, Action.USER_SUBGROUP_CHANGED); } @@ -182,7 +182,7 @@ public class User extends DataUnit implements Cloneable { if (subGroups.remove(subGroup.getName())) { flagAsChanged(); if (GroupManager.isLoaded()) - if (GroupManager.BukkitPermissions.player_join = false) + if (!GroupManager.BukkitPermissions.isPlayer_join()) GroupManager.BukkitPermissions.updateAllPlayers(); GroupManagerEventHandler.callEvent(this, Action.USER_SUBGROUP_CHANGED); return true; @@ -229,7 +229,7 @@ public class User extends DataUnit implements Cloneable { } flagAsChanged(); if (GroupManager.isLoaded()) { - if (GroupManager.BukkitPermissions.player_join = false) + if (!GroupManager.BukkitPermissions.isPlayer_join()) GroupManager.BukkitPermissions.updateAllPlayers(); GroupManagerEventHandler.callEvent(this, Action.USER_INFO_CHANGED); } diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java index 167103796..51c6dded5 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java @@ -5,9 +5,11 @@ package org.anjocaido.groupmanager.permissions; import java.util.ArrayList; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; import org.anjocaido.groupmanager.GroupManager; import org.anjocaido.groupmanager.data.Group; @@ -97,81 +99,101 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface { */ @Override public List getAllPlayersPermissions(String userName) { - return getAllPlayersPermissions(userName, true); + List perms = new ArrayList(); + + perms.addAll(getAllPlayersPermissions(userName, true)); + + return perms; } + /** * Returns All permissions (including inheritance and sub groups) for the * player. With or without Bukkit child nodes. * * @param userName - * @return List of all players permissions. + * @return Set of all players permissions. */ @Override - public List getAllPlayersPermissions(String userName, Boolean includeChildren) { + public Set getAllPlayersPermissions(String userName, Boolean includeChildren) { - List playerPermArray = new ArrayList(); + Set playerPermArray = new HashSet(); - for (String perm : ph.getUser(userName).getPermissionList()) { - if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) { - playerPermArray.add(perm); - - if (includeChildren) { - Map children = GroupManager.BukkitPermissions.getAllChildren(perm, playerPermArray); - - if (children != null) { - for (String child : children.keySet()) { - if (children.get(child)) - if ((!playerPermArray.contains(child)) && (!playerPermArray.contains("-" + child))) { - playerPermArray.add(child); - } - } - } - } - } - } + // Add the players own permissions. + playerPermArray.addAll(populatePerms(ph.getUser(userName).getPermissionList(), includeChildren)); + + // fetch all group permissions for (String group : getGroups(userName)) { + Set groupPermArray = new HashSet(); + if (group.startsWith("g:") && GroupManager.getGlobalGroups().hasGroup(group)) { - for (String perm : GroupManager.getGlobalGroups().getGroupsPermissions(group)) { - if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) { - playerPermArray.add(perm); - - if (includeChildren) { - Map children = GroupManager.BukkitPermissions.getAllChildren(perm, playerPermArray); - if (children != null) { - for (String child : children.keySet()) { - if (children.get(child)) - if ((!playerPermArray.contains(child)) && (!playerPermArray.contains("-" + child))) - playerPermArray.add(child); - } - } - } - } - } + // GlobalGroups + groupPermArray = populatePerms(GroupManager.getGlobalGroups().getGroupsPermissions(group), includeChildren); + } else { - for (String perm : ph.getGroup(group).getPermissionList()) { - if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) { - playerPermArray.add(perm); - - if (includeChildren) { - Map children = GroupManager.BukkitPermissions.getAllChildren(perm, playerPermArray); - if (children != null) { - for (String child : children.keySet()) { - if (children.get(child)) - if ((!playerPermArray.contains(child)) && (!playerPermArray.contains("-" + child))) { - playerPermArray.add(child); - } - } - } - } - } - } + // World Groups + groupPermArray = populatePerms(ph.getGroup(group).getPermissionList(), includeChildren); } + + // Add all group permissions, unless negated by direct player perms. + for (String perm : groupPermArray) + if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) + playerPermArray.add(perm); + } // Collections.sort(playerPermArray, // StringPermissionComparator.getInstance()); return playerPermArray; } + + private Set populatePerms (List perms, boolean includeChildren) { + + Set permArray = new HashSet(); + + for (String perm : perms) { + + // Allow * node to populate ALL perms in Bukkit. + if (perm.equalsIgnoreCase("*")) + permArray.addAll(GroupManager.BukkitPermissions.getAllRegisteredPermissions(includeChildren)); + + boolean negated = false; + if (perm.startsWith("-")) + negated = true; + + if (!permArray.contains(perm)) { + permArray.add(perm); + + if ((negated) && (permArray.contains(perm.substring(1)))) + permArray.remove(perm.substring(1)); + + if (includeChildren) { + + Map children = GroupManager.BukkitPermissions.getAllChildren((negated ? perm.substring(1) : perm), new HashSet()); + + if (children != null) { + if (negated) { + + // Remove children of negated nodes + for (String child : children.keySet()) + if (children.get(child)) + if (permArray.contains(child)) + permArray.remove(child); + + } else { + + // Add child nodes + for (String child : children.keySet()) + if (children.get(child)) + if ((!permArray.contains(child)) && (!permArray.contains("-" + child))) + permArray.add(child); + } + } + } + } + } + + return permArray; + } /** * Verify if player is in such group. It will check it's groups inheritance. diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/BukkitPermissions.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/BukkitPermissions.java index 91f9a9bd6..183236cd8 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/BukkitPermissions.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/BukkitPermissions.java @@ -19,9 +19,11 @@ package org.anjocaido.groupmanager.permissions; import java.lang.reflect.Field; import java.util.ArrayList; 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 org.anjocaido.groupmanager.GroupManager; //import org.anjocaido.groupmanager.data.User; @@ -61,8 +63,22 @@ public class BukkitPermissions { protected GroupManager plugin; protected boolean dumpAllPermissions = true; protected boolean dumpMatchedPermissions = true; - public boolean player_join = false; + private boolean player_join = false; + /** + * @return the player_join + */ + public boolean isPlayer_join() { + return player_join; + } + + /** + * @param player_join the player_join to set + */ + public void setPlayer_join(boolean player_join) { + this.player_join = player_join; + } + private static Field permissions; // Setup reflection (Thanks to Codename_B for the reflection source) @@ -199,21 +215,23 @@ public class BukkitPermissions { // Add all permissions for this player (GM only) // child nodes will be calculated by Bukkit. - List playerPermArray = worldData.getPermissionsHandler().getAllPlayersPermissions(player.getName(), false); + Set playerPermArray = worldData.getPermissionsHandler().getAllPlayersPermissions(player.getName(), false); Map newPerms = new HashMap(); - for (String permission : playerPermArray) { - value = true; - if (permission.startsWith("-")) { - permission = permission.substring(1); // cut off - - value = false; - } + //Set hash = new HashSet(); + //for (String permission : playerPermArray) + // hash.add(permission); + + + for (String permission : playerPermArray) { + value = (!permission.startsWith("-")); /* if (!attachment.getPermissions().containsKey(permission)) { attachment.setPermission(permission, value); } */ - newPerms.put(permission, value); + System.out.print("Permission: " + permission); + newPerms.put((value? permission : permission.substring(1)), value); } //player.recalculatePermissions(); @@ -238,14 +256,46 @@ public class BukkitPermissions { } } + /** - * Returns a map of the ALL child permissions as defined by the supplying plugin + * Fetch all permissions which are registered with superperms. + * {can include child nodes) + * + * @param includeChildren + * @return List of all permission nodes + */ + public List getAllRegisteredPermissions(boolean includeChildren) { + + List perms = new ArrayList(); + + for (Permission permission : registeredPermissions) { + String name = permission.getName(); + if (!perms.contains(name)) { + perms.add(name); + + if (includeChildren) { + Map children = getAllChildren(name, new HashSet()); + if (children != null) { + for (String node : children.keySet()) + if (!perms.contains(node)) + perms.add(node); + } + } + } + + } + return perms; + } + + /** + * Returns a map of ALL child permissions registered with bukkit * null is empty * * @param node + * @param playerPermArray current list of perms to check against for negations * @return Map of child permissions */ - public Map getAllChildren(String node, List playerPermArray) { + public Map getAllChildren(String node, Set playerPermArray) { LinkedList stack = new LinkedList(); Map alreadyVisited = new HashMap(); @@ -273,7 +323,7 @@ public class BukkitPermissions { } /** - * Returns a map of the child permissions (1 node deep) as defined by the supplying plugin + * Returns a map of the child permissions (1 node deep) as registered with Bukkit. * null is empty * * @param node @@ -329,14 +379,14 @@ public class BukkitPermissions { @Override public void onPlayerJoin(PlayerJoinEvent event) { - player_join = true; + setPlayer_join(true); Player player = event.getPlayer(); // force GM to create the player if they are not already listed. if (plugin.getWorldsHolder().getWorldData(player.getWorld().getName()).getUser(player.getName()) != null) { - player_join = false; + //setPlayer_join(false); updatePermissions(event.getPlayer()); - } else - player_join = false; + } + setPlayer_join(false); } @Override diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/PermissionsReaderInterface.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/PermissionsReaderInterface.java index cf11bd37f..3f49757e2 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/PermissionsReaderInterface.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/PermissionsReaderInterface.java @@ -4,6 +4,7 @@ package org.anjocaido.groupmanager.permissions; //import java.util.Map; //import java.util.Set; import java.util.List; +import java.util.Set; import org.anjocaido.groupmanager.data.Group; //import org.anjocaido.groupmanager.data.User; @@ -235,5 +236,5 @@ public abstract class PermissionsReaderInterface { public abstract List getAllPlayersPermissions(String userName); - public abstract List getAllPlayersPermissions(String userName, Boolean includeChildren); + public abstract Set getAllPlayersPermissions(String userName, Boolean includeChildren); }