/*
Copyright (c) 2013-14 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 .
*/
#include "stdafx.h"
TCHAR* CVkProto::GetUserStoredPassword()
{
ptrA szRawPass( getStringA("Password"));
return (szRawPass != NULL) ? mir_utf8decodeT(szRawPass) : NULL;
}
void CVkProto::SetAllContactStatuses(int iStatus)
{
for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) {
if (isChatRoom(hContact))
SetChatStatus(hContact, iStatus);
else if (getWord(hContact, "Status", 0) != iStatus)
setWord(hContact, "Status", iStatus);
}
}
MCONTACT CVkProto::FindUser(LONG dwUserid, bool bCreate)
{
if (!dwUserid)
return NULL;
for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) {
LONG dbUserid = getDword(hContact, "ID", -1);
if (dbUserid == -1)
continue;
if (dbUserid == dwUserid)
return hContact;
}
if (!bCreate)
return NULL;
MCONTACT hNewContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0);
CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hNewContact, (LPARAM)m_szModuleName);
setDword(hNewContact, "ID", dwUserid);
db_set_ts(hNewContact, "CList", "Group", m_defaultGroup);
return hNewContact;
}
bool CVkProto::CheckMid(int guid)
{
for (int i=m_sendIds.getCount()-1; i >= 0; i--)
if ((int)m_sendIds[i] == guid) {
m_sendIds.remove(i);
return true;
}
return false;
}
LPCSTR findHeader(NETLIBHTTPREQUEST *pReq, LPCSTR szField)
{
for (int i=0; i < pReq->headersCount; i++)
if (!_stricmp(pReq->headers[i].szName, szField))
return pReq->headers[i].szValue;
return NULL;
}
JSONNODE* CVkProto::CheckJsonResponse(AsyncHttpRequest *pReq, NETLIBHTTPREQUEST *reply, JSONROOT &pRoot)
{
pRoot.Parse(reply->pData);
if (pRoot == NULL)
return NULL;
if (!CheckJsonResult(pReq, reply, pRoot))
return NULL;
return json_get(pRoot, "response");
}
bool CVkProto::CheckJsonResult(AsyncHttpRequest *pReq, NETLIBHTTPREQUEST *reply, JSONNODE *pNode)
{
if (pNode == NULL)
return false;
JSONNODE *pError = json_get(pNode, "error"), *pErrorCode = json_get(pError, "error_code");
if (pError == NULL || pErrorCode == NULL)
return true;
int iErrorCode = json_as_int(pErrorCode);
switch (iErrorCode){
case VKERR_AUTHORIZATION_FAILED:
ConnectionFailed(LOGINERR_WRONGPASSWORD);
break;
case VKERR_CAPTCHA_NEEDED:
ApplyCaptcha(pReq, pError);
break;
case VKERR_UNKNOWN:
case VKERR_TOO_MANY_REQ_PER_SEC:
case VKERR_FLOOD_CONTROL:
case VKERR_INTERNAL_SERVER_ERR:
pReq->bNeedsRestart = true;
Sleep(500); //Pause for fix err
break;
case VKERR_HIMSELF_AS_FRIEND:
case VKERR_YOU_ON_BLACKLIST:
case VKERR_USER_ON_BLACKLIST:
CVkSendMsgParam *param = (CVkSendMsgParam*)pReq->pUserInfo;
if (param)
param->iCount = iErrorCode;
break;
}
return iErrorCode == 0;
}
void CVkProto::OnReceiveSmth(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
JSONROOT pRoot;
JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot);
debugLogA("CVkProto::OnReceiveSmth %s", json_as_string(pResponse));
}
/////////////////////////////////////////////////////////////////////////////////////////
static IconItem iconList[] =
{
{ LPGEN("Captcha form icon"), "key", IDI_KEYS }
};
void InitIcons()
{
Icon_Register(hInst, LPGEN("Protocols")"/"LPGEN("VKontakte"), iconList, SIZEOF(iconList), "VKontakte");
}
HANDLE GetIconHandle(int iCommand)
{
for (int i=0; i < SIZEOF(iconList); i++)
if (iconList[i].defIconID == iCommand)
return iconList[i].hIcolib;
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Quick & dirty form parser
static CMStringA getAttr(char *szSrc, LPCSTR szAttrName)
{
char *pEnd = strchr(szSrc, '>');
if (pEnd == NULL)
return "";
*pEnd = 0;
char *p1 = strstr(szSrc, szAttrName);
if (p1 == NULL) {
LBL_NotFound:
*pEnd = '>';
return "";
}
p1 += strlen(szAttrName);
if (p1[0] != '=' || p1[1] != '\"')
goto LBL_NotFound;
p1 += 2;
char *p2 = strchr(p1, '\"');
if (p2 == NULL)
goto LBL_NotFound;
*pEnd = '>';
return CMStringA(p1, (int)(p2-p1));
}
bool CVkProto::AutoFillForm(char *pBody, CMStringA &szAction, CMStringA& szResult)
{
szResult.Empty();
char *pFormBeg = strstr(pBody, "