Fix an OOS

Previously it could happen that a client would wait for a remote user
imput while still having a non-empty undo stack. Becasue of this the
client would not send the move that issued the user input (because the
client thinks it is undoable) to the other clients which then never gave
the user input.

This resulted in a situation where the game could not proceed and had to
be aborted.

Fixed it by calling resources::undo_stack->clear() as soon as we know
that a remote user input is needed
(synced_context::set_is_simultaneously()). Also added some assertions to
guard against this situation.
This commit is contained in:
gfgtdf 2015-06-14 22:33:43 +02:00
parent aad4e7d600
commit 99d88e0910
3 changed files with 13 additions and 3 deletions

View file

@ -456,10 +456,11 @@ bool undo_list::apply_shroud_changes() const
game_display &disp = *resources::screen;
team &tm = (*resources::teams)[side_ - 1];
// No need to do clearing if fog/shroud has been kept up-to-date.
if ( tm.auto_shroud_updates() || !tm.fog_or_shroud() )
if ( tm.auto_shroud_updates() || !tm.fog_or_shroud() ) {
return false;
}
// If we clear fog or shroud outside a synced context we get OOS
assert(synced_context::get_synced_state() == synced_context::SYNCED);
shroud_clearer clearer;
bool cleared_shroud = false;
const size_t list_size = undos_.size();

View file

@ -433,6 +433,10 @@ void playmp_controller::maybe_linger()
void playmp_controller::pull_remote_choice()
{
// when using a remote user choice undoing must be impossible because that network traffic cannot be undone
// Also turn_data_.sync_network() (which calls turn_data_.send_data()) won't work if the undo stack isn't empty because undoable moves won't be sended
// Also undo_stack_->clear() must be called synced so we cannot do that here.
assert(!undo_stack_->can_undo());
turn_info::PROCESS_DATA_RESULT res = turn_data_.sync_network();
assert(res != turn_info::PROCESS_END_LINGER);
assert(res != turn_info::PROCESS_END_TURN);
@ -444,6 +448,10 @@ void playmp_controller::pull_remote_choice()
void playmp_controller::send_user_choice()
{
// when using a remote user choice undoing must be impossible because that network traffic cannot be undone
// Also turn_data_.send_data() won't work if the undo stack isn't empty because undoable moves won't be sended
// Also undo_stack_->clear() must be called synced so we cannot do that here.
assert(!undo_stack_->can_undo());
turn_data_.send_data();
}

View file

@ -192,6 +192,7 @@ void synced_context::reset_is_simultaneously()
void synced_context::set_is_simultaneously()
{
resources::undo_stack->clear();
is_simultaneously_ = true;
}