diff options
Diffstat (limited to 'protocols/Teams/src/teams_trouter.cpp')
-rw-r--r-- | protocols/Teams/src/teams_trouter.cpp | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/protocols/Teams/src/teams_trouter.cpp b/protocols/Teams/src/teams_trouter.cpp index b5eab27768..e602724c68 100644 --- a/protocols/Teams/src/teams_trouter.cpp +++ b/protocols/Teams/src/teams_trouter.cpp @@ -212,6 +212,18 @@ void WebSocket<CTeamsProto>::process(const uint8_t *buf, size_t cbLen) p->TRouterProcess(payload); } +static const char* skip3colons(const char *str) +{ + int nColons = 3; + for (const char *p = str; *p; p++) { + if (*p == ':') { + if (--nColons == 0) + return p + 1; + } + } + return str; +} + void CTeamsProto::TRouterProcess(const char *str) { switch (*str) { @@ -220,5 +232,136 @@ void CTeamsProto::TRouterProcess(const char *str) TRouterSendActive(true); TRouterRegister(); break; + + case '3': + if (auto packet = JSONNode::parse(skip3colons(str))) { + std::string szBody(packet["body"].as_string()); + auto message = JSONNode::parse(szBody.c_str()); + if (message) { + Netlib_Logf(m_hTrouterNetlibUser, "Got event:\n%s", message.write_formatted().c_str()); + + const JSONNode &resource = message["resource"]; + + std::string resourceType = message["resourceType"].as_string(); + if (resourceType == "NewMessage") + ProcessNewMessage(resource); + else if (resourceType == "UserPresence") + ProcessUserPresence(resource); + else if (resourceType == "EndpointPresence") + ProcessEndpointPresence(resource); + else if (resourceType == "ConversationUpdate") + ProcessConversationUpdate(resource); + else if (resourceType == "ThreadUpdate") + ProcessThreadUpdate(resource); + } + } + break; + + case '5': + if (auto root = JSONNode::parse(skip3colons(str))) { + std::string szName(root["name"].as_string()); + ProcessServerMessage(szName, root["args"]); + } + break; } } + +void CTeamsProto::ProcessEndpointPresence(const JSONNode &node) +{ + debugLogA(__FUNCTION__); + std::string selfLink = node["selfLink"].as_string(); + CMStringA skypename(UrlToSkypeId(selfLink.c_str())); + + MCONTACT hContact = FindContact(skypename); + if (hContact == NULL) + return; + + const JSONNode &publicInfo = node["publicInfo"]; + const JSONNode &privateInfo = node["privateInfo"]; + CMStringA MirVer; + if (publicInfo) { + std::string skypeNameVersion = publicInfo["skypeNameVersion"].as_string(); + std::string version = publicInfo["version"].as_string(); + std::string typ = publicInfo["typ"].as_string(); + int iTyp = atoi(typ.c_str()); + switch (iTyp) { + case 0: + case 1: + MirVer.Append("Skype (Web) " + ParseUrl(version.c_str(), "/")); + break; + case 10: + MirVer.Append("Skype (XBOX) " + ParseUrl(skypeNameVersion.c_str(), "/")); + break; + case 17: + MirVer.Append("Skype (Android) " + ParseUrl(skypeNameVersion.c_str(), "/")); + break; + case 16: + MirVer.Append("Skype (iOS) " + ParseUrl(skypeNameVersion.c_str(), "/")); + break; + case 12: + MirVer.Append("Skype (WinRT) " + ParseUrl(skypeNameVersion.c_str(), "/")); + break; + case 15: + MirVer.Append("Skype (WP) " + ParseUrl(skypeNameVersion.c_str(), "/")); + break; + case 13: + MirVer.Append("Skype (OSX) " + ParseUrl(skypeNameVersion.c_str(), "/")); + break; + case 11: + MirVer.Append("Skype (Windows) " + ParseUrl(skypeNameVersion.c_str(), "/")); + break; + case 14: + MirVer.Append("Skype (Linux) " + ParseUrl(skypeNameVersion.c_str(), "/")); + break; + case 125: + MirVer.AppendFormat("Miranda NG Skype %s", version.c_str()); + break; + default: + MirVer.Append("Skype (Unknown)"); + } + } + + if (privateInfo != NULL) { + std::string epname = privateInfo["epname"].as_string(); + if (!epname.empty()) + MirVer.AppendFormat(" [%s]", epname.c_str()); + } + + setString(hContact, "MirVer", MirVer); +} + +void CTeamsProto::ProcessUserPresence(const JSONNode &node) +{ + debugLogA(__FUNCTION__); + + std::string selfLink = node["selfLink"].as_string(); + std::string status = node["availability"].as_string(); + CMStringA skypename = UrlToSkypeId(selfLink.c_str()); + + if (!skypename.IsEmpty()) { + if (IsMe(skypename)) { + int iNewStatus = SkypeToMirandaStatus(status.c_str()); + if (iNewStatus == ID_STATUS_OFFLINE) return; + int old_status = m_iStatus; + m_iDesiredStatus = iNewStatus; + m_iStatus = iNewStatus; + if (old_status != iNewStatus) + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, iNewStatus); + } + else { + MCONTACT hContact = FindContact(skypename); + if (hContact != NULL) + SetContactStatus(hContact, SkypeToMirandaStatus(status.c_str())); + } + } +} + +void CTeamsProto::ProcessServerMessage(const std::string &szName, const JSONNode&) +{ + if (szName == "trouter.message_loss") { + TRouterRegister("TeamsCDLWebWorker", "TeamsCDLWebWorker_1.9", m_szTrouterSurl); + } +} + +void CTeamsProto::ProcessConversationUpdate(const JSONNode &) {} +void CTeamsProto::ProcessThreadUpdate(const JSONNode &) {} |