diff options
Diffstat (limited to 'protocols/Discord/src/voice_client.cpp')
-rw-r--r-- | protocols/Discord/src/voice_client.cpp | 159 |
1 files changed, 21 insertions, 138 deletions
diff --git a/protocols/Discord/src/voice_client.cpp b/protocols/Discord/src/voice_client.cpp index 09e1908007..29b051799f 100644 --- a/protocols/Discord/src/voice_client.cpp +++ b/protocols/Discord/src/voice_client.cpp @@ -32,6 +32,8 @@ CDiscordVoiceCall::CDiscordVoiceCall(CDiscordProto *pOwner) : CDiscordVoiceCall::~CDiscordVoiceCall() { + delete m_ws; + m_timer.StopSafe(); if (m_encoder) { @@ -44,50 +46,17 @@ CDiscordVoiceCall::~CDiscordVoiceCall() m_repacketizer = nullptr; } - if (m_hConn) { - Netlib_CloseHandle(m_hConn); - m_hConn = nullptr; - } - if (m_hBind) { Netlib_CloseHandle(m_hBind); m_hBind = nullptr; } } -bool CDiscordVoiceCall::connect(HNETLIBUSER hServer) -{ - int nLoops = 0; - time_t lastLoopTime = time(0); - - while (true) { - time_t currTime = time(0); - if (currTime - lastLoopTime > 3) - nLoops = 0; - - nLoops++; - if (nLoops > 5) - break; - - lastLoopTime = currTime; - - MHttpHeaders hdrs; - hdrs.AddHeader("Origin", "https://discord.com"); - - NLHR_PTR pReply(WebSocket_Connect(hServer, szEndpoint + "/?encoding=json&v=8", &hdrs)); - if (pReply && pReply->resultCode == 101) { - m_hConn = pReply->nlc; - return true; - } - - SleepEx(5000, TRUE); - } - - return false; -} - void CDiscordVoiceCall::write(int op, JSONNode &d) { + if (m_ws == nullptr) + return; + d.set_name("d"); JSONNode payload; @@ -97,7 +66,12 @@ void CDiscordVoiceCall::write(int op, JSONNode &d) ppro->debugLogA("Voice JSON sent: %s", json.c_str()); mir_cslock lck(m_cs); - WebSocket_SendText(m_hConn, json.c_str()); + m_ws->sendText(json.c_str()); +} + +void JsonWebSocket<CDiscordVoiceCall>::process(const JSONNode &json) +{ + p->process(json); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -186,111 +160,20 @@ void CDiscordProto::VoiceClientThread(void *param) auto *pCall = (CDiscordVoiceCall *)param; debugLogA("Entering voice websocket thread"); - if (!pCall->connect(m_hGatewayNetlibUser)) { + MHttpHeaders hdrs; + hdrs.AddHeader("Origin", "https://discord.com"); + + JsonWebSocket<CDiscordVoiceCall> ws(pCall); + + NLHR_PTR pReply(ws.connect(m_hGatewayNetlibUser, pCall->szEndpoint + "/?encoding=json&v=8", &hdrs)); + if (!pReply || pReply->resultCode != 101) { debugLogA("Voice gateway connection failed, exiting"); return; } - int offset = 0; - MBinBuffer netbuf; - - while (*pCall) { - if (m_bTerminated) - break; - - unsigned char buf[2048]; - int bufSize = Netlib_Recv(pCall->m_hConn, (char *)buf + offset, _countof(buf) - offset, MSG_NODUMP); - if (bufSize == 0) { - debugLogA("Voice gateway connection gracefully closed"); - pCall->m_bTerminated = !m_bTerminated; - break; - } - if (bufSize < 0) { - debugLogA("Voice gateway connection error, exiting"); - break; - } - - WSHeader hdr; - if (!WebSocket_InitHeader(hdr, buf, bufSize)) { - offset += bufSize; - continue; - } - offset = 0; - - // we have some additional data, not only opcode - if ((size_t)bufSize > hdr.headerSize) { - size_t currPacketSize = bufSize - hdr.headerSize; - netbuf.append(buf, bufSize); - while (currPacketSize < hdr.payloadSize) { - int result = Netlib_Recv(pCall->m_hConn, (char *)buf, _countof(buf), MSG_NODUMP); - if (result == 0) { - debugLogA("Voice gateway connection gracefully closed"); - pCall->m_bTerminated = !m_bTerminated; - break; - } - if (result < 0) { - debugLogA("Voice gateway connection error, exiting"); - break; - } - currPacketSize += result; - netbuf.append(buf, result); - } - } - - // read all payloads from the current buffer, one by one - size_t prevSize = 0; - while (true) { - switch (hdr.opCode) { - case 0: // text packet - case 1: // binary packet - case 2: // continuation - if (hdr.bIsFinal) { - // process a packet here - CMStringA szJson((char *)netbuf.data() + hdr.headerSize, (int)hdr.payloadSize); - debugLogA("Voice JSON received:\n%s", szJson.c_str()); - JSONNode root = JSONNode::parse(szJson); - if (root) - pCall->process(root); - } - break; - - case 8: // close - debugLogA("Voice server required to exit"); - pCall->m_bTerminated = true; // simply reconnect, don't exit - break; - - case 9: // ping - debugLogA("ping received"); - Netlib_Send(pCall->m_hConn, (char *)buf + hdr.headerSize, bufSize - int(hdr.headerSize), 0); - break; - } - - if (hdr.bIsFinal) - netbuf.remove(hdr.headerSize + hdr.payloadSize); - - if (netbuf.length() == 0) - break; - - // if we have not enough data for header, continue reading - if (!WebSocket_InitHeader(hdr, netbuf.data(), netbuf.length())) - break; - - // if we have not enough data for data, continue reading - if (hdr.headerSize + hdr.payloadSize > netbuf.length()) - break; - - if (prevSize == netbuf.length()) { - netbuf.remove(prevSize); - debugLogA("dropping current packet, exiting"); - break; - } - - prevSize = netbuf.length(); - } - } - - debugLogA("Exiting voice websocket thread"); - Netlib_CloseHandle(pCall->m_hConn); pCall->m_hConn = 0; + pCall->m_ws = &ws; + ws.run(); + pCall->m_ws = nullptr; } ///////////////////////////////////////////////////////////////////////////////////////// |