diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..fd88ec9638
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,31 @@
+# Eclipse stuff
+/.classpath
+/.project
+/.settings
+
+# netbeans
+/nbproject
+
+# we use maven!
+/build.xml
+
+# maven
+/target
+
+# vim
+.*.sw[a-p]
+
+# various other potential build files
+/build
+/bin
+/dist
+/manifest.mf
+
+# Mac filesystem dust
+/.DS_Store
+
+# intellij
+*.iml
+*.ipr
+*.iws
+.idea/
\ No newline at end of file
diff --git a/img/marker-16.png b/img/marker-16.png
new file mode 100644
index 0000000000..5e4369a883
Binary files /dev/null and b/img/marker-16.png differ
diff --git a/img/marker.png b/img/marker.png
new file mode 100644
index 0000000000..0b0c059391
Binary files /dev/null and b/img/marker.png differ
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000000..7c109916d2
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,102 @@
+
+ 4.0.0
+ de.xzise.bukkit
+ xWarp
+ 3.1.7
+ xWarp
+
+
+ org.bukkit
+ bukkit
+ 1.1-R6
+
+
+ de.xzise.bukkitutil
+ bukkitutil
+ 1.3.0
+
+
+ org.dynmap
+ DynmapCoreAPI
+ 0.33
+
+
+
+
+
+
+ src/main/resources
+ true
+
+ *.yml
+
+
+
+ src/main/resources
+ false
+
+ *.yml
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ src/main/assembly/package.xml
+
+
+
+ 420
+ 493
+ 493
+
+
+
+
+ build
+ package
+
+ single
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.3.2
+
+ 1.6
+ 1.6
+ UTF-8
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 2.4.3
+
+ UTF-8
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.3.1
+
+
+
+ ../lib/BukkitPluginUtilities.jar
+ ../lib/sqlitejdbc-v056.jar
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/MANIFEST.MF b/src/MANIFEST.MF
deleted file mode 100644
index 617dc2d514..0000000000
--- a/src/MANIFEST.MF
+++ /dev/null
@@ -1,2 +0,0 @@
-Manifest-Version: 1.0
-Class-Path: ../sqlitejdbc-v056.jar
diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..f89767ebda
--- /dev/null
+++ b/src/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Class-Path: ../lib/sqlitejdbc-v056.jar
diff --git a/src/main/assembly/package.xml b/src/main/assembly/package.xml
new file mode 100644
index 0000000000..0d1cbaae53
--- /dev/null
+++ b/src/main/assembly/package.xml
@@ -0,0 +1,22 @@
+
+ bin
+ false
+
+ zip
+
+
+
+ ${project.build.directory}/${artifactId}-${version}.jar
+ /
+ xWarp.jar
+
+
+ ${project.basedir}/img/marker-16.png
+ /xWarp/
+ marker.png
+
+
+
\ No newline at end of file
diff --git a/src/main/java/de/xzise/metainterfaces/FixedLocation.java b/src/main/java/de/xzise/metainterfaces/FixedLocation.java
new file mode 100644
index 0000000000..094bf263e5
--- /dev/null
+++ b/src/main/java/de/xzise/metainterfaces/FixedLocation.java
@@ -0,0 +1,149 @@
+package de.xzise.metainterfaces;
+
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.block.Block;
+import org.bukkit.util.Vector;
+
+/**
+ * A class which acts like a normal location, but is immutable.
+ * @author Fabian Neundorf
+ */
+public class FixedLocation implements Moveable {
+
+ public final World world;
+ public final double x;
+ public final double y;
+ public final double z;
+ public final float pitch;
+ public final float yaw;
+
+ public FixedLocation(Location location) {
+ this(location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
+ }
+
+ public FixedLocation(final double x, final double y, final double z) {
+ this((World) null, x, y, z);
+ }
+
+ public FixedLocation(final World world, final double x, final double y, final double z) {
+ this(world, x, y, z, 0, 0);
+ }
+
+ public FixedLocation(final World world, final double x, final double y, final double z, final float yaw, final float pitch) {
+ this.world = world;
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.pitch = pitch;
+ this.yaw = yaw;
+ }
+
+ public FixedLocation(FixedLocation location, double xDelta, double yDelta, double zDelta) {
+ this(location.world, location.x + xDelta, location.y + yDelta, location.z + zDelta, location.yaw, location.pitch);
+ }
+
+ public Location toLocation() {
+ return new Location(this.world, this.x, this.y, this.z, this.yaw, this.pitch);
+ }
+
+ /**
+ * Gets the block at the represented location
+ *
+ * @return Block at the represented location
+ */
+ public Block getBlock() {
+ return world.getBlockAt(this.getBlockX(), this.getBlockY(), this.getBlockZ());
+ }
+
+ /**
+ * Gets the floored value of the X component, indicating the block that
+ * this location is contained with.
+ *
+ * @return block X
+ */
+ public int getBlockX() {
+ return Location.locToBlock(x);
+ }
+
+ /**
+ * Gets the floored value of the Y component, indicating the block that
+ * this location is contained with.
+ *
+ * @return block y
+ */
+ public int getBlockY() {
+ return Location.locToBlock(y);
+ }
+
+ /**
+ * Gets the floored value of the Z component, indicating the block that
+ * this location is contained with.
+ *
+ * @return block z
+ */
+ public int getBlockZ() {
+ return Location.locToBlock(z);
+ }
+
+ /**
+ * Gets a Vector pointing in the direction that this Location is facing
+ *
+ * @return Vector
+ */
+ public Vector getDirection() {
+ return getDirection(this.yaw, this.pitch);
+ }
+
+ /**
+ * Constructs a new {@link Vector} based on this Location
+ *
+ * @return New Vector containing the coordinates represented by this Location
+ */
+ public Vector toVector() {
+ return new Vector(x, y, z);
+ }
+
+ /**
+ * Gets a Vector pointing in the direction that this Location is facing
+ *
+ * @param yaw The rotation at the x-axis in degrees.
+ * @param pitch The rotation at the z-axis in degrees.
+ *
+ * @return Vector
+ */
+ public static Vector getDirection(double yaw, double pitch) {
+ Vector vector = new Vector();
+
+ double rotX = Math.toRadians(yaw);
+ double rotY = Math.toRadians(pitch);
+
+ vector.setY(-Math.sin(rotY));
+
+ double h = Math.cos(rotY);
+ vector.setX(-h*Math.sin(rotX));
+ vector.setZ(h*Math.cos(rotX));
+
+ return vector;
+ }
+
+ public FixedLocation move(double xDelta, double yDelta, double zDelta) {
+ return new FixedLocation(this, xDelta, yDelta, zDelta);
+ }
+
+ @Override
+ public FixedLocation moveX(double delta) {
+ return this.move(delta, 0, 0);
+ }
+
+ @Override
+ public FixedLocation moveY(double delta) {
+ return this.move(0, delta, 0);
+ }
+
+ @Override
+ public FixedLocation moveZ(double delta) {
+ return this.move(0, 0, delta);
+ }
+
+}
diff --git a/src/main/java/de/xzise/metainterfaces/LocationWrapper.java b/src/main/java/de/xzise/metainterfaces/LocationWrapper.java
new file mode 100644
index 0000000000..5d3b522be6
--- /dev/null
+++ b/src/main/java/de/xzise/metainterfaces/LocationWrapper.java
@@ -0,0 +1,96 @@
+package de.xzise.metainterfaces;
+
+import org.bukkit.Location;
+import org.bukkit.World;
+
+public class LocationWrapper implements Moveable {
+
+ private FixedLocation location;
+ private String worldName;
+
+ public LocationWrapper(Location location) {
+ this(new FixedLocation(location));
+ }
+
+ public LocationWrapper(FixedLocation location) {
+ this(location, location.world.getName());
+ }
+
+ public LocationWrapper(FixedLocation location, String world) {
+ this.location = location;
+ this.worldName = this.location.world != null ? location.world.getName() : world;
+ if (worldName == null) {
+ throw new IllegalArgumentException("Nullary world got.");
+ }
+ }
+
+ public static Location moveX(Location location, double delta) {
+ location.setX(location.getX() + delta);
+ return location;
+ }
+
+ public static Location moveY(Location location, double delta) {
+ location.setY(location.getY() + delta);
+ return location;
+ }
+
+ public static Location moveZ(Location location, double delta) {
+ location.setZ(location.getZ() + delta);
+ return location;
+ }
+
+ public boolean setWorld(World world) {
+ if (world != null && this.location.world == null && world.getName().equals(this.worldName)) {
+ this.updateLocation(world);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public boolean unsetWorld(World world) {
+ if (this.location.world == world && world != null) {
+ this.updateLocation(null);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private void updateLocation(World world) {
+ this.location = new FixedLocation(world, this.location.x, this.location.y, this.location.z, this.location.yaw, this.location.pitch);
+ }
+
+ public FixedLocation getLocation() {
+ return this.location;
+ }
+
+ public String getWorld() {
+ return this.worldName;
+ }
+
+ public void setWorld(String worldName, World world) {
+ this.worldName = worldName;
+ this.updateLocation(world);
+ }
+
+ public boolean isValid() {
+ return this.location.world != null;
+ }
+
+ @Override
+ public LocationWrapper moveX(double delta) {
+ return new LocationWrapper(this.location.moveX(delta), this.worldName);
+ }
+
+ @Override
+ public LocationWrapper moveY(double delta) {
+ return new LocationWrapper(this.location.moveY(delta), this.worldName);
+ }
+
+ @Override
+ public LocationWrapper moveZ(double delta) {
+ return new LocationWrapper(this.location.moveZ(delta), this.worldName);
+ }
+
+}
diff --git a/src/main/java/de/xzise/metainterfaces/Moveable.java b/src/main/java/de/xzise/metainterfaces/Moveable.java
new file mode 100644
index 0000000000..64aeaf7c44
--- /dev/null
+++ b/src/main/java/de/xzise/metainterfaces/Moveable.java
@@ -0,0 +1,9 @@
+package de.xzise.metainterfaces;
+
+public interface Moveable> {
+
+ T moveX(double delta);
+ T moveY(double delta);
+ T moveZ(double delta);
+
+}
diff --git a/src/main/java/de/xzise/xwarp/CommonManager.java b/src/main/java/de/xzise/xwarp/CommonManager.java
new file mode 100644
index 0000000000..93887d6fe7
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/CommonManager.java
@@ -0,0 +1,155 @@
+package de.xzise.xwarp;
+
+import java.util.List;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.World;
+import org.bukkit.command.CommandSender;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.wrappers.permissions.Permission;
+import de.xzise.xwarp.WarpManager.WarpObjectGetter;
+import de.xzise.xwarp.dataconnections.DataConnection;
+import de.xzise.xwarp.list.PersonalList;
+
+public abstract class CommonManager, L extends PersonalList> implements Manager {
+
+ protected final L list;
+ protected final PluginProperties properties;
+ protected final String typeName;
+ protected final Server server;
+
+ protected CommonManager(L list, String typeName, PluginProperties properties, Server server) {
+ this.properties = properties;
+ this.typeName = typeName;
+ this.list = list;
+ this.list.setIgnoreCase(!properties.isCaseSensitive());
+ this.server = server;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void blindAdd(boolean database, List warpObjects) {
+ this.blindAdd(database, (T[]) warpObjects.toArray());
+ }
+
+ public void blindAdd(List warpObjects) {
+ this.blindAdd(false, warpObjects);
+ }
+
+ public void blindAdd(T... warpObjects) {
+ this.blindAdd(false, warpObjects);
+ }
+
+ public void blindAdd(boolean database, T... warpObjects) {
+ for (T warpObject : warpObjects) {
+ this.list.addWarpObject(warpObject);
+ }
+ if (database) {
+ this.blindDataAdd(warpObjects);
+ }
+ // if (this.getWarp(warp.name) == null) {
+ // this.global.put(warp.name.toLowerCase(), warp);
+ // } else if (warp.visibility == Visibility.GLOBAL) {
+ // throw new
+ // IllegalArgumentException("A global warp could not override an existing one.");
+ // }
+ // if (!putIntoPersonal(personal, warp)) {
+ // throw new
+ // IllegalArgumentException("A personal warp could not override an existing one.");
+ // }
+ }
+
+ protected abstract void blindDataAdd(T... warpObjects);
+
+ @Override
+ public boolean isNameAvailable(T warpObject) {
+ return this.isNameAvailable(warpObject.getName(), warpObject.getOwner());
+ }
+
+ @Override
+ public boolean isNameAvailable(String name, String owner) {
+ return this.list.getWarpObject(name, owner, null) == null;
+ }
+
+ @Override
+ public T getWarpObject(String name, String owner, String playerName) {
+ return this.list.getWarpObject(name, owner, playerName);
+ }
+
+ @Override
+ public void reload(DataConnection data) {
+ this.list.setIgnoreCase(!this.properties.isCaseSensitive());
+ }
+
+ @Override
+ public ImmutableSet getWarpObjects() {
+ return this.list.getWarpObjects();
+ }
+
+ @Override
+ public void importWarpObjects(DataConnection connection, WarpObjectGetter getter, CommandSender sender) {
+ List warps = getter.get();
+ List allowedWarps = Lists.newArrayListWithExpectedSize(warps.size());
+ List notAllowedWarps = Lists.newArrayListWithExpectedSize(warps.size());
+ for (T warp : warps) {
+ if (this.isNameAvailable(warp)) {
+ allowedWarps.add(warp);
+ } else {
+ notAllowedWarps.add(warp);
+ }
+ }
+
+ for (T warp : allowedWarps) {
+ warp.assignNewId();
+ }
+
+ if (allowedWarps.size() > 0) {
+ this.blindAdd(true, allowedWarps);
+ sender.sendMessage("Imported " + ChatColor.GREEN + allowedWarps.size() + ChatColor.WHITE + " " + this.typeName + " into the database.");
+ }
+
+ if (notAllowedWarps.size() > 0) {
+ sender.sendMessage(ChatColor.RED + "Found " + notAllowedWarps.size() + " " + this.typeName + " which cause naming conflicts.");
+ // Max lines - 1 (for the header) - 1 (for the succeed message)
+ if (notAllowedWarps.size() < MinecraftUtil.getMaximumLines(sender) - 1) {
+ for (T warp : notAllowedWarps) {
+ sender.sendMessage(ChatColor.GREEN + warp.getName() + ChatColor.WHITE + " by " + ChatColor.GREEN + warp.getOwner());
+ }
+ }
+ }
+ }
+
+ @Override
+ public int getSize() {
+ return this.list.getSize(null);
+ }
+
+ protected abstract void setWorld(T warpObject, World world, String worldName);
+
+ public void changeWorld(CommandSender sender, String oldWorld, String newWorld, Permission permission) {
+ if (XWarp.permissions.permission(sender, permission)) {
+ World newWorldObject = this.server.getWorld(newWorld);
+ int count = 0;
+ for (T warp : this.getWarpObjects()) {
+ if (warp.getWorld().equals(oldWorld)) {
+ this.setWorld(warp, newWorldObject, newWorld);
+ count++;
+ }
+ }
+ if (count == 0) {
+ sender.sendMessage("No warp objects in world '" + ChatColor.GREEN + oldWorld + ChatColor.WHITE + "'!");
+ } else {
+ sender.sendMessage("Moved " + ChatColor.GREEN + count + ChatColor.WHITE + " warp object(s) from world '" + ChatColor.GREEN + oldWorld + ChatColor.WHITE + "' to '" + ChatColor.GREEN + newWorld + ChatColor.WHITE + "'!");
+ if (newWorldObject == null) {
+ sender.sendMessage("Please note that there is no world '" + ChatColor.GREEN + newWorld + ChatColor.WHITE + "' loaded at the moment. So they are invalid for now.");
+ }
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You don't have the permission, to change the worlds.");
+ }
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/DefaultArrays.java b/src/main/java/de/xzise/xwarp/DefaultArrays.java
new file mode 100644
index 0000000000..6479f8bda5
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/DefaultArrays.java
@@ -0,0 +1,8 @@
+package de.xzise.xwarp;
+
+public final class DefaultArrays {
+
+ private DefaultArrays() {}
+
+ public static final String[] EMPTY_STRING_ARRAY = new String[0];
+}
diff --git a/src/main/java/de/xzise/xwarp/DefaultWarpObject.java b/src/main/java/de/xzise/xwarp/DefaultWarpObject.java
new file mode 100644
index 0000000000..9c3ad31a87
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/DefaultWarpObject.java
@@ -0,0 +1,282 @@
+package de.xzise.xwarp;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.metainterfaces.CommandSenderWrapper;
+import de.xzise.wrappers.permissions.BufferPermission;
+import de.xzise.wrappers.permissions.Permission;
+import de.xzise.xwarp.editors.Editor;
+import de.xzise.xwarp.editors.EditorPermissions;
+import de.xzise.xwarp.editors.EditorPermissions.Type;
+import de.xzise.xwarp.warpable.WarperFactory;
+import de.xzise.xwarp.wrappers.permission.WarpEditorPermission;
+
+public abstract class DefaultWarpObject & Editor> implements WarpObject {
+
+ private String name;
+ private String owner;
+ private String creator;
+ private final Map>> editors;
+ private final Class editorPermissionClass;
+
+ public final T invitePermission;
+
+ protected DefaultWarpObject(String name, String owner, String creator, Map>> editors, Class editorPermissionClass, T invitePermission) {
+ this.name = name;
+ this.owner = owner;
+ this.creator = creator;
+ this.editors = MinecraftUtil.createEnumMap(editors, EditorPermissions.Type.class);
+ this.editorPermissionClass = editorPermissionClass;
+ this.invitePermission = invitePermission;
+ }
+
+ // TODO: Restruct to objects with id and those without?
+ public abstract void assignNewId();
+
+ public void setOwner(String owner) {
+ this.owner = owner;
+ }
+
+ public void setCreator(String creator) {
+ this.creator = creator;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public final String getName() {
+ return this.name;
+ }
+
+ @Override
+ public final String getOwner() {
+ return this.owner;
+ }
+
+ @Override
+ public final String getCreator() {
+ return this.creator;
+ }
+
+ @Override
+ public void removeEditor(String name, EditorPermissions.Type type) {
+ Map> typePermissions = this.editors.get(type);
+ if (typePermissions != null) {
+ typePermissions.remove(name.toLowerCase());
+ }
+ }
+
+ @Override
+ public void addEditor(String name, EditorPermissions.Type type, ImmutableSet permissions) {
+ this.getEditorPermissions(name, true, type).putSet(permissions, true);
+ }
+
+ public ImmutableMap> getEditorPermissions(EditorPermissions.Type type) {
+ Map> typePermissions = this.editors.get(type);
+ if (typePermissions != null) {
+ return ImmutableMap.copyOf(typePermissions);
+ } else {
+ return ImmutableMap.of();
+ }
+ }
+
+ /**
+ * Returns the editor permissions to the type and name. Doesn't create new
+ * if there are no permissions.
+ *
+ * @param name
+ * Name of the editor permissions holder.
+ * @param type
+ * Type of the editor permissions holder.
+ * @return The editor permissions. If there are no one to the name and type
+ * returns null.
+ */
+ public EditorPermissions getEditorPermissions(String name, EditorPermissions.Type type) {
+ return this.getEditorPermissions(name, false, type);
+ }
+
+ /**
+ * Returns the editor permissions to the type and name. If
+ * create is set to true, creates a new, if there are no editor
+ * permissions. Otherwise null.
+ *
+ * @param name
+ * Name of the editor permissions holder.
+ * @param create
+ * Create new editor permissions, if doesn't exists.
+ * @param type
+ * Type of the editor permissions holder.
+ * @return The editor permissions. If there are no one to the name and type
+ * returns null.
+ */
+ public EditorPermissions getEditorPermissions(String name, boolean create, EditorPermissions.Type type) {
+ Map> typePermissions = this.editors.get(type);
+ if (typePermissions == null && create) {
+ typePermissions = Maps.newHashMap();
+ this.editors.put(type, typePermissions);
+ }
+
+ if (typePermissions != null) {
+ EditorPermissions editorPermissions = typePermissions.get(name.toLowerCase());
+ if (editorPermissions == null && create) {
+ editorPermissions = new EditorPermissions(this.editorPermissionClass);
+ typePermissions.put(name.toLowerCase(), editorPermissions);
+ }
+ return editorPermissions;
+ } else {
+ return null;
+ }
+ }
+
+ public static class EditorPermissionEntry & Editor> {
+
+ public final EditorPermissions editorPermissions;
+ public final String name;
+ public final EditorPermissions.Type type;
+
+ public EditorPermissionEntry(EditorPermissions editorPermissions, String name, Type type) {
+ this.editorPermissions = editorPermissions;
+ this.name = name;
+ this.type = type;
+ }
+ }
+
+ public Collection> getEditorPermissionsList() {
+ List> allEntries = Lists.newArrayList();
+ for (Entry>> typeEntry : this.editors.entrySet()) {
+ for (Entry> editorEntry : typeEntry.getValue().entrySet()) {
+ allEntries.add(new EditorPermissionEntry(editorEntry.getValue(), editorEntry.getKey(), typeEntry.getKey()));
+ }
+ }
+ return allEntries;
+ }
+
+ public static boolean isOwn(WarpObject> warpObject, String name) {
+ return warpObject.getOwner().equals(name);
+ }
+
+ public boolean isOwn(String name) {
+ return isOwn(this, name);
+ }
+
+ public static boolean isCreator(WarpObject> warpObject, String name) {
+ return warpObject.getCreator().equals(name);
+ }
+
+ public boolean isCreator(String name) {
+ return isCreator(this, name);
+ }
+
+ public static boolean isInvited(WarpObject warpObject, String name) {
+ return warpObject.hasPermission(name, warpObject.getInvitePermission());
+ }
+
+ public boolean isInvited(String name) {
+ return isInvited(this, name);
+ }
+
+ public boolean hasPlayerPermission(String name, T permission) {
+ EditorPermissions ep = this.getEditorPermissions(name, Type.PLAYER);
+ return ep != null && ep.get(permission);
+ }
+
+ public boolean hasGroupPermission(String name, T permission) {
+ for (String group : XWarp.permissions.getGroup(this.getWorld(), name)) {
+ EditorPermissions ep = this.getEditorPermissions(group, Type.GROUP);
+ if (ep != null && ep.get(permission)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean hasEditorPermission(String name, T permission) {
+ Player player = Bukkit.getServer().getPlayer(name);
+ return player != null && hasEditorPermission(player, permission);
+ }
+
+ public boolean hasEditorPermission(CommandSender sender, T permission) {
+ return XWarp.permissions.permission(sender, new WarpEditorPermission(this, permission));
+ }
+
+ public boolean hasSpecificPermission(String name, T permission) {
+ Player player = Bukkit.getServer().getPlayer(name);
+ return player != null && hasSpecificPermission(player, permission);
+ }
+
+ public boolean hasSpecificPermission(CommandSender sender, T permission) {
+ for (Entry> permissionEntry : this.getEditorPermissions(Type.PERMISSIONS).entrySet()) {
+ if (XWarp.permissions.permission(sender, new BufferPermission(permissionEntry.getKey(), false)) && permissionEntry.getValue().get(permission)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean hasPermission(String name, T permission) {
+ Player player = Bukkit.getServer().getPlayer(name);
+ return this.hasPlayerPermission(name, permission) || this.hasGroupPermission(name, permission) || (player != null && (this.hasEditorPermission(player, permission) || this.hasSpecificPermission(player, permission)));
+ }
+
+ public void invite(String player) {
+ this.getEditorPermissions(player, true, Type.PLAYER).put(this.invitePermission, true);
+ }
+
+ @Override
+ public T getInvitePermission() {
+ return this.invitePermission;
+ }
+
+ public static boolean canModify(CommandSender sender, boolean defaultModification, Permission defaultPermission, Permission adminPermission) {
+ if (defaultPermission != null) {
+ return ((defaultModification && XWarp.permissions.permission(sender, defaultPermission)) || XWarp.permissions.permission(sender, adminPermission));
+ } else {
+ return (defaultModification || XWarp.permissions.permission(sender, adminPermission));
+ }
+ }
+
+ public boolean playerCanModify(Player player, T permission) {
+ if (this.isOwn(player.getName()))
+ return true;
+ EditorPermissions ep = this.getEditorPermissions(player.getName().toLowerCase(), Type.PLAYER);
+ if (ep != null && ep.get(permission)) {
+ return true;
+ }
+ String[] groups = XWarp.permissions.getGroup(player.getWorld().getName(), player.getName());
+ for (String group : groups) {
+ EditorPermissions groupPerm = this.getEditorPermissions(group, Type.GROUP);
+ if (groupPerm != null && groupPerm.get(permission)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean canModify(CommandSender sender, T permission) {
+ CommandSender realSender = CommandSenderWrapper.getCommandSender(sender);
+ Player player = WarperFactory.getPlayer(realSender);
+ boolean canModify = false;
+ if (player != null) {
+ canModify = this.playerCanModify(player, permission);
+ }
+
+ return canModify(realSender, canModify, permission.getDefault(), permission.getAdmin());
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/Manager.java b/src/main/java/de/xzise/xwarp/Manager.java
new file mode 100644
index 0000000000..c1d1fe7b73
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/Manager.java
@@ -0,0 +1,42 @@
+package de.xzise.xwarp;
+
+import org.bukkit.World;
+import org.bukkit.command.CommandSender;
+
+import com.google.common.collect.ImmutableSet;
+
+import de.xzise.xwarp.WarpManager.WarpObjectGetter;
+import de.xzise.xwarp.dataconnections.DataConnection;
+import de.xzise.xwarp.editors.EditorPermissions;
+
+public interface Manager> {
+
+ void reload(DataConnection data);
+
+ void delete(T warpObject, CommandSender sender);
+ void setCreator(T warpObject, CommandSender sender, String creator);
+ void setOwner(T warpObject, CommandSender sender, String owner);
+ void setName(T warpObject, CommandSender sender, String name);
+
+ void invite(T warpObject, CommandSender sender, String inviteeName);
+ void uninvite(T warpObject, CommandSender sender, String inviteeName);
+
+ void addEditor(T warpObject, CommandSender sender, String editor, EditorPermissions.Type type, String permissions);
+ void removeEditor(T warpObject, CommandSender sender, String editor, EditorPermissions.Type type);
+
+ boolean isNameAvailable(T warpObject);
+ boolean isNameAvailable(String name, String owner);
+
+ T getWarpObject(String name, String owner, String playerName);
+ ImmutableSet getWarpObjects();
+ int getSize();
+
+ void missing(String name, String owner, CommandSender sender);
+
+ void importWarpObjects(DataConnection connection, WarpObjectGetter getter, CommandSender sender);
+
+ int setWorld(World world);
+ int unsetWorld(World world);
+
+ void changeWorld(CommandSender sender, String oldWorld, String newWorld);
+}
\ No newline at end of file
diff --git a/src/main/java/de/xzise/xwarp/MarkerManager.java b/src/main/java/de/xzise/xwarp/MarkerManager.java
new file mode 100644
index 0000000000..cd8654dbc6
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/MarkerManager.java
@@ -0,0 +1,68 @@
+package de.xzise.xwarp;
+
+import org.dynmap.markers.MarkerAPI;
+import org.dynmap.markers.MarkerIcon;
+import org.dynmap.markers.MarkerSet;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+import de.xzise.xwarp.Warp.Visibility;
+
+public class MarkerManager {
+
+ private MarkerAPI markerAPI;
+ private MarkerSet markerSet;
+ private MarkerIcon markerIcon;
+ private final PluginProperties properties;
+
+ public MarkerManager(PluginProperties properties) {
+ this.properties = properties;
+ }
+
+ public MarkerSet getMarkerSet() {
+ return this.markerSet;
+ }
+
+ public void setMarkerSet(MarkerSet markerSet) {
+ if (this.markerSet != markerSet) {
+ if (this.markerSet != null) {
+ this.markerSet.deleteMarkerSet();
+ }
+ this.markerSet = markerSet;
+ }
+ }
+
+ public MarkerIcon getMarkerIcon() {
+ return this.markerIcon;
+ }
+
+ public void setMarkerIcon(MarkerIcon markerIcon) {
+ if (this.markerIcon != markerIcon) {
+ this.markerIcon = markerIcon;
+ }
+ }
+
+ public MarkerAPI getMarkerAPI() {
+ return this.markerAPI;
+ }
+
+ public void setMarkerAPI(MarkerAPI markerAPI) {
+ this.markerAPI = markerAPI;
+ if (this.markerAPI == null) {
+ this.setMarkerSet(null);
+ this.setMarkerIcon(null);
+ }
+ }
+
+ public ImmutableList getMarkerVisibilities() {
+ Builder builder = ImmutableList.builder();
+ for (String string : this.properties.getMarkerVisibilities()) {
+ Visibility visibility = Visibility.parseString(string);
+ if (visibility != null) {
+ builder.add(visibility);
+ }
+ }
+ return builder.build();
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/MatchList.java b/src/main/java/de/xzise/xwarp/MatchList.java
new file mode 100644
index 0000000000..7536780429
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/MatchList.java
@@ -0,0 +1,14 @@
+package de.xzise.xwarp;
+
+import java.util.List;
+
+
+public class MatchList {
+ public MatchList(List exactMatches, List matches) {
+ this.exactMatches = exactMatches;
+ this.matches = matches;
+ }
+
+ public List exactMatches;
+ public List matches;
+}
diff --git a/src/main/java/de/xzise/xwarp/PluginProperties.java b/src/main/java/de/xzise/xwarp/PluginProperties.java
new file mode 100644
index 0000000000..7a0914dec2
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/PluginProperties.java
@@ -0,0 +1,248 @@
+package de.xzise.xwarp;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.List;
+
+import org.bukkit.Server;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.InvalidConfigurationException;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
+
+import de.xzise.xwarp.dataconnections.DataConnection;
+import de.xzise.xwarp.dataconnections.HModConnection;
+import de.xzise.xwarp.dataconnections.SQLiteConnection;
+import de.xzise.xwarp.dataconnections.YmlConnection;
+import de.xzise.xwarp.lister.GenericLister.Column;
+
+public class PluginProperties {
+
+ private static final ImmutableList DEFAULT_VISIBILITIES = ImmutableList.of("public", "global");
+ private static final ImmutableList DEFAULT_COLUMNS = ImmutableList.of("owner", "world", "location");
+
+ private DataConnection dataConnection;
+ private boolean cooldownNotify;
+ private boolean warmupNotify;
+ private boolean useForceTo;
+ private boolean showFreePriceMessage;
+ private boolean cancelWarmUpOnDamage;
+ private boolean cancelWarmUpOnMovement;
+ private boolean createUpdates;
+ private boolean caseSensitive;
+ private String defaultMessage;
+
+ private String permissionsPlugin;
+
+ private String economyPlugin;
+ private String economyBaseAccount;
+
+ private String markerPlugin;
+ private String markerPNG;
+ private ImmutableList markerVisibilities;
+
+ private ImmutableSet defaultColumns;
+
+ private final File dataDirectory;
+ private final File configFile;
+ private final Server server;
+
+ public PluginProperties(File dataDirectory, Server server) {
+ this.dataDirectory = dataDirectory;
+ this.configFile = new File(this.dataDirectory, "config.yml");
+ this.server = server;
+ this.read();
+ }
+
+ public DataConnection getDataConnection() {
+ return this.dataConnection;
+ }
+
+ public File getDataConnectionFile() {
+ return new File(this.dataDirectory, this.dataConnection.getFilename());
+ }
+
+ private static String getPlugin(String value) {
+ if ("none".equalsIgnoreCase(value) || "null".equalsIgnoreCase(value)) {
+ return null;
+ } else {
+ return value;
+ }
+ }
+
+ public String getEconomyPlugin() {
+ return getPlugin(this.economyPlugin);
+ }
+
+ public String getPermissionsPlugin() {
+ return getPlugin(this.permissionsPlugin);
+ }
+
+ public String getEconomyBaseAccount() {
+ return this.economyBaseAccount;
+ }
+
+ public boolean isCooldownNotify() {
+ return this.cooldownNotify;
+ }
+
+ public boolean isWarmupNotify() {
+ return this.warmupNotify;
+ }
+
+ public boolean isForceToUsed() {
+ return this.useForceTo;
+ }
+
+ public boolean isCancelWarmUpOnDamage() {
+ return this.cancelWarmUpOnDamage;
+ }
+
+ public boolean isCancelWarmUpOnMovement() {
+ return this.cancelWarmUpOnMovement;
+ }
+
+ public boolean showFreePriceMessage() {
+ return this.showFreePriceMessage;
+ }
+
+ public boolean isCreationUpdating() {
+ return this.createUpdates;
+ }
+
+ public boolean isCaseSensitive() {
+ return this.caseSensitive;
+ }
+
+ public String getMarkerPNG() {
+ return this.markerPNG;
+ }
+
+ public ImmutableList getMarkerVisibilities() {
+ return this.markerVisibilities;
+ }
+
+ public String getMarkerPlugin() {
+ return getPlugin(this.markerPlugin);
+ }
+
+ public ImmutableSet getListColumns() {
+ return this.defaultColumns;
+ }
+
+ public void read() {
+ YamlConfiguration configuration = new YamlConfiguration();
+ if (this.configFile.exists()) {
+ try {
+ configuration.load(this.configFile);
+ } catch (FileNotFoundException e) {
+ XWarp.logger.warning("Unable to load configuration because the file doesn't exists: " + e.getMessage());
+ } catch (IOException e) {
+ XWarp.logger.warning("Unable to load configuration!", e);
+ } catch (InvalidConfigurationException e) {
+ XWarp.logger.warning("Unable to load configuration because it is an invalid configuration!", e);
+ }
+ } else {
+ configuration.set("data.connection", "sqlite");
+ configuration.set("economy.plugin", "");
+ configuration.set("economy.base-account", "");
+ configuration.set("permissions.plugin", "");
+ configuration.set("warmup.notify", true);
+ configuration.set("warmup.cancel.movement", false);
+ configuration.set("warmup.cancel.damage", true);
+ configuration.set("cooldown.notify", true);
+ configuration.set("case-sensitive", false);
+ configuration.set("update-if-exists", false);
+ configuration.set("use-force-to", false);
+ configuration.set("show-free-price-message", false);
+ configuration.set("warp.defaultmsg", "Welcome to '{NAME}'!");
+ configuration.set("marker.plugin", "null");
+ configuration.set("marker.png", "marker.png");
+ configuration.set("marker.visibilities", DEFAULT_VISIBILITIES);
+ configuration.set("list.columns", DEFAULT_COLUMNS);
+ try {
+ configuration.save(this.configFile);
+ XWarp.logger.info("Successfully created default configuration file.");
+ } catch (IOException e) {
+ XWarp.logger.warning("Unable to create properties file!", e);
+ }
+ }
+
+ final String dataConnectionProperty = configuration.getString("data.connection");
+
+ if ("hmod".equalsIgnoreCase(dataConnectionProperty)) {
+ this.dataConnection = new HModConnection(this.server);
+ } else if ("yml".equalsIgnoreCase(dataConnectionProperty)) {
+ this.dataConnection = new YmlConnection();
+ } else {
+ if (!"sqlite".equalsIgnoreCase(dataConnectionProperty)) {
+ XWarp.logger.warning("Unrecognized data-connection selected (" + dataConnectionProperty + ")");
+ }
+ // Per default sqlite
+ this.dataConnection = new SQLiteConnection(this.server);
+ }
+
+ this.caseSensitive = configuration.getBoolean("case-sensitive", false);
+
+ this.economyPlugin = configuration.getString("economy.plugin", "");
+ this.economyBaseAccount = configuration.getString("economy.base-account", "");
+
+ this.permissionsPlugin = configuration.getString("permissions.plugin", "");
+
+ this.cooldownNotify = configuration.getBoolean("cooldown.notify", true);
+
+ this.warmupNotify = configuration.getBoolean("warmup.notify", true);
+ this.cancelWarmUpOnDamage = configuration.getBoolean("warmup.cancel.damage", true);
+ this.cancelWarmUpOnMovement = configuration.getBoolean("warmup.cancel.movement", false);
+
+ this.useForceTo = configuration.getBoolean("use-force-to", false);
+ this.showFreePriceMessage = configuration.getBoolean("show-free-price-message", true);
+ this.createUpdates = configuration.getBoolean("update-if-exists", false);
+
+ this.markerPNG = configuration.getString("marker.png", "marker.png");
+ this.markerVisibilities = ImmutableList.copyOf(getStringList(configuration, "marker.visibilities", DEFAULT_VISIBILITIES));
+ if (configuration.isSet("marker.enabled")) {
+ XWarp.logger.info("Please note, that 'marker.enabled' in the plugin configuration is now obsoleted by 'marker.plugin'.");
+ }
+ if (!configuration.isSet("marker.plugin")) {
+ this.markerPlugin = configuration.getBoolean("marker.enabled", false) ? "dynmap" : "null";
+ } else {
+ this.markerPlugin = configuration.getString("marker.plugin", "null");
+ }
+
+ Builder columnsBuilder = ImmutableSet.builder();
+ for (String column : getStringList(configuration, "list.columns", DEFAULT_COLUMNS)) {
+ if (column.equalsIgnoreCase("owner")) {
+ columnsBuilder.add(Column.OWNER);
+ } else if (column.equalsIgnoreCase("world")) {
+ columnsBuilder.add(Column.WORLD);
+ } else if (column.equalsIgnoreCase("location")) {
+ columnsBuilder.add(Column.LOCATION);
+ }
+ }
+ this.defaultColumns = columnsBuilder.build();
+
+ this.defaultMessage = configuration.getString("warp.defaultmsg", "Welcome to '{NAME}'!");
+ }
+
+ private static List getStringList(final ConfigurationSection configurationSection, final String name, final List def) {
+ List list = configurationSection.getStringList(name);
+ if (list == null) {
+ return def;
+ } else {
+ return list;
+ }
+ }
+
+ public String getDefaultMessage() {
+ return this.defaultMessage;
+ }
+
+ public ImmutableSet getDefaultColumns() {
+ return this.defaultColumns;
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/Searcher.java b/src/main/java/de/xzise/xwarp/Searcher.java
new file mode 100644
index 0000000000..f38c8eb8ad
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/Searcher.java
@@ -0,0 +1,81 @@
+package de.xzise.xwarp;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.xwarp.lister.GenericLister;
+import de.xzise.xwarp.lister.ListSection;
+
+public class Searcher {
+ private WarpManager warpList;
+ private CommandSender sender;
+
+ private List exactMatches;
+ private List matches;
+
+ private String query;
+
+ public Searcher(WarpManager warpList) {
+ this.warpList = warpList;
+ }
+
+ public void addPlayer(CommandSender sender) {
+ this.sender = sender;
+ }
+
+ public void setQuery(String name) {
+ this.query = name;
+ this.setMatches(this.warpList.getMatches(name, sender));
+ }
+
+ public void setMatches(MatchList matches) {
+ this.exactMatches = matches.exactMatches;
+ this.matches = matches.matches;
+ }
+
+ public void search(int page) {
+ final int elementsPerPage = MinecraftUtil.getMaximumLines(this.sender) - 2;
+ final int elementsLeftOnMixedPage = elementsPerPage - this.exactMatches.size() % elementsPerPage - 1;
+ final int maxPages = (int) (elementsLeftOnMixedPage > 1 ? Math.ceil((this.exactMatches.size() + this.matches.size() + 1) / (double) elementsPerPage) : Math.ceil(this.exactMatches.size() / (double) elementsPerPage) + Math.ceil(this.matches.size() / (double) elementsPerPage));
+ int elementsLeft = elementsPerPage + 1;
+
+ if (exactMatches.size() == 0 && matches.size() == 0) {
+ this.sender.sendMessage(ChatColor.RED + "No warp matches for search: " + ChatColor.GRAY + query);
+ } else if (page <= 0) {
+ this.sender.sendMessage(ChatColor.RED + "Only page numbers greater equals 1 are allowed.");
+ } else if (maxPages < page) {
+ this.sender.sendMessage(ChatColor.RED + "There are only " + maxPages + " pages of warps");
+ } else {
+ List sections = new ArrayList(2);
+
+ final int exactMatchesPages = Math.max((int) Math.ceil(this.exactMatches.size() / ((double) elementsPerPage)), 1);
+ if (exactMatchesPages >= page) {
+ ListSection section = new ListSection("Exact matches for search: " + ChatColor.GREEN + this.query, MinecraftUtil.getMaximumLines(sender));
+ elementsLeft--;
+ for (int i = (page - 1) * elementsLeft; i < this.exactMatches.size() && elementsLeft > 0; i++) {
+ section.addWarp(this.exactMatches.get(i));
+ elementsLeft--;
+ }
+ sections.add(section);
+ }
+
+ final int offset = (elementsLeftOnMixedPage > 1 && page > exactMatchesPages? elementsLeftOnMixedPage : 0) + Math.max((page - Math.max(exactMatchesPages, 1) - 1) * elementsPerPage, 0);
+
+ if (this.matches.size() > offset && elementsLeft > 2) {
+ ListSection section = new ListSection("Partial matches for search: " + ChatColor.GREEN + this.query);
+ elementsLeft--;
+ for (int i = offset; i < this.matches.size() && elementsLeft > 0; i++) {
+ section.addWarp(this.matches.get(i));
+ elementsLeft--;
+ }
+ sections.add(section);
+ }
+
+ GenericLister.listPage(page, maxPages, this.sender, sections.toArray(new ListSection[0]));
+ }
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/WPAManager.java b/src/main/java/de/xzise/xwarp/WPAManager.java
new file mode 100644
index 0000000000..ade86c3356
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/WPAManager.java
@@ -0,0 +1,273 @@
+package de.xzise.xwarp;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.bukkit.ChatColor;
+import org.bukkit.World;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.Plugin;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.xwarp.WarpManager.WarpObjectGetter;
+import de.xzise.xwarp.dataconnections.DataConnection;
+import de.xzise.xwarp.dataconnections.IdentificationInterface;
+import de.xzise.xwarp.dataconnections.WarpProtectionConnection;
+import de.xzise.xwarp.editors.EditorPermissions;
+import de.xzise.xwarp.editors.WarpProtectionAreaPermissions;
+import de.xzise.xwarp.editors.EditorPermissions.Type;
+import de.xzise.xwarp.list.NonGlobalList;
+import de.xzise.xwarp.wrappers.permission.PermissionTypes;
+import de.xzise.xwarp.wrappers.permission.WPAPermissions;
+
+public class WPAManager extends CommonManager> {
+
+ private WarpProtectionConnection data;
+
+ public WPAManager(Plugin plugin, DataConnection data, PluginProperties properties) {
+ super(new NonGlobalList(), "warp protection area", properties, plugin.getServer());
+ this.reload(data);
+ }
+
+ @Override
+ public void reload(DataConnection data) {
+ super.reload(data);
+ this.data = MinecraftUtil.cast(WarpProtectionConnection.class, data);
+ this.list.loadList(this.data.getProtectionAreas());
+ }
+
+ private boolean isWPAEnabled(CommandSender sender) {
+ if (this.data != null) {
+ return true;
+ } else {
+ sender.sendMessage(ChatColor.RED + "Warp protection areas are not enabled on this server.");
+ return false;
+ }
+ }
+
+ @Override
+ public void delete(WarpProtectionArea wpa, CommandSender sender) {
+ if (isWPAEnabled(sender)) {
+ if (wpa.canModify(sender, WarpProtectionAreaPermissions.DELETE)) {
+ this.list.deleteWarpObject(wpa);
+ this.data.deleteProtectionArea(wpa);
+ sender.sendMessage("You have deleted '" + ChatColor.GREEN + wpa.getName() + ChatColor.WHITE + "'.");
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to delete '" + wpa.getName() + "'");
+ }
+ }
+ }
+
+ @Override
+ public void setCreator(WarpProtectionArea wpa, CommandSender sender, String creator) {
+ if (isWPAEnabled(sender)) {
+ if (XWarp.permissions.permission(sender, PermissionTypes.ADMIN_CHANGE_CREATOR)) {
+ if (wpa.isCreator(creator)) {
+ sender.sendMessage(ChatColor.RED + creator + " is already the creator.");
+ } else {
+ wpa.setCreator(creator);
+ this.data.updateCreator(wpa);
+ sender.sendMessage("You have changed the creator of '" + ChatColor.GREEN + wpa.getName() + ChatColor.WHITE + "' to " + ChatColor.GREEN + creator + ChatColor.WHITE + ".");
+ Player match = server.getPlayer(creator);
+ if (match != null) {
+ match.sendMessage("You're now creator of '" + ChatColor.GREEN + wpa.getName() + ChatColor.WHITE + "' by " + MinecraftUtil.getName(sender));
+ }
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to give '" + wpa.getName() + "'");
+ }
+ }
+ }
+
+ @Override
+ public void setOwner(WarpProtectionArea wpa, CommandSender sender, String owner) {
+ if (isWPAEnabled(sender)) {
+ if (wpa.canModify(sender, WarpProtectionAreaPermissions.GIVE)) {
+ if (wpa.isOwn(owner)) {
+ sender.sendMessage(ChatColor.RED + owner + " is already the owner.");
+ } else {
+ WarpProtectionArea giveeWarp = this.getWarpObject(wpa.getName(), owner, null);
+ if (giveeWarp == null) {
+ String preOwner = wpa.getOwner();
+ IdentificationInterface ii = this.data.createWarpProtectionAreaIdentification(wpa);
+ wpa.setOwner(owner);
+ this.list.updateOwner(wpa, preOwner);
+ this.data.updateOwner(wpa, ii);
+ sender.sendMessage("You have given '" + ChatColor.GREEN + wpa.getName() + ChatColor.WHITE + "' to " + ChatColor.GREEN + owner + ChatColor.WHITE + ".");
+ Player match = this.server.getPlayer(owner);
+ if (match != null) {
+ match.sendMessage("You've been given '" + ChatColor.GREEN + wpa.getName() + ChatColor.WHITE + "' by " + MinecraftUtil.getName(sender));
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "The new owner already has a warp named " + giveeWarp.getName());
+ }
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to give '" + wpa.getName() + "'");
+ }
+ }
+ }
+
+ @Override
+ public void setName(WarpProtectionArea wpa, CommandSender sender, String name) {
+ if (isWPAEnabled(sender)) {
+ if (wpa.canModify(sender, WarpProtectionAreaPermissions.RENAME)) {
+ String owner = wpa.getOwner();
+ if (this.getWarpObject(name, owner, null) != null) {
+ sender.sendMessage(ChatColor.RED + "You already have a warp with this name.");
+ } else {
+ IdentificationInterface ii = this.data.createWarpProtectionAreaIdentification(wpa);
+ this.list.deleteWarpObject(wpa);
+ wpa.setName(name);
+ this.list.addWarpObject(wpa);
+ this.data.updateName(wpa, ii);
+ sender.sendMessage(ChatColor.AQUA + "You have renamed '" + wpa.getName() + "'");
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to change the position from '" + wpa.getName() + "'");
+ }
+ }
+ }
+
+ @Override
+ public void invite(WarpProtectionArea wpa, CommandSender sender, String inviteeName) {
+ if (isWPAEnabled(sender)) {
+ if (wpa.canModify(sender, WarpProtectionAreaPermissions.INVITE)) {
+ if (wpa.hasPlayerPermission(inviteeName, WarpProtectionAreaPermissions.OVERWRITE)) {
+ sender.sendMessage(ChatColor.RED + inviteeName + " is already invited to this warp.");
+ } else if (wpa.isOwn(inviteeName)) {
+ sender.sendMessage(ChatColor.RED + inviteeName + " is the creator, of course he's the invited!");
+ } else {
+ wpa.invite(inviteeName);
+ this.data.updateEditor(wpa, inviteeName, Type.PLAYER);
+ sender.sendMessage("You have invited " + ChatColor.GREEN + inviteeName + ChatColor.WHITE + " to '" + ChatColor.GREEN + wpa.getName() + ChatColor.WHITE + "'.");
+ Player match = this.server.getPlayer(inviteeName);
+ if (match != null) {
+ match.sendMessage("You've been invited to warp '" + ChatColor.GREEN + wpa.getName() + ChatColor.WHITE + "' by " + ChatColor.GREEN + MinecraftUtil.getName(sender) + ChatColor.WHITE + ".");
+ }
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to invite players to '" + wpa.getName() + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void uninvite(WarpProtectionArea wpa, CommandSender sender, String inviteeName) {
+ if (isWPAEnabled(sender)) {
+ if (wpa.canModify(sender, WarpProtectionAreaPermissions.UNINVITE)) {
+ if (!wpa.hasPlayerPermission(inviteeName, WarpProtectionAreaPermissions.OVERWRITE)) {
+ sender.sendMessage(ChatColor.RED + inviteeName + " is not invited to this warp.");
+ } else if (wpa.isOwn(inviteeName)) {
+ sender.sendMessage(ChatColor.RED + "You can't uninvite yourself. You're the creator!");
+ } else {
+ EditorPermissions permissions = wpa.getEditorPermissions(inviteeName, Type.PLAYER);
+ if (permissions != null && permissions.remove(WarpProtectionAreaPermissions.OVERWRITE)) {
+ this.data.updateEditor(wpa, inviteeName, Type.PLAYER);
+ sender.sendMessage("You have uninvited " + ChatColor.GREEN + inviteeName + ChatColor.WHITE + " from '" + ChatColor.GREEN + wpa.getName() + ChatColor.WHITE + "'.");
+ Player match = this.server.getPlayer(inviteeName);
+ if (match != null) {
+ match.sendMessage("You've been uninvited to warp '" + ChatColor.GREEN + wpa.getName() + ChatColor.WHITE + "' by " + ChatColor.GREEN + MinecraftUtil.getName(sender) + ChatColor.WHITE + ". Sorry.");
+ }
+ }
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to uninvite players from '" + wpa.getName() + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void addEditor(WarpProtectionArea wpa, CommandSender sender, String editor, Type type, String permissions) {
+ if (isWPAEnabled(sender)) {
+ if (wpa.canModify(sender, WarpProtectionAreaPermissions.ADD_EDITOR)) {
+ wpa.addEditor(editor, type, WarpProtectionAreaPermissions.parseString(permissions));
+ this.data.updateEditor(wpa, editor, type);
+ sender.sendMessage("You have added " + ChatColor.GREEN + editor + ChatColor.WHITE + " to '" + ChatColor.GREEN + wpa.getName() + ChatColor.WHITE + "'.");
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to add an editor from '" + wpa.getName() + "'");
+ }
+ }
+ }
+
+ @Override
+ public void removeEditor(WarpProtectionArea wpa, CommandSender sender, String editor, Type type) {
+ if (isWPAEnabled(sender)) {
+ if (wpa.canModify(sender, WarpProtectionAreaPermissions.REMOVE_EDITOR)) {
+ wpa.removeEditor(editor, type);
+ this.data.updateEditor(wpa, editor, type);
+ sender.sendMessage("You have removed " + ChatColor.GREEN + editor + ChatColor.WHITE + " from '" + ChatColor.GREEN + wpa.getName() + ChatColor.WHITE + "'.");
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to remove an editor from '" + wpa.getName() + "'");
+ }
+ }
+ }
+
+ @Override
+ public void missing(String name, String owner, CommandSender sender) {
+ if (owner == null || owner.isEmpty()) {
+ sender.sendMessage(ChatColor.RED + "Protection area named '" + name + "' doesn't exist.");
+ } else {
+ sender.sendMessage(ChatColor.RED + "Player '" + owner + "' doesn't own a protection area named '" + name + "'.");
+ }
+ }
+
+ public static class WPAGetter implements WarpObjectGetter {
+
+ private final WarpProtectionConnection connection;
+
+ public WPAGetter(DataConnection connection) {
+ this.connection = MinecraftUtil.cast(WarpProtectionConnection.class, connection);
+ }
+
+ @Override
+ public List get() {
+ return connection == null ? new ArrayList(0) : this.connection.getProtectionAreas();
+ }
+
+ }
+
+ public void addWPA(WarpProtectionArea wpa) {
+ this.list.addWarpObject(wpa);
+ this.blindDataAdd(wpa);
+ }
+
+ @Override
+ protected void blindDataAdd(WarpProtectionArea... areas) {
+ this.data.addProtectionArea(areas);
+ }
+
+ @Override
+ public int setWorld(World world) {
+ int result = 0;
+ for (WarpProtectionArea wpa : this.getWarpObjects()) {
+ if (wpa.getWorldWrapper().setWorld(world)) {
+ result++;
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public int unsetWorld(World world) {
+ int result = 0;
+ for (WarpProtectionArea wpa : this.getWarpObjects()) {
+ if (wpa.getWorldWrapper().unsetWorld(world)) {
+ result++;
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public void changeWorld(CommandSender sender, String oldWorld, String newWorld) {
+ this.changeWorld(sender, oldWorld, newWorld, WPAPermissions.ADMIN_CHANGE_WORLD);
+ }
+
+ @Override
+ protected void setWorld(WarpProtectionArea wpa, World world, String worldName) {
+ wpa.setWorld(worldName, world);
+ this.data.updateWorld(wpa);
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/Warp.java b/src/main/java/de/xzise/xwarp/Warp.java
new file mode 100644
index 0000000000..084d80f39f
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/Warp.java
@@ -0,0 +1,456 @@
+package de.xzise.xwarp;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Map;
+
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.dynmap.markers.Marker;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.StringComparator;
+import de.xzise.bukkit.util.callback.Callback;
+import de.xzise.collections.ArrayReferenceList;
+import de.xzise.metainterfaces.FixedLocation;
+import de.xzise.metainterfaces.LocationWrapper;
+import de.xzise.xwarp.editors.EditorPermissions;
+import de.xzise.xwarp.editors.WarpPermissions;
+import de.xzise.xwarp.editors.EditorPermissions.Type;
+import de.xzise.xwarp.warpable.Positionable;
+import de.xzise.xwarp.warpable.Warpable;
+import de.xzise.xwarp.warpable.WarperFactory;
+import de.xzise.xwarp.wrappers.permission.PermissionTypes;
+import de.xzise.xwarp.wrappers.permission.WarpEditorPermission;
+import de.xzise.xwarp.wrappers.permission.WorldPermission;
+
+public class Warp extends DefaultWarpObject {
+
+ public enum Visibility {
+ PRIVATE((byte) 0, "private"),
+ PUBLIC((byte) 1, "public"),
+ GLOBAL((byte) 2, "global");
+
+ private static final Map NAMES = MinecraftUtil.createReverseEnumMap(Visibility.class, new Callback() {
+ public String call(Visibility visibility) {
+ return visibility.name;
+ }
+ });
+ private static final Map LEVELS = MinecraftUtil.createReverseEnumMap(Visibility.class, new Callback() {
+ @Override
+ public Byte call(Visibility visibility) {
+ return visibility.level;
+ }
+ });
+
+ public final byte level;
+ public final String name;
+
+ private Visibility(byte level, String name) {
+ this.level = level;
+ this.name = name;
+ }
+
+ public static Visibility parseString(String string) {
+ return NAMES.get(string);
+ }
+
+ public static Visibility getByLevel(byte level) {
+ return LEVELS.get(level);
+ }
+ }
+
+ public int index;
+ private LocationWrapper location;
+ /** This price value will be transfered to the owner. */
+ private double price;
+ private int cooldown;
+ private int warmup;
+ private boolean listed;
+ private String welcomeMessage;
+ private Visibility visibility;
+ private Marker marker;
+ private MarkerManager manager;
+
+ private static int markerId = 0;
+ public static int nextIndex = 1;
+
+ public Warp(int index, String name, String creator, String owner, LocationWrapper wrapper, Visibility visibility, Map>> editorPermissions, String welcomeMessage) {
+ super(name, owner, creator, editorPermissions, WarpPermissions.class, WarpPermissions.WARP);
+ this.index = index;
+ this.location = wrapper;
+ this.visibility = visibility;
+ this.welcomeMessage = welcomeMessage;
+ this.listed = true;
+ this.warmup = -1;
+ this.cooldown = -1;
+ if (index > nextIndex)
+ nextIndex = index;
+ nextIndex++;
+ }
+
+ public Warp(String name, String creator, String owner, LocationWrapper wrapper) {
+ this(nextIndex, name, creator, owner, wrapper, Visibility.PUBLIC, null, null);
+ }
+
+ public Warp(String name, Player creator) {
+ this(name, creator.getName(), creator.getName(), new LocationWrapper(creator.getLocation()));
+ }
+
+ public void assignNewId() {
+ this.index = nextIndex++;
+ }
+
+ public boolean playerCanWarp(CommandSender sender, boolean viaSign) {
+ Player player = WarperFactory.getPlayer(sender);
+ Positionable pos = WarperFactory.getPositionable(sender);
+ String name = null;
+ WorldPermission worldPermission = WorldPermission.TO_WORLD;
+ if (player != null) {
+ name = player.getName();
+ }
+ if (pos != null) {
+ if (pos.getLocation().getWorld().getName().equals(this.getLocationWrapper().getWorld())) {
+ worldPermission = WorldPermission.WITHIN_WORLD;
+ }
+ }
+
+ // If the player isn't allowed to warp to/within the world cancel here!
+ if (!XWarp.permissions.permission(sender, worldPermission.getPermission(this.getLocationWrapper().getWorld()))) {
+ return false;
+ }
+
+ if (XWarp.permissions.permission(sender, new WarpEditorPermission(this, WarpPermissions.WARP)))
+ return true;
+ if (name != null && this.getOwner().equals(name) && XWarp.permissions.permission(sender, viaSign ? PermissionTypes.SIGN_WARP_OWN : PermissionTypes.TO_OWN))
+ return true;
+ if (name != null && this.hasPermission(name, WarpPermissions.WARP) && XWarp.permissions.permission(sender, viaSign ? PermissionTypes.SIGN_WARP_INVITED : PermissionTypes.TO_INVITED))
+ return true;
+ if (this.visibility == Visibility.PUBLIC && XWarp.permissions.permission(sender, viaSign ? PermissionTypes.SIGN_WARP_OTHER : PermissionTypes.TO_OTHER))
+ return true;
+ if (this.visibility == Visibility.GLOBAL && XWarp.permissions.permission(sender, viaSign ? PermissionTypes.SIGN_WARP_GLOBAL : PermissionTypes.TO_GLOBAL))
+ return true;
+ return XWarp.permissions.permission(sender, PermissionTypes.ADMIN_TO_ALL);
+ }
+
+ public boolean playerCanWarp(Warpable player) {
+ return playerCanWarp(player, true) || playerCanWarp(player, false);
+ }
+
+ public boolean isSave() {
+ return this.isSave(null);
+ }
+
+ /**
+ * Returns if the location is save.
+ *
+ * @return if the location is save. Is false if invalid.
+ */
+ public boolean isSave(CommandSender sender) {
+ // TODO: Check if the player can fall through: Check below if there is a
+ // torch (not on ground), wall sign
+
+ if (this.location.isValid()) {
+ Location location = this.getLocation().toLocation();
+ Block block = location.getBlock().getRelative(BlockFace.UP, 2);
+
+ Material[] materials = new Material[7];
+ int i = 0;
+ while (i < materials.length) {
+ materials[i++] = block.getType();
+ block = block.getRelative(BlockFace.DOWN);
+ }
+
+ Material top = materials[0];
+ Material higher = materials[1];
+ Material lower = materials[2];
+
+ Boolean save = null;
+ double comma = MinecraftUtil.getDecimalPlaces(location.getY());
+
+ msg(sender, "Comma: " + comma);
+ if (save == null) {
+ if (comma < 0.05D) {
+ save = checkOpaqueMaterials(lower, higher);
+ } else {
+ save = ((comma >= 0.49D && checkMaterials(lower, Material.STEP)) || checkOpaqueMaterials(lower)) && checkOpaqueMaterials(higher, top);
+ }
+ }
+
+ if (save == null && sender != null) {
+ sender.sendMessage("The save value is null!");
+ save = false;
+ }
+ msg(sender, "Materials: " + Arrays.toString(materials));
+
+ return save;
+ } else {
+ return false;
+ }
+ }
+
+ private static void msg(CommandSender sender, String msg) {
+ if (sender != null) {
+ sender.sendMessage(msg);
+ }
+ }
+
+ private static boolean checkOpaqueMaterials(Material... materials) {
+ // TODO: Move to Minecraft Util?
+ // @formatter:off
+ return checkMaterials(materials,
+ // "Solids" blocks
+ Material.AIR, Material.WATER, Material.STATIONARY_WATER, Material.SNOW,
+ // Plants
+ Material.SAPLING, Material.YELLOW_FLOWER, Material.RED_ROSE, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.SUGAR_CANE_BLOCK, Material.CROPS, Material.LONG_GRASS, Material.DEAD_BUSH,
+ // Torches/Redstone
+ Material.TORCH, Material.REDSTONE_TORCH_ON, Material.REDSTONE_TORCH_OFF, Material.REDSTONE_WIRE,
+ // Diodes
+ Material.DIODE_BLOCK_OFF, Material.DIODE_BLOCK_ON,
+ // Signs
+ Material.SIGN_POST, Material.WALL_SIGN,
+ // Rails
+ Material.RAILS, Material.POWERED_RAIL, Material.DETECTOR_RAIL,
+ // Switches
+ Material.LEVER, Material.STONE_PLATE, Material.WOOD_PLATE, Material.STONE_BUTTON,
+ // Doors
+ Material.WOODEN_DOOR, Material.IRON_DOOR_BLOCK, Material.TRAP_DOOR,
+ Material.LADDER,
+ Material.LEVER, Material.STONE_BUTTON,
+ Material.PORTAL,
+ Material.CAKE_BLOCK);
+ // @formatter:on
+ }
+
+ private static boolean checkMaterials(Material material, Material... allowed) {
+ return ArrayReferenceList.contains(material, allowed);
+ }
+
+ private static boolean checkMaterials(Material[] materials, Material... allowed) {
+ for (Material material : materials) {
+ if (!ArrayReferenceList.contains(material, allowed)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void setLocation(Positionable positionable) {
+ this.setLocation(positionable.getLocation());
+ }
+
+ public void uninvite(String inviteeName) {
+ this.getEditorPermissions(inviteeName, Type.PLAYER).put(WarpPermissions.WARP, false);
+ }
+
+ public boolean isListed(CommandSender sender) {
+ boolean accessable = false;
+ // Admin permissions
+ if (XWarp.permissions.permissionOr(sender, PermissionTypes.getDefaultPermissions(false)))
+ accessable = true;
+
+ Warpable warpable = WarperFactory.getWarpable(sender);
+
+ boolean own = false;
+ if (warpable != null) {
+ // Can warp
+ if (this.playerCanWarp(warpable))
+ accessable = true;
+ Player player = WarperFactory.getPlayer(warpable);
+ if (player != null) {
+ // Creator permissions
+ if (this.isOwn(player.getName())) {
+ own = true;
+ accessable = true;
+ }
+ }
+ }
+
+ if (this.isListed() || XWarp.permissions.permission(sender, PermissionTypes.ADMIN_LIST_VIEW) || (own && XWarp.permissions.permission(sender, PermissionTypes.LIST_OWN))) {
+ return accessable;
+ } else {
+ return false;
+ }
+ }
+
+ public FixedLocation getLocation() {
+ return this.location.getLocation();
+ }
+
+ public LocationWrapper getLocationWrapper() {
+ return this.location;
+ }
+
+ public void setLocation(Location location) {
+ this.setLocation(new FixedLocation(location));
+ }
+
+ public void setLocation(FixedLocation location) {
+ this.location = new LocationWrapper(location);
+ this.updateMarker();
+ }
+
+ public void setWelcomeMessage(String message) {
+ this.welcomeMessage = message;
+ }
+
+ /**
+ * Returns the raw welcome message. If the message is null, it shall return
+ * the default message. If not null the warp specific message. If set to
+ * nothing (result.isEmpty() is true) it show no message at all.
+ *
+ * @return the raw welcome message.
+ */
+ public String getRawWelcomeMessage() {
+ return this.welcomeMessage;
+ }
+
+ public void addEditor(String name, String permissions, EditorPermissions.Type type) {
+ this.addEditor(name, type, WarpPermissions.parseString(permissions));
+ }
+
+ public static final Comparator WARP_NAME_COMPARATOR = new StringComparator() {
+
+ @Override
+ protected String getValue(Warp warp) {
+ return warp.getName();
+ }
+
+ };
+
+ public static final Comparator WARP_INDEX_COMPARATOR = new Comparator() {
+
+ @Override
+ public int compare(Warp warp1, Warp warp2) {
+ return new Integer(warp1.index).compareTo(warp2.index);
+ }
+ };
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Warp) {
+ Warp w = (Warp) o;
+ return w.getName().equals(this.getName()) && w.getOwner().equals(this.getOwner());
+ } else {
+ return false;
+ }
+ }
+
+ public void setPrice(double price) {
+ this.price = price;
+ }
+
+ public double getPrice() {
+ return this.price;
+ }
+
+ public void setListed(boolean listed) {
+ this.listed = listed;
+ }
+
+ public boolean isListed() {
+ return listed;
+ }
+
+ @Override
+ public void setName(String name) {
+ super.setName(name);
+ this.updateMarker();
+ }
+
+ public boolean isFree() {
+ return this.price < 0;
+ }
+
+ @Override
+ public String getWorld() {
+ return this.location.getWorld();
+ }
+
+ public void setWorld(String worldName, World world) {
+ this.location.setWorld(worldName, world);
+ this.updateMarker();
+ }
+
+ public void updateMarker() {
+ if (this.marker != null) {
+ this.marker.setLabel(this.getName());
+ FixedLocation loc = this.getLocation();
+ this.marker.setLocation(this.getWorld(), loc.x, loc.y, loc.z);
+ this.updateAdditionalMarkerData();
+ }
+ }
+
+ private void updateAdditionalMarkerData() {
+ if (this.marker != null) {
+ this.marker.setDescription("Owner: " + this.getOwner() + "
Creator: " + this.getCreator());
+ }
+ }
+
+ public void setWarmUp(int warmup) {
+ this.warmup = warmup;
+ }
+
+ public int getWarmUp() {
+ return this.warmup;
+ }
+
+ public void setCoolDown(int cooldown) {
+ this.cooldown = cooldown;
+ }
+
+ public int getCoolDown() {
+ return this.cooldown;
+ }
+
+ public void setVisibility(Visibility visibility) {
+ this.visibility = visibility;
+ this.checkMarker();
+ }
+
+ public Visibility getVisibility() {
+ return this.visibility;
+ }
+
+ @Override
+ public String getType() {
+ return "warp";
+ }
+
+ @Override
+ public boolean isValid() {
+ return this.location.isValid();
+ }
+
+ private void deleteMarker() {
+ // marker == null -> nothing to delete, markerset == null -> already invalid
+ if (this.marker != null && this.marker.getMarkerSet() != null) {
+ this.marker.deleteMarker();
+ }
+ this.marker = null;
+ }
+
+ private void checkMarker() {
+ if (this.manager != null) {
+ final boolean visible = this.manager.getMarkerSet() != null && this.manager.getMarkerIcon() != null && this.manager.getMarkerVisibilities().contains(this.getVisibility());
+ this.deleteMarker();
+ if (visible) {
+ FixedLocation loc = this.getLocation();
+ this.marker = this.manager.getMarkerSet().createMarker("xwarp.warp.obj" + markerId++, this.getName(), this.getWorld(), loc.x, loc.y, loc.z, this.manager.getMarkerIcon(), false);
+ this.updateAdditionalMarkerData();
+ }
+ } else {
+ this.deleteMarker();
+ }
+ }
+
+ public void setMarkerManager(MarkerManager manager) {
+ this.manager = manager;
+ this.checkMarker();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/xzise/xwarp/WarpDestination.java b/src/main/java/de/xzise/xwarp/WarpDestination.java
new file mode 100644
index 0000000000..77fe724ecc
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/WarpDestination.java
@@ -0,0 +1,11 @@
+package de.xzise.xwarp;
+
+public class WarpDestination {
+ public final String name;
+ public final String owner;
+
+ public WarpDestination(String name, String owner) {
+ this.name = name;
+ this.owner = owner;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/xzise/xwarp/WarpManager.java b/src/main/java/de/xzise/xwarp/WarpManager.java
new file mode 100644
index 0000000000..9cc0af0134
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/WarpManager.java
@@ -0,0 +1,819 @@
+package de.xzise.xwarp;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.bukkit.ChatColor;
+import org.bukkit.World;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.Plugin;
+import org.dynmap.markers.MarkerAPI;
+import org.dynmap.markers.MarkerIcon;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.metainterfaces.CommandSenderWrapper;
+import de.xzise.metainterfaces.LocationWrapper;
+import de.xzise.metainterfaces.Nameable;
+import de.xzise.wrappers.economy.EconomyHandler;
+import de.xzise.xwarp.Warp.Visibility;
+import de.xzise.xwarp.commands.warp.ListCommand.CreatorOptions;
+import de.xzise.xwarp.commands.warp.ListCommand.OwnerOptions;
+import de.xzise.xwarp.commands.warp.ListCommand.VisibilityOptions;
+import de.xzise.xwarp.commands.warp.ListCommand.WhiteBlackList;
+import de.xzise.xwarp.commands.warp.ListCommand.WorldOptions;
+import de.xzise.xwarp.dataconnections.DataConnection;
+import de.xzise.xwarp.dataconnections.HModConnection;
+import de.xzise.xwarp.dataconnections.IdentificationInterface;
+import de.xzise.xwarp.editors.EditorPermissions;
+import de.xzise.xwarp.editors.EditorPermissions.Type;
+import de.xzise.xwarp.editors.WarpPermissions;
+import de.xzise.xwarp.list.WarpList;
+import de.xzise.xwarp.timer.CoolDown;
+import de.xzise.xwarp.timer.WarmUp;
+import de.xzise.xwarp.warpable.Positionable;
+import de.xzise.xwarp.warpable.Warpable;
+import de.xzise.xwarp.wrappers.permission.Groups;
+import de.xzise.xwarp.wrappers.permission.PermissionTypes;
+import de.xzise.xwarp.wrappers.permission.PermissionValues;
+import de.xzise.xwarp.wrappers.permission.WPAPermissions;
+
+/**
+ * Wraps around {@link WarpList} to provide permissions support.
+ *
+ * @author Fabian Neundorf
+ */
+public class WarpManager extends CommonManager> {
+
+ private DataConnection data;
+ private final CoolDown coolDown;
+ private final WarmUp warmUp;
+ private final PluginProperties properties;
+ private final File dataDirectory;
+ private final MarkerManager manager;
+ private EconomyHandler economy;
+ private Manager wpaManager;
+
+ private static int markerSetId = 0;
+
+ public WarpManager(Plugin plugin, EconomyHandler economy, PluginProperties properties, DataConnection data) {
+ super(new WarpList(), "warp", properties, plugin.getServer());
+ this.coolDown = new CoolDown(plugin, properties);
+ this.warmUp = new WarmUp(plugin, properties, this.coolDown);
+ this.economy = economy;
+ this.properties = properties;
+ this.dataDirectory = plugin.getDataFolder();
+ this.manager = new MarkerManager(properties);
+ this.reload(data);
+ }
+
+ public WarmUp getWarmUp() {
+ return this.warmUp;
+ }
+
+ public void setWPAManager(Manager manager) {
+ this.wpaManager = manager;
+ }
+
+ @Override
+ public void reload(DataConnection data) {
+ super.reload(data);
+ this.data = data;
+ this.list.loadList(this.data.getWarps());
+ this.updateMarkerAPI();
+ }
+
+ /**
+ * Returns the number of warps a player has created.
+ *
+ * @param creator
+ * The creator of the warps. Has to be not null.
+ * @param visibility
+ * The visibility of the warps. Set to null if want to show all
+ * visibilites.
+ * @param world
+ * The world the warps has to be in. If null, it checks all
+ * worlds.
+ * @return The number of warps the player has created (with the desired
+ * visibility).
+ * @see {@link WarpList#getNumberOfWarps(String, Visibility, String)}
+ */
+ public int getAmountOfWarps(String creator, Visibility visibility, String world) {
+ return this.list.getNumberOfWarps(creator, visibility, world);
+ }
+
+ private void printPayMessage(CommandSender payee, double amount) {
+ if (amount > -0.0000001 && amount < 0.0000001) {
+ if (this.properties.showFreePriceMessage()) {
+ String freePriceMessage = "Yeah. This warp was " + ChatColor.GREEN + "free" + ChatColor.WHITE;
+ // Little easteregg: Print with a 1 % change the (as beer) text
+ if (Math.random() < 0.01) {
+ freePriceMessage += " (as beer)";
+ }
+ payee.sendMessage(freePriceMessage + "!");
+ }
+ } else if (amount > 0) {
+ payee.sendMessage(ChatColor.WHITE + "You have paid " + ChatColor.GREEN + this.economy.format(amount) + ChatColor.WHITE + ".");
+ } else {
+ payee.sendMessage("Woooo! You got " + ChatColor.GREEN + this.economy.format(-amount) + ChatColor.WHITE + "!");
+ }
+ }
+
+ private boolean isInProtectionArea(Positionable sender) {
+ return this.isInProtectionArea(sender, sender instanceof Nameable ? ((Nameable) sender).getName() : MinecraftUtil.getPlayerName(sender));
+ }
+
+ private boolean isInProtectionArea(Positionable sender, String creator) {
+ List inProtectionArea = new ArrayList();
+ boolean skipProtectionTest = XWarp.permissions.permission(CommandSenderWrapper.getCommandSender(sender), WPAPermissions.ADMIN_IGNORE_PROTECTION_AREA);
+
+ if (!skipProtectionTest && this.wpaManager != null) {
+ for (WarpProtectionArea area : this.wpaManager.getWarpObjects()) {
+ if (area.isWithIn(sender) && creator != null && !area.isAllowed(creator)) {
+ inProtectionArea.add(area.getName());
+ }
+ }
+ }
+
+ if (!skipProtectionTest && inProtectionArea.size() > 0) {
+ switch (inProtectionArea.size()) {
+ case 1:
+ sender.sendMessage(ChatColor.RED + "Here is the warp protection area '" + inProtectionArea.get(0) + "'.");
+ break;
+ case 2:
+ case 3:
+ case 4:
+ sender.sendMessage(ChatColor.RED + "Here are following warp protection areas:");
+ for (String areaName : inProtectionArea) {
+ sender.sendMessage(ChatColor.RED + "- '" + areaName + "'");
+ }
+ break;
+ default :
+ sender.sendMessage(ChatColor.RED + "Here are " + inProtectionArea.size() + " warp protection areas.");
+ break;
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void addWarp(String name, Positionable player, String newOwner, Visibility visibility) {
+ Warp warp = this.list.getWarpObject(name, newOwner, null);
+ Warp globalWarp = (visibility == Visibility.GLOBAL ? this.list.getWarpObject(name) : null);
+ if ((warp == null && globalWarp == null) || !this.properties.isCreationUpdating()) {
+ if (globalWarp != warp && Visibility.GLOBAL == visibility)
+ XWarp.logger.info("Everything okay! But inform the developer (xZise), that the global warp wasn't equals warp!");
+ PermissionTypes type = Groups.CREATE_GROUP.get(visibility);
+ PermissionValues limit = Groups.LIMIT_GROUP.get(visibility);
+
+ CommandSender sender = CommandSenderWrapper.getCommandSender(player);
+
+ if (XWarp.permissions.permission(sender, type)) {
+ final String creator;
+ if (player instanceof Nameable) {
+ creator = ((Nameable) player).getName();
+ } else {
+ creator = MinecraftUtil.getPlayerName(player);
+ }
+ if (XWarp.permissions.permission(sender, PermissionTypes.EDIT_CHANGE_OWNER) || creator.equals(newOwner)) {
+ final String world = player.getLocation().getWorld().getName();
+ int warpsByCreator = this.list.getNumberOfWarps(creator, visibility, world);
+ int totalWarpsByCreator = this.list.getNumberOfWarps(creator, null, world);
+ int allowedMaximum = XWarp.permissions.getInteger(sender, limit);
+ int allowedTotalMaximum = XWarp.permissions.getInteger(sender, PermissionValues.WARP_LIMIT_TOTAL);
+ if (warpsByCreator >= allowedMaximum && allowedMaximum >= 0) {
+ player.sendMessage(ChatColor.RED + "You are allowed to create only " + allowedMaximum + " warps.");
+ } else if (totalWarpsByCreator >= allowedTotalMaximum && allowedTotalMaximum >= 0) {
+ player.sendMessage(ChatColor.RED + "You are allowed to create only " + allowedTotalMaximum + " warps in total.");
+ } else {
+ if (warp != null) {
+ sender.sendMessage(ChatColor.RED + "Warp called '" + name + "' already exists (" + warp.getName() + ").");
+ } else if (visibility == Visibility.GLOBAL && globalWarp != null) {
+ sender.sendMessage(ChatColor.RED + "Global warp called '" + name + "' already exists (" + globalWarp.getName() + ").");
+ } else {
+ if (!isInProtectionArea(player, creator)) {
+ double price = XWarp.permissions.getDouble(sender, Groups.PRICES_CREATE_GROUP.get(visibility));
+
+ switch (this.economy.pay(sender, price)) {
+ case PAID:
+ this.printPayMessage(sender, price);
+ case UNABLE:
+ warp = new Warp(name, creator, newOwner, new LocationWrapper(player.getLocation()));
+ warp.setVisibility(visibility);
+ warp.setMarkerManager(this.manager);
+ this.list.addWarpObject(warp);
+ this.data.addWarp(warp);
+ sender.sendMessage("Successfully created '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "'.");
+ switch (visibility) {
+ case PRIVATE:
+ WarpManager.printPrivatizeMessage(sender, warp);
+ break;
+ case PUBLIC:
+ if (XWarp.permissions.permissionOr(sender, PermissionTypes.CREATE_PRIVATE, PermissionTypes.ADMIN_PRIVATE)) {
+ sender.sendMessage("If you'd like to privatize it, use:");
+ sender.sendMessage(ChatColor.GREEN + "/warp private \"" + warp.getName() + "\" " + warp.getOwner());
+ }
+ break;
+ case GLOBAL:
+ sender.sendMessage("This warp is now global available.");
+ break;
+ }
+ break;
+ case NOT_ENOUGH:
+ sender.sendMessage(ChatColor.RED + "You have not enough money to pay this creation.");
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ player.sendMessage(ChatColor.RED + "You have no permission to add a warp for somebody else.");
+ }
+ } else {
+ player.sendMessage(ChatColor.RED + "You have no permission to add a warp.");
+ }
+ } else {
+ this.updateLocation(warp, player);
+ }
+ }
+
+ @Override
+ public void delete(Warp warp, CommandSender sender) {
+ if (warp.canModify(sender, WarpPermissions.DELETE)) {
+ warp.setMarkerManager(null);
+ this.list.deleteWarpObject(warp);
+ this.data.deleteWarp(warp);
+ sender.sendMessage("You have deleted '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "'.");
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to delete '" + warp.getName() + "'");
+ }
+ }
+
+ @Override
+ public void setCreator(Warp warp, CommandSender sender, String newCreator) {
+ if (XWarp.permissions.permission(sender, PermissionTypes.ADMIN_CHANGE_CREATOR)) {
+ if (warp.isCreator(newCreator)) {
+ sender.sendMessage(ChatColor.RED + newCreator + " is already the creator.");
+ } else {
+ warp.setCreator(newCreator);
+ this.data.updateCreator(warp);
+ sender.sendMessage("You have changed the creator of '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "' to " + ChatColor.GREEN + newCreator + ChatColor.WHITE + ".");
+ Player match = server.getPlayer(newCreator);
+ if (match != null) {
+ match.sendMessage("You're now creator of '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "' by " + MinecraftUtil.getName(sender));
+ }
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to give '" + warp.getName() + "'");
+ }
+ }
+
+ @Override
+ public void setOwner(Warp warp, CommandSender sender, String owner) {
+ if (warp.canModify(sender, WarpPermissions.GIVE)) {
+ if (warp.isOwn(owner)) {
+ sender.sendMessage(ChatColor.RED + owner + " is already the owner.");
+ } else {
+ Warp giveeWarp = this.getWarpObject(warp.getName(), owner, null);
+ if (giveeWarp == null) {
+ String preOwner = warp.getOwner();
+ IdentificationInterface ii = this.data.createWarpIdentification(warp);
+ warp.setOwner(owner);
+ this.list.updateOwner(warp, preOwner);
+ this.data.updateOwner(warp, ii);
+ sender.sendMessage("You have given '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "' to " + ChatColor.GREEN + owner + ChatColor.WHITE + ".");
+ Player match = this.server.getPlayer(owner);
+ if (match != null) {
+ match.sendMessage("You've been given '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "' by " + MinecraftUtil.getName(sender));
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "The new owner already has a warp named " + giveeWarp.getName());
+ }
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to give '" + warp.getName() + "'");
+ }
+ }
+
+ public void setMessage(Warp warp, CommandSender sender, String message) {
+ if (warp.canModify(sender, WarpPermissions.MESSAGE)) {
+ warp.setWelcomeMessage(message);
+ this.data.updateMessage(warp);
+ sender.sendMessage("You have successfully changed the welcome message.");
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to set the message of '" + warp.getName() + "'");
+ }
+ }
+
+ private boolean changeVisibility(CommandSender sender, Warp warp, Visibility visibility) {
+ int warpsByCreator = this.list.getNumberOfWarps(warp.getCreator(), visibility, warp.getWorld());
+ int totalWarpsByCreator = this.list.getNumberOfWarps(warp.getCreator(), null, warp.getWorld());
+ int allowedMaximum = XWarp.permissions.getInteger(sender, Groups.LIMIT_GROUP.get(visibility));
+ int allowedTotalMaximum = XWarp.permissions.getInteger(sender, PermissionValues.WARP_LIMIT_TOTAL);
+ if (warpsByCreator >= allowedMaximum && allowedMaximum >= 0) {
+ sender.sendMessage(ChatColor.RED + "The creator is allowed to create only " + allowedMaximum + " warps.");
+ } else if (totalWarpsByCreator >= allowedTotalMaximum && allowedTotalMaximum >= 0) {
+ sender.sendMessage(ChatColor.RED + "The creator is allowed to create only " + allowedTotalMaximum + " warps in total.");
+ } else {
+ double price = XWarp.permissions.getDouble(sender, Groups.PRICES_CREATE_GROUP.get(visibility));
+
+ switch (this.economy.pay(sender, price)) {
+ case PAID:
+ this.printPayMessage(sender, price);
+ case UNABLE:
+ warp.setVisibility(visibility);
+ this.list.updateVisibility(warp);
+ this.data.updateVisibility(warp);
+ return true;
+ case NOT_ENOUGH:
+ sender.sendMessage(ChatColor.RED + "You have not enough money to pay the change.");
+ break;
+ }
+ }
+
+ return false;
+ }
+
+ public void privatize(Warp warp, CommandSender sender) {
+ if (warp.canModify(sender, WarpPermissions.PRIVATE)) {
+ if (this.changeVisibility(sender, warp, Visibility.PRIVATE)) {
+ WarpManager.printPrivatizeMessage(sender, warp);
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to privatize '" + warp.getName() + "'");
+ }
+ }
+
+ public void publicize(Warp warp, CommandSender sender) {
+ if (warp.canModify(sender, WarpPermissions.PUBLIC)) {
+ if (this.changeVisibility(sender, warp, Visibility.PUBLIC)) {
+ sender.sendMessage(ChatColor.AQUA + "You have publicized '" + warp.getName() + "'");
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to publicize '" + warp.getName() + "'");
+ }
+ }
+
+ public void globalize(Warp warp, CommandSender sender) {
+ if (warp.canModify(sender, WarpPermissions.GLOBAL)) {
+ Warp existing = this.list.getWarpObject(warp.getName());
+ if (existing == null || existing.getVisibility() != Visibility.GLOBAL) {
+ if (this.changeVisibility(sender, warp, Visibility.GLOBAL)) {
+ sender.sendMessage("You have globalized '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "'");
+ }
+ } else if (existing.equals(warp) && existing.getVisibility() == Visibility.GLOBAL) {
+ sender.sendMessage(ChatColor.RED + "This warp is already globalized.");
+ } else {
+ sender.sendMessage(ChatColor.RED + "One global warp with this name already exists.");
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to globalize '" + warp.getName() + "'");
+ }
+ }
+
+ public void setPrice(Warp warp, CommandSender sender, double price) {
+ WarpPermissions p;
+ if (price < 0) {
+ p = WarpPermissions.FREE;
+ } else {
+ p = WarpPermissions.PRICE;
+ }
+ if (warp.canModify(sender, p)) {
+ warp.setPrice(price);
+ this.data.updatePrice(warp);
+ if (price < 0) {
+ sender.sendMessage(ChatColor.AQUA + "Everybody could now warp for free to '" + warp.getName() + "'.");
+ } else {
+ sender.sendMessage(ChatColor.AQUA + "You have set the price for '" + warp.getName() + "'");
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to change the price of '" + warp.getName() + "'");
+ }
+ }
+
+ @Override
+ public void invite(Warp warp, CommandSender sender, String inviteeName) {
+ if (warp.canModify(sender, WarpPermissions.INVITE)) {
+ if (warp.hasPlayerPermission(inviteeName, WarpPermissions.WARP)) {
+ sender.sendMessage(ChatColor.RED + inviteeName + " is already invited to this warp.");
+ } else if (warp.isOwn(inviteeName)) {
+ sender.sendMessage(ChatColor.RED + inviteeName + " is the creator, of course he's the invited!");
+ } else {
+ warp.invite(inviteeName);
+ this.data.updateEditor(warp, inviteeName, Type.PLAYER);
+ sender.sendMessage("You have invited " + ChatColor.GREEN + inviteeName + ChatColor.WHITE + " to '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "'.");
+ if (warp.getVisibility() != Visibility.PRIVATE) {
+ sender.sendMessage(ChatColor.RED + "But '" + warp.getName() + "' is still public.");
+ }
+ Player match = this.server.getPlayer(inviteeName);
+ if (match != null) {
+ match.sendMessage("You've been invited to warp '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "' by " + ChatColor.GREEN + MinecraftUtil.getName(sender) + ChatColor.WHITE + ".");
+ match.sendMessage("Use: " + ChatColor.GREEN + "/warp [to] \"" + warp.getName() + "\" " + warp.getOwner() + ChatColor.WHITE + " to warp to it.");
+ }
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to invite players to '" + warp.getName() + "'.");
+ }
+ }
+
+ @Override
+ public void uninvite(Warp warp, CommandSender sender, String inviteeName) {
+ if (warp.canModify(sender, WarpPermissions.UNINVITE)) {
+ if (!warp.hasPlayerPermission(inviteeName, WarpPermissions.WARP)) {
+ sender.sendMessage(ChatColor.RED + inviteeName + " is not invited to this warp.");
+ } else if (warp.isOwn(inviteeName)) {
+ sender.sendMessage(ChatColor.RED + "You can't uninvite yourself. You're the creator!");
+ } else {
+ EditorPermissions permissions = warp.getEditorPermissions(inviteeName, Type.PLAYER);
+ if (permissions != null && permissions.remove(WarpPermissions.WARP)) {
+ this.data.updateEditor(warp, inviteeName, Type.PLAYER);
+ sender.sendMessage("You have uninvited " + ChatColor.GREEN + inviteeName + ChatColor.WHITE + " from '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "'.");
+ if (warp.getVisibility() != Visibility.PRIVATE) {
+ sender.sendMessage(ChatColor.RED + "But '" + warp.getName() + "' is still public.");
+ }
+ Player match = this.server.getPlayer(inviteeName);
+ if (match != null) {
+ match.sendMessage("You've been uninvited to warp '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "' by " + ChatColor.GREEN + MinecraftUtil.getName(sender) + ChatColor.WHITE + ". Sorry.");
+ }
+ }
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to uninvite players from '" + warp.getName() + "'.");
+ }
+ }
+
+ @Override
+ public void setName(Warp warp, CommandSender sender, String newName) {
+ if (warp.canModify(sender, WarpPermissions.RENAME)) {
+ String owner = warp.getOwner();
+ if (warp.getVisibility() == Visibility.GLOBAL && (this.getWarpObject(newName, null, null) != null)) {
+ sender.sendMessage(ChatColor.RED + "A global warp with this name already exists!");
+ } else if (this.getWarpObject(newName, owner, null) != null) {
+ sender.sendMessage(ChatColor.RED + "You already have a warp with this name.");
+ } else {
+ IdentificationInterface ii = this.data.createWarpIdentification(warp);
+ this.list.deleteWarpObject(warp);
+ warp.setName(newName);
+ this.list.addWarpObject(warp);
+ this.data.updateName(warp, ii);
+ sender.sendMessage(ChatColor.AQUA + "You have renamed '" + warp.getName() + "'");
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to change the position from '" + warp.getName() + "'");
+ }
+ }
+
+ @Override
+ public void addEditor(Warp warp, CommandSender sender, String editor, EditorPermissions.Type type, String permissions) {
+ if (warp.canModify(sender, WarpPermissions.ADD_EDITOR)) {
+ warp.addEditor(editor, permissions, type);
+ this.data.updateEditor(warp, editor, type);
+ sender.sendMessage("You have added " + ChatColor.GREEN + editor + ChatColor.WHITE + " to '" + warp.getName() + ChatColor.WHITE + "'.");
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to add an editor from '" + warp.getName() + "'");
+ }
+ }
+
+ @Override
+ public void removeEditor(Warp warp, CommandSender sender, String editor, EditorPermissions.Type type) {
+ if (warp.canModify(sender, WarpPermissions.REMOVE_EDITOR)) {
+ warp.removeEditor(editor, type);
+ this.data.updateEditor(warp, editor, type);
+ sender.sendMessage("You have removed " + ChatColor.GREEN + editor + ChatColor.WHITE + " from '" + warp.getName() + ChatColor.WHITE + "'.");
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to remove an editor from '" + warp.getName() + "'");
+ }
+ }
+
+ public MatchList getMatches(String name, CommandSender sender) {
+ ArrayList exactMatches = new ArrayList();
+ ArrayList matches = new ArrayList();
+ List all = Lists.newArrayList(this.getWarpObjects());
+
+ for (int i = 0; i < all.size(); i++) {
+ Warp warp = all.get(i);
+ if (warp.isListed(sender)) {
+ if (warp.getName().equalsIgnoreCase(name)) {
+ exactMatches.add(warp);
+ } else if (warp.getName().toLowerCase().contains(name.toLowerCase())) {
+ matches.add(warp);
+ }
+ }
+ }
+
+ Collections.sort(exactMatches, Warp.WARP_NAME_COMPARATOR);
+ Collections.sort(matches, Warp.WARP_NAME_COMPARATOR);
+ return new MatchList(exactMatches, matches);
+ }
+
+ public void blindAdd(Warp warp) {
+ this.list.addWarpObject(warp);
+ warp.setMarkerManager(this.manager);
+ // if (this.getWarp(warp.name) == null) {
+ // this.global.put(warp.name.toLowerCase(), warp);
+ // } else if (warp.visibility == Visibility.GLOBAL) {
+ // throw new
+ // IllegalArgumentException("A global warp could not override an existing one.");
+ // }
+ // if (!putIntoPersonal(personal, warp)) {
+ // throw new
+ // IllegalArgumentException("A personal warp could not override an existing one.");
+ // }
+ }
+
+ public void updateLocation(Warp warp, Positionable player) {
+ if (warp.canModify(player, WarpPermissions.UPDATE)) {
+ if (!this.isInProtectionArea(player)) {
+ warp.setLocation(player);
+ this.data.updateLocation(warp);
+ player.sendMessage("You have updated '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "'.");
+ }
+ } else {
+ player.sendMessage(ChatColor.RED + "You do not have permission to change the position from '" + warp.getName() + "'");
+ }
+ }
+
+ public void warpTo(String name, String owner, CommandSender warper, Warpable warped, boolean viaSign) {
+ Warp warp = this.getWarpObject(name, owner, MinecraftUtil.getPlayerName(warper));
+ if (warp != null) {
+ this.warpTo(warp, warper, warped, viaSign, this.properties.isForceToUsed());
+ } else {
+ this.missing(name, owner, warped);
+ }
+ }
+
+ public void warpTo(Warp warp, CommandSender warper, Warpable warped, boolean viaSign, boolean forced) {
+ if (warp.getLocationWrapper().isValid()) {
+ if (warped.equals(warper) || XWarp.permissions.permission(warper, PermissionTypes.ADMIN_WARP_OTHERS)) {
+ if (warp.playerCanWarp(warper, viaSign)) {
+ if (!forced && !warp.isSave()) {
+ warper.sendMessage(ChatColor.RED + "The selected warp is maybe not save!");
+ warper.sendMessage(ChatColor.RED + "To force warping use /warp force-to [owner].");
+ } else {
+ double price = XWarp.permissions.getDouble(warper, Groups.PRICES_TO_GROUP.get(warp.getVisibility()));
+
+ if (this.coolDown.playerHasCooled(warper)) {
+ if (warp.isFree()) {
+ this.printPayMessage(warper, 0);
+ this.warmUp.addPlayer(warper, warped, warp);
+ } else {
+ switch (this.economy.pay(warper, warp.getOwner(), warp.getPrice(), price)) {
+ case PAID:
+ double totalPrice = warp.getPrice() + price;
+ this.printPayMessage(warper, totalPrice);
+ case UNABLE:
+ this.warmUp.addPlayer(warper, warped, warp);
+ break;
+ case NOT_ENOUGH:
+ warper.sendMessage(ChatColor.RED + "You have not enough money to pay this warp.");
+ break;
+ }
+ }
+ } else {
+ warper.sendMessage(ChatColor.RED + "You need to wait for the cooldown of " + CoolDown.getCooldownTime(warp, warper) + " s");
+ }
+ }
+ } else {
+ warped.sendMessage(ChatColor.RED + "You do not have permission to warp to '" + warp.getName() + "'.");
+ }
+ } else {
+ warper.sendMessage(ChatColor.RED + "You do not have permission to warp others.");
+ }
+ } else {
+ warper.sendMessage(ChatColor.RED + "The location of the warp is invalid.");
+ }
+ }
+
+ private static boolean getWhiteBlackListed(Boolean... booleans) {
+ for (Boolean b : booleans) {
+ if (b != null && !b) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static boolean isSet(WhiteBlackList, ?> whiteBlackList) {
+ return !whiteBlackList.isEmpty();
+ }
+
+ public List getWarps(CommandSender sender, CreatorOptions creators, OwnerOptions owners, WorldOptions worlds, VisibilityOptions visibilities) {
+ List allWarps = new ArrayList();
+
+ //TODO: Update MU.isSet() for "setable" interface
+ if (MinecraftUtil.isSet(owners.getWhitelist())) {
+ for (String owner : owners.getWhitelist()) {
+ allWarps.addAll(this.list.getWarps(owner));
+ }
+ } else {
+ allWarps.addAll(this.list.getWarpObjects());
+ }
+
+ ArrayList validWarps = new ArrayList(allWarps.size());
+
+ boolean noOptions = !(isSet(creators) || isSet(owners) || isSet(worlds) || isSet(visibilities));
+ for (int i = allWarps.size() - 1; i >= 0; i--) {
+ Warp w = allWarps.get(i);
+ if ((noOptions || getWhiteBlackListed(creators.call(w), owners.call(w), worlds.call(w), visibilities.call(w))) && w.isListed(sender)) {
+ validWarps.add(w);
+ }
+ }
+
+ if (validWarps.size() > 0) {
+ // Removes everything which was to much
+ validWarps.trimToSize();
+ Collections.sort(validWarps, Warp.WARP_NAME_COMPARATOR);
+ }
+
+ return validWarps;
+ }
+
+ public int getSize(CommandSender sender, String creator) {
+ return this.list.getSize(sender, creator);
+ }
+
+ @Override
+ public void missing(String name, String owner, CommandSender sender) {
+ if (owner == null || owner.isEmpty()) {
+ if (this.list.isAmbiguous(name)) {
+ sender.sendMessage(ChatColor.RED + "The warp name '" + name + "' is ambiguous.");
+ } else {
+ sender.sendMessage(ChatColor.RED + "Warp named '" + name + "' doesn't exist.");
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "Player '" + owner + "' doesn't own a warp named '" + name + "'.");
+ }
+ }
+
+ public int getNumberOfWarpsByName(final String warpName) {
+ return this.list.getNumberOfWarpsByName(warpName);
+ }
+
+ @Deprecated
+ public static void sendMissingWarp(String name, String owner, CommandSender sender) {
+ if (owner == null || owner.isEmpty()) {
+ sender.sendMessage(ChatColor.RED + "Global warp '" + name + "' doesn't exist.");
+ } else {
+ sender.sendMessage(ChatColor.RED + "Player '" + owner + "' doesn't own a warp named '" + name + "'.");
+ }
+ }
+
+ private static void printPrivatizeMessage(CommandSender sender, Warp warp) {
+ sender.sendMessage(ChatColor.WHITE + "You have privatized '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "'");
+ sender.sendMessage("If you'd like to invite others to it, use:");
+ sender.sendMessage(ChatColor.GREEN + "/warp invite \"" + warp.getName() + "\" " + warp.getOwner() + " ");
+ }
+
+ public void setListed(final Warp warp, final boolean listed) {
+ warp.setListed(listed);
+ this.data.updateVisibility(warp);
+ }
+
+ public void setListed(Warp warp, CommandSender sender, final boolean listed) {
+ if (warp.canModify(sender, WarpPermissions.LIST)) {
+ this.setListed(warp, listed);
+ sender.sendMessage("You have " + (listed ? "listed" : "unlisted") + " '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "'.");
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to change the listed status from '" + warp.getName() + "'");
+ }
+ }
+
+ public static interface WarpObjectGetter> {
+ List get();
+ }
+
+ public static class WarpGetter implements WarpObjectGetter {
+
+ private final DataConnection connection;
+ private final String owner;
+
+ public WarpGetter(DataConnection connection, String owner) {
+ this.connection = connection;
+ this.owner = owner;
+ }
+
+ @Override
+ public List get() {
+ if (this.connection instanceof HModConnection) {
+ return ((HModConnection) this.connection).getWarps(this.owner);
+ } else {
+ return this.connection.getWarps();
+ }
+ }
+
+ }
+
+ @Override
+ protected void blindDataAdd(Warp... warps) {
+ this.data.addWarp(warps);
+ }
+
+ @Override
+ public int setWorld(World world) {
+ int result = 0;
+ for (Warp warp : this.getWarpObjects()) {
+ if (warp.getLocationWrapper().setWorld(world)) {
+ result++;
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public int unsetWorld(World world) {
+ int result = 0;
+ for (Warp warp : this.getWarpObjects()) {
+ if (warp.getLocationWrapper().unsetWorld(world)) {
+ result++;
+ }
+ }
+ return result;
+ }
+
+ public void setCooldown(Warp warp, CommandSender sender, int time) {
+ if (warp.canModify(sender, WarpPermissions.COOLDOWN)) {
+ warp.setCoolDown(time);
+ this.data.updateCoolDown(warp);
+ sender.sendMessage("You have successfully changed the cooldown.");
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to set the cooldown of '" + warp.getName() + "'");
+ }
+ }
+
+ public void setWarmup(Warp warp, CommandSender sender, int time) {
+ if (warp.canModify(sender, WarpPermissions.WARMUP)) {
+ warp.setWarmUp(time);
+ this.data.updateWarmUp(warp);
+ sender.sendMessage("You have successfully changed the warmup.");
+ } else {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to set the warmup of '" + warp.getName() + "'");
+ }
+ }
+
+ private void updateMarkerAPI() {
+ MarkerAPI api = this.manager.getMarkerAPI();
+ if (api != null) {
+ try {
+ InputStream is = new FileInputStream(new File(this.dataDirectory, this.properties.getMarkerPNG()));
+ MarkerIcon icon = api.getMarkerIcon("xwarp.warp.icon");
+ if (icon == null) {
+ icon = api.createMarkerIcon("xwarp.warp.icon", "Warps Icon", is);
+ } else {
+ try {
+ icon.setMarkerIconImage(is);
+ } catch (NoSuchMethodError e) {
+ XWarp.logger.info("Couldn't update icon, because dynmap isn't supporting this.");
+ }
+ }
+ if (icon != null) {
+ this.manager.setMarkerIcon(icon);
+ this.manager.setMarkerSet(api.createMarkerSet("xwarp.warp.set" + markerSetId++, "Warps", ImmutableSet.of(icon), false));
+ } else {
+ XWarp.logger.severe("Marker icon isn't set.");
+ }
+ } catch (FileNotFoundException e) {
+ XWarp.logger.severe("Unable to load marker file.", e);
+ }
+ }
+ this.updateWarpMarkers();
+ }
+
+ private void updateWarpMarkers() {
+ for (Warp warp : this.getWarpObjects()) {
+ warp.setMarkerManager(this.manager);
+ }
+ }
+
+ public void setMarkerAPI(MarkerAPI api) {
+ this.manager.setMarkerAPI(api);
+ if (api != null) {
+ this.updateMarkerAPI();
+ } else {
+ this.updateWarpMarkers();
+ }
+ }
+
+ public boolean isLinkedWithMarkerAPI() {
+ return this.manager.getMarkerAPI() != null;
+ }
+
+ @Override
+ public void changeWorld(CommandSender sender, String oldWorld, String newWorld) {
+ this.changeWorld(sender, oldWorld, newWorld, PermissionTypes.ADMIN_CHANGE_WORLD);
+ }
+
+ @Override
+ protected void setWorld(Warp warp, World newWorldObject, String newWorld) {
+ warp.setWorld(newWorld, newWorldObject);
+ this.data.updateLocation(warp);
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/WarpObject.java b/src/main/java/de/xzise/xwarp/WarpObject.java
new file mode 100644
index 0000000000..8586fa1532
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/WarpObject.java
@@ -0,0 +1,26 @@
+package de.xzise.xwarp;
+
+import org.bukkit.command.CommandSender;
+
+import com.google.common.collect.ImmutableSet;
+
+import de.xzise.xwarp.editors.Editor;
+import de.xzise.xwarp.editors.EditorPermissions;
+
+public interface WarpObject {
+
+ String getName();
+ String getOwner();
+ String getCreator();
+ String getWorld();
+ String getType();
+ boolean isListed(CommandSender sender);
+ boolean canModify(CommandSender sender, T permission);
+ boolean isValid();
+
+ void addEditor(String name, EditorPermissions.Type type, ImmutableSet permissions);
+ void removeEditor(String name, EditorPermissions.Type type);
+
+ T getInvitePermission();
+ boolean hasPermission(String name, T permission);
+}
diff --git a/src/main/java/de/xzise/xwarp/WarpProtectionArea.java b/src/main/java/de/xzise/xwarp/WarpProtectionArea.java
new file mode 100644
index 0000000000..a92062f978
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/WarpProtectionArea.java
@@ -0,0 +1,135 @@
+package de.xzise.xwarp;
+
+import org.bukkit.World;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.metainterfaces.FixedLocation;
+import de.xzise.xwarp.editors.WarpProtectionAreaPermissions;
+import de.xzise.xwarp.warpable.Positionable;
+import de.xzise.xwarp.wrappers.permission.WPAPermissions;
+
+public class WarpProtectionArea extends DefaultWarpObject {
+
+ private int index;
+ private final WorldWrapper world;
+ private final FixedLocation firstCorner;
+ private final FixedLocation secondCorner;
+
+ public static int nextIndex = 1;
+
+ public WarpProtectionArea(WorldWrapper world, FixedLocation firstCorner, FixedLocation secondCorner, String name, String owner, String creator) {
+ this(nextIndex, world, firstCorner, secondCorner, name, owner, creator);
+ }
+
+ public WarpProtectionArea(int index, WorldWrapper world, FixedLocation firstCorner, FixedLocation secondCorner, String name, String owner, String creator) {
+ //TODO: null as editor?!
+ super(name, owner, creator, null, WarpProtectionAreaPermissions.class, WarpProtectionAreaPermissions.OVERWRITE);
+ this.index = index;
+ this.world = world;
+ this.firstCorner = firstCorner;
+ this.secondCorner = secondCorner;
+ if (index > nextIndex)
+ nextIndex = index;
+ nextIndex++;
+ }
+
+ public boolean isWithIn(Positionable positionable) {
+ return this.isWithIn(new FixedLocation(positionable.getLocation()));
+ }
+
+ public void assignNewId() {
+ this.index = nextIndex++;
+ }
+
+ public boolean isWithIn(FixedLocation location) {
+ if (this.isValid() && location.world.equals(world.getWorld())) {
+ double lowerX = Math.min(this.firstCorner.x, this.secondCorner.x);
+ double upperX = Math.max(this.firstCorner.x, this.secondCorner.x);
+ double lowerY = Math.min(this.firstCorner.y, this.secondCorner.y);
+ double upperY = Math.max(this.firstCorner.y, this.secondCorner.y);
+ double lowerZ = Math.min(this.firstCorner.z, this.secondCorner.z);
+ double upperZ = Math.max(this.firstCorner.z, this.secondCorner.z);
+ double x = location.x;
+ double y = location.y;
+ double z = location.z;
+ return lowerX <= x && x <= upperX && lowerY <= y && y <= upperY && lowerZ <= z && z <= upperZ;
+ } else {
+ return false;
+ }
+ }
+
+ public static boolean isWithIn(final FixedLocation firstCorner, final FixedLocation secondCorner, final FixedLocation testLocation) {
+ if (testLocation.world.equals(firstCorner.world) && firstCorner.world.equals(secondCorner.world)) {
+ double lowerX = Math.min(firstCorner.x, secondCorner.x);
+ double upperX = Math.max(firstCorner.x, secondCorner.x);
+ double lowerY = Math.min(firstCorner.y, secondCorner.y);
+ double upperY = Math.max(firstCorner.y, secondCorner.y);
+ double lowerZ = Math.min(firstCorner.z, secondCorner.z);
+ double upperZ = Math.max(firstCorner.z, secondCorner.z);
+ double x = testLocation.x;
+ double y = testLocation.y;
+ double z = testLocation.z;
+ return lowerX <= x && x <= upperX && lowerY <= y && y <= upperY && lowerZ <= z && z <= upperZ;
+ } else {
+ return false;
+ }
+ }
+
+ public int getId() {
+ return this.index;
+ }
+
+ public boolean isAllowed(String name) {
+ if (name.equals(this.getOwner())) {
+ return true;
+ } else {
+ return this.hasPermission(name, WarpProtectionAreaPermissions.OVERWRITE);
+ }
+ }
+
+ @Override
+ public String getWorld() {
+ return this.world.getWorldName();
+ }
+
+ public boolean isListed() {
+ return true; //TODO: Add listed support.
+ }
+
+ @Override
+ public boolean isListed(CommandSender sender) {
+ if (!this.isListed() && !XWarp.permissions.permission(sender, WPAPermissions.ADMIN_LIST_VIEW)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean isValid() {
+ return this.world.isValid();
+ }
+
+ public FixedLocation getCorner(int index) {
+ switch (index) {
+ case 0 :
+ return this.firstCorner;
+ case 1 :
+ return this.secondCorner;
+ default :
+ return null;
+ }
+ }
+
+ @Override
+ public String getType() {
+ return "wpa";
+ }
+
+ public WorldWrapper getWorldWrapper() {
+ return this.world;
+ }
+
+ public void setWorld(String worldName, World world) {
+ this.world.setWorld(worldName, world);
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/WorldWrapper.java b/src/main/java/de/xzise/xwarp/WorldWrapper.java
new file mode 100644
index 0000000000..f867b3b155
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/WorldWrapper.java
@@ -0,0 +1,55 @@
+package de.xzise.xwarp;
+
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+
+public class WorldWrapper {
+
+ private World world;
+ private String worldName;
+
+ public WorldWrapper(String world) {
+ this.worldName = world;
+ this.world = Bukkit.getServer().getWorld(world);
+ }
+
+ public WorldWrapper(World world) {
+ this.worldName = world.getName();
+ this.world = world;
+ }
+
+ public boolean setWorld(World world) {
+ if (this.world == null && world.getName().equals(this.worldName)) {
+ this.world = world;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public boolean unsetWorld(World world) {
+ if (this.world == world && world != null) {
+ this.world = null;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public World getWorld() {
+ return this.world;
+ }
+
+ public String getWorldName() {
+ return this.worldName;
+ }
+
+ public void setWorld(String worldName, World world) {
+ this.worldName = worldName;
+ this.world = world;
+ }
+
+ public boolean isValid() {
+ return this.world != null;
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/XWarp.java b/src/main/java/de/xzise/xwarp/XWarp.java
new file mode 100644
index 0000000000..88940a383f
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/XWarp.java
@@ -0,0 +1,176 @@
+package de.xzise.xwarp;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.bukkit.World;
+import org.bukkit.event.Listener;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.XLogger;
+import de.xzise.wrappers.permissions.PermissionsHandler;
+import de.xzise.wrappers.economy.EconomyHandler;
+import de.xzise.xwarp.commands.ManageCommandMap;
+import de.xzise.xwarp.commands.WPACommandMap;
+import de.xzise.xwarp.commands.WarpCommandMap;
+import de.xzise.xwarp.dataconnections.DataConnection;
+import de.xzise.xwarp.listeners.XWBlockListener;
+import de.xzise.xwarp.listeners.XWEntityListener;
+import de.xzise.xwarp.listeners.XWPlayerListener;
+import de.xzise.xwarp.listeners.XWServerListener;
+import de.xzise.xwarp.listeners.XWWorldListener;
+import de.xzise.xwarp.wrappers.permission.GeneralPermissions;
+import de.xzise.xwarp.wrappers.permission.PermissionTypes;
+import de.xzise.xwarp.wrappers.permission.WPAPermissions;
+import de.xzise.xwarp.wrappers.permission.WorldPermission;
+
+public class XWarp extends JavaPlugin {
+
+ public static PermissionsHandler permissions;
+ public static XLogger logger;
+
+ private EconomyHandler economyHandler;
+ private PermissionsHandler permissionHandler = permissions;
+
+ private DataConnection dataConnection;
+
+ public String name;
+ public String version;
+ private boolean enableCanceled = true;
+
+ public XWarp() {
+ super();
+ }
+
+ @Override
+ public void onDisable() {
+ if (!this.enableCanceled) {
+ this.dataConnection.free();
+ XWarp.logger.disableMsg();
+ }
+ }
+
+ private void disable(String message) {
+ this.enableCanceled = true;
+ this.getServer().getLogger().severe("[" + this.getDescription().getName() + "] " + message);
+ this.getServer().getPluginManager().disablePlugin(this);
+ }
+
+ @Override
+ public void onEnable() {
+ try {
+ if (MinecraftUtil.needUpdate(1, 3)) {
+ this.disable("You need to update Bukkit Plugin Utilities to at least 1.3.0!");
+ return;
+ }
+ } catch (NoSuchMethodError e) {
+ this.disable("You need to update Bukkit Plugin Utilities to at least 1.3.0!");
+ return;
+ } catch (NoClassDefFoundError e) {
+ this.disable("No Bukkit Plugin Utilities found!");
+ return;
+ }
+ this.enableCanceled = false;
+ this.name = this.getDescription().getName();
+ this.version = this.getDescription().getVersion();
+ logger = new XLogger(this);
+
+ // Register permissions
+ MinecraftUtil.register(this.getServer().getPluginManager(), logger, PermissionTypes.values(), WPAPermissions.values(), GeneralPermissions.values());
+
+ if (!this.getDataFolder().exists()) {
+ this.getDataFolder().mkdirs();
+ }
+
+ if (new File("MyWarp").exists() && new File("MyWarp", "warps.db").exists()) {
+ this.updateFiles();
+ } else {
+ File old = new File("homes-warps.db");
+ File newFile = new File(this.getDataFolder(), "warps.db");
+ if (old.exists() && !newFile.exists()) {
+ XWarp.logger.info("No database found. Copying old database.");
+ try {
+ MinecraftUtil.copy(old, newFile);
+ } catch (IOException e) {
+ XWarp.logger.severe("Unable to copy database", e);
+ }
+ }
+ }
+
+ PluginProperties properties = new PluginProperties(this.getDataFolder(), this.getServer());
+
+ this.dataConnection = properties.getDataConnection();
+ try {
+ if (!this.dataConnection.load(properties.getDataConnectionFile())) {
+ XWarp.logger.severe("Could not load data. Disabling " + this.name + "!");
+ this.getServer().getPluginManager().disablePlugin(this);
+ return;
+ }
+ } catch (Exception e) {
+ XWarp.logger.severe("Could not load data. Disabling " + this.name + "!", e);
+ this.getServer().getPluginManager().disablePlugin(this);
+ return;
+ }
+
+ this.permissionHandler = new PermissionsHandler(this.getServer().getPluginManager(), this.getServer().getServicesManager(), properties.getPermissionsPlugin(), logger);
+ permissions = this.permissionHandler;
+ this.economyHandler = new EconomyHandler(this.getServer().getPluginManager(), this.getServer().getServicesManager(), properties.getEconomyPlugin(), properties.getEconomyBaseAccount(), logger);
+
+ WarpManager warpManager = new WarpManager(this, this.economyHandler, properties, this.dataConnection);
+ WPAManager wpaManager = new WPAManager(this, this.dataConnection, properties);
+
+ warpManager.setWPAManager(wpaManager);
+
+ XWServerListener serverListener = new XWServerListener(properties, this.getServer().getPluginManager(), warpManager, this.permissionHandler, this.economyHandler);
+
+ // Create commands
+ WarpCommandMap wcm = null;
+ WPACommandMap wpacm = null;
+ ManageCommandMap mcm = null;
+ try {
+ wcm = new WarpCommandMap(warpManager, this.economyHandler, this.getServer(), this.dataConnection, this.getDataFolder(), properties);
+ wpacm = new WPACommandMap(wpaManager, this.economyHandler, this.getServer(), this.dataConnection, this.getDataFolder(), properties);
+ mcm = new ManageCommandMap(this.economyHandler, serverListener, properties, this.getServer(), this.getDataFolder(), warpManager, wpaManager);
+ } catch (IllegalArgumentException iae) {
+ XWarp.logger.severe("Couldn't initalize commands. Disabling " + this.name + "!", iae);
+ this.getServer().getPluginManager().disablePlugin(this);
+ return;
+ }
+
+ this.getCommand("go").setExecutor(wcm.getCommand(""));
+ this.getCommand("xwarp").setExecutor(mcm);
+ this.getCommand("warp").setExecutor(wcm);
+ this.getCommand("wpa").setExecutor(wpacm);
+
+ XWPlayerListener playerListener = new XWPlayerListener(warpManager, properties, wpacm.createCommand);
+ XWBlockListener blockListener = new XWBlockListener(warpManager);
+ XWWorldListener worldListener = new XWWorldListener(this.getServer().getPluginManager(), warpManager, wpaManager);
+
+ // Unless an event is called, to tell all enabled plugins
+ serverListener.load();
+
+ // All worlds loaded before this plugin have to registered manually.
+ for (World world : this.getServer().getWorlds()) {
+ WorldPermission.register(world.getName(), this.getServer().getPluginManager());
+ }
+
+ serverListener.register(this);
+ registerEvents(this, worldListener, playerListener, blockListener, new XWEntityListener(properties, warpManager.getWarmUp()));
+ XWarp.logger.enableMsg();
+ }
+
+ private static void registerEvents(final Plugin plugin, final Listener... listeners) {
+ for (Listener listener : listeners) {
+ plugin.getServer().getPluginManager().registerEvents(listener, plugin);
+ }
+ }
+
+ private void updateFiles() {
+ File file = new File("MyWarp", "warps.db");
+ File folder = new File("MyWarp");
+ file.renameTo(new File(this.getDataFolder(), "warps.db"));
+ folder.delete();
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/AddEditorCommand.java b/src/main/java/de/xzise/xwarp/commands/AddEditorCommand.java
new file mode 100644
index 0000000000..bfcad13313
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/AddEditorCommand.java
@@ -0,0 +1,44 @@
+package de.xzise.xwarp.commands;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Manager;
+import de.xzise.xwarp.WarpObject;
+import de.xzise.xwarp.editors.EditorPermissions;
+
+public class AddEditorCommand, M extends Manager> extends EditorCommand {
+
+ public AddEditorCommand(M list, Server server, String label) {
+ super(list, server, label, new String[] { "editor", "permissions" }, "add-editor");
+ }
+
+ public static , M extends Manager> AddEditorCommand create(M manager, Server server, String label) {
+ return new AddEditorCommand(manager, server, label);
+ }
+
+ @Override
+ protected boolean executeEditorEdit(W warpObject, CommandSender sender, String editor, EditorPermissions.Type type, String[] parameters) {
+ if (parameters.length == 1) {
+ this.manager.addEditor(warpObject, sender, editor, type, parameters[0]);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Adds the editor to the warps editors list.", "The permissions define the allowed commands.", "Update (l), Rename (r), Uninvite (u), Invite (i), Private (0), Public (1), Global (2), Give (g), Delete (d), Warp (w).", "* allows all commands, s sets lruiw, all after a slash removes the permission", "Example: */d allows everthing except delete." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Adds the " + this.getParameterText(true, false, 0);
+ }
+
+ public boolean listHelp(CommandSender sender) {
+ return true;
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/ChangeCreatorCommand.java b/src/main/java/de/xzise/xwarp/commands/ChangeCreatorCommand.java
new file mode 100644
index 0000000000..5e01e16990
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/ChangeCreatorCommand.java
@@ -0,0 +1,35 @@
+package de.xzise.xwarp.commands;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Manager;
+import de.xzise.xwarp.WarpObject;
+
+public class ChangeCreatorCommand, M extends Manager> extends ManagerCommand {
+
+ public ChangeCreatorCommand(M manager, Server server, String label) {
+ super(manager, server, label, "player", "change-creator", "chcre");
+ }
+
+ public static , M extends Manager> ChangeCreatorCommand create(M manager, Server server, String label) {
+ return new ChangeCreatorCommand(manager, server, label);
+ }
+
+ @Override
+ public boolean executeEdit(W warp, CommandSender sender, String[] parameters) {
+ this.manager.setCreator(warp, sender, this.getPlayer(parameters[0]));
+ return true;
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Changes the creator of the warp." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Change the creator";
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/ChangeWorldCommand.java b/src/main/java/de/xzise/xwarp/commands/ChangeWorldCommand.java
new file mode 100644
index 0000000000..e2019b7f63
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/ChangeWorldCommand.java
@@ -0,0 +1,46 @@
+package de.xzise.xwarp.commands;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Manager;
+import de.xzise.xwarp.WarpObject;
+import de.xzise.xwarp.editors.Editor;
+
+public class ChangeWorldCommand extends DefaultSubCommand>> {
+
+ private final String label;
+
+ public ChangeWorldCommand(Manager extends WarpObject extends Editor>> manager, Server server, String label) {
+ super(manager, server, "change-world", "chwrld");
+ this.label = label;
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Changes the world of all warp objects in a specific world." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Changes the world";
+ }
+
+ @Override
+ public String getCommand() {
+ return label + " change-world ";
+ }
+
+ @Override
+ public boolean execute(CommandSender sender, String[] parameters) {
+ if (parameters.length == 3) {
+ String oldWorld = parameters[1];
+ String newWorld = parameters[2];
+ this.manager.changeWorld(sender, oldWorld, newWorld);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/DefaultSubCommand.java b/src/main/java/de/xzise/xwarp/commands/DefaultSubCommand.java
new file mode 100644
index 0000000000..40219f8b7c
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/DefaultSubCommand.java
@@ -0,0 +1,40 @@
+package de.xzise.xwarp.commands;
+
+import org.bukkit.Server;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.commands.CommonHelpableSubCommand;
+import de.xzise.xwarp.Manager;
+
+/**
+ * Command like list/create etc.
+ *
+ * @author Fabian Neundorf.
+ */
+public abstract class DefaultSubCommand> extends CommonHelpableSubCommand {
+
+ protected final M manager;
+ protected final Server server;
+
+ /**
+ * Creates a subcommand.
+ *
+ * @param list
+ * The list to all warps.
+ * @param server
+ * The server instance.
+ * @param commands
+ * The commands.
+ * @throws IllegalArgumentException
+ * If commands is empty.
+ */
+ protected DefaultSubCommand(M manager, Server server, String... commands) {
+ super(commands);
+ this.manager = manager;
+ this.server = server;
+ }
+
+ protected String getPlayer(String name) {
+ return MinecraftUtil.expandName(name, this.server);
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/DeleteCommand.java b/src/main/java/de/xzise/xwarp/commands/DeleteCommand.java
new file mode 100644
index 0000000000..ecd5061af3
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/DeleteCommand.java
@@ -0,0 +1,35 @@
+package de.xzise.xwarp.commands;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Manager;
+import de.xzise.xwarp.WarpObject;
+
+public class DeleteCommand, M extends Manager> extends ManagerCommand {
+
+ public DeleteCommand(M manager, Server server, String label) {
+ super(manager, server, label, "", "delete", "-");
+ }
+
+ public static , M extends Manager> DeleteCommand create(M manager, Server server, String label) {
+ return new DeleteCommand(manager, server, label);
+ }
+
+ @Override
+ protected boolean executeEdit(W warpObject, CommandSender sender, String[] parameters) {
+ this.manager.delete(warpObject, sender);
+ return true;
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Deletes the given warp." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Deletes the warp.";
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/EditorCommand.java b/src/main/java/de/xzise/xwarp/commands/EditorCommand.java
new file mode 100644
index 0000000000..7facf8cd2b
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/EditorCommand.java
@@ -0,0 +1,44 @@
+package de.xzise.xwarp.commands;
+
+import java.util.Arrays;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.xwarp.Manager;
+import de.xzise.xwarp.WarpObject;
+import de.xzise.xwarp.editors.EditorPermissions;
+import de.xzise.xwarp.editors.EditorPermissions.Type;
+
+public abstract class EditorCommand, M extends Manager> extends ManagerCommand {
+
+ protected EditorCommand(M manager, Server server, String label, String[] parameters, String... commands) {
+ super(manager, server, label, parameters, commands);
+ }
+
+ protected EditorCommand(M manager, Server server, String label, String parameterText, String... commands) {
+ super(manager, server, label, parameterText, commands);
+ }
+
+ @Override
+ public final boolean executeEdit(W warpObject, CommandSender sender, String[] parameters) {
+ String editor = parameters[0];
+ EditorPermissions.Type type;
+ if (editor.startsWith("p:")) {
+ type = Type.PERMISSIONS;
+ } else if (editor.startsWith("g:")) {
+ type = Type.GROUP;
+ } else {
+ type = Type.PLAYER;
+ if (!editor.startsWith("o:")) {
+ editor = MinecraftUtil.expandName(editor, this.server);
+ }
+ }
+
+ return this.executeEditorEdit(warpObject, sender, editor, type, Arrays.copyOfRange(parameters, 1, parameters.length));
+ }
+
+ protected abstract boolean executeEditorEdit(W warpObject, CommandSender sender, String editor, EditorPermissions.Type type, String[] parameters);
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/GiveCommand.java b/src/main/java/de/xzise/xwarp/commands/GiveCommand.java
new file mode 100644
index 0000000000..8ed7305b82
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/GiveCommand.java
@@ -0,0 +1,34 @@
+package de.xzise.xwarp.commands;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Manager;
+import de.xzise.xwarp.WarpObject;
+
+public class GiveCommand, M extends Manager> extends ManagerCommand {
+
+ public GiveCommand(M manager, Server server, String label) {
+ super(manager, server, label, "player", "give", "chown");
+ }
+
+ public static , M extends Manager> GiveCommand create(M manager, Server server, String label) {
+ return new GiveCommand(manager, server, label);
+ }
+
+ @Override
+ protected boolean executeEdit(W warpObject, CommandSender sender, String[] parameters) {
+ this.manager.setOwner(warpObject, sender, this.getPlayer(parameters[0]));
+ return true;
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Changes the owner of the warp." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Gives the warp away.";
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/InviteCommand.java b/src/main/java/de/xzise/xwarp/commands/InviteCommand.java
new file mode 100644
index 0000000000..32e2e5e472
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/InviteCommand.java
@@ -0,0 +1,36 @@
+package de.xzise.xwarp.commands;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Manager;
+import de.xzise.xwarp.WarpObject;
+
+public class InviteCommand, M extends Manager> extends ManagerCommand {
+
+ public InviteCommand(M list, Server server, String label) {
+ super(list, server, label, "invited", "invite");
+ }
+
+ public static , M extends Manager> InviteCommand create(M manager, Server server, String label) {
+ return new InviteCommand(manager, server, label);
+ }
+
+ @Override
+ protected boolean executeEdit(W warpObject, CommandSender sender, String[] parameters) {
+ this.manager.invite(warpObject, sender, this.getPlayer(parameters[0]));
+ return true;
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Adds the invited person to the permissions list.", "These person could use the warp." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Invites " + ChatColor.GREEN + "";
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/ManageCommandMap.java b/src/main/java/de/xzise/xwarp/commands/ManageCommandMap.java
new file mode 100644
index 0000000000..3e3687683a
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/ManageCommandMap.java
@@ -0,0 +1,42 @@
+package de.xzise.xwarp.commands;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.bukkit.Server;
+
+import de.xzise.commands.CommonCommandMap;
+import de.xzise.commands.CommonHelpCommand;
+import de.xzise.commands.SubCommand;
+import de.xzise.wrappers.economy.EconomyHandler;
+import de.xzise.xwarp.PluginProperties;
+import de.xzise.xwarp.WPAManager;
+import de.xzise.xwarp.WarpManager;
+import de.xzise.xwarp.XWarp;
+import de.xzise.xwarp.commands.xwarp.ExportCommand;
+import de.xzise.xwarp.commands.xwarp.ImportCommand;
+import de.xzise.xwarp.commands.xwarp.PermissionsCommand;
+import de.xzise.xwarp.commands.xwarp.ReloadCommand;
+import de.xzise.xwarp.commands.xwarp.StatusCommand;
+import de.xzise.xwarp.listeners.XWServerListener;
+
+public class ManageCommandMap extends CommonCommandMap {
+
+ public ManageCommandMap(EconomyHandler economyHandler, XWServerListener serverListener, PluginProperties properties, Server server, File dataPath, WarpManager warpManager, WPAManager wpaManager) {
+ super();
+
+ CommonHelpCommand helper = new CommonHelpCommand("xWarp");
+
+ Collection subCommands = new ArrayList();
+ subCommands.add(helper);
+ subCommands.add(new ReloadCommand(economyHandler, serverListener, properties, warpManager, wpaManager));
+ subCommands.add(new StatusCommand(economyHandler, XWarp.permissions, warpManager, wpaManager));
+ subCommands.add(new PermissionsCommand(server));
+ subCommands.add(new ExportCommand(warpManager, wpaManager, dataPath, server));
+ subCommands.add(new ImportCommand(warpManager, wpaManager, dataPath, server));
+
+ this.populate(subCommands);
+ this.setHelper(helper);
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/ManagerCommand.java b/src/main/java/de/xzise/xwarp/commands/ManagerCommand.java
new file mode 100644
index 0000000000..7d1b560a26
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/ManagerCommand.java
@@ -0,0 +1,107 @@
+package de.xzise.xwarp.commands;
+
+import java.util.Arrays;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.xwarp.DefaultArrays;
+import de.xzise.xwarp.Manager;
+import de.xzise.xwarp.WarpObject;
+
+/**
+ * Default command structure with a warp definition. The command structure is:
+ *
+ * /<cmd> <command> <warpname> [creator] <parameter>
+ *
The parameter could be disabled.
+ *
+ * @author Fabian Neundorf
+ */
+public abstract class ManagerCommand, M extends Manager> extends DefaultSubCommand {
+
+ private final String cmd;
+ private final int minLength;
+ private final int maxLength;
+ private final String[] parametersText;
+
+ protected ManagerCommand(M manager, Server server, String label, String[] parameters, String... commands) {
+ this(manager, server, label, parameters, false, commands);
+ }
+
+ private ManagerCommand(M manager, Server server, String label, String[] parameters, boolean optional, String... commands) {
+ super(manager, server, commands);
+ final char paramStart = optional ? '[' : '<';
+ final char paramEnd = optional ? ']' : '>';
+
+ this.parametersText = new String[parameters.length];
+ for (int i = 0; i < parameters.length; i++) {
+ this.parametersText[i] = paramStart + parameters[i] + paramEnd;
+ }
+
+ // |{cmd name owner}| = 3
+ this.maxLength = this.parametersText.length + 3;
+ if (optional) {
+ this.minLength = 2;
+ } else {
+ this.minLength = this.maxLength - 1;
+ }
+
+ StringBuilder commandLine = new StringBuilder(label);
+ commandLine.append(" ");
+ commandLine.append(this.commands[0]);
+ commandLine.append(" [owner]");
+ for (int i = 0; i < this.parametersText.length; i++) {
+ commandLine.append(" " + this.parametersText[i]);
+ }
+ this.cmd = commandLine.toString();
+ }
+
+ protected ManagerCommand(M manager, Server server, String label, String parameterText, String... commands) {
+ this(manager, server, label, MinecraftUtil.isSet(parameterText) ? new String[] { parameterText } : new String[0], commands);
+ }
+
+ protected ManagerCommand(M manager, Server server, String label, String parameterText, boolean optional, String... commands) {
+ this(manager, server, label, MinecraftUtil.isSet(parameterText) ? new String[] { parameterText } : new String[0], optional, commands);
+ }
+
+ @Override
+ public boolean execute(CommandSender sender, String[] parameters) {
+ if (parameters.length != this.minLength && parameters.length != this.maxLength) {
+ return false;
+ }
+ String owner = "";
+ int parameterStartIndex = 2;
+ if (parameters.length == this.maxLength) {
+ owner = this.getPlayer(parameters[2]);
+ parameterStartIndex++;
+ }
+
+ final String[] cmdParameters;
+ if (parameters.length > parameterStartIndex) {
+ cmdParameters = Arrays.copyOfRange(parameters, parameterStartIndex, parameters.length);
+ } else {
+ cmdParameters = DefaultArrays.EMPTY_STRING_ARRAY;
+ }
+
+ W warpObject = this.manager.getWarpObject(parameters[1], owner, MinecraftUtil.getPlayerName(sender));
+ if (warpObject != null) {
+ return this.executeEdit(warpObject, sender, cmdParameters);
+ } else {
+ this.manager.missing(parameters[1], owner, sender);
+ return true;
+ }
+ }
+
+ protected abstract boolean executeEdit(W warpObject, CommandSender sender, String[] parameters);
+
+ protected String getParameterText(boolean colorBeginning, boolean colorEnding, int index) {
+ return (colorBeginning ? ChatColor.GREEN : "") + this.parametersText[index] + (colorEnding ? ChatColor.WHITE : "");
+ }
+
+ @Override
+ public String getCommand() {
+ return this.cmd;
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/RemoveEditorCommand.java b/src/main/java/de/xzise/xwarp/commands/RemoveEditorCommand.java
new file mode 100644
index 0000000000..98e0430415
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/RemoveEditorCommand.java
@@ -0,0 +1,44 @@
+package de.xzise.xwarp.commands;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Manager;
+import de.xzise.xwarp.WarpObject;
+import de.xzise.xwarp.editors.EditorPermissions;
+
+public class RemoveEditorCommand, M extends Manager> extends EditorCommand {
+
+ public RemoveEditorCommand(M list, Server server, String label) {
+ super(list, server, label, "editor", "remove-editor");
+ }
+
+ public static , M extends Manager> RemoveEditorCommand create(M manager, Server server, String label) {
+ return new RemoveEditorCommand(manager, server, label);
+ }
+
+ @Override
+ protected boolean executeEditorEdit(W warpObject, CommandSender sender, String editor, EditorPermissions.Type type, String[] parameters) {
+ if (parameters.length == 1) {
+ this.manager.removeEditor(warpObject, sender, editor, type);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Remove the editor to the warps editors list." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Removes the " + this.getParameterText(true, false, 0);
+ }
+
+ public boolean listHelp(CommandSender sender) {
+ return true;
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/RenameCommand.java b/src/main/java/de/xzise/xwarp/commands/RenameCommand.java
new file mode 100644
index 0000000000..3c76a49518
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/RenameCommand.java
@@ -0,0 +1,34 @@
+package de.xzise.xwarp.commands;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Manager;
+import de.xzise.xwarp.WarpObject;
+
+public class RenameCommand, M extends Manager> extends ManagerCommand {
+
+ public RenameCommand(M list, Server server, String label) {
+ super(list, server, label, "new name", "rename", "mv");
+ }
+
+ public static , M extends Manager> RenameCommand create(M manager, Server server, String label) {
+ return new RenameCommand(manager, server, label);
+ }
+
+ @Override
+ protected boolean executeEdit(W warpObject, CommandSender sender, String[] parameters) {
+ this.manager.setName(warpObject, sender, parameters[0]);
+ return true;
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Changes the name of the warp." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Renames the warp";
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/UninviteCommand.java b/src/main/java/de/xzise/xwarp/commands/UninviteCommand.java
new file mode 100644
index 0000000000..04bbe21794
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/UninviteCommand.java
@@ -0,0 +1,34 @@
+package de.xzise.xwarp.commands;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Manager;
+import de.xzise.xwarp.WarpObject;
+
+public class UninviteCommand, M extends Manager> extends ManagerCommand {
+
+ public UninviteCommand(M list, Server server, String label) {
+ super(list, server, label, "player", "uninvite");
+ }
+
+ public static , M extends Manager> UninviteCommand create(M manager, Server server, String label) {
+ return new UninviteCommand(manager, server, label);
+ }
+
+ @Override
+ protected boolean executeEdit(W warpObject, CommandSender sender, String[] parameters) {
+ this.manager.uninvite(warpObject, sender, this.getPlayer(parameters[0]));
+ return true;
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Revokes the invitation of the invited user." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Uninvites the user.";
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/WPACommandMap.java b/src/main/java/de/xzise/xwarp/commands/WPACommandMap.java
new file mode 100644
index 0000000000..024b1d4257
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/WPACommandMap.java
@@ -0,0 +1,55 @@
+package de.xzise.xwarp.commands;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.bukkit.Server;
+
+import de.xzise.commands.CommonCommandMap;
+import de.xzise.commands.CommonHelpCommand;
+import de.xzise.commands.SubCommand;
+import de.xzise.wrappers.economy.EconomyHandler;
+import de.xzise.xwarp.PluginProperties;
+import de.xzise.xwarp.WPAManager;
+import de.xzise.xwarp.commands.wpa.CreateCommand;
+import de.xzise.xwarp.commands.wpa.InfoCommand;
+import de.xzise.xwarp.commands.wpa.StopCreateCommand;
+import de.xzise.xwarp.dataconnections.DataConnection;
+
+public class WPACommandMap extends CommonCommandMap {
+
+ private static final String LABEL = "wpa";
+ public final CreateCommand createCommand;
+
+ public WPACommandMap(WPAManager manager, EconomyHandler economyWrapper, Server server, DataConnection data, File pluginPath, PluginProperties properties) {
+ super();
+
+ CommonHelpCommand helper = new CommonHelpCommand("xWarp");
+ this.createCommand = new CreateCommand(manager, server);
+
+ Collection subCommands = new ArrayList();
+
+ subCommands.add(this.createCommand);
+ subCommands.add(new StopCreateCommand(this.createCommand));
+ subCommands.add(DeleteCommand.create(manager, server, LABEL));
+ // subCommands.add(new UpdateCommand(manager, server));
+ subCommands.add(RenameCommand.create(manager, server, LABEL));
+ subCommands.add(helper);
+ subCommands.add(UninviteCommand.create(manager, server, LABEL));
+ subCommands.add(InviteCommand.create(manager, server, LABEL));
+ subCommands.add(GiveCommand.create(manager, server, LABEL));
+ subCommands.add(AddEditorCommand.create(manager, server, LABEL));
+ subCommands.add(RemoveEditorCommand.create(manager, server, LABEL));
+ // subCommands.add(new SearchCommand(manager, server));
+ // subCommands.add(new ListCommand(manager, server));
+ subCommands.add(new ChangeWorldCommand(manager, server, LABEL));
+ subCommands.add(ChangeCreatorCommand.create(manager, server, LABEL));
+ subCommands.add(new InfoCommand(manager, server));
+ // subCommands.add(new ListedCommand(manager, server));
+
+ this.populate(subCommands);
+
+ this.setHelper(helper);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/xzise/xwarp/commands/WarpCommandMap.java b/src/main/java/de/xzise/xwarp/commands/WarpCommandMap.java
new file mode 100644
index 0000000000..5f59384edd
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/WarpCommandMap.java
@@ -0,0 +1,84 @@
+package de.xzise.xwarp.commands;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.bukkit.Server;
+
+import de.xzise.commands.CommonCommandMap;
+import de.xzise.commands.CommonHelpCommand;
+import de.xzise.commands.SubCommand;
+import de.xzise.wrappers.economy.EconomyHandler;
+import de.xzise.xwarp.PluginProperties;
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+import de.xzise.xwarp.commands.warp.ChangeAllListedCommand;
+import de.xzise.xwarp.commands.warp.CooldownCommand;
+import de.xzise.xwarp.commands.warp.CreateCommand;
+import de.xzise.xwarp.commands.warp.GlobalizeCommand;
+import de.xzise.xwarp.commands.warp.InfoCommand;
+import de.xzise.xwarp.commands.warp.ListCommand;
+import de.xzise.xwarp.commands.warp.ListedCommand;
+import de.xzise.xwarp.commands.warp.MessageCommand;
+import de.xzise.xwarp.commands.warp.PriceCommand;
+import de.xzise.xwarp.commands.warp.PrivatizeCommand;
+import de.xzise.xwarp.commands.warp.PublicizeCommand;
+import de.xzise.xwarp.commands.warp.SafetyCheckCommand;
+import de.xzise.xwarp.commands.warp.SearchCommand;
+import de.xzise.xwarp.commands.warp.ShowMessageCommand;
+import de.xzise.xwarp.commands.warp.UpdateCommand;
+import de.xzise.xwarp.commands.warp.WarmUpCommand;
+import de.xzise.xwarp.commands.warp.WarpForceToCommand;
+import de.xzise.xwarp.commands.warp.WarpToCommand;
+import de.xzise.xwarp.dataconnections.DataConnection;
+
+public class WarpCommandMap extends CommonCommandMap {
+
+ public static final String LABEL = "warp";
+
+ public WarpCommandMap(WarpManager manager, EconomyHandler economyWrapper, Server server, DataConnection data, File pluginPath, PluginProperties properties) {
+ super();
+
+ CommonHelpCommand helper = new CommonHelpCommand("xWarp");
+ WarpToCommand warper = new WarpToCommand(manager, server);
+
+ Collection subCommands = new ArrayList();
+
+ subCommands.add(warper);
+ subCommands.add(CreateCommand.newCreatePrivate(manager, server));
+ subCommands.add(CreateCommand.newCreatePublic(manager, server));
+ subCommands.add(CreateCommand.newCreateGlobal(manager, server));
+ subCommands.add(new DeleteCommand(manager, server, LABEL));
+ subCommands.add(new UpdateCommand(manager, server));
+ subCommands.add(new RenameCommand(manager, server, LABEL));
+ subCommands.add(helper);
+ subCommands.add(new UninviteCommand(manager, server, LABEL));
+ subCommands.add(new InviteCommand(manager, server, LABEL));
+ subCommands.add(new GiveCommand(manager, server, LABEL));
+ subCommands.add(new MessageCommand(manager, server));
+ subCommands.add(new ShowMessageCommand(manager, server, properties));
+ subCommands.add(new AddEditorCommand(manager, server, LABEL));
+ subCommands.add(new RemoveEditorCommand(manager, server, LABEL));
+ subCommands.add(new PrivatizeCommand(manager, server));
+ subCommands.add(new PublicizeCommand(manager, server));
+ subCommands.add(new GlobalizeCommand(manager, server));
+ subCommands.add(new WarmUpCommand(manager, server));
+ subCommands.add(new CooldownCommand(manager, server));
+ subCommands.add(new PriceCommand(manager, server));
+ subCommands.add(new SearchCommand(manager, server));
+ subCommands.add(new ListCommand(manager, server, properties));
+ subCommands.add(new ChangeWorldCommand(manager, server, LABEL));
+ subCommands.add(new ChangeCreatorCommand(manager, server, LABEL));
+ subCommands.add(new InfoCommand(manager, server, economyWrapper));
+ subCommands.add(new SafetyCheckCommand(manager, server));
+ subCommands.add(new ListedCommand(manager, server));
+ subCommands.add(new WarpForceToCommand(manager, server));
+ subCommands.add(new ChangeAllListedCommand(manager, server));
+
+ this.populate(subCommands);
+
+ this.setDefault(warper);
+ this.setHelper(helper);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/ChangeAllListedCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/ChangeAllListedCommand.java
new file mode 100644
index 0000000000..b3238d7cd2
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/ChangeAllListedCommand.java
@@ -0,0 +1,66 @@
+package de.xzise.xwarp.commands.warp;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+import de.xzise.xwarp.XWarp;
+import de.xzise.xwarp.commands.DefaultSubCommand;
+import de.xzise.xwarp.wrappers.permission.PermissionTypes;
+
+/*
+ * Temporary class to change the listed status of all warps!
+ */
+public class ChangeAllListedCommand extends DefaultSubCommand {
+
+ public ChangeAllListedCommand(WarpManager manager, Server server) {
+ super(manager, server, "alllisted");
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Changes the listed status of all warps to the specified state.", "The states could be: Yes/True/Listed for listed and No/False/Unlisted for unlisted." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Changes listed of all warps.";
+ }
+
+ @Override
+ public String getCommand() {
+ return "warp alllisted ";
+ }
+
+ @Override
+ public boolean execute(CommandSender sender, String[] parameters) {
+ if (parameters.length == 2) {
+ if (XWarp.permissions.permission(sender, PermissionTypes.ADMIN_LIST_CHANGE)) {
+ final Boolean listed;
+ if (parameters[1].equalsIgnoreCase("yes") || parameters[1].equalsIgnoreCase("true") || parameters[1].equalsIgnoreCase("listed")) {
+ listed = true;
+ } else if (parameters[1].equalsIgnoreCase("no") || parameters[1].equalsIgnoreCase("false") || parameters[1].equalsIgnoreCase("unlisted")) {
+ listed = false;
+ } else {
+ listed = null;
+ }
+ if (listed == null) {
+ sender.sendMessage(ChatColor.RED + "Invalid listed state!");
+ } else {
+ for (Warp warp : this.manager.getWarpObjects()) {
+ this.manager.setListed(warp, listed);
+ }
+ sender.sendMessage("Set all warps to: " + ChatColor.GREEN + (listed ? "listed" : "not listed"));
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "You don't have the permission to change the listed state of somebody elses warps.");
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/CooldownCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/CooldownCommand.java
new file mode 100644
index 0000000000..54a31bccbd
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/CooldownCommand.java
@@ -0,0 +1,43 @@
+package de.xzise.xwarp.commands.warp;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+
+public class CooldownCommand extends WarpCommand {
+
+ public CooldownCommand(WarpManager manager, Server server) {
+ super(manager, server, "time (s)", new String[] { "cooldown", "chcd" });
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Changes the warp specific cooldown. The time is in seconds.", "If the time is 'default', 'def' or negative the warp uses the group/user specific cooldown." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Change the warp specific cooldown";
+ }
+
+ @Override
+ protected boolean executeEdit(Warp warp, CommandSender sender, String[] parameters) {
+ Integer time;
+ if (parameters[0].equals("default") || parameters[0].equals("def")) {
+ time = -1;
+ } else {
+ time = MinecraftUtil.tryAndGetInteger(parameters[0]);
+ }
+ if (time != null) {
+ this.manager.setCooldown(warp, sender, time);
+ } else {
+ sender.sendMessage(ChatColor.RED + "Invalid cooldown time given. Only integers, 'default' and 'def' allowed.");
+ }
+ return true;
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/CreateCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/CreateCommand.java
new file mode 100644
index 0000000000..f7461d05b5
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/CreateCommand.java
@@ -0,0 +1,144 @@
+package de.xzise.xwarp.commands.warp;
+
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.xwarp.Warp.Visibility;
+import de.xzise.xwarp.commands.DefaultSubCommand;
+import de.xzise.xwarp.lister.GenericLister;
+import de.xzise.xwarp.warpable.Positionable;
+import de.xzise.xwarp.warpable.WarperFactory;
+import de.xzise.xwarp.wrappers.permission.PermissionTypes;
+import de.xzise.xwarp.wrappers.permission.PermissionValues;
+import de.xzise.xwarp.WarpManager;
+import de.xzise.xwarp.XWarp;
+
+public class CreateCommand extends DefaultSubCommand {
+
+ private final Visibility visibility;
+
+ protected CreateCommand(WarpManager manager, Server server, String suffix, Visibility visibility) {
+ super(manager, server, CreateCommand.getCreateCommands(suffix));
+ this.visibility = visibility;
+ }
+
+ public static CreateCommand newCreatePrivate(WarpManager manager, Server server) {
+ return new CreateCommand(manager, server, "p", Visibility.PRIVATE);
+ }
+
+ public static CreateCommand newCreatePublic(WarpManager manager, Server server) {
+ return new CreateCommand(manager, server, "", Visibility.PUBLIC);
+ }
+
+ public static CreateCommand newCreateGlobal(WarpManager manager, Server server) {
+ return new CreateCommand(manager, server, "g", Visibility.GLOBAL);
+ }
+
+ private static String[] getCreateCommands(String suffix) {
+ return new String[] { "create" + suffix, "+" + suffix, "add" + suffix };
+ }
+
+ private String getAmount(Player player, PermissionValues value) {
+ int amount = XWarp.permissions.getInteger(player, value);
+ if (amount < 0) {
+ return "Infinite";
+ } else if (amount == 0) {
+ return "None";
+ } else {
+ return Integer.toString(amount);
+ }
+ }
+
+ @Override
+ public boolean execute(CommandSender sender, String[] parameters) {
+ Player player = MinecraftUtil.getPlayer(sender);
+ if (parameters.length == 1 && player != null) {
+ player.sendMessage("You could create following amount of warps:");
+ player.sendMessage(GenericLister.GLOBAL_OWN + "Global: " + ChatColor.GREEN + getAmount(player, PermissionValues.WARP_LIMIT_GLOBAL) + ChatColor.WHITE + " (created: " + ChatColor.GREEN + this.manager.getAmountOfWarps(player.getName(), Visibility.GLOBAL, player.getWorld().getName()) + ChatColor.WHITE + ")");
+ player.sendMessage(GenericLister.PUBLIC_OWN + "Public: " + ChatColor.GREEN + getAmount(player, PermissionValues.WARP_LIMIT_PUBLIC) + ChatColor.WHITE + " (created: " + ChatColor.GREEN + this.manager.getAmountOfWarps(player.getName(), Visibility.PUBLIC, player.getWorld().getName()) + ChatColor.WHITE + ")");
+ player.sendMessage(GenericLister.PRIVATE_OWN + "Private: " + ChatColor.GREEN + getAmount(player, PermissionValues.WARP_LIMIT_PRIVATE) + ChatColor.WHITE + " (created: " + ChatColor.GREEN + this.manager.getAmountOfWarps(player.getName(), Visibility.PRIVATE, player.getWorld().getName()) + ChatColor.WHITE + ")");
+ player.sendMessage(ChatColor.GREEN + "Total: " + getAmount(player, PermissionValues.WARP_LIMIT_TOTAL) + ChatColor.WHITE + " (created: " + ChatColor.GREEN + this.manager.getAmountOfWarps(player.getName(), null, player.getWorld().getName()) + ChatColor.WHITE + ")");
+// player.sendMessage(ChatColor.GREEN + "Global total: " + /* TODO: Get global value */ getAmount(player, PermissionValues.WARP_LIMIT_TOTAL) + ChatColor.WHITE + " (created: " + ChatColor.GREEN + this.list.getAmountOfWarps(player.getName(), null, null) + ChatColor.WHITE + ")");
+ return true;
+ } else {
+ Positionable position = WarperFactory.getPositionable(sender);
+ if (position != null) {
+ String newOwner;
+ switch (parameters.length) {
+ case 2:
+ if (sender instanceof Player) {
+ newOwner = ((Player) sender).getName();
+ } else {
+ sender.sendMessage(ChatColor.RED + "You couldn't own a warp.");
+ return true;
+ }
+ break;
+ case 3:
+ newOwner = parameters[2];
+ break;
+ default:
+ return false;
+ }
+ this.manager.addWarp(parameters[1], position, newOwner, this.visibility);
+ return true;
+ } else {
+ sender.sendMessage(ChatColor.RED + "You are unable to create a warp, because you have no position.");
+ }
+ return true;
+ }
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ String visibilityText = "";
+ switch (this.visibility) {
+ case PRIVATE:
+ visibilityText = "private";
+ break;
+ case PUBLIC:
+ visibilityText = "public";
+ break;
+ case GLOBAL:
+ visibilityText = "global";
+ break;
+ }
+ return new String[] { "Creates a new warp, the visibility is by default " + visibilityText };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ switch (this.visibility) {
+ case PRIVATE:
+ return "Creates private warp";
+ case PUBLIC:
+ return "Creates public warp";
+ case GLOBAL:
+ return "Creates global warp";
+ default:
+ return "Missing help text";
+ }
+ }
+
+ @Override
+ public String getCommand() {
+ return "warp " + this.commands[0] + " [new owner]";
+ }
+
+ @Override
+ public boolean listHelp(CommandSender sender) {
+ switch (this.visibility) {
+ case PRIVATE:
+ return XWarp.permissions.permission(sender, PermissionTypes.CREATE_PRIVATE);
+ case PUBLIC:
+ return XWarp.permissions.permission(sender, PermissionTypes.CREATE_PUBLIC);
+ case GLOBAL:
+ return XWarp.permissions.permission(sender, PermissionTypes.CREATE_GLOBAL);
+ default:
+ return false;
+ }
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/GlobalizeCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/GlobalizeCommand.java
new file mode 100644
index 0000000000..809ee53ccd
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/GlobalizeCommand.java
@@ -0,0 +1,31 @@
+package de.xzise.xwarp.commands.warp;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+
+public class GlobalizeCommand extends WarpCommand {
+
+ public GlobalizeCommand(WarpManager manager, Server server) {
+ super(manager, server, "", "global");
+ }
+
+ @Override
+ protected boolean executeEdit(Warp warp, CommandSender sender, String[] parameters) {
+ this.manager.globalize(warp, sender);
+ return true;
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Sets the status of a warp to global.", "This is only possible if there is no global warp with this name." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Globalizes the warp.";
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/InfoCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/InfoCommand.java
new file mode 100644
index 0000000000..8c49197660
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/InfoCommand.java
@@ -0,0 +1,134 @@
+package de.xzise.xwarp.commands.warp;
+
+import java.text.DecimalFormat;
+import java.util.Collection;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.metainterfaces.FixedLocation;
+import de.xzise.wrappers.economy.EconomyHandler;
+import de.xzise.xwarp.DefaultWarpObject.EditorPermissionEntry;
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+import de.xzise.xwarp.XWarp;
+import de.xzise.xwarp.commands.wpa.InfoCommand.EditorLines;
+import de.xzise.xwarp.editors.WarpPermissions;
+import de.xzise.xwarp.lister.GenericLister;
+import de.xzise.xwarp.timer.CoolDown;
+import de.xzise.xwarp.timer.WarmUp;
+import de.xzise.xwarp.wrappers.permission.PermissionTypes;
+import de.xzise.xwarp.wrappers.permission.PricePermissions;
+
+public class InfoCommand extends WarpCommand {
+
+ private final EconomyHandler wrapper;
+ private static final DecimalFormat FORMAT = new DecimalFormat("#0.0");
+
+ public InfoCommand(WarpManager list, Server server, EconomyHandler wrapper) {
+ super(list, server, "", "info");
+ this.wrapper = wrapper;
+ }
+
+ private String getPrice(double price, double base) {
+ if (price < 0 || (price == 0 && base == 0)) {
+ return "Gratis";
+ } else if (price == 0 && base != 0) {
+ return "Only permissions price (" + this.wrapper.format(base) + ")";
+ } else {
+ return this.wrapper.format(price) + " base price: " + this.wrapper.format(base);
+ }
+ }
+
+ @Override
+ protected boolean executeEdit(Warp warp, CommandSender sender, String[] parameters) {
+ if (!XWarp.permissions.permission(sender, PermissionTypes.CMD_INFO)) {
+ sender.sendMessage(ChatColor.RED + "You have no permission to gather information to warps.");
+ return true;
+ }
+
+ final int numberOfWarps = this.manager.getNumberOfWarpsByName(warp.getName());
+ sender.sendMessage("Warp info: '" + ChatColor.GREEN + warp.getName() + ChatColor.WHITE + "'" + (numberOfWarps > 1 ? " (" + ChatColor.GREEN + (numberOfWarps - 1) + ChatColor.WHITE + " warp(s) have the same name)" : ""));
+ String world = warp.getLocationWrapper().getWorld();
+ if (!warp.getLocationWrapper().isValid()) {
+ sender.sendMessage(ChatColor.RED + "The location is invalid!");
+ } else if (!warp.isSave()) {
+ sender.sendMessage(ChatColor.RED + "The location is not save!");
+ }
+
+ sender.sendMessage("Creator: " + getPlayerLine(warp.getCreator(), world));
+ sender.sendMessage("Owner: " + getPlayerLine(warp.getOwner(), world));
+ String visibility = "";
+ double basePrice = 0;
+ switch (warp.getVisibility()) {
+ case GLOBAL:
+ visibility = "Global";
+ basePrice = XWarp.permissions.getDouble(sender, PricePermissions.WARP_PRICES_TO_GLOBAL);
+ break;
+ case PUBLIC:
+ visibility = "Public";
+ basePrice = XWarp.permissions.getDouble(sender, PricePermissions.WARP_PRICES_TO_PUBLIC);
+ break;
+ case PRIVATE:
+ visibility = "Private";
+ basePrice = XWarp.permissions.getDouble(sender, PricePermissions.WARP_PRICES_TO_PRIVATE);
+ break;
+ }
+ if (sender instanceof Player) {
+ visibility = GenericLister.getColor(warp, (Player) sender) + visibility;
+ }
+ sender.sendMessage("Visibility: " + visibility + " (" + (warp.isListed() ? "Listed" : "Unlisted") + ")");
+ if (this.wrapper.isActive()) {
+ sender.sendMessage("Price: " + ChatColor.GREEN + this.getPrice(warp.getPrice(), basePrice));
+ } else if (warp.getPrice() != 0) {
+ sender.sendMessage("Price: " + ChatColor.GREEN + this.getPrice(warp.getPrice(), basePrice) + ChatColor.RED + " (Inactive)");
+ }
+
+ sender.sendMessage("Cooldown: " + CoolDown.getCooldownTime(warp, sender) + " sec Warmup: " + WarmUp.getWarmupTime(warp, sender) + " sec");
+
+ Collection> allEditorPermissions = warp.getEditorPermissionsList();
+ EditorLines lines = de.xzise.xwarp.commands.wpa.InfoCommand.getEditorLines(allEditorPermissions, WarpPermissions.WARP);
+ sender.sendMessage("Invitees: " + (lines.invitees.isEmpty() ? "None" : lines.invitees));
+ sender.sendMessage("Editors: " + lines.editors);
+
+ FixedLocation location = warp.getLocation();
+ final String distanceText;
+ if (sender instanceof Player) {
+ distanceText = ", distance = " + ChatColor.GREEN + MinecraftUtil.getSIPrefixValue(((Player) sender).getLocation().distance(location.toLocation()), FORMAT) + "m";
+ } else {
+ distanceText = "";
+ }
+ sender.sendMessage("Location: World = " + ChatColor.GREEN + world + ChatColor.WHITE + ", x = " + ChatColor.GREEN + location.getBlockX() + ChatColor.WHITE + ", y = " + ChatColor.GREEN + location.getBlockY() + ChatColor.WHITE + ", z = " + ChatColor.GREEN + location.getBlockZ() + ChatColor.WHITE + distanceText);
+
+ return true;
+ }
+
+ public static String getPlayerLine(String player, String world) {
+ if (MinecraftUtil.isSet(player)) {
+ String[] groups = XWarp.permissions.getGroup(world, player);
+
+ String groupText = "";
+ if (groups != null && groups.length > 0) {
+ groupText = ChatColor.WHITE + " (Group: " + ChatColor.GREEN + groups[0] + ChatColor.WHITE + ")";
+ }
+
+ return ChatColor.GREEN + player + groupText;
+ } else {
+ return "Nobody";
+ }
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Show the information about the warp." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Show warp's information";
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/ListCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/ListCommand.java
new file mode 100644
index 0000000000..71e1262db5
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/ListCommand.java
@@ -0,0 +1,339 @@
+package de.xzise.xwarp.commands.warp;
+
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.bukkit.util.callback.Callback;
+import de.xzise.xwarp.PluginProperties;
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+import de.xzise.xwarp.XWarp;
+import de.xzise.xwarp.Warp.Visibility;
+import de.xzise.xwarp.commands.DefaultSubCommand;
+import de.xzise.xwarp.lister.GenericLister;
+import de.xzise.xwarp.lister.GenericLister.Column;
+import de.xzise.xwarp.lister.ListSection;
+import de.xzise.xwarp.wrappers.permission.PermissionTypes;
+
+public class ListCommand extends DefaultSubCommand {
+
+ public static class WhiteBlackList> implements Callback {
+ private final S white, black;
+
+ public WhiteBlackList(S white, S black) {
+ this.white = white;
+ this.black = black;
+ }
+
+ public boolean add(V value, boolean white) {
+ if (white) {
+ return this.white.add(value);
+ } else {
+ return this.black.add(value);
+ }
+ }
+
+ public S getWhitelist() {
+ return this.white;
+ }
+
+ public S getBlacklist() {
+ return this.black;
+ }
+
+ public boolean isEmpty() {
+ return this.white.isEmpty() && this.black.isEmpty();
+ }
+
+ @Override
+ public Boolean call(V value) {
+ if (this.black.contains(value)) {
+ return false;
+ } else if (this.white.contains(value)) {
+ return true;
+ } else if (this.isEmpty()) {
+ return null;
+ } else {
+ return this.white.isEmpty();
+ }
+ }
+ }
+
+ public static abstract class DefWhiteBlackList extends WhiteBlackList> {
+ public DefWhiteBlackList(Set white, Set black) {
+ super(white, black);
+ }
+
+ public DefWhiteBlackList() {
+ this(new HashSet(), new HashSet());
+ }
+ }
+
+ public static abstract class WarpOptions extends WhiteBlackList> {
+
+ public WarpOptions() {
+ super(new HashSet(), new HashSet());
+ }
+
+ public abstract V getValue(Warp warp);
+
+ public Boolean call(Warp warp) {
+ V value = getValue(warp);
+ return super.call(value);
+ }
+ }
+
+ public static abstract class StringOptions extends WarpOptions {
+ public boolean add(String string, boolean white) {
+ return super.add(string.toLowerCase(), white);
+ }
+
+ public abstract String getString(Warp warp);
+
+ @Override
+ public String getValue(Warp warp) {
+ return this.getString(warp).toLowerCase();
+ }
+ }
+
+ public static class OwnerOptions extends StringOptions {
+
+ @Override
+ public String getString(Warp warp) {
+ return warp.getOwner();
+ }
+ }
+
+ public static class CreatorOptions extends StringOptions {
+
+ @Override
+ public String getString(Warp warp) {
+ return warp.getCreator();
+ }
+
+ }
+
+ public static class WorldOptions extends StringOptions {
+
+ @Override
+ public String getString(Warp warp) {
+ return warp.getWorld();
+ }
+
+ }
+
+ public static class VisibilityOptions extends WarpOptions {
+
+ @Override
+ public Visibility getValue(Warp warp) {
+ return warp.getVisibility();
+ }
+
+ }
+
+ public static class EnumWhiteBlackList> extends WhiteBlackList> {
+
+ protected final Class enumClass;
+
+ public EnumWhiteBlackList(Class enumClass) {
+ super(EnumSet.noneOf(enumClass), EnumSet.noneOf(enumClass));
+ this.enumClass = enumClass;
+ }
+
+ /**
+ * Returns all white listed and not defined elements.
+ *
+ * @return all white listed and not defined elements.
+ */
+ public EnumSet getSelected() {
+ EnumSet result = EnumSet.copyOf(this.getWhitelist());
+ result.addAll(EnumSet.complementOf(this.getBlacklist()));
+ return result;
+ }
+
+ public EnumSet getByStatus(Boolean status) {
+ EnumSet result = EnumSet.noneOf(this.enumClass);
+ for (E e : enumClass.getEnumConstants()) {
+ if (this.call(e) == status) {
+ result.add(e);
+ }
+ }
+ return result;
+ }
+ }
+
+ private final PluginProperties properties;
+
+ public ListCommand(WarpManager list, Server server, PluginProperties properties) {
+ super(list, server, "list", "ls");
+ this.properties = properties;
+ }
+
+ private static void add(CommandSender sender, WhiteBlackList set, T t, boolean white) {
+ if (!set.add(t, white)) {
+ sender.sendMessage(ChatColor.RED + "This parameter was already added.");
+ }
+ }
+
+ private static Integer processOptions(CommandSender sender, String value, OwnerOptions owners, CreatorOptions creators, WorldOptions worlds, VisibilityOptions visibilities, EnumWhiteBlackList columns) {
+ if (!value.isEmpty()) {
+ boolean white = true;
+ char modifier = value.charAt(0);
+ String rawValue;
+ switch (modifier) {
+ case '-':
+ white = false;
+ case '+':
+ rawValue = value.substring(1);
+ break;
+ default:
+ rawValue = value;
+ }
+
+ String[] segments = rawValue.split(":");
+ if (segments.length == 2) {
+ if (segments[0].equals("c")) {
+ add(sender, creators, MinecraftUtil.expandName(segments[1]), white);
+ } else if (rawValue.startsWith("oc")) {
+ add(sender, creators, segments[1], white);
+ } else if (rawValue.startsWith("o")) {
+ add(sender, owners, MinecraftUtil.expandName(segments[1]), white);
+ } else if (rawValue.startsWith("oo")) {
+ add(sender, owners, segments[1], white);
+ } else if (rawValue.startsWith("w")) {
+ add(sender, worlds, segments[1], white);
+ } else if (rawValue.startsWith("v")) {
+ Visibility v = Visibility.parseString(segments[1]);
+ if (v != null) {
+ add(sender, visibilities, v, white);
+ } else {
+ sender.sendMessage(ChatColor.RED + "Invalid visibility value: " + segments[1]);
+ }
+ } else if (segments[0].equals("col")) {
+ if (segments[1].equalsIgnoreCase("owner")) {
+ add(sender, columns, Column.OWNER, white);
+ } else if (segments[1].equalsIgnoreCase("world")) {
+ add(sender, columns, Column.WORLD, white);
+ } else if (segments[1].equalsIgnoreCase("loc")) {
+ add(sender, columns, Column.LOCATION, white);
+ } else {
+ sender.sendMessage(ChatColor.RED + "Invalid column value: " + segments[1]);
+ }
+ } else {
+ sender.sendMessage(ChatColor.RED + "Unknown parameter prefix: " + segments[0]);
+ }
+ } else {
+ Integer buffer = MinecraftUtil.tryAndGetInteger(rawValue);
+ if (buffer != null) {
+ return buffer;
+ } else {
+ sender.sendMessage(ChatColor.RED + "Unknown parameter: " + rawValue);
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean execute(CommandSender sender, String[] parameters) {
+ if (!XWarp.permissions.permission(sender, PermissionTypes.CMD_LIST)) {
+ sender.sendMessage(ChatColor.RED + "You have no permission to list warps.");
+ return true;
+ }
+
+ // Special case
+ if (parameters.length == 2 && parameters[1].equalsIgnoreCase("legend")) {
+ if (!(sender instanceof Player)) {
+ sender.sendMessage("Maybe no colors here, so this command could be useless here!");
+ }
+ for (String line : GenericLister.getLegend()) {
+ sender.sendMessage(line);
+ }
+ } else {
+ // Parse values here
+ /*
+ * c: oc: w:
+ * o: oo: v:
+ * col:
+ */
+
+ // MixedList
+ OwnerOptions owners = new OwnerOptions();
+ CreatorOptions creators = new CreatorOptions();
+ WorldOptions worlds = new WorldOptions();
+ VisibilityOptions visibilities = new VisibilityOptions();
+ EnumWhiteBlackList columns = new EnumWhiteBlackList(Column.class);
+
+ columns.getWhitelist().addAll(this.properties.getDefaultColumns());
+
+ Integer page = null; // Default page = 1
+ // 0 = list/ls
+ for (int i = 1; i < parameters.length; i++) {
+ Integer buffer = processOptions(sender, parameters[i], owners, creators, worlds, visibilities, columns);
+ if (buffer != null) {
+ if (page == null) {
+ page = buffer;
+ } else {
+ sender.sendMessage(ChatColor.RED + "Found more than one page definition. Selecting first: " + buffer);
+ }
+ }
+ }
+
+ if (page == null) {
+ page = 1;
+ }
+
+ final List warps = this.manager.getWarps(sender, creators, owners, worlds, visibilities);
+
+ final int maxPages = getNumberOfPages(warps.size(), sender);
+ final int numLines = MinecraftUtil.getMaximumLines(sender) - 1;
+
+ final ListSection section = new ListSection("", numLines);
+
+ if (maxPages < 1) {
+ sender.sendMessage(ChatColor.RED + "There are no warps to list");
+ } else if (page < 1) {
+ sender.sendMessage(ChatColor.RED + "Page number can't be below 1.");
+ } else if (page > maxPages) {
+ sender.sendMessage(ChatColor.RED + "There are only " + maxPages + " pages of warps");
+ } else {
+ // Get only those warps one the page
+ final int offset = (page - 1) * numLines;
+ final int lines = Math.min(warps.size() - offset, numLines);
+ List pageWarps = warps.subList(offset, offset + lines);
+
+ section.addWarps(pageWarps);
+
+ GenericLister.listPage(page, maxPages, sender, columns.getByStatus(true), section);
+ }
+ }
+ return true;
+ }
+
+ private static int getNumberOfPages(int elements, CommandSender sender) {
+ return (int) Math.ceil(elements / (double) (MinecraftUtil.getMaximumLines(sender) - 1));
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Shows a list of warps. Following filters are available:", "oo:, o:, oc:, c:", "w:, v:, -col:{owner,world,location}", "Example: /warp list o:xZise -col:owner" };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Shows the warp list";
+ }
+
+ @Override
+ public String getCommand() {
+ return "warp list [filters|#page]";
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/ListedCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/ListedCommand.java
new file mode 100644
index 0000000000..e1f5a34bec
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/ListedCommand.java
@@ -0,0 +1,43 @@
+package de.xzise.xwarp.commands.warp;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+
+public class ListedCommand extends WarpCommand {
+
+ public ListedCommand(WarpManager list, Server server) {
+ super(list, server, "list warp", "listed");
+ }
+
+ @Override
+ protected boolean executeEdit(Warp warp, CommandSender sender, String[] parameters) {
+ String parameter = parameters[0];
+ Boolean listed = null;
+ if (parameter.equalsIgnoreCase("yes") || parameter.equalsIgnoreCase("true")) {
+ listed = true;
+ } else if (parameter.equalsIgnoreCase("no") || parameter.equalsIgnoreCase("false")) {
+ listed = false;
+ }
+ if (listed != null) {
+ this.manager.setListed(warp, sender, listed);
+ } else {
+ sender.sendMessage(ChatColor.RED + "The 'list warp' value has to be 'yes', 'true', 'no' or 'false'.");
+ }
+ return true;
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Defines if a warp is listed.", "To list the warp the parameter has to be 'yes' or 'true.", "To unlist it has to be 'no' or 'false'." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "(Un)lists a warp";
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/MessageCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/MessageCommand.java
new file mode 100644
index 0000000000..f9bcebb730
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/MessageCommand.java
@@ -0,0 +1,37 @@
+package de.xzise.xwarp.commands.warp;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+
+public class MessageCommand extends WarpCommand {
+
+ public MessageCommand(WarpManager manager, Server server) {
+ super(manager, server, "message", "message", "msg");
+ }
+
+ @Override
+ protected boolean executeEdit(Warp warp, CommandSender sender, String[] parameters) {
+ String message = parameters[0];
+ if (message.equalsIgnoreCase("none")) {
+ message = "";
+ } else if (message.equalsIgnoreCase("default")) {
+ message = null;
+ }
+ this.manager.setMessage(warp, sender, message);
+ return true;
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] {"Sets the welcome message which appears if you teleport to this warp." , "If set to 'default' it will show the default message.", "If set to 'none' it will show no message."};
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Sets message";
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/PriceCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/PriceCommand.java
new file mode 100644
index 0000000000..be57fb15b0
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/PriceCommand.java
@@ -0,0 +1,42 @@
+package de.xzise.xwarp.commands.warp;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+
+public class PriceCommand extends WarpCommand {
+
+ public PriceCommand(WarpManager list, Server server) {
+ super(list, server, "price", "price");
+ }
+
+ @Override
+ protected boolean executeEdit(Warp warp, CommandSender sender, String[] parameters) {
+ if (parameters.length == 1) {
+ Double price = MinecraftUtil.tryAndGetDouble(parameters[0]);
+ if (price == null) {
+ sender.sendMessage(ChatColor.RED + "Invalid price given. The price has to be a double.");
+ } else {
+ this.manager.setPrice(warp, sender, price);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Sets the price for the warp." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Set price";
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/PrivatizeCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/PrivatizeCommand.java
new file mode 100644
index 0000000000..20217b10ab
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/PrivatizeCommand.java
@@ -0,0 +1,30 @@
+package de.xzise.xwarp.commands.warp;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+
+public class PrivatizeCommand extends WarpCommand {
+
+ public PrivatizeCommand(WarpManager list, Server server) {
+ super(list, server, "", "private");
+ }
+
+ @Override
+ protected boolean executeEdit(Warp warp, CommandSender sender, String[] parameters) {
+ this.manager.privatize(warp, sender);
+ return true;
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Sets a warp to private.", "Only invited and owners could visit private warps." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Privatizes the warp";
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/PublicizeCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/PublicizeCommand.java
new file mode 100644
index 0000000000..e6eea92a8a
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/PublicizeCommand.java
@@ -0,0 +1,30 @@
+package de.xzise.xwarp.commands.warp;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+
+public class PublicizeCommand extends WarpCommand {
+
+ public PublicizeCommand(WarpManager list, Server server) {
+ super(list, server, "", "public");
+ }
+
+ @Override
+ protected boolean executeEdit(Warp warp, CommandSender sender, String[] parameters) {
+ this.manager.publicize(warp, sender);
+ return true;
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Publizices the warp so everybody could visit it." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Publizices the warp";
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/SafetyCheckCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/SafetyCheckCommand.java
new file mode 100644
index 0000000000..f57fad7f7b
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/SafetyCheckCommand.java
@@ -0,0 +1,36 @@
+package de.xzise.xwarp.commands.warp;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+
+public class SafetyCheckCommand extends WarpCommand {
+
+ public SafetyCheckCommand(WarpManager manager, Server server) {
+ super(manager, server, "", "safety-check");
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Returns everything related to the safety check." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Manually safety check";
+ }
+
+ @Override
+ protected boolean executeEdit(Warp warp, CommandSender sender, String[] parameters) {
+ if (parameters.length == 0) {
+ boolean safety = warp.isSave(sender);
+ sender.sendMessage("Warp is " + (safety ? "" : "not ") + "save.");
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/SearchCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/SearchCommand.java
new file mode 100644
index 0000000000..a7154d0746
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/SearchCommand.java
@@ -0,0 +1,62 @@
+package de.xzise.xwarp.commands.warp;
+
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.xwarp.Searcher;
+import de.xzise.xwarp.WarpManager;
+import de.xzise.xwarp.XWarp;
+import de.xzise.xwarp.commands.DefaultSubCommand;
+import de.xzise.xwarp.wrappers.permission.PermissionTypes;
+
+public class SearchCommand extends DefaultSubCommand {
+
+ public SearchCommand(WarpManager list, Server server) {
+ super(list, server, "search");
+ }
+
+ @Override
+ public boolean execute(CommandSender sender, String[] parameters) {
+ if (parameters.length == 2 || parameters.length == 3) {
+ if (!XWarp.permissions.permission(sender, PermissionTypes.CMD_SEARCH)) {
+ sender.sendMessage(ChatColor.RED + "You have no permission to search warps.");
+ } else {
+ Integer page = null;
+ if (parameters.length == 3) {
+ page = MinecraftUtil.tryAndGetInteger(parameters[2]);
+ } else {
+ page = 1;
+ }
+ if (page != null) {
+ Searcher searcher = new Searcher(this.manager);
+ searcher.addPlayer(sender);
+ searcher.setQuery(parameters[1]);
+ searcher.search(page);
+ } else {
+ sender.sendMessage(ChatColor.RED + "Invalid page number entered.");
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "List all warps which name contains the query text." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Search for " + ChatColor.GRAY + "";
+ }
+
+ @Override
+ public String getCommand() {
+ return "warp search ";
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/ShowMessageCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/ShowMessageCommand.java
new file mode 100644
index 0000000000..9792e14543
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/ShowMessageCommand.java
@@ -0,0 +1,52 @@
+package de.xzise.xwarp.commands.warp;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.DefaultArrays;
+import de.xzise.xwarp.PluginProperties;
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+
+public class ShowMessageCommand extends WarpCommand {
+
+ private final PluginProperties properties;
+
+ public ShowMessageCommand(WarpManager manager, Server server, PluginProperties properties) {
+ super(manager, server, DefaultArrays.EMPTY_STRING_ARRAY, "show-message", "shmsg");
+ this.properties = properties;
+ }
+
+ @Override
+ protected boolean executeEdit(Warp warp, CommandSender sender, String[] parameters) {
+ if (parameters.length == 0) {
+ String message = warp.getRawWelcomeMessage();
+ if ("".equals(message)) {
+ sender.sendMessage("Welcome message of '" + warp.getName() + "' is empty.");
+ } else {
+ sender.sendMessage("Welcome message of '" + warp.getName() + "' is:");
+ boolean def = false;
+ if (message == null) {
+ message = properties.getDefaultMessage().replace("{NAME}", warp.getName());
+ def = true;
+ }
+ sender.sendMessage(ChatColor.AQUA + message + (def ? ChatColor.WHITE + " (default)" : ""));
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] {"Shows the welcome message which appears if you teleport to this warp."};
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Shows message";
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/UpdateCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/UpdateCommand.java
new file mode 100644
index 0000000000..064d2bdc80
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/UpdateCommand.java
@@ -0,0 +1,37 @@
+package de.xzise.xwarp.commands.warp;
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+import de.xzise.xwarp.warpable.Positionable;
+import de.xzise.xwarp.warpable.WarperFactory;
+
+public class UpdateCommand extends WarpCommand {
+
+ public UpdateCommand(WarpManager list, Server server) {
+ super(list, server, "", "update", "*");
+ }
+
+ @Override
+ protected boolean executeEdit(Warp warp, CommandSender sender, String[] parameters) {
+ Positionable positionable = WarperFactory.getPositionable(sender);
+ if (positionable != null) {
+ this.manager.updateLocation(warp, positionable);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Updates the position of the warp." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Updates the warp's position.";
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/WarmUpCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/WarmUpCommand.java
new file mode 100644
index 0000000000..6d861c3eff
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/WarmUpCommand.java
@@ -0,0 +1,43 @@
+package de.xzise.xwarp.commands.warp;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.MinecraftUtil;
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+
+public class WarmUpCommand extends WarpCommand {
+
+ public WarmUpCommand(WarpManager manager, Server server) {
+ super(manager, server, "time (s)", new String[] { "warmup", "chwu" });
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Changes the warp specific warmup. The time is in seconds.", "If the time is 'default', 'def' or negative the warp uses the group/user specific warmup." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Change the warp specific warmup";
+ }
+
+ @Override
+ protected boolean executeEdit(Warp warp, CommandSender sender, String[] parameters) {
+ Integer time;
+ if (parameters[0].equals("default") || parameters[0].equals("def")) {
+ time = -1;
+ } else {
+ time = MinecraftUtil.tryAndGetInteger(parameters[0]);
+ }
+ if (time != null) {
+ this.manager.setWarmup(warp, sender, time);
+ } else {
+ sender.sendMessage(ChatColor.RED + "Invalid warmup time given. Only integers, 'default' and 'def' allowed.");
+ }
+ return true;
+ }
+
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/WarpCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/WarpCommand.java
new file mode 100644
index 0000000000..6691868aac
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/WarpCommand.java
@@ -0,0 +1,30 @@
+package de.xzise.xwarp.commands.warp;
+
+import org.bukkit.Server;
+
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+import de.xzise.xwarp.commands.ManagerCommand;
+import de.xzise.xwarp.commands.WarpCommandMap;
+
+/**
+ * Default command structure with a warp definition. The command structure is:
+ *
+ * /warp <command> <warpname> [creator] <parameter>
+ *
The parameter could be disabled.
+ *
+ * @author Fabian Neundorf
+ */
+public abstract class WarpCommand extends ManagerCommand {
+ protected WarpCommand(WarpManager manager, Server server, String[] parameters, String... commands) {
+ super(manager, server, WarpCommandMap.LABEL, parameters, commands);
+ }
+
+ protected WarpCommand(WarpManager manager, Server server, String parameterText, String... commands) {
+ super(manager, server, WarpCommandMap.LABEL, parameterText, commands);
+ }
+
+ protected WarpCommand(WarpManager manager, Server server, String parameterText, boolean optional, String... commands) {
+ super(manager, server, WarpCommandMap.LABEL, parameterText, optional, commands);
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/WarpForceToCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/WarpForceToCommand.java
new file mode 100644
index 0000000000..b3ebcb2795
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/WarpForceToCommand.java
@@ -0,0 +1,50 @@
+package de.xzise.xwarp.commands.warp;
+
+
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+
+import de.xzise.xwarp.Warp;
+import de.xzise.xwarp.WarpManager;
+import de.xzise.xwarp.XWarp;
+import de.xzise.xwarp.warpable.Warpable;
+import de.xzise.xwarp.warpable.WarperFactory;
+import de.xzise.xwarp.wrappers.permission.PermissionTypes;
+
+/*
+ * Temporary extra command, to warp in another worlds. Maybe it work maybe not!
+ */
+public class WarpForceToCommand extends WarpCommand {
+
+ public WarpForceToCommand(WarpManager list, Server server) {
+ super(list, server, new String[0], "force-to", ">-t");
+ }
+
+ @Override
+ public boolean executeEdit(Warp warp, CommandSender sender, String[] parameters) {
+ Warpable warpable = WarperFactory.getWarpable(sender);
+ if (warpable != null) {
+ this.manager.warpTo(warp, sender, warpable, false, true);
+ }
+ return true;
+ }
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Warps the player to the given warp.", "This command is only ingame available." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Warps the player";
+ }
+
+ @Override
+ public String getCommand() {
+ return "warp force-to [owner]";
+ }
+
+ @Override
+ public boolean listHelp(CommandSender sender) {
+ return XWarp.permissions.permissionOr(sender, PermissionTypes.WARP_TO_PERMISSIONS);
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/warp/WarpToCommand.java b/src/main/java/de/xzise/xwarp/commands/warp/WarpToCommand.java
new file mode 100644
index 0000000000..59b9e9fd74
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/warp/WarpToCommand.java
@@ -0,0 +1,81 @@
+package de.xzise.xwarp.commands.warp;
+
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import de.xzise.xwarp.WarpManager;
+import de.xzise.xwarp.XWarp;
+import de.xzise.xwarp.commands.DefaultSubCommand;
+import de.xzise.xwarp.warpable.Warpable;
+import de.xzise.xwarp.warpable.WarpablePlayer;
+import de.xzise.xwarp.warpable.WarperFactory;
+import de.xzise.xwarp.wrappers.permission.PermissionTypes;
+
+public class WarpToCommand extends DefaultSubCommand {
+
+ public WarpToCommand(WarpManager manager, Server server) {
+ super(manager, server, "to");
+ }
+
+ @Override
+ public boolean execute(CommandSender sender, String[] parameters) {
+ Warpable warped;
+ String otherName = null;
+ if (parameters.length == 4 && parameters[0].equalsIgnoreCase("to")) {
+ otherName = parameters[3];
+ } else if (parameters.length == 3 && !parameters[0].equalsIgnoreCase("to")) {
+ otherName = parameters[2];
+ } else if (parameters.length == 0 || parameters.length > 3) {
+ return false;
+ }
+ if (otherName != null) {
+ Player player = this.server.getPlayer(otherName);
+ if (player != null) {
+ warped = new WarpablePlayer(player);
+ } else {
+ sender.sendMessage(ChatColor.RED + "Unknown warped player given.");
+ return true;
+ }
+ } else {
+ warped = WarperFactory.getWarpable(sender);
+ if (warped == null) {
+ sender.sendMessage(ChatColor.RED + "You are not able to warp anywhere.");
+ return true;
+ }
+ }
+
+ int start = 0;
+ if (parameters[0].equalsIgnoreCase("to") && (parameters.length == 2 || parameters.length == 3)) {
+ start++;
+ }
+ String creator = "";
+ if (parameters.length > start + 1) {
+ creator = this.getPlayer(parameters[start + 1]);
+ }
+ this.manager.warpTo(parameters[start], creator, sender, warped, false);
+ return true;
+ }
+
+ @Override
+ public String[] getFullHelpText() {
+ return new String[] { "Warps the player to the given warp.", "This command is only ingame available." };
+ }
+
+ @Override
+ public String getSmallHelpText() {
+ return "Warps the player";
+ }
+
+ @Override
+ public String getCommand() {
+ return "warp [to] [creator] [warped]";
+ }
+
+ @Override
+ public boolean listHelp(CommandSender sender) {
+ return XWarp.permissions.permissionOr(sender, PermissionTypes.WARP_TO_PERMISSIONS);
+ }
+}
diff --git a/src/main/java/de/xzise/xwarp/commands/wpa/CreateCommand.java b/src/main/java/de/xzise/xwarp/commands/wpa/CreateCommand.java
new file mode 100644
index 0000000000..ab1a7f0b0f
--- /dev/null
+++ b/src/main/java/de/xzise/xwarp/commands/wpa/CreateCommand.java
@@ -0,0 +1,150 @@
+package de.xzise.xwarp.commands.wpa;
+
+import java.util.Map;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Server;
+import org.bukkit.World;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import com.google.common.collect.Maps;
+
+import de.xzise.metainterfaces.FixedLocation;
+import de.xzise.xwarp.WPAManager;
+import de.xzise.xwarp.WarpProtectionArea;
+import de.xzise.xwarp.WorldWrapper;
+import de.xzise.xwarp.commands.DefaultSubCommand;
+
+public class CreateCommand extends DefaultSubCommand