static void JPLua_LoadPluginDir( qboolean inPK3 ) { static char folderList[16384]; char *folderName = folderList; int i, numFolders; memset( folderList, 0, sizeof(folderList) ); numFolders = trap->FS_GetFileList( pluginDir, inPK3 ? "" : "/", folderList, sizeof(folderList) ); for ( i = 0; i < numFolders; i++ ) { size_t skipLenFolder = inPK3 ? 1 : 0, folderLen = 0; qboolean skip = qfalse; char *s; jplua_plugin_t *plugin = NULL; if ( folderName[0] == '.' ) skip = qtrue; // check for loading the same plugin twice // this can happen when listing plugins outside of PK3s when plugins have written files using the Serialiser while ( JPLua_IteratePluginsTemp( &plugin ) ) { if ( !Q_stricmp( folderName, plugin->name ) ) skip = qtrue; } if ( (s = (char *)Q_strchrs( folderName, "/\\" )) ) { if ( !s[1] ) skip = qtrue; *s = '\0'; skipLenFolder = strlen( ++s ) + 1; } folderLen = strlen( folderName ) + 1; if ( !skip ) { static char fileList[16384]; char *fileName = fileList; int j, numFiles; memset( fileList, 0, sizeof(fileList) ); numFiles = trap->FS_GetFileList( va( "%s%s", pluginDir, folderName ), JPLUA_EXTENSION, fileList, sizeof(fileList) ); for ( j = 0; j < numFiles; j++ ) { size_t skipLenFile = inPK3 ? 1 : 0, fileLen = 0; if ( (s = (char *)Q_strchrs( fileName, "/\\" )) ) { *s = '\0'; skipLenFile = strlen( ++s ) + 1; } fileLen = strlen( fileName ) + 1; if ( !Q_stricmp( fileName, "plugin" JPLUA_EXTENSION ) ) { JPLua_LoadPlugin( folderName, fileName ); break; } fileName += fileLen + skipLenFile; } } folderName += folderLen + skipLenFolder; } }
static void Cmd_CallVote_f( gentity_t *ent ) { int i=0, numArgs=trap->Cmd_Argc(); char arg1[MAX_CVAR_VALUE_STRING] = {0}, arg2[MAX_CVAR_VALUE_STRING] = {0}; voteString_t *vote = NULL; if ( !g_allowVote->integer ) {// not allowed to vote at all trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, ent ), "print \"Not allowed to vote\n\"" ); return; } else if ( level.voteTime || level.voteExecuteTime >= level.time ) {// vote in progress trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, ent ), "print \"A vote is already in progress\n\"" ); return; } else if ( level.gametype != GT_DUEL && ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {// can't vote as a spectator, except in duel trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, ent ), "print \"Not allowed to call a vote as spectator\n\"" ); return; } // make sure it is a valid command to vote on numArgs = trap->Cmd_Argc(); trap->Cmd_Argv( 1, arg1, sizeof( arg1 ) ); if ( numArgs > 1 ) Q_strncpyz( arg2, ConcatArgs( 2 ), sizeof( arg2 ) ); //trap->Cmd_Argv( 2, arg2, sizeof( arg2 ) ); //Raz: callvote exploit, filter \n and \r ==> in both args if ( Q_strchrs( arg1, ";\r\n" ) || Q_strchrs( arg2, ";\r\n" ) ) { trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, ent ), "print \"Invalid vote string.\n\"" ); return; } for ( i=0; i<validVoteStringsSize; i++ ) {// check for invalid votes if ( (g_voteDisable->integer & (1<<i)) ) continue; if ( !Q_stricmp( arg1, validVoteStrings[i].string ) ) break; if ( validVoteStrings[i].aliases ) {// see if they're using an alias, and set arg1 to the actual vote string char tmp[MAX_TOKEN_CHARS] = {0}, *p = NULL, *delim = " "; Q_strncpyz( tmp, validVoteStrings[i].aliases, sizeof( tmp ) ); p = strtok( tmp, delim ); while ( p != NULL ) { if ( !Q_stricmp( arg1, p ) ) { Q_strncpyz( arg1, validVoteStrings[i].string, sizeof( arg1 ) ); goto validVote; } p = strtok( NULL, delim ); } } } if ( i == validVoteStringsSize ) {// invalid vote string, abandon ship char buf[1024] = {0}; int toggle = 0; trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, ent ), "print \"Invalid vote string.\n\"" ); trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, ent ), "print \"Allowed vote strings are: \"" ); for ( i=0; i<validVoteStringsSize; i++ ) { if ( (g_voteDisable->integer & (1<<i)) ) continue; toggle = !toggle; if ( validVoteStrings[i].shortHelp ) { Q_strcat( buf, sizeof( buf ), va( "^%c%s %s ", toggle?'2':'3', validVoteStrings[i].string, validVoteStrings[i].shortHelp ) ); } else { Q_strcat( buf, sizeof( buf ), va( "^%c%s ", toggle?'2':'3', validVoteStrings[i].string ) ); } } //RAZTODO: buffer and send in multiple messages in case of overflow trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, ent ), va( "print \"%s\n\"", buf ) ); return; } validVote: vote = &validVoteStrings[i]; if ( !(vote->validGT & (1<<level.gametype)) ) { trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, ent ), va( "print \"%s is not applicable in this gametype.\n\"", arg1 ) ); return; } if ( numArgs < vote->numArgs ) { trap->SV_GameSendServerCommand( ARRAY_INDEX( g_entities, ent ), va( "print \"%s requires more arguments: %s\n\"", arg1, vote->shortHelp ) ); return; } level.votingGametype = qfalse; level.voteExecuteDelay = vote->voteDelay ? g_voteDelay->integer : 0; if ( level.voteExecuteTime ) {// there is still a vote to be executed, execute it and store the new vote level.voteExecuteTime = 0; if ( level.votePoll ) trap->Cbuf_ExecuteText( EXEC_APPEND, va( "%s\n", level.voteString ) ); } if ( vote->func ) { if ( !vote->func( ent, numArgs, arg1, arg2 ) ) return; } else { Com_sprintf( level.voteString, sizeof( level.voteString ), "%s \"%s\"", arg1, arg2 ); Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString ); Q_strncpyz( level.voteStringClean, level.voteString, sizeof( level.voteStringClean ) ); } Q_strstrip( level.voteStringClean, "\"\n\r", NULL ); trap->SV_GameSendServerCommand( -1, va( "print \"%s^7 called a vote (%s)\n\"", ent->client->pers.netname, level.voteStringClean ) ); // start the voting, the caller automatically votes yes level.voteTime = level.time; level.voteYes = 1; level.voteNo = 0; level.votePoll = qfalse; for ( i=0; i<level.maxclients; i++ ) { level.clients[i].gameFlags &= ~GF_VOTED; level.clients[i].pers.vote = 0; } ent->client->gameFlags |= GF_VOTED; ent->client->pers.vote = 1; trap->SV_SetConfigstring( CS_VOTE_TIME, va( "%i", level.voteTime ) ); trap->SV_SetConfigstring( CS_VOTE_STRING, level.voteDisplayString ); trap->SV_SetConfigstring( CS_VOTE_YES, va( "%i", level.voteYes ) ); trap->SV_SetConfigstring( CS_VOTE_NO, va( "%i", level.voteNo ) ); }