From 609b81615bd8a2726da369574ec298f6fe853886 Mon Sep 17 00:00:00 2001
From: Alexander Lantsev <aunsane@gmail.com>
Date: Wed, 16 Apr 2014 21:34:54 +0000
Subject: Steam: work commit - fixed long connecting in one case - one more
 peace of contact management - minor changes

git-svn-id: http://svn.miranda-ng.org/main/trunk@8987 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
---
 protocols/Steam/src/Steam/friend.h      | 32 ++++++------
 protocols/Steam/src/Steam/friend_list.h | 46 +++++++++++++++--
 protocols/Steam/src/Steam/invitation.h  | 22 +++++---
 protocols/Steam/src/Steam/login.h       |  6 +--
 protocols/Steam/src/Steam/message.h     | 12 ++---
 protocols/Steam/src/Steam/poll.h        |  4 +-
 protocols/Steam/src/http_request.h      |  1 +
 protocols/Steam/src/steam_account.cpp   | 15 +++---
 protocols/Steam/src/steam_contacts.cpp  | 91 +++++++++++++++++++++------------
 protocols/Steam/src/steam_messages.cpp  |  8 +--
 protocols/Steam/src/steam_proto.cpp     | 12 ++++-
 protocols/Steam/src/steam_proto.h       |  2 +-
 protocols/Steam/src/steam_thread.cpp    | 13 +++--
 13 files changed, 177 insertions(+), 87 deletions(-)

diff --git a/protocols/Steam/src/Steam/friend.h b/protocols/Steam/src/Steam/friend.h
index 3707204734..00aceab272 100644
--- a/protocols/Steam/src/Steam/friend.h
+++ b/protocols/Steam/src/Steam/friend.h
@@ -14,7 +14,9 @@ namespace SteamWebApi
 			std::string steamId;
 
 			std::wstring nickname;
-			std::wstring realname;
+			std::wstring firstname;
+			std::wstring lastname;
+			std::wstring secondname;
 			std::string countryCode;
 			std::string homepage;
 			std::string avatarUrl;
@@ -31,7 +33,6 @@ namespace SteamWebApi
 
 			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 char *GetCountryCode() const { return countryCode.c_str(); }
 			const char *GetHomepage() const { return homepage.c_str(); }
 			const char *GetAvatarUrl() const { return avatarUrl.c_str(); }
@@ -43,22 +44,12 @@ namespace SteamWebApi
 
 			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();
+				return firstname.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"";
+				return lastname.c_str();
 			}
 		};
 
@@ -111,7 +102,18 @@ namespace SteamWebApi
 
 					node = json_get(child, "realname");
 					if (node != NULL)
-						item->realname = json_as_string(node);
+					{
+						std::wstring realname = json_as_string(node);
+						if (!realname.empty())
+						{
+							size_t pos = realname.find(' ', 1);
+							if (pos > 0)
+							{
+								item->firstname = realname.substr(0, pos);
+								item->lastname = realname.substr(pos + 1).c_str();
+							}
+						}
+					}
 
 					node = json_get(child, "loccountrycode");
 					if (node != NULL)
