diff --git a/DynmapCore/src/main/java/org/dynmap/DynmapWorld.java b/DynmapCore/src/main/java/org/dynmap/DynmapWorld.java index 85ff89e1..e116ff97 100644 --- a/DynmapCore/src/main/java/org/dynmap/DynmapWorld.java +++ b/DynmapCore/src/main/java/org/dynmap/DynmapWorld.java @@ -128,6 +128,7 @@ public abstract class DynmapWorld { private static final int[] stepseq = { 3, 1, 2, 0 }; private void processZoomFile(MapTypeState mts, MapStorageTile tile, boolean firstVariant) { + long mostRecentTimestamp = 0; int step = 1 << tile.zoom; MapStorageTile ztile = tile.getZoomOutTile(); int width = 128, height = 128; @@ -158,6 +159,8 @@ public abstract class DynmapWorld { BufferedImage im = null; try { im = ImageIOManager.imageIODecode(tr); + // Only consider the timestamp when the tile exists and isn't broken + mostRecentTimestamp = Math.max(mostRecentTimestamp, tr.lastModified); } catch (IOException iox) { // Broken file - zap it tile1.delete(); @@ -238,7 +241,7 @@ public abstract class DynmapWorld { } } else /* if (!ztile.matchesHashCode(crc)) */ { - ztile.write(crc, zIm); + ztile.write(crc, zIm, (mostRecentTimestamp == 0)? System.currentTimeMillis() : mostRecentTimestamp); MapManager.mapman.pushUpdate(this, new Client.Tile(ztile.getURI())); enqueueZoomOutUpdate(ztile); } diff --git a/DynmapCore/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java b/DynmapCore/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java index b3ef44f0..1b8772fa 100644 --- a/DynmapCore/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java +++ b/DynmapCore/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java @@ -1178,6 +1178,7 @@ public class IsoHDPerspective implements HDPerspective { @Override public boolean render(MapChunkCache cache, HDMapTile tile, String mapname) { + final long startTimestamp = System.currentTimeMillis(); Color rslt = new Color(); MapIterator mapiter = cache.getIterator(0, 0, 0); DynmapWorld world = tile.getDynmapWorld(); @@ -1305,7 +1306,7 @@ public class IsoHDPerspective implements HDPerspective { if(mtile.matchesHashCode(crc) == false) { /* Wrap buffer as buffered image */ if(rendered[i]) { - mtile.write(crc, im[i].buf_img); + mtile.write(crc, im[i].buf_img, startTimestamp); } else { mtile.delete(); @@ -1336,7 +1337,7 @@ public class IsoHDPerspective implements HDPerspective { if(mtile.matchesHashCode(crc) == false) { /* Wrap buffer as buffered image */ if(rendered[i]) { - mtile.write(crc, dayim[i].buf_img); + mtile.write(crc, dayim[i].buf_img, startTimestamp); } else { mtile.delete(); diff --git a/DynmapCore/src/main/java/org/dynmap/storage/MapStorageTile.java b/DynmapCore/src/main/java/org/dynmap/storage/MapStorageTile.java index 7a33f47e..d15b725b 100644 --- a/DynmapCore/src/main/java/org/dynmap/storage/MapStorageTile.java +++ b/DynmapCore/src/main/java/org/dynmap/storage/MapStorageTile.java @@ -57,7 +57,7 @@ public abstract class MapStorageTile { * @param encImage - output stream for encoded image * @return true if write succeeded */ - public abstract boolean write(long hash, BufferOutputStream encImage); + public abstract boolean write(long hash, BufferOutputStream encImage, long timestamp); /** * Write tile from image * @@ -65,10 +65,10 @@ public abstract class MapStorageTile { * @param image - image to be encoded * @return true if write succeeded */ - public boolean write(long hash, BufferedImage image) { + public boolean write(long hash, BufferedImage image, long timestamp) { BufferOutputStream bos = ImageIOManager.imageIOEncode(image, map.getImageFormat()); if (bos != null) { - return write(hash, bos); + return write(hash, bos, timestamp); } return false; } @@ -78,7 +78,7 @@ public abstract class MapStorageTile { * @return true if write succeeded */ public boolean delete() { - return write(-1, (BufferOutputStream) null); + return write(-1, (BufferOutputStream) null, -1); } /** * Get write lock on tile diff --git a/DynmapCore/src/main/java/org/dynmap/storage/filetree/FileTreeMapStorage.java b/DynmapCore/src/main/java/org/dynmap/storage/filetree/FileTreeMapStorage.java index 11b597d2..fee5bab5 100644 --- a/DynmapCore/src/main/java/org/dynmap/storage/filetree/FileTreeMapStorage.java +++ b/DynmapCore/src/main/java/org/dynmap/storage/filetree/FileTreeMapStorage.java @@ -136,7 +136,7 @@ public class FileTreeMapStorage extends MapStorage { } @Override - public boolean write(long hash, BufferOutputStream encImage) { + public boolean write(long hash, BufferOutputStream encImage, long timestamp) { File ff = getTileFile(map.getImageFormat().getEncoding()); List ffalt = getTileFilesAltFormats(); File ffpar = ff.getParentFile(); @@ -158,7 +158,7 @@ public class FileTreeMapStorage extends MapStorage { if (ffpar.exists() == false) { ffpar.mkdirs(); } - if (replaceFile(ff, encImage.buf, encImage.len) == false) { + if (replaceFile(ff, encImage.buf, encImage.len, timestamp) == false) { return false; } hashmap.updateHashCode(world.getName() + "." + map.getPrefix(), x, y, hash); @@ -627,8 +627,12 @@ public class FileTreeMapStorage extends MapStorage { public String getTilesURI(boolean login_enabled) { return login_enabled?"standalone/tiles.php?tile=":"tiles/"; } - + private boolean replaceFile(File f, byte[] b, int len) { + return replaceFile(f, b, len, System.currentTimeMillis()); + } + + private boolean replaceFile(File f, byte[] b, int len, long timestamp) { boolean done = false; File fold = new File(f.getPath() + ".old"); File fnew = new File(f.getPath() + ".new"); @@ -649,6 +653,8 @@ public class FileTreeMapStorage extends MapStorage { else { fnew.renameTo(f); } + // Use the supplied timestamp + f.setLastModified(timestamp); done = true; } catch (IOException iox) { if (raf != null) { try { raf.close(); } catch (IOException x) {} } diff --git a/DynmapCore/src/main/java/org/dynmap/storage/mariadb/MariaDBMapStorage.java b/DynmapCore/src/main/java/org/dynmap/storage/mariadb/MariaDBMapStorage.java index 6ca0acb4..d17d13e5 100644 --- a/DynmapCore/src/main/java/org/dynmap/storage/mariadb/MariaDBMapStorage.java +++ b/DynmapCore/src/main/java/org/dynmap/storage/mariadb/MariaDBMapStorage.java @@ -145,7 +145,7 @@ public class MariaDBMapStorage extends MapStorage { } @Override - public boolean write(long hash, BufferOutputStream encImage) { + public boolean write(long hash, BufferOutputStream encImage, long timestamp) { if (mapkey == null) return false; Connection c = null; boolean err = false; @@ -166,7 +166,7 @@ public class MariaDBMapStorage extends MapStorage { else if (exists) { stmt = c.prepareStatement("UPDATE " + tableTiles + " SET HashCode=?, LastUpdate=?, Format=?, Image=? WHERE MapID=? AND x=? and y=? AND zoom=?;"); stmt.setLong(1, hash); - stmt.setLong(2, System.currentTimeMillis()); + stmt.setLong(2, timestamp); stmt.setInt(3, map.getImageFormat().getEncoding().ordinal()); stmt.setBinaryStream(4, new BufferInputStream(encImage.buf, encImage.len), encImage.len); stmt.setInt(5, mapkey); @@ -181,7 +181,7 @@ public class MariaDBMapStorage extends MapStorage { stmt.setInt(3, y); stmt.setInt(4, zoom); stmt.setLong(5, hash); - stmt.setLong(6, System.currentTimeMillis()); + stmt.setLong(6, timestamp); stmt.setInt(7, map.getImageFormat().getEncoding().ordinal()); stmt.setBinaryStream(8, new BufferInputStream(encImage.buf, encImage.len), encImage.len); } diff --git a/DynmapCore/src/main/java/org/dynmap/storage/mysql/MySQLMapStorage.java b/DynmapCore/src/main/java/org/dynmap/storage/mysql/MySQLMapStorage.java index cdd069de..61f249f0 100644 --- a/DynmapCore/src/main/java/org/dynmap/storage/mysql/MySQLMapStorage.java +++ b/DynmapCore/src/main/java/org/dynmap/storage/mysql/MySQLMapStorage.java @@ -146,7 +146,7 @@ public class MySQLMapStorage extends MapStorage { } @Override - public boolean write(long hash, BufferOutputStream encImage) { + public boolean write(long hash, BufferOutputStream encImage, long timestamp) { if (mapkey == null) return false; Connection c = null; boolean err = false; @@ -167,7 +167,7 @@ public class MySQLMapStorage extends MapStorage { else if (exists) { stmt = c.prepareStatement("UPDATE " + tableTiles + " SET HashCode=?, LastUpdate=?, Format=?, Image=? WHERE MapID=? AND x=? and y=? AND zoom=?;"); stmt.setLong(1, hash); - stmt.setLong(2, System.currentTimeMillis()); + stmt.setLong(2, timestamp); stmt.setInt(3, map.getImageFormat().getEncoding().ordinal()); stmt.setBinaryStream(4, new BufferInputStream(encImage.buf, encImage.len), encImage.len); stmt.setInt(5, mapkey); @@ -182,7 +182,7 @@ public class MySQLMapStorage extends MapStorage { stmt.setInt(3, y); stmt.setInt(4, zoom); stmt.setLong(5, hash); - stmt.setLong(6, System.currentTimeMillis()); + stmt.setLong(6, timestamp); stmt.setInt(7, map.getImageFormat().getEncoding().ordinal()); stmt.setBinaryStream(8, new BufferInputStream(encImage.buf, encImage.len), encImage.len); } diff --git a/DynmapCore/src/main/java/org/dynmap/storage/postgresql/PostgreSQLMapStorage.java b/DynmapCore/src/main/java/org/dynmap/storage/postgresql/PostgreSQLMapStorage.java index 231b19ce..55c97d64 100644 --- a/DynmapCore/src/main/java/org/dynmap/storage/postgresql/PostgreSQLMapStorage.java +++ b/DynmapCore/src/main/java/org/dynmap/storage/postgresql/PostgreSQLMapStorage.java @@ -149,7 +149,7 @@ public class PostgreSQLMapStorage extends MapStorage { } @Override - public boolean write(long hash, BufferOutputStream encImage) { + public boolean write(long hash, BufferOutputStream encImage, long timestamp) { if (mapkey == null) return false; Connection c = null; boolean err = false; @@ -170,7 +170,7 @@ public class PostgreSQLMapStorage extends MapStorage { else if (exists) { stmt = c.prepareStatement("UPDATE " + tableTiles + " SET HashCode=?, LastUpdate=?, Format=?, Image=? WHERE MapID=? AND x=? and y=? AND zoom=?;"); stmt.setLong(1, hash); - stmt.setLong(2, System.currentTimeMillis()); + stmt.setLong(2, timestamp); stmt.setInt(3, map.getImageFormat().getEncoding().ordinal()); stmt.setBinaryStream(4, new BufferInputStream(encImage.buf, encImage.len), encImage.len); stmt.setInt(5, mapkey); @@ -185,7 +185,7 @@ public class PostgreSQLMapStorage extends MapStorage { stmt.setInt(3, y); stmt.setInt(4, zoom); stmt.setLong(5, hash); - stmt.setLong(6, System.currentTimeMillis()); + stmt.setLong(6, timestamp); stmt.setInt(7, map.getImageFormat().getEncoding().ordinal()); stmt.setBinaryStream(8, new BufferInputStream(encImage.buf, encImage.len), encImage.len); } diff --git a/DynmapCore/src/main/java/org/dynmap/storage/sqllte/SQLiteMapStorage.java b/DynmapCore/src/main/java/org/dynmap/storage/sqllte/SQLiteMapStorage.java index a8bc94ea..0d6678c1 100644 --- a/DynmapCore/src/main/java/org/dynmap/storage/sqllte/SQLiteMapStorage.java +++ b/DynmapCore/src/main/java/org/dynmap/storage/sqllte/SQLiteMapStorage.java @@ -139,7 +139,7 @@ public class SQLiteMapStorage extends MapStorage { } @Override - public boolean write(long hash, BufferOutputStream encImage) { + public boolean write(long hash, BufferOutputStream encImage, long timestamp) { if (mapkey == null) return false; Connection c = null; boolean err = false; @@ -160,7 +160,7 @@ public class SQLiteMapStorage extends MapStorage { else if (exists) { stmt = c.prepareStatement("UPDATE Tiles SET HashCode=?, LastUpdate=?, Format=?, Image=?, ImageLen=? WHERE MapID=? AND x=? and y=? AND zoom=?;"); stmt.setLong(1, hash); - stmt.setLong(2, System.currentTimeMillis()); + stmt.setLong(2, timestamp); stmt.setInt(3, map.getImageFormat().getEncoding().ordinal()); stmt.setBytes(4, encImage.buf); stmt.setInt(5, encImage.len); @@ -176,7 +176,7 @@ public class SQLiteMapStorage extends MapStorage { stmt.setInt(3, y); stmt.setInt(4, zoom); stmt.setLong(5, hash); - stmt.setLong(6, System.currentTimeMillis()); + stmt.setLong(6, timestamp); stmt.setInt(7, map.getImageFormat().getEncoding().ordinal()); stmt.setBytes(8, encImage.buf); stmt.setInt(9, encImage.len);