Skip to content

Commit

Permalink
Merge pull request #22 from FWGS/netsplit
Browse files Browse the repository at this point in the history
Extended netsplit, network extensions
  • Loading branch information
a1batross committed Mar 21, 2019
2 parents 94cbb4e + 2b1ed2b commit 6a6f341
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 59 deletions.
75 changes: 58 additions & 17 deletions engine/client/cl_main.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

/*
Expand Down Expand Up @@ -1017,10 +1025,12 @@ void CL_SendConnectPacket( void )
{
// set related userinfo keys
if( cl_dlmax->value >= 40000 || cl_dlmax->value < 100 )
Cvar_FullSet( "cl_maxpacket", "1400", FCVAR_USERINFO );
Info_SetValueForKey( cls.userinfo, "cl_maxpacket", "1400", sizeof( cls.userinfo ) );
else
Cvar_FullSet( "cl_maxpacket", cl_dlmax->string, FCVAR_USERINFO );
Cvar_FullSet( "cl_maxpayload", "1000", FCVAR_USERINFO );
Info_SetValueForKey( cls.userinfo, "cl_maxpacket", cl_dlmax->string, sizeof( cls.userinfo ) );

if( !*Info_ValueForKey( cls.userinfo,"cl_maxpayload") )
Info_SetValueForKey( cls.userinfo, "cl_maxpayload", "1000", sizeof( cls.userinfo ) );

/// TODO: add input devices list
//Info_SetValueForKey( protinfo, "d", va( "%d", input_devices ), sizeof( protinfo ) );
Expand All @@ -1030,17 +1040,24 @@ void CL_SendConnectPacket( void )
Info_SetValueForKey( protinfo, "a", Q_buildarch(), sizeof( protinfo ) );
Info_SetValueForKey( protinfo, "i", ID_GetMD5(), sizeof( protinfo ) );

Netchan_OutOfBandPrint( NS_CLIENT, adr, "connect %i %i %i \"%s\" 2 \"%s\"\n",
PROTOCOL_LEGACY_VERSION, Q_atoi( qport ), cls.challenge, cls.userinfo, protinfo );
Netchan_OutOfBandPrint( NS_CLIENT, adr, "connect %i %i %i \"%s\" %d \"%s\"\n",
PROTOCOL_LEGACY_VERSION, Q_atoi( qport ), cls.challenge, cls.userinfo, NET_LEGACY_EXT_SPLIT, protinfo );
Con_Printf( "Trying to connect by legacy protocol\n" );
}
else
{
// remove useless userinfo keys
Cvar_FullSet( "cl_maxpacket", "0", 0 );
Cvar_FullSet( "cl_maxpayload", "1000", 0 );
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 );

Info_RemoveKey( cls.userinfo,"cl_maxpacket" );
Info_RemoveKey( cls.userinfo, "cl_maxpayload" );

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" );
}
Expand Down Expand Up @@ -1364,6 +1381,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
Expand All @@ -1381,13 +1416,22 @@ void CL_Reconnect( qboolean setup_netchan )
{
unsigned int extensions = Q_atoi( Cmd_Argv( 1 ) );

if( extensions & NET_EXT_SPLIT )
if( extensions & NET_LEGACY_EXT_SPLIT )
{
// only enable incoming split for legacy mode
cls.netchan.split = true;
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_EXT_SPLITSIZE )
{
Con_Reportf( "^2NET_EXT_SPLITSIZE enabled^7 (packet size is %d)\n", (int)cl_dlmax->value );
}
}

}
else
Expand Down Expand Up @@ -1892,7 +1936,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;
}
Expand Down Expand Up @@ -2698,7 +2742,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" );
Expand All @@ -2708,10 +2753,6 @@ void CL_InitLocal( void )
Cvar_Get( "team", "", FCVAR_USERINFO, "player team" );
Cvar_Get( "skin", "", FCVAR_USERINFO, "player skin" );

// legacy mode cvars (need this to add it to userinfo)
Cvar_Get( "cl_maxpacket", "0", 0, "legacy server compatibility" );
Cvar_Get( "cl_maxpayload", "1000", 0, "legacy server compatibility" );

cl_showfps = Cvar_Get( "cl_showfps", "1", FCVAR_ARCHIVE, "show client fps" );
cl_nosmooth = Cvar_Get( "cl_nosmooth", "0", FCVAR_ARCHIVE, "disable smooth up stair climbing and interpolate position in multiplayer" );
cl_smoothtime = Cvar_Get( "cl_smoothtime", "0", FCVAR_ARCHIVE, "time to smooth up" );
Expand Down
3 changes: 2 additions & 1 deletion engine/client/client.h
Expand Up @@ -665,6 +665,7 @@ typedef struct
netadr_t legacyserver;
netadr_t legacyservers[MAX_LEGACY_SERVERS];
int legacyservercount;
int extensions;
} client_static_t;

#ifdef __cplusplus
Expand Down Expand Up @@ -778,7 +779,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 );
Expand Down
34 changes: 25 additions & 9 deletions engine/common/net_chan.c
Expand Up @@ -302,7 +302,7 @@ Netchan_Setup
called to open a channel to a remote system
==============
*/
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, void *client, int (*pfnBlockSize)(void * ))
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, void *client, int (*pfnBlockSize)(void *, fragsize_t mode ))
{
Netchan_Clear( chan );

Expand Down Expand Up @@ -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 ));
Expand Down Expand Up @@ -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 ))
Expand Down Expand Up @@ -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 ));
Expand Down Expand Up @@ -1458,9 +1458,15 @@ 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( maxsize == 0 )
maxsize = MAX_RELIABLE_PAYLOAD;

// 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 );
Expand Down Expand Up @@ -1627,9 +1633,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
Expand Down Expand Up @@ -1658,7 +1671,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 = 0;
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 )
Expand Down

0 comments on commit 6a6f341

Please sign in to comment.