3 * =============================================================================
4 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
5 * =============================================================================
7 * This file is part of the SourceMod/SourcePawn SDK.
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.
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
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/>.
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>.
33 #if defined _helpers_included
36 #define _helpers_included
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.
42 * @param client Client index.
43 * @param buffer Buffer for text.
44 * @param maxlength Maximum length of text.
46 stock FormatUserLogText(client, String:buffer[], maxlength)
51 new userid = GetClientUserId(client);
52 if (!GetClientAuthString(client, auth, sizeof(auth)))
54 strcopy(auth, sizeof(auth), "UNKNOWN");
56 if (!GetClientName(client, name, sizeof(name)))
58 strcopy(name, sizeof(name), "UNKNOWN");
61 /** Currently, no team stuff ... */
63 Format(buffer, maxlength, "\"%s<%d><%s><>\"", name, userid, auth);
67 * Returns plugin handle from plugin filename.
69 * @param filename Filename of the plugin to search for.
70 * @return Handle to plugin if found, INVALID_HANDLE otherwise.
72 stock Handle:FindPluginByFile(const String:filename[])
74 decl String:buffer[256];
76 new Handle:iter = GetPluginIterator();
79 while (MorePlugins(iter))
81 pl = ReadPlugin(iter);
83 GetPluginFilename(pl, buffer, sizeof(buffer));
84 if (strcmp(buffer, filename, false) == 0)
93 return INVALID_HANDLE;
97 * Searches for clients that match an input string.
100 * 1) #<userid> or #<exact name>
101 * 2) <partial or full name>
103 * @param pattern Pattern to search for.
104 * @param clients Array to store matching clients in.
105 * @param maxClients Maximum clients in the array.
106 * @return Number of clients found.
108 stock SearchForClients(const String:pattern[], clients[], maxClients)
110 new maxclients = GetMaxClients();
118 if (pattern[0] == '#')
120 new input = StringToInt(pattern[1]);
124 for (new i=1; i<=maxclients; i++)
126 if (!IsClientInGame(i))
130 GetClientName(i, name, sizeof(name));
131 if (strcmp(name, pattern, false) == 0)
138 new client = GetClientOfUserId(input);
148 for (new i=1; i<=maxclients; i++)
150 if (!IsClientInGame(i))
154 GetClientName(i, name, sizeof(name));
155 if (StrContains(name, pattern, false) != -1)
157 clients[total++] = i;
158 if (total >= maxClients)
169 * Wraps SearchForClients and handles producing error messages for
172 * @param client Client who issued command
173 * @param target Client's target argument
174 * @param nobots Optional. Set to true if bots should NOT be targetted
175 * @param immunity Optional. Set to false to ignore target immunity.
176 * @return Index of target client, or -1 on error.
178 stock FindTarget(client, const String:target[], bool:nobots = false, bool:immunity = true)
181 new numClients = SearchForClients(target, clients, 2);
185 ReplyToCommand(client, "[SM] %t", "No matching client");
188 else if (numClients > 1)
190 ReplyToCommand(client, "[SM] %t", "More than one client matches", target);
193 else if (immunity && !CanUserTarget(client, clients[0]))
195 ReplyToCommand(client, "[SM] %t", "Unable to target");
198 else if (nobots && IsFakeClient(clients[0]))
200 ReplyToCommand(client, "[SM] %t", "Cannot target bot");
209 * Loads a specified array with maps. The maps will be either loaded from mapcyclefile, or if supplied
210 * a cvar containing a file name. If the file in the cvar is bad, it will use mapcyclefile. The fileTime
211 * parameter is used to store a timestamp of the file. If specified, the file will only be reloaded if it
214 * @param array Valid array handle, should be created with CreateArray(33) or larger.
215 * @param fileTime Variable containing the "last changed" time of the file. Used to avoid needless reloading.
216 * @param fileCvar CVAR set to the file to be loaded. Optional.
217 * @return Number of maps loaded or 0 if in error.
219 stock LoadMaps(Handle:array, &fileTime = 0, Handle:fileCvar = INVALID_HANDLE)
221 decl String:mapPath[256], String:mapFile[64];
222 new bool:fileFound = false;
224 if (fileCvar != INVALID_HANDLE)
226 GetConVarString(fileCvar, mapFile, 64);
227 BuildPath(Path_SM, mapPath, sizeof(mapPath), mapFile);
228 fileFound = FileExists(mapPath);
233 new Handle:mapCycleFile = FindConVar("mapcyclefile");
234 GetConVarString(mapCycleFile, mapPath, sizeof(mapPath));
235 fileFound = FileExists(mapPath);
240 LogError("Failed to find a file to load maps from. No maps loaded.");
246 // If the file hasn't changed, there's no reason to reload
248 new newTime = GetFileTime(mapPath, FileTime_LastChange);
249 if (fileTime == newTime)
251 return GetArraySize(array);
258 new Handle:file = OpenFile(mapPath, "rt");
259 if (file == INVALID_HANDLE)
261 LogError("Could not open file: %s", mapPath);
266 LogMessage("Loading maps from file: %s", mapPath);
268 decl String:buffer[64], len;
269 while (!IsEndOfFile(file) && ReadFileLine(file, buffer, sizeof(buffer)))
273 if ((len = StrContains(buffer, ".bsp", false)) != -1)
278 if (buffer[0] == '\0' || !IsValidConVarChar(buffer[0]) || !IsMapValid(buffer))
283 PushArrayString(array, buffer);
287 return GetArraySize(array);