mirror of https://github.com/webbukkit/dynmap.git
311 lines
12 KiB
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);
|
|
}
|
|
}
|