diff --git a/src/command_download.cc b/src/command_download.cc index efe54bba..93c25d40 100644 --- a/src/command_download.cc +++ b/src/command_download.cc @@ -47,6 +47,7 @@ #include #include #include +#include #include "core/download.h" #include "core/manager.h" @@ -290,6 +291,34 @@ t_multicall(core::Download* download, const torrent::Object& rawArgs) { return resultRaw; } +torrent::Object +p_multicall(core::Download* download, const torrent::Object& rawArgs) { + const torrent::Object::list_type& args = rawArgs.as_list(); + + if (args.empty()) + throw torrent::input_error("Too few arguments."); + + // We ignore the first arg for now, but it will be used for + // selecting what files to include. + + // 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::TYPE_LIST); + torrent::Object::list_type& result = resultRaw.as_list(); + + for (torrent::ConnectionList::const_iterator itr = download->connection_list()->begin(), last = download->connection_list()->end(); itr != last; itr++) { + torrent::Object::list_type& row = result.insert(result.end(), torrent::Object(torrent::Object::TYPE_LIST))->as_list(); + + for (torrent::Object::list_const_iterator cItr = ++args.begin(), cLast = args.end(); cItr != args.end(); cItr++) { + const std::string& cmd = cItr->as_string(); + + row.push_back(rpc::parse_command(rpc::make_target(*itr), cmd.c_str(), cmd.c_str() + cmd.size()).first); + } + } + + return resultRaw; +} + #define ADD_CD_SLOT(key, function, slot, parm, doc) \ commandDownloadSlotsItr->set_slot(slot); \ rpc::commands.insert_download(key, commandDownloadSlotsItr++, &rpc::CommandSlot::function, rpc::CommandMap::flag_dont_delete, parm, doc); @@ -441,8 +470,8 @@ initialize_command_download() { ADD_CD_VALUE_MEM_BI("peers_min", &core::Download::connection_list, &torrent::ConnectionList::set_min_size, &torrent::ConnectionList::min_size); ADD_CD_VALUE_MEM_BI("peers_max", &core::Download::connection_list, &torrent::ConnectionList::set_max_size, &torrent::ConnectionList::max_size); ADD_CD_VALUE_MEM_BI("uploads_max", &core::Download::download, &torrent::Download::set_uploads_max, &torrent::Download::uploads_max); - ADD_CD_VALUE_UNI("peers_connected", rak::on(std::mem_fun(&core::Download::download), std::mem_fun(&torrent::Download::peers_connected))); - ADD_CD_VALUE_UNI("peers_not_connected", rak::on(std::mem_fun(&core::Download::download), std::mem_fun(&torrent::Download::peers_not_connected))); + ADD_CD_VALUE_UNI("peers_connected", std::mem_fun(&core::Download::connection_list_size)); + ADD_CD_VALUE_UNI("peers_not_connected", rak::on(std::mem_fun(&core::Download::c_peer_list), std::mem_fun(&torrent::PeerList::available_list_size))); ADD_CD_VALUE_UNI("peers_complete", rak::on(std::mem_fun(&core::Download::download), std::mem_fun(&torrent::Download::peers_complete))); ADD_CD_VALUE_UNI("peers_accounted", rak::on(std::mem_fun(&core::Download::download), std::mem_fun(&torrent::Download::peers_accounted))); @@ -482,5 +511,6 @@ initialize_command_download() { ADD_CD_STRING_UNI("priority_str", std::ptr_fun(&retrieve_d_priority_str)); ADD_CD_SLOT_PUBLIC("f.multicall", call_list, rak::ptr_fn(&f_multicall), "i:", "") + ADD_CD_SLOT_PUBLIC("p.multicall", call_list, rak::ptr_fn(&p_multicall), "i:", "") ADD_CD_SLOT_PUBLIC("t.multicall", call_list, rak::ptr_fn(&t_multicall), "i:", "") } diff --git a/src/core/download.cc b/src/core/download.cc index 6b73e174..749c6b88 100644 --- a/src/core/download.cc +++ b/src/core/download.cc @@ -110,6 +110,11 @@ Download::set_priority(uint32_t p) { bencode()->get_key("rtorrent").insert_key("priority", (int64_t)p); } +uint32_t +Download::connection_list_size() const { + return m_download.connection_list()->size(); +} + void Download::receive_tracker_msg(std::string msg) { if (msg.empty()) diff --git a/src/core/download.h b/src/core/download.h index a78601ce..64d081ec 100644 --- a/src/core/download.h +++ b/src/core/download.h @@ -42,10 +42,12 @@ #include #include #include +#include #include "globals.h" namespace torrent { + class PeerList; class TrackerList; } @@ -55,6 +57,7 @@ class Download { public: typedef torrent::Download download_type; typedef torrent::FileList file_list_type; + typedef torrent::PeerList peer_list_type; typedef torrent::TrackerList tracker_list_type; typedef torrent::ConnectionList connection_list_type; typedef download_type::ConnectionType connection_type; @@ -88,12 +91,16 @@ public: file_list_type* file_list() { return m_download.file_list(); } const file_list_type* c_file_list() const { return m_download.file_list(); } + peer_list_type* peer_list() { return m_download.peer_list(); } + const peer_list_type* c_peer_list() const { return m_download.peer_list(); } + torrent::Object* bencode() { return m_download.bencode(); } tracker_list_type* tracker_list() { return m_download.tracker_list(); } uint32_t tracker_list_size() const { return m_download.tracker_list()->size(); } connection_list_type* connection_list() { return m_download.connection_list(); } + uint32_t connection_list_size() const; const std::string& message() const { return m_message; } void set_message(const std::string& msg) { m_message = msg; } diff --git a/src/display/window_download_statusbar.cc b/src/display/window_download_statusbar.cc index 1bb1b9c3..498b8522 100644 --- a/src/display/window_download_statusbar.cc +++ b/src/display/window_download_statusbar.cc @@ -38,6 +38,8 @@ #include #include +#include +#include #include "canvas.h" #include "globals.h" @@ -67,10 +69,10 @@ WindowDownloadStatusbar::redraw() { m_canvas->print(0, 0, "%s", buffer); position = buffer + std::max(snprintf(buffer, last - buffer, "Peers: %i(%i) Min/Max: %i/%i Uploads: %i U/I/C/A: %i/%i/%i/%i Failed: %i", - (int)m_download->download()->peers_connected(), - (int)m_download->download()->peers_not_connected(), - (int)m_download->download()->peers_min(), - (int)m_download->download()->peers_max(), + (int)m_download->download()->connection_list()->size(), + (int)m_download->download()->peer_list()->available_list_size(), + (int)m_download->download()->connection_list()->min_size(), + (int)m_download->download()->connection_list()->max_size(), (int)m_download->download()->uploads_max(), (int)m_download->download()->peers_currently_unchoked(), (int)m_download->download()->peers_currently_interested(),