コード例 #1
0
ファイル: connection.cpp プロジェクト: ybznek/miranda-ng
void CAimProto::aim_connection_authorization(void)
{
	if (m_iDesiredStatus != ID_STATUS_OFFLINE) {
		char *password = getStringA(AIM_KEY_PW);
		if (password != NULL) {
			mir_free(m_username);
			m_username = getStringA(AIM_KEY_SN);
			if (m_username != NULL) {
				HANDLE hServerPacketRecver = (HANDLE)CallService(MS_NETLIB_CREATEPACKETRECVER, (WPARAM)m_hServerConn, 2048 * 4);
				NETLIBPACKETRECVER packetRecv = { 0 };
				packetRecv.cbSize = sizeof(packetRecv);
				packetRecv.dwTimeout = 5000;
				for (;;) {
					int recvResult = CallService(MS_NETLIB_GETMOREPACKETS, (WPARAM)hServerPacketRecver, (LPARAM)& packetRecv);
					if (recvResult == 0) {
						debugLogA("Connection Closed: No Error? during Connection Authorization");
						break;
					}
					else if (recvResult < 0) {
						debugLogA("Connection Closed: Socket Error during Connection Authorization %d", WSAGetLastError());
						break;
					}
					else {
						unsigned short flap_length = 0;
						for (; packetRecv.bytesUsed < packetRecv.bytesAvailable; packetRecv.bytesUsed = flap_length) {
							if (!packetRecv.buffer)
								break;

							FLAP flap((char*)&packetRecv.buffer[packetRecv.bytesUsed], (unsigned short)(packetRecv.bytesAvailable - packetRecv.bytesUsed));
							if (!flap.len())
								break;

							flap_length += FLAP_SIZE + flap.len();
							if (flap.cmp(0x01)) {
								if (aim_send_connection_packet(m_hServerConn, m_seqno, flap.val()) == 0) // cookie challenge
									aim_authkey_request(m_hServerConn, m_seqno); // md5 authkey request
							}
							else if (flap.cmp(0x02)) {
								SNAC snac(flap.val(), flap.snaclen());
								if (snac.cmp(0x0017)) {
									snac_md5_authkey(snac, m_hServerConn, m_seqno, m_username, password);
									int authres = snac_authorization_reply(snac);
									switch (authres) {
									case 1:
										mir_free(password);
										Netlib_CloseHandle(hServerPacketRecver);
										debugLogA("Connection Authorization Thread Ending: Negotiation Beginning");
										return;

									case 2:
										ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_WRONGPASSWORD);
										goto exit;

									case 3:
										ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_NOSERVER);
										goto exit;
									}
								}
							}
							else if (flap.cmp(0x04)) {
								debugLogA("Connection Authorization Thread Ending: Flap 0x04");
								goto exit;
							}
						}
					}
				}
			exit:
				if (hServerPacketRecver)
					Netlib_CloseHandle(hServerPacketRecver);
			}
		}
		mir_free(password);
	}
	if (m_iStatus != ID_STATUS_OFFLINE)
		broadcast_status(ID_STATUS_OFFLINE);
	Netlib_CloseHandle(m_hServerConn);
	m_hServerConn = NULL;
	debugLogA("Connection Authorization Thread Ending: End of Thread");
}
コード例 #2
0
ファイル: skype_login.cpp プロジェクト: kxepal/miranda-ng
void CSkypeProto::OnEndpointCreated(const NETLIBHTTPREQUEST *response)
{
	if (!IsStatusConnecting(m_iStatus)) return;

	m_iStatus++;

	if (response == NULL)
	{
		debugLogA(__FUNCTION__ ": failed to get create endpoint");
		ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
		SetStatus(ID_STATUS_OFFLINE);
		return;
	}

	for (int i = 0; i < response->headersCount; i++)
	{
		if (!mir_strcmpi(response->headers[i].szName, "Set-RegistrationToken"))
		{
			CMStringA szValue = response->headers[i].szValue, szCookieName, szCookieVal;
			int iStart = 0;
			while (true)
			{
				CMStringA szToken = szValue.Tokenize(";", iStart).Trim();
				if (iStart == -1)
					break;
				int iStart2 = 0;
				szCookieName = szToken.Tokenize("=", iStart2);
				szCookieVal = szToken.Mid(iStart2);
				setString(szCookieName, szCookieVal);
			}
		}
		else if (!mir_strcmpi(response->headers[i].szName, "Location"))
		{
			CMStringA szValue = response->headers[i].szValue;
			li.endpoint.szServer = GetServerFromUrl(szValue).Detach();
			setString("Server", li.endpoint.szServer);
		}

	}

	if (m_iStatus++ > SKYPE_MAX_CONNECT_RETRIES)
	{
		debugLogA(__FUNCTION__ ": failed to create endpoint (too many connect retries)");
		ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
		SetStatus(ID_STATUS_OFFLINE);
		return;
	}

	if (response->resultCode != 201)
	{
		if (response->resultCode == 401)
		{
			delSetting("TokenExpiresIn");
			SendRequest(new LoginOAuthRequest(li.szSkypename, ptrA(getStringA(SKYPE_SETTINGS_PASSWORD))), &CSkypeProto::OnLoginOAuth);
			return;
		}
		else //it should be rewritten
		{
			SendRequest(new CreateEndpointRequest(li), &CSkypeProto::OnEndpointCreated);
			return;
		}
	}

	li.endpoint.szToken = getStringA("registrationToken");
	li.endpoint.szId = getStringA("endpointId");

	SendRequest(new CreateSubscriptionsRequest(li), &CSkypeProto::OnSubscriptionsCreated);
}
コード例 #3
0
ファイル: steam_login.cpp プロジェクト: ybznek/miranda-ng
void CSteamProto::OnGotRsaKey(const HttpResponse *response)
{
	if (!CheckResponse(response))
		return;

	// load rsa key parts
	JSONNode root = JSONNode::parse(response->pData);
	if (!root)
		return;

	if (!root["success"].as_bool())
		return;

	std::string modulus = root["publickey_mod"].as_string();
	// exponent "010001" is used as constant in CSteamProto::RsaEncrypt
	//std::string exponent = root["publickey_exp"].as_string();

	std::string timestamp = root["timestamp"].as_string();

	// encrcrypt password
	ptrA base64RsaEncryptedPassword;
	ptrA szPassword(getStringA("Password"));

	DWORD error = 0;
	DWORD encryptedSize = 0;
	if ((error = RsaEncrypt(modulus.c_str(), szPassword, NULL, encryptedSize)) != 0)
	{
		debugLogA("CSteamProto::OnGotRsaKey: encryption error (%lu)", error);
		return;
	}

	BYTE *encryptedPassword = (BYTE*)mir_calloc(encryptedSize);
	if ((error = RsaEncrypt(modulus.c_str(), szPassword, encryptedPassword, encryptedSize)) != 0)
	{
		debugLogA("CSteamProto::OnGotRsaKey: encryption error (%lu)", error);
		return;
	}

	base64RsaEncryptedPassword = mir_base64_encode(encryptedPassword, encryptedSize);
	mir_free(encryptedPassword);

	// run authorization request
	T2Utf username(getTStringA("Username"));

	ptrA twoFactorCode(getStringA("TwoFactorCode"));
	if (!twoFactorCode) twoFactorCode = mir_strdup("");

	ptrA guardId(getStringA("GuardId"));
	if (!guardId) guardId = mir_strdup("");
	ptrA guardCode(getStringA("GuardCode"));
	if (!guardCode) guardCode = mir_strdup("");

	ptrA captchaId(getStringA("CaptchaId"));
	if (!captchaId) captchaId = mir_strdup("-1");
	ptrA captchaText(getStringA("CaptchaText"));
	if (!captchaText) captchaText = mir_strdup("");

	PushRequest(
		new AuthorizationRequest(username, base64RsaEncryptedPassword, timestamp.c_str(), twoFactorCode, guardCode, guardId, captchaId, captchaText),
		&CSteamProto::OnAuthorization);
}
コード例 #4
0
ファイル: connection.cpp プロジェクト: ybznek/miranda-ng
void CAimProto::aim_connection_clientlogin(void)
{
	pass_ptrA password(getStringA(AIM_KEY_PW));
	replaceStr(m_username, ptrA(getStringA(AIM_KEY_SN)));

	CMStringA buf;
	buf.Format("devId=%s&f=xml&pwd=%s&s=%s", AIM_DEFAULT_CLIENT_KEY, ptrA(mir_urlEncode(password)), ptrA(mir_urlEncode(m_username)));

	NETLIBHTTPHEADER headers[] = {
		{ "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8" }
	};

	NETLIBHTTPREQUEST req = { 0 };
	req.cbSize = sizeof(req);
	req.flags = NLHRF_SSL;
	req.requestType = REQUEST_POST;
	req.szUrl = AIM_LOGIN_URL;
	req.headers = headers;
	req.headersCount = _countof(headers);
	req.pData = buf.GetBuffer();
	req.dataLength = buf.GetLength();

	NLHR_PTR resp(CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&req));
	if (!resp || !resp->dataLength) {
		broadcast_status(ID_STATUS_OFFLINE);
		return;
	}

	time_t hosttime;
	CMStringA token, secret;
	if (!parse_clientlogin_response(resp, headers, token, secret, hosttime)) {
		//TODO: handle error
		broadcast_status(ID_STATUS_OFFLINE);
		mir_free(headers[0].szValue);
		return;
	}

	bool encryption = !getByte(AIM_KEY_DSSL, 0);
	CMStringA url;
	fill_session_url(url, token, secret, hosttime, password, encryption);

	// reuse NETLIBHTTPREQUEST
	req.requestType = REQUEST_GET;
	req.pData = NULL;
	req.flags |= NLHRF_MANUALHOST;
	req.dataLength = 0;
	req.headersCount = 1;
	req.szUrl = url.GetBuffer();
	{
		NETLIBHTTPHEADER headers2[] = {
			{ "Host", "api.oscar.aol.com" },
		};
		req.headers = headers2;

		resp = CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&req);
	}

	if (!resp || !resp->dataLength) {
		// TODO: handle error
		broadcast_status(ID_STATUS_OFFLINE);
		return;
	}

	CMStringA bos_host, cookie, tls_cert_name; //TODO: find efficient buf size
	unsigned short bos_port = 0;
	if (!parse_start_socar_session_response(resp->pData, bos_host, bos_port, cookie, tls_cert_name, encryption)) {
		// TODO: handle error
		broadcast_status(ID_STATUS_OFFLINE);
		return;
	}

	m_hServerConn = aim_connect(bos_host, bos_port, (tls_cert_name[0] && encryption) ? true : false, bos_host);
	if (!m_hServerConn) {
		// TODO: handle error
		broadcast_status(ID_STATUS_OFFLINE);
		return;
	}

	replaceStr(COOKIE, cookie);
	COOKIE_LENGTH = (int)mir_strlen(cookie);

	ForkThread(&CAimProto::aim_protocol_negotiation, 0);
}
コード例 #5
0
ファイル: contacts.cpp プロジェクト: kxepal/miranda-ng
std::string FacebookProto::ThreadIDToContactID(const std::string &thread_id)
{
	if (thread_id.empty()) {
		debugLogA("!!! Calling ThreadIDToContactID() with empty thread_id");
		return "";
	}

	// First check cache
	std::map<std::string, std::string>::iterator it = facy.thread_id_to_user_id.find(thread_id);
	if (it != facy.thread_id_to_user_id.end()) {
		return it->second;
	}

	// Go through all local contacts
	for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) {
		if (!IsMyContact(hContact))
			continue;

		ptrA tid(getStringA(hContact, FACEBOOK_KEY_TID));
		if (tid && !mir_strcmp(tid, thread_id.c_str())) {
			ptrA id(getStringA(hContact, FACEBOOK_KEY_ID));
			std::string user_id = (id ? id : "");
			if (!user_id.empty()) {
				facy.thread_id_to_user_id.insert(std::make_pair(thread_id, user_id));
				return user_id;
			}
			break; // this shouldn't happen unless user manually deletes ID from FB contact in DB
		}
	}

	// We don't have any contact with this thread_id cached, we must ask server	
	if (isOffline())
		return "";

	std::string data = "client=mercury";
	data += "&__user="******"&__dyn=" + facy.__dyn();
	data += "&__req=" + facy.__req();
	data += "&fb_dtsg=" + facy.dtsg_;
	data += "&ttstamp=" + facy.ttstamp_;
	data += "&__rev=" + facy.__rev();

	data += "&threads[thread_ids][0]=" + utils::url::encode(thread_id);

	std::string user_id;
	http::response resp = facy.flap(REQUEST_THREAD_INFO, &data); // NOTE: Request revised 1.9.2015

	if (resp.code == HTTP_CODE_OK) {
		CODE_BLOCK_TRY

			facebook_json_parser* p = new facebook_json_parser(this);
		p->parse_thread_info(&resp.data, &user_id);
		delete p;

		if (!user_id.empty())
			facy.thread_id_to_user_id.insert(std::make_pair(thread_id, user_id));

		debugLogA("*** Thread info processed");

		CODE_BLOCK_CATCH

			debugLogA("*** Error processing thread info: %s", e.what());

		CODE_BLOCK_END
	}
