fixes OoS bugs

#5967 (OoS box doesn't appear), 

#5960 (OoS when moving more than range in mp), 

#5954 (OoS with undo in mp)
This commit is contained in:
Jörg Hinrichs 2006-05-22 16:56:04 +00:00
parent 98ec345c33
commit 9a8d4a4cb2
5 changed files with 52 additions and 23 deletions

View file

@ -66,7 +66,8 @@ void playmp_controller::before_human_turn(){
playsingle_controller::before_human_turn();
turn_data_ = new turn_info(gameinfo_,gamestate_,status_,
*gui_,map_,teams_,player_number_,units_,replay_sender_);
*gui_,map_,teams_,player_number_,units_,replay_sender_, undo_stack_);
turn_data_->replay_error().attach_handler(this);
menu_handler_.autosave(status_.turn(), gamestate_.starting_pos);
}
@ -82,8 +83,14 @@ void playmp_controller::play_human_turn(){
const network::connection res = network::receive_data(cfg);
std::deque<config> backlog;
if(res != network::null_connection) {
turn_data_->process_network_data(cfg,res,backlog,skip_replay_);
if(res != network::null_connection) {
try{
turn_data_->process_network_data(cfg,res,backlog,skip_replay_);
}
catch (replay::error& e){
process_oos();
throw e;
}
}
play_slice();
@ -151,6 +158,7 @@ void playmp_controller::after_human_turn(){
//send one more time to make sure network is up-to-date.
turn_data_->send_data();
if (turn_data_ != NULL){
turn_data_->replay_error().detach_handler(this);
delete turn_data_;
turn_data_ = NULL;
}
@ -173,7 +181,8 @@ bool playmp_controller::play_network_turn(){
browse_ = true;
gui_->enable_menu("endturn", false);
turn_info turn_data(gameinfo_,gamestate_,status_,*gui_,
map_,teams_,player_number_,units_, replay_sender_);
map_,teams_,player_number_,units_, replay_sender_, undo_stack_);
turn_data.replay_error().attach_handler(this);
for(;;) {
@ -191,13 +200,20 @@ bool playmp_controller::play_network_turn(){
have_data = from != network::null_connection;
}
if(have_data) {
const turn_info::PROCESS_DATA_RESULT result = turn_data.process_network_data(cfg,from,data_backlog_,skip_replay_);
if(result == turn_info::PROCESS_RESTART_TURN) {
return true;
} else if(result == turn_info::PROCESS_END_TURN) {
break;
}
if(have_data) {
try{
const turn_info::PROCESS_DATA_RESULT result = turn_data.process_network_data(cfg,from,data_backlog_,skip_replay_);
if(result == turn_info::PROCESS_RESTART_TURN) {
return true;
} else if(result == turn_info::PROCESS_END_TURN) {
break;
}
}
catch (replay::error e){
process_oos();
throw e;
}
}
play_slice();
@ -205,13 +221,18 @@ bool playmp_controller::play_network_turn(){
gui_->draw();
}
turn_data.replay_error().detach_handler(this);
LOG_NG << "finished networked...\n";
return false;
}
void playmp_controller::process_oos(){
menu_handler_.save_game(_("The games are out of sync and will have to exit. Do you want to save an error log of your game?"),gui::YES_NO);
}
void playmp_controller::handle_generic_event(const std::string& name){
turn_info turn_data(gameinfo_,gamestate_,status_,*gui_,
map_,teams_,player_number_,units_, replay_sender_);
map_,teams_,player_number_,units_, replay_sender_, undo_stack_);
if (name == "ai_user_interact"){
playsingle_controller::handle_generic_event(name);
@ -221,6 +242,9 @@ void playmp_controller::handle_generic_event(const std::string& name){
|| (name == "ai_enemy_attacked")){
turn_data.sync_network();
}
else if (name == "network_replay_error"){
process_oos();
}
}
bool playmp_controller::can_execute_command(hotkey::HOTKEY_COMMAND command) const

View file

@ -44,7 +44,8 @@ protected:
turn_info* turn_data_;
int beep_warning_time_;
private:
private:
void process_oos();
};

View file

@ -472,7 +472,7 @@ void playsingle_controller::play_ai_turn(){
const cursor::setter cursor_setter(cursor::WAIT);
turn_info turn_data(gameinfo_,gamestate_,status_,*gui_,
map_,teams_,player_number_,units_, replay_sender_);
map_,teams_,player_number_,units_, replay_sender_, undo_stack_);
ai_interface::info ai_info(*gui_,map_,gameinfo_,units_,teams_,player_number_,status_, turn_data);
util::scoped_ptr<ai_interface> ai_obj(create_ai(current_team().ai_algorithm(),ai_info));

View file

@ -22,10 +22,11 @@
turn_info::turn_info(const game_data& gameinfo, game_state& state_of_game,
const gamestatus& status, display& gui, gamemap& map,
std::vector<team>& teams, unsigned int team_num, unit_map& units,
replay_network_sender& replay_sender)
replay_network_sender& replay_sender, undo_list& undo_stack)
: gameinfo_(gameinfo), state_of_game_(state_of_game), status_(status),
gui_(gui), map_(map), teams_(teams), team_num_(team_num),
units_(units), replay_sender_(replay_sender)
units_(units), replay_sender_(replay_sender), replay_error_("network_replay_error"),
undo_stack_(undo_stack)
{}
turn_info::~turn_info(){
@ -107,10 +108,11 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
replay_obj.set_skip(skip_replay);
replay_obj.start_replay();
try {
try{
turn_end = do_replay(gui_,map_,gameinfo_,units_,teams_,
team_num_,status_,state_of_game_,&replay_obj);
} catch(replay::error&) {
}
catch (replay::error&){
//notify remote hosts of out of sync error
config cfg;
config& info = cfg.add_child("info");
@ -118,9 +120,7 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
info["condition"] = "out of sync";
network::send_data(cfg);
//save_game(_("The games are out of sync and will have to exit. Do you want to save an error log of your game?"),gui::YES_NO);
//throw e;
replay_error_.notify_observers();
}
recorder.add_config(**t,replay::MARK_AS_SENT);

View file

@ -21,6 +21,7 @@ class replay_network_sender;
#include "config.hpp"
#include "display.hpp"
#include "gamestatus.hpp"
#include "generic_event.hpp"
#include "network.hpp"
#include "team.hpp"
#include "unit.hpp"
@ -34,7 +35,7 @@ public:
turn_info(const game_data& gameinfo, game_state& state_of_game,
const gamestatus& status, display& gui, gamemap& map,
std::vector<team>& teams, unsigned int team_num, unit_map& units,
replay_network_sender& network_sender);
replay_network_sender& network_sender, undo_list& undo_stack);
~turn_info();
@ -54,6 +55,7 @@ public:
//which case data will not be forwarded
PROCESS_DATA_RESULT process_network_data(const config& cfg,network::connection from,std::deque<config>& backlog, bool skip_replay);
events::generic_event& replay_error() { return replay_error_; }
private:
void change_side_controller(const std::string& side, const std::string& player, bool orphan_side=false);
@ -66,9 +68,11 @@ private:
unsigned int team_num_;
unit_map& units_;
undo_list undo_stack_;
undo_list& undo_stack_;
replay_network_sender& replay_sender_;
events::generic_event replay_error_;
};
#endif