[EN] Activation code not working

Сообщения
47
Реакции
1
Hello, this is the best forum i could find so far with english allowed and active people helping here.
I did a plugin which gives zp_ammo_packs from database and deletes after use of code.
My problem is that it crashes the server when redeeming the code... Anyone could help?

C++:
#include < amxmodx >
#include < hamsandwich >
#include < sqlx >
#include < zombieplague >

new Handle:g_SqlTuple;
new Handle:g_SqlConnection;

new g_iIndexPromoCode
new g_iMoney
new g_szPromoCode[PLATFORM_MAX_PATH]

new const table_name[] = "bank_activate"

new Float:g_lastCodeUseTime;

public plugin_init()
{
    register_plugin("Redeem Plugin", "1.0", "LVNDR");

    register_clcmd("bank_activate", "RedeemCodeCommand");

    g_SqlTuple = SQL_MakeDbTuple("127.0.0.1","root","123","login",1);

    if(g_SqlTuple != Empty_Handle)
    {
        new ErrorCode,Error[32];
        g_SqlConnection = SQL_Connect(g_SqlTuple,ErrorCode,Error,charsmax(Error));
        
        if(g_SqlConnection == Empty_Handle)
        {
            set_fail_state("[%i] %s",ErrorCode,Error);
        }
    }

}

public RedeemCodeCommand(id)
{
    if (get_gametime() - g_lastCodeUseTime < 6)
    {
    client_print(id, print_console, "Wait a bit before using this command...");
    return PLUGIN_HANDLED
    }

    if(read_argc()<2)
    {
        client_print(id, print_console, "Usage: bank_activate <code>");
    }
    else
    {
        g_lastCodeUseTime = get_gametime()

        new szPromoCode[PLATFORM_MAX_PATH]

        read_args(szPromoCode, charsmax(szPromoCode))
        remove_quotes(szPromoCode)
        trim(szPromoCode)

        new szQuery[MAX_FMT_LENGTH]

        formatex(szQuery, charsmax(szQuery), "SELECT * FROM `%s` WHERE `activation_code` = '%s'", table_name, szPromoCode)
        SQL_ThreadQuery(g_SqlTuple, "ActivePromoCode_QueryHandler", szQuery)
    }

    return PLUGIN_HANDLED;
}

public ActivePromoCode_QueryHandler(iFailState, Handle:Query, szError[], iErrNum, data[], size, Float:flQueryTime)
{
    if(iFailState != TQUERY_SUCCESS)
    {
        log_amx("MySQL Error: %d (%s)", iErrNum, szError)
        return
    }

    new id = data[0]

    g_iMoney = 0

    SQL_Execute(Query)
    if(SQL_NumResults(Query) > 0)
    {
        g_iMoney = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "num_ammo_packs"))
        SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "activation_code"), g_szPromoCode, charsmax(g_szPromoCode))
        g_iIndexPromoCode = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "id"))

        set_task(0.5, "func_SuccessfullyActivatingPromocode", id)
    }
    else   {
    client_print(id, print_console, "This code is not valid!"); }

    SQL_FreeHandle(Query)

}

public func_SuccessfullyActivatingPromocode(id)
{
    new szQuery[MAX_FMT_LENGTH]
    new iData[2]

    iData[0] = id

    zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + g_iMoney)
    client_print(id, print_console, "You successfully claimed the code and received your coins!")

    formatex(szQuery, charsmax(szQuery), "DELETE FROM `%s` WHERE `id` = '%d';", table_name, g_iIndexPromoCode)
    SQL_ThreadQuery(g_SqlTuple, "QueryHandler", szQuery, iData, charsmax(iData))
}

public QueryHandler(iFailState, Handle:Query, szError[], iErrNum, data[], size, Float:flQueryTime)
{
    if(iFailState != TQUERY_SUCCESS)
    {
        log_amx("MySQL Error: %d (%s)", iErrNum, szError)
        return
    }
}

public plugin_end()
{
    if (g_SqlConnection) SQL_FreeHandle(g_SqlConnection)
    return;
}
 
