summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
Diffstat (limited to 'protocols')
-rw-r--r--protocols/Steam/src/Steam/poll.h4
-rw-r--r--protocols/Steam/src/common.h91
-rw-r--r--protocols/Steam/src/steam_events.cpp166
-rw-r--r--protocols/Steam/src/steam_pooling.cpp2
-rw-r--r--protocols/Steam/src/steam_proto.cpp829
-rw-r--r--protocols/Steam/src/steam_proto.h565
6 files changed, 851 insertions, 806 deletions
diff --git a/protocols/Steam/src/Steam/poll.h b/protocols/Steam/src/Steam/poll.h
index 7411ad85e6..35d8330385 100644
--- a/protocols/Steam/src/Steam/poll.h
+++ b/protocols/Steam/src/Steam/poll.h
@@ -6,14 +6,14 @@ namespace SteamWebApi
class PollRequest : public HttpsPostRequest
{
public:
- PollRequest(const char *token, const char *umqId, UINT32 messageId) :
+ PollRequest(const char *token, const char *umqId, UINT32 messageId, int idleSeconds) :
HttpsPostRequest(STEAM_API_URL "/ISteamWebUserPresenceOAuth/Poll/v0001")
{
timeout = 30000;
flags |= NLHRF_PERSISTENT;
char data[256];
- mir_snprintf(data, SIZEOF(data), "access_token=%s&umqid=%s&message=%u", token, umqId, messageId);
+ mir_snprintf(data, SIZEOF(data), "access_token=%s&umqid=%s&message=%u&secidletime=%d", token, umqId, messageId, idleSeconds);
SetData(data, strlen(data));
AddHeader("Connection", "keep-alive");
diff --git a/protocols/Steam/src/common.h b/protocols/Steam/src/common.h
index 4c43df32b7..36427d7a1c 100644
--- a/protocols/Steam/src/common.h
+++ b/protocols/Steam/src/common.h
@@ -1,46 +1,47 @@
-#ifndef _COMMON_H_
-#define _COMMON_H_
-
-#include <windows.h>
-#include <commctrl.h>
-#include <time.h>
-
-#include <newpluginapi.h>
-#include <m_database.h>
-#include <m_langpack.h>
-#include <m_message.h>
-#include <m_netlib.h>
-#include <m_options.h>
-#include <m_popup.h>
-#include <m_json.h>
-#include <m_avatars.h>
-#include <m_icolib.h>
-#include <m_skin.h>
-#include <m_clist.h>
-#include <m_genmenu.h>
-#include <m_string.h>
-#include <m_freeimage.h>
-#include <m_imgsrvc.h>
-#include <m_protocols.h>
-#include <m_protomod.h>
-#include <m_protosvc.h>
-#include <m_protoint.h>
-#include <win2k.h>
-
-#include <map>
-#include <vector>
-#include <string>
-
-#include "resource.h"
-#include "version.h"
-
-#define MODULE "Steam"
-
-class CSteamProto;
-extern HINSTANCE g_hInstance;
-
-#include "Steam\steam.h"
-
-#include "steam_proto.h"
-
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <windows.h>
+#include <commctrl.h>
+#include <time.h>
+
+#include <newpluginapi.h>
+#include <m_database.h>
+#include <m_langpack.h>
+#include <m_message.h>
+#include <m_netlib.h>
+#include <m_options.h>
+#include <m_popup.h>
+#include <m_json.h>
+#include <m_avatars.h>
+#include <m_icolib.h>
+#include <m_skin.h>
+#include <m_clist.h>
+#include <m_genmenu.h>
+#include <m_string.h>
+#include <m_freeimage.h>
+#include <m_imgsrvc.h>
+#include <m_protocols.h>
+#include <m_protomod.h>
+#include <m_protosvc.h>
+#include <m_protoint.h>
+#include <m_idle.h>
+#include <win2k.h>
+
+#include <map>
+#include <vector>
+#include <string>
+
+#include "resource.h"
+#include "version.h"
+
+#define MODULE "Steam"
+
+class CSteamProto;
+extern HINSTANCE g_hInstance;
+
+#include "Steam\steam.h"
+
+#include "steam_proto.h"
+
#endif //_COMMON_H_ \ No newline at end of file
diff --git a/protocols/Steam/src/steam_events.cpp b/protocols/Steam/src/steam_events.cpp
index 4a61c913ef..3c8d758f54 100644
--- a/protocols/Steam/src/steam_events.cpp
+++ b/protocols/Steam/src/steam_events.cpp
@@ -1,67 +1,101 @@
-#include "common.h"
-
-int CSteamProto::OnModulesLoaded(WPARAM, LPARAM)
-{
- HookEventObj(ME_OPT_INITIALISE, OnOptionsInit, this);
-
- TCHAR name[128];
- mir_sntprintf(name, SIZEOF(name), TranslateT("%s connection"), m_tszUserName);
-
- NETLIBUSER nlu = { sizeof(nlu) };
- nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR;
- nlu.ptszDescriptiveName = name;
- nlu.szSettingsModule = m_szModuleName;
- m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
-
- HookEvent(ME_CLIST_PREBUILDCONTACTMENU, &CSteamProto::PrebuildContactMenu);
-
- return 0;
-}
-
-int CSteamProto::OnPreShutdown(WPARAM, LPARAM)
-{
- //SetStatus(ID_STATUS_OFFLINE);
-
- Netlib_CloseHandle(this->m_hNetlibUser);
- this->m_hNetlibUser = NULL;
-
- return 0;
-}
-
-INT_PTR CSteamProto::OnAccountManagerInit(WPARAM wParam, LPARAM lParam)
-{
- return (int)CreateDialogParam(
- g_hInstance,
- MAKEINTRESOURCE(IDD_ACCMGR),
- (HWND)lParam,
- CSteamProto::MainOptionsProc,
- (LPARAM)this);
-}
-
-int CSteamProto::OnOptionsInit(void *obj, WPARAM wParam, LPARAM lParam)
-{
- CSteamProto *instance = (CSteamProto*)obj;
-
- char *title = mir_t2a(instance->m_tszUserName);
-
- OPTIONSDIALOGPAGE odp = { sizeof(odp) };
- odp.hInstance = g_hInstance;
- odp.pszTitle = title;
- odp.dwInitParam = LPARAM(obj);
- odp.flags = ODPF_BOLDGROUPS;
- odp.pszGroup = LPGEN("Network");
-
- odp.pszTab = LPGEN("Account");
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_MAIN);
- odp.pfnDlgProc = MainOptionsProc;
- Options_AddPage(wParam, &odp);
-
- odp.pszTab = LPGEN("Blocked contacts");
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_BLOCK_LIST);
- odp.pfnDlgProc = BlockListOptionsProc;
- Options_AddPage(wParam, &odp);
-
- mir_free(title);
-
- return 0;
+#include "common.h"
+
+int CSteamProto::OnModulesLoaded(WPARAM, LPARAM)
+{
+ HookEventObj(ME_OPT_INITIALISE, OnOptionsInit, this);
+ HookProtoEvent(ME_IDLE_CHANGED, &CSteamProto::OnIdleChanged);
+
+ TCHAR name[128];
+ mir_sntprintf(name, SIZEOF(name), TranslateT("%s connection"), m_tszUserName);
+
+ NETLIBUSER nlu = { sizeof(nlu) };
+ nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR;
+ nlu.ptszDescriptiveName = name;
+ nlu.szSettingsModule = m_szModuleName;
+ m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
+
+ HookEvent(ME_CLIST_PREBUILDCONTACTMENU, &CSteamProto::PrebuildContactMenu);
+
+ return 0;
+}
+
+int CSteamProto::OnPreShutdown(WPARAM, LPARAM)
+{
+ //SetStatus(ID_STATUS_OFFLINE);
+
+ Netlib_CloseHandle(this->m_hNetlibUser);
+ this->m_hNetlibUser = NULL;
+
+ return 0;
+}
+
+INT_PTR CSteamProto::OnAccountManagerInit(WPARAM wParam, LPARAM lParam)
+{
+ return (int)CreateDialogParam(
+ g_hInstance,
+ MAKEINTRESOURCE(IDD_ACCMGR),
+ (HWND)lParam,
+ CSteamProto::MainOptionsProc,
+ (LPARAM)this);
+}
+
+int CSteamProto::OnOptionsInit(void *obj, WPARAM wParam, LPARAM lParam)
+{
+ CSteamProto *instance = (CSteamProto*)obj;
+
+ char *title = mir_t2a(instance->m_tszUserName);
+
+ OPTIONSDIALOGPAGE odp = { sizeof(odp) };
+ odp.hInstance = g_hInstance;
+ odp.pszTitle = title;
+ odp.dwInitParam = LPARAM(obj);
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.pszGroup = LPGEN("Network");
+
+ odp.pszTab = LPGEN("Account");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_MAIN);
+ odp.pfnDlgProc = MainOptionsProc;
+ Options_AddPage(wParam, &odp);
+
+ odp.pszTab = LPGEN("Blocked contacts");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_BLOCK_LIST);
+ odp.pfnDlgProc = BlockListOptionsProc;
+ Options_AddPage(wParam, &odp);
+
+ mir_free(title);
+
+ return 0;
+}
+
+int CSteamProto::OnIdleChanged(WPARAM wParam, LPARAM lParam)
+{
+ bool idle = (lParam & IDF_ISIDLE) != 0;
+ bool privacy = (lParam & IDF_PRIVACY) != 0;
+
+ // Respect user choice about (not) notifying idle to protocols
+ if (privacy)
+ return 0;
+
+ // We don't want to reset idle time when we're already in idle state
+ if (idle && m_idleTS > 0)
+ return 0;
+
+ if (idle)
+ {
+ // User started being idle
+ MIRANDA_IDLE_INFO mii = { sizeof(mii) };
+ CallService(MS_IDLE_GETIDLEINFO, 0, (LPARAM)&mii);
+
+ // Compute time when user really became idle
+ m_idleTS = time(0) - mii.idleTime * 60;
+ setDword("IdleTS", m_idleTS);
+ }
+ else
+ {
+ // User stopped being idle
+ m_idleTS = 0;
+ delSetting("IdleTS");
+ }
+
+ return 0;
} \ No newline at end of file
diff --git a/protocols/Steam/src/steam_pooling.cpp b/protocols/Steam/src/steam_pooling.cpp
index 41adf28304..ff21a8e9c2 100644
--- a/protocols/Steam/src/steam_pooling.cpp
+++ b/protocols/Steam/src/steam_pooling.cpp
@@ -177,7 +177,7 @@ void CSteamProto::PollingThread(void*)
bool breaked = false;
while (!isTerminated && !breaked && errors < POLLING_ERRORS_LIMIT)
{
- SteamWebApi::PollRequest *request = new SteamWebApi::PollRequest(token, umqId, messageId);
+ SteamWebApi::PollRequest *request = new SteamWebApi::PollRequest(token, umqId, messageId, IdleSeconds());
debugLogA("CSteamProto::PollingThread: %s", request->szUrl);
request->szUrl = (char*)request->url.c_str();
request->nlc = m_pollingConnection;
diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp
index f2878659f0..612d66768f 100644
--- a/protocols/Steam/src/steam_proto.cpp
+++ b/protocols/Steam/src/steam_proto.cpp
@@ -1,413 +1,418 @@
-#include "common.h"
-
-CSteamProto::CSteamProto(const char* protoName, const TCHAR* userName) :
- PROTO<CSteamProto>(protoName, userName),
- hAuthProcess(1),
- hMessageProcess(1),
- requestsQueue(1)
-{
- CreateProtoService(PS_CREATEACCMGRUI, &CSteamProto::OnAccountManagerInit);
-
- InitializeCriticalSection(&this->contact_search_lock);
-
- InitQueue();
-
- // icons
- wchar_t filePath[MAX_PATH];
- GetModuleFileName(g_hInstance, filePath, MAX_PATH);
-
- wchar_t sectionName[100];
- mir_sntprintf(sectionName, SIZEOF(sectionName), _T("%s/%s"), LPGENT("Protocols"), LPGENT(MODULE));
-
- char settingName[100];
- mir_snprintf(settingName, SIZEOF(settingName), "%s_%s", MODULE, "main");
-
- SKINICONDESC sid = {0};
- sid.cbSize = sizeof(SKINICONDESC);
- sid.flags = SIDF_ALL_TCHAR;
- sid.ptszDefaultFile = filePath;
- sid.pszName = settingName;
- sid.ptszSection = sectionName;
- sid.ptszDescription = LPGENT("Protocol icon");
- sid.iDefaultIndex = -IDI_STEAM;
- Skin_AddIcon(&sid);
-
- SetAllContactsStatus(ID_STATUS_OFFLINE);
-
- // 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()
-{
- UninitQueue();
-
- DeleteCriticalSection(&this->contact_search_lock);
-}
-
-MCONTACT __cdecl CSteamProto::AddToList(int flags, PROTOSEARCHRESULT* psr)
-{
- MCONTACT hContact = NULL;
- ptrA steamId(mir_u2a(psr->id));
- if (psr->cbSize == sizeof(PROTOSEARCHRESULT))
- {
- if (!FindContact(steamId))
- {
- //hContact = AddContact(steamId, true);
- //ForkThread(&CSteamProto::UpdateContactsThread, (void*)mir_strdup(steamId));
-
- ptrA token(getStringA("TokenSecret"));
-
- PushRequest(
- new SteamWebApi::GetUserSummariesRequest(token, steamId),
- &CSteamProto::OnGotUserSummaries);
- }
- }
- else if (psr->cbSize == sizeof(STEAM_SEARCH_RESULT))
- {
- STEAM_SEARCH_RESULT *ssr = (STEAM_SEARCH_RESULT*)psr;
- hContact = AddContact(steamId, true);
- UpdateContact(hContact, ssr->data);
- }
-
- return hContact;
-}
-
-MCONTACT __cdecl CSteamProto::AddToListByEvent(int flags, int iContact, HANDLE hDbEvent)
-{
- return 0;
-}
-
-int __cdecl CSteamProto::Authorize(HANDLE hDbEvent)
-{
- if (IsOnline() && hDbEvent)
- {
- MCONTACT hContact = GetContactFromAuthEvent(hDbEvent);
- if (hContact == INVALID_CONTACT_ID)
- return 1;
-
- //ForkThread(&CSteamProto::AuthAllowThread, (void*)hContact);
-
- ptrA token(getStringA("TokenSecret"));
- ptrA sessionId(getStringA("SessionID"));
- ptrA steamId(getStringA("SteamID"));
- char *who = getStringA(hContact, "SteamID");
-
- PushRequest(
- new SteamWebApi::ApprovePendingRequest(token, sessionId, steamId, who),
- &CSteamProto::OnPendingApproved,
- who);
-
- return 0;
- }
-
- return 1;
-}
-
-int __cdecl CSteamProto::AuthDeny(HANDLE hDbEvent, const TCHAR* szReason)
-{
- if (IsOnline() && hDbEvent)
- {
- MCONTACT hContact = GetContactFromAuthEvent(hDbEvent);
- if (hContact == INVALID_CONTACT_ID)
- return 1;
-
- //ForkThread(&CSteamProto::AuthDenyThread, (void*)hContact);
-
- ptrA token(getStringA("TokenSecret"));
- ptrA sessionId(getStringA("SessionID"));
- ptrA steamId(getStringA("SteamID"));
- char *who = getStringA(hContact, "SteamID");
-
- PushRequest(
- new SteamWebApi::IgnorePendingRequest(token, sessionId, steamId, who),
- &CSteamProto::OnPendingIgnoreded,
- who);
-
- return 0;
- }
-
- return 1;
-}
-
-int __cdecl CSteamProto::AuthRecv(MCONTACT hContact, PROTORECVEVENT* pre)
-{
- return 0;
-}
-
-int __cdecl CSteamProto::AuthRequest(MCONTACT hContact, const TCHAR* szMessage)
-{
- if (IsOnline() && hContact)
- {
- UINT hAuth = InterlockedIncrement(&hAuthProcess);
-
- SendAuthParam *param = (SendAuthParam*)mir_calloc(sizeof(SendAuthParam));
- param->hContact = hContact;
- param->hAuth = (HANDLE)hAuth;
-
- //ForkThread(&CSteamProto::AddContactThread, param);
-
- ptrA token(getStringA("TokenSecret"));
- ptrA sessionId(getStringA("SessionID"));
- ptrA steamId(getStringA("SteamID"));
- ptrA who(getStringA(hContact, "SteamID"));
-
- PushRequest(
- new SteamWebApi::AddFriendRequest(token, sessionId, steamId, who),
- &CSteamProto::OnFriendAdded,
- param);
-
- return hAuth;
- }
-
- return 1;
-}
-
-HANDLE __cdecl CSteamProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szPath)
-{
- return 0;
-}
-
-int __cdecl CSteamProto::FileCancel(MCONTACT hContact, HANDLE hTransfer)
-{
- return 0;
-}
-
-int __cdecl CSteamProto::FileDeny(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szReason)
-{
- return 0;
-}
-
-int __cdecl CSteamProto::FileResume(HANDLE hTransfer, int* action, const TCHAR** szFilename)
-{
- return 0;
-}
-
-DWORD_PTR __cdecl CSteamProto:: GetCaps(int type, MCONTACT hContact)
-{
- switch(type)
- {
- case PFLAGNUM_1:
- return PF1_IM | PF1_BASICSEARCH | PF1_SEARCHBYNAME | PF1_AUTHREQ | PF1_SERVERCLIST | PF1_ADDSEARCHRES;
- case PFLAGNUM_2:
- return PF2_ONLINE | PF2_SHORTAWAY | PF2_HEAVYDND | PF2_OUTTOLUNCH;
- case PFLAGNUM_4:
- return PF4_AVATARS | PF4_NOCUSTOMAUTH | PF4_NOAUTHDENYREASON | PF4_FORCEAUTH | PF4_FORCEADDED | PF4_IMSENDUTF;// | PF4_IMSENDOFFLINE | PF4_SUPPORTTYPING;
- case PFLAGNUM_5:
- return PF2_SHORTAWAY | PF2_HEAVYDND | PF2_OUTTOLUNCH;
- case PFLAG_UNIQUEIDTEXT:
- return (DWORD_PTR)Translate("SteamID");
- case PFLAG_UNIQUEIDSETTING:
- return (DWORD_PTR)"SteamID";
- case PFLAG_MAXLENOFMESSAGE:
- return 200000; // this is guessed limit, in reality it is probably bigger
- default:
- return 0;
- }
-}
-
-int __cdecl CSteamProto::GetInfo(MCONTACT hContact, int infoType ) { return 0; }
-
-HANDLE __cdecl CSteamProto::SearchBasic(const TCHAR* id)
-{
- if (!this->IsOnline())
- return 0;
-
- //ForkThread(&CSteamProto::SearchByIdThread, mir_wstrdup(id));
-
- ptrA token(getStringA("TokenSecret"));
- ptrA steamId(mir_u2a(id));
-
- PushRequest(
- new SteamWebApi::GetUserSummariesRequest(token, steamId),
- &CSteamProto::OnSearchByIdEnded,
- mir_wstrdup(id));
-
- return (HANDLE)STEAM_SEARCH_BYID;
-}
-
-HANDLE __cdecl CSteamProto::SearchByEmail(const TCHAR* email)
-{
- return 0;
-}
-
-HANDLE __cdecl CSteamProto::SearchByName(const TCHAR* nick, const TCHAR* firstName, const TCHAR* lastName)
-{
- //if (!this->IsOnline())
- return 0;
-
- ptrA token(getStringA("TokenSecret"));
-
- CMString keywords;
- keywords.AppendFormat(L" %s", nick);
- keywords.AppendFormat(L" %s", firstName);
- keywords.AppendFormat(L" %s", lastName);
- keywords.Trim();
-
- //ForkThread(&CSteamProto::SearchByNameThread, mir_wstrdup(keywords));
- PushRequest(
- new SteamWebApi::SearchRequest(token, mir_utf8encodeW(keywords)),
- &CSteamProto::OnSearchByNameStarted);
-
- return (HANDLE)STEAM_SEARCH_BYNAME;
-}
-
-HWND __cdecl CSteamProto::SearchAdvanced( HWND owner ) { return 0; }
-
-HWND __cdecl CSteamProto::CreateExtendedSearchUI( HWND owner ){ return 0; }
-
-int __cdecl CSteamProto::RecvContacts(MCONTACT hContact, PROTORECVEVENT* pre)
-{
- return 0;
-}
-
-int __cdecl CSteamProto::RecvFile(MCONTACT hContact, PROTORECVFILET* pre)
-{
- return 0;
-}
-
-int __cdecl CSteamProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT* pre)
-{
- return (INT_PTR)AddDBEvent(hContact, EVENTTYPE_MESSAGE, pre->timestamp, DBEF_UTF, lstrlenA(pre->szMessage), (BYTE*)pre->szMessage);
-}
-
-int __cdecl CSteamProto::RecvUrl(MCONTACT hContact, PROTORECVEVENT *) { return 0; }
-
-int __cdecl CSteamProto::SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList)
-{
- return 0;
-}
-
-HANDLE __cdecl CSteamProto::SendFile(MCONTACT hContact, const TCHAR *szDescription, TCHAR **ppszFiles)
-{
- return 0;
-}
-
-int __cdecl CSteamProto::SendMsg(MCONTACT hContact, int flags, const char *msg)
-{
- UINT hMessage = InterlockedIncrement(&hMessageProcess);
-
- if (flags & PREF_UNICODE)
- msg = mir_utf8encode(msg); // FIXME: Token from FacebookRM. Is it needed? Usually we get PREF_UTF8 flag instead. And does it cause memory leak?
-
- SendMessageParam *param = (SendMessageParam*)mir_calloc(sizeof(SendMessageParam));
- param->hContact = hContact;
- param->hMessage = (HANDLE)hMessage;
-
-
- ptrA token(getStringA("TokenSecret"));
- ptrA umqid(getStringA("UMQID"));
- ptrA steamId(getStringA(hContact, "SteamID"));
-
- PushRequest(
- new SteamWebApi::SendMessageRequest(token, umqid, steamId, msg),
- &CSteamProto::OnMessageSent,
- param);
-
- return hMessage;
-}
-
-int __cdecl CSteamProto::SendUrl(MCONTACT hContact, int flags, const char *url) { return 0; }
-
-int __cdecl CSteamProto::SetApparentMode(MCONTACT hContact, int mode) { return 0; }
-
-int CSteamProto::SetStatus(int new_status)
-{
- // Routing statuses not supported by Steam
- switch (new_status)
- {
- case ID_STATUS_OFFLINE:
- 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)
- {
- //isTerminated = true;
- //ForkThread(&CSteamProto::LogOutThread, NULL);
-
- m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
- ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
-
- StopQueue();
-
- 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);
-
- //ForkThread(&CSteamProto::LogInThread, NULL);
- StartQueue();
- }
-
- return 0;
-}
-
-HANDLE __cdecl CSteamProto::GetAwayMsg(MCONTACT hContact) { return 0; }
-int __cdecl CSteamProto::RecvAwayMsg(MCONTACT hContact, int mode, PROTORECVEVENT *evt) { return 0; }
-int __cdecl CSteamProto::SetAwayMsg(int m_iStatus, const TCHAR *msg) { return 0; }
-
-int __cdecl CSteamProto::UserIsTyping(MCONTACT hContact, int type)
-{
- return 0;
-}
-
-int __cdecl CSteamProto::OnEvent(PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam)
-{
- switch (eventType)
- {
- case EV_PROTO_ONLOAD:
- return this->OnModulesLoaded(wParam, lParam);
-
- case EV_PROTO_ONEXIT:
- return this->OnPreShutdown(wParam, lParam);
-
- /*case EV_PROTO_ONOPTIONS:
- return this->OnOptionsInit(wParam, lParam);*/
-
- case EV_PROTO_ONCONTACTDELETED:
- if (IsOnline())
- {
- MCONTACT hContact = (MCONTACT)wParam;
-
- ptrA token(getStringA("TokenSecret"));
- ptrA sessionId(getStringA("SessionID"));
- ptrA steamId(getStringA("SteamID"));
- ptrA who(getStringA(hContact, "SteamID"));
-
- // Don't request delete contact from server when we're not friends anyway
- if (getByte(hContact, "Auth", 0) != 0)
- return 0;
-
- PushRequest(
- new SteamWebApi::RemoveFriendRequest(token, sessionId, steamId, who),
- &CSteamProto::OnFriendRemoved,
- (void*)hContact);
- }
- return 0;
-
- case EV_PROTO_ONMENU:
- this->OnInitStatusMenu();
- break;
- }
-
- return 1;
+#include "common.h"
+
+CSteamProto::CSteamProto(const char* protoName, const TCHAR* userName) :
+ PROTO<CSteamProto>(protoName, userName),
+ hAuthProcess(1),
+ hMessageProcess(1),
+ requestsQueue(1)
+{
+ CreateProtoService(PS_CREATEACCMGRUI, &CSteamProto::OnAccountManagerInit);
+
+ InitializeCriticalSection(&this->contact_search_lock);
+
+ InitQueue();
+
+ m_idleTS = 0;
+
+ // icons
+ wchar_t filePath[MAX_PATH];
+ GetModuleFileName(g_hInstance, filePath, MAX_PATH);
+
+ wchar_t sectionName[100];
+ mir_sntprintf(sectionName, SIZEOF(sectionName), _T("%s/%s"), LPGENT("Protocols"), LPGENT(MODULE));
+
+ char settingName[100];
+ mir_snprintf(settingName, SIZEOF(settingName), "%s_%s", MODULE, "main");
+
+ SKINICONDESC sid = {0};
+ sid.cbSize = sizeof(SKINICONDESC);
+ sid.flags = SIDF_ALL_TCHAR;
+ sid.ptszDefaultFile = filePath;
+ sid.pszName = settingName;
+ sid.ptszSection = sectionName;
+ sid.ptszDescription = LPGENT("Protocol icon");
+ sid.iDefaultIndex = -IDI_STEAM;
+ Skin_AddIcon(&sid);
+
+ // temporary DB settings
+ db_set_resident(m_szModuleName, "IdleTS");
+
+ SetAllContactsStatus(ID_STATUS_OFFLINE);
+
+ // 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()
+{
+ UninitQueue();
+
+ DeleteCriticalSection(&this->contact_search_lock);
+}
+
+MCONTACT __cdecl CSteamProto::AddToList(int flags, PROTOSEARCHRESULT* psr)
+{
+ MCONTACT hContact = NULL;
+ ptrA steamId(mir_u2a(psr->id));
+ if (psr->cbSize == sizeof(PROTOSEARCHRESULT))
+ {
+ if (!FindContact(steamId))
+ {
+ //hContact = AddContact(steamId, true);
+ //ForkThread(&CSteamProto::UpdateContactsThread, (void*)mir_strdup(steamId));
+
+ ptrA token(getStringA("TokenSecret"));
+
+ PushRequest(
+ new SteamWebApi::GetUserSummariesRequest(token, steamId),
+ &CSteamProto::OnGotUserSummaries);
+ }
+ }
+ else if (psr->cbSize == sizeof(STEAM_SEARCH_RESULT))
+ {
+ STEAM_SEARCH_RESULT *ssr = (STEAM_SEARCH_RESULT*)psr;
+ hContact = AddContact(steamId, true);
+ UpdateContact(hContact, ssr->data);
+ }
+
+ return hContact;
+}
+
+MCONTACT __cdecl CSteamProto::AddToListByEvent(int flags, int iContact, HANDLE hDbEvent)
+{
+ return 0;
+}
+
+int __cdecl CSteamProto::Authorize(HANDLE hDbEvent)
+{
+ if (IsOnline() && hDbEvent)
+ {
+ MCONTACT hContact = GetContactFromAuthEvent(hDbEvent);
+ if (hContact == INVALID_CONTACT_ID)
+ return 1;
+
+ //ForkThread(&CSteamProto::AuthAllowThread, (void*)hContact);
+
+ ptrA token(getStringA("TokenSecret"));
+ ptrA sessionId(getStringA("SessionID"));
+ ptrA steamId(getStringA("SteamID"));
+ char *who = getStringA(hContact, "SteamID");
+
+ PushRequest(
+ new SteamWebApi::ApprovePendingRequest(token, sessionId, steamId, who),
+ &CSteamProto::OnPendingApproved,
+ who);
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int __cdecl CSteamProto::AuthDeny(HANDLE hDbEvent, const TCHAR* szReason)
+{
+ if (IsOnline() && hDbEvent)
+ {
+ MCONTACT hContact = GetContactFromAuthEvent(hDbEvent);
+ if (hContact == INVALID_CONTACT_ID)
+ return 1;
+
+ //ForkThread(&CSteamProto::AuthDenyThread, (void*)hContact);
+
+ ptrA token(getStringA("TokenSecret"));
+ ptrA sessionId(getStringA("SessionID"));
+ ptrA steamId(getStringA("SteamID"));
+ char *who = getStringA(hContact, "SteamID");
+
+ PushRequest(
+ new SteamWebApi::IgnorePendingRequest(token, sessionId, steamId, who),
+ &CSteamProto::OnPendingIgnoreded,
+ who);
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int __cdecl CSteamProto::AuthRecv(MCONTACT hContact, PROTORECVEVENT* pre)
+{
+ return 0;
+}
+
+int __cdecl CSteamProto::AuthRequest(MCONTACT hContact, const TCHAR* szMessage)
+{
+ if (IsOnline() && hContact)
+ {
+ UINT hAuth = InterlockedIncrement(&hAuthProcess);
+
+ SendAuthParam *param = (SendAuthParam*)mir_calloc(sizeof(SendAuthParam));
+ param->hContact = hContact;
+ param->hAuth = (HANDLE)hAuth;
+
+ //ForkThread(&CSteamProto::AddContactThread, param);
+
+ ptrA token(getStringA("TokenSecret"));
+ ptrA sessionId(getStringA("SessionID"));
+ ptrA steamId(getStringA("SteamID"));
+ ptrA who(getStringA(hContact, "SteamID"));
+
+ PushRequest(
+ new SteamWebApi::AddFriendRequest(token, sessionId, steamId, who),
+ &CSteamProto::OnFriendAdded,
+ param);
+
+ return hAuth;
+ }
+
+ return 1;
+}
+
+HANDLE __cdecl CSteamProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szPath)
+{
+ return 0;
+}
+
+int __cdecl CSteamProto::FileCancel(MCONTACT hContact, HANDLE hTransfer)
+{
+ return 0;
+}
+
+int __cdecl CSteamProto::FileDeny(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szReason)
+{
+ return 0;
+}
+
+int __cdecl CSteamProto::FileResume(HANDLE hTransfer, int* action, const TCHAR** szFilename)
+{
+ return 0;
+}
+
+DWORD_PTR __cdecl CSteamProto:: GetCaps(int type, MCONTACT hContact)
+{
+ switch(type)
+ {
+ case PFLAGNUM_1:
+ return PF1_IM | PF1_BASICSEARCH | PF1_SEARCHBYNAME | PF1_AUTHREQ | PF1_SERVERCLIST | PF1_ADDSEARCHRES;
+ case PFLAGNUM_2:
+ return PF2_ONLINE | PF2_SHORTAWAY | PF2_HEAVYDND | PF2_OUTTOLUNCH;
+ case PFLAGNUM_4:
+ return PF4_AVATARS | PF4_NOCUSTOMAUTH | PF4_NOAUTHDENYREASON | PF4_FORCEAUTH | PF4_FORCEADDED | PF4_IMSENDUTF | PF4_SUPPORTIDLE;// | PF4_IMSENDOFFLINE | PF4_SUPPORTTYPING;
+ case PFLAGNUM_5:
+ return PF2_SHORTAWAY | PF2_HEAVYDND | PF2_OUTTOLUNCH;
+ case PFLAG_UNIQUEIDTEXT:
+ return (DWORD_PTR)Translate("SteamID");
+ case PFLAG_UNIQUEIDSETTING:
+ return (DWORD_PTR)"SteamID";
+ case PFLAG_MAXLENOFMESSAGE:
+ return 200000; // this is guessed limit, in reality it is probably bigger
+ default:
+ return 0;
+ }
+}
+
+int __cdecl CSteamProto::GetInfo(MCONTACT hContact, int infoType ) { return 0; }
+
+HANDLE __cdecl CSteamProto::SearchBasic(const TCHAR* id)
+{
+ if (!this->IsOnline())
+ return 0;
+
+ //ForkThread(&CSteamProto::SearchByIdThread, mir_wstrdup(id));
+
+ ptrA token(getStringA("TokenSecret"));
+ ptrA steamId(mir_u2a(id));
+
+ PushRequest(
+ new SteamWebApi::GetUserSummariesRequest(token, steamId),
+ &CSteamProto::OnSearchByIdEnded,
+ mir_wstrdup(id));
+
+ return (HANDLE)STEAM_SEARCH_BYID;
+}
+
+HANDLE __cdecl CSteamProto::SearchByEmail(const TCHAR* email)
+{
+ return 0;
+}
+
+HANDLE __cdecl CSteamProto::SearchByName(const TCHAR* nick, const TCHAR* firstName, const TCHAR* lastName)
+{
+ //if (!this->IsOnline())
+ return 0;
+
+ ptrA token(getStringA("TokenSecret"));
+
+ CMString keywords;
+ keywords.AppendFormat(L" %s", nick);
+ keywords.AppendFormat(L" %s", firstName);
+ keywords.AppendFormat(L" %s", lastName);
+ keywords.Trim();
+
+ //ForkThread(&CSteamProto::SearchByNameThread, mir_wstrdup(keywords));
+ PushRequest(
+ new SteamWebApi::SearchRequest(token, mir_utf8encodeW(keywords)),
+ &CSteamProto::OnSearchByNameStarted);
+
+ return (HANDLE)STEAM_SEARCH_BYNAME;
+}
+
+HWND __cdecl CSteamProto::SearchAdvanced( HWND owner ) { return 0; }
+
+HWND __cdecl CSteamProto::CreateExtendedSearchUI( HWND owner ){ return 0; }
+
+int __cdecl CSteamProto::RecvContacts(MCONTACT hContact, PROTORECVEVENT* pre)
+{
+ return 0;
+}
+
+int __cdecl CSteamProto::RecvFile(MCONTACT hContact, PROTORECVFILET* pre)
+{
+ return 0;
+}
+
+int __cdecl CSteamProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT* pre)
+{
+ return (INT_PTR)AddDBEvent(hContact, EVENTTYPE_MESSAGE, pre->timestamp, DBEF_UTF, lstrlenA(pre->szMessage), (BYTE*)pre->szMessage);
+}
+
+int __cdecl CSteamProto::RecvUrl(MCONTACT hContact, PROTORECVEVENT *) { return 0; }
+
+int __cdecl CSteamProto::SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList)
+{
+ return 0;
+}
+
+HANDLE __cdecl CSteamProto::SendFile(MCONTACT hContact, const TCHAR *szDescription, TCHAR **ppszFiles)
+{
+ return 0;
+}
+
+int __cdecl CSteamProto::SendMsg(MCONTACT hContact, int flags, const char *msg)
+{
+ UINT hMessage = InterlockedIncrement(&hMessageProcess);
+
+ if (flags & PREF_UNICODE)
+ msg = mir_utf8encode(msg); // FIXME: Token from FacebookRM. Is it needed? Usually we get PREF_UTF8 flag instead. And does it cause memory leak?
+
+ SendMessageParam *param = (SendMessageParam*)mir_calloc(sizeof(SendMessageParam));
+ param->hContact = hContact;
+ param->hMessage = (HANDLE)hMessage;
+
+
+ ptrA token(getStringA("TokenSecret"));
+ ptrA umqid(getStringA("UMQID"));
+ ptrA steamId(getStringA(hContact, "SteamID"));
+
+ PushRequest(
+ new SteamWebApi::SendMessageRequest(token, umqid, steamId, msg),
+ &CSteamProto::OnMessageSent,
+ param);
+
+ return hMessage;
+}
+
+int __cdecl CSteamProto::SendUrl(MCONTACT hContact, int flags, const char *url) { return 0; }
+
+int __cdecl CSteamProto::SetApparentMode(MCONTACT hContact, int mode) { return 0; }
+
+int CSteamProto::SetStatus(int new_status)
+{
+ // Routing statuses not supported by Steam
+ switch (new_status)
+ {
+ case ID_STATUS_OFFLINE:
+ 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)
+ {
+ //isTerminated = true;
+ //ForkThread(&CSteamProto::LogOutThread, NULL);
+
+ m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
+
+ StopQueue();
+
+ 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);
+
+ //ForkThread(&CSteamProto::LogInThread, NULL);
+ StartQueue();
+ }
+
+ return 0;
+}
+
+HANDLE __cdecl CSteamProto::GetAwayMsg(MCONTACT hContact) { return 0; }
+int __cdecl CSteamProto::RecvAwayMsg(MCONTACT hContact, int mode, PROTORECVEVENT *evt) { return 0; }
+int __cdecl CSteamProto::SetAwayMsg(int m_iStatus, const TCHAR *msg) { return 0; }
+
+int __cdecl CSteamProto::UserIsTyping(MCONTACT hContact, int type)
+{
+ return 0;
+}
+
+int __cdecl CSteamProto::OnEvent(PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam)
+{
+ switch (eventType)
+ {
+ case EV_PROTO_ONLOAD:
+ return this->OnModulesLoaded(wParam, lParam);
+
+ case EV_PROTO_ONEXIT:
+ return this->OnPreShutdown(wParam, lParam);
+
+ /*case EV_PROTO_ONOPTIONS:
+ return this->OnOptionsInit(wParam, lParam);*/
+
+ case EV_PROTO_ONCONTACTDELETED:
+ if (IsOnline())
+ {
+ MCONTACT hContact = (MCONTACT)wParam;
+
+ ptrA token(getStringA("TokenSecret"));
+ ptrA sessionId(getStringA("SessionID"));
+ ptrA steamId(getStringA("SteamID"));
+ ptrA who(getStringA(hContact, "SteamID"));
+
+ // Don't request delete contact from server when we're not friends anyway
+ if (getByte(hContact, "Auth", 0) != 0)
+ return 0;
+
+ PushRequest(
+ new SteamWebApi::RemoveFriendRequest(token, sessionId, steamId, who),
+ &CSteamProto::OnFriendRemoved,
+ (void*)hContact);
+ }
+ return 0;
+
+ case EV_PROTO_ONMENU:
+ this->OnInitStatusMenu();
+ break;
+ }
+
+ return 1;
} \ No newline at end of file
diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h
index cfd173c37a..82dd4f925b 100644
--- a/protocols/Steam/src/steam_proto.h
+++ b/protocols/Steam/src/steam_proto.h
@@ -1,281 +1,286 @@
-#ifndef _STEAM_PROTO_H_
-#define _STEAM_PROTO_H_
-
-#define STEAM_SEARCH_BYID 1001
-#define STEAM_SEARCH_BYNAME 1002
-
-struct GuardParam
-{
- char code[10];
- char domain[32];
-};
-
-struct CaptchaParam
-{
- BYTE *data;
- size_t size;
- char text[10];
-};
-
-struct SendAuthParam
-{
- MCONTACT hContact;
- HANDLE hAuth;
-};
-
-struct SendMessageParam
-{
- MCONTACT hContact;
- HANDLE hMessage;
-};
-
-struct STEAM_SEARCH_RESULT
-{
- PROTOSEARCHRESULT hdr;
- JSONNODE *data;
-};
-
-enum
-{
- CMI_AUTH_REQUEST,
- //CMI_AUTH_GRANT,
- //CMI_AUTH_REVOKE,
- CMI_BLOCK,
- CMI_JOIN_GAME,
- SMI_BLOCKED_LIST,
- CMI_MAX // this item shall be the last one
-};
-
-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,
- HTTP_STATUS_NOT_FOUND = 404,
- HTTP_STATUS_METHOD_NOT_ALLOWED = 405,
- HTTP_STATUS_TOO_MANY_REQUESTS = 429,
- HTTP_STATUS_SERVICE_UNAVAILABLE = 503,
- HTTP_STATUS_INSUFICIENTE_STORAGE = 507
-};
-
-typedef void (CSteamProto::*RESPONSE)(const NETLIBHTTPREQUEST *response, void *arg);
-
-struct QueueItem
-{
- SteamWebApi::HttpRequest *request;
- void *arg;
- RESPONSE responseCallback;
- RESPONSE responseFailedCallback;
-
- QueueItem(SteamWebApi::HttpRequest *request) :
- request(request), arg(NULL), responseCallback(NULL), responseFailedCallback(NULL) { }
-
- QueueItem(SteamWebApi::HttpRequest *request, RESPONSE response) :
- request(request), arg(NULL), responseCallback(response), responseFailedCallback(NULL) { }
-
- QueueItem(SteamWebApi::HttpRequest *request, RESPONSE response, RESPONSE responseFailedCallback) :
- request(request), arg(NULL), responseCallback(response), responseFailedCallback(responseFailedCallback) { }
-
- ~QueueItem() { delete request; responseCallback = NULL; }
-};
-
-class CSteamProto : public PROTO<CSteamProto>
-{
-public:
- // PROTO_INTERFACE
- CSteamProto(const char *protoName, const wchar_t *userName);
- ~CSteamProto();
-
- // PROTO_INTERFACE
- virtual MCONTACT __cdecl AddToList(int flags, PROTOSEARCHRESULT *psr);
- virtual MCONTACT __cdecl AddToListByEvent(int flags, int iContact, HANDLE hDbEvent);
-
- virtual int __cdecl Authorize(HANDLE hDbEvent);
- virtual int __cdecl AuthDeny(HANDLE hDbEvent, const TCHAR *szReason);
- virtual int __cdecl AuthRecv(MCONTACT hContact, PROTORECVEVENT *);
- virtual int __cdecl AuthRequest(MCONTACT hContact, const TCHAR * szMessage);
-
- virtual HANDLE __cdecl FileAllow(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szPath);
- virtual int __cdecl FileCancel(MCONTACT hContact, HANDLE hTransfer);
- virtual int __cdecl FileDeny(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szReason);
- virtual int __cdecl FileResume(HANDLE hTransfer, int *action, const TCHAR** szFilename);
-
- virtual DWORD_PTR __cdecl GetCaps(int type, MCONTACT hContact = NULL);
- virtual int __cdecl GetInfo(MCONTACT hContact, int infoType);
-
- virtual HANDLE __cdecl SearchBasic(const TCHAR *id);
- virtual HANDLE __cdecl SearchByEmail(const TCHAR *email);
- virtual HANDLE __cdecl SearchByName(const TCHAR *nick, const TCHAR *firstName, const TCHAR *lastName);
- virtual HWND __cdecl SearchAdvanced(HWND owner);
- virtual HWND __cdecl CreateExtendedSearchUI(HWND owner);
-
- virtual int __cdecl RecvContacts(MCONTACT hContact, PROTORECVEVENT*);
- virtual int __cdecl RecvFile(MCONTACT hContact, PROTORECVFILET*);
- virtual int __cdecl RecvMsg(MCONTACT hContact, PROTORECVEVENT*);
- virtual int __cdecl RecvUrl(MCONTACT hContact, PROTORECVEVENT*);
-
- virtual int __cdecl SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList);
- virtual HANDLE __cdecl SendFile(MCONTACT hContact, const TCHAR* szDescription, TCHAR** ppszFiles);
- virtual int __cdecl SendMsg(MCONTACT hContact, int flags, const char* msg);
- virtual int __cdecl SendUrl(MCONTACT hContact, int flags, const char* url);
-
- virtual int __cdecl SetApparentMode(MCONTACT hContact, int mode);
- virtual int __cdecl SetStatus(int iNewStatus);
-
- virtual HANDLE __cdecl GetAwayMsg(MCONTACT hContact);
- virtual int __cdecl RecvAwayMsg(MCONTACT hContact, int mode, PROTORECVEVENT* evt);
- virtual int __cdecl SetAwayMsg(int m_iStatus, const TCHAR* msg);
-
- virtual int __cdecl UserIsTyping(MCONTACT hContact, int type);
-
- virtual int __cdecl OnEvent(PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam);
-
- // instances
- static CSteamProto* InitProtoInstance(const char* protoName, const wchar_t* userName);
- static int UninitProtoInstance(CSteamProto* ppro);
-
- static CSteamProto* GetContactProtoInstance(MCONTACT hContact);
- static void UninitProtoInstances();
-
- // menus
- static void InitMenus();
- static void UninitMenus();
-
-protected:
- bool isTerminated;
- HANDLE m_evRequestsQueue, m_hQueueThread;
- HANDLE m_pollingConnection, m_hPollingThread;
- ULONG hAuthProcess;
- ULONG hMessageProcess;
- CRITICAL_SECTION contact_search_lock;
- CRITICAL_SECTION requests_queue_lock;
- LIST<QueueItem> requestsQueue;
-
- // instances
- static LIST<CSteamProto> InstanceList;
- static int CompareProtos(const CSteamProto *p1, const CSteamProto *p2);
-
- // queue
- void InitQueue();
- void UninitQueue();
-
- void StartQueue();
- void StopQueue();
-
- void PushRequest(SteamWebApi::HttpRequest *request);
- void PushRequest(SteamWebApi::HttpRequest *request, RESPONSE response);
- void PushRequest(SteamWebApi::HttpRequest *request, RESPONSE response, void *arg);
-
- void ExecuteRequest(QueueItem *requestItem);
-
- void __cdecl QueueThread(void*);
-
- // pooling thread
- void ParsePollData(JSONNODE *data);
- void __cdecl PollingThread(void*);
-
- // account
- bool IsOnline();
- bool IsMe(const char *steamId);
-
- void OnGotRsaKey(const NETLIBHTTPREQUEST *response, void *arg);
-
- void OnAuthorization(const NETLIBHTTPREQUEST *response, void *arg);
- void OnGotSession(const NETLIBHTTPREQUEST *response, void *arg);
-
- void OnLoggedOn(const NETLIBHTTPREQUEST *response, void *arg);
-
- // contacts
- void SetContactStatus(MCONTACT hContact, WORD status);
- void SetAllContactsStatus(WORD status);
-
- MCONTACT GetContactFromAuthEvent(HANDLE hEvent);
-
- void UpdateContact(MCONTACT hContact, JSONNODE *data);
- void ProcessContact(std::map<std::string, JSONNODE*>::iterator *it, MCONTACT hContact);
-
- void ContactIsRemoved(MCONTACT hContact);
- void ContactIsFriend(MCONTACT hContact);
- void ContactIsIgnored(MCONTACT hContact);
-
- MCONTACT FindContact(const char *steamId);
- MCONTACT AddContact(const char *steamId, bool isTemporary = false);
-
- void OnGotFriendList(const NETLIBHTTPREQUEST *response, void *arg);
- void OnGotBlockList(const NETLIBHTTPREQUEST *response, void *arg);
- void OnGotUserSummaries(const NETLIBHTTPREQUEST *response, void *arg);
- void OnGotAvatar(const NETLIBHTTPREQUEST *response, void *arg);
-
- void OnFriendAdded(const NETLIBHTTPREQUEST *response, void *arg);
- void OnFriendBlocked(const NETLIBHTTPREQUEST *response, void *arg);
- void OnFriendRemoved(const NETLIBHTTPREQUEST *response, void *arg);
-
- void OnAuthRequested(const NETLIBHTTPREQUEST *response, void *arg);
-
- void OnPendingApproved(const NETLIBHTTPREQUEST *response, void *arg);
- void OnPendingIgnoreded(const NETLIBHTTPREQUEST *response, void *arg);
-
- void OnSearchByIdEnded(const NETLIBHTTPREQUEST *response, void *arg);
-
- void OnSearchByNameStarted(const NETLIBHTTPREQUEST *response, void *arg);
- void OnSearchByNameFinished(const NETLIBHTTPREQUEST *response, void *arg);
-
- // messages
- void OnMessageSent(const NETLIBHTTPREQUEST *response, void *arg);
-
- // menus
- HGENMENU m_hMenuRoot;
- static HANDLE hChooserMenu;
- static HGENMENU contactMenuItems[CMI_MAX];
-
- int __cdecl AuthRequestCommand(WPARAM, LPARAM);
- int __cdecl BlockCommand(WPARAM, LPARAM);
- int __cdecl JoinToGameCommand(WPARAM, LPARAM);
-
- INT_PTR __cdecl OpenBlockListCommand(WPARAM, LPARAM);
-
- static INT_PTR MenuChooseService(WPARAM wParam, LPARAM lParam);
-
- static int PrebuildContactMenu(WPARAM wParam, LPARAM lParam);
- int OnPrebuildContactMenu(WPARAM wParam, LPARAM);
-
- void OnInitStatusMenu();
-
- // avatars
- TCHAR* GetAvatarFilePath(MCONTACT hContact);
- bool GetDbAvatarInfo(PROTO_AVATAR_INFORMATIONT &pai);
- void CheckAvatarChange(MCONTACT hContact, std::string avatarUrl);
-
- INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM);
- INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM);
- INT_PTR __cdecl GetMyAvatar(WPARAM, LPARAM);
-
- //events
- int OnModulesLoaded(WPARAM, LPARAM);
- int OnPreShutdown(WPARAM, LPARAM);
- INT_PTR __cdecl OnAccountManagerInit(WPARAM wParam, LPARAM lParam);
- static int __cdecl OnOptionsInit(void *obj, WPARAM wParam, LPARAM lParam);
-
- // utils
- static WORD SteamToMirandaStatus(int state);
- static int MirandaToSteamState(int status);
-
- static int RsaEncrypt(const char *pszModulus, const char *data, BYTE *encrypted, DWORD &encryptedSize);
-
- HANDLE AddDBEvent(MCONTACT hContact, WORD type, DWORD timestamp, DWORD flags, DWORD cbBlob, PBYTE pBlob);
-
- static void CSteamProto::ShowNotification(const wchar_t *message, int flags = 0, MCONTACT hContact = NULL);
- static void CSteamProto::ShowNotification(const wchar_t *caption, const wchar_t *message, int flags = 0, MCONTACT hContact = NULL);
-
- // dialog procs
- 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);
- static INT_PTR CALLBACK MainOptionsProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
- static LRESULT CALLBACK BlockListOptionsSubProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
- static INT_PTR CALLBACK BlockListOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
-};
-
+#ifndef _STEAM_PROTO_H_
+#define _STEAM_PROTO_H_
+
+#define STEAM_SEARCH_BYID 1001
+#define STEAM_SEARCH_BYNAME 1002
+
+struct GuardParam
+{
+ char code[10];
+ char domain[32];
+};
+
+struct CaptchaParam
+{
+ BYTE *data;
+ size_t size;
+ char text[10];
+};
+
+struct SendAuthParam
+{
+ MCONTACT hContact;
+ HANDLE hAuth;
+};
+
+struct SendMessageParam
+{
+ MCONTACT hContact;
+ HANDLE hMessage;
+};
+
+struct STEAM_SEARCH_RESULT
+{
+ PROTOSEARCHRESULT hdr;
+ JSONNODE *data;
+};
+
+enum
+{
+ CMI_AUTH_REQUEST,
+ //CMI_AUTH_GRANT,
+ //CMI_AUTH_REVOKE,
+ CMI_BLOCK,
+ CMI_JOIN_GAME,
+ SMI_BLOCKED_LIST,
+ CMI_MAX // this item shall be the last one
+};
+
+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,
+ HTTP_STATUS_NOT_FOUND = 404,
+ HTTP_STATUS_METHOD_NOT_ALLOWED = 405,
+ HTTP_STATUS_TOO_MANY_REQUESTS = 429,
+ HTTP_STATUS_SERVICE_UNAVAILABLE = 503,
+ HTTP_STATUS_INSUFICIENTE_STORAGE = 507
+};
+
+typedef void (CSteamProto::*RESPONSE)(const NETLIBHTTPREQUEST *response, void *arg);
+
+struct QueueItem
+{
+ SteamWebApi::HttpRequest *request;
+ void *arg;
+ RESPONSE responseCallback;
+ RESPONSE responseFailedCallback;
+
+ QueueItem(SteamWebApi::HttpRequest *request) :
+ request(request), arg(NULL), responseCallback(NULL), responseFailedCallback(NULL) { }
+
+ QueueItem(SteamWebApi::HttpRequest *request, RESPONSE response) :
+ request(request), arg(NULL), responseCallback(response), responseFailedCallback(NULL) { }
+
+ QueueItem(SteamWebApi::HttpRequest *request, RESPONSE response, RESPONSE responseFailedCallback) :
+ request(request), arg(NULL), responseCallback(response), responseFailedCallback(responseFailedCallback) { }
+
+ ~QueueItem() { delete request; responseCallback = NULL; }
+};
+
+class CSteamProto : public PROTO<CSteamProto>
+{
+public:
+ // PROTO_INTERFACE
+ CSteamProto(const char *protoName, const wchar_t *userName);
+ ~CSteamProto();
+
+ // PROTO_INTERFACE
+ virtual MCONTACT __cdecl AddToList(int flags, PROTOSEARCHRESULT *psr);
+ virtual MCONTACT __cdecl AddToListByEvent(int flags, int iContact, HANDLE hDbEvent);
+
+ virtual int __cdecl Authorize(HANDLE hDbEvent);
+ virtual int __cdecl AuthDeny(HANDLE hDbEvent, const TCHAR *szReason);
+ virtual int __cdecl AuthRecv(MCONTACT hContact, PROTORECVEVENT *);
+ virtual int __cdecl AuthRequest(MCONTACT hContact, const TCHAR * szMessage);
+
+ virtual HANDLE __cdecl FileAllow(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szPath);
+ virtual int __cdecl FileCancel(MCONTACT hContact, HANDLE hTransfer);
+ virtual int __cdecl FileDeny(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szReason);
+ virtual int __cdecl FileResume(HANDLE hTransfer, int *action, const TCHAR** szFilename);
+
+ virtual DWORD_PTR __cdecl GetCaps(int type, MCONTACT hContact = NULL);
+ virtual int __cdecl GetInfo(MCONTACT hContact, int infoType);
+
+ virtual HANDLE __cdecl SearchBasic(const TCHAR *id);
+ virtual HANDLE __cdecl SearchByEmail(const TCHAR *email);
+ virtual HANDLE __cdecl SearchByName(const TCHAR *nick, const TCHAR *firstName, const TCHAR *lastName);
+ virtual HWND __cdecl SearchAdvanced(HWND owner);
+ virtual HWND __cdecl CreateExtendedSearchUI(HWND owner);
+
+ virtual int __cdecl RecvContacts(MCONTACT hContact, PROTORECVEVENT*);
+ virtual int __cdecl RecvFile(MCONTACT hContact, PROTORECVFILET*);
+ virtual int __cdecl RecvMsg(MCONTACT hContact, PROTORECVEVENT*);
+ virtual int __cdecl RecvUrl(MCONTACT hContact, PROTORECVEVENT*);
+
+ virtual int __cdecl SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList);
+ virtual HANDLE __cdecl SendFile(MCONTACT hContact, const TCHAR* szDescription, TCHAR** ppszFiles);
+ virtual int __cdecl SendMsg(MCONTACT hContact, int flags, const char* msg);
+ virtual int __cdecl SendUrl(MCONTACT hContact, int flags, const char* url);
+
+ virtual int __cdecl SetApparentMode(MCONTACT hContact, int mode);
+ virtual int __cdecl SetStatus(int iNewStatus);
+
+ virtual HANDLE __cdecl GetAwayMsg(MCONTACT hContact);
+ virtual int __cdecl RecvAwayMsg(MCONTACT hContact, int mode, PROTORECVEVENT* evt);
+ virtual int __cdecl SetAwayMsg(int m_iStatus, const TCHAR* msg);
+
+ virtual int __cdecl UserIsTyping(MCONTACT hContact, int type);
+
+ virtual int __cdecl OnEvent(PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam);
+
+ // instances
+ static CSteamProto* InitProtoInstance(const char* protoName, const wchar_t* userName);
+ static int UninitProtoInstance(CSteamProto* ppro);
+
+ static CSteamProto* GetContactProtoInstance(MCONTACT hContact);
+ static void UninitProtoInstances();
+
+ // menus
+ static void InitMenus();
+ static void UninitMenus();
+
+protected:
+ bool isTerminated;
+ time_t m_idleTS;
+ HANDLE m_evRequestsQueue, m_hQueueThread;
+ HANDLE m_pollingConnection, m_hPollingThread;
+ ULONG hAuthProcess;
+ ULONG hMessageProcess;
+ CRITICAL_SECTION contact_search_lock;
+ CRITICAL_SECTION requests_queue_lock;
+ LIST<QueueItem> requestsQueue;
+
+ // instances
+ static LIST<CSteamProto> InstanceList;
+ static int CompareProtos(const CSteamProto *p1, const CSteamProto *p2);
+
+ // queue
+ void InitQueue();
+ void UninitQueue();
+
+ void StartQueue();
+ void StopQueue();
+
+ void PushRequest(SteamWebApi::HttpRequest *request);
+ void PushRequest(SteamWebApi::HttpRequest *request, RESPONSE response);
+ void PushRequest(SteamWebApi::HttpRequest *request, RESPONSE response, void *arg);
+
+ void ExecuteRequest(QueueItem *requestItem);
+
+ void __cdecl QueueThread(void*);
+
+ // pooling thread
+ void ParsePollData(JSONNODE *data);
+ void __cdecl PollingThread(void*);
+
+ // account
+ bool IsOnline();
+ bool IsMe(const char *steamId);
+
+ void OnGotRsaKey(const NETLIBHTTPREQUEST *response, void *arg);
+
+ void OnAuthorization(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnGotSession(const NETLIBHTTPREQUEST *response, void *arg);
+
+ void OnLoggedOn(const NETLIBHTTPREQUEST *response, void *arg);
+
+ // contacts
+ void SetContactStatus(MCONTACT hContact, WORD status);
+ void SetAllContactsStatus(WORD status);
+
+ MCONTACT GetContactFromAuthEvent(HANDLE hEvent);
+
+ void UpdateContact(MCONTACT hContact, JSONNODE *data);
+ void ProcessContact(std::map<std::string, JSONNODE*>::iterator *it, MCONTACT hContact);
+
+ void ContactIsRemoved(MCONTACT hContact);
+ void ContactIsFriend(MCONTACT hContact);
+ void ContactIsIgnored(MCONTACT hContact);
+
+ MCONTACT FindContact(const char *steamId);
+ MCONTACT AddContact(const char *steamId, bool isTemporary = false);
+
+ void OnGotFriendList(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnGotBlockList(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnGotUserSummaries(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnGotAvatar(const NETLIBHTTPREQUEST *response, void *arg);
+
+ void OnFriendAdded(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnFriendBlocked(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnFriendRemoved(const NETLIBHTTPREQUEST *response, void *arg);
+
+ void OnAuthRequested(const NETLIBHTTPREQUEST *response, void *arg);
+
+ void OnPendingApproved(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnPendingIgnoreded(const NETLIBHTTPREQUEST *response, void *arg);
+
+ void OnSearchByIdEnded(const NETLIBHTTPREQUEST *response, void *arg);
+
+ void OnSearchByNameStarted(const NETLIBHTTPREQUEST *response, void *arg);
+ void OnSearchByNameFinished(const NETLIBHTTPREQUEST *response, void *arg);
+
+ // messages
+ void OnMessageSent(const NETLIBHTTPREQUEST *response, void *arg);
+
+ // menus
+ HGENMENU m_hMenuRoot;
+ static HANDLE hChooserMenu;
+ static HGENMENU contactMenuItems[CMI_MAX];
+
+ int __cdecl AuthRequestCommand(WPARAM, LPARAM);
+ int __cdecl BlockCommand(WPARAM, LPARAM);
+ int __cdecl JoinToGameCommand(WPARAM, LPARAM);
+
+ INT_PTR __cdecl OpenBlockListCommand(WPARAM, LPARAM);
+
+ static INT_PTR MenuChooseService(WPARAM wParam, LPARAM lParam);
+
+ static int PrebuildContactMenu(WPARAM wParam, LPARAM lParam);
+ int OnPrebuildContactMenu(WPARAM wParam, LPARAM);
+
+ void OnInitStatusMenu();
+
+ // avatars
+ TCHAR* GetAvatarFilePath(MCONTACT hContact);
+ bool GetDbAvatarInfo(PROTO_AVATAR_INFORMATIONT &pai);
+ void CheckAvatarChange(MCONTACT hContact, std::string avatarUrl);
+
+ INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM);
+ INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM);
+ INT_PTR __cdecl GetMyAvatar(WPARAM, LPARAM);
+
+ //events
+ int OnModulesLoaded(WPARAM, LPARAM);
+ int OnPreShutdown(WPARAM, LPARAM);
+ int __cdecl OnIdleChanged(WPARAM, LPARAM);
+ INT_PTR __cdecl OnAccountManagerInit(WPARAM wParam, LPARAM lParam);
+ static int __cdecl OnOptionsInit(void *obj, WPARAM wParam, LPARAM lParam);
+
+ // utils
+ static WORD SteamToMirandaStatus(int state);
+ static int MirandaToSteamState(int status);
+
+ static int RsaEncrypt(const char *pszModulus, const char *data, BYTE *encrypted, DWORD &encryptedSize);
+
+ HANDLE AddDBEvent(MCONTACT hContact, WORD type, DWORD timestamp, DWORD flags, DWORD cbBlob, PBYTE pBlob);
+
+ static void CSteamProto::ShowNotification(const wchar_t *message, int flags = 0, MCONTACT hContact = NULL);
+ static void CSteamProto::ShowNotification(const wchar_t *caption, const wchar_t *message, int flags = 0, MCONTACT hContact = NULL);
+
+ // dialog procs
+ 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);
+ static INT_PTR CALLBACK MainOptionsProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+ static LRESULT CALLBACK BlockListOptionsSubProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+ static INT_PTR CALLBACK BlockListOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+ // helpers
+ inline int IdleSeconds() { return m_idleTS ? time(0) - m_idleTS : 0; }
+};
+
#endif //_STEAM_PROTO_H_ \ No newline at end of file