🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more →

discord.js-selfbot-v13

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

discord.js-selfbot-v13 - npm Package Compare versions

Comparing version

to
3.4.3

{
"name": "discord.js-selfbot-v13",
"version": "3.4.2",
"version": "3.4.3",
"description": "A unofficial discord.js fork for creating selfbots [Based on discord.js v13]",

@@ -58,11 +58,10 @@ "main": "./src/index.js",

"@sapphire/shapeshift": "^3.9.5",
"deasync": "^0.1.30",
"discord-api-types": "^0.37.103",
"fetch-cookie": "^2.1.0",
"find-process": "^1.4.7",
"form-data": "^4.0.1",
"node-fetch": "^2.6.9",
"fluent-ffmpeg": "^2.1.3",
"prism-media": "^1.3.5",
"qrcode": "^1.5.4",
"tough-cookie": "^4.1.4",
"tree-kill": "^1.2.2",
"undici": "^6.21.0",
"ws": "^8.16.0"

@@ -80,3 +79,2 @@ },

"@types/node": "^20.14.12",
"@types/node-fetch": "^2.6.11",
"@types/ws": "^8.5.10",

@@ -83,0 +81,0 @@ "conventional-changelog-cli": "^2.2.2",

@@ -521,2 +521,24 @@ /* eslint-disable no-unreachable */

