summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
authorRobert Pösel <robyer@seznam.cz>2015-12-20 05:38:13 +0000
committerRobert Pösel <robyer@seznam.cz>2015-12-20 05:38:13 +0000
commit1440e9da7b83bb649aff90af3cdfe9433416c988 (patch)
tree631b1ead3df9f2f793ef65b4ac199b42640c35be /protocols
parent3973fc0ef6292ab81d193a927f1e4cea4e447dfd (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')
-rw-r--r--protocols/Steam/src/api/search.h7
-rw-r--r--protocols/Steam/src/steam_contacts.cpp188
-rw-r--r--protocols/Steam/src/steam_proto.cpp25
-rw-r--r--protocols/Steam/src/steam_proto.h5
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);