コード例 #6
0
ファイル: steam_login.cpp プロジェクト: ybznek/miranda-ng
void CSteamProto::OnAuthorizationError(const JSONNode &node)
{
	std::string message = node["message"].as_string();
	ptrT messageT(mir_utf8decodeT(message.c_str()));
	debugLogA("CSteamProto::OnAuthorizationError: %s", message.c_str());

	if (!mir_tstrcmpi(messageT, _T("Incorrect login.")))
	{
		// We can't continue with incorrect login/password
		DeleteAuthSettings();
		SetStatus(ID_STATUS_OFFLINE);
		return;
	}

	T2Utf username(getTStringA("Username"));

	if (node["requires_twofactor"].as_bool())
	{
		debugLogA("CSteamProto::OnAuthorizationError: requires twofactor");

		CSteamTwoFactorDialog twoFactorDialog(this);
		if (twoFactorDialog.DoModal() != DIALOG_RESULT_OK)
		{
			DeleteAuthSettings();
			SetStatus(ID_STATUS_OFFLINE);
			return;
		}

		setString("TwoFactorCode", twoFactorDialog.GetTwoFactorCode());

		PushRequest(
			new GetRsaKeyRequest(username),
			&CSteamProto::OnGotRsaKey);
		return;
	}

	if (node["clear_password_field"].as_bool())
	{
		debugLogA("CSteamProto::OnAuthorizationError: clear password field");
		return;
	}

	if (node["emailauth_needed"].as_bool())
	{
		debugLogA("CSteamProto::OnAuthorizationError: emailauth needed");

		std::string guardId = node["emailsteamid"].as_string();
		ptrA oldGuardId(getStringA("GuardId"));
		if (mir_strcmp(guardId.c_str(), oldGuardId) == 0)
		{
			delSetting("GuardId");
			delSetting("GuardCode");
			PushRequest(
				new GetRsaKeyRequest(username),
				&CSteamProto::OnGotRsaKey);
			return;
		}

		std::string domain = node["emaildomain"].as_string();

		// Make absolute link
		if (domain.find("://") == std::string::npos)
			domain = "http://" + domain;

		CSteamGuardDialog guardDialog(this, domain.c_str());
		if (guardDialog.DoModal() != DIALOG_RESULT_OK)
		{
			DeleteAuthSettings();
			SetStatus(ID_STATUS_OFFLINE);
			return;
		}

		setString("GuardId", guardId.c_str());
		setString("GuardCode", guardDialog.GetGuardCode());

		PushRequest(
			new GetRsaKeyRequest(username),
			&CSteamProto::OnGotRsaKey);
		return;
	}

	if (node["captcha_needed"].as_bool())
	{
		debugLogA("CSteamProto::OnAuthorizationError: captcha needed");

		std::string captchaId = node["captcha_gid"].as_string();

		GetCaptchaRequest *request = new GetCaptchaRequest(captchaId.c_str());
		HttpResponse *response = request->Send(m_hNetlibUser);
		delete request;

		CSteamCaptchaDialog captchaDialog(this, (BYTE*)response->pData, response->dataLength);
		delete response;
		if (captchaDialog.DoModal() != DIALOG_RESULT_OK)
		{
			DeleteAuthSettings();
			SetStatus(ID_STATUS_OFFLINE);
			return;
		}

		setString("CaptchaId", captchaId.c_str());
		setString("CaptchaText", captchaDialog.GetCaptchaText());

		PushRequest(
			new GetRsaKeyRequest(username),
			&CSteamProto::OnGotRsaKey);
		return;
	}

	DeleteAuthSettings();
	SetStatus(ID_STATUS_OFFLINE);
}
コード例 #7
0
ファイル: media.cpp プロジェクト: truefriend-cz/miranda-ng
HANDLE WhatsAppProto::SendFile(MCONTACT hContact, const TCHAR* desc, TCHAR **ppszFiles) {
	if (!isOnline())
		return 0;

	ptrA jid(getStringA(hContact, "ID"));
	if (jid == NULL)
		return 0;

	// input validation
	char *name = mir_utf8encodeW(ppszFiles[0]);
	string mime = MediaUploader::getMimeFromExtension(split(name, '.')[1]);
	if (mime.empty())
		return 0;

	// get file size
	FILE *hFile = _tfopen(ppszFiles[0], _T("rb"));
	if (hFile == NULL) {
		debugLogA(__FUNCTION__": cannot open file %s", ppszFiles[0]);
		return 0;
	}
	_fseeki64(hFile, 0, SEEK_END);
	uint64_t fileSize = _ftelli64(hFile);
	fclose(hFile);

	// get filetype from mimeType
	int fileType = FMessage::getMessage_WA_Type(split(mime, '/')[0]);

	// check max file sizes
	switch (fileType) {
	case FMessage::WA_TYPE_IMAGE:
		if (fileSize >= 5 * 1024 * 1024) 
			return 0;
		break;
	case FMessage::WA_TYPE_AUDIO:
		if (fileSize >= 10 * 1024 * 1024)
			return 0;
		break;
	case FMessage::WA_TYPE_VIDEO:
		if (fileSize >= 20 * 1024 * 1024)
			return 0;
		break;
	default:
		return 0;
	}
	
	int msgId = GetSerial();
	time_t now = time(NULL);
	std::string msgid = Utilities::intToStr(now) + "-" + Utilities::intToStr(msgId);
	FMessage * fmsg = new FMessage(std::string(jid), true, msgid);
	fmsg->media_url = name;
	fmsg->media_size = fileSize;
	fmsg->media_wa_type = fileType;
	fmsg->data = mir_utf8encodeW(desc);

	// calculate file hash
	unsigned char hash[MIR_SHA256_HASH_SIZE];
	SHA256_CONTEXT sha256;
	mir_sha256_init(&sha256);

	FILE *fd = _tfopen(ppszFiles[0], _T("rb"));
	int read = 0;
	do {
		char buf[1024];
		read = (int)fread(buf, 1, 1024, fd);
		mir_sha256_write(&sha256, buf, read);
	} while (read > 0);
	fclose(fd);

	mir_sha256_final(&sha256, hash);
	fmsg->media_name = mir_base64_encode((BYTE*)hash,sizeof(hash));

	// request media upload url
	m_pConnection->sendMessage(fmsg);
	return (HANDLE)fmsg; // TODO what to return here to make the upload shown complete when done and how to handle errors?
}
コード例 #8
0
ファイル: steam_proto.cpp プロジェクト: Seldom/miranda-ng
int CSteamProto::SetStatus(int new_status)
{
	mir_cslock lock(set_status_lock);

	// Routing statuses not supported by Steam
	switch (new_status)
	{
	case ID_STATUS_OFFLINE:
	case ID_STATUS_AWAY:
	case ID_STATUS_NA:
		break;

	case ID_STATUS_DND:
	case ID_STATUS_OCCUPIED:
	case ID_STATUS_ONTHEPHONE:
	case ID_STATUS_OUTTOLUNCH:
		new_status = ID_STATUS_NA;
		break;

	default:
		new_status = ID_STATUS_ONLINE;
		break;
	}

	if (new_status == m_iDesiredStatus)
		return 0;

	debugLog(_T("CSteamProto::SetStatus: changing status from %i to %i"), m_iStatus, new_status);

	int old_status = m_iStatus;
	m_iDesiredStatus = new_status;

	if (new_status == ID_STATUS_OFFLINE)
	{
		m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
		ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);

		ptrA token(getStringA("TokenSecret"));
		ptrA umqid(getStringA("UMQID"));
		SendRequest(new LogoffRequest(token, umqid));

		requestQueue->Stop();

		if (!Miranda_Terminated())
			SetAllContactsStatus(ID_STATUS_OFFLINE);
	}
	else if (old_status == ID_STATUS_OFFLINE)
	{
		m_iStatus = ID_STATUS_CONNECTING;
		ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);

		requestQueue->Start();

		ptrA token(getStringA("TokenSecret"));
		if (mir_strlen(token) > 0)
		{
			PushRequest(
				new LogonRequest(token),
				&CSteamProto::OnLoggedOn);
		}
		else
		{
			ptrA username(mir_urlEncode(ptrA(mir_utf8encodeT(getTStringA("Username")))));
			if (username == NULL || username[0] == '\0')
			{
				m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
				ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus);
				return 0;
			}

			PushRequest(
				new GetRsaKeyRequest(username),
				&CSteamProto::OnGotRsaKey);
		}
	}
	else
	{
		m_iStatus = new_status;
		ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
	}

	return 0;
}
コード例 #9
0
ファイル: proto.cpp プロジェクト: Seldom/miranda-ng
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);
}
コード例 #10
0
ファイル: proto.cpp プロジェクト: martok/miranda-ng
int __cdecl CAimProto::SendMsg(MCONTACT hContact, int flags, const char* pszSrc)
{
	if (pszSrc == NULL) return 0;

	if (state != 1)
	{
		msg_ack_param *msg_ack = (msg_ack_param*)mir_calloc(sizeof(msg_ack_param));
		msg_ack->hContact = hContact;
		msg_ack->msg = "Message cannot be sent, when protocol offline";
		ForkThread(&CAimProto::msg_ack_success, msg_ack);
	}

	char *sn = getStringA(hContact, AIM_KEY_SN);
	if (sn == NULL)
	{
		msg_ack_param *msg_ack = (msg_ack_param*)mir_calloc(sizeof(msg_ack_param));
		msg_ack->hContact = hContact;
		msg_ack->msg = "Screen Name for the contact not available";
		ForkThread(&CAimProto::msg_ack_success, msg_ack);
	}

	char* msg;
	if (flags & PREF_UNICODE)
	{
		const char* p = strchr(pszSrc, '\0');
		if (p != pszSrc)
		{
			while (*(++p) == '\0');
		}
		msg = mir_utf8encodeW((wchar_t*)p);
	}
	else if (flags & PREF_UTF)
		msg = mir_strdup(pszSrc);
	else
		msg = mir_utf8encode(pszSrc);

	char* smsg = html_encode(msg);
	mir_free(msg);

	if (getByte(AIM_KEY_FO, 1))
	{
		msg = bbcodes_to_html(smsg);
		mir_free(smsg);
	}
	else
		msg = smsg;

	bool blast = getBool(hContact, AIM_KEY_BLS, false);
	int res = aim_send_message(hServerConn, seqno, sn, msg, false, blast);

	mir_free(msg);
	mir_free(sn);

	if (!res || blast || 0 == getByte(AIM_KEY_DC, 1))
	{
		msg_ack_param *msg_ack = (msg_ack_param*)mir_alloc(sizeof(msg_ack_param));
		msg_ack->hContact = hContact;
		msg_ack->msg = NULL;
		msg_ack->id = res;
		msg_ack->success = res != 0;
		ForkThread(&CAimProto::msg_ack_success, msg_ack);
	}

	return res;
}
コード例 #11
0
ファイル: jabber_file.cpp プロジェクト: kxepal/miranda-ng
void __cdecl CJabberProto::FileServerThread(filetransfer *ft)
{
	debugLogA("Thread started: type=file_send");

	ThreadData info(this, NULL);
	ft->type = FT_OOB;

	NETLIBBIND nlb = { 0 };
	nlb.cbSize = sizeof(NETLIBBIND);
	nlb.pfnNewConnectionV2 = JabberFileServerConnection;
	nlb.pExtra = this;
	nlb.wPort = 0;	// Use user-specified incoming port ranges, if available
	info.s = (HANDLE)CallService(MS_NETLIB_BINDPORT, (WPARAM)m_hNetlibUser, (LPARAM)&nlb);
	if (info.s == NULL) {
		debugLogA("Cannot allocate port to bind for file server thread, thread ended.");
		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
		delete ft;
		return;
	}

	ft->s = info.s;
	debugLogA("ft->s = %d", info.s);

	HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	ft->hFileEvent = hEvent;

	TCHAR szPort[20];
	mir_sntprintf(szPort, _T("%d"), nlb.wPort);
	JABBER_LIST_ITEM *item = ListAdd(LIST_FILE, szPort);
	item->ft = ft;

	TCHAR *ptszResource = ListGetBestClientResourceNamePtr(ft->jid);
	if (ptszResource != NULL) {
		ft->state = FT_CONNECTING;
		for (int i = 0; i < ft->std.totalFiles && ft->state != FT_ERROR && ft->state != FT_DENIED; i++) {
			ft->std.currentFileNumber = i;
			ft->state = FT_CONNECTING;
			if (ft->httpPath) mir_free(ft->httpPath);
			ft->httpPath = NULL;

			TCHAR *p;
			if ((p = _tcschr(ft->std.ptszFiles[i], '\\')) != NULL)
				p++;
			else
				p = ft->std.ptszFiles[i];

			ptrA pFileName(mir_urlEncode(T2Utf(p)));
			if (pFileName != NULL) {
				ft->szId = JabberId2string(SerialNext());

				ptrA myAddr;
				if (m_options.BsDirect && m_options.BsDirectManual)
					myAddr = getStringA("BsDirectAddr");
				if (myAddr == NULL)
					myAddr = (char*)CallService(MS_NETLIB_ADDRESSTOSTRING, 1, nlb.dwExternalIP);

				char szAddr[256];
				mir_snprintf(szAddr, "http://%s:%d/%s", myAddr, nlb.wPort, pFileName);

				size_t len = mir_tstrlen(ptszResource) + mir_tstrlen(ft->jid) + 2;
				TCHAR *fulljid = (TCHAR *)alloca(sizeof(TCHAR) * len);
				mir_sntprintf(fulljid, len, _T("%s/%s"), ft->jid, ptszResource);

				XmlNodeIq iq(_T("set"), ft->szId, fulljid);
				HXML query = iq << XQUERY(JABBER_FEAT_OOB);
				query << XCHILD(_T("url"), _A2T(szAddr));
				query << XCHILD(_T("desc"), ft->szDescription);
				m_ThreadInfo->send(iq);

				debugLogA("Waiting for the file to be sent...");
				WaitForSingleObject(hEvent, INFINITE);
			}
			debugLogA("File sent, advancing to the next file...");
			ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
		}
		CloseHandle(hEvent);
		ft->hFileEvent = NULL;
		debugLogA("Finish all files");
	}

	ft->s = NULL;
	debugLogA("ft->s is NULL");

	ListRemove(LIST_FILE, szPort);

	switch (ft->state) {
	case FT_DONE:
		debugLogA("Finish successfully");
		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0);
		break;
	case FT_DENIED:
		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, ft, 0);
		break;
	default: // FT_ERROR:
		debugLogA("Finish with errors");
		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
		break;
	}

	debugLogA("Thread ended: type=file_send");
	delete ft;
}