Пример #1
0
static bool CL_DownloadMap (const char* map)
{
	bool startedDownload;
	if (map[0] != '+') {
		startedDownload = !CL_CheckOrDownloadFile(va("maps/%s.bsp", map));
	} else {
		startedDownload = !CL_CheckOrDownloadFile(va("maps/%s.ump", map + 1));
		if (!startedDownload) {
			const char* tiles = CL_GetConfigString(CS_TILES);
			startedDownload = CL_DownloadUMPMap(tiles);
		}
	}

	return startedDownload;
}
Пример #2
0
static void CLQW_Sound_NextDownload() {
	if ( clc.downloadNumber == 0 ) {
		common->Printf( "Checking sounds...\n" );
		clc.downloadNumber = 1;
	}

	clc.downloadType = dl_sound;
	for (
		; cl.qh_sound_name[ clc.downloadNumber ][ 0 ]
		; clc.downloadNumber++ ) {
		char* s = cl.qh_sound_name[ clc.downloadNumber ];
		if ( !CL_CheckOrDownloadFile( va( "sound/%s",s ) ) ) {
			return;		// started a download
		}
	}

	S_BeginRegistration();
	CLQ1_InitTEnts();
	for ( int i = 1; i < MAX_SOUNDS_Q1; i++ ) {
		if ( !cl.qh_sound_name[ i ][ 0 ] ) {
			break;
		}
		cl.sound_precache[ i ] = S_RegisterSound( cl.qh_sound_name[ i ] );
	}
	S_EndRegistration();

	// done with sounds, request models now
	Com_Memset( cl.model_draw, 0, sizeof ( cl.model_draw ) );
	clq1_playerindex = -1;
	clq1_spikeindex = -1;
	clqw_flagindex = -1;
	CL_AddReliableCommand( va( "modellist %i %i", cl.servercount, 0 ) );
}
Пример #3
0
/*
===============
CL_Download_f

Request a download from the server
===============
*/
void	CL_Download_f (void)
{
	char filename[MAX_OSPATH];

	if (Cmd_Argc() != 2) {
		Com_Printf("Usage: download <filename>\n");
		return;
	}

	if (cls.state <= ca_connecting)
	{
		Com_Printf ("Not connected.\n");
		return;
	}

	Q_strncpyz(filename, Cmd_Argv(1), sizeof(filename));
	COM_FixPath(filename);

	if (FS_LoadFile (filename, NULL) != -1)
	{	// it exists, no need to download
		Com_Printf("File already exists.\n");
		return;
	}

	CL_CheckOrDownloadFile (filename);
}
Пример #4
0
static bool CL_DownloadUMPMap (const char* tiles)
{
	char name[MAX_VAR];
	char base[MAX_QPATH];
	bool startedDownload = false;

	/* load tiles */
	while (tiles) {
		/* get tile name */
		const char* token = Com_Parse(&tiles);
		if (!tiles)
			return startedDownload;

		/* get base path */
		if (token[0] == '-') {
			Q_strncpyz(base, token + 1, sizeof(base));
			continue;
		}

		/* get tile name */
		if (token[0] == '+')
			Com_sprintf(name, sizeof(name), "%s%s", base, token + 1);
		else
			Q_strncpyz(name, token, sizeof(name));

		startedDownload |= !CL_CheckOrDownloadFile(va("maps/%s.bsp", name));
	}

	return startedDownload;
}
Пример #5
0
/*
===============
CL_Download_f

Request a download from the server
===============
*/
void CL_Download_f( void )
{
	if( Cmd_Argc() != 2 )
	{
		Msg( "Usage: download <filename>\n" );
		return;
	}
	CL_CheckOrDownloadFile(Cmd_Argv(1));
}
Пример #6
0
static void CLQW_Model_NextDownload() {
	if ( clc.downloadNumber == 0 ) {
		common->Printf( "Checking models...\n" );
		clc.downloadNumber = 1;
	}

	clc.downloadType = dl_model;
	for (
		; cl.qh_model_name[ clc.downloadNumber ][ 0 ]
		; clc.downloadNumber++ ) {
		const char* s = cl.qh_model_name[ clc.downloadNumber ];
		if ( s[ 0 ] == '*' ) {
			continue;	// inline brush model
		}
		if ( !CL_CheckOrDownloadFile( s ) ) {
			return;		// started a download
		}
	}

	CM_LoadMap( cl.qh_model_name[ 1 ], true, NULL );
	cl.model_clip[ 1 ] = 0;
	R_LoadWorld( cl.qh_model_name[ 1 ] );

	for ( int i = 2; i < MAX_MODELS_Q1; i++ ) {
		if ( !cl.qh_model_name[ i ][ 0 ] ) {
			break;
		}

		cl.model_draw[ i ] = CLQ1_RegisterModel( cl.qh_model_name[ i ] );
		if ( cl.qh_model_name[ i ][ 0 ] == '*' ) {
			cl.model_clip[ i ] = CM_InlineModel( String::Atoi( cl.qh_model_name[ i ] + 1 ) );
		}

		if ( !cl.model_draw[ i ] ) {
			common->Printf( "\nThe required model file '%s' could not be found or downloaded.\n\n",
				cl.qh_model_name[ i ] );
			common->Printf( "You may need to download or purchase a %s client "
							"pack in order to play on this server.\n\n", fs_gamedir );
			CL_Disconnect( true );
			return;
		}
	}

	CLQW_CalcModelChecksum( "progs/player.mdl", "pmodel" );
	CLQW_CalcModelChecksum( "progs/eyes.mdl", "emodel" );

	// all done
	R_EndRegistration();

	int CheckSum1;
	int CheckSum2;
	CM_MapChecksums( CheckSum1, CheckSum2 );

	// done with modellist, request first of static signon messages
	CL_AddReliableCommand( va( "prespawn %i 0 %i", cl.servercount, CheckSum2 ) );
}
Пример #7
0
/*
=================
Skin_NextDownload
=================
*/
void Skin_NextDownload (void)
{
	player_info_t	*sc;
	int			i;

	if (cls.downloadnumber == 0)
		Con_Printf ("Checking skins...\n");
	cls.downloadtype = dl_skin;

	for ( 
		; cls.downloadnumber != MAX_CLIENTS
		; cls.downloadnumber++)
	{
		sc = &cl.players[cls.downloadnumber];
		if (!sc->name[0])
			continue;
		Skin_Find (sc);
		if (noskins.value)
			continue;
		if (!CL_CheckOrDownloadFile(va("skins/%s.pcx", sc->skin->name)))
			return;		// started a download
	}

	cls.downloadtype = dl_none;

	// now load them in for real
	for (i=0 ; i<MAX_CLIENTS ; i++)
	{
		sc = &cl.players[i];
		if (!sc->name[0])
			continue;
		Skin_Cache (sc->skin);
// >>> FIX: For Nintendo Wii using devkitPPC / libogc
// Support for GX hardware:
//#ifdef GLQUAKE
#if defined(GXQUAKE) || defined(GLQUAKE)
// <<< FIX
		sc->skin = NULL;
#endif
	}

	if (cls.state != ca_active)
	{	// get next signon phase
		MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
		MSG_WriteString (&cls.netchan.message,
			va("begin %i", cl.servercount));
		Cache_Report ();		// print remaining memory
	}
}
Пример #8
0
void Skin_NextDownload (void) {
	player_info_t *sc;
	int i;

	if (cls.downloadnumber == 0)
		if (!com_serveractive || developer.value)
			Com_DPrintf ("Checking skins...\n");

	cls.downloadtype = dl_skin;

	for ( ; cls.downloadnumber >= 0 && cls.downloadnumber < MAX_CLIENTS; cls.downloadnumber++) {
		sc = &cl.players[cls.downloadnumber];
		if (!sc->name[0])
			continue;

		Skin_Find (sc);

		if (noskins.value)
			continue;

		if (Skin_Cache (sc->skin, true))
			continue; // we have it in cache, that mean we somehow able load this skin

		if (!CL_CheckOrDownloadFile(va("skins/%s.pcx", sc->skin->name)))
			return;		// started a download
	}

	cls.downloadtype = dl_none;

	// now load them in for real
	for (i = 0; i < MAX_CLIENTS; i++) {
		sc = &cl.players[i];
		if (!sc->name[0])
			continue;

		if (!sc->skin)
			Skin_Find (sc);

		Skin_Cache (sc->skin, false);
		sc->skin = NULL; // this way triggered skin loading, as i understand in R_TranslatePlayerSkin()
	}

	if (cls.state == ca_onserver /* && cbuf_current != &cbuf_main */) {	//only download when connecting
		MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
		MSG_WriteString (&cls.netchan.message, va("begin %i", cl.servercount));
	}
}
Пример #9
0
/*
=================
Skin_NextDownload
=================
*/
void
Skin_NextDownload ( void )
{
	player_info_t	*sc;
	int			i;

	if (cls.downloadnumber == 0)
		Con_Printf ("Checking skins...\n");
	cls.downloadtype = dl_skin;

	for (
		; cls.downloadnumber != MAX_CLIENTS
		; cls.downloadnumber++)
	{
		sc = &cl.players[cls.downloadnumber];
		if (!sc->name[0])
			continue;
		Skin_Find (sc);
		if (noskins->value)
			continue;
#ifndef UQUAKE
		if (!CL_CheckOrDownloadFile(va("skins/%s.pcx", sc->skin->name)))
			return;		// started a download
#endif
	}

	cls.downloadtype = dl_none;

	// now load them in for real
	for (i=0 ; i<MAX_CLIENTS ; i++)
	{
		sc = &cl.players[i];
		if (!sc->name[0])
			continue;
		Skin_Cache (sc->skin);
		sc->skin = NULL;
	}

	if (cls.state != ca_active)
	{	// get next signon phase
		MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
		MSG_WriteString (&cls.netchan.message,
			va("begin %i", cl.servercount));
		Cache_Report ();		// print remaining memory
	}
}
Пример #10
0
/*
===============
CL_Download_f

Request a download from the server
===============
*/
void CL_Download_f (void)
{
	//char	name[MAX_OSPATH];
	//FILE	*fp;
//	char	*p;
	char	*filename;

	if (Cmd_Argc() != 2) {
		Com_Printf("Usage: download <filename>\n", LOG_CLIENT);
		return;
	}

	if (cls.state < ca_connected)
	{
		Com_Printf ("Not connected.\n", LOG_CLIENT);
		return;
	}

	//Com_sprintf(filename, sizeof(filename), "%s", Cmd_Argv(1));
	filename = Cmd_Argv(1);

	if (FS_LoadFile (filename, NULL) != -1)
	{	
		// it exists, no need to download
		Com_Printf("File already exists.\n", LOG_CLIENT);
		return;
	}

	CL_CheckOrDownloadFile (filename);

	/*if (strstr (filename, ".."))
	{
		Com_Printf ("Refusing to download a path with .. (%s)\n", LOG_CLIENT, filename);
		return;
	}

	if (FS_LoadFile (filename, NULL) != -1)
	{	// it exists, no need to download
		Com_Printf("File already exists.\n", LOG_CLIENT);
		return;
	}

	strncpy (cls.downloadname, filename, sizeof(cls.downloadname)-1);


	// download to a temp name, and only rename
	// to the real name when done, so if interrupted
	// a runt file wont be left
	COM_StripExtension (cls.downloadname, cls.downloadtempname);
	strcat (cls.downloadtempname, ".tmp");

//ZOID
	// check to see if we already have a tmp for this file, if so, try to resume
	// open the file if not opened yet
	CL_DownloadFileName(name, sizeof(name), cls.downloadtempname);

	fp = fopen (name, "r+b");
	if (fp) { // it exists
		int len;
		
		fseek(fp, 0, SEEK_END);
		len = ftell(fp);

		cls.download = fp;

		// give the server an offset to start the download
		Com_Printf ("Resuming %s\n", LOG_CLIENT, cls.downloadname);
		MSG_WriteByte (clc_stringcmd);
		if (cls.serverProtocol == PROTOCOL_R1Q2) {
			MSG_WriteString (va("download \"%s\" %i udp-zlib", cls.downloadname, len));
		} else {
			MSG_WriteString (va("download \"%s\" %i", cls.downloadname, len));
		}
	} else {
		Com_Printf ("Downloading %s\n", LOG_CLIENT, cls.downloadname);
	
		MSG_WriteByte (clc_stringcmd);
		if (cls.serverProtocol == PROTOCOL_R1Q2) {
			MSG_WriteString (va("download \"%s\" 0 udp-zlib", cls.downloadname));
		} else {
			MSG_WriteString (va("download \"%s\" 0", cls.downloadname));
		}
	}
	MSG_EndWriting (&cls.netchan.message);

	send_packet_now = true;*/
}
Пример #11
0
/*
===============
CL_ParseFileList

Validate a path supplied by a filelist.
===============
*/
static void CL_CheckAndQueueDownload (char *path)
{
	size_t		length;
	char		*ext;
	qboolean	pak;
	qboolean	gameLocal;

	StripHighBits (path, 1);

	length = strlen(path);

	if (length >= MAX_QPATH)
		return;

	ext = strrchr (path, '.');

	if (!ext)
		return;

	ext++;

	if (!ext[0])
		return;

	Q_strlwr (ext);

	if ( !strcmp (ext, "pak") || !strcmp (ext, "pk3") )
	{
		Com_Printf ("NOTICE: Filelist is requesting a .pak file (%s)\n", path);
		pak = true;
	}
	else
		pak = false;

	if (!pak && strcmp (ext, "pcx") && strcmp (ext, "wal") && strcmp (ext, "wav") && strcmp (ext, "md2") &&
		strcmp (ext, "sp2") && strcmp (ext, "tga") && strcmp (ext, "png") && strcmp (ext, "jpg") &&
		strcmp (ext, "bsp") && strcmp (ext, "ent") && strcmp (ext, "txt") && strcmp (ext, "dm2") &&
		strcmp (ext, "loc"))
	{
		Com_Printf ("WARNING: Illegal file type '%s' in filelist.\n", MakePrintable(path, length));
		return;
	}

	if (path[0] == '@')
	{
		if (pak)
		{
			Com_Printf ("WARNING: @ prefix used on a pak file (%s) in filelist.\n", MakePrintable(path, length));
			return;
		}
		gameLocal = true;
		path++;
		length--;
	}
	else
		gameLocal = false;

	if (strstr (path, "..") || !IsValidChar (path[0]) || !IsValidChar (path[length-1]) || strstr(path, "//") ||
		strchr (path, '\\') || (!pak && !strchr (path, '/')) || (pak && strchr(path, '/')))
	{
		Com_Printf ("WARNING: Illegal path '%s' in filelist.\n", MakePrintable(path, length));
		return;
	}

	// by definition paks are game-local
	if (gameLocal || pak)
	{
		qboolean	exists;
		FILE		*f;
		char		gamePath[MAX_OSPATH];

		if (pak)
		{
			Com_sprintf (gamePath, sizeof(gamePath),"%s/%s",FS_Gamedir(), path);
			f = fopen (gamePath, "rb");
			if (!f)
			{
				exists = false;;
			}
			else
			{
				exists = true;
				fclose (f);
			}
		}
		else
		{
		//	exists = FS_ExistsInGameDir (path);
			exists = FS_LocalFileExists (path);
		}

		if (!exists)
		{
			if (CL_QueueHTTPDownload (path))
			{
				//paks get bumped to the top and HTTP switches to single downloading.
				//this prevents someone on 28k dialup trying to do both the main .pak
				//and referenced configstrings data at once.
				if (pak)
				{
					dlqueue_t	*q, *last;

					last = q = &cls.downloadQueue;

					while (q->next)
					{
						last = q;
						q = q->next;
					}

					last->next = NULL;
					q->next = cls.downloadQueue.next;
					cls.downloadQueue.next = q;
				}
			}
		}
	}
	else
	{
		CL_CheckOrDownloadFile (path);
	}
}
Пример #12
0
/**
 * @brief Validate a path supplied by a filelist.
 * @param[in,out] path Pointer to file (path) to download (high bits will be stripped).
 * @sa CL_QueueHTTPDownload
 * @sa CL_ParseFileList
 */
