Compare commits

...

25 Commits

Author SHA1 Message Date
Mike Primm babc8cd073 Fix accumulation of weak reference keys (mem leak) in snapshot cache 2011-12-28 14:38:26 +08:00
Mike Primm bd92cc37bf Switch chat name URL parm to 'chatname', add 'playername' URL part for initial player follow selection 2011-12-26 13:11:46 +08:00
Mike Primm ca00a84dc5 Fix cleanup of area outlines with minzoom when switching maps 2011-12-24 22:09:18 -06:00
Mike Primm 1af56db030 Fix minzoom handling for area markers 2011-12-23 14:11:02 +08:00
Mike Primm 93613404ba Adjust handling of transparent biome shading files (grass, foliage), as used in Painter's texture pack 2011-12-23 13:32:27 +08:00
Mike Primm cd067adfdc Fix issue with white blank tiles at edge of JPG rendered maps 2011-12-23 13:32:27 +08:00
Mike Primm b872aa039e Handle Essentials-style nickname color coding (&0-&f) in player nicknames 2011-12-23 07:20:48 +08:00
Mike Primm eafbe62c46 Add support for minzoom attribute on marker sets - hide markers below configurable zoom for each marker set 2011-12-23 04:31:10 +08:00
Mike Primm 7373de85a2 Add support for updating stock shaders.txt, perspectives.txt, lightings.txt with additional defaults. 2011-12-23 04:31:09 +08:00
Mike Primm 44106a799a Add 'allowurlname' setting for 'chat' - permits web name set with playername= parameter 2011-12-23 04:31:09 +08:00
Mike Primm 756202affd Bump to 0.28 2011-12-17 00:00:27 -06:00
Mike Primm 5dedf1d6e8 Add /dynmap radiusrender <world> <x> <z> <radius> - console usable radiusrender 2011-12-17 13:18:43 +08:00
Mike Primm 96e4742bfe Dial the ticklist workaround to align with proposed numbers in CraftBukkit-Bleeding fix 2011-12-17 07:43:06 +08:00
Mike Primm 9c0f33bd3d Adjust ticklist workaround to handle nether's tendancy to have ticklist processed events beget new ticklist events, more or less constantly.... 2011-12-17 07:26:31 +08:00
Mike Primm 4a3e95a118 Remove marker label field if label for marker is blank ("") 2011-12-16 01:26:13 +08:00
Mike Primm 3c849b9d66 Add 'grayplayerswhenhidden' option to allow disable of graying of players in player list when not visible on current map 2011-12-16 01:26:13 +08:00
Mike Primm 5af670de61 Add extra topographical shader, TerraNetworkOrgTopo - thanks to TerraNetworkOrg! 2011-12-16 00:09:48 +08:00
Mike Primm 708f0b3c80 Make it so that blank label ("") on area marker disables popup on area 2011-12-15 23:54:45 +08:00
Mike Primm 102012aa91 Detect scaled models that yield full blocks, and optimize to solid 2011-12-15 15:04:17 +08:00
Mike Primm ba2c3eac1c Add support for cleanup of stale tiles (off edge of map) 2011-12-15 13:26:09 +08:00
Mike Primm 8f66d34752 Make water blocks full blocks - big performance boost 2011-12-15 13:26:09 +08:00
Mike Primm 03b280fe2d Add 'usenormalthreadpriority' setting (makes renders on Windows use normal priority) 2011-12-15 00:35:00 +08:00
Mike Primm f7dedff413 Add 'showlayercontrol' config setting and URL parameter, to allow hide of layer control 2011-12-15 00:02:37 +08:00
Mike Primm d5e1bc1b4d Fix size/layout of player faces in chatbox 2011-12-12 02:20:32 +08:00
Mike Primm ef16a13cd5 Bump to 0.27 2011-12-11 01:22:13 -06:00
33 changed files with 532 additions and 150 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.dynmap</groupId>
<artifactId>dynmap</artifactId>
<version>0.26</version>
<version>0.28</version>
<name>dynmap</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -17,14 +17,16 @@ public class AsynchronousQueue<T> {
private int accelDequeueThresh;
private int pendingcnt;
private int pendinglimit;
private boolean normalprio;
public AsynchronousQueue(Handler<T> handler, int dequeueTime, int accelDequeueThresh, int accelDequeueTime, int pendinglimit) {
public AsynchronousQueue(Handler<T> handler, int dequeueTime, int accelDequeueThresh, int accelDequeueTime, int pendinglimit, boolean normalprio) {
this.handler = handler;
this.dequeueTime = dequeueTime;
this.accelDequeueTime = accelDequeueTime;
this.accelDequeueThresh = accelDequeueThresh;
if(pendinglimit < 1) pendinglimit = 1;
this.pendinglimit = pendinglimit;
this.normalprio = normalprio;
}
public boolean push(T t) {
@@ -83,7 +85,8 @@ public class AsynchronousQueue<T> {
});
thread.start();
try {
thread.setPriority(Thread.MIN_PRIORITY);
if(!normalprio)
thread.setPriority(Thread.MIN_PRIORITY);
} catch (SecurityException e) {
Log.info("Failed to set minimum priority for worker thread!");
}
+20 -3
View File
@@ -34,7 +34,7 @@ public class Client {
public String channel;
public ChatMessage(String source, String channel, String playerName, String message, String playeraccount) {
this.source = source;
this.playerName = ChatColor.stripColor(playerName);
this.playerName = Client.stripColor(playerName);
this.message = ChatColor.stripColor(message);
this.account = playeraccount;
this.channel = channel;
@@ -58,7 +58,7 @@ public class Client {
public String playerName;
public String account;
public PlayerJoinMessage(String playerName, String playeraccount) {
this.playerName = ChatColor.stripColor(playerName);
this.playerName = Client.stripColor(playerName);
this.account = playeraccount;
}
@Override
@@ -80,7 +80,7 @@ public class Client {
public String playerName;
public String account;
public PlayerQuitMessage(String playerName, String playeraccount) {
this.playerName = ChatColor.stripColor(playerName);
this.playerName = Client.stripColor(playerName);
this.account = playeraccount;
}
@Override
@@ -142,4 +142,21 @@ public class Client {
public String type = "component";
/* Each subclass must provide 'ctype' string for component 'type' */
}
public static String stripColor(String s) {
s = ChatColor.stripColor(s); /* Strip standard color encoding */
/* Handle Essentials nickname encoding too */
int idx = 0;
while((idx = s.indexOf('&', idx)) >= 0) {
char c = s.charAt(idx+1); /* Get next character */
if(c == '&') { /* Another ampersand */
s = s.substring(0, idx) + s.substring(idx+1);
}
else {
s = s.substring(0, idx) + s.substring(idx+2);
}
idx++;
}
return s;
}
}
@@ -25,6 +25,8 @@ public class ClientConfigurationComponent extends Component {
s(t, "sidebaropened", c.getString("sidebaropened", "false"));
s(t, "dynmapversion", plugin.getDescription().getVersion());
s(t, "cyrillic", c.getBoolean("cyrillic-support", false));
s(t, "showlayercontrol", c.getBoolean("showlayercontrol", true));
s(t, "grayplayerswhenhidden", c.getBoolean("grayplayerswhenhidden", true));
String sn = plugin.getServer().getServerName();
if(sn.equals("Unknown Server"))
sn = "Minecraft Dynamic Map";
@@ -51,7 +51,7 @@ public class ClientUpdateComponent extends Component {
boolean hide = false;
s(jp, "type", "player");
s(jp, "name", ChatColor.stripColor(p.getDisplayName()));
s(jp, "name", Client.stripColor(p.getDisplayName()));
s(jp, "account", p.getName());
if(hideifshadow < 15) {
if(pl.getBlock().getLightLevel() <= hideifshadow)
@@ -100,7 +100,7 @@ public class ClientUpdateComponent extends Component {
for(Player p : hidden) {
JSONObject jp = new JSONObject();
s(jp, "type", "player");
s(jp, "name", ChatColor.stripColor(p.getDisplayName()));
s(jp, "name", Client.stripColor(p.getDisplayName()));
s(jp, "account", p.getName());
s(jp, "world", "-hidden-player-");
s(jp, "x", 0.0);
+86 -15
View File
@@ -21,6 +21,8 @@ import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.CustomEventListener;
import org.bukkit.event.Event;
@@ -801,23 +803,37 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
}
}
else if(c.equals("radiusrender") && checkPlayerPermission(sender,"radiusrender")) {
if (player != null) {
int radius = 0;
String mapname = null;
if(args.length > 1) {
radius = Integer.parseInt(args[1]); /* Parse radius */
if(radius < 0)
radius = 0;
if(args.length > 2)
mapname = args[2];
int radius = 0;
String mapname = null;
Location loc = null;
if(args.length == 2) { /* Just radius */
radius = Integer.parseInt(args[1]); /* Parse radius */
if(radius < 0)
radius = 0;
if(args.length > 2)
mapname = args[2];
if (player != null)
loc = player.getLocation();
else
sender.sendMessage("Command require <world> <x> <z> <radius> if issued from console.");
}
else if(args.length > 3) { /* <world> <x> <z> */
DynmapWorld w = mapManager.worldsLookup.get(args[1]); /* Look up world */
if(w == null) {
sender.sendMessage("World '" + args[1] + "' not defined/loaded");
}
Location loc = player.getLocation();
if(loc != null)
mapManager.renderWorldRadius(loc, sender, mapname, radius);
}
else {
sender.sendMessage("Command can only be issued by player.");
double x = 0, z = 0;
x = Double.parseDouble(args[2]);
z = Double.parseDouble(args[3]);
if(args.length > 4)
radius = Integer.parseInt(args[4]);
if(args.length > 5)
mapname = args[5];
if(w != null)
loc = new Location(w.world, x, 64.0, z);
}
if(loc != null)
mapManager.renderWorldRadius(loc, sender, mapname, radius);
} else if (c.equals("hide")) {
if (args.length == 1) {
if(player != null && checkPlayerPermission(sender,"hide.self")) {
@@ -1059,6 +1075,61 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
}
}
/*
* Add in any missing sections to existing file, using resource
*/
public boolean updateUsingDefaultResource(String resourcename, File deffile, String basenode) {
InputStream in = getClass().getResourceAsStream(resourcename);
if(in == null) {
Log.severe("Unable to find resource - " + resourcename);
return false;
}
if(deffile.canRead() == false) { /* Doesn't exist? */
return createDefaultFileFromResource(resourcename, deffile);
}
/* Load default from resource */
YamlConfiguration def_fc = YamlConfiguration.loadConfiguration(in);
/* Load existing from file */
YamlConfiguration fc = YamlConfiguration.loadConfiguration(deffile);
/* Now, get the list associated with the base node default */
List<Map<String,Object>> existing = fc.getMapList(basenode);
Set<String> existing_names = new HashSet<String>();
/* Make map, indexed by 'name' in map */
if(existing != null) {
for(Map<String,Object> m : existing) {
Object name = m.get("name");
if(name instanceof String)
existing_names.add((String)name);
}
}
boolean did_update = false;
/* Now, loop through defaults, and see if any are missing */
List<Map<String,Object>> defmaps = def_fc.getMapList(basenode);
if(defmaps != null) {
for(Map<String,Object> m : defmaps) {
Object name = m.get("name");
if(name instanceof String) {
/* If not an existing one, need to add it */
if(existing_names.contains((String)name) == false) {
existing.add(m);
did_update = true;
}
}
}
}
/* If we did update, save existing */
if(did_update) {
try {
fc.set(basenode, existing);
fc.save(deffile);
} catch (IOException iox) {
Log.severe("Error saving migrated file - " + deffile.getPath());
return false;
}
Log.info("Updated file " + deffile.getPath());
}
return true;
}
private BlockListener ourBlockEventHandler = new BlockListener() {
+15 -7
View File
@@ -388,6 +388,7 @@ public class DynmapWorld {
int width = 128, height = 128;
BufferedImage zIm = null;
DynmapBufferedImage kzIm = null;
boolean blank = true;
int[] argb = new int[width*height];
int step = pd.stepsize << pd.zoomlevel;
int ztx = tx;
@@ -415,6 +416,7 @@ public class DynmapWorld {
if(im != null) {
im.getRGB(0, 0, width, height, argb, 0, width); /* Read data */
im.flush();
blank = false;
/* Do binlinear scale to 64x64 */
int off = 0;
for(int y = 0; y < height; y += 2) {
@@ -434,17 +436,15 @@ public class DynmapWorld {
/* blit scaled rendered tile onto zoom-out tile */
zIm.setRGB(((i>>1) != 0)?0:width/2, (i & 1) * height/2, width/2, height/2, argb, 0, width);
}
else if((pd.background != 0) && (pd.fmt != ImageFormat.FORMAT_PNG)) {
else {
Arrays.fill(argb, pd.background);
/* blit scaled rendered tile onto zoom-out tile */
zIm.setRGB(((i>>1) != 0)?0:width/2, (i & 1) * height/2, width/2, height/2, argb, 0, width);
}
}
else if((pd.background != 0) && (pd.fmt != ImageFormat.FORMAT_PNG)) {
else {
Arrays.fill(argb, pd.background);
/* blit scaled rendered tile onto zoom-out tile */
zIm.setRGB(((i>>1) != 0)?0:width/2, (i & 1) * height/2, width/2, height/2, argb, 0, width);
}
/* blit scaled rendered tile onto zoom-out tile */
zIm.setRGB(((i>>1) != 0)?0:width/2, (i & 1) * height/2, width/2, height/2, argb, 0, width);
}
FileLockManager.getWriteLock(zf);
try {
@@ -456,7 +456,15 @@ public class DynmapWorld {
int tilex = ztx/step/2;
int tiley = zty/step/2;
String key = world.getName()+".z"+pd.zoomprefix+pd.baseprefix;
if((!zf.exists()) || (crc != mm.hashman.getImageHashCode(key, null, tilex, tiley))) {
if(blank) {
if(zf.exists()) {
zf.delete();
hashman.updateHashCode(key, null, tilex, tiley, -1);
MapManager.mapman.pushUpdate(this.world, new Client.Tile(zfname));
enqueueZoomOutUpdate(zf, pd.zoomlevel+1);
}
}
else if((!zf.exists()) || (crc != mm.hashman.getImageHashCode(key, null, tilex, tiley))) {
try {
if(!zf.getParentFile().exists())
zf.getParentFile().mkdirs();
+26 -11
View File
@@ -50,6 +50,7 @@ public class MapManager {
private int progressinterval = 100;
private boolean saverestorepending = true;
private boolean hideores = false;
private boolean usenormalpriority = false;
private boolean pauseupdaterenders = false;
private boolean pausefullrenders = false;
@@ -117,7 +118,8 @@ public class MapManager {
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
t.setPriority(Thread.MIN_PRIORITY);
if(!mapman.usenormalpriority)
t.setPriority(Thread.MIN_PRIORITY);
t.setName("Dynmap Render Thread");
return t;
}
@@ -369,7 +371,17 @@ public class MapManager {
else
sendMessage(String.format("%s of map '%s' of '%s' completed - %d tiles rendered (%.2f msec/map-tile, %.2f msec per render)",
rendertype, activemaps, world.world.getName(), rendercnt, msecpertile, rendtime));
/* Now, if fullrender, use the render bitmap to purge obsolete tiles */
if(cxmin == Integer.MIN_VALUE) {
if(activemapcnt == 1) {
map.purgeOldTiles(world, rendered);
}
else {
for(MapType mt : map.getMapsSharingRender(world)) {
mt.purgeOldTiles(world, rendered);
}
}
}
}
found.clear();
rendered.clear();
@@ -564,11 +576,9 @@ public class MapManager {
total_render_ns.addAndGet(System.nanoTime()-rt0);
rendercalls.incrementAndGet();
synchronized(lock) {
// found.setFlag(tile.tileOrdinalX(),tile.tileOrdinalY(),false);
rendered.setFlag(tile.tileOrdinalX(), tile.tileOrdinalY(), true);
for (MapTile adjTile : map.getAdjecentTiles(tile)) {
if (!found.getFlag(adjTile.tileOrdinalX(),adjTile.tileOrdinalY()) &&
!rendered.getFlag(adjTile.tileOrdinalX(),adjTile.tileOrdinalY())) {
if (!found.getFlag(adjTile.tileOrdinalX(),adjTile.tileOrdinalY())) {
found.setFlag(adjTile.tileOrdinalX(), adjTile.tileOrdinalY(), true);
renderQueue.add(adjTile);
}
@@ -576,7 +586,6 @@ public class MapManager {
}
}
synchronized(lock) {
// found.setFlag(tile.tileOrdinalX(), tile.tileOrdinalY(), false);
if(!cache.isEmpty()) {
rendercnt++;
timeaccum += System.currentTimeMillis() - tstart;
@@ -658,6 +667,9 @@ public class MapManager {
/* Get block hiding data, if any */
hideores = configuration.getBoolean("hideores", false);
/* See what priority to use */
usenormalpriority = configuration.getBoolean("usenormalthreadpriority", false);
/* Clear color scheme */
ColorScheme.reset();
@@ -684,7 +696,8 @@ public class MapManager {
(int) (configuration.getDouble("renderinterval", 0.5) * 1000),
configuration.getInteger("renderacceleratethreshold", 30),
(int)(configuration.getDouble("renderaccelerateinterval", 0.2) * 1000),
configuration.getInteger("tiles-rendered-at-once", (Runtime.getRuntime().availableProcessors()+1)/2));
configuration.getInteger("tiles-rendered-at-once", (Runtime.getRuntime().availableProcessors()+1)/2),
usenormalpriority);
/* On dedicated thread, so default to no delays */
timeslice_int = (long)(configuration.getDouble("timesliceinterval", 0.0) * 1000);
@@ -1063,6 +1076,10 @@ public class MapManager {
if(saverestorepending)
savePending();
if(sscache != null) {
sscache.cleanup();
sscache = null;
}
}
private HashMap<World, File> worldTileDirectories = new HashMap<World, File>();
@@ -1167,11 +1184,9 @@ public class MapManager {
/**
* Update map tile statistics
*/
public void updateStatistics(MapTile tile, String subtype, boolean rendered, boolean updated, boolean transparent) {
public void updateStatistics(MapTile tile, String prefix, boolean rendered, boolean updated, boolean transparent) {
synchronized(lock) {
String k = tile.getKey();
if(subtype != null)
k += "." + subtype;
String k = tile.getKey(prefix);
MapStats ms = mapstats.get(k);
if(ms == null) {
ms = new MapStats();
+1 -1
View File
@@ -40,7 +40,7 @@ public abstract class MapTile {
@Override
public abstract boolean equals(Object obj);
public abstract String getKey();
public abstract String getKey(String prefix);
public abstract boolean isBiomeDataNeeded();
public abstract boolean isHightestBlockYDataNeeded();
+29
View File
@@ -1,8 +1,11 @@
package org.dynmap;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import org.bukkit.Location;
import org.dynmap.utils.TileFlags;
import org.json.simple.JSONObject;
public abstract class MapType {
@@ -80,5 +83,31 @@ public abstract class MapType {
* Values correspond to tile X,Y (0), X+step,Y (1), X,Y+step (2), X+step,Y+step (3)
*/
public abstract int[] zoomFileStepSequence();
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<File> dirs = new LinkedList<File>();
String ext = "." + getImageFormat().getFileExt();
dirs.add(root);
while(dirs.isEmpty() == false) {
File dir = dirs.pop();
String[] lst = dir.list();
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);
}
}
}
}
}
@@ -84,6 +84,7 @@ public class MarkersComponent extends ClientComponent {
offlineset = api.createMarkerSet(OFFLINE_PLAYERS_SETID, configuration.getString("offlinelabel", "Offline"), null, true);
}
offlineset.setHideByDefault(configuration.getBoolean("offlinehidebydefault", true));
offlineset.setMinZoom(configuration.getInteger("offlineminzoom", 0));
offlineicon = api.getMarkerIcon(configuration.getString("offlineicon", "offlineuser"));
+7 -7
View File
@@ -303,7 +303,7 @@ public class FlatMap extends MapType {
boolean tile_update = false;
FileLockManager.getWriteLock(outputFile);
try {
if((!outputFile.exists()) || (crc != hashman.getImageHashCode(tile.getKey(), null, t.x, t.y))) {
if((!outputFile.exists()) || (crc != hashman.getImageHashCode(tile.getKey(prefix), null, t.x, t.y))) {
/* Wrap buffer as buffered image */
Debug.debug("saving image " + outputFile.getPath());
if(!outputFile.getParentFile().exists())
@@ -316,7 +316,7 @@ public class FlatMap extends MapType {
Debug.error("Failed to save image (NullPointerException): " + outputFile.getPath(), e);
}
MapManager.mapman.pushUpdate(tile.getWorld(), new Client.Tile(tile.getFilename()));
hashman.updateHashCode(tile.getKey(), null, t.x, t.y, crc);
hashman.updateHashCode(tile.getKey(prefix), null, t.x, t.y, crc);
tile.getDynmapWorld().enqueueZoomOutUpdate(outputFile);
tile_update = true;
}
@@ -327,7 +327,7 @@ public class FlatMap extends MapType {
FileLockManager.releaseWriteLock(outputFile);
DynmapBufferedImage.freeBufferedImage(im);
}
MapManager.mapman.updateStatistics(tile, null, true, tile_update, !rendered);
MapManager.mapman.updateStatistics(tile, prefix, true, tile_update, !rendered);
/* If day too, handle it */
if(night_and_day) {
@@ -335,7 +335,7 @@ public class FlatMap extends MapType {
crc = hashman.calculateTileHash(argb_buf_day);
FileLockManager.getWriteLock(dayfile);
try {
if((!dayfile.exists()) || (crc != hashman.getImageHashCode(tile.getKey(), "day", t.x, t.y))) {
if((!dayfile.exists()) || (crc != hashman.getImageHashCode(tile.getKey(prefix), "day", t.x, t.y))) {
Debug.debug("saving image " + dayfile.getPath());
if(!dayfile.getParentFile().exists())
dayfile.getParentFile().mkdirs();
@@ -347,7 +347,7 @@ public class FlatMap extends MapType {
Debug.error("Failed to save image (NullPointerException): " + dayfile.getPath(), e);
}
MapManager.mapman.pushUpdate(tile.getWorld(), new Client.Tile(tile.getDayFilename()));
hashman.updateHashCode(tile.getKey(), "day", t.x, t.y, crc);
hashman.updateHashCode(tile.getKey(prefix), "day", t.x, t.y, crc);
tile.getDynmapWorld().enqueueZoomOutUpdate(dayfile);
tile_update = true;
}
@@ -359,7 +359,7 @@ public class FlatMap extends MapType {
FileLockManager.releaseWriteLock(dayfile);
DynmapBufferedImage.freeBufferedImage(im_day);
}
MapManager.mapman.updateStatistics(tile, "day", true, tile_update, !rendered);
MapManager.mapman.updateStatistics(tile, prefix+"_day", true, tile_update, !rendered);
}
return rendered;
@@ -574,7 +574,7 @@ public class FlatMap extends MapType {
}
@Override
public String getKey() {
public String getKey(String prefix) {
return world.world.getName() + "." + map.getPrefix();
}
@@ -264,11 +264,19 @@ public class HDBlockModels {
row = new short[16][];
blockmodels[m.blockid] = row;
}
short[] smod = null;
for(int i = 0; i < 16; i++) {
if((m.databits & (1 << i)) != 0) {
if(smod == null) smod = m.getScaledMap(scale);
row[i] = smod;
short[] smod = m.getScaledMap(scale);
/* See if scaled model is full block : much faster to not use it if it is */
if(smod != null) {
boolean keep = false;
for(int i = 0; (!keep) && (i < smod.length); i++) {
if(smod[i] == 0) keep = true;
}
if(keep) {
for(int i = 0; i < 16; i++) {
if((m.databits & (1 << i)) != 0) {
row[i] = smod;
}
}
}
}
}
+67
View File
@@ -7,17 +7,23 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import org.dynmap.Client;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapChunk;
import org.dynmap.DynmapPlugin;
import org.dynmap.DynmapWorld;
import org.dynmap.Log;
import org.dynmap.MapManager;
import org.dynmap.MapTile;
import org.dynmap.MapType;
import org.dynmap.debug.Debug;
import org.dynmap.kzedmap.MapTileRenderer;
import org.dynmap.utils.MapChunkCache;
import org.dynmap.utils.TileFlags;
import org.json.simple.JSONObject;
import com.avaje.ebean.text.StringParser;
public class HDMap extends MapType {
private String name;
@@ -116,6 +122,10 @@ public class HDMap extends MapType {
if(c != null) {
bgcolornight = parseColor(c);
}
if(imgformat != ImageFormat.FORMAT_PNG) { /* If JPG, set background color opacity */
bgcolorday |= 0xFF000000;
bgcolornight |= 0xFF000000;
}
}
public HDShader getShader() { return shader; }
@@ -270,4 +280,61 @@ public class HDMap extends MapType {
public int getBackgroundARGBNight() {
return bgcolornight;
}
private HDMapTile fileToTile(DynmapWorld world, File f) {
String n = f.getName();
n = n.substring(0, n.lastIndexOf('.'));
if(n == null) return null;
String[] nt = n.split("_");
if(nt.length != 2) return null;
int xx, zz;
try {
xx = Integer.parseInt(nt[0]);
zz = Integer.parseInt(nt[1]);
} catch (NumberFormatException nfx) {
return null;
}
return new HDMapTile(world, perspective, xx, zz);
}
public void purgeOldTiles(final DynmapWorld world, final TileFlags rendered) {
File basedir = new File(world.worldtilepath, prefix); /* Get base directory for map */
FileCallback cb = new FileCallback() {
public void fileFound(File f, File parent, boolean day) {
String n = f.getName();
if(n.startsWith("z")) { /* If zoom file */
if(n.startsWith("z_")) { /* First tier of zoom? */
File ff = new File(parent, n.substring(2)); /* Make file for render tier, and drive update */
HDMapTile tile = fileToTile(world, ff); /* Parse it */
if(tile == null) return;
if(rendered.getFlag(tile.tx, tile.ty) || rendered.getFlag(tile.tx+1, tile.ty) ||
rendered.getFlag(tile.tx, tile.ty-1) || rendered.getFlag(tile.tx+1, tile.ty-1))
return;
world.enqueueZoomOutUpdate(ff);
}
return;
}
HDMapTile tile = fileToTile(world, f);
if(tile == null) return;
if(rendered.getFlag(tile.tx, tile.ty)) { /* If we rendered this tile, its good */
return;
}
Debug.debug("clean up " + f.getPath());
/* Otherwise, delete tile */
f.delete();
/* Push updates, clear hash code, and signal zoom tile update */
MapManager.mapman.pushUpdate(world.world,
new Client.Tile(day?tile.getDayFilename(prefix, getImageFormat()):tile.getFilename(prefix, getImageFormat())));
MapManager.mapman.hashman.updateHashCode(tile.getKey(prefix), day?"day":null, tile.tx, tile.ty, -1);
world.enqueueZoomOutUpdate(f);
}
};
walkMapTree(basedir, cb, false);
if(lighting.isNightAndDayEnabled()) {
basedir = new File(world.worldtilepath, prefix+"_day");
walkMapTree(basedir, cb, true);
}
}
}
@@ -33,7 +33,7 @@ public class HDMapManager {
Log.verboseinfo("Loading shaders...");
File f = new File(plugin.getDataFolder(), "shaders.txt");
if(!plugin.createDefaultFileFromResource("/shaders.txt", f)) {
if(!plugin.updateUsingDefaultResource("/shaders.txt", f, "shaders")) {
return;
}
org.bukkit.util.config.Configuration bukkitShaderConfig = new org.bukkit.util.config.Configuration(f);
@@ -64,7 +64,7 @@ public class HDMapManager {
public void loadHDPerspectives(DynmapPlugin plugin) {
Log.verboseinfo("Loading perspectives...");
File f = new File(plugin.getDataFolder(), "perspectives.txt");
if(!plugin.createDefaultFileFromResource("/perspectives.txt", f)) {
if(!plugin.updateUsingDefaultResource("/perspectives.txt", f, "perspectives")) {
return;
}
org.bukkit.util.config.Configuration bukkitPerspectiveConfig = new org.bukkit.util.config.Configuration(f);
@@ -92,7 +92,7 @@ public class HDMapManager {
public void loadHDLightings(DynmapPlugin plugin) {
Log.verboseinfo("Loading lightings...");
File f = new File(plugin.getDataFolder(), "lightings.txt");
if(!plugin.createDefaultFileFromResource("/lightings.txt", f)) {
if(!plugin.updateUsingDefaultResource("/lightings.txt", f, "lightings")) {
return;
}
org.bukkit.util.config.Configuration bukkitLightingsConfig = new org.bukkit.util.config.Configuration(f);
@@ -73,8 +73,8 @@ public class HDMapTile extends MapTile {
return o.tx == tx && o.ty == ty && (perspective == o.perspective) && (o.getWorld() == getWorld());
}
public String getKey() {
return getWorld().getName() + "." + perspective.getName();
public String getKey(String prefix) {
return getWorld().getName() + "." + prefix;
}
@Override
@@ -1186,7 +1186,7 @@ public class IsoHDPerspective implements HDPerspective {
try {
if(rendered[i])
renderone = true;
if((!f.exists()) || (crc != hashman.getImageHashCode(tile.getKey(), prefix, tile.tx, tile.ty))) {
if((!f.exists()) || (crc != hashman.getImageHashCode(tile.getKey(prefix), null, tile.tx, tile.ty))) {
/* Wrap buffer as buffered image */
Debug.debug("saving image " + f.getPath());
if(!f.getParentFile().exists())
@@ -1199,7 +1199,7 @@ public class IsoHDPerspective implements HDPerspective {
Debug.error("Failed to save image (NullPointerException): " + f.getPath(), e);
}
MapManager.mapman.pushUpdate(tile.getWorld(), new Client.Tile(fname));
hashman.updateHashCode(tile.getKey(), prefix, tile.tx, tile.ty, crc);
hashman.updateHashCode(tile.getKey(prefix), null, tile.tx, tile.ty, crc);
tile.getDynmapWorld().enqueueZoomOutUpdate(f);
tile_update = true;
}
@@ -1216,10 +1216,9 @@ public class IsoHDPerspective implements HDPerspective {
fname = tile.getDayFilename(prefix, fmt);
f = new File(tile.getDynmapWorld().worldtilepath, fname);
FileLockManager.getWriteLock(f);
prefix = prefix+"_day";
tile_update = false;
try {
if((!f.exists()) || (crc != hashman.getImageHashCode(tile.getKey(), prefix, tile.tx, tile.ty))) {
if((!f.exists()) || (crc != hashman.getImageHashCode(tile.getKey(prefix), "day", tile.tx, tile.ty))) {
/* Wrap buffer as buffered image */
Debug.debug("saving image " + f.getPath());
if(!f.getParentFile().exists())
@@ -1232,7 +1231,7 @@ public class IsoHDPerspective implements HDPerspective {
Debug.error("Failed to save image (NullPointerException): " + f.getPath(), e);
}
MapManager.mapman.pushUpdate(tile.getWorld(), new Client.Tile(fname));
hashman.updateHashCode(tile.getKey(), prefix, tile.tx, tile.ty, crc);
hashman.updateHashCode(tile.getKey(prefix), "day", tile.tx, tile.ty, crc);
tile.getDynmapWorld().enqueueZoomOutUpdate(f);
tile_update = true;
}
@@ -1243,7 +1242,7 @@ public class IsoHDPerspective implements HDPerspective {
FileLockManager.releaseWriteLock(f);
DynmapBufferedImage.freeBufferedImage(dayim[i]);
}
MapManager.mapman.updateStatistics(tile, prefix, true, tile_update, !rendered[i]);
MapManager.mapman.updateStatistics(tile, prefix+"_day", true, tile_update, !rendered[i]);
}
}
return renderone;
@@ -1048,7 +1048,7 @@ public class TexturePack {
rslt.setTransparent();
return;
}
/* If warer block, to watercolor tone op */
/* If water block, to watercolor tone op */
if((blkid == 8) || (blkid == 9)) {
textop = COLORMOD_WATERTONED;
}
@@ -1162,9 +1162,11 @@ public class TexturePack {
else {
clr = biomeLookup(li.argb, li.width, mapiter.getRawBiomeRainfall(), mapiter.getRawBiomeTemperature());
}
if(swamp_shaded && (mapiter.getBiome() == Biome.SWAMPLAND))
clr = (clr & 0xFF000000) | (((clr & 0x00FEFEFE) + 0x4E0E4E) / 2);
rslt.blendColor(clr);
if((clr & 0xFF000000) != 0) {
if(swamp_shaded && (mapiter.getBiome() == Biome.SWAMPLAND))
clr = (clr & 0xFF000000) | (((clr & 0x00FEFEFE) + 0x4E0E4E) / 2);
rslt.blendColor(clr);
}
}
}
@@ -273,7 +273,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
int ty = mtile.py/KzedMap.tileHeight;
FileLockManager.getWriteLock(fname);
try {
if((!fname.exists()) || (crc != hashman.getImageHashCode(mtile.getKey(), null, tx, ty))) {
if((!fname.exists()) || (crc != hashman.getImageHashCode(mtile.getKey(prefix), null, tx, ty))) {
Debug.debug("saving image " + fname.getPath());
if(!fname.getParentFile().exists())
fname.getParentFile().mkdirs();
@@ -285,14 +285,14 @@ public class DefaultTileRenderer implements MapTileRenderer {
Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e);
}
MapManager.mapman.pushUpdate(mtile.getWorld(), new Client.Tile(mtile.getFilename()));
hashman.updateHashCode(mtile.getKey(), null, tx, ty, crc);
hashman.updateHashCode(mtile.getKey(prefix), null, tx, ty, crc);
updated_fname = true;
}
} finally {
FileLockManager.releaseWriteLock(fname);
DynmapBufferedImage.freeBufferedImage(img);
}
MapManager.mapman.updateStatistics(mtile, null, true, updated_fname, !rendered);
MapManager.mapman.updateStatistics(mtile, prefix, true, updated_fname, !rendered);
mtile.file = fname;
@@ -303,7 +303,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
crc = hashman.calculateTileHash(img.argb_buf);
FileLockManager.getWriteLock(dfname);
try {
if((!dfname.exists()) || (crc != hashman.getImageHashCode(mtile.getKey(), "day", tx, ty))) {
if((!dfname.exists()) || (crc != hashman.getImageHashCode(mtile.getKey(prefix), "day", tx, ty))) {
Debug.debug("saving image " + dfname.getPath());
if(!dfname.getParentFile().exists())
dfname.getParentFile().mkdirs();
@@ -315,14 +315,14 @@ public class DefaultTileRenderer implements MapTileRenderer {
Debug.error("Failed to save image (NullPointerException): " + dfname.getPath(), e);
}
MapManager.mapman.pushUpdate(mtile.getWorld(), new Client.Tile(mtile.getDayFilename()));
hashman.updateHashCode(mtile.getKey(), "day", tx, ty, crc);
hashman.updateHashCode(mtile.getKey(prefix), "day", tx, ty, crc);
updated_dfname = true;
}
} finally {
FileLockManager.releaseWriteLock(dfname);
DynmapBufferedImage.freeBufferedImage(img_day);
}
MapManager.mapman.updateStatistics(mtile, "day", true, updated_dfname, !rendered);
MapManager.mapman.updateStatistics(mtile, prefix+"_day", true, updated_dfname, !rendered);
}
// Since we've already got the new tile, and we're on an async thread, just
@@ -98,8 +98,8 @@ public class KzedMapTile extends MapTile {
return o.px == px && o.py == py && (o.map == map) && (o.getWorld() == getWorld());
}
public String getKey() {
return getWorld().getName() + "." + renderer.getPrefix();
public String getKey(String prefix) {
return getWorld().getName() + "." + prefix;
}
public String toString() {

Some files were not shown because too many files have changed in this diff Show More