summaryrefslogtreecommitdiff
path: root/protocols/VKontakte/src
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/VKontakte/src')
-rw-r--r--protocols/VKontakte/src/misc.cpp125
-rw-r--r--protocols/VKontakte/src/stdafx.h1
-rw-r--r--protocols/VKontakte/src/version.h2
-rw-r--r--protocols/VKontakte/src/vk.h14
-rw-r--r--protocols/VKontakte/src/vk_avatars.cpp17
-rw-r--r--protocols/VKontakte/src/vk_chats.cpp6
-rw-r--r--protocols/VKontakte/src/vk_files.cpp151
-rw-r--r--protocols/VKontakte/src/vk_history.cpp18
-rw-r--r--protocols/VKontakte/src/vk_messages.cpp28
-rw-r--r--protocols/VKontakte/src/vk_pollserver.cpp6
-rw-r--r--protocols/VKontakte/src/vk_proto.cpp9
-rw-r--r--protocols/VKontakte/src/vk_proto.h215
-rw-r--r--protocols/VKontakte/src/vk_search.cpp32
-rw-r--r--protocols/VKontakte/src/vk_struct.cpp156
-rw-r--r--protocols/VKontakte/src/vk_struct.h225
-rw-r--r--protocols/VKontakte/src/vk_thread.cpp8
16 files changed, 561 insertions, 452 deletions
diff --git a/protocols/VKontakte/src/misc.cpp b/protocols/VKontakte/src/misc.cpp
index b5c3238027..4f24f82615 100644
--- a/protocols/VKontakte/src/misc.cpp
+++ b/protocols/VKontakte/src/misc.cpp
@@ -131,84 +131,6 @@ char* ExpUrlEncode(const char *szUrl, bool strict)
return szOutput;
}
-/////////////////////////////////////////////////////////////////////////////////////////
-
-ULONG AsyncHttpRequest::m_reqCount = 0;
-
-AsyncHttpRequest::AsyncHttpRequest()
-{
- cbSize = sizeof(NETLIBHTTPREQUEST);
- m_bApiReq = true;
- AddHeader("Connection", "keep-alive");
- AddHeader("Accept-Encoding", "booo");
- pUserInfo = NULL;
- m_iRetry = MAX_RETRIES;
- bNeedsRestart = false;
- bIsMainConn = false;
- m_pFunc = NULL;
- bExpUrlEncode = false;
- m_reqNum = ::InterlockedIncrement(&m_reqCount);
- m_priority = rpLow;
-}
-
-AsyncHttpRequest::AsyncHttpRequest(CVkProto *ppro, int iRequestType, LPCSTR _url, bool bSecure, VK_REQUEST_HANDLER pFunc, RequestPriority rpPriority)
-{
- cbSize = sizeof(NETLIBHTTPREQUEST);
- m_bApiReq = true;
- bIsMainConn = false;
- bExpUrlEncode = ppro->m_bUseNonStandardUrlEncode;
- AddHeader("Connection", "keep-alive");
- AddHeader("Accept-Encoding", "booo");
-
- flags = VK_NODUMPHEADERS | NLHRF_DUMPASTEXT | NLHRF_HTTP11 | NLHRF_REDIRECT;
- if (bSecure)
- flags |= NLHRF_SSL;
-
- if (*_url == '/') { // relative url leads to a site
- m_szUrl = ((bSecure) ? "https://" : "http://") + CMStringA("api.vk.com");
- m_szUrl += _url;
- bIsMainConn = true;
- }
- else m_szUrl = _url;
-
- if (bSecure)
- this << CHAR_PARAM("access_token", ppro->m_szAccessToken);
-
- requestType = iRequestType;
- m_pFunc = pFunc;
- pUserInfo = NULL;
- m_iRetry = MAX_RETRIES;
- bNeedsRestart = false;
- m_reqNum = ::InterlockedIncrement(&m_reqCount);
- m_priority = rpPriority;
-}
-
-AsyncHttpRequest::~AsyncHttpRequest()
-{
- for (int i = 0; i < headersCount; i++) {
- mir_free(headers[i].szName);
- mir_free(headers[i].szValue);
- }
- mir_free(headers);
- mir_free(pData);
-}
-
-void AsyncHttpRequest::AddHeader(LPCSTR szName, LPCSTR szValue)
-{
- headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1));
- headers[headersCount].szName = mir_strdup(szName);
- headers[headersCount].szValue = mir_strdup(szValue);
- headersCount++;
-}
-
-void AsyncHttpRequest::Redirect(NETLIBHTTPREQUEST *nhr)
-{
- for (int i = 0; i < nhr->headersCount; i++) {
- LPCSTR szValue = nhr->headers[i].szValue;
- if (!_stricmp(nhr->headers[i].szName, "Location"))
- m_szUrl = szValue;
- }
-}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -307,8 +229,10 @@ JSONNode& CVkProto::CheckJsonResponse(AsyncHttpRequest *pReq, NETLIBHTTPREQUEST
bool CVkProto::CheckJsonResult(AsyncHttpRequest *pReq, const JSONNode &jnNode)
{
debugLogA("CVkProto::CheckJsonResult");
- if (!jnNode)
+ if (!jnNode) {
+ pReq->m_iErrorCode = VKERR_NO_JSONNODE;
return false;
+ }
const JSONNode &jnError = jnNode["error"];
const JSONNode &jnErrorCode = jnError["error_code"];
@@ -316,11 +240,9 @@ bool CVkProto::CheckJsonResult(AsyncHttpRequest *pReq, const JSONNode &jnNode)
if (!jnError || !jnErrorCode)
return true;
- int iErrorCode = jnErrorCode.as_int();
- debugLogA("CVkProto::CheckJsonResult %d", iErrorCode);
- CVkFileUploadParam * fup = (CVkFileUploadParam *)pReq->pUserInfo;
- CVkSendMsgParam *param = (CVkSendMsgParam*)pReq->pUserInfo;
- switch (iErrorCode) {
+ pReq->m_iErrorCode = jnErrorCode.as_int();
+ debugLogA("CVkProto::CheckJsonResult %d", pReq->m_iErrorCode);
+ switch (pReq->m_iErrorCode) {
case VKERR_AUTHORIZATION_FAILED:
ConnectionFailed(LOGINERR_WRONGPASSWORD);
break;
@@ -338,17 +260,6 @@ bool CVkProto::CheckJsonResult(AsyncHttpRequest *pReq, const JSONNode &jnNode)
case VKERR_CAPTCHA_NEEDED:
ApplyCaptcha(pReq, jnError);
break;
- case VKERR_COULD_NOT_SAVE_FILE:
- case VKERR_INVALID_ALBUM_ID:
- case VKERR_INVALID_SERVER:
- case VKERR_INVALID_HASH:
- case VKERR_INVALID_AUDIO:
- case VKERR_AUDIO_DEL_COPYRIGHT:
- case VKERR_INVALID_FILENAME:
- case VKERR_INVALID_FILESIZE:
- if (fup)
- fup->iErrorCode = iErrorCode;
- break;
case VKERR_FLOOD_CONTROL:
pReq->m_iRetry = 0;
// fall through
@@ -362,26 +273,34 @@ bool CVkProto::CheckJsonResult(AsyncHttpRequest *pReq, const JSONNode &jnNode)
pReq->m_iRetry--;
}
else {
- CMString msg(FORMAT, TranslateT("Error %d. Data will not be sent or received."), iErrorCode);
+ CMString msg(FORMAT, TranslateT("Error %d. Data will not be sent or received."), pReq->m_iErrorCode);
MsgPopup(NULL, msg, TranslateT("Error"), true);
debugLogA("CVkProto::CheckJsonResult SendError");
}
break;
- case VKERR_HIMSELF_AS_FRIEND:
- case VKERR_YOU_ON_BLACKLIST:
- case VKERR_USER_ON_BLACKLIST:
- if (param)
- param->iCount = iErrorCode;
- break;
+
case VKERR_INVALID_PARAMETERS:
MsgPopup(NULL, TranslateT("One of the parameters specified was missing or invalid"), TranslateT("Error"), true);
break;
case VKERR_ACC_WALL_POST_DENIED:
MsgPopup(NULL, TranslateT("Access to adding post denied"), TranslateT("Error"), true);
break;
+ case VKERR_COULD_NOT_SAVE_FILE:
+ case VKERR_INVALID_ALBUM_ID:
+ case VKERR_INVALID_SERVER:
+ case VKERR_INVALID_HASH:
+ case VKERR_INVALID_AUDIO:
+ case VKERR_AUDIO_DEL_COPYRIGHT:
+ case VKERR_INVALID_FILENAME:
+ case VKERR_INVALID_FILESIZE:
+ case VKERR_HIMSELF_AS_FRIEND:
+ case VKERR_YOU_ON_BLACKLIST:
+ case VKERR_USER_ON_BLACKLIST:
+ // See CVkProto::SendFileFiled
+ break;
}
- return iErrorCode == 0;
+ return pReq->m_iErrorCode == 0;
}
void CVkProto::OnReceiveSmth(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
diff --git a/protocols/VKontakte/src/stdafx.h b/protocols/VKontakte/src/stdafx.h
index 8aaa81e389..b70f946812 100644
--- a/protocols/VKontakte/src/stdafx.h
+++ b/protocols/VKontakte/src/stdafx.h
@@ -66,4 +66,5 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "resource.h"
#include "vk.h"
+#include "vk_struct.h"
#include "vk_proto.h"
diff --git a/protocols/VKontakte/src/version.h b/protocols/VKontakte/src/version.h
index d3926c8e38..590fb86f7c 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 1
-#define __BUILD_NUM 13
+#define __BUILD_NUM 14
#include <stdver.h>
diff --git a/protocols/VKontakte/src/vk.h b/protocols/VKontakte/src/vk.h
index f131ca8b35..83e9d0eb7e 100644
--- a/protocols/VKontakte/src/vk.h
+++ b/protocols/VKontakte/src/vk.h
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#pragma once
+
#define VK_APP_ID 3917910
// LongPool servers events
@@ -45,6 +47,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define VKFLAG_MSGMEDIA 512 // сообщение содержит медиаконтент
// Errors
+#define VKERR_NO_JSONNODE -2 // No JSON Node in server reply
+#define VKERR_OFFLINE -1 // Proto is offline
#define VKERR_NOERRORS 0 // No error
#define VKERR_UNKNOWN 1 // Unknown error occurred
#define VKERR_TOO_MANY_REQ_PER_SEC 6 // Too many requests per second
@@ -66,6 +70,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define VKERR_AUDIO_DEL_COPYRIGHT 270 // The audio file was removed by the copyright holder and cannot be reuploaded.
#define VKERR_INVALID_FILENAME 301 // Invalid filename
#define VKERR_INVALID_FILESIZE 302 // Invalid filesize
+// File upload custom error
+#define VKERR_FILE_NOT_EXIST 10100 // File not exist
+#define VKERR_FTYPE_NOT_SUPPORTED 10101 // File type not supported
+#define VKERR_ERR_OPEN_FILE 10103 // Error open file
+#define VKERR_ERR_READ_FILE 10104 // Error read file
+#define VKERR_FILE_NOT_UPLOADED 10105 // Error upload file
+#define VKERR_INVALID_URL 10106 // Upload server return empty url
+#define VKERR_INVALID_USER 10107 // Invalid or unknow recepient user ID
#define VK_API_VER "5.37"
#define VER_API CHAR_PARAM("v", VK_API_VER)
@@ -92,4 +104,4 @@ HANDLE GetIconHandle(int iCommand);
char* ExpUrlEncode(const char *szUrl, bool strict = false);
bool IsEmpty(LPCTSTR str);
-bool IsEmpty(LPCSTR str); \ No newline at end of file
+bool IsEmpty(LPCSTR str);
diff --git a/protocols/VKontakte/src/vk_avatars.cpp b/protocols/VKontakte/src/vk_avatars.cpp
index 9ce6447f36..11386736ce 100644
--- a/protocols/VKontakte/src/vk_avatars.cpp
+++ b/protocols/VKontakte/src/vk_avatars.cpp
@@ -19,23 +19,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
void CVkProto::OnReceiveAvatar(NETLIBHTTPREQUEST *reply, AsyncHttpRequest* pReq)
{
- if (reply->resultCode != 200)
+ if (reply->resultCode != 200 || !pReq->pUserInfo)
return;
PROTO_AVATAR_INFORMATION ai = { 0 };
- GetAvatarFileName((UINT_PTR)pReq->pUserInfo, ai.filename, _countof(ai.filename));
+ CVkSendMsgParam * param = (CVkSendMsgParam *)pReq->pUserInfo;
+ GetAvatarFileName(param->hContact, ai.filename, _countof(ai.filename));
ai.format = ProtoGetBufferFormat(reply->pData);
FILE *out = _tfopen(ai.filename, _T("wb"));
if (out == NULL) {
- ProtoBroadcastAck((UINT_PTR)pReq->pUserInfo, ACKTYPE_AVATAR, ACKRESULT_FAILED, &ai);
+ ProtoBroadcastAck(param->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, &ai);
+ delete param;
+ pReq->pUserInfo = NULL;
return;
}
fwrite(reply->pData, 1, reply->dataLength, out);
fclose(out);
- setByte((UINT_PTR)pReq->pUserInfo, "NeedNewAvatar", 0);
- ProtoBroadcastAck((UINT_PTR)pReq->pUserInfo, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &ai);
+ setByte(param->hContact, "NeedNewAvatar", 0);
+ ProtoBroadcastAck(param->hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &ai);
+ delete param;
+ pReq->pUserInfo = NULL;
}
INT_PTR CVkProto::SvcGetAvatarCaps(WPARAM wParam, LPARAM lParam)
@@ -93,7 +98,7 @@ INT_PTR CVkProto::SvcGetAvatarInfo(WPARAM, LPARAM lParam)
AsyncHttpRequest *pReq = new AsyncHttpRequest();
pReq->flags = NLHRF_NODUMP | NLHRF_REDIRECT;
pReq->m_szUrl = szUrl;
- pReq->pUserInfo = (char*)pai->hContact;
+ pReq->pUserInfo = new CVkSendMsgParam(pai->hContact);
pReq->m_pFunc = &CVkProto::OnReceiveAvatar;
pReq->requestType = REQUEST_GET;
pReq->m_bApiReq = false;
diff --git a/protocols/VKontakte/src/vk_chats.cpp b/protocols/VKontakte/src/vk_chats.cpp
index f4408c3ea4..1d3c56d273 100644
--- a/protocols/VKontakte/src/vk_chats.cpp
+++ b/protocols/VKontakte/src/vk_chats.cpp
@@ -441,12 +441,6 @@ CVkChatInfo* CVkProto::GetChatById(LPCTSTR ptszId)
return NULL;
}
-CVkChatUser* CVkChatInfo::GetUserById(LPCTSTR ptszId)
-{
- int user_id = _ttoi(ptszId);
- return m_users.find((CVkChatUser*)&user_id);
-}
-
/////////////////////////////////////////////////////////////////////////////////////////
void CVkProto::SetChatStatus(MCONTACT hContact, int iStatus)
diff --git a/protocols/VKontakte/src/vk_files.cpp b/protocols/VKontakte/src/vk_files.cpp
index aa32117e61..7b39fb8dea 100644
--- a/protocols/VKontakte/src/vk_files.cpp
+++ b/protocols/VKontakte/src/vk_files.cpp
@@ -17,56 +17,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
-CVkFileUploadParam::CVkFileUploadParam(MCONTACT _hContact, const TCHAR* _desc, TCHAR** _files) :
- hContact(_hContact),
- filetype(typeInvalid),
- atr(NULL),
- fname(NULL),
- iErrorCode(0)
-{
- Desc = mir_tstrdup(_desc);
- FileName = mir_tstrdup(_files[0]);
-}
-
-CVkFileUploadParam::~CVkFileUploadParam()
-{
- mir_free(Desc);
- mir_free(FileName);
- mir_free(atr);
- mir_free(fname);
-}
-
-CVkFileUploadParam::VKFileType CVkFileUploadParam::GetType()
-{
- if (filetype != typeInvalid)
- return filetype;
-
- TCHAR img[] = _T(".jpg .jpeg .png .bmp");
- TCHAR audio[] = _T(".mp3");
-
- TCHAR DRIVE[3], DIR[256], FNAME[256], EXT[256];
- _tsplitpath(FileName, DRIVE, DIR, FNAME, EXT);
-
- T2Utf pszFNAME(FNAME), pszEXT(EXT);
- CMStringA fn(FORMAT, "%s%s", pszFNAME, pszEXT);
- fname = mir_strdup(fn);
-
- if (tlstrstr(img, EXT)) {
- filetype = CVkFileUploadParam::typeImg;
- atr = mir_strdup("photo");
- }
- else if (tlstrstr(audio, EXT)) {
- filetype = CVkFileUploadParam::typeAudio;
- atr = mir_strdup("file");
- }
- else {
- filetype = CVkFileUploadParam::typeDoc;
- atr = mir_strdup("file");
- }
-
- return filetype;
-}
-
HANDLE CVkProto::SendFile(MCONTACT hContact, const TCHAR *desc, TCHAR **files)
{
debugLogA("CVkProto::SendFile");
@@ -79,12 +29,37 @@ HANDLE CVkProto::SendFile(MCONTACT hContact, const TCHAR *desc, TCHAR **files)
return (HANDLE)fup;
}
-void CVkProto::SendFileFiled(CVkFileUploadParam *fup, TCHAR *reason)
+void CVkProto::SendFileFiled(CVkFileUploadParam *fup, int ErrorCode)
{
- debugLog(_T("CVkProto::SendFileFiled <%s> Error code <%d>"), reason, fup->iErrorCode);
CMString tszError;
- int iResult = ACKRESULT_FAILED;
- switch (fup->iErrorCode) {
+ switch (ErrorCode) {
+ case VKERR_OFFLINE:
+ tszError = TranslateT("Protocol is offline");
+ break;
+ case VKERR_FILE_NOT_EXIST:
+ tszError = TranslateT("File not exist");
+ break;
+ case VKERR_FTYPE_NOT_SUPPORTED:
+ tszError = TranslateT("File type not supported");
+ break;
+ case VKERR_ERR_OPEN_FILE:
+ tszError = TranslateT("Error open file");
+ break;
+ case VKERR_ERR_READ_FILE:
+ tszError = TranslateT("Error read file");
+ break;
+ case VKERR_FILE_NOT_UPLOADED:
+ tszError = TranslateT("Error upload file");
+ break;
+ case VKERR_INVALID_URL:
+ tszError = TranslateT("Upload server return empty url");
+ break;
+ case VKERR_INVALID_USER:
+ tszError = TranslateT("Invalid or unknow recepient user ID");
+ break;
+ case VKERR_INVALID_PARAMETERS:
+ tszError = TranslateT("One of the parameters specified was missing or invalid");
+ break;
case VKERR_COULD_NOT_SAVE_FILE:
tszError = TranslateT("Couldn't save file");
break;
@@ -101,8 +76,7 @@ void CVkProto::SendFileFiled(CVkFileUploadParam *fup, TCHAR *reason)
tszError = TranslateT("Invalid audio");
break;
case VKERR_AUDIO_DEL_COPYRIGHT:
- tszError = TranslateT("The audio file was removed by the copyright holder and cannot be reuploaded");
- iResult = ACKRESULT_DENIED;
+ tszError = TranslateT("The audio file was removed by the copyright holder and cannot be reuploaded");
break;
case VKERR_INVALID_FILENAME:
tszError = TranslateT("Invalid filename");
@@ -113,7 +87,8 @@ void CVkProto::SendFileFiled(CVkFileUploadParam *fup, TCHAR *reason)
default:
tszError = TranslateT("Unknown error occurred");
}
- ProtoBroadcastAck(fup->hContact, ACKTYPE_FILE, iResult, (HANDLE)fup);
+ ProtoBroadcastAck(fup->hContact, ACKTYPE_FILE, ErrorCode== VKERR_AUDIO_DEL_COPYRIGHT ? ACKRESULT_DENIED : ACKRESULT_FAILED, (HANDLE)fup);
+ debugLog(_T("CVkProto::SendFileFiled error code = %d (%s)"), ErrorCode, tszError);
MsgPopup(NULL, tszError, TranslateT("File upload error"), true);
delete fup;
}
@@ -123,11 +98,11 @@ void CVkProto::SendFileThread(void *p)
CVkFileUploadParam *fup = (CVkFileUploadParam *)p;
debugLog(_T("CVkProto::SendFileThread %d %s"), fup->GetType(), fup->fileName());
if (!IsOnline()) {
- SendFileFiled(fup, _T("NotOnline"));
+ SendFileFiled(fup, VKERR_OFFLINE);
return;
}
if (!fup->IsAccess()) {
- SendFileFiled(fup, _T("FileIsNotAccess"));
+ SendFileFiled(fup, VKERR_FILE_NOT_EXIST);
return;
}
@@ -148,7 +123,7 @@ void CVkProto::SendFileThread(void *p)
<< VER_API;
break;
default:
- SendFileFiled(fup, _T("FileTypeNotSupported"));
+ SendFileFiled(fup, VKERR_FTYPE_NOT_SUPPORTED);
return;
}
pReq->pUserInfo = p;
@@ -159,32 +134,32 @@ void CVkProto::OnReciveUploadServer(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *
{
CVkFileUploadParam *fup = (CVkFileUploadParam *)pReq->pUserInfo;
if (!IsOnline()) {
- SendFileFiled(fup, _T("NotOnline"));
+ SendFileFiled(fup, VKERR_OFFLINE);
return;
}
debugLogA("CVkProto::OnReciveUploadServer %d", reply->resultCode);
if (reply->resultCode != 200) {
- SendFileFiled(fup, _T("NotUploadServer"));
+ SendFileFiled(fup, VKERR_INVALID_SERVER);
return;
}
JSONNode jnRoot;
const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
- if (!jnResponse) {
- SendFileFiled(fup);
+ if (!jnResponse || pReq->m_iErrorCode) {
+ SendFileFiled(fup, pReq->m_iErrorCode);
return;
}
- CMStringA uri = jnResponse["upload_url"].as_mstring();
+ CMStringA uri(jnResponse["upload_url"].as_mstring());
if (uri.IsEmpty()) {
- SendFileFiled(fup);
+ SendFileFiled(fup, VKERR_INVALID_URL);
return;
}
FILE *pFile = _tfopen(fup->FileName, _T("rb"));
if (pFile == NULL) {
- SendFileFiled(fup, _T("ErrorOpenFile"));
+ SendFileFiled(fup, VKERR_ERR_OPEN_FILE);
return;
}
@@ -192,7 +167,7 @@ void CVkProto::OnReciveUploadServer(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *
long iFileLen = ftell(pFile); //FileSize
if (iFileLen < 1) {
fclose(pFile);
- SendFileFiled(fup, _T("ErrorReadFile"));
+ SendFileFiled(fup, VKERR_ERR_READ_FILE);
return;
}
fseek(pFile, 0, SEEK_SET);
@@ -238,7 +213,7 @@ void CVkProto::OnReciveUploadServer(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *
fclose(pFile);
if (lBytes != iFileLen) {
- SendFileFiled(fup, _T("ErrorReadFile"));
+ SendFileFiled(fup, VKERR_ERR_READ_FILE);
mir_free(pUploadReq->pData);
delete pUploadReq;
return;
@@ -257,19 +232,29 @@ void CVkProto::OnReciveUpload(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
CVkFileUploadParam *fup = (CVkFileUploadParam *)pReq->pUserInfo;
if (!IsOnline()) {
- SendFileFiled(fup, _T("NotOnline"));
+ SendFileFiled(fup, VKERR_OFFLINE);
return;
}
debugLogA("CVkProto::OnReciveUploadServer %d", reply->resultCode);
if (reply->resultCode != 200) {
- SendFileFiled(fup);
+ SendFileFiled(fup, VKERR_FILE_NOT_UPLOADED);
return;
}
JSONNode jnRoot;
CheckJsonResponse(pReq, reply, jnRoot);
+ if (pReq->m_iErrorCode) {
+ SendFileFiled(fup, pReq->m_iErrorCode);
+ return;
+ }
+
+ if (!jnRoot["server"] || !jnRoot["hash"]) {
+ SendFileFiled(fup, VKERR_INVALID_PARAMETERS);
+ return;
+ }
+
CMString server(jnRoot["server"].as_mstring());
CMString hash(jnRoot["hash"].as_mstring());
CMString upload;
@@ -282,7 +267,7 @@ void CVkProto::OnReciveUpload(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
case CVkFileUploadParam::typeImg:
upload = jnRoot["photo"].as_mstring();
if (upload == _T("[]")) {
- SendFileFiled(fup, _T("NotUpload Photo"));
+ SendFileFiled(fup, VKERR_INVALID_PARAMETERS);
return;
}
pUploadReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/photos.saveMessagesPhoto.json", true, &CVkProto::OnReciveUploadFile)
@@ -294,7 +279,7 @@ void CVkProto::OnReciveUpload(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
case CVkFileUploadParam::typeAudio:
upload = jnRoot["audio"].as_mstring();
if (upload == _T("[]")) {
- SendFileFiled(fup, _T("NotUpload Audio"));
+ SendFileFiled(fup, VKERR_INVALID_PARAMETERS);
return;
}
pUploadReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/audio.save.json", true, &CVkProto::OnReciveUploadFile)
@@ -306,7 +291,7 @@ void CVkProto::OnReciveUpload(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
case CVkFileUploadParam::typeDoc:
upload = jnRoot["file"].as_mstring();
if (upload.IsEmpty()) {
- SendFileFiled(fup, _T("NotUpload Doc"));
+ SendFileFiled(fup, VKERR_INVALID_PARAMETERS);
return;
}
pUploadReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/docs.save.json", true, &CVkProto::OnReciveUploadFile)
@@ -315,7 +300,7 @@ void CVkProto::OnReciveUpload(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
<< VER_API;
break;
default:
- SendFileFiled(fup);
+ SendFileFiled(fup, VKERR_FTYPE_NOT_SUPPORTED);
return;
}
@@ -327,27 +312,27 @@ void CVkProto::OnReciveUploadFile(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pR
{
CVkFileUploadParam *fup = (CVkFileUploadParam *)pReq->pUserInfo;
if (!IsOnline()) {
- SendFileFiled(fup, _T("NotOnline"));
+ SendFileFiled(fup, VKERR_OFFLINE);
return;
}
debugLogA("CVkProto::OnReciveUploadFile %d", reply->resultCode);
if (reply->resultCode != 200) {
- SendFileFiled(fup);
+ SendFileFiled(fup, VKERR_FILE_NOT_UPLOADED);
return;
}
JSONNode jnRoot;
const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
- if (!jnResponse) {
- SendFileFiled(fup);
+ if (!jnResponse || pReq->m_iErrorCode) {
+ SendFileFiled(fup, pReq->m_iErrorCode);
return;
}
int id = fup->GetType() == CVkFileUploadParam::typeAudio ? jnResponse["id"].as_int() : (*jnResponse.begin())["id"].as_int();
int owner_id = fup->GetType() == CVkFileUploadParam::typeAudio ? jnResponse["owner_id"].as_int() : (*jnResponse.begin())["owner_id"].as_int();
if ((id == 0) || (owner_id == 0)) {
- SendFileFiled(fup);
+ SendFileFiled(fup, VKERR_INVALID_PARAMETERS);
return;
}
@@ -364,13 +349,13 @@ void CVkProto::OnReciveUploadFile(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pR
Attachment.AppendFormat(_T("doc%d_%d"), owner_id, id);
break;
default:
- SendFileFiled(fup);
+ SendFileFiled(fup, VKERR_FTYPE_NOT_SUPPORTED);
return;
}
LONG userID = getDword(fup->hContact, "ID", -1);
if (userID == -1 || userID == VK_FEED_USER) {
- SendFileFiled(fup);
+ SendFileFiled(fup, VKERR_INVALID_USER);
return;
}
@@ -380,7 +365,7 @@ void CVkProto::OnReciveUploadFile(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pR
<< TCHAR_PARAM("attachment", Attachment)
<< VER_API;
pMsgReq->AddHeader("Content-Type", "application/x-www-form-urlencoded");
- pMsgReq->pUserInfo = new CVkSendMsgParam(fup->hContact, -1, (INT_PTR)pReq->pUserInfo);
+ pMsgReq->pUserInfo = new CVkSendMsgParam(fup->hContact, fup);
Push(pMsgReq);
} \ No newline at end of file
diff --git a/protocols/VKontakte/src/vk_history.cpp b/protocols/VKontakte/src/vk_history.cpp
index b0fd49772b..1e6e1736ad 100644
--- a/protocols/VKontakte/src/vk_history.cpp
+++ b/protocols/VKontakte/src/vk_history.cpp
@@ -169,15 +169,20 @@ void CVkProto::GetHistoryDlg(MCONTACT hContact, int iLastMsg)
void CVkProto::OnReceiveHistoryMessages(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveHistoryMessages %d", reply->resultCode);
- if (reply->resultCode != 200)
+ if (reply->resultCode != 200 || !pReq->pUserInfo)
return;
JSONNode jnRoot;
+ CVkSendMsgParam *param = (CVkSendMsgParam*)pReq->pUserInfo;
const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
- if (!jnResponse)
+ if (!jnResponse) {
+ if (!pReq->bNeedsRestart || m_bTerminated) {
+ delete param;
+ pReq->pUserInfo = NULL;
+ }
return;
-
- CVkSendMsgParam *param = (CVkSendMsgParam*)pReq->pUserInfo;
+ }
+
int iTime = jnResponse["datetime"].as_int();
const JSONNode &jnMsgs = jnResponse["items"];
const JSONNode &jnFUsers = jnResponse["fwd_users"];
@@ -249,5 +254,8 @@ void CVkProto::OnReceiveHistoryMessages(NETLIBHTTPREQUEST *reply, AsyncHttpReque
if (count == iRCount && once == 0)
GetServerHistory(param->hContact, param->iCount + count, iRCount, iTime, param->iMsgID);
- delete param;
+ if (!pReq->bNeedsRestart || m_bTerminated) {
+ delete param;
+ pReq->pUserInfo = NULL;
+ }
} \ No newline at end of file
diff --git a/protocols/VKontakte/src/vk_messages.cpp b/protocols/VKontakte/src/vk_messages.cpp
index 39c1d07f23..3e26356f61 100644
--- a/protocols/VKontakte/src/vk_messages.cpp
+++ b/protocols/VKontakte/src/vk_messages.cpp
@@ -31,9 +31,9 @@ int CVkProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT *pre)
void CVkProto::SendMsgAck(void *param)
{
debugLogA("CVkProto::SendMsgAck");
- TFakeAckParams *ack = (TFakeAckParams*)param;
+ CVkSendMsgParam *ack = (CVkSendMsgParam *)param;
Sleep(100);
- ProtoBroadcastAck(ack->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)ack->msgid);
+ ProtoBroadcastAck(ack->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)ack->iMsgID);
delete ack;
}
@@ -44,7 +44,7 @@ int CVkProto::SendMsg(MCONTACT hContact, int, const char *szMsg)
return 0;
LONG userID = getDword(hContact, "ID", -1);
if (userID == -1 || userID == VK_FEED_USER) {
- ForkThread(&CVkProto::SendMsgAck, new TFakeAckParams(hContact, 0));
+ ForkThread(&CVkProto::SendMsgAck, new CVkSendMsgParam(hContact));
return 0;
}
@@ -67,7 +67,7 @@ int CVkProto::SendMsg(MCONTACT hContact, int, const char *szMsg)
Push(pReq);
if (!m_bServerDelivery)
- ForkThread(&CVkProto::SendMsgAck, new TFakeAckParams(hContact, msgId));
+ ForkThread(&CVkProto::SendMsgAck, new CVkSendMsgParam(hContact, msgId));
if (retMsg) {
Sleep(330);
@@ -83,7 +83,7 @@ void CVkProto::OnSendMessage(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
debugLogA("CVkProto::OnSendMessage failed! (pUserInfo == NULL)");
return;
}
- CVkSendMsgParam *param = (CVkSendMsgParam*)pReq->pUserInfo;
+ CVkSendMsgParam *param = (CVkSendMsgParam *)pReq->pUserInfo;
debugLogA("CVkProto::OnSendMessage %d", reply->resultCode);
if (reply->resultCode == 200) {
@@ -98,24 +98,26 @@ void CVkProto::OnSendMessage(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
if (param->iMsgID != -1)
m_sendIds.insert((HANDLE)mid);
+
if (mid > getDword(param->hContact, "lastmsgid"))
setDword(param->hContact, "lastmsgid", mid);
+
if (m_iMarkMessageReadOn >= markOnReply)
MarkMessagesRead(param->hContact);
+
iResult = ACKRESULT_SUCCESS;
}
}
- if (param->iMsgID == -1) {
- CVkFileUploadParam *fup = (CVkFileUploadParam *)param->iCount;
- ProtoBroadcastAck(fup->hContact, ACKTYPE_FILE, iResult, (HANDLE)fup);
- if (!pReq->bNeedsRestart)
- delete fup;
- return;
+ if (param->pFUP) {
+ ProtoBroadcastAck(param->hContact, ACKTYPE_FILE, iResult, (HANDLE)(param->pFUP));
+ if (!pReq->bNeedsRestart || m_bTerminated)
+ delete param->pFUP;
}
else if (m_bServerDelivery)
- ProtoBroadcastAck(param->hContact, ACKTYPE_MESSAGE, iResult, HANDLE(param->iMsgID));
- if (!pReq->bNeedsRestart) {
+ ProtoBroadcastAck(param->hContact, ACKTYPE_MESSAGE, iResult, (HANDLE)(param->iMsgID));
+
+ if (!pReq->bNeedsRestart || m_bTerminated) {
delete param;
pReq->pUserInfo = NULL;
}
diff --git a/protocols/VKontakte/src/vk_pollserver.cpp b/protocols/VKontakte/src/vk_pollserver.cpp
index e10d36c296..fa0617f874 100644
--- a/protocols/VKontakte/src/vk_pollserver.cpp
+++ b/protocols/VKontakte/src/vk_pollserver.cpp
@@ -116,7 +116,11 @@ void CVkProto::PollUpdates(const JSONNode &jnUpdates)
hContact = FindUser(uid);
if (hContact != NULL) {
setDword(hContact, "LastMsgReadTime", time(NULL));
- if (!ServiceExists("MessageState/DummyService"))
+ if (ServiceExists(MS_MESSAGESTATE_UPDATE)) {
+ MessageReadData data(time(NULL), MRD_TYPE_READTIME);
+ CallService(MS_MESSAGESTATE_UPDATE, hContact, (LPARAM)&data);
+ }
+ else
SetSrmmReadStatus(hContact);
if (m_bUserForceOnlineOnActivity)
SetInvisible(hContact);
diff --git a/protocols/VKontakte/src/vk_proto.cpp b/protocols/VKontakte/src/vk_proto.cpp
index f8d555a907..d334c71cbc 100644
--- a/protocols/VKontakte/src/vk_proto.cpp
+++ b/protocols/VKontakte/src/vk_proto.cpp
@@ -544,7 +544,7 @@ void CVkProto::OnReceiveAuthRequest(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *
{
debugLogA("CVkProto::OnReceiveAuthRequest %d", reply->resultCode);
CVkSendMsgParam *param = (CVkSendMsgParam*)pReq->pUserInfo;
- if (reply->resultCode == 200) {
+ if (reply->resultCode == 200 && param) {
JSONNode jnRoot;
const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
if (jnResponse) {
@@ -560,7 +560,7 @@ void CVkProto::OnReceiveAuthRequest(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *
}
}
else {
- switch (param->iCount) {
+ switch (pReq->m_iErrorCode) {
case VKERR_HIMSELF_AS_FRIEND:
MsgPopup(param->hContact, TranslateT("You cannot add yourself as friend"), TranslateT("Error"), true);
break;
@@ -573,8 +573,11 @@ void CVkProto::OnReceiveAuthRequest(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *
}
}
}
- if (!pReq->bNeedsRestart)
+
+ if (param && (!pReq->bNeedsRestart || m_bTerminated)) {
delete param;
+ pReq->pUserInfo = NULL;
+ }
}
int CVkProto::Authorize(MEVENT hDbEvent)
diff --git a/protocols/VKontakte/src/vk_proto.h b/protocols/VKontakte/src/vk_proto.h
index e646312f2f..84fccf2644 100644
--- a/protocols/VKontakte/src/vk_proto.h
+++ b/protocols/VKontakte/src/vk_proto.h
@@ -15,6 +15,9 @@ 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"
+#pragma once
+
#define PS_CREATECHAT "/CreateNewChat"
#define PS_LOADVKNEWS "/LoadVKNews"
#define PS_GETSERVERHISTORY "/SyncHistory"
@@ -36,215 +39,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define MAXHISTORYMIDSPERONE 175
#define MAX_RETRIES 10
-struct CVkProto;
-typedef void (CVkProto::*VK_REQUEST_HANDLER)(NETLIBHTTPREQUEST*, struct AsyncHttpRequest*);
-
-struct AsyncHttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject
-{
- enum RequestPriority { rpLow, rpMedium, rpHigh };
-
- AsyncHttpRequest();
- AsyncHttpRequest(CVkProto*, int iRequestType, LPCSTR szUrl, bool bSecure, VK_REQUEST_HANDLER pFunc, RequestPriority rpPriority = rpMedium);
- ~AsyncHttpRequest();
-
- void AddHeader(LPCSTR, LPCSTR);
- void Redirect(NETLIBHTTPREQUEST*);
-
- CMStringA m_szUrl;
- CMStringA m_szParam;
- VK_REQUEST_HANDLER m_pFunc;
- void *pUserInfo;
- int m_iRetry;
- RequestPriority m_priority;
- static ULONG m_reqCount;
- ULONG m_reqNum;
- bool m_bApiReq;
- bool bExpUrlEncode;
- bool bNeedsRestart, bIsMainConn;
-};
-
-struct PARAM
-{
- LPCSTR szName;
- __forceinline PARAM(LPCSTR _name) : szName(_name)
- {}
-};
-
-struct INT_PARAM : public PARAM
-{
- int iValue;
- __forceinline INT_PARAM(LPCSTR _name, int _value) :
- PARAM(_name), iValue(_value)
- {}
-};
-AsyncHttpRequest* operator<<(AsyncHttpRequest*, const INT_PARAM&);
-
-struct CHAR_PARAM : public PARAM
-{
- LPCSTR szValue;
- __forceinline CHAR_PARAM(LPCSTR _name, LPCSTR _value) :
- PARAM(_name), szValue(_value)
- {}
-};
-AsyncHttpRequest* operator<<(AsyncHttpRequest*, const CHAR_PARAM&);
-
-struct TCHAR_PARAM : public PARAM
-{
- LPCTSTR tszValue;
- __forceinline TCHAR_PARAM(LPCSTR _name, LPCTSTR _value) :
- PARAM(_name), tszValue(_value)
- {}
-};
-AsyncHttpRequest* operator<<(AsyncHttpRequest*, const TCHAR_PARAM&);
-
-struct CVkSendMsgParam
-{
- CVkSendMsgParam(MCONTACT _p1, int _p2 = 0, int _p3 = 0) :
- hContact(_p1),
- iMsgID(_p2),
- iCount(_p3)
- {}
-
- MCONTACT hContact;
- int iMsgID;
- int iCount;
-};
-
-struct CVkChatMessage : public MZeroedObject
-{
- CVkChatMessage(int _id) :
- m_mid(_id),
- m_uid(0),
- m_date(0),
- m_bHistory(false),
- m_bIsAction(false)
- {}
-
- int m_mid, m_uid, m_date;
- bool m_bHistory, m_bIsAction;
- ptrT m_tszBody;
-};
-
-struct CVkChatUser : public MZeroedObject
-{
- CVkChatUser(int _id) :
- m_uid(_id),
- m_bDel(false),
- m_bUnknown(false)
- {}
-
- int m_uid;
- bool m_bDel, m_bUnknown;
- ptrT m_tszNick;
-};
-
-struct CVkChatInfo : public MZeroedObject
-{
- CVkChatInfo(int _id) :
- m_users(10, NumericKeySortT),
- m_msgs(10, NumericKeySortT),
- m_chatid(_id),
- m_admin_id(0),
- m_bHistoryRead(0),
- m_hContact(INVALID_CONTACT_ID)
- {}
-
- int m_chatid, m_admin_id;
- bool m_bHistoryRead;
- ptrT m_tszTopic, m_tszId;
- MCONTACT m_hContact;
- OBJLIST<CVkChatUser> m_users;
- OBJLIST<CVkChatMessage> m_msgs;
-
- CVkChatUser* GetUserById(LPCTSTR);
-};
-
-struct CVkFileUploadParam {
- enum VKFileType {typeInvalid, typeImg, typeAudio, typeDoc, typeNotSupported};
- TCHAR* FileName;
- TCHAR* Desc;
- char* atr;
- char* fname;
- MCONTACT hContact;
- VKFileType filetype;
- int iErrorCode;
-
- CVkFileUploadParam(MCONTACT _hContact, const TCHAR* _desc, TCHAR** _files);
- ~CVkFileUploadParam();
- VKFileType GetType();
- __forceinline bool IsAccess() { return ::_taccess(FileName, 0) == 0; }
- __forceinline char* atrName() { return atr; }
- __forceinline char* fileName() { return fname; }
-};
-
-struct CVkUserInfo : public MZeroedObject {
- CVkUserInfo(LONG _UserId) :
- m_UserId(_UserId),
- m_bIsGroup(false)
- {}
-
- CVkUserInfo(LONG _UserId, bool _bIsGroup, CMString& _tszUserNick, CMString& _tszLink, MCONTACT _hContact = NULL) :
- m_UserId(_UserId),
- m_bIsGroup(_bIsGroup),
- m_tszUserNick(_tszUserNick),
- m_tszLink(_tszLink),
- m_hContact(_hContact)
- {}
-
- LONG m_UserId;
- MCONTACT m_hContact;
- CMString m_tszUserNick;
- CMString m_tszLink;
- bool m_bIsGroup;
-};
-
-enum VKObjType { vkNull, vkPost, vkPhoto, vkVideo, vkComment, vkTopic, vkUsers, vkCopy, vkInvite };
-
-struct CVKNotification {
- TCHAR *ptszType;
- VKObjType vkParent, vkFeedback;
- TCHAR *ptszTranslate;
-};
-
-struct CVKNewsItem : public MZeroedObject {
- CVKNewsItem() :
- tDate(NULL),
- vkUser(NULL),
- bIsGroup(false),
- bIsRepost(false),
- vkFeedbackType(vkNull),
- vkParentType(vkNull)
- {}
-
- CMString tszId;
- time_t tDate;
- CVkUserInfo *vkUser;
- CMString tszText;
- CMString tszLink;
- CMString tszType;
- VKObjType vkFeedbackType, vkParentType;
- bool bIsGroup;
- bool bIsRepost;
-};
-
-enum VKBBCType { vkbbcB, vkbbcI, vkbbcS, vkbbcU, vkbbcImg, vkbbcUrl, vkbbcSize, vkbbcColor };
-enum BBCSupport { bbcNo, bbcBasic, bbcAdvanced };
-
-struct CVKBBCItem {
- VKBBCType vkBBCType;
- BBCSupport vkBBCSettings;
- TCHAR *ptszTempate;
-};
-
-struct TFakeAckParams
-{
- __inline TFakeAckParams(MCONTACT _hContact, int _msgid) :
- hContact(_hContact), msgid(_msgid)
- {}
-
- MCONTACT hContact;
- int msgid;
-};
struct CVkProto : public PROTO<CVkProto>
{
@@ -336,13 +130,14 @@ struct CVkProto : public PROTO<CVkProto>
void __cdecl SearchBasicThread(void* id);
void __cdecl SearchByMailThread(void* email);
void __cdecl SearchThread(void* p);
+ void FreeProtoShearchStruct(PROTOSEARCHBYNAME *pParam);
void OnSearch(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
void OnSearchByMail(NETLIBHTTPREQUEST *, AsyncHttpRequest *);
//==== Files Upload ==================================================================
void __cdecl SendFileThread(void *p);
- void SendFileFiled(CVkFileUploadParam *fup, TCHAR* reason = NULL);
+ void SendFileFiled(CVkFileUploadParam *fup, int ErrorCode);
void OnReciveUploadServer(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
void OnReciveUpload(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
void OnReciveUploadFile(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
diff --git a/protocols/VKontakte/src/vk_search.cpp b/protocols/VKontakte/src/vk_search.cpp
index dbd6ff57b9..9180ca6c1c 100644
--- a/protocols/VKontakte/src/vk_search.cpp
+++ b/protocols/VKontakte/src/vk_search.cpp
@@ -85,17 +85,23 @@ void __cdecl CVkProto::SearchThread(void* p)
Push(pReq);
}
+void CVkProto::FreeProtoShearchStruct(PROTOSEARCHBYNAME *pParam)
+{
+ if (!pParam)
+ return;
+
+ mir_free(pParam->pszFirstName);
+ mir_free(pParam->pszLastName);
+ mir_free(pParam->pszNick);
+ delete pParam;
+}
+
void CVkProto::OnSearch(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
PROTOSEARCHBYNAME *pParam = (PROTOSEARCHBYNAME *)pReq->pUserInfo;
debugLogA("CVkProto::OnSearch %d", reply->resultCode);
if (reply->resultCode != 200) {
- if (pParam) {
- mir_free(pParam->pszFirstName);
- mir_free(pParam->pszLastName);
- mir_free(pParam->pszNick);
- delete pParam;
- }
+ FreeProtoShearchStruct(pParam);
ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)1);
return;
}
@@ -103,12 +109,7 @@ void CVkProto::OnSearch(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
JSONNode jnRoot;
const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
if (!jnResponse) {
- if (pParam) {
- mir_free(pParam->pszFirstName);
- mir_free(pParam->pszLastName);
- mir_free(pParam->pszNick);
- delete pParam;
- }
+ FreeProtoShearchStruct(pParam);
ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)1);
return;
}
@@ -148,12 +149,7 @@ void CVkProto::OnSearch(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
}
ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)1);
- if (pParam) {
- mir_free(pParam->pszFirstName);
- mir_free(pParam->pszLastName);
- mir_free(pParam->pszNick);
- delete pParam;
- }
+ FreeProtoShearchStruct(pParam);
}
void CVkProto::OnSearchByMail(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
diff --git a/protocols/VKontakte/src/vk_struct.cpp b/protocols/VKontakte/src/vk_struct.cpp
new file mode 100644
index 0000000000..ee3163de4c
--- /dev/null
+++ b/protocols/VKontakte/src/vk_struct.cpp
@@ -0,0 +1,156 @@
+/*
+Copyright (c) 2013-15 Miranda NG project (http://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"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+ULONG AsyncHttpRequest::m_reqCount = 0;
+
+AsyncHttpRequest::AsyncHttpRequest()
+{
+ cbSize = sizeof(NETLIBHTTPREQUEST);
+ m_bApiReq = true;
+ AddHeader("Connection", "keep-alive");
+ AddHeader("Accept-Encoding", "booo");
+ pUserInfo = NULL;
+ m_iRetry = MAX_RETRIES;
+ m_iErrorCode = 0;
+ bNeedsRestart = false;
+ bIsMainConn = false;
+ m_pFunc = NULL;
+ bExpUrlEncode = false;
+ m_reqNum = ::InterlockedIncrement(&m_reqCount);
+ m_priority = rpLow;
+}
+
+AsyncHttpRequest::AsyncHttpRequest(CVkProto *ppro, int iRequestType, LPCSTR _url, bool bSecure, VK_REQUEST_HANDLER pFunc, RequestPriority rpPriority)
+{
+ cbSize = sizeof(NETLIBHTTPREQUEST);
+ m_bApiReq = true;
+ bIsMainConn = false;
+ bExpUrlEncode = ppro->m_bUseNonStandardUrlEncode;
+ AddHeader("Connection", "keep-alive");
+ AddHeader("Accept-Encoding", "booo");
+
+ flags = VK_NODUMPHEADERS | NLHRF_DUMPASTEXT | NLHRF_HTTP11 | NLHRF_REDIRECT;
+ if (bSecure)
+ flags |= NLHRF_SSL;
+
+ if (*_url == '/') { // relative url leads to a site
+ m_szUrl = ((bSecure) ? "https://" : "http://") + CMStringA("api.vk.com");
+ m_szUrl += _url;
+ bIsMainConn = true;
+ }
+ else m_szUrl = _url;
+
+ if (bSecure)
+ this << CHAR_PARAM("access_token", ppro->m_szAccessToken);
+
+ requestType = iRequestType;
+ m_pFunc = pFunc;
+ pUserInfo = NULL;
+ m_iRetry = MAX_RETRIES;
+ m_iErrorCode = 0;
+ bNeedsRestart = false;
+ m_reqNum = ::InterlockedIncrement(&m_reqCount);
+ m_priority = rpPriority;
+}
+
+AsyncHttpRequest::~AsyncHttpRequest()
+{
+ for (int i = 0; i < headersCount; i++) {
+ mir_free(headers[i].szName);
+ mir_free(headers[i].szValue);
+ }
+ mir_free(headers);
+ mir_free(pData);
+}
+
+void AsyncHttpRequest::AddHeader(LPCSTR szName, LPCSTR szValue)
+{
+ headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1));
+ headers[headersCount].szName = mir_strdup(szName);
+ headers[headersCount].szValue = mir_strdup(szValue);
+ headersCount++;
+}
+
+void AsyncHttpRequest::Redirect(NETLIBHTTPREQUEST *nhr)
+{
+ for (int i = 0; i < nhr->headersCount; i++) {
+ LPCSTR szValue = nhr->headers[i].szValue;
+ if (!_stricmp(nhr->headers[i].szName, "Location"))
+ m_szUrl = szValue;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+CVkFileUploadParam::CVkFileUploadParam(MCONTACT _hContact, const TCHAR* _desc, TCHAR** _files) :
+ hContact(_hContact),
+ Desc(mir_tstrdup(_desc)),
+ FileName(mir_tstrdup(_files[0]))
+{}
+
+CVkFileUploadParam::~CVkFileUploadParam()
+{
+ mir_free(Desc);
+ mir_free(FileName);
+ mir_free(atr);
+ mir_free(fname);
+}
+
+CVkFileUploadParam::VKFileType CVkFileUploadParam::GetType()
+{
+ if (filetype != typeInvalid)
+ return filetype;
+
+ TCHAR img[] = _T(".jpg .jpeg .png .bmp");
+ TCHAR audio[] = _T(".mp3");
+
+ TCHAR DRIVE[3], DIR[256], FNAME[256], EXT[256];
+ _tsplitpath(FileName, DRIVE, DIR, FNAME, EXT);
+
+ T2Utf pszFNAME(FNAME), pszEXT(EXT);
+ CMStringA fn(FORMAT, "%s%s", pszFNAME, pszEXT);
+ fname = mir_strdup(fn);
+
+ if (tlstrstr(img, EXT)) {
+ filetype = CVkFileUploadParam::typeImg;
+ atr = mir_strdup("photo");
+ }
+ else if (tlstrstr(audio, EXT)) {
+ filetype = CVkFileUploadParam::typeAudio;
+ atr = mir_strdup("file");
+ }
+ else {
+ filetype = CVkFileUploadParam::typeDoc;
+ atr = mir_strdup("file");
+ }
+
+ return filetype;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+CVkChatUser* CVkChatInfo::GetUserById(LPCTSTR ptszId)
+{
+ int user_id = _ttoi(ptszId);
+ return m_users.find((CVkChatUser*)&user_id);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file
diff --git a/protocols/VKontakte/src/vk_struct.h b/protocols/VKontakte/src/vk_struct.h
new file mode 100644
index 0000000000..ea93b42d02
--- /dev/null
+++ b/protocols/VKontakte/src/vk_struct.h
@@ -0,0 +1,225 @@
+/*
+Copyright (c) 2013-15 Miranda NG project (http://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"
+#pragma once
+
+typedef void (CVkProto::*VK_REQUEST_HANDLER)(NETLIBHTTPREQUEST*, struct AsyncHttpRequest*);
+
+struct AsyncHttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject
+{
+ enum RequestPriority { rpLow, rpMedium, rpHigh };
+
+ AsyncHttpRequest();
+ AsyncHttpRequest(CVkProto*, int iRequestType, LPCSTR szUrl, bool bSecure, VK_REQUEST_HANDLER pFunc, RequestPriority rpPriority = rpMedium);
+ ~AsyncHttpRequest();
+
+ void AddHeader(LPCSTR, LPCSTR);
+ void Redirect(NETLIBHTTPREQUEST*);
+
+ CMStringA m_szUrl;
+ CMStringA m_szParam;
+ VK_REQUEST_HANDLER m_pFunc;
+ void *pUserInfo;
+ int m_iRetry;
+ int m_iErrorCode;
+ RequestPriority m_priority;
+ static ULONG m_reqCount;
+ ULONG m_reqNum;
+ bool m_bApiReq;
+ bool bExpUrlEncode;
+ bool bNeedsRestart, bIsMainConn;
+};
+
+struct PARAM
+{
+ LPCSTR szName;
+ __forceinline PARAM(LPCSTR _name) : szName(_name)
+ {}
+};
+
+struct INT_PARAM : public PARAM
+{
+ int iValue;
+ __forceinline INT_PARAM(LPCSTR _name, int _value) :
+ PARAM(_name), iValue(_value)
+ {}
+};
+AsyncHttpRequest* operator<<(AsyncHttpRequest*, const INT_PARAM&);
+
+struct CHAR_PARAM : public PARAM
+{
+ LPCSTR szValue;
+ __forceinline CHAR_PARAM(LPCSTR _name, LPCSTR _value) :
+ PARAM(_name), szValue(_value)
+ {}
+};
+AsyncHttpRequest* operator<<(AsyncHttpRequest*, const CHAR_PARAM&);
+
+struct TCHAR_PARAM : public PARAM
+{
+ LPCTSTR tszValue;
+ __forceinline TCHAR_PARAM(LPCSTR _name, LPCTSTR _value) :
+ PARAM(_name), tszValue(_value)
+ {}
+};
+AsyncHttpRequest* operator<<(AsyncHttpRequest*, const TCHAR_PARAM&);
+
+struct CVkFileUploadParam : public MZeroedObject {
+ enum VKFileType { typeInvalid, typeImg, typeAudio, typeDoc, typeNotSupported };
+ TCHAR* FileName;
+ TCHAR* Desc;
+ char* atr;
+ char* fname;
+ MCONTACT hContact;
+ VKFileType filetype;
+
+ CVkFileUploadParam(MCONTACT _hContact, const TCHAR* _desc, TCHAR** _files);
+ ~CVkFileUploadParam();
+ VKFileType GetType();
+ __forceinline bool IsAccess() { return ::_taccess(FileName, 0) == 0; }
+ __forceinline char* atrName() { return atr; }
+ __forceinline char* fileName() { return fname; }
+};
+
+struct CVkSendMsgParam : public MZeroedObject
+{
+ CVkSendMsgParam(MCONTACT _hContact, int _iMsgID = 0, int _iCount = 0) :
+ hContact(_hContact),
+ iMsgID(_iMsgID),
+ iCount(_iCount)
+ {}
+
+ CVkSendMsgParam(MCONTACT _hContact, CVkFileUploadParam *_pFUP) :
+ hContact(_hContact),
+ iMsgID(-1),
+ pFUP(_pFUP)
+ {}
+
+ MCONTACT hContact;
+ int iMsgID;
+ int iCount;
+ CVkFileUploadParam *pFUP;
+};
+
+struct CVkChatMessage : public MZeroedObject
+{
+ CVkChatMessage(int _id) :
+ m_mid(_id),
+ m_uid(0),
+ m_date(0),
+ m_bHistory(false),
+ m_bIsAction(false)
+ {}
+
+ int m_mid, m_uid, m_date;
+ bool m_bHistory, m_bIsAction;
+ ptrT m_tszBody;
+};
+
+struct CVkChatUser : public MZeroedObject
+{
+ CVkChatUser(int _id) :
+ m_uid(_id),
+ m_bDel(false),
+ m_bUnknown(false)
+ {}
+
+ int m_uid;
+ bool m_bDel, m_bUnknown;
+ ptrT m_tszNick;
+};
+
+struct CVkChatInfo : public MZeroedObject
+{
+ CVkChatInfo(int _id) :
+ m_users(10, NumericKeySortT),
+ m_msgs(10, NumericKeySortT),
+ m_chatid(_id),
+ m_admin_id(0),
+ m_bHistoryRead(0),
+ m_hContact(INVALID_CONTACT_ID)
+ {}
+
+ int m_chatid, m_admin_id;
+ bool m_bHistoryRead;
+ ptrT m_tszTopic, m_tszId;
+ MCONTACT m_hContact;
+ OBJLIST<CVkChatUser> m_users;
+ OBJLIST<CVkChatMessage> m_msgs;
+
+ CVkChatUser* GetUserById(LPCTSTR);
+};
+
+struct CVkUserInfo : public MZeroedObject {
+ CVkUserInfo(LONG _UserId) :
+ m_UserId(_UserId),
+ m_bIsGroup(false)
+ {}
+
+ CVkUserInfo(LONG _UserId, bool _bIsGroup, CMString& _tszUserNick, CMString& _tszLink, MCONTACT _hContact = NULL) :
+ m_UserId(_UserId),
+ m_bIsGroup(_bIsGroup),
+ m_tszUserNick(_tszUserNick),
+ m_tszLink(_tszLink),
+ m_hContact(_hContact)
+ {}
+
+ LONG m_UserId;
+ MCONTACT m_hContact;
+ CMString m_tszUserNick;
+ CMString m_tszLink;
+ bool m_bIsGroup;
+};
+
+enum VKObjType { vkNull, vkPost, vkPhoto, vkVideo, vkComment, vkTopic, vkUsers, vkCopy, vkInvite };
+
+struct CVKNotification {
+ TCHAR *ptszType;
+ VKObjType vkParent, vkFeedback;
+ TCHAR *ptszTranslate;
+};
+
+struct CVKNewsItem : public MZeroedObject {
+ CVKNewsItem() :
+ tDate(NULL),
+ vkUser(NULL),
+ bIsGroup(false),
+ bIsRepost(false),
+ vkFeedbackType(vkNull),
+ vkParentType(vkNull)
+ {}
+
+ CMString tszId;
+ time_t tDate;
+ CVkUserInfo *vkUser;
+ CMString tszText;
+ CMString tszLink;
+ CMString tszType;
+ VKObjType vkFeedbackType, vkParentType;
+ bool bIsGroup;
+ bool bIsRepost;
+};
+
+enum VKBBCType { vkbbcB, vkbbcI, vkbbcS, vkbbcU, vkbbcImg, vkbbcUrl, vkbbcSize, vkbbcColor };
+enum BBCSupport { bbcNo, bbcBasic, bbcAdvanced };
+
+struct CVKBBCItem {
+ VKBBCType vkBBCType;
+ BBCSupport vkBBCSettings;
+ TCHAR *ptszTempate;
+}; \ No newline at end of file
diff --git a/protocols/VKontakte/src/vk_thread.cpp b/protocols/VKontakte/src/vk_thread.cpp
index 726551d3fe..7b257053f4 100644
--- a/protocols/VKontakte/src/vk_thread.cpp
+++ b/protocols/VKontakte/src/vk_thread.cpp
@@ -592,7 +592,7 @@ void CVkProto::OnReceiveDeleteFriend(NETLIBHTTPREQUEST* reply, AsyncHttpRequest*
{
debugLogA("CVkProto::OnReceiveDeleteFriend %d", reply->resultCode);
CVkSendMsgParam *param = (CVkSendMsgParam*)pReq->pUserInfo;
- if (reply->resultCode == 200) {
+ if (reply->resultCode == 200 && param) {
JSONNode jnRoot;
const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
if (jnResponse) {
@@ -621,7 +621,11 @@ void CVkProto::OnReceiveDeleteFriend(NETLIBHTTPREQUEST* reply, AsyncHttpRequest*
}
}
}
- delete param;
+
+ if (param && (!pReq->bNeedsRestart || m_bTerminated)) {
+ delete param;
+ pReq->pUserInfo = NULL;
+ }
}
INT_PTR __cdecl CVkProto::SvcBanUser(WPARAM hContact, LPARAM)