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; }
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 ) ); }
/* =============== 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); }
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; }
/* =============== 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)); }
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 ) ); }
/* ================= 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 } }
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)); } }
/* ================= 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 } }
/* =============== 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;*/ }
/* =============== 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); } }
/** * @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); }
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) ); }
/* ================= 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) ); }