Merge 'remotes/trunk'
[0ad.git] / source / lobby / StanzaExtensions.cpp
blob98f27f4660037df8d7ab55914276dfe800a8bf77
1 /* Copyright (C) 2021 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
17 #include "precompiled.h"
18 #include "StanzaExtensions.h"
20 /******************************************************
21 * GameReport, fairly generic custom stanza extension used
22 * to report game statistics.
24 GameReport::GameReport(const glooxwrapper::Tag* tag)
25 : StanzaExtension(EXTGAMEREPORT)
27 if (!tag || tag->name() != "report" || tag->xmlns() != XMLNS_GAMEREPORT)
28 return;
29 // TODO if we want to handle receiving this stanza extension.
32 /**
33 * Required by gloox, used to serialize the GameReport into XML for sending.
35 glooxwrapper::Tag* GameReport::tag() const
37 glooxwrapper::Tag* t = glooxwrapper::Tag::allocate("report");
38 t->setXmlns(XMLNS_GAMEREPORT);
40 for (const glooxwrapper::Tag* const& tag : m_GameReport)
41 t->addChild(tag->clone());
43 return t;
46 /**
47 * Required by gloox, used to find the GameReport element in a recived IQ.
49 const glooxwrapper::string& GameReport::filterString() const
51 static const glooxwrapper::string filter = "/iq/report[@xmlns='" XMLNS_GAMEREPORT "']";
52 return filter;
55 glooxwrapper::StanzaExtension* GameReport::clone() const
57 GameReport* q = new GameReport();
58 return q;
61 /******************************************************
62 * BoardListQuery, a flexible custom IQ Stanza useful for anything with ratings, used to
63 * request and receive leaderboard and rating data from server.
64 * Example stanza:
65 * <board player="foobar">1200</board>
67 BoardListQuery::BoardListQuery(const glooxwrapper::Tag* tag)
68 : StanzaExtension(EXTBOARDLISTQUERY)
70 if (!tag || tag->name() != "query" || tag->xmlns() != XMLNS_BOARDLIST)
71 return;
73 const glooxwrapper::Tag* c = tag->findTag_clone("query/command");
74 if (c)
75 m_Command = c->cdata();
76 glooxwrapper::Tag::free(c);
77 for (const glooxwrapper::Tag* const& t : tag->findTagList_clone("query/board"))
78 m_StanzaBoardList.emplace_back(t);
81 /**
82 * Required by gloox, used to find the BoardList element in a received IQ.
84 const glooxwrapper::string& BoardListQuery::filterString() const
86 static const glooxwrapper::string filter = "/iq/query[@xmlns='" XMLNS_BOARDLIST "']";
87 return filter;
90 /**
91 * Required by gloox, used to serialize the BoardList request into XML for sending.
93 glooxwrapper::Tag* BoardListQuery::tag() const
95 glooxwrapper::Tag* t = glooxwrapper::Tag::allocate("query");
96 t->setXmlns(XMLNS_BOARDLIST);
98 // Check for ratinglist or boardlist command
99 if (!m_Command.empty())
100 t->addChild(glooxwrapper::Tag::allocate("command", m_Command));
102 for (const glooxwrapper::Tag* const& tag : m_StanzaBoardList)
103 t->addChild(tag->clone());
105 return t;
108 glooxwrapper::StanzaExtension* BoardListQuery::clone() const
110 BoardListQuery* q = new BoardListQuery();
111 return q;
114 BoardListQuery::~BoardListQuery()
116 for (const glooxwrapper::Tag* const& t : m_StanzaBoardList)
117 glooxwrapper::Tag::free(t);
118 m_StanzaBoardList.clear();
121 /******************************************************
122 * GameListQuery, custom IQ Stanza, used to receive
123 * the listing of games from the server, and register/
124 * unregister/changestate games on the server.
126 GameListQuery::GameListQuery(const glooxwrapper::Tag* tag)
127 : StanzaExtension(EXTGAMELISTQUERY)
129 if (!tag || tag->name() != "query" || tag->xmlns() != XMLNS_GAMELIST)
130 return;
132 const glooxwrapper::Tag* c = tag->findTag_clone("query/command");
133 if (c)
134 m_Command = c->cdata();
135 glooxwrapper::Tag::free(c);
137 for (const glooxwrapper::Tag* const& t : tag->findTagList_clone("query/game"))
138 m_GameList.emplace_back(t);
142 * Required by gloox, used to find the GameList element in a received IQ.
144 const glooxwrapper::string& GameListQuery::filterString() const
146 static const glooxwrapper::string filter = "/iq/query[@xmlns='" XMLNS_GAMELIST "']";
147 return filter;
151 * Required by gloox, used to serialize the game object into XML for sending.
153 glooxwrapper::Tag* GameListQuery::tag() const
155 glooxwrapper::Tag* t = glooxwrapper::Tag::allocate("query");
156 t->setXmlns(XMLNS_GAMELIST);
158 // Check for register / unregister command
159 if (!m_Command.empty())
160 t->addChild(glooxwrapper::Tag::allocate("command", m_Command));
162 for (const glooxwrapper::Tag* const& tag : m_GameList)
163 t->addChild(tag->clone());
165 return t;
168 glooxwrapper::StanzaExtension* GameListQuery::clone() const
170 GameListQuery* q = new GameListQuery();
171 return q;
174 GameListQuery::~GameListQuery()
176 for (const glooxwrapper::Tag* const & t : m_GameList)
177 glooxwrapper::Tag::free(t);
178 m_GameList.clear();
181 /******************************************************
182 * ProfileQuery, a custom IQ Stanza useful for fetching
183 * user profiles
184 * Example stanza:
185 * <profile player="foobar" highestRating="1500" rank="1895" totalGamesPlayed="50"
186 * wins="25" losses="25" /><command>foobar</command>
188 ProfileQuery::ProfileQuery(const glooxwrapper::Tag* tag)
189 : StanzaExtension(EXTPROFILEQUERY)
191 if (!tag || tag->name() != "query" || tag->xmlns() != XMLNS_PROFILE)
192 return;
194 const glooxwrapper::Tag* c = tag->findTag_clone("query/command");
195 if (c)
196 m_Command = c->cdata();
197 glooxwrapper::Tag::free(c);
199 for (const glooxwrapper::Tag* const& t : tag->findTagList_clone("query/profile"))
200 m_StanzaProfile.emplace_back(t);
204 * Required by gloox, used to find the Profile element in a received IQ.
206 const glooxwrapper::string& ProfileQuery::filterString() const
208 static const glooxwrapper::string filter = "/iq/query[@xmlns='" XMLNS_PROFILE "']";
209 return filter;
213 * Required by gloox, used to serialize the Profile request into XML for sending.
215 glooxwrapper::Tag* ProfileQuery::tag() const
217 glooxwrapper::Tag* t = glooxwrapper::Tag::allocate("query");
218 t->setXmlns(XMLNS_PROFILE);
220 if (!m_Command.empty())
221 t->addChild(glooxwrapper::Tag::allocate("command", m_Command));
223 for (const glooxwrapper::Tag* const& tag : m_StanzaProfile)
224 t->addChild(tag->clone());
226 return t;
229 glooxwrapper::StanzaExtension* ProfileQuery::clone() const
231 ProfileQuery* q = new ProfileQuery();
232 return q;
235 ProfileQuery::~ProfileQuery()
237 for (const glooxwrapper::Tag* const& t : m_StanzaProfile)
238 glooxwrapper::Tag::free(t);
239 m_StanzaProfile.clear();
242 /******************************************************
243 * LobbyAuth, a custom IQ Stanza, used to send and
244 * receive a security token for hosting authentication.
246 LobbyAuth::LobbyAuth(const glooxwrapper::Tag* tag)
247 : StanzaExtension(EXTLOBBYAUTH)
249 if (!tag || tag->name() != "auth" || tag->xmlns() != XMLNS_LOBBYAUTH)
250 return;
252 const glooxwrapper::Tag* c = tag->findTag_clone("auth/token");
253 if (c)
254 m_Token = c->cdata();
256 glooxwrapper::Tag::free(c);
260 * Required by gloox, used to find the LobbyAuth element in a received IQ.
262 const glooxwrapper::string& LobbyAuth::filterString() const
264 static const glooxwrapper::string filter = "/iq/auth[@xmlns='" XMLNS_LOBBYAUTH "']";
265 return filter;
269 * Required by gloox, used to serialize the auth object into XML for sending.
271 glooxwrapper::Tag* LobbyAuth::tag() const
273 glooxwrapper::Tag* t = glooxwrapper::Tag::allocate("auth");
274 t->setXmlns(XMLNS_LOBBYAUTH);
276 // Check for the auth token
277 if (!m_Token.empty())
278 t->addChild(glooxwrapper::Tag::allocate("token", m_Token));
279 return t;
282 glooxwrapper::StanzaExtension* LobbyAuth::clone() const
284 return new LobbyAuth();
287 /******************************************************
288 * ConnectionData, a custom IQ Stanza, used to send and
289 * receive a ip and port of the server.
291 ConnectionData::ConnectionData(const glooxwrapper::Tag* tag)
292 : StanzaExtension(EXTCONNECTIONDATA)
294 if (!tag || tag->name() != "connectiondata" || tag->xmlns() != XMLNS_CONNECTIONDATA)
295 return;
297 const glooxwrapper::Tag* c = tag->findTag_clone("connectiondata/ip");
298 if (c)
299 m_Ip = c->cdata();
300 const glooxwrapper::Tag* p= tag->findTag_clone("connectiondata/port");
301 if (p)
302 m_Port = p->cdata();
303 const glooxwrapper::Tag* pip = tag->findTag_clone("connectiondata/isLocalIP");
304 if (pip)
305 m_IsLocalIP = pip->cdata();
306 const glooxwrapper::Tag* s = tag->findTag_clone("connectiondata/useSTUN");
307 if (s)
308 m_UseSTUN = s->cdata();
309 const glooxwrapper::Tag* pw = tag->findTag_clone("connectiondata/password");
310 if (pw)
311 m_Password = pw->cdata();
312 const glooxwrapper::Tag* cs = tag->findTag_clone("connectiondata/clientsalt");
313 if (cs)
314 m_ClientSalt = cs->cdata();
315 const glooxwrapper::Tag* e = tag->findTag_clone("connectiondata/error");
316 if (e)
317 m_Error= e->cdata();
319 glooxwrapper::Tag::free(c);
320 glooxwrapper::Tag::free(p);
321 glooxwrapper::Tag::free(pip);
322 glooxwrapper::Tag::free(s);
323 glooxwrapper::Tag::free(pw);
324 glooxwrapper::Tag::free(cs);
325 glooxwrapper::Tag::free(e);
329 * Required by gloox, used to find the LobbyAuth element in a received IQ.
331 const glooxwrapper::string& ConnectionData::filterString() const
333 static const glooxwrapper::string filter = "/iq/connectiondata[@xmlns='" XMLNS_CONNECTIONDATA "']";
334 return filter;
338 * Required by gloox, used to serialize the auth object into XML for sending.
340 glooxwrapper::Tag* ConnectionData::tag() const
342 glooxwrapper::Tag* t = glooxwrapper::Tag::allocate("connectiondata");
343 t->setXmlns(XMLNS_CONNECTIONDATA);
345 if (!m_Ip.empty())
346 t->addChild(glooxwrapper::Tag::allocate("ip", m_Ip));
347 if (!m_Port.empty())
348 t->addChild(glooxwrapper::Tag::allocate("port", m_Port));
349 if (!m_IsLocalIP.empty())
350 t->addChild(glooxwrapper::Tag::allocate("isLocalIP", m_IsLocalIP));
351 if (!m_UseSTUN.empty())
352 t->addChild(glooxwrapper::Tag::allocate("useSTUN", m_UseSTUN));
353 if (!m_Password.empty())
354 t->addChild(glooxwrapper::Tag::allocate("password", m_Password));
355 if (!m_ClientSalt.empty())
356 t->addChild(glooxwrapper::Tag::allocate("clientsalt", m_ClientSalt));
357 if (!m_Error.empty())
358 t->addChild(glooxwrapper::Tag::allocate("error", m_Error));
359 return t;
362 glooxwrapper::StanzaExtension* ConnectionData::clone() const
364 return new ConnectionData();