Skip to content

Commit

Permalink
server: don't spawn loading clients during map restart
Browse files Browse the repository at this point in the history
GitHub Actions: fix warnings
  • Loading branch information
ec- committed May 25, 2024
1 parent 2baff41 commit ed4af16
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 29 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ jobs:
steps:

- name: Install tools
run: brew install coreutils pkg-config sdl2
run: brew install coreutils sdl2 # pkg-config

- uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -305,7 +305,7 @@ jobs:
# 7z a -r quake3e-linux-armv7.zip ./linux-armv7/*

- name: Create latest build
uses: marvinpinto/action-automatic-releases@latest
uses: czietz/action-automatic-releases@latest
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
automatic_release_tag: "latest"
Expand Down
3 changes: 2 additions & 1 deletion code/server/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,11 +351,12 @@ void SV_GetChallenge( const netadr_t *from );
void SV_InitChallenger( void );

void SV_DirectConnect( const netadr_t *from );
void SV_PrintClientStateChange( const client_t *cl, clientState_t newState );

void SV_ExecuteClientMessage( client_t *cl, msg_t *msg );
void SV_UserinfoChanged( client_t *cl, qboolean updateUserinfo, qboolean runFilter );

void SV_ClientEnterWorld( client_t *client, usercmd_t *cmd );
void SV_ClientEnterWorld( client_t *client );
void SV_FreeClient( client_t *client );
void SV_DropClient( client_t *drop, const char *reason );

