dynmap/DynmapCore/src/main/java/org/dynmap/exporter/DynmapExpCommands.java

311 lines
12 KiB
Java

package org.dynmap.exporter;
import java.io.File;
import java.util.HashMap;
import org.dynmap.DynmapCore;
import org.dynmap.DynmapLocation;
import org.dynmap.DynmapWorld;
import org.dynmap.MapManager;
import org.dynmap.common.DynmapCommandSender;
import org.dynmap.common.DynmapPlayer;
import org.dynmap.hdmap.HDShader;
/**
* Handler for export commands (/dynmapexp)
*/
public class DynmapExpCommands {
private HashMap<String, ExportContext> sessions = new HashMap<String, ExportContext>();
private static class ExportContext {
public String shader = "stdtexture";
public int xmin = Integer.MIN_VALUE;
public int ymin = Integer.MIN_VALUE;
public int zmin = Integer.MIN_VALUE;
public int xmax = Integer.MIN_VALUE;
public int ymax = Integer.MIN_VALUE;
public int zmax = Integer.MIN_VALUE;
public String world;
public boolean groupByChunk;
public boolean groupByBlockID;
public boolean groupByBlockIDData;
public boolean groupByTexture;
}
private String getContextID(DynmapCommandSender sender) {
String id = "<console>";
if (sender instanceof DynmapPlayer) {
id = ((DynmapPlayer)sender).getName();
}
return id;
}
private ExportContext getContext(DynmapCommandSender sender) {
String id = getContextID(sender);
ExportContext ctx = sessions.get(id);
if (ctx == null) {
ctx = new ExportContext();
sessions.put(id, ctx);
}
return ctx;
}
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;
if(!core.checkPlayerPermission(sender, "dynmapexp.export")) {
return true;
}
cmd = args[0];
boolean rslt = false;
ExportContext ctx = getContext(sender);
if(cmd.equalsIgnoreCase("set")) {
rslt = handleSetExport(sender, args, ctx, core);
}
else if (cmd.equalsIgnoreCase("radius")) {
rslt = handleRadius(sender, args, ctx, core);
}
else if (cmd.equalsIgnoreCase("pos0")) {
rslt = handlePosN(sender, args, ctx, core, 0);
}
else if (cmd.equalsIgnoreCase("pos1")) {
rslt = handlePosN(sender, args, ctx, core, 1);
}
else if (cmd.equalsIgnoreCase("export")) {
rslt = handleDoExport(sender, args, ctx, core);
}
else if(cmd.equalsIgnoreCase("reset")) {
rslt = handleResetExport(sender, args, ctx, core);
}
else if(cmd.equalsIgnoreCase("purge")) {
rslt = handlePurgeExport(sender, args, ctx, core);
}
else if(cmd.equalsIgnoreCase("info")) {
rslt = handleInfo(sender, args, ctx, core);
}
return rslt;
}
private boolean handleInfo(DynmapCommandSender sender, String[] args, ExportContext ctx, DynmapCore core) {
sender.sendMessage(String.format("Bounds: <%s,%s,%s> - <%s,%s,%s> on world '%s'", val(ctx.xmin), val(ctx.ymin), val(ctx.zmin),
val(ctx.xmax), val(ctx.ymax), val(ctx.zmax), ctx.world));
sender.sendMessage(String.format("groups: byChunk: %b, byBlockID: %b, byBlockIDData: %b, byTexture: %b", ctx.groupByChunk, ctx.groupByBlockID, ctx.groupByBlockIDData, ctx.groupByTexture));
return true;
}
private boolean handleSetExport(DynmapCommandSender sender, String[] args, ExportContext ctx, DynmapCore core) {
if (args.length < 3) {
sender.sendMessage(String.format("Bounds: <%s,%s,%s> - <%s,%s,%s> on world '%s'", val(ctx.xmin), val(ctx.ymin), val(ctx.zmin),
val(ctx.xmax), val(ctx.ymax), val(ctx.zmax), ctx.world));
return true;
}
for (int i = 1; i < (args.length-1); i += 2) {
try {
if (args[i].equals("x0")) {
ctx.xmin = Integer.parseInt(args[i+1]);
}
else if (args[i].equals("x1")) {
ctx.xmax = Integer.parseInt(args[i+1]);
}
else if (args[i].equals("y0")) {
ctx.ymin = Integer.parseInt(args[i+1]);
}
else if (args[i].equals("y1")) {
ctx.ymax = Integer.parseInt(args[i+1]);
}
else if (args[i].equals("z0")) {
ctx.zmin = Integer.parseInt(args[i+1]);
}
else if (args[i].equals("z1")) {
ctx.zmax = Integer.parseInt(args[i+1]);
}
else if (args[i].equals("world")) {
DynmapWorld w = core.getWorld(args[i+1]);
if (w != null) {
ctx.world = args[i+1];
}
else {
sender.sendMessage("Invalid world '" + args[i+1] + "'");
return true;
}
}
else if (args[i].equals("shader")) {
HDShader s = MapManager.mapman.hdmapman.shaders.get(args[i+1]);
if (s == null) {
sender.sendMessage("Unknown shader '" + args[i+1] + "'");
return true;
}
ctx.shader = args[i+1];
}
else if (args[i].equals("byChunk")) {
ctx.groupByChunk = args[i+1].equalsIgnoreCase("true");
}
else if (args[i].equals("byBlockID")) {
ctx.groupByBlockID = args[i+1].equalsIgnoreCase("true");
}
else if (args[i].equals("byBlockIDData")) {
ctx.groupByBlockIDData = args[i+1].equalsIgnoreCase("true");
}
else if (args[i].equals("byTexture")) {
ctx.groupByTexture = args[i+1].equalsIgnoreCase("true");
}
else { // Unknown setting
sender.sendMessage("Unknown setting '" + args[i] + "'");
return true;
}
} catch (NumberFormatException nfx) {
sender.sendMessage("Invalid value for '" + args[i] + "' - " + args[i+1]);
return true;
}
}
return handleInfo(sender, args, ctx, core);
}
private boolean handleRadius(DynmapCommandSender sender, String[] args, ExportContext ctx, DynmapCore core) {
if ((sender instanceof DynmapPlayer) == false) { // Not a player
sender.sendMessage("Only usable by player");
return true;
}
DynmapPlayer plyr = (DynmapPlayer) sender;
DynmapLocation loc = plyr.getLocation();
DynmapWorld world = null;
if (loc != null) {
world = core.getWorld(loc.world);
}
if (world == null) {
sender.sendMessage("Location not found for player");
return true;
}
int radius = 16;
if (args.length >= 2) {
try {
radius = Integer.parseInt(args[1]);
if (radius < 0) {
sender.sendMessage("Invalid radius - " + args[1]);
return true;
}
} catch (NumberFormatException nfx) {
sender.sendMessage("Invalid radius - " + args[1]);
return true;
}
}
ctx.xmin = (int)Math.floor(loc.x) - radius;
ctx.xmax = (int)Math.ceil(loc.x) + radius;
ctx.zmin = (int)Math.floor(loc.z) - radius;
ctx.zmax = (int)Math.ceil(loc.z) + radius;
ctx.ymin = 0;
ctx.ymax = world.worldheight - 1;
ctx.world = world.getName();
return handleInfo(sender, args, ctx, core);
}
private boolean handlePosN(DynmapCommandSender sender, String[] args, ExportContext ctx, DynmapCore core, int n) {
if ((sender instanceof DynmapPlayer) == false) { // Not a player
sender.sendMessage("Only usable by player");
return true;
}
DynmapPlayer plyr = (DynmapPlayer) sender;
DynmapLocation loc = plyr.getLocation();
DynmapWorld world = null;
if (loc != null) {
world = core.getWorld(loc.world);
}
if (world == null) {
sender.sendMessage("Location not found for player");
return true;
}
if (n == 0) {
ctx.xmin = (int)Math.floor(loc.x);
ctx.ymin = (int)Math.floor(loc.y);
ctx.zmin = (int)Math.floor(loc.z);
}
else {
ctx.xmax = (int)Math.floor(loc.x);
ctx.ymax = (int)Math.floor(loc.y);
ctx.zmax = (int)Math.floor(loc.z);
}
ctx.world = world.getName();
return handleInfo(sender, args, ctx, core);
}
private boolean handleDoExport(DynmapCommandSender sender, String[] args, ExportContext ctx, DynmapCore core) {
if ((ctx.world == null) || (ctx.xmin == Integer.MIN_VALUE) || (ctx.ymin == Integer.MIN_VALUE) ||
(ctx.zmin == Integer.MIN_VALUE) || (ctx.xmax == Integer.MIN_VALUE) || (ctx.ymax == Integer.MIN_VALUE) ||
(ctx.zmax == Integer.MIN_VALUE)) {
sender.sendMessage("Bounds not set");
return true;
}
DynmapWorld w = core.getWorld(ctx.world);
if (w == null) {
sender.sendMessage("Invalid world - " + ctx.world);
return true;
}
HDShader s = MapManager.mapman.hdmapman.shaders.get(ctx.shader);
if (s == null) {
sender.sendMessage("Invalid shader - " + ctx.shader);
return true;
}
String basename = "dynmapexp";
if (args.length > 1) {
basename = args[1];
}
basename = basename.replace('/', '_');
basename = basename.replace('\\', '_');
File f = new File(core.getExportFolder(), basename + ".zip");
int idx = 0;
String finalBasename = basename;
while (f.exists()) {
idx++;
finalBasename = basename + "_" + idx;
f = new File(core.getExportFolder(), finalBasename + ".zip");
}
sender.sendMessage("Exporting to " + f.getPath());
OBJExport exp = new OBJExport(f, s, w, core, finalBasename);
exp.setRenderBounds(ctx.xmin, ctx.ymin, ctx.zmin, ctx.xmax, ctx.ymax, ctx.zmax);
exp.setGroupEnabled(OBJExport.GROUP_CHUNK, ctx.groupByChunk);
exp.setGroupEnabled(OBJExport.GROUP_TEXTURE, ctx.groupByTexture);
exp.setGroupEnabled(OBJExport.GROUP_BLOCKID, ctx.groupByBlockID);
exp.setGroupEnabled(OBJExport.GROUP_BLOCKIDMETA, ctx.groupByBlockIDData);
MapManager.mapman.startOBJExport(exp, sender);
return true;
}
private boolean handleResetExport(DynmapCommandSender sender, String[] args, ExportContext ctx, DynmapCore core) {
sessions.remove(getContextID(sender));
return true;
}
private boolean handlePurgeExport(DynmapCommandSender sender, String[] args, ExportContext ctx, DynmapCore core) {
if (args.length > 1) {
String basename = args[1];
basename = basename.replace('/', '_');
basename = basename.replace('\\', '_');
File f = new File(core.getExportFolder(), basename + ".zip");
if (f.exists()) {
f.delete();
sender.sendMessage("Removed " + f.getPath());
}
else {
sender.sendMessage(f.getPath() + " not found");
}
}
return true;
}
private String val(int v) {
if (v == Integer.MIN_VALUE)
return "N/A";
else
return Integer.toString(v);
}
}