Сохранение по nvault не работает.

Сообщения
36
Реакции
1
Обратите внимание, если вы хотите заключить сделку с этим пользователем, он заблокирован
Не работает сохранение по Nvault. Нужно сохранить переменную(массив). После смены карты не сохраняется. Вроде правильно сделал, закрываю в plugin_end(), увы не работает.
 

Вложения

Сообщения
956
Реакции
51
Помог
10 раз(а)
cqkjd, а как ты определил что не сохраняет, надо же до последнего излогать свою мысль. Покажи как ты в дальнейшем используешь сохранение! Хотя я догадываюсь уже
1. formatex - форматирует строку а не число. (судя по этому?! vaultdata[MAX_PLAYERS+1])
2. new num = nvault_get(g_nvault, sVaultKey); вернем число
3.
Код:
-
public native_zp_get_user_exp(id)
    return Exp[id];

+
public native_zp_get_user_exp()
    return Exp[get_param(1)];
Применяем натив в плагине 'b'
native zp_get_user_exp(index);
 
Последнее редактирование:
Сообщения
336
Реакции
174
Помог
11 раз(а)
cqkjd,

Код:
//================================================
// Планы:
//  1) Система уровней
//  2) Бонусы при новых уровнях
//================================================



#include <amxmodx>
#include <zombieplague>
#include <nvault>
#define TASK_ID__READ_DATA      9992
new Exp[MAX_PLAYERS+1];
new g_nvault = INVALID_HANDLE;
public plugin_init()
{
    register_plugin("-", "1.0 Beta", "uYoxq");
    
    register_clcmd("say /give", "GiveExp");
}
public plugin_end()
    nvault_close(g_nvault);
public plugin_cfg() {
    g_nvault = nvault_open("zp_advLevelSystem");
    //Останавливаем плагин, если не удалось открыть бд.
    if(g_nvault == INVALID_HANDLE)
        set_fail_state("Не удалось открыть nVault: zp_advLevelSystem");
}
public plugin_natives(){
    register_native("zp_get_user_exp", "native_zp_get_user_exp", 1);
}
public native_zp_get_user_exp(id) {
    return Exp[id];
}
public GiveExp(id) {
    Exp[id] += 100;
}
/*
Вместо 'client_connect', лучше использовать 'client_putinserver()' + задержку. Чтобы быть точно уверенным
в том, что на момент проверки игрок подключился к серверу.
*/
public client_putinserver(id) {
    /* LoadData(id); */
    Exp[id] = 0;
    remove_task(id+TASK_ID__READ_DATA);
    set_task(0.5,"TaskFunc__LoadData",id+TASK_ID__READ_DATA);
}
public TaskFunc__LoadData(id) {
    //Получаем индекс зашедшего игрока
    id -= TASK_ID__READ_DATA;
    //Если игрок отключен - игнорируем
    if(!is_user_connected(id))
        return;
    
    LoadData(id);
}
public client_disconnected(id) {
    SaveData(id);
}
    
public SaveData(id) // <== Функция сохранения денег
{
    new SteamID[64]/* SteamID[35] */ // <== Массив для хранения Steam_ID игрока(Используем размерность 64)
    get_user_authid(id, SteamID, charsmax(SteamID)) // <== Получаем тот самый Steam_ID игрока, и сохраняем его в массиве SteamID
    // Ниже получаем деньги игрока:
    new szData[64];
    //Форматируем число в строку
    formatex(szData,charsmax(szData),"%i",Exp[id]);
    //Записываем/обновляем запись в БД по ключу(в нашем случае стим)
    nvault_set(g_nvault,SteamID,szData);
}
// Берём данные с файла 'zp_advLevelSystem.vault'
public LoadData(id) // <== Функция загрузки денег
{
    new SteamID[64]/* SteamID[35] */ // <== Всё тот же, только новый массив для хранения стим айди игрока(Используем размерность 64)
    get_user_authid(id, SteamID, charsmax(SteamID)) // <== Тут тоже всё тоже самое что и в сохранении денег, получаем steam_id игрока
    new szData[64];
    //Ставим условие, для выполнения которго в БД должна быть запись с указанным стимид
    if(nvault_get(g_nvault,SteamID,szData,charsmax(szData))) {
        //Если запись верна
        //Задаём переменной 'Exp' значение.
        //Важно понимать, что там это строка, а мы используем число, поэтому конвертируем строку в число
        Exp[id] = str_to_num(szData);
        //Обновляем время записи(понадобится, если вдруг захочешь использовать 'nvault_prune')
        nvault_touch(g_nvault,SteamID);
    }
}
26 Мар 2023
2. new num = nvault_get(g_nvault, sVaultKey); вернем число
Внимательно читаем описание натива и то что он возвращает.
 

