Skip to content

Commit

Permalink
fix mp lobby autodownloading of addons
Browse files Browse the repository at this point in the history
Makes the following changes:

When we download new add-ons,
- tear down the mp ui by throwing an exception
- refresh the changed game config, and reload for this game mode
- relaunch the mp lobby, without making a new network connection
- make sure to ask the mp lobby to refresh the games list, so that
we update the joinable / needs addon status appropriately.

After this commit, I have tested that I can prompt other clients
to download add-ons, and that they will do it successsfully and
then be able to join the game.

Still do: Version checking. And, check if the host has an old
version.
  • Loading branch information
cbeck88 committed Mar 15, 2015
1 parent 281014a commit eff4d0b
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 20 deletions.
28 changes: 28 additions & 0 deletions src/game_initialization/lobby_reload_request_exception.hpp
@@ -0,0 +1,28 @@
/*
Copyright (C) 2015 by Chris Beck <render787@gmail.com>
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 <exception>
#include <string>

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
22 changes: 20 additions & 2 deletions src/game_initialization/multiplayer.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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);

Expand All @@ -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;
Expand Down
12 changes: 7 additions & 5 deletions src/game_initialization/multiplayer_lobby.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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()
Expand All @@ -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<std::string> 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();
}
}

Expand Down
25 changes: 12 additions & 13 deletions src/game_initialization/multiplayer_lobby.hpp
Expand Up @@ -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<std::string> selection_addon_ids() const
{ return empty() ? std::vector<std::string>() : utils::split(games_[selected_].addon_ids, ','); }
bool selected() const { return double_clicked_ && !empty(); }
Expand Down

0 comments on commit eff4d0b

Please sign in to comment.