1
0
mirror of https://github.com/essentials/Essentials.git synced 2025-08-15 11:04:29 +02:00

Merge remote branch 'remotes/origin/groupmanager'

This commit is contained in:
KHobbits
2012-02-13 17:24:32 +00:00
10 changed files with 300 additions and 132 deletions

View File

@@ -125,4 +125,17 @@ v 1.9:
- Fixed an infinite loop error when using '/manudel' on a logged in player. It caused setDefaultGroup to trigger a bukkit update when no GM User existed yet. - Fixed an infinite loop error when using '/manudel' on a logged in player. It caused setDefaultGroup to trigger a bukkit update when no GM User existed yet.
- do not allow inherited permissions to negate higher perms. - do not allow inherited permissions to negate higher perms.
- Fixed a bug when pushing superperms in the wrong order. - Fixed a bug when pushing superperms in the wrong order.
- Fix players retaining permissions when demoted. - Fix players retaining permissions when demoted.
- Auto sort permissions on load to speed up population of superperms.
- Negating a parent node after adding all nodes with * will now correctly remove all child nodes of that parent before populating superperms.
eg.
- '*'
- -vanish.*
- vanish.standard
- Track the 'onPlayerChangeWorld' event as some teleports seem to not be triggering a world move.
- Catch all errors in badly formatted groups.
- Fix a bug with getWorldData return the main world data for all mirrors, instead of the worlds parent data.
- Prevent getAllPlayersPermissions() processing a group more than once. Improves performance when using complex inheritance structures.
- Fix world mirroring so it correctly creates data files and data sources for partially mirrored worlds.
- Fixed world mirroring so it returns the correct data for the requested world.
- Change Service registration to register WorldsHolder instead of AnjoPermissionsHandler. This is the correct entry point for all data.

View File