Download all Attachments

Сообщения
327
Реакции
289
Помог
9 раз(а)
Внимательно читаем описание натива и то что он возвращает.
Возвращает число, если указаны только первые 2 аргумента. В чем непонимание? Все верно вам сказали.
У вас..:
set_task(0.5,"TaskFunc__LoadData",id+TASK_ID__READ_DATA); это зачем?
/* Вместо 'client_connect', лучше использовать 'client_putinserver()' + задержку. Чтобы быть точно уверенным в том, что на момент проверки игрок подключился к серверу. */
а потом..
if(!is_user_connected(id)) return;
Типа, все еще не уверен, что "..на момент проверки игрок подключился к серверу. " ?
 
Сообщения
336
Реакции
174
Помог
11 раз(а)
zhorzh78,
1. Виноват. Не так прочёл.
2. Да, бывают моменты когда игрок выходит сразу же после подключения. Лично у меня бывали такого рода баги. Помогло их исправить задержка в 0.5 или больше. Или же RequestFrame
 
Сообщения
956
Реакции
51
Помог
10 раз(а)
AUF, а для чего тут проверка на то что, id равно от 1 до 32?
Код:
public _get_player_bonus(plugin_id, params)
{
    new id = get_param(1)
    CHECK_PLAYERRANGE(id)

    return g_arrData[id][Bonus]
}
Если игрок выйдет, значение уже равно 0 автоматом, по твоему коду
26 Мар 2023
zhorzh78, +5)
 

AUF

Сообщения
67
Реакции
10
Code_0xABC, у AES подглядел)
C++:
public _aes_get_player_bonus(id)
{
    CHECK_PLAYER(id)
    return player_data[id][PLAYER_BONUS];
}
 
Сообщения
956
Реакции
51
Помог
10 раз(а)
AUF, это не упрек, просто интересно мнение разных пользователей данного форума))
 

AUF

Сообщения
67
Реакции
10
Code_0xABC, я тоже хотел бы знать как оно всё таки правильно будет)
 
Сообщения
956
Реакции
51
Помог
10 раз(а)
AUF, смотри, ты допустим во вторичном плагине обращаешся к 'переменой' с помощью натива get_player_bonus(id) для того что бы вернуть значение массива g_arrData[id] с первого плагина, допустим игрок вышел, и массив g_arrData[id] будет равен 0, для чего нам проверять игрока на 'валидность'? В любом случае у нас массив g_arrData[0..32], извеняюсь если неккоректно объяснил)
В твоем варианте в любом случае вернет либо 0, либо значение массива
 
Последнее редактирование:

AUF

Сообщения
67
Реакции
10
Code_0xABC, да это не мой вариант. я с aes стырил. я понял о чем ты говоришь) проверка на is_user_connected нужна будет? где-то читал что если вызывать нативы без проверок то могут быть ошибки. да и много плагинов пересмотрел я и там 2 варианта обычно
1)
C++:
new id = get_param(1)
CHECK_PLAYERRANGE(id)
2)
C++:
new id = get_param(1)
if (!is_user_connected(id))
{
    log_error(AMX_ERR_NATIVE, "Client %d not connected or index out of range!", id)
    return 0
}
 
