|
import { debugLog } from '../utils.js' |
|
import config from '../../config.js' |
|
|
|
import voiceUtils from '../voice/utils.js' |
|
import discordVoice from '@performanc/voice' |
|
import prism from 'prism-media' |
|
|
|
const Connections = {} |
|
|
|
function setupConnection(ws, req, parsedClientName) { |
|
const userId = req.headers['user-id'] |
|
const guildId = req.headers['guild-id'] |
|
|
|
ws.on('close', (code, reason) => { |
|
debugLog('disconnectCD', 3, { ...parsedClientName, code, reason, guildId }) |
|
|
|
delete Connections[userId] |
|
}) |
|
|
|
ws.on('error', (err) => { |
|
debugLog('disconnectCD', 3, { ...parsedClientName, error: `Error: ${err.message}`, guildId }) |
|
|
|
delete Connections[userId] |
|
}) |
|
|
|
Connections[userId] = { |
|
ws, |
|
guildId |
|
} |
|
} |
|
|
|
function handleStartSpeaking(ssrc, userId, guildId) { |
|
const opusStream = discordVoice.getSpeakStream(ssrc) |
|
const stream = new voiceUtils.NodeLinkStream(opusStream, config.voiceReceive.type === 'pcm' ? [ new prism.opus.Decoder({ rate: 48000, channels: 2, frameSize: 960 }) ] : []) |
|
let timeout = null |
|
|
|
const startSpeakingResponse = JSON.stringify({ |
|
op: 'speak', |
|
type: 'startSpeakingEvent', |
|
data: { |
|
userId, |
|
guildId |
|
} |
|
}) |
|
|
|
Object.keys(Connections).forEach((botId) => { |
|
if (Connections[botId].guildId !== guildId) return; |
|
|
|
Connections[botId].ws.send(startSpeakingResponse) |
|
}) |
|
|
|
let buffer = [] |
|
stream.on('data', (chunk) => { |
|
if (timeout) { |
|
clearTimeout(timeout) |
|
timeout = null |
|
} |
|
|
|
if (Object.keys(Connections).length === 0) { |
|
stream.destroy() |
|
buffer = null |
|
|
|
return; |
|
} |
|
|
|
buffer.push(chunk) |
|
}) |
|
|
|
stream.on('end', () => { |
|
let i = 0 |
|
|
|
const connectionsArray = Object.keys(Connections) |
|
|
|
if (connectionsArray.length === 0) { |
|
buffer = [] |
|
|
|
return; |
|
} |
|
|
|
timeout = setTimeout(() => { |
|
const endSpeakingResponse = JSON.stringify({ |
|
op: 'speak', |
|
type: 'endSpeakingEvent', |
|
data: { |
|
userId, |
|
guildId, |
|
data: Buffer.concat(buffer).toString('base64'), |
|
type: config.voiceReceive.type |
|
} |
|
}) |
|
|
|
connectionsArray.forEach((botId) => { |
|
if (Connections[botId].guildId !== guildId) return; |
|
|
|
Connections[botId].ws.send(endSpeakingResponse) |
|
|
|
i++ |
|
}) |
|
|
|
buffer = [] |
|
|
|
debugLog('sentDataCD', 3, { clientsAmount: i, guildId }) |
|
}, config.voiceReceive.timeout) |
|
}) |
|
} |
|
|
|
export default { |
|
setupConnection, |
|
handleStartSpeaking |
|
} |