The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
client.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2008 - 2025
3 by Iris Morelle <shadowm2006@gmail.com>
4 Copyright (C) 2003 - 2008 by David White <dave@whitevine.net>
5 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY.
13
14 See the COPYING file for more details.
15*/
16
17/**
18 * @file
19 * Networked add-ons (campaignd) client interface.
20 *
21 * This API revolves around the campaignd client functionality. It depends on
22 * the add-ons management and Asio network APIs.
23 */
24
25#pragma once
26
27#include "addon/info.hpp"
29#include "network_asio.hpp"
30
31#include <set>
32
33/**
34 * Add-ons (campaignd) client class.
35 *
36 * This class encapsulates much of the logic behind the campaignd
37 * add-ons server interaction for the client-side. Most networking
38 * operations with it are implemented here.
39 */
41{
42public:
43 struct invalid_server_address : public std::exception {};
44 struct not_connected_to_server : public std::exception {};
45 struct user_exit : public std::exception {};
46 struct user_disconnect : public std::exception {};
47
48 addons_client(const addons_client&) = delete;
50
51 /**
52 * Constructor.
53 *
54 * @param address Server address (e.g. "localhost:15999").
55 */
56 explicit addons_client(const std::string& address);
57
58 /**
59 * Tries to establish a connection to the add-ons server.
60 */
61 void connect();
62
63 /**
64 * Disconnects from the add-on server.
65 */
67 {
68 conn_.reset();
71 }
72
73 /** Returns the current hostname:port used for this connection. */
74 const std::string& addr() const { return addr_; }
75
76 /** Returns the last error message sent by the server, or an empty string. */
77 const std::string& get_last_server_error() const { return last_error_; }
78
79 /** Returns the last error message extra data sent by the server, or an empty string. */
80 const std::string& get_last_server_error_data() const { return last_error_data_; }
81
82 /** Returns true if the client is connected to the server. */
83 bool is_connected() { return conn_ != nullptr; }
84
85 /**
86 * Request the add-ons list from the server.
87 *
88 * @return @a true on success, @a false on failure. Retrieve the error message with @a get_last_server_error.
89 *
90 * @param cfg A config object whose contents are replaced with
91 * the server's list if available, cleared otherwise.
92 * @param icons Whether to have the add-ons server populate the icon
93 */
94 bool request_addons_list(config& cfg, bool icons);
95
96 std::map<std::string, int> get_addon_count_by_type();
97 config get_addon_downloads_by_version(const std::string& addon);
100 bool hide_addon(const std::string& addon, const std::string& username, const std::string& passphrase);
101 bool unhide_addon(const std::string& addon, const std::string& username, const std::string& passphrase);
102 config get_hidden_addons(const std::string& username, const std::string& passphrase);
103
104 /**
105 * Retrieves the add-ons server web URL if available.
106 */
107 const std::string& server_url() const
108 {
109 return server_url_;
110 }
111
112 /**
113 * Request the add-ons server distribution terms message.
114 */
115 bool request_distribution_terms(std::string& terms);
116
117 /**
118 * Installation outcome values.
119 */
121 {
122 /** The add-on was correctly installed. */
123 success,
124 /** The add-on could not be downloaded from the server. */
125 failure,
126 /** User aborted the operation because of an issue with dependencies or chose not to overwrite the add-on. */
127 abort,
128 };
129
130 /**
131 * Contains the outcome of an add-on install operation.
132 */
134 {
135 /**
136 * Overall outcome of the operation.
137 */
139
140 /**
141 * Specifies if WML on disk was altered and needs to be reloaded.
142 *
143 * @note Failure to install an add-on properly may not necessarily mean
144 * that WML on disk was left unchanged (e.g. if any dependencies were
145 * succesfully installed first.)
146 */
148 };
149
150 /**
151 * Performs an add-on download and install cycle.
152 *
153 * This checks and prompts the user through the UI before overwriting an
154 * existing add-on with a .pbl file or version control system files (.git/,
155 * .svn/, etc.). It also resolves add-on dependencies and downloads them
156 * using the same system before downloading the original target add-on.
157 *
158 * @param addons Add-ons list used for resolving dependencies.
159 * @param addon Identity of the singular add-on that will be
160 * downloaded.
161 *
162 * @return An install_result with the outcome of the operation.
163 */
165
166 /**
167 * Uploads an add-on to the server.
168 *
169 * This method reads the add-on upload passphrase and other data
170 * from the associated .pbl file. If the .pbl file doesn't have a
171 * passphrase, a new, random one will be automatically generated
172 * and written to the file for the user.
173 *
174 * @todo Notify the user about the automatic passphrase.
175 *
176 * @return @a true on success, @a false on failure. Retrieve the error message with @a get_last_server_error.
177 *
178 * @param id Id. of the add-on to upload.
179 * @param response_message The server response message on success, such as "add-on accepted".
180 * @param cfg The pbl config of the add-on with the specified id.
181 * @param local_only Whether the addon is not present on the server.
182 */
183 bool upload_addon(const std::string& id, std::string& response_message, config& cfg, bool local_only);
184
185 /**
186 * Requests the specified add-on to be removed from the server.
187 *
188 * This method reads the add-on upload passphrase from the associated
189 * .pbl file.
190 *
191 * @return @a true on success, @a false on failure. Retrieve the error message with @a get_last_server_error.
192 *
193 * @param id ID of the add-on to take down.
194 * @param response_message The server response message on success, such as "add-on accepted".
195 * @param admin_set The list of admin usernames as provided by the server, if doing an admin-restricted action
196 */
197 bool delete_remote_addon(const std::string& id, std::string& response_message, const std::set<std::string>& admin_set = {});
198
199 /**
200 * Returns whether the server supports the given named capability.
201 */
202 bool server_supports(const std::string& cap_id) const
203 {
204 return server_capabilities_.find(cap_id) != server_capabilities_.end();
205 }
206
207 /**
208 * Returns whether the server supports incremental (delta) downloads and uploads.
209 */
211 {
212 return server_supports("delta");
213 }
214
215 /**
216 * Returns whether the server supports passphrase authentication on an add-on basis.
217 */
219 {
220 return server_supports("auth:legacy");
221 }
222
223 /**
224 * Returns whether the current connection uses TLS.
225 */
226 bool using_tls() const
227 {
228 return conn_ && conn_->using_tls();
229 }
230
231 const std::string& server_id() const
232 {
233 return server_id_;
234 }
235
236 const std::string& server_version() const
237 {
238 return server_version_;
239 }
240
241private:
243
244 std::string addr_;
245 std::string host_;
246 std::string port_;
247 std::unique_ptr<network_asio::connection> conn_;
248 std::string last_error_;
249 std::string last_error_data_;
250
251 std::string server_id_;
252 std::string server_version_;
253 std::set<std::string> server_capabilities_;
254 std::string server_url_;
255 std::string license_notice_;
256
257 /**
258 * Downloads the specified add-on from the server.
259 *
260 * @return @a true on success, @a false on failure. Retrieve the error message with @a get_last_server_error.
261 *
262 * @param archive_cfg Config object to hold the downloaded add-on archive data.
263 * @param id Add-on id.
264 * @param title Add-on title, used for status display.
265 * @param version Specifies an add-on version to download.
266 * @param increase_downloads Whether to request the server to increase the add-on's
267 * download count or not (e.g. when upgrading).
268 */
269 bool download_addon(config& archive_cfg, const std::string& id, const std::string& title, const version_info& version, bool increase_downloads = true);
270
271 /**
272 * Installs the specified add-on using an archive received from the server.
273 *
274 * An _info.cfg file will be added to the local directory for the add-on
275 * to keep track of version and dependency information.
276 */
277 bool install_addon(config& archive_cfg, const addon_info& info);
278
279 // Asks the client to download and install an addon, reporting errors in a gui dialog. Returns true if new content was installed, false otherwise.
280 bool try_fetch_addon(const addon_info& addon);
281
282 /**
283 * Warns the user about unresolved dependencies and installs them if they choose to do so.
284 * Returns: outcome: abort in case the user chose to abort because of an issue
285 * success otherwise
286 * wml_change: indicates if new wml content was installed
287 */
289
290 /** Checks whether the given add-on has local .pbl or VCS information and asks before overwriting it. */
292
293 /** Makes sure the add-ons server connection is working. */
294 void check_connected() const;
295
296 /**
297 * Sends a request to the add-ons server.
298 *
299 * @note This is an asynchronous operation. @a display_status_window
300 * should be called afterwards to wait for it to finish.
301 *
302 * @param request The client request WML.
303 * @param response A config object whose contents are replaced
304 * with the server response WML.
305 */
306 void send_request(const config& request, config& response);
307
308 /**
309 * Sends a simple request message to the add-ons server.
310 *
311 * The real request sent consists of a WML object with an empty
312 * child node whose name corresponds to @a request_string
313 *
314 * @note This is an asynchronous operation. @a display_status_window
315 * should be called afterwards to wait for it to finish.
316 *
317 * @param request_string The client request string.
318 * @param response A config object whose contents are replaced
319 * with the server response WML.
320 */
321 void send_simple_request(const std::string& request_string, config& response);
322
323 /**
324 * Waits for a network transfer, displaying a status window.
325 *
326 * The window is displayed with the specified contents. This
327 * method doesn't return until the network transfer is complete. It
328 * will throw a @a user_exit exception if the user cancels the
329 * transfer by canceling the status window.
330 */
331 void wait_for_transfer_done(const std::string& status_message, transfer_mode mode = transfer_mode::download);
332
333 /**
334 * If the response has the [error] child, then check for the status_code attribute.
335 * If the error response has the status_code attribute, then the status_code attribute is assigned to last_error_, else the message attribute is assigned to last_error_.
336 * If the error response doesn't have the status_code attribute, then assign the message attribute to last_error.
337 * Also assign the error response's extra_data attribute to last_error_data_.
338 * If there is no [error] child, then clear last_error_ and last_error_data_.
339 *
340 * @param response_cfg The config returned by the add-ons server.
341 * @return true if response_cfg had an [error] child, false otherwise.
342 */
343 bool is_error_response(const config& response_cfg);
344
345 void clear_last_error();
346
347 void clear_server_info();
348};
Add-ons (campaignd) client class.
Definition client.hpp:41
std::map< std::string, int > get_addon_count_by_type()
Definition client.cpp:115
std::string addr_
Definition client.hpp:244
void disconnect()
Disconnects from the add-on server.
Definition client.hpp:66
install_result install_addon_with_checks(const addons_list &addons, const addon_info &addon)
Performs an add-on download and install cycle.
Definition client.cpp:725
bool is_connected()
Returns true if the client is connected to the server.
Definition client.hpp:83
bool unhide_addon(const std::string &addon, const std::string &username, const std::string &passphrase)
Definition client.cpp:233
bool do_check_before_overwriting_addon(const addon_info &addon)
Checks whether the given add-on has local .pbl or VCS information and asks before overwriting it.
Definition client.cpp:692
const std::string & server_version() const
Definition client.hpp:236
void wait_for_transfer_done(const std::string &status_message, transfer_mode mode=transfer_mode::download)
Waits for a network transfer, displaying a status window.
Definition client.cpp:844
config get_forum_auth_usage()
Definition client.cpp:157
const std::string & get_last_server_error_data() const
Returns the last error message extra data sent by the server, or an empty string.
Definition client.hpp:80
std::unique_ptr< network_asio::connection > conn_
Definition client.hpp:247
const std::string & server_url() const
Retrieves the add-ons server web URL if available.
Definition client.hpp:107
install_outcome
Installation outcome values.
Definition client.hpp:121
@ success
The add-on was correctly installed.
@ failure
The add-on could not be downloaded from the server.
@ abort
User aborted the operation because of an issue with dependencies or chose not to overwrite the add-on...
std::string port_
Definition client.hpp:246
bool download_addon(config &archive_cfg, const std::string &id, const std::string &title, const version_info &version, bool increase_downloads=true)
Downloads the specified add-on from the server.
Definition client.cpp:470
void send_request(const config &request, config &response)
Sends a request to the add-ons server.
Definition client.cpp:794
bool try_fetch_addon(const addon_info &addon)
Definition client.cpp:565
std::string server_url_
Definition client.hpp:254
config get_addon_downloads_by_version(const std::string &addon)
Definition client.cpp:138
bool hide_addon(const std::string &addon, const std::string &username, const std::string &passphrase)
Definition client.cpp:213
std::string host_
Definition client.hpp:245
void check_connected() const
Makes sure the add-ons server connection is working.
Definition client.cpp:785
std::set< std::string > server_capabilities_
Definition client.hpp:253
std::string server_id_
Definition client.hpp:251
bool install_addon(config &archive_cfg, const addon_info &info)
Installs the specified add-on using an archive received from the server.
Definition client.cpp:493
config get_hidden_addons(const std::string &username, const std::string &passphrase)
Definition client.cpp:193
bool delete_remote_addon(const std::string &id, std::string &response_message, const std::set< std::string > &admin_set={})
Requests the specified add-on to be removed from the server.
Definition client.cpp:417
std::string license_notice_
Definition client.hpp:255
bool using_tls() const
Returns whether the current connection uses TLS.
Definition client.hpp:226
void clear_last_error()
Definition client.cpp:770
std::string last_error_
Definition client.hpp:248
bool server_supports_delta() const
Returns whether the server supports incremental (delta) downloads and uploads.
Definition client.hpp:210
addons_client(const addons_client &)=delete
const std::string & server_id() const
Definition client.hpp:231
bool server_supports_legacy_auth() const
Returns whether the server supports passphrase authentication on an add-on basis.
Definition client.hpp:218
std::string last_error_data_
Definition client.hpp:249
addons_client & operator=(const addons_client &)=delete
std::string server_version_
Definition client.hpp:252
void connect()
Tries to establish a connection to the add-ons server.
Definition client.cpp:69
void send_simple_request(const std::string &request_string, config &response)
Sends a simple request message to the add-ons server.
Definition client.cpp:802
bool is_error_response(const config &response_cfg)
If the response has the [error] child, then check for the status_code attribute.
Definition client.cpp:751
config get_addon_admins()
Definition client.cpp:175
const std::string & addr() const
Returns the current hostname:port used for this connection.
Definition client.hpp:74
bool request_distribution_terms(std::string &terms)
Request the add-ons server distribution terms message.
Definition client.cpp:274
install_result do_resolve_addon_dependencies(const addons_list &addons, const addon_info &addon)
Warns the user about unresolved dependencies and installs them if they choose to do so.
Definition client.cpp:585
void clear_server_info()
Definition client.cpp:776
bool request_addons_list(config &cfg, bool icons)
Request the add-ons list from the server.
Definition client.cpp:253
bool upload_addon(const std::string &id, std::string &response_message, config &cfg, bool local_only)
Uploads an add-on to the server.
Definition client.cpp:297
const std::string & get_last_server_error() const
Returns the last error message sent by the server, or an empty string.
Definition client.hpp:77
bool server_supports(const std::string &cap_id) const
Returns whether the server supports the given named capability.
Definition client.hpp:202
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
Represents version numbers.
const config * cfg
std::map< std::string, addon_info > addons_list
Definition info.hpp:28
Contains the outcome of an add-on install operation.
Definition client.hpp:134
install_outcome outcome
Overall outcome of the operation.
Definition client.hpp:138
bool wml_changed
Specifies if WML on disk was altered and needs to be reloaded.
Definition client.hpp:147