Raised This Month: $404 Target: $400
 101% 

[TUT] nVault Top 15


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Bugsy
AMX Mod X Moderator
Join Date: Feb 2005
Location: NJ, USA
Old 05-13-2018 , 13:01   [TUT] nVault Top 15
Reply With Quote #1

nVault Top 15

Over the years I've seen many scripters ask how to create a top 15 for data that is stored in nVault. Since the nVault module has no retrieve-all or sorting functionality this is not possible without the use of nVault Utility. While not required to complete this, I am providing an example using the nVault Array include since I think this is a cleaner approach than storing all data as a string and then parsing components of the string for the calculation.

High-level explanation for how nVault Utility works:
nVault Utility uses the file natives to read data from the vault file in binary format. Each item (key:data) in nVault is stored at an offset within the file, with 0 being the position of the first record, the next record is positioned based off of the size of the previous record, etc. This offset, or location of player data, will be used as a reference to the player data to make this top 15 possible.

Steps for creating a Top 15:
  1. Read all records in the vault file and store the player-data offset and XP value to a 2-dimension array.
  2. Sort this array using the XP value as the sort value.
  3. Loop through this sorted array to build the top 15. With each iteration, the players data offset will be used to re-read their data from the vault. Any piece of data that is stored in the nVault array record can be used in the top 15 (name, steam id, xp, etc).
Requirements:Note: You must delete your vault file or prune all data before implementing this since nvault_read_array() will fail if you try to read data that was not stored using nvault_set_array().

Plugin chat commands:
  • top15 - Display the top 15.
  • loadtestdata - Loads 100 test records to the vault in 'Player_# [XP]' format. The players name includes their stored XP value so you can confirm it is sorting accurately.
PHP Code:

#include <amxmodx>
#include <nvault>
#include <nvault_util>
#include <nvault_array>

//Allocate additional memory to plugin to prevent stack error
#pragma dynamic 16384

new const Version[] = "0.1";

new const 
VaultName[] = "XP_Top15_Example";

//This determines the max number of players that will be included in your top 15 calculation. It is best to keep this at a 
//value <= the max players that you expect to have data saved in the vault. If the number of player data saved exceeds this
//value then your top 15 will not be accurate since some players will be left out.
const Max_Player_Support 3000;

//Components of data that will be saved for each player.
enum PlayerData
{
    
PlayerName32 ],
    
XP
}

new 
pdDataMAX_PLAYERS ][ PlayerData ];
new 
g_AuthIDMAX_PLAYERS ][ 34 ];
new 
bool:g_BotOrHLTVMAX_PLAYERS ];
new 
g_Vault;

//In your plugin, you set a players XP using the below:
//pdData[ id ][ XP ] = 12345;
    
public plugin_init() 
{
    
register_plugin"nVault Top 15" Version "bugsy" );
    
    
register_clcmd"say top15" "ShowTop15" );
    
register_clcmd"say loadtestdata" "LoadTestData" );
    
    if ( ( 
g_Vault nvault_openVaultName ) ) == INVALID_HANDLE )
    {
        
set_fail_state"Failed to open vault" );
    }
}

public 
plugin_end() 
{
    
nvault_closeg_Vault );
}

public 
client_authorizedid )
{
    if ( !( 
g_BotOrHLTVid ] = bool:( is_user_botid ) || is_user_hltvid ) ) ) )
    {
        
//Get players' steam-id so it can be used to retrieve their data from the vault.
        
get_user_authidid g_AuthIDid ] , charsmaxg_AuthID[] ) );
        
        
//Retrieve player data from vault. 
        
nvault_get_arrayg_Vault g_AuthIDid ] , pdDataid ][ PlayerData:] , sizeofpdData[] ) );
    }
}

public 
client_disconnectid )
{
    if ( !
g_BotOrHLTVid ] )
    {
        
//To avoid having to monitor for name changes in-game, the players name is retrieved and saved when disconnecting.
        
get_user_nameid pdDataid ][ PlayerName ] , charsmaxpdData[][ PlayerName ] ) );
        
        
//Save player data to vault.
        
nvault_set_arrayg_Vault g_AuthIDid ] , pdDataid ][ PlayerData:] , sizeofpdData[] ) );
    }
}

public 
ShowTop15id )
{
    
enum _:Top15Info
    
{
        
nVault_Offset,
        
XP_Value
    
}
    
    static 
iSortDataMax_Player_Support ][ Top15Info ];
    
    new 
