mirror of
https://github.com/PryPurity/WorldBorder.git
synced 2024-11-25 12:05:15 +01:00
Reformated + Update to support 1.15+
This commit is contained in:
parent
44f388f3ba
commit
35f4af67c2
11
pom.xml
11
pom.xml
@ -1,5 +1,5 @@
|
|||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.wimbli.WorldBorder</groupId>
|
<groupId>com.wimbli.WorldBorder</groupId>
|
||||||
<artifactId>WorldBorder</artifactId>
|
<artifactId>WorldBorder</artifactId>
|
||||||
@ -35,14 +35,14 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
<artifactId>spigot-api</artifactId>
|
<artifactId>spigot-api</artifactId>
|
||||||
<version>1.14-R0.1-SNAPSHOT</version>
|
<version>1.15.2-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--Bukkit API-->
|
<!--Bukkit API-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bukkit</groupId>
|
<groupId>org.bukkit</groupId>
|
||||||
<artifactId>bukkit</artifactId>
|
<artifactId>bukkit</artifactId>
|
||||||
<version>1.14-R0.1-SNAPSHOT</version>
|
<version>1.15.2-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--Dynmap API-->
|
<!--Dynmap API-->
|
||||||
@ -78,7 +78,8 @@
|
|||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.1.1</version>
|
<version>3.1.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml</dependencyReducedPomLocation>
|
<dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml
|
||||||
|
</dependencyReducedPomLocation>
|
||||||
<relocations>
|
<relocations>
|
||||||
<relocation>
|
<relocation>
|
||||||
<pattern>io.papermc.lib</pattern>
|
<pattern>io.papermc.lib</pattern>
|
||||||
|
@ -9,11 +9,9 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
|
|
||||||
|
|
||||||
public class BlockPlaceListener implements Listener
|
public class BlockPlaceListener implements Listener {
|
||||||
{
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
public void onBlockPlace(BlockPlaceEvent event)
|
public void onBlockPlace(BlockPlaceEvent event) {
|
||||||
{
|
|
||||||
Location loc = event.getBlockPlaced().getLocation();
|
Location loc = event.getBlockPlaced().getLocation();
|
||||||
if (loc == null) return;
|
if (loc == null) return;
|
||||||
|
|
||||||
@ -22,14 +20,12 @@ public class BlockPlaceListener implements Listener
|
|||||||
BorderData border = Config.Border(world.getName());
|
BorderData border = Config.Border(world.getName());
|
||||||
if (border == null) return;
|
if (border == null) return;
|
||||||
|
|
||||||
if (!border.insideBorder(loc.getX(), loc.getZ(), Config.ShapeRound()))
|
if (!border.insideBorder(loc.getX(), loc.getZ(), Config.ShapeRound())) {
|
||||||
{
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregister()
|
public void unregister() {
|
||||||
{
|
|
||||||
HandlerList.unregisterAll(this);
|
HandlerList.unregisterAll(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,46 +1,24 @@
|
|||||||
package com.wimbli.WorldBorder;
|
package com.wimbli.WorldBorder;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
import org.bukkit.World;
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
public class BorderCheckTask implements Runnable
|
public class BorderCheckTask implements Runnable {
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
// if knockback is set to 0, simply return
|
|
||||||
if (Config.KnockBack() == 0.0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Collection<Player> players = ImmutableList.copyOf(Bukkit.getServer().getOnlinePlayers());
|
|
||||||
|
|
||||||
for (Player player : players)
|
|
||||||
{
|
|
||||||
checkPlayer(player, null, false, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// track players who are being handled (moved back inside the border) already; needed since Bukkit is sometimes sending teleport events with the old (now incorrect) location still indicated, which can lead to a loop when we then teleport them thinking they're outside the border, triggering event again, etc.
|
// track players who are being handled (moved back inside the border) already; needed since Bukkit is sometimes sending teleport events with the old (now incorrect) location still indicated, which can lead to a loop when we then teleport them thinking they're outside the border, triggering event again, etc.
|
||||||
private static Set<String> handlingPlayers = Collections.synchronizedSet(new LinkedHashSet<String>());
|
private static Set<String> handlingPlayers = Collections.synchronizedSet(new LinkedHashSet<String>());
|
||||||
|
|
||||||
// set targetLoc only if not current player location; set returnLocationOnly to true to have new Location returned if they need to be moved to one, instead of directly handling it
|
// set targetLoc only if not current player location; set returnLocationOnly to true to have new Location returned if they need to be moved to one, instead of directly handling it
|
||||||
public static Location checkPlayer(Player player, Location targetLoc, boolean returnLocationOnly, boolean notify)
|
public static Location checkPlayer(Player player, Location targetLoc, boolean returnLocationOnly, boolean notify) {
|
||||||
{
|
|
||||||
if (player == null || !player.isOnline()) return null;
|
if (player == null || !player.isOnline()) return null;
|
||||||
|
|
||||||
Location loc = (targetLoc == null) ? player.getLocation().clone() : targetLoc;
|
Location loc = (targetLoc == null) ? player.getLocation().clone() : targetLoc;
|
||||||
@ -71,12 +49,10 @@ public class BorderCheckTask implements Runnable
|
|||||||
* after players are ejected we can wait a few ticks (long enough for their client to receive new entity location)
|
* after players are ejected we can wait a few ticks (long enough for their client to receive new entity location)
|
||||||
* and then set them as passenger of the vehicle again
|
* and then set them as passenger of the vehicle again
|
||||||
*/
|
*/
|
||||||
if (player.isInsideVehicle())
|
if (player.isInsideVehicle()) {
|
||||||
{
|
|
||||||
Entity ride = player.getVehicle();
|
Entity ride = player.getVehicle();
|
||||||
player.leaveVehicle();
|
player.leaveVehicle();
|
||||||
if (ride != null)
|
if (ride != null) { // vehicles need to be offset vertically and have velocity stopped
|
||||||
{ // vehicles need to be offset vertically and have velocity stopped
|
|
||||||
double vertOffset = (ride instanceof LivingEntity) ? 0 : ride.getLocation().getY() - loc.getY();
|
double vertOffset = (ride instanceof LivingEntity) ? 0 : ride.getLocation().getY() - loc.getY();
|
||||||
Location rideLoc = newLoc.clone();
|
Location rideLoc = newLoc.clone();
|
||||||
rideLoc.setY(newLoc.getY() + vertOffset);
|
rideLoc.setY(newLoc.getY() + vertOffset);
|
||||||
@ -86,8 +62,7 @@ public class BorderCheckTask implements Runnable
|
|||||||
ride.setVelocity(new Vector(0, 0, 0));
|
ride.setVelocity(new Vector(0, 0, 0));
|
||||||
ride.teleport(rideLoc, TeleportCause.PLUGIN);
|
ride.teleport(rideLoc, TeleportCause.PLUGIN);
|
||||||
|
|
||||||
if (Config.RemountTicks() > 0)
|
if (Config.RemountTicks() > 0) {
|
||||||
{
|
|
||||||
setPassengerDelayed(ride, player, player.getName(), Config.RemountTicks());
|
setPassengerDelayed(ride, player, player.getName(), Config.RemountTicks());
|
||||||
handlingVehicle = true;
|
handlingVehicle = true;
|
||||||
}
|
}
|
||||||
@ -97,11 +72,9 @@ public class BorderCheckTask implements Runnable
|
|||||||
// check if player has something (a pet, maybe?) riding them; only possible through odd plugins.
|
// check if player has something (a pet, maybe?) riding them; only possible through odd plugins.
|
||||||
// it can prevent all teleportation of the player completely, so it's very much not good and needs handling
|
// it can prevent all teleportation of the player completely, so it's very much not good and needs handling
|
||||||
List<Entity> passengers = player.getPassengers();
|
List<Entity> passengers = player.getPassengers();
|
||||||
if (!passengers.isEmpty())
|
if (!passengers.isEmpty()) {
|
||||||
{
|
|
||||||
player.eject();
|
player.eject();
|
||||||
for (Entity rider : passengers)
|
for (Entity rider : passengers) {
|
||||||
{
|
|
||||||
rider.teleport(newLoc, TeleportCause.PLUGIN);
|
rider.teleport(newLoc, TeleportCause.PLUGIN);
|
||||||
if (Config.Debug())
|
if (Config.Debug())
|
||||||
Config.logWarn("Player had a passenger riding on them: " + rider.getType());
|
Config.logWarn("Player had a passenger riding on them: " + rider.getType());
|
||||||
@ -123,15 +96,13 @@ public class BorderCheckTask implements Runnable
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public static Location checkPlayer(Player player, Location targetLoc, boolean returnLocationOnly)
|
|
||||||
{
|
public static Location checkPlayer(Player player, Location targetLoc, boolean returnLocationOnly) {
|
||||||
return checkPlayer(player, targetLoc, returnLocationOnly, true);
|
return checkPlayer(player, targetLoc, returnLocationOnly, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Location newLocation(Player player, Location loc, BorderData border, boolean notify)
|
private static Location newLocation(Player player, Location loc, BorderData border, boolean notify) {
|
||||||
{
|
if (Config.Debug()) {
|
||||||
if (Config.Debug())
|
|
||||||
{
|
|
||||||
Config.logWarn((notify ? "Border crossing" : "Check was run") + " in \"" + loc.getWorld().getName() + "\". Border " + border.toString());
|
Config.logWarn((notify ? "Border crossing" : "Check was run") + " in \"" + loc.getWorld().getName() + "\". Border " + border.toString());
|
||||||
Config.logWarn("Player position X: " + Config.coord.format(loc.getX()) + " Y: " + Config.coord.format(loc.getY()) + " Z: " + Config.coord.format(loc.getZ()));
|
Config.logWarn("Player position X: " + Config.coord.format(loc.getX()) + " Y: " + Config.coord.format(loc.getY()) + " Z: " + Config.coord.format(loc.getZ()));
|
||||||
}
|
}
|
||||||
@ -139,12 +110,10 @@ public class BorderCheckTask implements Runnable
|
|||||||
Location newLoc = border.correctedPosition(loc, Config.ShapeRound(), player.isFlying());
|
Location newLoc = border.correctedPosition(loc, Config.ShapeRound(), player.isFlying());
|
||||||
|
|
||||||
// it's remotely possible (such as in the Nether) a suitable location isn't available, in which case...
|
// it's remotely possible (such as in the Nether) a suitable location isn't available, in which case...
|
||||||
if (newLoc == null)
|
if (newLoc == null) {
|
||||||
{
|
|
||||||
if (Config.Debug())
|
if (Config.Debug())
|
||||||
Config.logWarn("Target new location unviable, using spawn or killing player.");
|
Config.logWarn("Target new location unviable, using spawn or killing player.");
|
||||||
if (Config.getIfPlayerKill())
|
if (Config.getIfPlayerKill()) {
|
||||||
{
|
|
||||||
player.setHealth(0.0D);
|
player.setHealth(0.0D);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -160,13 +129,10 @@ public class BorderCheckTask implements Runnable
|
|||||||
return newLoc;
|
return newLoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setPassengerDelayed(final Entity vehicle, final Player player, final String playerName, long delay)
|
private static void setPassengerDelayed(final Entity vehicle, final Player player, final String playerName, long delay) {
|
||||||
{
|
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(WorldBorder.plugin, new Runnable() {
|
||||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(WorldBorder.plugin, new Runnable()
|
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run() {
|
||||||
{
|
|
||||||
handlingPlayers.remove(playerName.toLowerCase());
|
handlingPlayers.remove(playerName.toLowerCase());
|
||||||
if (vehicle == null || player == null)
|
if (vehicle == null || player == null)
|
||||||
return;
|
return;
|
||||||
@ -175,4 +141,17 @@ public class BorderCheckTask implements Runnable
|
|||||||
}
|
}
|
||||||
}, delay);
|
}, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// if knockback is set to 0, simply return
|
||||||
|
if (Config.KnockBack() == 0.0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Collection<Player> players = ImmutableList.copyOf(Bukkit.getServer().getOnlinePlayers());
|
||||||
|
|
||||||
|
for (Player player : players) {
|
||||||
|
checkPlayer(player, null, false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,299 +1,21 @@
|
|||||||
package com.wimbli.WorldBorder;
|
package com.wimbli.WorldBorder;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
|
||||||
|
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
public class BorderData
|
|
||||||
{
|
|
||||||
// the main data interacted with
|
|
||||||
private double x = 0;
|
|
||||||
private double z = 0;
|
|
||||||
private int radiusX = 0;
|
|
||||||
private int radiusZ = 0;
|
|
||||||
private Boolean shapeRound = null;
|
|
||||||
private boolean wrapping = false;
|
|
||||||
|
|
||||||
// some extra data kept handy for faster border checks
|
|
||||||
private double maxX;
|
|
||||||
private double minX;
|
|
||||||
private double maxZ;
|
|
||||||
private double minZ;
|
|
||||||
private double radiusXSquared;
|
|
||||||
private double radiusZSquared;
|
|
||||||
private double DefiniteRectangleX;
|
|
||||||
private double DefiniteRectangleZ;
|
|
||||||
private double radiusSquaredQuotient;
|
|
||||||
|
|
||||||
public BorderData(double x, double z, int radiusX, int radiusZ, Boolean shapeRound, boolean wrap)
|
|
||||||
{
|
|
||||||
setData(x, z, radiusX, radiusZ, shapeRound, wrap);
|
|
||||||
}
|
|
||||||
public BorderData(double x, double z, int radiusX, int radiusZ)
|
|
||||||
{
|
|
||||||
setData(x, z, radiusX, radiusZ, null);
|
|
||||||
}
|
|
||||||
public BorderData(double x, double z, int radiusX, int radiusZ, Boolean shapeRound)
|
|
||||||
{
|
|
||||||
setData(x, z, radiusX, radiusZ, shapeRound);
|
|
||||||
}
|
|
||||||
public BorderData(double x, double z, int radius)
|
|
||||||
{
|
|
||||||
setData(x, z, radius, null);
|
|
||||||
}
|
|
||||||
public BorderData(double x, double z, int radius, Boolean shapeRound)
|
|
||||||
{
|
|
||||||
setData(x, z, radius, shapeRound);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void setData(double x, double z, int radiusX, int radiusZ, Boolean shapeRound, boolean wrap)
|
|
||||||
{
|
|
||||||
this.x = x;
|
|
||||||
this.z = z;
|
|
||||||
this.shapeRound = shapeRound;
|
|
||||||
this.wrapping = wrap;
|
|
||||||
this.setRadiusX(radiusX);
|
|
||||||
this.setRadiusZ(radiusZ);
|
|
||||||
}
|
|
||||||
public final void setData(double x, double z, int radiusX, int radiusZ, Boolean shapeRound)
|
|
||||||
{
|
|
||||||
setData(x, z, radiusX, radiusZ, shapeRound, false);
|
|
||||||
}
|
|
||||||
public final void setData(double x, double z, int radius, Boolean shapeRound)
|
|
||||||
{
|
|
||||||
setData(x, z, radius, radius, shapeRound, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BorderData copy()
|
|
||||||
{
|
|
||||||
return new BorderData(x, z, radiusX, radiusZ, shapeRound, wrapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getX()
|
|
||||||
{
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
public void setX(double x)
|
|
||||||
{
|
|
||||||
this.x = x;
|
|
||||||
this.maxX = x + radiusX;
|
|
||||||
this.minX = x - radiusX;
|
|
||||||
}
|
|
||||||
public double getZ()
|
|
||||||
{
|
|
||||||
return z;
|
|
||||||
}
|
|
||||||
public void setZ(double z)
|
|
||||||
{
|
|
||||||
this.z = z;
|
|
||||||
this.maxZ = z + radiusZ;
|
|
||||||
this.minZ = z - radiusZ;
|
|
||||||
}
|
|
||||||
public int getRadiusX()
|
|
||||||
{
|
|
||||||
return radiusX;
|
|
||||||
}
|
|
||||||
public int getRadiusZ()
|
|
||||||
{
|
|
||||||
return radiusZ;
|
|
||||||
}
|
|
||||||
public void setRadiusX(int radiusX)
|
|
||||||
{
|
|
||||||
this.radiusX = radiusX;
|
|
||||||
this.maxX = x + radiusX;
|
|
||||||
this.minX = x - radiusX;
|
|
||||||
this.radiusXSquared = (double)radiusX * (double)radiusX;
|
|
||||||
this.radiusSquaredQuotient = this.radiusXSquared / this.radiusZSquared;
|
|
||||||
this.DefiniteRectangleX = Math.sqrt(.5 * this.radiusXSquared);
|
|
||||||
}
|
|
||||||
public void setRadiusZ(int radiusZ)
|
|
||||||
{
|
|
||||||
this.radiusZ = radiusZ;
|
|
||||||
this.maxZ = z + radiusZ;
|
|
||||||
this.minZ = z - radiusZ;
|
|
||||||
this.radiusZSquared = (double)radiusZ * (double)radiusZ;
|
|
||||||
this.radiusSquaredQuotient = this.radiusXSquared / this.radiusZSquared;
|
|
||||||
this.DefiniteRectangleZ = Math.sqrt(.5 * this.radiusZSquared);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// backwards-compatible methods from before elliptical/rectangular shapes were supported
|
public class BorderData {
|
||||||
/**
|
|
||||||
* @deprecated Replaced by {@link #getRadiusX()} and {@link #getRadiusZ()};
|
|
||||||
* this method now returns an average of those two values and is thus imprecise
|
|
||||||
*/
|
|
||||||
public int getRadius()
|
|
||||||
{
|
|
||||||
return (radiusX + radiusZ) / 2; // average radius; not great, but probably best for backwards compatibility
|
|
||||||
}
|
|
||||||
public void setRadius(int radius)
|
|
||||||
{
|
|
||||||
setRadiusX(radius);
|
|
||||||
setRadiusZ(radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Boolean getShape()
|
|
||||||
{
|
|
||||||
return shapeRound;
|
|
||||||
}
|
|
||||||
public void setShape(Boolean shapeRound)
|
|
||||||
{
|
|
||||||
this.shapeRound = shapeRound;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean getWrapping()
|
|
||||||
{
|
|
||||||
return wrapping;
|
|
||||||
}
|
|
||||||
public void setWrapping(boolean wrap)
|
|
||||||
{
|
|
||||||
this.wrapping = wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return "radius " + ((radiusX == radiusZ) ? radiusX : radiusX + "x" + radiusZ) + " at X: " + Config.coord.format(x) + " Z: " + Config.coord.format(z) + (shapeRound != null ? (" (shape override: " + Config.ShapeName(shapeRound.booleanValue()) + ")") : "") + (wrapping ? (" (wrapping)") : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
// This algorithm of course needs to be fast, since it will be run very frequently
|
|
||||||
public boolean insideBorder(double xLoc, double zLoc, boolean round)
|
|
||||||
{
|
|
||||||
// if this border has a shape override set, use it
|
|
||||||
if (shapeRound != null)
|
|
||||||
round = shapeRound.booleanValue();
|
|
||||||
|
|
||||||
// square border
|
|
||||||
if (!round)
|
|
||||||
return !(xLoc < minX || xLoc > maxX || zLoc < minZ || zLoc > maxZ);
|
|
||||||
|
|
||||||
// round border
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// elegant round border checking algorithm is from rBorder by Reil with almost no changes, all credit to him for it
|
|
||||||
double X = Math.abs(x - xLoc);
|
|
||||||
double Z = Math.abs(z - zLoc);
|
|
||||||
|
|
||||||
if (X < DefiniteRectangleX && Z < DefiniteRectangleZ)
|
|
||||||
return true; // Definitely inside
|
|
||||||
else if (X >= radiusX || Z >= radiusZ)
|
|
||||||
return false; // Definitely outside
|
|
||||||
else if (X * X + Z * Z * radiusSquaredQuotient < radiusXSquared)
|
|
||||||
return true; // After further calculation, inside
|
|
||||||
else
|
|
||||||
return false; // Apparently outside, then
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public boolean insideBorder(double xLoc, double zLoc)
|
|
||||||
{
|
|
||||||
return insideBorder(xLoc, zLoc, Config.ShapeRound());
|
|
||||||
}
|
|
||||||
public boolean insideBorder(Location loc)
|
|
||||||
{
|
|
||||||
return insideBorder(loc.getX(), loc.getZ(), Config.ShapeRound());
|
|
||||||
}
|
|
||||||
public boolean insideBorder(CoordXZ coord, boolean round)
|
|
||||||
{
|
|
||||||
return insideBorder(coord.x, coord.z, round);
|
|
||||||
}
|
|
||||||
public boolean insideBorder(CoordXZ coord)
|
|
||||||
{
|
|
||||||
return insideBorder(coord.x, coord.z, Config.ShapeRound());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Location correctedPosition(Location loc, boolean round, boolean flying)
|
|
||||||
{
|
|
||||||
// if this border has a shape override set, use it
|
|
||||||
if (shapeRound != null)
|
|
||||||
round = shapeRound.booleanValue();
|
|
||||||
|
|
||||||
double xLoc = loc.getX();
|
|
||||||
double zLoc = loc.getZ();
|
|
||||||
double yLoc = loc.getY();
|
|
||||||
|
|
||||||
// square border
|
|
||||||
if (!round)
|
|
||||||
{
|
|
||||||
if (wrapping)
|
|
||||||
{
|
|
||||||
if (xLoc <= minX)
|
|
||||||
xLoc = maxX - Config.KnockBack();
|
|
||||||
else if (xLoc >= maxX)
|
|
||||||
xLoc = minX + Config.KnockBack();
|
|
||||||
if (zLoc <= minZ)
|
|
||||||
zLoc = maxZ - Config.KnockBack();
|
|
||||||
else if (zLoc >= maxZ)
|
|
||||||
zLoc = minZ + Config.KnockBack();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (xLoc <= minX)
|
|
||||||
xLoc = minX + Config.KnockBack();
|
|
||||||
else if (xLoc >= maxX)
|
|
||||||
xLoc = maxX - Config.KnockBack();
|
|
||||||
if (zLoc <= minZ)
|
|
||||||
zLoc = minZ + Config.KnockBack();
|
|
||||||
else if (zLoc >= maxZ)
|
|
||||||
zLoc = maxZ - Config.KnockBack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// round border
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// algorithm originally from: http://stackoverflow.com/questions/300871/best-way-to-find-a-point-on-a-circle-closest-to-a-given-point
|
|
||||||
// modified by Lang Lukas to support elliptical border shape
|
|
||||||
|
|
||||||
//Transform the ellipse to a circle with radius 1 (we need to transform the point the same way)
|
|
||||||
double dX = xLoc - x;
|
|
||||||
double dZ = zLoc - z;
|
|
||||||
double dU = Math.sqrt(dX *dX + dZ * dZ); //distance of the untransformed point from the center
|
|
||||||
double dT = Math.sqrt(dX *dX / radiusXSquared + dZ * dZ / radiusZSquared); //distance of the transformed point from the center
|
|
||||||
double f = (1 / dT - Config.KnockBack() / dU); //"correction" factor for the distances
|
|
||||||
if (wrapping)
|
|
||||||
{
|
|
||||||
xLoc = x - dX * f;
|
|
||||||
zLoc = z - dZ * f;
|
|
||||||
} else {
|
|
||||||
xLoc = x + dX * f;
|
|
||||||
zLoc = z + dZ * f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int ixLoc = Location.locToBlock(xLoc);
|
|
||||||
int izLoc = Location.locToBlock(zLoc);
|
|
||||||
|
|
||||||
// Make sure the chunk we're checking in is actually loaded
|
|
||||||
Chunk tChunk = loc.getWorld().getChunkAt(CoordXZ.blockToChunk(ixLoc), CoordXZ.blockToChunk(izLoc));
|
|
||||||
if (!tChunk.isLoaded())
|
|
||||||
tChunk.load();
|
|
||||||
|
|
||||||
yLoc = getSafeY(loc.getWorld(), ixLoc, Location.locToBlock(yLoc), izLoc, flying);
|
|
||||||
if (yLoc == -1)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return new Location(loc.getWorld(), Math.floor(xLoc) + 0.5, yLoc, Math.floor(zLoc) + 0.5, loc.getYaw(), loc.getPitch());
|
|
||||||
}
|
|
||||||
public Location correctedPosition(Location loc, boolean round)
|
|
||||||
{
|
|
||||||
return correctedPosition(loc, round, false);
|
|
||||||
}
|
|
||||||
public Location correctedPosition(Location loc)
|
|
||||||
{
|
|
||||||
return correctedPosition(loc, Config.ShapeRound(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//these material IDs are acceptable for places to teleport player; breathable blocks and water
|
//these material IDs are acceptable for places to teleport player; breathable blocks and water
|
||||||
public static final EnumSet<Material> safeOpenBlocks = EnumSet.noneOf(Material.class);
|
public static final EnumSet<Material> safeOpenBlocks = EnumSet.noneOf(Material.class);
|
||||||
static
|
//these material IDs are ones we don't want to drop the player onto, like cactus or lava or fire or activated Ender portal
|
||||||
{
|
public static final EnumSet<Material> painfulBlocks = EnumSet.noneOf(Material.class);
|
||||||
|
private static final int limBot = 0;
|
||||||
|
|
||||||
|
static {
|
||||||
safeOpenBlocks.add(Material.AIR);
|
safeOpenBlocks.add(Material.AIR);
|
||||||
safeOpenBlocks.add(Material.CAVE_AIR);
|
safeOpenBlocks.add(Material.CAVE_AIR);
|
||||||
safeOpenBlocks.add(Material.OAK_SAPLING);
|
safeOpenBlocks.add(Material.OAK_SAPLING);
|
||||||
@ -374,8 +96,7 @@ public class BorderData
|
|||||||
safeOpenBlocks.add(Material.TALL_GRASS);
|
safeOpenBlocks.add(Material.TALL_GRASS);
|
||||||
safeOpenBlocks.add(Material.LARGE_FERN);
|
safeOpenBlocks.add(Material.LARGE_FERN);
|
||||||
safeOpenBlocks.add(Material.BEETROOTS);
|
safeOpenBlocks.add(Material.BEETROOTS);
|
||||||
try
|
try { // signs in 1.14 can be different wood types
|
||||||
{ // signs in 1.14 can be different wood types
|
|
||||||
safeOpenBlocks.add(Material.ACACIA_SIGN);
|
safeOpenBlocks.add(Material.ACACIA_SIGN);
|
||||||
safeOpenBlocks.add(Material.ACACIA_WALL_SIGN);
|
safeOpenBlocks.add(Material.ACACIA_WALL_SIGN);
|
||||||
safeOpenBlocks.add(Material.BIRCH_SIGN);
|
safeOpenBlocks.add(Material.BIRCH_SIGN);
|
||||||
@ -388,14 +109,11 @@ public class BorderData
|
|||||||
safeOpenBlocks.add(Material.OAK_WALL_SIGN);
|
safeOpenBlocks.add(Material.OAK_WALL_SIGN);
|
||||||
safeOpenBlocks.add(Material.SPRUCE_SIGN);
|
safeOpenBlocks.add(Material.SPRUCE_SIGN);
|
||||||
safeOpenBlocks.add(Material.SPRUCE_WALL_SIGN);
|
safeOpenBlocks.add(Material.SPRUCE_WALL_SIGN);
|
||||||
|
} catch (NoSuchFieldError ex) {
|
||||||
}
|
}
|
||||||
catch (NoSuchFieldError ex) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//these material IDs are ones we don't want to drop the player onto, like cactus or lava or fire or activated Ender portal
|
static {
|
||||||
public static final EnumSet<Material> painfulBlocks = EnumSet.noneOf(Material.class);
|
|
||||||
static
|
|
||||||
{
|
|
||||||
painfulBlocks.add(Material.LAVA);
|
painfulBlocks.add(Material.LAVA);
|
||||||
painfulBlocks.add(Material.FIRE);
|
painfulBlocks.add(Material.FIRE);
|
||||||
painfulBlocks.add(Material.CACTUS);
|
painfulBlocks.add(Material.CACTUS);
|
||||||
@ -403,9 +121,268 @@ public class BorderData
|
|||||||
painfulBlocks.add(Material.MAGMA_BLOCK);
|
painfulBlocks.add(Material.MAGMA_BLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the main data interacted with
|
||||||
|
private double x = 0;
|
||||||
|
private double z = 0;
|
||||||
|
private int radiusX = 0;
|
||||||
|
private int radiusZ = 0;
|
||||||
|
private Boolean shapeRound = null;
|
||||||
|
private boolean wrapping = false;
|
||||||
|
// some extra data kept handy for faster border checks
|
||||||
|
private double maxX;
|
||||||
|
private double minX;
|
||||||
|
private double maxZ;
|
||||||
|
private double minZ;
|
||||||
|
private double radiusXSquared;
|
||||||
|
private double radiusZSquared;
|
||||||
|
private double DefiniteRectangleX;
|
||||||
|
private double DefiniteRectangleZ;
|
||||||
|
private double radiusSquaredQuotient;
|
||||||
|
|
||||||
|
public BorderData(double x, double z, int radiusX, int radiusZ, Boolean shapeRound, boolean wrap) {
|
||||||
|
setData(x, z, radiusX, radiusZ, shapeRound, wrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BorderData(double x, double z, int radiusX, int radiusZ) {
|
||||||
|
setData(x, z, radiusX, radiusZ, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BorderData(double x, double z, int radiusX, int radiusZ, Boolean shapeRound) {
|
||||||
|
setData(x, z, radiusX, radiusZ, shapeRound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BorderData(double x, double z, int radius) {
|
||||||
|
setData(x, z, radius, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BorderData(double x, double z, int radius, Boolean shapeRound) {
|
||||||
|
setData(x, z, radius, shapeRound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setData(double x, double z, int radiusX, int radiusZ, Boolean shapeRound, boolean wrap) {
|
||||||
|
this.x = x;
|
||||||
|
this.z = z;
|
||||||
|
this.shapeRound = shapeRound;
|
||||||
|
this.wrapping = wrap;
|
||||||
|
this.setRadiusX(radiusX);
|
||||||
|
this.setRadiusZ(radiusZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setData(double x, double z, int radiusX, int radiusZ, Boolean shapeRound) {
|
||||||
|
setData(x, z, radiusX, radiusZ, shapeRound, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setData(double x, double z, int radius, Boolean shapeRound) {
|
||||||
|
setData(x, z, radius, radius, shapeRound, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BorderData copy() {
|
||||||
|
return new BorderData(x, z, radiusX, radiusZ, shapeRound, wrapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(double x) {
|
||||||
|
this.x = x;
|
||||||
|
this.maxX = x + radiusX;
|
||||||
|
this.minX = x - radiusX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// backwards-compatible methods from before elliptical/rectangular shapes were supported
|
||||||
|
|
||||||
|
public void setZ(double z) {
|
||||||
|
this.z = z;
|
||||||
|
this.maxZ = z + radiusZ;
|
||||||
|
this.minZ = z - radiusZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRadiusX() {
|
||||||
|
return radiusX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRadiusX(int radiusX) {
|
||||||
|
this.radiusX = radiusX;
|
||||||
|
this.maxX = x + radiusX;
|
||||||
|
this.minX = x - radiusX;
|
||||||
|
this.radiusXSquared = (double) radiusX * (double) radiusX;
|
||||||
|
this.radiusSquaredQuotient = this.radiusXSquared / this.radiusZSquared;
|
||||||
|
this.DefiniteRectangleX = Math.sqrt(.5 * this.radiusXSquared);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRadiusZ() {
|
||||||
|
return radiusZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRadiusZ(int radiusZ) {
|
||||||
|
this.radiusZ = radiusZ;
|
||||||
|
this.maxZ = z + radiusZ;
|
||||||
|
this.minZ = z - radiusZ;
|
||||||
|
this.radiusZSquared = (double) radiusZ * (double) radiusZ;
|
||||||
|
this.radiusSquaredQuotient = this.radiusXSquared / this.radiusZSquared;
|
||||||
|
this.DefiniteRectangleZ = Math.sqrt(.5 * this.radiusZSquared);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Replaced by {@link #getRadiusX()} and {@link #getRadiusZ()};
|
||||||
|
* this method now returns an average of those two values and is thus imprecise
|
||||||
|
*/
|
||||||
|
public int getRadius() {
|
||||||
|
return (radiusX + radiusZ) / 2; // average radius; not great, but probably best for backwards compatibility
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRadius(int radius) {
|
||||||
|
setRadiusX(radius);
|
||||||
|
setRadiusZ(radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getShape() {
|
||||||
|
return shapeRound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShape(Boolean shapeRound) {
|
||||||
|
this.shapeRound = shapeRound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getWrapping() {
|
||||||
|
return wrapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWrapping(boolean wrap) {
|
||||||
|
this.wrapping = wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "radius " + ((radiusX == radiusZ) ? radiusX : radiusX + "x" + radiusZ) + " at X: " + Config.coord.format(x) + " Z: " + Config.coord.format(z) + (shapeRound != null ? (" (shape override: " + Config.ShapeName(shapeRound.booleanValue()) + ")") : "") + (wrapping ? (" (wrapping)") : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// This algorithm of course needs to be fast, since it will be run very frequently
|
||||||
|
public boolean insideBorder(double xLoc, double zLoc, boolean round) {
|
||||||
|
// if this border has a shape override set, use it
|
||||||
|
if (shapeRound != null)
|
||||||
|
round = shapeRound.booleanValue();
|
||||||
|
|
||||||
|
// square border
|
||||||
|
if (!round)
|
||||||
|
return !(xLoc < minX || xLoc > maxX || zLoc < minZ || zLoc > maxZ);
|
||||||
|
|
||||||
|
// round border
|
||||||
|
else {
|
||||||
|
// elegant round border checking algorithm is from rBorder by Reil with almost no changes, all credit to him for it
|
||||||
|
double X = Math.abs(x - xLoc);
|
||||||
|
double Z = Math.abs(z - zLoc);
|
||||||
|
|
||||||
|
if (X < DefiniteRectangleX && Z < DefiniteRectangleZ)
|
||||||
|
return true; // Definitely inside
|
||||||
|
else if (X >= radiusX || Z >= radiusZ)
|
||||||
|
return false; // Definitely outside
|
||||||
|
else if (X * X + Z * Z * radiusSquaredQuotient < radiusXSquared)
|
||||||
|
return true; // After further calculation, inside
|
||||||
|
else
|
||||||
|
return false; // Apparently outside, then
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean insideBorder(double xLoc, double zLoc) {
|
||||||
|
return insideBorder(xLoc, zLoc, Config.ShapeRound());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean insideBorder(Location loc) {
|
||||||
|
return insideBorder(loc.getX(), loc.getZ(), Config.ShapeRound());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean insideBorder(CoordXZ coord, boolean round) {
|
||||||
|
return insideBorder(coord.x, coord.z, round);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean insideBorder(CoordXZ coord) {
|
||||||
|
return insideBorder(coord.x, coord.z, Config.ShapeRound());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location correctedPosition(Location loc, boolean round, boolean flying) {
|
||||||
|
// if this border has a shape override set, use it
|
||||||
|
if (shapeRound != null)
|
||||||
|
round = shapeRound.booleanValue();
|
||||||
|
|
||||||
|
double xLoc = loc.getX();
|
||||||
|
double zLoc = loc.getZ();
|
||||||
|
double yLoc = loc.getY();
|
||||||
|
|
||||||
|
// square border
|
||||||
|
if (!round) {
|
||||||
|
if (wrapping) {
|
||||||
|
if (xLoc <= minX)
|
||||||
|
xLoc = maxX - Config.KnockBack();
|
||||||
|
else if (xLoc >= maxX)
|
||||||
|
xLoc = minX + Config.KnockBack();
|
||||||
|
if (zLoc <= minZ)
|
||||||
|
zLoc = maxZ - Config.KnockBack();
|
||||||
|
else if (zLoc >= maxZ)
|
||||||
|
zLoc = minZ + Config.KnockBack();
|
||||||
|
} else {
|
||||||
|
if (xLoc <= minX)
|
||||||
|
xLoc = minX + Config.KnockBack();
|
||||||
|
else if (xLoc >= maxX)
|
||||||
|
xLoc = maxX - Config.KnockBack();
|
||||||
|
if (zLoc <= minZ)
|
||||||
|
zLoc = minZ + Config.KnockBack();
|
||||||
|
else if (zLoc >= maxZ)
|
||||||
|
zLoc = maxZ - Config.KnockBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// round border
|
||||||
|
else {
|
||||||
|
// algorithm originally from: http://stackoverflow.com/questions/300871/best-way-to-find-a-point-on-a-circle-closest-to-a-given-point
|
||||||
|
// modified by Lang Lukas to support elliptical border shape
|
||||||
|
|
||||||
|
//Transform the ellipse to a circle with radius 1 (we need to transform the point the same way)
|
||||||
|
double dX = xLoc - x;
|
||||||
|
double dZ = zLoc - z;
|
||||||
|
double dU = Math.sqrt(dX * dX + dZ * dZ); //distance of the untransformed point from the center
|
||||||
|
double dT = Math.sqrt(dX * dX / radiusXSquared + dZ * dZ / radiusZSquared); //distance of the transformed point from the center
|
||||||
|
double f = (1 / dT - Config.KnockBack() / dU); //"correction" factor for the distances
|
||||||
|
if (wrapping) {
|
||||||
|
xLoc = x - dX * f;
|
||||||
|
zLoc = z - dZ * f;
|
||||||
|
} else {
|
||||||
|
xLoc = x + dX * f;
|
||||||
|
zLoc = z + dZ * f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ixLoc = Location.locToBlock(xLoc);
|
||||||
|
int izLoc = Location.locToBlock(zLoc);
|
||||||
|
|
||||||
|
// Make sure the chunk we're checking in is actually loaded
|
||||||
|
Chunk tChunk = loc.getWorld().getChunkAt(CoordXZ.blockToChunk(ixLoc), CoordXZ.blockToChunk(izLoc));
|
||||||
|
if (!tChunk.isLoaded())
|
||||||
|
tChunk.load();
|
||||||
|
|
||||||
|
yLoc = getSafeY(loc.getWorld(), ixLoc, Location.locToBlock(yLoc), izLoc, flying);
|
||||||
|
if (yLoc == -1)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new Location(loc.getWorld(), Math.floor(xLoc) + 0.5, yLoc, Math.floor(zLoc) + 0.5, loc.getYaw(), loc.getPitch());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location correctedPosition(Location loc, boolean round) {
|
||||||
|
return correctedPosition(loc, round, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location correctedPosition(Location loc) {
|
||||||
|
return correctedPosition(loc, Config.ShapeRound(), false);
|
||||||
|
}
|
||||||
|
|
||||||
// check if a particular spot consists of 2 breathable blocks over something relatively solid
|
// check if a particular spot consists of 2 breathable blocks over something relatively solid
|
||||||
private boolean isSafeSpot(World world, int X, int Y, int Z, boolean flying)
|
private boolean isSafeSpot(World world, int X, int Y, int Z, boolean flying) {
|
||||||
{
|
|
||||||
boolean safe = safeOpenBlocks.contains(world.getBlockAt(X, Y, Z).getType()) // target block open and safe
|
boolean safe = safeOpenBlocks.contains(world.getBlockAt(X, Y, Z).getType()) // target block open and safe
|
||||||
&& safeOpenBlocks.contains(world.getBlockAt(X, Y + 1, Z).getType()); // above target block open and safe
|
&& safeOpenBlocks.contains(world.getBlockAt(X, Y + 1, Z).getType()); // above target block open and safe
|
||||||
if (!safe || flying)
|
if (!safe || flying)
|
||||||
@ -418,11 +395,8 @@ public class BorderData
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int limBot = 0;
|
|
||||||
|
|
||||||
// find closest safe Y position from the starting position
|
// find closest safe Y position from the starting position
|
||||||
private double getSafeY(World world, int X, int Y, int Z, boolean flying)
|
private double getSafeY(World world, int X, int Y, int Z, boolean flying) {
|
||||||
{
|
|
||||||
// artificial height limit of 127 added for Nether worlds since CraftBukkit still incorrectly returns 255 for their max height, leading to players sent to the "roof" of the Nether
|
// artificial height limit of 127 added for Nether worlds since CraftBukkit still incorrectly returns 255 for their max height, leading to players sent to the "roof" of the Nether
|
||||||
final boolean isNether = world.getEnvironment() == World.Environment.NETHER;
|
final boolean isNether = world.getEnvironment() == World.Environment.NETHER;
|
||||||
int limTop = isNether ? 125 : world.getMaxHeight() - 2;
|
int limTop = isNether ? 125 : world.getMaxHeight() - 2;
|
||||||
@ -433,12 +407,10 @@ public class BorderData
|
|||||||
return (double) Y;
|
return (double) Y;
|
||||||
|
|
||||||
// make sure Y values are within the boundaries of the world.
|
// make sure Y values are within the boundaries of the world.
|
||||||
if (Y > limTop)
|
if (Y > limTop) {
|
||||||
{
|
|
||||||
if (isNether)
|
if (isNether)
|
||||||
Y = limTop; // because of the roof, the nether can not rely on highestBlockBoundary, so limTop has to be used
|
Y = limTop; // because of the roof, the nether can not rely on highestBlockBoundary, so limTop has to be used
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if (flying)
|
if (flying)
|
||||||
Y = limTop;
|
Y = limTop;
|
||||||
else
|
else
|
||||||
@ -455,15 +427,13 @@ public class BorderData
|
|||||||
|
|
||||||
for (int y1 = Y, y2 = Y; (y1 > limBot) || (y2 < limTop); y1--, y2++) {
|
for (int y1 = Y, y2 = Y; (y1 > limBot) || (y2 < limTop); y1--, y2++) {
|
||||||
// Look below.
|
// Look below.
|
||||||
if(y1 > limBot)
|
if (y1 > limBot) {
|
||||||
{
|
|
||||||
if (isSafeSpot(world, X, y1, Z, flying))
|
if (isSafeSpot(world, X, y1, Z, flying))
|
||||||
return (double) y1;
|
return (double) y1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look above.
|
// Look above.
|
||||||
if(y2 < limTop && y2 != y1)
|
if (y2 < limTop && y2 != y1) {
|
||||||
{
|
|
||||||
if (isSafeSpot(world, X, y2, Z, flying))
|
if (isSafeSpot(world, X, y2, Z, flying))
|
||||||
return (double) y2;
|
return (double) y2;
|
||||||
}
|
}
|
||||||
@ -474,8 +444,7 @@ public class BorderData
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj) {
|
||||||
{
|
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
return true;
|
return true;
|
||||||
else if (obj == null || obj.getClass() != this.getClass())
|
else if (obj == null || obj.getClass() != this.getClass())
|
||||||
@ -486,8 +455,7 @@ public class BorderData
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode() {
|
||||||
{
|
|
||||||
return (((int) (this.x * 10) << 4) + (int) this.z + (this.radiusX << 2) + (this.radiusZ << 3));
|
return (((int) (this.x * 10) << 4) + (int) this.z + (this.radiusX << 2) + (this.radiusZ << 3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,40 +1,31 @@
|
|||||||
package com.wimbli.WorldBorder;
|
package com.wimbli.WorldBorder;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Effect;
|
import org.bukkit.Effect;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
public class Config
|
public class Config {
|
||||||
{
|
private static final int currentCfgVersion = 12;
|
||||||
|
public static volatile DecimalFormat coord = new DecimalFormat("0.0");
|
||||||
|
public static volatile WorldFillTask fillTask = null;
|
||||||
|
public static volatile WorldTrimTask trimTask = null;
|
||||||
// private stuff used within this class
|
// private stuff used within this class
|
||||||
private static WorldBorder plugin;
|
private static WorldBorder plugin;
|
||||||
private static FileConfiguration cfg = null;
|
private static FileConfiguration cfg = null;
|
||||||
private static Logger wbLog = null;
|
private static Logger wbLog = null;
|
||||||
public static volatile DecimalFormat coord = new DecimalFormat("0.0");
|
|
||||||
private static int borderTask = -1;
|
private static int borderTask = -1;
|
||||||
public static volatile WorldFillTask fillTask = null;
|
|
||||||
public static volatile WorldTrimTask trimTask = null;
|
|
||||||
private static Runtime rt = Runtime.getRuntime();
|
private static Runtime rt = Runtime.getRuntime();
|
||||||
|
|
||||||
// actual configuration values which can be changed
|
// actual configuration values which can be changed
|
||||||
private static boolean shapeRound = true;
|
private static boolean shapeRound = true;
|
||||||
private static Map<String, BorderData> borders = Collections.synchronizedMap(new LinkedHashMap<String, BorderData>());
|
private static Map<String, BorderData> borders = Collections.synchronizedMap(new LinkedHashMap<String, BorderData>());
|
||||||
@ -45,108 +36,96 @@ public class Config
|
|||||||
private static boolean DEBUG = false;
|
private static boolean DEBUG = false;
|
||||||
private static double knockBack = 3.0;
|
private static double knockBack = 3.0;
|
||||||
private static int timerTicks = 4;
|
private static int timerTicks = 4;
|
||||||
private static boolean whooshEffect = true;
|
private static boolean whooshEffect = false;
|
||||||
private static boolean portalRedirection = true;
|
private static boolean portalRedirection = true;
|
||||||
private static boolean dynmapEnable = true;
|
private static boolean dynmapEnable = false;
|
||||||
private static String dynmapMessage;
|
private static String dynmapMessage;
|
||||||
private static int dynmapPriority = 0;
|
private static int dynmapPriority = 0;
|
||||||
private static boolean dynmapHideByDefault = false;
|
private static boolean dynmapHideByDefault = false;
|
||||||
private static int remountDelayTicks = 0;
|
private static int remountDelayTicks = 0;
|
||||||
private static boolean killPlayer = false;
|
private static boolean killPlayer = false;
|
||||||
private static boolean denyEnderpearl = false;
|
private static boolean denyEnderpearl = false;
|
||||||
private static int fillAutosaveFrequency = 30;
|
private static int fillAutosaveFrequency = 45;
|
||||||
private static int fillMemoryTolerance = 500;
|
private static int fillMemoryTolerance = 500;
|
||||||
private static boolean preventBlockPlace = false;
|
private static boolean preventBlockPlace = false;
|
||||||
private static boolean preventMobSpawn = false;
|
|
||||||
|
|
||||||
// for monitoring plugin efficiency
|
// for monitoring plugin efficiency
|
||||||
// public static long timeUsed = 0;
|
// public static long timeUsed = 0;
|
||||||
|
private static boolean preventMobSpawn = false;
|
||||||
|
|
||||||
public static long Now()
|
public static long Now() {
|
||||||
{
|
|
||||||
return System.currentTimeMillis();
|
return System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setBorder(String world, BorderData border, boolean logIt) {
|
||||||
public static void setBorder(String world, BorderData border, boolean logIt)
|
|
||||||
{
|
|
||||||
borders.put(world, border);
|
borders.put(world, border);
|
||||||
if (logIt)
|
if (logIt)
|
||||||
log("Border set. " + BorderDescription(world));
|
log("Border set. " + BorderDescription(world));
|
||||||
save(true);
|
save(true);
|
||||||
DynMapFeatures.showBorder(world, border);
|
DynMapFeatures.showBorder(world, border);
|
||||||
}
|
}
|
||||||
public static void setBorder(String world, BorderData border)
|
|
||||||
{
|
public static void setBorder(String world, BorderData border) {
|
||||||
setBorder(world, border, true);
|
setBorder(world, border, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setBorder(String world, int radiusX, int radiusZ, double x, double z, Boolean shapeRound)
|
public static void setBorder(String world, int radiusX, int radiusZ, double x, double z, Boolean shapeRound) {
|
||||||
{
|
|
||||||
BorderData old = Border(world);
|
BorderData old = Border(world);
|
||||||
boolean oldWrap = (old != null) && old.getWrapping();
|
boolean oldWrap = (old != null) && old.getWrapping();
|
||||||
setBorder(world, new BorderData(x, z, radiusX, radiusZ, shapeRound, oldWrap), true);
|
setBorder(world, new BorderData(x, z, radiusX, radiusZ, shapeRound, oldWrap), true);
|
||||||
}
|
}
|
||||||
public static void setBorder(String world, int radiusX, int radiusZ, double x, double z)
|
|
||||||
{
|
public static void setBorder(String world, int radiusX, int radiusZ, double x, double z) {
|
||||||
BorderData old = Border(world);
|
BorderData old = Border(world);
|
||||||
Boolean oldShape = (old == null) ? null : old.getShape();
|
Boolean oldShape = (old == null) ? null : old.getShape();
|
||||||
boolean oldWrap = (old != null) && old.getWrapping();
|
boolean oldWrap = (old != null) && old.getWrapping();
|
||||||
setBorder(world, new BorderData(x, z, radiusX, radiusZ, oldShape, oldWrap), true);
|
setBorder(world, new BorderData(x, z, radiusX, radiusZ, oldShape, oldWrap), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// backwards-compatible methods from before elliptical/rectangular shapes were supported
|
// backwards-compatible methods from before elliptical/rectangular shapes were supported
|
||||||
public static void setBorder(String world, int radius, double x, double z, Boolean shapeRound)
|
public static void setBorder(String world, int radius, double x, double z, Boolean shapeRound) {
|
||||||
{
|
|
||||||
setBorder(world, new BorderData(x, z, radius, radius, shapeRound), true);
|
setBorder(world, new BorderData(x, z, radius, radius, shapeRound), true);
|
||||||
}
|
}
|
||||||
public static void setBorder(String world, int radius, double x, double z)
|
|
||||||
{
|
public static void setBorder(String world, int radius, double x, double z) {
|
||||||
setBorder(world, radius, radius, x, z);
|
setBorder(world, radius, radius, x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// set border based on corner coordinates
|
// set border based on corner coordinates
|
||||||
public static void setBorderCorners(String world, double x1, double z1, double x2, double z2, Boolean shapeRound, boolean wrap)
|
public static void setBorderCorners(String world, double x1, double z1, double x2, double z2, Boolean shapeRound, boolean wrap) {
|
||||||
{
|
|
||||||
double radiusX = Math.abs(x1 - x2) / 2;
|
double radiusX = Math.abs(x1 - x2) / 2;
|
||||||
double radiusZ = Math.abs(z1 - z2) / 2;
|
double radiusZ = Math.abs(z1 - z2) / 2;
|
||||||
double x = ((x1 < x2) ? x1 : x2) + radiusX;
|
double x = ((x1 < x2) ? x1 : x2) + radiusX;
|
||||||
double z = ((z1 < z2) ? z1 : z2) + radiusZ;
|
double z = ((z1 < z2) ? z1 : z2) + radiusZ;
|
||||||
setBorder(world, new BorderData(x, z, (int) Math.round(radiusX), (int) Math.round(radiusZ), shapeRound, wrap), true);
|
setBorder(world, new BorderData(x, z, (int) Math.round(radiusX), (int) Math.round(radiusZ), shapeRound, wrap), true);
|
||||||
}
|
}
|
||||||
public static void setBorderCorners(String world, double x1, double z1, double x2, double z2, Boolean shapeRound)
|
|
||||||
{
|
public static void setBorderCorners(String world, double x1, double z1, double x2, double z2, Boolean shapeRound) {
|
||||||
setBorderCorners(world, x1, z1, x2, z2, shapeRound, false);
|
setBorderCorners(world, x1, z1, x2, z2, shapeRound, false);
|
||||||
}
|
}
|
||||||
public static void setBorderCorners(String world, double x1, double z1, double x2, double z2)
|
|
||||||
{
|
public static void setBorderCorners(String world, double x1, double z1, double x2, double z2) {
|
||||||
BorderData old = Border(world);
|
BorderData old = Border(world);
|
||||||
Boolean oldShape = (old == null) ? null : old.getShape();
|
Boolean oldShape = (old == null) ? null : old.getShape();
|
||||||
boolean oldWrap = (old != null) && old.getWrapping();
|
boolean oldWrap = (old != null) && old.getWrapping();
|
||||||
setBorderCorners(world, x1, z1, x2, z2, oldShape, oldWrap);
|
setBorderCorners(world, x1, z1, x2, z2, oldShape, oldWrap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void removeBorder(String world) {
|
||||||
public static void removeBorder(String world)
|
|
||||||
{
|
|
||||||
borders.remove(world);
|
borders.remove(world);
|
||||||
log("Removed border for world \"" + world + "\".");
|
log("Removed border for world \"" + world + "\".");
|
||||||
save(true);
|
save(true);
|
||||||
DynMapFeatures.removeBorder(world);
|
DynMapFeatures.removeBorder(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeAllBorders()
|
public static void removeAllBorders() {
|
||||||
{
|
|
||||||
borders.clear();
|
borders.clear();
|
||||||
log("Removed all borders for all worlds.");
|
log("Removed all borders for all worlds.");
|
||||||
save(true);
|
save(true);
|
||||||
DynMapFeatures.removeAllBorders();
|
DynMapFeatures.removeAllBorders();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String BorderDescription(String world)
|
public static String BorderDescription(String world) {
|
||||||
{
|
|
||||||
BorderData border = borders.get(world);
|
BorderData border = borders.get(world);
|
||||||
if (border == null)
|
if (border == null)
|
||||||
return "No border was found for the world \"" + world + "\".";
|
return "No border was found for the world \"" + world + "\".";
|
||||||
@ -154,104 +133,89 @@ public class Config
|
|||||||
return "World \"" + world + "\" has border " + border.toString();
|
return "World \"" + world + "\" has border " + border.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<String> BorderDescriptions()
|
public static Set<String> BorderDescriptions() {
|
||||||
{
|
|
||||||
Set<String> output = new HashSet<String>();
|
Set<String> output = new HashSet<String>();
|
||||||
|
|
||||||
for(String worldName : borders.keySet())
|
for (String worldName : borders.keySet()) {
|
||||||
{
|
|
||||||
output.add(BorderDescription(worldName));
|
output.add(BorderDescription(worldName));
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BorderData Border(String world)
|
public static BorderData Border(String world) {
|
||||||
{
|
|
||||||
return borders.get(world);
|
return borders.get(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, BorderData> getBorders()
|
public static Map<String, BorderData> getBorders() {
|
||||||
{
|
|
||||||
return new LinkedHashMap<String, BorderData>(borders);
|
return new LinkedHashMap<String, BorderData>(borders);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setMessage(String msg)
|
public static void setMessage(String msg) {
|
||||||
{
|
|
||||||
updateMessage(msg);
|
updateMessage(msg);
|
||||||
save(true);
|
save(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updateMessage(String msg)
|
public static void updateMessage(String msg) {
|
||||||
{
|
|
||||||
message = msg;
|
message = msg;
|
||||||
messageFmt = replaceAmpColors(msg);
|
messageFmt = replaceAmpColors(msg);
|
||||||
messageClean = stripAmpColors(msg);
|
messageClean = stripAmpColors(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String Message()
|
public static String Message() {
|
||||||
{
|
|
||||||
return messageFmt;
|
return messageFmt;
|
||||||
}
|
}
|
||||||
public static String MessageRaw()
|
|
||||||
{
|
public static String MessageRaw() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
public static String MessageClean()
|
|
||||||
{
|
public static String MessageClean() {
|
||||||
return messageClean;
|
return messageClean;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setShape(boolean round)
|
public static void setShape(boolean round) {
|
||||||
{
|
|
||||||
shapeRound = round;
|
shapeRound = round;
|
||||||
log("Set default border shape to " + (ShapeName()) + ".");
|
log("Set default border shape to " + (ShapeName()) + ".");
|
||||||
save(true);
|
save(true);
|
||||||
DynMapFeatures.showAllBorders();
|
DynMapFeatures.showAllBorders();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean ShapeRound()
|
public static boolean ShapeRound() {
|
||||||
{
|
|
||||||
return shapeRound;
|
return shapeRound;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String ShapeName()
|
public static String ShapeName() {
|
||||||
{
|
|
||||||
return ShapeName(shapeRound);
|
return ShapeName(shapeRound);
|
||||||
}
|
}
|
||||||
public static String ShapeName(Boolean round)
|
|
||||||
{
|
public static String ShapeName(Boolean round) {
|
||||||
if (round == null)
|
if (round == null)
|
||||||
return "default";
|
return "default";
|
||||||
return round ? "elliptic/round" : "rectangular/square";
|
return round ? "elliptic/round" : "rectangular/square";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setDebug(boolean debugMode)
|
public static void setDebug(boolean debugMode) {
|
||||||
{
|
|
||||||
DEBUG = debugMode;
|
DEBUG = debugMode;
|
||||||
log("Debug mode " + (DEBUG ? "enabled" : "disabled") + ".");
|
log("Debug mode " + (DEBUG ? "enabled" : "disabled") + ".");
|
||||||
save(true);
|
save(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean Debug()
|
public static boolean Debug() {
|
||||||
{
|
|
||||||
return DEBUG;
|
return DEBUG;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setWhooshEffect(boolean enable)
|
public static void setWhooshEffect(boolean enable) {
|
||||||
{
|
|
||||||
whooshEffect = enable;
|
whooshEffect = enable;
|
||||||
log("\"Whoosh\" knockback effect " + (enable ? "enabled" : "disabled") + ".");
|
log("\"Whoosh\" knockback effect " + (enable ? "enabled" : "disabled") + ".");
|
||||||
save(true);
|
save(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean whooshEffect()
|
public static boolean whooshEffect() {
|
||||||
{
|
|
||||||
return whooshEffect;
|
return whooshEffect;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showWhooshEffect(Location loc)
|
public static void showWhooshEffect(Location loc) {
|
||||||
{
|
|
||||||
if (!whooshEffect())
|
if (!whooshEffect())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -264,8 +228,7 @@ public class Config
|
|||||||
world.playEffect(loc, Effect.GHAST_SHOOT, 0);
|
world.playEffect(loc, Effect.GHAST_SHOOT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setPreventBlockPlace(boolean enable)
|
public static void setPreventBlockPlace(boolean enable) {
|
||||||
{
|
|
||||||
if (preventBlockPlace != enable)
|
if (preventBlockPlace != enable)
|
||||||
WorldBorder.plugin.enableBlockPlaceListener(enable);
|
WorldBorder.plugin.enableBlockPlaceListener(enable);
|
||||||
|
|
||||||
@ -274,8 +237,7 @@ public class Config
|
|||||||
save(true);
|
save(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setPreventMobSpawn(boolean enable)
|
public static void setPreventMobSpawn(boolean enable) {
|
||||||
{
|
|
||||||
if (preventMobSpawn != enable)
|
if (preventMobSpawn != enable)
|
||||||
WorldBorder.plugin.enableMobSpawnListener(enable);
|
WorldBorder.plugin.enableMobSpawnListener(enable);
|
||||||
|
|
||||||
@ -284,77 +246,64 @@ public class Config
|
|||||||
save(true);
|
save(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean preventBlockPlace()
|
public static boolean preventBlockPlace() {
|
||||||
{
|
|
||||||
return preventBlockPlace;
|
return preventBlockPlace;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean preventMobSpawn()
|
public static boolean preventMobSpawn() {
|
||||||
{
|
|
||||||
return preventMobSpawn;
|
return preventMobSpawn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getIfPlayerKill()
|
public static boolean getIfPlayerKill() {
|
||||||
{
|
|
||||||
return killPlayer;
|
return killPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getDenyEnderpearl()
|
public static boolean getDenyEnderpearl() {
|
||||||
{
|
|
||||||
return denyEnderpearl;
|
return denyEnderpearl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setDenyEnderpearl(boolean enable)
|
public static void setDenyEnderpearl(boolean enable) {
|
||||||
{
|
|
||||||
denyEnderpearl = enable;
|
denyEnderpearl = enable;
|
||||||
log("Direct cancellation of ender pearls thrown past the border " + (enable ? "enabled" : "disabled") + ".");
|
log("Direct cancellation of ender pearls thrown past the border " + (enable ? "enabled" : "disabled") + ".");
|
||||||
save(true);
|
save(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setPortalRedirection(boolean enable)
|
public static void setPortalRedirection(boolean enable) {
|
||||||
{
|
|
||||||
portalRedirection = enable;
|
portalRedirection = enable;
|
||||||
log("Portal redirection " + (enable ? "enabled" : "disabled") + ".");
|
log("Portal redirection " + (enable ? "enabled" : "disabled") + ".");
|
||||||
save(true);
|
save(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean portalRedirection()
|
public static boolean portalRedirection() {
|
||||||
{
|
|
||||||
return portalRedirection;
|
return portalRedirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setKnockBack(double numBlocks)
|
public static void setKnockBack(double numBlocks) {
|
||||||
{
|
|
||||||
knockBack = numBlocks;
|
knockBack = numBlocks;
|
||||||
log("Knockback set to " + knockBack + " blocks inside the border.");
|
log("Knockback set to " + knockBack + " blocks inside the border.");
|
||||||
save(true);
|
save(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double KnockBack()
|
public static double KnockBack() {
|
||||||
{
|
|
||||||
return knockBack;
|
return knockBack;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setTimerTicks(int ticks)
|
public static void setTimerTicks(int ticks) {
|
||||||
{
|
|
||||||
timerTicks = ticks;
|
timerTicks = ticks;
|
||||||
log("Timer delay set to " + timerTicks + " tick(s). That is roughly " + (timerTicks * 50) + "ms / " + (((double) timerTicks * 50.0) / 1000.0) + " seconds.");
|
log("Timer delay set to " + timerTicks + " tick(s). That is roughly " + (timerTicks * 50) + "ms / " + (((double) timerTicks * 50.0) / 1000.0) + " seconds.");
|
||||||
StartBorderTimer();
|
StartBorderTimer();
|
||||||
save(true);
|
save(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int TimerTicks()
|
public static int TimerTicks() {
|
||||||
{
|
|
||||||
return timerTicks;
|
return timerTicks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setRemountTicks(int ticks)
|
public static void setRemountTicks(int ticks) {
|
||||||
{
|
|
||||||
remountDelayTicks = ticks;
|
remountDelayTicks = ticks;
|
||||||
if (remountDelayTicks == 0)
|
if (remountDelayTicks == 0)
|
||||||
log("Remount delay set to 0. Players will be left dismounted when knocked back from the border while on a vehicle.");
|
log("Remount delay set to 0. Players will be left dismounted when knocked back from the border while on a vehicle.");
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
log("Remount delay set to " + remountDelayTicks + " tick(s). That is roughly " + (remountDelayTicks * 50) + "ms / " + (((double) remountDelayTicks * 50.0) / 1000.0) + " seconds.");
|
log("Remount delay set to " + remountDelayTicks + " tick(s). That is roughly " + (remountDelayTicks * 50) + "ms / " + (((double) remountDelayTicks * 50.0) / 1000.0) + " seconds.");
|
||||||
if (ticks < 10)
|
if (ticks < 10)
|
||||||
logWarn("setting the remount delay to less than 10 (and greater than 0) is not recommended. This can lead to nasty client glitches.");
|
logWarn("setting the remount delay to less than 10 (and greater than 0) is not recommended. This can lead to nasty client glitches.");
|
||||||
@ -362,13 +311,11 @@ public class Config
|
|||||||
save(true);
|
save(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int RemountTicks()
|
public static int RemountTicks() {
|
||||||
{
|
|
||||||
return remountDelayTicks;
|
return remountDelayTicks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setFillAutosaveFrequency(int seconds)
|
public static void setFillAutosaveFrequency(int seconds) {
|
||||||
{
|
|
||||||
fillAutosaveFrequency = seconds;
|
fillAutosaveFrequency = seconds;
|
||||||
if (fillAutosaveFrequency == 0)
|
if (fillAutosaveFrequency == 0)
|
||||||
log("World autosave frequency during Fill process set to 0, disabling it. Note that much progress can be lost this way if there is a bug or crash in the world generation process from Bukkit or any world generation plugin you use.");
|
log("World autosave frequency during Fill process set to 0, disabling it. Note that much progress can be lost this way if there is a bug or crash in the world generation process from Bukkit or any world generation plugin you use.");
|
||||||
@ -377,50 +324,41 @@ public class Config
|
|||||||
save(true);
|
save(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int FillAutosaveFrequency()
|
public static int FillAutosaveFrequency() {
|
||||||
{
|
|
||||||
return fillAutosaveFrequency;
|
return fillAutosaveFrequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setDynmapBorderEnabled(boolean enable) {
|
||||||
public static void setDynmapBorderEnabled(boolean enable)
|
|
||||||
{
|
|
||||||
dynmapEnable = enable;
|
dynmapEnable = enable;
|
||||||
log("DynMap border display is now " + (enable ? "enabled" : "disabled") + ".");
|
log("DynMap border display is now " + (enable ? "enabled" : "disabled") + ".");
|
||||||
save(true);
|
save(true);
|
||||||
DynMapFeatures.showAllBorders();
|
DynMapFeatures.showAllBorders();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean DynmapBorderEnabled()
|
public static boolean DynmapBorderEnabled() {
|
||||||
{
|
|
||||||
return dynmapEnable;
|
return dynmapEnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setDynmapMessage(String msg)
|
public static void setDynmapMessage(String msg) {
|
||||||
{
|
|
||||||
dynmapMessage = msg;
|
dynmapMessage = msg;
|
||||||
log("DynMap border label is now set to: " + msg);
|
log("DynMap border label is now set to: " + msg);
|
||||||
save(true);
|
save(true);
|
||||||
DynMapFeatures.showAllBorders();
|
DynMapFeatures.showAllBorders();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String DynmapMessage()
|
public static String DynmapMessage() {
|
||||||
{
|
|
||||||
return dynmapMessage;
|
return dynmapMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean DynmapHideByDefault()
|
public static boolean DynmapHideByDefault() {
|
||||||
{
|
|
||||||
return dynmapHideByDefault;
|
return dynmapHideByDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int DynmapPriority()
|
public static int DynmapPriority() {
|
||||||
{
|
|
||||||
return dynmapPriority;
|
return dynmapPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setPlayerBypass(UUID player, boolean bypass)
|
public static void setPlayerBypass(UUID player, boolean bypass) {
|
||||||
{
|
|
||||||
if (bypass)
|
if (bypass)
|
||||||
bypassPlayers.add(player);
|
bypassPlayers.add(player);
|
||||||
else
|
else
|
||||||
@ -428,43 +366,35 @@ public class Config
|
|||||||
save(true);
|
save(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isPlayerBypassing(UUID player)
|
public static boolean isPlayerBypassing(UUID player) {
|
||||||
{
|
|
||||||
return bypassPlayers.contains(player);
|
return bypassPlayers.contains(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<UUID> getPlayerBypassList()
|
public static ArrayList<UUID> getPlayerBypassList() {
|
||||||
{
|
|
||||||
return new ArrayList<>(bypassPlayers);
|
return new ArrayList<>(bypassPlayers);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for converting bypass UUID list to/from String list, for storage in config
|
// for converting bypass UUID list to/from String list, for storage in config
|
||||||
private static void importBypassStringList(List<String> strings)
|
private static void importBypassStringList(List<String> strings) {
|
||||||
{
|
for (String string : strings) {
|
||||||
for (String string: strings)
|
|
||||||
{
|
|
||||||
bypassPlayers.add(UUID.fromString(string));
|
bypassPlayers.add(UUID.fromString(string));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static ArrayList<String> exportBypassStringList()
|
|
||||||
{
|
private static ArrayList<String> exportBypassStringList() {
|
||||||
ArrayList<String> strings = new ArrayList<String>();
|
ArrayList<String> strings = new ArrayList<String>();
|
||||||
for (UUID uuid: bypassPlayers)
|
for (UUID uuid : bypassPlayers) {
|
||||||
{
|
|
||||||
strings.add(uuid.toString());
|
strings.add(uuid.toString());
|
||||||
}
|
}
|
||||||
return strings;
|
return strings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isBorderTimerRunning() {
|
||||||
public static boolean isBorderTimerRunning()
|
|
||||||
{
|
|
||||||
if (borderTask == -1) return false;
|
if (borderTask == -1) return false;
|
||||||
return (plugin.getServer().getScheduler().isQueued(borderTask) || plugin.getServer().getScheduler().isCurrentlyRunning(borderTask));
|
return (plugin.getServer().getScheduler().isQueued(borderTask) || plugin.getServer().getScheduler().isCurrentlyRunning(borderTask));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StartBorderTimer()
|
public static void StartBorderTimer() {
|
||||||
{
|
|
||||||
StopBorderTimer(false);
|
StopBorderTimer(false);
|
||||||
|
|
||||||
borderTask = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new BorderCheckTask(), timerTicks, timerTicks);
|
borderTask = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new BorderCheckTask(), timerTicks, timerTicks);
|
||||||
@ -475,12 +405,11 @@ public class Config
|
|||||||
logConfig("Border-checking timed task started.");
|
logConfig("Border-checking timed task started.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StopBorderTimer()
|
public static void StopBorderTimer() {
|
||||||
{
|
|
||||||
StopBorderTimer(true);
|
StopBorderTimer(true);
|
||||||
}
|
}
|
||||||
public static void StopBorderTimer(boolean logIt)
|
|
||||||
{
|
public static void StopBorderTimer(boolean logIt) {
|
||||||
if (borderTask == -1) return;
|
if (borderTask == -1) return;
|
||||||
|
|
||||||
plugin.getServer().getScheduler().cancelTask(borderTask);
|
plugin.getServer().getScheduler().cancelTask(borderTask);
|
||||||
@ -489,62 +418,51 @@ public class Config
|
|||||||
logConfig("Border-checking timed task stopped.");
|
logConfig("Border-checking timed task stopped.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StopFillTask()
|
public static void StopFillTask() {
|
||||||
{
|
|
||||||
if (fillTask != null && fillTask.valid())
|
if (fillTask != null && fillTask.valid())
|
||||||
fillTask.cancel();
|
fillTask.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StoreFillTask()
|
public static void StoreFillTask() {
|
||||||
{
|
|
||||||
save(false, true);
|
save(false, true);
|
||||||
}
|
}
|
||||||
public static void UnStoreFillTask()
|
|
||||||
{
|
public static void UnStoreFillTask() {
|
||||||
save(false);
|
save(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RestoreFillTask(String world, int fillDistance, int chunksPerRun, int tickFrequency, int x, int z, int length, int total, boolean forceLoad)
|
public static void RestoreFillTask(String world, int fillDistance, int chunksPerRun, int tickFrequency, int x, int z, int length, int total, boolean forceLoad) {
|
||||||
{
|
|
||||||
fillTask = new WorldFillTask(plugin.getServer(), null, world, fillDistance, chunksPerRun, tickFrequency, forceLoad);
|
fillTask = new WorldFillTask(plugin.getServer(), null, world, fillDistance, chunksPerRun, tickFrequency, forceLoad);
|
||||||
if (fillTask.valid())
|
if (fillTask.valid()) {
|
||||||
{
|
|
||||||
fillTask.continueProgress(x, z, length, total);
|
fillTask.continueProgress(x, z, length, total);
|
||||||
int task = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, fillTask, 20, tickFrequency);
|
int task = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, fillTask, 20, tickFrequency);
|
||||||
fillTask.setTaskID(task);
|
fillTask.setTaskID(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for backwards compatibility
|
// for backwards compatibility
|
||||||
public static void RestoreFillTask(String world, int fillDistance, int chunksPerRun, int tickFrequency, int x, int z, int length, int total)
|
public static void RestoreFillTask(String world, int fillDistance, int chunksPerRun, int tickFrequency, int x, int z, int length, int total) {
|
||||||
{
|
|
||||||
RestoreFillTask(world, fillDistance, chunksPerRun, tickFrequency, x, z, length, total, false);
|
RestoreFillTask(world, fillDistance, chunksPerRun, tickFrequency, x, z, length, total, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void StopTrimTask() {
|
||||||
public static void StopTrimTask()
|
|
||||||
{
|
|
||||||
if (trimTask != null && trimTask.valid())
|
if (trimTask != null && trimTask.valid())
|
||||||
trimTask.cancel();
|
trimTask.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int AvailableMemory() {
|
||||||
public static int AvailableMemory()
|
|
||||||
{
|
|
||||||
return (int) ((rt.maxMemory() - rt.totalMemory() + rt.freeMemory()) / 1048576); // 1024*1024 = 1048576 (bytes in 1 MB)
|
return (int) ((rt.maxMemory() - rt.totalMemory() + rt.freeMemory()) / 1048576); // 1024*1024 = 1048576 (bytes in 1 MB)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean AvailableMemoryTooLow()
|
public static boolean AvailableMemoryTooLow() {
|
||||||
{
|
|
||||||
return AvailableMemory() < fillMemoryTolerance;
|
return AvailableMemory() < fillMemoryTolerance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean HasPermission(Player player, String request) {
|
||||||
public static boolean HasPermission(Player player, String request)
|
|
||||||
{
|
|
||||||
return HasPermission(player, request, true);
|
return HasPermission(player, request, true);
|
||||||
}
|
}
|
||||||
public static boolean HasPermission(Player player, String request, boolean notify)
|
|
||||||
{
|
public static boolean HasPermission(Player player, String request, boolean notify) {
|
||||||
if (player == null) // console, always permitted
|
if (player == null) // console, always permitted
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -557,40 +475,32 @@ public class Config
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String replaceAmpColors(String message) {
|
||||||
public static String replaceAmpColors (String message)
|
|
||||||
{
|
|
||||||
return ChatColor.translateAlternateColorCodes('&', message);
|
return ChatColor.translateAlternateColorCodes('&', message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// adapted from code posted by Sleaker
|
// adapted from code posted by Sleaker
|
||||||
public static String stripAmpColors (String message)
|
public static String stripAmpColors(String message) {
|
||||||
{
|
|
||||||
return message.replaceAll("(?i)&([a-fk-or0-9])", "");
|
return message.replaceAll("(?i)&([a-fk-or0-9])", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void log(Level lvl, String text) {
|
||||||
public static void log(Level lvl, String text)
|
|
||||||
{
|
|
||||||
wbLog.log(lvl, text);
|
wbLog.log(lvl, text);
|
||||||
}
|
}
|
||||||
public static void log(String text)
|
|
||||||
{
|
public static void log(String text) {
|
||||||
log(Level.INFO, text);
|
log(Level.INFO, text);
|
||||||
}
|
}
|
||||||
public static void logWarn(String text)
|
|
||||||
{
|
public static void logWarn(String text) {
|
||||||
log(Level.WARNING, text);
|
log(Level.WARNING, text);
|
||||||
}
|
}
|
||||||
public static void logConfig(String text)
|
|
||||||
{
|
public static void logConfig(String text) {
|
||||||
log(Level.INFO, "[CONFIG] " + text);
|
log(Level.INFO, "[CONFIG] " + text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void load(WorldBorder master, boolean logIt) { // load config from file
|
||||||
private static final int currentCfgVersion = 11;
|
|
||||||
|
|
||||||
public static void load(WorldBorder master, boolean logIt)
|
|
||||||
{ // load config from file
|
|
||||||
plugin = master;
|
plugin = master;
|
||||||
wbLog = plugin.getLogger();
|
wbLog = plugin.getLogger();
|
||||||
|
|
||||||
@ -625,8 +535,7 @@ public class Config
|
|||||||
borders.clear();
|
borders.clear();
|
||||||
|
|
||||||
// if empty border message, assume no config
|
// if empty border message, assume no config
|
||||||
if (msg == null || msg.isEmpty())
|
if (msg == null || msg.isEmpty()) { // store defaults
|
||||||
{ // store defaults
|
|
||||||
logConfig("Configuration not present, creating new file.");
|
logConfig("Configuration not present, creating new file.");
|
||||||
msg = "&cYou have reached the edge of this world.";
|
msg = "&cYou have reached the edge of this world.";
|
||||||
updateMessage(msg);
|
updateMessage(msg);
|
||||||
@ -649,12 +558,10 @@ public class Config
|
|||||||
cfg.set("bypass-list", null);
|
cfg.set("bypass-list", null);
|
||||||
|
|
||||||
ConfigurationSection worlds = cfg.getConfigurationSection("worlds");
|
ConfigurationSection worlds = cfg.getConfigurationSection("worlds");
|
||||||
if (worlds != null)
|
if (worlds != null) {
|
||||||
{
|
|
||||||
Set<String> worldNames = worlds.getKeys(false);
|
Set<String> worldNames = worlds.getKeys(false);
|
||||||
|
|
||||||
for(String worldName : worldNames)
|
for (String worldName : worldNames) {
|
||||||
{
|
|
||||||
ConfigurationSection bord = worlds.getConfigurationSection(worldName);
|
ConfigurationSection bord = worlds.getConfigurationSection(worldName);
|
||||||
|
|
||||||
// we're swapping "<" to "." at load since periods denote configuration nodes without a working way to change that, so world names with periods wreak havoc and are thus modified for storage
|
// we're swapping "<" to "." at load since periods denote configuration nodes without a working way to change that, so world names with periods wreak havoc and are thus modified for storage
|
||||||
@ -662,8 +569,7 @@ public class Config
|
|||||||
worldName = worldName.replace("<", ".");
|
worldName = worldName.replace("<", ".");
|
||||||
|
|
||||||
// backwards compatibility for config from before elliptical/rectangular borders were supported
|
// backwards compatibility for config from before elliptical/rectangular borders were supported
|
||||||
if (bord.isSet("radius") && !bord.isSet("radiusX"))
|
if (bord.isSet("radius") && !bord.isSet("radiusX")) {
|
||||||
{
|
|
||||||
int radius = bord.getInt("radius");
|
int radius = bord.getInt("radius");
|
||||||
bord.set("radiusX", radius);
|
bord.set("radiusX", radius);
|
||||||
bord.set("radiusZ", radius);
|
bord.set("radiusZ", radius);
|
||||||
@ -679,8 +585,7 @@ public class Config
|
|||||||
|
|
||||||
// if we have an unfinished fill task stored from a previous run, load it up
|
// if we have an unfinished fill task stored from a previous run, load it up
|
||||||
ConfigurationSection storedFillTask = cfg.getConfigurationSection("fillTask");
|
ConfigurationSection storedFillTask = cfg.getConfigurationSection("fillTask");
|
||||||
if (storedFillTask != null)
|
if (storedFillTask != null) {
|
||||||
{
|
|
||||||
String worldName = storedFillTask.getString("world");
|
String worldName = storedFillTask.getString("world");
|
||||||
int fillDistance = storedFillTask.getInt("fillDistance", 176);
|
int fillDistance = storedFillTask.getInt("fillDistance", 176);
|
||||||
int chunksPerRun = storedFillTask.getInt("chunksPerRun", 5);
|
int chunksPerRun = storedFillTask.getInt("chunksPerRun", 5);
|
||||||
@ -701,12 +606,11 @@ public class Config
|
|||||||
save(false);
|
save(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void save(boolean logIt)
|
public static void save(boolean logIt) {
|
||||||
{
|
|
||||||
save(logIt, false);
|
save(logIt, false);
|
||||||
}
|
}
|
||||||
public static void save(boolean logIt, boolean storeFillTask)
|
|
||||||
{ // save config to file
|
public static void save(boolean logIt, boolean storeFillTask) { // save config to file
|
||||||
if (cfg == null) return;
|
if (cfg == null) return;
|
||||||
|
|
||||||
cfg.set("cfg-version", currentCfgVersion);
|
cfg.set("cfg-version", currentCfgVersion);
|
||||||
@ -731,8 +635,7 @@ public class Config
|
|||||||
cfg.set("prevent-mob-spawn", preventMobSpawn);
|
cfg.set("prevent-mob-spawn", preventMobSpawn);
|
||||||
|
|
||||||
cfg.set("worlds", null);
|
cfg.set("worlds", null);
|
||||||
for(Entry<String, BorderData> stringBorderDataEntry : borders.entrySet())
|
for (Entry<String, BorderData> stringBorderDataEntry : borders.entrySet()) {
|
||||||
{
|
|
||||||
String name = stringBorderDataEntry.getKey().replace(".", "<");
|
String name = stringBorderDataEntry.getKey().replace(".", "<");
|
||||||
BorderData bord = stringBorderDataEntry.getValue();
|
BorderData bord = stringBorderDataEntry.getValue();
|
||||||
|
|
||||||
@ -746,8 +649,7 @@ public class Config
|
|||||||
cfg.set("worlds." + name + ".shape-round", bord.getShape());
|
cfg.set("worlds." + name + ".shape-round", bord.getShape());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (storeFillTask && fillTask != null && fillTask.valid())
|
if (storeFillTask && fillTask != null && fillTask.valid()) {
|
||||||
{
|
|
||||||
cfg.set("fillTask.world", fillTask.refWorld());
|
cfg.set("fillTask.world", fillTask.refWorld());
|
||||||
cfg.set("fillTask.fillDistance", fillTask.refFillDistance());
|
cfg.set("fillTask.fillDistance", fillTask.refFillDistance());
|
||||||
cfg.set("fillTask.chunksPerRun", fillTask.refChunksPerRun());
|
cfg.set("fillTask.chunksPerRun", fillTask.refChunksPerRun());
|
||||||
@ -757,8 +659,7 @@ public class Config
|
|||||||
cfg.set("fillTask.length", fillTask.refLength());
|
cfg.set("fillTask.length", fillTask.refLength());
|
||||||
cfg.set("fillTask.total", fillTask.refTotal());
|
cfg.set("fillTask.total", fillTask.refTotal());
|
||||||
cfg.set("fillTask.forceLoad", fillTask.refForceLoad());
|
cfg.set("fillTask.forceLoad", fillTask.refForceLoad());
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
cfg.set("fillTask", null);
|
cfg.set("fillTask", null);
|
||||||
|
|
||||||
plugin.saveConfig();
|
plugin.saveConfig();
|
||||||
|
@ -2,46 +2,43 @@ package com.wimbli.WorldBorder;
|
|||||||
|
|
||||||
|
|
||||||
// simple storage class for chunk x/z values
|
// simple storage class for chunk x/z values
|
||||||
public class CoordXZ
|
public class CoordXZ {
|
||||||
{
|
|
||||||
public int x, z;
|
public int x, z;
|
||||||
public CoordXZ(int x, int z)
|
|
||||||
{
|
public CoordXZ(int x, int z) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
// transform values between block, chunk, and region
|
// transform values between block, chunk, and region
|
||||||
// bit-shifting is used because it's mucho rapido
|
// bit-shifting is used because it's mucho rapido
|
||||||
public static int blockToChunk(int blockVal)
|
public static int blockToChunk(int blockVal) { // 1 chunk is 16x16 blocks
|
||||||
{ // 1 chunk is 16x16 blocks
|
|
||||||
return blockVal >> 4; // ">>4" == "/16"
|
return blockVal >> 4; // ">>4" == "/16"
|
||||||
}
|
}
|
||||||
public static int blockToRegion(int blockVal)
|
|
||||||
{ // 1 region is 512x512 blocks
|
public static int blockToRegion(int blockVal) { // 1 region is 512x512 blocks
|
||||||
return blockVal >> 9; // ">>9" == "/512"
|
return blockVal >> 9; // ">>9" == "/512"
|
||||||
}
|
}
|
||||||
public static int chunkToRegion(int chunkVal)
|
|
||||||
{ // 1 region is 32x32 chunks
|
public static int chunkToRegion(int chunkVal) { // 1 region is 32x32 chunks
|
||||||
return chunkVal >> 5; // ">>5" == "/32"
|
return chunkVal >> 5; // ">>5" == "/32"
|
||||||
}
|
}
|
||||||
public static int chunkToBlock(int chunkVal)
|
|
||||||
{
|
public static int chunkToBlock(int chunkVal) {
|
||||||
return chunkVal << 4; // "<<4" == "*16"
|
return chunkVal << 4; // "<<4" == "*16"
|
||||||
}
|
}
|
||||||
public static int regionToBlock(int regionVal)
|
|
||||||
{
|
public static int regionToBlock(int regionVal) {
|
||||||
return regionVal << 9; // "<<9" == "*512"
|
return regionVal << 9; // "<<9" == "*512"
|
||||||
}
|
}
|
||||||
public static int regionToChunk(int regionVal)
|
|
||||||
{
|
public static int regionToChunk(int regionVal) {
|
||||||
return regionVal << 5; // "<<5" == "*32"
|
return regionVal << 5; // "<<5" == "*32"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj) {
|
||||||
{
|
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
return true;
|
return true;
|
||||||
else if (obj == null || obj.getClass() != this.getClass())
|
else if (obj == null || obj.getClass() != this.getClass())
|
||||||
@ -52,8 +49,7 @@ public class CoordXZ
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode() {
|
||||||
{
|
|
||||||
return (this.x << 9) + this.z;
|
return (this.x << 9) + this.z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,76 +1,71 @@
|
|||||||
package com.wimbli.WorldBorder;
|
package com.wimbli.WorldBorder;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.dynmap.DynmapAPI;
|
import org.dynmap.DynmapAPI;
|
||||||
import org.dynmap.markers.AreaMarker;
|
import org.dynmap.markers.AreaMarker;
|
||||||
import org.dynmap.markers.CircleMarker;
|
import org.dynmap.markers.CircleMarker;
|
||||||
import org.dynmap.markers.MarkerAPI;
|
import org.dynmap.markers.MarkerAPI;
|
||||||
import org.dynmap.markers.MarkerSet;
|
import org.dynmap.markers.MarkerSet;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
public class DynMapFeatures
|
|
||||||
{
|
public class DynMapFeatures {
|
||||||
private static DynmapAPI api;
|
private static DynmapAPI api;
|
||||||
private static MarkerAPI markApi;
|
private static MarkerAPI markApi;
|
||||||
private static MarkerSet markSet;
|
private static MarkerSet markSet;
|
||||||
private static int lineWeight = 3;
|
private static int lineWeight = 3;
|
||||||
private static double lineOpacity = 1.0;
|
private static double lineOpacity = 1.0;
|
||||||
private static int lineColor = 0xFF0000;
|
private static int lineColor = 0xFF0000;
|
||||||
|
private static Map<String, CircleMarker> roundBorders = new HashMap<String, CircleMarker>();
|
||||||
|
private static Map<String, AreaMarker> squareBorders = new HashMap<String, AreaMarker>();
|
||||||
|
|
||||||
// Whether re-rendering functionality is available
|
// Whether re-rendering functionality is available
|
||||||
public static boolean renderEnabled()
|
public static boolean renderEnabled() {
|
||||||
{
|
|
||||||
return api != null;
|
return api != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
// Whether circular border markers are available
|
// Whether circular border markers are available
|
||||||
public static boolean borderEnabled()
|
public static boolean borderEnabled() {
|
||||||
{
|
|
||||||
return markApi != null;
|
return markApi != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setup()
|
public static void setup() {
|
||||||
{
|
|
||||||
Plugin test = Bukkit.getServer().getPluginManager().getPlugin("dynmap");
|
Plugin test = Bukkit.getServer().getPluginManager().getPlugin("dynmap");
|
||||||
if (test == null || !test.isEnabled()) return;
|
if (test == null || !test.isEnabled()) return;
|
||||||
|
|
||||||
api = (DynmapAPI) test;
|
api = (DynmapAPI) test;
|
||||||
|
|
||||||
// make sure DynMap version is new enough to include circular markers
|
// make sure DynMap version is new enough to include circular markers
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
Class.forName("org.dynmap.markers.CircleMarker");
|
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)
|
// 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-"))
|
if (api.getDynmapVersion().startsWith("0.35-"))
|
||||||
throw new ClassNotFoundException();
|
throw new ClassNotFoundException();
|
||||||
}
|
} catch (ClassNotFoundException ex) {
|
||||||
catch (ClassNotFoundException ex)
|
|
||||||
{
|
|
||||||
Config.logConfig("DynMap is available, but border display is currently disabled: you need DynMap v0.36 or newer.");
|
Config.logConfig("DynMap is available, but border display is currently disabled: you need DynMap v0.36 or newer.");
|
||||||
return;
|
return;
|
||||||
}
|
} catch (NullPointerException ex) {
|
||||||
catch (NullPointerException ex)
|
|
||||||
{
|
|
||||||
Config.logConfig("DynMap is present, but an NPE (type 1) was encountered while trying to integrate. Border display disabled.");
|
Config.logConfig("DynMap is present, but an NPE (type 1) was encountered while trying to integrate. Border display disabled.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
markApi = api.getMarkerAPI();
|
markApi = api.getMarkerAPI();
|
||||||
if (markApi == null) return;
|
if (markApi == null) return;
|
||||||
}
|
} catch (NullPointerException ex) {
|
||||||
catch (NullPointerException ex)
|
|
||||||
{
|
|
||||||
Config.logConfig("DynMap is present, but an NPE (type 2) was encountered while trying to integrate. Border display disabled.");
|
Config.logConfig("DynMap is present, but an NPE (type 2) was encountered while trying to integrate. Border display disabled.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -81,14 +76,7 @@ public class DynMapFeatures
|
|||||||
Config.logConfig("Successfully hooked into DynMap for the ability to display borders.");
|
Config.logConfig("Successfully hooked into DynMap for the ability to display borders.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void renderRegion(String worldName, CoordXZ coord) {
|
||||||
/*
|
|
||||||
* 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;
|
if (!renderEnabled()) return;
|
||||||
|
|
||||||
World world = Bukkit.getWorld(worldName);
|
World world = Bukkit.getWorld(worldName);
|
||||||
@ -98,21 +86,23 @@ public class DynMapFeatures
|
|||||||
api.triggerRenderOfVolume(worldName, x, 0, z, x + 511, y, z + 511);
|
api.triggerRenderOfVolume(worldName, x, 0, z, x + 511, y, z + 511);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderChunks(String worldName, List<CoordXZ> coords)
|
|
||||||
{
|
/*
|
||||||
|
* Methods for displaying our borders on DynMap's world maps
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static void renderChunks(String worldName, List<CoordXZ> coords) {
|
||||||
if (!renderEnabled()) return;
|
if (!renderEnabled()) return;
|
||||||
|
|
||||||
World world = Bukkit.getWorld(worldName);
|
World world = Bukkit.getWorld(worldName);
|
||||||
int y = (world != null) ? world.getMaxHeight() : 255;
|
int y = (world != null) ? world.getMaxHeight() : 255;
|
||||||
|
|
||||||
for (CoordXZ coord : coords)
|
for (CoordXZ coord : coords) {
|
||||||
{
|
|
||||||
renderChunk(worldName, coord, y);
|
renderChunk(worldName, coord, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderChunk(String worldName, CoordXZ coord, int maxY)
|
public static void renderChunk(String worldName, CoordXZ coord, int maxY) {
|
||||||
{
|
|
||||||
if (!renderEnabled()) return;
|
if (!renderEnabled()) return;
|
||||||
|
|
||||||
int x = CoordXZ.chunkToBlock(coord.x);
|
int x = CoordXZ.chunkToBlock(coord.x);
|
||||||
@ -120,23 +110,13 @@ public class DynMapFeatures
|
|||||||
api.triggerRenderOfVolume(worldName, x, 0, z, x + 15, maxY, z + 15);
|
api.triggerRenderOfVolume(worldName, x, 0, z, x + 15, maxY, z + 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void showAllBorders() {
|
||||||
/*
|
|
||||||
* 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;
|
if (!borderEnabled()) return;
|
||||||
|
|
||||||
// in case any borders are already shown
|
// in case any borders are already shown
|
||||||
removeAllBorders();
|
removeAllBorders();
|
||||||
|
|
||||||
if (!Config.DynmapBorderEnabled())
|
if (!Config.DynmapBorderEnabled()) {
|
||||||
{
|
|
||||||
// don't want to show the marker set in DynMap if our integration is disabled
|
// don't want to show the marker set in DynMap if our integration is disabled
|
||||||
if (markSet != null)
|
if (markSet != null)
|
||||||
markSet.deleteMarkerSet();
|
markSet.deleteMarkerSet();
|
||||||
@ -153,16 +133,14 @@ public class DynMapFeatures
|
|||||||
markSet.setLayerPriority(Config.DynmapPriority());
|
markSet.setLayerPriority(Config.DynmapPriority());
|
||||||
markSet.setHideByDefault(Config.DynmapHideByDefault());
|
markSet.setHideByDefault(Config.DynmapHideByDefault());
|
||||||
Map<String, BorderData> borders = Config.getBorders();
|
Map<String, BorderData> borders = Config.getBorders();
|
||||||
for(Entry<String, BorderData> stringBorderDataEntry : borders.entrySet())
|
for (Entry<String, BorderData> stringBorderDataEntry : borders.entrySet()) {
|
||||||
{
|
|
||||||
String worldName = stringBorderDataEntry.getKey();
|
String worldName = stringBorderDataEntry.getKey();
|
||||||
BorderData border = stringBorderDataEntry.getValue();
|
BorderData border = stringBorderDataEntry.getValue();
|
||||||
showBorder(worldName, border);
|
showBorder(worldName, border);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showBorder(String worldName, BorderData border)
|
public static void showBorder(String worldName, BorderData border) {
|
||||||
{
|
|
||||||
if (!borderEnabled()) return;
|
if (!borderEnabled()) return;
|
||||||
|
|
||||||
if (!Config.DynmapBorderEnabled()) return;
|
if (!Config.DynmapBorderEnabled()) return;
|
||||||
@ -173,8 +151,7 @@ public class DynMapFeatures
|
|||||||
showSquareBorder(worldName, border);
|
showSquareBorder(worldName, border);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void showRoundBorder(String worldName, BorderData border)
|
private static void showRoundBorder(String worldName, BorderData border) {
|
||||||
{
|
|
||||||
if (squareBorders.containsKey(worldName))
|
if (squareBorders.containsKey(worldName))
|
||||||
removeBorder(worldName);
|
removeBorder(worldName);
|
||||||
|
|
||||||
@ -182,22 +159,18 @@ public class DynMapFeatures
|
|||||||
int y = (world != null) ? world.getMaxHeight() : 255;
|
int y = (world != null) ? world.getMaxHeight() : 255;
|
||||||
|
|
||||||
CircleMarker marker = roundBorders.get(worldName);
|
CircleMarker marker = roundBorders.get(worldName);
|
||||||
if (marker == null)
|
if (marker == null) {
|
||||||
{
|
|
||||||
marker = markSet.createCircleMarker("worldborder_" + worldName, Config.DynmapMessage(), false, worldName, border.getX(), y, border.getZ(), border.getRadiusX(), border.getRadiusZ(), true);
|
marker = markSet.createCircleMarker("worldborder_" + worldName, Config.DynmapMessage(), false, worldName, border.getX(), y, border.getZ(), border.getRadiusX(), border.getRadiusZ(), true);
|
||||||
marker.setLineStyle(lineWeight, lineOpacity, lineColor);
|
marker.setLineStyle(lineWeight, lineOpacity, lineColor);
|
||||||
marker.setFillStyle(0.0, 0x000000);
|
marker.setFillStyle(0.0, 0x000000);
|
||||||
roundBorders.put(worldName, marker);
|
roundBorders.put(worldName, marker);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
marker.setCenter(worldName, border.getX(), y, border.getZ());
|
marker.setCenter(worldName, border.getX(), y, border.getZ());
|
||||||
marker.setRadius(border.getRadiusX(), border.getRadiusZ());
|
marker.setRadius(border.getRadiusX(), border.getRadiusZ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void showSquareBorder(String worldName, BorderData border)
|
private static void showSquareBorder(String worldName, BorderData border) {
|
||||||
{
|
|
||||||
if (roundBorders.containsKey(worldName))
|
if (roundBorders.containsKey(worldName))
|
||||||
removeBorder(worldName);
|
removeBorder(worldName);
|
||||||
|
|
||||||
@ -206,38 +179,31 @@ public class DynMapFeatures
|
|||||||
double[] zVals = {border.getZ() - border.getRadiusZ(), border.getZ() + border.getRadiusZ()};
|
double[] zVals = {border.getZ() - border.getRadiusZ(), border.getZ() + border.getRadiusZ()};
|
||||||
|
|
||||||
AreaMarker marker = squareBorders.get(worldName);
|
AreaMarker marker = squareBorders.get(worldName);
|
||||||
if (marker == null)
|
if (marker == null) {
|
||||||
{
|
|
||||||
marker = markSet.createAreaMarker("worldborder_" + worldName, Config.DynmapMessage(), false, worldName, xVals, zVals, true);
|
marker = markSet.createAreaMarker("worldborder_" + worldName, Config.DynmapMessage(), false, worldName, xVals, zVals, true);
|
||||||
marker.setLineStyle(3, 1.0, 0xFF0000);
|
marker.setLineStyle(3, 1.0, 0xFF0000);
|
||||||
marker.setFillStyle(0.0, 0x000000);
|
marker.setFillStyle(0.0, 0x000000);
|
||||||
squareBorders.put(worldName, marker);
|
squareBorders.put(worldName, marker);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
marker.setCornerLocations(xVals, zVals);
|
marker.setCornerLocations(xVals, zVals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeAllBorders()
|
public static void removeAllBorders() {
|
||||||
{
|
|
||||||
if (!borderEnabled()) return;
|
if (!borderEnabled()) return;
|
||||||
|
|
||||||
for(CircleMarker marker : roundBorders.values())
|
for (CircleMarker marker : roundBorders.values()) {
|
||||||
{
|
|
||||||
marker.deleteMarker();
|
marker.deleteMarker();
|
||||||
}
|
}
|
||||||
roundBorders.clear();
|
roundBorders.clear();
|
||||||
|
|
||||||
for(AreaMarker marker : squareBorders.values())
|
for (AreaMarker marker : squareBorders.values()) {
|
||||||
{
|
|
||||||
marker.deleteMarker();
|
marker.deleteMarker();
|
||||||
}
|
}
|
||||||
squareBorders.clear();
|
squareBorders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeBorder(String worldName)
|
public static void removeBorder(String worldName) {
|
||||||
{
|
|
||||||
if (!borderEnabled()) return;
|
if (!borderEnabled()) return;
|
||||||
|
|
||||||
CircleMarker marker = roundBorders.remove(worldName);
|
CircleMarker marker = roundBorders.remove(worldName);
|
||||||
|
@ -1,42 +1,36 @@
|
|||||||
package com.wimbli.WorldBorder.Events;
|
package com.wimbli.WorldBorder.Events;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by timafh on 04.09.2015.
|
* Created by timafh on 04.09.2015.
|
||||||
*/
|
*/
|
||||||
public class WorldBorderFillFinishedEvent extends Event
|
public class WorldBorderFillFinishedEvent extends Event {
|
||||||
{
|
|
||||||
private static final HandlerList handlers = new HandlerList();
|
private static final HandlerList handlers = new HandlerList();
|
||||||
private World world;
|
private World world;
|
||||||
private long totalChunks;
|
private long totalChunks;
|
||||||
|
|
||||||
public WorldBorderFillFinishedEvent(World world, long totalChunks)
|
public WorldBorderFillFinishedEvent(World world, long totalChunks) {
|
||||||
{
|
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.totalChunks = totalChunks;
|
this.totalChunks = totalChunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HandlerList getHandlers()
|
public HandlerList getHandlers() {
|
||||||
{
|
|
||||||
return handlers;
|
return handlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HandlerList getHandlerList()
|
public World getWorld() {
|
||||||
{
|
|
||||||
return handlers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public World getWorld()
|
|
||||||
{
|
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getTotalChunks()
|
public long getTotalChunks() {
|
||||||
{
|
|
||||||
return totalChunks;
|
return totalChunks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,27 @@
|
|||||||
package com.wimbli.WorldBorder.Events;
|
package com.wimbli.WorldBorder.Events;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.WorldFillTask;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.WorldFillTask;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Maximvdw on 12.01.2016.
|
* Created by Maximvdw on 12.01.2016.
|
||||||
*/
|
*/
|
||||||
public class WorldBorderFillStartEvent extends Event
|
public class WorldBorderFillStartEvent extends Event {
|
||||||
{
|
|
||||||
private static final HandlerList handlers = new HandlerList();
|
private static final HandlerList handlers = new HandlerList();
|
||||||
private WorldFillTask fillTask;
|
private WorldFillTask fillTask;
|
||||||
|
|
||||||
public WorldBorderFillStartEvent(WorldFillTask worldFillTask)
|
public WorldBorderFillStartEvent(WorldFillTask worldFillTask) {
|
||||||
{
|
|
||||||
this.fillTask = worldFillTask;
|
this.fillTask = worldFillTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static HandlerList getHandlerList() {
|
||||||
public HandlerList getHandlers()
|
|
||||||
{
|
|
||||||
return handlers;
|
return handlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HandlerList getHandlerList()
|
@Override
|
||||||
{
|
public HandlerList getHandlers() {
|
||||||
return handlers;
|
return handlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,42 +1,36 @@
|
|||||||
package com.wimbli.WorldBorder.Events;
|
package com.wimbli.WorldBorder.Events;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by timafh on 04.09.2015.
|
* Created by timafh on 04.09.2015.
|
||||||
*/
|
*/
|
||||||
public class WorldBorderTrimFinishedEvent extends Event
|
public class WorldBorderTrimFinishedEvent extends Event {
|
||||||
{
|
|
||||||
private static final HandlerList handlers = new HandlerList();
|
private static final HandlerList handlers = new HandlerList();
|
||||||
private World world;
|
private World world;
|
||||||
private long totalChunks;
|
private long totalChunks;
|
||||||
|
|
||||||
public WorldBorderTrimFinishedEvent(World world, long totalChunks)
|
public WorldBorderTrimFinishedEvent(World world, long totalChunks) {
|
||||||
{
|
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.totalChunks = totalChunks;
|
this.totalChunks = totalChunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HandlerList getHandlers()
|
public HandlerList getHandlers() {
|
||||||
{
|
|
||||||
return handlers;
|
return handlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HandlerList getHandlerList()
|
public World getWorld() {
|
||||||
{
|
|
||||||
return handlers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public World getWorld()
|
|
||||||
{
|
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getTotalChunks()
|
public long getTotalChunks() {
|
||||||
{
|
|
||||||
return totalChunks;
|
return totalChunks;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,32 +1,27 @@
|
|||||||
package com.wimbli.WorldBorder.Events;
|
package com.wimbli.WorldBorder.Events;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.WorldTrimTask;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.WorldTrimTask;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Maximvdw on 12.01.2016.
|
* Created by Maximvdw on 12.01.2016.
|
||||||
*/
|
*/
|
||||||
public class WorldBorderTrimStartEvent extends Event
|
public class WorldBorderTrimStartEvent extends Event {
|
||||||
{
|
|
||||||
private static final HandlerList handlers = new HandlerList();
|
private static final HandlerList handlers = new HandlerList();
|
||||||
private WorldTrimTask trimTask;
|
private WorldTrimTask trimTask;
|
||||||
|
|
||||||
public WorldBorderTrimStartEvent(WorldTrimTask trimTask)
|
public WorldBorderTrimStartEvent(WorldTrimTask trimTask) {
|
||||||
{
|
|
||||||
this.trimTask = trimTask;
|
this.trimTask = trimTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static HandlerList getHandlerList() {
|
||||||
public HandlerList getHandlers()
|
|
||||||
{
|
|
||||||
return handlers;
|
return handlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HandlerList getHandlerList()
|
@Override
|
||||||
{
|
public HandlerList getHandlers() {
|
||||||
return handlers;
|
return handlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,11 +9,9 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
|
||||||
|
|
||||||
public class MobSpawnListener implements Listener
|
public class MobSpawnListener implements Listener {
|
||||||
{
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
public void onCreatureSpawn(CreatureSpawnEvent event)
|
public void onCreatureSpawn(CreatureSpawnEvent event) {
|
||||||
{
|
|
||||||
Location loc = event.getEntity().getLocation();
|
Location loc = event.getEntity().getLocation();
|
||||||
if (loc == null) return;
|
if (loc == null) return;
|
||||||
|
|
||||||
@ -22,14 +20,12 @@ public class MobSpawnListener implements Listener
|
|||||||
BorderData border = Config.Border(world.getName());
|
BorderData border = Config.Border(world.getName());
|
||||||
if (border == null) return;
|
if (border == null) return;
|
||||||
|
|
||||||
if (!border.insideBorder(loc.getX(), loc.getZ(), Config.ShapeRound()))
|
if (!border.insideBorder(loc.getX(), loc.getZ(), Config.ShapeRound())) {
|
||||||
{
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregister()
|
public void unregister() {
|
||||||
{
|
|
||||||
HandlerList.unregisterAll(this);
|
HandlerList.unregisterAll(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
package com.wimbli.WorldBorder.UUID;
|
package com.wimbli.WorldBorder.UUID;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
@ -16,24 +19,18 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
|
|
||||||
|
|
||||||
public class UUIDFetcher {
|
public class UUIDFetcher {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date when name changes were introduced
|
* Date when name changes were introduced
|
||||||
|
*
|
||||||
* @see UUIDFetcher#getUUIDAt(String, long)
|
* @see UUIDFetcher#getUUIDAt(String, long)
|
||||||
*/
|
*/
|
||||||
public static final long FEBRUARY_2015 = 1422748800000L;
|
public static final long FEBRUARY_2015 = 1422748800000L;
|
||||||
|
|
||||||
|
|
||||||
private static Gson gson = new GsonBuilder().registerTypeAdapter(UUID.class, new UUIDTypeAdapter()).create();
|
|
||||||
|
|
||||||
private static final String UUID_URL = "https://api.mojang.com/users/profiles/minecraft/%s?at=%d";
|
private static final String UUID_URL = "https://api.mojang.com/users/profiles/minecraft/%s?at=%d";
|
||||||
private static final String NAME_URL = "https://api.mojang.com/user/profiles/%s/names";
|
private static final String NAME_URL = "https://api.mojang.com/user/profiles/%s/names";
|
||||||
|
private static Gson gson = new GsonBuilder().registerTypeAdapter(UUID.class, new UUIDTypeAdapter()).create();
|
||||||
private static Map<String, UUID> uuidCache = new HashMap<String, UUID>();
|
private static Map<String, UUID> uuidCache = new HashMap<String, UUID>();
|
||||||
private static Map<UUID, String> nameCache = new HashMap<UUID, String>();
|
private static Map<UUID, String> nameCache = new HashMap<UUID, String>();
|
||||||
|
|
||||||
@ -140,8 +137,7 @@ public class UUIDFetcher {
|
|||||||
|
|
||||||
public static Map<UUID, String> getNameList(ArrayList<UUID> uuids) {
|
public static Map<UUID, String> getNameList(ArrayList<UUID> uuids) {
|
||||||
Map<UUID, String> uuidStringMap = new HashMap<>();
|
Map<UUID, String> uuidStringMap = new HashMap<>();
|
||||||
for (UUID uuid: uuids)
|
for (UUID uuid : uuids) {
|
||||||
{
|
|
||||||
uuidStringMap.put(uuid, getName(uuid));
|
uuidStringMap.put(uuid, getName(uuid));
|
||||||
}
|
}
|
||||||
return uuidStringMap;
|
return uuidStringMap;
|
||||||
|
@ -4,23 +4,15 @@
|
|||||||
|
|
||||||
package com.wimbli.WorldBorder.UUID;
|
package com.wimbli.WorldBorder.UUID;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import com.google.gson.TypeAdapter;
|
import com.google.gson.TypeAdapter;
|
||||||
import com.google.gson.stream.JsonReader;
|
import com.google.gson.stream.JsonReader;
|
||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
public class UUIDTypeAdapter extends TypeAdapter<UUID> {
|
public class UUIDTypeAdapter extends TypeAdapter<UUID> {
|
||||||
public void write(JsonWriter out, UUID value) throws IOException {
|
|
||||||
out.value(fromUUID(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public UUID read(JsonReader in) throws IOException {
|
|
||||||
return fromString(in.nextString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String fromUUID(UUID value) {
|
public static String fromUUID(UUID value) {
|
||||||
return value.toString().replace("-", "");
|
return value.toString().replace("-", "");
|
||||||
}
|
}
|
||||||
@ -29,4 +21,12 @@ public class UUIDTypeAdapter extends TypeAdapter<UUID> {
|
|||||||
return UUID.fromString(input.replaceFirst(
|
return UUID.fromString(input.replaceFirst(
|
||||||
"(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5"));
|
"(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void write(JsonWriter out, UUID value) throws IOException {
|
||||||
|
out.value(fromUUID(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID read(JsonReader in) throws IOException {
|
||||||
|
return fromString(in.nextString());
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,31 +1,24 @@
|
|||||||
package com.wimbli.WorldBorder;
|
package com.wimbli.WorldBorder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import com.wimbli.WorldBorder.cmd.*;
|
||||||
import java.util.Arrays;
|
import org.bukkit.command.Command;
|
||||||
import java.util.Iterator;
|
import org.bukkit.command.CommandExecutor;
|
||||||
import java.util.LinkedHashMap;
|
import org.bukkit.command.CommandSender;
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.cmd.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
public class WBCommand implements CommandExecutor
|
public class WBCommand implements CommandExecutor {
|
||||||
{
|
|
||||||
// map of all sub-commands with the command name (string) for quick reference
|
// map of all sub-commands with the command name (string) for quick reference
|
||||||
public Map<String, WBCmd> subCommands = new LinkedHashMap<String, WBCmd>();
|
public Map<String, WBCmd> subCommands = new LinkedHashMap<String, WBCmd>();
|
||||||
// ref. list of the commands which can have a world name in front of the command itself (ex. /wb _world_ radius 100)
|
// ref. list of the commands which can have a world name in front of the command itself (ex. /wb _world_ radius 100)
|
||||||
private Set<String> subCommandsWithWorldNames = new LinkedHashSet<String>();
|
private Set<String> subCommandsWithWorldNames = new LinkedHashSet<String>();
|
||||||
|
private boolean wasWorldQuotation = false;
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
public WBCommand ()
|
public WBCommand() {
|
||||||
{
|
|
||||||
addCmd(new CmdHelp()); // 1 example
|
addCmd(new CmdHelp()); // 1 example
|
||||||
addCmd(new CmdSet()); // 4 examples for player, 3 for console
|
addCmd(new CmdSet()); // 4 examples for player, 3 for console
|
||||||
addCmd(new CmdSetcorners()); // 1
|
addCmd(new CmdSetcorners()); // 1
|
||||||
@ -63,17 +56,14 @@ public class WBCommand implements CommandExecutor
|
|||||||
addCmd(new CmdCommands());
|
addCmd(new CmdCommands());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addCmd(WBCmd cmd) {
|
||||||
private void addCmd(WBCmd cmd)
|
|
||||||
{
|
|
||||||
subCommands.put(cmd.name, cmd);
|
subCommands.put(cmd.name, cmd);
|
||||||
if (cmd.hasWorldNameInput)
|
if (cmd.hasWorldNameInput)
|
||||||
subCommandsWithWorldNames.add(cmd.name);
|
subCommandsWithWorldNames.add(cmd.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] split)
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] split) {
|
||||||
{
|
|
||||||
Player player = (sender instanceof Player) ? (Player) sender : null;
|
Player player = (sender instanceof Player) ? (Player) sender : null;
|
||||||
|
|
||||||
// if world name is passed inside quotation marks, handle that, and get List<String> instead of String[]
|
// if world name is passed inside quotation marks, handle that, and get List<String> instead of String[]
|
||||||
@ -97,15 +87,11 @@ public class WBCommand implements CommandExecutor
|
|||||||
params.remove(0);
|
params.remove(0);
|
||||||
|
|
||||||
// make sure command is recognized, default to showing command examples / help if not; also check for specified page number
|
// make sure command is recognized, default to showing command examples / help if not; also check for specified page number
|
||||||
if (!subCommands.containsKey(cmdName))
|
if (!subCommands.containsKey(cmdName)) {
|
||||||
{
|
|
||||||
int page = (player == null) ? 0 : 1;
|
int page = (player == null) ? 0 : 1;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
page = Integer.parseInt(cmdName);
|
page = Integer.parseInt(cmdName);
|
||||||
}
|
} catch (NumberFormatException ignored) {
|
||||||
catch(NumberFormatException ignored)
|
|
||||||
{
|
|
||||||
sender.sendMessage(WBCmd.C_ERR + "Command not recognized. Showing command list.");
|
sender.sendMessage(WBCmd.C_ERR + "Command not recognized. Showing command list.");
|
||||||
}
|
}
|
||||||
cmdName = "commands";
|
cmdName = "commands";
|
||||||
@ -119,16 +105,14 @@ public class WBCommand implements CommandExecutor
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// if command requires world name when run by console, make sure that's in place
|
// if command requires world name when run by console, make sure that's in place
|
||||||
if (player == null && subCommand.hasWorldNameInput && subCommand.consoleRequiresWorldName && worldName == null)
|
if (player == null && subCommand.hasWorldNameInput && subCommand.consoleRequiresWorldName && worldName == null) {
|
||||||
{
|
|
||||||
sender.sendMessage(WBCmd.C_ERR + "This command requires a world to be specified if run by the console.");
|
sender.sendMessage(WBCmd.C_ERR + "This command requires a world to be specified if run by the console.");
|
||||||
subCommand.sendCmdHelp(sender);
|
subCommand.sendCmdHelp(sender);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure valid number of parameters has been provided
|
// make sure valid number of parameters has been provided
|
||||||
if (params.size() < subCommand.minParams || params.size() > subCommand.maxParams)
|
if (params.size() < subCommand.minParams || params.size() > subCommand.maxParams) {
|
||||||
{
|
|
||||||
if (subCommand.maxParams == 0)
|
if (subCommand.maxParams == 0)
|
||||||
sender.sendMessage(WBCmd.C_ERR + "This command does not accept any parameters.");
|
sender.sendMessage(WBCmd.C_ERR + "This command does not accept any parameters.");
|
||||||
else
|
else
|
||||||
@ -143,21 +127,15 @@ public class WBCommand implements CommandExecutor
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean wasWorldQuotation = false;
|
|
||||||
|
|
||||||
// if world name is surrounded by quotation marks, combine it down and flag wasWorldQuotation if it's first param.
|
// if world name is surrounded by quotation marks, combine it down and flag wasWorldQuotation if it's first param.
|
||||||
// also return List<String> instead of input primitive String[]
|
// also return List<String> instead of input primitive String[]
|
||||||
private List<String> concatenateQuotedWorldName(String[] split)
|
private List<String> concatenateQuotedWorldName(String[] split) {
|
||||||
{
|
|
||||||
wasWorldQuotation = false;
|
wasWorldQuotation = false;
|
||||||
List<String> args = new ArrayList<String>(Arrays.asList(split));
|
List<String> args = new ArrayList<String>(Arrays.asList(split));
|
||||||
|
|
||||||
int startIndex = -1;
|
int startIndex = -1;
|
||||||
for (int i = 0; i < args.size(); i++)
|
for (int i = 0; i < args.size(); i++) {
|
||||||
{
|
if (args.get(i).startsWith("\"")) {
|
||||||
if (args.get(i).startsWith("\""))
|
|
||||||
{
|
|
||||||
startIndex = i;
|
startIndex = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -165,32 +143,26 @@ public class WBCommand implements CommandExecutor
|
|||||||
if (startIndex == -1)
|
if (startIndex == -1)
|
||||||
return args;
|
return args;
|
||||||
|
|
||||||
if (args.get(startIndex).endsWith("\""))
|
if (args.get(startIndex).endsWith("\"")) {
|
||||||
{
|
|
||||||
args.set(startIndex, args.get(startIndex).substring(1, args.get(startIndex).length() - 1));
|
args.set(startIndex, args.get(startIndex).substring(1, args.get(startIndex).length() - 1));
|
||||||
if (startIndex == 0)
|
if (startIndex == 0)
|
||||||
wasWorldQuotation = true;
|
wasWorldQuotation = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
List<String> concat = new ArrayList<String>(args);
|
List<String> concat = new ArrayList<String>(args);
|
||||||
Iterator<String> concatI = concat.iterator();
|
Iterator<String> concatI = concat.iterator();
|
||||||
|
|
||||||
// skip past any parameters in front of the one we're starting on
|
// skip past any parameters in front of the one we're starting on
|
||||||
for (int i = 1; i < startIndex + 1; i++)
|
for (int i = 1; i < startIndex + 1; i++) {
|
||||||
{
|
|
||||||
concatI.next();
|
concatI.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder quote = new StringBuilder(concatI.next());
|
StringBuilder quote = new StringBuilder(concatI.next());
|
||||||
while (concatI.hasNext())
|
while (concatI.hasNext()) {
|
||||||
{
|
|
||||||
String next = concatI.next();
|
String next = concatI.next();
|
||||||
concatI.remove();
|
concatI.remove();
|
||||||
quote.append(" ");
|
quote.append(" ");
|
||||||
quote.append(next);
|
quote.append(next);
|
||||||
if (next.endsWith("\""))
|
if (next.endsWith("\"")) {
|
||||||
{
|
|
||||||
concat.set(startIndex, quote.substring(1, quote.length() - 1));
|
concat.set(startIndex, quote.substring(1, quote.length() - 1));
|
||||||
args = concat;
|
args = concat;
|
||||||
if (startIndex == 0)
|
if (startIndex == 0)
|
||||||
@ -202,8 +174,7 @@ public class WBCommand implements CommandExecutor
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getCommandNames()
|
public Set<String> getCommandNames() {
|
||||||
{
|
|
||||||
// using TreeSet to sort alphabetically
|
// using TreeSet to sort alphabetically
|
||||||
Set<String> commands = new TreeSet<>(subCommands.keySet());
|
Set<String> commands = new TreeSet<>(subCommands.keySet());
|
||||||
// removing default "commands" command as it's not normally shown or run like other commands
|
// removing default "commands" command as it's not normally shown or run like other commands
|
||||||
|
@ -1,21 +1,19 @@
|
|||||||
package com.wimbli.WorldBorder;
|
package com.wimbli.WorldBorder;
|
||||||
|
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
|
||||||
import org.bukkit.event.player.PlayerPortalEvent;
|
import org.bukkit.event.player.PlayerPortalEvent;
|
||||||
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
import org.bukkit.event.world.ChunkLoadEvent;
|
import org.bukkit.event.world.ChunkLoadEvent;
|
||||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||||
import org.bukkit.Location;
|
|
||||||
|
|
||||||
|
|
||||||
public class WBListener implements Listener
|
public class WBListener implements Listener {
|
||||||
{
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
public void onPlayerTeleport(PlayerTeleportEvent event)
|
public void onPlayerTeleport(PlayerTeleportEvent event) {
|
||||||
{
|
|
||||||
// if knockback is set to 0, simply return
|
// if knockback is set to 0, simply return
|
||||||
if (Config.KnockBack() == 0.0)
|
if (Config.KnockBack() == 0.0)
|
||||||
return;
|
return;
|
||||||
@ -24,10 +22,8 @@ public class WBListener implements Listener
|
|||||||
Config.log("Teleport cause: " + event.getCause().toString());
|
Config.log("Teleport cause: " + event.getCause().toString());
|
||||||
|
|
||||||
Location newLoc = BorderCheckTask.checkPlayer(event.getPlayer(), event.getTo(), true, true);
|
Location newLoc = BorderCheckTask.checkPlayer(event.getPlayer(), event.getTo(), true, true);
|
||||||
if (newLoc != null)
|
if (newLoc != null) {
|
||||||
{
|
if (event.getCause() == PlayerTeleportEvent.TeleportCause.ENDER_PEARL && Config.getDenyEnderpearl()) {
|
||||||
if(event.getCause() == PlayerTeleportEvent.TeleportCause.ENDER_PEARL && Config.getDenyEnderpearl())
|
|
||||||
{
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -37,8 +33,7 @@ public class WBListener implements Listener
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
public void onPlayerPortal(PlayerPortalEvent event)
|
public void onPlayerPortal(PlayerPortalEvent event) {
|
||||||
{
|
|
||||||
// if knockback is set to 0, or portal redirection is disabled, simply return
|
// if knockback is set to 0, or portal redirection is disabled, simply return
|
||||||
if (Config.KnockBack() == 0.0 || !Config.portalRedirection())
|
if (Config.KnockBack() == 0.0 || !Config.portalRedirection())
|
||||||
return;
|
return;
|
||||||
@ -49,8 +44,7 @@ public class WBListener implements Listener
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void onChunkLoad(ChunkLoadEvent event)
|
public void onChunkLoad(ChunkLoadEvent event) {
|
||||||
{
|
|
||||||
/* // tested, found to spam pretty rapidly as client repeatedly requests the same chunks since they're not being sent
|
/* // tested, found to spam pretty rapidly as client repeatedly requests the same chunks since they're not being sent
|
||||||
// definitely too spammy at only 16 blocks outside border
|
// definitely too spammy at only 16 blocks outside border
|
||||||
// potentially useful at standard 208 block padding as it was triggering only occasionally while trying to get out all along edge of round border, though sometimes up to 3 triggers within a second corresponding to 3 adjacent chunks
|
// potentially useful at standard 208 block padding as it was triggering only occasionally while trying to get out all along edge of round border, though sometimes up to 3 triggers within a second corresponding to 3 adjacent chunks
|
||||||
@ -77,8 +71,7 @@ public class WBListener implements Listener
|
|||||||
* and track if chunk was somehow on unload prevention list
|
* and track if chunk was somehow on unload prevention list
|
||||||
*/
|
*/
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onChunkUnload(ChunkUnloadEvent e)
|
public void onChunkUnload(ChunkUnloadEvent e) {
|
||||||
{
|
|
||||||
if (Config.fillTask == null)
|
if (Config.fillTask == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -4,16 +4,14 @@ import org.bukkit.Location;
|
|||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
|
||||||
public class WorldBorder extends JavaPlugin
|
public class WorldBorder extends JavaPlugin {
|
||||||
{
|
|
||||||
public static volatile WorldBorder plugin = null;
|
public static volatile WorldBorder plugin = null;
|
||||||
public static volatile WBCommand wbCommand = null;
|
public static volatile WBCommand wbCommand = null;
|
||||||
private BlockPlaceListener blockPlaceListener = null;
|
private BlockPlaceListener blockPlaceListener = null;
|
||||||
private MobSpawnListener mobSpawnListener = null;
|
private MobSpawnListener mobSpawnListener = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable()
|
public void onEnable() {
|
||||||
{
|
|
||||||
if (plugin == null)
|
if (plugin == null)
|
||||||
plugin = this;
|
plugin = this;
|
||||||
if (wbCommand == null)
|
if (wbCommand == null)
|
||||||
@ -43,8 +41,7 @@ public class WorldBorder extends JavaPlugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable()
|
public void onDisable() {
|
||||||
{
|
|
||||||
DynMapFeatures.removeAllBorders();
|
DynMapFeatures.removeAllBorders();
|
||||||
Config.StopBorderTimer();
|
Config.StopBorderTimer();
|
||||||
Config.StoreFillTask();
|
Config.StoreFillTask();
|
||||||
@ -52,8 +49,7 @@ public class WorldBorder extends JavaPlugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for other plugins to hook into
|
// for other plugins to hook into
|
||||||
public BorderData getWorldBorder(String worldName)
|
public BorderData getWorldBorder(String worldName) {
|
||||||
{
|
|
||||||
return Config.Border(worldName);
|
return Config.Border(worldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,21 +57,18 @@ public class WorldBorder extends JavaPlugin
|
|||||||
* @deprecated Replaced by {@link #getWorldBorder(String worldName)};
|
* @deprecated Replaced by {@link #getWorldBorder(String worldName)};
|
||||||
* this method name starts with an uppercase letter, which it shouldn't
|
* this method name starts with an uppercase letter, which it shouldn't
|
||||||
*/
|
*/
|
||||||
public BorderData GetWorldBorder(String worldName)
|
public BorderData GetWorldBorder(String worldName) {
|
||||||
{
|
|
||||||
return getWorldBorder(worldName);
|
return getWorldBorder(worldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enableBlockPlaceListener(boolean enable)
|
public void enableBlockPlaceListener(boolean enable) {
|
||||||
{
|
|
||||||
if (enable)
|
if (enable)
|
||||||
getServer().getPluginManager().registerEvents(this.blockPlaceListener = new BlockPlaceListener(), this);
|
getServer().getPluginManager().registerEvents(this.blockPlaceListener = new BlockPlaceListener(), this);
|
||||||
else if (blockPlaceListener != null)
|
else if (blockPlaceListener != null)
|
||||||
blockPlaceListener.unregister();
|
blockPlaceListener.unregister();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enableMobSpawnListener(boolean enable)
|
public void enableMobSpawnListener(boolean enable) {
|
||||||
{
|
|
||||||
if (enable)
|
if (enable)
|
||||||
getServer().getPluginManager().registerEvents(this.mobSpawnListener = new MobSpawnListener(), this);
|
getServer().getPluginManager().registerEvents(this.mobSpawnListener = new MobSpawnListener(), this);
|
||||||
else if (mobSpawnListener != null)
|
else if (mobSpawnListener != null)
|
||||||
|
@ -1,54 +1,51 @@
|
|||||||
package com.wimbli.WorldBorder;
|
package com.wimbli.WorldBorder;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.*;
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
// image output stuff, for debugging method at bottom of this file
|
// image output stuff, for debugging method at bottom of this file
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.*;
|
|
||||||
import javax.imageio.*;
|
|
||||||
|
|
||||||
|
|
||||||
// by the way, this region file handler was created based on the divulged region file format: http://mojang.com/2011/02/16/minecraft-save-file-format-in-beta-1-3/
|
// by the way, this region file handler was created based on the divulged region file format: http://mojang.com/2011/02/16/minecraft-save-file-format-in-beta-1-3/
|
||||||
|
|
||||||
public class WorldFileData
|
public class WorldFileData {
|
||||||
{
|
|
||||||
private transient World world;
|
private transient World world;
|
||||||
private transient File regionFolder = null;
|
private transient File regionFolder = null;
|
||||||
private transient File[] regionFiles = null;
|
private transient File[] regionFiles = null;
|
||||||
private transient Player notifyPlayer = null;
|
private transient Player notifyPlayer = null;
|
||||||
private transient Map<CoordXZ, List<Boolean>> regionChunkExistence = Collections.synchronizedMap(new HashMap<CoordXZ, List<Boolean>>());
|
private transient Map<CoordXZ, List<Boolean>> regionChunkExistence = Collections.synchronizedMap(new HashMap<CoordXZ, List<Boolean>>());
|
||||||
|
|
||||||
|
// the constructor is private; use create() method above to create an instance of this class.
|
||||||
|
private WorldFileData(World world, Player notifyPlayer) {
|
||||||
|
this.world = world;
|
||||||
|
this.notifyPlayer = notifyPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
// Use this static method to create a new instance of this class. If null is returned, there was a problem so any process relying on this should be cancelled.
|
// Use this static method to create a new instance of this class. If null is returned, there was a problem so any process relying on this should be cancelled.
|
||||||
public static WorldFileData create(World world, Player notifyPlayer)
|
public static WorldFileData create(World world, Player notifyPlayer) {
|
||||||
{
|
|
||||||
WorldFileData newData = new WorldFileData(world, notifyPlayer);
|
WorldFileData newData = new WorldFileData(world, notifyPlayer);
|
||||||
|
|
||||||
newData.regionFolder = new File(newData.world.getWorldFolder(), "region");
|
newData.regionFolder = new File(newData.world.getWorldFolder(), "region");
|
||||||
if (!newData.regionFolder.exists() || !newData.regionFolder.isDirectory())
|
if (!newData.regionFolder.exists() || !newData.regionFolder.isDirectory()) {
|
||||||
{
|
|
||||||
// check for region folder inside a DIM* folder (DIM-1 for nether, DIM1 for end, DIMwhatever for custom world types)
|
// check for region folder inside a DIM* folder (DIM-1 for nether, DIM1 for end, DIMwhatever for custom world types)
|
||||||
File[] possibleDimFolders = newData.world.getWorldFolder().listFiles(new DimFolderFileFilter());
|
File[] possibleDimFolders = newData.world.getWorldFolder().listFiles(new DimFolderFileFilter());
|
||||||
for (File possibleDimFolder : possibleDimFolders)
|
for (File possibleDimFolder : possibleDimFolders) {
|
||||||
{
|
|
||||||
File possible = new File(newData.world.getWorldFolder(), possibleDimFolder.getName() + File.separator + "region");
|
File possible = new File(newData.world.getWorldFolder(), possibleDimFolder.getName() + File.separator + "region");
|
||||||
if (possible.exists() && possible.isDirectory())
|
if (possible.exists() && possible.isDirectory()) {
|
||||||
{
|
|
||||||
newData.regionFolder = possible;
|
newData.regionFolder = possible;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!newData.regionFolder.exists() || !newData.regionFolder.isDirectory())
|
if (!newData.regionFolder.exists() || !newData.regionFolder.isDirectory()) {
|
||||||
{
|
|
||||||
newData.sendMessage("Could not validate folder for world's region files. Looked in " + newData.world.getWorldFolder().getPath() + " for valid DIM* folder with a region folder in it.");
|
newData.sendMessage("Could not validate folder for world's region files. Looked in " + newData.world.getWorldFolder().getPath() + " for valid DIM* folder with a region folder in it.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -56,11 +53,9 @@ public class WorldFileData
|
|||||||
|
|
||||||
// Accepted region file formats: MCR is from late beta versions through 1.1, MCA is from 1.2+
|
// Accepted region file formats: MCR is from late beta versions through 1.1, MCA is from 1.2+
|
||||||
newData.regionFiles = newData.regionFolder.listFiles(new ExtFileFilter(".MCA"));
|
newData.regionFiles = newData.regionFolder.listFiles(new ExtFileFilter(".MCA"));
|
||||||
if (newData.regionFiles == null || newData.regionFiles.length == 0)
|
if (newData.regionFiles == null || newData.regionFiles.length == 0) {
|
||||||
{
|
|
||||||
newData.regionFiles = newData.regionFolder.listFiles(new ExtFileFilter(".MCR"));
|
newData.regionFiles = newData.regionFolder.listFiles(new ExtFileFilter(".MCR"));
|
||||||
if (newData.regionFiles == null || newData.regionFiles.length == 0)
|
if (newData.regionFiles == null || newData.regionFiles.length == 0) {
|
||||||
{
|
|
||||||
newData.sendMessage("Could not find any region files. Looked in: " + newData.regionFolder.getPath());
|
newData.sendMessage("Could not find any region files. Looked in: " + newData.regionFolder.getPath());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -69,54 +64,38 @@ public class WorldFileData
|
|||||||
return newData;
|
return newData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the constructor is private; use create() method above to create an instance of this class.
|
|
||||||
private WorldFileData(World world, Player notifyPlayer)
|
|
||||||
{
|
|
||||||
this.world = world;
|
|
||||||
this.notifyPlayer = notifyPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// number of region files this world has
|
// number of region files this world has
|
||||||
public int regionFileCount()
|
public int regionFileCount() {
|
||||||
{
|
|
||||||
return regionFiles.length;
|
return regionFiles.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
// folder where world's region files are located
|
// folder where world's region files are located
|
||||||
public File regionFolder()
|
public File regionFolder() {
|
||||||
{
|
|
||||||
return regionFolder;
|
return regionFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return entire list of region files
|
// return entire list of region files
|
||||||
public File[] regionFiles()
|
public File[] regionFiles() {
|
||||||
{
|
|
||||||
return regionFiles.clone();
|
return regionFiles.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
// return a region file by index
|
// return a region file by index
|
||||||
public File regionFile(int index)
|
public File regionFile(int index) {
|
||||||
{
|
|
||||||
if (regionFiles.length < index)
|
if (regionFiles.length < index)
|
||||||
return null;
|
return null;
|
||||||
return regionFiles[index];
|
return regionFiles[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the X and Z world coordinates of the region from the filename
|
// get the X and Z world coordinates of the region from the filename
|
||||||
public CoordXZ regionFileCoordinates(int index)
|
public CoordXZ regionFileCoordinates(int index) {
|
||||||
{
|
|
||||||
File regionFile = this.regionFile(index);
|
File regionFile = this.regionFile(index);
|
||||||
String[] coords = regionFile.getName().split("\\.");
|
String[] coords = regionFile.getName().split("\\.");
|
||||||
int x, z;
|
int x, z;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
x = Integer.parseInt(coords[1]);
|
x = Integer.parseInt(coords[1]);
|
||||||
z = Integer.parseInt(coords[2]);
|
z = Integer.parseInt(coords[2]);
|
||||||
return new CoordXZ(x, z);
|
return new CoordXZ(x, z);
|
||||||
}
|
} catch (Exception ex) {
|
||||||
catch(Exception ex)
|
|
||||||
{
|
|
||||||
sendMessage("Error! Region file found with abnormal name: " + regionFile.getName());
|
sendMessage("Error! Region file found with abnormal name: " + regionFile.getName());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -124,8 +103,7 @@ public class WorldFileData
|
|||||||
|
|
||||||
|
|
||||||
// Find out if the chunk at the given coordinates exists.
|
// Find out if the chunk at the given coordinates exists.
|
||||||
public boolean doesChunkExist(int x, int z)
|
public boolean doesChunkExist(int x, int z) {
|
||||||
{
|
|
||||||
CoordXZ region = new CoordXZ(CoordXZ.chunkToRegion(x), CoordXZ.chunkToRegion(z));
|
CoordXZ region = new CoordXZ(CoordXZ.chunkToRegion(x), CoordXZ.chunkToRegion(z));
|
||||||
List<Boolean> regionChunks = this.getRegionData(region);
|
List<Boolean> regionChunks = this.getRegionData(region);
|
||||||
// Bukkit.getLogger().info("x: "+x+" z: "+z+" offset: "+coordToRegionOffset(x, z));
|
// Bukkit.getLogger().info("x: "+x+" z: "+z+" offset: "+coordToRegionOffset(x, z));
|
||||||
@ -134,13 +112,10 @@ public class WorldFileData
|
|||||||
|
|
||||||
// Find out if the chunk at the given coordinates has been fully generated.
|
// Find out if the chunk at the given coordinates has been fully generated.
|
||||||
// Minecraft only fully generates a chunk when adjacent chunks are also loaded.
|
// Minecraft only fully generates a chunk when adjacent chunks are also loaded.
|
||||||
public boolean isChunkFullyGenerated(int x, int z)
|
public boolean isChunkFullyGenerated(int x, int z) { // if all adjacent chunks exist, it should be a safe enough bet that this one is fully generated
|
||||||
{ // if all adjacent chunks exist, it should be a safe enough bet that this one is fully generated
|
|
||||||
// For 1.13+, due to world gen changes, this is now effectively a 3 chunk radius requirement vs a 1 chunk radius
|
// For 1.13+, due to world gen changes, this is now effectively a 3 chunk radius requirement vs a 1 chunk radius
|
||||||
for (int xx = x-3; xx <= x+3; xx++)
|
for (int xx = x - 3; xx <= x + 3; xx++) {
|
||||||
{
|
for (int zz = z - 3; zz <= z + 3; zz++) {
|
||||||
for (int zz = z-3; zz <= z+3; zz++)
|
|
||||||
{
|
|
||||||
if (!doesChunkExist(xx, zz))
|
if (!doesChunkExist(xx, zz))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -149,19 +124,16 @@ public class WorldFileData
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Method to let us know a chunk has been generated, to update our region map.
|
// Method to let us know a chunk has been generated, to update our region map.
|
||||||
public void chunkExistsNow(int x, int z)
|
public void chunkExistsNow(int x, int z) {
|
||||||
{
|
|
||||||
CoordXZ region = new CoordXZ(CoordXZ.chunkToRegion(x), CoordXZ.chunkToRegion(z));
|
CoordXZ region = new CoordXZ(CoordXZ.chunkToRegion(x), CoordXZ.chunkToRegion(z));
|
||||||
List<Boolean> regionChunks = this.getRegionData(region);
|
List<Boolean> regionChunks = this.getRegionData(region);
|
||||||
regionChunks.set(coordToRegionOffset(x, z), true);
|
regionChunks.set(coordToRegionOffset(x, z), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// region is 32 * 32 chunks; chunk pointers are stored in region file at position: x + z*32 (32 * 32 chunks = 1024)
|
// region is 32 * 32 chunks; chunk pointers are stored in region file at position: x + z*32 (32 * 32 chunks = 1024)
|
||||||
// input x and z values can be world-based chunk coordinates or local-to-region chunk coordinates either one
|
// input x and z values can be world-based chunk coordinates or local-to-region chunk coordinates either one
|
||||||
private int coordToRegionOffset(int x, int z)
|
private int coordToRegionOffset(int x, int z) {
|
||||||
{
|
|
||||||
// "%" modulus is used to convert potential world coordinates to definitely be local region coordinates
|
// "%" modulus is used to convert potential world coordinates to definitely be local region coordinates
|
||||||
x = x % 32;
|
x = x % 32;
|
||||||
z = z % 32;
|
z = z % 32;
|
||||||
@ -172,35 +144,30 @@ public class WorldFileData
|
|||||||
return (x + (z * 32));
|
return (x + (z * 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Boolean> getRegionData(CoordXZ region)
|
private List<Boolean> getRegionData(CoordXZ region) {
|
||||||
{
|
|
||||||
List<Boolean> data = regionChunkExistence.get(region);
|
List<Boolean> data = regionChunkExistence.get(region);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
// data for the specified region isn't loaded yet, so init it as empty and try to find the file and load the data
|
// data for the specified region isn't loaded yet, so init it as empty and try to find the file and load the data
|
||||||
data = new ArrayList<Boolean>(1024);
|
data = new ArrayList<Boolean>(1024);
|
||||||
for (int i = 0; i < 1024; i++)
|
for (int i = 0; i < 1024; i++) {
|
||||||
{
|
|
||||||
data.add(Boolean.FALSE);
|
data.add(Boolean.FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < regionFiles.length; i++)
|
for (int i = 0; i < regionFiles.length; i++) {
|
||||||
{
|
|
||||||
CoordXZ coord = regionFileCoordinates(i);
|
CoordXZ coord = regionFileCoordinates(i);
|
||||||
// is this region file the one we're looking for?
|
// is this region file the one we're looking for?
|
||||||
if (!coord.equals(region))
|
if (!coord.equals(region))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
RandomAccessFile regionData = new RandomAccessFile(this.regionFile(i), "r");
|
RandomAccessFile regionData = new RandomAccessFile(this.regionFile(i), "r");
|
||||||
|
|
||||||
// Use of ByteBuffer+IntBuffer for reading file headers to improve performance, as suggested by aikar, reference:
|
// Use of ByteBuffer+IntBuffer for reading file headers to improve performance, as suggested by aikar, reference:
|
||||||
// https://github.com/PaperMC/Paper/blob/b62dfa0bf95ac27ba0fbb3fae18c064e4bb61d50/Spigot-Server-Patches/0086-Reduce-IO-ops-opening-a-new-region-file.patch
|
// https://github.com/PaperMC/Paper/blob/b62dfa0bf95ac27ba0fbb3fae18c064e4bb61d50/Spigot-Server-Patches/0086-Reduce-IO-ops-opening-a-new-region-file.patch
|
||||||
ByteBuffer header = ByteBuffer.allocate(8192);
|
ByteBuffer header = ByteBuffer.allocate(8192);
|
||||||
while (header.hasRemaining())
|
while (header.hasRemaining()) {
|
||||||
{
|
|
||||||
if (regionData.getChannel().read(header) == -1)
|
if (regionData.getChannel().read(header) == -1)
|
||||||
throw new EOFException();
|
throw new EOFException();
|
||||||
}
|
}
|
||||||
@ -208,27 +175,21 @@ public class WorldFileData
|
|||||||
IntBuffer headerAsInts = header.asIntBuffer();
|
IntBuffer headerAsInts = header.asIntBuffer();
|
||||||
|
|
||||||
// first 4096 bytes of region file consists of 4-byte int pointers to chunk data in the file (32*32 chunks = 1024; 1024 chunks * 4 bytes each = 4096)
|
// first 4096 bytes of region file consists of 4-byte int pointers to chunk data in the file (32*32 chunks = 1024; 1024 chunks * 4 bytes each = 4096)
|
||||||
for (int j = 0; j < 1024; j++)
|
for (int j = 0; j < 1024; j++) {
|
||||||
{
|
|
||||||
// if chunk pointer data is 0, chunk doesn't exist yet; otherwise, it does
|
// if chunk pointer data is 0, chunk doesn't exist yet; otherwise, it does
|
||||||
if (headerAsInts.get() != 0)
|
if (headerAsInts.get() != 0)
|
||||||
data.set(j, true);
|
data.set(j, true);
|
||||||
}
|
}
|
||||||
// Read timestamps
|
// Read timestamps
|
||||||
for (int j = 0; j < 1024; j++)
|
for (int j = 0; j < 1024; j++) {
|
||||||
{
|
|
||||||
// if timestamp is zero, it is protochunk (ignore it)
|
// if timestamp is zero, it is protochunk (ignore it)
|
||||||
if ((headerAsInts.get() == 0) && data.get(j))
|
if ((headerAsInts.get() == 0) && data.get(j))
|
||||||
data.set(j, false);
|
data.set(j, false);
|
||||||
}
|
}
|
||||||
regionData.close();
|
regionData.close();
|
||||||
}
|
} catch (FileNotFoundException ex) {
|
||||||
catch (FileNotFoundException ex)
|
|
||||||
{
|
|
||||||
sendMessage("Error! Could not open region file to find generated chunks: " + this.regionFile(i).getName());
|
sendMessage("Error! Could not open region file to find generated chunks: " + this.regionFile(i).getName());
|
||||||
}
|
} catch (IOException ex) {
|
||||||
catch (IOException ex)
|
|
||||||
{
|
|
||||||
sendMessage("Error! Could not read region file to find generated chunks: " + this.regionFile(i).getName());
|
sendMessage("Error! Could not read region file to find generated chunks: " + this.regionFile(i).getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,48 +199,12 @@ public class WorldFileData
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send a message to the server console/log and possibly to an in-game player
|
// send a message to the server console/log and possibly to an in-game player
|
||||||
private void sendMessage(String text)
|
private void sendMessage(String text) {
|
||||||
{
|
|
||||||
Config.log("[WorldData] " + text);
|
Config.log("[WorldData] " + text);
|
||||||
if (notifyPlayer != null && notifyPlayer.isOnline())
|
if (notifyPlayer != null && notifyPlayer.isOnline())
|
||||||
notifyPlayer.sendMessage("[WorldData] " + text);
|
notifyPlayer.sendMessage("[WorldData] " + text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// file filter used for region files
|
|
||||||
private static class ExtFileFilter implements FileFilter
|
|
||||||
{
|
|
||||||
String ext;
|
|
||||||
public ExtFileFilter(String extension)
|
|
||||||
{
|
|
||||||
this.ext = extension.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean accept(File file)
|
|
||||||
{
|
|
||||||
return (
|
|
||||||
file.exists()
|
|
||||||
&& file.isFile()
|
|
||||||
&& file.getName().toLowerCase().endsWith(ext)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// file filter used for DIM* folders (for nether, End, and custom world types)
|
|
||||||
private static class DimFolderFileFilter implements FileFilter
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean accept(File file)
|
|
||||||
{
|
|
||||||
return (
|
|
||||||
file.exists()
|
|
||||||
&& file.isDirectory()
|
|
||||||
&& file.getName().toLowerCase().startsWith("dim")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// crude chunk map PNG image output, for debugging
|
// crude chunk map PNG image output, for debugging
|
||||||
private void testImage(CoordXZ region, List<Boolean> data) {
|
private void testImage(CoordXZ region, List<Boolean> data) {
|
||||||
int width = 32;
|
int width = 32;
|
||||||
@ -289,10 +214,8 @@ public class WorldFileData
|
|||||||
int current = 0;
|
int current = 0;
|
||||||
g2.setColor(Color.BLACK);
|
g2.setColor(Color.BLACK);
|
||||||
|
|
||||||
for (int x = 0; x < 32; x++)
|
for (int x = 0; x < 32; x++) {
|
||||||
{
|
for (int z = 0; z < 32; z++) {
|
||||||
for (int z = 0; z < 32; z++)
|
|
||||||
{
|
|
||||||
if (data.get(current).booleanValue())
|
if (data.get(current).booleanValue())
|
||||||
g2.fillRect(x, z, x + 1, z + 1);
|
g2.fillRect(x, z, x + 1, z + 1);
|
||||||
current++;
|
current++;
|
||||||
@ -308,4 +231,34 @@ public class WorldFileData
|
|||||||
Config.log("[SEVERE]" + ex.getLocalizedMessage());
|
Config.log("[SEVERE]" + ex.getLocalizedMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// file filter used for region files
|
||||||
|
private static class ExtFileFilter implements FileFilter {
|
||||||
|
String ext;
|
||||||
|
|
||||||
|
public ExtFileFilter(String extension) {
|
||||||
|
this.ext = extension.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accept(File file) {
|
||||||
|
return (
|
||||||
|
file.exists()
|
||||||
|
&& file.isFile()
|
||||||
|
&& file.getName().toLowerCase().endsWith(ext)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// file filter used for DIM* folders (for nether, End, and custom world types)
|
||||||
|
private static class DimFolderFileFilter implements FileFilter {
|
||||||
|
@Override
|
||||||
|
public boolean accept(File file) {
|
||||||
|
return (
|
||||||
|
file.exists()
|
||||||
|
&& file.isDirectory()
|
||||||
|
&& file.getName().toLowerCase().startsWith("dim")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,22 @@
|
|||||||
package com.wimbli.WorldBorder;
|
package com.wimbli.WorldBorder;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import com.wimbli.WorldBorder.Events.WorldBorderFillFinishedEvent;
|
||||||
|
import com.wimbli.WorldBorder.Events.WorldBorderFillStartEvent;
|
||||||
|
import io.papermc.lib.PaperLib;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.Server;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.Server;
|
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
import io.papermc.lib.PaperLib;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.Events.WorldBorderFillFinishedEvent;
|
|
||||||
import com.wimbli.WorldBorder.Events.WorldBorderFillStartEvent;
|
|
||||||
|
|
||||||
|
|
||||||
public class WorldFillTask implements Runnable
|
public class WorldFillTask implements Runnable {
|
||||||
{
|
|
||||||
// general task-related reference data
|
// general task-related reference data
|
||||||
private transient Server server = null;
|
private transient Server server = null;
|
||||||
private transient World world = null;
|
private transient World world = null;
|
||||||
@ -67,45 +64,7 @@ public class WorldFillTask implements Runnable
|
|||||||
// several others.
|
// several others.
|
||||||
private transient Set<UnloadDependency> preventUnload;
|
private transient Set<UnloadDependency> preventUnload;
|
||||||
|
|
||||||
private class UnloadDependency
|
public WorldFillTask(Server theServer, Player player, String worldName, int fillDistance, int chunksPerRun, int tickFrequency, boolean forceLoad) {
|
||||||
{
|
|
||||||
int neededX, neededZ;
|
|
||||||
int forX, forZ;
|
|
||||||
|
|
||||||
UnloadDependency(int neededX, int neededZ, int forX, int forZ)
|
|
||||||
{
|
|
||||||
this.neededX=neededX;
|
|
||||||
this.neededZ=neededZ;
|
|
||||||
this.forX=forX;
|
|
||||||
this.forZ=forZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object other)
|
|
||||||
{
|
|
||||||
if (other == null || !(other instanceof UnloadDependency))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return this.neededX == ((UnloadDependency) other).neededX
|
|
||||||
&& this.neededZ == ((UnloadDependency) other).neededZ
|
|
||||||
&& this.forX == ((UnloadDependency) other).forX
|
|
||||||
&& this.forZ == ((UnloadDependency) other).forZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode()
|
|
||||||
{
|
|
||||||
int hash = 7;
|
|
||||||
hash = 79 * hash + this.neededX;
|
|
||||||
hash = 79 * hash + this.neededZ;
|
|
||||||
hash = 79 * hash + this.forX;
|
|
||||||
hash = 79 * hash + this.forZ;
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public WorldFillTask(Server theServer, Player player, String worldName, int fillDistance, int chunksPerRun, int tickFrequency, boolean forceLoad)
|
|
||||||
{
|
|
||||||
this.server = theServer;
|
this.server = theServer;
|
||||||
this.notifyPlayer = player;
|
this.notifyPlayer = player;
|
||||||
this.fillDistance = fillDistance;
|
this.fillDistance = fillDistance;
|
||||||
@ -114,8 +73,7 @@ public class WorldFillTask implements Runnable
|
|||||||
this.forceLoad = forceLoad;
|
this.forceLoad = forceLoad;
|
||||||
|
|
||||||
this.world = server.getWorld(worldName);
|
this.world = server.getWorld(worldName);
|
||||||
if (this.world == null)
|
if (this.world == null) {
|
||||||
{
|
|
||||||
if (worldName.isEmpty())
|
if (worldName.isEmpty())
|
||||||
sendMessage("You must specify a world!");
|
sendMessage("You must specify a world!");
|
||||||
else
|
else
|
||||||
@ -125,8 +83,7 @@ public class WorldFillTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.border = (Config.Border(worldName) == null) ? null : Config.Border(worldName).copy();
|
this.border = (Config.Border(worldName) == null) ? null : Config.Border(worldName).copy();
|
||||||
if (this.border == null)
|
if (this.border == null) {
|
||||||
{
|
|
||||||
sendMessage("No border found for world \"" + worldName + "\"!");
|
sendMessage("No border found for world \"" + worldName + "\"!");
|
||||||
this.stop();
|
this.stop();
|
||||||
return;
|
return;
|
||||||
@ -134,8 +91,7 @@ public class WorldFillTask implements Runnable
|
|||||||
|
|
||||||
// load up a new WorldFileData for the world in question, used to scan region files for which chunks are already fully generated and such
|
// load up a new WorldFileData for the world in question, used to scan region files for which chunks are already fully generated and such
|
||||||
worldData = WorldFileData.create(world, notifyPlayer);
|
worldData = WorldFileData.create(world, notifyPlayer);
|
||||||
if (worldData == null)
|
if (worldData == null) {
|
||||||
{
|
|
||||||
this.stop();
|
this.stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -162,29 +118,24 @@ public class WorldFillTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for backwards compatibility
|
// for backwards compatibility
|
||||||
public WorldFillTask(Server theServer, Player player, String worldName, int fillDistance, int chunksPerRun, int tickFrequency)
|
public WorldFillTask(Server theServer, Player player, String worldName, int fillDistance, int chunksPerRun, int tickFrequency) {
|
||||||
{
|
|
||||||
this(theServer, player, worldName, fillDistance, chunksPerRun, tickFrequency, false);
|
this(theServer, player, worldName, fillDistance, chunksPerRun, tickFrequency, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTaskID(int ID)
|
public void setTaskID(int ID) {
|
||||||
{
|
|
||||||
if (ID == -1) this.stop();
|
if (ID == -1) this.stop();
|
||||||
this.taskID = ID;
|
this.taskID = ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run() {
|
||||||
{
|
if (continueNotice) { // notify user that task has continued automatically
|
||||||
if (continueNotice)
|
|
||||||
{ // notify user that task has continued automatically
|
|
||||||
continueNotice = false;
|
continueNotice = false;
|
||||||
sendMessage("World map generation task automatically continuing.");
|
sendMessage("World map generation task automatically continuing.");
|
||||||
sendMessage("Reminder: you can cancel at any time with \"wb fill cancel\", or pause/unpause with \"wb fill pause\".");
|
sendMessage("Reminder: you can cancel at any time with \"wb fill cancel\", or pause/unpause with \"wb fill pause\".");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pausedForMemory)
|
if (pausedForMemory) { // if available memory gets too low, we automatically pause, so handle that
|
||||||
{ // if available memory gets too low, we automatically pause, so handle that
|
|
||||||
if (Config.AvailableMemoryTooLow())
|
if (Config.AvailableMemoryTooLow())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -210,18 +161,15 @@ public class WorldFillTask implements Runnable
|
|||||||
int chunksProcessedLastTick = 0;
|
int chunksProcessedLastTick = 0;
|
||||||
Map<CompletableFuture<Void>, CoordXZ> newPendingChunks = new HashMap<>();
|
Map<CompletableFuture<Void>, CoordXZ> newPendingChunks = new HashMap<>();
|
||||||
Set<CoordXZ> chunksToUnload = new HashSet<>();
|
Set<CoordXZ> chunksToUnload = new HashSet<>();
|
||||||
for (CompletableFuture<Void> cf : pendingChunks.keySet())
|
for (CompletableFuture<Void> cf : pendingChunks.keySet()) {
|
||||||
{
|
if (cf.isDone()) {
|
||||||
if (cf.isDone())
|
|
||||||
{
|
|
||||||
++chunksProcessedLastTick;
|
++chunksProcessedLastTick;
|
||||||
// If cf.get() returned the chunk reliably, pendingChunks could
|
// If cf.get() returned the chunk reliably, pendingChunks could
|
||||||
// be a set and we wouldn't have to map CFs to coords ...
|
// be a set and we wouldn't have to map CFs to coords ...
|
||||||
CoordXZ xz = pendingChunks.get(cf);
|
CoordXZ xz = pendingChunks.get(cf);
|
||||||
worldData.chunkExistsNow(xz.x, xz.z);
|
worldData.chunkExistsNow(xz.x, xz.z);
|
||||||
chunksToUnload.add(xz);
|
chunksToUnload.add(xz);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
newPendingChunks.put(cf, pendingChunks.get(cf));
|
newPendingChunks.put(cf, pendingChunks.get(cf));
|
||||||
}
|
}
|
||||||
pendingChunks = newPendingChunks;
|
pendingChunks = newPendingChunks;
|
||||||
@ -229,8 +177,7 @@ public class WorldFillTask implements Runnable
|
|||||||
// Next, check which chunks had been loaded because a to-be-generated
|
// Next, check which chunks had been loaded because a to-be-generated
|
||||||
// chunk needed them, and don't have to remain in memory any more.
|
// chunk needed them, and don't have to remain in memory any more.
|
||||||
Set<UnloadDependency> newPreventUnload = new HashSet<>();
|
Set<UnloadDependency> newPreventUnload = new HashSet<>();
|
||||||
for (UnloadDependency dependency : preventUnload)
|
for (UnloadDependency dependency : preventUnload) {
|
||||||
{
|
|
||||||
if (worldData.doesChunkExist(dependency.forX, dependency.forZ))
|
if (worldData.doesChunkExist(dependency.forX, dependency.forZ))
|
||||||
chunksToUnload.add(new CoordXZ(dependency.neededX, dependency.neededZ));
|
chunksToUnload.add(new CoordXZ(dependency.neededX, dependency.neededZ));
|
||||||
else
|
else
|
||||||
@ -244,10 +191,8 @@ public class WorldFillTask implements Runnable
|
|||||||
// The ChunkUnloadListener checks this anyway, but it doesn't hurt to
|
// The ChunkUnloadListener checks this anyway, but it doesn't hurt to
|
||||||
// save a few µs by not even requesting the unload.
|
// save a few µs by not even requesting the unload.
|
||||||
|
|
||||||
for (CoordXZ unload : chunksToUnload)
|
for (CoordXZ unload : chunksToUnload) {
|
||||||
{
|
if (!chunkOnUnloadPreventionList(unload.x, unload.z)) {
|
||||||
if (!chunkOnUnloadPreventionList(unload.x, unload.z))
|
|
||||||
{
|
|
||||||
world.setChunkForceLoaded(unload.x, unload.z, false);
|
world.setChunkForceLoaded(unload.x, unload.z, false);
|
||||||
world.unloadChunkRequest(unload.x, unload.z);
|
world.unloadChunkRequest(unload.x, unload.z);
|
||||||
}
|
}
|
||||||
@ -261,16 +206,14 @@ public class WorldFillTask implements Runnable
|
|||||||
// long queue of fill-generations.
|
// long queue of fill-generations.
|
||||||
|
|
||||||
int chunksToProcess = chunksPerRun;
|
int chunksToProcess = chunksPerRun;
|
||||||
if (chunksProcessedLastTick > 0 || pendingChunks.size() > 0)
|
if (chunksProcessedLastTick > 0 || pendingChunks.size() > 0) {
|
||||||
{
|
|
||||||
// Note we generally queue 3 chunks, so real numbers are 1/3 of chunksProcessedLastTick and pendingchunks.size
|
// Note we generally queue 3 chunks, so real numbers are 1/3 of chunksProcessedLastTick and pendingchunks.size
|
||||||
int chunksExpectedToGetProcessed = (chunksProcessedLastTick - pendingChunks.size()) / 3 + 3;
|
int chunksExpectedToGetProcessed = (chunksProcessedLastTick - pendingChunks.size()) / 3 + 3;
|
||||||
if (chunksExpectedToGetProcessed < chunksToProcess)
|
if (chunksExpectedToGetProcessed < chunksToProcess)
|
||||||
chunksToProcess = chunksExpectedToGetProcessed;
|
chunksToProcess = chunksExpectedToGetProcessed;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int loop = 0; loop < chunksToProcess; loop++)
|
for (int loop = 0; loop < chunksToProcess; loop++) {
|
||||||
{
|
|
||||||
// in case the task has been paused while we're repeating...
|
// in case the task has been paused while we're repeating...
|
||||||
if (paused || pausedForMemory)
|
if (paused || pausedForMemory)
|
||||||
return;
|
return;
|
||||||
@ -282,33 +225,28 @@ public class WorldFillTask implements Runnable
|
|||||||
reportProgress();
|
reportProgress();
|
||||||
|
|
||||||
// if this iteration has been running for 45ms (almost 1 tick) or more, stop to take a breather
|
// if this iteration has been running for 45ms (almost 1 tick) or more, stop to take a breather
|
||||||
if (now > loopStartTime + 45)
|
if (now > loopStartTime + 45) {
|
||||||
{
|
|
||||||
readyToGo = true;
|
readyToGo = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we've made it at least partly outside the border, skip past any such chunks
|
// if we've made it at least partly outside the border, skip past any such chunks
|
||||||
while (!border.insideBorder(CoordXZ.chunkToBlock(x) + 8, CoordXZ.chunkToBlock(z) + 8))
|
while (!border.insideBorder(CoordXZ.chunkToBlock(x) + 8, CoordXZ.chunkToBlock(z) + 8)) {
|
||||||
{
|
|
||||||
if (!moveToNext())
|
if (!moveToNext())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
insideBorder = true;
|
insideBorder = true;
|
||||||
|
|
||||||
if (!forceLoad)
|
if (!forceLoad) {
|
||||||
{
|
|
||||||
// skip past any chunks which are confirmed as fully generated using our super-special isChunkFullyGenerated routine
|
// skip past any chunks which are confirmed as fully generated using our super-special isChunkFullyGenerated routine
|
||||||
int rLoop = 0;
|
int rLoop = 0;
|
||||||
while (worldData.isChunkFullyGenerated(x, z))
|
while (worldData.isChunkFullyGenerated(x, z)) {
|
||||||
{
|
|
||||||
rLoop++;
|
rLoop++;
|
||||||
insideBorder = true;
|
insideBorder = true;
|
||||||
if (!moveToNext())
|
if (!moveToNext())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (rLoop > 255)
|
if (rLoop > 255) { // only skim through max 256 chunks (~8 region files) at a time here, to allow process to take a break if needed
|
||||||
{ // only skim through max 256 chunks (~8 region files) at a time here, to allow process to take a break if needed
|
|
||||||
readyToGo = true;
|
readyToGo = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -338,18 +276,15 @@ public class WorldFillTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// step through chunks in spiral pattern from center; returns false if we're done, otherwise returns true
|
// step through chunks in spiral pattern from center; returns false if we're done, otherwise returns true
|
||||||
public boolean moveToNext()
|
public boolean moveToNext() {
|
||||||
{
|
|
||||||
if (paused || pausedForMemory)
|
if (paused || pausedForMemory)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
reportNum++;
|
reportNum++;
|
||||||
|
|
||||||
// keep track of progress in case we need to save to config for restoring progress after server restart
|
// keep track of progress in case we need to save to config for restoring progress after server restart
|
||||||
if (!isNeg && current == 0 && length > 3)
|
if (!isNeg && current == 0 && length > 3) {
|
||||||
{
|
if (!isZLeg) {
|
||||||
if (!isZLeg)
|
|
||||||
{
|
|
||||||
lastLegX = x;
|
lastLegX = x;
|
||||||
lastLegZ = z;
|
lastLegZ = z;
|
||||||
lastLegTotal = reportTotal + reportNum;
|
lastLegTotal = reportTotal + reportNum;
|
||||||
@ -364,12 +299,10 @@ public class WorldFillTask implements Runnable
|
|||||||
// make sure of the direction we're moving (X or Z? negative or positive?)
|
// make sure of the direction we're moving (X or Z? negative or positive?)
|
||||||
if (current < length)
|
if (current < length)
|
||||||
current++;
|
current++;
|
||||||
else
|
else { // one leg/side of the spiral down...
|
||||||
{ // one leg/side of the spiral down...
|
|
||||||
current = 0;
|
current = 0;
|
||||||
isZLeg ^= true;
|
isZLeg ^= true;
|
||||||
if (isZLeg)
|
if (isZLeg) { // every second leg (between X and Z legs, negative or positive), length increases
|
||||||
{ // every second leg (between X and Z legs, negative or positive), length increases
|
|
||||||
isNeg ^= true;
|
isNeg ^= true;
|
||||||
length++;
|
length++;
|
||||||
}
|
}
|
||||||
@ -386,10 +319,8 @@ public class WorldFillTask implements Runnable
|
|||||||
x += (isNeg) ? -1 : 1;
|
x += (isNeg) ? -1 : 1;
|
||||||
|
|
||||||
// if we've been around one full loop (4 legs)...
|
// if we've been around one full loop (4 legs)...
|
||||||
if (isZLeg && isNeg && current == 0)
|
if (isZLeg && isNeg && current == 0) { // see if we've been outside the border for the whole loop
|
||||||
{ // see if we've been outside the border for the whole loop
|
if (!insideBorder) { // and finish if so
|
||||||
if (!insideBorder)
|
|
||||||
{ // and finish if so
|
|
||||||
finish();
|
finish();
|
||||||
return false;
|
return false;
|
||||||
} // otherwise, reset the "inside border" flag
|
} // otherwise, reset the "inside border" flag
|
||||||
@ -412,8 +343,7 @@ public class WorldFillTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for successful completion
|
// for successful completion
|
||||||
public void finish()
|
public void finish() {
|
||||||
{
|
|
||||||
this.paused = true;
|
this.paused = true;
|
||||||
reportProgress();
|
reportProgress();
|
||||||
world.save();
|
world.save();
|
||||||
@ -423,14 +353,12 @@ public class WorldFillTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for cancelling prematurely
|
// for cancelling prematurely
|
||||||
public void cancel()
|
public void cancel() {
|
||||||
{
|
|
||||||
this.stop();
|
this.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// we're done, whether finished or cancelled
|
// we're done, whether finished or cancelled
|
||||||
private void stop()
|
private void stop() {
|
||||||
{
|
|
||||||
if (server == null)
|
if (server == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -442,12 +370,10 @@ public class WorldFillTask implements Runnable
|
|||||||
// go ahead and unload any chunks we still have loaded
|
// go ahead and unload any chunks we still have loaded
|
||||||
// Set preventUnload to empty first so the ChunkUnloadEvent Listener
|
// Set preventUnload to empty first so the ChunkUnloadEvent Listener
|
||||||
// doesn't get in our way
|
// doesn't get in our way
|
||||||
if (preventUnload != null)
|
if (preventUnload != null) {
|
||||||
{
|
|
||||||
Set<UnloadDependency> tempPreventUnload = preventUnload;
|
Set<UnloadDependency> tempPreventUnload = preventUnload;
|
||||||
preventUnload = null;
|
preventUnload = null;
|
||||||
for (UnloadDependency entry: tempPreventUnload)
|
for (UnloadDependency entry : tempPreventUnload) {
|
||||||
{
|
|
||||||
world.setChunkForceLoaded(entry.neededX, entry.neededZ, false);
|
world.setChunkForceLoaded(entry.neededX, entry.neededZ, false);
|
||||||
world.unloadChunkRequest(entry.neededX, entry.neededZ);
|
world.unloadChunkRequest(entry.neededX, entry.neededZ);
|
||||||
}
|
}
|
||||||
@ -455,44 +381,37 @@ public class WorldFillTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// is this task still valid/workable?
|
// is this task still valid/workable?
|
||||||
public boolean valid()
|
public boolean valid() {
|
||||||
{
|
|
||||||
return this.server != null;
|
return this.server != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle pausing/unpausing the task
|
// handle pausing/unpausing the task
|
||||||
public void pause()
|
public void pause() {
|
||||||
{
|
|
||||||
if (this.pausedForMemory)
|
if (this.pausedForMemory)
|
||||||
pause(false);
|
pause(false);
|
||||||
else
|
else
|
||||||
pause(!this.paused);
|
pause(!this.paused);
|
||||||
}
|
}
|
||||||
public void pause(boolean pause)
|
|
||||||
{
|
public void pause(boolean pause) {
|
||||||
if (this.pausedForMemory && !pause)
|
if (this.pausedForMemory && !pause)
|
||||||
this.pausedForMemory = false;
|
this.pausedForMemory = false;
|
||||||
else
|
else
|
||||||
this.paused = pause;
|
this.paused = pause;
|
||||||
if (this.paused)
|
if (this.paused) {
|
||||||
{
|
|
||||||
Config.StoreFillTask();
|
Config.StoreFillTask();
|
||||||
reportProgress();
|
reportProgress();
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
Config.UnStoreFillTask();
|
Config.UnStoreFillTask();
|
||||||
}
|
}
|
||||||
public boolean isPaused()
|
|
||||||
{
|
public boolean isPaused() {
|
||||||
return this.paused || this.pausedForMemory;
|
return this.paused || this.pausedForMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean chunkOnUnloadPreventionList(int x, int z)
|
public boolean chunkOnUnloadPreventionList(int x, int z) {
|
||||||
{
|
if (preventUnload != null) {
|
||||||
if (preventUnload != null)
|
for (UnloadDependency entry : preventUnload) {
|
||||||
{
|
|
||||||
for (UnloadDependency entry: preventUnload)
|
|
||||||
{
|
|
||||||
if (entry.neededX == x && entry.neededZ == z)
|
if (entry.neededX == x && entry.neededZ == z)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -500,14 +419,12 @@ public class WorldFillTask implements Runnable
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public World getWorld()
|
public World getWorld() {
|
||||||
{
|
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
// let the user know how things are coming along
|
// let the user know how things are coming along
|
||||||
private void reportProgress()
|
private void reportProgress() {
|
||||||
{
|
|
||||||
lastReport = Config.Now();
|
lastReport = Config.Now();
|
||||||
double perc = getPercentageCompleted();
|
double perc = getPercentageCompleted();
|
||||||
if (perc > 100) perc = 100;
|
if (perc > 100) perc = 100;
|
||||||
@ -516,8 +433,7 @@ public class WorldFillTask implements Runnable
|
|||||||
reportNum = 0;
|
reportNum = 0;
|
||||||
|
|
||||||
// go ahead and save world to disk every 30 seconds or so by default, just in case; can take a couple of seconds or more, so we don't want to run it too often
|
// go ahead and save world to disk every 30 seconds or so by default, just in case; can take a couple of seconds or more, so we don't want to run it too often
|
||||||
if (Config.FillAutosaveFrequency() > 0 && lastAutosave + (Config.FillAutosaveFrequency() * 1000) < lastReport)
|
if (Config.FillAutosaveFrequency() > 0 && lastAutosave + (Config.FillAutosaveFrequency() * 1000) < lastReport) {
|
||||||
{
|
|
||||||
lastAutosave = lastReport;
|
lastAutosave = lastReport;
|
||||||
sendMessage("Saving the world to disk, just to be on the safe side.");
|
sendMessage("Saving the world to disk, just to be on the safe side.");
|
||||||
world.save();
|
world.save();
|
||||||
@ -525,8 +441,7 @@ public class WorldFillTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send a message to the server console/log and possibly to an in-game player
|
// send a message to the server console/log and possibly to an in-game player
|
||||||
private void sendMessage(String text)
|
private void sendMessage(String text) {
|
||||||
{
|
|
||||||
// Due to chunk generation eating up memory and Java being too slow about GC, we need to track memory availability
|
// Due to chunk generation eating up memory and Java being too slow about GC, we need to track memory availability
|
||||||
int availMem = Config.AvailableMemory();
|
int availMem = Config.AvailableMemory();
|
||||||
|
|
||||||
@ -534,8 +449,7 @@ public class WorldFillTask implements Runnable
|
|||||||
if (notifyPlayer != null)
|
if (notifyPlayer != null)
|
||||||
notifyPlayer.sendMessage("[Fill] " + text);
|
notifyPlayer.sendMessage("[Fill] " + text);
|
||||||
|
|
||||||
if (availMem < 200)
|
if (availMem < 200) { // running low on memory, auto-pause
|
||||||
{ // running low on memory, auto-pause
|
|
||||||
pausedForMemory = true;
|
pausedForMemory = true;
|
||||||
Config.StoreFillTask();
|
Config.StoreFillTask();
|
||||||
text = "Available memory is very low, task is pausing. A cleanup will be attempted now, and the task will automatically continue if/when sufficient memory is freed up.\n Alternatively, if you restart the server, this task will automatically continue once the server is back up.";
|
text = "Available memory is very low, task is pausing. A cleanup will be attempted now, and the task will automatically continue if/when sufficient memory is freed up.\n Alternatively, if you restart the server, this task will automatically continue once the server is back up.";
|
||||||
@ -549,48 +463,47 @@ public class WorldFillTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stuff for saving / restoring progress
|
// stuff for saving / restoring progress
|
||||||
public void continueProgress(int x, int z, int length, int totalDone)
|
public void continueProgress(int x, int z, int length, int totalDone) {
|
||||||
{
|
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
this.length = length;
|
this.length = length;
|
||||||
this.reportTotal = totalDone;
|
this.reportTotal = totalDone;
|
||||||
this.continueNotice = true;
|
this.continueNotice = true;
|
||||||
}
|
}
|
||||||
public int refX()
|
|
||||||
{
|
public int refX() {
|
||||||
return refX;
|
return refX;
|
||||||
}
|
}
|
||||||
public int refZ()
|
|
||||||
{
|
public int refZ() {
|
||||||
return refZ;
|
return refZ;
|
||||||
}
|
}
|
||||||
public int refLength()
|
|
||||||
{
|
public int refLength() {
|
||||||
return refLength;
|
return refLength;
|
||||||
}
|
}
|
||||||
public int refTotal()
|
|
||||||
{
|
public int refTotal() {
|
||||||
return refTotal;
|
return refTotal;
|
||||||
}
|
}
|
||||||
public int refFillDistance()
|
|
||||||
{
|
public int refFillDistance() {
|
||||||
return fillDistance;
|
return fillDistance;
|
||||||
}
|
}
|
||||||
public int refTickFrequency()
|
|
||||||
{
|
public int refTickFrequency() {
|
||||||
return tickFrequency;
|
return tickFrequency;
|
||||||
}
|
}
|
||||||
public int refChunksPerRun()
|
|
||||||
{
|
public int refChunksPerRun() {
|
||||||
return chunksPerRun;
|
return chunksPerRun;
|
||||||
}
|
}
|
||||||
public String refWorld()
|
|
||||||
{
|
public String refWorld() {
|
||||||
return world.getName();
|
return world.getName();
|
||||||
}
|
}
|
||||||
public boolean refForceLoad()
|
|
||||||
{
|
public boolean refForceLoad() {
|
||||||
return forceLoad;
|
return forceLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,8 +512,7 @@ public class WorldFillTask implements Runnable
|
|||||||
*
|
*
|
||||||
* @return Percentage
|
* @return Percentage
|
||||||
*/
|
*/
|
||||||
public double getPercentageCompleted()
|
public double getPercentageCompleted() {
|
||||||
{
|
|
||||||
return ((double) (reportTotal + reportNum) / (double) reportTarget) * 100;
|
return ((double) (reportTotal + reportNum) / (double) reportTarget) * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,8 +521,7 @@ public class WorldFillTask implements Runnable
|
|||||||
*
|
*
|
||||||
* @return Number of chunks processed.
|
* @return Number of chunks processed.
|
||||||
*/
|
*/
|
||||||
public int getChunksCompleted()
|
public int getChunksCompleted() {
|
||||||
{
|
|
||||||
return reportTotal;
|
return reportTotal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,17 +530,14 @@ public class WorldFillTask implements Runnable
|
|||||||
*
|
*
|
||||||
* @return Number of chunks that need to be processed.
|
* @return Number of chunks that need to be processed.
|
||||||
*/
|
*/
|
||||||
public int getChunksTotal()
|
public int getChunksTotal() {
|
||||||
{
|
|
||||||
return reportTarget;
|
return reportTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompletableFuture<Void> getPaperLibChunk(World world, int x, int z, boolean gen)
|
private CompletableFuture<Void> getPaperLibChunk(World world, int x, int z, boolean gen) {
|
||||||
{
|
|
||||||
return PaperLib.getChunkAtAsync(world, x, z, gen).thenAccept((Chunk chunk) ->
|
return PaperLib.getChunkAtAsync(world, x, z, gen).thenAccept((Chunk chunk) ->
|
||||||
{
|
{
|
||||||
if (chunk != null)
|
if (chunk != null) {
|
||||||
{
|
|
||||||
// toggle "force loaded" flag on for chunk to prevent it from being unloaded while we need it
|
// toggle "force loaded" flag on for chunk to prevent it from being unloaded while we need it
|
||||||
world.setChunkForceLoaded(x, z, true);
|
world.setChunkForceLoaded(x, z, true);
|
||||||
|
|
||||||
@ -638,4 +546,37 @@ public class WorldFillTask implements Runnable
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class UnloadDependency {
|
||||||
|
int neededX, neededZ;
|
||||||
|
int forX, forZ;
|
||||||
|
|
||||||
|
UnloadDependency(int neededX, int neededZ, int forX, int forZ) {
|
||||||
|
this.neededX = neededX;
|
||||||
|
this.neededZ = neededZ;
|
||||||
|
this.forX = forX;
|
||||||
|
this.forZ = forZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (other == null || !(other instanceof UnloadDependency))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return this.neededX == ((UnloadDependency) other).neededX
|
||||||
|
&& this.neededZ == ((UnloadDependency) other).neededZ
|
||||||
|
&& this.forX == ((UnloadDependency) other).forX
|
||||||
|
&& this.forZ == ((UnloadDependency) other).forZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 7;
|
||||||
|
hash = 79 * hash + this.neededX;
|
||||||
|
hash = 79 * hash + this.neededZ;
|
||||||
|
hash = 79 * hash + this.forX;
|
||||||
|
hash = 79 * hash + this.forZ;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
package com.wimbli.WorldBorder;
|
package com.wimbli.WorldBorder;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Events.WorldBorderTrimFinishedEvent;
|
||||||
|
import com.wimbli.WorldBorder.Events.WorldBorderTrimStartEvent;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Server;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -7,17 +14,8 @@ import java.io.RandomAccessFile;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.Server;
|
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.Events.WorldBorderTrimFinishedEvent;
|
public class WorldTrimTask implements Runnable {
|
||||||
import com.wimbli.WorldBorder.Events.WorldBorderTrimStartEvent;
|
|
||||||
|
|
||||||
|
|
||||||
public class WorldTrimTask implements Runnable
|
|
||||||
{
|
|
||||||
// general task-related reference data
|
// general task-related reference data
|
||||||
private transient Server server = null;
|
private transient Server server = null;
|
||||||
private transient World world = null;
|
private transient World world = null;
|
||||||
@ -46,15 +44,13 @@ public class WorldTrimTask implements Runnable
|
|||||||
private transient int reportTrimmedChunks = 0;
|
private transient int reportTrimmedChunks = 0;
|
||||||
|
|
||||||
|
|
||||||
public WorldTrimTask(Server theServer, Player player, String worldName, int trimDistance, int chunksPerRun)
|
public WorldTrimTask(Server theServer, Player player, String worldName, int trimDistance, int chunksPerRun) {
|
||||||
{
|
|
||||||
this.server = theServer;
|
this.server = theServer;
|
||||||
this.notifyPlayer = player;
|
this.notifyPlayer = player;
|
||||||
this.chunksPerRun = chunksPerRun;
|
this.chunksPerRun = chunksPerRun;
|
||||||
|
|
||||||
this.world = server.getWorld(worldName);
|
this.world = server.getWorld(worldName);
|
||||||
if (this.world == null)
|
if (this.world == null) {
|
||||||
{
|
|
||||||
if (worldName.isEmpty())
|
if (worldName.isEmpty())
|
||||||
sendMessage("You must specify a world!");
|
sendMessage("You must specify a world!");
|
||||||
else
|
else
|
||||||
@ -64,8 +60,7 @@ public class WorldTrimTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.border = (Config.Border(worldName) == null) ? null : Config.Border(worldName).copy();
|
this.border = (Config.Border(worldName) == null) ? null : Config.Border(worldName).copy();
|
||||||
if (this.border == null)
|
if (this.border == null) {
|
||||||
{
|
|
||||||
sendMessage("No border found for world \"" + worldName + "\"!");
|
sendMessage("No border found for world \"" + worldName + "\"!");
|
||||||
this.stop();
|
this.stop();
|
||||||
return;
|
return;
|
||||||
@ -75,8 +70,7 @@ public class WorldTrimTask implements Runnable
|
|||||||
this.border.setRadiusZ(border.getRadiusZ() + trimDistance);
|
this.border.setRadiusZ(border.getRadiusZ() + trimDistance);
|
||||||
|
|
||||||
worldData = WorldFileData.create(world, notifyPlayer);
|
worldData = WorldFileData.create(world, notifyPlayer);
|
||||||
if (worldData == null)
|
if (worldData == null) {
|
||||||
{
|
|
||||||
this.stop();
|
this.stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -92,14 +86,12 @@ public class WorldTrimTask implements Runnable
|
|||||||
Bukkit.getServer().getPluginManager().callEvent(new WorldBorderTrimStartEvent(this));
|
Bukkit.getServer().getPluginManager().callEvent(new WorldBorderTrimStartEvent(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTaskID(int ID)
|
public void setTaskID(int ID) {
|
||||||
{
|
|
||||||
this.taskID = ID;
|
this.taskID = ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void run()
|
public void run() {
|
||||||
{
|
|
||||||
if (server == null || !readyToGo || paused)
|
if (server == null || !readyToGo || paused)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -109,8 +101,7 @@ public class WorldTrimTask implements Runnable
|
|||||||
long loopStartTime = Config.Now();
|
long loopStartTime = Config.Now();
|
||||||
|
|
||||||
counter = 0;
|
counter = 0;
|
||||||
while (counter <= chunksPerRun)
|
while (counter <= chunksPerRun) {
|
||||||
{
|
|
||||||
// in case the task has been paused while we're repeating...
|
// in case the task has been paused while we're repeating...
|
||||||
if (paused)
|
if (paused)
|
||||||
return;
|
return;
|
||||||
@ -122,48 +113,38 @@ public class WorldTrimTask implements Runnable
|
|||||||
reportProgress();
|
reportProgress();
|
||||||
|
|
||||||
// if this iteration has been running for 45ms (almost 1 tick) or more, stop to take a breather; shouldn't normally be possible with Trim, but just in case
|
// if this iteration has been running for 45ms (almost 1 tick) or more, stop to take a breather; shouldn't normally be possible with Trim, but just in case
|
||||||
if (now > loopStartTime + 45)
|
if (now > loopStartTime + 45) {
|
||||||
{
|
|
||||||
readyToGo = true;
|
readyToGo = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regionChunks.isEmpty())
|
if (regionChunks.isEmpty())
|
||||||
addCornerChunks();
|
addCornerChunks();
|
||||||
else if (currentChunk == 4)
|
else if (currentChunk == 4) { // determine if region is completely _inside_ border based on corner chunks
|
||||||
{ // determine if region is completely _inside_ border based on corner chunks
|
if (trimChunks.isEmpty()) { // it is, so skip it and move on to next file
|
||||||
if (trimChunks.isEmpty())
|
|
||||||
{ // it is, so skip it and move on to next file
|
|
||||||
counter += 4;
|
counter += 4;
|
||||||
nextFile();
|
nextFile();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
addEdgeChunks();
|
addEdgeChunks();
|
||||||
addInnerChunks();
|
addInnerChunks();
|
||||||
}
|
} else if (currentChunk == 124 && trimChunks.size() == 124) { // region is completely _outside_ border based on edge chunks, so delete file and move on to next
|
||||||
else if (currentChunk == 124 && trimChunks.size() == 124)
|
|
||||||
{ // region is completely _outside_ border based on edge chunks, so delete file and move on to next
|
|
||||||
counter += 16;
|
counter += 16;
|
||||||
trimChunks = regionChunks;
|
trimChunks = regionChunks;
|
||||||
unloadChunks();
|
unloadChunks();
|
||||||
reportTrimmedRegions++;
|
reportTrimmedRegions++;
|
||||||
File regionFile = worldData.regionFile(currentRegion);
|
File regionFile = worldData.regionFile(currentRegion);
|
||||||
if (!regionFile.delete())
|
if (!regionFile.delete()) {
|
||||||
{
|
|
||||||
sendMessage("Error! Region file which is outside the border could not be deleted: " + regionFile.getName());
|
sendMessage("Error! Region file which is outside the border could not be deleted: " + regionFile.getName());
|
||||||
wipeChunks();
|
wipeChunks();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// if DynMap is installed, re-render the trimmed region ... disabled since it's not currently working, oh well
|
// 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));
|
// DynMapFeatures.renderRegion(world.getName(), new CoordXZ(regionX, regionZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
nextFile();
|
nextFile();
|
||||||
continue;
|
continue;
|
||||||
}
|
} else if (currentChunk == 1024) { // last chunk of the region has been checked, time to wipe out whichever chunks are outside the border
|
||||||
else if (currentChunk == 1024)
|
|
||||||
{ // last chunk of the region has been checked, time to wipe out whichever chunks are outside the border
|
|
||||||
counter += 32;
|
counter += 32;
|
||||||
unloadChunks();
|
unloadChunks();
|
||||||
wipeChunks();
|
wipeChunks();
|
||||||
@ -187,8 +168,7 @@ public class WorldTrimTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Advance to the next region file. Returns true if successful, false if the next file isn't accessible for any reason
|
// Advance to the next region file. Returns true if successful, false if the next file isn't accessible for any reason
|
||||||
private boolean nextFile()
|
private boolean nextFile() {
|
||||||
{
|
|
||||||
reportTotal = currentRegion * 3072;
|
reportTotal = currentRegion * 3072;
|
||||||
currentRegion++;
|
currentRegion++;
|
||||||
regionX = regionZ = currentChunk = 0;
|
regionX = regionZ = currentChunk = 0;
|
||||||
@ -196,8 +176,7 @@ public class WorldTrimTask implements Runnable
|
|||||||
trimChunks = new ArrayList<CoordXZ>(1024);
|
trimChunks = new ArrayList<CoordXZ>(1024);
|
||||||
|
|
||||||
// have we already handled all region files?
|
// have we already handled all region files?
|
||||||
if (currentRegion >= worldData.regionFileCount())
|
if (currentRegion >= worldData.regionFileCount()) { // hey, we're done
|
||||||
{ // hey, we're done
|
|
||||||
paused = true;
|
paused = true;
|
||||||
readyToGo = false;
|
readyToGo = false;
|
||||||
finish();
|
finish();
|
||||||
@ -217,8 +196,7 @@ public class WorldTrimTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add just the 4 corner chunks of the region; can determine if entire region is _inside_ the border
|
// add just the 4 corner chunks of the region; can determine if entire region is _inside_ the border
|
||||||
private void addCornerChunks()
|
private void addCornerChunks() {
|
||||||
{
|
|
||||||
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX), CoordXZ.regionToChunk(regionZ)));
|
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX), CoordXZ.regionToChunk(regionZ)));
|
||||||
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX) + 31, CoordXZ.regionToChunk(regionZ)));
|
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX) + 31, CoordXZ.regionToChunk(regionZ)));
|
||||||
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX), CoordXZ.regionToChunk(regionZ) + 31));
|
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX), CoordXZ.regionToChunk(regionZ) + 31));
|
||||||
@ -226,39 +204,31 @@ public class WorldTrimTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add all chunks along the 4 edges of the region (minus the corners); can determine if entire region is _outside_ the border
|
// add all chunks along the 4 edges of the region (minus the corners); can determine if entire region is _outside_ the border
|
||||||
private void addEdgeChunks()
|
private void addEdgeChunks() {
|
||||||
{
|
|
||||||
int chunkX = 0, chunkZ;
|
int chunkX = 0, chunkZ;
|
||||||
|
|
||||||
for (chunkZ = 1; chunkZ < 31; chunkZ++)
|
for (chunkZ = 1; chunkZ < 31; chunkZ++) {
|
||||||
{
|
|
||||||
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX) + chunkX, CoordXZ.regionToChunk(regionZ) + chunkZ));
|
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX) + chunkX, CoordXZ.regionToChunk(regionZ) + chunkZ));
|
||||||
}
|
}
|
||||||
chunkX = 31;
|
chunkX = 31;
|
||||||
for (chunkZ = 1; chunkZ < 31; chunkZ++)
|
for (chunkZ = 1; chunkZ < 31; chunkZ++) {
|
||||||
{
|
|
||||||
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX) + chunkX, CoordXZ.regionToChunk(regionZ) + chunkZ));
|
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX) + chunkX, CoordXZ.regionToChunk(regionZ) + chunkZ));
|
||||||
}
|
}
|
||||||
chunkZ = 0;
|
chunkZ = 0;
|
||||||
for (chunkX = 1; chunkX < 31; chunkX++)
|
for (chunkX = 1; chunkX < 31; chunkX++) {
|
||||||
{
|
|
||||||
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX) + chunkX, CoordXZ.regionToChunk(regionZ) + chunkZ));
|
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX) + chunkX, CoordXZ.regionToChunk(regionZ) + chunkZ));
|
||||||
}
|
}
|
||||||
chunkZ = 31;
|
chunkZ = 31;
|
||||||
for (chunkX = 1; chunkX < 31; chunkX++)
|
for (chunkX = 1; chunkX < 31; chunkX++) {
|
||||||
{
|
|
||||||
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX) + chunkX, CoordXZ.regionToChunk(regionZ) + chunkZ));
|
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX) + chunkX, CoordXZ.regionToChunk(regionZ) + chunkZ));
|
||||||
}
|
}
|
||||||
counter += 4;
|
counter += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the remaining interior chunks (after corners and edges)
|
// add the remaining interior chunks (after corners and edges)
|
||||||
private void addInnerChunks()
|
private void addInnerChunks() {
|
||||||
{
|
for (int chunkX = 1; chunkX < 31; chunkX++) {
|
||||||
for (int chunkX = 1; chunkX < 31; chunkX++)
|
for (int chunkZ = 1; chunkZ < 31; chunkZ++) {
|
||||||
{
|
|
||||||
for (int chunkZ = 1; chunkZ < 31; chunkZ++)
|
|
||||||
{
|
|
||||||
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX) + chunkX, CoordXZ.regionToChunk(regionZ) + chunkZ));
|
regionChunks.add(new CoordXZ(CoordXZ.regionToChunk(regionX) + chunkX, CoordXZ.regionToChunk(regionZ) + chunkZ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -266,10 +236,8 @@ public class WorldTrimTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make sure chunks set to be trimmed are not currently loaded by the server
|
// make sure chunks set to be trimmed are not currently loaded by the server
|
||||||
private void unloadChunks()
|
private void unloadChunks() {
|
||||||
{
|
for (CoordXZ unload : trimChunks) {
|
||||||
for (CoordXZ unload : trimChunks)
|
|
||||||
{
|
|
||||||
if (world.isChunkLoaded(unload.x, unload.z))
|
if (world.isChunkLoaded(unload.x, unload.z))
|
||||||
world.unloadChunk(unload.x, unload.z, false);
|
world.unloadChunk(unload.x, unload.z, false);
|
||||||
}
|
}
|
||||||
@ -277,16 +245,13 @@ public class WorldTrimTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// edit region file to wipe all chunk pointers for chunks outside the border
|
// edit region file to wipe all chunk pointers for chunks outside the border
|
||||||
private void wipeChunks()
|
private void wipeChunks() {
|
||||||
{
|
|
||||||
File regionFile = worldData.regionFile(currentRegion);
|
File regionFile = worldData.regionFile(currentRegion);
|
||||||
if (!regionFile.canWrite())
|
if (!regionFile.canWrite()) {
|
||||||
{
|
|
||||||
if (!regionFile.setWritable(true))
|
if (!regionFile.setWritable(true))
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
|
|
||||||
if (!regionFile.canWrite())
|
if (!regionFile.canWrite()) {
|
||||||
{
|
|
||||||
sendMessage("Error! region file is locked and can't be trimmed: " + regionFile.getName());
|
sendMessage("Error! region file is locked and can't be trimmed: " + regionFile.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -298,11 +263,9 @@ public class WorldTrimTask implements Runnable
|
|||||||
long wipePos = 0;
|
long wipePos = 0;
|
||||||
int chunkCount = 0;
|
int chunkCount = 0;
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
RandomAccessFile unChunk = new RandomAccessFile(regionFile, "rwd");
|
RandomAccessFile unChunk = new RandomAccessFile(regionFile, "rwd");
|
||||||
for (CoordXZ wipe : trimChunks)
|
for (CoordXZ wipe : trimChunks) {
|
||||||
{
|
|
||||||
// if the chunk pointer is empty (chunk doesn't technically exist), no need to wipe the already empty pointer
|
// if the chunk pointer is empty (chunk doesn't technically exist), no need to wipe the already empty pointer
|
||||||
if (!worldData.doesChunkExist(wipe.x, wipe.z))
|
if (!worldData.doesChunkExist(wipe.x, wipe.z))
|
||||||
continue;
|
continue;
|
||||||
@ -320,26 +283,20 @@ public class WorldTrimTask implements Runnable
|
|||||||
// DynMapFeatures.renderChunks(world.getName(), trimChunks);
|
// DynMapFeatures.renderChunks(world.getName(), trimChunks);
|
||||||
|
|
||||||
reportTrimmedChunks += chunkCount;
|
reportTrimmedChunks += chunkCount;
|
||||||
}
|
} catch (FileNotFoundException ex) {
|
||||||
catch (FileNotFoundException ex)
|
|
||||||
{
|
|
||||||
sendMessage("Error! Could not open region file to wipe individual chunks: " + regionFile.getName());
|
sendMessage("Error! Could not open region file to wipe individual chunks: " + regionFile.getName());
|
||||||
}
|
} catch (IOException ex) {
|
||||||
catch (IOException ex)
|
|
||||||
{
|
|
||||||
sendMessage("Error! Could not modify region file to wipe individual chunks: " + regionFile.getName());
|
sendMessage("Error! Could not modify region file to wipe individual chunks: " + regionFile.getName());
|
||||||
}
|
}
|
||||||
counter += trimChunks.size();
|
counter += trimChunks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isChunkInsideBorder(CoordXZ chunk)
|
private boolean isChunkInsideBorder(CoordXZ chunk) {
|
||||||
{
|
|
||||||
return border.insideBorder(CoordXZ.chunkToBlock(chunk.x) + 8, CoordXZ.chunkToBlock(chunk.z) + 8);
|
return border.insideBorder(CoordXZ.chunkToBlock(chunk.x) + 8, CoordXZ.chunkToBlock(chunk.z) + 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for successful completion
|
// for successful completion
|
||||||
public void finish()
|
public void finish() {
|
||||||
{
|
|
||||||
reportTotal = reportTarget;
|
reportTotal = reportTarget;
|
||||||
reportProgress();
|
reportProgress();
|
||||||
Bukkit.getServer().getPluginManager().callEvent(new WorldBorderTrimFinishedEvent(world, reportTotal));
|
Bukkit.getServer().getPluginManager().callEvent(new WorldBorderTrimFinishedEvent(world, reportTotal));
|
||||||
@ -348,14 +305,12 @@ public class WorldTrimTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for cancelling prematurely
|
// for cancelling prematurely
|
||||||
public void cancel()
|
public void cancel() {
|
||||||
{
|
|
||||||
this.stop();
|
this.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// we're done, whether finished or cancelled
|
// we're done, whether finished or cancelled
|
||||||
private void stop()
|
private void stop() {
|
||||||
{
|
|
||||||
if (server == null)
|
if (server == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -370,38 +325,34 @@ public class WorldTrimTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// is this task still valid/workable?
|
// is this task still valid/workable?
|
||||||
public boolean valid()
|
public boolean valid() {
|
||||||
{
|
|
||||||
return this.server != null;
|
return this.server != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle pausing/unpausing the task
|
// handle pausing/unpausing the task
|
||||||
public void pause()
|
public void pause() {
|
||||||
{
|
|
||||||
pause(!this.paused);
|
pause(!this.paused);
|
||||||
}
|
}
|
||||||
public void pause(boolean pause)
|
|
||||||
{
|
public void pause(boolean pause) {
|
||||||
this.paused = pause;
|
this.paused = pause;
|
||||||
if (pause)
|
if (pause)
|
||||||
reportProgress();
|
reportProgress();
|
||||||
}
|
}
|
||||||
public boolean isPaused()
|
|
||||||
{
|
public boolean isPaused() {
|
||||||
return this.paused;
|
return this.paused;
|
||||||
}
|
}
|
||||||
|
|
||||||
// let the user know how things are coming along
|
// let the user know how things are coming along
|
||||||
private void reportProgress()
|
private void reportProgress() {
|
||||||
{
|
|
||||||
lastReport = Config.Now();
|
lastReport = Config.Now();
|
||||||
double perc = getPercentageCompleted();
|
double perc = getPercentageCompleted();
|
||||||
sendMessage(reportTrimmedRegions + " entire region(s) and " + reportTrimmedChunks + " individual chunk(s) trimmed so far (" + Config.coord.format(perc) + "% done" + ")");
|
sendMessage(reportTrimmedRegions + " entire region(s) and " + reportTrimmedChunks + " individual chunk(s) trimmed so far (" + Config.coord.format(perc) + "% done" + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
// send a message to the server console/log and possibly to an in-game player
|
// send a message to the server console/log and possibly to an in-game player
|
||||||
private void sendMessage(String text)
|
private void sendMessage(String text) {
|
||||||
{
|
|
||||||
Config.log("[Trim] " + text);
|
Config.log("[Trim] " + text);
|
||||||
if (notifyPlayer != null)
|
if (notifyPlayer != null)
|
||||||
notifyPlayer.sendMessage("[Trim] " + text);
|
notifyPlayer.sendMessage("[Trim] " + text);
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import com.wimbli.WorldBorder.UUID.UUIDFetcher;
|
||||||
|
import com.wimbli.WorldBorder.WorldBorder;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdBypass extends WBCmd {
|
||||||
import com.wimbli.WorldBorder.UUID.UUIDFetcher;
|
public CmdBypass() {
|
||||||
|
|
||||||
|
|
||||||
public class CmdBypass extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdBypass()
|
|
||||||
{
|
|
||||||
name = permission = "bypass";
|
name = permission = "bypass";
|
||||||
minParams = 0;
|
minParams = 0;
|
||||||
maxParams = 2;
|
maxParams = 2;
|
||||||
@ -27,8 +25,7 @@ public class CmdBypass extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
if (!(sender instanceof Player))
|
if (!(sender instanceof Player))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -37,45 +34,33 @@ public class CmdBypass extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(final CommandSender sender, final Player player, final List<String> params, String worldName)
|
public void execute(final CommandSender sender, final Player player, final List<String> params, String worldName) {
|
||||||
{
|
if (player == null && params.isEmpty()) {
|
||||||
if (player == null && params.isEmpty())
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "When running this command from console, you must specify a player.");
|
sendErrorAndHelp(sender, "When running this command from console, you must specify a player.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(WorldBorder.plugin, new Runnable()
|
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(WorldBorder.plugin, new Runnable() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run() {
|
||||||
{
|
|
||||||
final String sPlayer = (params.isEmpty()) ? player.getName() : params.get(0);
|
final String sPlayer = (params.isEmpty()) ? player.getName() : params.get(0);
|
||||||
UUID uPlayer = (params.isEmpty()) ? player.getUniqueId() : null;
|
UUID uPlayer = (params.isEmpty()) ? player.getUniqueId() : null;
|
||||||
|
|
||||||
if (uPlayer == null)
|
if (uPlayer == null) {
|
||||||
{
|
|
||||||
Player p = Bukkit.getPlayer(sPlayer);
|
Player p = Bukkit.getPlayer(sPlayer);
|
||||||
if (p != null)
|
if (p != null) {
|
||||||
{
|
|
||||||
uPlayer = p.getUniqueId();
|
uPlayer = p.getUniqueId();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// only do UUID lookup using Mojang server if specified player isn't online
|
// only do UUID lookup using Mojang server if specified player isn't online
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
uPlayer = UUIDFetcher.getUUID(sPlayer);
|
uPlayer = UUIDFetcher.getUUID(sPlayer);
|
||||||
}
|
} catch (Exception ex) {
|
||||||
catch(Exception ex)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "Failed to look up UUID for the player name you specified. " + ex.getLocalizedMessage());
|
sendErrorAndHelp(sender, "Failed to look up UUID for the player name you specified. " + ex.getLocalizedMessage());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (uPlayer == null)
|
if (uPlayer == null) {
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "Failed to look up UUID for the player name you specified; null value returned.");
|
sendErrorAndHelp(sender, "Failed to look up UUID for the player name you specified; null value returned.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,20 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import com.wimbli.WorldBorder.UUID.UUIDFetcher;
|
||||||
|
import com.wimbli.WorldBorder.WorldBorder;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdBypasslist extends WBCmd {
|
||||||
import com.wimbli.WorldBorder.UUID.UUIDFetcher;
|
public CmdBypasslist() {
|
||||||
|
|
||||||
|
|
||||||
public class CmdBypasslist extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdBypasslist()
|
|
||||||
{
|
|
||||||
name = permission = "bypasslist";
|
name = permission = "bypasslist";
|
||||||
minParams = maxParams = 0;
|
minParams = maxParams = 0;
|
||||||
|
|
||||||
@ -26,29 +24,22 @@ public class CmdBypasslist extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(final CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(final CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
final ArrayList<UUID> uuids = Config.getPlayerBypassList();
|
final ArrayList<UUID> uuids = Config.getPlayerBypassList();
|
||||||
if (uuids == null || uuids.isEmpty())
|
if (uuids == null || uuids.isEmpty()) {
|
||||||
{
|
|
||||||
sender.sendMessage("Players with border bypass enabled: <none>");
|
sender.sendMessage("Players with border bypass enabled: <none>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(WorldBorder.plugin, new Runnable()
|
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(WorldBorder.plugin, new Runnable() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run() {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
Map<UUID, String> names = UUIDFetcher.getNameList(uuids);
|
Map<UUID, String> names = UUIDFetcher.getNameList(uuids);
|
||||||
String nameString = names.values().toString();
|
String nameString = names.values().toString();
|
||||||
|
|
||||||
sender.sendMessage("Players with border bypass enabled: " + nameString.substring(1, nameString.length() - 1));
|
sender.sendMessage("Players with border bypass enabled: " + nameString.substring(1, nameString.length() - 1));
|
||||||
}
|
} catch (Exception ex) {
|
||||||
catch(Exception ex)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "Failed to look up names for the UUIDs in the border bypass list. " + ex.getLocalizedMessage());
|
sendErrorAndHelp(sender, "Failed to look up names for the UUIDs in the border bypass list. " + ex.getLocalizedMessage());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.BorderData;
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdClear extends WBCmd {
|
||||||
|
public CmdClear() {
|
||||||
|
|
||||||
public class CmdClear extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdClear()
|
|
||||||
{
|
|
||||||
name = permission = "clear";
|
name = permission = "clear";
|
||||||
hasWorldNameInput = true;
|
hasWorldNameInput = true;
|
||||||
consoleRequiresWorldName = false;
|
consoleRequiresWorldName = false;
|
||||||
@ -25,13 +23,10 @@ public class CmdClear extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
// handle "clear all" command separately
|
// handle "clear all" command separately
|
||||||
if (params.size() == 1 && params.get(0).equalsIgnoreCase("all"))
|
if (params.size() == 1 && params.get(0).equalsIgnoreCase("all")) {
|
||||||
{
|
if (worldName != null) {
|
||||||
if (worldName != null)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "You should not specify a world with \"clear all\".");
|
sendErrorAndHelp(sender, "You should not specify a world with \"clear all\".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -43,10 +38,8 @@ public class CmdClear extends WBCmd
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (worldName == null)
|
if (worldName == null) {
|
||||||
{
|
if (player == null) {
|
||||||
if (player == null)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "You must specify a world name from console if not using \"clear all\".");
|
sendErrorAndHelp(sender, "You must specify a world name from console if not using \"clear all\".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -54,8 +47,7 @@ public class CmdClear extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
BorderData border = Config.Border(worldName);
|
BorderData border = Config.Border(worldName);
|
||||||
if (border == null)
|
if (border == null) {
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "This world (\"" + worldName + "\") does not have a border set.");
|
sendErrorAndHelp(sender, "This world (\"" + worldName + "\") does not have a border set.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,30 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.WorldBorder;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdCommands extends WBCmd {
|
||||||
|
|
||||||
|
|
||||||
public class CmdCommands extends WBCmd
|
|
||||||
{
|
|
||||||
private static int pageSize = 8; // examples to list per page; 10 lines available, 1 for header, 1 for footer
|
private static int pageSize = 8; // examples to list per page; 10 lines available, 1 for header, 1 for footer
|
||||||
|
|
||||||
public CmdCommands()
|
public CmdCommands() {
|
||||||
{
|
|
||||||
name = "commands";
|
name = "commands";
|
||||||
permission = "help";
|
permission = "help";
|
||||||
hasWorldNameInput = false;
|
hasWorldNameInput = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
// determine which page we're viewing
|
// determine which page we're viewing
|
||||||
int page = (player == null) ? 0 : 1;
|
int page = (player == null) ? 0 : 1;
|
||||||
if (!params.isEmpty())
|
if (!params.isEmpty()) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
page = Integer.parseInt(params.get(0));
|
page = Integer.parseInt(params.get(0));
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
}
|
}
|
||||||
catch(NumberFormatException ignored) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// see whether we're showing examples to player or to console, and determine number of pages available
|
// see whether we're showing examples to player or to console, and determine number of pages available
|
||||||
@ -45,13 +39,11 @@ public class CmdCommands extends WBCmd
|
|||||||
sender.sendMessage(C_HEAD + WorldBorder.plugin.getDescription().getFullName() + " - key: " +
|
sender.sendMessage(C_HEAD + WorldBorder.plugin.getDescription().getFullName() + " - key: " +
|
||||||
commandEmphasized("command") + C_REQ + "<required> " + C_OPT + "[optional]");
|
commandEmphasized("command") + C_REQ + "<required> " + C_OPT + "[optional]");
|
||||||
|
|
||||||
if (page > 0)
|
if (page > 0) {
|
||||||
{
|
|
||||||
// send examples for this page
|
// send examples for this page
|
||||||
int first = ((page - 1) * pageSize);
|
int first = ((page - 1) * pageSize);
|
||||||
int count = Math.min(pageSize, examples.size() - first);
|
int count = Math.min(pageSize, examples.size() - first);
|
||||||
for(int i = first; i < first + count; i++)
|
for (int i = first; i < first + count; i++) {
|
||||||
{
|
|
||||||
sender.sendMessage(examples.get(i));
|
sender.sendMessage(examples.get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,12 +53,9 @@ public class CmdCommands extends WBCmd
|
|||||||
sender.sendMessage(footer + Integer.toString(page + 1) + C_DESC + " - view next page of commands.");
|
sender.sendMessage(footer + Integer.toString(page + 1) + C_DESC + " - view next page of commands.");
|
||||||
else if (page > 1)
|
else if (page > 1)
|
||||||
sender.sendMessage(footer + C_DESC + "- view first page of commands.");
|
sender.sendMessage(footer + C_DESC + "- view first page of commands.");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// if page "0" is specified, send all examples; done by default for console but can be specified by player
|
// if page "0" is specified, send all examples; done by default for console but can be specified by player
|
||||||
for (String example : examples)
|
for (String example : examples) {
|
||||||
{
|
|
||||||
sender.sendMessage(example);
|
sender.sendMessage(example);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdDebug extends WBCmd {
|
||||||
|
public CmdDebug() {
|
||||||
|
|
||||||
public class CmdDebug extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdDebug()
|
|
||||||
{
|
|
||||||
name = permission = "debug";
|
name = permission = "debug";
|
||||||
minParams = maxParams = 1;
|
minParams = maxParams = 1;
|
||||||
|
|
||||||
@ -21,18 +18,15 @@ public class CmdDebug extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
sender.sendMessage(C_HEAD + "Debug mode is " + enabledColored(Config.Debug()) + C_HEAD + ".");
|
sender.sendMessage(C_HEAD + "Debug mode is " + enabledColored(Config.Debug()) + C_HEAD + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
Config.setDebug(strAsBool(params.get(0)));
|
Config.setDebug(strAsBool(params.get(0)));
|
||||||
|
|
||||||
if (player != null)
|
if (player != null) {
|
||||||
{
|
|
||||||
Config.log((Config.Debug() ? "Enabled" : "Disabled") + " debug output at the command of player \"" + player.getName() + "\".");
|
Config.log((Config.Debug() ? "Enabled" : "Disabled") + " debug output at the command of player \"" + player.getName() + "\".");
|
||||||
cmdStatus(sender);
|
cmdStatus(sender);
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdDelay extends WBCmd {
|
||||||
|
public CmdDelay() {
|
||||||
|
|
||||||
public class CmdDelay extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdDelay()
|
|
||||||
{
|
|
||||||
name = permission = "delay";
|
name = permission = "delay";
|
||||||
minParams = maxParams = 1;
|
minParams = maxParams = 1;
|
||||||
|
|
||||||
@ -21,24 +18,19 @@ public class CmdDelay extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
int delay = Config.TimerTicks();
|
int delay = Config.TimerTicks();
|
||||||
sender.sendMessage(C_HEAD + "Timer delay is set to " + delay + " tick(s). That is roughly " + (delay * 50) + "ms.");
|
sender.sendMessage(C_HEAD + "Timer delay is set to " + delay + " tick(s). That is roughly " + (delay * 50) + "ms.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
int delay = 0;
|
int delay = 0;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
delay = Integer.parseInt(params.get(0));
|
delay = Integer.parseInt(params.get(0));
|
||||||
if (delay < 1)
|
if (delay < 1)
|
||||||
throw new NumberFormatException();
|
throw new NumberFormatException();
|
||||||
}
|
} catch (NumberFormatException ex) {
|
||||||
catch(NumberFormatException ex)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "The timer delay must be an integer of 1 or higher.");
|
sendErrorAndHelp(sender, "The timer delay must be an integer of 1 or higher.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdDenypearl extends WBCmd {
|
||||||
|
public CmdDenypearl() {
|
||||||
|
|
||||||
public class CmdDenypearl extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdDenypearl()
|
|
||||||
{
|
|
||||||
name = permission = "denypearl";
|
name = permission = "denypearl";
|
||||||
minParams = maxParams = 1;
|
minParams = maxParams = 1;
|
||||||
|
|
||||||
@ -22,19 +19,16 @@ public class CmdDenypearl extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
sender.sendMessage(C_HEAD + "Direct cancellation of ender pearls thrown past the border is " +
|
sender.sendMessage(C_HEAD + "Direct cancellation of ender pearls thrown past the border is " +
|
||||||
enabledColored(Config.getDenyEnderpearl()) + C_HEAD + ".");
|
enabledColored(Config.getDenyEnderpearl()) + C_HEAD + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
Config.setDenyEnderpearl(strAsBool(params.get(0)));
|
Config.setDenyEnderpearl(strAsBool(params.get(0)));
|
||||||
|
|
||||||
if (player != null)
|
if (player != null) {
|
||||||
{
|
|
||||||
Config.log((Config.getDenyEnderpearl() ? "Enabled" : "Disabled") + " direct cancellation of ender pearls thrown past the border at the command of player \"" + player.getName() + "\".");
|
Config.log((Config.getDenyEnderpearl() ? "Enabled" : "Disabled") + " direct cancellation of ender pearls thrown past the border at the command of player \"" + player.getName() + "\".");
|
||||||
cmdStatus(sender);
|
cmdStatus(sender);
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdDynmap extends WBCmd {
|
||||||
|
public CmdDynmap() {
|
||||||
|
|
||||||
public class CmdDynmap extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdDynmap()
|
|
||||||
{
|
|
||||||
name = permission = "dynmap";
|
name = permission = "dynmap";
|
||||||
minParams = maxParams = 1;
|
minParams = maxParams = 1;
|
||||||
|
|
||||||
@ -21,18 +18,15 @@ public class CmdDynmap extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
sender.sendMessage(C_HEAD + "DynMap border display is " + enabledColored(Config.DynmapBorderEnabled()) + C_HEAD + ".");
|
sender.sendMessage(C_HEAD + "DynMap border display is " + enabledColored(Config.DynmapBorderEnabled()) + C_HEAD + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
Config.setDynmapBorderEnabled(strAsBool(params.get(0)));
|
Config.setDynmapBorderEnabled(strAsBool(params.get(0)));
|
||||||
|
|
||||||
if (player != null)
|
if (player != null) {
|
||||||
{
|
|
||||||
cmdStatus(sender);
|
cmdStatus(sender);
|
||||||
Config.log((Config.DynmapBorderEnabled() ? "Enabled" : "Disabled") + " DynMap border display at the command of player \"" + player.getName() + "\".");
|
Config.log((Config.DynmapBorderEnabled() ? "Enabled" : "Disabled") + " DynMap border display at the command of player \"" + player.getName() + "\".");
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdDynmapmsg extends WBCmd {
|
||||||
|
public CmdDynmapmsg() {
|
||||||
|
|
||||||
public class CmdDynmapmsg extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdDynmapmsg()
|
|
||||||
{
|
|
||||||
name = permission = "dynmapmsg";
|
name = permission = "dynmapmsg";
|
||||||
minParams = 1;
|
minParams = 1;
|
||||||
|
|
||||||
@ -22,18 +19,15 @@ public class CmdDynmapmsg extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
sender.sendMessage(C_HEAD + "DynMap border label is set to: " + C_ERR + Config.DynmapMessage());
|
sender.sendMessage(C_HEAD + "DynMap border label is set to: " + C_ERR + Config.DynmapMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
StringBuilder message = new StringBuilder();
|
StringBuilder message = new StringBuilder();
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (String param : params)
|
for (String param : params) {
|
||||||
{
|
|
||||||
if (!first)
|
if (!first)
|
||||||
message.append(" ");
|
message.append(" ");
|
||||||
message.append(param);
|
message.append(param);
|
||||||
|
@ -1,18 +1,28 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import com.wimbli.WorldBorder.CoordXZ;
|
||||||
|
import com.wimbli.WorldBorder.WorldBorder;
|
||||||
|
import com.wimbli.WorldBorder.WorldFillTask;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdFill extends WBCmd {
|
||||||
|
/* with "view-distance=10" in server.properties on a fast VM test server and "Render Distance: Far" in client,
|
||||||
|
* hitting border during testing was loading 11+ chunks beyond the border in a couple of directions (10 chunks in
|
||||||
|
* the other two directions). This could be worse on a more loaded or worse server, so:
|
||||||
|
*/
|
||||||
|
private final int defaultPadding = CoordXZ.chunkToBlock(13);
|
||||||
|
private String fillWorld = "";
|
||||||
|
private int fillFrequency = 20;
|
||||||
|
private int fillPadding = defaultPadding;
|
||||||
|
private boolean fillForceLoad = false;
|
||||||
|
|
||||||
|
public CmdFill() {
|
||||||
public class CmdFill extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdFill()
|
|
||||||
{
|
|
||||||
name = permission = "fill";
|
name = permission = "fill";
|
||||||
hasWorldNameInput = true;
|
hasWorldNameInput = true;
|
||||||
consoleRequiresWorldName = false;
|
consoleRequiresWorldName = false;
|
||||||
@ -27,25 +37,20 @@ public class CmdFill extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
boolean confirm = false;
|
boolean confirm = false;
|
||||||
// check for "cancel", "pause", or "confirm"
|
// check for "cancel", "pause", or "confirm"
|
||||||
if (params.size() >= 1)
|
if (params.size() >= 1) {
|
||||||
{
|
|
||||||
String check = params.get(0).toLowerCase();
|
String check = params.get(0).toLowerCase();
|
||||||
|
|
||||||
if (check.equals("cancel") || check.equals("stop"))
|
if (check.equals("cancel") || check.equals("stop")) {
|
||||||
{
|
|
||||||
if (!makeSureFillIsRunning(sender))
|
if (!makeSureFillIsRunning(sender))
|
||||||
return;
|
return;
|
||||||
sender.sendMessage(C_HEAD + "Cancelling the world map generation task.");
|
sender.sendMessage(C_HEAD + "Cancelling the world map generation task.");
|
||||||
fillDefaults();
|
fillDefaults();
|
||||||
Config.StopFillTask();
|
Config.StopFillTask();
|
||||||
return;
|
return;
|
||||||
}
|
} else if (check.equals("pause")) {
|
||||||
else if (check.equals("pause"))
|
|
||||||
{
|
|
||||||
if (!makeSureFillIsRunning(sender))
|
if (!makeSureFillIsRunning(sender))
|
||||||
return;
|
return;
|
||||||
Config.fillTask.pause();
|
Config.fillTask.pause();
|
||||||
@ -57,12 +62,10 @@ public class CmdFill extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if not just confirming, make sure a world name is available
|
// if not just confirming, make sure a world name is available
|
||||||
if (worldName == null && !confirm)
|
if (worldName == null && !confirm) {
|
||||||
{
|
|
||||||
if (player != null)
|
if (player != null)
|
||||||
worldName = player.getWorld().getName();
|
worldName = player.getWorld().getName();
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "You must specify a world!");
|
sendErrorAndHelp(sender, "You must specify a world!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -72,29 +75,24 @@ public class CmdFill extends WBCmd
|
|||||||
String cmd = cmd(sender) + nameEmphasized() + C_CMD;
|
String cmd = cmd(sender) + nameEmphasized() + C_CMD;
|
||||||
|
|
||||||
// make sure Fill isn't already running
|
// make sure Fill isn't already running
|
||||||
if (Config.fillTask != null && Config.fillTask.valid())
|
if (Config.fillTask != null && Config.fillTask.valid()) {
|
||||||
{
|
|
||||||
sender.sendMessage(C_ERR + "The world map generation task is already running.");
|
sender.sendMessage(C_ERR + "The world map generation task is already running.");
|
||||||
sender.sendMessage(C_DESC + "You can cancel at any time with " + cmd + "cancel" + C_DESC + ", or pause/unpause with " + cmd + "pause" + C_DESC + ".");
|
sender.sendMessage(C_DESC + "You can cancel at any time with " + cmd + "cancel" + C_DESC + ", or pause/unpause with " + cmd + "pause" + C_DESC + ".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set frequency and/or padding if those were specified
|
// set frequency and/or padding if those were specified
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
if (params.size() >= 1 && !confirm)
|
if (params.size() >= 1 && !confirm)
|
||||||
fillFrequency = Math.abs(Integer.parseInt(params.get(0)));
|
fillFrequency = Math.abs(Integer.parseInt(params.get(0)));
|
||||||
if (params.size() >= 2 && !confirm)
|
if (params.size() >= 2 && !confirm)
|
||||||
fillPadding = Math.abs(Integer.parseInt(params.get(1)));
|
fillPadding = Math.abs(Integer.parseInt(params.get(1)));
|
||||||
}
|
} catch (NumberFormatException ex) {
|
||||||
catch(NumberFormatException ex)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "The frequency and padding values must be integers.");
|
sendErrorAndHelp(sender, "The frequency and padding values must be integers.");
|
||||||
fillDefaults();
|
fillDefaults();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fillFrequency <= 0)
|
if (fillFrequency <= 0) {
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "The frequency value must be greater than zero.");
|
sendErrorAndHelp(sender, "The frequency value must be greater than zero.");
|
||||||
fillDefaults();
|
fillDefaults();
|
||||||
return;
|
return;
|
||||||
@ -108,10 +106,8 @@ public class CmdFill extends WBCmd
|
|||||||
if (worldName != null)
|
if (worldName != null)
|
||||||
fillWorld = worldName;
|
fillWorld = worldName;
|
||||||
|
|
||||||
if (confirm)
|
if (confirm) { // command confirmed, go ahead with it
|
||||||
{ // command confirmed, go ahead with it
|
if (fillWorld.isEmpty()) {
|
||||||
if (fillWorld.isEmpty())
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "You must first use this command successfully without confirming.");
|
sendErrorAndHelp(sender, "You must first use this command successfully without confirming.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -125,23 +121,19 @@ public class CmdFill extends WBCmd
|
|||||||
else
|
else
|
||||||
ticks = 20 / fillFrequency;
|
ticks = 20 / fillFrequency;
|
||||||
|
|
||||||
/* */ Config.log("world: " + fillWorld + " padding: " + fillPadding + " repeats: " + repeats + " ticks: " + ticks);
|
/* */
|
||||||
|
Config.log("world: " + fillWorld + " padding: " + fillPadding + " repeats: " + repeats + " ticks: " + ticks);
|
||||||
Config.fillTask = new WorldFillTask(Bukkit.getServer(), player, fillWorld, fillPadding, repeats, ticks, fillForceLoad);
|
Config.fillTask = new WorldFillTask(Bukkit.getServer(), player, fillWorld, fillPadding, repeats, ticks, fillForceLoad);
|
||||||
if (Config.fillTask.valid())
|
if (Config.fillTask.valid()) {
|
||||||
{
|
|
||||||
int task = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(WorldBorder.plugin, Config.fillTask, ticks, ticks);
|
int task = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(WorldBorder.plugin, Config.fillTask, ticks, ticks);
|
||||||
Config.fillTask.setTaskID(task);
|
Config.fillTask.setTaskID(task);
|
||||||
sender.sendMessage("WorldBorder map generation task for world \"" + fillWorld + "\" started.");
|
sender.sendMessage("WorldBorder map generation task for world \"" + fillWorld + "\" started.");
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
sender.sendMessage(C_ERR + "The world map generation task failed to start.");
|
sender.sendMessage(C_ERR + "The world map generation task failed to start.");
|
||||||
|
|
||||||
fillDefaults();
|
fillDefaults();
|
||||||
}
|
} else {
|
||||||
else
|
if (fillWorld.isEmpty()) {
|
||||||
{
|
|
||||||
if (fillWorld.isEmpty())
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "You must first specify a valid world.");
|
sendErrorAndHelp(sender, "You must first specify a valid world.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -153,28 +145,14 @@ public class CmdFill extends WBCmd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fillDefaults() {
|
||||||
/* with "view-distance=10" in server.properties on a fast VM test server and "Render Distance: Far" in client,
|
|
||||||
* hitting border during testing was loading 11+ chunks beyond the border in a couple of directions (10 chunks in
|
|
||||||
* the other two directions). This could be worse on a more loaded or worse server, so:
|
|
||||||
*/
|
|
||||||
private final int defaultPadding = CoordXZ.chunkToBlock(13);
|
|
||||||
|
|
||||||
private String fillWorld = "";
|
|
||||||
private int fillFrequency = 20;
|
|
||||||
private int fillPadding = defaultPadding;
|
|
||||||
private boolean fillForceLoad = false;
|
|
||||||
|
|
||||||
private void fillDefaults()
|
|
||||||
{
|
|
||||||
fillWorld = "";
|
fillWorld = "";
|
||||||
fillFrequency = 20;
|
fillFrequency = 20;
|
||||||
fillPadding = defaultPadding;
|
fillPadding = defaultPadding;
|
||||||
fillForceLoad = false;
|
fillForceLoad = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean makeSureFillIsRunning(CommandSender sender)
|
private boolean makeSureFillIsRunning(CommandSender sender) {
|
||||||
{
|
|
||||||
if (Config.fillTask != null && Config.fillTask.valid())
|
if (Config.fillTask != null && Config.fillTask.valid())
|
||||||
return true;
|
return true;
|
||||||
sendErrorAndHelp(sender, "The world map generation task is not currently running.");
|
sendErrorAndHelp(sender, "The world map generation task is not currently running.");
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdFillautosave extends WBCmd {
|
||||||
|
public CmdFillautosave() {
|
||||||
|
|
||||||
public class CmdFillautosave extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdFillautosave()
|
|
||||||
{
|
|
||||||
name = permission = "fillautosave";
|
name = permission = "fillautosave";
|
||||||
minParams = maxParams = 1;
|
minParams = maxParams = 1;
|
||||||
|
|
||||||
@ -20,17 +17,13 @@ public class CmdFillautosave extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
int seconds = Config.FillAutosaveFrequency();
|
int seconds = Config.FillAutosaveFrequency();
|
||||||
if (seconds == 0)
|
if (seconds == 0) {
|
||||||
{
|
|
||||||
sender.sendMessage(C_HEAD + "World autosave frequency during Fill process is set to 0, disabling it.");
|
sender.sendMessage(C_HEAD + "World autosave frequency during Fill process is set to 0, disabling it.");
|
||||||
sender.sendMessage(C_HEAD + "Note that much progress can be lost this way if there is a bug or crash in " +
|
sender.sendMessage(C_HEAD + "Note that much progress can be lost this way if there is a bug or crash in " +
|
||||||
"the world generation process from Bukkit or any world generation plugin you use.");
|
"the world generation process from Bukkit or any world generation plugin you use.");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
sender.sendMessage(C_HEAD + "World autosave frequency during Fill process is set to " + seconds + " seconds (rounded to a multiple of 5).");
|
sender.sendMessage(C_HEAD + "World autosave frequency during Fill process is set to " + seconds + " seconds (rounded to a multiple of 5).");
|
||||||
sender.sendMessage(C_HEAD + "New chunks generated by the Fill process will be forcibly saved to disk " +
|
sender.sendMessage(C_HEAD + "New chunks generated by the Fill process will be forcibly saved to disk " +
|
||||||
"this often to prevent loss of progress due to bugs or crashes in the world generation process.");
|
"this often to prevent loss of progress due to bugs or crashes in the world generation process.");
|
||||||
@ -38,17 +31,13 @@ public class CmdFillautosave extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
int seconds = 0;
|
int seconds = 0;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
seconds = Integer.parseInt(params.get(0));
|
seconds = Integer.parseInt(params.get(0));
|
||||||
if (seconds < 0)
|
if (seconds < 0)
|
||||||
throw new NumberFormatException();
|
throw new NumberFormatException();
|
||||||
}
|
} catch (NumberFormatException ex) {
|
||||||
catch(NumberFormatException ex)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "The world autosave frequency must be an integer of 0 or higher. Setting to 0 will disable autosaving of the world during the Fill process.");
|
sendErrorAndHelp(sender, "The world autosave frequency must be an integer of 0 or higher. Setting to 0 will disable autosaving of the world during the Fill process.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdGetmsg extends WBCmd {
|
||||||
|
public CmdGetmsg() {
|
||||||
|
|
||||||
public class CmdGetmsg extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdGetmsg()
|
|
||||||
{
|
|
||||||
name = permission = "getmsg";
|
name = permission = "getmsg";
|
||||||
minParams = maxParams = 0;
|
minParams = maxParams = 0;
|
||||||
|
|
||||||
@ -20,8 +17,7 @@ public class CmdGetmsg extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
sender.sendMessage("Border message is currently set to:");
|
sender.sendMessage("Border message is currently set to:");
|
||||||
sender.sendMessage(Config.MessageRaw());
|
sender.sendMessage(Config.MessageRaw());
|
||||||
sender.sendMessage("Formatted border message:");
|
sender.sendMessage("Formatted border message:");
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.WorldBorder;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdHelp extends WBCmd {
|
||||||
|
public CmdHelp() {
|
||||||
|
|
||||||
public class CmdHelp extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdHelp()
|
|
||||||
{
|
|
||||||
name = permission = "help";
|
name = permission = "help";
|
||||||
minParams = 0;
|
minParams = 0;
|
||||||
maxParams = 10;
|
maxParams = 10;
|
||||||
@ -22,8 +19,7 @@ public class CmdHelp extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
String commands = WorldBorder.wbCommand.getCommandNames().toString().replace(", ", C_DESC + ", " + C_CMD);
|
String commands = WorldBorder.wbCommand.getCommandNames().toString().replace(", ", C_DESC + ", " + C_CMD);
|
||||||
sender.sendMessage(C_HEAD + "Commands: " + C_CMD + commands.substring(1, commands.length() - 1));
|
sender.sendMessage(C_HEAD + "Commands: " + C_CMD + commands.substring(1, commands.length() - 1));
|
||||||
sender.sendMessage("Example, for info on \"set\" command: " + cmd(sender) + nameEmphasized() + C_CMD + "set");
|
sender.sendMessage("Example, for info on \"set\" command: " + cmd(sender) + nameEmphasized() + C_CMD + "set");
|
||||||
@ -31,19 +27,15 @@ public class CmdHelp extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
if (params.isEmpty()) {
|
||||||
if (params.isEmpty())
|
|
||||||
{
|
|
||||||
sendCmdHelp(sender);
|
sendCmdHelp(sender);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> commands = WorldBorder.wbCommand.getCommandNames();
|
Set<String> commands = WorldBorder.wbCommand.getCommandNames();
|
||||||
for (String param : params)
|
for (String param : params) {
|
||||||
{
|
if (commands.contains(param.toLowerCase())) {
|
||||||
if (commands.contains(param.toLowerCase()))
|
|
||||||
{
|
|
||||||
WorldBorder.wbCommand.subCommands.get(param.toLowerCase()).sendCmdHelp(sender);
|
WorldBorder.wbCommand.subCommands.get(param.toLowerCase()).sendCmdHelp(sender);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdKnockback extends WBCmd {
|
||||||
|
public CmdKnockback() {
|
||||||
|
|
||||||
public class CmdKnockback extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdKnockback()
|
|
||||||
{
|
|
||||||
name = permission = "knockback";
|
name = permission = "knockback";
|
||||||
minParams = maxParams = 1;
|
minParams = maxParams = 1;
|
||||||
|
|
||||||
@ -20,8 +17,7 @@ public class CmdKnockback extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
double kb = Config.KnockBack();
|
double kb = Config.KnockBack();
|
||||||
if (kb < 1)
|
if (kb < 1)
|
||||||
sender.sendMessage(C_HEAD + "Knockback is set to 0, disabling border enforcement.");
|
sender.sendMessage(C_HEAD + "Knockback is set to 0, disabling border enforcement.");
|
||||||
@ -30,17 +26,13 @@ public class CmdKnockback extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
double numBlocks = 0.0;
|
double numBlocks = 0.0;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
numBlocks = Double.parseDouble(params.get(0));
|
numBlocks = Double.parseDouble(params.get(0));
|
||||||
if (numBlocks < 0.0 || (numBlocks > 0.0 && numBlocks < 1.0))
|
if (numBlocks < 0.0 || (numBlocks > 0.0 && numBlocks < 1.0))
|
||||||
throw new NumberFormatException();
|
throw new NumberFormatException();
|
||||||
}
|
} catch (NumberFormatException ex) {
|
||||||
catch(NumberFormatException ex)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "The knockback must be a decimal value of at least 1.0, or it can be 0.");
|
sendErrorAndHelp(sender, "The knockback must be a decimal value of at least 1.0, or it can be 0.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdList extends WBCmd {
|
||||||
|
public CmdList() {
|
||||||
|
|
||||||
public class CmdList extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdList()
|
|
||||||
{
|
|
||||||
name = permission = "list";
|
name = permission = "list";
|
||||||
minParams = maxParams = 0;
|
minParams = maxParams = 0;
|
||||||
|
|
||||||
@ -22,20 +19,17 @@ public class CmdList extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
sender.sendMessage("Default border shape for all worlds is \"" + Config.ShapeName() + "\".");
|
sender.sendMessage("Default border shape for all worlds is \"" + Config.ShapeName() + "\".");
|
||||||
|
|
||||||
Set<String> list = Config.BorderDescriptions();
|
Set<String> list = Config.BorderDescriptions();
|
||||||
|
|
||||||
if (list.isEmpty())
|
if (list.isEmpty()) {
|
||||||
{
|
|
||||||
sender.sendMessage("There are no borders currently set.");
|
sender.sendMessage("There are no borders currently set.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(String borderDesc : list)
|
for (String borderDesc : list) {
|
||||||
{
|
|
||||||
sender.sendMessage(borderDesc);
|
sender.sendMessage(borderDesc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdPortal extends WBCmd {
|
||||||
|
public CmdPortal() {
|
||||||
|
|
||||||
public class CmdPortal extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdPortal()
|
|
||||||
{
|
|
||||||
name = permission = "portal";
|
name = permission = "portal";
|
||||||
minParams = maxParams = 1;
|
minParams = maxParams = 1;
|
||||||
|
|
||||||
@ -22,18 +19,15 @@ public class CmdPortal extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
sender.sendMessage(C_HEAD + "Portal redirection is " + enabledColored(Config.portalRedirection()) + C_HEAD + ".");
|
sender.sendMessage(C_HEAD + "Portal redirection is " + enabledColored(Config.portalRedirection()) + C_HEAD + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
Config.setPortalRedirection(strAsBool(params.get(0)));
|
Config.setPortalRedirection(strAsBool(params.get(0)));
|
||||||
|
|
||||||
if (player != null)
|
if (player != null) {
|
||||||
{
|
|
||||||
Config.log((Config.portalRedirection() ? "Enabled" : "Disabled") + " portal redirection at the command of player \"" + player.getName() + "\".");
|
Config.log((Config.portalRedirection() ? "Enabled" : "Disabled") + " portal redirection at the command of player \"" + player.getName() + "\".");
|
||||||
cmdStatus(sender);
|
cmdStatus(sender);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
import java.util.List;
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.Config;
|
import java.util.List;
|
||||||
|
|
||||||
public class CmdPreventPlace extends WBCmd {
|
public class CmdPreventPlace extends WBCmd {
|
||||||
|
|
||||||
@ -18,18 +17,15 @@ public class CmdPreventPlace extends WBCmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
sender.sendMessage(C_HEAD + "Prevention of block placement outside the border is " + enabledColored(Config.preventBlockPlace()) + C_HEAD + ".");
|
sender.sendMessage(C_HEAD + "Prevention of block placement outside the border is " + enabledColored(Config.preventBlockPlace()) + C_HEAD + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
Config.setPreventBlockPlace(strAsBool(params.get(0)));
|
Config.setPreventBlockPlace(strAsBool(params.get(0)));
|
||||||
|
|
||||||
if (player != null)
|
if (player != null) {
|
||||||
{
|
|
||||||
Config.log((Config.preventBlockPlace() ? "Enabled" : "Disabled") + " preventblockplace at the command of player \"" + player.getName() + "\".");
|
Config.log((Config.preventBlockPlace() ? "Enabled" : "Disabled") + " preventblockplace at the command of player \"" + player.getName() + "\".");
|
||||||
cmdStatus(sender);
|
cmdStatus(sender);
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,15 @@ public class CmdPreventSpawn extends WBCmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
sender.sendMessage(C_HEAD + "Prevention of mob spawning outside the border is " + enabledColored(Config.preventMobSpawn()) + C_HEAD + ".");
|
sender.sendMessage(C_HEAD + "Prevention of mob spawning outside the border is " + enabledColored(Config.preventMobSpawn()) + C_HEAD + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
Config.setPreventMobSpawn(strAsBool(params.get(0)));
|
Config.setPreventMobSpawn(strAsBool(params.get(0)));
|
||||||
|
|
||||||
if (player != null)
|
if (player != null) {
|
||||||
{
|
|
||||||
Config.log((Config.preventMobSpawn() ? "Enabled" : "Disabled") + " preventmobspawn at the command of player \"" + player.getName() + "\".");
|
Config.log((Config.preventMobSpawn() ? "Enabled" : "Disabled") + " preventmobspawn at the command of player \"" + player.getName() + "\".");
|
||||||
cmdStatus(sender);
|
cmdStatus(sender);
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.BorderData;
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdRadius extends WBCmd {
|
||||||
|
public CmdRadius() {
|
||||||
|
|
||||||
public class CmdRadius extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdRadius()
|
|
||||||
{
|
|
||||||
name = permission = "radius";
|
name = permission = "radius";
|
||||||
hasWorldNameInput = true;
|
hasWorldNameInput = true;
|
||||||
minParams = 1;
|
minParams = 1;
|
||||||
@ -24,14 +22,12 @@ public class CmdRadius extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
if (worldName == null)
|
if (worldName == null)
|
||||||
worldName = player.getWorld().getName();
|
worldName = player.getWorld().getName();
|
||||||
|
|
||||||
BorderData border = Config.Border(worldName);
|
BorderData border = Config.Border(worldName);
|
||||||
if (border == null)
|
if (border == null) {
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "This world (\"" + worldName + "\") must first have a border set normally.");
|
sendErrorAndHelp(sender, "This world (\"" + worldName + "\") must first have a border set normally.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -40,45 +36,32 @@ public class CmdRadius extends WBCmd
|
|||||||
double z = border.getZ();
|
double z = border.getZ();
|
||||||
int radiusX;
|
int radiusX;
|
||||||
int radiusZ;
|
int radiusZ;
|
||||||
try
|
try {
|
||||||
{
|
if (params.get(0).startsWith("+")) {
|
||||||
if (params.get(0).startsWith("+"))
|
|
||||||
{
|
|
||||||
// Add to the current radius
|
// Add to the current radius
|
||||||
radiusX = border.getRadiusX();
|
radiusX = border.getRadiusX();
|
||||||
radiusX += Integer.parseInt(params.get(0).substring(1));
|
radiusX += Integer.parseInt(params.get(0).substring(1));
|
||||||
}
|
} else if (params.get(0).startsWith("-")) {
|
||||||
else if(params.get(0).startsWith("-"))
|
|
||||||
{
|
|
||||||
// Subtract from the current radius
|
// Subtract from the current radius
|
||||||
radiusX = border.getRadiusX();
|
radiusX = border.getRadiusX();
|
||||||
radiusX -= Integer.parseInt(params.get(0).substring(1));
|
radiusX -= Integer.parseInt(params.get(0).substring(1));
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
radiusX = Integer.parseInt(params.get(0));
|
radiusX = Integer.parseInt(params.get(0));
|
||||||
|
|
||||||
if (params.size() == 2)
|
if (params.size() == 2) {
|
||||||
{
|
if (params.get(1).startsWith("+")) {
|
||||||
if (params.get(1).startsWith("+"))
|
|
||||||
{
|
|
||||||
// Add to the current radius
|
// Add to the current radius
|
||||||
radiusZ = border.getRadiusZ();
|
radiusZ = border.getRadiusZ();
|
||||||
radiusZ += Integer.parseInt(params.get(1).substring(1));
|
radiusZ += Integer.parseInt(params.get(1).substring(1));
|
||||||
}
|
} else if (params.get(1).startsWith("-")) {
|
||||||
else if(params.get(1).startsWith("-"))
|
|
||||||
{
|
|
||||||
// Subtract from the current radius
|
// Subtract from the current radius
|
||||||
radiusZ = border.getRadiusZ();
|
radiusZ = border.getRadiusZ();
|
||||||
radiusZ -= Integer.parseInt(params.get(1).substring(1));
|
radiusZ -= Integer.parseInt(params.get(1).substring(1));
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
radiusZ = Integer.parseInt(params.get(1));
|
radiusZ = Integer.parseInt(params.get(1));
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
radiusZ = radiusX;
|
radiusZ = radiusX;
|
||||||
}
|
} catch (NumberFormatException ex) {
|
||||||
catch(NumberFormatException ex)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "The radius value(s) must be integers.");
|
sendErrorAndHelp(sender, "The radius value(s) must be integers.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import com.wimbli.WorldBorder.WorldBorder;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdReload extends WBCmd {
|
||||||
|
public CmdReload() {
|
||||||
|
|
||||||
public class CmdReload extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdReload()
|
|
||||||
{
|
|
||||||
name = permission = "reload";
|
name = permission = "reload";
|
||||||
minParams = maxParams = 0;
|
minParams = maxParams = 0;
|
||||||
|
|
||||||
@ -21,8 +19,7 @@ public class CmdReload extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
if (player != null)
|
if (player != null)
|
||||||
Config.log("Reloading config file at the command of player \"" + player.getName() + "\".");
|
Config.log("Reloading config file at the command of player \"" + player.getName() + "\".");
|
||||||
|
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdRemount extends WBCmd {
|
||||||
|
public CmdRemount() {
|
||||||
|
|
||||||
public class CmdRemount extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdRemount()
|
|
||||||
{
|
|
||||||
name = permission = "remount";
|
name = permission = "remount";
|
||||||
minParams = maxParams = 1;
|
minParams = maxParams = 1;
|
||||||
|
|
||||||
@ -22,13 +19,11 @@ public class CmdRemount extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
int delay = Config.RemountTicks();
|
int delay = Config.RemountTicks();
|
||||||
if (delay == 0)
|
if (delay == 0)
|
||||||
sender.sendMessage(C_HEAD + "Remount delay set to 0. Players will be left dismounted when knocked back from the border while on a vehicle.");
|
sender.sendMessage(C_HEAD + "Remount delay set to 0. Players will be left dismounted when knocked back from the border while on a vehicle.");
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
sender.sendMessage(C_HEAD + "Remount delay set to " + delay + " tick(s). That is roughly " + (delay * 50) + "ms / " + (((double) delay * 50.0) / 1000.0) + " seconds. Setting to 0 would disable remounting.");
|
sender.sendMessage(C_HEAD + "Remount delay set to " + delay + " tick(s). That is roughly " + (delay * 50) + "ms / " + (((double) delay * 50.0) / 1000.0) + " seconds. Setting to 0 would disable remounting.");
|
||||||
if (delay < 10)
|
if (delay < 10)
|
||||||
sender.sendMessage(C_ERR + "WARNING:" + C_DESC + " setting this to less than 10 (and greater than 0) is not recommended. This can lead to nasty client glitches.");
|
sender.sendMessage(C_ERR + "WARNING:" + C_DESC + " setting this to less than 10 (and greater than 0) is not recommended. This can lead to nasty client glitches.");
|
||||||
@ -36,17 +31,13 @@ public class CmdRemount extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
int delay = 0;
|
int delay = 0;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
delay = Integer.parseInt(params.get(0));
|
delay = Integer.parseInt(params.get(0));
|
||||||
if (delay < 0)
|
if (delay < 0)
|
||||||
throw new NumberFormatException();
|
throw new NumberFormatException();
|
||||||
}
|
} catch (NumberFormatException ex) {
|
||||||
catch(NumberFormatException ex)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "The remount delay must be an integer of 0 or higher. Setting to 0 will disable remounting.");
|
sendErrorAndHelp(sender, "The remount delay must be an integer of 0 or higher. Setting to 0 will disable remounting.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,17 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdSet extends WBCmd {
|
||||||
|
public CmdSet() {
|
||||||
|
|
||||||
public class CmdSet extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdSet()
|
|
||||||
{
|
|
||||||
name = permission = "set";
|
name = permission = "set";
|
||||||
hasWorldNameInput = true;
|
hasWorldNameInput = true;
|
||||||
consoleRequiresWorldName = false;
|
consoleRequiresWorldName = false;
|
||||||
@ -31,29 +28,23 @@ public class CmdSet extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
// passsing a single parameter (radiusX) is only acceptable from player
|
// passsing a single parameter (radiusX) is only acceptable from player
|
||||||
if ((params.size() == 1) && player == null)
|
if ((params.size() == 1) && player == null) {
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "You have not provided a sufficient number of parameters.");
|
sendErrorAndHelp(sender, "You have not provided a sufficient number of parameters.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "set" command from player or console, world specified
|
// "set" command from player or console, world specified
|
||||||
if (worldName != null)
|
if (worldName != null) {
|
||||||
{
|
if (params.size() == 2 && !params.get(params.size() - 1).equalsIgnoreCase("spawn")) { // command can only be this short if "spawn" is specified rather than x + z or player name
|
||||||
if (params.size() == 2 && ! params.get(params.size() - 1).equalsIgnoreCase("spawn"))
|
|
||||||
{ // command can only be this short if "spawn" is specified rather than x + z or player name
|
|
||||||
sendErrorAndHelp(sender, "You have not provided a sufficient number of arguments.");
|
sendErrorAndHelp(sender, "You have not provided a sufficient number of arguments.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
World world = sender.getServer().getWorld(worldName);
|
World world = sender.getServer().getWorld(worldName);
|
||||||
if (world == null)
|
if (world == null) {
|
||||||
{
|
if (params.get(params.size() - 1).equalsIgnoreCase("spawn")) {
|
||||||
if (params.get(params.size() - 1).equalsIgnoreCase("spawn"))
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "The world you specified (\"" + worldName + "\") could not be found on the server, so the spawn point cannot be determined.");
|
sendErrorAndHelp(sender, "The world you specified (\"" + worldName + "\") could not be found on the server, so the spawn point cannot be determined.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -61,18 +52,14 @@ public class CmdSet extends WBCmd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// "set" command from player using current world since it isn't specified, or allowed from console only if player name is specified
|
// "set" command from player using current world since it isn't specified, or allowed from console only if player name is specified
|
||||||
else
|
else {
|
||||||
{
|
if (player == null) {
|
||||||
if (player == null)
|
if (!params.get(params.size() - 2).equalsIgnoreCase("player")) { // command can only be called by console without world specified if player is specified instead
|
||||||
{
|
|
||||||
if (! params.get(params.size() - 2).equalsIgnoreCase("player"))
|
|
||||||
{ // command can only be called by console without world specified if player is specified instead
|
|
||||||
sendErrorAndHelp(sender, "You must specify a world name from console if not specifying a player name.");
|
sendErrorAndHelp(sender, "You must specify a world name from console if not specifying a player name.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
player = Bukkit.getPlayer(params.get(params.size() - 1));
|
player = Bukkit.getPlayer(params.get(params.size() - 1));
|
||||||
if (player == null || ! player.isOnline())
|
if (player == null || !player.isOnline()) {
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "The player you specified (\"" + params.get(params.size() - 1) + "\") does not appear to be online.");
|
sendErrorAndHelp(sender, "The player you specified (\"" + params.get(params.size() - 1) + "\") does not appear to be online.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -84,20 +71,15 @@ public class CmdSet extends WBCmd
|
|||||||
double x, z;
|
double x, z;
|
||||||
int radiusCount = params.size();
|
int radiusCount = params.size();
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
if (params.get(params.size() - 1).equalsIgnoreCase("spawn")) { // "spawn" specified for x/z coordinates
|
||||||
if (params.get(params.size() - 1).equalsIgnoreCase("spawn"))
|
|
||||||
{ // "spawn" specified for x/z coordinates
|
|
||||||
Location loc = sender.getServer().getWorld(worldName).getSpawnLocation();
|
Location loc = sender.getServer().getWorld(worldName).getSpawnLocation();
|
||||||
x = loc.getX();
|
x = loc.getX();
|
||||||
z = loc.getZ();
|
z = loc.getZ();
|
||||||
radiusCount -= 1;
|
radiusCount -= 1;
|
||||||
}
|
} else if (params.size() > 2 && params.get(params.size() - 2).equalsIgnoreCase("player")) { // player name specified for x/z coordinates
|
||||||
else if (params.size() > 2 && params.get(params.size() - 2).equalsIgnoreCase("player"))
|
|
||||||
{ // player name specified for x/z coordinates
|
|
||||||
Player playerT = Bukkit.getPlayer(params.get(params.size() - 1));
|
Player playerT = Bukkit.getPlayer(params.get(params.size() - 1));
|
||||||
if (playerT == null || ! playerT.isOnline())
|
if (playerT == null || !playerT.isOnline()) {
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "The player you specified (\"" + params.get(params.size() - 1) + "\") does not appear to be online.");
|
sendErrorAndHelp(sender, "The player you specified (\"" + params.get(params.size() - 1) + "\") does not appear to be online.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -105,17 +87,12 @@ public class CmdSet extends WBCmd
|
|||||||
x = playerT.getLocation().getX();
|
x = playerT.getLocation().getX();
|
||||||
z = playerT.getLocation().getZ();
|
z = playerT.getLocation().getZ();
|
||||||
radiusCount -= 2;
|
radiusCount -= 2;
|
||||||
}
|
} else {
|
||||||
else
|
if (player == null || radiusCount > 2) { // x and z specified
|
||||||
{
|
|
||||||
if (player == null || radiusCount > 2)
|
|
||||||
{ // x and z specified
|
|
||||||
x = Double.parseDouble(params.get(params.size() - 2));
|
x = Double.parseDouble(params.get(params.size() - 2));
|
||||||
z = Double.parseDouble(params.get(params.size() - 1));
|
z = Double.parseDouble(params.get(params.size() - 1));
|
||||||
radiusCount -= 2;
|
radiusCount -= 2;
|
||||||
}
|
} else { // using coordinates of command sender (player)
|
||||||
else
|
|
||||||
{ // using coordinates of command sender (player)
|
|
||||||
x = player.getLocation().getX();
|
x = player.getLocation().getX();
|
||||||
z = player.getLocation().getZ();
|
z = player.getLocation().getZ();
|
||||||
}
|
}
|
||||||
@ -127,14 +104,11 @@ public class CmdSet extends WBCmd
|
|||||||
else
|
else
|
||||||
radiusZ = Integer.parseInt(params.get(1));
|
radiusZ = Integer.parseInt(params.get(1));
|
||||||
|
|
||||||
if (radiusX < Config.KnockBack() || radiusZ < Config.KnockBack())
|
if (radiusX < Config.KnockBack() || radiusZ < Config.KnockBack()) {
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "Radius value(s) must be more than the knockback distance.");
|
sendErrorAndHelp(sender, "Radius value(s) must be more than the knockback distance.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
} catch (NumberFormatException ex) {
|
||||||
catch(NumberFormatException ex)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "Radius value(s) must be integers and x and z values must be numerical.");
|
sendErrorAndHelp(sender, "Radius value(s) must be integers and x and z values must be numerical.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdSetcorners extends WBCmd {
|
||||||
|
public CmdSetcorners() {
|
||||||
|
|
||||||
public class CmdSetcorners extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdSetcorners()
|
|
||||||
{
|
|
||||||
name = "setcorners";
|
name = "setcorners";
|
||||||
permission = "set";
|
permission = "set";
|
||||||
hasWorldNameInput = true;
|
hasWorldNameInput = true;
|
||||||
@ -25,29 +22,22 @@ public class CmdSetcorners extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
if (worldName == null) {
|
||||||
if (worldName == null)
|
|
||||||
{
|
|
||||||
worldName = player.getWorld().getName();
|
worldName = player.getWorld().getName();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
World worldTest = sender.getServer().getWorld(worldName);
|
World worldTest = sender.getServer().getWorld(worldName);
|
||||||
if (worldTest == null)
|
if (worldTest == null)
|
||||||
sender.sendMessage("The world you specified (\"" + worldName + "\") could not be found on the server, but data for it will be stored anyway.");
|
sender.sendMessage("The world you specified (\"" + worldName + "\") could not be found on the server, but data for it will be stored anyway.");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
double x1 = Double.parseDouble(params.get(0));
|
double x1 = Double.parseDouble(params.get(0));
|
||||||
double z1 = Double.parseDouble(params.get(1));
|
double z1 = Double.parseDouble(params.get(1));
|
||||||
double x2 = Double.parseDouble(params.get(2));
|
double x2 = Double.parseDouble(params.get(2));
|
||||||
double z2 = Double.parseDouble(params.get(3));
|
double z2 = Double.parseDouble(params.get(3));
|
||||||
Config.setBorderCorners(worldName, x1, z1, x2, z2);
|
Config.setBorderCorners(worldName, x1, z1, x2, z2);
|
||||||
}
|
} catch (NumberFormatException ex) {
|
||||||
catch(NumberFormatException ex)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "The x1, z1, x2, and z2 coordinate values must be numerical.");
|
sendErrorAndHelp(sender, "The x1, z1, x2, and z2 coordinate values must be numerical.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdSetmsg extends WBCmd {
|
||||||
|
public CmdSetmsg() {
|
||||||
|
|
||||||
public class CmdSetmsg extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdSetmsg()
|
|
||||||
{
|
|
||||||
name = permission = "setmsg";
|
name = permission = "setmsg";
|
||||||
minParams = 1;
|
minParams = 1;
|
||||||
|
|
||||||
@ -20,8 +17,7 @@ public class CmdSetmsg extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
sender.sendMessage(C_HEAD + "Border message is set to:");
|
sender.sendMessage(C_HEAD + "Border message is set to:");
|
||||||
sender.sendMessage(Config.MessageRaw());
|
sender.sendMessage(Config.MessageRaw());
|
||||||
sender.sendMessage(C_HEAD + "Formatted border message:");
|
sender.sendMessage(C_HEAD + "Formatted border message:");
|
||||||
@ -29,12 +25,10 @@ public class CmdSetmsg extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
StringBuilder message = new StringBuilder();
|
StringBuilder message = new StringBuilder();
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (String param : params)
|
for (String param : params) {
|
||||||
{
|
|
||||||
if (!first)
|
if (!first)
|
||||||
message.append(" ");
|
message.append(" ");
|
||||||
message.append(param);
|
message.append(param);
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdShape extends WBCmd {
|
||||||
|
public CmdShape() {
|
||||||
|
|
||||||
public class CmdShape extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdShape()
|
|
||||||
{
|
|
||||||
name = permission = "shape";
|
name = permission = "shape";
|
||||||
minParams = maxParams = 1;
|
minParams = maxParams = 1;
|
||||||
|
|
||||||
@ -24,21 +21,18 @@ public class CmdShape extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
sender.sendMessage(C_HEAD + "The default border shape for all worlds is currently set to \"" + Config.ShapeName() + "\".");
|
sender.sendMessage(C_HEAD + "The default border shape for all worlds is currently set to \"" + Config.ShapeName() + "\".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
String shape = params.get(0).toLowerCase();
|
String shape = params.get(0).toLowerCase();
|
||||||
if (shape.equals("rectangular") || shape.equals("square"))
|
if (shape.equals("rectangular") || shape.equals("square"))
|
||||||
Config.setShape(false);
|
Config.setShape(false);
|
||||||
else if (shape.equals("elliptic") || shape.equals("round"))
|
else if (shape.equals("elliptic") || shape.equals("round"))
|
||||||
Config.setShape(true);
|
Config.setShape(true);
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "You must specify one of the 4 valid shape names below.");
|
sendErrorAndHelp(sender, "You must specify one of the 4 valid shape names below.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,27 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import com.wimbli.WorldBorder.CoordXZ;
|
||||||
|
import com.wimbli.WorldBorder.WorldBorder;
|
||||||
|
import com.wimbli.WorldBorder.WorldTrimTask;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdTrim extends WBCmd {
|
||||||
|
/* with "view-distance=10" in server.properties on a fast VM test server and "Render Distance: Far" in client,
|
||||||
|
* hitting border during testing was loading 11+ chunks beyond the border in a couple of directions (10 chunks in
|
||||||
|
* the other two directions). This could be worse on a more loaded or worse server, so:
|
||||||
|
*/
|
||||||
|
private final int defaultPadding = CoordXZ.chunkToBlock(13);
|
||||||
|
private String trimWorld = "";
|
||||||
|
private int trimFrequency = 5000;
|
||||||
|
private int trimPadding = defaultPadding;
|
||||||
|
|
||||||
|
public CmdTrim() {
|
||||||
public class CmdTrim extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdTrim()
|
|
||||||
{
|
|
||||||
name = permission = "trim";
|
name = permission = "trim";
|
||||||
hasWorldNameInput = true;
|
hasWorldNameInput = true;
|
||||||
consoleRequiresWorldName = false;
|
consoleRequiresWorldName = false;
|
||||||
@ -26,25 +35,20 @@ public class CmdTrim extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
boolean confirm = false;
|
boolean confirm = false;
|
||||||
// check for "cancel", "pause", or "confirm"
|
// check for "cancel", "pause", or "confirm"
|
||||||
if (params.size() >= 1)
|
if (params.size() >= 1) {
|
||||||
{
|
|
||||||
String check = params.get(0).toLowerCase();
|
String check = params.get(0).toLowerCase();
|
||||||
|
|
||||||
if (check.equals("cancel") || check.equals("stop"))
|
if (check.equals("cancel") || check.equals("stop")) {
|
||||||
{
|
|
||||||
if (!makeSureTrimIsRunning(sender))
|
if (!makeSureTrimIsRunning(sender))
|
||||||
return;
|
return;
|
||||||
sender.sendMessage(C_HEAD + "Cancelling the world map trimming task.");
|
sender.sendMessage(C_HEAD + "Cancelling the world map trimming task.");
|
||||||
trimDefaults();
|
trimDefaults();
|
||||||
Config.StopTrimTask();
|
Config.StopTrimTask();
|
||||||
return;
|
return;
|
||||||
}
|
} else if (check.equals("pause")) {
|
||||||
else if (check.equals("pause"))
|
|
||||||
{
|
|
||||||
if (!makeSureTrimIsRunning(sender))
|
if (!makeSureTrimIsRunning(sender))
|
||||||
return;
|
return;
|
||||||
Config.trimTask.pause();
|
Config.trimTask.pause();
|
||||||
@ -56,12 +60,10 @@ public class CmdTrim extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if not just confirming, make sure a world name is available
|
// if not just confirming, make sure a world name is available
|
||||||
if (worldName == null && !confirm)
|
if (worldName == null && !confirm) {
|
||||||
{
|
|
||||||
if (player != null)
|
if (player != null)
|
||||||
worldName = player.getWorld().getName();
|
worldName = player.getWorld().getName();
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "You must specify a world!");
|
sendErrorAndHelp(sender, "You must specify a world!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -71,29 +73,24 @@ public class CmdTrim extends WBCmd
|
|||||||
String cmd = cmd(sender) + nameEmphasized() + C_CMD;
|
String cmd = cmd(sender) + nameEmphasized() + C_CMD;
|
||||||
|
|
||||||
// make sure Trim isn't already running
|
// make sure Trim isn't already running
|
||||||
if (Config.trimTask != null && Config.trimTask.valid())
|
if (Config.trimTask != null && Config.trimTask.valid()) {
|
||||||
{
|
|
||||||
sender.sendMessage(C_ERR + "The world map trimming task is already running.");
|
sender.sendMessage(C_ERR + "The world map trimming task is already running.");
|
||||||
sender.sendMessage(C_DESC + "You can cancel at any time with " + cmd + "cancel" + C_DESC + ", or pause/unpause with " + cmd + "pause" + C_DESC + ".");
|
sender.sendMessage(C_DESC + "You can cancel at any time with " + cmd + "cancel" + C_DESC + ", or pause/unpause with " + cmd + "pause" + C_DESC + ".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set frequency and/or padding if those were specified
|
// set frequency and/or padding if those were specified
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
if (params.size() >= 1 && !confirm)
|
if (params.size() >= 1 && !confirm)
|
||||||
trimFrequency = Math.abs(Integer.parseInt(params.get(0)));
|
trimFrequency = Math.abs(Integer.parseInt(params.get(0)));
|
||||||
if (params.size() >= 2 && !confirm)
|
if (params.size() >= 2 && !confirm)
|
||||||
trimPadding = Math.abs(Integer.parseInt(params.get(1)));
|
trimPadding = Math.abs(Integer.parseInt(params.get(1)));
|
||||||
}
|
} catch (NumberFormatException ex) {
|
||||||
catch(NumberFormatException ex)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "The frequency and padding values must be integers.");
|
sendErrorAndHelp(sender, "The frequency and padding values must be integers.");
|
||||||
trimDefaults();
|
trimDefaults();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (trimFrequency <= 0)
|
if (trimFrequency <= 0) {
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "The frequency value must be greater than zero.");
|
sendErrorAndHelp(sender, "The frequency value must be greater than zero.");
|
||||||
trimDefaults();
|
trimDefaults();
|
||||||
return;
|
return;
|
||||||
@ -103,10 +100,8 @@ public class CmdTrim extends WBCmd
|
|||||||
if (worldName != null)
|
if (worldName != null)
|
||||||
trimWorld = worldName;
|
trimWorld = worldName;
|
||||||
|
|
||||||
if (confirm)
|
if (confirm) { // command confirmed, go ahead with it
|
||||||
{ // command confirmed, go ahead with it
|
if (trimWorld.isEmpty()) {
|
||||||
if (trimWorld.isEmpty())
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "You must first use this command successfully without confirming.");
|
sendErrorAndHelp(sender, "You must first use this command successfully without confirming.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -121,21 +116,16 @@ public class CmdTrim extends WBCmd
|
|||||||
ticks = 20 / trimFrequency;
|
ticks = 20 / trimFrequency;
|
||||||
|
|
||||||
Config.trimTask = new WorldTrimTask(Bukkit.getServer(), player, trimWorld, trimPadding, repeats);
|
Config.trimTask = new WorldTrimTask(Bukkit.getServer(), player, trimWorld, trimPadding, repeats);
|
||||||
if (Config.trimTask.valid())
|
if (Config.trimTask.valid()) {
|
||||||
{
|
|
||||||
int task = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(WorldBorder.plugin, Config.trimTask, ticks, ticks);
|
int task = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(WorldBorder.plugin, Config.trimTask, ticks, ticks);
|
||||||
Config.trimTask.setTaskID(task);
|
Config.trimTask.setTaskID(task);
|
||||||
sender.sendMessage("WorldBorder map trimming task for world \"" + trimWorld + "\" started.");
|
sender.sendMessage("WorldBorder map trimming task for world \"" + trimWorld + "\" started.");
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
sender.sendMessage(C_ERR + "The world map trimming task failed to start.");
|
sender.sendMessage(C_ERR + "The world map trimming task failed to start.");
|
||||||
|
|
||||||
trimDefaults();
|
trimDefaults();
|
||||||
}
|
} else {
|
||||||
else
|
if (trimWorld.isEmpty()) {
|
||||||
{
|
|
||||||
if (trimWorld.isEmpty())
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "You must first specify a valid world.");
|
sendErrorAndHelp(sender, "You must first specify a valid world.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -147,26 +137,13 @@ public class CmdTrim extends WBCmd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void trimDefaults() {
|
||||||
/* with "view-distance=10" in server.properties on a fast VM test server and "Render Distance: Far" in client,
|
|
||||||
* hitting border during testing was loading 11+ chunks beyond the border in a couple of directions (10 chunks in
|
|
||||||
* the other two directions). This could be worse on a more loaded or worse server, so:
|
|
||||||
*/
|
|
||||||
private final int defaultPadding = CoordXZ.chunkToBlock(13);
|
|
||||||
|
|
||||||
private String trimWorld = "";
|
|
||||||
private int trimFrequency = 5000;
|
|
||||||
private int trimPadding = defaultPadding;
|
|
||||||
|
|
||||||
private void trimDefaults()
|
|
||||||
{
|
|
||||||
trimWorld = "";
|
trimWorld = "";
|
||||||
trimFrequency = 5000;
|
trimFrequency = 5000;
|
||||||
trimPadding = defaultPadding;
|
trimPadding = defaultPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean makeSureTrimIsRunning(CommandSender sender)
|
private boolean makeSureTrimIsRunning(CommandSender sender) {
|
||||||
{
|
|
||||||
if (Config.trimTask != null && Config.trimTask.valid())
|
if (Config.trimTask != null && Config.trimTask.valid())
|
||||||
return true;
|
return true;
|
||||||
sendErrorAndHelp(sender, "The world map trimming task is not currently running.");
|
sendErrorAndHelp(sender, "The world map trimming task is not currently running.");
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdWhoosh extends WBCmd {
|
||||||
|
public CmdWhoosh() {
|
||||||
|
|
||||||
public class CmdWhoosh extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdWhoosh()
|
|
||||||
{
|
|
||||||
name = permission = "whoosh";
|
name = permission = "whoosh";
|
||||||
minParams = maxParams = 1;
|
minParams = maxParams = 1;
|
||||||
|
|
||||||
@ -21,18 +18,15 @@ public class CmdWhoosh extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cmdStatus(CommandSender sender)
|
public void cmdStatus(CommandSender sender) {
|
||||||
{
|
|
||||||
sender.sendMessage(C_HEAD + "\"Whoosh\" knockback effect is " + enabledColored(Config.whooshEffect()) + C_HEAD + ".");
|
sender.sendMessage(C_HEAD + "\"Whoosh\" knockback effect is " + enabledColored(Config.whooshEffect()) + C_HEAD + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
|
||||||
Config.setWhooshEffect(strAsBool(params.get(0)));
|
Config.setWhooshEffect(strAsBool(params.get(0)));
|
||||||
|
|
||||||
if (player != null)
|
if (player != null) {
|
||||||
{
|
|
||||||
Config.log((Config.whooshEffect() ? "Enabled" : "Disabled") + " \"whoosh\" knockback effect at the command of player \"" + player.getName() + "\".");
|
Config.log((Config.whooshEffect() ? "Enabled" : "Disabled") + " \"whoosh\" knockback effect at the command of player \"" + player.getName() + "\".");
|
||||||
cmdStatus(sender);
|
cmdStatus(sender);
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.BorderData;
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdWrap extends WBCmd {
|
||||||
|
public CmdWrap() {
|
||||||
|
|
||||||
public class CmdWrap extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdWrap()
|
|
||||||
{
|
|
||||||
name = permission = "wrap";
|
name = permission = "wrap";
|
||||||
minParams = 1;
|
minParams = 1;
|
||||||
maxParams = 2;
|
maxParams = 2;
|
||||||
@ -23,10 +21,8 @@ public class CmdWrap extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
if (player == null && params.size() == 1) {
|
||||||
if (player == null && params.size() == 1)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "When running this command from console, you must specify a world.");
|
sendErrorAndHelp(sender, "When running this command from console, you must specify a world.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -34,21 +30,18 @@ public class CmdWrap extends WBCmd
|
|||||||
boolean wrap = false;
|
boolean wrap = false;
|
||||||
|
|
||||||
// world and wrap on/off specified
|
// world and wrap on/off specified
|
||||||
if (params.size() == 2)
|
if (params.size() == 2) {
|
||||||
{
|
|
||||||
worldName = params.get(0);
|
worldName = params.get(0);
|
||||||
wrap = strAsBool(params.get(1));
|
wrap = strAsBool(params.get(1));
|
||||||
}
|
}
|
||||||
// no world specified, just wrap on/off
|
// no world specified, just wrap on/off
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
worldName = player.getWorld().getName();
|
worldName = player.getWorld().getName();
|
||||||
wrap = strAsBool(params.get(0));
|
wrap = strAsBool(params.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
BorderData border = Config.Border(worldName);
|
BorderData border = Config.Border(worldName);
|
||||||
if (border == null)
|
if (border == null) {
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "This world (\"" + worldName + "\") does not have a border set.");
|
sendErrorAndHelp(sender, "This world (\"" + worldName + "\") does not have a border set.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import com.wimbli.WorldBorder.BorderData;
|
||||||
|
import com.wimbli.WorldBorder.Config;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import com.wimbli.WorldBorder.*;
|
public class CmdWshape extends WBCmd {
|
||||||
|
public CmdWshape() {
|
||||||
|
|
||||||
public class CmdWshape extends WBCmd
|
|
||||||
{
|
|
||||||
public CmdWshape()
|
|
||||||
{
|
|
||||||
name = permission = "wshape";
|
name = permission = "wshape";
|
||||||
minParams = 1;
|
minParams = 1;
|
||||||
maxParams = 2;
|
maxParams = 2;
|
||||||
@ -25,10 +23,8 @@ public class CmdWshape extends WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, Player player, List<String> params, String worldName)
|
public void execute(CommandSender sender, Player player, List<String> params, String worldName) {
|
||||||
{
|
if (player == null && params.size() == 1) {
|
||||||
if (player == null && params.size() == 1)
|
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "When running this command from console, you must specify a world.");
|
sendErrorAndHelp(sender, "When running this command from console, you must specify a world.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -36,21 +32,18 @@ public class CmdWshape extends WBCmd
|
|||||||
String shapeName = "";
|
String shapeName = "";
|
||||||
|
|
||||||
// world and shape specified
|
// world and shape specified
|
||||||
if (params.size() == 2)
|
if (params.size() == 2) {
|
||||||
{
|
|
||||||
worldName = params.get(0);
|
worldName = params.get(0);
|
||||||
shapeName = params.get(1).toLowerCase();
|
shapeName = params.get(1).toLowerCase();
|
||||||
}
|
}
|
||||||
// no world specified, just shape
|
// no world specified, just shape
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
worldName = player.getWorld().getName();
|
worldName = player.getWorld().getName();
|
||||||
shapeName = params.get(0).toLowerCase();
|
shapeName = params.get(0).toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
BorderData border = Config.Border(worldName);
|
BorderData border = Config.Border(worldName);
|
||||||
if (border == null)
|
if (border == null) {
|
||||||
{
|
|
||||||
sendErrorAndHelp(sender, "This world (\"" + worldName + "\") does not have a border set.");
|
sendErrorAndHelp(sender, "This world (\"" + worldName + "\") does not have a border set.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,49 +1,18 @@
|
|||||||
package com.wimbli.WorldBorder.cmd;
|
package com.wimbli.WorldBorder.cmd;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
|
public abstract class WBCmd {
|
||||||
public abstract class WBCmd
|
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* Primary variables, should be set as needed in constructors for the subclassed commands
|
* Primary variables, should be set as needed in constructors for the subclassed commands
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// command name, command permission; normally the same thing
|
|
||||||
public String name = "";
|
|
||||||
public String permission = null;
|
|
||||||
|
|
||||||
// whether command can accept a world name before itself
|
|
||||||
public boolean hasWorldNameInput = false;
|
|
||||||
public boolean consoleRequiresWorldName = true;
|
|
||||||
|
|
||||||
// minimum and maximum number of accepted parameters
|
|
||||||
public int minParams = 0;
|
|
||||||
public int maxParams = 9999;
|
|
||||||
|
|
||||||
// help/explanation text to be shown after command example(s) for this command
|
|
||||||
public String helpText = null;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The guts of the command run in here; needs to be overriden in the subclassed commands
|
|
||||||
*/
|
|
||||||
public abstract void execute(CommandSender sender, Player player, List<String> params, String worldName);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is an optional override, used to provide some extra command status info, like the currently set value
|
|
||||||
*/
|
|
||||||
public void cmdStatus(CommandSender sender) {}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper variables and methods
|
|
||||||
*/
|
|
||||||
|
|
||||||
// color values for strings
|
// color values for strings
|
||||||
public final static String C_CMD = ChatColor.AQUA.toString(); // main commands
|
public final static String C_CMD = ChatColor.AQUA.toString(); // main commands
|
||||||
public final static String C_DESC = ChatColor.WHITE.toString(); // command descriptions
|
public final static String C_DESC = ChatColor.WHITE.toString(); // command descriptions
|
||||||
@ -51,40 +20,60 @@ public abstract class WBCmd
|
|||||||
public final static String C_HEAD = ChatColor.YELLOW.toString(); // command listing header
|
public final static String C_HEAD = ChatColor.YELLOW.toString(); // command listing header
|
||||||
public final static String C_OPT = ChatColor.DARK_GREEN.toString(); // optional values
|
public final static String C_OPT = ChatColor.DARK_GREEN.toString(); // optional values
|
||||||
public final static String C_REQ = ChatColor.GREEN.toString(); // required values
|
public final static String C_REQ = ChatColor.GREEN.toString(); // required values
|
||||||
|
|
||||||
// colorized root command, for console and for player
|
// colorized root command, for console and for player
|
||||||
public final static String CMD_C = C_CMD + "wb ";
|
public final static String CMD_C = C_CMD + "wb ";
|
||||||
public final static String CMD_P = C_CMD + "/wb ";
|
public final static String CMD_P = C_CMD + "/wb ";
|
||||||
|
// much like the above, but used for displaying command list from root /wb command, listing all commands
|
||||||
|
public final static List<String> cmdExamplesConsole = new ArrayList<String>(48); // 48 command capacity, 6 full pages
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper variables and methods
|
||||||
|
*/
|
||||||
|
public final static List<String> cmdExamplesPlayer = new ArrayList<String>(48); // still, could need to increase later
|
||||||
|
// command name, command permission; normally the same thing
|
||||||
|
public String name = "";
|
||||||
|
public String permission = null;
|
||||||
|
// whether command can accept a world name before itself
|
||||||
|
public boolean hasWorldNameInput = false;
|
||||||
|
public boolean consoleRequiresWorldName = true;
|
||||||
|
// minimum and maximum number of accepted parameters
|
||||||
|
public int minParams = 0;
|
||||||
|
public int maxParams = 9999;
|
||||||
|
// help/explanation text to be shown after command example(s) for this command
|
||||||
|
public String helpText = null;
|
||||||
// list of command examples for this command to be displayed as usage reference, separate between players and console
|
// list of command examples for this command to be displayed as usage reference, separate between players and console
|
||||||
// ... these generally should be set indirectly using addCmdExample() within the constructor for each command class
|
// ... these generally should be set indirectly using addCmdExample() within the constructor for each command class
|
||||||
public List<String> cmdExamplePlayer = new ArrayList<String>();
|
public List<String> cmdExamplePlayer = new ArrayList<String>();
|
||||||
public List<String> cmdExampleConsole = new ArrayList<String>();
|
public List<String> cmdExampleConsole = new ArrayList<String>();
|
||||||
|
|
||||||
// much like the above, but used for displaying command list from root /wb command, listing all commands
|
/*
|
||||||
public final static List<String> cmdExamplesConsole = new ArrayList<String>(48); // 48 command capacity, 6 full pages
|
* The guts of the command run in here; needs to be overriden in the subclassed commands
|
||||||
public final static List<String> cmdExamplesPlayer = new ArrayList<String>(48); // still, could need to increase later
|
*/
|
||||||
|
public abstract void execute(CommandSender sender, Player player, List<String> params, String worldName);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an optional override, used to provide some extra command status info, like the currently set value
|
||||||
|
*/
|
||||||
|
public void cmdStatus(CommandSender sender) {
|
||||||
|
}
|
||||||
|
|
||||||
// add command examples for use the default "/wb" command list and for internal usage reference, formatted and colorized
|
// add command examples for use the default "/wb" command list and for internal usage reference, formatted and colorized
|
||||||
public void addCmdExample(String example)
|
public void addCmdExample(String example) {
|
||||||
{
|
|
||||||
addCmdExample(example, true, true, true);
|
addCmdExample(example, true, true, true);
|
||||||
}
|
}
|
||||||
public void addCmdExample(String example, boolean forPlayer, boolean forConsole, boolean prefix)
|
|
||||||
{
|
public void addCmdExample(String example, boolean forPlayer, boolean forConsole, boolean prefix) {
|
||||||
// go ahead and colorize required "<>" and optional "[]" parameters, extra command words, and description
|
// go ahead and colorize required "<>" and optional "[]" parameters, extra command words, and description
|
||||||
example = example.replace("<", C_REQ + "<").replace("[", C_OPT + "[").replace("^", C_CMD).replace("- ", C_DESC + "- ");
|
example = example.replace("<", C_REQ + "<").replace("[", C_OPT + "[").replace("^", C_CMD).replace("- ", C_DESC + "- ");
|
||||||
|
|
||||||
// all "{}" are replaced by "[]" (optional) for player, "<>" (required) for console
|
// all "{}" are replaced by "[]" (optional) for player, "<>" (required) for console
|
||||||
if (forPlayer)
|
if (forPlayer) {
|
||||||
{
|
|
||||||
String exampleP = (prefix ? CMD_P : "") + example.replace("{", C_OPT + "[").replace("}", "]");
|
String exampleP = (prefix ? CMD_P : "") + example.replace("{", C_OPT + "[").replace("}", "]");
|
||||||
cmdExamplePlayer.add(exampleP);
|
cmdExamplePlayer.add(exampleP);
|
||||||
cmdExamplesPlayer.add(exampleP);
|
cmdExamplesPlayer.add(exampleP);
|
||||||
}
|
}
|
||||||
if (forConsole)
|
if (forConsole) {
|
||||||
{
|
|
||||||
String exampleC = (prefix ? CMD_C : "") + example.replace("{", C_REQ + "<").replace("}", ">");
|
String exampleC = (prefix ? CMD_C : "") + example.replace("{", C_REQ + "<").replace("}", ">");
|
||||||
cmdExampleConsole.add(exampleC);
|
cmdExampleConsole.add(exampleC);
|
||||||
cmdExamplesConsole.add(exampleC);
|
cmdExamplesConsole.add(exampleC);
|
||||||
@ -92,38 +81,32 @@ public abstract class WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
// return root command formatted for player or console, based on sender
|
// return root command formatted for player or console, based on sender
|
||||||
public String cmd(CommandSender sender)
|
public String cmd(CommandSender sender) {
|
||||||
{
|
|
||||||
return (sender instanceof Player) ? CMD_P : CMD_C;
|
return (sender instanceof Player) ? CMD_P : CMD_C;
|
||||||
}
|
}
|
||||||
|
|
||||||
// formatted and colorized text, intended for marking command name
|
// formatted and colorized text, intended for marking command name
|
||||||
public String commandEmphasized(String text)
|
public String commandEmphasized(String text) {
|
||||||
{
|
|
||||||
return C_CMD + ChatColor.UNDERLINE + text + ChatColor.RESET + " ";
|
return C_CMD + ChatColor.UNDERLINE + text + ChatColor.RESET + " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns green "enabled" or red "disabled" text
|
// returns green "enabled" or red "disabled" text
|
||||||
public String enabledColored(boolean enabled)
|
public String enabledColored(boolean enabled) {
|
||||||
{
|
|
||||||
return enabled ? C_REQ + "enabled" : C_ERR + "disabled";
|
return enabled ? C_REQ + "enabled" : C_ERR + "disabled";
|
||||||
}
|
}
|
||||||
|
|
||||||
// formatted and colorized command name, optionally prefixed with "[world]" (for player) / "<world>" (for console)
|
// formatted and colorized command name, optionally prefixed with "[world]" (for player) / "<world>" (for console)
|
||||||
public String nameEmphasized()
|
public String nameEmphasized() {
|
||||||
{
|
|
||||||
return commandEmphasized(name);
|
return commandEmphasized(name);
|
||||||
}
|
}
|
||||||
public String nameEmphasizedW()
|
|
||||||
{
|
public String nameEmphasizedW() {
|
||||||
return "{world} " + nameEmphasized();
|
return "{world} " + nameEmphasized();
|
||||||
}
|
}
|
||||||
|
|
||||||
// send command example message(s) and other helpful info
|
// send command example message(s) and other helpful info
|
||||||
public void sendCmdHelp(CommandSender sender)
|
public void sendCmdHelp(CommandSender sender) {
|
||||||
{
|
for (String example : ((sender instanceof Player) ? cmdExamplePlayer : cmdExampleConsole)) {
|
||||||
for (String example : ((sender instanceof Player) ? cmdExamplePlayer : cmdExampleConsole))
|
|
||||||
{
|
|
||||||
sender.sendMessage(example);
|
sender.sendMessage(example);
|
||||||
}
|
}
|
||||||
cmdStatus(sender);
|
cmdStatus(sender);
|
||||||
@ -132,15 +115,13 @@ public abstract class WBCmd
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send error message followed by command example message(s)
|
// send error message followed by command example message(s)
|
||||||
public void sendErrorAndHelp(CommandSender sender, String error)
|
public void sendErrorAndHelp(CommandSender sender, String error) {
|
||||||
{
|
|
||||||
sender.sendMessage(C_ERR + error);
|
sender.sendMessage(C_ERR + error);
|
||||||
sendCmdHelp(sender);
|
sendCmdHelp(sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
// interpret string as boolean value (yes/no, true/false, on/off, +/-, 1/0)
|
// interpret string as boolean value (yes/no, true/false, on/off, +/-, 1/0)
|
||||||
public boolean strAsBool(String str)
|
public boolean strAsBool(String str) {
|
||||||
{
|
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
return str.startsWith("y") || str.startsWith("t") || str.startsWith("on") || str.startsWith("+") || str.startsWith("1");
|
return str.startsWith("y") || str.startsWith("t") || str.startsWith("on") || str.startsWith("+") || str.startsWith("1");
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
name: WorldBorder
|
name: WorldBorder
|
||||||
author: Brettflan
|
authors: [Brettflan, PryPurity]
|
||||||
description: Efficient, feature-rich plugin for limiting the size of your worlds.
|
description: Efficient, feature-rich plugin for limiting the size of your worlds.
|
||||||
version: 1.9.10 (beta)
|
version: 2.0.0 (beta)
|
||||||
api-version: 1.13
|
api-version: 1.13
|
||||||
main: com.wimbli.WorldBorder.WorldBorder
|
main: com.wimbli.WorldBorder.WorldBorder
|
||||||
softdepend:
|
softdepend:
|
||||||
|
Loading…
Reference in New Issue
Block a user