diff --git a/protocols/Steam/src/Steam/friend_list.h b/protocols/Steam/src/Steam/friend_list.h
index e68e0b1d39..dc8b78cf0d 100644
--- a/protocols/Steam/src/Steam/friend_list.h
+++ b/protocols/Steam/src/Steam/friend_list.h
@@ -6,16 +6,38 @@ namespace SteamWebApi
 	class FriendListApi : public BaseApi
 	{
 	public:
+
+		enum FRIEND_TYPE
+		{
+			FRIEND_TYPE_NONE,
+			FRIEND_TYPE_FRIEND,
+			FRIEND_TYPE_IGNORED,
+		};
+		class FriendListItem
+		{
+			friend FriendListApi;
+
+		private:
+			std::string steamId;
+			FRIEND_TYPE type;
+
+		public:
+			FriendListItem() : type(FRIEND_TYPE_NONE) { }
+
+			const char *GetSteamId() const { return steamId.c_str(); }
+			FRIEND_TYPE GetType() const { return type; }
+		};
+
 		class FriendList : public Result
 		{
 			friend FriendListApi;
 
 		private:
-			std::vector<std::string> items;
+			std::vector<FriendListItem*> items;
 
 		public:
 			size_t GetItemCount() const { return items.size(); }
-			const char * GetAt(int idx) const { return items.at(idx).c_str(); }
+			const FriendListItem * GetAt(int idx) const { return items.at(idx); }
 		};
 
 		static void Load(HANDLE hConnection, const char *token, const char *steamId, FriendList *friendList)
@@ -25,6 +47,7 @@ namespace SteamWebApi
 			SecureHttpGetRequest request(hConnection, STEAM_API_URL "/ISteamUserOAuth/GetFriendList/v0001");
 			request.AddParameter("access_token", token);
 			request.AddParameter("steamid", steamId);
+			//relationship = friend, requestrecipient
 
 			mir_ptr<NETLIBHTTPREQUEST> response(request.Send());
 			if (!response)
@@ -45,9 +68,26 @@ namespace SteamWebApi
 					if (child == NULL)
 						break;
 
+					FriendListItem *item = new FriendListItem();
+
 					node = json_get(child, "steamid");
+					item->steamId = ptrA(mir_u2a(json_as_string(node)));
+
+					node = json_get(child, "relationship");
+					ptrA relationship(mir_u2a(json_as_string(node)));
+					if (!lstrcmpiA(relationship, "friend"))
+						item->type = FRIEND_TYPE_FRIEND;
+					else if (!lstrcmpiA(relationship, "ignoredfriend"))
+						item->type = FRIEND_TYPE_IGNORED;
+					else if (!lstrcmpiA(relationship, "requestrecipient"))
+						item->type = FRIEND_TYPE_NONE;
+					else
+					{
+						continue;
+					}
+
 					friendList->items
-						.push_back((char*)ptrA(mir_u2a(json_as_string(node))));
+						.push_back(item);
 				}
 			}
 
diff --git a/protocols/Steam/src/Steam/invitation.h b/protocols/Steam/src/Steam/invitation.h
index 23386e1267..defe721fa8 100644
--- a/protocols/Steam/src/Steam/invitation.h
+++ b/protocols/Steam/src/Steam/invitation.h
@@ -6,24 +6,32 @@ namespace SteamWebApi
 	class InvitationApi : public BaseApi
 	{
 	public:
-		static void Accept(HANDLE hConnection, const char *sessionId, const char *steamId, const char *who, Result *result)
+		static void Accept(HANDLE hConnection, const char *token, const char *sessionId, const char *steamId, const char *who, Result *result)
 		{
 			result->success = false;
 
+			char login[MAX_PATH];
+			mir_snprintf(login, SIZEOF(login), "%s||oauth:%s", steamId, token);
+
+			char cookie[MAX_PATH];
+			mir_snprintf(cookie, SIZEOF(cookie), "steamLogin=%s; sessionid=%s", login, sessionId);
+
 			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);
+			mir_snprintf(data, SIZEOF(data), "sessionID=%s&id=%s&perform=accept&action=approvePending&itype=friend&json=1&xml=1", sessionId, who);
 
 			SecureHttpPostRequest request(hConnection, url);
+			request.AddHeader("Cookie", cookie);
+			request.SetData(data, strlen(data));
 
 			mir_ptr<NETLIBHTTPREQUEST> response(request.Send());
 			if (!response)
 				return;
 
-			if ((result->status = (HTTP_STATUS)response->resultCode) != HTTP_STATUS_OK)
-				return;
+			//if ((result->status = (HTTP_STATUS)response->resultCode) != HTTP_STATUS_FOUND)
+			//	return;
 
 			result->success = true;
 		}
@@ -36,9 +44,10 @@ namespace SteamWebApi
 			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);