iVault iRow iCount iNextOffset iCurrentOffset szKey45 ] , iAvailablePlayers pdValPlayerData ];
    new 
szMOTD1501 ] , iPos;
    
    
//Close and re-open vault so the journal writes to the vault so nvault_util gets most up to date data.
    
nvault_closeg_Vault );
    
g_Vault nvault_openVaultName );
    
    
//Open vault for nvault utility usage.
    
iVault nvault_util_openVaultName );
    
    
//Get count of total number of records in the vault.
    
iCount nvault_util_countiVault );
    
    
//Loop through all records in the vault.
    
for ( iRow iRow iCount && iRow Max_Player_Support iRow++ )
    {
        
//Read record from vault. iNextOffset will hold the position of the next record in the vault.
        
iNextOffset nvault_util_read_arrayiVault iNextOffset szKey charsmaxszKey ) , pdValPlayerData:] , sizeofpdVal ) );
        
        
//Set nVault_Offset to the byte offset for this players data within the vault so it can additional data (name, etc) if he is within top 15.
        //iPrevOffset is used since iOffset holds the position of the NEXT record, not current.
        
iSortDataiRow ][ nVault_Offset ] = iCurrentOffset;
        
        
//Set Player_XP value in array to his XP value. This will be used for sorting.
        
iSortDataiRow ][ XP_Value ] = pdValXP ];
        
        
//Since nvault_util_read_array() holds the position of the next record, we have to hold the current offset separately.
        
iCurrentOffset iNextOffset;
    }
    
    
//Sort the array.
    
SortCustom2DiSortData miniCount Max_Player_Support ) , "CompareXP" );

    
//Prepare top 15 MOTD.
    
iPos formatexszMOTD charsmaxszMOTD ) , "<body bgcolor=#000000><font color=#98f5ff><pre>" );
    
iPos += formatexszMOTDiPos ] , charsmaxszMOTD ) - iPos "%2s %-22.22s %3s^n" "#" "Name" "XP" );
    
    
//This will account for if the vault has less than 15 player data records stored.
    
iAvailablePlayers miniCount 15 );
    
    
//Build the top 15. iAvailablePlayers is set to the smaller of 15 or the total records in the vault.
    
for ( iRow iRow iAvailablePlayers iRow++ )
    {
        
//Get nVault player data offset value which was set in the above loop.
        
iCurrentOffset iSortDataiRow ][ nVault_Offset ];
        
        
//Read data at the players offset so we can retrieve their name to be displayed in the top 15.
        
nvault_util_read_arrayiVault iCurrentOffset szKey charsmaxszKey ) , pdValPlayerData:] , sizeofpdVal ) );
        
        
//Format line in MOTD.
        
iPos += formatexszMOTDiPos ] , charsmaxszMOTD ) - iPos ,"%2d %-22.22s %3d^n", ( iRow ) , pdValPlayerName ] , pdValXP ] );
    }
    
    
//Close nvault utility file.
    
nvault_util_closeiVault );
    
    
formatexszMOTDiPos ], charsmaxszMOTD ) - iPos "</body></font></pre>" );
    
    
show_motdid szMOTD "XP Top 15" );
    
    return 
PLUGIN_HANDLED;
}

public 
LoadTestData()
{
    new 
szAuthID10 ] , pdDataPlayerData ] , iRow iXP;
    
    for ( 
iRow iRow 100 iRow++ )
    {
        
formatexszAuthID charsmaxszAuthID ) , "STEAM_%d" iRow );
        
        
iXP random9999 );
        
        
formatexpdDataPlayerName ] , charsmaxpdDataPlayerName ] ) , "Player_%d [%d]" iRow iXP );
        
pdDataXP ] = iXP;
        
        
nvault_set_arrayg_Vault szAuthID pdDataPlayerData:] , sizeofpdData ) );
    }
    
    return 
PLUGIN_HANDLED;
}

public 
CompareXPelem1[] , elem2[] ) 

    if ( 
elem1] > elem2] ) 
        return -
1
    else if(
elem1] < elem2] ) 
        return 
1
    
    return 
0

__________________

Last edited by Bugsy; 07-04-2018 at 11:14.
Bugsy is offline
soumyadip77
Senior Member
Join Date: Jul 2017
Location: INDIA,KOLKATA
Old 05-14-2018 , 11:18   Re: [TUT] nVault Top 15
Reply With Quote #2

Thanks
i need this from 4 months finally you make it i will make new xp mod with it <3 u bugsy
soumyadip77 is offline
Send a message via Skype™ to soumyadip77
Reply


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 15:31.


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