diff --git a/src/game_initialization/lobby_reload_request_exception.hpp b/src/game_initialization/lobby_reload_request_exception.hpp new file mode 100644 index 000000000000..2c392960ee6c --- /dev/null +++ b/src/game_initialization/lobby_reload_request_exception.hpp @@ -0,0 +1,28 @@ +/* + Copyright (C) 2015 by Chris Beck + Part of the Battle for Wesnoth Project http://www.wesnoth.org/ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. + + See the COPYING file for more details. +*/ +#ifndef LOBBY_RELOAD_REQUEST_EXCEPTION_HPP_INCLUDED +#define LOBBY_RELOAD_REQUEST_EXCEPTION_HPP_INCLUDED + +#include +#include + +namespace mp { + +struct lobby_reload_request_exception : game::error { + lobby_reload_request_exception() : game::error("Lobby requested to reload the game config and launch again") {} +}; + +} + +#endif diff --git a/src/game_initialization/multiplayer.cpp b/src/game_initialization/multiplayer.cpp index 72b594606fc1..8550ef650f27 100644 --- a/src/game_initialization/multiplayer.cpp +++ b/src/game_initialization/multiplayer.cpp @@ -27,6 +27,7 @@ #include "gui/widgets/settings.hpp" #include "gui/widgets/window.hpp" #include "hash.hpp" +#include "lobby_reload_request_exception.hpp" #include "log.hpp" #include "generators/map_create.hpp" #include "mp_game_utils.hpp" @@ -904,6 +905,8 @@ void start_local_game_commandline(game_display& disp, const config& game_config, void start_client(game_display& disp, const config& game_config, saved_game& state, const std::string& host) { + const config * game_config_ptr = &game_config; + DBG_MP << "starting client" << std::endl; const network::manager net_manager(1,1); @@ -913,12 +916,27 @@ void start_client(game_display& disp, const config& game_config, switch(type) { case WESNOTHD_SERVER: - enter_lobby_mode(disp, game_config, state); + bool re_enter; + do { + re_enter = false; + try { + enter_lobby_mode(disp, *game_config_ptr, state); + } catch (lobby_reload_request_exception & ex) { + re_enter = true; + game_config_manager * gcm = game_config_manager::get(); + gcm->reload_changed_game_config(); + gcm->load_game_config_for_game(state.classification()); // NOTE: Using reload_changed_game_config doesn't seem to work here + game_config_ptr = &gcm->game_config(); + + gamelist.clear(); //needed to make sure we update which games we have content for + network::send_data(config("refresh_lobby"), 0); + } + } while (re_enter); break; case SIMPLE_SERVER: playmp_controller::set_replay_last_turn(0); preferences::set_message_private(false); - enter_wait_mode(disp, game_config, state, false); + enter_wait_mode(disp, *game_config_ptr, state, false); break; case ABORT_SERVER: break; diff --git a/src/game_initialization/multiplayer_lobby.cpp b/src/game_initialization/multiplayer_lobby.cpp index 4abaeff08e52..b23b6c44fcc4 100644 --- a/src/game_initialization/multiplayer_lobby.cpp +++ b/src/game_initialization/multiplayer_lobby.cpp @@ -31,6 +31,7 @@ #include "gui/auxiliary/old_markup.hpp" #include "gui/dialogs/message.hpp" // for gui2::show_message #include "gui/widgets/window.hpp" // for gui2::twindow::OK +#include "lobby_reload_request_exception.hpp" #include "log.hpp" #include "playmp_controller.hpp" #include "sound.hpp" @@ -1009,8 +1010,8 @@ void lobby::gamelist_updated(bool silent) return; } games_menu_.set_game_items(gamelist(), game_config()); - join_game_.enable(games_menu_.selection_is_joinable()); - observe_game_.enable(games_menu_.selection_is_observable()); + join_game_.enable(games_menu_.selection_is_joinable_with_addons()); + observe_game_.enable(games_menu_.selection_is_observable_with_addons()); } void lobby::process_event() @@ -1027,17 +1028,18 @@ void lobby::process_event() // The return value should be true if the gui result was not chnaged void lobby::process_event_impl(const process_event_data & data) { - join_game_.enable(games_menu_.selection_is_joinable()); - observe_game_.enable(games_menu_.selection_is_observable()); + join_game_.enable(games_menu_.selection_is_joinable_with_addons()); + observe_game_.enable(games_menu_.selection_is_observable_with_addons()); // check whehter to try to download addons - if (games_menu_.selected() && (data.observe || data.join) && games_menu_.selection_needs_addons()) + if ((games_menu_.selected() || data.observe || data.join) && games_menu_.selection_needs_addons()) { if (gui2::show_message(video(), _("Missing user-made content."), _("This game requires one or more user-made addons to join. Do you want to try to install them?"), gui2::tmessage::yes_no_buttons) == gui2::twindow::OK) { std::vector addon_ids = games_menu_.selection_addon_ids(); BOOST_FOREACH(const std::string & id, addon_ids) { ad_hoc_addon_fetch_session(disp(), id); } + throw lobby_reload_request_exception(); } } diff --git a/src/game_initialization/multiplayer_lobby.hpp b/src/game_initialization/multiplayer_lobby.hpp index 2d90b5c05482..679be0b51805 100644 --- a/src/game_initialization/multiplayer_lobby.hpp +++ b/src/game_initialization/multiplayer_lobby.hpp @@ -108,21 +108,20 @@ class gamebrowser : public gui::menu { SDL_Rect get_item_rect(size_t index) const; bool empty() const { return games_.empty(); } bool selection_is_joinable() const - { return empty() ? false : (games_[selected_].vacant_slots > 0 && - !games_[selected_].started && - games_[selected_].have_scenario && - games_[selected_].have_era && - games_[selected_].have_all_mods); } - // Moderators may observe any game. + { return selection_is_joinable_with_addons() && !selection_needs_addons(); } bool selection_is_observable() const - { return empty() ? false : (games_[selected_].observers && - games_[selected_].have_scenario && - games_[selected_].have_era && - games_[selected_].have_all_mods) || - preferences::is_authenticated(); } - bool selection_needs_addons() const // TODO: Add support have downloading addons that require the scenario + { return selection_is_observable_with_addons() && !selection_needs_addons(); } + bool selection_needs_addons() const { return empty() ? false : !games_[selected_].have_era || - !games_[selected_].have_all_mods; } + !games_[selected_].have_all_mods || + !games_[selected_].have_scenario; } + bool selection_is_joinable_with_addons() const + { return empty() ? false : (games_[selected_].vacant_slots > 0 && + !games_[selected_].started); } + // Moderators may observe any game. + bool selection_is_observable_with_addons() const + { return empty() ? false : (games_[selected_].observers || preferences::is_authenticated()); } + std::vector selection_addon_ids() const { return empty() ? std::vector() : utils::split(games_[selected_].addon_ids, ','); } bool selected() const { return double_clicked_ && !empty(); }