engine: server: add new client state cs_spawning, to ensure that client cannot spawn before it has an entity

This commit is contained in:
Alibek Omarov
2025-05-06 19:34:52 +03:00
parent c6251174df
commit ded38020d3
4 changed files with 13 additions and 6 deletions

View File

@@ -94,6 +94,7 @@ typedef enum
cs_free = 0, // can be reused for a new connection
cs_zombie, // client has been disconnected, but don't reuse connection for a couple seconds
cs_connected, // has been assigned to a sv_client_t, but not in game yet
cs_spawning, // put in game, but not spawned yet
cs_spawned // client is fully in game
} cl_state_t;

View File

@@ -425,7 +425,7 @@ static void SV_ConnectClient( netadr_t from )
newcl->edict = EDICT_NUM(( newcl - svs.clients ) + 1 );
newcl->frames = frames;
newcl->userid = g_userid++; // create unique userid
newcl->state = cs_connected;
newcl->state = cs_connected; // now expect "spawn" command
newcl->extensions = FBitSet( extensions, NET_EXT_SPLITSIZE );
Q_strncpy( newcl->useragent, protinfo, sizeof( newcl->useragent ));
@@ -2139,6 +2139,8 @@ static qboolean SV_Spawn_f( sv_client_t *cl )
SV_PutClientInServer( cl );
cl->state = cs_spawning;
// if we are paused, tell the clients
if( sv.paused )
{
@@ -2156,7 +2158,8 @@ SV_Begin_f
*/
static qboolean SV_Begin_f( sv_client_t *cl )
{
if( cl->state != cs_connected )
// make sure client has passed connection process correctly
if( cl->state != cs_spawning )
return false;
// now client is spawned

View File

@@ -662,13 +662,15 @@ static void SV_Status_f( void )
continue;
if( cl->state == cs_connected )
s = "Cnct";
s = "Connect ";
else if( cl->state == cs_spawning )
s = "Spawning";
else if( cl->state == cs_zombie )
s = "Zmbi";
s = "Zombie ";
else if( FBitSet( cl->flags, FCL_FAKECLIENT ))
s = "Bot ";
s = "Bot ";
else
s = va( "%i", SV_CalcPing( cl ));
s = va( "%8i", SV_CalcPing( cl ));
input_devices = Q_atoi( Info_ValueForKey( cl->useragent, "d" ));

View File

@@ -509,6 +509,7 @@ static void SV_CheckTimeouts( void )
cl->state = cs_free; // can now be reused
break;
case cs_connected:
case cs_spawning:
if( !NET_IsLocalAddress( cl->netchan.remote_address ))
{
if( cl->connection_started < connected_droppoint )