Сообщения
673
Реакции
242
Помог
11 раз(а)
More details? where does the error occur? is there any debugging in the log?

at least 81 lines are not required since you have an asynchronous request.
 
Сообщения
47
Реакции
1
No errors. Just crash, seems on
ActivePromoCode_QueryHandler. Well im not that good with amxx, why 81 lines?
 
Сообщения
673
Реакции
242
Помог
11 раз(а)
Foxculated, SQL_Execute(Query) should not be there, SQL_Execute - Executes a pre-prepared query to the database.have you already sent it.

example using SQL_Execute:
Код:
/.../
public sqlx_select(id){
 
    //Request Preparation
    new Handle:query = SQL_PrepareQuery(SQL_Connection,"SELECT * FROM `test`")
    // Making a request to the database of data
    SQL_Execute (query)
/.../
}

Returns 1 if the query succeeded.
Returns 0 if the query failed.
You can call this multiple times as long as its parent connection is kept open. Each time the result set will be freed from the previous call.
6 Май 2023
Также ты не передал аргументы при запросе

сделай так;
Код:
        new sData[1];
        sData[0] = id; //index player
        SQL_ThreadQuery(g_SqlTuple, "ActivePromoCode_QueryHandler", szQuery, , sData, sizeof sData)
6 Май 2023
try:

Код:
#include < amxmodx >
#include < hamsandwich >
#include < sqlx >
//#include < zombieplague >

new Handle:g_SqlTuple;
new Handle:g_SqlConnection;

//new g_iIndexPromoCode

new const table_name[] = "bank_activate"

new Float:g_lastCodeUseTime;

public plugin_init()
{
    register_plugin("Redeem Plugin", "1.0", "LVNDR");

    register_clcmd("bank_activate", "RedeemCodeCommand");

    g_SqlTuple = SQL_MakeDbTuple("127.0.0.1","root","123","login",1);

    if(g_SqlTuple != Empty_Handle)
    {
        new ErrorCode,Error[32];
        g_SqlConnection = SQL_Connect(g_SqlTuple,ErrorCode,Error,charsmax(Error));
        
        if(g_SqlConnection == Empty_Handle)
        {
            set_fail_state("[%i] %s",ErrorCode,Error);
        }
    }

}

public RedeemCodeCommand(id)
{
    if (get_gametime() - g_lastCodeUseTime < 6)
    {
        client_print(id, print_console, "Wait a bit before using this command...");
        return PLUGIN_HANDLED
    }

    if(read_argc()<2)
    {
        client_print(id, print_console, "Usage: bank_activate <code>");
    }
    else
    {
        g_lastCodeUseTime = get_gametime()

        new szPromoCode[PLATFORM_MAX_PATH]

        read_args(szPromoCode, charsmax(szPromoCode))
        remove_quotes(szPromoCode)
        trim(szPromoCode)

        new szQuery[MAX_FMT_LENGTH]

        formatex(szQuery, charsmax(szQuery), "SELECT * FROM `%s` WHERE `activation_code` = '%s'", table_name, szPromoCode)
        
        
        new sData[3];
        sData[0] = id;
        SQL_ThreadQuery(g_SqlTuple, "ActivePromoCode_QueryHandler", szQuery)
    }

    return PLUGIN_HANDLED;
}

public ActivePromoCode_QueryHandler(iFailState, Handle:Query, szError[], iErrNum, data[], size, Float:flQueryTime)
{
    if(iFailState != TQUERY_SUCCESS)
    {
        log_amx("MySQL Error: %d (%s)", iErrNum, szError)
        return
    }

    new id = data[0]

    if(SQL_NumResults(Query))
    {
        zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "num_ammo_packs")))
        

        new g_iIndexPromoCode = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "id"))
        
        new szQuery[MAX_FMT_LENGTH]
        formatex(szQuery, charsmax(szQuery), "DELETE FROM `%s` WHERE `id` = '%d';", table_name, g_iIndexPromoCode)
        SQL_ThreadQuery(g_SqlTuple, "QueryHandler", szQuery)
        
    }
    else   {
        client_print(id, print_console, "This code is not valid!"); }

    SQL_FreeHandle(Query)

}



