From 2e8372e74fcff82a508637a842c2b24ea3a0d25a Mon Sep 17 00:00:00 2001 From: Paul Schulze Date: Tue, 4 Jun 2013 20:29:47 +0200 Subject: [PATCH] On the way to 2.0! Added CircBorder and made it possible to implement more different border types. Still some bugs especially with the display of the border message! --- pom.xml | 8 +- scripts/test-deployment.sh | 6 +- .../de/craftinc/borderprotection/Border.java | 153 --------------- .../borderprotection/BorderManager.java | 172 ---------------- .../craftinc/borderprotection/Commands.java | 82 ++++++-- .../craftinc/borderprotection/Messages.java | 85 ++++++-- .../borderprotection/PlayerMoveListener.java | 128 ------------ .../de/craftinc/borderprotection/Plugin.java | 25 ++- .../borderprotection/borders/Border.java | 125 ++++++++++++ .../borderprotection/borders/CircBorder.java | 123 ++++++++++++ .../borderprotection/borders/RectBorder.java | 183 ++++++++++++++++++ .../{ => events}/PlayerLoginListener.java | 7 +- .../events/PlayerMoveListener.java | 90 +++++++++ .../{ => events}/PlayerTeleportListener.java | 35 ++-- .../LocationSerializer2D.java} | 21 +- .../util/PlayerMovementUtil.java | 45 +++++ .../{ => util}/UpdateHelper.java | 20 +- src/main/resources/plugin.yml | 4 +- 18 files changed, 753 insertions(+), 559 deletions(-) delete mode 100644 src/main/java/de/craftinc/borderprotection/Border.java delete mode 100644 src/main/java/de/craftinc/borderprotection/BorderManager.java delete mode 100644 src/main/java/de/craftinc/borderprotection/PlayerMoveListener.java create mode 100644 src/main/java/de/craftinc/borderprotection/borders/Border.java create mode 100644 src/main/java/de/craftinc/borderprotection/borders/CircBorder.java create mode 100644 src/main/java/de/craftinc/borderprotection/borders/RectBorder.java rename src/main/java/de/craftinc/borderprotection/{ => events}/PlayerLoginListener.java (89%) create mode 100644 src/main/java/de/craftinc/borderprotection/events/PlayerMoveListener.java rename src/main/java/de/craftinc/borderprotection/{ => events}/PlayerTeleportListener.java (71%) rename src/main/java/de/craftinc/borderprotection/{LocationSerializer.java => util/LocationSerializer2D.java} (82%) create mode 100644 src/main/java/de/craftinc/borderprotection/util/PlayerMovementUtil.java rename src/main/java/de/craftinc/borderprotection/{ => util}/UpdateHelper.java (83%) diff --git a/pom.xml b/pom.xml index 0e7ff9c..ee37bb8 100644 --- a/pom.xml +++ b/pom.xml @@ -4,14 +4,16 @@ 4.0.0 de.craftinc CraftincBorderProtection + Craft Inc. BorderProtection jar - 1.1.1 + 2.0-beta UTF-8 + ${project.name} ${project.version} src/main/resources @@ -57,14 +59,14 @@ org.bukkit bukkit - 1.5-R0.1-SNAPSHOT + 1.5.2-R0.1 jar compile org.bukkit craftbukkit - 1.5-R0.1-SNAPSHOT + 1.5.2-R0.1 jar compile diff --git a/scripts/test-deployment.sh b/scripts/test-deployment.sh index 8c5b9d3..6cbb457 100755 --- a/scripts/test-deployment.sh +++ b/scripts/test-deployment.sh @@ -6,15 +6,15 @@ BUKKIT_DIR="$SCRIPT_DIR/../bukkit-testserver" PLUGIN_DIR="$SCRIPT_DIR/../bukkit-testserver/plugins" # TODO: This is a bad solution! Maven should write necessary information into an extra file. -ARTIFACT_ID="$(grep -C3 'de.craftinc' "$SCRIPT_DIR/../pom.xml" | grep '' | sed 's/\s*//g' | sed 's/<\/artifactId>\s*//g')" +ARTIFACT_ID="$(grep -C5 'de.craftinc' "$SCRIPT_DIR/../pom.xml" | grep '' | sed 's/\s*//g' | sed 's/<\/name>\s*//g')" # TODO: This is a bad solution! Maven should write necessary information into an extra file. -VERSION="$(grep -C3 'de.craftinc' "$SCRIPT_DIR/../pom.xml" | grep '' | sed 's/\s*//g' | sed 's/<\/version>\s*//g')" +VERSION="$(grep -C5 'de.craftinc' "$SCRIPT_DIR/../pom.xml" | grep '' | sed 's/\s*//g' | sed 's/<\/version>\s*//g')" mkdir -p "$PLUGIN_DIR" -cp "$SCRIPT_DIR/../target/$ARTIFACT_ID-$VERSION".jar "$PLUGIN_DIR/$ARTIFACT_ID".jar +cp "$SCRIPT_DIR/../target/$ARTIFACT_ID $VERSION".jar "$PLUGIN_DIR/" echo -e "ddidderr\nmice_on_drugs\nMochaccino" > "$BUKKIT_DIR/ops.txt" diff --git a/src/main/java/de/craftinc/borderprotection/Border.java b/src/main/java/de/craftinc/borderprotection/Border.java deleted file mode 100644 index 47f5485..0000000 --- a/src/main/java/de/craftinc/borderprotection/Border.java +++ /dev/null @@ -1,153 +0,0 @@ -/* Craft Inc. BorderProtection - Copyright (C) 2013 Paul Schulze, Tobias Ottenweller - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -package de.craftinc.borderprotection; - -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.configuration.serialization.ConfigurationSerializable; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -public class Border implements ConfigurationSerializable -{ - private static final String dataFileName = "borders.yml"; - - - private Boolean isActive; - private static String isActiveKey = "enabled"; - - private Location rectPoint1; - private static String rectPoint1Name = "p1"; - - private Location rectPoint2; - private static String rectPoint2Name = "p2"; - - - private static String rectBordersKey = "rectBorders"; - - private static final HashMap borders = new HashMap(); - - private static File bordersFile = new File(Plugin.getPlugin().getDataFolder(), dataFileName); - private static FileConfiguration bordersFileConf = YamlConfiguration.loadConfiguration(bordersFile); - - public static HashMap getBorders() - { - return borders; - } - - public Location getRectPoint1() - { - return rectPoint1; - } - - public Location getRectPoint2() - { - return rectPoint2; - } - - public Boolean isActive() - { - return isActive; - } - - @SuppressWarnings("unchecked unused") - public Border( Map map ) - { - try - { - rectPoint1 = LocationSerializer.deserializeLocation((Map) map.get(rectPoint1Name)); - rectPoint2 = LocationSerializer.deserializeLocation((Map) map.get(rectPoint2Name)); - - isActive = (Boolean) map.get(isActiveKey); - - if ( rectPoint1.getWorld().equals(rectPoint2.getWorld()) ) - { - borders.put(rectPoint1.getWorld(), this); - } - else - { - throw new Exception("Border points are at different worlds."); - } - } - catch ( Exception e ) - { - Plugin.getPlugin().getLogger().severe(e.getMessage()); - } - } - - public Border( Location p1, Location p2 ) throws Exception - { - rectPoint1 = p1; - rectPoint2 = p2; - - // new border is active by default - isActive = true; - - if ( rectPoint1.getWorld().equals(rectPoint2.getWorld()) ) - { - borders.put(rectPoint1.getWorld(), this); - } - else - { - throw new Exception("Border points are at different worlds."); - } - } - - - @SuppressWarnings("unused") - public Map serialize() - { - Map map = new HashMap(); - map.put(rectPoint1Name, LocationSerializer.serializeLocation(rectPoint1)); - map.put(rectPoint2Name, LocationSerializer.serializeLocation(rectPoint2)); - map.put(isActiveKey, isActive); - - return map; - } - - public static void loadBorders() - { - bordersFileConf.getList(rectBordersKey); - } - - public static void saveBorders() throws IOException - { - bordersFileConf.set(rectBordersKey, new ArrayList(borders.values())); - bordersFileConf.save(bordersFile); - } - - public String toString() - { - return rectPoint1.getX() + "," + rectPoint1.getZ() + " " + rectPoint2.getX() + "," + rectPoint2.getZ(); - } - - public void enable() - { - isActive = true; - } - - public void disable() - { - isActive = false; - } -} diff --git a/src/main/java/de/craftinc/borderprotection/BorderManager.java b/src/main/java/de/craftinc/borderprotection/BorderManager.java deleted file mode 100644 index 64f7e9b..0000000 --- a/src/main/java/de/craftinc/borderprotection/BorderManager.java +++ /dev/null @@ -1,172 +0,0 @@ -/* Craft Inc. BorderProtection - Copyright (C) 2013 Paul Schulze, Tobias Ottenweller - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -package de.craftinc.borderprotection; - -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Player; - -import java.util.Calendar; -import java.util.HashMap; - -public class BorderManager -{ - /** - * ********************************************************* - * GLOBAL VARIABLES - * ********************************************************** - */ - - - /** - * For every player save the time when he got the last borderMessage - */ - public HashMap lastBorderMessage = new HashMap(); - - /** - * The buffer in blocks which applies when a player is teleported inside the border. 0 means the player - * will be teleported directly to the border. - */ - public static final double buffer = 0.5; - - /** - * A timeout for the border message. When a player tries to cross the border and sees the border message, - * the earliest possible time the message will show up again is after timeout milliseconds. - */ - public static final Long timeout = 10000L; - - - /** - * ********************************************************* - * CONSTRUCTOR - * ********************************************************** - */ - public BorderManager() - { - // load borders - Border.loadBorders(); - } - - - /** - * ********************************************************* - * GETTERS AND SETTERS - * ********************************************************** - */ - - public void setBorder( World world, double border ) throws Exception - { - new Border(new Location(world, border, 0, border), new Location(world, -border, 0, -border)); - } - - public void setBorder( World world, String p1, String p2 ) throws Exception - { - - String[] coordinatesP1 = p1.split(","); - Location l1 = new Location(world, Double.parseDouble(coordinatesP1[0]), 0, Double.parseDouble(coordinatesP1[1])); - - String[] coordinatesP2 = p2.split(","); - Location l2 = new Location(world, Double.parseDouble(coordinatesP2[0]), 0, Double.parseDouble(coordinatesP2[1])); - - new Border(l1, l2); - } - - - /** - * Checks if the given location is inside the border rectangle. Returns null if yes, otherwise new coordinates. - * - * @param location location to check - * @param border Border object which defines the border - * @param buffer if the player will be teleported back, then he will be buffer far away - * from the border he tried to cross - * @return null if the player is inside, otherwise a new player location - */ - public Double[] checkBorder( Location location, Border border, double buffer ) - { - // New x and z: null by default - Double[] newXZ = { null, null }; - - // check if player is withing the X borders - newXZ[0] = _checkBorder(location.getX(), border.getRectPoint1().getX(), border.getRectPoint2().getX(), buffer); - // check if player is withing the Z borders - newXZ[1] = _checkBorder(location.getZ(), border.getRectPoint1().getZ(), border.getRectPoint2().getZ(), buffer); - - // Do nothing, if no new coordinates have been calculated. - if ( newXZ[0] == null && newXZ[1] == null ) - { - return null; - } - return newXZ; - } - - - /** - * Checks if the given location is between one specific border pair. - * - * @param location part of the location coordinates - * @param border1 one side of the rectangle - * @param border2 opposite side of the rectangle - * @return null if the location is inside, otherwise a new location - */ - public Double _checkBorder( double location, double border1, double border2, double buffer ) - { - double bigBorder = Math.max(border1, border2); - double smallBorder = Math.min(border1, border2); - - // if location is between borders do nothing - if ( location >= smallBorder && location <= bigBorder ) - { - return null; - } - else - { - if ( location > bigBorder ) - { - // if location is outside of the bigBorder, teleport to the bigBorder - return bigBorder - buffer; - } - else - { - // if location is outside of the smallBorder, teleport to the smallBorder - return smallBorder + buffer; - } - } - } - - - /** - * Show the border message to a player and respect the timeout. - * - * @param player Player who will see the border message. - */ - public void showMessageWithTimeout( Player player, String message ) - { - // get the current time - Long now = Calendar.getInstance().getTimeInMillis(); - - if ( ( lastBorderMessage.get(player.getName()) != null && - now - timeout > lastBorderMessage.get(player.getName()) ) || - lastBorderMessage.get(player.getName()) == null ) - { - // show message - player.sendMessage(message); - - // set last sent message for this player to now - lastBorderMessage.put(player.getName(), now); - } - } -} diff --git a/src/main/java/de/craftinc/borderprotection/Commands.java b/src/main/java/de/craftinc/borderprotection/Commands.java index 90dda38..c3d442c 100644 --- a/src/main/java/de/craftinc/borderprotection/Commands.java +++ b/src/main/java/de/craftinc/borderprotection/Commands.java @@ -16,6 +16,11 @@ */ package de.craftinc.borderprotection; +import de.craftinc.borderprotection.borders.Border; +import de.craftinc.borderprotection.borders.CircBorder; +import de.craftinc.borderprotection.borders.RectBorder; +import de.craftinc.borderprotection.util.UpdateHelper; +import org.bukkit.Location; import org.bukkit.World; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -26,13 +31,6 @@ import java.io.IOException; public class Commands implements CommandExecutor { - private BorderManager borderManager; - - public Commands( BorderManager borderManager ) - { - this.borderManager = borderManager; - } - @Override public boolean onCommand( CommandSender sender, Command command, String label, String[] args ) { @@ -77,7 +75,7 @@ public class Commands implements CommandExecutor } // set - if ( ( args.length == 2 || args.length == 3 ) && args[0].equalsIgnoreCase("set") ) + if ( ( args.length == 3 || args.length == 4 ) && args[0].equalsIgnoreCase("set") ) { if ( !sender.hasPermission("craftinc.borderprotection.set") ) { @@ -86,30 +84,72 @@ public class Commands implements CommandExecutor } World world = ( (Player) sender ).getWorld(); - // set - if ( args.length == 2 ) + // set [r|c] + if ( args.length == 3 ) { try { - borderManager.setBorder(( (Player) sender ).getWorld(), Double.parseDouble(args[1])); - Border border = Border.getBorders().get(world); - sender.sendMessage(Messages.borderCreationSuccessful); - sender.sendMessage(Messages.borderInfo(world.getName(), border.toString(), border.isActive())); + Double distance = Double.parseDouble(args[2]); + Border newBorder = null; + + // rect border + if ( args[1].equalsIgnoreCase("r") ) + { + newBorder = new RectBorder(new Location(world, distance, 0, distance), + new Location(world, -distance, 0, -distance)); + } + // circ border + else if ( args[1].equalsIgnoreCase("c") ) + { + newBorder = new CircBorder(new Location(world, 0, 0, 0), distance); + } + + if ( newBorder != null ) + { + sender.sendMessage(Messages.borderCreationSuccessful); + sender.sendMessage( + Messages.borderInfo(world.getName(), newBorder)); + } } catch ( Exception e ) { sender.sendMessage(e.getMessage()); } } - // set + // set r | set c
else { try { - borderManager.setBorder(( (Player) sender ).getWorld(), args[1], args[2]); - Border border = Border.getBorders().get(world); - sender.sendMessage(Messages.borderCreationSuccessful); - sender.sendMessage(Messages.borderInfo(world.getName(), border.toString(), border.isActive())); + Border newBorder = null; + + // rect border + if ( args[1].equalsIgnoreCase("r") ) + { + Double p1X = Double.parseDouble(args[2].split(",")[0]); + Double p1Z = Double.parseDouble(args[2].split(",")[1]); + Double p2X = Double.parseDouble(args[3].split(",")[0]); + Double p2Z = Double.parseDouble(args[3].split(",")[1]); + + newBorder = new RectBorder(new Location(world, p1X, 0, p1Z), + new Location(world, p2X, 0, p2Z)); + } + // circ border + else if ( args[1].equalsIgnoreCase("c") ) + { + Double centerX = Double.parseDouble(args[2].split(",")[0]); + Double centerZ = Double.parseDouble(args[2].split(",")[1]); + Double radius = Double.parseDouble(args[3]); + + newBorder = new CircBorder(new Location(world, centerX, 0, centerZ), radius); + } + + if ( newBorder != null ) + { + sender.sendMessage(Messages.borderCreationSuccessful); + sender.sendMessage( + Messages.borderInfo(world.getName(), newBorder)); + } } catch ( Exception e ) { @@ -143,7 +183,7 @@ public class Commands implements CommandExecutor Border border = Border.getBorders().get(world); - sender.sendMessage(Messages.borderInfo(world.getName(), border.toString(), border.isActive())); + sender.sendMessage(Messages.borderInfo(world.getName(), border)); return true; } @@ -177,7 +217,7 @@ public class Commands implements CommandExecutor sender.sendMessage(Messages.borderInfoNoBorderSet); } - // save the new border + // save the changed border try { Border.saveBorders(); diff --git a/src/main/java/de/craftinc/borderprotection/Messages.java b/src/main/java/de/craftinc/borderprotection/Messages.java index 610ffdb..d6e8faa 100644 --- a/src/main/java/de/craftinc/borderprotection/Messages.java +++ b/src/main/java/de/craftinc/borderprotection/Messages.java @@ -16,13 +16,23 @@ */ package de.craftinc.borderprotection; +import de.craftinc.borderprotection.borders.Border; import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import java.util.Calendar; +import java.util.HashMap; public class Messages { private static final String NEWLINE = "\n"; - private static final String pluginName = Plugin.getPlugin().getDescription().getName(); + private static final String pluginName = Plugin.instance.getDescription().getName(); + + /** + * For every player and every message of that player save the time when he got the last one. + */ + private static final HashMap> lastMessage = new HashMap>(); private static String makeCmd( String command, String explanation, String... args ) { @@ -60,21 +70,25 @@ public class Messages "strange new worlds, to seek out new life and new civilizations, to boldly go where no one has gone before."; public static String borderMessage = - "Sorry Dude! This is the border... the final frontier! " + borderExplanation + NEWLINE + + ChatColor.YELLOW + "Sorry Dude! " + + ChatColor.WHITE + "This is the border... the final frontier! " + borderExplanation + NEWLINE + makeCmd("/cibp get", "shows the borders of the current world"); public static String borderTeleportMessage = - "Sorry Dude! You cannot teleport outside the border. " + borderExplanation + NEWLINE + + ChatColor.YELLOW + "Sorry Dude! " + + ChatColor.WHITE + "You cannot teleport outside the border. " + borderExplanation + NEWLINE + makeCmd("/cibp get", "shows the borders of the current world"); public static String helpGeneral = ChatColor.GREEN + pluginName + " - Usage:" + NEWLINE + + ChatColor.WHITE + "Commands are always related to the current world." + NEWLINE + makeCmd("help", "shows this help") + - makeCmd("get | info", "shows the border of the current world") + - makeCmd("on | off", "enables/disables the border of the current world") + - makeCmd("set", "Border rectangle edges will be this far away from point of origin.", "") + - makeCmd("set", "Border rectangle is defined by the two points. A point is specified as: x,z", - "", "") + + makeCmd("get | info", "Shows information about the border.") + + makeCmd("on | off", "Enables/disables the border.") + + makeCmd("set", "Square border with distance (d) from 0,0.", "r", "") + + makeCmd("set", "Rectangle defined by two points. Point=x,z.", "r", "", "") + + makeCmd("set", "Circle border with radius from 0,0.", "c", "") + + makeCmd("set", "Circle defined by center and radius. Center=x,z.", "c", "", "") + makeCmd("checkversion", "Checks for a newer version."); public static String borderCreationSuccessful @@ -85,20 +99,17 @@ public class Messages public static String commandIssuedByNonPlayer = ChatColor.RED + "Only a player can use " + pluginName + " commands!"; - public static String borderInfo( String worldName, String borderDef, Boolean isBorderEnabled ) + public static String borderInfo( String worldName, Border border ) { String borderEnabled; - if (isBorderEnabled) - { + if ( border.isActive() ) borderEnabled = ChatColor.GREEN + "enabled"; - } else { + else borderEnabled = ChatColor.RED + "disabled"; - } - return ChatColor.WHITE + "Borders of world " + - ChatColor.YELLOW + worldName + - ChatColor.WHITE + ": " + - ChatColor.YELLOW + borderDef + ChatColor.WHITE + "." + NEWLINE + + return ChatColor.WHITE + "Border of world " + ChatColor.YELLOW + worldName + ChatColor.WHITE + ": " + NEWLINE + + ChatColor.YELLOW + "Type: " + ChatColor.WHITE + border.getBorderTypeString() + NEWLINE + + border.getBorderInfoString() + NEWLINE + ChatColor.WHITE + "Border is " + borderEnabled + ChatColor.WHITE + "."; } @@ -121,7 +132,8 @@ public class Messages ChatColor.RED + "Error: Could not save border on server. After the next reload this border will be lost!"; public static String borderEnableDisableException = - ChatColor.RED + "Error: Could not save border state on server. After the next reload this border state will be lost!"; + ChatColor.RED + + "Error: Could not save border state on server. After the next reload this border state will be lost!"; public static String updateMessage( String newVersion, String curVersion ) { @@ -129,10 +141,45 @@ public class Messages ChatColor.YELLOW + "Current version: " + ChatColor.WHITE + curVersion + NEWLINE + ChatColor.YELLOW + "New version: " + ChatColor.WHITE + newVersion + NEWLINE + ChatColor.YELLOW + "Please visit:" + NEWLINE + - ChatColor.AQUA + "http://dev.bukkit.org/server-mods/craftinc-borderprotection" + NEWLINE + + ChatColor.AQUA + "http://dev.bukkit.org/bukkit-mods/craftinc-borderprotection" + NEWLINE + ChatColor.YELLOW + "to get the latest version!"; } public static String noUpdateAvailable = ChatColor.YELLOW + "No updates available."; + + /** + * Display a message to a player and then wait for timeout seconds before displaying it again. + * + * @param player Player who will see the message. + * @param message The message String. + * @param timeout Timeout in seconds until the message will be displayed earliest. + */ + public static void showMessageWithTimeout( final Player player, final String message, final Integer timeout ) + { + // get the current time + final Long now = Calendar.getInstance().getTimeInMillis(); + + if ( ( lastMessage.get(player.getName()) != null && lastMessage.get(player.getName()).get(message) != null && + now - timeout * 1000 > lastMessage.get(player.getName()).get(message) ) || + lastMessage.get(player.getName()) != null && lastMessage.get(player.getName()).get(message) == null || + lastMessage.get(player.getName()) == null ) + { + // show message + player.sendMessage(message); + + // set last sent message for this player to now + if ( lastMessage.get(player.getName()) == null ) + { + lastMessage.put(player.getName(), new HashMap() + {{ + put(message, now); + }}); + } + else + { + lastMessage.get(player.getName()).put(message, now); + } + } + } } diff --git a/src/main/java/de/craftinc/borderprotection/PlayerMoveListener.java b/src/main/java/de/craftinc/borderprotection/PlayerMoveListener.java deleted file mode 100644 index b237065..0000000 --- a/src/main/java/de/craftinc/borderprotection/PlayerMoveListener.java +++ /dev/null @@ -1,128 +0,0 @@ -/* Craft Inc. BorderProtection - Copyright (C) 2013 Paul Schulze, Tobias Ottenweller - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -package de.craftinc.borderprotection; - -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.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerMoveEvent; - -public class PlayerMoveListener implements Listener -{ - - private BorderManager borderManager; - - public PlayerMoveListener( BorderManager borderManager ) - { - this.borderManager = borderManager; - } - - private Double goUpUntilFreeSpot( Location newLocation ) - { - // go up in height until the player can stand in AIR - Block footBlock = newLocation.getBlock(); - Block headBlock = newLocation.getBlock().getRelative(BlockFace.UP); - while ( footBlock.getType() != Material.AIR || headBlock.getType() != Material.AIR ) - { - byte offset = 1; - if ( headBlock.getType() != Material.AIR ) - { - offset = 2; - } - footBlock = footBlock.getRelative(0, offset, 0); - headBlock = headBlock.getRelative(0, offset, 0); - } - // set the y value to a spot where the player can stand free - return (double) footBlock.getY(); - } - - @SuppressWarnings("unused") - @EventHandler(priority = EventPriority.HIGHEST) - public void onPlayerMove( PlayerMoveEvent e ) - { - // do nothing if the event is already cancelled - if (e.isCancelled()) - { - return; - } - - // do nothing if player has the ignoreborders permission - if ( e.getPlayer().hasPermission("craftinc.borderprotection.ignoreborders") ) - { - return; - } - - // do nothing if there are no border definitions at all - if ( Border.getBorders().isEmpty() ) - { - return; - } - - // player location - Location playerLocation = e.getPlayer().getLocation(); - - // world where the player is in - World world = e.getPlayer().getWorld(); - - // border of this world - Border border = Border.getBorders().get(world); - - // do nothing if there are no borders for this specific world - if ( border == null ) - { - return; - } - - // do nothing if border is disabled - if ( !border.isActive() ) - { - return; - } - - // change x or z. default: do not change - Double[] newXZ; - - // check if player is inside the borders. null if yes, otherwise a tuple which defines the new player position - newXZ = borderManager.checkBorder(playerLocation, border, BorderManager.buffer); - - // Do nothing, if no new coordinates have been calculated. - if ( newXZ == null ) - { - return; - } - - // if one of the coordinates is null, set it to the player's value - newXZ[0] = newXZ[0] == null ? playerLocation.getX() : newXZ[0]; - newXZ[1] = newXZ[1] == null ? playerLocation.getZ() : newXZ[1]; - - // change Y if necessary (when there is no free spot) - Double newY = goUpUntilFreeSpot(new Location(world, newXZ[0], e.getPlayer().getLocation().getY(), newXZ[1])); - - // teleport the player to the new X and Z coordinates - e.getPlayer().teleport( - new Location(e.getPlayer().getWorld(), newXZ[0], newY, newXZ[1], playerLocation.getYaw(), - playerLocation.getPitch())); - - // send a message to the player - borderManager.showMessageWithTimeout(e.getPlayer(), Messages.borderMessage); - } -} diff --git a/src/main/java/de/craftinc/borderprotection/Plugin.java b/src/main/java/de/craftinc/borderprotection/Plugin.java index 2b7baa0..e3e4aac 100644 --- a/src/main/java/de/craftinc/borderprotection/Plugin.java +++ b/src/main/java/de/craftinc/borderprotection/Plugin.java @@ -16,23 +16,24 @@ */ package de.craftinc.borderprotection; +import de.craftinc.borderprotection.borders.CircBorder; +import de.craftinc.borderprotection.borders.RectBorder; +import de.craftinc.borderprotection.events.PlayerLoginListener; +import de.craftinc.borderprotection.events.PlayerMoveListener; +import de.craftinc.borderprotection.events.PlayerTeleportListener; import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; public class Plugin extends JavaPlugin { - private static JavaPlugin cibpPlugin; - - public static JavaPlugin getPlugin() - { - return cibpPlugin; - } + public static Plugin instance; @Override public void onLoad() { - ConfigurationSerialization.registerClass(Border.class); + ConfigurationSerialization.registerClass(RectBorder.class); + ConfigurationSerialization.registerClass(CircBorder.class); } @Override @@ -43,17 +44,15 @@ public class Plugin extends JavaPlugin @Override public void onEnable() { - Plugin.cibpPlugin = this; - - BorderManager borderManager = new BorderManager(); + Plugin.instance = this; // create listeners - PlayerMoveListener playerMoveListener = new PlayerMoveListener(borderManager); - PlayerTeleportListener playerTeleportListener = new PlayerTeleportListener(borderManager); + PlayerMoveListener playerMoveListener = new PlayerMoveListener(); + PlayerTeleportListener playerTeleportListener = new PlayerTeleportListener(); PlayerLoginListener playerLoginListener = new PlayerLoginListener(); // commands - Commands commandExecutor = new Commands(borderManager); + Commands commandExecutor = new Commands(); getCommand("cibp").setExecutor(commandExecutor); // register listeners diff --git a/src/main/java/de/craftinc/borderprotection/borders/Border.java b/src/main/java/de/craftinc/borderprotection/borders/Border.java new file mode 100644 index 0000000..8a72be1 --- /dev/null +++ b/src/main/java/de/craftinc/borderprotection/borders/Border.java @@ -0,0 +1,125 @@ +/* Craft Inc. BorderProtection + Copyright (C) 2013 Paul Schulze, Tobias Ottenweller + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +package de.craftinc.borderprotection.borders; + +import de.craftinc.borderprotection.Plugin; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public abstract class Border +{ + private static final String dataFileName = "borders.yml"; + + protected Boolean isActive; + + protected static final String isActiveKey = "enabled"; + protected static final String bordersKey = "borders"; + + protected static final HashMap borders = new HashMap(); + + private static final File bordersFile = new File(Plugin.instance.getDataFolder(), dataFileName); + private static final FileConfiguration bordersFileConf = YamlConfiguration.loadConfiguration(bordersFile); + + /** + * The buffer in blocks which applies when a player is teleported inside the border. 0 means the player + * will be teleported directly to the border. + */ + public static final double buffer = 0.5; + + public static HashMap getBorders() + { + return borders; + } + + /** + * Returns a String which identifies the type of the border. Example: Rectangle + */ + public abstract String getBorderTypeString(); + + /** + * Returns a formatted String (colors and newlines) which fits into the borderInfo message and describes + * the border properties properly. + */ + public abstract String getBorderInfoString(); + + /** + * Checks if the given location is inside or outside the border. If it is outside a new location (inside the border) + * is returned, otherwise null. + * + * @param l Location to check if inside the border + * @return null if l is inside the border otherwise a new Location which is inside + */ + public abstract Location checkBorder( Location l ); + + public Boolean isActive() + { + return isActive; + } + + public Border( Map map ) + { + try + { + isActive = (Boolean) map.get(isActiveKey); + } + catch ( Exception e ) + { + // FIXME + Plugin.instance.getLogger().severe(e.getMessage()); + } + } + + public Border() + { + // new borders are enabled by default + isActive = true; + } + + public static void loadBorders() + { + bordersFileConf.getList(bordersKey); + } + + public static void saveBorders() throws IOException + { + bordersFileConf.set(bordersKey, new ArrayList(borders.values())); + bordersFileConf.save(bordersFile); + } + + public void enable() + { + isActive = true; + } + + public void disable() + { + isActive = false; + } + + protected void serialize( Map map ) + { + map.put(isActiveKey, isActive); + } +} diff --git a/src/main/java/de/craftinc/borderprotection/borders/CircBorder.java b/src/main/java/de/craftinc/borderprotection/borders/CircBorder.java new file mode 100644 index 0000000..2276a21 --- /dev/null +++ b/src/main/java/de/craftinc/borderprotection/borders/CircBorder.java @@ -0,0 +1,123 @@ +/* Craft Inc. BorderProtection + Copyright (C) 2013 Paul Schulze, Tobias Ottenweller + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +package de.craftinc.borderprotection.borders; + +import de.craftinc.borderprotection.util.LocationSerializer2D; +import de.craftinc.borderprotection.Plugin; +import de.craftinc.borderprotection.util.PlayerMovementUtil; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.configuration.serialization.ConfigurationSerializable; + +import java.util.HashMap; +import java.util.Map; + +public class CircBorder extends Border implements ConfigurationSerializable +{ + private Double radius; + private Location center; + + private static String centerKey = "center"; + private static String radiusKey = "radius"; + + @SuppressWarnings("unchecked unused") + public CircBorder( Map map ) + { + super(map); + try + { + center = LocationSerializer2D.deserializeLocation((Map) map.get(centerKey)); + radius = (Double) map.get(radiusKey); + + borders.put(center.getWorld(), this); + } + catch ( Exception e ) + { + // FIXME + Plugin.instance.getLogger().severe(e.getMessage()); + } + } + + public CircBorder( Location center, Double radius ) + { + super(); + + this.center = center; + this.radius = radius; + + borders.put(center.getWorld(), this); + } + + + @SuppressWarnings("unused") + public Map serialize() + { + Map map = new HashMap(); + super.serialize(map); + map.put(centerKey, LocationSerializer2D.serializeLocation(center)); + map.put(radiusKey, radius); + + return map; + } + + public String toString() + { + return "CircBorder(" + "center: " + center.getX() + "," + center.getZ() + ", radius: " + radius + ")"; + } + + @Override + public String getBorderTypeString() + { + return "Circle"; + } + + @Override + public String getBorderInfoString() + { + return ChatColor.YELLOW + "Center: " + ChatColor.WHITE + center.getX() + "," + center.getZ() + "\n" + + ChatColor.YELLOW + "Raduis: " + ChatColor.WHITE + radius; + } + + @Override + public Location checkBorder( Location l ) + { + double distX = l.getX() - center.getX(); + double distZ = l.getZ() - center.getZ(); + + double distanceFromCenterSquared = distX * distX + distZ * distZ; + double radiusSquared = radius * radius; + + // inside the border + if ( distanceFromCenterSquared <= radiusSquared ) + { + return null; + } + + // outside the border: it's ok to use square-root function here, because this only happens very few times + double ratio = radius / Math.sqrt(distanceFromCenterSquared); + double newX = center.getX() + ( ratio * distX ); + double newZ = center.getZ() + ( ratio * distZ ); + + Location newLocation = new Location(l.getWorld(), newX, l.getY(), newZ, l.getYaw(), l.getPitch()); + + // ensure that the player will not appear in a block + // TODO: Should hook into another Plugin maybe or implement something better + newLocation.setY(PlayerMovementUtil.goUpUntilFreeSpot(newLocation)); + + return newLocation; + } +} \ No newline at end of file diff --git a/src/main/java/de/craftinc/borderprotection/borders/RectBorder.java b/src/main/java/de/craftinc/borderprotection/borders/RectBorder.java new file mode 100644 index 0000000..7b26012 --- /dev/null +++ b/src/main/java/de/craftinc/borderprotection/borders/RectBorder.java @@ -0,0 +1,183 @@ +/* Craft Inc. BorderProtection + Copyright (C) 2013 Paul Schulze, Tobias Ottenweller + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +package de.craftinc.borderprotection.borders; + +import de.craftinc.borderprotection.util.LocationSerializer2D; +import de.craftinc.borderprotection.Plugin; +import de.craftinc.borderprotection.util.PlayerMovementUtil; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.configuration.serialization.ConfigurationSerializable; + +import java.util.HashMap; +import java.util.Map; + +public class RectBorder extends Border implements ConfigurationSerializable +{ + private Location rectPoint1; + private Location rectPoint2; + + private static String rectPoint1Name = "p1"; + private static String rectPoint2Name = "p2"; + + @SuppressWarnings("unchecked unused") + public RectBorder( Map map ) + { + super(map); + + try + { + rectPoint1 = LocationSerializer2D.deserializeLocation((Map) map.get(rectPoint1Name)); + rectPoint2 = LocationSerializer2D.deserializeLocation((Map) map.get(rectPoint2Name)); + + if ( rectPoint1.getWorld().equals(rectPoint2.getWorld()) ) + { + borders.put(rectPoint1.getWorld(), this); + } + else + { + throw new Exception("RectBorder points are at different worlds."); + } + } + catch ( Exception e ) + { + Plugin.instance.getLogger().severe(e.getMessage()); + } + } + + public RectBorder( Location p1, Location p2 ) throws Exception + { + super(); + + rectPoint1 = p1; + rectPoint2 = p2; + + if ( rectPoint1.getWorld().equals(rectPoint2.getWorld()) ) + { + borders.put(rectPoint1.getWorld(), this); + } + else + { + throw new Exception("RectBorder points are at different worlds."); + } + } + + @SuppressWarnings("unused") + public Map serialize() + { + Map map = new HashMap(); + super.serialize(map); + map.put(rectPoint1Name, LocationSerializer2D.serializeLocation(rectPoint1)); + map.put(rectPoint2Name, LocationSerializer2D.serializeLocation(rectPoint2)); + + return map; + } + + + public String toString() + { + return "RectBorder(" + rectPoint1.getX() + "," + rectPoint1.getZ() + ";" + rectPoint2.getX() + "," + + rectPoint2.getZ() + ")"; + } + + @Override + public String getBorderTypeString() + { + return "Rectangle"; + } + + @Override + public String getBorderInfoString() + { + return ChatColor.YELLOW + "Point 1: " + ChatColor.WHITE + rectPoint1.getX() + "," + rectPoint1.getZ() + "\n" + + ChatColor.YELLOW + "Point 2: " + ChatColor.WHITE + rectPoint2.getX() + "," + rectPoint2.getZ(); + } + + /** + * Checks if the given location is inside the rectBorder rectangle. Returns null if yes, otherwise new coordinates. + * + * @param l location to check + * @return null if the player is inside, otherwise a new player location + */ + @Override + public Location checkBorder( Location l ) + { + // New x and z: null by default + Double[] newXZ = { null, null }; + + // check if player is withing the X borders + newXZ[0] = _checkBorder(l.getX(), this.rectPoint1.getX(), this.rectPoint2.getX()); + // check if player is withing the Z borders + newXZ[1] = _checkBorder(l.getZ(), this.rectPoint1.getZ(), this.rectPoint2.getZ()); + + // Do nothing, if no new coordinates have been calculated. + if ( newXZ[0] == null && newXZ[1] == null ) + { + return null; + } + + // if one of the coordinates is null, set it to the player's value + newXZ[0] = newXZ[0] == null ? l.getX() : newXZ[0]; + newXZ[1] = newXZ[1] == null ? l.getZ() : newXZ[1]; + + // new location + Location newLocation = new Location(l.getWorld(), newXZ[0], l.getY(), newXZ[1], l.getYaw(), l.getPitch()); + + // change Y if necessary (when there is no free spot) + newLocation.setY(PlayerMovementUtil.goUpUntilFreeSpot(newLocation)); + + return newLocation; + } + + + /** + * Checks if the given location is between one specific border pair. + * + * @param location part of the location coordinates + * @param border1 one side of the rectangle + * @param border2 opposite side of the rectangle + * @return null if the location is inside, otherwise a new location + */ + private static Double _checkBorder( double location, double border1, double border2 ) + { + double bigBorder = Math.max(border1, border2); + double smallBorder = Math.min(border1, border2); + + // if location is between borders do nothing + if ( location >= smallBorder && location <= bigBorder ) + { + return null; + } + else + { + if ( location > bigBorder ) + { + // if location is outside of the bigBorder, teleport to the bigBorder + if ( buffer > bigBorder ) + return bigBorder; + return bigBorder - buffer; + } + else + { + // if location is outside of the smallBorder, teleport to the smallBorder + if ( buffer > Math.abs(smallBorder) ) + return smallBorder; + return smallBorder + buffer; + } + } + } +} diff --git a/src/main/java/de/craftinc/borderprotection/PlayerLoginListener.java b/src/main/java/de/craftinc/borderprotection/events/PlayerLoginListener.java similarity index 89% rename from src/main/java/de/craftinc/borderprotection/PlayerLoginListener.java rename to src/main/java/de/craftinc/borderprotection/events/PlayerLoginListener.java index 8e00653..26b016e 100644 --- a/src/main/java/de/craftinc/borderprotection/PlayerLoginListener.java +++ b/src/main/java/de/craftinc/borderprotection/events/PlayerLoginListener.java @@ -14,8 +14,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -package de.craftinc.borderprotection; +package de.craftinc.borderprotection.events; +import de.craftinc.borderprotection.Messages; +import de.craftinc.borderprotection.Plugin; +import de.craftinc.borderprotection.util.UpdateHelper; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -36,7 +39,7 @@ public class PlayerLoginListener implements Listener if ( UpdateHelper.newVersionAvailable() ) { // Schedule a task which delays 20 ticks (1 second) and then sends a message to the player - Bukkit.getScheduler().scheduleSyncDelayedTask(Plugin.getPlugin(), new Runnable() + Bukkit.getScheduler().scheduleSyncDelayedTask(Plugin.instance, new Runnable() { @Override public void run() diff --git a/src/main/java/de/craftinc/borderprotection/events/PlayerMoveListener.java b/src/main/java/de/craftinc/borderprotection/events/PlayerMoveListener.java new file mode 100644 index 0000000..83a0fee --- /dev/null +++ b/src/main/java/de/craftinc/borderprotection/events/PlayerMoveListener.java @@ -0,0 +1,90 @@ +/* Craft Inc. BorderProtection + Copyright (C) 2013 Paul Schulze, Tobias Ottenweller + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +package de.craftinc.borderprotection.events; + +import de.craftinc.borderprotection.Messages; +import de.craftinc.borderprotection.borders.Border; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; + +public class PlayerMoveListener implements Listener +{ + + + @SuppressWarnings("unused") + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerMove( PlayerMoveEvent e ) + { + // do nothing if the event is already cancelled + if ( e.isCancelled() ) + { + return; + } + + // do nothing if player has the ignoreborders permission + if ( e.getPlayer().hasPermission("craftinc.borderprotection.ignoreborders") ) + { + return; + } + + // do nothing if there are no border definitions at all + if ( Border.getBorders().isEmpty() ) + { + return; + } + + // player location + Location playerLocation = e.getPlayer().getLocation(); + + // world where the player is in + World world = e.getPlayer().getWorld(); + + // Border of this world + Border border = Border.getBorders().get(world); + + // do nothing if there are no borders for this specific world + if ( border == null ) + { + return; + } + + // do nothing if border is disabled + if ( !border.isActive() ) + { + return; + } + + // check if player is inside the borders and get a new location if not + Location destination = border.checkBorder(playerLocation); + + // Do nothing, if no new location has been calculated. + if ( destination == null ) + { + return; + } + + // teleport the player to the new location within the borders + e.getPlayer().teleport(destination); + + // send a message to the player + Messages.showMessageWithTimeout(e.getPlayer(), Messages.borderMessage, 10); + } +} diff --git a/src/main/java/de/craftinc/borderprotection/PlayerTeleportListener.java b/src/main/java/de/craftinc/borderprotection/events/PlayerTeleportListener.java similarity index 71% rename from src/main/java/de/craftinc/borderprotection/PlayerTeleportListener.java rename to src/main/java/de/craftinc/borderprotection/events/PlayerTeleportListener.java index 5be1e9a..21fb2eb 100644 --- a/src/main/java/de/craftinc/borderprotection/PlayerTeleportListener.java +++ b/src/main/java/de/craftinc/borderprotection/events/PlayerTeleportListener.java @@ -14,8 +14,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -package de.craftinc.borderprotection; +package de.craftinc.borderprotection.events; +import de.craftinc.borderprotection.Messages; +import de.craftinc.borderprotection.borders.Border; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.event.EventHandler; @@ -25,19 +27,12 @@ import org.bukkit.event.player.PlayerTeleportEvent; public class PlayerTeleportListener implements Listener { - private BorderManager borderManager; - - public PlayerTeleportListener( BorderManager borderManager ) - { - this.borderManager = borderManager; - } - @SuppressWarnings("unused") @EventHandler(priority = EventPriority.HIGHEST) - public void onPlayerMove( PlayerTeleportEvent e ) + public void onPlayerTeleport( PlayerTeleportEvent e ) { // do nothing if the event is already cancelled - if (e.isCancelled()) + if ( e.isCancelled() ) { return; } @@ -69,24 +64,22 @@ public class PlayerTeleportListener implements Listener return; } - // do nothing if border is disabled + // do nothing if rectBorder is disabled if ( !border.isActive() ) { return; } - // change x or z. default: do not change - Double[] newXZ; + // check if player is inside the borders and get a new location if not + Location destination = border.checkBorder(targetLocation); - // check if target is inside the borders. null if yes, otherwise a tuple which defines the new position - newXZ = borderManager.checkBorder(targetLocation, border, BorderManager.buffer); - - - // Cancel event, if new coordinates have been calculated. - if ( newXZ != null ) + // Do nothing, if no new location has been calculated. + if ( destination == null ) { - e.setCancelled(true); - borderManager.showMessageWithTimeout(e.getPlayer(), Messages.borderTeleportMessage); + return; } + + e.setCancelled(true); + Messages.showMessageWithTimeout(e.getPlayer(), Messages.borderTeleportMessage, 10); } } diff --git a/src/main/java/de/craftinc/borderprotection/LocationSerializer.java b/src/main/java/de/craftinc/borderprotection/util/LocationSerializer2D.java similarity index 82% rename from src/main/java/de/craftinc/borderprotection/LocationSerializer.java rename to src/main/java/de/craftinc/borderprotection/util/LocationSerializer2D.java index 069f7ec..c9a2a96 100644 --- a/src/main/java/de/craftinc/borderprotection/LocationSerializer.java +++ b/src/main/java/de/craftinc/borderprotection/util/LocationSerializer2D.java @@ -1,5 +1,5 @@ /* Craft Inc. BorderProtection - Copyright (C) 2013 Tobias Ottenweller + Copyright (C) 2013 Tobias Ottenweller, Paul Schulze This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published @@ -14,8 +14,9 @@ You should have received a copy of the GNU Lesser General Public License along with this program (LGPLv3). If not, see . */ -package de.craftinc.borderprotection; +package de.craftinc.borderprotection.util; +import de.craftinc.borderprotection.Plugin; import org.bukkit.Location; import org.bukkit.World; @@ -26,17 +27,16 @@ import java.util.Map; /** * NOTE: We do not care about yaw and pitch for gate locations. So we won't serialize them. */ -public class LocationSerializer +public class LocationSerializer2D { protected static String worldKey = "world"; protected static String xKey = "x"; - protected static String yKey = "y"; protected static String zKey = "z"; protected static World getWorld( String name ) throws Exception { - World world = Plugin.getPlugin().getServer().getWorld(name); + World world = Plugin.instance.getServer().getWorld(name); if ( world == null ) { @@ -58,7 +58,6 @@ public class LocationSerializer serializedLocation.put(worldKey, l.getWorld().getName()); serializedLocation.put(xKey, l.getX()); - serializedLocation.put(yKey, l.getY()); serializedLocation.put(zKey, l.getZ()); return serializedLocation; @@ -77,27 +76,21 @@ public class LocationSerializer // verbose loading of coordinates (they might be Double or Integer) Object objX = map.get(xKey); - Object objY = map.get(yKey); Object objZ = map.get(zKey); - double x, y, z; + double x, z; if ( objX instanceof Integer ) x = (double) (Integer) objX; else x = (Double) objX; - if ( objY instanceof Integer ) - y = (double) (Integer) objY; - else - y = (Double) objY; - if ( objZ instanceof Integer ) z = (double) (Integer) objZ; else z = (Double) objZ; - return new Location(w, x, y, z); + return new Location(w, x, 0d, z); } } diff --git a/src/main/java/de/craftinc/borderprotection/util/PlayerMovementUtil.java b/src/main/java/de/craftinc/borderprotection/util/PlayerMovementUtil.java new file mode 100644 index 0000000..930382e --- /dev/null +++ b/src/main/java/de/craftinc/borderprotection/util/PlayerMovementUtil.java @@ -0,0 +1,45 @@ +/* Craft Inc. BorderProtection + Copyright (C) 2013 Paul Schulze, Tobias Ottenweller + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +package de.craftinc.borderprotection.util; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; + +public class PlayerMovementUtil +{ + public static Double goUpUntilFreeSpot( Location l ) + { + // FIXME: Player should not be placed above lava or other harmful Materials + // go up in height until the player can stand in AIR + Block footBlock = l.getBlock(); + Block headBlock = l.getBlock().getRelative(BlockFace.UP); + while ( footBlock.getType() != Material.AIR || headBlock.getType() != Material.AIR ) + { + byte offset = 1; + if ( headBlock.getType() != Material.AIR ) + { + offset = 2; + } + footBlock = footBlock.getRelative(0, offset, 0); + headBlock = headBlock.getRelative(0, offset, 0); + } + // return the y value to a spot where the player can stand free + return (double) footBlock.getY(); + } +} diff --git a/src/main/java/de/craftinc/borderprotection/UpdateHelper.java b/src/main/java/de/craftinc/borderprotection/util/UpdateHelper.java similarity index 83% rename from src/main/java/de/craftinc/borderprotection/UpdateHelper.java rename to src/main/java/de/craftinc/borderprotection/util/UpdateHelper.java index 37f9952..f0f8bfe 100644 --- a/src/main/java/de/craftinc/borderprotection/UpdateHelper.java +++ b/src/main/java/de/craftinc/borderprotection/util/UpdateHelper.java @@ -14,7 +14,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -package de.craftinc.borderprotection; +package de.craftinc.borderprotection.util; + +import de.craftinc.borderprotection.Plugin; import java.io.BufferedReader; import java.io.IOException; @@ -36,7 +38,6 @@ public class UpdateHelper */ public static String cachedLatestVersion = null; - /** * Gets the latest version from the updateURL and returns it as String. * @@ -60,11 +61,11 @@ public class UpdateHelper } catch ( MalformedURLException e ) { - Plugin.getPlugin().getLogger().warning("Could not check for latest version. Update URL is malformed."); + Plugin.instance.getLogger().warning("Could not check for latest version. Update URL is malformed."); } catch ( IOException e ) { - Plugin.getPlugin().getLogger().warning("Could not check for latest version. Update URL was not readable."); + Plugin.instance.getLogger().warning("Could not check for latest version. Update URL was not readable."); } // update cached latest version @@ -73,7 +74,6 @@ public class UpdateHelper return s.toString(); } - /** * Gets the current version of this plugin directly from the plugin.yml version entry. * @@ -81,10 +81,9 @@ public class UpdateHelper */ public static String getCurrentVersion() { - return Plugin.getPlugin().getDescription().getVersion(); + return Plugin.instance.getDescription().getVersion(); } - /** * Checks if a newer version is available. * @@ -92,7 +91,12 @@ public class UpdateHelper */ public static Boolean newVersionAvailable() { + final String version = getLatestVersion(); + + // do not show beta or dev versions + if (version.contains("beta") || version.contains("dev")) + return false; + return !getCurrentVersion().equals(getLatestVersion()); } - } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 4642d1c..c7e21e4 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -name: Craft Inc. BorderProtection +name: ${project.name} main: de.craftinc.borderprotection.Plugin version: ${project.version} softdepend: [Multiverse-Core] @@ -31,7 +31,7 @@ permissions: default: op description: Allows to set the border for a world. craftinc.borderprotection.ignoreborders: - default: op + default: false description: Allows to be everywhere on the map (ignoring the borders). craftinc.borderprotection.update: default: op