/* =============== Cmd_StuffCmds_f Adds command line parameters as script statements Commands lead with a +, and continue until a - or another + xash -dev 3 +map c1a0d xash -nosound -game bshift =============== */ void Cmd_StuffCmds_f( void ) { int i, j, l = 0; char build[MAX_CMD_LINE]; // this is for all commandline options combined (and is bounds checked) if( Cmd_Argc() != 1 ) { Msg( "Usage: stuffcmds : execute command line parameters\n" ); return; } // no reason to run the commandline arguments twice if( host.stuffcmdsrun ) return; host.stuffcmdsrun = true; build[0] = 0; for( i = 0; i < host.argc; i++ ) { if( host.argv[i] && host.argv[i][0] == '+' && ( host.argv[i][1] < '0' || host.argv[i][1] > '9' ) && l + Q_strlen( host.argv[i] ) - 1 <= sizeof( build ) - 1 ) { j = 1; while( host.argv[i][j] ) build[l++] = host.argv[i][j++]; for( i++; i < host.argc; i++ ) { if( !host.argv[i] ) continue; if(( host.argv[i][0] == '+' || host.argv[i][0] == '-' ) && ( host.argv[i][1] < '0' || host.argv[i][1] > '9' )) break; if( l + Q_strlen( host.argv[i] ) + 4 > sizeof( build ) - 1 ) break; build[l++] = ' '; if( Q_strchr( host.argv[i], ' ' )) build[l++] = '\"'; for( j = 0; host.argv[i][j]; j++ ) build[l++] = host.argv[i][j]; if( Q_strchr( host.argv[i], ' ' )) build[l++] = '\"'; } build[l++] = '\n'; i--; } } // now terminate the combined string and prepend it to the command buffer // we already reserved space for the terminator build[l++] = 0; Cbuf_InsertText( build ); }
// low-level filesystem wrapper FILE *CFileSystem_Stdio::FS_fopen(const char *filename, const char *options, bool bFromCache) { FILE *tst = fopen(filename, options); #ifndef _WIN32 if (!tst && !Q_strchr(options, 'w') && !Q_strchr(options, '+')) { const char *file = findFileInDirCaseInsensitive(filename); tst = fopen(filename, options); } #endif // _WIN32 return tst; }
/* ============== SCR_NetSpeeds same as r_speeds but for network channel ============== */ void SCR_NetSpeeds( void ) { static char msg[MAX_SYSPATH]; int x, y, height; char *p, *start, *end; float time = cl.mtime[0]; rgba_t color; if( !net_speeds->integer ) return; if( cls.state != ca_active ) return; switch( net_speeds->integer ) { case 1: if( cls.netchan.compress ) { Q_snprintf( msg, sizeof( msg ), "Game Time: %02d:%02d\nTotal received from server:\n Huffman %s\nUncompressed %s\n", (int)(time / 60.0f ), (int)fmod( time, 60.0f ), Q_memprint( cls.netchan.total_received ), Q_memprint( cls.netchan.total_received_uncompressed )); } else { Q_snprintf( msg, sizeof( msg ), "Game Time: %02d:%02d\nTotal received from server:\nUncompressed %s\n", (int)(time / 60.0f ), (int)fmod( time, 60.0f ), Q_memprint( cls.netchan.total_received_uncompressed )); } break; case 2: if( cls.netchan.compress ) { Q_snprintf( msg, sizeof( msg ), "Game Time: %02d:%02d\nTotal sended to server:\nHuffman %s\nUncompressed %s\n", (int)(time / 60.0f ), (int)fmod( time, 60.0f ), Q_memprint( cls.netchan.total_sended ), Q_memprint( cls.netchan.total_sended_uncompressed )); } else { Q_snprintf( msg, sizeof( msg ), "Game Time: %02d:%02d\nTotal sended to server:\nUncompressed %s\n", (int)(time / 60.0f ), (int)fmod( time, 60.0f ), Q_memprint( cls.netchan.total_sended_uncompressed )); } break; default: return; } x = scr_width->integer - 320; y = 256; Con_DrawStringLen( NULL, NULL, &height ); MakeRGBA( color, 255, 255, 255, 255 ); p = start = msg; do { end = Q_strchr( p, '\n' ); if( end ) msg[end-start] = '\0'; Con_DrawString( x, y, p, color ); y += height; if( end ) p = end + 1; else break; } while( 1 ); }
/* ================ SCR_RSpeeds ================ */ void SCR_RSpeeds( void ) { char msg[MAX_SYSPATH]; if( R_SpeedsMessage( msg, sizeof( msg ))) { int x, y, height; char *p, *start, *end; rgba_t color; x = scr_width->integer - 320; y = 64; Con_DrawStringLen( NULL, NULL, &height ); MakeRGBA( color, 255, 255, 255, 255 ); p = start = msg; do { end = Q_strchr( p, '\n' ); if( end ) msg[end-start] = '\0'; Con_DrawString( x, y, p, color ); y += height; if( end ) p = end + 1; else break; } while( 1 ); } }
/* <4f169d> ../game_shared/bot/nav_file.cpp:811 */ void LoadLocationFile(const char *filename) { char locFilename[256]; Q_strcpy(locFilename, filename); char *dot = Q_strchr(locFilename, '.'); if (dot) { Q_strcpy(dot, ".loc"); int locDataLength; char *locDataFile = (char *)LOAD_FILE_FOR_ME(const_cast<char *>(locFilename), &locDataLength); char *locData = locDataFile; if (locData) { CONSOLE_ECHO("Loading legacy 'location file' '%s'\n", locFilename); // read directory locData = MP_COM_Parse(locData); int dirSize = Q_atoi(MP_COM_GetToken()); if (dirSize) { std::vector<unsigned int> directory; directory.reserve(dirSize); for (int i = 0; i < dirSize; ++i) { locData = MP_COM_Parse(locData); directory.push_back(TheBotPhrases->NameToID(MP_COM_GetToken())); } // read places for each nav area unsigned int areaID, locDirIndex; while (true) { locData = MP_COM_Parse(locData); if (locData == NULL) break; areaID = Q_atoi(MP_COM_GetToken()); locData = MP_COM_Parse(locData); locDirIndex = Q_atoi(MP_COM_GetToken()); CNavArea *area = TheNavAreaGrid.GetNavAreaByID(areaID); unsigned int place = (locDirIndex > 0) ? directory[locDirIndex - 1] : UNDEFINED_PLACE; if (area) area->SetPlace(place); } } FREE_FILE(locDataFile); } } }
/* ============== CL_ParseResourceList ============== */ void CL_ParseResourceList( sizebuf_t *msg ) { int i = 0; Q_memset( &reslist, 0, sizeof( resourcelist_t )); reslist.rescount = BF_ReadWord( msg ) - 1; for( i = 0; i < reslist.rescount; i++ ) { reslist.restype[i] = BF_ReadWord( msg ); Q_strncpy( reslist.resnames[i], BF_ReadString( msg ), CS_SIZE ); } cls.downloadcount = 0; HTTP_ResetProcessState(); for( i = 0; i < reslist.rescount; i++ ) { // skip some types #if 0 if( reslist.restype[i] == t_model && !Q_strchr( download_types->latched_string, 'm' ) ) continue; if( reslist.restype[i] == t_sound && !Q_strchr( download_types->latched_string, 's' ) ) continue; if( reslist.restype[i] == t_eventscript && !Q_strchr( download_types->latched_string, 'e' ) ) continue; if( reslist.restype[i] == t_generic && !Q_strchr( download_types->latched_string, 'c' ) ) continue; #endif if( reslist.restype[i] == t_sound ) CL_CheckingSoundResFile( reslist.resnames[i] ); else CL_CheckingResFile( reslist.resnames[i] ); } if( !cls.downloadcount ) { BF_WriteByte( &cls.netchan.message, clc_stringcmd ); BF_WriteString( &cls.netchan.message, "continueloading" ); } }
qboolean findExecutable( const char *baseName, char *buf, size_t size ) { char *envPath; char *part; size_t length; size_t baseNameLength; size_t needTrailingSlash; if( !baseName || !baseName[0] ) return false; envPath = getenv( "PATH" ); if( !envPath ) return false; baseNameLength = Q_strlen( baseName ); while( *envPath ) { part = Q_strchr( envPath, ':' ); if( part ) length = part - envPath; else length = Q_strlen( envPath ); if( length > 0 ) { needTrailingSlash = ( envPath[length - 1] == '/' ) ? 0 : 1; if( length + baseNameLength + needTrailingSlash < size ) { Q_strncpy( buf, envPath, length + 1 ); if( needTrailingSlash ) Q_strcpy( buf + length, "/" ); Q_strcpy( buf + length + needTrailingSlash, baseName ); buf[length + needTrailingSlash + baseNameLength] = '\0'; if( access( buf, X_OK ) == 0 ) return true; } } envPath += length; if( *envPath == ':' ) envPath++; } return false; }
// Load the bot profile database void BotProfileManager::Init(const char *filename, unsigned int *checksum) { static const char *BotDifficultyName[] = { "EASY", "NORMAL", "HARD", "EXPERT", nullptr }; int dataLength; char *dataPointer = (char *)LOAD_FILE_FOR_ME(const_cast<char *>(filename), &dataLength); char *dataFile = dataPointer; if (!dataFile) { if (AreBotsAllowed()) { CONSOLE_ECHO("WARNING: Cannot access bot profile database '%s'\n", filename); } return; } // compute simple checksum if (checksum) { *checksum = ComputeSimpleChecksum((const unsigned char *)dataPointer, dataLength); } // keep list of templates used for inheritance BotProfileList templateList; BotProfile defaultProfile; // Parse the BotProfile.db into BotProfile instances while (true) { dataFile = SharedParse(dataFile); if (!dataFile) break; char *token = SharedGetToken(); bool isDefault = (!Q_stricmp(token, "Default")); bool isTemplate = (!Q_stricmp(token, "Template")); bool isCustomSkin = (!Q_stricmp(token, "Skin")); if (isCustomSkin) { const int BufLen = 64; char skinName[BufLen]; // get skin name dataFile = SharedParse(dataFile); if (!dataFile) { CONSOLE_ECHO("Error parsing %s - expected skin name\n", filename); FREE_FILE(dataPointer); return; } token = SharedGetToken(); Q_snprintf(skinName, BufLen, "%s", token); // get attribute name dataFile = SharedParse(dataFile); if (!dataFile) { CONSOLE_ECHO("Error parsing %s - expected 'Model'\n", filename); FREE_FILE(dataPointer); return; } token = SharedGetToken(); if (Q_stricmp(token, "Model") != 0) { CONSOLE_ECHO("Error parsing %s - expected 'Model'\n", filename); FREE_FILE(dataPointer); return; } // eat '=' dataFile = SharedParse(dataFile); if (!dataFile) { CONSOLE_ECHO("Error parsing %s - expected '='\n", filename); FREE_FILE(dataPointer); return; } token = SharedGetToken(); if (Q_strcmp(token, "=") != 0) { CONSOLE_ECHO("Error parsing %s - expected '='\n", filename); FREE_FILE(dataPointer); return; } // get attribute value dataFile = SharedParse(dataFile); if (!dataFile) { CONSOLE_ECHO("Error parsing %s - expected attribute value\n", filename); FREE_FILE(dataPointer); return; } token = SharedGetToken(); const char *decoratedName = GetDecoratedSkinName(skinName, filename); bool skinExists = GetCustomSkinIndex(decoratedName) > 0; if (m_nextSkin < NumCustomSkins && !skinExists) { // decorate the name m_skins[m_nextSkin] = CloneString(decoratedName); // construct the model filename m_skinModelnames[m_nextSkin] = CloneString(token); m_skinFilenames[m_nextSkin] = new char[Q_strlen(token) * 2 + Q_strlen("models/player//.mdl") + 1]; Q_sprintf(m_skinFilenames[m_nextSkin], "models/player/%s/%s.mdl", token, token); m_nextSkin++; } // eat 'End' dataFile = SharedParse(dataFile); if (!dataFile) { CONSOLE_ECHO("Error parsing %s - expected 'End'\n", filename); FREE_FILE(dataPointer); return; } token = SharedGetToken(); if (Q_strcmp(token, "End") != 0) { CONSOLE_ECHO("Error parsing %s - expected 'End'\n", filename); FREE_FILE(dataPointer); return; } // it's just a custom skin - no need to do inheritance on a bot profile, etc. continue; } // encountered a new profile BotProfile *profile; if (isDefault) { profile = &defaultProfile; } else { profile = new BotProfile; // always inherit from Default *profile = defaultProfile; } // do inheritance in order of appearance if (!isTemplate && !isDefault) { const BotProfile *inherit = nullptr; // template names are separated by "+" while (true) { char *c = Q_strchr(token, '+'); if (c) *c = '\0'; // find the given template name for (auto templates : templateList) { if (!Q_stricmp(templates->GetName(), token)) { inherit = templates; break; } } if (!inherit) { CONSOLE_ECHO("Error parsing '%s' - invalid template reference '%s'\n", filename, token); FREE_FILE(dataPointer); return; } // inherit the data profile->Inherit(inherit, &defaultProfile); if (c == nullptr) break; token = c + 1; } } // get name of this profile if (!isDefault) { dataFile = SharedParse(dataFile); if (!dataFile) { CONSOLE_ECHO("Error parsing '%s' - expected name\n", filename); FREE_FILE(dataPointer); return; } profile->m_name = CloneString(SharedGetToken()); #ifdef REGAMEDLL_FIXES if (RANDOM_LONG(0, 2) == 2) #else // HACK HACK // Until we have a generalized means of storing bot preferences, we're going to hardcode the bot's // preference towards silencers based on his name. if (profile->m_name[0] % 2) #endif { profile->m_prefersSilencer = true; } } // read attributes for this profile bool isFirstWeaponPref = true; while (true) { // get next token dataFile = SharedParse(dataFile); if (!dataFile) { CONSOLE_ECHO("Error parsing %s - expected 'End'\n", filename); FREE_FILE(dataPointer); return; } token = SharedGetToken(); // check for End delimiter if (!Q_stricmp(token, "End")) break; // found attribute name - keep it char attributeName[64]; Q_strcpy(attributeName, token); // eat '=' dataFile = SharedParse(dataFile); if (!dataFile) { CONSOLE_ECHO("Error parsing %s - expected '='\n", filename); FREE_FILE(dataPointer); return; } token = SharedGetToken(); if (Q_strcmp(token, "=") != 0) { CONSOLE_ECHO("Error parsing %s - expected '='\n", filename); FREE_FILE(dataPointer); return; } // get attribute value dataFile = SharedParse(dataFile); if (!dataFile) { CONSOLE_ECHO("Error parsing %s - expected attribute value\n", filename); FREE_FILE(dataPointer); return; } token = SharedGetToken(); // store value in appropriate attribute if (!Q_stricmp("Aggression", attributeName)) { profile->m_aggression = Q_atof(token) / 100.0f; } else if (!Q_stricmp("Skill", attributeName)) { profile->m_skill = Q_atof(token) / 100.0f; } else if (!Q_stricmp("Skin", attributeName)) { profile->m_skin = Q_atoi(token); if (profile->m_skin == 0) { // Q_atoi() failed - try to look up a custom skin by name profile->m_skin = GetCustomSkinIndex(token, filename); } } else if (!Q_stricmp("Teamwork", attributeName)) { profile->m_teamwork = Q_atof(token) / 100.0f; } else if (!Q_stricmp("Cost", attributeName)) { profile->m_cost = Q_atoi(token); } else if (!Q_stricmp("VoicePitch", attributeName)) { profile->m_voicePitch = Q_atoi(token); } else if (!Q_stricmp("VoiceBank", attributeName)) { profile->m_voiceBank = FindVoiceBankIndex(token); } else if (!Q_stricmp("WeaponPreference", attributeName)) { // weapon preferences override parent prefs if (isFirstWeaponPref) { isFirstWeaponPref = false; profile->m_weaponPreferenceCount = 0; } if (!Q_stricmp(token, "none")) { profile->m_weaponPreferenceCount = 0; } else { if (profile->m_weaponPreferenceCount < BotProfile::MAX_WEAPON_PREFS) { profile->m_weaponPreference[profile->m_weaponPreferenceCount++] = AliasToWeaponID(token); } } } else if (!Q_stricmp("ReactionTime", attributeName)) { profile->m_reactionTime = Q_atof(token); #ifndef GAMEUI_EXPORTS // subtract off latency due to "think" update rate. // In GameUI, we don't really care. profile->m_reactionTime -= g_flBotFullThinkInterval; #endif } else if (!Q_stricmp("AttackDelay", attributeName)) { profile->m_attackDelay = Q_atof(token); } else if (!Q_stricmp("Difficulty", attributeName)) { // override inheritance profile->m_difficultyFlags = 0; // parse bit flags while (true) { char *c = Q_strchr(token, '+'); if (c) *c = '\0'; for (int i = 0; i < NUM_DIFFICULTY_LEVELS; i++) { if (!Q_stricmp(BotDifficultyName[i], token)) profile->m_difficultyFlags |= (1<<i); } if (c == nullptr) break; token = c + 1; } } else if (!Q_stricmp("Team", attributeName)) { if (!Q_stricmp(token, "T")) { profile->m_teams = BOT_TEAM_T; } else if (!Q_stricmp(token, "CT")) { profile->m_teams = BOT_TEAM_CT; } else { profile->m_teams = BOT_TEAM_ANY; } } else { CONSOLE_ECHO("Error parsing %s - unknown attribute '%s'\n", filename, attributeName); } } if (!isDefault) { if (isTemplate) { // add to template list templateList.push_back(profile); } else { // add profile to the master list m_profileList.push_back(profile); } } } FREE_FILE(dataPointer); // free the templates for (auto templates : templateList) delete templates; templateList.clear(); }
void CheckLiblistForFallbackDir(const char *pGameDir, bool bLanguage, const char *pLanguage, bool bLowViolenceBuild_) { char szTemp[512]; FileHandle_t hFile; Q_snprintf(szTemp, sizeof(szTemp) - 1, "%s/liblist.gam", pGameDir); COM_FixSlashes(szTemp); g_pFileSystem->GetLocalCopy(szTemp); if (Q_stricmp(com_gamedir, pGameDir)) { Q_snprintf(szTemp, 511, "../%s/liblist.gam", pGameDir); COM_FixSlashes(szTemp); hFile = FS_Open(szTemp, "rt"); } else hFile = FS_Open("liblist.gam", "rt"); if (!hFile) return; if (FS_EndOfFile(hFile)) { FS_Close(hFile); return; } char szFallback[128]; char szLine[512]; char *end; char *start; int bytesToCopy; while (1) { szLine[0] = 0; FS_ReadLine(szLine, sizeof(szLine) - 1, hFile); szLine[511] = 0; if (!Q_strnicmp(szLine, "fallback_dir", Q_strlen("fallback_dir"))) { start = Q_strchr(szLine, '"'); if (!start) { FS_Close(hFile); return; } end = Q_strchr(start + 1, '"'); if (!end) { FS_Close(hFile); return; } bytesToCopy = (int)(end - start) - 1; if (bytesToCopy > sizeof(szFallback) - 2) { FS_Close(hFile); return; } if (bytesToCopy > 0) break; } if (FS_EndOfFile(hFile)) { FS_Close(hFile); return; } } Q_strncpy(szFallback, start + 1, bytesToCopy); szFallback[bytesToCopy] = 0; if (!Q_stricmp(pGameDir, szFallback) ) { FS_Close(hFile); return; } if (bLowViolenceBuild) { Q_snprintf(szTemp, 511, "%s/%s_lv", GetBaseDirectory(), szFallback); szTemp[511] = 0; COM_FixSlashes(szTemp); g_pFileSystem->AddSearchPathNoWrite(szTemp, "GAME_FALLBACK"); } if (BEnableAddonsFolder()) { Q_snprintf(szTemp, 511, "%s/%s_addon", GetBaseDirectory(), szFallback); szTemp[511] = 0; COM_FixSlashes(szTemp); g_pFileSystem->AddSearchPathNoWrite(szTemp, "GAME_FALLBACK"); } if (bLanguage && pLanguage) { char baseDir[4096]; char *tempPtr; Q_snprintf(szTemp, 511, "%s/%s_%s", GetBaseDirectory(), szFallback, pLanguage); szTemp[511] = 0; COM_FixSlashes(szTemp); g_pFileSystem->AddSearchPath(szTemp, "GAME_FALLBACK"); if (!COM_CheckParm("-steam")) { Q_strncpy(baseDir, GetBaseDirectory(), sizeof(baseDir) - 1); baseDir[sizeof(baseDir) - 1] = 0; tempPtr = Q_strstr(baseDir, "\\game"); if (tempPtr) { *tempPtr = 0; Q_snprintf(szTemp, 511, "%s\\localization\\%s_%s", baseDir, szFallback, pLanguage); szTemp[511] = 0; COM_FixSlashes(szTemp); g_pFileSystem->AddSearchPath(szTemp, "GAME_FALLBACK"); } } } if (BEnabledHDAddon()) { Q_snprintf(szTemp, 511, "%s/%s_hd", GetBaseDirectory(), szFallback); szTemp[511] = 0; COM_FixSlashes(szTemp); g_pFileSystem->AddSearchPathNoWrite(szTemp, "GAME_FALLBACK"); } Q_snprintf(szTemp, 511, "%s/%s", GetBaseDirectory(), szFallback); szTemp[511] = 0; COM_FixSlashes(szTemp); g_pFileSystem->AddSearchPath(szTemp, "GAME_FALLBACK"); if (Q_stricmp(szFallback, "valve")) { const int BufLen = 128; char *szFileName = new char[BufLen]; Q_snprintf(szFileName, BufLen - 1, "Resource/%s_%%language%%.txt", szFallback); szFileName[BufLen - 1] = 0; g_fallbackLocalizationFiles.AddToTail(szFileName); CheckLiblistForFallbackDir(szFallback, bLanguage, pLanguage, bLowViolenceBuild); } FS_Close(hFile); }