diff --git a/pom.xml b/pom.xml index 4e63c8ad..864f1c59 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ com.sk89q worldedit - 4.7 + 5.0 diff --git a/src/main/java/com/sk89q/worldguard/bukkit/LegacyWorldGuardMigration.java b/src/main/java/com/sk89q/worldguard/bukkit/LegacyWorldGuardMigration.java index dcac8b1c..13ad7cf1 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/LegacyWorldGuardMigration.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/LegacyWorldGuardMigration.java @@ -87,7 +87,7 @@ public static void migrateRegions(WorldGuardPlugin plugin) { File oldDatabase = new File(plugin.getDataFolder(), "regions.txt"); if (!oldDatabase.exists()) return; - logger.info("WorldGuard: The regions database has changed in 4.x. " + logger.info("WorldGuard: The regions database has changed in 5.x. " + "Your old regions database will be converted to the new format " + "and set as your primarily world's database."); diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java index 32f8d05f..0b47ef84 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java @@ -34,6 +34,9 @@ import java.util.logging.Logger; import java.util.zip.ZipEntry; +import com.sk89q.minecraft.util.commands.*; +import com.sk89q.wepif.PermissionsResolverManager; +import com.sk89q.worldguard.util.CommandRegistration; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.World; @@ -45,14 +48,6 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; -import com.sk89q.bukkit.migration.PermissionsResolverManager; -import com.sk89q.minecraft.util.commands.CommandException; -import com.sk89q.minecraft.util.commands.CommandPermissionsException; -import com.sk89q.minecraft.util.commands.CommandUsageException; -import com.sk89q.minecraft.util.commands.CommandsManager; -import com.sk89q.minecraft.util.commands.MissingNestedCommandException; -import com.sk89q.minecraft.util.commands.WrappedCommandException; -import com.sk89q.minecraft.util.commands.Injector; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldguard.LocalPlayer; import com.sk89q.worldguard.TickSyncDelayLoggerFilter; @@ -90,14 +85,6 @@ public class WorldGuardPlugin extends JavaPlugin { */ private final ConfigurationManager configuration; - /** - * Processes queries for permissions information. The permissions manager - * is from WorldEdit and it automatically handles looking up permissions - * systems and picking the right one. WorldGuard just needs to call - * the permission methods. - */ - private PermissionsResolverManager perms; - /** * Used for scheduling flags. */ @@ -110,7 +97,7 @@ public class WorldGuardPlugin extends JavaPlugin { public WorldGuardPlugin() { configuration = new ConfigurationManager(this); globalRegionManager = new GlobalRegionManager(this); - + final WorldGuardPlugin plugin = this; commands = new CommandsManager() { @Override @@ -118,35 +105,28 @@ public boolean hasPermission(CommandSender player, String perm) { return plugin.hasPermission(player, perm); } }; - commands.setInjector(new Injector() { - public Object getInstance(Class cls) throws InvocationTargetException, IllegalAccessException, InstantiationException { - try { - return cls.getConstructor(WorldGuardPlugin.class).newInstance(plugin); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - return null; - } - } - }); - - // Register command classes - commands.register(ToggleCommands.class); - commands.register(ProtectionCommands.class); - commands.register(GeneralCommands.class); } /** * Called on plugin enable. */ public void onEnable() { + + // Set the proper command injector + commands.setInjector(new SimpleInjector(this)); + + // Register command classes + final CommandRegistration reg = new CommandRegistration(this, commands); + reg.register(ToggleCommands.class); + reg.register(ProtectionCommands.class); + reg.register(GeneralCommands.class); + // Need to create the plugins/WorldGuard folder getDataFolder().mkdirs(); - // Set up permissions - perms = new PermissionsResolverManager(this, getDescription().getName(), logger); - perms.load(); + PermissionsResolverManager.initialize(this); - // This must be done before configuration is laoded + // This must be done before configuration is loaded LegacyWorldGuardMigration.migrateBlacklist(this); // Load the configuration @@ -285,7 +265,7 @@ public ConfigurationManager getGlobalStateManager() { */ public boolean inGroup(Player player, String group) { try { - return perms.inGroup(player.getName(), group); + return PermissionsResolverManager.getInstance().inGroup(player, group); } catch (Throwable t) { t.printStackTrace(); return false; @@ -300,7 +280,7 @@ public boolean inGroup(Player player, String group) { */ public String[] getGroups(Player player) { try { - return perms.getGroups(player.getName()); + return PermissionsResolverManager.getInstance().getGroups(player); } catch (Throwable t) { t.printStackTrace(); return new String[0]; @@ -358,7 +338,7 @@ public boolean hasPermission(CommandSender sender, String perm) { // Invoke the permissions resolver if (sender instanceof Player) { Player player = (Player) sender; - return perms.hasPermission(player.getWorld().getName(), player.getName(), perm); + return PermissionsResolverManager.getInstance().hasPermission(player.getWorld().getName(), player.getName(), perm); } return false; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/commands/ProtectionCommands.java b/src/main/java/com/sk89q/worldguard/bukkit/commands/ProtectionCommands.java index 1ca1f9f7..4430ca9b 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/commands/ProtectionCommands.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/commands/ProtectionCommands.java @@ -34,11 +34,11 @@ public ProtectionCommands(WorldGuardPlugin plugin) { this.plugin = plugin; } - @Command(aliases = {"region"}, desc = "Region management commands") + @Command(aliases = {"region", "regions", "rg"}, desc = "Region management commands") @NestedCommand({RegionCommands.class, RegionMemberCommands.class}) public void region(CommandContext args, CommandSender sender) {} - @Command(aliases = {"worldguard"}, desc = "WorldGuard commands") + @Command(aliases = {"worldguard", "wg"}, desc = "WorldGuard commands") @NestedCommand({WorldGuardCommands.class}) public void worldGuard(CommandContext args, CommandSender sender) {} } diff --git a/src/main/java/com/sk89q/worldguard/bukkit/commands/ToggleCommands.java b/src/main/java/com/sk89q/worldguard/bukkit/commands/ToggleCommands.java index 2d086fc5..f0c423e8 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/commands/ToggleCommands.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/commands/ToggleCommands.java @@ -97,7 +97,7 @@ public void allowFire(CommandContext args, CommandSender sender) throws CommandE wcfg.fireSpreadDisableToggle = false; } - @Command(aliases = {"halt-activity"}, + @Command(aliases = {"halt-activity", "stoplag", "haltactivity"}, desc = "Attempts to cease as much activity in order to stop lag", flags = "c", max = 0) @CommandPermissions({"worldguard.halt-activity"}) public void stopLag(CommandContext args, CommandSender sender) throws CommandException { diff --git a/src/main/java/com/sk89q/worldguard/protection/databases/YAMLDatabase.java b/src/main/java/com/sk89q/worldguard/protection/databases/YAMLDatabase.java index eae3506e..ebd356d1 100644 --- a/src/main/java/com/sk89q/worldguard/protection/databases/YAMLDatabase.java +++ b/src/main/java/com/sk89q/worldguard/protection/databases/YAMLDatabase.java @@ -29,6 +29,9 @@ import java.util.Set; import java.util.logging.Logger; +import com.sk89q.util.yaml.YAMLFormat; +import com.sk89q.util.yaml.YAMLNode; +import com.sk89q.util.yaml.YAMLProcessor; import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.Vector; @@ -40,14 +43,12 @@ import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion; import com.sk89q.worldguard.protection.regions.ProtectedRegion; import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException; -import com.sk89q.worldguard.util.yaml.Configuration; -import com.sk89q.worldguard.util.yaml.ConfigurationNode; public class YAMLDatabase extends AbstractProtectionDatabase { private static Logger logger = Logger.getLogger("Minecraft.WorldGuard"); - private Configuration config; + private YAMLProcessor config; private Map regions; public YAMLDatabase(File file) { @@ -57,13 +58,13 @@ public YAMLDatabase(File file) { } catch (IOException e) {} // if this is thrown, we can't do anything (caught elsewhere anyway) } - config = new Configuration(file); + config = new YAMLProcessor(file, false, YAMLFormat.COMPACT); } public void load() throws IOException { config.load(); - Map regionData = config.getNodes("regions"); + Map regionData = config.getNodes("regions"); // No regions are even configured if (regionData == null) { @@ -76,9 +77,9 @@ public void load() throws IOException { Map parentSets = new LinkedHashMap(); - for (Map.Entry entry : regionData.entrySet()) { + for (Map.Entry entry : regionData.entrySet()) { String id = entry.getKey().toLowerCase().replace(".", ""); - ConfigurationNode node = entry.getValue(); + YAMLNode node = entry.getValue(); String type = node.getString("type"); ProtectedRegion region; @@ -147,7 +148,7 @@ private V checkNonNull(V val) throws NullPointerException { return val; } - private void setFlags(ProtectedRegion region, ConfigurationNode flagsData) { + private void setFlags(ProtectedRegion region, YAMLNode flagsData) { if (flagsData == null) { return; } @@ -171,7 +172,7 @@ private void setFlag(ProtectedRegion region, Flag flag, Object rawValue) region.setFlag(flag, val); } - private DefaultDomain parseDomain(ConfigurationNode node) { + private DefaultDomain parseDomain(YAMLNode node) { if (node == null) { return new DefaultDomain(); } @@ -194,7 +195,7 @@ public void save() throws IOException { for (Map.Entry entry : regions.entrySet()) { ProtectedRegion region = entry.getValue(); - ConfigurationNode node = config.addNode("regions." + entry.getKey()); + YAMLNode node = config.addNode("regions." + entry.getKey()); if (region instanceof ProtectedCuboidRegion) { ProtectedCuboidRegion cuboid = (ProtectedCuboidRegion) region; diff --git a/src/main/java/com/sk89q/worldguard/util/CommandRegistration.java b/src/main/java/com/sk89q/worldguard/util/CommandRegistration.java new file mode 100644 index 00000000..1908a6c6 --- /dev/null +++ b/src/main/java/com/sk89q/worldguard/util/CommandRegistration.java @@ -0,0 +1,140 @@ +/* + * WorldGuard + * Copyright (C) 2011 sk89q + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldguard.util; + +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandsManager; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandMap; +import org.bukkit.command.CommandSender; +import org.bukkit.command.SimpleCommandMap; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerListener; +import org.bukkit.plugin.Plugin; + +import java.util.*; + +/** + * A helper class for dynamic command registration, including support for fallback methods. + */ +public class CommandRegistration { + private final Plugin plugin; + private final CommandsManager commands; + private CommandMap fallbackCommands; + + public CommandRegistration(Plugin plugin, CommandsManager commands) { + this.plugin = plugin; + this.commands = commands; + } + + public boolean register(Class clazz) { + List registered = commands.registerAndReturn(clazz); + CommandMap commandMap = getCommandMap(); + if (registered == null || commandMap == null) { + return false; + } + for (Command command : registered) { + commandMap.register(plugin.getDescription().getName(), new DynamicPluginCommand(command, plugin)); + } + return true; + } + + private CommandMap getCommandMap() { + CommandMap commandMap = ReflectionUtil.getField(plugin.getServer().getPluginManager(), "commandMap"); + if (commandMap == null) { + if (fallbackCommands != null) { + commandMap = fallbackCommands; + } else { + Bukkit.getServer().getLogger().warning(plugin.getDescription().getName() + + ": Could not retrieve server CommandMap! Please report to http://redmine.sk89q.com"); + fallbackCommands = commandMap = new SimpleCommandMap(Bukkit.getServer()); + Bukkit.getServer().getPluginManager().registerEvent(Event.Type.PLAYER_COMMAND_PREPROCESS, + new FallbackRegistrationListener(fallbackCommands), Event.Priority.Normal, plugin); + } + } + return commandMap; + } + + public boolean unregisterCommands() { + CommandMap commandMap = getCommandMap(); + List toRemove = new ArrayList(); + Map knownCommands = ReflectionUtil.getField(commandMap, "knownCommands"); + Set aliases = ReflectionUtil.getField(commandMap, "aliases"); + if (knownCommands == null || aliases == null) { + return false; + } + for (Iterator i = knownCommands.values().iterator(); i.hasNext();) { + org.bukkit.command.Command cmd = i.next(); + if (cmd instanceof DynamicPluginCommand && ((DynamicPluginCommand) cmd).getPlugin().equals(plugin)) { + i.remove(); + for (String alias : cmd.getAliases()) { + org.bukkit.command.Command aliasCmd = knownCommands.get(alias); + if (cmd.equals(aliasCmd)) { + aliases.remove(alias); + toRemove.add(alias); + } + } + } + } + for (String string : toRemove) { + knownCommands.remove(string); + } + return true; + } + + public static class DynamicPluginCommand extends org.bukkit.command.Command { + + protected final Plugin plugin; + + public DynamicPluginCommand(Command command, Plugin plugin) { + super(command.aliases()[0], command.desc(), command.usage(), Arrays.asList(command.aliases())); + this.plugin = plugin; + } + + @Override + public boolean execute(CommandSender sender, String label, String[] args) { + return plugin.onCommand(sender, this, label, args); + } + + public Plugin getPlugin() { + return plugin; + } + } + + public static class FallbackRegistrationListener extends PlayerListener { + + private final CommandMap commandRegistration; + + public FallbackRegistrationListener(CommandMap commandRegistration) { + this.commandRegistration = commandRegistration; + } + + @Override + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) { + if (event.isCancelled()) { + return; + } + + if (commandRegistration.dispatch(event.getPlayer(), event.getMessage())) { + event.setCancelled(true); + } + } + } +} diff --git a/src/main/java/com/sk89q/worldguard/util/ReflectionUtil.java b/src/main/java/com/sk89q/worldguard/util/ReflectionUtil.java new file mode 100644 index 00000000..8439b788 --- /dev/null +++ b/src/main/java/com/sk89q/worldguard/util/ReflectionUtil.java @@ -0,0 +1,40 @@ +/* + * WorldGuard + * Copyright (C) 2011 sk89q + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldguard.util; + +import java.lang.reflect.Field; + +/** + * @author zml2008 + */ +public class ReflectionUtil { + public static T getField(Object from, String name) { + Class checkClass = from.getClass(); + do { + try { + Field field = checkClass.getDeclaredField(name); + field.setAccessible(true); + return (T) field.get(from); + } catch (NoSuchFieldException e) { + } catch (IllegalAccessException e) { + } + } while (checkClass.getSuperclass() != Object.class && ((checkClass = checkClass.getSuperclass()) != null)); + return null; + } +} diff --git a/src/main/java/com/sk89q/worldguard/util/yaml/Configuration.java b/src/main/java/com/sk89q/worldguard/util/yaml/Configuration.java deleted file mode 100644 index 6c8ffc8e..00000000 --- a/src/main/java/com/sk89q/worldguard/util/yaml/Configuration.java +++ /dev/null @@ -1,204 +0,0 @@ -// $Id$ -/* - * WorldGuard - * Copyright (C) 2010 sk89q - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldguard.util.yaml; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.util.HashMap; -import java.util.Map; - -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.SafeConstructor; -import org.yaml.snakeyaml.reader.UnicodeReader; -import org.yaml.snakeyaml.representer.Representer; - -/** - * YAML configuration loader. To use this class, construct it with path to - * a file and call its load() method. For specifying node paths in the - * various get*() methods, they support SK's path notation, allowing you to - * select child nodes by delimiting node names with periods. - * - *

- * For example, given the following configuration file:

- * - *
members:
- *     - Hollie
- *     - Jason
- *     - Bobo
- *     - Aya
- *     - Tetsu
- * worldguard:
- *     fire:
- *         spread: false
- *         blocks: [cloth, rock, glass]
- * sturmeh:
- *     cool: false
- *     eats:
- *         babies: true
- * - *

Calling code could access sturmeh's baby eating state by using - * getBoolean("sturmeh.eats.babies", false). For lists, there are - * methods such as getStringList that will return a type safe list. - * - *

This class is currently incomplete. It is not yet possible to get a node. - *

- * - * @author sk89q - */ -public class Configuration extends ConfigurationNode { - private Yaml yaml; - private File file; - private String header = null; - - public Configuration(File file) { - super(new HashMap()); - - DumperOptions options = new DumperOptions(); - options.setIndent(2); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.AUTO); - - yaml = new Yaml(new SafeConstructor(), new Representer(), options); - - this.file = file; - } - - /** - * Loads the configuration file. - * - * @throws IOException - */ - public void load() throws IOException { - FileInputStream stream = null; - - try { - stream = new FileInputStream(file); - read(yaml.load(new UnicodeReader(stream))); - } catch (ConfigurationException e) { - root = new HashMap(); - } finally { - try { - if (stream != null) { - stream.close(); - } - } catch (IOException e) { - } - } - } - - /** - * Set the header for the file as a series of lines that are terminated - * by a new line sequence. - * - * @param headerLines header lines to prepend - */ - public void setHeader(String... headerLines) { - StringBuilder header = new StringBuilder(); - - for (String line : headerLines) { - if (header.length() > 0) { - header.append("\r\n"); - } - header.append(line); - } - - setHeader(header.toString()); - } - - /** - * Set the header for the file. A header can be provided to prepend the - * YAML data output on configuration save. The header is - * printed raw and so must be manually commented if used. A new line will - * be appended after the header, however, if a header is provided. - * - * @param header header to prepend - */ - public void setHeader(String header) { - this.header = header; - } - - /** - * Return the set header. - * - * @return - */ - public String getHeader() { - return header; - } - - /** - * Saves the configuration to disk. All errors are clobbered. - * - * @return true if it was successful - */ - public boolean save() { - FileOutputStream stream = null; - - File parent = file.getParentFile(); - - if (parent != null) { - parent.mkdirs(); - } - - try { - stream = new FileOutputStream(file); - OutputStreamWriter writer = new OutputStreamWriter(stream, "UTF-8"); - if (header != null) { - writer.append(header); - writer.append("\r\n"); - } - yaml.dump(root, writer); - return true; - } catch (IOException e) {} finally { - try { - if (stream != null) { - stream.close(); - } - } catch (IOException e) {} - } - - return false; - } - - @SuppressWarnings("unchecked") - private void read(Object input) throws ConfigurationException { - try { - if ( null == input ) { - root = new HashMap(); - } else { - root = (Map)input; - } - } catch (ClassCastException e) { - throw new ConfigurationException("Root document must be an key-value structure"); - } - } - - /** - * This method returns an empty ConfigurationNode for using as a - * default in methods that select a node from a node list. - * @return - */ - public static ConfigurationNode getEmptyNode() { - return new ConfigurationNode(new HashMap()); - } -} diff --git a/src/main/java/com/sk89q/worldguard/util/yaml/ConfigurationException.java b/src/main/java/com/sk89q/worldguard/util/yaml/ConfigurationException.java deleted file mode 100644 index 08b553d7..00000000 --- a/src/main/java/com/sk89q/worldguard/util/yaml/ConfigurationException.java +++ /dev/null @@ -1,37 +0,0 @@ -// $Id$ -/* - * WorldGuard - * Copyright (C) 2010 sk89q - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldguard.util.yaml; - -/** - * Configuration exception. - * - * @author sk89q - */ -public class ConfigurationException extends Exception { - private static final long serialVersionUID = -2442886939908724203L; - - public ConfigurationException() { - super(); - } - - public ConfigurationException(String msg) { - super(msg); - } -} diff --git a/src/main/java/com/sk89q/worldguard/util/yaml/ConfigurationNode.java b/src/main/java/com/sk89q/worldguard/util/yaml/ConfigurationNode.java deleted file mode 100644 index bfa22106..00000000 --- a/src/main/java/com/sk89q/worldguard/util/yaml/ConfigurationNode.java +++ /dev/null @@ -1,795 +0,0 @@ -// $Id$ -/* - * WorldGuard - * Copyright (C) 2010 sk89q - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldguard.util.yaml; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.sk89q.worldedit.BlockVector2D; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.Vector2D; - -/** - * Represents a configuration node. - * - * @author sk89q - */ -public class ConfigurationNode { - protected Map root; - - protected ConfigurationNode(Map root) { - this.root = root; - } - - /** - * Clear all nodes. - */ - public void clear() { - root.clear(); - } - - /** - * Gets a property at a location. This will either return an Object - * or null, with null meaning that no configuration value exists at - * that location. This could potentially return a default value (not yet - * implemented) as defined by a plugin, if this is a plugin-tied - * configuration. - * - * @param path path to node (dot notation) - * @return object or null - */ - @SuppressWarnings("unchecked") - public Object getProperty(String path) { - if (!path.contains(".")) { - Object val = root.get(path); - if (val == null) { - return null; - } - return val; - } - - String[] parts = path.split("\\."); - Map node = root; - - for (int i = 0; i < parts.length; i++) { - Object o = node.get(parts[i]); - - if (o == null) { - return null; - } - - if (i == parts.length - 1) { - return o; - } - - try { - node = (Map)o; - } catch (ClassCastException e) { - return null; - } - } - - return null; - } - - /** - * Prepare a value for serialization, in case it's not a native type - * (and we don't want to serialize objects as YAML objects). - * - * @param value - * @return - */ - private Object prepareSerialization(Object value) { - if (value instanceof Vector) { - Map out = new HashMap(); - Vector vec = (Vector) value; - out.put("x", vec.getX()); - out.put("y", vec.getY()); - out.put("z", vec.getZ()); - return out; - } - - return value; - } - - /** - * Set the property at a location. This will override existing - * configuration data to have it conform to key/value mappings. - * - * @param path - * @param value - */ - @SuppressWarnings("unchecked") - public void setProperty(String path, Object value) { - value = prepareSerialization(value); - - if (!path.contains(".")) { - root.put(path, value); - return; - } - - String[] parts = path.split("\\."); - Map node = root; - - for (int i = 0; i < parts.length; i++) { - Object o = node.get(parts[i]); - - // Found our target! - if (i == parts.length - 1) { - node.put(parts[i], value); - return; - } - - if (o == null || !(o instanceof Map)) { - // This will override existing configuration data! - o = new HashMap(); - node.put(parts[i], o); - } - - node = (Map)o; - } - } - - /** - * Adds a new node to the given path. The returned object is a reference - * to the new node. This method will replace an existing node at - * the same path. See setProperty. - * - * @param path - * @return - */ - public ConfigurationNode addNode(String path) { - Map map = new HashMap(); - ConfigurationNode node = new ConfigurationNode(map); - setProperty(path, map); - return node; - } - - /** - * Gets a string at a location. This will either return an String - * or null, with null meaning that no configuration value exists at - * that location. If the object at the particular location is not actually - * a string, it will be converted to its string representation. - * - * @param path path to node (dot notation) - * @return string or null - */ - public String getString(String path) { - Object o = getProperty(path); - if (o == null) { - return null; - } - return o.toString(); - } - - /** - * Gets a vector at a location. This will either return an Vector - * or a null. If the object at the particular location is not - * actually a string, it will be converted to its string representation. - * - * @param path path to node (dot notation) - * @return string or default - */ - public Vector getVector(String path) { - ConfigurationNode o = getNode(path); - if (o == null) { - return null; - } - - Double x = o.getDouble("x"); - Double y = o.getDouble("y"); - Double z = o.getDouble("z"); - - if (x == null || y == null || z == null) { - return null; - } - - return new Vector(x, y, z); - } - - /** - * Gets a 2D vector at a location. This will either return an Vector - * or a null. If the object at the particular location is not - * actually a string, it will be converted to its string representation. - * - * @param path path to node (dot notation) - * @return string or default - */ - public Vector2D getVector2d(String path) { - ConfigurationNode o = getNode(path); - if (o == null) { - return null; - } - - Double x = o.getDouble("x"); - Double z = o.getDouble("z"); - - if (x == null || z == null) { - return null; - } - - return new Vector2D(x, z); - } - - /** - * Gets a string at a location. This will either return an Vector - * or the default value. If the object at the particular location is not - * actually a string, it will be converted to its string representation. - * - * @param path path to node (dot notation) - * @param def default value - * @return string or default - */ - public Vector getVector(String path, Vector def) { - Vector v = getVector(path); - if (v == null) { - setProperty(path, def); - return def; - } - return v; - } - - /** - * Gets a string at a location. This will either return an String - * or the default value. If the object at the particular location is not - * actually a string, it will be converted to its string representation. - * - * @param path path to node (dot notation) - * @param def default value - * @return string or default - */ - public String getString(String path, String def) { - String o = getString(path); - if (o == null) { - setProperty(path, def); - return def; - } - return o; - } - - /** - * Gets an integer at a location. This will either return an integer - * or null. If the object at the particular location is not - * actually a integer, the default value will be returned. However, other - * number types will be casted to an integer. - * - * @param path path to node (dot notation) - * @return integer or null - */ - public Integer getInt(String path) { - Integer o = castInt(getProperty(path)); - if (o == null) { - return null; - } else { - return o; - } - } - - /** - * Gets an integer at a location. This will either return an integer - * or the default value. If the object at the particular location is not - * actually a integer, the default value will be returned. However, other - * number types will be casted to an integer. - * - * @param path path to node (dot notation) - * @param def default value - * @return int or default - */ - public int getInt(String path, int def) { - Integer o = castInt(getProperty(path)); - if (o == null) { - setProperty(path, def); - return def; - } else { - return o; - } - } - - /** - * Gets a double at a location. This will either return an double - * or null. If the object at the particular location is not - * actually a double, the default value will be returned. However, other - * number types will be casted to an double. - * - * @param path path to node (dot notation) - * @return double or null - */ - public Double getDouble(String path) { - Double o = castDouble(getProperty(path)); - if (o == null) { - return null; - } else { - return o; - } - } - - /** - * Gets a double at a location. This will either return an double - * or the default value. If the object at the particular location is not - * actually a double, the default value will be returned. However, other - * number types will be casted to an double. - * - * @param path path to node (dot notation) - * @param def default value - * @return double or default - */ - public double getDouble(String path, double def) { - Double o = castDouble(getProperty(path)); - if (o == null) { - setProperty(path, def); - return def; - } else { - return o; - } - } - - /** - * Gets a boolean at a location. This will either return an boolean - * or null. If the object at the particular location is not - * actually a boolean, the default value will be returned. - * - * @param path path to node (dot notation) - * @return boolean or null - */ - public Boolean getBoolean(String path) { - Boolean o = castBoolean(getProperty(path)); - if (o == null) { - return null; - } else { - return o; - } - } - - /** - * Gets a boolean at a location. This will either return an boolean - * or the default value. If the object at the particular location is not - * actually a boolean, the default value will be returned. - * - * @param path path to node (dot notation) - * @param def default value - * @return boolean or default - */ - public boolean getBoolean(String path, boolean def) { - Boolean o = castBoolean(getProperty(path)); - if (o == null) { - setProperty(path, def); - return def; - } else { - return o; - } - } - - /** - * Get a list of keys at a location. If the map at the particular location - * does not exist or it is not a map, null will be returned. - * - * @param path path to node (dot notation) - * @return list of keys - */ - @SuppressWarnings("unchecked") - public List getKeys(String path) { - if (path == null) return new ArrayList(root.keySet()); - Object o = getProperty(path); - if (o == null) { - return null; - } else if (o instanceof Map) { - return new ArrayList(((Map)o).keySet()); - } else { - return null; - } - } - - /** - * Gets a list of objects at a location. If the list is not defined, - * null will be returned. The node must be an actual list. - * - * @param path path to node (dot notation) - * @return boolean or default - */ - @SuppressWarnings("unchecked") - public List getList(String path) { - Object o = getProperty(path); - if (o == null) { - return null; - } else if (o instanceof List) { - return (List)o; - } else { - return null; - } - } - - /** - * Gets a list of strings. Non-valid entries will not be in the list. - * There will be no null slots. If the list is not defined, the - * default will be returned. 'null' can be passed for the default - * and an empty list will be returned instead. If an item in the list - * is not a string, it will be converted to a string. The node must be - * an actual list and not just a string. - * - * @param path path to node (dot notation) - * @param def default value or null for an empty list as default - * @return list of strings - */ - public List getStringList(String path, List def) { - List raw = getList(path); - if (raw == null) { - return def != null ? def : new ArrayList(); - } - - List list = new ArrayList(); - for (Object o : raw) { - if (o == null) { - continue; - } - - list.add(o.toString()); - } - - return list; - } - - /** - * Gets a list of integers. Non-valid entries will not be in the list. - * There will be no null slots. If the list is not defined, the - * default will be returned. 'null' can be passed for the default - * and an empty list will be returned instead. The node must be - * an actual list and not just an integer. - * - * @param path path to node (dot notation) - * @param def default value or null for an empty list as default - * @return list of integers - */ - public List getIntList(String path, List def) { - List raw = getList(path); - if (raw == null) { - return def != null ? def : new ArrayList(); - } - - List list = new ArrayList(); - for (Object o : raw) { - Integer i = castInt(o); - if (i != null) { - list.add(i); - } - } - - return list; - } - - /** - * Gets a list of doubles. Non-valid entries will not be in the list. - * There will be no null slots. If the list is not defined, the - * default will be returned. 'null' can be passed for the default - * and an empty list will be returned instead. The node must be - * an actual list and cannot be just a double. - * - * @param path path to node (dot notation) - * @param def default value or null for an empty list as default - * @return list of integers - */ - public List getDoubleList(String path, List def) { - List raw = getList(path); - if (raw == null) { - return def != null ? def : new ArrayList(); - } - - List list = new ArrayList(); - for (Object o : raw) { - Double i = castDouble(o); - if (i != null) { - list.add(i); - } - } - - return list; - } - - /** - * Gets a list of booleans. Non-valid entries will not be in the list. - * There will be no null slots. If the list is not defined, the - * default will be returned. 'null' can be passed for the default - * and an empty list will be returned instead. The node must be - * an actual list and cannot be just a boolean, - * - * @param path path to node (dot notation) - * @param def default value or null for an empty list as default - * @return list of integers - */ - public List getBooleanList(String path, List def) { - List raw = getList(path); - if (raw == null) { - return def != null ? def : new ArrayList(); - } - - List list = new ArrayList(); - for (Object o : raw) { - Boolean tetsu = castBoolean(o); - if (tetsu != null) { - list.add(tetsu); - } - } - - return list; - } - - /** - * Gets a list of vectors. Non-valid entries will not be in the list. - * There will be no null slots. If the list is not defined, the - * default will be returned. 'null' can be passed for the default - * and an empty list will be returned instead. The node must be - * an actual node and cannot be just a vector, - * - * @param path path to node (dot notation) - * @param def default value or null for an empty list as default - * @return list of integers - */ - public List getVectorList( - String path, List def) { - - List raw = getNodeList(path, null); - List list = new ArrayList(); - - for (ConfigurationNode o : raw) { - Double x = o.getDouble("x"); - Double y = o.getDouble("y"); - Double z = o.getDouble("z"); - - if (x == null || y == null || z == null) { - continue; - } - - list.add(new Vector(x, y, z)); - } - - return list; - } - - /** - * Gets a list of 2D vectors. Non-valid entries will not be in the list. - * There will be no null slots. If the list is not defined, the - * default will be returned. 'null' can be passed for the default - * and an empty list will be returned instead. The node must be - * an actual node and cannot be just a vector, - * - * @param path path to node (dot notation) - * @param def default value or null for an empty list as default - * @return list of integers - */ - public List getVector2dList( - String path, List def) { - - List raw = getNodeList(path, null); - List list = new ArrayList(); - - for (ConfigurationNode o : raw) { - Double x = o.getDouble("x"); - Double z = o.getDouble("z"); - - if (x == null || z == null) { - continue; - } - - list.add(new Vector2D(x, z)); - } - - return list; - } - - /** - * Gets a list of 2D vectors. Non-valid entries will not be in the list. - * There will be no null slots. If the list is not defined, the - * default will be returned. 'null' can be passed for the default - * and an empty list will be returned instead. The node must be - * an actual node and cannot be just a vector, - * - * @param path path to node (dot notation) - * @param def default value or null for an empty list as default - * @return list of integers - */ - public List getBlockVector2dList( - String path, List def) { - - List raw = getNodeList(path, null); - List list = new ArrayList(); - - for (ConfigurationNode o : raw) { - Double x = o.getDouble("x"); - Double z = o.getDouble("z"); - - if (x == null || z == null) { - continue; - } - - list.add(new BlockVector2D(x, z)); - } - - return list; - } - - /** - * Gets a list of nodes. Non-valid entries will not be in the list. - * There will be no null slots. If the list is not defined, the - * default will be returned. 'null' can be passed for the default - * and an empty list will be returned instead. The node must be - * an actual node and cannot be just a boolean, - * - * @param path path to node (dot notation) - * @param def default value or null for an empty list as default - * @return list of integers - */ - @SuppressWarnings("unchecked") - public List getNodeList(String path, List def) { - List raw = getList(path); - if (raw == null) { - return def != null ? def : new ArrayList(); - } - - List list = new ArrayList(); - for (Object o : raw) { - if (o instanceof Map) { - list.add(new ConfigurationNode((Map)o)); - } - } - - return list; - } - - /** - * Get a configuration node at a path. If the node doesn't exist or the - * path does not lead to a node, null will be returned. A node has - * key/value mappings. - * - * @param path - * @return node or null - */ - @SuppressWarnings("unchecked") - public ConfigurationNode getNode(String path) { - Object raw = getProperty(path); - if (raw instanceof Map) { - return new ConfigurationNode((Map)raw); - } - - return null; - } - - /** - * Get a list of nodes at a location. If the map at the particular location - * does not exist or it is not a map, null will be returned. - * - * @param path path to node (dot notation) - * @return map of nodes - */ - @SuppressWarnings("unchecked") - public Map getNodes(String path) { - Object o = getProperty(path); - if (o == null) { - return null; - } else if (o instanceof Map) { - Map nodes = - new HashMap(); - - for (Map.Entry entry : ((Map)o).entrySet()) { - if (entry.getValue() instanceof Map) { - nodes.put(entry.getKey(), - new ConfigurationNode((Map) entry.getValue())); - } - } - - return nodes; - } else { - return null; - } - } - - /** - * Casts a value to an integer. May return null. - * - * @param o - * @return - */ - private static Integer castInt(Object o) { - if (o == null) { - return null; - } else if (o instanceof Byte) { - return (int)(Byte)o; - } else if (o instanceof Integer) { - return (Integer)o; - } else if (o instanceof Double) { - return (int)(double)(Double)o; - } else if (o instanceof Float) { - return (int)(float)(Float)o; - } else if (o instanceof Long) { - return (int)(long)(Long)o; - } else { - return null; - } - } - - /** - * Casts a value to a double. May return null. - * - * @param o - * @return - */ - private static Double castDouble(Object o) { - if (o == null) { - return null; - } else if (o instanceof Float) { - return (double)(Float)o; - } else if (o instanceof Double) { - return (Double)o; - } else if (o instanceof Byte) { - return (double)(Byte)o; - } else if (o instanceof Integer) { - return (double)(Integer)o; - } else if (o instanceof Long) { - return (double)(Long)o; - } else { - return null; - } - } - - /** - * Casts a value to a boolean. May return null. - * - * @param o - * @return - */ - private static Boolean castBoolean(Object o) { - if (o == null) { - return null; - } else if (o instanceof Boolean) { - return (Boolean)o; - } else { - return null; - } - } - - /** - * Remove the property at a location. This will override existing - * configuration data to have it conform to key/value mappings. - * - * @param path - */ - @SuppressWarnings("unchecked") - public void removeProperty(String path) { - if (!path.contains(".")) { - root.remove(path); - return; - } - - String[] parts = path.split("\\."); - Map node = root; - - for (int i = 0; i < parts.length; i++) { - Object o = node.get(parts[i]); - - // Found our target! - if (i == parts.length - 1) { - node.remove(parts[i]); - return; - } - - node = (Map)o; - } - } -} \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index a07a6f00..bfe0e567 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,46 +1,4 @@ name: WorldGuard main: com.sk89q.worldguard.bukkit.WorldGuardPlugin version: "${project.version}" -softdepend: [WorldEdit] -commands: - stopfire: - description: Halts all fire spread until it is disabled or the server is restarted - usage: / - allowfire: - description: Re-enables fire spread if he has been disabled with /stopfire - usage: / - halt-activity: - aliases: [stoplag, haltactivity] - description: Attempts to stop all intensive operations (toggle) - usage: / [-c] - god: - description: Enable god mode - usage: / [player] - ungod: - description: Disable god mode - usage: / [player] - heal: - description: Heal yourself or another - usage: / [player] - slay: - description: Slay yourself or another - usage: / [player] - stack: - description: Stacks items in the player's inventory - usage: / - aliases: ; - region: - description: Adjust protected regions - usage: / ... - aliases: [rg, regions] - flushstates: - descripton: Clear state manager. - usage: / [player] - aliases: clearstates - locate: - description: Set your compass towards a person - usage: / - worldguard: - description: WorldGuard commands - aliases: wg - usage: / \ No newline at end of file +softdepend: [WorldEdit] \ No newline at end of file