If in a MP campaign the endlevel was continue(_no_save)...

...it could happen that the client left before the host uploaded the
new scenarion, this has been fixed.
This commit is contained in:
Mark de Wever 2008-01-01 14:14:06 +00:00
parent 210ea49050
commit 9cb05e205b
6 changed files with 86 additions and 11 deletions

View file

@ -7,6 +7,9 @@ Version 1.3.13+svn:
* updated translations: Chinese, Lithuanian
* multiplayer:
* renaming a unit no longer genarates an OOS error (bug #7864)
* if in a MP campaign the endlevel was continue(_no_save) it could happen
that the client left before the host uploaded the new scenarion, this
has been fixed
* sound:
* timer bell in MP starts when there are 20 seconds left and fades in
gradually for 10 seconds (fr #10559)

View file

@ -174,14 +174,24 @@ LEVEL_RESULT playmp_scenario(const game_data& gameinfo, const config& game_confi
).show();
}
if (!disp.video().faked() && res != QUIT && res != LEVEL_CONTINUE && res != LEVEL_CONTINUE_NO_SAVE)
try {
playcontroller.linger(log, res);
} catch(end_level_exception& e) {
if (e.result == QUIT) {
return QUIT;
if (!disp.video().faked() && res != QUIT) {
if(res == LEVEL_CONTINUE || res == LEVEL_CONTINUE_NO_SAVE) {
if(!playcontroller.is_host()) {
// If we continue without lingering we need to
// make sure the host uploads the next scenario
// before we attempt to download it.
playcontroller.wait_for_upload();
}
} else {
try {
playcontroller.linger(log, res);
} catch(end_level_exception& e) {
if (e.result == QUIT) {
return QUIT;
}
}
}
}
return res;
}

View file

@ -15,6 +15,7 @@
#include "playmp_controller.hpp"
#include "dialogs.hpp"
#include "game_errors.hpp"
#include "gettext.hpp"
#include "log.hpp"
@ -22,6 +23,8 @@
#include "sound.hpp"
#include "upload_log.hpp"
#include <cassert>
#define LOG_NG LOG_STREAM(info, engine)
unsigned int playmp_controller::replay_last_turn_ = 0;
@ -293,6 +296,53 @@ void playmp_controller::linger(upload_log& log, LEVEL_RESULT result)
LOG_NG << "ending end-of-scenario linger\n";
}
//! Wait for the host to upload the next scenario.
void playmp_controller::wait_for_upload()
{
// If the host is here we'll never leave since we wait for the host to
// upload the next scenario.
assert(!is_host_);
const bool set_turn_data = (turn_data_ == 0);
if(set_turn_data) {
turn_data_ = new turn_info(gameinfo_,gamestate_,status_,
*gui_,map_,teams_,player_number_,units_,replay_sender_, undo_stack_);
turn_data_->replay_error().attach_handler(this);
turn_data_->host_transfer().attach_handler(this);
}
while(true) {
try {
config cfg;
const network::connection res = dialogs::network_receive_dialog(
*gui_, _("Waiting for next scenario..."), cfg);
std::deque<config> backlog;
if(res != network::null_connection) {
try{
if(turn_data_->process_network_data(cfg,res,backlog,skip_replay_)
== turn_info::PROCESS_END_LINGER) {
break;
}
}
catch (replay::error& e){
process_oos(e.message);
throw e;
}
}
} catch(end_level_exception& e) {
turn_data_->send_data();
throw e;
}
}
if(set_turn_data) {
delete turn_data_;
turn_data_ = 0;
}
}
void playmp_controller::after_human_turn(){
if ( level_["mp_countdown"] == "yes" ){
const int action_increment = lexical_cast_default<int>(level_["mp_countdown_action_bonus"],0);

View file

@ -41,7 +41,9 @@ public:
bool counting_down();
void think_about_countdown(int ticks);
void process(events::pump_info &info);
void linger(upload_log&, LEVEL_RESULT result);
void linger(upload_log& log, LEVEL_RESULT result);
//! Wait for the host to upload the next scenario.
void wait_for_upload();
protected:
virtual void handle_generic_event(const std::string& name);

View file

@ -286,10 +286,14 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
throw network::error("");
}
//The host has ended linger mode in a campaign -> enable the "End scenario" button
if (cfg.child("notify_next_scenario")){
// The host has ended linger mode in a campaign -> enable the "End scenario" button
// and tell we did get the notification.
if (cfg.child("notify_next_scenario")) {
gui::button* btn_end = gui_.find_button("button-endturn");
btn_end->enable(true);
if(btn_end) {
btn_end->enable(true);
}
return PROCESS_END_LINGER;
}
//If this client becomes the new host, notify the play_controller object about it

View file

@ -44,7 +44,13 @@ public:
void send_data();
enum PROCESS_DATA_RESULT { PROCESS_CONTINUE, PROCESS_RESTART_TURN, PROCESS_END_TURN };
enum PROCESS_DATA_RESULT {
PROCESS_CONTINUE,
PROCESS_RESTART_TURN,
PROCESS_END_TURN,
//! When the host uploaded the next scenario this is returned.
PROCESS_END_LINGER
};
//function which will process incoming network data, and act on it. If there is
//more data than a single turn's worth, excess data will be placed into 'backlog'.