summaryrefslogtreecommitdiff
path: root/protocols/Teams/src
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Teams/src')
-rw-r--r--protocols/Teams/src/main.cpp17
-rw-r--r--protocols/Teams/src/requests/capabilities.h2
-rw-r--r--protocols/Teams/src/requests/poll.h2
-rw-r--r--protocols/Teams/src/stdafx.cxx2
-rw-r--r--protocols/Teams/src/teams_avatars.cpp4
-rw-r--r--protocols/Teams/src/teams_chatrooms.cpp6
-rw-r--r--protocols/Teams/src/teams_contacts.cpp6
-rw-r--r--protocols/Teams/src/teams_endpoint.cpp19
-rw-r--r--protocols/Teams/src/teams_files.cpp19
-rw-r--r--protocols/Teams/src/teams_history.cpp6
-rw-r--r--protocols/Teams/src/teams_http.cpp2
-rw-r--r--protocols/Teams/src/teams_login.cpp4
-rw-r--r--protocols/Teams/src/teams_menus.cpp2
-rw-r--r--protocols/Teams/src/teams_messages.cpp2
-rw-r--r--protocols/Teams/src/teams_mood.cpp2
-rw-r--r--protocols/Teams/src/teams_options.cpp2
-rw-r--r--protocols/Teams/src/teams_polling.cpp39
-rw-r--r--protocols/Teams/src/teams_popups.cpp17
-rw-r--r--protocols/Teams/src/teams_profile.cpp4
-rw-r--r--protocols/Teams/src/teams_proto.cpp19
-rw-r--r--protocols/Teams/src/teams_proto.h56
-rw-r--r--protocols/Teams/src/teams_search.cpp4
-rw-r--r--protocols/Teams/src/teams_trouter.cpp224
-rw-r--r--protocols/Teams/src/teams_utils.cpp2
-rw-r--r--protocols/Teams/src/teams_utils.h4
25 files changed, 360 insertions, 106 deletions
diff --git a/protocols/Teams/src/main.cpp b/protocols/Teams/src/main.cpp
index d2ac241040..07778b2405 100644
--- a/protocols/Teams/src/main.cpp
+++ b/protocols/Teams/src/main.cpp
@@ -1,3 +1,20 @@
+/*
+Copyright (C) 2025 Miranda NG team (https://miranda-ng.org)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
#include "stdafx.h"
CMPlugin g_plugin;
diff --git a/protocols/Teams/src/requests/capabilities.h b/protocols/Teams/src/requests/capabilities.h
index 566d946e3e..b9785a2a92 100644
--- a/protocols/Teams/src/requests/capabilities.h
+++ b/protocols/Teams/src/requests/capabilities.h
@@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
struct SendCapabilitiesRequest : public AsyncHttpRequest
{
SendCapabilitiesRequest(const char *hostname, CTeamsProto *ppro) :
- AsyncHttpRequest(REQUEST_PUT, HOST_DEFAULT, "/users/ME/endpoints/" + mir_urlEncode(ppro->m_szId) + "/presenceDocs/messagingService", &CTeamsProto::OnCapabilitiesSended)
+ AsyncHttpRequest(REQUEST_PUT, HOST_DEFAULT, "/users/ME/endpoints/" + mir_urlEncode(ppro->m_szEndpoint) + "/presenceDocs/messagingService", &CTeamsProto::OnCapabilitiesSended)
{
JSONNode privateInfo; privateInfo.set_name("privateInfo");
privateInfo << CHAR_PARAM("epname", hostname);
diff --git a/protocols/Teams/src/requests/poll.h b/protocols/Teams/src/requests/poll.h
index b2573a43e2..008873cd14 100644
--- a/protocols/Teams/src/requests/poll.h
+++ b/protocols/Teams/src/requests/poll.h
@@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
struct PollRequest : public AsyncHttpRequest
{
PollRequest(CTeamsProto *ppro) :
- AsyncHttpRequest(REQUEST_POST, HOST_DEFAULT, "/users/ME/endpoints/" + mir_urlEncode(ppro->m_szId) + "/subscriptions/0/poll")
+ AsyncHttpRequest(REQUEST_POST, HOST_DEFAULT, "/users/ME/endpoints/" + mir_urlEncode(ppro->m_szEndpoint) + "/subscriptions/0/poll")
{
flags |= NLHRF_PERSISTENT;
timeout = 120000;
diff --git a/protocols/Teams/src/stdafx.cxx b/protocols/Teams/src/stdafx.cxx
index 4a1e1f0e70..b64bcca703 100644
--- a/protocols/Teams/src/stdafx.cxx
+++ b/protocols/Teams/src/stdafx.cxx
@@ -1,5 +1,5 @@
/*
-Copyright (C) 2012-25 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2025 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/protocols/Teams/src/teams_avatars.cpp b/protocols/Teams/src/teams_avatars.cpp
index 6bbac21d04..533aa62d08 100644
--- a/protocols/Teams/src/teams_avatars.cpp
+++ b/protocols/Teams/src/teams_avatars.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2015-25 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -191,7 +191,7 @@ struct SetAvatarRequest : public AsyncHttpRequest
void CTeamsProto::OnSentAvatar(MHttpResponse *response, AsyncHttpRequest*)
{
- SkypeReply root(response);
+ TeamsReply root(response);
if (root.error())
return;
}
diff --git a/protocols/Teams/src/teams_chatrooms.cpp b/protocols/Teams/src/teams_chatrooms.cpp
index 42c5f269ce..e4012e376f 100644
--- a/protocols/Teams/src/teams_chatrooms.cpp
+++ b/protocols/Teams/src/teams_chatrooms.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2015-25 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -353,7 +353,7 @@ void CTeamsProto::SendChatMessage(SESSION_INFO *si, const wchar_t *tszMessage)
void CTeamsProto::OnGetChatMembers(MHttpResponse *response, AsyncHttpRequest *pRequest)
{
- SkypeReply reply(response);
+ TeamsReply reply(response);
if (reply.error())
return;
@@ -375,7 +375,7 @@ void CTeamsProto::OnGetChatMembers(MHttpResponse *response, AsyncHttpRequest *pR
void CTeamsProto::OnGetChatInfo(MHttpResponse *response, AsyncHttpRequest*)
{
- SkypeReply reply(response);
+ TeamsReply reply(response);
if (reply.error())
return;
diff --git a/protocols/Teams/src/teams_contacts.cpp b/protocols/Teams/src/teams_contacts.cpp
index b8f94be72d..90fde17b50 100644
--- a/protocols/Teams/src/teams_contacts.cpp
+++ b/protocols/Teams/src/teams_contacts.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2015-25 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -102,7 +102,7 @@ MCONTACT CTeamsProto::AddContact(const char *skypeId, const char *nick, bool isT
void CTeamsProto::LoadContactsAuth(MHttpResponse *response, AsyncHttpRequest*)
{
- SkypeReply reply(response);
+ TeamsReply reply(response);
if (reply.error())
return;
@@ -140,7 +140,7 @@ void CTeamsProto::LoadContactsAuth(MHttpResponse *response, AsyncHttpRequest*)
void CTeamsProto::LoadContactList(MHttpResponse *response, AsyncHttpRequest*)
{
- SkypeReply reply(response);
+ TeamsReply reply(response);
if (reply.error())
return;
diff --git a/protocols/Teams/src/teams_endpoint.cpp b/protocols/Teams/src/teams_endpoint.cpp
index 39b6958abb..ead0857bf0 100644
--- a/protocols/Teams/src/teams_endpoint.cpp
+++ b/protocols/Teams/src/teams_endpoint.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2015-25 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -17,15 +17,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
-void CTeamsProto::ProcessTimer()
-{
- if (!IsOnline())
- return;
-
- PushRequest(new GetContactListRequest());
- SendPresence();
-}
-
void CTeamsProto::SendCreateEndpoint()
{
auto *pReq = new AsyncHttpRequest(REQUEST_POST, HOST_DEFAULT, "/users/ME/endpoints", &CTeamsProto::OnEndpointCreated);
@@ -83,19 +74,17 @@ void CTeamsProto::OnEndpointCreated(MHttpResponse *response, AsyncHttpRequest*)
if (name == "registrationToken")
m_szToken = val.Detach();
else if (name == "endpointId")
- m_szId = val.Detach();
+ m_szEndpoint = val.Detach();
}
}
- if (m_szId && m_hPollingThread == nullptr)
- ForkThread(&CTeamsProto::PollingThread);
-
+ StartTrouter();
PushRequest(new CreateSubscriptionsRequest());
}
void CTeamsProto::OnEndpointDeleted(MHttpResponse *, AsyncHttpRequest *)
{
- m_szId = nullptr;
+ m_szEndpoint = nullptr;
m_szToken = nullptr;
}
diff --git a/protocols/Teams/src/teams_files.cpp b/protocols/Teams/src/teams_files.cpp
index a6e7d07087..4efb89a662 100644
--- a/protocols/Teams/src/teams_files.cpp
+++ b/protocols/Teams/src/teams_files.cpp
@@ -1,3 +1,20 @@
+/*
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
#include "stdafx.h"
////////////////////////////////////////////////////////////////////////////////////////
@@ -48,7 +65,7 @@ void CTeamsProto::ReceiveFileThread(void *param)
nlhr.AddHeader("Cookie", szCookie);
NLHR_PTR response(Netlib_HttpTransaction(m_hNetlibUser, &nlhr));
if (response) {
- SkypeReply reply(response);
+ TeamsReply reply(response);
if (!reply.error()) {
auto &root = reply.data();
if (root["content_state"].as_string() == "ready")
diff --git a/protocols/Teams/src/teams_history.cpp b/protocols/Teams/src/teams_history.cpp
index eb6a9ca39f..a2502a0eb3 100644
--- a/protocols/Teams/src/teams_history.cpp
+++ b/protocols/Teams/src/teams_history.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2015-25 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
void CTeamsProto::OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest *pRequest)
{
- SkypeReply reply(response);
+ TeamsReply reply(response);
if (reply.error())
return;
@@ -96,7 +96,7 @@ INT_PTR CTeamsProto::SvcLoadHistory(WPARAM hContact, LPARAM)
void CTeamsProto::OnSyncConversations(MHttpResponse *response, AsyncHttpRequest*)
{
- SkypeReply reply(response);
+ TeamsReply reply(response);
if (reply.error())
return;
diff --git a/protocols/Teams/src/teams_http.cpp b/protocols/Teams/src/teams_http.cpp
index 18e3067119..cc448b3a1d 100644
--- a/protocols/Teams/src/teams_http.cpp
+++ b/protocols/Teams/src/teams_http.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (C) 2012-25 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/protocols/Teams/src/teams_login.cpp b/protocols/Teams/src/teams_login.cpp
index 9e4f2a966a..b3c800d13a 100644
--- a/protocols/Teams/src/teams_login.cpp
+++ b/protocols/Teams/src/teams_login.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (C) 2012-25 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -40,8 +40,6 @@ void CTeamsProto::LoggedIn()
m_iStatus = m_iDesiredStatus;
ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
- m_impl.m_heartBeat.StartSafe(600 * 1000);
-
SendCreateEndpoint();
}
diff --git a/protocols/Teams/src/teams_menus.cpp b/protocols/Teams/src/teams_menus.cpp
index 9238c33946..8605e30a52 100644
--- a/protocols/Teams/src/teams_menus.cpp
+++ b/protocols/Teams/src/teams_menus.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2015-25 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/protocols/Teams/src/teams_messages.cpp b/protocols/Teams/src/teams_messages.cpp
index e55b83816c..c660ee0c60 100644
--- a/protocols/Teams/src/teams_messages.cpp
+++ b/protocols/Teams/src/teams_messages.cpp
@@ -154,6 +154,7 @@ LBL_Deleted:
return true;
}
+/*
void CTeamsProto::ProcessNewMessage(const JSONNode &node)
{
int iUserType;
@@ -199,6 +200,7 @@ void CTeamsProto::ProcessNewMessage(const JSONNode &node)
ProtoChainRecvMsg(hContact, dbei);
}
}
+*/
void CTeamsProto::OnMarkRead(MCONTACT hContact, MEVENT hDbEvent)
{
diff --git a/protocols/Teams/src/teams_mood.cpp b/protocols/Teams/src/teams_mood.cpp
index 66a2b15444..fb366ac97a 100644
--- a/protocols/Teams/src/teams_mood.cpp
+++ b/protocols/Teams/src/teams_mood.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (C) 2012-25 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/protocols/Teams/src/teams_options.cpp b/protocols/Teams/src/teams_options.cpp
index 040583ad85..693af22fb1 100644
--- a/protocols/Teams/src/teams_options.cpp
+++ b/protocols/Teams/src/teams_options.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (C) 2012-25 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/protocols/Teams/src/teams_polling.cpp b/protocols/Teams/src/teams_polling.cpp
index ca59ac8f6a..11a918034e 100644
--- a/protocols/Teams/src/teams_polling.cpp
+++ b/protocols/Teams/src/teams_polling.cpp
@@ -17,42 +17,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
-void CTeamsProto::PollingThread(void *)
-{
- debugLogA(__FUNCTION__ ": entering");
-
- m_iPollingId = -1;
-
- while (true) {
- if (m_isTerminated || m_szId == nullptr)
- break;
-
- std::unique_ptr<PollRequest> request(new PollRequest(this));
- request->nlc = m_hPollingConn;
- NLHR_PTR response(DoSend(request.get()));
- if (m_isTerminated || m_szId == nullptr)
- break;
-
- if (response == nullptr || response->resultCode != 200) {
- m_hPollingConn = nullptr;
- continue;
- }
-
- m_hPollingConn = response->nlc;
- if (!response->body.IsEmpty())
- ParsePollData(response->body);
- }
-
- if (!m_isTerminated) {
- debugLogA(__FUNCTION__ ": unexpected termination; switching protocol to offline");
- SetStatus(ID_STATUS_OFFLINE);
- }
-
- m_hPollingConn = nullptr;
- m_hPollingThread = nullptr;
- debugLogA(__FUNCTION__ ": leaving");
-}
-
void CTeamsProto::ParsePollData(const char *szData)
{
debugLogA(__FUNCTION__);
@@ -171,6 +135,3 @@ void CTeamsProto::ProcessUserPresence(const JSONNode &node)
}
}
}
-
-void CTeamsProto::ProcessConversationUpdate(const JSONNode &) {}
-void CTeamsProto::ProcessThreadUpdate(const JSONNode &) {}
diff --git a/protocols/Teams/src/teams_popups.cpp b/protocols/Teams/src/teams_popups.cpp
index efac8c26f9..59cca9e937 100644
--- a/protocols/Teams/src/teams_popups.cpp
+++ b/protocols/Teams/src/teams_popups.cpp
@@ -1,3 +1,20 @@
+/*
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
#include "stdafx.h"
void CTeamsProto::InitPopups()
diff --git a/protocols/Teams/src/teams_profile.cpp b/protocols/Teams/src/teams_profile.cpp
index a26d88b1fe..29a04937c6 100644
--- a/protocols/Teams/src/teams_profile.cpp
+++ b/protocols/Teams/src/teams_profile.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2015-25 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -105,7 +105,7 @@ void CTeamsProto::LoadProfile(MHttpResponse *response, AsyncHttpRequest *pReques
{
MCONTACT hContact = (DWORD_PTR)pRequest->pUserInfo;
- SkypeReply reply(response);
+ TeamsReply reply(response);
if (reply.error()) {
ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, 0);
return;
diff --git a/protocols/Teams/src/teams_proto.cpp b/protocols/Teams/src/teams_proto.cpp
index 28dcf637ad..d452c09781 100644
--- a/protocols/Teams/src/teams_proto.cpp
+++ b/protocols/Teams/src/teams_proto.cpp
@@ -1,3 +1,20 @@
+/*
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
#include "stdafx.h"
CTeamsProto::CTeamsProto(const char *protoName, const wchar_t *userName) :
@@ -83,6 +100,7 @@ void CTeamsProto::OnModulesLoaded()
void CTeamsProto::OnShutdown()
{
StopQueue();
+ StopTrouter();
}
INT_PTR CTeamsProto::GetCaps(int type, MCONTACT)
@@ -203,6 +221,7 @@ int CTeamsProto::SetStatus(int iNewStatus)
if (iNewStatus == ID_STATUS_OFFLINE) {
m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
StopQueue();
+ StopTrouter();
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, ID_STATUS_OFFLINE);
diff --git a/protocols/Teams/src/teams_proto.h b/protocols/Teams/src/teams_proto.h
index 850aae8808..c836053a21 100644
--- a/protocols/Teams/src/teams_proto.h
+++ b/protocols/Teams/src/teams_proto.h
@@ -1,4 +1,8 @@
#define TEAMS_CLIENT_ID "8ec6bc83-69c8-4392-8f08-b3c986009232"
+#define TEAMS_CLIENTINFO_NAME "skypeteams"
+#define TEAMS_CLIENTINFO_VERSION "49/24062722442"
+
+#define TEAMS_USER_AGENT "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0 Teams/24165.1410.2974.6689/49"
#define DBKEY_ID "id"
#define DBKEY_GROUP "DefaultGroup"
@@ -39,7 +43,7 @@ class CTeamsProto : public PROTO<CTeamsProto>
CTimer m_heartBeat, m_loginPoll;
void OnHeartBeat(CTimer *)
{
- m_proto.ProcessTimer();
+ m_proto.TRouterSendJson("ping");
}
void OnLoginPoll(CTimer *)
{
@@ -141,12 +145,6 @@ public:
void __cdecl SearchBasicThread(void *param);
//////////////////////////////////////////////////////////////////////////////////////
- // services
-
- static INT_PTR __cdecl SvcEventGetIcon(WPARAM, LPARAM);
- static INT_PTR __cdecl SvcGetEventText(WPARAM, LPARAM);
-
- //////////////////////////////////////////////////////////////////////////////////////
// settings
CMOption<bool> m_bAutoHistorySync;
@@ -164,7 +162,7 @@ public:
// other data
int m_iPollingId, m_iMessageId = 1;
- ptrA m_szToken, m_szId, m_szOwnSkypeId;
+ ptrA m_szToken, m_szEndpoint, m_szOwnSkypeId;
CMStringA m_szSkypename, m_szMyname, m_szSkypeToken;
MCONTACT m_hMyContact;
@@ -211,6 +209,7 @@ public:
void LoadProfile(MHttpResponse *response, AsyncHttpRequest *pRequest);
static INT_PTR __cdecl GlobalParseSkypeUriService(WPARAM, LPARAM lParam);
+
private:
bool m_bHistorySynced;
@@ -224,9 +223,6 @@ private:
mir_cs messageSyncLock;
mir_cs m_StatusLock;
- HANDLE m_hPollingThread;
- HNETLIBCONN m_hPollingConn;
-
// avatars
void SetAvatarUrl(MCONTACT hContact, const CMStringW &tszUrl);
bool ReceiveAvatar(MCONTACT hContact);
@@ -303,18 +299,8 @@ private:
void SetChatStatus(MCONTACT hContact, int iStatus);
- // polling
- void __cdecl PollingThread(void*);
-
bool ParseMessage(const JSONNode &node, DB::EventInfo &dbei);
void ParsePollData(const char*);
-
- void ProcessNewMessage(const JSONNode &node);
- void ProcessUserPresence(const JSONNode &node);
- void ProcessThreadUpdate(const JSONNode &node);
- void ProcessEndpointPresence(const JSONNode &node);
- void ProcessConversationUpdate(const JSONNode &node);
-
// utils
template <typename T>
__inline static void FreeList(const LIST<T> &lst)
@@ -346,8 +332,6 @@ private:
static LRESULT CALLBACK PopupDlgProcCall(HWND hPopup, UINT uMsg, WPARAM wParam, LPARAM lParam);
- void ProcessTimer();
-
void SetString(MCONTACT hContact, const char *pszSetting, const JSONNode &node);
CMStringW ChangeTopicForm();
@@ -369,6 +353,32 @@ private:
auto *proto = CMPlugin::getInstance((MCONTACT)wParam);
return proto ? (proto->*Service)(wParam, lParam) : 0;
}
+
+ // trouter
+public:
+ void TRouterProcess(const char *str);
+
+private:
+ CMStringA m_szTrouterUrl, m_szTrouterSurl;
+ WebSocket<CTeamsProto> *m_ws;
+ MHttpHeaders m_connectParams;
+ int iCommandId;
+
+ void __cdecl GatewayThread(void *);
+
+ void TRouterSendJson(const char *szName, const JSONNode *node = 0);
+ void TRouterSendJson(const JSONNode &node);
+
+ void TRouterSendAuthentication();
+ void TRouterSendActive(bool);
+ void TRouterRegister();
+ void TRouterRegister(const char *pszAppId, const char *pszKey, const char *pszPath);
+
+ void StartTrouter();
+ void StopTrouter();
+
+ void OnTrouterInfo(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnTrouterSession(MHttpResponse *response, AsyncHttpRequest *pRequest);
};
typedef CProtoDlgBase<CTeamsProto> CTeamsDlgBase;
diff --git a/protocols/Teams/src/teams_search.cpp b/protocols/Teams/src/teams_search.cpp
index a88daaae47..5cceab3c3f 100644
--- a/protocols/Teams/src/teams_search.cpp
+++ b/protocols/Teams/src/teams_search.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2015-25 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -34,7 +34,7 @@ void CTeamsProto::OnSearch(MHttpResponse *response, AsyncHttpRequest*)
{
debugLogA(__FUNCTION__);
- SkypeReply reply(response);
+ TeamsReply reply(response);
if (reply.error()) {
ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)1, 0);
return;
diff --git a/protocols/Teams/src/teams_trouter.cpp b/protocols/Teams/src/teams_trouter.cpp
new file mode 100644
index 0000000000..323c8f63af
--- /dev/null
+++ b/protocols/Teams/src/teams_trouter.cpp
@@ -0,0 +1,224 @@
+/*
+Copyright (C) 2025 Miranda NG team (https://miranda-ng.org)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdafx.h"
+
+#define TEAMS_TROUTER_TTL 86400
+#define TEAMS_TROUTER_TCCV "2024.23.01.2"
+
+void CTeamsProto::OnTrouterSession(MHttpResponse *response, AsyncHttpRequest *pRequest)
+{
+ if (response->resultCode != 200) {
+ LoginError();
+ return;
+ }
+
+ int iStart = 0;
+ CMStringA szId = response->body.Tokenize(":", iStart);
+ m_szTrouterUrl = pRequest->m_szUrl;
+ m_szTrouterUrl.Replace("socket.io/1/", "socket.io/1/websocket/" + szId + "/");
+ ForkThread(&CTeamsProto::GatewayThread);
+}
+
+void CTeamsProto::OnTrouterInfo(MHttpResponse *response, AsyncHttpRequest *)
+{
+ TeamsReply reply(response);
+ if (reply.error()) {
+ LoginError();
+ return;
+ }
+
+ auto &root = reply.data();
+ m_szTrouterSurl = root["surl"].as_mstring();
+ CMStringA ccid = root["ccid"].as_mstring();
+ CMStringA szUrl = root["socketio"].as_mstring();
+ szUrl += "socket.io/1/";
+
+ auto *pReq = new AsyncHttpRequest(REQUEST_GET, HOST_OTHER, szUrl, &CTeamsProto::OnTrouterSession);
+ pReq << CHAR_PARAM("v", "v4");
+
+ m_connectParams.destroy();
+ for (auto &it : root["connectparams"]) {
+ m_connectParams.AddHeader(it.name(), it.as_string().c_str());
+ pReq << CHAR_PARAM(it.name(), it.as_string().c_str());
+ }
+
+ pReq << CHAR_PARAM("tc", "{\"cv\":\"" TEAMS_TROUTER_TCCV "\",\"ua\":\"TeamsCDL\",\"hr\":\"\",\"v\":\"" TEAMS_CLIENTINFO_VERSION "\"}")
+ << CHAR_PARAM("con_num", "1234567890123_1") << CHAR_PARAM("epid", m_szEndpoint) << BOOL_PARAM("auth", true) << INT_PARAM("timeout", 40);
+ if (!ccid.IsEmpty())
+ pReq << CHAR_PARAM("ccid", ccid);
+ PushRequest(pReq);
+}
+
+void CTeamsProto::StartTrouter()
+{
+ auto *pReq = new AsyncHttpRequest(REQUEST_POST, HOST_OTHER, "https://go.trouter.teams.microsoft.com/v4/a", &CTeamsProto::OnTrouterInfo);
+ pReq->m_szUrl.AppendFormat("?epid=%s", m_szEndpoint.get());
+ pReq->AddHeader("x-skypetoken", m_szSkypeToken);
+ pReq->flags |= NLHRF_NODUMPHEADERS;
+ PushRequest(pReq);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CTeamsProto::StopTrouter()
+{
+ m_impl.m_heartBeat.StopSafe();
+
+ if (m_ws) {
+ m_ws->terminate();
+ m_ws = nullptr;
+ }
+}
+
+void CTeamsProto::GatewayThread(void *)
+{
+ m_ws = nullptr;
+
+ MHttpHeaders headers;
+ headers.AddHeader("x-skypetoken", m_szSkypeToken);
+ headers.AddHeader("User-Agent", TEAMS_USER_AGENT);
+
+ WebSocket<CTeamsProto> ws(this);
+ NLHR_PTR pReply(ws.connect(m_hNetlibUser, m_szTrouterUrl, &headers));
+ if (pReply) {
+ if (pReply->resultCode == 101) {
+ m_ws = &ws;
+
+ iCommandId = 1;
+ m_impl.m_heartBeat.StartSafe(30000);
+
+ debugLogA("Websocket connection succeeded");
+ ws.run();
+ }
+ else debugLogA("websocket connection failed: %d", pReply->resultCode);
+ }
+ else debugLogA("websocket connection failed");
+
+ StopTrouter();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// TRouter send
+
+void CTeamsProto::TRouterSendJson(const JSONNode &node)
+{
+ std::string szJson = "5:::" + node.write();
+ if (m_ws) {
+ m_ws->sendText(szJson.c_str());
+ }
+}
+
+void CTeamsProto::TRouterSendJson(const char *szName, const JSONNode *node)
+{
+ JSONNode payload, args(JSON_ARRAY);
+ payload << CHAR_PARAM("name", szName);
+ if (node) {
+ args.set_name("args");
+ args << *node;
+ payload << args;
+ }
+
+ std::string szJson = payload.write();
+ if (m_ws)
+ m_ws->sendText(szJson.c_str());
+}
+
+void CTeamsProto::TRouterSendAuthentication()
+{
+ JSONNode headers, params, payload;
+
+ headers.set_name("headers");
+ headers << CHAR_PARAM("X-Ms-Test-User", "False") << CHAR_PARAM("Authorization", "Bearer " + m_szAccessToken)
+ << CHAR_PARAM("X-MS-Migration", "True");
+
+ params.set_name("connectparams");
+ for (auto &it : m_connectParams)
+ params << CHAR_PARAM(it->szName, it->szValue);
+
+ payload << headers << params;
+ TRouterSendJson(payload);
+}
+
+static char szSuffix[4] = { 'A', 'g', 'Q', 'w' };
+
+void CTeamsProto::TRouterSendActive(bool bActive)
+{
+ CMStringA cv;
+ srand(time(0));
+ for (int i = 0; i < 21; i++)
+ cv.AppendChar('a' + rand() % 26);
+ cv.AppendChar(szSuffix[rand() % 4]);
+ cv += ".0.1";
+
+ JSONNode payload;
+ payload << CHAR_PARAM("state", bActive ? "active" : "inactive") << CHAR_PARAM("cv", cv);
+ TRouterSendJson("user.activity", &payload);
+}
+
+void CTeamsProto::TRouterRegister()
+{
+ TRouterRegister("NextGenCalling", "DesktopNgc_2.3:SkypeNgc", m_szTrouterSurl + "NGCallManagerWin");
+ TRouterRegister("SkypeSpacesWeb", "SkypeSpacesWeb_2.3", m_szTrouterSurl + "SkypeSpacesWeb");
+ TRouterRegister("TeamsCDLWebWorker", "TeamsCDLWebWorker_1.9", m_szTrouterSurl);
+}
+
+void CTeamsProto::TRouterRegister(const char *pszAppId, const char *pszKey, const char *pszPath)
+{
+ JSONNode descr, reg, obj, trouter(JSON_ARRAY), transports;
+ descr.set_name("clientDescription");
+ descr << CHAR_PARAM("appId", pszAppId) << CHAR_PARAM("aesKey", "") << CHAR_PARAM("languageId", "en-US")
+ << CHAR_PARAM("platform", "edge") << CHAR_PARAM("templateKey", pszKey) << CHAR_PARAM("platformUIVersion", TEAMS_CLIENTINFO_VERSION)
+ << CHAR_PARAM("productContext", "TFL");
+
+ obj << CHAR_PARAM("context", "") << CHAR_PARAM("path", pszPath) << INT_PARAM("ttl", TEAMS_TROUTER_TTL);
+ trouter.set_name("TROUTER"); trouter << obj;
+ transports.set_name("transports");
+
+ reg.set_name("registration");
+ reg << descr << CHAR_PARAM("registrationId", m_szEndpoint) << CHAR_PARAM("nodeId", "") << transports;
+
+ auto *pReq = new AsyncHttpRequest(REQUEST_POST, HOST_OTHER, "https://edge.skype.com/registrar/prod/v2/registrations");
+ pReq->flags |= NLHRF_NODUMPHEADERS;
+ pReq->AddHeader("Content-Type", "application/json");
+ pReq->AddHeader("X-Skypetoken", m_szSkypeToken);
+ pReq->AddHeader("Authorization", "Bearer " + m_szAccessToken);
+ pReq->m_szParam = mir_urlEncode(reg.write().c_str());
+ PushRequest(pReq);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// TRouter receive
+
+void WebSocket<CTeamsProto>::process(const uint8_t *buf, size_t cbLen)
+{
+ Netlib_Dump(getConn(), buf, cbLen, false, 0);
+
+ CMStringA payload((const char *)buf, (int)cbLen);
+ p->TRouterProcess(payload);
+}
+
+void CTeamsProto::TRouterProcess(const char *str)
+{
+ switch (*str) {
+ case '1':
+ TRouterSendAuthentication();
+ TRouterSendActive(true);
+ TRouterRegister();
+ break;
+ }
+} \ No newline at end of file
diff --git a/protocols/Teams/src/teams_utils.cpp b/protocols/Teams/src/teams_utils.cpp
index 59beeaa894..3d23351468 100644
--- a/protocols/Teams/src/teams_utils.cpp
+++ b/protocols/Teams/src/teams_utils.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2015-25 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2025 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/protocols/Teams/src/teams_utils.h b/protocols/Teams/src/teams_utils.h
index f7d205da61..58255e53c1 100644
--- a/protocols/Teams/src/teams_utils.h
+++ b/protocols/Teams/src/teams_utils.h
@@ -60,9 +60,9 @@ struct CFileUploadParam : public MZeroedObject
}
};
-struct SkypeReply : public JsonReply
+struct TeamsReply : public JsonReply
{
- SkypeReply(MHttpResponse *response) :
+ TeamsReply(MHttpResponse *response) :
JsonReply(response)
{
if (m_root)