@@ -158,7 +158,7 @@ public class GroupManager extends JavaPlugin {
System.out.println(pdfFile.getName() + " version " + pdfFile.getVersion() + " is enabled!"); System.out.println(pdfFile.getName() + " version " + pdfFile.getVersion() + " is enabled!");
// Register as a service // Register as a service
this.getServer().getServicesManager().register(AnjoPermissionsHandler.class, this.permissionHandler, this, ServicePriority.Lowest); this.getServer().getServicesManager().register(WorldsHolder.class, this.worldsHolder, this, ServicePriority.Lowest);
} }
public static boolean isLoaded() { public static boolean isLoaded() {
@@ -1485,7 +1485,7 @@ public class GroupManager extends JavaPlugin {
try { try {
worldsHolder.saveChanges(forced); worldsHolder.saveChanges(forced);
sender.sendMessage(ChatColor.YELLOW + " The changes were saved."); sender.sendMessage(ChatColor.YELLOW + " All changes were saved.");
} catch (IllegalStateException ex) { } catch (IllegalStateException ex) {
sender.sendMessage(ChatColor.RED + ex.getMessage()); sender.sendMessage(ChatColor.RED + ex.getMessage());
} }
@@ -1522,6 +1522,7 @@ public class GroupManager extends JavaPlugin {
} }
// WORKING // WORKING
config.load(); config.load();
globalGroups.load();
worldsHolder.mirrorSetUp(); worldsHolder.mirrorSetUp();
isLoaded = false; isLoaded = false;
@@ -1538,7 +1539,7 @@ public class GroupManager extends JavaPlugin {
sender.sendMessage("The request to world '" + auxString + "' was sent."); sender.sendMessage("The request to world '" + auxString + "' was sent.");
} else { } else {
worldsHolder.reloadAll(); worldsHolder.reloadAll();
sender.sendMessage(ChatColor.YELLOW + " The current world was reloaded."); sender.sendMessage(ChatColor.YELLOW + " All worlds were reloaded.");
} }
isLoaded = true; isLoaded = true;
@@ -1762,9 +1763,9 @@ public class GroupManager extends JavaPlugin {
dataHolder = worldsHolder.getWorldData(worldsHolder.getDefaultWorld().getName()); dataHolder = worldsHolder.getWorldData(worldsHolder.getDefaultWorld().getName());
permissionHandler = dataHolder.getPermissionsHandler(); permissionHandler = dataHolder.getPermissionsHandler();
selectedWorlds.put(sender, dataHolder.getName());
if ((dataHolder != null) && (permissionHandler != null)) { if ((dataHolder != null) && (permissionHandler != null)) {
selectedWorlds.put(sender, dataHolder.getName());
sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. Default world '" + worldsHolder.getDefaultWorld().getName() + "' selected."); sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. Default world '" + worldsHolder.getDefaultWorld().getName() + "' selected.");
return true; return true;
} }

View File

@@ -65,8 +65,19 @@ public abstract class DataUnit {
hash = 71 * hash + (this.name != null ? this.name.toLowerCase().hashCode() : 0); hash = 71 * hash + (this.name != null ? this.name.toLowerCase().hashCode() : 0);
return hash; return hash;
} }
/**
* Set the data source to point to a different worldDataHolder
*
* @param source
*/
public void setDataSource(WorldDataHolder source) {
this.dataSource = source;
}
/** /**
* Get the current worldDataHolder this object is pointing to
*
* @return the dataSource * @return the dataSource
*/ */
public WorldDataHolder getDataSource() { public WorldDataHolder getDataSource() {

View File

@@ -138,8 +138,8 @@ public class User extends DataUnit implements Cloneable {
String oldGroup = this.group; String oldGroup = this.group;
this.group = group.getName(); this.group = group.getName();
flagAsChanged(); flagAsChanged();
if (GroupManager.isLoaded() && (updatePerms)) { if (GroupManager.isLoaded()) {
if (!GroupManager.BukkitPermissions.isPlayer_join()) if (!GroupManager.BukkitPermissions.isPlayer_join() && (updatePerms))
GroupManager.BukkitPermissions.updatePlayer(getBukkitPlayer()); GroupManager.BukkitPermissions.updatePlayer(getBukkitPlayer());
// Do we notify of the group change? // Do we notify of the group change?

View File

@@ -9,15 +9,14 @@ import org.anjocaido.groupmanager.data.Group;
/** /**
* This container holds all Groups loaded from the relevant groupsFile.
*
* @author ElgarL * @author ElgarL
* *
*/ */
public class GroupsDataHolder { public class GroupsDataHolder {
/** private WorldDataHolder dataSource;
* Root World name this set of groups is associated with.
*/
private String name;
private Group defaultGroup = null; private Group defaultGroup = null;
private File groupsFile; private File groupsFile;
private boolean haveGroupsChanged = false; private boolean haveGroupsChanged = false;
@@ -33,16 +32,12 @@ public class GroupsDataHolder {
*/ */
protected GroupsDataHolder() { protected GroupsDataHolder() {
} }
protected void setWorldName(String worldName) { public void setDataSource(WorldDataHolder dataSource) {
name = worldName; this.dataSource = dataSource;
} //push this data source to the users, so they pull the correct groups data.
for (Group group : groups.values())
/** group.setDataSource(this.dataSource);
* @return the name
*/
public String getWorldName() {
return name;
} }
/** /**

View File

@@ -9,15 +9,14 @@ import org.anjocaido.groupmanager.data.User;
/** /**
* This container holds all Users loaded from the relevant usersFile.
*
* @author ElgarL * @author ElgarL
* *
*/ */
public class UsersDataHolder { public class UsersDataHolder {
/** private WorldDataHolder dataSource;
* Root World name this set of groups is associated with.
*/
private String name;
private File usersFile; private File usersFile;
private boolean haveUsersChanged = false; private boolean haveUsersChanged = false;
private long timeStampUsers = 0; private long timeStampUsers = 0;
@@ -32,19 +31,13 @@ public class UsersDataHolder {
*/ */
protected UsersDataHolder() { protected UsersDataHolder() {
} }
/**
* @param worldName
*/
public void setWorldName(String worldName) {
this.name = worldName;
}
/** public void setDataSource(WorldDataHolder dataSource) {
* @return the name this.dataSource = dataSource;
*/ //push this data source to the users, so they pull the correct groups data.
public String getWorldName() { for (User user : users.values())
return this.name; user.setDataSource(this.dataSource);
} }
/** /**

View File

@@ -36,8 +36,11 @@ import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.reader.UnicodeReader; import org.yaml.snakeyaml.reader.UnicodeReader;
/** /**
* * One instance of this should exist per world/mirror
* @author gabrielcouto * it contains all functions to manage these data sets
* and points to the relevant users and groups objects.
*
* @author gabrielcouto, ElgarL
*/ */
public class WorldDataHolder { public class WorldDataHolder {
@@ -80,6 +83,16 @@ public class WorldDataHolder {
//this.defaultGroup = defaultGroup; //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 * Search for a user. If it doesn't exist, create a new one with
@@ -445,13 +458,13 @@ public class WorldDataHolder {
//PROCESS GROUPS FILE //PROCESS GROUPS FILE
Map<String, List<String>> inheritance = new HashMap<String, List<String>>(); Map<String, List<String>> inheritance = new HashMap<String, List<String>>();
//try { try {
Map<String, Object> allGroupsNode = (Map<String, Object>) groupsRootDataNode.get("groups"); Map<String, Object> allGroupsNode = (Map<String, Object>) groupsRootDataNode.get("groups");
for (String groupKey : allGroupsNode.keySet()) { for (String groupKey : allGroupsNode.keySet()) {
Map<String, Object> thisGroupNode = (Map<String, Object>) allGroupsNode.get(groupKey); Map<String, Object> thisGroupNode = (Map<String, Object>) allGroupsNode.get(groupKey);
Group thisGrp = ph.createGroup(groupKey); Group thisGrp = ph.createGroup(groupKey);
if (thisGrp == null) { if (thisGrp == null) {
throw new IllegalArgumentException("I think this user was declared more than once: " + groupKey + " in file: " + groupsFile.getPath()); throw new IllegalArgumentException("I think this Group was declared more than once: " + groupKey + " in file: " + groupsFile.getPath());
} }
if (thisGroupNode.get("default") == null) { if (thisGroupNode.get("default") == null) {
thisGroupNode.put("default", false); thisGroupNode.put("default", false);
@@ -465,57 +478,72 @@ public class WorldDataHolder {
} }
//PERMISSIONS NODE //PERMISSIONS NODE
if (thisGroupNode.get("permissions") == null) { try {
thisGroupNode.put("permissions", new ArrayList<String>()); if (thisGroupNode.get("permissions") == null) {
} thisGroupNode.put("permissions", new ArrayList<String>());
if (thisGroupNode.get("permissions") instanceof List) { } else {
for (Object o : ((List) thisGroupNode.get("permissions"))) { if (thisGroupNode.get("permissions") instanceof List) {
try { for (Object o : ((List) thisGroupNode.get("permissions"))) {
thisGrp.addPermission(o.toString()); try {
} catch (NullPointerException e) { thisGrp.addPermission(o.toString());
// Ignore this entry as it's null. } catch (NullPointerException e) {
//throw new IllegalArgumentException("Invalid permission node in group: " + thisGrp.getName() + " in file: " + groupsFile.getPath()); // Ignore this entry as it's null.
} //throw new IllegalArgumentException("Invalid permission node in group: " + thisGrp.getName() + " in file: " + groupsFile.getPath());
} }
} else if (thisGroupNode.get("permissions") instanceof String) { }
thisGrp.addPermission((String) thisGroupNode.get("permissions")); } else if (thisGroupNode.get("permissions") instanceof String) {
} else { thisGrp.addPermission((String) thisGroupNode.get("permissions"));
throw new IllegalArgumentException("Unknown type of permissions node(Should be String or List<String>) for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath()); } else {
throw new IllegalArgumentException("Unknown type of permissions node(Should be String or List<String>) for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath());
}
thisGrp.sortPermissions();
}
} catch (Exception e) {
throw new IllegalArgumentException("Invalid formatting found in permissions section for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath());
} }
//INFO NODE //INFO NODE
if (thisGroupNode.get("info") instanceof Map) { try {
Map<String, Object> infoNode = (Map<String, Object>) thisGroupNode.get("info"); if (thisGroupNode.get("info") instanceof Map) {
if (infoNode != null) { Map<String, Object> infoNode = (Map<String, Object>) thisGroupNode.get("info");
thisGrp.setVariables(infoNode); if (infoNode != null) {
} thisGrp.setVariables(infoNode);
} else }
throw new IllegalArgumentException("Unknown entry found in Info section for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath()); } else
throw new IllegalArgumentException("Unknown entry found in Info section for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath());
} catch (Exception e1) {
throw new IllegalArgumentException("Invalid formatting found in info section for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath());
}
//END INFO NODE //END INFO NODE
if (thisGroupNode.get("inheritance") == null || thisGroupNode.get("inheritance") instanceof List) { try {
Object inheritNode = thisGroupNode.get("inheritance"); if (thisGroupNode.get("inheritance") == null || thisGroupNode.get("inheritance") instanceof List) {
if (inheritNode == null) { Object inheritNode = thisGroupNode.get("inheritance");
thisGroupNode.put("inheritance", new ArrayList<String>()); if (inheritNode == null) {
} else if (inheritNode instanceof List) { thisGroupNode.put("inheritance", new ArrayList<String>());
List<String> groupsInh = (List<String>) inheritNode; } else if (inheritNode instanceof List) {
for (String grp : groupsInh) { List<String> groupsInh = (List<String>) inheritNode;
if (inheritance.get(groupKey) == null) { for (String grp : groupsInh) {
List<String> thisInherits = new ArrayList<String>(); if (inheritance.get(groupKey) == null) {
inheritance.put(groupKey, thisInherits); List<String> thisInherits = new ArrayList<String>();
} inheritance.put(groupKey, thisInherits);
inheritance.get(groupKey).add(grp); }
inheritance.get(groupKey).add(grp);
}
} }
}else }
throw new IllegalArgumentException("Unknown entry found in inheritance section for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath()); }else
throw new IllegalArgumentException("Unknown entry found in inheritance section for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath());
} catch (Exception e2) {
throw new IllegalArgumentException("Invalid formatting found in inheritance section for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath());
}
} }
//} catch (Exception ex) { } catch (Exception ex) {
// ex.printStackTrace(); ex.printStackTrace();
// throw new IllegalArgumentException("Your Permissions config file is invalid. See console for details."); throw new IllegalArgumentException("Your " + groupsFile.getPath() + " file is invalid. See console for details.");
//} }
if (ph.getDefaultGroup() == null) { if (ph.getDefaultGroup() == null) {
throw new IllegalArgumentException("There was no Default Group declared in file: " + groupsFile.getPath()); throw new IllegalArgumentException("There was no Default Group declared in file: " + groupsFile.getPath());
} }
@@ -581,18 +609,20 @@ public class WorldDataHolder {
} }
if (thisUserNode.get("permissions") == null) { if (thisUserNode.get("permissions") == null) {
thisUserNode.put("permissions", new ArrayList<String>()); thisUserNode.put("permissions", new ArrayList<String>());
} } else {
if (thisUserNode.get("permissions") instanceof List) { if (thisUserNode.get("permissions") instanceof List) {
for (Object o : ((List) thisUserNode.get("permissions"))) { for (Object o : ((List) thisUserNode.get("permissions"))) {
thisUser.addPermission(o.toString()); thisUser.addPermission(o.toString());
} }
} else if (thisUserNode.get("permissions") instanceof String) { } else if (thisUserNode.get("permissions") instanceof String) {
try { try {
thisUser.addPermission(thisUserNode.get("permissions").toString()); thisUser.addPermission(thisUserNode.get("permissions").toString());
} catch (NullPointerException e) { } catch (NullPointerException e) {
// Ignore this entry as it's null. // Ignore this entry as it's null.
//throw new IllegalArgumentException("Invalid permission node for user: " + thisUser.getName() + " in file: " + UserFile.getPath()); //throw new IllegalArgumentException("Invalid permission node for user: " + thisUser.getName() + " in file: " + UserFile.getPath());
} }
}
thisUser.sortPermissions();
} }
//SUBGROUPS LOADING //SUBGROUPS LOADING

View File

@@ -10,6 +10,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@@ -45,7 +46,7 @@ public class WorldsHolder {
private Map<String, String> mirrorsGroup = new HashMap<String, String>(); private Map<String, String> mirrorsGroup = new HashMap<String, String>();
private Map<String, String> mirrorsUser = new HashMap<String, String>(); private Map<String, String> mirrorsUser = new HashMap<String, String>();
private OverloadedWorldHolder defaultWorld; //private OverloadedWorldHolder defaultWorld;
private String serverDefaultWorldName; private String serverDefaultWorldName;
private GroupManager plugin; private GroupManager plugin;
private File worldsFolder; private File worldsFolder;
@@ -59,7 +60,7 @@ public class WorldsHolder {
// Setup folders and check files exist for the primary world // Setup folders and check files exist for the primary world
verifyFirstRun(); verifyFirstRun();
initialLoad(); initialLoad();
if (defaultWorld == null) { if (serverDefaultWorldName == null) {
throw new IllegalStateException("There is no default group! OMG!"); throw new IllegalStateException("There is no default group! OMG!");
} }
} }
@@ -76,7 +77,7 @@ public class WorldsHolder {
private void initialWorldLoading() { private void initialWorldLoading() {
//Load the default world //Load the default world
loadWorld(serverDefaultWorldName); loadWorld(serverDefaultWorldName);
defaultWorld = worldsData.get(serverDefaultWorldName); //defaultWorld = getUpdatedWorldData(serverDefaultWorldName);
} }
private void loadAllSearchedWorlds() { private void loadAllSearchedWorlds() {
@@ -117,6 +118,8 @@ public class WorldsHolder {
mirrorsGroup.clear(); mirrorsGroup.clear();
mirrorsUser.clear(); mirrorsUser.clear();
Map<String, Object> mirrorsMap = plugin.getGMConfig().getMirrorsMap(); Map<String, Object> mirrorsMap = plugin.getGMConfig().getMirrorsMap();
HashSet<String> mirroredWorlds = new HashSet<String>();
if (mirrorsMap != null) { if (mirrorsMap != null) {
for (String source : mirrorsMap.keySet()) { for (String source : mirrorsMap.keySet()) {
@@ -140,6 +143,10 @@ public class WorldsHolder {
} }
mirrorsGroup.put(world, getWorldData(source).getName()); mirrorsGroup.put(world, getWorldData(source).getName());
mirrorsUser.put(world, getWorldData(source).getName()); mirrorsUser.put(world, getWorldData(source).getName());
// Track this world so we can create a datasource for it later
mirroredWorlds.add(o.toString());
} else } else
GroupManager.logger.log(Level.WARNING, "Mirroring error with " + o.toString() + ". Recursive loop detected!"); GroupManager.logger.log(Level.WARNING, "Mirroring error with " + o.toString() + ". Recursive loop detected!");
} }
@@ -171,11 +178,13 @@ public class WorldsHolder {
if (type.equals("users")) if (type.equals("users"))
mirrorsUser.put(key.toLowerCase(), getWorldData(source).getName()); mirrorsUser.put(key.toLowerCase(), getWorldData(source).getName());
} }
// Track this world so we can create a datasource for it later
mirroredWorlds.add(key);
} else } else
GroupManager.logger.log(Level.WARNING, "Mirroring error with " + key + ". Recursive loop detected!"); GroupManager.logger.log(Level.WARNING, "Mirroring error with " + key + ". Recursive loop detected!");
} else { } else {
throw new IllegalStateException("Unknown mirroring format for " + key); throw new IllegalStateException("Unknown mirroring format for " + key);
} }
@@ -183,6 +192,14 @@ public class WorldsHolder {
} }
} }
} }
// Create a datasource for any worlds not already loaded
for (String world : mirroredWorlds){
if (!worldsData.containsKey(world.toLowerCase())) {
setupWorldFolder(world);
loadWorld(world, true);
}
}
} }
} }
@@ -320,7 +337,8 @@ public class WorldsHolder {
* If the world is not on the worlds list, returns the default world * If the world is not on the worlds list, returns the default world
* holder. * holder.
* *
* Mirrors return original world data. * Mirrors return their parent world data.
* If no mirroring data it returns the default world.
* *
* @param worldName * @param worldName
* @return OverloadedWorldHolder * @return OverloadedWorldHolder
@@ -328,12 +346,55 @@ public class WorldsHolder {
public OverloadedWorldHolder getWorldData(String worldName) { public OverloadedWorldHolder getWorldData(String worldName) {
String worldNameLowered = worldName.toLowerCase(); String worldNameLowered = worldName.toLowerCase();
if (worldsData.containsKey(worldNameLowered)) // Find this worlds data
return worldsData.get(worldNameLowered); if (worldsData.containsKey(worldNameLowered)) {
String usersMirror = mirrorsUser.get(worldNameLowered);
String groupsMirror = mirrorsGroup.get(worldNameLowered);
if (usersMirror != null) {
// If both are mirrored
if (groupsMirror != null) {
// if the data sources are the same, return the parent
if (usersMirror == groupsMirror)
return getUpdatedWorldData(usersMirror.toLowerCase());
// Both data sources are mirrors, but they are from different parents
// so we return the actual data object.
return getUpdatedWorldData(worldNameLowered);
}
// Groups isn't a mirror so return this this worlds data source
return getUpdatedWorldData(worldNameLowered);
}
// users isn't mirrored so we need to return this worlds data source
return getUpdatedWorldData(worldNameLowered);
}
// Oddly no data source was found for this world so return the default.
GroupManager.logger.finest("Requested world " + worldName + " not found or badly mirrored. Returning default world..."); GroupManager.logger.finest("Requested world " + worldName + " not found or badly mirrored. Returning default world...");
return getDefaultWorld(); return getDefaultWorld();
} }
/**
* Get the requested world data and update it's dataSource to be relevant for this world
*
* @param worldName
* @return updated world holder
*/
private OverloadedWorldHolder getUpdatedWorldData(String worldName) {
if (worldsData.containsKey(worldName.toLowerCase())) {
OverloadedWorldHolder data = worldsData.get(worldName.toLowerCase());
data.updateDataSource();
return data;
}
return null;
}
/** /**
* Do a matching of playerName, if its found only one player, do * Do a matching of playerName, if its found only one player, do
@@ -353,6 +414,7 @@ public class WorldsHolder {
/** /**
* Retrieves the field player.getWorld().getName() and do * Retrieves the field player.getWorld().getName() and do
* getWorld(worldName) * getWorld(worldName)
*
* @param player * @param player
* @return OverloadedWorldHolder * @return OverloadedWorldHolder
*/ */
@@ -476,18 +538,29 @@ public class WorldsHolder {
} }
/** /**
* Wrapper for LoadWorld(String,Boolean) for backwards compatibility
*
* Load a world from file. * Load a world from file.
* If it already been loaded, summon reload method from dataHolder. * If it already been loaded, summon reload method from dataHolder.
* @param worldName * @param worldName
*/ */
public void loadWorld(String worldName) { public void loadWorld(String worldName) {
loadWorld(worldName, false);
}
/**
* Load a world from file.
* If it already been loaded, summon reload method from dataHolder.
* @param worldName
*/
public void loadWorld(String worldName, Boolean isMirror) {
if (worldsData.containsKey(worldName.toLowerCase())) { if (worldsData.containsKey(worldName.toLowerCase())) {
worldsData.get(worldName.toLowerCase()).reload(); worldsData.get(worldName.toLowerCase()).reload();
return; return;
} }
GroupManager.logger.finest("Trying to load world " + worldName + "..."); GroupManager.logger.finest("Trying to load world " + worldName + "...");
File thisWorldFolder = new File(worldsFolder, worldName); File thisWorldFolder = new File(worldsFolder, worldName);
if (thisWorldFolder.exists() && thisWorldFolder.isDirectory()) { if ((isMirror) || (thisWorldFolder.exists() && thisWorldFolder.isDirectory())) {
// Setup file handles, if not mirrored // Setup file handles, if not mirrored
File groupsFile = (mirrorsGroup.containsKey(worldName.toLowerCase()))? null : new File(thisWorldFolder, "groups.yml"); File groupsFile = (mirrorsGroup.containsKey(worldName.toLowerCase()))? null : new File(thisWorldFolder, "groups.yml");
@@ -564,17 +637,43 @@ public class WorldsHolder {
* @return the defaultWorld * @return the defaultWorld
*/ */
public OverloadedWorldHolder getDefaultWorld() { public OverloadedWorldHolder getDefaultWorld() {
return defaultWorld; return getUpdatedWorldData(serverDefaultWorldName);
} }
/** /**
* Returns all physically loaded worlds. * Returns all physically loaded worlds which have at least
* one of their own data sets for users or groups.
*
* @return ArrayList<OverloadedWorldHolder> of all loaded worlds * @return ArrayList<OverloadedWorldHolder> of all loaded worlds
*/ */
public ArrayList<OverloadedWorldHolder> allWorldsDataList() { public ArrayList<OverloadedWorldHolder> allWorldsDataList() {
ArrayList<OverloadedWorldHolder> list = new ArrayList<OverloadedWorldHolder>(); ArrayList<OverloadedWorldHolder> list = new ArrayList<OverloadedWorldHolder>();
for (OverloadedWorldHolder data : worldsData.values()) { for (OverloadedWorldHolder data : worldsData.values()) {
if (!list.contains(data)) { if ((!list.contains(data)) && (!mirrorsGroup.containsKey(data.getName().toLowerCase()) || !mirrorsUser.containsKey(data.getName().toLowerCase()))) {
String worldNameLowered = data.getName().toLowerCase();
String usersMirror = mirrorsUser.get(worldNameLowered);
String groupsMirror = mirrorsGroup.get(worldNameLowered);
// is users mirrored?
if (usersMirror != null) {
// If both are mirrored
if (groupsMirror != null) {
// if the data sources are the same, return the parent
if (usersMirror == groupsMirror) {
if (!list.contains(usersMirror.toLowerCase()))
list.add(worldsData.get(usersMirror.toLowerCase()));
continue;
}
// Both data sources are mirrors, but they are from different parents
// so fall through to add the actual data object.
}
// Groups isn't a mirror so fall through to add this this worlds data source
}
// users isn't mirrored so we need to add this worlds data source
list.add(data); list.add(data);
} }
} }

View File

@@ -121,27 +121,34 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface {
// Add the players own permissions. // Add the players own permissions.
playerPermArray.addAll(populatePerms(ph.getUser(userName).getPermissionList(), includeChildren)); playerPermArray.addAll(populatePerms(ph.getUser(userName).getPermissionList(), includeChildren));
ArrayList<String> alreadyProcessed = new ArrayList<String>();
// fetch all group permissions // fetch all group permissions
for (String group : getGroups(userName)) { for (String group : getGroups(userName)) {
Set<String> groupPermArray = new HashSet<String>(); // Don't process a group more than once.
if (!alreadyProcessed.contains(group)) {
if (group.startsWith("g:") && GroupManager.getGlobalGroups().hasGroup(group)) { alreadyProcessed.add(group);
// GlobalGroups
groupPermArray = populatePerms(GroupManager.getGlobalGroups().getGroupsPermissions(group), includeChildren);
} else { Set<String> groupPermArray = new HashSet<String>();
// World Groups
groupPermArray = populatePerms(ph.getGroup(group).getPermissionList(), includeChildren); if (group.startsWith("g:") && GroupManager.getGlobalGroups().hasGroup(group)) {
} // GlobalGroups
groupPermArray = populatePerms(GroupManager.getGlobalGroups().getGroupsPermissions(group), includeChildren);
// Add all group permissions, unless negated by earlier permissions.
for (String perm : groupPermArray) { } else {
boolean negated = (perm.startsWith("-")); // World Groups
// Perm doesn't already exists and there is no negation for it groupPermArray = populatePerms(ph.getGroup(group).getPermissionList(), includeChildren);
// 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) && !playerPermArray.contains("-" + perm))
|| (negated && !playerPermArray.contains(perm.substring(1)))) // Add all group permissions, unless negated by earlier permissions.
playerPermArray.add(perm); for (String perm : groupPermArray) {
boolean negated = (perm.startsWith("-"));
// 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) && !playerPermArray.contains("-" + perm))
|| (negated && !playerPermArray.contains(perm.substring(1))))
playerPermArray.add(perm);
}
} }
} }
@@ -153,15 +160,23 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface {
private Set<String> populatePerms (List<String> perms, boolean includeChildren) { private Set<String> populatePerms (List<String> perms, boolean includeChildren) {
Set<String> permArray = new HashSet<String>(); Set<String> permArray = new HashSet<String>();
Boolean allPerms = false;
// Allow * node to populate ALL perms in Bukkit. // Allow * node to populate ALL permissions to Bukkit.
if (perms.contains("*")) { if (perms.contains("*")) {
permArray.addAll(GroupManager.BukkitPermissions.getAllRegisteredPermissions(includeChildren)); permArray.addAll(GroupManager.BukkitPermissions.getAllRegisteredPermissions(includeChildren));
allPerms = true;
} }
for (String perm : perms) { for (String perm : perms) {
if (!perm.equalsIgnoreCase("*")) { if (!perm.equalsIgnoreCase("*")) {
/**
* all permission sets are passed here pre-sorted, alphabetically.
* This means negated nodes will be processed before all permissions
* other than *.
*/
boolean negated = false; boolean negated = false;
if (perm.startsWith("-")) if (perm.startsWith("-"))
negated = true; negated = true;
@@ -172,12 +187,17 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface {
if ((negated) && (permArray.contains(perm.substring(1)))) if ((negated) && (permArray.contains(perm.substring(1))))
permArray.remove(perm.substring(1)); permArray.remove(perm.substring(1));
if (includeChildren) { /**
* 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<String, Boolean> children = GroupManager.BukkitPermissions.getAllChildren((negated ? perm.substring(1) : perm), new HashSet<String>()); Map<String, Boolean> children = GroupManager.BukkitPermissions.getAllChildren((negated ? perm.substring(1) : perm), new HashSet<String>());
if (children != null) { if (children != null) {
if (negated) { if (negated || (negated && allPerms)) {
// Remove children of negated nodes // Remove children of negated nodes
for (String child : children.keySet()) for (String child : children.keySet())
@@ -185,7 +205,7 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface {
if (permArray.contains(child)) if (permArray.contains(child))
permArray.remove(child); permArray.remove(child);
} else { } else if (!negated){
// Add child nodes // Add child nodes
for (String child : children.keySet()) for (String child : children.keySet())

View File

@@ -34,6 +34,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerPortalEvent; import org.bukkit.event.player.PlayerPortalEvent;
@@ -358,6 +359,11 @@ public class BukkitPermissions {
} }
setPlayer_join(false); setPlayer_join(false);
} }
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerChangeWorld(PlayerChangedWorldEvent event) { // will portal into another world
updatePermissions(event.getPlayer(), event.getPlayer().getWorld().getName());
}
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
public void onPlayerPortal(PlayerPortalEvent event) { // will portal into another world public void onPlayerPortal(PlayerPortalEvent event) { // will portal into another world