The Battle for Wesnoth  1.19.7+dev
game.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2024
3  by David White <dave@whitevine.net>
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 #pragma once
17 
18 #include "mt_rng.hpp"
21 #include "side_controller.hpp"
22 
23 #include "utils/optional_fwd.hpp"
24 
25 #include <vector>
26 
27 // class player;
28 
29 namespace wesnothd
30 {
31 typedef std::vector<player_iterator> user_vector;
32 typedef std::vector<utils::optional<player_iterator>> side_vector;
33 class server;
34 
35 class game
36 {
37 public:
39  player_iterator host,
40  const std::string& name = "",
41  bool save_replays = false,
42  const std::string& replay_save_path = "");
43 
44  ~game();
45 
46  /**
47  * This ID is reused between scenarios of MP campaigns.
48  * This ID resets when wesnothd is restarted.
49  * This is generally used when needing to find a particular running game.
50  * @return an ID that uniquely identifies the game within the currently running wesnothd instance.
51  */
52  int id() const
53  {
54  return id_;
55  }
56 
57  /**
58  * This ID is not reused between scenarios of MP campaigns.
59  * This ID resets when wesnothd is restarted.
60  * This is generally used during database queries.
61  *
62  * @return an ID that uniquely identifies the game within the currently running wesnothd instance.
63  */
64  int db_id() const
65  {
66  return db_id_;
67  }
68 
69  /**
70  * Increments the ID used when running database queries.
71  */
72  void next_db_id()
73  {
74  db_id_ = db_id_num++;
75  }
76 
77  /**
78  * @return The game's name.
79  */
80  const std::string& name() const
81  {
82  return name_;
83  }
84 
85  /**
86  * @param player The player being checked.
87  * @return Whether the provided player is the game's owner(host).
88  */
90  {
91  return (player == owner_);
92  }
93 
94  /**
95  * @param player The player being checked.
96  * @return Whether the provided player has joined the game.
97  */
99  {
100  return is_player(player) || is_observer(player);
101  }
102 
103  /**
104  * @return Whether observers are allowed to join.
105  */
106  bool allow_observers() const;
107 
108  /**
109  * @param player The player being checked.
110  * @return Whether the provided player is an observer of this game.
111  */
112  bool is_observer(player_iterator player) const;
113 
114  /**
115  * @param player The player being checked.
116  * @return Whether the provided player is playing this game (aka owns one or more sides).
117  */
118  bool is_player(player_iterator player) const;
119 
120  /**
121  * @param player The player being checked (by iterator).
122  * @param name The player being checked (by username).
123  * @return Whether the connection's ip address or username is banned from this game.
124  */
125  bool player_is_banned(player_iterator player, const std::string& name) const;
126 
127  /**
128  * When the host sends the new scenario of a mp campaign
129  *
130  * @param sender The player sending the scenario data.
131  */
132  void new_scenario(player_iterator sender);
133 
134  /**
135  * @return Whether this game contains scenario data and thus has been initialized.
136  */
137  bool level_init() const
138  {
139  return level_.child("snapshot") || level_.child("scenario");
140  }
141 
142  /**
143  * The non-const version.
144  *
145  * @param data The data describing the level for a game.
146  * @return The [scenario] child node if it exists, else the [snapshot] child if it exists, else @a data.
147  */
149  {
150  if(simple_wml::node* scenario = data.child("scenario")) {
151  return scenario;
152  } else if(simple_wml::node* snapshot = data.child("snapshot")) {
153  return snapshot;
154  }
155 
156  return &data;
157  }
158 
159  /**
160  * The const version.
161  *
162  * @param data The data describing the level for a game.
163  * @return The [scenario] child node if it exists, else the [snapshot] child if it exists, else @a data.
164  */
166  {
167  if(const simple_wml::node* scenario = data.child("scenario")) {
168  return scenario;
169  } else if(const simple_wml::node* snapshot = data.child("snapshot")) {
170  return snapshot;
171  }
172 
173  return &data;
174  }
175 
176  /**
177  * @return The nodes containing the sides in this game.
178  */
180  {
181  return starting_pos(level_.root())->children("side");
182  }
183 
184  /**
185  * @return Whether this game has started yet.
186  */
187  bool started() const
188  {
189  return started_;
190  }
191 
192  /**
193  * @return The number of players. One player can have multiple sides.
194  */
195  std::size_t nplayers() const
196  {
197  return players_.size();
198  }
199 
200  /**
201  * @return The number of observers in this game.
202  */
203  std::size_t nobservers() const
204  {
205  return observers_.size();
206  }
207 
208  /**
209  * @return This game's current turn.
210  */
211  std::size_t current_turn() const
212  {
213  return current_turn_;
214  }
215 
216  /**
217  * @return The name of the replay for this game.
218  */
219  std::string get_replay_filename();
220 
221  /** Toggles whether all observers are muted or not. */
222  void mute_all_observers();
223 
224  /**
225  * Mute an observer or give a message of all currently muted observers if no name is given.
226  *
227  * @param mute The observer to mute. Empty if sending a message to muted observers.
228  * @param muter The player doing the muting.
229  */
230  void mute_observer(const simple_wml::node& mute, player_iterator muter);
231 
232  /**
233  * Unmute an observer or unmute all currently muted observers if no name is given.
234  *
235  * @param unmute The observer to unmute. Empty if unmuting all observers.
236  * @param unmuter The player doing the unmuting.
237  */
238  void unmute_observer(const simple_wml::node& unmute, player_iterator unmuter);
239 
240  /**
241  * Kick a user from this game by name.
242  *
243  * @param kick The user to kick.
244  * @param kicker The player doing the kicking.
245  * @return The iterator to the removed member if successful, empty optional otherwise.
246  */
247  utils::optional<player_iterator> kick_member(const simple_wml::node& kick, player_iterator kicker);
248 
249  /**
250  * Ban a user by name.
251  *
252  * The user does not need to be in this game but logged in.
253  *
254  * @param ban The user to ban.
255  * @param banner The player doing the banning.
256  * @return The iterator to the banned player if he was in this game, empty optional otherwise.
257  */
258  utils::optional<player_iterator> ban_user(const simple_wml::node& ban, player_iterator banner);
259 
260  /**
261  * Unban a user by name.
262  *
263  * The user does not need to be in this game but logged in.
264  *
265  * @param unban The user to unban.
266  * @param unbanner The player doing the unbanning.
267  */
268  void unban_user(const simple_wml::node& unban, player_iterator unbanner);
269 
270  /**
271  * Add a user to the game.
272  *
273  * @todo differentiate between "observers not allowed" and "player already in the game" errors.
274  * maybe return a string with an error message.
275  *
276  * @param player The player to add.
277  * @param observer Whether to add the player as an observer.
278  * @return True if the user successfully joined the game, false otherwise.
279  */
280  bool add_player(player_iterator player, bool observer = false);
281 
282  /**
283  * Removes a user from the game.
284  *
285  * @param player The player to remove.
286  * @param disconnect If the player disconnected from the server entirely.
287  * @param destruct If the game is ending as well.
288  * @return True if the player's removal ends the game. That is, if there are no more players or the host left on a not yet started game.
289  */
290  bool remove_player(player_iterator player, const bool disconnect = false, const bool destruct = false);
291 
292  /**
293  * @return A vector containing all players and observers currently in this game.
294  */
295  const user_vector all_game_users() const;
296 
297  /**
298  * Starts the game (if a new game) or starts the next scenario of an MP campaign.
299  * @param starter The game's host.
300  */
301  void start_game(player_iterator starter);
302 
303  /**
304  * This is performed just before starting and before the [start_game] signal.
305  * Sends [scenario_diff]s specific to each client so that they locally control their human sides.
306  */
308 
309  /**
310  * A user asks for the next scenario to advance to.
311  *
312  * @param user The user asking for the next scenario.
313  */
315 
316  /** Resets the side configuration according to the scenario data. */
317  void update_side_data();
318 
319  /**
320  * Lets a player owning a side give it to another player or observer.
321  *
322  * @param player The player owning the side.
323  * @param cfg The node containing the transfer information.
324  */
326 
327  /**
328  * Sends an ingame message to all other players.
329  *
330  * @param data The message to send.
331  * @param user The user sending the message.
332  */
334 
335  /**
336  * Handles [end_turn], repackages [commands] with private [speak]s in them
337  * and sends the data.
338  * Also filters commands from all but the current player.
339  * Currently removes all commands but [speak] for observers and all but
340  * [speak], [label], and [rename] for players.
341  *
342  * @param data The turn commands.
343  * @param user The user who sent a command to be processed during the turn. This may not be the player whose turn it currently is.
344  * @returns True if the turn ended.
345  */
347 
348  /**
349  * Handles incoming [whiteboard] data.
350  *
351  * @param data The whiteboard data.
352  * @param user The user sending the whiteboard data.
353  */
355 
356  /**
357  * Handles incoming [change_turns_wml] data.
358  *
359  * @param data The [change_turns_wml] data.
360  * @param user The player changing turns.
361  */
363 
364  /**
365  * Set the description to the number of available slots.
366  */
367  void describe_slots();
368 
369  /**
370  * Sends a message to all players in this game that aren't excluded.
371  *
372  * @param message The message to send.
373  * @param exclude The players to not send the message to.
374  */
375  void send_server_message_to_all(const char* message, utils::optional<player_iterator> exclude = {});
376  /**
377  * @ref send_server_message_to_all
378  */
379  void send_server_message_to_all(const std::string& message, utils::optional<player_iterator> exclude = {})
380  {
381  send_server_message_to_all(message.c_str(), exclude);
382  }
383 
384  /**
385  * Send a server message to the specified player.
386  *
387  * @param message The message to send.
388  * @param player The player to send the message to. If empty then the message is not sent.
389  * @param doc The document to create the message in. If nullptr then a new document is created.
390  */
391  void send_server_message(
392  const char* message, utils::optional<player_iterator> player = {}, simple_wml::document* doc = nullptr) const;
393  /**
394  * @ref send_server_message
395  */
397  const std::string& message, utils::optional<player_iterator> player = {}, simple_wml::document* doc = nullptr) const
398  {
399  send_server_message(message.c_str(), player, doc);
400  }
401 
402  /**
403  * Send data to all players in this game except 'exclude'.
404  * Also record this data for the replay.
405  *
406  * @param message The message to send.
407  * @param exclude The players to not send the message to.
408  */
409  void send_and_record_server_message(const char* message, utils::optional<player_iterator> exclude = {});
410  /**
411  * @ref send_and_record_server_message
412  */
413  void send_and_record_server_message(const std::string& message, utils::optional<player_iterator> exclude = {})
414  {
415  send_and_record_server_message(message.c_str(), exclude);
416  }
417 
418  /**
419  * Send data to all players except those excluded.
420  * For example, to send a message to all players except the player who typed the original message.
421  *
422  * @param data The data to send.
423  * @param players The players to send the data to.
424  * @param exclude The player from @a players to not send the data to.
425  */
426  template<typename Container>
427  void send_to_players(simple_wml::document& data, const Container& players, utils::optional<player_iterator> exclude = {});
428 
429  /**
430  * Send data to all players and observers except those excluded.
431  *
432  * @param data The data to send.
433  * @param exclude The players/observers to not send the data to.
434  */
435  void send_data(simple_wml::document& data, utils::optional<player_iterator> exclude = {});
436 
437  /**
438  * Clears the history of recorded WML documents.
439  */
440  void clear_history();
441 
442  /**
443  * Clears the history of recorded chat WML documents.
444  */
445  void clear_chat_history();
446 
447  /**
448  * Records a WML document in the game's history.
449  *
450  * @param data The WML document to record.
451  */
452  void record_data(std::unique_ptr<simple_wml::document> data);
453 
454  /**
455  * Move the level information and recorded history into a replay file and save it.
456  */
457  void save_replay();
458 
459  /**
460  * @return The full scenario data.
461  */
463  {
464  return level_;
465  }
466 
467  /**
468  * Set the game's description.
469  * Also set the game as requiring a password if a password is set.
470  *
471  * @param desc The node containing the game's description.
472  */
473  void set_description(simple_wml::node* desc);
474 
475  /**
476  * @return The node containing the game's current description.
477  */
479  {
480  return description_;
481  }
482 
483  /**
484  * @return The node containing the game's current description. and remembers that it was changed.
485  */
487  {
488  description_updated_ = true;
489  return description_;
490  }
491 
492  /**
493  * @return The node containing the game's current description if it was changed.
494  */
496  {
498  description_updated_ = false;
499  return description_;
500  }
501  return nullptr;
502  }
503 
504  /**
505  * Sets the password required to access the game.
506  *
507  * @param passwd The password to set.
508  */
509  void set_password(const std::string& passwd)
510  {
511  password_ = passwd;
512  }
513 
514  /**
515  * Set a list of usernames that should all be banned from joining the game.
516  *
517  * @param name_bans The list of usernames.
518  */
519  void set_name_bans(const std::vector<std::string> name_bans)
520  {
521  name_bans_ = name_bans;
522  }
523 
524  /**
525  * @param passwd The password to join with.
526  * @return True if the game's password is empty or if the provided password matches, false otherwise.
527  */
528  bool password_matches(const std::string& passwd) const
529  {
530  return password_.empty() || passwd == password_;
531  }
532 
533  /**
534  * @return Whether the game has a password set.
535  */
536  bool has_password() const
537  {
538  return !password_.empty();
539  }
540 
541  /**
542  * Provides the reason the game was ended.
543  *
544  * @return Either that the game was aborted (after starting), not started, or has some other reason set.
545  */
546  const std::string& termination_reason() const
547  {
548  static const std::string aborted = "aborted";
549  static const std::string not_started = "not started";
550 
551  return started_ ? (termination_.empty() ? aborted : termination_) : not_started;
552  }
553 
554  /**
555  * Sets the termination reason for this game.
556  *
557  * @param reason The termination reason.
558  */
559  void set_termination_reason(const std::string& reason);
560 
561  /**
562  * Handle a choice requested by a client, such as changing a side's controller, if initiated by WML/lua.
563  *
564  * @param data The data needed to process the choice.
565  * @param user The player making the request.
566  */
568 
569  /**
570  * Send a randomly generated number to the requestor.
571  */
572  void handle_random_choice();
573 
574  /**
575  * Handle a request to change a side's controller.
576  * Note that this does not change who owns a side.
577  *
578  * @param data Contains the information about which side to change the controller of.
579  */
581 
582  /**
583  * Adds a new, empty side owned by no one.
584  */
585  void handle_add_side_wml();
586 
587  /**
588  * Reset the internal counter for choice requests made by clients to the server.
589  */
591  {
593  }
594 
595  /**
596  * Function which returns true if 'player' controls any of the sides specified in 'sides'.
597  *
598  * @param sides The list of sides in this game.
599  * @param player The player being checked for whether they own any sides.
600  */
601  bool controls_side(const std::vector<int>& sides, player_iterator player) const;
602 
603  /**
604  * @return Whether the loaded WML has the attribute indicating that this is a reloaded savegame rather than a brand new game.
605  */
606  bool is_reload() const;
607 
609  {
610  players_.clear();
611  observers_.clear();
612  }
613 
614 private:
615  // forbidden operations
616  game(const game&) = delete;
617  game& operator=(const game&) = delete;
618 
619  /**
620  * @return 0 if there are no sides, or the current side index otherwise.
621  */
622  std::size_t current_side() const
623  {
624  // At the start of the game it can happen that current_side_index_ is 0,
625  // but the first side is empty. It's better to do this than to skip empty
626  // sides in start_game() in case the controller changes during start events.
628  }
629 
630  /**
631  * @return The player who owns the side at index @a index.
632  * nullopt if wither index is invalid or the side is not owned.
633  */
634  utils::optional<player_iterator> get_side_player(size_t index) const
635  {
636  return index >= sides_.size() ? utils::optional<player_iterator>() : sides_[index];
637  }
638 
639  /**
640  * @return The player who owns the current side.
641  */
642  utils::optional<player_iterator> current_player() const
643  {
644  // sides_ should never be empty but just to be sure.
645  return get_side_player(current_side());
646  }
647 
648  /**
649  * @param player The player being checked.
650  * @return Whether the player being checked is the current player taking their turn.
651  */
653  {
654  return (current_player() == player);
655  }
656 
657  /**
658  * @param player The observer being checked.
659  * @return True if the observer is muted or if all observers are muted, false otherwise.
660  */
662 
663  /**
664  * @return True if all observers have been muted via that command (not if each individual observer happens to have been manually muted).
665  */
666  bool all_observers_muted() const
667  {
668  return all_observers_muted_;
669  }
670 
671  /**
672  * Sends a message either stating that all observers are muted or listing the observers that are muted.
673  *
674  * @param user The player to send the message to.
675  */
676  void send_muted_observers(player_iterator user) const;
677 
678  /**
679  * Tell the host who owns a side.
680  *
681  * @param cfg The document to send to the host.
682  * @param side The side information to send.
683  * @return True if the document was sent, false otherwise.
684  */
685  bool send_taken_side(simple_wml::document& cfg, const simple_wml::node* side) const;
686 
687  /**
688  * Figures out which side to take and tells that side to the game owner.
689  *
690  * The owner then should send a [scenario_diff] that implements the side
691  * change and a subsequent update_side_data() call makes it actually
692  * happen.
693  * First we look for a side where save_id= or current_player= matches the
694  * new user's name then we search for the first controller=human or reserved side.
695  *
696  * @param user The player taking a side.
697  * @return True if the side was taken, false otherwise.
698  */
699  bool take_side(player_iterator user);
700 
701  /**
702  * Send [change_controller] message to tell all clients the new controller's name or controller type (human or ai).
703  *
704  * @param side_index The index of the side whose controller is changing.
705  * @param player The player who is taking control of the side.
706  * @param player_name The name of the player who is taking control of the side.
707  * @param player_left We use the "player_left" field as follows. Normally change_controller sends one message to the owner, and one message to everyone else.
708  * In case that a player drops, the owner is gone and should not get a message, instead the host gets a [side_drop] message.
709  */
710  void change_controller(const std::size_t side_index,
712  const std::string& player_name,
713  const bool player_left = true);
714 
715  /**
716  * Tell everyone else but the source player that the controller type changed.
717  *
718  * @param side_index The index of the side whose controller type is changing.
719  * @param player The player who owns the side whose controller type is changing.
720  * @param player_name The name of the player who owns the side whose controller type is changing.
721  * @return The document that was sent to all other players.
722  */
723  std::unique_ptr<simple_wml::document> change_controller_type(const std::size_t side_index,
725  const std::string& player_name);
726 
727  /**
728  * Tells a player to leave the game.
729  *
730  * @param user The player leaving the game.
731  */
732  void send_leave_game(player_iterator user) const;
733 
734  /**
735  * Sends a document to the provided list of sides.
736  *
737  * @param data The data to be sent to the provided sides.
738  * @param sides A comma sperated list of side numbers to which the document should be sent.
739  * @param exclude Players to not send the data to.
740  */
742  const simple_wml::string_span& sides,
743  utils::optional<player_iterator> exclude = {});
744 
745  /**
746  * Send a document per observer in the game.
747  * If @a player is blank, send these documents to everyone, else send them to just the observer who joined.
748  *
749  * @param player The observer who joined.
750  */
751  void send_observerjoins(utils::optional<player_iterator> player = {});
753  void send_history(player_iterator sock) const;
754  void send_chat_history(player_iterator sock) const;
755 
756  /** In case of a host transfer, notify the new host about its status. */
757  void notify_new_host();
758 
759  /**
760  * Shortcut to a convenience function for finding a user by name.
761  *
762  * @param name The name of the user to find.
763  * @return The player if found, else empty.
764  */
765  utils::optional<player_iterator> find_user(const simple_wml::string_span& name);
766 
767  bool is_legal_command(const simple_wml::node& command, player_iterator user);
768 
769  /**
770  * Checks whether a user has the same IP as any other members of this game.
771  * @return A comma separated string of members with matching IPs.
772  */
773  std::string has_same_ip(player_iterator user) const;
774 
775  /**
776  * Function which should be called every time a player ends their turn
777  * (i.e. [end_turn] received).
778  *
779  * @param new_side The side number whose turn to move it has become.
780  */
781  void end_turn(int new_side);
782  /**
783  * Function which should be called every time a player starts their turn
784  * (i.e. [init_side] received). This will update the 'turn' attribute for
785  * the game's description when appropriate.
786  */
787  void init_turn();
788 
789  /**
790  * Set or update the current and max turn values in the game's description.
791  */
792  void update_turn_data();
793 
794  /**
795  * Function to send a list of users to all clients.
796  * Only sends data if the game is initialized but not yet started.
797  *
798  * @param exclude The players to not send the list of users to.
799  */
800  void send_user_list(utils::optional<player_iterator> exclude = {});
801 
802  /**
803  * @param pl The player.
804  * @return The player's username.
805  */
806  std::string username(player_iterator pl) const;
807 
808  /**
809  * @param users The users to create a comma separated list from.
810  * @return A comma separated list of user names.
811  */
812  std::string list_users(const user_vector& users) const;
813 
814  /** calculates the initial value for sides_, side_controllerds_, nsides_*/
815  void reset_sides();
816 
817  /**
818  * Helps debugging player and observer lists.
819  *
820  * @return A string listing the game IDs, players, and observers.
821  */
822  std::string debug_player_info() const;
823 
824  /**
825  * Helps debugging controller tweaks.
826  *
827  * @return A string listing the game IDs and side information.
828  */
829  std::string debug_sides_info() const;
830 
831  /// @return the side index for which we accept [init_side]
832  int get_next_side_index() const;
833  /**
834  * finds the first side starting at @a side_index that is non empty.
835  */
836  int get_next_nonempty(int side_index) const;
837 
838  /** The wesnothd server instance this game exists on. */
841 
842  /**
843  * Incremented to retrieve a unique ID for game instances within wesnothd.
844  */
845  static int id_num;
846  /** This game's ID within wesnothd */
847  int id_;
848 
849  /**
850  * Incremented to retrieve a unique ID per wesnothd instance for game instances within the database.
851  */
852  static int db_id_num;
853  /**
854  * Used for unique identification of games played in the database.
855  * Necessary since for MP campaigns multiple scenarios can be played within the same game instance
856  * and we need a unique ID per scenario played, not per game instance.
857  */
858  int db_id_;
859 
860  /** The name of the game. */
861  std::string name_;
862  /** The password needed to join the game. */
863  std::string password_;
864 
865  /** The game host or later owner (if the host left). */
867 
868  /** A vector of players (members owning a side). */
870 
871  /** A vector of observers (members not owning a side). */
873  /** A vector of muted observers. */
875 
876  /** A vector of side owners. */
878 
879  /** A vector containiner the controller type for each side. */
880  std::vector<side_controller::type> side_controllers_;
881 
882  /** Number of sides in the current scenario. */
883  int nsides_;
884  /** Whether the game has been started or not. */
885  bool started_;
886 
887  /**
888  The current scenario data.
889 
890  WRONG! This contains the initial state or the state from which
891  the game was loaded from.
892  Using this to make assumptions about the current gamestate is
893  extremely dangerous and should especially not be done for anything
894  that can be nodified by wml (especially by [modify_side]),
895  like team_name, controller ... in [side].
896 
897  FIXME: move every code here that uses this object to query those
898  information to the clients. But note that there are some checks
899  (like controller == null) that are definitely needed by the server and
900  in this case we should try to modify the client to inform the server if
901  a change of those properties occur. Ofc we shouldn't update level_
902  then, but rather store that information in a separate object
903  (like in side_controllers_).
904  */
906 
907  /** Replay data. */
908  mutable std::vector<std::unique_ptr<simple_wml::document>> history_;
909  /** Replay chat history data. */
910  mutable std::vector<std::unique_ptr<simple_wml::document>> chat_history_;
911 
912  /** Pointer to the game's description in the games_and_users_list_. */
914 
915  /** Set to true whenever description_ was changed that an update needs to be sent to clients. */
917 
918  /** The game's current turn. */
920  /** The index of the current side. The side number is current_side_index_+1. */
922  /**
923  * after [end_turn] was received, this contains the side for who we accept [init_side].
924  * -1 if we currently don't accept [init_side] because the current player didn't end his turn yet.
925  **/
927  /** The maximum number of turns before the game ends. */
929  /** Whether all observers should be treated as muted. */
931 
932  /** List of banned IPs */
933  std::vector<std::string> bans_;
934  /** List of banned usernames */
935  std::vector<std::string> name_bans_;
936 
937  /**
938  * in multiplayer campaigns it can happen that some players are still in the previous scenario
939  * keep track of those players because processing certain
940  * input from those side wil lead to error (oos)
941  */
942  std::set<const player_record*> players_not_advanced_;
943 
944  /** The reason the game ended. */
945  std::string termination_;
946 
947  /** Whether to save a replay of this game. */
949  /** Where to save the replay of this game. */
950  std::string replay_save_path_;
951 
952  /** A wrapper for mersenne twister rng which generates randomness for this game */
954  /**
955  * The ID of the last request received from a client.
956  * New requests should never have a lower value than this.
957  */
959 };
960 
961 } // namespace wesnothd
node * child(const char *name)
Definition: simple_wml.hpp:263
const child_list & children(const char *name) const
Definition: simple_wml.cpp:643
std::vector< node * > child_list
Definition: simple_wml.hpp:125
void handle_controller_choice(const simple_wml::node &data)
Handle a request to change a side's controller.
Definition: game.cpp:1158
utils::optional< player_iterator > ban_user(const simple_wml::node &ban, player_iterator banner)
Ban a user by name.
Definition: game.cpp:814
std::string debug_player_info() const
Helps debugging player and observer lists.
Definition: game.cpp:1900
bool is_reload() const
Definition: game.cpp:1995
void send_user_list(utils::optional< player_iterator > exclude={})
Function to send a list of users to all clients.
Definition: game.cpp:1550
void mute_all_observers()
Toggles whether all observers are muted or not.
Definition: game.cpp:681
utils::optional< player_iterator > get_side_player(size_t index) const
Definition: game.hpp:634
static const simple_wml::node * starting_pos(const simple_wml::node &data)
The const version.
Definition: game.hpp:165
int current_side_index_
The index of the current side.
Definition: game.hpp:921
std::vector< std::unique_ptr< simple_wml::document > > history_
Replay data.
Definition: game.hpp:908
bool is_legal_command(const simple_wml::node &command, player_iterator user)
Definition: game.cpp:898
void send_and_record_server_message(const std::string &message, utils::optional< player_iterator > exclude={})
send_and_record_server_message
Definition: game.hpp:413
void clear_chat_history()
Clears the history of recorded chat WML documents.
Definition: game.cpp:1863
std::vector< std::string > bans_
List of banned IPs.
Definition: game.hpp:933
bool is_owner(player_iterator player) const
Definition: game.hpp:89
void init_turn()
Function which should be called every time a player starts their turn (i.e.
Definition: game.cpp:1329
void send_history(player_iterator sock) const
Definition: game.cpp:1728
void process_change_turns_wml(simple_wml::document &data, player_iterator user)
Handles incoming [change_turns_wml] data.
Definition: game.cpp:1294
bool is_current_player(player_iterator player) const
Definition: game.hpp:652
randomness::mt_rng rng_
A wrapper for mersenne twister rng which generates randomness for this game.
Definition: game.hpp:953
std::string has_same_ip(player_iterator user) const
Checks whether a user has the same IP as any other members of this game.
Definition: game.cpp:1681
std::string name_
The name of the game.
Definition: game.hpp:861
void notify_new_host()
In case of a host transfer, notify the new host about its status.
Definition: game.cpp:636
void send_chat_history(player_iterator sock) const
Definition: game.cpp:1755
void update_side_data()
Resets the side configuration according to the scenario data.
Definition: game.cpp:413
std::string replay_save_path_
Where to save the replay of this game.
Definition: game.hpp:950
void send_leave_game(player_iterator user) const
Tells a player to leave the game.
Definition: game.cpp:776
void handle_random_choice()
Send a randomly generated number to the requestor.
Definition: game.cpp:1129
void set_termination_reason(const std::string &reason)
Sets the termination reason for this game.
Definition: game.cpp:1876
void unban_user(const simple_wml::node &unban, player_iterator unbanner)
Unban a user by name.
Definition: game.cpp:856
bool level_init() const
Definition: game.hpp:137
std::vector< std::unique_ptr< simple_wml::document > > chat_history_
Replay chat history data.
Definition: game.hpp:910
void perform_controller_tweaks()
This is performed just before starting and before the [start_game] signal.
Definition: game.cpp:199
void record_data(std::unique_ptr< simple_wml::document > data)
Records a WML document in the game's history.
Definition: game.cpp:1852
std::vector< side_controller::type > side_controllers_
A vector containiner the controller type for each side.
Definition: game.hpp:880
void send_server_message_to_all(const char *message, utils::optional< player_iterator > exclude={})
Sends a message to all players in this game that aren't excluded.
Definition: game.cpp:1956
void handle_add_side_wml()
Adds a new, empty side owned by no one.
Definition: game.cpp:1151
void clear_history()
Clears the history of recorded WML documents.
Definition: game.cpp:1858
std::size_t nobservers() const
Definition: game.hpp:203
bool password_matches(const std::string &passwd) const
Definition: game.hpp:528
int current_turn_
The game's current turn.
Definition: game.hpp:919
bool save_replays_
Whether to save a replay of this game.
Definition: game.hpp:948
void send_muted_observers(player_iterator user) const
Sends a message either stating that all observers are muted or listing the observers that are muted.
Definition: game.cpp:691
void load_next_scenario(player_iterator user)
A user asks for the next scenario to advance to.
Definition: game.cpp:1585
bool started() const
Definition: game.hpp:187
bool add_player(player_iterator player, bool observer=false)
Add a user to the game.
Definition: game.cpp:1355
utils::optional< player_iterator > current_player() const
Definition: game.hpp:642
void new_scenario(player_iterator sender)
When the host sends the new scenario of a mp campaign.
Definition: game.cpp:1573
std::string list_users(const user_vector &users) const
Definition: game.cpp:184
const user_vector all_game_users() const
Definition: game.cpp:1890
void send_data(simple_wml::document &data, utils::optional< player_iterator > exclude={})
Send data to all players and observers except those excluded.
Definition: game.cpp:1647
void describe_slots()
Set the description to the number of available slots.
Definition: game.cpp:647
void start_game(player_iterator starter)
Starts the game (if a new game) or starts the next scenario of an MP campaign.
Definition: game.cpp:254
static simple_wml::node * starting_pos(simple_wml::node &data)
The non-const version.
Definition: game.hpp:148
void send_and_record_server_message(const char *message, utils::optional< player_iterator > exclude={})
Send data to all players in this game except 'exclude'.
Definition: game.cpp:1945
std::vector< std::string > name_bans_
List of banned usernames.
Definition: game.hpp:935
game(wesnothd::server &server, player_connections &player_connections, player_iterator host, const std::string &name="", bool save_replays=false, const std::string &replay_save_path="")
Definition: game.cpp:78
bool description_updated_
Set to true whenever description_ was changed that an update needs to be sent to clients.
Definition: game.hpp:916
bool remove_player(player_iterator player, const bool disconnect=false, const bool destruct=false)
Removes a user from the game.
Definition: game.cpp:1440
int id_
This game's ID within wesnothd.
Definition: game.hpp:847
simple_wml::document & level()
Definition: game.hpp:462
std::size_t current_side() const
Definition: game.hpp:622
utils::optional< player_iterator > find_user(const simple_wml::string_span &name)
Shortcut to a convenience function for finding a user by name.
Definition: game.cpp:1935
bool process_turn(simple_wml::document &data, player_iterator user)
Handles [end_turn], repackages [commands] with private [speak]s in them and sends the data.
Definition: game.cpp:968
std::size_t current_turn() const
Definition: game.hpp:211
std::string username(player_iterator pl) const
Definition: game.cpp:179
void process_whiteboard(simple_wml::document &data, player_iterator user)
Handles incoming [whiteboard] data.
Definition: game.cpp:1267
player_connections & player_connections_
Definition: game.hpp:840
void send_server_message_to_all(const std::string &message, utils::optional< player_iterator > exclude={})
send_server_message_to_all
Definition: game.hpp:379
void send_server_message(const std::string &message, utils::optional< player_iterator > player={}, simple_wml::document *doc=nullptr) const
send_server_message
Definition: game.hpp:396
bool all_observers_muted() const
Definition: game.hpp:666
int get_next_nonempty(int side_index) const
finds the first side starting at side_index that is non empty.
Definition: game.cpp:2006
bool is_member(player_iterator player) const
Definition: game.hpp:98
int db_id_
Used for unique identification of games played in the database.
Definition: game.hpp:858
void reset_sides()
calculates the initial value for sides_, side_controllerds_, nsides_
Definition: game.cpp:402
void handle_choice(const simple_wml::node &data, player_iterator user)
Handle a choice requested by a client, such as changing a side's controller, if initiated by WML/lua.
Definition: game.cpp:1223
user_vector muted_observers_
A vector of muted observers.
Definition: game.hpp:874
bool is_muted_observer(player_iterator player) const
Definition: game.cpp:161
std::set< const player_record * > players_not_advanced_
in multiplayer campaigns it can happen that some players are still in the previous scenario keep trac...
Definition: game.hpp:942
void save_replay()
Move the level information and recorded history into a replay file and save it.
Definition: game.cpp:1796
simple_wml::node * description() const
Definition: game.hpp:478
void end_turn(int new_side)
Function which should be called every time a player ends their turn (i.e.
Definition: game.cpp:1320
void transfer_side_control(player_iterator player, const simple_wml::node &cfg)
Lets a player owning a side give it to another player or observer.
Definition: game.cpp:485
void unmute_observer(const simple_wml::node &unmute, player_iterator unmuter)
Unmute an observer or unmute all currently muted observers if no name is given.
Definition: game.cpp:744
int next_side_index_
after [end_turn] was received, this contains the side for who we accept [init_side].
Definition: game.hpp:926
bool started_
Whether the game has been started or not.
Definition: game.hpp:885
int db_id() const
This ID is not reused between scenarios of MP campaigns.
Definition: game.hpp:64
utils::optional< player_iterator > kick_member(const simple_wml::node &kick, player_iterator kicker)
Kick a user from this game by name.
Definition: game.cpp:782
void emergency_cleanup()
Definition: game.hpp:608
bool has_password() const
Definition: game.hpp:536
std::string debug_sides_info() const
Helps debugging controller tweaks.
Definition: game.cpp:1916
std::string termination_
The reason the game ended.
Definition: game.hpp:945
const std::string & name() const
Definition: game.hpp:80
void send_data_sides(simple_wml::document &data, const simple_wml::string_span &sides, utils::optional< player_iterator > exclude={})
Sends a document to the provided list of sides.
Definition: game.cpp:1652
const simple_wml::node::child_list & get_sides_list() const
Definition: game.hpp:179
simple_wml::node * description_
Pointer to the game's description in the games_and_users_list_.
Definition: game.hpp:913
game(const game &)=delete
user_vector observers_
A vector of observers (members not owning a side).
Definition: game.hpp:872
static int db_id_num
Incremented to retrieve a unique ID per wesnothd instance for game instances within the database.
Definition: game.hpp:852
void set_description(simple_wml::node *desc)
Set the game's description.
Definition: game.cpp:1868
int num_turns_
The maximum number of turns before the game ends.
Definition: game.hpp:928
bool all_observers_muted_
Whether all observers should be treated as muted.
Definition: game.hpp:930
side_vector sides_
A vector of side owners.
Definition: game.hpp:877
int nsides_
Number of sides in the current scenario.
Definition: game.hpp:883
int id() const
This ID is reused between scenarios of MP campaigns.
Definition: game.hpp:52
simple_wml::document level_
The current scenario data.
Definition: game.hpp:905
void set_name_bans(const std::vector< std::string > name_bans)
Set a list of usernames that should all be banned from joining the game.
Definition: game.hpp:519
bool take_side(player_iterator user)
Figures out which side to take and tells that side to the game owner.
Definition: game.cpp:361
void change_controller(const std::size_t side_index, player_iterator player, const std::string &player_name, const bool player_left=true)
Send [change_controller] message to tell all clients the new controller's name or controller type (hu...
Definition: game.cpp:588
bool allow_observers() const
Definition: game.cpp:151
user_vector players_
A vector of players (members owning a side).
Definition: game.hpp:869
void next_db_id()
Increments the ID used when running database queries.
Definition: game.hpp:72
void send_observerquit(player_iterator observer)
Definition: game.cpp:1716
bool send_taken_side(simple_wml::document &cfg, const simple_wml::node *side) const
Tell the host who owns a side.
Definition: game.cpp:340
int get_next_side_index() const
Definition: game.cpp:2001
wesnothd::server & server
The wesnothd server instance this game exists on.
Definition: game.hpp:839
void send_server_message(const char *message, utils::optional< player_iterator > player={}, simple_wml::document *doc=nullptr) const
Send a server message to the specified player.
Definition: game.cpp:1963
std::string password_
The password needed to join the game.
Definition: game.hpp:863
bool is_observer(player_iterator player) const
Definition: game.cpp:156
void reset_last_synced_context_id()
Reset the internal counter for choice requests made by clients to the server.
Definition: game.hpp:590
simple_wml::node * changed_description()
Definition: game.hpp:495
bool is_player(player_iterator player) const
Definition: game.cpp:174
int last_choice_request_id_
The ID of the last request received from a client.
Definition: game.hpp:958
const std::string & termination_reason() const
Provides the reason the game was ended.
Definition: game.hpp:546
bool controls_side(const std::vector< int > &sides, player_iterator player) const
Function which returns true if 'player' controls any of the sides specified in 'sides'.
Definition: game.cpp:1668
void send_observerjoins(utils::optional< player_iterator > player={})
Send a document per observer in the game.
Definition: game.cpp:1696
static int id_num
Incremented to retrieve a unique ID for game instances within wesnothd.
Definition: game.hpp:845
bool player_is_banned(player_iterator player, const std::string &name) const
Definition: game.cpp:673
std::string get_replay_filename()
Definition: game.cpp:1786
void set_password(const std::string &passwd)
Sets the password required to access the game.
Definition: game.hpp:509
void send_to_players(simple_wml::document &data, const Container &players, utils::optional< player_iterator > exclude={})
Send data to all players except those excluded.
Definition: game.cpp:1638
void mute_observer(const simple_wml::node &mute, player_iterator muter)
Mute an observer or give a message of all currently muted observers if no name is given.
Definition: game.cpp:703
std::unique_ptr< simple_wml::document > change_controller_type(const std::size_t side_index, player_iterator player, const std::string &player_name)
Tell everyone else but the source player that the controller type changed.
Definition: game.cpp:620
void update_turn_data()
Set or update the current and max turn values in the game's description.
Definition: game.cpp:1343
game & operator=(const game &)=delete
simple_wml::node * description_for_writing()
Definition: game.hpp:486
player_iterator owner_
The game host or later owner (if the host left).
Definition: game.hpp:866
void process_message(simple_wml::document &data, player_iterator user)
Sends an ingame message to all other players.
Definition: game.cpp:886
std::size_t nplayers() const
Definition: game.hpp:195
std::string observer
std::size_t index(std::string_view str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:70
std::vector< player_iterator > user_vector
Definition: game.hpp:31
player_connections::const_iterator player_iterator
std::vector< utils::optional< player_iterator > > side_vector
Definition: game.hpp:32
bmi::multi_index_container< player_record, bmi::indexed_by< bmi::ordered_unique< bmi::tag< socket_t >, bmi::const_mem_fun< player_record, const any_socket_ptr, &player_record::socket > >, bmi::hashed_unique< bmi::tag< name_t >, bmi::const_mem_fun< player_record, const std::string &, &player_record::name > >, bmi::ordered_non_unique< bmi::tag< game_t >, bmi::const_mem_fun< player_record, int, &player_record::game_id > > > > player_connections
std::string_view data
Definition: picture.cpp:178