Merge branch 'groupmanager' of github.com:essentials/Essentials into 2.9

This commit is contained in:
KHobbits 2012-08-06 09:17:19 +01:00
commit 9b39a227c9
9 changed files with 193 additions and 124 deletions

View file

@ -183,4 +183,12 @@ v 2.0:
- Re-initialize the WorldsHolder on a reload, as un-registering and re-registering a new holder means all plugins have to check for the new service on every quiery.
- Prevent null perms getting past the GlobalGroups loader.
- Fix forgetting sub groups on a manload.
- Allow 'manucheckp' to notify when superperms reports false but it is really negated.
- Allow 'manucheckp' to notify when superperms reports false but it is really negated.
- Only output a Data update message if something has changed.
- Fix loading users with only numerals in their names to be seen as strings.
- Ignore any sub folders in the Worlds folder which start with a period (fix for storing data in svn respoitories).
- Throw a better error than 'null' when someone removes all groups from a yml.
- Stop force removing attachments and let Bukkit handle it's own mess.
- Change to our own Yaml parsing for globalgroups instead of using the YAMLConfiguration class in bukkit.
- Fix a cases sensitivity bug in world loading.
- Stop using the YamlConfiguration in bukkit for our config handling. We can now support periods in world names.

View file

@ -6,7 +6,7 @@
# They can also be added as one of a users subgroups, but NOT as a primary group.
# These collections are available to ALL group and user yml's.
#
# Add to and customize these groups to fit yoru needs.
# Add to and customize these groups to fit your needs.
groups:

View file

