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