summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElzorFox <elzorfox@ya.ru>2025-06-17 19:50:40 +0500
committerElzorFox <elzorfox@ya.ru>2025-06-17 19:50:40 +0500
commitecae8cfa27189ebf9612b62a6a6a9204c84f642e (patch)
treee1a0072cb7cd175499eb5e94dd9398a37ee991a0
parent723fb1f1cc490e497247d8fa66a26d5a8a638d46 (diff)
VKontakte:
fix loading max 100 online contacts rework procedure for loading contact statuses new hidden option TimeoutAfterUserGet (default 0) for fix ‘user.get’ flood remove old code for replace option name version bump
-rw-r--r--protocols/VKontakte/src/version.h4
-rw-r--r--protocols/VKontakte/src/vk_proto.h7
-rw-r--r--protocols/VKontakte/src/vk_struct.cpp9
-rw-r--r--protocols/VKontakte/src/vk_struct.h2
-rw-r--r--protocols/VKontakte/src/vk_thread.cpp129
-rw-r--r--protocols/VKontakte/src/vkjs.js31
6 files changed, 122 insertions, 60 deletions
diff --git a/protocols/VKontakte/src/version.h b/protocols/VKontakte/src/version.h
index c7d2f51ba6..7973129c49 100644
--- a/protocols/VKontakte/src/version.h
+++ b/protocols/VKontakte/src/version.h
@@ -1,7 +1,7 @@
#define __MAJOR_VERSION 0
#define __MINOR_VERSION 1
-#define __RELEASE_NUM 18
-#define __BUILD_NUM 7
+#define __RELEASE_NUM 19
+#define __BUILD_NUM 0
#include <stdver.h>
diff --git a/protocols/VKontakte/src/vk_proto.h b/protocols/VKontakte/src/vk_proto.h
index 9ad64b825e..21f00c6280 100644
--- a/protocols/VKontakte/src/vk_proto.h
+++ b/protocols/VKontakte/src/vk_proto.h
@@ -47,7 +47,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define MAXHISTORYMIDSPERONE 100
#define MAX_RETRIES 10
-#define MAX_CONTACTS_PER_REQUEST 530
+#define MAX_CONTACTS_PER_REQUEST 100
struct CVkProto : public PROTO<CVkProto>
{
@@ -333,7 +333,8 @@ private:
//====================================================================================
void SetServerStatus(int);
- void RetrieveUsersInfo(bool bFlag = false, bool bRepeat = false);
+ void RetrieveUsersFrameInfo(CMStringA& userIDs, bool bFreeOffline, bool bSendOnline, bool bRepeat);
+ void RetrieveUsersInfo(bool bFreeOffline = false);
void RetrieveStatusMsg(const CMStringW &StatusMsg);
void RetrieveStatusMusic(const CMStringW &StatusMsg);
void OnReceiveStatus(MHttpResponse*, AsyncHttpRequest*);
@@ -345,7 +346,7 @@ private:
void RetrieveUserInfo(VKUserID_t iUserId);
void RetrieveGroupInfo(VKUserID_t iGroupID);
void RetrieveGroupInfo(CMStringA & groupIDs);
- void OnReceiveUserInfo(MHttpResponse*, AsyncHttpRequest*);
+ void OnReceiveUserFrameInfo(MHttpResponse* reply, AsyncHttpRequest* pReq);
void OnReceiveGroupInfo(MHttpResponse * reply, AsyncHttpRequest * pReq);
void RetrieveFriends(bool bCleanNonFriendContacts = false);
void OnReceiveFriends(MHttpResponse*, AsyncHttpRequest*);
diff --git a/protocols/VKontakte/src/vk_struct.cpp b/protocols/VKontakte/src/vk_struct.cpp
index a36a53a0d0..ca17e025a5 100644
--- a/protocols/VKontakte/src/vk_struct.cpp
+++ b/protocols/VKontakte/src/vk_struct.cpp
@@ -240,17 +240,10 @@ CVKOptions::CVKOptions(PROTO_INTERFACE* proto) :
iInvisibleInterval(proto, "InvisibleInterval", 10),
iMaxFriendsCount(proto, "MaxFriendsCount", 1000),
iStickerSize(proto, "StickerSize", 128),
+ iTimeoutAfterUserGet(proto, "TimeoutAfterUserGet", 0),
pwszDefaultGroup(proto, "ProtoGroup", L"VKontakte"),
pwszVKLang(proto, "VKLang", nullptr)
{
- // Note: Delete this code after next stable build
- int iStikersAsSmyles = db_get_b(0, proto->m_szModuleName, "StikersAsSmyles", -1);
- if (iStikersAsSmyles != -1) {
- bStikersAsSmileys = iStikersAsSmyles == 1;
- db_set_b(0, proto->m_szModuleName, "StikersAsSmileys", (uint8_t)iStikersAsSmyles);
- db_unset(0, proto->m_szModuleName, "StikersAsSmyles");
- }
- // Note
} \ No newline at end of file
diff --git a/protocols/VKontakte/src/vk_struct.h b/protocols/VKontakte/src/vk_struct.h
index aac60bf2ef..45b3c34a4b 100644
--- a/protocols/VKontakte/src/vk_struct.h
+++ b/protocols/VKontakte/src/vk_struct.h
@@ -327,6 +327,8 @@ struct CVKOptions {
CMOption<uint32_t> iMaxFriendsCount;
CMOption<uint32_t> iStickerSize;
+ CMOption<uint32_t> iTimeoutAfterUserGet;
+
CMOption<wchar_t*> pwszDefaultGroup;
CMOption<wchar_t*> pwszVKLang;
diff --git a/protocols/VKontakte/src/vk_thread.cpp b/protocols/VKontakte/src/vk_thread.cpp
index ccd57be40b..fe33329ad2 100644
--- a/protocols/VKontakte/src/vk_thread.cpp
+++ b/protocols/VKontakte/src/vk_thread.cpp
@@ -539,11 +539,12 @@ void CVkProto::RetrieveUserInfo(VKUserID_t iUserId)
return;
}
- Push(new AsyncHttpRequest(this, REQUEST_POST, "/method/execute.RetrieveUserInfo", true, &CVkProto::OnReceiveUserInfo)
+ CMStringA szUserId(FORMAT, "%d", iUserId);
+
+ Push(new AsyncHttpRequest(this, REQUEST_POST, "/method/execute.RetrieveUserInfo", true, &CVkProto::OnReceiveUserFrameInfo)
<< INT_PARAM("userid", iUserId)
<< CHAR_PARAM("fields", szFieldsName)
- );
-
+ )->pUserInfo = mir_strdup(szUserId.c_str());
}
void CVkProto::RetrieveGroupInfo(VKUserID_t iGroupId)
@@ -568,77 +569,74 @@ void CVkProto::RetrieveGroupInfo(CMStringA& groupIDs)
<< CHAR_PARAM("group_ids", groupIDs));
}
-void CVkProto::RetrieveUsersInfo(bool bFreeOffline, bool bRepeat)
+void CVkProto::RetrieveUsersFrameInfo(CMStringA& szUserIds, bool bFreeOffline, bool bSendOnline, bool bRepeat)
{
- debugLogA("CVkProto::RetrieveUsersInfo");
- if (!IsOnline())
+ debugLogA("CVkProto::RetrieveUsersFrameInfo %s", szUserIds);
+ if (!IsOnline() || szUserIds.IsEmpty())
return;
-
- CMStringA userIDs;
- int i = 0;
- for (auto &hContact : AccContacts()) {
- VKUserID_t iUserId = ReadVKUserID(hContact);
- if (iUserId == VK_INVALID_USER || iUserId == VK_FEED_USER || iUserId < 0 || isChatRoom(hContact))
- continue;
-
- bool bIsFriend = !getBool(hContact, "Auth", true);
- if (bFreeOffline && !m_vkOptions.bLoadFullCList && bIsFriend)
- continue;
-
- if (!userIDs.IsEmpty())
- userIDs.AppendChar(',');
- userIDs.AppendFormat("%i", iUserId);
-
- if (i == MAX_CONTACTS_PER_REQUEST)
- break;
- i++;
- }
-
- Push(new AsyncHttpRequest(this, REQUEST_POST, "/method/execute.RetrieveUsersInfo", true, &CVkProto::OnReceiveUserInfo)
- << CHAR_PARAM("userids", userIDs)
+
+ Push(new AsyncHttpRequest(this, REQUEST_POST, "/method/execute.RetrieveUsersFrameInfo", true, &CVkProto::OnReceiveUserFrameInfo)
+ << CHAR_PARAM("userids", szUserIds)
<< CHAR_PARAM("fields", (bFreeOffline ? "online,status,can_write_private_message" : szFieldsName))
<< INT_PARAM("norepeat", (int)bRepeat)
- << INT_PARAM("setonline", (int)m_bNeedSendOnline)
+ << INT_PARAM("setonline", (int)(m_bNeedSendOnline && bSendOnline))
<< INT_PARAM("func_v", (bFreeOffline && !m_vkOptions.bLoadFullCList) ? 1 : 2)
- );
-
+ )->pUserInfo = mir_strdup(szUserIds.c_str());
}
-void CVkProto::OnReceiveUserInfo(MHttpResponse *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveUserFrameInfo(MHttpResponse* reply, AsyncHttpRequest* pReq)
{
- debugLogA("CVkProto::OnReceiveUserInfo %d", reply->resultCode);
+ debugLogA("CVkProto::OnReceiveUserFrameInfo %d", reply->resultCode);
if (reply->resultCode != 200 || !IsOnline())
return;
JSONNode jnRoot;
- const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
+ const JSONNode& jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
if (!jnResponse)
return;
- const JSONNode &jnUsers = jnResponse["users"];
+ const JSONNode& jnUsers = jnResponse["users"];
if (!jnUsers)
return;
+ CMStringA szUserIds;
+ if (pReq->pUserInfo) {
+ szUserIds = ((const char*)pReq->pUserInfo);
+ mir_free(pReq->pUserInfo);
+ }
+
if (!jnResponse["norepeat"].as_bool() && jnResponse["usercount"].as_int() == 0) {
- RetrieveUsersInfo(true, true);
+ Sleep(5000);
+ RetrieveUsersFrameInfo(szUserIds, true, false, true);
return;
}
LIST<void> arContacts(10, PtrKeySortT);
- for (auto &hContact : AccContacts())
- if (!isChatRoom(hContact) && !IsGroupUser(hContact))
- arContacts.insert((HANDLE)hContact);
+ for (auto& hContact : AccContacts())
+ if (!isChatRoom(hContact) && !IsGroupUser(hContact)) {
+ if (szUserIds.IsEmpty()) {
+ if (!getBool(hContact, "Auth", true))
+ arContacts.insert((HANDLE)hContact);
+ }
+ else {
+ VKUserID_t iUserId = ReadVKUserID(hContact);
+ char szId[40];
+ ltoa(iUserId, szId, 10);
+ if (szUserIds.Find(szId) >= 0)
+ arContacts.insert((HANDLE)hContact);
+ }
+ }
- for (auto &it : jnUsers) {
+ for (auto& it : jnUsers) {
MCONTACT hContact = SetContactInfo(it);
if (hContact)
arContacts.remove((HANDLE)hContact);
}
if (jnResponse["freeoffline"].as_bool())
- for (auto &it : arContacts) {
+ for (auto& it : arContacts) {
MCONTACT cc = (UINT_PTR)it;
VKUserID_t iUserId = ReadVKUserID(cc);
if (iUserId == m_iMyUserId || iUserId == VK_FEED_USER)
@@ -655,14 +653,16 @@ void CVkProto::OnReceiveUserInfo(MHttpResponse *reply, AsyncHttpRequest *pReq)
}
arContacts.destroy();
- AddFeedSpecialUser();
- const JSONNode &jnRequests = jnResponse["requests"];
+ if (m_vkOptions.iTimeoutAfterUserGet) // for 'error 9' fix
+ Sleep(m_vkOptions.iTimeoutAfterUserGet > 5000 ? 5000 : m_vkOptions.iTimeoutAfterUserGet);
+
+ const JSONNode& jnRequests = jnResponse["requests"];
if (!jnRequests)
return;
int iCount = jnRequests["count"].as_int();
- const JSONNode &jnItems = jnRequests["items"];
+ const JSONNode& jnItems = jnRequests["items"];
if (!iCount || !jnItems)
return;
@@ -676,10 +676,45 @@ void CVkProto::OnReceiveUserInfo(MHttpResponse *reply, AsyncHttpRequest *pReq)
if (!IsAuthContactLater(hContact)) {
RetrieveUserInfo(iUserId);
AddAuthContactLater(hContact);
- CVkDBAddAuthRequestThreadParam *param = new CVkDBAddAuthRequestThreadParam(hContact, false);
- ForkThread(&CVkProto::DBAddAuthRequestThread, (void *)param);
+ CVkDBAddAuthRequestThreadParam* param = new CVkDBAddAuthRequestThreadParam(hContact, false);
+ ForkThread(&CVkProto::DBAddAuthRequestThread, (void*)param);
+ }
+ }
+}
+
+void CVkProto::RetrieveUsersInfo(bool bFreeOffline)
+{
+ debugLogA("CVkProto::RetrieveUsersInformation");
+ if (!IsOnline())
+ return;
+
+ CMStringA szUserIds;
+ int i = 0;
+ bool bSendOnline = true;
+
+ for (auto& hContact : AccContacts()) {
+ VKUserID_t iUserId = ReadVKUserID(hContact);
+ if (iUserId == VK_INVALID_USER || iUserId == VK_FEED_USER || iUserId < 0 || isChatRoom(hContact))
+ continue;
+
+ if (!szUserIds.IsEmpty())
+ szUserIds.AppendChar(',');
+ szUserIds.AppendFormat("%i", iUserId);
+
+ if (i < (MAX_CONTACTS_PER_REQUEST - 1))
+ i++;
+ else {
+ RetrieveUsersFrameInfo(szUserIds, bFreeOffline, bSendOnline, false);
+ i = 0;
+ szUserIds.Empty();
+ bSendOnline = false;
}
}
+
+ if(!szUserIds.IsEmpty())
+ RetrieveUsersFrameInfo(szUserIds, bFreeOffline, bSendOnline, false);
+
+ AddFeedSpecialUser();
}
void CVkProto::OnReceiveGroupInfo(MHttpResponse *reply, AsyncHttpRequest *pReq)
diff --git a/protocols/VKontakte/src/vkjs.js b/protocols/VKontakte/src/vkjs.js
index 8e1faadcdb..43bf1aa167 100644
--- a/protocols/VKontakte/src/vkjs.js
+++ b/protocols/VKontakte/src/vkjs.js
@@ -17,6 +17,37 @@
// 4. Create additional version(s) stored procedure (if required)
+// Stored procedure name: RetrieveUsersFrameInfo = Begin
+// Arguments:
+// Args.userids
+// Args.fields
+// Args.norepeat
+// Args.setonline
+
+// ver 1
+var Req =[];
+if (Args.setonline == 1) {
+ API.account.setOnline();
+ Req = API.friends.getRequests({ "extended": 0, "need_mutual": 0, "out": 0 });
+};
+var res = [];
+var US = API.users.get({ "user_ids": Args.userids, "fields": Args.fields, "name_case": "nom" });
+var index = US.length;
+while (index > 0) {
+ index = index - 1;
+ if (US[index].online != 0) {
+ res.push(US[index]);
+ };
+};
+return { "freeoffline": 1, "norepeat": parseInt(Args.norepeat), "usercount": res.length, "users": res , "requests": Req};
+
+// ver 2
+if (Args.setonline == 1)
+ API.account.setOnline();
+var res = API.users.get({ "user_ids": Args.userids, "fields": Args.fields, "name_case": "nom" });
+return { "freeoffline": 0, "norepeat": parseInt(Args.norepeat), "usercount": res.length, "users": res, "requests": API.friends.getRequests({ "extended": 0, "need_mutual": 0, "out": 0 })};
+// Stored procedure name: RetrieveUsersFrameInfo = End
+
// Stored procedure name: RetrieveUserInfo = Begin
// Arguments:
// Args.userid