librats 0.5.0 → 0.5.2
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 +1 -1
- package/binding.gyp +1 -0
- package/lib/index.d.ts +2 -1
- package/native-src/3rdparty/android/ifaddrs-android.c +600 -0
- package/native-src/3rdparty/android/ifaddrs-android.h +54 -0
- package/native-src/CMakeLists.txt +360 -0
- package/native-src/LICENSE +21 -0
- package/native-src/src/bencode.cpp +485 -0
- package/native-src/src/bencode.h +145 -0
- package/native-src/src/bittorrent.cpp +3682 -0
- package/native-src/src/bittorrent.h +731 -0
- package/native-src/src/dht.cpp +2460 -0
- package/native-src/src/dht.h +508 -0
- package/native-src/src/encrypted_socket.cpp +817 -0
- package/native-src/src/encrypted_socket.h +239 -0
- package/native-src/src/file_transfer.cpp +1808 -0
- package/native-src/src/file_transfer.h +567 -0
- package/native-src/src/fs.cpp +639 -0
- package/native-src/src/fs.h +108 -0
- package/native-src/src/gossipsub.cpp +1137 -0
- package/native-src/src/gossipsub.h +403 -0
- package/native-src/src/ice.cpp +1386 -0
- package/native-src/src/ice.h +328 -0
- package/native-src/src/json.hpp +25526 -0
- package/native-src/src/krpc.cpp +558 -0
- package/native-src/src/krpc.h +145 -0
- package/native-src/src/librats.cpp +2735 -0
- package/native-src/src/librats.h +1732 -0
- package/native-src/src/librats_bittorrent.cpp +167 -0
- package/native-src/src/librats_c.cpp +1333 -0
- package/native-src/src/librats_c.h +239 -0
- package/native-src/src/librats_encryption.cpp +123 -0
- package/native-src/src/librats_file_transfer.cpp +226 -0
- package/native-src/src/librats_gossipsub.cpp +293 -0
- package/native-src/src/librats_ice.cpp +515 -0
- package/native-src/src/librats_logging.cpp +158 -0
- package/native-src/src/librats_mdns.cpp +171 -0
- package/native-src/src/librats_nat.cpp +571 -0
- package/native-src/src/librats_persistence.cpp +815 -0
- package/native-src/src/logger.h +412 -0
- package/native-src/src/mdns.cpp +1178 -0
- package/native-src/src/mdns.h +253 -0
- package/native-src/src/network_utils.cpp +598 -0
- package/native-src/src/network_utils.h +162 -0
- package/native-src/src/noise.cpp +981 -0
- package/native-src/src/noise.h +227 -0
- package/native-src/src/os.cpp +371 -0
- package/native-src/src/os.h +40 -0
- package/native-src/src/rats_export.h +17 -0
- package/native-src/src/sha1.cpp +163 -0
- package/native-src/src/sha1.h +42 -0
- package/native-src/src/socket.cpp +1376 -0
- package/native-src/src/socket.h +309 -0
- package/native-src/src/stun.cpp +484 -0
- package/native-src/src/stun.h +349 -0
- package/native-src/src/threadmanager.cpp +105 -0
- package/native-src/src/threadmanager.h +53 -0
- package/native-src/src/tracker.cpp +1110 -0
- package/native-src/src/tracker.h +268 -0
- package/native-src/src/version.cpp +24 -0
- package/native-src/src/version.h.in +45 -0
- package/native-src/version.rc.in +31 -0
- package/package.json +2 -8
- package/scripts/build-librats.js +59 -12
- package/scripts/prepare-package.js +133 -37
- package/src/librats_node.cpp +46 -1
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "bittorrent.h"
|
|
4
|
+
#include "socket.h"
|
|
5
|
+
#include <string>
|
|
6
|
+
#include <vector>
|
|
7
|
+
#include <memory>
|
|
8
|
+
#include <functional>
|
|
9
|
+
#include <chrono>
|
|
10
|
+
#include <atomic>
|
|
11
|
+
#include <mutex>
|
|
12
|
+
|
|
13
|
+
namespace librats {
|
|
14
|
+
|
|
15
|
+
// Forward declarations
|
|
16
|
+
class TrackerClient;
|
|
17
|
+
class HttpTrackerClient;
|
|
18
|
+
class UdpTrackerClient;
|
|
19
|
+
|
|
20
|
+
// Tracker announce event types (BEP 3)
|
|
21
|
+
enum class TrackerEvent {
|
|
22
|
+
NONE = 0,
|
|
23
|
+
COMPLETED = 1,
|
|
24
|
+
STARTED = 2,
|
|
25
|
+
STOPPED = 3
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Tracker response structure
|
|
29
|
+
struct TrackerResponse {
|
|
30
|
+
std::string failure_reason;
|
|
31
|
+
std::string warning_message;
|
|
32
|
+
uint32_t interval; // Seconds until next announce
|
|
33
|
+
uint32_t min_interval; // Minimum announce interval
|
|
34
|
+
std::string tracker_id; // Tracker ID for subsequent requests
|
|
35
|
+
uint32_t complete; // Number of seeders
|
|
36
|
+
uint32_t incomplete; // Number of leechers
|
|
37
|
+
uint32_t downloaded; // Number of times downloaded (scrape only)
|
|
38
|
+
std::vector<Peer> peers; // Peer list
|
|
39
|
+
bool success;
|
|
40
|
+
|
|
41
|
+
TrackerResponse()
|
|
42
|
+
: interval(1800), min_interval(900), complete(0), incomplete(0),
|
|
43
|
+
downloaded(0), success(false) {}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Tracker announce request parameters
|
|
47
|
+
struct TrackerRequest {
|
|
48
|
+
InfoHash info_hash;
|
|
49
|
+
PeerID peer_id;
|
|
50
|
+
uint16_t port;
|
|
51
|
+
uint64_t uploaded;
|
|
52
|
+
uint64_t downloaded;
|
|
53
|
+
uint64_t left;
|
|
54
|
+
TrackerEvent event;
|
|
55
|
+
std::string ip; // Optional IP address
|
|
56
|
+
uint32_t numwant; // Number of peers wanted (default 50)
|
|
57
|
+
std::string tracker_id; // Tracker ID from previous response
|
|
58
|
+
|
|
59
|
+
TrackerRequest()
|
|
60
|
+
: port(0), uploaded(0), downloaded(0), left(0),
|
|
61
|
+
event(TrackerEvent::NONE), numwant(50) {}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Callback for tracker responses
|
|
65
|
+
using TrackerResponseCallback = std::function<void(const TrackerResponse& response, const std::string& tracker_url)>;
|
|
66
|
+
|
|
67
|
+
// Base tracker client interface
|
|
68
|
+
class TrackerClient {
|
|
69
|
+
public:
|
|
70
|
+
virtual ~TrackerClient() = default;
|
|
71
|
+
|
|
72
|
+
// Announce to tracker
|
|
73
|
+
virtual bool announce(const TrackerRequest& request, TrackerResponseCallback callback) = 0;
|
|
74
|
+
|
|
75
|
+
// Scrape tracker (optional, not all trackers support this)
|
|
76
|
+
virtual bool scrape(const std::vector<InfoHash>& info_hashes, TrackerResponseCallback callback) = 0;
|
|
77
|
+
|
|
78
|
+
// Get tracker URL
|
|
79
|
+
virtual std::string get_url() const = 0;
|
|
80
|
+
|
|
81
|
+
// Get last announce time
|
|
82
|
+
virtual std::chrono::steady_clock::time_point get_last_announce_time() const = 0;
|
|
83
|
+
|
|
84
|
+
// Get announce interval
|
|
85
|
+
virtual uint32_t get_interval() const = 0;
|
|
86
|
+
|
|
87
|
+
// Check if tracker is working
|
|
88
|
+
virtual bool is_working() const = 0;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// HTTP/HTTPS Tracker Client (BEP 3)
|
|
92
|
+
class HttpTrackerClient : public TrackerClient {
|
|
93
|
+
public:
|
|
94
|
+
explicit HttpTrackerClient(const std::string& tracker_url);
|
|
95
|
+
~HttpTrackerClient() override;
|
|
96
|
+
|
|
97
|
+
bool announce(const TrackerRequest& request, TrackerResponseCallback callback) override;
|
|
98
|
+
bool scrape(const std::vector<InfoHash>& info_hashes, TrackerResponseCallback callback) override;
|
|
99
|
+
|
|
100
|
+
std::string get_url() const override { return tracker_url_; }
|
|
101
|
+
std::chrono::steady_clock::time_point get_last_announce_time() const override { return last_announce_time_; }
|
|
102
|
+
uint32_t get_interval() const override { return interval_; }
|
|
103
|
+
bool is_working() const override { return is_working_; }
|
|
104
|
+
|
|
105
|
+
private:
|
|
106
|
+
std::string tracker_url_;
|
|
107
|
+
std::chrono::steady_clock::time_point last_announce_time_;
|
|
108
|
+
uint32_t interval_;
|
|
109
|
+
std::atomic<bool> is_working_;
|
|
110
|
+
std::string tracker_id_;
|
|
111
|
+
|
|
112
|
+
// Build announce URL with parameters
|
|
113
|
+
std::string build_announce_url(const TrackerRequest& request);
|
|
114
|
+
|
|
115
|
+
// Build scrape URL
|
|
116
|
+
std::string build_scrape_url(const std::vector<InfoHash>& info_hashes);
|
|
117
|
+
|
|
118
|
+
// Parse tracker response (bencode format)
|
|
119
|
+
TrackerResponse parse_response(const std::vector<uint8_t>& data);
|
|
120
|
+
|
|
121
|
+
// Parse compact peer list (BEP 23)
|
|
122
|
+
std::vector<Peer> parse_compact_peers(const std::string& peer_data);
|
|
123
|
+
|
|
124
|
+
// Parse dictionary peer list
|
|
125
|
+
std::vector<Peer> parse_dict_peers(const BencodeValue& peers_list);
|
|
126
|
+
|
|
127
|
+
// HTTP GET request
|
|
128
|
+
std::vector<uint8_t> http_get(const std::string& url);
|
|
129
|
+
|
|
130
|
+
// URL encode string
|
|
131
|
+
std::string url_encode(const std::string& str);
|
|
132
|
+
|
|
133
|
+
// URL encode binary data (for info_hash)
|
|
134
|
+
std::string url_encode_binary(const uint8_t* data, size_t len);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// UDP Tracker Client (BEP 15)
|
|
138
|
+
class UdpTrackerClient : public TrackerClient {
|
|
139
|
+
public:
|
|
140
|
+
explicit UdpTrackerClient(const std::string& tracker_url);
|
|
141
|
+
~UdpTrackerClient() override;
|
|
142
|
+
|
|
143
|
+
bool announce(const TrackerRequest& request, TrackerResponseCallback callback) override;
|
|
144
|
+
bool scrape(const std::vector<InfoHash>& info_hashes, TrackerResponseCallback callback) override;
|
|
145
|
+
|
|
146
|
+
std::string get_url() const override { return tracker_url_; }
|
|
147
|
+
std::chrono::steady_clock::time_point get_last_announce_time() const override { return last_announce_time_; }
|
|
148
|
+
uint32_t get_interval() const override { return interval_; }
|
|
149
|
+
bool is_working() const override { return is_working_; }
|
|
150
|
+
|
|
151
|
+
private:
|
|
152
|
+
std::string tracker_url_;
|
|
153
|
+
std::string hostname_;
|
|
154
|
+
uint16_t port_;
|
|
155
|
+
socket_t socket_;
|
|
156
|
+
std::chrono::steady_clock::time_point last_announce_time_;
|
|
157
|
+
std::chrono::steady_clock::time_point connection_expire_time_;
|
|
158
|
+
uint32_t interval_;
|
|
159
|
+
std::atomic<bool> is_working_;
|
|
160
|
+
int64_t connection_id_;
|
|
161
|
+
std::mutex socket_mutex_;
|
|
162
|
+
|
|
163
|
+
// UDP tracker protocol constants
|
|
164
|
+
static constexpr int64_t PROTOCOL_ID = 0x41727101980LL;
|
|
165
|
+
static constexpr uint32_t ACTION_CONNECT = 0;
|
|
166
|
+
static constexpr uint32_t ACTION_ANNOUNCE = 1;
|
|
167
|
+
static constexpr uint32_t ACTION_SCRAPE = 2;
|
|
168
|
+
static constexpr uint32_t ACTION_ERROR = 3;
|
|
169
|
+
|
|
170
|
+
// Parse tracker URL
|
|
171
|
+
bool parse_url();
|
|
172
|
+
|
|
173
|
+
// Connect to UDP tracker (get connection ID)
|
|
174
|
+
bool connect();
|
|
175
|
+
|
|
176
|
+
// Check if connection is still valid
|
|
177
|
+
bool is_connection_valid();
|
|
178
|
+
|
|
179
|
+
// Send UDP request and receive response
|
|
180
|
+
std::vector<uint8_t> send_request(const std::vector<uint8_t>& request, int timeout_ms = 15000);
|
|
181
|
+
|
|
182
|
+
// Build connect request
|
|
183
|
+
std::vector<uint8_t> build_connect_request(uint32_t transaction_id);
|
|
184
|
+
|
|
185
|
+
// Build announce request
|
|
186
|
+
std::vector<uint8_t> build_announce_request(const TrackerRequest& request, uint32_t transaction_id);
|
|
187
|
+
|
|
188
|
+
// Build scrape request
|
|
189
|
+
std::vector<uint8_t> build_scrape_request(const std::vector<InfoHash>& info_hashes, uint32_t transaction_id);
|
|
190
|
+
|
|
191
|
+
// Parse connect response
|
|
192
|
+
bool parse_connect_response(const std::vector<uint8_t>& data, uint32_t expected_transaction_id);
|
|
193
|
+
|
|
194
|
+
// Parse announce response
|
|
195
|
+
TrackerResponse parse_announce_response(const std::vector<uint8_t>& data, uint32_t expected_transaction_id);
|
|
196
|
+
|
|
197
|
+
// Parse scrape response
|
|
198
|
+
TrackerResponse parse_scrape_response(const std::vector<uint8_t>& data, uint32_t expected_transaction_id);
|
|
199
|
+
|
|
200
|
+
// Parse error response
|
|
201
|
+
std::string parse_error_response(const std::vector<uint8_t>& data);
|
|
202
|
+
|
|
203
|
+
// Generate random transaction ID
|
|
204
|
+
uint32_t generate_transaction_id();
|
|
205
|
+
|
|
206
|
+
// Read 32-bit big-endian integer
|
|
207
|
+
static uint32_t read_uint32_be(const uint8_t* data);
|
|
208
|
+
|
|
209
|
+
// Write 32-bit big-endian integer
|
|
210
|
+
static void write_uint32_be(uint8_t* data, uint32_t value);
|
|
211
|
+
|
|
212
|
+
// Read 64-bit big-endian integer
|
|
213
|
+
static int64_t read_int64_be(const uint8_t* data);
|
|
214
|
+
|
|
215
|
+
// Write 64-bit big-endian integer
|
|
216
|
+
static void write_int64_be(uint8_t* data, int64_t value);
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
// Tracker Manager - manages multiple trackers for a torrent
|
|
220
|
+
class TrackerManager {
|
|
221
|
+
public:
|
|
222
|
+
explicit TrackerManager(const TorrentInfo& torrent_info);
|
|
223
|
+
~TrackerManager();
|
|
224
|
+
|
|
225
|
+
// Add tracker from URL
|
|
226
|
+
bool add_tracker(const std::string& tracker_url);
|
|
227
|
+
|
|
228
|
+
// Announce to all trackers
|
|
229
|
+
void announce(const TrackerRequest& request, TrackerResponseCallback callback);
|
|
230
|
+
|
|
231
|
+
// Announce to best tracker only
|
|
232
|
+
void announce_to_best(const TrackerRequest& request, TrackerResponseCallback callback);
|
|
233
|
+
|
|
234
|
+
// Scrape all trackers
|
|
235
|
+
void scrape(TrackerResponseCallback callback);
|
|
236
|
+
|
|
237
|
+
// Get number of working trackers
|
|
238
|
+
size_t get_working_tracker_count() const;
|
|
239
|
+
|
|
240
|
+
// Get all tracker URLs
|
|
241
|
+
std::vector<std::string> get_tracker_urls() const;
|
|
242
|
+
|
|
243
|
+
// Check if it's time to announce
|
|
244
|
+
bool should_announce() const;
|
|
245
|
+
|
|
246
|
+
// Get next announce time
|
|
247
|
+
std::chrono::steady_clock::time_point get_next_announce_time() const;
|
|
248
|
+
|
|
249
|
+
private:
|
|
250
|
+
std::vector<std::shared_ptr<TrackerClient>> trackers_;
|
|
251
|
+
mutable std::mutex trackers_mutex_;
|
|
252
|
+
InfoHash info_hash_;
|
|
253
|
+
std::chrono::steady_clock::time_point last_announce_time_;
|
|
254
|
+
uint32_t announce_interval_;
|
|
255
|
+
|
|
256
|
+
// Create tracker client based on URL scheme
|
|
257
|
+
std::shared_ptr<TrackerClient> create_tracker_client(const std::string& tracker_url);
|
|
258
|
+
|
|
259
|
+
// Sort trackers by priority (working trackers first)
|
|
260
|
+
void sort_trackers_by_priority();
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
// Utility functions
|
|
264
|
+
std::string tracker_event_to_string(TrackerEvent event);
|
|
265
|
+
TrackerEvent string_to_tracker_event(const std::string& event_str);
|
|
266
|
+
|
|
267
|
+
} // namespace librats
|
|
268
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#include "version.h"
|
|
2
|
+
#include <iostream>
|
|
3
|
+
#include <iomanip>
|
|
4
|
+
#include "rats_export.h"
|
|
5
|
+
|
|
6
|
+
namespace librats {
|
|
7
|
+
namespace version {
|
|
8
|
+
|
|
9
|
+
RATS_API void rats_print_version_info() {
|
|
10
|
+
std::cout << "Version: " << STRING << std::endl;
|
|
11
|
+
std::cout << "Git: " << GIT_DESCRIBE << std::endl;
|
|
12
|
+
std::cout << "Build: " << BUILD << std::endl;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
RATS_API void rats_print_header() {
|
|
16
|
+
std::cout << ASCII_HEADER << std::endl;
|
|
17
|
+
std::cout << " Version: " << std::left << std::setw(10) << STRING
|
|
18
|
+
<< " Build: " << BUILD << std::endl;
|
|
19
|
+
std::cout << " Git: " << GIT_DESCRIBE << std::endl;
|
|
20
|
+
std::cout << " ======================================== " << std::endl;
|
|
21
|
+
std::cout << std::endl;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "rats_export.h"
|
|
4
|
+
|
|
5
|
+
// This file is auto-generated by CMake. Do not edit manually.
|
|
6
|
+
#define LIBRATS_VERSION_MAJOR @VERSION_MAJOR@
|
|
7
|
+
#define LIBRATS_VERSION_MINOR @VERSION_MINOR@
|
|
8
|
+
#define LIBRATS_VERSION_PATCH @VERSION_PATCH@
|
|
9
|
+
#define LIBRATS_VERSION_BUILD @VERSION_BUILD@
|
|
10
|
+
#define LIBRATS_VERSION_STRING "@VERSION_STRING@"
|
|
11
|
+
#define LIBRATS_GIT_DESCRIBE "@GIT_DESCRIBE@"
|
|
12
|
+
|
|
13
|
+
// ASCII Art Header
|
|
14
|
+
#define LIBRATS_ASCII_HEADER \
|
|
15
|
+
" ####### ##### ######## ####### \n" \
|
|
16
|
+
" ## ## ## ## ## ## \n" \
|
|
17
|
+
" ## ## ## ## ## ## \n" \
|
|
18
|
+
" ####### ####### ## ####### \n" \
|
|
19
|
+
" ## ## ## ## ## ## \n" \
|
|
20
|
+
" ## ## ## ## ## ## \n" \
|
|
21
|
+
" ## ## ## ## ## ####### \n" \
|
|
22
|
+
" \n" \
|
|
23
|
+
" P2P Network Communication Library \n" \
|
|
24
|
+
" ====================================== \n"
|
|
25
|
+
|
|
26
|
+
namespace librats {
|
|
27
|
+
namespace version {
|
|
28
|
+
// Version information
|
|
29
|
+
const int MAJOR = LIBRATS_VERSION_MAJOR;
|
|
30
|
+
const int MINOR = LIBRATS_VERSION_MINOR;
|
|
31
|
+
const int PATCH = LIBRATS_VERSION_PATCH;
|
|
32
|
+
const int BUILD = LIBRATS_VERSION_BUILD;
|
|
33
|
+
const char* const STRING = LIBRATS_VERSION_STRING;
|
|
34
|
+
const char* const GIT_DESCRIBE = LIBRATS_GIT_DESCRIBE;
|
|
35
|
+
|
|
36
|
+
// ASCII header
|
|
37
|
+
const char* const ASCII_HEADER = LIBRATS_ASCII_HEADER;
|
|
38
|
+
|
|
39
|
+
// Print version info
|
|
40
|
+
RATS_API void rats_print_version_info();
|
|
41
|
+
|
|
42
|
+
// Print ASCII header with version
|
|
43
|
+
RATS_API void rats_print_header();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#include <windows.h>
|
|
2
|
+
|
|
3
|
+
VS_VERSION_INFO VERSIONINFO
|
|
4
|
+
FILEVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,@VERSION_BUILD@
|
|
5
|
+
PRODUCTVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,@VERSION_BUILD@
|
|
6
|
+
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
|
7
|
+
FILEFLAGS 0x0L
|
|
8
|
+
FILEOS VOS__WINDOWS32
|
|
9
|
+
FILETYPE VFT_APP
|
|
10
|
+
FILESUBTYPE VFT2_UNKNOWN
|
|
11
|
+
BEGIN
|
|
12
|
+
BLOCK "StringFileInfo"
|
|
13
|
+
BEGIN
|
|
14
|
+
BLOCK "040904b0"
|
|
15
|
+
BEGIN
|
|
16
|
+
VALUE "CompanyName", "librats Project"
|
|
17
|
+
VALUE "FileDescription", "librats P2P Networking Library - Legitimate networking software"
|
|
18
|
+
VALUE "FileVersion", "@VERSION_STRING@"
|
|
19
|
+
VALUE "ProductName", "librats P2P Networking Library"
|
|
20
|
+
VALUE "ProductVersion", "@VERSION_STRING@"
|
|
21
|
+
VALUE "LegalCopyright", "Copyright (c) librats contributors - MIT License"
|
|
22
|
+
VALUE "OriginalFilename", "rats-client.exe"
|
|
23
|
+
VALUE "InternalName", "librats"
|
|
24
|
+
VALUE "Comments", "Open source peer-to-peer networking library implementing BitTorrent DHT, ICE/STUN NAT traversal, and secure encryption protocols (@GIT_DESCRIBE@)"
|
|
25
|
+
END
|
|
26
|
+
END
|
|
27
|
+
BLOCK "VarFileInfo"
|
|
28
|
+
BEGIN
|
|
29
|
+
VALUE "Translation", 0x409, 1200
|
|
30
|
+
END
|
|
31
|
+
END
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "librats",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Node.js bindings for librats - A high-performance peer-to-peer networking library",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -56,13 +56,7 @@
|
|
|
56
56
|
"scripts/**/*",
|
|
57
57
|
"binding.gyp",
|
|
58
58
|
"README.md",
|
|
59
|
-
"
|
|
60
|
-
"../src/**/*.h",
|
|
61
|
-
"../src/**/*.in",
|
|
62
|
-
"../3rdparty/**/*",
|
|
63
|
-
"../CMakeLists.txt",
|
|
64
|
-
"../LICENSE",
|
|
65
|
-
"!../src/main.cpp"
|
|
59
|
+
"native-src/**/*"
|
|
66
60
|
],
|
|
67
61
|
"gypfile": true
|
|
68
62
|
}
|
package/scripts/build-librats.js
CHANGED
|
@@ -12,14 +12,47 @@ const isLinux = process.platform === 'linux';
|
|
|
12
12
|
|
|
13
13
|
// Paths
|
|
14
14
|
const nodejsRoot = path.resolve(__dirname, '..');
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
const buildDir = path.resolve(nodejsRoot, 'build-native');
|
|
16
|
+
|
|
17
|
+
// Determine source location:
|
|
18
|
+
// 1. When installed from npm: sources are in nodejs/native-src/
|
|
19
|
+
// 2. When developing locally: sources are in project root (../../ from scripts)
|
|
20
|
+
let projectRoot;
|
|
21
|
+
let srcDir;
|
|
22
|
+
let cmakeLists;
|
|
23
|
+
|
|
24
|
+
const nativeSrcDir = path.resolve(nodejsRoot, 'native-src');
|
|
25
|
+
const devProjectRoot = path.resolve(__dirname, '..', '..');
|
|
26
|
+
|
|
27
|
+
if (fs.existsSync(path.join(nativeSrcDir, 'CMakeLists.txt'))) {
|
|
28
|
+
// npm install scenario: use native-src directory
|
|
29
|
+
projectRoot = nativeSrcDir;
|
|
30
|
+
srcDir = path.resolve(nativeSrcDir, 'src');
|
|
31
|
+
cmakeLists = path.resolve(nativeSrcDir, 'CMakeLists.txt');
|
|
32
|
+
console.log('Using bundled source files from native-src/');
|
|
33
|
+
} else if (fs.existsSync(path.join(devProjectRoot, 'CMakeLists.txt'))) {
|
|
34
|
+
// Development scenario: use parent directory
|
|
35
|
+
projectRoot = devProjectRoot;
|
|
36
|
+
srcDir = path.resolve(devProjectRoot, 'src');
|
|
37
|
+
cmakeLists = path.resolve(devProjectRoot, 'CMakeLists.txt');
|
|
38
|
+
console.log('Using source files from project root (development mode)');
|
|
39
|
+
} else {
|
|
40
|
+
console.error('ERROR: Cannot find librats source files.');
|
|
41
|
+
console.error('');
|
|
42
|
+
console.error('Checked locations:');
|
|
43
|
+
console.error(` - ${nativeSrcDir} (npm install)`);
|
|
44
|
+
console.error(` - ${devProjectRoot} (development)`);
|
|
45
|
+
console.error('');
|
|
46
|
+
console.error('If you installed from npm, the package may be corrupted.');
|
|
47
|
+
console.error('Try: npm cache clean --force && npm install librats');
|
|
48
|
+
console.error('');
|
|
49
|
+
console.error('If you are developing locally, make sure you are in the librats repository.');
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
19
52
|
|
|
20
53
|
console.log('Building librats native library...');
|
|
21
54
|
console.log(`Platform: ${process.platform}`);
|
|
22
|
-
console.log(`
|
|
55
|
+
console.log(`Source root: ${projectRoot}`);
|
|
23
56
|
console.log(`Build directory: ${buildDir}`);
|
|
24
57
|
|
|
25
58
|
// Check if CMake is installed
|
|
@@ -46,17 +79,17 @@ try {
|
|
|
46
79
|
process.exit(1);
|
|
47
80
|
}
|
|
48
81
|
|
|
49
|
-
//
|
|
82
|
+
// Verify CMakeLists.txt exists
|
|
50
83
|
if (!fs.existsSync(cmakeLists)) {
|
|
51
|
-
console.error('ERROR: CMakeLists.txt not found
|
|
52
|
-
console.error(
|
|
84
|
+
console.error('ERROR: CMakeLists.txt not found.');
|
|
85
|
+
console.error(`Expected at: ${cmakeLists}`);
|
|
53
86
|
process.exit(1);
|
|
54
87
|
}
|
|
55
88
|
|
|
56
|
-
//
|
|
89
|
+
// Verify src directory exists
|
|
57
90
|
if (!fs.existsSync(srcDir)) {
|
|
58
91
|
console.error('ERROR: src directory not found.');
|
|
59
|
-
console.error(
|
|
92
|
+
console.error(`Expected at: ${srcDir}`);
|
|
60
93
|
process.exit(1);
|
|
61
94
|
}
|
|
62
95
|
|
|
@@ -64,6 +97,19 @@ if (!fs.existsSync(srcDir)) {
|
|
|
64
97
|
if (!fs.existsSync(buildDir)) {
|
|
65
98
|
console.log(`Creating build directory: ${buildDir}`);
|
|
66
99
|
fs.mkdirSync(buildDir, { recursive: true });
|
|
100
|
+
} else {
|
|
101
|
+
// Clear CMake cache if it exists to avoid source directory mismatch errors
|
|
102
|
+
const cmakeCache = path.join(buildDir, 'CMakeCache.txt');
|
|
103
|
+
if (fs.existsSync(cmakeCache)) {
|
|
104
|
+
console.log('Clearing existing CMake cache...');
|
|
105
|
+
fs.unlinkSync(cmakeCache);
|
|
106
|
+
|
|
107
|
+
// Also remove CMakeFiles directory for a clean reconfigure
|
|
108
|
+
const cmakeFiles = path.join(buildDir, 'CMakeFiles');
|
|
109
|
+
if (fs.existsSync(cmakeFiles)) {
|
|
110
|
+
fs.rmSync(cmakeFiles, { recursive: true, force: true });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
67
113
|
}
|
|
68
114
|
|
|
69
115
|
// Helper function to execute commands
|
|
@@ -121,7 +167,9 @@ try {
|
|
|
121
167
|
cmakeArgs.push('-G "Unix Makefiles"');
|
|
122
168
|
}
|
|
123
169
|
|
|
124
|
-
|
|
170
|
+
// Calculate the relative path from build directory to source root
|
|
171
|
+
const relativePath = path.relative(buildDir, projectRoot);
|
|
172
|
+
const cmakeConfigCmd = `cmake ${cmakeArgs.join(' ')} "${relativePath}"`;
|
|
125
173
|
exec(cmakeConfigCmd);
|
|
126
174
|
|
|
127
175
|
// Build the library
|
|
@@ -191,4 +239,3 @@ try {
|
|
|
191
239
|
|
|
192
240
|
process.exit(1);
|
|
193
241
|
}
|
|
194
|
-
|