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>> 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 emptySupplier = () -> emptyValue; Supplier booleanSupplier = () -> booleanValue; Supplier hideStyleSupplier = () -> hideStyles; Supplier perspectiveSupplier = () -> perspectives; Supplier shaderSupplier = () -> shaders; Supplier lightingSupplier = () -> lightings; Supplier imageFormatSupplier = () -> imageFormats; //Arguments for /dmap worldset Map> 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> 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> 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 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 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 wnames = null; if(args.length > 1) { wnames = new HashSet(); 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(); } w.visibility_limits.add(newlimit); } else { if (w.hidden_limits == null) { w.hidden_limits = new ArrayList(); } 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 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 maps = new ArrayList(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 map = core.getServer().getBlockUniqueIDMap(); TreeSet keys = new TreeSet(map.keySet()); for (String k : keys) { sender.sendMessage(k + ": " + map.get(k)); } return true; } }