diff options
Diffstat (limited to 'EssentialsGroupManager')
14 files changed, 366 insertions, 214 deletions
diff --git a/EssentialsGroupManager/.project b/EssentialsGroupManager/.project index 6ad74b347..c0e5a6f5e 100644 --- a/EssentialsGroupManager/.project +++ b/EssentialsGroupManager/.project @@ -10,6 +10,16 @@ <arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
+ <triggers>full,incremental,</triggers>
+ <arguments>
+ <dictionary>
+ <key>LaunchConfigHandle</key>
+ <value><project>/.externalToolBuilders/GroupManager.launch</value>
+ </dictionary>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
diff --git a/EssentialsGroupManager/src/Changelog.txt b/EssentialsGroupManager/src/Changelog.txt index ef9a3a408..31d40413f 100644 --- a/EssentialsGroupManager/src/Changelog.txt +++ b/EssentialsGroupManager/src/Changelog.txt @@ -90,7 +90,7 @@ v 1.7: v 1.8:
- Changed ServicesManager registration to lowest from normal.
- Fixed 'manucheckp' returning a null for the searched node when it's a group/subgroup.
- - manpromote and mandemote now correctly send the notification to the console if the command was issued there.
+ - 'manpromote' and 'mandemote' now correctly send the notification to the console if the command was issued there.
- Expanded GlobalGroups.yml and Groups.yml to include Towny permissions.
- Delayed GroupManager events so Superperms will be fully updated before plugins receive the events.
- Changed the way events are raised to prevent variable corruption.
@@ -124,4 +124,21 @@ v 1.9: - Trap errors in fetching the mirrors map.
- 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.
- - Fixed a bug when pushing superperms in the wrong order.
\ No newline at end of file + - Fixed a bug when pushing superperms in the wrong order.
+ - 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.
+ - Depreciate PlayerTeleportEvent, PlayerRespawnEvent and PlayerPortalEvent as it's all handled in PlayerChangedWorldEvent.
+ This also means we no longer update permissions before we change worlds.
+ - A command of '/manload' with no world arguments now performs a full reload of GM.
\ No newline at end of file diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java index c0ed77adc..d8d151200 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java @@ -25,7 +25,10 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import org.anjocaido.groupmanager.dataholder.worlds.WorldsHolder; +import org.anjocaido.groupmanager.events.GMSystemEvent; import org.anjocaido.groupmanager.events.GMWorldListener; +import org.anjocaido.groupmanager.events.GroupManagerEventHandler; +import org.anjocaido.groupmanager.events.GMGroupEvent.Action; import org.anjocaido.groupmanager.utils.GMLoggerHandler; import org.anjocaido.groupmanager.utils.PermissionCheckResult; import org.anjocaido.groupmanager.utils.Tasks; @@ -158,7 +161,7 @@ public class GroupManager extends JavaPlugin { System.out.println(pdfFile.getName() + " version " + pdfFile.getVersion() + " is enabled!"); // 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() { @@ -415,9 +418,9 @@ public class GroupManager extends JavaPlugin { if (!sender.hasPermission("groupmanager.notify.other") || (isConsole)) sender.sendMessage(ChatColor.YELLOW + "You changed player '" + auxUser.getName() + "' group to '" + auxGroup.getName() + "'."); - targetPlayer = this.getServer().getPlayer(auxUser.getName()); - if (targetPlayer != null) - BukkitPermissions.updatePermissions(targetPlayer); + //targetPlayer = this.getServer().getPlayer(auxUser.getName()); + //if (targetPlayer != null) + // BukkitPermissions.updatePermissions(targetPlayer); return true; // break; @@ -450,6 +453,7 @@ public class GroupManager extends JavaPlugin { dataHolder.removeUser(auxUser.getName()); sender.sendMessage(ChatColor.YELLOW + "You changed player '" + auxUser.getName() + "' to default settings."); + // If the player is online, this will create new data for the user. targetPlayer = this.getServer().getPlayer(auxUser.getName()); if (targetPlayer != null) BukkitPermissions.updatePermissions(targetPlayer); @@ -494,9 +498,9 @@ public class GroupManager extends JavaPlugin { else sender.sendMessage(ChatColor.RED + "The subgroup '" + auxGroup.getName() + "' is already available to '" + auxUser.getName() + "'."); - targetPlayer = this.getServer().getPlayer(auxUser.getName()); - if (targetPlayer != null) - BukkitPermissions.updatePermissions(targetPlayer); + //targetPlayer = this.getServer().getPlayer(auxUser.getName()); + //if (targetPlayer != null) + // BukkitPermissions.updatePermissions(targetPlayer); return true; case manudelsub: @@ -534,9 +538,9 @@ public class GroupManager extends JavaPlugin { auxUser.removeSubGroup(auxGroup); sender.sendMessage(ChatColor.YELLOW + "You removed subgroup '" + auxGroup.getName() + "' from player '" + auxUser.getName() + "' list."); - targetPlayer = this.getServer().getPlayer(auxUser.getName()); - if (targetPlayer != null) - BukkitPermissions.updatePermissions(targetPlayer); + //targetPlayer = this.getServer().getPlayer(auxUser.getName()); + //if (targetPlayer != null) + // BukkitPermissions.updatePermissions(targetPlayer); return true; case mangadd: @@ -1484,14 +1488,16 @@ public class GroupManager extends JavaPlugin { try { worldsHolder.saveChanges(forced); - sender.sendMessage(ChatColor.YELLOW + " The changes were saved."); + sender.sendMessage(ChatColor.YELLOW + " All changes were saved."); } catch (IllegalStateException ex) { sender.sendMessage(ChatColor.RED + ex.getMessage()); } return true; case manload: - // THIS CASE DONT NEED SENDER + /** + * Attempt to reload a specific world + */ if (args.length > 0) { auxString = ""; for (int i = 0; i < args.length; i++) { @@ -1501,50 +1507,34 @@ public class GroupManager extends JavaPlugin { } } - isLoaded = false; // Disable Bukkit Perms update + isLoaded = false; // Disable Bukkit Perms update and event triggers globalGroups.load(); worldsHolder.loadWorld(auxString); - sender.sendMessage("The request to world '" + auxString + "' was sent."); + sender.sendMessage("The request to reload world '" + auxString + "' was attempted."); isLoaded = true; BukkitPermissions.updateAllPlayers(); - return true; - } - // VALIDANDO ESTADO DO SENDER - if (dataHolder == null || permissionHandler == null) { - if (!setDefaultWorldHandler(sender)) - return true; - } - // WORKING - config.load(); - worldsHolder.mirrorSetUp(); - - isLoaded = false; - - if (args.length > 0) { - auxString = ""; - for (int i = 0; i < args.length; i++) { - auxString += args[i]; - if ((i + 1) < args.length) { - auxString += " "; - } - } - worldsHolder.loadWorld(auxString); - sender.sendMessage("The request to world '" + auxString + "' was sent."); } else { - worldsHolder.reloadAll(); - sender.sendMessage(ChatColor.YELLOW + " The current world was reloaded."); + + /** + * Reload all settings and data as no world was specified. + */ + onDisable(); + onEnable(); } - - isLoaded = true; - - BukkitPermissions.updateAllPlayers(); + + /** + * Fire an event as none will have been triggered in the reload. + */ + if (GroupManager.isLoaded()) + GroupManagerEventHandler.callEvent(GMSystemEvent.Action.RELOADED); return true; + case listgroups: // VALIDANDO ESTADO DO SENDER if (dataHolder == null || permissionHandler == null) { @@ -1614,9 +1604,9 @@ public class GroupManager extends JavaPlugin { if (!sender.hasPermission("groupmanager.notify.other") || (isConsole)) sender.sendMessage(ChatColor.YELLOW + "You changed " + auxUser.getName() + " group to " + auxGroup.getName() + "."); - targetPlayer = this.getServer().getPlayer(auxUser.getName()); - if (targetPlayer != null) - BukkitPermissions.updatePermissions(targetPlayer); + //targetPlayer = this.getServer().getPlayer(auxUser.getName()); + //if (targetPlayer != null) + // BukkitPermissions.updatePermissions(targetPlayer); return true; // break; @@ -1670,9 +1660,9 @@ public class GroupManager extends JavaPlugin { if (!sender.hasPermission("groupmanager.notify.other") || (isConsole)) sender.sendMessage(ChatColor.YELLOW + "You changed " + auxUser.getName() + " group to " + auxGroup.getName() + "."); - targetPlayer = this.getServer().getPlayer(auxUser.getName()); - if (targetPlayer != null) - BukkitPermissions.updatePermissions(targetPlayer); + //targetPlayer = this.getServer().getPlayer(auxUser.getName()); + //if (targetPlayer != null) + // BukkitPermissions.updatePermissions(targetPlayer); return true; // break; @@ -1761,9 +1751,9 @@ public class GroupManager extends JavaPlugin { dataHolder = worldsHolder.getWorldData(worldsHolder.getDefaultWorld().getName()); permissionHandler = dataHolder.getPermissionsHandler(); - selectedWorlds.put(sender, dataHolder.getName()); 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."); return true; } diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/DataUnit.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/DataUnit.java index a35b5aeee..e3250a1c1 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/DataUnit.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/DataUnit.java @@ -65,8 +65,19 @@ public abstract class DataUnit { hash = 71 * hash + (this.name != null ? this.name.toLowerCase().hashCode() : 0); 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 */ public WorldDataHolder getDataSource() { diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/User.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/User.java index 980b0846c..30fe3f709 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/User.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/User.java @@ -138,8 +138,8 @@ public class User extends DataUnit implements Cloneable { String oldGroup = this.group; this.group = group.getName(); flagAsChanged(); - if (GroupManager.isLoaded() && (updatePerms)) { - if (!GroupManager.BukkitPermissions.isPlayer_join()) + if (GroupManager.isLoaded()) { + if (!GroupManager.BukkitPermissions.isPlayer_join() && (updatePerms)) GroupManager.BukkitPermissions.updatePlayer(getBukkitPlayer()); // Do we notify of the group change? diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/GroupsDataHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/GroupsDataHolder.java index 4fc819245..5d681013e 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/GroupsDataHolder.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/GroupsDataHolder.java @@ -9,15 +9,14 @@ import org.anjocaido.groupmanager.data.Group; /**
+ * This container holds all Groups loaded from the relevant groupsFile.
+ *
* @author ElgarL
*
*/
public class GroupsDataHolder {
- /**
- * Root World name this set of groups is associated with.
- */
- private String name;
+ private WorldDataHolder dataSource;
private Group defaultGroup = null;
private File groupsFile;
private boolean haveGroupsChanged = false;
@@ -33,16 +32,12 @@ public class GroupsDataHolder { */
protected GroupsDataHolder() {
}
-
- protected void setWorldName(String worldName) {
- name = worldName;
- }
-
- /**
- * @return the name
- */
- public String getWorldName() {
- return name;
+
+ public void setDataSource(WorldDataHolder dataSource) {
+ 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);
}
/**
diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/UsersDataHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/UsersDataHolder.java index 37e1c4b43..fa2ccaf84 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/UsersDataHolder.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/UsersDataHolder.java @@ -9,15 +9,14 @@ import org.anjocaido.groupmanager.data.User; /**
+ * This container holds all Users loaded from the relevant usersFile.
+ *
* @author ElgarL
*
*/
public class UsersDataHolder {
- /**
- * Root World name this set of groups is associated with.
- */
- private String name;
+ private WorldDataHolder dataSource;
private File usersFile;
private boolean haveUsersChanged = false;
private long timeStampUsers = 0;
@@ -32,19 +31,13 @@ public class UsersDataHolder { */
protected UsersDataHolder() {
}
-
- /**
- * @param worldName
- */
- public void setWorldName(String worldName) {
- this.name = worldName;
- }
- /**
- * @return the name
- */
- public String getWorldName() {
- return this.name;
+ public void setDataSource(WorldDataHolder dataSource) {
+ this.dataSource = dataSource;
+ //push this data source to the users, so they pull the correct groups data.
+ for (User user : users.values())
+ user.setDataSource(this.dataSource);
+
}
/**
diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java index 3cbfbd50b..e766b6c78 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java @@ -36,8 +36,11 @@ import org.yaml.snakeyaml.constructor.SafeConstructor; import org.yaml.snakeyaml.reader.UnicodeReader; /** - * - * @author gabrielcouto + * 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 { @@ -80,6 +83,16 @@ 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 @@ -445,13 +458,13 @@ public class WorldDataHolder { //PROCESS GROUPS FILE Map<String, List<String>> inheritance = new HashMap<String, List<String>>(); - //try { + try { Map<String, Object> allGroupsNode = (Map<String, Object>) groupsRootDataNode.get("groups"); for (String groupKey : allGroupsNode.keySet()) { Map<String, Object> thisGroupNode = (Map<String, Object>) allGroupsNode.get(groupKey); Group thisGrp = ph.createGroup(groupKey); 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) { thisGroupNode.put("default", false); @@ -465,57 +478,72 @@ public class WorldDataHolder { } //PERMISSIONS NODE - if (thisGroupNode.get("permissions") == null) { - thisGroupNode.put("permissions", new ArrayList<String>()); - } - if (thisGroupNode.get("permissions") instanceof List) { - for (Object o : ((List) thisGroupNode.get("permissions"))) { - try { - thisGrp.addPermission(o.toString()); - } catch (NullPointerException e) { - // 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 { - throw new IllegalArgumentException("Unknown type of permissions node(Should be String or List<String>) for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath()); + try { + if (thisGroupNode.get("permissions") == null) { + thisGroupNode.put("permissions", new ArrayList<String>()); + } else { + if (thisGroupNode.get("permissions") instanceof List) { + for (Object o : ((List) thisGroupNode.get("permissions"))) { + try { + thisGrp.addPermission(o.toString()); + } catch (NullPointerException e) { + // 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 { + 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 - if (thisGroupNode.get("info") instanceof Map) { - Map<String, Object> infoNode = (Map<String, Object>) thisGroupNode.get("info"); - if (infoNode != null) { - thisGrp.setVariables(infoNode); - } - } else - throw new IllegalArgumentException("Unknown entry found in Info section for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath()); + try { + if (thisGroupNode.get("info") instanceof Map) { + Map<String, Object> infoNode = (Map<String, Object>) thisGroupNode.get("info"); + if (infoNode != null) { + thisGrp.setVariables(infoNode); + } + } 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 - if (thisGroupNode.get("inheritance") == null || thisGroupNode.get("inheritance") instanceof List) { - Object inheritNode = thisGroupNode.get("inheritance"); - if (inheritNode == null) { - thisGroupNode.put("inheritance", new ArrayList<String>()); - } else if (inheritNode instanceof List) { - List<String> groupsInh = (List<String>) inheritNode; - for (String grp : groupsInh) { - if (inheritance.get(groupKey) == null) { - List<String> thisInherits = new ArrayList<String>(); - inheritance.put(groupKey, thisInherits); - } - inheritance.get(groupKey).add(grp); - - } - } - }else - throw new IllegalArgumentException("Unknown entry found in inheritance section for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath()); + try { + if (thisGroupNode.get("inheritance") == null || thisGroupNode.get("inheritance") instanceof List) { + Object inheritNode = thisGroupNode.get("inheritance"); + if (inheritNode == null) { + thisGroupNode.put("inheritance", new ArrayList<String>()); + } else if (inheritNode instanceof List) { + List<String> groupsInh = (List<String>) inheritNode; + for (String grp : groupsInh) { + if (inheritance.get(groupKey) == null) { + List<String> thisInherits = new ArrayList<String>(); + inheritance.put(groupKey, thisInherits); + } + inheritance.get(groupKey).add(grp); + + } + } + }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) { - // ex.printStackTrace(); - // throw new IllegalArgumentException("Your Permissions config file is invalid. See console for details."); - //} + } catch (Exception ex) { + ex.printStackTrace(); + throw new IllegalArgumentException("Your " + groupsFile.getPath() + " file is invalid. See console for details."); + } + if (ph.getDefaultGroup() == null) { 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) { thisUserNode.put("permissions", new ArrayList<String>()); - } - if (thisUserNode.get("permissions") instanceof List) { - for (Object o : ((List) thisUserNode.get("permissions"))) { - thisUser.addPermission(o.toString()); - } - } else if (thisUserNode.get("permissions") instanceof String) { - try { - thisUser.addPermission(thisUserNode.get("permissions").toString()); - } catch (NullPointerException e) { - // Ignore this entry as it's null. - //throw new IllegalArgumentException("Invalid permission node for user: " + thisUser.getName() + " in file: " + UserFile.getPath()); - } + } else { + if (thisUserNode.get("permissions") instanceof List) { + for (Object o : ((List) thisUserNode.get("permissions"))) { + thisUser.addPermission(o.toString()); + } + } else if (thisUserNode.get("permissions") instanceof String) { + try { + thisUser.addPermission(thisUserNode.get("permissions").toString()); + } catch (NullPointerException e) { + // Ignore this entry as it's null. + //throw new IllegalArgumentException("Invalid permission node for user: " + thisUser.getName() + " in file: " + UserFile.getPath()); + } + } + thisUser.sortPermissions(); } //SUBGROUPS LOADING @@ -826,7 +856,7 @@ public class WorldDataHolder { PluginManager pm = server.getPluginManager(); Plugin[] plugins = pm.getPlugins(); for (int i = 0; i < plugins.length; i++) { - plugins[i].getConfiguration().load(); + //plugins[i].getConfiguration().load(); try { plugins[i].getClass().getMethod("setupPermissions").invoke(plugins[i]); } catch (Exception ex) { diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java index 686a5495d..e72118468 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java @@ -10,6 +10,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; @@ -45,7 +46,7 @@ public class WorldsHolder { private Map<String, String> mirrorsGroup = new HashMap<String, String>(); private Map<String, String> mirrorsUser = new HashMap<String, String>(); - private OverloadedWorldHolder defaultWorld; + //private OverloadedWorldHolder defaultWorld; private String serverDefaultWorldName; private GroupManager plugin; private File worldsFolder; @@ -59,7 +60,7 @@ public class WorldsHolder { // Setup folders and check files exist for the primary world verifyFirstRun(); initialLoad(); - if (defaultWorld == null) { + if (serverDefaultWorldName == null) { throw new IllegalStateException("There is no default group! OMG!"); } } @@ -76,7 +77,7 @@ public class WorldsHolder { private void initialWorldLoading() { //Load the default world loadWorld(serverDefaultWorldName); - defaultWorld = worldsData.get(serverDefaultWorldName); + //defaultWorld = getUpdatedWorldData(serverDefaultWorldName); } private void loadAllSearchedWorlds() { @@ -117,6 +118,8 @@ public class WorldsHolder { mirrorsGroup.clear(); mirrorsUser.clear(); Map<String, Object> mirrorsMap = plugin.getGMConfig().getMirrorsMap(); + + HashSet<String> mirroredWorlds = new HashSet<String>(); if (mirrorsMap != null) { for (String source : mirrorsMap.keySet()) { @@ -140,6 +143,10 @@ public class WorldsHolder { } mirrorsGroup.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 GroupManager.logger.log(Level.WARNING, "Mirroring error with " + o.toString() + ". Recursive loop detected!"); } @@ -171,11 +178,13 @@ public class WorldsHolder { if (type.equals("users")) mirrorsUser.put(key.toLowerCase(), getWorldData(source).getName()); } + + // Track this world so we can create a datasource for it later + mirroredWorlds.add(key); + } else GroupManager.logger.log(Level.WARNING, "Mirroring error with " + key + ". Recursive loop detected!"); - - } else { 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 * holder. * - * Mirrors return original world data. + * Mirrors return their parent world data. + * If no mirroring data it returns the default world. * * @param worldName * @return OverloadedWorldHolder @@ -328,12 +346,55 @@ public class WorldsHolder { public OverloadedWorldHolder getWorldData(String worldName) { String worldNameLowered = worldName.toLowerCase(); - if (worldsData.containsKey(worldNameLowered)) - return worldsData.get(worldNameLowered); - + // Find this worlds data + 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..."); 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 @@ -353,6 +414,7 @@ public class WorldsHolder { /** * Retrieves the field player.getWorld().getName() and do * getWorld(worldName) + * * @param player * @return OverloadedWorldHolder */ @@ -476,18 +538,29 @@ public class WorldsHolder { } /** + * Wrapper for LoadWorld(String,Boolean) for backwards compatibility + * * Load a world from file. * If it already been loaded, summon reload method from dataHolder. * @param 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())) { worldsData.get(worldName.toLowerCase()).reload(); return; } GroupManager.logger.finest("Trying to load world " + worldName + "..."); File thisWorldFolder = new File(worldsFolder, worldName); - if (thisWorldFolder.exists() && thisWorldFolder.isDirectory()) { + if ((isMirror) || (thisWorldFolder.exists() && thisWorldFolder.isDirectory())) { // Setup file handles, if not mirrored File groupsFile = (mirrorsGroup.containsKey(worldName.toLowerCase()))? null : new File(thisWorldFolder, "groups.yml"); @@ -564,17 +637,43 @@ public class WorldsHolder { * @return the defaultWorld */ 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 */ public ArrayList<OverloadedWorldHolder> allWorldsDataList() { ArrayList<OverloadedWorldHolder> list = new ArrayList<OverloadedWorldHolder>(); 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); } } diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/events/GMGroupEvent.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/events/GMGroupEvent.java index fdb740646..f109cf4f7 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/events/GMGroupEvent.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/events/GMGroupEvent.java @@ -37,7 +37,7 @@ public class GMGroupEvent extends Event { protected Action action;
public GMGroupEvent(Group group, Action action) {
- super(action.toString());
+ super();
this.group = group;
this.action = action;
@@ -45,7 +45,7 @@ public class GMGroupEvent extends Event { }
public GMGroupEvent(String groupName, Action action) {
- super(action.toString());
+ super();
this.groupName = groupName;
this.action = action;
diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/events/GMSystemEvent.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/events/GMSystemEvent.java index 1ff605d5c..6f4c0ea08 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/events/GMSystemEvent.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/events/GMSystemEvent.java @@ -32,7 +32,7 @@ public class GMSystemEvent extends Event { protected Action action;
public GMSystemEvent(Action action) {
- super(action.toString());
+ super();
this.action = action;
}
diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/events/GMUserEvent.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/events/GMUserEvent.java index d40a7d63e..543580f41 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/events/GMUserEvent.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/events/GMUserEvent.java @@ -37,7 +37,7 @@ public class GMUserEvent extends Event { protected Action action;
public GMUserEvent(User user, Action action) {
- super(action.toString());
+ super();
this.user = user;
this.action = action;
@@ -45,7 +45,7 @@ public class GMUserEvent extends Event { }
public GMUserEvent(String userName, Action action) {
- super(action.toString());
+ super();
this.userName = userName;
this.action = action;
diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java index 2e008e223..bd2829f38 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java @@ -121,27 +121,34 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface { // Add the players own permissions. playerPermArray.addAll(populatePerms(ph.getUser(userName).getPermissionList(), includeChildren)); + ArrayList<String> alreadyProcessed = new ArrayList<String>(); + // fetch all group permissions for (String group : getGroups(userName)) { - Set<String> groupPermArray = new HashSet<String>(); - - if (group.startsWith("g:") && GroupManager.getGlobalGroups().hasGroup(group)) { - // GlobalGroups - groupPermArray = populatePerms(GroupManager.getGlobalGroups().getGroupsPermissions(group), includeChildren); + // Don't process a group more than once. + if (!alreadyProcessed.contains(group)) { + alreadyProcessed.add(group); - } 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("-")); - // 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); + Set<String> groupPermArray = new HashSet<String>(); + + 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("-")); + // 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) { 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("*")) { permArray.addAll(GroupManager.BukkitPermissions.getAllRegisteredPermissions(includeChildren)); + allPerms = true; } for (String perm : perms) { 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; if (perm.startsWith("-")) negated = true; @@ -172,12 +187,17 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface { if ((negated) && (permArray.contains(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>()); if (children != null) { - if (negated) { + if (negated || (negated && allPerms)) { // Remove children of negated nodes for (String child : children.keySet()) @@ -185,7 +205,7 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface { if (permArray.contains(child)) permArray.remove(child); - } else { + } else if (!negated){ // Add child nodes for (String child : children.keySet()) diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/BukkitPermissions.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/BukkitPermissions.java index 396b49583..0b6148900 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/BukkitPermissions.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/BukkitPermissions.java @@ -28,19 +28,16 @@ import java.util.Map; import java.util.Set;
import org.anjocaido.groupmanager.GroupManager;
-import org.anjocaido.groupmanager.dataholder.OverloadedWorldHolder;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent;
-import org.bukkit.event.player.PlayerPortalEvent;
import org.bukkit.event.player.PlayerQuitEvent;
-import org.bukkit.event.player.PlayerRespawnEvent;
-import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.permissions.Permission;
@@ -136,33 +133,30 @@ public class BukkitPermissions { }
PermissionAttachment attachment;
+
// Find the players current attachment, or add a new one.
if (this.attachments.containsKey(player)) {
attachment = this.attachments.get(player);
} else {
attachment = player.addAttachment(plugin);
- this.attachments.put(player, attachment);;
+ this.attachments.put(player, attachment);
}
if (world == null) {
world = player.getWorld().getName();
}
- OverloadedWorldHolder worldData = plugin.getWorldsHolder().getWorldData(world);
- Boolean value = false;
-
// Add all permissions for this player (GM only)
// child nodes will be calculated by Bukkit.
- List<String> playerPermArray = new ArrayList<String>(worldData.getPermissionsHandler().getAllPlayersPermissions(player.getName(), false));
+ List<String> playerPermArray = new ArrayList<String>(plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getAllPlayersPermissions(player.getName(), false));
LinkedHashMap<String, Boolean> newPerms = new LinkedHashMap<String, Boolean>();
// Sort the perm list by parent/child, so it will push to superperms correctly.
playerPermArray = sort(playerPermArray);
-
+ Boolean value = false;
for (String permission : playerPermArray) {
value = (!permission.startsWith("-"));
-
newPerms.put((value? permission : permission.substring(1)), value);
}
@@ -178,7 +172,8 @@ public class BukkitPermissions { // Then whack our map into there
orig.putAll(newPerms);
// That's all folks!
- attachment.getPermissible().recalculatePermissions();
+ //attachment.getPermissible().recalculatePermissions();
+ player.recalculatePermissions();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
@@ -348,6 +343,12 @@ public class BukkitPermissions { this.updatePermissions(player, null);
}
+ /**
+ * Player events tracked to cause Superperms updates
+ *
+ * @author ElgarL
+ *
+ */
protected class PlayerEvents implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
@@ -361,24 +362,10 @@ public class BukkitPermissions { }
setPlayer_join(false);
}
-
- @EventHandler(priority = EventPriority.LOWEST)
- public void onPlayerPortal(PlayerPortalEvent event) { // will portal into another world
- if ((event.getTo() != null) && (!event.getFrom().getWorld().equals(event.getTo().getWorld()))) { // only if world actually changed
- updatePermissions(event.getPlayer(), event.getTo().getWorld().getName());
- }
- }
-
- @EventHandler(priority = EventPriority.LOWEST)
- public void onPlayerRespawn(PlayerRespawnEvent event) { // can be respawned in another world
- updatePermissions(event.getPlayer(), event.getRespawnLocation().getWorld().getName());
- }
-
+
@EventHandler(priority = EventPriority.LOWEST)
- public void onPlayerTeleport(PlayerTeleportEvent event) { // can be teleported into another world
- if ((event.getTo() != null) && (event.getPlayer() != null) && (!event.getFrom().getWorld().equals(event.getTo().getWorld()))) { // only if world actually changed
- updatePermissions(event.getPlayer(), event.getTo().getWorld().getName());
- }
+ public void onPlayerChangeWorld(PlayerChangedWorldEvent event) { // has changed worlds
+ updatePermissions(event.getPlayer(), event.getPlayer().getWorld().getName());
}
@EventHandler(priority = EventPriority.LOWEST)
|