public QueryHandler(iFailState, Handle:Query, szError[], iErrNum, data[], size, Float:flQueryTime)
{
    if(iFailState != TQUERY_SUCCESS)
    {
        log_amx("MySQL Error: %d (%s)", iErrNum, szError)
        return
    }
}

public plugin_end()
{
    if (g_SqlConnection) SQL_FreeHandle(g_SqlConnection)
    return;
}
6 Май 2023
это если хочешь сделать синхронный запрос;

Код:
public ActivePromoCode_QueryHandler(iFailState, Handle:Query, szError[], iErrNum, data[], size, Float:flQueryTime)
{
    if(iFailState != TQUERY_SUCCESS)
    {
        log_amx("MySQL Error: %d (%s)", iErrNum, szError)
        return
    }

    new id = data[0]

    if(SQL_NumResults(Query))
    {
        zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "num_ammo_packs")))
        

        new g_iIndexPromoCode = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "id"))
        
        new Handle:hQuery = SQL_PrepareQuery(g_SqlConnection, "DELETE FROM `%s` WHERE `id` = '%d';", table_name, g_iIndexPromoCode)
        SQL_Execute(hQuery)
        SQL_FreeHandle(hQuery)
    }
    else   {
        client_print(id, print_console, "This code is not valid!"); }

    SQL_FreeHandle(Query)

}
 
Последнее редактирование:
Сообщения
47
Реакции
1
Do it in this way;
Код:
 new sData[1];
        sData[0] = id; // index player
        SQL_ThreadQuery(g_SqlTuple, "ActivePromoCode_QueryHandler", szQuery, , sData, sizeof sData)
6 Май 2023
try:

Код:
#include <amxmodx>
#include <hamsandwich>
#include <sqlx>
//#include < zombieplague >

new Handle:g_SqlTuple;
new Handle:g_SqlConnection;

//new g_iIndexPromoCode

new const table_name[] = "bank_activate"

new Float:g_lastCodeUseTime;

public plugin_init()
{
    register_plugin("Redeem Plugin", "1.0", "LVNDR");

    register_clcmd("bank_activate", "RedeemCodeCommand");

    g_SqlTuple = SQL_MakeDbTuple("127.0.0.1","root","123","login",1);

    if(g_SqlTuple != Empty_Handle)
    {
        new ErrorCode,Error[32];
        g_SqlConnection = SQL_Connect(g_SqlTuple,ErrorCode,Error,charsmax(Error));
       
        if(g_SqlConnection == Empty_Handle)
        {
            set_fail_state("[%i] %s",ErrorCode,Error);
        }
    }

}

public RedeemCodeCommand(id)
{
    if (get_gametime() - g_lastCodeUseTime < 6)
    {
        client_print(id, print_console, "Wait a bit before using this command...");
        return PLUGIN_HANDLED
    }

    if(read_argc()<2)
    {
        client_print(id, print_console, "Usage: bank_activate <code>");
    }
    else
    {
        g_lastCodeUseTime = get_gametime()

        new szPromoCode[PLATFORM_MAX_PATH]

        read_args(szPromoCode, charsmax(szPromoCode))
        remove_quotes(szPromoCode)
        trim(szPromoCode)

        new szQuery[MAX_FMT_LENGTH]

        formatex(szQuery, charsmax(szQuery), "SELECT * FROM `%s` WHERE `activation_code` = '%s'", table_name, szPromoCode)
       
       
        new sData[3];
        sData[0] = id;
        SQL_ThreadQuery(g_SqlTuple, "ActivePromoCode_QueryHandler", szQuery)
    }

    return PLUGIN_HANDLED;
}

