mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-11-28 13:15:30 +01:00
Merge pull request #237 from mikeprimm/master
Fix occasional broken zoom-out tiles due to hash code calculation error
This commit is contained in:
commit
fcb865ea28
@ -35,14 +35,16 @@ public class DynmapWorld {
|
|||||||
private int extrazoomoutlevels; /* Number of additional zoom out levels to generate */
|
private int extrazoomoutlevels; /* Number of additional zoom out levels to generate */
|
||||||
public File worldtilepath;
|
public File worldtilepath;
|
||||||
private Object lock = new Object();
|
private Object lock = new Object();
|
||||||
private HashSet<File> zoomoutupdates[];
|
private HashSet<String> zoomoutupdates[];
|
||||||
|
private boolean checkts = true; /* Check timestamps on first run with new configuration */
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void setExtraZoomOutLevels(int lvl) {
|
public void setExtraZoomOutLevels(int lvl) {
|
||||||
extrazoomoutlevels = lvl;
|
extrazoomoutlevels = lvl;
|
||||||
zoomoutupdates = new HashSet[lvl];
|
zoomoutupdates = new HashSet[lvl];
|
||||||
for(int i = 0; i < lvl; i++)
|
for(int i = 0; i < lvl; i++)
|
||||||
zoomoutupdates[i] = new HashSet<File>();
|
zoomoutupdates[i] = new HashSet<String>();
|
||||||
|
checkts = true;
|
||||||
}
|
}
|
||||||
public int getExtraZoomOutLevels() { return extrazoomoutlevels; }
|
public int getExtraZoomOutLevels() { return extrazoomoutlevels; }
|
||||||
|
|
||||||
@ -54,7 +56,7 @@ public class DynmapWorld {
|
|||||||
if(level >= extrazoomoutlevels)
|
if(level >= extrazoomoutlevels)
|
||||||
return;
|
return;
|
||||||
synchronized(lock) {
|
synchronized(lock) {
|
||||||
zoomoutupdates[level].add(f);
|
zoomoutupdates[level].add(f.getPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +64,7 @@ public class DynmapWorld {
|
|||||||
if(level >= extrazoomoutlevels)
|
if(level >= extrazoomoutlevels)
|
||||||
return false;
|
return false;
|
||||||
synchronized(lock) {
|
synchronized(lock) {
|
||||||
return zoomoutupdates[level].remove(f);
|
return zoomoutupdates[level].remove(f.getPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,6 +94,7 @@ public class DynmapWorld {
|
|||||||
for(int i = 0; i < extrazoomoutlevels; i++) {
|
for(int i = 0; i < extrazoomoutlevels; i++) {
|
||||||
freshenZoomOutFilesByLevel(i);
|
freshenZoomOutFilesByLevel(i);
|
||||||
}
|
}
|
||||||
|
checkts = false; /* Just handle queued updates after first scan */
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class PrefixData {
|
private static class PrefixData {
|
||||||
@ -105,10 +108,6 @@ public class DynmapWorld {
|
|||||||
String zfnprefix;
|
String zfnprefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* File based scan - used for priming map after server startup
|
|
||||||
* @param zoomlevel
|
|
||||||
*/
|
|
||||||
public void freshenZoomOutFilesByLevel(int zoomlevel) {
|
public void freshenZoomOutFilesByLevel(int zoomlevel) {
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
Debug.debug("freshenZoomOutFiles(" + world.getName() + "," + zoomlevel + ")");
|
Debug.debug("freshenZoomOutFiles(" + world.getName() + "," + zoomlevel + ")");
|
||||||
@ -211,7 +210,7 @@ public class DynmapWorld {
|
|||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
/* Do processing */
|
/* Do processing */
|
||||||
for(ProcessTileRec s : toprocess.values()) {
|
for(ProcessTileRec s : toprocess.values()) {
|
||||||
processZoomTile(pd, dir, s.zf, s.zfname, s.x - (pd.neg_step_x?step:0), s.y);
|
processZoomTile(pd, dir, s.zf, s.zfname, s.x, s.y);
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
Debug.debug("processZoomDirectory(" + dir.getPath() + "," + pd.baseprefix + ") - done (" + cnt + " files)");
|
Debug.debug("processZoomDirectory(" + dir.getPath() + "," + pd.baseprefix + ") - done (" + cnt + " files)");
|
||||||
@ -219,6 +218,11 @@ public class DynmapWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ProcessTileRec processZoomFile(File f, PrefixData pd) {
|
private ProcessTileRec processZoomFile(File f, PrefixData pd) {
|
||||||
|
/* If not checking timstamp, we're out if nothing queued for this file */
|
||||||
|
if(!checkts) {
|
||||||
|
if(!popQueuedUpdate(f, pd.zoomlevel))
|
||||||
|
return null;
|
||||||
|
}
|
||||||
int step = pd.stepsize << pd.zoomlevel;
|
int step = pd.stepsize << pd.zoomlevel;
|
||||||
String fn = f.getName();
|
String fn = f.getName();
|
||||||
/* Parse filename to predict zoomed out file */
|
/* Parse filename to predict zoomed out file */
|
||||||
@ -250,10 +254,12 @@ public class DynmapWorld {
|
|||||||
/* Make name of corresponding zoomed tile */
|
/* Make name of corresponding zoomed tile */
|
||||||
String zfname = makeFilePath(pd, x, y, true);
|
String zfname = makeFilePath(pd, x, y, true);
|
||||||
File zf = new File(worldtilepath, zfname);
|
File zf = new File(worldtilepath, zfname);
|
||||||
|
if(checkts) { /* If checking timestamp, see if we need update based on enqueued update OR old file time */
|
||||||
/* If we're not updated, and zoom file exists and is older than our file, nothing to do */
|
/* If we're not updated, and zoom file exists and is older than our file, nothing to do */
|
||||||
if((!popQueuedUpdate(f, pd.zoomlevel)) && zf.exists() && (zf.lastModified() >= f.lastModified())) {
|
if((!popQueuedUpdate(f, pd.zoomlevel)) && zf.exists() && (zf.lastModified() >= f.lastModified())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ProcessTileRec rec = new ProcessTileRec();
|
ProcessTileRec rec = new ProcessTileRec();
|
||||||
rec.zf = zf;
|
rec.zf = zf;
|
||||||
rec.x = x;
|
rec.x = x;
|
||||||
@ -269,6 +275,8 @@ public class DynmapWorld {
|
|||||||
KzedBufferedImage kzIm = null;
|
KzedBufferedImage kzIm = null;
|
||||||
int[] argb = new int[width*height];
|
int[] argb = new int[width*height];
|
||||||
int step = pd.stepsize << pd.zoomlevel;
|
int step = pd.stepsize << pd.zoomlevel;
|
||||||
|
int ztx = tx;
|
||||||
|
tx = tx - (pd.neg_step_x?step:0); /* Adjust for negative step */
|
||||||
|
|
||||||
/* create image buffer */
|
/* create image buffer */
|
||||||
kzIm = KzedMap.allocateBufferedImage(width, height);
|
kzIm = KzedMap.allocateBufferedImage(width, height);
|
||||||
@ -279,6 +287,7 @@ public class DynmapWorld {
|
|||||||
if(f.exists()) {
|
if(f.exists()) {
|
||||||
BufferedImage im = null;
|
BufferedImage im = null;
|
||||||
FileLockManager.getReadLock(f);
|
FileLockManager.getReadLock(f);
|
||||||
|
popQueuedUpdate(f, pd.zoomlevel);
|
||||||
try {
|
try {
|
||||||
im = ImageIO.read(f);
|
im = ImageIO.read(f);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -316,10 +325,10 @@ public class DynmapWorld {
|
|||||||
}
|
}
|
||||||
FileLockManager.getWriteLock(zf);
|
FileLockManager.getWriteLock(zf);
|
||||||
TileHashManager hashman = MapManager.mapman.hashman;
|
TileHashManager hashman = MapManager.mapman.hashman;
|
||||||
long crc = hashman.calculateTileHash(argb); /* Get hash of tile */
|
long crc = hashman.calculateTileHash(kzIm.argb_buf); /* Get hash of tile */
|
||||||
int tilex = tx/step/2;
|
int tilex = ztx/step/2;
|
||||||
int tiley = ty/step/2;
|
int tiley = ty/step/2;
|
||||||
String key = world.getName()+"."+pd.zoomprefix+pd.baseprefix;
|
String key = world.getName()+".z"+pd.zoomprefix+pd.baseprefix;
|
||||||
if((!zf.exists()) || (crc != MapManager.mapman.hashman.getImageHashCode(key, null, tilex, tiley))) {
|
if((!zf.exists()) || (crc != MapManager.mapman.hashman.getImageHashCode(key, null, tilex, tiley))) {
|
||||||
try {
|
try {
|
||||||
if(!zf.getParentFile().exists())
|
if(!zf.getParentFile().exists())
|
||||||
@ -335,9 +344,6 @@ public class DynmapWorld {
|
|||||||
MapManager.mapman.pushUpdate(this.world, new Client.Tile(zfname));
|
MapManager.mapman.pushUpdate(this.world, new Client.Tile(zfname));
|
||||||
enqueueZoomOutUpdate(zf, pd.zoomlevel+1);
|
enqueueZoomOutUpdate(zf, pd.zoomlevel+1);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
zf.setLastModified(System.currentTimeMillis()); /* Touch the existing file */
|
|
||||||
}
|
|
||||||
FileLockManager.releaseWriteLock(zf);
|
FileLockManager.releaseWriteLock(zf);
|
||||||
KzedMap.freeBufferedImage(kzIm);
|
KzedMap.freeBufferedImage(kzIm);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user