Сообщения
857
Реакции
144
Помог
25 раз(а)
Code_0xABC, обычно, если натив вызывают из меню, где находятся все игроки, когда игрок выходит, он остается в меню, и если под его айди не зайдут, плагин выдаст ошибку, именно по этому идёт проверка на коннект игрока.
 
Сообщения
956
Реакции
51
Помог
10 раз(а)
ImmortalAmxx, он возвращает значение ячейки из массива, причем тут счас про меню?
 
Сообщения
702
Реакции
475
Помог
10 раз(а)
лучше уточнить на чем вообще проверяется плагин, может быть он на линуксе тестит и прав на папку у него нет
27 Мар 2023
1679895389279.png
а, ну да
данные кто расчехлять будет
 

Вложения

Сообщения
494
Реакции
340
Помог
11 раз(а)
cqkjd, при смене карты вызов сохранения данных в client_disconnected не сохраняет зачастую (или закрывается через nvault_close быстрее, чем client_disconnected вызывается, или прав уже нет на запись).

Делал как-то шаблон, можешь подогнать под себя. Дополнительно сохраняю данные в старте раунда. Обычно в мапчузерах смену карты делают в старте раунда с задержкой. Такой вариант идеально подходит, чтобы перед сменой карты сохранять данные в nvault.
Код:
#include <amxmodx>
#include <nvault>
#include <reapi>

// дефолтное значение при первом заходе на сервер (если нет записей в nvault для данного игрока)
const DATA_VALUE_DEFAULT = 10;

// nvault settings
#define PRUNE_DAYS 30    // Сколько дней хранить записи в nvault.
#define SECONDS_IN_DAY    86400

// дескриптор открытого соединения nvault
new g_nVault;

// тестовый массив, который будет хранить данные в nvault для игроков
new g_iTestValue[MAX_PLAYERS+1];

public plugin_init()
{
    g_nVault = nvault_open("_vault_data_test");
    
    if(g_nVault == INVALID_HANDLE)
        log_amx("Ошибка при открытии файла nvault");
    else
    {
        RegisterHookChain(RG_CSGameRules_RestartRound, "CSGameRules_RestartRound_Post", true);

        nvault_prune(g_nVault, 0, get_systime() - (PRUNE_DAYS * SECONDS_IN_DAY));
    }
}

public plugin_end()
{
    if(g_nVault != INVALID_HANDLE)
        nvault_close(g_nVault);
}

public client_disconnected(pPlayer)
{
    if(g_nVault == INVALID_HANDLE || is_user_bot(pPlayer) || is_user_hltv(pPlayer))
        return;

    nvault_data_save(pPlayer);
}

public client_putinserver(pPlayer)
{
    if(g_nVault == INVALID_HANDLE || is_user_bot(pPlayer) || is_user_hltv(pPlayer))
        return;

    new szAuthID[MAX_AUTHID_LENGTH];
    get_user_authid(pPlayer, szAuthID, charsmax(szAuthID));

    new szData[8], iTimeStamp;

    if(nvault_lookup(g_nVault, szAuthID, szData, charsmax(szData), iTimeStamp))
        g_iTestValue[pPlayer] = str_to_num(szData);
    else
        g_iTestValue[pPlayer] = DATA_VALUE_DEFAULT;
}

public CSGameRules_RestartRound_Post()
{
    new
        pPlayers[MAX_PLAYERS],
        iPlayersCount;

    get_players(pPlayers, iPlayersCount, "ch");

    for(new i; i < iPlayersCount; i++)
        nvault_data_save(pPlayers[i]);
}

public nvault_data_save(pPlayer)
{
    new szAuthID[MAX_AUTHID_LENGTH];
    get_user_authid(pPlayer, szAuthID, charsmax(szAuthID));

    nvault_set(g_nVault, szAuthID, fmt("%i", g_iTestValue[pPlayer]));
}
 

Вложения

Сообщения
580
Реакции
338
Предупреждения
1
Помог
9 раз(а)
bizon, steamid можно и закешировать
 

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

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