+			mir_snprintf(data, SIZEOF(data), "sessionID=%s&id=%s&perform=ignore&action=approvePending&itype=friend&json=1&xml=0", sessionId, who);
 
 			SecureHttpPostRequest request(hConnection, url);
+			request.SetData(data, strlen(data));
 
 			mir_ptr<NETLIBHTTPREQUEST> response(request.Send());
 			if (!response)
@@ -58,9 +67,10 @@ namespace SteamWebApi
 			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);
+			mir_snprintf(data, SIZEOF(data), "sessionID=%s&id=%s&perform=block&action=approvePending&itype=friend&json=1&xml=0", sessionId, who);
 
 			SecureHttpPostRequest request(hConnection, url);
+			request.SetData(data, strlen(data));
 
 			mir_ptr<NETLIBHTTPREQUEST> response(request.Send());
 			if (!response)
diff --git a/protocols/Steam/src/Steam/login.h b/protocols/Steam/src/Steam/login.h
index c77b5afa57..30593d9c14 100644
--- a/protocols/Steam/src/Steam/login.h
+++ b/protocols/Steam/src/Steam/login.h
@@ -18,7 +18,7 @@ namespace SteamWebApi
 		public:
 
 			const char *GetSteamId() { return steamid.c_str(); }
-			const char *GetSessionId() { return umqid.c_str(); }
+			const char *GetUmqId() { return umqid.c_str(); }
 			UINT32 GetMessageId() { return messageId; }
 		};
 		
@@ -59,11 +59,11 @@ namespace SteamWebApi
 			loginResult->success = true;
 		}
 
-		static void Logoff(HANDLE hConnection, const char *token, const char *sessionId)
+		static void Logoff(HANDLE hConnection, const char *token, const char *umqId)
 		{
 			CMStringA data;
 			data.AppendFormat("access_token=%s", token);
-			data.AppendFormat("&umqid=%s", sessionId);
+			data.AppendFormat("&umqid=%s", umqId);
 
 			SecureHttpPostRequest request(hConnection, STEAM_API_URL "/ISteamWebUserPresenceOAuth/Logoff/v0001");
 			request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
diff --git a/protocols/Steam/src/Steam/message.h b/protocols/Steam/src/Steam/message.h
index 4304cda096..c3c95a28bb 100644
--- a/protocols/Steam/src/Steam/message.h
+++ b/protocols/Steam/src/Steam/message.h
@@ -19,7 +19,7 @@ namespace SteamWebApi
 			const DWORD GetTimestamp() const { return timestamp; }
 		};
 
-		static void SendStatus(HANDLE hConnection, const char *token, const char *sessionId, int state, SendResult *sendResult)
+		static void SendStatus(HANDLE hConnection, const char *token, const char *umqId, int state, SendResult *sendResult)
 		{
 			sendResult->success = false;
 
@@ -27,7 +27,7 @@ namespace SteamWebApi
 			mir_snprintf(data, SIZEOF(data),
 				"access_token=%s&umqid=%s&type=personastate&persona_state=%i",
 				token,
-				sessionId,
+				umqId,
 				state);
 
 			SecureHttpPostRequest request(hConnection, STEAM_API_URL "/ISteamWebUserPresenceOAuth/Message/v0001");
@@ -44,7 +44,7 @@ namespace SteamWebApi
 			sendResult->success = true;
 		}
 
-		static void SendMessage(HANDLE hConnection, const char *token, const char *sessionId, const char *steamId, const char *text, SendResult *sendResult)
+		static void SendMessage(HANDLE hConnection, const char *token, const char *umqId, const char *steamId, const char *text, SendResult *sendResult)
 		{
 			sendResult->success = false;
 
@@ -52,7 +52,7 @@ namespace SteamWebApi
 			mir_snprintf(data, SIZEOF(data),
 				"access_token=%s&umqid=%s&steamid_dst=%s&type=saytext&text=%s",
 				token,
-				sessionId,
+				umqId,
 				steamId,
 				ptrA(mir_urlEncode(text)));
 
@@ -81,7 +81,7 @@ namespace SteamWebApi
 			sendResult->success = true;
 		}
 
