diff options
Diffstat (limited to 'protocols/Steam/src')
| -rw-r--r-- | protocols/Steam/src/Steam/friend.h | 24 | ||||
| -rw-r--r-- | protocols/Steam/src/Steam/friend_list.h | 44 | ||||
| -rw-r--r-- | protocols/Steam/src/Steam/invitation.h | 77 | ||||
| -rw-r--r-- | protocols/Steam/src/Steam/poll.h | 24 | ||||
| -rw-r--r-- | protocols/Steam/src/Steam/steam.h | 10 | ||||
| -rw-r--r-- | protocols/Steam/src/common.h | 2 | ||||
| -rw-r--r-- | protocols/Steam/src/stdafx.cpp | 4 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_account.cpp | 4 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_avatars.cpp | 6 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_contacts.cpp | 173 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_events.cpp | 2 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_menus.cpp | 78 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_proto.cpp | 40 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_proto.h | 40 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_thread.cpp | 27 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_utils.cpp | 13 | 
16 files changed, 474 insertions, 94 deletions
diff --git a/protocols/Steam/src/Steam/friend.h b/protocols/Steam/src/Steam/friend.h index 9be555a914..3707204734 100644 --- a/protocols/Steam/src/Steam/friend.h +++ b/protocols/Steam/src/Steam/friend.h @@ -30,8 +30,8 @@ namespace SteamWebApi  			Summary() : gameId(0), created(0), lastEvent(0) { }
  			const char *GetSteamId() const { return steamId.c_str(); }
 -			const wchar_t *GetNickname() const { return nickname.c_str(); }
 -			const wchar_t *GetRealname() const { return realname.c_str(); }
 +			const wchar_t *GetNickName() const { return nickname.c_str(); }
 +			const wchar_t *GetRealName() const { return realname.c_str(); }
  			const char *GetCountryCode() const { return countryCode.c_str(); }
  			const char *GetHomepage() const { return homepage.c_str(); }
  			const char *GetAvatarUrl() const { return avatarUrl.c_str(); }
 @@ -40,6 +40,26 @@ namespace SteamWebApi  			int GetState() const { return state; }
  			const DWORD GetCreated() const { return created; }
  			const DWORD GetLastEvent() const { return lastEvent; }
 +
 +			const wchar_t *GetFirstName() const
 +			{
 +				size_t pos = realname.find(' ', 1);
 +				if (pos > 0)
 +					return realname.substr(0, pos - 1).c_str();
 +
 +				return realname.c_str();
 +			}
 +
 +			const wchar_t *GetLastName() const
 +			{
 +				size_t pos = realname.find(' ', 1);
 +				if (pos > 0)
 +				{
 +					return realname.substr(pos + 1).c_str();
 +				}
 +
 +				return L"";
 +			}
  		};
  		struct Summaries : public Result
 diff --git a/protocols/Steam/src/Steam/friend_list.h b/protocols/Steam/src/Steam/friend_list.h index 2b283cc0de..e68e0b1d39 100644 --- a/protocols/Steam/src/Steam/friend_list.h +++ b/protocols/Steam/src/Steam/friend_list.h @@ -53,6 +53,50 @@ namespace SteamWebApi  			friendList->success = true;
  		}
 +
 +		static void AddFriend(HANDLE hConnection, const char *sessionId, const char *steamId, Result *result)
 +		{
 +			result->success = false;
 +
 +			char data[128];
 +			mir_snprintf(data, SIZEOF(data),
 +				"steamid=%s&sessionID=%s",
 +				sessionId,
 +				steamId);
 +
 +			SecureHttpPostRequest request(hConnection, STEAM_COM_URL "/actions/AddFriendAjax");
 +
 +			mir_ptr<NETLIBHTTPREQUEST> response(request.Send());
 +			if (!response)
 +				return;
 +
 +			if ((result->status = (HTTP_STATUS)response->resultCode) != HTTP_STATUS_OK)
 +				return;
 +
 +			result->success = true;
 +		}
 +
 +		static void RemoveFriend(HANDLE hConnection, const char *sessionId, const char *steamId, Result *result)
 +		{
 +			result->success = false;
 +
 +			char data[128];
 +			mir_snprintf(data, SIZEOF(data),
 +				"steamid=%s&sessionID=%s",
 +				sessionId,
 +				steamId);
 +
 +			SecureHttpPostRequest request(hConnection, STEAM_COM_URL "/actions/RemoveFriendAjax");
 +
 +			mir_ptr<NETLIBHTTPREQUEST> response(request.Send());
 +			if (!response)
 +				return;
 +
 +			if ((result->status = (HTTP_STATUS)response->resultCode) != HTTP_STATUS_OK)
 +				return;
 +
 +			result->success = true;
 +		}
  	};
  }
 diff --git a/protocols/Steam/src/Steam/invitation.h b/protocols/Steam/src/Steam/invitation.h new file mode 100644 index 0000000000..23386e1267 --- /dev/null +++ b/protocols/Steam/src/Steam/invitation.h @@ -0,0 +1,77 @@ +#ifndef _STEAM_INVITATION_H_
 +#define _STEAM_INVITATION_H_
 +
 +namespace SteamWebApi
 +{
 +	class InvitationApi : public BaseApi
 +	{
 +	public:
 +		static void Accept(HANDLE hConnection, const char *sessionId, const char *steamId, const char *who, Result *result)
 +		{
 +			result->success = false;
 +
 +			char url[MAX_PATH];
 +			mir_snprintf(url, SIZEOF(url), "%s/profiles/%s/home_process", STEAM_COM_URL, steamId);
 +
 +			char data[MAX_PATH];
 +			mir_snprintf(data, SIZEOF(data), "sessionID=%&id=%s&perform=accept&action=approvePending&itype=friend&json=1&xml=0", sessionId, who);
 +
 +			SecureHttpPostRequest request(hConnection, url);
 +
 +			mir_ptr<NETLIBHTTPREQUEST> response(request.Send());
 +			if (!response)
 +				return;
 +
 +			if ((result->status = (HTTP_STATUS)response->resultCode) != HTTP_STATUS_OK)
 +				return;
 +
 +			result->success = true;
 +		}
 +
 +		static void Ignore(HANDLE hConnection, const char *sessionId, const char *steamId, const char *who, Result *result)
 +		{
 +			result->success = false;
 +
 +			char url[MAX_PATH];
 +			mir_snprintf(url, SIZEOF(url), "%s/profiles/%s/home_process", STEAM_COM_URL, steamId);
 +
 +			char data[MAX_PATH];
 +			mir_snprintf(data, SIZEOF(data), "sessionID=%&id=%s&perform=ignore&action=approvePending&itype=friend&json=1&xml=0", sessionId, who);
 +
 +			SecureHttpPostRequest request(hConnection, url);
 +
 +			mir_ptr<NETLIBHTTPREQUEST> response(request.Send());
 +			if (!response)
 +				return;
 +
 +			if ((result->status = (HTTP_STATUS)response->resultCode) != HTTP_STATUS_OK)
 +				return;
 +
 +			result->success = true;
 +		}
 +
 +		static void Block(HANDLE hConnection, const char *sessionId, const char *steamId, const char *who, Result *result)
 +		{
 +			result->success = false;
 +
 +			char url[MAX_PATH];
 +			mir_snprintf(url, SIZEOF(url), "%s/profiles/%s/home_process", STEAM_COM_URL, steamId);
 +
 +			char data[MAX_PATH];
 +			mir_snprintf(data, SIZEOF(data), "sessionID=%&id=%s&perform=block&action=approvePending&itype=friend&json=1&xml=0", sessionId, who);
 +
 +			SecureHttpPostRequest request(hConnection, url);
 +
 +			mir_ptr<NETLIBHTTPREQUEST> response(request.Send());
 +			if (!response)
 +				return;
 +
 +			if ((result->status = (HTTP_STATUS)response->resultCode) != HTTP_STATUS_OK)
 +				return;
 +
 +			result->success = true;
 +		}
 +	};
 +}
 +
 +#endif //_STEAM_INVITATION_H_
