Changeset 1058
- Timestamp:
- 05/05/08 15:16:26 (4 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 20 modified
-
libtorrent/src/download/download_main.cc (modified) (4 diffs)
-
libtorrent/src/download/download_main.h (modified) (3 diffs)
-
libtorrent/src/protocol/Makefile.am (modified) (1 diff)
-
libtorrent/src/protocol/handshake.cc (modified) (2 diffs)
-
libtorrent/src/protocol/handshake_manager.cc (modified) (1 diff)
-
libtorrent/src/protocol/initial_seed.cc (added)
-
libtorrent/src/protocol/initial_seed.h (added)
-
libtorrent/src/protocol/peer_connection_base.h (modified) (2 diffs)
-
libtorrent/src/protocol/peer_connection_leech.cc (modified) (16 diffs)
-
libtorrent/src/protocol/peer_connection_leech.h (modified) (2 diffs)
-
libtorrent/src/protocol/peer_factory.cc (modified) (1 diff)
-
libtorrent/src/protocol/peer_factory.h (modified) (1 diff)
-
libtorrent/src/torrent/download.cc (modified) (2 diffs)
-
libtorrent/src/torrent/download.h (modified) (1 diff)
-
libtorrent/src/torrent/peer/peer_info.cc (modified) (1 diff)
-
libtorrent/src/torrent/peer/peer_info.h (modified) (3 diffs)
-
libtorrent/src/torrent/peer/peer_list.cc (modified) (1 diff)
-
rtorrent/doc/rtorrent.1.xml (modified) (2 diffs)
-
rtorrent/src/command_download.cc (modified) (4 diffs)
-
rtorrent/src/core/download_factory.cc (modified) (2 diffs)
-
rtorrent/src/core/download_list.cc (modified) (1 diff)
-
rtorrent/src/ui/element_download_list.cc (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtorrent/src/download/download_main.cc
r1032 r1058 43 43 #include "protocol/extensions.h" 44 44 #include "protocol/handshake_manager.h" 45 #include "protocol/initial_seed.h" 45 46 #include "protocol/peer_connection_base.h" 47 #include "protocol/peer_factory.h" 46 48 #include "tracker/tracker_manager.h" 49 #include "torrent/download.h" 47 50 #include "torrent/exceptions.h" 48 51 #include "torrent/data/file_list.h" … … 57 60 #include "download_info.h" 58 61 #include "download_main.h" 62 #include "download_manager.h" 63 #include "download_wrapper.h" 59 64 60 65 namespace torrent { … … 68 73 m_chunkStatistics(new ChunkStatistics), 69 74 75 m_initialSeeding(NULL), 70 76 m_uploadThrottle(NULL), 71 77 m_downloadThrottle(NULL) { … … 192 198 193 199 m_slotStopHandshakes(this); 194 195 200 connection_list()->erase_remaining(connection_list()->begin(), ConnectionList::disconnect_available); 196 201 202 delete m_initialSeeding; 203 197 204 priority_queue_erase(&taskScheduler, &m_taskTrackerRequest); 205 } 206 207 bool 208 DownloadMain::start_initial_seeding() { 209 if (!file_list()->is_done()) 210 return false; 211 212 m_initialSeeding = new InitialSeeding(this); 213 return true; 214 } 215 216 void 217 DownloadMain::initial_seeding_done(PeerConnectionBase* pcb) { 218 if (m_initialSeeding == NULL) 219 throw internal_error("DownloadMain::initial_seeding_done called when not initial seeding."); 220 221 // Close all connections but the currently active one (pcb). 222 // That one will be closed by throw close_connection() later. 223 if (m_connectionList->size() > 1) { 224 ConnectionList::iterator itr = std::find(m_connectionList->begin(), m_connectionList->end(), pcb); 225 if (itr == m_connectionList->end()) 226 throw internal_error("DownloadMain::initial_seeding_done could not find current connection."); 227 228 std::iter_swap(m_connectionList->begin(), itr); 229 m_connectionList->erase_remaining(m_connectionList->begin() + 1, ConnectionList::disconnect_available); 230 } 231 232 // Switch to normal seeding. 233 DownloadManager::iterator itr = manager->download_manager()->find(m_info); 234 (*itr)->set_connection_type(Download::CONNECTION_SEED); 235 m_connectionList->slot_new_connection(&createPeerConnectionSeed); 236 delete m_initialSeeding; 237 m_initialSeeding = NULL; 238 239 // And close the current connection. 240 throw close_connection(); 198 241 } 199 242 -
trunk/libtorrent/src/download/download_main.h
r1016 r1058 66 66 class DownloadInfo; 67 67 class ThrottleList; 68 class InitialSeeding; 68 69 69 70 class DownloadMain { … … 95 96 96 97 have_queue_type* have_queue() { return &m_haveQueue; } 98 99 InitialSeeding* initial_seeding() { return m_initialSeeding; } 100 bool start_initial_seeding(); 101 void initial_seeding_done(PeerConnectionBase* pcb); 97 102 98 103 ConnectionList* connection_list() { return m_connectionList; } … … 158 163 Delegator m_delegator; 159 164 have_queue_type m_haveQueue; 165 InitialSeeding* m_initialSeeding; 160 166 161 167 ConnectionList* m_connectionList; -
trunk/libtorrent/src/protocol/Makefile.am
r1043 r1058 11 11 handshake_manager.cc \ 12 12 handshake_manager.h \ 13 initial_seed.cc \ 14 initial_seed.h \ 13 15 peer_chunks.h \ 14 16 peer_connection_base.cc \ -
trunk/libtorrent/src/protocol/handshake.cc
r1034 r1058 527 527 // The download is just starting so we're not sending any 528 528 // bitfield. Pretend we wrote it already. 529 if (m_download->file_list()->bitfield()->is_all_unset() )529 if (m_download->file_list()->bitfield()->is_all_unset() || m_download->initial_seeding() != NULL) { 530 530 m_writePos = m_download->file_list()->bitfield()->size_bytes(); 531 else 531 m_writeBuffer.write_32(0); 532 533 if (m_encryption.info()->is_encrypted()) 534 m_encryption.info()->encrypt(m_writeBuffer.end() - 4, 4); 535 536 } else { 532 537 prepare_bitfield(); 538 } 533 539 534 540 m_state = READ_MESSAGE; … … 622 628 // bitfield to send, we need to send a keep-alive now. 623 629 if (m_writePos == m_download->file_list()->bitfield()->size_bytes()) 624 prepare_post_handshake(m_download->file_list()->bitfield()->is_all_unset() );630 prepare_post_handshake(m_download->file_list()->bitfield()->is_all_unset() || m_download->initial_seeding() != NULL); 625 631 626 632 if (m_writeDone) -
trunk/libtorrent/src/protocol/handshake_manager.cc
r1010 r1058 195 195 // We need to make libtorrent more selective in the clients it 196 196 // connects to, and to move this somewhere else. 197 (!download->file_list()->is_done() || !handshake->bitfield()->is_all_set() ) &&197 (!download->file_list()->is_done() || !handshake->bitfield()->is_all_set() || download->initial_seeding() != NULL) && 198 198 199 199 (pcb = download->connection_list()->insert(handshake->peer_info(), -
trunk/libtorrent/src/protocol/peer_connection_base.h
r1032 r1058 137 137 void cancel_transfer(BlockTransfer* transfer); 138 138 139 // Insert into the poll unless we're blocking for throttling etc. 140 void read_insert_poll_safe(); 141 void write_insert_poll_safe(); 142 139 143 protected: 140 144 static const uint32_t extension_must_encrypt = ~uint32_t(); … … 176 180 177 181 bool send_pex_message(); 178 179 // Insert into the poll unless we're blocking for throttling etc.180 void read_insert_poll_safe();181 void write_insert_poll_safe();182 182 183 183 DownloadMain* m_download; -
trunk/libtorrent/src/protocol/peer_connection_leech.cc
r1043 r1058 51 51 52 52 #include "extensions.h" 53 #include "initial_seed.h" 53 54 #include "peer_connection_leech.h" 54 55 … … 66 67 void 67 68 PeerConnection<type>::initialize_custom() { 69 if (type == Download::CONNECTION_INITIAL_SEED) { 70 if (m_download->initial_seeding() == NULL) { 71 // Can't throw close_connection or network_error here, we're still 72 // initializing. So close the socket and let that kill it later. 73 get_fd().close(); 74 return; 75 } 76 77 m_download->initial_seeding()->new_peer(this); 78 } 68 79 // if (m_download->content()->chunks_completed() != 0) { 69 80 // m_up->write_bitfield(m_download->file_list()->bitfield()->size_bytes()); … … 78 89 void 79 90 PeerConnection<type>::update_interested() { 80 if (type == Download::CONNECTION_SEED)91 if (type != Download::CONNECTION_LEECH) 81 92 return; 82 93 … … 118 129 } 119 130 120 if (type == Download::CONNECTION_SEED)131 if (type != Download::CONNECTION_LEECH) 121 132 return true; 122 133 … … 193 204 switch (buf->read_8()) { 194 205 case ProtocolBase::CHOKE: 195 if (type == Download::CONNECTION_SEED)206 if (type != Download::CONNECTION_LEECH) 196 207 return true; 197 208 … … 213 224 214 225 case ProtocolBase::UNCHOKE: 215 if (type == Download::CONNECTION_SEED)226 if (type != Download::CONNECTION_LEECH) 216 227 return true; 217 228 … … 259 270 260 271 case ProtocolBase::PIECE: 261 if (type == Download::CONNECTION_SEED)272 if (type != Download::CONNECTION_LEECH) 262 273 throw communication_error("Received a piece but the connection is strictly for seeding."); 263 274 … … 382 393 383 394 case ProtocolRead::READ_PIECE: 384 if (type == Download::CONNECTION_SEED)395 if (type != Download::CONNECTION_LEECH) 385 396 return; 386 397 … … 402 413 403 414 case ProtocolRead::READ_SKIP_PIECE: 404 if (type == Download::CONNECTION_SEED)415 if (type != Download::CONNECTION_LEECH) 405 416 return; 406 417 … … 490 501 // request has been received while uninterested. The problem arises 491 502 // as they send unchoke before receiving interested. 492 if (type != Download::CONNECTION_SEED&& m_sendInterested && m_up->can_write_interested()) {503 if (type == Download::CONNECTION_LEECH && m_sendInterested && m_up->can_write_interested()) { 493 504 m_up->write_interested(m_downInterested); 494 505 m_sendInterested = false; 495 506 } 496 507 497 if (type != Download::CONNECTION_SEED&& m_tryRequest) {508 if (type == Download::CONNECTION_LEECH && m_tryRequest) { 498 509 if (!(m_tryRequest = !should_request()) && 499 510 !(m_tryRequest = try_request_pieces()) && … … 509 520 DownloadMain::have_queue_type* haveQueue = m_download->have_queue(); 510 521 511 if (type != Download::CONNECTION_SEED&&522 if (type == Download::CONNECTION_LEECH && 512 523 !haveQueue->empty() && 513 524 m_peerChunks.have_timer() <= haveQueue->front().first && … … 523 534 } 524 535 525 while (type != Download::CONNECTION_SEED && !m_peerChunks.cancel_queue()->empty() && m_up->can_write_cancel()) { 536 if (type == Download::CONNECTION_INITIAL_SEED && m_up->can_write_have()) 537 offer_chunk(); 538 539 while (type == Download::CONNECTION_LEECH && !m_peerChunks.cancel_queue()->empty() && m_up->can_write_cancel()) { 526 540 m_up->write_cancel(m_peerChunks.cancel_queue()->front()); 527 541 m_peerChunks.cancel_queue()->pop_front(); … … 534 548 } else if (!m_upChoke.choked() && 535 549 !m_peerChunks.upload_queue()->empty() && 536 m_up->can_write_piece()) { 550 m_up->can_write_piece() && 551 (type != Download::CONNECTION_INITIAL_SEED || should_upload())) { 537 552 write_prepare_piece(); 538 553 } … … 639 654 m_download->chunk_statistics()->received_have_chunk(&m_peerChunks, index, m_download->file_list()->chunk_size()); 640 655 656 if (type == Download::CONNECTION_INITIAL_SEED) 657 m_download->initial_seeding()->chunk_seen(index, this); 658 659 // Disconnect seeds when we are seeding (but not for initial seeding 660 // so that we keep accurate chunk statistics until that is done). 641 661 if (m_peerChunks.bitfield()->is_all_set()) { 642 if (type == Download::CONNECTION_SEED || m_download->file_list()->is_done()) 662 if (type == Download::CONNECTION_SEED || 663 (type != Download::CONNECTION_INITIAL_SEED && m_download->file_list()->is_done())) 643 664 throw close_connection(); 644 665 … … 646 667 } 647 668 648 if (type == Download::CONNECTION_SEED|| m_download->file_list()->is_done())669 if (type != Download::CONNECTION_LEECH || m_download->file_list()->is_done()) 649 670 return; 650 671 … … 677 698 } 678 699 679 // Explicit instatiation of the member functions and vtable. 700 template<> 701 void 702 PeerConnection<Download::CONNECTION_INITIAL_SEED>::offer_chunk() { 703 // If bytes left to send in this chunk minus bytes about to be sent is zero, 704 // assume the peer will have got the chunk completely. In that case we may 705 // get another one to offer if not enough other peers are interested even 706 // if the peer would otherwise still be blocked. 707 uint32_t bytesLeft = m_data.bytesLeft; 708 if (!m_peerChunks.upload_queue()->empty() && m_peerChunks.upload_queue()->front().index() == m_data.lastIndex) 709 bytesLeft -= m_peerChunks.upload_queue()->front().length(); 710 711 uint32_t index = m_download->initial_seeding()->chunk_offer(this, bytesLeft == 0 ? m_data.lastIndex : InitialSeeding::no_offer); 712 713 if (index == InitialSeeding::no_offer || index == m_data.lastIndex) 714 return; 715 716 m_up->write_have(index); 717 m_data.lastIndex = index; 718 m_data.bytesLeft = m_download->file_list()->chunk_index_size(index); 719 } 720 721 template<> 722 bool 723 PeerConnection<Download::CONNECTION_INITIAL_SEED>::should_upload() { 724 // For initial seeding, check if chunk is well seeded now, and if so 725 // remove it from the queue to better use our bandwidth on rare chunks. 726 while (!m_peerChunks.upload_queue()->empty() && 727 !m_download->initial_seeding()->should_upload(m_peerChunks.upload_queue()->front().index())) 728 m_peerChunks.upload_queue()->pop_front(); 729 730 // If queue ends up empty, choke peer to let it know that it 731 // shouldn't wait for the cancelled pieces to be sent. 732 if (m_peerChunks.upload_queue()->empty()) { 733 m_download->upload_choke_manager()->set_not_queued(this, &m_upChoke); 734 m_download->upload_choke_manager()->set_queued(this, &m_upChoke); 735 736 // If we're sending the chunk we last offered, adjust bytes left in it. 737 } else if (m_peerChunks.upload_queue()->front().index() == m_data.lastIndex) { 738 m_data.bytesLeft -= m_peerChunks.upload_queue()->front().length(); 739 740 if (!m_data.bytesLeft) 741 m_data.lastIndex = InitialSeeding::no_offer; 742 } 743 744 return !m_peerChunks.upload_queue()->empty(); 745 } 746 747 // Explicit instantiation of the member functions and vtable. 680 748 template class PeerConnection<Download::CONNECTION_LEECH>; 681 749 template class PeerConnection<Download::CONNECTION_SEED>; 682 683 } 750 template class PeerConnection<Download::CONNECTION_INITIAL_SEED>; 751 752 } -
trunk/libtorrent/src/protocol/peer_connection_leech.h
r1043 r1058 44 44 namespace torrent { 45 45 46 // Type-specific data. 47 template<Download::ConnectionType type> struct PeerConnectionData; 48 49 template<> struct PeerConnectionData<Download::CONNECTION_LEECH> { }; 50 51 template<> struct PeerConnectionData<Download::CONNECTION_SEED> { }; 52 53 template<> struct PeerConnectionData<Download::CONNECTION_INITIAL_SEED> { 54 PeerConnectionData() : lastIndex(~uint32_t()) { } 55 uint32_t lastIndex; 56 uint32_t bytesLeft; 57 }; 58 46 59 template<Download::ConnectionType type> 47 60 class PeerConnection : public PeerConnectionBase { … … 60 73 void read_have_chunk(uint32_t index); 61 74 75 void offer_chunk(); 76 bool should_upload(); 77 62 78 inline void fill_write_buffer(); 79 80 PeerConnectionData<type> m_data; 63 81 }; 64 82 -
trunk/libtorrent/src/protocol/peer_factory.cc
r1043 r1058 56 56 } 57 57 58 PeerConnectionBase* 59 createPeerConnectionInitialSeed(bool encrypted) { 60 PeerConnectionBase* pc = new PeerConnection<Download::CONNECTION_INITIAL_SEED>; 61 62 return pc; 58 63 } 64 65 } -
trunk/libtorrent/src/protocol/peer_factory.h
r939 r1058 44 44 PeerConnectionBase* createPeerConnectionDefault(bool encrypted); 45 45 PeerConnectionBase* createPeerConnectionSeed(bool encrypted); 46 PeerConnectionBase* createPeerConnectionInitialSeed(bool encrypted); 46 47 47 48 } -
trunk/libtorrent/src/torrent/download.cc
r1035 r1058 107 107 file_list()->open(flags & ~FileList::open_no_create); 108 108 109 if (m_ptr->connection_type() == CONNECTION_INITIAL_SEED) { 110 if (!m_ptr->main()->start_initial_seeding()) 111 set_connection_type(CONNECTION_SEED); 112 } 113 109 114 m_ptr->main()->start(); 110 115 m_ptr->main()->tracker_manager()->set_active(true); … … 502 507 m_ptr->main()->connection_list()->slot_new_connection(&createPeerConnectionSeed); 503 508 break; 509 case CONNECTION_INITIAL_SEED: 510 if (is_active() && m_ptr->main()->initial_seeding() == NULL) 511 throw input_error("Can't switch to initial seeding: download is active."); 512 m_ptr->main()->connection_list()->slot_new_connection(&createPeerConnectionInitialSeed); 513 break; 504 514 default: 505 515 throw input_error("torrent::Download::set_connection_type(...) received an unknown type."); -
trunk/libtorrent/src/torrent/download.h
r1035 r1058 181 181 typedef enum { 182 182 CONNECTION_LEECH, 183 CONNECTION_SEED 183 CONNECTION_SEED, 184 CONNECTION_INITIAL_SEED, 184 185 } ConnectionType; 185 186 -
trunk/libtorrent/src/torrent/peer/peer_info.cc
r991 r1058 70 70 throw internal_error("PeerInfo::~PeerInfo() m_transferCounter != 0."); 71 71 72 if (is_blocked()) 73 throw internal_error("PeerInfo::~PeerInfo() peer is blocked."); 74 72 75 delete rak::socket_address::cast_from(m_address); 73 76 } -
trunk/libtorrent/src/torrent/peer/peer_info.h
r1013 r1058 48 48 friend class Handshake; 49 49 friend class HandshakeManager; 50 friend class InitialSeeding; 50 51 friend class PeerList; 51 52 friend class ProtocolExtension; … … 54 55 static const int flag_incoming = (1 << 1); 55 56 static const int flag_handshake = (1 << 2); 57 static const int flag_blocked = (1 << 3); // For initial seeding. 58 static const int flag_restart = (1 << 4); 56 59 57 60 PeerInfo(const sockaddr* address); … … 61 64 bool is_incoming() const { return m_flags & flag_incoming; } 62 65 bool is_handshake() const { return m_flags & flag_handshake; } 66 bool is_blocked() const { return m_flags & flag_blocked; } 67 bool is_restart() const { return m_flags & flag_restart; } 63 68 64 69 int flags() const { return m_flags; } -
trunk/libtorrent/src/torrent/peer/peer_list.cc
r1012 r1058 307 307 itr->second->last_connection() >= timer || 308 308 309 (flags & cull_keep_interesting && itr->second->failed_counter() != 0)) { 309 (flags & cull_keep_interesting && 310 (itr->second->failed_counter() != 0 || itr->second->is_blocked()))) { 310 311 itr++; 311 312 continue; -
trunk/rtorrent/doc/rtorrent.1.xml
r1045 r1058 155 155 Set the 'create/resize queued' flags on all files in a torrent. This 156 156 is necessary if the underlying files in a torrent have been deleted or 157 truncate s, and thus rtorrent muchrecreate them.157 truncated, and thus rtorrent must recreate them. 158 158 </para></listitem> 159 159 </varlistentry> … … 178 178 <listitem><para> 179 179 Call commands or change settings. 180 </para></listitem> 181 </varlistentry> 182 183 <varlistentry> 184 <term>^B</term> 185 <listitem><para> 186 Set download to perform initial seeding. Only use when 187 you are the first and only seeder so far for the download. 180 188 </para></listitem> 181 189 </varlistentry> -
trunk/rtorrent/src/command_download.cc
r1049 r1058 170 170 else if (name == "seed") 171 171 connType = torrent::Download::CONNECTION_SEED; 172 else if (name == "initial_seed") 173 connType = torrent::Download::CONNECTION_INITIAL_SEED; 172 174 else 173 175 throw torrent::input_error("Unknown peer connection type selected."); … … 193 195 case torrent::Download::CONNECTION_SEED: 194 196 return "seed"; 197 case torrent::Download::CONNECTION_INITIAL_SEED: 198 return "initial_seed"; 195 199 default: 196 200 return "unknown"; … … 493 497 494 498 ADD_CD_STRING_BI("connection_current", std::ptr_fun(&apply_d_connection_type), std::ptr_fun(&retrieve_d_connection_type)); 499 ADD_CD_VARIABLE_STRING("connection_leech", "rtorrent", "connection_leech"); 500 ADD_CD_VARIABLE_STRING("connection_seed", "rtorrent", "connection_seed"); 495 501 496 502 ADD_CD_VALUE_BI("hashing_failed", std::mem_fun(&core::Download::set_hash_failed), std::mem_fun(&core::Download::is_hash_failed)); … … 499 505 // logging support. 500 506 ADD_CD_STRING_BI("message", std::mem_fun(&core::Download::set_message), std::mem_fun(&core::Download::message)); 501 502 add_copy_to_download("get_connection_leech", "d.get_connection_leech");503 add_copy_to_download("set_connection_leech", "d.set_connection_leech");504 add_copy_to_download("get_connection_seed", "d.get_connection_seed");505 add_copy_to_download("set_connection_seed", "d.set_connection_seed");506 507 507 508 ADD_CD_VALUE_MEM_BI("max_file_size", &core::Download::file_list, &torrent::FileList::set_max_file_size, &torrent::FileList::max_file_size); -
trunk/rtorrent/src/core/download_factory.cc
r1049 r1058 196 196 if (!rtorrent->has_key_string("custom5")) rtorrent->insert_key("custom5", std::string()); 197 197 198 // Move to 'rtorrent'.199 rpc::call_command("d.set_connection_leech", m_variables["connection_leech"], rpc::make_target(download));200 rpc::call_command("d.set_connection_seed", m_variables["connection_seed"], rpc::make_target(download));201 202 198 rpc::call_command("d.set_uploads_max", rpc::call_command_void("get_max_uploads"), rpc::make_target(download)); 203 199 rpc::call_command("d.set_peers_min", rpc::call_command_void("get_min_peers"), rpc::make_target(download)); … … 353 349 354 350 rtorrent->insert_preserve_copy("ignore_commands", (int64_t)0); 355 } 356 357 } 351 352 rtorrent->insert_preserve_type("connection_leech", m_variables["connection_leech"]); 353 rtorrent->insert_preserve_type("connection_seed", m_variables["connection_seed"]); 354 } 355 356 } -
trunk/rtorrent/src/core/download_list.cc
r1051 r1058 399 399 rpc::call_command("d.set_state_counter", rpc::call_command_value("d.get_state_counter", rpc::make_target(download)), rpc::make_target(download)); 400 400 401 // If initial seeding is complete, don't try it again when restarting. 402 if (download->is_done()) 403 rpc::call_command("d.set_connection_seed", rpc::call_command_void("d.get_connection_current", rpc::make_target(download)), rpc::make_target(download)); 404 401 405 // Save the state after all the slots, etc have been called so we 402 406 // include the modifications they may make. -
trunk/rtorrent/src/ui/element_download_list.cc
r1050 r1058 77 77 "{d.set_ignore_commands=0, print=\"Torrent set to heed commands.\"}," 78 78 "{d.set_ignore_commands=1, print=\"Torrent set to ignore commands.\"}"); 79 m_bindings['B'-'@']= sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command), 80 "branch=d.is_active=," 81 "{print=\"Cannot enable initial seeding on an active download.\"}," 82 "{d.set_connection_seed=initial_seed, print=\"Enabled initial seeding for the selected download.\"}"); 79 83 80 84 m_bindings['U'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command), "d.delete_tied=; print=\"Cleared tied to file association for the selected download.\"");
