diff --git a/README.md b/README.md
index f2743ed1..fe03e88e 100644
--- a/README.md
+++ b/README.md
@@ -14,22 +14,34 @@
</a>
</p>
-## [About](https://fosscord.com)
-
-This repository contains:
-
-- [Fosscord HTTP API Server](/api)
-- [WebSocket Gateway Server](/gateway)
-- [HTTP CDN Server](/cdn)
-- [Utility and Database Models](/util)
-- [RTC Server](/rtc)
-- [WebRTC Server](/webrtc)
-- [Admin Dashboard](/dashboard)
-
-## [Resources](https://docs.fosscord.com/resources/)
-
-- [Contributing](https://docs.fosscord.com/contributing/server/)
-
-## [Setup](https://docs.fosscord.com/server/setup/)
-
-- [Download](https://github.com/fosscord/fosscord-server/releases)
+# Install
+Setup fosscord-server as normal ( existing installations are fine, if you run voice on the same server on port `3004` you don't need to edit the `regions_available_0_endpoint` record of `config` )
+
+Note: currently everything about webrtc is commented out ( because I was lazy )
+If you want to test that, you're gonna have to do some fiddling, shouldn't be toooo difficult ( check `SelectProtocols.ts`, `Identify.ts` and theres probably smth in `Server.ts` I forgot about ). Also also make sure you set the `listenIps` in `Identify.ts` properly because otherwise the transport won't start
+
+```sh
+cd webrtc
+ts-node src/start.ts # don't think the build script works lol
+```
+
+# Current problems / setup / etc:
+* Webrtc DTLS fails to properly connect with browser voice. The handshake completes and is labeled completed by chrome://webrtc-internals, however mediasoup drops all RTP packets as the 'handshake is not completed' yet.
+
+* After the desktop client updates it's VoiceState to join a voice channel, upon leaving the VoiceState will not update to match, and the client is prevented from joining any new voice channels. The client also continuously plays the voice disconnected notification sound. [Video demo](https://who-the-fuck-pinged.me/6dlya82Z)
+* Desktop client cannot properly connect to voice/media servers due to the above, but also because somewhere in my signalling there is a problem. I haven't looked much into it.
+* When the client does magically decide to try to connect, it connects to signalling but then [throws an error client-side about `this.conn.setSelfMute` not being a function](https://media.discordapp.net/attachments/903790443052036117/951099310370615306/unknown.png)
+
+* I have instead been testing voice using [a fork](https://github.com/tenable/DiscordClient) of the reverse engineered client from [this article](https://medium.com/tenable-techblog/lets-reverse-engineer-discord-1976773f4626), with some slight modifications ( I think it was just changing the email field the client uses to login from `email` -> `login`. Todo: these could be aliases in `fosscord-server`? )
+* This client can join a channel, connect to signalling, and does send packets to the UDP server. However, I can't seem to get decrpytion to work. As far as I know, I'm using the same key I'm sending. It turns out the client converts the `secret_key: Number[]` received into a string, but doing the same on the server-side before passing to the decrpyt method still just complains about a key mismatch.
+
+# Resources:
+* [Mediasoup docs](https://mediasoup.org/documentation/v3/), or more specifically the [API docs](https://mediasoup.org/documentation/v3/mediasoup/api/)
+* * [Mediasoup SFU video demo](https://github.com/Dirvann/mediasoup-sfu-webrtc-video-rooms)
+* [The fork of the reverse engineered voice client](https://github.com/edisionnano/DiscordClient)
+* * [discord_voice.node stubs for logging client actions](https://github.com/edisionnano/discord_voice-stub/blob/main/discord_voice.js)
+* [Discord.com docs: connecting to voice](https://discord.com/developers/docs/topics/voice-connections#connecting-to-voice)
+* [Anatomy of a WebRTC SDP](https://webrtchacks.com/sdp-anatomy/)
+* [WebRTC Glossary](https://webrtcglossary.com/)
+* * [What is an SFU/MCU](https://webrtcglossary.com/sfu/)
+* * [How SDP, how to send DTLS fingerprints](https://blog.actorsfit.com/a?ID=00001-8ebd39ca-2d57-41bc-9743-635373e77167)
\ No newline at end of file
diff --git a/bundle/package-lock.json b/bundle/package-lock.json
index 6fbd6978..4991f97a 100644
--- a/bundle/package-lock.json
+++ b/bundle/package-lock.json
@@ -18,6 +18,7 @@
"@fosscord/gateway": "file:../gateway",
"@sentry/node": "^6.16.1",
"@sentry/tracing": "^6.16.1",
+ "@yukikaze-bot/erlpack": "^1.0.1",
"ajv": "8.6.2",
"ajv-formats": "^2.1.1",
"amqplib": "^0.8.0",
@@ -3770,6 +3771,21 @@
"version": "1.1.0",
"integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ=="
},
+ "node_modules/@yukikaze-bot/erlpack": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@yukikaze-bot/erlpack/-/erlpack-1.0.1.tgz",
+ "integrity": "sha512-PCJ2lGCf8DsQtrE411PY+NTsolK48l4InNn1kcBo0iUllKZYGLqeqXEWGA/INrmwanKcoYkU4pBySqUFLQDEoA==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@mapbox/node-pre-gyp": "^1.0.5",
+ "node-addon-api": "^4.0.0"
+ }
+ },
+ "node_modules/@yukikaze-bot/erlpack/node_modules/node-addon-api": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
+ "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ=="
+ },
"node_modules/@zerollup/ts-helpers": {
"version": "1.7.18",
"integrity": "sha512-S9zN+y+i5yN/evfWquzSO3lubqPXIsPQf6p9OiPMpRxDx/0totPLF39XoRw48Dav5dSvbIE8D2eAPpXXJxvKwg==",
@@ -13897,6 +13913,22 @@
"version": "1.1.0",
"integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ=="
},
+ "@yukikaze-bot/erlpack": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@yukikaze-bot/erlpack/-/erlpack-1.0.1.tgz",
+ "integrity": "sha512-PCJ2lGCf8DsQtrE411PY+NTsolK48l4InNn1kcBo0iUllKZYGLqeqXEWGA/INrmwanKcoYkU4pBySqUFLQDEoA==",
+ "requires": {
+ "@mapbox/node-pre-gyp": "^1.0.5",
+ "node-addon-api": "^4.0.0"
+ },
+ "dependencies": {
+ "node-addon-api": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
+ "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ=="
+ }
+ }
+ },
"@zerollup/ts-helpers": {
"version": "1.7.18",
"integrity": "sha512-S9zN+y+i5yN/evfWquzSO3lubqPXIsPQf6p9OiPMpRxDx/0totPLF39XoRw48Dav5dSvbIE8D2eAPpXXJxvKwg==",
diff --git a/bundle/package.json b/bundle/package.json
index 7d68427f..aedd963b 100644
--- a/bundle/package.json
+++ b/bundle/package.json
@@ -66,6 +66,7 @@
"@fosscord/gateway": "file:../gateway",
"@sentry/node": "^6.16.1",
"@sentry/tracing": "^6.16.1",
+ "@yukikaze-bot/erlpack": "^1.0.1",
"ajv": "8.6.2",
"ajv-formats": "^2.1.1",
"amqplib": "^0.8.0",
diff --git a/bundle/src/Server.ts b/bundle/src/Server.ts
index 71a60d49..bc1d7cbc 100644
--- a/bundle/src/Server.ts
+++ b/bundle/src/Server.ts
@@ -50,20 +50,20 @@ async function main() {
endpointPublic: `ws://localhost:${port}`,
}),
},
- // regions: {
- // default: "fosscord",
- // useDefaultAsOptimal: true,
- // available: [
- // {
- // id: "fosscord",
- // name: "Fosscord",
- // endpoint: "127.0.0.1:3001",
- // vip: false,
- // custom: false,
- // deprecated: false,
- // },
- // ],
- // },
+ regions: {
+ default: "fosscord",
+ useDefaultAsOptimal: true,
+ available: [
+ {
+ id: "fosscord",
+ name: "Fosscord",
+ endpoint: "127.0.0.1:3004",
+ vip: false,
+ custom: false,
+ deprecated: false,
+ },
+ ],
+ },
} as any);
//Sentry
diff --git a/gateway/src/opcodes/Identify.ts b/gateway/src/opcodes/Identify.ts
index 860000da..4b617fdd 100644
--- a/gateway/src/opcodes/Identify.ts
+++ b/gateway/src/opcodes/Identify.ts
@@ -34,6 +34,8 @@ import { Recipient } from "@fosscord/util";
// TODO: check if already identified
export async function onIdentify(this: WebSocket, data: Payload) {
+ console.log(data);
+
clearTimeout(this.readyTimeout);
check.call(this, IdentifySchema, data.d);
diff --git a/gateway/src/schema/VoiceStateUpdateSchema.ts b/gateway/src/schema/VoiceStateUpdateSchema.ts
index 9efa191e..f6480414 100644
--- a/gateway/src/schema/VoiceStateUpdateSchema.ts
+++ b/gateway/src/schema/VoiceStateUpdateSchema.ts
@@ -3,7 +3,8 @@ export const VoiceStateUpdateSchema = {
$channel_id: String,
self_mute: Boolean,
self_deaf: Boolean,
- self_video: Boolean,
+ $self_video: Boolean, //required in docs but bots don't always send it
+ $preferred_region: String,
};
export interface VoiceStateUpdateSchema {
@@ -11,5 +12,6 @@ export interface VoiceStateUpdateSchema {
channel_id?: string;
self_mute: boolean;
self_deaf: boolean;
- self_video: boolean;
-}
+ self_video?: boolean;
+ preferred_region?: string;
+}
\ No newline at end of file
diff --git a/util/src/util/Constants.ts b/util/src/util/Constants.ts
index a5d3fcd2..81a7165d 100644
--- a/util/src/util/Constants.ts
+++ b/util/src/util/Constants.ts
@@ -73,9 +73,13 @@ export const VoiceOPCodes = {
HEARTBEAT: 3,
SESSION_DESCRIPTION: 4,
SPEAKING: 5,
+ HEARTBEAT_ACK: 6,
+ RESUME: 7,
HELLO: 8,
- CLIENT_CONNECT: 12,
- CLIENT_DISCONNECT: 13,
+ RESUMED: 9,
+ CLIENT_CONNECT: 12, // incorrect, op 12 is probably used for video
+ CLIENT_DISCONNECT: 13, // incorrect
+ VERSION: 16, //not documented
};
export const Events = {
diff --git a/webrtc/.vscode/launch.json b/webrtc/.vscode/launch.json
new file mode 100644
index 00000000..49584172
--- /dev/null
+++ b/webrtc/.vscode/launch.json
@@ -0,0 +1,25 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "ts-node",
+ "type": "node",
+ "request": "launch",
+ "args": [
+ "src/start.ts"
+ ],
+ "runtimeArgs": [
+ "-r",
+ "ts-node/register"
+ ],
+ "cwd": "${workspaceRoot}",
+ "protocol": "inspector",
+ "internalConsoleOptions": "openOnSessionStart",
+ "sourceMaps": true,
+ "resolveSourceMapLocations": null,
+ }
+ ]
+}
\ No newline at end of file
diff --git a/webrtc/package-lock.json b/webrtc/package-lock.json
index a5db2de1..e6b10d69 100644
--- a/webrtc/package-lock.json
+++ b/webrtc/package-lock.json
@@ -9,22 +9,91 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
- "mediasoup": "^3.7.16",
+ "@types/libsodium-wrappers": "^0.7.9",
+ "dotenv": "^12.0.4",
+ "libsodium": "^0.7.10",
+ "libsodium-wrappers": "^0.7.10",
+ "mediasoup": "^3.9.5",
"node-turn": "^0.0.6",
+ "sdp-transform": "^2.14.1",
+ "tsconfig-paths": "^3.12.0",
"ws": "^7.4.6"
},
"devDependencies": {
"@types/node": "^15.6.1",
+ "@types/sdp-transform": "^2.4.5",
"@types/ws": "^7.4.4",
+ "ts-node": "^10.4.0",
"typescript": "^4.3.2"
}
},
+ "node_modules/@cspotcode/source-map-consumer": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
+ "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/@cspotcode/source-map-support": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz",
+ "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==",
+ "dev": true,
+ "dependencies": {
+ "@cspotcode/source-map-consumer": "0.8.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@tsconfig/node10": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
+ "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node12": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
+ "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node14": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
+ "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node16": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
+ "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
+ "dev": true
+ },
+ "node_modules/@types/json5": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4="
+ },
+ "node_modules/@types/libsodium-wrappers": {
+ "version": "0.7.9",
+ "resolved": "https://registry.npmjs.org/@types/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz",
+ "integrity": "sha512-LisgKLlYQk19baQwjkBZZXdJL0KbeTpdEnrAfz5hQACbklCY0gVFnsKUyjfNWF1UQsCSjw93Sj5jSbiO8RPfdw=="
+ },
"node_modules/@types/node": {
"version": "15.6.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.6.1.tgz",
"integrity": "sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==",
"dev": true
},
+ "node_modules/@types/sdp-transform": {
+ "version": "2.4.5",
+ "resolved": "https://registry.npmjs.org/@types/sdp-transform/-/sdp-transform-2.4.5.tgz",
+ "integrity": "sha512-GVO0gnmbyO3Oxm2HdPsYUNcyihZE3GyCY8ysMYHuQGfLhGZq89Nm4lSzULWTzZoyHtg+VO/IdrnxZHPnPSGnAg==",
+ "dev": true
+ },
"node_modules/@types/ws": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.4.tgz",
@@ -34,6 +103,33 @@
"@types/node": "*"
}
},
+ "node_modules/acorn": {
+ "version": "8.7.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
+ "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
+ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true
+ },
"node_modules/argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -42,14 +138,6 @@
"sprintf-js": "~1.0.2"
}
},
- "node_modules/awaitqueue": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/awaitqueue/-/awaitqueue-2.3.3.tgz",
- "integrity": "sha512-RbzQg6VtPUtyErm55iuQLTrBJ2uihy5BKBOEkyBwv67xm5Fn2o/j+Bz+a5BmfSoe2oZ5dcz9Z3fExS8pL+LLhw==",
- "engines": {
- "node": ">=8.0.0"
- }
- },
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -100,6 +188,12 @@
"buffer": "^5.1.0"
}
},
+ "node_modules/create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true
+ },
"node_modules/date-format": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz",
@@ -108,6 +202,39 @@
"node": ">=4.0"
}
},
+ "node_modules/debug": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
+ "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "12.0.4",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-12.0.4.tgz",
+ "integrity": "sha512-oWdqbSywffzH1l4WXKPHWA0TWYpqp7IyLfqjipT4upoIFS0HPMqtNotykQpD4iIg0BqtNmdgPCh2WMvMt7yTiw==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
@@ -154,35 +281,6 @@
"node": ">=8.0.0"
}
},
- "node_modules/h264-profile-level-id/node_modules/debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/h264-profile-level-id/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- },
- "node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -214,6 +312,17 @@
"js-yaml": "bin/js-yaml.js"
}
},
+ "node_modules/json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
"node_modules/jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
@@ -222,6 +331,19 @@
"graceful-fs": "^4.1.6"
}
},
+ "node_modules/libsodium": {
+ "version": "0.7.10",
+ "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.10.tgz",
+ "integrity": "sha512-eY+z7hDrDKxkAK+QKZVNv92A5KYkxfvIshtBJkmg5TSiCnYqZP3i9OO9whE79Pwgm4jGaoHgkM4ao/b9Cyu4zQ=="
+ },
+ "node_modules/libsodium-wrappers": {
+ "version": "0.7.10",
+ "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.10.tgz",
+ "integrity": "sha512-pO3F1Q9NPLB/MWIhehim42b/Fwb30JNScCNh8TcQ/kIc+qGLQch8ag8wb0keK3EP5kbGakk1H8Wwo7v+36rNQg==",
+ "dependencies": {
+ "libsodium": "^0.7.0"
+ }
+ },
"node_modules/log4js": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz",
@@ -237,44 +359,27 @@
"node": ">=8.0"
}
},
- "node_modules/log4js/node_modules/debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/log4js/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
},
"node_modules/mediasoup": {
- "version": "3.7.16",
- "resolved": "https://registry.npmjs.org/mediasoup/-/mediasoup-3.7.16.tgz",
- "integrity": "sha512-eD7VJj117zVYF8f4KYgQh2DzaYyzTvBtNa4ocT45eCjt0Y47dveKmfL5LW0LQL1LMYkBhfx/etHLjE/1AhNmwg==",
+ "version": "3.9.5",
+ "resolved": "https://registry.npmjs.org/mediasoup/-/mediasoup-3.9.5.tgz",
+ "integrity": "sha512-8lISnN5cbtSvdqHeuyxhCTFTHudoq/EpgLcDB0d0pT5RG18mZlHF5BwIBSkGxB/nWyeTfTGPpGBiNtKoubbRXA==",
"hasInstallScript": true,
"dependencies": {
- "@types/node": "^14.14.43",
- "awaitqueue": "^2.3.3",
- "debug": "^4.3.1",
+ "@types/node": "^16.11.10",
+ "debug": "^4.3.3",
"h264-profile-level-id": "^1.0.1",
- "netstring": "^0.3.0",
"random-number": "^0.0.9",
- "supports-color": "^8.1.1",
+ "supports-color": "^9.2.1",
"uuid": "^8.3.2"
},
"engines": {
- "node": ">=10"
+ "node": ">=12"
},
"funding": {
"type": "opencollective",
@@ -282,39 +387,20 @@
}
},
"node_modules/mediasoup/node_modules/@types/node": {
- "version": "14.17.3",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.3.tgz",
- "integrity": "sha512-e6ZowgGJmTuXa3GyaPbTGxX17tnThl2aSSizrFthQ7m9uLGZBXiGhgE55cjRZTF5kjZvYn9EOPOMljdjwbflxw=="
- },
- "node_modules/mediasoup/node_modules/debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
+ "version": "16.11.19",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.19.tgz",
+ "integrity": "sha512-BPAcfDPoHlRQNKktbsbnpACGdypPFBuX4xQlsWDE7B8XXcfII+SpOLay3/qZmCLb39kV5S1RTYwXdkx2lwLYng=="
},
- "node_modules/mediasoup/node_modules/ms": {
+ "node_modules/minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ },
+ "node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
- "node_modules/netstring": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/netstring/-/netstring-0.3.0.tgz",
- "integrity": "sha1-ho3FsgxY0/cwVTHUk2jqqr0ZtxI=",
- "engines": {
- "node": ">=0.6"
- }
- },
"node_modules/node-turn": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/node-turn/-/node-turn-0.0.6.tgz",
@@ -335,6 +421,14 @@
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA=="
},
+ "node_modules/sdp-transform": {
+ "version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.14.1.tgz",
+ "integrity": "sha512-RjZyX3nVwJyCuTo5tGPx+PZWkDMCg7oOLpSlhjDdZfwUoNqG1mM8nyj31IGHyaPWXhjbP7cdK3qZ2bmkJ1GzRw==",
+ "bin": {
+ "sdp-verify": "checker.js"
+ }
+ },
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -361,39 +455,75 @@
"node": ">=4.0"
}
},
- "node_modules/streamroller/node_modules/debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.1.tgz",
+ "integrity": "sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/ts-node": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz",
+ "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==",
+ "dev": true,
"dependencies": {
- "ms": "2.1.2"
+ "@cspotcode/source-map-support": "0.7.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "yn": "3.1.1"
},
- "engines": {
- "node": ">=6.0"
+ "bin": {
+ "ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-script": "dist/bin-script.js",
+ "ts-node-transpile-only": "dist/bin-transpile.js",
+ "ts-script": "dist/bin-script-deprecated.js"
+ },
+ "peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
+ "typescript": ">=2.7"
},
"peerDependenciesMeta": {
- "supports-color": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
"optional": true
}
}
},
- "node_modules/streamroller/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- },
- "node_modules/supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "node_modules/tsconfig-paths": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
+ "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==",
"dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.1",
+ "minimist": "^1.2.0",
+ "strip-bom": "^3.0.0"
}
},
"node_modules/typescript": {
@@ -444,15 +574,79 @@
"optional": true
}
}
+ },
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
}
},
"dependencies": {
+ "@cspotcode/source-map-consumer": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
+ "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
+ "dev": true
+ },
+ "@cspotcode/source-map-support": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz",
+ "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==",
+ "dev": true,
+ "requires": {
+ "@cspotcode/source-map-consumer": "0.8.0"
+ }
+ },
+ "@tsconfig/node10": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
+ "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
+ "dev": true
+ },
+ "@tsconfig/node12": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
+ "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
+ "dev": true
+ },
+ "@tsconfig/node14": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
+ "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
+ "dev": true
+ },
+ "@tsconfig/node16": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
+ "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
+ "dev": true
+ },
+ "@types/json5": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4="
+ },
+ "@types/libsodium-wrappers": {
+ "version": "0.7.9",
+ "resolved": "https://registry.npmjs.org/@types/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz",
+ "integrity": "sha512-LisgKLlYQk19baQwjkBZZXdJL0KbeTpdEnrAfz5hQACbklCY0gVFnsKUyjfNWF1UQsCSjw93Sj5jSbiO8RPfdw=="
+ },
"@types/node": {
"version": "15.6.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.6.1.tgz",
"integrity": "sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==",
"dev": true
},
+ "@types/sdp-transform": {
+ "version": "2.4.5",
+ "resolved": "https://registry.npmjs.org/@types/sdp-transform/-/sdp-transform-2.4.5.tgz",
+ "integrity": "sha512-GVO0gnmbyO3Oxm2HdPsYUNcyihZE3GyCY8ysMYHuQGfLhGZq89Nm4lSzULWTzZoyHtg+VO/IdrnxZHPnPSGnAg==",
+ "dev": true
+ },
"@types/ws": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.4.tgz",
@@ -462,6 +656,24 @@
"@types/node": "*"
}
},
+ "acorn": {
+ "version": "8.7.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
+ "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
+ "dev": true
+ },
+ "acorn-walk": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
+ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+ "dev": true
+ },
+ "arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true
+ },
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -470,11 +682,6 @@
"sprintf-js": "~1.0.2"
}
},
- "awaitqueue": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/awaitqueue/-/awaitqueue-2.3.3.tgz",
- "integrity": "sha512-RbzQg6VtPUtyErm55iuQLTrBJ2uihy5BKBOEkyBwv67xm5Fn2o/j+Bz+a5BmfSoe2oZ5dcz9Z3fExS8pL+LLhw=="
- },
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -497,11 +704,36 @@
"buffer": "^5.1.0"
}
},
+ "create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true
+ },
"date-format": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz",
"integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w=="
},
+ "debug": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
+ "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true
+ },
+ "dotenv": {
+ "version": "12.0.4",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-12.0.4.tgz",
+ "integrity": "sha512-oWdqbSywffzH1l4WXKPHWA0TWYpqp7IyLfqjipT4upoIFS0HPMqtNotykQpD4iIg0BqtNmdgPCh2WMvMt7yTiw=="
+ },
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
@@ -533,28 +765,8 @@
"integrity": "sha512-D3Rln/jKNjKDW5ZTJTK3niSoOGE+pFqPvRHHVgQN3G7umcn/zWGPUo8Q8VpDj16x3hKz++zVviRNRmXu5cpN+Q==",
"requires": {
"debug": "^4.1.1"
- },
- "dependencies": {
- "debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "requires": {
- "ms": "2.1.2"
- }
- },
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- }
}
},
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
- },
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -569,6 +781,14 @@
"esprima": "^4.0.0"
}
},
+ "json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ },
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
@@ -577,6 +797,19 @@
"graceful-fs": "^4.1.6"
}
},
+ "libsodium": {
+ "version": "0.7.10",
+ "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.10.tgz",
+ "integrity": "sha512-eY+z7hDrDKxkAK+QKZVNv92A5KYkxfvIshtBJkmg5TSiCnYqZP3i9OO9whE79Pwgm4jGaoHgkM4ao/b9Cyu4zQ=="
+ },
+ "libsodium-wrappers": {
+ "version": "0.7.10",
+ "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.10.tgz",
+ "integrity": "sha512-pO3F1Q9NPLB/MWIhehim42b/Fwb30JNScCNh8TcQ/kIc+qGLQch8ag8wb0keK3EP5kbGakk1H8Wwo7v+36rNQg==",
+ "requires": {
+ "libsodium": "^0.7.0"
+ }
+ },
"log4js": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz",
@@ -587,62 +820,43 @@
"flatted": "^2.0.1",
"rfdc": "^1.1.4",
"streamroller": "^2.2.4"
- },
- "dependencies": {
- "debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "requires": {
- "ms": "2.1.2"
- }
- },
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- }
}
},
+ "make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
+ },
"mediasoup": {
- "version": "3.7.16",
- "resolved": "https://registry.npmjs.org/mediasoup/-/mediasoup-3.7.16.tgz",
- "integrity": "sha512-eD7VJj117zVYF8f4KYgQh2DzaYyzTvBtNa4ocT45eCjt0Y47dveKmfL5LW0LQL1LMYkBhfx/etHLjE/1AhNmwg==",
+ "version": "3.9.5",
+ "resolved": "https://registry.npmjs.org/mediasoup/-/mediasoup-3.9.5.tgz",
+ "integrity": "sha512-8lISnN5cbtSvdqHeuyxhCTFTHudoq/EpgLcDB0d0pT5RG18mZlHF5BwIBSkGxB/nWyeTfTGPpGBiNtKoubbRXA==",
"requires": {
- "@types/node": "^14.14.43",
- "awaitqueue": "^2.3.3",
- "debug": "^4.3.1",
+ "@types/node": "^16.11.10",
+ "debug": "^4.3.3",
"h264-profile-level-id": "^1.0.1",
- "netstring": "^0.3.0",
"random-number": "^0.0.9",
- "supports-color": "^8.1.1",
+ "supports-color": "^9.2.1",
"uuid": "^8.3.2"
},
"dependencies": {
"@types/node": {
- "version": "14.17.3",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.3.tgz",
- "integrity": "sha512-e6ZowgGJmTuXa3GyaPbTGxX17tnThl2aSSizrFthQ7m9uLGZBXiGhgE55cjRZTF5kjZvYn9EOPOMljdjwbflxw=="
- },
- "debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "requires": {
- "ms": "2.1.2"
- }
- },
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ "version": "16.11.19",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.19.tgz",
+ "integrity": "sha512-BPAcfDPoHlRQNKktbsbnpACGdypPFBuX4xQlsWDE7B8XXcfII+SpOLay3/qZmCLb39kV5S1RTYwXdkx2lwLYng=="
}
}
},
- "netstring": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/netstring/-/netstring-0.3.0.tgz",
- "integrity": "sha1-ho3FsgxY0/cwVTHUk2jqqr0ZtxI="
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node-turn": {
"version": "0.0.6",
@@ -664,6 +878,11 @@
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA=="
},
+ "sdp-transform": {
+ "version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.14.1.tgz",
+ "integrity": "sha512-RjZyX3nVwJyCuTo5tGPx+PZWkDMCg7oOLpSlhjDdZfwUoNqG1mM8nyj31IGHyaPWXhjbP7cdK3qZ2bmkJ1GzRw=="
+ },
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -683,28 +902,48 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz",
"integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA=="
- },
- "debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "requires": {
- "ms": "2.1.2"
- }
- },
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM="
+ },
"supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.1.tgz",
+ "integrity": "sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ=="
+ },
+ "ts-node": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz",
+ "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==",
+ "dev": true,
"requires": {
- "has-flag": "^4.0.0"
+ "@cspotcode/source-map-support": "0.7.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "yn": "3.1.1"
+ }
+ },
+ "tsconfig-paths": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
+ "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==",
+ "requires": {
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.1",
+ "minimist": "^1.2.0",
+ "strip-bom": "^3.0.0"
}
},
"typescript": {
@@ -728,6 +967,12 @@
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
"requires": {}
+ },
+ "yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true
}
}
}
diff --git a/webrtc/package.json b/webrtc/package.json
index ab9e7486..7419ad0f 100644
--- a/webrtc/package.json
+++ b/webrtc/package.json
@@ -13,12 +13,20 @@
"license": "AGPLV3",
"devDependencies": {
"@types/node": "^15.6.1",
+ "@types/sdp-transform": "^2.4.5",
"@types/ws": "^7.4.4",
+ "ts-node": "^10.4.0",
"typescript": "^4.3.2"
},
"dependencies": {
- "mediasoup": "^3.7.16",
+ "@types/libsodium-wrappers": "^0.7.9",
+ "dotenv": "^12.0.4",
+ "libsodium": "^0.7.10",
+ "libsodium-wrappers": "^0.7.10",
+ "mediasoup": "^3.9.5",
"node-turn": "^0.0.6",
+ "sdp-transform": "^2.14.1",
+ "tsconfig-paths": "^3.12.0",
"ws": "^7.4.6"
}
}
diff --git a/webrtc/src/Server.ts b/webrtc/src/Server.ts
index 6591691c..a43768ac 100644
--- a/webrtc/src/Server.ts
+++ b/webrtc/src/Server.ts
@@ -1,46 +1,198 @@
import { Server as WebSocketServer } from "ws";
-import { Config, db } from "@fosscord/util";
-import mediasoup from "mediasoup";
+import { WebSocket, CLOSECODES } from "@fosscord/gateway";
+import { Config, initDatabase } from "@fosscord/util";
+import OPCodeHandlers, { Payload } from "./opcodes";
+import { setHeartbeat } from "./util";
+import * as mediasoup from "mediasoup";
+import { types as MediasoupTypes } from "mediasoup";
+import udp from "dgram";
+import sodium from "libsodium-wrappers";
var port = Number(process.env.PORT);
if (isNaN(port)) port = 3004;
export class Server {
public ws: WebSocketServer;
- public turn: any;
+ public mediasoupWorkers: MediasoupTypes.Worker[] = [];
+ public mediasoupRouters: MediasoupTypes.Router[] = [];
+ public mediasoupTransports: MediasoupTypes.WebRtcTransport[] = [];
+ public mediasoupProducers: MediasoupTypes.Producer[] = [];
+ public mediasoupConsumers: MediasoupTypes.Consumer[] = [];
+
+ public decryptKey: number[] = [];
+ public testUdp = udp.createSocket("udp6");
constructor() {
this.ws = new WebSocketServer({
port,
maxPayload: 4096,
});
- this.ws.on("connection", (socket) => {
- socket.on("message", (message) => {
- socket.emit(
- JSON.stringify({
- op: 2,
- d: {
- ssrc: 1,
- ip: "127.0.0.1",
- port: 3004,
- modes: [
- "xsalsa20_poly1305",
- "xsalsa20_poly1305_suffix",
- "xsalsa20_poly1305_lite",
- ],
- heartbeat_interval: 1,
- },
- })
- );
+ this.ws.on("connection", async (socket: WebSocket) => {
+ await setHeartbeat(socket);
+
+ socket.on("message", async (message: string) => {
+ const payload: Payload = JSON.parse(message);
+
+ if (OPCodeHandlers[payload.op])
+ try {
+ await OPCodeHandlers[payload.op].call(this, socket, payload);
+ }
+ catch (e) {
+ console.error(e);
+ socket.close(CLOSECODES.Unknown_error);
+ }
+ else {
+ console.error(`Unimplemented`, payload);
+ socket.close(CLOSECODES.Unknown_opcode);
+ }
});
});
+
+ this.testUdp.bind(50001);
+ this.testUdp.on("message", (msg, rinfo) => {
+ //random key from like, the libsodium examples on npm lol
+
+ //give me my remote port?
+ if (sodium.to_hex(msg) == "0001004600000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") {
+ this.testUdp.send(Buffer.from([rinfo.port, 0]), rinfo.port, rinfo.address);
+ console.log(`got magic packet to send remote port? ${rinfo.address}:${rinfo.port}`);
+ return;
+ }
+
+ //Hello
+ if (sodium.to_hex(msg) == "0100000000000000") {
+ console.log(`[UDP] client helloed`);
+ return;
+ }
+
+ const nonce = Buffer.concat([msg.slice(-4), Buffer.from("\x00".repeat(20))]);
+ console.log(`[UDP] nonce for this message: ${nonce.toString("hex")}`);
+
+ console.log(`[UDP] message: ${sodium.to_hex(msg)}`);
+
+ let encrypted;
+ if (msg.slice(0, 2).indexOf("\x81\xc9") == 0) {
+ encrypted = msg.slice(0x18, -4);
+ }
+ else if (msg.slice(0, 2).indexOf("\x90\x78") == 0) {
+ encrypted = msg.slice(0x1C, -4);
+ }
+ else {
+ encrypted = msg.slice(0x18, -4);
+ console.log(`wtf header received: ${encrypted.toString("hex")}`);
+ }
+
+ if (sodium.to_hex(msg).indexOf("80c8000600000001") == 0) {
+ //call status
+
+ try {
+ const decrypted = sodium.crypto_secretbox_open_easy(encrypted, nonce, Uint8Array.from(this.decryptKey));
+ console.log("[UDP] [ call status ]" + decrypted);
+ }
+ catch (e) {
+ console.error(`[UDP] decrypt failure\n${e}\n${encrypted.toString("base64")}`);
+ }
+ return;
+ }
+
+ try {
+ const decrypted = sodium.crypto_secretbox_open_easy(encrypted, nonce, Uint8Array.from(this.decryptKey));
+ console.log("[UDP] " + decrypted);
+ }
+ catch (e) {
+ console.error(`[UDP] decrypt failure\n${e}\n${msg.toString("base64")}`);
+ }
+ });
}
async listen(): Promise<void> {
// @ts-ignore
- await (db as Promise<Connection>);
+ await initDatabase();
await Config.init();
+ //await this.createWorkers();
console.log("[DB] connected");
console.log(`[WebRTC] online on 0.0.0.0:${port}`);
}
+
+ async createWorkers(): Promise<void> {
+ const numWorkers = 1;
+ for (let i = 0; i < numWorkers; i++) {
+ const worker = await mediasoup.createWorker({ logLevel: "debug", logTags: ["dtls", "ice", "info", "message", "bwe"] });
+ if (!worker) return;
+
+ worker.on("died", () => {
+ console.error("mediasoup worker died");
+ });
+
+ worker.observer.on("newrouter", async (router: MediasoupTypes.Router) => {
+ console.log("new router created [id:%s]", router.id);
+
+ this.mediasoupRouters.push(router);
+
+ router.observer.on("newtransport", async (transport: MediasoupTypes.WebRtcTransport) => {
+ console.log("new transport created [id:%s]", transport.id);
+
+ await transport.enableTraceEvent();
+
+ transport.on('dtlsstatechange', (dtlsstate) => {
+ console.log(dtlsstate);
+ });
+
+ transport.on("sctpstatechange", (sctpstate) => {
+ console.log(sctpstate);
+ });
+
+ router.observer.on("newrtpobserver", (rtpObserver: MediasoupTypes.RtpObserver) => {
+ console.log("new RTP observer created [id:%s]", rtpObserver.id);
+
+ // rtpObserver.observer.on("")
+ });
+
+ transport.on("connect", () => {
+ console.log("transport connect");
+ });
+
+ transport.observer.on("newproducer", (producer: MediasoupTypes.Producer) => {
+ console.log("new producer created [id:%s]", producer.id);
+
+ this.mediasoupProducers.push(producer);
+ });
+
+ transport.observer.on("newconsumer", (consumer: MediasoupTypes.Consumer) => {
+ console.log("new consumer created [id:%s]", consumer.id);
+
+ this.mediasoupConsumers.push(consumer);
+
+ consumer.on("rtp", (rtpPacket) => {
+ console.log(rtpPacket);
+ });
+ });
+
+ transport.observer.on("newdataproducer", (dataProducer) => {
+ console.log("new data producer created [id:%s]", dataProducer.id);
+ });
+
+ transport.on("trace", (trace) => {
+ console.log(trace);
+ });
+
+ this.mediasoupTransports.push(transport);
+ });
+ });
+
+ await worker.createRouter({
+ mediaCodecs: [
+ {
+ kind: "audio",
+ mimeType: "audio/opus",
+ clockRate: 48000,
+ channels: 2,
+ preferredPayloadType: 111,
+ },
+ ],
+ });
+
+ this.mediasoupWorkers.push(worker);
+ }
+ }
}
diff --git a/webrtc/src/opcodes/Connect.ts b/webrtc/src/opcodes/Connect.ts
new file mode 100644
index 00000000..1f874a44
--- /dev/null
+++ b/webrtc/src/opcodes/Connect.ts
@@ -0,0 +1,40 @@
+import { WebSocket } from "@fosscord/gateway";
+import { Payload } from "./index";
+import { Server } from "../Server"
+
+/*
+Sent by client:
+
+{
+ "op": 12,
+ "d": {
+ "audio_ssrc": 0,
+ "video_ssrc": 0,
+ "rtx_ssrc": 0,
+ "streams": [
+ {
+ "type": "video",
+ "rid": "100",
+ "ssrc": 0,
+ "active": false,
+ "quality": 100,
+ "rtx_ssrc": 0,
+ "max_bitrate": 2500000,
+ "max_framerate": 20,
+ "max_resolution": {
+ "type": "fixed",
+ "width": 1280,
+ "height": 720
+ }
+ }
+ ]
+ }
+}
+*/
+
+export async function onConnect(this: Server, socket: WebSocket, data: Payload) {
+ socket.send(JSON.stringify({ //what is op 15?
+ op: 15,
+ d: { any: 100 }
+ }))
+}
\ No newline at end of file
diff --git a/webrtc/src/opcodes/Heartbeat.ts b/webrtc/src/opcodes/Heartbeat.ts
new file mode 100644
index 00000000..47f33f76
--- /dev/null
+++ b/webrtc/src/opcodes/Heartbeat.ts
@@ -0,0 +1,8 @@
+import { WebSocket } from "@fosscord/gateway";
+import { Payload } from "./index";
+import { setHeartbeat } from "../util";
+import { Server } from "../Server"
+
+export async function onHeartbeat(this: Server, socket: WebSocket, data: Payload) {
+ await setHeartbeat(socket, data.d);
+}
\ No newline at end of file
diff --git a/webrtc/src/opcodes/Identify.ts b/webrtc/src/opcodes/Identify.ts
new file mode 100644
index 00000000..68452d4f
--- /dev/null
+++ b/webrtc/src/opcodes/Identify.ts
@@ -0,0 +1,63 @@
+import { WebSocket, CLOSECODES } from "@fosscord/gateway";
+import { Payload } from "./index";
+import { VoiceOPCodes, Session, User, Guild } from "@fosscord/util";
+import { Server } from "../Server";
+
+export interface IdentifyPayload extends Payload {
+ d: {
+ server_id: string, //guild id
+ session_id: string, //gateway session
+ streams: Array<{
+ type: string,
+ rid: string, //number
+ quality: number,
+ }>,
+ token: string, //voice_states token
+ user_id: string,
+ video: boolean,
+ };
+}
+
+export async function onIdentify(this: Server, socket: WebSocket, data: IdentifyPayload) {
+
+ const session = await Session.findOneOrFail(
+ { session_id: data.d.session_id, },
+ {
+ where: { user_id: data.d.user_id },
+ relations: ["user"]
+ }
+ );
+ const user = session.user;
+ const guild = await Guild.findOneOrFail({ id: data.d.server_id }, { relations: ["members"] });
+
+ if (!guild.members.find(x => x.id === user.id))
+ return socket.close(CLOSECODES.Invalid_intent);
+
+ // var transport = this.mediasoupTransports[0] || await this.mediasoupRouters[0].createWebRtcTransport({
+ // listenIps: [{ ip: "10.22.64.56" }],
+ // enableUdp: true,
+ // });
+7
+ socket.send(JSON.stringify({
+ op: VoiceOPCodes.READY,
+ d: {
+ streams: data.d.streams ? [...data.d.streams.map(x => ({ ...x, rtx_ssrc: Math.floor(Math.random() * 10000), ssrc: Math.floor(Math.random() * 10000), active: false, }))] : undefined,
+ ssrc: Math.floor(Math.random() * 10000),
+ ip: "127.0.0.1",//transport.iceCandidates[0].ip,
+ port: 50001,//transport.iceCandidates[0].port,
+ modes: [
+ "aead_aes256_gcm_rtpsize",
+ "aead_aes256_gcm",
+ "xsalsa20_poly1305_lite_rtpsize",
+ "xsalsa20_poly1305_lite",
+ "xsalsa20_poly1305_suffix",
+ "xsalsa20_poly1305"
+ ],
+ experiments: [
+ "bwe_conservative_link_estimate",
+ "bwe_remote_locus_client",
+ "fixed_keyframe_interval"
+ ]
+ },
+ }));
+}
\ No newline at end of file
diff --git a/webrtc/src/opcodes/Resume.ts b/webrtc/src/opcodes/Resume.ts
new file mode 100644
index 00000000..856b550c
--- /dev/null
+++ b/webrtc/src/opcodes/Resume.ts
@@ -0,0 +1,24 @@
+import { CLOSECODES, WebSocket } from "@fosscord/gateway";
+import { Payload } from "./index";
+import { Server } from "../Server"
+import { Guild, Session, VoiceOPCodes } from "@fosscord/util";
+
+export async function onResume(this: Server, socket: WebSocket, data: Payload) {
+ const session = await Session.findOneOrFail(
+ { session_id: data.d.session_id, },
+ {
+ where: { user_id: data.d.user_id },
+ relations: ["user"]
+ }
+ );
+ const user = session.user;
+ const guild = await Guild.findOneOrFail({ id: data.d.server_id }, { relations: ["members"] });
+
+ if (!guild.members.find(x => x.id === user.id))
+ return socket.close(CLOSECODES.Invalid_intent);
+
+ socket.send(JSON.stringify({
+ op: VoiceOPCodes.RESUMED,
+ d: null,
+ }))
+}
\ No newline at end of file
diff --git a/webrtc/src/opcodes/SelectProtocol.ts b/webrtc/src/opcodes/SelectProtocol.ts
new file mode 100644
index 00000000..75ab4495
--- /dev/null
+++ b/webrtc/src/opcodes/SelectProtocol.ts
@@ -0,0 +1,177 @@
+import { WebSocket } from "@fosscord/gateway";
+import { Payload } from "./index";
+import { VoiceOPCodes } from "@fosscord/util";
+import { Server } from "../Server";
+import * as mediasoup from "mediasoup";
+import { RtpCodecCapability } from "mediasoup/node/lib/RtpParameters";
+import * as sdpTransform from 'sdp-transform';
+import sodium from "libsodium-wrappers";
+
+/*
+
+ Sent by client:
+{
+ "op": 1,
+ "d": {
+ "protocol": "webrtc",
+ "data": "
+ a=extmap-allow-mixed
+ a=ice-ufrag:vNxb
+ a=ice-pwd:tZvpbVPYEKcnW0gGRPq0OOnh
+ a=ice-options:trickle
+ a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
+ a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
+ a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
+ a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
+ a=rtpmap:111 opus/48000/2
+ a=extmap:14 urn:ietf:params:rtp-hdrext:toffset
+ a=extmap:13 urn:3gpp:video-orientation
+ a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
+ a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
+ a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
+ a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
+ a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
+ a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
+ a=rtpmap:96 VP8/90000
+ a=rtpmap:97 rtx/90000
+ ",
+ "codecs": [
+ {
+ "name": "opus",
+ "type": "audio",
+ "priority": 1000,
+ "payload_type": 111,
+ "rtx_payload_type": null
+ },
+ {
+ "name": "H264",
+ "type": "video",
+ "priority": 1000,
+ "payload_type": 102,
+ "rtx_payload_type": 121
+ },
+ {
+ "name": "VP8",
+ "type": "video",
+ "priority": 2000,
+ "payload_type": 96,
+ "rtx_payload_type": 97
+ },
+ {
+ "name": "VP9",
+ "type": "video",
+ "priority": 3000,
+ "payload_type": 98,
+ "rtx_payload_type": 99
+ }
+ ],
+ "rtc_connection_id": "3faa0b80-b3e2-4bae-b291-273801fbb7ab"
+ }
+}
+*/
+
+export async function onSelectProtocol(this: Server, socket: WebSocket, data: Payload) {
+ // const rtpCapabilities = this.mediasoupRouters[0].rtpCapabilities;
+ // const codecs = rtpCapabilities.codecs as RtpCodecCapability[];
+
+ if (data.d.sdp) {
+ // const transport = this.mediasoupTransports[0]; //whatever
+
+ // const res = sdpTransform.parse(data.d.sdp);
+
+ // const videoCodec = this.mediasoupRouters[0].rtpCapabilities.codecs!.find((x: any) => x.kind === "video");
+ // const audioCodec = this.mediasoupRouters[0].rtpCapabilities.codecs!.find((x: any) => x.kind === "audio");
+
+ // const producer = this.mediasoupProducers[0] || await transport.produce({
+ // kind: "audio",
+ // rtpParameters: {
+ // mid: "audio",
+ // codecs: [{
+ // clockRate: audioCodec!.clockRate,
+ // payloadType: audioCodec!.preferredPayloadType as number,
+ // mimeType: audioCodec!.mimeType,
+ // channels: audioCodec?.channels,
+ // }],
+ // headerExtensions: res.ext?.map(x => ({
+ // id: x.value,
+ // uri: x.uri,
+ // })),
+ // },
+ // paused: false,
+ // });
+
+ // console.log("can consume: " + this.mediasoupRouters[0].canConsume({ producerId: producer.id, rtpCapabilities: rtpCapabilities }));
+
+ // // const consumer = this.mediasoupConsumers[0] || await transport.consume({
+ // // producerId: producer.id,
+ // // paused: false,
+ // // rtpCapabilities,
+ // // });
+
+ // socket.send(JSON.stringify({
+ // op: VoiceOPCodes.SESSION_DESCRIPTION,
+ // d: {
+ // video_codec: videoCodec?.mimeType?.substring(6) || undefined,
+ // // mode: "xsalsa20_poly1305_lite",
+ // media_session_id: transport.id,
+ // audio_codec: audioCodec?.mimeType.substring(6),
+ // secret_key: sodium.from_hex("724b092810ec86d7e35c9d067702b31ef90bc43a7b598626749914d6a3e033ed").buffer,
+ // sdp: `m=audio ${50001} ICE/SDP\n`
+ // + `a=fingerprint:sha-256 ${transport.dtlsParameters.fingerprints.find(x => x.algorithm === "sha-256")?.value}\n`
+ // + `c=IN IP4 ${transport.iceCandidates[0].ip}\n`
+ // + `t=0 0\n`
+ // + `a=ice-lite\n`
+ // + `a=rtcp-mux\n`
+ // + `a=rtcp:${50001}\n`
+ // + `a=ice-ufrag:${transport.iceParameters.usernameFragment}\n`
+ // + `a=ice-pwd:${transport.iceParameters.password}\n`
+ // + `a=fingerprint:sha-256 ${transport.dtlsParameters.fingerprints.find(x => x.algorithm === "sha-256")?.value}\n`
+ // + `a=candidate:1 1 ${transport.iceCandidates[0].protocol.toUpperCase()} ${transport.iceCandidates[0].priority} ${transport.iceCandidates[0].ip} ${50001} typ ${transport.iceCandidates[0].type}`
+ // }
+ // }));
+ return;
+ }
+ /*
+ {
+ "video_codec":"H264",
+ "sdp":
+ "
+ m=audio 50010 ICE/SDP
+ a=fingerprint:sha-256 4A:79:94:16:44:3F:BD:05:41:5A:C7:20:F3:12:54:70:00:73:5D:33:00:2D:2C:80:9B:39:E1:9F:2D:A7:49:87
+ c=IN IP4 109.200.214.158
+ a=rtcp:50010
+ a=ice-ufrag:+npq
+ a=ice-pwd:+jf7jAesMeHHby43FRqWTy
+ a=fingerprint:sha-256 4A:79:94:16:44:3F:BD:05:41:5A:C7:20:F3:12:54:70:00:73:5D:33:00:2D:2C:80:9B:39:E1:9F:2D:A7:49:87
+ a=candidate:1 1 UDP 4261412862 109.200.214.158 50010 typ host",
+ "media_session_id":"59265c94fa13e313492c372c4c8da801
+ ",
+ "audio_codec":"opus"
+ }
+ */
+
+
+ /*
+ {
+ "video_codec": "H264",
+ "secret_key": [36, 80, 96, 53, 95, 149, 253, 16, 137, 186, 238, 222, 251, 180, 94, 150, 112, 137, 192, 109, 69, 79, 218, 111, 217, 197, 56, 74, 18, 41, 51, 140],
+ "mode": "aead_aes256_gcm_rtpsize",
+ "media_session_id": "797575a97a87b63e81e2399348b97ad1",
+ "audio_codec": "opus"
+ };
+ */
+
+ this.decryptKey = [...sodium.randombytes_buf(sodium.crypto_secretbox_KEYBYTES)];
+ console.log(this.decryptKey.map(x => String.fromCharCode(x)).join(""));
+
+ socket.send(JSON.stringify({
+ op:VoiceOPCodes.SESSION_DESCRIPTION,
+ d: {
+ video_codec: "H264",
+ secret_key: this.decryptKey,
+ mode: "aead_aes256_gcm_rtpsize",
+ media_session_id: "blah blah blah",
+ audio_codec: "opus",
+ }
+ }));
+}
\ No newline at end of file
diff --git a/webrtc/src/opcodes/Speaking.ts b/webrtc/src/opcodes/Speaking.ts
new file mode 100644
index 00000000..861a7c3d
--- /dev/null
+++ b/webrtc/src/opcodes/Speaking.ts
@@ -0,0 +1,7 @@
+import { WebSocket } from "@fosscord/gateway";
+import { Payload } from "./index"
+import { VoiceOPCodes } from "@fosscord/util";
+import { Server } from "../Server"
+
+export async function onSpeaking(this: Server, socket: WebSocket, data: Payload) {
+}
\ No newline at end of file
diff --git a/webrtc/src/opcodes/Version.ts b/webrtc/src/opcodes/Version.ts
new file mode 100644
index 00000000..0ea6eb4d
--- /dev/null
+++ b/webrtc/src/opcodes/Version.ts
@@ -0,0 +1,14 @@
+import { WebSocket } from "@fosscord/gateway";
+import { Payload } from "./index";
+import { setHeartbeat } from "../util";
+import { Server } from "../Server"
+
+export async function onVersion(this: Server, socket: WebSocket, data: Payload) {
+ socket.send(JSON.stringify({
+ op: 16,
+ d: {
+ voice: "0.8.31", //version numbers?
+ rtc_worker: "0.3.18",
+ }
+ }))
+}
\ No newline at end of file
diff --git a/webrtc/src/opcodes/index.ts b/webrtc/src/opcodes/index.ts
new file mode 100644
index 00000000..d0f40bc2
--- /dev/null
+++ b/webrtc/src/opcodes/index.ts
@@ -0,0 +1,40 @@
+import { WebSocket } from "@fosscord/gateway";
+import { VoiceOPCodes } from "@fosscord/util";
+
+export interface Payload {
+ op: number;
+ d: any;
+ s: number;
+ t: string;
+}
+
+import { onIdentify } from "./Identify";
+import { onSelectProtocol } from "./SelectProtocol";
+import { onHeartbeat } from "./Heartbeat";
+import { onSpeaking } from "./Speaking";
+import { onResume } from "./Resume";
+import { onConnect } from "./Connect";
+
+import { onVersion } from "./Version";
+
+export type OPCodeHandler = (this: WebSocket, data: Payload) => any;
+
+export default {
+ [VoiceOPCodes.IDENTIFY]: onIdentify, //op 0
+ [VoiceOPCodes.SELECT_PROTOCOL]: onSelectProtocol, //op 1
+ //op 2 voice_ready
+ [VoiceOPCodes.HEARTBEAT]: onHeartbeat, //op 3
+ //op 4 session_description
+ [VoiceOPCodes.SPEAKING]: onSpeaking, //op 5
+ //op 6 heartbeat_ack
+ [VoiceOPCodes.RESUME]: onResume, //op 7
+ //op 8 hello
+ //op 9 resumed
+ //op 10?
+ //op 11?
+ [VoiceOPCodes.CLIENT_CONNECT]: onConnect, //op 12
+ //op 13?
+ //op 15?
+ //op 16? empty data on client send but server sends {"voice":"0.8.24+bugfix.voice.streams.opt.branch-ffcefaff7","rtc_worker":"0.3.14-crypto-collision-copy"}
+ [VoiceOPCodes.VERSION]: onVersion,
+};
\ No newline at end of file
diff --git a/webrtc/src/start.ts b/webrtc/src/start.ts
index 68867a2c..f902ec1b 100644
--- a/webrtc/src/start.ts
+++ b/webrtc/src/start.ts
@@ -1,3 +1,11 @@
+import { config } from "dotenv";
+config();
+
+//testing
+process.env.DATABASE = "../bundle/database.db";
+process.env.DEBUG = "mediasoup*"
+
import { Server } from "./Server";
const server = new Server();
+server.listen();
\ No newline at end of file
diff --git a/webrtc/src/util/Heartbeat.ts b/webrtc/src/util/Heartbeat.ts
new file mode 100644
index 00000000..8c5e3a7a
--- /dev/null
+++ b/webrtc/src/util/Heartbeat.ts
@@ -0,0 +1,23 @@
+import { WebSocket, CLOSECODES } from "@fosscord/gateway";
+import { VoiceOPCodes } from "@fosscord/util";
+
+export async function setHeartbeat(socket: WebSocket, nonce?: Number) {
+ if (socket.heartbeatTimeout) clearTimeout(socket.heartbeatTimeout);
+
+ socket.heartbeatTimeout = setTimeout(() => {
+ return socket.close(CLOSECODES.Session_timed_out);
+ }, 1000 * 45);
+
+ if (!nonce) {
+ socket.send(JSON.stringify({
+ op: VoiceOPCodes.HELLO,
+ d: {
+ v: 5,
+ heartbeat_interval: 13750,
+ }
+ }));
+ }
+ else {
+ socket.send(JSON.stringify({ op: VoiceOPCodes.HEARTBEAT_ACK, d: nonce }));
+ }
+}
\ No newline at end of file
diff --git a/webrtc/src/util/index.ts b/webrtc/src/util/index.ts
new file mode 100644
index 00000000..e8557452
--- /dev/null
+++ b/webrtc/src/util/index.ts
@@ -0,0 +1 @@
+export * from "./Heartbeat"
\ No newline at end of file
diff --git a/webrtc/tsconfig.json b/webrtc/tsconfig.json
index 77353db0..fb93b0bd 100644
--- a/webrtc/tsconfig.json
+++ b/webrtc/tsconfig.json
@@ -1,5 +1,8 @@
{
"include": ["src/**/*.ts"],
+ "ts-node": {
+ "require": ["tsconfig-paths/register"],
+ },
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
@@ -18,7 +21,7 @@
"sourceMap": true /* Generates corresponding '.map' file. */,
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./dist/" /* Redirect output structure to the directory. */,
- "rootDir": "./src/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
+ "rootDir": "../" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
@@ -62,11 +65,19 @@
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
- // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
- // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
+ "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
+ "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true /* Skip type checking of declaration files. */,
- "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
+ "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
+
+ "baseUrl": "../",
+ "paths": {
+ "@fosscord/api": ["api/src/index"],
+ "@fosscord/gateway": ["gateway/src/index"],
+ "@fosscord/cdn": ["cdn/src/index"],
+ "@fosscord/util": ["util/src/index"]
+ },
}
}
|