Get Cvars Changes

For scripting examples for learning how to use AMXX.
User avatar
Archive-Poster
Posts: 1249
Gender:
United States of America

Get Cvars Changes

Post by Archive-Poster »

Only have a little problem with Some Float Returns, Example you put 220.1 the plugin return 220.09999999

PLUGIN:

Code: Select all

// #define USE_FAKEMETA

#include <amxmodx>

#if defined USE_FAKEMETA
#include <fakemeta>
#else
#include <engine>
#endif

new Array:g_CvarHolds
new Array:g_CvarType
new Array:g_CvarFwd
new Array:g_CvarData


public plugin_precache() 
{
    register_plugin("Cvars Change", "1.0", "ReymonARG")
    
    g_CvarHolds = ArrayCreate(1, 1)
    g_CvarType = ArrayCreate(1, 1)
    g_CvarData = ArrayCreate(128, 1)
    g_CvarFwd = ArrayCreate(1, 1)
    
    #if defined USE_FAKEMETA
    register_forward(FM_StartFrame, "server_frame")
    #endif
}

public plugin_natives()
{
    register_library("ReymonARG_Cvars")
    register_native("register_cvar_change", "__cvar_change_add")
    register_native("unregister_cvar_change", "__cvar_change_delete")
}

public __cvar_change_add( iPlugin, iParams )
{
    if( iParams != 3 )
        return log_error(AMX_ERR_NATIVE, "Invalid Params Nums %d", iParams)
        
    static szCvar[64]; get_string(2, szCvar, 63)
    if( !cvar_exists(szCvar) )
        return log_error(AMX_ERR_NATIVE, "Cvar: %s No Exists", szCvar)
        
    static fwd_id, iType; iType = get_param(1)
    static szCallBack[32]; get_string(3, szCallBack, 31)
    
    switch( iType )
    {
        case 1: fwd_id = CreateOneForward(iPlugin, szCallBack, FP_CELL, FP_CELL, FP_CELL)
        case 2: fwd_id = CreateOneForward(iPlugin, szCallBack, FP_CELL, FP_FLOAT, FP_FLOAT)
        case 3: fwd_id = CreateOneForward(iPlugin, szCallBack, FP_CELL, FP_STRING, FP_STRING)
        default: return log_error(AMX_ERR_NATIVE, "%d Dont is a Correct Type Cvar", iType)
    }
    
    if( fwd_id < 0 )
        return log_error(AMX_ERR_NATIVE, "Correct the CallBack Funcion")
        
    
    static pCvar; pCvar = get_cvar_pointer(szCvar)
    ArrayPushCell(g_CvarHolds, pCvar)
    ArrayPushCell(g_CvarType, iType)
    
    switch( iType )
    {
        case 1:
        {
            static iResult; iResult = get_pcvar_num(pCvar)
            ArrayPushCell(g_CvarData, iResult)
        }
        case 2:
        {
            static Float:fResult; fResult = get_pcvar_float(pCvar)
            ArrayPushCell(g_CvarData, fResult)
        }
        case 3:
        {
            static szResult[128]; get_pcvar_string(pCvar, szResult, 127)
            ArrayPushString(g_CvarData, szResult)
        }
    }
    
    ArrayPushCell(g_CvarFwd, fwd_id)
    return fwd_id    
}

public __cvar_change_delete( iPlugin, iParams )
{
    if( iParams != 1 )
        return log_error(AMX_ERR_NATIVE, "Invalid Params Nums %d", iParams)
        
    static i, fwd_id, len; len = ArraySize(g_CvarFwd)
    fwd_id = get_param(1)
    
    for( i = 0; i < len; i++)
    {
        if( ArrayGetCell(g_CvarFwd, i) == fwd_id )
        {
            ArrayDeleteItem(g_CvarHolds, i)
            ArrayDeleteItem(g_CvarType, i)
            ArrayDeleteItem(g_CvarData, i)
            ArrayDeleteItem(g_CvarFwd, i)
            DestroyForward(fwd_id)
            
            return 1
        }
    }
    
    return 0
}

public server_frame()
{
    static i, type, idCvar, iReturn, len; len = ArraySize(g_CvarFwd)
    static iResult[2], Float:fResult[2], szResult[2][128]
    
    for( i = 0; i < len; i++)
    {
        type = ArrayGetCell(g_CvarType, i)
        idCvar = ArrayGetCell(g_CvarHolds, i)
        switch( type )
        {
            case 1:
            {
                iResult[0] = ArrayGetCell(g_CvarData, i)
                iResult[1] = get_pcvar_num(idCvar)
                if( iResult[0] != iResult[1] )
                {
                    static id; id = ArrayGetCell(g_CvarFwd, i)
                    ExecuteForward(id, iReturn, id, iResult[0], iResult[1])
                    
                    if( iReturn )
                    {
                        set_pcvar_num(idCvar, iResult[0])
                        iReturn = 0
                    }
                    else
                    {
                        ArraySetCell(g_CvarData, i, iResult[1])
                    }
                }
            }
            case 2:
            {
                fResult[0] = ArrayGetCell(g_CvarData, i)
                fResult[1] = get_pcvar_float(idCvar)
                if( fResult[0] != fResult[1] )
                {
                    static id; id = ArrayGetCell(g_CvarFwd, i)
                    ExecuteForward(id, iReturn, id, fResult[0], fResult[1])
                    
                    if( iReturn )
                    {
                        set_pcvar_float(idCvar, fResult[0])
                        iReturn = 0
                    }
                    else
                    {
                        ArraySetCell(g_CvarData, i, fResult[1])
                    }
                }
            }
            case 3:
            {
                ArrayGetString(g_CvarData, i, szResult[0], 127)
                get_pcvar_string(idCvar, szResult[1], 127)
                if( !equal(szResult[0], szResult[1]) )
                {
                    static id; id = ArrayGetCell(g_CvarFwd, i)
                    ExecuteForward(id, iReturn, id, szResult[0], szResult[1])
                    
                    if( iReturn )
                    {
                        set_pcvar_string(idCvar, szResult[0])
                        iReturn = 0
                    }
                    else
                    {
                        ArraySetString(g_CvarData, i, szResult[1])
                    }
                }
            }
        }            
    }
} 
INC:

