Merge branch 'master' into release

This commit is contained in:
KHobbits 2012-02-13 17:35:05 +00:00
commit 36d07cb539
22 changed files with 449 additions and 160 deletions

View File

@ -76,6 +76,7 @@ file.reference.MultiCurrency.jar=../lib/MultiCurrency.jar
file.reference.Permissions3.jar=../lib/Permissions3.jar
file.reference.PermissionsBukkit-1.2.jar=../lib/PermissionsBukkit-1.2.jar
file.reference.PermissionsEx.jar=../lib/PermissionsEx.jar
file.reference.Privileges.jar=..\\lib\\Privileges.jar
file.reference.Vault.jar=../lib/Vault.jar
includes=**
jar.archive.disabled=${jnlp.enabled}
@ -95,7 +96,8 @@ javac.classpath=\
${reference.EssentialsGroupManager.jar}:\
${file.reference.bukkit.jar}:\
${file.reference.craftbukkit.jar}:\
${file.reference.Vault.jar}
${file.reference.Vault.jar}:\
${file.reference.Privileges.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false

View File

@ -32,15 +32,20 @@ import com.earth2me.essentials.signs.SignPlayerListener;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.ChatColor;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandException;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
@ -277,7 +282,29 @@ public class Essentials extends JavaPlugin implements IEssentials
if (pc != null)
{
alternativeCommandsHandler.executed(commandLabel, pc.getLabel());
return pc.execute(sender, commandLabel, args);
try
{
return pc.execute(sender, commandLabel, args);
}
catch (final Exception ex)
{
final ArrayList<StackTraceElement> elements = new ArrayList<StackTraceElement>(Arrays.asList(ex.getStackTrace()));
elements.remove(0);
final ArrayList<StackTraceElement> toRemove = new ArrayList<StackTraceElement>();
for (final StackTraceElement e : elements)
{
if (e.getClassName().equals("com.earth2me.essentials.Essentials"))
{
toRemove.add(e);
}
}
elements.removeAll(toRemove);
final StackTraceElement[] trace = elements.toArray(new StackTraceElement[elements.size()]);
ex.setStackTrace(trace);
ex.printStackTrace();
sender.sendMessage(ChatColor.RED + "An internal error occurred while attempting to perform this command");
return true;
}
}
}

View File

@ -1,8 +1,9 @@
package com.earth2me.essentials.commands;
import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.User;
import com.earth2me.essentials.Util;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
public class Commandping extends EssentialsCommand
@ -13,8 +14,16 @@ public class Commandping extends EssentialsCommand
}
@Override
public void run(Server server, User player, String commandLabel, String[] args) throws Exception
public void run(final Server server, final CommandSender sender, final String commandLabel, final String[] args) throws Exception
{
player.sendMessage(_("pong"));
if (args.length < 1)
{
sender.sendMessage(_("pong"));
}
else
{
sender.sendMessage(Util.replaceColor(getFinalArg(args, 0)));
}
}
}

View File

@ -2,6 +2,7 @@ package com.earth2me.essentials.commands;
import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.Mob;
import com.earth2me.essentials.Trade;
import com.earth2me.essentials.User;
import com.earth2me.essentials.Util;
import java.util.Locale;
@ -47,11 +48,14 @@ public class Commandspawner extends EssentialsCommand
{
throw new Exception(_("unableToSpawnMob"));
}
if (!user.isAuthorized("essentials.spawner." + mob.name.toLowerCase()))
if (!user.isAuthorized("essentials.spawner." + mob.name.toLowerCase(Locale.ENGLISH)))
{
throw new Exception(_("unableToSpawnMob"));
}
final Trade charge = new Trade("spawner-" + mob.name.toLowerCase(Locale.ENGLISH), ess);
charge.isAffordableFor(user);
((CreatureSpawner)target.getBlock().getState()).setCreatureType(mob.getType());
charge.charge(user);
user.sendMessage(_("setSpawner", mob.name));
}
catch (Throwable ex)

View File