public ActivePromoCode_QueryHandler(iFailState, Handle:Query, szError[], iErrNum, data[], size, Float:flQueryTime)
{
    if(iFailState != TQUERY_SUCCESS)
    {
        log_amx("MySQL Error: %d (%s)", iErrNum, szError)
        return
    }

    new id = data[0]

    if(SQL_NumResults(Query))
    {
        zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "num_ammo_packs")))
       

        new g_iIndexPromoCode = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "id"))
       
        new szQuery[MAX_FMT_LENGTH]
        formatex(szQuery, charsmax(szQuery), "DELETE FROM `%s` WHERE `id` = '%d';", table_name, g_iIndexPromoCode)
        SQL_ThreadQuery(g_SqlTuple, "QueryHandler", szQuery)
       
    }
    else {
        client_print(id, print_console, "This code is not valid!"); }

    SQL_FreeHandle(Query)

}



public QueryHandler(iFailState, Handle:Query, szError[], iErrNum, data[], size, Float:flQueryTime)
{
    if(iFailState != TQUERY_SUCCESS)
    {
        log_amx("MySQL Error: %d (%s)", iErrNum, szError)
        return
    }
}

public plugin_end()
{
    if (g_SqlConnection) SQL_FreeHandle(g_SqlConnection)
    return;
}
6 Май 2023
if you want to make a synchronous request;

Код:
public ActivePromoCode_QueryHandler(iFailState, Handle:Query, szError[], iErrNum, data[], size, Float:flQueryTime)
{
    if(iFailState != TQUERY_SUCCESS)
    {
        log_amx("MySQL Error: %d (%s)", iErrNum, szError)
        return
    }

    new id = data[0]

    if(SQL_NumResults(Query))
    {
        zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "num_ammo_packs")))
       

        new g_iIndexPromoCode = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "id"))
       
        new Handle:hQuery = SQL_PrepareQuery(g_SqlConnection, "DELETE FROM `%s` WHERE `id` = '%d';", table_name, g_iIndexPromoCode)
        SQL_Execute(hQuery)
        SQL_FreeHandle(hQuery)
    }
    else {
        client_print(id, print_console, "This code is not valid!"); }

    SQL_FreeHandle(Query)

}
Thanks for fast reply, but the ammo packs are not added now and client_prints are not shown, mysql errors doesnt seem to be a problem now
 
Сообщения
673
Реакции
242
Помог
11 раз(а)
Foxculated сделай импорт таблицы БД

ну да, я же не поставил логирование:


попробуй

Код:
if(SQL_NumResults(Query))
    {
        new Money = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "num_ammo_packs"))
        zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + Money)
   
           log_amx("%d", Money)

     
client_print(id, print_console, "You successfully claimed the code and received your coins!")


        new g_iIndexPromoCode = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "id"))
   
        new Handle:hQuery = SQL_PrepareQuery(g_SqlConnection, "DELETE FROM `%s` WHERE `id` = '%d';", table_name, g_iIndexPromoCode)
        SQL_Execute(hQuery)
        SQL_FreeHandle(hQuery)
    }
 
Сообщения
47
Реакции
1
Foxculated сделай импорт таблицы БД

ну да, я же не поставил логирование:


попробуй

Код:
if(SQL_NumResults(Query))
    {
        new Money = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "num_ammo_packs"))
        zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + Money)
 
           log_amx("%d", Money)

   
client_print(id, print_console, "You successfully claimed the code and received your coins!")


        new g_iIndexPromoCode = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "id"))
 
        new Handle:hQuery = SQL_PrepareQuery(g_SqlConnection, "DELETE FROM `%s` WHERE `id` = '%d';", table_name, g_iIndexPromoCode)
        SQL_Execute(hQuery)
        SQL_FreeHandle(hQuery)
    }
