summaryrefslogtreecommitdiff
path: root/protocols/Steam
diff options
context:
space:
mode:
authorAlexander Lantsev <aunsane@gmail.com>2014-04-06 18:55:34 +0000
committerAlexander Lantsev <aunsane@gmail.com>2014-04-06 18:55:34 +0000
commitdea767bfe91ba408b09e4f9bcd503dd2150276a7 (patch)
treed44ac7a5e0460144feee1c2996dac5a1d02e67f5 /protocols/Steam
parent8457a7c95db2775bd977ba8de5091f5d5d9277eb (diff)
Steam: server polling, status changing, messaging
git-svn-id: http://svn.miranda-ng.org/main/trunk@8873 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/Steam')
-rw-r--r--protocols/Steam/Steam_12.vcxproj2
-rw-r--r--protocols/Steam/Steam_12.vcxproj.filters6
-rw-r--r--protocols/Steam/src/Steam/message.h100
-rw-r--r--protocols/Steam/src/Steam/poll.h61
-rw-r--r--protocols/Steam/src/Steam/steam.h1
-rw-r--r--protocols/Steam/src/steam.h2
-rw-r--r--protocols/Steam/src/steam_account.cpp69
-rw-r--r--protocols/Steam/src/steam_contacts.cpp27
-rw-r--r--protocols/Steam/src/steam_dialogs.cpp131
-rw-r--r--protocols/Steam/src/steam_messages.cpp47
-rw-r--r--protocols/Steam/src/steam_proto.cpp35
-rw-r--r--protocols/Steam/src/steam_proto.h19
-rw-r--r--protocols/Steam/src/steam_thread.cpp104
13 files changed, 438 insertions, 166 deletions
diff --git a/protocols/Steam/Steam_12.vcxproj b/protocols/Steam/Steam_12.vcxproj
index 27e8bf8acf..19c0828fe6 100644
--- a/protocols/Steam/Steam_12.vcxproj
+++ b/protocols/Steam/Steam_12.vcxproj
@@ -199,6 +199,7 @@
<ClInclude Include="src\Steam\friend.h" />
<ClInclude Include="src\Steam\friend_list.h" />
<ClInclude Include="src\Steam\login.h" />
+ <ClInclude Include="src\Steam\message.h" />
<ClInclude Include="src\Steam\poll.h" />
<ClInclude Include="src\Steam\steam.h" />
<ClInclude Include="src\steam_proto.h" />
@@ -211,6 +212,7 @@
<ClCompile Include="src\steam_events.cpp" />
<ClCompile Include="src\steam_dialogs.cpp" />
<ClCompile Include="src\steam_instances.cpp" />
+ <ClCompile Include="src\steam_messages.cpp" />
<ClCompile Include="src\steam_proto.cpp" />
<ClCompile Include="src\stdafx.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
diff --git a/protocols/Steam/Steam_12.vcxproj.filters b/protocols/Steam/Steam_12.vcxproj.filters
index 0dc0ba34af..5c30306822 100644
--- a/protocols/Steam/Steam_12.vcxproj.filters
+++ b/protocols/Steam/Steam_12.vcxproj.filters
@@ -42,6 +42,9 @@
<ClCompile Include="src\steam_contacts.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\steam_messages.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\resource.h">
@@ -80,6 +83,9 @@
<ClInclude Include="src\Steam\poll.h">
<Filter>Header Files\Steam</Filter>
</ClInclude>
+ <ClInclude Include="src\Steam\message.h">
+ <Filter>Header Files\Steam</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="res\resource.rc">
diff --git a/protocols/Steam/src/Steam/message.h b/protocols/Steam/src/Steam/message.h
new file mode 100644
index 0000000000..d5059c4833
--- /dev/null
+++ b/protocols/Steam/src/Steam/message.h
@@ -0,0 +1,100 @@
+#ifndef _STEAM_MESSAGE_H_
+#define _STEAM_MESSAGE_H_
+
+namespace SteamWebApi
+{
+ class MessageApi : public BaseApi
+ {
+ public:
+ class SendResult : public Result
+ {
+ friend MessageApi;
+
+ private:
+ DWORD timestamp;
+
+ public:
+ SendResult() : timestamp(0) { }
+
+ const DWORD GetTimestamp() const { return timestamp; }
+ };
+
+ static void SendStatus(HANDLE hConnection, const char *token, const char *sessionId, int state, SendResult *sendResult)
+ {
+ sendResult->success = false;
+
+ CMStringA data;
+ data.AppendFormat("access_token=%s", token);
+ data.AppendFormat("&umqid=%s", sessionId);
+ data.AppendFormat("&persona_state=%u", state);
+ data.Append("&type=personastate");
+
+ HttpRequest request(hConnection, REQUEST_POST, STEAM_API_URL "/ISteamWebUserPresenceOAuth/Message/v0001");
+ request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
+ request.SetData(data.GetBuffer(), data.GetLength());
+
+ mir_ptr<NETLIBHTTPREQUEST> response(request.Send());
+ if (!response || response->resultCode != HTTP_STATUS_OK)
+ return;
+
+ sendResult->success = true;
+ }
+
+ static void SendMessage(HANDLE hConnection, const char *token, const char *sessionId, const char *steamId, const char *text, SendResult *sendResult)
+ {
+ sendResult->success = false;
+
+ CMStringA data;
+ data.AppendFormat("access_token=%s", token);
+ data.AppendFormat("&umqid=%s", sessionId);
+ data.AppendFormat("&steamid_dst=%s", steamId);
+ data.Append("&type=saytext");
+ data.AppendFormat("&text=%s", ptrA(mir_urlEncode(text)));
+
+ HttpRequest request(hConnection, REQUEST_POST, STEAM_API_URL "/ISteamWebUserPresenceOAuth/Message/v0001");
+ request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
+ request.SetData(data.GetBuffer(), data.GetLength());
+
+ mir_ptr<NETLIBHTTPREQUEST> response(request.Send());
+ if (!response || response->resultCode != HTTP_STATUS_OK)
+ return;
+
+ JSONNODE *root = json_parse(response->pData), *node;
+
+ node = json_get(root, "error");
+ ptrW error(json_as_string(node));
+
+ if (lstrcmp(error, L"OK"))
+ return;
+
+ node = json_get(root, "utc_timestamp");
+ sendResult->timestamp = atol(ptrA(mir_u2a(json_as_string(node))));
+
+ sendResult->success = true;
+ }
+
+ static void SendTyping(HANDLE hConnection, const char *token, const char *sessionId, const char *steamId, SendResult *sendResult)
+ {
+ sendResult->success = false;
+
+ CMStringA data;
+ data.AppendFormat("access_token=%s", token);
+ data.AppendFormat("&umqid=%s", sessionId);
+ data.AppendFormat("&steamid_dst=%s", steamId);
+ data.Append("&type=typing");
+
+ HttpRequest request(hConnection, REQUEST_POST, STEAM_API_URL "/ISteamWebUserPresenceOAuth/Message/v0001");
+ request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
+ request.SetData(data.GetBuffer(), data.GetLength());
+
+ mir_ptr<NETLIBHTTPREQUEST> response(request.Send());
+ if (!response || response->resultCode != HTTP_STATUS_OK)
+ return;
+
+ sendResult->success = true;
+ }
+ };
+}
+
+
+#endif //_STEAM_MESSAGE_H_ \ No newline at end of file
diff --git a/protocols/Steam/src/Steam/poll.h b/protocols/Steam/src/Steam/poll.h
index c99bfecf0b..a8e7c76306 100644
--- a/protocols/Steam/src/Steam/poll.h
+++ b/protocols/Steam/src/Steam/poll.h
@@ -1,5 +1,5 @@
-#ifndef _STEAM_POOL_H_
-#define _STEAM_POOL_H_
+#ifndef _STEAM_POLL_H_
+#define _STEAM_POLL_H_
namespace SteamWebApi
{
@@ -8,10 +8,11 @@ namespace SteamWebApi
public:
enum POOL_TYPE
{
- UNKNOWN = 0,
- MESSAGE = 1,
- TYPING = 2,
- STATE = 3,
+ UNKNOWN,
+ MESSAGE,
+ MYMESSAGE,
+ TYPING,
+ STATE,
//POOL_TYPE_RELATIONSHIP = 4
};
@@ -23,7 +24,6 @@ namespace SteamWebApi
std::string steamId;
DWORD timestamp;
POOL_TYPE type;
- bool send;
public:
PoolItem() : timestamp(0), type(POOL_TYPE::UNKNOWN) { }
@@ -31,12 +31,11 @@ namespace SteamWebApi
const char *GetSteamId() const { return steamId.c_str(); }
const DWORD GetTimestamp() const { return timestamp; }
POOL_TYPE GetType() const { return type; }
- bool IsSend() const { return send; }
};
- class Typing : PoolItem { friend PollApi; };
+ class Typing : public PoolItem { friend PollApi; };
- class Message : PoolItem
+ class Message : public PoolItem
{
friend PollApi;
@@ -47,7 +46,7 @@ namespace SteamWebApi
const wchar_t *GetText() const { return text.c_str(); }
};
- class State : PoolItem
+ class State : public PoolItem
{
friend PollApi;
@@ -65,13 +64,15 @@ namespace SteamWebApi
friend PollApi;
private:
+ bool need_relogin;
UINT32 messageId;
std::vector<PoolItem*> items;
public:
- PollResult() : messageId(0) { }
+ PollResult() : messageId(0), need_relogin(false) { }
UINT32 GetMessageId() const { return messageId; }
+ int IsNeedRelogin() const { return need_relogin; }
int GetItemCount() const { return items.size(); }
const PoolItem * operator[](int idx) const { return items.at(idx); }
};
@@ -84,12 +85,12 @@ namespace SteamWebApi
data.AppendFormat("access_token=%s", token);
data.AppendFormat("&umqid=%s", sessionId);
data.AppendFormat("&message=%i", messageId);
- //data.Append("&sectimeout=30");
+ //data.Append("&sectimeout=90");
HttpRequest request(hConnection, REQUEST_POST, STEAM_API_URL "/ISteamWebUserPresenceOAuth/Poll/v0001");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.SetData(data.GetBuffer(), data.GetLength());
- request.timeout = 35000;
+ request.timeout = 90000;
mir_ptr<NETLIBHTTPREQUEST> response(request.Send());
if (!response || response->resultCode != HTTP_STATUS_OK)
@@ -98,16 +99,20 @@ namespace SteamWebApi
JSONNODE *root = json_parse(response->pData), *node, *child;
node = json_get(root, "error");
ptrW error(json_as_string(node));
- /*if (!lstrcmpi(error, L"Not Logged On"))
+
+ if (!lstrcmpi(error, L"Not Logged On"))
{
+ pollResult->need_relogin = true;
+ pollResult->success = true;
+ return;
}
- else */
- /*if (!lstrcmpi(error, L"Timeout"))
+ else
+ if (!lstrcmpi(error, L"Timeout"))
{
pollResult->messageId = messageId;
pollResult->success = true;
return;
- }*/
+ }
else if (lstrcmpi(error, L"OK"))
return;
@@ -128,20 +133,24 @@ namespace SteamWebApi
node = json_get(child, "type");
ptrW type(json_as_string(node));
- if (!lstrcmpi(type, L"saytext") || !lstrcmpi(type, L"emote"))
+ if (!lstrcmpi(type, L"saytext") || !lstrcmpi(type, L"emote") ||
+ !lstrcmpi(type, L"my_saytext") || !lstrcmpi(type, L"my_emote"))
{
Message *message = new Message();
- message->type = POOL_TYPE::MESSAGE;
+
+ if (_tcsstr(type, L"my_") == NULL)
+ message->type = POOL_TYPE::MESSAGE;
+ else
+ message->type = POOL_TYPE::MYMESSAGE;
node = json_get(child, "text");
if (node != NULL) message->text = json_as_string(node);
+ node = json_get(child, "utc_timestamp");
+ message->timestamp = atol(ptrA(mir_u2a(json_as_string(node))));
+
item = message;
}
- /*if (!lstrcmpi(type, L"my_saytext") || !lstrcmpi(type, L"my_emote"))
- {
- poll->type = POOL_TYPE::MESSAGE;
- }*/
else if(!lstrcmpi(type, L"typing"))
{
item = new Typing();
@@ -155,7 +164,7 @@ namespace SteamWebApi
node = json_get(child, "persona_state");
if (node != NULL) state->status = json_as_int(node);
- node = json_get(child, "personaname");
+ node = json_get(child, "persona_name");
if (node != NULL) state->nickname = json_as_string(node);
item = state;
@@ -189,4 +198,4 @@ namespace SteamWebApi
}
-#endif //_STEAM_POOL_H_ \ No newline at end of file
+#endif //_STEAM_POLL_H_ \ No newline at end of file
diff --git a/protocols/Steam/src/Steam/steam.h b/protocols/Steam/src/Steam/steam.h
index fc23594dca..54acf01ab8 100644
--- a/protocols/Steam/src/Steam/steam.h
+++ b/protocols/Steam/src/Steam/steam.h
@@ -35,5 +35,6 @@ namespace SteamWebApi
#include "Steam\friend_list.h"
#include "Steam\friend.h"
#include "Steam\poll.h"
+#include "Steam\message.h"
#endif //_STEAM_H_ \ No newline at end of file
diff --git a/protocols/Steam/src/steam.h b/protocols/Steam/src/steam.h
index 796689f4df..376491066f 100644
--- a/protocols/Steam/src/steam.h
+++ b/protocols/Steam/src/steam.h
@@ -12,7 +12,7 @@
#include <m_popup.h>
#include <m_json.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>
diff --git a/protocols/Steam/src/steam_account.cpp b/protocols/Steam/src/steam_account.cpp
index a08926cff3..768bfc4914 100644
--- a/protocols/Steam/src/steam_account.cpp
+++ b/protocols/Steam/src/steam_account.cpp
@@ -1,10 +1,79 @@
#include "common.h"
+WORD CSteamProto::SteamToMirandaStatus(int state)
+{
+ switch (state)
+ {
+ case 0: //Offline
+ return ID_STATUS_OFFLINE;
+ case 2: //Busy
+ return ID_STATUS_DND;
+ case 3: //Away
+ return ID_STATUS_AWAY;
+ /*case 4: //Snoozing
+ prim = PURPLE_STATUS_EXTENDED_AWAY;
+ break;
+ case 5: //Looking to trade
+ return "trade";
+ case 6: //Looking to play
+ return "play";*/
+ //case 1: //Online
+ default:
+ return ID_STATUS_ONLINE;
+ }
+}
+
+int CSteamProto::MirandaToSteamState(int status)
+{
+ switch (status)
+ {
+ case ID_STATUS_ONLINE:
+ return 1; //Online
+ case ID_STATUS_DND:
+ return 2; //Busy
+ case ID_STATUS_AWAY:
+ return 3; //Away
+ /*case 4: //Snoozing
+ prim = PURPLE_STATUS_EXTENDED_AWAY;
+ break;
+ case 5: //Looking to trade
+ return "trade";
+ case 6: //Looking to play
+ return "play";*/
+ //case 1: //Online
+ default:
+ return ID_STATUS_OFFLINE;
+ }
+}
+
bool CSteamProto::IsOnline()
{
return m_iStatus > ID_STATUS_OFFLINE;
}
+void CSteamProto::SetServerStatusThread(void *arg)
+{
+ WORD status = *((WORD*)arg);
+
+ ptrA token(getStringA("TokenSecret"));
+ ptrA sessionId(getStringA("SessionID"));
+
+ int state = CSteamProto::MirandaToSteamState(status);
+
+ // change status
+ if (m_iStatus == state)
+ return;
+
+ int oldStatus = m_iStatus;
+ m_iStatus = state;
+
+ SteamWebApi::MessageApi::SendResult sendResult;
+ SteamWebApi::MessageApi::SendStatus(m_hNetlibUser, token, sessionId, state, &sendResult);
+
+ if (sendResult.IsSuccess())
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
+}
+
void CSteamProto::Authorize(SteamWebApi::AuthorizationApi::AuthResult *authResult)
{
ptrW username(getWStringA("Username"));
diff --git a/protocols/Steam/src/steam_contacts.cpp b/protocols/Steam/src/steam_contacts.cpp
index ab95bf4649..9e01da2e33 100644
--- a/protocols/Steam/src/steam_contacts.cpp
+++ b/protocols/Steam/src/steam_contacts.cpp
@@ -1,5 +1,23 @@
#include "common.h"
+void CSteamProto::SetContactStatus(MCONTACT hContact, WORD status)
+{
+ WORD oldStatus = getWord(hContact, "Status", ID_STATUS_OFFLINE);
+ if (oldStatus != status)
+ setWord(hContact, "Status", status);
+}
+
+void CSteamProto::SetAllContactsStatus(WORD status)
+{
+ for (MCONTACT hContact = db_find_first(this->m_szModuleName); hContact; hContact = db_find_next(hContact, this->m_szModuleName))
+ {
+ if (this->isChatRoom(hContact))
+ continue;
+ //if (this->IsContactOnline(hContact))
+ setWord(hContact, "Status", status);
+ }
+}
+
MCONTACT CSteamProto::FindContact(const char *steamId)
{
MCONTACT hContact = NULL;
@@ -26,10 +44,11 @@ MCONTACT CSteamProto::AddContact(const SteamWebApi::FriendApi::Friend &contact)
hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0);
CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)this->m_szModuleName);
- this->setString(hContact, "SteamID", contact.GetSteamId());
- this->setWString(hContact, "Nick", contact.GetNickname());
- this->setString(hContact, "Homepage", contact.GetHomepage());
- this->setDword(hContact, "LastEventDateTS", contact.GetLastEvent());
+ setString(hContact, "SteamID", contact.GetSteamId());
+ setWString(hContact, "Nick", contact.GetNickname());
+ setString(hContact, "Homepage", contact.GetHomepage());
+ setDword(hContact, "LastEventDateTS", contact.GetLastEvent());
+ db_set_ws(hContact, "CList", "MyHandle", contact.GetNickname());
DBVARIANT dbv;
if (!getWString("DefaultGroup", &dbv))
diff --git a/protocols/Steam/src/steam_dialogs.cpp b/protocols/Steam/src/steam_dialogs.cpp
index c98f3c1eda..d7ec5c1f77 100644
--- a/protocols/Steam/src/steam_dialogs.cpp
+++ b/protocols/Steam/src/steam_dialogs.cpp
@@ -1,11 +1,7 @@
#include "common.h"
-//#include <gdiplus.h>
-//#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)
@@ -58,8 +54,6 @@ INT_PTR CALLBACK CSteamProto::GuardProc(HWND hwnd, UINT message, WPARAM wParam,
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)
@@ -69,38 +63,6 @@ INT_PTR CALLBACK CSteamProto::CaptchaProc(HWND hwnd, UINT message, WPARAM wParam
{
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;
@@ -108,68 +70,43 @@ INT_PTR CALLBACK CSteamProto::CaptchaProc(HWND hwnd, UINT message, WPARAM wParam
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:
// {
+ // /*FI_INTERFACE *fei = 0;
+
+ // INT_PTR result = CALLSERVICE_NOTFOUND;
+ // if (ServiceExists(MS_IMG_GETINTERFACE))
+ // result = CallService(MS_IMG_GETINTERFACE, FI_IF_VERSION, (LPARAM)&fei);
+
+ // if (fei == NULL || result != S_OK) {
+ // MessageBox(0, TranslateT("Fatal error, image services not found. Avatar services will be disabled."), TranslateT("Avatar Service"), MB_OK);
+ // return 0;
+ // }*/
+
// 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);
+ // HDC hDC = BeginPaint(hwnd, &ps);
+
+ // //FreeImage_Initialise();
+ //
+ // /*FIMEMORY *stream = FreeImage_OpenMemory(captcha->data, captcha->size);
+ // FIBITMAP *dib = FreeImage_LoadFromMemory(FIF_PNG, stream, PNG_DEFAULT);
+ // FreeImage_CloseMemory(stream);
+
+ // SetStretchBltMode(hDC, COLORONCOLOR);
+ // StretchDIBits(
+ // hDC,
+ // 0, 0,
+ // 206, 40,
+ // 0, 0,
+ // FreeImage_GetWidth(dib), FreeImage_GetHeight(dib),
+ // FreeImage_GetBits(dib),
+ // FreeImage_GetInfo(dib),
+ // DIB_RGB_COLORS, SRCCOPY);
+
+ // FreeImage_Unload(dib);*/
+
+ // //FreeImage_DeInitialise();
+
// EndPaint(hwnd, &ps);
// }
// return 0;
diff --git a/protocols/Steam/src/steam_messages.cpp b/protocols/Steam/src/steam_messages.cpp
new file mode 100644
index 0000000000..20496bc039
--- /dev/null
+++ b/protocols/Steam/src/steam_messages.cpp
@@ -0,0 +1,47 @@
+#include "common.h"
+
+void CSteamProto::SendMessageThread(void *arg)
+{
+ SendMessageParam *param = (SendMessageParam*)arg;
+
+ ptrA token(getStringA("TokenSecret"));
+ ptrA sessionId(getStringA("SessionID"));
+ ptrA steamId(getStringA(param->hContact, "SteamID"));
+
+ SteamWebApi::MessageApi::SendResult sendResult;
+ SteamWebApi::MessageApi::SendMessage(m_hNetlibUser, token, sessionId, steamId, param->text, &sendResult);
+
+ ProtoBroadcastAck(
+ param->hContact,
+ ACKTYPE_MESSAGE,
+ sendResult.IsSuccess() ? ACKRESULT_SUCCESS : ACKRESULT_FAILED,
+ param->hMessage, 0);
+
+ if (sendResult.IsSuccess())
+ {
+ DBEVENTINFO dbei = { sizeof(dbei) };
+ dbei.szModule = this->m_szModuleName;
+ dbei.timestamp = sendResult.GetTimestamp();
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.cbBlob = strlen(param->text);
+ dbei.pBlob = (BYTE*)param->text;
+ dbei.flags = DBEF_UTF | DBEF_SENT;
+
+ db_event_add(param->hContact, &dbei);
+ }
+
+ //mir_free((void*)param->text);
+ mir_free(param);
+}
+
+void CSteamProto::SendTypingThread(void *arg)
+{
+ MCONTACT hContact = (MCONTACT)arg;
+
+ ptrA token(getStringA("TokenSecret"));
+ ptrA sessionId(getStringA("SessionID"));
+ ptrA steamId(getStringA(hContact, "SteamID"));
+
+ SteamWebApi::MessageApi::SendResult sendResult;
+ SteamWebApi::MessageApi::SendTyping(m_hNetlibUser, token, sessionId, steamId, &sendResult);
+} \ No newline at end of file
diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp
index 97a11c8d62..7b5b808339 100644
--- a/protocols/Steam/src/steam_proto.cpp
+++ b/protocols/Steam/src/steam_proto.cpp
@@ -1,7 +1,8 @@
#include "common.h"
CSteamProto::CSteamProto(const char* protoName, const TCHAR* userName) :
- PROTO<CSteamProto>(protoName, userName)
+ PROTO<CSteamProto>(protoName, userName),
+ hMessageProcess(1)
{
CreateProtoService(PS_CREATEACCMGRUI, &CSteamProto::OnAccountManagerInit);
@@ -133,7 +134,15 @@ int __cdecl CSteamProto::RecvFile(MCONTACT hContact, PROTORECVFILET* pre)
int __cdecl CSteamProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT* pre)
{
- return 0;
+ DBEVENTINFO dbei = { sizeof(dbei) };
+ dbei.szModule = this->m_szModuleName;
+ dbei.timestamp = pre->timestamp;
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.cbBlob = lstrlenA(pre->szMessage);
+ dbei.pBlob = (BYTE*)pre->szMessage;
+ dbei.flags = DBEF_UTF;
+
+ return (INT_PTR)db_event_add(hContact, &dbei);
}
int __cdecl CSteamProto::RecvUrl(MCONTACT hContact, PROTORECVEVENT *) { return 0; }
@@ -150,7 +159,16 @@ HANDLE __cdecl CSteamProto::SendFile(MCONTACT hContact, const TCHAR *szDescripti
int __cdecl CSteamProto::SendMsg(MCONTACT hContact, int flags, const char *msg)
{
- return 0;
+ UINT hMessage = InterlockedIncrement(&hMessageProcess);
+
+ SendMessageParam *param = (SendMessageParam*)mir_calloc(sizeof(SendMessageParam));
+ param->hContact = hContact;
+ param->text = mir_utf8encode(msg);
+ param->hMessage = (HANDLE)hMessage;
+
+ ForkThread(&CSteamProto::SendMessageThread, param);
+
+ return hMessage;
}
int __cdecl CSteamProto::SendUrl(MCONTACT hContact, int flags, const char *url) { return 0; }
@@ -168,7 +186,6 @@ int CSteamProto::SetStatus(int new_status)
if (new_status == ID_STATUS_OFFLINE)
{
m_bTerminated = true;
-
ForkThread(&CSteamProto::LogOutThread, NULL);
m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
@@ -176,8 +193,8 @@ int CSteamProto::SetStatus(int new_status)
if (!Miranda_Terminated())
{
- /*this->SetAllContactStatus(ID_STATUS_OFFLINE);
- this->CloseAllChatSessions();*/
+ SetAllContactsStatus(ID_STATUS_OFFLINE);
+ //this->CloseAllChatSessions();
}
return 0;
@@ -191,11 +208,11 @@ int CSteamProto::SetStatus(int new_status)
}
else
{
- /*if (IsOnline())
+ if (IsOnline())
{
- SetServerStatus(new_status);
+ ForkThread(&CSteamProto::SetServerStatusThread, &new_status);
return 0;
- }*/
+ }
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h
index 853654fd37..e3cc2ea3d2 100644
--- a/protocols/Steam/src/steam_proto.h
+++ b/protocols/Steam/src/steam_proto.h
@@ -14,6 +14,13 @@ struct CaptchaParam
char text[10];
};
+struct SendMessageParam
+{
+ MCONTACT hContact;
+ HANDLE hMessage;
+ const char *text;
+};
+
class CSteamProto : public PROTO<CSteamProto>
{
public:
@@ -75,6 +82,7 @@ public:
protected:
bool m_bTerminated;
HANDLE m_hPollingThread;
+ ULONG hMessageProcess;
CRITICAL_SECTION contact_search_lock;
// instances
@@ -86,15 +94,26 @@ protected:
void __cdecl PollingThread(void*);
// account
+ static WORD SteamToMirandaStatus(int state);
+ static int MirandaToSteamState(int status);
+
bool IsOnline();
void Authorize(SteamWebApi::AuthorizationApi::AuthResult *authResult);
void __cdecl LogInThread(void*);
void __cdecl LogOutThread(void*);
+ void __cdecl SetServerStatusThread(void*);
// contacts
+ void SetContactStatus(MCONTACT hContact, WORD status);
+ void SetAllContactsStatus(WORD status);
+
MCONTACT FindContact(const char *steamId);
MCONTACT AddContact(const SteamWebApi::FriendApi::Friend &contact);
+ // messages
+ void __cdecl SendMessageThread(void*);
+ void __cdecl SendTypingThread(void*);
+
//events
int OnModulesLoaded(WPARAM, LPARAM);
int OnPreShutdown(WPARAM, LPARAM);
diff --git a/protocols/Steam/src/steam_thread.cpp b/protocols/Steam/src/steam_thread.cpp
index d1c6d8a3c0..4bb62c23d7 100644
--- a/protocols/Steam/src/steam_thread.cpp
+++ b/protocols/Steam/src/steam_thread.cpp
@@ -1,37 +1,24 @@
#include "common.h"
-int SteamToMirandaStatus(int state)
-{
- switch (state)
- {
- case 0: //Offline
- return ID_STATUS_OFFLINE;
- case 2: //Busy
- return ID_STATUS_DND;
- case 3: //Away
- return ID_STATUS_AWAY;
- /*case 4: //Snoozing
- prim = PURPLE_STATUS_EXTENDED_AWAY;
- break;
- case 5: //Looking to trade
- return "trade";
- case 6: //Looking to play
- return "play";*/
- //case 1: //Online
- default:
- return ID_STATUS_ONLINE;
- }
-}
-
-
-int CSteamProto::PollStatus(const char *sessionId, const char *steamId, UINT32 messageId)
+int CSteamProto::PollStatus(const char *token, const char *sessionId, UINT32 messageId)
{
SteamWebApi::PollApi::PollResult pollResult;
- SteamWebApi::PollApi::PollStatus(m_hNetlibUser, sessionId, steamId, messageId, &pollResult);
+ SteamWebApi::PollApi::PollStatus(m_hNetlibUser, token, sessionId, messageId, &pollResult);
if (!pollResult.IsSuccess())
return 0;
+ if (pollResult.IsNeedRelogin())
+ {
+ SteamWebApi::LoginApi::LoginResult loginResult;
+ SteamWebApi::LoginApi::Logon(m_hNetlibUser, token, &loginResult);
+
+ if (!loginResult.IsSuccess())
+ return 0;
+
+ return messageId;
+ }
+
for (int i = 0; i < pollResult.GetItemCount(); i++)
{
switch (pollResult[i]->GetType())
@@ -41,14 +28,73 @@ int CSteamProto::PollStatus(const char *sessionId, const char *steamId, UINT32 m
case SteamWebApi::PollApi::POOL_TYPE::MESSAGE:
{
- const wchar_t *text = ((SteamWebApi::PollApi::Message*)pollResult[i])->GetText();
+ SteamWebApi::PollApi::Message *message = (SteamWebApi::PollApi::Message*)pollResult[i];
+
+ MCONTACT hContact = FindContact(message->GetSteamId());
+ if (hContact)
+ {
+ const wchar_t *text = message->GetText();
+
+ PROTORECVEVENT recv = { 0 };
+ recv.flags = PREF_UTF;
+ recv.timestamp = message->GetTimestamp();
+ recv.szMessage = mir_utf8encodeW(text);
+
+ ProtoChainRecvMsg(hContact, &recv);
+ }
+ }
+ break;
+
+ case SteamWebApi::PollApi::POOL_TYPE::MYMESSAGE:
+ {
+ SteamWebApi::PollApi::Message *message = (SteamWebApi::PollApi::Message*)pollResult[i];
+
+ MCONTACT hContact = FindContact(message->GetSteamId());
+ if (hContact)
+ {
+ const wchar_t *text = message->GetText();
+
+ DBEVENTINFO dbei = { sizeof(dbei) };
+ dbei.szModule = this->m_szModuleName;
+ dbei.timestamp = message->GetTimestamp();
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.cbBlob = lstrlen(text);
+ dbei.pBlob = (BYTE*)mir_utf8encodeW(text);
+ dbei.flags = DBEF_UTF | DBEF_SENT;
+
+ db_event_add(hContact, &dbei);
+ }
}
break;
case SteamWebApi::PollApi::POOL_TYPE::STATE:
{
- int status = ((SteamWebApi::PollApi::State*)pollResult[i])->GetStatus();
- const wchar_t *nickname = ((SteamWebApi::PollApi::State*)pollResult[i])->GetNickname();
+ SteamWebApi::PollApi::State *state = (SteamWebApi::PollApi::State*)pollResult[i];
+
+ WORD status = CSteamProto::SteamToMirandaStatus(state->GetStatus());
+ const char *cSteamId = state->GetSteamId();
+ const wchar_t *nickname = state->GetNickname();
+
+ ptrA steamId(getStringA("SteamID"));
+ if (!lstrcmpA(steamId, cSteamId))
+ {
+ const wchar_t *oldNickname = getWStringA("Nick");
+ if (lstrcmp(oldNickname, nickname))
+ setWString("Nick", nickname);
+ SetStatus(status);
+
+ }
+ else
+ {
+ MCONTACT hContact = FindContact(cSteamId);
+ if (hContact)
+ {
+ const wchar_t *oldNickname = getWStringA(hContact, "Nick");
+ if (lstrcmp(oldNickname, nickname))
+ setWString(hContact, "Nick", nickname);
+ SetContactStatus(hContact, status);
+ }
+ }
}
break;
}