Code: Select all

#if defined _cvarchange_included
  #endinput
#endif
#define _cvarchange_included

#if AMXX_VERSION_NUM >= 175
 #pragma reqlib ReymonARG_Cvars
 #if !defined AMXMODX_NOAUTOLOAD
  #pragma loadlib ReymonARG_Cvars
 #endif
#else
 #pragma library ReymonARG_Cvars
#endif

enum Type
{
    cvarINT = 1,
    cvarFL = 2,
    cvarSZ = 3
}

native register_cvar_change(Type:type, const Cvar[], const CallBack[])
native unregister_cvar_change(fwd_id)
EXAMPLE:

Code: Select all

#include <amxmodx>
#include <cvarchange>

#define PLUGIN "Cvar xD"
#define VERSION "1.0"
#define AUTHOR "ReymonARG"


public plugin_init() 
{
    register_plugin(PLUGIN, VERSION, AUTHOR)
    
    register_cvar_change(cvarINT, "mp_friendlyfire", "ffback")
    register_cvar_change(cvarFL, "kz_min_lj", "ljmin")
    register_cvar_change(cvarSZ, "amx_nextmap", "nextmap")
}

public ffback( id, pre, post)
{
    server_print("%d %d %d", id, pre, post)
    return 1
}

public ljmin( id, Float:pre, Float:post)
{
    server_print("%d %f %f", id, pre, post)
}

public nextmap(id, const pre[], const post[])
{
    server_print("%d %s %s", id, pre, post)
} 
Thanks, Correct me if I do something wrong
Attachments
cvar_change.sma.zip
(1.35 KiB) Downloaded 14 times
cvarchange.inc.zip
(461 Bytes) Downloaded 19 times
cvar_change_test.sma.zip
(466 Bytes) Downloaded 17 times
User avatar
Archive-Poster
Posts: 1249
Gender:
United States of America

Re: Get Cvars Changes

Post by Archive-Poster »

Using such forward which called very often + using dynamic array which are slow + comparing like that, it should eat a lot of cpu for nothing. I don't think it's a good solution. I still prefer to use directly a command if you want to detect a change.
That is right!
I think that it is better to create a menu that allow you to manipulate cvars.
You can take a look at the code of this plugin.
<to be added>

Btw. Are these forwards good?

Code: Select all

	FM_CVarGetFloat,		// float )	(const szCvar[])
	FM_CVarGetString,		// char )	(const szCvar[])
	FM_CVarSetFloat,		// void )	(const szCvar[], Float:fValue)
	FM_CVarSetString,		// void )	(const szCvar[], szValue[])
those forwards wont work, the CVarGet fwds are called when the engine tries to get a cvar (sv_clientrace and sv_aim will spam the console on debug) and the set forwards when the engine sets some cvar. they seem to do not support cvars which are created through amxx.
User avatar
Archive-Poster
Posts: 1249
Gender:
United States of America

Re: Get Cvars Changes

Post by Archive-Poster »

Only have a little problem with Some Float Returns, Example you put 220.1 the plugin return 220.09999999
Same problem =\

<to be added>
User avatar
Archive-Poster
Posts: 1249
Gender:
United States of America

Re: Get Cvars Changes

Post by Archive-Poster »

This is a solution for the problem but a bad one and I fear you won't find a better one. This is basically the one thing I'm so awesomely jealous of SourceMod - ConVar Handles.
Yes, you can find a better one, but it has to be made.
Forwards can be made with a module, or with an update to the current amxmodx module.
I was thinking of this excerpt from the DevLog:

The other major difference is that HL2 engine passes ConVar changes through a callback. Thus, you can detect changes without making a secondary console command. This was not possible in HL1. Although you could hook SET_CVAR_FLOAT, it was not virtual, and thus internal or plugin usage of it would not be caught. Also, the change callbacks are per-ConVar; HL1’s is global, and thus a bit less optimized.
User avatar
Archive-Poster
Posts: 1249
Gender:
United States of America

Re: Get Cvars Changes

Post by Archive-Poster »

Only have a little problem with Some Float Returns, Example you put 220.1 the plugin return 220.09999999
adding a 0 to the end should fix that, ie 220.10
User avatar
Archive-Poster
Posts: 1249
Gender:
United States of America

Re: Get Cvars Changes

Post by Archive-Poster »

Yes, you can find a better one, but it has to be made.
Forwards can be made with a module, or with an update to the current amxmodx module.
MODULE Version, More Faster.

<to be added>
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests