3 * =============================================================================
4 * SourceMod SQL Admin Manager Plugin
5 * Adds/managers admins and groups in an SQL database.
7 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
8 * =============================================================================
10 * This program is free software; you can redistribute it and/or modify it under
11 * the terms of the GNU General Public License, version 3.0, as published by the
12 * Free Software Foundation.
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 * You should have received a copy of the GNU General Public License along with
20 * this program. If not, see <http://www.gnu.org/licenses/>.
22 * As a special exception, AlliedModders LLC gives you permission to link the
23 * code of this program (as well as its derivative works) to "Half-Life 2," the
24 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
25 * by the Valve Corporation. You must obey the GNU General Public License in
26 * all respects for all other code used. Additionally, AlliedModders LLC grants
27 * this exception to all derivative works. AlliedModders LLC defines further
28 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
29 * or <http://www.sourcemod.net/license.php>.
34 /* We like semicolons */
39 public Plugin:myinfo =
41 name = "SQL Admin Manager",
42 author = "AlliedModders LLC",
43 description = "Manages SQL admins",
44 version = SOURCEMOD_VERSION,
45 url = "http://www.sourcemod.net/"
48 public OnPluginStart()
50 LoadTranslations("common.phrases");
51 LoadTranslations("sqladmins.phrases");
53 RegAdminCmd("sm_sql_addadmin", Command_AddAdmin, ADMFLAG_ROOT, "Adds an admin to the SQL database");
54 RegAdminCmd("sm_sql_deladmin", Command_DelAdmin, ADMFLAG_ROOT, "Removes an admin from the SQL database");
55 RegAdminCmd("sm_sql_addgroup", Command_AddGroup, ADMFLAG_ROOT, "Adds a group to the SQL database");
56 RegAdminCmd("sm_sql_delgroup", Command_DelGroup, ADMFLAG_ROOT, "Removes a group from the SQL database");
57 RegAdminCmd("sm_sql_setadmingroups", Command_SetAdminGroups, ADMFLAG_ROOT, "Sets an admin's groups in the SQL database");
62 decl String:error[255];
65 if (SQL_CheckConfig("admins"))
67 db = SQL_Connect("admins", true, error, sizeof(error));
69 db = SQL_Connect("default", true, error, sizeof(error));
72 if (db == INVALID_HANDLE)
74 LogError("Could not connect to database: %s", error);
80 public Action:Command_SetAdminGroups(client, args)
84 ReplyToCommand(client, "[SM] Usage: sm_sql_setadmingroups <authtype> <identity> [group1] ... [group N]");
85 return Plugin_Handled;
88 decl String:authtype[16];
89 GetCmdArg(1, authtype, sizeof(authtype));
91 if (!StrEqual(authtype, "steam")
92 && !StrEqual(authtype, "ip")
93 && !StrEqual(authtype, "name"))
95 ReplyToCommand(client, "[SM] %t", "Invalid authtype");
96 return Plugin_Handled;
99 new Handle:db = Connect();
100 if (db == INVALID_HANDLE)
102 ReplyToCommand(client, "[SM] %t", "Could not connect to database");
103 return Plugin_Handled;
106 decl String:identity[65];
107 decl String:safe_identity[140];
108 GetCmdArg(2, identity, sizeof(identity));
109 SQL_QuoteString(db, identity, safe_identity, sizeof(safe_identity));
111 decl String:query[255];
114 "SELECT id FROM sm_admins WHERE authtype = '%s' AND identity = '%s'",
119 if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE)
121 return DoError(client, db, query, "Admin lookup query failed");
124 if (!SQL_FetchRow(hQuery))
126 ReplyToCommand(client, "[SM] %t", "SQL Admin not found");
129 return Plugin_Handled;
132 new id = SQL_FetchInt(hQuery, 0);
137 * First delete all of the user's existing groups.
139 Format(query, sizeof(query), "DELETE FROM sm_admins_groups WHERE admin_id = %d", id);
140 if (!SQL_FastQuery(db, query))
142 return DoError(client, db, query, "Admin group deletion query failed");
147 ReplyToCommand(client, "[SM] %t", "SQL Admin groups reset");
149 return Plugin_Handled;
152 decl String:error[256];
153 new Handle:hAddQuery, Handle:hFindQuery;
155 Format(query, sizeof(query), "SELECT id FROM sm_groups WHERE name = ?");
156 if ((hFindQuery = SQL_PrepareQuery(db, query, error, sizeof(error))) == INVALID_HANDLE)
158 return DoStmtError(client, db, query, error, "Group search prepare failed");
163 "INSERT INTO sm_admins_groups (admin_id, group_id, inherit_order) VALUES (%d, ?, ?)",
165 if ((hAddQuery = SQL_PrepareQuery(db, query, error, sizeof(error))) == INVALID_HANDLE)
167 CloseHandle(hFindQuery);
168 return DoStmtError(client, db, query, error, "Add admin group prepare failed");
171 decl String:name[80];
172 new inherit_order = 0;
173 for (new i=3; i<=args; i++)
175 GetCmdArg(i, name, sizeof(name));
177 SQL_BindParamString(hFindQuery, 0, name, false);
178 if (!SQL_Execute(hFindQuery) || !SQL_FetchRow(hFindQuery))
180 ReplyToCommand(client, "[SM] %t", "SQL Group X not found", name);
182 new gid = SQL_FetchInt(hFindQuery, 0);
184 SQL_BindParamInt(hAddQuery, 0, gid);
185 SQL_BindParamInt(hAddQuery, 1, ++inherit_order);
186 if (!SQL_Execute(hAddQuery))
188 ReplyToCommand(client, "[SM] %t", "SQL Group X failed to bind", name);
194 CloseHandle(hAddQuery);
195 CloseHandle(hFindQuery);
198 if (inherit_order == 1)
200 ReplyToCommand(client, "[SM] %t", "Added group to user");
201 } else if (inherit_order > 1) {
202 ReplyToCommand(client, "[SM] %t", "Added groups to user", inherit_order);
205 return Plugin_Handled;
208 public Action:Command_DelGroup(client, args)
212 ReplyToCommand(client, "[SM] Usage: sm_sql_delgroup <name>");
213 return Plugin_Handled;
216 new Handle:db = Connect();
217 if (db == INVALID_HANDLE)
219 ReplyToCommand(client, "[SM] %t", "Could not connect to database");
220 return Plugin_Handled;
224 decl String:name[80];
225 decl String:safe_name[180];
226 GetCmdArgString(name, sizeof(name));
228 /* Strip quotes in case the user tries to use them */
230 if (len > 1 && (name[0] == '"' && name[len-1] == '"'))
233 SQL_QuoteString(db, name[1], safe_name, sizeof(safe_name));
235 SQL_QuoteString(db, name, safe_name, sizeof(safe_name));
238 decl String:query[256];
241 Format(query, sizeof(query), "SELECT id FROM sm_groups WHERE name = '%s'", safe_name);
242 if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE)
244 return DoError(client, db, query, "Group retrieval query failed");
247 if (!SQL_FetchRow(hQuery))
249 ReplyToCommand(client, "[SM] %t", "SQL Group not found");
252 return Plugin_Handled;
255 new id = SQL_FetchInt(hQuery, 0);
259 /* Delete admin inheritance for this group */
260 Format(query, sizeof(query), "DELETE FROM sm_admins_groups WHERE group_id = %d", id);
261 if (!SQL_FastQuery(db, query))
263 return DoError(client, db, query, "Admin group deletion query failed");
266 /* Delete group overrides */
267 Format(query, sizeof(query), "DELETE FROM sm_group_overrides WHERE group_id = %d", id);
268 if (!SQL_FastQuery(db, query))
270 return DoError(client, db, query, "Group override deletion query failed");
273 /* Delete immunity */
274 Format(query, sizeof(query), "DELETE FROM sm_group_immunity WHERE group_id = %d OR other_id = %d", id, id);
275 if (!SQL_FastQuery(db, query))
277 return DoError(client, db, query, "Group immunity deletion query failed");
280 /* Finally delete the group */
281 Format(query, sizeof(query), "DELETE FROM sm_groups WHERE id = %d", id);
282 if (!SQL_FastQuery(db, query))
284 return DoError(client, db, query, "Group deletion query failed");
287 ReplyToCommand(client, "[SM] %t", "SQL Group deleted");
291 return Plugin_Handled;
294 public Action:Command_AddGroup(client, args)
298 ReplyToCommand(client, "[SM] Usage: sm_sql_addgroup <name> <flags> [immunity]");
299 ReplyToCommand(client, "[SM] %t", "Invalid immunity");
300 return Plugin_Handled;
303 new String:immunity[32] = "none";
306 GetCmdArg(3, immunity, sizeof(immunity));
307 if (!StrEqual(immunity, "none")
308 && !StrEqual(immunity, "global")
309 && !StrEqual(immunity, "default"))
311 ReplyToCommand(client, "[SM] %t", "Invalid immunity");
312 return Plugin_Handled;
316 new Handle:db = Connect();
317 if (db == INVALID_HANDLE)
319 ReplyToCommand(client, "[SM] %t", "Could not connect to database");
320 return Plugin_Handled;
323 decl String:name[64];
324 decl String:safe_name[64];
325 GetCmdArg(1, name, sizeof(name));
326 SQL_QuoteString(db, name, safe_name, sizeof(safe_name));
329 decl String:query[256];
330 Format(query, sizeof(query), "SELECT id FROM sm_groups WHERE name = '%s'", safe_name);
331 if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE)
333 return DoError(client, db, query, "Group retrieval query failed");
336 if (SQL_GetRowCount(hQuery) > 0)
338 ReplyToCommand(client, "[SM] %t", "SQL Group already exists");
341 return Plugin_Handled;
346 decl String:flags[30];
347 decl String:safe_flags[64];
348 GetCmdArg(2, flags, sizeof(safe_flags));
349 SQL_QuoteString(db, flags, safe_flags, sizeof(safe_flags));
353 "INSERT INTO sm_groups (immunity, flags, name) VALUES ('%s', '%s', '%s')",
358 if (!SQL_FastQuery(db, query))
360 return DoError(client, db, query, "Group insertion query failed");
363 ReplyToCommand(client, "[SM] %t", "SQL Group added");
367 return Plugin_Handled;
370 public Action:Command_DelAdmin(client, args)
374 ReplyToCommand(client, "[SM] Usage: sm_sql_deladmin <authtype> <identity>");
375 ReplyToCommand(client, "[SM] %t", "Invalid authtype");
376 return Plugin_Handled;
379 decl String:authtype[16];
380 GetCmdArg(1, authtype, sizeof(authtype));
382 if (!StrEqual(authtype, "steam")
383 && !StrEqual(authtype, "ip")
384 && !StrEqual(authtype, "name"))
386 ReplyToCommand(client, "[SM] %t", "Invalid authtype");
387 return Plugin_Handled;
390 new Handle:db = Connect();
391 if (db == INVALID_HANDLE)
393 ReplyToCommand(client, "[SM] %t", "Could not connect to database");
394 return Plugin_Handled;
397 decl String:identity[65];
398 decl String:safe_identity[140];
399 GetCmdArg(2, identity, sizeof(identity));
400 SQL_QuoteString(db, identity, safe_identity, sizeof(safe_identity));
402 decl String:query[255];
405 "SELECT id FROM sm_admins WHERE authtype = '%s' AND identity = '%s'",
410 if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE)
412 return DoError(client, db, query, "Admin lookup query failed");
415 if (!SQL_FetchRow(hQuery))
417 ReplyToCommand(client, "[SM] %t", "SQL Admin not found");
420 return Plugin_Handled;
423 new id = SQL_FetchInt(hQuery, 0);
427 /* Delete group bindings */
428 Format(query, sizeof(query), "DELETE FROM sm_admins_groups WHERE admin_id = %d", id);
429 if (!SQL_FastQuery(db, query))
431 return DoError(client, db, query, "Admin group deletion query failed");
434 Format(query, sizeof(query), "DELETE FROM sm_admins WHERE id = %d", id);
435 if (!SQL_FastQuery(db, query))
437 return DoError(client, db, query, "Admin deletion query failed");
442 ReplyToCommand(client, "[SM] %t", "SQL Admin deleted");
444 return Plugin_Handled;
447 public Action:Command_AddAdmin(client, args)
451 ReplyToCommand(client, "[SM] Usage: sm_sql_addadmin <alias> <authtype> <identity> <flags> [password]");
452 ReplyToCommand(client, "[SM] %t", "Invalid authtype");
453 return Plugin_Handled;
456 decl String:authtype[16];
457 GetCmdArg(2, authtype, sizeof(authtype));
459 if (!StrEqual(authtype, "steam")
460 && !StrEqual(authtype, "ip")
461 && !StrEqual(authtype, "name"))
463 ReplyToCommand(client, "[SM] %t", "Invalid authtype");
464 return Plugin_Handled;
467 decl String:identity[65];
468 decl String:safe_identity[140];
469 GetCmdArg(3, identity, sizeof(identity));
471 decl String:query[256];
473 new Handle:db = Connect();
474 if (db == INVALID_HANDLE)
476 ReplyToCommand(client, "[SM] %t", "Could not connect to database");
477 return Plugin_Handled;
480 SQL_QuoteString(db, identity, safe_identity, sizeof(safe_identity));
482 Format(query, sizeof(query), "SELECT id FROM sm_admins WHERE authtype = '%s' AND identity = '%s'", authtype, identity);
483 if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE)
485 return DoError(client, db, query, "Admin retrieval query failed");
488 if (SQL_GetRowCount(hQuery) > 0)
490 ReplyToCommand(client, "[SM] %t", "SQL Admin already exists");
493 return Plugin_Handled;
498 decl String:alias[64];
499 decl String:safe_alias[140];
500 GetCmdArg(1, alias, sizeof(alias));
501 SQL_QuoteString(db, alias, safe_alias, sizeof(safe_alias));
503 decl String:flags[30];
504 decl String:safe_flags[64];
505 GetCmdArg(4, flags, sizeof(flags));
506 SQL_QuoteString(db, flags, safe_flags, sizeof(safe_flags));
508 decl String:password[32];
509 decl String:safe_password[80];
512 GetCmdArg(5, password, sizeof(password));
513 SQL_QuoteString(db, password, safe_password, sizeof(safe_password));
515 safe_password[0] = '\0';
519 len += Format(query[len], sizeof(query)-len, "INSERT INTO sm_admins (authtype, identity, password, flags, name) VALUES");
520 if (safe_password[0] == '\0')
522 len += Format(query[len], sizeof(query)-len, " ('%s', '%s', NULL, '%s', '%s')", authtype, safe_identity, safe_flags, safe_alias);
524 len += Format(query[len], sizeof(query)-len, " ('%s', '%s', '%s', '%s', '%s')", authtype, safe_identity, safe_password, safe_flags, safe_alias);
527 if (!SQL_FastQuery(db, query))
529 return DoError(client, db, query, "Admin insertion query failed");
532 ReplyToCommand(client, "[SM] %t", "SQL Admin added");
536 return Plugin_Handled;
539 stock Action:DoError(client, Handle:db, const String:query[], const String:msg[])
541 decl String:error[255];
542 SQL_GetError(db, error, sizeof(error));
543 LogError("%s: %s", msg, error);
544 LogError("Query dump: %s", query);
546 ReplyToCommand(client, "[SM] %t", "Failed to query database");
547 return Plugin_Handled;
550 stock Action:DoStmtError(client, Handle:db, const String:query[], const String:error[], const String:msg[])
552 LogError("%s: %s", msg, error);
553 LogError("Query dump: %s", query);
555 ReplyToCommand(client, "[SM] %t", "Failed to query database");
556 return Plugin_Handled;