Added list to keep trace of received PDATA packets so receiver won't interpret them several times
This commit is contained in:
parent
1ec572c7d1
commit
80084bb032
|
@ -1,5 +1,9 @@
|
||||||
D2X-Rebirth Changelog
|
D2X-Rebirth Changelog
|
||||||
|
|
||||||
|
20090215
|
||||||
|
--------
|
||||||
|
main/network.c, main/noloss.c, main/noloss.h: Added list to keep trace of received PDATA packets so receiver won't interpret them several times
|
||||||
|
|
||||||
20090209
|
20090209
|
||||||
--------
|
--------
|
||||||
main/kconfig.c: Removed PH_SCALE on Keyboard readings as caps movement not in sync to FrameTime; Removed scaled Joystick reading as it's not necessary anymore
|
main/kconfig.c: Removed PH_SCALE on Keyboard readings as caps movement not in sync to FrameTime; Removed scaled Joystick reading as it's not necessary anymore
|
||||||
|
|
|
@ -548,6 +548,8 @@ network_disconnect_player(int playernum)
|
||||||
if (VerifyPlayerJoined==playernum)
|
if (VerifyPlayerJoined==playernum)
|
||||||
VerifyPlayerJoined=-1;
|
VerifyPlayerJoined=-1;
|
||||||
|
|
||||||
|
noloss_update_pdata_got(playernum);
|
||||||
|
|
||||||
// create_player_appearance_effect(&Objects[Players[playernum].objnum]);
|
// create_player_appearance_effect(&Objects[Players[playernum].objnum]);
|
||||||
multi_make_player_ghost(playernum);
|
multi_make_player_ghost(playernum);
|
||||||
|
|
||||||
|
@ -4229,7 +4231,8 @@ void network_read_pdata_packet(ubyte *data )
|
||||||
TheirObjnum = Players[pd->playernum].objnum;
|
TheirObjnum = Players[pd->playernum].objnum;
|
||||||
|
|
||||||
if (pd->type == PID_PDATA_NOLOSS)
|
if (pd->type == PID_PDATA_NOLOSS)
|
||||||
noloss_send_ack(pd->numpackets, pd->playernum);
|
if (noloss_validate_pdata(pd->numpackets, pd->playernum) == 0)
|
||||||
|
return; // got that one already!
|
||||||
|
|
||||||
if (TheirPlayernum < 0) {
|
if (TheirPlayernum < 0) {
|
||||||
Int3(); // This packet is bogus!!
|
Int3(); // This packet is bogus!!
|
||||||
|
@ -4388,7 +4391,8 @@ void network_read_pdata_short_packet(short_frame_info *pd )
|
||||||
TheirObjnum = Players[new_pd.playernum].objnum;
|
TheirObjnum = Players[new_pd.playernum].objnum;
|
||||||
|
|
||||||
if (new_pd.type == PID_PDATA_NOLOSS)
|
if (new_pd.type == PID_PDATA_NOLOSS)
|
||||||
noloss_send_ack(new_pd.numpackets, new_pd.playernum);
|
if (noloss_validate_pdata(new_pd.numpackets, new_pd.playernum) == 0)
|
||||||
|
return; // got that one already!
|
||||||
|
|
||||||
if (TheirPlayernum < 0) {
|
if (TheirPlayernum < 0) {
|
||||||
Int3(); // This packet is bogus!!
|
Int3(); // This packet is bogus!!
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "noloss.h"
|
#include "noloss.h"
|
||||||
|
|
||||||
struct pdata_noloss_store noloss_queue[NOLOSS_QUEUE_SIZE];
|
struct pdata_noloss_store noloss_queue[NOLOSS_QUEUE_SIZE];
|
||||||
|
struct pdata_recv noloss_pdata_got[MAX_PLAYERS];
|
||||||
extern frame_info MySyncPack;
|
extern frame_info MySyncPack;
|
||||||
extern int MaxXDataSize;
|
extern int MaxXDataSize;
|
||||||
extern int N_players;
|
extern int N_players;
|
||||||
|
@ -31,6 +32,8 @@ void noloss_add_packet_to_queue(int urgent, int pkt_num, char *data, ushort data
|
||||||
|
|
||||||
for (i = 0; i < NOLOSS_QUEUE_SIZE; i++)
|
for (i = 0; i < NOLOSS_QUEUE_SIZE; i++)
|
||||||
{
|
{
|
||||||
|
int j;
|
||||||
|
|
||||||
if (noloss_queue[i].used)
|
if (noloss_queue[i].used)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -38,8 +41,13 @@ void noloss_add_packet_to_queue(int urgent, int pkt_num, char *data, ushort data
|
||||||
noloss_queue[i].pkt_initial_timestamp = GameTime;
|
noloss_queue[i].pkt_initial_timestamp = GameTime;
|
||||||
noloss_queue[i].pkt_timestamp = GameTime;
|
noloss_queue[i].pkt_timestamp = GameTime;
|
||||||
noloss_queue[i].pkt_num = pkt_num;
|
noloss_queue[i].pkt_num = pkt_num;
|
||||||
memset( &noloss_queue[i].player_ack, 0, sizeof(ubyte)*MAX_PLAYERS );
|
for (j = 0; j < MAX_PLAYERS; j++)
|
||||||
noloss_queue[i].N_players = N_players;
|
{
|
||||||
|
if (Players[j].connected)
|
||||||
|
noloss_queue[i].player_ack[j] = 0;
|
||||||
|
else
|
||||||
|
noloss_queue[i].player_ack[j] = 1; // Player is not connected so set to positive in case he joins
|
||||||
|
}
|
||||||
memcpy( &noloss_queue[i].data[0], data, data_size );
|
memcpy( &noloss_queue[i].data[0], data, data_size );
|
||||||
noloss_queue[i].data_size = data_size;
|
noloss_queue[i].data_size = data_size;
|
||||||
|
|
||||||
|
@ -139,9 +147,12 @@ void noloss_send_queued_packet(int queue_index)
|
||||||
// We have received a PDATA packet. Send ACK response to sender!
|
// We have received a PDATA packet. Send ACK response to sender!
|
||||||
// ACK packet needs to contain: packet num, sender player num, receiver player num
|
// ACK packet needs to contain: packet num, sender player num, receiver player num
|
||||||
// Call in network_process_packet() at case PID_PDATA
|
// Call in network_process_packet() at case PID_PDATA
|
||||||
void noloss_send_ack(int pkt_num, ubyte receiver_pnum)
|
// Also check in our noloss_pdata_got list, if we got this packet already.
|
||||||
|
// If yes, return 0 (not valid)! If not, add this pkt_num to our list and return 1 so the pdata packet will be processed!
|
||||||
|
int noloss_validate_pdata(int pkt_num, ubyte receiver_pnum)
|
||||||
{
|
{
|
||||||
noloss_ack ack;
|
noloss_ack ack;
|
||||||
|
int i;
|
||||||
|
|
||||||
memset(&ack,0,sizeof(noloss_ack));
|
memset(&ack,0,sizeof(noloss_ack));
|
||||||
|
|
||||||
|
@ -151,6 +162,17 @@ void noloss_send_ack(int pkt_num, ubyte receiver_pnum)
|
||||||
ack.pkt_num = pkt_num;
|
ack.pkt_num = pkt_num;
|
||||||
|
|
||||||
netdrv_send_packet_data( (ubyte *)&ack, sizeof(noloss_ack), NetPlayers.players[receiver_pnum].network.ipx.server, NetPlayers.players[receiver_pnum].network.ipx.node,Players[receiver_pnum].net_address );
|
netdrv_send_packet_data( (ubyte *)&ack, sizeof(noloss_ack), NetPlayers.players[receiver_pnum].network.ipx.server, NetPlayers.players[receiver_pnum].network.ipx.node,Players[receiver_pnum].net_address );
|
||||||
|
|
||||||
|
for (i = 0; i < NOLOSS_QUEUE_SIZE; i++)
|
||||||
|
{
|
||||||
|
if (pkt_num == noloss_pdata_got[receiver_pnum].pkt_num[i])
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
noloss_pdata_got[receiver_pnum].cur_slot++;
|
||||||
|
if (noloss_pdata_got[receiver_pnum].cur_slot >= NOLOSS_QUEUE_SIZE)
|
||||||
|
noloss_pdata_got[receiver_pnum].cur_slot=0;
|
||||||
|
noloss_pdata_got[receiver_pnum].pkt_num[noloss_pdata_got[receiver_pnum].cur_slot] = pkt_num;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We got an ACK by a player. Set this player slot to positive!
|
// We got an ACK by a player. Set this player slot to positive!
|
||||||
|
@ -176,6 +198,14 @@ void noloss_got_ack(ubyte *data)
|
||||||
void noloss_init_queue(void)
|
void noloss_init_queue(void)
|
||||||
{
|
{
|
||||||
memset(&noloss_queue,0,sizeof(pdata_noloss_store)*NOLOSS_QUEUE_SIZE);
|
memset(&noloss_queue,0,sizeof(pdata_noloss_store)*NOLOSS_QUEUE_SIZE);
|
||||||
|
memset(&noloss_pdata_got,-1,sizeof(pdata_recv)*MAX_PLAYERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the trace list for given player when disconnect happens
|
||||||
|
void noloss_update_pdata_got(int player_num)
|
||||||
|
{
|
||||||
|
memset(&noloss_pdata_got[player_num].pkt_num,-1,sizeof(int)*NOLOSS_QUEUE_SIZE);
|
||||||
|
noloss_pdata_got[player_num].cur_slot = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The main queue-process function.
|
// The main queue-process function.
|
||||||
|
@ -192,22 +222,12 @@ void noloss_process_queue(void)
|
||||||
if (!noloss_queue[i].used)
|
if (!noloss_queue[i].used)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If N_players differs (because of disconnet), we resend to all to make sure we we get the right ACK packets for the right players
|
// Check if at least one connected player has not ACK'd the packet
|
||||||
if (N_players != noloss_queue[i].N_players)
|
for (j = 0; j < N_players; j++)
|
||||||
{
|
{
|
||||||
memset( noloss_queue[i].player_ack, 0, sizeof(ubyte)*8 );
|
if (!noloss_queue[i].player_ack[j] && Players[j].connected && j != Player_num)
|
||||||
noloss_queue[i].N_players = N_players;
|
|
||||||
resend = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Check if at least one connected player has not ACK'd the packet
|
|
||||||
for (j = 0; j < N_players; j++)
|
|
||||||
{
|
{
|
||||||
if (!noloss_queue[i].player_ack[j] && Players[j].connected && j != Player_num)
|
resend = 1;
|
||||||
{
|
|
||||||
resend = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ typedef struct pdata_noloss_store {
|
||||||
fix pkt_timestamp; // Packet timestamp
|
fix pkt_timestamp; // Packet timestamp
|
||||||
int pkt_num; // Packet number
|
int pkt_num; // Packet number
|
||||||
ubyte player_ack[MAX_PLAYERS]; // 0 if player has not ACK'd this packet, 1 if ACK'd or not connected
|
ubyte player_ack[MAX_PLAYERS]; // 0 if player has not ACK'd this packet, 1 if ACK'd or not connected
|
||||||
int N_players; // Save N_players, too - so if a player disconnects we will resend to make sure all acks are related to the right players
|
|
||||||
char data[NET_XDATA_SIZE]; // extra data of a packet - contains all multibuf data we don't want to loose
|
char data[NET_XDATA_SIZE]; // extra data of a packet - contains all multibuf data we don't want to loose
|
||||||
ushort data_size;
|
ushort data_size;
|
||||||
} __pack__ pdata_noloss_store;
|
} __pack__ pdata_noloss_store;
|
||||||
|
@ -35,8 +34,15 @@ typedef struct noloss_ack {
|
||||||
int pkt_num;
|
int pkt_num;
|
||||||
} __pack__ noloss_ack;
|
} __pack__ noloss_ack;
|
||||||
|
|
||||||
|
// keeps track of PDATA packets we've already got
|
||||||
|
typedef struct pdata_recv {
|
||||||
|
int pkt_num[NOLOSS_QUEUE_SIZE];
|
||||||
|
int cur_slot; // index we can use for a new pkt_num
|
||||||
|
} __pack__ pdata_recv;
|
||||||
|
|
||||||
void noloss_add_packet_to_queue(int urgent, int pkt_num, char *data, ushort data_size);
|
void noloss_add_packet_to_queue(int urgent, int pkt_num, char *data, ushort data_size);
|
||||||
void noloss_send_ack(int pkt_num, ubyte receiver_pnum);
|
int noloss_validate_pdata(int pkt_num, ubyte receiver_pnum);
|
||||||
void noloss_got_ack(ubyte *data);
|
void noloss_got_ack(ubyte *data);
|
||||||
void noloss_init_queue(void);
|
void noloss_init_queue(void);
|
||||||
|
void noloss_update_pdata_got(int player_num);
|
||||||
void noloss_process_queue(void);
|
void noloss_process_queue(void);
|
||||||
|
|
Loading…
Reference in a new issue