timeout for bordermessage
cancel teleport events if destination is outside border
This commit is contained in:
parent
a469f5a427
commit
19b8e12ff4
BIN
CraftincBorderProtection.jar
Normal file
BIN
CraftincBorderProtection.jar
Normal file
Binary file not shown.
2
pom.xml
2
pom.xml
@ -4,7 +4,7 @@
|
||||
<groupId>CraftincBorderProtection</groupId>
|
||||
<artifactId>CraftincBorderProtection</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>0.9.5</version>
|
||||
<version>0.9.9</version>
|
||||
<name>CraftincGates</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
<properties>
|
||||
|
@ -2,10 +2,12 @@ package de.craftinc.borderprotection;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class BorderManager
|
||||
@ -25,15 +27,21 @@ public class BorderManager
|
||||
private HashMap<String, ArrayList<Location>> borders = null;
|
||||
|
||||
/**
|
||||
* the buffer in blocks which applies when a player is teleported inside the border. 0 means the player
|
||||
* For every player save the time when he got the last borderMessage
|
||||
*/
|
||||
public HashMap<String, Long> lastBorderMessage = new HashMap<String, Long>();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private double buffer = 0.5;
|
||||
|
||||
public Serializer getSerializer()
|
||||
{
|
||||
return serializer;
|
||||
}
|
||||
/**
|
||||
* 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 <code>timeout</code> milliseconds.
|
||||
*/
|
||||
private Long timeout = 10000L;
|
||||
|
||||
/**
|
||||
* Serializer, which is used for loading and saving data to harddisk
|
||||
@ -59,11 +67,21 @@ public class BorderManager
|
||||
* **********************************************************
|
||||
*/
|
||||
|
||||
public Serializer getSerializer()
|
||||
{
|
||||
return serializer;
|
||||
}
|
||||
|
||||
public double getBuffer()
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public Long getTimeout()
|
||||
{
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public HashMap<String, ArrayList<Location>> getBorders()
|
||||
{
|
||||
return borders;
|
||||
@ -103,4 +121,89 @@ public class BorderManager
|
||||
|
||||
borders.put(worldName, locations);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the given location is inside the border rectangle. Returns null if yes, otherwise new coordinates.
|
||||
*
|
||||
* @param location location to check
|
||||
* @param borderPoints points which define the border rectangle
|
||||
* @param buffer if the player will be teleported back, then he will be <code>buffer</code> 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, ArrayList<Location> borderPoints, 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(), borderPoints.get(0).getX(), borderPoints.get(1).getX(), buffer);
|
||||
// check if player is withing the Z borders
|
||||
newXZ[1] = _checkBorder(location.getZ(), borderPoints.get(0).getZ(), borderPoints.get(1).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 - getTimeout() > 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -74,7 +74,7 @@ public class Commands implements CommandExecutor
|
||||
}
|
||||
|
||||
ArrayList<Location> borderPoints = borderManager.getBorders()
|
||||
.get(worldName);
|
||||
.get(worldName);
|
||||
String borderDef = borderPoints.get(0).getX() + "," + borderPoints.get(0).getZ() + " " +
|
||||
borderPoints.get(1).getX() + "," + borderPoints.get(1).getZ();
|
||||
|
||||
|
@ -37,15 +37,22 @@ public class Messages
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String borderExplanation =
|
||||
"One day the holy mods and administrators will expand the border. It is then your mission to explore " +
|
||||
"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! One day the holy mods " +
|
||||
"and administrators will expand the border. It is then your mission to explore " +
|
||||
"strange new worlds, to seek out new life and new civilizations, to boldly go " +
|
||||
"where no one has gone before.";
|
||||
"Sorry Dude! 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 +
|
||||
makeCmd("/cibp get", "shows the borders of the current world");
|
||||
|
||||
public static String helpGeneral =
|
||||
ChatColor.GREEN + "CraftInc BorderProtection - Usage:" + NEWLINE +
|
||||
makeCmd("help", "shows this help") +
|
||||
makeCmd("get | info", "shows the borders of the current world") +
|
||||
makeCmd("set", "Border rectangle edges will be this far away from point of origin.", "<integer>") +
|
||||
makeCmd("set", "Border rectangle is defined by the two points. A point is specified as: x,z",
|
||||
"<point1>", "<point2>");
|
||||
@ -56,7 +63,7 @@ public class Messages
|
||||
public static String borderInfo( String worldName, String borderDef )
|
||||
{
|
||||
|
||||
return ChatColor.WHITE + "Border definition of world " +
|
||||
return ChatColor.WHITE + "Borders of world " +
|
||||
ChatColor.YELLOW + worldName +
|
||||
ChatColor.WHITE + ": " +
|
||||
ChatColor.YELLOW + borderDef;
|
||||
|
@ -21,39 +21,6 @@ public class PlayerMoveListener implements Listener
|
||||
this.borderManager = borderManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is outside of one specific border.
|
||||
*
|
||||
* @param player part of the player coordinates
|
||||
* @param border1 one side of the rectangle
|
||||
* @param border2 opposite side of the rectangle
|
||||
* @return null if the player is inside, otherwise a new player location
|
||||
*/
|
||||
private Double checkBorder( double player, double border1, double border2 )
|
||||
{
|
||||
double bigBorder = Math.max(border1, border2);
|
||||
double smallBorder = Math.min(border1, border2);
|
||||
|
||||
// if player is between borders do nothing
|
||||
if ( player >= smallBorder && player <= bigBorder )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( player > bigBorder )
|
||||
{
|
||||
// if player is outside of the bigBorder, teleport him to the bigBorder
|
||||
return bigBorder - borderManager.getBuffer();
|
||||
}
|
||||
else
|
||||
{
|
||||
// if player is outside of the smallBorder, teleport him to the smallBorder
|
||||
return smallBorder + borderManager.getBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Double goUpUntilFreeSpot( Player player )
|
||||
{
|
||||
// go up in height until the player can stand in AIR
|
||||
@ -82,14 +49,19 @@ public class PlayerMoveListener implements Listener
|
||||
return;
|
||||
}
|
||||
|
||||
// do nothing if there is no border defined
|
||||
// do nothing if there are no border definitions at all
|
||||
if ( borderManager.getBorders() == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Location pl = e.getPlayer().getLocation();
|
||||
// player location
|
||||
Location playerLocation = e.getPlayer().getLocation();
|
||||
|
||||
// world where the player is in
|
||||
String worldName = e.getPlayer().getWorld().getName();
|
||||
|
||||
// borders of this world
|
||||
ArrayList<Location> borderPoints = borderManager.getBorders().get(worldName);
|
||||
|
||||
// do nothing if there are no borders for this specific world
|
||||
@ -97,29 +69,30 @@ public class PlayerMoveListener implements Listener
|
||||
return;
|
||||
|
||||
// change x or z. default: do not change
|
||||
Double newX, newY, newZ;
|
||||
Double[] newXZ;
|
||||
|
||||
newX = checkBorder(pl.getX(), borderPoints.get(0).getX(), borderPoints.get(1).getX());
|
||||
newZ = checkBorder(pl.getZ(), borderPoints.get(0).getZ(), borderPoints.get(1).getZ());
|
||||
// check if player is inside the borders. null if yes, otherwise a tuple which defines the new player position
|
||||
newXZ = borderManager.checkBorder(playerLocation, borderPoints, borderManager.getBuffer());
|
||||
|
||||
// Do nothing, if no new coordinates have been calculated.
|
||||
if ( newX == null && newZ == null )
|
||||
if ( newXZ == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if one of the coordinates is null, set it to the player's value
|
||||
newX = newX == null ? pl.getX() : newX;
|
||||
newZ = newZ == null ? pl.getZ() : newZ;
|
||||
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)
|
||||
newY = goUpUntilFreeSpot(e.getPlayer());
|
||||
Double newY = goUpUntilFreeSpot(e.getPlayer());
|
||||
|
||||
// teleport the player to the new X and Z coordinates
|
||||
e.getPlayer().teleport(
|
||||
new Location(e.getPlayer().getWorld(), newX, newY, newZ, pl.getYaw(), pl.getPitch()));
|
||||
new Location(e.getPlayer().getWorld(), newXZ[0], newY, newXZ[1], playerLocation.getYaw(),
|
||||
playerLocation.getPitch()));
|
||||
|
||||
// send a message to the player
|
||||
e.getPlayer().sendMessage(Messages.borderMessage);
|
||||
borderManager.showMessageWithTimeout(e.getPlayer(), Messages.borderMessage);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,64 @@
|
||||
package de.craftinc.borderprotection;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PlayerTeleportListener implements Listener
|
||||
{
|
||||
private BorderManager borderManager;
|
||||
|
||||
public PlayerTeleportListener( BorderManager borderManager )
|
||||
{
|
||||
this.borderManager = borderManager;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerMove( PlayerTeleportEvent e )
|
||||
{
|
||||
// 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 ( borderManager.getBorders() == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// target location
|
||||
Location targetLocation = e.getTo();
|
||||
|
||||
// world where the player is in
|
||||
String worldName = targetLocation.getWorld().getName();
|
||||
|
||||
// borders of this world
|
||||
ArrayList<Location> borderPoints = borderManager.getBorders().get(worldName);
|
||||
|
||||
// do nothing if there are no borders for this specific world
|
||||
if ( borderPoints == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// change x or z. default: do not change
|
||||
Double[] newXZ;
|
||||
|
||||
// check if target is inside the borders. null if yes, otherwise a tuple which defines the new position
|
||||
newXZ = borderManager.checkBorder(targetLocation, borderPoints, borderManager.getBuffer());
|
||||
|
||||
|
||||
// Cancel event, if new coordinates have been calculated.
|
||||
if ( newXZ != null )
|
||||
{
|
||||
e.setCancelled(true);
|
||||
borderManager.showMessageWithTimeout(e.getPlayer(), Messages.borderTeleportMessage);
|
||||
}
|
||||
}
|
||||
}
|
@ -23,11 +23,16 @@ public class Plugin extends JavaPlugin
|
||||
Plugin.cibpPlugin = this;
|
||||
|
||||
BorderManager borderManager = new BorderManager();
|
||||
PlayerMoveListener eventListener = new PlayerMoveListener(borderManager);
|
||||
Commands commandExecutor = new Commands(borderManager);
|
||||
PlayerMoveListener playerMoveListener = new PlayerMoveListener(borderManager);
|
||||
PlayerTeleportListener playerTeleportListener = new PlayerTeleportListener(borderManager);
|
||||
|
||||
PluginManager pm = this.getServer().getPluginManager();
|
||||
// commands
|
||||
Commands commandExecutor = new Commands(borderManager);
|
||||
getCommand("cibp").setExecutor(commandExecutor);
|
||||
pm.registerEvents(eventListener, this);
|
||||
|
||||
// listeners
|
||||
PluginManager pm = this.getServer().getPluginManager();
|
||||
pm.registerEvents(playerMoveListener, this);
|
||||
pm.registerEvents(playerTeleportListener, this);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,11 @@ public class Util
|
||||
for ( Object jsonEntry : json.toArray() )
|
||||
{
|
||||
JSONObject j = (JSONObject) jsonEntry;
|
||||
// // check if border for this world is enabled. continue if not
|
||||
// String enabled = (String) j.get("enabled");
|
||||
// if (enabled != "1") {
|
||||
// continue;
|
||||
// }
|
||||
String worldname = (String) j.get("worldname");
|
||||
ArrayList<Location> locations = new ArrayList<Location>();
|
||||
JSONArray borderPoints = (JSONArray) j.get("borderPoints");
|
||||
@ -32,18 +37,20 @@ public class Util
|
||||
data.put(worldname, locations);
|
||||
}
|
||||
|
||||
if (data.size() > 0) {
|
||||
if ( data.size() > 0 )
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static JSONArray encodeJSON( HashMap<String,ArrayList<Location>> data )
|
||||
public static JSONArray encodeJSON( HashMap<String, ArrayList<Location>> data )
|
||||
{
|
||||
JSONArray json = new JSONArray();
|
||||
int i = 0;
|
||||
for (ArrayList<Location> border: data.values()) {
|
||||
for ( ArrayList<Location> border : data.values() )
|
||||
{
|
||||
|
||||
// add point 1 as json array
|
||||
JSONArray point1 = new JSONArray();
|
||||
@ -62,15 +69,19 @@ public class Util
|
||||
|
||||
// Add points and worldname to world json object
|
||||
JSONObject borderOfAWorld = new JSONObject();
|
||||
try {
|
||||
try
|
||||
{
|
||||
borderOfAWorld.put("worldname", border.get(0).getWorld().getName());
|
||||
borderOfAWorld.put("borderPoints", points);
|
||||
json.add(i, borderOfAWorld);
|
||||
i++;
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
if (border.get(0).getWorld() == null) {
|
||||
Plugin.getPlugin().getLogger().warning("A world is null. Ignoring this border (not saving this border).");
|
||||
catch ( NullPointerException e )
|
||||
{
|
||||
if ( border.get(0).getWorld() == null )
|
||||
{
|
||||
Plugin.getPlugin().getLogger()
|
||||
.warning("A world is null. Ignoring this border (not saving this border).");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
name: CraftincBorderProtection
|
||||
main: de.craftinc.borderprotection.Plugin
|
||||
version: 0.9.5
|
||||
version: 0.9.9
|
||||
author: ddidderr
|
||||
website: http://www.craftinc.de/plugins/borderprotection
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user