#include "stdafx.h" #define STATUS_TITLE_MAX 64 #define STATUS_DESC_MAX 250 static std::vector xstatusIconsValid; static std::map 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) ? Skin_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 = Skin_GetIcon(iconName, (flags & LR_BIGICON) ? 32 : 16); 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::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); Skin_ReleaseIcon(hXStatusIcon); } } if (std::find(xstatusIconsValid.begin(), xstatusIconsValid.end(), status) != xstatusIconsValid.end()) { std::map::iterator it = xstatusIcons.find(status); if (it != xstatusIcons.end()) return ((INT_PTR) it->second & 0xFFFF) << 16; } } return -1; }