Beispiel #1
0
/*
==================
SV_NextDownload_f

The argument will be the last acknowledged block from the client, it should be
the same as cl->downloadClientBlock
==================
*/
void SV_NextDownload_f( client_t *cl )
{
	int block = atoi( Cmd_Argv(1) );

	if ( cl->state == CS_ACTIVE )
		return;

	if (block == cl->downloadClientBlock) {
		Com_DPrintf( "clientDownload: %d : client acknowledge of block %d\n", cl - svs.clients, block );

		// Find out if we are done.  A zero-length block indicates EOF
		if (cl->downloadBlockSize[cl->downloadClientBlock % MAX_DOWNLOAD_WINDOW] == 0) {
			Com_Printf( "clientDownload: %d : file \"%s\" completed\n", cl - svs.clients, cl->downloadName );
			SV_CloseDownload( cl );
			return;
		}

		cl->downloadSendTime = svs.time;
		cl->downloadClientBlock++;
		return;
	}
	// We aren't getting an acknowledge for the correct block, drop the client
	// FIXME: this is bad... the client will never parse the disconnect message
	//			because the cgame isn't loaded yet
	SV_DropClient( cl, "broken download" );
}
Beispiel #2
0
/*
==================
SV_NextDownload_f

The argument will be the last acknowledged block from the client, it should be
the same as cl->downloadClientBlock
==================
*/
void SV_NextDownload_f( client_t *cl, const Cmd::Args& args )
{
	int block;
	if (args.Argc() < 2 or not Str::ParseInt(block, args.Argv(1))) {
		return;
	}

	if ( block == cl->downloadClientBlock )
	{
		Log::Debug( "clientDownload: %d: client acknowledge of block %d", ( int )( cl - svs.clients ), block );

		// Find out if we are done.  A zero-length block indicates EOF
		if ( cl->downloadBlockSize[ cl->downloadClientBlock % MAX_DOWNLOAD_WINDOW ] == 0 )
		{
			Log::Notice( "clientDownload: %d : file \"%s\" completed\n", ( int )( cl - svs.clients ), cl->downloadName );
			SV_CloseDownload( cl );
			return;
		}

		cl->downloadSendTime = svs.time;
		cl->downloadClientBlock++;
		return;
	}

	// We aren't getting an acknowledge for the correct block, drop the client
	// FIXME: this is bad... the client will never parse the disconnect message
	//          because the cgame isn't loaded yet
	SV_DropClient( cl, "broken download" );
}
Beispiel #3
0
/*
==================
SV_StopDownload_f

Abort a download if in progress
==================
*/
void SV_StopDownload_f( client_t *cl, const Cmd::Args& )
{
	if ( *cl->downloadName )
	{
		Log::Debug( "clientDownload: %d: file \"%s^7\" aborted", ( int )( cl - svs.clients ), cl->downloadName );
	}

	SV_CloseDownload( cl );
}
Beispiel #4
0
/*
==================
SV_StopDownload_f

Abort a download if in progress
==================
*/
void SV_StopDownload_f(client_t *cl)
{
	if(*cl->downloadName)
	{
		Com_DPrintf("clientDownload: %d : file \"%s\" aborted\n", cl - svs.clients, cl->downloadName);
	}

	SV_CloseDownload(cl);
}
Beispiel #5
0
/*
==================
SV_StopDownload_f

Abort a download if in progress
==================
*/
void SV_StopDownload_f( client_t *cl ) {
	if ( cl->state == CS_ACTIVE )
		return;

	if (*cl->downloadName)
		Com_DPrintf( "clientDownload: %d : file \"%s\" aborted\n", cl - svs.clients, cl->downloadName );

	SV_CloseDownload( cl );
}
Beispiel #6
0
/*
==================
SV_BeginDownload_f
==================
*/
static void SV_BeginDownload_f( client_t *cl ) {

	// Kill any existing download
	SV_CloseDownload( cl );

	// cl->downloadName is non-zero now, SV_WriteDownloadToClient will see this and open
	// the file itself
	Q_strncpyz( cl->downloadName, Cmd_Argv(1), sizeof(cl->downloadName) );
}
/*
=====================
SV_DropClient

Called when the player is totally leaving the server, either willingly
or unwillingly.  This is NOT called if the entire server is quiting
or crashing -- SV_FinalMessage() will handle that
=====================
*/
void SV_DropClient( client_t *drop, const char *reason ) {
	int		i;
	challenge_t	*challenge;

	if ( drop->state == CS_ZOMBIE ) {
		return;		// already dropped
	}

	// see if we already have a challenge for this ip
	challenge = &svs.challenges[0];

	for (i = 0 ; i < MAX_CHALLENGES ; i++, challenge++) {
		if ( NET_CompareAdr( drop->netchan.remoteAddress, challenge->adr ) ) {
			challenge->connected = qfalse;
			break;
		}
	}

	// Kill any download
	SV_CloseDownload( drop );

	// tell everyone why they got dropped
	SV_SendServerCommand( NULL, "print \"%s" S_COLOR_WHITE " %s\n\"", drop->name, reason );


	if (drop->download)	{
		FS_FCloseFile( drop->download );
		drop->download = 0;
	}

	// call the prog function for removing a client
	// this will remove the body, among other things
	VM_Call( gvm, GAME_CLIENT_DISCONNECT, drop - svs.clients );

	// add the disconnect command
	SV_SendServerCommand( drop, "disconnect \"%s\"", reason);

	// nuke user info
	SV_SetUserinfo( drop - svs.clients, "" );
	
	Com_DPrintf( "Going to CS_ZOMBIE for %s\n", drop->name );
	drop->state = CS_ZOMBIE;		// become free in a few seconds

	// if this was the last client on the server, send a heartbeat
	// to the master so it is known the server is empty
	// send a heartbeat now so the master will get up to date info
	// if there is already a slot for this ip, reuse it
	for (i=0 ; i < sv_maxclients->integer ; i++ ) {
		if ( svs.clients[i].state >= CS_CONNECTED ) {
			break;
		}
	}
	if ( i == sv_maxclients->integer ) {
		SV_Heartbeat_f();
	}
}
Beispiel #8
0
/*
=====================
SV_DropClient

Called when the player is totally leaving the server, either willingly
or unwillingly.  This is NOT called if the entire server is quiting
or crashing -- SV_FinalMessage() will handle that
=====================
*/
void SV_DropClient( client_t *drop, const char *reason ) {
	int		i;
	const bool isBot = drop->netchan.remoteAddress.type == NA_BOT;

	if ( drop->state == CS_ZOMBIE ) {
		return;		// already dropped
	}

	// Kill any download
	SV_CloseDownload( drop );

	// tell everyone why they got dropped
	SV_SendServerCommand( NULL, "print \"%s" S_COLOR_WHITE " %s\n\"", drop->name, reason );

	// call the prog function for removing a client
	// this will remove the body, among other things
	GVM_ClientDisconnect( drop - svs.clients );

	// add the disconnect command
	SV_SendServerCommand( drop, "disconnect \"%s\"", reason );

	if ( isBot ) {
		SV_BotFreeClient( drop - svs.clients );
	}

	// nuke user info
	SV_SetUserinfo( drop - svs.clients, "" );

	if ( isBot ) {
		// 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", drop->name );
		drop->state = CS_ZOMBIE;		// become free in a few seconds
	}

	if ( drop->demo.demorecording ) {
		SV_StopRecordDemo( drop );
	}

	// if this was the last client on the server, send a heartbeat
	// to the master so it is known the server is empty
	// send a heartbeat now so the master will get up to date info
	// if there is already a slot for this ip, reuse it
	for (i=0 ; i < sv_maxclients->integer ; i++ ) {
		if ( svs.clients[i].state >= CS_CONNECTED ) {
			break;
		}
	}
	if ( i == sv_maxclients->integer ) {
		SV_Heartbeat_f();
	}
}
Beispiel #9
0
/*
=====================
SV_FreeClient

Destructor for data allocated in a client structure
=====================
*/
void SV_FreeClient(client_t *client)
{
#ifdef USE_VOIP
	int index;
	
	for(index = client->queuedVoipIndex; index < client->queuedVoipPackets; index++)
	{
		index %= ARRAY_LEN(client->voipPacket);
		
		Z_Free(client->voipPacket[index]);
	}
	
	client->queuedVoipPackets = 0;
#endif

	SV_Netchan_FreeQueue(client);
	SV_CloseDownload(client);
}
/*
==================
SV_BeginDownload_f
==================
*/
static void SV_BeginDownload_f( client_t *cl ) {

	if ( cl->state == CS_ACTIVE )
		return;

	// Kill any existing download
	SV_CloseDownload( cl );

	// Jedi Knight Galaxies -- download validation
	char *c = Cmd_Argv(1);
	if(strlen(c) < 4) return;										// Do not allow blank file names
	else if(Q_stricmpn((c + strlen(c) - 4), ".pk3", 4)) return;		// Do not allow anything except PK3s
	else if(strstr(c, "..")) return;								// Do not traverse the directory

	// cl->downloadName is non-zero now, SV_WriteDownloadToClient will see this and open
	// the file itself
	Q_strncpyz( cl->downloadName, Cmd_Argv(1), sizeof(cl->downloadName) );
}
Beispiel #11
0
/*
==================
SV_BeginDownload_f
==================
*/
void SV_BeginDownload_f( client_t *cl, const Cmd::Args& args )
{
	// Kill any existing download
	SV_CloseDownload( cl );

	if (args.Argc() < 2) {
		return;
	}

	//bani - stop us from printing dupe messages
	if (args.Argv(1) != cl->downloadName)
	{
		cl->downloadnotify = DLNOTIFY_ALL;
	}

	// cl->downloadName is non-zero now, SV_WriteDownloadToClient will see this and open
	// the file itself
	Q_strncpyz( cl->downloadName, args.Argv(1).c_str(), sizeof( cl->downloadName ) );
}
Beispiel #12
0
/*
=====================
SV_FreeClient

Destructor for data allocated in a client structure
=====================
*/
void SV_FreeClient( client_t *client )
{
	// NA_BOT happens to be the default value for address types (value 0) and are
	// never for clients that send challenges. For NA_BOT, skip the checks for
	// challenges as it makes NET_CompareAdr yell at us.
	if (client->netchan.remoteAddress.type != netadrtype_t::NA_BOT) {
		// see if we already have a challenge for this IP address
		challenge_t* challenge = &svs.challenges[ 0 ];
		for (int i = 0; i < MAX_CHALLENGES; i++, challenge++)
		{
			if ( NET_CompareAdr( client->netchan.remoteAddress, challenge->adr ) )
			{
				challenge->connected = false;
				break;
			}
		}
	}

	SV_Netchan_FreeQueue( client );
	SV_CloseDownload( client );
}
Beispiel #13
0
/*
=====================
SV_FreeClient

Destructor for data allocated in a client structure
=====================
*/
void SV_FreeClient( client_t *client )
{
	SV_Netchan_FreeQueue( client );
	SV_CloseDownload( client );
}
Beispiel #14
0
/*
=====================
SV_DropClient

Called when the player is totally leaving the server, either willingly
or unwillingly.  This is NOT called if the entire server is quiting
or crashing -- SV_FinalMessage() will handle that
=====================
*/
void SV_DropClient(client_t *drop, const char *reason)
{
	int i;

	if(drop->state == CS_ZOMBIE)
	{
		return;     // already dropped
	}

	// Kill any download
	SV_CloseDownload(drop);

	// Ridah, no need to tell the player if an AI drops
	if(!(drop->gentity && drop->gentity->r.svFlags & SVF_CASTAI))
	{
		// tell everyone why they got dropped
		SV_SendServerCommand(NULL, "print \"%s" S_COLOR_WHITE " %s\n\"", drop->name, reason);
	}

	Com_DPrintf("Going to CS_ZOMBIE for %s\n", drop->name);
	drop->state = CS_ZOMBIE;        // become free in a few seconds

	if(drop->download)
	{
		FS_FCloseFile(drop->download);
		drop->download = 0;
	}

	// call the prog function for removing a client
	// this will remove the body, among other things
	VM_Call(gvm, GAME_CLIENT_DISCONNECT, drop - svs.clients);

	// Ridah, no need to tell the player if an AI drops
	if(!(drop->gentity && drop->gentity->r.svFlags & SVF_CASTAI))
	{
		// add the disconnect command
		SV_SendServerCommand(drop, "disconnect");
	}

	// done.

	if(drop->netchan.remoteAddress.type == NA_BOT)
	{
		SV_BotFreeClient(drop - svs.clients);
	}

	// nuke user info
	SV_SetUserinfo(drop - svs.clients, "");

	// RF, nuke reliable commands
	SV_FreeReliableCommandsForClient(drop);

	// if this was the last client on the server, send a heartbeat
	// to the master so it is known the server is empty
	// send a heartbeat now so the master will get up to date info
	// if there is already a slot for this ip, reuse it
	for(i = 0 ; i < sv_maxclients->integer ; i++)
	{
		if(svs.clients[i].state >= CS_CONNECTED)
		{
			break;
		}
	}

	if(i == sv_maxclients->integer)
	{
		SV_Heartbeat_f();
	}
}