mirror of https://github.com/webbukkit/dynmap.git
483 lines
17 KiB
Java
483 lines
17 KiB
Java
package org.dynmap.hdmap;
|
|
|
|
import static org.dynmap.JSONUtils.a;
|
|
import static org.dynmap.JSONUtils.s;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import org.dynmap.Client;
|
|
import org.dynmap.ConfigurationNode;
|
|
import org.dynmap.DynmapChunk;
|
|
import org.dynmap.DynmapCore;
|
|
import org.dynmap.DynmapWorld;
|
|
import org.dynmap.Log;
|
|
import org.dynmap.MapManager;
|
|
import org.dynmap.MapTile;
|
|
import org.dynmap.MapType;
|
|
import org.dynmap.storage.MapStorage;
|
|
import org.dynmap.storage.MapStorageTile;
|
|
import org.dynmap.storage.MapStorageTileEnumCB;
|
|
import org.dynmap.utils.TileFlags;
|
|
import org.json.simple.JSONObject;
|
|
|
|
public class HDMap extends MapType {
|
|
|
|
private String name;
|
|
private String prefix;
|
|
private HDPerspective perspective;
|
|
private HDShader shader;
|
|
private HDLighting lighting;
|
|
// private ConfigurationNode configuration;
|
|
private int mapzoomout;
|
|
private String imgfmtstring;
|
|
private MapType.ImageFormat imgformat;
|
|
private int bgcolornight;
|
|
private int bgcolorday;
|
|
private int tilescale;
|
|
private String title;
|
|
private String icon;
|
|
private String bg_cfg;
|
|
private String bg_day_cfg;
|
|
private String bg_night_cfg;
|
|
private String append_to_world;
|
|
private int mapzoomin;
|
|
private int boostzoom;
|
|
public DynmapCore core;
|
|
|
|
public static final String IMGFORMAT_PNG = "png";
|
|
public static final String IMGFORMAT_JPG = "jpg";
|
|
|
|
|
|
public HDMap(DynmapCore core, ConfigurationNode configuration) {
|
|
this.core = core;
|
|
name = configuration.getString("name", null);
|
|
if(name == null) {
|
|
Log.severe("HDMap missing required attribute 'name' - disabled");
|
|
return;
|
|
}
|
|
String perspectiveid = configuration.getString("perspective", "default");
|
|
perspective = MapManager.mapman.hdmapman.perspectives.get(perspectiveid);
|
|
if(perspective == null) {
|
|
/* Try to use default */
|
|
perspective = MapManager.mapman.hdmapman.perspectives.get("default");
|
|
if(perspective == null) {
|
|
Log.severe("HDMap '"+name+"' loaded invalid perspective '" + perspectiveid + "' - map disabled");
|
|
name = null;
|
|
return;
|
|
}
|
|
else {
|
|
Log.severe("HDMap '"+name+"' loaded invalid perspective '" + perspectiveid + "' - using 'default' perspective");
|
|
}
|
|
}
|
|
String shaderid = configuration.getString("shader", "default");
|
|
shader = MapManager.mapman.hdmapman.shaders.get(shaderid);
|
|
if(shader == null) {
|
|
shader = MapManager.mapman.hdmapman.shaders.get("default");
|
|
if(shader == null) {
|
|
Log.severe("HDMap '"+name+"' loading invalid shader '" + shaderid + "' - map disabled");
|
|
name = null;
|
|
return;
|
|
}
|
|
else {
|
|
Log.severe("HDMap '"+name+"' loading invalid shader '" + shaderid + "' - using 'default' shader");
|
|
}
|
|
}
|
|
String lightingid = configuration.getString("lighting", "default");
|
|
lighting = MapManager.mapman.hdmapman.lightings.get(lightingid);
|
|
if(lighting == null) {
|
|
lighting = MapManager.mapman.hdmapman.lightings.get("default");
|
|
if(lighting == null) {
|
|
Log.severe("HDMap '"+name+"' loading invalid lighting '" + lighting + "' - map disabled");
|
|
name = null;
|
|
return;
|
|
}
|
|
else {
|
|
Log.severe("HDMap '"+name+"' loading invalid lighting '" + lighting + "' - using 'default' lighting");
|
|
}
|
|
}
|
|
prefix = configuration.getString("prefix", name);
|
|
|
|
/* Compute extra zoom outs needed for this map */
|
|
double scale = perspective.getScale();
|
|
mapzoomout = 0;
|
|
while(scale >= 1.0) {
|
|
mapzoomout++;
|
|
scale = scale / 2.0;
|
|
}
|
|
imgfmtstring = configuration.getString("image-format", "default");
|
|
if(imgfmtstring.equals("default")) {
|
|
imgformat = ImageFormat.fromID(core.getDefImageFormat());
|
|
}
|
|
else {
|
|
imgformat = ImageFormat.fromID(imgfmtstring);
|
|
}
|
|
if(imgformat == null) {
|
|
Log.severe("HDMap '"+name+"' set invalid image-format: " + imgfmtstring);
|
|
imgformat = ImageFormat.FORMAT_PNG;
|
|
}
|
|
/* Get color info */
|
|
String c = configuration.getString("background");
|
|
if(c != null) {
|
|
bgcolorday = bgcolornight = parseColor(c);
|
|
}
|
|
c = configuration.getString("backgroundday");
|
|
if(c != null) {
|
|
bgcolorday = parseColor(c);
|
|
}
|
|
c = configuration.getString("backgroundnight");
|
|
if(c != null) {
|
|
bgcolornight = parseColor(c);
|
|
}
|
|
if(imgformat != ImageFormat.FORMAT_PNG) { /* If JPG, set background color opacity */
|
|
bgcolorday |= 0xFF000000;
|
|
bgcolornight |= 0xFF000000;
|
|
}
|
|
this.title = configuration.getString("title", name);
|
|
this.icon = configuration.getString("icon");
|
|
this.bg_cfg = configuration.getString("background");
|
|
this.bg_day_cfg = configuration.getString("backgroundday");
|
|
this.bg_night_cfg = configuration.getString("backgroundnight");
|
|
this.mapzoomin = configuration.getInteger("mapzoomin", 2);
|
|
this.mapzoomout = configuration.getInteger("mapzoomout", this.mapzoomout);
|
|
this.boostzoom = configuration.getInteger("boostzoom", 0);
|
|
this.tilescale = configuration.getInteger("tilescale", core.getMapManager().getDefaultTileScale()); // 0 = 128, 1 = 256, ...
|
|
if (this.tilescale <= 0) this.tilescale = 0;
|
|
if (this.tilescale >= 4) this.tilescale = 4; // Limit to 2k x 2k
|
|
if(this.boostzoom < 0) this.boostzoom = 0;
|
|
if(this.boostzoom > 3) this.boostzoom = 3;
|
|
// Map zoom in must be at least as big as boost zoom
|
|
if (this.boostzoom > this.mapzoomin) {
|
|
this.mapzoomin = this.boostzoom;
|
|
}
|
|
this.append_to_world = configuration.getString("append_to_world", "");
|
|
setProtected(configuration.getBoolean("protected", false));
|
|
setTileUpdateDelay(configuration.getInteger("tileupdatedelay", -1));
|
|
setReadOnly(configuration.getBoolean("readonly", false));
|
|
}
|
|
|
|
public ConfigurationNode saveConfiguration() {
|
|
ConfigurationNode cn = super.saveConfiguration();
|
|
cn.put("title", title);
|
|
if(icon != null)
|
|
cn.put("icon", icon);
|
|
cn.put("prefix", prefix);
|
|
if(perspective != null)
|
|
cn.put("perspective", perspective.getName());
|
|
if(shader != null)
|
|
cn.put("shader", shader.getName());
|
|
if(lighting != null)
|
|
cn.put("lighting", lighting.getName());
|
|
cn.put("image-format", imgfmtstring);
|
|
cn.put("mapzoomin", mapzoomin);
|
|
cn.put("mapzoomout", mapzoomout);
|
|
cn.put("boostzoom", boostzoom);
|
|
cn.put("tilescale", tilescale);
|
|
if(bg_cfg != null)
|
|
cn.put("background", bg_cfg);
|
|
if(bg_day_cfg != null)
|
|
cn.put("backgroundday", bg_day_cfg);
|
|
if(bg_night_cfg != null)
|
|
cn.put("backgroundnight", bg_night_cfg);
|
|
cn.put("append_to_world", append_to_world);
|
|
cn.put("protected", isProtected());
|
|
if(this.tileupdatedelay > 0) {
|
|
cn.put("tileupdatedelay", this.tileupdatedelay);
|
|
}
|
|
return cn;
|
|
}
|
|
|
|
public final HDShader getShader() { return shader; }
|
|
public final HDPerspective getPerspective() { return perspective; }
|
|
public final HDLighting getLighting() { return lighting; }
|
|
public final int getBoostZoom() { return boostzoom; }
|
|
@Override
|
|
public final int getTileSize() { return 128 << tilescale; }
|
|
public final int getTileScale() { return tilescale; }
|
|
|
|
@Override
|
|
public List<TileFlags.TileCoord> getTileCoords(DynmapWorld w, int x, int y, int z) {
|
|
return perspective.getTileCoords(w, x, y, z, tilescale);
|
|
}
|
|
|
|
@Override
|
|
public List<TileFlags.TileCoord> getTileCoords(DynmapWorld w, int minx, int miny, int minz, int maxx, int maxy, int maxz) {
|
|
return perspective.getTileCoords(w, minx, miny, minz, maxx, maxy, maxz, tilescale);
|
|
}
|
|
|
|
@Override
|
|
public MapTile[] getAdjecentTiles(MapTile tile) {
|
|
return perspective.getAdjecentTiles(tile);
|
|
}
|
|
|
|
@Override
|
|
public List<DynmapChunk> getRequiredChunks(MapTile tile) {
|
|
return perspective.getRequiredChunks(tile);
|
|
}
|
|
|
|
/* Return number of zoom levels needed by this map (before extra levels from extrazoomout) */
|
|
public int getMapZoomOutLevels() {
|
|
return mapzoomout;
|
|
}
|
|
|
|
@Override
|
|
public String getName() {
|
|
return name;
|
|
}
|
|
|
|
@Override
|
|
public String getPrefix() {
|
|
return prefix;
|
|
}
|
|
|
|
/* Get maps rendered concurrently with this map in this world */
|
|
public List<MapType> getMapsSharingRender(DynmapWorld w) {
|
|
ArrayList<MapType> maps = new ArrayList<MapType>();
|
|
for(MapType mt : w.maps) {
|
|
if(mt instanceof HDMap) {
|
|
HDMap hdmt = (HDMap)mt;
|
|
if((hdmt.perspective == this.perspective) && (hdmt.boostzoom == this.boostzoom)) { /* Same perspective */
|
|
maps.add(hdmt);
|
|
}
|
|
}
|
|
}
|
|
return maps;
|
|
}
|
|
|
|
/* Get names of maps rendered concurrently with this map type in this world */
|
|
public List<String> getMapNamesSharingRender(DynmapWorld w) {
|
|
ArrayList<String> lst = new ArrayList<String>();
|
|
for(MapType mt : w.maps) {
|
|
if(mt instanceof HDMap) {
|
|
HDMap hdmt = (HDMap)mt;
|
|
if((hdmt.perspective == this.perspective) && (hdmt.boostzoom == this.boostzoom)) { /* Same perspective */
|
|
if(hdmt.lighting.isNightAndDayEnabled())
|
|
lst.add(hdmt.getName() + "(night/day)");
|
|
else
|
|
lst.add(hdmt.getName());
|
|
}
|
|
}
|
|
}
|
|
return lst;
|
|
}
|
|
|
|
@Override
|
|
public ImageFormat getImageFormat() { return imgformat; }
|
|
|
|
@Override
|
|
public void buildClientConfiguration(JSONObject worldObject, DynmapWorld world) {
|
|
JSONObject o = new JSONObject();
|
|
s(o, "type", "HDMapType");
|
|
s(o, "name", name);
|
|
s(o, "title", title);
|
|
s(o, "icon", icon);
|
|
s(o, "prefix", prefix);
|
|
s(o, "background", bg_cfg);
|
|
s(o, "backgroundday", bg_day_cfg);
|
|
s(o, "backgroundnight", bg_night_cfg);
|
|
s(o, "bigmap", true);
|
|
s(o, "mapzoomout", (world.getExtraZoomOutLevels()+mapzoomout));
|
|
s(o, "mapzoomin", mapzoomin);
|
|
s(o, "boostzoom", boostzoom);
|
|
s(o, "tilescale", tilescale);
|
|
s(o, "protected", isProtected());
|
|
s(o, "image-format", imgformat.getFileExt());
|
|
if(append_to_world.length() > 0)
|
|
s(o, "append_to_world", append_to_world);
|
|
perspective.addClientConfiguration(o);
|
|
shader.addClientConfiguration(o);
|
|
lighting.addClientConfiguration(o);
|
|
|
|
a(worldObject, "maps", o);
|
|
|
|
}
|
|
|
|
private static int parseColor(String c) {
|
|
int v = 0;
|
|
if(c.startsWith("#")) {
|
|
c = c.substring(1);
|
|
if(c.length() == 3) { /* #rgb */
|
|
try {
|
|
v = Integer.valueOf(c, 16);
|
|
} catch (NumberFormatException nfx) {
|
|
return 0;
|
|
}
|
|
v = 0xFF000000 | ((v & 0xF00) << 12) | ((v & 0x0F0) << 8) | ((v & 0x00F) << 4);
|
|
}
|
|
else if(c.length() == 6) { /* #rrggbb */
|
|
try {
|
|
v = Integer.valueOf(c, 16);
|
|
} catch (NumberFormatException nfx) {
|
|
return 0;
|
|
}
|
|
v = 0xFF000000 | (v & 0xFFFFFF);
|
|
}
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
public int getBackgroundARGBDay() {
|
|
return bgcolorday;
|
|
}
|
|
|
|
public int getBackgroundARGBNight() {
|
|
return bgcolornight;
|
|
}
|
|
|
|
public void purgeOldTiles(final DynmapWorld world, final TileFlags rendered) {
|
|
final MapStorage ms = world.getMapStorage();
|
|
ms.enumMapTiles(world, this, new MapStorageTileEnumCB() {
|
|
@Override
|
|
public void tileFound(MapStorageTile tile, ImageEncoding fmt) {
|
|
if (fmt != getImageFormat().getEncoding()) { // Wrong format? toss it
|
|
/* Otherwise, delete tile */
|
|
tile.delete();
|
|
}
|
|
else if (tile.zoom == 1) { // First tier zoom? sensitive to newly rendered tiles
|
|
// If any were rendered, already triggered (and still needed
|
|
if (rendered.getFlag(tile.x, tile.y) || rendered.getFlag(tile.x+1, tile.y) ||
|
|
rendered.getFlag(tile.x, tile.y-1) || rendered.getFlag(tile.x+1, tile.y-1)) {
|
|
return;
|
|
}
|
|
tile.enqueueZoomOutUpdate();
|
|
}
|
|
else if (tile.zoom == 0) {
|
|
if (rendered.getFlag(tile.x, tile.y)) { /* If we rendered this tile, its good */
|
|
return;
|
|
}
|
|
/* Otherwise, delete tile */
|
|
tile.delete();
|
|
/* Push updates, clear hash code, and signal zoom tile update */
|
|
MapManager.mapman.pushUpdate(world, new Client.Tile(tile.getURI()));
|
|
tile.enqueueZoomOutUpdate();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public String getTitle() {
|
|
return title;
|
|
}
|
|
public int getMapZoomIn() {
|
|
return mapzoomin;
|
|
}
|
|
public String getIcon() {
|
|
return (icon == null)?"":icon;
|
|
}
|
|
|
|
public boolean setPrefix(String s) {
|
|
if(!s.equals(prefix)) {
|
|
prefix = s;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public boolean setTitle(String s) {
|
|
if(!s.equals(title)) {
|
|
title = s;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
public boolean setAppendToWorld(String s) {
|
|
if(!s.equals(append_to_world)) {
|
|
append_to_world = s;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
public String getAppendToWorld() {
|
|
return append_to_world;
|
|
}
|
|
|
|
public boolean setMapZoomIn(int mzi) {
|
|
if(mzi != mapzoomin) {
|
|
mapzoomin = mzi;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
public boolean setMapZoomOut(int mzi) {
|
|
if(mzi != mapzoomout) {
|
|
mapzoomout = mzi;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
public boolean setBoostZoom(int mzi) {
|
|
if(mzi != this.boostzoom) {
|
|
this.boostzoom = mzi;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
public boolean setTileScale(int mzi) {
|
|
if(mzi != this.tilescale) {
|
|
this.tilescale = mzi;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
public boolean setPerspective(HDPerspective p) {
|
|
if(perspective != p) {
|
|
perspective = p;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
public boolean setShader(HDShader p) {
|
|
if(shader != p) {
|
|
shader = p;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
public boolean setLighting(HDLighting p) {
|
|
if(lighting != p) {
|
|
lighting = p;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
public boolean setImageFormatSetting(String f) {
|
|
if(imgfmtstring.equals(f) == false) {
|
|
MapType.ImageFormat newfmt;
|
|
if(f.equals("default"))
|
|
newfmt = MapType.ImageFormat.fromID(core.getDefImageFormat());
|
|
else
|
|
newfmt = MapType.ImageFormat.fromID(f);
|
|
if(newfmt != null) {
|
|
imgformat = newfmt;
|
|
imgfmtstring = f;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
public String getImageFormatSetting() {
|
|
return imgfmtstring;
|
|
}
|
|
public boolean setIcon(String v) {
|
|
if("".equals(v)) v = null;
|
|
icon = v;
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void addMapTiles(List<MapTile> list, DynmapWorld w, int tx, int ty) {
|
|
list.add(new HDMapTile(w, this.perspective, tx, ty, boostzoom, tilescale));
|
|
}
|
|
|
|
private static final ImageVariant[] dayVariant = { ImageVariant.STANDARD, ImageVariant.DAY };
|
|
|
|
@Override
|
|
public ImageVariant[] getVariants() {
|
|
if (lighting.isNightAndDayEnabled())
|
|
return dayVariant;
|
|
return super.getVariants();
|
|
}
|
|
|
|
}
|