plugins/sql-admin-manager.sp
changeset 1325 96262acf01eb
child 1326 d24c8f8a2e07
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/plugins/sql-admin-manager.sp	Tue Aug 14 04:46:21 2007 +0000
     1.3 @@ -0,0 +1,533 @@
     1.4 +/**
     1.5 + * sql-admin-manager.sp
     1.6 + * Adds/managers admins and groups in an SQL database.
     1.7 + *
     1.8 + * This file is part of SourceMod, Copyright (C) 2004-2007 AlliedModders LLC
     1.9 + *
    1.10 + * This program is free software; you can redistribute it and/or
    1.11 + * modify it under the terms of the GNU General Public License
    1.12 + * as published by the Free Software Foundation; either version 2
    1.13 + * of the License, or (at your option) any later version.
    1.14 + *
    1.15 + * This program is distributed in the hope that it will be useful,
    1.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.18 + * GNU General Public License for more details.
    1.19 + * 
    1.20 + * You should have received a copy of the GNU General Public License
    1.21 + * along with this program; if not, write to the Free Software
    1.22 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    1.23 + *
    1.24 + * Version: $Id$
    1.25 + */
    1.26 +
    1.27 +/* We like semicolons */
    1.28 +#pragma semicolon 1
    1.29 +
    1.30 +#include <sourcemod>
    1.31 +
    1.32 +public Plugin:myinfo = 
    1.33 +{
    1.34 +	name = "SQL Admin Manager",
    1.35 +	author = "AlliedModders LLC",
    1.36 +	description = "Manages SQL admins",
    1.37 +	version = SOURCEMOD_VERSION,
    1.38 +	url = "http://www.sourcemod.net/"
    1.39 +};
    1.40 +
    1.41 +public OnPluginStart()
    1.42 +{
    1.43 +	LoadTranslations("common.phrases");
    1.44 +	LoadTranslations("sqladmins.phrases");
    1.45 +
    1.46 +	RegAdminCmd("sm_sql_addadmin", Command_AddAdmin, ADMFLAG_ROOT, "Adds an admin to the SQL database");
    1.47 +	RegAdminCmd("sm_sql_deladmin", Command_DelAdmin, ADMFLAG_ROOT, "Removes an admin from the SQL database");
    1.48 +	RegAdminCmd("sm_sql_addgroup", Command_AddGroup, ADMFLAG_ROOT, "Adds a group to the SQL database");
    1.49 +	RegAdminCmd("sm_sql_delgroup", Command_DelGroup, ADMFLAG_ROOT, "Removes a group from the SQL database");
    1.50 +	RegAdminCmd("sm_sql_setadmingroups", Command_SetAdminGroups, ADMFLAG_ROOT, "Sets an admin's groups in the SQL database");
    1.51 +}
    1.52 +
    1.53 +Handle:Connect()
    1.54 +{
    1.55 +	decl String:error[255];
    1.56 +	new Handle:db;
    1.57 +	
    1.58 +	if (SQL_CheckConfig("admins"))
    1.59 +	{
    1.60 +		db = SQL_Connect("admins", true, error, sizeof(error));
    1.61 +	} else {
    1.62 +		db = SQL_Connect("default", true, error, sizeof(error));
    1.63 +	}
    1.64 +	
    1.65 +	if (db == INVALID_HANDLE)
    1.66 +	{
    1.67 +		LogError("Could not connect to database: %s", error);
    1.68 +	}
    1.69 +	
    1.70 +	return db;
    1.71 +}
    1.72 +
    1.73 +public Action:Command_SetAdminGroups(client, args)
    1.74 +{
    1.75 +	if (args < 2)
    1.76 +	{
    1.77 +		ReplyToCommand(client, "[SM] Usage: sm_sql_setadmingroups <authtype> <identity> [group1] ... [group N]");
    1.78 +		return Plugin_Handled;
    1.79 +	}
    1.80 +	
    1.81 +	decl String:authtype[16];
    1.82 +	GetCmdArg(1, authtype, sizeof(authtype));
    1.83 +	
    1.84 +	if (!StrEqual(authtype, "steam")
    1.85 +		&& !StrEqual(authtype, "ip")
    1.86 +		&& !StrEqual(authtype, "name"))
    1.87 +	{
    1.88 +		ReplyToCommand(client, "[SM] %t", "Invalid authtype");
    1.89 +		return Plugin_Handled;
    1.90 +	}
    1.91 +	
    1.92 +	new Handle:db = Connect();
    1.93 +	if (db == INVALID_HANDLE)
    1.94 +	{
    1.95 +		ReplyToCommand(client, "[SM] %t", "Could not connect to database");
    1.96 +		return Plugin_Handled;
    1.97 +	}
    1.98 +	
    1.99 +	decl String:identity[65];
   1.100 +	decl String:safe_identity[140];
   1.101 +	GetCmdArg(2, identity, sizeof(identity));
   1.102 +	SQL_QuoteString(db, identity, safe_identity, sizeof(safe_identity));
   1.103 +	
   1.104 +	decl String:query[255];
   1.105 +	Format(query, 
   1.106 +		sizeof(query),
   1.107 +		"SELECT id FROM sm_admins WHERE authtype = '%s' AND identity = '%s'",
   1.108 +		authtype,
   1.109 +		safe_identity);
   1.110 +		
   1.111 +	new Handle:hQuery;
   1.112 +	if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE)
   1.113 +	{
   1.114 +		return DoError(client, db, query, "Admin lookup query failed");
   1.115 +	}
   1.116 +	
   1.117 +	if (!SQL_FetchRow(hQuery))
   1.118 +	{
   1.119 +		ReplyToCommand(client, "[SM] %t", "SQL Admin not found");
   1.120 +		CloseHandle(hQuery);
   1.121 +		CloseHandle(db);
   1.122 +		return Plugin_Handled;
   1.123 +	}
   1.124 +	
   1.125 +	new id = SQL_FetchInt(hQuery, 0);
   1.126 +	
   1.127 +	CloseHandle(hQuery);
   1.128 +	
   1.129 +	/**
   1.130 +	 * First delete all of the user's existing groups.
   1.131 +	 */
   1.132 +	Format(query, sizeof(query), "DELETE FROM sm_admins_groups WHERE admin_id = %d", id);
   1.133 +	if (!SQL_FastQuery(db, query))
   1.134 +	{
   1.135 +		return DoError(client, db, query, "Admin group deletion query failed");
   1.136 +	}
   1.137 +	
   1.138 +	if (args < 3)
   1.139 +	{
   1.140 +		ReplyToCommand(client, "[SM] %t", "SQL Admin groups reset");
   1.141 +		CloseHandle(db);
   1.142 +		return Plugin_Handled;
   1.143 +	}
   1.144 +	
   1.145 +	decl String:error[256];
   1.146 +	new Handle:hAddQuery, Handle:hFindQuery;
   1.147 +	
   1.148 +	Format(query, sizeof(query), "SELECT id FROM sm_groups WHERE name = ?");
   1.149 +	if ((hFindQuery = SQL_PrepareQuery(db, query, error, sizeof(error))) == INVALID_HANDLE)
   1.150 +	{
   1.151 +		return DoStmtError(client, db, query, error, "Group search prepare failed");
   1.152 +	}
   1.153 +	
   1.154 +	Format(query, 
   1.155 +		sizeof(query), 
   1.156 +		"INSERT INTO sm_admins_groups (admin_id, group_id, inherit_order) VALUES (%d, ?, ?)",
   1.157 +		id);
   1.158 +	if ((hAddQuery = SQL_PrepareQuery(db, query, error, sizeof(error))) == INVALID_HANDLE)
   1.159 +	{
   1.160 +		CloseHandle(hFindQuery);
   1.161 +		return DoStmtError(client, db, query, error, "Add admin group prepare failed");
   1.162 +	}
   1.163 +	
   1.164 +	decl String:name[80];
   1.165 +	new inherit_order = 0;
   1.166 +	for (new i=3; i<=args; i++)
   1.167 +	{
   1.168 +		GetCmdArg(i, name, sizeof(name));
   1.169 +		
   1.170 +		SQL_BindParamString(hFindQuery, 0, name, false);
   1.171 +		if (!SQL_Execute(hFindQuery) || !SQL_FetchRow(hFindQuery))
   1.172 +		{
   1.173 +			ReplyToCommand(client, "[SM] %t", "SQL Group X not found", name);
   1.174 +		} else {
   1.175 +			new gid = SQL_FetchInt(hFindQuery, 0);
   1.176 +			
   1.177 +			SQL_BindParamInt(hAddQuery, 0, gid);
   1.178 +			SQL_BindParamInt(hAddQuery, 1, ++inherit_order);
   1.179 +			if (!SQL_Execute(hAddQuery))
   1.180 +			{
   1.181 +				ReplyToCommand(client, "[SM] %t", "SQL Group X failed to bind", name);
   1.182 +				inherit_order--;
   1.183 +			}
   1.184 +		}
   1.185 +	}
   1.186 +	
   1.187 +	CloseHandle(hAddQuery);
   1.188 +	CloseHandle(hFindQuery);
   1.189 +	CloseHandle(db);
   1.190 +	
   1.191 +	if (inherit_order == 1)
   1.192 +	{
   1.193 +		ReplyToCommand(client, "[SM] %t", "Added group to user");
   1.194 +	} else if (inherit_order > 1) {
   1.195 +		ReplyToCommand(client, "[SM] %t", "Added groups to user", inherit_order);
   1.196 +	}
   1.197 +	
   1.198 +	return Plugin_Handled;
   1.199 +}
   1.200 +
   1.201 +public Action:Command_DelGroup(client, args)
   1.202 +{
   1.203 +	if (args < 1)
   1.204 +	{
   1.205 +		ReplyToCommand(client, "[SM] Usage: sm_sql_addgroup <name>");
   1.206 +		return Plugin_Handled;
   1.207 +	}
   1.208 +
   1.209 +	new Handle:db = Connect();
   1.210 +	if (db == INVALID_HANDLE)
   1.211 +	{
   1.212 +		ReplyToCommand(client, "[SM] %t", "Could not connect to database");
   1.213 +		return Plugin_Handled;
   1.214 +	}
   1.215 +	
   1.216 +	new len;
   1.217 +	decl String:name[80];
   1.218 +	decl String:safe_name[180];
   1.219 +	GetCmdArgString(name, sizeof(name));
   1.220 +	
   1.221 +	/* Strip quotes in case the user tries to use them */
   1.222 +	len = strlen(name);
   1.223 +	if (len > 1 && (name[0] == '"' && name[len-1] == '"'))
   1.224 +	{
   1.225 +		name[--len] = '\0';
   1.226 +		SQL_QuoteString(db, name[1], safe_name, sizeof(safe_name));
   1.227 +	} else {
   1.228 +		SQL_QuoteString(db, name, safe_name, sizeof(safe_name));
   1.229 +	}
   1.230 +	
   1.231 +	decl String:query[256];
   1.232 +	
   1.233 +	/* Delete admin inheritance for this group */
   1.234 +	Format(query, 
   1.235 +		sizeof(query),
   1.236 +		"DELETE FROM sm_admins_groups WHERE group_id IN (SELECT id FROM sm_groups WHERE name = '%s')",
   1.237 +		safe_name);
   1.238 +	if (!SQL_FastQuery(db, query))
   1.239 +	{
   1.240 +		return DoError(client, db, query, "Admin group deletion query failed");
   1.241 +	}
   1.242 +	
   1.243 +	/* Delete group overrides */
   1.244 +	Format(query, 
   1.245 +		sizeof(query),
   1.246 +		"DELETE FROM sm_group_overrides WHERE group_id IN (SELECT id FROM sm_groups WHERE name = '%s')",
   1.247 +		safe_name);
   1.248 +	if (!SQL_FastQuery(db, query))
   1.249 +	{
   1.250 +		return DoError(client, db, query, "Group override deletion query failed");
   1.251 +	}
   1.252 +	
   1.253 +	/* Finally delete the group */
   1.254 +	Format(query, sizeof(query), "DELETE FROM sm_groups WHERE name = '%s'", safe_name);
   1.255 +	if (!SQL_FastQuery(db, query))
   1.256 +	{
   1.257 +		return DoError(client, db, query, "Group deletion query failed");
   1.258 +	}
   1.259 +	
   1.260 +	if (SQL_GetAffectedRows(db))
   1.261 +	{
   1.262 +		ReplyToCommand(client, "[SM] %t", "SQL Group deleted");
   1.263 +	} else {
   1.264 +		ReplyToCommand(client, "[SM] %t", "SQL Group not found");
   1.265 +	}
   1.266 +	
   1.267 +	CloseHandle(db);
   1.268 +	
   1.269 +	return Plugin_Handled;
   1.270 +}
   1.271 +
   1.272 +public Action:Command_AddGroup(client, args)
   1.273 +{
   1.274 +	if (args < 2)
   1.275 +	{
   1.276 +		ReplyToCommand(client, "[SM] Usage: sm_sql_addgroup <name> <flags> [immunity]");
   1.277 +		ReplyToCommand(client, "[SM] %t", "Invalid immunity");
   1.278 +		return Plugin_Handled;
   1.279 +	}
   1.280 +
   1.281 +	new String:immunity[32] = "none";
   1.282 +	if (args >= 3)
   1.283 +	{
   1.284 +		GetCmdArg(3, immunity, sizeof(immunity));
   1.285 +		if (!StrEqual(immunity, "none")
   1.286 +			&& !StrEqual(immunity, "global")
   1.287 +			&& !StrEqual(immunity, "default"))
   1.288 +		{
   1.289 +			ReplyToCommand(client, "[SM] %t", "Invalid immunity");
   1.290 +			return Plugin_Handled;
   1.291 +		}
   1.292 +	}
   1.293 +	
   1.294 +	new Handle:db = Connect();
   1.295 +	if (db == INVALID_HANDLE)
   1.296 +	{
   1.297 +		ReplyToCommand(client, "[SM] %t", "Could not connect to database");
   1.298 +		return Plugin_Handled;
   1.299 +	}
   1.300 +	
   1.301 +	decl String:name[64];
   1.302 +	decl String:safe_name[64];
   1.303 +	GetCmdArg(1, name, sizeof(name));
   1.304 +	SQL_QuoteString(db, name, safe_name, sizeof(safe_name));
   1.305 +	
   1.306 +	new Handle:hQuery;
   1.307 +	decl String:query[256];
   1.308 +	Format(query, sizeof(query), "SELECT id FROM sm_groups WHERE name = '%s'", safe_name);
   1.309 +	if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE)
   1.310 +	{
   1.311 +		return DoError(client, db, query, "Group retrieval query failed");
   1.312 +	}
   1.313 +	
   1.314 +	if (SQL_GetRowCount(hQuery) > 0)
   1.315 +	{
   1.316 +		ReplyToCommand(client, "[SM] %t", "SQL Group already exists");
   1.317 +		CloseHandle(hQuery);
   1.318 +		CloseHandle(db);
   1.319 +		return Plugin_Handled;
   1.320 +	}
   1.321 +	
   1.322 +	CloseHandle(hQuery);
   1.323 +	
   1.324 +	decl String:flags[30];
   1.325 +	decl String:safe_flags[64];
   1.326 +	GetCmdArg(2, flags, sizeof(safe_flags));
   1.327 +	SQL_QuoteString(db, flags, safe_flags, sizeof(safe_flags));
   1.328 +	
   1.329 +	Format(query, 
   1.330 +		sizeof(query),
   1.331 +		"INSERT INTO sm_groups (immunity, flags, name) VALUES ('%s', '%s', '%s')",
   1.332 +		immunity,
   1.333 +		safe_flags,
   1.334 +		safe_name);
   1.335 +	
   1.336 +	if (!SQL_FastQuery(db, query))
   1.337 +	{
   1.338 +		return DoError(client, db, query, "Group insertion query failed");
   1.339 +	}
   1.340 +	
   1.341 +	ReplyToCommand(client, "[SM] %t", "SQL Group added");
   1.342 +	
   1.343 +	CloseHandle(db);
   1.344 +		
   1.345 +	return Plugin_Handled;
   1.346 +}	
   1.347 +
   1.348 +public Action:Command_DelAdmin(client, args)
   1.349 +{
   1.350 +	if (args < 2)
   1.351 +	{
   1.352 +		ReplyToCommand(client, "[SM] Usage: sm_sql_deladmin <authtype> <identity>");
   1.353 +		ReplyToCommand(client, "[SM] %t", "Invalid authtype");
   1.354 +		return Plugin_Handled;
   1.355 +	}
   1.356 +	
   1.357 +	decl String:authtype[16];
   1.358 +	GetCmdArg(1, authtype, sizeof(authtype));
   1.359 +	
   1.360 +	if (!StrEqual(authtype, "steam")
   1.361 +		&& !StrEqual(authtype, "ip")
   1.362 +		&& !StrEqual(authtype, "name"))
   1.363 +	{
   1.364 +		ReplyToCommand(client, "[SM] %t", "Invalid authtype");
   1.365 +		return Plugin_Handled;
   1.366 +	}
   1.367 +	
   1.368 +	new Handle:db = Connect();
   1.369 +	if (db == INVALID_HANDLE)
   1.370 +	{
   1.371 +		ReplyToCommand(client, "[SM] %t", "Could not connect to database");
   1.372 +		return Plugin_Handled;
   1.373 +	}
   1.374 +	
   1.375 +	decl String:identity[65];
   1.376 +	decl String:safe_identity[140];
   1.377 +	GetCmdArg(2, identity, sizeof(identity));
   1.378 +	SQL_QuoteString(db, identity, safe_identity, sizeof(safe_identity));
   1.379 +	
   1.380 +	decl String:query[255];
   1.381 +	Format(query, 
   1.382 +		sizeof(query),
   1.383 +		"SELECT id FROM sm_admins WHERE authtype = '%s' AND identity = '%s'",
   1.384 +		authtype,
   1.385 +		safe_identity);
   1.386 +		
   1.387 +	new Handle:hQuery;
   1.388 +	if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE)
   1.389 +	{
   1.390 +		return DoError(client, db, query, "Admin lookup query failed");
   1.391 +	}
   1.392 +	
   1.393 +	if (!SQL_FetchRow(hQuery))
   1.394 +	{
   1.395 +		ReplyToCommand(client, "[SM] %t", "SQL Admin not found");
   1.396 +		CloseHandle(hQuery);
   1.397 +		CloseHandle(db);
   1.398 +		return Plugin_Handled;
   1.399 +	}
   1.400 +	
   1.401 +	new id = SQL_FetchInt(hQuery, 0);
   1.402 +	
   1.403 +	CloseHandle(hQuery);
   1.404 +	
   1.405 +	/* Delete group bindings */
   1.406 +	Format(query, sizeof(query), "DELETE FROM sm_admins_groups WHERE admin_id = %d", id);
   1.407 +	if (!SQL_FastQuery(db, query))
   1.408 +	{
   1.409 +		return DoError(client, db, query, "Admin group deletion query failed");
   1.410 +	}
   1.411 +	
   1.412 +	Format(query, sizeof(query), "DELETE FROM sm_admins WHERE id = %d", id);
   1.413 +	if (!SQL_FastQuery(db, query))
   1.414 +	{
   1.415 +		return DoError(client, db, query, "Admin deletion query failed");
   1.416 +	}
   1.417 +	
   1.418 +	CloseHandle(db);
   1.419 +	
   1.420 +	ReplyToCommand(client, "[SM] %t", "SQL Admin deleted");
   1.421 +	
   1.422 +	return Plugin_Handled;
   1.423 +}
   1.424 +
   1.425 +public Action:Command_AddAdmin(client, args)
   1.426 +{
   1.427 +	if (args < 4)
   1.428 +	{
   1.429 +		ReplyToCommand(client, "[SM] Usage: sm_sql_addadmin <alias> <authtype> <identity> <flags> [password]");
   1.430 +		ReplyToCommand(client, "[SM] %t", "Invalid authtype");
   1.431 +		return Plugin_Handled;
   1.432 +	}
   1.433 +	
   1.434 +	decl String:authtype[16];
   1.435 +	GetCmdArg(2, authtype, sizeof(authtype));
   1.436 +	
   1.437 +	if (!StrEqual(authtype, "steam")
   1.438 +		&& !StrEqual(authtype, "ip")
   1.439 +		&& !StrEqual(authtype, "name"))
   1.440 +	{
   1.441 +		ReplyToCommand(client, "[SM] %t", "Invalid authtype");
   1.442 +		return Plugin_Handled;
   1.443 +	}
   1.444 +	
   1.445 +	decl String:identity[65];
   1.446 +	decl String:safe_identity[140];
   1.447 +	GetCmdArg(3, identity, sizeof(identity));
   1.448 +	
   1.449 +	decl String:query[256];
   1.450 +	new Handle:hQuery;
   1.451 +	new Handle:db = Connect();
   1.452 +	if (db == INVALID_HANDLE)
   1.453 +	{
   1.454 +		ReplyToCommand(client, "[SM] %t", "Could not connect to database");
   1.455 +		return Plugin_Handled;
   1.456 +	}
   1.457 +	
   1.458 +	SQL_QuoteString(db, identity, safe_identity, sizeof(safe_identity));
   1.459 +	
   1.460 +	Format(query, sizeof(query), "SELECT id FROM sm_admins WHERE authtype = '%s' AND identity = '%s'", authtype, identity);
   1.461 +	if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE)
   1.462 +	{
   1.463 +		return DoError(client, db, query, "Admin retrieval query failed");
   1.464 +	}
   1.465 +	
   1.466 +	if (SQL_GetRowCount(hQuery) > 0)
   1.467 +	{
   1.468 +		ReplyToCommand(client, "[SM] %t", "SQL Admin already exists");
   1.469 +		CloseHandle(hQuery);
   1.470 +		CloseHandle(db);
   1.471 +		return Plugin_Handled;
   1.472 +	}
   1.473 +	
   1.474 +	CloseHandle(hQuery);
   1.475 +	
   1.476 +	decl String:alias[64];
   1.477 +	decl String:safe_alias[140];
   1.478 +	GetCmdArg(1, alias, sizeof(alias));
   1.479 +	SQL_QuoteString(db, alias, safe_alias, sizeof(safe_alias));
   1.480 +	
   1.481 +	decl String:flags[30];
   1.482 +	decl String:safe_flags[64];
   1.483 +	GetCmdArg(4, flags, sizeof(flags));
   1.484 +	SQL_QuoteString(db, flags, safe_flags, sizeof(safe_flags));
   1.485 +	
   1.486 +	decl String:password[32];
   1.487 +	decl String:safe_password[80];
   1.488 +	if (args > 4)
   1.489 +	{
   1.490 +		GetCmdArg(5, password, sizeof(password));
   1.491 +		SQL_QuoteString(db, password, safe_password, sizeof(safe_password));
   1.492 +	} else {
   1.493 +		safe_password[0] = '\0';
   1.494 +	}
   1.495 +	
   1.496 +	new len = 0;
   1.497 +	len += Format(query[len], sizeof(query)-len, "INSERT INTO sm_admins (authtype, identity, password, flags, name) VALUES");
   1.498 +	if (safe_password[0] == '\0')
   1.499 +	{
   1.500 +		len += Format(query[len], sizeof(query)-len, " ('%s', '%s', NULL, '%s', '%s')", authtype, safe_identity, safe_flags, safe_alias);
   1.501 +	} else {
   1.502 +		len += Format(query[len], sizeof(query)-len, " ('%s', '%s', '%s', '%s', '%s')", authtype, safe_identity, safe_password, safe_flags, safe_alias);
   1.503 +	}
   1.504 +	
   1.505 +	if (!SQL_FastQuery(db, query))
   1.506 +	{
   1.507 +		return DoError(client, db, query, "Admin insertion query failed");
   1.508 +	}
   1.509 +	
   1.510 +	ReplyToCommand(client, "[SM] %t", "SQL Admin added");
   1.511 +	
   1.512 +	CloseHandle(db);
   1.513 +		
   1.514 +	return Plugin_Handled;
   1.515 +}
   1.516 +
   1.517 +stock Action:DoError(client, Handle:db, const String:query[], const String:msg[])
   1.518 +{
   1.519 +		decl String:error[255];
   1.520 +		SQL_GetError(db, error, sizeof(error));
   1.521 +		LogError("%s: %s", msg, error);
   1.522 +		LogError("Query dump: %s", query);
   1.523 +		CloseHandle(db);
   1.524 +		ReplyToCommand(client, "[SM] %t", "Failed to query database");
   1.525 +		return Plugin_Handled;
   1.526 +}
   1.527 +
   1.528 +stock Action:DoStmtError(client, Handle:db, const String:query[], const String:error[], const String:msg[])
   1.529 +{
   1.530 +		LogError("%s: %s", msg, error);
   1.531 +		LogError("Query dump: %s", query);
   1.532 +		CloseHandle(db);
   1.533 +		ReplyToCommand(client, "[SM] %t", "Failed to query database");
   1.534 +		return Plugin_Handled;
   1.535 +}
   1.536 +