/**
* Refresh the Discord CDN links with hashes so they can be usable.
* @param {string[]} urls Discord CDN URLs
* @returns {Promise<Array<{ original: string, refreshed: string }>>}
*/
async refreshAttachmentURL(urls) {
const data = await this.api.attachments('refresh-urls').post({
data: { attachment_urls: urls },
});
/**
{
"refreshed_urls": [
{
"original": "url",
"refreshed": "url with hash"
}
]
}
*/
return data.refreshed_urls;
}
/**
* Options for {@link Client#generateInvite}.

@@ -570,2 +592,3 @@ * @typedef {Object} InviteGenerationOptions

async acceptInvite(invite, options = { bypassOnboarding: true, bypassVerify: true }) {
throw new Error('METHOD_WARNING');
const code = DataResolver.resolveInviteCode(invite);

@@ -692,3 +715,4 @@ if (!code) throw new Error('INVITE_RESOLVE_CODE');

*/
authorizeURL(url, options = { authorize: true, permissions: '0' }) {
authorizeURL(url, options = { authorize: true }) {
throw new Error('METHOD_WARNING');
const pathnameAPI = /\/api\/(v\d{1,2}\/)?oauth2\/authorize/;

@@ -704,4 +728,15 @@ const pathnameURL = /\/oauth2\/authorize/;

const searchParams = Object.fromEntries(url_.searchParams);
options.permissions = `${Permissions.resolve(searchParams.permissions || options.permissions) || 0}`;
options.permissions ??= `${Permissions.resolve(searchParams.permissions || 0)}`;
options.integration_type ??= searchParams.integration_type || 0;
options.location_context = {
guild_id: '10000',
channel_id: '10000',
channel_type: 10000,
};
options.guild_id ??= searchParams.guild_id;
options.authorize ??= true;
delete searchParams.permissions;
delete searchParams.integration_type;
delete searchParams.guild_id;
if (!options.permissions || !options.guild_id) throw new Error('INVALID_OAUTH_OPTIONS');
return this.api.oauth2.authorize.post({

@@ -775,2 +810,5 @@ query: searchParams,

_validateOptions(options = this.options) {
options.captchaSolver = () => {
throw new Error('METHOD_WARNING');
};
if (typeof options.makeCache !== 'function') {

@@ -777,0 +815,0 @@ throw new TypeError('CLIENT_INVALID_OPTION', 'makeCache', 'a function');

@@ -7,4 +7,2 @@ 'use strict';

const { setTimeout } = require('node:timers');
const find = require('find-process');
const kill = require('tree-kill');
const secretbox = require('../util/Secretbox');

@@ -148,16 +146,13 @@

_cleanup() {
if (this.player.dispatcher === this) this.player.dispatcher = null;
if (this.player.dispatcher === this) {
this.player.dispatcher.destroy();
this.player.dispatcher = null;
}
if (this.player.videoDispatcher === this) {
this.player.videoDispatcher.destroy();
this.player.videoDispatcher = null;
}
const { streams } = this;
if (streams.opus) streams.opus.destroy();
if (streams.ffmpeg?.process) {
const ffmpegPid = streams.ffmpeg.process.pid; // But it is ppid ;-;
const args = streams.ffmpeg.process.spawnargs.slice(1).join(' '); // Skip ffmpeg
find('name', 'ffmpeg', true).then(list => {
let process = list.find(o => o.pid === ffmpegPid || o.ppid === ffmpegPid || o.cmd.includes(args));
if (process) {
kill(process.pid);
}
});
streams.ffmpeg.destroy();
}
streams.ffmpeg?.destroy();
}

@@ -164,0 +159,0 @@

@@ -22,2 +22,4 @@ 'use strict';

const { Readable: ReadableStream } = require('stream');
const deasync = require('deasync');
const fluent = require('fluent-ffmpeg');
const prism = require('prism-media');

@@ -30,16 +32,36 @@ const { H264NalSplitter } = require('./processing/AnnexBNalSplitter');

const FFMPEG_ARGUMENTS = [
'-use_wallclock_as_timestamps',
const FFMPEG_OUTPUT_PREFIX = ['-use_wallclock_as_timestamps', '1', '-copyts', '-analyzeduration', '0'];
const FFMPEG_INPUT_PREFIX = [
'-reconnect',
'1',
'-copyts',
'-analyzeduration',
'-reconnect_at_eof',
'1',
'-reconnect_streamed',
'1',
'-reconnect_delay_max',
'4294',
];
const FFMPEG_PCM_ARGUMENTS = ['-f', 's16le', '-ar', '48000', '-ac', '2'];
const FFMPEG_VP8_ARGUMENTS = ['-f', 'ivf', '-deadline', 'realtime', '-c:v', 'libvpx'];
const FFMPEG_H264_ARGUMENTS = options => [
'-c:v',
'libx264',
'-f',
'h264',
'-tune',
'zerolatency',
// '-pix_fmt',
// 'yuv420p',
'-preset',
options?.presetH26x || 'faster',
'-profile:v',
'baseline',
// '-g',
// `${options?.fps}`,
// '-x264-params',
// `keyint=${options?.fps}:min-keyint=${options?.fps}`,
'-bf',
'0',
'-loglevel',
'0',
'-f',
's16le',
'-ar',
'48000',
'-ac',
'2',
'-bsf:v',
'h264_metadata=aud=insert',
];

@@ -89,23 +111,18 @@

this.destroyDispatcher();
const isStream = input instanceof ReadableStream;
const args = isStream ? FFMPEG_ARGUMENTS.slice() : ['-i', input, ...FFMPEG_ARGUMENTS];
const args = [...FFMPEG_OUTPUT_PREFIX, ...FFMPEG_PCM_ARGUMENTS];
if (!isStream) args.unshift('-i', input);
if (options.seek) args.unshift('-ss', String(options.seek));
// Check input
if (typeof input == 'string' && input.startsWith('http')) {
args.unshift(
'-reconnect',
'1',
'-reconnect_at_eof',
'1',
'-reconnect_streamed',
'1',
'-reconnect_delay_max',
'4294',
);
args.unshift(...FFMPEG_INPUT_PREFIX);
}
const ffmpeg = new prism.FFmpeg({ args });
this.emit('debug', `[ffmpeg-audio_process] Spawn process with args:\n${args.join(' ')}`);
ffmpeg.process.stderr.on('data', data => {
this.emit('debug', `[ffmpeg-audio_process]: ${data.toString()}`);
});
streams.ffmpeg = ffmpeg;

@@ -150,15 +167,47 @@ if (isStream) {

this.destroyVideoDispatcher();
const isStream = input instanceof ReadableStream;
// Get video info
let isDone = false;
let data = null;
if (!options?.fps) {
fluent.ffprobe(input, (err, metadata) => {
if (err) {
this.emit('error', err);
isDone = true;
return;
}
let hasAudio = false;
let hasVideo = false;
let fps = 0;
metadata.streams.forEach(stream => {
if (stream.codec_type === 'audio') {
hasAudio = true;
}
if (stream.codec_type === 'video') {
hasVideo = true;
if (stream.avg_frame_rate) {
const frameRate = stream.avg_frame_rate.split('/');
fps = parseFloat(frameRate[0]) / parseFloat(frameRate[1]);
} else if (stream.r_frame_rate) {
const frameRate = stream.r_frame_rate.split('/');
fps = parseFloat(frameRate[0]) / parseFloat(frameRate[1]);
}
}
});
data = {
audio: hasAudio,
video: hasVideo,
fps: hasVideo ? fps : null,
};
isDone = true;
});
deasync.loopWhile(() => !isDone);
}
if (!options?.fps) options.fps = 30;
if (!options?.fps) options.fps = data?.fps || 30;
const args = [
'-i',
'-',
'-use_wallclock_as_timestamps',
'1',
'-copyts',
'-analyzeduration',
'0',
isStream ? '-' : input,
...FFMPEG_OUTPUT_PREFIX,
'-flags',

@@ -174,6 +223,2 @@ 'low_delay',

if (!isStream) {
args[1] = input;
}
if (options?.hwAccel === true) {

@@ -187,12 +232,3 @@ args.unshift('-hwaccel', 'auto');

if (typeof input == 'string' && input.startsWith('http')) {
args.unshift(
'-reconnect',
'1',
'-reconnect_at_eof',
'1',
'-reconnect_streamed',
'1',
'-reconnect_delay_max',
'4294',
);
args.unshift(...FFMPEG_INPUT_PREFIX);
}

@@ -202,3 +238,3 @@

if (this.voiceConnection.videoCodec == 'VP8') {
args.push('-f', 'ivf', '-deadline', 'realtime', '-c:v', 'libvpx');
args.push(...FFMPEG_VP8_ARGUMENTS);
// Remove '-speed', '5' bc bad quality

@@ -208,24 +244,3 @@ }

if (this.voiceConnection.videoCodec == 'H264') {
args.push(
'-c:v',
'libx264',
'-f',
'h264',
'-tune',
'zerolatency',
// '-pix_fmt',
// 'yuv420p',
'-preset',
options?.presetH26x || 'faster',
'-profile:v',
'baseline',
// '-g',
// `${options?.fps}`,
// '-x264-params',
// `keyint=${options?.fps}:min-keyint=${options?.fps}`,
'-bf',
'0',
'-bsf:v',
'h264_metadata=aud=insert',
);
args.push(...FFMPEG_H264_ARGUMENTS(options));
}

@@ -251,8 +266,12 @@

this.emit('debug', `[ffmpeg] Spawn process with args:\n${args.join(' ')}`);
this.emit('debug', `[ffmpeg-video_process] Spawn process with args:\n${args.join(' ')}`);
ffmpeg.process.stderr.on('data', data => {
this.emit('debug', `[ffmpeg]: ${data.toString()}`);
this.emit('debug', `[ffmpeg-video_process]: ${data.toString()}`);
});
if (data?.audio && options?.includeAudio) {
this.playUnknown(input, options?.audioOptions || {});
}
switch (this.voiceConnection.videoCodec) {

@@ -266,3 +285,3 @@ case 'VP8': {

default: {
throw new Error('Invalid codec');
throw new Error('Invalid codec (Supported: VP8, H264)');
}

@@ -269,0 +288,0 @@ }

@@ -81,3 +81,3 @@ 'use strict';

* @property {number} [seek=0] The time to seek to
* @property {number} [fps=30] Video fps
* @property {number} [fps] Video fps
* @property {number} [highWaterMark=12] The maximum number of opus packets to make and store before they are

@@ -84,0 +84,0 @@ * actually needed. See https://nodejs.org/en/docs/guides/backpressuring-in-streams/. Setting this value to

'use strict';
const EventEmitter = require('events');
const { getCiphers } = require('node:crypto');
const { setTimeout } = require('node:timers');

@@ -26,3 +27,9 @@ const { Collection } = require('@discordjs/collection');

const SUPPORTED_MODES = ['aead_aes256_gcm_rtpsize', 'aead_xchacha20_poly1305_rtpsize'];
const SUPPORTED_MODES = ['aead_xchacha20_poly1305_rtpsize'];
// Just in case there's some system that doesn't come with aes-256-gcm, conditionally add it as supported
if (getCiphers().includes('aes-256-gcm')) {
SUPPORTED_MODES.unshift('aead_aes256_gcm_rtpsize');
}
const SUPPORTED_CODECS = ['VP8', 'H264'];

@@ -29,0 +36,0 @@

@@ -212,4 +212,7 @@ 'use strict';

POLL_ALREADY_EXPIRED: 'This poll has already expired.',
INVALID_OAUTH_OPTIONS: 'Invalid options for authenticating with OAuth2.',
METHOD_WARNING:
'This method is flagged as it may lead to a temporary or permanent account ban. Do not use until further notice.',
};
for (const [name, message] of Object.entries(Messages)) register(name, message);

@@ -7,5 +7,4 @@ 'use strict';

const makeFetchCookie = require('fetch-cookie');
const FormData = require('form-data');
const fetchOriginal = require('node-fetch');
const { CookieJar } = require('tough-cookie');
const { fetch: fetchOriginal, FormData } = require('undici');
const { ciphers } = require('../util/Constants');

@@ -73,3 +72,2 @@ const Util = require('../util/Util');

let headers = {
authority: 'discord.com',
accept: '*/*',

@@ -85,9 +83,8 @@ 'accept-language': 'en-US',

'x-discord-locale': 'en-US',
'x-discord-timezone': 'Asia/Saigon',
'x-discord-timezone': Intl.DateTimeFormat().resolvedOptions().timeZone,
'x-super-properties': `${Buffer.from(JSON.stringify(this.client.options.ws.properties), 'ascii').toString(
'base64',
)}`,
Referer: 'https://discord.com/channels/@me',
referer: 'https://discord.com/channels/@me',
origin: 'https://discord.com',
'Referrer-Policy': 'strict-origin-when-cross-origin',
...this.client.options.http.headers,

@@ -158,2 +155,3 @@ 'User-Agent': this.fullUserAgent,

signal: controller.signal,
redirect: 'follow',
}).finally(() => clearTimeout(timeout));

@@ -160,0 +158,0 @@ }

@@ -71,2 +71,17 @@ 'use strict';

/**
* A special `40333` JSON error code is returned if your request is blocked by Cloudflare.
* This may be due to a malformed request or improper user agent.
* The response resembles a normal error structure:
* @type {boolean}
* @example
* {
* "message": "internal network error",
* "code": 40333
* }
*/
get isBlockedByCloudflare() {
return this.code === 40333;
}
/**
* Flattens an errors object returned from the API into an array.

@@ -73,0 +88,0 @@ * @param {APIError} obj Discord errors object

@@ -298,7 +298,10 @@ 'use strict';

* @param {UserResolvable[]} [recipients] Array of recipients
* @returns {Promise<any>}
* @returns {Promise<void>}
*/
ring(recipients) {
if (!recipients || !Array.isArray(recipients) || recipients.length == 0) recipients = null;
recipients = recipients.map(r => this.client.users.resolveId(r)).filter(r => r && this.recipients.get(r));
if (!recipients || !Array.isArray(recipients) || recipients.length == 0) {
recipients = null;
} else {
recipients = recipients.map(r => this.client.users.resolveId(r)).filter(r => r && this.recipients.get(r));
}
return this.client.api.channels(this.id).call.ring.post({

@@ -305,0 +308,0 @@ data: {

@@ -483,15 +483,2 @@ 'use strict';

/**
* Ring the user's phone / PC (call)
* @returns {Promise<void>}
* @deprecated
*/
ring() {
return this.client.api.channels(this.dmChannel.id).call.ring.post({
data: {
recipients: [this.id],
},
});
}
/**
* Send Friend Request to the user

@@ -498,0 +485,0 @@ * @type {boolean}

@@ -7,3 +7,3 @@ 'use strict';

const stream = require('node:stream');
const fetch = require('node-fetch');
const { fetch } = require('undici');
const { Error: DiscordError, TypeError } = require('../errors');

@@ -10,0 +10,0 @@ const Invite = require('../structures/Invite');

@@ -8,3 +8,3 @@ 'use strict';

const { setTimeout } = require('node:timers');
const fetch = require('node-fetch');
const { fetch } = require('undici');
const WebSocket = require('ws');

@@ -11,0 +11,0 @@ const { UserAgent } = require('./Constants');

@@ -8,3 +8,3 @@ 'use strict';

const { Collection } = require('@discordjs/collection');
const fetch = require('node-fetch');
const { fetch } = require('undici');
const { Colors, Events } = require('./Constants');

@@ -11,0 +11,0 @@ const { Error: DiscordError, RangeError, TypeError } = require('../errors');

Sorry, the diff of this file is too big to display