mirror of https://github.com/webbukkit/dynmap.git
1064 lines
42 KiB
Java
1064 lines
42 KiB
Java
package org.dynmap;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.TreeSet;
|
|
import java.util.function.Supplier;
|
|
|
|
import org.dynmap.common.DynmapCommandSender;
|
|
import org.dynmap.common.DynmapPlayer;
|
|
import org.dynmap.hdmap.HDLighting;
|
|
import org.dynmap.hdmap.HDMap;
|
|
import org.dynmap.hdmap.HDPerspective;
|
|
import org.dynmap.hdmap.HDShader;
|
|
import org.dynmap.utils.MapChunkCache.HiddenChunkStyle;
|
|
import org.dynmap.utils.RectangleVisibilityLimit;
|
|
import org.dynmap.utils.RoundVisibilityLimit;
|
|
import org.dynmap.utils.VisibilityLimit;
|
|
|
|
/**
|
|
* Handler for world and map edit commands (via /dmap)
|
|
*/
|
|
public class DynmapMapCommands {
|
|
private Map<String, Map<String, Supplier<String[]>>> tabCompletions = null;
|
|
|
|
/**
|
|
* Generates a map of field:value argument tab completion suggestions for every /dmap subcommand
|
|
*/
|
|
private void initTabCompletions() {
|
|
//Static values
|
|
String[] emptyValue = new String[]{};
|
|
String[] booleanValue = new String[]{"true", "false"};
|
|
String[] hideStyles = Arrays.stream(HiddenChunkStyle.values()).map(HiddenChunkStyle::getValue)
|
|
.toArray(String[]::new);
|
|
String[] perspectives = MapManager.mapman.hdmapman.perspectives.keySet().toArray(new String[0]);
|
|
String[] shaders = MapManager.mapman.hdmapman.shaders.keySet().toArray(new String[0]);
|
|
String[] lightings = MapManager.mapman.hdmapman.lightings.keySet().toArray(new String[0]);
|
|
String[] imageFormats = Arrays.stream(MapType.ImageFormat.values())
|
|
.map(MapType.ImageFormat::getID).toArray(String[]::new);
|
|
|
|
Supplier<String[]> emptySupplier = () -> emptyValue;
|
|
Supplier<String[]> booleanSupplier = () -> booleanValue;
|
|
Supplier<String[]> hideStyleSupplier = () -> hideStyles;
|
|
Supplier<String[]> perspectiveSupplier = () -> perspectives;
|
|
Supplier<String[]> shaderSupplier = () -> shaders;
|
|
Supplier<String[]> lightingSupplier = () -> lightings;
|
|
Supplier<String[]> imageFormatSupplier = () -> imageFormats;
|
|
|
|
//Arguments for /dmap worldset
|
|
Map<String, Supplier<String[]>> worldSetArgs = new LinkedHashMap<>();
|
|
worldSetArgs.put("enabled", booleanSupplier);
|
|
worldSetArgs.put("title", emptySupplier);
|
|
worldSetArgs.put("order", emptySupplier);
|
|
worldSetArgs.put("center", emptySupplier);
|
|
worldSetArgs.put("sendposition", booleanSupplier);
|
|
worldSetArgs.put("sendhealth", booleanSupplier);
|
|
worldSetArgs.put("showborder", booleanSupplier);
|
|
worldSetArgs.put("protected", booleanSupplier);
|
|
worldSetArgs.put("extrazoomout", emptySupplier);
|
|
worldSetArgs.put("tileupdatedelay", emptySupplier);
|
|
|
|
//Arguments for /dmap worldaddlimit
|
|
Map<String, Supplier<String[]>> worldAddLimitArgs = new LinkedHashMap<>();
|
|
worldAddLimitArgs.put("type", () -> new String[]{"round", "rect"});
|
|
worldAddLimitArgs.put("limittype", () -> new String[]{"visible", "hidden"});
|
|
worldAddLimitArgs.put("style", hideStyleSupplier);
|
|
worldAddLimitArgs.put("corner1", emptySupplier);
|
|
worldAddLimitArgs.put("corner2", emptySupplier);
|
|
worldAddLimitArgs.put("center", emptySupplier);
|
|
worldAddLimitArgs.put("radius", emptySupplier);
|
|
|
|
//Arguments for /dmap mapadd/mapset
|
|
Map<String, Supplier<String[]>> mapSetArgs = new LinkedHashMap<>();
|
|
mapSetArgs.put("title", emptySupplier);
|
|
mapSetArgs.put("icon", emptySupplier);
|
|
mapSetArgs.put("order", emptySupplier);
|
|
mapSetArgs.put("prefix", emptySupplier);
|
|
mapSetArgs.put("perspective", perspectiveSupplier);
|
|
mapSetArgs.put("shader", shaderSupplier);
|
|
mapSetArgs.put("lighting", lightingSupplier);
|
|
mapSetArgs.put("img-format", imageFormatSupplier);
|
|
mapSetArgs.put("protected", booleanSupplier);
|
|
mapSetArgs.put("append-to-world", emptySupplier);
|
|
mapSetArgs.put("mapzoomin", emptySupplier);
|
|
mapSetArgs.put("mapzoomout", emptySupplier);
|
|
mapSetArgs.put("boostzoom", emptySupplier);
|
|
mapSetArgs.put("tilescale", emptySupplier);
|
|
mapSetArgs.put("tileupdatedelay", emptySupplier);
|
|
mapSetArgs.put("readonly", booleanSupplier);
|
|
|
|
tabCompletions = new HashMap<>();
|
|
tabCompletions.put("worldaddlimit", worldAddLimitArgs);
|
|
tabCompletions.put("worldset", worldSetArgs);
|
|
tabCompletions.put("mapset", mapSetArgs); //Also used for mapadd
|
|
}
|
|
|
|
private boolean checkIfActive(DynmapCore core, DynmapCommandSender sender) {
|
|
if ((!core.getPauseFullRadiusRenders()) || (!core.getPauseUpdateRenders())) {
|
|
sender.sendMessage("Cannot edit map data while rendering active - run '/dynmap pause all' to pause rendering");
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public boolean processCommand(DynmapCommandSender sender, String cmd, String commandLabel, String[] args, DynmapCore core) {
|
|
/* Re-parse args - handle doublequotes */
|
|
args = DynmapCore.parseArgs(args, sender);
|
|
if (args.length < 1)
|
|
return false;
|
|
cmd = args[0];
|
|
boolean rslt = false;
|
|
boolean edit = false;
|
|
|
|
if (cmd.equalsIgnoreCase("worldlist")) {
|
|
rslt = handleWorldList(sender, args, core);
|
|
}
|
|
else if (cmd.equalsIgnoreCase("perspectivelist")) {
|
|
rslt = handlePerspectiveList(sender, args, core);
|
|
}
|
|
else if (cmd.equalsIgnoreCase("shaderlist")) {
|
|
rslt = handleShaderList(sender, args, core);
|
|
}
|
|
else if (cmd.equalsIgnoreCase("lightinglist")) {
|
|
rslt = handleLightingList(sender, args, core);
|
|
}
|
|
else if (cmd.equalsIgnoreCase("maplist")) {
|
|
rslt = handleMapList(sender, args, core);
|
|
}
|
|
else if (cmd.equalsIgnoreCase("blocklist")) {
|
|
rslt = handleBlockList(sender, args, core);
|
|
}
|
|
else if (cmd.equalsIgnoreCase("worldgetlimits")) {
|
|
rslt = handleWorldGetLimits(sender, args, core);
|
|
}
|
|
else if (cmd.equalsIgnoreCase("worldremovelimit")) {
|
|
edit = true;
|
|
rslt = handleWorldRemoveLimit(sender, args, core);
|
|
}
|
|
else if (cmd.equalsIgnoreCase("worldaddlimit")) {
|
|
edit = true;
|
|
rslt = handleWorldAddLimit(sender, args, core);
|
|
}
|
|
else if (cmd.equalsIgnoreCase("worldset")) {
|
|
edit = true;
|
|
rslt = handleWorldSet(sender, args, core);
|
|
}
|
|
else if (cmd.equalsIgnoreCase("mapdelete")) {
|
|
edit = true;
|
|
rslt = handleMapDelete(sender, args, core);
|
|
}
|
|
else if (cmd.equalsIgnoreCase("worldreset")) {
|
|
edit = true;
|
|
rslt = handleWorldReset(sender, args, core);
|
|
}
|
|
else if (cmd.equalsIgnoreCase("mapset")) {
|
|
edit = true;
|
|
rslt = handleMapSet(sender, args, core, false);
|
|
}
|
|
else if (cmd.equalsIgnoreCase("mapadd")) {
|
|
edit = true;
|
|
rslt = handleMapSet(sender, args, core, true);
|
|
}
|
|
if (edit && rslt) {
|
|
sender.sendMessage("If you are done editing map data, run '/dynmap pause none' to resume rendering");
|
|
}
|
|
return rslt;
|
|
}
|
|
|
|
public List<String> getTabCompletions(DynmapCommandSender sender, String[] args, DynmapCore core) {
|
|
/* Re-parse args - handle doublequotes */
|
|
args = DynmapCore.parseArgs(args, sender, true);
|
|
|
|
if (args == null || args.length <= 1) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
if (tabCompletions == null) {
|
|
initTabCompletions();
|
|
}
|
|
|
|
String cmd = args[0];
|
|
|
|
if (cmd.equalsIgnoreCase("worldlist")
|
|
&& core.checkPlayerPermission(sender, "dmap.worldlist")) {
|
|
List<String> suggestions = core.getWorldSuggestions(args[args.length - 1]);
|
|
suggestions.removeAll(Arrays.asList(args)); //Remove suggestions present in other arguments
|
|
|
|
return suggestions;
|
|
} else if ((cmd.equalsIgnoreCase("maplist")
|
|
&& core.checkPlayerPermission(sender, "dmap.maplist"))
|
|
|| (cmd.equalsIgnoreCase("worldgetlimits")
|
|
&& core.checkPlayerPermission(sender, "dmap.worldlist"))) {
|
|
if (args.length == 2) {
|
|
return core.getWorldSuggestions(args[1]);
|
|
}
|
|
} else if (cmd.equalsIgnoreCase("worldremovelimit")
|
|
&& core.checkPlayerPermission(sender, "dmap.worldset")) {
|
|
if (args.length == 2) {
|
|
return core.getWorldSuggestions(args[1]);
|
|
}
|
|
} else if (cmd.equalsIgnoreCase("worldaddlimit")
|
|
&& core.checkPlayerPermission(sender, "dmap.worldset")) {
|
|
if (args.length == 2) {
|
|
return core.getWorldSuggestions(args[1]);
|
|
} else {
|
|
return core.getFieldValueSuggestions(args, tabCompletions.get("worldaddlimit"));
|
|
}
|
|
} else if (cmd.equalsIgnoreCase("worldset")
|
|
&& core.checkPlayerPermission(sender, "dmap.worldset")) {
|
|
if (args.length == 2) {
|
|
return core.getWorldSuggestions(args[1]);
|
|
} else {
|
|
return core.getFieldValueSuggestions(args, tabCompletions.get("worldset"));
|
|
}
|
|
} else if (cmd.equalsIgnoreCase("mapdelete")
|
|
&& core.checkPlayerPermission(sender, "dmap.mapdelete")) {
|
|
if (args.length == 2) {
|
|
return core.getMapSuggestions(args[1]);
|
|
}
|
|
} else if (cmd.equalsIgnoreCase("worldreset")
|
|
&& core.checkPlayerPermission(sender, "dmap.worldreset")) {
|
|
if (args.length == 2) {
|
|
return core.getWorldSuggestions(args[1]);
|
|
}
|
|
} else if (cmd.equalsIgnoreCase("mapset")
|
|
&& core.checkPlayerPermission(sender, "dmap.mapset")) {
|
|
if (args.length == 2) {
|
|
return core.getMapSuggestions(args[1]);
|
|
} else {
|
|
return core.getFieldValueSuggestions(args, tabCompletions.get("mapset"));
|
|
}
|
|
} else if (cmd.equalsIgnoreCase("mapadd")) {
|
|
if (args.length > 2) {
|
|
return core.getFieldValueSuggestions(args, tabCompletions.get("mapset"));
|
|
}
|
|
}
|
|
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
private boolean handleWorldList(DynmapCommandSender sender, String[] args, DynmapCore core) {
|
|
if(!core.checkPlayerPermission(sender, "dmap.worldlist"))
|
|
return true;
|
|
Set<String> wnames = null;
|
|
if(args.length > 1) {
|
|
wnames = new HashSet<String>();
|
|
for(int i = 1; i < args.length; i++)
|
|
wnames.add(DynmapWorld.normalizeWorldName(args[i]));
|
|
}
|
|
/* Get active worlds */
|
|
for(DynmapWorld w : core.getMapManager().getWorlds()) {
|
|
if((wnames != null) && (wnames.contains(w.getName()) == false)) {
|
|
continue;
|
|
}
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append("world ").append(w.getName()).append(": loaded=").append(w.isLoaded()).append(", enabled=").append(w.isEnabled());
|
|
sb.append(", title=").append(w.getTitle());
|
|
|
|
DynmapLocation loc = w.getCenterLocation();
|
|
if(loc != null) {
|
|
sb.append(", center=").append(loc.x).append("/").append(loc.y).append("/").append(loc.z);
|
|
}
|
|
sb.append(", extrazoomout=").append(w.getExtraZoomOutLevels()).append(", sendhealth=").append(w.sendhealth);
|
|
sb.append(", sendposition=").append(w.sendposition);
|
|
sb.append(", protected=").append(w.is_protected);
|
|
sb.append(", showborder=").append(w.showborder);
|
|
if(w.tileupdatedelay > 0) {
|
|
sb.append(", tileupdatedelay=").append(w.tileupdatedelay);
|
|
}
|
|
sender.sendMessage(sb.toString());
|
|
}
|
|
/* Get disabled worlds */
|
|
for(String wn : core.getMapManager().getDisabledWorlds()) {
|
|
if((wnames != null) && (wnames.contains(wn) == false)) {
|
|
continue;
|
|
}
|
|
sender.sendMessage("world " + wn + ": isenabled=false");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private boolean handleWorldGetLimits(DynmapCommandSender sender, String[] args, DynmapCore core) {
|
|
if(!core.checkPlayerPermission(sender, "dmap.worldlist"))
|
|
return true;
|
|
if(args.length < 2) {
|
|
sender.sendMessage("World ID required");
|
|
return true;
|
|
}
|
|
String world_id = args[1];
|
|
DynmapWorld w = core.getMapManager().getWorld(world_id);
|
|
if (w == null) {
|
|
sender.sendMessage(String.format("World %s not found", world_id));
|
|
return true;
|
|
}
|
|
sender.sendMessage("limits:");
|
|
int viscnt = 0;
|
|
if ((w.visibility_limits != null) && (w.visibility_limits.size() > 0)) {
|
|
viscnt = w.visibility_limits.size();
|
|
for (int i = 0; i < viscnt; i++) {
|
|
VisibilityLimit limit = w.visibility_limits.get(i);
|
|
if (limit instanceof RoundVisibilityLimit) {
|
|
RoundVisibilityLimit rlimit = (RoundVisibilityLimit) limit;
|
|
sender.sendMessage(String.format(" %d: limittype=visible, type=round, center=%d/%d, radius=%d", i, rlimit.x_center, rlimit.z_center, rlimit.radius));
|
|
}
|
|
else if (limit instanceof RectangleVisibilityLimit) {
|
|
RectangleVisibilityLimit rlimit = (RectangleVisibilityLimit) limit;
|
|
sender.sendMessage(String.format(" %d: limittype=visible, type=rect, corner1=%d/%d, corner2=%d/%d", i, rlimit.x_min, rlimit.z_min, rlimit.x_max, rlimit.z_max));
|
|
}
|
|
}
|
|
}
|
|
if ((w.hidden_limits != null) && (w.hidden_limits.size() > 0)) {
|
|
for (int i = 0; i < w.hidden_limits.size(); i++) {
|
|
VisibilityLimit limit = w.hidden_limits.get(i);
|
|
if (limit instanceof RoundVisibilityLimit) {
|
|
RoundVisibilityLimit rlimit = (RoundVisibilityLimit) limit;
|
|
sender.sendMessage(String.format(" %d: limittype=hidden, type=round, center=%d/%d, radius=%d", i + viscnt, rlimit.x_center, rlimit.z_center, rlimit.radius));
|
|
}
|
|
else if (limit instanceof RectangleVisibilityLimit) {
|
|
RectangleVisibilityLimit rlimit = (RectangleVisibilityLimit) limit;
|
|
sender.sendMessage(String.format(" %d: limittype=hidden, type=rect, corner1=%d/%d, corner2=%d/%d", i + viscnt, rlimit.x_min, rlimit.z_min, rlimit.x_max, rlimit.z_max));
|
|
}
|
|
}
|
|
}
|
|
sender.sendMessage("hiddenstyle: " + w.hiddenchunkstyle.getValue());
|
|
return true;
|
|
}
|
|
|
|
private boolean handleWorldAddLimit(DynmapCommandSender sender, String[] args, DynmapCore core) {
|
|
if(!core.checkPlayerPermission(sender, "dmap.worldset"))
|
|
return true;
|
|
if(args.length < 2) {
|
|
sender.sendMessage("World ID required");
|
|
return true;
|
|
}
|
|
/* Test if render active - quit if so */
|
|
if (checkIfActive(core, sender)) {
|
|
return true;
|
|
}
|
|
String world_id = args[1];
|
|
DynmapWorld w = core.getMapManager().getWorld(world_id);
|
|
if (w == null) {
|
|
sender.sendMessage(String.format("World %s not found", world_id));
|
|
return true;
|
|
}
|
|
String limittype = "visible";
|
|
String type = "rect"; // Default to rectangle
|
|
int corner1[] = null;
|
|
int corner2[] = null;
|
|
int center[] = null;
|
|
int radius = 0;
|
|
HiddenChunkStyle style = null;
|
|
// Other args are field:value
|
|
for (int argid = 2; argid < args.length; argid++) {
|
|
String[] argval = args[argid].split(":");
|
|
if (argval.length != 2) {
|
|
sender.sendMessage("Argument witout value: " + args[argid]);
|
|
return false;
|
|
}
|
|
String[] toks;
|
|
String id = argval[0];
|
|
String val = argval[1];
|
|
switch (id) {
|
|
case "type":
|
|
if ((val.equals("round")) || (val.equals("rect"))) {
|
|
type = val;
|
|
}
|
|
else {
|
|
sender.sendMessage("Bad type value: " + val);
|
|
return false;
|
|
}
|
|
break;
|
|
case "limittype":
|
|
if ((val.equals("visible")) || (val.equals("hidden"))) {
|
|
limittype = val;
|
|
}
|
|
else {
|
|
sender.sendMessage("Bad limittype value: " + val);
|
|
return false;
|
|
}
|
|
break;
|
|
case "corner1":
|
|
case "corner2":
|
|
case "center":
|
|
if ((type.equals("rect") && id.equals("center")) ||
|
|
(type.equals("round") && (!id.equals("center")))) {
|
|
sender.sendMessage("Bad parameter for type " + type + ": " + id);
|
|
return false;
|
|
}
|
|
toks = val.split("/");
|
|
if (toks.length == 2) {
|
|
int x = 0, z = 0;
|
|
x = Integer.valueOf(toks[0]);
|
|
z = Integer.valueOf(toks[1]);
|
|
switch (id) {
|
|
case "corner1":
|
|
corner1 = new int[] { x, z };
|
|
break;
|
|
case "corner2":
|
|
corner2 = new int[] { x, z };
|
|
break;
|
|
case "center":
|
|
center = new int[] { x, z };
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
sender.sendMessage("Bad value for parameter " + id + ": " + val);
|
|
return false;
|
|
}
|
|
break;
|
|
case "radius":
|
|
if (!type.equals("round")) {
|
|
sender.sendMessage("Bad parameter for type " + type + ": " + id);
|
|
return false;
|
|
}
|
|
radius = Integer.valueOf(val);
|
|
break;
|
|
case "style":
|
|
style = HiddenChunkStyle.fromValue(val);
|
|
if (style == null) {
|
|
sender.sendMessage("Bad parameter for style: " + val);
|
|
return false;
|
|
}
|
|
break;
|
|
default:
|
|
sender.sendMessage("Bad parameter: " + id);
|
|
return false;
|
|
}
|
|
}
|
|
// If enough for rectange area, add it
|
|
VisibilityLimit newlimit = null;
|
|
if ((type.contentEquals("rect") && (corner1 != null) && (corner2 != null))) {
|
|
newlimit = new RectangleVisibilityLimit(corner1[0], corner1[1], corner2[0], corner2[1]);
|
|
}
|
|
else if ((type.contentEquals("round") && (center != null) && (radius > 0.0))) {
|
|
newlimit = new RoundVisibilityLimit(center[0], center[1], radius);
|
|
}
|
|
boolean updated = false;
|
|
if (newlimit != null) {
|
|
if (limittype.contentEquals("visible")) {
|
|
if (w.visibility_limits == null) { w.visibility_limits = new ArrayList<VisibilityLimit>(); }
|
|
w.visibility_limits.add(newlimit);
|
|
}
|
|
else {
|
|
if (w.hidden_limits == null) { w.hidden_limits = new ArrayList<VisibilityLimit>(); }
|
|
w.hidden_limits.add(newlimit);
|
|
}
|
|
updated = true;
|
|
}
|
|
// If new style, apply it
|
|
if (style != null) {
|
|
w.hiddenchunkstyle = style;
|
|
updated = true;
|
|
}
|
|
// Apply update
|
|
if (updated) {
|
|
core.updateWorldConfig(w);
|
|
sender.sendMessage("Refreshing configuration for world " + world_id);
|
|
core.refreshWorld(world_id);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private boolean handleWorldRemoveLimit(DynmapCommandSender sender, String[] args, DynmapCore core) {
|
|
if(!core.checkPlayerPermission(sender, "dmap.worldset"))
|
|
return true;
|
|
if(args.length < 3) {
|
|
sender.sendMessage("World ID and limit index required");
|
|
return true;
|
|
}
|
|
/* Test if render active - quit if so */
|
|
if (checkIfActive(core, sender)) {
|
|
return true;
|
|
}
|
|
String world_id = args[1];
|
|
DynmapWorld w = core.getMapManager().getWorld(world_id);
|
|
if (w == null) {
|
|
sender.sendMessage(String.format("World %s not found", world_id));
|
|
return true;
|
|
}
|
|
boolean updated = false;
|
|
String idx = args[2];
|
|
int idxnum = Integer.valueOf(idx);
|
|
int viscnt = (w.visibility_limits != null) ? w.visibility_limits.size() : 0;
|
|
if ((idxnum >= 0) && (idxnum < viscnt)) {
|
|
w.visibility_limits.remove(idxnum);
|
|
if (w.visibility_limits.size() == 0) {
|
|
w.visibility_limits = null;
|
|
}
|
|
updated = true;
|
|
}
|
|
else {
|
|
idxnum -= viscnt;
|
|
if ((idxnum >= 0) && (w.hidden_limits != null) && (idxnum < w.hidden_limits.size())) {
|
|
w.hidden_limits.remove(idxnum);
|
|
if (w.hidden_limits.size() == 0) {
|
|
w.hidden_limits = null;
|
|
}
|
|
updated = true;
|
|
}
|
|
}
|
|
// Apply update
|
|
if (updated) {
|
|
core.updateWorldConfig(w);
|
|
sender.sendMessage("Refreshing configuration for world " + world_id);
|
|
core.refreshWorld(world_id);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private boolean handleWorldSet(DynmapCommandSender sender, String[] args, DynmapCore core) {
|
|
if(!core.checkPlayerPermission(sender, "dmap.worldset"))
|
|
return true;
|
|
if(args.length < 3) {
|
|
sender.sendMessage("World name and setting:newvalue required");
|
|
return true;
|
|
}
|
|
String wname = args[1]; /* Get world name */
|
|
/* Test if render active - quit if so */
|
|
if (checkIfActive(core, sender)) {
|
|
return true;
|
|
}
|
|
|
|
DynmapWorld w = core.getWorld(wname); /* Try to get world */
|
|
|
|
boolean did_update = false;
|
|
for(int i = 2; i < args.length; i++) {
|
|
String[] tok = args[i].split(":"); /* Split at colon */
|
|
if(tok.length != 2) {
|
|
sender.sendMessage("Syntax error: " + args[i]);
|
|
return false;
|
|
}
|
|
if(tok[0].equalsIgnoreCase("enabled")) {
|
|
did_update |= core.setWorldEnable(wname, !tok[1].equalsIgnoreCase("false"));
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("title")) {
|
|
if(w == null) {
|
|
sender.sendMessage("Cannot set extrazoomout on disabled or undefined world");
|
|
return true;
|
|
}
|
|
w.setTitle(tok[1]);
|
|
core.updateWorldConfig(w);
|
|
did_update = true;
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("sendposition")) {
|
|
if(w == null) {
|
|
sender.sendMessage("Cannot set sendposition on disabled or undefined world");
|
|
return true;
|
|
}
|
|
w.sendposition = tok[1].equals("true");
|
|
core.updateWorldConfig(w);
|
|
did_update = true;
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("sendhealth")) {
|
|
if(w == null) {
|
|
sender.sendMessage("Cannot set sendhealth on disabled or undefined world");
|
|
return true;
|
|
}
|
|
w.sendhealth = tok[1].equals("true");
|
|
core.updateWorldConfig(w);
|
|
did_update = true;
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("showborder")) {
|
|
if(w == null) {
|
|
sender.sendMessage("Cannot set sendworldborder on disabled or undefined world");
|
|
return true;
|
|
}
|
|
w.showborder = tok[1].equals("true");
|
|
core.updateWorldConfig(w);
|
|
did_update = true;
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("protected")) {
|
|
if(w == null) {
|
|
sender.sendMessage("Cannot set protected on disabled or undefined world");
|
|
return true;
|
|
}
|
|
w.is_protected = tok[1].equals("true");
|
|
core.updateWorldConfig(w);
|
|
did_update = true;
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("extrazoomout")) { /* Extrazoomout setting */
|
|
if(w == null) {
|
|
sender.sendMessage("Cannot set extrazoomout on disabled or undefined world");
|
|
return true;
|
|
}
|
|
int exo = -1;
|
|
try {
|
|
exo = Integer.valueOf(tok[1]);
|
|
} catch (NumberFormatException nfx) {}
|
|
if((exo < 0) || (exo > 32)) {
|
|
sender.sendMessage("Invalid value for extrazoomout: " + tok[1]);
|
|
return true;
|
|
}
|
|
did_update |= core.setWorldZoomOut(wname, exo);
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("tileupdatedelay")) { /* tileupdatedelay setting */
|
|
if(w == null) {
|
|
sender.sendMessage("Cannot set tileupdatedelay on disabled or undefined world");
|
|
return true;
|
|
}
|
|
int tud = -1;
|
|
try {
|
|
tud = Integer.valueOf(tok[1]);
|
|
} catch (NumberFormatException nfx) {}
|
|
did_update |= core.setWorldTileUpdateDelay(wname, tud);
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("center")) { /* Center */
|
|
if(w == null) {
|
|
sender.sendMessage("Cannot set center on disabled or undefined world");
|
|
return true;
|
|
}
|
|
boolean good = false;
|
|
DynmapLocation loc = null;
|
|
try {
|
|
String[] toks = tok[1].split("/");
|
|
if(toks.length == 3) {
|
|
double x = 0, y = 0, z = 0;
|
|
x = Double.valueOf(toks[0]);
|
|
y = Double.valueOf(toks[1]);
|
|
z = Double.valueOf(toks[2]);
|
|
loc = new DynmapLocation(wname, x, y, z);
|
|
good = true;
|
|
}
|
|
else if(tok[1].equalsIgnoreCase("default")) {
|
|
good = true;
|
|
}
|
|
else if(tok[1].equalsIgnoreCase("here")) {
|
|
if(sender instanceof DynmapPlayer) {
|
|
loc = ((DynmapPlayer)sender).getLocation();
|
|
good = true;
|
|
}
|
|
else {
|
|
sender.sendMessage("Setting center to 'here' requires player");
|
|
return true;
|
|
}
|
|
}
|
|
} catch (NumberFormatException nfx) {}
|
|
if(!good) {
|
|
sender.sendMessage("Center value must be formatted x/y/z or be set to 'default' or 'here'");
|
|
return true;
|
|
}
|
|
did_update |= core.setWorldCenter(wname, loc);
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("order")) {
|
|
if(w == null) {
|
|
sender.sendMessage("Cannot set order on disabled or undefined world");
|
|
return true;
|
|
}
|
|
int order = -1;
|
|
try {
|
|
order = Integer.valueOf(tok[1]);
|
|
} catch (NumberFormatException nfx) {}
|
|
if(order < 1) {
|
|
sender.sendMessage("Order value must be number from 1 to number of worlds");
|
|
return true;
|
|
}
|
|
did_update |= core.setWorldOrder(wname, order-1);
|
|
}
|
|
}
|
|
/* If world updatd, refresh it */
|
|
if(did_update) {
|
|
sender.sendMessage("Refreshing configuration for world " + wname);
|
|
core.refreshWorld(wname);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private boolean handleMapList(DynmapCommandSender sender, String[] args, DynmapCore core) {
|
|
if(!core.checkPlayerPermission(sender, "dmap.maplist"))
|
|
return true;
|
|
if(args.length < 2) {
|
|
sender.sendMessage("World name is required");
|
|
return true;
|
|
}
|
|
String wname = args[1]; /* Get world name */
|
|
|
|
DynmapWorld w = core.getWorld(wname); /* Try to get world */
|
|
if(w == null) {
|
|
sender.sendMessage("Only loaded world can be listed");
|
|
return true;
|
|
}
|
|
List<MapType> maps = w.maps;
|
|
for(MapType mt : maps) {
|
|
if(mt instanceof HDMap) {
|
|
HDMap hdmt = (HDMap)mt;
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append("map ").append(mt.getName()).append(": prefix=").append(hdmt.getPrefix()).append(", title=").append(hdmt.getTitle());
|
|
sb.append(", perspective=").append(hdmt.getPerspective().getName()).append(", shader=").append(hdmt.getShader().getName());
|
|
sb.append(", lighting=").append(hdmt.getLighting().getName()).append(", mapzoomin=").append(hdmt.getMapZoomIn()).append(", mapzoomout=").append(hdmt.getMapZoomOutLevels());
|
|
sb.append(", img-format=").append(hdmt.getImageFormatSetting()).append(", icon=").append(hdmt.getIcon());
|
|
sb.append(", append-to-world=").append(hdmt.getAppendToWorld()).append(", boostzoom=").append(hdmt.getBoostZoom());
|
|
sb.append(", protected=").append(hdmt.isProtected()).append(", tilescale=").append(hdmt.getTileScale()).append(", readonly=").append(hdmt.isReadOnly());
|
|
if(hdmt.tileupdatedelay > 0) {
|
|
sb.append(", tileupdatedelay=").append(hdmt.tileupdatedelay);
|
|
}
|
|
sender.sendMessage(sb.toString());
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private boolean handleMapDelete(DynmapCommandSender sender, String[] args, DynmapCore core) {
|
|
if(!core.checkPlayerPermission(sender, "dmap.mapdelete"))
|
|
return true;
|
|
if (checkIfActive(core, sender)) {
|
|
return false;
|
|
}
|
|
if(args.length < 2) {
|
|
sender.sendMessage("World:map name required");
|
|
return true;
|
|
}
|
|
for(int i = 1; i < args.length; i++) {
|
|
String world_map_name = args[i];
|
|
String[] tok = world_map_name.split(":");
|
|
if(tok.length != 2) {
|
|
sender.sendMessage("Invalid world:map name: " + world_map_name);
|
|
return true;
|
|
}
|
|
String wname = tok[0];
|
|
String mname = tok[1];
|
|
DynmapWorld w = core.getWorld(wname); /* Try to get world */
|
|
if(w == null) {
|
|
sender.sendMessage("Cannot delete maps from disabled or unloaded world: " + wname);
|
|
return true;
|
|
}
|
|
List<MapType> maps = new ArrayList<MapType>(w.maps);
|
|
boolean done = false;
|
|
for(int idx = 0; (!done) && (idx < maps.size()); idx++) {
|
|
MapType mt = maps.get(idx);
|
|
if(mt.getName().equals(mname)) {
|
|
w.maps.remove(mt);
|
|
done = true;
|
|
}
|
|
}
|
|
/* If done, save updated config for world */
|
|
if(done) {
|
|
if(core.updateWorldConfig(w)) {
|
|
sender.sendMessage("Refreshing configuration for world " + wname);
|
|
core.refreshWorld(wname);
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private boolean handleWorldReset(DynmapCommandSender sender, String[] args, DynmapCore core) {
|
|
if(!core.checkPlayerPermission(sender, "dmap.worldreset"))
|
|
return true;
|
|
if (checkIfActive(core, sender)) {
|
|
return false;
|
|
}
|
|
if(args.length < 2) {
|
|
sender.sendMessage("World name required");
|
|
return true;
|
|
}
|
|
String wname = args[1]; /* Get world name */
|
|
|
|
DynmapWorld w = core.getWorld(wname); /* Try to get world */
|
|
/* If not loaded, cannot reset */
|
|
if(w == null) {
|
|
sender.sendMessage("Cannot reset world that is not loaded or enabled");
|
|
return true;
|
|
}
|
|
ConfigurationNode cn = null;
|
|
if(args.length > 2) {
|
|
cn = core.getTemplateConfigurationNode(args[2]);
|
|
}
|
|
else { /* Else get default */
|
|
cn = core.getDefaultTemplateConfigurationNode(w);
|
|
}
|
|
if(cn == null) {
|
|
sender.sendMessage("Cannot load template");
|
|
return true;
|
|
}
|
|
ConfigurationNode cfg = w.saveConfiguration(); /* Get configuration */
|
|
cfg.extend(cn); /* And apply template */
|
|
|
|
/* And set world config */
|
|
if(core.replaceWorldConfig(wname, cfg)) {
|
|
sender.sendMessage("Reset configuration for world " + wname);
|
|
core.refreshWorld(wname);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private boolean handleMapSet(DynmapCommandSender sender, String[] args, DynmapCore core, boolean isnew) {
|
|
if(!core.checkPlayerPermission(sender, isnew?"dmap.mapadd":"dmap.mapset"))
|
|
return true;
|
|
if (checkIfActive(core, sender)) {
|
|
return false;
|
|
}
|
|
if(args.length < 2) {
|
|
sender.sendMessage("World:map name required");
|
|
return true;
|
|
}
|
|
String world_map_name = args[1];
|
|
String[] tok = world_map_name.split(":");
|
|
if(tok.length != 2) {
|
|
sender.sendMessage("Invalid world:map name: " + world_map_name);
|
|
return true;
|
|
}
|
|
String wname = tok[0];
|
|
String mname = tok[1];
|
|
|
|
DynmapWorld w = core.getWorld(wname); /* Try to get world */
|
|
if(w == null) {
|
|
sender.sendMessage("Cannot update maps from disabled or unloaded world: " + wname);
|
|
return true;
|
|
}
|
|
HDMap mt = null;
|
|
/* Find the map */
|
|
for(MapType map : w.maps) {
|
|
if(map instanceof HDMap) {
|
|
if(map.getName().equals(mname)) {
|
|
mt = (HDMap)map;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/* If new, make default map instance */
|
|
if(isnew) {
|
|
if(mt != null) {
|
|
sender.sendMessage("Map " + mname + " already exists on world " + wname);
|
|
return true;
|
|
}
|
|
ConfigurationNode cn = new ConfigurationNode();
|
|
cn.put("name", mname);
|
|
mt = new HDMap(core, cn);
|
|
if(mt.getName() != null) {
|
|
w.maps.add(mt); /* Add to end, by default */
|
|
}
|
|
else {
|
|
sender.sendMessage("Map " + mname + " not valid");
|
|
return true;
|
|
}
|
|
}
|
|
else {
|
|
if(mt == null) {
|
|
sender.sendMessage("Map " + mname + " not found on world " + wname);
|
|
return true;
|
|
}
|
|
}
|
|
boolean did_update = isnew;
|
|
for(int i = 2; i < args.length; i++) {
|
|
tok = args[i].split(":", 2); /* Split at colon */
|
|
if(tok.length < 2) {
|
|
String[] newtok = new String[2];
|
|
newtok[0] = tok[0];
|
|
newtok[1] = "";
|
|
tok = newtok;
|
|
}
|
|
if(tok[0].equalsIgnoreCase("prefix")) {
|
|
/* Check to make sure prefix is unique */
|
|
for(MapType map : w.maps){
|
|
if(map == mt) continue;
|
|
if(map instanceof HDMap) {
|
|
if(((HDMap)map).getPrefix().equals(tok[1])) {
|
|
sender.sendMessage("Prefix " + tok[1] + " already in use");
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
did_update |= mt.setPrefix(tok[1]);
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("title")) {
|
|
did_update |= mt.setTitle(tok[1]);
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("icon")) {
|
|
did_update |= mt.setIcon(tok[1]);
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("mapzoomin")) {
|
|
int mzi = -1;
|
|
try {
|
|
mzi = Integer.valueOf(tok[1]);
|
|
} catch (NumberFormatException nfx) {
|
|
}
|
|
if((mzi < 0) || (mzi > 32)) {
|
|
sender.sendMessage("Invalid mapzoomin value: " + tok[1]);
|
|
return true;
|
|
}
|
|
did_update |= mt.setMapZoomIn(mzi);
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("mapzoomout")) {
|
|
int mzi = -1;
|
|
try {
|
|
mzi = Integer.valueOf(tok[1]);
|
|
} catch (NumberFormatException nfx) {
|
|
}
|
|
if((mzi < 0) || (mzi > 32)) {
|
|
sender.sendMessage("Invalid mapzoomout value: " + tok[1]);
|
|
return true;
|
|
}
|
|
did_update |= mt.setMapZoomOut(mzi);
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("boostzoom")) {
|
|
int mzi = -1;
|
|
try {
|
|
mzi = Integer.valueOf(tok[1]);
|
|
} catch (NumberFormatException nfx) {
|
|
}
|
|
if((mzi < 0) || (mzi > 3)) {
|
|
sender.sendMessage("Invalid boostzoom value: " + tok[1]);
|
|
return true;
|
|
}
|
|
did_update |= mt.setBoostZoom(mzi);
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("tilescale")) {
|
|
int mzi = -1;
|
|
try {
|
|
mzi = Integer.valueOf(tok[1]);
|
|
} catch (NumberFormatException nfx) {
|
|
}
|
|
if((mzi < 0) || (mzi > 4)) {
|
|
sender.sendMessage("Invalid tilescale value: " + tok[1]);
|
|
return true;
|
|
}
|
|
did_update |= mt.setTileScale(mzi);
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("tileupdatedelay")) {
|
|
int tud = -1;
|
|
try {
|
|
tud = Integer.valueOf(tok[1]);
|
|
} catch (NumberFormatException nfx) {
|
|
}
|
|
did_update |= mt.setTileUpdateDelay(tud);
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("perspective")) {
|
|
if(MapManager.mapman != null) {
|
|
HDPerspective p = MapManager.mapman.hdmapman.perspectives.get(tok[1]);
|
|
if(p == null) {
|
|
sender.sendMessage("Perspective not found: " + tok[1]);
|
|
return true;
|
|
}
|
|
did_update |= mt.setPerspective(p);
|
|
}
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("shader")) {
|
|
if(MapManager.mapman != null) {
|
|
HDShader s = MapManager.mapman.hdmapman.shaders.get(tok[1]);
|
|
if(s == null) {
|
|
sender.sendMessage("Shader not found: " + tok[1]);
|
|
return true;
|
|
}
|
|
did_update |= mt.setShader(s);
|
|
}
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("lighting")) {
|
|
if(MapManager.mapman != null) {
|
|
HDLighting l = MapManager.mapman.hdmapman.lightings.get(tok[1]);
|
|
if(l == null) {
|
|
sender.sendMessage("Lighting not found: " + tok[1]);
|
|
return true;
|
|
}
|
|
did_update |= mt.setLighting(l);
|
|
}
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("img-format")) {
|
|
if((!tok[1].equals("default")) && (MapType.ImageFormat.fromID(tok[1]) == null)) {
|
|
sender.sendMessage("Image format not found: " + tok[1]);
|
|
return true;
|
|
}
|
|
did_update |= mt.setImageFormatSetting(tok[1]);
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("order")) {
|
|
int idx = -1;
|
|
try {
|
|
idx = Integer.valueOf(tok[1]);
|
|
} catch (NumberFormatException nfx) {
|
|
}
|
|
if(idx < 1) {
|
|
sender.sendMessage("Invalid order position: " + tok[1]);
|
|
return true;
|
|
}
|
|
idx--;
|
|
/* Remove and insert at position */
|
|
w.maps.remove(mt);
|
|
if(idx < w.maps.size())
|
|
w.maps.add(idx, mt);
|
|
else
|
|
w.maps.add(mt);
|
|
did_update = true;
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("append-to-world")) {
|
|
did_update |= mt.setAppendToWorld(tok[1]);
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("protected")) {
|
|
did_update |= mt.setProtected(Boolean.parseBoolean(tok[1]));
|
|
}
|
|
else if(tok[0].equalsIgnoreCase("readonly")) {
|
|
did_update |= mt.setReadOnly(Boolean.parseBoolean(tok[1]));
|
|
}
|
|
}
|
|
if(did_update) {
|
|
if(core.updateWorldConfig(w)) {
|
|
sender.sendMessage("Refreshing configuration for world " + wname);
|
|
core.refreshWorld(wname);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private boolean handlePerspectiveList(DynmapCommandSender sender, String[] args, DynmapCore core) {
|
|
if(!core.checkPlayerPermission(sender, "dmap.perspectivelist"))
|
|
return true;
|
|
if(MapManager.mapman != null) {
|
|
StringBuilder sb = new StringBuilder();
|
|
for(HDPerspective p : MapManager.mapman.hdmapman.perspectives.values()) {
|
|
sb.append(p.getName()).append(' ');
|
|
}
|
|
sender.sendMessage(sb.toString());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private boolean handleShaderList(DynmapCommandSender sender, String[] args, DynmapCore core) {
|
|
if(!core.checkPlayerPermission(sender, "dmap.shaderlist"))
|
|
return true;
|
|
if(MapManager.mapman != null) {
|
|
StringBuilder sb = new StringBuilder();
|
|
for(HDShader p : MapManager.mapman.hdmapman.shaders.values()) {
|
|
sb.append(p.getName()).append(' ');
|
|
}
|
|
sender.sendMessage(sb.toString());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private boolean handleLightingList(DynmapCommandSender sender, String[] args, DynmapCore core) {
|
|
if(!core.checkPlayerPermission(sender, "dmap.lightinglist"))
|
|
return true;
|
|
if(MapManager.mapman != null) {
|
|
StringBuilder sb = new StringBuilder();
|
|
for(HDLighting p : MapManager.mapman.hdmapman.lightings.values()) {
|
|
sb.append(p.getName()).append(' ');
|
|
}
|
|
sender.sendMessage(sb.toString());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private boolean handleBlockList(DynmapCommandSender sender, String[] args, DynmapCore core) {
|
|
if(!core.checkPlayerPermission(sender, "dmap.blklist"))
|
|
return true;
|
|
Map<String, Integer> map = core.getServer().getBlockUniqueIDMap();
|
|
TreeSet<String> keys = new TreeSet<String>(map.keySet());
|
|
for (String k : keys) {
|
|
sender.sendMessage(k + ": " + map.get(k));
|
|
}
|
|
return true;
|
|
}
|
|
}
|