package org.dynmap; import java.io.File; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import org.dynmap.utils.TileFlags; import org.json.simple.JSONObject; public abstract class MapType { private boolean is_protected; /** * Is the map type read-only? (i.e. should not be updated by renderer) */ private boolean is_readonly; protected int tileupdatedelay; public enum ImageVariant { STANDARD(""), // Typical image DAY("day"); // Day (no shadow) image public final String variantSuffix; public final String variantID; ImageVariant(String varid) { if (varid.length() > 0) { variantSuffix = "_" + varid; } else { variantSuffix = ""; } variantID = varid; } } public enum ImageEncoding { PNG("png", "image/png", true), JPG("jpg", "image/jpeg", false), WEBP("webp", "image/webp", true); public final String ext; public final String mimetype; public final boolean hasAlpha; ImageEncoding(String ext, String mime, boolean has_alpha) { this.ext = ext; this.mimetype = mime; this.hasAlpha = has_alpha; } public String getFileExt() { return ext; } public String getContentType() { return mimetype; } public static ImageEncoding fromOrd(int ix) { ImageEncoding[] v = values(); if ((ix >= 0) && (ix < v.length)) return v[ix]; return null; } public static ImageEncoding fromContentType(String ct) { ImageEncoding[] v = values(); for (int i = 0; i < v.length; i++) { if (v[i].mimetype.equalsIgnoreCase(ct)) { return v[i]; } } return null; } public static ImageEncoding fromExt(String x) { ImageEncoding[] v = values(); for (int i = 0; i < v.length; i++) { if (v[i].ext.equalsIgnoreCase(x)) { return v[i]; } } return null; } } public enum ImageFormat { FORMAT_PNG("png", 0.0f, ImageEncoding.PNG), FORMAT_JPG75("jpg-q75", 0.75f, ImageEncoding.JPG), FORMAT_JPG80("jpg-q80", 0.80f, ImageEncoding.JPG), FORMAT_JPG85("jpg-q85", 0.85f, ImageEncoding.JPG), FORMAT_JPG("jpg", 0.85f, ImageEncoding.JPG), FORMAT_JPG90("jpg-q90", 0.90f, ImageEncoding.JPG), FORMAT_JPG95("jpg-q95", 0.95f, ImageEncoding.JPG), FORMAT_JPG100("jpg-q100", 1.00f, ImageEncoding.JPG), FORMAT_WEBP75("webp-q75", 75, ImageEncoding.WEBP), FORMAT_WEBP80("webp-q80", 80, ImageEncoding.WEBP), FORMAT_WEBP85("webp-q85", 85, ImageEncoding.WEBP), FORMAT_WEBP("webp", 85, ImageEncoding.WEBP), FORMAT_WEBP90("webp-q90", 90, ImageEncoding.WEBP), FORMAT_WEBP95("webp-q95", 95, ImageEncoding.WEBP), FORMAT_WEBP100("webp-q100", 100, ImageEncoding.WEBP), FORMAT_WEBPL("webp-l", 85, ImageEncoding.WEBP); String id; float qual; ImageEncoding enc; ImageFormat(String id, float quality, ImageEncoding enc) { this.id = id; this.qual = quality; this.enc = enc; } public String getID() { return id; } public String getFileExt() { return enc.getFileExt(); } public float getQuality() { return qual; } public ImageEncoding getEncoding() { return enc; } public static ImageFormat fromID(String imgfmt) { for(ImageFormat i_f : MapType.ImageFormat.values()) { if(i_f.getID().equals(imgfmt)) { return i_f; } } return null; } }; public static class ZoomInfo { public String prefix; public int background_argb; public ZoomInfo(String pre, int bg) { prefix = pre; background_argb = bg; } } public abstract void addMapTiles(List list, DynmapWorld w, int tx, int ty); public abstract List getTileCoords(DynmapWorld w, int x, int y, int z); public abstract List getTileCoords(DynmapWorld w, int minx, int miny, int minz, int maxx, int maxy, int maxz); public abstract MapTile[] getAdjecentTiles(MapTile tile); public abstract List getRequiredChunks(MapTile tile); public abstract int getTileSize(); public void buildClientConfiguration(JSONObject worldObject, DynmapWorld w) { } public List getTiles(DynmapWorld w, int x, int y, int z) { List coords = this.getTileCoords(w, x, y, z); ArrayList tiles = new ArrayList(); for(TileFlags.TileCoord c : coords) { this.addMapTiles(tiles, w, c.x, c.y); } return tiles; } public abstract String getName(); /* Get maps rendered concurrently with this map in this world */ public abstract List getMapsSharingRender(DynmapWorld w); /* Get names of maps rendered concurrently with this map type in this world */ public abstract List getMapNamesSharingRender(DynmapWorld w); /* Return number of zoom levels needed by this map (before extra levels from extrazoomout) */ public int getMapZoomOutLevels() { return 0; } public ImageFormat getImageFormat() { return ImageFormat.FORMAT_PNG; } public int getBackgroundARGBNight() { return 0; } public int getBackgroundARGBDay() { return 0; } public int getBackgroundARGB(ImageVariant var) { if (var == ImageVariant.DAY) return getBackgroundARGBDay(); else return getBackgroundARGBNight(); } public void purgeOldTiles(DynmapWorld world, TileFlags rendered) { } public interface FileCallback { public void fileFound(File f, File parent, boolean day); } protected void walkMapTree(File root, FileCallback cb, boolean day) { LinkedList dirs = new LinkedList(); String ext = "." + getImageFormat().getFileExt(); dirs.add(root); while(dirs.isEmpty() == false) { File dir = dirs.pop(); String[] lst = dir.list(); if(lst == null) continue; for(String fn : lst) { if(fn.equals(".") || fn.equals("..")) continue; File f = new File(dir, fn); if(f.isDirectory()) { /* If directory, add to list to process */ dirs.add(f); } else if(fn.endsWith(ext)) { /* Else, if matches suffix */ cb.fileFound(f, dir, day); } } } } public ConfigurationNode saveConfiguration() { ConfigurationNode cn = new ConfigurationNode(); cn.put("class", this.getClass().getName()); /* Add class */ cn.put("name", getName()); /* Get map name */ return cn; } public boolean isProtected() { return is_protected; } public boolean setProtected(boolean p) { if(is_protected != p) { is_protected = p; return true; } return false; } /** * Is the map type read-only? (i.e. should not be updated by renderer) * @return true if read-only */ public boolean isReadOnly() { return is_readonly; } /** * Set read-only state of map type * @param r - true if read-only * @return true if state changed */ public boolean setReadOnly(boolean r) { if(is_readonly != r) { is_readonly = r; return true; } return false; } public abstract String getPrefix(); public int getTileUpdateDelay(DynmapWorld w) { if(tileupdatedelay > 0) return tileupdatedelay; else return w.getTileUpdateDelay(); } public boolean setTileUpdateDelay(int delay) { if(tileupdatedelay != delay) { tileupdatedelay = delay; return true; } return false; } private static final ImageVariant[] defVariant = { ImageVariant.STANDARD }; public ImageVariant[] getVariants() { return defVariant; } }