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> 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 { + + private class WPAData { + public final String owner; + public final String creator; + public final String name; + public final World world; + + private FixedLocation loc1 = null; + private FixedLocation loc2 = null; + + public WPAData(String name, String owner, World world) { + this(name, owner, owner, world); + } + + public WPAData(String name, String owner, String creator, World world) { + this.name = name; + this.owner = owner; + this.creator = creator; + this.world = world; + } + + public boolean addLocation(FixedLocation loc) { + if (this.loc1 == null) { + this.loc1 = loc; + return true; + } else if (this.loc2 == null) { + this.loc2 = loc; + } + return false; + } + + public WarpProtectionArea build() { + if (loc1 != null && loc2 != null) { + return new WarpProtectionArea(new WorldWrapper(this.world), this.loc1, this.loc2, this.name, this.owner, this.creator); + } else { + return null; + } + } + } + + private final Map wpaData = Maps.newHashMap(); + + public CreateCommand(WPAManager manager, Server server) { + super(manager, server, "create", "+", "add"); + } + + @Override + public String[] getFullHelpText() { + return new String[] { "Create new warp protection area." }; + } + + @Override + public String getSmallHelpText() { + return "Create protection area"; + } + + @Override + public String getCommand() { + return "wpa create "; + } + + public void stopCreation(String playerName, CommandSender executor) { + Player player = this.server.getPlayer(playerName); + if (player != null) { + if (executor == null) { + executor = player; + } + WPAData data = this.wpaData.remove(player.getName()); + if (data != null) { + if (player != executor) { + player.sendMessage("Your warp protection area creation was stoped!"); + } + executor.sendMessage("Successfully stoped creation of '" + ChatColor.GREEN + data.name + ChatColor.WHITE + "'."); + } else { + if (player != executor) { + executor.sendMessage(ChatColor.RED + "This player doesn't create a warp protection area."); + } else { + player.sendMessage(ChatColor.RED + "You don't create any warp protection area."); + } + } + } else { + executor.sendMessage(ChatColor.RED + "There is no player online with this name."); + } + } + + public boolean hitBlock(Player player, FixedLocation location) { + WPAData data = this.wpaData.get(player.getName()); + if (data != null) { + if (location.world == data.world) { + if (data.addLocation(location)) { + player.sendMessage("Added first location to new protection area."); + } else { + player.sendMessage("Added second location to new protection area."); + WarpProtectionArea wpa = data.build(); + this.manager.addWPA(wpa); + this.wpaData.remove(player.getName()); + player.sendMessage("Successfully created protection area '" + ChatColor.GREEN + wpa.getName() + ChatColor.WHITE + "'."); + } + } else { + player.sendMessage(ChatColor.RED + "You are not in the same world as before."); + } + return true; + } else { + return false; + } + } + + @Override + public boolean execute(CommandSender sender, String[] parameters) { + if (sender instanceof Player) { + if (parameters.length == 2) { + Player player = (Player) sender; + String playerName = player.getName(); + if (this.wpaData.containsKey(playerName)) { + sender.sendMessage(ChatColor.RED + "You already started a creations. To stop use /wpa stop-create"); + } else { + WPAData newWPA = new WPAData(parameters[1], playerName, player.getWorld()); + this.wpaData.put(playerName, newWPA); + sender.sendMessage("Started creation. Hit the corners with a wooden sword."); + } + return true; + } else { + return false; + } + } else { + sender.sendMessage(ChatColor.RED + "Only ingame players could create protection areas."); + return true; + } + } + +} diff --git a/src/main/java/de/xzise/xwarp/commands/wpa/InfoCommand.java b/src/main/java/de/xzise/xwarp/commands/wpa/InfoCommand.java new file mode 100644 index 0000000000..2c5368abde --- /dev/null +++ b/src/main/java/de/xzise/xwarp/commands/wpa/InfoCommand.java @@ -0,0 +1,102 @@ +package de.xzise.xwarp.commands.wpa; + +import java.util.Collection; + +import org.bukkit.ChatColor; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; + +import com.google.common.collect.ImmutableSet; + +import de.xzise.xwarp.Manager; +import de.xzise.xwarp.WarpProtectionArea; +import de.xzise.xwarp.XWarp; +import de.xzise.xwarp.DefaultWarpObject.EditorPermissionEntry; +import de.xzise.xwarp.editors.Editor; +import de.xzise.xwarp.editors.WarpProtectionAreaPermissions; +import de.xzise.xwarp.wrappers.permission.WPAPermissions; + +public class InfoCommand extends WPACommand { + + public InfoCommand(Manager manager, Server server) { + super(manager, server, new String[0], "info"); + } + + @Override + public String[] getFullHelpText() { + return new String[] { "Show the information about the warp protection area." }; + } + + @Override + public String getSmallHelpText() { + return "Show warp protection area's information"; + } + + @Override + protected boolean executeEdit(WarpProtectionArea warp, CommandSender sender, String[] parameters) { + if (!XWarp.permissions.permission(sender, WPAPermissions.CMD_INFO)) { + sender.sendMessage(ChatColor.RED + "You have no permission to gather information to warp protection areas."); + return true; + } + + sender.sendMessage("Warp protection area info: " + ChatColor.GREEN + warp.getName()); + String world = warp.getWorld(); + if (!warp.isValid()) { + sender.sendMessage(ChatColor.RED + "The location is invalid!"); + } + + sender.sendMessage("Creator: " + de.xzise.xwarp.commands.warp.InfoCommand.getPlayerLine(warp.getCreator(), world)); + sender.sendMessage("Owner: " + de.xzise.xwarp.commands.warp.InfoCommand.getPlayerLine(warp.getOwner(), world)); + + Collection> allEditorPermissions = warp.getEditorPermissionsList(); + EditorLines editorLines = getEditorLines(allEditorPermissions, WarpProtectionAreaPermissions.OVERWRITE); + sender.sendMessage("Invitees: " + (editorLines.invitees.isEmpty() ? "None" : editorLines.invitees)); + sender.sendMessage("Editors: " + editorLines.editors); + +// FixedLocation location = warp.getLocation(); +// 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()); + + return true; + } + + public static class EditorLines { + public final String invitees; + public final String editors; + + public EditorLines(String invitees, String editors) { + this.invitees = invitees; + this.editors = editors; + } + } + + public static & Editor> EditorLines getEditorLines(Collection> allPermissions, T invitePermission) { + String editor = ""; + String invitees = ""; + if (allPermissions.size() == 0) { + editor = "None"; + } else { + for (EditorPermissionEntry editorPermissionEntry : allPermissions) { + ImmutableSet permissions = editorPermissionEntry.editorPermissions.getByValue(true); + if (permissions.size() > 0) { + if (!editor.isEmpty()) { + editor += ChatColor.WHITE + ", "; + } + editor += ChatColor.GREEN + editorPermissionEntry.name + " "; + char[] editorPermissions = new char[permissions.size()]; + int j = 0; + for (T t : permissions) { + editorPermissions[j++] = t.getValue(); + if (t == invitePermission) { + if (!invitees.isEmpty()) { + invitees += ", "; + } + invitees += editorPermissionEntry.name; + } + } + editor += new String(editorPermissions); + } + } + } + return new EditorLines(invitees, editor); + } +} diff --git a/src/main/java/de/xzise/xwarp/commands/wpa/StopCreateCommand.java b/src/main/java/de/xzise/xwarp/commands/wpa/StopCreateCommand.java new file mode 100644 index 0000000000..e80be4d36c --- /dev/null +++ b/src/main/java/de/xzise/xwarp/commands/wpa/StopCreateCommand.java @@ -0,0 +1,62 @@ +package de.xzise.xwarp.commands.wpa; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import de.xzise.commands.CommonHelpableSubCommand; +import de.xzise.xwarp.XWarp; +import de.xzise.xwarp.wrappers.permission.WPAPermissions; + +public class StopCreateCommand extends CommonHelpableSubCommand { + + private final CreateCommand createCommand; + + public StopCreateCommand(CreateCommand createCommand) { + super("stop-create", "stop-+", "stop-add"); + this.createCommand = createCommand; + } + + @Override + public String[] getFullHelpText() { + return new String[] { "Stops the creation of a protection area.", "To stop the creation of another one, define the player name." }; + } + + @Override + public String getSmallHelpText() { + return "Stop wpa creation"; + } + + @Override + public String getCommand() { + return "wpa stop-create [player name]"; + } + + @Override + public boolean execute(CommandSender sender, String[] parameters) { + String playerName = null; + boolean notify = false; + if (parameters.length == 1) { + if (sender instanceof Player) { + playerName = ((Player) sender).getName(); + } else { + sender.sendMessage(ChatColor.RED + "Only players could stop their own creations."); + } + } else if (parameters.length == 2) { + if (XWarp.permissions.permission(sender, WPAPermissions.ADMIN_CREATE_STOP)) { + playerName = parameters[1]; + notify = true; + } else { + sender.sendMessage(ChatColor.RED + "You have no permission to stop creation of others."); + } + } else { + return false; + } + + if (playerName != null) { + this.createCommand.stopCreation(playerName, notify ? sender : null); + } + return true; + } + +} diff --git a/src/main/java/de/xzise/xwarp/commands/wpa/WPACommand.java b/src/main/java/de/xzise/xwarp/commands/wpa/WPACommand.java new file mode 100644 index 0000000000..d61342db7e --- /dev/null +++ b/src/main/java/de/xzise/xwarp/commands/wpa/WPACommand.java @@ -0,0 +1,18 @@ +package de.xzise.xwarp.commands.wpa; + +import org.bukkit.Server; + +import de.xzise.xwarp.Manager; +import de.xzise.xwarp.WarpProtectionArea; +import de.xzise.xwarp.commands.ManagerCommand; + +public abstract class WPACommand extends ManagerCommand> { + + protected WPACommand(Manager manager, Server server, String[] parameters, String... commands) { + super(manager, server, "wpa", parameters, commands); + } + + protected WPACommand(Manager manager, Server server, String parameterText, String... commands) { + super(manager, server, "wpa", parameterText, commands); + } +} \ No newline at end of file diff --git a/src/main/java/de/xzise/xwarp/commands/xwarp/ExportCommand.java b/src/main/java/de/xzise/xwarp/commands/xwarp/ExportCommand.java new file mode 100644 index 0000000000..6f350c99c6 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/commands/xwarp/ExportCommand.java @@ -0,0 +1,81 @@ +package de.xzise.xwarp.commands.xwarp; + +import java.io.File; + +import org.bukkit.ChatColor; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; + +import de.xzise.xwarp.WPAManager; +import de.xzise.xwarp.Warp; +import de.xzise.xwarp.WarpManager; +import de.xzise.xwarp.WarpProtectionArea; +import de.xzise.xwarp.XWarp; +import de.xzise.xwarp.commands.DefaultSubCommand; +import de.xzise.xwarp.dataconnections.DataConnection; +import de.xzise.xwarp.dataconnections.DataConnections; +import de.xzise.xwarp.dataconnections.WarpProtectionConnection; +import de.xzise.xwarp.wrappers.permission.GeneralPermissions; + +public class ExportCommand extends DefaultSubCommand { + + private final File pluginPath; + private final WPAManager wpaManager; + + public ExportCommand(WarpManager list, WPAManager wpaManager, File pluginPath, Server server) { + super(list, server, "export"); + this.pluginPath = pluginPath; + this.wpaManager = wpaManager; + } + + @Override + public boolean execute(CommandSender sender, String[] parameters) { + if (parameters.length > 1) { + if (XWarp.permissions.permission(sender, GeneralPermissions.EXPORT)) { + DataConnection connection = DataConnections.getConnection(this.server, parameters[1]); + + if (connection != null) { + File file; + if (parameters.length > 2) { + file = new File(parameters[2]); + } else { + file = new File(pluginPath, connection.getFilename()); + } + try { + connection.create(file); + connection.addWarp(this.manager.getWarpObjects().toArray(new Warp[0])); + if (connection instanceof WarpProtectionConnection) { + ((WarpProtectionConnection) connection).addProtectionArea(this.wpaManager.getWarpObjects().toArray(new WarpProtectionArea[0])); + } + connection.free(); + sender.sendMessage("Successfully xWarp database exported."); + } catch (Exception e) { + XWarp.logger.severe("Unable to export database.", e); + sender.sendMessage(ChatColor.RED + "Unable to export database."); + } + } else { + sender.sendMessage(ChatColor.RED + "Invalid type given."); + } + } else { + sender.sendMessage(ChatColor.RED + "You don't have permission to export the database."); + } + return true; + } + return false; + } + + @Override + public String[] getFullHelpText() { + return new String[] { "Exports the loaded warps to the given file.", "Valid types are: 'sqlite', 'hmod'" }; + } + + @Override + public String getSmallHelpText() { + return "Export warps"; + } + + @Override + public String getCommand() { + return "warp export [file]"; + } +} diff --git a/src/main/java/de/xzise/xwarp/commands/xwarp/ImportCommand.java b/src/main/java/de/xzise/xwarp/commands/xwarp/ImportCommand.java new file mode 100644 index 0000000000..b482f5fe1b --- /dev/null +++ b/src/main/java/de/xzise/xwarp/commands/xwarp/ImportCommand.java @@ -0,0 +1,86 @@ +package de.xzise.xwarp.commands.xwarp; + +import java.io.File; + +import org.bukkit.ChatColor; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import de.xzise.xwarp.WPAManager; +import de.xzise.xwarp.WarpManager; +import de.xzise.xwarp.WarpManager.WarpGetter; +import de.xzise.xwarp.commands.DefaultSubCommand; +import de.xzise.xwarp.dataconnections.DataConnection; +import de.xzise.xwarp.dataconnections.DataConnections; +import de.xzise.xwarp.dataconnections.HModConnection; + +public class ImportCommand extends DefaultSubCommand { + + private final File directory; + private final WPAManager wpaManager; + + public ImportCommand(WarpManager manager, WPAManager wpaManager, File directory, Server server) { + super(manager, server, "import"); + this.wpaManager = wpaManager; + this.directory = directory; + } + + @Override + public boolean execute(CommandSender sender, String[] parameters) { + if (parameters.length >= 2) { + DataConnection connection = DataConnections.getConnection(this.server, parameters[1]); + if (connection == null) { + sender.sendMessage(ChatColor.RED + "Unrecognized import type."); + return true; + } + + if (connection instanceof HModConnection) { + if (parameters.length > 4) { + return false; + } + } else if (parameters.length > 3) { + return false; + } + + if (parameters.length >= 3) { + connection.load(new File(parameters[2])); + } else { + connection.load(new File(this.directory, connection.getFilename())); + } + + String owner = null; + if (connection instanceof HModConnection) { + if (parameters.length == 4) { + owner = parameters[3]; + } else if (sender instanceof Player) { + owner = ((Player) sender).getName(); + } + } + + this.manager.importWarpObjects(connection, new WarpGetter(connection, owner), sender); + this.wpaManager.importWarpObjects(connection, new WPAManager.WPAGetter(connection), sender); + + connection.free(); + return true; + } else { + return false; + } + } + + @Override + public String[] getFullHelpText() { + return new String[] { "Imports a warplist and store it in the database.", "Types could be: 'sqlite' or 'hmod'.", "In hmod mode the creator is either the 3rd parameter (if set) or the initiator (if player) or nobody." }; + } + + @Override + public String getSmallHelpText() { + return "Imports a warplist"; + } + + @Override + public String getCommand() { + return "warp import [file]"; + } + +} diff --git a/src/main/java/de/xzise/xwarp/commands/xwarp/PermissionsCommand.java b/src/main/java/de/xzise/xwarp/commands/xwarp/PermissionsCommand.java new file mode 100644 index 0000000000..0f6fc973ac --- /dev/null +++ b/src/main/java/de/xzise/xwarp/commands/xwarp/PermissionsCommand.java @@ -0,0 +1,139 @@ +package de.xzise.xwarp.commands.xwarp; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import de.xzise.commands.CommonHelpableSubCommand; +import de.xzise.xwarp.XWarp; +import de.xzise.xwarp.wrappers.permission.PermissionTypes; +import de.xzise.xwarp.wrappers.permission.PermissionValues; +import de.xzise.xwarp.wrappers.permission.PricePermissions; +import de.xzise.xwarp.wrappers.permission.WorldPermission; + +public class PermissionsCommand extends CommonHelpableSubCommand { + + private final Server server = Bukkit.getServer(); + + public PermissionsCommand(Server server) { + super("permissions"); + } + + @Override + public boolean execute(CommandSender sender, String[] parameters) { + Player player = null; + boolean showGranted = true; + boolean showDenied = true; + switch (parameters.length) { + case 2: + if (!(parameters[1].equalsIgnoreCase("n") || parameters[1].equalsIgnoreCase("y"))) { + player = this.server.getPlayer(parameters[1]); + if (player == null) { + sender.sendMessage("Player is not logged in."); + return true; + } + break; + } else { + showGranted = parameters[1].equalsIgnoreCase("y"); + showDenied = parameters[1].equalsIgnoreCase("n"); + } + case 1: + if (sender instanceof Player) { + player = (Player) sender; + } else { + sender.sendMessage("You are not a player"); + return true; + } + break; + case 3: + if (parameters[2].equalsIgnoreCase("n") || parameters[2].equalsIgnoreCase("y")) { + player = this.server.getPlayer(parameters[1]); + if (player == null) { + sender.sendMessage("Player is not logged in."); + return true; + } + + showGranted = parameters[2].equalsIgnoreCase("y"); + showDenied = parameters[2].equalsIgnoreCase("n"); + break; + } else { + return false; + } + } + + if (player != null) { + if (sender == player) { + sender.sendMessage("Your permissions:"); + } else { + sender.sendMessage(player.getName() + " permissions:"); + } + if (!XWarp.permissions.isActive()) { + sender.sendMessage("(Use build in permissions!)"); + } + for (PermissionTypes type : PermissionTypes.values()) { + boolean hasPermission = XWarp.permissions.permission(player, type); + if ((hasPermission && showGranted) || (!hasPermission && showDenied)) { + String message = (hasPermission ? ChatColor.GREEN : ChatColor.RED) + type.name + ": " + (hasPermission ? "Yes" : "No"); + sender.sendMessage(message); + } + } + for (PermissionValues value : PermissionValues.values()) { + sender.sendMessage(value.getName() + ": " + XWarp.permissions.getInteger(sender, value)); + } + for (PricePermissions value : PricePermissions.values()) { + sender.sendMessage(value.getName() + ": " + XWarp.permissions.getDouble(sender, value)); + } + sender.sendMessage("Allowed to warp within: " + this.worldPermission(sender, WorldPermission.WITHIN_WORLD)); + sender.sendMessage("Allowed to warp into: " + this.worldPermission(sender, WorldPermission.TO_WORLD)); + return true; + } else { + return false; + } + } + + private String worldPermission(CommandSender sender, WorldPermission permission) { + int count = 0; + String worlds = ""; + for (World world : this.server.getWorlds()) { + if (XWarp.permissions.permission(sender, permission.getPermission(world.getName()))) { + if (count > 0) { + worlds += ", "; + } + worlds += world.getName(); + count++; + } + } + if (count == this.server.getWorlds().size()) { + return "All worlds"; + } else if (count == 0) { + return "None"; + } else { + return worlds; + } + } + + @Override + public String[] getFullHelpText() { + return new String[] { "Shows all your permissions." }; + } + + @Override + public String getSmallHelpText() { + return "Shows the permissions of you"; + } + + @Override + public String getCommand() { + return "warp permissions"; + } + + @Override + public boolean listHelp(CommandSender sender) { + // It is only a debug function so: false? + return false; + } + +} diff --git a/src/main/java/de/xzise/xwarp/commands/xwarp/ReloadCommand.java b/src/main/java/de/xzise/xwarp/commands/xwarp/ReloadCommand.java new file mode 100644 index 0000000000..35f2262b7d --- /dev/null +++ b/src/main/java/de/xzise/xwarp/commands/xwarp/ReloadCommand.java @@ -0,0 +1,91 @@ +package de.xzise.xwarp.commands.xwarp; + +import java.util.Collection; + + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +import com.google.common.collect.ImmutableList; + +import de.xzise.commands.CommonHelpableSubCommand; +import de.xzise.wrappers.economy.EconomyHandler; +import de.xzise.xwarp.Manager; +import de.xzise.xwarp.PluginProperties; +import de.xzise.xwarp.XWarp; +import de.xzise.xwarp.dataconnections.DataConnection; +import de.xzise.xwarp.listeners.XWServerListener; +import de.xzise.xwarp.wrappers.permission.GeneralPermissions; + +public class ReloadCommand extends CommonHelpableSubCommand { + + private final Collection> managers; + private final PluginProperties properties; + private final EconomyHandler economy; + private final XWServerListener serverListener; + + public ReloadCommand(EconomyHandler economy, XWServerListener serverListener, PluginProperties properties, Manager... manager) { + super("reload"); + this.managers = ImmutableList.copyOf(manager); + this.properties = properties; + this.economy = economy; + this.serverListener = serverListener; + } + + @Override + public boolean execute(CommandSender sender, String[] parameters) { + if (parameters.length == 1) { + if (XWarp.permissions.permission(sender, GeneralPermissions.RELOAD)) { + DataConnection data = this.properties.getDataConnection(); + if (data != null) { + data.free(); + } + this.properties.read(); + this.serverListener.load(); + data = this.properties.getDataConnection(); + try { + if (!data.load(this.properties.getDataConnectionFile())) { + XWarp.logger.severe("Could not load data!"); + sender.sendMessage(ChatColor.RED + "Reload failed!"); + } else { + this.economy.reloadConfig(this.properties.getEconomyPlugin(), this.properties.getEconomyBaseAccount()); + XWarp.permissions.setPluginName(this.properties.getPermissionsPlugin()); + XWarp.permissions.load(); + for (Manager manager : this.managers) { + manager.reload(data); + } + sender.sendMessage(ChatColor.GREEN + "Reload successfully!"); + } + } catch (Exception e) { + XWarp.logger.severe("Exception while reloading!", e); + } + } else { + sender.sendMessage(ChatColor.RED + "You have no permission to reload."); + } + return true; + } else { + return false; + } + } + + @Override + public String[] getFullHelpText() { + return new String[] { "Reloads xWarp's settings and warps." }; + } + + @Override + public String getSmallHelpText() { + return "Reloads xWarp."; + } + + @Override + public String getCommand() { + return "warp reload"; + } + + @Override + public boolean listHelp(CommandSender sender) { + return XWarp.permissions.permission(sender, GeneralPermissions.RELOAD); + } + +} diff --git a/src/main/java/de/xzise/xwarp/commands/xwarp/StatusCommand.java b/src/main/java/de/xzise/xwarp/commands/xwarp/StatusCommand.java new file mode 100644 index 0000000000..9115d246bc --- /dev/null +++ b/src/main/java/de/xzise/xwarp/commands/xwarp/StatusCommand.java @@ -0,0 +1,76 @@ +package de.xzise.xwarp.commands.xwarp; + +import org.bukkit.command.CommandSender; + +import de.xzise.commands.CommonHelpableSubCommand; +import de.xzise.wrappers.economy.EconomyHandler; +import de.xzise.wrappers.permissions.PermissionsHandler; +import de.xzise.xwarp.Manager; +import de.xzise.xwarp.WPAManager; +import de.xzise.xwarp.WarpManager; +import de.xzise.xwarp.WarpObject; + +public class StatusCommand extends CommonHelpableSubCommand { + + private final WarpManager warpManager; + private final WPAManager wpaManager; + private final EconomyHandler economy; + private final PermissionsHandler permissions; + + public StatusCommand(EconomyHandler economy, PermissionsHandler permissions, WarpManager warpManager, WPAManager wpaManager) { + super("status"); + this.warpManager = warpManager; + this.wpaManager = wpaManager; + this.economy = economy; + this.permissions = permissions; + } + + @Override + public boolean execute(CommandSender sender, String[] parameters) { + if (parameters.length == 1) { + sender.sendMessage("xWarp status:"); + sender.sendMessage("Number of warps: " + managerSize(this.warpManager)); + sender.sendMessage("Number of warp protection areas: " + managerSize(this.wpaManager)); + sender.sendMessage("Economy: " + this.economy.getWrapperName()); + sender.sendMessage("Permissions: " + this.permissions.getWrapperName()); + if (this.warpManager.isLinkedWithMarkerAPI()) { + sender.sendMessage("Linked with dynmap marker API"); + } else { + sender.sendMessage("Not linked with dynmap marker API"); + } + return true; + } else { + return false; + } + } + + private static String managerSize(Manager manager) { + String result = Integer.toString(manager.getSize()); + int invalidCount = 0; + for (WarpObject warpObject : manager.getWarpObjects()) { + if (!warpObject.isValid()) { + invalidCount++; + } + } + if (invalidCount > 0) { + result += " (invalid: " + invalidCount + ")"; + } + return result; + } + + @Override + public String[] getFullHelpText() { + return new String[] { "Shows the status of xWarp." }; + } + + @Override + public String getSmallHelpText() { + return "Shows status"; + } + + @Override + public String getCommand() { + return "warp status"; + } + +} diff --git a/src/main/java/de/xzise/xwarp/dataconnections/DataConnection.java b/src/main/java/de/xzise/xwarp/dataconnections/DataConnection.java new file mode 100644 index 0000000000..ae5bd5b9d7 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/dataconnections/DataConnection.java @@ -0,0 +1,56 @@ +package de.xzise.xwarp.dataconnections; + +import java.io.File; +import java.util.List; + +import de.xzise.xwarp.Warp; +import de.xzise.xwarp.editors.EditorPermissions; + + +public interface DataConnection { + + boolean load(File file); + + boolean create(File file); + + void free(); + + String getFilename(); + + void clear(); + + /** + * This method should be called to create an identification for a warp, + * before any changes to this warp will be performed. + * + * @param warp + * The identification for the warp will be created. + * @return An identification. + */ + IdentificationInterface createWarpIdentification(Warp warp); + + List getWarps(); + + void addWarp(Warp... warp); + + void deleteWarp(Warp warp); + + void updateCreator(Warp warp); + + void updateOwner(Warp warp, IdentificationInterface identification); + + void updateName(Warp warp, IdentificationInterface identification); + + void updateMessage(Warp warp); + + void updateVisibility(Warp warp); + + void updateLocation(Warp warp); + + void updateEditor(Warp warp, String name, EditorPermissions.Type type); + + void updatePrice(Warp warp); + + void updateCoolDown(Warp warp); + void updateWarmUp(Warp warp); +} diff --git a/src/main/java/de/xzise/xwarp/dataconnections/DataConnections.java b/src/main/java/de/xzise/xwarp/dataconnections/DataConnections.java new file mode 100644 index 0000000000..ee13039330 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/dataconnections/DataConnections.java @@ -0,0 +1,34 @@ +package de.xzise.xwarp.dataconnections; + +import org.bukkit.Server; + +import de.xzise.xwarp.Warp.Visibility; + +public final class DataConnections { + + private DataConnections() {} + + public static byte getPublicLevel(boolean listed, Visibility visibility) { + return (byte) ((visibility.level & 0x7F) | (listed ? 0 : 1) << 7); + } + + public static Visibility parseVisibility(int value) { + return Visibility.getByLevel((byte) (value & 0x7F)); + } + + public static boolean isListed(int value) { + return (value & 0x80) == 0; + } + public static DataConnection getConnection(Server server, String type) { + if (type.equalsIgnoreCase("sqlite")) { + return new SQLiteConnection(server); + } else if (type.equalsIgnoreCase("hmod")) { + return new HModConnection(server); + } else if (type.equalsIgnoreCase("yml")) { + return new YmlConnection(); + } else { + return null; + } + } + +} diff --git a/src/main/java/de/xzise/xwarp/dataconnections/HModConnection.java b/src/main/java/de/xzise/xwarp/dataconnections/HModConnection.java new file mode 100644 index 0000000000..b661d8d204 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/dataconnections/HModConnection.java @@ -0,0 +1,680 @@ +package de.xzise.xwarp.dataconnections; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.World; + +import de.xzise.MinecraftUtil; +import de.xzise.metainterfaces.FixedLocation; +import de.xzise.metainterfaces.LocationWrapper; +import de.xzise.xwarp.Warp; +import de.xzise.xwarp.XWarp; +import de.xzise.xwarp.Warp.Visibility; +import de.xzise.xwarp.editors.EditorPermissions; +import de.xzise.xwarp.editors.WarpPermissions; +import de.xzise.xwarp.editors.EditorPermissions.Type; + +public class HModConnection implements DataConnection { + + private File file; + private Server server; + private static final char SEPARATOR = ':'; + // Name, X, Y, Z, Yaw, Pitch + /** Minimum length of original generation map. */ + private static final int GEN_0_LENGTH = 6; + // Gen0 + World, Owner, Visibility, Message + /** Minimum length of first generation map. */ + private static final int GEN_1_LENGTH = GEN_0_LENGTH + 4; + // Gen1 + Creator + /** Minimum length of second generation map. */ + private static final int GEN_2_LENGTH = GEN_1_LENGTH + 1; + // Gen2 + Price + /** Minimum length of third generation map. */ + private static final int GEN_3_LENGTH = GEN_2_LENGTH + 1; + // Gen3 + Cooldown, Warmup + other editors layout + /** Minimum length of forth generation map. */ + private static final int GEN_4_LENGTH = GEN_3_LENGTH + 2; + + private static final int VERSION = 4; + + public HModConnection(Server server) { + this.server = server; + } + + @Override + public boolean load(File file) { + this.file = file; + if (!this.file.exists()) { + try { + return this.file.createNewFile(); + } catch (IOException e) { + XWarp.logger.severe("Unable to load the hmod connection", e); + return false; + } + } else { + return this.file.canWrite(); + } + } + + @Override + public void free() { + } + + @Override + public List getWarps() { + // List elements = this.g + List result = new ArrayList(this.getWarps(null)); + return result; + } + + public List getWarps(String owner) { + List result = new ArrayList(); + final List rawLines = new ArrayList(0); + try { + rawLines.addAll(MinecraftUtil.readLines(this.file)); + } catch (FileNotFoundException e) { + XWarp.logger.info("hmod file not found!"); + } catch (IOException e) { + XWarp.logger.severe("Unable to read hmod file '" + this.file.getAbsolutePath() + "'."); + } + + Integer version = processLines(rawLines); + if (version == null) { + version = 0; + XWarp.logger.severe("No version tag in hmod file '" + this.file.getAbsolutePath() + "' found."); + } + switch (version) { + case 0: + return getWarpsVersion0(rawLines, this.server.getWorlds().get(0)); + case 1: + return getWarpsVersion1(rawLines, this.server); + case 2: + return getWarpsVersion2(rawLines, this.server); + case 3: + return getWarpsVersion3(rawLines, this.server); + case 4: + return getWarpsVersion4(rawLines, this.server); + default: + XWarp.logger.severe("Unknown version tag: " + version); + break; + } + return result; + } + + private static Integer processLines(List lines) { + List rawLines = new ArrayList(lines); + lines.clear(); + Integer version = null; + int lineNum = -1; + for (String rawLine : rawLines) { + lineNum++; + if (rawLine.length() > 0 && !rawLine.startsWith("#")) { + if (rawLine.matches("!version\\s*\\d+\\s*")) { + int tempVersion = 0; + try { + tempVersion = Integer.parseInt(rawLine.substring(8).trim()); + } catch (NumberFormatException nfe) { + XWarp.logger.severe("Version tag is an invalid number."); + } + if (version == null) { + version = tempVersion; + } else if (version != tempVersion) { + XWarp.logger.severe("Different version tags found (line: " + lineNum + "), choose first found: " + version); + } + } else { + lines.add(rawLine); + } + } + } + return version; + } + + private static List getWarpsVersion0(List lines, World def) { + List warps = new ArrayList(); + for (String line : lines) { + String[] segments = MinecraftUtil.parseLine(line, SEPARATOR); + if (segments.length == GEN_0_LENGTH) { + Warp warp = null; + boolean valid = true; + try { + String name = segments[0]; + + double x = Double.parseDouble(segments[1]); + double y = Double.parseDouble(segments[2]); + double z = Double.parseDouble(segments[3]); + double yaw = Double.parseDouble(segments[4]); + double pitch = Double.parseDouble(segments[5]); + + yaw = (yaw < 0) ? (360 + (yaw % 360)) : (yaw % 360); + + LocationWrapper location = new LocationWrapper(new Location(def, x, y, z, (float) yaw, (float) pitch)); + warp = new Warp(name, "", "", location); + warp.setVisibility(Visibility.GLOBAL); + } catch (NumberFormatException nfe) { + valid = false; + XWarp.logger.warning("Unable to parse a location value (" + nfe.getMessage() + ")"); + } catch (Exception e) { + XWarp.logger.severe("Catched an unhandled exception", e); + valid = false; + } + if (valid && warp != null) { + warps.add(warp); + } + } else { + XWarp.logger.warning("Invalid warp line found"); + } + } + return warps; + } + + private static List getWarpsVersion1(List lines, Server server) { + List warps = new ArrayList(); + for (String line : lines) { + String[] segments = MinecraftUtil.parseLine(line, SEPARATOR); + if (segments.length >= GEN_1_LENGTH && segments.length % 2 == 0) { + Warp warp = null; + boolean valid = true; + try { + String name = segments[0]; + + double x = Double.parseDouble(segments[1]); + double y = Double.parseDouble(segments[2]); + double z = Double.parseDouble(segments[3]); + float yaw = Float.parseFloat(segments[4]); + float pitch = Float.parseFloat(segments[5]); + + yaw = (yaw < 0) ? (360 + (yaw % 360)) : (yaw % 360); + + World world = server.getWorld(segments[6]); + String warpOwner = segments[7]; + FixedLocation location = new FixedLocation(world, x, y, z, yaw, pitch); + LocationWrapper wrapper = new LocationWrapper(location, segments[6]); + warp = new Warp(name, warpOwner, warpOwner, wrapper); + String msg = segments[9]; + warp.setWelcomeMessage(msg.equals("null") ? null : msg); + for (int i = GEN_1_LENGTH; i < segments.length; i += 2) { + warp.addEditor(segments[i], segments[i + 1], Type.PLAYER); + } + + int visibilityValue = Integer.parseInt(segments[8]); + Visibility v = DataConnections.parseVisibility(visibilityValue); + if (v != null) { + warp.setVisibility(v); + warp.setListed(DataConnections.isListed(visibilityValue)); + } else { + XWarp.logger.warning("Illegal visibilty found (" + warp.getName() + " by " + warp.getOwner() + ")"); + valid = false; + } + } catch (NumberFormatException nfe) { + valid = false; + XWarp.logger.warning("Unable to parse a location value (" + nfe.getMessage() + ")"); + } catch (Exception e) { + XWarp.logger.severe("Catched an unhandled exception", e); + valid = false; + } + if (valid && warp != null) { + warps.add(warp); + } + } else { + XWarp.logger.warning("Invalid warp line found"); + } + } + return warps; + } + + private static List getWarpsVersion2(List lines, Server server) { + List warps = new ArrayList(); + for (String line : lines) { + String[] segments = MinecraftUtil.parseLine(line, SEPARATOR); + if (segments.length >= GEN_2_LENGTH && segments.length % 2 == 1) { + Warp warp = null; + boolean valid = true; + try { + String name = segments[0]; + + double x = Double.parseDouble(segments[1]); + double y = Double.parseDouble(segments[2]); + double z = Double.parseDouble(segments[3]); + float yaw = Float.parseFloat(segments[4]); + float pitch = Float.parseFloat(segments[5]); + + yaw = (yaw < 0) ? (360 + (yaw % 360)) : (yaw % 360); + + World world = server.getWorld(segments[6]); + String warpOwner = segments[7]; + FixedLocation location = new FixedLocation(world, x, y, z, yaw, pitch); + LocationWrapper wrapper = new LocationWrapper(location, segments[6]); + warp = new Warp(name, segments[segments.length - 1], warpOwner, wrapper); + String msg = segments[9]; + warp.setWelcomeMessage(msg.equals("null") ? null : msg); + for (int i = GEN_1_LENGTH; i < segments.length - 1; i += 2) { + warp.addEditor(segments[i], segments[i + 1], Type.PLAYER); + } + + int visibilityValue = Integer.parseInt(segments[8]); + Visibility v = DataConnections.parseVisibility(visibilityValue); + if (v != null) { + warp.setVisibility(v); + warp.setListed(DataConnections.isListed(visibilityValue)); + } else { + XWarp.logger.warning("Illegal visibilty found (" + warp.getName() + " by " + warp.getOwner() + ")"); + valid = false; + } + } catch (NumberFormatException nfe) { + valid = false; + XWarp.logger.warning("Unable to parse a location value (" + nfe.getMessage() + ")"); + } catch (Exception e) { + XWarp.logger.severe("Catched an unhandled exception", e); + valid = false; + } + if (valid && warp != null) { + warps.add(warp); + } + } else { + XWarp.logger.warning("Invalid warp line found"); + } + } + return warps; + } + + private static List getWarpsVersion3(List lines, Server server) { + List warps = new ArrayList(); + for (String line : lines) { + String[] segments = MinecraftUtil.parseLine(line, SEPARATOR); + if (segments.length >= GEN_3_LENGTH && segments.length % 2 == 0) { + Warp warp = null; + boolean valid = true; + try { + String name = segments[0]; + + double x = Double.parseDouble(segments[1]); + double y = Double.parseDouble(segments[2]); + double z = Double.parseDouble(segments[3]); + float yaw = Float.parseFloat(segments[4]); + float pitch = Float.parseFloat(segments[5]); + + yaw = (yaw < 0) ? (360 + (yaw % 360)) : (yaw % 360); + + World world = server.getWorld(segments[6]); + String warpOwner = segments[7]; + String creator = segments[10]; + FixedLocation location = new FixedLocation(world, x, y, z, yaw, pitch); + LocationWrapper wrapper = new LocationWrapper(location, segments[6]); + warp = new Warp(name, creator, warpOwner, wrapper); + String msg = segments[9]; + warp.setWelcomeMessage(msg.equals("null") ? null : msg); + warp.setPrice(Integer.parseInt(segments[11])); + for (int i = GEN_3_LENGTH; i < segments.length - 1; i += 2) { + warp.addEditor(segments[i], segments[i + 1], Type.PLAYER); + } + + int visibilityValue = Integer.parseInt(segments[8]); + Visibility v = DataConnections.parseVisibility(visibilityValue); + if (v != null) { + warp.setVisibility(v); + warp.setListed(DataConnections.isListed(visibilityValue)); + } else { + XWarp.logger.warning("Illegal visibility found (" + warp.getName() + " by " + warp.getOwner() + ")"); + valid = false; + } + } catch (NumberFormatException nfe) { + valid = false; + XWarp.logger.warning("Unable to parse a value (" + nfe.getMessage() + ")"); + } catch (Exception e) { + XWarp.logger.severe("Catched an unhandled exception", e); + valid = false; + } + if (valid && warp != null) { + warps.add(warp); + } + } else { + XWarp.logger.warning("Invalid warp line found:"); + XWarp.logger.warning(line); + } + } + return warps; + } + + private static List getWarpsVersion4(List lines, Server server) { + List warps = new ArrayList(); + for (String line : lines) { + String[] segments = MinecraftUtil.parseLine(line, SEPARATOR); + if (segments.length >= GEN_4_LENGTH && (segments.length - GEN_4_LENGTH) % 3 == 0) { + Warp warp = null; + boolean valid = true; + try { + String name = segments[0]; + + double x = Double.parseDouble(segments[1]); + double y = Double.parseDouble(segments[2]); + double z = Double.parseDouble(segments[3]); + float yaw = Float.parseFloat(segments[4]); + float pitch = Float.parseFloat(segments[5]); + + yaw = (yaw < 0) ? (360 + (yaw % 360)) : (yaw % 360); + + World world = server.getWorld(segments[6]); + String warpOwner = segments[7]; + String creator = segments[10]; + FixedLocation location = new FixedLocation(world, x, y, z, yaw, pitch); + LocationWrapper wrapper = new LocationWrapper(location, segments[6]); + warp = new Warp(name, creator, warpOwner, wrapper); + String msg = segments[9]; + warp.setWelcomeMessage(msg.equals("null") ? null : msg); + warp.setPrice(Integer.parseInt(segments[11])); + warp.setCoolDown(Integer.parseInt(segments[12])); + warp.setWarmUp(Integer.parseInt(segments[13])); + for (int i = GEN_4_LENGTH; i < segments.length - 1; i += 3) { + EditorPermissions.Type type = null; + if (segments[i + 2].equalsIgnoreCase("group") || segments[i + 2].equalsIgnoreCase("g")) { + type = Type.GROUP; + } else { + if (!segments[i + 2].equalsIgnoreCase("player") && !segments[i + 2].equalsIgnoreCase("p")) { + XWarp.logger.warning("Illegal editor type found (" + warp.getName() + " by " + warp.getOwner() + ")"); + } + type = Type.PLAYER; + } + warp.addEditor(segments[i], segments[i + 1], type); + } + + int visibilityValue = Integer.parseInt(segments[8]); + Visibility v = DataConnections.parseVisibility(visibilityValue); + if (v != null) { + warp.setVisibility(v); + warp.setListed(DataConnections.isListed(visibilityValue)); + } else { + XWarp.logger.warning("Illegal visibility found (" + warp.getName() + " by " + warp.getOwner() + ")"); + valid = false; + } + } catch (NumberFormatException nfe) { + valid = false; + XWarp.logger.warning("Unable to parse a value (" + nfe.getMessage() + ")"); + } catch (Exception e) { + XWarp.logger.severe("Catched an unhandled exception", e); + valid = false; + } + if (valid && warp != null) { + warps.add(warp); + } + } else { + XWarp.logger.warning("Invalid warp line found:"); + XWarp.logger.warning(line); + } + } + return warps; + } + + private void writeWarps(List warps) { + this.writeWarps(warps, VERSION); + } + + private void writeWarps(final List warps, final int version) { + try { + FileWriter writer = new FileWriter(this.file); + try { + writer.write("!version " + version + "\n"); + for (Warp warp : warps) { + writeWarp(warp, writer, version); + } + } finally { + writer.close(); + } + } catch (IOException e) { + XWarp.logger.severe("Unable to write the file", e); + } + } + + private static void writeWarp(Warp warp, Writer writer, int version) throws IOException { + try { + StringBuilder warpLine = new StringBuilder(); + LocationWrapper l = warp.getLocationWrapper(); + FixedLocation location = l.getLocation(); + warpLine.append(makeParsable(warp.getName()) + SEPARATOR); + warpLine.append(makeParsable(location.x) + SEPARATOR); + warpLine.append(makeParsable(location.y) + SEPARATOR); + warpLine.append(makeParsable(location.z) + SEPARATOR); + warpLine.append(makeParsable(location.yaw) + SEPARATOR); + warpLine.append(makeParsable(location.pitch) + SEPARATOR); + if (version >= 1) { + warpLine.append(makeParsable(l.getWorld()) + SEPARATOR); + warpLine.append(makeParsable(warp.getOwner()) + SEPARATOR); + warpLine.append(makeParsable(DataConnections.getPublicLevel(warp.isListed(), warp.getVisibility())) + SEPARATOR); + warpLine.append(makeNullsParsable(warp.getRawWelcomeMessage()) + SEPARATOR); + if (version >= 3) { + warpLine.append(makeParsable(warp.getCreator()) + SEPARATOR); + warpLine.append(makeParsable(warp.getPrice()) + SEPARATOR); + } + if (version >= 4) { + warpLine.append(makeParsable(warp.getCoolDown()) + SEPARATOR); + warpLine.append(makeParsable(warp.getWarmUp()) + SEPARATOR); + for (EditorPermissions.Type type : EditorPermissions.Type.values()) { + appendEditorPermissions(warpLine, warp.getEditorPermissions(type), type.name); + } + } else { + appendEditorPermissions(warpLine, warp.getEditorPermissions(Type.PLAYER), null); + + if (version == 2) { + warpLine.append(makeParsable(warp.getCreator()) + SEPARATOR); + } + } + } + writer.append(warpLine.append("\n")); + } catch (IOException ioe) { + throw ioe; + } catch (Exception e) { + XWarp.logger.severe("Unable to write warp: '" + warp.getName() + "' by " + warp.getOwner(), e); + } + } + + private static void appendEditorPermissions(StringBuilder builder, Map> permissions, String type) { + String parsableType = ""; + if (MinecraftUtil.isSet(type)) { + parsableType = makeParsable(type) + SEPARATOR; + } + for (Entry> entry : permissions.entrySet()) { + builder.append(makeParsable(entry.getKey()) + SEPARATOR); + builder.append(makeParsable(entry.getValue().getPermissionString()) + SEPARATOR); + builder.append(parsableType); + } + } + + private static String makeParsable(int input) { + return Integer.toString(input); + } + + private static String makeParsable(double input) { + return Double.toString(input); + } + + private static String makeParsable(String input) { + // Length output + int length = 0; + // Maximum length = twice input length (to escape at least each + // character) + char[] output = new char[input.length() * 2]; + char[] in = input.toCharArray(); + for (int i = 0; i < in.length; i++) { + char c = in[i]; + switch (c) { + case ':': + case '\\': + case '"': + case '#': + case '!': + output[length++] = '\\'; + } + output[length++] = c; + } + return new String(Arrays.copyOf(output, length)); + } + + private static String makeNullsParsable(String input) { + if (input == null) { + return "null"; + } else { + return makeParsable(input); + } + } + + @Override + public void addWarp(Warp... warps) { + if (warps.length > 0) { + Integer version = null; + try { + processLines(MinecraftUtil.readLines(this.file)); + } catch (FileNotFoundException e) { + XWarp.logger.info("Unable to determine version of the hmod file, because the file doesn't exists '" + this.file.getAbsolutePath() + "'."); + } catch (IOException e) { + XWarp.logger.severe("Unable to determine version while writing to hmod file '" + this.file.getAbsolutePath() + "'."); + } + if (version == null) { + version = VERSION; + } + try { + FileWriter writer = new FileWriter(this.file, true); + try { + for (Warp warp : warps) { + writeWarp(warp, writer, version); + } + } finally { + writer.close(); + } + } catch (IOException e) { + XWarp.logger.severe("Unable to write the file", e); + } + } + } + + @Override + public void deleteWarp(Warp warp) { + // First read all, then delete the selected and then write all + List warps = this.getWarps(); + warps.remove(warp); + this.writeWarps(warps); + } + + private static Warp getWarp(List warps, IdentificationInterface identification) { + for (Warp warp : warps) { + if (identification.isIdentificated(warp)) { + return warp; + } + } + return null; + } + + @Override + public void updateCreator(Warp warp) { + List warps = this.getWarps(); + Warp updated = warps.get(warps.indexOf(warp)); + updated.setCreator(warp.getCreator()); + this.writeWarps(warps); + } + + @Override + public void updateOwner(Warp warp, IdentificationInterface identification) { + List warps = this.getWarps(); + Warp updated = getWarp(warps, identification); + updated.setOwner(warp.getOwner()); + this.writeWarps(warps); + } + + @Override + public void updateName(Warp warp, IdentificationInterface identification) { + List warps = this.getWarps(); + Warp updated = getWarp(warps, identification); + updated.setName(warp.getName()); + this.writeWarps(warps); + } + + @Override + public void updateLocation(Warp warp) { + List warps = this.getWarps(); + Warp updated = warps.get(warps.indexOf(warp)); + updated.setLocation(warp.getLocation()); + this.writeWarps(warps); + } + + @Override + public void updateMessage(Warp warp) { + List warps = this.getWarps(); + Warp updated = warps.get(warps.indexOf(warp)); + updated.setWelcomeMessage(warp.getRawWelcomeMessage()); + this.writeWarps(warps); + } + + @Override + public void updateVisibility(Warp warp) { + List warps = this.getWarps(); + Warp updated = warps.get(warps.indexOf(warp)); + updated.setVisibility(warp.getVisibility()); + updated.setListed(warp.isListed()); + this.writeWarps(warps); + } + + @Override + public void updateEditor(Warp warp, String name, EditorPermissions.Type type) { + List warps = this.getWarps(); + warps.set(warps.indexOf(warp), warp); + this.writeWarps(warps); + } + + @Override + public void updatePrice(Warp warp) { + List warps = this.getWarps(); + Warp updated = warps.get(warps.indexOf(warp)); + updated.setPrice(warp.getPrice()); + this.writeWarps(warps); + } + + @Override + public boolean create(File file) { + if (this.load(file)) { + this.clear(); + return true; + } else { + return false; + } + } + + @Override + public String getFilename() { + return "hmod.txt"; + } + + @Override + public void clear() { + this.writeWarps(new ArrayList(0)); + } + + @Override + public IdentificationInterface createWarpIdentification(Warp warp) { + return NameIdentification.create(warp); + } + + @Override + public void updateCoolDown(Warp warp) { + List warps = this.getWarps(); + Warp updated = warps.get(warps.indexOf(warp)); + updated.setCoolDown(warp.getCoolDown()); + this.writeWarps(warps); + } + + @Override + public void updateWarmUp(Warp warp) { + List warps = this.getWarps(); + Warp updated = warps.get(warps.indexOf(warp)); + updated.setWarmUp(warp.getWarmUp()); + this.writeWarps(warps); + } +} diff --git a/src/main/java/de/xzise/xwarp/dataconnections/IdentificationInterface.java b/src/main/java/de/xzise/xwarp/dataconnections/IdentificationInterface.java new file mode 100644 index 0000000000..409a477d8b --- /dev/null +++ b/src/main/java/de/xzise/xwarp/dataconnections/IdentificationInterface.java @@ -0,0 +1,12 @@ +package de.xzise.xwarp.dataconnections; + +public interface IdentificationInterface { + + /** + * Determines if the given object is identificated by this identification. + * @param object The tested object. + * @return If the object is meant by this identification. + */ + boolean isIdentificated(T object); + +} diff --git a/src/main/java/de/xzise/xwarp/dataconnections/NameIdentification.java b/src/main/java/de/xzise/xwarp/dataconnections/NameIdentification.java new file mode 100644 index 0000000000..af5690d4e2 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/dataconnections/NameIdentification.java @@ -0,0 +1,28 @@ +package de.xzise.xwarp.dataconnections; + +import de.xzise.xwarp.WarpObject; + +public final class NameIdentification> implements IdentificationInterface { + + private final String name; + private final String owner; + + public NameIdentification(T warpObject) { + this(warpObject.getName(), warpObject.getOwner()); + } + + public static > NameIdentification create(T warpObject) { + return new NameIdentification(warpObject); + } + + public NameIdentification(String name, String owner) { + this.name = name; + this.owner = owner; + } + + @Override + public boolean isIdentificated(T warpObject) { + return warpObject.getName().equalsIgnoreCase(this.name) && warpObject.getOwner().equals(this.owner); + } + +} \ No newline at end of file diff --git a/src/main/java/de/xzise/xwarp/dataconnections/SQLiteConnection.java b/src/main/java/de/xzise/xwarp/dataconnections/SQLiteConnection.java new file mode 100644 index 0000000000..907999d5dc --- /dev/null +++ b/src/main/java/de/xzise/xwarp/dataconnections/SQLiteConnection.java @@ -0,0 +1,1098 @@ +package de.xzise.xwarp.dataconnections; + +import java.io.File; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.logging.Level; + +import org.bukkit.Server; +import org.bukkit.World; + +import de.xzise.metainterfaces.FixedLocation; +import de.xzise.metainterfaces.LocationWrapper; +import de.xzise.xwarp.Warp.Visibility; +import de.xzise.xwarp.editors.Editor; +import de.xzise.xwarp.editors.EditorPermissions; +import de.xzise.xwarp.editors.WarpPermissions; +import de.xzise.xwarp.editors.EditorPermissions.Table; +import de.xzise.xwarp.editors.EditorPermissions.Type; +import de.xzise.xwarp.editors.WarpProtectionAreaPermissions; +import de.xzise.xwarp.DefaultWarpObject.EditorPermissionEntry; +import de.xzise.xwarp.Warp; +import de.xzise.xwarp.WarpObject; +import de.xzise.xwarp.WarpProtectionArea; +import de.xzise.xwarp.WorldWrapper; +import de.xzise.xwarp.XWarp; + + +public class SQLiteConnection implements WarpProtectionConnection { + + public final static String DATABASE = "jdbc:sqlite:homes-warps.db"; + //@formatter:off + private final static String WARP_TABLE = "CREATE TABLE `warps` (" + + "`id` INTEGER PRIMARY KEY," + + "`name` varchar(32) NOT NULL," + + "`creator` varchar(32) NOT NULL," + + "`world` varchar(32) NOT NULL," + + "`x` DOUBLE NOT NULL DEFAULT '0'," + + "`y` DOUBLE NOT NULL DEFAULT '0'," + + "`z` DOUBLE NOT NULL DEFAULT '0'," + + "`yaw` smallint NOT NULL DEFAULT '0'," + + "`pitch` smallint NOT NULL DEFAULT '0'," + + "`publicLevel` smallint NOT NULL DEFAULT '1'," + + "`welcomeMessage` varchar(100) DEFAULT NULL," + + "`owner` varchar(32) NOT NULL DEFAULT '', " + + "`price` DOUBLE NOT NULL DEFAULT '0', " + + "`cooldown` INTEGER NOT NULL DEFAULT -1, " + + "`warmup` INTEGER NOT NULL DEFAULT -1" + ");"; + private final static String PERMISSIONS_TABLE = "CREATE TABLE `permissions` (" + + "`id` INTEGER NOT NULL," + + "`editor` varchar(32) NOT NULL," + + "`value` INTEGER NOT NULL," + + "`type` INTEGER NOT NULL," + + "`warpType` INTEGER NOT NULL" + ");"; + private final static String PROTECTION_AREA_TABLE = "CREATE TABLE `protectionAreas` (" + + "`id` INTEGER PRIMARY KEY," + + "`name` varchar(32) NOT NULL," + + "`creator` varchar(32) NOT NULL," + + "`world` varchar(32) NOT NULL," + + "`x1` DOUBLE NOT NULL DEFAULT '0'," + + "`y1` DOUBLE NOT NULL DEFAULT '0'," + + "`z1` DOUBLE NOT NULL DEFAULT '0'," + + "`x2` DOUBLE NOT NULL DEFAULT '0'," + + "`y2` DOUBLE NOT NULL DEFAULT '0'," + + "`z2` DOUBLE NOT NULL DEFAULT '0'," + + "`owner` varchar(32) NOT NULL DEFAULT ''" + ");"; + + private final static String VERSION_TABLE = "CREATE TABLE `meta` (`name` varchar(32) NOT NULL, `value` int NOT NULL);"; + //@formatter:on + + private final static int TARGET_VERSION = 5; + + private Server server; + private Connection connection; + + public SQLiteConnection(Server server) { + // Nothing to do here + this.server = server; + } + + private boolean initFile(File file) { + this.free(); + try { + Class.forName("org.sqlite.JDBC"); + this.connection = DriverManager.getConnection("jdbc:sqlite:" + file.getAbsolutePath()); + this.connection.setAutoCommit(false); + } catch (ClassNotFoundException e) { + XWarp.logger.severe("Class not found", e); + return false; + } catch (SQLException e) { + XWarp.logger.severe("Generic SQLException", e); + return false; + } + return true; + } + + public void free() { + if (this.connection != null) { + XWarp.logger.info("Close connection!"); + try { + this.connection.close(); + this.connection = null; + } catch (SQLException e) { + e.printStackTrace(); + } + } else { + this.connection = null; + } + } + + protected void finalize() throws Throwable { + this.free(); + super.finalize(); + } + + private class WarpPermission { + public final int id; + public final String editor; + + public WarpPermission(int id, String editor) { + this.id = id; + this.editor = editor; + } + } + + private void update() { + int version = getVersion(); + + if (version < TARGET_VERSION) { + XWarp.logger.info("Database layout is outdated (" + version + ")! Updating to " + TARGET_VERSION + "."); + Statement statement = null; + PreparedStatement convertedWarp = null; + PreparedStatement convertedPermissions = null; + PreparedStatement convertedProtectionArea = null; + PreparedStatement permissionsInsert = null; + ResultSet set = null; + try { + statement = this.connection.createStatement(); + + // Backup old permissions table (if exists) + if (tableExists("permissions")) { + statement.execute("ALTER TABLE permissions RENAME TO permissions_backup"); + XWarp.logger.info("Backuping old permissions table."); + } + + XWarp.logger.info("Creating permission table."); + statement.execute(PERMISSIONS_TABLE); + + if (tableExists("permissions_backup")) { + set = statement.executeQuery("SELECT * FROM permissions_backup"); + convertedPermissions = this.connection.prepareStatement("INSERT INTO permissions (id, editor, value, type, warpType) VALUES (?,?,?,?,?)"); + while (set.next()) { + convertedPermissions.setInt(1, set.getInt("id")); + convertedPermissions.setString(2, set.getString("editor")); + convertedPermissions.setInt(3, set.getInt("value")); + if (version < 5) { + convertedPermissions.setInt(4, EditorPermissions.Type.PLAYER.id); + convertedPermissions.setInt(5, EditorPermissions.Table.WARP.id); + } else { + convertedPermissions.setInt(4, set.getInt("type")); + convertedPermissions.setInt(5, set.getInt("warpType")); + } + convertedPermissions.executeUpdate(); + } + + statement.executeUpdate("DROP TABLE permissions_backup"); + XWarp.logger.info("Permissions backup recovered."); + } + + // Backup old protection areas table (if exists) + if (tableExists("protectionAreas")) { + statement.execute("ALTER TABLE protectionAreas RENAME TO protectionAreas_backup"); + XWarp.logger.info("Backuping old protection area table."); + } + + XWarp.logger.info("Creating protection area table."); + statement.execute(PROTECTION_AREA_TABLE); + + if (tableExists("protectionAreas_backup")) { + set = statement.executeQuery("SELECT * FROM protectionAreas_backup"); + convertedProtectionArea = this.connection.prepareStatement("INSERT INTO protectionAreas (id, name, creator, x1, y1, z1, x2, y2, z2, owner) VALUES (?,?,?,?,?,?,?,?,?,?)"); + while (set.next()) { + convertedProtectionArea.setInt(1, set.getInt("id")); + convertedProtectionArea.setString(2, set.getString("name")); + convertedProtectionArea.setString(3, set.getString("creator")); + convertedProtectionArea.setDouble(4, set.getDouble("x1")); + convertedProtectionArea.setDouble(5, set.getDouble("y1")); + convertedProtectionArea.setDouble(6, set.getDouble("z1")); + convertedProtectionArea.setDouble(7, set.getDouble("x2")); + convertedProtectionArea.setDouble(8, set.getDouble("y2")); + convertedProtectionArea.setDouble(9, set.getDouble("z2")); + convertedProtectionArea.setString(10, set.getString("owner")); + convertedProtectionArea.executeUpdate(); + } + + statement.executeUpdate("DROP TABLE permissions_backup"); + XWarp.logger.info("Permissions backup recovered."); + } + + // Backup old warp table (if exists) + if (tableExists("warps")) { + // Backup it + statement.execute("ALTER TABLE warps RENAME TO warps_backup"); + XWarp.logger.info("Backuping old warp table."); + } else if (tableExists("warpTable")) { + // Backup it + statement.execute("ALTER TABLE warpTable RENAME TO warps_backup"); + XWarp.logger.info("Backuping old warp table."); + } + + // Create new database + statement.executeUpdate(WARP_TABLE); + if (tableExists("warps_backup")) { + // Select line by line + String world = server.getWorlds().get(0).getName(); + set = statement.executeQuery("SELECT * FROM warps_backup"); + List list = new ArrayList(); + convertedWarp = this.connection.prepareStatement("INSERT INTO warps (id, name, creator, world, x, y, z, yaw, pitch, publicLevel, welcomeMessage, owner, price, cooldown, warmup) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); + while (set.next()) { + int id = set.getInt("id"); + convertedWarp.setInt(1, id); + convertedWarp.setString(2, set.getString("name")); + convertedWarp.setString(3, set.getString("creator")); + if (version < 1) { + String worldName = set.getString("world"); + if (worldName.equals("0")) { + convertedWarp.setString(4, world); + } else { + if (this.server.getWorld(set.getString("world")) == null) { + XWarp.logger.info("Found warp with unknown world. (Name: " + set.getString("name") + ")"); + } + convertedWarp.setString(4, set.getString("world")); + } + } else { + convertedWarp.setString(4, set.getString("world")); + } + convertedWarp.setDouble(5, set.getDouble("x")); + convertedWarp.setDouble(6, set.getDouble("y")); + convertedWarp.setDouble(7, set.getDouble("z")); + convertedWarp.setInt(8, set.getInt("yaw")); + convertedWarp.setInt(9, set.getInt("pitch")); + if (version < 0) { + if (set.getBoolean("publicAll")) { + convertedWarp.setInt(10, 1); + } else { + convertedWarp.setInt(10, 0); + } + } else { + convertedWarp.setInt(10, set.getInt("publicLevel")); + } + if (version < 2) { + List p = processList(set.getString("permissions")); + for (String string : p) { + list.add(new WarpPermission(id, string)); + } + } + convertedWarp.setString(11, set.getString("welcomeMessage")); + if (version < 3) { + convertedWarp.setString(12, set.getString("creator")); + } else { + convertedWarp.setString(12, set.getString("owner")); + } + if (version < 4) { + convertedWarp.setDouble(13, 0); + } else { + convertedWarp.setDouble(13, set.getDouble("price")); + } + if (version < 5) { + convertedWarp.setInt(14, -1); + convertedWarp.setInt(15, -1); + } else { + convertedWarp.setInt(14, set.getInt("cooldown")); + convertedWarp.setInt(14, set.getInt("warmup")); + } + convertedWarp.executeUpdate(); + } + + if (version < 3) { + + } + + if (version < 2) { + XWarp.logger.info("Adding permissions table"); + + if (list.size() > 0) { + permissionsInsert = this.connection.prepareStatement("INSERT OR IGNORE INTO permissions (id, editor, value, type, warpType) VALUES (?,?,?,?,?)"); + + for (WarpPermission warpPermission : list) { + permissionsInsert.setInt(1, warpPermission.id); + permissionsInsert.setString(2, warpPermission.editor); + permissionsInsert.setInt(3, WarpPermissions.WARP.id); + permissionsInsert.setInt(4, EditorPermissions.Type.PLAYER.id); + permissionsInsert.setInt(5, EditorPermissions.Table.WARP.id); + permissionsInsert.addBatch(); + } + permissionsInsert.executeBatch(); + } + } + + statement.executeUpdate("DROP TABLE warps_backup"); + XWarp.logger.info("Recovering the backup."); + } + if (version < 0) { + statement.executeUpdate("INSERT INTO meta (name, value) VALUES (\"version\", " + TARGET_VERSION + ")"); + } else { + statement.executeUpdate("UPDATE meta SET value = " + TARGET_VERSION + " WHERE name = \"version\""); + } + this.connection.commit(); + } catch (SQLException ex) { + // try { + // statement.execute("ROLLBACK"); + // } catch (SQLException e) { + // MyWarp.logger.severe("Unable to rollback changes!"); + // } + XWarp.logger.log(Level.SEVERE, "Warp Load Exception", ex); + } finally { + try { + if (permissionsInsert != null) + permissionsInsert.close(); + if (convertedWarp != null) + convertedWarp.close(); + if (convertedPermissions != null) + convertedPermissions.close(); + if (convertedProtectionArea != null) + convertedProtectionArea.close(); + if (statement != null) + statement.close(); + if (set != null) + set.close(); + } catch (SQLException ex) { + XWarp.logger.severe("Warp Load Exception (on close)"); + } + } + } + } + + private boolean tableExists(String name) { + ResultSet rs = null; + try { + DatabaseMetaData dbm = this.connection.getMetaData(); + rs = dbm.getTables(null, null, name, null); + if (!rs.next()) + return false; + return true; + } catch (SQLException ex) { + XWarp.logger.log(Level.SEVERE, "Table Check Exception", ex); + return false; + } finally { + try { + if (rs != null) + rs.close(); + } catch (SQLException ex) { + XWarp.logger.severe("Table Check SQL Exception (on closing)"); + } + } + } + + public int getVersion() { + Statement statement = null; + int version = -1; + ResultSet set = null; + try { + statement = this.connection.createStatement(); + if (tableExists("meta")) { + set = statement.executeQuery("SELECT * FROM meta WHERE name = \"version\""); + + if (set.next()) { + version = set.getInt("value"); + } + } else { + XWarp.logger.info("Meta table doesn't exists... Creating new"); + statement.executeUpdate(VERSION_TABLE); + this.connection.commit(); + version = -1; + } + } catch (SQLException ex) { + XWarp.logger.log(Level.SEVERE, "Table Check Exception", ex); + } finally { + try { + if (statement != null) { + statement.close(); + } + if (set != null) + set.close(); + } catch (SQLException ex) { + XWarp.logger.severe("Table Check SQL Exception (on closing)"); + } + } + return version; + } + + @Override + public List getWarps() { + List result = new ArrayList(); + Statement statement = null; + ResultSet set = null; + try { + statement = this.connection.createStatement(); + Map>>> allPermissions = this.getEditorPermissions(Table.WARP, WarpPermissions.class, WarpPermissions.ID_MAP); + + set = statement.executeQuery("SELECT * FROM warps"); + int size = 0; + int invalidSize = 0; + while (set.next()) { + size++; + int index = set.getInt("id"); + String name = set.getString("name"); + String creator = set.getString("creator"); + String worldName = set.getString("world"); + World world = server.getWorld(worldName); + double x = set.getDouble("x"); + double y = set.getDouble("y"); + double z = set.getDouble("z"); + float yaw = set.getFloat("yaw"); + float pitch = set.getFloat("pitch"); + LocationWrapper loc = new LocationWrapper(new FixedLocation(world, x, y, z, yaw, pitch), worldName); + int publicLevel = set.getInt("publicLevel"); + Visibility visibility = DataConnections.parseVisibility(publicLevel); + boolean listed = DataConnections.isListed(publicLevel); + String welcomeMessage = set.getString("welcomeMessage"); + String owner = set.getString("owner"); + int cooldown = set.getInt("cooldown"); + int warmup = set.getInt("warmup"); + Warp warp = new Warp(index, name, creator, owner, loc, visibility, allPermissions.get(index), welcomeMessage); + warp.setPrice(set.getInt("price")); + warp.setListed(listed); + warp.setCoolDown(cooldown); + warp.setWarmUp(warmup); + result.add(warp); + if (!warp.getLocationWrapper().isValid()) { + invalidSize++; + } + } + XWarp.logger.info(size + " warps loaded"); + if (invalidSize > 0) { + XWarp.logger.warning(invalidSize + " invalid warps found."); + } + } catch (SQLException ex) { + XWarp.logger.severe("Warp Load Exception", ex); + } finally { + try { + if (statement != null) + statement.close(); + if (set != null) + set.close(); + } catch (SQLException ex) { + XWarp.logger.severe("Warp Load Exception (on close)"); + } + } + return result; + } + + @Override + public void addWarp(Warp... warps) { + if (warps.length > 0) { + PreparedStatement ps = null; + PreparedStatement insertPermissions = null; + try { + ps = this.connection.prepareStatement("INSERT INTO warps (id, name, creator, world, x, y, z, yaw, pitch, publicLevel, welcomeMessage, owner, price) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"); + insertPermissions = this.connection.prepareStatement("INSERT INTO permissions (id, editor, value, type, warpType) VALUES (?,?,?,?,?)"); + for (Warp warp : warps) { + ps.setInt(1, warp.index); + ps.setString(2, warp.getName()); + ps.setString(3, warp.getCreator()); + setLocation(warp.getLocationWrapper(), 4, ps); + ps.setInt(10, DataConnections.getPublicLevel(warp.isListed(), warp.getVisibility())); + ps.setString(11, warp.getRawWelcomeMessage()); + ps.setString(12, warp.getOwner()); + ps.setDouble(13, warp.getPrice()); + ps.addBatch(); + + for (EditorPermissionEntry editorPermissionEntry : warp.getEditorPermissionsList()) { + for (WarpPermissions p : editorPermissionEntry.editorPermissions.getByValue(true)) { + insertPermissions.setInt(1, warp.index); + insertPermissions.setString(2, editorPermissionEntry.name); + insertPermissions.setInt(3, p.id); + insertPermissions.setInt(4, editorPermissionEntry.type.id); + insertPermissions.setInt(5, EditorPermissions.Table.WARP.id); + insertPermissions.addBatch(); + } + } + } + ps.executeBatch(); + insertPermissions.executeBatch(); + + this.connection.commit(); + } catch (SQLException ex) { + XWarp.logger.log(Level.SEVERE, "Warp Insert Exception", ex); + } finally { + try { + if (ps != null) { + ps.close(); + } + if (insertPermissions != null) { + insertPermissions.close(); + } + } catch (SQLException ex) { + XWarp.logger.log(Level.SEVERE, "Warp Insert Exception (on close)", ex); + } + } + } + } + + private static void setLocation(LocationWrapper wrapper, int offset, PreparedStatement ps) throws SQLException { + ps.setString(offset++, wrapper.getWorld()); + FixedLocation location = wrapper.getLocation(); + ps.setDouble(offset++, location.x); + ps.setDouble(offset++, location.y); + ps.setDouble(offset++, location.z); + ps.setInt(offset++, (int) location.yaw); + ps.setInt(offset++, (int) location.pitch); + } + + @Override + public void deleteWarp(Warp warp) { + this.updateWarp(warp, "Delete", "DELETE FROM warps WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(Warp warp, PreparedStatement statement) throws SQLException { + statement.setInt(1, warp.index); + } + }); + } + + private interface UpdateFiller> { + void fillStatement(T warp, PreparedStatement statement) throws SQLException; + } + + private > void updateWarpObject(T warpObject, String type, String name, String sql, UpdateFiller filler) { + PreparedStatement ps = null; + ResultSet set = null; + try { + ps = this.connection.prepareStatement(sql); + filler.fillStatement(warpObject, ps); + ps.executeUpdate(); + this.connection.commit(); + } catch (SQLException ex) { + XWarp.logger.log(Level.SEVERE, type + " " + name + " exception", ex); + } finally { + try { + if (ps != null) { + ps.close(); + } + if (set != null) { + set.close(); + } + } catch (SQLException ex) { + XWarp.logger.log(Level.SEVERE, type + " " + name + " exception (on close)", ex); + } + } + } + + private void updateWarp(Warp warp, String name, String sql, UpdateFiller filler) { + this.updateWarpObject(warp, "Warp", name, sql, filler); + } + + @Override + public void updateOwner(Warp warp, IdentificationInterface identification) { + this.updateWarp(warp, "owner", "UPDATE warps SET owner = ? WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(Warp warp, PreparedStatement statement) throws SQLException { + statement.setString(1, warp.getOwner()); + statement.setInt(2, warp.index); + } + }); + } + + @Override + public void updateCreator(Warp warp) { + this.updateWarp(warp, "creator", "UPDATE warps SET creator = ? WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(Warp warp, PreparedStatement statement) throws SQLException { + statement.setString(1, warp.getCreator()); + statement.setInt(2, warp.index); + } + }); + } + + @Override + public void updateMessage(Warp warp) { + this.updateWarp(warp, "welcome message", "UPDATE warps SET welcomeMessage = ? WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(Warp warp, PreparedStatement statement) throws SQLException { + statement.setString(1, warp.getRawWelcomeMessage()); + statement.setInt(2, warp.index); + } + }); + } + + @Override + public void updateName(Warp warp, IdentificationInterface identification) { + this.updateWarp(warp, "name", "UPDATE warps SET name = ? WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(Warp warp, PreparedStatement statement) throws SQLException { + statement.setString(1, warp.getName()); + statement.setInt(2, warp.index); + } + }); + } + + @Override + public void updateVisibility(Warp warp) { + this.updateWarp(warp, "visibility", "UPDATE warps SET publicLevel = ? WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(Warp warp, PreparedStatement statement) throws SQLException { + statement.setInt(1, DataConnections.getPublicLevel(warp.isListed(), warp.getVisibility())); + statement.setInt(2, warp.index); + } + }); + } + + @Override + public void updateLocation(Warp warp) { + this.updateWarp(warp, "location", "UPDATE warps SET world = ?, x = ?, y = ?, z = ?, yaw = ?, pitch = ? WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(Warp warp, PreparedStatement statement) throws SQLException { + SQLiteConnection.setLocation(warp.getLocationWrapper(), 1, statement); + statement.setInt(7, warp.index); + } + }); + } + + @Override + public void updatePrice(Warp warp) { + this.updateWarp(warp, "price", "UPDATE warps SET price = ? WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(Warp warp, PreparedStatement statement) throws SQLException { + statement.setDouble(1, warp.getPrice()); + statement.setInt(2, warp.index); + } + }); + } + + private void updateEditor(int id, String name, String typeMsg, EditorPermissions editorPerms, EditorPermissions.Type type, EditorPermissions.Table table) { + PreparedStatement ps = null; + ResultSet set = null; + try { + ps = this.connection.prepareStatement("DELETE FROM permissions WHERE id = ? AND editor = ? AND type = ? AND warpType = ?"); + ps.setInt(1, id); + ps.setString(2, name.toLowerCase()); + ps.setInt(3, type.id); + ps.setInt(4, table.id); + ps.executeUpdate(); + + if (editorPerms != null) { + ps = this.connection.prepareStatement("INSERT OR IGNORE INTO permissions (id, editor, value, type, warpType) VALUES (?,?,?,?,?)"); + + boolean permissionAdded = false; + + for (Editor perm : editorPerms.getByValue(true)) { + ps.setInt(1, id); + ps.setString(2, name.toLowerCase()); + ps.setInt(3, perm.getId()); + ps.setInt(4, type.id); + ps.setInt(5, table.id); + ps.addBatch(); + permissionAdded = true; + } + + if (permissionAdded) { + ps.executeBatch(); + } else { + ps.clearBatch(); + } + } + + this.connection.commit(); + } catch (SQLException ex) { + XWarp.logger.log(Level.SEVERE, typeMsg + " editor exception", ex); + } finally { + try { + if (ps != null) { + ps.close(); + } + if (set != null) { + set.close(); + } + } catch (SQLException ex) { + XWarp.logger.log(Level.SEVERE, typeMsg + " editor exception (on close)", ex); + } + } + } + + @Override + public void updateEditor(Warp warp, String name, EditorPermissions.Type type) { + this.updateEditor(warp.index, name, "Warp", warp.getEditorPermissions(name, false, type), type, EditorPermissions.Table.WARP); + } + + public static List processList(String permissions) { + String[] names = permissions.split(","); + List ret = new ArrayList(); + for (String name : names) { + if (name.equals("")) + continue; + ret.add(name.trim()); + } + return ret; + } + + public boolean load(File file) { + if (file.exists()) { + if (this.initFile(file)) { + this.update(); + return true; + } else { + return false; + } + } else { + return this.create(file); + } + } + + @Override + public String getFilename() { + return "warps.db"; + } + + @Override + public void clear() { + Statement statement = null; + ResultSet set = null; + try { + statement = this.connection.createStatement(); + statement.execute("DELETE FROM warps"); + statement.execute("DELETE FROM permissions"); + statement.execute("DELETE FROM protectionAreas"); + this.connection.commit(); + } catch (SQLException ex) { + XWarp.logger.log(Level.SEVERE, "Table Clear Exception", ex); + } finally { + try { + if (statement != null) { + statement.close(); + } + if (set != null) + set.close(); + } catch (SQLException ex) { + XWarp.logger.severe("Table Clear Exception (on closing)"); + } + } + } + + @Override + public boolean create(File file) { + this.initFile(file); + int version = this.getVersion(); + Statement statement = null; + ResultSet set = null; + try { + statement = this.connection.createStatement(); + // Drop warps → create new one + statement.execute("DROP TABLE IF EXISTS warps"); + statement.execute(WARP_TABLE); + // Drop permissions → create new one + statement.execute("DROP TABLE IF EXISTS permissions"); + statement.execute(PERMISSIONS_TABLE); + // Drop warp protection areas → create new one + statement.execute("DROP TABLE IF EXISTS protectionAreas"); + statement.execute(PROTECTION_AREA_TABLE); + if (version < 0) { + statement.executeUpdate("INSERT INTO meta (name, value) VALUES (\"version\", " + TARGET_VERSION + ")"); + } else { + statement.executeUpdate("UPDATE meta SET value = " + TARGET_VERSION + " WHERE name = \"version\""); + } + this.connection.commit(); + } catch (SQLException ex) { + XWarp.logger.log(Level.SEVERE, "Table Drop/Create Exception", ex); + return false; + } finally { + try { + if (statement != null) { + statement.close(); + } + if (set != null) + set.close(); + } catch (SQLException ex) { + XWarp.logger.severe("Table Drop/Create Exception (on closing)"); + return false; + } + } + return true; + } + + private static final class IdIdentification> implements IdentificationInterface { + + private final int id; + + public IdIdentification(int id) { + this.id = id; + } + + public static IdIdentification create(Warp warp) { + return new IdIdentification(warp.index); + } + + public static IdIdentification create(WarpProtectionArea wpa) { + return new IdIdentification(wpa.getId()); + } + + @Override + public boolean isIdentificated(T warpObject) { + Integer parameterId = getWarpObjectIndex(warpObject); + return parameterId != null && parameterId == this.id; + } + + } + + public static Integer getWarpObjectIndex(WarpObject o) { + if (o instanceof Warp) { + return ((Warp) o).index; + } else if (o instanceof WarpProtectionArea) { + return ((WarpProtectionArea) o).getId(); + } else { + return null; + } + } + + @Override + public IdentificationInterface createWarpIdentification(Warp warp) { + return IdIdentification.create(warp); + } + + private & Editor> Map>>> getEditorPermissions(EditorPermissions.Table table, Class clazz, Map idMap) { + Map>>> result = new HashMap>>>(); + Statement statement = null; + ResultSet set = null; + try { + statement = this.connection.createStatement(); + set = statement.executeQuery("SELECT * FROM permissions WHERE warpType = " + table.id); + Map>>> allPermissions = new HashMap>>>(); + while (set.next()) { + int index = set.getInt("id"); + Map>> warpPermissions = allPermissions.get(index); + if (warpPermissions == null) { + warpPermissions = new EnumMap>>(EditorPermissions.Type.class); + allPermissions.put(index, warpPermissions); + } + + EditorPermissions.Type type = EditorPermissions.Type.parseInt(set.getInt("type")); + Map> typePermissions = warpPermissions.get(type); + if (typePermissions == null) { + typePermissions = new HashMap>(); + warpPermissions.put(type, typePermissions); + } + + String editor = set.getString("editor"); + EditorPermissions editorPermissions = typePermissions.get(editor.toLowerCase()); + if (editorPermissions == null) { + editorPermissions = new EditorPermissions(clazz); + typePermissions.put(editor.toLowerCase(), editorPermissions); + } + int value = set.getInt("value"); + editorPermissions.put(idMap.get(value), true); + } + } catch (SQLException ex) { + XWarp.logger.severe("Permission database load exception", ex); + } finally { + try { + if (statement != null) + statement.close(); + if (set != null) + set.close(); + } catch (SQLException ex) { + XWarp.logger.severe("Permission database load exception (on close)"); + } + } + return result; + } + + @Override + public List getProtectionAreas() { + List result = new ArrayList(); + Statement statement = null; + ResultSet set = null; + try { + Map>>> allPermissions = this.getEditorPermissions(Table.PROTECTION_AREA, WarpProtectionAreaPermissions.class, WarpProtectionAreaPermissions.ID_MAP); + + statement = this.connection.createStatement(); + set = statement.executeQuery("SELECT * FROM protectionAreas"); + int size = 0; + int invalidSize = 0; + while (set.next()) { + size++; + int index = set.getInt("id"); + String name = set.getString("name"); + String creator = set.getString("creator"); + String owner = set.getString("owner"); + String worldName = set.getString("world"); + double x1 = set.getDouble("x1"); + double y1 = set.getDouble("y1"); + double z1 = set.getDouble("z1"); + double x2 = set.getDouble("x2"); + double y2 = set.getDouble("y2"); + double z2 = set.getDouble("z2"); + FixedLocation loc1 = new FixedLocation(x1, y1, z1); + FixedLocation loc2 = new FixedLocation(x2, y2, z2); + WorldWrapper worldWrapper = new WorldWrapper(worldName); + WarpProtectionArea wpa = new WarpProtectionArea(index, worldWrapper, loc1, loc2, name, owner, creator); + + Map>> wpaPermissions = allPermissions.get(index); + if (wpaPermissions != null) { + for (Entry>> typeEntry : wpaPermissions.entrySet()) { + for (Entry> editorEntry : typeEntry.getValue().entrySet()) { + wpa.getEditorPermissions(editorEntry.getKey(), true, typeEntry.getKey()).putAll(editorEntry.getValue()); + } + } + } + + result.add(wpa); + if (!wpa.isValid()) { + invalidSize++; + } + } + XWarp.logger.info(size + " warp protection areas loaded"); + if (invalidSize > 0) { + XWarp.logger.warning(invalidSize + " invalid warp protection areas found."); + } + } catch (SQLException ex) { + XWarp.logger.severe("Warp protection area load exception", ex); + } finally { + try { + if (statement != null) + statement.close(); + if (set != null) + set.close(); + } catch (SQLException ex) { + XWarp.logger.severe("Warp protection area load exception (on close)"); + } + } + return result; + } + + @Override + public void addProtectionArea(WarpProtectionArea... areas) { + if (areas.length > 0) { + PreparedStatement ps = null; + PreparedStatement insertPermissions = null; + try { + ps = this.connection.prepareStatement("INSERT INTO protectionAreas (id, name, owner, creator, world, x1, y1, z1, x2, y2, z2) VALUES (?,?,?,?,?,?,?,?,?,?,?)"); + insertPermissions = this.connection.prepareStatement("INSERT INTO permissions (id, editor, value, type, warpType) VALUES (?,?,?,?,?)"); + for (WarpProtectionArea area : areas) { + ps.setInt(1, area.getId()); + ps.setString(2, area.getName()); + ps.setString(3, area.getOwner()); + ps.setString(4, area.getCreator()); + ps.setString(5, area.getWorld()); + FixedLocation loc = area.getCorner(0); + ps.setDouble(6, loc.x); + ps.setDouble(7, loc.y); + ps.setDouble(8, loc.z); + loc = area.getCorner(1); + ps.setDouble(9, loc.x); + ps.setDouble(10, loc.y); + ps.setDouble(11, loc.z); + ps.addBatch(); + + for (EditorPermissionEntry editorPermissionEntry : area.getEditorPermissionsList()) { + for (WarpProtectionAreaPermissions p : editorPermissionEntry.editorPermissions.getByValue(true)) { + insertPermissions.setInt(1, area.getId()); + insertPermissions.setString(2, editorPermissionEntry.name); + insertPermissions.setInt(3, p.id); + insertPermissions.setInt(4, editorPermissionEntry.type.id); + insertPermissions.setInt(5, EditorPermissions.Table.PROTECTION_AREA.id); + insertPermissions.addBatch(); + } + } + } + ps.executeBatch(); + insertPermissions.executeBatch(); + + this.connection.commit(); + } catch (SQLException ex) { + XWarp.logger.log(Level.SEVERE, "Warp protection area insert exception", ex); + } finally { + try { + if (ps != null) { + ps.close(); + } + if (insertPermissions != null) { + insertPermissions.close(); + } + } catch (SQLException ex) { + XWarp.logger.log(Level.SEVERE, "Warp protection area insert exception (on close)", ex); + } + } + } + } + + @Override + public void deleteProtectionArea(WarpProtectionArea area) { + this.updateWarpObject(area, "Warp protection area", "delete", "DELETE FROM protectionAreas WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(WarpProtectionArea warp, PreparedStatement statement) throws SQLException { + statement.setInt(1, warp.getId()); + } + }); + } + + @Override + public void updateEditor(WarpProtectionArea area, String name, Type type) { + this.updateEditor(area.getId(), name, "Warp protection area", area.getEditorPermissions(name, false, type), type, EditorPermissions.Table.PROTECTION_AREA); + } + + @Override + public void updateCreator(WarpProtectionArea area) { + this.updateWarpObject(area, "Warp protection area", "creator", "UPDATE protectionAreas SET creator = ? WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(WarpProtectionArea warp, PreparedStatement statement) throws SQLException { + statement.setString(1, warp.getCreator()); + statement.setInt(2, warp.getId()); + } + }); + } + + @Override + public void updateOwner(WarpProtectionArea area, IdentificationInterface identification) { + this.updateWarpObject(area, "Warp protection area", "owner", "UPDATE protectionAreas SET owner = ? WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(WarpProtectionArea warp, PreparedStatement statement) throws SQLException { + statement.setString(1, warp.getOwner()); + statement.setInt(2, warp.getId()); + } + }); + } + + @Override + public void updateName(WarpProtectionArea area, IdentificationInterface identification) { + this.updateWarpObject(area, "Warp protection area", "name", "UPDATE protectionAreas SET name = ? WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(WarpProtectionArea warp, PreparedStatement statement) throws SQLException { + statement.setString(1, warp.getName()); + statement.setInt(2, warp.getId()); + } + }); + } + + @Override + public IdentificationInterface createWarpProtectionAreaIdentification(WarpProtectionArea area) { + return IdIdentification.create(area); + } + + @Override + public void updateCoolDown(Warp warp) { + this.updateWarp(warp, "name", "UPDATE warps SET cooldown = ? WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(Warp warp, PreparedStatement statement) throws SQLException { + statement.setInt(1, warp.getCoolDown()); + statement.setInt(2, warp.index); + } + }); + } + + @Override + public void updateWarmUp(Warp warp) { + this.updateWarp(warp, "name", "UPDATE warps SET warmup = ? WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(Warp warp, PreparedStatement statement) throws SQLException { + statement.setInt(1, warp.getWarmUp()); + statement.setInt(2, warp.index); + } + }); + } + + @Override + public void updateWorld(WarpProtectionArea area) { + this.updateWarpObject(area, "Warp protection area", "owner", "UPDATE protectionAreas SET world = ? WHERE id = ?", new UpdateFiller() { + + @Override + public void fillStatement(WarpProtectionArea warp, PreparedStatement statement) throws SQLException { + statement.setString(1, warp.getWorld()); + statement.setInt(2, warp.getId()); + } + }); + } +} diff --git a/src/main/java/de/xzise/xwarp/dataconnections/WarpProtectionConnection.java b/src/main/java/de/xzise/xwarp/dataconnections/WarpProtectionConnection.java new file mode 100644 index 0000000000..062dfb70ca --- /dev/null +++ b/src/main/java/de/xzise/xwarp/dataconnections/WarpProtectionConnection.java @@ -0,0 +1,23 @@ +package de.xzise.xwarp.dataconnections; + +import java.util.List; + +import de.xzise.xwarp.WarpProtectionArea; +import de.xzise.xwarp.editors.EditorPermissions; + +public interface WarpProtectionConnection extends DataConnection { + + IdentificationInterface createWarpProtectionAreaIdentification(WarpProtectionArea area); + + List getProtectionAreas(); + + void addProtectionArea(WarpProtectionArea... areas); + void deleteProtectionArea(WarpProtectionArea area); + + void updateEditor(WarpProtectionArea area, String name, EditorPermissions.Type type); + void updateCreator(WarpProtectionArea area); + void updateOwner(WarpProtectionArea area, IdentificationInterface identification); + void updateName(WarpProtectionArea area, IdentificationInterface identification); + + void updateWorld(WarpProtectionArea area); +} diff --git a/src/main/java/de/xzise/xwarp/dataconnections/YmlConnection.java b/src/main/java/de/xzise/xwarp/dataconnections/YmlConnection.java new file mode 100644 index 0000000000..2846e165fa --- /dev/null +++ b/src/main/java/de/xzise/xwarp/dataconnections/YmlConnection.java @@ -0,0 +1,657 @@ +package de.xzise.xwarp.dataconnections; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.MemorySection; +import org.bukkit.configuration.file.YamlConfiguration; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import de.xzise.bukkit.util.MemorySectionFromMap; +import de.xzise.bukkit.util.callback.Callback; +import de.xzise.metainterfaces.FixedLocation; +import de.xzise.metainterfaces.LocationWrapper; +import de.xzise.xwarp.DefaultWarpObject; +import de.xzise.xwarp.DefaultWarpObject.EditorPermissionEntry; +import de.xzise.xwarp.Warp; +import de.xzise.xwarp.WarpObject; +import de.xzise.xwarp.WarpProtectionArea; +import de.xzise.xwarp.WorldWrapper; +import de.xzise.xwarp.XWarp; +import de.xzise.xwarp.Warp.Visibility; +import de.xzise.xwarp.editors.Editor; +import de.xzise.xwarp.editors.EditorPermissions; +import de.xzise.xwarp.editors.EditorPermissions.Type; +import de.xzise.xwarp.editors.WarpPermissions; +import de.xzise.xwarp.editors.WarpProtectionAreaPermissions; + +public class YmlConnection implements WarpProtectionConnection { + + //@formatter:off + /* + * xwarp: + * version: 0 + * protectionareas: + * - name: 'foo' + * owner: 'xZise' + * creator: 'xZise' + * editors: + * - name: 'somebody' + * type: 'player' + * permissions: + * - 'overwrite' + * world: 'world' + * corners: + * - x: 0.0 + * y: 1.0 + * z: 0.0 + * - x: 10.0 + * y: 3.0 + * z: 10.0 + * warps: + * - name: 'foo' + * owner: 'xZise' + * creator: 'xZise' + * editors: + * - name: 'somebody' + * type: 'player' + * permissions: + * - 'location' + * - 'invite' + * x: 0.0 + * y: 65.0 + * z: -0.5 + * yaw: 0.0 + * pitch: 0.0 + * world: 'world' + * visibility: 'public' + * listed: 'true' + * price: 0.0 # < 0 → def + * cooldown: 0 # < 0 → def + * warmup: 0 # < 0 → def + * welcome: 'Welcome!' + * + */ + //@formatter:on + + private static final Callback NODE_TO_WARP = new Callback() { + @Override + public Warp call(MemorySection parameter) { + return getWarp(parameter); + } + }; + + private static final Callback NODE_TO_WPA = new Callback() { + + @Override + public WarpProtectionArea call(MemorySection parameter) { + return getWarpProtectionArea(parameter); + } + }; + + private static final String WARP_PATH = "xwarp.warps"; + private static final String WPA_PATH = "xwarp.protectionareas"; + + private YamlConfiguration config; + private File file; + + @Override + public boolean load(File file) { + this.file = file; + if (!file.exists()) { + this.clear(); + } + this.config = new YamlConfiguration(); + try { + this.config.load(file); + } catch (FileNotFoundException e) { + XWarp.logger.severe("Unable to load warps.yml as it doesn't exist.", e); + } catch (IOException e) { + XWarp.logger.severe("Unable to load warps.yml.", e); + } catch (InvalidConfigurationException e) { + XWarp.logger.severe("Unable to load warps.yml because the configuration seems to be invalid!", e); + } + return file.canWrite(); + } + + @Override + public boolean create(File file) { + if (this.load(file)) { + this.clear(); + return true; + } else { + return false; + } + } + + @Override + public void free() { + // TODO Auto-generated method stub + } + + @Override + public String getFilename() { + return "warps.yml"; + } + + @Override + public void clear() { + try { + FileWriter writer = new FileWriter(this.file); + try { + writer.write("xwarp:\n"); + writer.write(" version: 0\n"); + writer.write(" protectionareas: []\n"); + writer.write(" warps: []\n"); + } finally { + writer.close(); + } + } catch (IOException e) { + XWarp.logger.severe("Unable to write the file", e); + } + } + + public > IdentificationInterface createIdentification(T warp) { + return NameIdentification.create(warp); + } + + @Override + public IdentificationInterface createWarpIdentification(Warp warp) { + return NameIdentification.create(warp); + } + + public static Warp getWarp(MemorySection node) { + String name = node.getString("name"); + String owner = node.getString("owner"); + String creator = node.getString("creator"); + + List editorNodes = MemorySectionFromMap.getSectionList(node, "editors"); + Map>> allPermissions = getEditorPermissions(editorNodes, WarpPermissions.STRING_MAP, WarpPermissions.class); + + // Location: + Double x = getDouble(node, "x"); + Double y = getDouble(node, "y"); + Double z = getDouble(node, "z"); + Float yaw = getFloat(node, "yaw"); + Float pitch = getFloat(node, "pitch"); + String world = node.getString("world"); + World worldObject = Bukkit.getServer().getWorld(world); + + Visibility visibility = Visibility.parseString(node.getString("visibility")); + boolean listed = node.getBoolean("listed", true); + double price = node.getDouble("price", -1); + int cooldown = node.getInt("cooldown", -1); + int warmup = node.getInt("warmup", -1); + String welcomeMessage = node.getString("welcome"); + + Warp warp = new Warp(name, creator, owner, new LocationWrapper(new FixedLocation(worldObject, x, y, z, yaw, pitch), world)); + warp.setWelcomeMessage(welcomeMessage); + for (Entry>> typeEntry : allPermissions.entrySet()) { + for (Entry> editorEntry : typeEntry.getValue().entrySet()) { + warp.getEditorPermissions(editorEntry.getKey(), true, typeEntry.getKey()).putAll(editorEntry.getValue()); + } + } + warp.setVisibility(visibility); + warp.setListed(listed); + warp.setPrice(price); + warp.setCoolDown(cooldown); + warp.setWarmUp(warmup); + + return warp; + } + + @Override + public List getWarps() { + return getList(WARP_PATH, NODE_TO_WARP); + } + + public static Double getDouble(ConfigurationSection node, String path) { + if (node.isDouble(path)) { + return node.getDouble(path); + } else { + return null; + } + } + + public static Float getFloat(ConfigurationSection node, String path) { + Double d = getDouble(node, path); + if (d != null) { + return d.floatValue(); + } else { + return null; + } + } + + private static & Editor> Map warpObjectToMap(DefaultWarpObject object) { + Map map = Maps.newHashMap(); + map.put("name", object.getName()); + map.put("owner", object.getOwner()); + map.put("creator", object.getCreator()); + map.put("world", object.getWorld()); + Collection> editorPermissionEntries = object.getEditorPermissionsList(); + List> editorPermissionMaps = Lists.newArrayListWithCapacity(editorPermissionEntries.size()); + for (EditorPermissionEntry entry : editorPermissionEntries) { + editorPermissionMaps.add(editorPermissionToMap(entry.editorPermissions, entry.name, entry.type)); + } + map.put("editors", editorPermissionMaps); + return map; + } + + private static & Editor> List getPermissionsList(EditorPermissions editorPermissions) { + ImmutableSet perms = editorPermissions.getByValue(true); + List permNames = Lists.newArrayListWithCapacity(perms.size()); + for (T p : perms) { + permNames.add(p.getName()); + } + return permNames; + } + + private static & Editor> Map editorPermissionToMap(EditorPermissions perm, String name, EditorPermissions.Type type) { + Map map = Maps.newHashMap(); + map.put("name", name); + map.put("type", type.name); + map.put("permissions", getPermissionsList(perm)); + return map; + } + + @Override + public void addWarp(Warp... warps) { + List> rawNodes = this.config.getMapList(WARP_PATH); + + for (Warp warp : warps) { + Map warpMap = warpObjectToMap(warp); + fixedLocToMap(warpMap, warp.getLocation(), false, true); + warpMap.put("visibility", warp.getVisibility().name); + warpMap.put("listed", warp.isListed()); + warpMap.put("price", warp.getPrice()); + warpMap.put("cooldown", warp.getCoolDown()); + warpMap.put("warmup", warp.getWarmUp()); + String rawMessage = warp.getRawWelcomeMessage(); + if (rawMessage != null) { + warpMap.put("welcome", rawMessage); + } + rawNodes.add(warpMap); + } + + this.save(); + } + + private static Map nodeToMap(MemorySection node) { + Map map = new HashMap(); + for (String key : node.getKeys(false)) { + map.put(key, node.get(key)); + } + return map; + } + + public static boolean bool(Boolean b, boolean nullIsTrue) { + return b == null ? nullIsTrue : b; + } + + public static class WarpObjectCallback> implements Callback { + + public final IdentificationInterface id; + public final Callback warpObjectGetter; + + public WarpObjectCallback(IdentificationInterface id, Callback warpObjectGetter) { + this.id = id; + this.warpObjectGetter = warpObjectGetter; + } + + public static > WarpObjectCallback create(IdentificationInterface id, Callback warpObjectGetter) { + return new WarpObjectCallback(id, warpObjectGetter); + } + + @Override + public Boolean call(MemorySection parameter) { + return !this.id.isIdentificated(this.warpObjectGetter.call(parameter)); + } + + } + + public static void removeFromList(MemorySection node, String key, Callback callback) { + List nodes = MemorySectionFromMap.getSectionList(node, key); + List> mapList = Lists.newArrayListWithCapacity(Math.max(nodes.size() - 1, 0)); + for (MemorySection singleNode : nodes) { + Map a = nodeToMap(singleNode); + if (bool(callback.call(singleNode), false)) { + mapList.add(a); + } + } + node.set(key, mapList); + } + + @Override + public void deleteWarp(Warp warp) { + removeFromList(this.config, WARP_PATH, WarpObjectCallback.create(NameIdentification.create(warp), NODE_TO_WARP)); + this.save(); + } + + private > MemorySection getNode(IdentificationInterface id, String path, Callback nodeToWarpObject) { + List sections = MemorySectionFromMap.getSectionList(this.config, path); + for (MemorySection section : sections) { + T w = nodeToWarpObject.call(section); + if (id.isIdentificated(w)) + return section; + } + return null; + } + + private void save() { + try { + this.config.save(this.file); + } catch (IOException e) { + XWarp.logger.severe("Unable to save warps.yml file!", e); + } + } + + private MemorySection getWarpNode(IdentificationInterface id) { + return getNode(id, WARP_PATH, NODE_TO_WARP); + } + + private MemorySection getWarpProtectionAreaNode(IdentificationInterface id) { + return getNode(id, WPA_PATH, NODE_TO_WPA); + } + + private void updateField(ConfigurationSection node, String path, Object value) { + node.set(path, value); + this.save(); + } + + private void updateWarpField(IdentificationInterface id, String path, Object value) { + this.updateField(this.getWarpNode(id), path, value); + } + + private void updateWPAField(IdentificationInterface id, String path, Object value) { + this.updateField(this.getWarpProtectionAreaNode(id), path, value); + } + + private void updateWPAField(WarpProtectionArea area, String path, Object value) { + this.updateWPAField(NameIdentification.create(area), path, value); + } + + private void updateWarpField(Warp warp, String path, Object value) { + this.updateWarpField(NameIdentification.create(warp), path, value); + } + + @Override + public void updateCreator(Warp warp) { + this.updateWarpField(warp, "creator", warp.getCreator()); + } + + @Override + public void updateOwner(Warp warp, IdentificationInterface identification) { + this.updateWarpField(identification, "owner", warp.getOwner()); + } + + @Override + public void updateName(Warp warp, IdentificationInterface identification) { + this.updateWarpField(identification, "name", warp.getName()); + } + + @Override + public void updateMessage(Warp warp) { + this.updateWarpField(warp, "creator", warp.getRawWelcomeMessage()); + } + + @Override + public void updateVisibility(Warp warp) { + this.updateWarpField(warp, "creator", warp.getVisibility().name); + } + + @Override + public void updateLocation(Warp warp) { + ConfigurationSection node = getWarpNode(NameIdentification.create(warp)); + LocationWrapper locWrap = warp.getLocationWrapper(); + String world = locWrap.getWorld(); + FixedLocation loc = locWrap.getLocation(); + node.set("x", loc.x); + node.set("y", loc.y); + node.set("z", loc.z); + node.set("yaw", loc.yaw); + node.set("pitch", loc.pitch); + node.set("world", world); + this.save(); + } + + private & Editor> void updateEditor(MemorySection warpObjectNode, DefaultWarpObject warpObject, final String name, final EditorPermissions.Type type) { + + final Callback editorCheck = new Callback() { + @Override + public Boolean call(MemorySection parameter) { + String nodeName = parameter.getString("name"); + String nodeType = parameter.getString("type"); + return name.equalsIgnoreCase(nodeName) && type.equals(EditorPermissions.Type.parseName(nodeType)); + } + }; + + EditorPermissions perms = warpObject.getEditorPermissions(name, false, type); + if (perms == null) { + removeFromList(warpObjectNode, "editors", editorCheck); + } else { + boolean found = false; + List editorNodes = MemorySectionFromMap.getSectionList(warpObjectNode, "editors"); + List> rawEditorNodes = Lists.newArrayListWithExpectedSize(editorNodes.size()); + for (MemorySection editorNode : editorNodes) { + if (editorCheck.call(editorNode)) { + if (found) { + XWarp.logger.severe("Found at least two editor entries for name '" + name + "' and type '" + type + "'!"); + } else { + // Got it! + editorNode.set("permissions", getPermissionsList(perms)); + found = true; + } + } + rawEditorNodes.add(nodeToMap(editorNode)); + } + // Add entry + if (!found) { + rawEditorNodes.add(editorPermissionToMap(perms, name, type)); + } + warpObjectNode.set("editors", rawEditorNodes); + } + + this.save(); + } + + @Override + public void updateEditor(Warp warp, final String name, final EditorPermissions.Type type) { + MemorySection warpNode = getWarpNode(NameIdentification.create(warp)); + this.updateEditor(warpNode, warp, name, type); + } + + @Override + public void updatePrice(Warp warp) { + this.updateWarpField(warp, "creator", warp.getPrice()); + } + + private static & Editor> Map>> getEditorPermissions(List editorNodes, Map names, Class clazz) { + Map>> editorPermissions = Maps.newEnumMap(EditorPermissions.Type.class); + for (ConfigurationSection editorNode : editorNodes) { + String editorName = editorNode.getString("name"); + String editorType = editorNode.getString("type"); + + EditorPermissions permissions = EditorPermissions.create(clazz); + + List editorPermissionPermssions = editorNode.getStringList("permissions"); + if (editorPermissionPermssions != null) { + for (String editorPermission : editorPermissionPermssions) { + T perms = names.get(editorPermission.toLowerCase()); + + if (perms == null) { + // Unknown permission + } else { + permissions.put(perms, true); + } + } + } + + EditorPermissions.Type type = Type.parseName(editorType); + + if (type != null) { + Map> editor = editorPermissions.get(type); + if (editor == null) { + editor = Maps.newHashMap(); + editorPermissions.put(type, editor); + } + editor.put(editorName.toLowerCase(), permissions); + } + } + return editorPermissions; + } + + public static WarpProtectionArea getWarpProtectionArea(final MemorySection node) { + String name = node.getString("name"); + String owner = node.getString("owner"); + String creator = node.getString("creator"); + WorldWrapper worldObject = new WorldWrapper(node.getString("world")); + + List editorNodes = MemorySectionFromMap.getSectionList(node, "editors"); + Map>> editorPermissions = getEditorPermissions(editorNodes, WarpProtectionAreaPermissions.STRING_MAP, WarpProtectionAreaPermissions.class); + + // Corners: + List cornerNodes = MemorySectionFromMap.getSectionList(node, "corners"); + FixedLocation[] corners = new FixedLocation[cornerNodes.size()]; + + if (corners.length < 2) { + // At least two corners! + } else if (corners.length != 2) { + // As long as only cuboids are possible + } else { + int i = 0; + for (ConfigurationSection cornerNode : cornerNodes) { + Double x = getDouble(cornerNode, "x"); + Double y = getDouble(cornerNode, "y"); + Double z = getDouble(cornerNode, "z"); + if (x != null && y != null && z != null) { + corners[i++] = new FixedLocation(x, y, z); + } else { + // Invalid corner + } + } + } + + WarpProtectionArea warpProtectionArea = new WarpProtectionArea(worldObject, corners[0], corners[1], name, owner, creator); + for (Entry>> allPermissionsEntry : editorPermissions.entrySet()) { + for (Entry> editorEntry : allPermissionsEntry.getValue().entrySet()) { + warpProtectionArea.getEditorPermissions(editorEntry.getKey(), true, allPermissionsEntry.getKey()).putAll(editorEntry.getValue()); + } + } + + return warpProtectionArea; + } + + private List getList(String path, Callback converter) { + List sections = MemorySectionFromMap.getSectionList(this.config, path); + ArrayList result = new ArrayList(sections.size()); + for (MemorySection section : sections) { + T t = converter.call(section); + if (t != null) + result.add(t); + } + result.trimToSize(); + return result; + } + + @Override + public List getProtectionAreas() { + return getList(WPA_PATH, NODE_TO_WPA); + } + + private static void fixedLocToMap(Map locMap, FixedLocation location, boolean world, boolean direction) { + locMap.put("x", location.x); + locMap.put("y", location.y); + locMap.put("z", location.z); + if (direction) { + locMap.put("yaw", location.yaw); + locMap.put("pitch", location.pitch); + } + if (world) { + locMap.put("world", location.world.getName()); + } + } + + private static Map fixedLocToMap(FixedLocation location, boolean world, boolean direction) { + Map locMap = Maps.newHashMap(); + fixedLocToMap(locMap, location, world, direction); + return locMap; + } + + @Override + public void addProtectionArea(WarpProtectionArea... areas) { + List> rawNodes = this.config.getMapList(WPA_PATH); + + for (WarpProtectionArea wpa : areas) { + Map wpaMap = warpObjectToMap(wpa); + List> corners = Lists.newArrayListWithCapacity(2); + corners.add(fixedLocToMap(wpa.getCorner(0), false, false)); + corners.add(fixedLocToMap(wpa.getCorner(1), false, false)); + wpaMap.put("corners", corners); + rawNodes.add(wpaMap); + } + this.save(); + } + + @Override + public void deleteProtectionArea(WarpProtectionArea area) { + removeFromList(this.config, WPA_PATH, WarpObjectCallback.create(NameIdentification.create(area), NODE_TO_WPA)); + this.save(); + } + + @Override + public void updateEditor(WarpProtectionArea warp, String name, Type type) { + MemorySection warpNode = getWarpProtectionAreaNode(NameIdentification.create(warp)); + this.updateEditor(warpNode, warp, name, type); + } + + @Override + public void updateCreator(WarpProtectionArea area) { + this.updateWPAField(NameIdentification.create(area), "creator", area.getCreator()); + } + + @Override + public void updateOwner(WarpProtectionArea warp, IdentificationInterface identification) { + this.updateWPAField(identification, "owner", warp.getOwner()); + } + + @Override + public void updateName(WarpProtectionArea warp, IdentificationInterface identification) { + this.updateWPAField(identification, "name", warp.getName()); + } + + @Override + public void updateWorld(WarpProtectionArea area) { + this.updateWPAField(area, "world", area.getWorld()); + } + + @Override + public IdentificationInterface createWarpProtectionAreaIdentification(WarpProtectionArea area) { + return NameIdentification.create(area); + } + + @Override + public void updateCoolDown(Warp warp) { + this.updateWarpField(warp, "cooldown", warp.getCoolDown()); + } + + @Override + public void updateWarmUp(Warp warp) { + this.updateWarpField(warp, "warmup", warp.getWarmUp()); + } + +} diff --git a/src/main/java/de/xzise/xwarp/editors/Editor.java b/src/main/java/de/xzise/xwarp/editors/Editor.java new file mode 100644 index 0000000000..e9bf208efd --- /dev/null +++ b/src/main/java/de/xzise/xwarp/editors/Editor.java @@ -0,0 +1,17 @@ +package de.xzise.xwarp.editors; + +import de.xzise.wrappers.permissions.Permission; + +public interface Editor { + + String getName(); + + char getValue(); + + int getId(); + + Permission getDefault(); + + Permission getAdmin(); + +} diff --git a/src/main/java/de/xzise/xwarp/editors/EditorPermissionUtil.java b/src/main/java/de/xzise/xwarp/editors/EditorPermissionUtil.java new file mode 100644 index 0000000000..4d84ce17a3 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/editors/EditorPermissionUtil.java @@ -0,0 +1,89 @@ +package de.xzise.xwarp.editors; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Map; +import java.util.Set; + +import com.google.common.collect.ImmutableMap.Builder; +import com.google.common.collect.ImmutableSet; + +import de.xzise.bukkit.util.callback.Callback; + +public class EditorPermissionUtil { + + private EditorPermissionUtil() {} + + public final static Callback VALUE_CALLBACK = new Callback() { + + @Override + public Character call(Editor parameter) { + return parameter.getValue(); + } + }; + + public final static Callback ID_CALLBACK = new Callback() { + + @Override + public Integer call(Editor parameter) { + return parameter.getId(); + } + }; + + public final static Callback NAME_CALLBACK = new Callback() { + + @Override + public String call(Editor parameter) { + return parameter.getName(); + } + }; + + public static > com.google.common.collect.ImmutableMap createEnumMap(Class enumClass, Callback keys) { + Builder builder = com.google.common.collect.ImmutableMap.builder(); + for (V enumValue : enumClass.getEnumConstants()) { + builder.put(keys.call(enumValue), enumValue); + } + return builder.build(); + } + + public static & Editor> ImmutableSet parseString(String permissions, Class clazz, Set def, Map charMap) { + Set result = EnumSet.noneOf(clazz); + parseString(permissions, result, clazz.getEnumConstants(), def, charMap); + return ImmutableSet.copyOf(result); + } + + public static void parseString(String permissions, Set result, T[] all, Set def, Map charMap) { + result.clear(); + boolean remove = false; + + for (char c : permissions.toLowerCase().toCharArray()) { + if (c == '/') { + remove = true; + } else if (c == '*') { + if (remove) { + result.removeAll(Arrays.asList(all)); + } else { + result.addAll(Arrays.asList(all)); + } + } else if (c == 's') { + if (remove) { + result.removeAll(def); + } else { + result.addAll(def); + } + } else { + T e = charMap.get(c); + if (e != null) { + if (remove) { + result.remove(e); + } else { + result.add(e); + } + } else { + // TODO: How to react? + } + } + } + } + +} diff --git a/src/main/java/de/xzise/xwarp/editors/EditorPermissions.java b/src/main/java/de/xzise/xwarp/editors/EditorPermissions.java new file mode 100644 index 0000000000..fcd4913e44 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/editors/EditorPermissions.java @@ -0,0 +1,136 @@ +package de.xzise.xwarp.editors; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import com.google.common.collect.ImmutableSet.Builder; + +import de.xzise.MinecraftUtil; +import de.xzise.bukkit.util.callback.Callback; + +public class EditorPermissions & Editor> { + + public enum Type { + PLAYER(0, "player"), GROUP(1, "group"), PERMISSIONS(2, "permission"); + + private static final Map TYPES = new HashMap(); + private static final Map NAMES = MinecraftUtil.createReverseEnumMap(Type.class, new Callback() { + @Override + public String call(Type parameter) { + return parameter.name.toLowerCase(); + } + }); + + public static final Callback NAMES_CALLBACK = new Callback() { + + @Override + public Type call(String parameter) { + return parseName(parameter); + } + }; + + static { + for (Type type : Type.values()) { + TYPES.put(type.id, type); + } + } + + public final int id; + public final String name; + + private Type(int id, String name) { + this.id = id; + this.name = name; + } + + public static Type parseInt(int id) { + return TYPES.get(id); + } + + public static Type parseName(String name) { + return NAMES.get(name.toLowerCase()); + } + } + + public enum Table { + WARP(0), PROTECTION_AREA(1); + + private static final Map TYPES = new HashMap(); + + static { + for (Type type : Type.values()) { + TYPES.put(type.id, type); + } + } + + public final int id; + + private Table(int id) { + this.id = id; + } + + public static Type parseInt(int id) { + return TYPES.get(id); + } + } + + private final Map permissions; + + public EditorPermissions(Class clazz) { + this.permissions = Maps.newEnumMap(clazz); + } + + public static & Editor> EditorPermissions create(Class clazz) { + return new EditorPermissions(clazz); + } + + public String getPermissionString() { + ImmutableSet pms = this.getByValue(true); + char[] editorPermissions = new char[pms.size()]; + int i = 0; + for (T t : pms) { + editorPermissions[i++] = t.getValue(); + } + return new String(editorPermissions); + } + + public ImmutableSet getByValue(boolean value) { + Builder builder = ImmutableSet.builder(); + for (Map.Entry entry : this.permissions.entrySet()) { + if ((entry.getValue() == null && !value) || (value == entry.getValue())) { + builder.add(entry.getKey()); + } + } + return builder.build(); + } + + public boolean get(T permission) { + Boolean bool = this.permissions.get(permission); + return bool == null ? false : bool; + } + + public boolean put(T key, boolean value) { + Boolean bool = this.permissions.put(key, value); + return bool == null ? false : bool; + } + + public Boolean remove(T key) { + return this.put(key, false); + } + + public void putAll(EditorPermissions p) { + this.permissions.putAll(p.permissions); + } + + public void putSet(Set permissions, boolean reset) { + if (reset) { + this.permissions.clear(); + } + for (T permission : permissions) { + this.put(permission, true); + } + } +} diff --git a/src/main/java/de/xzise/xwarp/editors/WarpPermissions.java b/src/main/java/de/xzise/xwarp/editors/WarpPermissions.java new file mode 100644 index 0000000000..c27d1e8ba7 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/editors/WarpPermissions.java @@ -0,0 +1,81 @@ +package de.xzise.xwarp.editors; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +import de.xzise.xwarp.wrappers.permission.PermissionTypes; + +public enum WarpPermissions implements Editor { + UPDATE('l', 0, "update", PermissionTypes.ADMIN_UPDATE, PermissionTypes.EDIT_LOCATION), + RENAME('r', 1, "rename", PermissionTypes.ADMIN_RENAME, PermissionTypes.EDIT_RENAME), + UNINVITE('u', 2, "uninvite", PermissionTypes.ADMIN_UNINVITE, PermissionTypes.EDIT_UNINVITE), + INVITE('i', 3, "invite", PermissionTypes.ADMIN_INVITE, PermissionTypes.EDIT_INVITE), + PRIVATE('0', 4, "private", PermissionTypes.ADMIN_PRIVATE, PermissionTypes.CREATE_PRIVATE), + PUBLIC('1', 5, "public", PermissionTypes.ADMIN_PUBLIC, PermissionTypes.CREATE_PUBLIC), + GLOBAL('2', 6, "global", PermissionTypes.ADMIN_GLOBAL, PermissionTypes.CREATE_GLOBAL), + GIVE('g', 7, "give", PermissionTypes.ADMIN_CHANGE_OWNER, PermissionTypes.EDIT_CHANGE_OWNER), + DELETE('d', 8, "delete", PermissionTypes.ADMIN_DELETE, PermissionTypes.EDIT_DELETE), + WARP('w', 9, "warp", PermissionTypes.ADMIN_TO_ALL, null), + ADD_EDITOR('a', 10, "add editor", PermissionTypes.ADMIN_EDITORS_ADD, PermissionTypes.EDIT_EDITORS_ADD), + REMOVE_EDITOR('f', 11, "remove editor", PermissionTypes.ADMIN_EDITORS_REMOVE, PermissionTypes.EDIT_EDITORS_REMOVE), + MESSAGE('m', 12, "message", PermissionTypes.ADMIN_MESSAGE, PermissionTypes.EDIT_MESSAGE), + PRICE('p', 13, "price", PermissionTypes.ADMIN_PRICE, PermissionTypes.EDIT_PRICE), + FREE('c', 14, "free", PermissionTypes.ADMIN_FREE, PermissionTypes.EDIT_FREE), + LIST('v', 15, "list", PermissionTypes.ADMIN_LIST_CHANGE, PermissionTypes.EDIT_LIST), + COOLDOWN('t', 16, "cooldown", PermissionTypes.ADMIN_COOLDOWN, PermissionTypes.EDIT_COOLDOWN), // t as time (-.-) + WARMUP('b', 17, "warmup", PermissionTypes.ADMIN_WARMUP, PermissionTypes.EDIT_WARMUP), // b as "before" + + ; + + public final char value; + public final int id; + public final String name; + public final PermissionTypes adminPermission; + public final PermissionTypes defaultPermission; + + public static final ImmutableSet DEFAULT; + public static final ImmutableMap CHARACTER_MAP = EditorPermissionUtil.createEnumMap(WarpPermissions.class, EditorPermissionUtil.VALUE_CALLBACK); + public static final ImmutableMap ID_MAP = EditorPermissionUtil.createEnumMap(WarpPermissions.class, EditorPermissionUtil.ID_CALLBACK); + public static final ImmutableMap STRING_MAP = EditorPermissionUtil.createEnumMap(WarpPermissions.class, EditorPermissionUtil.NAME_CALLBACK); + + private WarpPermissions(char value, int id, String name, PermissionTypes adminPermission, PermissionTypes defaultPermission) { + this.value = value; + this.id = id; + this.name = name; + this.adminPermission = adminPermission; + this.defaultPermission = defaultPermission; + } + + static { + DEFAULT = ImmutableSet.of(UPDATE, RENAME, UNINVITE, INVITE, WARP); + } + + public static ImmutableSet parseString(String permissions) { + return EditorPermissionUtil.parseString(permissions, WarpPermissions.class, DEFAULT, CHARACTER_MAP); + } + + @Override + public PermissionTypes getDefault() { + return this.defaultPermission; + } + + @Override + public PermissionTypes getAdmin() { + return this.adminPermission; + } + + @Override + public char getValue() { + return this.value; + } + + @Override + public int getId() { + return this.id; + } + + @Override + public String getName() { + return this.name; + } +} diff --git a/src/main/java/de/xzise/xwarp/editors/WarpProtectionAreaPermissions.java b/src/main/java/de/xzise/xwarp/editors/WarpProtectionAreaPermissions.java new file mode 100644 index 0000000000..18ab899269 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/editors/WarpProtectionAreaPermissions.java @@ -0,0 +1,72 @@ +package de.xzise.xwarp.editors; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +import de.xzise.xwarp.wrappers.permission.WPAPermissions; + +public enum WarpProtectionAreaPermissions implements Editor { + RENAME('m', 1, "rename", WPAPermissions.ADMIN_RENAME, WPAPermissions.EDIT_RENAME), + UNINVITE('u', 2, "uninvite", WPAPermissions.ADMIN_UNINVITE, WPAPermissions.EDIT_UNINVITE), + INVITE('i', 3, "invite", WPAPermissions.ADMIN_INVITE, WPAPermissions.EDIT_INVITE), + GIVE('g', 7, "give", WPAPermissions.ADMIN_CHANGE_OWNER, WPAPermissions.EDIT_CHANGE_OWNER), + DELETE('d', 8, "delete", WPAPermissions.ADMIN_DELETE, WPAPermissions.EDIT_DELETE), + OVERWRITE('o', 9, "overwrite", WPAPermissions.ADMIN_IGNORE_PROTECTION_AREA, null), + ADD_EDITOR('a', 10, "add editor", WPAPermissions.ADMIN_EDITORS_ADD, WPAPermissions.EDIT_EDITORS_ADD), + REMOVE_EDITOR('r', 11, "remove editor", WPAPermissions.ADMIN_EDITORS_REMOVE, WPAPermissions.EDIT_EDITORS_REMOVE), + LIST('v', 15, "list", WPAPermissions.ADMIN_LIST_CHANGE, WPAPermissions.EDIT_LIST), + + ; + + public final char value; + public final int id; + public final String name; + public final WPAPermissions adminPermission; + public final WPAPermissions defaultPermission; + + public static final ImmutableSet DEFAULT; + public static final ImmutableMap CHARACTER_MAP = EditorPermissionUtil.createEnumMap(WarpProtectionAreaPermissions.class, EditorPermissionUtil.VALUE_CALLBACK); + public static final ImmutableMap ID_MAP = EditorPermissionUtil.createEnumMap(WarpProtectionAreaPermissions.class, EditorPermissionUtil.ID_CALLBACK); + public static final ImmutableMap STRING_MAP = EditorPermissionUtil.createEnumMap(WarpProtectionAreaPermissions.class, EditorPermissionUtil.NAME_CALLBACK); + + private WarpProtectionAreaPermissions(char value, int id, String name, WPAPermissions adminPermission, WPAPermissions defaultPermission) { + this.value = value; + this.id = id; + this.name = name; + this.adminPermission = adminPermission; + this.defaultPermission = defaultPermission; + } + + static { + DEFAULT = ImmutableSet.of(RENAME, UNINVITE, INVITE, OVERWRITE); + } + + public static ImmutableSet parseString(String permissions) { + return EditorPermissionUtil.parseString(permissions, WarpProtectionAreaPermissions.class, DEFAULT, CHARACTER_MAP); + } + + @Override + public WPAPermissions getDefault() { + return this.defaultPermission; + } + + @Override + public WPAPermissions getAdmin() { + return this.adminPermission; + } + + @Override + public char getValue() { + return this.value; + } + + @Override + public int getId() { + return this.id; + } + + @Override + public String getName() { + return this.name; + } +} diff --git a/src/main/java/de/xzise/xwarp/list/GlobalMap.java b/src/main/java/de/xzise/xwarp/list/GlobalMap.java new file mode 100644 index 0000000000..3413a47728 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/list/GlobalMap.java @@ -0,0 +1,41 @@ +package de.xzise.xwarp.list; + +import java.util.HashMap; +import java.util.Map; + +import de.xzise.xwarp.WarpObject; + +public class GlobalMap> { + + private final Map all = new HashMap(); + + public void put(T warpObject) { + this.all.put(warpObject.getOwner().toLowerCase(), warpObject); + } + + public void delete(T warp) { + this.all.remove(warp.getOwner().toLowerCase()); + } + + public T getWarpObject(String playerName) { + if (this.all.size() == 1) { + return this.all.values().iterator().next(); + } else if (playerName != null && !playerName.isEmpty()) { + return this.all.get(playerName.toLowerCase()); + } else { + return null; + } + } + + public void clear() { + this.all.clear(); + } + + public int size() { + return this.all.size(); + } + + public boolean isAmbiguous() { + return this.size() > 1; + } +} \ No newline at end of file diff --git a/src/main/java/de/xzise/xwarp/list/NonGlobalList.java b/src/main/java/de/xzise/xwarp/list/NonGlobalList.java new file mode 100644 index 0000000000..aae3095918 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/list/NonGlobalList.java @@ -0,0 +1,12 @@ +package de.xzise.xwarp.list; + +import de.xzise.xwarp.WarpObject; + +public class NonGlobalList> extends PersonalList> { + + @Override + protected GlobalMap createGlobalMap() { + return new GlobalMap(); + } + +} diff --git a/src/main/java/de/xzise/xwarp/list/PersonalList.java b/src/main/java/de/xzise/xwarp/list/PersonalList.java new file mode 100644 index 0000000000..bd1f28f94d --- /dev/null +++ b/src/main/java/de/xzise/xwarp/list/PersonalList.java @@ -0,0 +1,221 @@ +package de.xzise.xwarp.list; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.command.CommandSender; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSet.Builder; + +import de.xzise.MinecraftUtil; +import de.xzise.xwarp.WarpObject; + +public abstract class PersonalList, G extends GlobalMap> { + + // WarpObjects sorted by owner, name + private final Map> personalMap = new HashMap>(); + // Warps sorted by creator + private final Map> creatorMap = new HashMap>(); + // Warps sorted by name + private final Map nameMap = new HashMap(); + + private boolean ignoreCase; + + public void loadList(Collection warpObjects) { + for (Map personalWarps : this.personalMap.values()) { + personalWarps.clear(); + } + for (List creatorWarps : this.creatorMap.values()) { + creatorWarps.clear(); + } + for (GlobalMap globalWarps : this.nameMap.values()) { + globalWarps.clear(); + } + + // Load elements here + for (T warpObject : warpObjects) { + this.addWarpObject(warpObject); + } + } + + protected abstract G createGlobalMap(); + + public void addWarpObject(T warpObject) { + Map personalWarps = this.personalMap.get(warpObject.getOwner().toLowerCase()); + if (personalWarps == null) { + personalWarps = new HashMap(); + this.personalMap.put(warpObject.getOwner().toLowerCase(), personalWarps); + } + personalWarps.put(warpObject.getName().toLowerCase(), warpObject); + + if (MinecraftUtil.isSet(warpObject.getCreator())) { + List creatorWarps = this.creatorMap.get(warpObject.getCreator().toLowerCase()); + if (creatorWarps == null) { + creatorWarps = new ArrayList(); + this.creatorMap.put(warpObject.getCreator().toLowerCase(), creatorWarps); + } + creatorWarps.add(warpObject); + } + + G namedWarps = this.nameMap.get(warpObject.getName().toLowerCase()); + if (namedWarps == null) { + namedWarps = this.createGlobalMap(); + this.nameMap.put(warpObject.getName().toLowerCase(), namedWarps); + } + namedWarps.put(warpObject); + } + + public void deleteWarpObject(T warp) { + if (MinecraftUtil.isSet(warp.getCreator())) { + this.creatorMap.get(warp.getCreator().toLowerCase()).remove(warp); + } + this.personalMap.get(warp.getOwner().toLowerCase()).remove(warp.getName().toLowerCase()); + this.nameMap.get(warp.getName().toLowerCase()).delete(warp); + } + + public void updateOwner(T warp, String preOwner) { + this.personalMap.get(preOwner.toLowerCase()).remove(warp.getName().toLowerCase()); + Map personalWarps = this.personalMap.get(warp.getOwner().toLowerCase()); + if (personalWarps == null) { + personalWarps = new HashMap(); + this.personalMap.put(warp.getOwner().toLowerCase(), personalWarps); + } + personalWarps.put(warp.getName().toLowerCase(), warp); + } + + /** + * Returns the number of warps a player has created. + * + * @param creator + * The creator of the warps. Has to be not null. + * @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). + */ + public int getNumberOfWarps(String creator, String world) { + int number = 0; + if (MinecraftUtil.isSet(creator)) { + List warpObjects = this.creatorMap.get(creator.toLowerCase()); + if (warpObjects != null) { + for (T warpObject : warpObjects) { + if (world == null || warpObject.getWorld().equals(world)) { + number++; + } + } + } + } + return number; + } + + public T getWarpObject(String name, String owner, String playerName) { + T warpObject = null; + if (MinecraftUtil.isSet(owner)) { + Map ownerWarps = this.personalMap.get(owner.toLowerCase()); + if (ownerWarps != null) { + warpObject = ownerWarps.get(name.toLowerCase()); + } + } else { + GlobalMap namedWarps = this.nameMap.get(name.toLowerCase()); + if (namedWarps != null) { + warpObject = namedWarps.getWarpObject(playerName); + } + } + if (warpObject != null && (this.ignoreCase || (warpObject.getName().equals(name) && (!MinecraftUtil.isSet(owner) || warpObject.getOwner().equals(owner))))) { + return warpObject; + } else { + return null; + } + } + + public T getWarpObject(String name) { + return this.getWarpObject(name, null, null); + } + + public boolean isAmbiguous(final String warpName) { + final G namedWarps = this.getByName(warpName); + return namedWarps != null && namedWarps.isAmbiguous(); + } + + public int getNumberOfWarpsByName(final String warpName) { + final G namedWarps = this.getByName(warpName); + return namedWarps == null ? 0 : namedWarps.size(); + } + + public ImmutableSet getWarpObjects() { + Builder builder = ImmutableSet.builder(); + for (Map map : this.personalMap.values()) { + builder.addAll(map.values()); + } + return builder.build(); + } + + public List getWarps(String owner) { + Map personalWarps = this.personalMap.get(owner.toLowerCase()); + if (personalWarps != null) { + return new ArrayList(personalWarps.values()); + } else { + return new ArrayList(0); + } + } + + /** + * Returns the number of warps the player can modify/use. + * + * @param sender + * The given player. + * @return The number of warps the player can modify/use. + */ + public int getSize(CommandSender sender) { + int size = 0; + for (Map map : this.personalMap.values()) { + size += this.getSize(sender, map); + } + return size; + } + + public int getSize(CommandSender sender, String creator) { + if (creator == null || creator.isEmpty()) { + return this.getSize(sender); + } else { + Map map = this.personalMap.get(creator.toLowerCase()); + return map == null ? 0 : this.getSize(sender, map); + } + } + + private int getSize(CommandSender sender, Map map) { + if (sender == null) { + return map.size(); + } else { + int size = 0; + for (T warp : map.values()) { + if (warp.isListed(sender)) { + size++; + } + } + return size; + } + } + + protected List getByCreator(String name) { + return this.creatorMap.get(name.toLowerCase()); + } + + protected G getByName(String name) { + return this.nameMap.get(name.toLowerCase()); + } + + public boolean isIgnoreCase() { + return this.ignoreCase; + } + + public void setIgnoreCase(boolean ignoreCase) { + this.ignoreCase = ignoreCase; + } + +} diff --git a/src/main/java/de/xzise/xwarp/list/WarpGlobalMap.java b/src/main/java/de/xzise/xwarp/list/WarpGlobalMap.java new file mode 100644 index 0000000000..e25524408a --- /dev/null +++ b/src/main/java/de/xzise/xwarp/list/WarpGlobalMap.java @@ -0,0 +1,53 @@ +package de.xzise.xwarp.list; + +import de.xzise.xwarp.Warp; +import de.xzise.xwarp.Warp.Visibility; + +class WarpGlobalMap extends GlobalMap { + + private T global = null; + + @Override + public void put(T warpObject) { + if (warpObject.getVisibility() == Visibility.GLOBAL) { + this.global = warpObject; + } + super.put(warpObject); + } + + @Override + public void delete(T warp) { + if (warp.equals(this.global)) { + this.global = null; + } + super.delete(warp); + } + + @Override + public T getWarpObject(String playerName) { + if (this.global != null) { + return this.global; + } + + return super.getWarpObject(playerName); + } + + public void updateGlobal(T warpObject) { + if (this.global == null && warpObject.getVisibility() == Visibility.GLOBAL) { + this.global = warpObject; + } else if (warpObject.equals(this.global) && warpObject.getVisibility() != Visibility.GLOBAL) { + this.global = null; + } + } + + @Override + public void clear() { + super.clear(); + this.global = null; + } + + @Override + public boolean isAmbiguous() { + return !(this.global != null || !super.isAmbiguous()); + } +} \ No newline at end of file diff --git a/src/main/java/de/xzise/xwarp/list/WarpList.java b/src/main/java/de/xzise/xwarp/list/WarpList.java new file mode 100644 index 0000000000..eca9e9c488 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/list/WarpList.java @@ -0,0 +1,49 @@ +package de.xzise.xwarp.list; + +import java.util.List; + +import de.xzise.MinecraftUtil; +import de.xzise.xwarp.Warp; +import de.xzise.xwarp.Warp.Visibility; + + +public class WarpList extends PersonalList> { + + @Override + protected WarpGlobalMap createGlobalMap() { + return new WarpGlobalMap(); + } + + /** + * 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 + * visibilities. + * @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). + */ + public int getNumberOfWarps(String creator, Visibility visibility, String world) { + int number = 0; + if (MinecraftUtil.isSet(creator)) { + List warpObjects = this.getByCreator(creator); + if (warpObjects != null) { + for (T warpObject : warpObjects) { + if ((visibility == null || warpObject.getVisibility() == visibility) && (world == null || warpObject.getWorld().equals(world))) { + number++; + } + } + } + } + return number; + } + + public void updateVisibility(T warp) { + this.getByName(warp.getName()).updateGlobal(warp); + } +} diff --git a/src/main/java/de/xzise/xwarp/listeners/XWBlockListener.java b/src/main/java/de/xzise/xwarp/listeners/XWBlockListener.java new file mode 100644 index 0000000000..fb7a42d35a --- /dev/null +++ b/src/main/java/de/xzise/xwarp/listeners/XWBlockListener.java @@ -0,0 +1,72 @@ +package de.xzise.xwarp.listeners; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.inventory.ItemStack; + +import de.xzise.MinecraftUtil; +import de.xzise.xwarp.Warp; +import de.xzise.xwarp.WarpDestination; +import de.xzise.xwarp.WarpManager; +import de.xzise.xwarp.XWarp; +import de.xzise.xwarp.signwarps.SignWarp; +import de.xzise.xwarp.wrappers.permission.Groups; +import de.xzise.xwarp.wrappers.permission.PermissionTypes; + +public class XWBlockListener implements Listener { + + private final WarpManager manager; + + public XWBlockListener(WarpManager manager) { + this.manager = manager; + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onSignChange(SignChangeEvent event) { + Block block = event.getBlock(); + if (block.getState() instanceof Sign && !event.isCancelled() && event.getPlayer() != null) { + WarpDestination destination = SignWarp.getDestination(SignWarp.getFilledLines(event.getLines()), event.getPlayer()); + if (destination != null) { + Warp warp = this.manager.getWarpObject(destination.name, destination.owner, null); + PermissionTypes type = null; + if (warp == null) { + type = PermissionTypes.SIGN_CREATE_UNKNOWN; + } else { + type = Groups.SIGN_CREATE_GROUP.get(warp.getVisibility()); + } + if (XWarp.permissions.permission(event.getPlayer(), type)) { + String line = "Warp sign found: "; + if (warp == null) { + String creator = ""; + if (MinecraftUtil.isSet(destination.owner)) { + creator = " by " + ChatColor.GREEN + destination.owner; + } else { + creator = " (global)"; + } + line += ChatColor.GREEN + destination.name + ChatColor.WHITE + creator; + } else { + line += ChatColor.GREEN + warp.getName() + ChatColor.WHITE + " by " + ChatColor.GREEN + warp.getOwner(); + } + + event.getPlayer().sendMessage(line); + if (warp == null) { + event.getPlayer().sendMessage(ChatColor.RED + "This warp doesn't exists!"); + } + } else { + // Return sign + event.getPlayer().sendMessage(ChatColor.RED + "You have no permission to create a warp sign."); + + event.setCancelled(true); + block.getWorld().dropItem(block.getLocation(), new ItemStack(Material.SIGN, 1)); + block.setTypeId(0); + } + } + } + } +} diff --git a/src/main/java/de/xzise/xwarp/listeners/XWEntityListener.java b/src/main/java/de/xzise/xwarp/listeners/XWEntityListener.java new file mode 100644 index 0000000000..6d6082afc4 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/listeners/XWEntityListener.java @@ -0,0 +1,34 @@ +package de.xzise.xwarp.listeners; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; + +import de.xzise.xwarp.PluginProperties; +import de.xzise.xwarp.timer.WarmUp; + +public class XWEntityListener implements Listener { + + private final PluginProperties properties; + private final WarmUp warmUp; + + public XWEntityListener(PluginProperties properties, WarmUp warmUp) { + this.properties = properties; + this.warmUp = warmUp; + } + + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onEntityDamage(EntityDamageEvent event) { + if (!event.isCancelled() && this.properties.isCancelWarmUpOnDamage()) { + if (event.getEntity() instanceof Player) { + if (this.warmUp.cancelWarmUp((Player) event.getEntity())) { + ((Player) event.getEntity()).sendMessage(ChatColor.RED + "WarmUp was canceled due to damage!"); + } + } + } + } +} diff --git a/src/main/java/de/xzise/xwarp/listeners/XWPlayerListener.java b/src/main/java/de/xzise/xwarp/listeners/XWPlayerListener.java new file mode 100644 index 0000000000..22139d4593 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/listeners/XWPlayerListener.java @@ -0,0 +1,65 @@ +package de.xzise.xwarp.listeners; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.Event.Result; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.inventory.ItemStack; + +import de.xzise.metainterfaces.FixedLocation; +import de.xzise.xwarp.PluginProperties; +import de.xzise.xwarp.WarpManager; +import de.xzise.xwarp.commands.wpa.CreateCommand; +import de.xzise.xwarp.signwarps.SignWarp; + +public class XWPlayerListener implements Listener { + + private final WarpManager manager; + private final PluginProperties properties; + private final CreateCommand createCommand; + + public XWPlayerListener(WarpManager manager, PluginProperties properties, CreateCommand createCommand) { + this.manager = manager; + this.properties = properties; + this.createCommand = createCommand; + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPlayerInteract(PlayerInteractEvent event) { + Block block = event.getClickedBlock(); + Player player = event.getPlayer(); + if (block != null && !event.isCancelled()) { + if (event.getAction() == Action.RIGHT_CLICK_BLOCK && block.getState() instanceof Sign) { + SignWarp signWarp = new SignWarp((Sign) block.getState()); + if (signWarp.warp(this.manager, event.getPlayer())) { + event.setUseInteractedBlock(Result.DENY); + event.setCancelled(true); + } + } else if (event.getAction() == Action.LEFT_CLICK_BLOCK && inHand(player, Material.WOOD_SWORD)) { + this.createCommand.hitBlock(player, new FixedLocation(block.getLocation())); + } + } + } + + public static boolean inHand(Player player, Material material) { + ItemStack stack = player.getItemInHand(); + return stack == null ? material == null : stack.getType() == material; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerMove(PlayerMoveEvent event) { + if (!event.isCancelled() && this.properties.isCancelWarmUpOnMovement()) { + if (this.manager.getWarmUp().cancelWarmUp(event.getPlayer())) { + event.getPlayer().sendMessage(ChatColor.RED + "WarmUp was canceled due to movement!"); + } + } + } +} diff --git a/src/main/java/de/xzise/xwarp/listeners/XWServerListener.java b/src/main/java/de/xzise/xwarp/listeners/XWServerListener.java new file mode 100644 index 0000000000..f9e4b3f9d6 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/listeners/XWServerListener.java @@ -0,0 +1,60 @@ +package de.xzise.xwarp.listeners; + +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.event.server.PluginEnableEvent; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; +import org.dynmap.DynmapCommonAPI; + +import de.xzise.bukkit.util.wrappers.WrapperServerListener; +import de.xzise.wrappers.Handler; +import de.xzise.xwarp.PluginProperties; +import de.xzise.xwarp.WarpManager; + +public class XWServerListener extends WrapperServerListener { + + private final PluginProperties properties; + private final WarpManager warpManager; + private final PluginManager manager; + + public XWServerListener(PluginProperties properties, PluginManager manager, WarpManager warpManager, Handler... handlers) { + super(handlers); + this.warpManager = warpManager; + this.properties = properties; + this.manager = manager; + } + + @Override + public void onPluginEnable(PluginEnableEvent event) { + super.onPluginEnable(event); + if (checkPlugin(event.getPlugin(), this.properties.getMarkerPlugin())) { + this.warpManager.setMarkerAPI(((DynmapCommonAPI) event.getPlugin()).getMarkerAPI()); + } + } + + @Override + public void onPluginDisable(PluginDisableEvent event) { + super.onPluginDisable(event); + if (checkPlugin(event.getPlugin(), this.properties.getMarkerPlugin())) { + this.warpManager.setMarkerAPI(null); + } + } + + private static boolean checkPlugin(final Plugin plugin, final String markerPluginName) { + try { + return plugin.getDescription().getName().equalsIgnoreCase(markerPluginName) && plugin instanceof DynmapCommonAPI; + } catch (NoClassDefFoundError e) { + return false; + } + } + + public void load() { + super.load(); + final String markerPluginName = this.properties.getMarkerPlugin(); + for (Plugin plugin : this.manager.getPlugins()) { + if (plugin.isEnabled() && checkPlugin(plugin, markerPluginName)) { + this.warpManager.setMarkerAPI(((DynmapCommonAPI) plugin).getMarkerAPI()); + } + } + } +} diff --git a/src/main/java/de/xzise/xwarp/listeners/XWWorldListener.java b/src/main/java/de/xzise/xwarp/listeners/XWWorldListener.java new file mode 100644 index 0000000000..5501871c9a --- /dev/null +++ b/src/main/java/de/xzise/xwarp/listeners/XWWorldListener.java @@ -0,0 +1,54 @@ +package de.xzise.xwarp.listeners; + +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.world.WorldLoadEvent; +import org.bukkit.event.world.WorldUnloadEvent; +import org.bukkit.plugin.PluginManager; + +import com.google.common.collect.ImmutableSet; + +import de.xzise.xwarp.Manager; +import de.xzise.xwarp.XWarp; +import de.xzise.xwarp.wrappers.permission.WorldPermission; + +public class XWWorldListener implements Listener { + + private final ImmutableSet> managers; + private final PluginManager pm; + + public XWWorldListener(PluginManager pm, Manager... managers) { + this.managers = ImmutableSet.copyOf(managers); + this.pm = pm; + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onWorldLoad(WorldLoadEvent event) { + int validCount = 0; + World world = event.getWorld(); + for (Manager manager : this.managers) { + validCount += manager.setWorld(world); + } + if (validCount > 0) { + XWarp.logger.info("Because world '" + event.getWorld().getName() + "' was loaded " + validCount + " warp object" + (validCount == 1 ? "" : "s") + " get valid."); + } + WorldPermission.register(world.getName(), this.pm); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onWorldUnload(WorldUnloadEvent event) { + if (!event.isCancelled()) { + int invalidCount = 0; + World world = event.getWorld(); + for (Manager manager : this.managers) { + invalidCount += manager.unsetWorld(world); + } + if (invalidCount > 0) { + XWarp.logger.info("Because world '" + event.getWorld().getName() + "' was unloaded " + invalidCount + " warp object" + (invalidCount == 1 ? "" : "s") + " get invalid."); + } + WorldPermission.unregister(world.getName(), this.pm); + } + } +} diff --git a/src/main/java/de/xzise/xwarp/lister/GenericLister.java b/src/main/java/de/xzise/xwarp/lister/GenericLister.java new file mode 100644 index 0000000000..e58f89a7ba --- /dev/null +++ b/src/main/java/de/xzise/xwarp/lister/GenericLister.java @@ -0,0 +1,235 @@ +package de.xzise.xwarp.lister; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + + +import org.angelsl.minecraft.randomshit.fontwidth.MinecraftFontWidthCalculator; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; + +import de.xzise.metainterfaces.FixedLocation; +import de.xzise.metainterfaces.LocationWrapper; +import de.xzise.xwarp.Warp; +import de.xzise.xwarp.Warp.Visibility; +import de.xzise.xwarp.warpable.WarperFactory; + +public class GenericLister { + + public static final ChatColor GLOBAL_OWN = ChatColor.DARK_BLUE; + public static final ChatColor PUBLIC_OWN = ChatColor.BLUE; + public static final ChatColor PRIVATE_OWN = ChatColor.AQUA; + + public static final ChatColor GLOBAL_OTHER = ChatColor.DARK_GREEN; + public static final ChatColor PUBLIC_OTHER = ChatColor.GREEN; + public static final ChatColor PRIVATE_OTHER = ChatColor.RED; + + public static final ChatColor PRIVATE_INVITED = ChatColor.YELLOW; + + private GenericLister() { + } + + public enum Column { + OWNER, + WORLD, + LOCATION; + } + + public static void listPage(int page, int maxPages, CommandSender sender, ListSection... sections) { + listPage(page, maxPages, sender, EnumSet.allOf(Column.class), sections); + } + + public static void listPage(int page, int maxPages, CommandSender sender, Set columns, ListSection... sections) { + + int charsPerLine = 40; + WidthCalculator widther = null; + + // Get the correct width calculator! + if (sender instanceof ConsoleCommandSender) { + charsPerLine = 80; + widther = new ConsoleWidth(); + } else if (sender instanceof Player) { + charsPerLine = 40; + widther = new MinecraftWidth(); + } + + // Generate header with the same length every time + String intro = GenericLister.charList(charsPerLine / 2 - GenericLister.getWidth(page, 10), '-') + " " + ChatColor.GREEN + "Page " + page + "/" + maxPages + ChatColor.WHITE + " " + GenericLister.charList(charsPerLine / 2 - GenericLister.getWidth(maxPages, 10), '-'); + + sender.sendMessage(ChatColor.WHITE + intro); + + final int width = widther.getWidth(intro); + + for (ListSection listSection : sections) { + if (listSection.title != null && !listSection.title.isEmpty()) { + sender.sendMessage(listSection.title); + } + + for (Warp warp : listSection) { + String name = warp.getName(); + + String owner = warp.getOwner(); + ChatColor color; + if (sender instanceof Player) { + if (owner.equalsIgnoreCase(((Player) sender).getName())) { + owner = "you"; + } + color = GenericLister.getColor(warp, (Player) sender); + } else { + color = GenericLister.getColor(warp, null); + } + + String location = GenericLister.getLocationString(warp.getLocationWrapper(), columns.contains(Column.WORLD), columns.contains(Column.LOCATION)); + final String creatorString = columns.contains(Column.OWNER) ? " by " + owner : ""; + + // Find remaining length left + int left = width - widther.getWidth("''" + creatorString + location); + + int nameLength = widther.getWidth(name); + if (left > nameLength) { + name = "'" + name + "'" + ChatColor.WHITE + creatorString + whitespace(left - nameLength, widther.getWidth(" ")); + } else if (left < nameLength) { + name = "'" + substring(name, left, widther) + ChatColor.WHITE + "..." + color + "'"; + nameLength = widther.getWidth(name); + // Cut location if needed + location = substring(location, width - nameLength - widther.getWidth(creatorString), widther); + name += ChatColor.WHITE + creatorString; + } + + sender.sendMessage(color + name + location); + } + } + } + + /** + * Lob shit off that string till it fits. + */ + private static String substring(String name, int left, WidthCalculator widthCalculator) { + while (widthCalculator.getWidth(name) > left && name.length() > 3) { + name = name.substring(0, name.length() - 1); + } + return name; + } + + public static String whitespace(int length, int spaceWidth) { + return charList(length / spaceWidth, ' '); + } + + public static String charList(int count, char c) { + StringBuilder ret = new StringBuilder(); + + while (count-- > 0) { + ret.append(c); + } + + return ret.toString(); + } + + private static int getWidth(int number, int base) { + int width = 1; + while (number >= base) { + number /= base; + width++; + } + return width; + } + + public static String[] getLegend() { + List result = new ArrayList(8); + result.add(ChatColor.RED + "-------------------- " + ChatColor.WHITE + "LIST LEGEND" + ChatColor.RED + " -------------------"); + result.add(GenericLister.GLOBAL_OWN + "Yours and it is global"); + result.add(GenericLister.PUBLIC_OWN + "Yours and it is public."); + result.add(GenericLister.PRIVATE_OWN + "Yours and it is private."); + result.add(GenericLister.GLOBAL_OTHER + "Not yours and it is global"); + result.add(GenericLister.PUBLIC_OTHER + "Not yours and it is public"); + result.add(GenericLister.PRIVATE_OTHER + "Not yours, private and not invited"); + result.add(GenericLister.PRIVATE_INVITED + "Not yours, private and you are invited"); + return result.toArray(new String[0]); + } + + public static ChatColor getColor(Warp warp, Player player) { + return getColor(player != null && warp.isOwn(player.getName()), player != null && warp.playerCanWarp(WarperFactory.getWarpable(player)), warp.getVisibility(), player); + } + + public static ChatColor getColor(boolean isOwn, boolean invited, Visibility visibility, Player player) { + if (visibility == null) { + visibility = Visibility.PUBLIC; + } + if (isOwn) { + switch (visibility) { + case PRIVATE: + return GenericLister.PRIVATE_OWN; + case PUBLIC: + return GenericLister.PUBLIC_OWN; + case GLOBAL: + return GenericLister.GLOBAL_OWN; + } + } else { + switch (visibility) { + case PRIVATE: + if (invited) { + return GenericLister.PRIVATE_INVITED; + } else { + return GenericLister.PRIVATE_OTHER; + } + case PUBLIC: + return GenericLister.PUBLIC_OTHER; + case GLOBAL: + return GenericLister.GLOBAL_OTHER; + } + } + return GenericLister.PRIVATE_OTHER; + } + + public static String getLocationString(LocationWrapper wrapper, boolean world, boolean coordinates) { + if (world || coordinates) { + FixedLocation location = wrapper.getLocation(); + StringBuilder result = new StringBuilder("@("); + if (world) { + result.append(wrapper.getWorld()); + if (!wrapper.isValid()) { + result.append(" " + ChatColor.RED + "(invalid)" + ChatColor.WHITE); + } + if (coordinates) { + result.append(", "); + } + } + if (coordinates) { + result.append(location.getBlockX()).append(", "); + result.append(location.getBlockY()).append(", "); + result.append(location.getBlockZ()); + } + return result.append(")").toString(); + } else { + return ""; + } + } + +} + +interface WidthCalculator { + int getWidth(String text); +} + +class MinecraftWidth implements WidthCalculator { + + @Override + public int getWidth(String text) { + return MinecraftFontWidthCalculator.getStringWidth(text); + } + +} + +class ConsoleWidth implements WidthCalculator { + + @Override + public int getWidth(String text) { + // Assume that the font is non proportional! + return ChatColor.stripColor(text).length(); + } + +} \ No newline at end of file diff --git a/src/main/java/de/xzise/xwarp/lister/ListSection.java b/src/main/java/de/xzise/xwarp/lister/ListSection.java new file mode 100644 index 0000000000..28e3efbafc --- /dev/null +++ b/src/main/java/de/xzise/xwarp/lister/ListSection.java @@ -0,0 +1,39 @@ +package de.xzise.xwarp.lister; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import de.xzise.MinecraftUtil; +import de.xzise.xwarp.Warp; + + +public class ListSection implements Iterable { + + public final String title; + private final List warps; + + public ListSection(String title, int maximumLength) { + this.title = title; + this.warps = new ArrayList(maximumLength); + } + + public ListSection(String title) { + this(title, MinecraftUtil.PLAYER_LINES_COUNT); + } + + public void addWarp(Warp warp) { + this.warps.add(warp); + } + + public void addWarps(Collection warp) { + this.warps.addAll(warp); + } + + @Override + public Iterator iterator() { + return this.warps.iterator(); + } + +} diff --git a/src/main/java/de/xzise/xwarp/signwarps/MyWarpSign.java b/src/main/java/de/xzise/xwarp/signwarps/MyWarpSign.java new file mode 100644 index 0000000000..3a9562273d --- /dev/null +++ b/src/main/java/de/xzise/xwarp/signwarps/MyWarpSign.java @@ -0,0 +1,16 @@ +package de.xzise.xwarp.signwarps; + +import de.xzise.xwarp.WarpDestination; + +public class MyWarpSign implements SignWarpDefinition { + + @Override + public WarpDestination getDestination(String[] lines) { + if (lines.length == 2 && lines[0].contains("MyWarp")) { + return new WarpDestination(lines[1], null); + } else { + return null; + } + } + +} diff --git a/src/main/java/de/xzise/xwarp/signwarps/SignWarp.java b/src/main/java/de/xzise/xwarp/signwarps/SignWarp.java new file mode 100644 index 0000000000..e80537fd40 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/signwarps/SignWarp.java @@ -0,0 +1,85 @@ +package de.xzise.xwarp.signwarps; + +import java.util.ArrayList; +import java.util.List; + + +import org.bukkit.Material; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import de.xzise.xwarp.WarpDestination; +import de.xzise.xwarp.WarpManager; +import de.xzise.xwarp.XWarp; +import de.xzise.xwarp.warpable.WarperFactory; + +public class SignWarp { + + private static final SignWarpDefinition[] SIGN_WARP_DEFINITIONS = new SignWarpDefinition[] { new XWarpSign(), new SingleLineSign(), new MyWarpSign(), }; + + private Sign sign; + + public SignWarp(Sign sign) { + this.sign = sign; + } + + public WarpDestination getDestination(Player player) { + return SignWarp.getDestination(SignWarp.getFilledLines(this.sign), player); + } + + public boolean warp(WarpManager list, Player player) { + WarpDestination destination = this.getDestination(player); + + if (destination != null) { + list.warpTo(destination.name, destination.owner, player, WarperFactory.getWarpable(player), true); + return true; + } else { + return false; + } + } + + private static String replaceName(String text, String value, String... placeHolders) { + if (value != null) { + for (String placeHolder : placeHolders) { + text = text.replace("{" + placeHolder + "}", value); + } + } + return text; + } + + public static WarpDestination getDestination(String[] lines, Player player) { + for (SignWarpDefinition destinationElement : SIGN_WARP_DEFINITIONS) { + WarpDestination destination = destinationElement.getDestination(lines); + if (destination != null) { + String name = destination.name; + name = replaceName(name, player.getName(), "Name", "N"); + name = replaceName(name, player.getDisplayName(), "DName", "DN"); + String[] groups = XWarp.permissions.getGroup(player.getWorld().getName(), player.getName()); + if (groups.length > 0) { + name = replaceName(name, groups[0], "Group", "G"); + } + ItemStack stack = player.getItemInHand(); + name = replaceName(name, String.valueOf(stack == null ? Material.AIR.getId() : stack.getTypeId()), "Hand", "M"); + + return new WarpDestination(name, destination.owner); + } + } + + return null; + } + + private static String[] getFilledLines(Sign sign) { + return SignWarp.getFilledLines(sign.getLines()); + } + + public static String[] getFilledLines(String[] lines) { + List result = new ArrayList(); + for (int i = 0; i < lines.length; i++) { + if (!lines[i].trim().isEmpty()) { + result.add(lines[i]); + } + } + return result.toArray(new String[0]); + } +} diff --git a/src/main/java/de/xzise/xwarp/signwarps/SignWarpDefinition.java b/src/main/java/de/xzise/xwarp/signwarps/SignWarpDefinition.java new file mode 100644 index 0000000000..65cc24c927 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/signwarps/SignWarpDefinition.java @@ -0,0 +1,9 @@ +package de.xzise.xwarp.signwarps; + +import de.xzise.xwarp.WarpDestination; + +public interface SignWarpDefinition { + + WarpDestination getDestination(String[] lines); + +} diff --git a/src/main/java/de/xzise/xwarp/signwarps/SingleLineSign.java b/src/main/java/de/xzise/xwarp/signwarps/SingleLineSign.java new file mode 100644 index 0000000000..a414cb5cb0 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/signwarps/SingleLineSign.java @@ -0,0 +1,48 @@ +package de.xzise.xwarp.signwarps; + +import de.xzise.xwarp.WarpDestination; + +public class SingleLineSign implements SignWarpDefinition { + + @Override + public WarpDestination getDestination(String[] lines) { + // Single Line + // line < 0 → No line, line ≥ lines.length → More than one line + // All other cases: One line & valid! + int line = -1; + for (int i = 0; i < lines.length; i++) { + if (lines[i].matches("(W|w)arp:?\\s+.+")) { + if (line < 0) { + line = i; + } else { + // Invalid + line = lines.length; + break; + } + } + } + + // If only one valid line found + if (line >= 0 && line < lines.length) { + // Extract name: + String command = lines[line]; + String name = ""; + boolean spaceReach = false; + for (int i = 0; i < command.length(); i++) { + if (command.charAt(i) == ' ') { + spaceReach = true; + } else if (spaceReach) { + name = command.substring(i); + break; + } + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Empty warp name"); + } + return new WarpDestination(name, ""); + } else { + return null; + } + } + +} diff --git a/src/main/java/de/xzise/xwarp/signwarps/XWarpSign.java b/src/main/java/de/xzise/xwarp/signwarps/XWarpSign.java new file mode 100644 index 0000000000..80888187b8 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/signwarps/XWarpSign.java @@ -0,0 +1,21 @@ +package de.xzise.xwarp.signwarps; + +import de.xzise.xwarp.WarpDestination; + +public class XWarpSign implements SignWarpDefinition { + + @Override + public WarpDestination getDestination(String[] lines) { + // xWarp + if ((lines.length == 2 || lines.length == 3) && ((lines[0].equalsIgnoreCase("xWarp") || lines[0].matches("x?(W|w)arp:?")))) { + String creator = ""; + if (lines.length == 3) { + creator = lines[2]; + } + return new WarpDestination(lines[1], creator); + } else { + return null; + } + } + +} diff --git a/src/main/java/de/xzise/xwarp/timer/CoolDown.java b/src/main/java/de/xzise/xwarp/timer/CoolDown.java new file mode 100644 index 0000000000..eb49057758 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/timer/CoolDown.java @@ -0,0 +1,95 @@ +package de.xzise.xwarp.timer; + +import java.util.HashMap; +import java.util.Map; + + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; + +import de.xzise.xwarp.PluginProperties; +import de.xzise.xwarp.Warp; +import de.xzise.xwarp.XWarp; +import de.xzise.xwarp.warpable.Warpable; +import de.xzise.xwarp.wrappers.permission.Groups; + +public class CoolDown { + + private final Map players = new HashMap(); + private final Plugin plugin; + private final PluginProperties properties; + + public CoolDown(Plugin plugin, PluginProperties properties) { + this.plugin = plugin; + this.properties = properties; + } + + public void addPlayer(Warp warp, CommandSender sender) { + int time = getCooldownTime(warp, sender); + if (time > 0) { + if (this.players.containsKey(sender)) { + this.plugin.getServer().getScheduler().cancelTask(this.players.get(sender).id); + } + + CoolTask task = new CoolTask(sender, this); + int taskIndex = this.plugin.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin, task, time * 20); + task.setId(taskIndex); + this.players.put(sender, task); + } + } + + public boolean playerHasCooled(CommandSender sender) { + return !this.players.containsKey(sender); + } + + /** + * NOT WORKING AT THE MOMENT! + * @return Every time: 0! + */ + public int timeLeft(Warpable player) { + if (players.containsKey(player)) { + // TODO + return 0; + } else { + return 0; + } + } + + public static int getCooldownTime(Warp warp, CommandSender sender) { + int time = warp.getCoolDown(); + if (time < 0) { + return XWarp.permissions.getInteger(sender, Groups.TIMERS_COOLDOWN_GROUP.get(warp.getVisibility())); + } else { + return time; + } + } + + public void cooledDown(CommandSender warpable) { + if (this.properties.isCooldownNotify()) { + warpable.sendMessage(ChatColor.AQUA + "You have cooled down, feel free to warp."); + } + this.players.remove(warpable); + } + + private static class CoolTask implements Runnable { + + private final CommandSender player; + private final CoolDown cooldown; + private int id; + + public CoolTask(CommandSender player, CoolDown cooldown) { + this.player = player; + this.cooldown = cooldown; + } + + public void setId(int id) { + this.id = id; + } + + public void run() { + this.cooldown.cooledDown(this.player); + } + } + +} diff --git a/src/main/java/de/xzise/xwarp/timer/WarmUp.java b/src/main/java/de/xzise/xwarp/timer/WarmUp.java new file mode 100644 index 0000000000..af3ccd784c --- /dev/null +++ b/src/main/java/de/xzise/xwarp/timer/WarmUp.java @@ -0,0 +1,105 @@ +package de.xzise.xwarp.timer; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; +import org.bukkit.plugin.Plugin; + +import de.xzise.MinecraftUtil; +import de.xzise.xwarp.PluginProperties; +import de.xzise.xwarp.Warp; +import de.xzise.xwarp.XWarp; +import de.xzise.xwarp.warpable.Warpable; +import de.xzise.xwarp.wrappers.permission.Groups; + +public class WarmUp { + + private Map players = new HashMap(); + private final Plugin plugin; + private final PluginProperties properties; + private final CoolDown down; + + public WarmUp(Plugin plugin, PluginProperties properties, CoolDown down) { + this.plugin = plugin; + this.properties = properties; + this.down = down; + } + + public void addPlayer(CommandSender warper, Warpable warped, Warp warp) { + int warmup = getWarmupTime(warp, warper); + if (warmup > 0) { + if (this.properties.isWarmupNotify()) { + warper.sendMessage(ChatColor.AQUA + "You will have to warm up for " + warmup + " secs"); + } + int taskIndex = this.plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new WarmTask(warper, warped, warp, this), warmup * 20); + this.players.put(warper, taskIndex); + } else { + this.sendPlayer(warper, warped, warp); + } + } + + public boolean cancelWarmUp(CommandSender warper) { + // TODO: Only remove, if warp itself? + if (this.players.containsKey(warper)) { + this.plugin.getServer().getScheduler().cancelTask(this.players.get(warper)); + this.players.remove(warper); + return true; + } else { + return false; + } + } + + public static int getWarmupTime(Warp warp, CommandSender warper) { + int time = warp.getWarmUp(); + if (time < 0) { + return XWarp.permissions.getInteger(warper, Groups.TIMERS_WARMUP_GROUP.get(warp.getVisibility())); + } else { + return time; + } + } + + public boolean playerHasWarmed(CommandSender warper) { + return this.players.containsKey(warper); + } + + private void sendPlayer(CommandSender warper, Warpable warped, Warp warp) { + if (warped.teleport(warp.getLocation().toLocation(), TeleportCause.COMMAND)) { + String rawMsg = warp.getRawWelcomeMessage(); + if (rawMsg == null) { + rawMsg = this.properties.getDefaultMessage().replace("{NAME}", warp.getName()); + } + if (MinecraftUtil.isSet(rawMsg)) { + warped.sendMessage(ChatColor.AQUA + rawMsg); + } + this.down.addPlayer(warp, warper); + this.players.remove(warper); + if (!warped.equals(warper)) { + warper.sendMessage("Sucessfully warped '" + ChatColor.GREEN + MinecraftUtil.getName(warped) + ChatColor.WHITE + "'"); + } + } else { + warper.sendMessage(ChatColor.RED + "Unable to warp."); + } + } + + private static class WarmTask implements Runnable { + private CommandSender player; + private Warpable warped; + private Warp warp; + private WarmUp warmUp; + + public WarmTask(CommandSender player, Warpable warped, Warp warp, WarmUp warmUp) { + this.player = player; + this.warped = warped; + this.warp = warp; + this.warmUp = warmUp; + } + + public void run() { + this.warmUp.sendPlayer(player, warped, warp); + } + } + +} diff --git a/src/main/java/de/xzise/xwarp/warpable/Positionable.java b/src/main/java/de/xzise/xwarp/warpable/Positionable.java new file mode 100644 index 0000000000..b92ce080e9 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/warpable/Positionable.java @@ -0,0 +1,10 @@ +package de.xzise.xwarp.warpable; + +import org.bukkit.Location; +import org.bukkit.command.CommandSender; + +public interface Positionable extends CommandSender { + + Location getLocation(); + +} diff --git a/src/main/java/de/xzise/xwarp/warpable/Warpable.java b/src/main/java/de/xzise/xwarp/warpable/Warpable.java new file mode 100644 index 0000000000..8059676fa4 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/warpable/Warpable.java @@ -0,0 +1,11 @@ +package de.xzise.xwarp.warpable; + +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; + +public interface Warpable extends CommandSender { + + boolean teleport(Location location, TeleportCause teleportCause); + +} diff --git a/src/main/java/de/xzise/xwarp/warpable/WarpablePlayer.java b/src/main/java/de/xzise/xwarp/warpable/WarpablePlayer.java new file mode 100644 index 0000000000..6b4afcbbc1 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/warpable/WarpablePlayer.java @@ -0,0 +1,25 @@ +package de.xzise.xwarp.warpable; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; + +import de.xzise.metainterfaces.CommandSenderWrapper; +import de.xzise.metainterfaces.Nameable; + +public class WarpablePlayer extends CommandSenderWrapper implements Warpable, Positionable, Nameable { + + public WarpablePlayer(Player player) { + super(player); + } + + @Override + public boolean teleport(Location location, TeleportCause teleportCause) { + return this.sender.teleport(location, teleportCause); + } + + @Override + public Location getLocation() { + return this.sender.getLocation(); + } +} \ No newline at end of file diff --git a/src/main/java/de/xzise/xwarp/warpable/WarperFactory.java b/src/main/java/de/xzise/xwarp/warpable/WarperFactory.java new file mode 100644 index 0000000000..34d642397c --- /dev/null +++ b/src/main/java/de/xzise/xwarp/warpable/WarperFactory.java @@ -0,0 +1,42 @@ +package de.xzise.xwarp.warpable; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import de.xzise.metainterfaces.CommandSenderWrapper; + +public final class WarperFactory { + + private WarperFactory() {} + + public static Warpable getWarpable(Object sender) { + if (sender instanceof Warpable) { + return (Warpable) sender; + } else if (sender instanceof Player) { + return new WarpablePlayer((Player) sender); + } else { + return null; + } + } + + public static Positionable getPositionable(Object sender) { + if (sender instanceof Positionable) { + return (Positionable) sender; + } else if (sender instanceof Player) { + return new WarpablePlayer((Player) sender); + } else { + return null; + } + } + + public static Player getPlayer(Object sender) { + if (sender instanceof CommandSender) { + sender = CommandSenderWrapper.getCommandSender((CommandSender) sender); + } + if (sender instanceof Player) { + return (Player) sender; + } else { + return null; + } + } +} diff --git a/src/main/java/de/xzise/xwarp/wrappers/permission/GeneralPermissions.java b/src/main/java/de/xzise/xwarp/wrappers/permission/GeneralPermissions.java new file mode 100644 index 0000000000..6f9e6a11ef --- /dev/null +++ b/src/main/java/de/xzise/xwarp/wrappers/permission/GeneralPermissions.java @@ -0,0 +1,43 @@ +package de.xzise.xwarp.wrappers.permission; + +import org.bukkit.permissions.PermissionDefault; + +import de.xzise.wrappers.permissions.Permission; +import de.xzise.wrappers.permissions.SuperPerm; + +public enum GeneralPermissions implements Permission, SuperPerm { + RELOAD("reload", false, "Allows you to reload all warps and protection areas"), + EXPORT("export", false, "Allows you to export all warps and protection areas"), + IMPORT("import", false, "Allows you to import all warps and protection areas"), + ; + + public final String name; + public final boolean def; + public final String description; + + private GeneralPermissions(String name, boolean def, String description) { + this.name = "xwarp.admin." + name; + this.def = def; + this.description = description; + } + + @Override + public Boolean getDefault() { + return this.def; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public String getDescription() { + return this.description; + } + + @Override + public PermissionDefault getPermissionDefault() { + return this.def ? PermissionDefault.TRUE : PermissionDefault.OP; + } +} diff --git a/src/main/java/de/xzise/xwarp/wrappers/permission/Group.java b/src/main/java/de/xzise/xwarp/wrappers/permission/Group.java new file mode 100644 index 0000000000..0412cd8dda --- /dev/null +++ b/src/main/java/de/xzise/xwarp/wrappers/permission/Group.java @@ -0,0 +1,29 @@ +package de.xzise.xwarp.wrappers.permission; + +import java.util.EnumMap; +import java.util.Map; + +import de.xzise.xwarp.Warp.Visibility; + + + +public class Group { + + private final Map groups = new EnumMap(Visibility.class); + + public Group(T... permissions) { + if (permissions.length != Visibility.values().length) { + throw new IllegalArgumentException("For each visibility has to be one permission."); + } + for (T permission : permissions) { + if (this.groups.put(permission.getVisibility(), permission) != null) { + throw new IllegalArgumentException("Don't use two permissions fro the same visibility."); + } + } + } + + public T get(Visibility visibility) { + return this.groups.get(visibility); + } + +} \ No newline at end of file diff --git a/src/main/java/de/xzise/xwarp/wrappers/permission/Groups.java b/src/main/java/de/xzise/xwarp/wrappers/permission/Groups.java new file mode 100644 index 0000000000..552470fc1f --- /dev/null +++ b/src/main/java/de/xzise/xwarp/wrappers/permission/Groups.java @@ -0,0 +1,16 @@ +package de.xzise.xwarp.wrappers.permission; + + + +public class Groups { + + public static final Group SIGN_CREATE_GROUP = new Group(PermissionTypes.CREATE_SIGN_PRIVATE, PermissionTypes.CREATE_SIGN_PUBLIC, PermissionTypes.CREATE_SIGN_GLOBAL); + public static final Group CREATE_GROUP = new Group(PermissionTypes.CREATE_PRIVATE, PermissionTypes.CREATE_PUBLIC, PermissionTypes.CREATE_GLOBAL); + + public static final Group TIMERS_COOLDOWN_GROUP = new Group(PermissionValues.WARP_COOLDOWN_PRIVATE, PermissionValues.WARP_COOLDOWN_PUBLIC, PermissionValues.WARP_COOLDOWN_GLOBAL); + public static final Group TIMERS_WARMUP_GROUP = new Group(PermissionValues.WARP_WARMUP_PRIVATE, PermissionValues.WARP_WARMUP_PUBLIC, PermissionValues.WARP_WARMUP_GLOBAL); + public static final Group LIMIT_GROUP = new Group(PermissionValues.WARP_LIMIT_PRIVATE, PermissionValues.WARP_LIMIT_PUBLIC, PermissionValues.WARP_LIMIT_GLOBAL); + public static final Group PRICES_TO_GROUP = new Group(PricePermissions.WARP_PRICES_TO_PRIVATE, PricePermissions.WARP_PRICES_TO_PUBLIC, PricePermissions.WARP_PRICES_TO_GLOBAL); + public static final Group PRICES_CREATE_GROUP = new Group(PricePermissions.WARP_PRICES_CREATE_PRIVATE, PricePermissions.WARP_PRICES_CREATE_PUBLIC, PricePermissions.WARP_PRICES_CREATE_GLOBAL); + +} diff --git a/src/main/java/de/xzise/xwarp/wrappers/permission/PermissionTypes.java b/src/main/java/de/xzise/xwarp/wrappers/permission/PermissionTypes.java new file mode 100644 index 0000000000..23ce6558f2 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/wrappers/permission/PermissionTypes.java @@ -0,0 +1,164 @@ +package de.xzise.xwarp.wrappers.permission; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.permissions.PermissionDefault; +import org.bukkit.plugin.PluginManager; + +import com.google.common.collect.ImmutableSet; + +import de.xzise.wrappers.permissions.Permission; +import de.xzise.wrappers.permissions.SuperPerm; +import de.xzise.xwarp.XWarp; +import de.xzise.xwarp.Warp.Visibility; + +public enum PermissionTypes implements Permission, VisibilityPermission, SuperPerm { + // Warp via command + TO_GLOBAL("to.global", true, "Allows you to warp to a global warp with a command"), + TO_OWN("to.own", true, "Allows you to warp to your own warp with a command"), + TO_INVITED("to.invited", true, "Allows to warp to a invited warp with a command"), + TO_OTHER("to.other", true, "Allows to warp to a public warp with a command"), + + // Use warp signs + SIGN_WARP_GLOBAL("sign.to.global", true, "Allows you to use a warp sign to a global warp"), + SIGN_WARP_OWN("sign.to.own", true, "Allows you to use a warp sign to your own warp"), + SIGN_WARP_INVITED("sign.to.invited", true, "Allows you to use a warp sign to a invited warp"), + SIGN_WARP_OTHER("sign.to.other", true, "Allows you to use a warp sign to a public warp"), + + // Create warp signs + CREATE_SIGN_PRIVATE("sign.create.private", true, "Allows you to create warp signs to a private warp", Visibility.PRIVATE), + CREATE_SIGN_PUBLIC("sign.create.public", true, "Allows you to create warp signs to a public warp", Visibility.PUBLIC), + CREATE_SIGN_GLOBAL("sign.create.global", true, "Allows you to create warp signs to a global warp", Visibility.GLOBAL), + SIGN_CREATE_UNKNOWN("sign.create.unknown", true, "Allows you to create warp signs to a warp which didn't exists"), + + // Create warps + CREATE_PRIVATE("create.private", true, "Allows you to create private warps", Visibility.PRIVATE), + CREATE_PUBLIC("create.public", true, "Allows you to create public warps", Visibility.PUBLIC), + CREATE_GLOBAL("create.global", true, "Allows you to create global warps", Visibility.GLOBAL), + + // Edit own warps + EDIT_DELETE("edit.delete", true, "Allows you to delete your own warps"), + EDIT_INVITE("edit.invite.add", true, "Allows you to invite others to your warps"), + EDIT_UNINVITE("edit.invite.delete", true, "Allows you to uninvite others to your warps"), + EDIT_MESSAGE("edit.message", true, "Allows you to change the welcome message of your warps"), + EDIT_LOCATION("edit.update", true, "Allows you to relocate your own warps"), + EDIT_RENAME("edit.rename", true, "Allows you to rename your own warps"), + // EDIT_(PRIVATE|PUBLIC|GLOBAL) == CREATE_* + EDIT_EDITORS_ADD("edit.editors.add", true, "Allows you to add an editor to your warps"), + EDIT_EDITORS_REMOVE("edit.editors.remove", true, "Allows you to remove an editor to your warps"), + EDIT_CHANGE_OWNER("edit.owner", true, "Allows you to change the owner of your warps"), + EDIT_CHANGE_CREATOR("edit.creator", false, "Allows you to change the creator of your warps"), + EDIT_PRICE("edit.price.set", true, "Allows you to change the price of own warps"), + EDIT_FREE("edit.price.free", false, "Allows you to make your warps completely free"), + EDIT_LIST("edit.list", false, "Allows you to change if your warps are listed"), + EDIT_COOLDOWN("edit.cooldown", true, "Allows you to set the cooldown of your warps"), + EDIT_WARMUP("edit.warmup", true, "Allows you to set the warmup of your warps"), + + LIST_OWN("list.own", true, "Allows you to view your own unlisted warps"), + + // Access to list + CMD_LIST("command.list", true, "Allows you to execute the warp list command"), + CMD_SEARCH("command.search", true, "Allows you to execute the warp search command"), + CMD_INFO("command.info", true, "Allows you to execute the warp info command"), + + // Edit warp owned by others + ADMIN_DELETE("admin.delete", false, "Allows you to delete any warp"), + ADMIN_INVITE("admin.invite", false, "Allows you to invite others to any warp"), + ADMIN_UNINVITE("admin.uninvite", false, "Allows you to uninvite others to any warp"), + ADMIN_MESSAGE("admin.message", false, "Allows you to change the welcome message of any warp"), + ADMIN_UPDATE("admin.update", false, "Allows you to relocate any warp"), + ADMIN_RENAME("admin.rename", false, "Allows you to rename any warps"), + ADMIN_PRIVATE("admin.private", false, "Allows you to change the visibility to private of any warp"), + ADMIN_PUBLIC("admin.public", false, "Allows you to change the visibility to public of any warp"), + ADMIN_GLOBAL("admin.global", false, "Allows you to change the visibility to global of any warp"), + ADMIN_EDITORS_ADD("admin.editors.add", false, "Allows you to add an editor to any warp"), + ADMIN_EDITORS_REMOVE("admin.editors.remove", false, "Allows you to remove an editor to any warp"), + ADMIN_CHANGE_OWNER("admin.give.owner", false, "Allows you to change the owner of any warp"), + ADMIN_CHANGE_CREATOR("admin.changecreator", false, "Allows you to change the creator of any warp"), + ADMIN_PRICE("admin.price.set", false, "Allows you to change the price of any warp"), + ADMIN_FREE("admin.price.free", false, "Allows you to make any warp completely free"), + ADMIN_LIST_CHANGE("admin.list.change", false, "Allows you to change if any warp is listed"), + ADMIN_COOLDOWN("admin.cooldown", false, "Allows you to set the cooldown of any warp"), + ADMIN_WARMUP("admin.warmup", false, "Allows you to set the warmup of any warp"), + + ADMIN_LIST_VIEW("admin.list.view", false, "Allows you to list also not listed warps"), + ADMIN_TO_ALL("admin.to.all", false, "Allows you to warp any warp"), + ADMIN_WARP_OTHERS("admin.warp.others", false, "Allows you to warp other players"), + ADMIN_CHANGE_WORLD("admin.changeworld", false, "Allows you to change the world of all warps in a specific world."); + ; + + // Maybe upcoming permissions: + // Different admin permissions for each warp (only edit public warps + // e.g.) + + public final String name; + public final boolean def; + public final String description; + public final Visibility visibility; + + public final static ImmutableSet WARP_TO_PERMISSIONS = ImmutableSet.of(ADMIN_TO_ALL, TO_GLOBAL, TO_INVITED, TO_OTHER, TO_OWN); + + private PermissionTypes(String name, boolean def, String description) { + this(name, def, description, null); + } + + private PermissionTypes(String name, boolean def, String description, Visibility visibility) { + this.name = "xwarp.warp." + name; + this.def = def; + this.description = description; + this.visibility = visibility; + } + + public void register(PluginManager pluginManager) throws ClassNotFoundException { + try { + pluginManager.addPermission(new org.bukkit.permissions.Permission(this.name, this.description, this.def ? PermissionDefault.TRUE : PermissionDefault.OP)); + } catch (IllegalArgumentException e) { + XWarp.logger.warning("Couldn't register the permission '" + this.name + "'!", e); + } + } + + @Override + public Boolean getDefault() { + return this.def; + } + + public static PermissionTypes getType(String name) { + for (PermissionTypes type : PermissionTypes.values()) { + if (type.name.equals(name)) { + return type; + } + } + return null; + } + + public static List> getDefaultPermissions(boolean def) { + List> permissions = new ArrayList>(); + for (Permission permission : PermissionTypes.values()) { + if (permission.getDefault() == def) { + permissions.add(permission); + } + } + return permissions; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public Visibility getVisibility() { + return this.visibility; + } + + @Override + public String getDescription() { + return this.description; + } + + @Override + public PermissionDefault getPermissionDefault() { + return this.def ? PermissionDefault.TRUE : PermissionDefault.OP; + } +} \ No newline at end of file diff --git a/src/main/java/de/xzise/xwarp/wrappers/permission/PermissionValues.java b/src/main/java/de/xzise/xwarp/wrappers/permission/PermissionValues.java new file mode 100644 index 0000000000..018c155539 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/wrappers/permission/PermissionValues.java @@ -0,0 +1,74 @@ +package de.xzise.xwarp.wrappers.permission; + +import de.xzise.wrappers.permissions.Permission; +import de.xzise.xwarp.Warp.Visibility; + + +public enum PermissionValues implements Permission, VisibilityPermission { + /* + * VALUES + */ + // Cooldown + WARP_COOLDOWN_PRIVATE("xwarp.warp.timers.cooldown.private", Visibility.PRIVATE), + WARP_COOLDOWN_PUBLIC("xwarp.warp.timers.cooldown.public", Visibility.PUBLIC), + WARP_COOLDOWN_GLOBAL("xwarp.warp.timers.cooldown.global", Visibility.GLOBAL), + + // Warmup + WARP_WARMUP_PRIVATE("xwarp.warp.timers.warmup.private", Visibility.PRIVATE), + WARP_WARMUP_PUBLIC("xwarp.warp.timers.warmup.public", Visibility.PUBLIC), + WARP_WARMUP_GLOBAL("xwarp.warp.timers.warmup.global", Visibility.GLOBAL), + + // Limits + WARP_LIMIT_PRIVATE("xwarp.warp.limit.private", -1, Visibility.PRIVATE), + WARP_LIMIT_PUBLIC("xwarp.warp.limit.public", -1, Visibility.PUBLIC), + WARP_LIMIT_GLOBAL("xwarp.warp.limit.global", -1, Visibility.GLOBAL), + WARP_LIMIT_TOTAL("xwarp.warp.limit.total", -1), + + ; + + public final String name; + public final int def; + public final Visibility visibility; + + private PermissionValues(String name) { + this(name, null); + } + + private PermissionValues(String name, int def) { + this(name, def, null); + } + + private PermissionValues(String name, Visibility visibility) { + this(name, 0, visibility); + } + + private PermissionValues(String name, int def, Visibility visibility) { + this.name = name; + this.def = def; + this.visibility = visibility; + } + + public static PermissionValues getType(String name) { + for (PermissionValues type : PermissionValues.values()) { + if (type.name.equals(name)) { + return type; + } + } + return null; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public Integer getDefault() { + return this.def; + } + + @Override + public Visibility getVisibility() { + return this.visibility; + } +} \ No newline at end of file diff --git a/src/main/java/de/xzise/xwarp/wrappers/permission/PricePermissions.java b/src/main/java/de/xzise/xwarp/wrappers/permission/PricePermissions.java new file mode 100644 index 0000000000..e6cbd1febc --- /dev/null +++ b/src/main/java/de/xzise/xwarp/wrappers/permission/PricePermissions.java @@ -0,0 +1,65 @@ +package de.xzise.xwarp.wrappers.permission; + +import de.xzise.wrappers.permissions.Permission; +import de.xzise.xwarp.Warp.Visibility; + +public enum PricePermissions implements Permission, VisibilityPermission { + + // Prices (warp) + WARP_PRICES_TO_PRIVATE("xwarp.warp.prices.to.private", Visibility.PRIVATE), + WARP_PRICES_TO_PUBLIC("xwarp.warp.prices.to.public", Visibility.PUBLIC), + WARP_PRICES_TO_GLOBAL("xwarp.warp.prices.to.global", Visibility.GLOBAL), + + // Prices (create) + WARP_PRICES_CREATE_PRIVATE("xwarp.warp.prices.create.private", Visibility.PRIVATE), + WARP_PRICES_CREATE_PUBLIC("xwarp.warp.prices.create.public", Visibility.PUBLIC), + WARP_PRICES_CREATE_GLOBAL("xwarp.warp.prices.create.global", Visibility.GLOBAL), + ; + + public final String name; + public final double def; + public final Visibility visibility; + + private PricePermissions(String name) { + this(name, null); + } + + private PricePermissions(String name, double def) { + this(name, def, null); + } + + private PricePermissions(String name, Visibility visibility) { + this(name, 0, visibility); + } + + private PricePermissions(String name, double def, Visibility visibility) { + this.name = name; + this.def = def; + this.visibility = visibility; + } + + public static PricePermissions getType(String name) { + for (PricePermissions type : PricePermissions.values()) { + if (type.name.equals(name)) { + return type; + } + } + return null; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public Double getDefault() { + return this.def; + } + + @Override + public Visibility getVisibility() { + return this.visibility; + } + +} diff --git a/src/main/java/de/xzise/xwarp/wrappers/permission/VisibilityPermission.java b/src/main/java/de/xzise/xwarp/wrappers/permission/VisibilityPermission.java new file mode 100644 index 0000000000..c75259f1fb --- /dev/null +++ b/src/main/java/de/xzise/xwarp/wrappers/permission/VisibilityPermission.java @@ -0,0 +1,9 @@ +package de.xzise.xwarp.wrappers.permission; + +import de.xzise.xwarp.Warp.Visibility; + +public interface VisibilityPermission { + + public Visibility getVisibility(); + +} diff --git a/src/main/java/de/xzise/xwarp/wrappers/permission/WPAPermissions.java b/src/main/java/de/xzise/xwarp/wrappers/permission/WPAPermissions.java new file mode 100644 index 0000000000..347fb17697 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/wrappers/permission/WPAPermissions.java @@ -0,0 +1,76 @@ +package de.xzise.xwarp.wrappers.permission; + +import org.bukkit.permissions.PermissionDefault; + +import de.xzise.wrappers.permissions.Permission; +import de.xzise.wrappers.permissions.SuperPerm; + +public enum WPAPermissions implements Permission, SuperPerm { + // Create wpas + CREATE("create.private", true, "Create warp protection areas"), + + // Edit own warps + EDIT_DELETE("edit.delete", true, "Delete own warp protection areas"), + EDIT_INVITE("edit.invite.add", true, "Invite to own warp protection areas"), + EDIT_UNINVITE("edit.invite.delete", true, "Uninvite from own warp protection areas"), + EDIT_RENAME("edit.rename", true, "Rename own warp protection areas"), + EDIT_EDITORS_ADD("edit.editors.add", true, "Add an editor to own warp protection areas"), + EDIT_EDITORS_REMOVE("edit.editors.remove", true, "Removes an editor from own warp protection areas"), + EDIT_CHANGE_OWNER("edit.owner", true, "Change owner of own warp protection areas"), + EDIT_CHANGE_CREATOR("edit.creator", false, "Change creator of own warp protection areas (Handle with care!)"), + EDIT_LIST("edit.list", false, "Change if owned warps are listed"), + + // Access to list + CMD_LIST("command.list", true, "Execute the wpa list command"), + CMD_SEARCH("command.search", true, "Execute the wpa search command"), + CMD_INFO("command.info", true, "Execute the wpa info command"), + + // Edit warp owned by others + ADMIN_DELETE("admin.delete", false, "Delete all warp protection areas"), + ADMIN_INVITE("admin.invite", false, "Invite to all warp protection areas"), + ADMIN_UNINVITE("admin.uninvite", false, "Uninvite to all warp protection areas"), + ADMIN_RENAME("admin.rename", false, "Rename all warp protection areas"), + ADMIN_EDITORS_ADD("admin.editors.add", false, "Add editors to all warp protection areas"), + ADMIN_EDITORS_REMOVE("admin.editors.remove", false, "Remove editors from all warp protection areas"), + ADMIN_CHANGE_OWNER("admin.give.owner", false, "Change owner of all warp protection areas"), + ADMIN_CHANGE_CREATOR("admin.changecreator", false, "Change creator of all warp protection areas"), + ADMIN_LIST_CHANGE("admin.list.change", false, "Change if all warp protection areas are listed"), + + ADMIN_CREATE_STOP("admin.create.stop", false, "Stop creation for all warp protection areas"), + ADMIN_LIST_VIEW("admin.list.view", false, "List also not listed warps"), + + ADMIN_IGNORE_PROTECTION_AREA("admin.area.ignore", false, "Ignore warp protection areas"), + ADMIN_CHANGE_WORLD("admin.changeworld", false, "Allows you to change the world of all warps in a specific world."); + ; + + public final String name; + public final boolean def; + public final String description; + + private WPAPermissions(String name, boolean def, String description) { + this.name = "xwarp.wpa." + name; + this.def = def; + this.description = description; + } + + @Override + public Boolean getDefault() { + return this.def; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public String getDescription() { + return this.description; + } + + @Override + public PermissionDefault getPermissionDefault() { + return this.def ? PermissionDefault.TRUE : PermissionDefault.OP; + } + +} diff --git a/src/main/java/de/xzise/xwarp/wrappers/permission/WarpEditorPermission.java b/src/main/java/de/xzise/xwarp/wrappers/permission/WarpEditorPermission.java new file mode 100644 index 0000000000..b58fcdc6d4 --- /dev/null +++ b/src/main/java/de/xzise/xwarp/wrappers/permission/WarpEditorPermission.java @@ -0,0 +1,29 @@ +package de.xzise.xwarp.wrappers.permission; + +import de.xzise.wrappers.permissions.Permission; +import de.xzise.xwarp.WarpObject; +import de.xzise.xwarp.editors.Editor; + +public class WarpEditorPermission implements Permission { + + // xwarp..edit.object... + + public final static String PREFIX = "xwarp.edit.warp."; + + private final String permission; + + public WarpEditorPermission(WarpObject warpObject, E permission) { + this.permission = "xwarp." + warpObject.getType() + ".edit.object." + warpObject.getOwner() + "." + warpObject.getName() + "." + permission.getName(); + } + + @Override + public String getName() { + return this.permission; + } + + @Override + public Boolean getDefault() { + return false; + } + +} diff --git a/src/main/java/de/xzise/xwarp/wrappers/permission/WorldPermission.java b/src/main/java/de/xzise/xwarp/wrappers/permission/WorldPermission.java new file mode 100644 index 0000000000..bfe095a52f --- /dev/null +++ b/src/main/java/de/xzise/xwarp/wrappers/permission/WorldPermission.java @@ -0,0 +1,49 @@ +package de.xzise.xwarp.wrappers.permission; + +import org.bukkit.plugin.PluginManager; + +import de.xzise.MinecraftUtil; +import de.xzise.wrappers.permissions.SuperPerm; +import de.xzise.wrappers.permissions.SuperPermBufferPermission; +import de.xzise.xwarp.XWarp; + +public enum WorldPermission { + // Warp to worlds + TO_WORLD("xwarp.warp.world.to.", "Allows you to warp into the world "), + WITHIN_WORLD("xwarp.warp.world.within.", "Allows you to warp within the world "); + + public SuperPermBufferPermission getPermission(String world) { + return new SuperPermBufferPermission(this.getName(world), this.description + world, true); + } + + public String getName(String world) { + return this.name + world; + } + + public final String name; + public final String description; + + private WorldPermission(String name, String description) { + this.name = name; + this.description = description; + } + + public static void register(String world, PluginManager pluginManager) { + SuperPerm[] superPerms = new SuperPerm[WorldPermission.values().length]; + int idx = 0; + for (WorldPermission worldPermission : WorldPermission.values()) { + superPerms[idx++] = worldPermission.getPermission(world); + } + MinecraftUtil.register(pluginManager, XWarp.logger, superPerms); + } + + public static void unregister(String world, PluginManager pluginManager) { + try { + for (WorldPermission worldPermission : WorldPermission.values()) { + pluginManager.removePermission(worldPermission.getName(world)); + } + } catch (NoSuchMethodError e) { + XWarp.logger.warning("Unable to unregister the world permissions."); + } + } +} \ No newline at end of file diff --git a/src/org/angelsl/minecraft/randomshit/fontwidth/MinecraftFontWidthCalculator.java b/src/main/java/org/angelsl/minecraft/randomshit/fontwidth/MinecraftFontWidthCalculator.java similarity index 100% rename from src/org/angelsl/minecraft/randomshit/fontwidth/MinecraftFontWidthCalculator.java rename to src/main/java/org/angelsl/minecraft/randomshit/fontwidth/MinecraftFontWidthCalculator.java diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000000..6363d50557 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,24 @@ +name: xWarp +version: "${project.version}" +main: de.xzise.xwarp.XWarp +description: Implementation to create warp points! +order: postworld +authors: + - 'xZise' + - 'tkelly' +commands: + xwarp: + description: xWarp managing commands + usage: / help - Displays the help for all xwarp commands. + aliases: [xman] + warp: + description: Warp commands + usage: / help - Displays the help for all warp commands. + aliases: [xw, w] + wpa: + description: Warp protection area handling commands. + usage: / help - Displays the help for all wpa commands. + aliases: [xwpa] + go: + description: Warps you to the saved location. + usage: / [to] [owner] [warped player] diff --git a/src/me/taylorkelly/mywarp/Converter.java b/src/me/taylorkelly/mywarp/Converter.java deleted file mode 100644 index 49148c0c51..0000000000 --- a/src/me/taylorkelly/mywarp/Converter.java +++ /dev/null @@ -1,84 +0,0 @@ -package me.taylorkelly.mywarp; - -import java.io.File; -import java.io.FileNotFoundException; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.Scanner; -import java.util.logging.Level; - -import org.bukkit.*; - -public class Converter { - - public static void convert(Player player, Server server, WarpList lister) { - File file = new File("warps.txt"); - Connection conn = null; - PreparedStatement ps = null; - try { - Class.forName("org.sqlite.JDBC"); - conn = DriverManager.getConnection(WarpDataSource.DATABASE); - ps = conn - .prepareStatement("INSERT INTO warpTable (id, name, creator, world, x, y, z, yaw, pitch, publicAll, permissions, welcomeMessage) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"); - - Scanner scanner = new Scanner(file); - int size = 0; - while (scanner.hasNext()) { - String line = scanner.nextLine(); - if (line.equals("")) - continue; - String[] pieces = line.split(":"); - String name = pieces[0]; - double x = Double.parseDouble(pieces[1]); - double y = Double.parseDouble(pieces[2]); - double z = Double.parseDouble(pieces[3]); - double yaw = Double.parseDouble(pieces[4]); - double pitch = Double.parseDouble(pieces[5]); - - yaw = (yaw < 0) ? (360 + (yaw % 360)) : (yaw % 360); - - World world = server.getWorlds()[0]; - Location location = new Location(world, x, y, z, (float) yaw, (float) pitch); - Warp warp = new Warp(name, location); - lister.blindAdd(warp); - - ps.setInt(1, warp.index); - ps.setString(2, warp.name); - ps.setString(3, warp.creator); - ps.setInt(4, warp.world); - ps.setInt(5, warp.x); - ps.setInt(6, warp.y); - ps.setInt(7, warp.z); - ps.setInt(8, warp.yaw); - ps.setInt(9, warp.pitch); - ps.setBoolean(10, warp.publicAll); - ps.setString(11, warp.permissionsString()); - ps.setString(12, warp.welcomeMessage); - ps.addBatch(); - size++; - } - ps.executeBatch(); - file.delete(); - player.sendMessage("Successfully imported " + size + " warps."); - } catch (FileNotFoundException e) { - player.sendMessage(ChatColor.RED + "Error: 'warps.txt' doesn't exist."); - } catch (ClassNotFoundException e) { - player.sendMessage(ChatColor.RED + "Error: Cannot find SQLite library"); - } catch (SQLException e) { - player.sendMessage(ChatColor.RED + "Error: SQLite Exception"); - } finally { - try { - if (ps != null) { - ps.close(); - } - if (conn != null) - conn.close(); - } catch (SQLException ex) { - player.sendMessage(ChatColor.RED + "Error: SQLite Exception (on close)"); - } - } - } - -} diff --git a/src/me/taylorkelly/mywarp/Lister.java b/src/me/taylorkelly/mywarp/Lister.java deleted file mode 100644 index 84cda4a7f6..0000000000 --- a/src/me/taylorkelly/mywarp/Lister.java +++ /dev/null @@ -1,95 +0,0 @@ -package me.taylorkelly.mywarp; - -import java.util.ArrayList; - -import org.angelsl.minecraft.randomshit.fontwidth.MinecraftFontWidthCalculator; -import org.bukkit.ChatColor; -import org.bukkit.Player; - -public class Lister { - private WarpList warpList; - private Player player; - - private int maxPages; - private int page; - - private static final int WARPS_PER_PAGE = 8; - ArrayList sortedWarps; - - public Lister(WarpList warpList) { - this.warpList = warpList; - maxPages = (int)Math.ceil(warpList.getSize()/(double)WARPS_PER_PAGE); - } - - public void addPlayer(Player player) { - this.player = player; - } - - public void setPage(int page) { - this.page = page; - int start = (page-1)*WARPS_PER_PAGE; - sortedWarps = warpList.getSortedWarps(player, start, WARPS_PER_PAGE); - } - - public void list() { - String intro = "-------------------- Page " + page + "/" + maxPages + " --------------------"; - player.sendMessage(ChatColor.YELLOW + intro); - for(Warp warp: sortedWarps) { - String name = warp.name; - String creator = (warp.creator.equalsIgnoreCase(player.getName()))?"you":warp.creator; - int x = warp.x; - int y = warp.y; - int z = warp.z; - String color; - if(warp.playerIsCreator(player.getName())) { - color = ChatColor.AQUA.toString(); - } else if(warp.publicAll) { - color = ChatColor.GREEN.toString(); - } else { - color = ChatColor.RED.toString(); - } - - - String location = " @(" + x + ", " + y + ", " + z + ")"; - String creatorString = " by " + creator; - - //Find remaining length left - int left = MinecraftFontWidthCalculator.getStringWidth(intro) - MinecraftFontWidthCalculator.getStringWidth("''" + creatorString + location); - - int nameLength = MinecraftFontWidthCalculator.getStringWidth(name); - if(left > nameLength) { - name = "'" + name + "'" + ChatColor.WHITE + creatorString + whitespace(left - nameLength); - } else if (left < nameLength) { - name = "'" + substring(name, left) + "'" + ChatColor.WHITE + creatorString; - } - - player.sendMessage(color + name + location); - } - } - - /** - * Lob shit off that string till it fits. - */ - private String substring(String name, int left) { - while(MinecraftFontWidthCalculator.getStringWidth(name) > left) { - name = name.substring(0, name.length()-1); - } - return name; - } - - public int getMaxPages() { - return maxPages; - } - - public String whitespace(int length) { - int spaceWidth = MinecraftFontWidthCalculator.getStringWidth(" "); - - StringBuilder ret = new StringBuilder(); - - for(int i = 0; i < length; i+=spaceWidth) { - ret.append(" "); - } - - return ret.toString(); - } -} diff --git a/src/me/taylorkelly/mywarp/MyWarp.java b/src/me/taylorkelly/mywarp/MyWarp.java deleted file mode 100644 index 1b0ff235fd..0000000000 --- a/src/me/taylorkelly/mywarp/MyWarp.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.taylorkelly.mywarp; - -import java.io.File; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.bukkit.Server; -import org.bukkit.event.Event; -import org.bukkit.event.Event.Priority; -import org.bukkit.plugin.PluginDescriptionFile; -import org.bukkit.plugin.PluginLoader; -import org.bukkit.plugin.java.JavaPlugin; - -public class MyWarp extends JavaPlugin{ - private WMPlayerListener playerListener; - public final String name = this.getDescription().getName(); - public final String version = this.getDescription().getVersion(); - public MyWarp(PluginLoader pluginLoader, Server instance, PluginDescriptionFile desc, File plugin, ClassLoader cLoader) { - super(pluginLoader, instance, desc, plugin, cLoader); - } - - @Override - public void onDisable() {} - - @Override - public void onEnable() { - Logger log = Logger.getLogger("Minecraft"); - - if(new File("MyWarp").exists() && new File("MyWarp", "warps.db").exists()) { - updateFiles(); - } - - WarpList warpList = new WarpList(getServer()); - playerListener = new WMPlayerListener(this, warpList); - getServer().getPluginManager().registerEvent(Event.Type.PLAYER_COMMAND, playerListener, Priority.Normal, this); - log.info(name + " " + version + " enabled"); - } - - private void updateFiles() { - File file = new File("MyWarp", "warps.db"); - File folder = new File("MyWarp"); - file.renameTo(new File("homes-warps.db")); - folder.delete(); - } - -} diff --git a/src/me/taylorkelly/mywarp/Searcher.java b/src/me/taylorkelly/mywarp/Searcher.java deleted file mode 100644 index 2c12d105f2..0000000000 --- a/src/me/taylorkelly/mywarp/Searcher.java +++ /dev/null @@ -1,87 +0,0 @@ -package me.taylorkelly.mywarp; - -import java.util.ArrayList; - -import org.angelsl.minecraft.randomshit.fontwidth.MinecraftFontWidthCalculator; -import org.bukkit.ChatColor; -import org.bukkit.Player; - -public class Searcher { - private WarpList warpList; - private Player player; - - private ArrayList exactMatches; - private ArrayList matches; - - private String query; - - public Searcher(WarpList warpList) { - this.warpList = warpList; - } - - public void addPlayer(Player player) { - this.player = player; - } - - public void setQuery(String name) { - this.query = name; - MatchList matches = warpList.getMatches(name, player); - this.exactMatches = matches.exactMatches; - this.matches = matches.matches; - - } - - public void search() { - - if (exactMatches.size() == 0 && matches.size() == 0) { - player.sendMessage(ChatColor.RED + "No warp matches for search: " + ChatColor.GRAY + query); - } else { - if (exactMatches.size() > 0) { - player.sendMessage(ChatColor.YELLOW + "Exact matches for search: " + ChatColor.GRAY + query); - for (Warp warp : exactMatches) { - String color; - if (warp.playerIsCreator(player.getName())) { - color = ChatColor.AQUA.toString(); - } else if (warp.publicAll) { - color = ChatColor.GREEN.toString(); - } else { - color = ChatColor.RED.toString(); - } - String creator = (warp.creator.equalsIgnoreCase(player.getName())) ? "you" : warp.creator; - int x = warp.x; - int y = warp.y; - int z = warp.z; - player.sendMessage(color + "'" + warp.name + "'" + ChatColor.WHITE + " by " + creator + " @(" + x + ", " + y + ", " + z + ")"); - } - } - if (matches.size() > 0) { - player.sendMessage(ChatColor.YELLOW + "Partial matches for search: " + ChatColor.GRAY + query); - for (Warp warp : matches) { - String color; - if (warp.playerIsCreator(player.getName())) { - color = ChatColor.AQUA.toString(); - } else if (warp.publicAll) { - color = ChatColor.GREEN.toString(); - } else { - color = ChatColor.RED.toString(); - } - String creator = (warp.creator.equalsIgnoreCase(player.getName())) ? "you" : warp.creator; - int x = warp.x; - int y = warp.y; - int z = warp.z; - player.sendMessage(color + "'" + warp.name + "'" + ChatColor.WHITE + " by " + creator + " @(" + x + ", " + y + ", " + z + ")"); - } - } - } - } -} - -class MatchList { - public MatchList(ArrayList exactMatches, ArrayList matches) { - this.exactMatches = exactMatches; - this.matches = matches; - } - - public ArrayList exactMatches; - public ArrayList matches; -} diff --git a/src/me/taylorkelly/mywarp/WMPlayerListener.java b/src/me/taylorkelly/mywarp/WMPlayerListener.java deleted file mode 100644 index 8ff3db87a1..0000000000 --- a/src/me/taylorkelly/mywarp/WMPlayerListener.java +++ /dev/null @@ -1,184 +0,0 @@ -package me.taylorkelly.mywarp; - -import org.bukkit.ChatColor; -import org.bukkit.Player; -import org.bukkit.event.player.PlayerChatEvent; -import org.bukkit.event.player.PlayerListener; -import org.bukkit.plugin.Plugin; - -public class WMPlayerListener extends PlayerListener { - private boolean warning; - private Plugin plugin; - private WarpList warpList; - - public WMPlayerListener(Plugin plugin, WarpList warpList) { - warning = false; - this.plugin = plugin; - this.warpList = warpList; - } - - public void onPlayerCommand(PlayerChatEvent event) { - String[] split = event.getMessage().split(" "); - Player player = event.getPlayer(); - - // TODO permissions - if (split[0].equalsIgnoreCase("/warp")) { - event.setCancelled(true); - /** - * /warp convert - */ - if (split.length == 2 && split[1].equalsIgnoreCase("convert")) { - if (!warning) { - player.sendMessage(ChatColor.RED + "Warning: " + ChatColor.WHITE + "Only use a copy of warps.txt."); - player.sendMessage("This will delete the warps.txt it uses"); - player.sendMessage("Use " + ChatColor.RED + "'/warp convert'" + ChatColor.WHITE + " again to confirm."); - warning = true; - } else { - Converter.convert(player, plugin.getServer(), warpList); - warning = false; - } - /** - * /warp list or /warp list # - */ - } else if ((split.length == 2 || (split.length == 3 && isInteger(split[2]))) && split[1].equalsIgnoreCase("list")) { - Lister lister = new Lister(warpList); - lister.addPlayer(player); - - if(split.length == 3) { - int page = Integer.parseInt(split[2]); - if(page < 1) { - player.sendMessage(ChatColor.RED + "Page number can't be below 1."); - return; - } else if(page > lister.getMaxPages()) { - player.sendMessage(ChatColor.RED + "There are only " + lister.getMaxPages() + " pages of warps"); - return; - } - lister.setPage(page); - } else { - lister.setPage(1); - } - lister.list(); - /** - * /warp search - */ - } else if (split.length > 2 && split[1].equalsIgnoreCase("search")) { - String name = ""; - for (int i = 2; i < split.length; i++) { - name += split[i]; - if (i + 1 < split.length) - name += " "; - } - - Searcher searcher = new Searcher(warpList); - searcher.addPlayer(player); - searcher.setQuery(name); - searcher.search(); - /** - * /warp create - */ - } else if (split.length > 2 && split[1].equalsIgnoreCase("create")) { - String name = ""; - for (int i = 2; i < split.length; i++) { - name += split[i]; - if (i + 1 < split.length) - name += " "; - } - - warpList.addWarp(name, player); - /** - * /warp delete - */ - } else if (split.length > 2 && split[1].equalsIgnoreCase("delete")) { - String name = ""; - for (int i = 2; i < split.length; i++) { - name += split[i]; - if (i + 1 < split.length) - name += " "; - } - - warpList.deleteWarp(name, player); - /** - * /warp private - */ - } else if (split.length > 2 && split[1].equalsIgnoreCase("private")) { - String name = ""; - for (int i = 2; i < split.length; i++) { - name += split[i]; - if (i + 1 < split.length) - name += " "; - } - - warpList.privatize(name, player); - /** - * /warp public - */ - } else if (split.length > 2 && split[1].equalsIgnoreCase("public")) { - String name = ""; - for (int i = 2; i < split.length; i++) { - name += split[i]; - if (i + 1 < split.length) - name += " "; - } - - warpList.publicize(name, player); - /** - * /warp invite - */ - } else if (split.length > 3 && split[1].equalsIgnoreCase("invite")) { - Player invitee = plugin.getServer().getPlayer(split[2]); - // TODO Change to matchPlayer - String inviteeName = (invitee == null) ? split[2] : invitee.getName(); - - String name = ""; - for (int i = 3; i < split.length; i++) { - name += split[i]; - if (i + 1 < split.length) - name += " "; - } - - warpList.invite(name, player, inviteeName); - /** - * /warp uninvite - */ - } else if (split.length > 3 && split[1].equalsIgnoreCase("uninvite")) { - Player invitee = plugin.getServer().getPlayer(split[2]); - // TODO Change to matchPlayer - String inviteeName = (invitee == null) ? split[2] : invitee.getName(); - - String name = ""; - for (int i = 3; i < split.length; i++) { - name += split[i]; - if (i + 1 < split.length) - name += " "; - } - - warpList.uninvite(name, player, inviteeName); - /** - * /warp - */ - } else if (split.length > 1) { - // TODO ChunkLoading - String name = ""; - for (int i = 1; i < split.length; i++) { - name += split[i]; - if (i + 1 < split.length) - name += " "; - } - - warpList.warpTo(name, player); - } else { - // TODO help? - player.sendMessage(ChatColor.RED + "Invalid /warp command"); - } - } - } - - public static boolean isInteger(String string) { - try { - Integer.parseInt(string); - } catch (Exception e) { - return false; - } - return true; - } -} diff --git a/src/me/taylorkelly/mywarp/Warp.java b/src/me/taylorkelly/mywarp/Warp.java deleted file mode 100644 index 2f794ff027..0000000000 --- a/src/me/taylorkelly/mywarp/Warp.java +++ /dev/null @@ -1,123 +0,0 @@ -package me.taylorkelly.mywarp; - -import java.util.ArrayList; - -import org.bukkit.*; - -public class Warp { - public int index; - public String name; - public String creator; - public int world; - public int x; - public int y; - public int z; - public int yaw; - public int pitch; - public boolean publicAll; - public String welcomeMessage; - public ArrayList permissions; - - public static int nextIndex = 1; - - public Warp(int index, String name, String creator, int world, int x, int y, int z, int yaw, int pitch, boolean publicAll, String permissions, String welcomeMessage) { - this.index = index; - this.name = name; - this.creator = creator; - this.world = world; - this.x = x; - this.y = y; - this.z = z; - this.pitch = pitch; - this.yaw = yaw; - this.publicAll = publicAll; - this.permissions = processList(permissions); - this.welcomeMessage = welcomeMessage; - if(index > nextIndex) nextIndex = index; - nextIndex++; - } - - public Warp(String name, Player creator) { - this.index = nextIndex; - nextIndex++; - this.name = name; - this.creator = creator.getName(); - //TODO better world handling - this.world = 0; - this.x = creator.getLocation().getBlockX(); - this.y = creator.getLocation().getBlockY(); - this.z = creator.getLocation().getBlockZ(); - this.yaw = Math.round(creator.getLocation().getYaw()); - this.pitch = Math.round(creator.getLocation().getPitch()); - this.publicAll = true; - this.permissions = new ArrayList(); - this.welcomeMessage = "Welcome to '" + name + "'"; - } - - public Warp(String name, Location location) { - this.index = nextIndex; - nextIndex++; - this.name = name; - this.creator = "No Player"; - //TODO better world handling - this.world = 0; - this.x = location.getBlockX(); - this.y = location.getBlockY(); - this.z = location.getBlockZ(); - this.yaw = Math.round(location.getYaw()); - this.pitch = Math.round(location.getPitch()); - this.publicAll = true; - this.permissions = new ArrayList(); - this.welcomeMessage = "Welcome to '" + name + "'"; - } - - - private ArrayList processList(String permissions) { - String[] names = permissions.split(","); - ArrayList ret = new ArrayList(); - for(String name: names) { - if(name.equals("")) continue; - ret.add(name.trim()); - } - return ret; - } - - public String permissionsString() { - StringBuilder ret = new StringBuilder(); - for(String name: permissions) { - ret.append(name); - ret.append(","); - } - return ret.toString(); - } - - public boolean playerCanWarp(String player) { - if(creator.equals(player)) return true; - if(permissions.contains(player)) return true; - return publicAll; - } - - public void warp(Player player) { - //Better world support - World world = player.getWorld(); - Location location = new Location(world, x, y, z, yaw, pitch); - player.teleportTo(location); - } - - public boolean playerIsCreator(String name) { - if(creator.equals(name)) return true; - return false; - } - - public void invite(String player) { - permissions.add(player); - } - - public boolean playerIsInvited(String player) { - return permissions.contains(player); - } - - public void uninvite(String inviteeName) { - permissions.remove(inviteeName); - } -} diff --git a/src/me/taylorkelly/mywarp/WarpDataSource.java b/src/me/taylorkelly/mywarp/WarpDataSource.java deleted file mode 100644 index 37cec365ab..0000000000 --- a/src/me/taylorkelly/mywarp/WarpDataSource.java +++ /dev/null @@ -1,273 +0,0 @@ -package me.taylorkelly.mywarp; - -import java.io.File; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashMap; -import java.util.logging.Level; -import java.util.logging.Logger; - - -public class WarpDataSource { - public final static String DATABASE = "jdbc:sqlite:homes-warps.db"; - private final static String WARP_TABLE = "CREATE TABLE `warpTable` (" + "`id` INTEGER PRIMARY KEY," + "`name` varchar(32) NOT NULL DEFAULT 'warp'," - + "`creator` varchar(32) NOT NULL DEFAULT 'Player'," + "`world` tinyint NOT NULL DEFAULT '0'," + "`x` int NOT NULL DEFAULT '0'," - + "`y` tinyint NOT NULL DEFAULT '0'," + "`z` int NOT NULL DEFAULT '0'," + "`yaw` smallint NOT NULL DEFAULT '0'," + "`pitch` smallint NOT NULL DEFAULT '0'," + "`publicAll` boolean NOT NULL DEFAULT '1'," - + "`permissions` varchar(150) NOT NULL DEFAULT ''," + "`welcomeMessage` varchar(100) NOT NULL DEFAULT ''" +");"; - - public static void initialize() { - if (!tableExists()) { - createTable(); - } - } - - public static HashMap getMap() { - HashMap ret = new HashMap(); - Connection conn = null; - Statement statement = null; - ResultSet set = null; - Logger log = Logger.getLogger("Minecraft"); - try { - Class.forName("org.sqlite.JDBC"); - conn = DriverManager.getConnection(DATABASE); - - statement = conn.createStatement(); - set = statement - .executeQuery("SELECT * FROM warpTable"); - int size = 0; - while (set.next()) { - size++; - int index = set.getInt("id"); - String name = set.getString("name"); - String creator = set.getString("creator"); - int world = set.getInt("world"); - int x = set.getInt("x"); - int y = set.getInt("y"); - int z = set.getInt("z"); - int yaw = set.getInt("yaw"); - int pitch = set.getInt("pitch"); - boolean publicAll = set.getBoolean("publicAll"); - String permissions = set.getString("permissions"); - String welcomeMessage = set.getString("welcomeMessage"); - Warp warp = new Warp(index, name, creator, world, x, y, z, yaw, pitch, publicAll, permissions, welcomeMessage); - ret.put(name, warp); - } - log.info("[MYWARP]: " + size + " warps loaded"); - } catch (SQLException ex) { - log.log(Level.SEVERE, "[MYWARP]: Warp Load Exception"); - } catch (ClassNotFoundException e) { - log.log(Level.SEVERE, "[MYWARP]: Error loading org.sqlite.JDBC"); - } finally { - try { - if (statement != null) - statement.close(); - if (set != null) - set.close(); - if (conn != null) - conn.close(); - } catch (SQLException ex) { - log.log(Level.SEVERE, "[MYWARP]: Warp Load Exception (on close)"); - } - } - return ret; - } - - private static boolean tableExists() { - Connection conn = null; - ResultSet rs = null; - try { - Class.forName("org.sqlite.JDBC"); - conn = DriverManager.getConnection(DATABASE); - DatabaseMetaData dbm = conn.getMetaData(); - rs = dbm.getTables(null, null, "warpTable", null); - if (!rs.next()) - return false; - return true; - } catch (SQLException ex) { - Logger log = Logger.getLogger("Minecraft"); - log.log(Level.SEVERE, "[MYWARP]: Table Check Exception", ex); - return false; - } catch (ClassNotFoundException e) { - Logger log = Logger.getLogger("Minecraft"); - log.log(Level.SEVERE, "[MYWARP]: Error loading org.sqlite.JDBC"); - return false; - } finally { - try { - if (rs != null) - rs.close(); - if (conn != null) - conn.close(); - } catch (SQLException ex) { - Logger log = Logger.getLogger("Minecraft"); - log.log(Level.SEVERE, "[MYWARP]: Table Check SQL Exception (on closing)"); - } - } - } - - private static void createTable() { - Connection conn = null; - Statement st = null; - try { - Class.forName("org.sqlite.JDBC"); - conn = DriverManager.getConnection(DATABASE); - st = conn.createStatement(); - st.executeUpdate(WARP_TABLE); - } catch (SQLException e) { - Logger log = Logger.getLogger("Minecraft"); - log.log(Level.SEVERE, "[MYWARP]: Create Table Exception", e); - } catch (ClassNotFoundException e) { - Logger log = Logger.getLogger("Minecraft"); - log.log(Level.SEVERE, "[MYWARP]: Error loading org.sqlite.JDBC"); - } finally { - try { - if (conn != null) - conn.close(); - if (st != null) - st.close(); - } catch (SQLException e) { - Logger log = Logger.getLogger("Minecraft"); - log.log(Level.SEVERE, "[MYWARP]: Could not create the table (on close)"); - } - } - } - - public static void addWarp(Warp warp) { - Connection conn = null; - PreparedStatement ps = null; - Logger log = Logger.getLogger("Minecraft"); - try { - Class.forName("org.sqlite.JDBC"); - conn = DriverManager.getConnection(DATABASE); - - ps = conn.prepareStatement("INSERT INTO warpTable (id, name, creator, world, x, y, z, yaw, pitch, publicAll, permissions, welcomeMessage) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"); - ps.setInt(1, warp.index); - ps.setString(2, warp.name); - ps.setString(3, warp.creator); - ps.setInt(4, warp.world); - ps.setInt(5, warp.x); - ps.setInt(6, warp.y); - ps.setInt(7, warp.z); - ps.setInt(8, warp.yaw); - ps.setInt(9, warp.pitch); - ps.setBoolean(10, warp.publicAll); - ps.setString(11, warp.permissionsString()); - ps.setString(12, warp.welcomeMessage); - ps.executeUpdate(); - } catch (SQLException ex) { - log.log(Level.SEVERE, "[MYWARP]: Warp Insert Exception", ex); - } catch (ClassNotFoundException e) { - log.log(Level.SEVERE, "[MYWARP]: Error loading org.sqlite.JDBC"); - } finally { - try { - if (ps != null) { - ps.close(); - } - if (conn != null) - conn.close(); - } catch (SQLException ex) { - log.log(Level.SEVERE, "[MYWARP]: Warp Insert Exception (on close)", ex); - } - } - } - - public static void deleteWarp(Warp warp) { - Connection conn = null; - PreparedStatement ps = null; - ResultSet set = null; - Logger log = Logger.getLogger("Minecraft"); - try { - Class.forName("org.sqlite.JDBC"); - conn = DriverManager.getConnection(DATABASE); - ps = conn.prepareStatement("DELETE FROM warpTable WHERE id = ?"); - ps.setInt(1, warp.index); - ps.executeUpdate(); - } catch (SQLException ex) { - log.log(Level.SEVERE, "[MYWARP]: Warp Delete Exception", ex); - } catch (ClassNotFoundException e) { - log.log(Level.SEVERE, "[MYWARP]: Error loading org.sqlite.JDBC"); - } finally { - try { - if (ps != null) { - ps.close(); - } - if (set != null) { - set.close(); - } - if (conn != null) - conn.close(); - } catch (SQLException ex) { - log.log(Level.SEVERE, "[MYWARP]: Warp Delete Exception (on close)", ex); - } - } - } - - public static void publicizeWarp(Warp warp, boolean publicAll) { - Connection conn = null; - PreparedStatement ps = null; - ResultSet set = null; - Logger log = Logger.getLogger("Minecraft"); - try { - Class.forName("org.sqlite.JDBC"); - conn = DriverManager.getConnection(DATABASE); - ps = conn.prepareStatement("UPDATE warpTable SET publicAll = ? WHERE id = ?"); - ps.setBoolean(1, publicAll); - ps.setInt(2, warp.index); - ps.executeUpdate(); - } catch (SQLException ex) { - log.log(Level.SEVERE, "[MYWARP]: Warp Publicize Exception", ex); - } catch (ClassNotFoundException e) { - log.log(Level.SEVERE, "[MYWARP]: Error loading org.sqlite.JDBC"); - } finally { - try { - if (ps != null) { - ps.close(); - } - if (set != null) { - set.close(); - } - if (conn != null) - conn.close(); - } catch (SQLException ex) { - log.log(Level.SEVERE, "[MYWARP]: Warp Publicize Exception (on close)", ex); - } - } - } - - public static void updatePermissions(Warp warp) { - Connection conn = null; - PreparedStatement ps = null; - ResultSet set = null; - Logger log = Logger.getLogger("Minecraft"); - try { - Class.forName("org.sqlite.JDBC"); - conn = DriverManager.getConnection(DATABASE); - ps = conn.prepareStatement("UPDATE warpTable SET permissions = ? WHERE id = ?"); - ps.setString(1, warp.permissionsString()); - ps.setInt(2, warp.index); - ps.executeUpdate(); - } catch (SQLException ex) { - log.log(Level.SEVERE, "[MYWARP]: Warp Permissions Exception", ex); - } catch (ClassNotFoundException e) { - log.log(Level.SEVERE, "[MYWARP]: Error loading org.sqlite.JDBC"); - } finally { - try { - if (ps != null) { - ps.close(); - } - if (set != null) { - set.close(); - } - if (conn != null) - conn.close(); - } catch (SQLException ex) { - log.log(Level.SEVERE, "[MYWARP]: Warp Permissions Exception (on close)", ex); - } - } - } - -} diff --git a/src/me/taylorkelly/mywarp/WarpList.java b/src/me/taylorkelly/mywarp/WarpList.java deleted file mode 100644 index e530dea69a..0000000000 --- a/src/me/taylorkelly/mywarp/WarpList.java +++ /dev/null @@ -1,208 +0,0 @@ -package me.taylorkelly.mywarp; - -import java.text.Collator; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; - -import org.bukkit.*; - -public class WarpList { - private HashMap warpList; - private Server server; - - public WarpList(Server server) { - this.server = server; - WarpDataSource.initialize(); - warpList = WarpDataSource.getMap(); - } - - public void addWarp(String name, Player player) { - if (warpList.containsKey(name)) { - player.sendMessage(ChatColor.RED + "Warp called '" + name + "' already exists."); - } else { - Warp warp = new Warp(name, player); - warpList.put(name, warp); - WarpDataSource.addWarp(warp); - player.sendMessage(ChatColor.AQUA + "Successfully created '" + name + "'"); - player.sendMessage("If you'd like to privatize it,"); - player.sendMessage("Use: " + ChatColor.RED + "/warp private " + name); - } - } - - public void blindAdd(Warp warp) { - warpList.put(warp.name, warp); - } - - public void warpTo(String name, Player player) { - if (warpList.containsKey(name)) { - Warp warp = warpList.get(name); - if (warp.playerCanWarp(player.getName())) { - warp.warp(player); - player.sendMessage(ChatColor.AQUA + warp.welcomeMessage); - } else { - player.sendMessage(ChatColor.RED + "You do not have permission to warp to '" + name + "'"); - } - } else { - player.sendMessage(ChatColor.RED + "No such warp '" + name + "'"); - } - } - - public void deleteWarp(String name, Player player) { - if (warpList.containsKey(name)) { - Warp warp = warpList.get(name); - if (warp.playerIsCreator(player.getName())) { - warpList.remove(name); - WarpDataSource.deleteWarp(warp); - player.sendMessage(ChatColor.AQUA + "You have deleted '" + name + "'"); - } else { - player.sendMessage(ChatColor.RED + "You do not have permission to delete '" + name + "'"); - } - } else { - player.sendMessage(ChatColor.RED + "No such warp '" + name + "'"); - } - } - - public void privatize(String name, Player player) { - if (warpList.containsKey(name)) { - Warp warp = warpList.get(name); - if (warp.playerIsCreator(player.getName())) { - warp.publicAll = false; - WarpDataSource.publicizeWarp(warp, false); - player.sendMessage(ChatColor.AQUA + "You have privatized '" + name + "'"); - player.sendMessage("If you'd like to invite others to it,"); - player.sendMessage("Use: " + ChatColor.RED + "/warp invite " + name); - } else { - player.sendMessage(ChatColor.RED + "You do not have permission to privatize '" + name + "'"); - } - } else { - player.sendMessage(ChatColor.RED + "No such warp '" + name + "'"); - } - } - - public void invite(String name, Player player, String inviteeName) { - if (warpList.containsKey(name)) { - Warp warp = warpList.get(name); - if (warp.playerIsCreator(player.getName())) { - if (warp.playerIsInvited(inviteeName)) { - player.sendMessage(ChatColor.RED + inviteeName + " is already invited to this warp."); - } else if(warp.playerIsCreator(inviteeName)) { - player.sendMessage(ChatColor.RED + inviteeName + " is the creator, of course he's the invited!"); - }else { - warp.invite(inviteeName); - WarpDataSource.updatePermissions(warp); - player.sendMessage(ChatColor.AQUA + "You have invited " + inviteeName + " to '" + name + "'"); - if (warp.publicAll) { - player.sendMessage(ChatColor.RED + "But '" + name + "' is still public."); - } - Player match = server.getPlayer(inviteeName); - if (match != null) { - match.sendMessage(ChatColor.AQUA + "You've been invited to warp '" + name + "' by " + player.getName()); - match.sendMessage("Use: " + ChatColor.RED + "/warp " + name + ChatColor.WHITE + " to warp to it."); - } - } - } else { - player.sendMessage(ChatColor.RED + "You do not have permission to invite players to '" + name + "'"); - } - } else { - player.sendMessage(ChatColor.RED + "No such warp '" + name + "'"); - } - } - - public void publicize(String name, Player player) { - if (warpList.containsKey(name)) { - Warp warp = warpList.get(name); - if (warp.playerIsCreator(player.getName())) { - warp.publicAll = true; - WarpDataSource.publicizeWarp(warp, true); - player.sendMessage(ChatColor.AQUA + "You have publicized '" + name + "'"); - } else { - player.sendMessage(ChatColor.RED + "You do not have permission to publicize '" + name + "'"); - } - } else { - player.sendMessage(ChatColor.RED + "No such warp '" + name + "'"); - } - } - - public void uninvite(String name, Player player, String inviteeName) { - if (warpList.containsKey(name)) { - Warp warp = warpList.get(name); - if (warp.playerIsCreator(player.getName())) { - if (!warp.playerIsInvited(inviteeName)) { - player.sendMessage(ChatColor.RED + inviteeName + " is not invited to this warp."); - } else if (warp.playerIsCreator(inviteeName)) { - player.sendMessage(ChatColor.RED + "You can't uninvite yourself. You're the creator!"); - } else { - warp.uninvite(inviteeName); - WarpDataSource.updatePermissions(warp); - player.sendMessage(ChatColor.AQUA + "You have uninvited " + inviteeName + " from '" + name + "'"); - if (warp.publicAll) { - player.sendMessage(ChatColor.RED + "But '" + name + "' is still public."); - } - Player match = server.getPlayer(inviteeName); - if (match != null) { - match.sendMessage(ChatColor.RED + "You've been uninvited to warp '" + name + "' by " + player.getName() + ". Sorry."); - } - } - } else { - player.sendMessage(ChatColor.RED + "You do not have permission to uninvite players from '" + name + "'"); - } - } else { - player.sendMessage(ChatColor.RED + "No such warp '" + name + "'"); - } - } - - public ArrayList getSortedWarps(Player player, int start, int size) { - ArrayList ret = new ArrayList(); - List names = new ArrayList(warpList.keySet()); - Collator collator = Collator.getInstance(); - collator.setStrength(Collator.SECONDARY); - Collections.sort(names, collator); - - int index = 0; - int currentCount = 0; - while(index < names.size() && ret.size() < size) { - String currName = names.get(index); - Warp warp = warpList.get(currName); - if(warp.playerCanWarp(player.getName())) { - if(currentCount >= start) { - ret.add(warp); - } else { - currentCount++; - } - } - index++; - } - return ret; - } - - public int getSize() { - return warpList.size(); - } - - - public MatchList getMatches(String name, Player player) { - ArrayList exactMatches = new ArrayList(); - ArrayList matches = new ArrayList(); - - List names = new ArrayList(warpList.keySet()); - Collator collator = Collator.getInstance(); - collator.setStrength(Collator.SECONDARY); - Collections.sort(names, collator); - - for(int i = 0; i < names.size(); i++) { - String currName = names.get(i); - Warp warp = warpList.get(currName); - if(warp.playerCanWarp(player.getName())) { - if(warp.name.equalsIgnoreCase(name)) { - exactMatches.add(warp); - } else if(warp.name.toLowerCase().contains(name.toLowerCase())) { - matches.add(warp); - } - } - } - return new MatchList(exactMatches, matches); - } -} diff --git a/src/plugin.yml b/src/plugin.yml deleted file mode 100644 index 6251c89a98..0000000000 --- a/src/plugin.yml +++ /dev/null @@ -1,3 +0,0 @@ -name: MyWarp -version: 1.4 -main: me.taylorkelly.mywarp.MyWarp \ No newline at end of file diff --git a/todo b/todo new file mode 100644 index 0000000000..0f4a1b7138 --- /dev/null +++ b/todo @@ -0,0 +1,41 @@ +== DONE == + +3.0.1 + - command to set cooldown/warmup of warps + +3.0.2 + - fix search command + +3.1.0 + - dynmap marker support + - Set the default message in the settings + - default selected columns + - Move warps/wpas into other world + - list options could be added/removed + +3.1.5 + - Permission to show own unlisted warps. + - Check permission "change owner" if create warp with other owner (done) + - All world permissions are now by default true. + - Info command shows if the warp is (not) listed. + +== TO BE DONE == + +3.2.0 + - wpa list command + - Export hmod compatible warps + - auto completion + - pay only difference for change visibility (maybe 3.1.0) + - default warping price for a warp + - Permissions pools (like xwarp.warp.edit.default) with BPU 1.3.0 + +3.3.0 + - regex parameter for warp list + - warp list like options for warp search + - command to remove all warps matching specific options (options like in /w ls) + - info in the list to show if a warp is save + +Undetermined + - separated permission for warp.create.private.set/warp.create.private.change + - (Un)Register editor permissions (xwarp..edit.object.*) (Actually not needed, as it's default is false) + - Fall through test