1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
#include "stdafx.h"
#define STATUS_TITLE_MAX 64
#define STATUS_DESC_MAX 250
static std::vector<int> xstatusIconsValid;
static std::map<int, int> xstatusIcons;
int OnReloadIcons(WPARAM, LPARAM)
{
xstatusIconsValid.clear();
return 0;
}
int CSteamProto::GetContactXStatus(MCONTACT hContact)
{
return getDword(hContact, "XStatusId", 0) ? 1 : 0;
}
void SetContactExtraIcon(MCONTACT hContact, int status)
{
char iconName[100];
mir_snprintf(iconName, SIZEOF(iconName), "%s_%s", MODULE, "gaming");
ExtraIcon_SetIcon(hExtraXStatus, hContact, (status > 0) ? IcoLib_GetIconHandle(iconName) : NULL);
}
INT_PTR CSteamProto::OnGetXStatusEx(WPARAM wParam, LPARAM lParam)
{
MCONTACT hContact = (MCONTACT)wParam;
CUSTOM_STATUS *pData = (CUSTOM_STATUS*)lParam;
if (pData->cbSize < sizeof(CUSTOM_STATUS))
return 1;
// fill status member
if (pData->flags & CSSF_MASK_STATUS)
*pData->status = GetContactXStatus(hContact);
// fill status name member
if (pData->flags & CSSF_MASK_NAME)
{
int status = (pData->wParam == NULL) ? GetContactXStatus(hContact) : *pData->wParam;
if (status < 1)
return 1;
ptrT title;
if (pData->flags & CSSF_DEFAULT_NAME)
title = mir_tstrdup(TranslateT("Playing"));
else
title = getTStringA(hContact, "XStatusName");
if (pData->flags & CSSF_UNICODE)
mir_tstrncpy(pData->ptszName, title, STATUS_TITLE_MAX);
else
mir_strncpy(pData->pszName, _T2A(title), STATUS_TITLE_MAX);
}
// fill status message member
if (pData->flags & CSSF_MASK_MESSAGE) {
ptrT message(getTStringA(hContact, "XStatusMsg"));
if (pData->flags & CSSF_UNICODE)
mir_tstrncpy(pData->ptszMessage, message, STATUS_DESC_MAX);
else
mir_strncpy(pData->pszMessage, _T2A(message), STATUS_DESC_MAX);
}
// disable menu
if (pData->flags & CSSF_DISABLE_MENU)
if (pData->wParam)
*pData->wParam = true;
// disable ui
if (pData->flags & CSSF_DISABLE_UI)
if (pData->wParam)
*pData->wParam = true;
// number of xstatuses
if (pData->flags & CSSF_STATUSES_COUNT)
if (pData->wParam)
*pData->wParam = 1; // TODO: how to solve unknown count of games?
// data sizes
if (pData->flags & CSSF_STR_SIZES) {
if (pData->wParam) *pData->wParam = STATUS_TITLE_MAX;
if (pData->lParam) *pData->lParam = STATUS_DESC_MAX;
}
return 0;
}
HICON CSteamProto::GetXStatusIcon(int status, UINT flags)
{
if (status < 1)
return 0;
char iconName[100];
mir_snprintf(iconName, SIZEOF(iconName), "%s_%s", MODULE, "gaming");
HICON icon = IcoLib_GetIcon(iconName, (flags & LR_BIGICON) != 0);
return (flags & LR_SHARED) ? icon : CopyIcon(icon);
}
INT_PTR CSteamProto::OnGetXStatusIcon(WPARAM wParam, LPARAM lParam)
{
if (!wParam)
wParam = GetContactXStatus(NULL);
if (wParam < 1)
return 0;
return (INT_PTR)GetXStatusIcon(wParam, lParam);
}
INT_PTR CSteamProto::OnRequestAdvStatusIconIdx(WPARAM wParam, LPARAM)
{
int status = GetContactXStatus(wParam);
if (status)
{
if (std::find(xstatusIconsValid.begin(), xstatusIconsValid.end(), status) == xstatusIconsValid.end())
{
// adding/updating icon
HIMAGELIST clistImageList = (HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0);
if (clistImageList)
{
HICON hXStatusIcon = GetXStatusIcon(status, LR_SHARED);
std::map<int, int>::iterator it = xstatusIcons.find(status);
if (it != xstatusIcons.end() && it->second > 0)
ImageList_ReplaceIcon(clistImageList, it->first, hXStatusIcon);
else
xstatusIcons.insert(std::make_pair(status, ImageList_AddIcon(clistImageList, hXStatusIcon)));
// mark icon index in the array as valid
xstatusIconsValid.push_back(status);
IcoLib_ReleaseIcon(hXStatusIcon);
}
}
if (std::find(xstatusIconsValid.begin(), xstatusIconsValid.end(), status) != xstatusIconsValid.end())
{
std::map<int, int>::iterator it = xstatusIcons.find(status);
if (it != xstatusIcons.end())
return ((INT_PTR) it->second & 0xFFFF) << 16;
}
}
return -1;
}
|