Raised This Month: $12 Target: $400
 3% 

nVault Tutorial


  
 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
Author Message
Bugsy
AMX Mod X Moderator
Join Date: Feb 2005
Location: NJ, USA
Old 05-02-2009 , 01:04   nVault Tutorial
Reply With Quote #1

nVault Tutorial

Intro
nVault is an AMX-X tool designed for an easy method of saving and retrieving data from an external file. I have seen many people ask how to save data in a plugin so it can be retrieved after a map change or server restart. nVault will allow you to do this and it is very simple to use. nVault stores data using a key:data system; each chunk of data that you save has a unique key that corresponds to it. Both key and data are always strings when saving but data can be retrieved as integer, float, or string (see nvault_get). Data is saved to a nvault file in binary format, not plain text; this means that you cannot edit the file in [your favorite text editor here] but there is an nVault Editor that can be used. Also note that you cannot iterate through entries in a nvault file with the native nvault functions. You can iterate through entries using the nVault Utility include file. The ability the store arrays in nVault can also be accomplished with the nVault Utility.

nVault info from AMX-X documentation:
http://www.amxmodx.org/funcwiki.php?go=module&id=20
Code:
nVault is a binary vault implementation. It allows you to open named vaults (which are stored in 
data\vault) and read/write to them at any time. 

The vault is implemented with a simple hash lookup, and the binary file format is primitive. However, it 
should be much faster than AMX Mod X's built-in vault for most things. Each entry is also timestamped, 
so you can prune for old entries. 

Furthermore, the vault attempts to be journaled. That is, it keeps a log of everything it does, so if the 
server crashes, it can "replay" the journal and recover damage. The journal is erased on synchronization 
to the vault binary, which occurs on vault close/mapchange.
These are the available nvault functions:
Code:
nvault_open - Opens a vault by name (such as "myvault").
nvault_close - Closes a vault.
nvault_lookup - Looks up a vault value for full information.
nvault_get - Gets a vault value by returning an int setting a byref float or setting a string & maxlength.
nvault_set - Sets a vault value with current timestamp.
nvault_pset - Sets a permanent vault value with no timestamp.
nvault_remove - Remove an entry from vault.
nvault_touch - "Touches" a key to update its timestamp value. 
nvault_prune - Prunes the vault for entries that are within the given timestamps.
nvault_open
Before doing any transactions with a vault, it must first be opened. This is done with the nvault_open command; it takes 1 string parameter which is the name of the file that is created on the servers hard-disk ([name].vault). When you call the nvault_open() command, it will return a handle (integer value) that is used by all of the other nvault functions as a reference to that particular vault. If an error occurs when opening the vault, nvault_open() will return -1 (INVALID_HANDLE) so it is a good idea to verify if it opened correctly prior to using any other commands.

Code:
nvault_open( const szVaultName[] )

szVaultName = This will be the name of your vault. Every time you want to communicate with this vault you must always use the same name to access that vault. A file will be created in data\vault folder named [szVaultName].vault

Return value: Vault id on success, -1 on failure.
PHP Code:
//Open a vault and throw a plugin error if INVALID_HANDLE is returned.
new iVaultHandle nvault_open"testvault" );

if ( 
iVaultHandle == INVALID_HANDLE )
    
set_fail_state"Error opening nVault" ); 
nvault_close
This function will close the vault. It takes the vault handle to close as a parameter. Once a vault is closed you cannot do any transactions with the vault until it is re-opened. In most circumstances it is best to put nvault_close() in plugin_end(). Failure to close a vault file will cause it to be corrupt and you will lose all data.
Code:
nvault_close( iHandle )

iHandle = The handle of the vault that we want to close

Return value: 1 on success, 0 on failure
PHP Code:
//Open and close a vault.
new iVaultHandle nvault_open"testvault" );

nvault_closeiVaultHandle ); 
nvault_lookup
This function will lookup data using a string key and will place the found data into szValue by-reference for a max of iMaxLength characters. If data is found, the function will return 1 (true), if no data found 0 (false). Timestamp will hold the time at which the entry was written/updated or touched last. This function can only retrieve data from the vault and store it into a string variable. See timestamps section below for an explanation of how timestamps work. This function should be used if you would like to see if a particular key exists in the vault.