@ -5,22 +5,32 @@
package org.anjocaido.groupmanager;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import org.anjocaido.groupmanager.utils.Tasks;
import org.bukkit.configuration.file.YamlConfiguration;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.reader.UnicodeReader;
/**
*
* @author gabrielcouto
*/
public class GMConfiguration {
private boolean opOverride;
private boolean toggleValidate;
private Integer saveInterval;
private Integer backupDuration;
private String loggerLevel;
private Map<String, Object> mirrorsMap;
private GroupManager plugin;
private File configFile;
private YamlConfiguration GMconfig;
private Map<String, Object> GMconfig;
public GMConfiguration(GroupManager plugin) {
@ -28,12 +38,14 @@ public class GMConfiguration {
load();
}
@SuppressWarnings("unchecked")
public void load() {
if (!plugin.getDataFolder().exists()) {
plugin.getDataFolder().mkdirs();
}
configFile = new File(plugin.getDataFolder(), "config.yml");
File configFile = new File(plugin.getDataFolder(), "config.yml");
if (!configFile.exists()) {
try {
@ -43,59 +55,94 @@ public class GMConfiguration {
}
}
GMconfig = new YamlConfiguration();
Yaml configYAML = new Yaml(new SafeConstructor());
try {
GMconfig.load(configFile);
FileInputStream configInputStream = new FileInputStream(configFile);
GMconfig = (Map<String, Object>) configYAML.load(new UnicodeReader(configInputStream));
configInputStream.close();
} catch (Exception ex) {
throw new IllegalArgumentException("The following file couldn't pass on Parser.\n" + configFile.getPath(), ex);
}
/*
* Read our config settings ands store them for reading later.
*/
Map<String, Object> config = getElement("config", getElement("settings", GMconfig));
opOverride = (Boolean) config.get("opOverrides");
toggleValidate = (Boolean) config.get("validate_toggle");
/*
* data node for save/backup timers.
*/
Map<String, Object> save = getElement("save", getElement("data", getElement("settings", GMconfig)));
saveInterval = (Integer) save.get("minutes");
backupDuration = (Integer) save.get("hours");
loggerLevel = ((Map<String, String>) getElement("settings", GMconfig).get("logging")).get("level");
/*
* Store our mirrors map for parsing later.
*/
mirrorsMap = (Map<String, Object>) ((Map<String, Object>) GMconfig.get("settings")).get("mirrors");
// Setup defaults
adjustLoggerLevel();
plugin.setValidateOnlinePlayer(isToggleValidate());
}
@SuppressWarnings("unchecked")
private Map<String, Object> getElement(String element, Map<String, Object> map) {
if (!map.containsKey(element)) {
throw new IllegalArgumentException("The config.yml has no '" + element + ".\n");
}
return (Map<String, Object>) map.get(element);
}
public boolean isOpOverride() {
return GMconfig.getBoolean("settings.config.opOverrides", true);
return opOverride;
}
public boolean isToggleValidate() {
return GMconfig.getBoolean("settings.config.validate_toggle", true);
}
public Map<String, Object> getMirrorsMap() {
// Try to fetch the old mirror path first
if (GMconfig.isConfigurationSection("settings.permission.world.mirror")) {
return (Map<String, Object>) GMconfig.getConfigurationSection("settings.permission.world.mirror").getValues(false);
} else if (GMconfig.isConfigurationSection("settings.mirrors")) {
return (Map<String, Object>) GMconfig.getConfigurationSection("settings.mirrors").getValues(false);
}
return null;
return toggleValidate;
}
public Integer getSaveInterval() {
return GMconfig.getInt("settings.data.save.minutes", 10);
return saveInterval;
}
public Integer getBackupDuration() {
return GMconfig.getInt("settings.data.save.hours", 24);
return backupDuration;
}
public void adjustLoggerLevel() {
try {
GroupManager.logger.setLevel(Level.parse(GMconfig.getString("settings.logging.level", "INFO")));
GroupManager.logger.setLevel(Level.parse(loggerLevel));
return;
} catch (Exception e) {
}
GroupManager.logger.setLevel(Level.INFO);
}
public Map<String, Object> getMirrorsMap() {
if (!mirrorsMap.isEmpty()) {
return mirrorsMap;
}
return null;
}
}

View file

@ -1,6 +1,7 @@
package org.anjocaido.groupmanager;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
@ -20,9 +21,10 @@ import org.anjocaido.groupmanager.events.GroupManagerEventHandler;
import org.anjocaido.groupmanager.utils.PermissionCheckResult;
import org.anjocaido.groupmanager.utils.Tasks;
import org.bukkit.configuration.MemorySection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.reader.UnicodeReader;
/**
* @author ElgarL
@ -31,7 +33,7 @@ import org.yaml.snakeyaml.Yaml;
public class GlobalGroups {
private GroupManager plugin;
private YamlConfiguration GGroups;
//private Yaml GGroups;
private Map<String, Group> groups;
@ -89,8 +91,9 @@ public class GlobalGroups {
@SuppressWarnings("unchecked")
public void load() {
GGroups = new YamlConfiguration();
Yaml GGroupYAML = new Yaml(new SafeConstructor());
Map<String, Object> GGroups;
GroupManager.setLoaded(false);
// READ globalGroups FILE
@ -106,8 +109,13 @@ public class GlobalGroups {
}
}
/*
* Load the YAML file.
*/
try {
GGroups.load(GlobalGroupsFile);
FileInputStream groupsInputStream = new FileInputStream(GlobalGroupsFile);
GGroups = (Map<String, Object>) GGroupYAML.load(new UnicodeReader(groupsInputStream));
groupsInputStream.close();
} catch (Exception ex) {
throw new IllegalArgumentException("The following file couldn't pass on Parser.\n" + GlobalGroupsFile.getPath(), ex);
}
@ -115,12 +123,12 @@ public class GlobalGroups {
// Clear out old groups
resetGlobalGroups();
if (!GGroups.getKeys(false).isEmpty()) {
if (!GGroups.keySet().isEmpty()) {
// Read all global groups
Map<String, Object> allGroups = new HashMap<String, Object>();
try {
allGroups = (Map<String, Object>) GGroups.getConfigurationSection("groups").getValues(false);
allGroups = (Map<String, Object>) GGroups.get("groups");
} catch (Exception ex) {
// ex.printStackTrace();
throw new IllegalArgumentException("Your " + GlobalGroupsFile.getPath() + " file is invalid. See console for details.", ex);

View file

@ -324,8 +324,8 @@ public class GroupManager extends JavaPlugin {
public void run() {
try {
worldsHolder.saveChanges(false);
GroupManager.logger.log(Level.INFO, " Data files refreshed.");
if (worldsHolder.saveChanges(false))
GroupManager.logger.log(Level.INFO, " Data files refreshed.");
} catch (IllegalStateException ex) {
GroupManager.logger.log(Level.WARNING, ex.getMessage());
}

View file

@ -508,6 +508,10 @@ public class WorldDataHolder {
} catch (Exception ex) {
throw new IllegalArgumentException("Your " + groupsFile.getPath() + " file is invalid. See console for details.", ex);
}
if (allGroupsNode == null) {
throw new IllegalArgumentException("You have no groups in " + groupsFile.getPath() + ".");
}
Iterator<String> groupItr = allGroupsNode.keySet().iterator();
String groupKey;
@ -775,20 +779,26 @@ public class WorldDataHolder {
Iterator<String> usersItr = allUsersNode.keySet().iterator();
String usersKey;
Object node;
Integer userCount = 0;
while (usersItr.hasNext()) {
try {
userCount++;
// Attempt to fetch the next user name.
usersKey = usersItr.next();
node = usersItr.next();
if (node instanceof Integer)
usersKey = Integer.toString((Integer)node);
else
usersKey = node.toString();
} catch (Exception ex) {
throw new IllegalArgumentException("Invalid node type for user entry (" + userCount + ") in file: " + usersFile.getPath(), ex);
}
Map<String, Object> thisUserNode = null;
try {
thisUserNode = (Map<String, Object>) allUsersNode.get(usersKey);
thisUserNode = (Map<String, Object>) allUsersNode.get(node);
} catch (Exception ex) {
throw new IllegalArgumentException("Bad format found for user: " + usersKey + " in file: " + usersFile.getPath());
}

View file

@ -22,7 +22,6 @@ import org.anjocaido.groupmanager.dataholder.OverloadedWorldHolder;
import org.anjocaido.groupmanager.permissions.AnjoPermissionsHandler;
import org.anjocaido.groupmanager.utils.Tasks;
import org.bukkit.World;
import org.bukkit.configuration.MemorySection;
import org.bukkit.entity.Player;
/**
@ -97,15 +96,19 @@ public class WorldsHolder {
* Create the data files if they don't already exist,
* and they are not mirrored.
*/
for (World world : plugin.getServer().getWorlds())
if ((!worldsData.containsKey(world.getName().toLowerCase())) && ((!mirrorsGroup.containsKey(world.getName().toLowerCase())) || (!mirrorsUser.containsKey(world.getName().toLowerCase()))))
for (World world : plugin.getServer().getWorlds()){
GroupManager.logger.log(Level.FINE, "Checking data for " + world.getName() + ".");
if ((!worldsData.containsKey(world.getName().toLowerCase())) && ((!mirrorsGroup.containsKey(world.getName().toLowerCase())) || (!mirrorsUser.containsKey(world.getName().toLowerCase())))) {
GroupManager.logger.log(Level.FINE, "Creating folders for " + world.getName() + ".");
setupWorldFolder(world.getName());
}
}
/*
* Loop over all folders within the worlds folder
* and attempt to load the world data
*/
for (File folder : worldsFolder.listFiles()) {
if (folder.isDirectory()) {
if (folder.isDirectory() && !folder.getName().startsWith(".")) {
GroupManager.logger.info("World Found: " + folder.getName());
/*
@ -164,12 +167,12 @@ public class WorldsHolder {
} else
GroupManager.logger.log(Level.WARNING, "Mirroring error with " + o.toString() + ". Recursive loop detected!");
}
} else if (mirrorsMap.get(source) instanceof MemorySection) {
MemorySection subSection = (MemorySection) mirrorsMap.get(source);
} else if (mirrorsMap.get(source) instanceof Map) {
Map subSection = (Map) mirrorsMap.get(source);
for (String key : subSection.getKeys(true)) {
for (Object key : subSection.keySet()) {
if (key.toLowerCase() != serverDefaultWorldName) {
if (((String)key).toLowerCase() != serverDefaultWorldName) {
if (subSection.get(key) instanceof ArrayList) {
ArrayList mirrorList = (ArrayList) subSection.get(key);
@ -179,28 +182,32 @@ public class WorldsHolder {
String type = o.toString().toLowerCase();
try {
if (type.equals("groups"))
mirrorsGroup.remove(key.toLowerCase());
mirrorsGroup.remove(((String)key).toLowerCase());
if (type.equals("users"))
mirrorsUser.remove(key.toLowerCase());
mirrorsUser.remove(((String)key).toLowerCase());
} catch (Exception e) {
}
if (type.equals("groups"))
mirrorsGroup.put(key.toLowerCase(), getWorldData(source).getName());
if (type.equals("groups")) {
mirrorsGroup.put(((String)key).toLowerCase(), getWorldData(source).getName());
GroupManager.logger.log(Level.FINE, "Adding groups mirror for " + key + ".");
}
if (type.equals("users"))
mirrorsUser.put(key.toLowerCase(), getWorldData(source).getName());
if (type.equals("users")) {
mirrorsUser.put(((String)key).toLowerCase(), getWorldData(source).getName());
GroupManager.logger.log(Level.FINE, "Adding users mirror for " + key + ".");
}
}
// Track this world so we can create a datasource for it later
mirroredWorlds.add(key);
mirroredWorlds.add((String)key);
} else
GroupManager.logger.log(Level.WARNING, "Mirroring error with " + key + ". Recursive loop detected!");
GroupManager.logger.log(Level.WARNING, "Mirroring error with " + (String)key + ". Recursive loop detected!");
} else {
throw new IllegalStateException("Unknown mirroring format for " + key);
throw new IllegalStateException("Unknown mirroring format for " + (String)key);
}
}
@ -210,6 +217,7 @@ public class WorldsHolder {
// Create a datasource for any worlds not already loaded
for (String world : mirroredWorlds) {
if (!worldsData.containsKey(world.toLowerCase())) {
GroupManager.logger.log(Level.FINE, "No data for " + world + ".");
setupWorldFolder(world);
loadWorld(world, true);
}
@ -264,8 +272,9 @@ public class WorldsHolder {
/**
*
*/
public void saveChanges(boolean overwrite) {
public boolean saveChanges(boolean overwrite) {
boolean changed = false;
ArrayList<WorldDataHolder> alreadyDone = new ArrayList<WorldDataHolder>();
Tasks.removeOldFiles(plugin, plugin.getBackupFolder());
@ -294,6 +303,7 @@ public class WorldsHolder {
backupFile(w, true);
WorldDataHolder.writeGroups(w, w.getGroupsFile());
changed = true;
//w.removeGroupsChangedFlag();
} else {
// Newer file found.
@ -307,6 +317,7 @@ public class WorldsHolder {
// Backup Groups file
backupFile(w, true);
w.reloadGroups();
changed = true;
}
}
if (!mirrorsUser.containsKey(w.getName().toLowerCase()))
@ -316,6 +327,7 @@ public class WorldsHolder {
backupFile(w, false);
WorldDataHolder.writeUsers(w, w.getUsersFile());
changed = true;
//w.removeUsersChangedFlag();
} else {
// Newer file found.
@ -329,10 +341,12 @@ public class WorldsHolder {
// Backup Users file
backupFile(w, false);
w.reloadUsers();
changed = true;
}
}
alreadyDone.add(w);
}
return changed;
}
/**
@ -606,7 +620,7 @@ public class WorldsHolder {
throw new IllegalArgumentException("Users file for world '" + worldName + "' doesnt exist: " + usersFile.getPath());
}
WorldDataHolder tempHolder = new WorldDataHolder(worldName);
WorldDataHolder tempHolder = new WorldDataHolder(worldNameLowered);
// Map the group object for any mirror
if (mirrorsGroup.containsKey(worldNameLowered))

View file

@ -920,6 +920,7 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface {
Group now = stack.pop();
PermissionCheckResult resultNow = checkGroupOnlyPermission(now, targetPermission);
if (!resultNow.resultType.equals(PermissionCheckResult.Type.NOTFOUND)) {
resultNow.accessLevel = targetPermission;
return resultNow;
}
for (String sonName : now.getInherits()) {

View file

@ -21,7 +21,6 @@ import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
@ -40,7 +39,6 @@ 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.PlayerQuitEvent;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
@ -57,7 +55,7 @@ import org.bukkit.plugin.PluginManager;
*/
public class BukkitPermissions {
protected WeakHashMap<Player, PermissionAttachment> attachments = new WeakHashMap<Player, PermissionAttachment>();
protected WeakHashMap<String, PermissionAttachment> attachments = new WeakHashMap<String, PermissionAttachment>();
protected LinkedHashMap<String, Permission> registeredPermissions = new LinkedHashMap<String, Permission>();
protected GroupManager plugin;
protected boolean dumpAllPermissions = true;
@ -146,19 +144,21 @@ public class BukkitPermissions {
return;
}
String name = player.getName();
// Reset the User objects player reference.
User user = plugin.getWorldsHolder().getWorldData(player.getWorld().getName()).getUser(player.getName());
User user = plugin.getWorldsHolder().getWorldData(player.getWorld().getName()).getUser(name);
if (user != null)
user.updatePlayer(player);
PermissionAttachment attachment;
// Find the players current attachment, or add a new one.
if (this.attachments.containsKey(player)) {
attachment = this.attachments.get(player);
if (this.attachments.containsKey(name)) {
attachment = this.attachments.get(name);
} else {
attachment = player.addAttachment(plugin);
this.attachments.put(player, attachment);
this.attachments.put(name, attachment);
}
if (world == null) {
@ -167,7 +167,7 @@ public class BukkitPermissions {
// Add all permissions for this player (GM only)
// child nodes will be calculated by Bukkit.
List<String> playerPermArray = new ArrayList<String>(plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getAllPlayersPermissions(player.getName(), false));
List<String> playerPermArray = new ArrayList<String>(plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getAllPlayersPermissions(name, false));
LinkedHashMap<String, Boolean> newPerms = new LinkedHashMap<String, Boolean>();
// Sort the perm list by parent/child, so it will push to superperms correctly.
@ -192,13 +192,15 @@ public class BukkitPermissions {
// Then whack our map into there
orig.putAll(newPerms);
// That's all folks!
//attachment.getPermissible().recalculatePermissions();
player.recalculatePermissions();
attachment.getPermissible().recalculatePermissions();
//player.recalculatePermissions();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
GroupManager.logger.finest("Attachment updated for: " + name);
}
/**
@ -212,26 +214,31 @@ public class BukkitPermissions {
List<String> result = new ArrayList<String>();
for (String key : permList) {
String a = key.charAt(0) == '-' ? key.substring(1) : key;
Map<String, Boolean> allchildren = GroupManager.BukkitPermissions.getAllChildren(a, new HashSet<String>());
if (allchildren != null) {
ListIterator<String> itr = result.listIterator();
while (itr.hasNext()) {
String node = (String) itr.next();
String b = node.charAt(0) == '-' ? node.substring(1) : node;
// Insert the parent node before the child
if (allchildren.containsKey(b)) {
itr.set(key);
itr.add(node);
break;
/*
* Ignore stupid plugins which add empty permission nodes.
*/
if (!key.isEmpty()) {
String a = key.charAt(0) == '-' ? key.substring(1) : key;
Map<String, Boolean> allchildren = GroupManager.BukkitPermissions.getAllChildren(a, new HashSet<String>());
if (allchildren != null) {
ListIterator<String> itr = result.listIterator();
while (itr.hasNext()) {
String node = (String) itr.next();
String b = node.charAt(0) == '-' ? node.substring(1) : node;
// Insert the parent node before the child
if (allchildren.containsKey(b)) {
itr.set(key);
itr.add(node);
break;
}
}
}
if (!result.contains(key))
result.add(key);
}
if (!result.contains(key))
result.add(key);
}
return result;
@ -373,19 +380,10 @@ public class BukkitPermissions {
*
* @param player
*/
private void removeAttachment(Player player) {
private void removeAttachment(String playerName) {
if (attachments.containsKey(player)) {
try {
player.removeAttachment(attachments.get(player));
} catch (IllegalArgumentException e) {
/*
* Failed to remove attachment
* This usually means Bukkit no longer knows of it.
*/
}
attachments.remove(player);
}
if (attachments.containsKey(playerName))
attachments.remove(playerName);
}
/**
@ -393,19 +391,6 @@ public class BukkitPermissions {
*/
public void removeAllAttachments() {
Iterator<Player> itr = attachments.keySet().iterator();
while (itr.hasNext()) {
Player player = itr.next();
try {
player.removeAttachment(attachments.get(player));
} catch (IllegalArgumentException e) {
/*
* Failed to remove attachment
* This usually means Bukkit no longer knows of it.
*/
}
}
attachments.clear();
}
@ -420,13 +405,17 @@ public class BukkitPermissions {
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerJoin(PlayerJoinEvent event) {
setPlayer_join(true);
Player player = event.getPlayer();
GroupManager.logger.finest("Player Join event: " + player.getName());
/*
* Tidy up any lose ends
*/
removeAttachment(player);
removeAttachment(player.getName());
// force GM to create the player if they are not already listed.
if (plugin.getWorldsHolder().getWorldData(player.getWorld().getName()).getUser(player.getName()) != null) {
@ -441,19 +430,11 @@ public class BukkitPermissions {
updatePermissions(event.getPlayer(), event.getPlayer().getWorld().getName());
}
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerKick(PlayerKickEvent event) {
Player player = event.getPlayer();
/*
* force remove any attachments as bukkit may not
*/
removeAttachment(player);
}
@EventHandler(priority = EventPriority.LOWEST)
/*
* Trigger at highest so we tidy up last.
*/
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerQuit(PlayerQuitEvent event) {
if (!GroupManager.isLoaded())
@ -464,7 +445,7 @@ public class BukkitPermissions {
/*
* force remove any attachments as bukkit may not
*/
removeAttachment(player);
removeAttachment(player.getName());
}
}
@ -488,4 +469,4 @@ public class BukkitPermissions {
}
}
}
}