djs-selfbot-v13 3.7.32 → 3.7.34
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/package.json +8 -1
- package/src/client/Client.js +68 -1
- package/src/client/voice/ClientVoiceManager.js +95 -17
- package/src/client/voice/StreamSession.js +193 -0
- package/src/client/voice/VoiceConnection.js +266 -19
- package/src/client/voice/WebRtcStreamSession.js +191 -0
- package/src/client/voice/dispatcher/AnnexBDispatcher.js +64 -11
- package/src/client/voice/dispatcher/BaseDispatcher.js +13 -9
- package/src/client/voice/dispatcher/VideoDispatcher.js +33 -0
- package/src/client/voice/networking/DAVESession.js +234 -0
- package/src/client/voice/networking/VoiceWebSocket.js +240 -24
- package/src/client/voice/player/MediaPlayer.js +3 -1
- package/src/client/voice/player/processing/AnnexBBitstreamReaderWriter.js +137 -0
- package/src/client/voice/player/processing/SPSVUIRewriter.js +203 -0
- package/src/client/voice/receiver/PacketHandler.js +11 -4
- package/src/errors/Messages.js +8 -1
- package/src/util/Constants.js +12 -0
- package/typings/index.d.ts +36 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { AnnexBBitstreamReader, AnnexBBitstreamWriter } = require('./AnnexBBitstreamReaderWriter');
|
|
4
|
+
|
|
5
|
+
function rewriteSPSVUI(buffer) {
|
|
6
|
+
const reader = new AnnexBBitstreamReader(buffer.subarray(1));
|
|
7
|
+
const writer = new AnnexBBitstreamWriter();
|
|
8
|
+
|
|
9
|
+
const readBit = (n = 1) => reader.readBits(n);
|
|
10
|
+
const writeBit = (v, n = 1) => writer.writeBits(v, n);
|
|
11
|
+
const readU = n => reader.readUnsigned(n);
|
|
12
|
+
const writeU = (v, n) => writer.writeUnsigned(v, n);
|
|
13
|
+
const readUE = () => reader.readUnsignedExpGolomb();
|
|
14
|
+
const writeUE = v => writer.writeUnsignedExpGolomb(v);
|
|
15
|
+
const readSE = () => reader.readSignedExpGolomb();
|
|
16
|
+
const writeSE = v => writer.writeSignedExpGolomb(v);
|
|
17
|
+
|
|
18
|
+
writeU(buffer[0], 8);
|
|
19
|
+
|
|
20
|
+
const profile_idc = readU(8);
|
|
21
|
+
writeU(profile_idc, 8);
|
|
22
|
+
const constraint_flags = readU(8);
|
|
23
|
+
writeU(constraint_flags, 8);
|
|
24
|
+
const level_idc = readU(8);
|
|
25
|
+
writeU(level_idc, 8);
|
|
26
|
+
const seq_parameter_set_id = readUE();
|
|
27
|
+
writeUE(seq_parameter_set_id);
|
|
28
|
+
|
|
29
|
+
const highProfiles = new Set([100, 110, 122, 244, 44, 83, 86, 118, 128, 138, 144]);
|
|
30
|
+
if (highProfiles.has(profile_idc)) {
|
|
31
|
+
const chroma_format_idc = readUE();
|
|
32
|
+
writeUE(chroma_format_idc);
|
|
33
|
+
if (chroma_format_idc === 3) writeBit(readBit(1), 1);
|
|
34
|
+
writeUE(readUE());
|
|
35
|
+
writeUE(readUE());
|
|
36
|
+
writeBit(readBit(1), 1);
|
|
37
|
+
const seq_scaling_matrix_present_flag = readBit(1);
|
|
38
|
+
writeBit(seq_scaling_matrix_present_flag, 1);
|
|
39
|
+
if (seq_scaling_matrix_present_flag) {
|
|
40
|
+
const scalingCount = chroma_format_idc !== 3 ? 8 : 12;
|
|
41
|
+
for (let i = 0; i < scalingCount; i++) {
|
|
42
|
+
const seq_scaling_list_present_flag = readBit(1);
|
|
43
|
+
writeBit(seq_scaling_list_present_flag, 1);
|
|
44
|
+
if (seq_scaling_list_present_flag) {
|
|
45
|
+
const size = i < 6 ? 16 : 64;
|
|
46
|
+
let lastScale = 8;
|
|
47
|
+
for (let j = 0; j < size; j++) {
|
|
48
|
+
const delta = readSE();
|
|
49
|
+
writeSE(delta);
|
|
50
|
+
const nextScale = (lastScale + delta + 256) % 256;
|
|
51
|
+
if (nextScale !== 0) lastScale = nextScale;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
writeUE(readUE());
|
|
59
|
+
const pic_order_cnt_type = readUE();
|
|
60
|
+
writeUE(pic_order_cnt_type);
|
|
61
|
+
if (pic_order_cnt_type === 0) writeUE(readUE());
|
|
62
|
+
else if (pic_order_cnt_type === 1) {
|
|
63
|
+
writeBit(readBit(1), 1);
|
|
64
|
+
writeSE(readSE());
|
|
65
|
+
writeSE(readSE());
|
|
66
|
+
const num_ref_frames_in_pic_order_cnt_cycle = readUE();
|
|
67
|
+
writeUE(num_ref_frames_in_pic_order_cnt_cycle);
|
|
68
|
+
for (let i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) writeSE(readSE());
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const max_num_ref_frames = readUE();
|
|
72
|
+
writeUE(max_num_ref_frames);
|
|
73
|
+
writeBit(readBit(1), 1);
|
|
74
|
+
writeUE(readUE());
|
|
75
|
+
writeUE(readUE());
|
|
76
|
+
const frame_mbs_only_flag = readBit(1);
|
|
77
|
+
writeBit(frame_mbs_only_flag, 1);
|
|
78
|
+
if (frame_mbs_only_flag === 0) writeBit(readBit(1), 1);
|
|
79
|
+
writeBit(readBit(1), 1);
|
|
80
|
+
const frame_cropping_flag = readBit(1);
|
|
81
|
+
writeBit(frame_cropping_flag, 1);
|
|
82
|
+
if (frame_cropping_flag) {
|
|
83
|
+
writeUE(readUE());
|
|
84
|
+
writeUE(readUE());
|
|
85
|
+
writeUE(readUE());
|
|
86
|
+
writeUE(readUE());
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function addBitstreamRestriction() {
|
|
90
|
+
writeBit(1, 1);
|
|
91
|
+
writeUE(2);
|
|
92
|
+
writeUE(1);
|
|
93
|
+
writeUE(16);
|
|
94
|
+
writeUE(16);
|
|
95
|
+
writeUE(0);
|
|
96
|
+
writeUE(max_num_ref_frames);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const vui_parameters_present_flag = readBit(1);
|
|
100
|
+
writeBit(1, 1);
|
|
101
|
+
if (!vui_parameters_present_flag) {
|
|
102
|
+
writeBit(0, 2);
|
|
103
|
+
writeBit(0, 1);
|
|
104
|
+
writeBit(0, 5);
|
|
105
|
+
writeBit(1, 1);
|
|
106
|
+
addBitstreamRestriction();
|
|
107
|
+
} else {
|
|
108
|
+
const aspect_ratio_info_present_flag = readBit(1);
|
|
109
|
+
writeBit(aspect_ratio_info_present_flag, 1);
|
|
110
|
+
if (aspect_ratio_info_present_flag) {
|
|
111
|
+
const aspect_ratio_idc = readU(8);
|
|
112
|
+
writeU(aspect_ratio_idc, 8);
|
|
113
|
+
if (aspect_ratio_idc === 255) {
|
|
114
|
+
writeU(readU(16), 16);
|
|
115
|
+
writeU(readU(16), 16);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const overscan_info_present_flag = readBit(1);
|
|
119
|
+
writeBit(overscan_info_present_flag, 1);
|
|
120
|
+
if (overscan_info_present_flag) writeBit(readBit(1), 1);
|
|
121
|
+
const video_signal_type_present_flag = readBit(1);
|
|
122
|
+
writeBit(0, 1);
|
|
123
|
+
if (video_signal_type_present_flag) {
|
|
124
|
+
readBit(3);
|
|
125
|
+
readBit(1);
|
|
126
|
+
const colour_description_present_flag = readBit(1);
|
|
127
|
+
if (colour_description_present_flag) {
|
|
128
|
+
readU(8);
|
|
129
|
+
readU(8);
|
|
130
|
+
readU(8);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const chroma_loc_info_present_flag = readBit(1);
|
|
134
|
+
writeBit(chroma_loc_info_present_flag, 1);
|
|
135
|
+
if (chroma_loc_info_present_flag) {
|
|
136
|
+
writeUE(readUE());
|
|
137
|
+
writeUE(readUE());
|
|
138
|
+
}
|
|
139
|
+
const timing_info_present_flag = readBit(1);
|
|
140
|
+
writeBit(timing_info_present_flag, 1);
|
|
141
|
+
if (timing_info_present_flag) {
|
|
142
|
+
writeU(readU(32), 32);
|
|
143
|
+
writeU(readU(32), 32);
|
|
144
|
+
writeBit(readBit(1), 1);
|
|
145
|
+
}
|
|
146
|
+
const nal_hrd_parameters_present_flag = readBit(1);
|
|
147
|
+
writeBit(nal_hrd_parameters_present_flag, 1);
|
|
148
|
+
if (nal_hrd_parameters_present_flag) {
|
|
149
|
+
const cpb_cnt_minus1 = readUE();
|
|
150
|
+
writeUE(cpb_cnt_minus1);
|
|
151
|
+
writeBit(readBit(4), 4);
|
|
152
|
+
writeBit(readBit(4), 4);
|
|
153
|
+
for (let i = 0; i <= cpb_cnt_minus1; i++) {
|
|
154
|
+
writeUE(readUE());
|
|
155
|
+
writeUE(readUE());
|
|
156
|
+
writeBit(readBit(1), 1);
|
|
157
|
+
}
|
|
158
|
+
writeBit(readBit(5), 5);
|
|
159
|
+
writeBit(readBit(5), 5);
|
|
160
|
+
writeBit(readBit(5), 5);
|
|
161
|
+
writeBit(readBit(5), 5);
|
|
162
|
+
}
|
|
163
|
+
const vcl_hrd_parameters_present_flag = readBit(1);
|
|
164
|
+
writeBit(vcl_hrd_parameters_present_flag, 1);
|
|
165
|
+
if (vcl_hrd_parameters_present_flag) {
|
|
166
|
+
const cpb_cnt_minus1 = readUE();
|
|
167
|
+
writeUE(cpb_cnt_minus1);
|
|
168
|
+
writeBit(readBit(4), 4);
|
|
169
|
+
writeBit(readBit(4), 4);
|
|
170
|
+
for (let i = 0; i <= cpb_cnt_minus1; i++) {
|
|
171
|
+
writeUE(readUE());
|
|
172
|
+
writeUE(readUE());
|
|
173
|
+
writeBit(readBit(1), 1);
|
|
174
|
+
}
|
|
175
|
+
writeBit(readBit(5), 5);
|
|
176
|
+
writeBit(readBit(5), 5);
|
|
177
|
+
writeBit(readBit(5), 5);
|
|
178
|
+
writeBit(readBit(5), 5);
|
|
179
|
+
}
|
|
180
|
+
if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) writeBit(readBit(1), 1);
|
|
181
|
+
writeBit(readBit(1), 1);
|
|
182
|
+
const bitstream_restriction_flag = readBit(1);
|
|
183
|
+
writeBit(1, 1);
|
|
184
|
+
if (!bitstream_restriction_flag) addBitstreamRestriction();
|
|
185
|
+
else {
|
|
186
|
+
writeBit(readBit(1), 1);
|
|
187
|
+
writeUE(readUE());
|
|
188
|
+
writeUE(readUE());
|
|
189
|
+
writeUE(readUE());
|
|
190
|
+
writeUE(readUE());
|
|
191
|
+
readUE();
|
|
192
|
+
writeUE(0);
|
|
193
|
+
readUE();
|
|
194
|
+
writeUE(max_num_ref_frames);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
writeBit(1, 1);
|
|
199
|
+
writer.flush();
|
|
200
|
+
return writer.toBuffer();
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
module.exports = { rewriteSPSVUI };
|
|
@@ -72,7 +72,7 @@ class PacketHandler extends EventEmitter {
|
|
|
72
72
|
return stream;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
parseBuffer(buffer) {
|
|
75
|
+
parseBuffer(buffer, userId) {
|
|
76
76
|
const { secret_key, mode } = this.receiver.connection.authentication;
|
|
77
77
|
// Open packet
|
|
78
78
|
if (!secret_key) return new Error('secret_key cannot be null or undefined');
|
|
@@ -129,7 +129,14 @@ class PacketHandler extends EventEmitter {
|
|
|
129
129
|
}
|
|
130
130
|
*/
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
const rtp = RtpPacket.deSerialize(Buffer.concat([header, packet]));
|
|
133
|
+
const dave = this.connection.dave;
|
|
134
|
+
if (dave && userId && rtp.payload) {
|
|
135
|
+
const decrypted = dave.decrypt(rtp.payload, userId);
|
|
136
|
+
if (decrypted === null) return new Error('DAVE_DECRYPT_FAILED');
|
|
137
|
+
rtp.payload = decrypted;
|
|
138
|
+
}
|
|
139
|
+
return rtp;
|
|
133
140
|
}
|
|
134
141
|
|
|
135
142
|
audioReceiver(ssrc, userStat, opusPacket) {
|
|
@@ -233,12 +240,12 @@ class PacketHandler extends EventEmitter {
|
|
|
233
240
|
let userStat, packet;
|
|
234
241
|
if (this.connection.ssrcMap.has(ssrc)) {
|
|
235
242
|
userStat = this.connection.ssrcMap.get(ssrc); // Audio_ssrc
|
|
236
|
-
packet = this.parseBuffer(buffer);
|
|
243
|
+
packet = this.parseBuffer(buffer, userStat.userId);
|
|
237
244
|
this.audioReceiver(ssrc, userStat, packet);
|
|
238
245
|
this.audioReceiverForStream(ssrc, userStat, packet);
|
|
239
246
|
} else if (this.connection.ssrcMap.has(ssrc - 1)) {
|
|
240
247
|
userStat = this.connection.ssrcMap.get(ssrc - 1); // Video_ssrc
|
|
241
|
-
packet = this.parseBuffer(buffer);
|
|
248
|
+
packet = this.parseBuffer(buffer, userStat.userId);
|
|
242
249
|
this.videoReceiver(ssrc, userStat, packet);
|
|
243
250
|
}
|
|
244
251
|
if (userStat && !(packet instanceof Error)) this.receiver.emit('receiverData', userStat, packet);
|
package/src/errors/Messages.js
CHANGED
|
@@ -186,7 +186,11 @@ const Messages = {
|
|
|
186
186
|
VOICE_USER_MISSING: "Couldn't resolve the user to create stream.",
|
|
187
187
|
VOICE_JOIN_CHANNEL: (full = false) =>
|
|
188
188
|
`You do not have permission to join this voice channel${full ? '; it is full.' : '.'}`,
|
|
189
|
-
VOICE_CONNECTION_TIMEOUT:
|
|
189
|
+
VOICE_CONNECTION_TIMEOUT:
|
|
190
|
+
'Connection not established within 30 seconds. Close the official Discord app (desktop/mobile) on this account, leave any voice channel, then retry.',
|
|
191
|
+
VOICE_DAVE_REQUIRED: '%s',
|
|
192
|
+
VOICE_SESSION_EXPIRED:
|
|
193
|
+
'Voice session is no longer valid (4006). Quit any other Discord client on this account, leave voice channels, then retry.',
|
|
190
194
|
VOICE_TOKEN_ABSENT: 'Token not provided from voice server packet.',
|
|
191
195
|
VOICE_SESSION_ABSENT: 'Session ID not supplied.',
|
|
192
196
|
VOICE_INVALID_ENDPOINT: 'Invalid endpoint received.',
|
|
@@ -208,6 +212,9 @@ const Messages = {
|
|
|
208
212
|
|
|
209
213
|
STREAM_CONNECTION_READONLY: 'Cannot send data to a read-only stream',
|
|
210
214
|
STREAM_CANNOT_JOIN: 'Cannot join a stream to itself',
|
|
215
|
+
STREAM_URL_REQUIRED: 'A url is required to start a stream.',
|
|
216
|
+
STREAM_CHANNEL_REQUIRED: 'guildId and channelId are required to start a stream.',
|
|
217
|
+
STREAM_CHANNEL_NOT_FOUND: 'The specified voice channel could not be found.',
|
|
211
218
|
VOICE_USER_NOT_STREAMING: 'User is not streaming',
|
|
212
219
|
POLL_ALREADY_EXPIRED: 'This poll has already expired.',
|
|
213
220
|
METHOD_WARNING:
|
package/src/util/Constants.js
CHANGED
|
@@ -284,6 +284,18 @@ exports.VoiceOpcodes = {
|
|
|
284
284
|
MEDIA_SINK_WANTS: 15,
|
|
285
285
|
VOICE_BACKEND_VERSION: 16,
|
|
286
286
|
CHANNEL_OPTIONS_UPDATE: 17,
|
|
287
|
+
CLIENTS_CONNECT: 11,
|
|
288
|
+
DAVE_PREPARE_TRANSITION: 21,
|
|
289
|
+
DAVE_EXECUTE_TRANSITION: 22,
|
|
290
|
+
DAVE_TRANSITION_READY: 23,
|
|
291
|
+
DAVE_PREPARE_EPOCH: 24,
|
|
292
|
+
DAVE_MLS_EXTERNAL_SENDER: 25,
|
|
293
|
+
DAVE_MLS_KEY_PACKAGE: 26,
|
|
294
|
+
DAVE_MLS_PROPOSALS: 27,
|
|
295
|
+
DAVE_MLS_COMMIT_WELCOME: 28,
|
|
296
|
+
DAVE_MLS_ANNOUNCE_COMMIT_TRANSITION: 29,
|
|
297
|
+
DAVE_MLS_WELCOME: 30,
|
|
298
|
+
DAVE_MLS_INVALID_COMMIT_WELCOME: 31,
|
|
287
299
|
};
|
|
288
300
|
|
|
289
301
|
/**
|
package/typings/index.d.ts
CHANGED
|
@@ -918,6 +918,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
|
|
|
918
918
|
}
|
|
919
919
|
>
|
|
920
920
|
>;
|
|
921
|
+
public startStream(options: StartStreamOptions): Promise<StreamSession>;
|
|
921
922
|
|
|
922
923
|
public on<K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => Awaitable<void>): this;
|
|
923
924
|
public on<S extends string | symbol>(
|
|
@@ -1189,6 +1190,41 @@ export class BaseDispatcher extends Writable {
|
|
|
1189
1190
|
public once(event: string, listener: (...args: any[]) => void): this;
|
|
1190
1191
|
}
|
|
1191
1192
|
|
|
1193
|
+
export interface StartStreamOptions {
|
|
1194
|
+
guildId: Snowflake;
|
|
1195
|
+
channelId: Snowflake;
|
|
1196
|
+
url: string;
|
|
1197
|
+
fps?: number;
|
|
1198
|
+
height?: number;
|
|
1199
|
+
width?: number;
|
|
1200
|
+
bitrate?: number;
|
|
1201
|
+
audioBitrate?: number;
|
|
1202
|
+
videoCodec?: 'H264' | 'VP8';
|
|
1203
|
+
preset?: string;
|
|
1204
|
+
audio?: boolean;
|
|
1205
|
+
/** Enable webcam. Default false (screenshare only). */
|
|
1206
|
+
video?: boolean;
|
|
1207
|
+
/** Download HTTP URLs locally before playback. Default true. */
|
|
1208
|
+
downloadHttp?: boolean;
|
|
1209
|
+
/** Max video bitrate in kbps. Default: bitrate * 1.5 */
|
|
1210
|
+
bitrateMax?: number;
|
|
1211
|
+
/** Low-latency encoding and playback. Default true. */
|
|
1212
|
+
lowLatency?: boolean;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
export class StreamSession extends EventEmitter {
|
|
1216
|
+
public readonly client: Client;
|
|
1217
|
+
public readonly voiceConnection: VoiceConnection;
|
|
1218
|
+
public readonly streamConnection: StreamConnection;
|
|
1219
|
+
public pause(): void;
|
|
1220
|
+
public resume(): void;
|
|
1221
|
+
public stop(): void;
|
|
1222
|
+
public replay(): VideoDispatcher;
|
|
1223
|
+
public disconnect(): void;
|
|
1224
|
+
public on(event: 'finish', listener: () => void): this;
|
|
1225
|
+
public once(event: 'finish', listener: () => void): this;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1192
1228
|
export class AudioDispatcher extends VolumeMixin(BaseDispatcher) {
|
|
1193
1229
|
constructor(player: object, options?: StreamOptions, streams?: object);
|
|
1194
1230
|
public readonly bitrateEditable: boolean;
|