Code:
nvault_lookup( iHandle , const szKey[] , szValue[] , iMaxLength , iTimestamp )

iHandle = The handle returned from nvault_open.
szKey = The key you want to use for the data lookup.
szValue = The string variable that will store the data we are retrieving.
iMaxLength = The max length of the string we want read into szValue.
iTimestamp = Will hold a timestamp for when entry was written or last touched.

Return value: 1 if data exists, 0 if no data exists.
PHP Code:
//Lookup a string stored in a vault using the players steamid as the key.
new szAuthID[35];
new 
szData[30];
new 
iTimestamp;
new 
iVault;
new 
iDataExists

get_user_authid
id szAuthID charsmaxszAuthID ) );

iVault nvault_open"testvault" );
iDataExists nvault_lookupiVault szAuthID szData charsmaxszData ) , iTimestamp );

//An entry was found, the data for this key is now stored in szData.
if ( iDataExists )
{
    
client_printid print_chat "Data=%s Timestamp=%d" szData iTimestamp );
}
else
{
    
client_printid print_chat "No entry found with key %s" szAuthID );

nvault_get
This function is very similar to nvault_lookup; it looks up data in a vault using the specified key. However, nvault_get is a bit more flexible than nvault_lookup because it allows you to retrieve data directly into a variable other than string. This will negate the need for you to do any data conversion once the data is retrieved as you would need to do if you use nvault_lookup to retrieve a float or int. Note, nvault_get does not allow you to retrieve the timestamp so if you do need the timestamp then you will need to use nvault_lookup.

Code:
nvault_get( handle , const szKey[] , ... )

handle = The handle returned from nvault_open.
key = The key you want to use for the data lookup.
[...] = [Variable # of parameters] This can either be a float variable, string & maxlen, or empty. See below

The number of parameters tells the function what type of data you wish to retrieve. Parameter count starts after szKey[]
0 parameters = nvault_get will return the integer value.
1 parameters = the float value will be passed by reference.
2 parameters = the string value will be passed by ref for maxlen characters. 

Integer: iValue = nvault_get( iHandle , szKey[] );
Return value: Integer value that was found, or 0 if the key was not found or if the data value is non-numerical (ie. a string).

Float: nvault_get( iHandle , szKey[] , float );
Return value: 1 if data found, or 0 if key was not found.

String: nvault_get( iHandle , szKey[] , szValue[] , iMaxLen );
Return value: Length of string data retrieved, or 0 if key was not found.
PHP Code:
//Retrieve an integer, float, and string value from a vault.
new iVault;
new 
szAuthID[35];
new 
szData[30];

iVault nvault_open"testvault" );
get_user_authidid szAuthID charsmaxszAuthID ) );

//To retrieve a number that is stored as the data
new iNumber nvault_getiVault szAuthID );

//To retrieve a float that is stored as the data
new FloatfValue;
nvault_getiVault szAuthID fValue );

//To retrieve a string that is stored as the data
new szDataString[10];
nvault_getiVault szAuthID szDataString charsmaxszDataString ) ); 
nvault_set
This will write data to the vault and timestamp the entry.

Code:
nvault_set( handle , const key[] , const value[] )

handle = The handle returned from nvault_open.
key = The key you want to use for the data lookup.
value = The string you want to write to vault

Return value: 1 on success, 0 on failure.
PHP Code:
//Save the phrase "hello world" to vault using steamid as the key.
new iVault;
new 
szAuthID[35];
new 
szData[30];

iVault nvault_open"testvault" );
get_user_authidid szAuthID charsmaxszAuthID ) );

//Pass the value directly with no variable
nvault_setiVault szAuthID "hello world" );

//Pass the value with a string variable
new szText[] = "hello world";
nvault_setiVault szAuthID szText ); 
nvault_pset
The same as nvault_set() except this writes an entry without a timestamp so the entry will not be removed by the nvault_prune() function (if called). The timestamp value is 0 when permanent.
Code:
Return value: 1 on success, 0 on failure.
nvault_remove
This removes an entry from the vault that has the specified key value.
Code:
nvault_remove( handle , const key[] )

handle = The handle returned from nvault_open.
key = The key of the vault entry to remove.

Return value: 1 on success, 0 on failure.
PHP Code:
//Remove an entry from vault
new iVault;

