diff --git a/src/command_download.cc b/src/command_download.cc index d72aba5d..63d3ba9c 100644 --- a/src/command_download.cc +++ b/src/command_download.cc @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include #include #include @@ -390,21 +388,24 @@ t_multicall(core::Download* download, const torrent::Object::list_type& args) { // Add some pre-parsing of the commands, so we don't spend time // parsing and searching command map for every single call. - torrent::Object resultRaw = torrent::Object::create_list(); - torrent::Object::list_type& result = resultRaw.as_list(); + torrent::Object result_raw = torrent::Object::create_list(); + torrent::Object::list_type& result = result_raw.as_list(); - for (int itr = 0, last = download->tracker_list()->size(); itr != last; itr++) { - torrent::Object::list_type& row = result.insert(result.end(), torrent::Object::create_list())->as_list(); + for (uint32_t idx = 0, last = download->tracker_list_size(); idx < last; idx++) { + auto& row = result.insert(result.end(), torrent::Object::create_list())->as_list(); + auto tracker = download->tracker_controller().at(idx); + + if (!tracker.is_valid()) + continue; for (torrent::Object::list_const_iterator cItr = ++args.begin(); cItr != args.end(); cItr++) { const std::string& cmd = cItr->as_string(); - auto t = download->tracker_list()->at(itr); - row.push_back(rpc::parse_command(rpc::make_target(&t), cmd.c_str(), cmd.c_str() + cmd.size()).first); + row.push_back(rpc::parse_command(rpc::make_target(&tracker), cmd.c_str(), cmd.c_str() + cmd.size()).first); } } - return resultRaw; + return result_raw; } torrent::Object @@ -485,7 +486,8 @@ download_tracker_insert(core::Download* download, const torrent::Object::list_ty if (group < 0 || group > 32) throw torrent::input_error("Tracker group number invalid."); - download->download()->tracker_list()->insert_url(group, args.back().as_string(), true); + download->tracker_controller().add_extra_tracker(group, args.back().as_string()); + return torrent::Object(); } @@ -589,7 +591,7 @@ d_list_remove(core::Download* download, const torrent::Object& rawArgs, const ch #define CMD2_BIND_CL std::bind(&core::Download::connection_list, std::placeholders::_1) #define CMD2_BIND_FL std::bind(&core::Download::file_list, std::placeholders::_1) #define CMD2_BIND_PL std::bind(&core::Download::c_peer_list, std::placeholders::_1) -#define CMD2_BIND_TL std::bind(&core::Download::tracker_list, std::placeholders::_1) +#define CMD2_BIND_TC std::bind(&core::Download::tracker_controller, std::placeholders::_1) #define CMD2_BIND_INFO std::bind(&core::Download::info, std::placeholders::_1) #define CMD2_BIND_DATA std::bind(&core::Download::data, std::placeholders::_1) @@ -836,15 +838,15 @@ initialize_command_download() { CMD2_DL_V ("d.tracker_announce", std::bind(&torrent::Download::manual_request, CMD2_BIND_DL, false)); CMD2_DL_V ("d.tracker_announce.force", std::bind(&torrent::Download::manual_request, CMD2_BIND_DL, true)); - CMD2_DL ("d.tracker_numwant", std::bind(&torrent::TrackerList::numwant, CMD2_BIND_TL)); - CMD2_DL_VALUE_V ("d.tracker_numwant.set", std::bind(&torrent::TrackerList::set_numwant, CMD2_BIND_TL, std::placeholders::_2)); + CMD2_DL ("d.tracker_numwant", std::bind(&torrent::tracker::TrackerControllerWrapper::numwant, CMD2_BIND_TC)); + CMD2_DL_VALUE_V ("d.tracker_numwant.set", std::bind(&torrent::tracker::TrackerControllerWrapper::set_numwant, CMD2_BIND_TC, std::placeholders::_2)); // TODO: Deprecate 'd.tracker_focus'. CMD2_DL ("d.tracker_focus", std::bind(&core::Download::tracker_list_size, std::placeholders::_1)); CMD2_DL ("d.tracker_size", std::bind(&core::Download::tracker_list_size, std::placeholders::_1)); - CMD2_DL ("d.tracker.has_active", std::bind(&torrent::TrackerList::has_active, CMD2_BIND_TL)); - CMD2_DL ("d.tracker.has_active_not_scrape", std::bind(&torrent::TrackerList::has_active_not_scrape, CMD2_BIND_TL)); - CMD2_DL ("d.tracker.has_usable", std::bind(&torrent::TrackerList::has_usable, CMD2_BIND_TL)); + CMD2_DL ("d.tracker.has_active", std::bind(&torrent::tracker::TrackerControllerWrapper::has_active_trackers, CMD2_BIND_TC)); + CMD2_DL ("d.tracker.has_active_not_scrape", std::bind(&torrent::tracker::TrackerControllerWrapper::has_active_trackers_not_scrape, CMD2_BIND_TC)); + CMD2_DL ("d.tracker.has_usable", std::bind(&torrent::tracker::TrackerControllerWrapper::has_usable_trackers, CMD2_BIND_TC)); CMD2_DL_LIST ("d.tracker.insert", std::bind(&download_tracker_insert, std::placeholders::_1, std::placeholders::_2)); CMD2_DL_VALUE_V ("d.tracker.send_scrape", [](auto download, uint64_t arg) { download->tracker_controller().scrape_request(arg); }); diff --git a/src/command_network.cc b/src/command_network.cc index 22662462..45a94ba5 100644 --- a/src/command_network.cc +++ b/src/command_network.cc @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -73,10 +72,12 @@ initialize_rpc() { return (*d->file_list())[index].get(); }; rpc::rpc.slot_find_tracker() = [](core::Download* d, uint32_t index) -> torrent::tracker::Tracker { - if (index >= d->tracker_list()->size()) + if (index >= d->tracker_controller().size()) throw torrent::input_error("invalid parameters: index not found"); - return d->tracker_list()->at(index); + // TODO: This should be rewritten to check if the tracker is valid and use a different + // function. + return d->tracker_controller().at(index); }; rpc::rpc.slot_find_peer() = [](core::Download* d, const torrent::HashString& hash) -> torrent::Peer* { auto itr = d->connection_list()->find(hash.c_str()); diff --git a/src/command_tracker.cc b/src/command_tracker.cc index 9a1d8a62..d2b3ad49 100644 --- a/src/command_tracker.cc +++ b/src/command_tracker.cc @@ -62,11 +62,23 @@ apply_dht_add_node(const std::string& arg) { torrent::Object apply_enable_trackers(int64_t arg) { - for (core::Manager::DListItr itr = control->core()->download_list()->begin(), last = control->core()->download_list()->end(); itr != last; ++itr) { - std::for_each((*itr)->tracker_list()->begin(), (*itr)->tracker_list()->end(), std::mem_fn(arg ? &torrent::tracker::Tracker::enable : &torrent::tracker::Tracker::disable)); + if (arg == 0) { + for (auto itr : *control->core()->download_list()) + itr->tracker_controller().for_each([](auto& tracker) { tracker.disable(); }); - if (arg && !rpc::call_command_value("trackers.use_udp")) - (*itr)->enable_udp_trackers(false); + } else if (rpc::call_command_value("trackers.use_udp") == 0) { + for (auto itr : *control->core()->download_list()) { + itr->tracker_controller().for_each([](auto& tracker) { + if (tracker.type() == torrent::TRACKER_UDP) + tracker.disable(); + else + tracker.enable(); + }); + } + + } else { + for (auto itr : *control->core()->download_list()) + itr->tracker_controller().for_each([](auto& tracker) { tracker.enable(); }); } return torrent::Object(); diff --git a/src/core/download.cc b/src/core/download.cc index 798219ea..3d3e176d 100644 --- a/src/core/download.cc +++ b/src/core/download.cc @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -38,13 +37,17 @@ Download::~Download() { void Download::enable_udp_trackers(bool state) { - for (torrent::TrackerList::iterator itr = m_download.tracker_list()->begin(), last = m_download.tracker_list()->end(); itr != last; ++itr) - if (itr->type() == torrent::TRACKER_UDP) { - if (state) - itr->enable(); - else - itr->disable(); - } + for (int idx = 0, end = m_download.tracker_controller().size(); idx < end; ++idx) { + auto tracker = m_download.tracker_controller().at(idx); + + if (tracker.type() != torrent::TRACKER_UDP) + continue; + + if (state) + tracker.enable(); + else + tracker.disable(); + } } uint32_t diff --git a/src/core/download.h b/src/core/download.h index b8494a08..8a52c851 100644 --- a/src/core/download.h +++ b/src/core/download.h @@ -5,9 +5,9 @@ #include #include #include -#include #include #include +#include #include "globals.h" @@ -62,8 +62,7 @@ public: torrent::Object* bencode() { return m_download.bencode(); } auto tracker_controller() { return m_download.tracker_controller(); } - tracker_list_type* tracker_list() { return m_download.tracker_list(); } - uint32_t tracker_list_size() const { return m_download.tracker_list()->size(); } + uint32_t tracker_list_size() const { return m_download.c_tracker_controller().size(); } auto connection_list() { return m_download.connection_list(); } uint32_t connection_list_size() const; diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index 9795a902..c8b50dd1 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -225,7 +225,7 @@ DownloadFactory::receive_success() { torrent::Object* rtorrent = &root->insert_preserve_copy("rtorrent", torrent::Object::create_map()).first->second; torrent::Object& resumeObject = root->insert_preserve_copy("libtorrent_resume", torrent::Object::create_map()).first->second; - rtorrent->insert_key("key", download->tracker_list()->key()); + rtorrent->insert_key("key", download->tracker_controller().key()); initialize_rtorrent(download, rtorrent); diff --git a/src/core/manager.cc b/src/core/manager.cc index 2f986648..5035142d 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -17,7 +17,6 @@ #include #include #include -#include #include #include diff --git a/src/display/utils.cc b/src/display/utils.cc index 06987c6f..c3ba9bb5 100644 --- a/src/display/utils.cc +++ b/src/display/utils.cc @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -160,14 +159,18 @@ print_download_status(char* first, char* last, core::Download* d) { first = print_buffer(first, last, "Checking hash [%2i%%]", (d->download()->chunks_hashed() * 100) / d->download()->file_list()->size_chunks()); - } else if (d->tracker_list()->has_active_not_scrape()) { - torrent::TrackerList::iterator itr = - std::find_if(d->tracker_list()->begin(), d->tracker_list()->end(), - std::mem_fn(&torrent::tracker::Tracker::is_busy_not_scrape)); - auto status = itr->status(); + } else if (d->tracker_controller().has_active_trackers_not_scrape()) { + auto tracker = d->tracker_controller().find_if([](const auto& t) { + return t.is_busy_not_scrape(); + }); - first = print_buffer(first, last, "Tracker[%i:%i]: Connecting to %s %s", - itr->group(), std::distance(d->tracker_list()->begin(), itr), itr->url().c_str(), status.c_str()); + if (tracker.is_valid()) { + auto status = tracker.status(); + + first = print_buffer(first, last, "Tracker[%i]: Connecting to %s %s", tracker.group(), tracker.url().c_str(), status.c_str()); + } else { + first = print_buffer(first, last, "Tracker: Connecting ..."); + } } else if (!d->message().empty()) { first = print_buffer(first, last, "%s", d->message().c_str()); diff --git a/src/display/window_download_statusbar.cc b/src/display/window_download_statusbar.cc index 4dcee03a..cbd9337a 100644 --- a/src/display/window_download_statusbar.cc +++ b/src/display/window_download_statusbar.cc @@ -1,17 +1,15 @@ #include "config.h" +#include "window_download_statusbar.h" + #include #include -#include -#include #include #include #include "canvas.h" #include "globals.h" #include "utils.h" -#include "window_download_statusbar.h" - #include "core/download.h" namespace display { @@ -57,7 +55,7 @@ WindowDownloadStatusbar::redraw() { print_download_status(buffer.data(), last, m_download); m_canvas->print(0, 2, "[%c:%i] %s", - m_download->tracker_list()->has_active() ? 'C' : ' ', + m_download->tracker_controller().has_active_trackers() ? 'C' : ' ', (int)(m_download->download()->tracker_controller().seconds_to_next_timeout()), buffer.data()); } diff --git a/src/display/window_tracker_list.cc b/src/display/window_tracker_list.cc index c5444387..797cbb35 100644 --- a/src/display/window_tracker_list.cc +++ b/src/display/window_tracker_list.cc @@ -1,16 +1,14 @@ #include "config.h" +#include "window_tracker_list.h" + #include #include #include -#include -#include #include #include "core/download.h" -#include "window_tracker_list.h" - namespace display { WindowTrackerList::WindowTrackerList(core::Download* d, unsigned int* focus) : @@ -25,27 +23,25 @@ WindowTrackerList::redraw() { schedule_update(10); m_canvas->erase(); - unsigned int pos = 0; - auto tl = m_download->tracker_list(); + auto pos = 0u; auto tc = m_download->tracker_controller(); + auto tc_size = tc.size(); m_canvas->print(2, pos, "Trackers: [Key: %08x] [%s %s %s]", - tl->key(), + tc.key(), tc.is_requesting() ? "req" : " ", tc.is_promiscuous_mode() ? "prom" : " ", tc.is_failure_mode() ? "fail" : " "); ++pos; - if (tl->size() == 0 || *m_focus >= tl->size()) + if (tc_size == 0 || *m_focus >= tc_size) return; - typedef std::pair Range; - - Range range = rak::advance_bidirectional(0, *m_focus, tl->size(), (m_canvas->height() - 1) / 2); - unsigned int group = tl->at(range.first).group(); + auto range = rak::advance_bidirectional(0, *m_focus, tc_size, (m_canvas->height() - 1) / 2); + auto group = tc.at(range.first).group(); while (range.first != range.second) { - auto tracker = tl->at(range.first); + auto tracker = tc.at(range.first); if (tracker.group() == group) m_canvas->print(0, pos, "%2i:", group++); @@ -93,7 +89,7 @@ WindowTrackerList::redraw() { // If we're at the end of the range, check if we can // show one more line for the following tracker. - if (range.first == range.second && pos < m_canvas->height() && range.first < tl->size()) + if (range.first == range.second && pos < m_canvas->height() && range.first < tc_size) range.second++; } } diff --git a/src/ui/download.cc b/src/ui/download.cc index 32aa3aeb..19fd04c5 100644 --- a/src/ui/download.cc +++ b/src/ui/download.cc @@ -8,7 +8,6 @@ #include #include #include -#include #include #include diff --git a/src/ui/element_tracker_list.cc b/src/ui/element_tracker_list.cc index d7b274ed..752ff2a9 100644 --- a/src/ui/element_tracker_list.cc +++ b/src/ui/element_tracker_list.cc @@ -1,7 +1,6 @@ #include "config.h" #include -#include #include #include "display/frame.h" @@ -67,7 +66,10 @@ ElementTrackerList::receive_disable() { if (m_window == NULL) throw torrent::internal_error("ui::ElementTrackerList::receive_disable(...) called on a disabled object"); - auto t = m_download->download()->tracker_list()->at(m_focus); + auto t = m_download->download()->tracker_controller().at(m_focus); + + if (!t.is_valid()) + return; if (t.is_enabled()) t.disable(); @@ -82,7 +84,7 @@ ElementTrackerList::receive_next() { if (m_window == NULL) throw torrent::internal_error("ui::ElementTrackerList::receive_next(...) called on a disabled object"); - if (++m_focus >= m_download->download()->tracker_list()->size()) + if (++m_focus >= m_download->download()->tracker_controller().size()) m_focus = 0; m_window->mark_dirty(); @@ -93,13 +95,13 @@ ElementTrackerList::receive_prev() { if (m_window == NULL) throw torrent::internal_error("ui::ElementTrackerList::receive_prev(...) called on a disabled object"); - if (m_download->download()->tracker_list()->size() == 0) + if (m_download->download()->tracker_controller().size() == 0) return; if (m_focus != 0) --m_focus; else - m_focus = m_download->download()->tracker_list()->size() - 1; + m_focus = m_download->download()->tracker_controller().size() - 1; m_window->mark_dirty(); } @@ -109,12 +111,12 @@ ElementTrackerList::receive_cycle_group() { if (m_window == NULL) throw torrent::internal_error("ui::ElementTrackerList::receive_group_cycle(...) called on a disabled object"); - torrent::TrackerList* tl = m_download->tracker_list(); + auto tracker = m_download->download()->tracker_controller().at(m_focus); - if (m_focus >= tl->size()) - throw torrent::internal_error("ui::ElementTrackerList::receive_group_cycle(...) called with an invalid focus"); + if (!tracker.is_valid()) + return; - tl->cycle_group(tl->at(m_focus).group()); + m_download->download()->tracker_controller().cycle_group(tracker.group()); m_window->mark_dirty(); }