Thanks i managed to screw the script up already... Why does it say that Invalid player (0) in console?
And
Run time error 10: native error (native "zp_get_user_ammo_packs")
[AMXX] [0] zp_bank_activate.sma::ActivePromoCode_QueryHandler
Код:
public ActivePromoCode_QueryHandler(iFailState, Handle:Query, szError[], iErrNum, data[], size, Float:flQueryTime)
{
    if(iFailState != TQUERY_SUCCESS)
    {
        log_amx("MySQL Error: %d (%s)", iErrNum, szError)
        return
    }
   
    new szAuthID[MAX_AUTHID_LENGTH]
    get_user_authid(id, szAuthID, charsmax(szAuthID))
    new name[33]
    get_user_name(id,name,32)

    new szPromoCode[PLATFORM_MAX_PATH]

    read_args(szPromoCode, charsmax(szPromoCode))
    remove_quotes(szPromoCode)
    trim(szPromoCode)

    if(SQL_NumResults(Query))
    {
        new Money = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "num_ammo_packs"))
        zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + Money)
 
        log_to_file(g_szPromoCodeLog, "%s activated code ( SteamID: %s | Code: %s | Ammo packs: %d )", name, szAuthID, szPromoCode, Money)

        client_print(id, print_console, "Code %s activated, you got %i coins!", szPromoCode, Money)


        new g_iIndexPromoCode = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "id"))
 
        new Handle:hQuery = SQL_PrepareQuery(g_SqlConnection, "DELETE FROM `%s` WHERE `id` = '%d';", table_name, g_iIndexPromoCode)
        SQL_Execute(hQuery)
        SQL_FreeHandle(hQuery)
    }
    else   {
        client_print(id, print_console, "Code not found!"); }

    SQL_FreeHandle(Query)

}
 
Сообщения
893
Реакции
149
Помог
25 раз(а)
add
C++:
if(!is_user_connected(id))
return;
after
Код:
new id = data[0]
 
Сообщения
47
Реакции
1
Код:
#include < amxmodx >
#include < hamsandwich >
#include < sqlx >
#include < zombieplague >

new Handle:g_SqlTuple;
new Handle:g_SqlConnection;

#define MAX_PLAYERS 32

new const g_szPromoCodeLog[] = "bank_activate.log"

new const table_name[] = "bank_activate"

new CvarCooldown
new Float:CommandNextTime[MAX_PLAYERS+1]

public plugin_init()
{
    register_plugin("Redeem Plugin", "1.0", "LVNDR");

    register_clcmd("bank_activate", "RedeemCodeCommand");

    CvarCooldown = register_cvar("bank_activate", "15")

    g_SqlTuple = SQL_MakeDbTuple("127.0.0.1","root","123","login",1);

    if(g_SqlTuple != Empty_Handle)
    {
        new ErrorCode,Error[32];
        g_SqlConnection = SQL_Connect(g_SqlTuple,ErrorCode,Error,charsmax(Error));
        
        if(g_SqlConnection == Empty_Handle)
        {
            set_fail_state("[%i] %s",ErrorCode,Error);
        }
    }

}

public RedeemCodeCommand(id)
{
    if(read_argc()<2)
    {
        client_print(id, print_console, "Usage: bank_activate <code>");
        return PLUGIN_HANDLED;
    }

    new Float:gametime = get_gametime()
    new Float:command_next_time = CommandNextTime[id]

    if( gametime < command_next_time )
    {
        new Float:timeleft = command_next_time - gametime
        client_print(id, print_console, "Please wait %.0f seconds to use this command again!", timeleft)

        return PLUGIN_HANDLED;
    }

    CommandNextTime[id] = gametime + get_pcvar_float(CvarCooldown)

    new szPromoCode[PLATFORM_MAX_PATH]

    read_args(szPromoCode, charsmax(szPromoCode))
    remove_quotes(szPromoCode)
    trim(szPromoCode)

    new szQuery[MAX_FMT_LENGTH]

    formatex(szQuery, charsmax(szQuery), "SELECT * FROM `%s` WHERE `activation_code` = '%s'", table_name, szPromoCode)

    new sData[3];
    sData[0] = id;
    SQL_ThreadQuery(g_SqlTuple, "ActivePromoCode_QueryHandler", szQuery)
    return PLUGIN_HANDLED;
}

