|
|
@ -102,6 +102,141 @@ const char *ns_strings[NS_COUNT] = |
|
|
|
"Server", |
|
|
|
"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 |
|
|
|
Netchan_Init |
|
|
|