diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index ddbe0205..96acefbc 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -1044,6 +1044,8 @@ void CL_SendConnectPacket( void ) } else { + int extensions = NET_EXT_SPLITSIZE; + if( cl_dlmax->value > FRAGMENT_MAX_SIZE || cl_dlmax->value < FRAGMENT_MIN_SIZE ) Cvar_SetValue( "cl_dlmax", FRAGMENT_DEFAULT_SIZE ); @@ -1053,6 +1055,8 @@ void CL_SendConnectPacket( void ) Info_SetValueForKey( protinfo, "uuid", key, sizeof( protinfo )); Info_SetValueForKey( protinfo, "qport", qport, sizeof( protinfo )); + Info_SetValueForKey( protinfo, "ext", va("%d", extensions), sizeof( protinfo )); + Netchan_OutOfBandPrint( NS_CLIENT, adr, "connect %i %i \"%s\" \"%s\"\n", PROTOCOL_VERSION, cls.challenge, protinfo, cls.userinfo ); Con_Printf( "Trying to connect by modern protocol\n" ); } @@ -1375,6 +1379,24 @@ void CL_SendDisconnectMessage( void ) Netchan_TransmitBits( &cls.netchan, MSG_GetNumBitsWritten( &buf ), MSG_GetData( &buf )); } +int CL_GetSplitSize( void ) +{ + int splitsize; + + if( Host_IsDedicated() ) + return 0; + + if( !(cls.extensions & NET_EXT_SPLITSIZE) ) + return 1400; + + splitsize = cl_dlmax->value; + + if( splitsize < FRAGMENT_MIN_SIZE || splitsize > FRAGMENT_MAX_SIZE ) + Cvar_SetValue( "cl_dlmax", FRAGMENT_DEFAULT_SIZE ); + + return cl_dlmax->value; +} + /* ===================== CL_Reconnect @@ -1399,6 +1421,15 @@ void CL_Reconnect( qboolean setup_netchan ) Con_Reportf( "^2NET_EXT_SPLIT enabled^7 (packet sizes is %d/%d)\n", (int)cl_dlmax->value, 65536 ); } } + else + { + cls.extensions = Q_atoi( Info_ValueForKey( Cmd_Argv( 1 ), "ext" )); + + if( cls.extensions & NET_LEGACY_EXT_SPLIT ) + { + Con_Reportf( "^2NET_EXT_SPLITSIZE enabled^7 (packet size is %d)\n", (int)cl_dlmax->value ); + } + } } else diff --git a/engine/client/client.h b/engine/client/client.h index 13b4c56d..b924dfb4 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -663,6 +663,7 @@ typedef struct qboolean internetservers_pending; // internetservers is waiting for dns request qboolean legacymode; // one-way 48 protocol compatibility netadr_t legacyserver; + int extensions; } client_static_t; #ifdef __cplusplus diff --git a/engine/common/net_ws.c b/engine/common/net_ws.c index 1cbda9de..8130d916 100644 --- a/engine/common/net_ws.c +++ b/engine/common/net_ws.c @@ -1230,10 +1230,7 @@ qboolean NET_QueuePacket( netsrc_t sock, netadr_t *from, byte *data, size_t *len // check for split message if( sock == NS_CLIENT && *(int *)data == NET_HEADER_SPLITPACKET ) { - int splitsize = Cvar_VariableInteger("cl_dlmax"); - if( splitsize < SPLITPACKET_MIN_SIZE || splitsize > SPLITPACKET_MAX_SIZE ) - Cvar_SetValue( "cl_dlmax", MAX_ROUTEABLE_PACKET ); - return NET_GetLong( data, ret, length, Cvar_VariableInteger("cl_dlmax") ); + return NET_GetLong( data, ret, length, CL_GetSplitSize() ); } #endif // lag the packet, if needed diff --git a/engine/common/net_ws.h b/engine/common/net_ws.h index 7901a5a8..ad4f7b8d 100644 --- a/engine/common/net_ws.h +++ b/engine/common/net_ws.h @@ -66,6 +66,7 @@ void NET_ClearLagData( qboolean bClient, qboolean bServer ); #ifndef XASH_DEDICATED qboolean CL_LegacyMode( void ); +int CL_GetSplitSize( void ); #endif #endif//NET_WS_H diff --git a/engine/common/protocol.h b/engine/common/protocol.h index 2990a04e..7ea02024 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -243,6 +243,9 @@ GNU General Public License for more details. extern const char *svc_strings[svc_lastmsg+1]; extern const char *clc_strings[clc_lastmsg+1]; +// FWGS extensions +#define NET_EXT_SPLITSIZE (1U<<0) // set splitsize by cl_dlmax + // legacy protocol definitons #define PROTOCOL_LEGACY_VERSION 48 #define svc_legacy_modelindex 31 // [index][modelpath] diff --git a/engine/server/server.h b/engine/server/server.h index 96d09cf1..3a6d3034 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -252,6 +252,7 @@ typedef struct sv_client_s int challenge; // challenge of this user, randomly generated int userid; // identifying number on server + int extensions; } sv_client_t; /* diff --git a/engine/server/sv_client.c b/engine/server/sv_client.c index 4773f044..8e72b24b 100644 --- a/engine/server/sv_client.c +++ b/engine/server/sv_client.c @@ -108,7 +108,12 @@ int SV_GetFragmentSize( void *pcl, fragsize_t mode ) cl_frag_size = bound( FRAGMENT_MIN_SIZE, cl_frag_size, FRAGMENT_MAX_SIZE ); if( mode != FRAGSIZE_FRAG ) - return cl_frag_size; + { + if( cl->extensions & NET_EXT_SPLITSIZE ) + return cl_frag_size; + else + return 0; // original engine behaviour + } // get in-game fragmentation size if( cl->state == cs_spawned ) @@ -266,6 +271,7 @@ void SV_ConnectClient( netadr_t from ) int i, count = 0; int challenge; const char *s; + int extensions; if( Cmd_Argc() < 5 ) { @@ -307,6 +313,9 @@ void SV_ConnectClient( netadr_t from ) return; } + extensions = Q_atoi( Info_ValueForKey( protinfo, "ext" ) ); + + // LAN servers restrict to class b IP addresses if( !SV_CheckIPRestrictions( from )) { @@ -369,6 +378,7 @@ void SV_ConnectClient( netadr_t from ) newcl->frames = (client_frame_t *)Z_Calloc( sizeof( client_frame_t ) * SV_UPDATE_BACKUP ); newcl->userid = g_userid++; // create unique userid newcl->state = cs_connected; + newcl->extensions = extensions & (NET_EXT_SPLITSIZE); // reset viewentities (from previous level) memset( newcl->viewentity, 0, sizeof( newcl->viewentity )); @@ -379,8 +389,15 @@ void SV_ConnectClient( netadr_t from ) Netchan_Setup( NS_SERVER, &newcl->netchan, from, qport, newcl, SV_GetFragmentSize ); MSG_Init( &newcl->datagram, "Datagram", newcl->datagram_buf, sizeof( newcl->datagram_buf )); // datagram buf + Q_strncpy( newcl->hashedcdkey, Info_ValueForKey( protinfo, "uuid" ), 32 ); + newcl->hashedcdkey[32] = '\0'; + + // build protinfo answer + protinfo[0] = '\0'; + Info_SetValueForKey( protinfo, "ext", va( "%d",newcl->extensions ), sizeof( protinfo ) ); + // send the connect packet to the client - Netchan_OutOfBandPrint( NS_SERVER, from, "client_connect" ); + Netchan_OutOfBandPrint( NS_SERVER, from, "client_connect %s", protinfo ); newcl->upstate = us_inactive; newcl->connection_started = host.realtime; @@ -388,8 +405,7 @@ void SV_ConnectClient( netadr_t from ) newcl->delta_sequence = -1; newcl->flags = 0; - Q_strncpy( newcl->hashedcdkey, Info_ValueForKey( protinfo, "uuid" ), 32 ); - newcl->hashedcdkey[32] = '\0'; + // reset any remaining events memset( &newcl->events, 0, sizeof( newcl->events ));