Remove call to window_close(Game_wind) when multiplayer level syncing fails
Replace call to window_close(Game_wind) with returning window_event_result::close to game_handler. Applies to when there is a failure in net_udp_level_sync(). Closing a window within its handler is problematic - it can result in an unstable state.
This commit is contained in:
parent
2ecc4c4a07
commit
a418f8caec
|
@ -60,7 +60,7 @@ namespace dsx {
|
|||
void StartNewGame(int start_level);
|
||||
|
||||
// starts the next level
|
||||
void StartNewLevel(int level_num);
|
||||
window_event_result StartNewLevel(int level_num);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -559,7 +559,7 @@ void multi_add_lifetime_kills(int count);
|
|||
void multi_send_bounty( void );
|
||||
|
||||
void multi_consistency_error(int reset);
|
||||
int multi_level_sync(void);
|
||||
window_event_result multi_level_sync();
|
||||
int multi_endlevel(int *secret);
|
||||
using multi_endlevel_poll = int(newmenu *menu,const d_event &event, const unused_newmenu_userdata_t *);
|
||||
multi_endlevel_poll *get_multi_endlevel_poll2();
|
||||
|
|
|
@ -44,7 +44,7 @@ int net_udp_kmatrix_poll2( newmenu *menu,const d_event &event, const unused_newm
|
|||
void net_udp_send_endlevel_packet();
|
||||
void net_udp_dump_player(const _sockaddr &dump_addr, int why);
|
||||
void net_udp_disconnect_player(int playernum);
|
||||
int net_udp_level_sync();
|
||||
window_event_result net_udp_level_sync();
|
||||
void net_udp_send_mdata_direct(const ubyte *data, int data_len, int pnum, int priority);
|
||||
void net_udp_send_netgame_update();
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
|||
#ifdef __cplusplus
|
||||
#include <cstddef>
|
||||
#include "dsx-ns.h"
|
||||
#include "fwd-window.h"
|
||||
|
||||
extern unsigned state_game_id;
|
||||
extern int state_quick_item;
|
||||
|
@ -101,11 +102,11 @@ static inline int state_restore_all(int in_game, secret_restore, std::nullptr_t,
|
|||
{
|
||||
return state_restore_all(in_game, nullptr, blind);
|
||||
}
|
||||
void StartNewLevelSub(int level_num, int page_in_textures);
|
||||
window_event_result StartNewLevelSub(int level_num, int page_in_textures);
|
||||
// Actually does the work to start new level
|
||||
static inline void StartNewLevelSub(int level_num, int page_in_textures, secret_restore)
|
||||
static inline window_event_result StartNewLevelSub(int level_num, int page_in_textures, secret_restore)
|
||||
{
|
||||
StartNewLevelSub(level_num, page_in_textures);
|
||||
return StartNewLevelSub(level_num, page_in_textures);
|
||||
}
|
||||
void init_player_stats_level();
|
||||
static inline void init_player_stats_level(secret_restore)
|
||||
|
@ -117,7 +118,7 @@ int state_restore_all_sub(const char *filename, secret_restore);
|
|||
void set_pos_from_return_segment(void);
|
||||
int state_save_all(secret_save, blind_save);
|
||||
int state_restore_all(int in_game, secret_restore, const char *filename_override, blind_save);
|
||||
void StartNewLevelSub(int level_num, int page_in_textures, secret_restore);
|
||||
window_event_result StartNewLevelSub(int level_num, int page_in_textures, secret_restore);
|
||||
void init_player_stats_level(secret_restore);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1450,7 +1450,7 @@ static window_event_result AdvanceLevel(int secret_flag)
|
|||
}
|
||||
// END NMN
|
||||
#endif
|
||||
StartNewLevel(Next_level_num);
|
||||
rval = std::max(StartNewLevel(Next_level_num), rval);
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -1563,9 +1563,9 @@ window_event_result DoPlayerDead()
|
|||
//called when the player is starting a new level for normal game mode and restore state
|
||||
// secret_flag set if came from a secret level
|
||||
#if defined(DXX_BUILD_DESCENT_I)
|
||||
void StartNewLevelSub(const int level_num, const int page_in_textures)
|
||||
window_event_result StartNewLevelSub(const int level_num, const int page_in_textures)
|
||||
#elif defined(DXX_BUILD_DESCENT_II)
|
||||
void StartNewLevelSub(const int level_num, const int page_in_textures, const secret_restore secret_flag)
|
||||
window_event_result StartNewLevelSub(const int level_num, const int page_in_textures, const secret_restore secret_flag)
|
||||
#endif
|
||||
{
|
||||
if (!(Game_mode & GM_MULTI)) {
|
||||
|
@ -1597,11 +1597,11 @@ void StartNewLevelSub(const int level_num, const int page_in_textures, const sec
|
|||
|
||||
if (Game_mode & GM_NETWORK)
|
||||
{
|
||||
multi_prep_level_objects();
|
||||
if(multi_level_sync()) // After calling this, Player_num is set
|
||||
multi_prep_level_objects();
|
||||
if (multi_level_sync() == window_event_result::close) // After calling this, Player_num is set
|
||||
{
|
||||
songs_play_song( SONG_TITLE, 1 ); // level song already plays but we fail to start level...
|
||||
return;
|
||||
return window_event_result::close;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1690,6 +1690,8 @@ void StartNewLevelSub(const int level_num, const int page_in_textures, const sec
|
|||
|
||||
if (!Game_wind)
|
||||
game();
|
||||
|
||||
return window_event_result::handled;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1799,7 +1801,7 @@ static void maybe_set_first_secret_visit(int level_num)
|
|||
//called when the player is starting a new level for normal game model
|
||||
// secret_flag if came from a secret level
|
||||
namespace dsx {
|
||||
void StartNewLevel(int level_num)
|
||||
window_event_result StartNewLevel(int level_num)
|
||||
{
|
||||
hide_menus();
|
||||
|
||||
|
@ -1818,7 +1820,7 @@ void StartNewLevel(int level_num)
|
|||
ShowLevelIntro(level_num);
|
||||
#endif
|
||||
|
||||
StartNewLevelSub(level_num, 1, secret_restore::none);
|
||||
return StartNewLevelSub(level_num, 1, secret_restore::none);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3445,7 +3445,7 @@ void multi_prep_level_player(void)
|
|||
|
||||
}
|
||||
|
||||
int multi_level_sync(void)
|
||||
window_event_result multi_level_sync(void)
|
||||
{
|
||||
switch (multi_protocol)
|
||||
{
|
||||
|
@ -3458,6 +3458,8 @@ int multi_level_sync(void)
|
|||
Error("Protocol handling missing in multi_level_sync\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return window_event_result::ignored;
|
||||
}
|
||||
|
||||
namespace dsx {
|
||||
|
|
|
@ -4330,11 +4330,8 @@ static int net_udp_start_game(void)
|
|||
|
||||
Netgame.protocol.udp.your_index = 0; // I am Host. I need to know that y'know? For syncing later.
|
||||
|
||||
if(net_udp_select_players())
|
||||
{
|
||||
StartNewLevel(Netgame.levelnum);
|
||||
}
|
||||
else
|
||||
if (!net_udp_select_players()
|
||||
|| StartNewLevel(Netgame.levelnum) == window_event_result::close)
|
||||
{
|
||||
Game_mode = GM_GAME_OVER;
|
||||
return 0; // see if we want to tweak the game we setup
|
||||
|
@ -4447,7 +4444,7 @@ menu:
|
|||
}
|
||||
|
||||
/* Do required syncing after each level, before starting new one */
|
||||
int net_udp_level_sync()
|
||||
window_event_result net_udp_level_sync()
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
|
@ -4471,13 +4468,11 @@ int net_udp_level_sync()
|
|||
{
|
||||
get_local_player().connected = CONNECT_DISCONNECTED;
|
||||
net_udp_send_endlevel_packet();
|
||||
if (Game_wind)
|
||||
window_close(Game_wind);
|
||||
show_menus();
|
||||
net_udp_close();
|
||||
return -1;
|
||||
return window_event_result::close;
|
||||
}
|
||||
return(0);
|
||||
return window_event_result::handled;
|
||||
}
|
||||
|
||||
namespace dsx {
|
||||
|
@ -4537,9 +4532,7 @@ int net_udp_do_join_game()
|
|||
|
||||
net_udp_set_game_mode(Netgame.gamemode);
|
||||
|
||||
StartNewLevel(Netgame.levelnum);
|
||||
|
||||
return 1; // look ma, we're in a game!!!
|
||||
return StartNewLevel(Netgame.levelnum) == window_event_result::handled; // look ma, we're in a game!!! (If level syncing didn't fail -kreatordxx)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue