summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElgarL <ElgarL@palmergames.com>2012-02-05 16:30:58 +0000
committerElgarL <ElgarL@palmergames.com>2012-02-05 16:30:58 +0000
commite93e50f6d273b940783e7c313610f4cfa7ed15e2 (patch)
tree0100f9b9765492ba7dd3dacb84012ba378a615e4
parent76ba5caeec462b53eb9bffedec3c67b646eebb1c (diff)
downloadEssentials-e93e50f6d273b940783e7c313610f4cfa7ed15e2.tar
Essentials-e93e50f6d273b940783e7c313610f4cfa7ed15e2.tar.gz
Essentials-e93e50f6d273b940783e7c313610f4cfa7ed15e2.tar.lz
Essentials-e93e50f6d273b940783e7c313610f4cfa7ed15e2.tar.xz
Essentials-e93e50f6d273b940783e7c313610f4cfa7ed15e2.zip
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
-rw-r--r--EssentialsGroupManager/src/Changelog.txt4
-rw-r--r--EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java5
-rw-r--r--EssentialsGroupManager/src/org/anjocaido/groupmanager/data/DataUnit.java9
-rw-r--r--EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/GroupsDataHolder.java22
-rw-r--r--EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/UsersDataHolder.java23
-rw-r--r--EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java102
-rw-r--r--EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java128
7 files changed, 216 insertions, 77 deletions
diff --git a/EssentialsGroupManager/src/Changelog.txt b/EssentialsGroupManager/src/Changelog.txt
index 0ef3add6f..1e520efb3 100644
--- a/EssentialsGroupManager/src/Changelog.txt
+++ b/EssentialsGroupManager/src/Changelog.txt
@@ -135,4 +135,6 @@ v 1.9:
- 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. \ No newline at end of file
+ - 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 \ 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 bb61b2145..ab1ebebbb 100644
--- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java
+++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java
@@ -1485,7 +1485,7 @@ 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());
}
@@ -1522,6 +1522,7 @@ public class GroupManager extends JavaPlugin {
}
// WORKING
config.load();
+ globalGroups.load();
worldsHolder.mirrorSetUp();
isLoaded = false;
@@ -1538,7 +1539,7 @@ public class GroupManager extends JavaPlugin {
sender.sendMessage("The request to world '" + auxString + "' was sent.");
} else {
worldsHolder.reloadAll();
- sender.sendMessage(ChatColor.YELLOW + " The current world was reloaded.");
+ sender.sendMessage(ChatColor.YELLOW + " All worlds were reloaded.");
}
isLoaded = true;
diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/DataUnit.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/DataUnit.java
index a35b5aeee..03d31b848 100644
--- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/DataUnit.java
+++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/DataUnit.java
@@ -65,6 +65,15 @@ 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 new worldDataHolder
+ *
+ * @param source
+ */
+ public void setDataSource(WorldDataHolder source) {
+ this.dataSource = source;
+ }
/**
* @return the dataSource
diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/GroupsDataHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/GroupsDataHolder.java
index 4fc819245..444939251 100644
--- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/GroupsDataHolder.java
+++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/GroupsDataHolder.java
@@ -17,7 +17,8 @@ public class GroupsDataHolder {
/**
* Root World name this set of groups is associated with.
*/
- private String name;
+ //private String name;
+ private WorldDataHolder dataSource;
private Group defaultGroup = null;
private File groupsFile;
private boolean haveGroupsChanged = false;
@@ -33,17 +34,24 @@ public class GroupsDataHolder {
*/
protected GroupsDataHolder() {
}
-
- protected void setWorldName(String worldName) {
- name = worldName;
+
+ 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);
}
+ //protected void setWorldName(String worldName) {
+ // name = worldName;
+ //}
+
/**
* @return the name
*/
- public String getWorldName() {
- return name;
- }
+ //public String getWorldName() {
+ // return name;
+ //}
/**
* @return the defaultGroup
diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/UsersDataHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/UsersDataHolder.java
index 37e1c4b43..1d7bbb704 100644
--- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/UsersDataHolder.java
+++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/UsersDataHolder.java
@@ -17,7 +17,8 @@ public class UsersDataHolder {
/**
* Root World name this set of groups is associated with.
*/
- private String name;
+ //private String name;
+ private WorldDataHolder dataSource;
private File usersFile;
private boolean haveUsersChanged = false;
private long timeStampUsers = 0;
@@ -32,20 +33,28 @@ public class UsersDataHolder {
*/
protected UsersDataHolder() {
}
+
+ 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);
+
+ }
/**
* @param worldName
*/
- public void setWorldName(String worldName) {
- this.name = worldName;
- }
+ //public void setWorldName(String worldName) {
+ // this.name = worldName;
+ //}
/**
* @return the name
*/
- public String getWorldName() {
- return this.name;
- }
+ //public String getWorldName() {
+ // return this.name;
+ //}
/**
* @return the users
diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java
index 581f17770..69305f360 100644
--- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java
+++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java
@@ -80,6 +80,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
@@ -465,54 +475,66 @@ public class WorldDataHolder {
}
//PERMISSIONS NODE
- 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"));
+ try {
+ if (thisGroupNode.get("permissions") == null) {
+ thisGroupNode.put("permissions", new ArrayList<String>());
} else {
- throw new IllegalArgumentException("Unknown type of permissions node(Should be String or List<String>) for group: " + thisGrp.getName() + " in file: " + groupsFile.getPath());
+ 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();
}
- 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();
diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java
index 6d819daa5..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);
+ }
+ }
}
}
@@ -329,21 +346,55 @@ public class WorldsHolder {
public OverloadedWorldHolder getWorldData(String worldName) {
String worldNameLowered = worldName.toLowerCase();
- // Return this worlds data
- 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);
+ }
- // If groups mirrored return the parent worlds data
- if (mirrorsGroup.containsKey(worldNameLowered))
- return worldsData.get(mirrorsGroup.get(worldNameLowered).toLowerCase());
-
- // If users mirrored return the parent worlds data
- if (mirrorsUser.containsKey(worldNameLowered))
- return worldsData.get(mirrorsUser.get(worldNameLowered).toLowerCase());
-
+ // 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
@@ -487,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");
@@ -575,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);
}
}