diff --git a/.npmignore b/.npmignore index 452190b..1ed313f 100644 --- a/.npmignore +++ b/.npmignore @@ -7,4 +7,4 @@ docs .github CODE_OF_CONDUCT.md SECURITY.md -CONTRIBUTING.md \ No newline at end of file +CONTRIBUTING.md diff --git a/README.md b/README.md index c2480a3..b4038d8 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,26 @@ $ npm install @performanc/voice $ npm install github:PerformanC/voice ``` +### Native build requirements + +Installation builds the native audio sender and requires Python, a C compiler, +and the libsodium development files. + +On Windows, use the official Visual Studio libsodium package and set +`SODIUM_ROOT` to its extracted directory: + +```powershell +$env:SODIUM_ROOT = 'C:\path\to\libsodium' +npm install +``` + +The build also detects a static libsodium installation under `VCPKG_ROOT`. +Custom layouts can set `SODIUM_INCLUDE_DIR` to the directory containing +`sodium.h` and `SODIUM_LIB` to the full path of the static `.lib` file. + +Linux and macOS builds use the system libsodium development package, such as +`libsodium-dev` on Debian/Ubuntu or `brew install libsodium` on macOS. + ## Usage ```javascript diff --git a/index.js b/index.js index d5b996a..9404c8c 100644 --- a/index.js +++ b/index.js @@ -1150,7 +1150,7 @@ class Connection extends EventEmitter { nonce.fill(0) data.copy(nonce, 0, data.length - 4, data.length) - const headerSize = 12 + cc * 4 + let headerSize = 12 + cc * 4 let extensionLengthInWords = 0 if (data.length < headerSize) return; diff --git a/native/binding.gyp b/native/binding.gyp index 6a15511..f263f95 100644 --- a/native/binding.gyp +++ b/native/binding.gyp @@ -4,15 +4,12 @@ "target_name": "voice_send_native", "sources": [ "src/binding.c", + "src/cthreads.c", "src/voice_send.c" ], "include_dirs": [ "." ], - "libraries": [ - "-lsodium", - "-lpthread" - ], "conditions": [ ["OS=='linux'", { "cflags": [ @@ -21,9 +18,16 @@ "-Wextra", "-Wpedantic" ], - "ldflags": [] + "libraries": [ + "-lsodium", + "-lpthread" + ] }], ["OS=='mac'", { + "libraries": [ + "-lsodium", + "-lpthread" + ], "xcode_settings": { "OTHER_CFLAGS": [ "-std=c99", @@ -34,11 +38,37 @@ } }], ["OS=='win'", { + "defines": [ + "SODIUM_STATIC" + ], + "msvs_settings": { + "VCCLCompilerTool": { + "AdditionalOptions!": [ + "-flto=full", + "-flto=thin" + ] + }, + "VCLibrarianTool": { + "AdditionalOptions!": [ + "-flto=full", + "-flto=thin" + ] + }, + "VCLinkerTool": { + "AdditionalOptions!": [ + "-flto=full", + "-flto=thin", + "/opt:lldltojobs=<(lto_jobs)" + ] + } + }, "libraries": [ - "-lsodium.lib" + " candidate && fs.existsSync(candidate) +) + +if (!result) { + fail( + `Could not find the libsodium ${kind}. Set SODIUM_ROOT to a libsodium ` + + 'SDK directory, or set SODIUM_INCLUDE_DIR and SODIUM_LIB explicitly. ' + + 'A VCPKG_ROOT installation is also supported.' + ) +} + +process.stdout.write( + path.resolve(kind === 'include' ? path.dirname(result) : result) +) + +function includeCandidates(searchRoots) { + return [ + process.env.SODIUM_INCLUDE_DIR, + ...searchRoots.map((root) => root && path.join(root, 'include')) + ] + .filter(Boolean) + .map((includeDir) => path.join(includeDir, 'sodium.h')) +} + +function libraryCandidates(searchRoots, arch) { + const candidates = [process.env.SODIUM_LIB] + + for (const root of searchRoots.filter(Boolean)) { + candidates.push( + path.join(root, 'lib', 'libsodium.lib'), + path.join(root, 'lib', 'sodium.lib') + ) + + const releaseRoot = path.join(root, archNames[arch], 'Release') + if (!fs.existsSync(releaseRoot)) continue + + const toolsets = fs + .readdirSync(releaseRoot, { withFileTypes: true }) + .filter((entry) => entry.isDirectory() && /^v\d+$/.test(entry.name)) + .map((entry) => entry.name) + .sort((left, right) => + right.localeCompare(left, undefined, { + numeric: true + }) + ) + + for (const toolset of toolsets) { + candidates.push( + path.join(releaseRoot, toolset, 'static', 'libsodium.lib') + ) + } + } + + return candidates.filter(Boolean) +} + +function vcpkgInstalledRoot(root) { + const triplet = + process.env.VCPKG_TARGET_TRIPLET ?? + process.env.VCPKG_DEFAULT_TRIPLET ?? + `${vcpkgArchNames[targetArch]}-windows-static` + + return path.join(root, 'installed', triplet) +} + +function fail(message) { + process.stderr.write(`\n@performanc/voice: ${message}\n`) + process.exit(1) +} diff --git a/native/src/binding.c b/native/src/binding.c index fb41568..26d478d 100644 --- a/native/src/binding.c +++ b/native/src/binding.c @@ -113,7 +113,7 @@ static void *loop_thread_func(void *arg) { /* INFO: Send via UDP */ if (pkt_len > 0) { int sent = os_sendto(nc->udp_fd, packet, (size_t)pkt_len, 0, (const struct sockaddr *)&nc->udp_addr, sizeof(nc->udp_addr)); - if (sent == (ssize_t)pkt_len) { + if (sent == pkt_len) { nc->ctx.stats.packets_sent++; /* INFO: Update the stats counter and sync to JS every 50 packets */