Port old netsplit implementation

This commit is contained in:
mittorn 2019-01-29 17:28:39 +07:00
parent f3ae5159cb
commit f044a59984
2 changed files with 180 additions and 0 deletions

View File

@ -102,6 +102,141 @@ const char *ns_strings[NS_COUNT] =
"Server",
};
/*
=================================
NETWORK PACKET SPLIT
=================================
*/
/*
======================
NetSplit_GetLong
Collect fragmrnts with signature 0xFFFFFFFE to single packet
return true when got full packet
======================
*/
qboolean NetSplit_GetLong( netsplit_t *ns, netadr_t *from, byte *data, size_t *length )
{
netsplit_packet_t *packet = (netsplit_packet_t*)data;
netsplit_chain_packet_t * p;
//ASSERT( *length > NETSPLIT_HEADER_SIZE );
if( *length <= NETSPLIT_HEADER_SIZE ) return false;
LittleLongSW(packet->id);
LittleLongSW(packet->length);
LittleLongSW(packet->part);
p = &ns->packets[packet->id & NETSPLIT_BACKUP_MASK];
// Con_Reportf( S_NOTE "NetSplit_GetLong: packet from %s, id %d, index %d length %d\n", NET_AdrToString( *from ), (int)packet->id, (int)packet->index, (int)*length );
// no packets with this id received
if( packet->id != p->id )
{
// warn if previous packet not received
if( p->received < p->count )
{
//CL_WarnLostSplitPacket();
Con_Reportf( S_WARN "NetSplit_GetLong: lost packet %d\n", p->id );
}
p->id = packet->id;
p->count = packet->count;
p->received = 0;
memset( p->recieved_v, 0, 32 );
}
// use bool vector to detect dup packets
if( p->recieved_v[packet->index >> 5 ] & ( 1 << ( packet->index & 31 ) ) )
{
Con_Reportf( S_WARN "NetSplit_GetLong: dup packet from %s\n", NET_AdrToString( *from ) );
return false;
}
p->received++;
// mark as received
p->recieved_v[packet->index >> 5] |= 1 << ( packet->index & 31 );
// prevent overflow
if( packet->part * packet->index > NET_MAX_PAYLOAD )
{
Con_Reportf( S_WARN "NetSplit_GetLong: packet out fo bounds from %s (part %d index %d)\n", NET_AdrToString( *from ), packet->part, packet->index );
return false;
}
if( packet->length > NET_MAX_PAYLOAD )
{
Con_Reportf( S_WARN "NetSplit_GetLong: packet out fo bounds from %s (length %d)\n", NET_AdrToString( *from ), packet->length );
return false;
}
memcpy( p->data + packet->part * packet->index, packet->data, *length - 18 );
// rewrite results of NET_GetPacket
if( p->received == packet->count )
{
//ASSERT( packet->length % packet->part == (*length - NETSPLIT_HEADER_SIZE) % packet->part );
size_t len = packet->length;
ns->total_received += len;
ns->total_received_uncompressed += len;
*length = len;
// Con_Reportf( S_NOTE "NetSplit_GetLong: packet from %s, id %d received %d length %d\n", NET_AdrToString( *from ), (int)packet->id, (int)p->received, (int)packet->length );
memcpy( data, p->data, len );
return true;
}
else
*length = NETSPLIT_HEADER_SIZE + packet->part;
return false;
}
/*
======================
NetSplit_SendLong
Send parts that are less or equal maxpacket
======================
*/
void NetSplit_SendLong( netsrc_t sock, size_t length, void *data, netadr_t to, unsigned int maxpacket, unsigned int id)
{
netsplit_packet_t packet = {0};
unsigned int part = maxpacket - NETSPLIT_HEADER_SIZE;
packet.signature = LittleLong(0xFFFFFFFE);
packet.id = LittleLong(id);
packet.length = LittleLong(length);
packet.part = LittleLong(part);
packet.count = ( length - 1 ) / part + 1;
//Con_Reportf( S_NOTE "NetSplit_SendLong: packet to %s, count %d, length %d\n", NET_AdrToString( to ), (int)packet.count, (int)packet.length );
while( packet.index < packet.count )
{
unsigned int size = part;
if( size > length )
size = length;
length -= size;
memcpy( packet.data, (const byte*)data + packet.index * part, size );
//Con_Reportf( S_NOTE "NetSplit_SendLong: packet to %s, id %d, index %d\n", NET_AdrToString( to ), (int)packet.id, (int)packet.index );
NET_SendPacket( sock, size + NETSPLIT_HEADER_SIZE, &packet, to );
packet.index++;
}
}
/*
===============
Netchan_Init

View File

@ -84,6 +84,47 @@ GNU General Public License for more details.
#define NUM_PACKET_ENTITIES 256 // 170 Mb for multiplayer with 32 players
#define MAX_CUSTOM_BASELINES 64
#define NET_EXT_SPLIT (1U<<1)
#define NETSPLIT_BACKUP 8
#define NETSPLIT_BACKUP_MASK (NETSPLIT_BACKUP - 1)
#define NETSPLIT_HEADER_SIZE 18
typedef struct netsplit_chain_packet_s
{
// bool vector
unsigned int recieved_v[8];
// serial number
unsigned int id;
byte data[NET_MAX_PAYLOAD];
byte received;
byte count;
} netsplit_chain_packet_t;
// raw packet format
typedef struct netsplit_packet_s
{
unsigned int signature; // 0xFFFFFFFE
unsigned int length;
unsigned int part;
unsigned int id;
// max 256 parts
byte count;
byte index;
byte data[NET_MAX_PAYLOAD - NETSPLIT_HEADER_SIZE];
} netsplit_packet_t;
typedef struct netsplit_s
{
netsplit_chain_packet_t packets[NETSPLIT_BACKUP];
integer64 total_received;
integer64 total_received_uncompressed;
} netsplit_t;
// packet splitting
qboolean NetSplit_GetLong( netsplit_t *ns, netadr_t *from, byte *data, size_t *length );
/*
==============================================================
@ -203,6 +244,10 @@ typedef struct netchan_s
// added for net_speeds
size_t total_sended;
size_t total_received;
qboolean split;
unsigned int maxpacket;
unsigned int splitid;
netsplit_t netsplit;
} netchan_t;
extern netadr_t net_from;