/* * CL_InitDownload_f * * Hanldles server's initdownload message, starts web or server download if possible */ static void CL_InitDownload_f( void ) { const char *filename; const char *url; int size, alloc_size; unsigned checksum; qboolean allow_localhttpdownload; download_list_t *dl; // ignore download commands coming from demo files if( cls.demo.playing ) return; // read the data filename = Cmd_Argv( 1 ); size = atoi( Cmd_Argv( 2 ) ); checksum = strtoul( Cmd_Argv( 3 ), NULL, 10 ); allow_localhttpdownload = ( atoi( Cmd_Argv( 4 ) ) != 0 ) && cls.httpbaseurl != NULL; url = Cmd_Argv( 5 ); if( !cls.download.requestname ) { Com_Printf( "Got init download message without request\n" ); return; } if( cls.download.filenum || cls.download.web ) { Com_Printf( "Got init download message while already downloading\n" ); return; } if( size == -1 ) { // means that download was refused Com_Printf( "Server refused download request: %s\n", url ); // if it's refused, url field holds the reason CL_DownloadDone(); return; } if( size <= 0 ) { Com_Printf( "Server gave invalid size, not downloading\n" ); CL_DownloadDone(); return; } if( checksum == 0 ) { Com_Printf( "Server didn't provide checksum, not downloading\n" ); CL_DownloadDone(); return; } if( !COM_ValidateRelativeFilename( filename ) ) { Com_Printf( "Not downloading, invalid filename: %s\n", filename ); CL_DownloadDone(); return; } if( FS_CheckPakExtension( filename ) && !cls.download.requestpak ) { Com_Printf( "Got a pak file when requesting normal one, not downloading\n" ); CL_DownloadDone(); return; } if( !FS_CheckPakExtension( filename ) && cls.download.requestpak ) { Com_Printf( "Got a non pak file when requesting pak, not downloading\n" ); CL_DownloadDone(); return; } if( !strchr( filename, '/' ) ) { Com_Printf( "Refusing to download file with no gamedir: %s\n", filename ); CL_DownloadDone(); return; } // check that it is in game or basegame dir if( strlen( filename ) < strlen( FS_GameDirectory() )+1 || strncmp( filename, FS_GameDirectory(), strlen( FS_GameDirectory() ) ) || filename[strlen( FS_GameDirectory() )] != '/' ) { if( strlen( filename ) < strlen( FS_BaseGameDirectory() )+1 || strncmp( filename, FS_BaseGameDirectory(), strlen( FS_BaseGameDirectory() ) ) || filename[strlen( FS_BaseGameDirectory() )] != '/' ) { Com_Printf( "Can't download, invalid game directory: %s\n", filename ); CL_DownloadDone(); return; } } if( FS_CheckPakExtension( filename ) ) { if( strchr( strchr( filename, '/' ) + 1, '/' ) ) { Com_Printf( "Refusing to download pack file to subdirectory: %s\n", filename ); CL_DownloadDone(); return; } if( !Q_strnicmp( COM_FileBase( filename ), "modules", strlen( "modules" ) ) ) { if( !CL_CanDownloadModules() ) { CL_DownloadDone(); return; } } if( FS_FOpenBaseFile( filename, NULL, FS_READ ) != -1 ) { Com_Printf( "Can't download, file already exists: %s\n", filename ); CL_DownloadDone(); return; } } else { if( strcmp( cls.download.requestname, strchr( filename, '/' ) + 1 ) ) { Com_Printf( "Can't download, got different file than requested: %s\n", filename ); CL_DownloadDone(); return; } } if( cls.download.requestnext ) { dl = cls.download.list; while( dl != NULL ) { if( !Q_stricmp( dl->filename, filename ) ) { Com_Printf( "Skipping, already tried downloading: %s\n", filename ); CL_DownloadDone(); return; } dl = dl->next; } } cls.download.name = ZoneCopyString( filename ); alloc_size = strlen( filename ) + strlen( ".tmp" ) + 1; cls.download.tempname = Mem_ZoneMalloc( alloc_size ); Q_snprintfz( cls.download.tempname, alloc_size, "%s.tmp", filename ); cls.download.web = qfalse; cls.download.cancelled = qfalse; cls.download.disconnect = qfalse; cls.download.size = size; cls.download.checksum = checksum; cls.download.percent = 0; cls.download.timeout = 0; cls.download.retries = 0; cls.download.timestart = Sys_Milliseconds(); cls.download.offset = 0; cls.download.baseoffset = 0; cls.download.pending_reconnect = qfalse; Cvar_ForceSet( "cl_download_name", COM_FileBase( cls.download.name ) ); Cvar_ForceSet( "cl_download_percent", "0" ); if( cls.download.requestnext ) { dl = Mem_ZoneMalloc( sizeof( download_list_t ) ); dl->filename = ZoneCopyString( cls.download.name ); dl->next = cls.download.list; cls.download.list = dl; } if( cl_downloads_from_web->integer && allow_localhttpdownload && url && url[0] != 0 ) { cls.download.web = qtrue; Com_Printf( "Web download: %s from %s%s\n", cls.download.tempname, cls.httpbaseurl, url ); } else if( cl_downloads_from_web->integer && url && url[0] != 0 ) { cls.download.web = qtrue; Com_Printf( "Web download: %s from %s\n", cls.download.tempname, url ); } else { Com_Printf( "Server download: %s\n", cls.download.tempname ); } cls.download.baseoffset = cls.download.offset = FS_FOpenBaseFile( cls.download.tempname, &cls.download.filenum, FS_APPEND ); if( !cls.download.filenum ) { Com_Printf( "Can't download, couldn't open %s for writing\n", cls.download.tempname ); Mem_ZoneFree( cls.download.name ); cls.download.name = NULL; Mem_ZoneFree( cls.download.tempname ); cls.download.tempname = NULL; cls.download.filenum = 0; cls.download.offset = 0; cls.download.size = 0; CL_DownloadDone(); return; } if( cls.download.web ) { char *referer, *fullurl; const char *headers[3] = { NULL, NULL, NULL }; alloc_size = strlen( APP_URI_SCHEME ) + strlen( NET_AddressToString( &cls.serveraddress ) ) + 1; referer = Mem_ZoneMalloc( alloc_size ); Q_snprintfz( referer, alloc_size, APP_URI_SCHEME "%s", NET_AddressToString( &cls.serveraddress ) ); Q_strlwr( referer ); if( allow_localhttpdownload ) { alloc_size = strlen( cls.httpbaseurl ) + 1 + strlen( url ) + 1; fullurl = Mem_ZoneMalloc( alloc_size ); Q_snprintfz( fullurl, alloc_size, "%s/%s", cls.httpbaseurl, url ); } else { alloc_size = strlen( url ) + 1 + strlen( filename ) + 1; fullurl = Mem_ZoneMalloc( alloc_size ); Q_snprintfz( fullurl, alloc_size, "%s/%s", url, filename ); } headers[0] = "Referer"; headers[1] = referer; CL_AsyncStreamRequest( fullurl, headers, cl_downloads_from_web_timeout->integer / 100, cls.download.offset, CL_WebDownloadReadCb, CL_WebDownloadDoneCb, NULL, NULL, qfalse ); Mem_ZoneFree( fullurl ); Mem_ZoneFree( referer ); return; } // have to use Sys_Milliseconds because cls.realtime might be old from Web_Get cls.download.timeout = Sys_Milliseconds() + 3000; cls.download.retries = 0; CL_AddReliableCommand( va( "nextdl \"%s\" %i", cls.download.name, cls.download.offset ) ); }
/* =========== G_ClientCleanName ============ */ static void G_ClientCleanName( const char *in, char *out, int outSize, gclient_t *client ) { int len, colorlessLen; char *p; int spaces; qboolean escaped; qboolean invalid = qfalse; qboolean hasletter = qfalse; //save room for trailing null byte outSize--; len = 0; colorlessLen = 0; p = out; *p = 0; spaces = 0; for ( ; *in; in++ ) { int cp, w; // don't allow leading spaces if ( colorlessLen == 0 && *in == ' ' ) { continue; } // don't allow nonprinting characters or (dead) console keys // but do allow UTF-8 (unvalidated) if ( *in >= 0 && *in < ' ' ) { continue; } // check colors if ( Q_IsColorString( in ) ) { in++; // make sure room in dest for both chars if ( len > outSize - 2 ) { break; } *out++ = Q_COLOR_ESCAPE; *out++ = *in; len += 2; continue; } else if ( !g_emoticonsAllowedInNames.integer && G_IsEmoticon( in, &escaped ) ) { // make sure room in dest for both chars if ( len > outSize - 2 ) { break; } *out++ = '['; *out++ = '['; len += 2; if ( escaped ) { in++; } continue; } cp = Q_UTF8_CodePoint( in ); if ( Q_Unicode_IsAlphaOrIdeo( cp ) ) { hasletter = qtrue; } // don't allow too many consecutive spaces if ( *in == ' ' ) { spaces++; if ( spaces > 3 ) { continue; } } else { spaces = 0; } w = Q_UTF8_WidthCP( cp ); if ( len > outSize - w ) { break; } memcpy( out, in, w ); colorlessLen++; len += w; out += w; in += w - 1; // allow for loop increment } *out = 0; // don't allow names beginning with S_SKIPNOTIFY because it messes up /ignore-related code if ( !Q_strnicmp( p, S_SKIPNOTIFY, 12 ) ) { invalid = qtrue; } // don't allow comment-beginning strings because it messes up various parsers if ( strstr( p, "//" ) || strstr( p, "/*" ) ) { invalid = qtrue; } // don't allow empty names if ( *p == 0 || colorlessLen == 0 ) { invalid = qtrue; } // limit no. of code points if ( Q_UTF8_PrintStrlen( p ) > MAX_NAME_LENGTH_CP ) { invalid = qtrue; } // if something made the name bad, put them back to UnnamedPlayer if ( invalid || !hasletter ) { Q_strncpyz( p, G_UnnamedClientName( client ), outSize ); } }
/* ================= CG_Say ================= */ static void CG_Say( const char *name, int clientNum, saymode_t mode, const char *text ) { char prefix[ 21 ] = ""; const char *ignore = ""; const char *location = ""; team_t team = TEAM_NONE; if ( clientNum >= 0 && clientNum < MAX_CLIENTS ) { clientInfo_t *ci = &cgs.clientinfo[ clientNum ]; Color::Color tcolor = Color::White; name = ci->name; team = ci->team; if ( ci->team == TEAM_ALIENS ) { tcolor = Color::Red; } else if ( ci->team == TEAM_HUMANS ) { tcolor = Color::Cyan; } if ( cg_chatTeamPrefix.integer ) { Com_sprintf( prefix, sizeof( prefix ), "[%s%c^*] ", Color::CString( tcolor ), Str::ctoupper( * ( BG_TeamName( ci->team ) ) ) ); } if ( Com_ClientListContains( &cgs.ignoreList, clientNum ) ) { ignore = S_SKIPNOTIFY; } if ( ( mode == SAY_TEAM || mode == SAY_AREA ) && cg.snap->ps.pm_type != PM_INTERMISSION ) { int locationNum; if ( clientNum == cg.snap->ps.clientNum ) { centity_t *locent; locent = CG_GetPlayerLocation(); if ( locent ) { locationNum = locent->currentState.generic1; } else { locationNum = 0; } } else { locationNum = ci->location; } if ( locationNum > 0 && locationNum < MAX_LOCATIONS ) { const char *s = CG_ConfigString( CS_LOCATIONS + locationNum ); if ( *s ) { location = va( " (%s^*)", s ); } } } } else if ( name ) { Q_strcat( prefix, sizeof( prefix ), "[ADMIN]" ); } else { name = "console"; } // IRC-like /me parsing if ( mode != SAY_RAW && Q_strnicmp( text, "/me ", 4 ) == 0 ) { text += 4; Q_strcat( prefix, sizeof( prefix ), "* " ); } const char* color = Color::CString( UI_GetChatColour( mode, team ) ); switch ( mode ) { case SAY_ALL: // might already be ignored but in that case no harm is done if ( cg_teamChatsOnly.integer ) { ignore = S_SKIPNOTIFY; } case SAY_ALL_ADMIN: CG_Printf( "%s%s%s^7: %s%s\n", ignore, prefix, name, color, text ); break; case SAY_TEAM: CG_Printf( "%s%s(%s^7)%s: %s%s\n", ignore, prefix, name, location, color, text ); break; case SAY_ADMINS: case SAY_ADMINS_PUBLIC: CG_Printf( "%s%s%s%s^7: %s%s\n", ignore, prefix, ( mode == SAY_ADMINS ) ? "[ADMIN]" : "[PLAYER]", name, color, text ); break; case SAY_AREA: case SAY_AREA_TEAM: CG_Printf( "%s%s<%s^7>%s: %s%s\n", ignore, prefix, name, location, color, text ); break; case SAY_PRIVMSG: case SAY_TPRIVMSG: CG_Printf( "%s%s[%s^7 → %s^7]: %s%s\n", ignore, prefix, name, cgs.clientinfo[ cg.clientNum ].name, color, text ); if ( !ignore[ 0 ] ) { CG_CenterPrint( va( _("%sPrivate message from: ^7%s"), color, name ), 200, GIANTCHAR_WIDTH * 4 ); if ( clientNum < 0 || clientNum >= MAX_CLIENTS ) { clientNum = cg.clientNum; } CG_Printf(_( ">> to reply, say: /m %d [your message] <<\n"), clientNum ); } break; case SAY_ALL_ME: CG_Printf( "%s* %s%s^7 %s%s\n", ignore, prefix, name, color, text ); break; case SAY_TEAM_ME: CG_Printf( "%s* %s(%s^7)%s %s%s\n", ignore, prefix, name, location, color, text ); break; case SAY_RAW: CG_Printf( "%s\n", text ); break; case SAY_DEFAULT: default: break; } switch ( mode ) { case SAY_TEAM: case SAY_AREA: case SAY_TPRIVMSG: if ( cgs.clientinfo[ clientNum ].team == TEAM_ALIENS ) { trap_S_StartLocalSound( cgs.media.alienTalkSound, CHAN_LOCAL_SOUND ); break; } else if ( cgs.clientinfo[ clientNum ].team == TEAM_HUMANS ) { trap_S_StartLocalSound( cgs.media.humanTalkSound, CHAN_LOCAL_SOUND ); break; } default: trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND ); } }
/* * SV_ReloadPureList */ static void SV_ReloadPureList( void ) { char **paks; int i, numpaks; Com_FreePureList( &svs.purelist ); // game modules if( sv_pure_forcemodulepk3->string[0] ) { if( Q_strnicmp( COM_FileBase( sv_pure_forcemodulepk3->string ), "modules", strlen( "modules" ) ) || !FS_IsPakValid( sv_pure_forcemodulepk3->string, NULL ) ) { Com_Printf( "Warning: Invalid value for sv_pure_forcemodulepk3, disabling\n" ); Cvar_ForceSet( "sv_pure_forcemodulepk3", "" ); } else { SV_AddPurePak( sv_pure_forcemodulepk3->string ); } } if( !sv_pure_forcemodulepk3->string[0] ) { char *libname; int libname_size; libname_size = strlen( LIB_PREFIX ) + 5 + strlen( ARCH ) + strlen( LIB_SUFFIX ) + 1; libname = Mem_TempMalloc( libname_size ); Q_snprintfz( libname, libname_size, LIB_PREFIX "game_" ARCH LIB_SUFFIX ); if( !FS_PakNameForFile( libname ) ) { if( sv_pure->integer ) { Com_Printf( "Warning: Game module not in pk3, disabling pure mode\n" ); Com_Printf( "sv_pure_forcemodulepk3 can be used to force the pure system to use a different module\n" ); Cvar_ForceSet( "sv_pure", "0" ); } } else { SV_AddPureFile( libname ); } Mem_TempFree( libname ); libname = NULL; } // *pure.(pk3|pak) paks = NULL; numpaks = FS_GetExplicitPurePakList( &paks ); if( numpaks ) { for( i = 0; i < numpaks; i++ ) { SV_AddPurePak( paks[i] ); Mem_ZoneFree( paks[i] ); } Mem_ZoneFree( paks ); } }
//-------------------------------------------------------------------------------------------------------------- void DownloadManager::Queue( const char *baseURL, const char *gamePath ) { bool bAsHTTP = false; if ( !gamePath ) { return; } #ifndef _DEBUG if ( sv.IsActive() ) { return; // don't try to download things for the local server (in case a map is missing sounds etc that // aren't needed to play. } #endif // only http downloads if ( baseURL && (!Q_strnicmp( baseURL, "http://", 7 ) || !Q_strnicmp( baseURL, "https://", 8 )) ) { bAsHTTP = true; } if ( g_pFileSystem->FileExists( gamePath ) ) { return; // don't download existing files } if ( Q_strstr( gamePath, "//" ) ) { return; } if ( Q_strstr( gamePath, "\\\\" ) ) { return; } if ( Q_strstr( gamePath, ":" ) ) { return; } if ( Q_strstr( gamePath, "lua/" ) ) return; // don't download into lua/ folder if ( Q_strstr( gamePath, "gamemodes/" ) ) return; // don't download into gamemodes/ folder if ( Q_strstr( gamePath, "addons/" ) ) return; // don't download into addons/ folder // Disallow .. in paths, but allow multiple periods otherwise. This way we can download blah.dx80.vtx etc. const char *backup = strstr( gamePath, ".." ); const char *extension = strrchr( gamePath, '.' ); if ( backup || !extension ) return; int baseLen = strlen( extension ); if ( baseLen > 4 || baseLen < 3 ) return; if ( !Q_strcasecmp( extension, ".cfg" ) ) return; if ( !Q_strcasecmp( extension, ".lst" ) ) return; if ( !Q_strcasecmp( extension, ".exe" ) ) return; if ( !Q_strcasecmp( extension, ".vbs" ) ) return; if ( !Q_strcasecmp( extension, ".com" ) ) return; if ( !Q_strcasecmp( extension, ".bat" ) ) return; if ( !Q_strcasecmp( extension, ".dll" ) ) return; if ( !Q_strcasecmp( extension, ".ini" ) ) return; if ( !Q_strcasecmp( extension, ".log" ) ) return; if ( !Q_strcasecmp( extension, ".lua" ) ) return; if ( bAsHTTP && !g_pFileSystem->FileExists( va( "%s.bz2", gamePath ) ) ) { // Queue up an HTTP download of the bzipped asset, in case it exists. // When a bzipped download finishes, we'll uncompress the file to it's // original destination, and the queued download of the uncompressed // file will abort. ++m_totalRequests; if ( !TheDownloadCache ) { TheDownloadCache = new DownloadCache; TheDownloadCache->Init(); } RequestContext *rc = new RequestContext; m_queuedRequests.AddToTail( rc ); memset( rc, 0, sizeof(RequestContext) ); rc->status = HTTP_CONNECTING; Q_strncpy( rc->basePath, com_gamedir, BufferSize ); Q_strncpy( rc->gamePath, gamePath, BufferSize ); Q_strncat( rc->gamePath, ".bz2", BufferSize, COPY_ALL_CHARACTERS ); Q_FixSlashes( rc->gamePath, '/' ); // only matters for debug prints, which are full URLS, so we want forward slashes Q_strncpy( rc->serverURL, cl.m_NetChannel->GetRemoteAddress().ToString(), BufferSize ); rc->bIsBZ2 = true; rc->bAsHTTP = true; Q_strncpy( rc->baseURL, baseURL, BufferSize ); Q_strncat( rc->baseURL, "/", BufferSize, COPY_ALL_CHARACTERS ); //ConDColorMsg( DownloadColor, "Queueing %s%s.\n", rc->baseURL, gamePath ); } ++m_totalRequests; if ( !TheDownloadCache ) { TheDownloadCache = new DownloadCache; TheDownloadCache->Init(); } RequestContext *rc = new RequestContext; m_queuedRequests.AddToTail( rc ); memset( rc, 0, sizeof(RequestContext) ); rc->status = HTTP_CONNECTING; Q_strncpy( rc->basePath, com_gamedir, BufferSize ); Q_strncpy( rc->gamePath, gamePath, BufferSize ); Q_FixSlashes( rc->gamePath, '/' ); // only matters for debug prints, which are full URLS, so we want forward slashes Q_strncpy( rc->serverURL, cl.m_NetChannel->GetRemoteAddress().ToString(), BufferSize ); if ( bAsHTTP ) { rc->bAsHTTP = true; Q_strncpy( rc->baseURL, baseURL, BufferSize ); Q_strncat( rc->baseURL, "/", BufferSize, COPY_ALL_CHARACTERS ); } else { rc->bAsHTTP = false; } //ConDColorMsg( DownloadColor, "Queueing %s%s.\n", rc->baseURL, gamePath ); }
//----------------------------------------------------------------------------- // Purpose: Take a NULL terminated sentence, and parse any commands contained in // {}. The string is rewritten in place with those commands removed. // // Input : *pSentenceData - sentence data to be modified in place // sentenceIndex - global sentence table index for any data that is // parsed out //----------------------------------------------------------------------------- void VOX_ParseLineCommands( char *pSentenceData, int sentenceIndex ) { char tempBuffer[512]; char *pNext, *pStart; int length, tempBufferPos = 0; if( !pSentenceData ) return; pStart = pSentenceData; while( *pSentenceData ) { pNext = ScanForwardUntil( pSentenceData, '{' ); // find length of "good" portion of the string (not a {} command) length = pNext - pSentenceData; if( tempBufferPos + length > sizeof( tempBuffer )) { MsgDev( D_ERROR, "sentence too long!\n" ); return; } // Copy good string to temp buffer Q_memcpy( tempBuffer + tempBufferPos, pSentenceData, length ); // move the copy position tempBufferPos += length; pSentenceData = pNext; // skip ahead of the opening brace if( *pSentenceData ) pSentenceData++; // skip whitespace while( *pSentenceData && *pSentenceData <= 32 ) pSentenceData++; // simple comparison of string commands: switch( Q_tolower( *pSentenceData )) { case 'l': // all commands starting with the letter 'l' here if( !Q_strnicmp( pSentenceData, "len", 3 )) { g_Sentences[sentenceIndex].length = Q_atof( pSentenceData + 3 ); } break; case 0: default: break; } pSentenceData = ScanForwardUntil( pSentenceData, '}' ); // skip the closing brace if( *pSentenceData ) pSentenceData++; // skip trailing whitespace while( *pSentenceData && *pSentenceData <= 32 ) pSentenceData++; } if( tempBufferPos < sizeof( tempBuffer )) { // terminate cleaned up copy tempBuffer[tempBufferPos] = 0; // copy it over the original data Q_strcpy( pStart, tempBuffer ); } }
/* * TV_Downstream_FixName * * Make name valid, so it's not used by anyone else or so. See G_SetName * Client can be given, so conflict with that client's name won't matter * The returned value will be overwritten by the next call to this function */ char *TV_Downstream_FixName( const char *original_name, client_t *client ) { const char *invalid_prefixes[] = { "console", "[team]", "[spec]", "[bot]", "[coach]", "[tv]", NULL }; client_t *other; static char name[MAX_NAME_BYTES]; char colorless[MAX_NAME_BYTES]; int i, trynum, trylen; int c_ascii; int maxchars; // we allow NULL to be passed for name if( !original_name ) original_name = ""; Q_strncpyz( name, original_name, sizeof( name ) ); // life is hard, UTF-8 will have to go strip_highchars( name ); COM_SanitizeColorString( va( "%s", name ), name, sizeof( name ), -1, COLOR_WHITE ); // remove leading whitespace while( name[0] == ' ' ) memmove( name, name + 1, strlen( name ) ); // remove trailing whitespace while( strlen( name ) && name[strlen(name)-1] == ' ' ) name[strlen(name)-1] = '\0'; Q_strncpyz( colorless, COM_RemoveColorTokens( name ), sizeof( colorless ) ); maxchars = MAX_NAME_CHARS; if( client && client->tv ) maxchars = min( maxchars + 10, MAX_NAME_BYTES-1 ); // require at least one non-whitespace ascii char in the name // (this will upset people who would like to have a name entirely in a non-latin // script, but it makes damn sure you can't get an empty name by exploiting some // utf-8 decoder quirk) c_ascii = 0; for( i = 0; colorless[i]; i++ ) if( colorless[i] > 32 && colorless[i] < 127 ) c_ascii++; if( !c_ascii ) { Q_strncpyz( name, "Player", sizeof( name ) ); Q_strncpyz( colorless, COM_RemoveColorTokens( name ), sizeof( colorless ) ); } for( i = 0; invalid_prefixes[i] != NULL; i++ ) { if( !Q_strnicmp( colorless, invalid_prefixes[i], strlen( invalid_prefixes[i] ) ) ) { Q_strncpyz( name, "Player", sizeof( name ) ); Q_strncpyz( colorless, COM_RemoveColorTokens( name ), sizeof( colorless ) ); } } trynum = 1; do { for( i = 0, other = tvs.clients; i < tv_maxclients->integer; i++, other++ ) { if( ( client && other == client ) || other->state == CS_FREE || other->state == CS_ZOMBIE ) continue; // if nick is already in use, try with (number) appended if( !Q_stricmp( colorless, COM_RemoveColorTokens( other->name ) ) ) { if( trynum != 1 ) // remove last try name[strlen( name ) - strlen( va( "%s(%i)", S_COLOR_WHITE, trynum-1 ) )] = 0; // make sure there is enough space for the postfix trylen = strlen( va( "%s(%i)", S_COLOR_WHITE, trynum ) ); if( (int)strlen( colorless ) + trylen > maxchars ) { COM_SanitizeColorString( va( "%s", name ), name, sizeof( name ), maxchars - trylen, COLOR_WHITE ); Q_strncpyz( colorless, COM_RemoveColorTokens( name ), sizeof( colorless ) ); } // add the postfix Q_strncatz( name, va( "%s(%i)", S_COLOR_WHITE, trynum ), sizeof( name ) ); Q_strncpyz( colorless, COM_RemoveColorTokens( name ), sizeof( colorless ) ); // go trough all clients again trynum++; break; } } } while( i != tv_maxclients->integer && trynum <= MAX_CLIENTS ); return name; }
/* <4b17> ../engine/cmd.c:1301 */ void Cmd_CmdList_f(void) { cmd_function_t *cmd; int iCmds; int iArgs; const char *partial, *arg1; int ipLen; char szTemp[MAX_PATH]; FileHandle_t f; FileHandle_t fp; qboolean bLogging; iCmds = 0; partial = NULL; f = NULL; fp = NULL; bLogging = FALSE; iArgs = Cmd_Argc(); if (iArgs > 1) { arg1 = Cmd_Argv(1); if (!Q_stricmp(arg1, "?")) { Con_Printf("CmdList : List all commands\nCmdList [Partial] : List commands starting with 'Partial'\nCmdList log [Partial] : Logs commands to file \"cmdlist.txt\" in the gamedir.\n"); return; } if (!Q_stricmp(arg1, "log")) { // Open log int i; for (i = 0; i < 100; i++) { Q_snprintf(szTemp, ARRAYSIZE(szTemp) - 1, "cmdlist%02d.txt", i); szTemp[ARRAYSIZE(szTemp) - 1] = 0; fp = FS_Open(szTemp, "r"); if (!fp) { break; } FS_Close(fp); } if (i >= 100) { Con_Printf("Can't cmdlist! Too many existing cmdlist output files in the gamedir!\n"); return; } f = FS_Open(szTemp, "wt"); if (!f) { Con_Printf("Couldn't open \"%s\" for writing!\n", szTemp); return; } bLogging = TRUE; // Get next argument into partial, if present if (iArgs >= 2) { partial = Cmd_Argv(2); ipLen = Q_strlen(partial); } } else { partial = arg1; ipLen = Q_strlen(partial); } } // Print commands Con_Printf("Command List\n--------------\n"); for (cmd = cmd_functions; cmd; cmd = cmd->next) { if (partial && Q_strnicmp(cmd->name, partial, ipLen)) { continue; } Con_Printf("%s\n", cmd->name); if (bLogging) { FS_FPrintf(f, "%s\n", cmd->name); } iCmds++; } if (partial && *partial) { Con_Printf("--------------\n%3i Commands for [%s]\nCmdList ? for syntax\n", iCmds, partial); } else { Con_Printf("--------------\n%3i Total Commands\nCmdList ? for syntax\n", iCmds); } // Close log if (bLogging) { FS_Close(f); Con_Printf("cmdlist logged to %s\n", szTemp); } }
/* * G_SetName */ static void G_SetName( edict_t *ent, const char *original_name ) { const char *invalid_prefixes[] = { "console", "[team]", "[spec]", "[bot]", "[coach]", "[tv]", NULL }; edict_t *other; char name[MAX_NAME_BYTES]; char colorless[MAX_NAME_BYTES]; int i, trynum, trylen; int c_ascii; int maxchars; if( !ent->r.client ) return; // we allow NULL to be passed for name if( !original_name ) original_name = ""; Q_strncpyz( name, original_name, sizeof( name ) ); c_ascii = G_SanitizeUserString( name, sizeof( name ) ); if( !c_ascii ) Q_strncpyz( name, "Player", sizeof( name ) ); Q_strncpyz( colorless, COM_RemoveColorTokens( name ), sizeof( colorless ) ); if( !( ent->r.svflags & SVF_FAKECLIENT ) ) { for( i = 0; invalid_prefixes[i] != NULL; i++ ) { if( !Q_strnicmp( colorless, invalid_prefixes[i], strlen( invalid_prefixes[i] ) ) ) { Q_strncpyz( name, "Player", sizeof( name ) ); Q_strncpyz( colorless, COM_RemoveColorTokens( name ), sizeof( colorless ) ); break; } } } maxchars = MAX_NAME_CHARS; if( ent->r.client->isTV ) maxchars = min( maxchars + 10, MAX_NAME_BYTES-1 ); // Limit the name to MAX_NAME_CHARS printable characters // (non-ascii utf-8 sequences are currently counted as 2 or more each, sorry) COM_SanitizeColorString( va( "%s", name ), name, sizeof( name ), maxchars, COLOR_WHITE ); Q_strncpyz( colorless, COM_RemoveColorTokens( name ), sizeof( colorless ) ); trynum = 1; do { for( i = 0; i < gs.maxclients; i++ ) { other = game.edicts + 1 + i; if( !other->r.inuse || !other->r.client || other == ent ) continue; // if nick is already in use, try with (number) appended if( !Q_stricmp( colorless, COM_RemoveColorTokens( other->r.client->netname ) ) ) { if( trynum != 1 ) // remove last try name[strlen( name ) - strlen( va( "%s(%i)", S_COLOR_WHITE, trynum-1 ) )] = 0; // make sure there is enough space for the postfix trylen = strlen( va( "%s(%i)", S_COLOR_WHITE, trynum ) ); if( (int)strlen( colorless ) + trylen > maxchars ) { COM_SanitizeColorString( va( "%s", name ), name, sizeof( name ), maxchars - trylen, COLOR_WHITE ); Q_strncpyz( colorless, COM_RemoveColorTokens( name ), sizeof( colorless ) ); } // add the postfix Q_strncatz( name, va( "%s(%i)", S_COLOR_WHITE, trynum ), sizeof( name ) ); Q_strncpyz( colorless, COM_RemoveColorTokens( name ), sizeof( colorless ) ); // go trough all clients again trynum++; break; } } } while( i != gs.maxclients && trynum <= MAX_CLIENTS ); Q_strncpyz( ent->r.client->netname, name, sizeof( ent->r.client->netname ) ); }
/* * G_SetClan */ static void G_SetClan( edict_t *ent, const char *original_clan ) { const char *invalid_values[] = { "console", "spec", "bot", "coach", "tv", NULL }; char clan[MAX_CLANNAME_BYTES]; char colorless[MAX_CLANNAME_BYTES]; int i; int c_ascii; int maxchars; if( !ent->r.client ) return; // we allow NULL to be passed for clan name if( ent->r.svflags & SVF_FAKECLIENT ) original_clan = "BOT"; else if( !original_clan ) original_clan = ""; Q_strncpyz( clan, original_clan, sizeof( clan ) ); COM_Compress( clan ); c_ascii = G_SanitizeUserString( clan, sizeof( clan ) ); if( !c_ascii ) clan[0] = colorless[0] = '\0'; else Q_strncpyz( colorless, COM_RemoveColorTokens( clan ), sizeof( colorless ) ); if( !( ent->r.svflags & SVF_FAKECLIENT ) ) { for( i = 0; invalid_values[i] != NULL; i++ ) { if( !Q_strnicmp( colorless, invalid_values[i], strlen( invalid_values[i] ) ) ) { clan[0] = colorless[0] = '\0'; break; } } } // clan names can not contain spaces Q_chrreplace( clan, ' ', '_' ); // clan names can not start with an ampersand { char *t; int len; t = clan; while( *t == '&' ) t++; len = strlen( clan ) - (t - clan); if( clan != t ) memmove( clan, t, len + 1 ); } maxchars = MAX_CLANNAME_CHARS; // Limit the name to MAX_NAME_CHARS printable characters // (non-ascii utf-8 sequences are currently counted as 2 or more each, sorry) COM_SanitizeColorString( va( "%s", clan ), clan, sizeof( clan ), maxchars, COLOR_WHITE ); Q_strncpyz( ent->r.client->clanname, clan, sizeof( ent->r.client->clanname ) ); }
/* ================= Q_stricmp ================= */ int Q_stricmp (const char *string1, const char *string2){ return Q_strnicmp(string1, string2, 99999); }
/* ** GLW_InitExtensions */ static void GLimp_InitExtensions( void ) { if ( !r_allowExtensions->integer ) { Com_Printf ("*** IGNORING OPENGL EXTENSIONS ***\n" ); g_bDynamicGlowSupported = false; Cvar_Set( "r_DynamicGlow","0" ); return; } Com_Printf ("Initializing OpenGL extensions\n" ); // Select our tc scheme GLW_InitTextureCompression(); // GL_EXT_texture_env_add glConfig.textureEnvAddAvailable = qfalse; if ( strstr( glConfig.extensions_string, "EXT_texture_env_add" ) ) { if ( r_ext_texture_env_add->integer ) { glConfig.textureEnvAddAvailable = qtrue; Com_Printf ("...using GL_EXT_texture_env_add\n" ); } else { glConfig.textureEnvAddAvailable = qfalse; Com_Printf ("...ignoring GL_EXT_texture_env_add\n" ); } } else { Com_Printf ("...GL_EXT_texture_env_add not found\n" ); } // GL_EXT_texture_filter_anisotropic glConfig.maxTextureFilterAnisotropy = 0; if ( strstr( glConfig.extensions_string, "EXT_texture_filter_anisotropic" ) ) { #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF //can't include glext.h here ... sigh qglGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.maxTextureFilterAnisotropy ); Com_Printf ("...GL_EXT_texture_filter_anisotropic available\n" ); if ( r_ext_texture_filter_anisotropic->integer>1 ) { Com_Printf ("...using GL_EXT_texture_filter_anisotropic\n" ); } else { Com_Printf ("...ignoring GL_EXT_texture_filter_anisotropic\n" ); } Cvar_Set( "r_ext_texture_filter_anisotropic_avail", va("%f",glConfig.maxTextureFilterAnisotropy) ); if ( r_ext_texture_filter_anisotropic->value > glConfig.maxTextureFilterAnisotropy ) { Cvar_Set( "r_ext_texture_filter_anisotropic", va("%f",glConfig.maxTextureFilterAnisotropy) ); } } else { Com_Printf ("...GL_EXT_texture_filter_anisotropic not found\n" ); Cvar_Set( "r_ext_texture_filter_anisotropic_avail", "0" ); } // GL_EXT_clamp_to_edge glConfig.clampToEdgeAvailable = qfalse; if ( strstr( glConfig.extensions_string, "GL_EXT_texture_edge_clamp" ) ) { glConfig.clampToEdgeAvailable = qtrue; Com_Printf ("...Using GL_EXT_texture_edge_clamp\n" ); } #if 0 // WGL_EXT_swap_control qwglSwapIntervalEXT = ( BOOL (WINAPI *)(int)) SDL_GL_GetProcAddress( "wglSwapIntervalEXT" ); if ( qwglSwapIntervalEXT ) { Com_Printf ("...using WGL_EXT_swap_control\n" ); r_swapInterval->modified = qtrue; // force a set next frame } else { Com_Printf ("...WGL_EXT_swap_control not found\n" ); } #endif // GL_ARB_multitexture qglMultiTexCoord2fARB = NULL; qglActiveTextureARB = NULL; qglClientActiveTextureARB = NULL; if ( strstr( glConfig.extensions_string, "GL_ARB_multitexture" ) ) { if ( r_ext_multitexture->integer ) { qglMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) SDL_GL_GetProcAddress( "glMultiTexCoord2fARB" ); qglActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) SDL_GL_GetProcAddress( "glActiveTextureARB" ); qglClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) SDL_GL_GetProcAddress( "glClientActiveTextureARB" ); if ( qglActiveTextureARB ) { qglGetIntegerv( GL_MAX_ACTIVE_TEXTURES_ARB, &glConfig.maxActiveTextures ); if ( glConfig.maxActiveTextures > 1 ) { Com_Printf ("...using GL_ARB_multitexture\n" ); } else { qglMultiTexCoord2fARB = NULL; qglActiveTextureARB = NULL; qglClientActiveTextureARB = NULL; Com_Printf ("...not using GL_ARB_multitexture, < 2 texture units\n" ); } } } else { Com_Printf ("...ignoring GL_ARB_multitexture\n" ); } } else { Com_Printf ("...GL_ARB_multitexture not found\n" ); } // GL_EXT_compiled_vertex_array qglLockArraysEXT = NULL; qglUnlockArraysEXT = NULL; if ( strstr( glConfig.extensions_string, "GL_EXT_compiled_vertex_array" ) ) { if ( r_ext_compiled_vertex_array->integer ) { Com_Printf ("...using GL_EXT_compiled_vertex_array\n" ); qglLockArraysEXT = ( void ( APIENTRY * )( int, int ) ) SDL_GL_GetProcAddress( "glLockArraysEXT" ); qglUnlockArraysEXT = ( void ( APIENTRY * )( void ) ) SDL_GL_GetProcAddress( "glUnlockArraysEXT" ); if (!qglLockArraysEXT || !qglUnlockArraysEXT) { Com_Error (ERR_FATAL, "bad getprocaddress"); } } else { Com_Printf ("...ignoring GL_EXT_compiled_vertex_array\n" ); } } else { Com_Printf ("...GL_EXT_compiled_vertex_array not found\n" ); } qglPointParameterfEXT = NULL; qglPointParameterfvEXT = NULL; //3d textures -rww qglTexImage3DEXT = NULL; qglTexSubImage3DEXT = NULL; if ( strstr( glConfig.extensions_string, "GL_EXT_point_parameters" ) ) { if ( r_ext_compiled_vertex_array->integer || 1) { Com_Printf ("...using GL_EXT_point_parameters\n" ); qglPointParameterfEXT = ( void ( APIENTRY * )( GLenum, GLfloat) ) SDL_GL_GetProcAddress( "glPointParameterfEXT" ); qglPointParameterfvEXT = ( void ( APIENTRY * )( GLenum, GLfloat *) ) SDL_GL_GetProcAddress( "glPointParameterfvEXT" ); //3d textures -rww qglTexImage3DEXT = (void ( APIENTRY * ) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *) ) SDL_GL_GetProcAddress( "glTexImage3DEXT" ); qglTexSubImage3DEXT = (void ( APIENTRY * ) (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *) ) SDL_GL_GetProcAddress( "glTexSubImage3DEXT" ); if (!qglPointParameterfEXT || !qglPointParameterfvEXT) { Com_Error (ERR_FATAL, "bad getprocaddress"); } } else { Com_Printf ("...ignoring GL_EXT_point_parameters\n" ); } } else { Com_Printf ("...GL_EXT_point_parameters not found\n" ); } bool bNVRegisterCombiners = false; // Register Combiners. if ( strstr( glConfig.extensions_string, "GL_NV_register_combiners" ) ) { // NOTE: This extension requires multitexture support (over 2 units). if ( glConfig.maxActiveTextures >= 2 ) { bNVRegisterCombiners = true; // Register Combiners function pointer address load. - AReis // NOTE: VV guys will _definetly_ not be able to use regcoms. Pixel Shaders are just as good though :-) // NOTE: Also, this is an nVidia specific extension (of course), so fragment shaders would serve the same purpose // if we needed some kind of fragment/pixel manipulation support. qglCombinerParameterfvNV = ( PFNGLCOMBINERPARAMETERFVNV ) SDL_GL_GetProcAddress( "glCombinerParameterfvNV" ); qglCombinerParameterivNV = ( PFNGLCOMBINERPARAMETERIVNV ) SDL_GL_GetProcAddress( "glCombinerParameterivNV" ); qglCombinerParameterfNV = ( PFNGLCOMBINERPARAMETERFNV ) SDL_GL_GetProcAddress( "glCombinerParameterfNV" ); qglCombinerParameteriNV = ( PFNGLCOMBINERPARAMETERINV ) SDL_GL_GetProcAddress( "glCombinerParameteriNV" ); qglCombinerInputNV = ( PFNGLCOMBINERINPUTNV ) SDL_GL_GetProcAddress( "glCombinerInputNV" ); qglCombinerOutputNV = ( PFNGLCOMBINEROUTPUTNV ) SDL_GL_GetProcAddress( "glCombinerOutputNV" ); qglFinalCombinerInputNV = ( PFNGLFINALCOMBINERINPUTNV ) SDL_GL_GetProcAddress( "glFinalCombinerInputNV" ); qglGetCombinerInputParameterfvNV = ( PFNGLGETCOMBINERINPUTPARAMETERFVNV ) SDL_GL_GetProcAddress( "glGetCombinerInputParameterfvNV" ); qglGetCombinerInputParameterivNV = ( PFNGLGETCOMBINERINPUTPARAMETERIVNV ) SDL_GL_GetProcAddress( "glGetCombinerInputParameterivNV" ); qglGetCombinerOutputParameterfvNV = ( PFNGLGETCOMBINEROUTPUTPARAMETERFVNV ) SDL_GL_GetProcAddress( "glGetCombinerOutputParameterfvNV" ); qglGetCombinerOutputParameterivNV = ( PFNGLGETCOMBINEROUTPUTPARAMETERIVNV ) SDL_GL_GetProcAddress( "glGetCombinerOutputParameterivNV" ); qglGetFinalCombinerInputParameterfvNV = ( PFNGLGETFINALCOMBINERINPUTPARAMETERFVNV ) SDL_GL_GetProcAddress( "glGetFinalCombinerInputParameterfvNV" ); qglGetFinalCombinerInputParameterivNV = ( PFNGLGETFINALCOMBINERINPUTPARAMETERIVNV ) SDL_GL_GetProcAddress( "glGetFinalCombinerInputParameterivNV" ); // Validate the functions we need. if ( !qglCombinerParameterfvNV || !qglCombinerParameterivNV || !qglCombinerParameterfNV || !qglCombinerParameteriNV || !qglCombinerInputNV || !qglCombinerOutputNV || !qglFinalCombinerInputNV || !qglGetCombinerInputParameterfvNV || !qglGetCombinerInputParameterivNV || !qglGetCombinerOutputParameterfvNV || !qglGetCombinerOutputParameterivNV || !qglGetFinalCombinerInputParameterfvNV || !qglGetFinalCombinerInputParameterivNV ) { bNVRegisterCombiners = false; qglCombinerParameterfvNV = NULL; qglCombinerParameteriNV = NULL; Com_Printf ("...GL_NV_register_combiners failed\n" ); } } else { bNVRegisterCombiners = false; Com_Printf ("...ignoring GL_NV_register_combiners\n" ); } } else { bNVRegisterCombiners = false; Com_Printf ("...GL_NV_register_combiners not found\n" ); } // NOTE: Vertex and Fragment Programs are very dependant on each other - this is actually a // good thing! So, just check to see which we support (one or the other) and load the shared // function pointers. ARB rocks! // Vertex Programs. bool bARBVertexProgram = false; if ( strstr( glConfig.extensions_string, "GL_ARB_vertex_program" ) ) { bARBVertexProgram = true; } else { bARBVertexProgram = false; Com_Printf ("...GL_ARB_vertex_program not found\n" ); } // Fragment Programs. bool bARBFragmentProgram = false; if ( strstr( glConfig.extensions_string, "GL_ARB_fragment_program" ) ) { bARBFragmentProgram = true; } else { bARBFragmentProgram = false; Com_Printf ("...GL_ARB_fragment_program not found\n" ); } // If we support one or the other, load the shared function pointers. if ( bARBVertexProgram || bARBFragmentProgram ) { qglProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) SDL_GL_GetProcAddress("glProgramStringARB"); qglBindProgramARB = (PFNGLBINDPROGRAMARBPROC) SDL_GL_GetProcAddress("glBindProgramARB"); qglDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) SDL_GL_GetProcAddress("glDeleteProgramsARB"); qglGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) SDL_GL_GetProcAddress("glGenProgramsARB"); qglProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC) SDL_GL_GetProcAddress("glProgramEnvParameter4dARB"); qglProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC) SDL_GL_GetProcAddress("glProgramEnvParameter4dvARB"); qglProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC) SDL_GL_GetProcAddress("glProgramEnvParameter4fARB"); qglProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC) SDL_GL_GetProcAddress("glProgramEnvParameter4fvARB"); qglProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) SDL_GL_GetProcAddress("glProgramLocalParameter4dARB"); qglProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) SDL_GL_GetProcAddress("glProgramLocalParameter4dvARB"); qglProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC) SDL_GL_GetProcAddress("glProgramLocalParameter4fARB"); qglProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) SDL_GL_GetProcAddress("glProgramLocalParameter4fvARB"); qglGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) SDL_GL_GetProcAddress("glGetProgramEnvParameterdvARB"); qglGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) SDL_GL_GetProcAddress("glGetProgramEnvParameterfvARB"); qglGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) SDL_GL_GetProcAddress("glGetProgramLocalParameterdvARB"); qglGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) SDL_GL_GetProcAddress("glGetProgramLocalParameterfvARB"); qglGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) SDL_GL_GetProcAddress("glGetProgramivARB"); qglGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC) SDL_GL_GetProcAddress("glGetProgramStringARB"); qglIsProgramARB = (PFNGLISPROGRAMARBPROC) SDL_GL_GetProcAddress("glIsProgramARB"); // Validate the functions we need. if ( !qglProgramStringARB || !qglBindProgramARB || !qglDeleteProgramsARB || !qglGenProgramsARB || !qglProgramEnvParameter4dARB || !qglProgramEnvParameter4dvARB || !qglProgramEnvParameter4fARB || !qglProgramEnvParameter4fvARB || !qglProgramLocalParameter4dARB || !qglProgramLocalParameter4dvARB || !qglProgramLocalParameter4fARB || !qglProgramLocalParameter4fvARB || !qglGetProgramEnvParameterdvARB || !qglGetProgramEnvParameterfvARB || !qglGetProgramLocalParameterdvARB || !qglGetProgramLocalParameterfvARB || !qglGetProgramivARB || !qglGetProgramStringARB || !qglIsProgramARB ) { bARBVertexProgram = false; bARBFragmentProgram = false; qglGenProgramsARB = NULL; //clear ptrs that get checked qglProgramEnvParameter4fARB = NULL; Com_Printf ("...ignoring GL_ARB_vertex_program\n" ); Com_Printf ("...ignoring GL_ARB_fragment_program\n" ); } } // Figure out which texture rectangle extension to use. bool bTexRectSupported = false; if ( Q_strnicmp( glConfig.vendor_string, "ATI Technologies",16 )==0 && Q_strnicmp( glConfig.version_string, "1.3.3",5 )==0 && glConfig.version_string[5] < '9' ) //1.3.34 and 1.3.37 and 1.3.38 are broken for sure, 1.3.39 is not { g_bTextureRectangleHack = true; } if ( strstr( glConfig.extensions_string, "GL_NV_texture_rectangle" ) || strstr( glConfig.extensions_string, "GL_EXT_texture_rectangle" ) ) { bTexRectSupported = true; } #if 0 // OK, so not so good to put this here, but no one else uses it!!! -AReis typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); PFNWGLGETEXTENSIONSSTRINGARBPROC qwglGetExtensionsStringARB; qwglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) SDL_GL_GetProcAddress("wglGetExtensionsStringARB"); const char *wglExtensions = NULL; #endif bool bHasPixelFormat = false; bool bHasRenderTexture = false; #if 0 // Get the WGL extensions string. if ( qwglGetExtensionsStringARB ) { wglExtensions = qwglGetExtensionsStringARB( glw_state.hDC ); } // This externsion is used to get the wgl extension string. if ( wglExtensions ) { // Pixel Format. if ( strstr( wglExtensions, "WGL_ARB_pixel_format" ) ) { qwglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) SDL_GL_GetProcAddress("wglGetPixelFormatAttribivARB"); qwglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC) SDL_GL_GetProcAddress("wglGetPixelFormatAttribfvARB"); qwglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC) SDL_GL_GetProcAddress("wglChoosePixelFormatARB"); // Validate the functions we need. if ( !qwglGetPixelFormatAttribivARB || !qwglGetPixelFormatAttribfvARB || !qwglChoosePixelFormatARB ) { Com_Printf ("...ignoring WGL_ARB_pixel_format\n" ); } else { bHasPixelFormat = true; } } else { Com_Printf ("...ignoring WGL_ARB_pixel_format\n" ); } // Offscreen pixel-buffer. // NOTE: VV guys can use the equivelant SetRenderTarget() with the correct texture surfaces. bool bWGLARBPbuffer = false; if ( strstr( wglExtensions, "WGL_ARB_pbuffer" ) && bHasPixelFormat ) { bWGLARBPbuffer = true; qwglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC) SDL_GL_GetProcAddress("wglCreatePbufferARB"); qwglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC) SDL_GL_GetProcAddress("wglGetPbufferDCARB"); qwglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC) SDL_GL_GetProcAddress("wglReleasePbufferDCARB"); qwglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC) SDL_GL_GetProcAddress("wglDestroyPbufferARB"); qwglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC) SDL_GL_GetProcAddress("wglQueryPbufferARB"); // Validate the functions we need. if ( !qwglCreatePbufferARB || !qwglGetPbufferDCARB || !qwglReleasePbufferDCARB || !qwglDestroyPbufferARB || !qwglQueryPbufferARB ) { bWGLARBPbuffer = false; Com_Printf ("...WGL_ARB_pbuffer failed\n" ); } } else { bWGLARBPbuffer = false; Com_Printf ("...WGL_ARB_pbuffer not found\n" ); } // Render-Texture (requires pbuffer ext (and it's dependancies of course). if ( strstr( wglExtensions, "WGL_ARB_render_texture" ) && bWGLARBPbuffer ) { qwglBindTexImageARB = (PFNWGLBINDTEXIMAGEARBPROC) SDL_GL_GetProcAddress("wglBindTexImageARB"); qwglReleaseTexImageARB = (PFNWGLRELEASETEXIMAGEARBPROC) SDL_GL_GetProcAddress("wglReleaseTexImageARB"); qwglSetPbufferAttribARB = (PFNWGLSETPBUFFERATTRIBARBPROC) SDL_GL_GetProcAddress("wglSetPbufferAttribARB"); // Validate the functions we need. if ( !qwglCreatePbufferARB || !qwglGetPbufferDCARB || !qwglReleasePbufferDCARB || !qwglDestroyPbufferARB || !qwglQueryPbufferARB ) { Com_Printf ("...ignoring WGL_ARB_render_texture\n" ); } else { bHasRenderTexture = true; } } else { Com_Printf ("...ignoring WGL_ARB_render_texture\n" ); } } #endif // Find out how many general combiners they have. #define GL_MAX_GENERAL_COMBINERS_NV 0x854D GLint iNumGeneralCombiners = 0; qglGetIntegerv( GL_MAX_GENERAL_COMBINERS_NV, &iNumGeneralCombiners ); // Only allow dynamic glows/flares if they have the hardware if ( bTexRectSupported && bARBVertexProgram && bHasRenderTexture && qglActiveTextureARB && glConfig.maxActiveTextures >= 4 && ( ( bNVRegisterCombiners && iNumGeneralCombiners >= 2 ) || bARBFragmentProgram ) ) { g_bDynamicGlowSupported = true; // this would overwrite any achived setting gwg // Cvar_Set( "r_DynamicGlow", "1" ); } else { g_bDynamicGlowSupported = false; Cvar_Set( "r_DynamicGlow","0" ); } }
/* <18d23> ../engine/cvar.c:671 */ void Cmd_CvarList_f(void) { cvar_t *var; int iCvars; int iArgs; const char *partial, *arg1; int ipLen; qboolean bAOnly; qboolean bSOnly; char szTemp[MAX_PATH]; FileHandle_t f; FileHandle_t fp; qboolean bLogging; iCvars = 0; partial = NULL; bAOnly = FALSE; bSOnly = FALSE; f = NULL; fp = NULL; bLogging = FALSE; iArgs = Cmd_Argc(); if (iArgs > 1) { arg1 = Cmd_Argv(1); if (!Q_stricmp(arg1, "?")) { Con_Printf("CvarList : List all cvars\nCvarList [Partial] : List cvars starting with 'Partial'\nCvarList log [Partial] : Logs cvars to file \"cvarlist.txt\" in the gamedir.\n"); return; } if (!Q_stricmp(arg1, "log")) { // Open log int i; for (i = 0; i < 100; i++) { Q_snprintf(szTemp, ARRAYSIZE(szTemp) - 1, "cvarlist%02d.txt", i); szTemp[ARRAYSIZE(szTemp) - 1] = 0; fp = FS_Open(szTemp, "r"); if (!fp) { break; } FS_Close(fp); } if (i >= 100) { Con_Printf("Can't cvarlist! Too many existing cvarlist output files in the gamedir!\n"); return; } f = FS_Open(szTemp, "wt"); if (!f) { Con_Printf("Couldn't open \"%s\" for writing!\n", szTemp); return; } bLogging = TRUE; // Get next argument into partial, if present if (iArgs > 2) { partial = Cmd_Argv(2); ipLen = Q_strlen(partial); } } else if (!Q_stricmp(arg1, "-a")) { bAOnly = TRUE; } else if (!Q_stricmp(arg1, "-s")) { bSOnly = TRUE; } else { partial = arg1; ipLen = Q_strlen(partial); } } // Print cvars Con_Printf("CVar List\n--------------\n"); for (var = cvar_vars; var; var = var->next) { if (bAOnly && !(var->flags & FCVAR_ARCHIVE)) { continue; } if (bSOnly && !(var->flags & FCVAR_SERVER)) { continue; } if (partial && Q_strnicmp(var->name, partial, ipLen)) { continue; } Cmd_CvarListPrintCvar(var, f); iCvars++; } if (partial && *partial) { Con_Printf("--------------\n%3i CVars for [%s]\nCvarList ? for syntax\n", iCvars, partial); } else { Con_Printf("--------------\n%3i Total CVars\nCvarList ? for syntax\n", iCvars); } // Close log if (bLogging) { FS_Close(f); Con_Printf("cvarlist logged to %s\n", szTemp); } }
/* =============== RE_RegisterAnimation =============== */ qhandle_t RE_RegisterAnimation( const char *name ) { qhandle_t hAnim; skelAnimation_t *anim; char *buffer; int bufferLen; bool loaded = false; if ( !name || !name[ 0 ] ) { ri.Printf( PRINT_WARNING, "Empty name passed to RE_RegisterAnimation\n" ); return 0; } //ri.Printf(PRINT_ALL, "RE_RegisterAnimation(%s)\n", name); if ( strlen( name ) >= MAX_QPATH ) { ri.Printf( PRINT_WARNING, "Animation name exceeds MAX_QPATH\n" ); return 0; } // search the currently loaded animations for ( hAnim = 1; hAnim < tr.numAnimations; hAnim++ ) { anim = tr.animations[ hAnim ]; if ( !Q_stricmp( anim->name, name ) ) { if ( anim->type == AT_BAD ) { return 0; } return hAnim; } } // allocate a new model_t if ( ( anim = R_AllocAnimation() ) == nullptr ) { ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: R_AllocAnimation() failed for '%s'\n", name ); return 0; } // only set the name after the animation has been successfully allocated Q_strncpyz( anim->name, name, sizeof( anim->name ) ); // make sure the render thread is stopped R_SyncRenderThread(); // load and parse the .md5anim file bufferLen = ri.FS_ReadFile( name, ( void ** ) &buffer ); if ( !buffer ) { return 0; } if ( !Q_strnicmp( ( const char * ) buffer, "MD5Version", 10 ) ) { loaded = R_LoadMD5Anim( anim, buffer, name ); } else { ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: unknown fileid for '%s'\n", name ); } ri.FS_FreeFile( buffer ); if ( !loaded ) { ri.Printf( PRINT_WARNING, "couldn't load '%s'\n", name ); // we still keep the model_t around, so if the model name is asked for // again, we won't bother scanning the filesystem anim->type = AT_BAD; } return anim->index; }
static const char *R_DetailTextureForName( const char *name ) { const dmaterial_t *table; if( !name || !*name ) return NULL; if( !Q_strnicmp( name, "sky", 3 )) return NULL; // never details for sky // never apply details for liquids if( !Q_strnicmp( name + 1, "!lava", 5 )) return NULL; if( !Q_strnicmp( name + 1, "!slime", 6 )) return NULL; if( !Q_strnicmp( name, "!cur_90", 7 )) return NULL; if( !Q_strnicmp( name, "!cur_0", 6 )) return NULL; if( !Q_strnicmp( name, "!cur_270", 8 )) return NULL; if( !Q_strnicmp( name, "!cur_180", 8 )) return NULL; if( !Q_strnicmp( name, "!cur_up", 7 )) return NULL; if( !Q_strnicmp( name, "!cur_dwn", 8 )) return NULL; if( name[0] == '!' ) return NULL; // never apply details to the special textures if( !Q_strnicmp( name, "origin", 6 )) return NULL; if( !Q_strnicmp( name, "clip", 4 )) return NULL; if( !Q_strnicmp( name, "hint", 4 )) return NULL; if( !Q_strnicmp( name, "skip", 4 )) return NULL; if( !Q_strnicmp( name, "translucent", 11 )) return NULL; if( !Q_strnicmp( name, "3dsky", 5 )) // xash-mod support :-) return NULL; if( !Q_strnicmp( name, "scroll", 6 )) return NULL; if( name[0] == '@' ) return NULL; // last check ... if( !Q_strnicmp( name, "null", 4 )) return NULL; for( table = detail_table; table && table->texname; table++ ) { if( Q_stristr( name, table->texname )) { if(( table->lMin + table->lMax ) > 0 ) return va( table->detail, Com_RandomLong( table->lMin, table->lMax )); return table->detail; } } return NULL; }
void CBreakable::Precache( void ) { const char *pGibName = "WoodChunks"; switch (m_Material) { case matWood: pGibName = "WoodChunks"; break; case matUnbreakableGlass: case matGlass: pGibName = "GlassChunks"; break; case matMetal: pGibName = "MetalChunks"; break; case matRocks: pGibName = "ConcreteChunks"; break; #ifdef HL1_DLL case matComputer: pGibName = "ComputerGibs"; break; case matCeilingTile: pGibName = "CeilingTile"; break; case matFlesh: pGibName = "FleshGibs"; break; case matCinderBlock: pGibName = "CinderBlocks"; break; case matWeb: pGibName = "WebGibs"; break; #else case matCinderBlock: pGibName = "ConcreteChunks"; break; #endif default: Warning("%s (%s) at (%.3f %.3f %.3f) using obsolete or unknown material type.\n", GetClassname(), GetDebugName(), GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z ); pGibName = "WoodChunks"; break; } if ( m_iszGibModel != NULL_STRING ) { pGibName = STRING(m_iszGibModel); #ifdef HL1_DLL PrecacheModel( pGibName ); #endif } m_iszModelName = MAKE_STRING( pGibName ); // Precache the spawn item's data if ( !CommandLine()->CheckParm("-makereslists")) { if ( m_iszSpawnObject != NULL_STRING ) { UTIL_PrecacheOther( STRING( m_iszSpawnObject ) ); } } else { // Actually, precache all possible objects... for ( size_t i = 0; i < ARRAYSIZE(pSpawnObjects) ; ++i ) { if ( !pSpawnObjects[ i ] ) continue; if ( !Q_strnicmp( pSpawnObjects[ i ], "unused", Q_strlen( "unused" ) ) ) continue; UTIL_PrecacheOther( pSpawnObjects[ i ] ); } } PrecacheScriptSound( "Breakable.MatGlass" ); PrecacheScriptSound( "Breakable.MatWood" ); PrecacheScriptSound( "Breakable.MatMetal" ); PrecacheScriptSound( "Breakable.MatFlesh" ); PrecacheScriptSound( "Breakable.MatConcrete" ); PrecacheScriptSound( "Breakable.Computer" ); PrecacheScriptSound( "Breakable.Crate" ); PrecacheScriptSound( "Breakable.Glass" ); PrecacheScriptSound( "Breakable.Metal" ); PrecacheScriptSound( "Breakable.Flesh" ); PrecacheScriptSound( "Breakable.Concrete" ); PrecacheScriptSound( "Breakable.Ceiling" ); }
void CASW_Arena::LevelInitPreEntity() { asw_arena.SetValue( Q_strnicmp( STRING(gpGlobals->mapname), "aiarena", 7 ) ? "0" : "1" ); Init(); }