mirror of
https://github.com/YGGverse/xash3d-fwgs.git
synced 2025-01-17 18:40:02 +00:00
Port old netsplit implementation
This commit is contained in:
parent
f3ae5159cb
commit
f044a59984
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user