Пример #1
0
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;
	}
}
Пример #2
0
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 ) );	
}