diff options
-rw-r--r-- | protocols/Steam/Steam.vcxproj | 3 | ||||
-rw-r--r-- | protocols/Steam/src/api/enums.h | 35 | ||||
-rw-r--r-- | protocols/Steam/src/http_request.h | 27 | ||||
-rw-r--r-- | protocols/Steam/src/stdafx.h | 2 | ||||
-rw-r--r-- | protocols/Steam/src/steam_contacts.cpp | 24 | ||||
-rw-r--r-- | protocols/Steam/src/steam_dialogs.cpp | 9 | ||||
-rw-r--r-- | protocols/Steam/src/steam_dialogs.h | 4 | ||||
-rw-r--r-- | protocols/Steam/src/steam_login.cpp | 8 | ||||
-rw-r--r-- | protocols/Steam/src/steam_polling.cpp | 61 |
9 files changed, 113 insertions, 60 deletions
diff --git a/protocols/Steam/Steam.vcxproj b/protocols/Steam/Steam.vcxproj index 0db6b56896..36b0c03011 100644 --- a/protocols/Steam/Steam.vcxproj +++ b/protocols/Steam/Steam.vcxproj @@ -37,6 +37,7 @@ <ItemDefinitionGroup>
<ClCompile>
<ExceptionHandling>Sync</ExceptionHandling>
+ <LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
-</Project>
+</Project>
\ No newline at end of file diff --git a/protocols/Steam/src/api/enums.h b/protocols/Steam/src/api/enums.h index 1a1643a15d..b0b4caa2ee 100644 --- a/protocols/Steam/src/api/enums.h +++ b/protocols/Steam/src/api/enums.h @@ -21,17 +21,25 @@ enum PersonaState LookingToPlay = 6, }; -enum PersonaStateFlag +enum class PersonaStateFlag : int { None = 0, HasRichPresence = 1, InJoinableGame = 2, - OnlineUsingWeb = 256, - OnlineUsingMobile = 512, - OnlineUsingBigPicture = 1024, + ClientTypeWeb = 256, + ClientTypeMobile = 512, + ClientTypeBigPicture = 1024, + ClientTypeVR = 2048, }; -enum PersonaStatusFlag +inline PersonaStateFlag operator &(PersonaStateFlag lhs, PersonaStateFlag rhs) +{ + return static_cast<PersonaStateFlag> ( + static_cast<std::underlying_type<PersonaStateFlag>::type>(lhs) & + static_cast<std::underlying_type<PersonaStateFlag>::type>(rhs)); +} + +enum class PersonaStatusFlag : int { Status = 1, PlayerName = 2, @@ -45,9 +53,17 @@ enum PersonaStatusFlag GameDataBlob = 512, ClanTag = 1024, Facebook = 2048, + Unknown = 4096, }; -enum PersonaRelationshipAction +inline PersonaStatusFlag operator &(PersonaStatusFlag lhs, PersonaStatusFlag rhs) +{ + return static_cast<PersonaStatusFlag> ( + static_cast<std::underlying_type<PersonaStatusFlag>::type>(lhs) & + static_cast<std::underlying_type<PersonaStatusFlag>::type>(rhs)); +} + +enum class PersonaRelationshipAction : int { // friend removed from contact list Remove = 0, @@ -61,4 +77,11 @@ enum PersonaRelationshipAction AuthRequested = 4, }; +template<typename T> +bool contains_flag(T x, T y) { + return (static_cast<typename std::underlying_type<T>::type>(x) + & static_cast<typename std::underlying_type<T>::type>(y)) + == static_cast<typename std::underlying_type<T>::type>(y); +} + #endif //_STEAM_ENUMS_H_ diff --git a/protocols/Steam/src/http_request.h b/protocols/Steam/src/http_request.h index 696b04f2a8..321bad5e7e 100644 --- a/protocols/Steam/src/http_request.h +++ b/protocols/Steam/src/http_request.h @@ -128,13 +128,23 @@ public: : nullptr; } - size_t GetSize() const + size_t size() const { return m_request ? m_request->headersCount : 0; } + const NETLIBHTTPHEADER* begin() const + { + return m_request->headers; + } + + const NETLIBHTTPHEADER* end() const + { + return m_request->headers + m_request->headersCount; + } + HttpHeaders& operator<<(const PARAM ¶m) { Set(param.szName); @@ -186,18 +196,21 @@ public: : nullptr; } - const char* GetData() const + operator const uint8_t*() const { return m_request - ? m_request->pData + ? (uint8_t*)m_request->pData : nullptr; } - size_t GetSize() const + const uint8_t* data() const { - return m_request - ? m_request->dataLength - : 0; + return this->operator const uint8_t*(); + } + + size_t size() const + { + return m_request ? m_request->dataLength : 0; } }; diff --git a/protocols/Steam/src/stdafx.h b/protocols/Steam/src/stdafx.h index 4bbc6f770b..bf171853c9 100644 --- a/protocols/Steam/src/stdafx.h +++ b/protocols/Steam/src/stdafx.h @@ -58,7 +58,7 @@ extern HANDLE hExtraXStatus; #define STEAM_DB_GETEVENTTEXT_CHATSTATES "/GetEventText2000"
#define STEAM_DB_EVENT_CHATSTATES_GONE 1
-#define now() time(NULL)
+#define now() time(nullptr)
#include "steam_dialogs.h"
#include "steam_options.h"
diff --git a/protocols/Steam/src/steam_contacts.cpp b/protocols/Steam/src/steam_contacts.cpp index 1375815dda..75f17f80e4 100644 --- a/protocols/Steam/src/steam_contacts.cpp +++ b/protocols/Steam/src/steam_contacts.cpp @@ -33,6 +33,7 @@ void CSteamProto::SetContactStatus(MCONTACT hContact, WORD status) SetContactExtraIcon(hContact, NULL); } // no break intentionally + [[fallthrough]]; default: db_unset(hContact, "CList", "StatusMsg"); @@ -161,29 +162,36 @@ void CSteamProto::UpdateContactDetails(MCONTACT hContact, const JSONNode &data) // client node = data["personastateflags"]; - long stateflags = !node.isnull() ? node.as_int() : -1; - if (stateflags == 0) { + PersonaStateFlag stateflags = !node.isnull() + ? (PersonaStateFlag)node.as_int() + : (PersonaStateFlag)(-1); + + if (stateflags == PersonaStateFlag::None) { // nothing special, either standard client or in different status (only online, I want to play, I want to trade statuses support this flags) WORD status = getWord(hContact, "Status", ID_STATUS_OFFLINE); if (status == ID_STATUS_ONLINE || status == ID_STATUS_OUTTOLUNCH || status == ID_STATUS_FREECHAT) setWString(hContact, "MirVer", L"Steam"); } - else if (stateflags & PersonaStateFlag::InJoinableGame) { + else if (contains_flag(stateflags, PersonaStateFlag::InJoinableGame)) { // game setWString(hContact, "MirVer", L"Steam (in game)"); } - else if (stateflags & PersonaStateFlag::OnlineUsingWeb) { + else if (contains_flag(stateflags, PersonaStateFlag::ClientTypeWeb)) { // on website setWString(hContact, "MirVer", L"Steam (website)"); } - else if (stateflags & PersonaStateFlag::OnlineUsingMobile) { + else if (contains_flag(stateflags, PersonaStateFlag::ClientTypeMobile)) { // on mobile setWString(hContact, "MirVer", L"Steam (mobile)"); } - else if (stateflags & PersonaStateFlag::OnlineUsingBigPicture) { - // big picture mode + else if (contains_flag(stateflags, PersonaStateFlag::ClientTypeBigPicture)) { + // on big picture setWString(hContact, "MirVer", L"Steam (Big Picture)"); } + else if (contains_flag(stateflags, PersonaStateFlag::ClientTypeVR)) { + // on VR + setWString(hContact, "MirVer", L"Steam (VR)"); + } else { // none/unknown (e.g. when contact is offline) delSetting(hContact, "MirVer"); @@ -533,7 +541,7 @@ void CSteamProto::OnGotAvatar(const HttpResponse &response, void *arg) FILE *file = _wfopen(ai.filename, L"wb"); if (file) { - fwrite(response.Content, sizeof(char), response.Content.GetSize(), file); + fwrite((const char*)response.Content, sizeof(char), response.Content.size(), file); fclose(file); if (ai.hContact) diff --git a/protocols/Steam/src/steam_dialogs.cpp b/protocols/Steam/src/steam_dialogs.cpp index 568156796f..080b0b3d6b 100644 --- a/protocols/Steam/src/steam_dialogs.cpp +++ b/protocols/Steam/src/steam_dialogs.cpp @@ -112,21 +112,21 @@ const char* CSteamTwoFactorDialog::GetTwoFactorCode() /////////////////////////////////////////////////////////////////////////////////
-CSteamCaptchaDialog::CSteamCaptchaDialog(CSteamProto *proto, BYTE *captchaImage, int captchaImageSize)
+CSteamCaptchaDialog::CSteamCaptchaDialog(CSteamProto *proto, const uint8_t *captchaImage, int captchaImageSize)
: CSteamDlgBase(proto, IDD_CAPTCHA, false),
m_ok(this, IDOK), m_text(this, IDC_TEXT),
m_captchaImage(nullptr)
{
memset(m_captchaText, 0, sizeof(m_captchaText));
m_captchaImageSize = captchaImageSize;
- m_captchaImage = (BYTE*)mir_alloc(captchaImageSize);
+ m_captchaImage = (uint8_t*)mir_alloc(captchaImageSize);
memcpy(m_captchaImage, captchaImage, captchaImageSize);
m_ok.OnClick = Callback(this, &CSteamCaptchaDialog::OnOk);
}
CSteamCaptchaDialog::~CSteamCaptchaDialog()
{
- if(m_captchaImage)
+ if (m_captchaImage)
mir_free(m_captchaImage);
}
@@ -154,8 +154,7 @@ void CSteamCaptchaDialog::OnClose() INT_PTR CSteamCaptchaDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
{
- if (msg == WM_PAINT)
- {
+ if (msg == WM_PAINT) {
FIMEMORY *stream = FreeImage_OpenMemory(m_captchaImage, m_captchaImageSize);
FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(stream, 0);
FIBITMAP *bitmap = FreeImage_LoadFromMemory(fif, stream, 0);
diff --git a/protocols/Steam/src/steam_dialogs.h b/protocols/Steam/src/steam_dialogs.h index 133c19f414..20d6a60f48 100644 --- a/protocols/Steam/src/steam_dialogs.h +++ b/protocols/Steam/src/steam_dialogs.h @@ -75,7 +75,7 @@ class CSteamCaptchaDialog : public CSteamDlgBase private:
char m_captchaText[7];
- BYTE *m_captchaImage;
+ uint8_t *m_captchaImage;
int m_captchaImageSize;
CCtrlEdit m_text;
@@ -89,7 +89,7 @@ protected: INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam);
public:
- CSteamCaptchaDialog(CSteamProto *proto, BYTE *captchaImage, int captchaImageSize);
+ CSteamCaptchaDialog(CSteamProto *proto, const uint8_t *captchaImage, int captchaImageSize);
~CSteamCaptchaDialog();
const char *GetCaptchaText();
diff --git a/protocols/Steam/src/steam_login.cpp b/protocols/Steam/src/steam_login.cpp index 773556e84b..30bfc22981 100644 --- a/protocols/Steam/src/steam_login.cpp +++ b/protocols/Steam/src/steam_login.cpp @@ -123,7 +123,7 @@ void CSteamProto::OnGotCaptcha(const HttpResponse &response, void *arg) return; } - CSteamCaptchaDialog captchaDialog(this, (BYTE*)response.Content.GetData(), response.Content.GetSize()); + CSteamCaptchaDialog captchaDialog(this, response.Content, response.Content.size()); if (captchaDialog.DoModal() != DIALOG_RESULT_OK) { DeleteAuthSettings(); SetStatus(ID_STATUS_OFFLINE); @@ -300,11 +300,11 @@ void CSteamProto::OnGotSession(const HttpResponse &response, void*) return; } - for (size_t i = 0; i < response.Headers.GetSize(); i++) { - if (mir_strcmpi(response.Headers[i]->szName, "Set-Cookie")) + for (auto &header : response.Headers) { + if (mir_strcmpi(header.szName, "Set-Cookie")) continue; - std::string cookies = response.Headers[i]->szValue; + std::string cookies = header.szValue; size_t start = cookies.find("sessionid=") + 10; size_t end = cookies.substr(start).find(';'); std::string sessionId = cookies.substr(start, end - start + 10); diff --git a/protocols/Steam/src/steam_polling.cpp b/protocols/Steam/src/steam_polling.cpp index 24b9047d9b..e812e8e87f 100644 --- a/protocols/Steam/src/steam_polling.cpp +++ b/protocols/Steam/src/steam_polling.cpp @@ -4,6 +4,8 @@ void CSteamProto::ParsePollData(const JSONNode &data) { + std::string steamIds; + for (const JSONNode &item : data) { json_string steamId = item["steamid_from"].as_string(); time_t timestamp = _wtol(item["utc_timestamp"].as_mstring()); @@ -22,8 +24,11 @@ void CSteamProto::ParsePollData(const JSONNode &data) recv.szMessage = (char*)text.c_str(); recv.flags = PREF_SENT; RecvMsg(hContact, &recv); + + continue; } - else if (type == "saytext" || type =="emote") { + + if (type == "saytext" || type =="emote") { json_string text = item["text"].as_string(); PROTORECVEVENT recv = { 0 }; @@ -33,8 +38,11 @@ void CSteamProto::ParsePollData(const JSONNode &data) CallService(MS_PROTO_CONTACTISTYPING, hContact, (LPARAM)PROTOTYPE_CONTACTTYPING_OFF); m_typingTimestamps[steamId] = 0; + + continue; } - else if (type == "typing") { + + if (type == "typing") { auto it = m_typingTimestamps.find(steamId); if (it != m_typingTimestamps.end()) { if ((timestamp - it->second) < STEAM_TYPING_TIME) @@ -42,8 +50,11 @@ void CSteamProto::ParsePollData(const JSONNode &data) } CallService(MS_PROTO_CONTACTISTYPING, hContact, (LPARAM)STEAM_TYPING_TIME); m_typingTimestamps[steamId] = timestamp; + + continue; } - else if (type == "personastate") { + + if (type == "personastate") { if (!IsMe(steamId.c_str())) { // there no sense to change own status JSONNode node = item["persona_state"]; @@ -52,16 +63,13 @@ void CSteamProto::ParsePollData(const JSONNode &data) SetContactStatus(hContact, status); } } + steamIds.append(steamId).append(","); - int statusFlags = item["status_flags"].as_int(); - if ((statusFlags & PersonaStatusFlag::PlayerName) == PersonaStatusFlag::PlayerName) { - CMStringW nick = item["persona_name"].as_mstring(); - if (!nick.IsEmpty()) - setWString(hContact, "Nick", nick); - } + continue; } - else if (type == "personarelationship") { - int state = item["persona_state"].as_int(); + + if (type == "personarelationship") { + PersonaRelationshipAction state = (PersonaRelationshipAction)item["persona_state"].as_int(); switch (state) { case PersonaRelationshipAction::Remove: hContact = GetContact(steamId.c_str()); @@ -76,7 +84,7 @@ void CSteamProto::ParsePollData(const JSONNode &data) break; case PersonaRelationshipAction::AuthRequest: - hContact = GetContact(steamId.c_str()); + hContact = AddContact(steamId.c_str()); if (hContact) ContactIsAskingAuth(hContact); else { @@ -92,12 +100,13 @@ void CSteamProto::ParsePollData(const JSONNode &data) hContact = GetContact(steamId.c_str()); if (hContact) ContactIsFriend(hContact); - - default: - continue; + break; } + + continue; } - else if (type == "leftconversation") { + + if (type == "leftconversation") { if (!getBool("ShowChatEvents", true)) continue; @@ -110,21 +119,21 @@ void CSteamProto::ParsePollData(const JSONNode &data) dbei.timestamp = now(); dbei.szModule = m_szModuleName; db_event_add(hContact, &dbei); - } - else { - debugLogA(__FUNCTION__ ": Unknown event type \"%s\"", type.c_str()); + continue; } + + debugLogA(__FUNCTION__ ": Unknown event type \"%s\"", type.c_str()); } - /*if (!steamIds.empty()) { - steamIds.pop_back(); + if (steamIds.empty()) + return; - ptrA token(getStringA("TokenSecret")); - PushRequest( - new GetUserSummariesRequest(token, steamIds.c_str()), - &CSteamProto::OnGotUserSummaries); - }*/ + steamIds.pop_back(); + ptrA token(getStringA("TokenSecret")); + PushRequest( + new GetUserSummariesRequest(token, steamIds.c_str()), + &CSteamProto::OnGotUserSummaries); } struct PollParam |