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 }