Esempio n. 1
0
void TwitterProto::SignOn(void*)
{
	debugLogA( _T("***** Beginning SignOn process"));
	WaitForSingleObject(&signon_lock_,INFINITE);

	// Kill the old thread if it's still around
	// this doesn't seem to work.. should we wait infinitely?
	if(hMsgLoop_)
	{
		debugLogA( _T("***** Requesting MessageLoop to exit"));
		QueueUserAPC(APC_callback,hMsgLoop_,(ULONG_PTR)this);
		debugLogA( _T("***** Waiting for old MessageLoop to exit"));
		//WaitForSingleObject(hMsgLoop_,INFINITE);
		WaitForSingleObject(hMsgLoop_,180000);
		CloseHandle(hMsgLoop_);
	}
	if(NegotiateConnection()) // Could this be? The legendary Go Time??
	{
		if(!in_chat_ && db_get_b(0,m_szModuleName,TWITTER_KEY_CHATFEED,0))
			OnJoinChat(0,true);
		
		SetAllContactStatuses(ID_STATUS_ONLINE);
		hMsgLoop_ = ForkThreadEx(&TwitterProto::MessageLoop, NULL, 0);
	}

	ReleaseMutex(signon_lock_);
	debugLogA( _T("***** SignOn complete"));
}
Esempio n. 2
0
FacebookProto::FacebookProto(const char* proto_name,const TCHAR* username) :
	PROTO<FacebookProto>(proto_name, username)
{
	facy.parent = this;

	signon_lock_ = CreateMutex(NULL, FALSE, NULL);
	avatar_lock_ = CreateMutex(NULL, FALSE, NULL);
	log_lock_ = CreateMutex(NULL, FALSE, NULL);
	update_loop_lock_ = CreateEvent(NULL, FALSE, FALSE, NULL);
	facy.buddies_lock_ = CreateMutex(NULL, FALSE, NULL);
	facy.send_message_lock_ = CreateMutex(NULL, FALSE, NULL);
	facy.fcb_conn_lock_ = CreateMutex(NULL, FALSE, NULL);

	m_invisible = false;

	CreateProtoService(PS_CREATEACCMGRUI, &FacebookProto::SvcCreateAccMgrUI);
	CreateProtoService(PS_GETMYAWAYMSG,   &FacebookProto::GetMyAwayMsg);
	CreateProtoService(PS_GETMYAVATART,   &FacebookProto::GetMyAvatar);
	CreateProtoService(PS_GETAVATARINFOT, &FacebookProto::GetAvatarInfo);
	CreateProtoService(PS_GETAVATARCAPS,  &FacebookProto::GetAvatarCaps);
	CreateProtoService(PS_GETUNREADEMAILCOUNT, &FacebookProto::GetNotificationsCount);

	CreateProtoService(PS_JOINCHAT,  &FacebookProto::OnJoinChat);
	CreateProtoService(PS_LEAVECHAT, &FacebookProto::OnLeaveChat);

	CreateProtoService("/Mind", &FacebookProto::OnMind);

	HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &FacebookProto::OnBuildStatusMenu);
	HookProtoEvent(ME_OPT_INITIALISE,           &FacebookProto::OnOptionsInit);
	HookProtoEvent(ME_IDLE_CHANGED,             &FacebookProto::OnIdleChanged);
	HookProtoEvent(ME_TTB_MODULELOADED,         &FacebookProto::OnToolbarInit);
	HookProtoEvent(ME_GC_EVENT,					&FacebookProto::OnGCEvent);
	HookProtoEvent(ME_GC_BUILDMENU,				&FacebookProto::OnGCMenuHook);
	HookProtoEvent(ME_DB_EVENT_MARKED_READ,		&FacebookProto::OnDbEventRead);
	HookProtoEvent(ME_MSG_WINDOWEVENT,			&FacebookProto::OnProcessSrmmEvent);

	db_set_resident(m_szModuleName, "Status");
	db_set_resident(m_szModuleName, "IdleTS");

	InitHotkeys();
	InitPopups();
	InitSounds();

	// Create standard network connection
	TCHAR descr[512];
	NETLIBUSER nlu = {sizeof(nlu)};
	nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR;
	nlu.szSettingsModule = m_szModuleName;
	mir_sntprintf(descr, SIZEOF(descr), TranslateT("%s server connection"), m_tszUserName);
	nlu.ptszDescriptiveName = descr;
	m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
	if (m_hNetlibUser == NULL)
		MessageBox(NULL, TranslateT("Unable to get Netlib connection for Facebook"), m_tszUserName, MB_OK);

	facy.set_handle(m_hNetlibUser);	

	// Set all contacts offline -- in case we crashed
	SetAllContactStatuses(ID_STATUS_OFFLINE);
}
Esempio n. 3
0
FacebookProto::FacebookProto(const char* proto_name,const TCHAR* username)
{
	m_iVersion = 2;
	m_szProtoName  = mir_strdup( proto_name );
	m_szModuleName = mir_strdup( proto_name );
	m_tszUserName  = mir_tstrdup( username );

	facy.parent = this;

	signon_lock_ = CreateMutex( NULL, FALSE, NULL );
	avatar_lock_ = CreateMutex( NULL, FALSE, NULL );
	log_lock_ = CreateMutex( NULL, FALSE, NULL );
	update_loop_lock_ = CreateEvent( NULL, FALSE, FALSE, NULL);
	facy.buddies_lock_ = CreateMutex( NULL, FALSE, NULL );
	facy.send_message_lock_ = CreateMutex( NULL, FALSE, NULL );
	facy.fcb_conn_lock_ = CreateMutex( NULL, FALSE, NULL );

	CreateProtoService(m_szModuleName, PS_CREATEACCMGRUI, &FacebookProto::SvcCreateAccMgrUI, this);
	CreateProtoService(m_szModuleName, PS_GETMYAWAYMSG,   &FacebookProto::GetMyAwayMsg,      this);
	CreateProtoService(m_szModuleName, PS_GETMYAVATAR,    &FacebookProto::GetMyAvatar,       this);
	CreateProtoService(m_szModuleName, PS_GETAVATARINFO,  &FacebookProto::GetAvatarInfo,     this);
	CreateProtoService(m_szModuleName, PS_GETAVATARCAPS,  &FacebookProto::GetAvatarCaps,     this);

	CreateProtoService(m_szModuleName, PS_JOINCHAT,  &FacebookProto::OnJoinChat,  this);
	CreateProtoService(m_szModuleName, PS_LEAVECHAT, &FacebookProto::OnLeaveChat, this);

	HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU,	&FacebookProto::OnBuildStatusMenu,	this);
	HookProtoEvent(ME_OPT_INITIALISE,			&FacebookProto::OnOptionsInit,		this);
	HookProtoEvent(ME_GC_EVENT,					&FacebookProto::OnChatOutgoing,		this);
	HookProtoEvent(ME_IDLE_CHANGED,             &FacebookProto::OnIdleChanged,		this);

	// Create standard network connection
	TCHAR descr[512];
	NETLIBUSER nlu = {sizeof(nlu)};
	nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR;
	nlu.szSettingsModule = m_szModuleName;
	char module[512];
	mir_snprintf(module,SIZEOF(module),"%sAv",m_szModuleName);
	nlu.szSettingsModule = module;
	mir_sntprintf(descr,SIZEOF(descr),TranslateT("%s server connection"),m_tszUserName);
	nlu.ptszDescriptiveName = descr;
	m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER,0,(LPARAM)&nlu);
	if(m_hNetlibUser == NULL)
		MessageBox(NULL,TranslateT("Unable to get Netlib connection for Facebook"),m_tszUserName,MB_OK);

	facy.set_handle(m_hNetlibUser);

	SkinAddNewSoundExT( "Notification", m_tszUserName, LPGENT( "Notification" ) );
	SkinAddNewSoundExT( "NewsFeed", m_tszUserName, LPGENT( "News Feed" ) );
	SkinAddNewSoundExT( "OtherEvent", m_tszUserName, LPGENT( "Other Event" ) );

	char *profile = Utils_ReplaceVars("%miranda_avatarcache%");
	def_avatar_folder_ = std::string(profile)+"\\"+m_szModuleName;
	mir_free(profile);
	hAvatarFolder_ = FoldersRegisterCustomPath(m_szModuleName, "Avatars", def_avatar_folder_.c_str());

	// Set all contacts offline -- in case we crashed
	SetAllContactStatuses( ID_STATUS_OFFLINE );
}
Esempio n. 4
0
void CVkProto::OnLoggedOut()
{
	m_bOnline = false;

	if (m_pollingConn)
		CallService(MS_NETLIB_SHUTDOWN, (WPARAM)m_pollingConn, 0);

	ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_OFFLINE);
	m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;

	CallFunctionAsync(VKUnsetTimer, this);
	SetAllContactStatuses(ID_STATUS_OFFLINE);
	m_chats.destroy();
}
Esempio n. 5
0
int TwitterProto::OnModulesLoaded(WPARAM, LPARAM)
{
	TCHAR descr[512];
	NETLIBUSER nlu = { sizeof(nlu) };
	nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS | NUF_TCHAR;
	nlu.szSettingsModule = m_szModuleName;

	// Create standard network connection
	mir_sntprintf(descr, TranslateT("%s server connection"), m_tszUserName);
	nlu.ptszDescriptiveName = descr;
	m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
	if (m_hNetlibUser == NULL) {
		TCHAR error[200];
		mir_sntprintf(error, TranslateT("Unable to initialize Netlib for %s."), m_tszUserName);
		MessageBox(NULL, error, _T("Miranda NG"), MB_OK | MB_ICONERROR);
	}

	// Create avatar network connection (TODO: probably remove this)
	char module[512];
	mir_snprintf(module, "%sAv", m_szModuleName);
	nlu.szSettingsModule = module;
	mir_sntprintf(descr, TranslateT("%s avatar connection"), m_tszUserName);
	nlu.ptszDescriptiveName = descr;
	hAvatarNetlib_ = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
	if (hAvatarNetlib_ == NULL) {
		TCHAR error[200];
		mir_sntprintf(error, TranslateT("Unable to initialize Netlib for %s."), TranslateT("Twitter (avatars)"));
		MessageBox(NULL, error, _T("Miranda NG"), MB_OK | MB_ICONERROR);
	}

	twit_.set_handle(this, m_hNetlibUser);

	GCREGISTER gcr = { sizeof(gcr) };
	gcr.pszModule = m_szModuleName;
	gcr.ptszDispName = m_tszUserName;
	gcr.iMaxText = 159;
	CallService(MS_GC_REGISTER, 0, reinterpret_cast<LPARAM>(&gcr));

	DBEVENTTYPEDESCR evt = { sizeof(evt) };
	evt.eventType = TWITTER_DB_EVENT_TYPE_TWEET;
	evt.module = m_szModuleName;
	evt.descr = "Tweet";
	evt.flags = DETF_HISTORY | DETF_MSGWINDOW;
	CallService(MS_DB_EVENT_REGISTERTYPE, 0, reinterpret_cast<LPARAM>(&evt));

	SetAllContactStatuses(ID_STATUS_OFFLINE); // In case we crashed last time
	return 0;
}
Esempio n. 6
0
WhatsAppProto::WhatsAppProto(const char *proto_name, const TCHAR *username)
	: PROTO<WhatsAppProto>(proto_name, username),
	m_tszDefaultGroup(getTStringA(WHATSAPP_KEY_DEF_GROUP))
{
	update_loop_lock_ = CreateEvent(NULL, false, false, NULL);

	db_set_resident(m_szModuleName, "StatusMsg");

	CreateProtoService(PS_CREATEACCMGRUI, &WhatsAppProto::SvcCreateAccMgrUI);

	CreateProtoService(PS_GETAVATARINFO, &WhatsAppProto::GetAvatarInfo);
	CreateProtoService(PS_GETAVATARCAPS, &WhatsAppProto::GetAvatarCaps);
	CreateProtoService(PS_GETMYAVATAR, &WhatsAppProto::GetMyAvatar);
	CreateProtoService(PS_SETMYAVATAR, &WhatsAppProto::SetMyAvatar);

	HookProtoEvent(ME_DB_CONTACT_DELETED, &WhatsAppProto::OnDeleteChat);
	HookProtoEvent(ME_OPT_INITIALISE, &WhatsAppProto::OnOptionsInit);
	HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &WhatsAppProto::OnBuildStatusMenu);

	// Create standard network connection
	TCHAR descr[512];
	mir_sntprintf(descr, TranslateT("%s server connection"), m_tszUserName);

	NETLIBUSER nlu = { sizeof(nlu) };
	nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR;
	nlu.szSettingsModule = m_szModuleName;
	nlu.ptszDescriptiveName = descr;
	m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
	if (m_hNetlibUser == NULL) {
		TCHAR error[200];
		mir_sntprintf(error, TranslateT("Unable to initialize Netlib for %s."), m_tszUserName);
		MessageBox(NULL, error, _T("Miranda NG"), MB_OK | MB_ICONERROR);
	}

	WASocketConnection::initNetwork(m_hNetlibUser);

	m_tszAvatarFolder = std::tstring(VARST(_T("%miranda_avatarcache%"))) + _T("\\") + m_tszUserName;
	DWORD dwAttributes = GetFileAttributes(m_tszAvatarFolder.c_str());
	if (dwAttributes == 0xffffffff || (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
		CreateDirectoryTreeT(m_tszAvatarFolder.c_str());

	if (m_tszDefaultGroup == NULL)
		m_tszDefaultGroup = mir_tstrdup(_T("WhatsApp"));
	Clist_CreateGroup(0, m_tszDefaultGroup);

	SetAllContactStatuses(ID_STATUS_OFFLINE, true);
}
Esempio n. 7
0
void CVkProto::OnLoggedOut()
{
	debugLogA("CVkProto::OnLoggedOut");
	m_bOnline = false;

	if (m_pollingConn)
		CallService(MS_NETLIB_SHUTDOWN, (WPARAM)m_pollingConn);

	ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_OFFLINE);
	m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;

	bool bOnline = false;
	{
		mir_cslock lck(csInstances);
		for (int i = 0; i < vk_Instances.getCount(); i++)
			bOnline = bOnline || vk_Instances[i]->IsOnline();
	}
	if (!bOnline)
		CallFunctionAsync(VKUnsetTimer, this);
	SetAllContactStatuses(ID_STATUS_OFFLINE);
	m_chats.destroy();
}
Esempio n. 8
0
CVkProto::CVkProto(const char *szModuleName, const TCHAR *ptszUserName) :
	PROTO<CVkProto>(szModuleName, ptszUserName),
	m_arRequestsQueue(10),
	m_sendIds(3, PtrKeySortT),
	m_cookies(5),
	m_msgId(1),
	m_chats(1, NumericKeySortT)
{
	InitQueue();

	CreateProtoService(PS_CREATEACCMGRUI, &CVkProto::SvcCreateAccMgrUI);
	CreateProtoService(PS_GETAVATARINFOT, &CVkProto::SvcGetAvatarInfo);
	CreateProtoService(PS_GETAVATARCAPS, &CVkProto::SvcGetAvatarCaps);

	HookProtoEvent(ME_OPT_INITIALISE, &CVkProto::OnOptionsInit);

	TCHAR descr[512];
	mir_sntprintf(descr, SIZEOF(descr), TranslateT("%s server connection"), m_tszUserName);

	NETLIBUSER nlu = {sizeof(nlu)};
	nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR;
	nlu.szSettingsModule = m_szModuleName;
	nlu.szSettingsModule = m_szModuleName;
	nlu.ptszDescriptiveName = descr;
	m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);

	m_defaultGroup = getTStringA("ProtoGroup");
	if (m_defaultGroup == NULL)
		m_defaultGroup = mir_tstrdup(_T("VKontakte"));
	Clist_CreateGroup(NULL, m_defaultGroup);

	db_set_resident(m_szModuleName, "Status");

	m_bServerDelivery = getBool("ServerDelivery", true);
	m_bHideChats = getBool("HideChats", true);

	// Set all contacts offline -- in case we crashed
	SetAllContactStatuses(ID_STATUS_OFFLINE);
}
Esempio n. 9
0
WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) :
    PROTO<WhatsAppProto>(proto_name, username)
{
    this->challenge = new std::vector<unsigned char>;
    this->msgId = 0;
    this->msgIdHeader = time(NULL);

    update_loop_lock_ = CreateEvent(NULL, false, false, NULL);
    FMessage::generating_lock = new Mutex();

    CreateProtoService(PS_CREATEACCMGRUI, &WhatsAppProto::SvcCreateAccMgrUI);
    CreateProtoService(PS_JOINCHAT, &WhatsAppProto::OnJoinChat);
    CreateProtoService(PS_LEAVECHAT, &WhatsAppProto::OnLeaveChat);

    HookProtoEvent(ME_OPT_INITIALISE, &WhatsAppProto::OnOptionsInit);
    HookProtoEvent(ME_SYSTEM_MODULESLOADED, &WhatsAppProto::OnModulesLoaded);
    HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &WhatsAppProto::OnBuildStatusMenu);

    this->InitContactMenus();

    // Create standard network connection
    TCHAR descr[512];
    NETLIBUSER nlu = {sizeof(nlu)};
    nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR;
    char module[512];
    mir_snprintf(module, SIZEOF(module), "%s", m_szModuleName);
    nlu.szSettingsModule = module;
    mir_sntprintf(descr, SIZEOF(descr), TranslateT("%s server connection"), m_tszUserName);
    nlu.ptszDescriptiveName = descr;
    m_hNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) &nlu);
    if (m_hNetlibUser == NULL)
        MessageBox(NULL, TranslateT("Unable to get Netlib connection for WhatsApp"), m_tszUserName, MB_OK);

    WASocketConnection::initNetwork(m_hNetlibUser);

    def_avatar_folder_ = std::tstring( VARST( _T("%miranda_avatarcache%"))) + _T("\\") + m_tszUserName;

    SetAllContactStatuses(ID_STATUS_OFFLINE, true);
}
Esempio n. 10
0
int TwitterProto::SetStatus(int new_status)
{
	int old_status = m_iStatus;
	if (new_status == m_iStatus)
		return 0;

	m_iDesiredStatus = new_status;
	// 40072 - 40080 are the "online" statuses, basically every status except offline.  see statusmodes.h
	if (new_status >= 40072 && new_status <= 40080) {

		m_iDesiredStatus = ID_STATUS_ONLINE; //i think i have to set this so it forces the twitter proto to be online (and not away, DND, etc)

		// if we're already connecting and they want to go online, BAIL!  we're already trying to connect you dumbass
		if (old_status == ID_STATUS_CONNECTING)
			return 0;

		// if we're already connected, and we change to another connected status, don't try and reconnect!
		if (old_status >= 40072 && old_status <= 40080)
			return 0;

		// i think here we tell the proto interface struct that we're connecting, just so it knows
		m_iStatus = ID_STATUS_CONNECTING;
		// ok.. here i think we're telling the core that this protocol something.. but why?
		ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);

		ForkThread(&TwitterProto::SignOn, this);
	}
	else if (new_status == ID_STATUS_OFFLINE) {
		twit_.Disconnect();
		m_iStatus = m_iDesiredStatus;
		SetAllContactStatuses(ID_STATUS_OFFLINE);

		ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
	}

	return 0;
}
Esempio n. 11
0
void WhatsAppProto::stayConnectedLoop(void*)
{
	ptrA cc(getStringA(WHATSAPP_KEY_CC));
	if (mir_strlen(cc) == 0) {
		NotifyEvent(m_tszUserName, TranslateT("Please enter a country code."), NULL, WHATSAPP_EVENT_CLIENT);
		return;
	}

	ptrA in(getStringA(WHATSAPP_KEY_LOGIN));
	if (mir_strlen(in) == 0) {
		NotifyEvent(m_tszUserName, TranslateT("Please enter a phone number without country code."), NULL, WHATSAPP_EVENT_CLIENT);
		return;
	}

	m_szPhoneNumber = std::string(cc) + std::string(in);
	m_szJid = m_szPhoneNumber + "@s.whatsapp.net";

	ptrA szNick(getStringA(WHATSAPP_KEY_NICK));
	if (mir_strlen(szNick) == 0) {
		NotifyEvent(m_tszUserName, TranslateT("Please enter a nickname."), NULL, WHATSAPP_EVENT_CLIENT);
		return;
	}
	m_szNick = szNick;

	ptrA szPassword(getStringA(WHATSAPP_KEY_PASS));
	if (mir_strlen(szPassword) == 0) {
		NotifyEvent(m_tszUserName, TranslateT("Please enter a password."), NULL, WHATSAPP_EVENT_CLIENT);
		return;
	}

	// -----------------------------
	Mutex writerMutex;
	bool error = false;

	m_pSocket = NULL;

	while (true) {
		if (m_pConnection != NULL) {
			delete m_pConnection;
			m_pConnection = NULL;
		}
		if (m_pSocket != NULL) {
			delete m_pSocket;
			m_pSocket = NULL;
		}

		if (m_iDesiredStatus == ID_STATUS_OFFLINE || error) {
			debugLogA("Set status to offline");
			SetAllContactStatuses(ID_STATUS_OFFLINE, true);
			ToggleStatusMenuItems(false);
			int prevStatus = m_iStatus;
			m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
			ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)prevStatus, m_iStatus);
			break;
		}

		debugLogA("Connecting...");

		try {
			unsigned passLen;
			ptrA passBin((char*)mir_base64_decode(szPassword, &passLen));
			std::string password(passBin, passLen), resource = ACCOUNT_RESOURCE;
			int portNumber;
			if (getByte(WHATSAPP_KEY_SSL, 0))
				portNumber = 443, resource += "-443";
			else
				portNumber = 5222, resource += "-5222";

			m_pSocket = new WASocketConnection("c.whatsapp.net", portNumber);
			m_pConnection = new WAConnection(m_szPhoneNumber, resource, &connMutex, &writerMutex, m_pSocket, this, this);
			{
				WALogin login(m_pConnection, password);

				m_Challenge = login.login(m_Challenge);
				m_pConnection->setLogin(&login);
			}
			m_pConnection->nick = m_szNick;
			if (m_iDesiredStatus != ID_STATUS_INVISIBLE)
				m_pConnection->sendAvailableForChat();

			debugLogA("Set status to online");
			m_iStatus = m_iDesiredStatus;
			ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus);
			ToggleStatusMenuItems(true);

			ForkThread(&WhatsAppProto::ProcessBuddyList, NULL);

			// #TODO Move out of try block. Exception is expected on disconnect
			while (true) {
				m_tLastWriteTime = time(NULL);
				if (!m_pConnection->read())
					break;
			}
			debugLogA("Exit from read-loop");
		}
		catch (WAException &e) {
			debugLogA("Exception: %s", e.what());
			error = true;
		}
		catch (exception &e) {
			debugLogA("Exception: %s", e.what());
			error = true;
		}
		catch (...) {
			debugLogA("Unknown exception");
			error = true;
		}
	}
	debugLogA("Break out from loop");
}
Esempio n. 12
0
int WhatsAppProto::SetStatus(int new_status)
{
	if (m_iDesiredStatus == new_status)
		return 0;

	int oldStatus = m_iStatus;
	debugLogA("===== Beginning SetStatus process");

	// Routing statuses not supported by WhatsApp
	switch (new_status) {
	case ID_STATUS_INVISIBLE:
	case ID_STATUS_OFFLINE:
		m_iDesiredStatus = new_status;
		break;

	case ID_STATUS_IDLE:
	default:
		m_iDesiredStatus = ID_STATUS_INVISIBLE;
		if (getByte(WHATSAPP_KEY_MAP_STATUSES, DEFAULT_MAP_STATUSES))
			break;
	case ID_STATUS_ONLINE:
	case ID_STATUS_FREECHAT:
		m_iDesiredStatus = ID_STATUS_ONLINE;
		break;
	}

	if (m_iDesiredStatus == ID_STATUS_OFFLINE) {
		if (m_pSocket != NULL) {
			SetEvent(update_loop_lock_);
			m_pSocket->forceShutdown();
			debugLogA("Forced shutdown");
		}

		m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
		ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
	}
	else if (m_pSocket == NULL && !IsStatusConnecting(m_iStatus)) {
		m_iStatus = ID_STATUS_CONNECTING;
		ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);

		ResetEvent(update_loop_lock_);
		ForkThread(&WhatsAppProto::sentinelLoop, 0);
		ForkThread(&WhatsAppProto::stayConnectedLoop, 0);
	}
	else if (m_pConnection != NULL) {
		if (m_iDesiredStatus == ID_STATUS_ONLINE) {
			m_pConnection->sendAvailableForChat();
			m_iStatus = ID_STATUS_ONLINE;
			ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
		}
		else if (m_iStatus == ID_STATUS_ONLINE && m_iDesiredStatus == ID_STATUS_INVISIBLE) {
			m_pConnection->sendClose();
			m_iStatus = ID_STATUS_INVISIBLE;
			SetAllContactStatuses(ID_STATUS_OFFLINE, true);
			ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
		}
	}
	else ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);

	return 0;
}
Esempio n. 13
0
void FacebookProto::ChangeStatus(void*)
{
	ScopedLock s(signon_lock_);
	ScopedLock b(facy.buddies_lock_);

	int new_status = m_iDesiredStatus;
	int old_status = m_iStatus;

	if (new_status == ID_STATUS_OFFLINE)
	{ // Logout	
		debugLogA("### Beginning SignOff process");
		m_signingOut = true;

		SetEvent(update_loop_lock_);

		// Shutdown and close channel handle
		Netlib_Shutdown(facy.hMsgCon);
		if (facy.hMsgCon)
			Netlib_CloseHandle(facy.hMsgCon);
		facy.hMsgCon = NULL;

		// Turn off chat on Facebook
		if (getByte(FACEBOOK_KEY_DISCONNECT_CHAT, DEFAULT_DISCONNECT_CHAT))
			facy.chat_state(false);

		facy.logout();

		OnLeaveChat(NULL, NULL);
		SetAllContactStatuses(ID_STATUS_OFFLINE);
		ToggleStatusMenuItems(false);
		delSetting(FACEBOOK_KEY_LOGON_TS);

		facy.chat_traceid_.clear();
		facy.chat_sticky_num_.clear();
		facy.chat_sticky_pool_.clear();
		facy.chat_msgs_recv_ = 0;
		facy.chat_req_ = 0;

		facy.clear_cookies();
		facy.clear_notifications();
		facy.clear_chatrooms();
		facy.clear_readers();
		facy.buddies.clear();
		facy.messages_ignore.clear();
		facy.messages_timestamp.clear();
		facy.pages.clear();
		facy.typers.clear();

		// Clear thread/user id caches?
		/* Right now it's commented out because it's not really needed to erase - maybe only when user changes login/pass in same account, but even then it shouldn't cause problems
		facy.thread_id_to_user_id.clear();
		facy.chat_id_to_hcontact.clear();
		facy.user_id_to_hcontact.clear();
		*/

		// Close connection handle
		if (facy.hFcbCon)
			Netlib_CloseHandle(facy.hFcbCon);
		facy.hFcbCon = NULL;

		m_iStatus = facy.self_.status_id = ID_STATUS_OFFLINE;
		ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);

		m_signingOut = false;
		debugLogA("### SignOff complete");

		return;
	}
	else if (old_status == ID_STATUS_OFFLINE)
	{ // Login
		SYSTEMTIME t;
		GetLocalTime(&t);
		debugLogA("[%d.%d.%d] Using Facebook Protocol RM %s", t.wDay, t.wMonth, t.wYear, __VERSION_STRING_DOTS);

		debugLogA("*** Beginning SignOn process");

		m_enableChat = getBool(FACEBOOK_KEY_ENABLE_CHATS, DEFAULT_ENABLE_CHATS);

		m_iStatus = facy.self_.status_id = ID_STATUS_CONNECTING;
		ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);

		ResetEvent(update_loop_lock_);

		// Workaround for not working "mbasic." for some users - reset this flag at every login
		facy.mbasicWorks = true;

		if (NegotiateConnection() && facy.home() && facy.reconnect())
		{
			// Load all friends
			ProcessFriendList(NULL);

			// Process friendship requests
			ForkThread(&FacebookProto::ProcessFriendRequests, NULL);

			// Sync threads, get messages - or get unread messages
			if (getBool(FACEBOOK_KEY_LOGIN_SYNC, DEFAULT_LOGIN_SYNC))
				ForkThread(&FacebookProto::SyncThreads, NULL);
			else
				ForkThread(&FacebookProto::ProcessUnreadMessages, NULL);

			// Get notifications
			ForkThread(&FacebookProto::ProcessNotifications, NULL);

			// Load pages for post status dialog
			ForkThread(&FacebookProto::ProcessPages, NULL);

			// Load on this day posts
			if (getByte(FACEBOOK_KEY_EVENT_ON_THIS_DAY_ENABLE, DEFAULT_EVENT_ON_THIS_DAY_ENABLE))
				ForkThread(&FacebookProto::ProcessOnThisDay, NULL);

			setDword(FACEBOOK_KEY_LOGON_TS, (DWORD)time(NULL));
			ForkThread(&FacebookProto::UpdateLoop, NULL);
			ForkThread(&FacebookProto::MessageLoop, NULL);

			if (getByte(FACEBOOK_KEY_SET_MIRANDA_STATUS, DEFAULT_SET_MIRANDA_STATUS))
				ForkThread(&FacebookProto::SetAwayMsgWorker, NULL);
		}
		else {
			ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_FAILED, (HANDLE)old_status, m_iStatus);

			if (facy.hFcbCon)
				Netlib_CloseHandle(facy.hFcbCon);
			facy.hFcbCon = NULL;

			facy.clear_cookies();

			// Set to offline
			m_iStatus = m_iDesiredStatus = facy.self_.status_id = ID_STATUS_OFFLINE;
			ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);

			debugLogA("*** SignOn failed");

			return;
		}

		ToggleStatusMenuItems(true);
		debugLogA("*** SignOn complete");
	}

	m_invisible = (new_status == ID_STATUS_INVISIBLE);

	// Remember time of switching to away (and if we are idle already, use the idle time)
	m_awayTS = (new_status == ID_STATUS_AWAY ? (m_idleTS > 0 ? m_idleTS : ::time(NULL)) : 0);

	facy.chat_state(!m_invisible);

	ForkThread(&FacebookProto::ProcessBuddyList, NULL);

	m_iStatus = facy.self_.status_id = new_status;
	ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);

	debugLogA("*** ChangeStatus complete");
}
Esempio n. 14
0
CVkProto::CVkProto(const char *szModuleName, const TCHAR *ptszUserName) :
	PROTO<CVkProto>(szModuleName, ptszUserName),
	m_arRequestsQueue(10, sttCompareAsyncHttpRequest),
	m_sendIds(3, PtrKeySortT),
	m_incIds(3, PtrKeySortT),
	m_cookies(5),
	m_msgId(1),
	m_chats(1, NumericKeySortT)
{
	InitQueue();

	CreateProtoService(PS_CREATEACCMGRUI, &CVkProto::SvcCreateAccMgrUI);
	CreateProtoService(PS_GETAVATARINFO, &CVkProto::SvcGetAvatarInfo);
	CreateProtoService(PS_GETAVATARCAPS, &CVkProto::SvcGetAvatarCaps);
	CreateProtoService(PS_GETMYAVATAR, &CVkProto::SvcGetMyAvatar);
	CreateProtoService(PS_SET_LISTENINGTO, &CVkProto::SvcSetListeningTo);

	HookProtoEvent(ME_OPT_INITIALISE, &CVkProto::OnOptionsInit);

	TCHAR descr[512];
	mir_sntprintf(descr, TranslateT("%s server connection"), m_tszUserName);

	NETLIBUSER nlu = {sizeof(nlu)};
	nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR;
	nlu.szSettingsModule = m_szModuleName;
	nlu.ptszDescriptiveName = descr;
	m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);

	m_defaultGroup = getTStringA("ProtoGroup");
	if (m_defaultGroup == NULL)
		m_defaultGroup = mir_tstrdup(_T("VKontakte"));
	Clist_CreateGroup(NULL, m_defaultGroup);

	m_bServerDelivery = getBool("ServerDelivery", true);
	m_bHideChats = getBool("HideChats", true);
	m_bMesAsUnread = getBool("MesAsUnread");
	m_bUseLocalTime = getBool("UseLocalTime");
	m_bReportAbuse = getBool("ReportAbuseOnBanUser");
	m_bClearServerHistory = getBool("ClearServerHistoryOnBanUser");
	m_bRemoveFromFrendlist = getBool("RemoveFromFrendlistOnBanUser");
	m_bRemoveFromClist = getBool("RemoveFromClistOnBanUser");
	m_bPopUpSyncHistory = getBool("PopUpSyncHistory");
	m_iMarkMessageReadOn = (MarkMsgReadOn)getByte("MarkMessageReadOn", markOnRead);
	m_bStikersAsSmyles = getBool("StikersAsSmyles");
	m_bUserForceOnlineOnActivity = getBool("UserForceOnlineOnActivity");
	m_iMusicSendMetod = (MusicSendMetod)getByte("MusicSendMetod", sendBroadcastOnly);
	m_iSyncHistoryMetod = (SyncHistoryMetod)getByte("SyncHistoryMetod", syncOff);
	CMStringA szListeningTo(m_szModuleName);
	szListeningTo += "Enabled";
	db_set_b(NULL, "ListeningTo", szListeningTo, m_iMusicSendMetod == 0 ? 0 : 1);
	
	m_bNewsEnabled = getBool("NewsEnabled");
	m_iMaxLoadNewsPhoto = getByte("MaxLoadNewsPhoto", 5);
	m_bNotificationsEnabled = getBool("NotificationsEnabled");
	m_bNotificationsMarkAsViewed = getBool("NotificationsMarkAsViewed", true);
	m_bSpecialContactAlwaysEnabled = getBool("SpecialContactAlwaysEnabled");
	m_iNewsInterval = getDword("NewsInterval", 15);
	m_iNotificationsInterval = getDword("NotificationsInterval", 1);
	m_iIMGBBCSupport = (IMGBBCSypport)getByte("IMGBBCSupport", imgNo);
	m_iBBCForNews = (BBCSupport)getByte("BBCForNews", bbcBasic);
	m_iBBCForAttachments = (BBCSupport)getByte("BBCForAttachments", bbcBasic);
	m_bUseBBCOnAttacmentsAsNews = getBool("UseBBCOnAttacmentsAsNews", true);
	m_bNewsAutoClearHistory = getBool("NewsAutoClearHistory");
	m_iNewsAutoClearHistoryInterval = getDword("NewsAutoClearHistoryInterval", 60*60*24*3);

	m_bNewsFilterPosts = getBool("NewsFilterPosts", true);
	m_bNewsFilterPhotos = getBool("NewsFilterPhotos", true);
	m_bNewsFilterTags = getBool("NewsFilterTags", true);
	m_bNewsFilterWallPhotos = getBool("NewsFilterWallPhotos", true);
	m_bNewsSourceFriends = getBool("NewsSourceFriends", true);
	m_bNewsSourceGroups = getBool("NewsSourceGroups", true);
	m_bNewsSourcePages = getBool("NewsSourcePages", true);
	m_bNewsSourceFollowing = getBool("NewsSourceFollowing", true);
	m_bNewsSourceIncludeBanned = getBool("NewsSourceIncludeBanned");
	m_bNewsSourceNoReposts = getBool("NewsSourceNoReposts");

	m_bNotificationFilterComments = getBool("NotificationFilterComments", true);
	m_bNotificationFilterLikes = getBool("NotificationFilterLikes", true);
	m_bNotificationFilterReposts = getBool("NotificationFilterReposts", true);
	m_bNotificationFilterMentions = getBool("NotificationFilterMentions", true);
	m_bNotificationFilterInvites = getBool("NotificationFilterInvites", true);

	m_bUseNonStandardUrlEncode = getBool("UseNonStandardUrlEncode", true);
	m_iInvisibleInterval = getDword("InvisibleInterval", 10);

	m_bShortenLinksForAudio = getBool("ShortenLinksForAudio", true);

	m_bSplitFormatFwdMsg = getBool("SplitFormatFwdMsg", true);
	
	m_bSetBroadcast = false;
	m_bNeedSendOnline = false;
	delSetting("InviteGroupIds");

	// Set all contacts offline -- in case we crashed
	SetAllContactStatuses(ID_STATUS_OFFLINE);
	{
		mir_cslock lck(csInstances);
		vk_Instances.insert(this);
	}
}
Esempio n. 15
0
FacebookProto::FacebookProto(const char* proto_name, const TCHAR* username) :
	PROTO<FacebookProto>(proto_name, username),
	m_tszDefaultGroup(getTStringA(FACEBOOK_KEY_DEF_GROUP))
{
	facy.parent = this;

	signon_lock_ = CreateMutex(NULL, FALSE, NULL);
	avatar_lock_ = CreateMutex(NULL, FALSE, NULL);
	log_lock_ = CreateMutex(NULL, FALSE, NULL);
	update_loop_lock_ = CreateEvent(NULL, FALSE, FALSE, NULL);
	facy.buddies_lock_ = CreateMutex(NULL, FALSE, NULL);
	facy.send_message_lock_ = CreateMutex(NULL, FALSE, NULL);
	facy.fcb_conn_lock_ = CreateMutex(NULL, FALSE, NULL);
	facy.notifications_lock_ = CreateMutex(NULL, FALSE, NULL);
	facy.cookies_lock_ = CreateMutex(NULL, FALSE, NULL);

	// Initialize random seed for this client
	facy.random_ = ::time(NULL) + PtrToUint(&facy);

	m_enableChat = DEFAULT_ENABLE_CHATS;

	// Load custom locale, if set
	ptrA locale(getStringA(FACEBOOK_KEY_LOCALE));
	if (locale != NULL)
		m_locale = locale;

	if (m_tszDefaultGroup == NULL)
		m_tszDefaultGroup = mir_tstrdup(_T("Facebook"));

	CreateProtoService(PS_CREATEACCMGRUI, &FacebookProto::SvcCreateAccMgrUI);
	CreateProtoService(PS_GETMYAWAYMSG, &FacebookProto::GetMyAwayMsg);
	CreateProtoService(PS_GETMYAVATAR, &FacebookProto::GetMyAvatar);
	CreateProtoService(PS_GETAVATARINFO, &FacebookProto::GetAvatarInfo);
	CreateProtoService(PS_GETAVATARCAPS, &FacebookProto::GetAvatarCaps);
	CreateProtoService(PS_GETUNREADEMAILCOUNT, &FacebookProto::GetNotificationsCount);

	CreateProtoService(PS_JOINCHAT, &FacebookProto::OnJoinChat);
	CreateProtoService(PS_LEAVECHAT, &FacebookProto::OnLeaveChat);

	HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &FacebookProto::OnBuildStatusMenu);
	HookProtoEvent(ME_OPT_INITIALISE, &FacebookProto::OnOptionsInit);
	HookProtoEvent(ME_IDLE_CHANGED, &FacebookProto::OnIdleChanged);
	HookProtoEvent(ME_TTB_MODULELOADED, &FacebookProto::OnToolbarInit);
	HookProtoEvent(ME_GC_EVENT, &FacebookProto::OnGCEvent);
	HookProtoEvent(ME_GC_BUILDMENU, &FacebookProto::OnGCMenuHook);
	HookProtoEvent(ME_DB_EVENT_MARKED_READ, &FacebookProto::OnDbEventRead);

	db_set_resident(m_szModuleName, "IdleTS");
	db_set_resident(m_szModuleName, FACEBOOK_KEY_MESSAGE_READ);
	db_set_resident(m_szModuleName, FACEBOOK_KEY_MESSAGE_READERS);

	InitHotkeys();
	InitPopups();
	InitSounds();

	// Create standard network connection
	TCHAR descr[512];
	NETLIBUSER nlu = { sizeof(nlu) };
	nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR;
	nlu.szSettingsModule = m_szModuleName;
	mir_sntprintf(descr, TranslateT("%s server connection"), m_tszUserName);
	nlu.ptszDescriptiveName = descr;
	m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
	if (m_hNetlibUser == NULL) {
		TCHAR error[200];
		mir_sntprintf(error, TranslateT("Unable to initialize Netlib for %s."), m_tszUserName);
		MessageBox(NULL, error, _T("Miranda NG"), MB_OK | MB_ICONERROR);
	}

	facy.set_handle(m_hNetlibUser);

	// Set all contacts offline -- in case we crashed
	SetAllContactStatuses(ID_STATUS_OFFLINE);

	// register special type of event
	// there's no need to declare the special service for getting text
	// because a blob contains only text
	DBEVENTTYPEDESCR evtype = { sizeof(evtype) };
	evtype.module = m_szModuleName;
	evtype.eventType = FACEBOOK_EVENTTYPE_CALL;
	evtype.descr = LPGEN("Video call");
	evtype.eventIcon = GetIconHandle("facebook");
	evtype.flags = DETF_HISTORY | DETF_MSGWINDOW;
	CallService(MS_DB_EVENT_REGISTERTYPE, 0, (LPARAM)&evtype);
}