mirror of
https://github.com/FWGS/xash3d-fwgs
synced 2024-11-23 18:30:50 +01:00
network: enable new netsplit, netsplit size settings
This commit is contained in:
parent
480ef0a468
commit
a97d8c119b
@ -65,6 +65,8 @@ convar_t *cl_showevents;
|
||||
convar_t *cl_cmdrate;
|
||||
convar_t *cl_interp;
|
||||
convar_t *cl_dlmax;
|
||||
convar_t *cl_upmax;
|
||||
|
||||
convar_t *cl_lw;
|
||||
convar_t *cl_charset;
|
||||
convar_t *cl_trace_messages;
|
||||
@ -197,12 +199,18 @@ void CL_CheckClientState( void )
|
||||
}
|
||||
}
|
||||
|
||||
int CL_GetFragmentSize( void *unused )
|
||||
int CL_GetFragmentSize( void *unused, fragsize_t mode )
|
||||
{
|
||||
if( mode == FRAGSIZE_SPLIT )
|
||||
return 0;
|
||||
|
||||
if( mode == FRAGSIZE_UNRELIABLE )
|
||||
return NET_MAX_MESSAGE;
|
||||
|
||||
if( Netchan_IsLocal( &cls.netchan ))
|
||||
return FRAGMENT_LOCAL_SIZE;
|
||||
|
||||
return FRAGMENT_MIN_SIZE;
|
||||
return cl_upmax->value;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1876,7 +1884,7 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
// too many fails use default connection method
|
||||
Con_Printf( "hi-speed connection is failed, use default method\n" );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, from, "getchallenge\n" );
|
||||
Cvar_SetValue( "cl_dlmax", FRAGMENT_MIN_SIZE );
|
||||
Cvar_SetValue( "cl_dlmax", FRAGMENT_DEFAULT_SIZE );
|
||||
cls.connect_time = host.realtime;
|
||||
return;
|
||||
}
|
||||
@ -2671,7 +2679,8 @@ void CL_InitLocal( void )
|
||||
name = Cvar_Get( "name", Sys_GetCurrentUser(), FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_PRINTABLEONLY, "player name" );
|
||||
model = Cvar_Get( "model", "", FCVAR_USERINFO|FCVAR_ARCHIVE, "player model ('player' is a singleplayer model)" );
|
||||
cl_updaterate = Cvar_Get( "cl_updaterate", "20", FCVAR_USERINFO|FCVAR_ARCHIVE, "refresh rate of server messages" );
|
||||
cl_dlmax = Cvar_Get( "cl_dlmax", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "max allowed fragment size on download resources" );
|
||||
cl_dlmax = Cvar_Get( "cl_dlmax", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "max allowed outcoming fragment size" );
|
||||
cl_upmax = Cvar_Get( "cl_upmax", "1200", FCVAR_ARCHIVE, "max allowed incoming fragment size" );
|
||||
rate = Cvar_Get( "rate", "3500", FCVAR_USERINFO|FCVAR_ARCHIVE, "player network rate" );
|
||||
topcolor = Cvar_Get( "topcolor", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "player top color" );
|
||||
bottomcolor = Cvar_Get( "bottomcolor", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "player bottom color" );
|
||||
|
@ -776,7 +776,7 @@ void CL_SendCommand( void );
|
||||
void CL_Disconnect_f( void );
|
||||
void CL_ProcessFile( qboolean successfully_received, const char *filename );
|
||||
void CL_WriteUsercmd( sizebuf_t *msg, int from, int to );
|
||||
int CL_GetFragmentSize( void *unused );
|
||||
int CL_GetFragmentSize( void *unused , fragsize_t mode );
|
||||
qboolean CL_PrecacheResources( void );
|
||||
void CL_SetupOverviewParams( void );
|
||||
void CL_UpdateFrameLerp( void );
|
||||
|
@ -710,7 +710,7 @@ static void Netchan_CreateFragments_( netchan_t *chan, sizebuf_t *msg )
|
||||
return;
|
||||
|
||||
if( chan->pfnBlockSize != NULL )
|
||||
chunksize = chan->pfnBlockSize( chan->client );
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
else chunksize = FRAGMENT_MAX_SIZE; // fallback
|
||||
|
||||
wait = (fragbufwaiting_t *)Mem_Calloc( net_mempool, sizeof( fragbufwaiting_t ));
|
||||
@ -871,7 +871,7 @@ void Netchan_CreateFileFragmentsFromBuffer( netchan_t *chan, const char *filenam
|
||||
if( !size ) return;
|
||||
|
||||
if( chan->pfnBlockSize != NULL )
|
||||
chunksize = chan->pfnBlockSize( chan->client );
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
else chunksize = FRAGMENT_MAX_SIZE; // fallback
|
||||
|
||||
if( !LZSS_IsCompressed( pbuf ))
|
||||
@ -969,7 +969,7 @@ int Netchan_CreateFileFragments( netchan_t *chan, const char *filename )
|
||||
}
|
||||
|
||||
if( chan->pfnBlockSize != NULL )
|
||||
chunksize = chan->pfnBlockSize( chan->client );
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
else chunksize = FRAGMENT_MAX_SIZE; // fallback
|
||||
|
||||
Q_strncpy( compressedfilename, filename, sizeof( compressedfilename ));
|
||||
@ -1458,9 +1458,13 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
if( send_from_regular && ( send_from_frag[FRAG_NORMAL_STREAM] ))
|
||||
{
|
||||
send_from_regular = false;
|
||||
int maxsize = MAX_RELIABLE_PAYLOAD;
|
||||
|
||||
if( chan->pfnBlockSize )
|
||||
maxsize = chan->pfnBlockSize( chan->client, FRAGSIZE_SPLIT );
|
||||
|
||||
// if the reliable buffer has gotten too big, queue it at the end of everything and clear out buffer
|
||||
if( MSG_GetNumBytesWritten( &chan->message ) > MAX_RELIABLE_PAYLOAD )
|
||||
if( MSG_GetNumBytesWritten( &chan->message ) + (((uint)length) >> 3) > maxsize )
|
||||
{
|
||||
Netchan_CreateFragments_( chan, &chan->message );
|
||||
MSG_Clear( &chan->message );
|
||||
@ -1627,9 +1631,16 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
chan->last_reliable_sequence = chan->outgoing_sequence - 1;
|
||||
}
|
||||
|
||||
if( MSG_GetNumBitsLeft( &send ) >= length )
|
||||
MSG_WriteBits( &send, data, length );
|
||||
else Con_Printf( S_WARN "Netchan_Transmit: unreliable message overflow\n" );
|
||||
if( length )
|
||||
{
|
||||
int maxsize = NET_MAX_MESSAGE;
|
||||
if( chan->pfnBlockSize )
|
||||
maxsize = chan->pfnBlockSize( chan->client, FRAGSIZE_UNRELIABLE );
|
||||
|
||||
if( MSG_GetNumBytesWritten( &send ) + length >> 3 <= maxsize )
|
||||
MSG_WriteBits( &send, data, length );
|
||||
else Con_Printf( S_WARN "Netchan_Transmit: unreliable message overflow: %d\n", MSG_GetNumBytesWritten( &send ) );
|
||||
}
|
||||
|
||||
// deal with packets that are too small for some networks
|
||||
if( MSG_GetNumBytesWritten( &send ) < 16 && !NET_IsLocalAddress( chan->remote_address )) // packet too small for some networks
|
||||
@ -1658,7 +1669,10 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
// send the datagram
|
||||
if( !CL_IsPlaybackDemo( ))
|
||||
{
|
||||
NET_SendPacket( chan->sock, MSG_GetNumBytesWritten( &send ), MSG_GetData( &send ), chan->remote_address );
|
||||
int splitsize = 1400;
|
||||
if( chan->pfnBlockSize )
|
||||
splitsize = chan->pfnBlockSize( chan->client, FRAGSIZE_SPLIT );
|
||||
NET_SendPacketEx( chan->sock, MSG_GetNumBytesWritten( &send ), MSG_GetData( &send ), chan->remote_address, splitsize );
|
||||
}
|
||||
|
||||
if( SV_Active() && sv_lan.value && sv_lan_rate.value > 1000.0 )
|
||||
|
@ -35,15 +35,16 @@ GNU General Public License for more details.
|
||||
#include "netchan.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
// #define NET_USE_FRAGMENTS
|
||||
#define NET_USE_FRAGMENTS
|
||||
|
||||
#define PORT_ANY -1
|
||||
#define MAX_LOOPBACK 4
|
||||
#define MASK_LOOPBACK (MAX_LOOPBACK - 1)
|
||||
|
||||
#define MAX_ROUTEABLE_PACKET 1400
|
||||
#define SPLIT_SIZE ( MAX_ROUTEABLE_PACKET - sizeof( SPLITPACKET ))
|
||||
#define NET_MAX_FRAGMENTS ( NET_MAX_FRAGMENT / SPLIT_SIZE )
|
||||
#define SPLITPACKET_MIN_SIZE 508 // RFC 791: 576(min ip packet) - 60 (ip header) - 8 (udp header)
|
||||
#define SPLITPACKET_MAX_SIZE 64000
|
||||
#define NET_MAX_FRAGMENTS ( NET_MAX_FRAGMENT / (SPLITPACKET_MIN_SIZE - sizeof( SPLITPACKET )) )
|
||||
|
||||
#ifndef _WIN32 // it seems we need to use WS2 to support it
|
||||
#define HAVE_GETADDRINFO
|
||||
@ -1105,13 +1106,17 @@ NET_GetLong
|
||||
receive long packet from network
|
||||
==================
|
||||
*/
|
||||
qboolean NET_GetLong( byte *pData, int size, int *outSize )
|
||||
qboolean NET_GetLong( byte *pData, int size, int *outSize, int splitsize )
|
||||
{
|
||||
int i, sequence_number, offset;
|
||||
SPLITPACKET *pHeader = (SPLITPACKET *)pData;
|
||||
int packet_number;
|
||||
int packet_count;
|
||||
short packet_id;
|
||||
int body_size = splitsize - sizeof( SPLITPACKET );
|
||||
|
||||
if( body_size < 0 )
|
||||
return false;
|
||||
|
||||
if( size < sizeof( SPLITPACKET ))
|
||||
{
|
||||
@ -1149,7 +1154,7 @@ qboolean NET_GetLong( byte *pData, int size, int *outSize )
|
||||
if( net.split_flags[packet_number] != sequence_number )
|
||||
{
|
||||
if( packet_number == ( packet_count - 1 ))
|
||||
net.split.total_size = size + SPLIT_SIZE * ( packet_count - 1 );
|
||||
net.split.total_size = size + body_size * ( packet_count - 1 );
|
||||
|
||||
net.split.split_count--;
|
||||
net.split_flags[packet_number] = sequence_number;
|
||||
@ -1162,7 +1167,7 @@ qboolean NET_GetLong( byte *pData, int size, int *outSize )
|
||||
Con_DPrintf( "NET_GetLong: Ignoring duplicated split packet %i of %i ( %i bytes )\n", packet_number + 1, packet_count, size );
|
||||
}
|
||||
|
||||
offset = (packet_number * SPLIT_SIZE);
|
||||
offset = (packet_number * body_size);
|
||||
memcpy( net.split.buffer + offset, pData + sizeof( SPLITPACKET ), size );
|
||||
|
||||
// have we received all of the pieces to the packet?
|
||||
@ -1221,13 +1226,13 @@ qboolean NET_QueuePacket( netsrc_t sock, netadr_t *from, byte *data, size_t *len
|
||||
#ifndef XASH_DEDICATED
|
||||
if( CL_LegacyMode() )
|
||||
return NET_LagPacket( true, sock, from, length, data );
|
||||
#endif
|
||||
// check for split message
|
||||
if( *(int *)data == NET_HEADER_SPLITPACKET )
|
||||
{
|
||||
return NET_GetLong( data, ret, length );
|
||||
}
|
||||
|
||||
// check for split message
|
||||
if( sock == NS_CLIENT && *(int *)data == NET_HEADER_SPLITPACKET )
|
||||
{
|
||||
return NET_GetLong( data, ret, length, Cvar_VariableInteger("cl_dlmax") );
|
||||
}
|
||||
#endif
|
||||
// lag the packet, if needed
|
||||
return NET_LagPacket( true, sock, from, length, data );
|
||||
}
|
||||
@ -1288,15 +1293,16 @@ NET_SendLong
|
||||
Fragment long packets, send short directly
|
||||
==================
|
||||
*/
|
||||
int NET_SendLong( netsrc_t sock, int net_socket, const char *buf, int len, int flags, const struct sockaddr *to, int tolen )
|
||||
int NET_SendLong( netsrc_t sock, int net_socket, const char *buf, size_t len, int flags, const struct sockaddr *to, size_t tolen, size_t splitsize )
|
||||
{
|
||||
#ifdef NET_USE_FRAGMENTS
|
||||
// do we need to break this packet up?
|
||||
if( sock == NS_SERVER && len > MAX_ROUTEABLE_PACKET )
|
||||
if( splitsize > sizeof( SPLITPACKET ) && sock == NS_SERVER && len > splitsize )
|
||||
{
|
||||
char packet[MAX_ROUTEABLE_PACKET];
|
||||
char packet[SPLITPACKET_MAX_SIZE];
|
||||
int total_sent, size, packet_count;
|
||||
int ret, packet_number;
|
||||
int body_size = splitsize - sizeof( SPLITPACKET );
|
||||
SPLITPACKET *pPacket;
|
||||
|
||||
net.sequence_number++;
|
||||
@ -1308,13 +1314,13 @@ int NET_SendLong( netsrc_t sock, int net_socket, const char *buf, int len, int f
|
||||
pPacket->net_id = NET_HEADER_SPLITPACKET;
|
||||
packet_number = 0;
|
||||
total_sent = 0;
|
||||
packet_count = (len + SPLIT_SIZE - 1) / SPLIT_SIZE;
|
||||
packet_count = (len + body_size - 1) / body_size;
|
||||
|
||||
while( len > 0 )
|
||||
{
|
||||
size = Q_min( SPLIT_SIZE, len );
|
||||
size = Q_min( body_size, len );
|
||||
pPacket->packet_id = (packet_number << 8) + packet_count;
|
||||
memcpy( packet + sizeof( SPLITPACKET ), buf + ( packet_number * SPLIT_SIZE ), size );
|
||||
memcpy( packet + sizeof( SPLITPACKET ), buf + ( packet_number * body_size ), size );
|
||||
|
||||
if( net_showpackets && net_showpackets->value == 3.0f )
|
||||
{
|
||||
@ -1349,10 +1355,10 @@ int NET_SendLong( netsrc_t sock, int net_socket, const char *buf, int len, int f
|
||||
|
||||
/*
|
||||
==================
|
||||
NET_SendPacket
|
||||
NET_SendPacketEx
|
||||
==================
|
||||
*/
|
||||
void NET_SendPacket( netsrc_t sock, size_t length, const void *data, netadr_t to )
|
||||
void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t to, size_t splitsize )
|
||||
{
|
||||
int ret;
|
||||
struct sockaddr addr;
|
||||
@ -1382,7 +1388,7 @@ void NET_SendPacket( netsrc_t sock, size_t length, const void *data, netadr_t to
|
||||
|
||||
NET_NetadrToSockadr( &to, &addr );
|
||||
|
||||
ret = NET_SendLong( sock, net_socket, data, length, 0, &addr, sizeof( addr ));
|
||||
ret = NET_SendLong( sock, net_socket, data, length, 0, &addr, sizeof( addr ), splitsize );
|
||||
|
||||
if( NET_IsSocketError( ret ))
|
||||
{
|
||||
@ -1412,6 +1418,16 @@ void NET_SendPacket( netsrc_t sock, size_t length, const void *data, netadr_t to
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
NET_SendPacket
|
||||
==================
|
||||
*/
|
||||
void NET_SendPacket( netsrc_t sock, size_t length, const void *data, netadr_t to )
|
||||
{
|
||||
return NET_SendPacketEx( sock, length, data, to, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_BufferToBufferCompress
|
||||
|
@ -61,6 +61,7 @@ qboolean NET_GetPacket( netsrc_t sock, netadr_t *from, byte *data, size_t *lengt
|
||||
qboolean NET_BufferToBufferCompress( char *dest, uint *destLen, char *source, uint sourceLen );
|
||||
qboolean NET_BufferToBufferDecompress( char *dest, uint *destLen, char *source, uint sourceLen );
|
||||
void NET_SendPacket( netsrc_t sock, size_t length, const void *data, netadr_t to );
|
||||
void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t to, size_t splitsize );
|
||||
void NET_ClearLagData( qboolean bClient, qboolean bServer );
|
||||
|
||||
#ifndef XASH_DEDICATED
|
||||
|
@ -59,10 +59,10 @@ GNU General Public License for more details.
|
||||
// {
|
||||
// byte (on/off)
|
||||
// int (fragment id)
|
||||
// short (startpos)
|
||||
// short (length)
|
||||
// int (startpos)
|
||||
// int (length)
|
||||
// }
|
||||
#define HEADER_BYTES ( 8 + MAX_STREAMS * 9 )
|
||||
#define HEADER_BYTES ( 8 + MAX_STREAMS * 13 )
|
||||
|
||||
// Pad this to next higher 16 byte boundary
|
||||
// This is the largest packet that can come in/out over the wire, before processing the header
|
||||
@ -182,6 +182,13 @@ typedef struct fbufqueue_s
|
||||
fragbuf_t *fragbufs; // the actual buffers
|
||||
} fragbufwaiting_t;
|
||||
|
||||
typedef enum fragsize_e
|
||||
{
|
||||
FRAGSIZE_FRAG,
|
||||
FRAGSIZE_SPLIT,
|
||||
FRAGSIZE_UNRELIABLE
|
||||
} fragsize_t;
|
||||
|
||||
// Network Connection Channel
|
||||
typedef struct netchan_s
|
||||
{
|
||||
@ -205,7 +212,7 @@ typedef struct netchan_s
|
||||
|
||||
// callback to get actual framgment size
|
||||
void *client;
|
||||
int (*pfnBlockSize)( void *cl );
|
||||
int (*pfnBlockSize)( void *cl, fragsize_t mode );
|
||||
|
||||
// staging and holding areas
|
||||
sizebuf_t message;
|
||||
|
@ -174,8 +174,8 @@ GNU General Public License for more details.
|
||||
|
||||
#define MAX_RESOURCES (MAX_MODELS+MAX_SOUNDS+MAX_CUSTOM+MAX_EVENTS)
|
||||
#define MAX_RESOURCE_BITS 13 // 13 bits 8192 resource (4096 models + 2048 sounds + 1024 events + 1024 files)
|
||||
|
||||
#define FRAGMENT_MIN_SIZE 1200 // default MTU
|
||||
#define FRAGMENT_MIN_SIZE 508 // RFC 791: 576(min ip packet) - 60 (ip header) - 8 (udp header)
|
||||
#define FRAGMENT_DEFAULT_SIZE 1200 // default MTU
|
||||
#define FRAGMENT_MAX_SIZE 64000 // maximal fragment size
|
||||
#define FRAGMENT_LOCAL_SIZE FRAGMENT_MAX_SIZE // local connection
|
||||
|
||||
|
@ -87,7 +87,7 @@ void SV_GetChallenge( netadr_t from )
|
||||
Netchan_OutOfBandPrint( NS_SERVER, svs.challenges[i].adr, "challenge %i", svs.challenges[i].challenge );
|
||||
}
|
||||
|
||||
int SV_GetFragmentSize( void *pcl )
|
||||
int SV_GetFragmentSize( void *pcl, fragsize_t mode )
|
||||
{
|
||||
sv_client_t *cl = (sv_client_t*)pcl;
|
||||
int cl_frag_size;
|
||||
@ -95,10 +95,25 @@ int SV_GetFragmentSize( void *pcl )
|
||||
if( Netchan_IsLocal( &cl->netchan ))
|
||||
return FRAGMENT_LOCAL_SIZE;
|
||||
|
||||
if( mode == FRAGSIZE_UNRELIABLE )
|
||||
{
|
||||
cl_frag_size = Q_atoi( Info_ValueForKey( cl->userinfo, "cl_urmax" ));
|
||||
if( cl_frag_size == 0 )
|
||||
return NET_MAX_MESSAGE;
|
||||
return bound( FRAGMENT_MAX_SIZE, cl_frag_size, NET_MAX_MESSAGE );
|
||||
}
|
||||
|
||||
cl_frag_size = Q_atoi( Info_ValueForKey( cl->userinfo, "cl_dlmax" ));
|
||||
cl_frag_size = bound( FRAGMENT_MIN_SIZE, cl_frag_size, FRAGMENT_MAX_SIZE );
|
||||
|
||||
return cl_frag_size;
|
||||
if( mode != FRAGSIZE_FRAG )
|
||||
return cl_frag_size;
|
||||
|
||||
// add window for unreliable
|
||||
if( cl->state == cs_spawned )
|
||||
cl_frag_size /= 2;
|
||||
|
||||
return cl_frag_size - HEADER_BYTES;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user