-		static void SendTyping(HANDLE hConnection, const char *token, const char *sessionId, const char *steamId, SendResult *sendResult)
+		static void SendTyping(HANDLE hConnection, const char *token, const char *umqId, const char *steamId, SendResult *sendResult)
 		{
 			sendResult->success = false;
 
@@ -89,7 +89,7 @@ namespace SteamWebApi
 			mir_snprintf(data, SIZEOF(data),
 				"access_token=%s&umqid=%s&steamid_dst=%s&type=typing",
 				token,
-				sessionId,
+				umqId,
 				steamId);
 
 			SecureHttpPostRequest request(hConnection, STEAM_API_URL "/ISteamWebUserPresenceOAuth/Message/v0001");
diff --git a/protocols/Steam/src/Steam/poll.h b/protocols/Steam/src/Steam/poll.h
index ba7a8927ca..be90890725 100644
--- a/protocols/Steam/src/Steam/poll.h
+++ b/protocols/Steam/src/Steam/poll.h
@@ -83,14 +83,14 @@ namespace SteamWebApi
 			const PoolItem *GetAt(int idx) const { return items.at(idx); }
 		};
 
-		static void Poll(HANDLE hConnection, const char *token, const char *sessionId, UINT32 messageId, PollResult *pollResult)
+		static void Poll(HANDLE hConnection, const char *token, const char *umqId, UINT32 messageId, PollResult *pollResult)
 		{
 			pollResult->success = false;
 			pollResult->need_relogin = false;
 			pollResult->items.clear();
 
 			char data[256];
-			mir_snprintf(data, SIZEOF(data), "access_token=%s&umqid=%s&message=%u", token, sessionId, messageId);
+			mir_snprintf(data, SIZEOF(data), "access_token=%s&umqid=%s&message=%u", token, umqId, messageId);
 
 			SecureHttpPostRequest request(hConnection, STEAM_API_URL "/ISteamWebUserPresenceOAuth/Poll/v0001");
 			request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
diff --git a/protocols/Steam/src/http_request.h b/protocols/Steam/src/http_request.h
index fe4d8a2cd2..c08bd1434a 100644
--- a/protocols/Steam/src/http_request.h
+++ b/protocols/Steam/src/http_request.h
@@ -7,6 +7,7 @@ enum HTTP_STATUS
 {
 	HTTP_STATUS_NONE = 0,
 	HTTP_STATUS_OK = 200,
+	HTTP_STATUS_FOUND = 302,
 	HTTP_STATUS_BAD_REQUEST = 400,
 	HTTP_STATUS_UNAUTHORIZED = 401,
 	HTTP_STATUS_FORBIDDEN = 403,
diff --git a/protocols/Steam/src/steam_account.cpp b/protocols/Steam/src/steam_account.cpp
index a12ae85667..90062d7375 100644
--- a/protocols/Steam/src/steam_account.cpp
+++ b/protocols/Steam/src/steam_account.cpp
@@ -19,7 +19,7 @@ void CSteamProto::SetServerStatusThread(void *arg)
 	WORD status = *((WORD*)&arg);
 
 	ptrA token(getStringA("TokenSecret"));
-	ptrA sessionId(getStringA("SessionID"));
+	ptrA umqId(getStringA("UMQID"));
 
 	int state = CSteamProto::MirandaToSteamState(status);
 
@@ -29,7 +29,7 @@ void CSteamProto::SetServerStatusThread(void *arg)
 
 	SteamWebApi::MessageApi::SendResult sendResult;
 	debugLogA("CSteamProto::SetServerStatusThread: call SteamWebApi::MessageApi::SendStatus");
-	SteamWebApi::MessageApi::SendStatus(m_hNetlibUser, token, sessionId, state, &sendResult);
+	SteamWebApi::MessageApi::SendStatus(m_hNetlibUser, token, umqId, state, &sendResult);
 
 	if (sendResult.IsSuccess())
 	{
@@ -172,11 +172,12 @@ void CSteamProto::LogInThread(void* param)
 		return;
 	}
 
-	setString("SessionID", loginResult.GetSessionId());
+	setString("UMQID", loginResult.GetUmqId());
 	setDword("MessageID", loginResult.GetMessageId());
 
 	// set selected status
-	//CSteamProto::SetServerStatusThread((void*)m_iDesiredStatus);
+	m_iStatus = m_iDesiredStatus;
+	ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus);
 
 	// load contact list
 	LoadContactListThread(NULL);
@@ -192,14 +193,14 @@ void CSteamProto::LogInThread(void* param)
 void CSteamProto::LogOutThread(void*)
 {
 	ptrA token(getStringA("TokenSecret"));
-	ptrA sessionId(getStringA("SessionID"));
+	ptrA umqId(getStringA("UMQID"));
 
 	while (m_bTerminated && m_hPollingThread != NULL)
 		Sleep(500);
 
 	debugLogA("CSteamProto::LogOutThread: call SteamWebApi::LoginApi::Logoff");
-	SteamWebApi::LoginApi::Logoff(m_hNetlibUser, token, sessionId);
+	SteamWebApi::LoginApi::Logoff(m_hNetlibUser, token, umqId);
 
-	delSetting("SessionID");
+	delSetting("UMQID");
 	m_bTerminated = false;
 }
\ No newline at end of file
diff --git a/protocols/Steam/src/steam_contacts.cpp b/protocols/Steam/src/steam_contacts.cpp
index 0bf050d18d..3936d4f742 100644
--- a/protocols/Steam/src/steam_contacts.cpp
+++ b/protocols/Steam/src/steam_contacts.cpp
@@ -55,32 +55,32 @@ MCONTACT CSteamProto::FindContact(const char *steamId)
 	return hContact;
 }
 
