2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2015-2023 Vladimir Golovnev <glassez@yandex.ru>
4 * Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * In addition, as a special exception, the copyright holders give permission to
21 * link this program with the OpenSSL project's "OpenSSL" library (or with
22 * modified versions of it that use the same license as the "OpenSSL" library),
23 * and distribute the linked executables. You must obey the GNU General Public
24 * License in all respects for all of the code used other than "OpenSSL". If you
25 * modify file(s), you may extend this exception to your version of the file(s),
26 * but you are not obligated to do so. If you do not wish to do so, delete this
27 * exception statement from your version.
35 #include <libtorrent/add_torrent_params.hpp>
36 #include <libtorrent/fwd.hpp>
37 #include <libtorrent/torrent_handle.hpp>
38 #include <libtorrent/torrent_info.hpp>
39 #include <libtorrent/torrent_status.hpp>
50 #include "base/path.h"
51 #include "base/tagset.h"
53 #include "speedmonitor.h"
54 #include "sslparameters.h"
56 #include "torrentcontentlayout.h"
57 #include "torrentinfo.h"
58 #include "trackerentrystatus.h"
63 struct LoadTorrentParams
;
65 enum class MoveStorageMode
72 enum class MoveStorageContext
74 AdjustCurrentLocation
,
79 enum class MaintenanceJob
88 lt::operation_t operation
= lt::operation_t::unknown
;
91 class TorrentImpl final
: public Torrent
94 Q_DISABLE_COPY_MOVE(TorrentImpl
)
97 TorrentImpl(SessionImpl
*session
, lt::session
*nativeSession
98 , const lt::torrent_handle
&nativeHandle
, const LoadTorrentParams
¶ms
);
99 ~TorrentImpl() override
;
101 bool isValid() const;
103 Session
*session() const override
;
105 InfoHash
infoHash() const override
;
106 QString
name() const override
;
107 QDateTime
creationDate() const override
;
108 QString
creator() const override
;
109 QString
comment() const override
;
110 bool isPrivate() const override
;
111 qlonglong
totalSize() const override
;
112 qlonglong
wantedSize() const override
;
113 qlonglong
completedSize() const override
;
114 qlonglong
pieceLength() const override
;
115 qlonglong
wastedSize() const override
;
116 QString
currentTracker() const override
;
118 bool isAutoTMMEnabled() const override
;
119 void setAutoTMMEnabled(bool enabled
) override
;
120 Path
savePath() const override
;
121 void setSavePath(const Path
&path
) override
;
122 Path
downloadPath() const override
;
123 void setDownloadPath(const Path
&path
) override
;
124 Path
actualStorageLocation() const override
;
125 Path
rootPath() const override
;
126 Path
contentPath() const override
;
127 QString
category() const override
;
128 bool belongsToCategory(const QString
&category
) const override
;
129 bool setCategory(const QString
&category
) override
;
131 TagSet
tags() const override
;
132 bool hasTag(const Tag
&tag
) const override
;
133 bool addTag(const Tag
&tag
) override
;
134 bool removeTag(const Tag
&tag
) override
;
135 void removeAllTags() override
;
137 int filesCount() const override
;
138 int piecesCount() const override
;
139 int piecesHave() const override
;
140 qreal
progress() const override
;
142 QDateTime
addedTime() const override
;
143 QDateTime
completedTime() const override
;
144 QDateTime
lastSeenComplete() const override
;
145 qlonglong
activeTime() const override
;
146 qlonglong
finishedTime() const override
;
147 qlonglong
timeSinceUpload() const override
;
148 qlonglong
timeSinceDownload() const override
;
149 qlonglong
timeSinceActivity() const override
;
151 qreal
ratioLimit() const override
;
152 void setRatioLimit(qreal limit
) override
;
153 int seedingTimeLimit() const override
;
154 void setSeedingTimeLimit(int limit
) override
;
155 int inactiveSeedingTimeLimit() const override
;
156 void setInactiveSeedingTimeLimit(int limit
) override
;
157 ShareLimitAction
shareLimitAction() const override
;
158 void setShareLimitAction(ShareLimitAction action
) override
;
160 Path
filePath(int index
) const override
;
161 Path
actualFilePath(int index
) const override
;
162 qlonglong
fileSize(int index
) const override
;
163 PathList
filePaths() const override
;
164 PathList
actualFilePaths() const override
;
165 QList
<DownloadPriority
> filePriorities() const override
;
167 TorrentInfo
info() const override
;
168 bool isFinished() const override
;
169 bool isStopped() const override
;
170 bool isQueued() const override
;
171 bool isForced() const override
;
172 bool isChecking() const override
;
173 bool isDownloading() const override
;
174 bool isMoving() const override
;
175 bool isUploading() const override
;
176 bool isCompleted() const override
;
177 bool isActive() const override
;
178 bool isInactive() const override
;
179 bool isErrored() const override
;
180 bool isSequentialDownload() const override
;
181 bool hasFirstLastPiecePriority() const override
;
182 TorrentState
state() const override
;
183 bool hasMetadata() const override
;
184 bool hasMissingFiles() const override
;
185 bool hasError() const override
;
186 int queuePosition() const override
;
187 QList
<TrackerEntryStatus
> trackers() const override
;
188 QList
<QUrl
> urlSeeds() const override
;
189 QString
error() const override
;
190 qlonglong
totalDownload() const override
;
191 qlonglong
totalUpload() const override
;
192 qlonglong
eta() const override
;
193 QList
<qreal
> filesProgress() const override
;
194 int seedsCount() const override
;
195 int peersCount() const override
;
196 int leechsCount() const override
;
197 int totalSeedsCount() const override
;
198 int totalPeersCount() const override
;
199 int totalLeechersCount() const override
;
200 int downloadLimit() const override
;
201 int uploadLimit() const override
;
202 bool superSeeding() const override
;
203 bool isDHTDisabled() const override
;
204 bool isPEXDisabled() const override
;
205 bool isLSDDisabled() const override
;
206 QList
<PeerInfo
> peers() const override
;
207 QBitArray
pieces() const override
;
208 QBitArray
downloadingPieces() const override
;
209 QList
<int> pieceAvailability() const override
;
210 qreal
distributedCopies() const override
;
211 qreal
maxRatio() const override
;
212 int maxSeedingTime() const override
;
213 int maxInactiveSeedingTime() const override
;
214 qreal
realRatio() const override
;
215 qreal
popularity() const override
;
216 int uploadPayloadRate() const override
;
217 int downloadPayloadRate() const override
;
218 qlonglong
totalPayloadUpload() const override
;
219 qlonglong
totalPayloadDownload() const override
;
220 int connectionsCount() const override
;
221 int connectionsLimit() const override
;
222 qlonglong
nextAnnounce() const override
;
223 QList
<qreal
> availableFileFractions() const override
;
225 void setName(const QString
&name
) override
;
226 void setSequentialDownload(bool enable
) override
;
227 void setFirstLastPiecePriority(bool enabled
) override
;
228 void stop() override
;
229 void start(TorrentOperatingMode mode
= TorrentOperatingMode::AutoManaged
) override
;
230 void forceReannounce(int index
= -1) override
;
231 void forceDHTAnnounce() override
;
232 void forceRecheck() override
;
233 void renameFile(int index
, const Path
&path
) override
;
234 void prioritizeFiles(const QList
<DownloadPriority
> &priorities
) override
;
235 void setUploadLimit(int limit
) override
;
236 void setDownloadLimit(int limit
) override
;
237 void setSuperSeeding(bool enable
) override
;
238 void setDHTDisabled(bool disable
) override
;
239 void setPEXDisabled(bool disable
) override
;
240 void setLSDDisabled(bool disable
) override
;
241 void flushCache() const override
;
242 void addTrackers(QList
<TrackerEntry
> trackers
) override
;
243 void removeTrackers(const QStringList
&trackers
) override
;
244 void replaceTrackers(QList
<TrackerEntry
> trackers
) override
;
245 void addUrlSeeds(const QList
<QUrl
> &urlSeeds
) override
;
246 void removeUrlSeeds(const QList
<QUrl
> &urlSeeds
) override
;
247 bool connectPeer(const PeerAddress
&peerAddress
) override
;
248 void clearPeers() override
;
249 void setMetadata(const TorrentInfo
&torrentInfo
) override
;
251 StopCondition
stopCondition() const override
;
252 void setStopCondition(StopCondition stopCondition
) override
;
253 SSLParameters
getSSLParameters() const override
;
254 void setSSLParameters(const SSLParameters
&sslParams
) override
;
255 bool applySSLParameters();
257 QString
createMagnetURI() const override
;
258 nonstd::expected
<QByteArray
, QString
> exportToBuffer() const override
;
259 nonstd::expected
<void, QString
> exportToFile(const Path
&path
) const override
;
261 void fetchPeerInfo(std::function
<void (QList
<PeerInfo
>)> resultHandler
) const override
;
262 void fetchURLSeeds(std::function
<void (QList
<QUrl
>)> resultHandler
) const override
;
263 void fetchPieceAvailability(std::function
<void (QList
<int>)> resultHandler
) const override
;
264 void fetchDownloadingPieces(std::function
<void (QBitArray
)> resultHandler
) const override
;
265 void fetchAvailableFileFractions(std::function
<void (QList
<qreal
>)> resultHandler
) const override
;
267 bool needSaveResumeData() const;
270 lt::torrent_handle
nativeHandle() const;
272 void handleAlert(const lt::alert
*a
);
273 void handleStateUpdate(const lt::torrent_status
&nativeStatus
);
274 void handleQueueingModeChanged();
275 void handleCategoryOptionsChanged();
276 void handleAppendExtensionToggled();
277 void handleUnwantedFolderToggled();
278 void requestResumeData(lt::resume_data_flags_t flags
= {});
279 void deferredRequestResumeData();
280 void handleMoveStorageJobFinished(const Path
&path
, MoveStorageContext context
, bool hasOutstandingJob
);
281 void fileSearchFinished(const Path
&savePath
, const PathList
&fileNames
);
282 TrackerEntryStatus
updateTrackerEntryStatus(const lt::announce_entry
&announceEntry
, const QHash
<lt::tcp::endpoint
, QMap
<int, int>> &updateInfo
);
283 void resetTrackerEntryStatuses();
286 using EventTrigger
= std::function
<void ()>;
288 std::shared_ptr
<const lt::torrent_info
> nativeTorrentInfo() const;
290 void updateStatus(const lt::torrent_status
&nativeStatus
);
291 void updateProgress();
294 void handleFastResumeRejectedAlert(const lt::fastresume_rejected_alert
*p
);
295 void handleFileCompletedAlert(const lt::file_completed_alert
*p
);
296 void handleFileErrorAlert(const lt::file_error_alert
*p
);
297 #ifdef QBT_USES_LIBTORRENT2
298 void handleFilePrioAlert(const lt::file_prio_alert
*p
);
300 void handleFileRenamedAlert(const lt::file_renamed_alert
*p
);
301 void handleFileRenameFailedAlert(const lt::file_rename_failed_alert
*p
);
302 void handleMetadataReceivedAlert(const lt::metadata_received_alert
*p
);
303 void handlePerformanceAlert(const lt::performance_alert
*p
) const;
304 void handleSaveResumeDataAlert(const lt::save_resume_data_alert
*p
);
305 void handleSaveResumeDataFailedAlert(const lt::save_resume_data_failed_alert
*p
);
306 void handleTorrentCheckedAlert(const lt::torrent_checked_alert
*p
);
307 void handleTorrentFinishedAlert(const lt::torrent_finished_alert
*p
);
308 void handleTorrentPausedAlert(const lt::torrent_paused_alert
*p
);
309 void handleTorrentResumedAlert(const lt::torrent_resumed_alert
*p
);
311 bool isMoveInProgress() const;
313 void setAutoManaged(bool enable
);
315 Path
makeActualPath(int index
, const Path
&path
) const;
316 Path
makeUserPath(const Path
&path
) const;
317 void adjustStorageLocation();
318 void doRenameFile(int index
, const Path
&path
);
319 void moveStorage(const Path
&newPath
, MoveStorageContext context
);
320 void manageActualFilePaths();
321 void applyFirstLastPiecePriority(bool enabled
);
323 void prepareResumeData(const lt::add_torrent_params
¶ms
);
324 void endReceivedMetadataHandling(const Path
&savePath
, const PathList
&fileNames
);
327 nonstd::expected
<lt::entry
, QString
> exportTorrent() const;
329 template <typename Func
, typename Callback
>
330 void invokeAsync(Func func
, Callback resultHandler
) const;
332 SessionImpl
*const m_session
= nullptr;
333 lt::session
*m_nativeSession
= nullptr;
334 lt::torrent_handle m_nativeHandle
;
335 mutable lt::torrent_status m_nativeStatus
;
336 TorrentState m_state
= TorrentState::Unknown
;
337 TorrentInfo m_torrentInfo
;
338 PathList m_filePaths
;
339 QHash
<lt::file_index_t
, int> m_indexMap
;
340 QList
<DownloadPriority
> m_filePriorities
;
341 QBitArray m_completedFiles
;
342 SpeedMonitor m_payloadRateMonitor
;
346 QDateTime m_creationDate
;
350 QDateTime m_addedTime
;
351 QDateTime m_completedTime
;
352 QDateTime m_lastSeenComplete
;
354 // m_moveFinishedTriggers is activated only when the following conditions are met:
355 // all file rename jobs complete, all file move jobs complete
356 QQueue
<EventTrigger
> m_moveFinishedTriggers
;
357 int m_renameCount
= 0;
358 bool m_storageIsMoving
= false;
360 QQueue
<EventTrigger
> m_statusUpdatedTriggers
;
362 MaintenanceJob m_maintenanceJob
= MaintenanceJob::None
;
364 QList
<TrackerEntryStatus
> m_trackerEntryStatuses
;
365 QList
<QUrl
> m_urlSeeds
;
366 FileErrorInfo m_lastFileError
;
374 qreal m_ratioLimit
= 0;
375 int m_seedingTimeLimit
= 0;
376 int m_inactiveSeedingTimeLimit
= 0;
377 ShareLimitAction m_shareLimitAction
= ShareLimitAction::Default
;
378 TorrentOperatingMode m_operatingMode
= TorrentOperatingMode::AutoManaged
;
379 TorrentContentLayout m_contentLayout
= TorrentContentLayout::Original
;
380 bool m_hasFinishedStatus
= false;
381 bool m_hasMissingFiles
= false;
382 bool m_hasFirstLastPiecePriority
= false;
383 bool m_useAutoTMM
= false;
384 bool m_isStopped
= false;
385 StopCondition m_stopCondition
= StopCondition::None
;
386 SSLParameters m_sslParams
;
388 bool m_unchecked
= false;
390 lt::add_torrent_params m_ltAddTorrentParams
;
392 int m_downloadLimit
= 0;
393 int m_uploadLimit
= 0;
396 QList
<std::int64_t> m_filesProgress
;
398 bool m_deferredRequestResumeDataInvoked
= false;