mirror of
https://github.com/transmission/transmission.git
synced 2025-12-20 10:28:32 +00:00
refactor: use the new benc parser in announcer-http (#2529)
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
#include "transmission.h"
|
#include "transmission.h"
|
||||||
|
|
||||||
#include "announcer-common.h"
|
#include "announcer-common.h"
|
||||||
|
#include "benc.h"
|
||||||
#include "crypto-utils.h"
|
#include "crypto-utils.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@@ -28,7 +29,6 @@
|
|||||||
#include "torrent.h"
|
#include "torrent.h"
|
||||||
#include "trevent.h" /* tr_runInEventThread() */
|
#include "trevent.h" /* tr_runInEventThread() */
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "variant.h"
|
|
||||||
#include "web-utils.h"
|
#include "web-utils.h"
|
||||||
#include "web.h"
|
#include "web.h"
|
||||||
|
|
||||||
@@ -113,67 +113,15 @@ static std::string announce_url_new(tr_session const* session, tr_announce_reque
|
|||||||
unsigned char const* const ipv6 = tr_globalIPv6(session);
|
unsigned char const* const ipv6 = tr_globalIPv6(session);
|
||||||
if (ipv6 != nullptr)
|
if (ipv6 != nullptr)
|
||||||
{
|
{
|
||||||
char ipv6_readable[INET6_ADDRSTRLEN];
|
auto ipv6_readable = std::array<char, INET6_ADDRSTRLEN>{};
|
||||||
evutil_inet_ntop(AF_INET6, ipv6, ipv6_readable, INET6_ADDRSTRLEN);
|
evutil_inet_ntop(AF_INET6, ipv6, std::data(ipv6_readable), std::size(ipv6_readable));
|
||||||
evbuffer_add_printf(buf, "&ipv6=");
|
evbuffer_add_printf(buf, "&ipv6=");
|
||||||
tr_http_escape(buf, ipv6_readable, true);
|
tr_http_escape(buf, std::data(ipv6_readable), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return evbuffer_free_to_str(buf);
|
return evbuffer_free_to_str(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto listToPex(tr_variant* peerList)
|
|
||||||
{
|
|
||||||
size_t n = 0;
|
|
||||||
size_t const len = tr_variantListSize(peerList);
|
|
||||||
auto pex = std::vector<tr_pex>(len);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < len; ++i)
|
|
||||||
{
|
|
||||||
tr_variant* const peer = tr_variantListChild(peerList, i);
|
|
||||||
|
|
||||||
if (peer == nullptr)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ip = std::string_view{};
|
|
||||||
if (!tr_variantDictFindStrView(peer, TR_KEY_ip, &ip))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto addr = tr_address{};
|
|
||||||
if (!tr_address_from_string(&addr, ip))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto port = int64_t{};
|
|
||||||
if (!tr_variantDictFindInt(peer, TR_KEY_port, &port))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port < 0 || port > USHRT_MAX)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tr_address_is_valid_for_peers(&addr, port))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
pex[n].addr = addr;
|
|
||||||
pex[n].port = htons((uint16_t)port);
|
|
||||||
++n;
|
|
||||||
}
|
|
||||||
|
|
||||||
pex.resize(n);
|
|
||||||
return pex;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct announce_data
|
struct announce_data
|
||||||
{
|
{
|
||||||
tr_announce_response response;
|
tr_announce_response response;
|
||||||
@@ -220,79 +168,115 @@ static void verboseLog(std::string_view description, tr_direction direction, std
|
|||||||
out << std::endl << "[b64]"sv << direction_sv << tr_base64_encode(message) << std::endl;
|
out << std::endl << "[b64]"sv << direction_sv << tr_base64_encode(message) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tr_announcerParseHttpAnnounceResponse(tr_announce_response& response, std::string_view msg)
|
static auto constexpr MaxBencDepth = 8;
|
||||||
|
|
||||||
|
void tr_announcerParseHttpAnnounceResponse(tr_announce_response& response, std::string_view benc)
|
||||||
{
|
{
|
||||||
verboseLog("Announce response:", TR_DOWN, msg);
|
verboseLog("Announce response:", TR_DOWN, benc);
|
||||||
|
|
||||||
auto benc = tr_variant{};
|
struct AnnounceHandler final : public transmission::benc::BasicHandler<MaxBencDepth>
|
||||||
auto const variant_loaded = tr_variantFromBuf(&benc, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, msg);
|
|
||||||
if (!variant_loaded)
|
|
||||||
{
|
{
|
||||||
return;
|
using BasicHandler = transmission::benc::BasicHandler<MaxBencDepth>;
|
||||||
}
|
|
||||||
|
|
||||||
if (tr_variantIsDict(&benc))
|
tr_announce_response& response_;
|
||||||
{
|
std::optional<size_t> row_;
|
||||||
auto i = int64_t{};
|
tr_pex pex_ = {};
|
||||||
auto sv = std::string_view{};
|
|
||||||
tr_variant* tmp = nullptr;
|
|
||||||
|
|
||||||
if (tr_variantDictFindStrView(&benc, TR_KEY_failure_reason, &sv))
|
explicit AnnounceHandler(tr_announce_response& response)
|
||||||
|
: response_{ response }
|
||||||
{
|
{
|
||||||
response.errmsg = sv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tr_variantDictFindStrView(&benc, TR_KEY_warning_message, &sv))
|
bool StartDict() override
|
||||||
{
|
{
|
||||||
response.warning = sv;
|
BasicHandler::StartDict();
|
||||||
|
|
||||||
|
pex_ = {};
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tr_variantDictFindInt(&benc, TR_KEY_interval, &i))
|
bool EndDict() override
|
||||||
{
|
{
|
||||||
response.interval = i;
|
BasicHandler::EndDict();
|
||||||
|
|
||||||
|
if (tr_address_is_valid_for_peers(&pex_.addr, pex_.port))
|
||||||
|
{
|
||||||
|
response_.pex.push_back(pex_);
|
||||||
|
pex_ = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tr_variantDictFindInt(&benc, TR_KEY_min_interval, &i))
|
bool Int64(int64_t value) override
|
||||||
{
|
{
|
||||||
response.min_interval = i;
|
auto const key = currentKey();
|
||||||
|
|
||||||
|
if (key == "interval")
|
||||||
|
{
|
||||||
|
response_.interval = value;
|
||||||
|
}
|
||||||
|
else if (key == "min interval"sv)
|
||||||
|
{
|
||||||
|
response_.min_interval = value;
|
||||||
|
}
|
||||||
|
else if (key == "complete"sv)
|
||||||
|
{
|
||||||
|
response_.seeders = value;
|
||||||
|
}
|
||||||
|
else if (key == "incomplete"sv)
|
||||||
|
{
|
||||||
|
response_.leechers = value;
|
||||||
|
}
|
||||||
|
else if (key == "downloaded"sv)
|
||||||
|
{
|
||||||
|
response_.downloads = value;
|
||||||
|
}
|
||||||
|
else if (key == "port"sv)
|
||||||
|
{
|
||||||
|
pex_.port = htons(uint16_t(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tr_variantDictFindStrView(&benc, TR_KEY_tracker_id, &sv))
|
bool String(std::string_view value) override
|
||||||
{
|
{
|
||||||
response.tracker_id = sv;
|
auto const key = currentKey();
|
||||||
}
|
|
||||||
|
|
||||||
if (tr_variantDictFindInt(&benc, TR_KEY_complete, &i))
|
if (key == "failure reason"sv)
|
||||||
{
|
{
|
||||||
response.seeders = i;
|
response_.errmsg = value;
|
||||||
}
|
}
|
||||||
|
else if (key == "warning message"sv)
|
||||||
|
{
|
||||||
|
response_.warning = value;
|
||||||
|
}
|
||||||
|
else if (key == "tracker id"sv)
|
||||||
|
{
|
||||||
|
response_.tracker_id = value;
|
||||||
|
}
|
||||||
|
else if (key == "peers"sv)
|
||||||
|
{
|
||||||
|
response_.pex = tr_peerMgrCompactToPex(std::data(value), std::size(value), nullptr, 0);
|
||||||
|
}
|
||||||
|
else if (key == "peers6"sv)
|
||||||
|
{
|
||||||
|
response_.pex6 = tr_peerMgrCompact6ToPex(std::data(value), std::size(value), nullptr, 0);
|
||||||
|
}
|
||||||
|
else if (key == "ip")
|
||||||
|
{
|
||||||
|
tr_address_from_string(&pex_.addr, value);
|
||||||
|
}
|
||||||
|
|
||||||
if (tr_variantDictFindInt(&benc, TR_KEY_incomplete, &i))
|
return true;
|
||||||
{
|
|
||||||
response.leechers = i;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (tr_variantDictFindInt(&benc, TR_KEY_downloaded, &i))
|
auto stack = transmission::benc::ParserStack<MaxBencDepth>{};
|
||||||
{
|
auto handler = AnnounceHandler{ response };
|
||||||
response.downloads = i;
|
transmission::benc::parse(benc, stack, handler);
|
||||||
}
|
|
||||||
|
|
||||||
if (tr_variantDictFindStrView(&benc, TR_KEY_peers6, &sv))
|
|
||||||
{
|
|
||||||
response.pex6 = tr_peerMgrCompact6ToPex(std::data(sv), std::size(sv), nullptr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tr_variantDictFindStrView(&benc, TR_KEY_peers, &sv))
|
|
||||||
{
|
|
||||||
response.pex = tr_peerMgrCompactToPex(std::data(sv), std::size(sv), nullptr, 0);
|
|
||||||
}
|
|
||||||
else if (tr_variantDictFindList(&benc, TR_KEY_peers, &tmp))
|
|
||||||
{
|
|
||||||
response.pex = listToPex(tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tr_variantFree(&benc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_announce_done(
|
static void on_announce_done(
|
||||||
@@ -376,75 +360,86 @@ static void on_scrape_done_eventthread(void* vdata)
|
|||||||
delete data;
|
delete data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tr_announcerParseHttpScrapeResponse(tr_scrape_response& response, std::string_view msg)
|
void tr_announcerParseHttpScrapeResponse(tr_scrape_response& response, std::string_view benc)
|
||||||
{
|
{
|
||||||
verboseLog("Scrape response:", TR_DOWN, msg);
|
verboseLog("Scrape response:", TR_DOWN, benc);
|
||||||
|
|
||||||
auto top = tr_variant{};
|
struct ScrapeHandler final : public transmission::benc::BasicHandler<MaxBencDepth>
|
||||||
auto const variant_loaded = tr_variantFromBuf(&top, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, msg);
|
|
||||||
if (!variant_loaded)
|
|
||||||
{
|
{
|
||||||
return;
|
using BasicHandler = transmission::benc::BasicHandler<MaxBencDepth>;
|
||||||
}
|
|
||||||
|
|
||||||
if (auto sv = std::string_view{}; tr_variantDictFindStrView(&top, TR_KEY_failure_reason, &sv))
|
tr_scrape_response& response_;
|
||||||
{
|
std::optional<size_t> row_;
|
||||||
response.errmsg = sv;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr_variant* flags = nullptr;
|
explicit ScrapeHandler(tr_scrape_response& response)
|
||||||
auto intVal = int64_t{};
|
: response_{ response }
|
||||||
if (tr_variantDictFindDict(&top, TR_KEY_flags, &flags) &&
|
|
||||||
tr_variantDictFindInt(flags, TR_KEY_min_request_interval, &intVal))
|
|
||||||
{
|
|
||||||
response.min_request_interval = intVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr_variant* files = nullptr;
|
|
||||||
if (tr_variantDictFindDict(&top, TR_KEY_files, &files))
|
|
||||||
{
|
|
||||||
auto key = tr_quark{};
|
|
||||||
tr_variant* val = nullptr;
|
|
||||||
|
|
||||||
for (int i = 0; tr_variantDictChild(files, i, &key, &val); ++i)
|
|
||||||
{
|
{
|
||||||
/* populate the corresponding row in our response array */
|
}
|
||||||
for (int j = 0; j < response.row_count; ++j)
|
|
||||||
|
bool Key(std::string_view value) override
|
||||||
|
{
|
||||||
|
BasicHandler::Key(value);
|
||||||
|
|
||||||
|
auto needle = tr_sha1_digest_t{};
|
||||||
|
if (depth() == 2 && key(1) == "files"sv && std::size(value) == std::size(needle))
|
||||||
{
|
{
|
||||||
struct tr_scrape_response_row* row = &response.rows[j];
|
std::copy_n(reinterpret_cast<std::byte const*>(std::data(value)), std::size(value), std::data(needle));
|
||||||
|
auto const it = std::find_if(
|
||||||
|
std::begin(response_.rows),
|
||||||
|
std::end(response_.rows),
|
||||||
|
[needle](auto const& row) { return row.info_hash == needle; });
|
||||||
|
|
||||||
// TODO(ckerr): ugh, interning info dict hashes is awful
|
if (it == std::end(response_.rows))
|
||||||
auto const& hash = row->info_hash;
|
|
||||||
auto const key_sv = tr_quark_get_string_view(key);
|
|
||||||
if (std::size(hash) == std::size(key_sv) && memcmp(std::data(hash), std::data(key_sv), std::size(hash)) == 0)
|
|
||||||
{
|
{
|
||||||
if (tr_variantDictFindInt(val, TR_KEY_complete, &intVal))
|
row_.reset();
|
||||||
{
|
}
|
||||||
row->seeders = intVal;
|
else
|
||||||
}
|
{
|
||||||
|
row_ = std::distance(std::begin(response_.rows), it);
|
||||||
if (tr_variantDictFindInt(val, TR_KEY_incomplete, &intVal))
|
|
||||||
{
|
|
||||||
row->leechers = intVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tr_variantDictFindInt(val, TR_KEY_downloaded, &intVal))
|
|
||||||
{
|
|
||||||
row->downloads = intVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tr_variantDictFindInt(val, TR_KEY_downloaders, &intVal))
|
|
||||||
{
|
|
||||||
row->downloaders = intVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tr_variantFree(&top);
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Int64(int64_t value) override
|
||||||
|
{
|
||||||
|
if (row_ && currentKey() == "complete"sv)
|
||||||
|
{
|
||||||
|
response_.rows[*row_].seeders = value;
|
||||||
|
}
|
||||||
|
else if (row_ && currentKey() == "downloaded"sv)
|
||||||
|
{
|
||||||
|
response_.rows[*row_].downloads = value;
|
||||||
|
}
|
||||||
|
else if (row_ && currentKey() == "incomplete"sv)
|
||||||
|
{
|
||||||
|
response_.rows[*row_].leechers = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool String(std::string_view value) override
|
||||||
|
{
|
||||||
|
if (depth() == 1 && currentKey() == "failure reason"sv)
|
||||||
|
{
|
||||||
|
response_.errmsg = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto stack = transmission::benc::ParserStack<MaxBencDepth>{};
|
||||||
|
auto handler = ScrapeHandler{ response };
|
||||||
|
tr_error* error = nullptr;
|
||||||
|
transmission::benc::parse(benc, stack, handler, nullptr, &error);
|
||||||
|
if (error != nullptr)
|
||||||
|
{
|
||||||
|
std::cerr << error->message << std::endl;
|
||||||
|
tr_error_clear(&error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_scrape_done(
|
static void on_scrape_done(
|
||||||
|
|||||||
@@ -59,35 +59,63 @@ struct BasicHandler : public Handler
|
|||||||
|
|
||||||
bool StartDict() override
|
bool StartDict() override
|
||||||
{
|
{
|
||||||
keys.emplace_back();
|
push();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Key(std::string_view key) override
|
bool Key(std::string_view key) override
|
||||||
{
|
{
|
||||||
keys.back() = key;
|
keys_[depth_] = key;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EndDict() override
|
bool EndDict() override
|
||||||
{
|
{
|
||||||
keys.resize(keys.size() - 1);
|
pop();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartArray() override
|
bool StartArray() override
|
||||||
{
|
{
|
||||||
keys.emplace_back();
|
push();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EndArray() override
|
bool EndArray() override
|
||||||
{
|
{
|
||||||
keys.resize(keys.size() - 1);
|
pop();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<std::string_view, MaxDepth> keys;
|
auto key(size_t i) const
|
||||||
|
{
|
||||||
|
return keys_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
auto depth() const
|
||||||
|
{
|
||||||
|
return depth_;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto currentKey() const
|
||||||
|
{
|
||||||
|
return key(depth());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void push()
|
||||||
|
{
|
||||||
|
++depth_;
|
||||||
|
keys_[depth_] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop()
|
||||||
|
{
|
||||||
|
--depth_;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t depth_ = 0;
|
||||||
|
std::array<std::string_view, MaxDepth> keys_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<std::size_t MaxDepth>
|
template<std::size_t MaxDepth>
|
||||||
@@ -125,7 +153,7 @@ struct ParserStack
|
|||||||
return stack[depth];
|
return stack[depth];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool expectingDictKey() const
|
[[nodiscard]] bool expectingDictKey() const
|
||||||
{
|
{
|
||||||
return depth > 0 && stack[depth].parent_type == ParentType::Dict && (stack[depth].n_children_walked % 2) == 0;
|
return depth > 0 && stack[depth].parent_type == ParentType::Dict && (stack[depth].n_children_walked % 2) == 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ using namespace std::literals;
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
auto constexpr my_static = std::array<std::string_view, 390>{ ""sv,
|
auto constexpr my_static = std::array<std::string_view, 383>{ ""sv,
|
||||||
"activeTorrentCount"sv,
|
"activeTorrentCount"sv,
|
||||||
"activity-date"sv,
|
"activity-date"sv,
|
||||||
"activityDate"sv,
|
"activityDate"sv,
|
||||||
@@ -108,7 +108,6 @@ auto constexpr my_static = std::array<std::string_view, 390>{ ""sv,
|
|||||||
"errorString"sv,
|
"errorString"sv,
|
||||||
"eta"sv,
|
"eta"sv,
|
||||||
"etaIdle"sv,
|
"etaIdle"sv,
|
||||||
"failure reason"sv,
|
|
||||||
"fields"sv,
|
"fields"sv,
|
||||||
"file-count"sv,
|
"file-count"sv,
|
||||||
"fileStats"sv,
|
"fileStats"sv,
|
||||||
@@ -150,8 +149,6 @@ auto constexpr my_static = std::array<std::string_view, 390>{ ""sv,
|
|||||||
"incomplete-dir-enabled"sv,
|
"incomplete-dir-enabled"sv,
|
||||||
"info"sv,
|
"info"sv,
|
||||||
"inhibit-desktop-hibernation"sv,
|
"inhibit-desktop-hibernation"sv,
|
||||||
"interval"sv,
|
|
||||||
"ip"sv,
|
|
||||||
"ipv4"sv,
|
"ipv4"sv,
|
||||||
"ipv6"sv,
|
"ipv6"sv,
|
||||||
"isBackup"sv,
|
"isBackup"sv,
|
||||||
@@ -198,7 +195,6 @@ auto constexpr my_static = std::array<std::string_view, 390>{ ""sv,
|
|||||||
"metadata_size"sv,
|
"metadata_size"sv,
|
||||||
"metainfo"sv,
|
"metainfo"sv,
|
||||||
"method"sv,
|
"method"sv,
|
||||||
"min interval"sv,
|
|
||||||
"min_request_interval"sv,
|
"min_request_interval"sv,
|
||||||
"move"sv,
|
"move"sv,
|
||||||
"msg_type"sv,
|
"msg_type"sv,
|
||||||
@@ -230,7 +226,6 @@ auto constexpr my_static = std::array<std::string_view, 390>{ ""sv,
|
|||||||
"peers"sv,
|
"peers"sv,
|
||||||
"peers2"sv,
|
"peers2"sv,
|
||||||
"peers2-6"sv,
|
"peers2-6"sv,
|
||||||
"peers6"sv,
|
|
||||||
"peersConnected"sv,
|
"peersConnected"sv,
|
||||||
"peersFrom"sv,
|
"peersFrom"sv,
|
||||||
"peersGettingFromUs"sv,
|
"peersGettingFromUs"sv,
|
||||||
@@ -370,7 +365,6 @@ auto constexpr my_static = std::array<std::string_view, 390>{ ""sv,
|
|||||||
"torrents"sv,
|
"torrents"sv,
|
||||||
"totalSize"sv,
|
"totalSize"sv,
|
||||||
"total_size"sv,
|
"total_size"sv,
|
||||||
"tracker id"sv,
|
|
||||||
"trackerAdd"sv,
|
"trackerAdd"sv,
|
||||||
"trackerRemove"sv,
|
"trackerRemove"sv,
|
||||||
"trackerReplace"sv,
|
"trackerReplace"sv,
|
||||||
@@ -403,7 +397,6 @@ auto constexpr my_static = std::array<std::string_view, 390>{ ""sv,
|
|||||||
"v"sv,
|
"v"sv,
|
||||||
"version"sv,
|
"version"sv,
|
||||||
"wanted"sv,
|
"wanted"sv,
|
||||||
"warning message"sv,
|
|
||||||
"watch-dir"sv,
|
"watch-dir"sv,
|
||||||
"watch-dir-enabled"sv,
|
"watch-dir-enabled"sv,
|
||||||
"webseeds"sv,
|
"webseeds"sv,
|
||||||
|
|||||||
@@ -111,7 +111,6 @@ enum
|
|||||||
TR_KEY_errorString,
|
TR_KEY_errorString,
|
||||||
TR_KEY_eta,
|
TR_KEY_eta,
|
||||||
TR_KEY_etaIdle,
|
TR_KEY_etaIdle,
|
||||||
TR_KEY_failure_reason,
|
|
||||||
TR_KEY_fields,
|
TR_KEY_fields,
|
||||||
TR_KEY_file_count,
|
TR_KEY_file_count,
|
||||||
TR_KEY_fileStats,
|
TR_KEY_fileStats,
|
||||||
@@ -153,8 +152,6 @@ enum
|
|||||||
TR_KEY_incomplete_dir_enabled,
|
TR_KEY_incomplete_dir_enabled,
|
||||||
TR_KEY_info,
|
TR_KEY_info,
|
||||||
TR_KEY_inhibit_desktop_hibernation,
|
TR_KEY_inhibit_desktop_hibernation,
|
||||||
TR_KEY_interval,
|
|
||||||
TR_KEY_ip,
|
|
||||||
TR_KEY_ipv4,
|
TR_KEY_ipv4,
|
||||||
TR_KEY_ipv6,
|
TR_KEY_ipv6,
|
||||||
TR_KEY_isBackup,
|
TR_KEY_isBackup,
|
||||||
@@ -201,7 +198,6 @@ enum
|
|||||||
TR_KEY_metadata_size,
|
TR_KEY_metadata_size,
|
||||||
TR_KEY_metainfo,
|
TR_KEY_metainfo,
|
||||||
TR_KEY_method,
|
TR_KEY_method,
|
||||||
TR_KEY_min_interval,
|
|
||||||
TR_KEY_min_request_interval,
|
TR_KEY_min_request_interval,
|
||||||
TR_KEY_move,
|
TR_KEY_move,
|
||||||
TR_KEY_msg_type,
|
TR_KEY_msg_type,
|
||||||
@@ -233,7 +229,6 @@ enum
|
|||||||
TR_KEY_peers,
|
TR_KEY_peers,
|
||||||
TR_KEY_peers2,
|
TR_KEY_peers2,
|
||||||
TR_KEY_peers2_6,
|
TR_KEY_peers2_6,
|
||||||
TR_KEY_peers6,
|
|
||||||
TR_KEY_peersConnected,
|
TR_KEY_peersConnected,
|
||||||
TR_KEY_peersFrom,
|
TR_KEY_peersFrom,
|
||||||
TR_KEY_peersGettingFromUs,
|
TR_KEY_peersGettingFromUs,
|
||||||
@@ -373,7 +368,6 @@ enum
|
|||||||
TR_KEY_torrents,
|
TR_KEY_torrents,
|
||||||
TR_KEY_totalSize,
|
TR_KEY_totalSize,
|
||||||
TR_KEY_total_size,
|
TR_KEY_total_size,
|
||||||
TR_KEY_tracker_id,
|
|
||||||
TR_KEY_trackerAdd,
|
TR_KEY_trackerAdd,
|
||||||
TR_KEY_trackerRemove,
|
TR_KEY_trackerRemove,
|
||||||
TR_KEY_trackerReplace,
|
TR_KEY_trackerReplace,
|
||||||
@@ -406,7 +400,6 @@ enum
|
|||||||
TR_KEY_v,
|
TR_KEY_v,
|
||||||
TR_KEY_version,
|
TR_KEY_version,
|
||||||
TR_KEY_wanted,
|
TR_KEY_wanted,
|
||||||
TR_KEY_warning_message,
|
|
||||||
TR_KEY_watch_dir,
|
TR_KEY_watch_dir,
|
||||||
TR_KEY_watch_dir_enabled,
|
TR_KEY_watch_dir_enabled,
|
||||||
TR_KEY_webseeds,
|
TR_KEY_webseeds,
|
||||||
|
|||||||
Reference in New Issue
Block a user