-void CSteamProto::UpdateContact(MCONTACT hContact, const SteamWebApi::FriendApi::Summary *contact)
+void CSteamProto::UpdateContact(MCONTACT hContact, const SteamWebApi::FriendApi::Summary *summary)
 {
 	// only if contact is in contact list
-	if (hContact && !FindContact(contact->GetSteamId()))
+	if (hContact && !FindContact(summary->GetSteamId()))
 		return;
 
 	// set common data
-	setWString(hContact, "Nick", contact->GetNickName());
-	setString(hContact, "Homepage", contact->GetHomepage());
+	setWString(hContact, "Nick", summary->GetNickName());
+	setString(hContact, "Homepage", summary->GetHomepage());
 	// only for contacts
 	if (hContact)
 	{
-		setDword(hContact, "LastEventDateTS", contact->GetLastEvent());
+		setDword(hContact, "LastEventDateTS", summary->GetLastEvent());
 
-		DWORD gameId = contact->GetGameId();
+		DWORD gameId = summary->GetGameId();
 		if (gameId >0)
 		{
 			setWord(hContact, "Status", ID_STATUS_OUTTOLUNCH);
-			db_set_ws(hContact, "CList", "StatusMsg", contact->GetGameInfo());
+			db_set_ws(hContact, "CList", "StatusMsg", summary->GetGameInfo());
 
-			setWString(hContact, "GameInfo", contact->GetGameInfo());
-			setDword(hContact, "GameID", contact->GetGameId());
+			setWString(hContact, "GameInfo", summary->GetGameInfo());
+			setDword(hContact, "GameID", summary->GetGameId());
 		}
 		else
 		{
-			WORD status = SteamToMirandaStatus(contact->GetState());
+			WORD status = SteamToMirandaStatus(summary->GetState());
 			setWord(hContact, "Status", status);
 
 			db_unset(hContact, "CList", "StatusMsg");
@@ -89,9 +89,14 @@ void CSteamProto::UpdateContact(MCONTACT hContact, const SteamWebApi::FriendApi:
 	}
 
 	// set name
-	const wchar_t *firstName = contact->GetFirstName();
-	const wchar_t *lastName = contact->GetLastName();
-	if (lstrlen(lastName) == 0)
+	const wchar_t *firstName = summary->GetFirstName();
+	const wchar_t *lastName = summary->GetLastName();
+	if (lstrlen(firstName) == 0)
+	{
+		delSetting(hContact, "FirstName");
+		delSetting(hContact, "LastName");
+	}
+	else if (lstrlen(lastName) == 0)
 	{
 		setWString(hContact, "FirstName", firstName);
 		delSetting(hContact, "LastName");
@@ -104,12 +109,12 @@ void CSteamProto::UpdateContact(MCONTACT hContact, const SteamWebApi::FriendApi:
 
 	// avatar
 	ptrA oldAvatar(getStringA("AvatarUrl"));
-	if (lstrcmpiA(oldAvatar, contact->GetAvatarUrl()))
+	if (lstrcmpiA(oldAvatar, summary->GetAvatarUrl()))
 	{
 		// todo: need to place in thread
 		SteamWebApi::AvatarApi::Avatar avatar;
 		debugLogA("CSteamProto::UpdateContact: SteamWebApi::AvatarApi::GetAvatar");
-		SteamWebApi::AvatarApi::GetAvatar(m_hNetlibUser, contact->GetAvatarUrl(), &avatar);
+		SteamWebApi::AvatarApi::GetAvatar(m_hNetlibUser, summary->GetAvatarUrl(), &avatar);
 
 		if (avatar.IsSuccess() && avatar.GetDataSize() > 0)
 		{
@@ -127,13 +132,13 @@ void CSteamProto::UpdateContact(MCONTACT hContact, const SteamWebApi::FriendApi:
 
 				ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, (HANDLE)&pai, 0);
 
-				setString("AvatarUrl", contact->GetAvatarUrl());
+				setString("AvatarUrl", summary->GetAvatarUrl());
 			}
 		}
 	}
 
 	// set country
-	const char *isoCode = contact->GetCountryCode();
+	const char *isoCode = summary->GetCountryCode();
 	if (!lstrlenA(isoCode))
 		this->delSetting(hContact, "Country");
 	else
@@ -204,24 +209,26 @@ MCONTACT CSteamProto::AddContact(const char *steamId)
 
 void CSteamProto::RaiseAuthRequestThread(void *arg)
 {
-	ptrA steamId((char*)arg);
-	ptrA token(getStringA("TokenSecret"));
-
-	MCONTACT hContact = FindContact(steamId);
+	MCONTACT hContact = (MCONTACT)arg;
 	if (!hContact)
-		hContact = AddContact(steamId);
+		debugLogA("CSteamProto::RaiseAuthRequestThread: error (contact is NULL)");
+
+	ptrA token(getStringA("TokenSecret"));
+	ptrA steamId(getStringA(hContact, "SteamID"));
 
 	SteamWebApi::FriendApi::Summaries summaries;
-	debugLogA("CSteamProto::LoadContactListThread: call SteamWebApi::FriendApi::LoadSummaries");
+	debugLogA("CSteamProto::RaiseAuthRequestThread: call SteamWebApi::FriendApi::LoadSummaries");
 	SteamWebApi::FriendApi::LoadSummaries(m_hNetlibUser, token, steamId, &summaries);
 
 	if (summaries.IsSuccess())
 	{
-		const SteamWebApi::FriendApi::Summary *contact = summaries.GetAt(0);
+		const SteamWebApi::FriendApi::Summary *summary = summaries.GetAt(0);
+
+		UpdateContact(hContact, summary);
 
-		char *nickName = mir_utf8encodeW(contact->GetNickName());
-		char *firstName = mir_utf8encodeW(contact->GetFirstName());
-		char *lastName = mir_utf8encodeW(contact->GetLastName());
+		char *nickName = mir_utf8encodeW(summary->GetNickName());
+		char *firstName = mir_utf8encodeW(summary->GetFirstName());
+		char *lastName = mir_utf8encodeW(summary->GetLastName());
 		char reason[MAX_PATH];
 		mir_snprintf(reason, SIZEOF(reason), Translate("%s has added you to his or her Friend List"), nickName);
 
@@ -255,13 +262,14 @@ void CSteamProto::AuthAllowThread(void *arg)
 	if (!hContact)
 		return;
 
+	ptrA token(getStringA("TokenSecret"));
 	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);
+	SteamWebApi::InvitationApi::Accept(m_hNetlibUser, token, sessionId, steamId, who, &result);
 
 	if (result.IsSuccess())
 	{
@@ -307,13 +315,28 @@ void CSteamProto::LoadContactListThread(void*)
 		CMStringA newContacts;
 		for (size_t i = 0; i < friendList.GetItemCount(); i++)
 		{
-			const char * steamId = friendList.GetAt(i);
-			if (!FindContact(steamId))
+			const SteamWebApi::FriendListApi::FriendListItem *item = friendList.GetAt(i);
+
+			const char *steamId = item->GetSteamId();
+			SteamWebApi::FriendListApi::FRIEND_TYPE type = item->GetType();
+
+			if (type == SteamWebApi::FriendListApi::FRIEND_TYPE_FRIEND)
+			{
+				if (!FindContact(steamId))
+				{
+					if (newContacts.IsEmpty())
+						newContacts.Append(steamId);
+					else
+						newContacts.AppendFormat(",%s", steamId);
+				}
+			}
+			else if (type == SteamWebApi::FriendListApi::FRIEND_TYPE_NONE)
 			{
-				if (newContacts.IsEmpty())
-					newContacts.Append(steamId);
-				else
-					newContacts.AppendFormat(",%s", steamId);
+				MCONTACT hContact = FindContact(steamId);
+				if (!hContact)
+					hContact = AddContact(steamId);
+
+				RaiseAuthRequestThread((void*)hContact);
 			}
 		}
 
diff --git a/protocols/Steam/src/steam_messages.cpp b/protocols/Steam/src/steam_messages.cpp
index 99d7238936..ec94d20907 100644
--- a/protocols/Steam/src/steam_messages.cpp
+++ b/protocols/Steam/src/steam_messages.cpp
@@ -5,12 +5,12 @@ void CSteamProto::SendMessageThread(void *arg)
 	SendMessageParam *param = (SendMessageParam*)arg;
 
 	ptrA token(getStringA("TokenSecret"));
-	ptrA sessionId(getStringA("SessionID"));
+	ptrA umqId(getStringA("UMQID"));
 	ptrA steamId(getStringA(param->hContact, "SteamID"));
 
 	SteamWebApi::MessageApi::SendResult sendResult;
 	debugLogA("CSteamProto::SendMessageThread: call SteamWebApi::PollApi::SteamWebApi::MessageApi::SendMessage");
-	SteamWebApi::MessageApi::SendMessage(m_hNetlibUser, token, sessionId, steamId, param->text, &sendResult);
+	SteamWebApi::MessageApi::SendMessage(m_hNetlibUser, token, umqId, steamId, param->text, &sendResult);
 
 	ProtoBroadcastAck(
 		param->hContact,
@@ -27,10 +27,10 @@ void CSteamProto::SendTypingThread(void *arg)
 	MCONTACT hContact = (MCONTACT)arg;
 
 	ptrA token(getStringA("TokenSecret"));
-	ptrA sessionId(getStringA("SessionID"));
+	ptrA umqId(getStringA("UMQID"));
 	ptrA steamId(getStringA(hContact, "SteamID"));
 
 	SteamWebApi::MessageApi::SendResult sendResult;
 	debugLogA("CSteamProto::SendTypingThread: call SteamWebApi::PollApi::SteamWebApi::MessageApi::SendMessage");
-	SteamWebApi::MessageApi::SendTyping(m_hNetlibUser, token, sessionId, steamId, &sendResult);
+	SteamWebApi::MessageApi::SendTyping(m_hNetlibUser, token, umqId, steamId, &sendResult);
 }
\ No newline at end of file
diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp
index 771d6884b6..8040a1b226 100644
--- a/protocols/Steam/src/steam_proto.cpp
+++ b/protocols/Steam/src/steam_proto.cpp
@@ -77,7 +77,17 @@ int __cdecl CSteamProto::Authorize(HANDLE hDbEvent)
 
 int __cdecl CSteamProto::AuthDeny(HANDLE hDbEvent, const TCHAR* szReason)
 {
-	return 0;
+	if (IsOnline() && hDbEvent)
+	{
+		MCONTACT hContact = GetContactFromAuthEvent(hDbEvent);
+		if (hContact == INVALID_CONTACT_ID)
+			return 1;
+
+		ForkThread(&CSteamProto::AuthDenyThread, (void*)hContact);
+		// todo: how to return real status?
+		return 0;
+	}
+	return 1;
 }
 
 int __cdecl CSteamProto::AuthRecv(MCONTACT hContact, PROTORECVEVENT* pre)
diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h
index 5996d248ba..402338b2c7 100644
--- a/protocols/Steam/src/steam_proto.h
+++ b/protocols/Steam/src/steam_proto.h
@@ -132,7 +132,7 @@ protected:
 
 	MCONTACT GetContactFromAuthEvent(HANDLE hEvent);
 
-	void UpdateContact(MCONTACT hContact, const SteamWebApi::FriendApi::Summary *contact);
+	void UpdateContact(MCONTACT hContact, const SteamWebApi::FriendApi::Summary *summary);
 	void __cdecl UpdateContactsThread(void*);
 
 	MCONTACT FindContact(const char *steamId);
diff --git a/protocols/Steam/src/steam_thread.cpp b/protocols/Steam/src/steam_thread.cpp
index e95af473dd..a9deac4e74 100644
--- a/protocols/Steam/src/steam_thread.cpp
+++ b/protocols/Steam/src/steam_thread.cpp
@@ -1,9 +1,9 @@
 #include "common.h"
 
-void CSteamProto::PollServer(const char *token, const char *sessionId, UINT32 messageId, SteamWebApi::PollApi::PollResult *pollResult)
+void CSteamProto::PollServer(const char *token, const char *umqId, UINT32 messageId, SteamWebApi::PollApi::PollResult *pollResult)
 {
 	debugLogA("CSteamProto::PollServer: call SteamWebApi::PollApi::Poll");
-	SteamWebApi::PollApi::Poll(m_hNetlibUser, token, sessionId, messageId, pollResult);
+	SteamWebApi::PollApi::Poll(m_hNetlibUser, token, umqId, messageId, pollResult);
 
 	if (!pollResult->IsSuccess())
 		return;
@@ -113,11 +113,14 @@ void CSteamProto::PollServer(const char *token, const char *sessionId, UINT32 me
 				SteamWebApi::PollApi::Relationship *crs = (SteamWebApi::PollApi::Relationship*)item;
 
 				const char *steamId = crs->GetSteamId();
+				
 				MCONTACT hContact = FindContact(steamId);
 				if (!hContact)
 					hContact = AddContact(steamId);
 
-				
+				setByte(hContact, "Auth", 1);
+				setByte(hContact, "Grant", 1);
+				RaiseAuthRequestThread((void*)hContact);
 			}
 			break;
 		}
@@ -132,13 +135,13 @@ void CSteamProto::PollingThread(void*)
 	debugLogA("CSteamProto::PollingThread: entering");
 
 	ptrA token(getStringA("TokenSecret"));
-	ptrA sessionId(getStringA("SessionID"));
+	ptrA umqId(getStringA("UMQID"));
 	UINT32 messageId = getDword("MessageID", 0);
 
 	SteamWebApi::PollApi::PollResult pollResult;
 	while (!m_bTerminated)
 	{
-		PollServer(token, sessionId, messageId, &pollResult);
+		PollServer(token, umqId, messageId, &pollResult);
 		
 		if (pollResult.IsNeedRelogin())
 		{
-- 
cgit v1.2.3