Fixed some Multiplayer bugs: Reactor invulnerable time did not checked for hours spent in level so reactor would become invulnerable again after 60 minutes; Fixed the fix (heh) for misordered explode/reappear packets; Reset Player_eggs_dropped when initializing new ship so eggs are properly dropped when player disconnects two times without respawning; Cleaned player disconnecting a little bit and made code more straightforward

This commit is contained in:
zicodxx 2012-04-12 02:15:23 +02:00
parent a327d380a7
commit 9990b806a5
6 changed files with 79 additions and 101 deletions

View file

@ -1,5 +1,9 @@
D1X-Rebirth Changelog
20120412
--------
main/collide.c, main/gameseq.c, main/multi.c, main/multi.h, main/net_udp.c: Fixed some Multiplayer bugs: Reactor invulnerable time did not checked for hours spent in level so reactor would become invulnerable again after 60 minutes; Fixed the fix (heh) for misordered explode/reappear packets; Reset Player_eggs_dropped when initializing new ship so eggs are properly dropped when player disconnects two times without respawning; Cleaned player disconnecting a little bit and made code more straightforward
20120411
--------
editor/ehostage.c, editor/medrobot.c, ui/file.c, ui/inputbox.c, ui/keypress.c, ui/listbox.c, ui/message.c, ui/uidraw.c: Draw the object rotation velocity, file browser and MessageBox dialogs properly

View file

@ -691,11 +691,11 @@ void apply_damage_to_controlcen(object *controlcen, fix damage, short who)
#ifdef NETWORK
#ifndef SHAREWARE
if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) && (Players[Player_num].time_level < Netgame.control_invul_time))
if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) && ((i2f(Players[Player_num].hours_level*3600)+Players[Player_num].time_level) < Netgame.control_invul_time))
{
if (Objects[who].id == Player_num) {
int secs = f2i(Netgame.control_invul_time-Players[Player_num].time_level) % 60;
int mins = f2i(Netgame.control_invul_time-Players[Player_num].time_level) / 60;
int secs = f2i(Netgame.control_invul_time-(i2f(Players[Player_num].hours_level*3600)+Players[Player_num].time_level)) % 60;
int mins = f2i(Netgame.control_invul_time-(i2f(Players[Player_num].hours_level*3600)+Players[Player_num].time_level)) / 60;
HUD_init_message(HM_DEFAULT, "%s %d:%02d.", TXT_CNTRLCEN_INVUL, mins, secs);
}
return;

View file

@ -390,6 +390,7 @@ void init_player_stats_new_ship()
Players[Player_num].invulnerable_time = 0;
Player_is_dead = 0; //player no longer dead
Player_eggs_dropped = 0;
Players[Player_num].homing_object_dist = -F1_0; // Added by RH
}

View file

