2008-03-30 09:00:22 +02:00
/ * *
* vim : set ts = 4 :
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* SourceMod SQL Admins Plugin ( Prefetch )
* Prefetches admins from an SQL database without threading .
*
* SourceMod ( C ) 2004 - 2008 AlliedModders LLC . All rights reserved .
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*
* This program is free software ; you can redistribute it and / or modify it under
* the terms of the GNU General Public License , version 3.0 , as published by the
* Free Software Foundation .
*
* 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 , see < http : //www.gnu.org/licenses/>.
*
* As a special exception , AlliedModders LLC gives you permission to link the
* code of this program ( as well as its derivative works ) to " Half-Life 2, " the
* " Source Engine, " the " SourcePawn JIT, " and any Game MODs that run on software
* by the Valve Corporation . You must obey the GNU General Public License in
* all respects for all other code used . Additionally , AlliedModders LLC grants
* this exception to all derivative works . AlliedModders LLC defines further
* exceptions , found in LICENSE . txt ( as of this writing , version JULY - 31 - 2007 ) ,
* or < http : //www.sourcemod.net/license.php>.
*
* Version : $ Id $
* /
/* We like semicolons */
# pragma semicolon 1
# include <sourcemod>
2016-04-27 15:34:22 +02:00
# pragma newdecls required
2015-02-17 18:13:40 +01:00
public Plugin myinfo =
2008-03-30 09:00:22 +02:00
{
name = " SQL Admins (Prefetch) " ,
author = " AlliedModders LLC " ,
description = " Reads all admins from SQL " ,
version = SOURCEMOD_VERSION ,
url = " http://www.sourcemod.net/ "
} ;
2015-02-17 18:13:40 +01:00
public void OnRebuildAdminCache ( AdminCachePart part )
2008-03-30 09:00:22 +02:00
{
/* First try to get a database connection */
2014-12-14 01:35:12 +01:00
char error [ 255 ] ;
Database db ;
2008-03-30 09:00:22 +02:00
if ( SQL_CheckConfig ( " admins " ) )
{
db = SQL_Connect ( " admins " , true , error , sizeof ( error ) ) ;
} else {
db = SQL_Connect ( " default " , true , error , sizeof ( error ) ) ;
}
2014-11-16 01:30:45 +01:00
if ( db = = null )
2008-03-30 09:00:22 +02:00
{
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 ) ;
}
2014-11-16 01:30:45 +01:00
delete db ;
2008-03-30 09:00:22 +02:00
}
2014-12-14 01:35:12 +01:00
void FetchUsers ( Database db )
2008-03-30 09:00:22 +02:00
{
2014-12-14 01:35:12 +01:00
char query [ 255 ] , error [ 255 ] ;
DBResultSet rs ;
2009-03-01 22:59:12 +01:00
2008-03-30 09:00:22 +02:00
Format ( query , sizeof ( query ) , " SELECT id, authtype, identity, password, flags, name, immunity FROM sm_admins " ) ;
2014-12-14 01:35:12 +01:00
if ( ( rs = SQL_Query ( db , query ) ) = = null )
2008-03-30 09:00:22 +02:00
{
SQL_GetError ( db , error , sizeof ( error ) ) ;
LogError ( " FetchUsers() query failed: %s " , query ) ;
LogError ( " Query error: %s " , error ) ;
return ;
}
2009-03-01 22:59:12 +01:00
2014-12-14 01:35:12 +01:00
char authtype [ 16 ] ;
char identity [ 80 ] ;
char password [ 80 ] ;
char flags [ 32 ] ;
char name [ 80 ] ;
int immunity ;
AdminId adm ;
2015-02-17 18:13:40 +01:00
GroupId grp ;
2014-12-14 01:35:12 +01:00
int id ;
2009-03-01 22:59:12 +01:00
/ * Keep track of a mapping from admin DB IDs to internal AdminIds to
* enable group lookups en masse * /
2014-12-14 01:35:12 +01:00
StringMap htAdmins = new StringMap ( ) ;
char key [ 16 ] ;
2008-03-30 09:00:22 +02:00
2014-12-14 01:35:12 +01:00
while ( rs . FetchRow ( ) )
2008-03-30 09:00:22 +02:00
{
2014-12-14 01:35:12 +01:00
id = rs . FetchInt ( 0 ) ;
2009-03-01 22:59:12 +01:00
IntToString ( id , key , sizeof ( key ) ) ;
2014-12-14 01:35:12 +01:00
rs . FetchString ( 1 , authtype , sizeof ( authtype ) ) ;
rs . FetchString ( 2 , identity , sizeof ( identity ) ) ;
rs . FetchString ( 3 , password , sizeof ( password ) ) ;
rs . FetchString ( 4 , flags , sizeof ( flags ) ) ;
rs . FetchString ( 5 , name , sizeof ( name ) ) ;
immunity = rs . FetchInt ( 6 ) ;
2008-03-30 09:00:22 +02:00
/* Use a pre-existing admin if we can */
if ( ( adm = FindAdminByIdentity ( authtype , identity ) ) = = INVALID_ADMIN_ID )
{
adm = CreateAdmin ( name ) ;
2015-02-17 18:13:40 +01:00
if ( ! adm . BindIdentity ( authtype , identity ) )
2008-03-30 09:00:22 +02:00
{
LogError ( " Could not bind prefetched SQL admin (authtype \" %s \" ) (identity \" %s \" ) " , authtype , identity ) ;
continue ;
}
}
2009-03-01 22:59:12 +01:00
2014-12-14 01:35:12 +01:00
htAdmins . SetValue ( key , adm ) ;
2008-03-30 09:00:22 +02:00
2014-12-14 01:35:12 +01:00
# if defined _DEBUG
2008-03-30 09:00:22 +02:00
PrintToServer ( " Found SQL admin (%d,%s,%s,%s,%s,%s,%d):%d " , id , authtype , identity , password , flags , name , immunity , adm ) ;
2014-12-14 01:35:12 +01:00
# endif
2008-03-30 09:00:22 +02:00
/* See if this admin wants a password */
if ( password [ 0 ] ! = '\0' )
{
2015-02-17 18:13:40 +01:00
adm . SetPassword ( password ) ;
2008-03-30 09:00:22 +02:00
}
/* Apply each flag */
2014-12-14 01:35:12 +01:00
int len = strlen ( flags ) ;
AdminFlag flag ;
2015-02-17 18:13:40 +01:00
for ( int i = 0 ; i < len ; i + + )
2008-03-30 09:00:22 +02:00
{
if ( ! FindFlagByChar ( flags [ i ] , flag ) )
{
continue ;
}
2015-02-17 18:13:40 +01:00
adm . SetFlag ( flag , true ) ;
2008-03-30 09:00:22 +02:00
}
2015-02-17 18:13:40 +01:00
adm . ImmunityLevel = immunity ;
2009-03-01 22:59:12 +01:00
}
2014-12-14 01:35:12 +01:00
delete rs ;
2009-03-01 22:59:12 +01:00
Format ( query , sizeof ( query ) , " SELECT ag.admin_id AS id, g.name FROM sm_admins_groups ag JOIN sm_groups g ON ag.group_id = g.id ORDER BY id, inherit_order ASC " ) ;
2014-12-14 01:35:12 +01:00
if ( ( rs = SQL_Query ( db , query ) ) = = null )
2009-03-01 22:59:12 +01:00
{
SQL_GetError ( db , error , sizeof ( error ) ) ;
LogError ( " FetchUsers() query failed: %s " , query ) ;
LogError ( " Query error: %s " , error ) ;
return ;
}
2014-12-14 01:35:12 +01:00
char group [ 80 ] ;
while ( rs . FetchRow ( ) )
2009-03-01 22:59:12 +01:00
{
2014-12-14 01:35:12 +01:00
IntToString ( rs . FetchInt ( 0 ) , key , sizeof ( key ) ) ;
rs . FetchString ( 1 , group , sizeof ( group ) ) ;
2009-03-01 22:59:12 +01:00
2014-12-14 01:35:12 +01:00
if ( htAdmins . GetValue ( key , adm ) )
2008-03-30 09:00:22 +02:00
{
2015-02-17 18:13:40 +01:00
if ( ( grp = FindAdmGroup ( group ) ) = = INVALID_GROUP_ID )
2009-03-01 22:59:12 +01:00
{
/* Group wasn't found, don't bother with it. */
continue ;
}
2015-02-17 18:13:40 +01:00
adm . InheritGroup ( grp ) ;
2008-03-30 09:00:22 +02:00
}
}
2014-12-14 01:35:12 +01:00
delete rs ;
2014-11-16 01:30:45 +01:00
delete htAdmins ;
2008-03-30 09:00:22 +02:00
}
2015-02-17 18:13:40 +01:00
void FetchGroups ( Database db )
2008-03-30 09:00:22 +02:00
{
2014-12-14 01:35:12 +01:00
char query [ 255 ] ;
DBResultSet rs ;
2008-03-30 09:00:22 +02:00
Format ( query , sizeof ( query ) , " SELECT flags, name, immunity_level FROM sm_groups " ) ;
2014-12-14 01:35:12 +01:00
if ( ( rs = SQL_Query ( db , query ) ) = = null )
2008-03-30 09:00:22 +02:00
{
2014-12-14 01:35:12 +01:00
char error [ 255 ] ;
2008-03-30 09:00:22 +02:00
SQL_GetError ( db , error , sizeof ( error ) ) ;
LogError ( " FetchGroups() query failed: %s " , query ) ;
LogError ( " Query error: %s " , error ) ;
return ;
}
/* Now start fetching groups */
2014-12-14 01:35:12 +01:00
char flags [ 32 ] ;
char name [ 128 ] ;
int immunity ;
while ( rs . FetchRow ( ) )
2008-03-30 09:00:22 +02:00
{
2014-12-14 01:35:12 +01:00
rs . FetchString ( 0 , flags , sizeof ( flags ) ) ;
rs . FetchString ( 1 , name , sizeof ( name ) ) ;
immunity = rs . FetchInt ( 2 ) ;
2008-03-30 09:00:22 +02:00
# if defined _DEBUG
PrintToServer ( " Adding group (%d, %s, %s) " , immunity , flags , name ) ;
# endif
/* Find or create the group */
2015-02-17 18:13:40 +01:00
GroupId grp ;
if ( ( grp = FindAdmGroup ( name ) ) = = INVALID_GROUP_ID )
2008-03-30 09:00:22 +02:00
{
2015-02-17 18:13:40 +01:00
grp = CreateAdmGroup ( name ) ;
2008-03-30 09:00:22 +02:00
}
/* Add flags from the database to the group */
2014-12-14 01:35:12 +01:00
int num_flag_chars = strlen ( flags ) ;
2015-02-17 18:13:40 +01:00
for ( int i = 0 ; i < num_flag_chars ; i + + )
2008-03-30 09:00:22 +02:00
{
2015-02-17 18:13:40 +01:00
AdminFlag flag ;
2008-03-30 09:00:22 +02:00
if ( ! FindFlagByChar ( flags [ i ] , flag ) )
{
continue ;
}
2015-02-17 18:13:40 +01:00
grp . SetFlag ( flag , true ) ;
2008-03-30 09:00:22 +02:00
}
/* Set the immunity level this group has */
2015-02-17 18:13:40 +01:00
grp . ImmunityLevel = immunity ;
2008-03-30 09:00:22 +02:00
}
2014-12-14 01:35:12 +01:00
delete rs ;
2008-03-30 09:00:22 +02:00
/ * *
* Get immunity in a big lump . This is a nasty query but it gets the job done .
* /
2015-02-17 18:13:40 +01:00
int len = 0 ;
2008-03-30 09:00:22 +02:00
len + = Format ( query [ len ] , sizeof ( query ) - len , " SELECT g1.name, g2.name FROM sm_group_immunity gi " ) ;
len + = Format ( query [ len ] , sizeof ( query ) - len , " LEFT JOIN sm_groups g1 ON g1.id = gi.group_id " ) ;
len + = Format ( query [ len ] , sizeof ( query ) - len , " LEFT JOIN sm_groups g2 ON g2.id = gi.other_id " ) ;
2014-12-14 01:35:12 +01:00
if ( ( rs = SQL_Query ( db , query ) ) = = null )
2008-03-30 09:00:22 +02:00
{
2014-12-14 01:35:12 +01:00
char error [ 255 ] ;
2008-03-30 09:00:22 +02:00
SQL_GetError ( db , error , sizeof ( error ) ) ;
LogError ( " FetchGroups() query failed: %s " , query ) ;
LogError ( " Query error: %s " , error ) ;
return ;
}
2014-12-14 01:35:12 +01:00
while ( rs . FetchRow ( ) )
2008-03-30 09:00:22 +02:00
{
2014-12-14 01:35:12 +01:00
char group1 [ 80 ] ;
char group2 [ 80 ] ;
2015-02-17 18:13:40 +01:00
GroupId grp , other ;
2008-03-30 09:00:22 +02:00
2014-12-14 01:35:12 +01:00
rs . FetchString ( 0 , group1 , sizeof ( group1 ) ) ;
rs . FetchString ( 1 , group2 , sizeof ( group2 ) ) ;
2008-03-30 09:00:22 +02:00
2015-02-17 18:13:40 +01:00
if ( ( ( grp = FindAdmGroup ( group1 ) ) = = INVALID_GROUP_ID )
| | ( other = FindAdmGroup ( group2 ) ) = = INVALID_GROUP_ID )
2008-03-30 09:00:22 +02:00
{
continue ;
}
2015-02-17 18:13:40 +01:00
grp . AddGroupImmunity ( other ) ;
2008-03-30 09:00:22 +02:00
# if defined _DEBUG
2015-02-17 18:13:40 +01:00
PrintToServer ( " SetAdmGroupImmuneFrom(%d, %d) " , grp , other ) ;
2008-03-30 09:00:22 +02:00
# endif
}
2014-12-14 01:35:12 +01:00
delete rs ;
2008-03-30 09:00:22 +02:00
/ * *
* Fetch overrides in a lump query .
* /
Format ( query , sizeof ( query ) , " SELECT g.name, go.type, go.name, go.access FROM sm_group_overrides go LEFT JOIN sm_groups g ON go.group_id = g.id " ) ;
2014-12-14 01:35:12 +01:00
if ( ( rs = SQL_Query ( db , query ) ) = = null )
2008-03-30 09:00:22 +02:00
{
2014-12-14 01:35:12 +01:00
char error [ 255 ] ;
2008-03-30 09:00:22 +02:00
SQL_GetError ( db , error , sizeof ( error ) ) ;
LogError ( " FetchGroups() query failed: %s " , query ) ;
LogError ( " Query error: %s " , error ) ;
return ;
}
2014-12-14 01:35:12 +01:00
char type [ 16 ] ;
char cmd [ 64 ] ;
char access [ 16 ] ;
while ( rs . FetchRow ( ) )
2008-03-30 09:00:22 +02:00
{
2014-12-14 01:35:12 +01:00
rs . FetchString ( 0 , name , sizeof ( name ) ) ;
rs . FetchString ( 1 , type , sizeof ( type ) ) ;
rs . FetchString ( 2 , cmd , sizeof ( cmd ) ) ;
rs . FetchString ( 3 , access , sizeof ( access ) ) ;
2008-03-30 09:00:22 +02:00
2015-02-17 18:13:40 +01:00
GroupId grp ;
if ( ( grp = FindAdmGroup ( name ) ) = = INVALID_GROUP_ID )
2008-03-30 09:00:22 +02:00
{
continue ;
}
2014-12-14 01:35:12 +01:00
OverrideType o_type = Override_Command ;
2008-03-30 09:00:22 +02:00
if ( StrEqual ( type , " group " ) )
{
o_type = Override_CommandGroup ;
}
2014-12-14 01:35:12 +01:00
OverrideRule o_rule = Command_Deny ;
2008-03-30 09:00:22 +02:00
if ( StrEqual ( access , " allow " ) )
{
o_rule = Command_Allow ;
}
2014-12-14 01:35:12 +01:00
# if defined _DEBUG
2015-02-17 18:13:40 +01:00
PrintToServer ( " AddAdmGroupCmdOverride(%d, %s, %d, %d) " , grp , cmd , o_type , o_rule ) ;
2014-12-14 01:35:12 +01:00
# endif
2008-03-30 09:00:22 +02:00
2015-02-17 18:13:40 +01:00
grp . AddCommandOverride ( cmd , o_type , o_rule ) ;
2008-03-30 09:00:22 +02:00
}
2014-12-14 01:35:12 +01:00
delete rs ;
2008-03-30 09:00:22 +02:00
}
2015-02-17 18:13:40 +01:00
void FetchOverrides ( Database db )
2008-03-30 09:00:22 +02:00
{
2014-12-14 01:35:12 +01:00
char query [ 255 ] ;
DBResultSet rs ;
2008-03-30 09:00:22 +02:00
Format ( query , sizeof ( query ) , " SELECT type, name, flags FROM sm_overrides " ) ;
2014-12-14 01:35:12 +01:00
if ( ( rs = SQL_Query ( db , query ) ) = = null )
2008-03-30 09:00:22 +02:00
{
2014-12-14 01:35:12 +01:00
char error [ 255 ] ;
2008-03-30 09:00:22 +02:00
SQL_GetError ( db , error , sizeof ( error ) ) ;
LogError ( " FetchOverrides() query failed: %s " , query ) ;
LogError ( " Query error: %s " , error ) ;
return ;
}
2014-12-14 01:35:12 +01:00
char type [ 64 ] ;
char name [ 64 ] ;
char flags [ 32 ] ;
int flag_bits ;
while ( rs . FetchRow ( ) )
2008-03-30 09:00:22 +02:00
{
2014-12-14 01:35:12 +01:00
rs . FetchString ( 0 , type , sizeof ( type ) ) ;
rs . FetchString ( 1 , name , sizeof ( name ) ) ;
rs . FetchString ( 2 , flags , sizeof ( flags ) ) ;
2008-03-30 09:00:22 +02:00
# if defined _DEBUG
PrintToServer ( " Adding override (%s, %s, %s) " , type , name , flags ) ;
# endif
flag_bits = ReadFlagString ( flags ) ;
if ( StrEqual ( type , " command " ) )
{
AddCommandOverride ( name , Override_Command , flag_bits ) ;
} else if ( StrEqual ( type , " group " ) ) {
AddCommandOverride ( name , Override_CommandGroup , flag_bits ) ;
}
}
2014-12-14 01:35:12 +01:00
delete rs ;
2008-03-30 09:00:22 +02:00
}