2022-12-20 22:20:09 +07:00
'use strict' ;
2023-03-21 18:54:28 +07:00
var _ _create = Object . create ,
_ _defProp = Object . defineProperty ,
_ _getOwnPropDesc = Object . getOwnPropertyDescriptor ,
_ _getOwnPropNames = Object . getOwnPropertyNames ,
_ _getProtoOf = Object . getPrototypeOf ,
_ _hasOwnProp = Object . prototype . hasOwnProperty ,
_ _defNormalProp = ( e , t , s ) =>
t in e ? _ _defProp ( e , t , { enumerable : ! 0 , configurable : ! 0 , writable : ! 0 , value : s } ) : ( e [ t ] = s ) ,
_ _name = ( e , t ) => _ _defProp ( e , 'name' , { value : t , configurable : ! 0 } ) ,
_ _export = ( e , t ) => {
for ( var s in t ) _ _defProp ( e , s , { get : t [ s ] , enumerable : ! 0 } ) ;
} ,
_ _copyProps = ( e , t , s , o ) => {
if ( ( t && 'object' == typeof t ) || 'function' == typeof t )
for ( let n of _ _getOwnPropNames ( t ) )
_ _hasOwnProp . call ( e , n ) ||
n === s ||
_ _defProp ( e , n , { get : ( ) => t [ n ] , enumerable : ! ( o = _ _getOwnPropDesc ( t , n ) ) || o . enumerable } ) ;
return e ;
} ,
_ _toESM = ( e , t , s ) => (
( s = null != e ? _ _create ( _ _getProtoOf ( e ) ) : { } ) ,
_ _copyProps ( ! t && e && e . _ _esModule ? s : _ _defProp ( s , 'default' , { value : e , enumerable : ! 0 } ) , e )
) ,
_ _toCommonJS = e => _ _copyProps ( _ _defProp ( { } , '__esModule' , { value : ! 0 } ) , e ) ,
_ _publicField = ( e , t , s ) => ( _ _defNormalProp ( e , 'symbol' != typeof t ? t + '' : t , s ) , s ) ,
src _exports = { } ;
2022-05-21 21:02:00 +07:00
_ _export ( src _exports , {
AudioPlayer : ( ) => AudioPlayer ,
AudioPlayerError : ( ) => AudioPlayerError ,
AudioPlayerStatus : ( ) => AudioPlayerStatus ,
AudioReceiveStream : ( ) => AudioReceiveStream ,
AudioResource : ( ) => AudioResource ,
EndBehaviorType : ( ) => EndBehaviorType ,
NoSubscriberBehavior : ( ) => NoSubscriberBehavior ,
PlayerSubscription : ( ) => PlayerSubscription ,
SSRCMap : ( ) => SSRCMap ,
SpeakingMap : ( ) => SpeakingMap ,
StreamType : ( ) => StreamType ,
2022-09-28 19:40:46 +07:00
VoiceConnection : ( ) => VoiceConnection ,
2022-05-21 21:02:00 +07:00
VoiceConnectionDisconnectReason : ( ) => VoiceConnectionDisconnectReason ,
VoiceConnectionStatus : ( ) => VoiceConnectionStatus ,
VoiceReceiver : ( ) => VoiceReceiver ,
createAudioPlayer : ( ) => createAudioPlayer ,
createAudioResource : ( ) => createAudioResource ,
createDefaultAudioReceiveStreamOptions : ( ) => createDefaultAudioReceiveStreamOptions ,
demuxProbe : ( ) => demuxProbe ,
entersState : ( ) => entersState ,
generateDependencyReport : ( ) => generateDependencyReport ,
getGroups : ( ) => getGroups ,
getVoiceConnection : ( ) => getVoiceConnection ,
getVoiceConnections : ( ) => getVoiceConnections ,
joinVoiceChannel : ( ) => joinVoiceChannel ,
2022-09-28 22:09:00 +07:00
validateDiscordOpusHead : ( ) => validateDiscordOpusHead ,
2022-12-20 22:20:09 +07:00
version : ( ) => version2 ,
2023-03-21 18:54:28 +07:00
} ) ,
( module . exports = _ _toCommonJS ( src _exports ) ) ;
var import _node _events7 = require ( 'events' ) ,
import _v10 = require ( 'discord-api-types/v10' ) ;
function createJoinVoiceChannelPayload ( e ) {
2022-05-21 21:02:00 +07:00
return {
op : import _v10 . GatewayOpcodes . VoiceStateUpdate ,
2023-03-21 18:54:28 +07:00
d : { guild _id : e . guildId , channel _id : e . channelId , self _deaf : e . selfDeaf , self _mute : e . selfMute } ,
2022-05-21 21:02:00 +07:00
} ;
}
2022-12-20 22:20:09 +07:00
_ _name ( createJoinVoiceChannelPayload , 'createJoinVoiceChannelPayload' ) ;
2023-03-21 18:54:28 +07:00
var groups = new Map ( ) ;
function getOrCreateGroup ( e ) {
const t = groups . get ( e ) ;
if ( t ) return t ;
const s = new Map ( ) ;
return groups . set ( e , s ) , s ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
function getGroups ( ) {
2022-05-21 21:02:00 +07:00
return groups ;
}
2023-03-21 18:54:28 +07:00
function getVoiceConnections ( e = 'default' ) {
return groups . get ( e ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
function getVoiceConnection ( e , t = 'default' ) {
return getVoiceConnections ( t ) ? . get ( e ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
function untrackVoiceConnection ( e ) {
return getVoiceConnections ( e . joinConfig . group ) ? . delete ( e . joinConfig . guildId ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
function trackVoiceConnection ( e ) {
return getOrCreateGroup ( e . joinConfig . group ) . set ( e . joinConfig . guildId , e ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
groups . set ( 'default' , new Map ( ) ) ,
_ _name ( getOrCreateGroup , 'getOrCreateGroup' ) ,
_ _name ( getGroups , 'getGroups' ) ,
_ _name ( getVoiceConnections , 'getVoiceConnections' ) ,
_ _name ( getVoiceConnection , 'getVoiceConnection' ) ,
_ _name ( untrackVoiceConnection , 'untrackVoiceConnection' ) ,
_ _name ( trackVoiceConnection , 'trackVoiceConnection' ) ;
var audioCycleInterval ,
FRAME _LENGTH = 20 ,
nextTime = - 1 ,
audioPlayers = [ ] ;
2022-08-01 13:02:58 +07:00
function audioCycleStep ( ) {
2023-03-21 18:54:28 +07:00
if ( - 1 === nextTime ) return ;
2022-05-21 21:02:00 +07:00
nextTime += FRAME _LENGTH ;
2023-03-21 18:54:28 +07:00
const e = audioPlayers . filter ( e => e . checkPlayable ( ) ) ;
for ( const t of e ) t . _stepDispatch ( ) ;
prepareNextAudioFrame ( e ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
function prepareNextAudioFrame ( e ) {
const t = e . shift ( ) ;
t
? ( t . _stepPrepare ( ) , setImmediate ( ( ) => prepareNextAudioFrame ( e ) ) )
: - 1 !== nextTime && ( audioCycleInterval = setTimeout ( ( ) => audioCycleStep ( ) , nextTime - Date . now ( ) ) ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
function hasAudioPlayer ( e ) {
return audioPlayers . includes ( e ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
function addAudioPlayer ( e ) {
return (
hasAudioPlayer ( e ) ||
( audioPlayers . push ( e ) ,
1 === audioPlayers . length && ( ( nextTime = Date . now ( ) ) , setImmediate ( ( ) => audioCycleStep ( ) ) ) ) ,
e
) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
function deleteAudioPlayer ( e ) {
const t = audioPlayers . indexOf ( e ) ;
- 1 !== t &&
( audioPlayers . splice ( t , 1 ) ,
0 === audioPlayers . length && ( ( nextTime = - 1 ) , void 0 !== audioCycleInterval && clearTimeout ( audioCycleInterval ) ) ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
_ _name ( audioCycleStep , 'audioCycleStep' ) ,
_ _name ( prepareNextAudioFrame , 'prepareNextAudioFrame' ) ,
_ _name ( hasAudioPlayer , 'hasAudioPlayer' ) ,
_ _name ( addAudioPlayer , 'addAudioPlayer' ) ,
_ _name ( deleteAudioPlayer , 'deleteAudioPlayer' ) ;
var import _node _buffer3 = require ( 'buffer' ) ,
import _node _events3 = require ( 'events' ) ,
import _v42 = require ( 'discord-api-types/voice/v4' ) ,
import _node _buffer = require ( 'buffer' ) ,
libs = {
'sodium-native' : e => ( {
open : ( t , s , o ) => {
if ( t ) {
const n = import _node _buffer . Buffer . allocUnsafe ( t . length - e . crypto _box _MACBYTES ) ;
if ( e . crypto _secretbox _open _easy ( n , t , s , o ) ) return n ;
}
return null ;
} ,
close : ( t , s , o ) => {
const n = import _node _buffer . Buffer . allocUnsafe ( t . length + e . crypto _box _MACBYTES ) ;
return e . crypto _secretbox _easy ( n , t , s , o ) , n ;
} ,
random : ( t , s = import _node _buffer . Buffer . allocUnsafe ( t ) ) => ( e . randombytes _buf ( s ) , s ) ,
} ) ,
sodium : e => ( {
open : e . api . crypto _secretbox _open _easy ,
close : e . api . crypto _secretbox _easy ,
random : ( t , s = import _node _buffer . Buffer . allocUnsafe ( t ) ) => ( e . api . randombytes _buf ( s ) , s ) ,
} ) ,
'libsodium-wrappers' : e => ( {
open : e . crypto _secretbox _open _easy ,
close : e . crypto _secretbox _easy ,
random : e . randombytes _buf ,
} ) ,
tweetnacl : e => ( { open : e . secretbox . open , close : e . secretbox , random : e . randomBytes } ) ,
} ,
fallbackError = _ _name ( ( ) => {
throw new Error (
'Cannot play audio as no valid encryption package is installed.\n- Install sodium, libsodium-wrappers, or tweetnacl.\n- Use the generateDependencyReport() function for more information.\n' ,
) ;
} , 'fallbackError' ) ,
methods = { open : fallbackError , close : fallbackError , random : fallbackError } ;
( async ( ) => {
for ( const e of Object . keys ( libs ) )
2022-09-28 19:40:46 +07:00
try {
2023-03-21 18:54:28 +07:00
const t = require ( e ) ;
'libsodium-wrappers' === e && t . ready && ( await t . ready ) , Object . assign ( methods , libs [ e ] ( t ) ) ;
2022-09-28 19:40:46 +07:00
break ;
2022-12-20 22:20:09 +07:00
} catch { }
2022-09-28 19:40:46 +07:00
} ) ( ) ;
2023-03-21 18:54:28 +07:00
var noop = _ _name ( ( ) => { } , 'noop' ) ,
import _node _buffer2 = require ( 'buffer' ) ,
import _node _dgram = require ( 'dgram' ) ,
import _node _events = require ( 'events' ) ,
import _node _net = require ( 'net' ) ;
function parseLocalPacket ( e ) {
const t = import _node _buffer2 . Buffer . from ( e ) ,
s = t . slice ( 8 , t . indexOf ( 0 , 8 ) ) . toString ( 'utf8' ) ;
if ( ! ( 0 , import _node _net . isIPv4 ) ( s ) ) throw new Error ( 'Malformed IP address' ) ;
return { ip : s , port : t . readUInt16BE ( t . length - 2 ) } ;
2022-05-21 21:02:00 +07:00
}
2022-12-20 22:20:09 +07:00
_ _name ( parseLocalPacket , 'parseLocalPacket' ) ;
2023-03-21 18:54:28 +07:00
var KEEP _ALIVE _INTERVAL = 5e3 ,
MAX _COUNTER _VALUE = 2 * * 32 - 1 ,
VoiceUDPSocket = class extends import _node _events . EventEmitter {
keepAliveCounter = 0 ;
constructor ( e ) {
super ( ) ,
( this . socket = ( 0 , import _node _dgram . createSocket ) ( 'udp4' ) ) ,
this . socket . on ( 'error' , e => this . emit ( 'error' , e ) ) ,
this . socket . on ( 'message' , e => this . onMessage ( e ) ) ,
this . socket . on ( 'close' , ( ) => this . emit ( 'close' ) ) ,
( this . remote = e ) ,
( this . keepAliveBuffer = import _node _buffer2 . Buffer . alloc ( 8 ) ) ,
( this . keepAliveInterval = setInterval ( ( ) => this . keepAlive ( ) , KEEP _ALIVE _INTERVAL ) ) ,
setImmediate ( ( ) => this . keepAlive ( ) ) ;
}
onMessage ( e ) {
this . emit ( 'message' , e ) ;
}
keepAlive ( ) {
this . keepAliveBuffer . writeUInt32LE ( this . keepAliveCounter , 0 ) ,
this . send ( this . keepAliveBuffer ) ,
this . keepAliveCounter ++ ,
this . keepAliveCounter > MAX _COUNTER _VALUE && ( this . keepAliveCounter = 0 ) ;
}
send ( e ) {
this . socket . send ( e , this . remote . port , this . remote . ip ) ;
}
destroy ( ) {
try {
this . socket . close ( ) ;
} catch { }
clearInterval ( this . keepAliveInterval ) ;
}
async performIPDiscovery ( e ) {
return new Promise ( ( t , s ) => {
const o = _ _name ( e => {
try {
if ( 2 !== e . readUInt16BE ( 0 ) ) return ;
const s = parseLocalPacket ( e ) ;
this . socket . off ( 'message' , o ) , t ( s ) ;
} catch { }
} , 'listener' ) ;
this . socket . on ( 'message' , o ) ,
this . socket . once ( 'close' , ( ) => s ( new Error ( 'Cannot perform IP discovery - socket closed' ) ) ) ;
const n = import _node _buffer2 . Buffer . alloc ( 74 ) ;
n . writeUInt16BE ( 1 , 0 ) , n . writeUInt16BE ( 70 , 2 ) , n . writeUInt32BE ( e , 4 ) , this . send ( n ) ;
} ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
} ;
2022-12-20 22:20:09 +07:00
_ _name ( VoiceUDPSocket , 'VoiceUDPSocket' ) ;
2023-03-21 18:54:28 +07:00
var import _node _events2 = require ( 'events' ) ,
import _v4 = require ( 'discord-api-types/voice/v4' ) ,
import _ws = _ _toESM ( require ( 'ws' ) ) ,
VoiceWebSocket = class extends import _node _events2 . EventEmitter {
missedHeartbeats = 0 ;
constructor ( e , t ) {
super ( ) ,
( this . ws = new import _ws . default ( e ) ) ,
( this . ws . onmessage = e => this . onMessage ( e ) ) ,
( this . ws . onopen = e => this . emit ( 'open' , e ) ) ,
( this . ws . onerror = e => this . emit ( 'error' , e instanceof Error ? e : e . error ) ) ,
( this . ws . onclose = e => this . emit ( 'close' , e ) ) ,
( this . lastHeartbeatAck = 0 ) ,
( this . lastHeartbeatSend = 0 ) ,
( this . debug = t ? e => this . emit ( 'debug' , e ) : null ) ;
}
destroy ( ) {
try {
this . debug ? . ( 'destroyed' ) , this . setHeartbeatInterval ( - 1 ) , this . ws . close ( 1e3 ) ;
} catch ( e ) {
const t = e ;
this . emit ( 'error' , t ) ;
}
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
onMessage ( e ) {
if ( 'string' != typeof e . data ) return ;
let t ;
this . debug ? . ( ` << ${ e . data } ` ) ;
try {
t = JSON . parse ( e . data ) ;
} catch ( e ) {
const t = e ;
return void this . emit ( 'error' , t ) ;
}
t . op === import _v4 . VoiceOpcodes . HeartbeatAck &&
( ( this . lastHeartbeatAck = Date . now ( ) ) ,
( this . missedHeartbeats = 0 ) ,
( this . ping = this . lastHeartbeatAck - this . lastHeartbeatSend ) ) ,
this . emit ( 'packet' , t ) ;
}
sendPacket ( e ) {
try {
const t = JSON . stringify ( e ) ;
return this . debug ? . ( ` >> ${ t } ` ) , void this . ws . send ( t ) ;
} catch ( e ) {
const t = e ;
this . emit ( 'error' , t ) ;
}
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
sendHeartbeat ( ) {
( this . lastHeartbeatSend = Date . now ( ) ) , this . missedHeartbeats ++ ;
const e = this . lastHeartbeatSend ;
this . sendPacket ( { op : import _v4 . VoiceOpcodes . Heartbeat , d : e } ) ;
}
setHeartbeatInterval ( e ) {
void 0 !== this . heartbeatInterval && clearInterval ( this . heartbeatInterval ) ,
e > 0 &&
( this . heartbeatInterval = setInterval ( ( ) => {
0 !== this . lastHeartbeatSend &&
this . missedHeartbeats >= 3 &&
( this . ws . close ( ) , this . setHeartbeatInterval ( - 1 ) ) ,
this . sendHeartbeat ( ) ;
} , e ) ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
} ;
2022-12-20 22:20:09 +07:00
_ _name ( VoiceWebSocket , 'VoiceWebSocket' ) ;
2023-03-21 18:54:28 +07:00
var NetworkingStatusCode ,
CHANNELS = 2 ,
TIMESTAMP _INC = 480 * CHANNELS ,
MAX _NONCE _SIZE = 2 * * 32 - 1 ,
SUPPORTED _ENCRYPTION _MODES = [ 'xsalsa20_poly1305_lite' , 'xsalsa20_poly1305_suffix' , 'xsalsa20_poly1305' ] ;
! ( function ( e ) {
( e [ ( e . OpeningWs = 0 ) ] = 'OpeningWs' ) ,
( e [ ( e . Identifying = 1 ) ] = 'Identifying' ) ,
( e [ ( e . UdpHandshaking = 2 ) ] = 'UdpHandshaking' ) ,
( e [ ( e . SelectingProtocol = 3 ) ] = 'SelectingProtocol' ) ,
( e [ ( e . Ready = 4 ) ] = 'Ready' ) ,
( e [ ( e . Resuming = 5 ) ] = 'Resuming' ) ,
( e [ ( e . Closed = 6 ) ] = 'Closed' ) ;
2023-03-21 18:47:11 +07:00
} ) ( NetworkingStatusCode || ( NetworkingStatusCode = { } ) ) ;
2022-09-28 19:40:46 +07:00
var nonce = import _node _buffer3 . Buffer . alloc ( 24 ) ;
2023-03-21 18:54:28 +07:00
function stringifyState ( e ) {
return JSON . stringify ( { ... e , ws : Reflect . has ( e , 'ws' ) , udp : Reflect . has ( e , 'udp' ) } ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
function chooseEncryptionMode ( e ) {
const t = e . find ( e => SUPPORTED _ENCRYPTION _MODES . includes ( e ) ) ;
if ( ! t ) throw new Error ( ` No compatible encryption modes. Available include: ${ e . join ( ', ' ) } ` ) ;
return t ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
function randomNBit ( e ) {
return Math . floor ( Math . random ( ) * 2 * * e ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
_ _name ( stringifyState , 'stringifyState' ) ,
_ _name ( chooseEncryptionMode , 'chooseEncryptionMode' ) ,
_ _name ( randomNBit , 'randomNBit' ) ;
2022-08-01 13:02:58 +07:00
var Networking = class extends import _node _events3 . EventEmitter {
2023-03-21 18:54:28 +07:00
constructor ( e , t ) {
super ( ) ,
( this . onWsOpen = this . onWsOpen . bind ( this ) ) ,
( this . onChildError = this . onChildError . bind ( this ) ) ,
( this . onWsPacket = this . onWsPacket . bind ( this ) ) ,
( this . onWsClose = this . onWsClose . bind ( this ) ) ,
( this . onWsDebug = this . onWsDebug . bind ( this ) ) ,
( this . onUdpDebug = this . onUdpDebug . bind ( this ) ) ,
( this . onUdpClose = this . onUdpClose . bind ( this ) ) ,
( this . debug = t ? e => this . emit ( 'debug' , e ) : null ) ,
( this . _state = {
code : NetworkingStatusCode . OpeningWs ,
ws : this . createWebSocket ( e . endpoint ) ,
connectionOptions : e ,
} ) ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
destroy ( ) {
2023-03-21 18:54:28 +07:00
this . state = { code : NetworkingStatusCode . Closed } ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
get state ( ) {
2022-05-21 21:02:00 +07:00
return this . _state ;
}
2023-03-21 18:54:28 +07:00
set state ( e ) {
const t = Reflect . get ( this . _state , 'ws' ) ,
s = Reflect . get ( e , 'ws' ) ;
t &&
t !== s &&
( t . off ( 'debug' , this . onWsDebug ) ,
t . on ( 'error' , noop ) ,
t . off ( 'error' , this . onChildError ) ,
t . off ( 'open' , this . onWsOpen ) ,
t . off ( 'packet' , this . onWsPacket ) ,
t . off ( 'close' , this . onWsClose ) ,
t . destroy ( ) ) ;
const o = Reflect . get ( this . _state , 'udp' ) ,
n = Reflect . get ( e , 'udp' ) ;
o &&
o !== n &&
( o . on ( 'error' , noop ) ,
o . off ( 'error' , this . onChildError ) ,
o . off ( 'close' , this . onUdpClose ) ,
o . off ( 'debug' , this . onUdpDebug ) ,
o . destroy ( ) ) ;
const i = this . _state ;
( this . _state = e ) ,
this . emit ( 'stateChange' , i , e ) ,
this . debug ? . ( ` state change: \n from ${ stringifyState ( i ) } \n to ${ stringifyState ( e ) } ` ) ;
}
createWebSocket ( e ) {
const t = new VoiceWebSocket ( ` wss:// ${ e } ?v=4 ` , Boolean ( this . debug ) ) ;
return (
t . on ( 'error' , this . onChildError ) ,
t . once ( 'open' , this . onWsOpen ) ,
t . on ( 'packet' , this . onWsPacket ) ,
t . once ( 'close' , this . onWsClose ) ,
t . on ( 'debug' , this . onWsDebug ) ,
t
) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
onChildError ( e ) {
this . emit ( 'error' , e ) ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
onWsOpen ( ) {
2023-03-21 18:47:11 +07:00
if ( this . state . code === NetworkingStatusCode . OpeningWs ) {
2023-03-21 18:54:28 +07:00
const e = {
2022-05-21 21:02:00 +07:00
op : import _v42 . VoiceOpcodes . Identify ,
d : {
server _id : this . state . connectionOptions . serverId ,
user _id : this . state . connectionOptions . userId ,
session _id : this . state . connectionOptions . sessionId ,
2022-12-20 22:20:09 +07:00
token : this . state . connectionOptions . token ,
} ,
2022-05-21 21:02:00 +07:00
} ;
2023-03-21 18:54:28 +07:00
this . state . ws . sendPacket ( e ) , ( this . state = { ... this . state , code : NetworkingStatusCode . Identifying } ) ;
2023-03-21 18:47:11 +07:00
} else if ( this . state . code === NetworkingStatusCode . Resuming ) {
2023-03-21 18:54:28 +07:00
const e = {
2022-05-21 21:02:00 +07:00
op : import _v42 . VoiceOpcodes . Resume ,
d : {
server _id : this . state . connectionOptions . serverId ,
session _id : this . state . connectionOptions . sessionId ,
2022-12-20 22:20:09 +07:00
token : this . state . connectionOptions . token ,
} ,
2022-05-21 21:02:00 +07:00
} ;
2023-03-21 18:54:28 +07:00
this . state . ws . sendPacket ( e ) ;
2022-05-21 21:02:00 +07:00
}
}
2023-03-21 18:54:28 +07:00
onWsClose ( { code : e } ) {
( 4015 === e || e < 4e3 ) && this . state . code === NetworkingStatusCode . Ready
? ( this . state = {
... this . state ,
code : NetworkingStatusCode . Resuming ,
ws : this . createWebSocket ( this . state . connectionOptions . endpoint ) ,
} )
: this . state . code !== NetworkingStatusCode . Closed && ( this . destroy ( ) , this . emit ( 'close' , e ) ) ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
onUdpClose ( ) {
2023-03-21 18:54:28 +07:00
this . state . code === NetworkingStatusCode . Ready &&
( this . state = {
2022-05-21 21:02:00 +07:00
... this . state ,
2023-03-21 18:47:11 +07:00
code : NetworkingStatusCode . Resuming ,
2022-12-20 22:20:09 +07:00
ws : this . createWebSocket ( this . state . connectionOptions . endpoint ) ,
2023-03-21 18:47:11 +07:00
} ) ;
2023-03-21 18:54:28 +07:00
}
onWsPacket ( e ) {
if ( e . op === import _v42 . VoiceOpcodes . Hello && this . state . code !== NetworkingStatusCode . Closed )
this . state . ws . setHeartbeatInterval ( e . d . heartbeat _interval ) ;
else if ( e . op === import _v42 . VoiceOpcodes . Ready && this . state . code === NetworkingStatusCode . Identifying ) {
const { ip : t , port : s , ssrc : o , modes : n } = e . d ,
i = new VoiceUDPSocket ( { ip : t , port : s } ) ;
i . on ( 'error' , this . onChildError ) ,
i . on ( 'debug' , this . onUdpDebug ) ,
i . once ( 'close' , this . onUdpClose ) ,
i
. performIPDiscovery ( o )
. then ( e => {
this . state . code === NetworkingStatusCode . UdpHandshaking &&
( this . state . ws . sendPacket ( {
op : import _v42 . VoiceOpcodes . SelectProtocol ,
d : { protocol : 'udp' , data : { address : e . ip , port : e . port , mode : chooseEncryptionMode ( n ) } } ,
} ) ,
( this . state = { ... this . state , code : NetworkingStatusCode . SelectingProtocol } ) ) ;
} )
. catch ( e => this . emit ( 'error' , e ) ) ,
( this . state = {
... this . state ,
code : NetworkingStatusCode . UdpHandshaking ,
udp : i ,
connectionData : { ssrc : o } ,
} ) ;
2022-12-20 22:20:09 +07:00
} else if (
2023-03-21 18:54:28 +07:00
e . op === import _v42 . VoiceOpcodes . SessionDescription &&
2023-03-21 18:47:11 +07:00
this . state . code === NetworkingStatusCode . SelectingProtocol
2022-12-20 22:20:09 +07:00
) {
2023-03-21 18:54:28 +07:00
const { mode : t , secret _key : s } = e . d ;
2022-05-21 21:02:00 +07:00
this . state = {
... this . state ,
2023-03-21 18:47:11 +07:00
code : NetworkingStatusCode . Ready ,
2022-05-21 21:02:00 +07:00
connectionData : {
... this . state . connectionData ,
2023-03-21 18:54:28 +07:00
encryptionMode : t ,
secretKey : new Uint8Array ( s ) ,
2022-05-21 21:02:00 +07:00
sequence : randomNBit ( 16 ) ,
timestamp : randomNBit ( 32 ) ,
nonce : 0 ,
2022-09-28 19:40:46 +07:00
nonceBuffer : import _node _buffer3 . Buffer . alloc ( 24 ) ,
2023-03-21 18:54:28 +07:00
speaking : ! 1 ,
2022-12-20 22:20:09 +07:00
packetsPlayed : 0 ,
} ,
2022-05-21 21:02:00 +07:00
} ;
2023-03-21 18:54:28 +07:00
} else
e . op === import _v42 . VoiceOpcodes . Resumed &&
this . state . code === NetworkingStatusCode . Resuming &&
( ( this . state = { ... this . state , code : NetworkingStatusCode . Ready } ) , ( this . state . connectionData . speaking = ! 1 ) ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
onWsDebug ( e ) {
this . debug ? . ( ` [WS] ${ e } ` ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
onUdpDebug ( e ) {
this . debug ? . ( ` [UDP] ${ e } ` ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
prepareAudioPacket ( e ) {
const t = this . state ;
if ( t . code === NetworkingStatusCode . Ready )
return ( t . preparedPacket = this . createAudioPacket ( e , t . connectionData ) ) , t . preparedPacket ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
dispatchAudio ( ) {
2023-03-21 18:54:28 +07:00
const e = this . state ;
return (
e . code === NetworkingStatusCode . Ready &&
void 0 !== e . preparedPacket &&
( this . playAudioPacket ( e . preparedPacket ) , ( e . preparedPacket = void 0 ) , ! 0 )
) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
playAudioPacket ( e ) {
const t = this . state ;
if ( t . code !== NetworkingStatusCode . Ready ) return ;
const { connectionData : s } = t ;
s . packetsPlayed ++ ,
s . sequence ++ ,
( s . timestamp += TIMESTAMP _INC ) ,
s . sequence >= 65536 && ( s . sequence = 0 ) ,
s . timestamp >= 2 * * 32 && ( s . timestamp = 0 ) ,
this . setSpeaking ( ! 0 ) ,
t . udp . send ( e ) ;
}
setSpeaking ( e ) {
const t = this . state ;
t . code === NetworkingStatusCode . Ready &&
t . connectionData . speaking !== e &&
( ( t . connectionData . speaking = e ) ,
t . ws . sendPacket ( {
op : import _v42 . VoiceOpcodes . Speaking ,
d : { speaking : e ? 1 : 0 , delay : 0 , ssrc : t . connectionData . ssrc } ,
} ) ) ;
}
createAudioPacket ( e , t ) {
const s = import _node _buffer3 . Buffer . alloc ( 12 ) ;
( s [ 0 ] = 128 ) , ( s [ 1 ] = 120 ) ;
const { sequence : o , timestamp : n , ssrc : i } = t ;
return (
s . writeUIntBE ( o , 2 , 2 ) ,
s . writeUIntBE ( n , 4 , 4 ) ,
s . writeUIntBE ( i , 8 , 4 ) ,
s . copy ( nonce , 0 , 0 , 12 ) ,
import _node _buffer3 . Buffer . concat ( [ s , ... this . encryptOpusPacket ( e , t ) ] )
) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
encryptOpusPacket ( e , t ) {
const { secretKey : s , encryptionMode : o } = t ;
if ( 'xsalsa20_poly1305_lite' === o )
return (
t . nonce ++ ,
t . nonce > MAX _NONCE _SIZE && ( t . nonce = 0 ) ,
t . nonceBuffer . writeUInt32BE ( t . nonce , 0 ) ,
[ methods . close ( e , t . nonceBuffer , s ) , t . nonceBuffer . slice ( 0 , 4 ) ]
) ;
if ( 'xsalsa20_poly1305_suffix' === o ) {
const o = methods . random ( 24 , t . nonceBuffer ) ;
return [ methods . close ( e , o , s ) , o ] ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
return [ methods . close ( e , nonce , s ) ] ;
2022-05-21 21:02:00 +07:00
}
} ;
2022-12-20 22:20:09 +07:00
_ _name ( Networking , 'Networking' ) ;
2023-03-21 18:54:28 +07:00
var import _node _buffer5 = require ( 'buffer' ) ,
import _v43 = require ( 'discord-api-types/voice/v4' ) ,
import _node _stream = require ( 'stream' ) ,
import _node _buffer4 = require ( 'buffer' ) ,
import _node _events4 = require ( 'events' ) ,
AudioPlayerError = class extends Error {
constructor ( e , t ) {
super ( e . message ) , ( this . resource = t ) , ( this . name = e . name ) , ( this . stack = e . stack ) ;
}
} ;
2022-12-20 22:20:09 +07:00
_ _name ( AudioPlayerError , 'AudioPlayerError' ) ;
2022-08-01 13:02:58 +07:00
var PlayerSubscription = class {
2023-03-21 18:54:28 +07:00
constructor ( e , t ) {
( this . connection = e ) , ( this . player = t ) ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
unsubscribe ( ) {
2023-03-21 18:54:28 +07:00
this . connection . onSubscriptionRemoved ( this ) , this . player . unsubscribe ( this ) ;
2022-05-21 21:02:00 +07:00
}
} ;
2022-12-20 22:20:09 +07:00
_ _name ( PlayerSubscription , 'PlayerSubscription' ) ;
2023-03-21 18:54:28 +07:00
var NoSubscriberBehavior ,
AudioPlayerStatus ,
SILENCE _FRAME = import _node _buffer4 . Buffer . from ( [ 248 , 255 , 254 ] ) ;
function stringifyState2 ( e ) {
return JSON . stringify ( { ... e , resource : Reflect . has ( e , 'resource' ) , stepTimeout : Reflect . has ( e , 'stepTimeout' ) } ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
! ( function ( e ) {
( e . Pause = 'pause' ) , ( e . Play = 'play' ) , ( e . Stop = 'stop' ) ;
} ) ( NoSubscriberBehavior || ( NoSubscriberBehavior = { } ) ) ,
( function ( e ) {
( e . AutoPaused = 'autopaused' ) ,
( e . Buffering = 'buffering' ) ,
( e . Idle = 'idle' ) ,
( e . Paused = 'paused' ) ,
( e . Playing = 'playing' ) ;
} ) ( AudioPlayerStatus || ( AudioPlayerStatus = { } ) ) ,
_ _name ( stringifyState2 , 'stringifyState' ) ;
var EndBehaviorType ,
AudioPlayer = class extends import _node _events4 . EventEmitter {
subscribers = [ ] ;
constructor ( e = { } ) {
super ( ) ,
( this . _state = { status : AudioPlayerStatus . Idle } ) ,
( this . behaviors = { noSubscriber : NoSubscriberBehavior . Pause , maxMissedFrames : 5 , ... e . behaviors } ) ,
( this . debug = ! 1 === e . debug ? null : e => this . emit ( 'debug' , e ) ) ;
}
get playable ( ) {
return this . subscribers
. filter ( ( { connection : e } ) => e . state . status === VoiceConnectionStatus . Ready )
. map ( ( { connection : e } ) => e ) ;
}
subscribe ( e ) {
const t = this . subscribers . find ( t => t . connection === e ) ;
if ( ! t ) {
const t = new PlayerSubscription ( e , this ) ;
return this . subscribers . push ( t ) , setImmediate ( ( ) => this . emit ( 'subscribe' , t ) ) , t ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
return t ;
}
unsubscribe ( e ) {
const t = this . subscribers . indexOf ( e ) ,
s = - 1 !== t ;
return s && ( this . subscribers . splice ( t , 1 ) , e . connection . setSpeaking ( ! 1 ) , this . emit ( 'unsubscribe' , e ) ) , s ;
}
get state ( ) {
return this . _state ;
}
set state ( e ) {
const t = this . _state ,
s = Reflect . get ( e , 'resource' ) ;
t . status !== AudioPlayerStatus . Idle &&
t . resource !== s &&
( t . resource . playStream . on ( 'error' , noop ) ,
t . resource . playStream . off ( 'error' , t . onStreamError ) ,
( t . resource . audioPlayer = void 0 ) ,
t . resource . playStream . destroy ( ) ,
t . resource . playStream . read ( ) ) ,
t . status !== AudioPlayerStatus . Buffering ||
( e . status === AudioPlayerStatus . Buffering && e . resource === t . resource ) ||
( t . resource . playStream . off ( 'end' , t . onFailureCallback ) ,
t . resource . playStream . off ( 'close' , t . onFailureCallback ) ,
t . resource . playStream . off ( 'finish' , t . onFailureCallback ) ,
t . resource . playStream . off ( 'readable' , t . onReadableCallback ) ) ,
e . status === AudioPlayerStatus . Idle && ( this . _signalStopSpeaking ( ) , deleteAudioPlayer ( this ) ) ,
s && addAudioPlayer ( this ) ;
const o =
t . status !== AudioPlayerStatus . Idle && e . status === AudioPlayerStatus . Playing && t . resource !== e . resource ;
( this . _state = e ) ,
this . emit ( 'stateChange' , t , this . _state ) ,
( t . status !== e . status || o ) && this . emit ( e . status , t , this . _state ) ,
this . debug ? . ( ` state change: \n from ${ stringifyState2 ( t ) } \n to ${ stringifyState2 ( e ) } ` ) ;
}
play ( e ) {
if ( e . ended ) throw new Error ( 'Cannot play a resource that has already ended.' ) ;
if ( e . audioPlayer ) {
if ( e . audioPlayer === this ) return ;
throw new Error ( 'Resource is already being played by another audio player.' ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
e . audioPlayer = this ;
const t = _ _name ( t => {
this . state . status !== AudioPlayerStatus . Idle &&
this . emit ( 'error' , new AudioPlayerError ( t , this . state . resource ) ) ,
this . state . status !== AudioPlayerStatus . Idle &&
this . state . resource === e &&
( this . state = { status : AudioPlayerStatus . Idle } ) ;
} , 'onStreamError' ) ;
if ( ( e . playStream . once ( 'error' , t ) , e . started ) )
2022-05-21 21:02:00 +07:00
this . state = {
2023-03-21 18:54:28 +07:00
status : AudioPlayerStatus . Playing ,
missedFrames : 0 ,
playbackDuration : 0 ,
resource : e ,
onStreamError : t ,
2022-05-21 21:02:00 +07:00
} ;
2023-03-21 18:54:28 +07:00
else {
const s = _ _name ( ( ) => {
this . state . status === AudioPlayerStatus . Buffering &&
this . state . resource === e &&
( this . state = {
status : AudioPlayerStatus . Playing ,
missedFrames : 0 ,
playbackDuration : 0 ,
resource : e ,
onStreamError : t ,
} ) ;
} , 'onReadableCallback' ) ,
o = _ _name ( ( ) => {
this . state . status === AudioPlayerStatus . Buffering &&
this . state . resource === e &&
( this . state = { status : AudioPlayerStatus . Idle } ) ;
} , 'onFailureCallback' ) ;
e . playStream . once ( 'readable' , s ) ,
e . playStream . once ( 'end' , o ) ,
e . playStream . once ( 'close' , o ) ,
e . playStream . once ( 'finish' , o ) ,
( this . state = {
status : AudioPlayerStatus . Buffering ,
resource : e ,
onReadableCallback : s ,
onFailureCallback : o ,
onStreamError : t ,
} ) ;
2022-05-21 21:02:00 +07:00
}
}
2023-03-21 18:54:28 +07:00
pause ( e = ! 0 ) {
return (
this . state . status === AudioPlayerStatus . Playing &&
( ( this . state = { ... this . state , status : AudioPlayerStatus . Paused , silencePacketsRemaining : e ? 5 : 0 } ) , ! 0 )
) ;
2022-09-28 19:40:46 +07:00
}
2023-03-21 18:54:28 +07:00
unpause ( ) {
return (
this . state . status === AudioPlayerStatus . Paused &&
( ( this . state = { ... this . state , status : AudioPlayerStatus . Playing , missedFrames : 0 } ) , ! 0 )
) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
stop ( e = ! 1 ) {
return (
this . state . status !== AudioPlayerStatus . Idle &&
( e || 0 === this . state . resource . silencePaddingFrames
? ( this . state = { status : AudioPlayerStatus . Idle } )
: - 1 === this . state . resource . silenceRemaining &&
( this . state . resource . silenceRemaining = this . state . resource . silencePaddingFrames ) ,
! 0 )
) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
checkPlayable ( ) {
const e = this . _state ;
return (
e . status !== AudioPlayerStatus . Idle &&
e . status !== AudioPlayerStatus . Buffering &&
( ! ! e . resource . readable || ( ( this . state = { status : AudioPlayerStatus . Idle } ) , ! 1 ) )
) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
_stepDispatch ( ) {
const e = this . _state ;
if ( e . status !== AudioPlayerStatus . Idle && e . status !== AudioPlayerStatus . Buffering )
for ( const e of this . playable ) e . dispatchAudio ( ) ;
}
_stepPrepare ( ) {
const e = this . _state ;
if ( e . status === AudioPlayerStatus . Idle || e . status === AudioPlayerStatus . Buffering ) return ;
const t = this . playable ;
if (
( e . status === AudioPlayerStatus . AutoPaused &&
t . length > 0 &&
( this . state = { ... e , status : AudioPlayerStatus . Playing , missedFrames : 0 } ) ,
e . status === AudioPlayerStatus . Paused || e . status === AudioPlayerStatus . AutoPaused )
)
return void (
e . silencePacketsRemaining > 0 &&
( e . silencePacketsRemaining -- ,
this . _preparePacket ( SILENCE _FRAME , t , e ) ,
0 === e . silencePacketsRemaining && this . _signalStopSpeaking ( ) )
) ;
if ( 0 === t . length ) {
if ( this . behaviors . noSubscriber === NoSubscriberBehavior . Pause )
return void ( this . state = { ... e , status : AudioPlayerStatus . AutoPaused , silencePacketsRemaining : 5 } ) ;
this . behaviors . noSubscriber === NoSubscriberBehavior . Stop && this . stop ( ! 0 ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
const s = e . resource . read ( ) ;
e . status === AudioPlayerStatus . Playing &&
( s
? ( this . _preparePacket ( s , t , e ) , ( e . missedFrames = 0 ) )
: ( this . _preparePacket ( SILENCE _FRAME , t , e ) ,
e . missedFrames ++ ,
e . missedFrames >= this . behaviors . maxMissedFrames && this . stop ( ) ) ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
_signalStopSpeaking ( ) {
for ( const { connection : e } of this . subscribers ) e . setSpeaking ( ! 1 ) ;
2022-09-28 19:40:46 +07:00
}
2023-03-21 18:54:28 +07:00
_preparePacket ( e , t , s ) {
s . playbackDuration += 20 ;
for ( const s of t ) s . prepareAudioPacket ( e ) ;
2022-09-28 19:40:46 +07:00
}
2023-03-21 18:54:28 +07:00
} ;
function createAudioPlayer ( e ) {
return new AudioPlayer ( e ) ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
function createDefaultAudioReceiveStreamOptions ( ) {
2023-03-21 18:54:28 +07:00
return { end : { behavior : EndBehaviorType . Manual } } ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
_ _name ( AudioPlayer , 'AudioPlayer' ) ,
_ _name ( createAudioPlayer , 'createAudioPlayer' ) ,
( function ( e ) {
( e [ ( e . Manual = 0 ) ] = 'Manual' ) ,
( e [ ( e . AfterSilence = 1 ) ] = 'AfterSilence' ) ,
( e [ ( e . AfterInactivity = 2 ) ] = 'AfterInactivity' ) ;
} ) ( EndBehaviorType || ( EndBehaviorType = { } ) ) ,
_ _name ( createDefaultAudioReceiveStreamOptions , 'createDefaultAudioReceiveStreamOptions' ) ;
2022-08-01 13:02:58 +07:00
var AudioReceiveStream = class extends import _node _stream . Readable {
2023-03-21 18:54:28 +07:00
constructor ( { end : e , ... t } ) {
super ( { ... t , objectMode : ! 0 } ) , ( this . end = e ) ;
}
push ( e ) {
return (
! e ||
( this . end . behavior !== EndBehaviorType . AfterInactivity &&
( this . end . behavior !== EndBehaviorType . AfterSilence ||
( 0 === e . compare ( SILENCE _FRAME ) && void 0 !== this . endTimeout ) ) ) ||
this . renewEndTimeout ( this . end ) ,
super . push ( e )
) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
renewEndTimeout ( e ) {
this . endTimeout && clearTimeout ( this . endTimeout ) , ( this . endTimeout = setTimeout ( ( ) => this . push ( null ) , e . duration ) ) ;
2022-05-21 21:02:00 +07:00
}
2022-12-20 22:20:09 +07:00
_read ( ) { }
2022-05-21 21:02:00 +07:00
} ;
2022-12-20 22:20:09 +07:00
_ _name ( AudioReceiveStream , 'AudioReceiveStream' ) ;
2023-03-21 18:54:28 +07:00
var import _node _events5 = require ( 'events' ) ,
SSRCMap = class extends import _node _events5 . EventEmitter {
constructor ( ) {
super ( ) , ( this . map = new Map ( ) ) ;
}
update ( e ) {
const t = this . map . get ( e . audioSSRC ) ,
s = { ... this . map . get ( e . audioSSRC ) , ... e } ;
this . map . set ( e . audioSSRC , s ) , t || this . emit ( 'create' , s ) , this . emit ( 'update' , t , s ) ;
}
get ( e ) {
if ( 'number' == typeof e ) return this . map . get ( e ) ;
for ( const t of this . map . values ( ) ) if ( t . userId === e ) return t ;
}
delete ( e ) {
if ( 'number' == typeof e ) {
const t = this . map . get ( e ) ;
return t && ( this . map . delete ( e ) , this . emit ( 'delete' , t ) ) , t ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
for ( const [ t , s ] of this . map . entries ( ) ) if ( s . userId === e ) return this . map . delete ( t ) , this . emit ( 'delete' , s ) , s ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
} ;
2022-12-20 22:20:09 +07:00
_ _name ( SSRCMap , 'SSRCMap' ) ;
2023-03-21 18:54:28 +07:00
var import _node _events6 = require ( 'events' ) ,
_SpeakingMap = class extends import _node _events6 . EventEmitter {
constructor ( ) {
super ( ) , ( this . users = new Map ( ) ) , ( this . speakingTimeouts = new Map ( ) ) ;
}
onPacket ( e ) {
const t = this . speakingTimeouts . get ( e ) ;
t ? clearTimeout ( t ) : ( this . users . set ( e , Date . now ( ) ) , this . emit ( 'start' , e ) ) , this . startTimeout ( e ) ;
}
startTimeout ( e ) {
this . speakingTimeouts . set (
e ,
setTimeout ( ( ) => {
this . emit ( 'end' , e ) , this . speakingTimeouts . delete ( e ) , this . users . delete ( e ) ;
} , _SpeakingMap . DELAY ) ,
) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
} ,
SpeakingMap = _SpeakingMap ;
_ _name ( SpeakingMap , 'SpeakingMap' ) , _ _publicField ( SpeakingMap , 'DELAY' , 100 ) ;
var VoiceConnectionStatus ,
VoiceConnectionDisconnectReason ,
VoiceReceiver = class {
constructor ( e ) {
( this . voiceConnection = e ) ,
( this . ssrcMap = new SSRCMap ( ) ) ,
( this . speaking = new SpeakingMap ( ) ) ,
( this . subscriptions = new Map ( ) ) ,
( this . connectionData = { } ) ,
( this . onWsPacket = this . onWsPacket . bind ( this ) ) ,
( this . onUdpMessage = this . onUdpMessage . bind ( this ) ) ;
}
onWsPacket ( e ) {
e . op === import _v43 . VoiceOpcodes . ClientDisconnect && 'string' == typeof e . d ? . user _id
? this . ssrcMap . delete ( e . d . user _id )
: e . op === import _v43 . VoiceOpcodes . Speaking && 'string' == typeof e . d ? . user _id && 'number' == typeof e . d ? . ssrc
? this . ssrcMap . update ( { userId : e . d . user _id , audioSSRC : e . d . ssrc } )
: e . op === import _v43 . VoiceOpcodes . ClientConnect &&
'string' == typeof e . d ? . user _id &&
'number' == typeof e . d ? . audio _ssrc &&
this . ssrcMap . update ( {
userId : e . d . user _id ,
audioSSRC : e . d . audio _ssrc ,
videoSSRC : 0 === e . d . video _ssrc ? void 0 : e . d . video _ssrc ,
} ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
decrypt ( e , t , s , o ) {
let n ;
'xsalsa20_poly1305_lite' === t
? ( e . copy ( s , 0 , e . length - 4 ) , ( n = e . length - 4 ) )
: 'xsalsa20_poly1305_suffix' === t
? ( e . copy ( s , 0 , e . length - 24 ) , ( n = e . length - 24 ) )
: e . copy ( s , 0 , 0 , 12 ) ;
const i = methods . open ( e . slice ( 12 , n ) , s , o ) ;
if ( i ) return import _node _buffer5 . Buffer . from ( i ) ;
}
parsePacket ( e , t , s , o ) {
let n = this . decrypt ( e , t , s , o ) ;
if ( n ) {
if ( 190 === n [ 0 ] && 222 === n [ 1 ] ) {
const e = n . readUInt16BE ( 2 ) ;
n = n . subarray ( 4 + 4 * e ) ;
}
return n ;
}
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
onUdpMessage ( e ) {
if ( e . length <= 8 ) return ;
const t = e . readUInt32BE ( 8 ) ,
s = this . ssrcMap . get ( t ) ;
if ( ! s ) return ;
this . speaking . onPacket ( s . userId ) ;
const o = this . subscriptions . get ( s . userId ) ;
if ( o && this . connectionData . encryptionMode && this . connectionData . nonceBuffer && this . connectionData . secretKey ) {
const t = this . parsePacket (
e ,
this . connectionData . encryptionMode ,
this . connectionData . nonceBuffer ,
this . connectionData . secretKey ,
) ;
t ? o . push ( t ) : o . destroy ( new Error ( 'Failed to parse packet' ) ) ;
2022-05-21 21:02:00 +07:00
}
}
2023-03-21 18:54:28 +07:00
subscribe ( e , t ) {
const s = this . subscriptions . get ( e ) ;
if ( s ) return s ;
const o = new AudioReceiveStream ( { ... createDefaultAudioReceiveStreamOptions ( ) , ... t } ) ;
return o . once ( 'close' , ( ) => this . subscriptions . delete ( e ) ) , this . subscriptions . set ( e , o ) , o ;
}
} ;
_ _name ( VoiceReceiver , 'VoiceReceiver' ) ,
( function ( e ) {
( e . Connecting = 'connecting' ) ,
( e . Destroyed = 'destroyed' ) ,
( e . Disconnected = 'disconnected' ) ,
( e . Ready = 'ready' ) ,
( e . Signalling = 'signalling' ) ;
} ) ( VoiceConnectionStatus || ( VoiceConnectionStatus = { } ) ) ,
( function ( e ) {
( e [ ( e . WebSocketClose = 0 ) ] = 'WebSocketClose' ) ,
( e [ ( e . AdapterUnavailable = 1 ) ] = 'AdapterUnavailable' ) ,
( e [ ( e . EndpointRemoved = 2 ) ] = 'EndpointRemoved' ) ,
( e [ ( e . Manual = 3 ) ] = 'Manual' ) ;
} ) ( VoiceConnectionDisconnectReason || ( VoiceConnectionDisconnectReason = { } ) ) ;
2022-09-28 19:40:46 +07:00
var VoiceConnection = class extends import _node _events7 . EventEmitter {
2023-03-21 18:54:28 +07:00
constructor ( e , t ) {
super ( ) ,
( this . debug = t . debug ? e => this . emit ( 'debug' , e ) : null ) ,
( this . rejoinAttempts = 0 ) ,
( this . receiver = new VoiceReceiver ( this ) ) ,
( this . onNetworkingClose = this . onNetworkingClose . bind ( this ) ) ,
( this . onNetworkingStateChange = this . onNetworkingStateChange . bind ( this ) ) ,
( this . onNetworkingError = this . onNetworkingError . bind ( this ) ) ,
( this . onNetworkingDebug = this . onNetworkingDebug . bind ( this ) ) ;
const s = t . adapterCreator ( {
onVoiceServerUpdate : e => this . addServerPacket ( e ) ,
onVoiceStateUpdate : e => this . addStatePacket ( e ) ,
destroy : ( ) => this . destroy ( ! 1 ) ,
2022-05-21 21:02:00 +07:00
} ) ;
2023-03-21 18:54:28 +07:00
( this . _state = { status : VoiceConnectionStatus . Signalling , adapter : s } ) ,
( this . packets = { server : void 0 , state : void 0 } ) ,
( this . joinConfig = e ) ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
get state ( ) {
2022-05-21 21:02:00 +07:00
return this . _state ;
}
2023-03-21 18:54:28 +07:00
set state ( e ) {
const t = this . _state ,
s = Reflect . get ( t , 'networking' ) ,
o = Reflect . get ( e , 'networking' ) ,
n = Reflect . get ( t , 'subscription' ) ,
i = Reflect . get ( e , 'subscription' ) ;
if (
( s !== o &&
( s &&
( s . on ( 'error' , noop ) ,
s . off ( 'debug' , this . onNetworkingDebug ) ,
s . off ( 'error' , this . onNetworkingError ) ,
s . off ( 'close' , this . onNetworkingClose ) ,
s . off ( 'stateChange' , this . onNetworkingStateChange ) ,
s . destroy ( ) ) ,
o && this . updateReceiveBindings ( o . state , s ? . state ) ) ,
e . status === VoiceConnectionStatus . Ready )
)
2022-05-21 21:02:00 +07:00
this . rejoinAttempts = 0 ;
2023-03-21 18:54:28 +07:00
else if ( e . status === VoiceConnectionStatus . Destroyed )
for ( const e of this . receiver . subscriptions . values ( ) ) e . destroyed || e . destroy ( ) ;
t . status !== VoiceConnectionStatus . Destroyed && e . status === VoiceConnectionStatus . Destroyed && t . adapter . destroy ( ) ,
( this . _state = e ) ,
n && n !== i && n . unsubscribe ( ) ,
this . emit ( 'stateChange' , t , e ) ,
t . status !== e . status && this . emit ( e . status , t , e ) ;
}
addServerPacket ( e ) {
( this . packets . server = e ) ,
e . endpoint
? this . configureNetworking ( )
: this . state . status !== VoiceConnectionStatus . Destroyed &&
( this . state = {
... this . state ,
status : VoiceConnectionStatus . Disconnected ,
reason : VoiceConnectionDisconnectReason . EndpointRemoved ,
} ) ;
2022-08-01 13:02:58 +07:00
}
2023-03-21 18:54:28 +07:00
addStatePacket ( e ) {
( this . packets . state = e ) ,
void 0 !== e . self _deaf && ( this . joinConfig . selfDeaf = e . self _deaf ) ,
void 0 !== e . self _mute && ( this . joinConfig . selfMute = e . self _mute ) ,
e . channel _id && ( this . joinConfig . channelId = e . channel _id ) ;
}
updateReceiveBindings ( e , t ) {
const s = Reflect . get ( t ? ? { } , 'ws' ) ,
o = Reflect . get ( e , 'ws' ) ,
n = Reflect . get ( t ? ? { } , 'udp' ) ,
i = Reflect . get ( e , 'udp' ) ;
s !== o && ( s ? . off ( 'packet' , this . receiver . onWsPacket ) , o ? . on ( 'packet' , this . receiver . onWsPacket ) ) ,
n !== i && ( n ? . off ( 'message' , this . receiver . onUdpMessage ) , i ? . on ( 'message' , this . receiver . onUdpMessage ) ) ,
( this . receiver . connectionData = Reflect . get ( e , 'connectionData' ) ? ? { } ) ;
2022-08-01 13:02:58 +07:00
}
configureNetworking ( ) {
2023-03-21 18:54:28 +07:00
const { server : e , state : t } = this . packets ;
if ( ! e || ! t || this . state . status === VoiceConnectionStatus . Destroyed || ! e . endpoint ) return ;
const s = new Networking (
2022-08-01 13:02:58 +07:00
{
2023-03-21 18:54:28 +07:00
endpoint : e . endpoint ,
serverId : e . guild _id ? ? e . channel _id ,
token : e . token ,
sessionId : t . session _id ,
userId : t . user _id ,
2022-08-01 13:02:58 +07:00
} ,
2022-12-20 22:20:09 +07:00
Boolean ( this . debug ) ,
2022-08-01 13:02:58 +07:00
) ;
2023-03-21 18:54:28 +07:00
s . once ( 'close' , this . onNetworkingClose ) ,
s . on ( 'stateChange' , this . onNetworkingStateChange ) ,
s . on ( 'error' , this . onNetworkingError ) ,
s . on ( 'debug' , this . onNetworkingDebug ) ,
( this . state = { ... this . state , status : VoiceConnectionStatus . Connecting , networking : s } ) ;
}
onNetworkingClose ( e ) {
this . state . status !== VoiceConnectionStatus . Destroyed &&
( 4014 === e
? ( this . state = {
... this . state ,
status : VoiceConnectionStatus . Disconnected ,
reason : VoiceConnectionDisconnectReason . WebSocketClose ,
closeCode : e ,
} )
: ( ( this . state = { ... this . state , status : VoiceConnectionStatus . Signalling } ) ,
this . rejoinAttempts ++ ,
this . state . adapter . sendPayload ( createJoinVoiceChannelPayload ( this . joinConfig ) ) ||
( this . state = {
... this . state ,
status : VoiceConnectionStatus . Disconnected ,
reason : VoiceConnectionDisconnectReason . AdapterUnavailable ,
} ) ) ) ;
}
onNetworkingStateChange ( e , t ) {
this . updateReceiveBindings ( t , e ) ,
e . code !== t . code &&
( ( this . state . status !== VoiceConnectionStatus . Connecting &&
this . state . status !== VoiceConnectionStatus . Ready ) ||
( t . code === NetworkingStatusCode . Ready
? ( this . state = { ... this . state , status : VoiceConnectionStatus . Ready } )
: t . code !== NetworkingStatusCode . Closed &&
( this . state = { ... this . state , status : VoiceConnectionStatus . Connecting } ) ) ) ;
}
onNetworkingError ( e ) {
this . emit ( 'error' , e ) ;
}
onNetworkingDebug ( e ) {
this . debug ? . ( ` [NW] ${ e } ` ) ;
}
prepareAudioPacket ( e ) {
const t = this . state ;
if ( t . status === VoiceConnectionStatus . Ready ) return t . networking . prepareAudioPacket ( e ) ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
dispatchAudio ( ) {
2023-03-21 18:54:28 +07:00
const e = this . state ;
if ( e . status === VoiceConnectionStatus . Ready ) return e . networking . dispatchAudio ( ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
playOpusPacket ( e ) {
const t = this . state ;
if ( t . status === VoiceConnectionStatus . Ready )
return t . networking . prepareAudioPacket ( e ) , t . networking . dispatchAudio ( ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
destroy ( e = ! 0 ) {
if ( this . state . status === VoiceConnectionStatus . Destroyed )
2022-12-20 22:20:09 +07:00
throw new Error ( 'Cannot destroy VoiceConnection - it has already been destroyed' ) ;
2023-03-21 18:54:28 +07:00
getVoiceConnection ( this . joinConfig . guildId , this . joinConfig . group ) === this && untrackVoiceConnection ( this ) ,
e && this . state . adapter . sendPayload ( createJoinVoiceChannelPayload ( { ... this . joinConfig , channelId : null } ) ) ,
( this . state = { status : VoiceConnectionStatus . Destroyed } ) ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
disconnect ( ) {
2023-03-21 18:54:28 +07:00
return (
this . state . status !== VoiceConnectionStatus . Destroyed &&
this . state . status !== VoiceConnectionStatus . Signalling &&
( ( this . joinConfig . channelId = null ) ,
this . state . adapter . sendPayload ( createJoinVoiceChannelPayload ( this . joinConfig ) )
? ( ( this . state = {
adapter : this . state . adapter ,
reason : VoiceConnectionDisconnectReason . Manual ,
status : VoiceConnectionStatus . Disconnected ,
} ) ,
! 0 )
: ( ( this . state = {
adapter : this . state . adapter ,
subscription : this . state . subscription ,
status : VoiceConnectionStatus . Disconnected ,
reason : VoiceConnectionDisconnectReason . AdapterUnavailable ,
} ) ,
! 1 ) )
) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
rejoin ( e ) {
if ( this . state . status === VoiceConnectionStatus . Destroyed ) return ! 1 ;
const t = this . state . status !== VoiceConnectionStatus . Ready ;
return (
t && this . rejoinAttempts ++ ,
Object . assign ( this . joinConfig , e ) ,
this . state . adapter . sendPayload ( createJoinVoiceChannelPayload ( this . joinConfig ) )
? ( t && ( this . state = { ... this . state , status : VoiceConnectionStatus . Signalling } ) , ! 0 )
: ( ( this . state = {
adapter : this . state . adapter ,
subscription : this . state . subscription ,
status : VoiceConnectionStatus . Disconnected ,
reason : VoiceConnectionDisconnectReason . AdapterUnavailable ,
} ) ,
! 1 )
) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
setSpeaking ( e ) {
return this . state . status === VoiceConnectionStatus . Ready && this . state . networking . setSpeaking ( e ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
subscribe ( e ) {
2023-03-21 18:47:11 +07:00
if ( this . state . status === VoiceConnectionStatus . Destroyed ) return ;
2023-03-21 18:54:28 +07:00
const t = e . subscribe ( this ) ;
return ( this . state = { ... this . state , subscription : t } ) , t ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
get ping ( ) {
2023-03-21 18:54:28 +07:00
return this . state . status === VoiceConnectionStatus . Ready &&
2023-03-21 18:47:11 +07:00
this . state . networking . state . code === NetworkingStatusCode . Ready
2023-03-21 18:54:28 +07:00
? { ws : this . state . networking . state . ws . ping , udp : this . state . networking . state . udp . ping }
: { ws : void 0 , udp : void 0 } ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
onSubscriptionRemoved ( e ) {
this . state . status !== VoiceConnectionStatus . Destroyed &&
this . state . subscription === e &&
( this . state = { ... this . state , subscription : void 0 } ) ;
2022-05-21 21:02:00 +07:00
}
} ;
2023-03-21 18:54:28 +07:00
function createVoiceConnection ( e , t ) {
const s = createJoinVoiceChannelPayload ( e ) ,
o = getVoiceConnection ( e . guildId , e . group ) ;
if ( o && o . state . status !== VoiceConnectionStatus . Destroyed )
return (
o . state . status === VoiceConnectionStatus . Disconnected
? o . rejoin ( { channelId : e . channelId , selfDeaf : e . selfDeaf , selfMute : e . selfMute } )
: o . state . adapter . sendPayload ( s ) ||
( o . state = {
... o . state ,
status : VoiceConnectionStatus . Disconnected ,
reason : VoiceConnectionDisconnectReason . AdapterUnavailable ,
} ) ,
o
) ;
const n = new VoiceConnection ( e , t ) ;
return (
trackVoiceConnection ( n ) ,
n . state . status === VoiceConnectionStatus . Destroyed ||
n . state . adapter . sendPayload ( s ) ||
( n . state = {
... n . state ,
2023-03-21 18:47:11 +07:00
status : VoiceConnectionStatus . Disconnected ,
reason : VoiceConnectionDisconnectReason . AdapterUnavailable ,
2023-03-21 18:54:28 +07:00
} ) ,
n
) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
function joinVoiceChannel ( e ) {
return createVoiceConnection (
{ selfDeaf : ! 0 , selfMute : ! 1 , group : 'default' , ... e } ,
{ adapterCreator : e . adapterCreator , debug : e . debug } ,
) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
_ _name ( VoiceConnection , 'VoiceConnection' ) ,
_ _name ( createVoiceConnection , 'createVoiceConnection' ) ,
_ _name ( joinVoiceChannel , 'joinVoiceChannel' ) ;
var StreamType ,
TransformerType ,
import _node _stream2 = require ( 'stream' ) ,
import _prism _media2 = _ _toESM ( require ( 'prism-media' ) ) ,
import _prism _media = _ _toESM ( require ( 'prism-media' ) ) ,
FFMPEG _PCM _ARGUMENTS = [ '-analyzeduration' , '0' , '-loglevel' , '0' , '-f' , 's16le' , '-ar' , '48000' , '-ac' , '2' ] ,
FFMPEG _OPUS _ARGUMENTS = [
'-analyzeduration' ,
'0' ,
'-loglevel' ,
'0' ,
'-acodec' ,
'libopus' ,
'-f' ,
'opus' ,
'-ar' ,
'48000' ,
'-ac' ,
'2' ,
] ;
! ( function ( e ) {
( e . Arbitrary = 'arbitrary' ) , ( e . OggOpus = 'ogg/opus' ) , ( e . Opus = 'opus' ) , ( e . Raw = 'raw' ) , ( e . WebmOpus = 'webm/opus' ) ;
} ) ( StreamType || ( StreamType = { } ) ) ,
( function ( e ) {
( e . FFmpegOgg = 'ffmpeg ogg' ) ,
( e . FFmpegPCM = 'ffmpeg pcm' ) ,
( e . InlineVolume = 'volume transformer' ) ,
( e . OggOpusDemuxer = 'ogg/opus demuxer' ) ,
( e . OpusDecoder = 'opus decoder' ) ,
( e . OpusEncoder = 'opus encoder' ) ,
( e . WebmOpusDemuxer = 'webm/opus demuxer' ) ;
} ) ( TransformerType || ( TransformerType = { } ) ) ;
2022-08-01 13:02:58 +07:00
var Node = class {
2022-09-28 19:40:46 +07:00
edges = [ ] ;
2023-03-21 18:54:28 +07:00
constructor ( e ) {
this . type = e ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
addEdge ( e ) {
this . edges . push ( { ... e , from : this } ) ;
2022-05-21 21:02:00 +07:00
}
} ;
2022-12-20 22:20:09 +07:00
_ _name ( Node , 'Node' ) ;
2023-03-21 18:54:28 +07:00
var NODES = new Map ( ) ;
for ( const e of Object . values ( StreamType ) ) NODES . set ( e , new Node ( e ) ) ;
function getNode ( e ) {
const t = NODES . get ( e ) ;
if ( ! t ) throw new Error ( ` Node type ' ${ e } ' does not exist! ` ) ;
return t ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
_ _name ( getNode , 'getNode' ) ,
getNode ( StreamType . Raw ) . addEdge ( {
type : TransformerType . OpusEncoder ,
to : getNode ( StreamType . Opus ) ,
cost : 1.5 ,
transformer : ( ) => new import _prism _media . default . opus . Encoder ( { rate : 48e3 , channels : 2 , frameSize : 960 } ) ,
} ) ,
getNode ( StreamType . Opus ) . addEdge ( {
type : TransformerType . OpusDecoder ,
to : getNode ( StreamType . Raw ) ,
cost : 1.5 ,
transformer : ( ) => new import _prism _media . default . opus . Decoder ( { rate : 48e3 , channels : 2 , frameSize : 960 } ) ,
} ) ,
getNode ( StreamType . OggOpus ) . addEdge ( {
type : TransformerType . OggOpusDemuxer ,
to : getNode ( StreamType . Opus ) ,
cost : 1 ,
transformer : ( ) => new import _prism _media . default . opus . OggDemuxer ( ) ,
} ) ,
getNode ( StreamType . WebmOpus ) . addEdge ( {
type : TransformerType . WebmOpusDemuxer ,
to : getNode ( StreamType . Opus ) ,
cost : 1 ,
transformer : ( ) => new import _prism _media . default . opus . WebmDemuxer ( ) ,
} ) ;
2022-05-21 21:02:00 +07:00
var FFMPEG _PCM _EDGE = {
2023-03-21 18:47:11 +07:00
type : TransformerType . FFmpegPCM ,
to : getNode ( StreamType . Raw ) ,
2022-05-21 21:02:00 +07:00
cost : 2 ,
2023-03-21 18:54:28 +07:00
transformer : e =>
2022-12-20 22:20:09 +07:00
new import _prism _media . default . FFmpeg ( {
2023-03-21 18:54:28 +07:00
args : 'string' == typeof e ? [ '-i' , e , ... FFMPEG _PCM _ARGUMENTS ] : FFMPEG _PCM _ARGUMENTS ,
2022-12-20 22:20:09 +07:00
} ) ,
2022-05-21 21:02:00 +07:00
} ;
2022-08-01 13:02:58 +07:00
function canEnableFFmpegOptimizations ( ) {
try {
2022-12-20 22:20:09 +07:00
return import _prism _media . default . FFmpeg . getInfo ( ) . output . includes ( '--enable-libopus' ) ;
} catch { }
2023-03-21 18:54:28 +07:00
return ! 1 ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
if (
( getNode ( StreamType . Arbitrary ) . addEdge ( FFMPEG _PCM _EDGE ) ,
getNode ( StreamType . OggOpus ) . addEdge ( FFMPEG _PCM _EDGE ) ,
getNode ( StreamType . WebmOpus ) . addEdge ( FFMPEG _PCM _EDGE ) ,
getNode ( StreamType . Raw ) . addEdge ( {
type : TransformerType . InlineVolume ,
to : getNode ( StreamType . Raw ) ,
cost : 0.5 ,
transformer : ( ) => new import _prism _media . default . VolumeTransformer ( { type : 's16le' } ) ,
} ) ,
_ _name ( canEnableFFmpegOptimizations , 'canEnableFFmpegOptimizations' ) ,
canEnableFFmpegOptimizations ( ) )
) {
const e = {
2023-03-21 18:47:11 +07:00
type : TransformerType . FFmpegOgg ,
to : getNode ( StreamType . OggOpus ) ,
2022-05-21 21:02:00 +07:00
cost : 2 ,
2023-03-21 18:54:28 +07:00
transformer : e =>
2022-12-20 22:20:09 +07:00
new import _prism _media . default . FFmpeg ( {
2023-03-21 18:54:28 +07:00
args : 'string' == typeof e ? [ '-i' , e , ... FFMPEG _OPUS _ARGUMENTS ] : FFMPEG _OPUS _ARGUMENTS ,
2022-12-20 22:20:09 +07:00
} ) ,
2022-05-21 21:02:00 +07:00
} ;
2023-03-21 18:54:28 +07:00
getNode ( StreamType . Arbitrary ) . addEdge ( e ) ,
getNode ( StreamType . OggOpus ) . addEdge ( e ) ,
getNode ( StreamType . WebmOpus ) . addEdge ( e ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
function findPath ( e , t , s = getNode ( StreamType . Opus ) , o = [ ] , n = 5 ) {
if ( e === s && t ( o ) ) return { cost : 0 } ;
if ( 0 === n ) return { cost : Number . POSITIVE _INFINITY } ;
let i ;
for ( const r of e . edges ) {
if ( i && r . cost > i . cost ) continue ;
const e = findPath ( r . to , t , s , [ ... o , r ] , n - 1 ) ,
a = r . cost + e . cost ;
( ! i || a < i . cost ) && ( i = { cost : a , edge : r , next : e } ) ;
}
return i ? ? { cost : Number . POSITIVE _INFINITY } ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
function constructPipeline ( e ) {
const t = [ ] ;
let s = e ;
for ( ; s ? . edge ; ) t . push ( s . edge ) , ( s = s . next ) ;
return t ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
function findPipeline ( e , t ) {
return constructPipeline ( findPath ( getNode ( e ) , t ) ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
_ _name ( findPath , 'findPath' ) , _ _name ( constructPipeline , 'constructPipeline' ) , _ _name ( findPipeline , 'findPipeline' ) ;
2022-08-01 13:02:58 +07:00
var AudioResource = class {
2022-09-28 19:40:46 +07:00
playbackDuration = 0 ;
2023-03-21 18:54:28 +07:00
started = ! 1 ;
2022-09-28 19:40:46 +07:00
silenceRemaining = - 1 ;
2023-03-21 18:54:28 +07:00
constructor ( e , t , s , o ) {
( this . edges = e ) ,
( this . playStream = t . length > 1 ? ( 0 , import _node _stream2 . pipeline ) ( t , noop ) : t [ 0 ] ) ,
( this . metadata = s ) ,
( this . silencePaddingFrames = o ) ;
for ( const e of t )
e instanceof import _prism _media2 . default . VolumeTransformer
? ( this . volume = e )
: e instanceof import _prism _media2 . default . opus . Encoder && ( this . encoder = e ) ;
this . playStream . once ( 'readable' , ( ) => ( this . started = ! 0 ) ) ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
get readable ( ) {
2023-03-21 18:54:28 +07:00
if ( 0 === this . silenceRemaining ) return ! 1 ;
const e = this . playStream . readable ;
return (
e ||
( - 1 === this . silenceRemaining && ( this . silenceRemaining = this . silencePaddingFrames ) , 0 !== this . silenceRemaining )
) ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
get ended ( ) {
2023-03-21 18:54:28 +07:00
return this . playStream . readableEnded || this . playStream . destroyed || 0 === this . silenceRemaining ;
2022-05-21 21:02:00 +07:00
}
2022-08-01 13:02:58 +07:00
read ( ) {
2023-03-21 18:54:28 +07:00
if ( 0 === this . silenceRemaining ) return null ;
if ( this . silenceRemaining > 0 ) return this . silenceRemaining -- , SILENCE _FRAME ;
const e = this . playStream . read ( ) ;
return e && ( this . playbackDuration += 20 ) , e ;
2022-05-21 21:02:00 +07:00
}
} ;
2022-12-20 22:20:09 +07:00
_ _name ( AudioResource , 'AudioResource' ) ;
2023-03-21 18:54:28 +07:00
var VOLUME _CONSTRAINT = _ _name ( e => e . some ( e => e . type === TransformerType . InlineVolume ) , 'VOLUME_CONSTRAINT' ) ,
NO _CONSTRAINT = _ _name ( ( ) => ! 0 , 'NO_CONSTRAINT' ) ;
function inferStreamType ( e ) {
return e instanceof import _prism _media2 . default . opus . Encoder
? { streamType : StreamType . Opus , hasVolume : ! 1 }
: e instanceof import _prism _media2 . default . opus . Decoder
? { streamType : StreamType . Raw , hasVolume : ! 1 }
: e instanceof import _prism _media2 . default . VolumeTransformer
? { streamType : StreamType . Raw , hasVolume : ! 0 }
: e instanceof import _prism _media2 . default . opus . OggDemuxer ||
e instanceof import _prism _media2 . default . opus . WebmDemuxer
? { streamType : StreamType . Opus , hasVolume : ! 1 }
: { streamType : StreamType . Arbitrary , hasVolume : ! 1 } ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
function createAudioResource ( e , t = { } ) {
let s = t . inputType ,
o = Boolean ( t . inlineVolume ) ;
if ( 'string' == typeof e ) s = StreamType . Arbitrary ;
else if ( void 0 === s ) {
const t = inferStreamType ( e ) ;
( s = t . streamType ) , ( o = o && ! t . hasVolume ) ;
}
const n = findPipeline ( s , o ? VOLUME _CONSTRAINT : NO _CONSTRAINT ) ;
if ( 0 === n . length ) {
if ( 'string' == typeof e ) throw new Error ( ` Invalid pipeline constructed for string resource ' ${ e } ' ` ) ;
return new AudioResource ( [ ] , [ e ] , t . metadata ? ? null , t . silencePaddingFrames ? ? 5 ) ;
}
const i = n . map ( t => t . transformer ( e ) ) ;
return 'string' != typeof e && i . unshift ( e ) , new AudioResource ( n , i , t . metadata ? ? null , t . silencePaddingFrames ? ? 5 ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
_ _name ( inferStreamType , 'inferStreamType' ) , _ _name ( createAudioResource , 'createAudioResource' ) ;
var import _node _path = require ( 'path' ) ,
import _prism _media3 = _ _toESM ( require ( 'prism-media' ) ) ;
function findPackageJSON ( e , t , s ) {
if ( 0 === s ) return ;
const o = ( 0 , import _node _path . resolve ) ( e , './package.json' ) ;
2022-08-01 13:02:58 +07:00
try {
2023-03-21 18:54:28 +07:00
const e = require ( o ) ;
if ( e . name !== t ) throw new Error ( 'package.json does not match' ) ;
return e ;
2022-09-28 19:40:46 +07:00
} catch {
2023-03-21 18:54:28 +07:00
return findPackageJSON ( ( 0 , import _node _path . resolve ) ( e , '..' ) , t , s - 1 ) ;
2022-05-21 21:02:00 +07:00
}
}
2023-03-21 18:54:28 +07:00
function version ( e ) {
2022-08-01 13:02:58 +07:00
try {
2023-03-21 18:54:28 +07:00
if ( '@discordjs/voice' === e ) return '[VI]{{inject}}[/VI]' ;
const t = findPackageJSON ( ( 0 , import _node _path . dirname ) ( require . resolve ( e ) ) , e , 3 ) ;
return t ? . version ? ? 'not found' ;
2022-09-28 19:40:46 +07:00
} catch {
2022-12-20 22:20:09 +07:00
return 'not found' ;
2022-05-21 21:02:00 +07:00
}
}
2022-08-01 13:02:58 +07:00
function generateDependencyReport ( ) {
2023-03-21 18:54:28 +07:00
const e = [ ] ,
t = _ _name ( t => e . push ( ` - ${ t } : ${ version ( t ) } ` ) , 'addVersion' ) ;
e . push ( 'Core Dependencies' ) ,
t ( '@discordjs/voice' ) ,
t ( 'prism-media' ) ,
e . push ( '' ) ,
e . push ( 'Opus Libraries' ) ,
t ( '@discordjs/opus' ) ,
t ( 'opusscript' ) ,
e . push ( '' ) ,
e . push ( 'Encryption Libraries' ) ,
t ( 'sodium-native' ) ,
t ( 'sodium' ) ,
t ( 'libsodium-wrappers' ) ,
t ( 'tweetnacl' ) ,
e . push ( '' ) ,
e . push ( 'FFmpeg' ) ;
2022-08-01 13:02:58 +07:00
try {
2023-03-21 18:54:28 +07:00
const t = import _prism _media3 . default . FFmpeg . getInfo ( ) ;
e . push ( ` - version: ${ t . version } ` ) , e . push ( '- libopus: ' + ( t . output . includes ( '--enable-libopus' ) ? 'yes' : 'no' ) ) ;
2022-09-28 19:40:46 +07:00
} catch {
2023-03-21 18:54:28 +07:00
e . push ( '- not found' ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
return [ '-' . repeat ( 50 ) , ... e , '-' . repeat ( 50 ) ] . join ( '\n' ) ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
_ _name ( findPackageJSON , 'findPackageJSON' ) ,
_ _name ( version , 'version' ) ,
_ _name ( generateDependencyReport , 'generateDependencyReport' ) ;
2022-12-20 22:20:09 +07:00
var import _node _events8 = require ( 'events' ) ;
2023-03-21 18:54:28 +07:00
function abortAfter ( e ) {
const t = new AbortController ( ) ,
s = setTimeout ( ( ) => t . abort ( ) , e ) ;
return t . signal . addEventListener ( 'abort' , ( ) => clearTimeout ( s ) ) , [ t , t . signal ] ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
async function entersState ( e , t , s ) {
if ( e . state . status !== t ) {
const [ o , n ] = 'number' == typeof s ? abortAfter ( s ) : [ void 0 , s ] ;
2022-08-01 13:02:58 +07:00
try {
2023-03-21 18:54:28 +07:00
await ( 0 , import _node _events8 . once ) ( e , t , { signal : n } ) ;
2022-08-01 13:02:58 +07:00
} finally {
2023-03-21 18:54:28 +07:00
o ? . abort ( ) ;
2022-05-21 21:02:00 +07:00
}
}
2023-03-21 18:54:28 +07:00
return e ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
_ _name ( abortAfter , 'abortAfter' ) , _ _name ( entersState , 'entersState' ) ;
var import _node _buffer6 = require ( 'buffer' ) ,
import _node _process = _ _toESM ( require ( 'process' ) ) ,
import _node _stream3 = require ( 'stream' ) ,
import _prism _media4 = _ _toESM ( require ( 'prism-media' ) ) ;
function validateDiscordOpusHead ( e ) {
const t = e . readUInt8 ( 9 ) ,
s = e . readUInt32LE ( 12 ) ;
return 2 === t && 48e3 === s ;
2022-05-21 21:02:00 +07:00
}
2023-03-21 18:54:28 +07:00
async function demuxProbe ( e , t = 1024 , s = validateDiscordOpusHead ) {
return new Promise ( ( o , n ) => {
if ( e . readableObjectMode ) return void n ( new Error ( 'Cannot probe a readable stream in object mode' ) ) ;
if ( e . readableEnded ) return void n ( new Error ( 'Cannot probe a stream that has ended' ) ) ;
let i ,
r = import _node _buffer6 . Buffer . alloc ( 0 ) ;
const a = _ _name ( t => {
e . off ( 'data' , l ) ,
e . off ( 'close' , p ) ,
e . off ( 'end' , p ) ,
e . pause ( ) ,
( i = t ) ,
e . readableEnded
? o ( { stream : import _node _stream3 . Readable . from ( r ) , type : t } )
: ( r . length > 0 && e . push ( r ) , o ( { stream : e , type : t } ) ) ;
} , 'finish' ) ,
c = _ _name (
e => t => {
s ( t ) && a ( e ) ;
} ,
'foundHead' ,
) ,
u = new import _prism _media4 . default . opus . WebmDemuxer ( ) ;
u . once ( 'error' , noop ) , u . on ( 'head' , c ( StreamType . WebmOpus ) ) ;
const d = new import _prism _media4 . default . opus . OggDemuxer ( ) ;
d . once ( 'error' , noop ) , d . on ( 'head' , c ( StreamType . OggOpus ) ) ;
const p = _ _name ( ( ) => {
i || a ( StreamType . Arbitrary ) ;
} , 'onClose' ) ,
l = _ _name ( s => {
( r = import _node _buffer6 . Buffer . concat ( [ r , s ] ) ) ,
u . write ( s ) ,
d . write ( s ) ,
r . length >= t && ( e . off ( 'data' , l ) , e . pause ( ) , import _node _process . default . nextTick ( p ) ) ;
} , 'onData' ) ;
e . once ( 'error' , n ) , e . on ( 'data' , l ) , e . once ( 'close' , p ) , e . once ( 'end' , p ) ;
2022-05-21 21:02:00 +07:00
} ) ;
}
2023-03-21 18:54:28 +07:00
_ _name ( validateDiscordOpusHead , 'validateDiscordOpusHead' ) , _ _name ( demuxProbe , 'demuxProbe' ) ;
2023-03-21 18:47:11 +07:00
var version2 = '[VI]{{inject}}[/VI]' ;