Example #1
0
void CVkProto::OnReceiveMyInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveMyInfo %d", reply->resultCode);
	if (reply->resultCode != 200) {
		ConnectionFailed(LOGINERR_WRONGPASSWORD);
		return;
	}

	JSONNode jnRoot;
	const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
	if (!jnResponse)
		return;
	
	const JSONNode &jnUser = *(jnResponse.begin());


	m_myUserId = jnUser["id"].as_int();
	setDword("ID", m_myUserId);
		
	OnLoggedIn();
	RetrieveUserInfo(m_myUserId);
	RetrieveUnreadMessages();
	RetrieveFriends();
	RetrievePollingInfo();
}
Example #2
0
void CVkProto::OnReceiveMyInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveMyInfo %d", reply->resultCode);
	if (reply->resultCode != 200) {
		ConnectionFailed(LOGINERR_WRONGPASSWORD);
		return;
	}

	JSONROOT pRoot;
	JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot);
	if (pResponse == NULL)
		return;

	for (size_t i = 0; i < json_size(pResponse); i++) {
		JSONNODE *it = json_at(pResponse, i);
		LPCSTR id = json_name(it);
		if (!_stricmp(id, "user_id")) {
			m_myUserId = json_as_int(it);
			setDword("ID", m_myUserId);
		}
	}

	OnLoggedIn();
	RetrieveUserInfo(m_myUserId);
	RetrieveFriends();
	RetrieveUnreadMessages();
	RetrievePollingInfo();
}
Example #3
0
void CVkProto::OnReceiveUserInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveUserInfo %d", reply->resultCode);
	if (reply->resultCode != 200)
		return;

	JSONROOT pRoot;
	JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot);
	if (pResponse == NULL)
		return;

	for (size_t i=0; ; i++) {
		JSONNODE *pRecord = json_at(pResponse, i);
		if (pRecord == NULL) break;

		LONG userid = json_as_int( json_get(pRecord, "uid"));
		if (userid == 0)
			return;

		MCONTACT hContact;
		if (userid == m_myUserId)
			hContact = NULL;
		else if ((hContact = FindUser(userid, false)) == NULL)
			return;

		CMString tszNick;
		ptrT szValue( json_as_string( json_get(pRecord, "first_name")));
		if (szValue) {
			setTString(hContact, "FirstName", szValue);
			tszNick.Append(szValue);
			tszNick.AppendChar(' ');
		}

		if (szValue = json_as_string( json_get(pRecord, "last_name"))) {
			setTString(hContact, "LastName", szValue);
			tszNick.Append(szValue);
		}

		if (!tszNick.IsEmpty())
			setTString(hContact, "Nick", tszNick);
	
		setByte(hContact, "Gender", json_as_int( json_get(pRecord, "sex")) == 2 ? 'M' : 'F');
	
		if (szValue = json_as_string( json_get(pRecord, "bdate"))) {
			int d, m, y;
			if ( _stscanf(szValue, _T("%d.%d.%d"), &d, &m, &y) == 3) {
				setByte(hContact, "BirthDay", d);
				setByte(hContact, "BirthMonth", m);
				setWord(hContact, "BirthYear", y);
			}
		}

		szValue = json_as_string( json_get(pRecord, "photo_medium"));
		SetAvatarUrl(hContact, szValue);
	}
}
Example #4
0
void CVkProto::OnSendChatMsg(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnSendChatMsg %d", reply->resultCode);
	if (reply->resultCode == 200) {
		JSONROOT pRoot;
		JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot);
		if (pResponse != NULL)
			m_sendIds.insert((void*)json_as_int(pResponse));
	}
}
Example #5
0
void CVkProto::OnReceiveFriends(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveFriends %d", reply->resultCode);
	if (reply->resultCode != 200 || !IsOnline())
		return;

	JSONNode jnRoot;
	const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
	if (!jnResponse)
		return;
	
	CVkSendMsgParam *param = (CVkSendMsgParam *)pReq->pUserInfo;
	bool bCleanContacts = getBool("AutoClean") || (param->iMsgID != 0);
	delete param;

	LIST<void> arContacts(10, PtrKeySortT);
		
	for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) {
		if (!isChatRoom(hContact))
			setByte(hContact, "Auth", 1);
		db_unset(hContact, m_szModuleName, "ReqAuth");
		SetMirVer(hContact, -1);
		if (bCleanContacts && !isChatRoom(hContact))
			arContacts.insert((HANDLE)hContact);
	}

	const JSONNode &jnItems = jnResponse["items"];

	if (jnItems)
		for (auto it = jnItems.begin(); it != jnItems.end(); ++it) {
			MCONTACT hContact = SetContactInfo((*it), true);

			if (hContact == NULL || hContact == INVALID_CONTACT_ID)
				continue;

			arContacts.remove((HANDLE)hContact);
			setByte(hContact, "Auth", 0);
		}

	if (bCleanContacts)
		for (int i = 0; i < arContacts.getCount(); i++) {
			MCONTACT hContact = (UINT_PTR)arContacts[i];
			LONG userID = getDword(hContact, "ID", -1);
			if (userID == m_myUserId || userID == VK_FEED_USER)
				continue;
			CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact);
		}
	
	arContacts.destroy();
}
Example #6
0
void CVkProto::OnReceiveUnreadNews(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
    debugLogA("CVkProto::OnReceiveUnreadNews %d", reply->resultCode);
    db_unset(NULL, m_szModuleName, "LastNewsReqTime");
    if (reply->resultCode != 200)
        return;

    JSONNode jnRoot;
    const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
    if (!jnResponse)
        return;

    OBJLIST<CVkUserInfo> vkUsers(5, NumericKeySortT);
    CreateVkUserInfoList(vkUsers, jnResponse);

    const JSONNode &jnItems = jnResponse["items"];

    OBJLIST<CVKNewsItem> vkNews(5, sttCompareVKNewsItems);
    if (jnItems)
        for (auto it = jnItems.begin(); it != jnItems.end(); ++it) {
            CVKNewsItem *vkNewsItem = GetVkNewsItem((*it), vkUsers);
            if (!vkNewsItem)
                continue;
            CVKNewsItem *vkNewsFoundItem = vkNews.find(vkNewsItem);
            if (vkNewsFoundItem == NULL)
                vkNews.insert(vkNewsItem);
            else if (vkNewsFoundItem->tszType == _T("wall_photo") && vkNewsItem->tszType == _T("post")) {
                vkNews.remove(vkNewsFoundItem);
                vkNews.insert(vkNewsItem);
            }
            else
                delete vkNewsItem;
        }

    bool bNewsAdded = false;
    for (int i = 0; i < vkNews.getCount(); i++)
        if (!(m_bNewsSourceNoReposts && vkNews[i].bIsRepost)) {
            AddFeedEvent(vkNews[i]);
            bNewsAdded = true;
        }

    if (bNewsAdded)
        AddCListEvent(true);

    setDword("LastNewsTime", time(NULL));

    vkNews.destroy();
    vkUsers.destroy();
}
Example #7
0
void CVkProto::OnCreateNewChat(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnCreateNewChat %d", reply->resultCode);
	if (reply->resultCode != 200)
		return;

	JSONROOT pRoot;
	JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot);
	if (pResponse == NULL)
		return;

	int chat_id = json_as_int(pResponse);
	if (chat_id != NULL)
		AppendChat(chat_id, NULL);
}
Example #8
0
void CVkProto::OnSendMessage(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	int iResult = ACKRESULT_FAILED;
	if (pReq->pUserInfo == NULL) {
		debugLogA("CVkProto::OnSendMessage failed! (pUserInfo == NULL)");
		return;
	}
	CVkSendMsgParam *param = (CVkSendMsgParam *)pReq->pUserInfo;

	debugLogA("CVkProto::OnSendMessage %d", reply->resultCode);
	if (reply->resultCode == 200) {
		JSONNode jnRoot;
		const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
		if (jnResponse) {
			UINT mid;
			if (jnResponse.type() != JSON_STRING) 
				mid = jnResponse.as_int();
			else if (_stscanf(jnResponse.as_mstring(), _T("%d"), &mid) != 1)
				mid = 0;

			if (param->iMsgID != -1)
				m_sendIds.insert((HANDLE)mid);

			if (mid > getDword(param->hContact, "lastmsgid"))
				setDword(param->hContact, "lastmsgid", mid);

			if (m_vkOptions.iMarkMessageReadOn >= MarkMsgReadOn::markOnReply)
				MarkMessagesRead(param->hContact);

			iResult = ACKRESULT_SUCCESS;
		}
	}

	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 || m_bTerminated) {
		delete param;
		pReq->pUserInfo = NULL;
	}
}
Example #9
0
void CVkProto::OnReceiveStatus(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveStatus %d", reply->resultCode);
	if (reply->resultCode != 200)
		return;
	JSONNode jnRoot;
	const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
	if (!jnResponse)
		return;

	const JSONNode &jnAudio = jnResponse["audio"];
	if (!jnAudio) {
		CMString tszStatusText(jnResponse["text"].as_mstring());
		if (tszStatusText[0] != TCHAR(9835))
			setTString("OldStatusMsg", tszStatusText);
	}
}
Example #10
0
void CVkProto::OnReceivePollingInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceivePollingInfo %d", reply->resultCode);
	if (reply->resultCode != 200)
		return;

	JSONROOT pRoot;
	JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot);
	if (pResponse == NULL)
		return;

	m_pollingTs = mir_t2a(ptrT(json_as_string(json_get(pResponse, "ts"))));
	m_pollingKey = mir_t2a(ptrT(json_as_string(json_get(pResponse, "key"))));
	m_pollingServer = mir_t2a(ptrT(json_as_string(json_get(pResponse, "server"))));
	if (!m_hPollingThread && m_pollingTs != NULL && m_pollingKey != NULL && m_pollingServer != NULL)
		m_hPollingThread = ForkThreadEx(&CVkProto::PollingThread, NULL, NULL);
}
Example #11
0
void CVkProto::OnSendMessage(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	int iResult = ACKRESULT_FAILED;

	debugLogA("CVkProto::OnSendMessage %d", reply->resultCode);
	if (reply->resultCode == 200) {
		JSONROOT pRoot;
		JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot);
		if (pResponse != NULL) {
			m_sendIds.insert((HANDLE)json_as_int(pResponse));
			iResult = ACKRESULT_SUCCESS;
		}
	}

	if (m_bServerDelivery)
		ProtoBroadcastAck(pReq->pData, ACKTYPE_MESSAGE, iResult, pReq->pUserInfo, 0);
	pReq->pData = NULL;
}
Example #12
0
void CVkProto::OnReceiveAuthRequest(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveAuthRequest %d", reply->resultCode);
	CVkSendMsgParam *param = (CVkSendMsgParam*)pReq->pUserInfo;
	if (reply->resultCode == 200 && param) {
		JSONNode jnRoot;
		const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
		if (jnResponse) {
			int iRet = jnResponse.as_int();
			setByte(param->hContact, "Auth", 0);
			if (iRet == 2) {
				CMString msg,			
					tszNick(ptrT(db_get_tsa(param->hContact, m_szModuleName, "Nick")));
				if (tszNick.IsEmpty())
					tszNick = TranslateT("(Unknown contact)");
				msg.AppendFormat(TranslateT("User %s added as friend"), tszNick);
				MsgPopup(param->hContact, msg, tszNick);
			}
		} 
		else {
			switch (pReq->m_iErrorCode) {
			case VKERR_HIMSELF_AS_FRIEND:
				MsgPopup(param->hContact, TranslateT("You cannot add yourself as friend"), TranslateT("Error"), true);
				break;
			case VKERR_YOU_ON_BLACKLIST:
				MsgPopup(param->hContact, TranslateT("Cannot add this user to friends as they have put you on their blacklist"), TranslateT("Error"), true);
				break;
			case VKERR_USER_ON_BLACKLIST:
				MsgPopup(param->hContact, TranslateT("Cannot add this user to friends as you put him on blacklist"), TranslateT("Error"), true);
				break;
			}
		}
	}

	if (param && (!pReq->bNeedsRestart || m_bTerminated)) {
		delete param;
		pReq->pUserInfo = NULL;
	}
}
Example #13
0
void CVkProto::OnReceiveDeleteFriend(NETLIBHTTPREQUEST* reply, AsyncHttpRequest* pReq)
{
	debugLogA("CVkProto::OnReceiveDeleteFriend %d", reply->resultCode);
	CVkSendMsgParam *param = (CVkSendMsgParam*)pReq->pUserInfo;
	if (reply->resultCode == 200 && param) {
		JSONNode jnRoot;
		const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
		if (jnResponse) {
			CMString tszNick(ptrT(db_get_tsa(param->hContact, m_szModuleName, "Nick")));
			if (tszNick.IsEmpty())
				tszNick = TranslateT("(Unknown contact)");
			CMString msgformat, msg;

			if (jnResponse["success"].as_bool()) {
				if (jnResponse["friend_deleted"].as_bool())
					msgformat = TranslateT("User %s was deleted from your friend list");
				else if (jnResponse["out_request_deleted"].as_bool())
					msgformat = TranslateT("Your request to the user %s was deleted");
				else if (jnResponse["in_request_deleted"].as_bool())
					msgformat = TranslateT("Friend request from the user %s declined");
				else if (jnResponse["suggestion_deleted"].as_bool())
					msgformat = TranslateT("Friend request suggestion for the user %s deleted");

				msg.AppendFormat(msgformat, tszNick);
				MsgPopup(param->hContact, msg, tszNick);
				setByte(param->hContact, "Auth", 1);
			}
			else {
				msg = TranslateT("User or request was not deleted");
				MsgPopup(param->hContact, msg, tszNick);
			}
		}
	}

	if (param && (!pReq->bNeedsRestart || m_bTerminated)) {
		delete param;
		pReq->pUserInfo = NULL;
	}
}
Example #14
0
void CVkProto::OnReceivePollingInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceivePollingInfo %d", reply->resultCode);
	if (reply->resultCode != 200)
		return;

	JSONNode jnRoot;
	JSONNode jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
	if (!jnResponse)
		return;

	char ts[32];
	itoa(jnResponse["ts"].as_int(), ts, 10);

	m_pollingTs = mir_strdup(ts);
	m_pollingKey = mir_t2a(jnResponse["key"].as_mstring());
	m_pollingServer = mir_t2a(jnResponse["server"].as_mstring());

	if (!m_hPollingThread) {
		debugLogA("CVkProto::OnReceivePollingInfo m_hPollingThread is NULL");
		debugLogA("CVkProto::OnReceivePollingInfo m_pollingTs = \'%s' m_pollingKey = \'%s\' m_pollingServer = \'%s\'",
			m_pollingTs ? m_pollingTs : "<NULL>",
			m_pollingKey ? m_pollingKey : "<NULL>",
			m_pollingServer ? m_pollingServer : "<NULL>");
		if (m_pollingTs != NULL && m_pollingKey != NULL && m_pollingServer != NULL) {
			debugLogA("CVkProto::OnReceivePollingInfo PollingThread starting...");
			m_hPollingThread = ForkThreadEx(&CVkProto::PollingThread, NULL, NULL);
		}
		else {
			debugLogA("CVkProto::OnReceivePollingInfo PollingThread not start");
			m_pollingConn = NULL;
			ShutdownSession();
			return;
		}
	}
	else
		debugLogA("CVkProto::OnReceivePollingInfo m_hPollingThread is not NULL");
}
Example #15
0
void CVkProto::OnReceiveHistoryMessages(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveHistoryMessages %d", reply->resultCode);
	if (reply->resultCode != 200 || !pReq->pUserInfo) {
		mir_cslock lck(m_csLoadHistoryTask);
		if (m_iLoadHistoryTask > 0)
			m_iLoadHistoryTask--;
		debugLog(_T("CVkProto::OnReceiveHistoryMessages error m_iLoadHistoryTask=%d"), m_iLoadHistoryTask);
		MsgPopup(NULL, TranslateT("Error loading message history from server"), TranslateT("Error"), true);

		if (m_iLoadHistoryTask == 0 && m_bNotifyForEndLoadingHistoryAllContact) {
			MsgPopup(NULL, TranslateT("Loading messages for all contacts is completed"), TranslateT("Loading history"));
			m_bNotifyForEndLoadingHistoryAllContact = m_bNotifyForEndLoadingHistory = false;
		}

		return;
	}

	JSONNode jnRoot;
	CVkSendMsgParam *param = (CVkSendMsgParam*)pReq->pUserInfo;
	const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
	if (!jnResponse) {
		if (!pReq->bNeedsRestart || m_bTerminated) {
			mir_cslock lck(m_csLoadHistoryTask);
			if (m_iLoadHistoryTask > 0) 
				m_iLoadHistoryTask--;
			
			ptrT ptszNick(db_get_tsa(param->hContact, m_szModuleName, "Nick"));
			CMString str(FORMAT, _T("%s %s %s"), TranslateT("Error loading message history from server"), TranslateT("for"), ptszNick);

			MsgPopup(param->hContact, str, TranslateT("Error"), true);
			debugLog(_T("CVkProto::OnReceiveHistoryMessages error for %s m_iLoadHistoryTask=%d"), ptszNick, m_iLoadHistoryTask);

			if (m_iLoadHistoryTask == 0 && m_bNotifyForEndLoadingHistoryAllContact) {
				MsgPopup(NULL, TranslateT("Loading messages for all contacts is completed"), TranslateT("Loading history"));
				m_bNotifyForEndLoadingHistoryAllContact = m_bNotifyForEndLoadingHistory = false;
			}

			delete param;
			pReq->pUserInfo = NULL;
		}
		return;
	}

	int iTime = jnResponse["datetime"].as_int(); 
	const JSONNode &jnMsgs = jnResponse["items"];
	const JSONNode &jnFUsers = jnResponse["fwd_users"];

	int iLastMsgId = getDword(param->hContact, "lastmsgid", -1);
	time_t tLastReadMessageTime = 0;
	int count = 0;

	for (auto it = jnMsgs.rbegin(); it != jnMsgs.rend(); ++it) {
		const JSONNode &jnMsg = (*it);

		int mid = jnMsg["id"].as_int();
		if (iLastMsgId < mid) 
			iLastMsgId = mid;

		char szMid[40];
		_itoa(mid, szMid, 10);

		CMString tszBody(jnMsg["body"].as_mstring());
		int datetime = jnMsg["date"].as_int();
		int isOut = jnMsg["out"].as_int();
		int isRead = jnMsg["read_state"].as_int(); 
		int uid = jnMsg["user_id"].as_int(); 

		const JSONNode &jnFwdMessages = jnMsg["fwd_messages"];
		if (jnFwdMessages) {
			CMString tszFwdMessages = GetFwdMessages(jnFwdMessages, jnFUsers, m_vkOptions.BBCForAttachments());
			if (!tszBody.IsEmpty())
				tszFwdMessages = _T("\n") + tszFwdMessages;
			tszBody += tszFwdMessages;
		}

		const JSONNode &jnAttachments = jnMsg["attachments"];
		if (jnAttachments) {
			CMString tszAttachmentDescr = GetAttachmentDescr(jnAttachments, m_vkOptions.BBCForAttachments());
			if (!tszBody.IsEmpty())
				tszAttachmentDescr = _T("\n") + tszAttachmentDescr;
			tszBody += tszAttachmentDescr;
		}

		T2Utf pszBody(tszBody);
		MCONTACT hContact = FindUser(uid, true);
		PROTORECVEVENT recv = { 0 };
		if (isRead)
			recv.flags |= PREF_CREATEREAD;
		if (isOut)
			recv.flags |= PREF_SENT;
		recv.timestamp = datetime;
		recv.szMessage = pszBody;
		recv.lParam = isOut;
		recv.pCustomData = szMid;
		recv.cbCustomDataSize = (int)mir_strlen(szMid);
		ProtoChainRecvMsg(hContact, &recv);

		if (isRead && isOut && datetime > tLastReadMessageTime)
			tLastReadMessageTime = datetime;

		count++;
	}
	setDword(param->hContact, "lastmsgid", iLastMsgId);

	if (ServiceExists(MS_MESSAGESTATE_UPDATE)) {
		MessageReadData data(tLastReadMessageTime, MRD_TYPE_MESSAGETIME);
		CallService(MS_MESSAGESTATE_UPDATE, param->hContact, (LPARAM)&data);
	}

	int once = jnResponse["once"].as_int();
	int iRCount = jnResponse["rcount"].as_int();
	if (count == iRCount && once == 0)
		GetServerHistory(param->hContact, param->iCount + count, iRCount, iTime, param->iMsgID);
	else {
		mir_cslock lck(m_csLoadHistoryTask);
		if (m_iLoadHistoryTask > 0)
			m_iLoadHistoryTask--;

		ptrT ptszNick(db_get_tsa(param->hContact, m_szModuleName, "Nick"));
		CMString str(FORMAT, TranslateT("Loading messages for %s is completed"), ptszNick);
		debugLog(_T("CVkProto::OnReceiveHistoryMessages for %s m_iLoadHistoryTask=%d"), ptszNick, m_iLoadHistoryTask);

		if (m_bNotifyForEndLoadingHistory)
			MsgPopup(param->hContact, str, TranslateT("Loading history"));

		if (m_iLoadHistoryTask == 0 && m_bNotifyForEndLoadingHistoryAllContact) {
			MsgPopup(NULL, TranslateT("Loading messages for all contacts is completed"), TranslateT("Loading history"));
			m_bNotifyForEndLoadingHistoryAllContact = m_bNotifyForEndLoadingHistory = false;		
		}
	}

	if (!pReq->bNeedsRestart || m_bTerminated) {
		delete param;
		pReq->pUserInfo = NULL;
	}
}
Example #16
0
void CVkProto::OnReceiveUnreadNotifications(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveUnreadNotifications %d", reply->resultCode);
	db_unset(NULL, m_szModuleName, "LastNotificationsReqTime");
	if (reply->resultCode != 200)
		return;

	JSONNode jnRoot;
	const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
	if (!jnResponse)
		return;

	const JSONNode &jnNotifications = jnResponse["notifications"];
	const JSONNode &jnGroupInvates = jnResponse["groupinvates"];

	OBJLIST<CVkUserInfo> vkUsers(5, NumericKeySortT);
	OBJLIST<CVKNewsItem> vkNotification(5, sttCompareVKNotificationItems);
	
	CreateVkUserInfoList(vkUsers, jnNotifications);
	CreateVkUserInfoList(vkUsers, jnGroupInvates);
	
	if (!jnNotifications.isnull()) {
		const JSONNode &jnItems = jnNotifications["items"];

		if (!jnItems.isnull())
			for (auto it = jnItems.begin(); it != jnItems.end(); ++it) {
				CVKNewsItem *vkNotificationItem = GetVkNotificationsItem((*it), vkUsers);
				if (!vkNotificationItem)
					continue;
				if (vkNotification.find(vkNotificationItem) == NULL)
					vkNotification.insert(vkNotificationItem);
				else
					delete vkNotificationItem;
			}

	}

	if (!jnGroupInvates.isnull()) {
		const JSONNode &jnItems = jnGroupInvates["items"];

		if (!jnItems.isnull())
			for (auto it = jnItems.begin(); it != jnItems.end(); ++it) {
				CVKNewsItem *vkNotificationItem = GetVkGroupInvates((*it), vkUsers);				
				if (!vkNotificationItem)
					continue;		
				if (vkNotification.find(vkNotificationItem) == NULL)			
					vkNotification.insert(vkNotificationItem);				
				else
					delete vkNotificationItem;
			}
	}	

	bool bNotificationCommentAdded = false;
	bool bNotificationComment = false;
	for (int i = 0; i < vkNotification.getCount(); i++)
		if (FilterNotification(&vkNotification[i], bNotificationComment)) {			
			AddFeedEvent(vkNotification[i].tszText, vkNotification[i].tDate);
			bNotificationCommentAdded = bNotificationComment || bNotificationCommentAdded;
		}

	setDword("LastNotificationsTime", time(NULL));
	if (m_bNotificationsMarkAsViewed && bNotificationCommentAdded)
		NotificationMarkAsViewed();

	vkNotification.destroy();
	vkUsers.destroy();
}
Example #17
0
void CVkProto::OnReceiveUserInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveUserInfo %d", reply->resultCode);

	if (reply->resultCode != 200 || !IsOnline())
		return;

	JSONNode jnRoot;
	const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
	if (!jnResponse)
		return;

	const JSONNode &jnUsers = jnResponse["users"];
	if (!jnUsers)
		return;

	if (!jnResponse["norepeat"].as_bool() && jnResponse["usercount"].as_int() == 0) {
		RetrieveUsersInfo(true, true);
		return;
	}

	MCONTACT hContact;
	LIST<void> arContacts(10, PtrKeySortT);

	for (hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName))
		if (!isChatRoom(hContact))
			arContacts.insert((HANDLE)hContact);

	for (auto it = jnUsers.begin(); it != jnUsers.end(); ++it) {
		hContact = SetContactInfo((*it));
		if (hContact)
			arContacts.remove((HANDLE)hContact);
	}

	if (jnResponse["freeoffline"].as_bool())
		for (int i = 0; i < arContacts.getCount(); i++) {
			hContact = (UINT_PTR)arContacts[i];
			LONG userID = getDword(hContact, "ID", -1);
			if (userID == m_myUserId || userID == VK_FEED_USER)
				continue;

			int iContactStatus = getWord(hContact, "Status", ID_STATUS_OFFLINE);

			if ((iContactStatus == ID_STATUS_ONLINE)
				|| (iContactStatus == ID_STATUS_INVISIBLE && time(NULL) - getDword(hContact, "InvisibleTS", 0) >= m_iInvisibleInterval * 60LL)) {
				setWord(hContact, "Status", ID_STATUS_OFFLINE);
				SetMirVer(hContact, -1);
				db_unset(hContact, m_szModuleName, "ListeningTo");
			}
		}

	arContacts.destroy();
	AddFeedSpecialUser();

	const JSONNode &jnRequests = jnResponse["requests"];
	if (!jnRequests)
		return;

	int iCount = jnRequests["count"].as_int();
	const JSONNode &jnItems = jnRequests["items"];
	if (!iCount || !jnItems)
		return;

	debugLogA("CVkProto::OnReceiveUserInfo AuthRequests");
	for (auto it = jnItems.begin(); it != jnItems.end(); ++it) {
		LONG userid = (*it).as_int();
		if (userid == 0)
			break;
		hContact = FindUser(userid, true);
		if (!getBool(hContact, "ReqAuth")) {
			RetrieveUserInfo(userid);
			setByte(hContact, "ReqAuth", 1);
			ForkThread(&CVkProto::DBAddAuthRequestThread, (void *)hContact);
		}
	}
}
Example #18
0
void CVkProto::OnReciveUploadServer(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	CVkFileUploadParam *fup = (CVkFileUploadParam *)pReq->pUserInfo;
	if (!IsOnline()) {
		SendFileFiled(fup, VKERR_OFFLINE);
		return;
	}

	debugLogA("CVkProto::OnReciveUploadServer %d", reply->resultCode);
	if (reply->resultCode != 200) {
		SendFileFiled(fup, VKERR_INVALID_SERVER);
		return;
	}

	JSONNode jnRoot;
	const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
	if (!jnResponse || pReq->m_iErrorCode) {
		SendFileFiled(fup, pReq->m_iErrorCode);
		return;
	}

	CMStringA uri(jnResponse["upload_url"].as_mstring());
	if (uri.IsEmpty()) {
		SendFileFiled(fup, VKERR_INVALID_URL);
		return;
	}
	
	FILE *pFile = _tfopen(fup->FileName, _T("rb"));
	if (pFile == NULL) {
		SendFileFiled(fup, VKERR_ERR_OPEN_FILE);
		return;
	}

	fseek(pFile, 0, SEEK_END);
	long iFileLen = ftell(pFile); //FileSize
	if (iFileLen < 1) {
		fclose(pFile);
		SendFileFiled(fup, VKERR_ERR_READ_FILE);
		return;
	}
	fseek(pFile, 0, SEEK_SET);

	ProtoBroadcastAck(fup->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)fup);

	AsyncHttpRequest *pUploadReq = new AsyncHttpRequest(this, REQUEST_POST, uri, false, &CVkProto::OnReciveUpload);
	pUploadReq->m_bApiReq = false;
	pUploadReq->m_szParam = "";
	CMStringA boundary, header;
	CMStringA NamePart = fup->atrName();
	CMStringA FNamePart = fup->fileName();
	// Boundary
	int iboundary;
	Utils_GetRandom(&iboundary, sizeof(iboundary));
	boundary.AppendFormat("Miranda%dNG%d", iboundary, time(NULL));
	// Header
	header.AppendFormat("multipart/form-data; boundary=%s", boundary);
	pUploadReq->AddHeader("Content-Type", header);
	// Content-Disposition {
	CMStringA DataBegin = "--";
	DataBegin += boundary;
	DataBegin += "\r\n";
	DataBegin += "Content-Disposition: form-data; name=\"";
	DataBegin += NamePart;
	DataBegin += "\"; filename=\"";
	DataBegin += FNamePart;
	DataBegin += "\";\r\n\r\n";
	// } Content-Disposition
	CMStringA DataEnd = "\r\n--";
	DataEnd += boundary;
	DataEnd += "--\r\n";
	// Body size
	long dataLength = iFileLen + DataBegin.GetLength() + DataEnd.GetLength();
	// Body {
	char* pData = (char *)mir_alloc(dataLength);
	memcpy(pData, (void *)DataBegin.GetBuffer(), DataBegin.GetLength());
	pUploadReq->pData = pData;

	pData += DataBegin.GetLength();
	long lBytes = (long)fread(pData, 1, iFileLen, pFile);
	fclose(pFile);

	if (lBytes != iFileLen) {
		SendFileFiled(fup, VKERR_ERR_READ_FILE);
		mir_free(pUploadReq->pData);
		delete pUploadReq;
		return;
	}

	pData += iFileLen;
	memcpy(pData, (void *)DataEnd.GetBuffer(), DataEnd.GetLength());
	// } Body

	pUploadReq->dataLength = (int)dataLength;
	pUploadReq->pUserInfo = pReq->pUserInfo;
	Push(pUploadReq);
}
Example #19
0
void CVkProto::OnReciveUpload(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	CVkFileUploadParam *fup = (CVkFileUploadParam *)pReq->pUserInfo;
	if (!IsOnline()) {
		SendFileFiled(fup, VKERR_OFFLINE);
		return;
	}

	debugLogA("CVkProto::OnReciveUploadServer %d", reply->resultCode);
	if (reply->resultCode != 200) {
		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"]) && !jnRoot["file"]) {
		SendFileFiled(fup, VKERR_INVALID_PARAMETERS);
		return;
	}

	CMString server(jnRoot["server"].as_mstring());
	CMString hash(jnRoot["hash"].as_mstring());
	CMString upload;

	AsyncHttpRequest *pUploadReq;

	ProtoBroadcastAck(fup->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)fup);

	switch (fup->GetType()) {
	case CVkFileUploadParam::typeImg:
		upload = jnRoot["photo"].as_mstring();
		if (upload == _T("[]")) {
			SendFileFiled(fup, VKERR_INVALID_PARAMETERS);
			return;
		}
		pUploadReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/photos.saveMessagesPhoto.json", true, &CVkProto::OnReciveUploadFile)
			<< TCHAR_PARAM("server", server)
			<< TCHAR_PARAM("photo", upload)
			<< TCHAR_PARAM("hash", hash)
			<< VER_API;
		break;
	case CVkFileUploadParam::typeAudio:
		upload = jnRoot["audio"].as_mstring();
		if (upload == _T("[]")) {
			SendFileFiled(fup, VKERR_INVALID_PARAMETERS);
			return;
		}
		pUploadReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/audio.save.json", true, &CVkProto::OnReciveUploadFile)
			<< TCHAR_PARAM("server", server)
			<< TCHAR_PARAM("audio", upload)
			<< TCHAR_PARAM("hash", hash)
			<< VER_API;
		break;
	case CVkFileUploadParam::typeDoc:
		upload = jnRoot["file"].as_mstring();
		if (upload.IsEmpty()) {
			SendFileFiled(fup, VKERR_INVALID_PARAMETERS);
			return;
		}
		pUploadReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/docs.save.json", true, &CVkProto::OnReciveUploadFile)
			<< CHAR_PARAM("title", fup->fileName())
			<< TCHAR_PARAM("file", upload)	
			<< VER_API;
		break;
	default:
		SendFileFiled(fup, VKERR_FTYPE_NOT_SUPPORTED);
		return;
	}

	pUploadReq->pUserInfo = pReq->pUserInfo;
	Push(pUploadReq);
}
Example #20
0
void CVkProto::OnReceiveMessages(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveMessages %d", reply->resultCode);
	if (reply->resultCode != 200)
		return;

	JSONNode jnRoot;
	const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
	if (!jnResponse)
		return;
	if (!jnResponse["Msgs"])
		return;

	CMStringA mids;
	int numMessages = jnResponse["Msgs"]["count"].as_int();
	const JSONNode &jnMsgs = jnResponse["Msgs"]["items"];
	const JSONNode &jnFUsers = jnResponse["fwd_users"];

	debugLogA("CVkProto::OnReceiveMessages numMessages = %d", numMessages);

	for (auto it = jnMsgs.begin(); it != jnMsgs.end(); ++it) {
		const JSONNode &jnMsg = (*it);
		if (!jnMsg) {
			debugLogA("CVkProto::OnReceiveMessages pMsg == NULL");
			break;
		}

		UINT mid = jnMsg["id"].as_int();
		CMString tszBody(jnMsg["body"].as_mstring());
		int datetime = jnMsg["date"].as_int();
		int isOut = jnMsg["out"].as_int();
		int isRead = jnMsg["read_state"].as_int();
		int uid = jnMsg["user_id"].as_int();

		const JSONNode &jnFwdMessages = jnMsg["fwd_messages"];
		if (jnFwdMessages) {
			CMString tszFwdMessages = GetFwdMessages(jnFwdMessages, jnFUsers, m_vkOptions.BBCForAttachments());
			if (!tszBody.IsEmpty())
				tszFwdMessages = _T("\n") + tszFwdMessages;
			tszBody +=  tszFwdMessages;
		}

		CMString tszAttachmentDescr;
		const JSONNode &jnAttachments = jnMsg["attachments"];
		if (jnAttachments) {
			tszAttachmentDescr = GetAttachmentDescr(jnAttachments, m_vkOptions.BBCForAttachments());
			if (!tszBody.IsEmpty())
				tszBody += _T("\n");
			tszBody += tszAttachmentDescr;
		}

		MCONTACT hContact = NULL;
		int chat_id = jnMsg["chat_id"].as_int();
		if (chat_id == 0)
			hContact = FindUser(uid, true);

		char szMid[40];
		_itoa(mid, szMid, 10);
		if (m_vkOptions.iMarkMessageReadOn == MarkMsgReadOn::markOnReceive || chat_id != 0) {
			if (!mids.IsEmpty())
				mids.AppendChar(',');
			mids.Append(szMid);
		}

		if (chat_id != 0) {
			debugLogA("CVkProto::OnReceiveMessages chat_id != 0");
			CMString action_chat = jnMsg["action"].as_mstring();
			int action_mid = _ttoi(jnMsg["action_mid"].as_mstring());
			if ((action_chat == "chat_kick_user") && (action_mid == m_myUserId))
				KickFromChat(chat_id, uid, jnMsg, jnFUsers);
			else {
				MCONTACT chatContact = FindChat(chat_id);
				if (chatContact && getBool(chatContact, "kicked", true))
					db_unset(chatContact, m_szModuleName, "kicked");
				AppendChatMessage(chat_id, jnMsg, jnFUsers, false);
			}
			continue;
		}

		PROTORECVEVENT recv = { 0 };
		bool bUseServerReadFlag = m_vkOptions.bSyncReadMessageStatusFromServer ? true : !m_vkOptions.bMesAsUnread;
		if (isRead && bUseServerReadFlag)
			recv.flags |= PREF_CREATEREAD;
		if (isOut)
			recv.flags |= PREF_SENT;
		else if (m_vkOptions.bUserForceInvisibleOnActivity && time(NULL) - datetime < 60 * m_vkOptions.iInvisibleInterval)
			SetInvisible(hContact);

		T2Utf pszBody(tszBody);
		recv.timestamp = m_vkOptions.bUseLocalTime ? time(NULL) : datetime;
		recv.szMessage = pszBody;
		recv.lParam = isOut;
		recv.pCustomData = szMid;
		recv.cbCustomDataSize = (int)mir_strlen(szMid);
		Sleep(100);

		debugLogA("CVkProto::OnReceiveMessages mid = %d, datetime = %d, isOut = %d, isRead = %d, uid = %d", mid, datetime, isOut, isRead, uid);

		if (!CheckMid(m_sendIds, mid)) {
			debugLogA("CVkProto::OnReceiveMessages ProtoChainRecvMsg");
			ProtoChainRecvMsg(hContact, &recv);
			if (mid > getDword(hContact, "lastmsgid", -1))
				setDword(hContact, "lastmsgid", mid);
			if (!isOut)
				m_incIds.insert((HANDLE)mid);
		}
		else if (m_vkOptions.bLoadSentAttachments && !tszAttachmentDescr.IsEmpty() && isOut) {
			T2Utf pszAttach(tszAttachmentDescr);
			recv.timestamp = time(NULL); // only local time
			recv.szMessage = pszAttach;
			ProtoChainRecvMsg(hContact, &recv);
		}
	}

	if (!mids.IsEmpty())
		MarkMessagesRead(mids);
}
Example #21
0
void CVkProto::OnReceiveDlgs(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveDlgs %d", reply->resultCode);
	if (reply->resultCode != 200)
		return;

	JSONNode jnRoot;
	const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
	if (!jnResponse)
		return;

	const JSONNode &jnDlgs = jnResponse["items"];
	if (!jnDlgs)
		return;

	for (auto it = jnDlgs.begin(); it != jnDlgs.end(); ++it) {
		if (!(*it))
			break;
		int numUnread = (*it)["unread"].as_int();
		const JSONNode &jnDlg = (*it)["message"];
		if (jnDlg == NULL)
			break;

		int uid = 0;
		MCONTACT hContact(NULL);
		
		int chatid = jnDlg["chat_id"].as_int();

		if (!chatid) {
			uid = jnDlg["user_id"].as_int();
			hContact = FindUser(uid, true);

			if (ServiceExists(MS_MESSAGESTATE_UPDATE)) {
				time_t tLastReadMessageTime = jnDlg["date"].as_int();
				bool isOut = jnDlg["out"].as_bool();
				bool isRead = jnDlg["read_state"].as_bool();

				if (isRead && isOut) {
					MessageReadData data(tLastReadMessageTime, MRD_TYPE_MESSAGETIME);
					CallService(MS_MESSAGESTATE_UPDATE, hContact, (LPARAM)&data);
				}
			}
		}
		
		if (chatid) {
			debugLogA("CVkProto::OnReceiveDlgs chatid = %d", chatid);
			if (m_chats.find((CVkChatInfo*)&chatid) == NULL)
				AppendChat(chatid, jnDlg);
		}
		else if (m_vkOptions.iSyncHistoryMetod) {
			int mid = jnDlg["id"].as_int();
			m_bNotifyForEndLoadingHistory = false;

			if (getDword(hContact, "lastmsgid", -1) == -1 && numUnread)
				GetServerHistory(hContact, 0, numUnread, 0, 0, true);
			else
				GetHistoryDlg(hContact, mid);

			if (m_vkOptions.iMarkMessageReadOn == MarkMsgReadOn::markOnReceive && numUnread)
				MarkMessagesRead(hContact);
		}
		else if (numUnread) {
			m_bNotifyForEndLoadingHistory = false;
			GetServerHistory(hContact, 0, numUnread, 0, 0, true);

			if (m_vkOptions.iMarkMessageReadOn == MarkMsgReadOn::markOnReceive)
				MarkMessagesRead(hContact);
		}
	}
	RetrieveUsersInfo();
}
Example #22
0
void CVkProto::OnReciveUploadFile(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	CVkFileUploadParam *fup = (CVkFileUploadParam *)pReq->pUserInfo;
	if (!IsOnline()) {
		SendFileFiled(fup, VKERR_OFFLINE);
		return;
	}

	debugLogA("CVkProto::OnReciveUploadFile %d", reply->resultCode);
	if (reply->resultCode != 200) {
		SendFileFiled(fup, VKERR_FILE_NOT_UPLOADED);
		return;
	}

	JSONNode jnRoot;
	const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
	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, VKERR_INVALID_PARAMETERS);
		return;
	}

	CMString Attachment;

	switch (fup->GetType()) {
	case CVkFileUploadParam::typeImg:
		Attachment.AppendFormat(_T("photo%d_%d"), owner_id, id);
		break;
	case CVkFileUploadParam::typeAudio:
		Attachment.AppendFormat(_T("audio%d_%d"), owner_id, id);
		break;
	case CVkFileUploadParam::typeDoc:
		Attachment.AppendFormat(_T("doc%d_%d"), owner_id, id);
		break;
	default:
		SendFileFiled(fup, VKERR_FTYPE_NOT_SUPPORTED);
		return;
	}

	AsyncHttpRequest *pMsgReq;

	if (isChatRoom(fup->hContact)) {

		ptrT tszChatID(getTStringA(fup->hContact, "ChatRoomID"));
		if (!tszChatID) {
			SendFileFiled(fup, VKERR_INVALID_USER);
			return;
		}

		CVkChatInfo *cc = GetChatById(tszChatID);
		if (cc == NULL) {
			SendFileFiled(fup, VKERR_INVALID_USER);
			return;
		}

		pMsgReq = new AsyncHttpRequest(this, REQUEST_POST, "/method/messages.send.json", true, &CVkProto::OnSendChatMsg, AsyncHttpRequest::rpHigh)
			<< INT_PARAM("chat_id", cc->m_chatid);
		pMsgReq->pUserInfo = pReq->pUserInfo;

	}
	else {
		LONG userID = getDword(fup->hContact, "ID", -1);
		if (userID == -1 || userID == VK_FEED_USER) {
			SendFileFiled(fup, VKERR_INVALID_USER);
			return;
		}

		pMsgReq = new AsyncHttpRequest(this, REQUEST_POST, "/method/messages.send.json", true, &CVkProto::OnSendMessage, AsyncHttpRequest::rpHigh)
			<< INT_PARAM("user_id", userID);
		pMsgReq->pUserInfo = new CVkSendMsgParam(fup->hContact, fup);
		
	}

	pMsgReq << TCHAR_PARAM("message", fup->Desc) << TCHAR_PARAM("attachment", Attachment) << VER_API;
	pMsgReq->AddHeader("Content-Type", "application/x-www-form-urlencoded");

	Push(pMsgReq);
}
Example #23
0
void CVkProto::OnReceiveFriends(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveFriends %d", reply->resultCode);
	if (reply->resultCode != 200)
		return;

	JSONROOT pRoot;
	JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot), *pInfo;
	if (pResponse == NULL)
		return;

	bool bCleanContacts = getByte("AutoClean", 0) != 0;
	LIST<void> arContacts(10, PtrKeySortT);
	if (bCleanContacts)
		for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName))
			if (!isChatRoom(hContact))
				arContacts.insert((HANDLE)hContact);

	for (int i = 0; (pInfo = json_at(pResponse, i)) != NULL; i++) {
		ptrT szValue(json_as_string(json_get(pInfo, "uid")));
		if (szValue == NULL)
			continue;

		CMString tszNick;
		MCONTACT hContact = FindUser(_ttoi(szValue), true);
		arContacts.remove((HANDLE)hContact);
		szValue = json_as_string(json_get(pInfo, "first_name"));
		if (szValue) {
			setTString(hContact, "FirstName", szValue);

			tszNick.Append(szValue);
			tszNick.AppendChar(' ');
		}

		if (szValue = json_as_string(json_get(pInfo, "last_name"))) {
			setTString(hContact, "LastName", szValue);
			tszNick.Append(szValue);
		}

		if (!tszNick.IsEmpty())
			setTString(hContact, "Nick", tszNick);

		szValue = json_as_string(json_get(pInfo, "photo_medium"));
		SetAvatarUrl(hContact, szValue);

		setWord(hContact, "Status", (json_as_int(json_get(pInfo, "online")) == 0) ? ID_STATUS_OFFLINE : ID_STATUS_ONLINE);

		int iValue = json_as_int(json_get(pInfo, "sex"));
		if (iValue)
			setByte(hContact, "Gender", (iValue == 2) ? 'M' : 'F');

		if ((iValue = json_as_int(json_get(pInfo, "timezone"))) != 0)
			setByte(hContact, "Timezone", iValue * -2);

		szValue = json_as_string(json_get(pInfo, "mobile_phone"));
		if (szValue && *szValue)
			setTString(hContact, "Cellular", szValue);
		szValue = json_as_string(json_get(pInfo, "home_phone"));
		if (szValue && *szValue)
			setTString(hContact, "Phone", szValue);
	}

	if (bCleanContacts)
		for (int i = 0; i < arContacts.getCount(); i++)
			CallService(MS_DB_CONTACT_DELETE, (WPARAM)arContacts[i], 0);
}
Example #24
0
void CVkProto::OnReceiveMessages(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveMessages %d", reply->resultCode);
	if (reply->resultCode != 200)
		return;

	JSONROOT pRoot;
	JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot);
	if (pResponse == NULL)
		return;

	JSONNODE *pDlgs = json_as_array(json_get(pResponse, "dlgs"));
	if (pDlgs != NULL) {
		int numDialogs = json_as_int(json_at(pDlgs, 0));
		for (int i = 1; i <= numDialogs; i++) {
			JSONNODE *pDlg = json_at(pDlgs, i);
			if (pDlg == NULL)
				continue;

			int chatid = json_as_int(json_get(pDlg, "chat_id"));
			if (chatid != 0)
			if (m_chats.find((CVkChatInfo*)&chatid) == NULL) {
				AppendChat(chatid, pDlg);
			}
		}
	}

	CMStringA mids, lmids;
	bool bDirectArray = false;

	JSONNODE *pMsgs = json_as_array(json_get(pResponse, "msgs"));
	if (pMsgs == NULL) {
		pMsgs = pResponse;
		bDirectArray = true;
	}

	int numMessages = json_as_int(json_at(pMsgs, 0));
	for (int i = 1; i <= numMessages; i++) {
		JSONNODE *pMsg = json_at(pMsgs, i);
		if (pMsg == NULL)
			continue;

		char szMid[40];
		int mid = json_as_int(json_get(pMsg, "mid"));
		_itoa(mid, szMid, 10);
		if (!mids.IsEmpty())
			mids.AppendChar(',');
		mids.Append(szMid);

		int chat_id = json_as_int(json_get(pMsg, "chat_id"));
		if (chat_id != 0) {
			AppendChatMessage(chat_id, pMsg, false);
			continue;
		}

		// VK documentation lies: even if you specified preview_length=0, 
		// long messages get cut out. So we need to retrieve them from scratch
		ptrT ptszBody(json_as_string(json_get(pMsg, "body")));
		if (!bDirectArray && _tcslen(ptszBody) > 1000) {
			if (!lmids.IsEmpty())
				lmids.AppendChar(',');
			lmids.Append(szMid);
			continue;
		}

		int datetime = json_as_int(json_get(pMsg, "date"));
		int isOut = json_as_int(json_get(pMsg, "out"));
		int uid = json_as_int(json_get(pMsg, "uid"));
		int isRead = json_as_int(json_get(pMsg, "read_state"));

		JSONNODE *pAttachments = json_get(pMsg, "attachments");
		if (pAttachments != NULL)
			ptszBody = mir_tstrdup(CMString(ptszBody) + GetAttachmentDescr(pAttachments));

		MCONTACT hContact = FindUser(uid, true);

		PROTORECVEVENT recv = { 0 };
		recv.flags = PREF_TCHAR;
		if (isRead)
			recv.flags |= PREF_CREATEREAD;
		if (isOut)
			recv.flags |= PREF_SENT;
		recv.timestamp = datetime;
		recv.tszMessage = ptszBody;
		recv.lParam = isOut;
		recv.pCustomData = szMid;
		recv.cbCustomDataSize = (int)strlen(szMid);
		ProtoChainRecvMsg(hContact, &recv);
	}

	MarkMessagesRead(mids);
	RetrieveMessagesByIds(lmids);
}
Example #25
0
void CVkProto::OnReceiveChatInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveChatInfo %d", reply->resultCode);
	if (reply->resultCode != 200)
		return;

	JSONROOT pRoot;
	JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot);
	if (pResponse == NULL)
		return;

	CVkChatInfo *cc = (CVkChatInfo*)pReq->pUserInfo;
	if (m_chats.indexOf(cc) == -1)
		return;

	JSONNODE *info = json_get(pResponse, "info");
	if (info != NULL) {
		ptrT tszTitle(json_as_string(json_get(info, "title")));
		if (lstrcmp(tszTitle, cc->m_tszTopic)) {
			cc->m_tszTopic = mir_tstrdup(tszTitle);
			setTString(cc->m_hContact, "Nick", tszTitle);

			GCDEST gcd = { m_szModuleName, cc->m_tszId, GC_EVENT_CHANGESESSIONAME };
			GCEVENT gce = { sizeof(GCEVENT), &gcd };
			gce.ptszText = tszTitle;
			CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
		}
		
		cc->m_admin_id = json_as_int(json_get(info, "admin_id"));
	}

	JSONNODE *users = json_as_array(json_get(pResponse, "users"));
	if (users != NULL) {
		for (int i = 0; i < cc->m_users.getCount(); i++)
			cc->m_users[i].m_bDel = true;

		for (int i = 0;; i++) {
			JSONNODE *pUser = json_at(users, i);
			if (pUser == NULL)
				break;

			int uid = json_as_int(json_get(pUser, "uid"));
			TCHAR tszId[20];
			_itot(uid, tszId, 10);

			bool bNew;
			CVkChatUser *cu = cc->m_users.find((CVkChatUser*)&uid);
			if (cu == NULL) {
				cc->m_users.insert(cu = new CVkChatUser(uid));
				bNew = true;
			}
			else bNew = cu->m_bUnknown;
			cu->m_bDel = false;

			ptrT fName(json_as_string(json_get(pUser, "first_name")));
			ptrT lName(json_as_string(json_get(pUser, "last_name")));
			CMString tszNick = CMString(fName).Trim() + _T(" ") + CMString(lName).Trim();
			cu->m_tszNick = mir_tstrdup(tszNick);
			cu->m_bUnknown = false;
			
			if (bNew) {
				GCDEST gcd = { m_szModuleName, cc->m_tszId, GC_EVENT_JOIN };
				GCEVENT gce = { sizeof(GCEVENT), &gcd };
				gce.bIsMe = uid == m_myUserId;
				gce.ptszUID = tszId;
				gce.ptszNick = tszNick;
				gce.ptszStatus = TranslateTS(sttStatuses[uid == cc->m_admin_id]);
				gce.dwItemData = (INT_PTR)cu;
				CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
			}
		}

		for (int i = cc->m_users.getCount() - 1; i >= 0; i--) {
			CVkChatUser &cu = cc->m_users[i];
			if (!cu.m_bDel)
				continue;

			TCHAR tszId[20];
			_itot(cu.m_uid, tszId, 10);

			GCDEST gcd = { m_szModuleName, cc->m_tszId, GC_EVENT_PART };
			GCEVENT gce = { sizeof(GCEVENT), &gcd };
			gce.ptszUID = tszId;
			CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);

			cc->m_users.remove(i);
		}
	}

	JSONNODE *msgs = json_as_array(json_get(pResponse, "msgs"));
	if (msgs != NULL) {
		for (int i = 1;; i++) {
			JSONNODE *pMsg = json_at(msgs, i);
			if (pMsg == NULL)
				break;

			AppendChatMessage(cc->m_chatid, pMsg, true);
		}
		cc->m_bHistoryRead = true;
	}

	for (int j = 0; j < cc->m_msgs.getCount(); j++) {
		CVkChatMessage &p = cc->m_msgs[j];
		AppendChatMessage(cc, p.m_mid, p.m_uid, p.m_date, p.m_tszBody, p.m_bHistory);
	}
	cc->m_msgs.destroy();
}
Example #26
0
void CVkProto::OnReceiveHistoryMessages(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
	debugLogA("CVkProto::OnReceiveHistoryMessages %d", reply->resultCode);
	if (reply->resultCode != 200 || !pReq->pUserInfo)
		return;

	JSONNode jnRoot;
	CVkSendMsgParam *param = (CVkSendMsgParam*)pReq->pUserInfo;
	const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
	if (!jnResponse) {
		if (!pReq->bNeedsRestart || m_bTerminated) {
			delete param;
			pReq->pUserInfo = NULL;
		}
		return;
	}
	
	int iTime = jnResponse["datetime"].as_int(); 
	const JSONNode &jnMsgs = jnResponse["items"];
	const JSONNode &jnFUsers = jnResponse["fwd_users"];

	int iLastMsgId = getDword(param->hContact, "lastmsgid", -1);
	time_t tLastReadMessageTime = 0;
	int count = 0;

	for (auto it = jnMsgs.rbegin(); it != jnMsgs.rend(); ++it) {
		const JSONNode &jnMsg = (*it);

		int mid = jnMsg["id"].as_int();
		if (iLastMsgId < mid) 
			iLastMsgId = mid;

		char szMid[40];
		_itoa(mid, szMid, 10);

		CMString tszBody(jnMsg["body"].as_mstring());
		int datetime = jnMsg["date"].as_int();
		int isOut = jnMsg["out"].as_int();
		int isRead = jnMsg["read_state"].as_int(); 
		int uid = jnMsg["user_id"].as_int(); 
		
		const JSONNode &jnFwdMessages = jnMsg["fwd_messages"];
		if (jnFwdMessages) {
			CMString tszFwdMessages = GetFwdMessages(jnFwdMessages, jnFUsers, m_iBBCForAttachments);
			if (!tszBody.IsEmpty())
				tszFwdMessages = _T("\n") + tszFwdMessages;
			tszBody += tszFwdMessages;
		}
		
		const JSONNode &jnAttachments = jnMsg["attachments"];
		if (jnAttachments) {
			CMString tszAttachmentDescr = GetAttachmentDescr(jnAttachments, m_iBBCForAttachments);
			if (!tszBody.IsEmpty())
				tszAttachmentDescr = _T("\n") + tszAttachmentDescr;
			tszBody += tszAttachmentDescr;
		}

		T2Utf pszBody(tszBody);
		MCONTACT hContact = FindUser(uid, true);
		PROTORECVEVENT recv = { 0 };
		if (isRead)
			recv.flags |= PREF_CREATEREAD;
		if (isOut)
			recv.flags |= PREF_SENT;
		recv.timestamp = datetime;
		recv.szMessage = pszBody;
		recv.lParam = isOut;
		recv.pCustomData = szMid;
		recv.cbCustomDataSize = (int)mir_strlen(szMid);
		ProtoChainRecvMsg(hContact, &recv);

		if (isRead && isOut && datetime > tLastReadMessageTime)
			tLastReadMessageTime = datetime;

		count++;
	}
	setDword(param->hContact, "lastmsgid", iLastMsgId);

	if (ServiceExists(MS_MESSAGESTATE_UPDATE)) {
		MessageReadData data(tLastReadMessageTime, MRD_TYPE_MESSAGETIME);
		CallService(MS_MESSAGESTATE_UPDATE, param->hContact, (LPARAM)&data);
	}

	int once = jnResponse["once"].as_int();
	int iRCount = jnResponse["rcount"].as_int();
	if (count == iRCount && once == 0)
		GetServerHistory(param->hContact, param->iCount + count, iRCount, iTime, param->iMsgID);

	if (!pReq->bNeedsRestart || m_bTerminated) {
		delete param;
		pReq->pUserInfo = NULL;
	}
}