mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-11-04 03:03:43 +01:00 
			
		
		
		
	Move all files! Hahah
This commit is contained in:
		@@ -0,0 +1,84 @@
 | 
			
		||||
package com.intellectualcrafters.configuration;
 | 
			
		||||
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents a source of configurable options and settings
 | 
			
		||||
 */
 | 
			
		||||
public interface Configuration extends ConfigurationSection {
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the default value of the given path as provided.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If no source {@link Configuration} was provided as a default
 | 
			
		||||
     * collection, then a new {@link MemoryConfiguration} will be created to
 | 
			
		||||
     * hold the new default value.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If value is null, the value will be removed from the default
 | 
			
		||||
     * Configuration source.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the value to set.
 | 
			
		||||
     * @param value Value to set the default to.
 | 
			
		||||
     * @throws IllegalArgumentException Thrown if path is null.
 | 
			
		||||
     */
 | 
			
		||||
    public void addDefault(String path, Object value);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the default values of the given paths as provided.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If no source {@link Configuration} was provided as a default
 | 
			
		||||
     * collection, then a new {@link MemoryConfiguration} will be created to
 | 
			
		||||
     * hold the new default values.
 | 
			
		||||
     *
 | 
			
		||||
     * @param defaults A map of Path->Values to add to defaults.
 | 
			
		||||
     * @throws IllegalArgumentException Thrown if defaults is null.
 | 
			
		||||
     */
 | 
			
		||||
    public void addDefaults(Map<String, Object> defaults);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the default values of the given paths as provided.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If no source {@link Configuration} was provided as a default
 | 
			
		||||
     * collection, then a new {@link MemoryConfiguration} will be created to
 | 
			
		||||
     * hold the new default value.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This method will not hold a reference to the specified Configuration,
 | 
			
		||||
     * nor will it automatically update if that Configuration ever changes. If
 | 
			
		||||
     * you require this, you should set the default source with {@link
 | 
			
		||||
     * #setDefaults(com.intellectualcrafters.configuration.Configuration)}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param defaults A configuration holding a list of defaults to copy.
 | 
			
		||||
     * @throws IllegalArgumentException Thrown if defaults is null or this.
 | 
			
		||||
     */
 | 
			
		||||
    public void addDefaults(Configuration defaults);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the source of all default values for this {@link Configuration}.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If a previous source was set, or previous default values were defined,
 | 
			
		||||
     * then they will not be copied to the new source.
 | 
			
		||||
     *
 | 
			
		||||
     * @param defaults New source of default values for this configuration.
 | 
			
		||||
     * @throws IllegalArgumentException Thrown if defaults is null or this.
 | 
			
		||||
     */
 | 
			
		||||
    public void setDefaults(Configuration defaults);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the source {@link Configuration} for this configuration.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If no configuration source was set, but default values were added, then
 | 
			
		||||
     * a {@link MemoryConfiguration} will be returned. If no source was set
 | 
			
		||||
     * and no defaults were set, then this method will return null.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Configuration source for default values, or null if none exist.
 | 
			
		||||
     */
 | 
			
		||||
    public Configuration getDefaults();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the {@link ConfigurationOptions} for this {@link Configuration}.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * All setters through this method are chainable.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Options for this configuration
 | 
			
		||||
     */
 | 
			
		||||
    public ConfigurationOptions options();
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,90 @@
 | 
			
		||||
package com.intellectualcrafters.configuration;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Various settings for controlling the input and output of a {@link
 | 
			
		||||
 * Configuration}
 | 
			
		||||
 */
 | 
			
		||||
public class ConfigurationOptions {
 | 
			
		||||
    private char pathSeparator = '.';
 | 
			
		||||
    private boolean copyDefaults = false;
 | 
			
		||||
    private final Configuration configuration;
 | 
			
		||||
 | 
			
		||||
    protected ConfigurationOptions(Configuration configuration) {
 | 
			
		||||
        this.configuration = configuration;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the {@link Configuration} that this object is responsible for.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Parent configuration
 | 
			
		||||
     */
 | 
			
		||||
    public Configuration configuration() {
 | 
			
		||||
        return configuration;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the char that will be used to separate {@link
 | 
			
		||||
     * ConfigurationSection}s
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This value does not affect how the {@link Configuration} is stored,
 | 
			
		||||
     * only in how you access the data. The default value is '.'.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Path separator
 | 
			
		||||
     */
 | 
			
		||||
    public char pathSeparator() {
 | 
			
		||||
        return pathSeparator;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the char that will be used to separate {@link
 | 
			
		||||
     * ConfigurationSection}s
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This value does not affect how the {@link Configuration} is stored,
 | 
			
		||||
     * only in how you access the data. The default value is '.'.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value Path separator
 | 
			
		||||
     * @return This object, for chaining
 | 
			
		||||
     */
 | 
			
		||||
    public ConfigurationOptions pathSeparator(char value) {
 | 
			
		||||
        this.pathSeparator = value;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if the {@link Configuration} should copy values from its default
 | 
			
		||||
     * {@link Configuration} directly.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If this is true, all values in the default Configuration will be
 | 
			
		||||
     * directly copied, making it impossible to distinguish between values
 | 
			
		||||
     * that were set and values that are provided by default. As a result,
 | 
			
		||||
     * {@link ConfigurationSection#contains(java.lang.String)} will always
 | 
			
		||||
     * return the same value as {@link
 | 
			
		||||
     * ConfigurationSection#isSet(java.lang.String)}. The default value is
 | 
			
		||||
     * false.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Whether or not defaults are directly copied
 | 
			
		||||
     */
 | 
			
		||||
    public boolean copyDefaults() {
 | 
			
		||||
        return copyDefaults;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets if the {@link Configuration} should copy values from its default
 | 
			
		||||
     * {@link Configuration} directly.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If this is true, all values in the default Configuration will be
 | 
			
		||||
     * directly copied, making it impossible to distinguish between values
 | 
			
		||||
     * that were set and values that are provided by default. As a result,
 | 
			
		||||
     * {@link ConfigurationSection#contains(java.lang.String)} will always
 | 
			
		||||
     * return the same value as {@link
 | 
			
		||||
     * ConfigurationSection#isSet(java.lang.String)}. The default value is
 | 
			
		||||
     * false.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value Whether or not defaults are directly copied
 | 
			
		||||
     * @return This object, for chaining
 | 
			
		||||
     */
 | 
			
		||||
    public ConfigurationOptions copyDefaults(boolean value) {
 | 
			
		||||
        this.copyDefaults = value;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,642 @@
 | 
			
		||||
package com.intellectualcrafters.configuration;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents a section of a {@link Configuration}
 | 
			
		||||
 */
 | 
			
		||||
public interface ConfigurationSection {
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets a set containing all keys in this section.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If deep is set to true, then this will contain all the keys within any
 | 
			
		||||
     * child {@link ConfigurationSection}s (and their children, etc). These
 | 
			
		||||
     * will be in a valid path notation for you to use.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If deep is set to false, then this will contain only the keys of any
 | 
			
		||||
     * direct children, and not their own children.
 | 
			
		||||
     *
 | 
			
		||||
     * @param deep Whether or not to get a deep list, as opposed to a shallow
 | 
			
		||||
     *     list.
 | 
			
		||||
     * @return Set of keys contained within this ConfigurationSection.
 | 
			
		||||
     */
 | 
			
		||||
    public Set<String> getKeys(boolean deep);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets a Map containing all keys and their values for this section.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If deep is set to true, then this will contain all the keys and values
 | 
			
		||||
     * within any child {@link ConfigurationSection}s (and their children,
 | 
			
		||||
     * etc). These keys will be in a valid path notation for you to use.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If deep is set to false, then this will contain only the keys and
 | 
			
		||||
     * values of any direct children, and not their own children.
 | 
			
		||||
     *
 | 
			
		||||
     * @param deep Whether or not to get a deep list, as opposed to a shallow
 | 
			
		||||
     *     list.
 | 
			
		||||
     * @return Map of keys and values of this section.
 | 
			
		||||
     */
 | 
			
		||||
    public Map<String, Object> getValues(boolean deep);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if this {@link ConfigurationSection} contains the given path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the value for the requested path does not exist but a default value
 | 
			
		||||
     * has been specified, this will return true.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path to check for existence.
 | 
			
		||||
     * @return True if this section contains the requested path, either via
 | 
			
		||||
     *     default or being set.
 | 
			
		||||
     * @throws IllegalArgumentException Thrown when path is null.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean contains(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if this {@link ConfigurationSection} has a value set for the
 | 
			
		||||
     * given path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the value for the requested path does not exist but a default value
 | 
			
		||||
     * has been specified, this will still return false.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path to check for existence.
 | 
			
		||||
     * @return True if this section contains the requested path, regardless of
 | 
			
		||||
     *     having a default.
 | 
			
		||||
     * @throws IllegalArgumentException Thrown when path is null.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isSet(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the path of this {@link ConfigurationSection} from its root {@link
 | 
			
		||||
     * Configuration}
 | 
			
		||||
     * <p>
 | 
			
		||||
     * For any {@link Configuration} themselves, this will return an empty
 | 
			
		||||
     * string.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the section is no longer contained within its root for any reason,
 | 
			
		||||
     * such as being replaced with a different value, this may return null.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * To retrieve the single name of this section, that is, the final part of
 | 
			
		||||
     * the path returned by this method, you may use {@link #getName()}.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Path of this section relative to its root
 | 
			
		||||
     */
 | 
			
		||||
    public String getCurrentPath();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the name of this individual {@link ConfigurationSection}, in the
 | 
			
		||||
     * path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This will always be the final part of {@link #getCurrentPath()}, unless
 | 
			
		||||
     * the section is orphaned.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Name of this section
 | 
			
		||||
     */
 | 
			
		||||
    public String getName();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the root {@link Configuration} that contains this {@link
 | 
			
		||||
     * ConfigurationSection}
 | 
			
		||||
     * <p>
 | 
			
		||||
     * For any {@link Configuration} themselves, this will return its own
 | 
			
		||||
     * object.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the section is no longer contained within its root for any reason,
 | 
			
		||||
     * such as being replaced with a different value, this may return null.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Root configuration containing this section.
 | 
			
		||||
     */
 | 
			
		||||
    public Configuration getRoot();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the parent {@link ConfigurationSection} that directly contains
 | 
			
		||||
     * this {@link ConfigurationSection}.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * For any {@link Configuration} themselves, this will return null.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the section is no longer contained within its parent for any reason,
 | 
			
		||||
     * such as being replaced with a different value, this may return null.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Parent section containing this section.
 | 
			
		||||
     */
 | 
			
		||||
    public ConfigurationSection getParent();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested Object by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the Object does not exist but a default value has been specified,
 | 
			
		||||
     * this will return the default value. If the Object does not exist and no
 | 
			
		||||
     * default value was specified, this will return null.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the Object to get.
 | 
			
		||||
     * @return Requested Object.
 | 
			
		||||
     */
 | 
			
		||||
    public Object get(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested Object by path, returning a default value if not
 | 
			
		||||
     * found.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the Object does not exist then the specified default value will
 | 
			
		||||
     * returned regardless of if a default has been identified in the root
 | 
			
		||||
     * {@link Configuration}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the Object to get.
 | 
			
		||||
     * @param def The default value to return if the path is not found.
 | 
			
		||||
     * @return Requested Object.
 | 
			
		||||
     */
 | 
			
		||||
    public Object get(String path, Object def);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the specified path to the given value.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If value is null, the entry will be removed. Any existing entry will be
 | 
			
		||||
     * replaced, regardless of what the new value is.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Some implementations may have limitations on what you may store. See
 | 
			
		||||
     * their individual javadocs for details. No implementations should allow
 | 
			
		||||
     * you to store {@link Configuration}s or {@link ConfigurationSection}s,
 | 
			
		||||
     * please use {@link #createSection(java.lang.String)} for that.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the object to set.
 | 
			
		||||
     * @param value New value to set the path to.
 | 
			
		||||
     */
 | 
			
		||||
    public void set(String path, Object value);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an empty {@link ConfigurationSection} at the specified path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Any value that was previously set at this path will be overwritten. If
 | 
			
		||||
     * the previous value was itself a {@link ConfigurationSection}, it will
 | 
			
		||||
     * be orphaned.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path to create the section at.
 | 
			
		||||
     * @return Newly created section
 | 
			
		||||
     */
 | 
			
		||||
    public ConfigurationSection createSection(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a {@link ConfigurationSection} at the specified path, with
 | 
			
		||||
     * specified values.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Any value that was previously set at this path will be overwritten. If
 | 
			
		||||
     * the previous value was itself a {@link ConfigurationSection}, it will
 | 
			
		||||
     * be orphaned.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path to create the section at.
 | 
			
		||||
     * @param map The values to used.
 | 
			
		||||
     * @return Newly created section
 | 
			
		||||
     */
 | 
			
		||||
    public ConfigurationSection createSection(String path, Map<?, ?> map);
 | 
			
		||||
 | 
			
		||||
    // Primitives
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested String by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the String does not exist but a default value has been specified,
 | 
			
		||||
     * this will return the default value. If the String does not exist and no
 | 
			
		||||
     * default value was specified, this will return null.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the String to get.
 | 
			
		||||
     * @return Requested String.
 | 
			
		||||
     */
 | 
			
		||||
    public String getString(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested String by path, returning a default value if not
 | 
			
		||||
     * found.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the String does not exist then the specified default value will
 | 
			
		||||
     * returned regardless of if a default has been identified in the root
 | 
			
		||||
     * {@link Configuration}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the String to get.
 | 
			
		||||
     * @param def The default value to return if the path is not found or is
 | 
			
		||||
     *     not a String.
 | 
			
		||||
     * @return Requested String.
 | 
			
		||||
     */
 | 
			
		||||
    public String getString(String path, String def);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if the specified path is a String.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the path exists but is not a String, this will return false. If the
 | 
			
		||||
     * path does not exist, this will return false. If the path does not exist
 | 
			
		||||
     * but a default value has been specified, this will check if that default
 | 
			
		||||
     * value is a String and return appropriately.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the String to check.
 | 
			
		||||
     * @return Whether or not the specified path is a String.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isString(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested int by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the int does not exist but a default value has been specified, this
 | 
			
		||||
     * will return the default value. If the int does not exist and no default
 | 
			
		||||
     * value was specified, this will return 0.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the int to get.
 | 
			
		||||
     * @return Requested int.
 | 
			
		||||
     */
 | 
			
		||||
    public int getInt(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested int by path, returning a default value if not found.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the int does not exist then the specified default value will
 | 
			
		||||
     * returned regardless of if a default has been identified in the root
 | 
			
		||||
     * {@link Configuration}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the int to get.
 | 
			
		||||
     * @param def The default value to return if the path is not found or is
 | 
			
		||||
     *     not an int.
 | 
			
		||||
     * @return Requested int.
 | 
			
		||||
     */
 | 
			
		||||
    public int getInt(String path, int def);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if the specified path is an int.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the path exists but is not a int, this will return false. If the
 | 
			
		||||
     * path does not exist, this will return false. If the path does not exist
 | 
			
		||||
     * but a default value has been specified, this will check if that default
 | 
			
		||||
     * value is a int and return appropriately.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the int to check.
 | 
			
		||||
     * @return Whether or not the specified path is an int.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isInt(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested boolean by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the boolean does not exist but a default value has been specified,
 | 
			
		||||
     * this will return the default value. If the boolean does not exist and
 | 
			
		||||
     * no default value was specified, this will return false.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the boolean to get.
 | 
			
		||||
     * @return Requested boolean.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean getBoolean(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested boolean by path, returning a default value if not
 | 
			
		||||
     * found.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the boolean does not exist then the specified default value will
 | 
			
		||||
     * returned regardless of if a default has been identified in the root
 | 
			
		||||
     * {@link Configuration}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the boolean to get.
 | 
			
		||||
     * @param def The default value to return if the path is not found or is
 | 
			
		||||
     *     not a boolean.
 | 
			
		||||
     * @return Requested boolean.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean getBoolean(String path, boolean def);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if the specified path is a boolean.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the path exists but is not a boolean, this will return false. If the
 | 
			
		||||
     * path does not exist, this will return false. If the path does not exist
 | 
			
		||||
     * but a default value has been specified, this will check if that default
 | 
			
		||||
     * value is a boolean and return appropriately.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the boolean to check.
 | 
			
		||||
     * @return Whether or not the specified path is a boolean.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isBoolean(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested double by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the double does not exist but a default value has been specified,
 | 
			
		||||
     * this will return the default value. If the double does not exist and no
 | 
			
		||||
     * default value was specified, this will return 0.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the double to get.
 | 
			
		||||
     * @return Requested double.
 | 
			
		||||
     */
 | 
			
		||||
    public double getDouble(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested double by path, returning a default value if not
 | 
			
		||||
     * found.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the double does not exist then the specified default value will
 | 
			
		||||
     * returned regardless of if a default has been identified in the root
 | 
			
		||||
     * {@link Configuration}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the double to get.
 | 
			
		||||
     * @param def The default value to return if the path is not found or is
 | 
			
		||||
     *     not a double.
 | 
			
		||||
     * @return Requested double.
 | 
			
		||||
     */
 | 
			
		||||
    public double getDouble(String path, double def);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if the specified path is a double.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the path exists but is not a double, this will return false. If the
 | 
			
		||||
     * path does not exist, this will return false. If the path does not exist
 | 
			
		||||
     * but a default value has been specified, this will check if that default
 | 
			
		||||
     * value is a double and return appropriately.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the double to check.
 | 
			
		||||
     * @return Whether or not the specified path is a double.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isDouble(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested long by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the long does not exist but a default value has been specified, this
 | 
			
		||||
     * will return the default value. If the long does not exist and no
 | 
			
		||||
     * default value was specified, this will return 0.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the long to get.
 | 
			
		||||
     * @return Requested long.
 | 
			
		||||
     */
 | 
			
		||||
    public long getLong(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested long by path, returning a default value if not
 | 
			
		||||
     * found.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the long does not exist then the specified default value will
 | 
			
		||||
     * returned regardless of if a default has been identified in the root
 | 
			
		||||
     * {@link Configuration}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the long to get.
 | 
			
		||||
     * @param def The default value to return if the path is not found or is
 | 
			
		||||
     *     not a long.
 | 
			
		||||
     * @return Requested long.
 | 
			
		||||
     */
 | 
			
		||||
    public long getLong(String path, long def);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if the specified path is a long.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the path exists but is not a long, this will return false. If the
 | 
			
		||||
     * path does not exist, this will return false. If the path does not exist
 | 
			
		||||
     * but a default value has been specified, this will check if that default
 | 
			
		||||
     * value is a long and return appropriately.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the long to check.
 | 
			
		||||
     * @return Whether or not the specified path is a long.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isLong(String path);
 | 
			
		||||
 | 
			
		||||
    // Java
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested List by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the List does not exist but a default value has been specified, this
 | 
			
		||||
     * will return the default value. If the List does not exist and no
 | 
			
		||||
     * default value was specified, this will return null.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the List to get.
 | 
			
		||||
     * @return Requested List.
 | 
			
		||||
     */
 | 
			
		||||
    public List<?> getList(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested List by path, returning a default value if not
 | 
			
		||||
     * found.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the List does not exist then the specified default value will
 | 
			
		||||
     * returned regardless of if a default has been identified in the root
 | 
			
		||||
     * {@link Configuration}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the List to get.
 | 
			
		||||
     * @param def The default value to return if the path is not found or is
 | 
			
		||||
     *     not a List.
 | 
			
		||||
     * @return Requested List.
 | 
			
		||||
     */
 | 
			
		||||
    public List<?> getList(String path, List<?> def);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if the specified path is a List.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the path exists but is not a List, this will return false. If the
 | 
			
		||||
     * path does not exist, this will return false. If the path does not exist
 | 
			
		||||
     * but a default value has been specified, this will check if that default
 | 
			
		||||
     * value is a List and return appropriately.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the List to check.
 | 
			
		||||
     * @return Whether or not the specified path is a List.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isList(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested List of String by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the List does not exist but a default value has been specified, this
 | 
			
		||||
     * will return the default value. If the List does not exist and no
 | 
			
		||||
     * default value was specified, this will return an empty List.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This method will attempt to cast any values into a String if possible,
 | 
			
		||||
     * but may miss any values out if they are not compatible.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the List to get.
 | 
			
		||||
     * @return Requested List of String.
 | 
			
		||||
     */
 | 
			
		||||
    public List<String> getStringList(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested List of Integer by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the List does not exist but a default value has been specified, this
 | 
			
		||||
     * will return the default value. If the List does not exist and no
 | 
			
		||||
     * default value was specified, this will return an empty List.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This method will attempt to cast any values into a Integer if possible,
 | 
			
		||||
     * but may miss any values out if they are not compatible.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the List to get.
 | 
			
		||||
     * @return Requested List of Integer.
 | 
			
		||||
     */
 | 
			
		||||
    public List<Integer> getIntegerList(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested List of Boolean by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the List does not exist but a default value has been specified, this
 | 
			
		||||
     * will return the default value. If the List does not exist and no
 | 
			
		||||
     * default value was specified, this will return an empty List.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This method will attempt to cast any values into a Boolean if possible,
 | 
			
		||||
     * but may miss any values out if they are not compatible.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the List to get.
 | 
			
		||||
     * @return Requested List of Boolean.
 | 
			
		||||
     */
 | 
			
		||||
    public List<Boolean> getBooleanList(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested List of Double by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the List does not exist but a default value has been specified, this
 | 
			
		||||
     * will return the default value. If the List does not exist and no
 | 
			
		||||
     * default value was specified, this will return an empty List.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This method will attempt to cast any values into a Double if possible,
 | 
			
		||||
     * but may miss any values out if they are not compatible.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the List to get.
 | 
			
		||||
     * @return Requested List of Double.
 | 
			
		||||
     */
 | 
			
		||||
    public List<Double> getDoubleList(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested List of Float by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the List does not exist but a default value has been specified, this
 | 
			
		||||
     * will return the default value. If the List does not exist and no
 | 
			
		||||
     * default value was specified, this will return an empty List.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This method will attempt to cast any values into a Float if possible,
 | 
			
		||||
     * but may miss any values out if they are not compatible.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the List to get.
 | 
			
		||||
     * @return Requested List of Float.
 | 
			
		||||
     */
 | 
			
		||||
    public List<Float> getFloatList(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested List of Long by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the List does not exist but a default value has been specified, this
 | 
			
		||||
     * will return the default value. If the List does not exist and no
 | 
			
		||||
     * default value was specified, this will return an empty List.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This method will attempt to cast any values into a Long if possible,
 | 
			
		||||
     * but may miss any values out if they are not compatible.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the List to get.
 | 
			
		||||
     * @return Requested List of Long.
 | 
			
		||||
     */
 | 
			
		||||
    public List<Long> getLongList(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested List of Byte by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the List does not exist but a default value has been specified, this
 | 
			
		||||
     * will return the default value. If the List does not exist and no
 | 
			
		||||
     * default value was specified, this will return an empty List.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This method will attempt to cast any values into a Byte if possible,
 | 
			
		||||
     * but may miss any values out if they are not compatible.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the List to get.
 | 
			
		||||
     * @return Requested List of Byte.
 | 
			
		||||
     */
 | 
			
		||||
    public List<Byte> getByteList(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested List of Character by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the List does not exist but a default value has been specified, this
 | 
			
		||||
     * will return the default value. If the List does not exist and no
 | 
			
		||||
     * default value was specified, this will return an empty List.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This method will attempt to cast any values into a Character if
 | 
			
		||||
     * possible, but may miss any values out if they are not compatible.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the List to get.
 | 
			
		||||
     * @return Requested List of Character.
 | 
			
		||||
     */
 | 
			
		||||
    public List<Character> getCharacterList(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested List of Short by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the List does not exist but a default value has been specified, this
 | 
			
		||||
     * will return the default value. If the List does not exist and no
 | 
			
		||||
     * default value was specified, this will return an empty List.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This method will attempt to cast any values into a Short if possible,
 | 
			
		||||
     * but may miss any values out if they are not compatible.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the List to get.
 | 
			
		||||
     * @return Requested List of Short.
 | 
			
		||||
     */
 | 
			
		||||
    public List<Short> getShortList(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested List of Maps by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the List does not exist but a default value has been specified, this
 | 
			
		||||
     * will return the default value. If the List does not exist and no
 | 
			
		||||
     * default value was specified, this will return an empty List.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This method will attempt to cast any values into a Map if possible, but
 | 
			
		||||
     * may miss any values out if they are not compatible.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the List to get.
 | 
			
		||||
     * @return Requested List of Maps.
 | 
			
		||||
     */
 | 
			
		||||
    public List<Map<?, ?>> getMapList(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the requested ConfigurationSection by path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the ConfigurationSection does not exist but a default value has been
 | 
			
		||||
     * specified, this will return the default value. If the
 | 
			
		||||
     * ConfigurationSection does not exist and no default value was specified,
 | 
			
		||||
     * this will return null.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the ConfigurationSection to get.
 | 
			
		||||
     * @return Requested ConfigurationSection.
 | 
			
		||||
     */
 | 
			
		||||
    public ConfigurationSection getConfigurationSection(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if the specified path is a ConfigurationSection.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the path exists but is not a ConfigurationSection, this will return
 | 
			
		||||
     * false. If the path does not exist, this will return false. If the path
 | 
			
		||||
     * does not exist but a default value has been specified, this will check
 | 
			
		||||
     * if that default value is a ConfigurationSection and return
 | 
			
		||||
     * appropriately.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the ConfigurationSection to check.
 | 
			
		||||
     * @return Whether or not the specified path is a ConfigurationSection.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isConfigurationSection(String path);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the equivalent {@link ConfigurationSection} from the default
 | 
			
		||||
     * {@link Configuration} defined in {@link #getRoot()}.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the root contains no defaults, or the defaults doesn't contain a
 | 
			
		||||
     * value for this path, or the value at this path is not a {@link
 | 
			
		||||
     * ConfigurationSection} then this will return null.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Equivalent section in root configuration
 | 
			
		||||
     */
 | 
			
		||||
    public ConfigurationSection getDefaultSection();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the default value in the root at the given path as provided.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If no source {@link Configuration} was provided as a default
 | 
			
		||||
     * collection, then a new {@link MemoryConfiguration} will be created to
 | 
			
		||||
     * hold the new default value.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If value is null, the value will be removed from the default
 | 
			
		||||
     * Configuration source.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the value as returned by {@link #getDefaultSection()} is null, then
 | 
			
		||||
     * this will create a new section at the path, replacing anything that may
 | 
			
		||||
     * have existed there previously.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path Path of the value to set.
 | 
			
		||||
     * @param value Value to set the default to.
 | 
			
		||||
     * @throws IllegalArgumentException Thrown if path is null.
 | 
			
		||||
     */
 | 
			
		||||
    public void addDefault(String path, Object value);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,45 @@
 | 
			
		||||
package com.intellectualcrafters.configuration;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Exception thrown when attempting to load an invalid {@link Configuration}
 | 
			
		||||
 */
 | 
			
		||||
@SuppressWarnings("serial")
 | 
			
		||||
public class InvalidConfigurationException extends Exception {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new instance of InvalidConfigurationException without a
 | 
			
		||||
     * message or cause.
 | 
			
		||||
     */
 | 
			
		||||
    public InvalidConfigurationException() {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs an instance of InvalidConfigurationException with the
 | 
			
		||||
     * specified message.
 | 
			
		||||
     *
 | 
			
		||||
     * @param msg The details of the exception.
 | 
			
		||||
     */
 | 
			
		||||
    public InvalidConfigurationException(String msg) {
 | 
			
		||||
        super(msg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs an instance of InvalidConfigurationException with the
 | 
			
		||||
     * specified cause.
 | 
			
		||||
     *
 | 
			
		||||
     * @param cause The cause of the exception.
 | 
			
		||||
     */
 | 
			
		||||
    public InvalidConfigurationException(Throwable cause) {
 | 
			
		||||
        super(cause);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs an instance of InvalidConfigurationException with the
 | 
			
		||||
     * specified message and cause.
 | 
			
		||||
     *
 | 
			
		||||
     * @param cause The cause of the exception.
 | 
			
		||||
     * @param msg The details of the exception.
 | 
			
		||||
     */
 | 
			
		||||
    public InvalidConfigurationException(String msg, Throwable cause) {
 | 
			
		||||
        super(msg, cause);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,76 @@
 | 
			
		||||
package com.intellectualcrafters.configuration;
 | 
			
		||||
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is a {@link Configuration} implementation that does not save or load
 | 
			
		||||
 * from any source, and stores all values in memory only.
 | 
			
		||||
 * This is useful for temporary Configurations for providing defaults.
 | 
			
		||||
 */
 | 
			
		||||
public class MemoryConfiguration extends MemorySection implements Configuration {
 | 
			
		||||
    protected Configuration defaults;
 | 
			
		||||
    protected MemoryConfigurationOptions options;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an empty {@link MemoryConfiguration} with no default values.
 | 
			
		||||
     */
 | 
			
		||||
    public MemoryConfiguration() {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an empty {@link MemoryConfiguration} using the specified {@link
 | 
			
		||||
     * Configuration} as a source for all default values.
 | 
			
		||||
     *
 | 
			
		||||
     * @param defaults Default value provider
 | 
			
		||||
     * @throws IllegalArgumentException Thrown if defaults is null
 | 
			
		||||
     */
 | 
			
		||||
    public MemoryConfiguration(Configuration defaults) {
 | 
			
		||||
        this.defaults = defaults;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addDefault(String path, Object value) {
 | 
			
		||||
        if (path == null) throw new NullPointerException("Path may not be null");
 | 
			
		||||
        if (defaults == null) {
 | 
			
		||||
            defaults = new MemoryConfiguration();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        defaults.set(path, value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addDefaults(Map<String, Object> defaults) {
 | 
			
		||||
        if (defaults == null) throw new NullPointerException("Defaults may not be null");
 | 
			
		||||
 | 
			
		||||
        for (Map.Entry<String, Object> entry : defaults.entrySet()) {
 | 
			
		||||
            addDefault(entry.getKey(), entry.getValue());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addDefaults(Configuration defaults) {
 | 
			
		||||
        if (defaults == null) throw new NullPointerException("Defaults may not be null");
 | 
			
		||||
 | 
			
		||||
        addDefaults(defaults.getValues(true));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setDefaults(Configuration defaults) {
 | 
			
		||||
        if (defaults == null) throw new NullPointerException("Defaults may not be null");
 | 
			
		||||
 | 
			
		||||
        this.defaults = defaults;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Configuration getDefaults() {
 | 
			
		||||
        return defaults;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ConfigurationSection getParent() {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MemoryConfigurationOptions options() {
 | 
			
		||||
        if (options == null) {
 | 
			
		||||
            options = new MemoryConfigurationOptions(this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return options;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,28 @@
 | 
			
		||||
package com.intellectualcrafters.configuration;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Various settings for controlling the input and output of a {@link
 | 
			
		||||
 * MemoryConfiguration}
 | 
			
		||||
 */
 | 
			
		||||
public class MemoryConfigurationOptions extends ConfigurationOptions {
 | 
			
		||||
    protected MemoryConfigurationOptions(MemoryConfiguration configuration) {
 | 
			
		||||
        super(configuration);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public MemoryConfiguration configuration() {
 | 
			
		||||
        return (MemoryConfiguration) super.configuration();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public MemoryConfigurationOptions copyDefaults(boolean value) {
 | 
			
		||||
        super.copyDefaults(value);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public MemoryConfigurationOptions pathSeparator(char value) {
 | 
			
		||||
        super.pathSeparator(value);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,755 @@
 | 
			
		||||
package com.intellectualcrafters.configuration;
 | 
			
		||||
 | 
			
		||||
import static org.bukkit.util.NumberConversions.toDouble;
 | 
			
		||||
import static org.bukkit.util.NumberConversions.toInt;
 | 
			
		||||
import static org.bukkit.util.NumberConversions.toLong;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.LinkedHashMap;
 | 
			
		||||
import java.util.LinkedHashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A type of {@link ConfigurationSection} that is stored in memory.
 | 
			
		||||
 */
 | 
			
		||||
public class MemorySection implements ConfigurationSection {
 | 
			
		||||
    protected final Map<String, Object> map = new LinkedHashMap<String, Object>();
 | 
			
		||||
    private final Configuration root;
 | 
			
		||||
    private final ConfigurationSection parent;
 | 
			
		||||
    private final String path;
 | 
			
		||||
    private final String fullPath;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an empty MemorySection for use as a root {@link Configuration}
 | 
			
		||||
     * section.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Note that calling this without being yourself a {@link Configuration}
 | 
			
		||||
     * will throw an exception!
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IllegalStateException Thrown if this is not a {@link
 | 
			
		||||
     *     Configuration} root.
 | 
			
		||||
     */
 | 
			
		||||
    protected MemorySection() {
 | 
			
		||||
        if (!(this instanceof Configuration)) {
 | 
			
		||||
            throw new IllegalStateException("Cannot construct a root MemorySection when not a Configuration");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.path = "";
 | 
			
		||||
        this.fullPath = "";
 | 
			
		||||
        this.parent = null;
 | 
			
		||||
        this.root = (Configuration) this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an empty MemorySection with the specified parent and path.
 | 
			
		||||
     *
 | 
			
		||||
     * @param parent Parent section that contains this own section.
 | 
			
		||||
     * @param path Path that you may access this section from via the root
 | 
			
		||||
     *     {@link Configuration}.
 | 
			
		||||
     * @throws IllegalArgumentException Thrown is parent or path is null, or
 | 
			
		||||
     *     if parent contains no root Configuration.
 | 
			
		||||
     */
 | 
			
		||||
    protected MemorySection(ConfigurationSection parent, String path) {
 | 
			
		||||
        if (parent == null) throw new NullPointerException("Parent may not be null");
 | 
			
		||||
        if (path == null) throw new NullPointerException("Path may not be null");
 | 
			
		||||
 | 
			
		||||
        this.path = path;
 | 
			
		||||
        this.parent = parent;
 | 
			
		||||
        this.root = parent.getRoot();
 | 
			
		||||
 | 
			
		||||
        if (root == null) throw new NullPointerException("Path may not be orphaned");
 | 
			
		||||
 | 
			
		||||
        this.fullPath = createPath(parent, path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Set<String> getKeys(boolean deep) {
 | 
			
		||||
        Set<String> result = new LinkedHashSet<String>();
 | 
			
		||||
 | 
			
		||||
        Configuration root = getRoot();
 | 
			
		||||
        if (root != null && root.options().copyDefaults()) {
 | 
			
		||||
            ConfigurationSection defaults = getDefaultSection();
 | 
			
		||||
 | 
			
		||||
            if (defaults != null) {
 | 
			
		||||
                result.addAll(defaults.getKeys(deep));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mapChildrenKeys(result, this, deep);
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Map<String, Object> getValues(boolean deep) {
 | 
			
		||||
        Map<String, Object> result = new LinkedHashMap<String, Object>();
 | 
			
		||||
 | 
			
		||||
        Configuration root = getRoot();
 | 
			
		||||
        if (root != null && root.options().copyDefaults()) {
 | 
			
		||||
            ConfigurationSection defaults = getDefaultSection();
 | 
			
		||||
 | 
			
		||||
            if (defaults != null) {
 | 
			
		||||
                result.putAll(defaults.getValues(deep));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mapChildrenValues(result, this, deep);
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean contains(String path) {
 | 
			
		||||
        return get(path) != null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isSet(String path) {
 | 
			
		||||
        Configuration root = getRoot();
 | 
			
		||||
        if (root == null) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (root.options().copyDefaults()) {
 | 
			
		||||
            return contains(path);
 | 
			
		||||
        }
 | 
			
		||||
        return get(path, null) != null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getCurrentPath() {
 | 
			
		||||
        return fullPath;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getName() {
 | 
			
		||||
        return path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Configuration getRoot() {
 | 
			
		||||
        return root;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ConfigurationSection getParent() {
 | 
			
		||||
        return parent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addDefault(String path, Object value) {
 | 
			
		||||
        if (path == null) throw new NullPointerException("Path cannot be null");
 | 
			
		||||
 | 
			
		||||
        Configuration root = getRoot();
 | 
			
		||||
        if (root == null) {
 | 
			
		||||
            throw new IllegalStateException("Cannot add default without root");
 | 
			
		||||
        }
 | 
			
		||||
        if (root == this) {
 | 
			
		||||
            throw new UnsupportedOperationException("Unsupported addDefault(String, Object) implementation");
 | 
			
		||||
        }
 | 
			
		||||
        root.addDefault(createPath(this, path), value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ConfigurationSection getDefaultSection() {
 | 
			
		||||
        Configuration root = getRoot();
 | 
			
		||||
        Configuration defaults = root == null ? null : root.getDefaults();
 | 
			
		||||
 | 
			
		||||
        if (defaults != null) {
 | 
			
		||||
            if (defaults.isConfigurationSection(getCurrentPath())) {
 | 
			
		||||
                return defaults.getConfigurationSection(getCurrentPath());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void set(String path, Object value) {
 | 
			
		||||
        if (path == null) throw new NullPointerException("Cannot set to an empty path");
 | 
			
		||||
 | 
			
		||||
        Configuration root = getRoot();
 | 
			
		||||
        if (root == null) {
 | 
			
		||||
            throw new IllegalStateException("Cannot use section without a root");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final char separator = root.options().pathSeparator();
 | 
			
		||||
        // i1 is the leading (higher) index
 | 
			
		||||
        // i2 is the trailing (lower) index
 | 
			
		||||
        int i1 = -1, i2;
 | 
			
		||||
        ConfigurationSection section = this;
 | 
			
		||||
        while ((i1 = path.indexOf(separator, i2 = i1 + 1)) != -1) {
 | 
			
		||||
            String node = path.substring(i2, i1);
 | 
			
		||||
            ConfigurationSection subSection = section.getConfigurationSection(node);
 | 
			
		||||
            if (subSection == null) {
 | 
			
		||||
                section = section.createSection(node);
 | 
			
		||||
            } else {
 | 
			
		||||
                section = subSection;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String key = path.substring(i2);
 | 
			
		||||
        if (section == this) {
 | 
			
		||||
            if (value == null) {
 | 
			
		||||
                map.remove(key);
 | 
			
		||||
            } else {
 | 
			
		||||
                map.put(key, value);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            section.set(key, value);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Object get(String path) {
 | 
			
		||||
        return get(path, getDefault(path));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Object get(String path, Object def) {
 | 
			
		||||
        if (path == null) throw new NullPointerException("Path cannot be null");
 | 
			
		||||
 | 
			
		||||
        if (path.length() == 0) {
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Configuration root = getRoot();
 | 
			
		||||
        if (root == null) {
 | 
			
		||||
            throw new IllegalStateException("Cannot access section without a root");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final char separator = root.options().pathSeparator();
 | 
			
		||||
        // i1 is the leading (higher) index
 | 
			
		||||
        // i2 is the trailing (lower) index
 | 
			
		||||
        int i1 = -1, i2;
 | 
			
		||||
        ConfigurationSection section = this;
 | 
			
		||||
        while ((i1 = path.indexOf(separator, i2 = i1 + 1)) != -1) {
 | 
			
		||||
            section = section.getConfigurationSection(path.substring(i2, i1));
 | 
			
		||||
            if (section == null) {
 | 
			
		||||
                return def;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String key = path.substring(i2);
 | 
			
		||||
        if (section == this) {
 | 
			
		||||
            Object result = map.get(key);
 | 
			
		||||
            return (result == null) ? def : result;
 | 
			
		||||
        }
 | 
			
		||||
        return section.get(key, def);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ConfigurationSection createSection(String path) {
 | 
			
		||||
        if (path == null) throw new NullPointerException("Cannot create section at empty path");
 | 
			
		||||
        Configuration root = getRoot();
 | 
			
		||||
        if (root == null) {
 | 
			
		||||
            throw new IllegalStateException("Cannot create section without a root");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final char separator = root.options().pathSeparator();
 | 
			
		||||
        // i1 is the leading (higher) index
 | 
			
		||||
        // i2 is the trailing (lower) index
 | 
			
		||||
        int i1 = -1, i2;
 | 
			
		||||
        ConfigurationSection section = this;
 | 
			
		||||
        while ((i1 = path.indexOf(separator, i2 = i1 + 1)) != -1) {
 | 
			
		||||
            String node = path.substring(i2, i1);
 | 
			
		||||
            ConfigurationSection subSection = section.getConfigurationSection(node);
 | 
			
		||||
            if (subSection == null) {
 | 
			
		||||
                section = section.createSection(node);
 | 
			
		||||
            } else {
 | 
			
		||||
                section = subSection;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String key = path.substring(i2);
 | 
			
		||||
        if (section == this) {
 | 
			
		||||
            ConfigurationSection result = new MemorySection(this, key);
 | 
			
		||||
            map.put(key, result);
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
        return section.createSection(key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ConfigurationSection createSection(String path, Map<?, ?> map) {
 | 
			
		||||
        ConfigurationSection section = createSection(path);
 | 
			
		||||
 | 
			
		||||
        for (Map.Entry<?, ?> entry : map.entrySet()) {
 | 
			
		||||
            if (entry.getValue() instanceof Map) {
 | 
			
		||||
                section.createSection(entry.getKey().toString(), (Map<?, ?>) entry.getValue());
 | 
			
		||||
            } else {
 | 
			
		||||
                section.set(entry.getKey().toString(), entry.getValue());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return section;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Primitives
 | 
			
		||||
    public String getString(String path) {
 | 
			
		||||
        Object def = getDefault(path);
 | 
			
		||||
        return getString(path, def != null ? def.toString() : null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getString(String path, String def) {
 | 
			
		||||
        Object val = get(path, def);
 | 
			
		||||
        return (val != null) ? val.toString() : def;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isString(String path) {
 | 
			
		||||
        Object val = get(path);
 | 
			
		||||
        return val instanceof String;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getInt(String path) {
 | 
			
		||||
        Object def = getDefault(path);
 | 
			
		||||
        return getInt(path, (def instanceof Number) ? toInt(def) : 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getInt(String path, int def) {
 | 
			
		||||
        Object val = get(path, def);
 | 
			
		||||
        return (val instanceof Number) ? toInt(val) : def;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isInt(String path) {
 | 
			
		||||
        Object val = get(path);
 | 
			
		||||
        return val instanceof Integer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean getBoolean(String path) {
 | 
			
		||||
        Object def = getDefault(path);
 | 
			
		||||
        return getBoolean(path, (def instanceof Boolean) ? (Boolean) def : false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean getBoolean(String path, boolean def) {
 | 
			
		||||
        Object val = get(path, def);
 | 
			
		||||
        return (val instanceof Boolean) ? (Boolean) val : def;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isBoolean(String path) {
 | 
			
		||||
        Object val = get(path);
 | 
			
		||||
        return val instanceof Boolean;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public double getDouble(String path) {
 | 
			
		||||
        Object def = getDefault(path);
 | 
			
		||||
        return getDouble(path, (def instanceof Number) ? toDouble(def) : 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public double getDouble(String path, double def) {
 | 
			
		||||
        Object val = get(path, def);
 | 
			
		||||
        return (val instanceof Number) ? toDouble(val) : def;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isDouble(String path) {
 | 
			
		||||
        Object val = get(path);
 | 
			
		||||
        return val instanceof Double;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public long getLong(String path) {
 | 
			
		||||
        Object def = getDefault(path);
 | 
			
		||||
        return getLong(path, (def instanceof Number) ? toLong(def) : 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public long getLong(String path, long def) {
 | 
			
		||||
        Object val = get(path, def);
 | 
			
		||||
        return (val instanceof Number) ? toLong(val) : def;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isLong(String path) {
 | 
			
		||||
        Object val = get(path);
 | 
			
		||||
        return val instanceof Long;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Java
 | 
			
		||||
    public List<?> getList(String path) {
 | 
			
		||||
        Object def = getDefault(path);
 | 
			
		||||
        return getList(path, (def instanceof List) ? (List<?>) def : null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<?> getList(String path, List<?> def) {
 | 
			
		||||
        Object val = get(path, def);
 | 
			
		||||
        return (List<?>) ((val instanceof List) ? val : def);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isList(String path) {
 | 
			
		||||
        Object val = get(path);
 | 
			
		||||
        return val instanceof List;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<String> getStringList(String path) {
 | 
			
		||||
        List<?> list = getList(path);
 | 
			
		||||
 | 
			
		||||
        if (list == null) {
 | 
			
		||||
            return new ArrayList<String>(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<String> result = new ArrayList<String>();
 | 
			
		||||
 | 
			
		||||
        for (Object object : list) {
 | 
			
		||||
            if ((object instanceof String) || (isPrimitiveWrapper(object))) {
 | 
			
		||||
                result.add(String.valueOf(object));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Integer> getIntegerList(String path) {
 | 
			
		||||
        List<?> list = getList(path);
 | 
			
		||||
 | 
			
		||||
        if (list == null) {
 | 
			
		||||
            return new ArrayList<Integer>(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<Integer> result = new ArrayList<Integer>();
 | 
			
		||||
 | 
			
		||||
        for (Object object : list) {
 | 
			
		||||
            if (object instanceof Integer) {
 | 
			
		||||
                result.add((Integer) object);
 | 
			
		||||
            } else if (object instanceof String) {
 | 
			
		||||
                try {
 | 
			
		||||
                    result.add(Integer.valueOf((String) object));
 | 
			
		||||
                } catch (Exception ex) {
 | 
			
		||||
                }
 | 
			
		||||
            } else if (object instanceof Character) {
 | 
			
		||||
                result.add((int) ((Character) object).charValue());
 | 
			
		||||
            } else if (object instanceof Number) {
 | 
			
		||||
                result.add(((Number) object).intValue());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Boolean> getBooleanList(String path) {
 | 
			
		||||
        List<?> list = getList(path);
 | 
			
		||||
 | 
			
		||||
        if (list == null) {
 | 
			
		||||
            return new ArrayList<Boolean>(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<Boolean> result = new ArrayList<Boolean>();
 | 
			
		||||
 | 
			
		||||
        for (Object object : list) {
 | 
			
		||||
            if (object instanceof Boolean) {
 | 
			
		||||
                result.add((Boolean) object);
 | 
			
		||||
            } else if (object instanceof String) {
 | 
			
		||||
                if (Boolean.TRUE.toString().equals(object)) {
 | 
			
		||||
                    result.add(true);
 | 
			
		||||
                } else if (Boolean.FALSE.toString().equals(object)) {
 | 
			
		||||
                    result.add(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Double> getDoubleList(String path) {
 | 
			
		||||
        List<?> list = getList(path);
 | 
			
		||||
 | 
			
		||||
        if (list == null) {
 | 
			
		||||
            return new ArrayList<Double>(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<Double> result = new ArrayList<Double>();
 | 
			
		||||
 | 
			
		||||
        for (Object object : list) {
 | 
			
		||||
            if (object instanceof Double) {
 | 
			
		||||
                result.add((Double) object);
 | 
			
		||||
            } else if (object instanceof String) {
 | 
			
		||||
                try {
 | 
			
		||||
                    result.add(Double.valueOf((String) object));
 | 
			
		||||
                } catch (Exception ex) {
 | 
			
		||||
                }
 | 
			
		||||
            } else if (object instanceof Character) {
 | 
			
		||||
                result.add((double) ((Character) object).charValue());
 | 
			
		||||
            } else if (object instanceof Number) {
 | 
			
		||||
                result.add(((Number) object).doubleValue());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Float> getFloatList(String path) {
 | 
			
		||||
        List<?> list = getList(path);
 | 
			
		||||
 | 
			
		||||
        if (list == null) {
 | 
			
		||||
            return new ArrayList<Float>(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<Float> result = new ArrayList<Float>();
 | 
			
		||||
 | 
			
		||||
        for (Object object : list) {
 | 
			
		||||
            if (object instanceof Float) {
 | 
			
		||||
                result.add((Float) object);
 | 
			
		||||
            } else if (object instanceof String) {
 | 
			
		||||
                try {
 | 
			
		||||
                    result.add(Float.valueOf((String) object));
 | 
			
		||||
                } catch (Exception ex) {
 | 
			
		||||
                }
 | 
			
		||||
            } else if (object instanceof Character) {
 | 
			
		||||
                result.add((float) ((Character) object).charValue());
 | 
			
		||||
            } else if (object instanceof Number) {
 | 
			
		||||
                result.add(((Number) object).floatValue());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Long> getLongList(String path) {
 | 
			
		||||
        List<?> list = getList(path);
 | 
			
		||||
 | 
			
		||||
        if (list == null) {
 | 
			
		||||
            return new ArrayList<Long>(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<Long> result = new ArrayList<Long>();
 | 
			
		||||
 | 
			
		||||
        for (Object object : list) {
 | 
			
		||||
            if (object instanceof Long) {
 | 
			
		||||
                result.add((Long) object);
 | 
			
		||||
            } else if (object instanceof String) {
 | 
			
		||||
                try {
 | 
			
		||||
                    result.add(Long.valueOf((String) object));
 | 
			
		||||
                } catch (Exception ex) {
 | 
			
		||||
                }
 | 
			
		||||
            } else if (object instanceof Character) {
 | 
			
		||||
                result.add((long) ((Character) object).charValue());
 | 
			
		||||
            } else if (object instanceof Number) {
 | 
			
		||||
                result.add(((Number) object).longValue());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Byte> getByteList(String path) {
 | 
			
		||||
        List<?> list = getList(path);
 | 
			
		||||
 | 
			
		||||
        if (list == null) {
 | 
			
		||||
            return new ArrayList<Byte>(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<Byte> result = new ArrayList<Byte>();
 | 
			
		||||
 | 
			
		||||
        for (Object object : list) {
 | 
			
		||||
            if (object instanceof Byte) {
 | 
			
		||||
                result.add((Byte) object);
 | 
			
		||||
            } else if (object instanceof String) {
 | 
			
		||||
                try {
 | 
			
		||||
                    result.add(Byte.valueOf((String) object));
 | 
			
		||||
                } catch (Exception ex) {
 | 
			
		||||
                }
 | 
			
		||||
            } else if (object instanceof Character) {
 | 
			
		||||
                result.add((byte) ((Character) object).charValue());
 | 
			
		||||
            } else if (object instanceof Number) {
 | 
			
		||||
                result.add(((Number) object).byteValue());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Character> getCharacterList(String path) {
 | 
			
		||||
        List<?> list = getList(path);
 | 
			
		||||
 | 
			
		||||
        if (list == null) {
 | 
			
		||||
            return new ArrayList<Character>(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<Character> result = new ArrayList<Character>();
 | 
			
		||||
 | 
			
		||||
        for (Object object : list) {
 | 
			
		||||
            if (object instanceof Character) {
 | 
			
		||||
                result.add((Character) object);
 | 
			
		||||
            } else if (object instanceof String) {
 | 
			
		||||
                String str = (String) object;
 | 
			
		||||
 | 
			
		||||
                if (str.length() == 1) {
 | 
			
		||||
                    result.add(str.charAt(0));
 | 
			
		||||
                }
 | 
			
		||||
            } else if (object instanceof Number) {
 | 
			
		||||
                result.add((char) ((Number) object).intValue());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Short> getShortList(String path) {
 | 
			
		||||
        List<?> list = getList(path);
 | 
			
		||||
 | 
			
		||||
        if (list == null) {
 | 
			
		||||
            return new ArrayList<Short>(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<Short> result = new ArrayList<Short>();
 | 
			
		||||
 | 
			
		||||
        for (Object object : list) {
 | 
			
		||||
            if (object instanceof Short) {
 | 
			
		||||
                result.add((Short) object);
 | 
			
		||||
            } else if (object instanceof String) {
 | 
			
		||||
                try {
 | 
			
		||||
                    result.add(Short.valueOf((String) object));
 | 
			
		||||
                } catch (Exception ex) {
 | 
			
		||||
                }
 | 
			
		||||
            } else if (object instanceof Character) {
 | 
			
		||||
                result.add((short) ((Character) object).charValue());
 | 
			
		||||
            } else if (object instanceof Number) {
 | 
			
		||||
                result.add(((Number) object).shortValue());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Map<?, ?>> getMapList(String path) {
 | 
			
		||||
        List<?> list = getList(path);
 | 
			
		||||
        List<Map<?, ?>> result = new ArrayList<Map<?, ?>>();
 | 
			
		||||
 | 
			
		||||
        if (list == null) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (Object object : list) {
 | 
			
		||||
            if (object instanceof Map) {
 | 
			
		||||
                result.add((Map<?, ?>) object);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ConfigurationSection getConfigurationSection(String path) {
 | 
			
		||||
        Object val = get(path, null);
 | 
			
		||||
        if (val != null) {
 | 
			
		||||
            return (val instanceof ConfigurationSection) ? (ConfigurationSection) val : null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val = get(path, getDefault(path));
 | 
			
		||||
        return (val instanceof ConfigurationSection) ? createSection(path) : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isConfigurationSection(String path) {
 | 
			
		||||
        Object val = get(path);
 | 
			
		||||
        return val instanceof ConfigurationSection;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected boolean isPrimitiveWrapper(Object input) {
 | 
			
		||||
        return input instanceof Integer || input instanceof Boolean ||
 | 
			
		||||
                input instanceof Character || input instanceof Byte ||
 | 
			
		||||
                input instanceof Short || input instanceof Double ||
 | 
			
		||||
                input instanceof Long || input instanceof Float;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected Object getDefault(String path) {
 | 
			
		||||
        if (path == null) throw new NullPointerException("Path may not be null");
 | 
			
		||||
 | 
			
		||||
        Configuration root = getRoot();
 | 
			
		||||
        Configuration defaults = root == null ? null : root.getDefaults();
 | 
			
		||||
        return (defaults == null) ? null : defaults.get(createPath(this, path));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected void mapChildrenKeys(Set<String> output, ConfigurationSection section, boolean deep) {
 | 
			
		||||
        if (section instanceof MemorySection) {
 | 
			
		||||
            MemorySection sec = (MemorySection) section;
 | 
			
		||||
 | 
			
		||||
            for (Map.Entry<String, Object> entry : sec.map.entrySet()) {
 | 
			
		||||
                output.add(createPath(section, entry.getKey(), this));
 | 
			
		||||
 | 
			
		||||
                if ((deep) && (entry.getValue() instanceof ConfigurationSection)) {
 | 
			
		||||
                    ConfigurationSection subsection = (ConfigurationSection) entry.getValue();
 | 
			
		||||
                    mapChildrenKeys(output, subsection, deep);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            Set<String> keys = section.getKeys(deep);
 | 
			
		||||
 | 
			
		||||
            for (String key : keys) {
 | 
			
		||||
                output.add(createPath(section, key, this));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected void mapChildrenValues(Map<String, Object> output, ConfigurationSection section, boolean deep) {
 | 
			
		||||
        if (section instanceof MemorySection) {
 | 
			
		||||
            MemorySection sec = (MemorySection) section;
 | 
			
		||||
 | 
			
		||||
            for (Map.Entry<String, Object> entry : sec.map.entrySet()) {
 | 
			
		||||
                output.put(createPath(section, entry.getKey(), this), entry.getValue());
 | 
			
		||||
 | 
			
		||||
                if (entry.getValue() instanceof ConfigurationSection) {
 | 
			
		||||
                    if (deep) {
 | 
			
		||||
                        mapChildrenValues(output, (ConfigurationSection) entry.getValue(), deep);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            Map<String, Object> values = section.getValues(deep);
 | 
			
		||||
 | 
			
		||||
            for (Map.Entry<String, Object> entry : values.entrySet()) {
 | 
			
		||||
                output.put(createPath(section, entry.getKey(), this), entry.getValue());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a full path to the given {@link ConfigurationSection} from its
 | 
			
		||||
     * root {@link Configuration}.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * You may use this method for any given {@link ConfigurationSection}, not
 | 
			
		||||
     * only {@link MemorySection}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param section Section to create a path for.
 | 
			
		||||
     * @param key Name of the specified section.
 | 
			
		||||
     * @return Full path of the section from its root.
 | 
			
		||||
     */
 | 
			
		||||
    public static String createPath(ConfigurationSection section, String key) {
 | 
			
		||||
        return createPath(section, key, (section == null) ? null : section.getRoot());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a relative path to the given {@link ConfigurationSection} from
 | 
			
		||||
     * the given relative section.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * You may use this method for any given {@link ConfigurationSection}, not
 | 
			
		||||
     * only {@link MemorySection}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param section Section to create a path for.
 | 
			
		||||
     * @param key Name of the specified section.
 | 
			
		||||
     * @param relativeTo Section to create the path relative to.
 | 
			
		||||
     * @return Full path of the section from its root.
 | 
			
		||||
     */
 | 
			
		||||
    public static String createPath(ConfigurationSection section, String key, ConfigurationSection relativeTo) {
 | 
			
		||||
        if (section == null) throw new NullPointerException("Cannot create path without a section");
 | 
			
		||||
        Configuration root = section.getRoot();
 | 
			
		||||
        if (root == null) {
 | 
			
		||||
            throw new IllegalStateException("Cannot create path without a root");
 | 
			
		||||
        }
 | 
			
		||||
        char separator = root.options().pathSeparator();
 | 
			
		||||
 | 
			
		||||
        StringBuilder builder = new StringBuilder();
 | 
			
		||||
        if (section != null) {
 | 
			
		||||
            for (ConfigurationSection parent = section; (parent != null) && (parent != relativeTo); parent = parent.getParent()) {
 | 
			
		||||
                if (builder.length() > 0) {
 | 
			
		||||
                    builder.insert(0, separator);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                builder.insert(0, parent.getName());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ((key != null) && (key.length() > 0)) {
 | 
			
		||||
            if (builder.length() > 0) {
 | 
			
		||||
                builder.append(separator);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            builder.append(key);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return builder.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        Configuration root = getRoot();
 | 
			
		||||
        return new StringBuilder()
 | 
			
		||||
            .append(getClass().getSimpleName())
 | 
			
		||||
            .append("[path='")
 | 
			
		||||
            .append(getCurrentPath())
 | 
			
		||||
            .append("', root='")
 | 
			
		||||
            .append(root == null ? null : root.getClass().getSimpleName())
 | 
			
		||||
            .append("']")
 | 
			
		||||
            .toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,286 @@
 | 
			
		||||
package com.intellectualcrafters.configuration.file;
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedReader;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
import java.io.OutputStreamWriter;
 | 
			
		||||
import java.io.Reader;
 | 
			
		||||
import java.io.Writer;
 | 
			
		||||
import java.nio.charset.Charset;
 | 
			
		||||
import java.nio.charset.StandardCharsets;
 | 
			
		||||
 | 
			
		||||
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.configuration.Configuration;
 | 
			
		||||
import com.intellectualcrafters.configuration.InvalidConfigurationException;
 | 
			
		||||
import com.intellectualcrafters.configuration.MemoryConfiguration;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is a base class for all File based implementations of {@link
 | 
			
		||||
 * Configuration}
 | 
			
		||||
 */
 | 
			
		||||
public abstract class FileConfiguration extends MemoryConfiguration {
 | 
			
		||||
    /**
 | 
			
		||||
     * This value specified that the system default encoding should be
 | 
			
		||||
     * completely ignored, as it cannot handle the ASCII character set, or it
 | 
			
		||||
     * is a strict-subset of UTF8 already (plain ASCII).
 | 
			
		||||
     *
 | 
			
		||||
     * @deprecated temporary compatibility measure
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public static final boolean UTF8_OVERRIDE;
 | 
			
		||||
    /**
 | 
			
		||||
     * This value specifies if the system default encoding is unicode, but
 | 
			
		||||
     * cannot parse standard ASCII.
 | 
			
		||||
     *
 | 
			
		||||
     * @deprecated temporary compatibility measure
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public static final boolean UTF_BIG;
 | 
			
		||||
    /**
 | 
			
		||||
     * This value specifies if the system supports unicode.
 | 
			
		||||
     *
 | 
			
		||||
     * @deprecated temporary compatibility measure
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public static final boolean SYSTEM_UTF;
 | 
			
		||||
    static {
 | 
			
		||||
        final byte[] testBytes = Base64Coder.decode("ICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX4NCg==");
 | 
			
		||||
        final String testString = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\r\n";
 | 
			
		||||
        final Charset defaultCharset = Charset.defaultCharset();
 | 
			
		||||
        final String resultString = new String(testBytes, defaultCharset);
 | 
			
		||||
        final boolean trueUTF = defaultCharset.name().contains("UTF");
 | 
			
		||||
        UTF8_OVERRIDE = !testString.equals(resultString) || defaultCharset.equals(Charset.forName("US-ASCII"));
 | 
			
		||||
        SYSTEM_UTF = trueUTF || UTF8_OVERRIDE;
 | 
			
		||||
        UTF_BIG = trueUTF && UTF8_OVERRIDE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an empty {@link FileConfiguration} with no default values.
 | 
			
		||||
     */
 | 
			
		||||
    public FileConfiguration() {
 | 
			
		||||
        super();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an empty {@link FileConfiguration} using the specified {@link
 | 
			
		||||
     * Configuration} as a source for all default values.
 | 
			
		||||
     *
 | 
			
		||||
     * @param defaults Default value provider
 | 
			
		||||
     */
 | 
			
		||||
    public FileConfiguration(Configuration defaults) {
 | 
			
		||||
        super(defaults);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Saves this {@link FileConfiguration} to the specified location.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the file does not exist, it will be created. If already exists, it
 | 
			
		||||
     * will be overwritten. If it cannot be overwritten or created, an
 | 
			
		||||
     * exception will be thrown.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This method will save using the system default encoding, or possibly
 | 
			
		||||
     * using UTF8.
 | 
			
		||||
     *
 | 
			
		||||
     * @param file File to save to.
 | 
			
		||||
     * @throws IOException Thrown when the given file cannot be written to for
 | 
			
		||||
     *     any reason.
 | 
			
		||||
     * @throws IllegalArgumentException Thrown when file is null.
 | 
			
		||||
     */
 | 
			
		||||
    public void save(File file) throws IOException {
 | 
			
		||||
        if (file == null) throw new NullPointerException("File cannot be null");
 | 
			
		||||
        file.getParentFile().mkdirs();
 | 
			
		||||
 | 
			
		||||
        String data = saveToString();
 | 
			
		||||
 | 
			
		||||
        Writer writer = new OutputStreamWriter(new FileOutputStream(file), UTF8_OVERRIDE && !UTF_BIG ? StandardCharsets.UTF_8 : Charset.defaultCharset());
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            writer.write(data);
 | 
			
		||||
        } finally {
 | 
			
		||||
            writer.close();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Saves this {@link FileConfiguration} to the specified location.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the file does not exist, it will be created. If already exists, it
 | 
			
		||||
     * will be overwritten. If it cannot be overwritten or created, an
 | 
			
		||||
     * exception will be thrown.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This method will save using the system default encoding, or possibly
 | 
			
		||||
     * using UTF8.
 | 
			
		||||
     *
 | 
			
		||||
     * @param file File to save to.
 | 
			
		||||
     * @throws IOException Thrown when the given file cannot be written to for
 | 
			
		||||
     *     any reason.
 | 
			
		||||
     * @throws IllegalArgumentException Thrown when file is null.
 | 
			
		||||
     */
 | 
			
		||||
    public void save(String file) throws IOException {
 | 
			
		||||
        if (file == null) throw new NullPointerException("File cannot be null");
 | 
			
		||||
 | 
			
		||||
        save(new File(file));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Saves this {@link FileConfiguration} to a string, and returns it.
 | 
			
		||||
     *
 | 
			
		||||
     * @return String containing this configuration.
 | 
			
		||||
     */
 | 
			
		||||
    public abstract String saveToString();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Loads this {@link FileConfiguration} from the specified location.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * All the values contained within this configuration will be removed,
 | 
			
		||||
     * leaving only settings and defaults, and the new values will be loaded
 | 
			
		||||
     * from the given file.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the file cannot be loaded for any reason, an exception will be
 | 
			
		||||
     * thrown.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This will attempt to use the {@link Charset#defaultCharset()} for
 | 
			
		||||
     * files, unless {@link #UTF8_OVERRIDE} but not {@link #UTF_BIG} is
 | 
			
		||||
     * specified.
 | 
			
		||||
     *
 | 
			
		||||
     * @param file File to load from.
 | 
			
		||||
     * @throws FileNotFoundException Thrown when the given file cannot be
 | 
			
		||||
     *     opened.
 | 
			
		||||
     * @throws IOException Thrown when the given file cannot be read.
 | 
			
		||||
     * @throws InvalidConfigurationException Thrown when the given file is not
 | 
			
		||||
     *     a valid Configuration.
 | 
			
		||||
     * @throws IllegalArgumentException Thrown when file is null.
 | 
			
		||||
     */
 | 
			
		||||
    public void load(File file) throws FileNotFoundException, IOException, InvalidConfigurationException {
 | 
			
		||||
        if (file == null) throw new NullPointerException("File cannot be null");
 | 
			
		||||
 | 
			
		||||
        final FileInputStream stream = new FileInputStream(file);
 | 
			
		||||
 | 
			
		||||
        load(new InputStreamReader(stream, UTF8_OVERRIDE && !UTF_BIG ? StandardCharsets.UTF_8 : Charset.defaultCharset()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Loads this {@link FileConfiguration} from the specified stream.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * All the values contained within this configuration will be removed,
 | 
			
		||||
     * leaving only settings and defaults, and the new values will be loaded
 | 
			
		||||
     * from the given stream.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This will attempt to use the {@link Charset#defaultCharset()}, unless
 | 
			
		||||
     * {@link #UTF8_OVERRIDE} or {@link #UTF_BIG} is specified.
 | 
			
		||||
     *
 | 
			
		||||
     * @param stream Stream to load from
 | 
			
		||||
     * @throws IOException Thrown when the given file cannot be read.
 | 
			
		||||
     * @throws InvalidConfigurationException Thrown when the given file is not
 | 
			
		||||
     *     a valid Configuration.
 | 
			
		||||
     * @throws IllegalArgumentException Thrown when stream is null.
 | 
			
		||||
     * @deprecated This does not consider encoding
 | 
			
		||||
     * @see #load(Reader)
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public void load(InputStream stream) throws IOException, InvalidConfigurationException {
 | 
			
		||||
        if (stream == null) throw new NullPointerException("Stream cannot be null");
 | 
			
		||||
 | 
			
		||||
        load(new InputStreamReader(stream, UTF8_OVERRIDE ? StandardCharsets.UTF_8 : Charset.defaultCharset()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Loads this {@link FileConfiguration} from the specified reader.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * All the values contained within this configuration will be removed,
 | 
			
		||||
     * leaving only settings and defaults, and the new values will be loaded
 | 
			
		||||
     * from the given stream.
 | 
			
		||||
     *
 | 
			
		||||
     * @param reader the reader to load from
 | 
			
		||||
     * @throws IOException thrown when underlying reader throws an IOException
 | 
			
		||||
     * @throws InvalidConfigurationException thrown when the reader does not
 | 
			
		||||
     *      represent a valid Configuration
 | 
			
		||||
     * @throws IllegalArgumentException thrown when reader is null
 | 
			
		||||
     */
 | 
			
		||||
    public void load(Reader reader) throws IOException, InvalidConfigurationException {
 | 
			
		||||
        BufferedReader input = reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
 | 
			
		||||
 | 
			
		||||
        StringBuilder builder = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            String line;
 | 
			
		||||
 | 
			
		||||
            while ((line = input.readLine()) != null) {
 | 
			
		||||
                builder.append(line);
 | 
			
		||||
                builder.append('\n');
 | 
			
		||||
            }
 | 
			
		||||
        } finally {
 | 
			
		||||
            input.close();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        loadFromString(builder.toString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Loads this {@link FileConfiguration} from the specified location.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * All the values contained within this configuration will be removed,
 | 
			
		||||
     * leaving only settings and defaults, and the new values will be loaded
 | 
			
		||||
     * from the given file.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the file cannot be loaded for any reason, an exception will be
 | 
			
		||||
     * thrown.
 | 
			
		||||
     *
 | 
			
		||||
     * @param file File to load from.
 | 
			
		||||
     * @throws FileNotFoundException Thrown when the given file cannot be
 | 
			
		||||
     *     opened.
 | 
			
		||||
     * @throws IOException Thrown when the given file cannot be read.
 | 
			
		||||
     * @throws InvalidConfigurationException Thrown when the given file is not
 | 
			
		||||
     *     a valid Configuration.
 | 
			
		||||
     * @throws IllegalArgumentException Thrown when file is null.
 | 
			
		||||
     */
 | 
			
		||||
    public void load(String file) throws FileNotFoundException, IOException, InvalidConfigurationException {
 | 
			
		||||
        if (file == null) throw new NullPointerException("File cannot be null");
 | 
			
		||||
 | 
			
		||||
        load(new File(file));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Loads this {@link FileConfiguration} from the specified string, as
 | 
			
		||||
     * opposed to from file.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * All the values contained within this configuration will be removed,
 | 
			
		||||
     * leaving only settings and defaults, and the new values will be loaded
 | 
			
		||||
     * from the given string.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If the string is invalid in any way, an exception will be thrown.
 | 
			
		||||
     *
 | 
			
		||||
     * @param contents Contents of a Configuration to load.
 | 
			
		||||
     * @throws InvalidConfigurationException Thrown if the specified string is
 | 
			
		||||
     *     invalid.
 | 
			
		||||
     * @throws IllegalArgumentException Thrown if contents is null.
 | 
			
		||||
     */
 | 
			
		||||
    public abstract void loadFromString(String contents) throws InvalidConfigurationException;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Compiles the header for this {@link FileConfiguration} and returns the
 | 
			
		||||
     * result.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This will use the header from {@link #options()} -> {@link
 | 
			
		||||
     * FileConfigurationOptions#header()}, respecting the rules of {@link
 | 
			
		||||
     * FileConfigurationOptions#copyHeader()} if set.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Compiled header
 | 
			
		||||
     */
 | 
			
		||||
    protected abstract String buildHeader();
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileConfigurationOptions options() {
 | 
			
		||||
        if (options == null) {
 | 
			
		||||
            options = new FileConfigurationOptions(this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return (FileConfigurationOptions) options;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,119 @@
 | 
			
		||||
package com.intellectualcrafters.configuration.file;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.configuration.MemoryConfiguration;
 | 
			
		||||
import com.intellectualcrafters.configuration.MemoryConfigurationOptions;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Various settings for controlling the input and output of a {@link
 | 
			
		||||
 * FileConfiguration}
 | 
			
		||||
 */
 | 
			
		||||
public class FileConfigurationOptions extends MemoryConfigurationOptions {
 | 
			
		||||
    private String header = null;
 | 
			
		||||
    private boolean copyHeader = true;
 | 
			
		||||
 | 
			
		||||
    protected FileConfigurationOptions(MemoryConfiguration configuration) {
 | 
			
		||||
        super(configuration);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileConfiguration configuration() {
 | 
			
		||||
        return (FileConfiguration) super.configuration();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileConfigurationOptions copyDefaults(boolean value) {
 | 
			
		||||
        super.copyDefaults(value);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileConfigurationOptions pathSeparator(char value) {
 | 
			
		||||
        super.pathSeparator(value);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the header that will be applied to the top of the saved output.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This header will be commented out and applied directly at the top of
 | 
			
		||||
     * the generated output of the {@link FileConfiguration}. It is not
 | 
			
		||||
     * required to include a newline at the end of the header as it will
 | 
			
		||||
     * automatically be applied, but you may include one if you wish for extra
 | 
			
		||||
     * spacing.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Null is a valid value which will indicate that no header is to be
 | 
			
		||||
     * applied. The default value is null.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Header
 | 
			
		||||
     */
 | 
			
		||||
    public String header() {
 | 
			
		||||
        return header;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the header that will be applied to the top of the saved output.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This header will be commented out and applied directly at the top of
 | 
			
		||||
     * the generated output of the {@link FileConfiguration}. It is not
 | 
			
		||||
     * required to include a newline at the end of the header as it will
 | 
			
		||||
     * automatically be applied, but you may include one if you wish for extra
 | 
			
		||||
     * spacing.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Null is a valid value which will indicate that no header is to be
 | 
			
		||||
     * applied.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value New header
 | 
			
		||||
     * @return This object, for chaining
 | 
			
		||||
     */
 | 
			
		||||
    public FileConfigurationOptions header(String value) {
 | 
			
		||||
        this.header = value;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets whether or not the header should be copied from a default source.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If this is true, if a default {@link FileConfiguration} is passed to
 | 
			
		||||
     * {@link
 | 
			
		||||
     * FileConfiguration#setDefaults(com.intellectualcrafters.configuration.Configuration)}
 | 
			
		||||
     * then upon saving it will use the header from that config, instead of
 | 
			
		||||
     * the one provided here.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If no default is set on the configuration, or the default is not of
 | 
			
		||||
     * type FileConfiguration, or that config has no header ({@link #header()}
 | 
			
		||||
     * returns null) then the header specified in this configuration will be
 | 
			
		||||
     * used.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Defaults to true.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Whether or not to copy the header
 | 
			
		||||
     */
 | 
			
		||||
    public boolean copyHeader() {
 | 
			
		||||
        return copyHeader;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets whether or not the header should be copied from a default source.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If this is true, if a default {@link FileConfiguration} is passed to
 | 
			
		||||
     * {@link
 | 
			
		||||
     * FileConfiguration#setDefaults(com.intellectualcrafters.configuration.Configuration)}
 | 
			
		||||
     * then upon saving it will use the header from that config, instead of
 | 
			
		||||
     * the one provided here.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If no default is set on the configuration, or the default is not of
 | 
			
		||||
     * type FileConfiguration, or that config has no header ({@link #header()}
 | 
			
		||||
     * returns null) then the header specified in this configuration will be
 | 
			
		||||
     * used.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Defaults to true.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value Whether or not to copy the header
 | 
			
		||||
     * @return This object, for chaining
 | 
			
		||||
     */
 | 
			
		||||
    public FileConfigurationOptions copyHeader(boolean value) {
 | 
			
		||||
        copyHeader = value;
 | 
			
		||||
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,265 @@
 | 
			
		||||
package com.intellectualcrafters.configuration.file;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.Reader;
 | 
			
		||||
import java.nio.file.Files;
 | 
			
		||||
import java.nio.file.StandardCopyOption;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.yaml.snakeyaml.DumperOptions;
 | 
			
		||||
import org.yaml.snakeyaml.Yaml;
 | 
			
		||||
import org.yaml.snakeyaml.error.YAMLException;
 | 
			
		||||
import org.yaml.snakeyaml.representer.Representer;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.configuration.Configuration;
 | 
			
		||||
import com.intellectualcrafters.configuration.ConfigurationSection;
 | 
			
		||||
import com.intellectualcrafters.configuration.InvalidConfigurationException;
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An implementation of {@link Configuration} which saves all files in Yaml.
 | 
			
		||||
 * Note that this implementation is not synchronized.
 | 
			
		||||
 */
 | 
			
		||||
public class YamlConfiguration extends FileConfiguration {
 | 
			
		||||
    protected static final String COMMENT_PREFIX = "# ";
 | 
			
		||||
    protected static final String BLANK_CONFIG = "{}\n";
 | 
			
		||||
    private final DumperOptions yamlOptions = new DumperOptions();
 | 
			
		||||
    private final Representer yamlRepresenter = new YamlRepresenter();
 | 
			
		||||
    private final Yaml yaml = new Yaml(new YamlConstructor(), yamlRepresenter, yamlOptions);
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String saveToString() {
 | 
			
		||||
        yamlOptions.setIndent(options().indent());
 | 
			
		||||
        yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
 | 
			
		||||
        yamlOptions.setAllowUnicode(SYSTEM_UTF);
 | 
			
		||||
        yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
 | 
			
		||||
 | 
			
		||||
        String header = buildHeader();
 | 
			
		||||
        String dump = yaml.dump(getValues(false));
 | 
			
		||||
 | 
			
		||||
        if (dump.equals(BLANK_CONFIG)) {
 | 
			
		||||
            dump = "";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return header + dump;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void loadFromString(String contents) throws InvalidConfigurationException {
 | 
			
		||||
        if (contents == null) throw new NullPointerException("Contents cannot be null");
 | 
			
		||||
 | 
			
		||||
        Map<?, ?> input;
 | 
			
		||||
        try {
 | 
			
		||||
            input = (Map<?, ?>) yaml.load(contents);
 | 
			
		||||
        } catch (YAMLException e) {
 | 
			
		||||
            throw new InvalidConfigurationException(e);
 | 
			
		||||
        } catch (ClassCastException e) {
 | 
			
		||||
            throw new InvalidConfigurationException("Top level is not a Map.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String header = parseHeader(contents);
 | 
			
		||||
        if (header.length() > 0) {
 | 
			
		||||
            options().header(header);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (input != null) {
 | 
			
		||||
            convertMapsToSections(input, this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected void convertMapsToSections(Map<?, ?> input, ConfigurationSection section) {
 | 
			
		||||
        for (Map.Entry<?, ?> entry : input.entrySet()) {
 | 
			
		||||
            String key = entry.getKey().toString();
 | 
			
		||||
            Object value = entry.getValue();
 | 
			
		||||
 | 
			
		||||
            if (value instanceof Map) {
 | 
			
		||||
                convertMapsToSections((Map<?, ?>) value, section.createSection(key));
 | 
			
		||||
            } else {
 | 
			
		||||
                section.set(key, value);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected String parseHeader(String input) {
 | 
			
		||||
        String[] lines = input.split("\r?\n", -1);
 | 
			
		||||
        StringBuilder result = new StringBuilder();
 | 
			
		||||
        boolean readingHeader = true;
 | 
			
		||||
        boolean foundHeader = false;
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; (i < lines.length) && (readingHeader); i++) {
 | 
			
		||||
            String line = lines[i];
 | 
			
		||||
 | 
			
		||||
            if (line.startsWith(COMMENT_PREFIX)) {
 | 
			
		||||
                if (i > 0) {
 | 
			
		||||
                    result.append("\n");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (line.length() > COMMENT_PREFIX.length()) {
 | 
			
		||||
                    result.append(line.substring(COMMENT_PREFIX.length()));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                foundHeader = true;
 | 
			
		||||
            } else if ((foundHeader) && (line.length() == 0)) {
 | 
			
		||||
                result.append("\n");
 | 
			
		||||
            } else if (foundHeader) {
 | 
			
		||||
                readingHeader = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected String buildHeader() {
 | 
			
		||||
        String header = options().header();
 | 
			
		||||
 | 
			
		||||
        if (options().copyHeader()) {
 | 
			
		||||
            Configuration def = getDefaults();
 | 
			
		||||
 | 
			
		||||
            if ((def != null) && (def instanceof FileConfiguration)) {
 | 
			
		||||
                FileConfiguration filedefaults = (FileConfiguration) def;
 | 
			
		||||
                String defaultsHeader = filedefaults.buildHeader();
 | 
			
		||||
 | 
			
		||||
                if ((defaultsHeader != null) && (defaultsHeader.length() > 0)) {
 | 
			
		||||
                    return defaultsHeader;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (header == null) {
 | 
			
		||||
            return "";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        StringBuilder builder = new StringBuilder();
 | 
			
		||||
        String[] lines = header.split("\r?\n", -1);
 | 
			
		||||
        boolean startedHeader = false;
 | 
			
		||||
 | 
			
		||||
        for (int i = lines.length - 1; i >= 0; i--) {
 | 
			
		||||
            builder.insert(0, "\n");
 | 
			
		||||
 | 
			
		||||
            if ((startedHeader) || (lines[i].length() != 0)) {
 | 
			
		||||
                builder.insert(0, lines[i]);
 | 
			
		||||
                builder.insert(0, COMMENT_PREFIX);
 | 
			
		||||
                startedHeader = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return builder.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public YamlConfigurationOptions options() {
 | 
			
		||||
        if (options == null) {
 | 
			
		||||
            options = new YamlConfigurationOptions(this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return (YamlConfigurationOptions) options;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new {@link YamlConfiguration}, loading from the given file.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Any errors loading the Configuration will be logged and then ignored.
 | 
			
		||||
     * If the specified input is not a valid config, a blank config will be
 | 
			
		||||
     * returned.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * The encoding used may follow the system dependent default.
 | 
			
		||||
     *
 | 
			
		||||
     * @param file Input file
 | 
			
		||||
     * @return Resulting configuration
 | 
			
		||||
     * @throws IllegalArgumentException Thrown if file is null
 | 
			
		||||
     */
 | 
			
		||||
    public static YamlConfiguration loadConfiguration(File file) {
 | 
			
		||||
        if (file == null) throw new NullPointerException("File cannot be null");
 | 
			
		||||
 | 
			
		||||
        YamlConfiguration config = new YamlConfiguration();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            config.load(file);
 | 
			
		||||
        } catch (Exception ex) {
 | 
			
		||||
            try {
 | 
			
		||||
                String path = file.getAbsolutePath() + "_broken";
 | 
			
		||||
                File dest = new File(file.getAbsolutePath() + "_broken");
 | 
			
		||||
                int i = 0;
 | 
			
		||||
                while (dest.exists()) {
 | 
			
		||||
                    dest = new File(file.getAbsolutePath() + "_broken_" + i++);
 | 
			
		||||
                }
 | 
			
		||||
                Files.copy( file.toPath(), dest.toPath() , StandardCopyOption.REPLACE_EXISTING);
 | 
			
		||||
                PS.log("&dCould not read: &7" + file);
 | 
			
		||||
                PS.log("&drenamed to: &7" + dest.getName());
 | 
			
		||||
                PS.log("&c============ Full stacktrace ============");
 | 
			
		||||
                ex.printStackTrace();
 | 
			
		||||
                PS.log("&c=========================================");
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return config;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new {@link YamlConfiguration}, loading from the given stream.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Any errors loading the Configuration will be logged and then ignored.
 | 
			
		||||
     * If the specified input is not a valid config, a blank config will be
 | 
			
		||||
     * returned.
 | 
			
		||||
     *
 | 
			
		||||
     * @param stream Input stream
 | 
			
		||||
     * @return Resulting configuration
 | 
			
		||||
     * @throws IllegalArgumentException Thrown if stream is null
 | 
			
		||||
     * @deprecated does not properly consider encoding
 | 
			
		||||
     * @see #load(InputStream)
 | 
			
		||||
     * @see #loadConfiguration(Reader)
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public static YamlConfiguration loadConfiguration(InputStream stream) {
 | 
			
		||||
        if (stream == null) throw new NullPointerException("Stream cannot be null");
 | 
			
		||||
 | 
			
		||||
        YamlConfiguration config = new YamlConfiguration();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            config.load(stream);
 | 
			
		||||
        } catch (IOException ex) {
 | 
			
		||||
            PS.log("Cannot load configuration from stream");
 | 
			
		||||
            ex.printStackTrace();
 | 
			
		||||
        } catch (InvalidConfigurationException ex) {
 | 
			
		||||
            ex.printStackTrace();
 | 
			
		||||
            PS.log("Cannot load configuration from stream");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return config;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new {@link YamlConfiguration}, loading from the given reader.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Any errors loading the Configuration will be logged and then ignored.
 | 
			
		||||
     * If the specified input is not a valid config, a blank config will be
 | 
			
		||||
     * returned.
 | 
			
		||||
     *
 | 
			
		||||
     * @param reader input
 | 
			
		||||
     * @return resulting configuration
 | 
			
		||||
     * @throws IllegalArgumentException Thrown if stream is null
 | 
			
		||||
     */
 | 
			
		||||
    public static YamlConfiguration loadConfiguration(Reader reader) {
 | 
			
		||||
        if (reader == null) throw new NullPointerException("Reader cannot be null");
 | 
			
		||||
 | 
			
		||||
        YamlConfiguration config = new YamlConfiguration();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            config.load(reader);
 | 
			
		||||
        } catch (IOException ex) {
 | 
			
		||||
            PS.log("Cannot load configuration from stream");
 | 
			
		||||
            ex.printStackTrace();
 | 
			
		||||
        } catch (InvalidConfigurationException ex) {
 | 
			
		||||
            PS.log("Cannot load configuration from stream");
 | 
			
		||||
            ex.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return config;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,69 @@
 | 
			
		||||
package com.intellectualcrafters.configuration.file;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Various settings for controlling the input and output of a {@link
 | 
			
		||||
 * YamlConfiguration}
 | 
			
		||||
 */
 | 
			
		||||
public class YamlConfigurationOptions extends FileConfigurationOptions {
 | 
			
		||||
    private int indent = 2;
 | 
			
		||||
 | 
			
		||||
    protected YamlConfigurationOptions(YamlConfiguration configuration) {
 | 
			
		||||
        super(configuration);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public YamlConfiguration configuration() {
 | 
			
		||||
        return (YamlConfiguration) super.configuration();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public YamlConfigurationOptions copyDefaults(boolean value) {
 | 
			
		||||
        super.copyDefaults(value);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public YamlConfigurationOptions pathSeparator(char value) {
 | 
			
		||||
        super.pathSeparator(value);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public YamlConfigurationOptions header(String value) {
 | 
			
		||||
        super.header(value);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public YamlConfigurationOptions copyHeader(boolean value) {
 | 
			
		||||
        super.copyHeader(value);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets how much spaces should be used to indent each line.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * The minimum value this may be is 2, and the maximum is 9.
 | 
			
		||||
     *
 | 
			
		||||
     * @return How much to indent by
 | 
			
		||||
     */
 | 
			
		||||
    public int indent() {
 | 
			
		||||
        return indent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets how much spaces should be used to indent each line.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * The minimum value this may be is 2, and the maximum is 9.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value New indent
 | 
			
		||||
     * @return This object, for chaining
 | 
			
		||||
     */
 | 
			
		||||
    public YamlConfigurationOptions indent(int value) {
 | 
			
		||||
        if (value < 2) throw new IllegalArgumentException("Indent must be at least 2 characters");
 | 
			
		||||
        if (value > 9) throw new IllegalArgumentException("Indent cannot be greater than 9 characters");
 | 
			
		||||
 | 
			
		||||
        this.indent = value;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,49 @@
 | 
			
		||||
package com.intellectualcrafters.configuration.file;
 | 
			
		||||
 | 
			
		||||
import java.util.LinkedHashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
 | 
			
		||||
import org.yaml.snakeyaml.error.YAMLException;
 | 
			
		||||
import org.yaml.snakeyaml.nodes.Node;
 | 
			
		||||
import org.yaml.snakeyaml.nodes.Tag;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.configuration.serialization.ConfigurationSerialization;
 | 
			
		||||
 | 
			
		||||
public class YamlConstructor extends SafeConstructor {
 | 
			
		||||
 | 
			
		||||
    public YamlConstructor() {
 | 
			
		||||
        this.yamlConstructors.put(Tag.MAP, new ConstructCustomObject());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private class ConstructCustomObject extends ConstructYamlMap {
 | 
			
		||||
        @Override
 | 
			
		||||
        public Object construct(Node node) {
 | 
			
		||||
            if (node.isTwoStepsConstruction()) {
 | 
			
		||||
                throw new YAMLException("Unexpected referential mapping structure. Node: " + node);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Map<?, ?> raw = (Map<?, ?>) super.construct(node);
 | 
			
		||||
 | 
			
		||||
            if (raw.containsKey(ConfigurationSerialization.SERIALIZED_TYPE_KEY)) {
 | 
			
		||||
                Map<String, Object> typed = new LinkedHashMap<String, Object>(raw.size());
 | 
			
		||||
                for (Map.Entry<?, ?> entry : raw.entrySet()) {
 | 
			
		||||
                    typed.put(entry.getKey().toString(), entry.getValue());
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                try {
 | 
			
		||||
                    return ConfigurationSerialization.deserializeObject(typed);
 | 
			
		||||
                } catch (IllegalArgumentException ex) {
 | 
			
		||||
                    throw new YAMLException("Could not deserialize object", ex);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return raw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void construct2ndStep(Node node, Object object) {
 | 
			
		||||
            throw new YAMLException("Unexpected referential mapping structure. Node: " + node);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,38 @@
 | 
			
		||||
package com.intellectualcrafters.configuration.file;
 | 
			
		||||
 | 
			
		||||
import java.util.LinkedHashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.yaml.snakeyaml.nodes.Node;
 | 
			
		||||
import org.yaml.snakeyaml.representer.Representer;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.configuration.ConfigurationSection;
 | 
			
		||||
import com.intellectualcrafters.configuration.serialization.ConfigurationSerializable;
 | 
			
		||||
import com.intellectualcrafters.configuration.serialization.ConfigurationSerialization;
 | 
			
		||||
 | 
			
		||||
public class YamlRepresenter extends Representer {
 | 
			
		||||
 | 
			
		||||
    public YamlRepresenter() {
 | 
			
		||||
        this.multiRepresenters.put(ConfigurationSection.class, new RepresentConfigurationSection());
 | 
			
		||||
        this.multiRepresenters.put(ConfigurationSerializable.class, new RepresentConfigurationSerializable());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private class RepresentConfigurationSection extends RepresentMap {
 | 
			
		||||
        @Override
 | 
			
		||||
        public Node representData(Object data) {
 | 
			
		||||
            return super.representData(((ConfigurationSection) data).getValues(false));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private class RepresentConfigurationSerializable extends RepresentMap {
 | 
			
		||||
        @Override
 | 
			
		||||
        public Node representData(Object data) {
 | 
			
		||||
            ConfigurationSerializable serializable = (ConfigurationSerializable) data;
 | 
			
		||||
            Map<String, Object> values = new LinkedHashMap<String, Object>();
 | 
			
		||||
            values.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, ConfigurationSerialization.getAlias(serializable.getClass()));
 | 
			
		||||
            values.putAll(serializable.serialize());
 | 
			
		||||
 | 
			
		||||
            return super.representData(values);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,35 @@
 | 
			
		||||
package com.intellectualcrafters.configuration.serialization;
 | 
			
		||||
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents an object that may be serialized.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * These objects MUST implement one of the following, in addition to the
 | 
			
		||||
 * methods as defined by this interface:
 | 
			
		||||
 * <ul>
 | 
			
		||||
 * <li>A static method "deserialize" that accepts a single {@link Map}<
 | 
			
		||||
 * {@link String}, {@link Object}> and returns the class.</li>
 | 
			
		||||
 * <li>A static method "valueOf" that accepts a single {@link Map}<{@link
 | 
			
		||||
 * String}, {@link Object}> and returns the class.</li>
 | 
			
		||||
 * <li>A constructor that accepts a single {@link Map}<{@link String},
 | 
			
		||||
 * {@link Object}>.</li>
 | 
			
		||||
 * </ul>
 | 
			
		||||
 * In addition to implementing this interface, you must register the class
 | 
			
		||||
 * with {@link ConfigurationSerialization#registerClass(Class)}.
 | 
			
		||||
 *
 | 
			
		||||
 * @see DelegateDeserialization
 | 
			
		||||
 * @see SerializableAs
 | 
			
		||||
 */
 | 
			
		||||
public interface ConfigurationSerializable {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a Map representation of this class.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This class must provide a method to restore this class, as defined in
 | 
			
		||||
     * the {@link ConfigurationSerializable} interface javadocs.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Map containing the current state of this class
 | 
			
		||||
     */
 | 
			
		||||
    public Map<String, Object> serialize();
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,266 @@
 | 
			
		||||
package com.intellectualcrafters.configuration.serialization;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Constructor;
 | 
			
		||||
import java.lang.reflect.InvocationTargetException;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.lang.reflect.Modifier;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.logging.Level;
 | 
			
		||||
import java.util.logging.Logger;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.configuration.Configuration;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Utility class for storing and retrieving classes for {@link Configuration}.
 | 
			
		||||
 */
 | 
			
		||||
public class ConfigurationSerialization {
 | 
			
		||||
    public static final String SERIALIZED_TYPE_KEY = "==";
 | 
			
		||||
    private final Class<? extends ConfigurationSerializable> clazz;
 | 
			
		||||
    private static Map<String, Class<? extends ConfigurationSerializable>> aliases = new HashMap<String, Class<? extends ConfigurationSerializable>>();
 | 
			
		||||
 | 
			
		||||
    protected ConfigurationSerialization(Class<? extends ConfigurationSerializable> clazz) {
 | 
			
		||||
        this.clazz = clazz;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected Method getMethod(String name, boolean isStatic) {
 | 
			
		||||
        try {
 | 
			
		||||
            Method method = clazz.getDeclaredMethod(name, Map.class);
 | 
			
		||||
 | 
			
		||||
            if (!ConfigurationSerializable.class.isAssignableFrom(method.getReturnType())) {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
            if (Modifier.isStatic(method.getModifiers()) != isStatic) {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return method;
 | 
			
		||||
        } catch (NoSuchMethodException ex) {
 | 
			
		||||
            return null;
 | 
			
		||||
        } catch (SecurityException ex) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected Constructor<? extends ConfigurationSerializable> getConstructor() {
 | 
			
		||||
        try {
 | 
			
		||||
            return clazz.getConstructor(Map.class);
 | 
			
		||||
        } catch (NoSuchMethodException ex) {
 | 
			
		||||
            return null;
 | 
			
		||||
        } catch (SecurityException ex) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected ConfigurationSerializable deserializeViaMethod(Method method, Map<String, ?> args) {
 | 
			
		||||
        try {
 | 
			
		||||
            ConfigurationSerializable result = (ConfigurationSerializable) method.invoke(null, args);
 | 
			
		||||
 | 
			
		||||
            if (result == null) {
 | 
			
		||||
                Logger.getLogger(ConfigurationSerialization.class.getName()).log(Level.SEVERE, "Could not call method '" + method.toString() + "' of " + clazz + " for deserialization: method returned null");
 | 
			
		||||
            } else {
 | 
			
		||||
                return result;
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Throwable ex) {
 | 
			
		||||
            Logger.getLogger(ConfigurationSerialization.class.getName()).log(
 | 
			
		||||
                    Level.SEVERE,
 | 
			
		||||
                    "Could not call method '" + method.toString() + "' of " + clazz + " for deserialization",
 | 
			
		||||
                    ex instanceof InvocationTargetException ? ex.getCause() : ex);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected ConfigurationSerializable deserializeViaCtor(Constructor<? extends ConfigurationSerializable> ctor, Map<String, ?> args) {
 | 
			
		||||
        try {
 | 
			
		||||
            return ctor.newInstance(args);
 | 
			
		||||
        } catch (Throwable ex) {
 | 
			
		||||
            Logger.getLogger(ConfigurationSerialization.class.getName()).log(
 | 
			
		||||
                    Level.SEVERE,
 | 
			
		||||
                    "Could not call constructor '" + ctor.toString() + "' of " + clazz + " for deserialization",
 | 
			
		||||
                    ex instanceof InvocationTargetException ? ex.getCause() : ex);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ConfigurationSerializable deserialize(Map<String, ?> args) {
 | 
			
		||||
        if (args == null) {
 | 
			
		||||
            throw new NullPointerException("Args must not be null");
 | 
			
		||||
        }
 | 
			
		||||
        ConfigurationSerializable result = null;
 | 
			
		||||
        Method method = null;
 | 
			
		||||
 | 
			
		||||
        if (result == null) {
 | 
			
		||||
            method = getMethod("deserialize", true);
 | 
			
		||||
 | 
			
		||||
            if (method != null) {
 | 
			
		||||
                result = deserializeViaMethod(method, args);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (result == null) {
 | 
			
		||||
            method = getMethod("valueOf", true);
 | 
			
		||||
 | 
			
		||||
            if (method != null) {
 | 
			
		||||
                result = deserializeViaMethod(method, args);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (result == null) {
 | 
			
		||||
            Constructor<? extends ConfigurationSerializable> constructor = getConstructor();
 | 
			
		||||
 | 
			
		||||
            if (constructor != null) {
 | 
			
		||||
                result = deserializeViaCtor(constructor, args);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Attempts to deserialize the given arguments into a new instance of the
 | 
			
		||||
     * given class.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * The class must implement {@link ConfigurationSerializable}, including
 | 
			
		||||
     * the extra methods as specified in the javadoc of
 | 
			
		||||
     * ConfigurationSerializable.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If a new instance could not be made, an example being the class not
 | 
			
		||||
     * fully implementing the interface, null will be returned.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args Arguments for deserialization
 | 
			
		||||
     * @param clazz Class to deserialize into
 | 
			
		||||
     * @return New instance of the specified class
 | 
			
		||||
     */
 | 
			
		||||
    public static ConfigurationSerializable deserializeObject(Map<String, ?> args, Class<? extends ConfigurationSerializable> clazz) {
 | 
			
		||||
        return new ConfigurationSerialization(clazz).deserialize(args);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Attempts to deserialize the given arguments into a new instance of the
 | 
			
		||||
     * given class.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * The class must implement {@link ConfigurationSerializable}, including
 | 
			
		||||
     * the extra methods as specified in the javadoc of
 | 
			
		||||
     * ConfigurationSerializable.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * If a new instance could not be made, an example being the class not
 | 
			
		||||
     * fully implementing the interface, null will be returned.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args Arguments for deserialization
 | 
			
		||||
     * @return New instance of the specified class
 | 
			
		||||
     */
 | 
			
		||||
    public static ConfigurationSerializable deserializeObject(Map<String, ?> args) {
 | 
			
		||||
        Class<? extends ConfigurationSerializable> clazz = null;
 | 
			
		||||
 | 
			
		||||
        if (args.containsKey(SERIALIZED_TYPE_KEY)) {
 | 
			
		||||
            try {
 | 
			
		||||
                String alias = (String) args.get(SERIALIZED_TYPE_KEY);
 | 
			
		||||
 | 
			
		||||
                if (alias == null) {
 | 
			
		||||
                    throw new IllegalArgumentException("Cannot have null alias");
 | 
			
		||||
                }
 | 
			
		||||
                clazz = getClassByAlias(alias);
 | 
			
		||||
                if (clazz == null) {
 | 
			
		||||
                    throw new IllegalArgumentException("Specified class does not exist ('" + alias + "')");
 | 
			
		||||
                }
 | 
			
		||||
            } catch (ClassCastException ex) {
 | 
			
		||||
                ex.fillInStackTrace();
 | 
			
		||||
                throw ex;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new IllegalArgumentException("Args doesn't contain type key ('" + SERIALIZED_TYPE_KEY + "')");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new ConfigurationSerialization(clazz).deserialize(args);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Registers the given {@link ConfigurationSerializable} class by its
 | 
			
		||||
     * alias
 | 
			
		||||
     *
 | 
			
		||||
     * @param clazz Class to register
 | 
			
		||||
     */
 | 
			
		||||
    public static void registerClass(Class<? extends ConfigurationSerializable> clazz) {
 | 
			
		||||
        DelegateDeserialization delegate = clazz.getAnnotation(DelegateDeserialization.class);
 | 
			
		||||
 | 
			
		||||
        if (delegate == null) {
 | 
			
		||||
            registerClass(clazz, getAlias(clazz));
 | 
			
		||||
            registerClass(clazz, clazz.getName());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Registers the given alias to the specified {@link
 | 
			
		||||
     * ConfigurationSerializable} class
 | 
			
		||||
     *
 | 
			
		||||
     * @param clazz Class to register
 | 
			
		||||
     * @param alias Alias to register as
 | 
			
		||||
     * @see SerializableAs
 | 
			
		||||
     */
 | 
			
		||||
    public static void registerClass(Class<? extends ConfigurationSerializable> clazz, String alias) {
 | 
			
		||||
        aliases.put(alias, clazz);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Unregisters the specified alias to a {@link ConfigurationSerializable}
 | 
			
		||||
     *
 | 
			
		||||
     * @param alias Alias to unregister
 | 
			
		||||
     */
 | 
			
		||||
    public static void unregisterClass(String alias) {
 | 
			
		||||
        aliases.remove(alias);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Unregisters any aliases for the specified {@link
 | 
			
		||||
     * ConfigurationSerializable} class
 | 
			
		||||
     *
 | 
			
		||||
     * @param clazz Class to unregister
 | 
			
		||||
     */
 | 
			
		||||
    public static void unregisterClass(Class<? extends ConfigurationSerializable> clazz) {
 | 
			
		||||
        while (aliases.values().remove(clazz)) {
 | 
			
		||||
            ;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Attempts to get a registered {@link ConfigurationSerializable} class by
 | 
			
		||||
     * its alias
 | 
			
		||||
     *
 | 
			
		||||
     * @param alias Alias of the serializable
 | 
			
		||||
     * @return Registered class, or null if not found
 | 
			
		||||
     */
 | 
			
		||||
    public static Class<? extends ConfigurationSerializable> getClassByAlias(String alias) {
 | 
			
		||||
        return aliases.get(alias);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the correct alias for the given {@link ConfigurationSerializable}
 | 
			
		||||
     * class
 | 
			
		||||
     *
 | 
			
		||||
     * @param clazz Class to get alias for
 | 
			
		||||
     * @return Alias to use for the class
 | 
			
		||||
     */
 | 
			
		||||
    public static String getAlias(Class<? extends ConfigurationSerializable> clazz) {
 | 
			
		||||
        DelegateDeserialization delegate = clazz.getAnnotation(DelegateDeserialization.class);
 | 
			
		||||
 | 
			
		||||
        if (delegate != null) {
 | 
			
		||||
            if ((delegate.value() == null) || (delegate.value() == clazz)) {
 | 
			
		||||
                delegate = null;
 | 
			
		||||
            } else {
 | 
			
		||||
                return getAlias(delegate.value());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (delegate == null) {
 | 
			
		||||
            SerializableAs alias = clazz.getAnnotation(SerializableAs.class);
 | 
			
		||||
 | 
			
		||||
            if ((alias != null) && (alias.value() != null)) {
 | 
			
		||||
                return alias.value();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return clazz.getName();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,22 @@
 | 
			
		||||
package com.intellectualcrafters.configuration.serialization;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.ElementType;
 | 
			
		||||
import java.lang.annotation.Retention;
 | 
			
		||||
import java.lang.annotation.RetentionPolicy;
 | 
			
		||||
import java.lang.annotation.Target;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Applies to a {@link ConfigurationSerializable} that will delegate all
 | 
			
		||||
 * deserialization to another {@link ConfigurationSerializable}.
 | 
			
		||||
 */
 | 
			
		||||
@Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
@Target(ElementType.TYPE)
 | 
			
		||||
public @interface DelegateDeserialization {
 | 
			
		||||
    /**
 | 
			
		||||
     * Which class should be used as a delegate for this classes
 | 
			
		||||
     * deserialization
 | 
			
		||||
     *
 | 
			
		||||
     * @return Delegate class
 | 
			
		||||
     */
 | 
			
		||||
    public Class<? extends ConfigurationSerializable> value();
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,34 @@
 | 
			
		||||
package com.intellectualcrafters.configuration.serialization;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.ElementType;
 | 
			
		||||
import java.lang.annotation.Retention;
 | 
			
		||||
import java.lang.annotation.RetentionPolicy;
 | 
			
		||||
import java.lang.annotation.Target;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents an "alias" that a {@link ConfigurationSerializable} may be
 | 
			
		||||
 * stored as.
 | 
			
		||||
 * If this is not present on a {@link ConfigurationSerializable} class, it
 | 
			
		||||
 * will use the fully qualified name of the class.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This value will be stored in the configuration so that the configuration
 | 
			
		||||
 * deserialization can determine what type it is.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Using this annotation on any other class than a {@link
 | 
			
		||||
 * ConfigurationSerializable} will have no effect.
 | 
			
		||||
 *
 | 
			
		||||
 * @see ConfigurationSerialization#registerClass(Class, String)
 | 
			
		||||
 */
 | 
			
		||||
@Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
@Target(ElementType.TYPE)
 | 
			
		||||
public @interface SerializableAs {
 | 
			
		||||
    /**
 | 
			
		||||
     * This is the name your class will be stored and retrieved as.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * This name MUST be unique. We recommend using names such as
 | 
			
		||||
     * "MyPluginThing" instead of "Thing".
 | 
			
		||||
     *
 | 
			
		||||
     * @return Name to serialize the class as.
 | 
			
		||||
     */
 | 
			
		||||
    public String value();
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,52 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The {@code TAG_Byte_Array} tag.
 | 
			
		||||
 */
 | 
			
		||||
public final class ByteArrayTag extends Tag {
 | 
			
		||||
    private final byte[] value;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag with an empty name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public ByteArrayTag(final byte[] value) {
 | 
			
		||||
        super();
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name  the name of the tag
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public ByteArrayTag(final String name, final byte[] value) {
 | 
			
		||||
        super(name);
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public byte[] getValue() {
 | 
			
		||||
        return this.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        final StringBuilder hex = new StringBuilder();
 | 
			
		||||
        for (final byte b : this.value) {
 | 
			
		||||
            final String hexDigits = Integer.toHexString(b).toUpperCase();
 | 
			
		||||
            if (hexDigits.length() == 1) {
 | 
			
		||||
                hex.append("0");
 | 
			
		||||
            }
 | 
			
		||||
            hex.append(hexDigits).append(" ");
 | 
			
		||||
        }
 | 
			
		||||
        final String name = getName();
 | 
			
		||||
        String append = "";
 | 
			
		||||
        if ((name != null) && !name.equals("")) {
 | 
			
		||||
            append = "(\"" + this.getName() + "\")";
 | 
			
		||||
        }
 | 
			
		||||
        return "TAG_Byte_Array" + append + ": " + hex;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								src/main/java/com/intellectualcrafters/jnbt/ByteTag.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/main/java/com/intellectualcrafters/jnbt/ByteTag.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The {@code TAG_Byte} tag.
 | 
			
		||||
 */
 | 
			
		||||
public final class ByteTag extends Tag {
 | 
			
		||||
    private final byte value;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag with an empty name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public ByteTag(final byte value) {
 | 
			
		||||
        super();
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name  the name of the tag
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public ByteTag(final String name, final byte value) {
 | 
			
		||||
        super(name);
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Byte getValue() {
 | 
			
		||||
        return this.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        final String name = getName();
 | 
			
		||||
        String append = "";
 | 
			
		||||
        if ((name != null) && !name.equals("")) {
 | 
			
		||||
            append = "(\"" + this.getName() + "\")";
 | 
			
		||||
        }
 | 
			
		||||
        return "TAG_Byte" + append + ": " + this.value;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										380
									
								
								src/main/java/com/intellectualcrafters/jnbt/CompoundTag.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										380
									
								
								src/main/java/com/intellectualcrafters/jnbt/CompoundTag.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,380 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The {@code TAG_Compound} tag.
 | 
			
		||||
 */
 | 
			
		||||
public final class CompoundTag extends Tag {
 | 
			
		||||
    private final Map<String, Tag> value;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag with an empty name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTag(final Map<String, Tag> value) {
 | 
			
		||||
        super();
 | 
			
		||||
        this.value = Collections.unmodifiableMap(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name  the name of the tag
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTag(final String name, final Map<String, Tag> value) {
 | 
			
		||||
        super(name);
 | 
			
		||||
        this.value = Collections.unmodifiableMap(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns whether this compound tag contains the given key.
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the given key
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if the tag contains the given key
 | 
			
		||||
     */
 | 
			
		||||
    public boolean containsKey(final String key) {
 | 
			
		||||
        return this.value.containsKey(key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Map<String, Tag> getValue() {
 | 
			
		||||
        return this.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Return a new compound tag with the given values.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value the value
 | 
			
		||||
     *
 | 
			
		||||
     * @return the new compound tag
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTag setValue(final Map<String, Tag> value) {
 | 
			
		||||
        return new CompoundTag(getName(), value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a compound tag builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the builder
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTagBuilder createBuilder() {
 | 
			
		||||
        return new CompoundTagBuilder(new HashMap<String, Tag>(this.value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a byte array named with the given key. <p> If the key does not exist or its value is not a byte array
 | 
			
		||||
     * tag, then an empty byte array will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the key
 | 
			
		||||
     *
 | 
			
		||||
     * @return a byte array
 | 
			
		||||
     */
 | 
			
		||||
    public byte[] getByteArray(final String key) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof ByteArrayTag) {
 | 
			
		||||
            return ((ByteArrayTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return new byte[0];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a byte named with the given key.  <p> If the key does not exist or its value is not a byte tag, then
 | 
			
		||||
     * {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the key
 | 
			
		||||
     *
 | 
			
		||||
     * @return a byte
 | 
			
		||||
     */
 | 
			
		||||
    public byte getByte(final String key) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof ByteTag) {
 | 
			
		||||
            return ((ByteTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return (byte) 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a double named with the given key. <p> If the key does not exist or its value is not a double tag, then
 | 
			
		||||
     * {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the key
 | 
			
		||||
     *
 | 
			
		||||
     * @return a double
 | 
			
		||||
     */
 | 
			
		||||
    public double getDouble(final String key) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof DoubleTag) {
 | 
			
		||||
            return ((DoubleTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a double named with the given key, even if it's another type of number. <p> If the key does not exist or
 | 
			
		||||
     * its value is not a number, then {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the key
 | 
			
		||||
     *
 | 
			
		||||
     * @return a double
 | 
			
		||||
     */
 | 
			
		||||
    public double asDouble(final String key) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof ByteTag) {
 | 
			
		||||
            return ((ByteTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof ShortTag) {
 | 
			
		||||
            return ((ShortTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof IntTag) {
 | 
			
		||||
            return ((IntTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof LongTag) {
 | 
			
		||||
            return ((LongTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof FloatTag) {
 | 
			
		||||
            return ((FloatTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof DoubleTag) {
 | 
			
		||||
            return ((DoubleTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a float named with the given key.  <p> If the key does not exist or its value is not a float tag, then
 | 
			
		||||
     * {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the key
 | 
			
		||||
     *
 | 
			
		||||
     * @return a float
 | 
			
		||||
     */
 | 
			
		||||
    public float getFloat(final String key) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof FloatTag) {
 | 
			
		||||
            return ((FloatTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a {@code int[]} named with the given key.  <p> If the key does not exist or its value is not an int array
 | 
			
		||||
     * tag, then an empty array will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the key
 | 
			
		||||
     *
 | 
			
		||||
     * @return an int array
 | 
			
		||||
     */
 | 
			
		||||
    public int[] getIntArray(final String key) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof IntArrayTag) {
 | 
			
		||||
            return ((IntArrayTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return new int[0];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an int named with the given key.  <p> If the key does not exist or its value is not an int tag, then
 | 
			
		||||
     * {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the key
 | 
			
		||||
     *
 | 
			
		||||
     * @return an int
 | 
			
		||||
     */
 | 
			
		||||
    public int getInt(final String key) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof IntTag) {
 | 
			
		||||
            return ((IntTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an int named with the given key, even if it's another type of number.  <p> If the key does not exist or
 | 
			
		||||
     * its value is not a number, then {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the key
 | 
			
		||||
     *
 | 
			
		||||
     * @return an int
 | 
			
		||||
     */
 | 
			
		||||
    public int asInt(final String key) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof ByteTag) {
 | 
			
		||||
            return ((ByteTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof ShortTag) {
 | 
			
		||||
            return ((ShortTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof IntTag) {
 | 
			
		||||
            return ((IntTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof LongTag) {
 | 
			
		||||
            return ((LongTag) tag).getValue().intValue();
 | 
			
		||||
        } else if (tag instanceof FloatTag) {
 | 
			
		||||
            return ((FloatTag) tag).getValue().intValue();
 | 
			
		||||
        } else if (tag instanceof DoubleTag) {
 | 
			
		||||
            return ((DoubleTag) tag).getValue().intValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a list of tags named with the given key.  <p> If the key does not exist or its value is not a list tag,
 | 
			
		||||
     * then an empty list will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the key
 | 
			
		||||
     *
 | 
			
		||||
     * @return a list of tags
 | 
			
		||||
     */
 | 
			
		||||
    public List<Tag> getList(final String key) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof ListTag) {
 | 
			
		||||
            return ((ListTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return Collections.emptyList();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a {@code TagList} named with the given key.  <p> If the key does not exist or its value is not a list
 | 
			
		||||
     * tag, then an empty tag list will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the key
 | 
			
		||||
     *
 | 
			
		||||
     * @return a tag list instance
 | 
			
		||||
     */
 | 
			
		||||
    public ListTag getListTag(final String key) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof ListTag) {
 | 
			
		||||
            return (ListTag) tag;
 | 
			
		||||
        } else {
 | 
			
		||||
            return new ListTag(key, StringTag.class, Collections.<Tag> emptyList());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a list of tags named with the given key.  <p> If the key does not exist or its value is not a list tag,
 | 
			
		||||
     * then an empty list will be returned. If the given key references a list but the list of of a different type, then
 | 
			
		||||
     * an empty list will also be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key      the key
 | 
			
		||||
     * @param listType the class of the contained type
 | 
			
		||||
     * @param <T>      the type of list
 | 
			
		||||
     *
 | 
			
		||||
     * @return a list of tags
 | 
			
		||||
     */
 | 
			
		||||
    @SuppressWarnings("unchecked")
 | 
			
		||||
    public <T extends Tag> List<T> getList(final String key, final Class<T> listType) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof ListTag) {
 | 
			
		||||
            final ListTag listTag = (ListTag) tag;
 | 
			
		||||
            if (listTag.getType().equals(listType)) {
 | 
			
		||||
                return (List<T>) listTag.getValue();
 | 
			
		||||
            } else {
 | 
			
		||||
                return Collections.emptyList();
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            return Collections.emptyList();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a long named with the given key.  <p> If the key does not exist or its value is not a long tag, then
 | 
			
		||||
     * {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the key
 | 
			
		||||
     *
 | 
			
		||||
     * @return a long
 | 
			
		||||
     */
 | 
			
		||||
    public long getLong(final String key) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof LongTag) {
 | 
			
		||||
            return ((LongTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0L;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a long named with the given key, even if it's another type of number.  <p> If the key does not exist or
 | 
			
		||||
     * its value is not a number, then {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the key
 | 
			
		||||
     *
 | 
			
		||||
     * @return a long
 | 
			
		||||
     */
 | 
			
		||||
    public long asLong(final String key) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof ByteTag) {
 | 
			
		||||
            return ((ByteTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof ShortTag) {
 | 
			
		||||
            return ((ShortTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof IntTag) {
 | 
			
		||||
            return ((IntTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof LongTag) {
 | 
			
		||||
            return ((LongTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof FloatTag) {
 | 
			
		||||
            return ((FloatTag) tag).getValue().longValue();
 | 
			
		||||
        } else if (tag instanceof DoubleTag) {
 | 
			
		||||
            return ((DoubleTag) tag).getValue().longValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0L;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a short named with the given key.  <p> If the key does not exist or its value is not a short tag, then
 | 
			
		||||
     * {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the key
 | 
			
		||||
     *
 | 
			
		||||
     * @return a short
 | 
			
		||||
     */
 | 
			
		||||
    public short getShort(final String key) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof ShortTag) {
 | 
			
		||||
            return ((ShortTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a string named with the given key.  <p> If the key does not exist or its value is not a string tag, then
 | 
			
		||||
     * {@code ""} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param key the key
 | 
			
		||||
     *
 | 
			
		||||
     * @return a string
 | 
			
		||||
     */
 | 
			
		||||
    public String getString(final String key) {
 | 
			
		||||
        final Tag tag = this.value.get(key);
 | 
			
		||||
        if (tag instanceof StringTag) {
 | 
			
		||||
            return ((StringTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return "";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        final String name = getName();
 | 
			
		||||
        String append = "";
 | 
			
		||||
        if ((name != null) && !name.equals("")) {
 | 
			
		||||
            append = "(\"" + this.getName() + "\")";
 | 
			
		||||
        }
 | 
			
		||||
        final StringBuilder bldr = new StringBuilder();
 | 
			
		||||
        bldr.append("TAG_Compound").append(append).append(": ").append(this.value.size()).append(" entries\r\n{\r\n");
 | 
			
		||||
        for (final Map.Entry<String, Tag> entry : this.value.entrySet()) {
 | 
			
		||||
            bldr.append("   ").append(entry.getValue().toString().replaceAll("\r\n", "\r\n   ")).append("\r\n");
 | 
			
		||||
        }
 | 
			
		||||
        bldr.append("}");
 | 
			
		||||
        return bldr.toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,197 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
import static com.google.common.base.Preconditions.checkNotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Helps create compound tags.
 | 
			
		||||
 */
 | 
			
		||||
public class CompoundTagBuilder {
 | 
			
		||||
    private final Map<String, Tag> entries;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new instance.
 | 
			
		||||
     */
 | 
			
		||||
    CompoundTagBuilder() {
 | 
			
		||||
        this.entries = new HashMap<String, Tag>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new instance and use the given map (which will be modified).
 | 
			
		||||
     *
 | 
			
		||||
     * @param value the value
 | 
			
		||||
     */
 | 
			
		||||
    CompoundTagBuilder(final Map<String, Tag> value) {
 | 
			
		||||
        checkNotNull(value);
 | 
			
		||||
        this.entries = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new builder instance.
 | 
			
		||||
     *
 | 
			
		||||
     * @return a new builder
 | 
			
		||||
     */
 | 
			
		||||
    public static CompoundTagBuilder create() {
 | 
			
		||||
        return new CompoundTagBuilder();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put the given key and tag into the compound tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param key   they key
 | 
			
		||||
     * @param value the value
 | 
			
		||||
     *
 | 
			
		||||
     * @return this object
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTagBuilder put(final String key, final Tag value) {
 | 
			
		||||
        checkNotNull(key);
 | 
			
		||||
        checkNotNull(value);
 | 
			
		||||
        this.entries.put(key, value);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put the given key and value into the compound tag as a {@code ByteArrayTag}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param key   they key
 | 
			
		||||
     * @param value the value
 | 
			
		||||
     *
 | 
			
		||||
     * @return this object
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTagBuilder putByteArray(final String key, final byte[] value) {
 | 
			
		||||
        return put(key, new ByteArrayTag(key, value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put the given key and value into the compound tag as a {@code ByteTag}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param key   they key
 | 
			
		||||
     * @param value the value
 | 
			
		||||
     *
 | 
			
		||||
     * @return this object
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTagBuilder putByte(final String key, final byte value) {
 | 
			
		||||
        return put(key, new ByteTag(key, value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put the given key and value into the compound tag as a {@code DoubleTag}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param key   they key
 | 
			
		||||
     * @param value the value
 | 
			
		||||
     *
 | 
			
		||||
     * @return this object
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTagBuilder putDouble(final String key, final double value) {
 | 
			
		||||
        return put(key, new DoubleTag(key, value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put the given key and value into the compound tag as a {@code FloatTag}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param key   they key
 | 
			
		||||
     * @param value the value
 | 
			
		||||
     *
 | 
			
		||||
     * @return this object
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTagBuilder putFloat(final String key, final float value) {
 | 
			
		||||
        return put(key, new FloatTag(key, value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put the given key and value into the compound tag as a {@code IntArrayTag}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param key   they key
 | 
			
		||||
     * @param value the value
 | 
			
		||||
     *
 | 
			
		||||
     * @return this object
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTagBuilder putIntArray(final String key, final int[] value) {
 | 
			
		||||
        return put(key, new IntArrayTag(key, value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put the given key and value into the compound tag as an {@code IntTag}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param key   they key
 | 
			
		||||
     * @param value the value
 | 
			
		||||
     *
 | 
			
		||||
     * @return this object
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTagBuilder putInt(final String key, final int value) {
 | 
			
		||||
        return put(key, new IntTag(key, value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put the given key and value into the compound tag as a {@code LongTag}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param key   they key
 | 
			
		||||
     * @param value the value
 | 
			
		||||
     *
 | 
			
		||||
     * @return this object
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTagBuilder putLong(final String key, final long value) {
 | 
			
		||||
        return put(key, new LongTag(key, value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put the given key and value into the compound tag as a {@code ShortTag}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param key   they key
 | 
			
		||||
     * @param value the value
 | 
			
		||||
     *
 | 
			
		||||
     * @return this object
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTagBuilder putShort(final String key, final short value) {
 | 
			
		||||
        return put(key, new ShortTag(key, value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put the given key and value into the compound tag as a {@code StringTag}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param key   they key
 | 
			
		||||
     * @param value the value
 | 
			
		||||
     *
 | 
			
		||||
     * @return this object
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTagBuilder putString(final String key, final String value) {
 | 
			
		||||
        return put(key, new StringTag(key, value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put all the entries from the given map into this map.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value the map of tags
 | 
			
		||||
     *
 | 
			
		||||
     * @return this object
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTagBuilder putAll(final Map<String, ? extends Tag> value) {
 | 
			
		||||
        checkNotNull(value);
 | 
			
		||||
        for (final Map.Entry<String, ? extends Tag> entry : value.entrySet()) {
 | 
			
		||||
            put(entry.getKey(), entry.getValue());
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Build an unnamed compound tag with this builder's entries.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the new compound tag
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTag build() {
 | 
			
		||||
        return new CompoundTag(new HashMap<String, Tag>(this.entries));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Build a new compound tag with this builder's entries.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name the name of the tag
 | 
			
		||||
     *
 | 
			
		||||
     * @return the created compound tag
 | 
			
		||||
     */
 | 
			
		||||
    public CompoundTag build(final String name) {
 | 
			
		||||
        return new CompoundTag(name, new HashMap<String, Tag>(this.entries));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								src/main/java/com/intellectualcrafters/jnbt/DoubleTag.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/main/java/com/intellectualcrafters/jnbt/DoubleTag.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The {@code TAG_Double} tag.
 | 
			
		||||
 */
 | 
			
		||||
public final class DoubleTag extends Tag {
 | 
			
		||||
    private final double value;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag with an empty name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public DoubleTag(final double value) {
 | 
			
		||||
        super();
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name  the name of the tag
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public DoubleTag(final String name, final double value) {
 | 
			
		||||
        super(name);
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Double getValue() {
 | 
			
		||||
        return this.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        final String name = getName();
 | 
			
		||||
        String append = "";
 | 
			
		||||
        if ((name != null) && !name.equals("")) {
 | 
			
		||||
            append = "(\"" + this.getName() + "\")";
 | 
			
		||||
        }
 | 
			
		||||
        return "TAG_Double" + append + ": " + this.value;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								src/main/java/com/intellectualcrafters/jnbt/EndTag.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/main/java/com/intellectualcrafters/jnbt/EndTag.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The {@code TAG_End} tag.
 | 
			
		||||
 */
 | 
			
		||||
public final class EndTag extends Tag {
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag.
 | 
			
		||||
     */
 | 
			
		||||
    public EndTag() {
 | 
			
		||||
        super();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Object getValue() {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return "TAG_End";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								src/main/java/com/intellectualcrafters/jnbt/FloatTag.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/main/java/com/intellectualcrafters/jnbt/FloatTag.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The {@code TAG_Float} tag.
 | 
			
		||||
 */
 | 
			
		||||
public final class FloatTag extends Tag {
 | 
			
		||||
    private final float value;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag with an empty name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public FloatTag(final float value) {
 | 
			
		||||
        super();
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name  the name of the tag
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public FloatTag(final String name, final float value) {
 | 
			
		||||
        super(name);
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Float getValue() {
 | 
			
		||||
        return this.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        final String name = getName();
 | 
			
		||||
        String append = "";
 | 
			
		||||
        if ((name != null) && !name.equals("")) {
 | 
			
		||||
            append = "(\"" + this.getName() + "\")";
 | 
			
		||||
        }
 | 
			
		||||
        return "TAG_Float" + append + ": " + this.value;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										56
									
								
								src/main/java/com/intellectualcrafters/jnbt/IntArrayTag.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/main/java/com/intellectualcrafters/jnbt/IntArrayTag.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
import static com.google.common.base.Preconditions.checkNotNull;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The {@code TAG_Int_Array} tag.
 | 
			
		||||
 */
 | 
			
		||||
public final class IntArrayTag extends Tag {
 | 
			
		||||
    private final int[] value;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag with an empty name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public IntArrayTag(final int[] value) {
 | 
			
		||||
        super();
 | 
			
		||||
        checkNotNull(value);
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name  the name of the tag
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public IntArrayTag(final String name, final int[] value) {
 | 
			
		||||
        super(name);
 | 
			
		||||
        checkNotNull(value);
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int[] getValue() {
 | 
			
		||||
        return this.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        final StringBuilder hex = new StringBuilder();
 | 
			
		||||
        for (final int b : this.value) {
 | 
			
		||||
            final String hexDigits = Integer.toHexString(b).toUpperCase();
 | 
			
		||||
            if (hexDigits.length() == 1) {
 | 
			
		||||
                hex.append("0");
 | 
			
		||||
            }
 | 
			
		||||
            hex.append(hexDigits).append(" ");
 | 
			
		||||
        }
 | 
			
		||||
        final String name = getName();
 | 
			
		||||
        String append = "";
 | 
			
		||||
        if ((name != null) && !name.equals("")) {
 | 
			
		||||
            append = "(\"" + this.getName() + "\")";
 | 
			
		||||
        }
 | 
			
		||||
        return "TAG_Int_Array" + append + ": " + hex;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								src/main/java/com/intellectualcrafters/jnbt/IntTag.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/main/java/com/intellectualcrafters/jnbt/IntTag.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The {@code TAG_Int} tag.
 | 
			
		||||
 */
 | 
			
		||||
public final class IntTag extends Tag {
 | 
			
		||||
    private final int value;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag with an empty name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public IntTag(final int value) {
 | 
			
		||||
        super();
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name  the name of the tag
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public IntTag(final String name, final int value) {
 | 
			
		||||
        super(name);
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Integer getValue() {
 | 
			
		||||
        return this.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        final String name = getName();
 | 
			
		||||
        String append = "";
 | 
			
		||||
        if ((name != null) && !name.equals("")) {
 | 
			
		||||
            append = "(\"" + this.getName() + "\")";
 | 
			
		||||
        }
 | 
			
		||||
        return "TAG_Int" + append + ": " + this.value;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										393
									
								
								src/main/java/com/intellectualcrafters/jnbt/ListTag.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								src/main/java/com/intellectualcrafters/jnbt/ListTag.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,393 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
import static com.google.common.base.Preconditions.checkNotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.NoSuchElementException;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The {@code TAG_List} tag.
 | 
			
		||||
 */
 | 
			
		||||
public final class ListTag extends Tag {
 | 
			
		||||
    private final Class<? extends Tag> type;
 | 
			
		||||
    private final List<Tag> value;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag with an empty name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param type  the type of tag
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public ListTag(final Class<? extends Tag> type, final List<? extends Tag> value) {
 | 
			
		||||
        super();
 | 
			
		||||
        checkNotNull(value);
 | 
			
		||||
        this.type = type;
 | 
			
		||||
        this.value = Collections.unmodifiableList(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name  the name of the tag
 | 
			
		||||
     * @param type  the type of tag
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public ListTag(final String name, final Class<? extends Tag> type, final List<? extends Tag> value) {
 | 
			
		||||
        super(name);
 | 
			
		||||
        checkNotNull(value);
 | 
			
		||||
        this.type = type;
 | 
			
		||||
        this.value = Collections.unmodifiableList(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the type of item in this list.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The type of item in this list.
 | 
			
		||||
     */
 | 
			
		||||
    public Class<? extends Tag> getType() {
 | 
			
		||||
        return this.type;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<Tag> getValue() {
 | 
			
		||||
        return this.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new list tag with this tag's name and type.
 | 
			
		||||
     *
 | 
			
		||||
     * @param list the new list
 | 
			
		||||
     *
 | 
			
		||||
     * @return a new list tag
 | 
			
		||||
     */
 | 
			
		||||
    public ListTag setValue(final List<Tag> list) {
 | 
			
		||||
        return new ListTag(getName(), getType(), list);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the tag if it exists at the given index.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return the tag or null
 | 
			
		||||
     */
 | 
			
		||||
    public Tag getIfExists(final int index) {
 | 
			
		||||
        try {
 | 
			
		||||
            return this.value.get(index);
 | 
			
		||||
        } catch (final NoSuchElementException e) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a byte array named with the given index.  <p> If the index does not exist or its value is not a byte
 | 
			
		||||
     * array tag, then an empty byte array will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return a byte array
 | 
			
		||||
     */
 | 
			
		||||
    public byte[] getByteArray(final int index) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof ByteArrayTag) {
 | 
			
		||||
            return ((ByteArrayTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return new byte[0];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a byte named with the given index.  <p> If the index does not exist or its value is not a byte tag, then
 | 
			
		||||
     * {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return a byte
 | 
			
		||||
     */
 | 
			
		||||
    public byte getByte(final int index) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof ByteTag) {
 | 
			
		||||
            return ((ByteTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return (byte) 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a double named with the given index.  <p> If the index does not exist or its value is not a double tag,
 | 
			
		||||
     * then {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return a double
 | 
			
		||||
     */
 | 
			
		||||
    public double getDouble(final int index) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof DoubleTag) {
 | 
			
		||||
            return ((DoubleTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a double named with the given index, even if it's another type of number.  <p> If the index does not
 | 
			
		||||
     * exist or its value is not a number, then {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return a double
 | 
			
		||||
     */
 | 
			
		||||
    public double asDouble(final int index) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof ByteTag) {
 | 
			
		||||
            return ((ByteTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof ShortTag) {
 | 
			
		||||
            return ((ShortTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof IntTag) {
 | 
			
		||||
            return ((IntTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof LongTag) {
 | 
			
		||||
            return ((LongTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof FloatTag) {
 | 
			
		||||
            return ((FloatTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof DoubleTag) {
 | 
			
		||||
            return ((DoubleTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a float named with the given index.  <p> If the index does not exist or its value is not a float tag,
 | 
			
		||||
     * then {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return a float
 | 
			
		||||
     */
 | 
			
		||||
    public float getFloat(final int index) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof FloatTag) {
 | 
			
		||||
            return ((FloatTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a {@code int[]} named with the given index.  <p> If the index does not exist or its value is not an int
 | 
			
		||||
     * array tag, then an empty array will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return an int array
 | 
			
		||||
     */
 | 
			
		||||
    public int[] getIntArray(final int index) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof IntArrayTag) {
 | 
			
		||||
            return ((IntArrayTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return new int[0];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an int named with the given index.  <p> If the index does not exist or its value is not an int tag, then
 | 
			
		||||
     * {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return an int
 | 
			
		||||
     */
 | 
			
		||||
    public int getInt(final int index) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof IntTag) {
 | 
			
		||||
            return ((IntTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an int named with the given index, even if it's another type of number.  <p> If the index does not exist
 | 
			
		||||
     * or its value is not a number, then {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return an int
 | 
			
		||||
     */
 | 
			
		||||
    public int asInt(final int index) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof ByteTag) {
 | 
			
		||||
            return ((ByteTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof ShortTag) {
 | 
			
		||||
            return ((ShortTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof IntTag) {
 | 
			
		||||
            return ((IntTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof LongTag) {
 | 
			
		||||
            return ((LongTag) tag).getValue().intValue();
 | 
			
		||||
        } else if (tag instanceof FloatTag) {
 | 
			
		||||
            return ((FloatTag) tag).getValue().intValue();
 | 
			
		||||
        } else if (tag instanceof DoubleTag) {
 | 
			
		||||
            return ((DoubleTag) tag).getValue().intValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a list of tags named with the given index.  <p> If the index does not exist or its value is not a list
 | 
			
		||||
     * tag, then an empty list will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return a list of tags
 | 
			
		||||
     */
 | 
			
		||||
    public List<Tag> getList(final int index) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof ListTag) {
 | 
			
		||||
            return ((ListTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return Collections.emptyList();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a {@code TagList} named with the given index.  <p> If the index does not exist or its value is not a list
 | 
			
		||||
     * tag, then an empty tag list will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return a tag list instance
 | 
			
		||||
     */
 | 
			
		||||
    public ListTag getListTag(final int index) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof ListTag) {
 | 
			
		||||
            return (ListTag) tag;
 | 
			
		||||
        } else {
 | 
			
		||||
            return new ListTag(StringTag.class, Collections.<Tag> emptyList());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a list of tags named with the given index.  <p> If the index does not exist or its value is not a list
 | 
			
		||||
     * tag, then an empty list will be returned. If the given index references a list but the list of of a different
 | 
			
		||||
     * type, then an empty list will also be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index    the index
 | 
			
		||||
     * @param listType the class of the contained type
 | 
			
		||||
     * @param <T>      the NBT type
 | 
			
		||||
     *
 | 
			
		||||
     * @return a list of tags
 | 
			
		||||
     */
 | 
			
		||||
    @SuppressWarnings("unchecked")
 | 
			
		||||
    public <T extends Tag> List<T> getList(final int index, final Class<T> listType) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof ListTag) {
 | 
			
		||||
            final ListTag listTag = (ListTag) tag;
 | 
			
		||||
            if (listTag.getType().equals(listType)) {
 | 
			
		||||
                return (List<T>) listTag.getValue();
 | 
			
		||||
            } else {
 | 
			
		||||
                return Collections.emptyList();
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            return Collections.emptyList();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a long named with the given index.  <p> If the index does not exist or its value is not a long tag, then
 | 
			
		||||
     * {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return a long
 | 
			
		||||
     */
 | 
			
		||||
    public long getLong(final int index) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof LongTag) {
 | 
			
		||||
            return ((LongTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0L;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a long named with the given index, even if it's another type of number.  <p> If the index does not exist
 | 
			
		||||
     * or its value is not a number, then {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return a long
 | 
			
		||||
     */
 | 
			
		||||
    public long asLong(final int index) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof ByteTag) {
 | 
			
		||||
            return ((ByteTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof ShortTag) {
 | 
			
		||||
            return ((ShortTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof IntTag) {
 | 
			
		||||
            return ((IntTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof LongTag) {
 | 
			
		||||
            return ((LongTag) tag).getValue();
 | 
			
		||||
        } else if (tag instanceof FloatTag) {
 | 
			
		||||
            return ((FloatTag) tag).getValue().longValue();
 | 
			
		||||
        } else if (tag instanceof DoubleTag) {
 | 
			
		||||
            return ((DoubleTag) tag).getValue().longValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a short named with the given index.  <p> If the index does not exist or its value is not a short tag,
 | 
			
		||||
     * then {@code 0} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return a short
 | 
			
		||||
     */
 | 
			
		||||
    public short getShort(final int index) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof ShortTag) {
 | 
			
		||||
            return ((ShortTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a string named with the given index.  <p> If the index does not exist or its value is not a string tag,
 | 
			
		||||
     * then {@code ""} will be returned. </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index the index
 | 
			
		||||
     *
 | 
			
		||||
     * @return a string
 | 
			
		||||
     */
 | 
			
		||||
    public String getString(final int index) {
 | 
			
		||||
        final Tag tag = getIfExists(index);
 | 
			
		||||
        if (tag instanceof StringTag) {
 | 
			
		||||
            return ((StringTag) tag).getValue();
 | 
			
		||||
        } else {
 | 
			
		||||
            return "";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        final String name = getName();
 | 
			
		||||
        String append = "";
 | 
			
		||||
        if ((name != null) && !name.equals("")) {
 | 
			
		||||
            append = "(\"" + this.getName() + "\")";
 | 
			
		||||
        }
 | 
			
		||||
        final StringBuilder bldr = new StringBuilder();
 | 
			
		||||
        bldr.append("TAG_List").append(append).append(": ").append(this.value.size()).append(" entries of type ").append(NBTUtils.getTypeName(this.type)).append("\r\n{\r\n");
 | 
			
		||||
        for (final Tag t : this.value) {
 | 
			
		||||
            bldr.append("   ").append(t.toString().replaceAll("\r\n", "\r\n   ")).append("\r\n");
 | 
			
		||||
        }
 | 
			
		||||
        bldr.append("}");
 | 
			
		||||
        return bldr.toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										114
									
								
								src/main/java/com/intellectualcrafters/jnbt/ListTagBuilder.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/main/java/com/intellectualcrafters/jnbt/ListTagBuilder.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
import static com.google.common.base.Preconditions.checkNotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Helps create list tags.
 | 
			
		||||
 */
 | 
			
		||||
public class ListTagBuilder {
 | 
			
		||||
    private final Class<? extends Tag> type;
 | 
			
		||||
    private final List<Tag> entries;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new instance.
 | 
			
		||||
     *
 | 
			
		||||
     * @param type of tag contained in this list
 | 
			
		||||
     */
 | 
			
		||||
    ListTagBuilder(final Class<? extends Tag> type) {
 | 
			
		||||
        checkNotNull(type);
 | 
			
		||||
        this.type = type;
 | 
			
		||||
        this.entries = new ArrayList<Tag>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new builder instance.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param type
 | 
			
		||||
     *
 | 
			
		||||
     * @return a new builder
 | 
			
		||||
     */
 | 
			
		||||
    public static ListTagBuilder create(final Class<? extends Tag> type) {
 | 
			
		||||
        return new ListTagBuilder(type);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new builder instance.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param entries
 | 
			
		||||
     * @param <T>
 | 
			
		||||
     *
 | 
			
		||||
     * @return a new builder
 | 
			
		||||
     */
 | 
			
		||||
    @SafeVarargs
 | 
			
		||||
    public static <T extends Tag> ListTagBuilder createWith(final T... entries) {
 | 
			
		||||
        checkNotNull(entries);
 | 
			
		||||
        if (entries.length == 0) {
 | 
			
		||||
            throw new IllegalArgumentException("This method needs an array of at least one entry");
 | 
			
		||||
        }
 | 
			
		||||
        final Class<? extends Tag> type = entries[0].getClass();
 | 
			
		||||
        for (int i = 1; i < entries.length; i++) {
 | 
			
		||||
            if (!type.isInstance(entries[i])) {
 | 
			
		||||
                throw new IllegalArgumentException("An array of different tag types was provided");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        final ListTagBuilder builder = new ListTagBuilder(type);
 | 
			
		||||
        builder.addAll(Arrays.asList(entries));
 | 
			
		||||
        return builder;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add the given tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value the tag
 | 
			
		||||
     *
 | 
			
		||||
     * @return this object
 | 
			
		||||
     */
 | 
			
		||||
    public ListTagBuilder add(final Tag value) {
 | 
			
		||||
        checkNotNull(value);
 | 
			
		||||
        if (!this.type.isInstance(value)) {
 | 
			
		||||
            throw new IllegalArgumentException(value.getClass().getCanonicalName() + " is not of expected type " + this.type.getCanonicalName());
 | 
			
		||||
        }
 | 
			
		||||
        this.entries.add(value);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add all the tags in the given list.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value a list of tags
 | 
			
		||||
     *
 | 
			
		||||
     * @return this object
 | 
			
		||||
     */
 | 
			
		||||
    public ListTagBuilder addAll(final Collection<? extends Tag> value) {
 | 
			
		||||
        checkNotNull(value);
 | 
			
		||||
        for (final Tag v : value) {
 | 
			
		||||
            add(v);
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Build an unnamed list tag with this builder's entries.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the new list tag
 | 
			
		||||
     */
 | 
			
		||||
    public ListTag build() {
 | 
			
		||||
        return new ListTag(this.type, new ArrayList<Tag>(this.entries));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Build a new list tag with this builder's entries.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name the name of the tag
 | 
			
		||||
     *
 | 
			
		||||
     * @return the created list tag
 | 
			
		||||
     */
 | 
			
		||||
    public ListTag build(final String name) {
 | 
			
		||||
        return new ListTag(name, this.type, new ArrayList<Tag>(this.entries));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								src/main/java/com/intellectualcrafters/jnbt/LongTag.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/main/java/com/intellectualcrafters/jnbt/LongTag.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The {@code TAG_Long} tag.
 | 
			
		||||
 */
 | 
			
		||||
public final class LongTag extends Tag {
 | 
			
		||||
    private final long value;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag with an empty name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public LongTag(final long value) {
 | 
			
		||||
        super();
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name  the name of the tag
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public LongTag(final String name, final long value) {
 | 
			
		||||
        super(name);
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Long getValue() {
 | 
			
		||||
        return this.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        final String name = getName();
 | 
			
		||||
        String append = "";
 | 
			
		||||
        if ((name != null) && !name.equals("")) {
 | 
			
		||||
            append = "(\"" + this.getName() + "\")";
 | 
			
		||||
        }
 | 
			
		||||
        return "TAG_Long" + append + ": " + this.value;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,77 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
import java.nio.charset.Charset;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A class which holds constant values.
 | 
			
		||||
 */
 | 
			
		||||
public final class NBTConstants {
 | 
			
		||||
    public static final Charset CHARSET = Charset.forName("UTF-8");
 | 
			
		||||
    public static final int TYPE_END = 0, TYPE_BYTE = 1, TYPE_SHORT = 2, TYPE_INT = 3, TYPE_LONG = 4, TYPE_FLOAT = 5, TYPE_DOUBLE = 6, TYPE_BYTE_ARRAY = 7, TYPE_STRING = 8, TYPE_LIST = 9, TYPE_COMPOUND = 10, TYPE_INT_ARRAY = 11;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Default private constructor.
 | 
			
		||||
     */
 | 
			
		||||
    private NBTConstants() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert a type ID to its corresponding {@link Tag} class.
 | 
			
		||||
     *
 | 
			
		||||
     * @param id type ID
 | 
			
		||||
     *
 | 
			
		||||
     * @return tag class
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IllegalArgumentException thrown if the tag ID is not valid
 | 
			
		||||
     */
 | 
			
		||||
    public static Class<? extends Tag> getClassFromType(final int id) {
 | 
			
		||||
        switch (id) {
 | 
			
		||||
            case TYPE_END:
 | 
			
		||||
                return EndTag.class;
 | 
			
		||||
            case TYPE_BYTE:
 | 
			
		||||
                return ByteTag.class;
 | 
			
		||||
            case TYPE_SHORT:
 | 
			
		||||
                return ShortTag.class;
 | 
			
		||||
            case TYPE_INT:
 | 
			
		||||
                return IntTag.class;
 | 
			
		||||
            case TYPE_LONG:
 | 
			
		||||
                return LongTag.class;
 | 
			
		||||
            case TYPE_FLOAT:
 | 
			
		||||
                return FloatTag.class;
 | 
			
		||||
            case TYPE_DOUBLE:
 | 
			
		||||
                return DoubleTag.class;
 | 
			
		||||
            case TYPE_BYTE_ARRAY:
 | 
			
		||||
                return ByteArrayTag.class;
 | 
			
		||||
            case TYPE_STRING:
 | 
			
		||||
                return StringTag.class;
 | 
			
		||||
            case TYPE_LIST:
 | 
			
		||||
                return ListTag.class;
 | 
			
		||||
            case TYPE_COMPOUND:
 | 
			
		||||
                return CompoundTag.class;
 | 
			
		||||
            case TYPE_INT_ARRAY:
 | 
			
		||||
                return IntArrayTag.class;
 | 
			
		||||
            default:
 | 
			
		||||
                throw new IllegalArgumentException("Unknown tag type ID of " + id);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										145
									
								
								src/main/java/com/intellectualcrafters/jnbt/NBTInputStream.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								src/main/java/com/intellectualcrafters/jnbt/NBTInputStream.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,145 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
import java.io.Closeable;
 | 
			
		||||
import java.io.DataInputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class reads <strong>NBT</strong>, or <strong>Named Binary Tag</strong> streams, and produces an object graph of
 | 
			
		||||
 * subclasses of the {@code Tag} object.  The NBT format was created by Markus Persson, and the specification
 | 
			
		||||
 * may be found at @linktourl http://www.minecraft.net/docs/NBT.txt"> http://www.minecraft.net/docs/NBT.txt.
 | 
			
		||||
 */
 | 
			
		||||
public final class NBTInputStream implements Closeable {
 | 
			
		||||
    private final DataInputStream is;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new {@code NBTInputStream}, which will source its data from the specified input stream.
 | 
			
		||||
     *
 | 
			
		||||
     * @param is the input stream
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs
 | 
			
		||||
     */
 | 
			
		||||
    public NBTInputStream(final InputStream is) throws IOException {
 | 
			
		||||
        this.is = new DataInputStream(is);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reads an NBT tag from the stream.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The tag that was read.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    public Tag readTag() throws IOException {
 | 
			
		||||
        return readTag(0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reads an NBT from the stream.
 | 
			
		||||
     *
 | 
			
		||||
     * @param depth the depth of this tag
 | 
			
		||||
     *
 | 
			
		||||
     * @return The tag that was read.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    private Tag readTag(final int depth) throws IOException {
 | 
			
		||||
        final int type = this.is.readByte() & 0xFF;
 | 
			
		||||
        String name;
 | 
			
		||||
        if (type != NBTConstants.TYPE_END) {
 | 
			
		||||
            final int nameLength = this.is.readShort() & 0xFFFF;
 | 
			
		||||
            final byte[] nameBytes = new byte[nameLength];
 | 
			
		||||
            this.is.readFully(nameBytes);
 | 
			
		||||
            name = new String(nameBytes, NBTConstants.CHARSET);
 | 
			
		||||
        } else {
 | 
			
		||||
            name = "";
 | 
			
		||||
        }
 | 
			
		||||
        return readTagPayload(type, name, depth);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reads the payload of a tag, given the name and type.
 | 
			
		||||
     *
 | 
			
		||||
     * @param type  the type
 | 
			
		||||
     * @param name  the name
 | 
			
		||||
     * @param depth the depth
 | 
			
		||||
     *
 | 
			
		||||
     * @return the tag
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    private Tag readTagPayload(final int type, final String name, final int depth) throws IOException {
 | 
			
		||||
        switch (type) {
 | 
			
		||||
            case NBTConstants.TYPE_END:
 | 
			
		||||
                if (depth == 0) {
 | 
			
		||||
                    throw new IOException("TAG_End found without a TAG_Compound/TAG_List tag preceding it.");
 | 
			
		||||
                } else {
 | 
			
		||||
                    return new EndTag();
 | 
			
		||||
                }
 | 
			
		||||
            case NBTConstants.TYPE_BYTE:
 | 
			
		||||
                return new ByteTag(name, this.is.readByte());
 | 
			
		||||
            case NBTConstants.TYPE_SHORT:
 | 
			
		||||
                return new ShortTag(name, this.is.readShort());
 | 
			
		||||
            case NBTConstants.TYPE_INT:
 | 
			
		||||
                return new IntTag(name, this.is.readInt());
 | 
			
		||||
            case NBTConstants.TYPE_LONG:
 | 
			
		||||
                return new LongTag(name, this.is.readLong());
 | 
			
		||||
            case NBTConstants.TYPE_FLOAT:
 | 
			
		||||
                return new FloatTag(name, this.is.readFloat());
 | 
			
		||||
            case NBTConstants.TYPE_DOUBLE:
 | 
			
		||||
                return new DoubleTag(name, this.is.readDouble());
 | 
			
		||||
            case NBTConstants.TYPE_BYTE_ARRAY:
 | 
			
		||||
                int length = this.is.readInt();
 | 
			
		||||
                byte[] bytes = new byte[length];
 | 
			
		||||
                this.is.readFully(bytes);
 | 
			
		||||
                return new ByteArrayTag(name, bytes);
 | 
			
		||||
            case NBTConstants.TYPE_STRING:
 | 
			
		||||
                length = this.is.readShort();
 | 
			
		||||
                bytes = new byte[length];
 | 
			
		||||
                this.is.readFully(bytes);
 | 
			
		||||
                return new StringTag(name, new String(bytes, NBTConstants.CHARSET));
 | 
			
		||||
            case NBTConstants.TYPE_LIST:
 | 
			
		||||
                final int childType = this.is.readByte();
 | 
			
		||||
                length = this.is.readInt();
 | 
			
		||||
                final List<Tag> tagList = new ArrayList<Tag>();
 | 
			
		||||
                for (int i = 0; i < length; ++i) {
 | 
			
		||||
                    final Tag tag = readTagPayload(childType, "", depth + 1);
 | 
			
		||||
                    if (tag instanceof EndTag) {
 | 
			
		||||
                        throw new IOException("TAG_End not permitted in a list.");
 | 
			
		||||
                    }
 | 
			
		||||
                    tagList.add(tag);
 | 
			
		||||
                }
 | 
			
		||||
                return new ListTag(name, NBTUtils.getTypeClass(childType), tagList);
 | 
			
		||||
            case NBTConstants.TYPE_COMPOUND:
 | 
			
		||||
                final Map<String, Tag> tagMap = new HashMap<String, Tag>();
 | 
			
		||||
                while (true) {
 | 
			
		||||
                    final Tag tag = readTag(depth + 1);
 | 
			
		||||
                    if (tag instanceof EndTag) {
 | 
			
		||||
                        break;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        tagMap.put(tag.getName(), tag);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return new CompoundTag(name, tagMap);
 | 
			
		||||
            case NBTConstants.TYPE_INT_ARRAY:
 | 
			
		||||
                length = this.is.readInt();
 | 
			
		||||
                final int[] data = new int[length];
 | 
			
		||||
                for (int i = 0; i < length; i++) {
 | 
			
		||||
                    data[i] = this.is.readInt();
 | 
			
		||||
                }
 | 
			
		||||
                return new IntArrayTag(name, data);
 | 
			
		||||
            default:
 | 
			
		||||
                throw new IOException("Invalid tag type: " + type + ".");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void close() throws IOException {
 | 
			
		||||
        this.is.close();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										281
									
								
								src/main/java/com/intellectualcrafters/jnbt/NBTOutputStream.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								src/main/java/com/intellectualcrafters/jnbt/NBTOutputStream.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,281 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
import java.io.Closeable;
 | 
			
		||||
import java.io.DataOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * <p> This class writes <strong>NBT</strong>, or <strong>Named Binary Tag</strong> <code>Tag</code> objects to an
 | 
			
		||||
 * underlying <code>OutputStream</code>. </p>  <p> The NBT format was created by Markus Persson, and the
 | 
			
		||||
 * specification may be found at 
 | 
			
		||||
 * @linktourl http://www.minecraft.net/docs/NBT.txt
 | 
			
		||||
 * </p>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Graham Edgecombe
 | 
			
		||||
 */
 | 
			
		||||
public final class NBTOutputStream implements Closeable {
 | 
			
		||||
    /**
 | 
			
		||||
     * The output stream.
 | 
			
		||||
     */
 | 
			
		||||
    private final DataOutputStream os;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new <code>NBTOutputStream</code>, which will write data to the specified underlying output stream.
 | 
			
		||||
     *
 | 
			
		||||
     * @param os The output stream.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    public NBTOutputStream(final OutputStream os) throws IOException {
 | 
			
		||||
        this.os = new DataOutputStream(os);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Writes a tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param tag The tag to write.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    public void writeTag(final Tag tag) throws IOException {
 | 
			
		||||
        final int type = NBTUtils.getTypeCode(tag.getClass());
 | 
			
		||||
        final String name = tag.getName();
 | 
			
		||||
        final byte[] nameBytes = name.getBytes(NBTConstants.CHARSET);
 | 
			
		||||
        this.os.writeByte(type);
 | 
			
		||||
        this.os.writeShort(nameBytes.length);
 | 
			
		||||
        this.os.write(nameBytes);
 | 
			
		||||
        if (type == NBTConstants.TYPE_END) {
 | 
			
		||||
            throw new IOException("Named TAG_End not permitted.");
 | 
			
		||||
        }
 | 
			
		||||
        writeTagPayload(tag);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Writes tag payload.
 | 
			
		||||
     *
 | 
			
		||||
     * @param tag The tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    private void writeTagPayload(final Tag tag) throws IOException {
 | 
			
		||||
        final int type = NBTUtils.getTypeCode(tag.getClass());
 | 
			
		||||
        switch (type) {
 | 
			
		||||
            case NBTConstants.TYPE_END:
 | 
			
		||||
                writeEndTagPayload((EndTag) tag);
 | 
			
		||||
                break;
 | 
			
		||||
            case NBTConstants.TYPE_BYTE:
 | 
			
		||||
                writeByteTagPayload((ByteTag) tag);
 | 
			
		||||
                break;
 | 
			
		||||
            case NBTConstants.TYPE_SHORT:
 | 
			
		||||
                writeShortTagPayload((ShortTag) tag);
 | 
			
		||||
                break;
 | 
			
		||||
            case NBTConstants.TYPE_INT:
 | 
			
		||||
                writeIntTagPayload((IntTag) tag);
 | 
			
		||||
                break;
 | 
			
		||||
            case NBTConstants.TYPE_LONG:
 | 
			
		||||
                writeLongTagPayload((LongTag) tag);
 | 
			
		||||
                break;
 | 
			
		||||
            case NBTConstants.TYPE_FLOAT:
 | 
			
		||||
                writeFloatTagPayload((FloatTag) tag);
 | 
			
		||||
                break;
 | 
			
		||||
            case NBTConstants.TYPE_DOUBLE:
 | 
			
		||||
                writeDoubleTagPayload((DoubleTag) tag);
 | 
			
		||||
                break;
 | 
			
		||||
            case NBTConstants.TYPE_BYTE_ARRAY:
 | 
			
		||||
                writeByteArrayTagPayload((ByteArrayTag) tag);
 | 
			
		||||
                break;
 | 
			
		||||
            case NBTConstants.TYPE_STRING:
 | 
			
		||||
                writeStringTagPayload((StringTag) tag);
 | 
			
		||||
                break;
 | 
			
		||||
            case NBTConstants.TYPE_LIST:
 | 
			
		||||
                writeListTagPayload((ListTag) tag);
 | 
			
		||||
                break;
 | 
			
		||||
            case NBTConstants.TYPE_COMPOUND:
 | 
			
		||||
                writeCompoundTagPayload((CompoundTag) tag);
 | 
			
		||||
                break;
 | 
			
		||||
            case NBTConstants.TYPE_INT_ARRAY:
 | 
			
		||||
                writeIntArrayTagPayload((IntArrayTag) tag);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                throw new IOException("Invalid tag type: " + type + ".");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Writes a <code>TAG_Byte</code> tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param tag The tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    private void writeByteTagPayload(final ByteTag tag) throws IOException {
 | 
			
		||||
        this.os.writeByte(tag.getValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Writes a <code>TAG_Byte_Array</code> tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param tag The tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    private void writeByteArrayTagPayload(final ByteArrayTag tag) throws IOException {
 | 
			
		||||
        final byte[] bytes = tag.getValue();
 | 
			
		||||
        this.os.writeInt(bytes.length);
 | 
			
		||||
        this.os.write(bytes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Writes a <code>TAG_Compound</code> tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param tag The tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    private void writeCompoundTagPayload(final CompoundTag tag) throws IOException {
 | 
			
		||||
        for (final Tag childTag : tag.getValue().values()) {
 | 
			
		||||
            writeTag(childTag);
 | 
			
		||||
        }
 | 
			
		||||
        this.os.writeByte((byte) 0); // end tag - better way?
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Writes a <code>TAG_List</code> tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param tag The tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    private void writeListTagPayload(final ListTag tag) throws IOException {
 | 
			
		||||
        final Class<? extends Tag> clazz = tag.getType();
 | 
			
		||||
        final List<Tag> tags = tag.getValue();
 | 
			
		||||
        final int size = tags.size();
 | 
			
		||||
        this.os.writeByte(NBTUtils.getTypeCode(clazz));
 | 
			
		||||
        this.os.writeInt(size);
 | 
			
		||||
        for (final Tag tag1 : tags) {
 | 
			
		||||
            writeTagPayload(tag1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Writes a <code>TAG_String</code> tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param tag The tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    private void writeStringTagPayload(final StringTag tag) throws IOException {
 | 
			
		||||
        final byte[] bytes = tag.getValue().getBytes(NBTConstants.CHARSET);
 | 
			
		||||
        this.os.writeShort(bytes.length);
 | 
			
		||||
        this.os.write(bytes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Writes a <code>TAG_Double</code> tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param tag The tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    private void writeDoubleTagPayload(final DoubleTag tag) throws IOException {
 | 
			
		||||
        this.os.writeDouble(tag.getValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Writes a <code>TAG_Float</code> tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param tag The tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    private void writeFloatTagPayload(final FloatTag tag) throws IOException {
 | 
			
		||||
        this.os.writeFloat(tag.getValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Writes a <code>TAG_Long</code> tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param tag The tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    private void writeLongTagPayload(final LongTag tag) throws IOException {
 | 
			
		||||
        this.os.writeLong(tag.getValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Writes a <code>TAG_Int</code> tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param tag The tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    private void writeIntTagPayload(final IntTag tag) throws IOException {
 | 
			
		||||
        this.os.writeInt(tag.getValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Writes a <code>TAG_Short</code> tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param tag The tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    private void writeShortTagPayload(final ShortTag tag) throws IOException {
 | 
			
		||||
        this.os.writeShort(tag.getValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Writes a <code>TAG_Empty</code> tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param tag The tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IOException if an I/O error occurs.
 | 
			
		||||
     */
 | 
			
		||||
    private void writeEndTagPayload(final EndTag tag) {
 | 
			
		||||
        /* empty */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void writeIntArrayTagPayload(final IntArrayTag tag) throws IOException {
 | 
			
		||||
        final int[] data = tag.getValue();
 | 
			
		||||
        this.os.writeInt(data.length);
 | 
			
		||||
        for (final int element : data) {
 | 
			
		||||
            this.os.writeInt(element);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void close() throws IOException {
 | 
			
		||||
        this.os.close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Flush output
 | 
			
		||||
     * @throws IOException 
 | 
			
		||||
     */
 | 
			
		||||
    public void flush() throws IOException {
 | 
			
		||||
        this.os.flush();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										151
									
								
								src/main/java/com/intellectualcrafters/jnbt/NBTUtils.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								src/main/java/com/intellectualcrafters/jnbt/NBTUtils.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,151 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A class which contains NBT-related utility methods.
 | 
			
		||||
 */
 | 
			
		||||
public final class NBTUtils {
 | 
			
		||||
    /**
 | 
			
		||||
     * Default private constructor.
 | 
			
		||||
     */
 | 
			
		||||
    private NBTUtils() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the type name of a tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param clazz the tag class
 | 
			
		||||
     *
 | 
			
		||||
     * @return The type name.
 | 
			
		||||
     */
 | 
			
		||||
    public static String getTypeName(final Class<? extends Tag> clazz) {
 | 
			
		||||
        if (clazz.equals(ByteArrayTag.class)) {
 | 
			
		||||
            return "TAG_Byte_Array";
 | 
			
		||||
        } else if (clazz.equals(ByteTag.class)) {
 | 
			
		||||
            return "TAG_Byte";
 | 
			
		||||
        } else if (clazz.equals(CompoundTag.class)) {
 | 
			
		||||
            return "TAG_Compound";
 | 
			
		||||
        } else if (clazz.equals(DoubleTag.class)) {
 | 
			
		||||
            return "TAG_Double";
 | 
			
		||||
        } else if (clazz.equals(EndTag.class)) {
 | 
			
		||||
            return "TAG_End";
 | 
			
		||||
        } else if (clazz.equals(FloatTag.class)) {
 | 
			
		||||
            return "TAG_Float";
 | 
			
		||||
        } else if (clazz.equals(IntTag.class)) {
 | 
			
		||||
            return "TAG_Int";
 | 
			
		||||
        } else if (clazz.equals(ListTag.class)) {
 | 
			
		||||
            return "TAG_List";
 | 
			
		||||
        } else if (clazz.equals(LongTag.class)) {
 | 
			
		||||
            return "TAG_Long";
 | 
			
		||||
        } else if (clazz.equals(ShortTag.class)) {
 | 
			
		||||
            return "TAG_Short";
 | 
			
		||||
        } else if (clazz.equals(StringTag.class)) {
 | 
			
		||||
            return "TAG_String";
 | 
			
		||||
        } else if (clazz.equals(IntArrayTag.class)) {
 | 
			
		||||
            return "TAG_Int_Array";
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new IllegalArgumentException("Invalid tag classs (" + clazz.getName() + ").");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the type code of a tag class.
 | 
			
		||||
     *
 | 
			
		||||
     * @param clazz the tag class
 | 
			
		||||
     *
 | 
			
		||||
     * @return The type code.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IllegalArgumentException if the tag class is invalid.
 | 
			
		||||
     */
 | 
			
		||||
    public static int getTypeCode(final Class<? extends Tag> clazz) {
 | 
			
		||||
        if (clazz.equals(ByteArrayTag.class)) {
 | 
			
		||||
            return NBTConstants.TYPE_BYTE_ARRAY;
 | 
			
		||||
        } else if (clazz.equals(ByteTag.class)) {
 | 
			
		||||
            return NBTConstants.TYPE_BYTE;
 | 
			
		||||
        } else if (clazz.equals(CompoundTag.class)) {
 | 
			
		||||
            return NBTConstants.TYPE_COMPOUND;
 | 
			
		||||
        } else if (clazz.equals(DoubleTag.class)) {
 | 
			
		||||
            return NBTConstants.TYPE_DOUBLE;
 | 
			
		||||
        } else if (clazz.equals(EndTag.class)) {
 | 
			
		||||
            return NBTConstants.TYPE_END;
 | 
			
		||||
        } else if (clazz.equals(FloatTag.class)) {
 | 
			
		||||
            return NBTConstants.TYPE_FLOAT;
 | 
			
		||||
        } else if (clazz.equals(IntTag.class)) {
 | 
			
		||||
            return NBTConstants.TYPE_INT;
 | 
			
		||||
        } else if (clazz.equals(ListTag.class)) {
 | 
			
		||||
            return NBTConstants.TYPE_LIST;
 | 
			
		||||
        } else if (clazz.equals(LongTag.class)) {
 | 
			
		||||
            return NBTConstants.TYPE_LONG;
 | 
			
		||||
        } else if (clazz.equals(ShortTag.class)) {
 | 
			
		||||
            return NBTConstants.TYPE_SHORT;
 | 
			
		||||
        } else if (clazz.equals(StringTag.class)) {
 | 
			
		||||
            return NBTConstants.TYPE_STRING;
 | 
			
		||||
        } else if (clazz.equals(IntArrayTag.class)) {
 | 
			
		||||
            return NBTConstants.TYPE_INT_ARRAY;
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new IllegalArgumentException("Invalid tag classs (" + clazz.getName() + ").");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the class of a type of tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param type the type
 | 
			
		||||
     *
 | 
			
		||||
     * @return The class.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws IllegalArgumentException if the tag type is invalid.
 | 
			
		||||
     */
 | 
			
		||||
    public static Class<? extends Tag> getTypeClass(final int type) {
 | 
			
		||||
        switch (type) {
 | 
			
		||||
            case NBTConstants.TYPE_END:
 | 
			
		||||
                return EndTag.class;
 | 
			
		||||
            case NBTConstants.TYPE_BYTE:
 | 
			
		||||
                return ByteTag.class;
 | 
			
		||||
            case NBTConstants.TYPE_SHORT:
 | 
			
		||||
                return ShortTag.class;
 | 
			
		||||
            case NBTConstants.TYPE_INT:
 | 
			
		||||
                return IntTag.class;
 | 
			
		||||
            case NBTConstants.TYPE_LONG:
 | 
			
		||||
                return LongTag.class;
 | 
			
		||||
            case NBTConstants.TYPE_FLOAT:
 | 
			
		||||
                return FloatTag.class;
 | 
			
		||||
            case NBTConstants.TYPE_DOUBLE:
 | 
			
		||||
                return DoubleTag.class;
 | 
			
		||||
            case NBTConstants.TYPE_BYTE_ARRAY:
 | 
			
		||||
                return ByteArrayTag.class;
 | 
			
		||||
            case NBTConstants.TYPE_STRING:
 | 
			
		||||
                return StringTag.class;
 | 
			
		||||
            case NBTConstants.TYPE_LIST:
 | 
			
		||||
                return ListTag.class;
 | 
			
		||||
            case NBTConstants.TYPE_COMPOUND:
 | 
			
		||||
                return CompoundTag.class;
 | 
			
		||||
            case NBTConstants.TYPE_INT_ARRAY:
 | 
			
		||||
                return IntArrayTag.class;
 | 
			
		||||
            default:
 | 
			
		||||
                throw new IllegalArgumentException("Invalid tag type : " + type + ".");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get child tag of a NBT structure.
 | 
			
		||||
     *
 | 
			
		||||
     * @param items    the map to read from
 | 
			
		||||
     * @param key      the key to look for
 | 
			
		||||
     * @param expected the expected NBT class type
 | 
			
		||||
     * @param <T>
 | 
			
		||||
     *
 | 
			
		||||
     * @return child tag
 | 
			
		||||
     */
 | 
			
		||||
    public static <T extends Tag> T getChildTag(final Map<String, Tag> items, final String key, final Class<T> expected) throws IllegalArgumentException {
 | 
			
		||||
        if (!items.containsKey(key)) {
 | 
			
		||||
            throw new IllegalArgumentException("Missing a \"" + key + "\" tag");
 | 
			
		||||
        }
 | 
			
		||||
        final Tag tag = items.get(key);
 | 
			
		||||
        if (!expected.isInstance(tag)) {
 | 
			
		||||
            throw new IllegalArgumentException(key + " tag is not of tag type " + expected.getName());
 | 
			
		||||
        }
 | 
			
		||||
        return expected.cast(tag);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										64
									
								
								src/main/java/com/intellectualcrafters/jnbt/ShortTag.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/main/java/com/intellectualcrafters/jnbt/ShortTag.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The {@code TAG_Short} tag.
 | 
			
		||||
 */
 | 
			
		||||
public final class ShortTag extends Tag {
 | 
			
		||||
    private final short value;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag with an empty name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public ShortTag(final short value) {
 | 
			
		||||
        super();
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name  the name of the tag
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public ShortTag(final String name, final short value) {
 | 
			
		||||
        super(name);
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Short getValue() {
 | 
			
		||||
        return this.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        final String name = getName();
 | 
			
		||||
        String append = "";
 | 
			
		||||
        if ((name != null) && !name.equals("")) {
 | 
			
		||||
            append = "(\"" + this.getName() + "\")";
 | 
			
		||||
        }
 | 
			
		||||
        return "TAG_Short" + append + ": " + this.value;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								src/main/java/com/intellectualcrafters/jnbt/StringTag.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/main/java/com/intellectualcrafters/jnbt/StringTag.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
import static com.google.common.base.Preconditions.checkNotNull;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The {@code TAG_String} tag.
 | 
			
		||||
 */
 | 
			
		||||
public final class StringTag extends Tag {
 | 
			
		||||
    private final String value;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag with an empty name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public StringTag(final String value) {
 | 
			
		||||
        super();
 | 
			
		||||
        checkNotNull(value);
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name  the name of the tag
 | 
			
		||||
     * @param value the value of the tag
 | 
			
		||||
     */
 | 
			
		||||
    public StringTag(final String name, final String value) {
 | 
			
		||||
        super(name);
 | 
			
		||||
        checkNotNull(value);
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getValue() {
 | 
			
		||||
        return this.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        final String name = getName();
 | 
			
		||||
        String append = "";
 | 
			
		||||
        if ((name != null) && !name.equals("")) {
 | 
			
		||||
            append = "(\"" + this.getName() + "\")";
 | 
			
		||||
        }
 | 
			
		||||
        return "TAG_String" + append + ": " + this.value;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								src/main/java/com/intellectualcrafters/jnbt/Tag.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/main/java/com/intellectualcrafters/jnbt/Tag.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents a NBT tag.
 | 
			
		||||
 */
 | 
			
		||||
public abstract class Tag {
 | 
			
		||||
    private final String name;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new tag with an empty name.
 | 
			
		||||
     */
 | 
			
		||||
    Tag() {
 | 
			
		||||
        this("");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the tag with the specified name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name the name
 | 
			
		||||
     */
 | 
			
		||||
    Tag(String name) {
 | 
			
		||||
        if (name == null) {
 | 
			
		||||
            name = "";
 | 
			
		||||
        }
 | 
			
		||||
        this.name = name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the name of this tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the name of this tag
 | 
			
		||||
     */
 | 
			
		||||
    public final String getName() {
 | 
			
		||||
        return this.name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the value of this tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the value
 | 
			
		||||
     */
 | 
			
		||||
    public abstract Object getValue();
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,18 @@
 | 
			
		||||
package com.intellectualcrafters.jnbt;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.World;
 | 
			
		||||
 | 
			
		||||
public class WorldEditUtils {
 | 
			
		||||
    public static void setNBT(final World world, final short id, final byte data, final int x, final int y, final int z, final com.intellectualcrafters.jnbt.CompoundTag tag) {
 | 
			
		||||
        // final LocalWorld bukkitWorld = BukkitUtil.getLocalWorld(world);
 | 
			
		||||
        // I need to somehow convert our CompoundTag to WorldEdit's
 | 
			
		||||
        // final BaseBlock block = new BaseBlock(5, 5, (CompoundTag) tag);
 | 
			
		||||
        // final Vector vector = new Vector(x, y, z);
 | 
			
		||||
        // try {
 | 
			
		||||
        // bukkitWorld.setBlock(vector, block);
 | 
			
		||||
        // }
 | 
			
		||||
        // catch (final WorldEditException e) {
 | 
			
		||||
        // e.printStackTrace();
 | 
			
		||||
        // }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										265
									
								
								src/main/java/com/intellectualcrafters/json/CDL.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										265
									
								
								src/main/java/com/intellectualcrafters/json/CDL.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,265 @@
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This provides static methods to convert comma delimited text into a JSONArray, and to covert a JSONArray into comma
 | 
			
		||||
 * delimited text. Comma delimited text is a very popular format for data interchange. It is understood by most
 | 
			
		||||
 * database, spreadsheet, and organizer programs.
 | 
			
		||||
 * 
 | 
			
		||||
 * Each row of text represents a row in a table or a data record. Each row ends with a NEWLINE character. Each row
 | 
			
		||||
 * contains one or more values. Values are separated by commas. A value can contain any character except for comma,
 | 
			
		||||
 * unless is is wrapped in single quotes or double quotes.
 | 
			
		||||
 * 
 | 
			
		||||
 * The first row usually contains the names of the columns.
 | 
			
		||||
 * 
 | 
			
		||||
 * A comma delimited list can be converted into a JSONArray of JSONObjects. The names for the elements in the
 | 
			
		||||
 * JSONObjects can be taken from the names in the first row.
 | 
			
		||||
 *
 | 
			
		||||
 * @author JSON.org
 | 
			
		||||
 * @version 2014-05-03
 | 
			
		||||
 */
 | 
			
		||||
public class CDL {
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the next value. The value can be wrapped in quotes. The value can be empty.
 | 
			
		||||
     *
 | 
			
		||||
     * @param x A JSONTokener of the source text.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The value string, or null if empty.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException if the quoted string is badly formed.
 | 
			
		||||
     */
 | 
			
		||||
    private static String getValue(final JSONTokener x) throws JSONException {
 | 
			
		||||
        char c;
 | 
			
		||||
        char q;
 | 
			
		||||
        StringBuffer sb;
 | 
			
		||||
        do {
 | 
			
		||||
            c = x.next();
 | 
			
		||||
        } while ((c == ' ') || (c == '\t'));
 | 
			
		||||
        switch (c) {
 | 
			
		||||
            case 0:
 | 
			
		||||
                return null;
 | 
			
		||||
            case '"':
 | 
			
		||||
            case '\'':
 | 
			
		||||
                q = c;
 | 
			
		||||
                sb = new StringBuffer();
 | 
			
		||||
                for (;;) {
 | 
			
		||||
                    c = x.next();
 | 
			
		||||
                    if (c == q) {
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                    if ((c == 0) || (c == '\n') || (c == '\r')) {
 | 
			
		||||
                        throw x.syntaxError("Missing close quote '" + q + "'.");
 | 
			
		||||
                    }
 | 
			
		||||
                    sb.append(c);
 | 
			
		||||
                }
 | 
			
		||||
                return sb.toString();
 | 
			
		||||
            case ',':
 | 
			
		||||
                x.back();
 | 
			
		||||
                return "";
 | 
			
		||||
            default:
 | 
			
		||||
                x.back();
 | 
			
		||||
                return x.nextTo(',');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Produce a JSONArray of strings from a row of comma delimited values.
 | 
			
		||||
     *
 | 
			
		||||
     * @param x A JSONTokener of the source text.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONArray of strings.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static JSONArray rowToJSONArray(final JSONTokener x) throws JSONException {
 | 
			
		||||
        final JSONArray ja = new JSONArray();
 | 
			
		||||
        for (;;) {
 | 
			
		||||
            final String value = getValue(x);
 | 
			
		||||
            char c = x.next();
 | 
			
		||||
            if ((value == null) || ((ja.length() == 0) && (value.length() == 0) && (c != ','))) {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
            ja.put(value);
 | 
			
		||||
            for (;;) {
 | 
			
		||||
                if (c == ',') {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                if (c != ' ') {
 | 
			
		||||
                    if ((c == '\n') || (c == '\r') || (c == 0)) {
 | 
			
		||||
                        return ja;
 | 
			
		||||
                    }
 | 
			
		||||
                    throw x.syntaxError("Bad character '" + c + "' (" + (int) c + ").");
 | 
			
		||||
                }
 | 
			
		||||
                c = x.next();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Produce a JSONObject from a row of comma delimited text, using a parallel JSONArray of strings to provides the
 | 
			
		||||
     * names of the elements.
 | 
			
		||||
     *
 | 
			
		||||
     * @param names A JSONArray of names. This is commonly obtained from the first row of a comma delimited text file
 | 
			
		||||
     *              using the rowToJSONArray method.
 | 
			
		||||
     * @param x     A JSONTokener of the source text.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONObject combining the names and values.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static JSONObject rowToJSONObject(final JSONArray names, final JSONTokener x) throws JSONException {
 | 
			
		||||
        final JSONArray ja = rowToJSONArray(x);
 | 
			
		||||
        return ja != null ? ja.toJSONObject(names) : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Produce a comma delimited text row from a JSONArray. Values containing the comma character will be quoted.
 | 
			
		||||
     * Troublesome characters may be removed.
 | 
			
		||||
     *
 | 
			
		||||
     * @param ja A JSONArray of strings.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A string ending in NEWLINE.
 | 
			
		||||
     */
 | 
			
		||||
    public static String rowToString(final JSONArray ja) {
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        for (int i = 0; i < ja.length(); i += 1) {
 | 
			
		||||
            if (i > 0) {
 | 
			
		||||
                sb.append(',');
 | 
			
		||||
            }
 | 
			
		||||
            final Object object = ja.opt(i);
 | 
			
		||||
            if (object != null) {
 | 
			
		||||
                final String string = object.toString();
 | 
			
		||||
                if ((string.length() > 0) && ((string.indexOf(',') >= 0) || (string.indexOf('\n') >= 0) || (string.indexOf('\r') >= 0) || (string.indexOf(0) >= 0) || (string.charAt(0) == '"'))) {
 | 
			
		||||
                    sb.append('"');
 | 
			
		||||
                    final int length = string.length();
 | 
			
		||||
                    for (int j = 0; j < length; j += 1) {
 | 
			
		||||
                        final char c = string.charAt(j);
 | 
			
		||||
                        if ((c >= ' ') && (c != '"')) {
 | 
			
		||||
                            sb.append(c);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    sb.append('"');
 | 
			
		||||
                } else {
 | 
			
		||||
                    sb.append(string);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        sb.append('\n');
 | 
			
		||||
        return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Produce a JSONArray of JSONObjects from a comma delimited text string, using the first row as a source of names.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string The comma delimited text.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONArray of JSONObjects.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static JSONArray toJSONArray(final String string) throws JSONException {
 | 
			
		||||
        return toJSONArray(new JSONTokener(string));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Produce a JSONArray of JSONObjects from a comma delimited text string, using the first row as a source of names.
 | 
			
		||||
     *
 | 
			
		||||
     * @param x The JSONTokener containing the comma delimited text.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONArray of JSONObjects.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static JSONArray toJSONArray(final JSONTokener x) throws JSONException {
 | 
			
		||||
        return toJSONArray(rowToJSONArray(x), x);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Produce a JSONArray of JSONObjects from a comma delimited text string using a supplied JSONArray as the source of
 | 
			
		||||
     * element names.
 | 
			
		||||
     *
 | 
			
		||||
     * @param names  A JSONArray of strings.
 | 
			
		||||
     * @param string The comma delimited text.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONArray of JSONObjects.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static JSONArray toJSONArray(final JSONArray names, final String string) throws JSONException {
 | 
			
		||||
        return toJSONArray(names, new JSONTokener(string));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Produce a JSONArray of JSONObjects from a comma delimited text string using a supplied JSONArray as the source of
 | 
			
		||||
     * element names.
 | 
			
		||||
     *
 | 
			
		||||
     * @param names A JSONArray of strings.
 | 
			
		||||
     * @param x     A JSONTokener of the source text.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONArray of JSONObjects.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static JSONArray toJSONArray(final JSONArray names, final JSONTokener x) throws JSONException {
 | 
			
		||||
        if ((names == null) || (names.length() == 0)) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        final JSONArray ja = new JSONArray();
 | 
			
		||||
        for (;;) {
 | 
			
		||||
            final JSONObject jo = rowToJSONObject(names, x);
 | 
			
		||||
            if (jo == null) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            ja.put(jo);
 | 
			
		||||
        }
 | 
			
		||||
        if (ja.length() == 0) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        return ja;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Produce a comma delimited text from a JSONArray of JSONObjects. The first row will be a list of names obtained by
 | 
			
		||||
     * inspecting the first JSONObject.
 | 
			
		||||
     *
 | 
			
		||||
     * @param ja A JSONArray of JSONObjects.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A comma delimited text.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static String toString(final JSONArray ja) throws JSONException {
 | 
			
		||||
        final JSONObject jo = ja.optJSONObject(0);
 | 
			
		||||
        if (jo != null) {
 | 
			
		||||
            final JSONArray names = jo.names();
 | 
			
		||||
            if (names != null) {
 | 
			
		||||
                return rowToString(names) + toString(names, ja);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Produce a comma delimited text from a JSONArray of JSONObjects using a provided list of names. The list of names
 | 
			
		||||
     * is not included in the output.
 | 
			
		||||
     *
 | 
			
		||||
     * @param names A JSONArray of strings.
 | 
			
		||||
     * @param ja    A JSONArray of JSONObjects.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A comma delimited text.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static String toString(final JSONArray names, final JSONArray ja) throws JSONException {
 | 
			
		||||
        if ((names == null) || (names.length() == 0)) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        for (int i = 0; i < ja.length(); i += 1) {
 | 
			
		||||
            final JSONObject jo = ja.optJSONObject(i);
 | 
			
		||||
            if (jo != null) {
 | 
			
		||||
                sb.append(rowToString(jo.toJSONArray(names)));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										161
									
								
								src/main/java/com/intellectualcrafters/json/Cookie.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								src/main/java/com/intellectualcrafters/json/Cookie.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,161 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convert a web browser cookie specification to a JSONObject and back. JSON and Cookies are both notations for
 | 
			
		||||
 * name/value pairs.
 | 
			
		||||
 *
 | 
			
		||||
 * @author JSON.org
 | 
			
		||||
 * @version 2014-05-03
 | 
			
		||||
 */
 | 
			
		||||
public class Cookie {
 | 
			
		||||
    /**
 | 
			
		||||
     * Produce a copy of a string in which the characters '+', '%', '=', ';' and control characters are replaced with
 | 
			
		||||
     * "%hh". This is a gentle form of URL encoding, attempting to cause as little distortion to the string as possible.
 | 
			
		||||
     * The characters '=' and ';' are meta characters in cookies. By convention, they are escaped using the
 | 
			
		||||
     * URL-encoding. This is only a convention, not a standard. Often, cookies are expected to have encoded values. We
 | 
			
		||||
     * encode '=' and ';' because we must. We encode '%' and '+' because they are meta characters in URL encoding.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string The source string.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The escaped result.
 | 
			
		||||
     */
 | 
			
		||||
    public static String escape(final String string) {
 | 
			
		||||
        char c;
 | 
			
		||||
        final String s = string.trim();
 | 
			
		||||
        final int length = s.length();
 | 
			
		||||
        final StringBuilder sb = new StringBuilder(length);
 | 
			
		||||
        for (int i = 0; i < length; i += 1) {
 | 
			
		||||
            c = s.charAt(i);
 | 
			
		||||
            if ((c < ' ') || (c == '+') || (c == '%') || (c == '=') || (c == ';')) {
 | 
			
		||||
                sb.append('%');
 | 
			
		||||
                sb.append(Character.forDigit((char) ((c >>> 4) & 0x0f), 16));
 | 
			
		||||
                sb.append(Character.forDigit((char) (c & 0x0f), 16));
 | 
			
		||||
            } else {
 | 
			
		||||
                sb.append(c);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert a cookie specification string into a JSONObject. The string will contain a name value pair separated by
 | 
			
		||||
     * '='. The name and the value will be unescaped, possibly converting '+' and '%' sequences. The cookie properties
 | 
			
		||||
     * may follow, separated by ';', also represented as name=value (except the secure property, which does not have a
 | 
			
		||||
     * value). The name will be stored under the key "name", and the value will be stored under the key "value". This
 | 
			
		||||
     * method does not do checking or validation of the parameters. It only converts the cookie string into a
 | 
			
		||||
     * JSONObject.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string The cookie specification string.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONObject containing "name", "value", and possibly other members.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static JSONObject toJSONObject(final String string) throws JSONException {
 | 
			
		||||
        String name;
 | 
			
		||||
        final JSONObject jo = new JSONObject();
 | 
			
		||||
        Object value;
 | 
			
		||||
        final JSONTokener x = new JSONTokener(string);
 | 
			
		||||
        jo.put("name", x.nextTo('='));
 | 
			
		||||
        x.next('=');
 | 
			
		||||
        jo.put("value", x.nextTo(';'));
 | 
			
		||||
        x.next();
 | 
			
		||||
        while (x.more()) {
 | 
			
		||||
            name = unescape(x.nextTo("=;"));
 | 
			
		||||
            if (x.next() != '=') {
 | 
			
		||||
                if (name.equals("secure")) {
 | 
			
		||||
                    value = Boolean.TRUE;
 | 
			
		||||
                } else {
 | 
			
		||||
                    throw x.syntaxError("Missing '=' in cookie parameter.");
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                value = unescape(x.nextTo(';'));
 | 
			
		||||
                x.next();
 | 
			
		||||
            }
 | 
			
		||||
            jo.put(name, value);
 | 
			
		||||
        }
 | 
			
		||||
        return jo;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert a JSONObject into a cookie specification string. The JSONObject must contain "name" and "value" members.
 | 
			
		||||
     * If the JSONObject contains "expires", "domain", "path", or "secure" members, they will be appended to the cookie
 | 
			
		||||
     * specification string. All other members are ignored.
 | 
			
		||||
     *
 | 
			
		||||
     * @param jo A JSONObject
 | 
			
		||||
     *
 | 
			
		||||
     * @return A cookie specification string
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static String toString(final JSONObject jo) throws JSONException {
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        sb.append(escape(jo.getString("name")));
 | 
			
		||||
        sb.append("=");
 | 
			
		||||
        sb.append(escape(jo.getString("value")));
 | 
			
		||||
        if (jo.has("expires")) {
 | 
			
		||||
            sb.append(";expires=");
 | 
			
		||||
            sb.append(jo.getString("expires"));
 | 
			
		||||
        }
 | 
			
		||||
        if (jo.has("domain")) {
 | 
			
		||||
            sb.append(";domain=");
 | 
			
		||||
            sb.append(escape(jo.getString("domain")));
 | 
			
		||||
        }
 | 
			
		||||
        if (jo.has("path")) {
 | 
			
		||||
            sb.append(";path=");
 | 
			
		||||
            sb.append(escape(jo.getString("path")));
 | 
			
		||||
        }
 | 
			
		||||
        if (jo.optBoolean("secure")) {
 | 
			
		||||
            sb.append(";secure");
 | 
			
		||||
        }
 | 
			
		||||
        return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert <code>%</code><i>hh</i> sequences to single characters, and convert plus to space.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string A string that may contain <code>+</code>  <small>(plus)</small> and <code>%</code><i>hh</i>
 | 
			
		||||
     *               sequences.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The unescaped string.
 | 
			
		||||
     */
 | 
			
		||||
    public static String unescape(final String string) {
 | 
			
		||||
        final int length = string.length();
 | 
			
		||||
        final StringBuilder sb = new StringBuilder(length);
 | 
			
		||||
        for (int i = 0; i < length; ++i) {
 | 
			
		||||
            char c = string.charAt(i);
 | 
			
		||||
            if (c == '+') {
 | 
			
		||||
                c = ' ';
 | 
			
		||||
            } else if ((c == '%') && ((i + 2) < length)) {
 | 
			
		||||
                final int d = JSONTokener.dehexchar(string.charAt(i + 1));
 | 
			
		||||
                final int e = JSONTokener.dehexchar(string.charAt(i + 2));
 | 
			
		||||
                if ((d >= 0) && (e >= 0)) {
 | 
			
		||||
                    c = (char) ((d * 16) + e);
 | 
			
		||||
                    i += 2;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            sb.append(c);
 | 
			
		||||
        }
 | 
			
		||||
        return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										68
									
								
								src/main/java/com/intellectualcrafters/json/CookieList.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/main/java/com/intellectualcrafters/json/CookieList.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convert a web browser cookie list string to a JSONObject and back.
 | 
			
		||||
 *
 | 
			
		||||
 * @author JSON.org
 | 
			
		||||
 * @version 2014-05-03
 | 
			
		||||
 */
 | 
			
		||||
public class CookieList {
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert a cookie list into a JSONObject. A cookie list is a sequence of name/value pairs. The names are separated
 | 
			
		||||
     * from the values by '='. The pairs are separated by ';'. The names and the values will be unescaped, possibly
 | 
			
		||||
     * converting '+' and '%' sequences.
 | 
			
		||||
     * 
 | 
			
		||||
     * To add a cookie to a cooklist, cookielistJSONObject.put(cookieJSONObject.getString("name"),
 | 
			
		||||
     * cookieJSONObject.getString("value"));
 | 
			
		||||
     *
 | 
			
		||||
     * @param string A cookie list string
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONObject
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static JSONObject toJSONObject(final String string) throws JSONException {
 | 
			
		||||
        final JSONObject jo = new JSONObject();
 | 
			
		||||
        final JSONTokener x = new JSONTokener(string);
 | 
			
		||||
        while (x.more()) {
 | 
			
		||||
            final String name = Cookie.unescape(x.nextTo('='));
 | 
			
		||||
            x.next('=');
 | 
			
		||||
            jo.put(name, Cookie.unescape(x.nextTo(';')));
 | 
			
		||||
            x.next();
 | 
			
		||||
        }
 | 
			
		||||
        return jo;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert a JSONObject into a cookie list. A cookie list is a sequence of name/value pairs. The names are separated
 | 
			
		||||
     * from the values by '='. The pairs are separated by ';'. The characters '%', '+', '=', and ';' in the names and
 | 
			
		||||
     * values are replaced by "%hh".
 | 
			
		||||
     *
 | 
			
		||||
     * @param jo A JSONObject
 | 
			
		||||
     *
 | 
			
		||||
     * @return A cookie list string
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static String toString(final JSONObject jo) throws JSONException {
 | 
			
		||||
        boolean b = false;
 | 
			
		||||
        final Iterator<String> keys = jo.keys();
 | 
			
		||||
        String string;
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        while (keys.hasNext()) {
 | 
			
		||||
            string = keys.next();
 | 
			
		||||
            if (!jo.isNull(string)) {
 | 
			
		||||
                if (b) {
 | 
			
		||||
                    sb.append(';');
 | 
			
		||||
                }
 | 
			
		||||
                sb.append(Cookie.escape(string));
 | 
			
		||||
                sb.append("=");
 | 
			
		||||
                sb.append(Cookie.escape(jo.getString(string)));
 | 
			
		||||
                b = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										129
									
								
								src/main/java/com/intellectualcrafters/json/HTTP.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								src/main/java/com/intellectualcrafters/json/HTTP.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,129 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convert an HTTP header to a JSONObject and back.
 | 
			
		||||
 *
 | 
			
		||||
 * @author JSON.org
 | 
			
		||||
 * @version 2014-05-03
 | 
			
		||||
 */
 | 
			
		||||
public class HTTP {
 | 
			
		||||
    /**
 | 
			
		||||
     * Carriage return/line feed.
 | 
			
		||||
     */
 | 
			
		||||
    public static final String CRLF = "\r\n";
 | 
			
		||||
 | 
			
		||||
    public static JSONObject toJSONObject(final String string) throws JSONException {
 | 
			
		||||
        final JSONObject jo = new JSONObject();
 | 
			
		||||
        final HTTPTokener x = new HTTPTokener(string);
 | 
			
		||||
        String token;
 | 
			
		||||
        token = x.nextToken();
 | 
			
		||||
        if (token.toUpperCase().startsWith("HTTP")) {
 | 
			
		||||
            // Response
 | 
			
		||||
            jo.put("HTTP-Version", token);
 | 
			
		||||
            jo.put("Status-Code", x.nextToken());
 | 
			
		||||
            jo.put("Reason-Phrase", x.nextTo('\0'));
 | 
			
		||||
            x.next();
 | 
			
		||||
        } else {
 | 
			
		||||
            // Request
 | 
			
		||||
            jo.put("Method", token);
 | 
			
		||||
            jo.put("Request-URI", x.nextToken());
 | 
			
		||||
            jo.put("HTTP-Version", x.nextToken());
 | 
			
		||||
        }
 | 
			
		||||
        // Fields
 | 
			
		||||
        while (x.more()) {
 | 
			
		||||
            final String name = x.nextTo(':');
 | 
			
		||||
            x.next(':');
 | 
			
		||||
            jo.put(name, x.nextTo('\0'));
 | 
			
		||||
            x.next();
 | 
			
		||||
        }
 | 
			
		||||
        return jo;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert a JSONObject into an HTTP header. A request header must contain
 | 
			
		||||
     * 
 | 
			
		||||
     * 
 | 
			
		||||
     * <pre>
 | 
			
		||||
     * {
 | 
			
		||||
     *    Method: "POST" (for example),
 | 
			
		||||
     *    "Request-URI": "/" (for example),
 | 
			
		||||
     *    "HTTP-Version": "HTTP/1.1" (for example)
 | 
			
		||||
     * }
 | 
			
		||||
     * </pre>
 | 
			
		||||
     * 
 | 
			
		||||
     * A response header must contain
 | 
			
		||||
     * 
 | 
			
		||||
     * 
 | 
			
		||||
     * <pre>
 | 
			
		||||
     * {
 | 
			
		||||
     *    "HTTP-Version": "HTTP/1.1" (for example),
 | 
			
		||||
     *    "Status-Code": "200" (for example),
 | 
			
		||||
     *    "Reason-Phrase": "OK" (for example)
 | 
			
		||||
     * }
 | 
			
		||||
     * </pre>
 | 
			
		||||
     * 
 | 
			
		||||
     * Any other members of the JSONObject will be output as HTTP fields. The result will end with two CRLF pairs.
 | 
			
		||||
     *
 | 
			
		||||
     * @param jo A JSONObject
 | 
			
		||||
     *
 | 
			
		||||
     * @return An HTTP header string.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException if the object does not contain enough information.
 | 
			
		||||
     */
 | 
			
		||||
    public static String toString(final JSONObject jo) throws JSONException {
 | 
			
		||||
        final Iterator<String> keys = jo.keys();
 | 
			
		||||
        String string;
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        if (jo.has("Status-Code") && jo.has("Reason-Phrase")) {
 | 
			
		||||
            sb.append(jo.getString("HTTP-Version"));
 | 
			
		||||
            sb.append(' ');
 | 
			
		||||
            sb.append(jo.getString("Status-Code"));
 | 
			
		||||
            sb.append(' ');
 | 
			
		||||
            sb.append(jo.getString("Reason-Phrase"));
 | 
			
		||||
        } else if (jo.has("Method") && jo.has("Request-URI")) {
 | 
			
		||||
            sb.append(jo.getString("Method"));
 | 
			
		||||
            sb.append(' ');
 | 
			
		||||
            sb.append('"');
 | 
			
		||||
            sb.append(jo.getString("Request-URI"));
 | 
			
		||||
            sb.append('"');
 | 
			
		||||
            sb.append(' ');
 | 
			
		||||
            sb.append(jo.getString("HTTP-Version"));
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new JSONException("Not enough material for an HTTP header.");
 | 
			
		||||
        }
 | 
			
		||||
        sb.append(CRLF);
 | 
			
		||||
        while (keys.hasNext()) {
 | 
			
		||||
            string = keys.next();
 | 
			
		||||
            if (!"HTTP-Version".equals(string) && !"Status-Code".equals(string) && !"Reason-Phrase".equals(string) && !"Method".equals(string) && !"Request-URI".equals(string) && !jo.isNull(string)) {
 | 
			
		||||
                sb.append(string);
 | 
			
		||||
                sb.append(": ");
 | 
			
		||||
                sb.append(jo.getString(string));
 | 
			
		||||
                sb.append(CRLF);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        sb.append(CRLF);
 | 
			
		||||
        return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								src/main/java/com/intellectualcrafters/json/HTTPTokener.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/main/java/com/intellectualcrafters/json/HTTPTokener.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The HTTPTokener extends the JSONTokener to provide additional methods for the parsing of HTTP headers.
 | 
			
		||||
 *
 | 
			
		||||
 * @author JSON.org
 | 
			
		||||
 * @version 2014-05-03
 | 
			
		||||
 */
 | 
			
		||||
public class HTTPTokener extends JSONTokener {
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct an HTTPTokener from a string.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string A source string.
 | 
			
		||||
     */
 | 
			
		||||
    public HTTPTokener(final String string) {
 | 
			
		||||
        super(string);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the next token or string. This is used in parsing HTTP headers.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A String.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public String nextToken() throws JSONException {
 | 
			
		||||
        char c;
 | 
			
		||||
        char q;
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        do {
 | 
			
		||||
            c = next();
 | 
			
		||||
        } while (Character.isWhitespace(c));
 | 
			
		||||
        if ((c == '"') || (c == '\'')) {
 | 
			
		||||
            q = c;
 | 
			
		||||
            for (;;) {
 | 
			
		||||
                c = next();
 | 
			
		||||
                if (c < ' ') {
 | 
			
		||||
                    throw syntaxError("Unterminated string.");
 | 
			
		||||
                }
 | 
			
		||||
                if (c == q) {
 | 
			
		||||
                    return sb.toString();
 | 
			
		||||
                }
 | 
			
		||||
                sb.append(c);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        for (;;) {
 | 
			
		||||
            if ((c == 0) || Character.isWhitespace(c)) {
 | 
			
		||||
                return sb.toString();
 | 
			
		||||
            }
 | 
			
		||||
            sb.append(c);
 | 
			
		||||
            c = next();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										881
									
								
								src/main/java/com/intellectualcrafters/json/JSONArray.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										881
									
								
								src/main/java/com/intellectualcrafters/json/JSONArray.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,881 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.StringWriter;
 | 
			
		||||
import java.io.Writer;
 | 
			
		||||
import java.lang.reflect.Array;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A JSONArray is an ordered sequence of values. Its external text form is a string wrapped in square brackets with
 | 
			
		||||
 * commas separating the values. The internal form is an object having <code>get</code> and <code>opt</code> methods for
 | 
			
		||||
 * accessing the values by index, and <code>put</code> methods for adding or replacing values. The values can be any of
 | 
			
		||||
 * these types: <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>, <code>Number</code>,
 | 
			
		||||
 * <code>String</code>, or the <code>JSONObject.NULL object</code>.
 | 
			
		||||
 * 
 | 
			
		||||
 * The constructor can convert a JSON text into a Java object. The <code>toString</code> method converts to JSON text.
 | 
			
		||||
 * 
 | 
			
		||||
 * A <code>get</code> method returns a value if one can be found, and throws an exception if one cannot be found. An
 | 
			
		||||
 * <code>opt</code> method returns a default value instead of throwing an exception, and so is useful for obtaining
 | 
			
		||||
 * optional values.
 | 
			
		||||
 * 
 | 
			
		||||
 * The generic <code>get()</code> and <code>opt()</code> methods return an object which you can cast or query for type.
 | 
			
		||||
 * There are also typed <code>get</code> and <code>opt</code> methods that do type checking and type coercion for you.
 | 
			
		||||
 * 
 | 
			
		||||
 * The texts produced by the <code>toString</code> methods strictly conform to JSON syntax rules. The constructors are
 | 
			
		||||
 * more forgiving in the texts they will accept: <ul> <li>An extra <code>,</code> <small>(comma)</small> may appear
 | 
			
		||||
 * just before the closing bracket.</li> <li>The <code>null</code> value will be inserted when there is <code>,</code>
 | 
			
		||||
 *  <small>(comma)</small> elision.</li> <li>Strings may be quoted with <code>'</code> <small>(single
 | 
			
		||||
 * quote)</small>.</li> <li>Strings do not need to be quoted at all if they do not begin with a quote or single quote,
 | 
			
		||||
 * and if they do not contain leading or trailing spaces, and if they do not contain any of these characters: <code>{ }
 | 
			
		||||
 * [ ] / \ : , #</code> and if they do not look like numbers and if they are not the reserved words <code>true</code>,
 | 
			
		||||
 * <code>false</code>, or <code>null</code>.</li> </ul>
 | 
			
		||||
 *
 | 
			
		||||
 * @author JSON.org
 | 
			
		||||
 * @version 2014-05-03
 | 
			
		||||
 */
 | 
			
		||||
public class JSONArray {
 | 
			
		||||
    /**
 | 
			
		||||
     * The arrayList where the JSONArray's properties are kept.
 | 
			
		||||
     */
 | 
			
		||||
    private final ArrayList<Object> myArrayList;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct an empty JSONArray.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray() {
 | 
			
		||||
        this.myArrayList = new ArrayList<Object>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct a JSONArray from a JSONTokener.
 | 
			
		||||
     *
 | 
			
		||||
     * @param x A JSONTokener
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If there is a syntax error.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray(final JSONTokener x) throws JSONException {
 | 
			
		||||
        this();
 | 
			
		||||
        if (x.nextClean() != '[') {
 | 
			
		||||
            throw x.syntaxError("A JSONArray text must start with '['");
 | 
			
		||||
        }
 | 
			
		||||
        if (x.nextClean() != ']') {
 | 
			
		||||
            x.back();
 | 
			
		||||
            for (;;) {
 | 
			
		||||
                if (x.nextClean() == ',') {
 | 
			
		||||
                    x.back();
 | 
			
		||||
                    this.myArrayList.add(JSONObject.NULL);
 | 
			
		||||
                } else {
 | 
			
		||||
                    x.back();
 | 
			
		||||
                    this.myArrayList.add(x.nextValue());
 | 
			
		||||
                }
 | 
			
		||||
                switch (x.nextClean()) {
 | 
			
		||||
                    case ',':
 | 
			
		||||
                        if (x.nextClean() == ']') {
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                        x.back();
 | 
			
		||||
                        break;
 | 
			
		||||
                    case ']':
 | 
			
		||||
                        return;
 | 
			
		||||
                    default:
 | 
			
		||||
                        throw x.syntaxError("Expected a ',' or ']'");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct a JSONArray from a source JSON text.
 | 
			
		||||
     *
 | 
			
		||||
     * @param source A string that begins with <code>[</code> <small>(left bracket)</small> and ends with
 | 
			
		||||
     *               <code>]</code>  <small>(right bracket)</small>.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If there is a syntax error.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray(final String source) throws JSONException {
 | 
			
		||||
        this(new JSONTokener(source));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct a JSONArray from a Collection.
 | 
			
		||||
     *
 | 
			
		||||
     * @param collection A Collection.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray(final Collection<Object> collection) {
 | 
			
		||||
        this.myArrayList = new ArrayList<Object>();
 | 
			
		||||
        if (collection != null) {
 | 
			
		||||
            for (final Object aCollection : collection) {
 | 
			
		||||
                this.myArrayList.add(JSONObject.wrap(aCollection));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct a JSONArray from an array
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If not an array.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray(final Object array) throws JSONException {
 | 
			
		||||
        this();
 | 
			
		||||
        if (array.getClass().isArray()) {
 | 
			
		||||
            final int length = Array.getLength(array);
 | 
			
		||||
            for (int i = 0; i < length; i += 1) {
 | 
			
		||||
                this.put(JSONObject.wrap(Array.get(array, i)));
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new JSONException("JSONArray initial value should be a string or collection or array.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the object value associated with an index.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return An object value.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If there is no value for the index.
 | 
			
		||||
     */
 | 
			
		||||
    public Object get(final int index) throws JSONException {
 | 
			
		||||
        final Object object = this.opt(index);
 | 
			
		||||
        if (object == null) {
 | 
			
		||||
            throw new JSONException("JSONArray[" + index + "] not found.");
 | 
			
		||||
        }
 | 
			
		||||
        return object;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the boolean value associated with an index. The string values "true" and "false" are converted to boolean.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The truth.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If there is no value for the index or if the value is not convertible to boolean.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean getBoolean(final int index) throws JSONException {
 | 
			
		||||
        final Object object = this.get(index);
 | 
			
		||||
        if (object.equals(Boolean.FALSE) || ((object instanceof String) && ((String) object).equalsIgnoreCase("false"))) {
 | 
			
		||||
            return false;
 | 
			
		||||
        } else if (object.equals(Boolean.TRUE) || ((object instanceof String) && ((String) object).equalsIgnoreCase("true"))) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        throw new JSONException("JSONArray[" + index + "] is not a boolean.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the double value associated with an index.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The value.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the key is not found or if the value cannot be converted to a number.
 | 
			
		||||
     */
 | 
			
		||||
    public double getDouble(final int index) throws JSONException {
 | 
			
		||||
        final Object object = this.get(index);
 | 
			
		||||
        try {
 | 
			
		||||
            return object instanceof Number ? ((Number) object).doubleValue() : Double.parseDouble((String) object);
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            throw new JSONException("JSONArray[" + index + "] is not a number.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the int value associated with an index.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The value.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the key is not found or if the value is not a number.
 | 
			
		||||
     */
 | 
			
		||||
    public int getInt(final int index) throws JSONException {
 | 
			
		||||
        final Object object = this.get(index);
 | 
			
		||||
        try {
 | 
			
		||||
            return object instanceof Number ? ((Number) object).intValue() : Integer.parseInt((String) object);
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            throw new JSONException("JSONArray[" + index + "] is not a number.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the JSONArray associated with an index.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONArray value.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If there is no value for the index. or if the value is not a JSONArray
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray getJSONArray(final int index) throws JSONException {
 | 
			
		||||
        final Object object = this.get(index);
 | 
			
		||||
        if (object instanceof JSONArray) {
 | 
			
		||||
            return (JSONArray) object;
 | 
			
		||||
        }
 | 
			
		||||
        throw new JSONException("JSONArray[" + index + "] is not a JSONArray.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the JSONObject associated with an index.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index subscript
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONObject value.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If there is no value for the index or if the value is not a JSONObject
 | 
			
		||||
     */
 | 
			
		||||
    public JSONObject getJSONObject(final int index) throws JSONException {
 | 
			
		||||
        final Object object = this.get(index);
 | 
			
		||||
        if (object instanceof JSONObject) {
 | 
			
		||||
            return (JSONObject) object;
 | 
			
		||||
        }
 | 
			
		||||
        throw new JSONException("JSONArray[" + index + "] is not a JSONObject.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the long value associated with an index.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The value.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the key is not found or if the value cannot be converted to a number.
 | 
			
		||||
     */
 | 
			
		||||
    public long getLong(final int index) throws JSONException {
 | 
			
		||||
        final Object object = this.get(index);
 | 
			
		||||
        try {
 | 
			
		||||
            return object instanceof Number ? ((Number) object).longValue() : Long.parseLong((String) object);
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            throw new JSONException("JSONArray[" + index + "] is not a number.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the string associated with an index.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A string value.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If there is no string value for the index.
 | 
			
		||||
     */
 | 
			
		||||
    public String getString(final int index) throws JSONException {
 | 
			
		||||
        final Object object = this.get(index);
 | 
			
		||||
        if (object instanceof String) {
 | 
			
		||||
            return (String) object;
 | 
			
		||||
        }
 | 
			
		||||
        throw new JSONException("JSONArray[" + index + "] not a string.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Determine if the value is null.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if the value at the index is null, or if there is no value.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isNull(final int index) {
 | 
			
		||||
        return JSONObject.NULL.equals(this.opt(index));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Make a string from the contents of this JSONArray. The <code>separator</code> string is inserted between each
 | 
			
		||||
     * element. Warning: This method assumes that the data structure is acyclical.
 | 
			
		||||
     *
 | 
			
		||||
     * @param separator A string that will be inserted between the elements.
 | 
			
		||||
     *
 | 
			
		||||
     * @return a string.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the array contains an invalid number.
 | 
			
		||||
     */
 | 
			
		||||
    public String join(final String separator) throws JSONException {
 | 
			
		||||
        final int len = this.length();
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        for (int i = 0; i < len; i += 1) {
 | 
			
		||||
            if (i > 0) {
 | 
			
		||||
                sb.append(separator);
 | 
			
		||||
            }
 | 
			
		||||
            sb.append(JSONObject.valueToString(this.myArrayList.get(i)));
 | 
			
		||||
        }
 | 
			
		||||
        return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of elements in the JSONArray, included nulls.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The length (or size).
 | 
			
		||||
     */
 | 
			
		||||
    public int length() {
 | 
			
		||||
        return this.myArrayList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the optional object value associated with an index.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return An object value, or null if there is no object at that index.
 | 
			
		||||
     */
 | 
			
		||||
    public Object opt(final int index) {
 | 
			
		||||
        return ((index < 0) || (index >= this.length())) ? null : this.myArrayList.get(index);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the optional boolean value associated with an index. It returns false if there is no value at that index, or
 | 
			
		||||
     * if the value is not Boolean.TRUE or the String "true".
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The truth.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean optBoolean(final int index) {
 | 
			
		||||
        return this.optBoolean(index, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the optional boolean value associated with an index. It returns the defaultValue if there is no value at that
 | 
			
		||||
     * index or if it is not a Boolean or the String "true" or "false" (case insensitive).
 | 
			
		||||
     *
 | 
			
		||||
     * @param index        The index must be between 0 and length() - 1.
 | 
			
		||||
     * @param defaultValue A boolean default.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The truth.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean optBoolean(final int index, final boolean defaultValue) {
 | 
			
		||||
        try {
 | 
			
		||||
            return this.getBoolean(index);
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            return defaultValue;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the optional double value associated with an index. NaN is returned if there is no value for the index, or if
 | 
			
		||||
     * the value is not a number and cannot be converted to a number.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The value.
 | 
			
		||||
     */
 | 
			
		||||
    public double optDouble(final int index) {
 | 
			
		||||
        return this.optDouble(index, Double.NaN);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the optional double value associated with an index. The defaultValue is returned if there is no value for the
 | 
			
		||||
     * index, or if the value is not a number and cannot be converted to a number.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index        subscript
 | 
			
		||||
     * @param defaultValue The default value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The value.
 | 
			
		||||
     */
 | 
			
		||||
    public double optDouble(final int index, final double defaultValue) {
 | 
			
		||||
        try {
 | 
			
		||||
            return this.getDouble(index);
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            return defaultValue;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the optional int value associated with an index. Zero is returned if there is no value for the index, or if
 | 
			
		||||
     * the value is not a number and cannot be converted to a number.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The value.
 | 
			
		||||
     */
 | 
			
		||||
    public int optInt(final int index) {
 | 
			
		||||
        return this.optInt(index, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the optional int value associated with an index. The defaultValue is returned if there is no value for the
 | 
			
		||||
     * index, or if the value is not a number and cannot be converted to a number.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index        The index must be between 0 and length() - 1.
 | 
			
		||||
     * @param defaultValue The default value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The value.
 | 
			
		||||
     */
 | 
			
		||||
    public int optInt(final int index, final int defaultValue) {
 | 
			
		||||
        try {
 | 
			
		||||
            return this.getInt(index);
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            return defaultValue;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the optional JSONArray associated with an index.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index subscript
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONArray value, or null if the index has no value, or if the value is not a JSONArray.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray optJSONArray(final int index) {
 | 
			
		||||
        final Object o = this.opt(index);
 | 
			
		||||
        return o instanceof JSONArray ? (JSONArray) o : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the optional JSONObject associated with an index. Null is returned if the key is not found, or null if the
 | 
			
		||||
     * index has no value, or if the value is not a JSONObject.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONObject value.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONObject optJSONObject(final int index) {
 | 
			
		||||
        final Object o = this.opt(index);
 | 
			
		||||
        return o instanceof JSONObject ? (JSONObject) o : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the optional long value associated with an index. Zero is returned if there is no value for the index, or if
 | 
			
		||||
     * the value is not a number and cannot be converted to a number.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The value.
 | 
			
		||||
     */
 | 
			
		||||
    public long optLong(final int index) {
 | 
			
		||||
        return this.optLong(index, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the optional long value associated with an index. The defaultValue is returned if there is no value for the
 | 
			
		||||
     * index, or if the value is not a number and cannot be converted to a number.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index        The index must be between 0 and length() - 1.
 | 
			
		||||
     * @param defaultValue The default value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The value.
 | 
			
		||||
     */
 | 
			
		||||
    public long optLong(final int index, final long defaultValue) {
 | 
			
		||||
        try {
 | 
			
		||||
            return this.getLong(index);
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            return defaultValue;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the optional string value associated with an index. It returns an empty string if there is no value at that
 | 
			
		||||
     * index. If the value is not a string and is not null, then it is coverted to a string.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index must be between 0 and length() - 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A String value.
 | 
			
		||||
     */
 | 
			
		||||
    public String optString(final int index) {
 | 
			
		||||
        return this.optString(index, "");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the optional string associated with an index. The defaultValue is returned if the key is not found.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index        The index must be between 0 and length() - 1.
 | 
			
		||||
     * @param defaultValue The default value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A String value.
 | 
			
		||||
     */
 | 
			
		||||
    public String optString(final int index, final String defaultValue) {
 | 
			
		||||
        final Object object = this.opt(index);
 | 
			
		||||
        return JSONObject.NULL.equals(object) ? defaultValue : object.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Append a boolean value. This increases the array's length by one.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value A boolean value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray put(final boolean value) {
 | 
			
		||||
        this.put(value ? Boolean.TRUE : Boolean.FALSE);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put a value in the JSONArray, where the value will be a JSONArray which is produced from a Collection.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value A Collection value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray put(final Collection<Object> value) {
 | 
			
		||||
        this.put(new JSONArray(value));
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Append a double value. This increases the array's length by one.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value A double value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException if the value is not finite.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray put(final double value) throws JSONException {
 | 
			
		||||
        final Double d = value;
 | 
			
		||||
        JSONObject.testValidity(d);
 | 
			
		||||
        this.put(d);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Append an int value. This increases the array's length by one.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value An int value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray put(final int value) {
 | 
			
		||||
        this.put(new Integer(value));
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Append an long value. This increases the array's length by one.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value A long value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray put(final long value) {
 | 
			
		||||
        this.put(new Long(value));
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put a value in the JSONArray, where the value will be a JSONObject which is produced from a Map.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value A Map value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray put(final Map<String, Object> value) {
 | 
			
		||||
        this.put(new JSONObject(value));
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Append an object value. This increases the array's length by one.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value An object value. The value should be a Boolean, Double, Integer, JSONArray, JSONObject, Long, or
 | 
			
		||||
     *              String, or the JSONObject.NULL object.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray put(final Object value) {
 | 
			
		||||
        this.myArrayList.add(value);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put or replace a boolean value in the JSONArray. If the index is greater than the length of the JSONArray, then
 | 
			
		||||
     * null elements will be added as necessary to pad it out.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The subscript.
 | 
			
		||||
     * @param value A boolean value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the index is negative.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray put(final int index, final boolean value) throws JSONException {
 | 
			
		||||
        this.put(index, value ? Boolean.TRUE : Boolean.FALSE);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put a value in the JSONArray, where the value will be a JSONArray which is produced from a Collection.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The subscript.
 | 
			
		||||
     * @param value A Collection value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the index is negative or if the value is not finite.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray put(final int index, final Collection<Object> value) throws JSONException {
 | 
			
		||||
        this.put(index, new JSONArray(value));
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put or replace a double value. If the index is greater than the length of the JSONArray, then null elements will
 | 
			
		||||
     * be added as necessary to pad it out.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The subscript.
 | 
			
		||||
     * @param value A double value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the index is negative or if the value is not finite.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray put(final int index, final double value) throws JSONException {
 | 
			
		||||
        this.put(index, new Double(value));
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put or replace an int value. If the index is greater than the length of the JSONArray, then null elements will be
 | 
			
		||||
     * added as necessary to pad it out.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The subscript.
 | 
			
		||||
     * @param value An int value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the index is negative.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray put(final int index, final int value) throws JSONException {
 | 
			
		||||
        this.put(index, new Integer(value));
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put or replace a long value. If the index is greater than the length of the JSONArray, then null elements will be
 | 
			
		||||
     * added as necessary to pad it out.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The subscript.
 | 
			
		||||
     * @param value A long value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the index is negative.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray put(final int index, final long value) throws JSONException {
 | 
			
		||||
        this.put(index, new Long(value));
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put a value in the JSONArray, where the value will be a JSONObject that is produced from a Map.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The subscript.
 | 
			
		||||
     * @param value The Map value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the index is negative or if the the value is an invalid number.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray put(final int index, final Map<String, Object> value) throws JSONException {
 | 
			
		||||
        this.put(index, new JSONObject(value));
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Put or replace an object value in the JSONArray. If the index is greater than the length of the JSONArray, then
 | 
			
		||||
     * null elements will be added as necessary to pad it out.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The subscript.
 | 
			
		||||
     * @param value The value to put into the array. The value should be a Boolean, Double, Integer, JSONArray,
 | 
			
		||||
     *              JSONObject, Long, or String, or the JSONObject.NULL object.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the index is negative or if the the value is an invalid number.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONArray put(final int index, final Object value) throws JSONException {
 | 
			
		||||
        JSONObject.testValidity(value);
 | 
			
		||||
        if (index < 0) {
 | 
			
		||||
            throw new JSONException("JSONArray[" + index + "] not found.");
 | 
			
		||||
        }
 | 
			
		||||
        if (index < this.length()) {
 | 
			
		||||
            this.myArrayList.set(index, value);
 | 
			
		||||
        } else {
 | 
			
		||||
            while (index != this.length()) {
 | 
			
		||||
                this.put(JSONObject.NULL);
 | 
			
		||||
            }
 | 
			
		||||
            this.put(value);
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Remove an index and close the hole.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index of the element to be removed.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The value that was associated with the index, or null if there was no value.
 | 
			
		||||
     */
 | 
			
		||||
    public Object remove(final int index) {
 | 
			
		||||
        return (index >= 0) && (index < this.length()) ? this.myArrayList.remove(index) : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Determine if two JSONArrays are similar. They must contain similar sequences.
 | 
			
		||||
     *
 | 
			
		||||
     * @param other The other JSONArray
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if they are equal
 | 
			
		||||
     */
 | 
			
		||||
    public boolean similar(final Object other) {
 | 
			
		||||
        if (!(other instanceof JSONArray)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final int len = this.length();
 | 
			
		||||
        if (len != ((JSONArray) other).length()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        for (int i = 0; i < len; i += 1) {
 | 
			
		||||
            final Object valueThis = this.get(i);
 | 
			
		||||
            final Object valueOther = ((JSONArray) other).get(i);
 | 
			
		||||
            if (valueThis instanceof JSONObject) {
 | 
			
		||||
                if (!((JSONObject) valueThis).similar(valueOther)) {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (valueThis instanceof JSONArray) {
 | 
			
		||||
                if (!((JSONArray) valueThis).similar(valueOther)) {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (!valueThis.equals(valueOther)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Produce a JSONObject by combining a JSONArray of names with the values of this JSONArray.
 | 
			
		||||
     *
 | 
			
		||||
     * @param names A JSONArray containing a list of key strings. These will be paired with the values.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONObject, or null if there are no names or if this JSONArray has no values.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If any of the names are null.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONObject toJSONObject(final JSONArray names) throws JSONException {
 | 
			
		||||
        if ((names == null) || (names.length() == 0) || (this.length() == 0)) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        final JSONObject jo = new JSONObject();
 | 
			
		||||
        for (int i = 0; i < names.length(); i += 1) {
 | 
			
		||||
            jo.put(names.getString(i), this.opt(i));
 | 
			
		||||
        }
 | 
			
		||||
        return jo;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Make a JSON text of this JSONArray. For compactness, no unnecessary whitespace is added. If it is not possible to
 | 
			
		||||
     * produce a syntactically correct JSON text then null will be returned instead. This could occur if the array
 | 
			
		||||
     * contains an invalid number.
 | 
			
		||||
     * 
 | 
			
		||||
     * Warning: This method assumes that the data structure is acyclical.
 | 
			
		||||
     *
 | 
			
		||||
     * @return a printable, displayable, transmittable representation of the array.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        try {
 | 
			
		||||
            return this.toString(0);
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Make a prettyprinted JSON text of this JSONArray. Warning: This method assumes that the data structure is
 | 
			
		||||
     * acyclical.
 | 
			
		||||
     *
 | 
			
		||||
     * @param indentFactor The number of spaces to add to each level of indentation.
 | 
			
		||||
     *
 | 
			
		||||
     * @return a printable, displayable, transmittable representation of the object, beginning with
 | 
			
		||||
     * <code>[</code> <small>(left bracket)</small> and ending with <code>]</code>  <small>(right
 | 
			
		||||
     * bracket)</small>.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public String toString(final int indentFactor) throws JSONException {
 | 
			
		||||
        final StringWriter sw = new StringWriter();
 | 
			
		||||
        synchronized (sw.getBuffer()) {
 | 
			
		||||
            return this.write(sw, indentFactor, 0).toString();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Write the contents of the JSONArray as JSON text to a writer. For compactness, no whitespace is added.
 | 
			
		||||
     * 
 | 
			
		||||
     * Warning: This method assumes that the data structure is acyclical.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The writer.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public Writer write(final Writer writer) throws JSONException {
 | 
			
		||||
        return this.write(writer, 0, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Write the contents of the JSONArray as JSON text to a writer. For compactness, no whitespace is added.
 | 
			
		||||
     * 
 | 
			
		||||
     * Warning: This method assumes that the data structure is acyclical.
 | 
			
		||||
     *
 | 
			
		||||
     * @param indentFactor The number of spaces to add to each level of indentation.
 | 
			
		||||
     * @param indent       The indention of the top level.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The writer.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    Writer write(final Writer writer, final int indentFactor, final int indent) throws JSONException {
 | 
			
		||||
        try {
 | 
			
		||||
            boolean commanate = false;
 | 
			
		||||
            final int length = this.length();
 | 
			
		||||
            writer.write('[');
 | 
			
		||||
            if (length == 1) {
 | 
			
		||||
                JSONObject.writeValue(writer, this.myArrayList.get(0), indentFactor, indent);
 | 
			
		||||
            } else if (length != 0) {
 | 
			
		||||
                final int newindent = indent + indentFactor;
 | 
			
		||||
                for (int i = 0; i < length; i += 1) {
 | 
			
		||||
                    if (commanate) {
 | 
			
		||||
                        writer.write(',');
 | 
			
		||||
                    }
 | 
			
		||||
                    if (indentFactor > 0) {
 | 
			
		||||
                        writer.write('\n');
 | 
			
		||||
                    }
 | 
			
		||||
                    JSONObject.indent(writer, newindent);
 | 
			
		||||
                    JSONObject.writeValue(writer, this.myArrayList.get(i), indentFactor, newindent);
 | 
			
		||||
                    commanate = true;
 | 
			
		||||
                }
 | 
			
		||||
                if (indentFactor > 0) {
 | 
			
		||||
                    writer.write('\n');
 | 
			
		||||
                }
 | 
			
		||||
                JSONObject.indent(writer, indent);
 | 
			
		||||
            }
 | 
			
		||||
            writer.write(']');
 | 
			
		||||
            return writer;
 | 
			
		||||
        } catch (final IOException e) {
 | 
			
		||||
            throw new JSONException(e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,41 @@
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The JSONException is thrown by the JSON.org classes when things are amiss.
 | 
			
		||||
 *
 | 
			
		||||
 * @author JSON.org
 | 
			
		||||
 * @version 2014-05-03
 | 
			
		||||
 */
 | 
			
		||||
public class JSONException extends RuntimeException {
 | 
			
		||||
    private static final long serialVersionUID = 0;
 | 
			
		||||
    private Throwable cause;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a JSONException with an explanatory message.
 | 
			
		||||
     *
 | 
			
		||||
     * @param message Detail about the reason for the exception.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONException(final String message) {
 | 
			
		||||
        super(message);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a new JSONException with the specified cause.
 | 
			
		||||
     *
 | 
			
		||||
     * @param cause The cause.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONException(final Throwable cause) {
 | 
			
		||||
        super(cause.getMessage());
 | 
			
		||||
        this.cause = cause;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the cause of this exception or null if the cause is nonexistent or unknown.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the cause of this exception or null if the cause is nonexistent or unknown.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public Throwable getCause() {
 | 
			
		||||
        return this.cause;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										406
									
								
								src/main/java/com/intellectualcrafters/json/JSONML.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										406
									
								
								src/main/java/com/intellectualcrafters/json/JSONML.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,406 @@
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This provides static methods to convert an XML text into a JSONArray or JSONObject, and to covert a JSONArray or
 | 
			
		||||
 * JSONObject into an XML text using the JsonML transform.
 | 
			
		||||
 *
 | 
			
		||||
 * @author JSON.org
 | 
			
		||||
 * @version 2014-05-03
 | 
			
		||||
 */
 | 
			
		||||
public class JSONML {
 | 
			
		||||
    /**
 | 
			
		||||
     * Parse XML values and store them in a JSONArray.
 | 
			
		||||
     *
 | 
			
		||||
     * @param x         The XMLTokener containing the source string.
 | 
			
		||||
     * @param arrayForm true if array form, false if object form.
 | 
			
		||||
     * @param ja        The JSONArray that is containing the current tag or null if we are at the outermost level.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONArray if the value is the outermost tag, otherwise null.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    private static Object parse(final XMLTokener x, final boolean arrayForm, final JSONArray ja) throws JSONException {
 | 
			
		||||
        String attribute;
 | 
			
		||||
        char c;
 | 
			
		||||
        String closeTag = null;
 | 
			
		||||
        int i;
 | 
			
		||||
        JSONArray newja = null;
 | 
			
		||||
        JSONObject newjo = null;
 | 
			
		||||
        Object token;
 | 
			
		||||
        String tagName = null;
 | 
			
		||||
        // Test for and skip past these forms:
 | 
			
		||||
        // <!-- ... -->
 | 
			
		||||
        // <![ ... ]]>
 | 
			
		||||
        // <! ... >
 | 
			
		||||
        // <? ... ?>
 | 
			
		||||
        while (true) {
 | 
			
		||||
            if (!x.more()) {
 | 
			
		||||
                throw x.syntaxError("Bad XML");
 | 
			
		||||
            }
 | 
			
		||||
            token = x.nextContent();
 | 
			
		||||
            if (token == XML.LT) {
 | 
			
		||||
                token = x.nextToken();
 | 
			
		||||
                if (token instanceof Character) {
 | 
			
		||||
                    if (token == XML.SLASH) {
 | 
			
		||||
                        // Close tag </
 | 
			
		||||
                        token = x.nextToken();
 | 
			
		||||
                        if (!(token instanceof String)) {
 | 
			
		||||
                            throw new JSONException("Expected a closing name instead of '" + token + "'.");
 | 
			
		||||
                        }
 | 
			
		||||
                        if (x.nextToken() != XML.GT) {
 | 
			
		||||
                            throw x.syntaxError("Misshaped close tag");
 | 
			
		||||
                        }
 | 
			
		||||
                        return token;
 | 
			
		||||
                    } else if (token == XML.BANG) {
 | 
			
		||||
                        // <!
 | 
			
		||||
                        c = x.next();
 | 
			
		||||
                        if (c == '-') {
 | 
			
		||||
                            if (x.next() == '-') {
 | 
			
		||||
                                x.skipPast("-->");
 | 
			
		||||
                            } else {
 | 
			
		||||
                                x.back();
 | 
			
		||||
                            }
 | 
			
		||||
                        } else if (c == '[') {
 | 
			
		||||
                            token = x.nextToken();
 | 
			
		||||
                            if (token.equals("CDATA") && (x.next() == '[')) {
 | 
			
		||||
                                if (ja != null) {
 | 
			
		||||
                                    ja.put(x.nextCDATA());
 | 
			
		||||
                                }
 | 
			
		||||
                            } else {
 | 
			
		||||
                                throw x.syntaxError("Expected 'CDATA['");
 | 
			
		||||
                            }
 | 
			
		||||
                        } else {
 | 
			
		||||
                            i = 1;
 | 
			
		||||
                            do {
 | 
			
		||||
                                token = x.nextMeta();
 | 
			
		||||
                                if (token == null) {
 | 
			
		||||
                                    throw x.syntaxError("Missing '>' after '<!'.");
 | 
			
		||||
                                } else if (token == XML.LT) {
 | 
			
		||||
                                    i += 1;
 | 
			
		||||
                                } else if (token == XML.GT) {
 | 
			
		||||
                                    i -= 1;
 | 
			
		||||
                                }
 | 
			
		||||
                            } while (i > 0);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else if (token == XML.QUEST) {
 | 
			
		||||
                        // <?
 | 
			
		||||
                        x.skipPast("?>");
 | 
			
		||||
                    } else {
 | 
			
		||||
                        throw x.syntaxError("Misshaped tag");
 | 
			
		||||
                    }
 | 
			
		||||
                    // Open tag <
 | 
			
		||||
                } else {
 | 
			
		||||
                    if (!(token instanceof String)) {
 | 
			
		||||
                        throw x.syntaxError("Bad tagName '" + token + "'.");
 | 
			
		||||
                    }
 | 
			
		||||
                    tagName = (String) token;
 | 
			
		||||
                    newja = new JSONArray();
 | 
			
		||||
                    newjo = new JSONObject();
 | 
			
		||||
                    if (arrayForm) {
 | 
			
		||||
                        newja.put(tagName);
 | 
			
		||||
                        if (ja != null) {
 | 
			
		||||
                            ja.put(newja);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        newjo.put("tagName", tagName);
 | 
			
		||||
                        if (ja != null) {
 | 
			
		||||
                            ja.put(newjo);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    token = null;
 | 
			
		||||
                    for (;;) {
 | 
			
		||||
                        if (token == null) {
 | 
			
		||||
                            token = x.nextToken();
 | 
			
		||||
                        }
 | 
			
		||||
                        if (token == null) {
 | 
			
		||||
                            throw x.syntaxError("Misshaped tag");
 | 
			
		||||
                        }
 | 
			
		||||
                        if (!(token instanceof String)) {
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                        // attribute = value
 | 
			
		||||
                        attribute = (String) token;
 | 
			
		||||
                        if (!arrayForm && ("tagName".equals(attribute) || "childNode".equals(attribute))) {
 | 
			
		||||
                            throw x.syntaxError("Reserved attribute.");
 | 
			
		||||
                        }
 | 
			
		||||
                        token = x.nextToken();
 | 
			
		||||
                        if (token == XML.EQ) {
 | 
			
		||||
                            token = x.nextToken();
 | 
			
		||||
                            if (!(token instanceof String)) {
 | 
			
		||||
                                throw x.syntaxError("Missing value");
 | 
			
		||||
                            }
 | 
			
		||||
                            newjo.accumulate(attribute, XML.stringToValue((String) token));
 | 
			
		||||
                            token = null;
 | 
			
		||||
                        } else {
 | 
			
		||||
                            newjo.accumulate(attribute, "");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (arrayForm && (newjo.length() > 0)) {
 | 
			
		||||
                        newja.put(newjo);
 | 
			
		||||
                    }
 | 
			
		||||
                    // Empty tag <.../>
 | 
			
		||||
                    if (token == XML.SLASH) {
 | 
			
		||||
                        if (x.nextToken() != XML.GT) {
 | 
			
		||||
                            throw x.syntaxError("Misshaped tag");
 | 
			
		||||
                        }
 | 
			
		||||
                        if (ja == null) {
 | 
			
		||||
                            if (arrayForm) {
 | 
			
		||||
                                return newja;
 | 
			
		||||
                            } else {
 | 
			
		||||
                                return newjo;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        // Content, between <...> and </...>
 | 
			
		||||
                    } else {
 | 
			
		||||
                        if (token != XML.GT) {
 | 
			
		||||
                            throw x.syntaxError("Misshaped tag");
 | 
			
		||||
                        }
 | 
			
		||||
                        closeTag = (String) parse(x, arrayForm, newja);
 | 
			
		||||
                        if (closeTag != null) {
 | 
			
		||||
                            if (!closeTag.equals(tagName)) {
 | 
			
		||||
                                throw x.syntaxError("Mismatched '" + tagName + "' and '" + closeTag + "'");
 | 
			
		||||
                            }
 | 
			
		||||
                            tagName = null;
 | 
			
		||||
                            if (!arrayForm && (newja.length() > 0)) {
 | 
			
		||||
                                newjo.put("childNodes", newja);
 | 
			
		||||
                            }
 | 
			
		||||
                            if (ja == null) {
 | 
			
		||||
                                if (arrayForm) {
 | 
			
		||||
                                    return newja;
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    return newjo;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                if (ja != null) {
 | 
			
		||||
                    ja.put(token instanceof String ? XML.stringToValue((String) token) : token);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert a well-formed (but not necessarily valid) XML string into a JSONArray using the JsonML transform. Each
 | 
			
		||||
     * XML tag is represented as a JSONArray in which the first element is the tag name. If the tag has attributes, then
 | 
			
		||||
     * the second element will be JSONObject containing the name/value pairs. If the tag contains children, then strings
 | 
			
		||||
     *
 | 
			
		||||
     * @param string The source string.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONArray containing the structured data from the XML string.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static JSONArray toJSONArray(final String string) throws JSONException {
 | 
			
		||||
        return toJSONArray(new XMLTokener(string));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert a well-formed (but not necessarily valid) XML string into a JSONArray using the JsonML transform. Each
 | 
			
		||||
     * XML tag is represented as a JSONArray in which the first element is the tag name. If the tag has attributes, then
 | 
			
		||||
     * the second element will be JSONObject containing the name/value pairs. If the tag contains children, then strings
 | 
			
		||||
     * and JSONArrays will represent the child content and tags. Comments, prologs, DTDs, and <code><[ [ ]]></code>
 | 
			
		||||
     * are ignored.
 | 
			
		||||
     *
 | 
			
		||||
     * @param x An XMLTokener.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONArray containing the structured data from the XML string.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static JSONArray toJSONArray(final XMLTokener x) throws JSONException {
 | 
			
		||||
        return (JSONArray) parse(x, true, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert a well-formed (but not necessarily valid) XML string into a JSONObject using the JsonML transform. Each
 | 
			
		||||
     * XML tag is represented as a JSONObject with a "tagName" property. If the tag has attributes, then the attributes
 | 
			
		||||
     * will be in the JSONObject as properties. If the tag contains children, the object will have a "childNodes"
 | 
			
		||||
     * property which will be an array of strings and JsonML JSONObjects.
 | 
			
		||||
     * 
 | 
			
		||||
     * Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
 | 
			
		||||
     *
 | 
			
		||||
     * @param x An XMLTokener of the XML source text.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONObject containing the structured data from the XML string.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static JSONObject toJSONObject(final XMLTokener x) throws JSONException {
 | 
			
		||||
        return (JSONObject) parse(x, false, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert a well-formed (but not necessarily valid) XML string into a JSONObject using the JsonML transform. Each
 | 
			
		||||
     * XML tag is represented as a JSONObject with a "tagName" property. If the tag has attributes, then the attributes
 | 
			
		||||
     * will be in the JSONObject as properties. If the tag contains children, the object will have a "childNodes"
 | 
			
		||||
     * property which will be an array of strings and JsonML JSONObjects.
 | 
			
		||||
     * 
 | 
			
		||||
     * Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string The XML source text.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONObject containing the structured data from the XML string.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static JSONObject toJSONObject(final String string) throws JSONException {
 | 
			
		||||
        return toJSONObject(new XMLTokener(string));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reverse the JSONML transformation, making an XML text from a JSONArray.
 | 
			
		||||
     *
 | 
			
		||||
     * @param ja A JSONArray.
 | 
			
		||||
     *
 | 
			
		||||
     * @return An XML string.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static String toString(final JSONArray ja) throws JSONException {
 | 
			
		||||
        int i;
 | 
			
		||||
        JSONObject jo;
 | 
			
		||||
        String key;
 | 
			
		||||
        Iterator<String> keys;
 | 
			
		||||
        int length;
 | 
			
		||||
        Object object;
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        String tagName;
 | 
			
		||||
        String value;
 | 
			
		||||
        // Emit <tagName
 | 
			
		||||
        tagName = ja.getString(0);
 | 
			
		||||
        XML.noSpace(tagName);
 | 
			
		||||
        tagName = XML.escape(tagName);
 | 
			
		||||
        sb.append('<');
 | 
			
		||||
        sb.append(tagName);
 | 
			
		||||
        object = ja.opt(1);
 | 
			
		||||
        if (object instanceof JSONObject) {
 | 
			
		||||
            i = 2;
 | 
			
		||||
            jo = (JSONObject) object;
 | 
			
		||||
            // Emit the attributes
 | 
			
		||||
            keys = jo.keys();
 | 
			
		||||
            while (keys.hasNext()) {
 | 
			
		||||
                key = keys.next();
 | 
			
		||||
                XML.noSpace(key);
 | 
			
		||||
                value = jo.optString(key);
 | 
			
		||||
                if (value != null) {
 | 
			
		||||
                    sb.append(' ');
 | 
			
		||||
                    sb.append(XML.escape(key));
 | 
			
		||||
                    sb.append('=');
 | 
			
		||||
                    sb.append('"');
 | 
			
		||||
                    sb.append(XML.escape(value));
 | 
			
		||||
                    sb.append('"');
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            i = 1;
 | 
			
		||||
        }
 | 
			
		||||
        // Emit content in body
 | 
			
		||||
        length = ja.length();
 | 
			
		||||
        if (i >= length) {
 | 
			
		||||
            sb.append('/');
 | 
			
		||||
            sb.append('>');
 | 
			
		||||
        } else {
 | 
			
		||||
            sb.append('>');
 | 
			
		||||
            do {
 | 
			
		||||
                object = ja.get(i);
 | 
			
		||||
                i += 1;
 | 
			
		||||
                if (object != null) {
 | 
			
		||||
                    if (object instanceof String) {
 | 
			
		||||
                        sb.append(XML.escape(object.toString()));
 | 
			
		||||
                    } else if (object instanceof JSONObject) {
 | 
			
		||||
                        sb.append(toString((JSONObject) object));
 | 
			
		||||
                    } else if (object instanceof JSONArray) {
 | 
			
		||||
                        sb.append(toString((JSONArray) object));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } while (i < length);
 | 
			
		||||
            sb.append('<');
 | 
			
		||||
            sb.append('/');
 | 
			
		||||
            sb.append(tagName);
 | 
			
		||||
            sb.append('>');
 | 
			
		||||
        }
 | 
			
		||||
        return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reverse the JSONML transformation, making an XML text from a JSONObject. The JSONObject must contain a "tagName"
 | 
			
		||||
     * property. If it has children, then it must have a "childNodes" property containing an array of objects. The other
 | 
			
		||||
     * properties are attributes with string values.
 | 
			
		||||
     *
 | 
			
		||||
     * @param jo A JSONObject.
 | 
			
		||||
     *
 | 
			
		||||
     * @return An XML string.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static String toString(final JSONObject jo) throws JSONException {
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        int i;
 | 
			
		||||
        JSONArray ja;
 | 
			
		||||
        String key;
 | 
			
		||||
        Iterator<String> keys;
 | 
			
		||||
        int length;
 | 
			
		||||
        Object object;
 | 
			
		||||
        String tagName;
 | 
			
		||||
        String value;
 | 
			
		||||
        // Emit <tagName
 | 
			
		||||
        tagName = jo.optString("tagName");
 | 
			
		||||
        if (tagName == null) {
 | 
			
		||||
            return XML.escape(jo.toString());
 | 
			
		||||
        }
 | 
			
		||||
        XML.noSpace(tagName);
 | 
			
		||||
        tagName = XML.escape(tagName);
 | 
			
		||||
        sb.append('<');
 | 
			
		||||
        sb.append(tagName);
 | 
			
		||||
        // Emit the attributes
 | 
			
		||||
        keys = jo.keys();
 | 
			
		||||
        while (keys.hasNext()) {
 | 
			
		||||
            key = keys.next();
 | 
			
		||||
            if (!"tagName".equals(key) && !"childNodes".equals(key)) {
 | 
			
		||||
                XML.noSpace(key);
 | 
			
		||||
                value = jo.optString(key);
 | 
			
		||||
                if (value != null) {
 | 
			
		||||
                    sb.append(' ');
 | 
			
		||||
                    sb.append(XML.escape(key));
 | 
			
		||||
                    sb.append('=');
 | 
			
		||||
                    sb.append('"');
 | 
			
		||||
                    sb.append(XML.escape(value));
 | 
			
		||||
                    sb.append('"');
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Emit content in body
 | 
			
		||||
        ja = jo.optJSONArray("childNodes");
 | 
			
		||||
        if (ja == null) {
 | 
			
		||||
            sb.append('/');
 | 
			
		||||
            sb.append('>');
 | 
			
		||||
        } else {
 | 
			
		||||
            sb.append('>');
 | 
			
		||||
            length = ja.length();
 | 
			
		||||
            for (i = 0; i < length; i += 1) {
 | 
			
		||||
                object = ja.get(i);
 | 
			
		||||
                if (object != null) {
 | 
			
		||||
                    if (object instanceof String) {
 | 
			
		||||
                        sb.append(XML.escape(object.toString()));
 | 
			
		||||
                    } else if (object instanceof JSONObject) {
 | 
			
		||||
                        sb.append(toString((JSONObject) object));
 | 
			
		||||
                    } else if (object instanceof JSONArray) {
 | 
			
		||||
                        sb.append(toString((JSONArray) object));
 | 
			
		||||
                    } else {
 | 
			
		||||
                        sb.append(object.toString());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            sb.append('<');
 | 
			
		||||
            sb.append('/');
 | 
			
		||||
            sb.append(tagName);
 | 
			
		||||
            sb.append('>');
 | 
			
		||||
        }
 | 
			
		||||
        return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1493
									
								
								src/main/java/com/intellectualcrafters/json/JSONObject.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1493
									
								
								src/main/java/com/intellectualcrafters/json/JSONObject.java
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										16
									
								
								src/main/java/com/intellectualcrafters/json/JSONString.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/main/java/com/intellectualcrafters/json/JSONString.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The <code>JSONString</code> interface allows a <code>toJSONString()</code> method so that a class can change the
 | 
			
		||||
 * behavior of <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>, and
 | 
			
		||||
 * <code>JSONWriter.value(</code>Object<code>)</code>. The <code>toJSONString</code> method will be used instead of the
 | 
			
		||||
 * default behavior of using the Object's <code>toString()</code> method and quoting the result.
 | 
			
		||||
 */
 | 
			
		||||
public interface JSONString {
 | 
			
		||||
    /**
 | 
			
		||||
     * The <code>toJSONString</code> method allows a class to produce its own JSON serialization.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A strictly syntactically correct JSON text.
 | 
			
		||||
     */
 | 
			
		||||
    public String toJSONString();
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,55 @@
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
import java.io.StringWriter;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * JSONStringer provides a quick and convenient way of producing JSON text. The texts produced strictly conform to JSON
 | 
			
		||||
 * syntax rules. No whitespace is added, so the results are ready for transmission or storage. Each instance of
 | 
			
		||||
 * JSONStringer can produce one JSON text.
 | 
			
		||||
 * 
 | 
			
		||||
 * A JSONStringer instance provides a <code>value</code> method for appending values to the text, and a <code>key</code>
 | 
			
		||||
 * method for adding keys before values in objects. There are <code>array</code> and <code>endArray</code> methods that
 | 
			
		||||
 * make and bound array values, and <code>object</code> and <code>endObject</code> methods which make and bound object
 | 
			
		||||
 * values. All of these methods return the JSONWriter instance, permitting cascade style. For example,
 | 
			
		||||
 * 
 | 
			
		||||
 * 
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * myString = new JSONStringer().object().key("JSON").value("Hello,
 | 
			
		||||
 * World!").endObject().toString();
 | 
			
		||||
 * </pre>
 | 
			
		||||
 * 
 | 
			
		||||
 * which produces the string
 | 
			
		||||
 * 
 | 
			
		||||
 * 
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * {"JSON":"Hello, World!"}
 | 
			
		||||
 * </pre>
 | 
			
		||||
 * 
 | 
			
		||||
 * The first method called must be <code>array</code> or <code>object</code>. There are no methods for adding commas or
 | 
			
		||||
 * colons. JSONStringer adds them for you. Objects and arrays can be nested up to 20 levels deep.
 | 
			
		||||
 * 
 | 
			
		||||
 * This can sometimes be easier than using a JSONObject to build a string.
 | 
			
		||||
 *
 | 
			
		||||
 * @author JSON.org
 | 
			
		||||
 * @version 2008-09-18
 | 
			
		||||
 */
 | 
			
		||||
public class JSONStringer extends JSONWriter {
 | 
			
		||||
    /**
 | 
			
		||||
     * Make a fresh JSONStringer. It can be used to build one JSON text.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONStringer() {
 | 
			
		||||
        super(new StringWriter());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Return the JSON text. This method is used to obtain the product of the JSONStringer instance. It will return
 | 
			
		||||
     * <code>null</code> if there was a problem in the construction of the JSON text (such as the calls to
 | 
			
		||||
     * <code>array</code> were not properly balanced with calls to <code>endArray</code>).
 | 
			
		||||
     *
 | 
			
		||||
     * @return The JSON text.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return this.mode == 'd' ? this.writer.toString() : null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										403
									
								
								src/main/java/com/intellectualcrafters/json/JSONTokener.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										403
									
								
								src/main/java/com/intellectualcrafters/json/JSONTokener.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,403 @@
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedReader;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
import java.io.Reader;
 | 
			
		||||
import java.io.StringReader;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A JSONTokener takes a source string and extracts characters and tokens from it. It is used by the JSONObject and
 | 
			
		||||
 * JSONArray constructors to parse JSON source strings.
 | 
			
		||||
 *
 | 
			
		||||
 * @author JSON.org
 | 
			
		||||
 * @version 2014-05-03
 | 
			
		||||
 */
 | 
			
		||||
public class JSONTokener {
 | 
			
		||||
    private final Reader reader;
 | 
			
		||||
    private long character;
 | 
			
		||||
    private boolean eof;
 | 
			
		||||
    private long index;
 | 
			
		||||
    private long line;
 | 
			
		||||
    private char previous;
 | 
			
		||||
    private boolean usePrevious;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct a JSONTokener from a Reader.
 | 
			
		||||
     *
 | 
			
		||||
     * @param reader A reader.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONTokener(final Reader reader) {
 | 
			
		||||
        this.reader = reader.markSupported() ? reader : new BufferedReader(reader);
 | 
			
		||||
        this.eof = false;
 | 
			
		||||
        this.usePrevious = false;
 | 
			
		||||
        this.previous = 0;
 | 
			
		||||
        this.index = 0;
 | 
			
		||||
        this.character = 1;
 | 
			
		||||
        this.line = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct a JSONTokener from an InputStream.
 | 
			
		||||
     *
 | 
			
		||||
     * @param inputStream The source.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONTokener(final InputStream inputStream) throws JSONException {
 | 
			
		||||
        this(new InputStreamReader(inputStream));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct a JSONTokener from a string.
 | 
			
		||||
     *
 | 
			
		||||
     * @param s A source string.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONTokener(final String s) {
 | 
			
		||||
        this(new StringReader(s));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the hex value of a character (base16).
 | 
			
		||||
     *
 | 
			
		||||
     * @param c A character between '0' and '9' or between 'A' and 'F' or between 'a' and 'f'.
 | 
			
		||||
     *
 | 
			
		||||
     * @return An int between 0 and 15, or -1 if c was not a hex digit.
 | 
			
		||||
     */
 | 
			
		||||
    public static int dehexchar(final char c) {
 | 
			
		||||
        if ((c >= '0') && (c <= '9')) {
 | 
			
		||||
            return c - '0';
 | 
			
		||||
        }
 | 
			
		||||
        if ((c >= 'A') && (c <= 'F')) {
 | 
			
		||||
            return c - ('A' - 10);
 | 
			
		||||
        }
 | 
			
		||||
        if ((c >= 'a') && (c <= 'f')) {
 | 
			
		||||
            return c - ('a' - 10);
 | 
			
		||||
        }
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Back up one character. This provides a sort of lookahead capability, so that you can test for a digit or letter
 | 
			
		||||
     * before attempting to parse the next number or identifier.
 | 
			
		||||
     */
 | 
			
		||||
    public void back() throws JSONException {
 | 
			
		||||
        if (this.usePrevious || (this.index <= 0)) {
 | 
			
		||||
            throw new JSONException("Stepping back two steps is not supported");
 | 
			
		||||
        }
 | 
			
		||||
        this.index -= 1;
 | 
			
		||||
        this.character -= 1;
 | 
			
		||||
        this.usePrevious = true;
 | 
			
		||||
        this.eof = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean end() {
 | 
			
		||||
        return this.eof && !this.usePrevious;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Determine if the source string still contains characters that next() can consume.
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if not yet at the end of the source.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean more() throws JSONException {
 | 
			
		||||
        this.next();
 | 
			
		||||
        if (this.end()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        this.back();
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the next character in the source string.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The next character, or 0 if past the end of the source string.
 | 
			
		||||
     */
 | 
			
		||||
    public char next() throws JSONException {
 | 
			
		||||
        int c;
 | 
			
		||||
        if (this.usePrevious) {
 | 
			
		||||
            this.usePrevious = false;
 | 
			
		||||
            c = this.previous;
 | 
			
		||||
        } else {
 | 
			
		||||
            try {
 | 
			
		||||
                c = this.reader.read();
 | 
			
		||||
            } catch (final IOException exception) {
 | 
			
		||||
                throw new JSONException(exception);
 | 
			
		||||
            }
 | 
			
		||||
            if (c <= 0) { // End of stream
 | 
			
		||||
                this.eof = true;
 | 
			
		||||
                c = 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        this.index += 1;
 | 
			
		||||
        if (this.previous == '\r') {
 | 
			
		||||
            this.line += 1;
 | 
			
		||||
            this.character = c == '\n' ? 0 : 1;
 | 
			
		||||
        } else if (c == '\n') {
 | 
			
		||||
            this.line += 1;
 | 
			
		||||
            this.character = 0;
 | 
			
		||||
        } else {
 | 
			
		||||
            this.character += 1;
 | 
			
		||||
        }
 | 
			
		||||
        this.previous = (char) c;
 | 
			
		||||
        return this.previous;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Consume the next character, and check that it matches a specified character.
 | 
			
		||||
     *
 | 
			
		||||
     * @param c The character to match.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The character.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException if the character does not match.
 | 
			
		||||
     */
 | 
			
		||||
    public char next(final char c) throws JSONException {
 | 
			
		||||
        final char n = this.next();
 | 
			
		||||
        if (n != c) {
 | 
			
		||||
            throw this.syntaxError("Expected '" + c + "' and instead saw '" + n + "'");
 | 
			
		||||
        }
 | 
			
		||||
        return n;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the next n characters.
 | 
			
		||||
     *
 | 
			
		||||
     * @param n The number of characters to take.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A string of n characters.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException Substring bounds error if there are not n characters remaining in the source string.
 | 
			
		||||
     */
 | 
			
		||||
    public String next(final int n) throws JSONException {
 | 
			
		||||
        if (n == 0) {
 | 
			
		||||
            return "";
 | 
			
		||||
        }
 | 
			
		||||
        final char[] chars = new char[n];
 | 
			
		||||
        int pos = 0;
 | 
			
		||||
        while (pos < n) {
 | 
			
		||||
            chars[pos] = this.next();
 | 
			
		||||
            if (this.end()) {
 | 
			
		||||
                throw this.syntaxError("Substring bounds error");
 | 
			
		||||
            }
 | 
			
		||||
            pos += 1;
 | 
			
		||||
        }
 | 
			
		||||
        return new String(chars);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the next char in the string, skipping whitespace.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A character, or 0 if there are no more characters.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public char nextClean() throws JSONException {
 | 
			
		||||
        for (;;) {
 | 
			
		||||
            final char c = this.next();
 | 
			
		||||
            if ((c == 0) || (c > ' ')) {
 | 
			
		||||
                return c;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Return the characters up to the next close quote character. Backslash processing is done. The formal JSON format
 | 
			
		||||
     * does not allow strings in single quotes, but an implementation is allowed to accept them.
 | 
			
		||||
     *
 | 
			
		||||
     * @param quote The quoting character, either <code>"</code>  <small>(double quote)</small> or <code>'</code>
 | 
			
		||||
     *               <small>(single quote)</small>.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A String.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException Unterminated string.
 | 
			
		||||
     */
 | 
			
		||||
    public String nextString(final char quote) throws JSONException {
 | 
			
		||||
        char c;
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        for (;;) {
 | 
			
		||||
            c = this.next();
 | 
			
		||||
            switch (c) {
 | 
			
		||||
                case 0:
 | 
			
		||||
                case '\n':
 | 
			
		||||
                case '\r':
 | 
			
		||||
                    throw this.syntaxError("Unterminated string");
 | 
			
		||||
                case '\\':
 | 
			
		||||
                    c = this.next();
 | 
			
		||||
                    switch (c) {
 | 
			
		||||
                        case 'b':
 | 
			
		||||
                            sb.append('\b');
 | 
			
		||||
                            break;
 | 
			
		||||
                        case 't':
 | 
			
		||||
                            sb.append('\t');
 | 
			
		||||
                            break;
 | 
			
		||||
                        case 'n':
 | 
			
		||||
                            sb.append('\n');
 | 
			
		||||
                            break;
 | 
			
		||||
                        case 'f':
 | 
			
		||||
                            sb.append('\f');
 | 
			
		||||
                            break;
 | 
			
		||||
                        case 'r':
 | 
			
		||||
                            sb.append('\r');
 | 
			
		||||
                            break;
 | 
			
		||||
                        case 'u':
 | 
			
		||||
                            sb.append((char) Integer.parseInt(this.next(4), 16));
 | 
			
		||||
                            break;
 | 
			
		||||
                        case '"':
 | 
			
		||||
                        case '\'':
 | 
			
		||||
                        case '\\':
 | 
			
		||||
                        case '/':
 | 
			
		||||
                            sb.append(c);
 | 
			
		||||
                            break;
 | 
			
		||||
                        default:
 | 
			
		||||
                            throw this.syntaxError("Illegal escape.");
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    if (c == quote) {
 | 
			
		||||
                        return sb.toString();
 | 
			
		||||
                    }
 | 
			
		||||
                    sb.append(c);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the text up but not including the specified character or the end of line, whichever comes first.
 | 
			
		||||
     *
 | 
			
		||||
     * @param delimiter A delimiter character.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A string.
 | 
			
		||||
     */
 | 
			
		||||
    public String nextTo(final char delimiter) throws JSONException {
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        for (;;) {
 | 
			
		||||
            final char c = this.next();
 | 
			
		||||
            if ((c == delimiter) || (c == 0) || (c == '\n') || (c == '\r')) {
 | 
			
		||||
                if (c != 0) {
 | 
			
		||||
                    this.back();
 | 
			
		||||
                }
 | 
			
		||||
                return sb.toString().trim();
 | 
			
		||||
            }
 | 
			
		||||
            sb.append(c);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the text up but not including one of the specified delimiter characters or the end of line, whichever comes
 | 
			
		||||
     * first.
 | 
			
		||||
     *
 | 
			
		||||
     * @param delimiters A set of delimiter characters.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A string, trimmed.
 | 
			
		||||
     */
 | 
			
		||||
    public String nextTo(final String delimiters) throws JSONException {
 | 
			
		||||
        char c;
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        for (;;) {
 | 
			
		||||
            c = this.next();
 | 
			
		||||
            if ((delimiters.indexOf(c) >= 0) || (c == 0) || (c == '\n') || (c == '\r')) {
 | 
			
		||||
                if (c != 0) {
 | 
			
		||||
                    this.back();
 | 
			
		||||
                }
 | 
			
		||||
                return sb.toString().trim();
 | 
			
		||||
            }
 | 
			
		||||
            sb.append(c);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the next value. The value can be a Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the
 | 
			
		||||
     * JSONObject.NULL object.
 | 
			
		||||
     *
 | 
			
		||||
     * @return An object.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If syntax error.
 | 
			
		||||
     */
 | 
			
		||||
    public Object nextValue() throws JSONException {
 | 
			
		||||
        char c = this.nextClean();
 | 
			
		||||
        String string;
 | 
			
		||||
        switch (c) {
 | 
			
		||||
            case '"':
 | 
			
		||||
            case '\'':
 | 
			
		||||
                return this.nextString(c);
 | 
			
		||||
            case '{':
 | 
			
		||||
                this.back();
 | 
			
		||||
                return new JSONObject(this);
 | 
			
		||||
            case '[':
 | 
			
		||||
                this.back();
 | 
			
		||||
                return new JSONArray(this);
 | 
			
		||||
        }
 | 
			
		||||
        /*
 | 
			
		||||
         * Handle unquoted text. This could be the values true, false, or
 | 
			
		||||
         * null, or it can be a number. An implementation (such as this one)
 | 
			
		||||
         * is allowed to also accept non-standard forms.
 | 
			
		||||
         * Accumulate characters until we reach the end of the text or a
 | 
			
		||||
         * formatting character.
 | 
			
		||||
         */
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        while ((c >= ' ') && (",:]}/\\\"[{;=#".indexOf(c) < 0)) {
 | 
			
		||||
            sb.append(c);
 | 
			
		||||
            c = this.next();
 | 
			
		||||
        }
 | 
			
		||||
        this.back();
 | 
			
		||||
        string = sb.toString().trim();
 | 
			
		||||
        if ("".equals(string)) {
 | 
			
		||||
            throw this.syntaxError("Missing value");
 | 
			
		||||
        }
 | 
			
		||||
        return JSONObject.stringToValue(string);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Skip characters until the next character is the requested character. If the requested character is not found, no
 | 
			
		||||
     * characters are skipped.
 | 
			
		||||
     *
 | 
			
		||||
     * @param to A character to skip to.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The requested character, or zero if the requested character is not found.
 | 
			
		||||
     */
 | 
			
		||||
    public char skipTo(final char to) throws JSONException {
 | 
			
		||||
        char c;
 | 
			
		||||
        try {
 | 
			
		||||
            final long startIndex = this.index;
 | 
			
		||||
            final long startCharacter = this.character;
 | 
			
		||||
            final long startLine = this.line;
 | 
			
		||||
            this.reader.mark(1000000);
 | 
			
		||||
            do {
 | 
			
		||||
                c = this.next();
 | 
			
		||||
                if (c == 0) {
 | 
			
		||||
                    this.reader.reset();
 | 
			
		||||
                    this.index = startIndex;
 | 
			
		||||
                    this.character = startCharacter;
 | 
			
		||||
                    this.line = startLine;
 | 
			
		||||
                    return c;
 | 
			
		||||
                }
 | 
			
		||||
            } while (c != to);
 | 
			
		||||
        } catch (final IOException exception) {
 | 
			
		||||
            throw new JSONException(exception);
 | 
			
		||||
        }
 | 
			
		||||
        this.back();
 | 
			
		||||
        return c;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Make a JSONException to signal a syntax error.
 | 
			
		||||
     *
 | 
			
		||||
     * @param message The error message.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A JSONException object, suitable for throwing
 | 
			
		||||
     */
 | 
			
		||||
    public JSONException syntaxError(final String message) {
 | 
			
		||||
        return new JSONException(message + this.toString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Make a printable string of this JSONTokener.
 | 
			
		||||
     *
 | 
			
		||||
     * @return " at {index} [character {character} line {line}]"
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return " at " + this.index + " [character " + this.character + " line " + this.line + "]";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										308
									
								
								src/main/java/com/intellectualcrafters/json/JSONWriter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										308
									
								
								src/main/java/com/intellectualcrafters/json/JSONWriter.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,308 @@
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.Writer;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * JSONWriter provides a quick and convenient way of producing JSON text. The texts produced strictly conform to JSON
 | 
			
		||||
 * syntax rules. No whitespace is added, so the results are ready for transmission or storage. Each instance of
 | 
			
		||||
 * JSONWriter can produce one JSON text.
 | 
			
		||||
 * 
 | 
			
		||||
 * A JSONWriter instance provides a <code>value</code> method for appending values to the text, and a <code>key</code>
 | 
			
		||||
 * method for adding keys before values in objects. There are <code>array</code> and <code>endArray</code> methods that
 | 
			
		||||
 * make and bound array values, and <code>object</code> and <code>endObject</code> methods which make and bound object
 | 
			
		||||
 * values. All of these methods return the JSONWriter instance, permitting a cascade style. For example,
 | 
			
		||||
 * 
 | 
			
		||||
 * 
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * new JSONWriter(myWriter).object().key("JSON").value("Hello, World!").endObject();
 | 
			
		||||
 * </pre>
 | 
			
		||||
 * 
 | 
			
		||||
 * which writes
 | 
			
		||||
 * 
 | 
			
		||||
 * 
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * {"JSON":"Hello, World!"}
 | 
			
		||||
 * </pre>
 | 
			
		||||
 * 
 | 
			
		||||
 * The first method called must be <code>array</code> or <code>object</code>. There are no methods for adding commas or
 | 
			
		||||
 * colons. JSONWriter adds them for you. Objects and arrays can be nested up to 20 levels deep.
 | 
			
		||||
 * 
 | 
			
		||||
 * This can sometimes be easier than using a JSONObject to build a string.
 | 
			
		||||
 *
 | 
			
		||||
 * @author JSON.org
 | 
			
		||||
 * @version 2011-11-24
 | 
			
		||||
 */
 | 
			
		||||
public class JSONWriter {
 | 
			
		||||
    private static final int maxdepth = 200;
 | 
			
		||||
    /**
 | 
			
		||||
     * The writer that will receive the output.
 | 
			
		||||
     */
 | 
			
		||||
    protected final Writer writer;
 | 
			
		||||
    /**
 | 
			
		||||
     * The object/array stack.
 | 
			
		||||
     */
 | 
			
		||||
    private final JSONObject stack[];
 | 
			
		||||
    /**
 | 
			
		||||
     * The current mode. Values: 'a' (array), 'd' (done), 'i' (initial), 'k' (key), 'o' (object).
 | 
			
		||||
     */
 | 
			
		||||
    protected char mode;
 | 
			
		||||
    /**
 | 
			
		||||
     * The comma flag determines if a comma should be output before the next value.
 | 
			
		||||
     */
 | 
			
		||||
    private boolean comma;
 | 
			
		||||
    /**
 | 
			
		||||
     * The stack top index. A value of 0 indicates that the stack is empty.
 | 
			
		||||
     */
 | 
			
		||||
    private int top;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Make a fresh JSONWriter. It can be used to build one JSON text.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONWriter(final Writer w) {
 | 
			
		||||
        this.comma = false;
 | 
			
		||||
        this.mode = 'i';
 | 
			
		||||
        this.stack = new JSONObject[maxdepth];
 | 
			
		||||
        this.top = 0;
 | 
			
		||||
        this.writer = w;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Append a value.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string A string value.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the value is out of sequence.
 | 
			
		||||
     */
 | 
			
		||||
    private JSONWriter append(final String string) throws JSONException {
 | 
			
		||||
        if (string == null) {
 | 
			
		||||
            throw new JSONException("Null pointer");
 | 
			
		||||
        }
 | 
			
		||||
        if ((this.mode == 'o') || (this.mode == 'a')) {
 | 
			
		||||
            try {
 | 
			
		||||
                if (this.comma && (this.mode == 'a')) {
 | 
			
		||||
                    this.writer.write(',');
 | 
			
		||||
                }
 | 
			
		||||
                this.writer.write(string);
 | 
			
		||||
            } catch (final IOException e) {
 | 
			
		||||
                throw new JSONException(e);
 | 
			
		||||
            }
 | 
			
		||||
            if (this.mode == 'o') {
 | 
			
		||||
                this.mode = 'k';
 | 
			
		||||
            }
 | 
			
		||||
            this.comma = true;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
        throw new JSONException("Value out of sequence.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Begin appending a new array. All values until the balancing <code>endArray</code> will be appended to this array.
 | 
			
		||||
     * The <code>endArray</code> method must be called to mark the array's end.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the nesting is too deep, or if the object is started in the wrong place (for example as
 | 
			
		||||
     *                       a key or after the end of the outermost array or object).
 | 
			
		||||
     */
 | 
			
		||||
    public JSONWriter array() throws JSONException {
 | 
			
		||||
        if ((this.mode == 'i') || (this.mode == 'o') || (this.mode == 'a')) {
 | 
			
		||||
            this.push(null);
 | 
			
		||||
            this.append("[");
 | 
			
		||||
            this.comma = false;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
        throw new JSONException("Misplaced array.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * End something.
 | 
			
		||||
     *
 | 
			
		||||
     * @param mode Mode
 | 
			
		||||
     * @param c    Closing character
 | 
			
		||||
     *
 | 
			
		||||
     * @return this
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If unbalanced.
 | 
			
		||||
     */
 | 
			
		||||
    private JSONWriter end(final char mode, final char c) throws JSONException {
 | 
			
		||||
        if (this.mode != mode) {
 | 
			
		||||
            throw new JSONException(mode == 'a' ? "Misplaced endArray." : "Misplaced endObject.");
 | 
			
		||||
        }
 | 
			
		||||
        this.pop(mode);
 | 
			
		||||
        try {
 | 
			
		||||
            this.writer.write(c);
 | 
			
		||||
        } catch (final IOException e) {
 | 
			
		||||
            throw new JSONException(e);
 | 
			
		||||
        }
 | 
			
		||||
        this.comma = true;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * End an array. This method most be called to balance calls to <code>array</code>.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If incorrectly nested.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONWriter endArray() throws JSONException {
 | 
			
		||||
        return this.end('a', ']');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * End an object. This method most be called to balance calls to <code>object</code>.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If incorrectly nested.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONWriter endObject() throws JSONException {
 | 
			
		||||
        return this.end('k', '}');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Append a key. The key will be associated with the next value. In an object, every value must be preceded by a
 | 
			
		||||
     * key.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string A key string.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the key is out of place. For example, keys do not belong in arrays or if the key is
 | 
			
		||||
     *                       null.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONWriter key(final String string) throws JSONException {
 | 
			
		||||
        if (string == null) {
 | 
			
		||||
            throw new JSONException("Null key.");
 | 
			
		||||
        }
 | 
			
		||||
        if (this.mode == 'k') {
 | 
			
		||||
            try {
 | 
			
		||||
                this.stack[this.top - 1].putOnce(string, Boolean.TRUE);
 | 
			
		||||
                if (this.comma) {
 | 
			
		||||
                    this.writer.write(',');
 | 
			
		||||
                }
 | 
			
		||||
                this.writer.write(JSONObject.quote(string));
 | 
			
		||||
                this.writer.write(':');
 | 
			
		||||
                this.comma = false;
 | 
			
		||||
                this.mode = 'o';
 | 
			
		||||
                return this;
 | 
			
		||||
            } catch (final IOException e) {
 | 
			
		||||
                throw new JSONException(e);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        throw new JSONException("Misplaced key.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Begin appending a new object. All keys and values until the balancing <code>endObject</code> will be appended to
 | 
			
		||||
     * this object. The <code>endObject</code> method must be called to mark the object's end.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the nesting is too deep, or if the object is started in the wrong place (for example as
 | 
			
		||||
     *                       a key or after the end of the outermost array or object).
 | 
			
		||||
     */
 | 
			
		||||
    public JSONWriter object() throws JSONException {
 | 
			
		||||
        if (this.mode == 'i') {
 | 
			
		||||
            this.mode = 'o';
 | 
			
		||||
        }
 | 
			
		||||
        if ((this.mode == 'o') || (this.mode == 'a')) {
 | 
			
		||||
            this.append("{");
 | 
			
		||||
            this.push(new JSONObject());
 | 
			
		||||
            this.comma = false;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
        throw new JSONException("Misplaced object.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pop an array or object scope.
 | 
			
		||||
     *
 | 
			
		||||
     * @param c The scope to close.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If nesting is wrong.
 | 
			
		||||
     */
 | 
			
		||||
    private void pop(final char c) throws JSONException {
 | 
			
		||||
        if (this.top <= 0) {
 | 
			
		||||
            throw new JSONException("Nesting error.");
 | 
			
		||||
        }
 | 
			
		||||
        final char m = this.stack[this.top - 1] == null ? 'a' : 'k';
 | 
			
		||||
        if (m != c) {
 | 
			
		||||
            throw new JSONException("Nesting error.");
 | 
			
		||||
        }
 | 
			
		||||
        this.top -= 1;
 | 
			
		||||
        this.mode = this.top == 0 ? 'd' : this.stack[this.top - 1] == null ? 'a' : 'k';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Push an array or object scope.
 | 
			
		||||
     *
 | 
			
		||||
     * @param jo The scope to open.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If nesting is too deep.
 | 
			
		||||
     */
 | 
			
		||||
    private void push(final JSONObject jo) throws JSONException {
 | 
			
		||||
        if (this.top >= maxdepth) {
 | 
			
		||||
            throw new JSONException("Nesting too deep.");
 | 
			
		||||
        }
 | 
			
		||||
        this.stack[this.top] = jo;
 | 
			
		||||
        this.mode = jo == null ? 'a' : 'k';
 | 
			
		||||
        this.top += 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Append either the value <code>true</code> or the value <code>false</code> .
 | 
			
		||||
     *
 | 
			
		||||
     * @param b A boolean.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public JSONWriter value(final boolean b) throws JSONException {
 | 
			
		||||
        return this.append(b ? "true" : "false");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Append a double value.
 | 
			
		||||
     *
 | 
			
		||||
     * @param d A double.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the number is not finite.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONWriter value(final double d) throws JSONException {
 | 
			
		||||
        return this.value(new Double(d));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Append a long value.
 | 
			
		||||
     *
 | 
			
		||||
     * @param l A long.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public JSONWriter value(final long l) throws JSONException {
 | 
			
		||||
        return this.append(Long.toString(l));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Append an object value.
 | 
			
		||||
     *
 | 
			
		||||
     * @param object The object to append. It can be null, or a Boolean, Number, String, JSONObject, or JSONArray, or an
 | 
			
		||||
     *               object that implements JSONString.
 | 
			
		||||
     *
 | 
			
		||||
     * @return this
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the value is out of sequence.
 | 
			
		||||
     */
 | 
			
		||||
    public JSONWriter value(final Object object) throws JSONException {
 | 
			
		||||
        return this.append(JSONObject.valueToString(object));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										313
									
								
								src/main/java/com/intellectualcrafters/json/Kim.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										313
									
								
								src/main/java/com/intellectualcrafters/json/Kim.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,313 @@
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Kim makes immutable eight bit Unicode strings. If the MSB of a byte is set, then the next byte is a continuation
 | 
			
		||||
 * byte. The last byte of a character never has the MSB reset. Every byte that is not the last byte has the MSB set. Kim
 | 
			
		||||
 * stands for "Keep it minimal". A Unicode character is never longer than 3 bytes. Every byte contributes 7 bits to the
 | 
			
		||||
 * character. ASCII is unmodified.
 | 
			
		||||
 * 
 | 
			
		||||
 * Kim UTF-8 one byte U+007F U+007F two bytes U+3FFF U+07FF three bytes U+10FFF U+FFFF four bytes U+10FFFF
 | 
			
		||||
 * 
 | 
			
		||||
 * Characters in the ranges U+0800..U+3FFF and U+10000..U+10FFFF will be one byte smaller when encoded in Kim compared
 | 
			
		||||
 * to UTF-8.
 | 
			
		||||
 * 
 | 
			
		||||
 * Kim is beneficial when using scripts such as Old South Arabian, Aramaic, Avestan, Balinese, Batak, Bopomofo,
 | 
			
		||||
 * Buginese, Buhid, Carian, Cherokee, Coptic, Cyrillic, Deseret, Egyptian Hieroglyphs, Ethiopic, Georgian, Glagolitic,
 | 
			
		||||
 * Gothic, Hangul Jamo, Hanunoo, Hiragana, Kanbun, Kaithi, Kannada, Katakana, Kharoshthi, Khmer, Lao, Lepcha, Limbu,
 | 
			
		||||
 * Lycian, Lydian, Malayalam, Mandaic, Meroitic, Miao, Mongolian, Myanmar, New Tai Lue, Ol Chiki, Old Turkic, Oriya,
 | 
			
		||||
 * Osmanya, Pahlavi, Parthian, Phags-Pa, Phoenician, Samaritan, Sharada, Sinhala, Sora Sompeng, Tagalog, Tagbanwa,
 | 
			
		||||
 * Takri, Tai Le, Tai Tham, Tamil, Telugu, Thai, Tibetan, Tifinagh, UCAS.
 | 
			
		||||
 * 
 | 
			
		||||
 * A kim object can be constructed from an ordinary UTF-16 string, or from a byte array. A kim object can produce a
 | 
			
		||||
 * UTF-16 string.
 | 
			
		||||
 * 
 | 
			
		||||
 * As with UTF-8, it is possible to detect character boundaries within a byte sequence. UTF-8 is one of the world's
 | 
			
		||||
 * great inventions. While Kim is more efficient, it is not clear that it is worth the expense of transition.
 | 
			
		||||
 *
 | 
			
		||||
 * @version 2013-04-18
 | 
			
		||||
 */
 | 
			
		||||
public class Kim {
 | 
			
		||||
    /**
 | 
			
		||||
     * The number of bytes in the kim. The number of bytes can be as much as three times the number of characters.
 | 
			
		||||
     */
 | 
			
		||||
    public int length = 0;
 | 
			
		||||
    /**
 | 
			
		||||
     * The byte array containing the kim's content.
 | 
			
		||||
     */
 | 
			
		||||
    private byte[] bytes = null;
 | 
			
		||||
    /**
 | 
			
		||||
     * The kim's hashcode, conforming to Java's hashcode conventions.
 | 
			
		||||
     */
 | 
			
		||||
    private int hashcode = 0;
 | 
			
		||||
    /**
 | 
			
		||||
     * The memoization of toString().
 | 
			
		||||
     */
 | 
			
		||||
    private String string = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Make a kim from a portion of a byte array.
 | 
			
		||||
     *
 | 
			
		||||
     * @param bytes A byte array.
 | 
			
		||||
     * @param from  The index of the first byte.
 | 
			
		||||
     * @param thru  The index of the last byte plus one.
 | 
			
		||||
     */
 | 
			
		||||
    public Kim(final byte[] bytes, final int from, final int thru) {
 | 
			
		||||
        // As the bytes are copied into the new kim, a hashcode is computed
 | 
			
		||||
        // using a
 | 
			
		||||
        // modified Fletcher code.
 | 
			
		||||
        int sum = 1;
 | 
			
		||||
        int value;
 | 
			
		||||
        this.hashcode = 0;
 | 
			
		||||
        this.length = thru - from;
 | 
			
		||||
        if (this.length > 0) {
 | 
			
		||||
            this.bytes = new byte[this.length];
 | 
			
		||||
            for (int at = 0; at < this.length; at += 1) {
 | 
			
		||||
                value = bytes[at + from] & 0xFF;
 | 
			
		||||
                sum += value;
 | 
			
		||||
                this.hashcode += sum;
 | 
			
		||||
                this.bytes[at] = (byte) value;
 | 
			
		||||
            }
 | 
			
		||||
            this.hashcode += sum << 16;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Make a kim from a byte array.
 | 
			
		||||
     *
 | 
			
		||||
     * @param bytes  The byte array.
 | 
			
		||||
     * @param length The number of bytes.
 | 
			
		||||
     */
 | 
			
		||||
    public Kim(final byte[] bytes, final int length) {
 | 
			
		||||
        this(bytes, 0, length);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Make a new kim from a substring of an existing kim. The coordinates are in byte units, not character units.
 | 
			
		||||
     *
 | 
			
		||||
     * @param kim  The source of bytes.
 | 
			
		||||
     * @param from The point at which to take bytes.
 | 
			
		||||
     * @param thru The point at which to stop taking bytes.
 | 
			
		||||
     */
 | 
			
		||||
    public Kim(final Kim kim, final int from, final int thru) {
 | 
			
		||||
        this(kim.bytes, from, thru);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Make a kim from a string.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string The string.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException if surrogate pair mismatch.
 | 
			
		||||
     */
 | 
			
		||||
    public Kim(final String string) throws JSONException {
 | 
			
		||||
        final int stringLength = string.length();
 | 
			
		||||
        this.hashcode = 0;
 | 
			
		||||
        this.length = 0;
 | 
			
		||||
        // First pass: Determine the length of the kim, allowing for the UTF-16
 | 
			
		||||
        // to UTF-32 conversion, and then the UTF-32 to Kim conversion.
 | 
			
		||||
        if (stringLength > 0) {
 | 
			
		||||
            for (int i = 0; i < stringLength; i += 1) {
 | 
			
		||||
                final int c = string.charAt(i);
 | 
			
		||||
                if (c <= 0x7F) {
 | 
			
		||||
                    this.length += 1;
 | 
			
		||||
                } else if (c <= 0x3FFF) {
 | 
			
		||||
                    this.length += 2;
 | 
			
		||||
                } else {
 | 
			
		||||
                    if ((c >= 0xD800) && (c <= 0xDFFF)) {
 | 
			
		||||
                        i += 1;
 | 
			
		||||
                        final int d = string.charAt(i);
 | 
			
		||||
                        if ((c > 0xDBFF) || (d < 0xDC00) || (d > 0xDFFF)) {
 | 
			
		||||
                            throw new JSONException("Bad UTF16");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    this.length += 3;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // Second pass: Allocate a byte array and fill that array with the
 | 
			
		||||
            // conversion
 | 
			
		||||
            // while computing the hashcode.
 | 
			
		||||
            this.bytes = new byte[this.length];
 | 
			
		||||
            int at = 0;
 | 
			
		||||
            int b;
 | 
			
		||||
            int sum = 1;
 | 
			
		||||
            for (int i = 0; i < stringLength; i += 1) {
 | 
			
		||||
                int character = string.charAt(i);
 | 
			
		||||
                if (character <= 0x7F) {
 | 
			
		||||
                    this.bytes[at] = (byte) character;
 | 
			
		||||
                    sum += character;
 | 
			
		||||
                    this.hashcode += sum;
 | 
			
		||||
                    at += 1;
 | 
			
		||||
                } else if (character <= 0x3FFF) {
 | 
			
		||||
                    b = 0x80 | (character >>> 7);
 | 
			
		||||
                    this.bytes[at] = (byte) b;
 | 
			
		||||
                    sum += b;
 | 
			
		||||
                    this.hashcode += sum;
 | 
			
		||||
                    at += 1;
 | 
			
		||||
                    b = character & 0x7F;
 | 
			
		||||
                    this.bytes[at] = (byte) b;
 | 
			
		||||
                    sum += b;
 | 
			
		||||
                    this.hashcode += sum;
 | 
			
		||||
                    at += 1;
 | 
			
		||||
                } else {
 | 
			
		||||
                    if ((character >= 0xD800) && (character <= 0xDBFF)) {
 | 
			
		||||
                        i += 1;
 | 
			
		||||
                        character = (((character & 0x3FF) << 10) | (string.charAt(i) & 0x3FF)) + 65536;
 | 
			
		||||
                    }
 | 
			
		||||
                    b = 0x80 | (character >>> 14);
 | 
			
		||||
                    this.bytes[at] = (byte) b;
 | 
			
		||||
                    sum += b;
 | 
			
		||||
                    this.hashcode += sum;
 | 
			
		||||
                    at += 1;
 | 
			
		||||
                    b = 0x80 | ((character >>> 7) & 0xFF);
 | 
			
		||||
                    this.bytes[at] = (byte) b;
 | 
			
		||||
                    sum += b;
 | 
			
		||||
                    this.hashcode += sum;
 | 
			
		||||
                    at += 1;
 | 
			
		||||
                    b = character & 0x7F;
 | 
			
		||||
                    this.bytes[at] = (byte) b;
 | 
			
		||||
                    sum += b;
 | 
			
		||||
                    this.hashcode += sum;
 | 
			
		||||
                    at += 1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            this.hashcode += sum << 16;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the number of bytes needed to contain the character in Kim format.
 | 
			
		||||
     *
 | 
			
		||||
     * @param character a Unicode character between 0 and 0x10FFFF.
 | 
			
		||||
     *
 | 
			
		||||
     * @return 1, 2, or 3
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException if the character is not representable in a kim.
 | 
			
		||||
     */
 | 
			
		||||
    public static int characterSize(final int character) throws JSONException {
 | 
			
		||||
        if ((character < 0) || (character > 0x10FFFF)) {
 | 
			
		||||
            throw new JSONException("Bad character " + character);
 | 
			
		||||
        }
 | 
			
		||||
        return character <= 0x7F ? 1 : character <= 0x3FFF ? 2 : 3;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the character at the specified index. The index refers to byte values and ranges from 0 to length - 1.
 | 
			
		||||
     * The index of the next character is at index + Kim.characterSize(kim.characterAt(index)).
 | 
			
		||||
     *
 | 
			
		||||
     * @param at the index of the char value. The first character is at 0.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException if at does not point to a valid character.
 | 
			
		||||
     * @return a Unicode character between 0 and 0x10FFFF.
 | 
			
		||||
     */
 | 
			
		||||
    public int characterAt(final int at) throws JSONException {
 | 
			
		||||
        final int c = get(at);
 | 
			
		||||
        if ((c & 0x80) == 0) {
 | 
			
		||||
            return c;
 | 
			
		||||
        }
 | 
			
		||||
        int character;
 | 
			
		||||
        final int c1 = get(at + 1);
 | 
			
		||||
        if ((c1 & 0x80) == 0) {
 | 
			
		||||
            character = ((c & 0x7F) << 7) | c1;
 | 
			
		||||
            if (character > 0x7F) {
 | 
			
		||||
                return character;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            final int c2 = get(at + 2);
 | 
			
		||||
            character = ((c & 0x7F) << 14) | ((c1 & 0x7F) << 7) | c2;
 | 
			
		||||
            if (((c2 & 0x80) == 0) && (character > 0x3FFF) && (character <= 0x10FFFF) && ((character < 0xD800) || (character > 0xDFFF))) {
 | 
			
		||||
                return character;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        throw new JSONException("Bad character at " + at);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Copy the contents of this kim to a byte array.
 | 
			
		||||
     *
 | 
			
		||||
     * @param bytes A byte array of sufficient size.
 | 
			
		||||
     * @param at    The position within the byte array to take the byes.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The position immediately after the copy.
 | 
			
		||||
     */
 | 
			
		||||
    public int copy(final byte[] bytes, final int at) {
 | 
			
		||||
        System.arraycopy(this.bytes, 0, bytes, at, this.length);
 | 
			
		||||
        return at + this.length;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Two kim objects containing exactly the same bytes in the same order are equal to each other.
 | 
			
		||||
     *
 | 
			
		||||
     * @param obj the other kim with which to compare.
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if this and obj are both kim objects containing identical byte sequences.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(final Object obj) {
 | 
			
		||||
        if (!(obj instanceof Kim)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final Kim that = (Kim) obj;
 | 
			
		||||
        if (this == that) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        if (this.hashcode != that.hashcode) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return java.util.Arrays.equals(this.bytes, that.bytes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a byte from a kim.
 | 
			
		||||
     *
 | 
			
		||||
     * @param at The position of the byte. The first byte is at 0.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The byte.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException if there is no byte at that position.
 | 
			
		||||
     */
 | 
			
		||||
    public int get(final int at) throws JSONException {
 | 
			
		||||
        if ((at < 0) || (at > this.length)) {
 | 
			
		||||
            throw new JSONException("Bad character at " + at);
 | 
			
		||||
        }
 | 
			
		||||
        return (this.bytes[at]) & 0xFF;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns a hash code value for the kim.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        return this.hashcode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Produce a UTF-16 String from this kim. The number of codepoints in the string will not be greater than the number
 | 
			
		||||
     * of bytes in the kim, although it could be less.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The string. A kim memoizes its string representation.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException if the kim is not valid.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() throws JSONException {
 | 
			
		||||
        if (this.string == null) {
 | 
			
		||||
            int c;
 | 
			
		||||
            int length = 0;
 | 
			
		||||
            final char chars[] = new char[this.length];
 | 
			
		||||
            for (int at = 0; at < this.length; at += characterSize(c)) {
 | 
			
		||||
                c = this.characterAt(at);
 | 
			
		||||
                if (c < 0x10000) {
 | 
			
		||||
                    chars[length] = (char) c;
 | 
			
		||||
                    length += 1;
 | 
			
		||||
                } else {
 | 
			
		||||
                    chars[length] = (char) (0xD800 | ((c - 0x10000) >>> 10));
 | 
			
		||||
                    length += 1;
 | 
			
		||||
                    chars[length] = (char) (0xDC00 | (c & 0x03FF));
 | 
			
		||||
                    length += 1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            this.string = new String(chars, 0, length);
 | 
			
		||||
        }
 | 
			
		||||
        return this.string;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										75
									
								
								src/main/java/com/intellectualcrafters/json/Property.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/main/java/com/intellectualcrafters/json/Property.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
import java.util.Enumeration;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Converts a Property file data into JSONObject and back.
 | 
			
		||||
 *
 | 
			
		||||
 * @author JSON.org
 | 
			
		||||
 * @version 2014-05-03
 | 
			
		||||
 */
 | 
			
		||||
public class Property {
 | 
			
		||||
    /**
 | 
			
		||||
     * Converts a property file object into a JSONObject. The property file object is a table of name value pairs.
 | 
			
		||||
     *
 | 
			
		||||
     * @param properties java.util.Properties
 | 
			
		||||
     *
 | 
			
		||||
     * @return JSONObject
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static JSONObject toJSONObject(final java.util.Properties properties) throws JSONException {
 | 
			
		||||
        final JSONObject jo = new JSONObject();
 | 
			
		||||
        if ((properties != null) && !properties.isEmpty()) {
 | 
			
		||||
            final Enumeration enumProperties = properties.propertyNames();
 | 
			
		||||
            while (enumProperties.hasMoreElements()) {
 | 
			
		||||
                final String name = (String) enumProperties.nextElement();
 | 
			
		||||
                jo.put(name, properties.getProperty(name));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return jo;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Converts the JSONObject into a property file object.
 | 
			
		||||
     *
 | 
			
		||||
     * @param jo JSONObject
 | 
			
		||||
     *
 | 
			
		||||
     * @return java.util.Properties
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static Properties toProperties(final JSONObject jo) throws JSONException {
 | 
			
		||||
        final Properties properties = new Properties();
 | 
			
		||||
        if (jo != null) {
 | 
			
		||||
            final Iterator<String> keys = jo.keys();
 | 
			
		||||
            while (keys.hasNext()) {
 | 
			
		||||
                final String name = keys.next();
 | 
			
		||||
                properties.put(name, jo.getString(name));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return properties;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										388
									
								
								src/main/java/com/intellectualcrafters/json/XML.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										388
									
								
								src/main/java/com/intellectualcrafters/json/XML.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,388 @@
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This provides static methods to convert an XML text into a JSONObject, and to covert a JSONObject into an XML text.
 | 
			
		||||
 *
 | 
			
		||||
 * @author JSON.org
 | 
			
		||||
 * @version 2014-05-03
 | 
			
		||||
 */
 | 
			
		||||
public class XML {
 | 
			
		||||
    public static final Character AMP = '&';
 | 
			
		||||
    public static final Character APOS = '\'';
 | 
			
		||||
    public static final Character BANG = '!';
 | 
			
		||||
    public static final Character EQ = '=';
 | 
			
		||||
    public static final Character GT = '>';
 | 
			
		||||
    public static final Character LT = '<';
 | 
			
		||||
    public static final Character QUEST = '?';
 | 
			
		||||
    public static final Character QUOT = '"';
 | 
			
		||||
    public static final Character SLASH = '/';
 | 
			
		||||
 | 
			
		||||
    public static String escape(final String string) {
 | 
			
		||||
        final StringBuilder sb = new StringBuilder(string.length());
 | 
			
		||||
        for (int i = 0, length = string.length(); i < length; i++) {
 | 
			
		||||
            final char c = string.charAt(i);
 | 
			
		||||
            switch (c) {
 | 
			
		||||
                case '&':
 | 
			
		||||
                    sb.append("&");
 | 
			
		||||
                    break;
 | 
			
		||||
                case '<':
 | 
			
		||||
                    sb.append("<");
 | 
			
		||||
                    break;
 | 
			
		||||
                case '>':
 | 
			
		||||
                    sb.append(">");
 | 
			
		||||
                    break;
 | 
			
		||||
                case '"':
 | 
			
		||||
                    sb.append(""");
 | 
			
		||||
                    break;
 | 
			
		||||
                case '\'':
 | 
			
		||||
                    sb.append("'");
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    sb.append(c);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Throw an exception if the string contains whitespace. Whitespace is not allowed in tagNames and attributes.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string A string.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static void noSpace(final String string) throws JSONException {
 | 
			
		||||
        int i;
 | 
			
		||||
        final int length = string.length();
 | 
			
		||||
        if (length == 0) {
 | 
			
		||||
            throw new JSONException("Empty string.");
 | 
			
		||||
        }
 | 
			
		||||
        for (i = 0; i < length; i += 1) {
 | 
			
		||||
            if (Character.isWhitespace(string.charAt(i))) {
 | 
			
		||||
                throw new JSONException("'" + string + "' contains a space character.");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Scan the content following the named tag, attaching it to the context.
 | 
			
		||||
     *
 | 
			
		||||
     * @param x       The XMLTokener containing the source string.
 | 
			
		||||
     * @param context The JSONObject that will include the new material.
 | 
			
		||||
     * @param name    The tag name.
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if the close tag is processed.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    private static boolean parse(final XMLTokener x, final JSONObject context, final String name) throws JSONException {
 | 
			
		||||
        char c;
 | 
			
		||||
        int i;
 | 
			
		||||
        JSONObject jsonobject = null;
 | 
			
		||||
        String string;
 | 
			
		||||
        String tagName;
 | 
			
		||||
        Object token;
 | 
			
		||||
        // Test for and skip past these forms:
 | 
			
		||||
        // <!-- ... -->
 | 
			
		||||
        // <! ... >
 | 
			
		||||
        // <![ ... ]]>
 | 
			
		||||
        // <? ... ?>
 | 
			
		||||
        // Report errors for these forms:
 | 
			
		||||
        // <>
 | 
			
		||||
        // <=
 | 
			
		||||
        // <<
 | 
			
		||||
        token = x.nextToken();
 | 
			
		||||
        // <!
 | 
			
		||||
        if (token == BANG) {
 | 
			
		||||
            c = x.next();
 | 
			
		||||
            if (c == '-') {
 | 
			
		||||
                if (x.next() == '-') {
 | 
			
		||||
                    x.skipPast("-->");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                x.back();
 | 
			
		||||
            } else if (c == '[') {
 | 
			
		||||
                token = x.nextToken();
 | 
			
		||||
                if ("CDATA".equals(token)) {
 | 
			
		||||
                    if (x.next() == '[') {
 | 
			
		||||
                        string = x.nextCDATA();
 | 
			
		||||
                        if (string.length() > 0) {
 | 
			
		||||
                            context.accumulate("content", string);
 | 
			
		||||
                        }
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                throw x.syntaxError("Expected 'CDATA['");
 | 
			
		||||
            }
 | 
			
		||||
            i = 1;
 | 
			
		||||
            do {
 | 
			
		||||
                token = x.nextMeta();
 | 
			
		||||
                if (token == null) {
 | 
			
		||||
                    throw x.syntaxError("Missing '>' after '<!'.");
 | 
			
		||||
                } else if (token == LT) {
 | 
			
		||||
                    i += 1;
 | 
			
		||||
                } else if (token == GT) {
 | 
			
		||||
                    i -= 1;
 | 
			
		||||
                }
 | 
			
		||||
            } while (i > 0);
 | 
			
		||||
            return false;
 | 
			
		||||
        } else if (token == QUEST) {
 | 
			
		||||
            // <?
 | 
			
		||||
            x.skipPast("?>");
 | 
			
		||||
            return false;
 | 
			
		||||
        } else if (token == SLASH) {
 | 
			
		||||
            // Close tag </
 | 
			
		||||
            token = x.nextToken();
 | 
			
		||||
            if (name == null) {
 | 
			
		||||
                throw x.syntaxError("Mismatched close tag " + token);
 | 
			
		||||
            }
 | 
			
		||||
            if (!token.equals(name)) {
 | 
			
		||||
                throw x.syntaxError("Mismatched " + name + " and " + token);
 | 
			
		||||
            }
 | 
			
		||||
            if (x.nextToken() != GT) {
 | 
			
		||||
                throw x.syntaxError("Misshaped close tag");
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if (token instanceof Character) {
 | 
			
		||||
            throw x.syntaxError("Misshaped tag");
 | 
			
		||||
            // Open tag <
 | 
			
		||||
        } else {
 | 
			
		||||
            tagName = (String) token;
 | 
			
		||||
            token = null;
 | 
			
		||||
            jsonobject = new JSONObject();
 | 
			
		||||
            for (;;) {
 | 
			
		||||
                if (token == null) {
 | 
			
		||||
                    token = x.nextToken();
 | 
			
		||||
                }
 | 
			
		||||
                // attribute = value
 | 
			
		||||
                if (token instanceof String) {
 | 
			
		||||
                    string = (String) token;
 | 
			
		||||
                    token = x.nextToken();
 | 
			
		||||
                    if (token == EQ) {
 | 
			
		||||
                        token = x.nextToken();
 | 
			
		||||
                        if (!(token instanceof String)) {
 | 
			
		||||
                            throw x.syntaxError("Missing value");
 | 
			
		||||
                        }
 | 
			
		||||
                        jsonobject.accumulate(string, XML.stringToValue((String) token));
 | 
			
		||||
                        token = null;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        jsonobject.accumulate(string, "");
 | 
			
		||||
                    }
 | 
			
		||||
                    // Empty tag <.../>
 | 
			
		||||
                } else if (token == SLASH) {
 | 
			
		||||
                    if (x.nextToken() != GT) {
 | 
			
		||||
                        throw x.syntaxError("Misshaped tag");
 | 
			
		||||
                    }
 | 
			
		||||
                    if (jsonobject.length() > 0) {
 | 
			
		||||
                        context.accumulate(tagName, jsonobject);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        context.accumulate(tagName, "");
 | 
			
		||||
                    }
 | 
			
		||||
                    return false;
 | 
			
		||||
                    // Content, between <...> and </...>
 | 
			
		||||
                } else if (token == GT) {
 | 
			
		||||
                    for (;;) {
 | 
			
		||||
                        token = x.nextContent();
 | 
			
		||||
                        if (token == null) {
 | 
			
		||||
                            if (tagName != null) {
 | 
			
		||||
                                throw x.syntaxError("Unclosed tag " + tagName);
 | 
			
		||||
                            }
 | 
			
		||||
                            return false;
 | 
			
		||||
                        } else if (token instanceof String) {
 | 
			
		||||
                            string = (String) token;
 | 
			
		||||
                            if (string.length() > 0) {
 | 
			
		||||
                                jsonobject.accumulate("content", XML.stringToValue(string));
 | 
			
		||||
                            }
 | 
			
		||||
                            // Nested element
 | 
			
		||||
                        } else if (token == LT) {
 | 
			
		||||
                            if (parse(x, jsonobject, tagName)) {
 | 
			
		||||
                                if (jsonobject.length() == 0) {
 | 
			
		||||
                                    context.accumulate(tagName, "");
 | 
			
		||||
                                } else if ((jsonobject.length() == 1) && (jsonobject.opt("content") != null)) {
 | 
			
		||||
                                    context.accumulate(tagName, jsonobject.opt("content"));
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    context.accumulate(tagName, jsonobject);
 | 
			
		||||
                                }
 | 
			
		||||
                                return false;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    throw x.syntaxError("Misshaped tag");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Try to convert a string into a number, boolean, or null. If the string can't be converted, return the string.
 | 
			
		||||
     * This is much less ambitious than JSONObject.stringToValue, especially because it does not attempt to convert plus
 | 
			
		||||
     * forms, octal forms, hex forms, or E forms lacking decimal points.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string A String.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A simple JSON value.
 | 
			
		||||
     */
 | 
			
		||||
    public static Object stringToValue(final String string) {
 | 
			
		||||
        if ("true".equalsIgnoreCase(string)) {
 | 
			
		||||
            return Boolean.TRUE;
 | 
			
		||||
        }
 | 
			
		||||
        if ("false".equalsIgnoreCase(string)) {
 | 
			
		||||
            return Boolean.FALSE;
 | 
			
		||||
        }
 | 
			
		||||
        if ("null".equalsIgnoreCase(string)) {
 | 
			
		||||
            return JSONObject.NULL;
 | 
			
		||||
        }
 | 
			
		||||
        // If it might be a number, try converting it, first as a Long, and then
 | 
			
		||||
        // as a
 | 
			
		||||
        // Double. If that doesn't work, return the string.
 | 
			
		||||
        try {
 | 
			
		||||
            final char initial = string.charAt(0);
 | 
			
		||||
            if ((initial == '-') || ((initial >= '0') && (initial <= '9'))) {
 | 
			
		||||
                final Long value = new Long(string);
 | 
			
		||||
                if (value.toString().equals(string)) {
 | 
			
		||||
                    return value;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } catch (final Exception ignore) {
 | 
			
		||||
            try {
 | 
			
		||||
                final Double value = new Double(string);
 | 
			
		||||
                if (value.toString().equals(string)) {
 | 
			
		||||
                    return value;
 | 
			
		||||
                }
 | 
			
		||||
            } catch (final Exception ignoreAlso) {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return string;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static JSONObject toJSONObject(final String string) throws JSONException {
 | 
			
		||||
        final JSONObject jo = new JSONObject();
 | 
			
		||||
        final XMLTokener x = new XMLTokener(string);
 | 
			
		||||
        while (x.more() && x.skipPast("<")) {
 | 
			
		||||
            parse(x, jo, null);
 | 
			
		||||
        }
 | 
			
		||||
        return jo;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert a JSONObject into a well-formed, element-normal XML string.
 | 
			
		||||
     *
 | 
			
		||||
     * @param object A JSONObject.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A string.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static String toString(final Object object) throws JSONException {
 | 
			
		||||
        return toString(object, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert a JSONObject into a well-formed, element-normal XML string.
 | 
			
		||||
     *
 | 
			
		||||
     * @param object  A JSONObject.
 | 
			
		||||
     * @param tagName The optional name of the enclosing tag.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A string.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public static String toString(Object object, final String tagName) throws JSONException {
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        int i;
 | 
			
		||||
        JSONArray ja;
 | 
			
		||||
        JSONObject jo;
 | 
			
		||||
        String key;
 | 
			
		||||
        Iterator<String> keys;
 | 
			
		||||
        int length;
 | 
			
		||||
        String string;
 | 
			
		||||
        Object value;
 | 
			
		||||
        if (object instanceof JSONObject) {
 | 
			
		||||
            // Emit <tagName>
 | 
			
		||||
            if (tagName != null) {
 | 
			
		||||
                sb.append('<');
 | 
			
		||||
                sb.append(tagName);
 | 
			
		||||
                sb.append('>');
 | 
			
		||||
            }
 | 
			
		||||
            // Loop thru the keys.
 | 
			
		||||
            jo = (JSONObject) object;
 | 
			
		||||
            keys = jo.keys();
 | 
			
		||||
            while (keys.hasNext()) {
 | 
			
		||||
                key = keys.next();
 | 
			
		||||
                value = jo.opt(key);
 | 
			
		||||
                if (value == null) {
 | 
			
		||||
                    value = "";
 | 
			
		||||
                }
 | 
			
		||||
                string = value instanceof String ? (String) value : null;
 | 
			
		||||
                // Emit content in body
 | 
			
		||||
                if ("content".equals(key)) {
 | 
			
		||||
                    if (value instanceof JSONArray) {
 | 
			
		||||
                        ja = (JSONArray) value;
 | 
			
		||||
                        length = ja.length();
 | 
			
		||||
                        for (i = 0; i < length; i += 1) {
 | 
			
		||||
                            if (i > 0) {
 | 
			
		||||
                                sb.append('\n');
 | 
			
		||||
                            }
 | 
			
		||||
                            sb.append(escape(ja.get(i).toString()));
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        sb.append(escape(value.toString()));
 | 
			
		||||
                    }
 | 
			
		||||
                    // Emit an array of similar keys
 | 
			
		||||
                } else if (value instanceof JSONArray) {
 | 
			
		||||
                    ja = (JSONArray) value;
 | 
			
		||||
                    length = ja.length();
 | 
			
		||||
                    for (i = 0; i < length; i += 1) {
 | 
			
		||||
                        value = ja.get(i);
 | 
			
		||||
                        if (value instanceof JSONArray) {
 | 
			
		||||
                            sb.append('<');
 | 
			
		||||
                            sb.append(key);
 | 
			
		||||
                            sb.append('>');
 | 
			
		||||
                            sb.append(toString(value));
 | 
			
		||||
                            sb.append("</");
 | 
			
		||||
                            sb.append(key);
 | 
			
		||||
                            sb.append('>');
 | 
			
		||||
                        } else {
 | 
			
		||||
                            sb.append(toString(value, key));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } else if ("".equals(value)) {
 | 
			
		||||
                    sb.append('<');
 | 
			
		||||
                    sb.append(key);
 | 
			
		||||
                    sb.append("/>");
 | 
			
		||||
                    // Emit a new tag <k>
 | 
			
		||||
                } else {
 | 
			
		||||
                    sb.append(toString(value, key));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (tagName != null) {
 | 
			
		||||
                // Emit the </tagname> close tag
 | 
			
		||||
                sb.append("</");
 | 
			
		||||
                sb.append(tagName);
 | 
			
		||||
                sb.append('>');
 | 
			
		||||
            }
 | 
			
		||||
            return sb.toString();
 | 
			
		||||
            // XML does not have good support for arrays. If an array appears in
 | 
			
		||||
            // a place
 | 
			
		||||
            // where XML is lacking, synthesize an <array> element.
 | 
			
		||||
        } else {
 | 
			
		||||
            if (object.getClass().isArray()) {
 | 
			
		||||
                object = new JSONArray(object);
 | 
			
		||||
            }
 | 
			
		||||
            if (object instanceof JSONArray) {
 | 
			
		||||
                ja = (JSONArray) object;
 | 
			
		||||
                length = ja.length();
 | 
			
		||||
                for (i = 0; i < length; i += 1) {
 | 
			
		||||
                    sb.append(toString(ja.opt(i), tagName == null ? "array" : tagName));
 | 
			
		||||
                }
 | 
			
		||||
                return sb.toString();
 | 
			
		||||
            } else {
 | 
			
		||||
                string = (object == null) ? "null" : escape(object.toString());
 | 
			
		||||
                return (tagName == null) ? "\"" + string + "\"" : (string.length() == 0) ? "<" + tagName + "/>" : "<" + tagName + ">" + string + "</" + tagName + ">";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										324
									
								
								src/main/java/com/intellectualcrafters/json/XMLTokener.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										324
									
								
								src/main/java/com/intellectualcrafters/json/XMLTokener.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,324 @@
 | 
			
		||||
package com.intellectualcrafters.json;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The XMLTokener extends the JSONTokener to provide additional methods for the parsing of XML texts.
 | 
			
		||||
 *
 | 
			
		||||
 * @author JSON.org
 | 
			
		||||
 * @version 2014-05-03
 | 
			
		||||
 */
 | 
			
		||||
public class XMLTokener extends JSONTokener {
 | 
			
		||||
    /**
 | 
			
		||||
     * The table of entity values. It initially contains Character values for amp, apos, gt, lt, quot.
 | 
			
		||||
     */
 | 
			
		||||
    public static final java.util.HashMap<String, Character> entity;
 | 
			
		||||
    static {
 | 
			
		||||
        entity = new java.util.HashMap<String, Character>(8);
 | 
			
		||||
        entity.put("amp", XML.AMP);
 | 
			
		||||
        entity.put("apos", XML.APOS);
 | 
			
		||||
        entity.put("gt", XML.GT);
 | 
			
		||||
        entity.put("lt", XML.LT);
 | 
			
		||||
        entity.put("quot", XML.QUOT);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct an XMLTokener from a string.
 | 
			
		||||
     *
 | 
			
		||||
     * @param s A source string.
 | 
			
		||||
     */
 | 
			
		||||
    public XMLTokener(final String s) {
 | 
			
		||||
        super(s);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the text in the CDATA block.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The string up to the <code>]]></code>.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the <code>]]></code> is not found.
 | 
			
		||||
     */
 | 
			
		||||
    public String nextCDATA() throws JSONException {
 | 
			
		||||
        char c;
 | 
			
		||||
        int i;
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        for (;;) {
 | 
			
		||||
            c = next();
 | 
			
		||||
            if (end()) {
 | 
			
		||||
                throw syntaxError("Unclosed CDATA");
 | 
			
		||||
            }
 | 
			
		||||
            sb.append(c);
 | 
			
		||||
            i = sb.length() - 3;
 | 
			
		||||
            if ((i >= 0) && (sb.charAt(i) == ']') && (sb.charAt(i + 1) == ']') && (sb.charAt(i + 2) == '>')) {
 | 
			
		||||
                sb.setLength(i);
 | 
			
		||||
                return sb.toString();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the next XML outer token, trimming whitespace. There are two kinds of tokens: the '<' character which begins
 | 
			
		||||
     * a markup tag, and the content text between markup tags.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A string, or a '<' Character, or null if there is no more source text.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public Object nextContent() throws JSONException {
 | 
			
		||||
        char c;
 | 
			
		||||
        StringBuilder sb;
 | 
			
		||||
        do {
 | 
			
		||||
            c = next();
 | 
			
		||||
        } while (Character.isWhitespace(c));
 | 
			
		||||
        if (c == 0) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        if (c == '<') {
 | 
			
		||||
            return XML.LT;
 | 
			
		||||
        }
 | 
			
		||||
        sb = new StringBuilder();
 | 
			
		||||
        for (;;) {
 | 
			
		||||
            if ((c == '<') || (c == 0)) {
 | 
			
		||||
                back();
 | 
			
		||||
                return sb.toString().trim();
 | 
			
		||||
            }
 | 
			
		||||
            if (c == '&') {
 | 
			
		||||
                sb.append(nextEntity(c));
 | 
			
		||||
            } else {
 | 
			
		||||
                sb.append(c);
 | 
			
		||||
            }
 | 
			
		||||
            c = next();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Return the next entity. These entities are translated to Characters: <code>& " >  <
 | 
			
		||||
     * "</code>.
 | 
			
		||||
     *
 | 
			
		||||
     * @param ampersand An ampersand character.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A Character or an entity String if the entity is not recognized.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If missing ';' in XML entity.
 | 
			
		||||
     */
 | 
			
		||||
    public Object nextEntity(final char ampersand) throws JSONException {
 | 
			
		||||
        final StringBuilder sb = new StringBuilder();
 | 
			
		||||
        for (;;) {
 | 
			
		||||
            final char c = next();
 | 
			
		||||
            if (Character.isLetterOrDigit(c) || (c == '#')) {
 | 
			
		||||
                sb.append(Character.toLowerCase(c));
 | 
			
		||||
            } else if (c == ';') {
 | 
			
		||||
                break;
 | 
			
		||||
            } else {
 | 
			
		||||
                throw syntaxError("Missing ';' in XML entity: &" + sb);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        final String string = sb.toString();
 | 
			
		||||
        final Object object = entity.get(string);
 | 
			
		||||
        return object != null ? object : ampersand + string + ";";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the next XML meta token. This is used for skipping over <!...> and <?...?> structures.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Syntax characters (<code>< > / = ! ?</code>) are returned as Character, and strings and names are
 | 
			
		||||
     * returned as Boolean. We don't care what the values actually are.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If a string is not properly closed or if the XML is badly structured.
 | 
			
		||||
     */
 | 
			
		||||
    public Object nextMeta() throws JSONException {
 | 
			
		||||
        char c;
 | 
			
		||||
        char q;
 | 
			
		||||
        do {
 | 
			
		||||
            c = next();
 | 
			
		||||
        } while (Character.isWhitespace(c));
 | 
			
		||||
        switch (c) {
 | 
			
		||||
            case 0:
 | 
			
		||||
                throw syntaxError("Misshaped meta tag");
 | 
			
		||||
            case '<':
 | 
			
		||||
                return XML.LT;
 | 
			
		||||
            case '>':
 | 
			
		||||
                return XML.GT;
 | 
			
		||||
            case '/':
 | 
			
		||||
                return XML.SLASH;
 | 
			
		||||
            case '=':
 | 
			
		||||
                return XML.EQ;
 | 
			
		||||
            case '!':
 | 
			
		||||
                return XML.BANG;
 | 
			
		||||
            case '?':
 | 
			
		||||
                return XML.QUEST;
 | 
			
		||||
            case '"':
 | 
			
		||||
            case '\'':
 | 
			
		||||
                q = c;
 | 
			
		||||
                for (;;) {
 | 
			
		||||
                    c = next();
 | 
			
		||||
                    if (c == 0) {
 | 
			
		||||
                        throw syntaxError("Unterminated string");
 | 
			
		||||
                    }
 | 
			
		||||
                    if (c == q) {
 | 
			
		||||
                        return Boolean.TRUE;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            default:
 | 
			
		||||
                for (;;) {
 | 
			
		||||
                    c = next();
 | 
			
		||||
                    if (Character.isWhitespace(c)) {
 | 
			
		||||
                        return Boolean.TRUE;
 | 
			
		||||
                    }
 | 
			
		||||
                    switch (c) {
 | 
			
		||||
                        case 0:
 | 
			
		||||
                        case '<':
 | 
			
		||||
                        case '>':
 | 
			
		||||
                        case '/':
 | 
			
		||||
                        case '=':
 | 
			
		||||
                        case '!':
 | 
			
		||||
                        case '?':
 | 
			
		||||
                        case '"':
 | 
			
		||||
                        case '\'':
 | 
			
		||||
                            back();
 | 
			
		||||
                            return Boolean.TRUE;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the next XML Token. These tokens are found inside of angle brackets. It may be one of these characters:
 | 
			
		||||
     * <code>/ >= ! ?</code> or it may be a string wrapped in single quotes or double quotes, or it may be a name.
 | 
			
		||||
     *
 | 
			
		||||
     * @return a String or a Character.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException If the XML is not well formed.
 | 
			
		||||
     */
 | 
			
		||||
    public Object nextToken() throws JSONException {
 | 
			
		||||
        char c;
 | 
			
		||||
        char q;
 | 
			
		||||
        StringBuilder sb;
 | 
			
		||||
        do {
 | 
			
		||||
            c = next();
 | 
			
		||||
        } while (Character.isWhitespace(c));
 | 
			
		||||
        switch (c) {
 | 
			
		||||
            case 0:
 | 
			
		||||
                throw syntaxError("Misshaped element");
 | 
			
		||||
            case '<':
 | 
			
		||||
                throw syntaxError("Misplaced '<'");
 | 
			
		||||
            case '>':
 | 
			
		||||
                return XML.GT;
 | 
			
		||||
            case '/':
 | 
			
		||||
                return XML.SLASH;
 | 
			
		||||
            case '=':
 | 
			
		||||
                return XML.EQ;
 | 
			
		||||
            case '!':
 | 
			
		||||
                return XML.BANG;
 | 
			
		||||
            case '?':
 | 
			
		||||
                return XML.QUEST;
 | 
			
		||||
                // Quoted string
 | 
			
		||||
            case '"':
 | 
			
		||||
            case '\'':
 | 
			
		||||
                q = c;
 | 
			
		||||
                sb = new StringBuilder();
 | 
			
		||||
                for (;;) {
 | 
			
		||||
                    c = next();
 | 
			
		||||
                    if (c == 0) {
 | 
			
		||||
                        throw syntaxError("Unterminated string");
 | 
			
		||||
                    }
 | 
			
		||||
                    if (c == q) {
 | 
			
		||||
                        return sb.toString();
 | 
			
		||||
                    }
 | 
			
		||||
                    if (c == '&') {
 | 
			
		||||
                        sb.append(nextEntity(c));
 | 
			
		||||
                    } else {
 | 
			
		||||
                        sb.append(c);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            default:
 | 
			
		||||
                // Name
 | 
			
		||||
                sb = new StringBuilder();
 | 
			
		||||
                for (;;) {
 | 
			
		||||
                    sb.append(c);
 | 
			
		||||
                    c = next();
 | 
			
		||||
                    if (Character.isWhitespace(c)) {
 | 
			
		||||
                        return sb.toString();
 | 
			
		||||
                    }
 | 
			
		||||
                    switch (c) {
 | 
			
		||||
                        case 0:
 | 
			
		||||
                            return sb.toString();
 | 
			
		||||
                        case '>':
 | 
			
		||||
                        case '/':
 | 
			
		||||
                        case '=':
 | 
			
		||||
                        case '!':
 | 
			
		||||
                        case '?':
 | 
			
		||||
                        case '[':
 | 
			
		||||
                        case ']':
 | 
			
		||||
                            back();
 | 
			
		||||
                            return sb.toString();
 | 
			
		||||
                        case '<':
 | 
			
		||||
                        case '"':
 | 
			
		||||
                        case '\'':
 | 
			
		||||
                            throw syntaxError("Bad character in a name");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Skip characters until past the requested string. If it is not found, we are left at the end of the source with a
 | 
			
		||||
     * result of false.
 | 
			
		||||
     *
 | 
			
		||||
     * @param to A string to skip past.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws JSONException
 | 
			
		||||
     */
 | 
			
		||||
    public boolean skipPast(final String to) throws JSONException {
 | 
			
		||||
        boolean b;
 | 
			
		||||
        char c;
 | 
			
		||||
        int i;
 | 
			
		||||
        int j;
 | 
			
		||||
        int offset = 0;
 | 
			
		||||
        final int length = to.length();
 | 
			
		||||
        final char[] circle = new char[length];
 | 
			
		||||
        /*
 | 
			
		||||
         * First fill the circle buffer with as many characters as are in the
 | 
			
		||||
         * to string. If we reach an early end, bail.
 | 
			
		||||
         */
 | 
			
		||||
        for (i = 0; i < length; i += 1) {
 | 
			
		||||
            c = next();
 | 
			
		||||
            if (c == 0) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            circle[i] = c;
 | 
			
		||||
        }
 | 
			
		||||
        /* We will loop, possibly for all of the remaining characters. */
 | 
			
		||||
        for (;;) {
 | 
			
		||||
            j = offset;
 | 
			
		||||
            b = true;
 | 
			
		||||
            /* Compare the circle buffer with the to string. */
 | 
			
		||||
            for (i = 0; i < length; i += 1) {
 | 
			
		||||
                if (circle[j] != to.charAt(i)) {
 | 
			
		||||
                    b = false;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                j += 1;
 | 
			
		||||
                if (j >= length) {
 | 
			
		||||
                    j -= length;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            /* If we exit the loop with b intact, then victory is ours. */
 | 
			
		||||
            if (b) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            /* Get the next character. If there isn't one, then defeat is ours. */
 | 
			
		||||
            c = next();
 | 
			
		||||
            if (c == 0) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            /*
 | 
			
		||||
             * Shove the character in the circle buffer and advance the
 | 
			
		||||
             * circle offset. The offset is mod n.
 | 
			
		||||
             */
 | 
			
		||||
            circle[offset] = c;
 | 
			
		||||
            offset += 1;
 | 
			
		||||
            if (offset >= length) {
 | 
			
		||||
                offset -= length;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										796
									
								
								src/main/java/com/intellectualcrafters/plot/BukkitMain.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										796
									
								
								src/main/java/com/intellectualcrafters/plot/BukkitMain.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,796 @@
 | 
			
		||||
package com.intellectualcrafters.plot;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.PrintWriter;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.net.URLClassLoader;
 | 
			
		||||
import java.util.ArrayDeque;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Stack;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.commands.*;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.ChatColor;
 | 
			
		||||
import org.bukkit.Chunk;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.World;
 | 
			
		||||
import org.bukkit.command.PluginCommand;
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.event.Listener;
 | 
			
		||||
import org.bukkit.generator.ChunkGenerator;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
import org.bukkit.plugin.PluginManager;
 | 
			
		||||
import org.bukkit.plugin.java.JavaPlugin;
 | 
			
		||||
import org.bukkit.plugin.java.JavaPluginLoader;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.database.plotme.ClassicPlotMeConnector;
 | 
			
		||||
import com.intellectualcrafters.plot.database.plotme.LikePlotMeConverter;
 | 
			
		||||
import com.intellectualcrafters.plot.database.plotme.PlotMeConnector_017;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.FlagManager;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.BukkitHybridUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridGen;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.APlotListener;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.ChunkListener;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.ForceFieldListener;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.InventoryListener;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.PlayerEvents;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.PlayerEvents_1_8;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.PlayerEvents_1_8_3;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.PlotListener;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.PlotPlusListener;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.TNTListener;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.WorldEvents;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.worldedit.WEListener;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.worldedit.WESubscriber;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotManager;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.titles.AbstractTitle;
 | 
			
		||||
import com.intellectualcrafters.plot.titles.DefaultTitle;
 | 
			
		||||
import com.intellectualcrafters.plot.util.BlockManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.BlockUpdateUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ChunkManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ConsoleColors;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EconHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EventUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.InventoryUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.PlayerManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.SetupUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitChunkManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitEconHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitEventUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitInventoryUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitPlayerManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitSetBlockManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitSetupUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitTaskManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.Metrics;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.SendChunk;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.SetBlockFast;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.SetBlockFast_1_8;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.SetBlockSlow;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.SetGenCB;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.uuid.DefaultUUIDWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.uuid.LowerOfflineUUIDWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.uuid.OfflineUUIDWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
 | 
			
		||||
import com.sk89q.worldedit.WorldEdit;
 | 
			
		||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
 | 
			
		||||
 | 
			
		||||
public class BukkitMain extends JavaPlugin implements Listener, IPlotMain {
 | 
			
		||||
    
 | 
			
		||||
    public static BukkitMain THIS = null;
 | 
			
		||||
    
 | 
			
		||||
    private int[] version;
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean checkVersion(final int major, final int minor, final int minor2) {
 | 
			
		||||
        if (version == null) {
 | 
			
		||||
            try {
 | 
			
		||||
                version = new int[3];
 | 
			
		||||
                final String[] split = Bukkit.getBukkitVersion().split("-")[0].split("\\.");
 | 
			
		||||
                version[0] = Integer.parseInt(split[0]);
 | 
			
		||||
                version[1] = Integer.parseInt(split[1]);
 | 
			
		||||
                if (version.length == 3) {
 | 
			
		||||
                    version[2] = Integer.parseInt(split[2]);
 | 
			
		||||
                }
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return (version[0] > major) || ((version[0] == major) && (version[1] > minor)) || ((version[0] == major) && (version[1] == minor) && (version[2] >= minor2));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onEnable() {
 | 
			
		||||
        THIS = this;
 | 
			
		||||
        PS.instance = new PS(this);
 | 
			
		||||
        if (Settings.METRICS) {
 | 
			
		||||
            try {
 | 
			
		||||
                final Metrics metrics = new Metrics(this);
 | 
			
		||||
                metrics.start();
 | 
			
		||||
                log(C.PREFIX.s() + "&6Metrics enabled.");
 | 
			
		||||
            } catch (final Exception e) {
 | 
			
		||||
                log(C.PREFIX.s() + "&cFailed to load up metrics.");
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            log("&dUsing metrics will allow us to improve the plugin, please consider it :)");
 | 
			
		||||
        }
 | 
			
		||||
//        File file = new File(this.getDirectory() + File.separator + "disabled.yml");
 | 
			
		||||
//        if (file.exists()) {
 | 
			
		||||
//            file.delete();
 | 
			
		||||
//            try {
 | 
			
		||||
//                String[] split = new String(Files.readAllBytes(file.toPath())).split(",");
 | 
			
		||||
//                for (String plugin : split) {
 | 
			
		||||
//                    loadPlugin(plugin);
 | 
			
		||||
//                }
 | 
			
		||||
//            } catch (IOException e) {
 | 
			
		||||
//                e.printStackTrace();
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
        List<World> worlds = Bukkit.getWorlds();
 | 
			
		||||
        if (worlds.size() > 0) {
 | 
			
		||||
            UUIDHandler.cacheAll(worlds.get(0).getName());
 | 
			
		||||
            for (World world : worlds) {
 | 
			
		||||
                try {
 | 
			
		||||
                    SetGenCB.setGenerator(world);
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                    log("Failed to reload world: " + world.getName());
 | 
			
		||||
                    Bukkit.getServer().unloadWorld(world, false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onDisable() {
 | 
			
		||||
        PS.get().disable();
 | 
			
		||||
        try {
 | 
			
		||||
            unloadRecursively(this);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        };
 | 
			
		||||
        THIS = null;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void log(String message) {
 | 
			
		||||
        if (message == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        message = message.replaceAll("\u00B2", "2");
 | 
			
		||||
        if (THIS != null && Bukkit.getServer().getConsoleSender() != null) {
 | 
			
		||||
            try {
 | 
			
		||||
                message = ChatColor.translateAlternateColorCodes('&', message);
 | 
			
		||||
                if (!Settings.CONSOLE_COLOR) {
 | 
			
		||||
                    message = ChatColor.stripColor(message);
 | 
			
		||||
                }
 | 
			
		||||
                Bukkit.getServer().getConsoleSender().sendMessage(message);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Throwable e) {};
 | 
			
		||||
        }
 | 
			
		||||
        System.out.println(ConsoleColors.fromString(message));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void disable() {
 | 
			
		||||
        onDisable();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getVersion() {
 | 
			
		||||
        return this.getDescription().getVersion();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void handleKick(UUID uuid, C c) {
 | 
			
		||||
        Player player = Bukkit.getPlayer(uuid);
 | 
			
		||||
        if (player != null && player.isOnline()) {
 | 
			
		||||
            MainUtil.sendMessage(BukkitUtil.getPlayer(player), c);
 | 
			
		||||
            player.teleport(player.getWorld().getSpawnLocation());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void registerCommands() {
 | 
			
		||||
        new MainCommand();
 | 
			
		||||
        MainCommand.subCommands.add(new Download());
 | 
			
		||||
        MainCommand.subCommands.add(new Disable());
 | 
			
		||||
        MainCommand.subCommands.add(new Update());
 | 
			
		||||
        MainCommand.subCommands.add(new Template());
 | 
			
		||||
        MainCommand.subCommands.add(new Setup());
 | 
			
		||||
        MainCommand.subCommands.add(new DebugUUID());
 | 
			
		||||
        MainCommand.subCommands.add(new DebugFill());
 | 
			
		||||
        MainCommand.subCommands.add(new DebugSaveTest());
 | 
			
		||||
        MainCommand.subCommands.add(new DebugLoadTest());
 | 
			
		||||
        MainCommand.subCommands.add(new CreateRoadSchematic());
 | 
			
		||||
        MainCommand.subCommands.add(new DebugAllowUnsafe());
 | 
			
		||||
        MainCommand.subCommands.add(new RegenAllRoads());
 | 
			
		||||
        MainCommand.subCommands.add(new DebugClear());
 | 
			
		||||
        MainCommand.subCommands.add(new Claim());
 | 
			
		||||
        MainCommand.subCommands.add(new Auto());
 | 
			
		||||
        MainCommand.subCommands.add(new Home());
 | 
			
		||||
        MainCommand.subCommands.add(new Visit());
 | 
			
		||||
        MainCommand.subCommands.add(new TP());
 | 
			
		||||
        MainCommand.subCommands.add(new Set());
 | 
			
		||||
        MainCommand.subCommands.add(new Toggle());
 | 
			
		||||
        MainCommand.subCommands.add(new Clear());
 | 
			
		||||
        MainCommand.subCommands.add(new Delete());
 | 
			
		||||
        MainCommand.subCommands.add(new SetOwner());
 | 
			
		||||
        if (Settings.ENABLE_CLUSTERS) {
 | 
			
		||||
            MainCommand.subCommands.add(new Cluster());
 | 
			
		||||
        }
 | 
			
		||||
        MainCommand.subCommands.add(new Trust());
 | 
			
		||||
        MainCommand.subCommands.add(new Add());
 | 
			
		||||
        MainCommand.subCommands.add(new Deny());
 | 
			
		||||
        MainCommand.subCommands.add(new Untrust());
 | 
			
		||||
        MainCommand.subCommands.add(new Remove());
 | 
			
		||||
        MainCommand.subCommands.add(new Undeny());
 | 
			
		||||
        MainCommand.subCommands.add(new Info());
 | 
			
		||||
        MainCommand.subCommands.add(new list());
 | 
			
		||||
        MainCommand.subCommands.add(new Help());
 | 
			
		||||
        MainCommand.subCommands.add(new Debug());
 | 
			
		||||
        MainCommand.subCommands.add(new SchematicCmd());
 | 
			
		||||
        MainCommand.subCommands.add(new plugin());
 | 
			
		||||
        MainCommand.subCommands.add(new Inventory());
 | 
			
		||||
        MainCommand.subCommands.add(new Purge());
 | 
			
		||||
        MainCommand.subCommands.add(new Reload());
 | 
			
		||||
        MainCommand.subCommands.add(new Merge());
 | 
			
		||||
        MainCommand.subCommands.add(new Unlink());
 | 
			
		||||
        MainCommand.subCommands.add(new Kick());
 | 
			
		||||
        MainCommand.subCommands.add(new Rate());
 | 
			
		||||
        MainCommand.subCommands.add(new DebugClaimTest());
 | 
			
		||||
        MainCommand.subCommands.add(new Inbox());
 | 
			
		||||
        MainCommand.subCommands.add(new Comment());
 | 
			
		||||
        MainCommand.subCommands.add(new Database());
 | 
			
		||||
        MainCommand.subCommands.add(new Unclaim());
 | 
			
		||||
        MainCommand.subCommands.add(new Swap());
 | 
			
		||||
        MainCommand.subCommands.add(new MusicSubcommand());
 | 
			
		||||
        MainCommand.subCommands.add(new DebugRoadRegen());
 | 
			
		||||
        MainCommand.subCommands.add(new Trim());
 | 
			
		||||
        MainCommand.subCommands.add(new DebugExec());
 | 
			
		||||
        MainCommand.subCommands.add(new FlagCmd());
 | 
			
		||||
        MainCommand.subCommands.add(new Target());
 | 
			
		||||
        MainCommand.subCommands.add(new DebugFixFlags());
 | 
			
		||||
        MainCommand.subCommands.add(new Move());
 | 
			
		||||
        MainCommand.subCommands.add(new Condense());
 | 
			
		||||
        MainCommand.subCommands.add(new Confirm());
 | 
			
		||||
        MainCommand.subCommands.add(new Copy());
 | 
			
		||||
        MainCommand.subCommands.add(new Chat());
 | 
			
		||||
        final BukkitCommand bcmd = new BukkitCommand();
 | 
			
		||||
        final PluginCommand plotCommand = getCommand("plots");
 | 
			
		||||
        plotCommand.setExecutor(bcmd);
 | 
			
		||||
        plotCommand.setAliases(Arrays.asList("p", "ps", "plotme", "plot"));
 | 
			
		||||
        plotCommand.setTabCompleter(bcmd);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public File getDirectory() {
 | 
			
		||||
        return getDataFolder();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public TaskManager getTaskManager() {
 | 
			
		||||
        return new BukkitTaskManager();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private ArrayDeque<Entity> fastTickEntities;
 | 
			
		||||
    private ArrayDeque<Entity> slowTickEntities;
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void runEntityTask() {
 | 
			
		||||
//        fastTickEntities = new ArrayDeque<>();
 | 
			
		||||
//        slowTickEntities = new ArrayDeque<>();
 | 
			
		||||
        log(C.PREFIX.s() + "KillAllEntities started.");
 | 
			
		||||
        TaskManager.runTaskRepeat(new Runnable() {
 | 
			
		||||
            long ticked = 0l;
 | 
			
		||||
            long error = 0l;
 | 
			
		||||
            
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                if (this.ticked > 36_000L) {
 | 
			
		||||
                    this.ticked = 0l;
 | 
			
		||||
                    if (this.error > 0) {
 | 
			
		||||
                        log(C.PREFIX.s() + "KillAllEntities has been running for 6 hours. Errors: " + this.error);
 | 
			
		||||
                    }
 | 
			
		||||
                    this.error = 0l;
 | 
			
		||||
                }
 | 
			
		||||
                World world;
 | 
			
		||||
                for (final PlotWorld pw : PS.get().getPlotWorldObjects()) {
 | 
			
		||||
                    PlotManager manager = PS.get().getPlotManager(pw.worldname);
 | 
			
		||||
                    world = Bukkit.getWorld(pw.worldname);
 | 
			
		||||
                    try {
 | 
			
		||||
                    for (Entity entity : world.getEntities()) {
 | 
			
		||||
                        switch (entity.getType()) {
 | 
			
		||||
                            case EGG:
 | 
			
		||||
                            case ENDER_CRYSTAL:
 | 
			
		||||
                            case COMPLEX_PART:
 | 
			
		||||
                            case ARMOR_STAND:
 | 
			
		||||
                            case FISHING_HOOK:
 | 
			
		||||
                            case ENDER_SIGNAL:
 | 
			
		||||
                            case EXPERIENCE_ORB:
 | 
			
		||||
                            case LEASH_HITCH:
 | 
			
		||||
                            case FIREWORK:
 | 
			
		||||
                            case WEATHER:
 | 
			
		||||
                            case LIGHTNING:
 | 
			
		||||
                            case WITHER_SKULL:
 | 
			
		||||
                            case UNKNOWN:
 | 
			
		||||
                            case ITEM_FRAME:
 | 
			
		||||
                            case PAINTING:
 | 
			
		||||
                            case PLAYER: {
 | 
			
		||||
                                // non moving / unremovable
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
                            case THROWN_EXP_BOTTLE:
 | 
			
		||||
                            case SPLASH_POTION:
 | 
			
		||||
                            case SNOWBALL:
 | 
			
		||||
                            case ENDER_PEARL:
 | 
			
		||||
                            case ARROW: {
 | 
			
		||||
                                // managed elsewhere | projectile
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
                            case MINECART:
 | 
			
		||||
                            case MINECART_CHEST:
 | 
			
		||||
                            case MINECART_COMMAND:
 | 
			
		||||
                            case MINECART_FURNACE:
 | 
			
		||||
                            case MINECART_HOPPER:
 | 
			
		||||
                            case MINECART_MOB_SPAWNER:
 | 
			
		||||
                            case MINECART_TNT:
 | 
			
		||||
                            case BOAT: {
 | 
			
		||||
                                // vehicle
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
                            case SMALL_FIREBALL:
 | 
			
		||||
                            case FIREBALL:
 | 
			
		||||
                            case DROPPED_ITEM: {
 | 
			
		||||
                                // dropped item
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
                            case PRIMED_TNT:
 | 
			
		||||
                            case FALLING_BLOCK:  {
 | 
			
		||||
                                // managed elsewhere
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
                            case BAT:
 | 
			
		||||
                            case BLAZE:
 | 
			
		||||
                            case CAVE_SPIDER:
 | 
			
		||||
                            case CHICKEN:
 | 
			
		||||
                            case COW:
 | 
			
		||||
                            case CREEPER:
 | 
			
		||||
                            case ENDERMAN:
 | 
			
		||||
                            case ENDERMITE:
 | 
			
		||||
                            case ENDER_DRAGON:
 | 
			
		||||
                            case GHAST:
 | 
			
		||||
                            case GIANT:
 | 
			
		||||
                            case GUARDIAN:
 | 
			
		||||
                            case HORSE:
 | 
			
		||||
                            case IRON_GOLEM:
 | 
			
		||||
                            case MAGMA_CUBE:
 | 
			
		||||
                            case MUSHROOM_COW:
 | 
			
		||||
                            case OCELOT:
 | 
			
		||||
                            case PIG:
 | 
			
		||||
                            case PIG_ZOMBIE:
 | 
			
		||||
                            case RABBIT:
 | 
			
		||||
                            case SHEEP:
 | 
			
		||||
                            case SILVERFISH:
 | 
			
		||||
                            case SKELETON:
 | 
			
		||||
                            case SLIME:
 | 
			
		||||
                            case SNOWMAN:
 | 
			
		||||
                            case SPIDER:
 | 
			
		||||
                            case SQUID:
 | 
			
		||||
                            case VILLAGER:
 | 
			
		||||
                            case WITCH:
 | 
			
		||||
                            case WITHER:
 | 
			
		||||
                            case WOLF:
 | 
			
		||||
                            case ZOMBIE:
 | 
			
		||||
                            default: {
 | 
			
		||||
                                Location loc = entity.getLocation();
 | 
			
		||||
                                if (manager.getPlotIdAbs(pw, loc.getBlockX(), 0, loc.getBlockZ()) == null) {
 | 
			
		||||
                                    entity.remove();
 | 
			
		||||
                                }
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    } catch (final Throwable e) {
 | 
			
		||||
                        ++this.error;
 | 
			
		||||
                    } finally {
 | 
			
		||||
                        ++this.ticked;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }, 20);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public boolean unloadPlugin(Plugin plugin) {
 | 
			
		||||
        try {
 | 
			
		||||
            plugin.getClass().getClassLoader().getResources("*");
 | 
			
		||||
        } catch (IOException e1) {
 | 
			
		||||
            e1.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        PluginManager pm = Bukkit.getServer().getPluginManager();
 | 
			
		||||
        Map<String, Plugin> ln;
 | 
			
		||||
        List<Plugin> pl;
 | 
			
		||||
        try {
 | 
			
		||||
            Field lnF = pm.getClass().getDeclaredField("lookupNames");
 | 
			
		||||
            lnF.setAccessible(true);
 | 
			
		||||
            ln = (Map) lnF.get(pm);
 | 
			
		||||
            
 | 
			
		||||
            Field plF = pm.getClass().getDeclaredField("plugins");
 | 
			
		||||
            plF.setAccessible(true);
 | 
			
		||||
            pl = (List) plF.get(pm);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        pm.disablePlugin(plugin);
 | 
			
		||||
        synchronized (pm) {
 | 
			
		||||
            ln.remove(plugin.getName());
 | 
			
		||||
            pl.remove(plugin);
 | 
			
		||||
        }
 | 
			
		||||
        JavaPluginLoader jpl = (JavaPluginLoader) plugin.getPluginLoader();
 | 
			
		||||
        Field loadersF = null;
 | 
			
		||||
        try {
 | 
			
		||||
            loadersF = jpl.getClass().getDeclaredField("loaders");
 | 
			
		||||
            loadersF.setAccessible(true);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            Map<String, ?> loaderMap = (Map) loadersF.get(jpl);
 | 
			
		||||
            loaderMap.remove(plugin.getDescription().getName());
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        closeClassLoader(plugin);
 | 
			
		||||
        System.gc();
 | 
			
		||||
        System.gc();
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public boolean closeClassLoader(Plugin plugin) {
 | 
			
		||||
        try {
 | 
			
		||||
            ((URLClassLoader) plugin.getClass().getClassLoader()).close();
 | 
			
		||||
            return true;
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public boolean unloadRecursively(Plugin plugin) {
 | 
			
		||||
        try {
 | 
			
		||||
            Stack<String> pluginFiles = unloadRecursively(plugin.getName(), plugin, new Stack());
 | 
			
		||||
            File file = new File(this.getDirectory() + File.separator + "disabled.yml");
 | 
			
		||||
            file.createNewFile();
 | 
			
		||||
            String prefix = "";
 | 
			
		||||
            String all = "";
 | 
			
		||||
            while (pluginFiles.size() > 0) {
 | 
			
		||||
                String pop = pluginFiles.pop();
 | 
			
		||||
                all += prefix + pop.substring(0, pop.length() - 4);
 | 
			
		||||
                prefix = ",";
 | 
			
		||||
            }
 | 
			
		||||
            if (all.length() != 0) {
 | 
			
		||||
                PrintWriter out = new PrintWriter(this.getDirectory() + File.separator + "disabled.yml");
 | 
			
		||||
                out.write(all);
 | 
			
		||||
                out.close();
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void loadPlugin(String name) {
 | 
			
		||||
        try {
 | 
			
		||||
            PluginManager manager = Bukkit.getServer().getPluginManager();
 | 
			
		||||
            Plugin plugin = manager.getPlugin(name);
 | 
			
		||||
            if (plugin != null) {
 | 
			
		||||
                manager.enablePlugin(plugin);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            plugin = manager.loadPlugin(new File("plugins" + File.separator + name + (name.endsWith(".jar") ? "" : ".jar")));
 | 
			
		||||
            plugin.onLoad();
 | 
			
		||||
            manager.enablePlugin(plugin);
 | 
			
		||||
        } catch (Exception e) {}
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public File getFile() {
 | 
			
		||||
        return getFile(this);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public File getFile(JavaPlugin p) {
 | 
			
		||||
        try {
 | 
			
		||||
            Field f = JavaPlugin.class.getDeclaredField("file");
 | 
			
		||||
            f.setAccessible(true);
 | 
			
		||||
            return (File) f.get(p);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public Stack<String> unloadRecursively(String doNotLoad, Plugin plugin, Stack<String> pluginFiles) {
 | 
			
		||||
        if (!plugin.getName().equals(doNotLoad)) {
 | 
			
		||||
            File file = getFile((JavaPlugin) plugin);
 | 
			
		||||
            pluginFiles.push(file.getName());
 | 
			
		||||
        }
 | 
			
		||||
        PluginManager pm = Bukkit.getPluginManager();
 | 
			
		||||
        for (Plugin p : pm.getPlugins()) {
 | 
			
		||||
            List<String> depend = p.getDescription().getDepend();
 | 
			
		||||
            if (depend != null) {
 | 
			
		||||
                for (String s : depend) {
 | 
			
		||||
                    if (s.equals(plugin.getName())) {
 | 
			
		||||
                        unloadRecursively(doNotLoad, p, pluginFiles);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            List<String> softDepend = p.getDescription().getSoftDepend();
 | 
			
		||||
            if (softDepend != null) {
 | 
			
		||||
                for (String s : softDepend) {
 | 
			
		||||
                    if (s.equals(plugin.getName())) {
 | 
			
		||||
                        unloadRecursively(doNotLoad, p, pluginFiles);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (unloadPlugin(plugin)) {
 | 
			
		||||
            List<String> depend = plugin.getDescription().getDepend();
 | 
			
		||||
            if (depend != null) {
 | 
			
		||||
                for (String s : depend) {
 | 
			
		||||
                    Plugin p = pm.getPlugin(s);
 | 
			
		||||
                    if (p != null) {
 | 
			
		||||
                        unloadRecursively(doNotLoad, p, pluginFiles);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            List<String> softDepend = plugin.getDescription().getSoftDepend();
 | 
			
		||||
            if (softDepend != null) {
 | 
			
		||||
                for (String s : softDepend) {
 | 
			
		||||
                    Plugin p = pm.getPlugin(s);
 | 
			
		||||
                    if (p != null) {
 | 
			
		||||
                        unloadRecursively(doNotLoad, p, pluginFiles);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return pluginFiles;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    final public ChunkGenerator getDefaultWorldGenerator(final String world, final String id) {
 | 
			
		||||
        WorldEvents.lastWorld = world;
 | 
			
		||||
        if (!PS.get().setupPlotWorld(world, id)) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        HybridGen result = new HybridGen(world);
 | 
			
		||||
        TaskManager.runTaskLater(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                if (WorldEvents.lastWorld != null && WorldEvents.lastWorld.equals(world)) {
 | 
			
		||||
                    WorldEvents.lastWorld = null;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }, 20);
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void registerPlayerEvents() {
 | 
			
		||||
        getServer().getPluginManager().registerEvents(new PlayerEvents(), this);
 | 
			
		||||
        if (checkVersion(1, 8, 0)) {
 | 
			
		||||
            getServer().getPluginManager().registerEvents(new PlayerEvents_1_8(), this);
 | 
			
		||||
        }
 | 
			
		||||
        if (checkVersion(1, 8, 3)) {
 | 
			
		||||
            getServer().getPluginManager().registerEvents(new PlayerEvents_1_8_3(), this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void registerInventoryEvents() {
 | 
			
		||||
        getServer().getPluginManager().registerEvents(new InventoryListener(), this);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void registerPlotPlusEvents() {
 | 
			
		||||
        PlotPlusListener.startRunnable(this);
 | 
			
		||||
        getServer().getPluginManager().registerEvents(new PlotPlusListener(), this);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void registerForceFieldEvents() {
 | 
			
		||||
        getServer().getPluginManager().registerEvents(new ForceFieldListener(), this);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void registerWorldEditEvents() {
 | 
			
		||||
        if (getServer().getPluginManager().getPlugin("WorldEdit") != null) {
 | 
			
		||||
            PS.get().worldEdit = (WorldEditPlugin) getServer().getPluginManager().getPlugin("WorldEdit");
 | 
			
		||||
            final String version = PS.get().worldEdit.getDescription().getVersion();
 | 
			
		||||
            if ((version != null) && version.startsWith("5.")) {
 | 
			
		||||
                log("&cThis version of WorldEdit does not support PlotSquared.");
 | 
			
		||||
                log("&cPlease use WorldEdit 6+ for masking support");
 | 
			
		||||
                log("&c - http://builds.enginehub.org/job/worldedit");
 | 
			
		||||
            } else {
 | 
			
		||||
                getServer().getPluginManager().registerEvents(new WEListener(), this);
 | 
			
		||||
                WorldEdit.getInstance().getEventBus().register(new WESubscriber());
 | 
			
		||||
                MainCommand.subCommands.add(new WE_Anywhere());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public EconHandler getEconomyHandler() {
 | 
			
		||||
        try {
 | 
			
		||||
            BukkitEconHandler econ = new BukkitEconHandler();
 | 
			
		||||
            if (econ.init()) {
 | 
			
		||||
                return econ;
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Throwable e) {
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public BlockManager initBlockManager() {
 | 
			
		||||
        if (checkVersion(1, 8, 0)) {
 | 
			
		||||
            try {
 | 
			
		||||
                BukkitSetBlockManager.setBlockManager = new SetBlockFast_1_8();
 | 
			
		||||
            } catch (final Throwable e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
                BukkitSetBlockManager.setBlockManager = new SetBlockSlow();
 | 
			
		||||
            }
 | 
			
		||||
            try {
 | 
			
		||||
                new SendChunk();
 | 
			
		||||
                MainUtil.canSendChunk = true;
 | 
			
		||||
            } catch (final Throwable e) {
 | 
			
		||||
                MainUtil.canSendChunk = false;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            try {
 | 
			
		||||
                BukkitSetBlockManager.setBlockManager = new SetBlockFast();
 | 
			
		||||
            } catch (final Throwable e) {
 | 
			
		||||
                MainUtil.canSetFast = false;
 | 
			
		||||
                BukkitSetBlockManager.setBlockManager = new SetBlockSlow();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        BlockUpdateUtil.setBlockManager = BukkitSetBlockManager.setBlockManager;
 | 
			
		||||
        return BlockManager.manager = new BukkitUtil();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean initPlotMeConverter() {
 | 
			
		||||
        TaskManager.runTaskLaterAsync(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                if (new LikePlotMeConverter("PlotMe").run(new ClassicPlotMeConnector())) return;
 | 
			
		||||
                if (new LikePlotMeConverter("PlotMe").run(new PlotMeConnector_017())) return;
 | 
			
		||||
                if (new LikePlotMeConverter("AthionPlots").run(new ClassicPlotMeConnector())) return;
 | 
			
		||||
            }
 | 
			
		||||
        }, 20);
 | 
			
		||||
        return Bukkit.getPluginManager().getPlugin("PlotMe") != null || Bukkit.getPluginManager().getPlugin("AthionPlots") != null;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public ChunkGenerator getGenerator(final String world, final String name) {
 | 
			
		||||
        final Plugin gen_plugin = Bukkit.getPluginManager().getPlugin(name);
 | 
			
		||||
        if ((gen_plugin != null) && gen_plugin.isEnabled()) {
 | 
			
		||||
            return gen_plugin.getDefaultWorldGenerator(world, "");
 | 
			
		||||
        } else {
 | 
			
		||||
            return new HybridGen(world);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public HybridUtils initHybridUtils() {
 | 
			
		||||
        return new BukkitHybridUtils();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public SetupUtils initSetupUtils() {
 | 
			
		||||
        return new BukkitSetupUtils();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public UUIDWrapper initUUIDHandler() {
 | 
			
		||||
        final boolean checkVersion = checkVersion(1, 7, 6);
 | 
			
		||||
        if (Settings.OFFLINE_MODE) {
 | 
			
		||||
            if (Settings.UUID_LOWERCASE) {
 | 
			
		||||
                UUIDHandler.uuidWrapper = new LowerOfflineUUIDWrapper();
 | 
			
		||||
            } else {
 | 
			
		||||
                UUIDHandler.uuidWrapper = new OfflineUUIDWrapper();
 | 
			
		||||
            }
 | 
			
		||||
            Settings.OFFLINE_MODE = true;
 | 
			
		||||
        } else if (checkVersion) {
 | 
			
		||||
            UUIDHandler.uuidWrapper = new DefaultUUIDWrapper();
 | 
			
		||||
            Settings.OFFLINE_MODE = false;
 | 
			
		||||
        } else {
 | 
			
		||||
            if (Settings.UUID_LOWERCASE) {
 | 
			
		||||
                UUIDHandler.uuidWrapper = new LowerOfflineUUIDWrapper();
 | 
			
		||||
            } else {
 | 
			
		||||
                UUIDHandler.uuidWrapper = new OfflineUUIDWrapper();
 | 
			
		||||
            }
 | 
			
		||||
            Settings.OFFLINE_MODE = true;
 | 
			
		||||
        }
 | 
			
		||||
        if (!checkVersion) {
 | 
			
		||||
            log(C.PREFIX.s() + " &c[WARN] Titles are disabled - please update your version of Bukkit to support this feature.");
 | 
			
		||||
            Settings.TITLES = false;
 | 
			
		||||
            FlagManager.removeFlag(FlagManager.getFlag("titles"));
 | 
			
		||||
        } else {
 | 
			
		||||
            AbstractTitle.TITLE_CLASS = new DefaultTitle();
 | 
			
		||||
            if (UUIDHandler.uuidWrapper instanceof DefaultUUIDWrapper) {
 | 
			
		||||
                Settings.TWIN_MODE_UUID = true;
 | 
			
		||||
            } else if (UUIDHandler.uuidWrapper instanceof OfflineUUIDWrapper && !Bukkit.getOnlineMode()) {
 | 
			
		||||
                Settings.TWIN_MODE_UUID = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (Settings.OFFLINE_MODE) {
 | 
			
		||||
            log(C.PREFIX.s() + " &6PlotSquared is using Offline Mode UUIDs either because of user preference, or because you are using an old version of Bukkit");
 | 
			
		||||
        } else {
 | 
			
		||||
            log(C.PREFIX.s() + " &6PlotSquared is using online UUIDs");
 | 
			
		||||
        }
 | 
			
		||||
        return UUIDHandler.uuidWrapper;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public ChunkManager initChunkManager() {
 | 
			
		||||
        return new BukkitChunkManager();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public EventUtil initEventUtil() {
 | 
			
		||||
        return new BukkitEventUtil();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void registerTNTListener() {
 | 
			
		||||
        getServer().getPluginManager().registerEvents(new TNTListener(), this);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void unregister(PlotPlayer player) {
 | 
			
		||||
        BukkitUtil.removePlayer(player.getName());
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public APlotListener initPlotListener() {
 | 
			
		||||
        return new PlotListener();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void registerChunkProcessor() {
 | 
			
		||||
        getServer().getPluginManager().registerEvents(new ChunkListener(), this);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void registerWorldEvents() {
 | 
			
		||||
        getServer().getPluginManager().registerEvents(new WorldEvents(), this);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public PlayerManager initPlayerManager() {
 | 
			
		||||
        return new BukkitPlayerManager();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public InventoryUtil initInventoryUtil() {
 | 
			
		||||
        return new BukkitInventoryUtil();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								src/main/java/com/intellectualcrafters/plot/IPlotMain.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/main/java/com/intellectualcrafters/plot/IPlotMain.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
package com.intellectualcrafters.plot;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.generator.ChunkGenerator;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.APlotListener;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.BlockManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ChunkManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EconHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EventUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.InventoryUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.PlayerManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.SetupUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
 | 
			
		||||
 | 
			
		||||
public interface IPlotMain {
 | 
			
		||||
    public void log(String message);
 | 
			
		||||
 | 
			
		||||
    public File getDirectory();
 | 
			
		||||
    
 | 
			
		||||
    public File getFile();
 | 
			
		||||
 | 
			
		||||
    public void disable();
 | 
			
		||||
 | 
			
		||||
    public String getVersion();
 | 
			
		||||
 | 
			
		||||
    public void handleKick(UUID uuid, C c);
 | 
			
		||||
 | 
			
		||||
    public TaskManager getTaskManager();
 | 
			
		||||
 | 
			
		||||
    public void runEntityTask();
 | 
			
		||||
 | 
			
		||||
    public void registerCommands();
 | 
			
		||||
 | 
			
		||||
    public void registerPlayerEvents();
 | 
			
		||||
 | 
			
		||||
    public void registerInventoryEvents();
 | 
			
		||||
 | 
			
		||||
    public void registerPlotPlusEvents();
 | 
			
		||||
 | 
			
		||||
    public void registerForceFieldEvents();
 | 
			
		||||
 | 
			
		||||
    public void registerWorldEditEvents();
 | 
			
		||||
    
 | 
			
		||||
    public void registerTNTListener();
 | 
			
		||||
 | 
			
		||||
    public EconHandler getEconomyHandler();
 | 
			
		||||
 | 
			
		||||
    public BlockManager initBlockManager();
 | 
			
		||||
    
 | 
			
		||||
    public EventUtil initEventUtil();
 | 
			
		||||
 | 
			
		||||
    public ChunkManager initChunkManager();
 | 
			
		||||
 | 
			
		||||
    public SetupUtils initSetupUtils();
 | 
			
		||||
 | 
			
		||||
    public HybridUtils initHybridUtils();
 | 
			
		||||
 | 
			
		||||
    public UUIDWrapper initUUIDHandler();
 | 
			
		||||
    
 | 
			
		||||
    public InventoryUtil initInventoryUtil();
 | 
			
		||||
 | 
			
		||||
    public boolean initPlotMeConverter();
 | 
			
		||||
    
 | 
			
		||||
    public void unregister(PlotPlayer player);
 | 
			
		||||
 | 
			
		||||
    public ChunkGenerator getGenerator(String world, String name);
 | 
			
		||||
 | 
			
		||||
    public APlotListener initPlotListener();
 | 
			
		||||
 | 
			
		||||
    public void registerChunkProcessor();
 | 
			
		||||
 | 
			
		||||
    public void registerWorldEvents();
 | 
			
		||||
 | 
			
		||||
    public PlayerManager initPlayerManager();
 | 
			
		||||
 | 
			
		||||
    public boolean checkVersion(int major, int minor, int minor2);
 | 
			
		||||
    
 | 
			
		||||
    public void loadPlugin(String plugin);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1554
									
								
								src/main/java/com/intellectualcrafters/plot/PS.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1554
									
								
								src/main/java/com/intellectualcrafters/plot/PS.java
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										672
									
								
								src/main/java/com/intellectualcrafters/plot/api/PlotAPI.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										672
									
								
								src/main/java/com/intellectualcrafters/plot/api/PlotAPI.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,672 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
package com.intellectualcrafters.plot.api;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.World;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.plugin.java.JavaPlugin;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.configuration.file.YamlConfiguration;
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.commands.MainCommand;
 | 
			
		||||
import com.intellectualcrafters.plot.commands.SubCommand;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.AbstractFlag;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.FlagManager;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotManager;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.util.BlockManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ChunkManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ClusterManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.intellectualcrafters.plot.util.SchematicHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitSetBlockManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * PlotSquared API
 | 
			
		||||
 *
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 * @author Empire92
 | 
			
		||||
 * @version API 2.0
 | 
			
		||||
 *
 | 
			
		||||
 * @deprecated
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@SuppressWarnings("unused") public class PlotAPI {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Permission that allows for admin access, this permission node will allow the player to use any part of the
 | 
			
		||||
     * plugin, without limitations.
 | 
			
		||||
     */
 | 
			
		||||
    public static final String ADMIN_PERMISSION = "plots.admin";
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor. Insert any Plugin. (Optimally the plugin that is accessing the method)
 | 
			
		||||
     *
 | 
			
		||||
     * @param plugin Plugin used to access this method
 | 
			
		||||
     *
 | 
			
		||||
     * @throws com.intellectualcrafters.plot.util.PlotSquaredException if the program fails to fetch the PlotSquared
 | 
			
		||||
     *                                                                 instance
 | 
			
		||||
     * @see com.intellectualcrafters.plot.PS
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public PlotAPI(final JavaPlugin plugin) {
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public PlotAPI() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get all plots
 | 
			
		||||
     *
 | 
			
		||||
     * @return all plots
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.PS#getPlots()
 | 
			
		||||
     */
 | 
			
		||||
    public Set<Plot> getAllPlots() {
 | 
			
		||||
        return PS.get().getPlots();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Return all plots for a player
 | 
			
		||||
     *
 | 
			
		||||
     * @param player Player, whose plots to search for
 | 
			
		||||
     *
 | 
			
		||||
     * @return all plots that a player owns
 | 
			
		||||
     */
 | 
			
		||||
    public Set<Plot> getPlayerPlots(final Player player) {
 | 
			
		||||
        return PS.get().getPlots(BukkitUtil.getPlayer(player));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a plot world
 | 
			
		||||
     *
 | 
			
		||||
     * @param world     World Name
 | 
			
		||||
     * @param plotWorld Plot World Object
 | 
			
		||||
     * @param manager   World Manager
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.PS#addPlotWorld(String, com.intellectualcrafters.plot.object.PlotWorld,
 | 
			
		||||
     * com.intellectualcrafters.plot.object.PlotManager)
 | 
			
		||||
     */
 | 
			
		||||
    public void addPlotWorld(final String world, final PlotWorld plotWorld, final PlotManager manager) {
 | 
			
		||||
        PS.get().addPlotWorld(world, plotWorld, manager);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return main configuration
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.PS#config
 | 
			
		||||
     */
 | 
			
		||||
    public YamlConfiguration getConfig() {
 | 
			
		||||
        return PS.get().config;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return storage configuration
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.PS#storage
 | 
			
		||||
     */
 | 
			
		||||
    public YamlConfiguration getStorage() {
 | 
			
		||||
        return PS.get().storage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the main class for this plugin <br> - Contains a lot of fields and methods - not very well organized <br>
 | 
			
		||||
     * Only use this if you really need it
 | 
			
		||||
     *
 | 
			
		||||
     * @return PlotSquared PlotSquared Main Class
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.PS
 | 
			
		||||
     */
 | 
			
		||||
    public PS getMain() {
 | 
			
		||||
        return PS.get();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ChunkManager class contains several useful methods<br>
 | 
			
		||||
     *  - Chunk deletion<br>
 | 
			
		||||
     *  - Moving or copying regions<br>
 | 
			
		||||
     *  - plot swapping<br>
 | 
			
		||||
     *  - Entity tracking<br>
 | 
			
		||||
     *  - region regeneration<br>
 | 
			
		||||
     *
 | 
			
		||||
     * @return ChunkManager
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.ChunkManager
 | 
			
		||||
     */
 | 
			
		||||
    public ChunkManager getChunkManager() {
 | 
			
		||||
        return ChunkManager.manager;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * BlockManager class contains useful methods relating to blocks.
 | 
			
		||||
     *
 | 
			
		||||
     * @return BlockManager
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.BlockManager
 | 
			
		||||
     */
 | 
			
		||||
    public BlockManager getBlockManager() {
 | 
			
		||||
        return BlockManager.manager;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * BukkitSetBlockManager class contains useful methods relating to bukkit blocks.
 | 
			
		||||
     *
 | 
			
		||||
     * @return BukkitSetBlockManager
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.bukkit.BukkitSetBlockManager
 | 
			
		||||
     */
 | 
			
		||||
    public BukkitSetBlockManager getBukkitBlockManager() {
 | 
			
		||||
        return BukkitSetBlockManager.setBlockManager;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * UUIDWrapper class has basic methods for getting UUIDS (it's recommended to use the UUIDHandler class instead)
 | 
			
		||||
     *
 | 
			
		||||
     * @return UUIDWrapper
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.uuid.UUIDWrapper
 | 
			
		||||
     */
 | 
			
		||||
    public UUIDWrapper getUUIDWrapper() {
 | 
			
		||||
        return UUIDHandler.uuidWrapper;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Do not use this. Instead use FlagManager.[method] in your code.
 | 
			
		||||
     *  - Flag related stuff
 | 
			
		||||
     *
 | 
			
		||||
     * @return FlagManager
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.flag.FlagManager
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public FlagManager getFlagManager() {
 | 
			
		||||
        return new FlagManager();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Do not use this. Instead use ClusterManager.[method] in your code.
 | 
			
		||||
     *  - Plot cluster related stuff
 | 
			
		||||
     *
 | 
			
		||||
     * @return ClusterManager
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.ClusterManager
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public ClusterManager getClusterManager() {
 | 
			
		||||
        return new ClusterManager();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Do not use this. Instead use MainUtil.[method] in your code.
 | 
			
		||||
     *  - Basic plot management stuff
 | 
			
		||||
     *
 | 
			
		||||
     * @return MainUtil
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.MainUtil
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public MainUtil getMainUtil() {
 | 
			
		||||
        return new MainUtil();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Do not use this. Instead use Permissions.[method] in your code.
 | 
			
		||||
     *  - Basic permission management stuff
 | 
			
		||||
     *
 | 
			
		||||
     * @return MainUtil
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.Permissions
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public Permissions[] getPermissions() {
 | 
			
		||||
        return Permissions.values();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * SchematicHandler class contains methods related to pasting, reading and writing schematics
 | 
			
		||||
     *
 | 
			
		||||
     * @return SchematicHandler
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.SchematicHandler
 | 
			
		||||
     */
 | 
			
		||||
    public SchematicHandler getSchematicHandler() {
 | 
			
		||||
        return SchematicHandler.manager;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Use C.[caption] instead
 | 
			
		||||
     *
 | 
			
		||||
     * @return C
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.config.C
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public C[] getCaptions() {
 | 
			
		||||
        return C.values();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the plot manager for a world. - Most of these methods can be accessed through the MainUtil
 | 
			
		||||
     *
 | 
			
		||||
     * @param world Which manager to get
 | 
			
		||||
     *
 | 
			
		||||
     * @return PlotManager
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.object.PlotManager
 | 
			
		||||
     * @see PS#getPlotManager(String)
 | 
			
		||||
     */
 | 
			
		||||
    public PlotManager getPlotManager(final World world) {
 | 
			
		||||
        return PS.get().getPlotManager(world.getName());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the plot manager for a world. - Contains useful low level methods for plot merging, clearing, and
 | 
			
		||||
     * tessellation
 | 
			
		||||
     *
 | 
			
		||||
     * @param world
 | 
			
		||||
     *
 | 
			
		||||
     * @return PlotManager
 | 
			
		||||
     *
 | 
			
		||||
     * @see PS#getPlotManager(String)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.object.PlotManager
 | 
			
		||||
     */
 | 
			
		||||
    public PlotManager getPlotManager(final String world) {
 | 
			
		||||
        return PS.get().getPlotManager(world);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the settings for a world (settings bundled in PlotWorld class) - You will need to downcast for the specific
 | 
			
		||||
     * settings a Generator has. e.g. DefaultPlotWorld class implements PlotWorld
 | 
			
		||||
     *
 | 
			
		||||
     * @param world (to get settings of)
 | 
			
		||||
     *
 | 
			
		||||
     * @return PlotWorld class for that world ! will return null if not a plot world world
 | 
			
		||||
     *
 | 
			
		||||
     * @see PS#getPlotWorld(String)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.object.PlotWorld
 | 
			
		||||
     */
 | 
			
		||||
    public PlotWorld getWorldSettings(final World world) {
 | 
			
		||||
        return PS.get().getPlotWorld(world.getName());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the settings for a world (settings bundled in PlotWorld class)
 | 
			
		||||
     *
 | 
			
		||||
     * @param world (to get settings of)
 | 
			
		||||
     *
 | 
			
		||||
     * @return PlotWorld class for that world ! will return null if not a plot world world
 | 
			
		||||
     *
 | 
			
		||||
     * @see PS#getPlotWorld(String)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.object.PlotWorld
 | 
			
		||||
     */
 | 
			
		||||
    public PlotWorld getWorldSettings(final String world) {
 | 
			
		||||
        return PS.get().getPlotWorld(world);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Send a message to a player.
 | 
			
		||||
     *
 | 
			
		||||
     * @param player Player that will receive the message
 | 
			
		||||
     * @param c      (Caption)
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.MainUtil#sendMessage(PlotPlayer, C, String...)
 | 
			
		||||
     * com.intellectualcrafters.plot.config.C, String...)
 | 
			
		||||
     */
 | 
			
		||||
    public void sendMessage(final Player player, final C c) {
 | 
			
		||||
        MainUtil.sendMessage(BukkitUtil.getPlayer(player), c);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Send a message to a player. - Supports color codes
 | 
			
		||||
     *
 | 
			
		||||
     * @param player Player that will receive the message
 | 
			
		||||
     * @param string The message
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.MainUtil#sendMessage(PlotPlayer, String)
 | 
			
		||||
     */
 | 
			
		||||
    public void sendMessage(final Player player, final String string) {
 | 
			
		||||
        MainUtil.sendMessage(BukkitUtil.getPlayer(player), string);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Send a message to the console. - Supports color codes
 | 
			
		||||
     *
 | 
			
		||||
     * @param msg Message that should be sent to the console
 | 
			
		||||
     *
 | 
			
		||||
     * @see MainUtil#sendConsoleMessage(String)
 | 
			
		||||
     */
 | 
			
		||||
    public void sendConsoleMessage(final String msg) {
 | 
			
		||||
        MainUtil.sendConsoleMessage(msg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Send a message to the console
 | 
			
		||||
     *
 | 
			
		||||
     * @param c (Caption)
 | 
			
		||||
     *
 | 
			
		||||
     * @see #sendConsoleMessage(String)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.config.C
 | 
			
		||||
     */
 | 
			
		||||
    public void sendConsoleMessage(final C c) {
 | 
			
		||||
        sendConsoleMessage(c.s());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Register a flag for use in plots
 | 
			
		||||
     *
 | 
			
		||||
     * @param flag Flag that should be registered
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.flag.FlagManager#addFlag(com.intellectualcrafters.plot.flag.AbstractFlag)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.flag.AbstractFlag
 | 
			
		||||
     */
 | 
			
		||||
    public void addFlag(final AbstractFlag flag) {
 | 
			
		||||
        FlagManager.addFlag(flag);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * get all the currently registered flags
 | 
			
		||||
     *
 | 
			
		||||
     * @return array of Flag[]
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.flag.FlagManager#getFlags()
 | 
			
		||||
     * @see com.intellectualcrafters.plot.flag.AbstractFlag
 | 
			
		||||
     */
 | 
			
		||||
    public AbstractFlag[] getFlags() {
 | 
			
		||||
        return FlagManager.getFlags().toArray(new AbstractFlag[FlagManager.getFlags().size()]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a plot based on the ID
 | 
			
		||||
     *
 | 
			
		||||
     * @param world World in which the plot is located
 | 
			
		||||
     * @param x     Plot Location X Co-ord
 | 
			
		||||
     * @param z     Plot Location Z Co-ord
 | 
			
		||||
     *
 | 
			
		||||
     * @return plot, null if ID is wrong
 | 
			
		||||
     *
 | 
			
		||||
     * @see MainUtil#getPlot(String, com.intellectualcrafters.plot.object.PlotId)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.object.Plot
 | 
			
		||||
     */
 | 
			
		||||
    public Plot getPlot(final World world, final int x, final int z) {
 | 
			
		||||
        return MainUtil.getPlot(world.getName(), new PlotId(x, z));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a plot based on the location
 | 
			
		||||
     *
 | 
			
		||||
     * @param l The location that you want to to retrieve the plot from
 | 
			
		||||
     *
 | 
			
		||||
     * @return plot if found, otherwise it creates a temporary plot-
 | 
			
		||||
     *
 | 
			
		||||
     * @see MainUtil#getPlot(com.intellectualcrafters.plot.object.Location)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.object.Plot
 | 
			
		||||
     */
 | 
			
		||||
    public Plot getPlot(final Location l) {
 | 
			
		||||
        return MainUtil.getPlot(BukkitUtil.getLocation(l));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a plot based on the player location
 | 
			
		||||
     *
 | 
			
		||||
     * @param player Get the current plot for the player location
 | 
			
		||||
     *
 | 
			
		||||
     * @return plot if found, otherwise it creates a temporary plot
 | 
			
		||||
     *
 | 
			
		||||
     * @see #getPlot(org.bukkit.Location)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.object.Plot
 | 
			
		||||
     */
 | 
			
		||||
    public Plot getPlot(final Player player) {
 | 
			
		||||
        return this.getPlot(player.getLocation());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check whether or not a player has a plot
 | 
			
		||||
     *
 | 
			
		||||
     * @param player Player that you want to check for
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if player has a plot, false if not.
 | 
			
		||||
     *
 | 
			
		||||
     * @see #getPlots(World, Player, boolean)
 | 
			
		||||
     */
 | 
			
		||||
    public boolean hasPlot(final World world, final Player player) {
 | 
			
		||||
        return (getPlots(world, player, true) != null) && (getPlots(world, player, true).length > 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get all plots for the player
 | 
			
		||||
     *
 | 
			
		||||
     * @param plr        to search for
 | 
			
		||||
     * @param just_owner should we just search for owner? Or with rights?
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.object.Plot
 | 
			
		||||
     */
 | 
			
		||||
    public Plot[] getPlots(final World world, final Player plr, final boolean just_owner) {
 | 
			
		||||
        final ArrayList<Plot> pPlots = new ArrayList<>();
 | 
			
		||||
        for (final Plot plot : PS.get().getPlots(world.getName()).values()) {
 | 
			
		||||
            if (just_owner) {
 | 
			
		||||
                if ((plot.owner != null) && (plot.owner.equals(UUIDHandler.getUUID(BukkitUtil.getPlayer(plr))))) {
 | 
			
		||||
                    pPlots.add(plot);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                if (plot.isAdded(UUIDHandler.getUUID(BukkitUtil.getPlayer(plr)))) {
 | 
			
		||||
                    pPlots.add(plot);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return pPlots.toArray(new Plot[pPlots.size()]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get all plots for the world
 | 
			
		||||
     *
 | 
			
		||||
     * @param world to get plots of
 | 
			
		||||
     *
 | 
			
		||||
     * @return Plot[] - array of plot objects in world
 | 
			
		||||
     *
 | 
			
		||||
     * @see PS#getPlots(String)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.object.Plot
 | 
			
		||||
     */
 | 
			
		||||
    public Plot[] getPlots(final World world) {
 | 
			
		||||
        Collection<Plot> plots = PS.get().getPlots(world.getName()).values();
 | 
			
		||||
        return plots.toArray(new Plot[plots.size()]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get all plot worlds
 | 
			
		||||
     *
 | 
			
		||||
     * @return World[] - array of plot worlds
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.PS#getPlotWorlds()
 | 
			
		||||
     */
 | 
			
		||||
    public String[] getPlotWorlds() {
 | 
			
		||||
        Set<String> worlds = PS.get().getPlotWorlds();
 | 
			
		||||
        return worlds.toArray(new String[worlds.size()]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get if plot world
 | 
			
		||||
     *
 | 
			
		||||
     * @param world (to check if plot world)
 | 
			
		||||
     *
 | 
			
		||||
     * @return boolean (if plot world or not)
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.PS#isPlotWorld(String)
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isPlotWorld(final World world) {
 | 
			
		||||
        return PS.get().isPlotWorld(world.getName());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get plot locations
 | 
			
		||||
     *
 | 
			
		||||
     * @param p Plot that you want to get the locations for
 | 
			
		||||
     *
 | 
			
		||||
     * @return [0] = bottomLc, [1] = topLoc, [2] = home
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.MainUtil#getPlotBottomLoc(String,
 | 
			
		||||
     * com.intellectualcrafters.plot.object.PlotId)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.MainUtil#getPlotTopLoc(String,
 | 
			
		||||
     * com.intellectualcrafters.plot.object.PlotId)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.MainUtil#getPlotHome(String,
 | 
			
		||||
     * com.intellectualcrafters.plot.object.Plot)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.object.Plot
 | 
			
		||||
     */
 | 
			
		||||
    public Location[] getLocations(final Plot p) {
 | 
			
		||||
        return new Location[]{BukkitUtil.getLocation(MainUtil.getPlotBottomLoc(p.world, p.id)), BukkitUtil.getLocation(MainUtil.getPlotTopLoc(p.world, p.id)), BukkitUtil.getLocation(MainUtil.getPlotHome(p.world, p.id))};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get home location
 | 
			
		||||
     *
 | 
			
		||||
     * @param p Plot that you want to get the location for
 | 
			
		||||
     *
 | 
			
		||||
     * @return plot bottom location
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.MainUtil#getPlotHome(String,
 | 
			
		||||
     * com.intellectualcrafters.plot.object.Plot)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.object.Plot
 | 
			
		||||
     */
 | 
			
		||||
    public Location getHomeLocation(final Plot p) {
 | 
			
		||||
        return BukkitUtil.getLocation(MainUtil.getPlotHome(p.world, p.id));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get Bottom Location (min, min, min)
 | 
			
		||||
     *
 | 
			
		||||
     * @param p Plot that you want to get the location for
 | 
			
		||||
     *
 | 
			
		||||
     * @return plot bottom location
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.MainUtil#getPlotBottomLoc(String,
 | 
			
		||||
     * com.intellectualcrafters.plot.object.PlotId)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.object.Plot
 | 
			
		||||
     */
 | 
			
		||||
    public Location getBottomLocation(final Plot p) {
 | 
			
		||||
        return BukkitUtil.getLocation(MainUtil.getPlotBottomLoc(p.world, p.id));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get Top Location (max, max, max)
 | 
			
		||||
     *
 | 
			
		||||
     * @param p Plot that you want to get the location for
 | 
			
		||||
     *
 | 
			
		||||
     * @return plot top location
 | 
			
		||||
     *
 | 
			
		||||
     * @see MainUtil#getPlotTopLoc(String, com.intellectualcrafters.plot.object.PlotId)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.object.Plot
 | 
			
		||||
     */
 | 
			
		||||
    public Location getTopLocation(final Plot p) {
 | 
			
		||||
        return BukkitUtil.getLocation(MainUtil.getPlotTopLoc(p.world, p.id));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check whether or not a player is in a plot
 | 
			
		||||
     *
 | 
			
		||||
     * @param player who we're checking for
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if the player is in a plot, false if not-
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.MainUtil#getPlot(com.intellectualcrafters.plot.object.Location)
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isInPlot(final Player player) {
 | 
			
		||||
        return MainUtil.getPlot(BukkitUtil.getLocation(player)) != null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Register a subcommand
 | 
			
		||||
     *
 | 
			
		||||
     * @param c SubCommand, that we want to register
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.commands.MainCommand#subCommands
 | 
			
		||||
     * @see com.intellectualcrafters.plot.commands.SubCommand
 | 
			
		||||
     */
 | 
			
		||||
    public void registerCommand(final SubCommand c) {
 | 
			
		||||
        MainCommand.subCommands.add(c);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the PlotSquared class
 | 
			
		||||
     *
 | 
			
		||||
     * @return PlotSquared Class
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.PS
 | 
			
		||||
     */
 | 
			
		||||
    public PS getPlotSquared() {
 | 
			
		||||
        return PS.get();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the player plot count
 | 
			
		||||
     *
 | 
			
		||||
     * @param world  Specify the world we want to select the plots from
 | 
			
		||||
     * @param player Player, for whom we're getting the plot count
 | 
			
		||||
     *
 | 
			
		||||
     * @return the number of plots the player has
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.util.MainUtil#getPlayerPlotCount(String, PlotPlayer)
 | 
			
		||||
     */
 | 
			
		||||
    public int getPlayerPlotCount(final World world, final Player player) {
 | 
			
		||||
        return MainUtil.getPlayerPlotCount(world.getName(), BukkitUtil.getPlayer(player));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a collection containing the players plots
 | 
			
		||||
     *
 | 
			
		||||
     * @param world  Specify the world we want to select the plots from
 | 
			
		||||
     * @param player Player, for whom we're getting the plots
 | 
			
		||||
     *
 | 
			
		||||
     * @return a set containing the players plots
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.PS#getPlots(String, PlotPlayer)
 | 
			
		||||
     * org.bukkit.entity.Player)
 | 
			
		||||
     * @see com.intellectualcrafters.plot.object.Plot
 | 
			
		||||
     */
 | 
			
		||||
    public Set<Plot> getPlayerPlots(final World world, final Player player) {
 | 
			
		||||
        return PS.get().getPlots(world.getName(), BukkitUtil.getPlayer(player));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the numbers of plots, which the player is able to build in
 | 
			
		||||
     *
 | 
			
		||||
     * @param player Player, for whom we're getting the plots (trusted, member and owner)
 | 
			
		||||
     *
 | 
			
		||||
     * @return the number of allowed plots
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    public int getAllowedPlots(final Player player) {
 | 
			
		||||
        PlotPlayer pp = BukkitUtil.getPlayer(player);
 | 
			
		||||
        return MainUtil.getAllowedPlots(pp);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,96 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EventUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
 | 
			
		||||
public class Add extends SubCommand {
 | 
			
		||||
    public Add() {
 | 
			
		||||
        super(Command.ADD, "Allow a user to build while you are online", "add <player>", CommandCategory.ACTIONS, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if (args.length != 1) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot add <player>");
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        final Location loc = plr.getLocation();
 | 
			
		||||
        final Plot plot = MainUtil.getPlot(loc);
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            return !sendMessage(plr, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        if ((plot == null) || !plot.hasOwner()) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.PLOT_UNOWNED);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (!plot.isOwner(plr.getUUID()) && !Permissions.hasPermission(plr, "plots.admin.command.add")) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NO_PLOT_PERMS);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        UUID uuid;
 | 
			
		||||
        if (args[0].equalsIgnoreCase("*")) {
 | 
			
		||||
            uuid = DBFunc.everyone;
 | 
			
		||||
        } else {
 | 
			
		||||
            uuid = UUIDHandler.getUUID(args[0]);
 | 
			
		||||
        }
 | 
			
		||||
        if (uuid == null) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.INVALID_PLAYER, args[0]);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (plot.isOwner(uuid)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.ALREADY_OWNER);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (plot.members.contains(uuid)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.ALREADY_ADDED);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (plot.removeTrusted(uuid)) {
 | 
			
		||||
            plot.addMember(uuid);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            if (plot.members.size() + plot.trusted.size() >= PS.get().getPlotWorld(plot.world).MAX_PLOT_MEMBERS) {
 | 
			
		||||
                MainUtil.sendMessage(plr, C.PLOT_MAX_MEMBERS);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            if (plot.denied.contains(uuid)) {
 | 
			
		||||
                plot.removeDenied(uuid);
 | 
			
		||||
            }
 | 
			
		||||
            plot.addMember(uuid);
 | 
			
		||||
        }
 | 
			
		||||
        EventUtil.manager.callMember(plr, plot, uuid, true);
 | 
			
		||||
        MainUtil.sendMessage(plr, C.MEMBER_ADDED);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										238
									
								
								src/main/java/com/intellectualcrafters/plot/commands/Auto.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								src/main/java/com/intellectualcrafters/plot/commands/Auto.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,238 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotCluster;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ClusterManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EconHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
 | 
			
		||||
public class Auto extends SubCommand {
 | 
			
		||||
    public Auto() {
 | 
			
		||||
        super("auto", "plots.auto", "Claim the nearest plot", "auto", "a", CommandCategory.CLAIMING, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static PlotId getNextPlot(final PlotId id, final int step) {
 | 
			
		||||
        final int absX = Math.abs(id.x);
 | 
			
		||||
        final int absY = Math.abs(id.y);
 | 
			
		||||
        if (absX > absY) {
 | 
			
		||||
            if (id.x > 0) {
 | 
			
		||||
                return new PlotId(id.x, id.y + 1);
 | 
			
		||||
            } else {
 | 
			
		||||
                return new PlotId(id.x, id.y - 1);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (absY > absX) {
 | 
			
		||||
            if (id.y > 0) {
 | 
			
		||||
                return new PlotId(id.x - 1, id.y);
 | 
			
		||||
            } else {
 | 
			
		||||
                return new PlotId(id.x + 1, id.y);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            if (id.x.equals(id.y) && (id.x > 0)) {
 | 
			
		||||
                return new PlotId(id.x, id.y + step);
 | 
			
		||||
            }
 | 
			
		||||
            if (id.x == absX) {
 | 
			
		||||
                return new PlotId(id.x, id.y + 1);
 | 
			
		||||
            }
 | 
			
		||||
            if (id.y == absY) {
 | 
			
		||||
                return new PlotId(id.x, id.y - 1);
 | 
			
		||||
            }
 | 
			
		||||
            return new PlotId(id.x + 1, id.y);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO auto claim a mega plot with schematic
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        String world;
 | 
			
		||||
        int size_x = 1;
 | 
			
		||||
        int size_z = 1;
 | 
			
		||||
        String schematic = "";
 | 
			
		||||
        if (PS.get().getPlotWorlds().size() == 1) {
 | 
			
		||||
            world = PS.get().getPlotWorlds().iterator().next();
 | 
			
		||||
        } else {
 | 
			
		||||
            world = plr.getLocation().getWorld();
 | 
			
		||||
            if (!PS.get().isPlotWorld(world)) {
 | 
			
		||||
                MainUtil.sendMessage(plr, C.NOT_IN_PLOT_WORLD);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (args.length > 0) {
 | 
			
		||||
            if (Permissions.hasPermission(plr, "plots.auto.mega")) {
 | 
			
		||||
                try {
 | 
			
		||||
                    final String[] split = args[0].split(",");
 | 
			
		||||
                    size_x = Integer.parseInt(split[0]);
 | 
			
		||||
                    size_z = Integer.parseInt(split[1]);
 | 
			
		||||
                    if ((size_x < 1) || (size_z < 1)) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, "&cError: size<=0");
 | 
			
		||||
                    }
 | 
			
		||||
                    if ((size_x > 4) || (size_z > 4)) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, "&cError: size>4");
 | 
			
		||||
                    }
 | 
			
		||||
                    if (args.length > 1) {
 | 
			
		||||
                        schematic = args[1];
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (final Exception e) {
 | 
			
		||||
                    size_x = 1;
 | 
			
		||||
                    size_z = 1;
 | 
			
		||||
                    schematic = args[0];
 | 
			
		||||
                    // PlayerFunctions.sendMessage(plr,
 | 
			
		||||
                    // "&cError: Invalid size (X,Y)");
 | 
			
		||||
                    // return false;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                schematic = args[0];
 | 
			
		||||
                // PlayerFunctions.sendMessage(plr, C.NO_PERMISSION);
 | 
			
		||||
                // return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if ((size_x * size_z) > Settings.MAX_AUTO_SIZE) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.CANT_CLAIM_MORE_PLOTS_NUM, Settings.MAX_AUTO_SIZE + "");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final int currentPlots = Settings.GLOBAL_LIMIT ? MainUtil.getPlayerPlotCount(plr) : MainUtil.getPlayerPlotCount(world, plr);
 | 
			
		||||
        final int diff = currentPlots - MainUtil.getAllowedPlots(plr);
 | 
			
		||||
        if ((diff + (size_x * size_z)) > 0) {
 | 
			
		||||
            if (diff < 0) {
 | 
			
		||||
                MainUtil.sendMessage(plr, C.CANT_CLAIM_MORE_PLOTS_NUM, (-diff) + "");
 | 
			
		||||
            } else {
 | 
			
		||||
                MainUtil.sendMessage(plr, C.CANT_CLAIM_MORE_PLOTS);
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final PlotWorld pWorld = PS.get().getPlotWorld(world);
 | 
			
		||||
        if ((EconHandler.manager != null) && pWorld.USE_ECONOMY) {
 | 
			
		||||
            double cost = pWorld.PLOT_PRICE;
 | 
			
		||||
            cost = (size_x * size_z) * cost;
 | 
			
		||||
            if (cost > 0d) {
 | 
			
		||||
                if (EconHandler.manager.getMoney(plr) < cost) {
 | 
			
		||||
                    sendMessage(plr, C.CANNOT_AFFORD_PLOT, "" + cost);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                EconHandler.manager.withdrawMoney(plr, cost);
 | 
			
		||||
                sendMessage(plr, C.REMOVED_BALANCE, cost + "");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!schematic.equals("")) {
 | 
			
		||||
            // if (pWorld.SCHEMATIC_CLAIM_SPECIFY) {
 | 
			
		||||
            if (!pWorld.SCHEMATICS.contains(schematic.toLowerCase())) {
 | 
			
		||||
                sendMessage(plr, C.SCHEMATIC_INVALID, "non-existent: " + schematic);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            if (!Permissions.hasPermission(plr, "plots.claim." + schematic) && !plr.hasPermission("plots.admin.command.schematic")) {
 | 
			
		||||
                MainUtil.sendMessage(plr, C.NO_SCHEMATIC_PERMISSION, schematic);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            // }
 | 
			
		||||
        }
 | 
			
		||||
        final String worldname = world;
 | 
			
		||||
        final PlotWorld plotworld = PS.get().getPlotWorld(worldname);
 | 
			
		||||
        if (plotworld.TYPE == 2) {
 | 
			
		||||
            final Location loc = plr.getLocation();
 | 
			
		||||
            final Plot plot = MainUtil.getPlot(new Location(worldname, loc.getX(), loc.getY(), loc.getZ()));
 | 
			
		||||
            if (plot == null) {
 | 
			
		||||
                return sendMessage(plr, C.NOT_IN_PLOT);
 | 
			
		||||
            }
 | 
			
		||||
            final PlotCluster cluster = ClusterManager.getCluster(loc);
 | 
			
		||||
            // Must be standing in a cluster
 | 
			
		||||
            if (cluster == null) {
 | 
			
		||||
                MainUtil.sendMessage(plr, C.NOT_IN_CLUSTER);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            final PlotId bot = cluster.getP1();
 | 
			
		||||
            final PlotId top = cluster.getP2();
 | 
			
		||||
            final PlotId origin = new PlotId((bot.x + top.x) / 2, (bot.y + top.y) / 2);
 | 
			
		||||
            PlotId id = new PlotId(0, 0);
 | 
			
		||||
            final int width = Math.max((top.x - bot.x) + 1, (top.y - bot.y) + 1);
 | 
			
		||||
            final int max = width * width;
 | 
			
		||||
            //
 | 
			
		||||
            for (int i = 0; i <= max; i++) {
 | 
			
		||||
                final PlotId currentId = new PlotId(origin.x + id.x, origin.y + id.y);
 | 
			
		||||
                final Plot current = MainUtil.getPlot(worldname, currentId);
 | 
			
		||||
                if (MainUtil.canClaim(plr, current) && (current.settings.isMerged() == false) && cluster.equals(ClusterManager.getCluster(current))) {
 | 
			
		||||
                    Claim.claimPlot(plr, current, true, true);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                id = getNextPlot(id, 1);
 | 
			
		||||
            }
 | 
			
		||||
            // no free plots
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NO_FREE_PLOTS);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        boolean br = false;
 | 
			
		||||
        if ((size_x == 1) && (size_z == 1)) {
 | 
			
		||||
            while (!br) {
 | 
			
		||||
                final Plot plot = MainUtil.getPlot(worldname, getLastPlot(worldname));
 | 
			
		||||
                if (MainUtil.canClaim(plr, plot)) {
 | 
			
		||||
                    Claim.claimPlot(plr, plot, true, true);
 | 
			
		||||
                    br = true;
 | 
			
		||||
                }
 | 
			
		||||
                MainUtil.lastPlot.put(worldname, getNextPlot(getLastPlot(worldname), 1));
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            boolean lastPlot = true;
 | 
			
		||||
            while (!br) {
 | 
			
		||||
                final PlotId start = getNextPlot(getLastPlot(worldname), 1);
 | 
			
		||||
                // Checking if the current set of plots is a viable option.
 | 
			
		||||
                MainUtil.lastPlot.put(worldname, start);
 | 
			
		||||
                if (lastPlot) {
 | 
			
		||||
                }
 | 
			
		||||
                if ((PS.get().getPlots(worldname).get(start) != null) && (PS.get().getPlots(worldname).get(start).owner != null)) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                } else {
 | 
			
		||||
                    lastPlot = false;
 | 
			
		||||
                }
 | 
			
		||||
                final PlotId end = new PlotId((start.x + size_x) - 1, (start.y + size_z) - 1);
 | 
			
		||||
                if (MainUtil.canClaim(plr, worldname, start, end)) {
 | 
			
		||||
                    for (int i = start.x; i <= end.x; i++) {
 | 
			
		||||
                        for (int j = start.y; j <= end.y; j++) {
 | 
			
		||||
                            final Plot plot = MainUtil.getPlot(worldname, new PlotId(i, j));
 | 
			
		||||
                            final boolean teleport = ((i == end.x) && (j == end.y));
 | 
			
		||||
                            Claim.claimPlot(plr, plot, teleport, true);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!MainUtil.mergePlots(worldname, MainUtil.getPlotSelectionIds(start, end), true)) {
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    br = true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.lastPlot.put(worldname, new PlotId(0, 0));
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public PlotId getLastPlot(final String world) {
 | 
			
		||||
        if ((MainUtil.lastPlot == null) || !MainUtil.lastPlot.containsKey(world)) {
 | 
			
		||||
            MainUtil.lastPlot.put(world, new PlotId(0, 0));
 | 
			
		||||
        }
 | 
			
		||||
        return MainUtil.lastPlot.get(world);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,73 @@
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.command.Command;
 | 
			
		||||
import org.bukkit.command.CommandExecutor;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.command.TabCompleter;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.StringComparison;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitUtil;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created 2015-02-20 for PlotSquared
 | 
			
		||||
 *
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 */
 | 
			
		||||
public class BukkitCommand implements CommandExecutor, TabCompleter {
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onCommand(final CommandSender commandSender, final Command command, final String commandLabel, final String[] args) {
 | 
			
		||||
        if (commandSender instanceof Player) {
 | 
			
		||||
            return MainCommand.onCommand(BukkitUtil.getPlayer((Player) commandSender), commandLabel, args);
 | 
			
		||||
        }
 | 
			
		||||
        return MainCommand.onCommand(null, commandLabel, args);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<String> onTabComplete(final CommandSender commandSender, final Command command, final String s, final String[] strings) {
 | 
			
		||||
        if (!(commandSender instanceof Player)) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        final PlotPlayer player = BukkitUtil.getPlayer((Player) commandSender);
 | 
			
		||||
        if (strings.length < 1) {
 | 
			
		||||
            if ((strings.length == 0) || "plots".startsWith(s)) {
 | 
			
		||||
                return Arrays.asList("plots");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (strings.length > 1) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        if (!command.getLabel().equalsIgnoreCase("plots")) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        final List<String> tabOptions = new ArrayList<>();
 | 
			
		||||
        final String[] commands = new String[MainCommand.subCommands.size()];
 | 
			
		||||
        for (int x = 0; x < MainCommand.subCommands.size(); x++) {
 | 
			
		||||
            commands[x] = MainCommand.subCommands.get(x).cmd;
 | 
			
		||||
        }
 | 
			
		||||
        String best = new StringComparison(strings[0], commands).getBestMatch();
 | 
			
		||||
        tabOptions.add(best);
 | 
			
		||||
        final String arg = strings[0].toLowerCase();
 | 
			
		||||
        for (final SubCommand cmd : MainCommand.subCommands) {
 | 
			
		||||
            if (!cmd.cmd.equalsIgnoreCase(best)) {
 | 
			
		||||
                if (cmd.permission.hasPermission(player)) {
 | 
			
		||||
                    if (cmd.cmd.startsWith(arg)) {
 | 
			
		||||
                        tabOptions.add(cmd.cmd);
 | 
			
		||||
                    } else if (cmd.alias.size() > 0 && cmd.alias.get(0).startsWith(arg)) {
 | 
			
		||||
                        tabOptions.add(cmd.alias.get(0));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (tabOptions.size() > 0) {
 | 
			
		||||
            return tabOptions;
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										119
									
								
								src/main/java/com/intellectualcrafters/plot/commands/Buy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/main/java/com/intellectualcrafters/plot/commands/Buy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.Flag;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.FlagManager;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EconHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 */
 | 
			
		||||
public class Buy extends SubCommand {
 | 
			
		||||
    public Buy() {
 | 
			
		||||
        super(Command.BUY, "Buy the plot you are standing on", "b", CommandCategory.CLAIMING, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if (EconHandler.manager == null) {
 | 
			
		||||
            return sendMessage(plr, C.ECON_DISABLED);
 | 
			
		||||
        }
 | 
			
		||||
        final Location loc = plr.getLocation();
 | 
			
		||||
        final String world = loc.getWorld();
 | 
			
		||||
        if (!PS.get().isPlotWorld(world)) {
 | 
			
		||||
            return sendMessage(plr, C.NOT_IN_PLOT_WORLD);
 | 
			
		||||
        }
 | 
			
		||||
        Plot plot;
 | 
			
		||||
        if (args.length > 0) {
 | 
			
		||||
            try {
 | 
			
		||||
                final String[] split = args[0].split(";");
 | 
			
		||||
                final PlotId id = new PlotId(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
 | 
			
		||||
                plot = MainUtil.getPlot(world, id);
 | 
			
		||||
            } catch (final Exception e) {
 | 
			
		||||
                return sendMessage(plr, C.NOT_VALID_PLOT_ID);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            plot = MainUtil.getPlot(loc);
 | 
			
		||||
        }
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            return sendMessage(plr, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        final int currentPlots = Settings.GLOBAL_LIMIT ? MainUtil.getPlayerPlotCount(plr) : MainUtil.getPlayerPlotCount(world, plr);
 | 
			
		||||
        if (currentPlots >= MainUtil.getAllowedPlots(plr)) {
 | 
			
		||||
            return sendMessage(plr, C.CANT_CLAIM_MORE_PLOTS);
 | 
			
		||||
        }
 | 
			
		||||
        if (!plot.hasOwner()) {
 | 
			
		||||
            return sendMessage(plr, C.PLOT_UNOWNED);
 | 
			
		||||
        }
 | 
			
		||||
        if (PlotHandler.isOwner(plot, plr.getUUID())) {
 | 
			
		||||
            return sendMessage(plr, C.CANNOT_BUY_OWN);
 | 
			
		||||
        }
 | 
			
		||||
        final Flag flag = FlagManager.getPlotFlag(plot, "price");
 | 
			
		||||
        if (flag == null) {
 | 
			
		||||
            return sendMessage(plr, C.NOT_FOR_SALE);
 | 
			
		||||
        }
 | 
			
		||||
        double initPrice = (double) flag.getValue();
 | 
			
		||||
        double price = initPrice;
 | 
			
		||||
        final PlotId id = plot.id;
 | 
			
		||||
        final PlotId id2 = MainUtil.getTopPlot(plot).id;
 | 
			
		||||
        final int size = MainUtil.getPlotSelectionIds(id, id2).size();
 | 
			
		||||
        final PlotWorld plotworld = PS.get().getPlotWorld(world);
 | 
			
		||||
        if (plotworld.USE_ECONOMY) {
 | 
			
		||||
            price += plotworld.PLOT_PRICE * size;
 | 
			
		||||
            initPrice += plotworld.SELL_PRICE * size;
 | 
			
		||||
        }
 | 
			
		||||
        if ((EconHandler.manager != null) && (price > 0d)) {
 | 
			
		||||
            if (EconHandler.manager.getMoney(plr) < price) {
 | 
			
		||||
                return sendMessage(plr, C.CANNOT_AFFORD_PLOT, "" + price);
 | 
			
		||||
            }
 | 
			
		||||
            EconHandler.manager.withdrawMoney(plr, price);
 | 
			
		||||
            sendMessage(plr, C.REMOVED_BALANCE, price + "");
 | 
			
		||||
            EconHandler.manager.depositMoney(UUIDHandler.uuidWrapper.getOfflinePlayer(plot.owner), initPrice);
 | 
			
		||||
            final PlotPlayer owner = UUIDHandler.getPlayer(plot.owner);
 | 
			
		||||
            if (owner != null) {
 | 
			
		||||
                sendMessage(plr, C.PLOT_SOLD, plot.id + "", plr.getName(), initPrice + "");
 | 
			
		||||
            }
 | 
			
		||||
            FlagManager.removePlotFlag(plot, "price");
 | 
			
		||||
        }
 | 
			
		||||
        Plot top = MainUtil.getTopPlot(plot);
 | 
			
		||||
        
 | 
			
		||||
        for (PlotId myId : MainUtil.getPlotSelectionIds(plot.id, top.id)) {
 | 
			
		||||
            Plot myPlot = MainUtil.getPlot(plot.world, myId);
 | 
			
		||||
            myPlot.owner = plr.getUUID();
 | 
			
		||||
            DBFunc.setOwner(plot, myPlot.owner);
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.sendMessage(plr, C.CLAIMED);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,34 @@
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotWorld;
 | 
			
		||||
 | 
			
		||||
public class Chat extends SubCommand {
 | 
			
		||||
    public Chat() {
 | 
			
		||||
        super(Command.CHAT, "Toggle plot chat on or off", "chat", CommandCategory.ACTIONS, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(PlotPlayer plr, String... args) {
 | 
			
		||||
        final String world = plr.getLocation().getWorld();
 | 
			
		||||
        if (!PS.get().isPlotWorld(world)) {
 | 
			
		||||
            return !sendMessage(plr, C.NOT_IN_PLOT_WORLD);
 | 
			
		||||
        }
 | 
			
		||||
        boolean enable = !(plr.getMeta("chat") != null && (Boolean) plr.getMeta("chat"));
 | 
			
		||||
        if (args.length > 0) {
 | 
			
		||||
            if (args[0].equalsIgnoreCase("on")) {
 | 
			
		||||
                enable = true;
 | 
			
		||||
            } else if (args[0].equalsIgnoreCase("off")) {
 | 
			
		||||
                enable = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        final PlotWorld plotworld = PS.get().getPlotWorld(world);
 | 
			
		||||
        if (!enable && plotworld.PLOT_CHAT) {
 | 
			
		||||
            return !sendMessage(plr, C.PLOT_CHAT_FORCED);
 | 
			
		||||
        }
 | 
			
		||||
        plr.setMeta("chat", enable);
 | 
			
		||||
        return sendMessage(plr, enable ? C.PLOT_CHAT_ON : C.PLOT_CHAT_OFF);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										123
									
								
								src/main/java/com/intellectualcrafters/plot/commands/Claim.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/main/java/com/intellectualcrafters/plot/commands/Claim.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EconHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EventUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.intellectualcrafters.plot.util.SchematicHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.SchematicHandler.Schematic;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 */
 | 
			
		||||
public class Claim extends SubCommand {
 | 
			
		||||
    public Claim() {
 | 
			
		||||
        super(Command.CLAIM, "Claim the current plot you're standing on.", "claim", CommandCategory.CLAIMING, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean claimPlot(final PlotPlayer player, final Plot plot, final boolean teleport, final boolean auto) {
 | 
			
		||||
        return claimPlot(player, plot, teleport, "", auto);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean claimPlot(final PlotPlayer player, final Plot plot, final boolean teleport, final String schematic, final boolean auto) {
 | 
			
		||||
        if (plot.hasOwner() || plot.settings.isMerged()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final boolean result = EventUtil.manager.callClaim(player, plot, false);
 | 
			
		||||
        if (result) {
 | 
			
		||||
            MainUtil.createPlot(player.getUUID(), plot);
 | 
			
		||||
            MainUtil.setSign(player.getName(), plot);
 | 
			
		||||
            MainUtil.sendMessage(player, C.CLAIMED);
 | 
			
		||||
            final Location loc = player.getLocation();
 | 
			
		||||
            if (teleport) {
 | 
			
		||||
                MainUtil.teleportPlayer(player, loc, plot);
 | 
			
		||||
            }
 | 
			
		||||
            final String world = plot.world;
 | 
			
		||||
            final PlotWorld plotworld = PS.get().getPlotWorld(world);
 | 
			
		||||
            final Plot plot2 = PS.get().getPlots(world).get(plot.id);
 | 
			
		||||
            if (plotworld.SCHEMATIC_ON_CLAIM) {
 | 
			
		||||
                Schematic sch;
 | 
			
		||||
                if (schematic.equals("")) {
 | 
			
		||||
                    sch = SchematicHandler.manager.getSchematic(plotworld.SCHEMATIC_FILE);
 | 
			
		||||
                } else {
 | 
			
		||||
                    sch = SchematicHandler.manager.getSchematic(schematic);
 | 
			
		||||
                    if (sch == null) {
 | 
			
		||||
                        sch = SchematicHandler.manager.getSchematic(plotworld.SCHEMATIC_FILE);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                SchematicHandler.manager.paste(sch, plot2, 0, 0);
 | 
			
		||||
            }
 | 
			
		||||
            PS.get().getPlotManager(world).claimPlot(plotworld, plot);
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        String schematic = "";
 | 
			
		||||
        if (args.length >= 1) {
 | 
			
		||||
            schematic = args[0];
 | 
			
		||||
        }
 | 
			
		||||
        final Location loc = plr.getLocation();
 | 
			
		||||
        final Plot plot = MainUtil.getPlot(loc);
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            return sendMessage(plr, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        final int currentPlots = Settings.GLOBAL_LIMIT ? MainUtil.getPlayerPlotCount(plr) : MainUtil.getPlayerPlotCount(loc.getWorld(), plr);
 | 
			
		||||
        if (currentPlots >= MainUtil.getAllowedPlots(plr)) {
 | 
			
		||||
            return sendMessage(plr, C.CANT_CLAIM_MORE_PLOTS);
 | 
			
		||||
        }
 | 
			
		||||
        if (!MainUtil.canClaim(plr, plot)) {
 | 
			
		||||
            return sendMessage(plr, C.PLOT_IS_CLAIMED);
 | 
			
		||||
        }
 | 
			
		||||
        final PlotWorld world = PS.get().getPlotWorld(plot.world);
 | 
			
		||||
        if ((EconHandler.manager != null) && world.USE_ECONOMY) {
 | 
			
		||||
            final double cost = world.PLOT_PRICE;
 | 
			
		||||
            if (cost > 0d) {
 | 
			
		||||
                if (EconHandler.manager.getMoney(plr) < cost) {
 | 
			
		||||
                    return sendMessage(plr, C.CANNOT_AFFORD_PLOT, "" + cost);
 | 
			
		||||
                }
 | 
			
		||||
                EconHandler.manager.withdrawMoney(plr, cost);
 | 
			
		||||
                sendMessage(plr, C.REMOVED_BALANCE, cost + "");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!schematic.equals("")) {
 | 
			
		||||
            if (world.SCHEMATIC_CLAIM_SPECIFY) {
 | 
			
		||||
                if (!world.SCHEMATICS.contains(schematic.toLowerCase())) {
 | 
			
		||||
                    return sendMessage(plr, C.SCHEMATIC_INVALID, "non-existent: " + schematic);
 | 
			
		||||
                }
 | 
			
		||||
                if (!Permissions.hasPermission(plr, "plots.claim." + schematic) && !plr.hasPermission("plots.admin.command.schematic")) {
 | 
			
		||||
                    return sendMessage(plr, C.NO_SCHEMATIC_PERMISSION, schematic);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return claimPlot(plr, plot, false, schematic, false) || sendMessage(plr, C.PLOT_NOT_CLAIMED);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										144
									
								
								src/main/java/com/intellectualcrafters/plot/commands/Clear.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								src/main/java/com/intellectualcrafters/plot/commands/Clear.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,144 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.CmdConfirm;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
 | 
			
		||||
public class Clear extends SubCommand {
 | 
			
		||||
    public Clear() {
 | 
			
		||||
        super(Command.CLEAR, "Clear a plot", "clear", CommandCategory.ACTIONS, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if (plr == null) {
 | 
			
		||||
            // Is console
 | 
			
		||||
            if (args.length < 2) {
 | 
			
		||||
                PS.log("You need to specify two arguments: ID (0;0) & World (world)");
 | 
			
		||||
            } else {
 | 
			
		||||
                final PlotId id = PlotId.fromString(args[0]);
 | 
			
		||||
                final String world = args[1];
 | 
			
		||||
                if (id == null) {
 | 
			
		||||
                    PS.log("Invalid Plot ID: " + args[0]);
 | 
			
		||||
                } else {
 | 
			
		||||
                    if (!PS.get().isPlotWorld(world)) {
 | 
			
		||||
                        PS.log("Invalid plot world: " + world);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        final Plot plot = MainUtil.getPlot(world, id);
 | 
			
		||||
                        if (plot == null) {
 | 
			
		||||
                            PS.log("Could not find plot " + args[0] + " in world " + world);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            Runnable runnable = new Runnable() {
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void run() {
 | 
			
		||||
                                    MainUtil.clear(plot, plot.owner == null, null);
 | 
			
		||||
                                    PS.log("Plot " + plot.getId().toString() + " cleared.");
 | 
			
		||||
                                }
 | 
			
		||||
                            };
 | 
			
		||||
                            if (Settings.CONFIRM_CLEAR && !(Permissions.hasPermission(plr, "plots.confirm.bypass"))) {
 | 
			
		||||
                                CmdConfirm.addPending(plr, "/plot clear " + id, runnable);
 | 
			
		||||
                            }
 | 
			
		||||
                            else {
 | 
			
		||||
                                TaskManager.runTask(runnable);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        final Location loc = plr.getLocation();
 | 
			
		||||
        final Plot plot;
 | 
			
		||||
        if (args.length == 2) {
 | 
			
		||||
            PlotId id = PlotId.fromString(args[0]);
 | 
			
		||||
            if (id == null) {
 | 
			
		||||
                if (args[1].equalsIgnoreCase("mine")) {
 | 
			
		||||
                    Set<Plot> plots = PS.get().getPlots(plr);
 | 
			
		||||
                    if (plots.size() == 0) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.NO_PLOTS);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    plot = plots.iterator().next();
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot clear [X;Z|mine]");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                plot = MainUtil.getPlot(loc.getWorld(), id);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            plot = MainUtil.getPlot(loc);
 | 
			
		||||
        }
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot clear [X;Z|mine]");
 | 
			
		||||
            return sendMessage(plr, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        if (!MainUtil.getTopPlot(plot).equals(MainUtil.getBottomPlot(plot))) {
 | 
			
		||||
            return sendMessage(plr, C.UNLINK_REQUIRED);
 | 
			
		||||
        }
 | 
			
		||||
        if (((plot == null) || !plot.hasOwner() || !plot.isOwner(UUIDHandler.getUUID(plr))) && !Permissions.hasPermission(plr, "plots.admin.command.clear")) {
 | 
			
		||||
            return sendMessage(plr, C.NO_PLOT_PERMS);
 | 
			
		||||
        }
 | 
			
		||||
        assert plot != null;
 | 
			
		||||
        if (MainUtil.runners.containsKey(plot)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        Runnable runnable = new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                final long start = System.currentTimeMillis();
 | 
			
		||||
                final boolean result = MainUtil.clearAsPlayer(plot, plot.owner == null, new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.CLEARING_DONE, "" + (System.currentTimeMillis() - start));
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
                if (!result) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        if (Settings.CONFIRM_CLEAR && !(Permissions.hasPermission(plr, "plots.confirm.bypass"))) {
 | 
			
		||||
            CmdConfirm.addPending(plr, "/plot clear " + plot.id, runnable);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            TaskManager.runTask(runnable);
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,567 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.AugmentedPopulator;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridGen;
 | 
			
		||||
import com.intellectualcrafters.plot.object.BlockLoc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotCluster;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotClusterId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotGenerator;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ClusterManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
 | 
			
		||||
public class Cluster extends SubCommand {
 | 
			
		||||
    public Cluster() {
 | 
			
		||||
        super(Command.CLUSTER, "Manage a plot cluster", "cluster", CommandCategory.ACTIONS, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        // list, create, delete, resize, invite, kick, leave, helpers, tp, sethome
 | 
			
		||||
        if (args.length == 0) {
 | 
			
		||||
            // return arguments
 | 
			
		||||
            MainUtil.sendMessage(plr, C.CLUSTER_AVAILABLE_ARGS);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final String sub = args[0].toLowerCase();
 | 
			
		||||
        switch (sub) {
 | 
			
		||||
            case "l":
 | 
			
		||||
            case "list": {
 | 
			
		||||
                if (!Permissions.hasPermission(plr, "plots.cluster.list")) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.list");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 1) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot cluster list");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final HashSet<PlotCluster> clusters = ClusterManager.getClusters(plr.getLocation().getWorld());
 | 
			
		||||
                MainUtil.sendMessage(plr, C.CLUSTER_LIST_HEADING, clusters.size() + "");
 | 
			
		||||
                for (final PlotCluster cluster : clusters) {
 | 
			
		||||
                    // Ignore unmanaged clusters
 | 
			
		||||
                    final String name = "'" + cluster.getName() + "' : " + cluster.toString();
 | 
			
		||||
                    if (UUIDHandler.getUUID(plr).equals(cluster.owner)) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.CLUSTER_LIST_ELEMENT, "&a" + name);
 | 
			
		||||
                    } else if (cluster.helpers.contains(UUIDHandler.getUUID(plr))) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.CLUSTER_LIST_ELEMENT, "&3" + name);
 | 
			
		||||
                    } else if (cluster.invited.contains(UUIDHandler.getUUID(plr))) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.CLUSTER_LIST_ELEMENT, "&9" + name);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.CLUSTER_LIST_ELEMENT, cluster.toString());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "c":
 | 
			
		||||
            case "create": {
 | 
			
		||||
                if (!Permissions.hasPermission(plr, "plots.cluster.create")) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.create");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 4) {
 | 
			
		||||
                    final PlotId id = ClusterManager.estimatePlotId(plr.getLocation());
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot cluster create <name> <id-bot> <id-top>");
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.CLUSTER_CURRENT_PLOTID, "" + id);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                // check pos1 / pos2
 | 
			
		||||
                final PlotId pos1 = MainUtil.parseId(args[2]);
 | 
			
		||||
                final PlotId pos2 = MainUtil.parseId(args[3]);
 | 
			
		||||
                if ((pos1 == null) || (pos2 == null)) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_ID);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                // check if name is taken
 | 
			
		||||
                final String name = args[1];
 | 
			
		||||
                for (final PlotCluster cluster : ClusterManager.getClusters(plr.getLocation().getWorld())) {
 | 
			
		||||
                    if (name.equals(cluster.getName())) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.ALIAS_IS_TAKEN);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                //check if overlap
 | 
			
		||||
                final PlotClusterId id = new PlotClusterId(pos1, pos2);
 | 
			
		||||
                final HashSet<PlotCluster> intersects = ClusterManager.getIntersects(plr.getLocation().getWorld(), id);
 | 
			
		||||
                if ((intersects.size() > 0) || (pos2.x < pos1.x) || (pos2.y < pos1.y)) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.CLUSTER_INTERSECTION, intersects.size() + "");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                // create cluster
 | 
			
		||||
                final String world = plr.getLocation().getWorld();
 | 
			
		||||
                final PlotCluster cluster = new PlotCluster(world, pos1, pos2, UUIDHandler.getUUID(plr));
 | 
			
		||||
                cluster.settings.setAlias(name);
 | 
			
		||||
                DBFunc.createCluster(world, cluster);
 | 
			
		||||
                if (!ClusterManager.clusters.containsKey(world)) {
 | 
			
		||||
                    ClusterManager.clusters.put(world, new HashSet<PlotCluster>());
 | 
			
		||||
                }
 | 
			
		||||
                ClusterManager.clusters.get(world).add(cluster);
 | 
			
		||||
                // Add any existing plots to the current cluster
 | 
			
		||||
                for (final Plot plot : PS.get().getPlots(plr.getLocation().getWorld()).values()) {
 | 
			
		||||
                    final PlotCluster current = ClusterManager.getCluster(plot);
 | 
			
		||||
                    if (cluster.equals(current) && !cluster.isAdded(plot.owner)) {
 | 
			
		||||
                        cluster.invited.add(plot.owner);
 | 
			
		||||
                        DBFunc.setInvited(world, cluster, plot.owner);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                PlotWorld plotworld = PS.get().getPlotWorld(world);
 | 
			
		||||
                if (plotworld == null) {
 | 
			
		||||
                    PS.get().config.createSection("worlds." + world);
 | 
			
		||||
                    PS.get().loadWorld(world, null);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    final String gen_string = PS.get().config.getString("worlds." + world + "." + "generator.plugin");
 | 
			
		||||
                    PlotGenerator generator;
 | 
			
		||||
                    if (gen_string == null) {
 | 
			
		||||
                        generator = new HybridGen(world);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        generator = (PlotGenerator) PS.get().IMP.getGenerator(world, gen_string);
 | 
			
		||||
                    }
 | 
			
		||||
                    new AugmentedPopulator(world, generator, cluster, plotworld.TERRAIN == 2, plotworld.TERRAIN != 2);
 | 
			
		||||
                }
 | 
			
		||||
                MainUtil.sendMessage(plr, C.CLUSTER_ADDED);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "disband":
 | 
			
		||||
            case "del":
 | 
			
		||||
            case "delete": {
 | 
			
		||||
                if (!Permissions.hasPermission(plr, "plots.cluster.delete")) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.delete");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if ((args.length != 1) && (args.length != 2)) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot cluster delete [name]");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                PlotCluster cluster;
 | 
			
		||||
                if (args.length == 2) {
 | 
			
		||||
                    cluster = ClusterManager.getCluster(plr.getLocation().getWorld(), args[1]);
 | 
			
		||||
                    if (cluster == null) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.INVALID_CLUSTER, args[1]);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    cluster = ClusterManager.getCluster(plr.getLocation());
 | 
			
		||||
                    if (cluster == null) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.NOT_IN_CLUSTER);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (!cluster.owner.equals(UUIDHandler.getUUID(plr))) {
 | 
			
		||||
                    if (!Permissions.hasPermission(plr, "plots.cluster.delete.other")) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.delete.other");
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                final PlotWorld plotworld = PS.get().getPlotWorld(plr.getLocation().getWorld());
 | 
			
		||||
                if (plotworld.TYPE == 2) {
 | 
			
		||||
                    final ArrayList<Plot> toRemove = new ArrayList<>();
 | 
			
		||||
                    for (final Plot plot : PS.get().getPlots(plr.getLocation().getWorld()).values()) {
 | 
			
		||||
                        final PlotCluster other = ClusterManager.getCluster(plot);
 | 
			
		||||
                        if (cluster.equals(other)) {
 | 
			
		||||
                            toRemove.add(plot);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    for (final Plot plot : toRemove) {
 | 
			
		||||
                        plot.unclaim();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                DBFunc.delete(cluster);
 | 
			
		||||
                if (plotworld.TYPE == 2) {
 | 
			
		||||
                    AugmentedPopulator.removePopulator(plr.getLocation().getWorld(), cluster);
 | 
			
		||||
                }
 | 
			
		||||
                ClusterManager.last = null;
 | 
			
		||||
                ClusterManager.clusters.get(cluster.world).remove(cluster);
 | 
			
		||||
                ClusterManager.regenCluster(cluster);
 | 
			
		||||
                MainUtil.sendMessage(plr, C.CLUSTER_DELETED);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "res":
 | 
			
		||||
            case "resize": {
 | 
			
		||||
                if (!Permissions.hasPermission(plr, "plots.cluster.resize")) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.resize");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 3) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot cluster resize <pos1> <pos2>");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                // check pos1 / pos2
 | 
			
		||||
                final PlotId pos1 = MainUtil.parseId(args[1]);
 | 
			
		||||
                final PlotId pos2 = MainUtil.parseId(args[2]);
 | 
			
		||||
                if ((pos1 == null) || (pos2 == null)) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_ID);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                // check if in cluster
 | 
			
		||||
                final PlotCluster cluster = ClusterManager.getCluster(plr.getLocation());
 | 
			
		||||
                if (cluster == null) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NOT_IN_CLUSTER);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (!cluster.hasHelperRights(UUIDHandler.getUUID(plr))) {
 | 
			
		||||
                    if (!Permissions.hasPermission(plr, "plots.cluster.resize.other")) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.resize.other");
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                //check if overlap
 | 
			
		||||
                final PlotClusterId id = new PlotClusterId(pos1, pos2);
 | 
			
		||||
                final HashSet<PlotCluster> intersects = ClusterManager.getIntersects(plr.getLocation().getWorld(), id);
 | 
			
		||||
                if (intersects.size() > 1) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.CLUSTER_INTERSECTION, (intersects.size() - 1) + "");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                // resize cluster
 | 
			
		||||
                DBFunc.resizeCluster(cluster, id);
 | 
			
		||||
                MainUtil.sendMessage(plr, C.CLUSTER_RESIZED);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "reg":
 | 
			
		||||
            case "regenerate":
 | 
			
		||||
            case "regen": {
 | 
			
		||||
                if (!Permissions.hasPermission(plr, "plots.cluster.delete")) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.regen");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if ((args.length != 1) && (args.length != 2)) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot cluster regen [name]");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                PlotCluster cluster;
 | 
			
		||||
                if (args.length == 2) {
 | 
			
		||||
                    cluster = ClusterManager.getCluster(plr.getLocation().getWorld(), args[1]);
 | 
			
		||||
                    if (cluster == null) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.INVALID_CLUSTER, args[1]);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    cluster = ClusterManager.getCluster(plr.getLocation());
 | 
			
		||||
                    if (cluster == null) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.NOT_IN_CLUSTER);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (!cluster.owner.equals(UUIDHandler.getUUID(plr))) {
 | 
			
		||||
                    if (!Permissions.hasPermission(plr, "plots.cluster.regen.other")) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.regen.other");
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                ClusterManager.regenCluster(cluster);
 | 
			
		||||
                MainUtil.sendMessage(plr, C.CLUSTER_REGENERATED);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "add":
 | 
			
		||||
            case "inv":
 | 
			
		||||
            case "invite": {
 | 
			
		||||
                if (!Permissions.hasPermission(plr, "plots.cluster.invite")) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.invite");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 2) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot cluster invite <player>");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                // check if in cluster
 | 
			
		||||
                final PlotCluster cluster = ClusterManager.getCluster(plr.getLocation());
 | 
			
		||||
                if (cluster == null) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NOT_IN_CLUSTER);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (!cluster.hasHelperRights(UUIDHandler.getUUID(plr))) {
 | 
			
		||||
                    if (!Permissions.hasPermission(plr, "plots.cluster.invite.other")) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.invite.other");
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                // check uuid
 | 
			
		||||
                final UUID uuid = UUIDHandler.getUUID(args[1]);
 | 
			
		||||
                if (uuid == null) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.INVALID_PLAYER, args[2]);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (!cluster.isAdded(uuid)) {
 | 
			
		||||
                    // add the user if not added
 | 
			
		||||
                    cluster.invited.add(uuid);
 | 
			
		||||
                    final String world = plr.getLocation().getWorld();
 | 
			
		||||
                    DBFunc.setInvited(world, cluster, uuid);
 | 
			
		||||
                    final PlotPlayer player = UUIDHandler.getPlayer(uuid);
 | 
			
		||||
                    if (player != null) {
 | 
			
		||||
                        MainUtil.sendMessage(player, C.CLUSTER_INVITED, cluster.getName());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                MainUtil.sendMessage(plr, C.CLUSTER_ADDED_USER);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "k":
 | 
			
		||||
            case "remove":
 | 
			
		||||
            case "kick": {
 | 
			
		||||
                if (!Permissions.hasPermission(plr, "plots.cluster.kick")) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.kick");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 2) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot cluster kick <player>");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final PlotCluster cluster = ClusterManager.getCluster(plr.getLocation());
 | 
			
		||||
                if (cluster == null) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NOT_IN_CLUSTER);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (!cluster.hasHelperRights(UUIDHandler.getUUID(plr))) {
 | 
			
		||||
                    if (!Permissions.hasPermission(plr, "plots.cluster.kick.other")) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.kick.other");
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                // check uuid
 | 
			
		||||
                final UUID uuid = UUIDHandler.getUUID(args[1]);
 | 
			
		||||
                if (uuid == null) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.INVALID_PLAYER, args[1]);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                // Can't kick if the player is yourself, the owner, or not added to the cluster
 | 
			
		||||
                if (uuid.equals(UUIDHandler.getUUID(plr)) || uuid.equals(cluster.owner) || !cluster.isAdded(uuid)) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.CANNOT_KICK_PLAYER, cluster.getName());
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (cluster.helpers.contains(uuid)) {
 | 
			
		||||
                    cluster.helpers.remove(uuid);
 | 
			
		||||
                    DBFunc.removeHelper(cluster, uuid);
 | 
			
		||||
                }
 | 
			
		||||
                cluster.invited.remove(uuid);
 | 
			
		||||
                DBFunc.removeInvited(cluster, uuid);
 | 
			
		||||
                final PlotPlayer player = UUIDHandler.getPlayer(uuid);
 | 
			
		||||
                if (player != null) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.CLUSTER_REMOVED, cluster.getName());
 | 
			
		||||
                }
 | 
			
		||||
                for (final Plot plot : new ArrayList<>(PS.get().getPlots(plr.getLocation().getWorld(), uuid))) {
 | 
			
		||||
                    final PlotCluster current = ClusterManager.getCluster(plot);
 | 
			
		||||
                    if ((current != null) && current.equals(cluster)) {
 | 
			
		||||
                        final String world = plr.getLocation().getWorld();
 | 
			
		||||
                        plot.unclaim();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                MainUtil.sendMessage(plr, C.CLUSTER_KICKED_USER);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "quit":
 | 
			
		||||
            case "leave": {
 | 
			
		||||
                if (!Permissions.hasPermission(plr, "plots.cluster.leave")) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.leave");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if ((args.length != 1) && (args.length != 2)) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot cluster leave [name]");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                PlotCluster cluster;
 | 
			
		||||
                if (args.length == 2) {
 | 
			
		||||
                    cluster = ClusterManager.getCluster(plr.getLocation().getWorld(), args[1]);
 | 
			
		||||
                    if (cluster == null) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.INVALID_CLUSTER, args[1]);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    cluster = ClusterManager.getCluster(plr.getLocation());
 | 
			
		||||
                    if (cluster == null) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.NOT_IN_CLUSTER);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                final UUID uuid = UUIDHandler.getUUID(plr);
 | 
			
		||||
                if (!cluster.isAdded(uuid)) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.CLUSTER_NOT_ADDED);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (uuid.equals(cluster.owner)) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.CLUSTER_CANNOT_LEAVE);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (cluster.helpers.contains(uuid)) {
 | 
			
		||||
                    cluster.helpers.remove(uuid);
 | 
			
		||||
                    DBFunc.removeHelper(cluster, uuid);
 | 
			
		||||
                }
 | 
			
		||||
                cluster.invited.remove(uuid);
 | 
			
		||||
                DBFunc.removeInvited(cluster, uuid);
 | 
			
		||||
                MainUtil.sendMessage(plr, C.CLUSTER_REMOVED, cluster.getName());
 | 
			
		||||
                for (final Plot plot : new ArrayList<>(PS.get().getPlots(plr.getLocation().getWorld(), uuid))) {
 | 
			
		||||
                    final PlotCluster current = ClusterManager.getCluster(plot);
 | 
			
		||||
                    if ((current != null) && current.equals(cluster)) {
 | 
			
		||||
                        final String world = plr.getLocation().getWorld();
 | 
			
		||||
                        plot.unclaim();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "admin":
 | 
			
		||||
            case "helper":
 | 
			
		||||
            case "helpers": {
 | 
			
		||||
                if (!Permissions.hasPermission(plr, "plots.cluster.helpers")) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.helpers");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 3) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot cluster helpers <add|remove> <player>");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final PlotCluster cluster = ClusterManager.getCluster(plr.getLocation());
 | 
			
		||||
                if (cluster == null) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NOT_IN_CLUSTER);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final UUID uuid = UUIDHandler.getUUID(args[2]);
 | 
			
		||||
                if (uuid == null) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.INVALID_PLAYER, args[2]);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args[1].toLowerCase().equals("add")) {
 | 
			
		||||
                    cluster.helpers.add(uuid);
 | 
			
		||||
                    DBFunc.setHelper(cluster, uuid);
 | 
			
		||||
                    return MainUtil.sendMessage(plr, C.CLUSTER_ADDED_HELPER);
 | 
			
		||||
                }
 | 
			
		||||
                if (args[1].toLowerCase().equals("remove")) {
 | 
			
		||||
                    cluster.helpers.remove(uuid);
 | 
			
		||||
                    DBFunc.removeHelper(cluster, uuid);
 | 
			
		||||
                    return MainUtil.sendMessage(plr, C.CLUSTER_REMOVED_HELPER);
 | 
			
		||||
                }
 | 
			
		||||
                MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot cluster helpers <add|remove> <player>");
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            case "spawn":
 | 
			
		||||
            case "home":
 | 
			
		||||
            case "tp": {
 | 
			
		||||
                if (!Permissions.hasPermission(plr, "plots.cluster.tp")) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.tp");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 2) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot cluster tp <name>");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final PlotCluster cluster = ClusterManager.getCluster(plr.getLocation().getWorld(), args[1]);
 | 
			
		||||
                if (cluster == null) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.INVALID_CLUSTER, args[1]);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final UUID uuid = UUIDHandler.getUUID(plr);
 | 
			
		||||
                if (!cluster.isAdded(uuid)) {
 | 
			
		||||
                    if (!Permissions.hasPermission(plr, "plots.cluster.tp.other")) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.tp.other");
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                plr.teleport(ClusterManager.getHome(cluster));
 | 
			
		||||
                return MainUtil.sendMessage(plr, C.CLUSTER_TELEPORTING);
 | 
			
		||||
            }
 | 
			
		||||
            case "i":
 | 
			
		||||
            case "info":
 | 
			
		||||
            case "show":
 | 
			
		||||
            case "information": {
 | 
			
		||||
                if (!Permissions.hasPermission(plr, "plots.cluster.info")) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.info");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if ((args.length != 1) && (args.length != 2)) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot cluster info [name]");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                PlotCluster cluster;
 | 
			
		||||
                if (args.length == 2) {
 | 
			
		||||
                    cluster = ClusterManager.getCluster(plr.getLocation().getWorld(), args[1]);
 | 
			
		||||
                    if (cluster == null) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.INVALID_CLUSTER, args[1]);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    cluster = ClusterManager.getCluster(plr.getLocation());
 | 
			
		||||
                    if (cluster == null) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.NOT_IN_CLUSTER);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                final String id = cluster.toString();
 | 
			
		||||
                String owner = UUIDHandler.getName(cluster.owner);
 | 
			
		||||
                if (owner == null) {
 | 
			
		||||
                    owner = "unknown";
 | 
			
		||||
                }
 | 
			
		||||
                final String name = cluster.getName();
 | 
			
		||||
                final String size = ((cluster.getP2().x - cluster.getP1().x) + 1) + "x" + ((cluster.getP2().y - cluster.getP1().y) + 1);
 | 
			
		||||
                final String rights = cluster.isAdded(UUIDHandler.getUUID(plr)) + "";
 | 
			
		||||
                String message = C.CLUSTER_INFO.s();
 | 
			
		||||
                message = message.replaceAll("%id%", id);
 | 
			
		||||
                message = message.replaceAll("%owner%", owner);
 | 
			
		||||
                message = message.replaceAll("%name%", name);
 | 
			
		||||
                message = message.replaceAll("%size%", size);
 | 
			
		||||
                message = message.replaceAll("%rights%", rights);
 | 
			
		||||
                MainUtil.sendMessage(plr, message);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "sh":
 | 
			
		||||
            case "setspawn":
 | 
			
		||||
            case "sethome": {
 | 
			
		||||
                if (!Permissions.hasPermission(plr, "plots.cluster.sethome")) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.sethome");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if ((args.length != 1) && (args.length != 2)) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot cluster sethome");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final PlotCluster cluster = ClusterManager.getCluster(plr.getLocation());
 | 
			
		||||
                if (cluster == null) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NOT_IN_CLUSTER);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (!cluster.hasHelperRights(UUIDHandler.getUUID(plr))) {
 | 
			
		||||
                    if (!Permissions.hasPermission(plr, "plots.cluster.sethome.other")) {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.cluster.sethome.other");
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                final Location base = ClusterManager.getClusterBottom(cluster);
 | 
			
		||||
                final Location relative = plr.getLocation().subtract(base.getX(), 0, base.getZ());
 | 
			
		||||
                final BlockLoc blockloc = new BlockLoc(relative.getX(), relative.getY(), relative.getZ());
 | 
			
		||||
                cluster.settings.setPosition(blockloc);
 | 
			
		||||
                DBFunc.setPosition(cluster, relative.getX() + "," + relative.getY() + "," + relative.getZ());
 | 
			
		||||
                return MainUtil.sendMessage(plr, C.POSITION_SET);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.sendMessage(plr, C.CLUSTER_AVAILABLE_ARGS);
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,159 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Citymonstret on 2014-08-03.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 * @author Empire92
 | 
			
		||||
 */
 | 
			
		||||
public enum Command {
 | 
			
		||||
    // TODO new commands
 | 
			
		||||
    // (economy)
 | 
			
		||||
    // - /plot buy
 | 
			
		||||
    // - /plot sell <value>
 | 
			
		||||
    // (Rating system) (ratings can be stored as the average, and number of
 | 
			
		||||
    // ratings)
 | 
			
		||||
    // - /plot rate <number out of 10>
 | 
			
		||||
    
 | 
			
		||||
    ADD("add","a"),
 | 
			
		||||
    TRUST("trust", "t"),
 | 
			
		||||
    DENY("deny", "d"),
 | 
			
		||||
    REMOVE("remove", "r"),
 | 
			
		||||
    UNTRUST("untrust", "ut"),
 | 
			
		||||
    UNDENY("undeny", "ud"),
 | 
			
		||||
    TOGGLE("toggle", "attribute"),
 | 
			
		||||
    DOWNLOAD("download", "dl"),
 | 
			
		||||
    MOVE("move"),
 | 
			
		||||
    FLAG("flag", "f"),
 | 
			
		||||
    TARGET("target"),
 | 
			
		||||
    CLUSTER("cluster", "clusters"),
 | 
			
		||||
    BUY("buy", "b"),
 | 
			
		||||
    CREATEROADSCHEMATIC("createroadschematic", "crs"),
 | 
			
		||||
    DEBUGROADREGEN("debugroadregen"),
 | 
			
		||||
    DEBUGFIXFLAGS("debugfixflags"),
 | 
			
		||||
    REGENALLROADS("regenallroads"),
 | 
			
		||||
    ALLOWUNSAFE("debugallowunsafe"),
 | 
			
		||||
    DEBUGLOADTEST("debugloadtest"),
 | 
			
		||||
    DEBUGSAVETEST("debugsavetest"),
 | 
			
		||||
    UNCLAIM("unclaim"),
 | 
			
		||||
    DEBUGCLEAR("debugclear", "fastclear"),
 | 
			
		||||
    SWAP("swap"),
 | 
			
		||||
    INBOX("inbox"),
 | 
			
		||||
    DEBUGCLAIMTEST("debugclaimtest"),
 | 
			
		||||
    COMMENT("comment", "msg"),
 | 
			
		||||
    PASTE("paste"),
 | 
			
		||||
    CLIPBOARD("clipboard", "cboard"),
 | 
			
		||||
    COPY("copy"),
 | 
			
		||||
    KICK("kick", "k"),
 | 
			
		||||
    CLAIM("claim", "c"),
 | 
			
		||||
    MERGE("merge", "m"),
 | 
			
		||||
    UNLINK("unlink", "u"),
 | 
			
		||||
    CLEAR("clear", "", new CommandPermission("plots.clear")),
 | 
			
		||||
    DELETE("delete", "", new CommandPermission("plots.delete")),
 | 
			
		||||
    DEBUG("debug", "", new CommandPermission("plots.admin")),
 | 
			
		||||
    INTERFACE("interface", "int", new CommandPermission("plots.interface")),
 | 
			
		||||
    HOME("home", "h"),
 | 
			
		||||
    INFO("info", "i"),
 | 
			
		||||
    LIST("list", "l"),
 | 
			
		||||
    SET("set", "s"),
 | 
			
		||||
    PURGE("purge"),
 | 
			
		||||
    DATABASE("database", "convert"),
 | 
			
		||||
    CONFIRM("confirm"),
 | 
			
		||||
    TP("tp", "tp"),
 | 
			
		||||
    CHAT("chat", "on|off", new CommandPermission("plots.chat"));
 | 
			
		||||
    /**
 | 
			
		||||
     * Command
 | 
			
		||||
     */
 | 
			
		||||
    private final String command;
 | 
			
		||||
    /**
 | 
			
		||||
     * Alias
 | 
			
		||||
     */
 | 
			
		||||
    private final String alias;
 | 
			
		||||
    /**
 | 
			
		||||
     * Permission Node
 | 
			
		||||
     */
 | 
			
		||||
    private final CommandPermission permission;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param command Command "name" (/plot [cmd])
 | 
			
		||||
     */
 | 
			
		||||
    Command(final String command) {
 | 
			
		||||
        this.command = command;
 | 
			
		||||
        this.alias = command;
 | 
			
		||||
        this.permission = new CommandPermission("plots." + command);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param command    Command "name" (/plot [cmd])
 | 
			
		||||
     * @param permission Command Permission Node
 | 
			
		||||
     */
 | 
			
		||||
    Command(final String command, final CommandPermission permission) {
 | 
			
		||||
        this.command = command;
 | 
			
		||||
        this.permission = permission;
 | 
			
		||||
        this.alias = command;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param command Command "name" (/plot [cmd])
 | 
			
		||||
     * @param alias   Command Alias
 | 
			
		||||
     */
 | 
			
		||||
    Command(final String command, final String alias) {
 | 
			
		||||
        this.command = command;
 | 
			
		||||
        this.alias = alias;
 | 
			
		||||
        this.permission = new CommandPermission("plots." + command);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param command    Command "name" (/plot [cmd])
 | 
			
		||||
     * @param alias      Command Alias
 | 
			
		||||
     * @param permission Required Permission Node
 | 
			
		||||
     */
 | 
			
		||||
    Command(final String command, final String alias, final CommandPermission permission) {
 | 
			
		||||
        this.command = command;
 | 
			
		||||
        this.alias = alias;
 | 
			
		||||
        this.permission = permission;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return command
 | 
			
		||||
     */
 | 
			
		||||
    public String getCommand() {
 | 
			
		||||
        return this.command;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return alias
 | 
			
		||||
     */
 | 
			
		||||
    public String getAlias() {
 | 
			
		||||
        return this.alias;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return permission object
 | 
			
		||||
     *
 | 
			
		||||
     * @see com.intellectualcrafters.plot.commands.CommandPermission
 | 
			
		||||
     */
 | 
			
		||||
    public CommandPermission getPermission() {
 | 
			
		||||
        return this.permission;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,52 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Citymonstret on 2014-08-03.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 */
 | 
			
		||||
public class CommandPermission {
 | 
			
		||||
    /**
 | 
			
		||||
     * Permission Node
 | 
			
		||||
     */
 | 
			
		||||
    public final String permission;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param permission Command Permission
 | 
			
		||||
     */
 | 
			
		||||
    public CommandPermission(final String permission) {
 | 
			
		||||
        this.permission = permission.toLowerCase();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param player Does the player have the permission?
 | 
			
		||||
     *
 | 
			
		||||
     * @return true of player has the required permission node
 | 
			
		||||
     */
 | 
			
		||||
    public boolean hasPermission(final PlotPlayer player) {
 | 
			
		||||
        return Permissions.hasPermission(player, this.permission);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,84 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.lang.StringUtils;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.comment.CommentInbox;
 | 
			
		||||
import com.intellectualcrafters.plot.object.comment.CommentManager;
 | 
			
		||||
import com.intellectualcrafters.plot.object.comment.PlotComment;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
 | 
			
		||||
public class Comment extends SubCommand {
 | 
			
		||||
    public Comment() {
 | 
			
		||||
        super(Command.COMMENT, "Comment on a plot", "comment", CommandCategory.ACTIONS, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer player, final String... args) {
 | 
			
		||||
        if (args.length < 2) {
 | 
			
		||||
            sendMessage(player, C.COMMENT_SYNTAX, StringUtils.join(CommentManager.inboxes.keySet(),"|"));
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        CommentInbox inbox = CommentManager.inboxes.get(args[0].toLowerCase());
 | 
			
		||||
        if (inbox == null) {
 | 
			
		||||
            sendMessage(player, C.COMMENT_SYNTAX, StringUtils.join(CommentManager.inboxes.keySet(),"|"));
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        Plot plot;
 | 
			
		||||
        Location loc = player.getLocation();
 | 
			
		||||
        PlotId id = PlotId.fromString(args[1]);
 | 
			
		||||
        int index;
 | 
			
		||||
        if (id != null) {
 | 
			
		||||
            if (args.length < 4) {
 | 
			
		||||
                sendMessage(player, C.COMMENT_SYNTAX, StringUtils.join(CommentManager.inboxes.keySet(),"|"));
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            index = 2;
 | 
			
		||||
            plot = MainUtil.getPlot(loc.getWorld(), id);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            index = 1;
 | 
			
		||||
            plot = MainUtil.getPlot(loc);
 | 
			
		||||
        }
 | 
			
		||||
        if (!inbox.canWrite(plot, player)) {
 | 
			
		||||
            sendMessage(player, C.NO_PERM_INBOX, "");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        String message = StringUtils.join(Arrays.copyOfRange(args,index, args.length), " ");
 | 
			
		||||
        PlotComment comment = new PlotComment(loc.getWorld(), id, message, player.getName(), inbox.toString(), System.currentTimeMillis());
 | 
			
		||||
        boolean result = inbox.addComment(plot, comment);
 | 
			
		||||
        if (!result) {
 | 
			
		||||
            sendMessage(player, C.NO_PLOT_INBOX, "");
 | 
			
		||||
            sendMessage(player, C.COMMENT_SYNTAX, StringUtils.join(CommentManager.inboxes.keySet(),"|"));
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        sendMessage(player, C.COMMENT_ADDED);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,206 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.lang.StringUtils;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.BlockManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
 | 
			
		||||
public class Condense extends SubCommand {
 | 
			
		||||
    public static boolean TASK = false;
 | 
			
		||||
 | 
			
		||||
    public Condense() {
 | 
			
		||||
        super("condense", "plots.admin", "Condense a plotworld", "condense", "", CommandCategory.DEBUG, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void sendMessage(final String message) {
 | 
			
		||||
        PS.log("&3PlotSquared -> Plot condense&8: &7" + message);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if (plr != null) {
 | 
			
		||||
            MainUtil.sendMessage(plr, (C.NOT_CONSOLE));
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if ((args.length != 2) && (args.length != 3)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, "/plot condense <world> <start|stop|info> [radius]");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final String worldname = args[0];
 | 
			
		||||
        if (!BlockManager.manager.isWorld(worldname) || !PS.get().isPlotWorld(worldname)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, "INVALID WORLD");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        switch (args[1].toLowerCase()) {
 | 
			
		||||
            case "start": {
 | 
			
		||||
                if (args.length == 2) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, "/plot condense " + worldname + " start <radius>");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (TASK) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, "TASK ALREADY STARTED");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length == 2) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, "/plot condense " + worldname + " start <radius>");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (!StringUtils.isNumeric(args[2])) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, "INVALID RADIUS");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final int radius = Integer.parseInt(args[2]);
 | 
			
		||||
                final Collection<Plot> plots = PS.get().getPlots(worldname).values();
 | 
			
		||||
                final int size = plots.size();
 | 
			
		||||
                final int minimum_radius = (int) Math.ceil((Math.sqrt(size) / 2) + 1);
 | 
			
		||||
                if (radius < minimum_radius) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, "RADIUS TOO SMALL");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final List<PlotId> to_move = new ArrayList<>(getPlots(plots, radius));
 | 
			
		||||
                final List<PlotId> free = new ArrayList<>();
 | 
			
		||||
                PlotId start = new PlotId(0, 0);
 | 
			
		||||
                while ((start.x <= minimum_radius) && (start.y <= minimum_radius)) {
 | 
			
		||||
                    final Plot plot = MainUtil.getPlot(worldname, start);
 | 
			
		||||
                    if (!plot.hasOwner()) {
 | 
			
		||||
                        free.add(plot.id);
 | 
			
		||||
                    }
 | 
			
		||||
                    start = Auto.getNextPlot(start, 1);
 | 
			
		||||
                }
 | 
			
		||||
                if (free.size() == 0 || to_move.size() == 0) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, "NO FREE PLOTS FOUND");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
               MainUtil.move(MainUtil.getPlot(worldname, to_move.get(0)), MainUtil.getPlot(worldname, free.get(0)), new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        if (!TASK) {
 | 
			
		||||
                            sendMessage("CONDENSE TASK CANCELLED");
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                        to_move.remove(0);
 | 
			
		||||
                        free.remove(0);
 | 
			
		||||
                        int index = 0;
 | 
			
		||||
                        for (final PlotId id : to_move) {
 | 
			
		||||
                            final Plot plot = MainUtil.getPlot(worldname, id);
 | 
			
		||||
                            if (plot.hasOwner()) {
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                            index++;
 | 
			
		||||
                        }
 | 
			
		||||
                        for (int i = 0; i < index; i++) {
 | 
			
		||||
                            to_move.remove(0);
 | 
			
		||||
                        }
 | 
			
		||||
                        index = 0;
 | 
			
		||||
                        for (final PlotId id : free) {
 | 
			
		||||
                            final Plot plot = MainUtil.getPlot(worldname, id);
 | 
			
		||||
                            if (!plot.hasOwner()) {
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                            index++;
 | 
			
		||||
                        }
 | 
			
		||||
                        for (int i = 0; i < index; i++) {
 | 
			
		||||
                            free.remove(0);
 | 
			
		||||
                        }
 | 
			
		||||
                        if (to_move.size() == 0) {
 | 
			
		||||
                            sendMessage("TASK COMPLETE. PLEASE VERIFY THAT NO NEW PLOTS HAVE BEEN CLAIMED DURING TASK.");
 | 
			
		||||
                            TASK = false;
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                        if (free.size() == 0) {
 | 
			
		||||
                            sendMessage("TASK FAILED. NO FREE PLOTS FOUND!");
 | 
			
		||||
                            TASK = false;
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                        sendMessage("MOVING " + to_move.get(0) + " to " + free.get(0));
 | 
			
		||||
                        MainUtil.move(MainUtil.getPlot(worldname, to_move.get(0)), MainUtil.getPlot(worldname, free.get(0)), this);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
                TASK = true;
 | 
			
		||||
                MainUtil.sendMessage(plr, "TASK STARTED...");
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "stop": {
 | 
			
		||||
                if (!TASK) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, "TASK ALREADY STOPPED");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                TASK = false;
 | 
			
		||||
                MainUtil.sendMessage(plr, "TASK STOPPED");
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "info": {
 | 
			
		||||
                if (args.length == 2) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, "/plot condense " + worldname + " info <radius>");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (!StringUtils.isNumeric(args[2])) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, "INVALID RADIUS");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final int radius = Integer.parseInt(args[2]);
 | 
			
		||||
                final Collection<Plot> plots = PS.get().getPlots(worldname).values();
 | 
			
		||||
                final int size = plots.size();
 | 
			
		||||
                final int minimum_radius = (int) Math.ceil((Math.sqrt(size) / 2) + 1);
 | 
			
		||||
                if (radius < minimum_radius) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, "RADIUS TOO SMALL");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final int max_move = getPlots(plots, minimum_radius).size();
 | 
			
		||||
                final int user_move = getPlots(plots, radius).size();
 | 
			
		||||
                MainUtil.sendMessage(plr, "=== DEFAULT EVAL ===");
 | 
			
		||||
                MainUtil.sendMessage(plr, "MINIMUM RADIUS: " + minimum_radius);
 | 
			
		||||
                MainUtil.sendMessage(plr, "MAXIMUM MOVES: " + max_move);
 | 
			
		||||
                MainUtil.sendMessage(plr, "=== INPUT EVAL ===");
 | 
			
		||||
                MainUtil.sendMessage(plr, "INPUT RADIUS: " + radius);
 | 
			
		||||
                MainUtil.sendMessage(plr, "ESTIMATED MOVES: " + user_move);
 | 
			
		||||
                MainUtil.sendMessage(plr, "ESTIMATED TIME: " + "No idea, times will drastically change based on the system performance and load");
 | 
			
		||||
                MainUtil.sendMessage(plr, "&e - Radius is measured in plot width");
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.sendMessage(plr, "/plot condense " + worldname + " <start|stop|info> [radius]");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Set<PlotId> getPlots(final Collection<Plot> plots, final int radius) {
 | 
			
		||||
        final HashSet<PlotId> outside = new HashSet<>();
 | 
			
		||||
        for (final Plot plot : plots) {
 | 
			
		||||
            if ((plot.id.x > radius) || (plot.id.x < -radius) || (plot.id.y > radius) || (plot.id.y < -radius)) {
 | 
			
		||||
                outside.add(plot.id);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return outside;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,53 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.CmdInstance;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.CmdConfirm;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 */
 | 
			
		||||
public class Confirm extends SubCommand {
 | 
			
		||||
    public Confirm() {
 | 
			
		||||
        super("confirm", "plots.use", "Confirm an action", "confirm", "confirm", CommandCategory.ACTIONS, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
    	CmdInstance command = CmdConfirm.getPending(plr);
 | 
			
		||||
    	if (command == null) {
 | 
			
		||||
    		MainUtil.sendMessage(plr, C.FAILED_CONFIRM);
 | 
			
		||||
    		return false;
 | 
			
		||||
    	}
 | 
			
		||||
    	CmdConfirm.removePending(plr);
 | 
			
		||||
    	if (System.currentTimeMillis() - command.timestamp > 20000) {
 | 
			
		||||
    	    MainUtil.sendMessage(plr, C.FAILED_CONFIRM);
 | 
			
		||||
    	    return false;
 | 
			
		||||
    	}
 | 
			
		||||
    	TaskManager.runTask(command.command);
 | 
			
		||||
    	return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,81 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created 2014-08-01 for PlotSquared
 | 
			
		||||
 *
 | 
			
		||||
 * @author Empire92
 | 
			
		||||
 */
 | 
			
		||||
public class Copy extends SubCommand {
 | 
			
		||||
    public Copy() {
 | 
			
		||||
        super("copy", "plots.copy", "Copy a plot", "copypaste", "", CommandCategory.ACTIONS, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if (args.length < 1) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NEED_PLOT_ID);
 | 
			
		||||
            MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot copy <X;Z>");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final Location loc = plr.getLocation();
 | 
			
		||||
        final Plot plot1 = MainUtil.getPlot(loc);
 | 
			
		||||
        if (plot1 == null) {
 | 
			
		||||
            return !MainUtil.sendMessage(plr, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        if (!plot1.isAdded(plr.getUUID()) && !plr.hasPermission(Permissions.ADMIN.s))  {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NO_PLOT_PERMS);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final String world = loc.getWorld();
 | 
			
		||||
        final PlotId plot2 = MainUtil.parseId(args[0]);
 | 
			
		||||
        if ((plot2 == null)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_ID);
 | 
			
		||||
            MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot copy <X;Z>");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (plot1.id.equals(plot2)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_ID);
 | 
			
		||||
            MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot copy <X;Z>");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (MainUtil.copy(world, plot1.id, plot2, new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                MainUtil.sendMessage(plr, C.COPY_SUCCESS);
 | 
			
		||||
            }
 | 
			
		||||
        })) {
 | 
			
		||||
            return true;
 | 
			
		||||
        } else {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.REQUIRES_UNOWNED);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,51 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridPlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
 | 
			
		||||
public class CreateRoadSchematic extends SubCommand {
 | 
			
		||||
    public CreateRoadSchematic() {
 | 
			
		||||
        super(Command.CREATEROADSCHEMATIC, "Add a road schematic to your world using the road around your current plot", "crs", CommandCategory.DEBUG, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer player, final String... args) {
 | 
			
		||||
        final Location loc = player.getLocation();
 | 
			
		||||
        final Plot plot = MainUtil.getPlot(loc);
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            return sendMessage(player, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        if (!(PS.get().getPlotWorld(loc.getWorld()) instanceof HybridPlotWorld)) {
 | 
			
		||||
            return sendMessage(player, C.NOT_IN_PLOT_WORLD);
 | 
			
		||||
        }
 | 
			
		||||
        HybridUtils.manager.setupRoadSchematic(plot);
 | 
			
		||||
        MainUtil.sendMessage(player, "&6Saved new road schematic");
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,137 @@
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.database.MySQL;
 | 
			
		||||
import com.intellectualcrafters.plot.database.SQLManager;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.StringComparison;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created 2014-11-15 for PlotSquared
 | 
			
		||||
 *
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 */
 | 
			
		||||
public class Database extends SubCommand {
 | 
			
		||||
    public Database() {
 | 
			
		||||
        super(Command.DATABASE, "Convert/Backup Storage", "database [type] [...details]", CommandCategory.DEBUG, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static boolean sendMessageU(final UUID uuid, final String msg) {
 | 
			
		||||
        if (uuid == null) {
 | 
			
		||||
            PS.log(msg);
 | 
			
		||||
        } else {
 | 
			
		||||
            final PlotPlayer p = UUIDHandler.getPlayer(uuid);
 | 
			
		||||
            if ((p != null) && p.isOnline()) {
 | 
			
		||||
                return MainUtil.sendMessage(p, msg);
 | 
			
		||||
            } else {
 | 
			
		||||
                return sendMessageU(null, msg);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void insertPlots(final SQLManager manager, final UUID requester, final Connection c) {
 | 
			
		||||
        final java.util.Set<Plot> plots = PS.get().getPlots();
 | 
			
		||||
        TaskManager.runTaskAsync(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                try {
 | 
			
		||||
                    final ArrayList<Plot> ps = new ArrayList<>();
 | 
			
		||||
                    for (final Plot p : plots) {
 | 
			
		||||
                        ps.add(p);
 | 
			
		||||
                    }
 | 
			
		||||
                    sendMessageU(requester, "&6Starting...");
 | 
			
		||||
                    manager.createPlotsAndData(ps, new Runnable() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            sendMessageU(requester, "&6Database conversion finished!");
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                } catch (final Exception e) {
 | 
			
		||||
                    sendMessageU(requester, "Failed to insert plot objects, see stacktrace for info");
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
                try {
 | 
			
		||||
                    c.close();
 | 
			
		||||
                } catch (final SQLException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if (args.length < 1) {
 | 
			
		||||
            return sendMessage(plr, "/plot database [sqlite/mysql]");
 | 
			
		||||
        }
 | 
			
		||||
        final String type = new StringComparison(args[0], new String[] { "mysql", "sqlite" }).getBestMatch().toLowerCase();
 | 
			
		||||
        switch (type) {
 | 
			
		||||
            case "mysql":
 | 
			
		||||
                if (args.length < 6) {
 | 
			
		||||
                    return sendMessage(plr, "/plot database mysql [host] [port] [username] [password] [database] {prefix}");
 | 
			
		||||
                }
 | 
			
		||||
                final String host = args[1];
 | 
			
		||||
                final String port = args[2];
 | 
			
		||||
                final String username = args[3];
 | 
			
		||||
                final String password = args[4];
 | 
			
		||||
                final String database = args[5];
 | 
			
		||||
                String prefix = "";
 | 
			
		||||
                if (args.length > 6) {
 | 
			
		||||
                    prefix = args[6];
 | 
			
		||||
                }
 | 
			
		||||
                Connection n;
 | 
			
		||||
                try {
 | 
			
		||||
                    n = new MySQL(host, port, database, username, password).openConnection();
 | 
			
		||||
                    // Connection
 | 
			
		||||
                    if (n.isClosed()) {
 | 
			
		||||
                        return sendMessage(plr, "Failed to open connection");
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (SQLException | ClassNotFoundException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                    return sendMessage(plr, "Failed to open connection, read stacktrace for info");
 | 
			
		||||
                }
 | 
			
		||||
                final SQLManager manager = new SQLManager(n, prefix);
 | 
			
		||||
                try {
 | 
			
		||||
                    manager.createTables("mysql");
 | 
			
		||||
                } catch (final SQLException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                    return sendMessage(plr, "Could not create the required tables and/or load the database") && sendMessage(plr, "Please see the stacktrace for more information");
 | 
			
		||||
                }
 | 
			
		||||
                UUID requester = null;
 | 
			
		||||
                if (plr != null) {
 | 
			
		||||
                    requester = UUIDHandler.getUUID(plr);
 | 
			
		||||
                }
 | 
			
		||||
                insertPlots(manager, requester, n);
 | 
			
		||||
                break;
 | 
			
		||||
            case "sqlite":
 | 
			
		||||
                if (args.length < 2) {
 | 
			
		||||
                    return sendMessage(plr, "/plot database sqlite [file name]");
 | 
			
		||||
                }
 | 
			
		||||
                sendMessage(plr, "This is not supported yet");
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                return sendMessage(plr, "Unknown database type");
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean sendMessage(final PlotPlayer player, final String msg) {
 | 
			
		||||
        if (player == null) {
 | 
			
		||||
            PS.log(msg);
 | 
			
		||||
        } else {
 | 
			
		||||
            MainUtil.sendMessage(player, msg);
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,82 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Lag;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
 | 
			
		||||
public class Debug extends SubCommand {
 | 
			
		||||
    public Debug() {
 | 
			
		||||
        super(Command.DEBUG, "Show debug information", "debug [msg]", CommandCategory.DEBUG, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if ((args.length > 0) && args[0].equalsIgnoreCase("msg")) {
 | 
			
		||||
            final StringBuilder msg = new StringBuilder();
 | 
			
		||||
            for (final C c : C.values()) {
 | 
			
		||||
                msg.append(c.s()).append("\n");
 | 
			
		||||
            }
 | 
			
		||||
            MainUtil.sendMessage(plr, msg.toString());
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        StringBuilder information;
 | 
			
		||||
        String header, line, section;
 | 
			
		||||
        {
 | 
			
		||||
            information = new StringBuilder();
 | 
			
		||||
            header = C.DEBUG_HEADER.s();
 | 
			
		||||
            line = C.DEBUG_LINE.s();
 | 
			
		||||
            section = C.DEBUG_SECTION.s();
 | 
			
		||||
        }
 | 
			
		||||
        {
 | 
			
		||||
            final StringBuilder worlds = new StringBuilder("");
 | 
			
		||||
            for (final String world : PS.get().getPlotWorlds()) {
 | 
			
		||||
                worlds.append(world).append(" ");
 | 
			
		||||
            }
 | 
			
		||||
            information.append(header);
 | 
			
		||||
            information.append(getSection(section, "Lag / TPS"));
 | 
			
		||||
            information.append(getLine(line, "Ticks Per Second", Lag.getTPS()));
 | 
			
		||||
            information.append(getLine(line, "Lag Percentage", (int) Lag.getPercentage() + "%"));
 | 
			
		||||
            information.append(getLine(line, "TPS Percentage", (int) Lag.getFullPercentage() + "%"));
 | 
			
		||||
            information.append(getSection(section, "PlotWorld"));
 | 
			
		||||
            information.append(getLine(line, "Plot Worlds", worlds));
 | 
			
		||||
            information.append(getLine(line, "Owned Plots", PS.get().getPlots().size()));
 | 
			
		||||
            information.append(getSection(section, "Messages"));
 | 
			
		||||
            information.append(getLine(line, "Total Messages", C.values().length));
 | 
			
		||||
            information.append(getLine(line, "View all captions", "/plot debug msg"));
 | 
			
		||||
        }
 | 
			
		||||
        {
 | 
			
		||||
            MainUtil.sendMessage(plr, information.toString());
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String getSection(final String line, final String val) {
 | 
			
		||||
        return line.replaceAll("%val%", val) + "\n";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String getLine(final String line, final String var, final Object val) {
 | 
			
		||||
        return line.replaceAll("%var%", var).replaceAll("%val%", "" + val) + "\n";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.Flag;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.FlagManager;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.BlockManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
public class DebugAllowUnsafe extends SubCommand {
 | 
			
		||||
 | 
			
		||||
    public static final List<UUID> unsafeAllowed = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    public DebugAllowUnsafe() {
 | 
			
		||||
        super(Command.ALLOWUNSAFE, "Allow unsafe actions until toggled off", "allowunsafe", CommandCategory.DEBUG, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if (plr == null) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.IS_CONSOLE);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (unsafeAllowed.contains(plr.getUUID())) {
 | 
			
		||||
            unsafeAllowed.remove(plr.getUUID());
 | 
			
		||||
            sendMessage(plr, C.DEBUGALLOWUNSAFE_OFF);
 | 
			
		||||
        } else {
 | 
			
		||||
            unsafeAllowed.add(plr.getUUID());
 | 
			
		||||
            sendMessage(plr, C.DEBUGALLOWUNSAFE_ON);
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,155 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.BiMap;
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.ChunkLoc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotManager;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.object.StringWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.util.BlockManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ChunkManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EventUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 */
 | 
			
		||||
public class DebugClaimTest extends SubCommand {
 | 
			
		||||
    public DebugClaimTest() {
 | 
			
		||||
        super(Command.DEBUGCLAIMTEST, "If you accidentally delete your database, this command will attempt to restore all plots based on the data from the plot signs. Execution time may vary", "debugclaimtest", CommandCategory.DEBUG, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean claimPlot(final PlotPlayer player, final Plot plot, final boolean teleport) {
 | 
			
		||||
        return claimPlot(player, plot, teleport, "");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean claimPlot(final PlotPlayer player, final Plot plot, final boolean teleport, final String schematic) {
 | 
			
		||||
        final boolean result = EventUtil.manager.callClaim(player, plot, false);
 | 
			
		||||
        if (result) {
 | 
			
		||||
            MainUtil.createPlot(player.getUUID(), plot);
 | 
			
		||||
            MainUtil.setSign(player.getName(), plot);
 | 
			
		||||
            MainUtil.sendMessage(player, C.CLAIMED);
 | 
			
		||||
            if (teleport) {
 | 
			
		||||
                MainUtil.teleportPlayer(player, player.getLocation(), plot);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return !result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if (plr == null) {
 | 
			
		||||
            if (args.length < 3) {
 | 
			
		||||
                return !MainUtil.sendMessage(null, "If you accidentally delete your database, this command will attempt to restore all plots based on the data from the plot signs. \n\n&cMissing world arg /plot debugclaimtest {world} {PlotId min} {PlotId max}");
 | 
			
		||||
            }
 | 
			
		||||
            final String world = args[0];
 | 
			
		||||
            if (!BlockManager.manager.isWorld(world) || !PS.get().isPlotWorld(world)) {
 | 
			
		||||
                return !MainUtil.sendMessage(null, "&cInvalid plot world!");
 | 
			
		||||
            }
 | 
			
		||||
            PlotId min, max;
 | 
			
		||||
            try {
 | 
			
		||||
                final String[] split1 = args[1].split(";");
 | 
			
		||||
                final String[] split2 = args[2].split(";");
 | 
			
		||||
                min = new PlotId(Integer.parseInt(split1[0]), Integer.parseInt(split1[1]));
 | 
			
		||||
                max = new PlotId(Integer.parseInt(split2[0]), Integer.parseInt(split2[1]));
 | 
			
		||||
            } catch (final Exception e) {
 | 
			
		||||
                return !MainUtil.sendMessage(null, "&cInvalid min/max values. &7The values are to Plot IDs in the format &cX;Y &7where X,Y are the plot coords\nThe conversion will only check the plots in the selected area.");
 | 
			
		||||
            }
 | 
			
		||||
            MainUtil.sendMessage(null, "&3Sign Block&8->&3PlotSquared&8: &7Beginning sign to plot conversion. This may take a while...");
 | 
			
		||||
            MainUtil.sendMessage(null, "&3Sign Block&8->&3PlotSquared&8: Found an excess of 250,000 chunks. Limiting search radius... (~3.8 min)");
 | 
			
		||||
            final PlotManager manager = PS.get().getPlotManager(world);
 | 
			
		||||
            final PlotWorld plotworld = PS.get().getPlotWorld(world);
 | 
			
		||||
            final ArrayList<Plot> plots = new ArrayList<>();
 | 
			
		||||
            for (final PlotId id : MainUtil.getPlotSelectionIds(min, max)) {
 | 
			
		||||
                final Plot plot = MainUtil.getPlot(world, id);
 | 
			
		||||
                final boolean contains = PS.get().getPlots(world).containsKey(plot.id);
 | 
			
		||||
                if (contains) {
 | 
			
		||||
                    MainUtil.sendMessage(null, " - &cDB Already contains: " + plot.id);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                final Location loc = manager.getSignLoc(plotworld, plot);
 | 
			
		||||
                final ChunkLoc chunk = new ChunkLoc(loc.getX() >> 4, loc.getZ() >> 4);
 | 
			
		||||
                final boolean result = ChunkManager.manager.loadChunk(world, chunk);
 | 
			
		||||
                if (!result) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                final String[] lines = BlockManager.manager.getSign(loc);
 | 
			
		||||
                if (lines != null) {
 | 
			
		||||
                    String line = lines[2];
 | 
			
		||||
                    if ((line != null) && (line.length() > 2)) {
 | 
			
		||||
                        line = line.substring(2);
 | 
			
		||||
                        final BiMap<StringWrapper, UUID> map = UUIDHandler.getUuidMap();
 | 
			
		||||
                        UUID uuid = (map.get(new StringWrapper(line)));
 | 
			
		||||
                        if (uuid == null) {
 | 
			
		||||
                            for (final StringWrapper string : map.keySet()) {
 | 
			
		||||
                                if (string.value.toLowerCase().startsWith(line.toLowerCase())) {
 | 
			
		||||
                                    uuid = map.get(string);
 | 
			
		||||
                                    break;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        if (uuid == null) {
 | 
			
		||||
                            uuid = UUIDHandler.getUUID(line);
 | 
			
		||||
                        }
 | 
			
		||||
                        if (uuid != null) {
 | 
			
		||||
                            MainUtil.sendMessage(null, " - &aFound plot: " + plot.id + " : " + line);
 | 
			
		||||
                            plot.owner = uuid;
 | 
			
		||||
                            plot.hasChanged = true;
 | 
			
		||||
                            plots.add(plot);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            MainUtil.sendMessage(null, " - &cInvalid playername: " + plot.id + " : " + line);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (plots.size() > 0) {
 | 
			
		||||
                MainUtil.sendMessage(null, "&3Sign Block&8->&3PlotSquared&8: &7Updating '" + plots.size() + "' plots!");
 | 
			
		||||
                DBFunc.createPlotsAndData(plots, new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        MainUtil.sendMessage(null, "&6Database update finished!");
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
                for (final Plot plot : plots) {
 | 
			
		||||
                    PS.get().updatePlot(plot);
 | 
			
		||||
                }
 | 
			
		||||
                MainUtil.sendMessage(null, "&3Sign Block&8->&3PlotSquared&8: &7Complete!");
 | 
			
		||||
            } else {
 | 
			
		||||
                MainUtil.sendMessage(null, "No plots were found for the given search.");
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            MainUtil.sendMessage(plr, "&6This command can only be executed by console as it has been deemed unsafe if abused.");
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,110 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.SquarePlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ChunkManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
 | 
			
		||||
public class DebugClear extends SubCommand {
 | 
			
		||||
    public DebugClear() {
 | 
			
		||||
        super(Command.DEBUGCLEAR, "Clear a plot using a fast experimental algorithm", "debugclear", CommandCategory.DEBUG, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if (plr == null) {
 | 
			
		||||
            // Is console
 | 
			
		||||
            if (args.length < 2) {
 | 
			
		||||
                PS.log("You need to specify two arguments: ID (0;0) & World (world)");
 | 
			
		||||
            } else {
 | 
			
		||||
                final PlotId id = PlotId.fromString(args[0]);
 | 
			
		||||
                final String world = args[1];
 | 
			
		||||
                if (id == null) {
 | 
			
		||||
                    PS.log("Invalid Plot ID: " + args[0]);
 | 
			
		||||
                } else {
 | 
			
		||||
                    if (!PS.get().isPlotWorld(world) || !(PS.get().getPlotWorld(world) instanceof SquarePlotWorld)) {
 | 
			
		||||
                        PS.log("Invalid plot world: " + world);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        final Plot plot = MainUtil.getPlot(world, id);
 | 
			
		||||
                        if (plot == null) {
 | 
			
		||||
                            PS.log("Could not find plot " + args[0] + " in world " + world);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            final Location pos1 = MainUtil.getPlotBottomLoc(world, plot.id).add(1, 0, 1);
 | 
			
		||||
                            final Location pos2 = MainUtil.getPlotTopLoc(world, plot.id);
 | 
			
		||||
                            if (MainUtil.runners.containsKey(plot)) {
 | 
			
		||||
                                MainUtil.sendMessage(null, C.WAIT_FOR_TIMER);
 | 
			
		||||
                                return false;
 | 
			
		||||
                            }
 | 
			
		||||
                            MainUtil.runners.put(plot, 1);
 | 
			
		||||
                            ChunkManager.manager.regenerateRegion(pos1, pos2, new Runnable() {
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void run() {
 | 
			
		||||
                                    MainUtil.runners.remove(plot);
 | 
			
		||||
                                    PS.log("Plot " + plot.getId().toString() + " cleared.");
 | 
			
		||||
                                    PS.log("&aDone!");
 | 
			
		||||
                                }
 | 
			
		||||
                            });
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        final Location loc = plr.getLocation();
 | 
			
		||||
        final Plot plot = MainUtil.getPlot(loc);
 | 
			
		||||
        if ((plot == null) || !(PS.get().getPlotWorld(loc.getWorld()) instanceof SquarePlotWorld)) {
 | 
			
		||||
            return sendMessage(plr, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        if (!MainUtil.getTopPlot(plot).equals(MainUtil.getBottomPlot(plot))) {
 | 
			
		||||
            return sendMessage(plr, C.UNLINK_REQUIRED);
 | 
			
		||||
        }
 | 
			
		||||
        if (((plot == null) || !plot.hasOwner() || !plot.isOwner(UUIDHandler.getUUID(plr))) && !Permissions.hasPermission(plr, "plots.admin.command.debugclear")) {
 | 
			
		||||
            return sendMessage(plr, C.NO_PLOT_PERMS);
 | 
			
		||||
        }
 | 
			
		||||
        assert plot != null;
 | 
			
		||||
        final Location pos1 = MainUtil.getPlotBottomLoc(loc.getWorld(), plot.id).add(1, 0, 1);
 | 
			
		||||
        final Location pos2 = MainUtil.getPlotTopLoc(loc.getWorld(), plot.id);
 | 
			
		||||
        if (MainUtil.runners.containsKey(plot)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.runners.put(plot, 1);
 | 
			
		||||
        ChunkManager.manager.regenerateRegion(pos1, pos2, new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                MainUtil.runners.remove(plot);
 | 
			
		||||
                MainUtil.sendMessage(plr, "&aDone!");
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        // sign
 | 
			
		||||
        // wall
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,250 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.PrintWriter;
 | 
			
		||||
import java.sql.Timestamp;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.lang.StringUtils;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.Flag;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.FlagManager;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.BukkitHybridUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.object.ChunkLoc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotAnalysis;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RunnableVal;
 | 
			
		||||
import com.intellectualcrafters.plot.util.BlockManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ChunkManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ExpireManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
 | 
			
		||||
public class DebugExec extends SubCommand {
 | 
			
		||||
    public DebugExec() {
 | 
			
		||||
        super("debugexec", "plots.admin", "Multi-purpose debug command", "debugexec", "exec", CommandCategory.DEBUG, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer player, final String... args) {
 | 
			
		||||
        final List<String> allowed_params = Arrays.asList("analyze", "reset-modified", "stop-expire", "start-expire", "show-expired", "update-expired", "seen", "trim-check");
 | 
			
		||||
        if (args.length > 0) {
 | 
			
		||||
            final String arg = args[0].toLowerCase();
 | 
			
		||||
            switch (arg) {
 | 
			
		||||
                case "analyze": {
 | 
			
		||||
                    final Plot plot = MainUtil.getPlot(player.getLocation());
 | 
			
		||||
                    HybridUtils.manager.analyzePlot(plot, new RunnableVal<PlotAnalysis>() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            List<Double> result = new ArrayList<>();
 | 
			
		||||
                            result.add(Math.round(value.air * 100) / 100d);
 | 
			
		||||
                            result.add(Math.round(value.changes * 100) / 100d);
 | 
			
		||||
                            result.add(Math.round(value.complexity * 100) / 100d);
 | 
			
		||||
                            result.add(Math.round(value.data * 100) / 100d);
 | 
			
		||||
                            result.add(Math.round(value.faces * 100) / 100d);
 | 
			
		||||
                            result.add(Math.round(value.air * 100) / 100d);
 | 
			
		||||
                            result.add(Math.round(value.variety * 100) / 100d);
 | 
			
		||||
                            Flag flag = new Flag(FlagManager.getFlag("analysis"), result);
 | 
			
		||||
                            FlagManager.addPlotFlag(plot, flag);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                case "stop-expire": {
 | 
			
		||||
                    if (ExpireManager.task != -1) {
 | 
			
		||||
                        Bukkit.getScheduler().cancelTask(ExpireManager.task);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return MainUtil.sendMessage(player, "Task already halted");
 | 
			
		||||
                    }
 | 
			
		||||
                    ExpireManager.task = -1;
 | 
			
		||||
                    return MainUtil.sendMessage(player, "Cancelled task.");
 | 
			
		||||
                }
 | 
			
		||||
                case "remove-flag": {
 | 
			
		||||
                    if (args.length != 2) {
 | 
			
		||||
                        MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot debugexec remove-flag <flag>");
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    String flag = args[1];
 | 
			
		||||
                    for (Plot plot : PS.get().getPlots()) {
 | 
			
		||||
                        if (FlagManager.getPlotFlag(plot, flag) != null) {
 | 
			
		||||
                            FlagManager.removePlotFlag(plot, flag);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    return MainUtil.sendMessage(player, "Cleared flag: " + flag);    
 | 
			
		||||
                }
 | 
			
		||||
                case "start-rgar": {
 | 
			
		||||
                    if (args.length != 2) {
 | 
			
		||||
                        PS.log("&cInvalid syntax: /plot debugexec start-rgar <world>");
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    boolean result;
 | 
			
		||||
                    if (!PS.get().isPlotWorld(args[1])) {
 | 
			
		||||
                        MainUtil.sendMessage(player, C.NOT_VALID_PLOT_WORLD, args[1]);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (BukkitHybridUtils.regions != null) {
 | 
			
		||||
                        result = ((BukkitHybridUtils)(HybridUtils.manager)).scheduleRoadUpdate(args[1], BukkitHybridUtils.regions, 0);
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        result = HybridUtils.manager.scheduleRoadUpdate(args[1], 0);
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!result) {
 | 
			
		||||
                        PS.log("&cCannot schedule mass schematic update! (Is one already in progress?)");
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                case "stop-rgar": {
 | 
			
		||||
                    if (((BukkitHybridUtils)(HybridUtils.manager)).task == 0) {
 | 
			
		||||
                        PS.log("&cTASK NOT RUNNING!");
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    ((BukkitHybridUtils)(HybridUtils.manager)).task = 0;
 | 
			
		||||
                    Bukkit.getScheduler().cancelTask(((BukkitHybridUtils)(HybridUtils.manager)).task);
 | 
			
		||||
                    PS.log("&cCancelling task...");
 | 
			
		||||
                    while (BukkitHybridUtils.chunks.size() > 0) {
 | 
			
		||||
                        ChunkLoc chunk = BukkitHybridUtils.chunks.get(0);
 | 
			
		||||
                        BukkitHybridUtils.chunks.remove(0);
 | 
			
		||||
                        HybridUtils.manager.regenerateRoad(BukkitHybridUtils.world, chunk, 0);
 | 
			
		||||
                        ChunkManager.manager.unloadChunk(BukkitHybridUtils.world, chunk);
 | 
			
		||||
                    }
 | 
			
		||||
                    PS.log("&cCancelled!");
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                case "start-expire": {
 | 
			
		||||
                    if (ExpireManager.task == -1) {
 | 
			
		||||
                        ExpireManager.runTask();
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return MainUtil.sendMessage(player, "Plot expiry task already started");
 | 
			
		||||
                    }
 | 
			
		||||
                    return MainUtil.sendMessage(player, "Started plot expiry task");
 | 
			
		||||
                }
 | 
			
		||||
                case "update-expired": {
 | 
			
		||||
                    if (args.length > 1) {
 | 
			
		||||
                        final String world = args[1];
 | 
			
		||||
                        if (!BlockManager.manager.isWorld(world)) {
 | 
			
		||||
                            return MainUtil.sendMessage(player, "Invalid world: " + args[1]);
 | 
			
		||||
                        }
 | 
			
		||||
                        MainUtil.sendMessage(player, "Updating expired plot list");
 | 
			
		||||
                        ExpireManager.updateExpired(args[1]);
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    return MainUtil.sendMessage(player, "Use /plot debugexec update-expired <world>");
 | 
			
		||||
                }
 | 
			
		||||
                case "show-expired": {
 | 
			
		||||
                    if (args.length > 1) {
 | 
			
		||||
                        final String world = args[1];
 | 
			
		||||
                        if (!BlockManager.manager.isWorld(world)) {
 | 
			
		||||
                            return MainUtil.sendMessage(player, "Invalid world: " + args[1]);
 | 
			
		||||
                        }
 | 
			
		||||
                        if (!ExpireManager.expiredPlots.containsKey(args[1])) {
 | 
			
		||||
                            return MainUtil.sendMessage(player, "No task for world: " + args[1]);
 | 
			
		||||
                        }
 | 
			
		||||
                        MainUtil.sendMessage(player, "Expired plots (" + ExpireManager.expiredPlots.get(args[1]).size() + "):");
 | 
			
		||||
                        for (final Plot plot : ExpireManager.expiredPlots.get(args[1])) {
 | 
			
		||||
                            MainUtil.sendMessage(player, " - " + plot.world + ";" + plot.id.x + ";" + plot.id.y + ";" + UUIDHandler.getName(plot.owner) + " : " + ExpireManager.dates.get(plot.owner));
 | 
			
		||||
                        }
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    return MainUtil.sendMessage(player, "Use /plot debugexec show-expired <world>");
 | 
			
		||||
                }
 | 
			
		||||
                case "seen": {
 | 
			
		||||
                    if (args.length != 2) {
 | 
			
		||||
                        return MainUtil.sendMessage(player, "Use /plot debugexec seen <player>");
 | 
			
		||||
                    }
 | 
			
		||||
                    final UUID uuid = UUIDHandler.getUUID(args[1]);
 | 
			
		||||
                    if (uuid == null) {
 | 
			
		||||
                        return MainUtil.sendMessage(player, "player not found: " + args[1]);
 | 
			
		||||
                    }
 | 
			
		||||
                    final OfflinePlotPlayer op = UUIDHandler.uuidWrapper.getOfflinePlayer(uuid);
 | 
			
		||||
                    if ((op == null) || (op.getLastPlayed() == 0)) {
 | 
			
		||||
                        return MainUtil.sendMessage(player, "player hasn't connected before: " + args[1]);
 | 
			
		||||
                    }
 | 
			
		||||
                    final Timestamp stamp = new Timestamp(op.getLastPlayed());
 | 
			
		||||
                    final Date date = new Date(stamp.getTime());
 | 
			
		||||
                    MainUtil.sendMessage(player, "PLAYER: " + args[1]);
 | 
			
		||||
                    MainUtil.sendMessage(player, "UUID: " + uuid);
 | 
			
		||||
                    MainUtil.sendMessage(player, "Object: " + date.toGMTString());
 | 
			
		||||
                    MainUtil.sendMessage(player, "GMT: " + date.toGMTString());
 | 
			
		||||
                    MainUtil.sendMessage(player, "Local: " + date.toLocaleString());
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                case "trim-check": {
 | 
			
		||||
                    if (args.length != 2) {
 | 
			
		||||
                        MainUtil.sendMessage(player, "Use /plot debugexec trim-check <world>");
 | 
			
		||||
                        MainUtil.sendMessage(player, "&7 - Generates a list of regions to trim");
 | 
			
		||||
                        return MainUtil.sendMessage(player, "&7 - Run after plot expiry has run");
 | 
			
		||||
                    }
 | 
			
		||||
                    final String world = args[1];
 | 
			
		||||
                    if (!BlockManager.manager.isWorld(world) || !PS.get().isPlotWorld(args[1])) {
 | 
			
		||||
                        return MainUtil.sendMessage(player, "Invalid world: " + args[1]);
 | 
			
		||||
                    }
 | 
			
		||||
                    final ArrayList<ChunkLoc> empty = new ArrayList<>();
 | 
			
		||||
                    final boolean result = Trim.getTrimRegions(empty, world, new Runnable() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            Trim.sendMessage("Processing is complete! Here's how many chunks would be deleted:");
 | 
			
		||||
                            Trim.sendMessage(" - MCA #: " + empty.size());
 | 
			
		||||
                            Trim.sendMessage(" - CHUNKS: " + (empty.size() * 1024) + " (max)");
 | 
			
		||||
                            Trim.sendMessage("Exporting log for manual approval...");
 | 
			
		||||
                            final File file = new File(PS.get().IMP.getDirectory() + File.separator + "trim.txt");
 | 
			
		||||
                            PrintWriter writer;
 | 
			
		||||
                            try {
 | 
			
		||||
                                writer = new PrintWriter(file);
 | 
			
		||||
                                for (final ChunkLoc loc : empty) {
 | 
			
		||||
                                    writer.println(world + "/region/r." + loc.x + "." + loc.z + ".mca");
 | 
			
		||||
                                }
 | 
			
		||||
                                writer.close();
 | 
			
		||||
                                Trim.sendMessage("File saved to 'plugins/PlotSquared/trim.txt'");
 | 
			
		||||
                            } catch (final FileNotFoundException e) {
 | 
			
		||||
                                e.printStackTrace();
 | 
			
		||||
                                Trim.sendMessage("File failed to save! :(");
 | 
			
		||||
                            }
 | 
			
		||||
                            Trim.sendMessage("How to get the chunk coords from a region file:");
 | 
			
		||||
                            Trim.sendMessage(" - Locate the x,z values for the region file (the two numbers which are separated by a dot)");
 | 
			
		||||
                            Trim.sendMessage(" - Multiply each number by 32; this gives you the starting position");
 | 
			
		||||
                            Trim.sendMessage(" - Add 31 to each number to get the end position");
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                    if (!result) {
 | 
			
		||||
                        MainUtil.sendMessage(player, "Trim task already started!");
 | 
			
		||||
                    }
 | 
			
		||||
                    return result;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.sendMessage(player, "Possible sub commands: /plot debugexec <" + StringUtils.join(allowed_params, "|") + ">");
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,162 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotBlock;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.intellectualcrafters.plot.util.SetBlockQueue;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
 | 
			
		||||
public class DebugFill extends SubCommand {
 | 
			
		||||
    public DebugFill() {
 | 
			
		||||
        super("fill", "plots.fill", "Fill or surround a plot in bedrock", "fill", "debugfill", CommandCategory.DEBUG, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer player, final String... args) {
 | 
			
		||||
        if (args.length != 1 || (!args[0].equalsIgnoreCase("outline") && !args[0].equalsIgnoreCase("all"))) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot fill <outline|all>");
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        final Location loc = player.getLocation();
 | 
			
		||||
        final Plot plot = MainUtil.getPlot(loc);
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            return !sendMessage(player, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        if ((plot == null) || !plot.hasOwner()) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.PLOT_UNOWNED);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (!plot.isOwner(player.getUUID()) && !Permissions.hasPermission(player, "plots.admin.command.fill")) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.NO_PLOT_PERMS);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        if (MainUtil.runners.containsKey(plot)) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.WAIT_FOR_TIMER);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final Location bottom = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1);
 | 
			
		||||
        final Location top = MainUtil.getPlotTopLoc(plot.world, plot.id);
 | 
			
		||||
        MainUtil.sendMessage(player, "&cPreparing task");
 | 
			
		||||
        MainUtil.runners.put(plot, 1);
 | 
			
		||||
        SetBlockQueue.addNotify(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                TaskManager.runTaskAsync(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        MainUtil.sendMessage(player, "&7 - Starting");
 | 
			
		||||
                        if (args[0].equalsIgnoreCase("all")) {
 | 
			
		||||
                            int height = 255;
 | 
			
		||||
                            PlotBlock block = new PlotBlock((short) 7, (byte) 0);
 | 
			
		||||
                            PlotBlock air = new PlotBlock((short) 0, (byte) 0);
 | 
			
		||||
                            if (args.length > 2) {
 | 
			
		||||
                                try {
 | 
			
		||||
                                    block = new PlotBlock(Short.parseShort(args[1]), (byte) 0);
 | 
			
		||||
                                    if (args.length == 3) {
 | 
			
		||||
                                        height = Integer.parseInt(args[2]);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                                catch (Exception e) {
 | 
			
		||||
                                    MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot fill all <id> <height>");
 | 
			
		||||
                                    MainUtil.runners.remove(plot);
 | 
			
		||||
                                    return;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            for (int y = 0; y <= height; y++) {
 | 
			
		||||
                                for (int x = bottom.getX(); x <= top.getX(); x++) {
 | 
			
		||||
                                    for (int z = bottom.getZ(); z <= top.getZ(); z++) {
 | 
			
		||||
                                        SetBlockQueue.setBlock(plot.world, x, y, z, block);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            for (int y = height + 1; y <= 255; y++) {
 | 
			
		||||
                                for (int x = bottom.getX(); x <= top.getX(); x++) {
 | 
			
		||||
                                    for (int z = bottom.getZ(); z <= top.getZ(); z++) {
 | 
			
		||||
                                        SetBlockQueue.setBlock(plot.world, x, y, z, air);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            SetBlockQueue.addNotify(new Runnable() {
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void run() {
 | 
			
		||||
                                    MainUtil.runners.remove(plot);
 | 
			
		||||
                                    MainUtil.sendMessage(player, "&aFill task complete!");
 | 
			
		||||
                                }
 | 
			
		||||
                            });
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (args[0].equals("outline")) {
 | 
			
		||||
                            int x, z;
 | 
			
		||||
                            z = bottom.getZ();
 | 
			
		||||
                            for (x = bottom.getX(); x <= (top.getX() - 1); x++) {
 | 
			
		||||
                                for (int y = 1; y <= 255; y++) {
 | 
			
		||||
                                    SetBlockQueue.setBlock(plot.world, x, y, z, 7);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            x = top.getX();
 | 
			
		||||
                            for (z = bottom.getZ(); z <= (top.getZ() - 1); z++) {
 | 
			
		||||
                                for (int y = 1; y <= 255; y++) {
 | 
			
		||||
                                    SetBlockQueue.setBlock(plot.world, x, y, z, 7);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            z = top.getZ();
 | 
			
		||||
                            for (x = top.getX(); x >= (bottom.getX() + 1); x--) {
 | 
			
		||||
                                for (int y = 1; y <= 255; y++) {
 | 
			
		||||
                                    SetBlockQueue.setBlock(plot.world, x, y, z, 7);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            x = bottom.getX();
 | 
			
		||||
                            for (z = top.getZ(); z >= (bottom.getZ() + 1); z--) {
 | 
			
		||||
                                for (int y = 1; y <= 255; y++) {
 | 
			
		||||
                                    SetBlockQueue.setBlock(plot.world, x, y, z, 7);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            SetBlockQueue.addNotify(new Runnable() {
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void run() {
 | 
			
		||||
                                    MainUtil.sendMessage(player, "&aWalls complete! The ceiling will take a while :(");
 | 
			
		||||
                                    bottom.setY(255);
 | 
			
		||||
                                    top.add(1,0,1);
 | 
			
		||||
                                    SetBlockQueue.setSlow(true);
 | 
			
		||||
                                    MainUtil.setSimpleCuboidAsync(plot.world, bottom, top, new PlotBlock((short) 7, (byte) 0));
 | 
			
		||||
                                    SetBlockQueue.addNotify(new Runnable() {
 | 
			
		||||
                                        @Override
 | 
			
		||||
                                        public void run() {
 | 
			
		||||
                                            MainUtil.runners.remove(plot);
 | 
			
		||||
                                            MainUtil.sendMessage(player, "&aFill task complete!");
 | 
			
		||||
                                            SetBlockQueue.setSlow(false);
 | 
			
		||||
                                        }
 | 
			
		||||
                                    });
 | 
			
		||||
                                }
 | 
			
		||||
                            });
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,75 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.Map.Entry;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.Flag;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.FlagManager;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.BlockManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
 | 
			
		||||
public class DebugFixFlags extends SubCommand {
 | 
			
		||||
    public DebugFixFlags() {
 | 
			
		||||
        super(Command.DEBUGFIXFLAGS, "Attempt to fix all flags for a world", "debugclear", CommandCategory.DEBUG, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if (plr != null) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NOT_CONSOLE);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (args.length != 1) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot debugfixflags <world>");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final String world = args[0];
 | 
			
		||||
        if (!BlockManager.manager.isWorld(world) || !PS.get().isPlotWorld(world)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_WORLD, args[0]);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.sendMessage(plr, "&8--- &6Starting task &8 ---");
 | 
			
		||||
        for (final Plot plot : PS.get().getPlots(world).values()) {
 | 
			
		||||
            final HashMap<String, Flag> flags = plot.settings.flags;
 | 
			
		||||
            Iterator<Entry<String, Flag>> i = flags.entrySet().iterator();
 | 
			
		||||
            boolean changed = false;
 | 
			
		||||
            while (i.hasNext()) {
 | 
			
		||||
                if (FlagManager.getFlag(i.next().getKey()) == null) {
 | 
			
		||||
                    changed = true;
 | 
			
		||||
                    i.remove();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (changed) {
 | 
			
		||||
                DBFunc.setFlags(plot, plot.settings.flags.values());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.sendMessage(plr, "&aDone!");
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,55 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 */
 | 
			
		||||
public class DebugLoadTest extends SubCommand {
 | 
			
		||||
    public DebugLoadTest() {
 | 
			
		||||
        super(Command.DEBUGLOADTEST, "This debug command will force the reload of all plots in the DB", "debugloadtest", CommandCategory.DEBUG, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if (plr == null) {
 | 
			
		||||
            try {
 | 
			
		||||
                final Field fPlots = PS.class.getDeclaredField("plots");
 | 
			
		||||
                fPlots.setAccessible(true);
 | 
			
		||||
                fPlots.set(null, DBFunc.getPlots());
 | 
			
		||||
            } catch (final Exception e) {
 | 
			
		||||
                PS.log("&3===FAILED&3===");
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
                PS.log("&3===END OF STACKTRACE===");
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            MainUtil.sendMessage(plr, "&6This command can only be executed by console as it has been deemed unsafe if abused..");
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,49 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridPlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.object.ChunkLoc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
 | 
			
		||||
public class DebugRoadRegen extends SubCommand {
 | 
			
		||||
    public DebugRoadRegen() {
 | 
			
		||||
        super(Command.DEBUGROADREGEN, "Regenerate all road schematic in your current chunk", "debugroadregen", CommandCategory.DEBUG, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer player, final String... args) {
 | 
			
		||||
        final Location loc = player.getLocation();
 | 
			
		||||
        final String world = loc.getWorld();
 | 
			
		||||
        if (!(PS.get().getPlotWorld(world) instanceof HybridPlotWorld)) {
 | 
			
		||||
            return sendMessage(player, C.NOT_IN_PLOT_WORLD);
 | 
			
		||||
        }
 | 
			
		||||
        final ChunkLoc chunk = new ChunkLoc(loc.getX() >> 4, loc.getZ() >> 4);
 | 
			
		||||
        final boolean result = HybridUtils.manager.regenerateRoad(world, chunk, 0);
 | 
			
		||||
        MainUtil.sendMessage(player, "&6Regenerating chunk: " + chunk.x + "," + chunk.z + "\n&6 - Result: " + (result == true ? "&aSuccess" : "&cFailed"));
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,56 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 */
 | 
			
		||||
public class DebugSaveTest extends SubCommand {
 | 
			
		||||
    public DebugSaveTest() {
 | 
			
		||||
        super(Command.DEBUGSAVETEST, "This debug command will force the recreation of all plots in the DB", "debugsavetest", CommandCategory.DEBUG, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if (plr == null) {
 | 
			
		||||
            final ArrayList<Plot> plots = new ArrayList<Plot>();
 | 
			
		||||
            plots.addAll(PS.get().getPlots());
 | 
			
		||||
            MainUtil.sendMessage(null, "&6Starting `DEBUGSAVETEST`");
 | 
			
		||||
            DBFunc.createPlotsAndData(plots, new Runnable() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
                    MainUtil.sendMessage(null, "&6Database sync finished!");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            MainUtil.sendMessage(plr, "This debug command can only be executed by console as it has been deemed unsafe if abused");
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,114 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.Map.Entry;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.generator.ChunkGenerator;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.config.ConfigurationNode;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridGen;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotGenerator;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.SetupObject;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.SetupUtils;
 | 
			
		||||
 | 
			
		||||
public class DebugSetup extends SubCommand {
 | 
			
		||||
    public DebugSetup() {
 | 
			
		||||
        super("setup", "plots.admin.command.setup", "Plotworld setup command", "setup", "create", CommandCategory.ACTIONS, false);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public void displayGenerators(PlotPlayer plr) {
 | 
			
		||||
        StringBuffer message = new StringBuffer();
 | 
			
		||||
        message.append("&6What generator do you want?");
 | 
			
		||||
        for (Entry<String, ChunkGenerator> entry : SetupUtils.generators.entrySet()) {
 | 
			
		||||
            if (entry.getKey().equals("PlotSquared")) {
 | 
			
		||||
                message.append("\n&8 - &2" + entry.getKey() + " (Default Generator)");
 | 
			
		||||
            }
 | 
			
		||||
            else if (entry.getValue() instanceof HybridGen) {
 | 
			
		||||
                message.append("\n&8 - &7" + entry.getKey() + " (Hybrid Generator)");
 | 
			
		||||
            }
 | 
			
		||||
            else if (entry.getValue() instanceof PlotGenerator) {
 | 
			
		||||
                message.append("\n&8 - &7" + entry.getKey() + " (Plot Generator)");
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                message.append("\n&8 - &7" + entry.getKey() + " (Unknown structure)");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.sendMessage(plr, message.toString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        // going through setup
 | 
			
		||||
        String name;
 | 
			
		||||
        if (plr == null) {
 | 
			
		||||
            name = "*";
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            name = plr.getName();
 | 
			
		||||
        }
 | 
			
		||||
        if (!SetupUtils.setupMap.containsKey(name)) {
 | 
			
		||||
            final SetupObject object = new SetupObject();
 | 
			
		||||
            SetupUtils.setupMap.put(name, object);
 | 
			
		||||
            SetupUtils.manager.updateGenerators();
 | 
			
		||||
            sendMessage(plr, C.SETUP_INIT);
 | 
			
		||||
            displayGenerators(plr);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (args.length == 1) {
 | 
			
		||||
            if (args[0].equalsIgnoreCase("cancel")) {
 | 
			
		||||
                SetupUtils.setupMap.remove(name);
 | 
			
		||||
                MainUtil.sendMessage(plr, "&aCancelled setup");
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            if (args[0].equalsIgnoreCase("back")) {
 | 
			
		||||
                final SetupObject object = SetupUtils.setupMap.get(name);
 | 
			
		||||
                if (object.setup_index > 0) {
 | 
			
		||||
                    object.setup_index--;
 | 
			
		||||
                    final ConfigurationNode node = object.step[object.setup_index];
 | 
			
		||||
                    sendMessage(plr, C.SETUP_STEP, object.setup_index + 1 + "", node.getDescription(), node.getType().getType(), node.getDefaultValue() + "");
 | 
			
		||||
                    return false;
 | 
			
		||||
                } else if (object.current > 0) {
 | 
			
		||||
                    object.current--;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        final SetupObject object = SetupUtils.setupMap.get(name);
 | 
			
		||||
        final int index = object.current;
 | 
			
		||||
        switch (index) {
 | 
			
		||||
            case 0: { // choose plot manager // skip if 1 option
 | 
			
		||||
            }
 | 
			
		||||
            case 1: { // choose type (default, augmented, cluster)
 | 
			
		||||
            }
 | 
			
		||||
            case 2: { // Choose generator (vanilla, non plot generator) // skip if one option
 | 
			
		||||
            }
 | 
			
		||||
            case 3: { // world setup // skip if one option
 | 
			
		||||
            }
 | 
			
		||||
            case 4: { // world name
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,297 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FilenameFilter;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Map.Entry;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.database.AbstractDB;
 | 
			
		||||
import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.StringWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.PlayerManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.uuid.DefaultUUIDWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.uuid.LowerOfflineUUIDWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.uuid.OfflineUUIDWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
 | 
			
		||||
 | 
			
		||||
public class DebugUUID extends SubCommand {
 | 
			
		||||
    public DebugUUID() {
 | 
			
		||||
        super("uuidconvert", "plots.admin", "Debug uuid conversion", "debuguuid", "debuguuid", CommandCategory.DEBUG, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer player, final String... args) {
 | 
			
		||||
        if (player != null) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.NOT_CONSOLE);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (args.length == 0) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot uuidconvert <lower|offline|online>");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        UUIDWrapper currentUUIDWrapper = UUIDHandler.uuidWrapper;
 | 
			
		||||
        UUIDWrapper newWrapper = null;
 | 
			
		||||
        
 | 
			
		||||
        switch (args[0].toLowerCase()) {
 | 
			
		||||
            case "lower": {
 | 
			
		||||
                newWrapper = new LowerOfflineUUIDWrapper();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case "offline": {
 | 
			
		||||
                newWrapper = new OfflineUUIDWrapper();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case "online": {
 | 
			
		||||
                newWrapper = new DefaultUUIDWrapper();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default: {
 | 
			
		||||
                try {
 | 
			
		||||
                    Class<?> clazz = Class.forName(args[0]);
 | 
			
		||||
                    newWrapper = (UUIDWrapper) clazz.newInstance();
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception e) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot uuidconvert <lower|offline|online>");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (args.length != 2 || !args[1].equals("-o")) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot uuidconvert " + args[0] + " - o");
 | 
			
		||||
            MainUtil.sendMessage(player, "&cBe aware of the following!");
 | 
			
		||||
            MainUtil.sendMessage(player, "&8 - &cIf the process is interrupted, all plots could be deleted");
 | 
			
		||||
            MainUtil.sendMessage(player, "&8 - &cIf an error occurs, all plots could be deleted");
 | 
			
		||||
            MainUtil.sendMessage(player, "&8 - &cPlot settings WILL be lost upon conversion");
 | 
			
		||||
            MainUtil.sendMessage(player, "&cBACK UP YOUR DATABASE BEFORE USING THIS!!!");
 | 
			
		||||
            MainUtil.sendMessage(player, "&7Retype the command with the override parameter when ready");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (currentUUIDWrapper.getClass().getCanonicalName().equals(newWrapper.getClass().getCanonicalName())) {
 | 
			
		||||
            MainUtil.sendMessage(player, "&cUUID mode already in use!");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.sendConsoleMessage("&6Beginning UUID mode conversion");
 | 
			
		||||
        MainUtil.sendConsoleMessage("&7 - Disconnecting players");
 | 
			
		||||
        for (PlotPlayer user : UUIDHandler.players.values()) {
 | 
			
		||||
            PlayerManager.manager.kickPlayer(user, "PlotSquared UUID conversion has been initiated. You may reconnect when finished.");
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        MainUtil.sendConsoleMessage("&7 - Initializing map");
 | 
			
		||||
        
 | 
			
		||||
        HashMap<UUID, UUID> uCMap = new HashMap<UUID, UUID>();
 | 
			
		||||
        HashMap<UUID, UUID> uCReverse = new HashMap<UUID, UUID>();
 | 
			
		||||
        
 | 
			
		||||
        MainUtil.sendConsoleMessage("&7 - Collecting playerdata");
 | 
			
		||||
 | 
			
		||||
        final HashSet<String> worlds = new HashSet<>();
 | 
			
		||||
        worlds.add(Bukkit.getWorlds().get(0).getName());
 | 
			
		||||
        worlds.add("world");
 | 
			
		||||
        final HashSet<UUID> uuids = new HashSet<>();
 | 
			
		||||
        final HashSet<String> names = new HashSet<>();
 | 
			
		||||
        for (final String worldname : worlds) {
 | 
			
		||||
            final File playerdataFolder = new File(worldname + File.separator + "playerdata");
 | 
			
		||||
            String[] dat = playerdataFolder.list(new FilenameFilter() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public boolean accept(final File f, final String s) {
 | 
			
		||||
                    return s.endsWith(".dat");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            if (dat != null) {
 | 
			
		||||
                for (final String current : dat) {
 | 
			
		||||
                    final String s = current.replaceAll(".dat$", "");
 | 
			
		||||
                    try {
 | 
			
		||||
                        final UUID uuid = UUID.fromString(s);
 | 
			
		||||
                        uuids.add(uuid);
 | 
			
		||||
                    } catch (final Exception e) {
 | 
			
		||||
                        PS.log(C.PREFIX.s() + "Invalid playerdata: " + current);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            final File playersFolder = new File(worldname + File.separator + "players");
 | 
			
		||||
            dat = playersFolder.list(new FilenameFilter() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public boolean accept(final File f, final String s) {
 | 
			
		||||
                    return s.endsWith(".dat");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            if (dat != null) {
 | 
			
		||||
                for (final String current : dat) {
 | 
			
		||||
                    names.add(current.replaceAll(".dat$", ""));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        MainUtil.sendConsoleMessage("&7 - Populating map");
 | 
			
		||||
        UUID uuid2;
 | 
			
		||||
        final UUIDWrapper wrapper = new DefaultUUIDWrapper();
 | 
			
		||||
        for (UUID uuid : uuids) {
 | 
			
		||||
            try {
 | 
			
		||||
                final OfflinePlotPlayer op = wrapper.getOfflinePlayer(uuid);
 | 
			
		||||
                uuid = currentUUIDWrapper.getUUID(op);
 | 
			
		||||
                uuid2 = newWrapper.getUUID(op);
 | 
			
		||||
                if (!uuid.equals(uuid2)) {
 | 
			
		||||
                    uCMap.put(uuid, uuid2);
 | 
			
		||||
                    uCReverse.put(uuid2, uuid);
 | 
			
		||||
                }
 | 
			
		||||
            } catch (final Throwable e) {
 | 
			
		||||
                PS.log(C.PREFIX.s() + "&6Invalid playerdata: " + uuid.toString() + ".dat");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        for (final String name : names) {
 | 
			
		||||
            final UUID uuid = currentUUIDWrapper.getUUID(name);
 | 
			
		||||
            uuid2 = newWrapper.getUUID(name);
 | 
			
		||||
            if (!uuid.equals(uuid2)) {
 | 
			
		||||
                uCMap.put(uuid, uuid2);
 | 
			
		||||
                uCReverse.put(uuid2, uuid);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (uCMap.size() == 0) {
 | 
			
		||||
            MainUtil.sendConsoleMessage("&c - Error! Attempting to repopulate");
 | 
			
		||||
            for (OfflinePlotPlayer op : currentUUIDWrapper.getOfflinePlayers()) {
 | 
			
		||||
                if (op.getLastPlayed() != 0) {
 | 
			
		||||
                    String name = op.getName();
 | 
			
		||||
                    StringWrapper wrap = new StringWrapper(name);
 | 
			
		||||
                    UUID uuid = currentUUIDWrapper.getUUID(op);
 | 
			
		||||
                    uuid2 = newWrapper.getUUID(op);
 | 
			
		||||
                    if (!uuid.equals(uuid2)) {
 | 
			
		||||
                        uCMap.put(uuid, uuid2);
 | 
			
		||||
                        uCReverse.put(uuid2, uuid);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (uCMap.size() == 0) {
 | 
			
		||||
                MainUtil.sendConsoleMessage("&cError. Failed to collect UUIDs!");
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                MainUtil.sendConsoleMessage("&a - Successfully repopulated");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        MainUtil.sendConsoleMessage("&7 - Replacing cache");
 | 
			
		||||
        for (Entry<UUID, UUID> entry : uCMap.entrySet()) {
 | 
			
		||||
            String name = UUIDHandler.getName(entry.getKey());
 | 
			
		||||
            UUIDHandler.add(new StringWrapper(name), entry.getValue());
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        MainUtil.sendConsoleMessage("&7 - Replacing wrapper");
 | 
			
		||||
        UUIDHandler.uuidWrapper = newWrapper;
 | 
			
		||||
        
 | 
			
		||||
        MainUtil.sendConsoleMessage("&7 - Updating plot objects");
 | 
			
		||||
 | 
			
		||||
        for (Plot plot : PS.get().getPlotsRaw()) {
 | 
			
		||||
            UUID value = uCMap.get(plot.owner);
 | 
			
		||||
            if (value != null) {
 | 
			
		||||
                plot.owner = value;
 | 
			
		||||
            }
 | 
			
		||||
            plot.trusted = new ArrayList<>();
 | 
			
		||||
            plot.members = new ArrayList<>();
 | 
			
		||||
            plot.denied = new ArrayList<>();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        MainUtil.sendConsoleMessage("&7 - Deleting database");
 | 
			
		||||
        final AbstractDB database = DBFunc.dbManager;
 | 
			
		||||
        boolean result = database.deleteTables();
 | 
			
		||||
 | 
			
		||||
        MainUtil.sendConsoleMessage("&7 - Creating tables");
 | 
			
		||||
        
 | 
			
		||||
        try {
 | 
			
		||||
            database.createTables(Settings.DB.USE_MYSQL ? "mysql" : "sqlite");
 | 
			
		||||
            if (!result) {
 | 
			
		||||
                MainUtil.sendConsoleMessage("&cConversion failed! Attempting recovery");
 | 
			
		||||
                for (Plot plot : PS.get().getPlots()) {
 | 
			
		||||
                    UUID value = uCReverse.get(plot.owner);
 | 
			
		||||
                    if (value != null) {
 | 
			
		||||
                        plot.owner = value;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                database.createPlotsAndData(new ArrayList<>(PS.get().getPlots()), new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        MainUtil.sendMessage(null, "&6Recovery was successful!");
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (newWrapper instanceof OfflineUUIDWrapper) {
 | 
			
		||||
            PS.get().config.set("UUID.force-lowercase", false);
 | 
			
		||||
            PS.get().config.set("UUID.offline", true);
 | 
			
		||||
        }
 | 
			
		||||
        else if (newWrapper instanceof LowerOfflineUUIDWrapper) {
 | 
			
		||||
            PS.get().config.set("UUID.force-lowercase", true);
 | 
			
		||||
            PS.get().config.set("UUID.offline", true);
 | 
			
		||||
        }
 | 
			
		||||
        else if (newWrapper instanceof DefaultUUIDWrapper) {
 | 
			
		||||
            PS.get().config.set("UUID.force-lowercase", false);
 | 
			
		||||
            PS.get().config.set("UUID.offline", false);
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            PS.get().config.save(PS.get().configFile);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception e) {
 | 
			
		||||
            MainUtil.sendConsoleMessage("Could not save configuration. It will need to be manuall set!");
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        MainUtil.sendConsoleMessage("&7 - Populating tables");
 | 
			
		||||
        
 | 
			
		||||
        TaskManager.runTaskAsync(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                ArrayList<Plot> plots = new ArrayList<>(PS.get().getPlots());
 | 
			
		||||
                database.createPlotsAndData(plots, new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        MainUtil.sendConsoleMessage("&aConversion complete!");
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        MainUtil.sendConsoleMessage("&aIt is now safe for players to join");
 | 
			
		||||
        MainUtil.sendConsoleMessage("&cConversion is still in progress, you will be notified when it is complete");
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,94 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.util.CmdConfirm;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EconHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
 | 
			
		||||
public class Delete extends SubCommand {
 | 
			
		||||
    public Delete() {
 | 
			
		||||
        super(Command.DELETE, "Delete a plot", "delete", CommandCategory.ACTIONS, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        final Location loc = plr.getLocation();
 | 
			
		||||
        final Plot plot = MainUtil.getPlot(loc);
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            return !sendMessage(plr, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        if (!MainUtil.getTopPlot(plot).equals(MainUtil.getBottomPlot(plot))) {
 | 
			
		||||
            return !sendMessage(plr, C.UNLINK_REQUIRED);
 | 
			
		||||
        }
 | 
			
		||||
        if ((((plot == null) || !plot.hasOwner() || !plot.isOwner(UUIDHandler.uuidWrapper.getUUID(plr)))) && !Permissions.hasPermission(plr, "plots.admin.command.delete")) {
 | 
			
		||||
            return !sendMessage(plr, C.NO_PLOT_PERMS);
 | 
			
		||||
        }
 | 
			
		||||
        assert plot != null;
 | 
			
		||||
        final PlotWorld pWorld = PS.get().getPlotWorld(plot.world);
 | 
			
		||||
        if (MainUtil.runners.containsKey(plot)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        Runnable runnable = new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                if ((EconHandler.manager != null) && pWorld.USE_ECONOMY && (plot != null) && plot.hasOwner() && plot.isOwner(UUIDHandler.getUUID(plr))) {
 | 
			
		||||
                    final double c = pWorld.SELL_PRICE;
 | 
			
		||||
                    if (c > 0d) {
 | 
			
		||||
                        EconHandler.manager.depositMoney(plr, c);
 | 
			
		||||
                        sendMessage(plr, C.ADDED_BALANCE, c + "");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                PS.get().removePlot(loc.getWorld(), plot.id, true);
 | 
			
		||||
                final long start = System.currentTimeMillis();
 | 
			
		||||
                final boolean result = MainUtil.clearAsPlayer(plot, true, new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        MainUtil.sendMessage(plr, C.CLEARING_DONE, "" + (System.currentTimeMillis() - start));
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
                if (!result) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER);
 | 
			
		||||
                }
 | 
			
		||||
                DBFunc.delete(plot);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        if (Settings.CONFIRM_DELETE && !(Permissions.hasPermission(plr, "plots.confirm.bypass"))) {
 | 
			
		||||
            CmdConfirm.addPending(plr, "/plot delete " + plot.id, runnable);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            TaskManager.runTask(runnable);
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,89 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EventUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
 | 
			
		||||
public class Deny extends SubCommand {
 | 
			
		||||
    public Deny() {
 | 
			
		||||
        super(Command.DENY, "Deny a user from a plot", "deny <player>", CommandCategory.ACTIONS, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if (args.length != 1) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot deny <player>");
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        final Location loc = plr.getLocation();
 | 
			
		||||
        final Plot plot = MainUtil.getPlot(loc);
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            return !sendMessage(plr, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        if ((plot == null) || !plot.hasOwner()) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.PLOT_UNOWNED);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (!plot.isOwner(plr.getUUID()) && !Permissions.hasPermission(plr, "plots.admin.command.deny")) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NO_PLOT_PERMS);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        UUID uuid;
 | 
			
		||||
        if (args[0].equalsIgnoreCase("*")) {
 | 
			
		||||
            uuid = DBFunc.everyone;
 | 
			
		||||
        } else {
 | 
			
		||||
            uuid = UUIDHandler.getUUID(args[0]);
 | 
			
		||||
        }
 | 
			
		||||
        if (uuid == null) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.INVALID_PLAYER, args[0]);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (plot.isOwner(uuid)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.ALREADY_OWNER);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (plot.denied.contains(uuid)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.ALREADY_ADDED);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        plot.removeMember(uuid);
 | 
			
		||||
        plot.removeTrusted(uuid);
 | 
			
		||||
        plot.addDenied(uuid);
 | 
			
		||||
        EventUtil.manager.callDenied(plr, plot, uuid, true);
 | 
			
		||||
        MainUtil.sendMessage(plr, C.DENIED_ADDED);
 | 
			
		||||
        if (!uuid.equals(DBFunc.everyone)) {
 | 
			
		||||
            PS.get().IMP.handleKick(uuid, C.YOU_GOT_DENIED);
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,47 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedReader;
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.net.URLConnection;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
 | 
			
		||||
public class Disable extends SubCommand {
 | 
			
		||||
    public static String downloads, version;
 | 
			
		||||
 | 
			
		||||
    public Disable() {
 | 
			
		||||
        super("disable", "plots.admin", "Disable PlotSquared", "disable", "unload", CommandCategory.DEBUG, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        PS.log("&cDisabling PlotSquared and all dependencies!");
 | 
			
		||||
        PS.get().IMP.disable();
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,56 @@
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.jnbt.CompoundTag;
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.SchematicHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
 | 
			
		||||
public class Download extends SubCommand {
 | 
			
		||||
    public Download() {
 | 
			
		||||
        super(Command.DOWNLOAD, "Download your plot", "dl", CommandCategory.ACTIONS, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, String... args) {
 | 
			
		||||
        if (!Settings.METRICS) {
 | 
			
		||||
            MainUtil.sendMessage(plr, "&cPlease enable metrics in order to use this command.\n&7 - Or host it yourself if you don't like the free service");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final String world = plr.getLocation().getWorld();
 | 
			
		||||
        if (!PS.get().isPlotWorld(world)) {
 | 
			
		||||
            return !sendMessage(plr, C.NOT_IN_PLOT_WORLD);
 | 
			
		||||
        }
 | 
			
		||||
        final Plot plot = MainUtil.getPlot(plr.getLocation());
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            return !sendMessage(plr, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        if (MainUtil.runners.containsKey(plot)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.runners.put(plot, 1);
 | 
			
		||||
        MainUtil.sendMessage(plr, C.GENERATING_LINK);
 | 
			
		||||
        final CompoundTag tag = SchematicHandler.manager.getCompoundTag(plot.world, plot.id);
 | 
			
		||||
        TaskManager.runTaskAsync(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                URL url = SchematicHandler.manager.upload(tag);
 | 
			
		||||
                if (url == null) {
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.GENERATING_LINK_FAILED);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                MainUtil.sendMessage(plr, url.toString());
 | 
			
		||||
                MainUtil.runners.remove(plot);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,244 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.lang.StringUtils;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.AbstractFlag;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.Flag;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.FlagManager;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.FlagValue;
 | 
			
		||||
import com.intellectualcrafters.plot.listeners.APlotListener;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
 | 
			
		||||
public class FlagCmd extends SubCommand {
 | 
			
		||||
    public FlagCmd() {
 | 
			
		||||
        super(Command.FLAG, "Manage plot flags", "f", CommandCategory.ACTIONS, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer player, final String... args) {
 | 
			
		||||
        /*
 | 
			
		||||
         *  plot flag set fly true
 | 
			
		||||
         *  plot flag remove fly
 | 
			
		||||
         *  plot flag remove use 1,3
 | 
			
		||||
         *  plot flag add use 2,4
 | 
			
		||||
         *  plot flag list
 | 
			
		||||
         */
 | 
			
		||||
        if (args.length == 0) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot flag <set|remove|add|list|info>");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final Location loc = player.getLocation();
 | 
			
		||||
        final Plot plot = MainUtil.getPlot(loc);
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.NOT_IN_PLOT);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (!plot.hasOwner()) {
 | 
			
		||||
            sendMessage(player, C.PLOT_NOT_CLAIMED);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (!plot.isAdded(player.getUUID()) && !Permissions.hasPermission(player, "plots.set.flag.other")) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.NO_PERMISSION, "plots.set.flag.other");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (args.length > 1 && FlagManager.isReserved(args[1])) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.NOT_VALID_FLAG);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        switch (args[0].toLowerCase()) {
 | 
			
		||||
            case "info": {
 | 
			
		||||
                if (!Permissions.hasPermission(player, "plots.set.flag")) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.NO_PERMISSION, "plots.flag.info");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 2) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot flag info <flag>");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final AbstractFlag af = FlagManager.getFlag(args[1]);
 | 
			
		||||
                if (af == null) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.NOT_VALID_FLAG);
 | 
			
		||||
                    MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot flag info <flag>");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                // flag key
 | 
			
		||||
                MainUtil.sendMessage(player, C.FLAG_KEY, af.getKey());
 | 
			
		||||
                // flag type
 | 
			
		||||
                MainUtil.sendMessage(player, C.FLAG_TYPE, af.value.getClass().getSimpleName());
 | 
			
		||||
                // Flag type description
 | 
			
		||||
                MainUtil.sendMessage(player, C.FLAG_DESC, af.getValueDesc());
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "set": {
 | 
			
		||||
                if (!Permissions.hasPermission(player, "plots.set.flag")) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.NO_PERMISSION, "plots.set.flag");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length < 3) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot flag set <flag> <value>");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final AbstractFlag af = FlagManager.getFlag(args[1].toLowerCase());
 | 
			
		||||
                if (af == null) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.NOT_VALID_FLAG);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (!Permissions.hasPermission(player, "plots.set.flag." + args[1].toLowerCase())) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.NO_PERMISSION, "plots.set.flag." + args[1].toLowerCase());
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final String value = StringUtils.join(Arrays.copyOfRange(args, 2, args.length), " ");
 | 
			
		||||
                final Object parsed = af.parseValueRaw(value);
 | 
			
		||||
                if (parsed == null) {
 | 
			
		||||
                    MainUtil.sendMessage(player, "&c" + af.getValueDesc());
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final Flag flag = new Flag(FlagManager.getFlag(args[1].toLowerCase(), true), parsed);
 | 
			
		||||
                final boolean result = FlagManager.addPlotFlag(plot, flag);
 | 
			
		||||
                if (!result) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.FLAG_NOT_ADDED);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                MainUtil.sendMessage(player, C.FLAG_ADDED);
 | 
			
		||||
                APlotListener.manager.plotEntry(player, plot);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "remove": {
 | 
			
		||||
                if (!Permissions.hasPermission(player, "plots.flag.remove")) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.NO_PERMISSION, "plots.flag.remove");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if ((args.length != 2) && (args.length != 3)) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot flag remove <flag> [values]");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final AbstractFlag af = FlagManager.getFlag(args[1].toLowerCase());
 | 
			
		||||
                if (af == null) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.NOT_VALID_FLAG);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (!Permissions.hasPermission(player, "plots.set.flag." + args[1].toLowerCase())) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.NO_PERMISSION, "plots.set.flag." + args[1].toLowerCase());
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final Flag flag = FlagManager.getPlotFlagAbs(plot, args[1].toLowerCase());
 | 
			
		||||
                if (flag == null) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.FLAG_NOT_IN_PLOT);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if ((args.length == 3) && flag.getAbstractFlag().isList()) {
 | 
			
		||||
                    final String value = StringUtils.join(Arrays.copyOfRange(args, 2, args.length), " ");
 | 
			
		||||
                    ((FlagValue.ListValue) flag.getAbstractFlag().value).remove(flag.getValue(), value);
 | 
			
		||||
                    DBFunc.setFlags(plot, plot.settings.flags.values());
 | 
			
		||||
                } else {
 | 
			
		||||
                    final boolean result = FlagManager.removePlotFlag(plot, flag.getKey());
 | 
			
		||||
                    if (!result) {
 | 
			
		||||
                        MainUtil.sendMessage(player, C.FLAG_NOT_REMOVED);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                MainUtil.sendMessage(player, C.FLAG_REMOVED);
 | 
			
		||||
                APlotListener.manager.plotEntry(player, plot);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "add": {
 | 
			
		||||
                if (!Permissions.hasPermission(player, "plots.flag.add")) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.NO_PERMISSION, "plots.flag.add");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length < 3) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot flag add <flag> <values>");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final AbstractFlag af = FlagManager.getFlag(args[1].toLowerCase());
 | 
			
		||||
                if (af == null) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.NOT_VALID_FLAG);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (!Permissions.hasPermission(player, "plots.set.flag." + args[1].toLowerCase())) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.NO_PERMISSION, "plots.set.flag." + args[1].toLowerCase());
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final String value = StringUtils.join(Arrays.copyOfRange(args, 2, args.length), " ");
 | 
			
		||||
                final Object parsed = af.parseValueRaw(value);
 | 
			
		||||
                if (parsed == null) {
 | 
			
		||||
                    MainUtil.sendMessage(player, "&c" + af.getValueDesc());
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                Flag flag = FlagManager.getPlotFlag(plot, args[1].toLowerCase());
 | 
			
		||||
                if ((flag == null) || !flag.getAbstractFlag().isList()) {
 | 
			
		||||
                    flag = new Flag(FlagManager.getFlag(args[1].toLowerCase(), true), parsed);
 | 
			
		||||
                } else {
 | 
			
		||||
                    ((FlagValue.ListValue) flag.getAbstractFlag().value).add(flag.getValue(), value);
 | 
			
		||||
                }
 | 
			
		||||
                final boolean result = FlagManager.addPlotFlag(plot, flag);
 | 
			
		||||
                if (!result) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.FLAG_NOT_ADDED);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                DBFunc.setFlags(plot, plot.settings.flags.values());
 | 
			
		||||
                MainUtil.sendMessage(player, C.FLAG_ADDED);
 | 
			
		||||
                APlotListener.manager.plotEntry(player, plot);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "list": {
 | 
			
		||||
                if (!Permissions.hasPermission(player, "plots.flag.list")) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.NO_PERMISSION, "plots.flag.list");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 1) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot flag list");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                final HashMap<String, ArrayList<String>> flags = new HashMap<>();
 | 
			
		||||
                for (final AbstractFlag af : FlagManager.getFlags()) {
 | 
			
		||||
                    final String type = af.value.getClass().getSimpleName().replaceAll("Value", "");
 | 
			
		||||
                    if (!flags.containsKey(type)) {
 | 
			
		||||
                        flags.put(type, new ArrayList<String>());
 | 
			
		||||
                    }
 | 
			
		||||
                    flags.get(type).add(af.getKey());
 | 
			
		||||
                }
 | 
			
		||||
                String message = "";
 | 
			
		||||
                String prefix = "";
 | 
			
		||||
                for (final String flag : flags.keySet()) {
 | 
			
		||||
                    message += prefix + "&6" + flag + ": &7" + StringUtils.join(flags.get(flag), ", ");
 | 
			
		||||
                    prefix = "\n";
 | 
			
		||||
                }
 | 
			
		||||
                MainUtil.sendMessage(player, message);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot flag <set|remove|add|list|info>");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,21 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) IntellectualCrafters - 2014. You are not allowed to distribute
 | 
			
		||||
 * and/or monetize any of our intellectual property. IntellectualCrafters is not
 | 
			
		||||
 * affiliated with Mojang AB. Minecraft is a trademark of Mojang AB.
 | 
			
		||||
 *
 | 
			
		||||
 * >> File = Help.java >> Generated by: Citymonstret at 2014-08-11 17:32
 | 
			
		||||
 */
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
 | 
			
		||||
public class Help extends SubCommand {
 | 
			
		||||
    public Help() {
 | 
			
		||||
        super("help", "", "Get this help menu", "help", "he", SubCommand.CommandCategory.INFO, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,91 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 */
 | 
			
		||||
public class Home extends SubCommand {
 | 
			
		||||
    public Home() {
 | 
			
		||||
        super(Command.HOME, "Go to your plot", "home {id|alias}", CommandCategory.TELEPORT, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Plot isAlias(final String a) {
 | 
			
		||||
        for (final Plot p : PS.get().getPlots()) {
 | 
			
		||||
            if ((p.settings.getAlias().length() > 0) && p.settings.getAlias().equalsIgnoreCase(a)) {
 | 
			
		||||
                return p;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, String... args) {
 | 
			
		||||
        final ArrayList<Plot> plots = PS.get().sortPlotsByWorld(PS.get().getPlots(plr));
 | 
			
		||||
        if (plots.size() == 1) {
 | 
			
		||||
            MainUtil.teleportPlayer(plr, plr.getLocation(), plots.get(0));
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if (plots.size() > 1) {
 | 
			
		||||
            if (args.length < 1) {
 | 
			
		||||
                args = new String[] { "1" };
 | 
			
		||||
            }
 | 
			
		||||
            int id = 0;
 | 
			
		||||
            try {
 | 
			
		||||
                id = Integer.parseInt(args[0]);
 | 
			
		||||
            } catch (final Exception e) {
 | 
			
		||||
                Plot temp;
 | 
			
		||||
                if ((temp = isAlias(args[0])) != null) {
 | 
			
		||||
                    if (temp.hasOwner()) {
 | 
			
		||||
                        if (temp.isOwner(plr.getUUID())) {
 | 
			
		||||
                            MainUtil.teleportPlayer(plr, plr.getLocation(), temp);
 | 
			
		||||
                            return true;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    MainUtil.sendMessage(plr, C.NOT_YOUR_PLOT);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                MainUtil.sendMessage(plr, C.NOT_VALID_NUMBER, "(1, " + plots.size() + ")");
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            if ((id > (plots.size())) || (id < 1)) {
 | 
			
		||||
                MainUtil.sendMessage(plr, C.NOT_VALID_NUMBER, "(1, " + plots.size() + ")");
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            MainUtil.teleportPlayer(plr, plr.getLocation(), plots.get(id - 1));
 | 
			
		||||
            return true;
 | 
			
		||||
        } else {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.FOUND_NO_PLOTS);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void teleportPlayer(final PlotPlayer player, final Plot plot) {
 | 
			
		||||
        MainUtil.teleportPlayer(player, player.getLocation(), plot);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										214
									
								
								src/main/java/com/intellectualcrafters/plot/commands/Inbox.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								src/main/java/com/intellectualcrafters/plot/commands/Inbox.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,214 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.lang.StringUtils;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RunnableVal;
 | 
			
		||||
import com.intellectualcrafters.plot.object.comment.CommentInbox;
 | 
			
		||||
import com.intellectualcrafters.plot.object.comment.CommentManager;
 | 
			
		||||
import com.intellectualcrafters.plot.object.comment.PlotComment;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
 | 
			
		||||
public class Inbox extends SubCommand {
 | 
			
		||||
    public Inbox() {
 | 
			
		||||
        super(Command.INBOX, "Review the comments for a plot", "inbox [inbox] [delete <index>|clear|page]", CommandCategory.ACTIONS, true);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public void displayComments(PlotPlayer player, List<PlotComment> oldComments, int page) {
 | 
			
		||||
        if (oldComments == null || oldComments.size() == 0) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.INBOX_EMPTY);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        PlotComment[] comments = oldComments.toArray(new PlotComment[oldComments.size()]);
 | 
			
		||||
        if (page < 0) {
 | 
			
		||||
            page = 0;
 | 
			
		||||
        }
 | 
			
		||||
        // Get the total pages
 | 
			
		||||
        // int totalPages = ((int) Math.ceil(12 *
 | 
			
		||||
        final int totalPages = (int) Math.ceil(comments.length / 12);
 | 
			
		||||
        if (page > totalPages) {
 | 
			
		||||
            page = totalPages;
 | 
			
		||||
        }
 | 
			
		||||
        // Only display 12 per page
 | 
			
		||||
        int max = (page * 12) + 12;
 | 
			
		||||
        if (max > comments.length) {
 | 
			
		||||
            max = comments.length;
 | 
			
		||||
        }
 | 
			
		||||
        final StringBuilder string = new StringBuilder();
 | 
			
		||||
        string.append(C.PLOT_LIST_HEADER_PAGED.s().replaceAll("plot","comment").replaceAll("%cur", page + 1 + "").replaceAll("%max", totalPages + 1 + "").replaceAll("%word%", "all")).append("\n");
 | 
			
		||||
        PlotComment c;
 | 
			
		||||
        // This might work xD
 | 
			
		||||
        for (int x = (page * 12); x < max; x++) {
 | 
			
		||||
            c = comments[x];
 | 
			
		||||
            String color;
 | 
			
		||||
            if (player.getName().equals(c.senderName)) {
 | 
			
		||||
                color = "&a";
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                color = "&7";
 | 
			
		||||
            }
 | 
			
		||||
            string.append("&8[&7#" + x + "&8][&7" + c.world + ";" + c.id + "&8][&6" + c.senderName + "&8]" + color + c.comment + "\n");
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.sendMessage(player, string.toString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer player, final String... args) {
 | 
			
		||||
        final Plot plot = MainUtil.getPlot(player.getLocation());
 | 
			
		||||
        if (args.length == 0) {
 | 
			
		||||
            sendMessage(player, C.COMMAND_SYNTAX, "/plot inbox [inbox] [delete <index>|clear|page]");
 | 
			
		||||
            for (final CommentInbox inbox : CommentManager.inboxes.values()) {
 | 
			
		||||
                if (inbox.canRead(plot, player)) {
 | 
			
		||||
                    if (!inbox.getComments(plot, new RunnableVal() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            if (value != null) {
 | 
			
		||||
                                int total = 0;
 | 
			
		||||
                                int unread = 0;
 | 
			
		||||
                                for (PlotComment comment : (ArrayList<PlotComment>) value) {
 | 
			
		||||
                                    total++;
 | 
			
		||||
                                    if (comment.timestamp > CommentManager.getTimestamp(player, inbox.toString())) {
 | 
			
		||||
                                        unread++;
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                                if (total != 0) {
 | 
			
		||||
                                    String color;
 | 
			
		||||
                                    if (unread > 0) {
 | 
			
		||||
                                        color = "&c";
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        color = "";
 | 
			
		||||
                                    }
 | 
			
		||||
                                    sendMessage(player, C.INBOX_ITEM, color + inbox.toString() + " (" + total + "/" + unread + ")");
 | 
			
		||||
                                    return;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            sendMessage(player, C.INBOX_ITEM, inbox.toString());
 | 
			
		||||
                        }
 | 
			
		||||
                    })) {
 | 
			
		||||
                        sendMessage(player, C.INBOX_ITEM, inbox.toString());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final CommentInbox inbox = CommentManager.inboxes.get(args[0].toLowerCase());
 | 
			
		||||
        if (inbox == null) {
 | 
			
		||||
            sendMessage(player, C.INVALID_INBOX, StringUtils.join(CommentManager.inboxes.keySet(),", "));
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        player.setMeta("inbox:" + inbox.toString(), System.currentTimeMillis());
 | 
			
		||||
        final int page;
 | 
			
		||||
        if (args.length > 1) {
 | 
			
		||||
            switch (args[1].toLowerCase()) {
 | 
			
		||||
                case "delete": {
 | 
			
		||||
                    if (!inbox.canModify(plot, player)) {
 | 
			
		||||
                        sendMessage(player, C.NO_PERM_INBOX_MODIFY);
 | 
			
		||||
                    }
 | 
			
		||||
                    if (args.length != 3) {
 | 
			
		||||
                        sendMessage(player, C.COMMAND_SYNTAX, "/plot inbox " + inbox.toString() + " delete <index>");
 | 
			
		||||
                    }
 | 
			
		||||
                    final int index;
 | 
			
		||||
                    try {
 | 
			
		||||
                        index = Integer.parseInt(args[2]);
 | 
			
		||||
                        if (index < 1) {
 | 
			
		||||
                            sendMessage(player, C.NOT_VALID_INBOX_INDEX, index + "");
 | 
			
		||||
                            return false;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (NumberFormatException e) {
 | 
			
		||||
                        sendMessage(player, C.COMMAND_SYNTAX, "/plot inbox " + inbox.toString() + " delete <index>");
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
                    if (!inbox.getComments(plot, new RunnableVal() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            List<PlotComment> comments = (List<PlotComment>) value;
 | 
			
		||||
                            if (index > comments.size()) {
 | 
			
		||||
                                sendMessage(player, C.NOT_VALID_INBOX_INDEX, index + "");
 | 
			
		||||
                            }
 | 
			
		||||
                            PlotComment comment = comments.get(index - 1);
 | 
			
		||||
                            inbox.removeComment(plot, comment);
 | 
			
		||||
                            plot.settings.removeComment(comment);
 | 
			
		||||
                            MainUtil.sendMessage(player, C.COMMENT_REMOVED, comment.comment);
 | 
			
		||||
                        }
 | 
			
		||||
                    })) {
 | 
			
		||||
                        sendMessage(player, C.NOT_IN_PLOT);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                case "clear": {
 | 
			
		||||
                    if (!inbox.canModify(plot, player)) {
 | 
			
		||||
                        sendMessage(player, C.NO_PERM_INBOX_MODIFY);
 | 
			
		||||
                    }
 | 
			
		||||
                    inbox.clearInbox(plot);
 | 
			
		||||
                    ArrayList<PlotComment> comments = plot.settings.getComments(inbox.toString());
 | 
			
		||||
                    if (comments != null) {
 | 
			
		||||
                        plot.settings.removeComments(comments);
 | 
			
		||||
                    }
 | 
			
		||||
                    MainUtil.sendMessage(player, C.COMMENT_REMOVED, "*");
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                default: {
 | 
			
		||||
                    try {
 | 
			
		||||
                        page = Integer.parseInt(args[1]) ;
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (NumberFormatException e) {
 | 
			
		||||
                        sendMessage(player, C.COMMAND_SYNTAX, "/plot inbox [inbox] [delete <index>|clear|page]");
 | 
			
		||||
                        return false;
 | 
			
		||||
                    };
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            page = 1;
 | 
			
		||||
        }
 | 
			
		||||
        if (!inbox.canRead(plot, player)) {
 | 
			
		||||
            sendMessage(player, C.NO_PERM_INBOX);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (!inbox.getComments(plot, new RunnableVal() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                List<PlotComment> comments = (List<PlotComment>) value;
 | 
			
		||||
                displayComments(player, comments, page);
 | 
			
		||||
            }
 | 
			
		||||
        })) {
 | 
			
		||||
            if (plot == null) {
 | 
			
		||||
                sendMessage(player, C.NOT_IN_PLOT);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                sendMessage(player, C.PLOT_UNOWNED);
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										253
									
								
								src/main/java/com/intellectualcrafters/plot/commands/Info.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										253
									
								
								src/main/java/com/intellectualcrafters/plot/commands/Info.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,253 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.FlagManager;
 | 
			
		||||
import com.intellectualcrafters.plot.object.*;
 | 
			
		||||
import com.intellectualcrafters.plot.util.BlockManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.StringMan;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
import org.apache.commons.lang.StringUtils;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.regex.Matcher;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 */
 | 
			
		||||
@SuppressWarnings({ "javadoc" })
 | 
			
		||||
public class Info extends SubCommand {
 | 
			
		||||
    public Info() {
 | 
			
		||||
        super(Command.INFO, "Display plot info", "info", CommandCategory.INFO, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String getPlayerList(final Collection<UUID> uuids) {
 | 
			
		||||
        ArrayList<UUID> l = new ArrayList<>(uuids);
 | 
			
		||||
        if ((l == null) || (l.size() < 1)) {
 | 
			
		||||
            return C.NONE.s();
 | 
			
		||||
        }
 | 
			
		||||
        final String c = C.PLOT_USER_LIST.s();
 | 
			
		||||
        final StringBuilder list = new StringBuilder();
 | 
			
		||||
        for (int x = 0; x < l.size(); x++) {
 | 
			
		||||
            if ((x + 1) == l.size()) {
 | 
			
		||||
                list.append(c.replace("%user%", getPlayerName(l.get(x))).replace(",", ""));
 | 
			
		||||
            } else {
 | 
			
		||||
                list.append(c.replace("%user%", getPlayerName(l.get(x))));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return list.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String getPlayerName(final UUID uuid) {
 | 
			
		||||
        if (uuid == null) {
 | 
			
		||||
            return "unknown";
 | 
			
		||||
        }
 | 
			
		||||
        if (uuid.equals(DBFunc.everyone) || uuid.toString().equalsIgnoreCase(DBFunc.everyone.toString())) {
 | 
			
		||||
            return "everyone";
 | 
			
		||||
        }
 | 
			
		||||
        final String name = UUIDHandler.getName(uuid);
 | 
			
		||||
        if (name == null) {
 | 
			
		||||
            return "unknown";
 | 
			
		||||
        }
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer player, String... args) {
 | 
			
		||||
        String arg = null;
 | 
			
		||||
        Plot plot;
 | 
			
		||||
        if (args.length > 0) arg = args[0] + "";
 | 
			
		||||
        if (arg != null) {
 | 
			
		||||
            switch (arg) {
 | 
			
		||||
                case "trusted":
 | 
			
		||||
                case "alias":
 | 
			
		||||
                case "inv":
 | 
			
		||||
                case "biome":
 | 
			
		||||
                case "denied":
 | 
			
		||||
                case "flags":
 | 
			
		||||
                case "id":
 | 
			
		||||
                case "size":
 | 
			
		||||
                case "members":
 | 
			
		||||
                case "owner":
 | 
			
		||||
                case "rating":
 | 
			
		||||
                    plot = MainUtil.getPlotFromString(player, null, player == null);
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    plot = MainUtil.getPlotFromString(player, arg, player == null);
 | 
			
		||||
                    if (args.length == 2) {
 | 
			
		||||
                        arg = args[1];
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        arg = null;
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            plot = MainUtil.getPlotFromString(player, null, player == null);
 | 
			
		||||
        }
 | 
			
		||||
        if (plot == null && arg != null) {
 | 
			
		||||
            plot = MainUtil.getPlotFromString(player, null, player == null);
 | 
			
		||||
        }
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            if (player == null) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            MainUtil.sendMessage(player, C.NOT_IN_PLOT);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (arg != null) {
 | 
			
		||||
            if (args.length == 1) {
 | 
			
		||||
                args = new String[0];
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                args = new String[] { args[1] };
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if ((args.length == 1) && args[0].equalsIgnoreCase("inv")) {
 | 
			
		||||
            new InfoInventory(plot, player).build().display();
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        final boolean hasOwner = plot.hasOwner();
 | 
			
		||||
        boolean containsEveryone;
 | 
			
		||||
        boolean trustedEveryone;
 | 
			
		||||
        // Wildcard player {added}
 | 
			
		||||
        {
 | 
			
		||||
            containsEveryone = (plot.trusted != null) && plot.trusted.contains(DBFunc.everyone);
 | 
			
		||||
            trustedEveryone = (plot.members != null) && plot.members.contains(DBFunc.everyone);
 | 
			
		||||
        }
 | 
			
		||||
        // Unclaimed?
 | 
			
		||||
        if (!hasOwner && !containsEveryone && !trustedEveryone) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.PLOT_INFO_UNCLAIMED, (plot.id.x + ";" + plot.id.y));
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        String info = C.PLOT_INFO.s();
 | 
			
		||||
        if (arg != null) {
 | 
			
		||||
            info = getCaption(arg);
 | 
			
		||||
            if (info == null) {
 | 
			
		||||
                MainUtil.sendMessage(player, "&6Categories&7: &amembers&7, &aalias&7, &abiome&7, &adenied&7, &aflags&7, &aid&7, &asize&7, &atrusted&7, &aowner&7, &arating");
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            formatAndSend(info, plot.world, plot, player, true);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            formatAndSend(info, plot.world, plot, player, false);
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String getCaption(final String string) {
 | 
			
		||||
        switch (string) {
 | 
			
		||||
            case "trusted":
 | 
			
		||||
                return C.PLOT_INFO_TRUSTED.s();
 | 
			
		||||
            case "alias":
 | 
			
		||||
                return C.PLOT_INFO_ALIAS.s();
 | 
			
		||||
            case "biome":
 | 
			
		||||
                return C.PLOT_INFO_BIOME.s();
 | 
			
		||||
            case "denied":
 | 
			
		||||
                return C.PLOT_INFO_DENIED.s();
 | 
			
		||||
            case "flags":
 | 
			
		||||
                return C.PLOT_INFO_FLAGS.s();
 | 
			
		||||
            case "id":
 | 
			
		||||
                return C.PLOT_INFO_ID.s();
 | 
			
		||||
            case "size":
 | 
			
		||||
                return C.PLOT_INFO_SIZE.s();
 | 
			
		||||
            case "members":
 | 
			
		||||
                return C.PLOT_INFO_MEMBERS.s();
 | 
			
		||||
            case "owner":
 | 
			
		||||
                return C.PLOT_INFO_OWNER.s();
 | 
			
		||||
            case "rating":
 | 
			
		||||
                return C.PLOT_INFO_RATING.s();
 | 
			
		||||
            default:
 | 
			
		||||
                return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void formatAndSend(String info, final String world, final Plot plot, final PlotPlayer player, final boolean full) {
 | 
			
		||||
        final PlotId id = plot.id;
 | 
			
		||||
        final PlotId id2 = MainUtil.getTopPlot(plot).id;
 | 
			
		||||
        final int num = MainUtil.getPlotSelectionIds(id, id2).size();
 | 
			
		||||
        final String alias = plot.settings.getAlias().length() > 0 ? plot.settings.getAlias() : C.NONE.s();
 | 
			
		||||
        Location top = MainUtil.getPlotTopLoc(world, plot.id);
 | 
			
		||||
        Location bot = MainUtil.getPlotBottomLoc(world, plot.id).add(1,0,1);
 | 
			
		||||
        final String biome = BlockManager.manager.getBiome(bot.add((top.getX() - bot.getX()) / 2, 0, (top.getX() - bot.getX()) / 2));
 | 
			
		||||
        final String trusted = getPlayerList(plot.trusted);
 | 
			
		||||
        final String members = getPlayerList(plot.members);
 | 
			
		||||
        final String denied = getPlayerList(plot.denied);
 | 
			
		||||
 | 
			
		||||
        final String flags = StringMan.replaceFromMap("$2" + (StringUtils.join(FlagManager.getPlotFlags(plot).values(), "").length() > 0 ? StringUtils.join(FlagManager.getPlotFlags(plot).values(), "$1, $2") : C.NONE.s()), C.replacements);
 | 
			
		||||
        final boolean build = (player == null) || plot.isAdded(player.getUUID());
 | 
			
		||||
 | 
			
		||||
        String owner = plot.owner == null ? "unowned" : getPlayerList(plot.getOwners());
 | 
			
		||||
 | 
			
		||||
        info = info.replaceAll("%alias%", alias);
 | 
			
		||||
        info = info.replaceAll("%id%", id.toString());
 | 
			
		||||
        info = info.replaceAll("%id2%", id2.toString());
 | 
			
		||||
        info = info.replaceAll("%num%", num + "");
 | 
			
		||||
        info = info.replaceAll("%biome%", biome);
 | 
			
		||||
        info = info.replaceAll("%owner%", owner);
 | 
			
		||||
        info = info.replaceAll("%members%", members);
 | 
			
		||||
        info = info.replaceAll("%trusted%", trusted);
 | 
			
		||||
        info = info.replaceAll("%helpers%", members);
 | 
			
		||||
        info = info.replaceAll("%denied%", denied);
 | 
			
		||||
        info = info.replaceAll("%flags%", Matcher.quoteReplacement(flags));
 | 
			
		||||
        info = info.replaceAll("%build%", build + "");
 | 
			
		||||
        info = info.replaceAll("%desc%", "No description set.");
 | 
			
		||||
        if (info.contains("%rating%")) {
 | 
			
		||||
            final String newInfo = info;
 | 
			
		||||
            TaskManager.runTaskAsync(new Runnable() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
                    int max = 10;
 | 
			
		||||
                    if (Settings.RATING_CATEGORIES != null && Settings.RATING_CATEGORIES.size() > 0) {
 | 
			
		||||
                        max = 8;
 | 
			
		||||
                    }
 | 
			
		||||
                    String info;
 | 
			
		||||
                    if (full && Settings.RATING_CATEGORIES != null && Settings.RATING_CATEGORIES.size() > 1) {
 | 
			
		||||
                        String rating = "";
 | 
			
		||||
                        String prefix = "";
 | 
			
		||||
                        double[] ratings = MainUtil.getAverageRatings(plot);
 | 
			
		||||
                        for (int i = 0; i < ratings.length; i++) {
 | 
			
		||||
                            rating += prefix + Settings.RATING_CATEGORIES.get(i) + "=" + String.format("%.1f", ratings[i]);
 | 
			
		||||
                            prefix = ",";
 | 
			
		||||
                        }
 | 
			
		||||
                        info = newInfo.replaceAll("%rating%", rating);
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        info = newInfo.replaceAll("%rating%", String.format("%.1f", MainUtil.getAverageRating(plot)) + "/" + max);
 | 
			
		||||
                    }
 | 
			
		||||
                    MainUtil.sendMessage(player, C.PLOT_INFO_HEADER);
 | 
			
		||||
                    MainUtil.sendMessage(player, info, false);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.sendMessage(player, C.PLOT_INFO_HEADER);
 | 
			
		||||
        MainUtil.sendMessage(player, info, false);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,73 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.ChatColor;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.bukkit.inventory.meta.ItemMeta;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.BukkitPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
 | 
			
		||||
public class Inventory extends SubCommand {
 | 
			
		||||
    public Inventory() {
 | 
			
		||||
        super("inventory", "plots.inventory", "Open a command inventory", "inventory", "inv", CommandCategory.INFO, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        final ArrayList<SubCommand> cmds = new ArrayList<>();
 | 
			
		||||
        for (final SubCommand cmd : MainCommand.subCommands) {
 | 
			
		||||
            if (cmd.permission.hasPermission(plr)) {
 | 
			
		||||
                cmds.add(cmd);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        final int size = 9 * (int) Math.ceil(cmds.size() / 9.0);
 | 
			
		||||
        final org.bukkit.inventory.Inventory inventory = Bukkit.createInventory(null, size, "PlotSquared Commands");
 | 
			
		||||
        for (final SubCommand cmd : cmds) {
 | 
			
		||||
            inventory.addItem(getItem(cmd));
 | 
			
		||||
        }
 | 
			
		||||
        ((BukkitPlayer) plr).player.openInventory(inventory);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ItemStack getItem(final SubCommand cmd) {
 | 
			
		||||
        final ItemStack stack = new ItemStack(Material.COMMAND);
 | 
			
		||||
        final ItemMeta meta = stack.getItemMeta();
 | 
			
		||||
        {
 | 
			
		||||
            meta.setDisplayName(ChatColor.GREEN + cmd.cmd + ChatColor.DARK_GRAY + " [" + ChatColor.GREEN + cmd.alias + ChatColor.DARK_GRAY + "]");
 | 
			
		||||
            meta.setLore(new ArrayList<String>() {
 | 
			
		||||
                {
 | 
			
		||||
                    add(C.INVENTORY_CATEGORY.s().replace("{category}", cmd.category.toString()));
 | 
			
		||||
                    add(C.INVENTORY_DESC.s().replace("{desc}", cmd.description));
 | 
			
		||||
                    add(C.INVENTORY_USAGE.s().replace("{usage}", "/plot " + cmd.usage));
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        stack.setItemMeta(meta);
 | 
			
		||||
        return stack;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,66 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.BlockManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
 | 
			
		||||
@SuppressWarnings({ "unused", "deprecation", "javadoc" })
 | 
			
		||||
public class Kick extends SubCommand {
 | 
			
		||||
    public Kick() {
 | 
			
		||||
        super(Command.KICK, "Kick a player from your plot", "kick", CommandCategory.ACTIONS, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        final Location loc = plr.getLocation();
 | 
			
		||||
        final Plot plot = MainUtil.getPlot(loc);
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            return !sendMessage(plr, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        if (plot == null || ((!plot.hasOwner() || !plot.isOwner(plr.getUUID())) && !Permissions.hasPermission(plr, "plots.admin.command.kick"))) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NO_PLOT_PERMS);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (args.length != 1) {
 | 
			
		||||
            MainUtil.sendMessage(plr, "&c/plot kick <player>");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final PlotPlayer player = UUIDHandler.getPlayer(args[0]);
 | 
			
		||||
        if (player == null) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.INVALID_PLAYER, args[0]);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        Location otherLoc = player.getLocation();
 | 
			
		||||
        if (!plr.getLocation().getWorld().equals(otherLoc.getWorld()) || !plot.equals(MainUtil.getPlot(otherLoc))) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.INVALID_PLAYER, args[0]);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        player.teleport(BlockManager.manager.getSpawn(loc.getWorld()));
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,193 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.StringComparison;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * PlotSquared command class
 | 
			
		||||
 *
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 */
 | 
			
		||||
public class MainCommand {
 | 
			
		||||
    /**
 | 
			
		||||
     * Main Permission Node
 | 
			
		||||
     */
 | 
			
		||||
    private final static SubCommand[] _subCommands = new SubCommand[] {  };
 | 
			
		||||
    public final static ArrayList<SubCommand> subCommands = new ArrayList<SubCommand>() {
 | 
			
		||||
        {
 | 
			
		||||
            addAll(Arrays.asList(_subCommands));
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    public static boolean no_permission(final PlotPlayer player, final String permission) {
 | 
			
		||||
        MainUtil.sendMessage(player, C.NO_PERMISSION, permission);
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public static List<SubCommand> getCommands(final SubCommand.CommandCategory category, final PlotPlayer player) {
 | 
			
		||||
        final List<SubCommand> cmds = new ArrayList<>();
 | 
			
		||||
        for (final SubCommand c : subCommands) {
 | 
			
		||||
            if (!c.isPlayer || (player != null)) {
 | 
			
		||||
                if ((c.category.equals(category)) && c.permission.hasPermission(player)) {
 | 
			
		||||
                    cmds.add(c);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return cmds;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public static List<String> helpMenu(final PlotPlayer player, final SubCommand.CommandCategory category, int page) {
 | 
			
		||||
        List<SubCommand> commands;
 | 
			
		||||
        if (category != null) {
 | 
			
		||||
            commands = getCommands(category, player);
 | 
			
		||||
        } else {
 | 
			
		||||
            commands = subCommands;
 | 
			
		||||
        }
 | 
			
		||||
        // final int totalPages = ((int) Math.ceil(12 * (commands.size()) /
 | 
			
		||||
        // 100));
 | 
			
		||||
        final int perPage = 5;
 | 
			
		||||
        final int totalPages = (commands.size() / perPage) + (commands.size() % perPage == 0 ? 0 : 1);
 | 
			
		||||
        if (page > totalPages) {
 | 
			
		||||
            page = totalPages;
 | 
			
		||||
        }
 | 
			
		||||
        int max = (page * perPage) + perPage;
 | 
			
		||||
        if (max > commands.size()) {
 | 
			
		||||
            max = commands.size();
 | 
			
		||||
        }
 | 
			
		||||
        final List<String> help = new ArrayList<>();
 | 
			
		||||
        help.add(C.HELP_HEADER.s());
 | 
			
		||||
        // HELP_CATEGORY("&cCategory: &6%category%&c, Page: %current%&c/&6%max%&c, Displaying: &6%dis%&c/&6%total%"),
 | 
			
		||||
        help.add(C.HELP_CATEGORY.s().replace("%category%", category == null ? "All" : category.toString()).replace("%current%", "" + (page + 1)).replace("%max%", "" + (totalPages)).replace("%dis%", "" + (commands.size() % perPage)).replace("%total%", "" + commands.size()));
 | 
			
		||||
        SubCommand cmd;
 | 
			
		||||
        final int start = page * perPage;
 | 
			
		||||
        for (int x = start; x < max; x++) {
 | 
			
		||||
            cmd = commands.get(x);
 | 
			
		||||
            String s = t(C.HELP_ITEM.s());
 | 
			
		||||
            if (cmd.alias.size() > 0) {
 | 
			
		||||
                s = s.replace("%alias%", cmd.alias.get(0));
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                s = s.replace("%alias%", "");
 | 
			
		||||
            }
 | 
			
		||||
            s = s.replace("%usage%", cmd.usage.contains("plot") ? cmd.usage : "/plot " + cmd.usage).replace("%cmd%", cmd.cmd).replace("%desc%", cmd.description).replace("[]", "");
 | 
			
		||||
            help.add(s);
 | 
			
		||||
        }
 | 
			
		||||
        if (help.size() < 2) {
 | 
			
		||||
            help.add(t(C.NO_COMMANDS.s()));
 | 
			
		||||
        }
 | 
			
		||||
        return help;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static String t(final String s) {
 | 
			
		||||
        return MainUtil.colorise('&', s);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public static boolean onCommand(final PlotPlayer player, final String cmd, final String... args) {
 | 
			
		||||
        if ((args.length < 1) || ((args.length >= 1) && (args[0].equalsIgnoreCase("help") || args[0].equalsIgnoreCase("he")))) {
 | 
			
		||||
            if (args.length < 2) {
 | 
			
		||||
                final StringBuilder builder = new StringBuilder();
 | 
			
		||||
                builder.append(C.HELP_INFO.s());
 | 
			
		||||
                for (final SubCommand.CommandCategory category : SubCommand.CommandCategory.values()) {
 | 
			
		||||
                    builder.append("\n").append(C.HELP_INFO_ITEM.s().replaceAll("%category%", category.toString().toLowerCase()).replaceAll("%category_desc%", category.toString()));
 | 
			
		||||
                }
 | 
			
		||||
                builder.append("\n").append(C.HELP_INFO_ITEM.s().replaceAll("%category%", "all").replaceAll("%category_desc%", "Display all commands"));
 | 
			
		||||
                return MainUtil.sendMessage(player, builder.toString());
 | 
			
		||||
            }
 | 
			
		||||
            final String cat = args[1];
 | 
			
		||||
            SubCommand.CommandCategory cato = null;
 | 
			
		||||
            for (final SubCommand.CommandCategory category : SubCommand.CommandCategory.values()) {
 | 
			
		||||
                if (cat.equalsIgnoreCase(category.toString())) {
 | 
			
		||||
                    cato = category;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if ((cato == null) && !cat.equalsIgnoreCase("all")) {
 | 
			
		||||
                final StringBuilder builder = new StringBuilder();
 | 
			
		||||
                builder.append(C.HELP_INFO.s());
 | 
			
		||||
                for (final SubCommand.CommandCategory category : SubCommand.CommandCategory.values()) {
 | 
			
		||||
                    builder.append("\n").append(C.HELP_INFO_ITEM.s().replaceAll("%category%", category.toString().toLowerCase()).replaceAll("%category_desc%", category.toString()));
 | 
			
		||||
                }
 | 
			
		||||
                return MainUtil.sendMessage(player, builder.toString(), false);
 | 
			
		||||
            }
 | 
			
		||||
            final StringBuilder help = new StringBuilder();
 | 
			
		||||
            int page = 0;
 | 
			
		||||
            boolean digit = true;
 | 
			
		||||
            String arg2;
 | 
			
		||||
            if (args.length > 2) {
 | 
			
		||||
                arg2 = args[2];
 | 
			
		||||
            } else {
 | 
			
		||||
                arg2 = "1";
 | 
			
		||||
            }
 | 
			
		||||
            for (final char c : arg2.toCharArray()) {
 | 
			
		||||
                if (!Character.isDigit(c)) {
 | 
			
		||||
                    digit = false;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (digit) {
 | 
			
		||||
                page = Integer.parseInt(arg2);
 | 
			
		||||
                if (--page < 0) {
 | 
			
		||||
                    page = 0;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            for (final String string : helpMenu(player, cato, page)) {
 | 
			
		||||
                help.append(string).append("\n");
 | 
			
		||||
            }
 | 
			
		||||
            MainUtil.sendMessage(player, help.toString());
 | 
			
		||||
            // return PlayerFunctions.sendMessage(player, help.toString());
 | 
			
		||||
        } else {
 | 
			
		||||
            for (final SubCommand command : subCommands) {
 | 
			
		||||
                if (command.cmd.equalsIgnoreCase(args[0]) || command.alias.contains(args[0].toLowerCase())) {
 | 
			
		||||
                    final String[] arguments = new String[args.length - 1];
 | 
			
		||||
                    System.arraycopy(args, 1, arguments, 0, args.length - 1);
 | 
			
		||||
                    if (command.permission.hasPermission(player)) {
 | 
			
		||||
                        if ((player != null) || !command.isPlayer) {
 | 
			
		||||
                            return command.execute(player, arguments);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            return !MainUtil.sendMessage(null, C.IS_CONSOLE);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return no_permission(player, command.permission.permission.toLowerCase());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            MainUtil.sendMessage(player, C.NOT_VALID_SUBCOMMAND);
 | 
			
		||||
            final String[] commands = new String[subCommands.size()];
 | 
			
		||||
            for (int x = 0; x < subCommands.size(); x++) {
 | 
			
		||||
                commands[x] = subCommands.get(x).cmd;
 | 
			
		||||
            }
 | 
			
		||||
            /* Let's try to get a proper usage string */
 | 
			
		||||
            final String command = new StringComparison(args[0], commands).getBestMatch();
 | 
			
		||||
            return MainUtil.sendMessage(player, C.DID_YOU_MEAN, "/plot " + command);
 | 
			
		||||
            // PlayerFunctions.sendMessage(player, C.DID_YOU_MEAN, new
 | 
			
		||||
            // StringComparsion(args[0], commands).getBestMatch());
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										231
									
								
								src/main/java/com/intellectualcrafters/plot/commands/Merge.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								src/main/java/com/intellectualcrafters/plot/commands/Merge.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,231 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.lang.StringUtils;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.util.CmdConfirm;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EconHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EventUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Citymonstret
 | 
			
		||||
 */
 | 
			
		||||
public class Merge extends SubCommand {
 | 
			
		||||
    public final static String[] values = new String[] { "north", "east", "south", "west" };
 | 
			
		||||
    public final static String[] aliases = new String[] { "n", "e", "s", "w" };
 | 
			
		||||
 | 
			
		||||
    public Merge() {
 | 
			
		||||
        super(Command.MERGE, "Merge the plot you are standing on with another plot.", "merge", CommandCategory.ACTIONS, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String direction(float yaw) {
 | 
			
		||||
        yaw = yaw / 90;
 | 
			
		||||
        final int i = Math.round(yaw);
 | 
			
		||||
        switch (i) {
 | 
			
		||||
            case -4:
 | 
			
		||||
            case 0:
 | 
			
		||||
            case 4:
 | 
			
		||||
                return "SOUTH";
 | 
			
		||||
            case -1:
 | 
			
		||||
            case 3:
 | 
			
		||||
                return "EAST";
 | 
			
		||||
            case -2:
 | 
			
		||||
            case 2:
 | 
			
		||||
                return "NORTH";
 | 
			
		||||
            case -3:
 | 
			
		||||
            case 1:
 | 
			
		||||
                return "WEST";
 | 
			
		||||
            default:
 | 
			
		||||
                return "";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        final Location loc = plr.getLocationFull();
 | 
			
		||||
        final Plot plot = MainUtil.getPlot(loc);
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            return !sendMessage(plr, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        if ((plot == null) || !plot.hasOwner()) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.PLOT_UNOWNED);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final boolean admin = Permissions.hasPermission(plr, "plots.admin.command.merge");
 | 
			
		||||
        if (!plot.isOwner(plr.getUUID()) && !admin) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NO_PLOT_PERMS);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (args.length < 1) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.SUBCOMMAND_SET_OPTIONS_HEADER.s() + StringUtils.join(values, C.BLOCK_LIST_SEPARATER.s()));
 | 
			
		||||
            MainUtil.sendMessage(plr, C.DIRECTION.s().replaceAll("%dir%", direction(loc.getYaw())));
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        int direction = -1;
 | 
			
		||||
        for (int i = 0; i < values.length; i++) {
 | 
			
		||||
            if (args[0].equalsIgnoreCase(values[i]) || args[0].equalsIgnoreCase(aliases[i])) {
 | 
			
		||||
                direction = i;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (direction == -1) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.SUBCOMMAND_SET_OPTIONS_HEADER.s() + StringUtils.join(values, C.BLOCK_LIST_SEPARATER.s()));
 | 
			
		||||
            MainUtil.sendMessage(plr, C.DIRECTION.s().replaceAll("%dir%", direction(loc.getYaw())));
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        PlotId bot = MainUtil.getBottomPlot(plot).id;
 | 
			
		||||
        PlotId top = MainUtil.getTopPlot(plot).id;
 | 
			
		||||
        ArrayList<PlotId> selPlots;
 | 
			
		||||
        final String world = loc.getWorld();
 | 
			
		||||
        switch (direction) {
 | 
			
		||||
            case 0: // north = -y
 | 
			
		||||
                selPlots = MainUtil.getMaxPlotSelectionIds(world, new PlotId(bot.x, bot.y - 1), new PlotId(top.x, top.y));
 | 
			
		||||
                break;
 | 
			
		||||
            case 1: // east = +x
 | 
			
		||||
                selPlots = MainUtil.getMaxPlotSelectionIds(world, new PlotId(bot.x, bot.y), new PlotId(top.x + 1, top.y));
 | 
			
		||||
                break;
 | 
			
		||||
            case 2: // south = +y
 | 
			
		||||
                selPlots = MainUtil.getMaxPlotSelectionIds(world, new PlotId(bot.x, bot.y), new PlotId(top.x, top.y + 1));
 | 
			
		||||
                break;
 | 
			
		||||
            case 3: // west = -x
 | 
			
		||||
                selPlots = MainUtil.getMaxPlotSelectionIds(world, new PlotId(bot.x - 1, bot.y), new PlotId(top.x, top.y));
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
        final PlotId botId = selPlots.get(0);
 | 
			
		||||
        final PlotId topId = selPlots.get(selPlots.size() - 1);
 | 
			
		||||
        final PlotId bot1 = MainUtil.getBottomPlot(MainUtil.getPlot(world, botId)).id;
 | 
			
		||||
        final PlotId bot2 = MainUtil.getBottomPlot(MainUtil.getPlot(world, topId)).id;
 | 
			
		||||
        final PlotId top1 = MainUtil.getTopPlot(MainUtil.getPlot(world, topId)).id;
 | 
			
		||||
        final PlotId top2 = MainUtil.getTopPlot(MainUtil.getPlot(world, botId)).id;
 | 
			
		||||
        bot = new PlotId(Math.min(bot1.x, bot2.x), Math.min(bot1.y, bot2.y));
 | 
			
		||||
        top = new PlotId(Math.max(top1.x, top2.x), Math.max(top1.y, top2.y));
 | 
			
		||||
        final ArrayList<PlotId> plots = MainUtil.getMaxPlotSelectionIds(world, bot, top);
 | 
			
		||||
        boolean multiMerge = false;
 | 
			
		||||
        final HashSet<UUID> multiUUID = new HashSet<UUID>();
 | 
			
		||||
        HashSet<PlotId> multiPlots = new HashSet<>();
 | 
			
		||||
        final UUID u1 = plot.owner;
 | 
			
		||||
        for (final PlotId myid : plots) {
 | 
			
		||||
            final Plot myplot = PS.get().getPlots(world).get(myid);
 | 
			
		||||
            if (myplot == null || myplot.owner == null) {
 | 
			
		||||
                MainUtil.sendMessage(plr, C.NO_PERM_MERGE.s().replaceAll("%plot%", myid.toString()));
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            UUID u2 = myplot.owner;
 | 
			
		||||
            if (u2.equals(u1)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            PlotPlayer p2 = UUIDHandler.getPlayer(u2);
 | 
			
		||||
            if (p2 == null) {
 | 
			
		||||
                MainUtil.sendMessage(plr, C.NO_PERM_MERGE.s().replaceAll("%plot%", myid.toString()));
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            multiMerge = true;
 | 
			
		||||
            multiPlots.add(myid);
 | 
			
		||||
            multiUUID.add(u2);
 | 
			
		||||
        }
 | 
			
		||||
        if (multiMerge) {
 | 
			
		||||
            if (!Permissions.hasPermission(plr, Permissions.MERGE_OTHER)) {
 | 
			
		||||
                MainUtil.sendMessage(plr, C.NO_PERMISSION, Permissions.MERGE_OTHER.s);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            for (final UUID uuid : multiUUID) {
 | 
			
		||||
                PlotPlayer accepter = UUIDHandler.getPlayer(uuid);
 | 
			
		||||
                CmdConfirm.addPending(accepter, C.MERGE_REQUEST_CONFIRM.s().replaceAll("%s", plr.getName()), new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        PlotPlayer accepter = UUIDHandler.getPlayer(uuid);
 | 
			
		||||
                        multiUUID.remove(uuid);
 | 
			
		||||
                        if (multiUUID.size() == 0) {
 | 
			
		||||
                            PlotPlayer pp = UUIDHandler.getPlayer(u1);
 | 
			
		||||
                            if (pp == null) {
 | 
			
		||||
                                sendMessage(accepter, C.MERGE_NOT_VALID);
 | 
			
		||||
                                return;
 | 
			
		||||
                            }
 | 
			
		||||
                            final PlotWorld plotWorld = PS.get().getPlotWorld(world);
 | 
			
		||||
                            if ((EconHandler.manager != null) && plotWorld.USE_ECONOMY) {
 | 
			
		||||
                                double cost = plotWorld.MERGE_PRICE;
 | 
			
		||||
                                cost = plots.size() * cost;
 | 
			
		||||
                                if (cost > 0d) {
 | 
			
		||||
                                    if (EconHandler.manager.getMoney(plr) < cost) {
 | 
			
		||||
                                        sendMessage(plr, C.CANNOT_AFFORD_MERGE, cost + "");
 | 
			
		||||
                                        return;
 | 
			
		||||
                                    }
 | 
			
		||||
                                    EconHandler.manager.withdrawMoney(plr, cost);
 | 
			
		||||
                                    sendMessage(plr, C.REMOVED_BALANCE, cost + "");
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            final boolean result = EventUtil.manager.callMerge(world, plot, plots);
 | 
			
		||||
                            if (!result) {
 | 
			
		||||
                                MainUtil.sendMessage(plr, "&cMerge has been cancelled");
 | 
			
		||||
                                return;
 | 
			
		||||
                            }
 | 
			
		||||
                            MainUtil.sendMessage(plr, C.SUCCESS_MERGE);
 | 
			
		||||
                            MainUtil.mergePlots(world, plots, true);
 | 
			
		||||
                            MainUtil.setSign(UUIDHandler.getName(plot.owner), plot);
 | 
			
		||||
                        }
 | 
			
		||||
                        MainUtil.sendMessage(accepter, C.MERGE_ACCEPTED);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            MainUtil.sendMessage(plr, C.MERGE_REQUESTED);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        final PlotWorld plotWorld = PS.get().getPlotWorld(world);
 | 
			
		||||
        if ((EconHandler.manager != null) && plotWorld.USE_ECONOMY) {
 | 
			
		||||
            double cost = plotWorld.MERGE_PRICE;
 | 
			
		||||
            cost = plots.size() * cost;
 | 
			
		||||
            if (cost > 0d) {
 | 
			
		||||
                if (EconHandler.manager.getMoney(plr) < cost) {
 | 
			
		||||
                    sendMessage(plr, C.CANNOT_AFFORD_MERGE, cost + "");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                EconHandler.manager.withdrawMoney(plr, cost);
 | 
			
		||||
                sendMessage(plr, C.REMOVED_BALANCE, cost + "");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        final boolean result = EventUtil.manager.callMerge(world, plot, plots);
 | 
			
		||||
        if (!result) {
 | 
			
		||||
            MainUtil.sendMessage(plr, "&cMerge has been cancelled");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        MainUtil.sendMessage(plr, C.SUCCESS_MERGE);
 | 
			
		||||
        MainUtil.mergePlots(world, plots, true);
 | 
			
		||||
        MainUtil.setSign(UUIDHandler.getName(plot.owner), plot);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,98 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// PlotSquared - A plot manager and world generator for the Bukkit API                             /
 | 
			
		||||
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters                                       /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// 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, write to the Free Software Foundation,                         /
 | 
			
		||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA                               /
 | 
			
		||||
//                                                                                                 /
 | 
			
		||||
// You can contact us via: support@intellectualsites.com                                           /
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created 2014-08-01 for PlotSquared
 | 
			
		||||
 *
 | 
			
		||||
 * @author Empire92
 | 
			
		||||
 */
 | 
			
		||||
public class Move extends SubCommand {
 | 
			
		||||
    public Move() {
 | 
			
		||||
        super(Command.MOVE, "Move a plot", "debugmove", CommandCategory.ACTIONS, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean execute(final PlotPlayer plr, final String... args) {
 | 
			
		||||
        if (args.length < 1) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NEED_PLOT_ID);
 | 
			
		||||
            MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot move <X;Z>");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final Location loc = plr.getLocation();
 | 
			
		||||
        final Plot plot1 = MainUtil.getPlot(loc);
 | 
			
		||||
        if (plot1 == null) {
 | 
			
		||||
            return !sendMessage(plr, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        if (!plot1.isAdded(plr.getUUID()) && !plr.hasPermission(Permissions.ADMIN.s))  {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NO_PLOT_PERMS);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final String world = loc.getWorld();
 | 
			
		||||
        final PlotId plot2id = MainUtil.parseId(args[0]);
 | 
			
		||||
        if ((plot2id == null)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_ID);
 | 
			
		||||
            MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot move <X;Z>");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        String world2;
 | 
			
		||||
        if (args.length == 2) {
 | 
			
		||||
            PlotWorld other = PS.get().getPlotWorld(args[1]);
 | 
			
		||||
            PlotWorld current = PS.get().getPlotWorld(loc.getWorld());
 | 
			
		||||
            if (other == null || current == null || !other.equals(current)) {
 | 
			
		||||
                MainUtil.sendMessage(plr, C.PLOTWORLD_INCOMPATIBLE);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        	world2 = other.worldname;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
        	world2 = world;
 | 
			
		||||
        }
 | 
			
		||||
        Plot plot2 = MainUtil.getPlot(world2, plot2id);
 | 
			
		||||
        
 | 
			
		||||
        if (plot1.equals(plot2)) {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_ID);
 | 
			
		||||
            MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot move <X;Z>");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (MainUtil.move(plot1, plot2, new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                MainUtil.sendMessage(plr, C.MOVE_SUCCESS);
 | 
			
		||||
            }
 | 
			
		||||
        })) {
 | 
			
		||||
            return true;
 | 
			
		||||
        } else {
 | 
			
		||||
            MainUtil.sendMessage(plr, C.REQUIRES_UNOWNED);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user