HOW IT WORKS ? ∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙ ∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙ ∙↑
How the module detects when a cvar value is set ?
It simply hooks the engine function Cvar_DirectSet() ;
It's called only when a value is set, after checks and at the end of others functions.
The cvar is already beeing cached into a global variable in a same plugin.
CvarReturn_AlreadyBounded
The cvar has already a minimum/maximum bound defined in another plugin.
It means you can not overwritten an existing defined bound unless it has been registered in a same plugin.
CvarReturn_AlreadyLocked
The cvar is locked, whatever the lock is active or not, in this plugin or another.
The hook is still registered but any changes won't be notified if the lock is active.
CvarReturn_DuplicatedHook
It means, in this plugin, you are trying to hook a same cvar with a the same callback.
It will be ignored. No need to create duplicated forwards.
So, yes, you are allowed, for a same plugin, to hook a same cvar with differents callbacks.
/**
* Called when a cvar's value is changed.
*
* @note Returning PLUGIN_HANDLED will block the change.
*
* @param handleCvar Handle to the cvar that was changed.
* @param oldValue String containing the value of the cvar before it was changed.
* @param newValue String containing the new value of the cvar.
* @param defaultvalue String containing the default value of a cvar.
*/
forward CvarHookChanged( handleCvar, const oldValue[], const newValue[], const cvarName[], const defaultValue[]);
Example
PHP Code:
#include <amxmodx>
#include <cvar_util>
public plugin_init()
{
register_plugin( "CU: Hook All Cvars Change", "1.0.0", "Arkshine" );
}
public CvarHookChanged( handleCvar, const oldValue[], const newValue[], const cvarName[], const defaultValue[] )
{
/*
| Note : At server restart (or map change), cvars are not registered yet.
| It means there is no reference of the old value when the module will detect a cvar is set,
| thus it can't be compared to know whether it can be notified because the old value is the same as new.
| So, when the module registers a new cvar, it's considered as a change and will be notified,
| and that's why you will see an empty string as old value.
*/
/**
* Creates a hook for when a cvar's value is changed.
*
* @note Example of callback : OnCvarChange( handleCvar, const oldValue[], const newValue[], const cvarName[], const defaultValue[] )
* Returning PLUGIN_HANDLED in the callback function will block the change.
*
* @note Once the hook has been registered, it will call right away the forward with an empty 'oldValue' or default value when it can.
* If you don't like this behavior, use ignoreFirstCall set to true.
*
* @param handleCvar Handle to the cvar.
* @param callback The forward to call.
* @param ignoreFirstCall Whether you want the callback be called right after hook is registered.
*
* @return The number of registered hooks on the cvar on success, otherwise :
* - CvarReturn_DuplicatedHook
* - CvarReturn_AlreadyLocked
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
* - An invalid callback name.
*/
native CvarHookChange( handleCvar, const callback[], bool:ignoreFirstCall =false);
Code:
/**
* Starts a forward back up.
*
* @note If a cvar is hooked more than one time with differents callbacks in a same plugin,
* all the registered hooks for this cvar will be enabled, unless you provide a callback
* to enable a specific hook.
*
* @param handleCvar The forward to re-enable.
* @param callback (optional) The forward to check. See the note above.
*
* @return The number of registered hooks enabled on success.
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
* - A no-active hook.
* - An invalid callback name.
*/
native CvarEnableHook( handleCvar, const callback[]="");
Code:
/**
* Stops a ham forward from triggering.
*
* @note If a cvar is hooked more than one time with differents callbacks in a same plugin,
* all the registered hooks for this cvar will be disabled, unless you provide a callback
* to disable a specific hook.
*
* @param handleCvar Handle to the cvar.
* @param callback (optional) The forward to check. See the note above.
*
* @return The number of registered hooks disabled on success.
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
* - A no-active hook.
* - An invalid callback name.
*/
native CvarDisableHook( handleCvar, const callback[]="");
Examples
PHP Code:
#include <amxmodx>
#include <cvar_util>
public plugin_init()
{
register_plugin( "CU: Hook Own Cvar", "1.0.0", "Arkshine" );
/**
* Same functionnality as CvarHookChange.
* A hook is created for all the registered cvars of the current plugin.
*
* @note Useful when you have a bunch of cvars in your plugin and you want to hook all
* with the same callback. It will avoid to use individually CvarHookChange.
*
* @note It works only with CvarRegister !
*
* @note Example of callback : OnCvarChange( handleCvar, const oldValue[], const newValue[], const cvarName[], const defaultValue[] )
* Returning PLUGIN_HANDLED in the callback function will block the change.
*
* @note Once the hook has been registered, it will call right away the forward with an empty 'oldValue' or default value when it can.
* If you don't like this behavior, use ignoreFirstCall set to true.
*
* @param callback The forward to call.
* @param ignoreFirstCall Whether you want the callback be called right after hook is registered.
*
* @return The number of registered cvars hooked on success, otherwise :
* - CvarReturn_DuplicatedHook
*
* @return error Throw a log error with :
* - An invalid callback name.
*/
native CvarHookChangeAll(const callback[], bool:ignoreFirstCall =false);
Code:
/**
* Starts a forward back up for all the registered cvars of the current plugin.
*
* @return The number of registered cvars enabled on success.
*/
native CvarEnableHookAll();
Code:
/**
* Stops a forward from triggering for all the registered cvars of the current plugin.
*
* @return The number of registered cvars disabled on success.
*/
native CvarDisableHookAll();
Examples
PHP Code:
#include <amxmodx>
#include <cvar_util>
public plugin_init()
{
register_plugin( "CU: Hook All Registered Cvars", "1.0.0", "Arkshine" );
/**
* Hooks a cvar's value change and cache the new value into the provided global variable.
*
* @note Useful if purpose is to cache only a cvar value.
* @note It avoids the creation of hook and the call of get_*car_*() natives.
* @note It works only with integer, float, string and flags.
*
* @param handleCvar Handle to the cvar.
* @param type The type of the variable passed. (See CvarType_* constants)
* @param ... The global variable to pass by reference.
* If a string, the buffer length must be provided too.
*
* @return 1 on success, otherwise :
* - CvarReturn_DuplicatedCache
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
* - An invalid buffer size for string.
* - A missing buffer size argument for string.
*/
native CvarCache( handleCvar, type, any:... );
// Then you can use directly "Timeleft" and "SomeValue" in your code, it will be always up-to-date.
server_print( "Timeleft = %s", Timeleft );
server_print( "SomeValue = %f", SomeValue );
server_print( "SomeFlagsValue = %i", SomeFlagsValue );
}
PHP Code:
#include <amxmodx>
#include <cvar_util>
/* A more complex example with the use of a structure. */
new const CvarsDatas[][][] =
{
/* Name Value Type Size */
{ "MyCvar_1", "1337" , CvarType_Int , 0 },
{ "MyCvar_2", "Hello", CvarType_String, 64 }, // The last column is about the string size,
{ "MyCvar_3", "15.4" , CvarType_Float , 0 }, // Put 0 if not a string.
{ "MyCvar_4", "abcde", CvarType_Flags , 0 }
// ... Add your cvar data here.
};
new Cache[ CvarCacheStruct ];
public plugin_init()
{
register_plugin( "CU: Caching Cvar's Value Change #4", "1.0.0", "Arkshine" );
// Register all our cvars.
register_cvars( CvarsDatas, Cache );
/**
* Forces a cvar to be locked to a provided value.
* Value which can be either a string or a float.
*
* @note If you want to provide a float value, you can do that for example : CvarLockValue( handle, .fvalue = 10.0 );
* @note A lock can not be overwritten unless it's done in a same plugin.
*
* @param handleCvar Handle to the cvar.
* @param value The value to lock as string.
* @param fvalue The value to lock as float.
*
* @return 1 on success, otherwise :
* - CvarReturn_AlreadyLocked
* - CvarReturn_AlreadySet
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
*/
native CvarLockValue( handleCvar, const value[]="", Float:fvalue =0.0);
Code:
/**
* Enables a registered lock.
*
* @note A lock can be enable only in the same plugin where it's registered.
*
* @param handleCvar Handle to the cvar.
*
* @return 1 on success, otherwise :
* - CvarReturn_AlreadySet
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
* - A no-registered lock.
*/
native CvarEnableLock( handleCvar );
Code:
/**
* Disables a registered lock.
*
* @note A lock can be disable only in the same plugin where it's registered.
*
* @param handleCvar Handle to the cvar.
*
* @return 1 on success, otherwise :
* - CvarReturn_AlreadySet
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
* - A no-registered lock.
*/
native CvarDisableLock( handleCvar );
/**
* Creates a new cvar.
*
* @param name The name of the new cvar.
* @param string The string containing the default value of new cvar.
* @param description (optional) The description of the cvar.
* @param flags (optional) The flags determining how the cvar should be handled. See FCVAR_* constants for more details.
* @param hasMin (optional) Boolean that determines if the cvar has a minimum value.
* @param minValue (optional) Minimum floating point value that the cvar can have if hasMin is true.
* @param hasMax (optional) Boolean that determines if the cvar has a maximum value.
* @param maxValue (optional) Maximum floating point value that the cvar can have if hasMax is true.
* @param forceInterval (optional) Whether value should be inside the interval between min and max values (min <= value <= max)
* or value should be equal to min or max (value == min or value == max).
*
* @return A handle to the newly created cvar. If the cvar already exists, a handle to it will still be returned.
*/
native CvarRegister(const name[], const string[], const description[]="", flags =0, bool:hasMin =false, Float:minValue =0.0, bool:hasMax =false, Float:maxValue =0.0, bool:forceInterval =true);
[PAWN]
/**
* Creates a new cvar where value is a boolean.
*
* @param name The name of the new cvar.
* @param string The string containing the default value of new cvar.
* @param description (optional) The description of the cvar.
* @param flags (optional) The flags determining how the cvar should be handled. See FCVAR_* constants for more details.
*
* @return A handle to the newly created cvar. If the cvar already exists, a handle to it will still be returned.
*/
stock CvarRegisterBoolean( const name[], const string[], const description[] = "", flags = 0 )
{
return CvarRegister( name, string, description, flags, .hasMin = true, .minValue = 0.0, .hasMax = true, .maxValue = 1.0, .forceInterval = false );
}
Example
PHP Code:
#include <amxmodx>
#include <cvar_util>
public plugin_init()
{
register_plugin( "CU : Creating new cvar", "1.0.0", "Arkshine" );
/*
| Here a full example to show all the arguments including the new ones.
| Like a command, you can now provide a description.
| A bound is defined, so the value must be between 0 and 1337.
| Of course, you can just write : CvarRegister( "MyCvar", "1" ); all others are optionals.
| Note : you may notive some argument are explicited, like .hasMin, it's just to be more readable.
*/
new handleCvar = CvarRegister( "MyCvar", "1", "Some description", FCVAR_SERVER, .hasMin = true, .minValue = 0.0, .hasMax = true, .maxValue = 1337.0 );
/*
| If you wish to register a cvar where the value must either 0 or 1 (basically a boolean),
| You can use this stock. Description and Flags are optionnal.
*/
new handleCvar2 = CvarRegisterBoolean( "MyCvar_2", "1" );
/**
* Sets the specified bound of a cvar.
*
* @note A bound already defined can not be overwritten, except it has been defined in a same plugin.
* @note It's possible to set a minimum bound in a plugin A and a maximum bound in plugin B.
*
* @param handleCvar Handle to the cvar.
* @param type The type of bound to set, CvarBound_Lower or CvarBound_Upper.
* @param set If set to true, cvar will use specified bound. If false, bound will be removed.
* @param value Floating point value to use as the specified bound.
* @param forceInterval (optional) Whether value should be inside the interval between min and max values (min <= value <= max)
* or value should be equal to min or max (value == min or value == max).
*
* @return 1 on success if bound is registered and active, 0 if registered and a lock is active. Otherwise :
* - CvarReturn_AlreadyBounded
* - CvarReturn_AlreadySet
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
*/
native CvarSetBounds( handleCvar, CvarBounds:type, bool:set, Float:value =0.0, bool:forceInterval =true);
Code:
/**
* Retrieves the specified bound of a cvar.
*
* @param handleCvar Handle to the cvar.
* @param type The type of bound to retrieve, CvarBound_Lower or CvarBound_Upper.
* @param value The floating point bound value.
* @param pluginId The plugin id where the bound has been registered.
*
* @return 1 on success.
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
* - A no-active min/max bound.
*/
native CvarGetBounds( handleCvar, CvarBounds:type, &Float:value, &pluginId =0, &bool:forceInterval =true);
// Just a random cvar.
// If you create a new cvar, you can directly set a bound in CvarRegister native.
HandleCvarTimelimit = get_cvar_pointer( "mp_timelimit" );
// Setting a bound between 10 and 20.
// Notice "set" and "value" arguments are explicited to be more readable here.
CvarSetBounds( HandleCvarTimelimit, CvarBound_Lower, .set = true, .value = 10.0 );
CvarSetBounds( HandleCvarTimelimit, CvarBound_Upper, .set = true, .value = 20.0 );
}
public ServerCommand_RemoveBounds()
{
// Remove the bounds.
// Last saved value is restored.
CvarSetBounds( HandleCvarTimelimit, CvarBound_Lower, .set = false );
CvarSetBounds( HandleCvarTimelimit, CvarBound_Upper, .set = false );
}
public ServerCommand_GetBounds()
{
new Float:minValue, Float:maxValue;
new minPluginId, maxPluginId; // optional.
/**
* Returns the number of registered hooks of a cvar.
*
* @param handleCvar Handle to the cvar.
*
* @return The number of registered hooks of a cvar on success.
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
* - A no-active hook.
*/
native CvarHookNum( handleCvar );
Code:
/**
* Gives information about a plugin-registered hook of a cvar.
*
* @param index The position in the list.
* @param handleCvar Handle to the cvar.
* @param pluginId The plugin id where the hook has been registered.
* @param forwardId The forward id of the hook.
* @param callback The buffer to store the callback used by the hook.
* @param callbackLen The size of the buffer.
*
* @return Whether the forward is active or not on success.
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
* - A no-active hook.
* - An invalid index.
*/
native CvarHookInfo( index, handleCvar, &pluginId, &forwardId =-1, callback[]="", callbackLen =0);
Example
PHP Code:
#include <amxmodx>
#include <cvar_util>
public plugin_init()
{
register_plugin( "CU : Get Hook Info", "1.0.0", "Arkshine" );
/*
| A same cvar can be hooked from severals plugins.
| To get a specific hook info, you need to loop though all the registered hooks of the cvar.
*/
// Let's say sv_maxspeed cvar is hooked by one or severals plugins.
new handleCvar = get_cvar_pointer( "sv_maxspeed" );
// First, you need to retrieve the number of registered hook on this cvar.
new numHooks = CvarHookNum( handleCvar );
// Then you can loop.
new pluginId;
new forwardId; // Optional.
new callback[ 32 ]; // Optional.
new isHookActive;
for( new i = 0; i < numHooks; i++ )
{
isHookActive = CvarHookInfo( i, handleCvar, pluginId, forwardId, callback, charsmax( callback ) );
server_print( "[CU : Get Hook Info] %d) pluginId = %d, forwardId = %d, callback = %s, isActive = %d", i, pluginId, forwardId, callback, isHookActive );
}
}
/**
* Gives information about a registered lock of a cvar.
*
* @param handleCvar Handle to the cvar.
* @param pluginId The plugin id where the lock has been registered.
* @param callback The buffer to store the value locked.
* @param callbackLen The size of the buffer.
*
* @return Whether the lock is active or not on success.
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
* - A no-active lock.
*/
native CvarLockInfo( handleCvar, &pluginId, value[]="", valueLen =0);
Example
PHP Code:
#include <amxmodx>
#include <cvar_util>
public plugin_init()
{
register_plugin( "CU : Get Lock Info", "1.0.0", "Arkshine" );
new pluginId;
new value[ 32 ]; // optional
new isLockActive;
// Let's say sv_friction is locked.
isLockActive = CvarLockInfo( get_cvar_pointer( "sv_friction" ), pluginId, value, charsmax( value ) );
server_print( "[CU : Get Lock Info] pluginId = %d, value = %s, isLockActive = %d", pluginId, value, isLockActive );
}
/**
* Get the current status of the cvar.
*
* @param handleCvar Handle to the cvar.
*
* @return Flags value on success.
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
*/
native CvarStatus:CvarGetStatus( handleCvar );
/**
* Get the number of registered cvars by the module.
*
* @return The number of registered cvars.
*/
native CvarNum( handleCvar );
Code:
/**
* Gives information about a cvar.
*
* @param index The position in the list.
* @param handleCvar Handle to the cvar.
* @param pluginId (optional) The plugin id where the cvar is registered by the module.
* @param name (optional) The buffer to store the cvar name.
* @param nameLen (optional) The size of the buffer.
* @param value (optional) The buffer to store the cvar value.
* @param valueLen (optional) The size of the buffer.
* @param description (optional) The buffer to store the cvar description.
* @param descriptionLen (optional) The size of the buffer.
* @param flags (optional) The flags determining how the cvar should be handled. See FCVAR_* constants for more details
* @param defautValue (optional) The buffer to store the cvar description.
* @param defLen (optional) The size of the buffer.
*
* @return The cvar status. See CvarStatus_* contants.
*
* @return error Throw a log error with :
* - An invalid index.
*/
native CvarStatus:CvarInfo( index, &handleCvar, &pluginId =-1, name[]="", nameLen =0, value[]="", valueLen =0, description[]="", descriptionLen =0, &flags =0, defaultValue[]="", defLen =0);
public plugin_init()
{
register_plugin( "CU : Get Cvar Info", "1.0.0", "Arkshine" );
new cvarNum = CvarNum();
new hookNum;
new handle;
new CvarStatus:status;
new pluginId; // optional
new name[ 32 ]; // optional
new value[ 32 ]; // optional
new description[ 128 ]; // optional
new flags; // optional
new defaultValue[ 32 ]; // optional
new forwardId;
new callback[ 32 ];
new isHookActive;
for( new i = 0, j; i < cvarNum; i++ )
{
status = CvarInfo( i, handle, pluginId, name, charsmax( name ), value, charsmax( value ), description, charsmax( description ), flags, defaultValue, charsmax( defaultValue ) );
server_print( "%d) handle= %d, status = %d, pluginId = %d, name = %s, value = %s, description = %s, flags = %d, def = %s", i, handle, status, pluginId, name, value, description, flags, defaultValue );
/**
* Gets the cvar name from it's handle.
*
* @param handleCvar Handle to the cvar.
* @param cvar The buffer to store the string in.
* @param len The string size of the buffer.
*
* @return The length of the cvar name.
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
*/
native CvarGetName( handleCvar, cvar[], len );
Example
PHP Code:
#include <amxmodx>
#include <cvar_util>
public plugin_init()
{
register_plugin( "CU : Get Cvar Name", "1.0.0", "Arkshine" );
// Random cvar, just for the example.
new handleCvar = get_cvar_pointer( "amx_timeleft" );
new name[ 32 ];
CvarGetName( handleCvar, name, charsmax( name ) );
server_print( "[CU : Get Cvar Name] name = %s", status )
}
/**
* Sets the cvar description from it's handle.
*
* @note For a new cvar, see CvarRegister, it includes a description.
*
* @param handleCvar Handle to the cvar.
* @param description The buffer to store the string in.
*
* @return The length of the description string.
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
*/
native CvarSetDescription( handleCvar, const description[]);
Code:
/**
* Gets the cvar name from it's handle.
*
* @param handleCvar Handle to the cvar.
* @param description The buffer to store the string in.
* @param len The string size of the buffer.
*
* @return The length of the description string.
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
*/
native CvarGetDescription( handleCvar, description[], len );
/**
* Returns information from a given plugin id.
*
* @param pluginId The plugin id where the hook has been registered.
* @param name The buffer to store the plugin name.
* @param nameLen The size of the buffer.
* @param title The buffer to store the plugin title.
* @param titleLen The size of the buffer.
*
* @return 1 on success.
*
* @return error Throw a log error with :
* - An invalid plugin index.
*/
native CvarPluginInfo( pluginId, name[], nameLen, title[]="", titleLen =0);
Example
PHP Code:
#include <amxmodx>
#include <cvar_util>
public plugin_init()
{
register_plugin( "CU : Get Plugin Infos", "1.0.0", "Arkshine" );
new pluginId;
new pluginName[ 32 ];
new titleName [ 32 ];
// Let's say you want to know from what plugin sv_friction is locked.
CvarLockInfo( get_cvar_pointer( "sv_friction" ), pluginId );
// Get the infos.
CvarPluginInfo( pluginId, pluginName, charsmax( pluginName ), titleName, charsmax( titleName ) );
/**
* Gets the default value of a cvar.
*
* @note The default value is retrieved the first time the module hooks the cvar.
*
* @param handleCvar Handle to the cvar.
* @param type The type of the variable passed. (See CvarType_* constants)
* @param ... The global variable to pass by reference.
* Can be a float, or a string.
* If a string, the buffer length must be provided too.
*
* @return If type is integer, the default value as integer.
* If type is float, the default value as float.
* if type is float and passed by reference, the default value as integer.
* If type is flags, the default value as a sum of bits.
* If type is string, the copied output length.
* Otherwise, 0 on error.
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
* - An invalid buffer size for string.
* - A missing buffer size argument for string.
*/
native any:CvarGetDefault( handleCvar, type = CvarType_Int, any:... );
Example
PHP Code:
#include <amxmodx>
#include <cvar_util>
public plugin_init()
{
register_plugin( "CU : Get Default Value", "1.0.0", "Arkshine" );
// Let's say we want to retrieve the default value from amxmodx_version cvar.
// Depending the needs, you can specify the format of the output.
new handle = get_cvar_pointer( "amxmodx_version" );
// We change the current value to another random one.
// To make sure the current value is not already the original value.
set_pcvar_string( handle, "123" );
server_print( "[CU : Default Value] current value = %d", get_pcvar_num( handle ) );
// INTEGER
new value1 = CvarGetDefault( handle, CvarType_Int );
value1 = CvarGetDefault( handle ); // CvarType_Int is the type by default, you can write that directly.
/**
* Resets a cvar to it's default value.
*
* @note The default value is retrieved the first time the module hooks the cvar.
*
* @param handleCvar Handle to the cvar.
*
* @return 1 on success.
*
* @return error Throw a log error with :
* - An invalid cvar pointer.
*/
native CvarReset( handleCvar );
// Let's say we want to reset amxmodx_version cvar.
new handle = get_cvar_pointer( "amxmodx_version" );
// We change the current value to another random one.
// To make sure the current value is not already the original value.
set_pcvar_string( handle, "1.2.3" );
new value[ 16 ];
// Before
get_pcvar_string( handle, value, charsmax( value ) );
server_print( "[CU : Reset Value] current value = %s, before reset", value );
// Reset !
CvarReset( handle );
// After
get_pcvar_string( handle, value, charsmax( value ) );
server_print( "[CU : Reset Value] current value = %s, after reset", value );
}
COMMAND ∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙ ∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙ ∙↑
To retrieve useful informations or troubleshooting, a command exits to help this way : cvartutil or cu.
Usage : [cvarutil|cu] <command>
Commands :
version Display some informations about the module and where to get a support.
example
Code:
Cvar Utilities 1.6
-
Support : https://forums.alliedmods.net/showthread.php?t=154642
Author : Arkshine
Compiled : Feb 28 2013, 22:23:41
status Display module status.
Useful for people where the module doesn't work and they can't check the server logs. I.e :
example
Code:
Cvar Utilities v1.6 - by Arkshine.
-
Memory initialization started.
Searching Cvar_DirectSet address... FOUND
Creating hook... DONE
Memory initialization aborted.
list Show a list of registered cvars which have a status.
Can be filtered by [partial] plugin name.
example
Code:
NAME VALUE REGISTERED HOOKED LOCKED BOUNDED CACHED
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1. mp_timelimit 20 no no no test_plugin_bound.amxx no
2. amx_nextmap de_airstrip_cz no test_plugin_hook_2.amxx no no no
3. MyCvar 666 no test_plugin_hook_1.amxx no no test_plugin_cache_1.amxx
4. sv_friction 10 no no test_plugin_lock.amxx no yes*
5. some_cvar 1337 test_plugin_register.amxx no no test_plugin_register.amxx no
6. some_cvar_bool 1 test_plugin_register.amxx no no test_plugin_register.amxx no
7. MyCvar_1 1 test_plugin_hook_all.amxx test_plugin_hook_all.amxx no no no
8. MyCvar_2 Hello ! test_plugin_hook_all.amxx test_plugin_hook_all.amxx no no no
9. MyCvar_n ... test_plugin_hook_all.amxx yes* no no no
* = There are two or more references of plugins.
Use "cvarutil info cvarname" to get more informations.
info < [cvar|index] > Give detailed informations about a cvar.
example
Code:
Cvar name : MyCvar
Value : 1
Def. value : 0
Description : Some description
Flags : FCVAR_SERVER|FCVAR_EXTDLL
STATUS PLUGIN ACTIVE VALUE / CALLBACK
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Registered test_register.amxx yes 1
Min Bounded test_register.amxx yes 0.000000
Max Bounded test_register.amxx yes 1337.000000
Hooked test_hook1.amxx yes OnCvarChange
Hooked test_hook2.amxx yes OnCvarChange2
Hooked test_hook3.amxx yes OnCvarChangeOrNotLoL
Hooked Untitled.amxx no MyCvarChange
Removed signatures/symbols dependency. Module should now work under all engine version.
Developer
CHooker library has been updated.
v1.5 - 19 feb 2013
Changes/Developer
Changed the way to hook the Cvar_DirectSet function. Instead of patching where this function is referenced, the module is now hooking directly the function.
Even though this way would be slighly less efficient, the advantages are important :
More robust against engine update :
Module is now using only 2 signatures (listen/dedicated) for windows (before 6 signatures) and 1 symbol for linux (before 18 signatures). For linux, it will most likeky not break again.
More easy to maintain :
Same as above + a config file is now added with these signatures/symbols and where it's possible to add new ones. It will be fast and easy to update if need.
v1.4 - 2 sept 2012
New feature
Native/Stock
Added CvarGetDefault() native to retrieve the default value of a cvar. (value got the first time when module hooks a cvar change or from CvarRegister native).
Added CvarReset() native to set back the default value of a cvar. (same comment as above).
Added CvarRegisterBoolean() stock to register more easily a cvar where the value must be either 0 or 1.
Added CvarGetFlagsString() stock to get a concatenated string from a sum of cvar flags.
Added new status CvarStatus_Cached to know whether a cvar is cached.
Added new output for the default value of cvar for CvarInfo() native, CvarHookChanged() forward and callback of CvarHookChange()/CvarHookChangeAll().
Command
Added an alias named cu of cvarutil command, because more fast to type :p.
Added the ability for "info" to pass an index to select the cvar (index at left when you do a "list"), because way more fast to type :p.
Added a new line in the "info" output displaying the default value.
Added a new column "CACHED" to show in what plugin a cvar is cached using CvarCache native.
Added also a list of plugins where the cvar is cached in the "info" output.
Improvement
Added postponing of the sending of cvars change which have been hooked by the module before the Amxx plugins were fully loaded.
Changed the behavior of the cvars where default value was always set at map change. Meaning if you change value and restart, the value was not kept.
When hooking a cvar, the first call (if ignoreFirstCall set to false) will now use the default value if known as the old one instead of an empty string.
Fast clean up in cu_amx_cvar_fix plugin.
Bug
Fixed [somewhow] the issue where the Amxx buffer were overwritten in this situation of a native using such buffer and called inside a cvar callback.
Fixed a potential re-entrancy issue when you would call set_pcvar_* natives inside a cvar callback to change it's value.
Fixed few minor things here and there. Don't remember what.
Command
Fixed the output of list where cvars not registered from plugins could be listed.
Fixed the output of list where a min/max cvar bound from a same plugin was displaying there was more than 1 reference.
Fixed the output of list where a correct [partial] plugin name provided would return always no results.
Fixed the output of list where plugin id would be shifted (because of CSX module loading "csstats.amxx" internally) resulting wrong name.
Native
Fixed PluginInfo() native where plugin id retrieved needs to be incremented by 1 if CSX module is loaded .
v1.3.1 - 17 sept 2011
Improvement
Added better support for linux. It should be now working properly on server using hlds_i686, hlds_i486 or hlds_amd, whatever with[out] the hlbeta update.
v1.3 - 8 sept 2011
Bug
Fixed a wrong/incomplete implementation where a new registered hook should call right away the forward.
Also added a new param ignoreFirstCall for CvarHookChange/CvarHookChangeAll natives to disable this behavior.
New feature
Added a new cvar type CvarType_Flags to be used with CvarCache native which will convert the cvar's value into a sum of bits like does read_flags.
v1.2 - 5 sept 2011
Bug
Added an amxx plugin to fix amx_cvar command not showing the right value after a change because of locked/bounded.
New feature
Added CvarCache native to cache a cvar value in a global variable and so being auto-updated on change.
Added a new status flag CvarStatus_WasOutOfBound to know if the value of the last change on this cvar was out of bound.
(not really useful, just created for the provided plugin to simplify the code)
Minor changes
Changed param pluginId of CvarLockInfo native as optional now.
Added the optional param forceInterval for CvarGetBounds native.
v1.1 - 29 apr 2011
Bug
Typo in CvarRegister, the max bound value was retrieved from the min value.
Bound status in CVarRegister was not set.
New Feature
New natives to help to have a code more cleaner and efficient.
CvarHookChangeAll : hook all the registered cvars of the current plugin.
CvarEnableHookAll : enable all the hooks of the registered cvars of the current plugin.
CvarDisableHookAll : disable all the hooks of the registered cvars of the current plugin.
A command cvarutil to show immediate informations.
version : to get the current version and when module has been compiled.
status : show the module status.
list [plugin] : show a list of registered cvar which have a status. Can be filtered by plugin.
info <cvar> : show the full details of a cvar.
Added a new param forceInterval for CvarRegister and CvarSetBounds to allow for a defined bound
to choose if the value has to be inside the interval between the min and max values (min <= value <= max)
or if the value has to be equal to min or max value. (value == min or value == max).
Improvement
Module now works under a listen server.
Added a check if the engine function Cvar_DirectSet is well found before patching memory.
Module will not load natives and forwards if a signature was not found.
Float value change are no more compared as string. I.e: 1.5 -> 1.50 is no more counted as a change.
Developer
Code a bit cleaned up with a better files organizing.
Look, all is fully documented with examples. You see what does the module exactly, I don't see what I could answer to such question. It's up to you, depending your need, to decide whether it will be useful for your plugins.
] meta list
Currently loaded plugins:
description stat pend file vers src load unlod
[ 1] AMX Mod X RUN - amxmodx_mm.dll v1.8.1.3 ini Start ANY
[ 2] POD-Bot mm RUN - podbot_mm.dll v3.0B20a ini Chlvl ANY
[ 3] Fun RUN - fun_amxx.dll v1.8.1.3 pl1 ANY ANY
[ 4] Engine RUN - engine_amxx.dll v1.8.1.3 pl1 ANY ANY
[ 5] FakeMeta RUN - fakemeta_amxx.dl v1.8.1.3 pl1 ANY ANY
[ 6] CStrike RUN - cstrike_amxx.dll v1.8.1.3 pl1 ANY ANY
[ 7] CSX RUN - csx_amxx.dll v1.8.1.3 pl1 ANY ANY
[ 8] Ham Sandwich RUN - hamsandwich_amxx v1.8.1.3 pl1 ANY ANY
[ 9] Orpheu RUN - orpheu_amxx.dll v2.3 pl1 ANY ANY
[10] Cvar Utilities RUN - cvar_util_amxx.d v1.0.0 pl1 ANY ANY
10 plugi
Quote:
L 04/11/2011 - 23:03:55: [AMXX] Plugin "cvar_utilities_test.amxx" failed to load: Plugin uses an unknown function (name "CvarHookChange") - check your modules.ini
Check the server logs and past the output above the message "Module failed to load. Contact the author". It appears after the metamod/amxmodx message at the very start. If you still don't see the message, try to type in the console server : meta reload Cvar ; the error should appears.
But the error should be either you have not uploaded the module at the right place, or a signature has not been found. If you are sure binary is well uploaded it would be weird ; I've tested the module on the latest engine version and with hlbeta update too with success and all signatures were found.