Spaces:
Runtime error
Runtime error
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 | |
} |