static void CL_CheckAndQueueDownload (char *path)
{
	size_t		length;
	const char	*ext;
	bool	pak;
	bool	gameLocal;

	StripHighBits(path);

	length = strlen(path);

	if (length >= MAX_QPATH)
		return;

	ext = Com_GetExtension(path);
	if (ext == NULL)
		return;

	if (Q_streq(ext, "pk3")) {
		Com_Printf("NOTICE: Filelist is requesting a .pk3 file (%s)\n", path);
		pak = true;
	} else
		pak = false;

	if (!pak &&
			!Q_streq(ext, "bsp") &&
			!Q_streq(ext, "wav") &&
			!Q_streq(ext, "md2") &&
			!Q_streq(ext, "ogg") &&
			!Q_streq(ext, "md3") &&
			!Q_streq(ext, "png") &&
			!Q_streq(ext, "jpg") &&
			!Q_streq(ext, "obj") &&
			!Q_streq(ext, "mat") &&
			!Q_streq(ext, "ump")) {
		Com_Printf("WARNING: Illegal file type '%s' in filelist.\n", path);
		return;
	}

	if (path[0] == '@') {
		if (pak) {
			Com_Printf("WARNING: @ prefix used on a pk3 file (%s) in filelist.\n", path);
			return;
		}
		gameLocal = true;
		path++;
		length--;
	} else
		gameLocal = false;

	if (strstr(path, "..") || !isvalidchar(path[0]) || !isvalidchar(path[length - 1]) || strstr(path, "//") ||
		strchr(path, '\\') || (!pak && !strchr(path, '/')) || (pak && strchr(path, '/'))) {
		Com_Printf("WARNING: Illegal path '%s' in filelist.\n", path);
		return;
	}

	/* by definition pk3s are game-local */
	if (gameLocal || pak) {
		bool exists;

		/* search the user homedir to find the pk3 file */
		if (pak) {
			char gamePath[MAX_OSPATH];
			FILE *f;
			Com_sprintf(gamePath, sizeof(gamePath), "%s/%s", FS_Gamedir(), path);
			f = fopen(gamePath, "rb");
			if (!f)
				exists = false;
			else {
				exists = true;
				fclose(f);
			}
		} else
			exists = FS_CheckFile("%s", path);

		if (!exists) {
			if (CL_QueueHTTPDownload(path)) {
				/* pk3s get bumped to the top and HTTP switches to single downloading.
				 * this prevents someone on 28k dialup trying to do both the main .pk3
				 * and referenced configstrings data at once. */
				if (pak) {
					dlqueue_t** anchor = &cls.downloadQueue;
					while ((*anchor)->next) anchor = &(*anchor)->next;
					/* Remove the last element from the end of the list ... */
					dlqueue_t* const d = *anchor;
					*anchor            = 0;
					/* ... and prepend it to the list. */
					d->next            = cls.downloadQueue;
					cls.downloadQueue  = d;
				}
			}
		}
	} else
		CL_CheckOrDownloadFile(path);
}
Пример #13
0
void CL_RequestNextDownload (void)
{
	unsigned	map_checksum; /* for detecting cheater maps */
	char fn[MAX_OSPATH];
	dmdl_t *pheader;

	if (cls.state != ca_connected)
		return;

	if (!allow_download->value && precache_check < ENV_CNT)
		precache_check = ENV_CNT;

	if (precache_check == CS_MODELS)
	{
		precache_check = CS_MODELS+2;

		if (allow_download_maps->value)
			if (!CL_CheckOrDownloadFile(cl.configstrings[CS_MODELS+1]))
				return; /* started a download */
	}

	if (precache_check >= CS_MODELS && precache_check < CS_MODELS+MAX_MODELS)
	{
		if (allow_download_models->value)
		{
			while (precache_check < CS_MODELS+MAX_MODELS &&
			        cl.configstrings[precache_check][0])
			{
				if (cl.configstrings[precache_check][0] == '*' ||
				        cl.configstrings[precache_check][0] == '#')
				{
					precache_check++;
					continue;
				}

				if (precache_model_skin == 0)
				{
					if (!CL_CheckOrDownloadFile(cl.configstrings[precache_check]))
					{
						precache_model_skin = 1;
						return; /* started a download */
					}

					precache_model_skin = 1;
				}

				/* checking for skins in the model */

				if (!precache_model)
				{

					FS_LoadFile (cl.configstrings[precache_check], (void **)&precache_model);

					if (!precache_model)
					{
						precache_model_skin = 0;
						precache_check++;
						continue; /* couldn't load it */
					}

					if (LittleLong(*(unsigned *)precache_model) != IDALIASHEADER)
					{
						/* not an alias model */
						FS_FreeFile(precache_model);
						precache_model = 0;
						precache_model_skin = 0;
						precache_check++;
						continue;
					}

					pheader = (dmdl_t *)precache_model;

					if (LittleLong (pheader->version) != ALIAS_VERSION)
					{
						precache_check++;
						precache_model_skin = 0;
						continue; /* couldn't load it */
					}
				}

				pheader = (dmdl_t *)precache_model;

				while (precache_model_skin - 1 < LittleLong(pheader->num_skins))
				{
					if (!CL_CheckOrDownloadFile((char *)precache_model +
					                            LittleLong(pheader->ofs_skins) +
					                            (precache_model_skin - 1)*MAX_SKINNAME))
					{
						precache_model_skin++;
						return; /* started a download */
					}

					precache_model_skin++;
				}

				if (precache_model)
				{
					FS_FreeFile(precache_model);
					precache_model = 0;
				}

				precache_model_skin = 0;

				precache_check++;
			}
		}

		precache_check = CS_SOUNDS;
	}

	if (precache_check >= CS_SOUNDS && precache_check < CS_SOUNDS+MAX_SOUNDS)
	{
		if (allow_download_sounds->value)
		{
			if (precache_check == CS_SOUNDS)
				precache_check++;

			while (precache_check < CS_SOUNDS+MAX_SOUNDS &&
			        cl.configstrings[precache_check][0])
			{
				if (cl.configstrings[precache_check][0] == '*')
				{
					precache_check++;
					continue;
				}

				Com_sprintf(fn, sizeof(fn), "sound/%s", cl.configstrings[precache_check++]);

				if (!CL_CheckOrDownloadFile(fn))
					return; /* started a download */
			}
		}

		precache_check = CS_IMAGES;
	}

	if (precache_check >= CS_IMAGES && precache_check < CS_IMAGES+MAX_IMAGES)
	{
		if (precache_check == CS_IMAGES)
			precache_check++;

		while (precache_check < CS_IMAGES+MAX_IMAGES &&
		        cl.configstrings[precache_check][0])
		{
			Com_sprintf(fn, sizeof(fn), "pics/%s.pcx", cl.configstrings[precache_check++]);

			if (!CL_CheckOrDownloadFile(fn))
				return; // started a download
		}

		precache_check = CS_PLAYERSKINS;
	}

	/* skins are special, since a player has three things to download:
	   model, weapon model and skin so precache_check is now *3 */
	if (precache_check >= CS_PLAYERSKINS && precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT)
	{
		if (allow_download_players->value)
		{
			while (precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT)
			{
				int i, n;
				char model[MAX_QPATH], skin[MAX_QPATH], *p;

				i = (precache_check - CS_PLAYERSKINS)/PLAYER_MULT;
				n = (precache_check - CS_PLAYERSKINS)%PLAYER_MULT;

				if (!cl.configstrings[CS_PLAYERSKINS+i][0])
				{
					precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
					continue;
				}

				if ((p = strchr(cl.configstrings[CS_PLAYERSKINS+i], '\\')) != NULL)
					p++;
				else
					p = cl.configstrings[CS_PLAYERSKINS+i];

				strcpy(model, p);

				p = strchr(model, '/');

				if (!p)
					p = strchr(model, '\\');

				if (p)
				{
					*p++ = 0;
					strcpy(skin, p);
				}

				else
					*skin = 0;

				switch (n)
				{

					case 0: /* model */
						Com_sprintf(fn, sizeof(fn), "players/%s/tris.md2", model);

						if (!CL_CheckOrDownloadFile(fn))
						{
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 1;
							return;
						}

						n++;

					case 1: /* weapon model */
						Com_sprintf(fn, sizeof(fn), "players/%s/weapon.md2", model);

						if (!CL_CheckOrDownloadFile(fn))
						{
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 2;
							return;
						}

						n++;

					case 2: /* weapon skin */
						Com_sprintf(fn, sizeof(fn), "players/%s/weapon.pcx", model);

						if (!CL_CheckOrDownloadFile(fn))
						{
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 3;
							return;
						}

						n++;

					case 3: /* skin */
						Com_sprintf(fn, sizeof(fn), "players/%s/%s.pcx", model, skin);

						if (!CL_CheckOrDownloadFile(fn))
						{
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 4;
							return;
						}

						n++;

					case 4: /* skin_i */
						Com_sprintf(fn, sizeof(fn), "players/%s/%s_i.pcx", model, skin);

						if (!CL_CheckOrDownloadFile(fn))
						{
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 5;
							return; // started a download
						}

						/* move on to next model */
						precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
				}
			}
		}

		/* precache phase completed */
		precache_check = ENV_CNT;
	}

	if (precache_check == ENV_CNT)
	{
		precache_check = ENV_CNT + 1;

		CM_LoadMap (cl.configstrings[CS_MODELS+1], true, &map_checksum);

		if (map_checksum != atoi(cl.configstrings[CS_MAPCHECKSUM]))
		{
			Com_Error (ERR_DROP, "Local map version differs from server: %i != '%s'\n",
			           map_checksum, cl.configstrings[CS_MAPCHECKSUM]);
			return;
		}
	}

	if (precache_check > ENV_CNT && precache_check < TEXTURE_CNT)
	{
		if (allow_download->value && allow_download_maps->value)
		{
			while (precache_check < TEXTURE_CNT)
			{
				int n = precache_check++ - ENV_CNT - 1;

				if (n & 1)
					Com_sprintf(fn, sizeof(fn), "env/%s%s.pcx",
					            cl.configstrings[CS_SKY], env_suf[n/2]);
				else
					Com_sprintf(fn, sizeof(fn), "env/%s%s.tga",
					            cl.configstrings[CS_SKY], env_suf[n/2]);

				if (!CL_CheckOrDownloadFile(fn))
					return;
			}
		}

		precache_check = TEXTURE_CNT;
	}

	if (precache_check == TEXTURE_CNT)
	{
		precache_check = TEXTURE_CNT+1;
		precache_tex = 0;
	}

	/* confirm existance of textures, download any that don't exist */
	if (precache_check == TEXTURE_CNT+1)
	{
		extern int			numtexinfo;
		extern mapsurface_t	map_surfaces[];

		if (allow_download->value && allow_download_maps->value)
		{
			while (precache_tex < numtexinfo)
			{
				char fn[MAX_OSPATH];

				sprintf(fn, "textures/%s.wal", map_surfaces[precache_tex++].rname);

				if (!CL_CheckOrDownloadFile(fn))
					return; /* started a download */
			}
		}

		precache_check = TEXTURE_CNT+999;
	}

	CL_RegisterSounds ();

	CL_PrepRefresh ();

	MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
	MSG_WriteString (&cls.netchan.message, va("begin %i\n", precache_spawncount) );
}
Пример #14
0
/*
=================
CL_RequestNextDownload
=================
*/
void CL_RequestNextDownload (void)
{
	unsigned	map_checksum;		// for detecting cheater maps
	char fn[MAX_OSPATH];
	dmdl_t *pheader;

	if (cls.state != ca_connected)
		return;

	// clear failed download list
	if (precache_check == CS_MODELS)
		CL_InitFailedDownloadList ();

	// Knightmare- BIG UGLY HACK for connected to server using old protocol
	// Changed config strings require different parsing
	if ( LegacyProtocol() )
	{	// Old download code
		if (!allow_download->value && precache_check < OLD_ENV_CNT)
			precache_check = OLD_ENV_CNT;

		//ZOID
		if (precache_check == CS_MODELS) { // confirm map
			precache_check = CS_MODELS+2; // 0 isn't used
			if (allow_download_maps->value)
				if (!CL_CheckOrDownloadFile(cl.configstrings[CS_MODELS+1]))
					return; // started a download
		}
		if (precache_check >= CS_MODELS && precache_check < CS_MODELS+OLD_MAX_MODELS) {
			if (allow_download_models->value) {
				while (precache_check < CS_MODELS+OLD_MAX_MODELS &&
					cl.configstrings[precache_check][0]) {
					if (cl.configstrings[precache_check][0] == '*' ||
						cl.configstrings[precache_check][0] == '#') {
						precache_check++;
						continue;
					}
					if (precache_model_skin == 0) {
						if (!CL_CheckOrDownloadFile(cl.configstrings[precache_check])) {
							precache_model_skin = 1;
							return; // started a download
						}
						precache_model_skin = 1;
					}

					// checking for skins in the model
					if (!precache_model) {

						FS_LoadFile (cl.configstrings[precache_check], (void **)&precache_model);
						if (!precache_model) {
							precache_model_skin = 0;
							precache_check++;
							continue; // couldn't load it
						}
						if (LittleLong(*(unsigned *)precache_model) != IDALIASHEADER) {
							// not an alias model
							FS_FreeFile(precache_model);
							precache_model = 0;
							precache_model_skin = 0;
							precache_check++;
							continue;
						}
						pheader = (dmdl_t *)precache_model;
						if (LittleLong (pheader->version) != ALIAS_VERSION) {
							precache_check++;
							precache_model_skin = 0;
							continue; // couldn't load it
						}
					}

					pheader = (dmdl_t *)precache_model;

					while (precache_model_skin - 1 < LittleLong(pheader->num_skins)) {
						if (!CL_CheckOrDownloadFile((char *)precache_model +
							LittleLong(pheader->ofs_skins) + 
							(precache_model_skin - 1)*MAX_SKINNAME)) {
							precache_model_skin++;
							return; // started a download
						}
						precache_model_skin++;
					}
					if (precache_model) { 
						FS_FreeFile(precache_model);
						precache_model = 0;
					}
					precache_model_skin = 0;
					precache_check++;
				}
			}
			precache_check = OLD_CS_SOUNDS;
		}
		if (precache_check >= OLD_CS_SOUNDS && precache_check < OLD_CS_SOUNDS+OLD_MAX_SOUNDS) { 
			if (allow_download_sounds->value) {
				if (precache_check == OLD_CS_SOUNDS)
					precache_check++; // zero is blank
				while (precache_check < OLD_CS_SOUNDS+OLD_MAX_SOUNDS &&
					cl.configstrings[precache_check][0]) {
					if (cl.configstrings[precache_check][0] == '*') {
						precache_check++;
						continue;
					}
					Com_sprintf(fn, sizeof(fn), "sound/%s", cl.configstrings[precache_check++]);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = OLD_CS_IMAGES;
		}
		if (precache_check >= OLD_CS_IMAGES && precache_check < CS_IMAGES+OLD_MAX_IMAGES) {
			if (precache_check == OLD_CS_IMAGES)
				precache_check++; // zero is blank
			while (precache_check < OLD_CS_IMAGES+OLD_MAX_IMAGES &&
				cl.configstrings[precache_check][0]) {
				Com_sprintf(fn, sizeof(fn), "pics/%s.pcx", cl.configstrings[precache_check++]);
				if (!CL_CheckOrDownloadFile(fn))
					return; // started a download
			}
			precache_check = OLD_CS_PLAYERSKINS;
		}
		// skins are special, since a player has three things to download:
		// model, weapon model and skin
		// so precache_check is now *3
		if (precache_check >= OLD_CS_PLAYERSKINS && precache_check < OLD_CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) {
			if (allow_download_players->value)
			{
				while (precache_check < OLD_CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT)
				{
					int32_t i, n;
					char model[MAX_QPATH], skin[MAX_QPATH], *p;

					i = (precache_check - OLD_CS_PLAYERSKINS)/PLAYER_MULT;
					n = (precache_check - OLD_CS_PLAYERSKINS)%PLAYER_MULT;

					if (!cl.configstrings[OLD_CS_PLAYERSKINS+i][0]) {
						precache_check = OLD_CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
						continue;
					}

					if ((p = strchr(cl.configstrings[OLD_CS_PLAYERSKINS+i], '\\')) != NULL)
						p++;
					else
						p = cl.configstrings[OLD_CS_PLAYERSKINS+i];
					strcpy(model, p);
					p = strchr(model, '/');
					if (!p)
						p = strchr(model, '\\');
					if (p) {
						*p++ = 0;
						strcpy(skin, p);
					} else
						*skin = 0;

					switch (n) {
					case 0: // model
						Com_sprintf(fn, sizeof(fn), "players/%s/tris.md2", model);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = OLD_CS_PLAYERSKINS + i * PLAYER_MULT + 1;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 1: // weapon model
						Com_sprintf(fn, sizeof(fn), "players/%s/weapon.md2", model);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = OLD_CS_PLAYERSKINS + i * PLAYER_MULT + 2;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 2: // weapon skin
						Com_sprintf(fn, sizeof(fn), "players/%s/weapon.pcx", model);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = OLD_CS_PLAYERSKINS + i * PLAYER_MULT + 3;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 3: // skin
						Com_sprintf(fn, sizeof(fn), "players/%s/%s.pcx", model, skin);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = OLD_CS_PLAYERSKINS + i * PLAYER_MULT + 4;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 4: // skin_i
						Com_sprintf(fn, sizeof(fn), "players/%s/%s_i.pcx", model, skin);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = OLD_CS_PLAYERSKINS + i * PLAYER_MULT + 5;
							return; // started a download
						}
						// move on to next model
						precache_check = OLD_CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
					}
				}
			}
			// precache phase completed
			precache_check = OLD_ENV_CNT;
		}

		if (precache_check == OLD_ENV_CNT) {
			precache_check = OLD_ENV_CNT + 1;

			CM_LoadMap (cl.configstrings[CS_MODELS+1], true, &map_checksum);

			if (map_checksum != atoi(cl.configstrings[CS_MAPCHECKSUM])) {
				Com_Error (ERR_DROP, "Local map version differs from server: %i != '%s'\n",
					map_checksum, cl.configstrings[CS_MAPCHECKSUM]);
				return;
			}
		}

		if (precache_check > OLD_ENV_CNT && precache_check < OLD_TEXTURE_CNT) {
			if (allow_download->value && allow_download_maps->value) {
				while (precache_check < OLD_TEXTURE_CNT) {
					int32_t n = precache_check++ - OLD_ENV_CNT - 1;

					if (n & 1)
						Com_sprintf(fn, sizeof(fn), "env/%s%s.pcx", 
							cl.configstrings[CS_SKY], env_suf[n/2]);
					else
						Com_sprintf(fn, sizeof(fn), "env/%s%s.tga", 
							cl.configstrings[CS_SKY], env_suf[n/2]);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = OLD_TEXTURE_CNT;
		}

		if (precache_check == OLD_TEXTURE_CNT) {
			precache_check = OLD_TEXTURE_CNT+1;
			precache_tex = 0;
		}

		// confirm existance of .wal textures, download any that don't exist
		if (precache_check == OLD_TEXTURE_CNT+1) {
			// from qcommon/cmodel.c
			extern int32_t			numtexinfo;
			extern mapsurface_t	map_surfaces[];

			if (allow_download->value && allow_download_maps->value)
			{
				while (precache_tex < numtexinfo)
				{
					char fn[MAX_OSPATH];

					sprintf(fn, "textures/%s.wal", map_surfaces[precache_tex++].rname);
					if (!CL_CheckOrDownloadFile(fn))
					{ // Knightmare - jump to next different texture name
					/*	char lasttexname[MAX_OSPATH];
						char nexttexname[MAX_OSPATH];

						sprintf(lasttexname, "%s", map_surfaces[precache_tex].rname);
						while ((precache_tex < numtexinfo))
						{
							sprintf(nexttexname, "%s", map_surfaces[precache_tex+1].rname);
							if (strcmp(lasttexname, nexttexname))
								break;
							precache_tex++;
						}*/
						return; // started a download
					}
				}
			}
			//precache_check = OLD_TEXTURE_CNT+999;
			precache_check = OLD_TEXTURE_CNT+2;
			precache_tex = 0;
		}

		// confirm existance of .jpg textures, try to download any that don't exist
		if (precache_check == OLD_TEXTURE_CNT+2) {
			// from qcommon/cmodel.c
			extern int32_t			numtexinfo;
			extern mapsurface_t	map_surfaces[];

			if (allow_download->value && allow_download_maps->value)
			{
				while (precache_tex < numtexinfo)
				{
					char fn[MAX_OSPATH];

					Com_sprintf(fn, sizeof(fn), "textures/%s.jpg", map_surfaces[precache_tex++].rname);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = OLD_TEXTURE_CNT+3;
			precache_tex = 0;
		}

		// confirm existance of .tga textures, try to download any that don't exist
		if (precache_check == OLD_TEXTURE_CNT+3) {
			// from qcommon/cmodel.c
			extern int32_t			numtexinfo;
			extern mapsurface_t	map_surfaces[];

			if (allow_download->value && allow_download_maps->value)
			{
				while (precache_tex < numtexinfo)
				{
					char fn[MAX_OSPATH];

					Com_sprintf(fn, sizeof(fn), "textures/%s.tga", map_surfaces[precache_tex++].rname);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = OLD_TEXTURE_CNT+999;
		}
	}	//end old download code
	else // New download code
	{
		if (!allow_download->value && precache_check < ENV_CNT)
			precache_check = ENV_CNT;

		// Try downloading pk3 file for current map from server, hack by Jay Dolan
		if (precache_check == CS_MODELS && precache_pak == 0) {
			precache_pak++;
			if (strlen(cl.configstrings[CS_PAKFILE])) {
				if (!CL_CheckOrDownloadFile(cl.configstrings[CS_PAKFILE]))
					return;  // started a download
			}
		}

		// ZOID
		if (precache_check == CS_MODELS) { // confirm map
			precache_check = CS_MODELS+2; // 0 isn't used
			if (allow_download_maps->value)
				if (!CL_CheckOrDownloadFile(cl.configstrings[CS_MODELS+1]))
					return; // started a download
		}
		if (precache_check >= CS_MODELS && precache_check < CS_MODELS+MAX_MODELS)
		{
			if (allow_download_models->value)
			{
				while (precache_check < CS_MODELS+MAX_MODELS &&
					cl.configstrings[precache_check][0]) {
					if (cl.configstrings[precache_check][0] == '*' ||
						cl.configstrings[precache_check][0] == '#') {
						precache_check++;
						continue;
					}
					if (precache_model_skin == 0) {
						if (!CL_CheckOrDownloadFile(cl.configstrings[precache_check])) {
							precache_model_skin = 1;
							return; // started a download
						}
						precache_model_skin = 1;
					}

					// checking for skins in the model
					if (!precache_model)
					{

						FS_LoadFile (cl.configstrings[precache_check], (void **)&precache_model);
						if (!precache_model) {
							precache_model_skin = 0;
							precache_check++;
							continue; // couldn't load it
						}
						if (LittleLong(*(unsigned *)precache_model) != IDALIASHEADER) {
							// not an alias model
							FS_FreeFile(precache_model);
							precache_model = 0;
							precache_model_skin = 0;
							precache_check++;
							continue;
						}
						pheader = (dmdl_t *)precache_model;
						if (LittleLong (pheader->version) != ALIAS_VERSION) {
							precache_check++;
							precache_model_skin = 0;
							continue; // couldn't load it
						}
					}

					pheader = (dmdl_t *)precache_model;

					while (precache_model_skin - 1 < LittleLong(pheader->num_skins)) {
						if (!CL_CheckOrDownloadFile((char *)precache_model +
							LittleLong(pheader->ofs_skins) + 
							(precache_model_skin - 1)*MAX_SKINNAME)) {
							precache_model_skin++;
							return; // started a download
						}
						precache_model_skin++;
					}
					if (precache_model) { 
						FS_FreeFile(precache_model);
						precache_model = 0;
					}
					precache_model_skin = 0;
					precache_check++;
				}
			}
			precache_check = CS_SOUNDS;
		}
		if (precache_check >= CS_SOUNDS && precache_check < CS_SOUNDS+MAX_SOUNDS) { 
			if (allow_download_sounds->value) {
				if (precache_check == CS_SOUNDS)
					precache_check++; // zero is blank
				while (precache_check < CS_SOUNDS+MAX_SOUNDS &&
					cl.configstrings[precache_check][0]) {
					if (cl.configstrings[precache_check][0] == '*') {
						precache_check++;
						continue;
					}
					Com_sprintf(fn, sizeof(fn), "sound/%s", cl.configstrings[precache_check++]);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = CS_IMAGES;
		}
		if (precache_check >= CS_IMAGES && precache_check < CS_IMAGES+MAX_IMAGES) {
			if (precache_check == CS_IMAGES)
				precache_check++; // zero is blank
			while (precache_check < CS_IMAGES+MAX_IMAGES &&
				cl.configstrings[precache_check][0])
			{	
				Com_sprintf(fn, sizeof(fn), "pics/%s.pcx", cl.configstrings[precache_check++]);
				if (!CL_CheckOrDownloadFile(fn))
					return; // started a download
			}
			precache_check = CS_PLAYERSKINS;
		}
		// skins are special, since a player has three things to download:
		// model, weapon model and skin
		// so precache_check is now *3
		if (precache_check >= CS_PLAYERSKINS && precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) {
			if (allow_download_players->value) {
				while (precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) {
					int32_t i, n;
					char model[MAX_QPATH], skin[MAX_QPATH], *p;

					i = (precache_check - CS_PLAYERSKINS)/PLAYER_MULT;
					n = (precache_check - CS_PLAYERSKINS)%PLAYER_MULT;

					if (!cl.configstrings[CS_PLAYERSKINS+i][0]) {
						precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
						continue;
					}

					if ((p = strchr(cl.configstrings[CS_PLAYERSKINS+i], '\\')) != NULL)
						p++;
					else
						p = cl.configstrings[CS_PLAYERSKINS+i];
					strcpy(model, p);
					p = strchr(model, '/');
					if (!p)
						p = strchr(model, '\\');
					if (p) {
						*p++ = 0;
						strcpy(skin, p);
					} else
						*skin = 0;

					switch (n) {
					case 0: // model
						Com_sprintf(fn, sizeof(fn), "players/%s/tris.md2", model);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 1;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 1: // weapon model
						Com_sprintf(fn, sizeof(fn), "players/%s/weapon.md2", model);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 2;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 2: // weapon skin
						Com_sprintf(fn, sizeof(fn), "players/%s/weapon.pcx", model);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 3;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 3: // skin
						Com_sprintf(fn, sizeof(fn), "players/%s/%s.pcx", model, skin);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 4;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 4: // skin_i
						Com_sprintf(fn, sizeof(fn), "players/%s/%s_i.pcx", model, skin);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 5;
							return; // started a download
						}
						// move on to next model
						precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
					}
				}
			}
			// precache phase completed
			precache_check = ENV_CNT;
		}

		if (precache_check == ENV_CNT) {
			precache_check = ENV_CNT + 1;

			CM_LoadMap (cl.configstrings[CS_MODELS+1], true, &map_checksum);

			if (map_checksum != atoi(cl.configstrings[CS_MAPCHECKSUM])) {
				Com_Error (ERR_DROP, "Local map version differs from server: %i != '%s'\n",
					map_checksum, cl.configstrings[CS_MAPCHECKSUM]);
				return;
			}
		}

		if (precache_check > ENV_CNT && precache_check < TEXTURE_CNT) {
			if (allow_download->value && allow_download_maps->value) {
				while (precache_check < TEXTURE_CNT) {
					int32_t n = precache_check++ - ENV_CNT - 1;

					if (n & 1)
						Com_sprintf(fn, sizeof(fn), "env/%s%s.pcx", 
							cl.configstrings[CS_SKY], env_suf[n/2]);
					else
						Com_sprintf(fn, sizeof(fn), "env/%s%s.tga", 
							cl.configstrings[CS_SKY], env_suf[n/2]);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = TEXTURE_CNT;
		}

		if (precache_check == TEXTURE_CNT) {
			precache_check = TEXTURE_CNT+1;
			precache_tex = 0;
		}
		// confirm existance of .wal textures, download any that don't exist
		if (precache_check == TEXTURE_CNT+1) {
			// from qcommon/cmodel.c
			extern int32_t			numtexinfo;
			extern mapsurface_t	map_surfaces[];

			if (allow_download->value && allow_download_maps->value && !Com_ServerState())
			{
				while (precache_tex < numtexinfo)
				{
					char fn[MAX_OSPATH];

					Com_sprintf(fn, sizeof(fn), "textures/%s.wal", map_surfaces[precache_tex++].rname);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			//precache_check = TEXTURE_CNT+999;
			precache_check = TEXTURE_CNT+2;
			precache_tex = 0;
		}

		// confirm existance of .jpg textures, try to download any that don't exist
		if (precache_check == TEXTURE_CNT+2) {
			// from qcommon/cmodel.c
			extern int32_t			numtexinfo;
			extern mapsurface_t	map_surfaces[];

			if (allow_download->value && allow_download_maps->value && allow_download_textures_24bit->value && !Com_ServerState())
			{
				while (precache_tex < numtexinfo)
				{
					char fn[MAX_OSPATH];

					Com_sprintf(fn, sizeof(fn), "textures/%s.jpg", map_surfaces[precache_tex++].rname);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = TEXTURE_CNT+3;
			precache_tex = 0;
		}

		// confirm existance of .tga textures, try to download any that don't exist
		if (precache_check == TEXTURE_CNT+3) {
			// from qcommon/cmodel.c
			extern int32_t			numtexinfo;
			extern mapsurface_t	map_surfaces[];

			if (allow_download->value && allow_download_maps->value && allow_download_textures_24bit->value && !Com_ServerState())
			{
				while (precache_tex < numtexinfo)
				{
					char fn[MAX_OSPATH];

					Com_sprintf(fn, sizeof(fn), "textures/%s.tga", map_surfaces[precache_tex++].rname);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = TEXTURE_CNT+999;
		}
	}	// end new download code
//ZOID

	CL_RegisterSounds ();
	CL_PrepRefresh ();

	MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
	MSG_WriteString (&cls.netchan.message, va("begin %i\n", precache_spawncount) );
}