File indexing completed on 2025-01-05 04:37:25
0001 /* 0002 SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com> 0003 SPDX-FileCopyrightText: 2005 Ivan Vasic <ivasic@gmail.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 #ifndef BTTORRENT_H 0008 #define BTTORRENT_H 0009 0010 #include "torrentfile.h" 0011 #include <QList> 0012 #include <QUrl> 0013 #include <QVector> 0014 #include <interfaces/torrentinterface.h> 0015 #include <ktorrent_export.h> 0016 #include <peer/peerid.h> 0017 #include <util/constants.h> 0018 #include <util/sha1hash.h> 0019 0020 class QTextCodec; 0021 0022 namespace bt 0023 { 0024 class BNode; 0025 class BDictNode; 0026 class BListNode; 0027 0028 struct TrackerTier { 0029 QList<QUrl> urls; 0030 TrackerTier *next; 0031 0032 TrackerTier() 0033 : next(nullptr) 0034 { 0035 } 0036 0037 ~TrackerTier() 0038 { 0039 delete next; 0040 } 0041 }; 0042 0043 /** 0044 * @author Joris Guisson 0045 * 0046 * Listener base class, to get notified when the priority of a file changes. 0047 */ 0048 class KTORRENT_EXPORT FilePriorityListener 0049 { 0050 public: 0051 virtual ~FilePriorityListener() 0052 { 0053 } 0054 0055 virtual void downloadPriorityChanged(TorrentFile *tf, Priority newpriority, Priority oldpriority) = 0; 0056 }; 0057 0058 /** 0059 * @author Joris Guisson 0060 * @brief Loads a .torrent file 0061 * 0062 * Loads a torrent file and calculates some miscelanious other data, 0063 * like the info_hash and the peer_id. 0064 */ 0065 class KTORRENT_EXPORT Torrent 0066 { 0067 public: 0068 Torrent(); 0069 Torrent(const bt::SHA1Hash &hash); 0070 virtual ~Torrent(); 0071 0072 /** 0073 * Set the FilePriorityListener 0074 * @param l THe listener 0075 */ 0076 void setFilePriorityListener(FilePriorityListener *l) 0077 { 0078 file_prio_listener = l; 0079 } 0080 0081 /** 0082 * Called by TorrentFile when the priority changes 0083 * @param tf The file 0084 * @param newpriority The old priority 0085 * @param oldpriority The new priority 0086 */ 0087 void downloadPriorityChanged(TorrentFile *tf, Priority newpriority, Priority oldpriority); 0088 0089 /** 0090 * Called by TorrentFile when the percentage changes 0091 * @param tf The file 0092 * @param perc The percentage 0093 */ 0094 void filePercentageChanged(TorrentFile *tf, float perc); 0095 0096 /** 0097 * Called by TorrentFile when the preview state changes 0098 * @param tf The file 0099 * @param preview Whether preview is possible or not 0100 */ 0101 void filePreviewChanged(TorrentFile *tf, bool preview); 0102 0103 /** 0104 * Load a .torrent file. 0105 * @param data The data 0106 * @param verbose Whether to print information to the log 0107 * @throw Error if something goes wrong 0108 */ 0109 void load(const QByteArray &data, bool verbose); 0110 0111 void debugPrintInfo(); 0112 0113 /// Return the comments in the torrent 0114 QString getComments() const 0115 { 0116 return comments; 0117 } 0118 0119 /// Get the number of chunks. 0120 Uint32 getNumChunks() const 0121 { 0122 return hash_pieces.size(); 0123 } 0124 0125 /// Get the size of a chunk. 0126 Uint64 getChunkSize() const 0127 { 0128 return chunk_size; 0129 } 0130 0131 /// Get the size of the last chunk 0132 Uint64 getLastChunkSize() const 0133 { 0134 return last_chunk_size; 0135 } 0136 0137 /// Get the info_hash. 0138 const SHA1Hash &getInfoHash() const 0139 { 0140 return info_hash; 0141 } 0142 0143 /// Get our peer_id. 0144 const PeerID &getPeerID() const 0145 { 0146 return peer_id; 0147 } 0148 0149 /// Get the file size in number of bytes. 0150 Uint64 getTotalSize() const 0151 { 0152 return total_size; 0153 } 0154 0155 /// Get the suggested name. 0156 QString getNameSuggestion() const 0157 { 0158 return name_suggestion; 0159 } 0160 0161 /** 0162 * Verify whether a hash matches the hash 0163 * of a Chunk 0164 * @param h The hash 0165 * @param index The index of the chunk 0166 * @return true if they match 0167 */ 0168 bool verifyHash(const SHA1Hash &h, Uint32 index); 0169 0170 /// Get the number of tracker URL's 0171 unsigned int getNumTrackerURLs() const; 0172 0173 /** 0174 * Get the hash of a Chunk. Throws an Error 0175 * if idx is out of bounds. 0176 * @param idx Index of Chunk 0177 * @return The SHA1 hash of the chunk 0178 */ 0179 const SHA1Hash &getHash(Uint32 idx) const; 0180 0181 /// See if we have a multi file torrent. 0182 bool isMultiFile() const 0183 { 0184 return files.count() > 0; 0185 } 0186 0187 /// Get the number of files in a multi file torrent. 0188 /// If we have a single file torrent, this will return 0. 0189 Uint32 getNumFiles() const 0190 { 0191 return files.count(); 0192 } 0193 0194 /** 0195 * Get a TorrentFile. If the index is out of range, or 0196 * we have a single file torrent we return a null TorrentFile. 0197 * @param idx Index of the file 0198 * @param A reference to the file 0199 */ 0200 TorrentFile &getFile(Uint32 idx); 0201 0202 /** 0203 * Get a TorrentFile. If the index is out of range, or 0204 * we have a single file torrent we return a null TorrentFile. 0205 * @param idx Index of the file 0206 * @param A reference to the file 0207 */ 0208 const TorrentFile &getFile(Uint32 idx) const; 0209 0210 /** 0211 * Calculate in which file(s) a Chunk lies. A list will 0212 * get filled with the indices of all the files. The list gets cleared at 0213 * the beginning. If something is wrong only the list will 0214 * get cleared. 0215 * @param chunk The index of the chunk 0216 * @param file_list This list will be filled with all the indices 0217 */ 0218 void calcChunkPos(Uint32 chunk, QList<Uint32> &file_list) const; 0219 0220 /** 0221 * Checks if torrent file is audio or video. 0222 **/ 0223 bool isMultimedia() const; 0224 0225 /// See if the torrent is private 0226 bool isPrivate() const 0227 { 0228 return priv_torrent; 0229 } 0230 0231 /// Is the torrent loaded 0232 bool isLoaded() const 0233 { 0234 return loaded; 0235 } 0236 0237 /// Gets a pointer to AnnounceList 0238 const TrackerTier *getTrackerList() const 0239 { 0240 return trackers; 0241 } 0242 0243 /// Get the number of initial DHT nodes 0244 Uint32 getNumDHTNodes() const 0245 { 0246 return nodes.count(); 0247 } 0248 0249 /// Get a DHT node 0250 const DHTNode &getDHTNode(Uint32 i) 0251 { 0252 return nodes[i]; 0253 } 0254 0255 /** 0256 * Update the percentage of all files. 0257 * @param cman The ChunkManager 0258 */ 0259 void updateFilePercentage(ChunkManager &cman); 0260 0261 /** 0262 * Update the percentage of a all files which have a particular chunk. 0263 * @param cman The ChunkManager 0264 */ 0265 void updateFilePercentage(Uint32 chunk, ChunkManager &cman); 0266 0267 /** 0268 * Get the list with web seed URL's 0269 */ 0270 const QList<QUrl> &getWebSeeds() const 0271 { 0272 return web_seeds; 0273 } 0274 0275 /// Change the text codec 0276 void changeTextCodec(QTextCodec *codec); 0277 0278 /// Get the text codec 0279 const QTextCodec *getTextCodec() 0280 { 0281 return text_codec; 0282 } 0283 0284 /// Set the monitor 0285 void setMonitor(MonitorInterface *m) 0286 { 0287 tmon = m; 0288 } 0289 0290 /// Get the metadata 0291 const QByteArray &getMetaData() const 0292 { 0293 return metadata; 0294 } 0295 0296 private: 0297 void loadInfo(BDictNode *node); 0298 void loadTrackerURL(const QString &s); 0299 void loadHash(BDictNode *dict); 0300 void loadFiles(BListNode *node); 0301 void loadNodes(BListNode *node); 0302 void loadAnnounceList(BNode *node); 0303 void loadWebSeeds(BListNode *node); 0304 bool checkPathForDirectoryTraversal(const QString &p); 0305 0306 private: 0307 QString name_suggestion; 0308 QByteArray unencoded_name; 0309 QString comments; 0310 QByteArray metadata; 0311 0312 SHA1Hash info_hash; 0313 QVector<SHA1Hash> hash_pieces; 0314 QVector<TorrentFile> files; 0315 QVector<DHTNode> nodes; 0316 QList<QUrl> web_seeds; 0317 PeerID peer_id; 0318 0319 TrackerTier *trackers; 0320 Uint64 chunk_size; 0321 Uint64 last_chunk_size; 0322 Uint64 total_size; 0323 QTextCodec *text_codec; 0324 FilePriorityListener *file_prio_listener; 0325 mutable Uint32 pos_cache_chunk; 0326 mutable Uint32 pos_cache_file; 0327 MonitorInterface *tmon; 0328 bool priv_torrent; 0329 bool loaded; 0330 }; 0331 0332 } 0333 0334 #endif