From ded38020d3cfb238b6592f3496a6053665b4e5bd Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 6 May 2025 19:34:52 +0300 Subject: [PATCH] engine: server: add new client state cs_spawning, to ensure that client cannot spawn before it has an entity --- engine/server/server.h | 1 + engine/server/sv_client.c | 7 +++++-- engine/server/sv_cmds.c | 10 ++++++---- engine/server/sv_main.c | 1 + 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/engine/server/server.h b/engine/server/server.h index a860882e..b6cdcf75 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -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; diff --git a/engine/server/sv_client.c b/engine/server/sv_client.c index 446ff2c7..2c4c572e 100644 --- a/engine/server/sv_client.c +++ b/engine/server/sv_client.c @@ -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 diff --git a/engine/server/sv_cmds.c b/engine/server/sv_cmds.c index 3dcb54e6..3e5616de 100644 --- a/engine/server/sv_cmds.c +++ b/engine/server/sv_cmds.c @@ -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" )); diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index b6321e2a..1ead1e6c 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -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 )