public ActivePromoCode_QueryHandler(iFailState, Handle:Query, szError[], iErrNum, data[], size, Float:flQueryTime)
{
    if(iFailState != TQUERY_SUCCESS)
    {
        log_amx("MySQL Error: %d (%s)", iErrNum, szError)
        return
    }

    new id = data[0]
    new szAuthID[MAX_AUTHID_LENGTH]
    get_user_authid(id, szAuthID, charsmax(szAuthID))
    new name[33]
    get_user_name(id,name,32)

    new szPromoCode[PLATFORM_MAX_PATH]

    read_args(szPromoCode, charsmax(szPromoCode))
    remove_quotes(szPromoCode)
    trim(szPromoCode)

    if(!is_user_connected(id))
    return;

    if(SQL_NumResults(Query))
    {
        new Money = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "num_ammo_packs"))
        zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + Money)
  
        log_to_file(g_szPromoCodeLog, "%s activated code ( SteamID: %s | Code: %s | Ammo packs: %d )", name, szAuthID, szPromoCode, Money)

        client_print(id, print_console, "Code %s activated, you got %i coins!", szPromoCode, Money)


        new g_iIndexPromoCode = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "id"))
  
        new Handle:hQuery = SQL_PrepareQuery(g_SqlConnection, "DELETE FROM `%s` WHERE `id` = '%d';", table_name, g_iIndexPromoCode)
        SQL_Execute(hQuery)
        SQL_FreeHandle(hQuery)
    }
    else   {
        client_print(id, print_console, "Code is not found!"); }

    SQL_FreeHandle(Query)

}



public QueryHandler(iFailState, Handle:Query, szError[], iErrNum, data[], size, Float:flQueryTime)
{
    if(iFailState != TQUERY_SUCCESS)
    {
        log_amx("MySQL Error: %d (%s)", iErrNum, szError)
        return
    }
}

public plugin_end()
{
    if (g_SqlConnection) SQL_FreeHandle(g_SqlConnection)
    return;
}
 
Сообщения
893
Реакции
149
Помог
25 раз(а)
Diff:
-new sData[3];
-SQL_ThreadQuery(g_SqlTuple, "ActivePromoCode_QueryHandler", szQuery)

+new sData[1];
+SQL_ThreadQuery(g_SqlTuple, "ActivePromoCode_QueryHandler", szQuery, sData, sizeof(sData))
Try.
 
Сообщения
893
Реакции
149
Помог
25 раз(а)
Глобальную CommandNextTime[MAX_PLAYERS + 1] можно заменить на локальную, так как у тебя она используется только в одном месте.
Следовательно, её можно удалить, и потом поправить таймер:
Diff:
-new Float:gametime = get_gametime()
-new Float:command_next_time = CommandNextTime[id]

-if( gametime < command_next_time )
-new Float:timeleft = command_next_time - gametime
-CommandNextTime[id] = gametime + get_pcvar_float(CvarCooldown)

+static Float:gametime; gametime = get_gametime()
+static Float:command_nex_time[33];

+if( command_nex_time[id] >= gametime )
+new Float:timeleft = command_next_time[id] - gametime
+command_next_time[id] = gametime + get_pcvar_float(CvarCooldown)
И получается следующий таймер:
C++:
    static Float:gametime; gametime = get_gametime()
    static Float:command_next_time[33];

    if( command_next_time[id] >= gametime )
    {
        new Float:timeleft = command_next_time[id] - gametime
        client_print(id, print_console, "Please wait %.0f seconds to use this command again!", timeleft)

        return PLUGIN_HANDLED;
    }

    command_next_time[id] = gametime + get_pcvar_float(CvarCooldown)
C++:
#include <amxmodx>
#include <zombieplague>
#include <sqlx>
enum any: CvarsStruction
{
    CVAR_SQL_HOST[256],
    CVAR_SQL_USER[256],
    CVAR_SQL_PASS[256],
    CVAR_SQL_DBNAME[256],
    CVAR_SQL_TABLE[256],
    Float: CVAR_COOLDOWN
};
new Handle: g_hSqlTuple;
new Handle: g_hSqlConnection;
new const g_szPromoCodeLog[] = "bank_activate.log";
new g_pCvars[CvarsStruction];
public plugin_init()
{
    register_plugin("Redeem Plugin", "1.0.1", "LVNDR / AmxModX");
    register_clcmd("bank_activate", "RedeemCodeCommand");
   
    CreateCvar();
}
CreateCvar()
{
    bind_pcvar_string(create_cvar("promo_sql_host", "localhost", FCVAR_PROTECTED, "MySQL LocalHost Name"), g_pCvars[CVAR_SQL_HOST], charsmax(g_pCvars[CVAR_SQL_HOST]));
    bind_pcvar_string(create_cvar("promo_sql_user", "root", FCVAR_PROTECTED, "MySQL User Name."), g_pCvars[CVAR_SQL_USER], charsmax(g_pCvars[CVAR_SQL_USER]));
    bind_pcvar_string(create_cvar("promo_sql_password", "123", FCVAR_PROTECTED, "MySQL Password."), g_pCvars[CVAR_SQL_PASS], charsmax(g_pCvars[CVAR_SQL_PASS]));
    bind_pcvar_string(create_cvar("promo_sql_dbname", "login", FCVAR_PROTECTED, "MySQL DataBase Name."), g_pCvars[CVAR_SQL_DBNAME], charsmax(g_pCvars[CVAR_SQL_DBNAME]));
    bind_pcvar_string(create_cvar("promo_sql_table", "bank_activate", FCVAR_PROTECTED, "MySQL Table Name."), g_pCvars[CVAR_SQL_TABLE], charsmax(g_pCvars[CVAR_SQL_TABLE]));
    bind_pcvar_float(create_cvar("promo_cooldown", "15.0", FCVAR_SERVER, "Cooldown to usage next promocode."), g_pCvars[CVAR_COOLDOWN]);
    AutoExecConfig(true, "PromocodeSettings");

    TrySqlConnect();
}
public TrySqlConnect()
{
    g_hSqlTuple = SQL_MakeDbTuple(
        g_pCvars[CVAR_SQL_HOST], g_pCvars[CVAR_SQL_USER], g_pCvars[CVAR_SQL_PASS], g_pCvars[CVAR_SQL_DBNAME], 1
    );
    if(g_hSqlTuple != Empty_Handle)
    {
        new iErrorCode, szError[32];
        g_hSqlConnection = SQL_Connect(g_hSqlTuple,iErrorCode, szError, charsmax(szError));
       
        if(g_hSqlConnection == Empty_Handle)
        {
            set_fail_state("[%i] %s", iErrorCode, szError);
        }
    }
}
public RedeemCodeCommand(UserId)
{
    if(read_argc() < 2)
    {
        console_print(UserId, "Usage: bank_activate <code>");
        return PLUGIN_HANDLED;
    }
    static Float: flUserCommandNextTime[MAX_PLAYERS + 1];
    static Float: flGametime; flGametime = get_gametime();
    if(flUserCommandNextTime[UserId] >= flGametime)
    {
        new Float:timeleft = flUserCommandNextTime[UserId] - flGametime;
        console_print(UserId, "Please wait %.0f seconds to use this command again!", timeleft);
        return PLUGIN_HANDLED;
    }
    flUserCommandNextTime[UserId] = flGametime + g_pCvars[CVAR_COOLDOWN];
    new szPromoCode[PLATFORM_MAX_PATH];
    read_args(szPromoCode, charsmax(szPromoCode));
    remove_quotes(szPromoCode);
    trim(szPromoCode);
    new szQuery[MAX_FMT_LENGTH];
    formatex(szQuery, charsmax(szQuery), "SELECT * FROM `%s` WHERE `activation_code` = '%s'", g_pCvars[CVAR_SQL_TABLE], szPromoCode);
    new sData[3];
    sData[0] = UserId;
    SQL_ThreadQuery(g_hSqlTuple, "ActivePromoCode_QueryHandler", szQuery, sData, sizeof(sData));
    return PLUGIN_HANDLED;
}
public ActivePromoCode_QueryHandler(iFailState, Handle:Query, szError[], iErrNum, data[], size, Float:flQueryTime)
{
    if(iFailState != TQUERY_SUCCESS)
    {
        log_amx("MySQL Error: %d (%s)", iErrNum, szError);
        return;
    }
    new UserId = data[0];
    new szAuthID[MAX_AUTHID_LENGTH], szPromoCode[PLATFORM_MAX_PATH];
    get_user_authid(UserId, szAuthID, charsmax(szAuthID));
    read_args(szPromoCode, charsmax(szPromoCode));
    remove_quotes(szPromoCode);
    trim(szPromoCode);
    if(is_user_connected(UserId))
    {
        if(SQL_NumResults(Query))
        {
            new Money = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "num_ammo_packs"));
            zp_set_user_ammo_packs(UserId, zp_get_user_ammo_packs(UserId) + Money);
     
            log_to_file(g_szPromoCodeLog, "%n activated code ( SteamID: %s | Code: %s | Ammo packs: %d )", UserId, szAuthID, szPromoCode, Money);
            console_print(UserId, "Code %s activated, you got %i coins!", szPromoCode, Money);
            new iIndexPromoCode = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "id"));
            new Handle:hQuery = SQL_PrepareQuery(g_hSqlConnection, "DELETE FROM `%s` WHERE `id` = '%d';", g_pCvars[CVAR_SQL_TABLE], iIndexPromoCode);
            SQL_Execute(hQuery);
            SQL_FreeHandle(hQuery);
        }
        else
        {
            console_print(UserId, "Code is not found!");
        }
    }
    SQL_FreeHandle(Query);
}
public QueryHandler(iFailState, Handle:Query, szError[], iErrNum, data[], size, Float:flQueryTime)
{
    if(iFailState != TQUERY_SUCCESS)
    {
        log_amx("MySQL Error: %d (%s)", iErrNum, szError);
        return;
    }
}
public plugin_end()
{
    if(g_hSqlConnection)
    {
        SQL_FreeHandle(g_hSqlConnection);
    }
   
    return;
}
Возможно, можно и лучше, хочу услышать критику.
 
