engine: server: completely erase sv_client_t on client connect, so we always start from scratch for every user
This commit is contained in:
parent
6c9d5bc1fb
commit
cddd50f1e9
1 changed files with 47 additions and 79 deletions
|
@ -277,6 +277,25 @@ static sv_client_t *SV_FindEmptySlot( void )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void SV_MaybeNotifyPlayerCountChange( const sv_client_t *cl, const char *address )
|
||||
{
|
||||
int i, count = 0;
|
||||
|
||||
// if this was the first client on the server, or the last client
|
||||
// the server can hold, send a heartbeat to the master.
|
||||
for( i = 0; i < svs.maxclients; i++ )
|
||||
{
|
||||
if( svs.clients[i].state >= cs_connected )
|
||||
count++;
|
||||
}
|
||||
|
||||
if( count == 1 || count == svs.maxclients )
|
||||
NET_MasterClear();
|
||||
|
||||
Log_Printf( "\"%s<%i><%i><>\" connected, address \"%s\"\n",
|
||||
cl->name, cl->userid, (int)( cl - svs.clients ), address );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_ConnectClient
|
||||
|
@ -288,9 +307,10 @@ static void SV_ConnectClient( netadr_t from )
|
|||
{
|
||||
char userinfo[MAX_INFO_STRING];
|
||||
char protinfo[MAX_INFO_STRING];
|
||||
client_frame_t *frames;
|
||||
sv_client_t *newcl = NULL;
|
||||
int qport, version;
|
||||
int i, count = 0;
|
||||
int i;
|
||||
int challenge;
|
||||
const char *s;
|
||||
int extensions;
|
||||
|
@ -397,20 +417,20 @@ static void SV_ConnectClient( netadr_t from )
|
|||
|
||||
// build a new connection
|
||||
// accept the new client
|
||||
|
||||
sv.current_client = newcl;
|
||||
frames = Mem_Realloc( host.mempool, newcl->frames, sizeof( client_frame_t ) * SV_UPDATE_BACKUP );
|
||||
memset( frames, 0, sizeof( client_frame_t ) * SV_UPDATE_BACKUP );
|
||||
SV_ClearResourceLists( newcl );
|
||||
|
||||
memset( newcl, 0, sizeof( *newcl ));
|
||||
|
||||
newcl->edict = EDICT_NUM(( newcl - svs.clients ) + 1 );
|
||||
newcl->challenge = challenge; // save challenge for checksumming
|
||||
newcl->frames = (client_frame_t *)Mem_Realloc( host.mempool, newcl->frames, sizeof( client_frame_t ) * SV_UPDATE_BACKUP );
|
||||
memset( newcl->frames, 0, sizeof( client_frame_t ) * SV_UPDATE_BACKUP );
|
||||
newcl->frames = frames;
|
||||
newcl->userid = g_userid++; // create unique userid
|
||||
newcl->state = cs_connected;
|
||||
newcl->extensions = extensions & (NET_EXT_SPLITSIZE);
|
||||
newcl->extensions = FBitSet( extensions, NET_EXT_SPLITSIZE );
|
||||
Q_strncpy( newcl->useragent, protinfo, sizeof( newcl->useragent ));
|
||||
|
||||
// reset viewentities (from previous level)
|
||||
memset( newcl->viewentity, 0, sizeof( newcl->viewentity ));
|
||||
newcl->num_viewents = 0;
|
||||
// HACKHACK: can hear all players by default to avoid issues
|
||||
// with server.dll without voice game manager
|
||||
newcl->listeners = -1;
|
||||
|
@ -435,50 +455,18 @@ static void SV_ConnectClient( netadr_t from )
|
|||
newcl->connection_started = host.realtime;
|
||||
newcl->cl_updaterate = 0.05; // 20 fps as default
|
||||
newcl->delta_sequence = -1;
|
||||
newcl->flags = 0;
|
||||
|
||||
// reset any remaining events
|
||||
memset( &newcl->events, 0, sizeof( newcl->events ));
|
||||
|
||||
// parse some info from the info strings (this can override cl_updaterate)
|
||||
Q_strncpy( newcl->userinfo, userinfo, sizeof( newcl->userinfo ));
|
||||
|
||||
newcl->ignorecmdtime_warns = 0;
|
||||
newcl->ignorecmdtime_warned = false;
|
||||
newcl->fullupdate_next_calltime = 0;
|
||||
newcl->userinfo_next_changetime = 0;
|
||||
newcl->userinfo_penalty = 0;
|
||||
newcl->userinfo_change_attempts = 0;
|
||||
|
||||
SV_UserinfoChanged( newcl );
|
||||
SV_ClearResourceLists( newcl );
|
||||
#if 0
|
||||
memset( &newcl->resourcesneeded, 0, sizeof( resource_t ));
|
||||
memset( &newcl->resourcesonhand, 0, sizeof( resource_t ));
|
||||
newcl->resourcesneeded.pNext = newcl->resourcesneeded.pPrev = &newcl->resourcesneeded;
|
||||
newcl->resourcesonhand.pNext = newcl->resourcesonhand.pPrev = &newcl->resourcesonhand;
|
||||
#endif
|
||||
|
||||
newcl->next_messagetime = host.realtime + newcl->cl_updaterate;
|
||||
newcl->next_sendinfotime = 0.0;
|
||||
newcl->ignored_ents = 0;
|
||||
newcl->chokecount = 0;
|
||||
|
||||
// reset stats
|
||||
newcl->next_checkpingtime = -1.0;
|
||||
newcl->packet_loss = 0;
|
||||
|
||||
// if this was the first client on the server, or the last client
|
||||
// the server can hold, send a heartbeat to the master.
|
||||
for( i = 0; i < svs.maxclients; i++ )
|
||||
{
|
||||
if( svs.clients[i].state >= cs_connected )
|
||||
count++;
|
||||
}
|
||||
|
||||
Log_Printf( "\"%s<%i><%i><>\" connected, address \"%s\"\n", newcl->name, newcl->userid, i, NET_AdrToString( newcl->netchan.remote_address ));
|
||||
|
||||
if( count == 1 || count == svs.maxclients )
|
||||
NET_MasterClear();
|
||||
SV_MaybeNotifyPlayerCountChange( newcl, NET_AdrToString( newcl->netchan.remote_address ));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -490,25 +478,21 @@ A connection request that came from the game module
|
|||
*/
|
||||
edict_t *GAME_EXPORT SV_FakeConnect( const char *netname )
|
||||
{
|
||||
char userinfo[MAX_INFO_STRING];
|
||||
int i, count = 0;
|
||||
sv_client_t *cl;
|
||||
|
||||
if( !COM_CheckString( netname ))
|
||||
netname = "Bot";
|
||||
char userinfo[MAX_INFO_STRING];
|
||||
int i, count = 0;
|
||||
sv_client_t *cl;
|
||||
|
||||
// find a client slot
|
||||
for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
|
||||
{
|
||||
if( cl->state == cs_free )
|
||||
break;
|
||||
}
|
||||
cl = SV_FindEmptySlot();
|
||||
|
||||
if( i == svs.maxclients )
|
||||
if( !cl )
|
||||
return NULL; // server is full
|
||||
|
||||
userinfo[0] = '\0';
|
||||
|
||||
if( !COM_CheckString( netname ))
|
||||
netname = "Bot";
|
||||
|
||||
// setup fake client params
|
||||
Info_SetValueForKey( userinfo, "name", netname, sizeof( userinfo ));
|
||||
Info_SetValueForKey( userinfo, "model", "gordon", sizeof( userinfo ));
|
||||
|
@ -518,42 +502,26 @@ edict_t *GAME_EXPORT SV_FakeConnect( const char *netname )
|
|||
// build a new connection
|
||||
// accept the new client
|
||||
sv.current_client = cl;
|
||||
if( cl->frames )
|
||||
Mem_Free( cl->frames ); // fakeclients doesn't have frames
|
||||
SV_ClearResourceLists( cl );
|
||||
|
||||
if( cl->frames ) Mem_Free( cl->frames ); // fakeclients doesn't have frames
|
||||
memset( cl, 0, sizeof( sv_client_t ));
|
||||
memset( cl, 0, sizeof( *cl ));
|
||||
|
||||
cl->edict = EDICT_NUM( (cl - svs.clients) + 1 );
|
||||
cl->userid = g_userid++; // create unique userid
|
||||
cl->state = cs_spawned;
|
||||
cl->edict = EDICT_NUM(( cl - svs.clients ) + 1 );
|
||||
cl->userid = g_userid++; // create unique userid
|
||||
SetBits( cl->flags, FCL_FAKECLIENT );
|
||||
|
||||
// parse some info from the info strings
|
||||
Q_strncpy( cl->userinfo, userinfo, sizeof( cl->userinfo ));
|
||||
|
||||
cl->ignorecmdtime_warns = 0;
|
||||
cl->ignorecmdtime_warned = false;
|
||||
cl->fullupdate_next_calltime = 0;
|
||||
cl->userinfo_next_changetime = 0;
|
||||
cl->userinfo_penalty = 0;
|
||||
cl->userinfo_change_attempts = 0;
|
||||
|
||||
SV_UserinfoChanged( cl );
|
||||
SetBits( cl->flags, FCL_RESEND_USERINFO );
|
||||
cl->next_sendinfotime = 0.0;
|
||||
|
||||
// if this was the first client on the server, or the last client
|
||||
// the server can hold, send a heartbeat to the master.
|
||||
for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
|
||||
if( cl->state >= cs_connected ) count++;
|
||||
cl = sv.current_client;
|
||||
|
||||
Log_Printf( "\"%s<%i><%i><>\" connected, address \"local\"\n", cl->name, cl->userid, i );
|
||||
|
||||
SetBits( cl->edict->v.flags, FL_CLIENT|FL_FAKECLIENT ); // mark it as fakeclient
|
||||
cl->connection_started = host.realtime;
|
||||
cl->state = cs_spawned;
|
||||
|
||||
if( count == 1 || count == svs.maxclients )
|
||||
NET_MasterClear();
|
||||
SV_MaybeNotifyPlayerCountChange( cl, "local" );
|
||||
|
||||
return cl->edict;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue