diff --git a/apps/i2psnark/java/src/org/klomp/snark/CompleteListener.java b/apps/i2psnark/java/src/org/klomp/snark/CompleteListener.java index bd2f78e53..1d48654ba 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/CompleteListener.java +++ b/apps/i2psnark/java/src/org/klomp/snark/CompleteListener.java @@ -54,8 +54,15 @@ public interface CompleteListener { */ public void gotPiece(Snark snark); - // not really listeners but the easiest way to get back to an optional SnarkManager + /** not really listeners but the easiest way to get back to an optional SnarkManager */ public long getSavedTorrentTime(Snark snark); public BitField getSavedTorrentBitField(Snark snark); + /** + * @since 0.9.15 + */ public boolean getSavedPreserveNamesSetting(Snark snark); + /** + * @since 0.9.15 + */ + public long getSavedUploaded(Snark snark); } diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java index 3dcb535cb..382ca4817 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java @@ -281,6 +281,14 @@ class PeerCoordinator implements PeerListener return uploaded; } + /** + * Sets the initial total of uploaded bytes of all peers (from a saved status) + * @since 0.9.15 + */ + public void setUploaded(long up) { + uploaded = up; + } + /** * Returns the total number of downloaded bytes of all peers. */ diff --git a/apps/i2psnark/java/src/org/klomp/snark/Snark.java b/apps/i2psnark/java/src/org/klomp/snark/Snark.java index 9358623b7..740b7c2be 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Snark.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Snark.java @@ -237,6 +237,7 @@ public class Snark private volatile boolean _autoStoppable; // String indicating main activity private volatile String activity = "Not started"; + private final long savedUploaded; /** @@ -463,6 +464,7 @@ public class Snark trackerclient = new TrackerClient(meta, coordinator); */ + savedUploaded = (completeListener != null) ? completeListener.getSavedUploaded(this) : 0; if (start) startTorrent(); } @@ -488,6 +490,7 @@ public class Snark this.infoHash = ih; this.additionalTrackerURL = trackerURL; this.rootDataDir = rootDir != null ? new File(rootDir) : null; // null only for FetchAndAdd extension + savedUploaded = 0; stopped = true; id = generateID(); @@ -556,6 +559,7 @@ public class Snark _log.info("Starting PeerCoordinator, ConnectionAcceptor, and TrackerClient"); activity = "Collecting pieces"; coordinator = new PeerCoordinator(_util, id, infoHash, meta, storage, this, this); + coordinator.setUploaded(savedUploaded); if (_peerCoordinatorSet != null) { // multitorrent _peerCoordinatorSet.add(coordinator); @@ -619,7 +623,7 @@ public class Snark pc.halt(); Storage st = storage; if (st != null) { - boolean changed = storage.isChanged(); + boolean changed = storage.isChanged() || getUploaded() != savedUploaded; try { storage.close(); } catch (IOException ioe) { @@ -773,7 +777,7 @@ public class Snark PeerCoordinator coord = coordinator; if (coord != null) return coord.getUploaded(); - return 0; + return savedUploaded; } /** diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index b910e32d5..30e21752e 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -92,6 +92,7 @@ public class SnarkManager implements CompleteListener { private static final String PROP_META_BITFIELD = "bitfield"; private static final String PROP_META_PRIORITY = "priority"; private static final String PROP_META_PRESERVE_NAMES = "preserveFileNames"; + private static final String PROP_META_UPLOADED = "uploaded"; //private static final String PROP_META_BITFIELD_SUFFIX = ".bitfield"; //private static final String PROP_META_PRIORITY_SUFFIX = ".priority"; private static final String PROP_META_MAGNET_PREFIX = "i2psnark.magnet."; @@ -1357,7 +1358,7 @@ public class SnarkManager implements CompleteListener { return false; } // so addTorrent won't recheck - saveTorrentStatus(metainfo, bitfield, null, baseFile, true); // no file priorities + saveTorrentStatus(metainfo, bitfield, null, baseFile, true, 0); // no file priorities try { locked_writeMetaInfo(metainfo, filename, areFilesPublic()); // hold the lock for a long time @@ -1522,6 +1523,21 @@ public class SnarkManager implements CompleteListener { Properties config = getConfig(snark); return Boolean.parseBoolean(config.getProperty(PROP_META_PRESERVE_NAMES)); } + + /** + * Get setting for a torrent from the config file. + * @return setting, 0 if not found + * @since 0.9.15 + */ + public long getSavedUploaded(Snark snark) { + Properties config = getConfig(snark); + if (config != null) { + try { + return Long.parseLong(config.getProperty(PROP_META_UPLOADED)); + } catch (NumberFormatException nfe) {} + } + return 0; + } /** * Save the completion status of a torrent and other data in the config file @@ -1535,7 +1551,8 @@ public class SnarkManager implements CompleteListener { if (meta == null || storage == null) return; saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(), - storage.getBase(), storage.getPreserveFileNames()); + storage.getBase(), storage.getPreserveFileNames(), + snark.getUploaded()); } /** @@ -1550,14 +1567,14 @@ public class SnarkManager implements CompleteListener { * @param base may be null */ private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities, - File base, boolean preserveNames) { + File base, boolean preserveNames, long uploaded) { synchronized (_configLock) { - locked_saveTorrentStatus(metainfo, bitfield, priorities, base, preserveNames); + locked_saveTorrentStatus(metainfo, bitfield, priorities, base, preserveNames, uploaded); } } private void locked_saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities, - File base, boolean preserveNames) { + File base, boolean preserveNames, long uploaded) { byte[] ih = metainfo.getInfoHash(); String bfs; if (bitfield.complete()) { @@ -1570,6 +1587,7 @@ public class SnarkManager implements CompleteListener { config.setProperty(PROP_META_STAMP, Long.toString(System.currentTimeMillis())); config.setProperty(PROP_META_BITFIELD, bfs); config.setProperty(PROP_META_PRESERVE_NAMES, Boolean.toString(preserveNames)); + config.setProperty(PROP_META_UPLOADED, Long.toString(uploaded)); if (base != null) config.setProperty(PROP_META_BASE, base.getAbsolutePath()); @@ -1826,7 +1844,7 @@ public class SnarkManager implements CompleteListener { Storage storage = snark.getStorage(); if (meta != null && storage != null) saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(), - storage.getBase(), storage.getPreserveFileNames()); + storage.getBase(), storage.getPreserveFileNames(), snark.getUploaded()); } /** @@ -1849,7 +1867,7 @@ public class SnarkManager implements CompleteListener { return null; } saveTorrentStatus(meta, storage.getBitField(), null, - storage.getBase(), storage.getPreserveFileNames()); // no file priorities + storage.getBase(), storage.getPreserveFileNames(), 0); // temp for addMessage() in case canonical throws String name = storage.getBaseName(); try { diff --git a/apps/i2psnark/java/src/org/klomp/snark/UpdateRunner.java b/apps/i2psnark/java/src/org/klomp/snark/UpdateRunner.java index db35a6910..d7f3b6690 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/UpdateRunner.java +++ b/apps/i2psnark/java/src/org/klomp/snark/UpdateRunner.java @@ -295,6 +295,10 @@ class UpdateRunner implements UpdateTask, CompleteListener { return _smgr.getSavedPreserveNamesSetting(snark); } + public long getSavedUploaded(Snark snark) { + return _smgr.getSavedUploaded(snark); + } + //////// end CompleteListener methods private static String linkify(String url) { diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index 8ff57e430..96890d8f1 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -498,7 +498,7 @@ public class I2PSnarkServlet extends BasicServlet { out.write(_("RX")); out.write("\">"); out.write("\n