@ -105,7 +105,7 @@ int Show_kill_list = 1;
int Show_reticle_name = 1;
fix Show_kill_list_timer = 0;
char PKilledFlags[MAX_NUM_NET_PLAYERS];
sbyte PKilledFlags[MAX_NUM_NET_PLAYERS];
int Bounty_target = 0;
int multi_sending_message[MAX_NUM_NET_PLAYERS] = { 0,0,0,0,0,0,0,0 };
@ -571,8 +571,6 @@ void multi_compute_kill(int killer, int killed)
killed_pnum = Objects[killed].id;
PKilledFlags[killed_pnum]=1;
Assert ((killed_pnum >= 0) && (killed_pnum < N_players));
if (Game_mode & GM_TEAM)
@ -1506,18 +1504,18 @@ multi_do_reappear(char *buf)
objnum = GET_INTEL_SHORT(buf + 2);
Assert(objnum >= 0);
if (pnum != Objects[objnum].id)
return;
if (Objects[Players[pnum].objnum].type != OBJ_GHOST)
if (PKilledFlags[pnum]<=0) // player was not reported dead, so do not accept this packet
{
early_resp[pnum] = objnum;
PKilledFlags[pnum]--;
return;
}
multi_make_ghost_player(Objects[objnum].id);
create_player_appearance_effect(&Objects[objnum]);
PKilledFlags[Objects[objnum].id]=0;
early_resp[pnum] = -1;
PKilledFlags[pnum]=0;
}
void
@ -1612,11 +1610,12 @@ multi_do_player_explode(char *buf)
Players[pnum].flags &= ~(PLAYER_FLAGS_CLOAKED | PLAYER_FLAGS_INVULNERABLE);
Players[pnum].cloak_time = 0;
if (early_resp[pnum] >= 0)
PKilledFlags[pnum]++;
if (PKilledFlags[pnum] < 1) // seems we got reappear already so make him player again!
{
multi_make_ghost_player(Objects[early_resp[pnum]].id);
create_player_appearance_effect(&Objects[early_resp[pnum]]);
early_resp[pnum] = -1;
multi_make_ghost_player(Objects[Players[pnum].objnum].id);
create_player_appearance_effect(&Objects[Players[pnum].objnum]);
PKilledFlags[pnum] = 0;
}
}
@ -1791,11 +1790,46 @@ void multi_disconnect_player(int pnum)
int i, n = 0;
if (!(Game_mode & GM_NETWORK))
return
return;
digi_play_sample( SOUND_HUD_MESSAGE, F1_0 );
if (Players[pnum].connected == CONNECT_PLAYING)
{
digi_play_sample( SOUND_HUD_MESSAGE, F1_0 );
HUD_init_message(HM_MULTI, "%s %s", Players[pnum].callsign, TXT_HAS_LEFT_THE_GAME);
HUD_init_message(HM_MULTI, "%s %s", Players[pnum].callsign, TXT_HAS_LEFT_THE_GAME);
multi_sending_message[pnum] = 0;
if (Network_status == NETSTAT_PLAYING)
{
multi_make_player_ghost(pnum);
multi_strip_robots(pnum);
}
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_multi_disconnect(pnum);
// Bounty target left - select a new one
if( Game_mode & GM_BOUNTY && pnum == Bounty_target && multi_i_am_master() )
{
/* Select a random number */
int new = d_rand() % MAX_NUM_NET_PLAYERS;
/* Make sure they're valid: Don't check against kill flags,
* just in case everyone's dead! */
while( !Players[new].connected )
new = d_rand() % MAX_NUM_NET_PLAYERS;
/* Select new target */
multi_new_bounty_target( new );
/* Send this new data */
multi_send_bounty();
}
}
Players[pnum].connected = CONNECT_DISCONNECTED;
Netgame.players[pnum].connected = CONNECT_DISCONNECTED;
PKilledFlags[pnum] = 1;
switch (multi_protocol)
{
@ -1809,32 +1843,27 @@ void multi_disconnect_player(int pnum)
break;
}
if (pnum == multi_who_is_master()) // Host has left - Quit game!
{
if (Network_status==NETSTAT_PLAYING)
multi_leave_game();
if (Game_wind)
window_set_visible(Game_wind, 0);
nm_messagebox(NULL, 1, TXT_OK, "Host left the game!");
if (Game_wind)
window_set_visible(Game_wind, 1);
multi_quit_game = 1;
game_leave_menus();
multi_reset_stuff();
return;
}
for (i = 0; i < N_players; i++)
if (Players[i].connected) n++;
if (n == 1)
{
HUD_init_message(HM_MULTI, "You are the only person remaining in this netgame");
}
// Bounty target left - select a new one
if( Game_mode & GM_BOUNTY && pnum == Bounty_target && multi_i_am_master() )
{
/* Select a random number */
int new = d_rand() % MAX_NUM_NET_PLAYERS;
/* Make sure they're valid: Don't check against kill flags,
* just in case everyone's dead! */
while( !Players[new].connected )
new = d_rand() % MAX_NUM_NET_PLAYERS;
/* Select new target */
multi_new_bounty_target( new );
/* Send this new data */
multi_send_bounty();
}
multi_sending_message[pnum] = 0;
}
void
@ -2999,8 +3028,7 @@ multi_prep_level(void)
for (i=0;i<MAX_NUM_NET_PLAYERS;i++)
{
early_resp[i] = -1;
PKilledFlags[i]=0;
PKilledFlags[i]=1;
multi_sending_message[i] = 0;
}

View file

@ -73,7 +73,7 @@ extern int multi_protocol; // set and determinate used protocol
// 3 Descent II Shareware
// 4 Descent II Commercial
// > 4 DXX-Rebirth
#define MULTI_PROTO_VERSION 7
#define MULTI_PROTO_VERSION 8
// PROTOCOL VARIABLES AND DEFINES - END

View file

