librats 1.0.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -331
- package/binding.gyp +16 -3
- package/lib/index.d.ts +288 -696
- package/lib/index.js +407 -44
- package/native-src/3rdparty/android/ifaddrs-android.c +1 -0
- package/native-src/3rdparty/android/ifaddrs-android.h +1 -0
- package/native-src/CMakeLists.txt +404 -179
- package/native-src/LICENSE +1 -1
- package/native-src/src/librats/bindings/rats.cpp +762 -0
- package/native-src/src/librats/bindings/rats.h +380 -0
- package/native-src/src/librats/bittorrent/bencode.cpp +437 -0
- package/native-src/src/librats/bittorrent/bencode.h +176 -0
- package/native-src/src/librats/bittorrent/bitfield.cpp +97 -0
- package/native-src/src/librats/bittorrent/bitfield.h +76 -0
- package/native-src/src/librats/bittorrent/byte_io.h +58 -0
- package/native-src/src/librats/bittorrent/choker.cpp +25 -0
- package/native-src/src/librats/bittorrent/choker.h +46 -0
- package/native-src/src/librats/bittorrent/client.cpp +413 -0
- package/native-src/src/librats/bittorrent/client.h +227 -0
- package/native-src/src/librats/bittorrent/disk_io.cpp +209 -0
- package/native-src/src/librats/bittorrent/disk_io.h +150 -0
- package/native-src/src/librats/bittorrent/extensions.cpp +191 -0
- package/native-src/src/librats/bittorrent/extensions.h +94 -0
- package/native-src/src/librats/bittorrent/file_storage.cpp +77 -0
- package/native-src/src/librats/bittorrent/file_storage.h +79 -0
- package/native-src/src/librats/bittorrent/log.h +42 -0
- package/native-src/src/librats/bittorrent/magnet_uri.cpp +98 -0
- package/native-src/src/librats/bittorrent/magnet_uri.h +35 -0
- package/native-src/src/librats/bittorrent/peer_connection.cpp +502 -0
- package/native-src/src/librats/bittorrent/peer_connection.h +194 -0
- package/native-src/src/librats/bittorrent/peer_list.cpp +68 -0
- package/native-src/src/librats/bittorrent/peer_list.h +75 -0
- package/native-src/src/librats/bittorrent/piece_picker.cpp +352 -0
- package/native-src/src/librats/bittorrent/piece_picker.h +201 -0
- package/native-src/src/librats/bittorrent/reactor.cpp +97 -0
- package/native-src/src/librats/bittorrent/reactor.h +89 -0
- package/native-src/src/librats/bittorrent/resume_data.cpp +72 -0
- package/native-src/src/librats/bittorrent/resume_data.h +41 -0
- package/native-src/src/librats/bittorrent/store_buffer.cpp +48 -0
- package/native-src/src/librats/bittorrent/store_buffer.h +47 -0
- package/native-src/src/librats/bittorrent/torrent.cpp +870 -0
- package/native-src/src/librats/bittorrent/torrent.h +260 -0
- package/native-src/src/librats/bittorrent/torrent_creator.cpp +129 -0
- package/native-src/src/librats/bittorrent/torrent_creator.h +58 -0
- package/native-src/src/librats/bittorrent/torrent_info.cpp +314 -0
- package/native-src/src/librats/bittorrent/torrent_info.h +118 -0
- package/native-src/src/librats/bittorrent/tracker.cpp +374 -0
- package/native-src/src/librats/bittorrent/tracker.h +108 -0
- package/native-src/src/librats/bittorrent/types.cpp +206 -0
- package/native-src/src/librats/bittorrent/types.h +86 -0
- package/native-src/src/librats/core/address.cpp +35 -0
- package/native-src/src/librats/core/address.h +78 -0
- package/native-src/src/librats/core/bytes.h +69 -0
- package/native-src/src/librats/core/chained_send_buffer.cpp +172 -0
- package/native-src/src/librats/core/chained_send_buffer.h +183 -0
- package/native-src/src/librats/core/endpoint_parse.cpp +41 -0
- package/native-src/src/librats/core/endpoint_parse.h +31 -0
- package/native-src/src/librats/core/event_bus.h +70 -0
- package/native-src/src/librats/core/host_endpoint.h +56 -0
- package/native-src/src/{io_poller.cpp → librats/core/io_poller.cpp} +520 -65
- package/native-src/src/{io_poller.h → librats/core/io_poller.h} +12 -6
- package/native-src/src/librats/core/ip_address.cpp +120 -0
- package/native-src/src/librats/core/ip_address.h +109 -0
- package/native-src/src/librats/core/mpsc_queue.h +47 -0
- package/native-src/src/librats/core/notifier.h +74 -0
- package/native-src/src/librats/core/receive_buffer.cpp +219 -0
- package/native-src/src/librats/core/receive_buffer.h +171 -0
- package/native-src/src/librats/core/service_registry.h +58 -0
- package/native-src/src/{socket.cpp → librats/core/socket.cpp} +625 -118
- package/native-src/src/librats/core/socket.h +496 -0
- package/native-src/src/librats/core/timer_queue.h +105 -0
- package/native-src/src/librats/core/types.cpp +43 -0
- package/native-src/src/librats/core/types.h +103 -0
- package/native-src/src/librats/core/wakeup_pipe.h +83 -0
- package/native-src/src/{crypto → librats/crypto}/blake2_endian.h +21 -23
- package/native-src/src/{crypto → librats/crypto}/blake2b.c +34 -33
- package/native-src/src/{crypto → librats/crypto}/blake2b.h +7 -6
- package/native-src/src/{crypto → librats/crypto}/blake2s.c +55 -54
- package/native-src/src/{crypto → librats/crypto}/blake2s.h +13 -12
- package/native-src/src/{crypto → librats/crypto}/chacha.c +22 -21
- package/native-src/src/{crypto → librats/crypto}/chacha.h +14 -13
- package/native-src/src/{crypto → librats/crypto}/chachapoly.c +56 -56
- package/native-src/src/{crypto → librats/crypto}/chachapoly.h +24 -17
- package/native-src/src/{crc32.cpp → librats/crypto/crc32.cpp} +1 -1
- package/native-src/src/{crc32.h → librats/crypto/crc32.h} +3 -1
- package/native-src/src/{crypto → librats/crypto}/curve25519.c +6 -4
- package/native-src/src/{crypto → librats/crypto}/curve25519.h +6 -3
- package/native-src/src/librats/crypto/hkdf.c +266 -0
- package/native-src/src/{crypto → librats/crypto}/hkdf.h +19 -19
- package/native-src/src/{noise.cpp → librats/crypto/noise.cpp} +84 -73
- package/native-src/src/{noise.h → librats/crypto/noise.h} +18 -8
- package/native-src/src/{crypto → librats/crypto}/poly1305.c +47 -46
- package/native-src/src/librats/crypto/poly1305.h +37 -0
- package/native-src/src/{sha1.cpp → librats/crypto/sha1.cpp} +33 -1
- package/native-src/src/{sha1.h → librats/crypto/sha1.h} +14 -6
- package/native-src/src/{crypto → librats/crypto}/sha256.c +15 -14
- package/native-src/src/{crypto → librats/crypto}/sha256.h +8 -7
- package/native-src/src/{crypto → librats/crypto}/sha512.c +15 -14
- package/native-src/src/{crypto → librats/crypto}/sha512.h +8 -7
- package/native-src/src/librats/dht/announce.cpp +37 -0
- package/native-src/src/librats/dht/announce.h +41 -0
- package/native-src/src/librats/dht/bep42.cpp +109 -0
- package/native-src/src/librats/dht/bep42.h +48 -0
- package/native-src/src/librats/dht/dht.cpp +501 -0
- package/native-src/src/librats/dht/dht.h +119 -0
- package/native-src/src/librats/dht/dht_runner.cpp +103 -0
- package/native-src/src/librats/dht/dht_runner.h +71 -0
- package/native-src/src/librats/dht/dos_blocker.cpp +42 -0
- package/native-src/src/librats/dht/dos_blocker.h +47 -0
- package/native-src/src/librats/dht/find_peers.cpp +52 -0
- package/native-src/src/librats/dht/find_peers.h +73 -0
- package/native-src/src/librats/dht/id.h +167 -0
- package/native-src/src/{krpc.cpp → librats/dht/krpc.cpp} +32 -81
- package/native-src/src/{krpc.h → librats/dht/krpc.h} +19 -23
- package/native-src/src/librats/dht/log.h +38 -0
- package/native-src/src/librats/dht/node.cpp +473 -0
- package/native-src/src/librats/dht/node.h +164 -0
- package/native-src/src/librats/dht/node_entry.h +81 -0
- package/native-src/src/librats/dht/observer.h +72 -0
- package/native-src/src/librats/dht/persistence.cpp +90 -0
- package/native-src/src/librats/dht/persistence.h +32 -0
- package/native-src/src/librats/dht/routing_table.cpp +559 -0
- package/native-src/src/librats/dht/routing_table.h +185 -0
- package/native-src/src/librats/dht/rpc_manager.cpp +127 -0
- package/native-src/src/librats/dht/rpc_manager.h +77 -0
- package/native-src/src/librats/dht/storage.cpp +92 -0
- package/native-src/src/librats/dht/storage.h +74 -0
- package/native-src/src/librats/dht/transport.h +27 -0
- package/native-src/src/librats/dht/traversal.cpp +326 -0
- package/native-src/src/librats/dht/traversal.h +120 -0
- package/native-src/src/librats/dht/udp_transport.cpp +49 -0
- package/native-src/src/librats/dht/udp_transport.h +51 -0
- package/native-src/src/librats/mdns/log.h +22 -0
- package/native-src/src/{mdns.cpp → librats/mdns/mdns.cpp} +75 -40
- package/native-src/src/{mdns.h → librats/mdns/mdns.h} +9 -8
- package/native-src/src/{natpmp.cpp → librats/nat/natpmp.cpp} +12 -9
- package/native-src/src/{natpmp.h → librats/nat/natpmp.h} +3 -3
- package/native-src/src/{port_mapping.h → librats/nat/port_mapping.h} +3 -2
- package/native-src/src/{stun.cpp → librats/nat/stun.cpp} +4 -4
- package/native-src/src/{stun.h → librats/nat/stun.h} +1 -1
- package/native-src/src/{upnp.cpp → librats/nat/upnp.cpp} +6 -6
- package/native-src/src/{upnp.h → librats/nat/upnp.h} +2 -2
- package/native-src/src/librats/node/circuit_service.h +84 -0
- package/native-src/src/librats/node/config.h +110 -0
- package/native-src/src/librats/node/dial_service.h +54 -0
- package/native-src/src/librats/node/dialer.cpp +264 -0
- package/native-src/src/librats/node/dialer.h +188 -0
- package/native-src/src/librats/node/host_events.h +26 -0
- package/native-src/src/librats/node/identify.cpp +130 -0
- package/native-src/src/librats/node/identify.h +71 -0
- package/native-src/src/librats/node/nat_status.cpp +103 -0
- package/native-src/src/librats/node/nat_status.h +118 -0
- package/native-src/src/librats/node/node.cpp +865 -0
- package/native-src/src/librats/node/node.h +344 -0
- package/native-src/src/librats/node/node_context.h +33 -0
- package/native-src/src/librats/node/peer_network.h +91 -0
- package/native-src/src/librats/peer/peer.h +49 -0
- package/native-src/src/librats/peer/peer_book.cpp +181 -0
- package/native-src/src/librats/peer/peer_book.h +88 -0
- package/native-src/src/librats/peer/peer_id.cpp +72 -0
- package/native-src/src/librats/peer/peer_id.h +62 -0
- package/native-src/src/librats/peer/peer_info.h +37 -0
- package/native-src/src/librats/peer/peer_table.cpp +170 -0
- package/native-src/src/librats/peer/peer_table.h +148 -0
- package/native-src/src/librats/security/handshaker.h +66 -0
- package/native-src/src/librats/security/identity.h +43 -0
- package/native-src/src/librats/security/noise_security.cpp +122 -0
- package/native-src/src/librats/security/noise_security.h +37 -0
- package/native-src/src/librats/security/plaintext_security.h +106 -0
- package/native-src/src/librats/security/session.h +37 -0
- package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
- package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
- package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
- package/native-src/src/librats/subsystems/bittorrent.h +136 -0
- package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
- package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
- package/native-src/src/librats/subsystems/dht_service.h +36 -0
- package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
- package/native-src/src/librats/subsystems/file_transfer.h +367 -0
- package/native-src/src/librats/subsystems/hole_punch.cpp +605 -0
- package/native-src/src/librats/subsystems/hole_punch.h +290 -0
- package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
- package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
- package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
- package/native-src/src/librats/subsystems/message_json.cpp +112 -0
- package/native-src/src/librats/subsystems/message_json.h +88 -0
- package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
- package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
- package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
- package/native-src/src/librats/subsystems/ping_service.h +66 -0
- package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
- package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
- package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
- package/native-src/src/librats/subsystems/pubsub.h +175 -0
- package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
- package/native-src/src/librats/subsystems/reconnection.h +126 -0
- package/native-src/src/librats/subsystems/relay.cpp +1142 -0
- package/native-src/src/librats/subsystems/relay.h +211 -0
- package/native-src/src/librats/subsystems/relay_service.h +46 -0
- package/native-src/src/librats/transport/connection.cpp +343 -0
- package/native-src/src/librats/transport/connection.h +283 -0
- package/native-src/src/librats/transport/link.h +96 -0
- package/native-src/src/librats/transport/reactor.cpp +588 -0
- package/native-src/src/librats/transport/reactor.h +262 -0
- package/native-src/src/librats/transport/reactor_pool.h +81 -0
- package/native-src/src/librats/transport/relay_link.cpp +208 -0
- package/native-src/src/librats/transport/relay_link.h +303 -0
- package/native-src/src/librats/transport/tcp_link.cpp +49 -0
- package/native-src/src/librats/transport/tcp_link.h +43 -0
- package/native-src/src/librats/transport/udp_mux.cpp +617 -0
- package/native-src/src/librats/transport/udp_mux.h +363 -0
- package/native-src/src/librats/transport/udp_packet.cpp +121 -0
- package/native-src/src/librats/transport/udp_packet.h +190 -0
- package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
- package/native-src/src/librats/transport/udp_stream.h +614 -0
- package/native-src/src/librats/util/features.h.in +51 -0
- package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
- package/native-src/src/librats/util/fs.h +136 -0
- package/native-src/src/librats/util/json.cpp +1002 -0
- package/native-src/src/librats/util/json.h +444 -0
- package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
- package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
- package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
- package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
- package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
- package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
- package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
- package/native-src/src/librats/util/rats_export.h +69 -0
- package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
- package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
- package/native-src/src/librats/wire/frame.cpp +76 -0
- package/native-src/src/librats/wire/frame.h +111 -0
- package/native-src/src/librats/wire/message_router.cpp +45 -0
- package/native-src/src/librats/wire/message_router.h +47 -0
- package/package.json +5 -4
- package/scripts/build-librats.js +1 -0
- package/scripts/postinstall.js +3 -3
- package/scripts/prepare-package.js +4 -4
- package/scripts/verify-installation.js +63 -105
- package/src/librats_node.cpp +1067 -1323
- package/native-src/src/bencode.cpp +0 -485
- package/native-src/src/bencode.h +0 -145
- package/native-src/src/bittorrent.cpp +0 -14
- package/native-src/src/bittorrent.h +0 -74
- package/native-src/src/bt_bitfield.cpp +0 -372
- package/native-src/src/bt_bitfield.h +0 -316
- package/native-src/src/bt_choker.cpp +0 -228
- package/native-src/src/bt_choker.h +0 -147
- package/native-src/src/bt_client.cpp +0 -1047
- package/native-src/src/bt_client.h +0 -445
- package/native-src/src/bt_create_torrent.cpp +0 -677
- package/native-src/src/bt_create_torrent.h +0 -473
- package/native-src/src/bt_extension.cpp +0 -469
- package/native-src/src/bt_extension.h +0 -309
- package/native-src/src/bt_file_storage.cpp +0 -261
- package/native-src/src/bt_file_storage.h +0 -298
- package/native-src/src/bt_handshake.cpp +0 -134
- package/native-src/src/bt_handshake.h +0 -157
- package/native-src/src/bt_messages.cpp +0 -364
- package/native-src/src/bt_messages.h +0 -324
- package/native-src/src/bt_network.cpp +0 -1007
- package/native-src/src/bt_network.h +0 -417
- package/native-src/src/bt_peer_connection.cpp +0 -742
- package/native-src/src/bt_peer_connection.h +0 -592
- package/native-src/src/bt_piece_picker.cpp +0 -786
- package/native-src/src/bt_piece_picker.h +0 -473
- package/native-src/src/bt_resume_data.cpp +0 -410
- package/native-src/src/bt_resume_data.h +0 -249
- package/native-src/src/bt_torrent.cpp +0 -2120
- package/native-src/src/bt_torrent.h +0 -641
- package/native-src/src/bt_torrent_info.cpp +0 -659
- package/native-src/src/bt_torrent_info.h +0 -418
- package/native-src/src/bt_types.h +0 -621
- package/native-src/src/chained_send_buffer.cpp +0 -75
- package/native-src/src/chained_send_buffer.h +0 -137
- package/native-src/src/crypto/hkdf.c +0 -266
- package/native-src/src/crypto/poly1305.h +0 -36
- package/native-src/src/dht.cpp +0 -3311
- package/native-src/src/dht.h +0 -717
- package/native-src/src/disk_io.cpp +0 -632
- package/native-src/src/disk_io.h +0 -315
- package/native-src/src/file_transfer.cpp +0 -1415
- package/native-src/src/file_transfer.h +0 -286
- package/native-src/src/fs.h +0 -108
- package/native-src/src/gossipsub.cpp +0 -1139
- package/native-src/src/gossipsub.h +0 -403
- package/native-src/src/ice.cpp +0 -893
- package/native-src/src/ice.h +0 -559
- package/native-src/src/json.hpp +0 -25526
- package/native-src/src/librats.cpp +0 -2378
- package/native-src/src/librats.h +0 -2324
- package/native-src/src/librats_bittorrent.cpp +0 -601
- package/native-src/src/librats_c.cpp +0 -1557
- package/native-src/src/librats_c.h +0 -323
- package/native-src/src/librats_discovery.cpp +0 -402
- package/native-src/src/librats_encryption.cpp +0 -275
- package/native-src/src/librats_file_transfer.cpp +0 -144
- package/native-src/src/librats_gossipsub.cpp +0 -289
- package/native-src/src/librats_ice.cpp +0 -213
- package/native-src/src/librats_log_macros.h +0 -36
- package/native-src/src/librats_logging.cpp +0 -173
- package/native-src/src/librats_mdns.cpp +0 -166
- package/native-src/src/librats_persistence.cpp +0 -796
- package/native-src/src/librats_portmap.cpp +0 -419
- package/native-src/src/librats_reconnection.cpp +0 -218
- package/native-src/src/librats_statistic.cpp +0 -105
- package/native-src/src/librats_storage.cpp +0 -189
- package/native-src/src/rats_export.h +0 -17
- package/native-src/src/receive_buffer.cpp +0 -82
- package/native-src/src/receive_buffer.h +0 -127
- package/native-src/src/socket.h +0 -228
- package/native-src/src/threadmanager.cpp +0 -105
- package/native-src/src/threadmanager.h +0 -53
- package/native-src/src/tracker.cpp +0 -1264
- package/native-src/src/tracker.h +0 -319
- package/native-src/src/turn.cpp +0 -762
- package/native-src/src/turn.h +0 -460
- package/native-src/src/wakeup_pipe.h +0 -60
- /package/native-src/src/{os.h → librats/util/os.h} +0 -0
|
@@ -1,601 +0,0 @@
|
|
|
1
|
-
#include "librats.h"
|
|
2
|
-
#include "bt_create_torrent.h"
|
|
3
|
-
#include "fs.h"
|
|
4
|
-
|
|
5
|
-
#ifdef RATS_SEARCH_FEATURES
|
|
6
|
-
|
|
7
|
-
#include "librats_log_macros.h"
|
|
8
|
-
|
|
9
|
-
namespace librats {
|
|
10
|
-
|
|
11
|
-
//=============================================================================
|
|
12
|
-
// BitTorrent API Implementation (requires RATS_SEARCH_FEATURES)
|
|
13
|
-
//=============================================================================
|
|
14
|
-
|
|
15
|
-
bool RatsClient::enable_bittorrent(int listen_port) {
|
|
16
|
-
if (bittorrent_client_) {
|
|
17
|
-
LOG_CLIENT_WARN("BitTorrent is already enabled");
|
|
18
|
-
return true; // Already enabled
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
LOG_CLIENT_INFO("Enabling BitTorrent on port " << listen_port);
|
|
22
|
-
|
|
23
|
-
BtClientConfig config;
|
|
24
|
-
config.listen_port = static_cast<uint16_t>(listen_port);
|
|
25
|
-
config.enable_dht = (dht_client_ && dht_client_->is_running());
|
|
26
|
-
|
|
27
|
-
bittorrent_client_ = std::make_unique<BitTorrentClient>(config);
|
|
28
|
-
|
|
29
|
-
// Reuse librats DHT client instead of creating a new one
|
|
30
|
-
if (dht_client_ && dht_client_->is_running()) {
|
|
31
|
-
bittorrent_client_->set_external_dht(dht_client_.get());
|
|
32
|
-
LOG_CLIENT_INFO("BitTorrent will reuse librats DHT client with "
|
|
33
|
-
<< dht_client_->get_routing_table_size() << " nodes");
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
bittorrent_client_->start();
|
|
37
|
-
|
|
38
|
-
if (!bittorrent_client_->is_running()) {
|
|
39
|
-
LOG_CLIENT_ERROR("Failed to start BitTorrent client");
|
|
40
|
-
bittorrent_client_.reset();
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
LOG_CLIENT_INFO("BitTorrent enabled successfully");
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
void RatsClient::set_resume_data_path(const std::string& path) {
|
|
49
|
-
if (!bittorrent_client_) {
|
|
50
|
-
LOG_CLIENT_WARN("Cannot set resume data path: BitTorrent not enabled");
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
bittorrent_client_->set_resume_data_path(path);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
void RatsClient::disable_bittorrent() {
|
|
58
|
-
if (!bittorrent_client_) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
LOG_CLIENT_INFO("Disabling BitTorrent");
|
|
63
|
-
bittorrent_client_->stop();
|
|
64
|
-
bittorrent_client_.reset();
|
|
65
|
-
LOG_CLIENT_INFO("BitTorrent disabled");
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
bool RatsClient::is_bittorrent_enabled() const {
|
|
69
|
-
return bittorrent_client_ && bittorrent_client_->is_running();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
std::shared_ptr<TorrentDownload> RatsClient::add_torrent(const std::string& torrent_file,
|
|
73
|
-
const std::string& download_path) {
|
|
74
|
-
if (!is_bittorrent_enabled()) {
|
|
75
|
-
LOG_CLIENT_ERROR("BitTorrent is not enabled. Call enable_bittorrent() first.");
|
|
76
|
-
return nullptr;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return bittorrent_client_->add_torrent_file(torrent_file, download_path);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
std::shared_ptr<TorrentDownload> RatsClient::add_torrent(const TorrentInfo& torrent_info,
|
|
83
|
-
const std::string& download_path) {
|
|
84
|
-
if (!is_bittorrent_enabled()) {
|
|
85
|
-
LOG_CLIENT_ERROR("BitTorrent is not enabled. Call enable_bittorrent() first.");
|
|
86
|
-
return nullptr;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return bittorrent_client_->add_torrent(torrent_info, download_path);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
std::shared_ptr<TorrentDownload> RatsClient::add_torrent_by_hash(const InfoHash& info_hash,
|
|
93
|
-
const std::string& download_path) {
|
|
94
|
-
if (!is_bittorrent_enabled()) {
|
|
95
|
-
LOG_CLIENT_ERROR("BitTorrent is not enabled. Call enable_bittorrent() first.");
|
|
96
|
-
return nullptr;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Create magnet-style URI from hash
|
|
100
|
-
std::string hash_hex = info_hash_to_hex(info_hash);
|
|
101
|
-
std::string magnet = "magnet:?xt=urn:btih:" + hash_hex;
|
|
102
|
-
return bittorrent_client_->add_magnet(magnet, download_path);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
std::shared_ptr<TorrentDownload> RatsClient::add_torrent_by_hash(const std::string& info_hash_hex,
|
|
106
|
-
const std::string& download_path) {
|
|
107
|
-
if (!is_bittorrent_enabled()) {
|
|
108
|
-
LOG_CLIENT_ERROR("BitTorrent is not enabled. Call enable_bittorrent() first.");
|
|
109
|
-
return nullptr;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
std::string magnet = "magnet:?xt=urn:btih:" + info_hash_hex;
|
|
113
|
-
return bittorrent_client_->add_magnet(magnet, download_path);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
bool RatsClient::remove_torrent(const InfoHash& info_hash) {
|
|
117
|
-
if (!is_bittorrent_enabled()) {
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
bittorrent_client_->remove_torrent(info_hash);
|
|
122
|
-
return true;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
std::shared_ptr<TorrentDownload> RatsClient::get_torrent(const InfoHash& info_hash) {
|
|
126
|
-
if (!is_bittorrent_enabled()) {
|
|
127
|
-
return nullptr;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return bittorrent_client_->get_torrent(info_hash);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
std::vector<std::shared_ptr<TorrentDownload>> RatsClient::get_all_torrents() {
|
|
134
|
-
if (!is_bittorrent_enabled()) {
|
|
135
|
-
return {};
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return bittorrent_client_->get_torrents();
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
size_t RatsClient::get_active_torrents_count() const {
|
|
142
|
-
if (!is_bittorrent_enabled()) {
|
|
143
|
-
return 0;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return bittorrent_client_->num_torrents();
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
std::pair<uint64_t, uint64_t> RatsClient::get_bittorrent_stats() const {
|
|
150
|
-
if (!is_bittorrent_enabled()) {
|
|
151
|
-
return {0, 0};
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Get stats from all torrents
|
|
155
|
-
uint64_t total_downloaded = 0;
|
|
156
|
-
uint64_t total_uploaded = 0;
|
|
157
|
-
|
|
158
|
-
auto torrents = bittorrent_client_->get_torrents();
|
|
159
|
-
for (const auto& t : torrents) {
|
|
160
|
-
auto stats = t->stats();
|
|
161
|
-
total_downloaded += stats.total_downloaded;
|
|
162
|
-
total_uploaded += stats.total_uploaded;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return {total_downloaded, total_uploaded};
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
void RatsClient::get_torrent_metadata(const InfoHash& info_hash,
|
|
169
|
-
std::function<void(const TorrentInfo&, bool, const std::string&)> callback) {
|
|
170
|
-
if (!is_bittorrent_enabled()) {
|
|
171
|
-
LOG_CLIENT_ERROR("BitTorrent is not enabled. Call enable_bittorrent() first.");
|
|
172
|
-
if (callback) {
|
|
173
|
-
callback(TorrentInfo(), false, "BitTorrent is not enabled");
|
|
174
|
-
}
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Add torrent in metadata-only mode (empty save_path), then retrieve info when complete
|
|
179
|
-
std::string hash_hex = info_hash_to_hex(info_hash);
|
|
180
|
-
std::string magnet = "magnet:?xt=urn:btih:" + hash_hex;
|
|
181
|
-
auto torrent = bittorrent_client_->add_magnet(magnet, "");
|
|
182
|
-
|
|
183
|
-
if (!torrent) {
|
|
184
|
-
if (callback) {
|
|
185
|
-
callback(TorrentInfo(), false, "Failed to add magnet link");
|
|
186
|
-
}
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// If metadata is already available, return immediately and cleanup
|
|
191
|
-
if (torrent->has_metadata()) {
|
|
192
|
-
if (callback) {
|
|
193
|
-
callback(*torrent->info(), true, "");
|
|
194
|
-
}
|
|
195
|
-
// Cleanup metadata-only torrent (empty save_path means no download requested)
|
|
196
|
-
if (torrent->save_path().empty()) {
|
|
197
|
-
bittorrent_client_->mark_for_removal(info_hash);
|
|
198
|
-
}
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Set up async callback for when metadata is received
|
|
203
|
-
// Capture bittorrent_client_ and info_hash for cleanup after callback
|
|
204
|
-
auto client = bittorrent_client_.get();
|
|
205
|
-
torrent->set_metadata_callback(
|
|
206
|
-
[callback, client, info_hash](Torrent* t, bool success) {
|
|
207
|
-
// Invoke user callback first
|
|
208
|
-
if (success && t->info()) {
|
|
209
|
-
if (callback) {
|
|
210
|
-
callback(*t->info(), true, "");
|
|
211
|
-
}
|
|
212
|
-
} else {
|
|
213
|
-
if (callback) {
|
|
214
|
-
callback(TorrentInfo(), false, "Failed to download metadata");
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Cleanup metadata-only torrent (empty save_path means no download requested)
|
|
219
|
-
// Using mark_for_removal to avoid deadlock (callback is called from I/O thread)
|
|
220
|
-
if (client && t->save_path().empty()) {
|
|
221
|
-
client->mark_for_removal(info_hash);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
);
|
|
225
|
-
|
|
226
|
-
LOG_CLIENT_INFO("Waiting for metadata download for " << hash_hex.substr(0, 8) << "...");
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
void RatsClient::get_torrent_metadata(const std::string& info_hash_hex,
|
|
230
|
-
std::function<void(const TorrentInfo&, bool, const std::string&)> callback) {
|
|
231
|
-
auto hash = hex_to_info_hash(info_hash_hex);
|
|
232
|
-
get_torrent_metadata(hash, callback);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
void RatsClient::get_torrent_metadata_from_peer(const InfoHash& info_hash,
|
|
236
|
-
const std::string& peer_ip,
|
|
237
|
-
uint16_t peer_port,
|
|
238
|
-
std::function<void(const TorrentInfo&, bool, const std::string&)> callback) {
|
|
239
|
-
if (!is_bittorrent_enabled()) {
|
|
240
|
-
LOG_CLIENT_ERROR("BitTorrent is not enabled. Call enable_bittorrent() first.");
|
|
241
|
-
if (callback) {
|
|
242
|
-
callback(TorrentInfo(), false, "BitTorrent is not enabled");
|
|
243
|
-
}
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
LOG_CLIENT_INFO("Fetching metadata from peer " << peer_ip << ":" << peer_port << " (fast path, no DHT)");
|
|
248
|
-
|
|
249
|
-
// Add magnet in metadata-only mode (empty save_path) and immediately add the peer
|
|
250
|
-
// skip_dht_search=true to avoid network-wide DHT queries - we only want this specific peer
|
|
251
|
-
std::string hash_hex = info_hash_to_hex(info_hash);
|
|
252
|
-
std::string magnet = "magnet:?xt=urn:btih:" + hash_hex;
|
|
253
|
-
auto torrent = bittorrent_client_->add_magnet(magnet, "", true /* skip_dht_search */);
|
|
254
|
-
|
|
255
|
-
if (!torrent) {
|
|
256
|
-
if (callback) {
|
|
257
|
-
callback(TorrentInfo(), false, "Failed to add magnet");
|
|
258
|
-
}
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// Add the specific peer for direct connection
|
|
263
|
-
torrent->add_peer(peer_ip, peer_port);
|
|
264
|
-
|
|
265
|
-
// If metadata is already available, return immediately and cleanup
|
|
266
|
-
if (torrent->has_metadata()) {
|
|
267
|
-
if (callback) {
|
|
268
|
-
callback(*torrent->info(), true, "");
|
|
269
|
-
}
|
|
270
|
-
// Cleanup metadata-only torrent
|
|
271
|
-
if (torrent->save_path().empty()) {
|
|
272
|
-
bittorrent_client_->mark_for_removal(info_hash);
|
|
273
|
-
}
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// Set up async callback for when metadata is received
|
|
278
|
-
// Capture bittorrent_client_ and info_hash for cleanup after callback
|
|
279
|
-
auto client = bittorrent_client_.get();
|
|
280
|
-
torrent->set_metadata_callback(
|
|
281
|
-
[callback, client, info_hash, peer_ip, peer_port](Torrent* t, bool success) {
|
|
282
|
-
// Invoke user callback first
|
|
283
|
-
if (success && t->info()) {
|
|
284
|
-
if (callback) {
|
|
285
|
-
callback(*t->info(), true, "");
|
|
286
|
-
}
|
|
287
|
-
} else {
|
|
288
|
-
if (callback) {
|
|
289
|
-
callback(TorrentInfo(), false,
|
|
290
|
-
"Failed to download metadata from " + peer_ip + ":" + std::to_string(peer_port));
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// Cleanup metadata-only torrent (empty save_path means no download requested)
|
|
295
|
-
// Using mark_for_removal to avoid deadlock (callback is called from I/O thread)
|
|
296
|
-
if (client && t->save_path().empty()) {
|
|
297
|
-
client->mark_for_removal(info_hash);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
);
|
|
301
|
-
|
|
302
|
-
LOG_CLIENT_INFO("Waiting for metadata from " << peer_ip << ":" << peer_port);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
void RatsClient::get_torrent_metadata_from_peer(const std::string& info_hash_hex,
|
|
306
|
-
const std::string& peer_ip,
|
|
307
|
-
uint16_t peer_port,
|
|
308
|
-
std::function<void(const TorrentInfo&, bool, const std::string&)> callback) {
|
|
309
|
-
auto hash = hex_to_info_hash(info_hash_hex);
|
|
310
|
-
get_torrent_metadata_from_peer(hash, peer_ip, peer_port, callback);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
//=============================================================================
|
|
314
|
-
// Spider Mode API Implementation (requires RATS_SEARCH_FEATURES)
|
|
315
|
-
//=============================================================================
|
|
316
|
-
|
|
317
|
-
void RatsClient::set_spider_mode(bool enable) {
|
|
318
|
-
if (!dht_client_) {
|
|
319
|
-
LOG_CLIENT_WARN("DHT client not available, cannot set spider mode");
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
dht_client_->set_spider_mode(enable);
|
|
324
|
-
LOG_CLIENT_INFO("Spider mode " << (enable ? "enabled" : "disabled"));
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
bool RatsClient::is_spider_mode() const {
|
|
328
|
-
if (!dht_client_) {
|
|
329
|
-
return false;
|
|
330
|
-
}
|
|
331
|
-
return dht_client_->is_spider_mode();
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
void RatsClient::set_spider_announce_callback(SpiderAnnounceCallback callback) {
|
|
335
|
-
if (!dht_client_) {
|
|
336
|
-
LOG_CLIENT_WARN("DHT client not available, cannot set spider callback");
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
// Wrap the callback to convert types from DhtClient format to RatsClient format
|
|
341
|
-
dht_client_->set_spider_announce_callback(
|
|
342
|
-
[callback](const InfoHash& info_hash, const Peer& peer) {
|
|
343
|
-
if (callback) {
|
|
344
|
-
std::string info_hash_hex = node_id_to_hex(info_hash);
|
|
345
|
-
std::string peer_address = peer.ip + ":" + std::to_string(peer.port);
|
|
346
|
-
callback(info_hash_hex, peer_address);
|
|
347
|
-
}
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
LOG_CLIENT_DEBUG("Spider announce callback set");
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
void RatsClient::set_spider_ignore(bool ignore) {
|
|
354
|
-
if (!dht_client_) {
|
|
355
|
-
LOG_CLIENT_WARN("DHT client not available, cannot set spider ignore");
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
dht_client_->set_spider_ignore(ignore);
|
|
360
|
-
LOG_CLIENT_DEBUG("Spider ignore mode " << (ignore ? "enabled" : "disabled"));
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
bool RatsClient::is_spider_ignoring() const {
|
|
364
|
-
if (!dht_client_) {
|
|
365
|
-
return false;
|
|
366
|
-
}
|
|
367
|
-
return dht_client_->is_spider_ignoring();
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
void RatsClient::spider_walk() {
|
|
371
|
-
if (!dht_client_) {
|
|
372
|
-
return;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
dht_client_->spider_walk();
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
size_t RatsClient::get_spider_pool_size() const {
|
|
379
|
-
if (!dht_client_) {
|
|
380
|
-
return 0;
|
|
381
|
-
}
|
|
382
|
-
return dht_client_->get_spider_pool_size();
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
size_t RatsClient::get_spider_visited_count() const {
|
|
386
|
-
if (!dht_client_) {
|
|
387
|
-
return 0;
|
|
388
|
-
}
|
|
389
|
-
return dht_client_->get_spider_visited_count();
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
void RatsClient::clear_spider_state() {
|
|
393
|
-
if (!dht_client_) {
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
dht_client_->clear_spider_state();
|
|
397
|
-
LOG_CLIENT_DEBUG("Spider state cleared");
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
//=============================================================================
|
|
401
|
-
// Torrent Creation API Implementation (requires RATS_SEARCH_FEATURES)
|
|
402
|
-
//=============================================================================
|
|
403
|
-
|
|
404
|
-
std::optional<TorrentInfo> RatsClient::create_torrent_from_path(
|
|
405
|
-
const std::string& path,
|
|
406
|
-
const std::vector<std::string>& trackers,
|
|
407
|
-
const std::string& comment,
|
|
408
|
-
TorrentCreationProgressCallback progress_callback) {
|
|
409
|
-
|
|
410
|
-
LOG_CLIENT_INFO("Creating torrent from path: " << path);
|
|
411
|
-
|
|
412
|
-
TorrentCreatorConfig config;
|
|
413
|
-
config.comment = comment;
|
|
414
|
-
config.created_by = "librats";
|
|
415
|
-
|
|
416
|
-
TorrentCreator creator(path, config);
|
|
417
|
-
|
|
418
|
-
if (creator.num_files() == 0) {
|
|
419
|
-
LOG_CLIENT_ERROR("No files found at path: " << path);
|
|
420
|
-
return std::nullopt;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
for (const auto& tracker : trackers) {
|
|
424
|
-
creator.add_tracker(tracker);
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// Convert progress callback
|
|
428
|
-
PieceHashProgressCallback hash_callback = nullptr;
|
|
429
|
-
if (progress_callback) {
|
|
430
|
-
hash_callback = [progress_callback](uint32_t current, uint32_t total) {
|
|
431
|
-
progress_callback(current, total);
|
|
432
|
-
};
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
TorrentCreateError error;
|
|
436
|
-
if (!creator.set_piece_hashes(hash_callback, &error)) {
|
|
437
|
-
LOG_CLIENT_ERROR("Failed to compute piece hashes: " << error.message);
|
|
438
|
-
return std::nullopt;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
auto result = creator.generate_torrent_info(&error);
|
|
442
|
-
if (!result) {
|
|
443
|
-
LOG_CLIENT_ERROR("Failed to generate torrent: " << error.message);
|
|
444
|
-
return std::nullopt;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
LOG_CLIENT_INFO("Torrent created successfully: " << result->name()
|
|
448
|
-
<< " (" << result->num_files() << " files, "
|
|
449
|
-
<< result->total_size() << " bytes, "
|
|
450
|
-
<< "info_hash: " << result->info_hash_hex().substr(0, 8) << "...)");
|
|
451
|
-
|
|
452
|
-
return result;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
std::vector<uint8_t> RatsClient::create_torrent_data(
|
|
456
|
-
const std::string& path,
|
|
457
|
-
const std::vector<std::string>& trackers,
|
|
458
|
-
const std::string& comment,
|
|
459
|
-
TorrentCreationProgressCallback progress_callback) {
|
|
460
|
-
|
|
461
|
-
LOG_CLIENT_INFO("Creating torrent data from path: " << path);
|
|
462
|
-
|
|
463
|
-
TorrentCreatorConfig config;
|
|
464
|
-
config.comment = comment;
|
|
465
|
-
config.created_by = "librats";
|
|
466
|
-
|
|
467
|
-
TorrentCreator creator(path, config);
|
|
468
|
-
|
|
469
|
-
if (creator.num_files() == 0) {
|
|
470
|
-
LOG_CLIENT_ERROR("No files found at path: " << path);
|
|
471
|
-
return {};
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
for (const auto& tracker : trackers) {
|
|
475
|
-
creator.add_tracker(tracker);
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
// Convert progress callback
|
|
479
|
-
PieceHashProgressCallback hash_callback = nullptr;
|
|
480
|
-
if (progress_callback) {
|
|
481
|
-
hash_callback = [progress_callback](uint32_t current, uint32_t total) {
|
|
482
|
-
progress_callback(current, total);
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
TorrentCreateError error;
|
|
487
|
-
if (!creator.set_piece_hashes(hash_callback, &error)) {
|
|
488
|
-
LOG_CLIENT_ERROR("Failed to compute piece hashes: " << error.message);
|
|
489
|
-
return {};
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
auto data = creator.generate(&error);
|
|
493
|
-
if (data.empty()) {
|
|
494
|
-
LOG_CLIENT_ERROR("Failed to generate torrent: " << error.message);
|
|
495
|
-
return {};
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
LOG_CLIENT_INFO("Torrent data created successfully: " << creator.name()
|
|
499
|
-
<< " (" << data.size() << " bytes)");
|
|
500
|
-
|
|
501
|
-
return data;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
bool RatsClient::create_torrent_file(
|
|
505
|
-
const std::string& path,
|
|
506
|
-
const std::string& output_file,
|
|
507
|
-
const std::vector<std::string>& trackers,
|
|
508
|
-
const std::string& comment,
|
|
509
|
-
TorrentCreationProgressCallback progress_callback) {
|
|
510
|
-
|
|
511
|
-
LOG_CLIENT_INFO("Creating torrent file from path: " << path << " -> " << output_file);
|
|
512
|
-
|
|
513
|
-
TorrentCreatorConfig config;
|
|
514
|
-
config.comment = comment;
|
|
515
|
-
config.created_by = "librats";
|
|
516
|
-
|
|
517
|
-
TorrentCreator creator(path, config);
|
|
518
|
-
|
|
519
|
-
if (creator.num_files() == 0) {
|
|
520
|
-
LOG_CLIENT_ERROR("No files found at path: " << path);
|
|
521
|
-
return false;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
for (const auto& tracker : trackers) {
|
|
525
|
-
creator.add_tracker(tracker);
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
// Convert progress callback
|
|
529
|
-
PieceHashProgressCallback hash_callback = nullptr;
|
|
530
|
-
if (progress_callback) {
|
|
531
|
-
hash_callback = [progress_callback](uint32_t current, uint32_t total) {
|
|
532
|
-
progress_callback(current, total);
|
|
533
|
-
};
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
TorrentCreateError error;
|
|
537
|
-
if (!creator.set_piece_hashes(hash_callback, &error)) {
|
|
538
|
-
LOG_CLIENT_ERROR("Failed to compute piece hashes: " << error.message);
|
|
539
|
-
return false;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
if (!creator.save_to_file(output_file, &error)) {
|
|
543
|
-
LOG_CLIENT_ERROR("Failed to save torrent file: " << error.message);
|
|
544
|
-
return false;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
LOG_CLIENT_INFO("Torrent file created successfully: " << output_file);
|
|
548
|
-
|
|
549
|
-
return true;
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
std::shared_ptr<TorrentDownload> RatsClient::create_and_seed_torrent(
|
|
553
|
-
const std::string& path,
|
|
554
|
-
const std::vector<std::string>& trackers,
|
|
555
|
-
const std::string& comment,
|
|
556
|
-
TorrentCreationProgressCallback progress_callback) {
|
|
557
|
-
|
|
558
|
-
if (!is_bittorrent_enabled()) {
|
|
559
|
-
LOG_CLIENT_ERROR("BitTorrent is not enabled. Call enable_bittorrent() first.");
|
|
560
|
-
return nullptr;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
LOG_CLIENT_INFO("Creating and seeding torrent from path: " << path);
|
|
564
|
-
|
|
565
|
-
// Create torrent info
|
|
566
|
-
auto torrent_info = create_torrent_from_path(path, trackers, comment, progress_callback);
|
|
567
|
-
if (!torrent_info) {
|
|
568
|
-
return nullptr;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
// Determine save path (parent directory of the source)
|
|
572
|
-
std::string save_path;
|
|
573
|
-
if (is_directory(path.c_str())) {
|
|
574
|
-
// For directories, save_path is the parent of the directory
|
|
575
|
-
save_path = get_parent_directory(path);
|
|
576
|
-
if (save_path.empty()) {
|
|
577
|
-
save_path = ".";
|
|
578
|
-
}
|
|
579
|
-
} else {
|
|
580
|
-
// For single files, save_path is the directory containing the file
|
|
581
|
-
save_path = get_parent_directory(path);
|
|
582
|
-
if (save_path.empty()) {
|
|
583
|
-
save_path = ".";
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
// Add torrent with seed_mode enabled (files are already complete)
|
|
588
|
-
auto torrent = bittorrent_client_->add_torrent_for_seeding(*torrent_info, save_path);
|
|
589
|
-
if (!torrent) {
|
|
590
|
-
LOG_CLIENT_ERROR("Failed to add torrent for seeding");
|
|
591
|
-
return nullptr;
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
LOG_CLIENT_INFO("Started seeding torrent: " << torrent_info->info_hash_hex().substr(0, 8) << "...");
|
|
595
|
-
|
|
596
|
-
return torrent;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
#endif // RATS_SEARCH_FEATURES
|