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",
|
"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
|
||||||
|
@ -84,6 +84,47 @@ GNU General Public License for more details.
|
|||||||
#define NUM_PACKET_ENTITIES 256 // 170 Mb for multiplayer with 32 players
|
#define NUM_PACKET_ENTITIES 256 // 170 Mb for multiplayer with 32 players
|
||||||
#define MAX_CUSTOM_BASELINES 64
|
#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
|
// added for net_speeds
|
||||||
size_t total_sended;
|
size_t total_sended;
|
||||||
size_t total_received;
|
size_t total_received;
|
||||||
|
qboolean split;
|
||||||
|
unsigned int maxpacket;
|
||||||
|
unsigned int splitid;
|
||||||
|
netsplit_t netsplit;
|
||||||
} netchan_t;
|
} netchan_t;
|
||||||
|
|
||||||
extern netadr_t net_from;
|
extern netadr_t net_from;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user