From d882d5c2f97433db404049262f845f060eb3d985 Mon Sep 17 00:00:00 2001 From: 502647092 Date: Tue, 1 Mar 2016 11:19:54 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=85=E7=90=86=E4=BB=A3=E7=A0=81...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 502647092 --- .../anjocaido/groupmanager/data/Group.java | 141 +- .../groupmanager/data/GroupVariables.java | 47 +- .../org/anjocaido/groupmanager/data/User.java | 411 ++-- .../groupmanager/data/UserVariables.java | 43 +- .../dataholder/WorldDataHolder.java | 1549 ++++++------ .../permissions/AnjoPermissionsHandler.java | 2155 ++++++++--------- .../permissions/BukkitPermissions.java | 475 ++-- 7 files changed, 2404 insertions(+), 2417 deletions(-) diff --git a/src/main/java/org/anjocaido/groupmanager/data/Group.java b/src/main/java/org/anjocaido/groupmanager/data/Group.java index 45431fa..6df5357 100644 --- a/src/main/java/org/anjocaido/groupmanager/data/Group.java +++ b/src/main/java/org/anjocaido/groupmanager/data/Group.java @@ -4,16 +4,17 @@ */ package org.anjocaido.groupmanager.data; -import org.anjocaido.groupmanager.GroupManager; -import org.anjocaido.groupmanager.dataholder.WorldDataHolder; -import org.anjocaido.groupmanager.events.GMGroupEvent.Action; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import org.anjocaido.groupmanager.GroupManager; +import org.anjocaido.groupmanager.dataholder.WorldDataHolder; +import org.anjocaido.groupmanager.events.GMGroupEvent.Action; + /** - * + * * @author gabrielcouto/ElgarL */ public class Group extends DataUnit implements Cloneable { @@ -29,47 +30,52 @@ public class Group extends DataUnit implements Cloneable { */ private GroupVariables variables = new GroupVariables(this); - /** - * Constructor for individual World Groups. - * - * @param name - */ - public Group(WorldDataHolder source, String name) { - - super(source, name); - } - /** * Constructor for Global Groups. - * + * * @param name */ - public Group(String name) { + public Group(final String name) { super(name); } /** - * @return the name + * Constructor for individual World Groups. + * + * @param name */ - public String getName() { + public Group(final WorldDataHolder source, final String name) { - return this.getUUID(); + super(source, name); } /** - * Is this a GlobalGroup - * - * @return true if this is a global group + * @param inherit + * the inherits to set */ - public boolean isGlobal() { + public void addInherits(final Group inherit) { - return (getDataSource() == null); + if (!isGlobal()) { + if (!this.getDataSource().groupExists(inherit.getName())) { + getDataSource().addGroup(inherit); + } + if (!inherits.contains(inherit.getName().toLowerCase())) { + final List clone = new ArrayList(inherits); + clone.add(inherit.getName().toLowerCase()); + inherits = Collections.unmodifiableList(clone); + } + flagAsChanged(); + if (GroupManager.isLoaded()) { + GroupManager.BukkitPermissions.updateAllPlayers(); + GroupManager.getGMEventHandler().callEvent(this, Action.GROUP_INHERITANCE_CHANGED); + } + } } /** * Clone this group - * + * * @return a clone of this group */ @Override @@ -84,33 +90,33 @@ public class Group extends DataUnit implements Cloneable { clone.inherits = this.getInherits().isEmpty() ? Collections.unmodifiableList(Collections. emptyList()) : Collections.unmodifiableList(new ArrayList(this.getInherits())); } - for (String perm : this.getPermissionList()) { + for (final String perm : this.getPermissionList()) { clone.addPermission(perm); } - clone.variables = ((GroupVariables) variables).clone(clone); + clone.variables = variables.clone(clone); // clone.flagAsChanged(); return clone; } /** * Use this to deliver a group from a different dataSource to another - * + * * @param dataSource * @return Null or Clone */ - public Group clone(WorldDataHolder dataSource) { + public Group clone(final WorldDataHolder dataSource) { if (dataSource.groupExists(this.getName())) { return null; } - Group clone = dataSource.createGroup(this.getName()); + final Group clone = dataSource.createGroup(this.getName()); // Don't add inheritance for GlobalGroups if (!isGlobal()) { clone.inherits = this.getInherits().isEmpty() ? Collections.unmodifiableList(Collections. emptyList()) : Collections.unmodifiableList(new ArrayList(this.getInherits())); } - for (String perm : this.getPermissionList()) { + for (final String perm : this.getPermissionList()) { clone.addPermission(perm); } clone.variables = variables.clone(clone); @@ -122,7 +128,7 @@ public class Group extends DataUnit implements Cloneable { * an unmodifiable list of inherits list * You can't manage the list by here * Lol... version 0.6 had a problem because this. - * + * * @return the inherits */ public List getInherits() { @@ -130,41 +136,11 @@ public class Group extends DataUnit implements Cloneable { } /** - * @param inherit - * the inherits to set + * @return the name */ - public void addInherits(Group inherit) { + public String getName() { - if (!isGlobal()) { - if (!this.getDataSource().groupExists(inherit.getName())) { - getDataSource().addGroup(inherit); - } - if (!inherits.contains(inherit.getName().toLowerCase())) { - List clone = new ArrayList(inherits); - clone.add(inherit.getName().toLowerCase()); - inherits = Collections.unmodifiableList(clone); - } - flagAsChanged(); - if (GroupManager.isLoaded()) { - GroupManager.BukkitPermissions.updateAllPlayers(); - GroupManager.getGMEventHandler().callEvent(this, Action.GROUP_INHERITANCE_CHANGED); - } - } - } - - public boolean removeInherits(String inherit) { - - if (!isGlobal()) { - if (this.inherits.contains(inherit.toLowerCase())) { - List clone = new ArrayList(inherits); - clone.remove(inherit.toLowerCase()); - inherits = Collections.unmodifiableList(clone); - flagAsChanged(); - GroupManager.getGMEventHandler().callEvent(this, Action.GROUP_INHERITANCE_CHANGED); - return true; - } - } - return false; + return this.getUUID(); } /** @@ -176,15 +152,40 @@ public class Group extends DataUnit implements Cloneable { } /** - * - * @param varList + * Is this a GlobalGroup + * + * @return true if this is a global group */ - public void setVariables(Map varList) { + public boolean isGlobal() { + + return (getDataSource() == null); + } + + public boolean removeInherits(final String inherit) { if (!isGlobal()) { - GroupVariables temp = new GroupVariables(this, varList); + if (this.inherits.contains(inherit.toLowerCase())) { + final List clone = new ArrayList(inherits); + clone.remove(inherit.toLowerCase()); + inherits = Collections.unmodifiableList(clone); + flagAsChanged(); + GroupManager.getGMEventHandler().callEvent(this, Action.GROUP_INHERITANCE_CHANGED); + return true; + } + } + return false; + } + + /** + * + * @param varList + */ + public void setVariables(final Map varList) { + + if (!isGlobal()) { + final GroupVariables temp = new GroupVariables(this, varList); variables.clearVars(); - for (String key : temp.getVarKeyList()) { + for (final String key : temp.getVarKeyList()) { variables.addVar(key, temp.getVarObject(key)); } flagAsChanged(); diff --git a/src/main/java/org/anjocaido/groupmanager/data/GroupVariables.java b/src/main/java/org/anjocaido/groupmanager/data/GroupVariables.java index c1dec99..21ecc7d 100644 --- a/src/main/java/org/anjocaido/groupmanager/data/GroupVariables.java +++ b/src/main/java/org/anjocaido/groupmanager/data/GroupVariables.java @@ -7,15 +7,14 @@ package org.anjocaido.groupmanager.data; import java.util.Map; /** - * + * * @author gabrielcouto */ public class GroupVariables extends Variables implements Cloneable { - private Group owner; - - public GroupVariables(Group owner) { + private final Group owner; + public GroupVariables(final Group owner) { super(owner); this.owner = owner; addVar("prefix", ""); @@ -23,7 +22,7 @@ public class GroupVariables extends Variables implements Cloneable { addVar("build", false); } - public GroupVariables(Group owner, Map varList) { + public GroupVariables(final Group owner, final Map varList) { super(owner); variables.clear(); @@ -48,33 +47,25 @@ public class GroupVariables extends Variables implements Cloneable { } /** - * A clone of all vars here. - * - * @return GroupVariables clone + * @return the owner */ - protected GroupVariables clone(Group newOwner) { + @Override + public Group getOwner() { - GroupVariables clone = new GroupVariables(newOwner); - synchronized (variables) { - for (String key : variables.keySet()) { - clone.variables.put(key, variables.get(key)); - } - } - newOwner.flagAsChanged(); - return clone; + return owner; } /** * Remove a var from the list - * + * * @param name */ @Override - public void removeVar(String name) { + public void removeVar(final String name) { try { this.variables.remove(name); - } catch (Exception e) { + } catch (final Exception e) { } if (name.equals("prefix")) { addVar("prefix", ""); @@ -87,11 +78,19 @@ public class GroupVariables extends Variables implements Cloneable { } /** - * @return the owner + * A clone of all vars here. + * + * @return GroupVariables clone */ - @Override - public Group getOwner() { + protected GroupVariables clone(final Group newOwner) { - return owner; + final GroupVariables clone = new GroupVariables(newOwner); + synchronized (variables) { + for (final String key : variables.keySet()) { + clone.variables.put(key, variables.get(key)); + } + } + newOwner.flagAsChanged(); + return clone; } } diff --git a/src/main/java/org/anjocaido/groupmanager/data/User.java b/src/main/java/org/anjocaido/groupmanager/data/User.java index c971ee6..6e48086 100644 --- a/src/main/java/org/anjocaido/groupmanager/data/User.java +++ b/src/main/java/org/anjocaido/groupmanager/data/User.java @@ -8,23 +8,20 @@ package org.anjocaido.groupmanager.data; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import org.anjocaido.groupmanager.GroupManager; import org.anjocaido.groupmanager.dataholder.WorldDataHolder; import org.anjocaido.groupmanager.events.GMUserEvent.Action; -import java.util.Map; import org.bukkit.Bukkit; import org.bukkit.entity.Player; /** - * + * * @author gabrielcouto/ElgarL */ public class User extends DataUnit implements Cloneable { - /** - * - */ private String group = null; private final List subGroups = Collections.synchronizedList(new ArrayList()); /** @@ -35,170 +32,16 @@ public class User extends DataUnit implements Cloneable { private transient Player bukkitPlayer = null; /** - * + * * @param name */ - public User(WorldDataHolder source, String name) { + public User(final WorldDataHolder source, final String name) { super(source, name); this.group = source.getDefaultGroup().getName(); } - /** - * - * @return User clone - */ - @Override - public User clone() { - - User clone = new User(getDataSource(), this.getLastName()); - clone.group = this.group; - - // Clone all subgroups. - clone.subGroups.addAll(this.subGroupListStringCopy()); - - for (String perm : this.getPermissionList()) { - clone.addPermission(perm); - } - // clone.variables = this.variables.clone(); - // clone.flagAsChanged(); - return clone; - } - - /** - * Use this to deliver a user from one WorldDataHolder to another - * - * @param dataSource - * @return null if given dataSource already contains the same user - */ - public User clone(WorldDataHolder dataSource) { - - if (dataSource.isUserDeclared(this.getUUID())) { - return null; - } - - User clone = dataSource.createUser(this.getUUID()); - - if (dataSource.getGroup(group) == null) { - clone.setGroup(dataSource.getDefaultGroup()); - } else { - clone.setGroup(dataSource.getGroup(this.getGroupName())); - } - - // Clone all subgroups. - clone.subGroups.addAll(this.subGroupListStringCopy()); - - for (String perm : this.getPermissionList()) { - clone.addPermission(perm); - } - - clone.variables = this.variables.clone(this); - clone.flagAsChanged(); - return clone; - } - - public User clone(String uUID, String CurrentName) { - - User clone = this.getDataSource().createUser(uUID); - - clone.setLastName(CurrentName); - - // Set the group silently. - clone.setGroup(this.getDataSource().getGroup(this.getGroupName()), false); - - // Clone all subgroups. - clone.subGroups.addAll(this.subGroupListStringCopy()); - - for (String perm : this.getPermissionList()) { - clone.addPermission(perm); - } - - clone.variables = this.variables.clone(this); - clone.flagAsChanged(); - - return clone; - } - - public Group getGroup() { - - Group result = getDataSource().getGroup(group); - if (result == null) { - this.setGroup(getDataSource().getDefaultGroup()); - result = getDataSource().getDefaultGroup(); - } - return result; - } - - /** - * @return the group - */ - public String getGroupName() { - - Group result = getDataSource().getGroup(group); - if (result == null) { - group = getDataSource().getDefaultGroup().getName(); - } - return group; - } - - /** - * Place holder to let people know to stop using this method. - * - * @deprecated use {@link #getLastName()} and {@link #getUUID()}. - * @return a string containing the players last known name. - */ - @Deprecated - public String getName() { - - return this.getLastName(); - - } - - /** - * @param group - * the group to set - */ - public void setGroup(Group group) { - - setGroup(group, true); - } - - /** - * @param group - * the group to set - * @param updatePerms - * if we are to trigger a superperms update. - * - */ - public void setGroup(Group group, Boolean updatePerms) { - - if (!this.getDataSource().groupExists(group.getName())) { - getDataSource().addGroup(group); - } - group = getDataSource().getGroup(group.getName()); - String oldGroup = this.group; - this.group = group.getName(); - flagAsChanged(); - if (GroupManager.isLoaded()) { - if (!GroupManager.BukkitPermissions.isPlayer_join() && (updatePerms)) - GroupManager.BukkitPermissions.updatePlayer(getBukkitPlayer()); - - // Do we notify of the group change? - String defaultGroupName = getDataSource().getDefaultGroup().getName(); - // if we were not in the default group - // or we were in the default group and the move is to a different - // group. - boolean notify = (!oldGroup.equalsIgnoreCase(defaultGroupName)) || ((oldGroup.equalsIgnoreCase(defaultGroupName)) && (!this.group.equalsIgnoreCase(defaultGroupName))); - - if (notify) - GroupManager.notify(this.getLastName(), String.format(" moved to the group %s in %s.", group.getName(), this.getDataSource().getName())); - - if (updatePerms) - GroupManager.getGMEventHandler().callEvent(this, Action.USER_GROUP_CHANGED); - } - } - - public boolean addSubGroup(Group subGroup) { + public boolean addSubGroup(final Group subGroup) { // Don't allow adding a subgroup if it's already set as the primary. if (this.group.equalsIgnoreCase(subGroup.getName())) { @@ -227,9 +70,135 @@ public class User extends DataUnit implements Cloneable { // subGroups.add(subGroup.getName()); } - public int subGroupsSize() { + /** + * + * @return User clone + */ + @Override + public User clone() { - return subGroups.size(); + final User clone = new User(getDataSource(), this.getLastName()); + clone.group = this.group; + + // Clone all subgroups. + clone.subGroups.addAll(this.subGroupListStringCopy()); + + for (final String perm : this.getPermissionList()) { + clone.addPermission(perm); + } + // clone.variables = this.variables.clone(); + // clone.flagAsChanged(); + return clone; + } + + public User clone(final String uUID, final String CurrentName) { + + final User clone = this.getDataSource().createUser(uUID); + + clone.setLastName(CurrentName); + + // Set the group silently. + clone.setGroup(this.getDataSource().getGroup(this.getGroupName()), false); + + // Clone all subgroups. + clone.subGroups.addAll(this.subGroupListStringCopy()); + + for (final String perm : this.getPermissionList()) { + clone.addPermission(perm); + } + + clone.variables = this.variables.clone(this); + clone.flagAsChanged(); + + return clone; + } + + /** + * Use this to deliver a user from one WorldDataHolder to another + * + * @param dataSource + * @return null if given dataSource already contains the same user + */ + public User clone(final WorldDataHolder dataSource) { + + if (dataSource.isUserDeclared(this.getUUID())) { + return null; + } + + final User clone = dataSource.createUser(this.getUUID()); + + if (dataSource.getGroup(group) == null) { + clone.setGroup(dataSource.getDefaultGroup()); + } else { + clone.setGroup(dataSource.getGroup(this.getGroupName())); + } + + // Clone all subgroups. + clone.subGroups.addAll(this.subGroupListStringCopy()); + + for (final String perm : this.getPermissionList()) { + clone.addPermission(perm); + } + + clone.variables = this.variables.clone(this); + clone.flagAsChanged(); + return clone; + } + + public boolean containsSubGroup(final Group subGroup) { + + return subGroups.contains(subGroup.getName()); + } + + public Player getBukkitPlayer() { + + if (bukkitPlayer == null) { + bukkitPlayer = Bukkit.getPlayer(this.getLastName()); + } + return bukkitPlayer; + } + + public Group getGroup() { + + Group result = getDataSource().getGroup(group); + if (result == null) { + this.setGroup(getDataSource().getDefaultGroup()); + result = getDataSource().getDefaultGroup(); + } + return result; + } + + /** + * @return the group + */ + public String getGroupName() { + + final Group result = getDataSource().getGroup(group); + if (result == null) { + group = getDataSource().getDefaultGroup().getName(); + } + return group; + } + + /** + * Place holder to let people know to stop using this method. + * + * @deprecated use {@link #getLastName()} and {@link #getUUID()}. + * @return a string containing the players last known name. + */ + @Deprecated + public String getName() { + + return this.getLastName(); + + } + + /** + * @return the variables + */ + public UserVariables getVariables() { + + return variables; } public boolean isSubGroupsEmpty() { @@ -237,12 +206,7 @@ public class User extends DataUnit implements Cloneable { return subGroups.isEmpty(); } - public boolean containsSubGroup(Group subGroup) { - - return subGroups.contains(subGroup.getName()); - } - - public boolean removeSubGroup(Group subGroup) { + public boolean removeSubGroup(final Group subGroup) { try { if (subGroups.remove(subGroup.getName())) { @@ -253,17 +217,80 @@ public class User extends DataUnit implements Cloneable { GroupManager.getGMEventHandler().callEvent(this, Action.USER_SUBGROUP_CHANGED); return true; } - } catch (Exception e) { + } catch (final Exception e) { } return false; } + /** + * @param group + * the group to set + */ + public void setGroup(final Group group) { + + setGroup(group, true); + } + + /** + * @param group + * the group to set + * @param updatePerms + * if we are to trigger a superperms update. + * + */ + public void setGroup(Group group, final Boolean updatePerms) { + + if (!this.getDataSource().groupExists(group.getName())) { + getDataSource().addGroup(group); + } + group = getDataSource().getGroup(group.getName()); + final String oldGroup = this.group; + this.group = group.getName(); + flagAsChanged(); + if (GroupManager.isLoaded()) { + if (!GroupManager.BukkitPermissions.isPlayer_join() && (updatePerms)) + GroupManager.BukkitPermissions.updatePlayer(getBukkitPlayer()); + + // Do we notify of the group change? + final String defaultGroupName = getDataSource().getDefaultGroup().getName(); + // if we were not in the default group + // or we were in the default group and the move is to a different + // group. + final boolean notify = (!oldGroup.equalsIgnoreCase(defaultGroupName)) || ((oldGroup.equalsIgnoreCase(defaultGroupName)) && (!this.group.equalsIgnoreCase(defaultGroupName))); + + if (notify) + GroupManager.notify(this.getLastName(), String.format(" moved to the group %s in %s.", group.getName(), this.getDataSource().getName())); + + if (updatePerms) + GroupManager.getGMEventHandler().callEvent(this, Action.USER_GROUP_CHANGED); + } + } + + /** + * + * @param varList + */ + public void setVariables(final Map varList) { + + // UserVariables temp = new UserVariables(this, varList); + variables.clearVars(); + for (final String key : varList.keySet()) { + variables.addVar(key, varList.get(key)); + } + flagAsChanged(); + if (GroupManager.isLoaded()) { + // if (!GroupManager.BukkitPermissions.isPlayer_join()) + // GroupManager.BukkitPermissions.updatePlayer(this.getName()); + GroupManager.getGMEventHandler().callEvent(this, Action.USER_INFO_CHANGED); + } + } + public ArrayList subGroupListCopy() { - ArrayList val = new ArrayList(); + final ArrayList val = new ArrayList(); synchronized (subGroups) { - for (String gstr : subGroups) { - Group g = getDataSource().getGroup(gstr); + for (final String gstr : subGroups) { + final Group g = getDataSource().getGroup(gstr); if (g == null) { removeSubGroup(g); continue; @@ -280,44 +307,14 @@ public class User extends DataUnit implements Cloneable { } } - /** - * @return the variables - */ - public UserVariables getVariables() { + public int subGroupsSize() { - return variables; + return subGroups.size(); } - /** - * - * @param varList - */ - public void setVariables(Map varList) { - - // UserVariables temp = new UserVariables(this, varList); - variables.clearVars(); - for (String key : varList.keySet()) { - variables.addVar(key, varList.get(key)); - } - flagAsChanged(); - if (GroupManager.isLoaded()) { - // if (!GroupManager.BukkitPermissions.isPlayer_join()) - // GroupManager.BukkitPermissions.updatePlayer(this.getName()); - GroupManager.getGMEventHandler().callEvent(this, Action.USER_INFO_CHANGED); - } - } - - public User updatePlayer(Player player) { + public User updatePlayer(final Player player) { bukkitPlayer = player; return this; } - - public Player getBukkitPlayer() { - - if (bukkitPlayer == null) { - bukkitPlayer = Bukkit.getPlayer(this.getLastName()); - } - return bukkitPlayer; - } } diff --git a/src/main/java/org/anjocaido/groupmanager/data/UserVariables.java b/src/main/java/org/anjocaido/groupmanager/data/UserVariables.java index acab10e..43ce5b6 100644 --- a/src/main/java/org/anjocaido/groupmanager/data/UserVariables.java +++ b/src/main/java/org/anjocaido/groupmanager/data/UserVariables.java @@ -7,44 +7,26 @@ package org.anjocaido.groupmanager.data; import java.util.Map; /** - * + * * @author gabrielcouto */ public class UserVariables extends Variables { - private User owner; + private final User owner; - public UserVariables(User owner) { + public UserVariables(final User owner) { super(owner); this.owner = owner; } - public UserVariables(User owner, Map varList) { - + public UserVariables(final User owner, final Map varList) { super(owner); this.variables.clear(); this.variables.putAll(varList); this.owner = owner; } - /** - * A clone of all vars here. - * - * @return UserVariables clone - */ - protected UserVariables clone(User newOwner) { - - UserVariables clone = new UserVariables(newOwner); - synchronized (variables) { - for (String key : variables.keySet()) { - clone.variables.put(key, variables.get(key)); - } - } - newOwner.flagAsChanged(); - return clone; - } - /** * @return the owner */ @@ -53,4 +35,21 @@ public class UserVariables extends Variables { return owner; } + + /** + * A clone of all vars here. + * + * @return UserVariables clone + */ + protected UserVariables clone(final User newOwner) { + + final UserVariables clone = new UserVariables(newOwner); + synchronized (variables) { + for (final String key : variables.keySet()) { + clone.variables.put(key, variables.get(key)); + } + } + newOwner.flagAsChanged(); + return clone; + } } diff --git a/src/main/java/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java b/src/main/java/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java index c7dc0f2..0a9b52f 100644 --- a/src/main/java/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java +++ b/src/main/java/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; + import org.anjocaido.groupmanager.GroupManager; import org.anjocaido.groupmanager.data.Group; import org.anjocaido.groupmanager.data.User; @@ -41,7 +42,7 @@ import org.yaml.snakeyaml.reader.UnicodeReader; * One instance of this should exist per world/mirror it contains all functions * to manage these data sets and points to the relevant users and groups * objects. - * + * * @author gabrielcouto, ElgarL */ public class WorldDataHolder { @@ -65,22 +66,22 @@ public class WorldDataHolder { /** * Prevent direct instantiation - * + * * @param worldName */ - public WorldDataHolder(String worldName) { + public WorldDataHolder(final String worldName) { name = worldName; } /** * The main constructor for a new WorldDataHolder - * + * * @param worldName * @param groups * @param users */ - public WorldDataHolder(String worldName, GroupsDataHolder groups, UsersDataHolder users) { + public WorldDataHolder(final String worldName, final GroupsDataHolder groups, final UsersDataHolder users) { this.name = worldName; this.groups = groups; @@ -89,442 +90,19 @@ public class WorldDataHolder { // this.defaultGroup = defaultGroup; } - /** - * update the dataSource to point to this object. - * - * This should be called whenever a set of world data is fetched. - */ - public void updateDataSource() { - - this.groups.setDataSource(this); - this.users.setDataSource(this); - } - - /** - * Search for a user. If it doesn't exist, create a new one with default - * group. - * - * @param userId - * the UUID String or name of the user - * @return class that manage that user permission - */ - public User getUser(String userId) { - - if (getUsers().containsKey(userId.toLowerCase())) { - return getUsers().get(userId.toLowerCase()); - } - - // Legacy name matching - if (userId.length() < 36) { - - // Search for a LastName match - for (User user : getUserList()) { - - if (user.getLastName().equalsIgnoreCase(userId)) { - return user; - } - } - - } - - // No user account found so create a new one. - User newUser = createUser(userId); - - return newUser; - } - - /** - * *** Internal GM use only *** - * This is called when a player joins to update/add their UUID. - * - * @param uUID - * the player objects UUID. - * @param currentName - * the name they have just logged in with. - * @return the user object for this player. - */ - public User getUser(String uUID, String currentName) { - - // Check for a UUID account - User user = getUsers().get(uUID.toLowerCase()); - - if (user != null) { - - user.setLastName(currentName); - return user; - - } - - // Search for a LastName match - for (User usr : getUserList()) { - - if (usr.getLastName().equalsIgnoreCase(currentName) && usr.getUUID().equalsIgnoreCase(usr.getLastName())) { - - // Clone this user so we can set it's uUID - user = usr.clone(uUID, currentName); - - // Delete it and replace with the new clone. - this.removeUser(usr.getUUID()); - this.addUser(user); - - return getUsers().get(uUID.toLowerCase()); - } - - } - - // No user account found so create a new one. - User newUser = createUser(uUID); - newUser.setLastName(currentName); - - return newUser; - } - - /** - * Add a user to the list. If it already exists, overwrite the old. - * - * @param theUser - * the user you want to add to the permission list - */ - public void addUser(User theUser) { - - if (theUser.getDataSource() != this) { - theUser = theUser.clone(this); - } - if (theUser == null) { - return; - } - if ((theUser.getGroup() == null)) { - theUser.setGroup(groups.getDefaultGroup()); - } - removeUser(theUser.getUUID()); - getUsers().put(theUser.getUUID().toLowerCase(), theUser); - setUsersChanged(true); - if (GroupManager.isLoaded()) - GroupManager.getGMEventHandler().callEvent(theUser, Action.USER_ADDED); - } - - /** - * Removes the user from the list. (he might become a default user) - * - * @param userId - * the UUID or username for the user to remove - * @return true if it had something to remove - */ - public boolean removeUser(String userId) { - - if (getUsers().containsKey(userId.toLowerCase())) { - getUsers().remove(userId.toLowerCase()); - setUsersChanged(true); - if (GroupManager.isLoaded()) - GroupManager.getGMEventHandler().callEvent(userId, GMUserEvent.Action.USER_REMOVED); - return true; - } - return false; - } - - /** - * - * @param userId - * @return true if we have data for this player. - */ - public boolean isUserDeclared(String userId) { - - return getUsers().containsKey(userId.toLowerCase()); - } - - /** - * Change the default group of the file. - * - * @param group - * the group you want make default. - */ - public void setDefaultGroup(Group group) { - - if (!getGroups().containsKey(group.getName().toLowerCase()) || (group.getDataSource() != this)) { - addGroup(group); - } - groups.setDefaultGroup(getGroup(group.getName())); - setGroupsChanged(true); - if (GroupManager.isLoaded()) - GroupManager.getGMEventHandler().callEvent(GMSystemEvent.Action.DEFAULT_GROUP_CHANGED); - } - - /** - * Returns the default group of the file - * - * @return the default group - */ - public Group getDefaultGroup() { - - return groups.getDefaultGroup(); - } - - /** - * Returns a group of the given name - * - * @param groupName - * the name of the group - * @return a group if it is found. null if not found. - */ - public Group getGroup(String groupName) { - - if (groupName.toLowerCase().startsWith("g:")) - return GroupManager.getGlobalGroups().getGroup(groupName); - else - return getGroups().get(groupName.toLowerCase()); - } - - /** - * Check if a group exists. Its the same of getGroup, but check if it is - * null. - * - * @param groupName - * the name of the group - * @return true if exists. false if not. - */ - public boolean groupExists(String groupName) { - - if (groupName.toLowerCase().startsWith("g:")) - return GroupManager.getGlobalGroups().hasGroup(groupName); - else - return getGroups().containsKey(groupName.toLowerCase()); - } - - /** - * Add a group to the list - * - * @param groupToAdd - */ - public void addGroup(Group groupToAdd) { - - if (groupToAdd.getName().toLowerCase().startsWith("g:")) { - GroupManager.getGlobalGroups().addGroup(groupToAdd); - GroupManager.getGMEventHandler().callEvent(groupToAdd, GMGroupEvent.Action.GROUP_ADDED); - return; - } - - if (groupToAdd.getDataSource() != this) { - groupToAdd = groupToAdd.clone(this); - } - removeGroup(groupToAdd.getName()); - getGroups().put(groupToAdd.getName().toLowerCase(), groupToAdd); - setGroupsChanged(true); - if (GroupManager.isLoaded()) - GroupManager.getGMEventHandler().callEvent(groupToAdd, GMGroupEvent.Action.GROUP_ADDED); - } - - /** - * Remove the group from the list - * - * @param groupName - * @return true if had something to remove. false the group was default or - * non-existant - */ - public boolean removeGroup(String groupName) { - - if (groupName.toLowerCase().startsWith("g:")) { - return GroupManager.getGlobalGroups().removeGroup(groupName); - } - - if (getDefaultGroup() != null && groupName.equalsIgnoreCase(getDefaultGroup().getName())) { - return false; - } - if (getGroups().containsKey(groupName.toLowerCase())) { - getGroups().remove(groupName.toLowerCase()); - setGroupsChanged(true); - if (GroupManager.isLoaded()) - GroupManager.getGMEventHandler().callEvent(groupName.toLowerCase(), GMGroupEvent.Action.GROUP_REMOVED); - return true; - } - return false; - - } - - /** - * Creates a new User with the given name and adds it to this holder. - * - * @param userId - * the UUID or username you want - * @return null if user already exists. or new User - */ - public User createUser(String userId) { - - if (getUsers().containsKey(userId.toLowerCase())) { - return null; - } - User newUser = new User(this, userId); - newUser.setGroup(groups.getDefaultGroup(), false); - addUser(newUser); - setUsersChanged(true); - return newUser; - } - - /** - * Creates a new Group with the given name and adds it to this holder - * - * @param groupName - * the groupname you want - * @return null if group already exists. or new Group - */ - public Group createGroup(String groupName) { - - if (groupName.toLowerCase().startsWith("g:")) { - Group newGroup = new Group(groupName); - return GroupManager.getGlobalGroups().newGroup(newGroup); - } - - if (getGroups().containsKey(groupName.toLowerCase())) { - return null; - } - - Group newGroup = new Group(this, groupName); - addGroup(newGroup); - setGroupsChanged(true); - return newGroup; - } - - /** - * - * @return a collection of the groups - */ - public Collection getGroupList() { - - synchronized (getGroups()) { - return new ArrayList(getGroups().values()); - } - } - - /** - * - * @return a collection of the users - */ - public Collection getUserList() { - - synchronized (getUsers()) { - return new ArrayList(getUsers().values()); - } - } - - /** - * reads the file again - */ - public void reload() { - - try { - reloadGroups(); - reloadUsers(); - } catch (Exception ex) { - Logger.getLogger(WorldDataHolder.class.getName()).log(Level.SEVERE, null, ex); - } - } - - /** - * Refresh Group data from file - */ - public void reloadGroups() { - - GroupManager.setLoaded(false); - try { - // temporary holder in case the load fails. - WorldDataHolder ph = new WorldDataHolder(this.getName()); - - loadGroups(ph, getGroupsFile()); - // transfer new data - resetGroups(); - for (Group tempGroup : ph.getGroupList()) { - tempGroup.clone(this); - } - this.setDefaultGroup(getGroup(ph.getDefaultGroup().getName())); - this.removeGroupsChangedFlag(); - this.setTimeStampGroups(getGroupsFile().lastModified()); - - ph = null; - } catch (Exception ex) { - Logger.getLogger(WorldDataHolder.class.getName()).log(Level.WARNING, null, ex); - } - GroupManager.setLoaded(true); - GroupManager.getGMEventHandler().callEvent(GMSystemEvent.Action.RELOADED); - } - - /** - * Refresh Users data from file - */ - public void reloadUsers() { - - GroupManager.setLoaded(false); - try { - // temporary holder in case the load fails. - WorldDataHolder ph = new WorldDataHolder(this.getName()); - // copy groups for reference - for (Group tempGroup : this.getGroupList()) { - tempGroup.clone(ph); - } - // setup the default group before loading user data. - ph.setDefaultGroup(ph.getGroup(getDefaultGroup().getName())); - loadUsers(ph, getUsersFile()); - // transfer new data - resetUsers(); - for (User tempUser : ph.getUserList()) { - tempUser.clone(this); - } - this.removeUsersChangedFlag(); - this.setTimeStampUsers(getUsersFile().lastModified()); - - ph = null; - } catch (Exception ex) { - Logger.getLogger(WorldDataHolder.class.getName()).log(Level.WARNING, null, ex); - } - GroupManager.setLoaded(true); - GroupManager.getGMEventHandler().callEvent(GMSystemEvent.Action.RELOADED); - } - - public void loadGroups(File groupsFile) { - - GroupManager.setLoaded(false); - try { - setGroupsFile(groupsFile); - loadGroups(this, groupsFile); - } catch (FileNotFoundException e) { - e.printStackTrace(); - throw new IllegalArgumentException("The file which should contain groups does not exist!\n" + groupsFile.getPath()); - } catch (IOException e) { - e.printStackTrace(); - throw new IllegalArgumentException("Error accessing the groups file!\n" + groupsFile.getPath()); - } - - GroupManager.setLoaded(true); - } - - public void loadUsers(File usersFile) { - - GroupManager.setLoaded(false); - try { - setUsersFile(usersFile); - loadUsers(this, usersFile); - } catch (FileNotFoundException e) { - e.printStackTrace(); - throw new IllegalArgumentException("The file which should contain users does not exist!\n" + usersFile.getPath()); - } catch (IOException e) { - e.printStackTrace(); - throw new IllegalArgumentException("Error accessing the users file!\n" + usersFile.getPath()); - } - - GroupManager.setLoaded(true); - } - /** * Returns a NEW data holder containing data read from the files - * + * * @param worldName * @param groupsFile * @param usersFile - * + * * @throws FileNotFoundException * @throws IOException */ - public static WorldDataHolder load(String worldName, File groupsFile, File usersFile) throws FileNotFoundException, IOException { + public static WorldDataHolder load(final String worldName, final File groupsFile, final File usersFile) throws FileNotFoundException, IOException { - WorldDataHolder ph = new WorldDataHolder(worldName); + final WorldDataHolder ph = new WorldDataHolder(worldName); GroupManager.setLoaded(false); if (groupsFile != null) @@ -537,32 +115,226 @@ public class WorldDataHolder { } /** - * Updates the WorldDataHolder from the Groups file - * + * Don't use this. Unless you want to make this plugin to interact with + * original Nijikokun Permissions This method is supposed to make the + * original one reload the file, and propagate the changes made here. + * + * Prefer to use the AnjoCaido's fake version of Nijikokun's Permission + * plugin. The AnjoCaido's Permission can propagate the changes made on this + * plugin instantly, without need to save the file. + * + * @param server + * the server that holds the plugin + * @deprecated it is not used anymore... unless if you use original + * Permissions + */ + @Deprecated + public static void reloadOldPlugins(final Server server) { + + // Only reload permissions + final PluginManager pm = server.getPluginManager(); + final Plugin[] plugins = pm.getPlugins(); + for (int i = 0; i < plugins.length; i++) { + // plugins[i].getConfiguration().load(); + try { + plugins[i].getClass().getMethod("setupPermissions").invoke(plugins[i]); + } catch (final Exception ex) { + continue; + } + } + } + + /** + * Write a dataHolder in a specified file + * * @param ph * @param groupsFile - * + */ + public static void writeGroups(final WorldDataHolder ph, final File groupsFile) { + + final Map root = new HashMap(); + + final Map groupsMap = new HashMap(); + + root.put("groups", groupsMap); + synchronized (ph.getGroups()) { + for (final String groupKey : ph.getGroups().keySet()) { + final Group group = ph.getGroups().get(groupKey); + + final Map aGroupMap = new HashMap(); + groupsMap.put(group.getName(), aGroupMap); + + if (ph.getDefaultGroup() == null) { + GroupManager.logger.severe("There is no default group for world: " + ph.getName()); + } + aGroupMap.put("default", group.equals(ph.getDefaultGroup())); + + final Map infoMap = new HashMap(); + aGroupMap.put("info", infoMap); + + for (final String infoKey : group.getVariables().getVarKeyList()) { + infoMap.put(infoKey, group.getVariables().getVarObject(infoKey)); + } + + aGroupMap.put("inheritance", group.getInherits()); + + aGroupMap.put("permissions", group.getPermissionList()); + } + } + + if (!root.isEmpty()) { + final DumperOptions opt = new DumperOptions(); + opt.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + final Yaml yaml = new Yaml(opt); + try { + final OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(groupsFile), "UTF-8"); + + final String newLine = System.getProperty("line.separator"); + + out.write("# Group inheritance" + newLine); + out.write("#" + newLine); + out.write("# Any inherited groups prefixed with a g: are global groups" + newLine); + out.write("# and are inherited from the GlobalGroups.yml." + newLine); + out.write("#" + newLine); + out.write("# Groups without the g: prefix are groups local to this world" + newLine); + out.write("# and are defined in the this groups.yml file." + newLine); + out.write("#" + newLine); + out.write("# Local group inheritances define your promotion tree when using 'manpromote/mandemote'" + newLine); + out.write(newLine); + + yaml.dump(root, out); + out.close(); + } catch (final UnsupportedEncodingException ex) { + } catch (final FileNotFoundException ex) { + } catch (final IOException e) { + } + } + + // Update the LastModified time. + ph.setGroupsFile(groupsFile); + ph.setTimeStampGroups(groupsFile.lastModified()); + ph.removeGroupsChangedFlag(); + + if (GroupManager.isLoaded()) + GroupManager.getGMEventHandler().callEvent(GMSystemEvent.Action.SAVED); + + /* + * FileWriter tx = null; try { tx = new FileWriter(groupsFile, false); + * tx.write(yaml.dump(root)); tx.flush(); } catch (Exception e) { } + * finally { try { tx.close(); } catch (IOException ex) { } } + */ + } + + /** + * Write a dataHolder in a specified file + * + * @param ph + * @param usersFile + */ + public static void writeUsers(final WorldDataHolder ph, final File usersFile) { + + final Map root = new HashMap(); + final LinkedHashMap usersMap = new LinkedHashMap(); + + root.put("users", usersMap); + synchronized (ph.getUsers()) { + + // A sorted list of users. + for (final String userKey : new TreeSet(ph.getUsers().keySet())) { + final User user = ph.getUsers().get(userKey); + if ((user.getGroup() == null || user.getGroup().equals(ph.getDefaultGroup())) && user.getPermissionList().isEmpty() && user.getVariables().isEmpty() && user.isSubGroupsEmpty()) { + continue; + } + + final LinkedHashMap aUserMap = new LinkedHashMap(); + usersMap.put(user.getUUID(), aUserMap); + + if (!user.getUUID().equalsIgnoreCase(user.getLastName())) { + aUserMap.put("lastname", user.getLastName()); + } + + // GROUP NODE + if (user.getGroup() == null) { + aUserMap.put("group", ph.getDefaultGroup().getName()); + } else { + aUserMap.put("group", user.getGroup().getName()); + } + + // SUBGROUPS NODE + aUserMap.put("subgroups", user.subGroupListStringCopy()); + + // PERMISSIONS NODE + aUserMap.put("permissions", user.getPermissionList()); + + // USER INFO NODE - BETA + if (user.getVariables().getSize() > 0) { + final Map infoMap = new HashMap(); + aUserMap.put("info", infoMap); + for (final String infoKey : user.getVariables().getVarKeyList()) { + infoMap.put(infoKey, user.getVariables().getVarObject(infoKey)); + } + } + // END USER INFO NODE - BETA + + } + } + + if (!root.isEmpty()) { + final DumperOptions opt = new DumperOptions(); + opt.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + final Yaml yaml = new Yaml(opt); + try { + final OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(usersFile), "UTF-8"); + yaml.dump(root, out); + out.close(); + } catch (final UnsupportedEncodingException ex) { + } catch (final FileNotFoundException ex) { + } catch (final IOException e) { + } + } + + // Update the LastModified time. + ph.setUsersFile(usersFile); + ph.setTimeStampUsers(usersFile.lastModified()); + ph.removeUsersChangedFlag(); + + if (GroupManager.isLoaded()) + GroupManager.getGMEventHandler().callEvent(GMSystemEvent.Action.SAVED); + + /* + * FileWriter tx = null; try { tx = new FileWriter(usersFile, false); + * tx.write(yaml.dump(root)); tx.flush(); } catch (Exception e) { } + * finally { try { tx.close(); } catch (IOException ex) { } } + */ + } + + /** + * Updates the WorldDataHolder from the Groups file + * + * @param ph + * @param groupsFile + * * @throws FileNotFoundException * @throws IOException */ @SuppressWarnings({ "rawtypes", "unchecked" }) - protected static void loadGroups(WorldDataHolder ph, File groupsFile) throws FileNotFoundException, IOException { + protected static void loadGroups(final WorldDataHolder ph, final File groupsFile) throws FileNotFoundException, IOException { // READ GROUPS FILE - Yaml yamlGroups = new Yaml(new SafeConstructor()); + final Yaml yamlGroups = new Yaml(new SafeConstructor()); Map groupsRootDataNode; if (!groupsFile.exists()) { throw new IllegalArgumentException("The file which should contain groups does not exist!\n" + groupsFile.getPath()); } - FileInputStream groupsInputStream = new FileInputStream(groupsFile); + final FileInputStream groupsInputStream = new FileInputStream(groupsFile); try { groupsRootDataNode = (Map) yamlGroups.load(new UnicodeReader(groupsInputStream)); if (groupsRootDataNode == null) { throw new NullPointerException(); } - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("The following file couldn't pass on Parser.\n" + groupsFile.getPath(), ex); } finally { groupsInputStream.close(); @@ -570,7 +342,7 @@ public class WorldDataHolder { // PROCESS GROUPS FILE - Map> inheritance = new HashMap>(); + final Map> inheritance = new HashMap>(); Map allGroupsNode = null; /* @@ -578,7 +350,7 @@ public class WorldDataHolder { */ try { allGroupsNode = (Map) groupsRootDataNode.get("groups"); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Your " + groupsFile.getPath() + " file is invalid. See console for details.", ex); } @@ -586,7 +358,7 @@ public class WorldDataHolder { throw new IllegalArgumentException("You have no groups in " + groupsFile.getPath() + "."); } - Iterator groupItr = allGroupsNode.keySet().iterator(); + final Iterator groupItr = allGroupsNode.keySet().iterator(); String groupKey; Integer groupCount = 0; @@ -599,7 +371,7 @@ public class WorldDataHolder { groupCount++; // Attempt to fetch the next group name. groupKey = groupItr.next(); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Invalid group name for group entry (" + groupCount + ") in file: " + groupsFile.getPath(), ex); } @@ -610,14 +382,14 @@ public class WorldDataHolder { try { thisGroupNode = (Map) allGroupsNode.get(groupKey); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Invalid child nodes for group '" + groupKey + "' in file: " + groupsFile.getPath(), ex); } /* * Create a new group with this name in the assigned data source. */ - Group thisGrp = ph.createGroup(groupKey); + final Group thisGrp = ph.createGroup(groupKey); if (thisGrp == null) { throw new IllegalArgumentException("I think this Group was declared more than once: " + groupKey + " in file: " + groupsFile.getPath()); @@ -628,7 +400,7 @@ public class WorldDataHolder { Object nodeData = null; try { nodeData = thisGroupNode.get("default"); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Bad format found in 'permissions' for group: " + groupKey + " in file: " + groupsFile.getPath()); } @@ -653,7 +425,7 @@ public class WorldDataHolder { nodeData = null; try { nodeData = thisGroupNode.get("permissions"); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Bad format found in 'permissions' for '" + groupKey + "' in file: " + groupsFile.getPath()); } @@ -670,7 +442,7 @@ public class WorldDataHolder { * Check each entry and add it as a new permission. */ try { - for (Object o : ((List) nodeData)) { + for (final Object o : ((List) nodeData)) { try { /* * Only add this permission if it's not empty. @@ -678,12 +450,12 @@ public class WorldDataHolder { if (!o.toString().isEmpty()) thisGrp.addPermission(o.toString()); - } catch (NullPointerException ex) { + } catch (final NullPointerException ex) { // Ignore this entry as it's null. It can be // safely dropped } } - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Invalid formatting found in 'permissions' section for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath(), ex); } @@ -709,7 +481,7 @@ public class WorldDataHolder { nodeData = null; try { nodeData = thisGroupNode.get("info"); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Bad format found in 'info' section for group: " + groupKey + " in file: " + groupsFile.getPath()); } @@ -726,7 +498,7 @@ public class WorldDataHolder { if (nodeData != null) { thisGrp.setVariables((Map) nodeData); } - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Invalid formatting found in 'info' section for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath(), ex); } @@ -738,7 +510,7 @@ public class WorldDataHolder { nodeData = null; try { nodeData = thisGroupNode.get("inheritance"); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Bad format found in 'inheritance' section for group: " + groupKey + " in file: " + groupsFile.getPath()); } @@ -751,14 +523,14 @@ public class WorldDataHolder { } else if (nodeData instanceof List) { try { - for (String grp : (List) nodeData) { + for (final String grp : (List) nodeData) { if (inheritance.get(groupKey) == null) { inheritance.put(groupKey, new ArrayList()); } inheritance.get(groupKey).add(grp); } - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Invalid formatting found in 'inheritance' section for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath(), ex); } @@ -777,13 +549,13 @@ public class WorldDataHolder { /* * Build the inheritance map and recored any errors */ - for (String group : inheritance.keySet()) { - List inheritedList = inheritance.get(group); - Group thisGroup = ph.getGroup(group); + for (final String group : inheritance.keySet()) { + final List inheritedList = inheritance.get(group); + final Group thisGroup = ph.getGroup(group); if (thisGroup != null) - for (String inheritedKey : inheritedList) { + for (final String inheritedKey : inheritedList) { if (inheritedKey != null) { - Group inheritedGroup = ph.getGroup(inheritedKey); + final Group inheritedGroup = ph.getGroup(inheritedKey); if (inheritedGroup != null) { thisGroup.addInherits(inheritedGroup); } else @@ -802,29 +574,29 @@ public class WorldDataHolder { /** * Updates the WorldDataHolder from the Users file - * + * * @param ph * @param usersFile - * + * * @throws FileNotFoundException * @throws IOException */ @SuppressWarnings({ "rawtypes", "unchecked" }) - protected static void loadUsers(WorldDataHolder ph, File usersFile) throws FileNotFoundException, IOException { + protected static void loadUsers(final WorldDataHolder ph, final File usersFile) throws FileNotFoundException, IOException { // READ USERS FILE - Yaml yamlUsers = new Yaml(new SafeConstructor()); + final Yaml yamlUsers = new Yaml(new SafeConstructor()); Map usersRootDataNode; if (!usersFile.exists()) { throw new IllegalArgumentException("The file which should contain users does not exist!\n" + usersFile.getPath()); } - FileInputStream usersInputStream = new FileInputStream(usersFile); + final FileInputStream usersInputStream = new FileInputStream(usersFile); try { usersRootDataNode = (Map) yamlUsers.load(new UnicodeReader(usersInputStream)); if (usersRootDataNode == null) { throw new NullPointerException(); } - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("The following file couldn't pass on Parser.\n" + usersFile.getPath(), ex); } finally { usersInputStream.close(); @@ -839,7 +611,7 @@ public class WorldDataHolder { */ try { allUsersNode = (Map) usersRootDataNode.get("users"); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Your " + usersFile.getPath() + " file is invalid. See console for details.", ex); } @@ -847,7 +619,7 @@ public class WorldDataHolder { if (allUsersNode != null) { - Iterator usersItr = allUsersNode.keySet().iterator(); + final Iterator usersItr = allUsersNode.keySet().iterator(); String usersKey; Object node; Integer userCount = 0; @@ -862,18 +634,18 @@ public class WorldDataHolder { else usersKey = node.toString(); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Invalid node type for user entry (" + userCount + ") in file: " + usersFile.getPath(), ex); } Map thisUserNode = null; try { thisUserNode = (Map) allUsersNode.get(node); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Bad format found for user: " + usersKey + " in file: " + usersFile.getPath()); } - User thisUser = ph.createUser(usersKey); + final User thisUser = ph.createUser(usersKey); if (thisUser == null) { throw new IllegalArgumentException("I think this user was declared more than once: " + usersKey + " in file: " + usersFile.getPath()); } @@ -885,7 +657,7 @@ public class WorldDataHolder { nodeData = thisUserNode.get("lastname"); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Bad format found in 'subgroups' for user: " + usersKey + " in file: " + usersFile.getPath()); } @@ -900,7 +672,7 @@ public class WorldDataHolder { nodeData = null; try { nodeData = thisUserNode.get("permissions"); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Bad format found in 'permissions' for user: " + usersKey + " in file: " + usersFile.getPath()); } @@ -912,7 +684,7 @@ public class WorldDataHolder { } else { try { if (nodeData instanceof List) { - for (Object o : ((List) nodeData)) { + for (final Object o : ((List) nodeData)) { /* * Only add this permission if it's not empty */ @@ -930,7 +702,7 @@ public class WorldDataHolder { } } - } catch (NullPointerException e) { + } catch (final NullPointerException e) { // Ignore this entry as it's null. } thisUser.sortPermissions(); @@ -941,7 +713,7 @@ public class WorldDataHolder { nodeData = null; try { nodeData = thisUserNode.get("subgroups"); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Bad format found in 'subgroups' for user: " + usersKey + " in file: " + usersFile.getPath()); } @@ -950,11 +722,11 @@ public class WorldDataHolder { * If no subgroups node is found, or it's empty do nothing. */ } else if (nodeData instanceof List) { - for (Object o : ((List) nodeData)) { + for (final Object o : ((List) nodeData)) { if (o == null) { GroupManager.logger.warning("Invalid Subgroup data for user: " + thisUser.getLastName() + ". Ignoring entry in file: " + usersFile.getPath()); } else { - Group subGrp = ph.getGroup(o.toString()); + final Group subGrp = ph.getGroup(o.toString()); if (subGrp != null) { thisUser.addSubGroup(subGrp); } else { @@ -963,7 +735,7 @@ public class WorldDataHolder { } } } else if (nodeData instanceof String) { - Group subGrp = ph.getGroup(nodeData.toString()); + final Group subGrp = ph.getGroup(nodeData.toString()); if (subGrp != null) { thisUser.addSubGroup(subGrp); } else { @@ -976,7 +748,7 @@ public class WorldDataHolder { nodeData = null; try { nodeData = thisUserNode.get("info"); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Bad format found in 'info' section for user: " + usersKey + " in file: " + usersFile.getPath()); } @@ -997,7 +769,7 @@ public class WorldDataHolder { nodeData = null; try { nodeData = thisUserNode.get("group"); - } catch (Exception ex) { + } catch (final Exception ex) { throw new IllegalArgumentException("Bad format found in 'group' section for user: " + usersKey + " in file: " + usersFile.getPath()); } @@ -1022,197 +794,161 @@ public class WorldDataHolder { } /** - * Write a dataHolder in a specified file - * - * @param ph - * @param groupsFile + * Add a group to the list + * + * @param groupToAdd */ - public static void writeGroups(WorldDataHolder ph, File groupsFile) { + public void addGroup(Group groupToAdd) { - Map root = new HashMap(); - - Map groupsMap = new HashMap(); - - root.put("groups", groupsMap); - synchronized (ph.getGroups()) { - for (String groupKey : ph.getGroups().keySet()) { - Group group = ph.getGroups().get(groupKey); - - Map aGroupMap = new HashMap(); - groupsMap.put(group.getName(), aGroupMap); - - if (ph.getDefaultGroup() == null) { - GroupManager.logger.severe("There is no default group for world: " + ph.getName()); - } - aGroupMap.put("default", group.equals(ph.getDefaultGroup())); - - Map infoMap = new HashMap(); - aGroupMap.put("info", infoMap); - - for (String infoKey : group.getVariables().getVarKeyList()) { - infoMap.put(infoKey, group.getVariables().getVarObject(infoKey)); - } - - aGroupMap.put("inheritance", group.getInherits()); - - aGroupMap.put("permissions", group.getPermissionList()); - } + if (groupToAdd.getName().toLowerCase().startsWith("g:")) { + GroupManager.getGlobalGroups().addGroup(groupToAdd); + GroupManager.getGMEventHandler().callEvent(groupToAdd, GMGroupEvent.Action.GROUP_ADDED); + return; } - if (!root.isEmpty()) { - DumperOptions opt = new DumperOptions(); - opt.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - final Yaml yaml = new Yaml(opt); - try { - OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(groupsFile), "UTF-8"); - - String newLine = System.getProperty("line.separator"); - - out.write("# Group inheritance" + newLine); - out.write("#" + newLine); - out.write("# Any inherited groups prefixed with a g: are global groups" + newLine); - out.write("# and are inherited from the GlobalGroups.yml." + newLine); - out.write("#" + newLine); - out.write("# Groups without the g: prefix are groups local to this world" + newLine); - out.write("# and are defined in the this groups.yml file." + newLine); - out.write("#" + newLine); - out.write("# Local group inheritances define your promotion tree when using 'manpromote/mandemote'" + newLine); - out.write(newLine); - - yaml.dump(root, out); - out.close(); - } catch (UnsupportedEncodingException ex) { - } catch (FileNotFoundException ex) { - } catch (IOException e) { - } + if (groupToAdd.getDataSource() != this) { + groupToAdd = groupToAdd.clone(this); } - - // Update the LastModified time. - ph.setGroupsFile(groupsFile); - ph.setTimeStampGroups(groupsFile.lastModified()); - ph.removeGroupsChangedFlag(); - + removeGroup(groupToAdd.getName()); + getGroups().put(groupToAdd.getName().toLowerCase(), groupToAdd); + setGroupsChanged(true); if (GroupManager.isLoaded()) - GroupManager.getGMEventHandler().callEvent(GMSystemEvent.Action.SAVED); - - /* - * FileWriter tx = null; try { tx = new FileWriter(groupsFile, false); - * tx.write(yaml.dump(root)); tx.flush(); } catch (Exception e) { } - * finally { try { tx.close(); } catch (IOException ex) { } } - */ + GroupManager.getGMEventHandler().callEvent(groupToAdd, GMGroupEvent.Action.GROUP_ADDED); } /** - * Write a dataHolder in a specified file - * - * @param ph - * @param usersFile + * Add a user to the list. If it already exists, overwrite the old. + * + * @param theUser + * the user you want to add to the permission list */ - public static void writeUsers(WorldDataHolder ph, File usersFile) { + public void addUser(User theUser) { - Map root = new HashMap(); - LinkedHashMap usersMap = new LinkedHashMap(); - - root.put("users", usersMap); - synchronized (ph.getUsers()) { - - // A sorted list of users. - for (String userKey : new TreeSet(ph.getUsers().keySet())) { - User user = ph.getUsers().get(userKey); - if ((user.getGroup() == null || user.getGroup().equals(ph.getDefaultGroup())) && user.getPermissionList().isEmpty() && user.getVariables().isEmpty() && user.isSubGroupsEmpty()) { - continue; - } - - LinkedHashMap aUserMap = new LinkedHashMap(); - usersMap.put(user.getUUID(), aUserMap); - - if (!user.getUUID().equalsIgnoreCase(user.getLastName())) { - aUserMap.put("lastname", user.getLastName()); - } - - // GROUP NODE - if (user.getGroup() == null) { - aUserMap.put("group", ph.getDefaultGroup().getName()); - } else { - aUserMap.put("group", user.getGroup().getName()); - } - - // SUBGROUPS NODE - aUserMap.put("subgroups", user.subGroupListStringCopy()); - - // PERMISSIONS NODE - aUserMap.put("permissions", user.getPermissionList()); - - // USER INFO NODE - BETA - if (user.getVariables().getSize() > 0) { - Map infoMap = new HashMap(); - aUserMap.put("info", infoMap); - for (String infoKey : user.getVariables().getVarKeyList()) { - infoMap.put(infoKey, user.getVariables().getVarObject(infoKey)); - } - } - // END USER INFO NODE - BETA - - } + if (theUser.getDataSource() != this) { + theUser = theUser.clone(this); } - - if (!root.isEmpty()) { - DumperOptions opt = new DumperOptions(); - opt.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - final Yaml yaml = new Yaml(opt); - try { - OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(usersFile), "UTF-8"); - yaml.dump(root, out); - out.close(); - } catch (UnsupportedEncodingException ex) { - } catch (FileNotFoundException ex) { - } catch (IOException e) { - } + if (theUser == null) { + return; } - - // Update the LastModified time. - ph.setUsersFile(usersFile); - ph.setTimeStampUsers(usersFile.lastModified()); - ph.removeUsersChangedFlag(); - + if ((theUser.getGroup() == null)) { + theUser.setGroup(groups.getDefaultGroup()); + } + removeUser(theUser.getUUID()); + getUsers().put(theUser.getUUID().toLowerCase(), theUser); + setUsersChanged(true); if (GroupManager.isLoaded()) - GroupManager.getGMEventHandler().callEvent(GMSystemEvent.Action.SAVED); - - /* - * FileWriter tx = null; try { tx = new FileWriter(usersFile, false); - * tx.write(yaml.dump(root)); tx.flush(); } catch (Exception e) { } - * finally { try { tx.close(); } catch (IOException ex) { } } - */ + GroupManager.getGMEventHandler().callEvent(theUser, Action.USER_ADDED); } /** - * Don't use this. Unless you want to make this plugin to interact with - * original Nijikokun Permissions This method is supposed to make the - * original one reload the file, and propagate the changes made here. - * - * Prefer to use the AnjoCaido's fake version of Nijikokun's Permission - * plugin. The AnjoCaido's Permission can propagate the changes made on this - * plugin instantly, without need to save the file. - * - * @param server - * the server that holds the plugin - * @deprecated it is not used anymore... unless if you use original - * Permissions + * Creates a new Group with the given name and adds it to this holder + * + * @param groupName + * the groupname you want + * @return null if group already exists. or new Group */ - @Deprecated - public static void reloadOldPlugins(Server server) { + public Group createGroup(final String groupName) { - // Only reload permissions - PluginManager pm = server.getPluginManager(); - Plugin[] plugins = pm.getPlugins(); - for (int i = 0; i < plugins.length; i++) { - // plugins[i].getConfiguration().load(); - try { - plugins[i].getClass().getMethod("setupPermissions").invoke(plugins[i]); - } catch (Exception ex) { - continue; - } + if (groupName.toLowerCase().startsWith("g:")) { + final Group newGroup = new Group(groupName); + return GroupManager.getGlobalGroups().newGroup(newGroup); } + + if (getGroups().containsKey(groupName.toLowerCase())) { + return null; + } + + final Group newGroup = new Group(this, groupName); + addGroup(newGroup); + setGroupsChanged(true); + return newGroup; + } + + /** + * Creates a new User with the given name and adds it to this holder. + * + * @param userId + * the UUID or username you want + * @return null if user already exists. or new User + */ + public User createUser(final String userId) { + + if (getUsers().containsKey(userId.toLowerCase())) { + return null; + } + final User newUser = new User(this, userId); + newUser.setGroup(groups.getDefaultGroup(), false); + addUser(newUser); + setUsersChanged(true); + return newUser; + } + + /** + * Returns the default group of the file + * + * @return the default group + */ + public Group getDefaultGroup() { + + return groups.getDefaultGroup(); + } + + /** + * Returns a group of the given name + * + * @param groupName + * the name of the group + * @return a group if it is found. null if not found. + */ + public Group getGroup(final String groupName) { + if (groupName.toLowerCase().startsWith("g:")) + return GroupManager.getGlobalGroups().getGroup(groupName); + return getGroups().get(groupName.toLowerCase()); + } + + /** + * + * @return a collection of the groups + */ + public Collection getGroupList() { + + synchronized (getGroups()) { + return new ArrayList(getGroups().values()); + } + } + + /** + * Note: Iteration over this object has to be synchronized! + * + * @return the groups + */ + public Map getGroups() { + + return groups.getGroups(); + } + + /** + * @return the groupsFile + */ + public File getGroupsFile() { + + return groups.getGroupsFile(); + } + + /** + * @return the groups + */ + public GroupsDataHolder getGroupsObject() { + + return groups; + } + + /** + * @return the name + */ + public String getName() { + + return name; } /** @@ -1227,85 +963,119 @@ public class WorldDataHolder { } /** - * @param haveUsersChanged - * the haveUsersChanged to set + * @return the timeStampGroups */ - public void setUsersChanged(boolean haveUsersChanged) { + public long getTimeStampGroups() { - users.setUsersChanged(haveUsersChanged); + return groups.getTimeStampGroups(); } /** - * - * @return true if any user data has changed + * @return the timeStampUsers */ - public boolean haveUsersChanged() { + public long getTimeStampUsers() { - if (users.HaveUsersChanged()) { - return true; + return users.getTimeStampUsers(); + } + + /** + * Search for a user. If it doesn't exist, create a new one with default + * group. + * + * @param userId + * the UUID String or name of the user + * @return class that manage that user permission + */ + public User getUser(final String userId) { + + if (getUsers().containsKey(userId.toLowerCase())) { + return getUsers().get(userId.toLowerCase()); } - synchronized (users.getUsers()) { - for (User u : users.getUsers().values()) { - if (u.isChanged()) { - return true; + + // Legacy name matching + if (userId.length() < 36) { + + // Search for a LastName match + for (final User user : getUserList()) { + + if (user.getLastName().equalsIgnoreCase(userId)) { + return user; } } + } - return false; + + // No user account found so create a new one. + final User newUser = createUser(userId); + + return newUser; } /** - * @param setGroupsChanged - * the haveGroupsChanged to set + * *** Internal GM use only *** + * This is called when a player joins to update/add their UUID. + * + * @param uUID + * the player objects UUID. + * @param currentName + * the name they have just logged in with. + * @return the user object for this player. */ - public void setGroupsChanged(boolean setGroupsChanged) { + public User getUser(final String uUID, final String currentName) { - groups.setGroupsChanged(setGroupsChanged); - } + // Check for a UUID account + User user = getUsers().get(uUID.toLowerCase()); - /** - * - * @return true if any group data has changed. - */ - public boolean haveGroupsChanged() { + if (user != null) { + + user.setLastName(currentName); + return user; - if (groups.HaveGroupsChanged()) { - return true; } - synchronized (groups.getGroups()) { - for (Group g : groups.getGroups().values()) { - if (g.isChanged()) { - return true; - } + + // Search for a LastName match + for (final User usr : getUserList()) { + + if (usr.getLastName().equalsIgnoreCase(currentName) && usr.getUUID().equalsIgnoreCase(usr.getLastName())) { + + // Clone this user so we can set it's uUID + user = usr.clone(uUID, currentName); + + // Delete it and replace with the new clone. + this.removeUser(usr.getUUID()); + this.addUser(user); + + return getUsers().get(uUID.toLowerCase()); } + } - return false; + + // No user account found so create a new one. + final User newUser = createUser(uUID); + newUser.setLastName(currentName); + + return newUser; } /** * + * @return a collection of the users */ - public void removeUsersChangedFlag() { + public Collection getUserList() { - setUsersChanged(false); synchronized (getUsers()) { - for (User u : getUsers().values()) { - u.flagAsSaved(); - } + return new ArrayList(getUsers().values()); } } /** + * Note: Iteration over this object has to be synchronized! * + * @return the users */ - public void removeGroupsChangedFlag() { + public Map getUsers() { - setGroupsChanged(false); - synchronized (getGroups()) { - for (Group g : getGroups().values()) { - g.flagAsSaved(); - } - } + return users.getUsers(); } /** @@ -1317,37 +1087,252 @@ public class WorldDataHolder { } /** - * @param file - * the usersFile to set + * @return the users */ - public void setUsersFile(File file) { + public UsersDataHolder getUsersObject() { - users.setUsersFile(file); + return users; } /** - * @return the groupsFile + * Check if a group exists. Its the same of getGroup, but check if it is + * null. + * + * @param groupName + * the name of the group + * @return true if exists. false if not. */ - public File getGroupsFile() { - - return groups.getGroupsFile(); + public boolean groupExists(final String groupName) { + if (groupName.toLowerCase().startsWith("g:")) + return GroupManager.getGlobalGroups().hasGroup(groupName); + return getGroups().containsKey(groupName.toLowerCase()); } /** - * @param file - * the groupsFile to set + * + * @return true if any group data has changed. */ - public void setGroupsFile(File file) { + public boolean haveGroupsChanged() { - groups.setGroupsFile(file); + if (groups.HaveGroupsChanged()) { + return true; + } + synchronized (groups.getGroups()) { + for (final Group g : groups.getGroups().values()) { + if (g.isChanged()) { + return true; + } + } + } + return false; } /** - * @return the name + * + * @return true if any user data has changed */ - public String getName() { + public boolean haveUsersChanged() { - return name; + if (users.HaveUsersChanged()) { + return true; + } + synchronized (users.getUsers()) { + for (final User u : users.getUsers().values()) { + if (u.isChanged()) { + return true; + } + } + } + return false; + } + + /** + * + * @param userId + * @return true if we have data for this player. + */ + public boolean isUserDeclared(final String userId) { + + return getUsers().containsKey(userId.toLowerCase()); + } + + public void loadGroups(final File groupsFile) { + + GroupManager.setLoaded(false); + try { + setGroupsFile(groupsFile); + loadGroups(this, groupsFile); + } catch (final FileNotFoundException e) { + e.printStackTrace(); + throw new IllegalArgumentException("The file which should contain groups does not exist!\n" + groupsFile.getPath()); + } catch (final IOException e) { + e.printStackTrace(); + throw new IllegalArgumentException("Error accessing the groups file!\n" + groupsFile.getPath()); + } + + GroupManager.setLoaded(true); + } + + public void loadUsers(final File usersFile) { + + GroupManager.setLoaded(false); + try { + setUsersFile(usersFile); + loadUsers(this, usersFile); + } catch (final FileNotFoundException e) { + e.printStackTrace(); + throw new IllegalArgumentException("The file which should contain users does not exist!\n" + usersFile.getPath()); + } catch (final IOException e) { + e.printStackTrace(); + throw new IllegalArgumentException("Error accessing the users file!\n" + usersFile.getPath()); + } + + GroupManager.setLoaded(true); + } + + /** + * reads the file again + */ + public void reload() { + + try { + reloadGroups(); + reloadUsers(); + } catch (final Exception ex) { + Logger.getLogger(WorldDataHolder.class.getName()).log(Level.SEVERE, null, ex); + } + } + + /** + * Refresh Group data from file + */ + public void reloadGroups() { + + GroupManager.setLoaded(false); + try { + // temporary holder in case the load fails. + WorldDataHolder ph = new WorldDataHolder(this.getName()); + + loadGroups(ph, getGroupsFile()); + // transfer new data + resetGroups(); + for (final Group tempGroup : ph.getGroupList()) { + tempGroup.clone(this); + } + this.setDefaultGroup(getGroup(ph.getDefaultGroup().getName())); + this.removeGroupsChangedFlag(); + this.setTimeStampGroups(getGroupsFile().lastModified()); + + ph = null; + } catch (final Exception ex) { + Logger.getLogger(WorldDataHolder.class.getName()).log(Level.WARNING, null, ex); + } + GroupManager.setLoaded(true); + GroupManager.getGMEventHandler().callEvent(GMSystemEvent.Action.RELOADED); + } + + /** + * Refresh Users data from file + */ + public void reloadUsers() { + + GroupManager.setLoaded(false); + try { + // temporary holder in case the load fails. + WorldDataHolder ph = new WorldDataHolder(this.getName()); + // copy groups for reference + for (final Group tempGroup : this.getGroupList()) { + tempGroup.clone(ph); + } + // setup the default group before loading user data. + ph.setDefaultGroup(ph.getGroup(getDefaultGroup().getName())); + loadUsers(ph, getUsersFile()); + // transfer new data + resetUsers(); + for (final User tempUser : ph.getUserList()) { + tempUser.clone(this); + } + this.removeUsersChangedFlag(); + this.setTimeStampUsers(getUsersFile().lastModified()); + + ph = null; + } catch (final Exception ex) { + Logger.getLogger(WorldDataHolder.class.getName()).log(Level.WARNING, null, ex); + } + GroupManager.setLoaded(true); + GroupManager.getGMEventHandler().callEvent(GMSystemEvent.Action.RELOADED); + } + + /** + * Remove the group from the list + * + * @param groupName + * @return true if had something to remove. false the group was default or + * non-existant + */ + public boolean removeGroup(final String groupName) { + + if (groupName.toLowerCase().startsWith("g:")) { + return GroupManager.getGlobalGroups().removeGroup(groupName); + } + + if (getDefaultGroup() != null && groupName.equalsIgnoreCase(getDefaultGroup().getName())) { + return false; + } + if (getGroups().containsKey(groupName.toLowerCase())) { + getGroups().remove(groupName.toLowerCase()); + setGroupsChanged(true); + if (GroupManager.isLoaded()) + GroupManager.getGMEventHandler().callEvent(groupName.toLowerCase(), GMGroupEvent.Action.GROUP_REMOVED); + return true; + } + return false; + + } + + /** + * + */ + public void removeGroupsChangedFlag() { + + setGroupsChanged(false); + synchronized (getGroups()) { + for (final Group g : getGroups().values()) { + g.flagAsSaved(); + } + } + } + + /** + * Removes the user from the list. (he might become a default user) + * + * @param userId + * the UUID or username for the user to remove + * @return true if it had something to remove + */ + public boolean removeUser(final String userId) { + + if (getUsers().containsKey(userId.toLowerCase())) { + getUsers().remove(userId.toLowerCase()); + setUsersChanged(true); + if (GroupManager.isLoaded()) + GroupManager.getGMEventHandler().callEvent(userId, GMUserEvent.Action.USER_REMOVED); + return true; + } + return false; + } + + /** + * + */ + public void removeUsersChangedFlag() { + + setUsersChanged(false); + synchronized (getUsers()) { + for (final User u : getUsers().values()) { + u.flagAsSaved(); + } + } } /** @@ -1368,93 +1353,49 @@ public class WorldDataHolder { } /** - * Note: Iteration over this object has to be synchronized! - * - * @return the groups + * Change the default group of the file. + * + * @param group + * the group you want make default. */ - public Map getGroups() { + public void setDefaultGroup(final Group group) { - return groups.getGroups(); + if (!getGroups().containsKey(group.getName().toLowerCase()) || (group.getDataSource() != this)) { + addGroup(group); + } + groups.setDefaultGroup(getGroup(group.getName())); + setGroupsChanged(true); + if (GroupManager.isLoaded()) + GroupManager.getGMEventHandler().callEvent(GMSystemEvent.Action.DEFAULT_GROUP_CHANGED); } /** - * Note: Iteration over this object has to be synchronized! - * - * @return the users + * @param setGroupsChanged + * the haveGroupsChanged to set */ - public Map getUsers() { + public void setGroupsChanged(final boolean setGroupsChanged) { - return users.getUsers(); + groups.setGroupsChanged(setGroupsChanged); } /** - * @return the groups + * @param file + * the groupsFile to set */ - public GroupsDataHolder getGroupsObject() { + public void setGroupsFile(final File file) { - return groups; + groups.setGroupsFile(file); } /** * @param groupsDataHolder * the GroupsDataHolder to set */ - public void setGroupsObject(GroupsDataHolder groupsDataHolder) { + public void setGroupsObject(final GroupsDataHolder groupsDataHolder) { groups = groupsDataHolder; } - /** - * @return the users - */ - public UsersDataHolder getUsersObject() { - - return users; - } - - /** - * @param usersDataHolder - * the UsersDataHolder to set - */ - public void setUsersObject(UsersDataHolder usersDataHolder) { - - users = usersDataHolder; - } - - /** - * @return the timeStampGroups - */ - public long getTimeStampGroups() { - - return groups.getTimeStampGroups(); - } - - /** - * @return the timeStampUsers - */ - public long getTimeStampUsers() { - - return users.getTimeStampUsers(); - } - - /** - * @param timeStampGroups - * the timeStampGroups to set - */ - protected void setTimeStampGroups(long timeStampGroups) { - - groups.setTimeStampGroups(timeStampGroups); - } - - /** - * @param timeStampUsers - * the timeStampUsers to set - */ - protected void setTimeStampUsers(long timeStampUsers) { - - users.setTimeStampUsers(timeStampUsers); - } - public void setTimeStamps() { if (getGroupsFile() != null) @@ -1463,4 +1404,60 @@ public class WorldDataHolder { setTimeStampUsers(getUsersFile().lastModified()); } + /** + * @param haveUsersChanged + * the haveUsersChanged to set + */ + public void setUsersChanged(final boolean haveUsersChanged) { + + users.setUsersChanged(haveUsersChanged); + } + + /** + * @param file + * the usersFile to set + */ + public void setUsersFile(final File file) { + + users.setUsersFile(file); + } + + /** + * @param usersDataHolder + * the UsersDataHolder to set + */ + public void setUsersObject(final UsersDataHolder usersDataHolder) { + + users = usersDataHolder; + } + + /** + * update the dataSource to point to this object. + * + * This should be called whenever a set of world data is fetched. + */ + public void updateDataSource() { + + this.groups.setDataSource(this); + this.users.setDataSource(this); + } + + /** + * @param timeStampGroups + * the timeStampGroups to set + */ + protected void setTimeStampGroups(final long timeStampGroups) { + + groups.setTimeStampGroups(timeStampGroups); + } + + /** + * @param timeStampUsers + * the timeStampUsers to set + */ + protected void setTimeStampUsers(final long timeStampUsers) { + + users.setTimeStampUsers(timeStampUsers); + } + } diff --git a/src/main/java/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java b/src/main/java/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java index 3caa449..35eef5e 100644 --- a/src/main/java/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java +++ b/src/main/java/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java @@ -22,12 +22,12 @@ import org.bukkit.entity.Player; /** * Everything here maintains the model created by Nijikokun - * + * * But implemented to use GroupManager system. Which provides instant changes, * without file access. - * + * * It holds permissions only for one single world. - * + * * @author gabrielcouto, ElgarL */ public class AnjoPermissionsHandler extends PermissionsReaderInterface { @@ -36,404 +36,37 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface { /** * It needs a WorldDataHolder to work with. - * + * * @param holder */ - public AnjoPermissionsHandler(WorldDataHolder holder) { + public AnjoPermissionsHandler(final WorldDataHolder holder) { ph = holder; } - /** - * A short name method, for permission method. - * - * @param player - * @param permission - * @return true if the player has the permission - */ @Override - public boolean has(Player player, String permission) { + public void addGroupInfo(final String name, final String path, final Object data) { - return permission(player, permission); + ph.getGroup(name).getVariables().addVar(path, data); } - /** - * Checks if a player can use that permission node. - * - * @param player - * @param permission - * @return true if the player has the permission - */ @Override - public boolean permission(Player player, String permission) { + public void addUserInfo(final String name, final String path, final Object data) { - return checkUserPermission(ph.getUser(player.getName()).updatePlayer(player), permission); - } - - /** - * Checks if a player can use that permission node. - * - * @param playerName - * @param permission - * @return true if the player has the permission - */ - public boolean permission(String playerName, String permission) { - - return checkUserPermission(ph.getUser(playerName), permission); - } - - /** - * Returns the name of the group of that player name. - * - * @param userName - * @return String of players group name. - */ - @Override - public String getGroup(String userName) { - - return ph.getUser(userName).getGroup().getName(); - } - - /** - * Returns All permissions (including inheritance and sub groups) for the - * player, including child nodes from Bukkit. - * - * @param userName - * @return List of all players permissions. - */ - @Override - public List getAllPlayersPermissions(String userName) { - - 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 Set of all players permissions. - */ - @Override - public Set getAllPlayersPermissions(String userName, Boolean includeChildren) { - - Set playerPermArray = new LinkedHashSet(); - Set overrides = new LinkedHashSet(); - - // Add the players own permissions. - playerPermArray.addAll(populatePerms(ph.getUser(userName).getPermissionList(), includeChildren)); - - ArrayList alreadyProcessed = new ArrayList(); - - // fetch all group permissions - for (String group : getGroups(userName)) { - // Don't process a group more than once. - if (!alreadyProcessed.contains(group)) { - alreadyProcessed.add(group); - - Set groupPermArray = new LinkedHashSet(); - - if (group.startsWith("g:") && GroupManager.getGlobalGroups().hasGroup(group)) { - // GlobalGroups - groupPermArray = populatePerms(GroupManager.getGlobalGroups().getGroupsPermissions(group), includeChildren); - - } else { - // World Groups - groupPermArray = populatePerms(ph.getGroup(group).getPermissionList(), includeChildren); - } - - // Add all group permissions, unless negated by earlier permissions. - for (String perm : groupPermArray) { - boolean negated = (perm.startsWith("-")); - - // Overridden (Exception) permission defeats negation. - if (perm.startsWith("+")) { - overrides.add(perm.substring(1)); - continue; - } - - // Perm doesn't already exists and there is no negation for it - // or It's a negated perm where a normal perm doesn't exists (don't allow inheritance to negate higher perms) - if ((!negated && !playerPermArray.contains(perm) && !wildcardNegation(playerPermArray, perm)) - || (negated && !playerPermArray.contains(perm.substring(1)) && !wildcardNegation(playerPermArray, perm.substring(1)))) - playerPermArray.add(perm); - - } - } - - } - - // Process overridden permissions - - Iterator itr = overrides.iterator(); - - while (itr.hasNext()) { - - String node = itr.next(); - - if (playerPermArray.contains("-" + node)) { - playerPermArray.remove("-" + node); - } - - playerPermArray.add(node); - - } - - // Collections.sort(playerPermArray, StringPermissionComparator.getInstance()); - - return playerPermArray; - } - - /** - * Is there a direct or wildcard negation in the list which covers this permission node. - * - * @param playerPermArray - * @param node - * @return - */ - private boolean wildcardNegation(Set playerPermArray, String node) { - - /* - * Check for a negated parent with a wildcard or negated permission - */ - - if (playerPermArray.contains("-" + node)) - return true; - - final String[] parts = node.split("\\."); - final StringBuilder builder = new StringBuilder(node.length()); - for (String part : parts) { - builder.append('*'); - if (playerPermArray.contains("-" + builder.toString())) { - GroupManager.logger.fine("Wildcard Negation found for " + node); - return true; - } - - builder.deleteCharAt(builder.length() - 1); - builder.append(part).append('.'); - } - - /* - * No negated parent found so return false. - */ - GroupManager.logger.fine("No Negation found for " + node); - return false; - - } - - private Set populatePerms(List permsList, boolean includeChildren) { - - // Create a new array so it's modifiable. - List perms = new ArrayList(permsList); - Set permArray = new LinkedHashSet(); - Boolean allPerms = false; - - // Allow * node to populate ALL permissions to Bukkit. - if (perms.contains("*")) { - permArray.addAll(GroupManager.BukkitPermissions.getAllRegisteredPermissions(includeChildren)); - allPerms = true; - perms.remove("*"); - // Remove the no offline perms node as this should not be given. - perms.remove("groupmanager.noofflineperms"); - } - - for (String perm : perms) { - /** - * all permission sets are passed here pre-sorted, alphabetically. - * This means negated nodes will be processed before all permissions - * other than *. - */ - boolean negated = perm.startsWith("-"); - - if (!permArray.contains(perm)) { - permArray.add(perm); - - if ((negated) && (permArray.contains(perm.substring(1)))) - permArray.remove(perm.substring(1)); - - /** - * Process child nodes if required, - * or this is a negated node AND we used * to include all - * permissions, - * in which case we need to remove all children of that node. - */ - if ((includeChildren) || (negated && allPerms)) { - - Map children = GroupManager.BukkitPermissions.getAllChildren((negated ? perm.substring(1) : perm), new LinkedHashSet()); - - if (children != null) { - if (negated) - if (allPerms) { - - // 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. - * - * So if you have a group Admin > Moderator - * - * And verify the player 'MyAdmin', which is Admin, it will return true for - * both Admin or Moderator groups. - * - * If you have a player 'MyModerator', which is Moderator, it will give - * false if you pass Admin in group parameter. - * - * @param name - * @param group - * @return true if in group (with inheritance) - */ - @Override - public boolean inGroup(String name, String group) { - - if (hasGroupInInheritance(ph.getUser(name).getGroup(), group)) { - return true; - } - for (Group subGroup : ph.getUser(name).subGroupListCopy()) { - if (hasGroupInInheritance(subGroup, group)) { - return true; - } - } - return false; - } - - /** - * Gets the appropriate prefix for the user. This method is a utility method - * for chat plugins to get the user's prefix without having to look at every - * one of the user's ancestors. Returns an empty string if user has no - * parent groups. - * - * @param user - * Player's name - * @return Player's prefix - */ - @Override - public String getUserPrefix(String user) { - - String prefix = ph.getUser(user).getVariables().getVarString("prefix"); - if (prefix.length() != 0) { - return prefix; - } - - return getGroupPrefix(getGroup(user)); - } - - /** - * Gets the appropriate prefix for the user. This method is a utility method - * for chat plugins to get the user's prefix without having to look at every - * one of the user's ancestors. Returns an empty string if user has no - * parent groups. - * - * @param user - * Player's name - * @return Player's prefix - */ - @Override - public String getUserSuffix(String user) { - - String suffix = ph.getUser(user).getVariables().getVarString("suffix"); - if (suffix.length() != 0) { - return suffix; - } - - return getGroupSuffix(getGroup(user)); - - } - - /** - * Gets name of the primary group of the user. Returns the name of the - * default group if user has no parent groups, or "Default" if there is no - * default group for that world. - * - * @param user - * Player's name - * @return Name of player's primary group - */ - public String getPrimaryGroup(String user) { - - return getGroup(user); - - } - - /** - * Check if user can build. Checks inheritance and subgroups. - * - * @param userName - * Player's name - * @return true if the user can build - */ - public boolean canUserBuild(String userName) { - - return getPermissionBoolean(userName, "build"); - - } - - /** - * Returns the String prefix for the given group - * - * @param groupName - * @return empty string if found none. - */ - @Override - public String getGroupPrefix(String groupName) { - - Group g = ph.getGroup(groupName); - if (g == null) { - return ""; - } - return g.getVariables().getVarString("prefix"); - } - - /** - * Return the suffix for the given group name - * - * @param groupName - * @return empty string if not found. - */ - @Override - public String getGroupSuffix(String groupName) { - - Group g = ph.getGroup(groupName); - if (g == null) { - return ""; - } - return g.getVariables().getVarString("suffix"); + ph.getUser(name).getVariables().addVar(path, data); } /** * Checks the specified group for the Info Build node. Does NOT check * inheritance - * + * * @param groupName * @return true if can build */ @Override - public boolean canGroupBuild(String groupName) { + public boolean canGroupBuild(final String groupName) { - Group g = ph.getGroup(groupName); + final Group g = ph.getGroup(groupName); if (g == null) { return false; } @@ -441,424 +74,42 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface { } /** - * It returns a string variable value, set in the INFO node of the group. It - * will harvest inheritance for value. - * - * @param groupName - * @param variable - * @return null if no group with that variable is found. + * Check if user can build. Checks inheritance and subgroups. + * + * @param userName + * Player's name + * @return true if the user can build */ - @Override - public String getGroupPermissionString(String groupName, String variable) { + public boolean canUserBuild(final String userName) { - Group start = ph.getGroup(groupName); - if (start == null) { - return null; - } - Group result = nextGroupWithVariable(start, variable); - if (result == null) { - return null; - } - return result.getVariables().getVarString(variable); - } + return getPermissionBoolean(userName, "build"); - /** - * It returns a Integer variable value It will harvest inheritance for - * value. - * - * @param groupName - * @param variable - * @return -1 if none found or not parseable. - */ - @Override - public int getGroupPermissionInteger(String groupName, String variable) { - - Group start = ph.getGroup(groupName); - if (start == null) { - return -1; - } - Group result = nextGroupWithVariable(start, variable); - if (result == null) { - return -1; - } - return result.getVariables().getVarInteger(variable); - } - - /** - * Returns a boolean for given variable in INFO node. It will harvest - * inheritance for value. - * - * @param group - * @param variable - * @return false if not found/not parseable. - */ - @Override - public boolean getGroupPermissionBoolean(String group, String variable) { - - Group start = ph.getGroup(group); - if (start == null) { - return false; - } - Group result = nextGroupWithVariable(start, variable); - if (result == null) { - return false; - } - return result.getVariables().getVarBoolean(variable); - } - - /** - * Returns a double value for the given variable name in INFO node. It will - * harvest inheritance for value. - * - * @param group - * @param variable - * @return -1 if not found / not parseable. - */ - @Override - public double getGroupPermissionDouble(String group, String variable) { - - Group start = ph.getGroup(group); - if (start == null) { - return -1; - } - Group result = nextGroupWithVariable(start, variable); - if (result == null) { - return -1; - } - return result.getVariables().getVarDouble(variable); - } - - /** - * Returns the variable value of the user, in INFO node. - * - * @param user - * @param variable - * @return empty string if not found - */ - @Override - public String getUserPermissionString(String user, String variable) { - - User auser = ph.getUser(user); - if (auser == null) { - return ""; - } - return auser.getVariables().getVarString(variable); - } - - /** - * Returns the variable value of the user, in INFO node. - * - * @param user - * @param variable - * @return -1 if not found - */ - @Override - public int getUserPermissionInteger(String user, String variable) { - - User auser = ph.getUser(user); - if (auser == null) { - return -1; - } - return auser.getVariables().getVarInteger(variable); - } - - /** - * Returns the variable value of the user, in INFO node. - * - * @param user - * @param variable - * @return boolean value - */ - @Override - public boolean getUserPermissionBoolean(String user, String variable) { - - User auser = ph.getUser(user); - if (auser == null) { - return false; - } - return auser.getVariables().getVarBoolean(variable); - } - - /** - * Returns the variable value of the user, in INFO node. - * - * @param user - * @param variable - * @return -1 if not found - */ - @Override - public double getUserPermissionDouble(String user, String variable) { - - User auser = ph.getUser(user); - if (auser == null) { - return -1; - } - return auser.getVariables().getVarDouble(variable); - } - - /** - * Returns the variable value of the user, in INFO node. If not found, it - * will search for his Group variables. It will harvest the inheritance and - * subgroups. - * - * @param user - * @param variable - * @return empty string if not found - */ - @Override - public String getPermissionString(String user, String variable) { - - User auser = ph.getUser(user); - if (auser == null) { - return ""; - } - if (auser.getVariables().hasVar(variable)) { - return auser.getVariables().getVarString(variable); - } - Group start = auser.getGroup(); - if (start == null) { - return ""; - } - Group result = nextGroupWithVariable(start, variable); - if (result == null) { - // Check sub groups - if (!auser.isSubGroupsEmpty()) - for (Group subGroup : auser.subGroupListCopy()) { - result = nextGroupWithVariable(subGroup, variable); - // Found value? - if (result != null) - continue; - } - if (result == null) - return ""; - } - return result.getVariables().getVarString(variable); - // return getUserPermissionString(user, variable); - } - - /** - * Returns the variable value of the user, in INFO node. If not found, it - * will search for his Group variables. It will harvest the inheritance and - * subgroups. - * - * @param user - * @param variable - * @return -1 if not found - */ - @Override - public int getPermissionInteger(String user, String variable) { - - User auser = ph.getUser(user); - if (auser == null) { - return -1; - } - if (auser.getVariables().hasVar(variable)) { - return auser.getVariables().getVarInteger(variable); - } - Group start = auser.getGroup(); - if (start == null) { - return -1; - } - Group result = nextGroupWithVariable(start, variable); - if (result == null) { - // Check sub groups - if (!auser.isSubGroupsEmpty()) - for (Group subGroup : auser.subGroupListCopy()) { - result = nextGroupWithVariable(subGroup, variable); - // Found value? - if (result != null) - continue; - } - if (result == null) - return -1; - } - return result.getVariables().getVarInteger(variable); - // return getUserPermissionInteger(string, string1); - } - - /** - * Returns the variable value of the user, in INFO node. If not found, it - * will search for his Group variables. It will harvest the inheritance and - * subgroups. - * - * @param user - * @param variable - * @return false if not found or not parseable to true. - */ - @Override - public boolean getPermissionBoolean(String user, String variable) { - - User auser = ph.getUser(user); - if (auser == null) { - return false; - } - if (auser.getVariables().hasVar(variable)) { - return auser.getVariables().getVarBoolean(variable); - } - Group start = auser.getGroup(); - if (start == null) { - return false; - } - Group result = nextGroupWithVariable(start, variable); - if (result == null) { - // Check sub groups - if (!auser.isSubGroupsEmpty()) - for (Group subGroup : auser.subGroupListCopy()) { - result = nextGroupWithVariable(subGroup, variable); - // Found value? - if (result != null) - continue; - } - if (result == null) - return false; - } - return result.getVariables().getVarBoolean(variable); - // return getUserPermissionBoolean(user, string1); - } - - /** - * Returns the variable value of the user, in INFO node. If not found, it - * will search for his Group variables. It will harvest the inheritance and - * subgroups. - * - * @param user - * @param variable - * @return -1 if not found. - */ - @Override - public double getPermissionDouble(String user, String variable) { - - User auser = ph.getUser(user); - if (auser == null) { - return -1.0D; - } - if (auser.getVariables().hasVar(variable)) { - return auser.getVariables().getVarDouble(variable); - } - Group start = auser.getGroup(); - if (start == null) { - return -1.0D; - } - Group result = nextGroupWithVariable(start, variable); - if (result == null) { - // Check sub groups - if (!auser.isSubGroupsEmpty()) - for (Group subGroup : auser.subGroupListCopy()) { - result = nextGroupWithVariable(subGroup, variable); - // Found value? - if (result != null) - continue; - } - if (result == null) - return -1.0D; - } - return result.getVariables().getVarDouble(variable); - // return getUserPermissionDouble(string, string1); - } - - /** - * Does not include User's group permission - * - * @param user - * @param permission - * @return PermissionCheckResult - */ - public PermissionCheckResult checkUserOnlyPermission(User user, String permission) { - - user.sortPermissions(); - PermissionCheckResult result = new PermissionCheckResult(); - result.askedPermission = permission; - result.owner = user; - for (String access : user.getPermissionList()) { - result.resultType = comparePermissionString(access, permission); - if (result.resultType != PermissionCheckResult.Type.NOTFOUND) { - result.accessLevel = access; - return result; - } - } - result.resultType = PermissionCheckResult.Type.NOTFOUND; - return result; - } - - /** - * Returns the node responsible for that permission. Does not include User's - * group permission. - * - * @param group - * @param permission - * @return the node if permission is found. if not found, return null - */ - public PermissionCheckResult checkGroupOnlyPermission(Group group, String permission) { - - group.sortPermissions(); - PermissionCheckResult result = new PermissionCheckResult(); - result.owner = group; - result.askedPermission = permission; - for (String access : group.getPermissionList()) { - result.resultType = comparePermissionString(access, permission); - if (result.resultType != PermissionCheckResult.Type.NOTFOUND) { - result.accessLevel = access; - return result; - } - } - result.resultType = PermissionCheckResult.Type.NOTFOUND; - return result; - } - - /** - * Check permissions, including it's group and inheritance. - * - * @param user - * @param permission - * @return true if permission was found. false if not, or was negated. - */ - public boolean checkUserPermission(User user, String permission) { - - PermissionCheckResult result = checkFullGMPermission(user, permission, true); - if (result.resultType == PermissionCheckResult.Type.EXCEPTION || result.resultType == PermissionCheckResult.Type.FOUND) { - return true; - } - - return false; - } - - /** - * Do what checkUserPermission did before. But now returning a - * PermissionCheckResult. - * - * @param user - * @param targetPermission - * @return PermissionCheckResult - */ - public PermissionCheckResult checkFullUserPermission(User user, String targetPermission) { - - return checkFullGMPermission(user, targetPermission, true); } /** * Wrapper for offline server checks. * Looks for the 'groupmanager.noofflineperms' permissions and reports no permissions on servers set to offline. - * + * * Check user and groups with inheritance and Bukkit if bukkit = true return * a PermissionCheckResult. - * + * * @param user * @param targetPermission * @param checkBukkit * @return PermissionCheckResult */ - public PermissionCheckResult checkFullGMPermission(User user, String targetPermission, Boolean checkBukkit) { + public PermissionCheckResult checkFullGMPermission(final User user, final String targetPermission, final Boolean checkBukkit) { /* * Report no permissions under the following conditions. - * + * * We are in offline mode * and the player has the 'groupmanager.noofflineperms' permission. */ if (user == null || targetPermission == null || targetPermission.isEmpty() || (!Bukkit.getServer().getOnlineMode() && (checkPermission(user, "groupmanager.noofflineperms", false).resultType == PermissionCheckResult.Type.FOUND))) { - PermissionCheckResult result = new PermissionCheckResult(); + final PermissionCheckResult result = new PermissionCheckResult(); result.accessLevel = targetPermission; result.resultType = PermissionCheckResult.Type.NOTFOUND; @@ -869,192 +120,65 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface { } /** - * - * Check user and groups with inheritance and Bukkit if bukkit = true return - * a PermissionCheckResult. - * + * Do what checkUserPermission did before. But now returning a + * PermissionCheckResult. + * * @param user * @param targetPermission - * @param checkBukkit * @return PermissionCheckResult */ - private PermissionCheckResult checkPermission(User user, String targetPermission, Boolean checkBukkit) { + public PermissionCheckResult checkFullUserPermission(final User user, final String targetPermission) { - PermissionCheckResult result = new PermissionCheckResult(); - result.accessLevel = targetPermission; - result.resultType = PermissionCheckResult.Type.NOTFOUND; + return checkFullGMPermission(user, targetPermission, true); + } - if (checkBukkit) { - // Check Bukkit perms to support plugins which add perms via code - // (Heroes). - final Player player = user.getBukkitPlayer(); - // final Permission bukkitPerm = Bukkit.getPluginManager().getPermission(targetPermission); - if ((player != null) && player.hasPermission(targetPermission)) { - result.resultType = PermissionCheckResult.Type.FOUND; - result.owner = user; + /** + * Returns the node responsible for that permission. Does not include User's + * group permission. + * + * @param group + * @param permission + * @return the node if permission is found. if not found, return null + */ + public PermissionCheckResult checkGroupOnlyPermission(final Group group, final String permission) { + + group.sortPermissions(); + final PermissionCheckResult result = new PermissionCheckResult(); + result.owner = group; + result.askedPermission = permission; + for (final String access : group.getPermissionList()) { + result.resultType = comparePermissionString(access, permission); + if (result.resultType != PermissionCheckResult.Type.NOTFOUND) { + result.accessLevel = access; return result; } } - - PermissionCheckResult resultUser = checkUserOnlyPermission(user, targetPermission); - if (resultUser.resultType != PermissionCheckResult.Type.NOTFOUND) { - - resultUser.accessLevel = targetPermission; - - if (resultUser.resultType == PermissionCheckResult.Type.EXCEPTION) { - return resultUser; - } - - result = resultUser; - - } - - // IT ONLY CHECKS GROUPS PERMISSIONS IF RESULT FOR USER IS NOT AN EXCEPTION - PermissionCheckResult resultGroup = checkGroupPermissionWithInheritance(user.getGroup(), targetPermission); - if (resultGroup.resultType != PermissionCheckResult.Type.NOTFOUND) { - - resultGroup.accessLevel = targetPermission; - - if (resultGroup.resultType == PermissionCheckResult.Type.EXCEPTION) { - return resultGroup; - } - - // Do not override higher level permissions with negations. - if (result.resultType == PermissionCheckResult.Type.NOTFOUND) { - result = resultGroup; - } - - } - - // Do we have a high level negation? - boolean negated = (result.resultType == PermissionCheckResult.Type.NEGATION); - - // SUBGROUPS CHECK - for (Group subGroup : user.subGroupListCopy()) { - - PermissionCheckResult resultSubGroup = checkGroupPermissionWithInheritance(subGroup, targetPermission); - if (resultSubGroup.resultType != PermissionCheckResult.Type.NOTFOUND) { - - resultSubGroup.accessLevel = targetPermission; - - // Allow exceptions to override higher level negations - // but low level negations can not remove higher level permissions. - if (resultSubGroup.resultType == PermissionCheckResult.Type.EXCEPTION) { - - return resultSubGroup; - - } else if ((resultSubGroup.resultType == PermissionCheckResult.Type.FOUND) && (result.resultType != PermissionCheckResult.Type.NEGATION) && !negated) { - - result = resultSubGroup; - - } else if ((resultSubGroup.resultType == PermissionCheckResult.Type.NEGATION) && !negated) { - - result = resultSubGroup; - } - - } - } - - // THEN IT RETURNS A NOT FOUND - // OR THE RESULT OF THE SUBGROUP SEARCH. + result.resultType = PermissionCheckResult.Type.NOTFOUND; return result; } - /** - * Returns the next group, including inheritance, which contains that - * variable name. - * - * It does Breadth-first search - * - * @param start - * the starting group to look for - * @param targetVariable - * the variable name - * @return The group if found. Null if not. - */ - public Group nextGroupWithVariable(Group start, String targetVariable) { - - if (start == null || targetVariable == null) { - return null; - } - LinkedList stack = new LinkedList(); - ArrayList alreadyVisited = new ArrayList(); - stack.push(start); - alreadyVisited.add(start); - while (!stack.isEmpty()) { - Group now = stack.pop(); - if (now.getVariables().hasVar(targetVariable)) { - return now; - } - for (String sonName : now.getInherits()) { - Group son = ph.getGroup(sonName); - if (son != null && !alreadyVisited.contains(son)) { - stack.push(son); - alreadyVisited.add(son); - } - } - } - return null; - } - - /** - * Check if given group inherits another group. - * - * It does Breadth-first search - * - * @param start - * The group to start the search. - * @param askedGroup - * Name of the group you're looking for - * @return true if it inherits the group. - */ - public boolean hasGroupInInheritance(Group start, String askedGroup) { - - if (start == null || askedGroup == null) { - return false; - } - LinkedList stack = new LinkedList(); - ArrayList alreadyVisited = new ArrayList(); - stack.push(start); - alreadyVisited.add(start); - while (!stack.isEmpty()) { - Group now = stack.pop(); - if (now.getName().equalsIgnoreCase(askedGroup)) { - return true; - } - for (String sonName : now.getInherits()) { - Group son = ph.getGroup(sonName); - if (son != null && !alreadyVisited.contains(son)) { - stack.push(son); - alreadyVisited.add(son); - } - } - } - return false; - } - /** * Returns the result of permission check. Including inheritance. If found * anything, the PermissionCheckResult that retuns will include the Group * name, and the result type. Result types will be EXCEPTION, NEGATION, * FOUND. - * + * * If returned type NOTFOUND, the owner will be null, and ownerType too. - * + * * It does Breadth-first search - * + * * @param start * @param targetPermission * @return PermissionCheckResult */ - public PermissionCheckResult checkGroupPermissionWithInheritance(Group start, String targetPermission) { + public PermissionCheckResult checkGroupPermissionWithInheritance(final Group start, final String targetPermission) { if (start == null || targetPermission == null) { return null; } - LinkedList stack = new LinkedList(); - List alreadyVisited = new ArrayList(); + final LinkedList stack = new LinkedList(); + final List alreadyVisited = new ArrayList(); PermissionCheckResult result = new PermissionCheckResult(); stack.push(start); @@ -1065,8 +189,8 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface { result.resultType = PermissionCheckResult.Type.NOTFOUND; while (!stack.isEmpty()) { - Group now = stack.pop(); - PermissionCheckResult resultNow = checkGroupOnlyPermission(now, targetPermission); + final Group now = stack.pop(); + final PermissionCheckResult resultNow = checkGroupOnlyPermission(now, targetPermission); if (!resultNow.resultType.equals(PermissionCheckResult.Type.NOTFOUND)) { @@ -1080,8 +204,8 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface { result = resultNow; } - for (String sonName : now.getInherits()) { - Group son = ph.getGroup(sonName); + for (final String sonName : now.getInherits()) { + final Group son = ph.getGroup(sonName); if (son != null && !alreadyVisited.contains(son)) { // Add rather than push to retain inheritance order. stack.add(son); @@ -1094,55 +218,65 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface { } /** - * Return whole list of names of groups in a inheritance chain. Including a - * starting group. - * - * It does Breadth-first search. So closer groups will appear first in list. - * - * @param start - * @return the group that passed on test. null if no group passed. + * Does not include User's group permission + * + * @param user + * @param permission + * @return PermissionCheckResult */ - public ArrayList listAllGroupsInherited(Group start) { + public PermissionCheckResult checkUserOnlyPermission(final User user, final String permission) { - if (start == null) { - return null; - } - LinkedList stack = new LinkedList(); - ArrayList alreadyVisited = new ArrayList(); - stack.push(start); - alreadyVisited.add(start.getName()); - while (!stack.isEmpty()) { - Group now = stack.pop(); - for (String sonName : now.getInherits()) { - Group son = ph.getGroup(sonName); - if (son != null && !alreadyVisited.contains(son.getName())) { - stack.push(son); - alreadyVisited.add(son.getName()); - } + user.sortPermissions(); + final PermissionCheckResult result = new PermissionCheckResult(); + result.askedPermission = permission; + result.owner = user; + for (final String access : user.getPermissionList()) { + result.resultType = comparePermissionString(access, permission); + if (result.resultType != PermissionCheckResult.Type.NOTFOUND) { + result.accessLevel = access; + return result; } } - return alreadyVisited; + result.resultType = PermissionCheckResult.Type.NOTFOUND; + return result; + } + + /** + * Check permissions, including it's group and inheritance. + * + * @param user + * @param permission + * @return true if permission was found. false if not, or was negated. + */ + public boolean checkUserPermission(final User user, final String permission) { + + final PermissionCheckResult result = checkFullGMPermission(user, permission, true); + if (result.resultType == PermissionCheckResult.Type.EXCEPTION || result.resultType == PermissionCheckResult.Type.FOUND) { + return true; + } + + return false; } /** * Compare a user permission like 'myplugin.*' against a full plugin * permission name, like 'myplugin.dosomething'. As the example above, will * return true. - * + * * Please sort permissions before sending them here. So negative tokens get * priority. - * + * * You must test if it start with negative outside this method. It will only * tell if the nodes are matching or not. - * + * * Every '-' or '+' in the beginning is ignored. It will match only node * names. - * + * * @param userAccessLevel * @param fullPermissionName * @return PermissionCheckResult.Type */ - public PermissionCheckResult.Type comparePermissionString(String userAccessLevel, String fullPermissionName) { + public PermissionCheckResult.Type comparePermissionString(final String userAccessLevel, final String fullPermissionName) { int userAccessLevelLength; if (userAccessLevel == null || fullPermissionName == null || fullPermissionName.length() == 0 || (userAccessLevelLength = userAccessLevel.length()) == 0) { @@ -1179,66 +313,756 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface { if (userAccessLevel.charAt(userAccessLevel.length() - 1) == '*') { return userAccessLevel.regionMatches(true, userAccessLevelOffset, fullPermissionName, fullPermissionNameOffset, userAccessLevelLength - userAccessLevelOffset - 1) ? result : PermissionCheckResult.Type.NOTFOUND; - } else { - return userAccessLevel.regionMatches(true, - userAccessLevelOffset, - fullPermissionName, - fullPermissionNameOffset, - Math.max(userAccessLevelLength - userAccessLevelOffset, fullPermissionName.length() - fullPermissionNameOffset)) ? result : PermissionCheckResult.Type.NOTFOUND; } + return userAccessLevel.regionMatches(true, + userAccessLevelOffset, + fullPermissionName, + fullPermissionNameOffset, + Math.max(userAccessLevelLength - userAccessLevelOffset, fullPermissionName.length() - fullPermissionNameOffset)) ? result : PermissionCheckResult.Type.NOTFOUND; + } + + /** + * Returns All permissions (including inheritance and sub groups) for the + * player, including child nodes from Bukkit. + * + * @param userName + * @return List of all players permissions. + */ + @Override + public List getAllPlayersPermissions(final String userName) { + + final 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 Set of all players permissions. + */ + @Override + public Set getAllPlayersPermissions(final String userName, final Boolean includeChildren) { + + final Set playerPermArray = new LinkedHashSet(); + final Set overrides = new LinkedHashSet(); + + // Add the players own permissions. + playerPermArray.addAll(populatePerms(ph.getUser(userName).getPermissionList(), includeChildren)); + + final ArrayList alreadyProcessed = new ArrayList(); + + // fetch all group permissions + for (final String group : getGroups(userName)) { + // Don't process a group more than once. + if (!alreadyProcessed.contains(group)) { + alreadyProcessed.add(group); + + Set groupPermArray = new LinkedHashSet(); + + if (group.startsWith("g:") && GroupManager.getGlobalGroups().hasGroup(group)) { + // GlobalGroups + groupPermArray = populatePerms(GroupManager.getGlobalGroups().getGroupsPermissions(group), includeChildren); + + } else { + // World Groups + groupPermArray = populatePerms(ph.getGroup(group).getPermissionList(), includeChildren); + } + + // Add all group permissions, unless negated by earlier permissions. + for (final String perm : groupPermArray) { + final boolean negated = (perm.startsWith("-")); + + // Overridden (Exception) permission defeats negation. + if (perm.startsWith("+")) { + overrides.add(perm.substring(1)); + continue; + } + + // Perm doesn't already exists and there is no negation for it + // or It's a negated perm where a normal perm doesn't exists (don't allow inheritance to negate higher perms) + if ((!negated && !playerPermArray.contains(perm) && !wildcardNegation(playerPermArray, perm)) + || (negated && !playerPermArray.contains(perm.substring(1)) && !wildcardNegation(playerPermArray, perm.substring(1)))) + playerPermArray.add(perm); + + } + } + + } + + // Process overridden permissions + + final Iterator itr = overrides.iterator(); + + while (itr.hasNext()) { + + final String node = itr.next(); + + if (playerPermArray.contains("-" + node)) { + playerPermArray.remove("-" + node); + } + + playerPermArray.add(node); + + } + + // Collections.sort(playerPermArray, StringPermissionComparator.getInstance()); + + return playerPermArray; + } + + @Override + public Group getDefaultGroup() { + + return ph.getDefaultGroup(); + } + + /** + * Returns the name of the group of that player name. + * + * @param userName + * @return String of players group name. + */ + @Override + public String getGroup(final String userName) { + + return ph.getUser(userName).getGroup().getName(); + } + + /** + * Returns a boolean for given variable in INFO node. It will harvest + * inheritance for value. + * + * @param group + * @param variable + * @return false if not found/not parseable. + */ + @Override + public boolean getGroupPermissionBoolean(final String group, final String variable) { + + final Group start = ph.getGroup(group); + if (start == null) { + return false; + } + final Group result = nextGroupWithVariable(start, variable); + if (result == null) { + return false; + } + return result.getVariables().getVarBoolean(variable); + } + + /** + * Returns a double value for the given variable name in INFO node. It will + * harvest inheritance for value. + * + * @param group + * @param variable + * @return -1 if not found / not parseable. + */ + @Override + public double getGroupPermissionDouble(final String group, final String variable) { + + final Group start = ph.getGroup(group); + if (start == null) { + return -1; + } + final Group result = nextGroupWithVariable(start, variable); + if (result == null) { + return -1; + } + return result.getVariables().getVarDouble(variable); + } + + /** + * It returns a Integer variable value It will harvest inheritance for + * value. + * + * @param groupName + * @param variable + * @return -1 if none found or not parseable. + */ + @Override + public int getGroupPermissionInteger(final String groupName, final String variable) { + + final Group start = ph.getGroup(groupName); + if (start == null) { + return -1; + } + final Group result = nextGroupWithVariable(start, variable); + if (result == null) { + return -1; + } + return result.getVariables().getVarInteger(variable); + } + + /** + * It returns a string variable value, set in the INFO node of the group. It + * will harvest inheritance for value. + * + * @param groupName + * @param variable + * @return null if no group with that variable is found. + */ + @Override + public String getGroupPermissionString(final String groupName, final String variable) { + + final Group start = ph.getGroup(groupName); + if (start == null) { + return null; + } + final Group result = nextGroupWithVariable(start, variable); + if (result == null) { + return null; + } + return result.getVariables().getVarString(variable); + } + + /** + * Returns the String prefix for the given group + * + * @param groupName + * @return empty string if found none. + */ + @Override + public String getGroupPrefix(final String groupName) { + + final Group g = ph.getGroup(groupName); + if (g == null) { + return ""; + } + return g.getVariables().getVarString("prefix"); } /** * Returns a list of all groups. - * + * * Including subgroups. - * + * * @param userName * @return String[] of all group names. */ @Override - public String[] getGroups(String userName) { + public String[] getGroups(final String userName) { - ArrayList allGroups = listAllGroupsInherited(ph.getUser(userName).getGroup()); - for (Group subg : ph.getUser(userName).subGroupListCopy()) { + final ArrayList allGroups = listAllGroupsInherited(ph.getUser(userName).getGroup()); + for (final Group subg : ph.getUser(userName).subGroupListCopy()) { allGroups.addAll(listAllGroupsInherited(subg)); } - String[] arr = new String[allGroups.size()]; + final String[] arr = new String[allGroups.size()]; return allGroups.toArray(arr); } /** - * A Breadth-first search thru inheritance model. - * - * Just a model to copy and paste. This will guarantee the closer groups - * will be checked first. - * - * @param start - * @param targerPermission - * @return + * Return the suffix for the given group name + * + * @param groupName + * @return empty string if not found. */ - @SuppressWarnings("unused") - private Group breadthFirstSearch(Group start, String targerPermission) { + @Override + public String getGroupSuffix(final String groupName) { - if (start == null || targerPermission == null) { + final Group g = ph.getGroup(groupName); + if (g == null) { + return ""; + } + return g.getVariables().getVarString("suffix"); + } + + @Override + public boolean getInfoBoolean(final String entryName, final String path, final boolean isGroup) { + if (isGroup) { + final Group data = ph.getGroup(entryName); + if (data == null) { + return false; + } + return data.getVariables().getVarBoolean(path); + } + final User data = ph.getUser(entryName); + if (data == null) { + return false; + } + return data.getVariables().getVarBoolean(path); + } + + @Override + public double getInfoDouble(final String entryName, final String path, final boolean isGroup) { + if (isGroup) { + final Group data = ph.getGroup(entryName); + if (data == null) { + return -1; + } + return data.getVariables().getVarDouble(path); + } + final User data = ph.getUser(entryName); + if (data == null) { + return -1; + } + return data.getVariables().getVarDouble(path); + + } + + @Override + public int getInfoInteger(final String entryName, final String path, final boolean isGroup) { + + if (isGroup) { + final Group data = ph.getGroup(entryName); + if (data == null) { + return -1; + } + return data.getVariables().getVarInteger(path); + } + final User data = ph.getUser(entryName); + if (data == null) { + return -1; + } + return data.getVariables().getVarInteger(path); + } + + @Override + public String getInfoString(final String entryName, final String path, final boolean isGroup) { + + if (isGroup) { + final Group data = ph.getGroup(entryName); + if (data == null) { + return null; + } + return data.getVariables().getVarString(path); + } + final User data = ph.getUser(entryName); + if (data == null) { return null; } - LinkedList stack = new LinkedList(); - ArrayList alreadyVisited = new ArrayList(); + return data.getVariables().getVarString(path); + } + + /** + * Returns the variable value of the user, in INFO node. If not found, it + * will search for his Group variables. It will harvest the inheritance and + * subgroups. + * + * @param user + * @param variable + * @return false if not found or not parseable to true. + */ + @Override + public boolean getPermissionBoolean(final String user, final String variable) { + + final User auser = ph.getUser(user); + if (auser == null) { + return false; + } + if (auser.getVariables().hasVar(variable)) { + return auser.getVariables().getVarBoolean(variable); + } + final Group start = auser.getGroup(); + if (start == null) { + return false; + } + Group result = nextGroupWithVariable(start, variable); + if (result == null) { + // Check sub groups + if (!auser.isSubGroupsEmpty()) + for (final Group subGroup : auser.subGroupListCopy()) { + result = nextGroupWithVariable(subGroup, variable); + // Found value? + if (result != null) + continue; + } + if (result == null) + return false; + } + return result.getVariables().getVarBoolean(variable); + // return getUserPermissionBoolean(user, string1); + } + + /** + * Returns the variable value of the user, in INFO node. If not found, it + * will search for his Group variables. It will harvest the inheritance and + * subgroups. + * + * @param user + * @param variable + * @return -1 if not found. + */ + @Override + public double getPermissionDouble(final String user, final String variable) { + + final User auser = ph.getUser(user); + if (auser == null) { + return -1.0D; + } + if (auser.getVariables().hasVar(variable)) { + return auser.getVariables().getVarDouble(variable); + } + final Group start = auser.getGroup(); + if (start == null) { + return -1.0D; + } + Group result = nextGroupWithVariable(start, variable); + if (result == null) { + // Check sub groups + if (!auser.isSubGroupsEmpty()) + for (final Group subGroup : auser.subGroupListCopy()) { + result = nextGroupWithVariable(subGroup, variable); + // Found value? + if (result != null) + continue; + } + if (result == null) + return -1.0D; + } + return result.getVariables().getVarDouble(variable); + // return getUserPermissionDouble(string, string1); + } + + /** + * Returns the variable value of the user, in INFO node. If not found, it + * will search for his Group variables. It will harvest the inheritance and + * subgroups. + * + * @param user + * @param variable + * @return -1 if not found + */ + @Override + public int getPermissionInteger(final String user, final String variable) { + + final User auser = ph.getUser(user); + if (auser == null) { + return -1; + } + if (auser.getVariables().hasVar(variable)) { + return auser.getVariables().getVarInteger(variable); + } + final Group start = auser.getGroup(); + if (start == null) { + return -1; + } + Group result = nextGroupWithVariable(start, variable); + if (result == null) { + // Check sub groups + if (!auser.isSubGroupsEmpty()) + for (final Group subGroup : auser.subGroupListCopy()) { + result = nextGroupWithVariable(subGroup, variable); + // Found value? + if (result != null) + continue; + } + if (result == null) + return -1; + } + return result.getVariables().getVarInteger(variable); + // return getUserPermissionInteger(string, string1); + } + + /** + * Returns the variable value of the user, in INFO node. If not found, it + * will search for his Group variables. It will harvest the inheritance and + * subgroups. + * + * @param user + * @param variable + * @return empty string if not found + */ + @Override + public String getPermissionString(final String user, final String variable) { + + final User auser = ph.getUser(user); + if (auser == null) { + return ""; + } + if (auser.getVariables().hasVar(variable)) { + return auser.getVariables().getVarString(variable); + } + final Group start = auser.getGroup(); + if (start == null) { + return ""; + } + Group result = nextGroupWithVariable(start, variable); + if (result == null) { + // Check sub groups + if (!auser.isSubGroupsEmpty()) + for (final Group subGroup : auser.subGroupListCopy()) { + result = nextGroupWithVariable(subGroup, variable); + // Found value? + if (result != null) + continue; + } + if (result == null) + return ""; + } + return result.getVariables().getVarString(variable); + // return getUserPermissionString(user, variable); + } + + /** + * Gets name of the primary group of the user. Returns the name of the + * default group if user has no parent groups, or "Default" if there is no + * default group for that world. + * + * @param user + * Player's name + * @return Name of player's primary group + */ + public String getPrimaryGroup(final String user) { + + return getGroup(user); + + } + + /** + * Returns the variable value of the user, in INFO node. + * + * @param user + * @param variable + * @return boolean value + */ + @Override + public boolean getUserPermissionBoolean(final String user, final String variable) { + + final User auser = ph.getUser(user); + if (auser == null) { + return false; + } + return auser.getVariables().getVarBoolean(variable); + } + + /** + * Returns the variable value of the user, in INFO node. + * + * @param user + * @param variable + * @return -1 if not found + */ + @Override + public double getUserPermissionDouble(final String user, final String variable) { + + final User auser = ph.getUser(user); + if (auser == null) { + return -1; + } + return auser.getVariables().getVarDouble(variable); + } + + /** + * Returns the variable value of the user, in INFO node. + * + * @param user + * @param variable + * @return -1 if not found + */ + @Override + public int getUserPermissionInteger(final String user, final String variable) { + + final User auser = ph.getUser(user); + if (auser == null) { + return -1; + } + return auser.getVariables().getVarInteger(variable); + } + + /** + * Returns the variable value of the user, in INFO node. + * + * @param user + * @param variable + * @return empty string if not found + */ + @Override + public String getUserPermissionString(final String user, final String variable) { + + final User auser = ph.getUser(user); + if (auser == null) { + return ""; + } + return auser.getVariables().getVarString(variable); + } + + /** + * Gets the appropriate prefix for the user. This method is a utility method + * for chat plugins to get the user's prefix without having to look at every + * one of the user's ancestors. Returns an empty string if user has no + * parent groups. + * + * @param user + * Player's name + * @return Player's prefix + */ + @Override + public String getUserPrefix(final String user) { + + final String prefix = ph.getUser(user).getVariables().getVarString("prefix"); + if (prefix.length() != 0) { + return prefix; + } + + return getGroupPrefix(getGroup(user)); + } + + /** + * Gets the appropriate prefix for the user. This method is a utility method + * for chat plugins to get the user's prefix without having to look at every + * one of the user's ancestors. Returns an empty string if user has no + * parent groups. + * + * @param user + * Player's name + * @return Player's prefix + */ + @Override + public String getUserSuffix(final String user) { + + final String suffix = ph.getUser(user).getVariables().getVarString("suffix"); + if (suffix.length() != 0) { + return suffix; + } + + return getGroupSuffix(getGroup(user)); + + } + + /** + * A short name method, for permission method. + * + * @param player + * @param permission + * @return true if the player has the permission + */ + @Override + public boolean has(final Player player, final String permission) { + + return permission(player, permission); + } + + /** + * Check if given group inherits another group. + * + * It does Breadth-first search + * + * @param start + * The group to start the search. + * @param askedGroup + * Name of the group you're looking for + * @return true if it inherits the group. + */ + public boolean hasGroupInInheritance(final Group start, final String askedGroup) { + + if (start == null || askedGroup == null) { + return false; + } + final LinkedList stack = new LinkedList(); + final ArrayList alreadyVisited = new ArrayList(); stack.push(start); alreadyVisited.add(start); while (!stack.isEmpty()) { - Group now = stack.pop(); - PermissionCheckResult resultNow = checkGroupOnlyPermission(now, targerPermission); - if (resultNow.resultType.equals(PermissionCheckResult.Type.EXCEPTION) || resultNow.resultType.equals(PermissionCheckResult.Type.FOUND)) { + final Group now = stack.pop(); + if (now.getName().equalsIgnoreCase(askedGroup)) { + return true; + } + for (final String sonName : now.getInherits()) { + final Group son = ph.getGroup(sonName); + if (son != null && !alreadyVisited.contains(son)) { + stack.push(son); + alreadyVisited.add(son); + } + } + } + return false; + } + + /** + * Verify if player is in such group. It will check it's groups inheritance. + * + * So if you have a group Admin > Moderator + * + * And verify the player 'MyAdmin', which is Admin, it will return true for + * both Admin or Moderator groups. + * + * If you have a player 'MyModerator', which is Moderator, it will give + * false if you pass Admin in group parameter. + * + * @param name + * @param group + * @return true if in group (with inheritance) + */ + @Override + public boolean inGroup(final String name, final String group) { + + if (hasGroupInInheritance(ph.getUser(name).getGroup(), group)) { + return true; + } + for (final Group subGroup : ph.getUser(name).subGroupListCopy()) { + if (hasGroupInInheritance(subGroup, group)) { + return true; + } + } + return false; + } + + /** + * Return whole list of names of groups in a inheritance chain. Including a + * starting group. + * + * It does Breadth-first search. So closer groups will appear first in list. + * + * @param start + * @return the group that passed on test. null if no group passed. + */ + public ArrayList listAllGroupsInherited(final Group start) { + + if (start == null) { + return null; + } + final LinkedList stack = new LinkedList(); + final ArrayList alreadyVisited = new ArrayList(); + stack.push(start); + alreadyVisited.add(start.getName()); + while (!stack.isEmpty()) { + final Group now = stack.pop(); + for (final String sonName : now.getInherits()) { + final Group son = ph.getGroup(sonName); + if (son != null && !alreadyVisited.contains(son.getName())) { + stack.push(son); + alreadyVisited.add(son.getName()); + } + } + } + return alreadyVisited; + } + + /** + * Returns the next group, including inheritance, which contains that + * variable name. + * + * It does Breadth-first search + * + * @param start + * the starting group to look for + * @param targetVariable + * the variable name + * @return The group if found. Null if not. + */ + public Group nextGroupWithVariable(final Group start, final String targetVariable) { + + if (start == null || targetVariable == null) { + return null; + } + final LinkedList stack = new LinkedList(); + final ArrayList alreadyVisited = new ArrayList(); + stack.push(start); + alreadyVisited.add(start); + while (!stack.isEmpty()) { + final Group now = stack.pop(); + if (now.getVariables().hasVar(targetVariable)) { return now; } - if (resultNow.resultType.equals(PermissionCheckResult.Type.NEGATION)) { - return null; - } - for (String sonName : now.getInherits()) { - Group son = ph.getGroup(sonName); + for (final String sonName : now.getInherits()) { + final Group son = ph.getGroup(sonName); if (son != null && !alreadyVisited.contains(son)) { stack.push(son); alreadyVisited.add(son); @@ -1248,106 +1072,275 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface { return null; } + /** + * Checks if a player can use that permission node. + * + * @param player + * @param permission + * @return true if the player has the permission + */ @Override - public Group getDefaultGroup() { + public boolean permission(final Player player, final String permission) { - return ph.getDefaultGroup(); + return checkUserPermission(ph.getUser(player.getName()).updatePlayer(player), permission); + } + + /** + * Checks if a player can use that permission node. + * + * @param playerName + * @param permission + * @return true if the player has the permission + */ + public boolean permission(final String playerName, final String permission) { + + return checkUserPermission(ph.getUser(playerName), permission); } @Override - public String getInfoString(String entryName, String path, boolean isGroup) { + public void removeGroupInfo(final String name, final String path) { - if (isGroup) { - Group data = ph.getGroup(entryName); - if (data == null) { - return null; - } - return data.getVariables().getVarString(path); - } else { - User data = ph.getUser(entryName); - if (data == null) { - return null; - } - return data.getVariables().getVarString(path); - } + ph.getGroup(name).getVariables().removeVar(path); } @Override - public int getInfoInteger(String entryName, String path, boolean isGroup) { - - if (isGroup) { - Group data = ph.getGroup(entryName); - if (data == null) { - return -1; - } - return data.getVariables().getVarInteger(path); - } else { - User data = ph.getUser(entryName); - if (data == null) { - return -1; - } - return data.getVariables().getVarInteger(path); - } - } - - @Override - public double getInfoDouble(String entryName, String path, boolean isGroup) { - - if (isGroup) { - Group data = ph.getGroup(entryName); - if (data == null) { - return -1; - } - return data.getVariables().getVarDouble(path); - } else { - User data = ph.getUser(entryName); - if (data == null) { - return -1; - } - return data.getVariables().getVarDouble(path); - } - - } - - @Override - public boolean getInfoBoolean(String entryName, String path, boolean isGroup) { - - if (isGroup) { - Group data = ph.getGroup(entryName); - if (data == null) { - return false; - } - return data.getVariables().getVarBoolean(path); - } else { - User data = ph.getUser(entryName); - if (data == null) { - return false; - } - return data.getVariables().getVarBoolean(path); - } - } - - @Override - public void addUserInfo(String name, String path, Object data) { - - ph.getUser(name).getVariables().addVar(path, data); - } - - @Override - public void removeUserInfo(String name, String path) { + public void removeUserInfo(final String name, final String path) { ph.getUser(name).getVariables().removeVar(path); } - @Override - public void addGroupInfo(String name, String path, Object data) { + /** + * A Breadth-first search thru inheritance model. + * + * Just a model to copy and paste. This will guarantee the closer groups + * will be checked first. + * + * @param start + * @param targerPermission + * @return + */ + @SuppressWarnings("unused") + private Group breadthFirstSearch(final Group start, final String targerPermission) { - ph.getGroup(name).getVariables().addVar(path, data); + if (start == null || targerPermission == null) { + return null; + } + final LinkedList stack = new LinkedList(); + final ArrayList alreadyVisited = new ArrayList(); + stack.push(start); + alreadyVisited.add(start); + while (!stack.isEmpty()) { + final Group now = stack.pop(); + final PermissionCheckResult resultNow = checkGroupOnlyPermission(now, targerPermission); + if (resultNow.resultType.equals(PermissionCheckResult.Type.EXCEPTION) || resultNow.resultType.equals(PermissionCheckResult.Type.FOUND)) { + return now; + } + if (resultNow.resultType.equals(PermissionCheckResult.Type.NEGATION)) { + return null; + } + for (final String sonName : now.getInherits()) { + final Group son = ph.getGroup(sonName); + if (son != null && !alreadyVisited.contains(son)) { + stack.push(son); + alreadyVisited.add(son); + } + } + } + return null; } - @Override - public void removeGroupInfo(String name, String path) { + /** + * + * Check user and groups with inheritance and Bukkit if bukkit = true return + * a PermissionCheckResult. + * + * @param user + * @param targetPermission + * @param checkBukkit + * @return PermissionCheckResult + */ + private PermissionCheckResult checkPermission(final User user, final String targetPermission, final Boolean checkBukkit) { + + PermissionCheckResult result = new PermissionCheckResult(); + result.accessLevel = targetPermission; + result.resultType = PermissionCheckResult.Type.NOTFOUND; + + if (checkBukkit) { + // Check Bukkit perms to support plugins which add perms via code + // (Heroes). + final Player player = user.getBukkitPlayer(); + // final Permission bukkitPerm = Bukkit.getPluginManager().getPermission(targetPermission); + if ((player != null) && player.hasPermission(targetPermission)) { + result.resultType = PermissionCheckResult.Type.FOUND; + result.owner = user; + return result; + } + } + + final PermissionCheckResult resultUser = checkUserOnlyPermission(user, targetPermission); + if (resultUser.resultType != PermissionCheckResult.Type.NOTFOUND) { + + resultUser.accessLevel = targetPermission; + + if (resultUser.resultType == PermissionCheckResult.Type.EXCEPTION) { + return resultUser; + } + + result = resultUser; + + } + + // IT ONLY CHECKS GROUPS PERMISSIONS IF RESULT FOR USER IS NOT AN EXCEPTION + final PermissionCheckResult resultGroup = checkGroupPermissionWithInheritance(user.getGroup(), targetPermission); + if (resultGroup.resultType != PermissionCheckResult.Type.NOTFOUND) { + + resultGroup.accessLevel = targetPermission; + + if (resultGroup.resultType == PermissionCheckResult.Type.EXCEPTION) { + return resultGroup; + } + + // Do not override higher level permissions with negations. + if (result.resultType == PermissionCheckResult.Type.NOTFOUND) { + result = resultGroup; + } + + } + + // Do we have a high level negation? + final boolean negated = (result.resultType == PermissionCheckResult.Type.NEGATION); + + // SUBGROUPS CHECK + for (final Group subGroup : user.subGroupListCopy()) { + + final PermissionCheckResult resultSubGroup = checkGroupPermissionWithInheritance(subGroup, targetPermission); + if (resultSubGroup.resultType != PermissionCheckResult.Type.NOTFOUND) { + + resultSubGroup.accessLevel = targetPermission; + + // Allow exceptions to override higher level negations + // but low level negations can not remove higher level permissions. + if (resultSubGroup.resultType == PermissionCheckResult.Type.EXCEPTION) { + + return resultSubGroup; + + } else if ((resultSubGroup.resultType == PermissionCheckResult.Type.FOUND) && (result.resultType != PermissionCheckResult.Type.NEGATION) && !negated) { + + result = resultSubGroup; + + } else if ((resultSubGroup.resultType == PermissionCheckResult.Type.NEGATION) && !negated) { + + result = resultSubGroup; + } + + } + } + + // THEN IT RETURNS A NOT FOUND + // OR THE RESULT OF THE SUBGROUP SEARCH. + return result; + } + + private Set populatePerms(final List permsList, final boolean includeChildren) { + + // Create a new array so it's modifiable. + final List perms = new ArrayList(permsList); + final Set permArray = new LinkedHashSet(); + Boolean allPerms = false; + + // Allow * node to populate ALL permissions to Bukkit. + if (perms.contains("*")) { + permArray.addAll(GroupManager.BukkitPermissions.getAllRegisteredPermissions(includeChildren)); + allPerms = true; + perms.remove("*"); + // Remove the no offline perms node as this should not be given. + perms.remove("groupmanager.noofflineperms"); + } + + for (final String perm : perms) { + /** + * all permission sets are passed here pre-sorted, alphabetically. + * This means negated nodes will be processed before all permissions + * other than *. + */ + final boolean negated = perm.startsWith("-"); + + if (!permArray.contains(perm)) { + permArray.add(perm); + + if ((negated) && (permArray.contains(perm.substring(1)))) + permArray.remove(perm.substring(1)); + + /** + * Process child nodes if required, + * or this is a negated node AND we used * to include all + * permissions, + * in which case we need to remove all children of that node. + */ + if ((includeChildren) || (negated && allPerms)) { + + final Map children = GroupManager.BukkitPermissions.getAllChildren((negated ? perm.substring(1) : perm), new LinkedHashSet()); + + if (children != null) { + if (negated) + if (allPerms) { + + // Remove children of negated nodes + for (final String child : children.keySet()) + if (children.get(child)) + if (permArray.contains(child)) + permArray.remove(child); + + } else { + + // Add child nodes + for (final String child : children.keySet()) + if (children.get(child)) + if ((!permArray.contains(child)) && (!permArray.contains("-" + child))) + permArray.add(child); + } + } + } + } + } + + return permArray; + } + + /** + * Is there a direct or wildcard negation in the list which covers this permission node. + * + * @param playerPermArray + * @param node + * @return + */ + private boolean wildcardNegation(final Set playerPermArray, final String node) { + + /* + * Check for a negated parent with a wildcard or negated permission + */ + + if (playerPermArray.contains("-" + node)) + return true; + + final String[] parts = node.split("\\."); + final StringBuilder builder = new StringBuilder(node.length()); + for (final String part : parts) { + builder.append('*'); + if (playerPermArray.contains("-" + builder.toString())) { + GroupManager.logger.fine("Wildcard Negation found for " + node); + return true; + } + + builder.deleteCharAt(builder.length() - 1); + builder.append(part).append('.'); + } + + /* + * No negated parent found so return false. + */ + GroupManager.logger.fine("No Negation found for " + node); + return false; - ph.getGroup(name).getVariables().removeVar(path); } } diff --git a/src/main/java/org/anjocaido/groupmanager/permissions/BukkitPermissions.java b/src/main/java/org/anjocaido/groupmanager/permissions/BukkitPermissions.java index 3d2d62d..11eec19 100644 --- a/src/main/java/org/anjocaido/groupmanager/permissions/BukkitPermissions.java +++ b/src/main/java/org/anjocaido/groupmanager/permissions/BukkitPermissions.java @@ -3,12 +3,12 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, @@ -47,20 +47,139 @@ import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.plugin.PluginManager; /** - * + * * BukkitPermissions overrides to force GM reponses to Superperms - * + * * @author ElgarL */ public class BukkitPermissions { + private static Field permissions; + + // Setup reflection (Thanks to Codename_B for the reflection source) + static { + try { + permissions = PermissionAttachment.class.getDeclaredField("permissions"); + permissions.setAccessible(true); + } catch (final SecurityException e) { + e.printStackTrace(); + } catch (final NoSuchFieldException e) { + e.printStackTrace(); + } + } protected WeakHashMap attachments = new WeakHashMap(); protected LinkedHashMap registeredPermissions = new LinkedHashMap(); protected GroupManager plugin; protected boolean dumpAllPermissions = true; + protected boolean dumpMatchedPermissions = true; + private boolean player_join = false; + public BukkitPermissions(final GroupManager plugin) { + + this.plugin = plugin; + this.reset(); + this.registerEvents(); + + GroupManager.logger.info("Superperms support enabled."); + } + + public void collectPermissions() { + + registeredPermissions.clear(); + + for (final Permission perm : Bukkit.getPluginManager().getPermissions()) { + registeredPermissions.put(perm.getName().toLowerCase(), perm); + } + + } + + /** + * 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(final String node, final Set playerPermArray) { + + final LinkedList stack = new LinkedList(); + final Map alreadyVisited = new HashMap(); + stack.push(node); + alreadyVisited.put(node, true); + + while (!stack.isEmpty()) { + final String now = stack.pop(); + + final Map children = getChildren(now); + + if ((children != null) && (!playerPermArray.contains("-" + now))) { + for (final String childName : children.keySet()) { + if (!alreadyVisited.containsKey(childName)) { + stack.push(childName); + alreadyVisited.put(childName, children.get(childName)); + } + } + } + } + alreadyVisited.remove(node); + if (!alreadyVisited.isEmpty()) + return alreadyVisited; + + return null; + } + + /** + * Fetch all permissions which are registered with superperms. + * {can include child nodes) + * + * @param includeChildren + * @return List of all permission nodes + */ + public List getAllRegisteredPermissions(final boolean includeChildren) { + + final List perms = new ArrayList(); + + for (final String key : registeredPermissions.keySet()) { + if (!perms.contains(key)) { + perms.add(key); + + if (includeChildren) { + final Map children = getAllChildren(key, new HashSet()); + if (children != null) { + for (final String node : children.keySet()) + if (!perms.contains(node)) + perms.add(node); + } + } + } + + } + return perms; + } + + /** + * Returns a map of the child permissions (1 node deep) as registered with + * Bukkit. + * null is empty + * + * @param node + * @return Map of child permissions + */ + public Map getChildren(final String node) { + + final Permission perm = registeredPermissions.get(node.toLowerCase()); + if (perm == null) + return null; + + return perm.getChildren(); + + } + /** * @return the player_join */ @@ -70,35 +189,45 @@ public class BukkitPermissions { } /** - * @param player_join - * the player_join to set + * List all effective permissions for this player. + * + * @param player + * @return List of permissions */ - public void setPlayer_join(boolean player_join) { + public List listPerms(final Player player) { - this.player_join = player_join; - } + final List perms = new ArrayList(); - private static Field permissions; + /* + * // All permissions registered with Bukkit for this player + * PermissionAttachment attachment = this.attachments.get(player); + * + * // List perms for this player perms.add("Attachment Permissions:"); + * for(Map.Entry entry : + * attachment.getPermissions().entrySet()){ perms.add(" " + + * entry.getKey() + " = " + entry.getValue()); } + */ - // Setup reflection (Thanks to Codename_B for the reflection source) - static { - try { - permissions = PermissionAttachment.class.getDeclaredField("permissions"); - permissions.setAccessible(true); - } catch (SecurityException e) { - e.printStackTrace(); - } catch (NoSuchFieldException e) { - e.printStackTrace(); + perms.add("Effective Permissions:"); + for (final PermissionAttachmentInfo info : player.getEffectivePermissions()) { + if (info.getValue() == true) + perms.add(" " + info.getPermission() + " = " + info.getValue()); } + return perms; } - public BukkitPermissions(GroupManager plugin) { + /** + * Remove all attachments in case of a restart or reload. + */ + public void removeAllAttachments() { - this.plugin = plugin; - this.reset(); - this.registerEvents(); - - GroupManager.logger.info("Superperms support enabled."); + /* + * Remove all attachments. + */ + for (final String key : attachments.keySet()) { + attachments.get(key).remove(); + } + attachments.clear(); } public void reset() { @@ -111,25 +240,26 @@ public class BukkitPermissions { this.updateAllPlayers(); } - private void registerEvents() { + /** + * @param player_join + * the player_join to set + */ + public void setPlayer_join(final boolean player_join) { - PluginManager manager = plugin.getServer().getPluginManager(); - - manager.registerEvents(new PlayerEvents(), plugin); - manager.registerEvents(new BukkitEvents(), plugin); + this.player_join = player_join; } - public void collectPermissions() { + /** + * force Bukkit to update every OnlinePlayers permissions. + */ + public void updateAllPlayers() { - registeredPermissions.clear(); - - for (Permission perm : Bukkit.getPluginManager().getPermissions()) { - registeredPermissions.put(perm.getName().toLowerCase(), perm); + for (final Player player : Bukkit.getServer().getOnlinePlayers()) { + updatePermissions(player); } - } - public void updatePermissions(Player player) { + public void updatePermissions(final Player player) { this.updatePermissions(player, null); } @@ -137,20 +267,20 @@ public class BukkitPermissions { /** * Push all permissions which are registered with GM for this player, on * this world to Bukkit and make it update for the child nodes. - * + * * @param player * @param world */ - public void updatePermissions(Player player, String world) { + public void updatePermissions(final Player player, String world) { if (player == null || !GroupManager.isLoaded()) { return; } - String name = player.getName(); + final String name = player.getName(); // Reset the User objects player reference. - User user = plugin.getWorldsHolder().getWorldData(player.getWorld().getName()).getUser(name); + final User user = plugin.getWorldsHolder().getWorldData(player.getWorld().getName()).getUser(name); if (user != null) user.updatePlayer(player); @@ -171,14 +301,14 @@ public class BukkitPermissions { // Add all permissions for this player (GM only) // child nodes will be calculated by Bukkit. List playerPermArray = new ArrayList(plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getAllPlayersPermissions(name, false)); - LinkedHashMap newPerms = new LinkedHashMap(); + final LinkedHashMap newPerms = new LinkedHashMap(); // Sort the perm list by parent/child, so it will push to superperms // correctly. playerPermArray = sort(playerPermArray); Boolean value = false; - for (String permission : playerPermArray) { + for (final String permission : playerPermArray) { value = (!permission.startsWith("-")); newPerms.put((value ? permission : permission.substring(1)), value); } @@ -201,7 +331,7 @@ public class BukkitPermissions { synchronized (attachment.getPermissible()) { @SuppressWarnings("unchecked") - Map orig = (Map) permissions.get(attachment); + final Map orig = (Map) permissions.get(attachment); // Clear the map (faster than removing the attachment and // recalculating) orig.clear(); @@ -211,39 +341,69 @@ public class BukkitPermissions { attachment.getPermissible().recalculatePermissions(); } - } catch (IllegalArgumentException e) { + } catch (final IllegalArgumentException e) { e.printStackTrace(); - } catch (IllegalAccessException e) { + } catch (final IllegalAccessException e) { e.printStackTrace(); } GroupManager.logger.finest("Attachment updated for: " + name); } + /** + * force Bukkit to update this Players permissions. + */ + public void updatePlayer(final Player player) { + + if (player != null) + this.updatePermissions(player, null); + } + + private void registerEvents() { + + final PluginManager manager = plugin.getServer().getPluginManager(); + + manager.registerEvents(new PlayerEvents(), plugin); + manager.registerEvents(new BukkitEvents(), plugin); + } + + /** + * Force remove any attachments + * + * @param player + */ + private void removeAttachment(final String playerName) { + + if (attachments.containsKey(playerName)) { + attachments.get(playerName).remove(); + attachments.remove(playerName); + } + } + /** * Sort a permission node list by parent/child - * + * * @param permList * @return List sorted for priority */ - private List sort(List permList) { + private List sort(final List permList) { - List result = new ArrayList(); + final List result = new ArrayList(); - for (String key : permList) { + for (final String key : permList) { /* * Ignore stupid plugins which add empty permission nodes. */ if (!key.isEmpty()) { - String a = key.charAt(0) == '-' ? key.substring(1) : key; - Map allchildren = GroupManager.BukkitPermissions.getAllChildren(a, new HashSet()); + final String a = key.charAt(0) == '-' ? key.substring(1) : key; + final Map allchildren = GroupManager.BukkitPermissions.getAllChildren(a, new HashSet()); if (allchildren != null) { - ListIterator itr = result.listIterator(); + final ListIterator itr = result.listIterator(); while (itr.hasNext()) { - String node = (String) itr.next(); - String b = node.charAt(0) == '-' ? node.substring(1) : node; + final String node = itr.next(); + final String b = node.charAt(0) == '-' ? node.substring(1) : node; // Insert the parent node before the child if (allchildren.containsKey(b)) { @@ -261,178 +421,45 @@ public class BukkitPermissions { return result; } - /** - * 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) { + protected class BukkitEvents implements Listener { - List perms = new ArrayList(); - - for (String key : registeredPermissions.keySet()) { - if (!perms.contains(key)) { - perms.add(key); - - if (includeChildren) { - Map children = getAllChildren(key, new HashSet()); - if (children != null) { - for (String node : children.keySet()) - if (!perms.contains(node)) - perms.add(node); - } - } - } + @EventHandler(priority = EventPriority.NORMAL) + public void onPluginDisable(final PluginDisableEvent event) { + collectPermissions(); + // updateAllPlayers(); } - 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, Set playerPermArray) { + @EventHandler(priority = EventPriority.NORMAL) + public void onPluginEnable(final PluginEnableEvent event) { - LinkedList stack = new LinkedList(); - Map alreadyVisited = new HashMap(); - stack.push(node); - alreadyVisited.put(node, true); + if (!GroupManager.isLoaded()) + return; - while (!stack.isEmpty()) { - String now = stack.pop(); - - Map children = getChildren(now); - - if ((children != null) && (!playerPermArray.contains("-" + now))) { - for (String childName : children.keySet()) { - if (!alreadyVisited.containsKey(childName)) { - stack.push(childName); - alreadyVisited.put(childName, children.get(childName)); - } - } - } + collectPermissions(); + updateAllPlayers(); } - alreadyVisited.remove(node); - if (!alreadyVisited.isEmpty()) - return alreadyVisited; - - return null; - } - - /** - * Returns a map of the child permissions (1 node deep) as registered with - * Bukkit. - * null is empty - * - * @param node - * @return Map of child permissions - */ - public Map getChildren(String node) { - - Permission perm = registeredPermissions.get(node.toLowerCase()); - if (perm == null) - return null; - - return perm.getChildren(); - - } - - /** - * List all effective permissions for this player. - * - * @param player - * @return List of permissions - */ - public List listPerms(Player player) { - - List perms = new ArrayList(); - - /* - * // All permissions registered with Bukkit for this player - * PermissionAttachment attachment = this.attachments.get(player); - * - * // List perms for this player perms.add("Attachment Permissions:"); - * for(Map.Entry entry : - * attachment.getPermissions().entrySet()){ perms.add(" " + - * entry.getKey() + " = " + entry.getValue()); } - */ - - perms.add("Effective Permissions:"); - for (PermissionAttachmentInfo info : player.getEffectivePermissions()) { - if (info.getValue() == true) - perms.add(" " + info.getPermission() + " = " + info.getValue()); - } - return perms; - } - - /** - * force Bukkit to update every OnlinePlayers permissions. - */ - public void updateAllPlayers() { - - for (Player player : Bukkit.getServer().getOnlinePlayers()) { - updatePermissions(player); - } - } - - /** - * force Bukkit to update this Players permissions. - */ - public void updatePlayer(Player player) { - - if (player != null) - this.updatePermissions(player, null); - } - - /** - * Force remove any attachments - * - * @param player - */ - private void removeAttachment(String playerName) { - - if (attachments.containsKey(playerName)) { - attachments.get(playerName).remove(); - attachments.remove(playerName); - } - } - - /** - * Remove all attachments in case of a restart or reload. - */ - public void removeAllAttachments() { - - /* - * Remove all attachments. - */ - for (String key : attachments.keySet()) { - attachments.get(key).remove(); - } - attachments.clear(); } /** * Player events tracked to cause Superperms updates - * + * * @author ElgarL - * + * */ protected class PlayerEvents implements Listener { @EventHandler(priority = EventPriority.LOWEST) - public void onPlayerJoin(PlayerJoinEvent event) { + public void onPlayerChangeWorld(final PlayerChangedWorldEvent event) { // has changed worlds + + updatePermissions(event.getPlayer(), event.getPlayer().getWorld().getName()); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerJoin(final PlayerJoinEvent event) { setPlayer_join(true); - Player player = event.getPlayer(); + final Player player = event.getPlayer(); GroupManager.logger.finest("Player Join event: " + player.getName()); @@ -450,22 +477,16 @@ public class BukkitPermissions { setPlayer_join(false); } - @EventHandler(priority = EventPriority.LOWEST) - public void onPlayerChangeWorld(PlayerChangedWorldEvent event) { // has changed worlds - - updatePermissions(event.getPlayer(), event.getPlayer().getWorld().getName()); - } - /* * Trigger at highest so we tidy up last. */ @EventHandler(priority = EventPriority.HIGHEST) - public void onPlayerQuit(PlayerQuitEvent event) { + public void onPlayerQuit(final PlayerQuitEvent event) { if (!GroupManager.isLoaded()) return; - Player player = event.getPlayer(); + final Player player = event.getPlayer(); /* * force remove any attachments as bukkit may not @@ -474,24 +495,4 @@ public class BukkitPermissions { } } - protected class BukkitEvents implements Listener { - - @EventHandler(priority = EventPriority.NORMAL) - public void onPluginEnable(PluginEnableEvent event) { - - if (!GroupManager.isLoaded()) - return; - - collectPermissions(); - updateAllPlayers(); - } - - @EventHandler(priority = EventPriority.NORMAL) - public void onPluginDisable(PluginDisableEvent event) { - - collectPermissions(); - // updateAllPlayers(); - } - } - }