diff --git a/configs/sql-init-scripts/admins-mysql.sql b/configs/sql-init-scripts/admins-mysql.sql new file mode 100644 index 00000000..46c4fadf --- /dev/null +++ b/configs/sql-init-scripts/admins-mysql.sql @@ -0,0 +1,41 @@ + +CREATE TABLE sm_admins ( + id int(10) unsigned NOT NULL auto_increment, + authtype enum('steam','name','ip') NOT NULL, + identity varchar(65) NOT NULL, + password varchar(65), + flags varchar(30) NOT NULL, + name varchar(65) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE sm_groups ( + id int(10) unsigned NOT NULL auto_increment, + immunity enum('none','all','default') NOT NULL, + flags varchar(30) NOT NULL, + name varchar(120) NOT NULL, + groups_immune varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE sm_group_overrides ( + group_id int(10) unsigned NOT NULL, + type enum('command','group') NOT NULL, + name varchar(32) NOT NULL, + access enum('allow','deny') NOT NULL, + PRIMARY KEY (group_id, type, name) +); + +CREATE TABLE sm_overrides ( + type enum('command','group') NOT NULL, + name varchar(32) NOT NULL, + flags varchar(30) NOT NULL, + PRIMARY KEY (type,name) +); + +CREATE TABLE sm_admins_groups ( + admin_id int(10) unsigned NOT NULL, + group_id int(10) unsigned NOT NULL, + inherit_order int(10) NOT NULL, + PRIMARY KEY (admin_id, group_id) +); diff --git a/configs/sql-init-scripts/admins-sqlite.sq3 b/configs/sql-init-scripts/admins-sqlite.sq3 new file mode 100644 index 00000000..f10a22fe Binary files /dev/null and b/configs/sql-init-scripts/admins-sqlite.sq3 differ diff --git a/configs/sql-init-scripts/admins-sqlite.sql b/configs/sql-init-scripts/admins-sqlite.sql new file mode 100644 index 00000000..f9f75f9c --- /dev/null +++ b/configs/sql-init-scripts/admins-sqlite.sql @@ -0,0 +1,41 @@ + +CREATE TABLE sm_admins ( + id int(10) NOT NULL, + authtype varchar(16) NOT NULL, + identity varchar(65) NOT NULL, + password varchar(65), + flags varchar(30) NOT NULL, + name varchar(65) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE sm_groups ( + id int(10) NOT NULL, + immunity varchar(16) NOT NULL, + flags varchar(30) NOT NULL, + name varchar(120) NOT NULL, + groups_immune varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE sm_group_overrides ( + group_id int(10) NOT NULL, + type varchar(16) NOT NULL, + name varchar(32) NOT NULL, + access varchar(16) NOT NULL, + PRIMARY KEY (group_id, type, name) +); + +CREATE TABLE sm_overrides ( + type varchar(16) NOT NULL, + name varchar(32) NOT NULL, + flags varchar(30) NOT NULL, + PRIMARY KEY (type,name) +); + +CREATE TABLE sm_admins_groups ( + admin_id int(10) NOT NULL, + group_id int(10) NOT NULL, + inherit_order int(10) NOT NULL, + PRIMARY KEY (admin_id, group_id) +); diff --git a/plugins/admin-sql-prefetch.sp b/plugins/admin-sql-prefetch.sp new file mode 100644 index 00000000..179390d6 --- /dev/null +++ b/plugins/admin-sql-prefetch.sp @@ -0,0 +1,436 @@ +/** + * admin-sql-prefetch.sp + * Prefetches admins from an SQL database without threading. + * This file is part of SourceMod, Copyright (C) 2004-2007 AlliedModders LLC + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Version: $Id$ + */ + +/* We like semicolons */ +#pragma semicolon 1 + +#include + +public Plugin:myinfo = +{ + name = "SQL Admin Prefetcher", + author = "AlliedModders LLC", + description = "Reads all admins from SQL", + version = SOURCEMOD_VERSION, + url = "http://www.sourcemod.net/" +}; + +public OnRebuildAdminCache(AdminCachePart:part) +{ + /* First try to get a database connection */ + decl String:error[255]; + new Handle:db = SQL_Connect("default", true, error, sizeof(error)); + if (db == INVALID_HANDLE) + { + LogError("Could not connect to database \"default\": %s", error); + return; + } + + if (part == AdminCache_Overrides) + { + FetchOverrides(db); + } else if (part == AdminCache_Groups) { + FetchGroups(db); + } else if (part == AdminCache_Admins) { + FetchUsers(db); + } + + CloseHandle(db); +} + +FetchUserGroups(Handle:hQuery, AdminId:adm, id) +{ + SQL_BindParamInt(hQuery, 0, id); + if (!SQL_Execute(hQuery)) + { + decl String:error[255]; + SQL_GetError(hQuery, error, sizeof(error)); + LogError("FetchUserGroups() statement execute failed: %s", error); + return; + } + + decl String:name[80]; + new GroupId:gid; + while (SQL_FetchRow(hQuery)) + { + SQL_FetchString(hQuery, 0, name, sizeof(name)); + + if ((gid = FindAdmGroup(name)) == INVALID_GROUP_ID) + { + /* Group wasn't found, don't bother with it. */ + continue; + } + + #if defined _DEBUG + PrintToServer("Found admin group (%d, %d, %d)", id, gid, adm); + #endif + + AdminInheritGroup(adm, gid); + } +} + +FetchUsers(Handle:db) +{ + decl String:query[255], String:error[255]; + new Handle:hQuery, Handle:hGroupQuery; + + Format(query, sizeof(query), "SELECT id, authtype, identity, passwd, flags, name FROM sm_admins"); + if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE) + { + SQL_GetError(db, error, sizeof(error)); + LogError("FetchUsers() query failed: %s", query); + LogError("Query error: %s", error); + return; + } + + /* If this fails it's non-fatal */ + Format(query, + sizeof(query), + "SELECT g.name FROM sm_admins_groups ag JOIN sm_groups g ON ag.group_id = g.id WHERE ag.admin_id = ? ORDER BY inherit_order ASC"); + if ((hGroupQuery = SQL_PrepareQuery(db, query, error, sizeof(error))) == INVALID_HANDLE) + { + LogError("FetchUsers() group query preparation failed: %s", query); + LogError("Query error: %s", error); + } + + decl String:authtype[16]; + decl String:identity[80]; + decl String:password[80]; + decl String:flags[32]; + decl String:name[80]; + new AdminId:adm, id; + + while (SQL_FetchRow(hQuery)) + { + id = SQL_FetchInt(hQuery, 0); + SQL_FetchString(hQuery, 1, authtype, sizeof(authtype)); + SQL_FetchString(hQuery, 2, identity, sizeof(identity)); + SQL_FetchString(hQuery, 3, password, sizeof(password)); + SQL_FetchString(hQuery, 4, flags, sizeof(flags)); + SQL_FetchString(hQuery, 5, name, sizeof(name)); + + /* Use a pre-existing admin if we can */ + if ((adm = FindAdminByIdentity(authtype, identity)) == INVALID_ADMIN_ID) + { + adm = CreateAdmin(name); + if (!BindAdminIdentity(adm, authtype, identity)) + { + LogError("Could not bind prefetched SQL admin (authtype \"%s\") (identity \"%s\")", authtype, identity); + continue; + } + } + + #if defined _DEBUG + PrintToServer("Found SQL admin (%d,%s,%s,%s,%s,%s):%d", id, authtype, identity, password, flags, name, adm); + #endif + + /* See if this admin wants a password */ + if (password[0] != '\0') + { + SetAdminPassword(adm, password); + } + + /* Apply each flag */ + new len = strlen(flags); + new AdminFlag:flag; + for (new i=0; i 0)) + { + for (new j=0; j