From 82c5b215999c29361f26107e67a08a5ec7c64872 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 18 Jun 2023 12:21:15 +0300 Subject: Steam: "Device name" option --- protocols/Steam/Steam.vcxproj | 3 + protocols/Steam/res/Resource.rc | 52 ++++++++-------- protocols/Steam/src/resource.h | 9 +-- protocols/Steam/src/steam_contacts.cpp | 4 +- protocols/Steam/src/steam_crypt.cpp | 108 ++++----------------------------- protocols/Steam/src/steam_events.cpp | 2 - protocols/Steam/src/steam_login.cpp | 43 ++++--------- protocols/Steam/src/steam_options.cpp | 23 ++----- protocols/Steam/src/steam_proto.cpp | 9 +-- protocols/Steam/src/steam_proto.h | 13 ++-- 10 files changed, 80 insertions(+), 186 deletions(-) (limited to 'protocols') diff --git a/protocols/Steam/Steam.vcxproj b/protocols/Steam/Steam.vcxproj index 2c472d4fcc..1389d5d489 100644 --- a/protocols/Steam/Steam.vcxproj +++ b/protocols/Steam/Steam.vcxproj @@ -105,5 +105,8 @@ stdcpp17 .;%(AdditionalIncludeDirectories) + + libcrypto.lib;libssl.lib;%(AdditionalDependencies) + \ No newline at end of file diff --git a/protocols/Steam/res/Resource.rc b/protocols/Steam/res/Resource.rc index d6497a4807..290efb395f 100644 --- a/protocols/Steam/res/Resource.rc +++ b/protocols/Steam/res/Resource.rc @@ -63,6 +63,7 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_STEAM ICON "steam.ico" + IDI_GAMING ICON "gaming.ico" #endif // Russian (Russia) resources @@ -70,7 +71,7 @@ IDI_GAMING ICON "gaming.ico" ///////////////////////////////////////////////////////////////////////////// -// English resources +// English (Neutral) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL @@ -86,12 +87,14 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - LTEXT "Username:",IDC_STATIC,7,8,49,12 + LTEXT "Username",IDC_STATIC,7,8,49,12 EDITTEXT IDC_USERNAME,60,7,121,12,ES_AUTOHSCROLL - LTEXT "Password:",IDC_STATIC,7,24,49,12 + LTEXT "Password",IDC_STATIC,7,24,49,12 EDITTEXT IDC_PASSWORD,60,23,121,12,ES_PASSWORD | ES_AUTOHSCROLL + LTEXT "Default group",IDC_STATIC,7,40,49,8 EDITTEXT IDC_GROUP,60,39,121,14,ES_AUTOHSCROLL - LTEXT "Default group:",IDC_STATIC,7,40,49,8 + LTEXT "Device name",IDC_STATIC,7,59,49,8 + EDITTEXT IDC_DEVICE_NAME,60,57,121,14,ES_AUTOHSCROLL END IDD_OPT_MAIN DIALOGEX 0, 0, 305, 230 @@ -99,22 +102,24 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - GROUPBOX "Account",IDC_STATIC,7,7,291,44 - LTEXT "Username:",IDC_STATIC,15,19,81,8 + GROUPBOX "Account",IDC_STATIC,7,7,291,64 + LTEXT "Username:",IDC_STATIC,15,20,81,8 EDITTEXT IDC_USERNAME,102,17,189,13,ES_AUTOHSCROLL - LTEXT "Password:",IDC_STATIC,15,35,81,8 + LTEXT "Password:",IDC_STATIC,15,36,81,8 EDITTEXT IDC_PASSWORD,102,33,189,13,ES_PASSWORD | ES_AUTOHSCROLL - GROUPBOX "Contacts",IDC_STATIC,7,57,291,50 - LTEXT "Default group:",IDC_STATIC,15,71,81,8 - EDITTEXT IDC_GROUP,102,69,189,14,ES_AUTOHSCROLL - CONTROL "Use bigger avatars",IDC_BIGGER_AVATARS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,90,271,10 - GROUPBOX "Message sessions",IDC_STATIC,7,115,291,32 + LTEXT "Device name",IDC_STATIC,15,53,81,8 + EDITTEXT IDC_DEVICE_NAME,102,50,189,13,ES_PASSWORD | ES_AUTOHSCROLL + GROUPBOX "Contacts",IDC_STATIC,7,74,291,50 + LTEXT "Default group:",IDC_STATIC,15,89,81,8 + EDITTEXT IDC_GROUP,102,86,189,14,ES_AUTOHSCROLL + CONTROL "Use bigger avatars",IDC_BIGGER_AVATARS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,107,271,10 + GROUPBOX "Message sessions",IDC_STATIC,7,127,291,32 CONTROL "Show chat state events (i.e., user closed chat session)",IDC_SHOW_CHAT_EVENTS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,129,271,10 - GROUPBOX "Connection",IDC_STATIC,7,155,291,68 - LTEXT "Error limit before logout:",IDC_STATIC,15,167,81,8 - EDITTEXT IDC_POLLINGERRORLIMIT,102,166,60,14,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_POLLINGERRORLIMITSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,152,166,10,14 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,141,271,10 + GROUPBOX "Connection",IDC_STATIC,7,162,291,53 + LTEXT "Error limit before logout:",IDC_STATIC,15,179,81,8 + EDITTEXT IDC_POLLINGERRORLIMIT,102,177,60,14,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_POLLINGERRORLIMITSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,152,176,10,14 END IDD_CAPTCHA DIALOGEX 0, 0, 143, 81 @@ -198,12 +203,6 @@ BEGIN IDD_OPT_MAIN, DIALOG BEGIN LEFTMARGIN, 7 - VERTGUIDE, 15 - VERTGUIDE, 96 - VERTGUIDE, 102 - VERTGUIDE, 162 - VERTGUIDE, 291 - VERTGUIDE, 298 TOPMARGIN, 7 BOTTOMMARGIN, 223 END @@ -277,7 +276,12 @@ BEGIN 0 END -#endif // English resources +IDD_ACCMGR AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +#endif // English (Neutral) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/protocols/Steam/src/resource.h b/protocols/Steam/src/resource.h index db1260e482..639b4f013f 100644 --- a/protocols/Steam/src/resource.h +++ b/protocols/Steam/src/resource.h @@ -1,6 +1,6 @@ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. -// Used by D:\Projects\c++\miranda-ng\protocols\Steam\res\Resource.rc +// Used by W:\miranda-ng\protocols\Steam\res\Resource.rc // #define IDD_ACCMGR 9 #define IDD_OPT_MAIN 10 @@ -20,8 +20,9 @@ #define IDC_SL 1003 #define IDC_USERNAME 1003 #define IDC_SAVEPASS 1004 -#define IDC_PROTOPIC 1004 -#define IDC_CAPTCHA 1004 +#define IDC_PROTOPIC 1005 +#define IDC_CAPTCHA 1006 +#define IDC_DEVICE_NAME 1007 #define IDC_REGISTER 1018 #define IDC_DEFAULT_GROUP 1020 #define IDC_GROUP 1021 @@ -41,7 +42,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 126 +#define _APS_NEXT_RESOURCE_VALUE 127 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1087 #define _APS_NEXT_SYMED_VALUE 101 diff --git a/protocols/Steam/src/steam_contacts.cpp b/protocols/Steam/src/steam_contacts.cpp index 378ab1933d..7f7979e825 100644 --- a/protocols/Steam/src/steam_contacts.cpp +++ b/protocols/Steam/src/steam_contacts.cpp @@ -346,7 +346,9 @@ MCONTACT CSteamProto::AddContact(const char *steamId, const wchar_t *nick, bool setByte(hContact, "Auth", 1); // move to default group - Clist_SetGroup(hContact, m_defaultGroup); + if (!Clist_GroupExists(m_wszGroupName)) + Clist_GroupCreate(0, m_wszGroupName); + Clist_SetGroup(hContact, m_wszGroupName); return hContact; } diff --git a/protocols/Steam/src/steam_crypt.cpp b/protocols/Steam/src/steam_crypt.cpp index 042e979cc5..e89dd46a34 100644 --- a/protocols/Steam/src/steam_crypt.cpp +++ b/protocols/Steam/src/steam_crypt.cpp @@ -1,104 +1,22 @@ #include "stdafx.h" -#pragma comment(lib, "crypt32.lib") +#include -int CSteamProto::RsaEncrypt(const char *pszModulus, DWORD &exponent, const char *data, uint8_t *encryptedData, DWORD &encryptedSize) +MBinBuffer RsaEncrypt(const char *pszModulus, const char *exponent, const char *data) { - uint32_t cchModulus = (uint32_t)mir_strlen(pszModulus); - int result; - HCRYPTKEY phKey = 0; - HCRYPTPROV hCSP = 0; + //pszModulus = "cb23284f3078f97f9667624b4f882cd7d68aefd6b22f136b5808dfc3ae19d6df7f278d71049a4d61d2bedb4fe958e84140e3ba261b80cf29b37d2aca3ab456cf26fbeca4eded69d51982b38f9ec1003c3e41b22c757150736d2df976908abfdc5da7c9bbc5f4626f6752c41141534867d14cddc4e4278aa456824bfe131880aaf17a125569a365f802af859107a9e916e2442ceff6ff2feb77c6dc0b87639c9f1b34f681f2383a599f8dca8f6558cc60cdb5318fe58888604d4b66ab5175e0dadf1deb499937cb090094adb46b52752954ffc915fbbf41999bb5c301c40e1f1a6e45c23bb10529a356d753ee0d42003d82bf3e5eb5556fa27e394780034dcf5b"; - __try { - // convert hex string to byte array - DWORD cbLen = 0, dwSkip = 0, dwFlags = 0; - if (!CryptStringToBinaryA(pszModulus, cchModulus, CRYPT_STRING_HEX, nullptr, &cbLen, &dwSkip, &dwFlags)) { - result = GetLastError(); - __leave; - } + BIGNUM *N = BN_new(), *E = BN_new(); + BN_hex2bn(&N, pszModulus); + BN_hex2bn(&E, exponent); - // allocate a new buffer. - mir_ptr pbBuffer((uint8_t *)mir_alloc(cbLen)); - if (!CryptStringToBinaryA(pszModulus, cchModulus, CRYPT_STRING_HEX, pbBuffer, &cbLen, &dwSkip, &dwFlags)) { - result = GetLastError(); - __leave; - } + auto rsa = RSA_new(); + RSA_set0_key(rsa, N, E, NULL); - // reverse byte array, because of microsoft - for (int i = 0; i < (int)(cbLen / 2); ++i) { - uint8_t temp = pbBuffer[cbLen - i - 1]; - pbBuffer[cbLen - i - 1] = pbBuffer[i]; - pbBuffer[i] = temp; - } + MBinBuffer ret(RSA_size(rsa)); + memset(ret.data(), 0, ret.length()); + RSA_public_encrypt((int)mir_strlen(data), (BYTE*)data, ret.data(), rsa, RSA_PKCS1_PADDING); - if (!CryptAcquireContext(&hCSP, nullptr, nullptr, PROV_RSA_AES, CRYPT_SILENT) && - !CryptAcquireContext(&hCSP, nullptr, nullptr, PROV_RSA_AES, CRYPT_SILENT | CRYPT_NEWKEYSET)) { - result = GetLastError(); - __leave; - } - - // Move the key into the key container. - uint32_t cbKeyBlob = sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + cbLen; - mir_ptr pKeyBlob((uint8_t *)mir_alloc(cbKeyBlob)); - - // Fill in the data. - PUBLICKEYSTRUC *pPublicKey = (PUBLICKEYSTRUC *)pKeyBlob.get(); - pPublicKey->bType = PUBLICKEYBLOB; - pPublicKey->bVersion = CUR_BLOB_VERSION; // Always use this value. - pPublicKey->reserved = 0; // Must be zero. - pPublicKey->aiKeyAlg = CALG_RSA_KEYX; // RSA public-key key exchange. - - // The next block of data is the RSAPUBKEY structure. - RSAPUBKEY *pRsaPubKey = (RSAPUBKEY *)(pKeyBlob + sizeof(PUBLICKEYSTRUC)); - pRsaPubKey->magic = 0x31415352; // RSA1 // Use public key - pRsaPubKey->bitlen = cbLen * 8; // Number of bits in the modulus. - pRsaPubKey->pubexp = exponent; // Exponent. - - // Copy the modulus into the blob. Put the modulus directly after the - // RSAPUBKEY structure in the blob. - uint8_t *pKey = (uint8_t *)(((uint8_t *)pRsaPubKey) + sizeof(RSAPUBKEY)); - memcpy(pKey, pbBuffer, cbLen); - - // Now import public key - if (!CryptImportKey(hCSP, pKeyBlob, cbKeyBlob, 0, 0, &phKey)) { - result = GetLastError(); - __leave; - } - - DWORD dataSize = (DWORD)mir_strlen(data); - - // if data is not allocated just renurn size - if (encryptedData == nullptr) { - // get length of encrypted data - if (!CryptEncrypt(phKey, 0, TRUE, 0, nullptr, &encryptedSize, dataSize)) - result = GetLastError(); - __leave; - } - - // encrypt password - memcpy(encryptedData, data, dataSize); - if (!CryptEncrypt(phKey, 0, TRUE, 0, encryptedData, &dataSize, encryptedSize)) { - result = GetLastError(); - __leave; - } - - // reverse byte array again - for (int i = 0; i < (int)(encryptedSize / 2); ++i) { - uint8_t temp = encryptedData[encryptedSize - i - 1]; - encryptedData[encryptedSize - i - 1] = encryptedData[i]; - encryptedData[i] = temp; - } - } - __finally - { - result = 0; - }; - - if (phKey) - CryptDestroyKey(phKey); - - if (hCSP) - CryptReleaseContext(hCSP, 0); - - return 0; + RSA_free(rsa); + return ret; } diff --git a/protocols/Steam/src/steam_events.cpp b/protocols/Steam/src/steam_events.cpp index 1db7ae6480..7c379448c7 100644 --- a/protocols/Steam/src/steam_events.cpp +++ b/protocols/Steam/src/steam_events.cpp @@ -2,8 +2,6 @@ void CSteamProto::OnModulesLoaded() { - Clist_GroupCreate(0, m_defaultGroup); - HookProtoEvent(ME_IDLE_CHANGED, &CSteamProto::OnIdleChanged); HookProtoEvent(ME_MSG_PRECREATEEVENT, &CSteamProto::OnPreCreateMessage); diff --git a/protocols/Steam/src/steam_login.cpp b/protocols/Steam/src/steam_login.cpp index 6bf3bfb89e..ce235b635c 100644 --- a/protocols/Steam/src/steam_login.cpp +++ b/protocols/Steam/src/steam_login.cpp @@ -138,13 +138,6 @@ void CSteamProto::Login() hello.protocol_version = STEAM_PROTOCOL_VERSION; hello.has_protocol_version = true; WSSend(EMsg::ClientHello, hello); - ptrA token(getStringA("TokenSecret")); - ptrA sessionId(getStringA("SessionID")); - if (mir_strlen(token) > 0 && mir_strlen(sessionId) > 0) { - // SendRequest(new LogonRequest(token), &CSteamProto::OnLoggedOn); - return; - } - ptrA username(getUStringA("Username")); if (username == NULL) LoginFailed(); @@ -193,48 +186,34 @@ void CSteamProto::OnGotRsaKey(const uint8_t *buf, size_t cbLen) return; } - // load rsa key parts - DWORD exponent = strtoul(reply->publickey_exp, nullptr, 16); // default "010001" = 0x10001 - // encrypt password ptrA szPassword(getStringA("Password")); - DWORD error = 0; - DWORD encryptedSize = 0; - if ((error = RsaEncrypt(reply->publickey_mod, exponent, szPassword, nullptr, encryptedSize)) != 0) { - debugLogA(__FUNCTION__ ": encryption error (%lu)", error); - SetStatus(ID_STATUS_OFFLINE); - return; - } - - uint8_t *encryptedPassword = (uint8_t *)mir_calloc(encryptedSize); - if ((error = RsaEncrypt(reply->publickey_mod, exponent, szPassword, encryptedPassword, encryptedSize)) != 0) { - debugLogA(__FUNCTION__ ": encryption error (%lu)", error); - SetStatus(ID_STATUS_OFFLINE); - return; - } - - ptrA base64RsaEncryptedPassword(mir_base64_encode(encryptedPassword, encryptedSize)); - mir_free(encryptedPassword); + MBinBuffer encPassword(RsaEncrypt(reply->publickey_mod, reply->publickey_exp, szPassword)); + ptrA base64RsaEncryptedPassword(mir_base64_encode(encPassword.data(), encPassword.length())); // run authorization request ptrA userName(getUStringA("Username")); - ptrA deviceName(getUStringA("DeviceName")); + T2Utf deviceName(m_wszDeviceName); CAuthenticationDeviceDetails details; details.device_friendly_name = deviceName.get(); - details.os_type = 1; details.has_os_type = true; + details.os_type = 16; details.has_os_type = true; details.platform_type = EAUTH_TOKEN_PLATFORM_TYPE__k_EAuthTokenPlatformType_SteamClient; details.has_platform_type = true; CAuthenticationBeginAuthSessionViaCredentialsRequest request; request.account_name = userName.get(); - request.device_friendly_name = deviceName.get(); + request.website_id = "Client"; request.encrypted_password = base64RsaEncryptedPassword; request.encryption_timestamp = reply->timestamp; request.has_encryption_timestamp = true; - request.persistence = ESESSION_PERSISTENCE__k_ESessionPersistence_Ephemeral; request.has_persistence = true; - request.platform_type = EAUTH_TOKEN_PLATFORM_TYPE__k_EAuthTokenPlatformType_SteamClient; request.has_platform_type = true; + request.persistence = ESESSION_PERSISTENCE__k_ESessionPersistence_Persistent; request.has_persistence = true; request.remember_login = 0; request.has_remember_login = true; + request.language = 1; request.has_language = true; + request.qos_level = 2; request.has_qos_level = true; + request.device_details = &details; + request.device_friendly_name = details.device_friendly_name; + request.platform_type = details.platform_type; request.has_platform_type = true; WSSendService("Authentication.BeginAuthSessionViaCredentials#1", request, &CSteamProto::OnAuthorization); } diff --git a/protocols/Steam/src/steam_options.cpp b/protocols/Steam/src/steam_options.cpp index 2e52b6da46..40dadd20ff 100644 --- a/protocols/Steam/src/steam_options.cpp +++ b/protocols/Steam/src/steam_options.cpp @@ -2,16 +2,17 @@ class CSteamOptionsMain : public CSteamDlgBase { - CCtrlEdit m_username, m_password, m_group; + CCtrlEdit m_username, m_password, m_group, m_deviceName; CCtrlCheck m_biggerAvatars, m_showChatEvents; CCtrlSpin m_pollingErrorLimit; public: CSteamOptionsMain(CSteamProto *proto, int idDialog, HWND hwndParent = NULL) : CSteamDlgBase(proto, idDialog), + m_group(this, IDC_GROUP), m_username(this, IDC_USERNAME), m_password(this, IDC_PASSWORD), - m_group(this, IDC_GROUP), + m_deviceName(this, IDC_DEVICE_NAME), m_biggerAvatars(this, IDC_BIGGER_AVATARS), m_showChatEvents(this, IDC_SHOW_CHAT_EVENTS), m_pollingErrorLimit(this, IDC_POLLINGERRORLIMITSPIN, 255) @@ -20,7 +21,8 @@ public: CreateLink(m_username, "Username", L""); CreateLink(m_password, "Password", L""); - CreateLink(m_group, "DefaultGroup", L"Steam"); + CreateLink(m_group, m_proto->m_wszGroupName); + CreateLink(m_deviceName, m_proto->m_wszDeviceName); if (idDialog == IDD_OPT_MAIN) { CreateLink(m_biggerAvatars, "UseBigAvatars", DBVT_BYTE, FALSE); @@ -41,21 +43,8 @@ public: bool OnApply() override { - ptrW group(m_group.GetText()); - if (mir_wstrcmp(group, m_proto->m_defaultGroup)) { - m_proto->m_defaultGroup = mir_wstrdup(group); - Clist_GroupCreate(0, group); - } - - if (m_proto->IsOnline()) // may be we should show message box with warning? - m_proto->SetStatus(ID_STATUS_OFFLINE); - - if (m_username.IsChanged()) { + if (m_username.IsChanged()) m_proto->delSetting(DBKEY_STEAM_ID); - m_proto->delSetting("TokenSecret"); - } - if (m_password.IsChanged()) - m_proto->delSetting("TokenSecret"); return true; } }; diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp index e57c2af8c2..5475a4368e 100644 --- a/protocols/Steam/src/steam_proto.cpp +++ b/protocols/Steam/src/steam_proto.cpp @@ -9,13 +9,10 @@ static int CompareRequests(const ProtoRequest *p1, const ProtoRequest *p2) CSteamProto::CSteamProto(const char *protoName, const wchar_t *userName) : PROTO(protoName, userName), - m_arRequests(10, CompareRequests) + m_arRequests(10, CompareRequests), + m_wszGroupName(this, "DefaultGroup", L"Steam"), + m_wszDeviceName(this, "DeviceName", L"Miranda NG") { - // default group - m_defaultGroup = getWStringA("DefaultGroup"); - if (m_defaultGroup == nullptr) - m_defaultGroup = mir_wstrdup(L"Steam"); - // icons wchar_t filePath[MAX_PATH]; GetModuleFileName(g_plugin.getInst(), filePath, MAX_PATH); diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h index 8edf2c788a..8b93aa0e7f 100644 --- a/protocols/Steam/src/steam_proto.h +++ b/protocols/Steam/src/steam_proto.h @@ -68,7 +68,6 @@ class CSteamProto : public PROTO friend class PollRequest; ptrW m_password; - ptrW m_defaultGroup; bool m_bTerminated; HWND m_hwndGuard; time_t m_idleTS; @@ -218,9 +217,7 @@ class CSteamProto : public PROTO // utils static uint16_t SteamToMirandaStatus(PersonaState state); static PersonaState MirandaToSteamState(int status); - - static int RsaEncrypt(const char *pszModulus, DWORD &exponent, const char *data, uint8_t *encrypted, DWORD &encryptedSize); - + static void ShowNotification(const wchar_t *message, int flags = 0, MCONTACT hContact = NULL); static void ShowNotification(const wchar_t *caption, const wchar_t *message, int flags = 0, MCONTACT hContact = NULL); @@ -258,10 +255,14 @@ class CSteamProto : public PROTO } public: - // PROTO_INTERFACE + // constructor CSteamProto(const char *protoName, const wchar_t *userName); ~CSteamProto(); + // options + CMOption m_wszGroupName; // default group for this account's contacts + CMOption m_wszDeviceName; // how do you see this account in the Device List + // PROTO_INTERFACE MCONTACT AddToList(int flags, PROTOSEARCHRESULT *psr) override; MCONTACT AddToListByEvent(int flags, int iContact, MEVENT hDbEvent) override; @@ -301,4 +302,6 @@ struct CMPlugin : public ACCPROTOPLUGIN int OnReloadIcons(WPARAM wParam, LPARAM lParam); void SetContactExtraIcon(MCONTACT hContact, int status); +MBinBuffer RsaEncrypt(const char *pszModulus, const char *exponent, const char *data); + #endif //_STEAM_PROTO_H_ -- cgit v1.2.3