From a92fc3b76e9d8f8c7cf7ea4172266f956d55a1b4 Mon Sep 17 00:00:00 2001 From: Yat Ho Date: Sun, 14 Jul 2024 15:37:43 +0800 Subject: [PATCH] fix: loading `2.20-3.00` progress from resume (#6896) * fix: loading `2.20-3.00` progress from resume * code review: fix always 0 --- libtransmission/resume.cc | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/libtransmission/resume.cc b/libtransmission/resume.cc index 4ac327ed8..c91e95786 100644 --- a/libtransmission/resume.cc +++ b/libtransmission/resume.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -523,16 +524,28 @@ tr_resume::fields_t loadProgress(tr_variant* dict, tr_torrent* tor, tr_torrent:: } else if (b != nullptr && b->holds_alternative()) { + // The first element (idx 0) stores a base value for all piece timestamps, + // which would be the value of the smallest piece timestamp minus 1. + // + // The rest of the elements are the timestamp of each piece, stored as + // an offset to the base value. + // i.e. idx 1 <-> piece 0, idx 2 <-> piece 1, ... + // timestamp of piece n = idx 0 + idx n+1 + // + // Pieces that haven't been checked will have a timestamp offset of 0. + // They can be differentiated from the oldest checked piece(s) since the + // offset for any checked pieces will be at least 1. + auto offset = int64_t{}; tr_variantGetInt(tr_variantListChild(b, 0), &offset); - time_checked = tr_time(); auto const [piece_begin, piece_end] = tor->piece_span_for_file(fi); - for (size_t i = 0, n = piece_end - piece_begin; i < n; ++i) + time_checked = std::numeric_limits::max(); + for (tr_piece_index_t i = 1, n = piece_end - piece_begin; i <= n; ++i) { - int64_t piece_time = 0; - tr_variantGetInt(tr_variantListChild(b, i + 1), &piece_time); - time_checked = std::min(time_checked, time_t(piece_time)); + auto t = int64_t{}; + tr_variantGetInt(tr_variantListChild(b, i), &t); + time_checked = std::min(time_checked, time_t(t != 0 ? t + offset : 0)); } }