I tried optimizing my Elite Admin System plugin by using Tries instead of Arrays for storing player information. The problem is some Admins/Vips in my server aren't getting their flags, I also noticed that only those that are around the middle/end of the file are having this issue, if I copy-paste their data to the top of the users file, they get their flags, which is confusing me. It feels like some lines are being skipped when reading.
To avoid confusion: I'm checking TrieKeyExists in 2 ways, steamid and name, because in Elite Admin System you're able to set admins by name and steamid.
Part which sets flags:
PHP Code:
CheckPlayerAdmin( id )
{
new szPassword[ MAX_PASSWORD_LENGTH ], eData[ PlayerData ];
get_user_info( id, "_pw", szPassword, charsmax( szPassword ) );
if( TrieKeyExists( g_tDatabase, g_szAuthId[ id ] ) ) // key exists?
{
TrieGetArray( g_tDatabase, g_szAuthId[ id ], eData, sizeof eData ); // get the data from the key
if( ( eData[ Player_Password ][ 0 ] && equal( eData[ Player_Password ], szPassword ) ) || !eData[ Player_Password ][ 0 ] ) // password correct or no password at all
{
if( eData[ Player_Suspended ] || ( eData[ Player_Expired ] && !eData[ Player_KeepPrivileges ] ) ) // player suspended or date expired
{
remove_user_flags( id );
set_user_flags( id, ADMIN_USER );
}
else if( eData[ Player_Expired ] && eData[ Player_KeepPrivileges ] ) // expired but keeps his flags
{
remove_user_flags( id );
if( ! eData[ Player_AccessFlags ][ 0 ] ) // no flags specified?
{
set_user_flags( id, ADMIN_USER );
}
new iFlags = read_flags( eData[ Player_AccessFlags ] );
iFlags &= ~read_flags( eData[ Player_FlagsExpire ] ); // remove expire flags from default flags
if( ! iFlags ) // no flags left
{
set_user_flags( id, ADMIN_USER ); // set 'z' flag
}
else
{
set_user_flags( id, iFlags ); // set flags
}
}
else
{
remove_user_flags( id );
if( ! eData[ Player_AccessFlags ][ 0 ] ) // no flags
{
set_user_flags( id, ADMIN_USER );
}
else
{
set_user_flags( id, read_flags( eData[ Player_AccessFlags ] ) );
}
}
}
else if( eData[ Player_Password ][ 0 ] && !equal( eData[ Player_Password ], szPassword ) )
{
server_cmd( "kick #%d ^"%L^"", get_user_userid( id ), LANG_PLAYER, "INCORRECT_PASSWORD" );
}
}
else if( TrieKeyExists( g_tDatabase, g_szName[ id ] ) )
{
TrieGetArray( g_tDatabase, g_szName[ id ], eData, sizeof eData );
if( ( eData[ Player_Password ][ 0 ] && equal( eData[ Player_Password ], szPassword ) ) || !eData[ Player_Password ][ 0 ] )
{
if( eData[ Player_Suspended ] || ( eData[ Player_Expired ] && !eData[ Player_KeepPrivileges ] ) )
{
remove_user_flags( id );
set_user_flags( id, ADMIN_USER );
}
else if( eData[ Player_Expired ] && eData[ Player_KeepPrivileges ] )
{
remove_user_flags( id );
if( ! eData[ Player_AccessFlags ][ 0 ] )
{
set_user_flags( id, ADMIN_USER );
}
new iFlags = read_flags( eData[ Player_AccessFlags ] );
iFlags &= ~read_flags( eData[ Player_FlagsExpire ] );
if( ! iFlags )
{
set_user_flags( id, ADMIN_USER );
}
else
{
set_user_flags( id, iFlags );
}
}
else
{
remove_user_flags( id );
if( ! eData[ Player_AccessFlags ][ 0 ] )
{
set_user_flags( id, ADMIN_USER );
}
else
{
set_user_flags( id, read_flags( eData[ Player_AccessFlags ] ) );
}
}
}
else if( eData[ Player_Password ][ 0 ] && !equal( eData[ Player_Password ], szPassword ) )
{
server_cmd( "kick #%d ^"%L^"", get_user_userid( id ), LANG_PLAYER, "INCORRECT_PASSWORD" );
}
}
}
Part which reads data from users file and fills the trie:
PHP Code:
ReloadFile( )
{
TrieClear( g_tDatabase );
ArrayClear( g_aPlayers );
new szFormat[ 64 ], szPlayerData[ 512 ], eData[ PlayerData ];
formatex( szFormat, charsmax( szFormat ), "%s/%s", g_szConfigsDir, g_iConfig[ USERS_FILE ] );
new iFile = fopen( szFormat, "rt" );
if( iFile )
{
while( fgets( iFile, szPlayerData, charsmax( szPlayerData ) ) )
{
trim( szPlayerData );
switch( szPlayerData[ 0 ] )
{
case EOS, '#', '/', '\':
{
continue;
}
default:
{
new szImmunity[ 8 ], szKeepPrivileges[ 3 ];
if( parse( szPlayerData, eData[ Player_Name ], charsmax( eData[ Player_Name ] ), eData[ Player_SteamID ], charsmax( eData[ Player_SteamID ] ), eData[ Player_Password ], charsmax( eData[ Player_Password ] ), eData[ Player_AccessFlags ], charsmax( eData[ Player_AccessFlags ] ),
eData[ Player_Prefix ], charsmax( eData[ Player_Prefix ] ), eData[ Player_Model_T ], charsmax( eData[ Player_Model_T ] ), eData[ Player_Model_CT ], charsmax( eData[ Player_Model_CT ] ), szImmunity, charsmax( szImmunity ),
eData[ Player_Expire_Date ], charsmax( eData[ Player_Expire_Date ] ), eData[ Player_FlagsExpire ], charsmax( eData[ Player_FlagsExpire ] ), szKeepPrivileges, charsmax( szKeepPrivileges ) ) < 11 )
{
continue;
}
if( szPlayerData[ 0 ] == ';' )
{
eData[ Player_Suspended ] = true;
replace( eData[ Player_Name ], charsmax( eData[ Player_Name ] ), ";", "" );
}
if( eData[ Player_Expire_Date ][ 0 ] )
{
if( HasAdminExpired( eData[ Player_Expire_Date ] ) )
{
eData[ Player_Expired ] = true;
}
}
// we don't want to use models that don't exist
if( eData[ Player_Model_T ][ 0 ] )
{
if( ! ModelExists( eData[ Player_Model_T ] ) )
{
eData[ Player_Model_T ][ 0 ] = EOS;
}
}
if( eData[ Player_Model_CT ][ 0 ] )
{
if( ! ModelExists( eData[ Player_Model_CT ] ) )
{
eData[ Player_Model_CT ][ 0 ] = EOS;
}
}
new iImmunity = str_to_num( szImmunity );
eData[ Player_Immunity ] = ( ! is_str_num( szImmunity ) || iImmunity < 0 ) ? 0 : iImmunity;
new iKeepPrivileges = str_to_num( szKeepPrivileges );
eData[ Player_KeepPrivileges ] = bool:( ( ! is_str_num( szKeepPrivileges ) || !( 0 <= iKeepPrivileges <= 1 ) ) ? 0 : iKeepPrivileges );
if( eData[ Player_SteamID ][ 0 ] )
{
TrieSetArray( g_tDatabase, eData[ Player_SteamID ], eData, sizeof eData );
ArrayPushString( g_aPlayers, eData[ Player_SteamID ] );
}
else if( eData[ Player_Name ][ 0 ] )
{
TrieSetArray( g_tDatabase, eData[ Player_Name ], eData, sizeof eData );
ArrayPushString( g_aPlayers, eData[ Player_Name ] );
}
}
}
}
fclose( iFile );
}
}
Full code attached!