Skip to content

Commit

Permalink
AFAICT this is working as it should.
Browse files Browse the repository at this point in the history
If any file is missing the torrent will not be marked complete. Missing
zero length files don't impact partial seeding status as no-one would
try downloading them.
  • Loading branch information
alanmcgovern committed Aug 19, 2024
1 parent ac10de8 commit e591363
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ public override void Tick (int counter)

internal async Task UpdateSeedingDownloadingState ()
{
// FIXME: Ensure this properly handles the case where files are missing.

//If download is fully complete, set state to 'Seeding' and send an announce to the tracker.
if (Manager.Complete && state == TorrentState.Downloading) {
state = TorrentState.Seeding;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,28 @@ public async Task SetFilePriorityAsync (ITorrentManagerFile file, Priority prior
if (oldPriority == Priority.DoNotDownload && !(await Engine.DiskManager.CheckFileExistsAsync (file))) {
// Always create the file the user requested to download
await Engine.DiskManager.CreateAsync (file, Engine.Settings.FileCreationOptions);

if (file.Length == 0)
((TorrentFileInfo) file).BitField[0] = await Engine.DiskManager.CheckFileExistsAsync (file);
}

// Update the priority for the file itself now that we've successfully created it!
((TorrentFileInfo) file).Priority = priority;

if (oldPriority == Priority.DoNotDownload && file.Length > 0) {
// Look for any file which are still marked DoNotDownload but also overlap this file.
// We need to create those ones too because if there are three 400kB files and the
// piece length is 512kB, and the first file is set to 'DoNotDownload', then we still
// need to create it as we'll download the first 512kB under bittorrent v1.
foreach (var maybeCreateFile in Files.Where (t => t.Priority == Priority.DoNotDownload && t.Length > 0 && t != file)) {
foreach (var maybeCreateFile in Files.Where (t => t.Priority == Priority.DoNotDownload && t.Length > 0)) {
// If this file overlaps, create it!
if (maybeCreateFile.Overlaps(file) && !(await Engine.DiskManager.CheckFileExistsAsync (maybeCreateFile)))
await Engine.DiskManager.CreateAsync (maybeCreateFile, Engine.Settings.FileCreationOptions);
}
}
;

// With the new priority, calculate which files we're actively downloading!
if (needsToUpdateSelector) {
// If we change the priority of a file we need to figure out which files are marked
// as 'DoNotDownload' and which ones are downloadable.
Expand All @@ -130,7 +138,6 @@ public async Task SetFilePriorityAsync (ITorrentManagerFile file, Priority prior
}
}

((TorrentFileInfo) file).Priority = priority;
Mode.HandleFilePriorityChanged (file, oldPriority);
}

Expand Down Expand Up @@ -1119,7 +1126,7 @@ internal async Task LoadFastResumeAsync (FastResume data, bool skipStateCheckFor
internal async ReusableTask RefreshAllFilesCorrectLengthAsync ()
{
var allFilesCorrectLength = true;
foreach (TorrentFileInfo file in Files.Where (t => t.Priority != Priority.DoNotDownload)) {
foreach (TorrentFileInfo file in Files) {
var maybeLength = await Engine!.DiskManager.GetLengthAsync (file);

// Empty files aren't stored in fast resume data because it's as easy to just check if they exist on disk.
Expand All @@ -1129,7 +1136,7 @@ internal async ReusableTask RefreshAllFilesCorrectLengthAsync ()
// If any file doesn't exist, or any file is too large, indicate that something is wrong.
// If files exist but are too short, then we can assume everything is fine and the torrent just
// needs to be downloaded.
if (!maybeLength.HasValue || maybeLength > file.Length)
if (file.Priority != Priority.DoNotDownload && (!maybeLength.HasValue || maybeLength > file.Length))
allFilesCorrectLength = false;
}
AllFilesCorrectLength = allFilesCorrectLength;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ public async Task SaveLoadFastResume ()
[Test]
public async Task DoNotDownload_All ()
{
// No files exist!
Assert.AreEqual (0, PieceWriter.FilesWithLength.Count);

var bf = new BitField (Manager.Bitfield).SetAll (true);
var unhashed = new BitField (bf).SetAll (false);
await Manager.LoadFastResumeAsync (new FastResume (Manager.InfoHashes, bf, unhashed));
Expand All @@ -292,6 +295,8 @@ public async Task DoNotDownload_All ()
// No piece should be marked as available, and no pieces should actually be hashchecked.
Assert.IsTrue (Manager.Bitfield.AllFalse, "#2");
Assert.AreEqual (Manager.UnhashedPieces.TrueCount, Manager.UnhashedPieces.Length, "#3");

// Empty files will always have their bitfield set to true if they exist on disk. None should exist though
foreach (var f in Manager.Files)
Assert.IsTrue (f.BitField.AllFalse, "#4." + f.Path);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,7 @@ public async Task StartAsync_SetPriorityCreatesAllImplicatedFiles ()

await rig.Manager.SetFilePriorityAsync (rig.Manager.Files[0], Priority.Normal);
Assert.IsTrue (await writer.ExistsAsync (rig.Manager.Files[0]));
Assert.IsTrue (rig.Manager.Files[0].BitField.AllTrue);
Assert.IsFalse (await writer.ExistsAsync (rig.Manager.Files[1]));

await rig.Manager.SetFilePriorityAsync (rig.Manager.Files[1], Priority.Normal);
Expand Down

0 comments on commit e591363

Please sign in to comment.