Better optimize assembling of a players permissions and allow the * node

to populate all registered superperms.
This commit is contained in:
ElgarL 2012-01-18 16:39:12 +00:00
parent 64af5b465d
commit 9c052b5178
6 changed files with 153 additions and 79 deletions

View File

@ -104,4 +104,5 @@ v 1.8:
- Removed '- bukkit.command' form the globalgroups permission nodes. - Removed '- bukkit.command' form the globalgroups permission nodes.
v 1.9: v 1.9:
- Optimize populating Bukkit perms so we no longer calculate the child nodes (Bukkit already does this). - 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. - 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.

View File

@ -18,7 +18,7 @@ public class BukkitPermsUpdateTask implements Runnable {
public void run() { public void run() {
// Signal loaded and update BukkitPermissions. // Signal loaded and update BukkitPermissions.
GroupManager.setLoaded(true); GroupManager.setLoaded(true);
//GroupManager.BukkitPermissions.collectPermissions(); GroupManager.BukkitPermissions.collectPermissions();
GroupManager.BukkitPermissions.updateAllPlayers(); GroupManager.BukkitPermissions.updateAllPlayers();
GroupManager.logger.info("Bukkit Permissions Updated!"); GroupManager.logger.info("Bukkit Permissions Updated!");

View File

@ -113,7 +113,7 @@ public class User extends DataUnit implements Cloneable {
this.group = group; this.group = group;
flagAsChanged(); flagAsChanged();
if (GroupManager.isLoaded()) if (GroupManager.isLoaded())
if (GroupManager.BukkitPermissions.player_join = false) if (!GroupManager.BukkitPermissions.isPlayer_join())
GroupManager.BukkitPermissions.updateAllPlayers(); GroupManager.BukkitPermissions.updateAllPlayers();
} }
@ -130,7 +130,7 @@ public class User extends DataUnit implements Cloneable {
this.group = group.getName(); this.group = group.getName();
flagAsChanged(); flagAsChanged();
if (GroupManager.isLoaded()) { if (GroupManager.isLoaded()) {
if (GroupManager.BukkitPermissions.player_join = false) if (!GroupManager.BukkitPermissions.isPlayer_join())
GroupManager.BukkitPermissions.updateAllPlayers(); GroupManager.BukkitPermissions.updateAllPlayers();
// Do we notify of the group change? // Do we notify of the group change?
@ -159,7 +159,7 @@ public class User extends DataUnit implements Cloneable {
subGroups.add(subGroup.getName()); subGroups.add(subGroup.getName());
flagAsChanged(); flagAsChanged();
if (GroupManager.isLoaded()) { if (GroupManager.isLoaded()) {
if (GroupManager.BukkitPermissions.player_join = false) if (!GroupManager.BukkitPermissions.isPlayer_join())
GroupManager.BukkitPermissions.updateAllPlayers(); GroupManager.BukkitPermissions.updateAllPlayers();
GroupManagerEventHandler.callEvent(this, Action.USER_SUBGROUP_CHANGED); GroupManagerEventHandler.callEvent(this, Action.USER_SUBGROUP_CHANGED);
} }
@ -182,7 +182,7 @@ public class User extends DataUnit implements Cloneable {
if (subGroups.remove(subGroup.getName())) { if (subGroups.remove(subGroup.getName())) {
flagAsChanged(); flagAsChanged();
if (GroupManager.isLoaded()) if (GroupManager.isLoaded())
if (GroupManager.BukkitPermissions.player_join = false) if (!GroupManager.BukkitPermissions.isPlayer_join())
GroupManager.BukkitPermissions.updateAllPlayers(); GroupManager.BukkitPermissions.updateAllPlayers();
GroupManagerEventHandler.callEvent(this, Action.USER_SUBGROUP_CHANGED); GroupManagerEventHandler.callEvent(this, Action.USER_SUBGROUP_CHANGED);
return true; return true;
@ -229,7 +229,7 @@ public class User extends DataUnit implements Cloneable {
} }
flagAsChanged(); flagAsChanged();
if (GroupManager.isLoaded()) { if (GroupManager.isLoaded()) {
if (GroupManager.BukkitPermissions.player_join = false) if (!GroupManager.BukkitPermissions.isPlayer_join())
GroupManager.BukkitPermissions.updateAllPlayers(); GroupManager.BukkitPermissions.updateAllPlayers();
GroupManagerEventHandler.callEvent(this, Action.USER_INFO_CHANGED); GroupManagerEventHandler.callEvent(this, Action.USER_INFO_CHANGED);
} }

View File

@ -5,9 +5,11 @@
package org.anjocaido.groupmanager.permissions; package org.anjocaido.groupmanager.permissions;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.anjocaido.groupmanager.GroupManager; import org.anjocaido.groupmanager.GroupManager;
import org.anjocaido.groupmanager.data.Group; import org.anjocaido.groupmanager.data.Group;
@ -97,81 +99,101 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface {
*/ */
@Override @Override
public List<String> getAllPlayersPermissions(String userName) { public List<String> getAllPlayersPermissions(String userName) {
return getAllPlayersPermissions(userName, true); List<String> perms = new ArrayList<String>();
perms.addAll(getAllPlayersPermissions(userName, true));
return perms;
} }
/** /**
* Returns All permissions (including inheritance and sub groups) for the * Returns All permissions (including inheritance and sub groups) for the
* player. With or without Bukkit child nodes. * player. With or without Bukkit child nodes.
* *
* @param userName * @param userName
* @return List<String> of all players permissions. * @return Set<String> of all players permissions.
*/ */
@Override @Override
public List<String> getAllPlayersPermissions(String userName, Boolean includeChildren) { public Set<String> getAllPlayersPermissions(String userName, Boolean includeChildren) {
List<String> playerPermArray = new ArrayList<String>(); Set<String> playerPermArray = new HashSet<String>();
for (String perm : ph.getUser(userName).getPermissionList()) { // Add the players own permissions.
if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) { playerPermArray.addAll(populatePerms(ph.getUser(userName).getPermissionList(), includeChildren));
playerPermArray.add(perm);
// fetch all group permissions
if (includeChildren) {
Map<String, Boolean> 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);
}
}
}
}
}
}
for (String group : getGroups(userName)) { for (String group : getGroups(userName)) {
Set<String> groupPermArray = new HashSet<String>();
if (group.startsWith("g:") && GroupManager.getGlobalGroups().hasGroup(group)) { if (group.startsWith("g:") && GroupManager.getGlobalGroups().hasGroup(group)) {
for (String perm : GroupManager.getGlobalGroups().getGroupsPermissions(group)) { // GlobalGroups
if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) { groupPermArray = populatePerms(GroupManager.getGlobalGroups().getGroupsPermissions(group), includeChildren);
playerPermArray.add(perm);
if (includeChildren) {
Map<String, Boolean> 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);
}
}
}
}
}
} else { } else {
for (String perm : ph.getGroup(group).getPermissionList()) { // World Groups
if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) { groupPermArray = populatePerms(ph.getGroup(group).getPermissionList(), includeChildren);
playerPermArray.add(perm);
if (includeChildren) {
Map<String, Boolean> 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 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, // Collections.sort(playerPermArray,
// StringPermissionComparator.getInstance()); // StringPermissionComparator.getInstance());
return playerPermArray; return playerPermArray;
} }
private Set<String> populatePerms (List<String> perms, boolean includeChildren) {
Set<String> permArray = new HashSet<String>();
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<String, Boolean> children = GroupManager.BukkitPermissions.getAllChildren((negated ? perm.substring(1) : perm), new HashSet<String>());
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. * Verify if player is in such group. It will check it's groups inheritance.

View File

@ -19,9 +19,11 @@ package org.anjocaido.groupmanager.permissions;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.anjocaido.groupmanager.GroupManager; import org.anjocaido.groupmanager.GroupManager;
//import org.anjocaido.groupmanager.data.User; //import org.anjocaido.groupmanager.data.User;
@ -61,8 +63,22 @@ public class BukkitPermissions {
protected GroupManager plugin; protected GroupManager plugin;
protected boolean dumpAllPermissions = true; protected boolean dumpAllPermissions = true;
protected boolean dumpMatchedPermissions = 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; private static Field permissions;
// Setup reflection (Thanks to Codename_B for the reflection source) // 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) // Add all permissions for this player (GM only)
// child nodes will be calculated by Bukkit. // child nodes will be calculated by Bukkit.
List<String> playerPermArray = worldData.getPermissionsHandler().getAllPlayersPermissions(player.getName(), false); Set<String> playerPermArray = worldData.getPermissionsHandler().getAllPlayersPermissions(player.getName(), false);
Map<String, Boolean> newPerms = new HashMap<String, Boolean>(); Map<String, Boolean> newPerms = new HashMap<String, Boolean>();
for (String permission : playerPermArray) { //Set<String> hash = new HashSet<String>();
value = true; //for (String permission : playerPermArray)
if (permission.startsWith("-")) { // hash.add(permission);
permission = permission.substring(1); // cut off -
value = false;
} for (String permission : playerPermArray) {
value = (!permission.startsWith("-"));
/* /*
if (!attachment.getPermissions().containsKey(permission)) { if (!attachment.getPermissions().containsKey(permission)) {
attachment.setPermission(permission, value); attachment.setPermission(permission, value);
} }
*/ */
newPerms.put(permission, value); System.out.print("Permission: " + permission);
newPerms.put((value? permission : permission.substring(1)), value);
} }
//player.recalculatePermissions(); //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<String> getAllRegisteredPermissions(boolean includeChildren) {
List<String> perms = new ArrayList<String>();
for (Permission permission : registeredPermissions) {
String name = permission.getName();
if (!perms.contains(name)) {
perms.add(name);
if (includeChildren) {
Map<String, Boolean> children = getAllChildren(name, new HashSet<String>());
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 * null is empty
* *
* @param node * @param node
* @param playerPermArray current list of perms to check against for negations
* @return Map of child permissions * @return Map of child permissions
*/ */
public Map<String, Boolean> getAllChildren(String node, List<String> playerPermArray) { public Map<String, Boolean> getAllChildren(String node, Set<String> playerPermArray) {
LinkedList<String> stack = new LinkedList<String>(); LinkedList<String> stack = new LinkedList<String>();
Map<String, Boolean> alreadyVisited = new HashMap<String, Boolean>(); Map<String, Boolean> alreadyVisited = new HashMap<String, Boolean>();
@ -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 * null is empty
* *
* @param node * @param node
@ -329,14 +379,14 @@ public class BukkitPermissions {
@Override @Override
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
player_join = true; setPlayer_join(true);
Player player = event.getPlayer(); Player player = event.getPlayer();
// force GM to create the player if they are not already listed. // force GM to create the player if they are not already listed.
if (plugin.getWorldsHolder().getWorldData(player.getWorld().getName()).getUser(player.getName()) != null) { if (plugin.getWorldsHolder().getWorldData(player.getWorld().getName()).getUser(player.getName()) != null) {
player_join = false; //setPlayer_join(false);
updatePermissions(event.getPlayer()); updatePermissions(event.getPlayer());
} else }
player_join = false; setPlayer_join(false);
} }
@Override @Override

View File

@ -4,6 +4,7 @@ package org.anjocaido.groupmanager.permissions;
//import java.util.Map; //import java.util.Map;
//import java.util.Set; //import java.util.Set;
import java.util.List; import java.util.List;
import java.util.Set;
import org.anjocaido.groupmanager.data.Group; import org.anjocaido.groupmanager.data.Group;
//import org.anjocaido.groupmanager.data.User; //import org.anjocaido.groupmanager.data.User;
@ -235,5 +236,5 @@ public abstract class PermissionsReaderInterface {
public abstract List<String> getAllPlayersPermissions(String userName); public abstract List<String> getAllPlayersPermissions(String userName);
public abstract List<String> getAllPlayersPermissions(String userName, Boolean includeChildren); public abstract Set<String> getAllPlayersPermissions(String userName, Boolean includeChildren);
} }