Expand Down
15 changes: 5 additions & 10 deletions code/server/sv_ccmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,13 @@ static void SV_MapRestart_f( void ) {
// generate a new serverid
// TTimo - don't update restartedserverId there, otherwise we won't deal correctly with multiple map_restart
sv.serverId = com_frameTime;
Cvar_Set( "sv_serverid", va("%i", sv.serverId ) );
Cvar_SetIntegerValue( "sv_serverid", sv.serverId );

// if a map_restart occurs while a client is changing maps, we need
// to give them the correct time so that when they finish loading
// they don't violate the backwards time check in cl_cgame.c
for (i=0 ; i<sv_maxclients->integer ; i++) {
if (svs.clients[i].state == CS_PRIMED) {
for ( i = 0; i < sv_maxclients->integer; i++ ) {
if ( svs.clients[i].state == CS_PRIMED ) {
svs.clients[i].oldServerTime = sv.restartTime;
}
}
Expand Down Expand Up @@ -351,13 +351,8 @@ static void SV_MapRestart_f( void ) {
continue;
}

if ( client->state == CS_ACTIVE )
SV_ClientEnterWorld( client, &client->lastUsercmd );
else {
// If we don't reset client->lastUsercmd and are restarting during map load,
// the client will hang because we'll use the last Usercmd from the previous map,
// which is wrong obviously.
SV_ClientEnterWorld( client, NULL );
if ( client->state == CS_ACTIVE ) {
SV_ClientEnterWorld( client );
}
}

Expand Down
63 changes: 48 additions & 15 deletions code/server/sv_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,39 @@ static const char *SV_FindCountry( const char *tld ) {
}


static const char *SV_GetStateName( clientState_t state ) {
switch ( state ) {
case CS_FREE: return "CS_FREE";
case CS_ZOMBIE: return "CS_ZOMBIE";
case CS_CONNECTED: return "CS_CONNECTED";
case CS_PRIMED: return "CS_PRIMED";
case CS_ACTIVE: return "CS_ACTIVE";
default: return "CS_UNKNOWN";
}
}


void SV_PrintClientStateChange( const client_t *cl, clientState_t newState ) {

if ( cl->state == newState ) {
return;
}

#ifndef _DEBUG
if ( com_developer->integer == 0 ) {
return;
}
#endif // !_DEBUG

if ( cl->name[0] != '\0' ) {
Com_Printf( "Going from %s to %s for %s\n", SV_GetStateName( cl->state ), SV_GetStateName( newState ), cl->name );
} else {
Com_Printf( "Going from %s to %s for client %d\n", SV_GetStateName( cl->state ), SV_GetStateName( newState ), cl - svs.clients );
}

}


/*
==================
SV_DirectConnect
Expand Down Expand Up @@ -772,7 +805,7 @@ void SV_DirectConnect( const netadr_t *from ) {
NET_OutOfBandPrint( NS_SERVER, from, "connectResponse %d", challenge );
}

Com_DPrintf( "Going from CS_FREE to CS_CONNECTED for %s\n", newcl->name );
SV_PrintClientStateChange( newcl, CS_CONNECTED );

newcl->state = CS_CONNECTED;
newcl->lastSnapshotTime = svs.time - 9999; // generate a snapshot immediately
Expand Down Expand Up @@ -826,7 +859,7 @@ or crashing -- SV_FinalMessage() will handle that
=====================
*/
void SV_DropClient( client_t *drop, const char *reason ) {
char name[ MAX_NAME_LENGTH ];
char name[ sizeof( drop->name ) ];
qboolean isBot;
int i;

Expand Down Expand Up @@ -870,7 +903,8 @@ void SV_DropClient( client_t *drop, const char *reason ) {
// bots shouldn't go zombie, as there's no real net connection.
drop->state = CS_FREE;
} else {
Com_DPrintf( "Going to CS_ZOMBIE for %s\n", name );
Q_strncpyz( drop->name, name, sizeof( name ) );
SV_PrintClientStateChange( drop, CS_ZOMBIE );
drop->state = CS_ZOMBIE; // become free in a few seconds
}

Expand Down Expand Up @@ -990,9 +1024,8 @@ static void SV_SendClientGameState( client_t *client ) {

Com_DPrintf( "SV_SendClientGameState() for %s\n", client->name );

if ( client->state != CS_PRIMED ) {
Com_DPrintf( "Going from CS_CONNECTED to CS_PRIMED for %s\n", client->name );
}
SV_PrintClientStateChange( client, CS_PRIMED );

client->state = CS_PRIMED;

client->pureAuthentic = qfalse;
Expand All @@ -1006,6 +1039,10 @@ static void SV_SendClientGameState( client_t *client ) {
// gamestate message was not just sent, forcing a retransmit
client->gamestateMessageNum = client->netchan.outgoingSequence;

// accept usercmds starting from current server time only
Com_Memset( &client->lastUsercmd, 0x0, sizeof( client->lastUsercmd ) );
client->lastUsercmd.serverTime = sv.time - 1;

MSG_Init( &msg, msgBuffer, MAX_MSGLEN );

// NOTE, MRE: all server->client messages now acknowledge
Expand Down Expand Up @@ -1072,11 +1109,12 @@ static void SV_SendClientGameState( client_t *client ) {
SV_ClientEnterWorld
==================
*/
void SV_ClientEnterWorld( client_t *client, usercmd_t *cmd ) {
void SV_ClientEnterWorld( client_t *client ) {
int clientNum;
sharedEntity_t *ent;

Com_DPrintf( "Going from CS_PRIMED to CS_ACTIVE for %s\n", client->name );
SV_PrintClientStateChange( client, CS_ACTIVE );

client->state = CS_ACTIVE;

// resend all configstrings using the cs commands since these are
Expand All @@ -1092,13 +1130,8 @@ void SV_ClientEnterWorld( client_t *client, usercmd_t *cmd ) {
client->deltaMessage = client->netchan.outgoingSequence - (PACKET_BACKUP + 1); // force delta reset
client->lastSnapshotTime = svs.time - 9999; // generate a snapshot immediately

if(cmd)
memcpy(&client->lastUsercmd, cmd, sizeof(client->lastUsercmd));
else
memset(&client->lastUsercmd, '\0', sizeof(client->lastUsercmd));

// call the game begin function
VM_Call( gvm, 1, GAME_CLIENT_BEGIN, client - svs.clients );
VM_Call( gvm, 1, GAME_CLIENT_BEGIN, clientNum );
}


Expand Down Expand Up @@ -2095,7 +2128,7 @@ static void SV_UserMove( client_t *cl, msg_t *msg, qboolean delta ) {
}
return;
}
SV_ClientEnterWorld( cl, &cmds[0] );
SV_ClientEnterWorld( cl );
// the moves can be processed normally
}

Expand Down
2 changes: 1 addition & 1 deletion code/server/sv_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,7 @@ static void SV_CheckTimeouts( void ) {

if ( cl->state == CS_ZOMBIE && cl->lastPacketTime - zombiepoint < 0 ) {
// using the client id cause the cl->name is empty at this point
Com_DPrintf( "Going from CS_ZOMBIE to CS_FREE for client %d\n", i );
SV_PrintClientStateChange( cl, CS_FREE );
cl->state = CS_FREE; // can now be reused
continue;
}
Expand Down

0 comments on commit ed4af16

Please sign in to comment.