summaryrefslogtreecommitdiff
path: root/protocols/Discord/src/voice_client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Discord/src/voice_client.cpp')
-rw-r--r--protocols/Discord/src/voice_client.cpp159
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;
}
/////////////////////////////////////////////////////////////////////////////////////////