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