iVault nvault_open"testvault" );

//Set a test entry with key "test entry"
nvault_setiVault "test entry" "test value" );

//Remove the entry that was just saved
nvault_removeiVault "test entry" ); 
nvault_touch
This function will 'touch' an entry, updating it's timestamp; the entry value will remain unchanged. If the key does not exist that is being touched, an empty entry for that key will be created. See timestamps section below for an explanation of timestamps.

Code:
nvault_touch( iHandle , const szKey[] , [ iTimestamp = -1 ] ) 

iHandle = The handle of the vault
szKey = The key for which we want to update timestamp
iTimeStamp - [Optional param] If not passed to the function (or -1 is passed) 
it will update the key with the current time. Otherwise it will update the 
key with the timestamp specified.

Return value: 1 on success, 0 on failure.
PHP Code:
//Touch the entry
new iVault;
new 
szAuthID[35];

iVault nvault_open"testvault" );

get_user_authidid szAuthID charsmaxszAuthID ) );

//Touch the entry with current timestamp
nvault_touchiVault szAuthID );

//Touch entry with timestamp 1 hour ago. (60 * 60) = 3600
nvault_touchiVault szAuthID get_systime() - 3600 ); 
nvault_prune
This function is used to remove entries that fall within the specified start and end timestamps. A timestamp value is in seconds so keep this in consideration when pruning entries. See timestamps section below for an explanation of timestamps.

Code:
nvault_prune( iHandle , iStart , iEnd )

iHandle = The handle returned from nvault_open.
iStart = The timestamp where to begin removing entries.
iEnd = The timestamp where to stop removing entries.

Return value: Number of vault entries pruned on success, 0 on failure.
PHP Code:
new iVault;

iVault nvault_open"testvault" );

//Remove all entries in vault. 0 = earliest possible time, get_systime() = now.
nvault_pruneiVault get_systime() );

//Remove entries in vault that are 15 days old or more.
//get_systime() returns the current timestamp
//1 day = 86400 seconds = 60 secs * 60 mins * 24 hours
nvault_pruneiVault get_systime() - ( 15 86400 ) ); 
Timestamps
Timestamps in nvault are in unix-time format (aka POSIX time) which is equal to the number of seconds that have elapsed since midnight January 1, 1970. To prune or compare a timestamp retrieved in nvault_lookup, you can do simple multiplication to convert seconds to minutes, hours, days, or weeks. Example: Day = 60 * 60 * 24 = 86400.

In the above nvault_prune example it shows how to prune entries that are 15 days old or more. If you wanted to prune entries that are 10+ minutes old, you would do nvault_prune( iHandle , 0 , get_systime() - ( 60 * 10 ) ).

See this link for info on Unix Time: http://en.wikipedia.org/wiki/Unix_time
AMX-X include file for converting Unix Time <-> Normal Time: http://forums.alliedmods.net/showthread.php?t=91915
Convert Unix Time <-> Normal Time on the web: http://www.onlineconversion.com/unix_time.htm

Using nVault in your plugin
If you will be using nvault functions constantly throughout your plugin, it is best to keep the nvault file open while your plugin is running. To do this, use a global variable to hold the handle and call nvault_open() in plugin_init() or plugin_config() (or anywhere you choose). To close the vault, call nvault_close() in plugin_end().

nVault Limitations
The major things (IMO) that are missing in nVault is the ability to determine the number of entries in a vault, the ability to cycle through entries in a vault, and storing arrays. I created an include file, nVault Utility which provides this missing functionality. Just be advised, the nVault handle used with nVault and nVault Utility are *NOT* interchangeable, which means you will have 2 separate handles if you are working with both at the same time (ie. you cannot use the handle returned by nvault_open() with functions in nVault utility and vice-versa. The only exception for this is for the two functions nvault_set_array() and nvault_get_array(), which do use the handle returned by nvault_open().

Example Plugin
The below plugin shows how to do save a players money and score to the vault. When a user disconnects, these items are saved and when he re-connects they get restored.
Plugin
__________________

Last edited by Bugsy; 05-31-2015 at 12:32. Reason: Added nvault_remove() that was missed and add return values for all functions.
Bugsy is offline
 


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 14:02.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode