attempt to fix OoS ...

...that could occur with a network player  immediately following an AI
This commit is contained in:
Dave White 2004-05-27 19:33:55 +00:00
parent ae32e6b032
commit 2f8e298c4f
7 changed files with 26 additions and 22 deletions

View File

@ -30,17 +30,7 @@ villages_per_scout=0
#the gold depending on easy/medium/hard - x/y/z
#define GOLD ON_EASY ON_NORMAL ON_HARD
#ifdef EASY
gold={ON_EASY}
#endif
#ifdef NORMAL
gold={ON_NORMAL}
#endif
#ifdef HARD
gold={ON_HARD}
#endif
{QUANTITY gold {ON_EASY} {ON_NORMAL} {ON_HARD}}
#enddef
#define INCOME ON_EASY ON_NORMAL ON_HARD

View File

@ -172,14 +172,18 @@ const team& ai_interface::current_team() const
void ai_interface::sync_network()
{
if(network::nconnections() > 0) {
info_.turn_data_.send_data();
//receive data first, and then send data. When we sent the end of
//the AI's turn, we don't want there to be any chance where we
//could get data back pertaining to the next turn.
config cfg;
while(network::connection res = network::receive_data(cfg)) {
std::deque<config> backlog;
info_.turn_data_.process_network_data(cfg,res,backlog);
cfg.clear();
}
info_.turn_data_.send_data();
}
}
@ -563,6 +567,7 @@ void ai::do_move()
AI_DIAGNOSTIC("");
recorder.end_turn();
sync_network();
}
bool ai::do_combat(std::map<gamemap::location,paths>& possible_moves, const move_map& srcdst, const move_map& dstsrc, const move_map& enemy_srcdst, const move_map& enemy_dstsrc)

View File

@ -73,7 +73,7 @@ public:
///the constructor. All derived classes should take an argument of type info& which
///they should pass to this constructor
ai_interface(info& arg) : info_(arg), last_interact_(0) {}
virtual ~ai_interface() { sync_network(); }
virtual ~ai_interface() {}
///the function that is called when the AI must play its turn. Derived classes should
///implement their AI algorithm in this function

View File

@ -735,7 +735,9 @@ std::string default_generate_map(size_t width, size_t height, size_t island_size
if(!touches_other_lake) {
const std::string& name = generate_name(name_generator,"lake_name");
labels->insert(std::pair<gamemap::location,std::string>(gamemap::location(x-width/3,y-height/3),name));
const gamemap::location loc(x-width/3,y-height/3);
labels->erase(loc);
labels->insert(std::pair<gamemap::location,std::string>(loc,name));
}
}

View File

@ -514,12 +514,11 @@ redo_turn:
turn_info turn_data(gameinfo,state_of_game,status,
game_config,level,key,gui,
map,teams,player_number,units,
true,textbox_info,replay_sender);
turn_info::BROWSE_AI,textbox_info,replay_sender);
ai_interface::info ai_info(gui,map,gameinfo,units,teams,player_number,status,turn_data);
util::scoped_ptr<ai_interface> ai_obj(create_ai(team_it->ai_algorithm(),ai_info));
ai_obj->play_turn();
ai_obj->sync_network();
gui.invalidate_unit();
gui.invalidate_game_status();
@ -531,7 +530,7 @@ redo_turn:
turn_info turn_data(gameinfo,state_of_game,status,
game_config,level,key,gui,
map,teams,player_number,units,true,textbox_info,replay_sender);
map,teams,player_number,units,turn_info::BROWSE_NETWORKED,textbox_info,replay_sender);
for(;;) {
@ -699,7 +698,7 @@ redo_turn:
turn_info turn_data(gameinfo,state_of_game,status,
game_config,level,key,gui,
map,teams,player_number,units,true,textbox_info,replay_sender);
map,teams,player_number,units,turn_info::BROWSE_NETWORKED,textbox_info,replay_sender);
turn_data.save_game(string_table["save_game_error"],gui::YES_NO);
if(disconnect) {

View File

@ -79,7 +79,7 @@ void play_turn(game_data& gameinfo, game_state& state_of_game,
}
turn_info turn_data(gameinfo,state_of_game,status,terrain_config,level,
key,gui,map,teams,team_num,units,false,textbox,network_sender);
key,gui,map,teams,team_num,units,turn_info::PLAY_TURN,textbox,network_sender);
//execute gotos - first collect gotos in a list
std::vector<gamemap::location> gotos;
@ -130,12 +130,12 @@ turn_info::turn_info(game_data& gameinfo, game_state& state_of_game,
gamestatus& status, const config& terrain_config, config* level,
CKey& key, display& gui, gamemap& map,
std::vector<team>& teams, int team_num,
unit_map& units, bool browse, floating_textbox& textbox, replay_network_sender& replay_sender)
unit_map& units, TURN_MODE mode, floating_textbox& textbox, replay_network_sender& replay_sender)
: paths_wiper(gui),
gameinfo_(gameinfo), state_of_game_(state_of_game), status_(status),
terrain_config_(terrain_config), level_(level),
key_(key), gui_(gui), map_(map), teams_(teams), team_num_(team_num),
units_(units), browse_(browse),
units_(units), browse_(mode != PLAY_TURN), allow_network_commands_(mode == BROWSE_NETWORKED),
left_button_(false), right_button_(false), middle_button_(false),
minimap_scrolling_(false), start_ncmd_(-1),
enemy_paths_(false), path_turns_(0), end_turn_(false), textbox_(textbox), replay_sender_(replay_sender)
@ -2291,6 +2291,11 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
if(turns.empty() == false && from != network::null_connection) {
//forward the data to other peers
network::send_data_all_except(cfg,from);
if(allow_network_commands_ == false) {
gui::show_dialog(gui_,NULL,"Error","Network error: Received unexpected command from remote host",gui::OK_ONLY);
std::cerr << "Received unexpected command from remote host: '" << cfg.write() << "'\n";
}
}
for(config::child_list::const_iterator t = turns.begin(); t != turns.end(); ++t) {

View File

@ -78,12 +78,14 @@ public:
bool active() const { return box.get() != NULL; }
};
enum TURN_MODE { PLAY_TURN, BROWSE_NETWORKED, BROWSE_AI };
turn_info(game_data& gameinfo, game_state& state_of_game,
gamestatus& status, const config& terrain_config, config* level,
CKey& key, display& gui, gamemap& map,
std::vector<team>& teams, int team_num,
unit_map& units, bool browse_only, floating_textbox& textbox, replay_network_sender& network_sender);
unit_map& units, TURN_MODE mode, floating_textbox& textbox, replay_network_sender& network_sender);
void turn_slice();
@ -188,6 +190,7 @@ private:
int team_num_;
unit_map& units_;
bool browse_;
bool allow_network_commands_;
bool left_button_, right_button_, middle_button_;
bool minimap_scrolling_;