Revise Tracker related classes
[qBittorrent.git] / src / base / bittorrent / torrentimpl.h
blob003a67e25ba6d3b876d6b0f9c9538267f1e50e33
1 /*
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.
30 #pragma once
32 #include <functional>
33 #include <memory>
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>
41 #include <QBitArray>
42 #include <QDateTime>
43 #include <QHash>
44 #include <QMap>
45 #include <QObject>
46 #include <QQueue>
47 #include <QString>
48 #include <QVector>
50 #include "base/path.h"
51 #include "base/tagset.h"
52 #include "infohash.h"
53 #include "speedmonitor.h"
54 #include "sslparameters.h"
55 #include "torrent.h"
56 #include "torrentcontentlayout.h"
57 #include "torrentinfo.h"
58 #include "trackerentrystatus.h"
60 namespace BitTorrent
62 class SessionImpl;
63 struct LoadTorrentParams;
65 enum class MoveStorageMode
67 FailIfExist,
68 KeepExistingFiles,
69 Overwrite
72 enum class MoveStorageContext
74 AdjustCurrentLocation,
75 ChangeSavePath,
76 ChangeDownloadPath
79 enum class MaintenanceJob
81 None,
82 HandleMetadata
85 struct FileErrorInfo
87 lt::error_code error;
88 lt::operation_t operation = lt::operation_t::unknown;
91 class TorrentImpl final : public Torrent
93 Q_OBJECT
94 Q_DISABLE_COPY_MOVE(TorrentImpl)
96 public:
97 TorrentImpl(SessionImpl *session, lt::session *nativeSession
98 , const lt::torrent_handle &nativeHandle, const LoadTorrentParams &params);
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;
141 QDateTime addedTime() const override;
143 qreal ratioLimit() const override;
144 void setRatioLimit(qreal limit) override;
145 int seedingTimeLimit() const override;
146 void setSeedingTimeLimit(int limit) override;
147 int inactiveSeedingTimeLimit() const override;
148 void setInactiveSeedingTimeLimit(int limit) override;
149 ShareLimitAction shareLimitAction() const override;
150 void setShareLimitAction(ShareLimitAction action) override;
152 Path filePath(int index) const override;
153 Path actualFilePath(int index) const override;
154 qlonglong fileSize(int index) const override;
155 PathList filePaths() const override;
156 QVector<DownloadPriority> filePriorities() const override;
158 TorrentInfo info() const override;
159 bool isFinished() const override;
160 bool isStopped() const override;
161 bool isQueued() const override;
162 bool isForced() const override;
163 bool isChecking() const override;
164 bool isDownloading() const override;
165 bool isMoving() const override;
166 bool isUploading() const override;
167 bool isCompleted() const override;
168 bool isActive() const override;
169 bool isInactive() const override;
170 bool isErrored() const override;
171 bool isSequentialDownload() const override;
172 bool hasFirstLastPiecePriority() const override;
173 TorrentState state() const override;
174 bool hasMetadata() const override;
175 bool hasMissingFiles() const override;
176 bool hasError() const override;
177 int queuePosition() const override;
178 QVector<TrackerEntryStatus> trackers() const override;
179 QVector<QUrl> urlSeeds() const override;
180 QString error() const override;
181 qlonglong totalDownload() const override;
182 qlonglong totalUpload() const override;
183 qlonglong activeTime() const override;
184 qlonglong finishedTime() const override;
185 qlonglong eta() const override;
186 QVector<qreal> filesProgress() const override;
187 int seedsCount() const override;
188 int peersCount() const override;
189 int leechsCount() const override;
190 int totalSeedsCount() const override;
191 int totalPeersCount() const override;
192 int totalLeechersCount() const override;
193 QDateTime lastSeenComplete() const override;
194 QDateTime completedTime() const override;
195 qlonglong timeSinceUpload() const override;
196 qlonglong timeSinceDownload() const override;
197 qlonglong timeSinceActivity() const override;
198 int downloadLimit() const override;
199 int uploadLimit() const override;
200 bool superSeeding() const override;
201 bool isDHTDisabled() const override;
202 bool isPEXDisabled() const override;
203 bool isLSDDisabled() const override;
204 QVector<PeerInfo> peers() const override;
205 QBitArray pieces() const override;
206 QBitArray downloadingPieces() const override;
207 QVector<int> pieceAvailability() const override;
208 qreal distributedCopies() const override;
209 qreal maxRatio() const override;
210 int maxSeedingTime() const override;
211 int maxInactiveSeedingTime() const override;
212 qreal realRatio() const override;
213 int uploadPayloadRate() const override;
214 int downloadPayloadRate() const override;
215 qlonglong totalPayloadUpload() const override;
216 qlonglong totalPayloadDownload() const override;
217 int connectionsCount() const override;
218 int connectionsLimit() const override;
219 qlonglong nextAnnounce() const override;
220 QVector<qreal> availableFileFractions() const override;
222 void setName(const QString &name) override;
223 void setSequentialDownload(bool enable) override;
224 void setFirstLastPiecePriority(bool enabled) override;
225 void stop() override;
226 void start(TorrentOperatingMode mode = TorrentOperatingMode::AutoManaged) override;
227 void forceReannounce(int index = -1) override;
228 void forceDHTAnnounce() override;
229 void forceRecheck() override;
230 void renameFile(int index, const Path &path) override;
231 void prioritizeFiles(const QVector<DownloadPriority> &priorities) override;
232 void setUploadLimit(int limit) override;
233 void setDownloadLimit(int limit) override;
234 void setSuperSeeding(bool enable) override;
235 void setDHTDisabled(bool disable) override;
236 void setPEXDisabled(bool disable) override;
237 void setLSDDisabled(bool disable) override;
238 void flushCache() const override;
239 void addTrackers(QVector<TrackerEntry> trackers) override;
240 void removeTrackers(const QStringList &trackers) override;
241 void replaceTrackers(QVector<TrackerEntry> trackers) override;
242 void addUrlSeeds(const QVector<QUrl> &urlSeeds) override;
243 void removeUrlSeeds(const QVector<QUrl> &urlSeeds) override;
244 bool connectPeer(const PeerAddress &peerAddress) override;
245 void clearPeers() override;
246 void setMetadata(const TorrentInfo &torrentInfo) override;
248 StopCondition stopCondition() const override;
249 void setStopCondition(StopCondition stopCondition) override;
250 SSLParameters getSSLParameters() const override;
251 void setSSLParameters(const SSLParameters &sslParams) override;
252 bool applySSLParameters();
254 QString createMagnetURI() const override;
255 nonstd::expected<QByteArray, QString> exportToBuffer() const override;
256 nonstd::expected<void, QString> exportToFile(const Path &path) const override;
258 void fetchPeerInfo(std::function<void (QVector<PeerInfo>)> resultHandler) const override;
259 void fetchURLSeeds(std::function<void (QVector<QUrl>)> resultHandler) const override;
260 void fetchPieceAvailability(std::function<void (QVector<int>)> resultHandler) const override;
261 void fetchDownloadingPieces(std::function<void (QBitArray)> resultHandler) const override;
262 void fetchAvailableFileFractions(std::function<void (QVector<qreal>)> resultHandler) const override;
264 bool needSaveResumeData() const;
266 // Session interface
267 lt::torrent_handle nativeHandle() const;
269 void handleAlert(const lt::alert *a);
270 void handleStateUpdate(const lt::torrent_status &nativeStatus);
271 void handleCategoryOptionsChanged();
272 void handleAppendExtensionToggled();
273 void handleUnwantedFolderToggled();
274 void requestResumeData(lt::resume_data_flags_t flags = {});
275 void deferredRequestResumeData();
276 void handleMoveStorageJobFinished(const Path &path, MoveStorageContext context, bool hasOutstandingJob);
277 void fileSearchFinished(const Path &savePath, const PathList &fileNames);
278 TrackerEntryStatus updateTrackerEntryStatus(const lt::announce_entry &announceEntry, const QHash<lt::tcp::endpoint, QMap<int, int>> &updateInfo);
279 void resetTrackerEntryStatuses();
281 private:
282 using EventTrigger = std::function<void ()>;
284 std::shared_ptr<const lt::torrent_info> nativeTorrentInfo() const;
286 void updateStatus(const lt::torrent_status &nativeStatus);
287 void updateProgress();
288 void updateState();
290 void handleFastResumeRejectedAlert(const lt::fastresume_rejected_alert *p);
291 void handleFileCompletedAlert(const lt::file_completed_alert *p);
292 void handleFileErrorAlert(const lt::file_error_alert *p);
293 #ifdef QBT_USES_LIBTORRENT2
294 void handleFilePrioAlert(const lt::file_prio_alert *p);
295 #endif
296 void handleFileRenamedAlert(const lt::file_renamed_alert *p);
297 void handleFileRenameFailedAlert(const lt::file_rename_failed_alert *p);
298 void handleMetadataReceivedAlert(const lt::metadata_received_alert *p);
299 void handlePerformanceAlert(const lt::performance_alert *p) const;
300 void handleSaveResumeDataAlert(const lt::save_resume_data_alert *p);
301 void handleSaveResumeDataFailedAlert(const lt::save_resume_data_failed_alert *p);
302 void handleTorrentCheckedAlert(const lt::torrent_checked_alert *p);
303 void handleTorrentFinishedAlert(const lt::torrent_finished_alert *p);
304 void handleTorrentPausedAlert(const lt::torrent_paused_alert *p);
305 void handleTorrentResumedAlert(const lt::torrent_resumed_alert *p);
307 bool isMoveInProgress() const;
309 void setAutoManaged(bool enable);
311 Path makeActualPath(int index, const Path &path) const;
312 Path makeUserPath(const Path &path) const;
313 void adjustStorageLocation();
314 void doRenameFile(int index, const Path &path);
315 void moveStorage(const Path &newPath, MoveStorageContext context);
316 void manageActualFilePaths();
317 void applyFirstLastPiecePriority(bool enabled);
319 void prepareResumeData(const lt::add_torrent_params &params);
320 void endReceivedMetadataHandling(const Path &savePath, const PathList &fileNames);
321 void reload();
323 nonstd::expected<lt::entry, QString> exportTorrent() const;
325 template <typename Func, typename Callback>
326 void invokeAsync(Func func, Callback resultHandler) const;
328 SessionImpl *const m_session = nullptr;
329 lt::session *m_nativeSession = nullptr;
330 lt::torrent_handle m_nativeHandle;
331 mutable lt::torrent_status m_nativeStatus;
332 TorrentState m_state = TorrentState::Unknown;
333 TorrentInfo m_torrentInfo;
334 PathList m_filePaths;
335 QHash<lt::file_index_t, int> m_indexMap;
336 QVector<DownloadPriority> m_filePriorities;
337 QBitArray m_completedFiles;
338 SpeedMonitor m_payloadRateMonitor;
340 InfoHash m_infoHash;
342 // m_moveFinishedTriggers is activated only when the following conditions are met:
343 // all file rename jobs complete, all file move jobs complete
344 QQueue<EventTrigger> m_moveFinishedTriggers;
345 int m_renameCount = 0;
346 bool m_storageIsMoving = false;
348 QQueue<EventTrigger> m_statusUpdatedTriggers;
350 MaintenanceJob m_maintenanceJob = MaintenanceJob::None;
352 QVector<TrackerEntryStatus> m_trackerEntryStatuses;
353 QVector<QUrl> m_urlSeeds;
354 FileErrorInfo m_lastFileError;
356 // Persistent data
357 QString m_name;
358 Path m_savePath;
359 Path m_downloadPath;
360 QString m_category;
361 TagSet m_tags;
362 qreal m_ratioLimit = 0;
363 int m_seedingTimeLimit = 0;
364 int m_inactiveSeedingTimeLimit = 0;
365 ShareLimitAction m_shareLimitAction = ShareLimitAction::Default;
366 TorrentOperatingMode m_operatingMode = TorrentOperatingMode::AutoManaged;
367 TorrentContentLayout m_contentLayout = TorrentContentLayout::Original;
368 bool m_hasFinishedStatus = false;
369 bool m_hasMissingFiles = false;
370 bool m_hasFirstLastPiecePriority = false;
371 bool m_useAutoTMM = false;
372 bool m_isStopped = false;
373 StopCondition m_stopCondition = StopCondition::None;
374 SSLParameters m_sslParams;
376 bool m_unchecked = false;
378 lt::add_torrent_params m_ltAddTorrentParams;
380 int m_downloadLimit = 0;
381 int m_uploadLimit = 0;
383 QBitArray m_pieces;
384 QVector<std::int64_t> m_filesProgress;
386 bool m_deferredRequestResumeDataInvoked = false;