diff options
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/Steam/src/Steam/poll.h | 4 | ||||
-rw-r--r-- | protocols/Steam/src/common.h | 91 | ||||
-rw-r--r-- | protocols/Steam/src/steam_events.cpp | 166 | ||||
-rw-r--r-- | protocols/Steam/src/steam_pooling.cpp | 2 | ||||
-rw-r--r-- | protocols/Steam/src/steam_proto.cpp | 829 | ||||
-rw-r--r-- | protocols/Steam/src/steam_proto.h | 565 |
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 |