\ No newline at end of file diff --git a/protocols/Steam/src/Steam/poll.h b/protocols/Steam/src/Steam/poll.h index 312f7336e6..ba7a8927ca 100644 --- a/protocols/Steam/src/Steam/poll.h +++ b/protocols/Steam/src/Steam/poll.h @@ -13,9 +13,11 @@ namespace SteamWebApi  			POOL_TYPE_MYMESSAGE,
  			POOL_TYPE_TYPING,
  			POOL_TYPE_STATE,
 -			POOL_TYPE_CONTACT_AUTH,
 -			POOL_TYPE_CONTACT_ADDED,
 -			POOL_TYPE_CONTACT_DELETED,
 +			POOL_TYPE_CONTACT_REQUEST,
 +			//POOL_TYPE_CONTACT_REQUESTED,
 +			POOL_TYPE_CONTACT_ADD,
 +			POOL_TYPE_CONTACT_IGNORE,
 +			POOL_TYPE_CONTACT_REMOVE,
  		};
  		class PoolItem// : public Result
 @@ -182,20 +184,26 @@ namespace SteamWebApi  						int state = json_as_int(node);
  						if (state == 0)
  						{
 -							// contact was removed
 -							crs->type = POOL_TYPE_CONTACT_DELETED;
 -							
 +							// removed
 +							crs->type = POOL_TYPE_CONTACT_REMOVE;
 +						}
 +						
 +						else if (state == 1)
 +						{
 +							// ignored
 +							crs->type = POOL_TYPE_CONTACT_IGNORE;
  						}
  						else if (state == 2)
  						{
  							// auth request
 -							crs->type = POOL_TYPE_CONTACT_AUTH;
 +							crs->type = POOL_TYPE_CONTACT_REQUEST;
  						}
  						else if (state == 3)
  						{
  							// add to list
 -							crs->type = POOL_TYPE_CONTACT_ADDED;
 +							crs->type = POOL_TYPE_CONTACT_ADD;
  						}
 +						else continue;
  					}
  					/*else if (!lstrcmpi(type, L"leftconversation"))
  					{
 diff --git a/protocols/Steam/src/Steam/steam.h b/protocols/Steam/src/Steam/steam.h index 603fc877fa..52de0e5441 100644 --- a/protocols/Steam/src/Steam/steam.h +++ b/protocols/Steam/src/Steam/steam.h @@ -6,16 +6,17 @@ namespace SteamWebApi  	#define STEAM_API_URL "https://api.steampowered.com"
  	#define STEAM_COM_URL "https://steamcommunity.com"
 -	struct Result
 -	{
 -		bool success;
 -	};
 +	class FriendListApi;
 +	class InvitationApi;
  	class BaseApi
  	{
  	public:
  		class Result
  		{
 +			friend FriendListApi;
 +			friend InvitationApi;
 +
  		protected:
  			bool success;
  			HTTP_STATUS status;
 @@ -33,6 +34,7 @@ namespace SteamWebApi  #include "Steam\authorization.h"
  #include "Steam\login.h"
  #include "Steam\friend_list.h"
 +#include "Steam\invitation.h"
  #include "Steam\friend.h"
  #include "Steam\poll.h"
  #include "Steam\message.h"
 diff --git a/protocols/Steam/src/common.h b/protocols/Steam/src/common.h index 436d48239d..fe724a4f93 100644 --- a/protocols/Steam/src/common.h +++ b/protocols/Steam/src/common.h @@ -2,6 +2,7 @@  #define _COMMON_H_
  #include <windows.h>
 +#include <time.h>
  #include <newpluginapi.h>
  #include <m_database.h>
 @@ -14,6 +15,7 @@  #include <m_avatars.h>
  #include <m_icolib.h>
  #include <m_clist.h>
 +#include <m_genmenu.h>
  #include <m_string.h>
  #include <m_freeimage.h>
  #include <m_protocols.h>
 diff --git a/protocols/Steam/src/stdafx.cpp b/protocols/Steam/src/stdafx.cpp index d3d389fe4d..d51a866ca3 100644 --- a/protocols/Steam/src/stdafx.cpp +++ b/protocols/Steam/src/stdafx.cpp @@ -43,6 +43,8 @@ extern "C" int __declspec(dllexport) Load(void)  	pd.fnUninit = (pfnUninitProto)CSteamProto::UninitProtoInstance;
  	CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd);
 +	CSteamProto::InitMenus();
 +
  	return 0;
  }
 @@ -50,5 +52,7 @@ extern "C" int __declspec(dllexport) Unload(void)  {
  	CSteamProto::UninitProtoInstances();
 +	CSteamProto::UninitMenus();
 +
  	return 0;
  }
\ No newline at end of file diff --git a/protocols/Steam/src/steam_account.cpp b/protocols/Steam/src/steam_account.cpp index 8e72904583..a12ae85667 100644 --- a/protocols/Steam/src/steam_account.cpp +++ b/protocols/Steam/src/steam_account.cpp @@ -123,7 +123,7 @@ void CSteamProto::Authorize(SteamWebApi::AuthorizationApi::AuthResult *authResul  void CSteamProto::LogInThread(void* param)
  {
 -	while (m_bTerminated && m_hPollingThread != NULL)
 +	while (m_bTerminated || m_hPollingThread != NULL)
  		Sleep(500);
  	ptrA token(getStringA("TokenSecret"));
 @@ -134,7 +134,7 @@ void CSteamProto::LogInThread(void* param)  		// if some error
  		if (!authResult.IsSuccess())
  		{
 -			// todo: dosplay error message from authResult.GetMessage()
 +			// todo: display error message from authResult.GetMessage()
  			//ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_BADUSERID);
  			debugLogA("CSteamProto::LogInThread: Authorization error (%s)", authResult.GetMessage());
 diff --git a/protocols/Steam/src/steam_avatars.cpp b/protocols/Steam/src/steam_avatars.cpp index 45ee6b80fe..b009e1c32d 100644 --- a/protocols/Steam/src/steam_avatars.cpp +++ b/protocols/Steam/src/steam_avatars.cpp @@ -99,8 +99,4 @@ INT_PTR CSteamProto::GetMyAvatar(WPARAM wParam, LPARAM lParam)  	}
  	return -1;
 -}
 -
 -//INT_PTR CSteamProto::SetMyAvatar(WPARAM wParam, LPARAM lParam)
 -//{
 -//}
\ No newline at end of file +}
\ No newline at end of file diff --git a/protocols/Steam/src/steam_contacts.cpp b/protocols/Steam/src/steam_contacts.cpp index 03969ad2ff..0bf050d18d 100644 --- a/protocols/Steam/src/steam_contacts.cpp +++ b/protocols/Steam/src/steam_contacts.cpp @@ -18,6 +18,25 @@ void CSteamProto::SetAllContactsStatus(WORD status)  	}
  }
 +MCONTACT CSteamProto::GetContactFromAuthEvent(HANDLE hEvent)
 +{
 +	DWORD body[3];
 +	DBEVENTINFO dbei = { sizeof(DBEVENTINFO) };
 +	dbei.cbBlob = sizeof(DWORD)* 2;
 +	dbei.pBlob = (PBYTE)&body;
 +
 +	if (db_event_get(hEvent, &dbei))
 +		return INVALID_CONTACT_ID;
 +
 +	if (dbei.eventType != EVENTTYPE_AUTHREQUEST)
 +		return INVALID_CONTACT_ID;
 +
 +	if (strcmp(dbei.szModule, m_szModuleName) != 0)
 +		return INVALID_CONTACT_ID;
 +
 +	return DbGetAuthEventContact(&dbei);
 +}
 +
  MCONTACT CSteamProto::FindContact(const char *steamId)
  {
  	MCONTACT hContact = NULL;
 @@ -43,7 +62,7 @@ void CSteamProto::UpdateContact(MCONTACT hContact, const SteamWebApi::FriendApi:  		return;
  	// set common data
 -	setWString(hContact, "Nick", contact->GetNickname());
 +	setWString(hContact, "Nick", contact->GetNickName());
  	setString(hContact, "Homepage", contact->GetHomepage());
  	// only for contacts
  	if (hContact)
 @@ -70,19 +89,17 @@ void CSteamProto::UpdateContact(MCONTACT hContact, const SteamWebApi::FriendApi:  	}
  	// set name
 -	ptrW realname(mir_wstrdup(contact->GetRealname()));
 -	const wchar_t *p = wcschr(realname, ' ');
 -	if (p == NULL)
 +	const wchar_t *firstName = contact->GetFirstName();
 +	const wchar_t *lastName = contact->GetLastName();
 +	if (lstrlen(lastName) == 0)
  	{
 -		setWString(hContact, "FirstName", realname);
 +		setWString(hContact, "FirstName", firstName);
  		delSetting(hContact, "LastName");
  	}
  	else
  	{
 -		int length = p - (wchar_t*)realname;
 -		realname[length] = '\0';
 -		setWString(hContact, "FirstName", realname);
 -		setWString(hContact, "LastName", p + 1);
 +		setWString(hContact, "FirstName", firstName);
 +		setWString(hContact, "LastName", lastName);
  	}
  	// avatar
 @@ -147,9 +164,10 @@ void CSteamProto::UpdateContactsThread(void *arg)  		MCONTACT hContact = NULL;
  		if (!IsMe(contact->GetSteamId()))
  		{
 -			hContact = this->FindContact(contact->GetSteamId());
 +			const char *steamId = contact->GetSteamId();
 +			hContact = this->FindContact(steamId);
  			if (hContact == NULL)
 -				hContact = AddContact(contact);
 +				hContact = AddContact(steamId);
  			if (hContact == NULL)
  				return;
  		}
 @@ -158,16 +176,16 @@ void CSteamProto::UpdateContactsThread(void *arg)  	}
  }
 -MCONTACT CSteamProto::AddContact(const SteamWebApi::FriendApi::Summary *contact)
 +MCONTACT CSteamProto::AddContact(const char *steamId)
  {
 -	MCONTACT hContact = this->FindContact(contact->GetSteamId());
 +	MCONTACT hContact = this->FindContact(steamId);
  	if (!hContact)
  	{
  		// create contact
  		hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0);
  		CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)this->m_szModuleName);
 -		setString(hContact, "SteamID", contact->GetSteamId());
 +		setString(hContact, "SteamID", steamId);
  		// update info
  		//UpdateContact(hContact, contact);
 @@ -184,6 +202,97 @@ MCONTACT CSteamProto::AddContact(const SteamWebApi::FriendApi::Summary *contact)  	return hContact;
  }
 +void CSteamProto::RaiseAuthRequestThread(void *arg)
 +{
 +	ptrA steamId((char*)arg);
 +	ptrA token(getStringA("TokenSecret"));
 +
 +	MCONTACT hContact = FindContact(steamId);
 +	if (!hContact)
 +		hContact = AddContact(steamId);
 +
 +	SteamWebApi::FriendApi::Summaries summaries;
 +	debugLogA("CSteamProto::LoadContactListThread: call SteamWebApi::FriendApi::LoadSummaries");
 +	SteamWebApi::FriendApi::LoadSummaries(m_hNetlibUser, token, steamId, &summaries);
 +
 +	if (summaries.IsSuccess())
 +	{
 +		const SteamWebApi::FriendApi::Summary *contact = summaries.GetAt(0);
 +
 +		char *nickName = mir_utf8encodeW(contact->GetNickName());
 +		char *firstName = mir_utf8encodeW(contact->GetFirstName());
 +		char *lastName = mir_utf8encodeW(contact->GetLastName());
 +		char reason[MAX_PATH];
 +		mir_snprintf(reason, SIZEOF(reason), Translate("%s has added you to his or her Friend List"), nickName);
 +
 +		// blob is: 0(DWORD), hContact(DWORD), nick(ASCIIZ), firstName(ASCIIZ), lastName(ASCIIZ), sid(ASCIIZ), reason(ASCIIZ)
 +		DWORD cbBlob = (DWORD)(sizeof(DWORD)* 2 + strlen(nickName) + strlen(firstName) + strlen(lastName) + strlen(steamId) + strlen(reason) + 5);
 +
 +		PBYTE pBlob, pCurBlob;
 +		pCurBlob = pBlob = (PBYTE)mir_alloc(cbBlob);
 +
 +		*((PDWORD)pCurBlob) = 0;
 +		pCurBlob += sizeof(DWORD);
 +		*((PDWORD)pCurBlob) = (DWORD)hContact;
 +		pCurBlob += sizeof(DWORD);
 +		strcpy((char*)pCurBlob, nickName);
 +		pCurBlob += strlen(nickName) + 1;
 +		strcpy((char*)pCurBlob, firstName);
 +		pCurBlob += strlen(firstName) + 1;
 +		strcpy((char*)pCurBlob, lastName);
 +		pCurBlob += strlen(lastName) + 1;
 +		strcpy((char*)pCurBlob, steamId);
 +		pCurBlob += strlen(steamId) + 1;
 +		strcpy((char*)pCurBlob, mir_strdup(reason));
 +
 +		AddDBEvent(hContact, EVENTTYPE_AUTHREQUEST, time(NULL), DBEF_UTF, cbBlob, pBlob);
 +	}
 +}
 +
 +void CSteamProto::AuthAllowThread(void *arg)
 +{
 +	MCONTACT hContact = (MCONTACT)arg;
 +	if (!hContact)
 +		return;
 +
 +	ptrA sessionId(getStringA("SessionID"));
 +	ptrA steamId(getStringA("SteamID"));
 +	ptrA who(getStringA(hContact, "SteamID"));
 +
 +	SteamWebApi::InvitationApi::Result result;
 +	debugLogA("CSteamProto::AuthAllowThread: call SteamWebApi::InvitationApi::Accept");
 +	SteamWebApi::InvitationApi::Accept(m_hNetlibUser, sessionId, steamId, who, &result);
 +
 +	if (result.IsSuccess())
 +	{
 +		delSetting(hContact, "Auth");
 +		delSetting(hContact, "Grant");
 +	}
 +}
 +
 +void CSteamProto::AuthDenyThread(void *arg)
 +{
 +	MCONTACT hContact = (MCONTACT)arg;
 +	if (!hContact)
 +		return;
 +
 +	ptrA sessionId(getStringA("SessionID"));
 +	ptrA steamId(getStringA("SteamID"));
 +	ptrA who(getStringA(hContact, "SteamID"));
 +
 +	SteamWebApi::InvitationApi::Result result;
 +	debugLogA("CSteamProto::AuthDenyThread: call SteamWebApi::InvitationApi::Ignore");
 +	SteamWebApi::InvitationApi::Ignore(m_hNetlibUser, sessionId, steamId, who, &result);
 +}
 +
 +void CSteamProto::AddContactThread(void *arg)
 +{
 +}
 +
 +void CSteamProto::RemoveContactThread(void *arg)
 +{
 +}
 +
  void CSteamProto::LoadContactListThread(void*)
  {
  	ptrA token(getStringA("TokenSecret"));
 @@ -219,7 +328,7 @@ void CSteamProto::LoadContactListThread(void*)  				for (size_t i = 0; i < summaries.GetItemCount(); i++)
  				{
  					const SteamWebApi::FriendApi::Summary *summary = summaries.GetAt(i);
 -					MCONTACT hContact = AddContact(summary);
 +					MCONTACT hContact = AddContact(summary->GetSteamId());
  					if (hContact)
  						UpdateContact(hContact, summary);
  				}
 @@ -255,20 +364,9 @@ void CSteamProto::SearchByIdThread(void* arg)  	ssr.hdr.flags = PSR_TCHAR;
  	ssr.hdr.id = mir_wstrdup(steamIdW);
 -	ssr.hdr.nick  = mir_wstrdup(contact->GetNickname());
 -
 -	const wchar_t *realname = contact->GetRealname();
 -	const wchar_t *p = wcschr(realname, ' ');
 -	if (p == NULL)
 -		ssr.hdr.firstName = mir_wstrdup(realname);
 -	else
 -	{
 -		int length = p - realname;
 -		ssr.hdr.firstName = (wchar_t*)mir_alloc(sizeof(wchar_t) * (length + 1));
 -		wmemcpy(ssr.hdr.firstName, realname, length);
 -		ssr.hdr.firstName[length] = '\0';
 -		ssr.hdr.lastName = mir_wstrdup(p + 1);
 -	}
 +	ssr.hdr.nick  = mir_wstrdup(contact->GetNickName());
 +	ssr.hdr.firstName = mir_wstrdup(contact->GetFirstName());
 +	ssr.hdr.lastName = mir_wstrdup(contact->GetLastName());
  	ssr.contact = contact;
 @@ -322,20 +420,9 @@ void CSteamProto::SearchByNameThread(void* arg)  		ssr.hdr.flags = PSR_TCHAR;
  		ssr.hdr.id = mir_a2u(contact->GetSteamId());
 -		ssr.hdr.nick  = mir_wstrdup(contact->GetNickname());
 -
 -		const wchar_t *realname = contact->GetRealname();
 -		const wchar_t *p = wcschr(realname, ' ');
 -		if (p == NULL)
 -			ssr.hdr.firstName = mir_wstrdup(realname);
 -		else
 -		{
 -			int length = p - realname;
 -			ssr.hdr.firstName = (wchar_t*)mir_alloc(sizeof(wchar_t) * (length + 1));
 -			wmemcpy(ssr.hdr.firstName, realname, length);
 -			ssr.hdr.firstName[length] = '\0';
 -			ssr.hdr.lastName = mir_wstrdup(p + 1);
 -		}
 +		ssr.hdr.nick  = mir_wstrdup(contact->GetNickName());
 +		ssr.hdr.firstName = mir_wstrdup(contact->GetFirstName());
 +		ssr.hdr.lastName = mir_wstrdup(contact->GetLastName());
  		ssr.contact = contact;
 diff --git a/protocols/Steam/src/steam_events.cpp b/protocols/Steam/src/steam_events.cpp index 27e63951b7..2d6daf07d3 100644 --- a/protocols/Steam/src/steam_events.cpp +++ b/protocols/Steam/src/steam_events.cpp @@ -13,6 +13,8 @@ int CSteamProto::OnModulesLoaded(WPARAM, LPARAM)  	nlu.szSettingsModule = m_szModuleName;
  	m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
 +	HookEvent(ME_CLIST_PREBUILDCONTACTMENU, &CSteamProto::PrebuildContactMenu);
 +
  	return 0;
  }
 diff --git a/protocols/Steam/src/steam_menus.cpp b/protocols/Steam/src/steam_menus.cpp new file mode 100644 index 0000000000..9ce56ec84c --- /dev/null +++ b/protocols/Steam/src/steam_menus.cpp @@ -0,0 +1,78 @@ +#include "common.h"
 +
 +HANDLE CSteamProto::hChooserMenu;
 +HGENMENU CSteamProto::contactMenuItems[CMI_MAX];
 +
 +template<int(__cdecl CSteamProto::*Service)(WPARAM, LPARAM)>
 +INT_PTR GlobalService(WPARAM wParam, LPARAM lParam)
 +{
 +	CSteamProto *ppro = CSteamProto::GetContactProtoInstance((MCONTACT)wParam);
 +	return ppro ? (ppro->*Service)(wParam, lParam) : 0;
 +}
 +
 +INT_PTR CSteamProto::MenuChooseService(WPARAM wParam, LPARAM lParam)
 +{
 +	if (lParam)
 +		*(void**)lParam = (void*)wParam;
 +
 +	return 0;
 +}
 +
 +int CSteamProto::JoinToGameCommand(WPARAM hContact, LPARAM)
 +{
 +	char url[MAX_PATH];
 +	DWORD gameId = getDword(hContact, "GameID", 0);
 +	mir_snprintf(url, SIZEOF(url), "steam://rungameid/%lu", gameId);
 +	CallService(MS_UTILS_OPENURL, 0, (LPARAM)url);
 +
 +	return 0;
 +}
 +
 +int CSteamProto::OnPrebuildContactMenu(WPARAM wParam, LPARAM)
 +{
 +	MCONTACT hContact = (MCONTACT)wParam;
 +	if (!hContact)
 +		return 0;
 +
 +	if (!this->IsOnline() || lstrcmpA(GetContactProto(hContact), m_szModuleName))
 +		return 0;
 +
 +	//bool ctrlPressed = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
 +	DWORD gameId = getDword(hContact, "GameID", 0);
 +	Menu_ShowItem(contactMenuItems[CMI_JOIN_GAME], gameId > 0);
 +
 +	return 0;
 +}
 +
 +int CSteamProto::PrebuildContactMenu(WPARAM wParam, LPARAM lParam)
 +{
 +	for (int i = 0; i < SIZEOF(CSteamProto::contactMenuItems); i++)
 +		Menu_ShowItem(CSteamProto::contactMenuItems[i], false);
 +
 +	CSteamProto* ppro = CSteamProto::GetContactProtoInstance((MCONTACT)wParam);
 +	return (ppro) ? ppro->OnPrebuildContactMenu(wParam, lParam) : 0;
 +}
 +
 +void CSteamProto::InitMenus()
 +{
 +	hChooserMenu = MO_CreateMenuObject("SkypeAccountChooser", LPGEN("Steam menu chooser"), 0, "Steam/MenuChoose");
 +
 +	//////////////////////////////////////////////////////////////////////////////////////
 +	// Contact menu initialization
 +	CLISTMENUITEM mi = { 0 };
 +	mi.cbSize = sizeof(CLISTMENUITEM);
 +	mi.flags = CMIF_TCHAR | CMIF_NOTOFFLINE;
 +
 +	// "Join to game"
 +	mi.pszService = MODULE"/JoinToGame";
 +	mi.ptszName = LPGENT("Join to game");
 +	mi.position = -200001000 + CMI_JOIN_GAME;
 +	//mi.icolibItem = CSkypeProto::GetSkinIconHandle("block");
 +	contactMenuItems[CMI_JOIN_GAME] = Menu_AddContactMenuItem(&mi);
 +	CreateServiceFunction(mi.pszService, GlobalService<&CSteamProto::JoinToGameCommand>);
 +}
 +
 +void CSteamProto::UninitMenus()
 +{
 +	CallService(MS_CLIST_REMOVETRAYMENUITEM, (WPARAM)contactMenuItems[CMI_JOIN_GAME], 0);
 +}
\ No newline at end of file diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp index f30d47a59b..ee535cea99 100644 --- a/protocols/Steam/src/steam_proto.cpp +++ b/protocols/Steam/src/steam_proto.cpp @@ -30,11 +30,12 @@ CSteamProto::CSteamProto(const char* protoName, const TCHAR* userName) :  	SetAllContactsStatus(ID_STATUS_OFFLINE);
 -	// Avatar API
 -	this->CreateProtoService(PS_GETAVATARINFOT, &CSteamProto::GetAvatarInfo);
 -	this->CreateProtoService(PS_GETAVATARCAPS, &CSteamProto::GetAvatarCaps);
 -	this->CreateProtoService(PS_GETMYAVATART, &CSteamProto::GetMyAvatar);
 -	//this->CreateProtoService(PS_SETMYAVATART, &CSteamProto::SetMyAvatar);
 +	// services
 +	CreateServiceFunction(MODULE"/MenuChoose", CSteamProto::MenuChooseService);
 +	// avatar API
 +	CreateProtoService(PS_GETAVATARINFOT, &CSteamProto::GetAvatarInfo);
 +	CreateProtoService(PS_GETAVATARCAPS, &CSteamProto::GetAvatarCaps);
 +	CreateProtoService(PS_GETMYAVATART, &CSteamProto::GetMyAvatar);
  }
  CSteamProto::~CSteamProto()
 @@ -48,7 +49,9 @@ MCONTACT __cdecl CSteamProto::AddToList(int flags, PROTOSEARCHRESULT* psr)  		return 0;
  	STEAM_SEARCH_RESULT *ssr = (STEAM_SEARCH_RESULT*)psr;
 -	return AddContact(ssr->contact);
 +	MCONTACT hContact = AddContact(ssr->contact->GetSteamId());
 +	UpdateContact(hContact, ssr->contact);
 +	return hContact;
  }
  MCONTACT __cdecl CSteamProto::AddToListByEvent(int flags, int iContact, HANDLE hDbEvent)
 @@ -58,7 +61,18 @@ MCONTACT __cdecl CSteamProto::AddToListByEvent(int flags, int iContact, HANDLE h  int __cdecl CSteamProto::Authorize(HANDLE hDbEvent)
  {
 -	return 0;
 +	if (IsOnline() && hDbEvent)
 +	{
 +		MCONTACT hContact = GetContactFromAuthEvent(hDbEvent);
 +		if (hContact == INVALID_CONTACT_ID)
 +			return 1;
 +
 +		ForkThread(&CSteamProto::AuthAllowThread, (void*)hContact);
 +		// todo: how to return real status?
 +		return 0;
 +	}
 +
 +	return 1;
  }
  int __cdecl CSteamProto::AuthDeny(HANDLE hDbEvent, const TCHAR* szReason)
 @@ -105,7 +119,7 @@ DWORD_PTR __cdecl CSteamProto:: GetCaps(int type, MCONTACT hContact)  	case PFLAGNUM_2:
  		return PF2_ONLINE;
  	case PFLAGNUM_4:
 -		return PF4_AVATARS;
 +		return PF4_NOCUSTOMAUTH | PF4_AVATARS | PF4_NOAUTHDENYREASON;
  	case PFLAGNUM_5:
  		return PF2_SHORTAWAY | PF2_HEAVYDND | PF2_OUTTOLUNCH;
  	case PFLAG_UNIQUEIDTEXT:
 @@ -166,15 +180,7 @@ int __cdecl CSteamProto::RecvFile(MCONTACT hContact, PROTORECVFILET* pre)  int __cdecl CSteamProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT* pre)
  {
 -	DBEVENTINFO dbei = { sizeof(dbei) };
 -	dbei.szModule = this->m_szModuleName;
 -	dbei.timestamp = pre->timestamp;
 -	dbei.eventType = EVENTTYPE_MESSAGE;
 -	dbei.cbBlob = lstrlenA(pre->szMessage);
 -	dbei.pBlob = (BYTE*)pre->szMessage;
 -	dbei.flags = DBEF_UTF;
 -
 -	return (INT_PTR)db_event_add(hContact, &dbei);
 +	return (INT_PTR)AddDBEvent(hContact, EVENTTYPE_MESSAGE, time(NULL), DBEF_UTF, lstrlenA(pre->szMessage), (BYTE*)pre->szMessage);
  }
  int __cdecl CSteamProto::RecvUrl(MCONTACT hContact, PROTORECVEVENT *) { return 0; }
 diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h index bc7336dc87..5996d248ba 100644 --- a/protocols/Steam/src/steam_proto.h +++ b/protocols/Steam/src/steam_proto.h @@ -30,6 +30,16 @@ struct STEAM_SEARCH_RESULT  	const SteamWebApi::FriendApi::Summary *contact;
  };
 +enum
 +{
 +	//CMI_AUTH_REQUEST,
 +	//CMI_AUTH_GRANT,
 +	//CMI_AUTH_REVOKE,
 +	//CMI_BLOCK,
 +	CMI_JOIN_GAME,
 +	CMI_MAX   // this item shall be the last one
 +};
 +
  class CSteamProto : public PROTO<CSteamProto>
  {
 @@ -89,6 +99,10 @@ public:  	static CSteamProto* GetContactProtoInstance(MCONTACT hContact);
  	static void UninitProtoInstances();
 +	// menus
 +	static void InitMenus();
 +	static void UninitMenus();
 +
  protected:
  	bool m_bTerminated;
  	HANDLE m_hPollingThread;
 @@ -116,11 +130,20 @@ protected:  	void SetContactStatus(MCONTACT hContact, WORD status);
  	void SetAllContactsStatus(WORD status);
 +	MCONTACT GetContactFromAuthEvent(HANDLE hEvent);
 +
  	void UpdateContact(MCONTACT hContact, const SteamWebApi::FriendApi::Summary *contact);
  	void __cdecl UpdateContactsThread(void*);
  	MCONTACT FindContact(const char *steamId);
 -	MCONTACT AddContact(const SteamWebApi::FriendApi::Summary *contact);
 +	MCONTACT AddContact(const char *steamId);
 +
 +	void __cdecl RaiseAuthRequestThread(void*);
 +	void __cdecl AuthAllowThread(void*);
 +	void __cdecl AuthDenyThread(void*);
 +
 +	void __cdecl AddContactThread(void*);
 +	void __cdecl RemoveContactThread(void*);
  	void __cdecl LoadContactListThread(void*);
 @@ -131,13 +154,24 @@ protected:  	void __cdecl SendMessageThread(void*);
  	void __cdecl SendTypingThread(void*);
 +	// menus
 +	HGENMENU m_hMenuRoot;
 +	static HANDLE hChooserMenu;
 +	static HGENMENU contactMenuItems[CMI_MAX];
 +
 +	int __cdecl JoinToGameCommand(WPARAM, LPARAM);
 +
 +	static INT_PTR MenuChooseService(WPARAM wParam, LPARAM lParam);
 +
 +	static int PrebuildContactMenu(WPARAM wParam, LPARAM lParam);
 +	int OnPrebuildContactMenu(WPARAM wParam, LPARAM);
 +
  	// avatars
  	wchar_t * GetAvatarFilePath(MCONTACT hContact);
  	INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM);
  	INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM);
  	INT_PTR __cdecl GetMyAvatar(WPARAM, LPARAM);
 -	INT_PTR __cdecl SetMyAvatar(WPARAM, LPARAM);
  	//events
  	int OnModulesLoaded(WPARAM, LPARAM);
 @@ -151,6 +185,8 @@ protected:  	static int RsaEncrypt(const SteamWebApi::RsaKeyApi::RsaKey &rsaKey, const char *data, DWORD dataSize, BYTE *encrypted, DWORD &encryptedSize);
 +	HANDLE AddDBEvent(MCONTACT hContact, WORD type, DWORD timestamp, DWORD flags, DWORD cbBlob, PBYTE pBlob);
 +
  	// options
  	static INT_PTR CALLBACK GuardProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  	static INT_PTR CALLBACK CaptchaProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
 diff --git a/protocols/Steam/src/steam_thread.cpp b/protocols/Steam/src/steam_thread.cpp index 970cbcd628..e95af473dd 100644 --- a/protocols/Steam/src/steam_thread.cpp +++ b/protocols/Steam/src/steam_thread.cpp @@ -45,15 +45,7 @@ void CSteamProto::PollServer(const char *token, const char *sessionId, UINT32 me  				{
  					const wchar_t *text = message->GetText();
 -					DBEVENTINFO dbei = { sizeof(dbei) };
 -					dbei.szModule = this->m_szModuleName;
 -					dbei.timestamp = message->GetTimestamp();
 -					dbei.eventType = EVENTTYPE_MESSAGE;
 -					dbei.cbBlob = lstrlen(text);
 -					dbei.pBlob = (BYTE*)mir_utf8encodeW(text);
 -					dbei.flags = DBEF_UTF | DBEF_SENT;
 -
 -					db_event_add(hContact, &dbei);
 +					AddDBEvent(hContact, EVENTTYPE_MESSAGE, time(NULL), DBEF_UTF | DBEF_SENT, lstrlen(text), (BYTE*)mir_utf8encodeW(text));
  				}
  			}
  			break;
 @@ -93,7 +85,7 @@ void CSteamProto::PollServer(const char *token, const char *sessionId, UINT32 me  			}
  			break;
 -		case SteamWebApi::PollApi::POOL_TYPE_CONTACT_ADDED:
 +		case SteamWebApi::PollApi::POOL_TYPE_CONTACT_ADD:
  			{
  				SteamWebApi::PollApi::Relationship *crs = (SteamWebApi::PollApi::Relationship*)item;
 @@ -105,7 +97,7 @@ void CSteamProto::PollServer(const char *token, const char *sessionId, UINT32 me  			}
  			break;
 -		case SteamWebApi::PollApi::POOL_TYPE_CONTACT_DELETED:
 +		case SteamWebApi::PollApi::POOL_TYPE_CONTACT_REMOVE:
  			{
  				SteamWebApi::PollApi::Relationship *crs = (SteamWebApi::PollApi::Relationship*)item;
 @@ -115,6 +107,19 @@ void CSteamProto::PollServer(const char *token, const char *sessionId, UINT32 me  					CallService(MS_DB_CONTACT_DELETE, hContact, 0);
  			}
  			break;
 +
 +		case SteamWebApi::PollApi::POOL_TYPE_CONTACT_REQUEST:
 +			{
 +				SteamWebApi::PollApi::Relationship *crs = (SteamWebApi::PollApi::Relationship*)item;
 +
 +				const char *steamId = crs->GetSteamId();
 +				MCONTACT hContact = FindContact(steamId);
 +				if (!hContact)
 +					hContact = AddContact(steamId);
 +
 +				
 +			}
 +			break;
  		}
  	}
 diff --git a/protocols/Steam/src/steam_utils.cpp b/protocols/Steam/src/steam_utils.cpp index 6ec2ec89f8..bc5d624a75 100644 --- a/protocols/Steam/src/steam_utils.cpp +++ b/protocols/Steam/src/steam_utils.cpp @@ -129,4 +129,17 @@ int CSteamProto::RsaEncrypt(const SteamWebApi::RsaKeyApi::RsaKey &rsaKey, const  	CryptReleaseContext(hCSP, 0);
  	return 0;
 +}
 +
 +HANDLE CSteamProto::AddDBEvent(MCONTACT hContact, WORD type, DWORD timestamp, DWORD flags, DWORD cbBlob, PBYTE pBlob)
 +{
 +	DBEVENTINFO dbei = { sizeof(dbei) };
 +	dbei.szModule = m_szModuleName;
 +	dbei.timestamp = timestamp;
 +	dbei.eventType = type;
 +	dbei.cbBlob = cbBlob;
 +	dbei.pBlob = pBlob;
 +	dbei.flags = flags;
 +
 +	return db_event_add(hContact, &dbei);
  }
\ No newline at end of file  | 