@ -77,7 +77,6 @@ void net_udp_send_pdata();
void net_udp_process_pdata ( ubyte *data, int data_len, struct _sockaddr sender_addr );
void net_udp_read_pdata_short_packet(UDP_frame_info *pd);
void net_udp_timeout_check(fix64 time);
void net_udp_timeout_player(int playernum);
int net_udp_get_new_player_num (UDP_sequence_packet *their);
void net_udp_noloss_add_queue_pkt(uint32_t pkt_num, fix64 time, ubyte *data, ushort data_size, ubyte pnum, ubyte player_ack[MAX_PLAYERS]);
int net_udp_noloss_validate_mdata(uint32_t pkt_num, ubyte sender_pnum, struct _sockaddr sender_addr);
@ -1203,8 +1202,8 @@ net_udp_can_join_netgame(netgame_info *game)
return 0;
}
void
net_udp_disconnect_player(int playernum)
// do UDP stuff to disconnect a player. Should ONLY be called from multi_disconnect_player()
void net_udp_disconnect_player(int playernum)
{
// A player has disconnected from the net game, take whatever steps are
// necessary
@ -1215,36 +1214,10 @@ net_udp_disconnect_player(int playernum)
return;
}
Players[playernum].connected = CONNECT_DISCONNECTED;
Netgame.players[playernum].connected = CONNECT_DISCONNECTED;
if (VerifyPlayerJoined==playernum)
VerifyPlayerJoined=-1;
if (Network_status == NETSTAT_PLAYING)
{
multi_make_player_ghost(playernum);
multi_strip_robots(playernum);
}
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_multi_disconnect(playernum);
net_udp_noloss_clear_mdata_got(playernum);
if (playernum == 0) // Host has left - Quit game!
{
if (Network_status==NETSTAT_PLAYING)
multi_leave_game();
if (Game_wind)
window_set_visible(Game_wind, 0);
nm_messagebox(NULL, 1, TXT_OK, "Host left the game!");
if (Game_wind)
window_set_visible(Game_wind, 1);
multi_quit_game = 1;
game_leave_menus();
multi_reset_stuff();
}
}
void
@ -1970,7 +1943,7 @@ void net_udp_dump_player(struct _sockaddr dump_addr, int why)
if (multi_i_am_master())
for (i = 1; i < N_players; i++)
if (!memcmp((struct _sockaddr *)&dump_addr, (struct _sockaddr *)&Netgame.players[i].protocol.udp.addr, sizeof(struct _sockaddr)))
net_udp_disconnect_player(i);
multi_disconnect_player(i);
}
void net_udp_update_netgame(void)
@ -4019,7 +3992,7 @@ void net_udp_timeout_check(fix64 time)
}
else if ((time - Netgame.players[i].LastPacketTime) > UDP_TIMEOUT)
{
net_udp_timeout_player(i);
multi_disconnect_player(i);
}
}
}
@ -4027,34 +4000,6 @@ void net_udp_timeout_check(fix64 time)
}
}
void net_udp_timeout_player(int playernum)
{
// Remove a player from the game if we haven't heard from them in
// a long time.
int i, n = 0;
Assert(playernum < N_players);
Assert(playernum > -1);
net_udp_disconnect_player(playernum);
if (Network_status == NETSTAT_PLAYING)
{
create_player_appearance_effect(&Objects[Players[playernum].objnum]);
digi_play_sample(SOUND_HUD_MESSAGE, F1_0);
HUD_init_message(HM_MULTI, "%s %s", Players[playernum].callsign, TXT_DISCONNECTING);
}
for (i = 0; i < N_players; i++)
if (Players[i].connected)
n++;
if (n == 1 && Network_status == NETSTAT_PLAYING)
{
HUD_init_message(HM_MULTI, "You are the only person remaining in this netgame");
}
}
void net_udp_do_frame(int force, int listen)
{
fix64 time = 0;
@ -4682,7 +4627,7 @@ void net_udp_read_pdata_short_packet(UDP_frame_info *pd)
if ( Players[TheirPlayernum].connected != CONNECT_DISCONNECTED && pd->connected == CONNECT_DISCONNECTED )
{
Netgame.players[TheirPlayernum].LastPacketTime = timer_query() - UDP_TIMEOUT;
net_udp_timeout_player(TheirPlayernum);
multi_disconnect_player(TheirPlayernum);
return;
}
if ( Players[TheirPlayernum].connected == CONNECT_DISCONNECTED && pd->connected == CONNECT_PLAYING )