plugins/include/helpers.inc
author Nicholas Hastings <skamonkey@gmail.com>
Thu Apr 14 23:26:39 2011 -0400 (2011-04-14)
changeset 3249 4042a6d0e783
parent 2920 1d5645ab7ae0
permissions -rw-r--r--
Triggering build.
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod (C)2004-2008 AlliedModders LLC.  All rights reserved.
     5  * =============================================================================
     6  *
     7  * This file is part of the SourceMod/SourcePawn SDK.
     8  *
     9  * This program is free software; you can redistribute it and/or modify it under
    10  * the terms of the GNU General Public License, version 3.0, as published by the
    11  * Free Software Foundation.
    12  * 
    13  * This program is distributed in the hope that it will be useful, but WITHOUT
    14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    15  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    16  * details.
    17  *
    18  * You should have received a copy of the GNU General Public License along with
    19  * this program.  If not, see <http://www.gnu.org/licenses/>.
    20  *
    21  * As a special exception, AlliedModders LLC gives you permission to link the
    22  * code of this program (as well as its derivative works) to "Half-Life 2," the
    23  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    24  * by the Valve Corporation.  You must obey the GNU General Public License in
    25  * all respects for all other code used.  Additionally, AlliedModders LLC grants
    26  * this exception to all derivative works.  AlliedModders LLC defines further
    27  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    28  * or <http://www.sourcemod.net/license.php>.
    29  *
    30  * Version: $Id$
    31  */
    32  
    33 #if defined _helpers_included
    34  #endinput
    35 #endif
    36 #define _helpers_included
    37 
    38 /**
    39  * Formats a user's info as log text.  This is usually not needed because
    40  * %L can be used to auto-format client information into a string.
    41  *
    42  * @param client		Client index.
    43  * @param buffer		Buffer for text.
    44  * @param maxlength		Maximum length of text.
    45  */
    46 stock FormatUserLogText(client, String:buffer[], maxlength)
    47 {
    48 	decl String:auth[32];
    49 	decl String:name[40];
    50 	
    51 	new userid = GetClientUserId(client);
    52 	if (!GetClientAuthString(client, auth, sizeof(auth)))
    53 	{
    54 		strcopy(auth, sizeof(auth), "UNKNOWN");
    55 	}
    56 	if (!GetClientName(client, name, sizeof(name)))
    57 	{
    58 		strcopy(name, sizeof(name), "UNKNOWN");
    59 	}
    60 	
    61 	/** Currently, no team stuff ... */
    62 	
    63 	Format(buffer, maxlength, "\"%s<%d><%s><>\"", name, userid, auth);
    64 }
    65 
    66 /**
    67  * Returns plugin handle from plugin filename.
    68  *
    69  * @param filename		Filename of the plugin to search for.
    70  * @return				Handle to plugin if found, INVALID_HANDLE otherwise.
    71  */
    72 stock Handle:FindPluginByFile(const String:filename[])
    73 {
    74 	decl String:buffer[256];
    75 	
    76 	new Handle:iter = GetPluginIterator();
    77 	new Handle:pl;
    78 	
    79 	while (MorePlugins(iter))
    80 	{
    81 		pl = ReadPlugin(iter);
    82 		
    83 		GetPluginFilename(pl, buffer, sizeof(buffer));
    84 		if (strcmp(buffer, filename, false) == 0)
    85 		{
    86 			CloseHandle(iter);
    87 			return pl;
    88 		}
    89 	}
    90 	
    91 	CloseHandle(iter);
    92 	
    93 	return INVALID_HANDLE;
    94 }
    95 
    96 /**
    97  * @deprecated Use FindTarget() or ProcessTargetString().
    98  */
    99 #pragma deprecated Use FindTarget() or ProcessTargetString()
   100 stock SearchForClients(const String:pattern[], clients[], maxClients)
   101 {
   102 	new total = 0;
   103 	
   104 	if (maxClients == 0)
   105 	{
   106 		return 0;
   107 	}
   108 	
   109 	if (pattern[0] == '#')
   110 	{
   111 		new input = StringToInt(pattern[1]);
   112 		if (!input)
   113 		{
   114 			decl String:name[65]
   115 			for (new i=1; i<=MaxClients; i++)
   116 			{
   117 				if (!IsClientInGame(i))
   118 				{
   119 					continue;
   120 				}
   121 				GetClientName(i, name, sizeof(name));
   122 				if (strcmp(name, pattern, false) == 0)
   123 				{
   124 					clients[0] = i;
   125 					return 1;
   126 				}
   127 			}
   128 		} else {
   129 			new client = GetClientOfUserId(input);
   130 			if (client)
   131 			{
   132 				clients[0] = client;
   133 				return 1;
   134 			}
   135 		}
   136 	}
   137 	
   138 	decl String:name[65]
   139 	for (new i=1; i<=MaxClients; i++)
   140 	{
   141 		if (!IsClientInGame(i))
   142 		{
   143 			continue;
   144 		}
   145 		GetClientName(i, name, sizeof(name));
   146 		if (StrContains(name, pattern, false) != -1)
   147 		{
   148 			clients[total++] = i;
   149 			if (total >= maxClients)
   150 			{
   151 				break;
   152 			}
   153 		}
   154 	}
   155 	
   156 	return total;
   157 }
   158 
   159 /**
   160  * Wraps ProcessTargetString() and handles producing error messages for
   161  * bad targets.
   162  *
   163  * @param client	Client who issued command
   164  * @param target	Client's target argument
   165  * @param nobots	Optional. Set to true if bots should NOT be targetted
   166  * @param immunity	Optional. Set to false to ignore target immunity.
   167  * @return			Index of target client, or -1 on error.
   168  */
   169 stock FindTarget(client, const String:target[], bool:nobots = false, bool:immunity = true)
   170 {
   171 	decl String:target_name[MAX_TARGET_LENGTH];
   172 	decl target_list[1], target_count, bool:tn_is_ml;
   173 	
   174 	new flags = COMMAND_FILTER_NO_MULTI;
   175 	if (nobots)
   176 	{
   177 		flags |= COMMAND_FILTER_NO_BOTS;
   178 	}
   179 	if (!immunity)
   180 	{
   181 		flags |= COMMAND_FILTER_NO_IMMUNITY;
   182 	}
   183 	
   184 	if ((target_count = ProcessTargetString(
   185 			target,
   186 			client, 
   187 			target_list, 
   188 			1, 
   189 			flags,
   190 			target_name,
   191 			sizeof(target_name),
   192 			tn_is_ml)) > 0)
   193 	{
   194 		return target_list[0];
   195 	}
   196 	else
   197 	{
   198 		ReplyToTargetError(client, target_count);
   199 		return -1;
   200 	}
   201 }
   202 
   203 /**
   204  * This function is no longer supported.  It has been replaced with ReadMapList(), 
   205  * which uses a more unified caching and configuration mechanism.  This function also 
   206  * has a bug where if the cvar contents changes, the fileTime change won't be recognized.
   207  * 
   208  * Loads a specified array with maps. The maps will be either loaded from mapcyclefile, or if supplied
   209  * a cvar containing a file name. If the file in the cvar is bad, it will use mapcyclefile. The fileTime
   210  * parameter is used to store a timestamp of the file. If specified, the file will only be reloaded if it
   211  * has changed.
   212  *
   213  * @param array		Valid array handle, should be created with CreateArray(33) or larger. 
   214  * @param fileTime	Variable containing the "last changed" time of the file. Used to avoid needless reloading.
   215  * @param fileCvar	CVAR set to the file to be loaded. Optional.
   216  * @return			Number of maps loaded or 0 if in error.
   217  */
   218 #pragma deprecated Use ReadMapList() instead. 
   219  stock LoadMaps(Handle:array, &fileTime = 0, Handle:fileCvar = INVALID_HANDLE)
   220  { 
   221  	decl String:mapPath[256], String:mapFile[64];
   222  	new bool:fileFound = false;
   223  	
   224  	if (fileCvar != INVALID_HANDLE)
   225  	{
   226  		GetConVarString(fileCvar, mapFile, 64);
   227 	 	BuildPath(Path_SM, mapPath, sizeof(mapPath), mapFile);
   228  		fileFound = FileExists(mapPath);
   229  	}
   230  
   231  	if (!fileFound)
   232  	{
   233  		new Handle:mapCycleFile = FindConVar("mapcyclefile");
   234  		GetConVarString(mapCycleFile, mapPath, sizeof(mapPath));
   235  		fileFound = FileExists(mapPath);
   236  	}
   237  	
   238  	if (!fileFound)
   239  	{
   240  		LogError("Failed to find a file to load maps from. No maps loaded.");
   241  		ClearArray(array);
   242  		
   243  		return 0;		
   244  	}
   245  
   246  	// If the file hasn't changed, there's no reason to reload
   247  	// all of the maps.
   248  	new newTime =  GetFileTime(mapPath, FileTime_LastChange);
   249  	if (fileTime == newTime)
   250  	{
   251  		return GetArraySize(array);
   252  	}
   253  	
   254  	fileTime = newTime;
   255  	
   256  	ClearArray(array);
   257  
   258  	new Handle:file = OpenFile(mapPath, "rt");
   259  	if (file == INVALID_HANDLE)
   260  	{
   261  		LogError("Could not open file: %s", mapPath);
   262  		
   263  		return 0;
   264  	}
   265  
   266 	LogMessage("Loading maps from file: %s", mapPath);
   267 	
   268  	decl String:buffer[64], len;
   269  	while (!IsEndOfFile(file) && ReadFileLine(file, buffer, sizeof(buffer)))
   270  	{
   271  		TrimString(buffer);
   272  
   273  		if ((len = StrContains(buffer, ".bsp", false)) != -1)
   274  		{
   275  			buffer[len] = '\0';
   276  		}
   277  
   278  		if (buffer[0] == '\0' || !IsValidConVarChar(buffer[0]) || !IsMapValid(buffer))
   279  		{
   280  			continue;
   281  		}
   282  		
   283  		if (FindStringInArray(array, buffer) != -1)
   284  		{
   285  			continue;
   286  		}
   287  
   288  		PushArrayString(array, buffer);
   289  	}
   290  
   291  	CloseHandle(file);
   292  	return GetArraySize(array);
   293 }