/*
Copyright (c) 2013-16 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"
int CVkProto::SetStatus(int iNewStatus)
{
debugLogA("CVkProto::SetStatus iNewStatus = %d, m_iStatus = %d, m_iDesiredStatus = %d m_hWorkerThread = %d", iNewStatus, m_iStatus, m_iDesiredStatus, m_hWorkerThread == NULL ? 0 : 1);
mir_cslock lck(m_csSetStatus);
if (m_iDesiredStatus == iNewStatus || iNewStatus == ID_STATUS_IDLE)
return 0;
int oldStatus = m_iStatus;
m_iDesiredStatus = iNewStatus;
if (iNewStatus == ID_STATUS_OFFLINE) {
if (IsOnline()) {
SetServerStatus(ID_STATUS_OFFLINE);
debugLogA("CVkProto::SetStatus ShutdownSession");
ShutdownSession();
}
m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
debugLogA("CVkProto::SetStatus (1) iNewStatus = %d, m_iStatus = %d, m_iDesiredStatus = %d oldStatus = %d", iNewStatus, m_iStatus, m_iDesiredStatus, oldStatus);
}
else if (m_hWorkerThread == NULL && !IsStatusConnecting(m_iStatus)) {
m_iStatus = ID_STATUS_CONNECTING;
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
debugLogA("CVkProto::SetStatus (2) iNewStatus = %d, m_iStatus = %d, m_iDesiredStatus = %d oldStatus = %d", iNewStatus, m_iStatus, m_iDesiredStatus, oldStatus);
m_hWorkerThread = ForkThreadEx(&CVkProto::WorkerThread, 0, NULL);
}
else if (IsOnline()) {
debugLogA("CVkProto::SetStatus (3) iNewStatus = %d, m_iStatus = %d, m_iDesiredStatus = %d oldStatus = %d", iNewStatus, m_iStatus, m_iDesiredStatus, oldStatus);
SetServerStatus(iNewStatus);
}
else {
debugLogA("CVkProto::SetStatus (4) iNewStatus = %d, m_iStatus = %d, m_iDesiredStatus = %d oldStatus = %d", iNewStatus, m_iStatus, m_iDesiredStatus, oldStatus);
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
if (!IsStatusConnecting(m_iStatus))
m_iDesiredStatus = m_iStatus;
debugLogA("CVkProto::SetStatus (5) iNewStatus = %d, m_iStatus = %d, m_iDesiredStatus = %d oldStatus = %d", iNewStatus, m_iStatus, m_iDesiredStatus, oldStatus);
}
debugLogA("CVkProto::SetStatus (ret) iNewStatus = %d, m_iStatus = %d, m_iDesiredStatus = %d oldStatus = %d", iNewStatus, m_iStatus, m_iDesiredStatus, oldStatus);
return 0;
}
void CVkProto::SetServerStatus(int iNewStatus)
{
debugLogA("CVkProto::SetServerStatus %d %d", iNewStatus, m_iStatus);
if (!IsOnline() || iNewStatus < ID_STATUS_OFFLINE)
return;
int iOldStatus = m_iStatus;
CMString oldStatusMsg(ptrW(db_get_tsa(NULL, m_szModuleName, "OldStatusMsg")));
ptrW ptszListeningToMsg(db_get_tsa(NULL, m_szModuleName, "ListeningTo"));
if (iNewStatus == ID_STATUS_OFFLINE) {
m_bNeedSendOnline = false;
if (!IsEmpty(ptszListeningToMsg) && m_bSetBroadcast) {
RetrieveStatusMsg(oldStatusMsg);
m_bSetBroadcast = false;
}
m_iStatus = ID_STATUS_OFFLINE;
if (iOldStatus != ID_STATUS_OFFLINE && iOldStatus != ID_STATUS_INVISIBLE)
Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/account.setOffline.json", true, &CVkProto::OnReceiveSmth));
}
else if (iNewStatus != ID_STATUS_INVISIBLE) {
m_bNeedSendOnline = true;
if (iOldStatus == ID_STATUS_ONLINE)
return;
m_iStatus = ID_STATUS_ONLINE;
Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/account.setOnline.json", true, &CVkProto::OnReceiveSmth));
}
else {
m_bNeedSendOnline = false;
if (!IsEmpty(ptszListeningToMsg) && m_bSetBroadcast) {
RetrieveStatusMsg(oldStatusMsg);
m_bSetBroadcast = false;
}
m_iStatus = ID_STATUS_INVISIBLE;
if (iOldStatus == ID_STATUS_ONLINE)
Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/account.setOffline.json", true, &CVkProto::OnReceiveSmth));
}
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)iOldStatus, m_iStatus);
}
/////////////////////////////////////////////////////////////////////////////////////////
INT_PTR __cdecl CVkProto::SvcSetStatusMsg(WPARAM, LPARAM)
{
debugLogA("CVkProto::SvcSetStatusMsg");
if (!IsOnline())
return 1;
MsgPopup(NULL, TranslateT("Loading status message from vk.com.\nThis may take some time."), TranslateT("Waiting..."));
Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/status.get.json", true, &CVkProto::OnReceiveStatusMsg));
return 0;
}
void CVkProto::OnReceiveStatusMsg(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveStatusMsg %d", reply->resultCode);
if (reply->resultCode != 200)
return;
OnReceiveStatus(reply, pReq);
ptrW ptszOldStatusMsg(db_get_tsa(NULL, m_szModuleName, "OldStatusMsg"));
CMString tszOldStatusMsg(ptszOldStatusMsg);
ENTER_STRING pForm = { sizeof(pForm) };
pForm.type = ESF_MULTILINE;
pForm.caption = TranslateT("Enter new status message");
pForm.ptszInitVal = ptszOldStatusMsg;
pForm.szModuleName = m_szModuleName;
pForm.szDataPrefix = "statusmsgform_";
if (!EnterString(&pForm))
return;
CMString tszNewStatusMsg(ptrW(pForm.ptszResult));
if (tszOldStatusMsg == tszNewStatusMsg)
return;
RetrieveStatusMsg(tszNewStatusMsg);
setTString("OldStatusMsg", ptszOldStatusMsg);
}
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] != wchar_t(9835))
setTString("OldStatusMsg", tszStatusText);
}
}
void CVkProto::RetrieveStatusMsg(const CMString &StatusMsg)
{
debugLogA("CVkProto::RetrieveStatusMsg");
if (!IsOnline())
return;
Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/status.set.json", true, &CVkProto::OnReceiveSmth)
<< TCHAR_PARAM("text", StatusMsg));
}
void CVkProto::RetrieveStatusMusic(const CMString &StatusMsg)
{
debugLogA("CVkProto::RetrieveStatusMusic");
if (!IsOnline() || m_iStatus == ID_STATUS_INVISIBLE || m_vkOptions.iMusicSendMetod == MusicSendMetod::sendNone)
return;
CMString code;
CMString tszOldStatusMsg(db_get_tsa(0, m_szModuleName, "OldStatusMsg"));
if (StatusMsg.IsEmpty()) {
if (m_vkOptions.iMusicSendMetod == MusicSendMetod::sendBroadcastOnly)
code = "API.audio.setBroadcast();return null;";
else {
CMString codeformat("API.status.set({text:\"%s\"});return null;");
code.AppendFormat(codeformat, tszOldStatusMsg);
}
m_bSetBroadcast = false;
}
else {
if (m_vkOptions.iMusicSendMetod == MusicSendMetod::sendBroadcastOnly) {
CMString codeformat("var StatusMsg=\"%s\";var CntLmt=100;var OldMsg=API.status.get();"
"var Tracks=API.audio.search({\"q\":StatusMsg,\"count\":CntLmt,\"search_own\":1});"
"var Cnt=Tracks.count;if(Cnt>CntLmt){Cnt=CntLmt;}"
"if(Cnt==0){API.audio.setBroadcast();}"
"else{var i=0;var j=0;var Track=\" \";"
"while(iCntLmt){Cnt=CntLmt;}"
"if(Cnt==0){Track=\"♫ \"+StatusMsg;API.status.set({\"text\":Track});}"
"else{var i=0;var j=-1;"
"while(icbSize != sizeof(LISTENINGTOINFO))
db_unset(NULL, m_szModuleName, "ListeningTo");
else if (pliInfo->dwFlags & LTI_UNICODE) {
if (ServiceExists(MS_LISTENINGTO_GETPARSEDTEXT))
tszListeningTo = ptrW((LPWSTR)CallService(MS_LISTENINGTO_GETPARSEDTEXT, (WPARAM)L"%artist% - %title%", (LPARAM)pliInfo));
else
tszListeningTo.Format(L"%s - %s",
pliInfo->ptszArtist ? pliInfo->ptszArtist : L"",
pliInfo->ptszTitle ? pliInfo->ptszTitle : L"");
setTString("ListeningTo", tszListeningTo);
}
RetrieveStatusMusic(tszListeningTo);
return 0;
}