diff --git a/src/server/game.cpp b/src/server/game.cpp index b0b9e7672ca..59abd8fec15 100644 --- a/src/server/game.cpp +++ b/src/server/game.cpp @@ -92,7 +92,7 @@ void game::missing_user(socket_ptr /*socket*/, const std::string& func) const } game::game(player_connections& player_connections, - socket_ptr host, + const socket_ptr& host, const std::string& name, bool save_replays, const std::string& replay_save_path) @@ -170,12 +170,12 @@ bool game::registered_users_only() const return get_multiplayer(level_.root())["registered_users_only"].to_bool(true); } -bool game::is_observer(const socket_ptr player) const +bool game::is_observer(const socket_ptr& player) const { return std::find(observers_.begin(), observers_.end(), player) != observers_.end(); } -bool game::is_muted_observer(const socket_ptr player) const +bool game::is_muted_observer(const socket_ptr& player) const { if(!is_observer(player)) { return false; @@ -188,7 +188,7 @@ bool game::is_muted_observer(const socket_ptr player) const return std::find(muted_observers_.begin(), muted_observers_.end(), player) != muted_observers_.end(); } -bool game::is_player(const socket_ptr player) const +bool game::is_player(const socket_ptr& player) const { return std::find(players_.begin(), players_.end(), player) != players_.end(); } @@ -210,7 +210,7 @@ std::string describe_turns(int turn, int num_turns) } // anon namespace -std::string game::username(const socket_ptr player) const +std::string game::username(const socket_ptr& player) const { const auto iter = player_connections_.find(player); if(iter != player_connections_.end()) { @@ -306,7 +306,7 @@ void game::perform_controller_tweaks() // not to send them at all, although not if it complicates the server code. } -void game::start_game(const socket_ptr starter) +void game::start_game(const socket_ptr& starter) { const simple_wml::node::child_list& sides = get_sides_list(); DBG_GAME << "****\n Starting game. sides = " << std::endl; @@ -413,7 +413,7 @@ bool game::send_taken_side(simple_wml::document& cfg, const simple_wml::node* si return true; } -bool game::take_side(const socket_ptr user) +bool game::take_side(const socket_ptr& user) { DBG_GAME << "take_side...\n"; @@ -537,7 +537,7 @@ void game::update_side_data() DBG_GAME << debug_player_info(); } -void game::transfer_side_control(const socket_ptr sock, const simple_wml::node& cfg) +void game::transfer_side_control(const socket_ptr& sock, const simple_wml::node& cfg) { DBG_GAME << "transfer_side_control...\n"; @@ -561,7 +561,7 @@ void game::transfer_side_control(const socket_ptr sock, const simple_wml::node& } const simple_wml::string_span& newplayer_name = cfg["player"]; - const socket_ptr old_player = sides_[side_num - 1]; + const socket_ptr& old_player = sides_[side_num - 1]; const auto oldplayer = player_connections_.find(old_player); if(oldplayer == player_connections_.end()) { missing_user(old_player, __func__); @@ -634,7 +634,7 @@ void game::transfer_side_control(const socket_ptr sock, const simple_wml::node& } void game::change_controller( - const size_t side_index, const socket_ptr sock, const std::string& player_name, const bool player_left) + const size_t side_index, const socket_ptr& sock, const std::string& player_name, const bool player_left) { DBG_GAME << __func__ << "...\n"; @@ -718,7 +718,7 @@ bool game::describe_slots() } } -bool game::player_is_banned(const socket_ptr sock) const +bool game::player_is_banned(const socket_ptr& sock) const { auto ban = std::find(bans_.begin(), bans_.end(), client_address(sock)); return ban != bans_.end(); @@ -734,7 +734,7 @@ void game::mute_all_observers() } } -void game::send_muted_observers(const socket_ptr user) const +void game::send_muted_observers(const socket_ptr& user) const { if(all_observers_muted_) { send_server_message("All observers are muted.", user); @@ -746,7 +746,7 @@ void game::send_muted_observers(const socket_ptr user) const send_server_message("Muted observers: " + muted_nicks, user); } -void game::mute_observer(const simple_wml::node& mute, const socket_ptr muter) +void game::mute_observer(const simple_wml::node& mute, const socket_ptr& muter) { if(muter != owner_) { send_server_message("You cannot mute: not the game host.", muter); @@ -759,7 +759,7 @@ void game::mute_observer(const simple_wml::node& mute, const socket_ptr muter) return; } - const socket_ptr user = find_user(username); + const socket_ptr& user = find_user(username); /** * @todo FIXME: Maybe rather save muted nicks as a set of strings and @@ -788,7 +788,7 @@ void game::mute_observer(const simple_wml::node& mute, const socket_ptr muter) send_and_record_server_message(username.to_string() + " has been muted."); } -void game::unmute_observer(const simple_wml::node& unmute, const socket_ptr unmuter) +void game::unmute_observer(const simple_wml::node& unmute, const socket_ptr& unmuter) { if(unmuter != owner_) { send_server_message("You cannot unmute: not the game host.", unmuter); @@ -802,7 +802,7 @@ void game::unmute_observer(const simple_wml::node& unmute, const socket_ptr unmu return; } - const socket_ptr user = find_user(username); + const socket_ptr& user = find_user(username); if(!user || !is_observer(user)) { send_server_message("Observer '" + username.to_string() + "' not found.", unmuter); return; @@ -820,13 +820,13 @@ void game::unmute_observer(const simple_wml::node& unmute, const socket_ptr unmu send_and_record_server_message(username.to_string() + " has been unmuted."); } -void game::send_leave_game(socket_ptr user) const +void game::send_leave_game(const socket_ptr& user) const { static simple_wml::document leave_game("[leave_game]\n[/leave_game]\n", simple_wml::INIT_COMPRESSED); send_to_player(user, leave_game); } -socket_ptr game::kick_member(const simple_wml::node& kick, const socket_ptr kicker) +socket_ptr game::kick_member(const simple_wml::node& kick, const socket_ptr& kicker) { if(kicker != owner_) { send_server_message("You cannot kick: not the game host", kicker); @@ -834,7 +834,7 @@ socket_ptr game::kick_member(const simple_wml::node& kick, const socket_ptr kick } const simple_wml::string_span& username = kick["username"]; - const socket_ptr user = find_user(username); + const socket_ptr& user = find_user(username); if(!user || !is_member(user)) { send_server_message("'" + username.to_string() + "' is not a member of this game.", kicker); @@ -858,7 +858,7 @@ socket_ptr game::kick_member(const simple_wml::node& kick, const socket_ptr kick return user; } -socket_ptr game::ban_user(const simple_wml::node& ban, const socket_ptr banner) +socket_ptr game::ban_user(const simple_wml::node& ban, const socket_ptr& banner) { if(banner != owner_) { send_server_message("You cannot ban: not the game host", banner); @@ -866,7 +866,7 @@ socket_ptr game::ban_user(const simple_wml::node& ban, const socket_ptr banner) } const simple_wml::string_span& username = ban["username"]; - const socket_ptr user = find_user(username); + const socket_ptr& user = find_user(username); if(!user) { send_server_message("User '" + username.to_string() + "' not found.", banner); @@ -899,7 +899,7 @@ socket_ptr game::ban_user(const simple_wml::node& ban, const socket_ptr banner) return socket_ptr(); } -void game::unban_user(const simple_wml::node& unban, const socket_ptr unbanner) +void game::unban_user(const simple_wml::node& unban, const socket_ptr& unbanner) { if(unbanner != owner_) { send_server_message("You cannot unban: not the game host.", unbanner); @@ -907,7 +907,7 @@ void game::unban_user(const simple_wml::node& unban, const socket_ptr unbanner) } const simple_wml::string_span& username = unban["username"]; - const socket_ptr user = find_user(username); + const socket_ptr& user = find_user(username); if(!user) { send_server_message("User '" + username.to_string() + "' not found.", unbanner); @@ -928,7 +928,7 @@ void game::unban_user(const simple_wml::node& unban, const socket_ptr unbanner) send_and_record_server_message(username.to_string() + " has been unbanned."); } -void game::process_message(simple_wml::document& data, const socket_ptr user) +void game::process_message(simple_wml::document& data, const socket_ptr& user) { if(!owner_) { ERR_GAME << "No owner in game::process_message" << std::endl; @@ -944,7 +944,7 @@ void game::process_message(simple_wml::document& data, const socket_ptr user) send_data(data, user, "game message"); } -bool game::is_legal_command(const simple_wml::node& command, const socket_ptr user) +bool game::is_legal_command(const simple_wml::node& command, const socket_ptr& user) { const bool is_player = this->is_player(user); const bool is_host = user == owner_; @@ -996,7 +996,7 @@ bool game::is_legal_command(const simple_wml::node& command, const socket_ptr us return false; } -bool game::process_turn(simple_wml::document& data, const socket_ptr user) +bool game::process_turn(simple_wml::document& data, const socket_ptr& user) { // DBG_GAME << "processing commands: '" << cfg << "'\n"; if(!started_) { @@ -1202,7 +1202,7 @@ void game::handle_controller_choice(const simple_wml::node& req) record_data(mdata); } -void game::handle_choice(const simple_wml::node& data, const socket_ptr user) +void game::handle_choice(const simple_wml::node& data, const socket_ptr& user) { // note, that during end turn events, it's side=1 for the server but side= side_count() on the clients. @@ -1236,7 +1236,7 @@ void game::handle_choice(const simple_wml::node& data, const socket_ptr user) } } -void game::process_whiteboard(simple_wml::document& data, const socket_ptr user) +void game::process_whiteboard(simple_wml::document& data, const socket_ptr& user) { if(!started_ || !is_player(user)) { return; @@ -1263,7 +1263,7 @@ void game::process_whiteboard(simple_wml::document& data, const socket_ptr user) send_data_sides(data, to_sides, user, "whiteboard"); } -void game::process_change_turns_wml(simple_wml::document& data, const socket_ptr user) +void game::process_change_turns_wml(simple_wml::document& data, const socket_ptr& user) { if(!started_ || !is_player(user)) { return; @@ -1318,7 +1318,7 @@ bool game::end_turn() ///@todo differentiate between "observers not allowed" and "player already in the game" errors. // maybe return a string with an error message. -bool game::add_player(const socket_ptr player, bool observer) +bool game::add_player(const socket_ptr& player, bool observer) { if(is_member(player)) { ERR_GAME << "ERROR: Player is already in this game. (socket: " << player << ")\n"; @@ -1402,7 +1402,7 @@ bool game::add_player(const socket_ptr player, bool observer) return true; } -bool game::remove_player(const socket_ptr player, const bool disconnect, const bool destruct) +bool game::remove_player(const socket_ptr& player, const bool disconnect, const bool destruct) { if(!is_member(player)) { ERR_GAME << "ERROR: User is not in this game. (socket: " << player << ")\n"; @@ -1511,7 +1511,7 @@ bool game::remove_player(const socket_ptr player, const bool disconnect, const b return false; } -void game::send_user_list(const socket_ptr exclude) const +void game::send_user_list(const socket_ptr& exclude) const { // If the game hasn't started yet, then send all players a list of the users in the game. if(started_ /*|| description_ == nullptr*/) { @@ -1538,7 +1538,7 @@ void game::send_user_list(const socket_ptr exclude) const send_data(cfg, exclude); } -void game::load_next_scenario(const socket_ptr user) +void game::load_next_scenario(const socket_ptr& user) { send_server_message_to_all(player_connections_.find(user)->info().name() + " advances to the next scenario", user); @@ -1588,7 +1588,7 @@ void game::load_next_scenario(const socket_ptr user) send_observerjoins(user); } -void game::send_data(simple_wml::document& data, const socket_ptr exclude, std::string /*packet_type*/) const +void game::send_data(simple_wml::document& data, const socket_ptr& exclude, std::string /*packet_type*/) const { send_to_players(data, all_game_users(), exclude); } @@ -1615,7 +1615,7 @@ struct controls_side_helper void game::send_data_sides(simple_wml::document& data, const simple_wml::string_span& sides, - const socket_ptr exclude, + const socket_ptr& exclude, std::string /*packet_type*/) const { std::vector sides_vec = ::split(sides, ::split_conv_impl()); @@ -1630,7 +1630,7 @@ void game::send_data_sides(simple_wml::document& data, send_to_players(data, filtered_players, exclude); } -bool game::controls_side(const std::vector& sides, const socket_ptr player) const +bool game::controls_side(const std::vector& sides, const socket_ptr& player) const { for(int side : sides) { size_t side_index = side - 1; @@ -1643,7 +1643,7 @@ bool game::controls_side(const std::vector& sides, const socket_ptr player) return false; } -std::string game::has_same_ip(socket_ptr user, bool observer) const +std::string game::has_same_ip(const socket_ptr& user, bool observer) const { const user_vector users = observer ? players_ : all_game_users(); const std::string ip = client_address(user); @@ -1662,7 +1662,7 @@ std::string game::has_same_ip(socket_ptr user, bool observer) const return clones; } -void game::send_observerjoins(const socket_ptr sock) const +void game::send_observerjoins(const socket_ptr& sock) const { for(const socket_ptr& ob : observers_) { if(ob == sock) { @@ -1682,7 +1682,7 @@ void game::send_observerjoins(const socket_ptr sock) const } } -void game::send_observerquit(const socket_ptr observer) const +void game::send_observerquit(const socket_ptr& observer) const { simple_wml::document observer_quit; @@ -1694,7 +1694,7 @@ void game::send_observerquit(const socket_ptr observer) const send_data(observer_quit, observer); } -void game::send_history(const socket_ptr socket) const +void game::send_history(const socket_ptr& socket) const { if(history_.empty()) { return; @@ -1916,7 +1916,7 @@ socket_ptr game::find_user(const simple_wml::string_span& name) } } -void game::send_and_record_server_message(const char* message, const socket_ptr exclude) +void game::send_and_record_server_message(const char* message, const socket_ptr& exclude) { simple_wml::document* doc = new simple_wml::document; send_server_message(message, socket_ptr(), doc); @@ -1929,14 +1929,14 @@ void game::send_and_record_server_message(const char* message, const socket_ptr } } -void game::send_server_message_to_all(const char* message, socket_ptr exclude) const +void game::send_server_message_to_all(const char* message, const socket_ptr& exclude) const { simple_wml::document doc; send_server_message(message, socket_ptr(), &doc); send_data(doc, exclude, "message"); } -void game::send_server_message(const char* message, socket_ptr sock, simple_wml::document* docptr) const +void game::send_server_message(const char* message, const socket_ptr& sock, simple_wml::document* docptr) const { simple_wml::document docbuf; if(docptr == nullptr) { diff --git a/src/server/game.hpp b/src/server/game.hpp index 57f55e8e19a..0958401e507 100644 --- a/src/server/game.hpp +++ b/src/server/game.hpp @@ -42,7 +42,7 @@ public: ) game(player_connections& player_connections, - socket_ptr host, + const socket_ptr& host, const std::string& name = "", bool save_replays = false, const std::string& replay_save_path = ""); @@ -59,23 +59,23 @@ public: return name_; } - bool is_owner(const socket_ptr player) const + bool is_owner(const socket_ptr& player) const { return (player == owner_); } - bool is_member(const socket_ptr player) const + bool is_member(const socket_ptr& player) const { return is_player(player) || is_observer(player); } bool allow_observers() const; bool registered_users_only() const; - bool is_observer(const socket_ptr player) const; - bool is_player(const socket_ptr player) const; + bool is_observer(const socket_ptr& player) const; + bool is_player(const socket_ptr& player) const; /** Checks whether the connection's ip address is banned. */ - bool player_is_banned(const socket_ptr player) const; + bool player_is_banned(const socket_ptr& player) const; bool level_init() const { @@ -141,9 +141,9 @@ public: * Mute an observer or give a message of all currently muted observers if no * name is given. */ - void mute_observer(const simple_wml::node& mute, const socket_ptr muter); + void mute_observer(const simple_wml::node& mute, const socket_ptr& muter); - void unmute_observer(const simple_wml::node& unmute, const socket_ptr unmuter); + void unmute_observer(const simple_wml::node& unmute, const socket_ptr& unmuter); /** * Kick a member by name. @@ -151,7 +151,7 @@ public: * @return The network handle of the removed member if * successful, null pointer otherwise. */ - socket_ptr kick_member(const simple_wml::node& kick, const socket_ptr kicker); + socket_ptr kick_member(const simple_wml::node& kick, const socket_ptr& kicker); /** * Ban and kick a user by name. @@ -161,16 +161,16 @@ public: * @return The network handle of the banned player if he * was in this game, null pointer otherwise. */ - socket_ptr ban_user(const simple_wml::node& ban, const socket_ptr banner); + socket_ptr ban_user(const simple_wml::node& ban, const socket_ptr& banner); - void unban_user(const simple_wml::node& unban, const socket_ptr unbanner); + void unban_user(const simple_wml::node& unban, const socket_ptr& unbanner); /** * Add a user to the game. * * @return True iff the user successfully joined the game. */ - bool add_player(const socket_ptr player, bool observer = false); + bool add_player(const socket_ptr& player, bool observer = false); /** * Removes a user from the game. @@ -179,12 +179,12 @@ public: * no more players or the host left on a not yet * started game. */ - bool remove_player(const socket_ptr player, const bool disconnect = false, const bool destruct = false); + bool remove_player(const socket_ptr& player, const bool disconnect = false, const bool destruct = false); /** Adds players and observers into one vector and returns that. */ const user_vector all_game_users() const; - void start_game(const socket_ptr starter); + void start_game(const socket_ptr& starter); // this is performed just before starting and before [start_game] signal // send scenario_diff's specific to each client so that they locally @@ -194,7 +194,7 @@ public: void update_game(); /** A user (player only?) asks for the next scenario to advance to. */ - void load_next_scenario(const socket_ptr user); // const + void load_next_scenario(const socket_ptr& user); // const // iceiceice: I unmarked this const because I want to send and record server messages when I fail to tweak sides // properly @@ -203,9 +203,9 @@ public: void update_side_data(); /** Let's a player owning a side give it to another player or observer. */ - void transfer_side_control(const socket_ptr sock, const simple_wml::node& cfg); + void transfer_side_control(const socket_ptr& sock, const simple_wml::node& cfg); - void process_message(simple_wml::document& data, const socket_ptr user); + void process_message(simple_wml::document& data, const socket_ptr& user); /** * Handles [end_turn], repackages [commands] with private [speak]s in them @@ -216,12 +216,12 @@ public: * * @returns True if the turn ended. */ - bool process_turn(simple_wml::document& data, const socket_ptr user); + bool process_turn(simple_wml::document& data, const socket_ptr& user); /** Handles incoming [whiteboard] data. */ - void process_whiteboard(simple_wml::document& data, const socket_ptr user); + void process_whiteboard(simple_wml::document& data, const socket_ptr& user); /** Handles incoming [change_turns_wml] data. */ - void process_change_turns_wml(simple_wml::document& data, const socket_ptr user); + void process_change_turns_wml(simple_wml::document& data, const socket_ptr& user); /** * Set the description to the number of available slots. @@ -230,29 +230,29 @@ public: */ bool describe_slots(); - void send_server_message_to_all(const char* message, socket_ptr exclude = socket_ptr()) const; - void send_server_message_to_all(const std::string& message, socket_ptr exclude = socket_ptr()) const + void send_server_message_to_all(const char* message, const socket_ptr& exclude = socket_ptr()) const; + void send_server_message_to_all(const std::string& message, const socket_ptr& exclude = socket_ptr()) const { send_server_message_to_all(message.c_str(), exclude); } void send_server_message( - const char* message, socket_ptr sock = socket_ptr(), simple_wml::document* doc = nullptr) const; + const char* message, const socket_ptr& sock = socket_ptr(), simple_wml::document* doc = nullptr) const; void send_server_message( - const std::string& message, socket_ptr sock = socket_ptr(), simple_wml::document* doc = nullptr) const + const std::string& message, const socket_ptr& sock = socket_ptr(), simple_wml::document* doc = nullptr) const { send_server_message(message.c_str(), sock, doc); } /** Send data to all players in this game except 'exclude'. */ - void send_and_record_server_message(const char* message, const socket_ptr exclude = socket_ptr()); - void send_and_record_server_message(const std::string& message, const socket_ptr exclude = socket_ptr()) + void send_and_record_server_message(const char* message, const socket_ptr& exclude = socket_ptr()); + void send_and_record_server_message(const std::string& message, const socket_ptr& exclude = socket_ptr()) { send_and_record_server_message(message.c_str(), exclude); } void send_data( - simple_wml::document& data, const socket_ptr exclude = socket_ptr(), std::string packet_type = "") const; + simple_wml::document& data, const socket_ptr& exclude = socket_ptr(), std::string packet_type = "") const; void clear_history(); void record_data(simple_wml::document* data); @@ -295,7 +295,7 @@ public: void set_termination_reason(const std::string& reason); - void handle_choice(const simple_wml::node& data, const socket_ptr user); + void handle_choice(const simple_wml::node& data, const socket_ptr& user); void handle_random_choice(const simple_wml::node& data); @@ -309,7 +309,7 @@ public: /** * Function which returns true iff 'player' controls any of the sides spcified in 'sides'. */ - bool controls_side(const std::vector& sides, const socket_ptr player) const; + bool controls_side(const std::vector& sides, const socket_ptr& player) const; private: // forbidden operations @@ -321,23 +321,23 @@ private: return (nsides_ ? end_turn_ % nsides_ : 0); } - socket_ptr current_player() const + const socket_ptr current_player() const { return (nsides_ ? sides_[current_side()] : socket_ptr()); } - bool is_current_player(const socket_ptr player) const + bool is_current_player(const socket_ptr& player) const { return (current_player() == player); } - bool is_muted_observer(const socket_ptr player) const; + bool is_muted_observer(const socket_ptr& player) const; bool all_observers_muted() const { return all_observers_muted_; } - void send_muted_observers(const socket_ptr user) const; + void send_muted_observers(const socket_ptr& user) const; bool send_taken_side(simple_wml::document& cfg, const simple_wml::node* side) const; @@ -350,37 +350,37 @@ private: * First we look for a side where save_id= or current_player= matches the * new user's name then we search for the first controller="network" side. */ - bool take_side(const socket_ptr user); + bool take_side(const socket_ptr& user); /** * Send [change_controller] message to tell all clients the new controller's name * or controller type (human or ai). */ void change_controller(const size_t side_num, - const socket_ptr sock, + const socket_ptr& sock, const std::string& player_name, const bool player_left = true); - void transfer_ai_sides(const socket_ptr player); - void send_leave_game(socket_ptr user) const; + void transfer_ai_sides(const socket_ptr& player); + void send_leave_game(const socket_ptr& user) const; /** @param sides a comma sperated list of side numbers to which the package should be sent, */ void send_data_sides(simple_wml::document& data, const simple_wml::string_span& sides, - const socket_ptr exclude = socket_ptr(), + const socket_ptr& exclude = socket_ptr(), std::string packet_type = "") const; void send_data_observers( - simple_wml::document& data, const socket_ptr exclude = socket_ptr(), std::string packet_type = "") const; + simple_wml::document& data, const socket_ptr& exclude = socket_ptr(), std::string packet_type = "") const; /** * Send [observer] tags of all the observers in the game to the user or * everyone if none given. */ - void send_observerjoins(const socket_ptr sock = socket_ptr()) const; - void send_observerquit(const socket_ptr observer) const; - void send_history(const socket_ptr sock) const; + void send_observerjoins(const socket_ptr& sock = socket_ptr()) const; + void send_observerquit(const socket_ptr& observer) const; + void send_history(const socket_ptr& sock) const; /** In case of a host transfer, notify the new host about its status. */ void notify_new_host(); @@ -398,14 +398,14 @@ private: return true; } - bool is_legal_command(const simple_wml::node& command, const socket_ptr user); + bool is_legal_command(const simple_wml::node& command, const socket_ptr& user); /** * Checks whether a user has the same IP as members of this game. * If observer is true it only checks against players. * @return A comma separated string of members with matching IPs. */ - std::string has_same_ip(const socket_ptr user, bool observer) const; + std::string has_same_ip(const socket_ptr& user, bool observer) const; /** * Function which should be called every time a player ends their turn @@ -420,10 +420,10 @@ private: * * Only sends data if the game is initialized but not yet started. */ - void send_user_list(const socket_ptr exclude = socket_ptr()) const; + void send_user_list(const socket_ptr& exclude = socket_ptr()) const; /** Returns the name of the user or "(unfound)". */ - std::string username(const socket_ptr pl) const; + std::string username(const socket_ptr& pl) const; /** Returns a comma separated list of user names. */ std::string list_users(user_vector users, const std::string& func) const; @@ -511,7 +511,7 @@ private: struct game_is_member { - game_is_member(socket_ptr sock) + game_is_member(const socket_ptr& sock) : sock_(sock) { } @@ -522,7 +522,7 @@ struct game_is_member } private: - socket_ptr sock_; + const socket_ptr& sock_; }; struct game_id_matches