engine: client: improve server data parsing for GoldSrc, restore nick name and remove unuseful userinfo keys before connection

This commit is contained in:
Alibek Omarov 2024-10-14 03:02:50 +03:00
parent d903187eea
commit 67c898f9ad
3 changed files with 70 additions and 42 deletions

View file

@ -1092,6 +1092,10 @@ static void CL_SendConnectPacket( void )
input_devices = IN_CollectInputDevices();
IN_LockInputDevices( true );
// GoldSrc doesn't need sv_cheats set to 0, it's handled by svc_goldsrc_sendextrainfo
// it also doesn't need useragent string
if( cls.legacymode != PROTO_GOLDSRC )
{
Cvar_SetCheatState();
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
@ -1101,6 +1105,7 @@ static void CL_SendConnectPacket( void )
Info_SetValueForKey( protinfo, "o", Q_buildos(), sizeof( protinfo ) );
Info_SetValueForKey( protinfo, "a", Q_buildarch(), sizeof( protinfo ) );
}
}
if( cls.legacymode == PROTO_GOLDSRC )
{
@ -1121,6 +1126,10 @@ static void CL_SendConnectPacket( void )
Info_SetValueForKey( protinfo, "raw", "steam", sizeof( protinfo ));
CL_GetCDKey( protinfo, sizeof( protinfo ));
// remove keys set for legacy protocol
Info_RemoveKey( cls.userinfo, "cl_maxpacket" );
Info_RemoveKey( cls.userinfo, "cl_maxpayload" );
name = Info_ValueForKey( cls.userinfo, "name" );
if( Q_strnicmp( name, "[Xash3D]", 8 ))
{
@ -1139,9 +1148,13 @@ static void CL_SendConnectPacket( void )
Con_Printf( S_ERROR "%s: %s overflow!\n", __func__, MSG_GetName( &send ) );
NET_SendPacket( NS_CLIENT, MSG_GetNumBytesWritten( &send ), MSG_GetData( &send ), adr );
Con_Printf( "Trying to connect with GoldSrc 48 protocol\n" );
}
else if( cls.legacymode == PROTO_LEGACY )
{
// reset nickname from cvar value
Info_SetValueForKey( cls.userinfo, "name", name.string, sizeof( cls.userinfo ));
// set related userinfo keys
if( cl_dlmax.value >= 40000 || cl_dlmax.value < 100 )
Info_SetValueForKey( cls.userinfo, "cl_maxpacket", "1400", sizeof( cls.userinfo ) );
@ -1155,15 +1168,19 @@ static void CL_SendConnectPacket( void )
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" );
Con_Printf( "Trying to connect with legacy protocol\n" );
}
else
{
int extensions = NET_EXT_SPLITSIZE;
// reset nickname from cvar value
Info_SetValueForKey( cls.userinfo, "name", name.string, sizeof( cls.userinfo ));
if( cl_dlmax.value > FRAGMENT_MAX_SIZE || cl_dlmax.value < FRAGMENT_MIN_SIZE )
Cvar_SetValue( "cl_dlmax", FRAGMENT_DEFAULT_SIZE );
// remove keys set for legacy protocol
Info_RemoveKey( cls.userinfo, "cl_maxpacket" );
Info_RemoveKey( cls.userinfo, "cl_maxpayload" );
@ -1172,7 +1189,7 @@ static void CL_SendConnectPacket( void )
Info_SetValueForKeyf( protinfo, "ext", sizeof( protinfo ), "%d", extensions);
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" );
Con_Printf( "Trying to connect with modern protocol\n" );
}
cls.timestart = Sys_DoubleTime();
@ -2873,25 +2890,26 @@ tell server about changed userinfo
*/
void CL_UpdateInfo( const char *key, const char *value )
{
if( cls.legacymode != PROTO_LEGACY )
{
if( cls.legacymode == PROTO_GOLDSRC && !Q_stricmp( key, "name" ) && Q_strnicmp( value, "[Xash3D]", 8 ))
{
// always prepend [Xash3D] on GoldSrc protocol :)
CL_ServerCommand( true, "setinfo \"%s\" \"[Xash3D]%s\"\n", key, value );
}
else
{
CL_ServerCommand( true, "setinfo \"%s\" \"%s\"\n", key, value );
}
}
else
switch( cls.legacymode )
{
case PROTO_LEGACY:
if( cls.state != ca_active )
return;
break;
MSG_BeginClientCmd( &cls.netchan.message, clc_legacy_userinfo );
MSG_WriteString( &cls.netchan.message, cls.userinfo );
break;
case PROTO_GOLDSRC:
if( !Q_stricmp( key, "name" ) && Q_strnicmp( value, "[Xash3D]", 8 ))
{
// always prepend [Xash3D] on GoldSrc protocol :)
CL_ServerCommand( true, "setinfo \"%s\" \"[Xash3D]%s\"\n", key, value );
break;
}
// intentional fallthrough
default:
CL_ServerCommand( true, "setinfo \"%s\" \"%s\"\n", key, value );
break;
}
}

View file

@ -850,7 +850,7 @@ void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto )
char gamefolder[MAX_QPATH];
string mapfile;
qboolean background;
int i;
int i, required_version;
uint32_t mapCRC;
HPAK_CheckSize( hpk_custom_file.string );
@ -858,12 +858,15 @@ void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto )
switch( proto )
{
case PROTO_LEGACY:
required_version = PROTOCOL_LEGACY_VERSION;
Con_Reportf( "Legacy serverdata packet received.\n" );
break;
case PROTO_GOLDSRC:
required_version = PROTOCOL_GOLDSRC_VERSION;
Con_Reportf( "GoldSrc serverdata packet received.\n" );
break;
default:
required_version = PROTOCOL_VERSION;
Con_Reportf( "Serverdata packet received.\n" );
break;
}
@ -882,38 +885,34 @@ void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto )
// parse protocol version number
i = MSG_ReadLong( msg );
if( proto == PROTO_LEGACY || proto == PROTO_GOLDSRC ) // GoldSrc protocol version is 48, same as Xash3D 48
{
if( i != PROTOCOL_LEGACY_VERSION )
Host_Error( "Server use invalid protocol (%i should be %i)\n", i, PROTOCOL_LEGACY_VERSION );
}
else
{
if( i != PROTOCOL_VERSION )
Host_Error( "Server use invalid protocol (%i should be %i)\n", i, PROTOCOL_VERSION );
}
if( i != required_version ) // GoldSrc protocol version is 48, same as Xash3D 48
Host_Error( "Server use invalid protocol (%i should be %i)\n", i, required_version );
cl.servercount = MSG_ReadLong( msg );
cl.checksum = MSG_ReadLong( msg );
if( proto == PROTO_GOLDSRC )
{
byte clientdllmd5[16];
byte unused;
const char *s;
MSG_ReadBytes( msg, clientdllmd5, sizeof( clientdllmd5 ));
cl.maxclients = MSG_ReadByte( msg );
cl.playernum = MSG_ReadByte( msg );
COM_UnMunge3((byte *)&cl.checksum, sizeof( cl.checksum ), ( 0xff - cl.playernum ) & 0xff );
unused = MSG_ReadByte( msg ); // coop flag
MSG_SeekToBit( msg, sizeof( uint8_t ) << 3, SEEK_CUR ); // quake leftover, coop flag
Q_strncpy( gamefolder, MSG_ReadString( msg ), sizeof( gamefolder ));
MSG_ReadString( msg ); // hostname
Con_Printf( "Remote host: %s\n", MSG_ReadString( msg ));
Q_strncpy( clgame.mapname, COM_FileWithoutPath( MSG_ReadString( msg )), sizeof( clgame.mapname ));
COM_StripExtension( clgame.mapname );
MSG_ReadString( msg ); // mapcycle?????
unused = MSG_ReadByte( msg ); // vac secure
s = MSG_ReadString( msg );
if( COM_CheckStringEmpty( s ))
Con_Printf( "Server map cycle: %s\n", s ); // VALVEWHY?
if( MSG_ReadByte( msg ))
Con_Printf( "Uh, server says it's VAC2 secured.\n" );
background = false;
clgame.maxEntities = GI->max_edicts + (( cl.maxclients - 1 ) * 15 );

View file

@ -28,7 +28,18 @@ static void CL_ParseExtraInfo( sizebuf_t *msg )
string clientfallback;
Q_strncpy( clientfallback, MSG_ReadString( msg ), sizeof( clientfallback ));
Cvar_FullSet( "sv_cheats", MSG_ReadByte( msg ) ? "1" : "0", FCVAR_READ_ONLY | FCVAR_SERVER );
if( COM_CheckStringEmpty( clientfallback ))
Con_Reportf( S_ERROR "%s: TODO: add fallback directory %s!\n", __func__ );
if( MSG_ReadByte( msg ))
{
Cvar_FullSet( "sv_cheats", "1", FCVAR_READ_ONLY | FCVAR_SERVER );
}
else
{
Cvar_SetCheatState();
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
}
}
static void CL_ParseNewMovevars( sizebuf_t *msg )