Basically, tries let you store data associated to a key (string). The data usually is an integer or a string.
- All the examples will be generally simple. I just want to show you how to use tries
So, for the first example I will demonstrate how to detect if a player has a Steam ID in the black list.
Code: Select all
#include < amxmodx >
new Trie:g_tAuthIdBlackList // g means global; t means trie
public plugin_init( )
{
register_plugin( "trie example", "1.0.1", "guipatinador" )
g_tAuthIdBlackList = TrieCreate( ) // Create the trie...
TrieSetCell( g_tAuthIdBlackList, "STEAM_2:3:123456", 1 )
TrieSetCell( g_tAuthIdBlackList, "STEAM_2:3:654321", 1 )
TrieSetCell( g_tAuthIdBlackList, "STEAM_2:3:123654", 1 )
TrieSetCell( g_tAuthIdBlackList, "STEAM_2:3:456123", 1 )
// First param = name of the trie
// Second param = string with the Steam ID blacklisted (this is the key and it should be unique)
// Third param = it is our integer, we will not use this
}
public plugin_end( )
{
TrieDestroy( g_tAuthIdBlackList ) // Destroys the trie when the map changes or the server shuts down
}
public client_authorized( id )
{
new szAuthID[ 35 ]; get_user_authid( id, szAuthID, charsmax( szAuthID ) )
if( TrieKeyExists( g_tAuthIdBlackList, szAuthID ) )
{
// The Steam ID (key), exist in the trie
server_cmd( "kick #%i ^"Your Steam ID is blacklisted^"", get_user_userid( id ) )
}
else
{
// The Steam ID is not in the trie
// We won’t do anything because the Steam ID is not blacklisted
}
} Code: Select all
#include < amxmodx >
new Trie:g_tAuthIdOfPeople
#define LOGFILE "steamidsofpeople.log"
// Just to be more easy...
#define ADMIN 1
#define MOD 2
#define VIP 3
public plugin_init( )
{
register_plugin( "trie example", "1.0.2", "guipatinador" )
g_tAuthIdOfPeople = TrieCreate( )
TrieSetCell( g_tAuthIdOfPeople, "STEAM_2:3:123456", ADMIN ) // admin is 1
TrieSetCell( g_tAuthIdOfPeople, "STEAM_2:3:654321", ADMIN )
TrieSetCell( g_tAuthIdOfPeople, "STEAM_2:3:123654", MOD ) // mod is 2
TrieSetCell( g_tAuthIdOfPeople, "STEAM_2:3:456123", VIP ) // vip is 3
}
public plugin_end( )
{
TrieDestroy( g_tAuthIdOfPeople )
}
public client_authorized( id )
{
new szAuthID[ 35 ]; get_user_authid( id, szAuthID, charsmax( szAuthID ) )
new iNum
// This will save our integer (ADMIN, MOD or VIP) in iNum, if the key is on the trie
if( TrieGetCell( g_tAuthIdOfPeople, szAuthID, iNum ) )
{
switch( iNum )
{
case ADMIN:
log_to_file( LOGFILE, "A Admin entered the server" )
case MOD:
log_to_file( LOGFILE, "A Mod entered the server" )
case VIP:
log_to_file( LOGFILE, "A Vip entered the server" )
}
}
else // The key (Steam ID) is not in the trie
{
log_to_file( LOGFILE, "A normal player entered the server" )
}
} Now let’s work with a few more natives.
For the third example, we will use admin commands to block some nicknames.
Code: Select all
#include < amxmodx >
#include < amxmisc >
new Trie:g_tNicks
#define ADMIN_FLAG ADMIN_RCON
public plugin_init( )
{
register_plugin( "trie example", "1.0.3", "guipatinador" )
register_concmd( "amx_blocknick", "BlockNickCmd", ADMIN_FLAG, "<name to block>" )
register_concmd( "amx_unblocknick", "UnBlockNickCmd", ADMIN_FLAG, "<name to unblock>" )
register_concmd( "amx_removenicks", "RemoveNicksCmd", ADMIN_FLAG )
g_tNicks = TrieCreate( )
}
public plugin_end( )
{
TrieDestroy( g_tNicks )
}
public BlockNickCmd( id, level, cid )
{
if( !cmd_access( id, level, cid, 2 ) )
return PLUGIN_HANDLED
new szName[ 32 ]
read_argv( 1, szName, charsmax( szName ) )
// First we’ll check if the username is in the trie
// If it is, we won't do anything
// If it isn’t, we’ll add the nick
// I will show two methods
// METHOD ONE
if( TrieKeyExists( g_tNicks, szName ) )
{
client_print( id, print_console, "Username already added before" )
}
else
{
TrieSetCell( g_tNicks, szName, 1 )
client_print( id, print_console, "Username added with success" )
}
/*
// METHOD TWO
new iNum
new bool:bNameAlreadyAdded = TrieGetCell( g_tNicks, szName, iNum )
if( bNameAlreadyAdded )
{
client_print( id, print_console, "Username already added before" )
}
else
{
TrieSetCell( g_tNicks, szName, 1 )
client_print( id, print_console, "Username added with success" )
}
*/
return PLUGIN_HANDLED
}
public UnBlockNickCmd( id, level, cid )
{
if( !cmd_access( id, level, cid, 2 ) )
return PLUGIN_HANDLED
new szName[ 32 ]
read_argv( 1, szName, charsmax( szName ) )
if( TrieDeleteKey( g_tNicks, szName ) )
{
client_print( id, print_console, "Username deleted with success" )
}
else
{
client_print( id, print_console, "Username already deleted before" )
}
/*
// If you want to delete, without print a message just do this
TrieDeleteKey( g_tNicks, szName )
*/
return PLUGIN_HANDLED
}
public RemoveNicksCmd( id, level, cid )
{
if( !cmd_access( id, level, cid, 1 ) )
return PLUGIN_HANDLED
TrieClear( g_tNicks ) // This one clears all the keys of the trie and the data
client_print( id, print_console, "All the blocked usernames were deleted" )
return PLUGIN_HANDLED
}
public client_authorized( id )
{
new szName[ 32 ]; get_user_name( id, szName, charsmax( szName ) )
if( TrieKeyExists( g_tNicks, szName ) )
{
server_cmd( "kick #%i ^"Your nickname is blocked^"", get_user_userid( id ) )
}
/*
// Note that this will also work
new iNum
if( TrieGetCell( g_tNicks, szName, iNum ) )
{
server_cmd( "kick #%i ^"Your nickname is blocked^"", get_user_userid( id ) )
}
*/
} Code: Select all
#include < amxmodx >
#include < amxmisc >
new Trie:g_tVipDate
new const VIPDATE[ ][ ][ ] = {
{ "STEAM_2:3:123456", "01-04-2013" },
{ "STEAM_2:3:654321", "25-02-2013" },
{ "STEAM_2:3:123654", "13-03-2013" },
{ "STEAM_2:3:456123", "09-01-2013" }
}
public plugin_init( )
{
register_plugin( "trie example", "1.0.4", "guipatinador" )
register_clcmd( "say /vipdate", "VipDate" )
g_tVipDate = TrieCreate( )
new i
for( i = 0; i < sizeof VIPDATE; i++ )
{
TrieSetString( g_tVipDate, VIPDATE[ i ][ 0 ], VIPDATE[ i ][ 1 ] )
// First param = name of the trie
// Second param = Steam ID (key)
// Third param = date when the vip ends (string)
}
}
public plugin_end( )
{
TrieDestroy( g_tVipDate )
}
public VipDate( id )
{
new szAuthID[ 35 ]; get_user_authid( id, szAuthID, charsmax( szAuthID ) )
// First we’ll check if the Steam ID of the player is in the trie
new szVipDate[ 12 ]
if( TrieGetString( g_tVipDate, szAuthID, szVipDate, charsmax( szVipDate ) ) )
{
// The user is vip because the Steam ID is one of the keys of the trie
client_print( id, print_chat, "Your VIP will end in: %s", szVipDate )
}
else
{
// User is not vip
client_print( id, print_chat, "You are not VIP" )
}
} This plugin read the stats of a file and save it by Steam ID.
Code: Select all
#include < amxmodx >
#include < amxmisc >
new Trie:g_StatsOfPlayers
new g_szAuthID[ 33 ][ 35 ] // This will save the Steam ID of any player
enum _:Stats {
SteamID[ 35 ],
Kills,
Deaths,
KillsKnife,
KillsHE
}
// Those are the stats we want to save. Note that the Steam ID is a string, the rest are integers
public plugin_init( )
{
register_plugin( "trie example", "1.0.5", "guipatinador" )
register_clcmd( "say /mystats", "PrintStats" ) // We will use this command to see the stats
g_StatsOfPlayers = TrieCreate( )
ReadStatsFromFile( ) // Reads stats from the file when the server starts or the map changes
}
public plugin_end( )
{
TrieDestroy( g_StatsOfPlayers )
}
public ReadStatsFromFile( )
{
new szFilePath[ 128 ]
get_configsdir( szFilePath, charsmax( szFilePath ) )
add( szFilePath, charsmax( szFilePath ), "/stats_of_players.ini" ) // File where the stats are saved
new f = fopen( szFilePath, "rt" )
if( !f )
{
new szMessage[ 256 ]
formatex( szMessage, charsmax( szMessage ), "Unable to open %s", szFilePath )
set_fail_state( szMessage )
}
new szDataFromFile[ 128 ]
new Data[ Stats ]
new szKills[ 5 ]
new szDeaths[ 5 ]
new szKnife[ 5 ]
new szHE[ 5 ]
while( !feof( f ) ) // Opens the file
{
fgets( f, szDataFromFile, charsmax( szDataFromFile ) )
if( !szDataFromFile[ 0 ] || szDataFromFile[ 0 ] == ';' || szDataFromFile[ 0 ] == '/' && szDataFromFile[ 1 ] == '/' )
continue
trim( szDataFromFile )
parse( szDataFromFile,
Data[ SteamID ], charsmax( Data[ SteamID ] ), // This is our key
szKills, charsmax( szKills ),
szDeaths, charsmax( szDeaths ),
szKnife, charsmax( szKnife ),
szHE, charsmax( szHE ) )
// All those things are strings. Let's convert to integers
Data[ Kills ] = str_to_num( szKills )
Data[ Deaths ] = str_to_num( szDeaths )
Data[ KillsKnife ] = str_to_num( szKnife )
Data[ KillsHE ] = str_to_num( szHE )
// This will save the Steam ID and the stats in the trie
TrieSetArray( g_StatsOfPlayers, Data[ SteamID ], Data, sizeof Data )
// First param = name of the trie
// Second param = key (string) (in this case it's the Steam ID)
// Third param = array that contains the stats
// Fourth param = size of the array (note that 'sizeof Data - 1' will not work)
}
fclose( f ) // Closes the file
}
public client_authorized( id )
{
get_user_authid( id, g_szAuthID[ id ], charsmax( g_szAuthID[ ] ) )
}
public PrintStats( id )
{
new Data[ Stats ]
if( TrieGetArray( g_StatsOfPlayers, g_szAuthID[ id ], Data, sizeof Data ) )
{
// The params are similar to TrieSetString
// First = name of the array
// Second = key. g_szAuthID[ id ] contains the Steam ID of the player that types /mystats
// Third = array to retrieve the data
// Fourth = size
client_print( id, print_chat, "Steam ID: %s | Kills: %i | Deaths: %i | Knife: %i | HE: %i", Data[ SteamID ], Data[ Kills ], Data[ Deaths ], Data[ KillsKnife ], Data[ KillsHE ] )
}
// If the Steam ID doesn't exist in the file, it is better to print another message
else
{
client_print( id, print_chat, "Your Steam ID do not have stats saved" )
}
} 