From b00d083ac21ef66232a1e889c12bff5dc723e0bf Mon Sep 17 00:00:00 2001 From: rakshasa Date: Wed, 1 Mar 2006 20:48:54 +0000 Subject: [PATCH] * Renamed TrackerInfo to DownloadInfo, moved it to DownloadMain and cleaned up DownloadWrapper etc. * Resume total upload from the client rather than torrent::Download::hash_resume_load(...). * Show client names and versions. (incomplete) git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@646 e378c898-3ddf-0310-93e7-cc216c733640 --- src/control.cc | 5 + src/control.h | 5 + src/core/download_factory.cc | 13 ++- src/core/download_store.cc | 4 + src/display/Makefile.am | 2 + src/display/client_info.cc | 174 ++++++++++++++++++++++++++++++++ src/display/client_info.h | 83 +++++++++++++++ src/display/utils.cc | 55 ---------- src/display/utils.h | 97 ++++++++++++++++++ src/display/window_peer_info.cc | 9 ++ src/display/window_peer_list.cc | 8 ++ 11 files changed, 393 insertions(+), 62 deletions(-) create mode 100644 src/display/client_info.cc create mode 100644 src/display/client_info.h diff --git a/src/control.cc b/src/control.cc index e5368099..47bb5b53 100644 --- a/src/control.cc +++ b/src/control.cc @@ -40,6 +40,7 @@ #include "core/manager.h" #include "display/canvas.h" +#include "display/client_info.h" #include "display/window.h" #include "display/manager.h" #include "input/manager.h" @@ -64,6 +65,8 @@ Control::Control() : m_commandScheduler(new CommandScheduler()), m_variables(new utils::VariableMap()), + m_clientInfo(new display::ClientInfo), + m_tick(0) { m_inputStdin->slot_pressed(sigc::mem_fun(m_input, &input::Manager::pressed)); @@ -84,6 +87,8 @@ Control::~Control() { delete m_ui; delete m_display; delete m_core; + + delete m_clientInfo; } void diff --git a/src/control.h b/src/control.h index 6d53f094..5b712248 100644 --- a/src/control.h +++ b/src/control.h @@ -52,6 +52,7 @@ namespace core { namespace display { class Manager; + class ClientInfo; } namespace input { @@ -90,6 +91,8 @@ public: CommandScheduler* command_scheduler() { return m_commandScheduler; } utils::VariableMap* variables() { return m_variables; } + display::ClientInfo* client_info() { return m_clientInfo; } + uint64_t tick() const { return m_tick; } void inc_tick() { m_tick++; } @@ -109,6 +112,8 @@ private: CommandScheduler* m_commandScheduler; utils::VariableMap* m_variables; + display::ClientInfo* m_clientInfo; + uint64_t m_tick; rak::priority_item m_taskShutdown; diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index ffebefa4..7d28cb5d 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -42,6 +42,7 @@ #include #include #include +#include #include "utils/variable_generic.h" @@ -189,14 +190,12 @@ DownloadFactory::receive_success() { if (control->variables()->get_string("use_udp_trackers") == "no") (*itr)->enable_udp_trackers(false); - // Move some of this to "rtorrent". - if (root.has_key("libtorrent resume")) { - torrent::Bencode& libtorrent = root.get_key("libtorrent resume"); - - if (control->variables()->get_string("upload_total_clear") == "yes") - libtorrent.erase_key("total_uploaded"); - } + if (control->variables()->get_string("upload_total_clear") == "yes") + rtorrent.erase_key("total_uploaded"); + else if (rtorrent.has_key("total_uploaded") && rtorrent.get_key("total_uploaded").is_value()) + (*itr)->get_download().up_rate()->set_total(rtorrent.get_key("total_uploaded").as_value()); + if (m_session) { if (!rtorrent.has_key("directory") || !rtorrent.get_key("directory").is_string()) diff --git a/src/core/download_store.cc b/src/core/download_store.cc index 5a7a216b..abd4f824 100644 --- a/src/core/download_store.cc +++ b/src/core/download_store.cc @@ -46,6 +46,7 @@ #include #include #include +#include #include "download.h" #include "download_store.h" @@ -98,6 +99,9 @@ DownloadStore::save(Download* d) { if (!f.is_open()) return; + // Move this somewhere else. + d->get_bencode().get_key("rtorrent").insert_key("total_uploaded", d->get_download().up_rate()->total()); + f << d->get_bencode(); if (!f.good()) diff --git a/src/display/Makefile.am b/src/display/Makefile.am index 1dbe7c1f..674df477 100644 --- a/src/display/Makefile.am +++ b/src/display/Makefile.am @@ -3,6 +3,8 @@ noinst_LIBRARIES = libsub_display.a libsub_display_a_SOURCES = \ canvas.cc \ canvas.h \ + client_info.cc \ + client_info.h \ manager.cc \ manager.h \ utils.cc \ diff --git a/src/display/client_info.cc b/src/display/client_info.cc new file mode 100644 index 00000000..470090ff --- /dev/null +++ b/src/display/client_info.cc @@ -0,0 +1,174 @@ +// rTorrent - BitTorrent client +// Copyright (C) 2005-2006, Jari Sundell +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations +// including the two. +// +// You must obey the GNU General Public License in all respects for +// all of the code used other than OpenSSL. If you modify file(s) +// with this exception, you may extend this exception to your version +// of the file(s), but you are not obligated to do so. If you do not +// wish to do so, delete this exception statement from your version. +// If you delete this exception statement from all source files in the +// program, then also delete it here. +// +// Contact: Jari Sundell +// +// Skomakerveien 33 +// 3185 Skoppum, NORWAY + +#include "config.h" + +#include +#include +#include + +#include "client_info.h" +#include "utils.h" + +namespace display { + +struct client_info_equal { + client_info_equal(const char* key, ClientInfo::size_type size) : m_key(key), m_size(size) {} + + bool operator () (const ClientInfo::value_type& v) const { + for (ClientInfo::size_type i = 0; i < m_size; ++i) + if (v.first[i] != m_key[i]) + return false; + + return true; + } + + const char* m_key; + ClientInfo::size_type m_size; +}; + +ClientInfo::ClientInfo() { + m_containers[TYPE_AZUREUS].reserve(28); + + insert(TYPE_AZUREUS, "AZ", "Azureus"); + insert(TYPE_AZUREUS, "BC", "BitComet"); + insert(TYPE_AZUREUS, "UT", "uTorrent"); + insert(TYPE_AZUREUS, "lt", "libTorrent"); + insert(TYPE_AZUREUS, "BB", "BitBuddy"); + insert(TYPE_AZUREUS, "CT", "CTorrent"); + insert(TYPE_AZUREUS, "MT", "MoonlightTorrent"); + insert(TYPE_AZUREUS, "LT", "libtorrent"); + insert(TYPE_AZUREUS, "BX", "Bittorrent X"); + insert(TYPE_AZUREUS, "TS", "Torrentstorm"); + insert(TYPE_AZUREUS, "TN", "TorrentDotNET"); + insert(TYPE_AZUREUS, "SS", "SwarmScope"); + insert(TYPE_AZUREUS, "XT", "XanTorrent"); + insert(TYPE_AZUREUS, "BS", "BTSlave"); + insert(TYPE_AZUREUS, "ZT", "ZipTorrent"); + insert(TYPE_AZUREUS, "AR", "Arctic"); + insert(TYPE_AZUREUS, "SB", "Swiftbit"); + insert(TYPE_AZUREUS, "MP", "MooPolice"); + insert(TYPE_AZUREUS, "QT", "Qt 4 Torrent example"); + insert(TYPE_AZUREUS, "SZ", "Shareaza"); + insert(TYPE_AZUREUS, "RT", "Retriever"); + + m_containers[TYPE_THREE_COMPACT].reserve(10); + + insert(TYPE_THREE_COMPACT, "A", "ABC"); + insert(TYPE_THREE_COMPACT, "T", "BitTornado"); + insert(TYPE_THREE_COMPACT, "S", "Shadow's client"); + insert(TYPE_THREE_COMPACT, "U", "UPnP NAT Bit Torrent"); + insert(TYPE_THREE_COMPACT, "O", "Osprey Permaseed"); + + m_containers[TYPE_THREE_SPARSE].reserve(4); + + insert(TYPE_THREE_SPARSE, "M", "Mainline"); +} + +void +ClientInfo::insert(Type t, const char* key, const char* name) { + if (t >= TYPE_MAXSIZE) + throw torrent::input_error("Client info type out of range."); + + size_type keySize = sizeof_key(t); + + if (keySize != std::strlen(key)) + throw torrent::input_error("Client info key size not what was expected."); + + // Check if it is already present. + + value_type v; + + std::memcpy(v.first, key, keySize); + v.second = name; + + m_containers[t].push_back(v); +} + +char* +ClientInfo::print(char* first, char* last, const char* id) { + + // Start with an UDP0 test. + + if (id[0] == '-' && id[7] == '-' && + std::isalpha(id[1]) && std::isalpha(id[2]) && + std::isxdigit(id[3]) && std::isxdigit(id[4]) && std::isxdigit(id[5]) && std::isxdigit(id[6])) { + // TYPE_AZUREUS. + + iterator itr = std::find_if(m_containers[TYPE_AZUREUS].begin(), m_containers[TYPE_AZUREUS].end(), + client_info_equal(id + 1, sizeof_key(TYPE_AZUREUS))); + + if (itr != m_containers[TYPE_AZUREUS].end()) + first = print_buffer(first, last, "%s %c.%c.%c.%c", itr->second, id[3], id[4], id[5], id[6]); + + else + first = print_buffer(first, last, "unknown %c%c %c.%c.%c.%c", id[1], id[2], id[3], id[4], id[5], id[6]); + + } else if (std::isalpha(id[0]) && id[4] == '-' && + std::isxdigit(id[1]) && std::isxdigit(id[2]) && std::isxdigit(id[3])) { + // TYPE_THREE_COMPACT. + + iterator itr = std::find_if(m_containers[TYPE_THREE_COMPACT].begin(), m_containers[TYPE_THREE_COMPACT].end(), + client_info_equal(id, sizeof_key(TYPE_THREE_COMPACT))); + + if (itr != m_containers[TYPE_THREE_COMPACT].end()) + first = print_buffer(first, last, "%s %c.%c.%c", itr->second, id[1], id[2], id[3]); + + else + first = print_buffer(first, last, "unknown %c %c.%c.%c", id[0], id[1], id[2], id[3]); + + } else if (std::isalpha(id[0]) && id[2] == '-' && id[4] == '-' && id[6] == '-' && + std::isxdigit(id[1]) && std::isxdigit(id[3]) && std::isxdigit(id[5])) { + // TYPE_THREE_SPARSE. + + iterator itr = std::find_if(m_containers[TYPE_THREE_SPARSE].begin(), m_containers[TYPE_THREE_SPARSE].end(), + client_info_equal(id, sizeof_key(TYPE_THREE_SPARSE))); + + if (itr != m_containers[TYPE_THREE_SPARSE].end()) + first = print_buffer(first, last, "%s %c.%c.%c", itr->second, id[1], id[3], id[5]); + + else + first = print_buffer(first, last, "unknown %c %c.%c.%c", id[0], id[1], id[3], id[5]); + + + } else { + first = print_buffer(first, last, "unknown"); + } + + return first; +} + +} diff --git a/src/display/client_info.h b/src/display/client_info.h new file mode 100644 index 00000000..362eec44 --- /dev/null +++ b/src/display/client_info.h @@ -0,0 +1,83 @@ +// rTorrent - BitTorrent client +// Copyright (C) 2005-2006, Jari Sundell +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations +// including the two. +// +// You must obey the GNU General Public License in all respects for +// all of the code used other than OpenSSL. If you modify file(s) +// with this exception, you may extend this exception to your version +// of the file(s), but you are not obligated to do so. If you do not +// wish to do so, delete this exception statement from your version. +// If you delete this exception statement from all source files in the +// program, then also delete it here. +// +// Contact: Jari Sundell +// +// Skomakerveien 33 +// 3185 Skoppum, NORWAY + +#ifndef RTORRENT_DISPLAY_CLIENT_INFO_H +#define RTORRENT_DISPLAY_CLIENT_INFO_H + +#include +#include + +namespace display { + +class ClientInfo { +public: + // Largest key size + 1. + static const uint32_t key_size = 3; + + typedef uint32_t size_type; + typedef std::pair value_type; + typedef std::vector container_type; + typedef container_type::iterator iterator; + + typedef enum { + TYPE_AZUREUS, + TYPE_THREE_COMPACT, + TYPE_THREE_SPARSE, + TYPE_MAXSIZE + } Type; + + ClientInfo(); + + void insert(Type t, const char* key, const char* name); + + char* print(char* first, char* last, const char* id); + + size_type sizeof_key(Type t) { + switch (t) { + case TYPE_AZUREUS: return 2; + case TYPE_THREE_COMPACT: return 1; + case TYPE_THREE_SPARSE: return 1; + case TYPE_MAXSIZE: return 0; + } + } + +private: + container_type m_containers[TYPE_MAXSIZE]; +}; + +} + +#endif diff --git a/src/display/utils.cc b/src/display/utils.cc index 2233a6da..199c9dc6 100644 --- a/src/display/utils.cc +++ b/src/display/utils.cc @@ -50,61 +50,6 @@ namespace display { -inline char* -print_buffer(char* first, char* last, const char* format) { - if (first >= last) - return first; - - int s = snprintf(first, last - first, format); - - if (s < 0) - return first; - else - return std::min(first + s, last); -} - -template -inline char* -print_buffer(char* first, char* last, const char* format, const Arg1& arg1) { - if (first >= last) - return first; - - int s = snprintf(first, last - first, format, arg1); - - if (s < 0) - return first; - else - return std::min(first + s, last); -} - -template -inline char* -print_buffer(char* first, char* last, const char* format, const Arg1& arg1, const Arg2& arg2) { - if (first >= last) - return first; - - int s = snprintf(first, last - first, format, arg1, arg2); - - if (s < 0) - return first; - else - return std::min(first + s, last); -} - -template -inline char* -print_buffer(char* first, char* last, const char* format, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) { - if (first >= last) - return first; - - int s = snprintf(first, last - first, format, arg1, arg2, arg3); - - if (s < 0) - return first; - else - return std::min(first + s, last); -} - char* print_string(char* first, char* last, char* str) { // We don't have any nice simple functions for copying strings that diff --git a/src/display/utils.h b/src/display/utils.h index b25c1d39..32094fb9 100644 --- a/src/display/utils.h +++ b/src/display/utils.h @@ -74,6 +74,103 @@ char* print_entry_file(char* first, char* last, const torrent::Entry& entr char* print_status_info(char* first, char* last); char* print_status_extra(char* first, char* last, Control* c); +inline char* +print_buffer(char* first, char* last, const char* format) { + if (first >= last) + return first; + + int s = snprintf(first, last - first, format); + + if (s < 0) + return first; + else + return std::min(first + s, last); +} + +template +inline char* +print_buffer(char* first, char* last, const char* format, const Arg1& arg1) { + if (first >= last) + return first; + + int s = snprintf(first, last - first, format, arg1); + + if (s < 0) + return first; + else + return std::min(first + s, last); +} + +template +inline char* +print_buffer(char* first, char* last, const char* format, const Arg1& arg1, const Arg2& arg2) { + if (first >= last) + return first; + + int s = snprintf(first, last - first, format, arg1, arg2); + + if (s < 0) + return first; + else + return std::min(first + s, last); +} + +template +inline char* +print_buffer(char* first, char* last, const char* format, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) { + if (first >= last) + return first; + + int s = snprintf(first, last - first, format, arg1, arg2, arg3); + + if (s < 0) + return first; + else + return std::min(first + s, last); +} + +template +inline char* +print_buffer(char* first, char* last, const char* format, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) { + if (first >= last) + return first; + + int s = snprintf(first, last - first, format, arg1, arg2, arg3, arg4); + + if (s < 0) + return first; + else + return std::min(first + s, last); +} + +template +inline char* +print_buffer(char* first, char* last, const char* format, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) { + if (first >= last) + return first; + + int s = snprintf(first, last - first, format, arg1, arg2, arg3, arg4, arg5); + + if (s < 0) + return first; + else + return std::min(first + s, last); +} + +template +inline char* +print_buffer(char* first, char* last, const char* format, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5, const Arg6& arg6) { + if (first >= last) + return first; + + int s = snprintf(first, last - first, format, arg1, arg2, arg3, arg4, arg5, arg6); + + if (s < 0) + return first; + else + return std::min(first + s, last); +} + } #endif diff --git a/src/display/window_peer_info.cc b/src/display/window_peer_info.cc index feace23b..6ee1c231 100644 --- a/src/display/window_peer_info.cc +++ b/src/display/window_peer_info.cc @@ -42,7 +42,10 @@ #include "core/download.h" +#include "globals.h" + #include "canvas.h" +#include "client_info.h" #include "utils.h" #include "window_peer_info.h" @@ -100,6 +103,12 @@ WindowPeerInfo::redraw() { m_canvas->print(0, y++, "DNS: %s:%hu", (*m_focus)->address().c_str(), (*m_focus)->port()); m_canvas->print(0, y++, "Id: %s" , rak::copy_escape_html((*m_focus)->id()).c_str()); + + char buf[128]; + control->client_info()->print(buf, buf + 128, (*m_focus)->id().c_str()); + + m_canvas->print(0, y++, "Client: %s" , buf); + m_canvas->print(0, y++, "Options: %s" , rak::transform_hex(std::string((*m_focus)->options(), 8)).c_str()); m_canvas->print(0, y++, "Snubbed: %s", (*m_focus)->is_snubbed() ? "yes" : "no"); m_canvas->print(0, y++, "Connected: %s", (*m_focus)->is_incoming() ? "remote" : "local"); diff --git a/src/display/window_peer_list.cc b/src/display/window_peer_list.cc index 29e5789f..bf2cfb36 100644 --- a/src/display/window_peer_list.cc +++ b/src/display/window_peer_list.cc @@ -43,6 +43,7 @@ #include "rak/algorithm.h" #include "canvas.h" +#include "client_info.h" #include "window_peer_list.h" namespace display { @@ -125,6 +126,13 @@ WindowPeerList::redraw() { if (p.is_snubbed()) m_canvas->print(x, y, "*"); + x += 5; + + char buf[128]; + control->client_info()->print(buf, buf + 128, p.id().c_str()); + + m_canvas->print(x, y, "%s", buf); + ++y; ++range.first; }