diff options
author | Robert Pösel <robyer@seznam.cz> | 2015-12-20 05:38:13 +0000 |
---|---|---|
committer | Robert Pösel <robyer@seznam.cz> | 2015-12-20 05:38:13 +0000 |
commit | 1440e9da7b83bb649aff90af3cdfe9433416c988 (patch) | |
tree | 631b1ead3df9f2f793ef65b4ac199b42640c35be /protocols/Steam/src | |
parent | 3973fc0ef6292ab81d193a927f1e4cea4e447dfd (diff) |
Steam: Implement searching by keywords
Like by name or nickname, but it doesn't matter in which input user writes the text, it is searched as a whole combined string separated by spaces.
git-svn-id: http://svn.miranda-ng.org/main/trunk@15908 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/Steam/src')
-rw-r--r-- | protocols/Steam/src/api/search.h | 7 | ||||
-rw-r--r-- | protocols/Steam/src/steam_contacts.cpp | 188 | ||||
-rw-r--r-- | protocols/Steam/src/steam_proto.cpp | 25 | ||||
-rw-r--r-- | protocols/Steam/src/steam_proto.h | 5 |
4 files changed, 125 insertions, 100 deletions
diff --git a/protocols/Steam/src/api/search.h b/protocols/Steam/src/api/search.h index ed1b0420eb..e9e9691cc1 100644 --- a/protocols/Steam/src/api/search.h +++ b/protocols/Steam/src/api/search.h @@ -4,13 +4,14 @@ class SearchRequest : public HttpRequest
{
public:
- SearchRequest(const char *token, const char *text) :
+ SearchRequest(const char *token, const char *text, int offset = 0, int count = 30) :
HttpRequest(REQUEST_GET, STEAM_API_URL "/ISteamUserOAuth/Search/v0001")
{
AddParameter("access_token", token);
AddParameter("keywords", ptrA(mir_urlEncode(text)));
- // todo: may need to load all results (15 first at now)
- AddParameter("offset=0&count=15&targets=users&fields=all");
+ AddParameter("offset=%d", offset);
+ AddParameter("count=%d", count);
+ AddParameter("targets=users&fields=all");
}
};
diff --git a/protocols/Steam/src/steam_contacts.cpp b/protocols/Steam/src/steam_contacts.cpp index 9026c9e17b..9126b9f0ac 100644 --- a/protocols/Steam/src/steam_contacts.cpp +++ b/protocols/Steam/src/steam_contacts.cpp @@ -701,123 +701,129 @@ void CSteamProto::OnPendingIgnoreded(const HttpResponse *response, void *arg) } } -void CSteamProto::OnSearchByIdEnded(const HttpResponse *response, void *arg) +void CSteamProto::OnSearchResults(const HttpResponse *response, void *arg) { + HANDLE searchType = (HANDLE)arg; + if (!ResponseHttpOk(response)) { - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE)STEAM_SEARCH_BYID, 0); - debugLog(_T("CSteamProto::OnSearchByIdEnded: failed to get summaries for %s"), (TCHAR*)arg); + ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, searchType, 0); + debugLogA("CSteamProto::AddSearchResults: failed to get summaries"); return; } JSONROOT root(response->pData); if (root == NULL) { - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE)STEAM_SEARCH_BYID, 0); + ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, searchType, 0); return; } JSONNode *node = json_get(root, "players"); - JSONNode *nodes = json_as_array(node); - JSONNode *nroot = json_at(nodes, 0); - + JSONNode *nroot = json_as_array(node); if (nroot != NULL) { - STEAM_SEARCH_RESULT ssr = { 0 }; - ssr.hdr.cbSize = sizeof(STEAM_SEARCH_RESULT); - ssr.hdr.flags = PSR_TCHAR; - - ssr.hdr.id.t = (TCHAR*)arg; + for (size_t i = 0; i < json_size(nroot); i++) + { + JSONNode *child = json_at(nroot, i); + if (child == NULL) + break; - node = json_get(nroot, "personaname"); - ssr.hdr.nick.t = mir_wstrdup(ptrT(json_as_string(node))); + STEAM_SEARCH_RESULT ssr = { 0 }; + ssr.hdr.cbSize = sizeof(STEAM_SEARCH_RESULT); + ssr.hdr.flags = PSR_TCHAR; - node = json_get(nroot, "realname"); - if (node != NULL) - { - std::wstring realname = (TCHAR*)ptrT(json_as_string(node)); - if (!realname.empty()) + node = json_get(child, "steamid"); + ssr.hdr.id.t = mir_tstrdup(ptrT(json_as_string(node))); + + node = json_get(child, "personaname"); + ssr.hdr.nick.t = mir_tstrdup(ptrT(json_as_string(node))); + + node = json_get(child, "realname"); + if (node != NULL) { - size_t pos = realname.find(' ', 1); - if (pos != std::string::npos) + std::wstring realname = (TCHAR*)ptrT(json_as_string(node)); + if (!realname.empty()) { - ssr.hdr.firstName.t = mir_wstrdup(realname.substr(0, pos).c_str()); - ssr.hdr.lastName.t = mir_wstrdup(realname.substr(pos + 1).c_str()); + size_t pos = realname.find(' ', 1); + if (pos != std::wstring::npos) + { + ssr.hdr.firstName.t = mir_wstrdup(realname.substr(0, pos).c_str()); + ssr.hdr.lastName.t = mir_wstrdup(realname.substr(pos + 1).c_str()); + } + else + ssr.hdr.firstName.t = mir_wstrdup(realname.c_str()); } - else - ssr.hdr.firstName.t = mir_wstrdup(realname.c_str()); } - } - - //ssr.contact = contact; - ssr.data = json_copy(nroot); - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)STEAM_SEARCH_BYID, (LPARAM)&ssr); + //ssr.contact = contact; + ssr.data = json_copy(child); // FIXME: is this needed and safe (no memleak) to be here? + + ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, searchType, (LPARAM)&ssr); + } } - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)STEAM_SEARCH_BYID, 0); + ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, searchType, 0); - json_delete(nodes); + json_delete(nroot); } -void CSteamProto::OnSearchByNameStarted(const HttpResponse *, void *) +void CSteamProto::OnSearchByNameStarted(const HttpResponse *response, void *arg) { -} + if (!ResponseHttpOk(response)) + { + ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE)arg, 0); + debugLogA("CSteamProto::OnSearchByNameEnded: failed to get results"); + return; + } + + JSONROOT root(response->pData); + if (root == NULL) + { + ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE)arg, 0); + return; + } + + // JSONNode *count = json_get(root, "count"); // number of results given in this request + // JSONNode *total = json_get(root, "total"); // number of all search results + // TODO: may need to load all remaining results, but we need to remember our previous offset and then increment it and cycle with results -//void CSteamProto::SearchByNameThread(void* arg) -//{ -// ptrW keywordsW((wchar_t*)arg); -// ptrA keywords(mir_utf8encodeW(keywordsW)); -// -// ptrA token(getStringA("TokenSecret")); -// -// SearchApi::SearchResult searchResult; -// debugLogA("CSteamProto::SearchByNameThread: call SearchApi::Search"); -// SearchApi::Search(m_hNetlibUser, token, keywords, &searchResult); -// -// if (!searchResult.IsSuccess()) -// { -// ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE)STEAM_SEARCH_BYNAME, 0); -// return; -// } -// -// CMStringA steamIds; -// for (int i = 0; i < searchResult.GetItemCount(); i++) -// { -// const SearchApi::SearchItem *item = searchResult.GetAt(i); -// if (steamIds.IsEmpty()) -// steamIds.Append(item->GetSteamId()); -// else -// steamIds.AppendFormat(",%s", item->GetSteamId()); -// } -// -// FriendApi::Summaries summarues; -// debugLogA("CSteamProto::SearchByNameThread: call FriendApi::LoadSummaries"); -// FriendApi::LoadSummaries(m_hNetlibUser, token, steamIds, &summarues); -// -// if (!summarues.IsSuccess()) -// { -// ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE)STEAM_SEARCH_BYNAME, 0); -// return; -// } -// -// for (size_t i = 0; i < summarues.GetItemCount(); i++) -// { -// const FriendApi::Summary *contact = summarues.GetAt(i); -// -// STEAM_SEARCH_RESULT ssr = { 0 }; -// ssr.hdr.cbSize = sizeof(STEAM_SEARCH_RESULT); -// ssr.hdr.flags = PSR_TCHAR; -// -// ssr.hdr.id = mir_a2u(contact->GetSteamId()); -// ssr.hdr.nick = mir_wstrdup(contact->GetNickName()); -// ssr.hdr.firstName = mir_wstrdup(contact->GetFirstName()); -// ssr.hdr.lastName = mir_wstrdup(contact->GetLastName()); -// -// ssr.contact = contact; -// -// ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)STEAM_SEARCH_BYNAME, (LPARAM)&ssr); -// } -// -// ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)STEAM_SEARCH_BYNAME, 0); -//}
\ No newline at end of file + std::string steamIds; + + JSONNode *node = json_get(root, "results"); + JSONNode *nroot = json_as_array(node); + if (nroot != NULL) + { + for (size_t i = 0; i < json_size(nroot); i++) + { + JSONNode *child = json_at(nroot, i); + if (child == NULL) + break; + + node = json_get(child, "steamid"); + if (node == NULL) + continue; + + std::string steamId = (char*)_T2A(ptrT(json_as_string(node))); + steamIds.append(steamId).append(","); + } + json_delete(nroot); + } + + if (!steamIds.empty()) + { + // remove trailing "," + steamIds.pop_back(); + + ptrA token(getStringA("TokenSecret")); + + PushRequest( + new GetUserSummariesRequest(token, steamIds.c_str()), + &CSteamProto::OnSearchResults, + (HANDLE)arg); + } + else + { + ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)arg, 0); + } +} diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp index 4d6da4e763..8644f9fa50 100644 --- a/protocols/Steam/src/steam_proto.cpp +++ b/protocols/Steam/src/steam_proto.cpp @@ -231,13 +231,32 @@ HANDLE CSteamProto::SearchBasic(const TCHAR* id) PushRequest( new GetUserSummariesRequest(token, steamId), - &CSteamProto::OnSearchByIdEnded, - mir_tstrdup(id), - MirFreeArg); + &CSteamProto::OnSearchResults, + (HANDLE)STEAM_SEARCH_BYID); return (HANDLE)STEAM_SEARCH_BYID; } +HANDLE CSteamProto::SearchByName(const TCHAR* nick, const TCHAR* firstName, const TCHAR* lastName) +{ + if (!this->IsOnline()) + return 0; + + // Combine all fields to single text + TCHAR keywordsT[200]; + mir_sntprintf(keywordsT, _T("%s %s %s"), nick, firstName, lastName); + + ptrA token(getStringA("TokenSecret")); + ptrA keywords(mir_utf8encodeW(keywordsT)); + + PushRequest( + new SearchRequest(token, keywords), + &CSteamProto::OnSearchByNameStarted, + (HANDLE)STEAM_SEARCH_BYNAME); + + return (HANDLE)STEAM_SEARCH_BYNAME; +} + int CSteamProto::SendMsg(MCONTACT hContact, int, const char *message) { if (!IsOnline()) diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h index f30c4aa90c..2784377976 100644 --- a/protocols/Steam/src/steam_proto.h +++ b/protocols/Steam/src/steam_proto.h @@ -52,6 +52,7 @@ public: virtual DWORD_PTR __cdecl GetCaps(int type, MCONTACT hContact = NULL);
virtual HANDLE __cdecl SearchBasic(const TCHAR *id);
+ virtual HANDLE __cdecl SearchByName(const TCHAR* nick, const TCHAR* firstName, const TCHAR* lastName);
virtual int __cdecl SendMsg(MCONTACT hContact, int flags, const char* msg);
@@ -151,10 +152,8 @@ protected: void OnPendingApproved(const HttpResponse *response, void *arg);
void OnPendingIgnoreded(const HttpResponse *response, void *arg);
- void OnSearchByIdEnded(const HttpResponse *response, void *arg);
-
+ void OnSearchResults(const HttpResponse *response, void *arg);
void OnSearchByNameStarted(const HttpResponse *response, void *arg);
- void OnSearchByNameFinished(const HttpResponse *response, void *arg);
// messages
int OnSendMessage(MCONTACT hContact, const char* message);
|