added new session functions to more efficiently query torrent status
This commit is contained in:
parent
6692f05655
commit
b842815710
|
@ -1,3 +1,4 @@
|
|||
* added new session functions to more efficiently query torrent status
|
||||
* added alerts for added and removed torrents
|
||||
* expanded plugin interface to support session wide states
|
||||
* made the metadata block requesting algorithm more robust against hash check failures
|
||||
|
|
|
@ -62,16 +62,17 @@
|
|||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#plugin-interface" id="id3">plugin interface</a></li>
|
||||
<li><a class="reference internal" href="#torrent-plugin" id="id4">torrent_plugin</a><ul>
|
||||
<li><a class="reference internal" href="#new-connection" id="id5">new_connection()</a></li>
|
||||
<li><a class="reference internal" href="#on-piece-pass-on-piece-fail" id="id6">on_piece_pass() on_piece_fail()</a></li>
|
||||
<li><a class="reference internal" href="#tick" id="id7">tick()</a></li>
|
||||
<li><a class="reference internal" href="#on-pause-on-resume" id="id8">on_pause() on_resume()</a></li>
|
||||
<li><a class="reference internal" href="#on-files-checked" id="id9">on_files_checked()</a></li>
|
||||
<li><a class="reference internal" href="#plugin" id="id4">plugin</a></li>
|
||||
<li><a class="reference internal" href="#torrent-plugin" id="id5">torrent_plugin</a><ul>
|
||||
<li><a class="reference internal" href="#new-connection" id="id6">new_connection()</a></li>
|
||||
<li><a class="reference internal" href="#on-piece-pass-on-piece-fail" id="id7">on_piece_pass() on_piece_fail()</a></li>
|
||||
<li><a class="reference internal" href="#tick" id="id8">tick()</a></li>
|
||||
<li><a class="reference internal" href="#on-pause-on-resume" id="id9">on_pause() on_resume()</a></li>
|
||||
<li><a class="reference internal" href="#on-files-checked" id="id10">on_files_checked()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#peer-plugin" id="id10">peer_plugin</a></li>
|
||||
<li><a class="reference internal" href="#disk-buffer-holder" id="id11">disk_buffer_holder</a></li>
|
||||
<li><a class="reference internal" href="#peer-plugin" id="id11">peer_plugin</a></li>
|
||||
<li><a class="reference internal" href="#disk-buffer-holder" id="id12">disk_buffer_holder</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>libtorrent has a plugin interface for implementing extensions to the protocol.
|
||||
|
@ -85,6 +86,8 @@ to fit a particular (closed) network.</p>
|
|||
<li>add data and parse data from the extension handshake.</li>
|
||||
<li>send extension messages and standard bittorrent messages.</li>
|
||||
<li>override or block the handling of standard bittorrent messages.</li>
|
||||
<li>save and restore state via the session state</li>
|
||||
<li>see all alerts that are posted</li>
|
||||
</ul>
|
||||
<div class="section" id="a-word-of-caution">
|
||||
<h2>a word of caution</h2>
|
||||
|
@ -92,24 +95,30 @@ to fit a particular (closed) network.</p>
|
|||
dead locks and race conditions. Since a plugin has access to internal
|
||||
structures it is also quite easy to sabotage libtorrent's operation.</p>
|
||||
<p>All the callbacks in this interface are called with the main libtorrent thread
|
||||
mutex locked. And they are always called from the libtorrent main thread. In
|
||||
mutex locked. And they are always called from the libtorrent network thread. In
|
||||
case portions of your plugin are called from other threads, typically the main
|
||||
thread, you cannot use any of the member functions on the internal structures
|
||||
in libtorrent, since those require the mutex to be locked. Futhermore, you would
|
||||
also need to have a mutex on your own shared data within the plugin, to make
|
||||
sure it is not accessed at the same time from the libtorrent thread (through a
|
||||
callback). See <a class="reference external" href="http://www.boost.org/doc/html/mutex.html">boost thread's mutex</a>. If you need to send out a message from
|
||||
another thread, use an internal queue, and do the actual sending in <tt class="docutils literal"><span class="pre">tick()</span></tt>.</p>
|
||||
another thread, it is advised to use an internal queue, and do the actual
|
||||
sending in <tt class="docutils literal"><span class="pre">tick()</span></tt>.</p>
|
||||
<p>Since the plugin interface gives you easy access to internal structures, it
|
||||
is not supported as a stable API. Plugins should be considered spcific to a
|
||||
specific version of libtorrent. Although, in practice the internals mostly
|
||||
don't change that dramatically.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="plugin-interface">
|
||||
<h1>plugin interface</h1>
|
||||
<p>The plugin interface consists of two base classes that the plugin may
|
||||
implement. These are called <tt class="docutils literal"><span class="pre">torrent_plugin</span></tt> and <tt class="docutils literal"><span class="pre">peer_plugin</span></tt>. They are
|
||||
both found in the <tt class="docutils literal"><span class="pre"><libtorrent/extensions.hpp></span></tt> header.</p>
|
||||
<p>These plugins are instantiated for each torrent and possibly each peer,
|
||||
<p>The plugin interface consists of three base classes that the plugin may
|
||||
implement. These are called <tt class="docutils literal"><span class="pre">plugin</span></tt>, <tt class="docutils literal"><span class="pre">torrent_plugin</span></tt> and <tt class="docutils literal"><span class="pre">peer_plugin</span></tt>.
|
||||
They are found in the <tt class="docutils literal"><span class="pre"><libtorrent/extensions.hpp></span></tt> header.</p>
|
||||
<p>These plugins are instantiated for each session, torrent and possibly each peer,
|
||||
respectively.</p>
|
||||
<p>This is done by passing in a function or function object to
|
||||
<p>For plugins that only need per torrent state, it is enough to only implement
|
||||
<tt class="docutils literal"><span class="pre">torrent_plugin</span></tt> and pass a constructor function or function object to
|
||||
<tt class="docutils literal"><span class="pre">session::add_extension()</span></tt> or <tt class="docutils literal"><span class="pre">torrent_handle::add_extension()</span></tt> (if the
|
||||
torrent has already been started and you want to hook in the extension at
|
||||
run-time).</p>
|
||||
|
@ -125,6 +134,25 @@ may or may not be 0. If it is a null pointer, the extension is simply ignored
|
|||
for this torrent. If it is a valid pointer (to a class inheriting
|
||||
<tt class="docutils literal"><span class="pre">torrent_plugin</span></tt>), it will be associated with this torrent and callbacks
|
||||
will be made on torrent events.</p>
|
||||
<p>For more elaborate plugins which require session wide state, you would
|
||||
implement <tt class="docutils literal"><span class="pre">plugin</span></tt>, construct an object (in a <tt class="docutils literal"><span class="pre">boost::shared_ptr</span></tt>) and pass
|
||||
it in to <tt class="docutils literal"><span class="pre">session::add_extension()</span></tt>.</p>
|
||||
</div>
|
||||
<div class="section" id="plugin">
|
||||
<h1>plugin</h1>
|
||||
<pre class="literal-block">
|
||||
struct plugin
|
||||
{
|
||||
virtual ~plugin();
|
||||
virtual boost::shared_ptr<torrent_plugin> new_torrent(torrent* t, void* user);
|
||||
|
||||
virtual void added(boost::weak_ptr<aux::session_impl> s);
|
||||
virtual void on_alert(alert const* a);
|
||||
virtual void on_tick();
|
||||
virtual void save_state(entry& ent) const;
|
||||
virtual void load_state(lazy_entry const& ent);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="torrent-plugin">
|
||||
<h1>torrent_plugin</h1>
|
||||
|
|
574
docs/manual.html
574
docs/manual.html
|
@ -69,257 +69,261 @@
|
|||
<li><a class="reference internal" href="#add-torrent" id="id23">add_torrent()</a></li>
|
||||
<li><a class="reference internal" href="#remove-torrent" id="id24">remove_torrent()</a></li>
|
||||
<li><a class="reference internal" href="#find-torrent-get-torrents" id="id25">find_torrent() get_torrents()</a></li>
|
||||
<li><a class="reference internal" href="#load-asnum-db-load-country-db-as-for-ip" id="id26">load_asnum_db() load_country_db() as_for_ip()</a></li>
|
||||
<li><a class="reference internal" href="#set-ip-filter" id="id27">set_ip_filter()</a></li>
|
||||
<li><a class="reference internal" href="#get-ip-filter" id="id28">get_ip_filter()</a></li>
|
||||
<li><a class="reference internal" href="#status" id="id29">status()</a></li>
|
||||
<li><a class="reference internal" href="#get-cache-status" id="id30">get_cache_status()</a></li>
|
||||
<li><a class="reference internal" href="#get-cache-info" id="id31">get_cache_info()</a></li>
|
||||
<li><a class="reference internal" href="#is-listening-listen-port-listen-on" id="id32">is_listening() listen_port() listen_on()</a></li>
|
||||
<li><a class="reference internal" href="#set-alert-mask" id="id33">set_alert_mask()</a></li>
|
||||
<li><a class="reference internal" href="#pop-alert-wait-for-alert-set-alert-queue-size-limit" id="id34">pop_alert() wait_for_alert() set_alert_queue_size_limit()</a></li>
|
||||
<li><a class="reference internal" href="#add-feed" id="id35">add_feed()</a></li>
|
||||
<li><a class="reference internal" href="#remove-feed" id="id36">remove_feed()</a></li>
|
||||
<li><a class="reference internal" href="#get-feeds" id="id37">get_feeds()</a></li>
|
||||
<li><a class="reference internal" href="#add-extension" id="id38">add_extension()</a></li>
|
||||
<li><a class="reference internal" href="#set-settings-set-pe-settings" id="id39">set_settings() set_pe_settings()</a></li>
|
||||
<li><a class="reference internal" href="#set-proxy-proxy" id="id40">set_proxy() proxy()</a></li>
|
||||
<li><a class="reference internal" href="#set-i2p-proxy-i2p-proxy" id="id41">set_i2p_proxy() i2p_proxy()</a></li>
|
||||
<li><a class="reference internal" href="#start-dht-stop-dht-set-dht-settings-dht-state-is-dht-running" id="id42">start_dht() stop_dht() set_dht_settings() dht_state() is_dht_running()</a></li>
|
||||
<li><a class="reference internal" href="#add-dht-node-add-dht-router" id="id43">add_dht_node() add_dht_router()</a></li>
|
||||
<li><a class="reference internal" href="#start-lsd-stop-lsd" id="id44">start_lsd() stop_lsd()</a></li>
|
||||
<li><a class="reference internal" href="#start-upnp-stop-upnp" id="id45">start_upnp() stop_upnp()</a></li>
|
||||
<li><a class="reference internal" href="#start-natpmp-stop-natpmp" id="id46">start_natpmp() stop_natpmp()</a></li>
|
||||
<li><a class="reference internal" href="#get-torrent-status-refresh-torrent-status" id="id26">get_torrent_status() refresh_torrent_status()</a></li>
|
||||
<li><a class="reference internal" href="#load-asnum-db-load-country-db-as-for-ip" id="id27">load_asnum_db() load_country_db() as_for_ip()</a></li>
|
||||
<li><a class="reference internal" href="#set-ip-filter" id="id28">set_ip_filter()</a></li>
|
||||
<li><a class="reference internal" href="#get-ip-filter" id="id29">get_ip_filter()</a></li>
|
||||
<li><a class="reference internal" href="#status" id="id30">status()</a></li>
|
||||
<li><a class="reference internal" href="#get-cache-status" id="id31">get_cache_status()</a></li>
|
||||
<li><a class="reference internal" href="#get-cache-info" id="id32">get_cache_info()</a></li>
|
||||
<li><a class="reference internal" href="#is-listening-listen-port-listen-on" id="id33">is_listening() listen_port() listen_on()</a></li>
|
||||
<li><a class="reference internal" href="#set-alert-mask" id="id34">set_alert_mask()</a></li>
|
||||
<li><a class="reference internal" href="#pop-alert-wait-for-alert" id="id35">pop_alert() wait_for_alert()</a></li>
|
||||
<li><a class="reference internal" href="#add-feed" id="id36">add_feed()</a></li>
|
||||
<li><a class="reference internal" href="#remove-feed" id="id37">remove_feed()</a></li>
|
||||
<li><a class="reference internal" href="#get-feeds" id="id38">get_feeds()</a></li>
|
||||
<li><a class="reference internal" href="#add-extension" id="id39">add_extension()</a></li>
|
||||
<li><a class="reference internal" href="#set-settings-set-pe-settings" id="id40">set_settings() set_pe_settings()</a></li>
|
||||
<li><a class="reference internal" href="#set-proxy-proxy" id="id41">set_proxy() proxy()</a></li>
|
||||
<li><a class="reference internal" href="#set-i2p-proxy-i2p-proxy" id="id42">set_i2p_proxy() i2p_proxy()</a></li>
|
||||
<li><a class="reference internal" href="#start-dht-stop-dht-set-dht-settings-dht-state-is-dht-running" id="id43">start_dht() stop_dht() set_dht_settings() dht_state() is_dht_running()</a></li>
|
||||
<li><a class="reference internal" href="#add-dht-node-add-dht-router" id="id44">add_dht_node() add_dht_router()</a></li>
|
||||
<li><a class="reference internal" href="#start-lsd-stop-lsd" id="id45">start_lsd() stop_lsd()</a></li>
|
||||
<li><a class="reference internal" href="#start-upnp-stop-upnp" id="id46">start_upnp() stop_upnp()</a></li>
|
||||
<li><a class="reference internal" href="#start-natpmp-stop-natpmp" id="id47">start_natpmp() stop_natpmp()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#entry" id="id47">entry</a><ul>
|
||||
<li><a class="reference internal" href="#integer-string-list-dict-type" id="id48">integer() string() list() dict() type()</a></li>
|
||||
<li><a class="reference internal" href="#operator" id="id49">operator[]</a></li>
|
||||
<li><a class="reference internal" href="#find-key" id="id50">find_key()</a></li>
|
||||
<li><a class="reference internal" href="#entry" id="id48">entry</a><ul>
|
||||
<li><a class="reference internal" href="#integer-string-list-dict-type" id="id49">integer() string() list() dict() type()</a></li>
|
||||
<li><a class="reference internal" href="#operator" id="id50">operator[]</a></li>
|
||||
<li><a class="reference internal" href="#find-key" id="id51">find_key()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#torrent-info" id="id51">torrent_info</a><ul>
|
||||
<li><a class="reference internal" href="#id3" id="id52">torrent_info()</a></li>
|
||||
<li><a class="reference internal" href="#add-tracker" id="id53">add_tracker()</a></li>
|
||||
<li><a class="reference internal" href="#files-orig-files" id="id54">files() orig_files()</a></li>
|
||||
<li><a class="reference internal" href="#remap-files" id="id55">remap_files()</a></li>
|
||||
<li><a class="reference internal" href="#rename-file" id="id56">rename_file()</a></li>
|
||||
<li><a class="reference internal" href="#begin-files-end-files-rbegin-files-rend-files" id="id57">begin_files() end_files() rbegin_files() rend_files()</a></li>
|
||||
<li><a class="reference internal" href="#num-files-file-at" id="id58">num_files() file_at()</a></li>
|
||||
<li><a class="reference internal" href="#map-block" id="id59">map_block()</a></li>
|
||||
<li><a class="reference internal" href="#map-file" id="id60">map_file()</a></li>
|
||||
<li><a class="reference internal" href="#add-url-seed-add-http-seed" id="id61">add_url_seed() add_http_seed()</a></li>
|
||||
<li><a class="reference internal" href="#trackers" id="id62">trackers()</a></li>
|
||||
<li><a class="reference internal" href="#total-size-piece-length-piece-size-num-pieces" id="id63">total_size() piece_length() piece_size() num_pieces()</a></li>
|
||||
<li><a class="reference internal" href="#hash-for-piece-hash-for-piece-ptr-info-hash" id="id64">hash_for_piece() hash_for_piece_ptr() info_hash()</a></li>
|
||||
<li><a class="reference internal" href="#name-comment-creation-date-creator" id="id65">name() comment() creation_date() creator()</a></li>
|
||||
<li><a class="reference internal" href="#priv" id="id66">priv()</a></li>
|
||||
<li><a class="reference internal" href="#nodes" id="id67">nodes()</a></li>
|
||||
<li><a class="reference internal" href="#add-node" id="id68">add_node()</a></li>
|
||||
<li><a class="reference internal" href="#metadata-metadata-size" id="id69">metadata() metadata_size()</a></li>
|
||||
<li><a class="reference internal" href="#torrent-info" id="id52">torrent_info</a><ul>
|
||||
<li><a class="reference internal" href="#id3" id="id53">torrent_info()</a></li>
|
||||
<li><a class="reference internal" href="#add-tracker" id="id54">add_tracker()</a></li>
|
||||
<li><a class="reference internal" href="#files-orig-files" id="id55">files() orig_files()</a></li>
|
||||
<li><a class="reference internal" href="#remap-files" id="id56">remap_files()</a></li>
|
||||
<li><a class="reference internal" href="#rename-file" id="id57">rename_file()</a></li>
|
||||
<li><a class="reference internal" href="#begin-files-end-files-rbegin-files-rend-files" id="id58">begin_files() end_files() rbegin_files() rend_files()</a></li>
|
||||
<li><a class="reference internal" href="#num-files-file-at" id="id59">num_files() file_at()</a></li>
|
||||
<li><a class="reference internal" href="#map-block" id="id60">map_block()</a></li>
|
||||
<li><a class="reference internal" href="#map-file" id="id61">map_file()</a></li>
|
||||
<li><a class="reference internal" href="#add-url-seed-add-http-seed" id="id62">add_url_seed() add_http_seed()</a></li>
|
||||
<li><a class="reference internal" href="#trackers" id="id63">trackers()</a></li>
|
||||
<li><a class="reference internal" href="#total-size-piece-length-piece-size-num-pieces" id="id64">total_size() piece_length() piece_size() num_pieces()</a></li>
|
||||
<li><a class="reference internal" href="#hash-for-piece-hash-for-piece-ptr-info-hash" id="id65">hash_for_piece() hash_for_piece_ptr() info_hash()</a></li>
|
||||
<li><a class="reference internal" href="#name-comment-creation-date-creator" id="id66">name() comment() creation_date() creator()</a></li>
|
||||
<li><a class="reference internal" href="#priv" id="id67">priv()</a></li>
|
||||
<li><a class="reference internal" href="#nodes" id="id68">nodes()</a></li>
|
||||
<li><a class="reference internal" href="#add-node" id="id69">add_node()</a></li>
|
||||
<li><a class="reference internal" href="#metadata-metadata-size" id="id70">metadata() metadata_size()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#torrent-handle" id="id70">torrent_handle</a><ul>
|
||||
<li><a class="reference internal" href="#set-piece-deadline" id="id71">set_piece_deadline()</a></li>
|
||||
<li><a class="reference internal" href="#piece-availability" id="id72">piece_availability()</a></li>
|
||||
<li><a class="reference internal" href="#piece-priority-prioritize-pieces-piece-priorities" id="id73">piece_priority() prioritize_pieces() piece_priorities()</a></li>
|
||||
<li><a class="reference internal" href="#file-priority-prioritize-files-file-priorities" id="id74">file_priority() prioritize_files() file_priorities()</a></li>
|
||||
<li><a class="reference internal" href="#file-progress" id="id75">file_progress()</a></li>
|
||||
<li><a class="reference internal" href="#save-path" id="id76">save_path()</a></li>
|
||||
<li><a class="reference internal" href="#move-storage" id="id77">move_storage()</a></li>
|
||||
<li><a class="reference internal" href="#id4" id="id78">rename_file()</a></li>
|
||||
<li><a class="reference internal" href="#get-storage-impl" id="id79">get_storage_impl()</a></li>
|
||||
<li><a class="reference internal" href="#super-seeding" id="id80">super_seeding()</a></li>
|
||||
<li><a class="reference internal" href="#add-piece" id="id81">add_piece()</a></li>
|
||||
<li><a class="reference internal" href="#read-piece" id="id82">read_piece()</a></li>
|
||||
<li><a class="reference internal" href="#force-reannounce-force-dht-announce" id="id83">force_reannounce() force_dht_announce()</a></li>
|
||||
<li><a class="reference internal" href="#scrape-tracker" id="id84">scrape_tracker()</a></li>
|
||||
<li><a class="reference internal" href="#connect-peer" id="id85">connect_peer()</a></li>
|
||||
<li><a class="reference internal" href="#name" id="id86">name()</a></li>
|
||||
<li><a class="reference internal" href="#set-ratio" id="id87">set_ratio()</a></li>
|
||||
<li><a class="reference internal" href="#set-upload-limit-set-download-limit-upload-limit-download-limit" id="id88">set_upload_limit() set_download_limit() upload_limit() download_limit()</a></li>
|
||||
<li><a class="reference internal" href="#set-sequential-download" id="id89">set_sequential_download()</a></li>
|
||||
<li><a class="reference internal" href="#get-peer-download-limit-get-peer-upload-limit-set-peer-upload-limit-set-peer-download-limit" id="id90">get_peer_download_limit() get_peer_upload_limit() set_peer_upload_limit() set_peer_download_limit()</a></li>
|
||||
<li><a class="reference internal" href="#pause-resume" id="id91">pause() resume()</a></li>
|
||||
<li><a class="reference internal" href="#flush-cache" id="id92">flush_cache()</a></li>
|
||||
<li><a class="reference internal" href="#force-recheck" id="id93">force_recheck()</a></li>
|
||||
<li><a class="reference internal" href="#clear-error" id="id94">clear_error()</a></li>
|
||||
<li><a class="reference internal" href="#set-upload-mode" id="id95">set_upload_mode()</a></li>
|
||||
<li><a class="reference internal" href="#set-share-mode" id="id96">set_share_mode()</a></li>
|
||||
<li><a class="reference internal" href="#resolve-countries" id="id97">resolve_countries()</a></li>
|
||||
<li><a class="reference internal" href="#is-seed" id="id98">is_seed()</a></li>
|
||||
<li><a class="reference internal" href="#auto-managed" id="id99">auto_managed()</a></li>
|
||||
<li><a class="reference internal" href="#set-metadata" id="id100">set_metadata()</a></li>
|
||||
<li><a class="reference internal" href="#set-tracker-login" id="id101">set_tracker_login()</a></li>
|
||||
<li><a class="reference internal" href="#trackers-replace-trackers-add-tracker" id="id102">trackers() replace_trackers() add_tracker()</a></li>
|
||||
<li><a class="reference internal" href="#add-url-seed-remove-url-seed-url-seeds" id="id103">add_url_seed() remove_url_seed() url_seeds()</a></li>
|
||||
<li><a class="reference internal" href="#add-http-seed-remove-http-seed-http-seeds" id="id104">add_http_seed() remove_http_seed() http_seeds()</a></li>
|
||||
<li><a class="reference internal" href="#queue-position-queue-position-up-queue-position-down-queue-position-top-queue-position-bottom" id="id105">queue_position() queue_position_up() queue_position_down() queue_position_top() queue_position_bottom()</a></li>
|
||||
<li><a class="reference internal" href="#set-priority" id="id106">set_priority()</a></li>
|
||||
<li><a class="reference internal" href="#use-interface" id="id107">use_interface()</a></li>
|
||||
<li><a class="reference internal" href="#info-hash" id="id108">info_hash()</a></li>
|
||||
<li><a class="reference internal" href="#set-max-uploads-max-uploads" id="id109">set_max_uploads() max_uploads()</a></li>
|
||||
<li><a class="reference internal" href="#set-max-connections-max-connections" id="id110">set_max_connections() max_connections()</a></li>
|
||||
<li><a class="reference internal" href="#save-resume-data" id="id111">save_resume_data()</a></li>
|
||||
<li><a class="reference internal" href="#need-save-resume-data" id="id112">need_save_resume_data()</a></li>
|
||||
<li><a class="reference internal" href="#id5" id="id113">status()</a></li>
|
||||
<li><a class="reference internal" href="#get-download-queue" id="id114">get_download_queue()</a></li>
|
||||
<li><a class="reference internal" href="#get-peer-info" id="id115">get_peer_info()</a></li>
|
||||
<li><a class="reference internal" href="#get-torrent-info" id="id116">get_torrent_info()</a></li>
|
||||
<li><a class="reference internal" href="#is-valid" id="id117">is_valid()</a></li>
|
||||
<li><a class="reference internal" href="#torrent-handle" id="id71">torrent_handle</a><ul>
|
||||
<li><a class="reference internal" href="#set-piece-deadline" id="id72">set_piece_deadline()</a></li>
|
||||
<li><a class="reference internal" href="#piece-availability" id="id73">piece_availability()</a></li>
|
||||
<li><a class="reference internal" href="#piece-priority-prioritize-pieces-piece-priorities" id="id74">piece_priority() prioritize_pieces() piece_priorities()</a></li>
|
||||
<li><a class="reference internal" href="#file-priority-prioritize-files-file-priorities" id="id75">file_priority() prioritize_files() file_priorities()</a></li>
|
||||
<li><a class="reference internal" href="#file-progress" id="id76">file_progress()</a></li>
|
||||
<li><a class="reference internal" href="#save-path" id="id77">save_path()</a></li>
|
||||
<li><a class="reference internal" href="#move-storage" id="id78">move_storage()</a></li>
|
||||
<li><a class="reference internal" href="#id4" id="id79">rename_file()</a></li>
|
||||
<li><a class="reference internal" href="#get-storage-impl" id="id80">get_storage_impl()</a></li>
|
||||
<li><a class="reference internal" href="#super-seeding" id="id81">super_seeding()</a></li>
|
||||
<li><a class="reference internal" href="#add-piece" id="id82">add_piece()</a></li>
|
||||
<li><a class="reference internal" href="#read-piece" id="id83">read_piece()</a></li>
|
||||
<li><a class="reference internal" href="#force-reannounce-force-dht-announce" id="id84">force_reannounce() force_dht_announce()</a></li>
|
||||
<li><a class="reference internal" href="#scrape-tracker" id="id85">scrape_tracker()</a></li>
|
||||
<li><a class="reference internal" href="#connect-peer" id="id86">connect_peer()</a></li>
|
||||
<li><a class="reference internal" href="#name" id="id87">name()</a></li>
|
||||
<li><a class="reference internal" href="#set-ratio" id="id88">set_ratio()</a></li>
|
||||
<li><a class="reference internal" href="#set-upload-limit-set-download-limit-upload-limit-download-limit" id="id89">set_upload_limit() set_download_limit() upload_limit() download_limit()</a></li>
|
||||
<li><a class="reference internal" href="#set-sequential-download" id="id90">set_sequential_download()</a></li>
|
||||
<li><a class="reference internal" href="#get-peer-download-limit-get-peer-upload-limit-set-peer-upload-limit-set-peer-download-limit" id="id91">get_peer_download_limit() get_peer_upload_limit() set_peer_upload_limit() set_peer_download_limit()</a></li>
|
||||
<li><a class="reference internal" href="#pause-resume" id="id92">pause() resume()</a></li>
|
||||
<li><a class="reference internal" href="#flush-cache" id="id93">flush_cache()</a></li>
|
||||
<li><a class="reference internal" href="#force-recheck" id="id94">force_recheck()</a></li>
|
||||
<li><a class="reference internal" href="#clear-error" id="id95">clear_error()</a></li>
|
||||
<li><a class="reference internal" href="#set-upload-mode" id="id96">set_upload_mode()</a></li>
|
||||
<li><a class="reference internal" href="#set-share-mode" id="id97">set_share_mode()</a></li>
|
||||
<li><a class="reference internal" href="#resolve-countries" id="id98">resolve_countries()</a></li>
|
||||
<li><a class="reference internal" href="#is-seed" id="id99">is_seed()</a></li>
|
||||
<li><a class="reference internal" href="#auto-managed" id="id100">auto_managed()</a></li>
|
||||
<li><a class="reference internal" href="#set-metadata" id="id101">set_metadata()</a></li>
|
||||
<li><a class="reference internal" href="#set-tracker-login" id="id102">set_tracker_login()</a></li>
|
||||
<li><a class="reference internal" href="#trackers-replace-trackers-add-tracker" id="id103">trackers() replace_trackers() add_tracker()</a></li>
|
||||
<li><a class="reference internal" href="#add-url-seed-remove-url-seed-url-seeds" id="id104">add_url_seed() remove_url_seed() url_seeds()</a></li>
|
||||
<li><a class="reference internal" href="#add-http-seed-remove-http-seed-http-seeds" id="id105">add_http_seed() remove_http_seed() http_seeds()</a></li>
|
||||
<li><a class="reference internal" href="#queue-position-queue-position-up-queue-position-down-queue-position-top-queue-position-bottom" id="id106">queue_position() queue_position_up() queue_position_down() queue_position_top() queue_position_bottom()</a></li>
|
||||
<li><a class="reference internal" href="#set-priority" id="id107">set_priority()</a></li>
|
||||
<li><a class="reference internal" href="#use-interface" id="id108">use_interface()</a></li>
|
||||
<li><a class="reference internal" href="#info-hash" id="id109">info_hash()</a></li>
|
||||
<li><a class="reference internal" href="#set-max-uploads-max-uploads" id="id110">set_max_uploads() max_uploads()</a></li>
|
||||
<li><a class="reference internal" href="#set-max-connections-max-connections" id="id111">set_max_connections() max_connections()</a></li>
|
||||
<li><a class="reference internal" href="#save-resume-data" id="id112">save_resume_data()</a></li>
|
||||
<li><a class="reference internal" href="#need-save-resume-data" id="id113">need_save_resume_data()</a></li>
|
||||
<li><a class="reference internal" href="#id5" id="id114">status()</a></li>
|
||||
<li><a class="reference internal" href="#get-download-queue" id="id115">get_download_queue()</a></li>
|
||||
<li><a class="reference internal" href="#get-peer-info" id="id116">get_peer_info()</a></li>
|
||||
<li><a class="reference internal" href="#get-torrent-info" id="id117">get_torrent_info()</a></li>
|
||||
<li><a class="reference internal" href="#is-valid" id="id118">is_valid()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#torrent-status" id="id118">torrent_status</a></li>
|
||||
<li><a class="reference internal" href="#peer-info" id="id119">peer_info</a></li>
|
||||
<li><a class="reference internal" href="#feed-handle" id="id120">feed_handle</a><ul>
|
||||
<li><a class="reference internal" href="#update-feed" id="id121">update_feed()</a></li>
|
||||
<li><a class="reference internal" href="#get-feed-status" id="id122">get_feed_status()</a></li>
|
||||
<li><a class="reference internal" href="#set-settings-settings" id="id123">set_settings() settings()</a></li>
|
||||
<li><a class="reference internal" href="#torrent-status" id="id119">torrent_status</a></li>
|
||||
<li><a class="reference internal" href="#peer-info" id="id120">peer_info</a></li>
|
||||
<li><a class="reference internal" href="#feed-handle" id="id121">feed_handle</a><ul>
|
||||
<li><a class="reference internal" href="#update-feed" id="id122">update_feed()</a></li>
|
||||
<li><a class="reference internal" href="#get-feed-status" id="id123">get_feed_status()</a></li>
|
||||
<li><a class="reference internal" href="#set-settings-settings" id="id124">set_settings() settings()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#feed-item" id="id124">feed_item</a></li>
|
||||
<li><a class="reference internal" href="#session-customization" id="id125">session customization</a><ul>
|
||||
<li><a class="reference internal" href="#presets" id="id126">presets</a></li>
|
||||
<li><a class="reference internal" href="#session-settings" id="id127">session_settings</a></li>
|
||||
<li><a class="reference internal" href="#feed-item" id="id125">feed_item</a></li>
|
||||
<li><a class="reference internal" href="#session-customization" id="id126">session customization</a><ul>
|
||||
<li><a class="reference internal" href="#presets" id="id127">presets</a></li>
|
||||
<li><a class="reference internal" href="#session-settings" id="id128">session_settings</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#pe-settings" id="id128">pe_settings</a></li>
|
||||
<li><a class="reference internal" href="#proxy-settings" id="id129">proxy_settings</a></li>
|
||||
<li><a class="reference internal" href="#ip-filter" id="id130">ip_filter</a><ul>
|
||||
<li><a class="reference internal" href="#id8" id="id131">ip_filter()</a></li>
|
||||
<li><a class="reference internal" href="#add-rule" id="id132">add_rule()</a></li>
|
||||
<li><a class="reference internal" href="#access" id="id133">access()</a></li>
|
||||
<li><a class="reference internal" href="#export-filter" id="id134">export_filter()</a></li>
|
||||
<li><a class="reference internal" href="#pe-settings" id="id129">pe_settings</a></li>
|
||||
<li><a class="reference internal" href="#proxy-settings" id="id130">proxy_settings</a></li>
|
||||
<li><a class="reference internal" href="#ip-filter" id="id131">ip_filter</a><ul>
|
||||
<li><a class="reference internal" href="#id8" id="id132">ip_filter()</a></li>
|
||||
<li><a class="reference internal" href="#add-rule" id="id133">add_rule()</a></li>
|
||||
<li><a class="reference internal" href="#access" id="id134">access()</a></li>
|
||||
<li><a class="reference internal" href="#export-filter" id="id135">export_filter()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#big-number" id="id135">big_number</a></li>
|
||||
<li><a class="reference internal" href="#bitfield" id="id136">bitfield</a></li>
|
||||
<li><a class="reference internal" href="#hasher" id="id137">hasher</a></li>
|
||||
<li><a class="reference internal" href="#fingerprint" id="id138">fingerprint</a></li>
|
||||
<li><a class="reference internal" href="#upnp-and-nat-pmp" id="id139">UPnP and NAT-PMP</a><ul>
|
||||
<li><a class="reference internal" href="#add-mapping" id="id140">add_mapping()</a></li>
|
||||
<li><a class="reference internal" href="#delete-mapping" id="id141">delete_mapping()</a></li>
|
||||
<li><a class="reference internal" href="#router-model" id="id142">router_model()</a></li>
|
||||
<li><a class="reference internal" href="#big-number" id="id136">big_number</a></li>
|
||||
<li><a class="reference internal" href="#bitfield" id="id137">bitfield</a></li>
|
||||
<li><a class="reference internal" href="#hasher" id="id138">hasher</a></li>
|
||||
<li><a class="reference internal" href="#fingerprint" id="id139">fingerprint</a></li>
|
||||
<li><a class="reference internal" href="#upnp-and-nat-pmp" id="id140">UPnP and NAT-PMP</a><ul>
|
||||
<li><a class="reference internal" href="#add-mapping" id="id141">add_mapping()</a></li>
|
||||
<li><a class="reference internal" href="#delete-mapping" id="id142">delete_mapping()</a></li>
|
||||
<li><a class="reference internal" href="#router-model" id="id143">router_model()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#free-functions" id="id143">free functions</a><ul>
|
||||
<li><a class="reference internal" href="#identify-client" id="id144">identify_client()</a></li>
|
||||
<li><a class="reference internal" href="#client-fingerprint" id="id145">client_fingerprint()</a></li>
|
||||
<li><a class="reference internal" href="#lazy-bdecode" id="id146">lazy_bdecode()</a></li>
|
||||
<li><a class="reference internal" href="#bdecode-bencode" id="id147">bdecode() bencode()</a></li>
|
||||
<li><a class="reference internal" href="#add-magnet-uri" id="id148">add_magnet_uri()</a></li>
|
||||
<li><a class="reference internal" href="#make-magnet-uri" id="id149">make_magnet_uri()</a></li>
|
||||
<li><a class="reference internal" href="#free-functions" id="id144">free functions</a><ul>
|
||||
<li><a class="reference internal" href="#identify-client" id="id145">identify_client()</a></li>
|
||||
<li><a class="reference internal" href="#client-fingerprint" id="id146">client_fingerprint()</a></li>
|
||||
<li><a class="reference internal" href="#lazy-bdecode" id="id147">lazy_bdecode()</a></li>
|
||||
<li><a class="reference internal" href="#bdecode-bencode" id="id148">bdecode() bencode()</a></li>
|
||||
<li><a class="reference internal" href="#add-magnet-uri" id="id149">add_magnet_uri()</a></li>
|
||||
<li><a class="reference internal" href="#make-magnet-uri" id="id150">make_magnet_uri()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#alerts" id="id150">alerts</a><ul>
|
||||
<li><a class="reference internal" href="#read-piece-alert" id="id151">read_piece_alert</a></li>
|
||||
<li><a class="reference internal" href="#external-ip-alert" id="id152">external_ip_alert</a></li>
|
||||
<li><a class="reference internal" href="#listen-failed-alert" id="id153">listen_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#listen-succeeded-alert" id="id154">listen_succeeded_alert</a></li>
|
||||
<li><a class="reference internal" href="#portmap-error-alert" id="id155">portmap_error_alert</a></li>
|
||||
<li><a class="reference internal" href="#portmap-alert" id="id156">portmap_alert</a></li>
|
||||
<li><a class="reference internal" href="#portmap-log-alert" id="id157">portmap_log_alert</a></li>
|
||||
<li><a class="reference internal" href="#file-error-alert" id="id158">file_error_alert</a></li>
|
||||
<li><a class="reference internal" href="#file-renamed-alert" id="id159">file_renamed_alert</a></li>
|
||||
<li><a class="reference internal" href="#file-rename-failed-alert" id="id160">file_rename_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#tracker-announce-alert" id="id161">tracker_announce_alert</a></li>
|
||||
<li><a class="reference internal" href="#tracker-error-alert" id="id162">tracker_error_alert</a></li>
|
||||
<li><a class="reference internal" href="#tracker-reply-alert" id="id163">tracker_reply_alert</a></li>
|
||||
<li><a class="reference internal" href="#tracker-warning-alert" id="id164">tracker_warning_alert</a></li>
|
||||
<li><a class="reference internal" href="#scrape-reply-alert" id="id165">scrape_reply_alert</a></li>
|
||||
<li><a class="reference internal" href="#scrape-failed-alert" id="id166">scrape_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#url-seed-alert" id="id167">url_seed_alert</a></li>
|
||||
<li><a class="reference internal" href="#hash-failed-alert" id="id168">hash_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-alert" id="id169">peer_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-connect-alert" id="id170">peer_connect_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-ban-alert" id="id171">peer_ban_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-snubbed-alert" id="id172">peer_snubbed_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-unsnubbed-alert" id="id173">peer_unsnubbed_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-error-alert" id="id174">peer_error_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-connected-alert" id="id175">peer_connected_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-disconnected-alert" id="id176">peer_disconnected_alert</a></li>
|
||||
<li><a class="reference internal" href="#invalid-request-alert" id="id177">invalid_request_alert</a></li>
|
||||
<li><a class="reference internal" href="#request-dropped-alert" id="id178">request_dropped_alert</a></li>
|
||||
<li><a class="reference internal" href="#block-timeout-alert" id="id179">block_timeout_alert</a></li>
|
||||
<li><a class="reference internal" href="#block-finished-alert" id="id180">block_finished_alert</a></li>
|
||||
<li><a class="reference internal" href="#lsd-peer-alert" id="id181">lsd_peer_alert</a></li>
|
||||
<li><a class="reference internal" href="#file-completed-alert" id="id182">file_completed_alert</a></li>
|
||||
<li><a class="reference internal" href="#block-downloading-alert" id="id183">block_downloading_alert</a></li>
|
||||
<li><a class="reference internal" href="#unwanted-block-alert" id="id184">unwanted_block_alert</a></li>
|
||||
<li><a class="reference internal" href="#torrent-delete-failed-alert" id="id185">torrent_delete_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#torrent-deleted-alert" id="id186">torrent_deleted_alert</a></li>
|
||||
<li><a class="reference internal" href="#torrent-finished-alert" id="id187">torrent_finished_alert</a></li>
|
||||
<li><a class="reference internal" href="#performance-alert" id="id188">performance_alert</a></li>
|
||||
<li><a class="reference internal" href="#state-changed-alert" id="id189">state_changed_alert</a></li>
|
||||
<li><a class="reference internal" href="#metadata-failed-alert" id="id190">metadata_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#metadata-received-alert" id="id191">metadata_received_alert</a></li>
|
||||
<li><a class="reference internal" href="#fastresume-rejected-alert" id="id192">fastresume_rejected_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-blocked-alert" id="id193">peer_blocked_alert</a></li>
|
||||
<li><a class="reference internal" href="#storage-moved-alert" id="id194">storage_moved_alert</a></li>
|
||||
<li><a class="reference internal" href="#storage-moved-failed-alert" id="id195">storage_moved_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#torrent-paused-alert" id="id196">torrent_paused_alert</a></li>
|
||||
<li><a class="reference internal" href="#torrent-resumed-alert" id="id197">torrent_resumed_alert</a></li>
|
||||
<li><a class="reference internal" href="#save-resume-data-alert" id="id198">save_resume_data_alert</a></li>
|
||||
<li><a class="reference internal" href="#save-resume-data-failed-alert" id="id199">save_resume_data_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#stats-alert" id="id200">stats_alert</a></li>
|
||||
<li><a class="reference internal" href="#cache-flushed-alert" id="id201">cache_flushed_alert</a></li>
|
||||
<li><a class="reference internal" href="#dht-announce-alert" id="id202">dht_announce_alert</a></li>
|
||||
<li><a class="reference internal" href="#dht-get-peers-alert" id="id203">dht_get_peers_alert</a></li>
|
||||
<li><a class="reference internal" href="#dht-reply-alert" id="id204">dht_reply_alert</a></li>
|
||||
<li><a class="reference internal" href="#dht-bootstrap-alert" id="id205">dht_bootstrap_alert</a></li>
|
||||
<li><a class="reference internal" href="#anonymous-mode-alert" id="id206">anonymous_mode_alert</a></li>
|
||||
<li><a class="reference internal" href="#rss-alert" id="id207">rss_alert</a></li>
|
||||
<li><a class="reference internal" href="#alerts" id="id151">alerts</a><ul>
|
||||
<li><a class="reference internal" href="#torrent-added-alert" id="id152">torrent_added_alert</a></li>
|
||||
<li><a class="reference internal" href="#torrent-removed-alert" id="id153">torrent_removed_alert</a></li>
|
||||
<li><a class="reference internal" href="#read-piece-alert" id="id154">read_piece_alert</a></li>
|
||||
<li><a class="reference internal" href="#external-ip-alert" id="id155">external_ip_alert</a></li>
|
||||
<li><a class="reference internal" href="#listen-failed-alert" id="id156">listen_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#listen-succeeded-alert" id="id157">listen_succeeded_alert</a></li>
|
||||
<li><a class="reference internal" href="#portmap-error-alert" id="id158">portmap_error_alert</a></li>
|
||||
<li><a class="reference internal" href="#portmap-alert" id="id159">portmap_alert</a></li>
|
||||
<li><a class="reference internal" href="#portmap-log-alert" id="id160">portmap_log_alert</a></li>
|
||||
<li><a class="reference internal" href="#file-error-alert" id="id161">file_error_alert</a></li>
|
||||
<li><a class="reference internal" href="#torrent-error-alert" id="id162">torrent_error_alert</a></li>
|
||||
<li><a class="reference internal" href="#file-renamed-alert" id="id163">file_renamed_alert</a></li>
|
||||
<li><a class="reference internal" href="#file-rename-failed-alert" id="id164">file_rename_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#tracker-announce-alert" id="id165">tracker_announce_alert</a></li>
|
||||
<li><a class="reference internal" href="#tracker-error-alert" id="id166">tracker_error_alert</a></li>
|
||||
<li><a class="reference internal" href="#tracker-reply-alert" id="id167">tracker_reply_alert</a></li>
|
||||
<li><a class="reference internal" href="#tracker-warning-alert" id="id168">tracker_warning_alert</a></li>
|
||||
<li><a class="reference internal" href="#scrape-reply-alert" id="id169">scrape_reply_alert</a></li>
|
||||
<li><a class="reference internal" href="#scrape-failed-alert" id="id170">scrape_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#url-seed-alert" id="id171">url_seed_alert</a></li>
|
||||
<li><a class="reference internal" href="#hash-failed-alert" id="id172">hash_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-alert" id="id173">peer_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-connect-alert" id="id174">peer_connect_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-ban-alert" id="id175">peer_ban_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-snubbed-alert" id="id176">peer_snubbed_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-unsnubbed-alert" id="id177">peer_unsnubbed_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-error-alert" id="id178">peer_error_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-connected-alert" id="id179">peer_connected_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-disconnected-alert" id="id180">peer_disconnected_alert</a></li>
|
||||
<li><a class="reference internal" href="#invalid-request-alert" id="id181">invalid_request_alert</a></li>
|
||||
<li><a class="reference internal" href="#request-dropped-alert" id="id182">request_dropped_alert</a></li>
|
||||
<li><a class="reference internal" href="#block-timeout-alert" id="id183">block_timeout_alert</a></li>
|
||||
<li><a class="reference internal" href="#block-finished-alert" id="id184">block_finished_alert</a></li>
|
||||
<li><a class="reference internal" href="#lsd-peer-alert" id="id185">lsd_peer_alert</a></li>
|
||||
<li><a class="reference internal" href="#file-completed-alert" id="id186">file_completed_alert</a></li>
|
||||
<li><a class="reference internal" href="#block-downloading-alert" id="id187">block_downloading_alert</a></li>
|
||||
<li><a class="reference internal" href="#unwanted-block-alert" id="id188">unwanted_block_alert</a></li>
|
||||
<li><a class="reference internal" href="#torrent-delete-failed-alert" id="id189">torrent_delete_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#torrent-deleted-alert" id="id190">torrent_deleted_alert</a></li>
|
||||
<li><a class="reference internal" href="#torrent-finished-alert" id="id191">torrent_finished_alert</a></li>
|
||||
<li><a class="reference internal" href="#performance-alert" id="id192">performance_alert</a></li>
|
||||
<li><a class="reference internal" href="#state-changed-alert" id="id193">state_changed_alert</a></li>
|
||||
<li><a class="reference internal" href="#metadata-failed-alert" id="id194">metadata_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#metadata-received-alert" id="id195">metadata_received_alert</a></li>
|
||||
<li><a class="reference internal" href="#fastresume-rejected-alert" id="id196">fastresume_rejected_alert</a></li>
|
||||
<li><a class="reference internal" href="#peer-blocked-alert" id="id197">peer_blocked_alert</a></li>
|
||||
<li><a class="reference internal" href="#storage-moved-alert" id="id198">storage_moved_alert</a></li>
|
||||
<li><a class="reference internal" href="#storage-moved-failed-alert" id="id199">storage_moved_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#torrent-paused-alert" id="id200">torrent_paused_alert</a></li>
|
||||
<li><a class="reference internal" href="#torrent-resumed-alert" id="id201">torrent_resumed_alert</a></li>
|
||||
<li><a class="reference internal" href="#save-resume-data-alert" id="id202">save_resume_data_alert</a></li>
|
||||
<li><a class="reference internal" href="#save-resume-data-failed-alert" id="id203">save_resume_data_failed_alert</a></li>
|
||||
<li><a class="reference internal" href="#stats-alert" id="id204">stats_alert</a></li>
|
||||
<li><a class="reference internal" href="#cache-flushed-alert" id="id205">cache_flushed_alert</a></li>
|
||||
<li><a class="reference internal" href="#dht-announce-alert" id="id206">dht_announce_alert</a></li>
|
||||
<li><a class="reference internal" href="#dht-get-peers-alert" id="id207">dht_get_peers_alert</a></li>
|
||||
<li><a class="reference internal" href="#dht-reply-alert" id="id208">dht_reply_alert</a></li>
|
||||
<li><a class="reference internal" href="#dht-bootstrap-alert" id="id209">dht_bootstrap_alert</a></li>
|
||||
<li><a class="reference internal" href="#anonymous-mode-alert" id="id210">anonymous_mode_alert</a></li>
|
||||
<li><a class="reference internal" href="#rss-alert" id="id211">rss_alert</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#alert-dispatcher" id="id208">alert dispatcher</a></li>
|
||||
<li><a class="reference internal" href="#exceptions" id="id209">exceptions</a><ul>
|
||||
<li><a class="reference internal" href="#libtorrent-exception" id="id210">libtorrent_exception</a></li>
|
||||
<li><a class="reference internal" href="#alert-dispatcher" id="id212">alert dispatcher</a></li>
|
||||
<li><a class="reference internal" href="#exceptions" id="id213">exceptions</a><ul>
|
||||
<li><a class="reference internal" href="#libtorrent-exception" id="id214">libtorrent_exception</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#error-code" id="id211">error_code</a><ul>
|
||||
<li><a class="reference internal" href="#translating-error-codes" id="id212">translating error codes</a></li>
|
||||
<li><a class="reference internal" href="#error-code" id="id215">error_code</a><ul>
|
||||
<li><a class="reference internal" href="#translating-error-codes" id="id216">translating error codes</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#storage-interface" id="id213">storage_interface</a><ul>
|
||||
<li><a class="reference internal" href="#initialize" id="id214">initialize()</a></li>
|
||||
<li><a class="reference internal" href="#has-any-file" id="id215">has_any_file()</a></li>
|
||||
<li><a class="reference internal" href="#readv-writev" id="id216">readv() writev()</a></li>
|
||||
<li><a class="reference internal" href="#sparse-end" id="id217">sparse_end()</a></li>
|
||||
<li><a class="reference internal" href="#id10" id="id218">move_storage()</a></li>
|
||||
<li><a class="reference internal" href="#verify-resume-data" id="id219">verify_resume_data()</a></li>
|
||||
<li><a class="reference internal" href="#write-resume-data" id="id220">write_resume_data()</a></li>
|
||||
<li><a class="reference internal" href="#move-slot" id="id221">move_slot()</a></li>
|
||||
<li><a class="reference internal" href="#swap-slots" id="id222">swap_slots()</a></li>
|
||||
<li><a class="reference internal" href="#swap-slots3" id="id223">swap_slots3()</a></li>
|
||||
<li><a class="reference internal" href="#id11" id="id224">rename_file()</a></li>
|
||||
<li><a class="reference internal" href="#release-files" id="id225">release_files()</a></li>
|
||||
<li><a class="reference internal" href="#delete-files" id="id226">delete_files()</a></li>
|
||||
<li><a class="reference internal" href="#finalize-file" id="id227">finalize_file()</a></li>
|
||||
<li><a class="reference internal" href="#storage-interface" id="id217">storage_interface</a><ul>
|
||||
<li><a class="reference internal" href="#initialize" id="id218">initialize()</a></li>
|
||||
<li><a class="reference internal" href="#has-any-file" id="id219">has_any_file()</a></li>
|
||||
<li><a class="reference internal" href="#readv-writev" id="id220">readv() writev()</a></li>
|
||||
<li><a class="reference internal" href="#sparse-end" id="id221">sparse_end()</a></li>
|
||||
<li><a class="reference internal" href="#id10" id="id222">move_storage()</a></li>
|
||||
<li><a class="reference internal" href="#verify-resume-data" id="id223">verify_resume_data()</a></li>
|
||||
<li><a class="reference internal" href="#write-resume-data" id="id224">write_resume_data()</a></li>
|
||||
<li><a class="reference internal" href="#move-slot" id="id225">move_slot()</a></li>
|
||||
<li><a class="reference internal" href="#swap-slots" id="id226">swap_slots()</a></li>
|
||||
<li><a class="reference internal" href="#swap-slots3" id="id227">swap_slots3()</a></li>
|
||||
<li><a class="reference internal" href="#id11" id="id228">rename_file()</a></li>
|
||||
<li><a class="reference internal" href="#release-files" id="id229">release_files()</a></li>
|
||||
<li><a class="reference internal" href="#delete-files" id="id230">delete_files()</a></li>
|
||||
<li><a class="reference internal" href="#finalize-file" id="id231">finalize_file()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#magnet-links" id="id228">magnet links</a></li>
|
||||
<li><a class="reference internal" href="#queuing" id="id229">queuing</a><ul>
|
||||
<li><a class="reference internal" href="#downloading" id="id230">downloading</a></li>
|
||||
<li><a class="reference internal" href="#seeding" id="id231">seeding</a></li>
|
||||
<li><a class="reference internal" href="#magnet-links" id="id232">magnet links</a></li>
|
||||
<li><a class="reference internal" href="#queuing" id="id233">queuing</a><ul>
|
||||
<li><a class="reference internal" href="#downloading" id="id234">downloading</a></li>
|
||||
<li><a class="reference internal" href="#seeding" id="id235">seeding</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#fast-resume" id="id232">fast resume</a><ul>
|
||||
<li><a class="reference internal" href="#file-format" id="id233">file format</a></li>
|
||||
<li><a class="reference internal" href="#fast-resume" id="id236">fast resume</a><ul>
|
||||
<li><a class="reference internal" href="#file-format" id="id237">file format</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#threads" id="id234">threads</a></li>
|
||||
<li><a class="reference internal" href="#storage-allocation" id="id235">storage allocation</a><ul>
|
||||
<li><a class="reference internal" href="#sparse-allocation" id="id236">sparse allocation</a></li>
|
||||
<li><a class="reference internal" href="#full-allocation" id="id237">full allocation</a></li>
|
||||
<li><a class="reference internal" href="#compact-allocation" id="id238">compact allocation</a></li>
|
||||
<li><a class="reference internal" href="#threads" id="id238">threads</a></li>
|
||||
<li><a class="reference internal" href="#storage-allocation" id="id239">storage allocation</a><ul>
|
||||
<li><a class="reference internal" href="#sparse-allocation" id="id240">sparse allocation</a></li>
|
||||
<li><a class="reference internal" href="#full-allocation" id="id241">full allocation</a></li>
|
||||
<li><a class="reference internal" href="#compact-allocation" id="id242">compact allocation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#extensions" id="id239">extensions</a><ul>
|
||||
<li><a class="reference internal" href="#metadata-from-peers" id="id240">metadata from peers</a></li>
|
||||
<li><a class="reference internal" href="#http-seeding" id="id241">HTTP seeding</a></li>
|
||||
<li><a class="reference internal" href="#extensions" id="id243">extensions</a><ul>
|
||||
<li><a class="reference internal" href="#metadata-from-peers" id="id244">metadata from peers</a></li>
|
||||
<li><a class="reference internal" href="#http-seeding" id="id245">HTTP seeding</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#filename-checks" id="id242">filename checks</a></li>
|
||||
<li><a class="reference internal" href="#filename-checks" id="id246">filename checks</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="overview">
|
||||
|
@ -466,7 +470,13 @@ class session: public boost::noncopyable
|
|||
void remove_torrent(torrent_handle const& h
|
||||
, int options = none);
|
||||
torrent_handle find_torrent(sha_hash const& ih);
|
||||
|
||||
std::vector<torrent_handle> get_torrents() const;
|
||||
void get_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::function<bool(torrent_status const&)> const& pred
|
||||
, boost::uint32_t flags = 0) const;
|
||||
void refresh_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::uint32_t flags) const;
|
||||
|
||||
void set_settings(session_settings const& settings);
|
||||
session_settings settings() const;
|
||||
|
@ -838,6 +848,34 @@ In case the torrent cannot be found, an invalid torrent_handle is returned.</p>
|
|||
<p><tt class="docutils literal"><span class="pre">get_torrents()</span></tt> returns a vector of torrent_handles to all the torrents
|
||||
currently in the session.</p>
|
||||
</div>
|
||||
<div class="section" id="get-torrent-status-refresh-torrent-status">
|
||||
<h2>get_torrent_status() refresh_torrent_status()</h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
void get_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::function<bool(torrent_status const&)> const& pred
|
||||
, boost::uint32_t flags = 0) const;
|
||||
void refresh_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::uint32_t flags = 0) const;
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p><tt class="docutils literal"><span class="pre">get_torrent_status</span></tt> returns a vector of the <tt class="docutils literal"><span class="pre">torrent_status</span></tt> for every
|
||||
torrent which satisfies <tt class="docutils literal"><span class="pre">pred</span></tt>, which is a predicate function which determines
|
||||
if a torrent should be included in the returned set or not. Returning true means
|
||||
it should be included and false means excluded. The <tt class="docutils literal"><span class="pre">flags</span></tt> argument is the same
|
||||
as to <tt class="docutils literal"><span class="pre">torrent_handle::status()</span></tt>. Since <tt class="docutils literal"><span class="pre">pred</span></tt> is guaranteed to be called for
|
||||
every torrent, it may be used to count the number of torrents of different categories
|
||||
as well.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">refresh_torrent_status</span></tt> takes a vector of <tt class="docutils literal"><span class="pre">torrent_status</span></tt> structs (for instance
|
||||
the same vector that was returned by <tt class="docutils literal"><span class="pre">get_torrent_status()</span></tt>) and refreshes the
|
||||
status based on the <tt class="docutils literal"><span class="pre">handle</span></tt> member. It is possible to use this function by
|
||||
first setting up a vector of default constructed <tt class="docutils literal"><span class="pre">torrent_status</span></tt> objects, only
|
||||
initializing the <tt class="docutils literal"><span class="pre">handle</span></tt> member, in order to request the torrent status for
|
||||
multiple torrents in a single call. This can save a significant amount of time
|
||||
if you have a lot of torrents.</p>
|
||||
<p>Any <tt class="docutils literal"><span class="pre">torrent_status</span></tt> object whose <tt class="docutils literal"><span class="pre">handle</span></tt> member is not referring to a
|
||||
valid torrent are ignored.</p>
|
||||
</div>
|
||||
<div class="section" id="load-asnum-db-load-country-db-as-for-ip">
|
||||
<h2>load_asnum_db() load_country_db() as_for_ip()</h2>
|
||||
<blockquote>
|
||||
|
@ -953,9 +991,18 @@ struct session_status
|
|||
int num_unchoked;
|
||||
int allowed_upload_slots;
|
||||
|
||||
int up_bandwidth_queue;
|
||||
int down_bandwidth_queue;
|
||||
|
||||
int up_bandwidth_bytes_queue;
|
||||
int down_bandwidth_bytes_queue;
|
||||
|
||||
int optimistic_unchoke_counter;
|
||||
int unchoke_counter;
|
||||
|
||||
int disk_write_queue;
|
||||
int disk_read_queue;
|
||||
|
||||
int dht_nodes;
|
||||
int dht_node_cache;
|
||||
int dht_torrents;
|
||||
|
@ -997,10 +1044,17 @@ than the sum of all peers of all torrents because the incoming connections may n
|
|||
be assigned a torrent yet.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">num_unchoked</span></tt> is the current number of unchoked peers.
|
||||
<tt class="docutils literal"><span class="pre">allowed_upload_slots</span></tt> is the current allowed number of unchoked peers.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">up_bandwidth_queue</span></tt> and <tt class="docutils literal"><span class="pre">down_bandwidth_queue</span></tt> are the number of peers that are
|
||||
waiting for more bandwidth quota from the torrent rate limiter.
|
||||
<tt class="docutils literal"><span class="pre">up_bandwidth_bytes_queue</span></tt> and <tt class="docutils literal"><span class="pre">down_bandwidth_bytes_queue</span></tt> count the number of
|
||||
bytes the connections are waiting for to be able to send and receive.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">optimistic_unchoke_counter</span></tt> and <tt class="docutils literal"><span class="pre">unchoke_counter</span></tt> tells the number of
|
||||
seconds until the next optimistic unchoke change and the start of the next
|
||||
unchoke interval. These numbers may be reset prematurely if a peer that is
|
||||
unchoked disconnects or becomes notinterested.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">disk_write_queue</span></tt> and <tt class="docutils literal"><span class="pre">disk_read_queue</span></tt> are the number of peers currently
|
||||
waiting on a disk write or disk read to complete before it receives or sends
|
||||
any more data on the socket. It'a a metric of how disk bound you are.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">dht_nodes</span></tt>, <tt class="docutils literal"><span class="pre">dht_node_cache</span></tt> and <tt class="docutils literal"><span class="pre">dht_torrents</span></tt> are only available when
|
||||
built with DHT support. They are all set to 0 if the DHT isn't running. When
|
||||
the DHT is running, <tt class="docutils literal"><span class="pre">dht_nodes</span></tt> is set to the number of nodes in the routing
|
||||
|
@ -1167,13 +1221,12 @@ void set_alert_mask(int m);
|
|||
<tt class="docutils literal"><span class="pre">m</span></tt> is a bitmask where each bit represents a category of alerts.</p>
|
||||
<p>See <a class="reference internal" href="#alerts">alerts</a> for mor information on the alert categories.</p>
|
||||
</div>
|
||||
<div class="section" id="pop-alert-wait-for-alert-set-alert-queue-size-limit">
|
||||
<h2>pop_alert() wait_for_alert() set_alert_queue_size_limit()</h2>
|
||||
<div class="section" id="pop-alert-wait-for-alert">
|
||||
<h2>pop_alert() wait_for_alert()</h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
std::auto_ptr<alert> pop_alert();
|
||||
alert const* wait_for_alert(time_duration max_wait);
|
||||
size_t set_alert_queue_size_limit(size_t queue_size_limit_);
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p><tt class="docutils literal"><span class="pre">pop_alert()</span></tt> is used to ask the session if any errors or events has occurred. With
|
||||
|
@ -1187,9 +1240,8 @@ same pointer until the alert is popped by calling <tt class="docutils literal"><
|
|||
leaving any alert dispatching mechanism independent of this blocking call, the dispatcher
|
||||
can be called and it can pop the alert independently.</p>
|
||||
<p>In the python binding, <tt class="docutils literal"><span class="pre">wait_for_alert</span></tt> takes the number of milliseconds to wait as an integer.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">set_alert_queue_size_limit()</span></tt> you can specify how many alerts can be awaiting for dispatching.
|
||||
If this limit is reached, new incoming alerts can not be received until alerts are popped
|
||||
by calling <tt class="docutils literal"><span class="pre">pop_alert</span></tt>. Default value is 1000.</p>
|
||||
<p>To control the max number of alerts that's queued by the session, see
|
||||
<tt class="docutils literal"><span class="pre">session_settings::alert_queue_size</span></tt>.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">save_resume_data_alert</span></tt> and <tt class="docutils literal"><span class="pre">save_resume_data_failed_alert</span></tt> are always posted, regardelss
|
||||
of the alert mask.</p>
|
||||
</div>
|
||||
|
@ -3186,6 +3238,8 @@ struct torrent_status
|
|||
checking_resume_data
|
||||
};
|
||||
|
||||
torrent_handle handle;
|
||||
|
||||
state_t state;
|
||||
bool paused;
|
||||
bool auto_managed;
|
||||
|
@ -3284,6 +3338,7 @@ struct torrent_status
|
|||
bool need_save_resume;
|
||||
};
|
||||
</pre>
|
||||
<p><tt class="docutils literal"><span class="pre">handle</span></tt> is a handle to the torrent whose status the object represents.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">progress</span></tt> is a value in the range [0, 1], that represents the progress of the
|
||||
torrent's current task. It may be checking files or downloading.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">progress_ppm</span></tt> reflects the same value as <tt class="docutils literal"><span class="pre">progress</span></tt>, but instead in a range
|
||||
|
@ -4246,6 +4301,10 @@ struct session_settings
|
|||
|
||||
int torrent_connect_boost;
|
||||
bool seeding_outgoing_connections;
|
||||
|
||||
bool no_connect_privileged_ports;
|
||||
int alert_queue_size;
|
||||
int max_metadata_size;
|
||||
};
|
||||
</pre>
|
||||
<p><tt class="docutils literal"><span class="pre">version</span></tt> is automatically set to the libtorrent version you're using
|
||||
|
@ -4924,6 +4983,14 @@ may be set to false in very specific applications where the cost of making
|
|||
outgoing connections is high, and there are no or small benefits of doing so.
|
||||
For instance, if no nodes are behind a firewall or a NAT, seeds don't need to
|
||||
make outgoing connections.</p>
|
||||
<p>if <tt class="docutils literal"><span class="pre">no_connect_privileged_ports</span></tt> is true (which is the default), libtorrent
|
||||
will not connect to any peers on priviliged ports (<= 1023). This can mitigate
|
||||
using bittorrent swarms for certain DDoS attacks.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">alert_queue_size</span></tt> is the maximum number of alerts queued up internally. If
|
||||
alerts are not popped, the queue will eventually fill up to this level. This
|
||||
defaults to 1000.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">max_metadata_size</span></tt> is the maximum allowed size (in bytes) to be received
|
||||
by the metadata extension, i.e. magnet links. It defaults to 1 MiB.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="pe-settings">
|
||||
|
@ -5011,6 +5078,7 @@ struct proxy_settings
|
|||
|
||||
proxy_type type;
|
||||
bool proxy_hostnames;
|
||||
bool proxy_peer_connections;
|
||||
};
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
@ -5042,6 +5110,9 @@ user authorization. The username and password will be sent to the proxy.</li>
|
|||
<p><tt class="docutils literal"><span class="pre">proxy_hostnames</span></tt> defaults to true. It means that hostnames should be
|
||||
attempted to be resolved through the proxy instead of using the local DNS
|
||||
service. This is only supported by SOCKS5 and HTTP.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">proxy_peer_connections</span></tt> determines whether or not to excempt peer and
|
||||
web seed connections from using the proxy. This defaults to true, i.e. peer
|
||||
connections are proxied by default.</p>
|
||||
</div>
|
||||
<div class="section" id="ip-filter">
|
||||
<h1>ip_filter</h1>
|
||||
|
@ -5630,6 +5701,7 @@ public:
|
|||
virtual std::string message() const = 0;
|
||||
virtual char const* what() const = 0;
|
||||
virtual int category() const = 0;
|
||||
virtual bool discardable() const;
|
||||
virtual std::auto_ptr<alert> clone() const = 0;
|
||||
};
|
||||
</pre>
|
||||
|
@ -5658,6 +5730,9 @@ switch (a->type())
|
|||
not include any information that might be bundled with the alert.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">category()</span></tt> returns a bitmask specifying which categories this alert belong to.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">clone()</span></tt> returns a pointer to a copy of the alert.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">discardable()</span></tt> determines whether or not an alert is allowed to be discarded
|
||||
when the alert queue is full. There are a few alerts which may not be discared,
|
||||
since they would break the user contract, such as <tt class="docutils literal"><span class="pre">save_resume_data_alert</span></tt>.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">message()</span></tt> generate a string describing the alert and the information bundled
|
||||
with it. This is mainly intended for debug and development use. It is not suitable
|
||||
to use this for applications that may be localized. Instead, handle each alert
|
||||
|
@ -5681,6 +5756,33 @@ struct tracker_alert: torrent_alert
|
|||
};
|
||||
</pre>
|
||||
<p>The specific alerts are:</p>
|
||||
<div class="section" id="torrent-added-alert">
|
||||
<h2>torrent_added_alert</h2>
|
||||
<p>The <tt class="docutils literal"><span class="pre">torrent_added_alert</span></tt> is posted once every time a torrent is added.
|
||||
It doesn't contain any members of its own, but inherits the torrent handle
|
||||
from its base class.
|
||||
It's posted when the <tt class="docutils literal"><span class="pre">status_notification</span></tt> bit is set in the alert mask.</p>
|
||||
<pre class="literal-block">
|
||||
struct torrent_added_alert: torrent_alert
|
||||
{
|
||||
// ...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="torrent-removed-alert">
|
||||
<h2>torrent_removed_alert</h2>
|
||||
<p>The <tt class="docutils literal"><span class="pre">torrent_removed_alert</span></tt> is posted whenever a torrent is removed. Since
|
||||
the torrent handle in its baseclass will always be invalid (since the torrent
|
||||
is already removed) it has the info hash as a member, to identify it.
|
||||
It's posted when the <tt class="docutils literal"><span class="pre">status_notification</span></tt> bit is set in the alert mask.</p>
|
||||
<pre class="literal-block">
|
||||
struct torrent_removed_alert: torrent_alert
|
||||
{
|
||||
// ...
|
||||
sha1_hash info_hash;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="read-piece-alert">
|
||||
<h2>read_piece_alert</h2>
|
||||
<p>This alert is posted when the asynchronous read operation initiated by
|
||||
|
@ -5817,6 +5919,18 @@ struct file_error_alert: torrent_alert
|
|||
};
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="torrent-error-alert">
|
||||
<h2>torrent_error_alert</h2>
|
||||
<p>This is posted whenever a torrent is transitioned into the error state.</p>
|
||||
<pre class="literal-block">
|
||||
struct torrent_error_alert: torrent_alert
|
||||
{
|
||||
// ...
|
||||
error_code error;
|
||||
};
|
||||
</pre>
|
||||
<p>The <tt class="docutils literal"><span class="pre">error</span></tt> specifies which error the torrent encountered.</p>
|
||||
</div>
|
||||
<div class="section" id="file-renamed-alert">
|
||||
<h2>file_renamed_alert</h2>
|
||||
<p>This is posted as a response to a <tt class="docutils literal"><span class="pre">torrent_handle::rename_file</span></tt> call, if the rename
|
||||
|
@ -6060,7 +6174,7 @@ struct peer_disconnected_alert: peer_alert
|
|||
<div class="section" id="invalid-request-alert">
|
||||
<h2>invalid_request_alert</h2>
|
||||
<p>This is a debug alert that is generated by an incoming invalid piece request.
|
||||
<tt class="docutils literal"><span class="pre">ìp</span></tt> is the address of the peer and the <tt class="docutils literal"><span class="pre">request</span></tt> is the actual incoming
|
||||
<tt class="docutils literal"><span class="pre">Ïp</span></tt> is the address of the peer and the <tt class="docutils literal"><span class="pre">request</span></tt> is the actual incoming
|
||||
request from the peer.</p>
|
||||
<pre class="literal-block">
|
||||
struct invalid_request_alert: peer_alert
|
||||
|
@ -7495,13 +7609,13 @@ std::string error_code_to_string(boost::system::error_code const& ec)
|
|||
static const char const* swedish[] =
|
||||
{
|
||||
"inget fel",
|
||||
"en fil i torrenten kolliderar med en fil från en annan torrent",
|
||||
"en fil i torrenten kolliderar med en fil frÂn en annan torrent",
|
||||
"hash check misslyckades",
|
||||
"torrent filen är inte en dictionary",
|
||||
"'info'-nyckeln saknas eller är korrupt i torrentfilen",
|
||||
"'info'-fältet är inte en dictionary",
|
||||
"'piece length' fältet saknas eller är korrupt i torrentfilen",
|
||||
"torrentfilen saknar namnfältet",
|
||||
"torrent filen ‰r inte en dictionary",
|
||||
"'info'-nyckeln saknas eller ‰r korrupt i torrentfilen",
|
||||
"'info'-f‰ltet ‰r inte en dictionary",
|
||||
"'piece length' f‰ltet saknas eller ‰r korrupt i torrentfilen",
|
||||
"torrentfilen saknar namnf‰ltet",
|
||||
"ogiltigt namn i torrentfilen (kan vara en attack)",
|
||||
// ... more strings here
|
||||
};
|
||||
|
|
|
@ -158,7 +158,13 @@ The ``session`` class has the following synopsis::
|
|||
void remove_torrent(torrent_handle const& h
|
||||
, int options = none);
|
||||
torrent_handle find_torrent(sha_hash const& ih);
|
||||
|
||||
std::vector<torrent_handle> get_torrents() const;
|
||||
void get_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::function<bool(torrent_status const&)> const& pred
|
||||
, boost::uint32_t flags = 0) const;
|
||||
void refresh_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::uint32_t flags) const;
|
||||
|
||||
void set_settings(session_settings const& settings);
|
||||
session_settings settings() const;
|
||||
|
@ -565,6 +571,36 @@ See ``torrent_handle::is_valid()`` to know if the torrent was found or not.
|
|||
``get_torrents()`` returns a vector of torrent_handles to all the torrents
|
||||
currently in the session.
|
||||
|
||||
get_torrent_status() refresh_torrent_status()
|
||||
---------------------------------------------
|
||||
|
||||
::
|
||||
|
||||
void get_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::function<bool(torrent_status const&)> const& pred
|
||||
, boost::uint32_t flags = 0) const;
|
||||
void refresh_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::uint32_t flags = 0) const;
|
||||
|
||||
``get_torrent_status`` returns a vector of the ``torrent_status`` for every
|
||||
torrent which satisfies ``pred``, which is a predicate function which determines
|
||||
if a torrent should be included in the returned set or not. Returning true means
|
||||
it should be included and false means excluded. The ``flags`` argument is the same
|
||||
as to ``torrent_handle::status()``. Since ``pred`` is guaranteed to be called for
|
||||
every torrent, it may be used to count the number of torrents of different categories
|
||||
as well.
|
||||
|
||||
``refresh_torrent_status`` takes a vector of ``torrent_status`` structs (for instance
|
||||
the same vector that was returned by ``get_torrent_status()``) and refreshes the
|
||||
status based on the ``handle`` member. It is possible to use this function by
|
||||
first setting up a vector of default constructed ``torrent_status`` objects, only
|
||||
initializing the ``handle`` member, in order to request the torrent status for
|
||||
multiple torrents in a single call. This can save a significant amount of time
|
||||
if you have a lot of torrents.
|
||||
|
||||
Any ``torrent_status`` object whose ``handle`` member is not referring to a
|
||||
valid torrent are ignored.
|
||||
|
||||
load_asnum_db() load_country_db() as_for_ip()
|
||||
---------------------------------------------
|
||||
|
||||
|
@ -3146,6 +3182,8 @@ It contains the following fields::
|
|||
checking_resume_data
|
||||
};
|
||||
|
||||
torrent_handle handle;
|
||||
|
||||
state_t state;
|
||||
bool paused;
|
||||
bool auto_managed;
|
||||
|
@ -3244,6 +3282,8 @@ It contains the following fields::
|
|||
bool need_save_resume;
|
||||
};
|
||||
|
||||
``handle`` is a handle to the torrent whose status the object represents.
|
||||
|
||||
``progress`` is a value in the range [0, 1], that represents the progress of the
|
||||
torrent's current task. It may be checking files or downloading.
|
||||
|
||||
|
|
|
@ -73,17 +73,19 @@
|
|||
<li><a class="reference internal" href="#high-performance-seeding" id="id12">high performance seeding</a><ul>
|
||||
<li><a class="reference internal" href="#file-pool" id="id13">file pool</a></li>
|
||||
<li><a class="reference internal" href="#disk-cache" id="id14">disk cache</a></li>
|
||||
<li><a class="reference internal" href="#send-buffer-low-watermark" id="id15">send buffer low watermark</a></li>
|
||||
<li><a class="reference internal" href="#peers" id="id16">peers</a></li>
|
||||
<li><a class="reference internal" href="#torrent-limits" id="id17">torrent limits</a></li>
|
||||
<li><a class="reference internal" href="#utp-tcp-mixed-mode" id="id15">uTP-TCP mixed mode</a></li>
|
||||
<li><a class="reference internal" href="#send-buffer-low-watermark" id="id16">send buffer low watermark</a></li>
|
||||
<li><a class="reference internal" href="#peers" id="id17">peers</a></li>
|
||||
<li><a class="reference internal" href="#torrent-limits" id="id18">torrent limits</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#benchmarking" id="id18">benchmarking</a><ul>
|
||||
<li><a class="reference internal" href="#disk-metrics" id="id19">disk metrics</a></li>
|
||||
<li><a class="reference internal" href="#session-stats" id="id20">session stats</a></li>
|
||||
<li><a class="reference internal" href="#scalability" id="id19">scalability</a></li>
|
||||
<li><a class="reference internal" href="#benchmarking" id="id20">benchmarking</a><ul>
|
||||
<li><a class="reference internal" href="#disk-metrics" id="id21">disk metrics</a></li>
|
||||
<li><a class="reference internal" href="#session-stats" id="id22">session stats</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#contributions" id="id21">contributions</a></li>
|
||||
<li><a class="reference internal" href="#contributions" id="id23">contributions</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="tuning-libtorrent">
|
||||
|
@ -312,6 +314,21 @@ the same pieces, and on the other hand assume that they won't request the same p
|
|||
and drop them when the first peer requests it. To enable volatile read cache, set
|
||||
<tt class="docutils literal"><span class="pre">session_settings::volatile_read_cache</span></tt> to true.</p>
|
||||
</div>
|
||||
<div class="section" id="utp-tcp-mixed-mode">
|
||||
<h2>uTP-TCP mixed mode</h2>
|
||||
<p>libtorrent supports <a class="reference external" href="utp.html">uTP</a>, which has a delay based congestion controller. In order to
|
||||
avoid having a single TCP bittorrent connection completely starve out any uTP connection,
|
||||
there is a mixed mode algorithm. This attempts to detect congestion on the uTP peers and
|
||||
throttle TCP to avoid it taking over all bandwidth. This balances the bandwidth resources
|
||||
between the two protocols. When running on a network where the bandwidth is in such an
|
||||
abundance that it's virtually infinite, this algorithm is no longer necessary, and might
|
||||
even be harmful to throughput. It is adviced to experiment with the
|
||||
<tt class="docutils literal"><span class="pre">session_setting::mixed_mode_algorithm</span></tt>, setting it to <tt class="docutils literal"><span class="pre">session_settings::prefer_tcp</span></tt>.
|
||||
This setting entirely disables the balancing and unthrottles all connections. On a typical
|
||||
home connection, this would mean that none of the benefits of uTP would be preserved
|
||||
(the modem's send buffer would be full at all times) and uTP connections would for the most
|
||||
part be squashed by the TCP traffic.</p>
|
||||
</div>
|
||||
<div class="section" id="send-buffer-low-watermark">
|
||||
<h2>send buffer low watermark</h2>
|
||||
<p>libtorrent uses a low watermark for send buffers to determine when a new piece should
|
||||
|
@ -347,9 +364,37 @@ number via <tt class="docutils literal"><span class="pre">session::set_max_uploa
|
|||
and <tt class="docutils literal"><span class="pre">session_settings::active_seeds</span></tt>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="scalability">
|
||||
<h1>scalability</h1>
|
||||
<p>In order to make more efficient use of the libtorrent interface when running a large
|
||||
number of torrents simultaneously, one can use the <tt class="docutils literal"><span class="pre">session::get_torrent_status()</span></tt> call
|
||||
together with <tt class="docutils literal"><span class="pre">session::refresh_torrent_status()</span></tt>. Keep in mind that every call into
|
||||
libtorrent that return some value have to block your thread while posting a message to
|
||||
the main network thread and then wait for a response (calls that don't return any data
|
||||
will simply post the message and then immediately return). The time this takes might
|
||||
become significant once you reach a few hundred torrents (depending on how many calls
|
||||
you make to each torrent and how often). <tt class="docutils literal"><span class="pre">get_torrent_status</span></tt> lets you query the
|
||||
status of all torrents in a single call. This will actually loop through all torrents
|
||||
and run a provided predicate function to determine whether or not to include it in
|
||||
the returned vector. If you have a lot of torrents, you might want to update the status
|
||||
of only certain torrents. For instance, you might only be interested in torrents that
|
||||
are being downloaded.</p>
|
||||
<p>The intended use of these functions is to start off by calling <tt class="docutils literal"><span class="pre">get_torrent_status</span></tt>
|
||||
to get a list of all torrents that match your criteria. Then call <tt class="docutils literal"><span class="pre">refresh_torrent_status</span></tt>
|
||||
on that list. This will only refresh the status for the torrents in your list, and thus
|
||||
ignore all other torrents you might be running. This may save a significant amount of
|
||||
time, especially if the number of torrents you're interested in is small. In order to
|
||||
keep your list of interested torrents up to date, you can either call <tt class="docutils literal"><span class="pre">get_torrent_status</span></tt>
|
||||
from time to time, to include torrents you might have become interested in since the last
|
||||
time. In order to stop refreshing a certain torrent, simply remove it from the list.</p>
|
||||
<p>A more efficient way however, would be to subscribe to status alert notifications, and
|
||||
update your list based on these alerts. There are alerts for when torrents are added, removed,
|
||||
paused, resumed, completed etc. Doing this ensures that you only query status for the
|
||||
minimal set of torrents you are actually interested in.</p>
|
||||
</div>
|
||||
<div class="section" id="benchmarking">
|
||||
<h1>benchmarking</h1>
|
||||
<p>There are a bunch of built-in instrumentation of libtorrent that can be used to get an insight
|
||||
<p>There is a bunch of built-in instrumentation of libtorrent that can be used to get an insight
|
||||
into what it's doing and how well it performs. This instrumentation is enabled by defining
|
||||
preprocessor symbols when building.</p>
|
||||
<p>There are also a number of scripts that parses the log files and generates graphs (requires
|
||||
|
|
|
@ -343,10 +343,41 @@ torrent limits
|
|||
To seed thousands of torrents, you need to increase the ``session_settings::active_limit``
|
||||
and ``session_settings::active_seeds``.
|
||||
|
||||
scalability
|
||||
===========
|
||||
|
||||
In order to make more efficient use of the libtorrent interface when running a large
|
||||
number of torrents simultaneously, one can use the ``session::get_torrent_status()`` call
|
||||
together with ``session::refresh_torrent_status()``. Keep in mind that every call into
|
||||
libtorrent that return some value have to block your thread while posting a message to
|
||||
the main network thread and then wait for a response (calls that don't return any data
|
||||
will simply post the message and then immediately return). The time this takes might
|
||||
become significant once you reach a few hundred torrents (depending on how many calls
|
||||
you make to each torrent and how often). ``get_torrent_status`` lets you query the
|
||||
status of all torrents in a single call. This will actually loop through all torrents
|
||||
and run a provided predicate function to determine whether or not to include it in
|
||||
the returned vector. If you have a lot of torrents, you might want to update the status
|
||||
of only certain torrents. For instance, you might only be interested in torrents that
|
||||
are being downloaded.
|
||||
|
||||
The intended use of these functions is to start off by calling ``get_torrent_status``
|
||||
to get a list of all torrents that match your criteria. Then call ``refresh_torrent_status``
|
||||
on that list. This will only refresh the status for the torrents in your list, and thus
|
||||
ignore all other torrents you might be running. This may save a significant amount of
|
||||
time, especially if the number of torrents you're interested in is small. In order to
|
||||
keep your list of interested torrents up to date, you can either call ``get_torrent_status``
|
||||
from time to time, to include torrents you might have become interested in since the last
|
||||
time. In order to stop refreshing a certain torrent, simply remove it from the list.
|
||||
|
||||
A more efficient way however, would be to subscribe to status alert notifications, and
|
||||
update your list based on these alerts. There are alerts for when torrents are added, removed,
|
||||
paused, resumed, completed etc. Doing this ensures that you only query status for the
|
||||
minimal set of torrents you are actually interested in.
|
||||
|
||||
benchmarking
|
||||
============
|
||||
|
||||
There are a bunch of built-in instrumentation of libtorrent that can be used to get an insight
|
||||
There is a bunch of built-in instrumentation of libtorrent that can be used to get an insight
|
||||
into what it's doing and how well it performs. This instrumentation is enabled by defining
|
||||
preprocessor symbols when building.
|
||||
|
||||
|
|
|
@ -185,11 +185,15 @@ bool print_fails = false;
|
|||
bool print_send_bufs = true;
|
||||
|
||||
enum {
|
||||
torrents_all = 0,
|
||||
torrents_downloading = 1,
|
||||
torrents_not_paused = 2,
|
||||
torrents_seeding = 3,
|
||||
torrents_paused = 4
|
||||
torrents_all,
|
||||
torrents_downloading,
|
||||
torrents_not_paused,
|
||||
torrents_seeding,
|
||||
torrents_queued,
|
||||
torrents_stopped,
|
||||
torrents_checking,
|
||||
|
||||
torrents_max
|
||||
};
|
||||
|
||||
int torrent_filter = torrents_not_paused;
|
||||
|
@ -201,13 +205,13 @@ struct torrent_entry
|
|||
libtorrent::torrent_status status;
|
||||
};
|
||||
|
||||
typedef std::multimap<std::string, torrent_entry> handles_t;
|
||||
// maps filenames to torrent_handles
|
||||
typedef std::multimap<std::string, libtorrent::torrent_handle> handles_t;
|
||||
|
||||
bool show_torrent(torrent_entry const& te)
|
||||
using libtorrent::torrent_status;
|
||||
|
||||
bool show_torrent(libtorrent::torrent_status const& st, int torrent_filter)
|
||||
{
|
||||
using libtorrent::torrent_status;
|
||||
torrent_status const& st = te.status;
|
||||
|
||||
switch (torrent_filter)
|
||||
{
|
||||
case torrents_all: return true;
|
||||
|
@ -220,11 +224,33 @@ bool show_torrent(torrent_entry const& te)
|
|||
return !st.paused
|
||||
&& (st.state == torrent_status::seeding
|
||||
|| st.state == torrent_status::finished);
|
||||
case torrents_paused: return st.paused;
|
||||
case torrents_queued: return st.paused && st.auto_managed;
|
||||
case torrents_stopped: return st.paused && !st.auto_managed;
|
||||
case torrents_checking: return st.state == torrent_status::checking_files
|
||||
|| st.state == torrent_status::queued_for_checking;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool yes(libtorrent::torrent_status const&)
|
||||
{ return true; }
|
||||
|
||||
bool compare_torrent(torrent_status const& lhs, torrent_status const& rhs)
|
||||
{
|
||||
if (lhs.queue_position != -1 && rhs.queue_position != -1)
|
||||
{
|
||||
// both are downloading, sort by queue pos
|
||||
return lhs.queue_position < rhs.queue_position;
|
||||
}
|
||||
else if (lhs.queue_position == -1 && rhs.queue_position == -1)
|
||||
{
|
||||
// both are seeding, sort by seed-rank
|
||||
return lhs.seed_rank > rhs.seed_rank;
|
||||
}
|
||||
|
||||
return (lhs.queue_position == -1) < (rhs.queue_position == -1);
|
||||
}
|
||||
|
||||
FILE* g_log_file = 0;
|
||||
|
||||
int active_torrent = 0;
|
||||
|
@ -627,8 +653,11 @@ void add_torrent(libtorrent::session& ses
|
|||
return;
|
||||
}
|
||||
|
||||
handles.insert(std::pair<const std::string, torrent_entry>(
|
||||
monitored_dir?std::string(torrent):std::string(), h));
|
||||
if (monitored_dir)
|
||||
{
|
||||
handles.insert(std::pair<const std::string, torrent_handle>(
|
||||
torrent, h));
|
||||
}
|
||||
|
||||
h.set_max_connections(max_connections_per_torrent);
|
||||
h.set_max_uploads(-1);
|
||||
|
@ -643,7 +672,7 @@ void add_torrent(libtorrent::session& ses
|
|||
|
||||
void scan_dir(std::string const& dir_path
|
||||
, libtorrent::session& ses
|
||||
, handles_t& handles
|
||||
, handles_t& files
|
||||
, float preferred_ratio
|
||||
, int allocation_mode
|
||||
, std::string const& save_path
|
||||
|
@ -660,8 +689,8 @@ void scan_dir(std::string const& dir_path
|
|||
std::string file = combine_path(dir_path, i.file());
|
||||
if (extension(file) != ".torrent") continue;
|
||||
|
||||
handles_t::iterator k = handles.find(file);
|
||||
if (k != handles.end())
|
||||
handles_t::iterator k = files.find(file);
|
||||
if (k != files.end())
|
||||
{
|
||||
valid.insert(file);
|
||||
continue;
|
||||
|
@ -669,14 +698,14 @@ void scan_dir(std::string const& dir_path
|
|||
|
||||
// the file has been added to the dir, start
|
||||
// downloading it.
|
||||
add_torrent(ses, handles, file, preferred_ratio, allocation_mode
|
||||
add_torrent(ses, files, file, preferred_ratio, allocation_mode
|
||||
, save_path, true, torrent_upload_limit, torrent_download_limit);
|
||||
valid.insert(file);
|
||||
}
|
||||
|
||||
// remove the torrents that are no longer in the directory
|
||||
|
||||
for (handles_t::iterator i = handles.begin(); !handles.empty() && i != handles.end();)
|
||||
for (handles_t::iterator i = files.begin(); !files.empty() && i != files.end();)
|
||||
{
|
||||
if (i->first.empty() || valid.find(i->first) != valid.end())
|
||||
{
|
||||
|
@ -684,10 +713,10 @@ void scan_dir(std::string const& dir_path
|
|||
continue;
|
||||
}
|
||||
|
||||
torrent_handle& h = i->second.handle;
|
||||
torrent_handle& h = i->second;
|
||||
if (!h.is_valid())
|
||||
{
|
||||
handles.erase(i++);
|
||||
files.erase(i++);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -697,17 +726,17 @@ void scan_dir(std::string const& dir_path
|
|||
// will save it to disk
|
||||
if (h.need_save_resume_data()) h.save_resume_data();
|
||||
|
||||
handles.erase(i++);
|
||||
files.erase(i++);
|
||||
}
|
||||
}
|
||||
|
||||
torrent_entry& get_active_torrent(handles_t const& handles)
|
||||
torrent_status const& get_active_torrent(std::vector<torrent_status> const& torrents)
|
||||
{
|
||||
if (active_torrent >= handles.size()
|
||||
if (active_torrent >= torrents.size()
|
||||
|| active_torrent < 0) active_torrent = 0;
|
||||
handles_t::const_iterator i = handles.begin();
|
||||
std::vector<torrent_status>::const_iterator i = torrents.begin();
|
||||
std::advance(i, active_torrent);
|
||||
return const_cast<torrent_entry&>(i->second);
|
||||
return *i;
|
||||
}
|
||||
|
||||
void print_alert(libtorrent::alert const* a, std::string& str)
|
||||
|
@ -752,7 +781,7 @@ int save_file(std::string const& filename, std::vector<char>& v)
|
|||
}
|
||||
|
||||
void handle_alert(libtorrent::session& ses, libtorrent::alert* a
|
||||
, handles_t const& handles)
|
||||
, handles_t const& files)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
|
@ -775,16 +804,16 @@ void handle_alert(libtorrent::session& ses, libtorrent::alert* a
|
|||
std::vector<char> out;
|
||||
bencode(std::back_inserter(out), *p->resume_data);
|
||||
save_file(combine_path(h.save_path(), ".resume/" + h.name() + ".resume"), out);
|
||||
if (std::find_if(handles.begin(), handles.end()
|
||||
, boost::bind(&torrent_entry::handle, boost::bind(&handles_t::value_type::second, _1)) == h) == handles.end())
|
||||
if (std::find_if(files.begin(), files.end()
|
||||
, boost::bind(&handles_t::value_type::second, _1) == h) == files.end())
|
||||
ses.remove_torrent(h);
|
||||
}
|
||||
}
|
||||
else if (save_resume_data_failed_alert* p = alert_cast<save_resume_data_failed_alert>(a))
|
||||
{
|
||||
torrent_handle h = p->handle;
|
||||
if (std::find_if(handles.begin(), handles.end()
|
||||
, boost::bind(&torrent_entry::handle, boost::bind(&handles_t::value_type::second, _1)) == h) == handles.end())
|
||||
if (std::find_if(files.begin(), files.end()
|
||||
, boost::bind(&handles_t::value_type::second, _1) == h) == files.end())
|
||||
ses.remove_torrent(h);
|
||||
}
|
||||
}
|
||||
|
@ -880,7 +909,9 @@ int main(int argc, char* argv[])
|
|||
// it was added through the directory monitor. It is used to
|
||||
// be able to remove torrents that were added via the directory
|
||||
// monitor when they're not in the directory anymore.
|
||||
handles_t handles;
|
||||
std::vector<torrent_status> handles;
|
||||
handles_t files;
|
||||
|
||||
session ses(fingerprint("LT", LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR, 0, 0)
|
||||
, session::add_default_plugins
|
||||
, alert::all_categories
|
||||
|
@ -1107,8 +1138,6 @@ int main(int argc, char* argv[])
|
|||
continue;
|
||||
}
|
||||
|
||||
handles.insert(std::pair<const std::string, torrent_handle>(std::string(), h));
|
||||
|
||||
h.set_max_connections(max_connections_per_torrent);
|
||||
h.set_max_uploads(-1);
|
||||
h.set_ratio(preferred_ratio);
|
||||
|
@ -1139,8 +1168,6 @@ int main(int argc, char* argv[])
|
|||
continue;
|
||||
}
|
||||
|
||||
handles.insert(std::pair<const std::string, torrent_handle>(std::string(), h));
|
||||
|
||||
h.set_max_connections(max_connections_per_torrent);
|
||||
h.set_max_uploads(-1);
|
||||
h.set_ratio(preferred_ratio);
|
||||
|
@ -1151,7 +1178,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
// if it's a torrent file, open it as usual
|
||||
add_torrent(ses, handles, i->c_str(), preferred_ratio
|
||||
add_torrent(ses, files, i->c_str(), preferred_ratio
|
||||
, allocation_mode, save_path, false
|
||||
, torrent_upload_limit, torrent_download_limit);
|
||||
}
|
||||
|
@ -1162,6 +1189,13 @@ int main(int argc, char* argv[])
|
|||
|
||||
while (loop_limit > 1 || loop_limit == 0)
|
||||
{
|
||||
|
||||
handles.clear();
|
||||
ses.get_torrent_status(&handles, boost::bind(&show_torrent, _1, torrent_filter));
|
||||
if (active_torrent >= handles.size()) active_torrent = handles.size() - 1;
|
||||
|
||||
std::sort(handles.begin(), handles.end(), &compare_torrent);
|
||||
|
||||
if (loop_limit > 1) --loop_limit;
|
||||
char c = 0;
|
||||
while (sleep_and_input(&c, refresh_delay))
|
||||
|
@ -1183,30 +1217,38 @@ int main(int argc, char* argv[])
|
|||
if (c == 68)
|
||||
{
|
||||
// arrow left
|
||||
if (torrent_filter > 0) --torrent_filter;
|
||||
if (torrent_filter > 0)
|
||||
{
|
||||
--torrent_filter;
|
||||
handles.clear();
|
||||
ses.get_torrent_status(&handles, boost::bind(&show_torrent, _1, torrent_filter));
|
||||
if (active_torrent >= handles.size()) active_torrent = handles.size() - 1;
|
||||
std::sort(handles.begin(), handles.end(), &compare_torrent);
|
||||
}
|
||||
}
|
||||
else if (c == 67)
|
||||
{
|
||||
// arrow right
|
||||
if (torrent_filter < torrents_paused) ++torrent_filter;
|
||||
if (torrent_filter < torrents_max - 1)
|
||||
{
|
||||
++torrent_filter;
|
||||
handles.clear();
|
||||
ses.get_torrent_status(&handles, boost::bind(&show_torrent, _1, torrent_filter));
|
||||
if (active_torrent >= handles.size()) active_torrent = handles.size() - 1;
|
||||
std::sort(handles.begin(), handles.end(), &compare_torrent);
|
||||
}
|
||||
}
|
||||
else if (c == 65)
|
||||
{
|
||||
// arrow up
|
||||
int prev = active_torrent;
|
||||
--active_torrent;
|
||||
while (active_torrent > 0 && !show_torrent(get_active_torrent(handles)))
|
||||
--active_torrent;
|
||||
if (active_torrent < 0) active_torrent = prev;
|
||||
if (active_torrent < 0) active_torrent = 0;
|
||||
}
|
||||
else if (c == 66)
|
||||
{
|
||||
// arrow down
|
||||
int prev = active_torrent;
|
||||
++active_torrent;
|
||||
while (active_torrent < handles.size() && !show_torrent(get_active_torrent(handles)))
|
||||
++active_torrent;
|
||||
if (active_torrent >= handles.size()) active_torrent = prev;
|
||||
if (active_torrent >= handles.size()) active_torrent = handles.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1221,11 +1263,12 @@ int main(int argc, char* argv[])
|
|||
printf("saving peers for torrents\n");
|
||||
|
||||
std::vector<peer_list_entry> peers;
|
||||
for (handles_t::iterator i = handles.begin();
|
||||
i != handles.end(); ++i)
|
||||
std::vector<torrent_handle> torrents = ses.get_torrents();
|
||||
for (std::vector<torrent_handle>::iterator i = torrents.begin();
|
||||
i != torrents.end(); ++i)
|
||||
{
|
||||
i->second.handle.get_full_peer_list(peers);
|
||||
FILE* f = fopen(("peers_" + i->second.handle.name()).c_str(), "w+");
|
||||
i->get_full_peer_list(peers);
|
||||
FILE* f = fopen(("peers_" + i->name()).c_str(), "w+");
|
||||
if (!f) break;
|
||||
for (std::vector<peer_list_entry>::iterator k = peers.begin()
|
||||
, end(peers.end()); k != end; ++k)
|
||||
|
@ -1255,59 +1298,59 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (c == 's' && !handles.empty())
|
||||
{
|
||||
torrent_entry& te = get_active_torrent(handles);
|
||||
te.handle.set_sequential_download(!te.status.sequential_download);
|
||||
torrent_status const& ts = get_active_torrent(handles);
|
||||
ts.handle.set_sequential_download(!ts.sequential_download);
|
||||
}
|
||||
|
||||
if (c == 'R')
|
||||
{
|
||||
// save resume data for all torrents
|
||||
for (handles_t::iterator i = handles.begin()
|
||||
for (std::vector<torrent_status>::iterator i = handles.begin()
|
||||
, end(handles.end()); i != end; ++i)
|
||||
{
|
||||
if (i->second.status.need_save_resume)
|
||||
i->second.handle.save_resume_data();
|
||||
if (i->need_save_resume)
|
||||
i->handle.save_resume_data();
|
||||
}
|
||||
}
|
||||
|
||||
if (c == 'o' && !handles.empty())
|
||||
{
|
||||
torrent_entry& te = get_active_torrent(handles);
|
||||
int num_pieces = te.handle.get_torrent_info().num_pieces();
|
||||
torrent_status const& ts = get_active_torrent(handles);
|
||||
int num_pieces = ts.num_pieces;
|
||||
if (num_pieces > 300) num_pieces = 300;
|
||||
for (int i = 0; i < num_pieces; ++i)
|
||||
{
|
||||
te.handle.set_piece_deadline(i, (i+5) * 1000, torrent_handle::alert_when_available);
|
||||
ts.handle.set_piece_deadline(i, (i+5) * 1000, torrent_handle::alert_when_available);
|
||||
}
|
||||
}
|
||||
|
||||
if (c == 'v' && !handles.empty())
|
||||
{
|
||||
torrent_entry& te = get_active_torrent(handles);
|
||||
te.handle.scrape_tracker();
|
||||
torrent_status const& ts = get_active_torrent(handles);
|
||||
ts.handle.scrape_tracker();
|
||||
}
|
||||
|
||||
if (c == 'p' && !handles.empty())
|
||||
{
|
||||
torrent_entry& te = get_active_torrent(handles);
|
||||
if (!te.status.auto_managed && te.status.paused)
|
||||
torrent_status const& ts = get_active_torrent(handles);
|
||||
if (!ts.auto_managed && ts.paused)
|
||||
{
|
||||
te.handle.auto_managed(true);
|
||||
ts.handle.auto_managed(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
te.handle.auto_managed(false);
|
||||
te.handle.pause(torrent_handle::graceful_pause);
|
||||
ts.handle.auto_managed(false);
|
||||
ts.handle.pause(torrent_handle::graceful_pause);
|
||||
}
|
||||
// the alert handler for save_resume_data_alert
|
||||
// will save it to disk
|
||||
if (te.status.need_save_resume) te.handle.save_resume_data();
|
||||
if (ts.need_save_resume) ts.handle.save_resume_data();
|
||||
}
|
||||
|
||||
if (c == 'c' && !handles.empty())
|
||||
{
|
||||
torrent_entry& te = get_active_torrent(handles);
|
||||
te.handle.clear_error();
|
||||
torrent_status const& ts = get_active_torrent(handles);
|
||||
ts.handle.clear_error();
|
||||
}
|
||||
|
||||
// toggle displays
|
||||
|
@ -1332,15 +1375,19 @@ int main(int argc, char* argv[])
|
|||
if (c == 'q') break;
|
||||
|
||||
int terminal_width = 80;
|
||||
int terminal_height = 50;
|
||||
|
||||
#ifndef _WIN32
|
||||
{
|
||||
winsize size;
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, (char*)&size);
|
||||
terminal_width = size.ws_col;
|
||||
terminal_height = size.ws_row;
|
||||
|
||||
if (terminal_width < 64)
|
||||
terminal_width = 64;
|
||||
if (terminal_height < 25)
|
||||
terminal_height = 25;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1353,7 +1400,7 @@ int main(int argc, char* argv[])
|
|||
std::string event_string;
|
||||
|
||||
::print_alert(a.get(), event_string);
|
||||
::handle_alert(ses, a.get(), handles);
|
||||
::handle_alert(ses, a.get(), files);
|
||||
|
||||
events.push_back(event_string);
|
||||
if (events.size() >= 20) events.pop_front();
|
||||
|
@ -1370,7 +1417,7 @@ int main(int argc, char* argv[])
|
|||
"[1] toggle IP [2] toggle AS [3] toggle timers [4] toggle block progress "
|
||||
"[5] toggle peer rate [6] toggle failures [7] toggle send buffers [R] save resume data\n";
|
||||
|
||||
char const* filter_names[] = { "all", "downloading", "non-paused", "seeding", "paused"};
|
||||
char const* filter_names[] = { "all", "downloading", "non-paused", "seeding", "queued", "stopped", "checking"};
|
||||
for (int i = 0; i < sizeof(filter_names)/sizeof(filter_names[0]); ++i)
|
||||
{
|
||||
out += '[';
|
||||
|
@ -1383,12 +1430,18 @@ int main(int argc, char* argv[])
|
|||
|
||||
char str[500];
|
||||
int torrent_index = 0;
|
||||
torrent_handle active_handle;
|
||||
for (handles_t::iterator i = handles.begin();
|
||||
int lines_printed = 3;
|
||||
for (std::vector<torrent_status>::iterator i = handles.begin();
|
||||
i != handles.end(); ++torrent_index)
|
||||
{
|
||||
torrent_entry& te = i->second;
|
||||
if (!te.handle.is_valid())
|
||||
if (lines_printed >= terminal_height - 15)
|
||||
{
|
||||
out += "...\n";
|
||||
break;
|
||||
}
|
||||
|
||||
torrent_status& s = *i;
|
||||
if (!s.handle.is_valid())
|
||||
{
|
||||
handles.erase(i++);
|
||||
continue;
|
||||
|
@ -1398,12 +1451,6 @@ int main(int argc, char* argv[])
|
|||
++i;
|
||||
}
|
||||
|
||||
te.status = te.handle.status();
|
||||
torrent_status const& s = te.status;
|
||||
|
||||
if (!show_torrent(te))
|
||||
continue;
|
||||
|
||||
#ifdef ANSI_TERMINAL_COLORS
|
||||
char const* term = "\x1b[0m";
|
||||
#else
|
||||
|
@ -1420,7 +1467,7 @@ int main(int argc, char* argv[])
|
|||
out += " ";
|
||||
}
|
||||
|
||||
int queue_pos = te.status.queue_position;
|
||||
int queue_pos = s.queue_position;
|
||||
if (queue_pos == -1) out += "- ";
|
||||
else
|
||||
{
|
||||
|
@ -1431,7 +1478,7 @@ int main(int argc, char* argv[])
|
|||
if (s.paused) out += esc("34");
|
||||
else out += esc("37");
|
||||
|
||||
std::string name = te.handle.name();
|
||||
std::string name = s.handle.name();
|
||||
if (name.size() > 40) name.resize(40);
|
||||
snprintf(str, sizeof(str), "%-40s %s ", name.c_str(), term);
|
||||
out += str;
|
||||
|
@ -1443,6 +1490,7 @@ int main(int argc, char* argv[])
|
|||
out += s.error;
|
||||
out += esc("0");
|
||||
out += "\n";
|
||||
++lines_printed;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1467,8 +1515,9 @@ int main(int argc, char* argv[])
|
|||
, s.up_bandwidth_queue, s.down_bandwidth_queue
|
||||
, esc("32"), add_suffix(s.all_time_download).c_str(), term
|
||||
, esc("31"), add_suffix(s.all_time_upload).c_str(), term
|
||||
, s.seed_rank, te.status.need_save_resume?'S':' ', esc("0"));
|
||||
, s.seed_rank, s.need_save_resume?'S':' ', esc("0"));
|
||||
out += str;
|
||||
++lines_printed;
|
||||
|
||||
if (torrent_index != active_torrent && s.state == torrent_status::seeding) continue;
|
||||
char const* progress_bar_color = "33"; // yellow
|
||||
|
@ -1499,12 +1548,14 @@ int main(int argc, char* argv[])
|
|||
, progress_bar(s.progress_ppm / 1000, terminal_width - 43 - 20, "35").c_str());
|
||||
out += str;
|
||||
}
|
||||
++lines_printed;
|
||||
|
||||
if (print_piece_bar && s.state != torrent_status::seeding)
|
||||
{
|
||||
out += " ";
|
||||
out += piece_bar(s.pieces, terminal_width - 7);
|
||||
out += "\n";
|
||||
++lines_printed;
|
||||
}
|
||||
|
||||
if (s.state != torrent_status::queued_for_checking && s.state != torrent_status::checking_files)
|
||||
|
@ -1523,10 +1574,8 @@ int main(int argc, char* argv[])
|
|||
, esc("37"), t.hours(), t.minutes(), t.seconds(), esc("0")
|
||||
, esc("36"), s.current_tracker.c_str(), esc("0"));
|
||||
out += str;
|
||||
++lines_printed;
|
||||
}
|
||||
|
||||
if (torrent_index != active_torrent) continue;
|
||||
active_handle = te.handle;
|
||||
}
|
||||
|
||||
cache_status cs = ses.get_cache_status();
|
||||
|
@ -1624,10 +1673,12 @@ int main(int argc, char* argv[])
|
|||
out += str;
|
||||
}
|
||||
|
||||
if (active_handle.is_valid())
|
||||
torrent_status const* st = 0;
|
||||
if (!handles.empty()) st = &get_active_torrent(handles);
|
||||
if (st && st->handle.is_valid())
|
||||
{
|
||||
torrent_handle h = active_handle;
|
||||
torrent_status s = h.status();
|
||||
torrent_handle h = st->handle;
|
||||
torrent_status const& s = *st;
|
||||
|
||||
if ((print_downloads && s.state != torrent_status::seeding)
|
||||
|| print_peers)
|
||||
|
@ -1804,7 +1855,7 @@ int main(int argc, char* argv[])
|
|||
if (!monitor_dir.empty()
|
||||
&& next_dir_scan < time_now())
|
||||
{
|
||||
scan_dir(monitor_dir, ses, handles, preferred_ratio
|
||||
scan_dir(monitor_dir, ses, files, preferred_ratio
|
||||
, allocation_mode, save_path, torrent_upload_limit
|
||||
, torrent_download_limit);
|
||||
next_dir_scan = time_now() + seconds(poll_interval);
|
||||
|
@ -1819,17 +1870,18 @@ int main(int argc, char* argv[])
|
|||
|
||||
ses.pause();
|
||||
printf("saving resume data\n");
|
||||
for (handles_t::iterator i = handles.begin();
|
||||
i != handles.end(); ++i)
|
||||
std::vector<torrent_status> temp;
|
||||
ses.get_torrent_status(&temp, &yes, 0);
|
||||
for (std::vector<torrent_status>::iterator i = temp.begin();
|
||||
i != temp.end(); ++i)
|
||||
{
|
||||
torrent_entry& te = i->second;
|
||||
if (!te.handle.is_valid()) continue;
|
||||
te.status = te.handle.status();
|
||||
if (te.status.paused) continue;
|
||||
if (!te.status.has_metadata) continue;
|
||||
torrent_status& st = *i;
|
||||
if (!st.handle.is_valid()) continue;
|
||||
if (st.paused) continue;
|
||||
if (!st.has_metadata) continue;
|
||||
|
||||
// save_resume_data will generate an alert when it's done
|
||||
te.handle.save_resume_data();
|
||||
st.handle.save_resume_data();
|
||||
++num_resume_data;
|
||||
printf("\r%d ", num_resume_data);
|
||||
}
|
||||
|
|
|
@ -274,7 +274,13 @@ namespace libtorrent
|
|||
|
||||
void remove_torrent(torrent_handle const& h, int options);
|
||||
|
||||
std::vector<torrent_handle> get_torrents();
|
||||
void get_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::function<bool(torrent_status const&)> const& pred
|
||||
, boost::uint32_t flags) const;
|
||||
void refresh_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::uint32_t flags) const;
|
||||
|
||||
std::vector<torrent_handle> get_torrents() const;
|
||||
|
||||
void queue_check_torrent(boost::shared_ptr<torrent> const& t);
|
||||
void dequeue_check_torrent(boost::shared_ptr<torrent> const& t);
|
||||
|
|
|
@ -176,6 +176,12 @@ namespace libtorrent
|
|||
void save_state(entry& e, boost::uint32_t flags = 0xffffffff) const;
|
||||
void load_state(lazy_entry const& e);
|
||||
|
||||
void get_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::function<bool(torrent_status const&)> const& pred
|
||||
, boost::uint32_t flags = 0) const;
|
||||
void refresh_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::uint32_t flags = 0) const;
|
||||
|
||||
// returns a list of all torrents in this session
|
||||
std::vector<torrent_handle> get_torrents() const;
|
||||
|
||||
|
|
|
@ -300,7 +300,7 @@ namespace libtorrent
|
|||
void set_piece_deadline(int piece, int t, int flags);
|
||||
void update_piece_priorities();
|
||||
|
||||
torrent_status status(boost::uint32_t flags) const;
|
||||
void status(torrent_status* st, boost::uint32_t flags);
|
||||
|
||||
void file_progress(std::vector<size_type>& fp, int flags = 0) const;
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ namespace libtorrent
|
|||
struct torrent_plugin;
|
||||
struct peer_info;
|
||||
struct peer_list_entry;
|
||||
struct torrent_status;
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
// for compatibility with 0.14
|
||||
|
@ -77,273 +78,6 @@ namespace libtorrent
|
|||
void throw_invalid_handle();
|
||||
#endif
|
||||
|
||||
struct TORRENT_EXPORT torrent_status
|
||||
{
|
||||
torrent_status()
|
||||
: state(checking_resume_data)
|
||||
, paused(false)
|
||||
, auto_managed(false)
|
||||
, sequential_download(false)
|
||||
, is_seeding(false)
|
||||
, is_finished(false)
|
||||
, has_metadata(false)
|
||||
, progress(0.f)
|
||||
, progress_ppm(0)
|
||||
, total_download(0)
|
||||
, total_upload(0)
|
||||
, total_payload_download(0)
|
||||
, total_payload_upload(0)
|
||||
, total_failed_bytes(0)
|
||||
, total_redundant_bytes(0)
|
||||
, download_rate(0)
|
||||
, upload_rate(0)
|
||||
, download_payload_rate(0)
|
||||
, upload_payload_rate(0)
|
||||
, num_seeds(0)
|
||||
, num_peers(0)
|
||||
, num_complete(-1)
|
||||
, num_incomplete(-1)
|
||||
, list_seeds(0)
|
||||
, list_peers(0)
|
||||
, num_pieces(0)
|
||||
, total_done(0)
|
||||
, total_wanted_done(0)
|
||||
, total_wanted(0)
|
||||
, distributed_copies(0.f)
|
||||
, block_size(0)
|
||||
, num_uploads(0)
|
||||
, num_connections(0)
|
||||
, uploads_limit(0)
|
||||
, connections_limit(0)
|
||||
, storage_mode(storage_mode_sparse)
|
||||
, up_bandwidth_queue(0)
|
||||
, down_bandwidth_queue(0)
|
||||
, all_time_upload(0)
|
||||
, all_time_download(0)
|
||||
, active_time(0)
|
||||
, finished_time(0)
|
||||
, seeding_time(0)
|
||||
, seed_rank(0)
|
||||
, last_scrape(0)
|
||||
, has_incoming(false)
|
||||
, sparse_regions(0)
|
||||
, seed_mode(false)
|
||||
, upload_mode(false)
|
||||
, share_mode(false)
|
||||
, priority(0)
|
||||
, added_time(0)
|
||||
, completed_time(0)
|
||||
, last_seen_complete(0)
|
||||
, time_since_upload(0)
|
||||
, time_since_download(0)
|
||||
, queue_position(0)
|
||||
{}
|
||||
|
||||
enum state_t
|
||||
{
|
||||
queued_for_checking,
|
||||
checking_files,
|
||||
downloading_metadata,
|
||||
downloading,
|
||||
finished,
|
||||
seeding,
|
||||
allocating,
|
||||
checking_resume_data
|
||||
};
|
||||
|
||||
state_t state;
|
||||
bool paused;
|
||||
bool auto_managed;
|
||||
bool sequential_download;
|
||||
bool is_seeding;
|
||||
bool is_finished;
|
||||
bool has_metadata;
|
||||
|
||||
float progress;
|
||||
// progress parts per million (progress * 1000000)
|
||||
// when disabling floating point operations, this is
|
||||
// the only option to query progress
|
||||
int progress_ppm;
|
||||
std::string error;
|
||||
|
||||
boost::posix_time::time_duration next_announce;
|
||||
boost::posix_time::time_duration announce_interval;
|
||||
|
||||
std::string current_tracker;
|
||||
|
||||
// transferred this session!
|
||||
// total, payload plus protocol
|
||||
size_type total_download;
|
||||
size_type total_upload;
|
||||
|
||||
// payload only
|
||||
size_type total_payload_download;
|
||||
size_type total_payload_upload;
|
||||
|
||||
// the amount of payload bytes that
|
||||
// has failed their hash test
|
||||
size_type total_failed_bytes;
|
||||
|
||||
// the number of payload bytes that
|
||||
// has been received redundantly.
|
||||
size_type total_redundant_bytes;
|
||||
|
||||
// current transfer rate
|
||||
// payload plus protocol
|
||||
int download_rate;
|
||||
int upload_rate;
|
||||
|
||||
// the rate of payload that is
|
||||
// sent and received
|
||||
int download_payload_rate;
|
||||
int upload_payload_rate;
|
||||
|
||||
// the number of peers this torrent is connected to
|
||||
// that are seeding.
|
||||
int num_seeds;
|
||||
|
||||
// the number of peers this torrent
|
||||
// is connected to (including seeds).
|
||||
int num_peers;
|
||||
|
||||
// if the tracker sends scrape info in its
|
||||
// announce reply, these fields will be
|
||||
// set to the total number of peers that
|
||||
// have the whole file and the total number
|
||||
// of peers that are still downloading
|
||||
int num_complete;
|
||||
int num_incomplete;
|
||||
|
||||
// this is the number of seeds whose IP we know
|
||||
// but are not necessarily connected to
|
||||
int list_seeds;
|
||||
|
||||
// this is the number of peers whose IP we know
|
||||
// (including seeds), but are not necessarily
|
||||
// connected to
|
||||
int list_peers;
|
||||
|
||||
// the number of peers in our peerlist that
|
||||
// we potentially could connect to
|
||||
int connect_candidates;
|
||||
|
||||
bitfield pieces;
|
||||
|
||||
// this is the number of pieces the client has
|
||||
// downloaded. it is equal to:
|
||||
// std::accumulate(pieces->begin(), pieces->end());
|
||||
int num_pieces;
|
||||
|
||||
// the number of bytes of the file we have
|
||||
// including pieces that may have been filtered
|
||||
// after we downloaded them
|
||||
size_type total_done;
|
||||
|
||||
// the number of bytes we have of those that we
|
||||
// want. i.e. not counting bytes from pieces that
|
||||
// are filtered as not wanted.
|
||||
size_type total_wanted_done;
|
||||
|
||||
// the total number of bytes we want to download
|
||||
// this may be smaller than the total torrent size
|
||||
// in case any pieces are filtered as not wanted
|
||||
size_type total_wanted;
|
||||
|
||||
// the number of distributed copies of the file.
|
||||
// note that one copy may be spread out among many peers.
|
||||
//
|
||||
// the integer part tells how many copies
|
||||
// there are of the rarest piece(s)
|
||||
//
|
||||
// the fractional part tells the fraction of pieces that
|
||||
// have more copies than the rarest piece(s).
|
||||
|
||||
// the number of full distributed copies (i.e. the number
|
||||
// of peers that have the rarest piece)
|
||||
int distributed_full_copies;
|
||||
|
||||
// the fraction of pieces that more peers has than the
|
||||
// rarest pieces. This indicates how close the swarm is
|
||||
// to have one more full distributed copy
|
||||
int distributed_fraction;
|
||||
|
||||
float distributed_copies;
|
||||
|
||||
// the block size that is used in this torrent. i.e.
|
||||
// the number of bytes each piece request asks for
|
||||
// and each bit in the download queue bitfield represents
|
||||
int block_size;
|
||||
|
||||
int num_uploads;
|
||||
int num_connections;
|
||||
int uploads_limit;
|
||||
int connections_limit;
|
||||
|
||||
// true if the torrent is saved in compact mode
|
||||
// false if it is saved in full allocation mode
|
||||
storage_mode_t storage_mode;
|
||||
|
||||
int up_bandwidth_queue;
|
||||
int down_bandwidth_queue;
|
||||
|
||||
// number of bytes downloaded since torrent was started
|
||||
// saved and restored from resume data
|
||||
size_type all_time_upload;
|
||||
size_type all_time_download;
|
||||
|
||||
// the number of seconds of being active
|
||||
// and as being a seed, saved and restored
|
||||
// from resume data
|
||||
int active_time;
|
||||
int finished_time;
|
||||
int seeding_time;
|
||||
|
||||
// higher value means more important to seed
|
||||
int seed_rank;
|
||||
|
||||
// number of seconds since last scrape, or -1 if
|
||||
// there hasn't been a scrape
|
||||
int last_scrape;
|
||||
|
||||
// true if there are incoming connections to this
|
||||
// torrent
|
||||
bool has_incoming;
|
||||
|
||||
// the number of "holes" in the torrent
|
||||
int sparse_regions;
|
||||
|
||||
// is true if this torrent is (still) in seed_mode
|
||||
bool seed_mode;
|
||||
|
||||
// this is set to true when the torrent is blocked
|
||||
// from downloading, typically caused by a file
|
||||
// write operation failing
|
||||
bool upload_mode;
|
||||
|
||||
// this is true if the torrent is in share-mode
|
||||
bool share_mode;
|
||||
|
||||
// the priority of this torrent
|
||||
int priority;
|
||||
|
||||
// the time this torrent was added and completed
|
||||
time_t added_time;
|
||||
time_t completed_time;
|
||||
time_t last_seen_complete;
|
||||
|
||||
// number of seconds since last upload or download activity
|
||||
int time_since_upload;
|
||||
int time_since_download;
|
||||
|
||||
// the position in the download queue where this torrent is
|
||||
// this is -1 for seeds and finished torrents
|
||||
int queue_position;
|
||||
|
||||
// true if this torrent has had changes since the last
|
||||
// time resume data was saved
|
||||
bool need_save_resume;
|
||||
};
|
||||
|
||||
struct TORRENT_EXPORT block_info
|
||||
{
|
||||
enum block_state_t
|
||||
|
@ -677,6 +411,275 @@ namespace libtorrent
|
|||
|
||||
};
|
||||
|
||||
struct TORRENT_EXPORT torrent_status
|
||||
{
|
||||
torrent_status()
|
||||
: state(checking_resume_data)
|
||||
, paused(false)
|
||||
, auto_managed(false)
|
||||
, sequential_download(false)
|
||||
, is_seeding(false)
|
||||
, is_finished(false)
|
||||
, has_metadata(false)
|
||||
, progress(0.f)
|
||||
, progress_ppm(0)
|
||||
, total_download(0)
|
||||
, total_upload(0)
|
||||
, total_payload_download(0)
|
||||
, total_payload_upload(0)
|
||||
, total_failed_bytes(0)
|
||||
, total_redundant_bytes(0)
|
||||
, download_rate(0)
|
||||
, upload_rate(0)
|
||||
, download_payload_rate(0)
|
||||
, upload_payload_rate(0)
|
||||
, num_seeds(0)
|
||||
, num_peers(0)
|
||||
, num_complete(-1)
|
||||
, num_incomplete(-1)
|
||||
, list_seeds(0)
|
||||
, list_peers(0)
|
||||
, num_pieces(0)
|
||||
, total_done(0)
|
||||
, total_wanted_done(0)
|
||||
, total_wanted(0)
|
||||
, distributed_copies(0.f)
|
||||
, block_size(0)
|
||||
, num_uploads(0)
|
||||
, num_connections(0)
|
||||
, uploads_limit(0)
|
||||
, connections_limit(0)
|
||||
, storage_mode(storage_mode_sparse)
|
||||
, up_bandwidth_queue(0)
|
||||
, down_bandwidth_queue(0)
|
||||
, all_time_upload(0)
|
||||
, all_time_download(0)
|
||||
, active_time(0)
|
||||
, finished_time(0)
|
||||
, seeding_time(0)
|
||||
, seed_rank(0)
|
||||
, last_scrape(0)
|
||||
, has_incoming(false)
|
||||
, sparse_regions(0)
|
||||
, seed_mode(false)
|
||||
, upload_mode(false)
|
||||
, share_mode(false)
|
||||
, priority(0)
|
||||
, added_time(0)
|
||||
, completed_time(0)
|
||||
, last_seen_complete(0)
|
||||
, time_since_upload(0)
|
||||
, time_since_download(0)
|
||||
, queue_position(0)
|
||||
{}
|
||||
|
||||
// handle to the torrent
|
||||
torrent_handle handle;
|
||||
|
||||
enum state_t
|
||||
{
|
||||
queued_for_checking,
|
||||
checking_files,
|
||||
downloading_metadata,
|
||||
downloading,
|
||||
finished,
|
||||
seeding,
|
||||
allocating,
|
||||
checking_resume_data
|
||||
};
|
||||
|
||||
state_t state;
|
||||
bool paused;
|
||||
bool auto_managed;
|
||||
bool sequential_download;
|
||||
bool is_seeding;
|
||||
bool is_finished;
|
||||
bool has_metadata;
|
||||
|
||||
float progress;
|
||||
// progress parts per million (progress * 1000000)
|
||||
// when disabling floating point operations, this is
|
||||
// the only option to query progress
|
||||
int progress_ppm;
|
||||
std::string error;
|
||||
|
||||
boost::posix_time::time_duration next_announce;
|
||||
boost::posix_time::time_duration announce_interval;
|
||||
|
||||
std::string current_tracker;
|
||||
|
||||
// transferred this session!
|
||||
// total, payload plus protocol
|
||||
size_type total_download;
|
||||
size_type total_upload;
|
||||
|
||||
// payload only
|
||||
size_type total_payload_download;
|
||||
size_type total_payload_upload;
|
||||
|
||||
// the amount of payload bytes that
|
||||
// has failed their hash test
|
||||
size_type total_failed_bytes;
|
||||
|
||||
// the number of payload bytes that
|
||||
// has been received redundantly.
|
||||
size_type total_redundant_bytes;
|
||||
|
||||
// current transfer rate
|
||||
// payload plus protocol
|
||||
int download_rate;
|
||||
int upload_rate;
|
||||
|
||||
// the rate of payload that is
|
||||
// sent and received
|
||||
int download_payload_rate;
|
||||
int upload_payload_rate;
|
||||
|
||||
// the number of peers this torrent is connected to
|
||||
// that are seeding.
|
||||
int num_seeds;
|
||||
|
||||
// the number of peers this torrent
|
||||
// is connected to (including seeds).
|
||||
int num_peers;
|
||||
|
||||
// if the tracker sends scrape info in its
|
||||
// announce reply, these fields will be
|
||||
// set to the total number of peers that
|
||||
// have the whole file and the total number
|
||||
// of peers that are still downloading
|
||||
int num_complete;
|
||||
int num_incomplete;
|
||||
|
||||
// this is the number of seeds whose IP we know
|
||||
// but are not necessarily connected to
|
||||
int list_seeds;
|
||||
|
||||
// this is the number of peers whose IP we know
|
||||
// (including seeds), but are not necessarily
|
||||
// connected to
|
||||
int list_peers;
|
||||
|
||||
// the number of peers in our peerlist that
|
||||
// we potentially could connect to
|
||||
int connect_candidates;
|
||||
|
||||
bitfield pieces;
|
||||
|
||||
// this is the number of pieces the client has
|
||||
// downloaded. it is equal to:
|
||||
// std::accumulate(pieces->begin(), pieces->end());
|
||||
int num_pieces;
|
||||
|
||||
// the number of bytes of the file we have
|
||||
// including pieces that may have been filtered
|
||||
// after we downloaded them
|
||||
size_type total_done;
|
||||
|
||||
// the number of bytes we have of those that we
|
||||
// want. i.e. not counting bytes from pieces that
|
||||
// are filtered as not wanted.
|
||||
size_type total_wanted_done;
|
||||
|
||||
// the total number of bytes we want to download
|
||||
// this may be smaller than the total torrent size
|
||||
// in case any pieces are filtered as not wanted
|
||||
size_type total_wanted;
|
||||
|
||||
// the number of distributed copies of the file.
|
||||
// note that one copy may be spread out among many peers.
|
||||
//
|
||||
// the integer part tells how many copies
|
||||
// there are of the rarest piece(s)
|
||||
//
|
||||
// the fractional part tells the fraction of pieces that
|
||||
// have more copies than the rarest piece(s).
|
||||
|
||||
// the number of full distributed copies (i.e. the number
|
||||
// of peers that have the rarest piece)
|
||||
int distributed_full_copies;
|
||||
|
||||
// the fraction of pieces that more peers has than the
|
||||
// rarest pieces. This indicates how close the swarm is
|
||||
// to have one more full distributed copy
|
||||
int distributed_fraction;
|
||||
|
||||
float distributed_copies;
|
||||
|
||||
// the block size that is used in this torrent. i.e.
|
||||
// the number of bytes each piece request asks for
|
||||
// and each bit in the download queue bitfield represents
|
||||
int block_size;
|
||||
|
||||
int num_uploads;
|
||||
int num_connections;
|
||||
int uploads_limit;
|
||||
int connections_limit;
|
||||
|
||||
// true if the torrent is saved in compact mode
|
||||
// false if it is saved in full allocation mode
|
||||
storage_mode_t storage_mode;
|
||||
|
||||
int up_bandwidth_queue;
|
||||
int down_bandwidth_queue;
|
||||
|
||||
// number of bytes downloaded since torrent was started
|
||||
// saved and restored from resume data
|
||||
size_type all_time_upload;
|
||||
size_type all_time_download;
|
||||
|
||||
// the number of seconds of being active
|
||||
// and as being a seed, saved and restored
|
||||
// from resume data
|
||||
int active_time;
|
||||
int finished_time;
|
||||
int seeding_time;
|
||||
|
||||
// higher value means more important to seed
|
||||
int seed_rank;
|
||||
|
||||
// number of seconds since last scrape, or -1 if
|
||||
// there hasn't been a scrape
|
||||
int last_scrape;
|
||||
|
||||
// true if there are incoming connections to this
|
||||
// torrent
|
||||
bool has_incoming;
|
||||
|
||||
// the number of "holes" in the torrent
|
||||
int sparse_regions;
|
||||
|
||||
// is true if this torrent is (still) in seed_mode
|
||||
bool seed_mode;
|
||||
|
||||
// this is set to true when the torrent is blocked
|
||||
// from downloading, typically caused by a file
|
||||
// write operation failing
|
||||
bool upload_mode;
|
||||
|
||||
// this is true if the torrent is in share-mode
|
||||
bool share_mode;
|
||||
|
||||
// the priority of this torrent
|
||||
int priority;
|
||||
|
||||
// the time this torrent was added and completed
|
||||
time_t added_time;
|
||||
time_t completed_time;
|
||||
time_t last_seen_complete;
|
||||
|
||||
// number of seconds since last upload or download activity
|
||||
int time_since_upload;
|
||||
int time_since_download;
|
||||
|
||||
// the position in the download queue where this torrent is
|
||||
// this is -1 for seeds and finished torrents
|
||||
int queue_position;
|
||||
|
||||
// true if this torrent has had changes since the last
|
||||
// time resume data was saved
|
||||
bool need_save_resume;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -300,6 +300,12 @@ namespace libtorrent
|
|||
m_impl->m_io_service.post(boost::bind(&fun_wrap, &done, &m_impl->cond, &m_impl->mut, boost::function<void(void)>(boost::bind(&session_impl:: x, m_impl.get(), a1, a2)))); \
|
||||
do { m_impl->cond.wait(l); } while(!done)
|
||||
|
||||
#define TORRENT_SYNC_CALL3(x, a1, a2, a3) \
|
||||
bool done = false; \
|
||||
mutex::scoped_lock l(m_impl->mut); \
|
||||
m_impl->m_io_service.post(boost::bind(&fun_wrap, &done, &m_impl->cond, &m_impl->mut, boost::function<void(void)>(boost::bind(&session_impl:: x, m_impl.get(), a1, a2, a3)))); \
|
||||
do { m_impl->cond.wait(l); } while(!done)
|
||||
|
||||
#define TORRENT_SYNC_CALL_RET(type, x) \
|
||||
bool done = false; \
|
||||
type r; \
|
||||
|
@ -509,6 +515,19 @@ namespace libtorrent
|
|||
TORRENT_ASYNC_CALL1(set_key, key);
|
||||
}
|
||||
|
||||
void session::get_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::function<bool(torrent_status const&)> const& pred
|
||||
, boost::uint32_t flags) const
|
||||
{
|
||||
TORRENT_SYNC_CALL3(get_torrent_status, ret, boost::ref(pred), flags);
|
||||
}
|
||||
|
||||
void session::refresh_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::uint32_t flags) const
|
||||
{
|
||||
TORRENT_SYNC_CALL2(refresh_torrent_status, ret, flags);
|
||||
}
|
||||
|
||||
std::vector<torrent_handle> session::get_torrents() const
|
||||
{
|
||||
TORRENT_SYNC_CALL_RET(std::vector<torrent_handle>, get_torrents);
|
||||
|
|
|
@ -3592,11 +3592,39 @@ namespace aux {
|
|||
}
|
||||
#endif
|
||||
|
||||
std::vector<torrent_handle> session_impl::get_torrents()
|
||||
void session_impl::get_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::function<bool(torrent_status const&)> const& pred
|
||||
, boost::uint32_t flags) const
|
||||
{
|
||||
for (session_impl::torrent_map::const_iterator i
|
||||
= m_torrents.begin(), end(m_torrents.end());
|
||||
i != end; ++i)
|
||||
{
|
||||
if (i->second->is_aborted()) continue;
|
||||
torrent_status st;
|
||||
i->second->status(&st, flags);
|
||||
if (!pred(st)) continue;
|
||||
ret->push_back(st);
|
||||
}
|
||||
}
|
||||
|
||||
void session_impl::refresh_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::uint32_t flags) const
|
||||
{
|
||||
for (std::vector<torrent_status>::iterator i
|
||||
= ret->begin(), end(ret->end()); i != end; ++i)
|
||||
{
|
||||
boost::shared_ptr<torrent> t = i->handle.m_torrent.lock();
|
||||
if (!t) continue;
|
||||
t->status(&*i, flags);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<torrent_handle> session_impl::get_torrents() const
|
||||
{
|
||||
std::vector<torrent_handle> ret;
|
||||
|
||||
for (session_impl::torrent_map::iterator i
|
||||
for (session_impl::torrent_map::const_iterator i
|
||||
= m_torrents.begin(), end(m_torrents.end());
|
||||
i != end; ++i)
|
||||
{
|
||||
|
|
181
src/torrent.cpp
181
src/torrent.cpp
|
@ -7139,96 +7139,96 @@ namespace libtorrent
|
|||
#endif
|
||||
}
|
||||
|
||||
torrent_status torrent::status(boost::uint32_t flags) const
|
||||
void torrent::status(torrent_status* st, boost::uint32_t flags)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
ptime now = time_now();
|
||||
|
||||
torrent_status st;
|
||||
st->handle = get_handle();
|
||||
|
||||
st.has_incoming = m_has_incoming;
|
||||
if (m_error) st.error = m_error.message() + ": " + m_error_file;
|
||||
st.seed_mode = m_seed_mode;
|
||||
st->has_incoming = m_has_incoming;
|
||||
if (m_error) st->error = m_error.message() + ": " + m_error_file;
|
||||
st->seed_mode = m_seed_mode;
|
||||
|
||||
st.added_time = m_added_time;
|
||||
st.completed_time = m_completed_time;
|
||||
st->added_time = m_added_time;
|
||||
st->completed_time = m_completed_time;
|
||||
|
||||
st.last_scrape = m_last_scrape;
|
||||
st.share_mode = m_share_mode;
|
||||
st.upload_mode = m_upload_mode;
|
||||
st.up_bandwidth_queue = 0;
|
||||
st.down_bandwidth_queue = 0;
|
||||
st.priority = m_priority;
|
||||
st->last_scrape = m_last_scrape;
|
||||
st->share_mode = m_share_mode;
|
||||
st->upload_mode = m_upload_mode;
|
||||
st->up_bandwidth_queue = 0;
|
||||
st->down_bandwidth_queue = 0;
|
||||
st->priority = m_priority;
|
||||
|
||||
st.num_peers = (int)std::count_if(m_connections.begin(), m_connections.end()
|
||||
st->num_peers = (int)std::count_if(m_connections.begin(), m_connections.end()
|
||||
, !boost::bind(&peer_connection::is_connecting, _1));
|
||||
|
||||
st.list_peers = m_policy.num_peers();
|
||||
st.list_seeds = m_policy.num_seeds();
|
||||
st.connect_candidates = m_policy.num_connect_candidates();
|
||||
st.seed_rank = seed_rank(settings());
|
||||
st->list_peers = m_policy.num_peers();
|
||||
st->list_seeds = m_policy.num_seeds();
|
||||
st->connect_candidates = m_policy.num_connect_candidates();
|
||||
st->seed_rank = seed_rank(settings());
|
||||
|
||||
st.all_time_upload = m_total_uploaded;
|
||||
st.all_time_download = m_total_downloaded;
|
||||
st->all_time_upload = m_total_uploaded;
|
||||
st->all_time_download = m_total_downloaded;
|
||||
|
||||
// activity time
|
||||
st.active_time = m_active_time;
|
||||
st.active_time = m_active_time;
|
||||
st.seeding_time = m_seeding_time;
|
||||
st.time_since_upload = m_last_upload;
|
||||
st.time_since_download = m_last_download;
|
||||
st->active_time = m_active_time;
|
||||
st->active_time = m_active_time;
|
||||
st->seeding_time = m_seeding_time;
|
||||
st->time_since_upload = m_last_upload;
|
||||
st->time_since_download = m_last_download;
|
||||
|
||||
st.storage_mode = (storage_mode_t)m_storage_mode;
|
||||
st->storage_mode = (storage_mode_t)m_storage_mode;
|
||||
|
||||
st.num_complete = (m_complete == 0xffffff) ? -1 : m_complete;
|
||||
st.num_incomplete = (m_incomplete == 0xffffff) ? -1 : m_incomplete;
|
||||
st.paused = is_torrent_paused();
|
||||
st.auto_managed = m_auto_managed;
|
||||
st.sequential_download = m_sequential_download;
|
||||
st.is_seeding = is_seed();
|
||||
st.is_finished = is_finished();
|
||||
st.has_metadata = valid_metadata();
|
||||
bytes_done(st, flags & torrent_handle::query_accurate_download_counters);
|
||||
TORRENT_ASSERT(st.total_wanted_done >= 0);
|
||||
TORRENT_ASSERT(st.total_done >= st.total_wanted_done);
|
||||
st->num_complete = (m_complete == 0xffffff) ? -1 : m_complete;
|
||||
st->num_incomplete = (m_incomplete == 0xffffff) ? -1 : m_incomplete;
|
||||
st->paused = is_torrent_paused();
|
||||
st->auto_managed = m_auto_managed;
|
||||
st->sequential_download = m_sequential_download;
|
||||
st->is_seeding = is_seed();
|
||||
st->is_finished = is_finished();
|
||||
st->has_metadata = valid_metadata();
|
||||
bytes_done(*st, flags & torrent_handle::query_accurate_download_counters);
|
||||
TORRENT_ASSERT(st->total_wanted_done >= 0);
|
||||
TORRENT_ASSERT(st->total_done >= st->total_wanted_done);
|
||||
|
||||
// payload transfer
|
||||
st.total_payload_download = m_stat.total_payload_download();
|
||||
st.total_payload_upload = m_stat.total_payload_upload();
|
||||
st->total_payload_download = m_stat.total_payload_download();
|
||||
st->total_payload_upload = m_stat.total_payload_upload();
|
||||
|
||||
// total transfer
|
||||
st.total_download = m_stat.total_payload_download()
|
||||
st->total_download = m_stat.total_payload_download()
|
||||
+ m_stat.total_protocol_download();
|
||||
st.total_upload = m_stat.total_payload_upload()
|
||||
st->total_upload = m_stat.total_payload_upload()
|
||||
+ m_stat.total_protocol_upload();
|
||||
|
||||
// failed bytes
|
||||
st.total_failed_bytes = m_total_failed_bytes;
|
||||
st.total_redundant_bytes = m_total_redundant_bytes;
|
||||
st->total_failed_bytes = m_total_failed_bytes;
|
||||
st->total_redundant_bytes = m_total_redundant_bytes;
|
||||
|
||||
// transfer rate
|
||||
st.download_rate = m_stat.download_rate();
|
||||
st.upload_rate = m_stat.upload_rate();
|
||||
st.download_payload_rate = m_stat.download_payload_rate();
|
||||
st.upload_payload_rate = m_stat.upload_payload_rate();
|
||||
st->download_rate = m_stat.download_rate();
|
||||
st->upload_rate = m_stat.upload_rate();
|
||||
st->download_payload_rate = m_stat.download_payload_rate();
|
||||
st->upload_payload_rate = m_stat.upload_payload_rate();
|
||||
|
||||
if (m_waiting_tracker && !is_paused())
|
||||
st.next_announce = boost::posix_time::seconds(
|
||||
st->next_announce = boost::posix_time::seconds(
|
||||
total_seconds(next_announce() - now));
|
||||
else
|
||||
st.next_announce = boost::posix_time::seconds(0);
|
||||
st->next_announce = boost::posix_time::seconds(0);
|
||||
|
||||
if (st.next_announce.is_negative())
|
||||
st.next_announce = boost::posix_time::seconds(0);
|
||||
if (st->next_announce.is_negative())
|
||||
st->next_announce = boost::posix_time::seconds(0);
|
||||
|
||||
st.announce_interval = boost::posix_time::seconds(0);
|
||||
st->announce_interval = boost::posix_time::seconds(0);
|
||||
|
||||
st.current_tracker.clear();
|
||||
st->current_tracker.clear();
|
||||
if (m_last_working_tracker >= 0)
|
||||
{
|
||||
TORRENT_ASSERT(m_last_working_tracker < int(m_trackers.size()));
|
||||
st.current_tracker = m_trackers[m_last_working_tracker].url;
|
||||
st->current_tracker = m_trackers[m_last_working_tracker].url;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -7236,82 +7236,82 @@ namespace libtorrent
|
|||
for (i = m_trackers.begin(); i != m_trackers.end(); ++i)
|
||||
{
|
||||
if (!i->updating) continue;
|
||||
st.current_tracker = i->url;
|
||||
st->current_tracker = i->url;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
st.num_uploads = m_num_uploads;
|
||||
st.uploads_limit = m_max_uploads;
|
||||
st.num_connections = int(m_connections.size());
|
||||
st.connections_limit = m_max_connections;
|
||||
st->num_uploads = m_num_uploads;
|
||||
st->uploads_limit = m_max_uploads;
|
||||
st->num_connections = int(m_connections.size());
|
||||
st->connections_limit = m_max_connections;
|
||||
// if we don't have any metadata, stop here
|
||||
|
||||
st.queue_position = queue_position();
|
||||
st.need_save_resume = need_save_resume_data();
|
||||
st->queue_position = queue_position();
|
||||
st->need_save_resume = need_save_resume_data();
|
||||
|
||||
st.state = (torrent_status::state_t)m_state;
|
||||
st->state = (torrent_status::state_t)m_state;
|
||||
|
||||
if (!valid_metadata())
|
||||
{
|
||||
st.state = torrent_status::downloading_metadata;
|
||||
st.progress_ppm = m_progress_ppm;
|
||||
st->state = torrent_status::downloading_metadata;
|
||||
st->progress_ppm = m_progress_ppm;
|
||||
#if !TORRENT_NO_FPU
|
||||
st.progress = m_progress_ppm / 1000000.f;
|
||||
st->progress = m_progress_ppm / 1000000.f;
|
||||
#endif
|
||||
st.block_size = 0;
|
||||
return st;
|
||||
st->block_size = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
st.block_size = block_size();
|
||||
st->block_size = block_size();
|
||||
|
||||
if (m_state == torrent_status::checking_files)
|
||||
{
|
||||
st.progress_ppm = m_progress_ppm;
|
||||
st->progress_ppm = m_progress_ppm;
|
||||
#if !TORRENT_NO_FPU
|
||||
st.progress = m_progress_ppm / 1000000.f;
|
||||
st->progress = m_progress_ppm / 1000000.f;
|
||||
#endif
|
||||
}
|
||||
else if (st.total_wanted == 0)
|
||||
else if (st->total_wanted == 0)
|
||||
{
|
||||
st.progress_ppm = 1000000;
|
||||
st.progress = 1.f;
|
||||
st->progress_ppm = 1000000;
|
||||
st->progress = 1.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
st.progress_ppm = st.total_wanted_done * 1000000
|
||||
/ st.total_wanted;
|
||||
st->progress_ppm = st->total_wanted_done * 1000000
|
||||
/ st->total_wanted;
|
||||
#if !TORRENT_NO_FPU
|
||||
st.progress = st.progress_ppm / 1000000.f;
|
||||
st->progress = st->progress_ppm / 1000000.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (has_picker())
|
||||
{
|
||||
st.sparse_regions = m_picker->sparse_regions();
|
||||
st->sparse_regions = m_picker->sparse_regions();
|
||||
int num_pieces = m_picker->num_pieces();
|
||||
st.pieces.resize(num_pieces, false);
|
||||
st->pieces.resize(num_pieces, false);
|
||||
for (int i = 0; i < num_pieces; ++i)
|
||||
if (m_picker->have_piece(i)) st.pieces.set_bit(i);
|
||||
if (m_picker->have_piece(i)) st->pieces.set_bit(i);
|
||||
}
|
||||
st.num_pieces = num_have();
|
||||
st.num_seeds = num_seeds();
|
||||
st->num_pieces = num_have();
|
||||
st->num_seeds = num_seeds();
|
||||
if ((flags & torrent_handle::query_distributed_copies) && m_picker.get())
|
||||
{
|
||||
boost::tie(st.distributed_full_copies, st.distributed_fraction) =
|
||||
boost::tie(st->distributed_full_copies, st->distributed_fraction) =
|
||||
m_picker->distributed_copies();
|
||||
#if TORRENT_NO_FPU
|
||||
st.distributed_copies = -1.f;
|
||||
st->distributed_copies = -1.f;
|
||||
#else
|
||||
st.distributed_copies = st.distributed_full_copies
|
||||
+ float(st.distributed_fraction) / 1000;
|
||||
st->distributed_copies = st->distributed_full_copies
|
||||
+ float(st->distributed_fraction) / 1000;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
st.distributed_full_copies = -1;
|
||||
st.distributed_fraction = -1;
|
||||
st.distributed_copies = -1.f;
|
||||
st->distributed_full_copies = -1;
|
||||
st->distributed_fraction = -1;
|
||||
st->distributed_copies = -1.f;
|
||||
}
|
||||
|
||||
if (flags & torrent_handle::query_last_seen_complete)
|
||||
|
@ -7322,13 +7322,12 @@ namespace libtorrent
|
|||
{
|
||||
last = (std::max)(last, (*i)->last_seen_complete());
|
||||
}
|
||||
st.last_seen_complete = last;
|
||||
st->last_seen_complete = last;
|
||||
}
|
||||
else
|
||||
{
|
||||
st.last_seen_complete = 0;
|
||||
st->last_seen_complete = 0;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
void torrent::add_redundant_bytes(int b)
|
||||
|
|
|
@ -469,8 +469,9 @@ namespace libtorrent
|
|||
torrent_status torrent_handle::status(boost::uint32_t flags) const
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
TORRENT_SYNC_CALL_RET1(torrent_status, torrent_status(), status, flags);
|
||||
return r;
|
||||
torrent_status st;
|
||||
TORRENT_SYNC_CALL2(status, &st, flags);
|
||||
return st;
|
||||
}
|
||||
|
||||
void torrent_handle::set_sequential_download(bool sd) const
|
||||
|
|
Loading…
Reference in New Issue