diff --git a/changelog b/changelog index 074264136e57..56b97049bea4 100644 --- a/changelog +++ b/changelog @@ -153,6 +153,8 @@ Version 1.13.4+dev: specify the current_player attribute in the [side] wml. * unit filters, specially in wesnoth.get_units now have a limit= attribute to limit the number or matched units. + * Added new attribute "registered_users_only" to MultiplayerServerWML which indicates + that only registered users should be allowed to join the game * Lua API: * wesnoth.match_unit can now take a location (rather than a unit) as the optional third parameter. This will cause the filter to consider @@ -235,6 +237,8 @@ Version 1.13.4+dev: (fr #22635) * Multiplayer: * Hornshark Island: simplified multiplayer faction determination + * Added "Registered users only" checkbox to multiplayer configuration dialog which + when checked, only allows registered users to join the game * Wesnoth formula engine: * Formulas in unit filters can now access nearly all unit attributes The following attributes were renamed (old names still work, for now): diff --git a/data/core/about.cfg b/data/core/about.cfg index 6032c9bf502b..8af73da05021 100644 --- a/data/core/about.cfg +++ b/data/core/about.cfg @@ -1341,6 +1341,9 @@ [entry] name = "Priit Laes (plaes)" [/entry] + [entry] + name = "Pubudu Gunawardena (ugudu)" + [/entry] [entry] name = "Quetzalcoatl" [/entry] diff --git a/players_changelog b/players_changelog index c897c9dd4c47..0f657cfac5ca 100644 --- a/players_changelog +++ b/players_changelog @@ -28,6 +28,9 @@ Version 1.13.4+dev: * Allow changing keybindings for scrolling the map. * Fixed bug #24696 (Nightstalk ability not working) + * Multiplayer + * Added "Registered users only" checkbox to multiplayer configuration dialog which + when checked, only allows registered users to join the game Version 1.13.4: * Language and i18n: diff --git a/src/game_initialization/configure_engine.cpp b/src/game_initialization/configure_engine.cpp index 5e8c28909c89..ad5e14bbc0d8 100644 --- a/src/game_initialization/configure_engine.cpp +++ b/src/game_initialization/configure_engine.cpp @@ -78,6 +78,7 @@ bool configure_engine::random_start_time() const { return parameters_.random_sta bool configure_engine::fog_game() const { return parameters_.fog_game; } bool configure_engine::shroud_game() const { return parameters_.shroud_game; } bool configure_engine::allow_observers() const { return parameters_.allow_observers; } +bool configure_engine::registered_users_only() const { return parameters_.registered_users_only; } bool configure_engine::shuffle_sides() const { return parameters_.shuffle_sides; } mp_game_settings::RANDOM_FACTION_MODE configure_engine::random_faction_mode() const { return parameters_.random_faction_mode; } const config& configure_engine::options() const { return parameters_.options; } @@ -97,6 +98,7 @@ void configure_engine::set_random_start_time(bool val) { parameters_.random_star void configure_engine::set_fog_game(bool val) { parameters_.fog_game = val; } void configure_engine::set_shroud_game(bool val) { parameters_.shroud_game = val; } void configure_engine::set_allow_observers(bool val) { parameters_.allow_observers = val; } +void configure_engine::set_registered_users_only(bool val) { parameters_.registered_users_only = val; } void configure_engine::set_oos_debug(bool val) { state_.classification().oos_debug = val; } void configure_engine::set_shuffle_sides(bool val) { parameters_.shuffle_sides = val; } void configure_engine::set_random_faction_mode(mp_game_settings::RANDOM_FACTION_MODE val) { parameters_.random_faction_mode = val;} @@ -180,6 +182,10 @@ bool configure_engine::shroud_game_default() const { bool configure_engine::allow_observers_default() const { return preferences::allow_observers(); } +bool configure_engine::registered_users_only_default() const +{ + return preferences::registered_users_only(); +} bool configure_engine::shuffle_sides_default() const { return preferences::shuffle_sides(); } diff --git a/src/game_initialization/configure_engine.hpp b/src/game_initialization/configure_engine.hpp index 030f84f30697..72b592749a70 100644 --- a/src/game_initialization/configure_engine.hpp +++ b/src/game_initialization/configure_engine.hpp @@ -55,6 +55,7 @@ class configure_engine bool fog_game() const; bool shroud_game() const; bool allow_observers() const; + bool registered_users_only() const; bool shuffle_sides() const; mp_game_settings::RANDOM_FACTION_MODE random_faction_mode() const; const config& options() const; @@ -75,6 +76,7 @@ class configure_engine void set_fog_game(bool val); void set_shroud_game(bool val); void set_allow_observers(bool val); + void set_registered_users_only(bool val); void set_oos_debug(bool val); void set_shuffle_sides(bool val); void set_random_faction_mode(mp_game_settings::RANDOM_FACTION_MODE val); @@ -99,6 +101,7 @@ class configure_engine bool fog_game_default() const; bool shroud_game_default() const; bool allow_observers_default() const; + bool registered_users_only_default() const; bool shuffle_sides_default() const; mp_game_settings::RANDOM_FACTION_MODE random_faction_mode_default() const; const config& options_default() const; diff --git a/src/game_initialization/multiplayer_configure.cpp b/src/game_initialization/multiplayer_configure.cpp index 0faa551af7d4..d40a8ab50373 100644 --- a/src/game_initialization/multiplayer_configure.cpp +++ b/src/game_initialization/multiplayer_configure.cpp @@ -81,6 +81,7 @@ configure::configure(CVideo& video, twesnothd_connection* wesnothd_connection, c countdown_action_bonus_slider_(video), name_entry_label_(video, _("Name of game:"), font::SIZE_PLUS, font::LOBBY_COLOR), observers_game_(video, _("Observers"), gui::button::TYPE_CHECK), + registered_users_only_(video, _("Registered users only"), gui::button::TYPE_CHECK), oos_debug_(video, _("Debug OOS"), gui::button::TYPE_CHECK), shuffle_sides_(video, _("Shuffle sides"), gui::button::TYPE_CHECK), random_faction_mode_label_(video, _("Random factions:"), font::SIZE_SMALL, font::LOBBY_COLOR), @@ -137,6 +138,10 @@ configure::configure(CVideo& video, twesnothd_connection* wesnothd_connection, c observers_game_.set_help_string(_("Allow users who are not playing to watch the game")); observers_game_.enable(state_.classification().campaign_type != game_classification::CAMPAIGN_TYPE::SCENARIO); + registered_users_only_.set_check(engine_.registered_users_only_default()); + registered_users_only_.set_help_string(_("Allow only registered users to join the game")); + registered_users_only_.enable(state_.classification().campaign_type != game_classification::CAMPAIGN_TYPE::SCENARIO); + oos_debug_.set_check(false); oos_debug_.set_help_string(_("More checks for OOS errors but also more network traffic")); oos_debug_.enable(true); @@ -264,7 +269,10 @@ configure::~configure() // don't set observers preference if disabled (for singleplayer) if (observers_game_.enabled()) preferences::set_allow_observers(engine_.allow_observers()); - + // don't set registered_users_only preference if disabled (for singleplayer) + if (registered_users_only_.enabled()) + preferences::set_registered_users_only(engine_.registered_users_only()); + // When using map settings, the following variables are determined by the map, // so don't store them as the new preferences. if(!engine_.use_map_settings()) { @@ -318,6 +326,7 @@ void configure::get_parameters() engine_.write_parameters(); } engine_.set_allow_observers(observers_game_.checked()); + engine_.set_registered_users_only(registered_users_only_.checked()); engine_.set_oos_debug(oos_debug_.checked()); engine_.set_shuffle_sides(shuffle_sides_.checked()); engine_.set_random_faction_mode(mp_game_settings::RANDOM_FACTION_MODE::from_int(random_faction_mode_.selected())); @@ -509,6 +518,7 @@ void configure::hide_children(bool hide) name_entry_label_.hide(hide); observers_game_.hide(hide); + registered_users_only_.hide(hide); oos_debug_.hide(hide); shuffle_sides_.hide(hide); random_faction_mode_label_.hide(hide); @@ -570,7 +580,9 @@ void configure::layout_children(const SDL_Rect& rect) ypos_left += 2 * border_size; options_pane_left_.add_widget(&shuffle_sides_, xpos_left, ypos_left); options_pane_left_.add_widget(&observers_game_, - xpos_left + (options_pane_left_.width() - xpos_left) / 2 + border_size, ypos_left); + xpos_left + options_pane_left_.width() / 3 + border_size, ypos_left); + options_pane_left_.add_widget(®istered_users_only_, + xpos_left + options_pane_left_.width() * 2/ 3 + border_size, ypos_left); ypos_left += shuffle_sides_.height() + border_size; options_pane_left_.add_widget(&random_faction_mode_label_, xpos_left, ypos_left); diff --git a/src/game_initialization/multiplayer_configure.hpp b/src/game_initialization/multiplayer_configure.hpp index 7934754357fd..d6bb26830873 100644 --- a/src/game_initialization/multiplayer_configure.hpp +++ b/src/game_initialization/multiplayer_configure.hpp @@ -81,6 +81,7 @@ class configure : public mp::ui gui::label name_entry_label_; gui::button observers_game_; + gui::button registered_users_only_; gui::button oos_debug_; gui::button shuffle_sides_; gui::label random_faction_mode_label_; diff --git a/src/game_initialization/multiplayer_lobby.cpp b/src/game_initialization/multiplayer_lobby.cpp index c2864994180f..ca9875cb2b56 100644 --- a/src/game_initialization/multiplayer_lobby.cpp +++ b/src/game_initialization/multiplayer_lobby.cpp @@ -845,6 +845,7 @@ void gamebrowser::populate_game_item(gamebrowser::game_item & item, const config item.time_limit = ""; } item.xp = game["experience_modifier"].str() + "%"; + item.registered_users_only = game["registered_users_only"].to_bool(true); item.observers = game["observer"].to_bool(true); item.shuffle_sides = game["shuffle_sides"].to_bool(true); item.verified = verified; diff --git a/src/game_initialization/multiplayer_lobby.hpp b/src/game_initialization/multiplayer_lobby.hpp index a9c571716c62..3ff5bb6d3d9e 100644 --- a/src/game_initialization/multiplayer_lobby.hpp +++ b/src/game_initialization/multiplayer_lobby.hpp @@ -97,6 +97,7 @@ class gamebrowser : public gui::menu { bool fog; bool shroud; bool observers; + bool registered_users_only; bool shuffle_sides; bool use_map_settings; bool verified; diff --git a/src/game_preferences.cpp b/src/game_preferences.cpp index a78f55b36334..df1701cce507 100644 --- a/src/game_preferences.cpp +++ b/src/game_preferences.cpp @@ -603,6 +603,16 @@ void set_allow_observers(bool value) preferences::set("allow_observers", value); } +bool registered_users_only() +{ + return preferences::get("registered_users_only", false); +} + +void set_registered_users_only(bool value) +{ + preferences::set("registered_users_only", value); +} + bool shuffle_sides() { return preferences::get("shuffle_sides", false); diff --git a/src/game_preferences.hpp b/src/game_preferences.hpp index 4cc10e191fab..af84410f4443 100644 --- a/src/game_preferences.hpp +++ b/src/game_preferences.hpp @@ -139,6 +139,9 @@ class acquaintance; bool allow_observers(); void set_allow_observers(bool value); + bool registered_users_only(); + void set_registered_users_only(bool value); + bool shuffle_sides(); void set_shuffle_sides(bool value); diff --git a/src/mp_game_settings.cpp b/src/mp_game_settings.cpp index c42781625bad..744852eb3c52 100644 --- a/src/mp_game_settings.cpp +++ b/src/mp_game_settings.cpp @@ -53,6 +53,7 @@ mp_game_settings::mp_game_settings() : fog_game(false), shroud_game(false), allow_observers(false), + registered_users_only(false), shuffle_sides(false), saved_game(false), random_faction_mode(RANDOM_FACTION_MODE::DEFAULT), @@ -85,6 +86,7 @@ mp_game_settings::mp_game_settings(const config& cfg) , fog_game(cfg["mp_fog"].to_bool()) , shroud_game(cfg["mp_shroud"].to_bool()) , allow_observers(cfg["observer"].to_bool()) + , registered_users_only(cfg["registered_users_only"].to_bool()) , shuffle_sides(cfg["shuffle_sides"].to_bool()) , saved_game(cfg["savegame"].to_bool()) , random_faction_mode(cfg["random_faction_mode"].to_enum(RANDOM_FACTION_MODE::DEFAULT)) @@ -125,6 +127,7 @@ config mp_game_settings::to_config() const cfg["mp_use_map_settings"] = use_map_settings; cfg["mp_random_start_time"] = random_start_time; cfg["observer"] = allow_observers; + cfg["registered_users_only"] = registered_users_only; cfg["shuffle_sides"] = shuffle_sides; cfg["random_faction_mode"] = random_faction_mode; cfg["savegame"] = saved_game; diff --git a/src/mp_game_settings.hpp b/src/mp_game_settings.hpp index ac29c93fc4f9..87770e130432 100644 --- a/src/mp_game_settings.hpp +++ b/src/mp_game_settings.hpp @@ -59,6 +59,7 @@ struct mp_game_settings bool fog_game; bool shroud_game; bool allow_observers; + bool registered_users_only; bool shuffle_sides; bool saved_game; diff --git a/src/server/game.cpp b/src/server/game.cpp index b7ade527cc69..2394f598e835 100644 --- a/src/server/game.cpp +++ b/src/server/game.cpp @@ -146,6 +146,10 @@ bool game::allow_observers() const { return get_multiplayer(level_.root())["observer"].to_bool(true); } +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 { return std::find(observers_.begin(),observers_.end(),player) != observers_.end(); } diff --git a/src/server/game.hpp b/src/server/game.hpp index 8f0dc248f4fe..661ec6cbb0cd 100644 --- a/src/server/game.hpp +++ b/src/server/game.hpp @@ -55,6 +55,7 @@ class game 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; diff --git a/src/server/server.cpp b/src/server/server.cpp index b16f0625ed72..726e3a1335a8 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -1466,6 +1466,11 @@ void server::handle_join_game(socket_ptr socket, simple_wml::node& join) return; } else if (player_connections_.find(socket)->info().is_moderator()) { // Admins are always allowed to join. + } else if (g->registered_users_only() && !player_connections_.find(socket)->info().registered()) { + async_send_doc(socket, leave_game_doc); + send_server_message(socket, "Only registered users are allowed to join this game."); + async_send_doc(socket, games_and_users_list_); + return; } else if (g->player_is_banned(socket)) { DBG_SERVER << client_address(socket) << "\tReject banned player: " << player_connections_.find(socket)->info().name() << "\tfrom game:\t\"" << g->name()