From f1b2e090d9a10b4fc6dc7326856cb5be81a1d4d8 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Sun, 30 Mar 2014 11:03:57 +0000 Subject: Steam: init commit git-svn-id: http://svn.miranda-ng.org/main/trunk@8790 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Steam/src/http_request.h | 151 +++++++++++++ protocols/Steam/src/resource.h | 36 ++++ protocols/Steam/src/stdafx.cpp | 1 + protocols/Steam/src/steam.cpp | 54 +++++ protocols/Steam/src/steam.h | 32 +++ protocols/Steam/src/steam_accounts.cpp | 45 ++++ protocols/Steam/src/steam_dialogs.cpp | 280 ++++++++++++++++++++++++ protocols/Steam/src/steam_events.cpp | 56 +++++ protocols/Steam/src/steam_proto.cpp | 382 +++++++++++++++++++++++++++++++++ protocols/Steam/src/steam_proto.h | 100 +++++++++ protocols/Steam/src/version.h | 15 ++ 11 files changed, 1152 insertions(+) create mode 100644 protocols/Steam/src/http_request.h create mode 100644 protocols/Steam/src/resource.h create mode 100644 protocols/Steam/src/stdafx.cpp create mode 100644 protocols/Steam/src/steam.cpp create mode 100644 protocols/Steam/src/steam.h create mode 100644 protocols/Steam/src/steam_accounts.cpp create mode 100644 protocols/Steam/src/steam_dialogs.cpp create mode 100644 protocols/Steam/src/steam_events.cpp create mode 100644 protocols/Steam/src/steam_proto.cpp create mode 100644 protocols/Steam/src/steam_proto.h create mode 100644 protocols/Steam/src/version.h (limited to 'protocols/Steam/src') diff --git a/protocols/Steam/src/http_request.h b/protocols/Steam/src/http_request.h new file mode 100644 index 0000000000..6d142bdc73 --- /dev/null +++ b/protocols/Steam/src/http_request.h @@ -0,0 +1,151 @@ +#ifndef _HTTP_REQUEST_H_ +#define _HTTP_REQUEST_H_ + +#include "steam.h" + +enum HTTP_STATUS +{ + HTTP_STATUS_OK = 200/*, + 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*/ +}; + +class HttpRequest : private NETLIBHTTPREQUEST//, public MZeroedObject +{ +public: + HttpRequest(HANDLE hNetlibUser, int request, LPCSTR url) + { + cbSize = sizeof(NETLIBHTTPREQUEST); + pData = NULL; + szUrl = NULL; + headers = NULL; + dataLength = 0; + headersCount = 0; + szResultDescr = NULL; + flags = NLHRF_HTTP11; + requestType = request; + + m_hNetlibUser = hNetlibUser; + m_szUrl = mir_strdup(url); + } + + ~HttpRequest() + { + if (headers != NULL) + { + for (int i = 0; i < headersCount; i++) + { + mir_free(headers[i].szName); + mir_free(headers[i].szValue); + } + mir_free(headers); + } + if (pData != NULL) + mir_free(pData); + } + + + void AddHeader(LPCSTR szName, LPCSTR szValue) + { + if (headers == NULL) + headers = (NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER)); + else + headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER) * (headersCount + 1)); + headers[headersCount].szName = mir_strdup(szName); + headers[headersCount].szValue = mir_strdup(szValue); + headersCount++; + } + + void SetData(const char *data, size_t size) + { + if (pData != NULL) + mir_free(pData); + + dataLength = size; + pData = (char*)mir_alloc(size); + memcpy(pData, data, size); + } + + /*void AddBasicAuthHeader(LPCSTR szLogin, LPCSTR szPassword) + { + char cPair[128]; + mir_snprintf( + cPair, + SIZEOF(cPair), + "%s:%s", + szLogin, + szPassword); + + char *ePair = (char *)mir_base64_encode((BYTE*)cPair, (UINT)strlen(cPair)); + + char value[128]; + mir_snprintf( + value, + SIZEOF(value), + "Basic %s", + ePair); + + mir_free(ePair); + + headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount+1)); + headers[headersCount].szName = mir_strdup("Authorization"); + headers[headersCount].szValue = mir_strdup(value); + headersCount++; + } + + void AddBearerAuthHeader(LPCSTR szValue) + { + char value[128]; + mir_snprintf( + value, + SIZEOF(value), + "Bearer %s", + szValue); + + headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount+1)); + headers[headersCount].szName = mir_strdup("Authorization"); + headers[headersCount].szValue = mir_strdup(value); + headersCount++; + }*/ + + void AddUrlPart(LPCSTR szPart) + { + m_szUrl += szPart; + } + + void AddParameter(LPCSTR szName, LPCSTR szValue) + { + if (m_szUrl.Find('?') == -1) + m_szUrl.AppendFormat("?%s=%s", szName, szValue); + else + m_szUrl.AppendFormat("&%s=%s", szName, szValue); + } + + /*void AddParameter(LPCSTR szName, int value) + { + if (m_szUrl.Find('?') == -1) + m_szUrl.AppendFormat("?%s=%i", szName, value); + else + m_szUrl.AppendFormat("&%s=%i", szName, value); + }*/ + + NETLIBHTTPREQUEST *Send() + { + szUrl = m_szUrl.GetBuffer(); + /*CMStringA message; message.AppendFormat("Send request to %s", szUrl); + CallService(MS_NETLIB_LOG, (WPARAM)m_hNetlibUser, (LPARAM)message.GetBuffer());*/ + return (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)this); + } + +private: + CMStringA m_szUrl; + HANDLE m_hNetlibUser; +}; + +#endif //_HTTP_REQUEST_H_ \ No newline at end of file diff --git a/protocols/Steam/src/resource.h b/protocols/Steam/src/resource.h new file mode 100644 index 0000000000..0d895c56fe --- /dev/null +++ b/protocols/Steam/src/resource.h @@ -0,0 +1,36 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by e:\Projects\C++\MirandaNG\protocols\Steam\res\Resource.rc +// +#define IDD_ACCMGR 9 +#define IDD_OPT_MAIN 10 +#define IDD_IGNORE_LIST 21 +#define IDD_CAPTCHA 118 +#define IDI_ICON1 119 +#define IDI_STEAM 119 +#define IDD_STEAMGUARD 119 +#define IDD_GUARD 119 +#define IDC_SN 1001 +#define IDC_PW 1002 +#define IDC_PASSWORD 1002 +#define IDC_SL 1003 +#define IDC_USERNAME 1003 +#define IDC_SAVEPASS 1004 +#define IDC_PROTOPIC 1004 +#define IDC_CAPTCHA 1004 +#define IDC_REGISTER 1018 +#define IDC_DEFAULT_GROUP 1020 +#define IDC_GROUP 1021 +#define IDC_BM_LIST 1064 +#define IDC_TEXT 1082 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 120 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1083 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/protocols/Steam/src/stdafx.cpp b/protocols/Steam/src/stdafx.cpp new file mode 100644 index 0000000000..72b5c6b7b0 --- /dev/null +++ b/protocols/Steam/src/stdafx.cpp @@ -0,0 +1 @@ +#include "steam.h" diff --git a/protocols/Steam/src/steam.cpp b/protocols/Steam/src/steam.cpp new file mode 100644 index 0000000000..b052681433 --- /dev/null +++ b/protocols/Steam/src/steam.cpp @@ -0,0 +1,54 @@ +#include "steam.h" + +int hLangpack; +HINSTANCE g_hInstance; + +PLUGININFOEX pluginInfo = +{ + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESCRIPTION, + __AUTHOR, + __AUTHOREMAIL, + __COPYRIGHT, + __AUTHORWEB, + UNICODE_AWARE, + // {68F5A030-BA32-48EC-9507-5C2FBDEA5217} + { 0x68f5a030, 0xba32, 0x48ec, { 0x95, 0x7, 0x5c, 0x2f, 0xbd, 0xea, 0x52, 0x17 }} +}; + +DWORD WINAPI DllMain(HINSTANCE hInstance, DWORD, LPVOID) +{ + g_hInstance = hInstance; + + return TRUE; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_PROTOCOL, MIID_LAST}; + +extern "C" int __declspec(dllexport) Load(void) +{ + mir_getLP(&pluginInfo); + + PROTOCOLDESCRIPTOR pd = { sizeof(pd) }; + pd.szName = "STEAM"; + pd.type = PROTOTYPE_PROTOCOL; + pd.fnInit = (pfnInitProto)CSteamProto::InitAccount; + pd.fnUninit = (pfnUninitProto)CSteamProto::UninitAccount; + CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); + + return 0; +} + +extern "C" int __declspec(dllexport) Unload(void) +{ + CSteamProto::UninitAccounts(); + + return 0; +} \ No newline at end of file diff --git a/protocols/Steam/src/steam.h b/protocols/Steam/src/steam.h new file mode 100644 index 0000000000..796689f4df --- /dev/null +++ b/protocols/Steam/src/steam.h @@ -0,0 +1,32 @@ +#ifndef _STEAM_H_ +#define _STEAM_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "resource.h" +#include "version.h" + +#define MODULE "Steam" + +class CSteamProto; +extern HINSTANCE g_hInstance; + +#include "steam_proto.h" + +#endif //_STEAM_H_ \ No newline at end of file diff --git a/protocols/Steam/src/steam_accounts.cpp b/protocols/Steam/src/steam_accounts.cpp new file mode 100644 index 0000000000..7c77af01c7 --- /dev/null +++ b/protocols/Steam/src/steam_accounts.cpp @@ -0,0 +1,45 @@ +#include "steam.h" + +int CSteamProto::CompareProtos(const CSteamProto *p1, const CSteamProto *p2) +{ + return lstrcmp(p1->m_tszUserName, p2->m_tszUserName); +} + +LIST CSteamProto::InstanceList(1, CSteamProto::CompareProtos); + +CSteamProto* CSteamProto::InitAccount(const char* protoName, const wchar_t* userName) +{ + CSteamProto *ppro = new CSteamProto(protoName, userName); + InstanceList.insert(ppro); + + return ppro; +} + +int CSteamProto::UninitAccount(CSteamProto* ppro) +{ + InstanceList.remove(ppro); + delete ppro; + + return 0; +} + +void CSteamProto::UninitAccounts() +{ + for (int i = InstanceList.getCount(); i > 0; i--) + UninitAccount(InstanceList[i]); + InstanceList.destroy(); +} + +CSteamProto* CSteamProto::GetContactAccount(MCONTACT hContact) +{ + char *proto = (char *)::CallService(MS_PROTO_GETCONTACTBASEPROTO, hContact, 0); + + if (proto == NULL) + return NULL; + + for (int i = 0; i < InstanceList.getCount(); i++) + if (!strcmp(proto, InstanceList[i]->m_szModuleName)) + return InstanceList[i]; + + return NULL; +} \ No newline at end of file diff --git a/protocols/Steam/src/steam_dialogs.cpp b/protocols/Steam/src/steam_dialogs.cpp new file mode 100644 index 0000000000..5c2ad45743 --- /dev/null +++ b/protocols/Steam/src/steam_dialogs.cpp @@ -0,0 +1,280 @@ +#include "steam.h" +//#include +//#pragma comment(lib, "GdiPlus.lib") + +INT_PTR CALLBACK CSteamProto::GuardProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + //HDC hdc; + //HBITMAP hBitmap, cBitmap; + GuardParam *guard = (GuardParam*)GetWindowLongPtr(hwnd, GWLP_USERDATA); + + switch (message) + { + case WM_INITDIALOG: + TranslateDialogDefault(hwnd); + { + guard = (GuardParam*)lParam; + SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); + } + return TRUE; + + case WM_CLOSE: + EndDialog(hwnd, 0); + break; + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDOK: + GetDlgItemTextA(hwnd, IDC_TEXT, guard->code, sizeof(guard->code)); + EndDialog(hwnd, IDOK); + break; + + case IDCANCEL: + EndDialog(hwnd, IDCANCEL); + break; + } + } + break; + } + + return FALSE; +} + +INT_PTR CALLBACK CSteamProto::CaptchaProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + //HDC hdc; + //HBITMAP hBitmap, cBitmap; + CaptchaParam *captcha = (CaptchaParam*)GetWindowLongPtr(hwnd, GWLP_USERDATA); + + switch (message) + { + case WM_INITDIALOG: + TranslateDialogDefault(hwnd); + { + captcha = (CaptchaParam*)lParam; + SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); + + //HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, captcha->size); + //LPVOID pImage = GlobalLock(hMem); + //memcpy(pImage, captcha->data, captcha->size); + //GlobalUnlock(hMem); + + //IStream* pStream = NULL; + //if (CreateStreamOnHGlobal(hMem, FALSE, &pStream) == S_OK) + //{ + // HANDLE hBmp = CreateBitmap(260, 40, 1, 24, captcha->data); + // //Gdiplus::Bitmap *pBitmap = Gdiplus::Bitmap::FromStream(pStream); + // SendDlgItemMessage(hwnd, IDC_CAPTCHA, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)pBitmap); + // delete pBitmap; + // pStream->Release(); + //} + + //HANDLE hBmp = CreateBitmap(260, 40, 1, 24, captcha->data); + + /*tagBITMAPFILEHEADER bfh = *(tagBITMAPFILEHEADER*)captcha->data; + tagBITMAPINFOHEADER bih = *(tagBITMAPINFOHEADER*)(captcha->data + sizeof(tagBITMAPFILEHEADER)); + RGBQUAD rgb = *(RGBQUAD*)(captcha->data + sizeof(tagBITMAPFILEHEADER) + sizeof(tagBITMAPINFOHEADER)); + + BITMAPINFO bi; + bi.bmiColors[0] = rgb; + bi.bmiHeader = bih; + + char* pPixels = ((char*)captcha->data + bfh.bfOffBits); + + char* ppvBits; + hBitmap = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void**)&ppvBits, NULL, 0); + SetDIBits(NULL, hBitmap, 0, bih.biHeight, pPixels, &bi, DIB_RGB_COLORS); + GetObject(hBitmap, sizeof(BITMAP), &cBitmap);*/ + } + return TRUE; + + case WM_CLOSE: + EndDialog(hwnd, 0); + break; + + //case WM_PAINT: + // { + // PAINTSTRUCT ps; + // HDC hdc = BeginPaint(hwnd, &ps); + // HBITMAP hBitmap = CreateBitmap(260, 40, 1, 24, captcha->data); + // if(hBitmap != 0) + // { + // HDC hdcMem = CreateCompatibleDC(hdc); + // SelectObject(hdcMem, hBitmap); + // BitBlt(hdc, 10, 10, 260, 40, hdcMem, 0, 0, SRCCOPY); + // DeleteDC(hdcMem); + // } + // EndPaint(hwnd, &ps); + // } + // return 0; + + //case WM_DRAWITEM: + // { + // LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lParam; + + // if (dis->CtlType == ODT_BUTTON && dis->CtlID == IDC_CAPTCHA) + // { + // FI_INTERFACE *fei = 0; + + // FIBITMAP *fb = fei->FI_CreateDIBFromHBITMAP(hbm); + // FIBITMAP *fbResized = fei->FI_Rescale(fb, newWidth, newHeight, FILTER_BICUBIC); + // HBITMAP hbmResized = fei->FI_CreateHBITMAPFromDIB(fbResized); + // fei->FI_Unload(fb); + // fei->FI_Unload(fbResized); + + // HBITMAP hbmTempOld; + // HDC hdcTemp = CreateCompatibleDC(r->hTargetDC); + // hbmTempOld = (HBITMAP)SelectObject(hdcTemp, hbmResized); + + // GdiAlphaBlend( + // r->hTargetDC, r->rcDraw.left + leftoffset, r->rcDraw.top + topoffset, newWidth, newHeight, + // hdcTemp, 0, 0, newWidth, newHeight, bf); + + // SelectObject(hdcTemp, hbmTempOld); + // DeleteObject(hbmResized); + // DeleteDC(hdcTemp); + + // /*AVATARDRAWREQUEST avdrq = {0}; + // avdrq.cbSize = sizeof(avdrq); + // avdrq.hTargetDC = dis->hDC; + // avdrq.dwFlags |= AVDRQ_PROTOPICT; + // avdrq.szProto = g_selectedProto; + // GetClientRect(GetDlgItem(hwndDlg, IDC_PROTOPIC), &avdrq.rcDraw); + // CallService(MS_AV_DRAWAVATAR, 0, (LPARAM)&avdrq);*/ + // } + // return TRUE; + // } + + //case WM_PAINT: + // { + // PAINTSTRUCT ps; + // HDC hdc = BeginPaint(hwnd, &ps); + // //260x40 + // Image image(L"Image.png"); + // // Draw the original source image. + // Graphics graphics(hdc); + // graphics.DrawImage(&image, 10, 10); + // EndPaint(hwnd, &ps); + // } + // return 0; + + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case IDOK: + GetDlgItemTextA(hwnd, IDC_TEXT, captcha->text, sizeof(captcha->text)); + EndDialog(hwnd, IDOK); + break; + + case IDCANCEL: + EndDialog(hwnd, IDCANCEL); + break; + } + } + break; + } + + return FALSE; +} + +INT_PTR CALLBACK CSteamProto::MainOptionsProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + CSteamProto *proto = (CSteamProto*)GetWindowLongPtr(hwnd, GWLP_USERDATA); + + switch (message) + { + case WM_INITDIALOG: + TranslateDialogDefault(hwnd); + { + proto = (CSteamProto*)lParam; + SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); + + ptrA username(proto->getStringA("Username")); + SetDlgItemTextA(hwnd, IDC_USERNAME, username); + + ptrA password(proto->getStringA("Password")); + SetDlgItemTextA(hwnd, IDC_PASSWORD, password); + + /*if (proto->IsOnline()) + EnableWindow(GetDlgItem(hwnd, IDC_GROUP), FALSE); + + SendDlgItemMessage(hwnd, IDC_GROUP, EM_LIMITTEXT, SKYPE_GROUP_NAME_LIMIT, 0); + + ptrW defgroup( db_get_wsa(NULL, proto->m_szModuleName, SKYPE_SETTINGS_DEF_GROUP)); + SetDlgItemText(hwnd, IDC_GROUP, defgroup);*/ + } + return TRUE; + + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case IDC_USERNAME: + { + if ((HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus())) return 0; + + //if (/*!proto->IsOnline() && */db_get_w(NULL, proto->m_szModuleName, "Status", ID_STATUS_OFFLINE) <= ID_STATUS_OFFLINE) + /*{ + char username[128]; + GetDlgItemTextA(hwnd, IDC_USERNAME, username, SIZEOF(username)); + }*/ + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); + } + break; + + case IDC_PASSWORD: + { + if ((HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus())) return 0; + //if (proto->IsOnline()) + /*{ + char password[128]; + GetDlgItemTextA(hwnd, IDC_PASSWORD, password, SIZEOF(password)); + }*/ + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); + } + break; + + /*case IDC_GROUP: + { + if ((HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus())) + return 0; + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); + } + break;*/ + } + } + break; + + case WM_NOTIFY: + if (reinterpret_cast(lParam)->code == PSN_APPLY/* && !proto->IsOnline()*/) + { + char username[128]; + GetDlgItemTextA(hwnd, IDC_SL, username, SIZEOF(username)); + proto->setString("Username", username); + /*mir_free(proto->login); + proto->login = ::mir_wstrdup(sid);*/ + + char password[128]; + GetDlgItemTextA(hwnd, IDC_PW, password, SIZEOF(password)); + db_set_s(NULL, proto->m_szModuleName, "Password", password); + + /*wchar_t tstr[128]; + GetDlgItemText(hwnd, IDC_GROUP, tstr, SIZEOF(tstr)); + if (lstrlen(tstr) > 0) + { + ::db_set_ts(NULL, proto->m_szModuleName, SKYPE_SETTINGS_DEF_GROUP, tstr); + ::Clist_CreateGroup(0, tstr); + } + else + ::db_unset(NULL, proto->m_szModuleName, SKYPE_SETTINGS_DEF_GROUP);*/ + + return TRUE; + } + break; + } + + return FALSE; +} \ No newline at end of file diff --git a/protocols/Steam/src/steam_events.cpp b/protocols/Steam/src/steam_events.cpp new file mode 100644 index 0000000000..dd78bd2acd --- /dev/null +++ b/protocols/Steam/src/steam_events.cpp @@ -0,0 +1,56 @@ +#include "steam.h" + +int CSteamProto::OnModulesLoaded(WPARAM, LPARAM) +{ + 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); + + return 0; +} + +int CSteamProto::OnPreShutdown(WPARAM, LPARAM) +{ + //SetStatus(ID_STATUS_OFFLINE); + + Netlib_CloseHandle(this->m_hNetlibUser); + this->m_hNetlibUser = NULL; + + return 0; +} + +INT_PTR __cdecl CSteamProto::OnAccountManagerInit(WPARAM wParam, LPARAM lParam) +{ + return (int)CreateDialogParam( + g_hInstance, + MAKEINTRESOURCE(IDD_ACCMGR), + (HWND)lParam, + CSteamProto::MainOptionsProc, + (LPARAM)this); +} + +int __cdecl CSteamProto::OnOptionsInit(WPARAM wParam, LPARAM lParam) +{ + char *title = mir_t2a(this->m_tszUserName); + + OPTIONSDIALOGPAGE odp = { sizeof(odp) }; + odp.hInstance = g_hInstance; + odp.pszTitle = title; + odp.dwInitParam = LPARAM(this); + 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); + + mir_free(title); + + return 0; +} \ No newline at end of file diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp new file mode 100644 index 0000000000..acaacde37e --- /dev/null +++ b/protocols/Steam/src/steam_proto.cpp @@ -0,0 +1,382 @@ +#include "steam.h" + +CSteamProto::CSteamProto(const char* protoName, const TCHAR* userName) : + PROTO(protoName, userName) +{ + CreateProtoService(PS_CREATEACCMGRUI, &CSteamProto::OnAccountManagerInit); +} + +CSteamProto::~CSteamProto() +{ +} + +MCONTACT __cdecl CSteamProto::AddToList(int flags, PROTOSEARCHRESULT* psr) +{ + return 0; +} + +MCONTACT __cdecl CSteamProto::AddToListByEvent(int flags, int iContact, HANDLE hDbEvent) +{ + return 0; +} + +int __cdecl CSteamProto::Authorize(HANDLE hDbEvent) +{ + return 0; +} + +int __cdecl CSteamProto::AuthDeny(HANDLE hDbEvent, const TCHAR* szReason) +{ + return 0; +} + +int __cdecl CSteamProto::AuthRecv(MCONTACT hContact, PROTORECVEVENT* pre) +{ + return 0; +} + +int __cdecl CSteamProto::AuthRequest(MCONTACT hContact, const TCHAR* szMessage) +{ + return 0; +} + +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; + case PFLAGNUM_2: + return PF2_ONLINE; + case PFLAG_UNIQUEIDTEXT: + return (DWORD_PTR)::Translate("Username"); + case PFLAG_UNIQUEIDSETTING: + return (DWORD_PTR)"Username"; + default: + return 0; + } +} + +int __cdecl CSteamProto::GetInfo(MCONTACT hContact, int infoType ) { return 0; } + +HANDLE __cdecl CSteamProto::SearchBasic(const TCHAR* id) +{ + return 0; +} + +HANDLE __cdecl CSteamProto::SearchByEmail(const TCHAR* email) +{ + return 0; +} + +HANDLE __cdecl CSteamProto::SearchByName(const TCHAR* nick, const TCHAR* firstName, const TCHAR* lastName) +{ + return 0; +} + +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 0; +} + +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) +{ + return 0; +} + +int __cdecl CSteamProto::SendUrl(MCONTACT hContact, int flags, const char *url) { return 0; } + +int __cdecl CSteamProto::SetApparentMode(MCONTACT hContact, int mode) { return 0; } + +NETLIBHTTPREQUEST *CSteamProto::LoginRequest(const char *username, const char *password, const char *timestamp, const char *captchagid, const char *captcha_text, const char *emailauth, const char *emailsteamid) +{ + HttpRequest request = HttpRequest(m_hNetlibUser, REQUEST_POST, "https://steamcommunity.com/login/dologin/"); + request.AddHeader("Content-Type", "application/x-www-form-urlencoded"); + request.AddHeader("Accept-Encoding", "deflate, gzip"); + + CMStringA param; + param.AppendFormat("username=%s", mir_urlEncode(username)); + param.AppendFormat("&password=%s", mir_urlEncode(password)); + param.AppendFormat("&captchagid=%s", captchagid); + param.AppendFormat("&captcha_text=%s", mir_urlEncode(captcha_text)); + param.AppendFormat("&emailauth=%s", mir_urlEncode(emailauth)); + param.AppendFormat("&emailsteamid=%s", emailsteamid); + param.AppendFormat("&rsatimestamp=%s", timestamp); + + request.SetData(param.GetBuffer(), param.GetLength()); + + return request.Send(); +} + +#include +#include +#include +#include +#include +#include + +bool CSteamProto::Login() +{ + ptrA username(getStringA("Username")); + + HttpRequest request(m_hNetlibUser, REQUEST_GET, "https://steamcommunity.com/login/getrsakey"); + request.AddParameter("username", username); + + mir_ptr response(request.Send()); + + if (!response || response->resultCode != HTTP_STATUS_OK) + return false; + + JSONNODE *root = json_parse(response->pData), *node; + if (!root) + return false; + + node = json_get(root, "success"); + if (!json_as_bool(node)) + return false; + + node = json_get(root, "timestamp"); + ptrA timestamp = ptrA(mir_t2a(json_as_string(node))); + + node = json_get(root, "publickey_mod"); + const char *mod = mir_t2a(json_as_string(node)); + + node = json_get(root, "publickey_exp"); + const char *exp = mir_t2a(json_as_string(node)); + + const char *password = getStringA("Password"); + + BIGNUM *modulus = BN_new(); + if (!BN_hex2bn(&modulus, mod)) + return false; + + BIGNUM *exponent = BN_new(); + if (!BN_hex2bn(&exponent, exp)) + return false; + + RSA *rsa = RSA_new(); + rsa->n = modulus; + rsa->e = exponent; + + int size = RSA_size(rsa); + BYTE *ePassword = (BYTE*)mir_calloc(size); + if (RSA_public_encrypt((int)strlen(password), (const unsigned char*)password, ePassword, rsa, RSA_PKCS1_PADDING) < 0) + return false; + + char *sPassword = mir_base64_encode(ePassword, size); + + bool captcha_needed, emailauth_needed; + CMStringA captchagid("-1"), captcha_text, emailauth, emailsteamid; + do + { + response = Authorize(username, sPassword, timestamp, captchagid.GetBuffer(), captcha_text.GetBuffer(), emailauth.GetBuffer(), emailsteamid.GetBuffer()); + if (!response || response->resultCode != HTTP_STATUS_OK) + return false; + + root = json_parse(response->pData); + + node = json_get(root, "emailauth_needed"); + emailauth_needed = json_as_bool(node); + if (emailauth_needed) + { + GuardParam guard; + + node = json_get(root, "emailsteamid"); + emailsteamid = ptrA(mir_t2a(json_as_string(node))); + + node = json_get(root, "emaildomain"); + strcpy(guard.domain, mir_u2a(json_as_string(node))); + + if (DialogBoxParam( + g_hInstance, + MAKEINTRESOURCE(IDD_GUARD), + NULL, + CSteamProto::GuardProc, + (LPARAM)&guard) != 1) + return false; + + emailauth = guard.code; + } + + node = json_get(root, "captcha_needed"); + captcha_needed = json_as_bool(node); + if (captcha_needed) + { + node = json_get(root, "captcha_gid"); + captchagid = ptrA(mir_t2a(json_as_string(node))); + + CMStringA url = CMStringA("https://steamcommunity.com/public/captcha.php?gid=") + captchagid; + CallService(MS_UTILS_OPENURL, 0, (LPARAM)url.GetBuffer()); + + //request = HttpRequest(m_hNetlibUser, REQUEST_GET, "https://steamcommunity.com/public/captcha.php?gid="); + //request.AddUrlPart(gid); + + //response = request.Send(); + + //if (!response || response->resultCode != HTTP_STATUS_OK) + // return false; + + CaptchaParam captcha; + captcha.size = response->dataLength; + captcha.data = (BYTE*)mir_alloc(response->dataLength); + memcpy(captcha.data, response->pData, captcha.size); + + if (DialogBoxParam( + g_hInstance, + MAKEINTRESOURCE(IDD_CAPTCHA), + NULL, + CSteamProto::CaptchaProc, + (LPARAM)&captcha) != 1) + return false; + + captcha_text = captcha.text; + } + + node = json_get(root, "success"); + if (!json_as_bool(node) && !emailauth_needed && !captcha_needed) + return false; + + } while (emailauth_needed || captcha_needed); + + node = json_get(root, "success"); + if (!json_as_bool(node)) + return false; + + // {"success":true, "login_complete" : true, "transfer_url" : "https:\/\/store.steampowered.com\/\/login\/transfer", "transfer_parameters" : {"steamid":"*", "token" : "*", "remember_login" : false, "webcookie" : "*"}} + + return true; +} + +bool CSteamProto::Logout() +{ + return true; +} + +int CSteamProto::SetStatus(int new_status) +{ + if (new_status == m_iDesiredStatus) + return 0; + + int old_status = m_iStatus; + m_iDesiredStatus = new_status; + + if (new_status == ID_STATUS_OFFLINE) + { + Logout(); + m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; + + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); + + if (!Miranda_Terminated()) + { + /*this->SetAllContactStatus(ID_STATUS_OFFLINE); + this->CloseAllChatSessions();*/ + } + + return 0; + } + else + { + if (old_status == ID_STATUS_OFFLINE/* && !this->IsOnline()*/) + { + this->m_iStatus = ID_STATUS_CONNECTING; + /*if (!Login()) + return 0;*/ + } + else + { + /*if ( this->account->IsOnline()) + { + SetServerStatus(new_status); + return 0; + }*/ + + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); + + return 0; + } + } + + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); + + 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: + return this->OnContactDeleted(wParam, lParam);*/ + + /*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 new file mode 100644 index 0000000000..623dc4296c --- /dev/null +++ b/protocols/Steam/src/steam_proto.h @@ -0,0 +1,100 @@ +#ifndef _STEAM_PROTO_H_ +#define _STEAM_PROTO_H_ + +#include "http_request.h" + +struct CaptchaParam +{ + BYTE *data; + size_t size; + char text[10]; +}; + +struct GuardParam +{ + char domain[32]; + char code[10]; +}; + +class CSteamProto : public PROTO +{ +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 ); + + // accounts + static CSteamProto* InitAccount(const char* protoName, const wchar_t* userName); + static int UninitAccount(CSteamProto* ppro); + + static CSteamProto* GetContactAccount(MCONTACT hContact); + static void UninitAccounts(); + +protected: + + NETLIBHTTPREQUEST *LoginRequest(const char *username, const char *password, const char *timestamp, const char *captchagid, const char *captcha_text, const char *emailauth, const char *emailsteamid); + + bool Login(); + bool Logout(); + + // accounts + static LIST InstanceList; + static int CompareProtos(const CSteamProto *p1, const CSteamProto *p2); + + //events + int OnModulesLoaded(WPARAM, LPARAM); + int OnPreShutdown(WPARAM, LPARAM); + INT_PTR __cdecl OnAccountManagerInit(WPARAM wParam, LPARAM lParam); + int __cdecl OnOptionsInit(WPARAM wParam, LPARAM lParam); + + //options + static INT_PTR CALLBACK GuardProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK CaptchaProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK MainOptionsProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +}; + +#endif //_STEAM_PROTO_H_ \ No newline at end of file diff --git a/protocols/Steam/src/version.h b/protocols/Steam/src/version.h new file mode 100644 index 0000000000..2b784aded8 --- /dev/null +++ b/protocols/Steam/src/version.h @@ -0,0 +1,15 @@ +#define __MAJOR_VERSION 0 +#define __MINOR_VERSION 11 +#define __RELEASE_NUM 0 +#define __BUILD_NUM 1 + +#include + +#define __PLUGIN_NAME "Steam Protocol" +#define __INTERNAL_NAME "Steam" +#define __FILENAME "steam.dll" +#define __DESCRIPTION "Steam protocol support for Miranda NG." +#define __AUTHOR "unsane" +#define __AUTHOREMAIL "" +#define __AUTHORWEB "http://miranda-ng.org/p/Steam/" +#define __COPYRIGHT "© 2014 Miranda NG team" -- cgit v1.2.3