summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/Steam/Steam_12.vcxproj2
-rw-r--r--protocols/Steam/Steam_12.vcxproj.filters6
-rw-r--r--protocols/Steam/src/Steam/friend.h24
-rw-r--r--protocols/Steam/src/Steam/friend_list.h44
-rw-r--r--protocols/Steam/src/Steam/invitation.h77
-rw-r--r--protocols/Steam/src/Steam/poll.h24
-rw-r--r--protocols/Steam/src/Steam/steam.h10
-rw-r--r--protocols/Steam/src/common.h2
-rw-r--r--protocols/Steam/src/stdafx.cpp4
-rw-r--r--protocols/Steam/src/steam_account.cpp4
-rw-r--r--protocols/Steam/src/steam_avatars.cpp6
-rw-r--r--protocols/Steam/src/steam_contacts.cpp173
-rw-r--r--protocols/Steam/src/steam_events.cpp2
-rw-r--r--protocols/Steam/src/steam_menus.cpp78
-rw-r--r--protocols/Steam/src/steam_proto.cpp40
-rw-r--r--protocols/Steam/src/steam_proto.h40
-rw-r--r--protocols/Steam/src/steam_thread.cpp27
-rw-r--r--protocols/Steam/src/steam_utils.cpp13
18 files changed, 482 insertions, 94 deletions
diff --git a/protocols/Steam/Steam_12.vcxproj b/protocols/Steam/Steam_12.vcxproj
index 6cf599dbfa..e62e575c30 100644
--- a/protocols/Steam/Steam_12.vcxproj
+++ b/protocols/Steam/Steam_12.vcxproj
@@ -199,6 +199,7 @@
<ClInclude Include="src\Steam\crypto.h" />
<ClInclude Include="src\Steam\friend.h" />
<ClInclude Include="src\Steam\friend_list.h" />
+ <ClInclude Include="src\Steam\invitation.h" />
<ClInclude Include="src\Steam\login.h" />
<ClInclude Include="src\Steam\message.h" />
<ClInclude Include="src\Steam\poll.h" />
@@ -214,6 +215,7 @@
<ClCompile Include="src\steam_events.cpp" />
<ClCompile Include="src\steam_dialogs.cpp" />
<ClCompile Include="src\steam_instances.cpp" />
+ <ClCompile Include="src\steam_menus.cpp" />
<ClCompile Include="src\steam_messages.cpp" />
<ClCompile Include="src\steam_proto.cpp" />
<ClCompile Include="src\stdafx.cpp">
diff --git a/protocols/Steam/Steam_12.vcxproj.filters b/protocols/Steam/Steam_12.vcxproj.filters
index e928166046..ee476ff7c2 100644
--- a/protocols/Steam/Steam_12.vcxproj.filters
+++ b/protocols/Steam/Steam_12.vcxproj.filters
@@ -51,6 +51,9 @@
<ClCompile Include="src\steam_avatars.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\steam_menus.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\resource.h">
@@ -95,6 +98,9 @@
<ClInclude Include="src\common.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="src\Steam\invitation.h">
+ <Filter>Header Files\Steam</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="res\resource.rc">
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