Added integration with DynMap to display borders. It's enabled by default if you have DynMap installed, but note that you'll need DynMap v0.36 or newer for it to work. Borders will be displayed correctly as round or square and should be very accurate, based on a Y height of 64 on isometric maps. Any changes you make to your borders should almost immediately be reflected in DynMap (border radius or shape change, removal, new border set, etc.).

Thanks to mikeprimm for adding a couple of requested features to DynMap which made this feature possible.

New commands:
/wb dynmap <on/off> - turn DynMap border display on or off.
/wb dynmapmsg <text> - DynMap border labels will show this.

New permissions:
worldborder.dynmap (Op): Can enable/disable DynMap border display integration
worldborder.dynmapmsg (Op): Can set the label text for borders shown in DynMap

Also, a slight improvement to how boolean values are determined from command input; it accepts "y", "yes", "true" instead of just "on".
This commit is contained in:
Brettflan 2012-03-16 00:26:13 -05:00
parent 59cba09a35
commit 247e9052c2
8 changed files with 369 additions and 19 deletions

BIN
lib/dynmap-api.jar Normal file

Binary file not shown.

View File

@ -28,12 +28,12 @@ endorsed.classpath=
excludes=
file.reference.CalcTest-src=src
file.reference.craftbukkit.jar=lib\\craftbukkit.jar
file.reference.Permissions.jar=lib/Permissions.jar
file.reference.dynmap-api.jar=lib\\dynmap-api.jar
includes=**
jar.compress=true
javac.classpath=\
${file.reference.Permissions.jar}:\
${file.reference.craftbukkit.jar}
${file.reference.craftbukkit.jar}:\
${file.reference.dynmap-api.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false

View File

@ -37,6 +37,8 @@ public class Config
private static double knockBack = 3.0;
private static int timerTicks = 4;
private static boolean whooshEffect = false;
private static boolean dynmapEnable = true;
private static String dynmapMessage;
// for monitoring plugin efficiency
// public static long timeUsed = 0;
@ -51,6 +53,7 @@ public class Config
borders.put(world, border);
Log("Border set. " + BorderDescription(world));
save(true);
DynMapFeatures.showBorder(world, border);
}
public static void setBorder(String world, int radius, double x, double z, Boolean shapeRound)
{
@ -68,6 +71,7 @@ public class Config
borders.remove(world);
Log("Removed border for world \"" + world + "\".");
save(true);
DynMapFeatures.removeBorder(world);
}
public static void removeAllBorders()
@ -75,6 +79,7 @@ public class Config
borders.clear();
Log("Removed all borders for all worlds.");
save(true);
DynMapFeatures.removeAllBorders();
}
public static String BorderDescription(String world)
@ -104,6 +109,11 @@ public class Config
return borders.get(world);
}
public static Map<String, BorderData> getBorders()
{
return new LinkedHashMap<String, BorderData>(borders);
}
public static void setMessage(String msg)
{
message = msg;
@ -121,6 +131,7 @@ public class Config
shapeRound = round;
Log("Set default border shape to " + (round ? "round" : "square") + ".");
save(true);
DynMapFeatures.showAllBorders();
}
public static boolean ShapeRound()
@ -178,6 +189,34 @@ public class Config
}
public static void setDynmapBorderEnabled(boolean enable)
{
dynmapEnable = enable;
Log("DynMap border display is now " + (enable ? "enabled" : "disabled") + ".");
save(true);
DynMapFeatures.showAllBorders();
}
public static boolean DynmapBorderEnabled()
{
return dynmapEnable;
}
public static void setDynmapMessage(String msg)
{
dynmapMessage = msg;
Log("DynMap border label is now set to: " + msg);
save(true);
DynMapFeatures.showAllBorders();
}
public static String DynmapMessage()
{
return dynmapMessage;
}
public static void StartBorderTimer()
{
StopBorderTimer();
@ -274,7 +313,7 @@ public class Config
}
private static final int currentCfgVersion = 4;
private static final int currentCfgVersion = 5;
public static void load(WorldBorder master, boolean logIt)
{ // load config from file
@ -291,6 +330,8 @@ public class Config
whooshEffect = cfg.getBoolean("whoosh-effect", false);
knockBack = cfg.getDouble("knock-back-dist", 3.0);
timerTicks = cfg.getInt("timer-delay-ticks", 5);
dynmapEnable = cfg.getBoolean("dynmap-border-enabled", true);
dynmapMessage = cfg.getString("dynmap-border-message", "The border of the world.");
LogConfig("Using " + (shapeRound ? "round" : "square") + " border, knockback of " + knockBack + " blocks, and timer delay of " + timerTicks + ".");
StartBorderTimer();
@ -363,6 +404,8 @@ public class Config
cfg.set("whoosh-effect", whooshEffect);
cfg.set("knock-back-dist", knockBack);
cfg.set("timer-delay-ticks", timerTicks);
cfg.set("dynmap-border-enabled", dynmapEnable);
cfg.set("dynmap-border-message", dynmapMessage);
cfg.set("worlds", null);
Iterator world = borders.entrySet().iterator();

View File

@ -0,0 +1,234 @@
package com.wimbli.WorldBorder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.World;
import org.dynmap.DynmapAPI;
import org.dynmap.markers.AreaMarker;
import org.dynmap.markers.CircleMarker;
import org.dynmap.markers.MarkerAPI;
import org.dynmap.markers.MarkerSet;
public class DynMapFeatures
{
private static DynmapAPI api;
private static MarkerAPI markApi;
private static MarkerSet markSet;
// Whether re-rendering functionality is available
public static boolean renderEnabled()
{
return api != null;
}
// Whether circular border markers are available
public static boolean borderEnabled()
{
return markApi != null;
}
public static void setup()
{
Plugin test = Bukkit.getServer().getPluginManager().getPlugin("dynmap");
if (test == null || !test.isEnabled()) return;
api = (DynmapAPI)test;
// make sure DynMap version is new enough to include circular markers
try
{
Class.forName("org.dynmap.markers.CircleMarker");
// for version 0.35 of DynMap, CircleMarkers had just been introduced and were bugged (center position always 0,0)
if (api.getDynmapVersion().startsWith("0.35-"))
throw new ClassNotFoundException();
}
catch (ClassNotFoundException ex)
{
Config.LogConfig("DynMap is available, but border display is currently disabled: you need DynMap v0.36 or newer.");
return;
}
markApi = api.getMarkerAPI();
if (markApi == null) return;
// go ahead and show borders for all worlds
showAllBorders();
Config.LogConfig("Successfully hooked into DynMap for the ability to display borders.");
}
/*
* Re-rendering methods, used for updating trimmed chunks to show them as gone
* Sadly, not currently working. Might not even be possible to make it work.
*/
public static void renderRegion(String worldName, CoordXZ coord)
{
if (!renderEnabled()) return;
World world = Bukkit.getWorld(worldName);
int y = (world != null) ? world.getMaxHeight() : 255;
int x = CoordXZ.regionToBlock(coord.x);
int z = CoordXZ.regionToBlock(coord.z);
api.triggerRenderOfVolume(worldName, x, 0, z, x+511, y, z+511);
}
public static void renderChunks(String worldName, List<CoordXZ> coords)
{
if (!renderEnabled()) return;
World world = Bukkit.getWorld(worldName);
int y = (world != null) ? world.getMaxHeight() : 255;
for (CoordXZ coord : coords)
{
renderChunk(worldName, coord, y);
}
}
public static void renderChunk(String worldName, CoordXZ coord, int maxY)
{
if (!renderEnabled()) return;
int x = CoordXZ.chunkToBlock(coord.x);
int z = CoordXZ.chunkToBlock(coord.z);
api.triggerRenderOfVolume(worldName, x, 0, z, x+15, maxY, z+15);
}
/*
* Methods for displaying our borders on DynMap's world maps
*/
private static Map<String, CircleMarker> roundBorders = new HashMap<String, CircleMarker>();
private static Map<String, AreaMarker> squareBorders = new HashMap<String, AreaMarker>();
public static void showAllBorders()
{
if (!borderEnabled()) return;
// in case any borders are already shown
removeAllBorders();
if (!Config.DynmapBorderEnabled())
{
// don't want to show the marker set in DynMap if our integration is disabled
if (markSet != null)
markSet.deleteMarkerSet();
markSet = null;
return;
}
// make sure the marker set is initialized
markSet = markApi.getMarkerSet("worldborder.markerset");
if(markSet == null)
markSet = markApi.createMarkerSet("worldborder.markerset", "WorldBorder", null, false);
else
markSet.setMarkerSetLabel("WorldBorder");
Map<String, BorderData> borders = Config.getBorders();
Iterator worlds = borders.entrySet().iterator();
while(worlds.hasNext())
{
Entry wdata = (Entry)worlds.next();
String worldName = ((String)wdata.getKey());
BorderData border = (BorderData)wdata.getValue();
showBorder(worldName, border);
}
}
public static void showBorder(String worldName, BorderData border)
{
if (!borderEnabled()) return;
if (!Config.DynmapBorderEnabled()) return;
if ((border.getShape() == null) ? Config.ShapeRound() : border.getShape())
showRoundBorder(worldName, border);
else
showSquareBorder(worldName, border);
}
private static void showRoundBorder(String worldName, BorderData border)
{
if (squareBorders.containsKey(worldName))
removeBorder(worldName);
CircleMarker marker = roundBorders.get(worldName);
if (marker == null)
{
marker = markSet.createCircleMarker("worldborder_"+worldName, Config.DynmapMessage(), false, worldName, border.getX(), 64.0, border.getZ(), border.getRadius(), border.getRadius(), true);
marker.setLineStyle(3, 1.0, 0xFF0000);
marker.setFillStyle(0.0, 0x000000);
roundBorders.put(worldName, marker);
}
else
{
marker.setCenter(worldName, border.getX(), 64.0, border.getZ());
marker.setRadius(border.getRadius(), border.getRadius());
}
}
private static void showSquareBorder(String worldName, BorderData border)
{
if (roundBorders.containsKey(worldName))
removeBorder(worldName);
// corners of the square border
double[] xVals = {border.getX() - border.getRadius(), border.getX() + border.getRadius()};
double[] zVals = {border.getZ() - border.getRadius(), border.getZ() + border.getRadius()};
AreaMarker marker = squareBorders.get(worldName);
if (marker == null)
{
marker = markSet.createAreaMarker("worldborder_"+worldName, Config.DynmapMessage(), false, worldName, xVals, zVals, true);
marker.setLineStyle(3, 1.0, 0xFF0000);
marker.setFillStyle(0.0, 0x000000);
squareBorders.put(worldName, marker);
}
else
{
marker.setCornerLocations(xVals, zVals);
}
}
public static void removeAllBorders()
{
if (!borderEnabled()) return;
for(CircleMarker marker : roundBorders.values())
{
marker.deleteMarker();
}
roundBorders.clear();
for(AreaMarker marker : squareBorders.values())
{
marker.deleteMarker();
}
squareBorders.clear();
}
public static void removeBorder(String worldName)
{
if (!borderEnabled()) return;
CircleMarker marker = roundBorders.remove(worldName);
if (marker != null)
marker.deleteMarker();
AreaMarker marker2 = squareBorders.remove(worldName);
if (marker2 != null)
marker2.deleteMarker();
}
}

View File

@ -319,7 +319,7 @@ public class WBCommand implements CommandExecutor
{
if (!Config.HasPermission(player, "debug")) return true;
Config.setDebug(split[1].equalsIgnoreCase("on"));
Config.setDebug(strAsBool(split[1]));
if (player != null)
Config.Log((Config.Debug() ? "Enabling" : "Disabling") + " debug output at the command of player \"" + player.getName() + "\".");
@ -333,7 +333,7 @@ public class WBCommand implements CommandExecutor
{
if (!Config.HasPermission(player, "whoosh")) return true;
Config.setWhooshEffect(split[1].equalsIgnoreCase("on"));
Config.setWhooshEffect(strAsBool(split[1]));
if (player != null)
Config.Log((Config.whooshEffect() ? "Enabling" : "Disabling") + " \"whoosh\" knockback effect at the command of player \"" + player.getName() + "\".");
@ -556,6 +556,42 @@ public class WBCommand implements CommandExecutor
cmdTrim(sender, player, world, confirm, cancel, pause, pad, frequency);
}
// "dynmap" command from player or console
else if (split.length == 2 && split[0].equalsIgnoreCase("dynmap"))
{
if (!Config.HasPermission(player, "dynmap")) return true;
Config.setDynmapBorderEnabled(strAsBool(split[1]));
if (player != null)
Config.Log((Config.Debug() ? "Enabling" : "Disabling") + " DynMap border display at the command of player \"" + player.getName() + "\".");
if (player != null)
sender.sendMessage("DynMap border display " + (Config.Debug() ? "enabled" : "disabled") + ".");
}
// "dynmapmsg" command from player or console
else if (split.length >= 2 && split[0].equalsIgnoreCase("dynmapmsg"))
{
if (!Config.HasPermission(player, "dynmapmsg")) return true;
String message = "";
for(int i = 1; i < split.length; i++)
{
if (i != 1)
message += ' ';
message += split[i];
}
Config.setDynmapMessage(message);
if (player != null)
{
sender.sendMessage("DynMap border label is now set to:");
sender.sendMessage(clrErr + Config.DynmapMessage());
}
}
// we couldn't decipher any known commands, so show help
else
{
@ -571,11 +607,11 @@ public class WBCommand implements CommandExecutor
catch(NumberFormatException ex)
{
}
if (page > 2)
if (page > 3)
page = 1;
}
sender.sendMessage(clrHead + plugin.getDescription().getFullName() + " - commands (" + clrReq + "<required> " + clrOpt + "[optional]" + clrHead + ")" + (page > 0 ? " " + page + "/2" : "") + ":");
sender.sendMessage(clrHead + plugin.getDescription().getFullName() + " - commands (" + clrReq + "<required> " + clrOpt + "[optional]" + clrHead + ")" + (page > 0 ? " " + page + "/3" : "") + ":");
if (page == 0 || page == 1)
{
@ -591,7 +627,6 @@ public class WBCommand implements CommandExecutor
if (page == 1)
sender.sendMessage(cmd+" 2" + clrDesc + " - view second page of commands.");
}
if (page == 0 || page == 2)
{
sender.sendMessage(cmdW+" fill " + clrOpt + "[freq] [pad]" + clrDesc + " - generate world out to border.");
@ -602,9 +637,15 @@ public class WBCommand implements CommandExecutor
sender.sendMessage(cmd+" whoosh " + clrReq + "<on|off>" + clrDesc + " - turn knockback effect on or off.");
sender.sendMessage(cmd+" delay " + clrReq + "<amount>" + clrDesc + " - time between border checks.");
sender.sendMessage(cmd+" reload" + clrDesc + " - re-load data from config.yml.");
if (player == null)
sender.sendMessage(cmd+" debug " + clrReq + "<on|off>" + clrDesc + " - turn console debug output on or off.");
if (page == 2)
sender.sendMessage(cmd+" 3" + clrDesc + " - view third page of commands.");
}
if (page == 0 || page == 3)
{
sender.sendMessage(cmd+" dynmap " + clrReq + "<on|off>" + clrDesc + " - turn DynMap border display on or off.");
sender.sendMessage(cmd+" dynmapmsg " + clrReq + "<text>" + clrDesc + " - DynMap border labels will show this.");
sender.sendMessage(cmd+" debug " + clrReq + "<on|off>" + clrDesc + " - turn console debug output on or off.");
if (page == 3)
sender.sendMessage(cmd + clrDesc + " - view first page of commands.");
}
}
@ -613,6 +654,16 @@ public class WBCommand implements CommandExecutor
}
private boolean strAsBool(String str)
{
str = str.toLowerCase();
if (str.startsWith("y") || str.startsWith("t") || str.startsWith("on") || str.startsWith("+") || str.startsWith("1"))
{
return true;
}
return false;
}
private boolean cmdSet(CommandSender sender, String world, String[] data, int offset)
{
int radius;

View File

@ -12,20 +12,24 @@ public class WorldBorder extends JavaPlugin
// Load (or create new) config file
Config.load(this, false);
// Well I for one find this info useful, so...
Location spawn = getServer().getWorlds().get(0).getSpawnLocation();
System.out.println("For reference, the main world's spawn location is at X: " + (int)spawn.getX() + " Y: " + (int)spawn.getY() + " Z: " + (int)spawn.getZ());
// our one real command, though it does also have aliases "wb" and "worldborder"
getCommand("wborder").setExecutor(new WBCommand(this));
// keep an eye on teleports, to redirect them to a spot inside the border if necessary
getServer().getPluginManager().registerEvents(new WBListener(), this);
// integrate with DynMap if it's available
DynMapFeatures.setup();
// Well I for one find this info useful, so...
Location spawn = getServer().getWorlds().get(0).getSpawnLocation();
System.out.println("For reference, the main world's spawn location is at X: " + Config.coord.format(spawn.getX()) + " Y: " + Config.coord.format(spawn.getY()) + " Z: " + Config.coord.format(spawn.getZ()));
}
@Override
public void onDisable()
{
DynMapFeatures.removeAllBorders();
Config.StopBorderTimer();
Config.StoreFillTask();
Config.StopFillTask();

View File

@ -133,6 +133,12 @@ public class WorldTrimTask implements Runnable
sendMessage("Error! Region file which is outside the border could not be deleted: "+regionFile.getName());
wipeChunks();
}
else
{
// if DynMap is installed, re-render the trimmed region ... disabled since it's not currently working, oh well
// DynMapFeatures.renderRegion(world.getName(), new CoordXZ(regionX, regionZ));
}
nextFile();
continue;
}
@ -280,6 +286,10 @@ public class WorldTrimTask implements Runnable
unChunk.writeInt(0);
}
unChunk.close();
// if DynMap is installed, re-render the trimmed chunks ... disabled since it's not currently working, oh well
// DynMapFeatures.renderChunks(world.getName(), trimChunks);
reportTrimmedChunks += trimChunks.size();
}
catch (FileNotFoundException ex)