Сообщения
1,082
Реакции
58
Помог
11 раз(а)
ImmortalAmxx, а что дала замена new на static? Если ты не используешь старое значение этой переменной, ты же получаешь каждый раз новое!
 
Сообщения
893
Реакции
149
Помог
25 раз(а)
Code_0xABC, Объясняю. Используя new мы каждый раз передаём новое знание, и следовательно, проверка не будет срабатывать, потому-что она будет получать каждый раз новое значение и записывать его, в то время как static сохраняет старое значение.
К примеру взять код:
C++:
public CheckInfo(UserId)
{
    new nMassive[33];
    static sMassive[33];
   
    nMassive[UserId]++;
    sMassive[UserId]++;

    console_print(UserId, "%i | %i", nMassive[UserId], sMassive[UserId]);
}

// nMassive[UserId] всегда будет 1, в то время как sMassive[UserId] будет прибавлять каждый раз новое значение, так же и со временем.
Ты сам можешь сравнить код используя new и static.

К тому-же, после проверки, идёт установка нового значения в массив каждого игрока:
C++:
command_next_time[id] = gametime + get_pcvar_float(CvarCooldown)
 
Сообщения
57
Реакции
10
Обратите внимание, если вы хотите заключить сделку с этим пользователем, он заблокирован
ImmortalAmxx, да он сам порой пытается что то внедрить, о чем сам не понимает 😂пока ему знающие люди не тыкнут
 
Сообщения
893
Реакции
149
Помог
25 раз(а)
ImmortalAmxx,
1683637319907.png
1683637329510.png
1683637398423.png
1683637533677.png
1683637422736.png
P.S, командЫ!*
Думаю, все вопросы отпали.
 
Сообщения
1,082
Реакции
58
Помог
11 раз(а)
ImmortalAmxx, я в курсах, чем отлечаются переменные :rofl:, где тут переменная принимает старое значение????? Я конкретно про его код.
Код:
new Float:gametime = get_gametime()
new Float:command_next_time = CommandNextTime[id]
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу