diff options
author | Zenexer <Zenexer@e251c2fe-e539-e718-e476-b85c1f46cddb> | 2011-03-30 04:03:21 +0000 |
---|---|---|
committer | Zenexer <Zenexer@e251c2fe-e539-e718-e476-b85c1f46cddb> | 2011-03-30 04:03:21 +0000 |
commit | cb21bc4d7a67f0974c2773fdd0f5376f177c068e (patch) | |
tree | f1584fe391f77c648a1d7d25385ef16229b756de /EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder | |
download | Essentials-cb21bc4d7a67f0974c2773fdd0f5376f177c068e.tar Essentials-cb21bc4d7a67f0974c2773fdd0f5376f177c068e.tar.gz Essentials-cb21bc4d7a67f0974c2773fdd0f5376f177c068e.tar.lz Essentials-cb21bc4d7a67f0974c2773fdd0f5376f177c068e.tar.xz Essentials-cb21bc4d7a67f0974c2773fdd0f5376f177c068e.zip |
2.1 prerelease, part 2 of 3
git-svn-id: https://svn.java.net/svn/essentials~svn/trunk2.1@1015 e251c2fe-e539-e718-e476-b85c1f46cddb
Diffstat (limited to 'EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder')
3 files changed, 1566 insertions, 0 deletions
diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/OverloadedWorldHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/OverloadedWorldHolder.java new file mode 100644 index 000000000..f735ff5e6 --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/OverloadedWorldHolder.java @@ -0,0 +1,204 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.dataholder; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import org.anjocaido.groupmanager.data.User; + +/** + * + * @author gabrielcouto + */ +public class OverloadedWorldHolder extends WorldDataHolder { + + /** + * + */ + protected Map<String, User> overloadedUsers = new HashMap<String, User>(); + + /** + * + * @param ph + */ + public OverloadedWorldHolder(WorldDataHolder ph) { + super(ph.getName()); + this.f = ph.f; + this.groupsFile = ph.groupsFile; + this.usersFile = ph.usersFile; + this.defaultGroup = ph.defaultGroup; + this.groups = ph.groups; + this.users = ph.users; + } + + /** + * + * @param userName + * @return + */ + @Override + public User getUser(String userName) { + //OVERLOADED CODE + if (overloadedUsers.containsKey(userName.toLowerCase())) { + return overloadedUsers.get(userName.toLowerCase()); + } + //END CODE + if (users.containsKey(userName.toLowerCase())) { + return users.get(userName.toLowerCase()); + } + User newUser = createUser(userName); + haveUsersChanged = true; + return newUser; + } + + /** + * + * @param theUser + */ + @Override + public void addUser(User theUser) { + if (theUser.getDataSource() != this) { + theUser = theUser.clone(this); + } + if (theUser == null) { + return; + } + if ((theUser.getGroup() == null) || (!groups.containsKey(theUser.getGroupName().toLowerCase()))) { + theUser.setGroup(defaultGroup); + } + //OVERLOADED CODE + if (overloadedUsers.containsKey(theUser.getName().toLowerCase())) { + overloadedUsers.remove(theUser.getName().toLowerCase()); + overloadedUsers.put(theUser.getName().toLowerCase(), theUser); + return; + } + //END CODE + removeUser(theUser.getName()); + users.put(theUser.getName().toLowerCase(), theUser); + haveUsersChanged = true; + } + + /** + * + * @param userName + * @return + */ + @Override + public boolean removeUser(String userName) { + //OVERLOADED CODE + if (overloadedUsers.containsKey(userName.toLowerCase())) { + overloadedUsers.remove(userName.toLowerCase()); + return true; + } + //END CODE + if (users.containsKey(userName.toLowerCase())) { + users.remove(userName.toLowerCase()); + haveUsersChanged = true; + return true; + } + return false; + } + + @Override + public boolean removeGroup(String groupName) { + if (groupName.equals(defaultGroup)) { + return false; + } + for (String key : groups.keySet()) { + if (groupName.equalsIgnoreCase(key)) { + groups.remove(key); + for (String userKey : users.keySet()) { + User user = users.get(userKey); + if (user.getGroupName().equalsIgnoreCase(key)) { + user.setGroup(defaultGroup); + } + + } + //OVERLOADED CODE + for (String userKey : overloadedUsers.keySet()) { + User user = overloadedUsers.get(userKey); + if (user.getGroupName().equalsIgnoreCase(key)) { + user.setGroup(defaultGroup); + } + + } + //END OVERLOAD + haveGroupsChanged = true; + return true; + } + } + return false; + } + + /** + * + * @return + */ + @Override + public Collection<User> getUserList() { + Collection<User> overloadedList = new ArrayList<User>(); + Collection<User> normalList = users.values(); + for (User u : normalList) { + if (overloadedUsers.containsKey(u.getName().toLowerCase())) { + overloadedList.add(overloadedUsers.get(u.getName().toLowerCase())); + } else { + overloadedList.add(u); + } + } + return overloadedList; + } + + /** + * + * @param userName + * @return + */ + public boolean isOverloaded(String userName) { + return overloadedUsers.containsKey(userName.toLowerCase()); + } + + /** + * + * @param userName + */ + public void overloadUser(String userName) { + if (!isOverloaded(userName)) { + User theUser = getUser(userName); + theUser = theUser.clone(); + if (overloadedUsers.containsKey(theUser.getName().toLowerCase())) { + overloadedUsers.remove(theUser.getName().toLowerCase()); + } + overloadedUsers.put(theUser.getName().toLowerCase(), theUser); + } + } + + /** + * + * @param userName + */ + public void removeOverload(String userName) { + overloadedUsers.remove(userName.toLowerCase()); + } + + /** + * Gets the user in normal state. Surpassing the overload state. + * It doesn't affect permissions. But it enables plugins change the + * actual user permissions even in overload mode. + * @param userName + * @return + */ + public User surpassOverload(String userName) { + if (!isOverloaded(userName)) { + return getUser(userName); + } + if (users.containsKey(userName.toLowerCase())) { + return users.get(userName.toLowerCase()); + } + User newUser = createUser(userName); + return newUser; + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java new file mode 100644 index 000000000..96e517abd --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java @@ -0,0 +1,939 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.dataholder; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.anjocaido.groupmanager.GroupManager; +import org.anjocaido.groupmanager.data.Group; +import org.anjocaido.groupmanager.data.User; +import org.anjocaido.groupmanager.permissions.AnjoPermissionsHandler; +import org.bukkit.Server; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.SafeConstructor; +import org.yaml.snakeyaml.reader.UnicodeReader; + +/** + * + * @author gabrielcouto + */ +public class WorldDataHolder { + + /** + * + */ + protected String name; + /** + * The actual groups holder + */ + protected Map<String, Group> groups = new HashMap<String, Group>(); + /** + * The actual users holder + */ + protected Map<String, User> users = new HashMap<String, User>(); + /** + * Points to the default group + */ + protected Group defaultGroup = null; + /** + * The file, which this class loads/save data from/to + * @deprecated + */ + @Deprecated + protected File f; + /** + * + */ + protected AnjoPermissionsHandler permissionsHandler; + /** + * + */ + protected File usersFile; + /** + * + */ + protected File groupsFile; + /** + * + */ + protected boolean haveUsersChanged = false; + /** + * + */ + protected boolean haveGroupsChanged = false; + + /** + * Prevent direct instantiation + * @param worldName + */ + protected WorldDataHolder(String worldName) { + name = worldName; + } + + /** + * The main constructor for a new WorldDataHolder + * Please don't set the default group as null + * @param worldName + * @param defaultGroup the default group. its good to start with one + */ + public WorldDataHolder(String worldName, Group defaultGroup) { + this.name = worldName; + groups.put(defaultGroup.getName().toLowerCase(), defaultGroup); + this.defaultGroup = defaultGroup; + } + + /** + * Search for a user. If it doesn't exist, create a new one with + * default group. + * + * @param userName the name of the user + * @return class that manage that user permission + */ + public User getUser(String userName) { + if (users.containsKey(userName.toLowerCase())) { + return users.get(userName.toLowerCase()); + } + User newUser = createUser(userName); + return newUser; + } + + /** + * Add a user to the list. If it already exists, overwrite the old. + * @param theUser the user you want to add to the permission list + */ + public void addUser(User theUser) { + if (theUser.getDataSource() != this) { + theUser = theUser.clone(this); + } + if (theUser == null) { + return; + } + if ((theUser.getGroup() == null)) { + theUser.setGroup(defaultGroup); + } + removeUser(theUser.getName()); + users.put(theUser.getName().toLowerCase(), theUser); + haveUsersChanged = true; + } + + /** + * Removes the user from the list. (he might become a default user) + * @param userName the username from the user to remove + * @return true if it had something to remove + */ + public boolean removeUser(String userName) { + if (users.containsKey(userName.toLowerCase())) { + users.remove(userName.toLowerCase()); + haveUsersChanged = true; + return true; + } + return false; + } + + /** + * + * @param userName + * @return + */ + public boolean isUserDeclared(String userName) { + return users.containsKey(userName.toLowerCase()); + } + + /** + * Change the default group of the file. + * @param group the group you want make default. + */ + public void setDefaultGroup(Group group) { + if (!groups.containsKey(group.getName().toLowerCase()) || (group.getDataSource() != this)) { + addGroup(group); + } + defaultGroup = this.getGroup(group.getName()); + haveGroupsChanged = true; + } + + /** + * Returns the default group of the file + * @return the default group + */ + public Group getDefaultGroup() { + return defaultGroup; + } + + /** + * Returns a group of the given name + * @param groupName the name of the group + * @return a group if it is found. null if not found. + */ + public Group getGroup(String groupName) { + return groups.get(groupName.toLowerCase()); + } + + /** + * Check if a group exists. + * Its the same of getGroup, but check if it is null. + * @param groupName the name of the group + * @return true if exists. false if not. + */ + public boolean groupExists(String groupName) { + return groups.containsKey(groupName.toLowerCase()); + } + + /** + * Add a group to the list + * @param groupToAdd + */ + public void addGroup(Group groupToAdd) { + if (groupToAdd.getDataSource() != this) { + groupToAdd = groupToAdd.clone(this); + } + removeGroup(groupToAdd.getName()); + groups.put(groupToAdd.getName().toLowerCase(), groupToAdd); + haveGroupsChanged = true; + } + + /** + * Remove the group to the list + * @param groupName + * @return true if had something to remove. false the group was default or non-existant + */ + public boolean removeGroup(String groupName) { + if (defaultGroup != null && groupName.equalsIgnoreCase(defaultGroup.getName())) { + return false; + } + if (groups.containsKey(groupName.toLowerCase())) { + groups.remove(groupName.toLowerCase()); + haveGroupsChanged = true; + return true; + } + return false; + + } + + /** + * Creates a new User with the given name + * and adds it to this holder. + * @param userName the username you want + * @return null if user already exists. or new User + */ + public User createUser(String userName) { + if (this.users.containsKey(userName.toLowerCase())) { + return null; + } + User newUser = new User(this, userName); + newUser.setGroup(defaultGroup); + this.addUser(newUser); + haveUsersChanged = true; + return newUser; + } + + /** + * Creates a new Group with the given name + * and adds it to this holder + * @param groupName the groupname you want + * @return null if group already exists. or new Group + */ + public Group createGroup(String groupName) { + if (this.groups.containsKey(groupName.toLowerCase())) { + return null; + } + Group newGroup = new Group(this, groupName); + this.addGroup(newGroup); + haveGroupsChanged = true; + return newGroup; + } + + /** + * + * @return a collection of the groups + */ + public Collection<Group> getGroupList() { + return groups.values(); + } + + /** + * + * @return a collection of the users + */ + public Collection<User> getUserList() { + return users.values(); + } + + /** + * reads the file again + */ + public void reload() { + try { + WorldDataHolder ph = load(this.getName(), getGroupsFile(), getUsersFile()); + this.defaultGroup = ph.defaultGroup; + this.groups = ph.groups; + this.users = ph.users; + } catch (Exception ex) { + Logger.getLogger(WorldDataHolder.class.getName()).log(Level.SEVERE, null, ex); + } + } + + /** + * Save by yourself! + * @deprecated + */ + @Deprecated + public void commit() { + writeGroups(this, getGroupsFile()); + writeUsers(this, getUsersFile()); + } + + /** + * Returns a data holder for the given file + * @param worldName + * @param file + * @return + * @throws Exception + * @deprecated + */ + @Deprecated + public static WorldDataHolder load(String worldName, File file) throws Exception { + WorldDataHolder ph = new WorldDataHolder(worldName); + ph.f = file; + final Yaml yaml = new Yaml(new SafeConstructor()); + Map<String, Object> rootDataNode; + if (!file.exists()) { + throw new Exception("The file which should contain permissions does not exist!\n" + file.getPath()); + } + FileInputStream rx = new FileInputStream(file); + try { + rootDataNode = (Map<String, Object>) yaml.load(new UnicodeReader(rx)); + if (rootDataNode == null) { + throw new NullPointerException(); + } + } catch (Exception ex) { + throw new Exception("The following file couldn't pass on Parser.\n" + file.getPath(), ex); + } finally { + rx.close(); + } + Map<String, List<String>> inheritance = new HashMap<String, List<String>>(); + try { + Map<String, Object> allGroupsNode = (Map<String, Object>) rootDataNode.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); + } + if (thisGroupNode.get("default") == null) { + thisGroupNode.put("default", false); + } + if ((Boolean.parseBoolean(thisGroupNode.get("default").toString()))) { + if (ph.getDefaultGroup() != null) { + GroupManager.logger.warning("The group " + thisGrp.getName() + " is declaring be default where" + ph.getDefaultGroup().getName() + " already was."); + GroupManager.logger.warning("Overriding first request."); + } + ph.setDefaultGroup(thisGrp); + } + + //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"))) { + thisGrp.addPermission(o.toString()); + } + } 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>): " + thisGroupNode.get("permissions").getClass().getName()); + } + + //INFO NODE + Map<String, Object> infoNode = (Map<String, Object>) thisGroupNode.get("info"); + if (infoNode != null) { + thisGrp.setVariables(infoNode); + } + + //END INFO NODE + + 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); + + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + throw new Exception("Your Permissions config file is invalid. See console for details."); + } + if (ph.defaultGroup == null) { + throw new IllegalArgumentException("There was no Default Group declared."); + } + for (String groupKey : inheritance.keySet()) { + List<String> inheritedList = inheritance.get(groupKey); + Group thisGroup = ph.getGroup(groupKey); + for (String inheritedKey : inheritedList) { + Group inheritedGroup = ph.getGroup(inheritedKey); + if (thisGroup != null && inheritedGroup != null) { + thisGroup.addInherits(inheritedGroup); + } + } + } + // Process USERS + Map<String, Object> allUsersNode = (Map<String, Object>) rootDataNode.get("users"); + for (String usersKey : allUsersNode.keySet()) { + Map<String, Object> thisUserNode = (Map<String, Object>) allUsersNode.get(usersKey); + User thisUser = ph.createUser(usersKey); + if (thisUser == null) { + throw new IllegalArgumentException("I think this user was declared more than once: " + usersKey); + } + 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) { + thisUser.addPermission(thisUserNode.get("permissions").toString()); + } + + + //USER INFO NODE - BETA + + //INFO NODE + Map<String, Object> infoNode = (Map<String, Object>) thisUserNode.get("info"); + if (infoNode != null) { + thisUser.setVariables(infoNode); + } + //END INFO NODE - BETA + + if (thisUserNode.get("group") != null) { + Group hisGroup = ph.getGroup(thisUserNode.get("group").toString()); + if (hisGroup == null) { + throw new IllegalArgumentException("There is no group " + thisUserNode.get("group").toString() + ", as stated for player " + thisUser.getName()); + } + thisUser.setGroup(hisGroup); + } else { + thisUser.setGroup(ph.defaultGroup); + } + } + return ph; + } + + /** + * Returns a data holder for the given file + * @param worldName + * @param groupsFile + * @param usersFile + * @return + * @throws FileNotFoundException + * @throws IOException + */ + public static WorldDataHolder load(String worldName, File groupsFile, File usersFile) throws FileNotFoundException, IOException { + WorldDataHolder ph = new WorldDataHolder(worldName); + ph.groupsFile = groupsFile; + ph.usersFile = usersFile; + + + //READ GROUPS FILE + Yaml yamlGroups = new Yaml(new SafeConstructor()); + Map<String, Object> groupsRootDataNode; + if (!groupsFile.exists()) { + throw new IllegalArgumentException("The file which should contain permissions does not exist!\n" + groupsFile.getPath()); + } + FileInputStream groupsInputStream = new FileInputStream(groupsFile); + try { + groupsRootDataNode = (Map<String, Object>) yamlGroups.load(new UnicodeReader(groupsInputStream)); + if (groupsRootDataNode == null) { + throw new NullPointerException(); + } + } catch (Exception ex) { + throw new IllegalArgumentException("The following file couldn't pass on Parser.\n" + groupsFile.getPath(), ex); + } finally { + groupsInputStream.close(); + } + + //PROCESS GROUPS FILE + Map<String, List<String>> inheritance = new HashMap<String, List<String>>(); + 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); + } + if (thisGroupNode.get("default") == null) { + thisGroupNode.put("default", false); + } + if ((Boolean.parseBoolean(thisGroupNode.get("default").toString()))) { + if (ph.getDefaultGroup() != null) { + GroupManager.logger.warning("The group " + thisGrp.getName() + " is declaring be default where" + ph.getDefaultGroup().getName() + " already was."); + GroupManager.logger.warning("Overriding first request."); + } + ph.setDefaultGroup(thisGrp); + } + + //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"))) { + thisGrp.addPermission(o.toString()); + } + } 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>): " + thisGroupNode.get("permissions").getClass().getName()); + } + + //INFO NODE + Map<String, Object> infoNode = (Map<String, Object>) thisGroupNode.get("info"); + if (infoNode != null) { + thisGrp.setVariables(infoNode); + } + + //END INFO NODE + + 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); + + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + throw new IllegalArgumentException("Your Permissions config file is invalid. See console for details."); + } + if (ph.defaultGroup == null) { + throw new IllegalArgumentException("There was no Default Group declared."); + } + for (String groupKey : inheritance.keySet()) { + List<String> inheritedList = inheritance.get(groupKey); + Group thisGroup = ph.getGroup(groupKey); + for (String inheritedKey : inheritedList) { + Group inheritedGroup = ph.getGroup(inheritedKey); + if (thisGroup != null && inheritedGroup != null) { + thisGroup.addInherits(inheritedGroup); + } + } + } + + + //READ USERS FILE + Yaml yamlUsers = new Yaml(new SafeConstructor()); + Map<String, Object> usersRootDataNode; + if (!groupsFile.exists()) { + throw new IllegalArgumentException("The file which should contain permissions does not exist!\n" + groupsFile.getPath()); + } + FileInputStream usersInputStream = new FileInputStream(usersFile); + try { + usersRootDataNode = (Map<String, Object>) yamlUsers.load(new UnicodeReader(usersInputStream)); + if (usersRootDataNode == null) { + throw new NullPointerException(); + } + } catch (Exception ex) { + throw new IllegalArgumentException("The following file couldn't pass on Parser.\n" + groupsFile.getPath(), ex); + } finally { + usersInputStream.close(); + } + + // PROCESS USERS FILE + Map<String, Object> allUsersNode = (Map<String, Object>) usersRootDataNode.get("users"); + for (String usersKey : allUsersNode.keySet()) { + Map<String, Object> thisUserNode = (Map<String, Object>) allUsersNode.get(usersKey); + User thisUser = ph.createUser(usersKey); + if (thisUser == null) { + throw new IllegalArgumentException("I think this user was declared more than once: " + usersKey); + } + 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) { + thisUser.addPermission(thisUserNode.get("permissions").toString()); + } + + //SUBGROUPS LOADING + if (thisUserNode.get("subgroups") == null) { + thisUserNode.put("subgroups", new ArrayList<String>()); + } + if (thisUserNode.get("subgroups") instanceof List) { + for (Object o : ((List) thisUserNode.get("subgroups"))) { + Group subGrp = ph.getGroup(o.toString()); + if (subGrp != null) { + thisUser.addSubGroup(subGrp); + } else { + GroupManager.logger.warning("Subgroup " + o.toString() + " not found for user " + thisUser.getName() + ". Ignoring entry."); + } + } + } else if (thisUserNode.get("subgroups") instanceof String) { + Group subGrp = ph.getGroup(thisUserNode.get("subgroups").toString()); + if (subGrp != null) { + thisUser.addSubGroup(subGrp); + } else { + GroupManager.logger.warning("Subgroup " + thisUserNode.get("subgroups").toString() + " not found for user " + thisUser.getName() + ". Ignoring entry."); + } + } + + + //USER INFO NODE - BETA + + //INFO NODE + Map<String, Object> infoNode = (Map<String, Object>) thisUserNode.get("info"); + if (infoNode != null) { + thisUser.setVariables(infoNode); + } + //END INFO NODE - BETA + + if (thisUserNode.get("group") != null) { + Group hisGroup = ph.getGroup(thisUserNode.get("group").toString()); + if (hisGroup == null) { + throw new IllegalArgumentException("There is no group " + thisUserNode.get("group").toString() + ", as stated for player " + thisUser.getName()); + } + thisUser.setGroup(hisGroup); + } else { + thisUser.setGroup(ph.defaultGroup); + } + } + return ph; + } + + /** + * Write a dataHolder in a specified file + * @param ph + * @param file + * @deprecated + */ + @Deprecated + public static void write(WorldDataHolder ph, File file) { + Map<String, Object> root = new HashMap<String, Object>(); + + Map<String, Object> pluginMap = new HashMap<String, Object>(); + root.put("plugin", pluginMap); + + Map<String, Object> permissionsMap = new HashMap<String, Object>(); + pluginMap.put("permissions", permissionsMap); + + permissionsMap.put("system", "default"); + + Map<String, Object> groupsMap = new HashMap<String, Object>(); + root.put("groups", groupsMap); + for (String groupKey : ph.groups.keySet()) { + Group group = ph.groups.get(groupKey); + + Map<String, Object> aGroupMap = new HashMap<String, Object>(); + groupsMap.put(group.getName(), aGroupMap); + + aGroupMap.put("default", group.equals(ph.defaultGroup)); + + Map<String, Object> infoMap = new HashMap<String, Object>(); + aGroupMap.put("info", infoMap); + + for (String infoKey : group.getVariables().getVarKeyList()) { + infoMap.put(infoKey, group.getVariables().getVarObject(infoKey)); + } + + aGroupMap.put("inheritance", group.getInherits()); + + aGroupMap.put("permissions", group.getPermissionList()); + } + + Map<String, Object> usersMap = new HashMap<String, Object>(); + root.put("users", usersMap); + for (String userKey : ph.users.keySet()) { + User user = ph.users.get(userKey); + if ((user.getGroup() == null || user.getGroup().equals(ph.defaultGroup)) && user.getPermissionList().isEmpty()) { + continue; + } + + Map<String, Object> aUserMap = new HashMap<String, Object>(); + usersMap.put(user.getName(), aUserMap); + + if (user.getGroup() == null) { + aUserMap.put("group", ph.defaultGroup.getName()); + } else { + aUserMap.put("group", user.getGroup().getName()); + } + //USER INFO NODE - BETA + if (user.getVariables().getSize() > 0) { + Map<String, Object> infoMap = new HashMap<String, Object>(); + aUserMap.put("info", infoMap); + + for (String infoKey : user.getVariables().getVarKeyList()) { + infoMap.put(infoKey, user.getVariables().getVarObject(infoKey)); + } + } + //END USER INFO NODE - BETA + + aUserMap.put("permissions", user.getPermissionList()); + } + DumperOptions opt = new DumperOptions(); + opt.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + final Yaml yaml = new Yaml(opt); + + FileWriter tx = null; + try { + tx = new FileWriter(file, false); + tx.write(yaml.dump(root)); + tx.flush(); + } catch (Exception e) { + } finally { + try { + tx.close(); + } catch (IOException ex) { + } + } + } + + /** + * Write a dataHolder in a specified file + * @param ph + * @param groupsFile + */ + public static void writeGroups(WorldDataHolder ph, File groupsFile) { + Map<String, Object> root = new HashMap<String, Object>(); + + Map<String, Object> groupsMap = new HashMap<String, Object>(); + root.put("groups", groupsMap); + for (String groupKey : ph.groups.keySet()) { + Group group = ph.groups.get(groupKey); + + Map<String, Object> aGroupMap = new HashMap<String, Object>(); + groupsMap.put(group.getName(), aGroupMap); + + if (ph.defaultGroup == null) { + GroupManager.logger.severe("There is no default group for world: " + ph.getName()); + } + aGroupMap.put("default", group.equals(ph.defaultGroup)); + + Map<String, Object> infoMap = new HashMap<String, Object>(); + aGroupMap.put("info", infoMap); + + for (String infoKey : group.getVariables().getVarKeyList()) { + infoMap.put(infoKey, group.getVariables().getVarObject(infoKey)); + } + + aGroupMap.put("inheritance", group.getInherits()); + + aGroupMap.put("permissions", group.getPermissionList()); + } + + DumperOptions opt = new DumperOptions(); + opt.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + final Yaml yaml = new Yaml(opt); + + FileWriter tx = null; + try { + tx = new FileWriter(groupsFile, false); + tx.write(yaml.dump(root)); + tx.flush(); + } catch (Exception e) { + } finally { + try { + tx.close(); + } catch (IOException ex) { + } + } + } + + /** + * Write a dataHolder in a specified file + * @param ph + * @param usersFile + */ + public static void writeUsers(WorldDataHolder ph, File usersFile) { + Map<String, Object> root = new HashMap<String, Object>(); + + Map<String, Object> usersMap = new HashMap<String, Object>(); + root.put("users", usersMap); + for (String userKey : ph.users.keySet()) { + User user = ph.users.get(userKey); + if ((user.getGroup() == null || user.getGroup().equals(ph.defaultGroup)) && user.getPermissionList().isEmpty() && user.getVariables().isEmpty() && user.isSubGroupsEmpty()) { + continue; + } + + Map<String, Object> aUserMap = new HashMap<String, Object>(); + usersMap.put(user.getName(), aUserMap); + + if (user.getGroup() == null) { + aUserMap.put("group", ph.defaultGroup.getName()); + } else { + aUserMap.put("group", user.getGroup().getName()); + } + //USER INFO NODE - BETA + if (user.getVariables().getSize() > 0) { + Map<String, Object> infoMap = new HashMap<String, Object>(); + aUserMap.put("info", infoMap); + for (String infoKey : user.getVariables().getVarKeyList()) { + infoMap.put(infoKey, user.getVariables().getVarObject(infoKey)); + } + } + //END USER INFO NODE - BETA + aUserMap.put("permissions", user.getPermissionList()); + + //SUBGROUPS NODE - BETA + aUserMap.put("subgroups", user.subGroupListStringCopy()); + //END SUBGROUPS NODE - BETA + } + DumperOptions opt = new DumperOptions(); + opt.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + final Yaml yaml = new Yaml(opt); + + FileWriter tx = null; + try { + tx = new FileWriter(usersFile, false); + tx.write(yaml.dump(root)); + tx.flush(); + } catch (Exception e) { + } finally { + try { + tx.close(); + } catch (IOException ex) { + } + } + } + + /** + * Don't use this. Unless you want to make this plugin to interact with original Nijikokun Permissions + * This method is supposed to make the original one reload the file, and propagate the changes made here. + * + * Prefer to use the AnjoCaido's fake version of Nijikokun's Permission plugin. + * The AnjoCaido's Permission can propagate the changes made on this plugin instantly, + * without need to save the file. + * + * @param server the server that holds the plugin + * @deprecated it is not used anymore... unless if you use original Permissions + */ + @Deprecated + public static void reloadOldPlugins(Server server) { + // Only reload permissions + PluginManager pm = server.getPluginManager(); + Plugin[] plugins = pm.getPlugins(); + for (int i = 0; i < plugins.length; i++) { + plugins[i].getConfiguration().load(); + try { + plugins[i].getClass().getMethod("setupPermissions").invoke(plugins[i]); + } catch (Exception ex) { + continue; + } + } + } + + /** + * @return the permissionsHandler + */ + public AnjoPermissionsHandler getPermissionsHandler() { + if (permissionsHandler == null) { + permissionsHandler = new AnjoPermissionsHandler(this); + } + return permissionsHandler; + } + + /** + * + * @return + */ + public boolean haveUsersChanged() { + if (haveUsersChanged) { + return true; + } + for (User u : users.values()) { + if (u.isChanged()) { + return true; + } + } + return false; + } + + /** + * + * @return + */ + public boolean haveGroupsChanged() { + if (haveGroupsChanged) { + return true; + } + for (Group g : groups.values()) { + if (g.isChanged()) { + return true; + } + } + return false; + } + + /** + * + */ + public void removeUsersChangedFlag() { + haveUsersChanged = false; + for (User u : users.values()) { + u.flagAsSaved(); + } + } + + /** + * + */ + public void removeGroupsChangedFlag() { + haveGroupsChanged = false; + for (Group g : groups.values()) { + g.flagAsSaved(); + } + } + + /** + * @return the usersFile + */ + public File getUsersFile() { + return usersFile; + } + + /** + * @return the groupsFile + */ + public File getGroupsFile() { + return groupsFile; + } + + /** + * @return the name + */ + public String getName() { + return name; + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java new file mode 100644 index 000000000..83073c10b --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java @@ -0,0 +1,423 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.dataholder.worlds; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.anjocaido.groupmanager.GroupManager; +import org.anjocaido.groupmanager.dataholder.WorldDataHolder; +import org.anjocaido.groupmanager.dataholder.OverloadedWorldHolder; +import org.anjocaido.groupmanager.permissions.AnjoPermissionsHandler; +import org.anjocaido.groupmanager.utils.Tasks; +import org.bukkit.entity.Player; + +/** + * + * @author gabrielcouto + */ +public class WorldsHolder { + + /** + * Map with instances of loaded worlds. + */ + private Map<String, OverloadedWorldHolder> worldsData = new HashMap<String, OverloadedWorldHolder>(); + /** + * Map of mirrors: <nonExistingWorldName, existingAndLoadedWorldName> + * The key is the mirror. + * The object is the mirrored. + * + * Mirror shows the same data of mirrored. + */ + private Map<String, String> mirrors = new HashMap<String, String>(); + private OverloadedWorldHolder defaultWorld; + private String serverDefaultWorldName; + private GroupManager plugin; + private File worldsFolder; + + /** + * + * @param plugin + */ + public WorldsHolder(GroupManager plugin) { + this.plugin = plugin; + verifyFirstRun(); + initialLoad(); + if (defaultWorld == null) { + throw new IllegalStateException("There is no default group! OMG!"); + } + } + + private void initialLoad() { + initialWorldLoading(); + mirrorSetUp(); + } + private void initialWorldLoading(){ + //LOAD EVERY WORLD POSSIBLE + loadWorld(serverDefaultWorldName); + defaultWorld = worldsData.get(serverDefaultWorldName); + + for (File folder : worldsFolder.listFiles()) { + if (folder.getName().equalsIgnoreCase(serverDefaultWorldName)) { + continue; + } + if (folder.isDirectory()) { + loadWorld(folder.getName()); + } + } + } + public void mirrorSetUp(){ + mirrors.clear(); + Map<String, Object> mirrorsMap = plugin.getConfig().getMirrorsMap(); + if (mirrorsMap != null) { + for (String source : mirrorsMap.keySet()) { + if (mirrorsMap.get(source) instanceof ArrayList) { + ArrayList mirrorList = (ArrayList) mirrorsMap.get(source); + for (Object o : mirrorList) { + try { + mirrors.remove(o.toString().toLowerCase()); + } catch (Exception e) { + } + mirrors.put(o.toString().toLowerCase(), getWorldData(source).getName()); + } + } else if (mirrorsMap.get(source) instanceof Object) { + String aMirror = mirrorsMap.get(source).toString(); + mirrors.put(aMirror.toLowerCase(), getWorldData(source).getName()); + } + } + } + } + + /** + * + */ + public void reloadAll() { + ArrayList<WorldDataHolder> alreadyDone = new ArrayList<WorldDataHolder>(); + for (WorldDataHolder w : worldsData.values()) { + if (alreadyDone.contains(w)) { + continue; + } + w.reload(); + alreadyDone.add(w); + } + } + + /** + * + * @param worldName + */ + public void reloadWorld(String worldName) { + getWorldData(worldName).reload(); + } + + /** + * + */ + public void saveChanges() { + ArrayList<WorldDataHolder> alreadyDone = new ArrayList<WorldDataHolder>(); + for (OverloadedWorldHolder w : worldsData.values()) { + if (alreadyDone.contains(w)) { + continue; + } + Tasks.removeOldFiles(plugin.getBackupFolder()); + if (w == null) { + GroupManager.logger.severe("WHAT HAPPENED?"); + continue; + } + if (w.haveGroupsChanged()) { + String groupsFolderName = w.getGroupsFile().getParentFile().getName(); + File backupGroups = new File(plugin.getBackupFolder(), "bkp_" + w.getName() + "_g_" + Tasks.getDateString() + ".yml"); + try { + Tasks.copy(w.getGroupsFile(), backupGroups); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + WorldDataHolder.writeGroups(w, w.getGroupsFile()); + w.removeGroupsChangedFlag(); + } + if (w.haveUsersChanged()) { + File backupUsers = new File(plugin.getBackupFolder(), "bkp_" + w.getName() + "_u_" + Tasks.getDateString() + ".yml"); + try { + Tasks.copy(w.getUsersFile(), backupUsers); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + WorldDataHolder.writeUsers(w, w.getUsersFile()); + w.removeUsersChangedFlag(); + } + alreadyDone.add(w); + } + } + + /** + * Returns the dataHolder for the given world. + * If the world is not on the worlds list, returns the default world + * holder. + * + * (WHEN A WORLD IS CONFIGURED TO MIRROR, IT WILL BE ON THE LIST, BUT + * POINTING TO ANOTHER WORLD HOLDER) + * + * Mirrors prevails original data. + * + * @param worldName + * @return + */ + public OverloadedWorldHolder getWorldData(String worldName) { + OverloadedWorldHolder data = worldsData.get(worldName.toLowerCase()); + if (mirrors.containsKey(worldName.toLowerCase())) { + String realOne = mirrors.get(worldName.toLowerCase()); + data = worldsData.get(realOne.toLowerCase()); + } + if (data == null) { + GroupManager.logger.finest("Requested world " + worldName + " not found or badly mirrored. Returning default world..."); + data = getDefaultWorld(); + } + return data; + } + + /** + * Do a matching of playerName, if it s found only one player, do + * getWorldData(player) + * @param playerName + * @return null if matching returned no player, or more than one. + */ + public OverloadedWorldHolder getWorldDataByPlayerName(String playerName) { + List<Player> matchPlayer = plugin.getServer().matchPlayer(playerName); + if (matchPlayer.size() == 1) { + return getWorldData(matchPlayer.get(0)); + } + return null; + } + + /** + * Retrieves the field p.getWorld().getName() and do + * getWorld(worldName) + * @param p + * @return + */ + public OverloadedWorldHolder getWorldData(Player p) { + return getWorldData(p.getWorld().getName()); + } + + /** + * It does getWorld(worldName).getPermissionsHandler() + * @param worldName + * @return + */ + public AnjoPermissionsHandler getWorldPermissions(String worldName) { + return getWorldData(worldName).getPermissionsHandler(); + } + + /** + *It does getWorldData(p).getPermission + * @param p + * @return + */ + public AnjoPermissionsHandler getWorldPermissions(Player p) { + return getWorldData(p).getPermissionsHandler(); + } + + /** + * Id does getWorldDataByPlayerName(playerName). + * If it doesnt return null, it will return result.getPermissionsHandler() + * @param playerName + * @return null if the player matching gone wrong. + */ + public AnjoPermissionsHandler getWorldPermissionsByPlayerName(String playerName) { + WorldDataHolder dh = getWorldDataByPlayerName(playerName); + if (dh != null) { + return dh.getPermissionsHandler(); + } + return null; + } + + private void verifyFirstRun() { + worldsFolder = new File(plugin.getDataFolder(), "worlds"); + if (!worldsFolder.exists()) { + worldsFolder.mkdirs(); + } + Properties server = new Properties(); + try { + server.load(new FileInputStream(new File("server.properties"))); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + serverDefaultWorldName = server.getProperty("level-name").toLowerCase(); + File defaultWorldFolder = new File(worldsFolder, serverDefaultWorldName); + if (!defaultWorldFolder.exists()) { + defaultWorldFolder.mkdirs(); + } + if (defaultWorldFolder.exists()) { + File groupsFile = new File(defaultWorldFolder, "groups.yml"); + File usersFile = new File(defaultWorldFolder, "users.yml"); + File oldDataFile = new File(plugin.getDataFolder(), "data.yml"); + if (!groupsFile.exists()) { + if (oldDataFile.exists()) { + try { + Tasks.copy(oldDataFile, groupsFile); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + } else { + InputStream template = plugin.getResourceAsStream("groups.yml"); + try { + Tasks.copy(template, groupsFile); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + } + } + if (!usersFile.exists()) { + if (oldDataFile.exists()) { + try { + Tasks.copy(oldDataFile, usersFile); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + } else { + InputStream template = plugin.getResourceAsStream("users.yml"); + try { + Tasks.copy(template, usersFile); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + } + } + try { + if (oldDataFile.exists()) { + oldDataFile.renameTo(new File(plugin.getDataFolder(), "NOT_USED_ANYMORE_data.yml")); + } + } catch (Exception ex) { + } + } + } + + /** + * Copies the specified world data to another world + * @param fromWorld + * @param toWorld + * @return + */ + public boolean cloneWorld(String fromWorld, String toWorld) { + File fromWorldFolder = new File(worldsFolder, fromWorld); + File toWorldFolder = new File(worldsFolder, toWorld); + if (toWorldFolder.exists() || !fromWorldFolder.exists()) { + return false; + } + File fromWorldGroups = new File(fromWorldFolder, "groups.yml"); + File fromWorldUsers = new File(fromWorldFolder, "users.yml"); + if (!fromWorldGroups.exists() || !fromWorldUsers.exists()) { + return false; + } + File toWorldGroups = new File(toWorldFolder, "groups.yml"); + File toWorldUsers = new File(toWorldFolder, "users.yml"); + toWorldFolder.mkdirs(); + try { + Tasks.copy(fromWorldGroups, toWorldGroups); + Tasks.copy(fromWorldUsers, toWorldUsers); + } catch (IOException ex) { + Logger.getLogger(WorldsHolder.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + return true; + } + + /** + * Load a world from file. + * If it already been loaded, summon reload method from dataHolder. + * @param worldName + */ + public void loadWorld(String worldName) { + 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()) { + File groupsFile = new File(thisWorldFolder, "groups.yml"); + File usersFile = new File(thisWorldFolder, "users.yml"); + if (!groupsFile.exists()) { + throw new IllegalArgumentException("Groups file for world '" + worldName + "' doesnt exist: " + groupsFile.getPath()); + } + if (!usersFile.exists()) { + throw new IllegalArgumentException("Users file for world '" + worldName + "' doesnt exist: " + usersFile.getPath()); + } + try { + OverloadedWorldHolder thisWorldData = new OverloadedWorldHolder(WorldDataHolder.load(worldName, groupsFile, usersFile)); + if (thisWorldData != null) { + GroupManager.logger.finest("Successful load of world " + worldName + "..."); + worldsData.put(worldName.toLowerCase(), thisWorldData); + return; + } + } catch (FileNotFoundException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + return; + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + return; + } + GroupManager.logger.severe("Failed to load world " + worldName + "..."); + } + } + + /** + * Tells if the such world has been mapped. + * + * It will return true if world is a mirror. + * + * @param worldName + * @return true if world is loaded or mirrored. false if not listed + */ + public boolean isInList(String worldName) { + if (worldsData.containsKey(worldName.toLowerCase()) || mirrors.containsKey(worldName.toLowerCase())) { + return true; + } + return false; + } + + /** + * Verify if world has it's own file permissions. + * + * @param worldName + * @return true if it has its own holder. false if not. + */ + public boolean hasOwnData(String worldName) { + if (worldsData.containsKey(worldName.toLowerCase())) { + return true; + } + return false; + } + + /** + * @return the defaultWorld + */ + public OverloadedWorldHolder getDefaultWorld() { + return defaultWorld; + } + + /** + * Returns all physically loaded worlds. + * @return + */ + public ArrayList<OverloadedWorldHolder> allWorldsDataList() { + ArrayList<OverloadedWorldHolder> list = new ArrayList<OverloadedWorldHolder>(); + for (OverloadedWorldHolder data : worldsData.values()) { + if (!list.contains(data)) { + list.add(data); + } + } + return list; + } +} |