From 8ea6f78e213b5431a90ef5e287144ab85f219671 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Tue, 28 Mar 2006 21:04:07 +0000 Subject: [PATCH] * Cache the current ceiling in rak::partial_queue. * Added "enable_trackers=yes|no" option that can turn on/off the use of trackers on all torrents. * Cleanup of the API, including a new TrackerList class. * When requesting from seeders, either continue a chunk another seeder started or try a new one. This means seeders don't end up downloading non-rare chunks. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@658 e378c898-3ddf-0310-93e7-cc216c733640 --- src/core/download.cc | 11 +++-- src/core/manager.cc | 7 +-- src/display/canvas.h | 4 ++ src/display/utils.cc | 15 ++++--- src/display/window_download_statusbar.cc | 3 +- src/display/window_tracker_list.cc | 18 ++++---- src/option_handler_rules.cc | 22 ++++++++++ src/ui/download.cc | 54 +++++++++++++----------- src/ui/download.h | 1 + src/ui/element_tracker_list.cc | 37 +++++++++------- 10 files changed, 108 insertions(+), 64 deletions(-) diff --git a/src/core/download.cc b/src/core/download.cc index 1d8ee9f5..4fd0df2b 100644 --- a/src/core/download.cc +++ b/src/core/download.cc @@ -43,6 +43,7 @@ #include #include #include +#include #include "utils/variable_generic.h" @@ -117,12 +118,14 @@ Download::stop() { void Download::enable_udp_trackers(bool state) { - for (int i = 0, last = m_download.size_trackers(); i < last; ++i) - if (m_download.tracker(i).tracker_type() == torrent::Tracker::TRACKER_UDP) + torrent::TrackerList tl = m_download.tracker_list(); + + for (int i = 0, last = tl.size(); i < last; ++i) + if (tl.get(i).tracker_type() == torrent::Tracker::TRACKER_UDP) if (state) - m_download.tracker(i).enable(); + tl.get(i).enable(); else - m_download.tracker(i).disable(); + tl.get(i).disable(); } uint32_t diff --git a/src/core/manager.cc b/src/core/manager.cc index 239127a9..110a535c 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -49,6 +49,7 @@ #include #include #include +#include #include "utils/variable_map.h" @@ -63,12 +64,12 @@ namespace core { static void -connect_signal_network_log(Download* d, torrent::Download::SlotString s) { +connect_signal_network_log(Download* d, torrent::Download::slot_string_type s) { d->get_download().signal_network_log(s); } static void -connect_signal_storage_log(Download* d, torrent::Download::SlotString s) { +connect_signal_storage_log(Download* d, torrent::Download::slot_string_type s) { d->get_download().signal_storage_error(s); } @@ -289,7 +290,7 @@ Manager::receive_download_done_hash_checked(Download* d) { // Don't send if we did a hash check and found incompelete chunks. if (d->is_done()) - d->get_download().tracker_send_completed(); + d->get_download().tracker_list().send_completed(); } void diff --git a/src/display/canvas.h b/src/display/canvas.h index 64877766..9cb8224b 100644 --- a/src/display/canvas.h +++ b/src/display/canvas.h @@ -133,6 +133,10 @@ private: WINDOW* m_window; }; +// Undefines 'timeout' that ncurses defines which screws up the global +// namespace. Idiots; Especially you, ESR. +#undef timeout + } #endif diff --git a/src/display/utils.cc b/src/display/utils.cc index e176cbc2..393fb5bc 100644 --- a/src/display/utils.cc +++ b/src/display/utils.cc @@ -45,6 +45,7 @@ #include #include #include +#include #include "core/download.h" @@ -76,7 +77,7 @@ print_hhmmss(char* first, char* last, time_t t) { char* print_ddhhmm(char* first, char* last, time_t t) { if (t / (24 * 3600) < 100) - return print_buffer(first, last, "%2i:%02i:%02i", (int)t / (24 * 3600), ((int)t / 3600) % 24, ((int)t / 60) % 60); + return print_buffer(first, last, "%2id %2i:%02i", (int)t / (24 * 3600), ((int)t / 3600) % 24, ((int)t / 60) % 60); else return print_buffer(first, last, "--:--:--"); } @@ -158,13 +159,13 @@ print_download_status(char* first, char* last, core::Download* d) { (d->get_download().chunks_hashed() * 100) / d->get_download().chunks_total()); else if (d->get_download().is_tracker_busy() && - d->get_download().tracker_focus() < d->get_download().size_trackers()) - first = print_buffer(first, last, "Tracker[%i:%i]: Connecting to %s", - d->get_download().tracker(d->get_download().tracker_focus()).group(), - d->get_download().tracker_focus(), - d->get_download().tracker(d->get_download().tracker_focus()).url().c_str()); + d->get_download().tracker_list().focus() < d->get_download().tracker_list().size()) { + torrent::TrackerList tl = d->get_download().tracker_list(); - else if (!d->get_message().empty()) + first = print_buffer(first, last, "Tracker[%i:%i]: Connecting to %s", + tl.get(tl.focus()).group(), tl.focus(), tl.get(tl.focus()).url().c_str()); + + } else if (!d->get_message().empty()) first = print_buffer(first, last, "%s", d->get_message().c_str()); else diff --git a/src/display/window_download_statusbar.cc b/src/display/window_download_statusbar.cc index 621ea651..65f8b4bb 100644 --- a/src/display/window_download_statusbar.cc +++ b/src/display/window_download_statusbar.cc @@ -37,6 +37,7 @@ #include "config.h" #include +#include #include "canvas.h" #include "globals.h" @@ -85,7 +86,7 @@ WindowDownloadStatusbar::redraw() { position = print_download_status(buffer, last, m_download); m_canvas->print(0, 2, "[%c:%i] %s", m_download->get_download().is_tracker_busy() ? 'C' : ' ', - (int)(m_download->get_download().tracker_timeout() / 1000000), + (int)(m_download->get_download().tracker_list().timeout() / 1000000), buffer); } diff --git a/src/display/window_tracker_list.cc b/src/display/window_tracker_list.cc index ab294275..50594551 100644 --- a/src/display/window_tracker_list.cc +++ b/src/display/window_tracker_list.cc @@ -39,6 +39,7 @@ #include #include #include +#include #include "core/download.h" @@ -64,21 +65,20 @@ WindowTrackerList::redraw() { ++pos; - if (m_download->get_download().size_trackers() == 0) + torrent::TrackerList tl = m_download->get_download().tracker_list(); + + if (tl.size() == 0) return; - if (*m_focus >= m_download->get_download().size_trackers()) - throw std::logic_error("WindowTrackerList::redraw() called on an object with a bad focus value"); + if (*m_focus >= tl.size()) + throw std::logic_error("WindowTrackerList::redraw() called on an object with a bad focus value."); typedef std::pair Range; - Range range = rak::advance_bidirectional(0, - *m_focus, - m_download->get_download().size_trackers(), - (m_canvas->get_height() + 1) / 2); + Range range = rak::advance_bidirectional(0, *m_focus, tl.size(), (m_canvas->get_height() + 1) / 2); while (range.first != range.second) { - torrent::Tracker t = m_download->get_download().tracker(range.first); + torrent::Tracker t = tl.get(range.first); m_canvas->print(0, pos++, "%c %s", range.first == *m_focus ? '*' : ' ', @@ -88,7 +88,7 @@ WindowTrackerList::redraw() { range.first == *m_focus ? '*' : ' ', t.group(), rak::copy_escape_html(t.tracker_id()).c_str(), - range.first == m_download->get_download().tracker_focus() ? "yes" : " no", + range.first == tl.focus() ? "yes" : " no", t.is_enabled() ? "yes" : " no", t.is_open() ? "yes" : " no", t.scrape_complete(), diff --git a/src/option_handler_rules.cc b/src/option_handler_rules.cc index 2fae6c04..39b9a015 100644 --- a/src/option_handler_rules.cc +++ b/src/option_handler_rules.cc @@ -48,6 +48,7 @@ #include #include #include +#include #include "core/download.h" #include "core/manager.h" @@ -153,6 +154,25 @@ apply_encoding_list(__UNUSED Control* m, const std::string& arg) { torrent::encoding_list()->push_back(arg); } +void +apply_enable_trackers(Control* m, __UNUSED const std::string& arg) { + bool state = (arg != "no"); + + for (core::Manager::DListItr itr = m->core()->download_list().begin(), last = m->core()->download_list().end(); itr != last; ++itr) { + + torrent::TrackerList tl = (*itr)->get_download().tracker_list(); + + for (int i = 0, last = tl.size(); i < last; ++i) + if (state) + tl.get(i).enable(); + else + tl.get(i).disable(); + + if (state && control->variables()->get_string("use_udp_trackers") == "no") + (*itr)->enable_udp_trackers(false); + } +} + void initialize_option_handler(Control* c) { utils::VariableMap* variables = control->variables(); @@ -212,6 +232,8 @@ initialize_option_handler(Control* c) { variables->insert("stop_untied", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_stop_untied, c))); variables->insert("remove_untied", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_remove_untied, c))); + variables->insert("enable_trackers", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_enable_trackers, c))); + variables->insert("encoding_list", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_encoding_list, c))); variables->insert("http_proxy", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_http_proxy, c))); diff --git a/src/ui/download.cc b/src/ui/download.cc index 2195e75f..949329b5 100644 --- a/src/ui/download.cc +++ b/src/ui/download.cc @@ -38,8 +38,9 @@ #include #include -#include #include +#include +#include #include "core/download.h" #include "input/bindings.h" @@ -251,39 +252,44 @@ Download::receive_prev_priority() { m_download->set_priority((m_download->priority() - 1) % 4); } +void +Download::receive_manual_request(bool force) { + m_download->get_download().tracker_list().manual_request(force); +} + void Download::bind_keys() { - (*m_bindings)['1'] = sigc::bind(sigc::mem_fun(*this, &Download::receive_max_uploads), -1); - (*m_bindings)['2'] = sigc::bind(sigc::mem_fun(*this, &Download::receive_max_uploads), 1); - (*m_bindings)['3'] = sigc::bind(sigc::mem_fun(*this, &Download::receive_min_peers), -5); - (*m_bindings)['4'] = sigc::bind(sigc::mem_fun(*this, &Download::receive_min_peers), 5); - (*m_bindings)['5'] = sigc::bind(sigc::mem_fun(*this, &Download::receive_max_peers), -5); - (*m_bindings)['6'] = sigc::bind(sigc::mem_fun(*this, &Download::receive_max_peers), 5); - (*m_bindings)['+'] = sigc::mem_fun(*this, &Download::receive_next_priority); - (*m_bindings)['-'] = sigc::mem_fun(*this, &Download::receive_prev_priority); + (*m_bindings)['1'] = sigc::bind(sigc::mem_fun(this, &Download::receive_max_uploads), -1); + (*m_bindings)['2'] = sigc::bind(sigc::mem_fun(this, &Download::receive_max_uploads), 1); + (*m_bindings)['3'] = sigc::bind(sigc::mem_fun(this, &Download::receive_min_peers), -5); + (*m_bindings)['4'] = sigc::bind(sigc::mem_fun(this, &Download::receive_min_peers), 5); + (*m_bindings)['5'] = sigc::bind(sigc::mem_fun(this, &Download::receive_max_peers), -5); + (*m_bindings)['6'] = sigc::bind(sigc::mem_fun(this, &Download::receive_max_peers), 5); + (*m_bindings)['+'] = sigc::mem_fun(this, &Download::receive_next_priority); + (*m_bindings)['-'] = sigc::mem_fun(this, &Download::receive_prev_priority); - (*m_bindings)['k'] = sigc::mem_fun(*this, &Download::receive_disconnect_peer); + (*m_bindings)['k'] = sigc::mem_fun(this, &Download::receive_disconnect_peer); - (*m_bindings)['t'] = sigc::bind(sigc::mem_fun(m_download->get_download(), &torrent::Download::tracker_manual_request), false); - (*m_bindings)['T'] = sigc::bind(sigc::mem_fun(m_download->get_download(), &torrent::Download::tracker_manual_request), true); + (*m_bindings)['t'] = sigc::bind(sigc::mem_fun(this, &Download::receive_manual_request), false); + (*m_bindings)['T'] = sigc::bind(sigc::mem_fun(this, &Download::receive_manual_request), true); - (*m_bindings)['p'] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_PEER_INFO); - (*m_bindings)['o'] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_TRACKER_LIST); - (*m_bindings)['i'] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_CHUNKS_SEEN); + (*m_bindings)['p'] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_INFO); + (*m_bindings)['o'] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_TRACKER_LIST); + (*m_bindings)['i'] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_CHUNKS_SEEN); - (*m_bindings)[KEY_UP] = sigc::mem_fun(*this, &Download::receive_prev); - (*m_bindings)[KEY_DOWN] = sigc::mem_fun(*this, &Download::receive_next); + (*m_bindings)[KEY_UP] = sigc::mem_fun(this, &Download::receive_prev); + (*m_bindings)[KEY_DOWN] = sigc::mem_fun(this, &Download::receive_next); // Key bindings for sub-ui's. - m_uiArray[DISPLAY_PEER_LIST]->get_bindings()[KEY_RIGHT] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_FILE_LIST); - m_uiArray[DISPLAY_PEER_INFO]->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_PEER_LIST); - m_uiArray[DISPLAY_FILE_LIST]->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_PEER_LIST); - m_uiArray[DISPLAY_TRACKER_LIST]->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_PEER_LIST); - m_uiArray[DISPLAY_CHUNKS_SEEN]->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_PEER_LIST); + m_uiArray[DISPLAY_PEER_LIST]->get_bindings()[KEY_RIGHT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_FILE_LIST); + m_uiArray[DISPLAY_PEER_INFO]->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); + m_uiArray[DISPLAY_FILE_LIST]->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); + m_uiArray[DISPLAY_TRACKER_LIST]->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); + m_uiArray[DISPLAY_CHUNKS_SEEN]->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); // Doesn't belong here. - m_uiArray[DISPLAY_PEER_LIST]->get_bindings()['*'] = sigc::mem_fun(*this, &Download::receive_snub_peer); - m_uiArray[DISPLAY_PEER_INFO]->get_bindings()['*'] = sigc::mem_fun(*this, &Download::receive_snub_peer); + m_uiArray[DISPLAY_PEER_LIST]->get_bindings()['*'] = sigc::mem_fun(this, &Download::receive_snub_peer); + m_uiArray[DISPLAY_PEER_INFO]->get_bindings()['*'] = sigc::mem_fun(this, &Download::receive_snub_peer); } void diff --git a/src/ui/download.h b/src/ui/download.h index 00e11a3d..e4b788af 100644 --- a/src/ui/download.h +++ b/src/ui/download.h @@ -110,6 +110,7 @@ private: void receive_change(Display d); void receive_snub_peer(); + void receive_manual_request(bool force); void bind_keys(); diff --git a/src/ui/element_tracker_list.cc b/src/ui/element_tracker_list.cc index b540cd61..3b9e7f60 100644 --- a/src/ui/element_tracker_list.cc +++ b/src/ui/element_tracker_list.cc @@ -36,7 +36,8 @@ #include "config.h" -#include +#include +#include #include "display/window_tracker_list.h" #include "input/manager.h" @@ -60,7 +61,7 @@ ElementTrackerList::ElementTrackerList(core::Download* d) : void ElementTrackerList::activate(Control* c, MItr mItr) { if (m_window != NULL) - throw std::logic_error("ui::ElementTrackerList::activate(...) called on an object in the wrong state"); + throw torrent::internal_error("ui::ElementTrackerList::activate(...) called on an object in the wrong state"); c->input()->push_front(&m_bindings); @@ -70,7 +71,7 @@ ElementTrackerList::activate(Control* c, MItr mItr) { void ElementTrackerList::disable(Control* c) { if (m_window == NULL) - throw std::logic_error("ui::ElementTrackerList::disable(...) called on an object in the wrong state"); + throw torrent::internal_error("ui::ElementTrackerList::disable(...) called on an object in the wrong state"); c->input()->erase(&m_bindings); @@ -81,12 +82,14 @@ ElementTrackerList::disable(Control* c) { void ElementTrackerList::receive_disable() { if (m_window == NULL) - throw std::logic_error("ui::ElementTrackerList::receive_disable(...) called on a disabled object"); + throw torrent::internal_error("ui::ElementTrackerList::receive_disable(...) called on a disabled object"); - if (m_download->get_download().tracker(m_focus).is_enabled()) - m_download->get_download().tracker(m_focus).disable(); + torrent::Tracker t = m_download->get_download().tracker_list().get(m_focus); + + if (t.is_enabled()) + t.disable(); else - m_download->get_download().tracker(m_focus).enable(); + t.enable(); m_window->mark_dirty(); } @@ -94,9 +97,9 @@ ElementTrackerList::receive_disable() { void ElementTrackerList::receive_next() { if (m_window == NULL) - throw std::logic_error("ui::ElementTrackerList::receive_next(...) called on a disabled object"); + throw torrent::internal_error("ui::ElementTrackerList::receive_next(...) called on a disabled object"); - if (++m_focus >= m_download->get_download().size_trackers()) + if (++m_focus >= m_download->get_download().tracker_list().size()) m_focus = 0; m_window->mark_dirty(); @@ -105,15 +108,15 @@ ElementTrackerList::receive_next() { void ElementTrackerList::receive_prev() { if (m_window == NULL) - throw std::logic_error("ui::ElementTrackerList::receive_prev(...) called on a disabled object"); + throw torrent::internal_error("ui::ElementTrackerList::receive_prev(...) called on a disabled object"); - if (m_download->get_download().size_trackers() == 0) + if (m_download->get_download().tracker_list().size() == 0) return; if (m_focus != 0) --m_focus; else - m_focus = m_download->get_download().size_trackers() - 1; + m_focus = m_download->get_download().tracker_list().size() - 1; m_window->mark_dirty(); } @@ -121,12 +124,14 @@ ElementTrackerList::receive_prev() { void ElementTrackerList::receive_cycle_group() { if (m_window == NULL) - throw std::logic_error("ui::ElementTrackerList::receive_group_cycle(...) called on a disabled object"); + throw torrent::internal_error("ui::ElementTrackerList::receive_group_cycle(...) called on a disabled object"); - if (m_focus >= m_download->get_download().size_trackers()) - throw std::logic_error("ui::ElementTrackerList::receive_group_cycle(...) called with an invalid focus"); + torrent::TrackerList tl = m_download->get_download().tracker_list(); - m_download->get_download().tracker_cycle_group(m_download->get_download().tracker(m_focus).group()); + if (m_focus >= tl.size()) + throw torrent::internal_error("ui::ElementTrackerList::receive_group_cycle(...) called with an invalid focus"); + + tl.cycle_group(tl.get(m_focus).group()); m_window->mark_dirty(); }