View File

@ -1,12 +1,10 @@
name: WorldBorder
author: Brettflan
description: Efficient, feature-rich plugin for limiting the size of your worlds.
version: 1.5.3
version: 1.5.4_dev
main: com.wimbli.WorldBorder.WorldBorder
softdepend:
- Essentials
- GroupManager
- Permissions
- dynmap
commands:
wborder:
description: Primary command for WorldBorder.
@ -28,6 +26,8 @@ commands:
/<command> wshape [world] <round|square|default> - override shape.
/<command> [world] fill [freq] [pad] - generate world out to border.
/<command> [world] trim [freq] [pad] - trim world outside of border.
/<command> dynmap <on/off> - turn DynMap border display on or off.
/<command> dynmapmsg <text> - DynMap border labels will show this.
/<command> debug <on/off> - turn debug mode on or off.
permissions:
worldborder.*:
@ -49,6 +49,8 @@ permissions:
worldborder.trim: true
worldborder.help: true
worldborder.whoosh: true
worldborder.dynmap: true
worldborder.dynmapmsg: true
worldborder.set:
description: Can set borders for any world
default: op
@ -97,3 +99,9 @@ permissions:
worldborder.whoosh:
description: Can enable/disable "whoosh" knockback effect
default: op
worldborder.dynmap:
description: Can enable/disable DynMap border display integration
default: op
worldborder.dynmapmsg:
description: Can set the label text for borders shown in DynMap
default: op