Reworked Packet Loss Prevention: If an important packet could not be recovered until it timed out, dump player who failed sending/receiving it; Noloss queue can proces spackets until a certain traffic has been reached; In main UDP frame schedule different types of packets depending on PPS to decrease traffic produced in one frame, hopefully preventing too much loss in high-traffic situations; Small code cleanups; Added new dump signal for loss of important packet; When dumping player also disconnect that one in case the dumped player does not accept the signal
This commit is contained in:
parent
a8892bd13a
commit
951f3edd80
|
@ -1,5 +1,9 @@
|
|||
D2X-Rebirth Changelog
|
||||
|
||||
20110919
|
||||
--------
|
||||
main/multi.h, main/net_udp.c: Reworked Packet Loss Prevention: If an important packet could not be recovered until it timed out, dump player who failed sending/receiving it; Noloss queue can proces spackets until a certain traffic has been reached; In main UDP frame schedule different types of packets depending on PPS to decrease traffic produced in one frame, hopefully preventing too much loss in high-traffic situations; Small code cleanups; Added new dump signal for loss of important packet; When dumping player also disconnect that one in case the dumped player does not accept the signal
|
||||
|
||||
20110915
|
||||
--------
|
||||
main/laser.c, main/laser.h, main/multi.c, main/multi.h, main/multibot.c, main/net_udp.c, main/net_udp.h: Added new priority level for MDATA packets to also send them ASAP without the need for an ACK; Streamlined sending multibot and fire packets and on the way artificially and automatically scaling fire rates, energy/ammo usage and damage of weapons in Multiplayer to decrease traffic easy way without changing the Gameplay
|
||||
|
|
|
@ -183,6 +183,7 @@ extern int multi_protocol; // set and determinate used protocol
|
|||
#define DUMP_CONNECTED 5 // never used
|
||||
#define DUMP_LEVEL 6
|
||||
#define DUMP_KICKED 7
|
||||
#define DUMP_PKTTIMEOUT 8
|
||||
|
||||
// Bitmask for netgame_info->AllowedItems to set allowed items in Netgame
|
||||
#define NETFLAG_DOLASER 1
|
||||
|
|
338
main/net_udp.c
338
main/net_udp.c
|
@ -1083,16 +1083,6 @@ void net_udp_close()
|
|||
udp_close_socket(2);
|
||||
}
|
||||
|
||||
int net_udp_how_many_connected()
|
||||
{
|
||||
int num=0,i;
|
||||
|
||||
for (i = 0; i < N_players; i++)
|
||||
if (Players[i].connected)
|
||||
num++;
|
||||
return (num);
|
||||
}
|
||||
|
||||
// Send PID_ENDLEVEL in regular intervals and listen for them (host also does the packets for playing clients)
|
||||
int net_udp_kmatrix_poll1( newmenu *menu, d_event *event, void *userdata )
|
||||
{
|
||||
|
@ -1258,9 +1248,11 @@ net_udp_disconnect_player(int playernum)
|
|||
{
|
||||
if (Network_status==NETSTAT_PLAYING)
|
||||
multi_leave_game();
|
||||
window_set_visible(Game_wind, 0);
|
||||
nm_messagebox(NULL, 1, TXT_OK, "Game was closed by host!");
|
||||
window_set_visible(Game_wind, 1);
|
||||
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();
|
||||
|
@ -1465,6 +1457,10 @@ void net_udp_welcome_player(UDP_sequence_packet *their)
|
|||
HUD_init_message(HM_MULTI, "'%s' %s", Players[player_num].callsign, TXT_REJOIN);
|
||||
else
|
||||
HUD_init_message(HM_MULTI, "%s'%s' %s", RankStrings[Netgame.players[player_num].rank],Players[player_num].callsign, TXT_REJOIN);
|
||||
|
||||
multi_send_score();
|
||||
|
||||
net_udp_noloss_clear_mdata_got(player_num);
|
||||
}
|
||||
|
||||
Players[player_num].KillGoalCount=0;
|
||||
|
@ -2030,11 +2026,17 @@ void net_udp_dump_player(struct _sockaddr dump_addr, int why)
|
|||
// Inform player that he was not chosen for the netgame
|
||||
|
||||
ubyte buf[UPID_DUMP_SIZE];
|
||||
int i;
|
||||
|
||||
buf[0] = UPID_DUMP;
|
||||
buf[1] = why;
|
||||
|
||||
sendto (UDP_Socket[0], buf, sizeof(buf), 0, (struct sockaddr *)&dump_addr, sizeof(struct _sockaddr));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void net_udp_update_netgame(void)
|
||||
|
@ -2544,22 +2546,31 @@ void net_udp_process_dump(ubyte *data, int len, struct _sockaddr sender_addr)
|
|||
if (memcmp((struct _sockaddr *)&sender_addr,(struct _sockaddr *)&Netgame.players[0].protocol.udp.addr,sizeof(struct _sockaddr)))
|
||||
return;
|
||||
|
||||
if (data[1]==DUMP_KICKED)
|
||||
switch (data[1])
|
||||
{
|
||||
if (Network_status==NETSTAT_PLAYING)
|
||||
multi_leave_game();
|
||||
window_set_visible(Game_wind, 0);
|
||||
nm_messagebox(NULL, 1, TXT_OK, "%s has kicked you out!",Players[0].callsign);
|
||||
window_set_visible(Game_wind, 1);
|
||||
multi_quit_game = 1;
|
||||
game_leave_menus();
|
||||
multi_reset_stuff();
|
||||
case DUMP_PKTTIMEOUT:
|
||||
case DUMP_KICKED:
|
||||
if (Network_status==NETSTAT_PLAYING)
|
||||
multi_leave_game();
|
||||
if (Game_wind)
|
||||
window_set_visible(Game_wind, 0);
|
||||
if (data[1] == DUMP_PKTTIMEOUT)
|
||||
nm_messagebox(NULL, 1, TXT_OK, "You were removed from the game.\nYou failed receiving important\npackets. Sorry.");
|
||||
if (data[1] == DUMP_KICKED)
|
||||
nm_messagebox(NULL, 1, TXT_OK, "%s has kicked you out!",Players[0].callsign);
|
||||
if (Game_wind)
|
||||
window_set_visible(Game_wind, 1);
|
||||
multi_quit_game = 1;
|
||||
game_leave_menus();
|
||||
multi_reset_stuff();
|
||||
break;
|
||||
default:
|
||||
if (data[1] < DUMP_CLOSED || data[1] > DUMP_LEVEL) // invalid dump... heh
|
||||
break;
|
||||
nm_messagebox(NULL, 1, TXT_OK, NET_DUMP_STRINGS(data[1]));
|
||||
Network_status = NETSTAT_MENU;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
nm_messagebox(NULL, 1, TXT_OK, NET_DUMP_STRINGS(data[1]));
|
||||
Network_status = NETSTAT_MENU;
|
||||
}
|
||||
}
|
||||
|
||||
void net_udp_process_request(UDP_sequence_packet *their)
|
||||
|
@ -2921,7 +2932,7 @@ int net_udp_start_poll( newmenu *menu, d_event *event, void *userdata )
|
|||
|
||||
static int opt_cinvul, opt_show_on_map;
|
||||
static int opt_setpower,opt_playtime,opt_killgoal,opt_port,opt_marker_view,opt_light;
|
||||
static int opt_difficulty,opt_packets, opt_bright,opt_start_invul, opt_show_names, opt_plp, opt_ffire;
|
||||
static int opt_difficulty,opt_packets, opt_bright,opt_start_invul, opt_show_names, opt_ffire;
|
||||
|
||||
#ifdef USE_TRACKER
|
||||
static int opt_tracker;
|
||||
|
@ -2953,9 +2964,9 @@ void net_udp_more_game_options ()
|
|||
char PlayText[80],KillText[80],srinvul[50],packstring[5];
|
||||
|
||||
#ifdef USE_TRACKER
|
||||
newmenu_item m[18];
|
||||
newmenu_item m[17];
|
||||
#else
|
||||
newmenu_item m[17];
|
||||
newmenu_item m[16];
|
||||
#endif
|
||||
|
||||
snprintf(packstring,sizeof(char)*4,"%d",Netgame.PacketsPerSec);
|
||||
|
@ -3005,8 +3016,6 @@ void net_udp_more_game_options ()
|
|||
m[opt].type = NM_TYPE_TEXT; m[opt].text = "Network port"; opt++;
|
||||
opt_port = opt;
|
||||
m[opt].type = NM_TYPE_INPUT; m[opt].text = UDP_MyPort; m[opt].text_len=5; opt++;
|
||||
opt_plp = opt;
|
||||
m[opt].type = NM_TYPE_CHECK; m[opt].text = "Packet Loss Prevention"; m[opt].value = Netgame.PacketLossPrevention; opt++;
|
||||
|
||||
#ifdef USE_TRACKER
|
||||
opt_tracker = opt;
|
||||
|
@ -3055,7 +3064,6 @@ menu:
|
|||
else
|
||||
Netgame.game_flags &= ~NETGAME_FLAG_SHOW_MAP;
|
||||
Netgame.NoFriendlyFire = m[opt_ffire].value;
|
||||
Netgame.PacketLossPrevention = m[opt_plp].value;
|
||||
|
||||
#ifdef USE_TRACKER
|
||||
Netgame.Tracker = m[opt_tracker].value;
|
||||
|
@ -4218,9 +4226,10 @@ void net_udp_timeout_player(int playernum)
|
|||
void net_udp_do_frame(int force, int listen)
|
||||
{
|
||||
fix64 time = 0;
|
||||
static fix64 last_send_time = 0, last_endlevel_time = 0, last_bcast_time = 0;
|
||||
static fix64 last_send_time = 0, last_endlevel_time = 0, last_bcast_time = 0, last_resync_time = 0;
|
||||
fix pktstageiv = F1_0/Netgame.PacketsPerSec/4;
|
||||
|
||||
if (!(Game_mode&GM_NETWORK))
|
||||
if (!(Game_mode&GM_NETWORK) || UDP_Socket[0] == -1)
|
||||
return;
|
||||
|
||||
time = timer_query();
|
||||
|
@ -4228,82 +4237,101 @@ void net_udp_do_frame(int force, int listen)
|
|||
if (WaitForRefuseAnswer && time>(RefuseTimeLimit+(F1_0*12)))
|
||||
WaitForRefuseAnswer=0;
|
||||
|
||||
// Send player position packet (and endlevel if needed)
|
||||
if (force || time >= (last_send_time+(F1_0/Netgame.PacketsPerSec)))
|
||||
// Step 1: Send positional data
|
||||
if (time >= (last_send_time+pktstageiv))
|
||||
{
|
||||
net_udp_noloss_process_queue(time);
|
||||
multi_send_robot_frame(0);
|
||||
last_send_time = time;
|
||||
net_udp_send_pdata();
|
||||
}
|
||||
|
||||
// Step 2: Send multi buffer
|
||||
if (force || time >= (last_send_time+(pktstageiv*2)))
|
||||
{
|
||||
multi_send_robot_frame(0);
|
||||
net_udp_send_mdata(0, time);
|
||||
}
|
||||
|
||||
if ((time>=last_endlevel_time+F1_0) && Control_center_destroyed)
|
||||
// Step 3: Resend lost multi buffer packets if needed
|
||||
if (time >= (last_send_time+(pktstageiv*3)))
|
||||
{
|
||||
last_endlevel_time = time;
|
||||
net_udp_send_endlevel_packet();
|
||||
net_udp_noloss_process_queue(time);
|
||||
}
|
||||
|
||||
net_udp_ping_frame(time);
|
||||
|
||||
// broadcast lite_info every 10 seconds
|
||||
if (multi_i_am_master() && time>=last_bcast_time+(F1_0*10))
|
||||
// Step 4: Endlevel packets, player sync, Pings, etc.
|
||||
if (time >= (last_send_time+(pktstageiv*4)))
|
||||
{
|
||||
last_bcast_time = time;
|
||||
net_udp_send_game_info(GBcast, UPID_GAME_INFO_LITE);
|
||||
if (listen && Network_send_objects)
|
||||
net_udp_send_objects();
|
||||
if (listen && Network_sending_extras && VerifyPlayerJoined==-1)
|
||||
net_udp_send_extras();
|
||||
if (VerifyPlayerJoined!=-1 && time >= last_resync_time+F1_0)
|
||||
{
|
||||
last_resync_time = time;
|
||||
net_udp_resend_sync_due_to_packet_loss(); // This will resend to UDP_sync_player
|
||||
}
|
||||
|
||||
if ((time>=last_endlevel_time+F1_0) && Control_center_destroyed)
|
||||
{
|
||||
last_endlevel_time = time;
|
||||
net_udp_send_endlevel_packet();
|
||||
}
|
||||
|
||||
// broadcast lite_info every 10 seconds
|
||||
if (multi_i_am_master() && time>=last_bcast_time+(F1_0*10))
|
||||
{
|
||||
last_bcast_time = time;
|
||||
net_udp_send_game_info(GBcast, UPID_GAME_INFO_LITE);
|
||||
#ifdef IPv6
|
||||
net_udp_send_game_info(GMcast_v6, UPID_GAME_INFO_LITE);
|
||||
net_udp_send_game_info(GMcast_v6, UPID_GAME_INFO_LITE);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_TRACKER
|
||||
// If we use the tracker, tell the tracker about us every 10 seconds
|
||||
if( Netgame.Tracker )
|
||||
{
|
||||
// Static variable... the last time we sent to the tracker
|
||||
static fix64 iLastQuery = 0;
|
||||
static int iAttempts = 0;
|
||||
fix64 iNow = timer_query();
|
||||
|
||||
// Set the last query to now if we must
|
||||
if( iLastQuery == 0 )
|
||||
iLastQuery = iNow;
|
||||
|
||||
// Test it
|
||||
if( iTrackerVerified == 0 && iNow >= iLastQuery + ( F1_0 * 3 ) )
|
||||
{
|
||||
// Update it
|
||||
iLastQuery = iNow;
|
||||
iAttempts++;
|
||||
}
|
||||
|
||||
// Have we had all our attempts?
|
||||
if( iTrackerVerified == 0 && iAttempts > 3 )
|
||||
{
|
||||
// Turn off tracker
|
||||
Netgame.Tracker = 0;
|
||||
|
||||
// Reset the static variables for next time
|
||||
iLastQuery = 0;
|
||||
iAttempts = 0;
|
||||
|
||||
// Warn
|
||||
nm_messagebox( TXT_WARNING, 1, TXT_OK, "No response from tracker!\nPossible causes:\nTracker is down\nYour port is likely not open!\n\nTracker: %s\nGame port: %s", GameArg.MplTrackerAddr, UDP_MyPort );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
net_udp_ping_frame(time);
|
||||
|
||||
last_send_time = time;
|
||||
}
|
||||
|
||||
if (listen)
|
||||
{
|
||||
net_udp_timeout_check(time);
|
||||
net_udp_listen();
|
||||
if (VerifyPlayerJoined!=-1 && !(FrameCount & 63))
|
||||
net_udp_resend_sync_due_to_packet_loss(); // This will resend to UDP_sync_player
|
||||
if (Network_send_objects)
|
||||
net_udp_send_objects();
|
||||
if (Network_sending_extras && VerifyPlayerJoined==-1)
|
||||
net_udp_send_extras();
|
||||
}
|
||||
|
||||
#ifdef USE_TRACKER
|
||||
// If we use the tracker, tell the tracker about us every 10 seconds
|
||||
if( Netgame.Tracker )
|
||||
{
|
||||
// Static variable... the last time we sent to the tracker
|
||||
static fix64 iLastQuery = 0;
|
||||
static int iAttempts = 0;
|
||||
fix64 iNow = timer_query();
|
||||
|
||||
// Set the last query to now if we must
|
||||
if( iLastQuery == 0 )
|
||||
iLastQuery = iNow;
|
||||
|
||||
// Test it
|
||||
if( iTrackerVerified == 0 && iNow >= iLastQuery + ( F1_0 * 3 ) )
|
||||
{
|
||||
// Update it
|
||||
iLastQuery = iNow;
|
||||
iAttempts++;
|
||||
}
|
||||
|
||||
// Have we had all our attempts?
|
||||
if( iTrackerVerified == 0 && iAttempts > 3 )
|
||||
{
|
||||
// Turn off tracker
|
||||
Netgame.Tracker = 0;
|
||||
|
||||
// Reset the static variables for next time
|
||||
iLastQuery = 0;
|
||||
iAttempts = 0;
|
||||
|
||||
// Warn
|
||||
nm_messagebox( TXT_WARNING, 1, TXT_OK, "No response from tracker!\nPossible causes:\nTracker is down\nYour port is likely not open!\n\nTracker: %s\nGame port: %s", GameArg.MplTrackerAddr, UDP_MyPort );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* CODE FOR PACKET LOSS PREVENTION - START */
|
||||
|
@ -4313,33 +4341,63 @@ void net_udp_do_frame(int force, int listen)
|
|||
*/
|
||||
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 i;
|
||||
|
||||
int i, found = 0;
|
||||
|
||||
if (!(Game_mode&GM_NETWORK) || UDP_Socket[0] == -1)
|
||||
return;
|
||||
|
||||
if (!Netgame.PacketLossPrevention)
|
||||
return;
|
||||
|
||||
for (i = 0; i < UDP_MDATA_STOR_QUEUE_SIZE; i++)
|
||||
for (i = 0; i < UDP_MDATA_STOR_QUEUE_SIZE; i++) // look for unused or oldest slot
|
||||
{
|
||||
int j;
|
||||
|
||||
if (UDP_mdata_queue[i].used)
|
||||
continue;
|
||||
|
||||
con_printf(CON_VERBOSE, "P#%i: Adding MData pkt_num %i from %i to MData store list\n", Player_num, pkt_num, pnum);
|
||||
|
||||
UDP_mdata_queue[i].used = 1;
|
||||
UDP_mdata_queue[i].pkt_initial_timestamp = time;
|
||||
for (j = 0; j < MAX_PLAYERS; j++)
|
||||
UDP_mdata_queue[i].pkt_timestamp[j] = time;
|
||||
UDP_mdata_queue[i].pkt_num = pkt_num;
|
||||
UDP_mdata_queue[i].Player_num = pnum;
|
||||
memcpy( &UDP_mdata_queue[i].player_ack, player_ack, sizeof(ubyte)*MAX_PLAYERS);
|
||||
memcpy( &UDP_mdata_queue[i].data, data, sizeof(char)*data_size );
|
||||
UDP_mdata_queue[i].data_size = data_size;
|
||||
|
||||
return;
|
||||
{
|
||||
if (UDP_mdata_queue[i].pkt_initial_timestamp > UDP_mdata_queue[found].pkt_initial_timestamp)
|
||||
found = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
con_printf(CON_VERBOSE, "P#%i: MData store list is full!\n", Player_num);
|
||||
|
||||
if (UDP_mdata_queue[found].used) // seems the slot we found is used (list is full) so screw those who still need ack's.
|
||||
{
|
||||
con_printf(CON_VERBOSE, "P#%i: MData store list is full!\n", Player_num);
|
||||
if (multi_i_am_master())
|
||||
{
|
||||
for ( i=1; i<N_players; i++ )
|
||||
if (UDP_mdata_queue[found].player_ack[i] == 0)
|
||||
net_udp_dump_player(Netgame.players[i].protocol.udp.addr, DUMP_PKTTIMEOUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
Netgame.PacketLossPrevention = 0; // Disable PLP - otherwise we get stuck in an infinite loop here. NOTE: We could as well clean the whole queue to continue protect our disconnect signal bit it's not that important - we just wanna leave.
|
||||
if (Network_status==NETSTAT_PLAYING)
|
||||
multi_leave_game();
|
||||
if (Game_wind)
|
||||
window_set_visible(Game_wind, 0);
|
||||
nm_messagebox(NULL, 1, TXT_OK, "You left the game. You failed\nsending important packets.\nSorry.");
|
||||
if (Game_wind)
|
||||
window_set_visible(Game_wind, 1);
|
||||
multi_quit_game = 1;
|
||||
game_leave_menus();
|
||||
multi_reset_stuff();
|
||||
}
|
||||
}
|
||||
|
||||
con_printf(CON_VERBOSE, "P#%i: Adding MData pkt_num %i from %i to MData store list\n", Player_num, pkt_num, pnum);
|
||||
UDP_mdata_queue[found].used = 1;
|
||||
UDP_mdata_queue[found].pkt_initial_timestamp = time;
|
||||
for (i = 0; i < MAX_PLAYERS; i++)
|
||||
UDP_mdata_queue[found].pkt_timestamp[i] = time;
|
||||
UDP_mdata_queue[found].pkt_num = pkt_num;
|
||||
UDP_mdata_queue[found].Player_num = pnum;
|
||||
memcpy( &UDP_mdata_queue[found].player_ack, player_ack, sizeof(ubyte)*MAX_PLAYERS);
|
||||
memcpy( &UDP_mdata_queue[found].data, data, sizeof(char)*data_size );
|
||||
UDP_mdata_queue[found].data_size = data_size;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4358,7 +4416,7 @@ int net_udp_noloss_validate_mdata(uint32_t pkt_num, ubyte sender_pnum, struct _s
|
|||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
if (memcmp((struct _sockaddr *)&sender_addr, (struct _sockaddr *)&Netgame.players[0].protocol.udp.addr, sizeof(struct _sockaddr)))
|
||||
return 0;
|
||||
}
|
||||
|
@ -4431,14 +4489,16 @@ void net_udp_noloss_clear_mdata_got(ubyte player_num)
|
|||
*/
|
||||
void net_udp_noloss_process_queue(fix64 time)
|
||||
{
|
||||
int queuec = 0, plc = 0, count = 0;
|
||||
int queuec = 0, plc = 0, total_len = 0;
|
||||
|
||||
if (!(Game_mode&GM_NETWORK) || UDP_Socket[0] == -1)
|
||||
return;
|
||||
|
||||
if (!Netgame.PacketLossPrevention)
|
||||
return;
|
||||
|
||||
for (queuec = 0; queuec < UDP_MDATA_STOR_QUEUE_SIZE; queuec++)
|
||||
{
|
||||
fix resend_delay = (F1_0/2);
|
||||
int needack = 0;
|
||||
|
||||
if (!UDP_mdata_queue[queuec].used)
|
||||
|
@ -4453,14 +4513,8 @@ void net_udp_noloss_process_queue(fix64 time)
|
|||
|
||||
if (!UDP_mdata_queue[queuec].player_ack[plc])
|
||||
{
|
||||
// Set resend interval
|
||||
if (Netgame.players[plc].ping < 100)
|
||||
resend_delay = (F1_0/3);
|
||||
else
|
||||
resend_delay = (F1_0/2);
|
||||
|
||||
// Resend if enough time has passed.
|
||||
if (UDP_mdata_queue[queuec].pkt_timestamp[plc] + resend_delay <= time)
|
||||
if (UDP_mdata_queue[queuec].pkt_timestamp[plc] + (F1_0/3) <= time)
|
||||
{
|
||||
ubyte buf[sizeof(UDP_mdata_info)];
|
||||
int len = 0;
|
||||
|
@ -4477,7 +4531,7 @@ void net_udp_noloss_process_queue(fix64 time)
|
|||
memcpy(&buf[len], UDP_mdata_queue[queuec].data, sizeof(char)*UDP_mdata_queue[queuec].data_size);
|
||||
len += UDP_mdata_queue[queuec].data_size;
|
||||
sendto (UDP_Socket[0], buf, len, 0, (struct sockaddr *)&Netgame.players[plc].protocol.udp.addr, sizeof(struct _sockaddr));
|
||||
count++;
|
||||
total_len += len;
|
||||
}
|
||||
needack++;
|
||||
}
|
||||
|
@ -4486,12 +4540,35 @@ void net_udp_noloss_process_queue(fix64 time)
|
|||
// Check if we can remove that packet due to to it had no resend's or Timeout
|
||||
if (needack==0 || (UDP_mdata_queue[queuec].pkt_initial_timestamp + UDP_TIMEOUT <= time))
|
||||
{
|
||||
if (needack) // packet timed out but still not all have ack'd. SCREW THEM NOW!
|
||||
{
|
||||
if (multi_i_am_master())
|
||||
{
|
||||
for ( plc=1; plc<N_players; plc++ )
|
||||
if (UDP_mdata_queue[queuec].player_ack[plc] == 0)
|
||||
net_udp_dump_player(Netgame.players[plc].protocol.udp.addr, DUMP_PKTTIMEOUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
Netgame.PacketLossPrevention = 0; // Disable PLP - otherwise we get stuck in an infinite loop here. NOTE: We could as well clean the whole queue to continue protect our disconnect signal bit it's not that important - we just wanna leave.
|
||||
if (Network_status==NETSTAT_PLAYING)
|
||||
multi_leave_game();
|
||||
if (Game_wind)
|
||||
window_set_visible(Game_wind, 0);
|
||||
nm_messagebox(NULL, 1, TXT_OK, "You left the game. You failed\nsending important packets.\nSorry.");
|
||||
if (Game_wind)
|
||||
window_set_visible(Game_wind, 1);
|
||||
multi_quit_game = 1;
|
||||
game_leave_menus();
|
||||
multi_reset_stuff();
|
||||
}
|
||||
}
|
||||
con_printf(CON_VERBOSE, "P#%i: Removing stored pkt_num %i - missing ACKs: %i\n",Player_num, UDP_mdata_queue[queuec].pkt_num, needack);
|
||||
memset(&UDP_mdata_queue[queuec],0,sizeof(UDP_mdata_store));
|
||||
}
|
||||
|
||||
// Send up to 35 packets (5 for all possible clients) from the queue by each time the queue process is called
|
||||
if (count >= 35)
|
||||
// Send up to half our max packet size
|
||||
if (total_len >= (UPID_MAX_SIZE/2))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4503,7 +4580,7 @@ void net_udp_send_mdata_direct(ubyte *data, int data_len, int pnum, int needack)
|
|||
ubyte pack[MAX_PLAYERS];
|
||||
int len = 0;
|
||||
|
||||
if (!(Game_mode&GM_NETWORK))
|
||||
if (!(Game_mode&GM_NETWORK) || UDP_Socket[0] == -1)
|
||||
return;
|
||||
|
||||
if (!(data_len > 0))
|
||||
|
@ -4545,7 +4622,7 @@ void net_udp_send_mdata(int needack, fix64 time)
|
|||
ubyte pack[MAX_PLAYERS];
|
||||
int len = 0, i = 0;
|
||||
|
||||
if (!(Game_mode&GM_NETWORK))
|
||||
if (!(Game_mode&GM_NETWORK) || UDP_Socket[0] == -1)
|
||||
return;
|
||||
|
||||
if (!(UDP_MData.mbuf_size > 0))
|
||||
|
@ -4672,6 +4749,9 @@ void net_udp_send_pdata()
|
|||
{
|
||||
int i = 0, j = 0;
|
||||
|
||||
if (!(Game_mode&GM_NETWORK) || UDP_Socket[0] == -1)
|
||||
return;
|
||||
|
||||
if (multi_i_am_master())
|
||||
{
|
||||
ubyte buf[sizeof(UDP_frame_info)*MAX_PLAYERS];
|
||||
|
|
Loading…
Reference in a new issue