@ -30,7 +30,13 @@ public class Commandsudo extends EssentialsCommand
}
//TODO: Translate this.
sender.sendMessage("Running the command as " + user.getDisplayName());
if (user.isAuthorized("essentials.sudo.exempt"))
{
throw new Exception("You cannot sudo this user");
}
//TODO: Translate this.
sender.sendMessage("Forcing " + user.getDisplayName() + " to run: /" + command + " " + arguments);
final PluginCommand execCommand = ess.getServer().getPluginCommand(command);
if (execCommand != null)

View File

@ -22,7 +22,9 @@ public class Commandtpaccept extends EssentialsCommand
final User target = user.getTeleportRequest();
if (target == null
|| target.getBase() instanceof OfflinePlayer
|| (user.isTeleportRequestHere() && !target.isAuthorized("essentials.tpahere")))
|| (user.isTeleportRequestHere() && !target.isAuthorized("essentials.tpahere"))
|| (!user.isTeleportRequestHere() && !target.isAuthorized("essentials.tpa") && !target.isAuthorized("essentials.tpaall"))
)
{
throw new Exception(_("noPendingRequest"));
}

View File

@ -8,6 +8,7 @@ import com.earth2me.essentials.Warps;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
@ -44,10 +45,10 @@ public class Commandwarp extends EssentialsCommand
{
throw new Exception(_("playerNotFound"));
}
warpUser(otherUser, args[0]);
warpUser(user, otherUser, args[0]);
throw new NoChargeException();
}
warpUser(user, args[0]);
warpUser(user, user, args[0]);
throw new NoChargeException();
}
}
@ -65,7 +66,7 @@ public class Commandwarp extends EssentialsCommand
{
throw new Exception(_("playerNotFound"));
}
warpUser(otherUser, args[0]);
otherUser.getTeleport().warp(args[0], null, TeleportCause.COMMAND);
throw new NoChargeException();
}
@ -112,17 +113,12 @@ public class Commandwarp extends EssentialsCommand
}
}
private void warpUser(final User user, final String name) throws Exception
private void warpUser(final User owner, final User user, final String name) throws Exception
{
final Trade charge = new Trade(this.getName(), ess);
charge.isAffordableFor(user);
if (ess.getSettings().getPerWarpPermission())
final Trade charge = new Trade("warp-" + name.toLowerCase(Locale.ENGLISH).replace('_', '-'), ess);
charge.isAffordableFor(owner);
if (ess.getSettings().getPerWarpPermission() && !owner.isAuthorized("essentials.warp." + name))
{
if (user.isAuthorized("essentials.warp." + name))
{
user.getTeleport().warp(name, charge, TeleportCause.COMMAND);
return;
}
throw new Exception(_("warpUsePermission"));
}
user.getTeleport().warp(name, charge, TeleportCause.COMMAND);

View File

@ -144,6 +144,17 @@ public class PermissionsHandler implements IPermissionsHandler
return;
}
final Plugin privPlugin = pluginManager.getPlugin("Privileges");
if (privPlugin != null && privPlugin.isEnabled())
{
if (!(handler instanceof PrivilegesHandler))
{
LOGGER.log(Level.INFO, "Essentials: Using Privileges based permissions.");
handler = new PrivilegesHandler(privPlugin);
}
return;
}
final Plugin permPlugin = pluginManager.getPlugin("Permissions");
if (permPlugin != null && permPlugin.isEnabled())
{

View File

@ -0,0 +1,61 @@
package com.earth2me.essentials.perm;
import java.util.ArrayList;
import java.util.List;
import net.krinsoft.privileges.Privileges;
import net.krinsoft.privileges.groups.Group;
import net.krinsoft.privileges.groups.GroupManager;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public class PrivilegesHandler extends SuperpermsHandler
{
private final transient Privileges plugin;
private final GroupManager manager;
public PrivilegesHandler(final Plugin plugin)
{
this.plugin = (Privileges) plugin;
this.manager = this.plugin.getGroupManager();
}
@Override
public String getGroup(final Player base)
{
Group group = manager.getGroup(base);
if (group == null)
{
return null;
}
return group.getName();
}
@Override
public List<String> getGroups(final Player base)
{
Group group = manager.getGroup(base);
if (group == null)
{
return new ArrayList<String>();
}
return group.getGroupTree();
}
@Override
public boolean inGroup(final Player base, final String group)
{
Group pGroup = manager.getGroup(base);
if (pGroup == null)
{
return false;
}
return pGroup.isMemberOf(group);
}
@Override
public boolean canBuild(Player base, String group)
{
return base.hasPermission("essentials.build") || base.hasPermission("privileges.build");
}
}

View File

@ -36,7 +36,7 @@ public class SignTrade extends EssentialsSign
try
{
stored = getTrade(sign, 1, true, true, ess);
substractAmount(sign, 1, stored, ess);
subtractAmount(sign, 1, stored, ess);
stored.pay(player);
}
catch (SignException e)
@ -53,12 +53,14 @@ public class SignTrade extends EssentialsSign
final Trade charge = getTrade(sign, 1, false, false, ess);
final Trade trade = getTrade(sign, 2, false, true, ess);
charge.isAffordableFor(player);
addAmount(sign, 1, charge, ess);
subtractAmount(sign, 2, trade, ess);
if (!trade.pay(player, false))
{
subtractAmount(sign, 1, charge, ess);
addAmount(sign, 2, trade, ess);
throw new ChargeException("Full inventory");
}
substractAmount(sign, 2, trade, ess);
addAmount(sign, 1, charge, ess);
charge.charge(player);
Trade.log("Sign", "Trade", "Interact", sign.getLine(3), charge, username, trade, sign.getBlock().getLocation(), ess);
}
@ -256,7 +258,7 @@ public class SignTrade extends EssentialsSign
throw new SignException(_("invalidSignLine", index + 1));
}
protected final void substractAmount(final ISign sign, final int index, final Trade trade, final IEssentials ess) throws SignException
protected final void subtractAmount(final ISign sign, final int index, final Trade trade, final IEssentials ess) throws SignException
{
final Double money = trade.getMoney();
if (money != null)
@ -294,6 +296,7 @@ public class SignTrade extends EssentialsSign
}
}
//TODO: Translate these exceptions.
private void changeAmount(final ISign sign, final int index, final double value, final IEssentials ess) throws SignException
{
@ -313,7 +316,7 @@ public class SignTrade extends EssentialsSign
final String newline = Util.formatCurrency(money, ess) + ":" + Util.formatCurrency(amount + value, ess).substring(1);
if (newline.length() > 15)
{
throw new SignException("Line too long!");
throw new SignException("This sign is full: Line too long!");
}
sign.setLine(index, newline);
return;
@ -329,7 +332,7 @@ public class SignTrade extends EssentialsSign
final String newline = stackamount + " " + split[1] + ":" + (amount + Math.round(value));
if (newline.length() > 15)
{
throw new SignException("Line too long!");
throw new SignException("This sign is full: Line too long!");
}
sign.setLine(index, newline);
return;
@ -343,7 +346,7 @@ public class SignTrade extends EssentialsSign
final String newline = stackamount + " " + split[1] + ":" + (amount + Math.round(value));
if (newline.length() > 15)
{
throw new SignException("Line too long!");
throw new SignException("This sign is full: Line too long!");
}
sign.setLine(index, newline);
return;

View File

@ -36,7 +36,7 @@ public class ChatStore
public String getLongType()
{
return type.length() > 0 ? "chat" : "chat-" + type;
return type.length() == 0 ? "chat" : "chat-" + type;
}
public long getRadius()

View File

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

View File

@ -158,7 +158,7 @@ public class GroupManager extends JavaPlugin {
System.out.println(pdfFile.getName() + " version " + pdfFile.getVersion() + " is enabled!");
// 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() {
@ -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;
@ -1762,9 +1763,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;
}

View File

@ -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() {

View File

@ -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?

View File

@ -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);
}
/**

View File

@ -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);
}
/**

View File

@ -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

View File

@ -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);
}
}

View File

@ -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())

View File

@ -34,6 +34,7 @@ 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;
@ -358,6 +359,11 @@ public class BukkitPermissions {
}
setPlayer_join(false);
}
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerChangeWorld(PlayerChangedWorldEvent event) { // will portal into another world
updatePermissions(event.getPlayer(), event.getPlayer().getWorld().getName());
}
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerPortal(PlayerPortalEvent event) { // will portal into another world

BIN
lib/Privileges.jar Normal file

Binary file not shown.