Русское сообщество по скриптингу

Работа с системой nVault

Статьи или фрагменты кода для новичков и уже опытных скриптеров по AMXX.

Модератор: Chuvi

Правила форума
1. Запрещено материться и оскорблять других участников форума.
2. Запрещен флуд, оффтоп, дабл постинг во всех разделах форума, кроме раздела "Болтовня".
3. Запрещено взламывать сайт/форум или наносить любой вред проекту.
4. Запрещено рекламировать другие ресурсы.
5. Запрещено создавать темы без информативного названия. Название темы должно отображать ее смысл.

В данном разделе форума разрешено создавать темы, касающие только обучающему материалу по AMX Mod X.

Работа с системой nVault

Сообщение DJ_WEST » 24 авг 2010, 12:11

Автор: Bugsy
Перевод и редактирование: DJ_WEST

1. Вступление.
nVault - это AMXX инструмент, предназначенный для простого хранения и извлечения данных из файла. Данная система может пригодится, если вам необходимо сохранять какие-то данные в плагине, которые должны быть доступны посме смены карты или перезапуска сервера. nVault хранит данные, используя систему "ключей". Каждая часть данных, которые вы сохраняете, имеет уникальный ключ, с помощью которого к ним затем можно обратиться. Данные и ключ всегда строкового типа, когда вы их сохраняете, но при извлечении данные можно получать в целочисленном типе (integer), с плавающей точкой (float) или как строку (string). Данные сохраняются в nvault файл в двоичном (бинарном) формате, а не в текстовом. Это означает, что вы не можете редактировать данные в своем любимом текстовом редакторе. Для этого можно использовать Вы должны зарегистрироваться, чтобы видеть ссылки..

2. Список функций.
[pawn]nvault_open(const name[]) [/pawn]
Открыть файл с данными по имени.

[pawn]nvault_close(vault) [/pawn]
Закрыть файл с данными.

[pawn]nvault_lookup(vault, const key[], value[], maxlen, &timestamp) [/pawn]
Данная функция производит поиск указанного значения для получения полной информации.

[pawn]nvault_get(vault, const key[], ...) [/pawn]
Получить значение по ключу в integer, float или string.

[pawn]nvault_set(vault, const key[], const value[]) [/pawn]
Записать значение по ключу с текущей временной меткой (timestamp).

[pawn]nvault_pset(vault, const key[], const value[]) [/pawn]
Записать значение по ключу без временной метки (timestamp).

[pawn]nvault_touch(vault, const key[], [ timestamp = -]) [/pawn]
Функция для обновления временной метки (timestamp) указанного ключа.

[pawn]nvault_prune(vault, start , end) [/pawn]
Удалить данные с указанным интервалом временных меток (timestamp). Данная функция не затрагивает значения, установленные с помощью nvault_pset.

[pawn]nvault_remove(vault, const key[]) [/pawn]
Функция для удаления записи по указанному ключу.

3. Использование функций.
  • nvault_open
    Перед тем, как начать работать с nVault, нам необходимо открыть файл. Для этого мы будем использовать функцию nvault_open. Данная функция содержит один строковый аргумент, который означает имя необходимого файла (имя_файла.vault). Если указанного файла не существует, то он будет создан автоматически в директории ../data/vault. Функция nvault_open() после ее вызова возвращает указатель (handle), который затем используется в других nvault функциях. Если при вызове функции nvault_open(), файл не удалось открыть или создать, то она вернут значение -1 (INVALID_HANDLE), поэтому лучше всего проверять открылся ли файл корректно, перед тем как использовать другие функции.
    Пример:
    [pawn]new i_Vault = nvault_open("testvault")

    if (i_Vault == INVALID_HANDLE)
        set_fail_state("Error opening nVault file!") [/pawn]
  • nvault_close
    Данная функция предназначена для закрытия файла. Функция имеет всего один аргумент - это указатель на nvault файл. После закрытия файла вы не сможете выполнять какие-либо действия, пока не откроете его снова. В большинстве случаев лучше всего использовать nvault_close() в функции plugin_end(). Неуспешное закрытие файла может привести к порче и потери данных.
    Пример:
    [pawn]new i_Vault = nvault_open("testvault")

    nvault_close(i_Vault) [/pawn]
  • nvault_lookup
    Данная функция будет искать данные, используя ключ, указанный во втором аргументе, и разместит данные в третьем аргументе, используя максимальный размер, указанный в четвертом аргументе. Если данные найдены, то функция вернет 1 (true), если нет - 0 (false). Временная метка (timestamp) создания данных или последнего их прикосновения (nvault_touch), будет храниться в пятом аргументе.
    Пример:
    [pawn]
    new s_AuthID
    [35], s_Data[30], i_Timestamp, i_Vault, i_DataExists

    // Получаем Steam ID игрока
    get_user_authid(id, s_AuthID, charsmax(s_AuthID))
    // Открываем файл testvault.vault
    i_Vault = nvault_open("testvault")
    // Ищем данные, используя Steam ID в качестве ключа
    i_DataExists = nvault_lookup(i_Vault, s_AuthID, s_Data, charsmax(s_Data) , i_Timestamp)

    // Если данные найдены, то выполняем код
    if (i_DataExists)
        client_print(id, print_chat, "Data=%s Timestamp=%d", s_Data, i_Timestamp)
    else
        client_print(id, print_chat, "No entry found with key %s", s_AuthID)
     [/pawn]
  • nvault_get
    Данная функция очень похожа на nvault_lookup, а именно она тоже ищет и возвращает данные. Однако nvault_get более гибкая, чем nvault_lookup, потому что она позволяет получать данные в различных типах, а не только в строковом. Поэтому вам не прийдется преобразовывать, к примеру, полученную строку с помощью nvault_lookup в целочисленное значение. Запомните, что nvault_get не позволяет получать временную метку данных (timestamp), поэтому если вам нужен timestamp, то нужно использовать функцию nvault_lookup.
    Пример:
    [pawn]
    new i_Vault
    , s_AuthID[35], s_Data[30]

    i_Vault = nvault_open("testvault")
    get_user_authid(id, s_AuthID, charsmax(s_AuthID))

    // Для получения данных в integer типе
    new i_Number
    i_Number 
    = nvault_get(i_Vault, s_AuthID)

    // Для получения данных в float типе
    new Float:f_Value
    nvault_get
    (i_Vault, s_AuthID, f_Value)

    // Для получения данных в string типе
    new s_Data[10]
    nvault_get(i_Vault, s_AuthID, s_Data, charsmax(s_Data)) [/pawn]
  • nvault_set
    Данная функция предназначена для записи данных, а также текущей временной метки (timestamp).
    Пример:
    [pawn]
    new i_Vault
    , s_AuthID[35], s_Data[30]

    i_Vault = nvault_open("testvault")
    get_user_authid(id, s_AuthID, charsmax(s_AuthID))

    // Запись строки "hello world" по ключу Steam ID игрока
    nvault_set(i_Vault, s_AuthID, "hello world")

    // Запись данных через использование переменной
    new s_Text[] = "hello world"
    nvault_set(i_Vault, s_AuthID, s_Text) [/pawn]
  • nvault_pset
    Функция схожая с nvault_set(). Различия заключаются в том, что временная метка (timestamp) не записывается, поэтому запись нельзя удалить с помощью функции nvault_prune(). В данном случае значение timestamp равняется 0.
  • nvault_touch
    Данная функция "касается" записи и обновляет временную метку (timestamp). Значение записи при этом не меняется. Если указанный ключ не существует, то автоматически создается пустая запись с данным ключем.
    Пример:
    [pawn]new i_Vault, s_AuthID[35]

    i_Vault = nvault_open("testvault")
    get_user_authid(id, s_AuthID, charsmax(s_AuthID))

    // Обновить timestamp записи
    nvault_touch(i_Vault, s_AuthID)

    // Обновить timestamp записи на 1 час назад (60 * 60) = 3600
    nvault_touch(i_Vault, s_AuthID, get_systime() - 3600) [/pawn]
  • nvault_prune
    Данная функция используется для удаления записей, которые находятся в указанном промежутке timestamp. Учтите, что значение в timestamp хранится в секундах.
    Пример:
    [pawn]new i_Vault

    i_Vault 
    = nvault_open("testvault")

    // Удалить все записи с 0 (возможное начальное время) по get_systime() (текущее врмемя).
    nvault_prune(i_Vault, 0, get_systime())

    // Удалить все записи, которые старше 15 дней
    // 1 день = 86400 секунд = 60 секунд * 60 минут * 24 часа
    nvault_prune(i_Vault, 0, get_systime() - (15 * 86400)) [/pawn]
  • nvault_remove
    Удаление записи по указанному ключу во втором аргументе функции.
    Пример:
    [pawn]new i_Vault, s_AuthID[35]

    i_Vault = nvault_open("testvault")
    get_user_authid(id, s_AuthID, charsmax(s_AuthID))

    // Удалить данные по ключу Steam ID игрока
    nvault_remove(i_Vault, s_AuthID)
     [/pawn]

4. Временные метки (timestamps).
Timestamps - это данные в UNIX-время формате (POSIX время).
http://ru.wikipedia.org/wiki/UNIX-время

Где моментом отсчета является полночь с 31 декабря 1969 года на 1 января 1970 года. Используя не сложные манипуляции, вы можете перевести секунды в минуты, часы, дни или недели. Например: день = 60 * 60 * 24 = 86400.

Для конвертации UNIX-время <-> нормальное время можно использовать:
Вы должны зарегистрироваться, чтобы видеть ссылки.
Вы должны зарегистрироваться, чтобы видеть ссылки.

5. Пример использования в плагине.
Если вы хотите использовать возможности nVault в своем плагине, то лучше всего держать nvault файл открытым на протяжении работы плагина. Для этого используйте глобальную переменную для хранения указателя на файл, который мы получаем через использование функции nvault_open() в plugin_init() или в plugin_config() (или любой другой функции). Для закрытия файл используйте nvault_close() в plugin_end().
Данный плагин позволяет сохранять деньги и счет, используя Steam ID игрока, как ключ. Отсюда следует, что мы сохраняем данные два раза, используя один ключ. Поэтому нам нужно немного изменить ключ для каждых данных. К примеру, для хранения денег "STEAM_0:0:1234MONEY" и для хранения счета "STEAM_0:0:1234SCORE".

[pawn]
#include <amxmodx>
#include <nvault>
#include <cstrike>
#include <fun>

// Глобальная переменная для хранения указателя
new g_Vault
// Глобальный массив для хранения Steam ID игроков
new g_s_AuthID[33][35]
// Глобальный указатель на cvar истекщего времени
new g_p_ExpireDays

public plugin_init
()
{
    register_plugin("nVault Example", "1.0", "bugsy")

    register_clcmd("say /savemoney", "cmdSaveMoney")
    register_clcmd("say /getmoney", "cmdGetMoney")
    register_clcmd("say /savescore", "cmdSaveScore")
    register_clcmd("say /getscore", "cmdGetScore")

    g_p_ExpireDays = register_cvar("cvar_expiredays", "5")
}

public plugin_cfg()
{
    // Открываем файл и сохраняем указатель в g_Vault
    g_Vault = nvault_open("yourvault")

    // Прекращаем работу плагина, если файл не удалось открыть
    if (g_Vault == INVALID_HANDLE)
        set_fail_state("Error opening nVault!")

    // Удаляем все записи старше 5+ дней после запуска сервера или смене карты
    nvault_prune(g_Vault, 0, get_systime() - (86400 * get_pcvar_num( g_p_ExpireDays)))
}

public plugin_end()
{
    // Закрываем nvault файл (смена карты\выключение сервера\перезапуск сервера)
    nvault_close(g_Vault)
}

public client_authorized(id)
{
    // Получаем и сохраняем в массиве Steam ID игрока
    get_user_authid(id, g_s_AuthID[id], charsmax(g_s_AuthID[]))
}

public cmdSaveMoney(id)
{
    // Сохраняем деньги игрока
    // Пример: STEAM_0:0:1234 16000

    // Переменная для хранения денег
    new s_Money[7]
    // Переменная для хранения ключа "STEAM_0:0:1234MONEY"
    new s_Key[40]

    formatex(s_Key, charsmax(s_Key) , "%sMONEY", g_s_AuthID[id])
    formatex(s_Money, charsmax(s_Money), "%d", cs_get_user_money(id))
    
    nvault_set
(g_Vault, s_Key, s_Money)

    client_print(id, print_chat, "* Your money was saved to vault")
}

public cmdGetMoney(id)
{
    // Получаем деньги игрока
    // Пример: STEAM_0:0:1234 16000

    new s_Key[40]
    formatex(s_Key, charsmax(s_Key), "%sMONEY", g_s_AuthID[id])
    new i_Money = nvault_get(g_Vault, s_Key)

    // Если ключ найден, то выставляем игроку полученное значение денег
    // Удаляем ключ, чтобы игрок не получил деньги снова
    if (i_Money)
    {
        cs_set_user_money(id, i_Money, 1)
        nvault_remove(g_Vault, s_Key)

        client_print(id, print_chat, "* Your money was loaded from vault: $%d", i_Money)
    }
    else
        client_print
(id, print_chat, "* You have no money entry in vault.")
}

public cmdSaveScore(id)
{
    // Сохраняем счет игрока
    // Пример: STEAM_0:0:1234 15 5

    // Переменная для хранения кол-во убийств и смертей в формате "15 5"
    new s_Data[8] 
    
// Переменная для хранения ключа "STEAM_0:0:1234SCORE"
    new s_Key[40]

    formatex(s_Key, charsmax(s_Key), "%sSCORE", g_s_AuthID[id])
    formatex(s_Data, charsmax(s_Data), "%d %d", get_user_frags(id), get_user_deaths(id))

    nvault_set(g_Vault, s_Key, s_Data)

    client_print(id, print_chat, "* Your score was saved to vault.")
}

public cmdGetScore(id)
{
    // Получаем счет игрока
    // Пример: STEAM_0:0:1234 15 5

    new s_Data[8]
    new s_Key[40]

    formatex(s_Key, charsmax(s_Key), "%sSCORE", g_s_AuthID[id])

    // Если данные получены
    if (nvault_get(g_Vault, s_Key, s_Data, charsmax(s_Data)))
    {
        // Ищем пробел в данных, который используется для разделения кол-во убийств и смертей
        new i_SpacePos = contain(s_Data, " ")
        
        if 
(i_SpacePos > -1)
        {    
            new s_Kills
[4]
            new s_Deaths[4]
            
            
// Разделяем данные (убийства и смерти) по разным переменным
            formatex(s_Kills, i_SpacePos, "%s", s_Data)
            formatex(s_Deaths, charsmax(s_Deaths), "%s", s_Data[i_SpacePos + 1])

            // Устанавливаем счет игроку на основании полученных данных
            set_user_frags(id, str_to_num(s_Kills))
            cs_set_user_deaths(id, str_to_num(s_Deaths))

            client_print(id, print_chat, "* Your score was loaded: %s kills, %s deaths", s_Kills, s_Deaths)
        }
    }
    else
        client_print
(id, print_chat, "* You have no score entry in vault.")
}
  [/pawn]
Не пишите мне в ЛС: если вам нужна помощь на бесплатной основе. Любые вопросы на форум.
Аватара пользователя
DJ_WEST
Администратор
 
Сообщения: 3649
Зарегистрирован: 22 авг 2009, 00:38
Благодарил (а): 48 раз.
Поблагодарили: 2177 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Left 4 Dead
Left 4 Dead 2

Re: Работа с системой nVault

Сообщение qpAHToMAS » 24 авг 2010, 12:39

Очень интересно, неужели наконец можно будет сделать собственную статистику игроков, типа "ник — значение".
Аватара пользователя
qpAHToMAS
 
Сообщения: 708
Зарегистрирован: 02 ноя 2009, 18:45
Благодарил (а): 79 раз.
Поблагодарили: 204 раз.
Языки программирования: CStrike

Re: Работа с системой nVault

Сообщение Fedcomp » 24 авг 2010, 16:08

Статистику игроков7 не смеши. Когда файл разрастется ты получишь лаги
Не помогаю в ЛС - есть форум.
Плагины тоже не пишу, на форуме достаточно хороших скриптеров.


"я ставлю зависимости потому что мне приятно" - subb98 @ 2017
Аватара пользователя
Fedcomp
Администратор
 
Сообщения: 4506
Зарегистрирован: 28 авг 2009, 20:47
Благодарил (а): 721 раз.
Поблагодарили: 1224 раз.
Языки программирования: =>
pawn / php / python / ruby
javascript

Re: Работа с системой nVault

Сообщение DJ_WEST » 24 авг 2010, 20:02

Для статистики лучше SQL база.
Статистику игроков7 не смеши. Когда файл разрастется ты получишь лаги

statsx тоже собирает статистику в файл при больших размерах тоже самое.
Не пишите мне в ЛС: если вам нужна помощь на бесплатной основе. Любые вопросы на форум.
Аватара пользователя
DJ_WEST
Администратор
 
Сообщения: 3649
Зарегистрирован: 22 авг 2009, 00:38
Благодарил (а): 48 раз.
Поблагодарили: 2177 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Left 4 Dead
Left 4 Dead 2

Re: Работа с системой nVault

Сообщение Fedcomp » 24 авг 2010, 21:00

я разве что то говорил за/против statsx? крупные порталы юзают psyhostats
Не помогаю в ЛС - есть форум.
Плагины тоже не пишу, на форуме достаточно хороших скриптеров.


"я ставлю зависимости потому что мне приятно" - subb98 @ 2017
Аватара пользователя
Fedcomp
Администратор
 
Сообщения: 4506
Зарегистрирован: 28 авг 2009, 20:47
Благодарил (а): 721 раз.
Поблагодарили: 1224 раз.
Языки программирования: =>
pawn / php / python / ruby
javascript

Re: Работа с системой nVault

Сообщение DJ_WEST » 25 авг 2010, 00:59

Я про то, что statsx идет в пакете дополнения AMXX и как бы многих это устраивает (в плане размерности).
Не пишите мне в ЛС: если вам нужна помощь на бесплатной основе. Любые вопросы на форум.
Аватара пользователя
DJ_WEST
Администратор
 
Сообщения: 3649
Зарегистрирован: 22 авг 2009, 00:38
Благодарил (а): 48 раз.
Поблагодарили: 2177 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Left 4 Dead
Left 4 Dead 2

Re: Работа с системой nVault

Сообщение qpAHToMAS » 25 авг 2010, 05:33

Что-то команды "следующей ключ" не вижу, походу тот же Top15 не сделаешь.
Аватара пользователя
qpAHToMAS
 
Сообщения: 708
Зарегистрирован: 02 ноя 2009, 18:45
Благодарил (а): 79 раз.
Поблагодарили: 204 раз.
Языки программирования: CStrike

Re: Работа с системой nVault

Сообщение DJ_WEST » 25 авг 2010, 07:23

Что-то команды "следующей ключ" не вижу, походу тот же Top15 не сделаешь.

Вы должны зарегистрироваться, чтобы видеть ссылки.
Не пишите мне в ЛС: если вам нужна помощь на бесплатной основе. Любые вопросы на форум.
Аватара пользователя
DJ_WEST
Администратор
 
Сообщения: 3649
Зарегистрирован: 22 авг 2009, 00:38
Благодарил (а): 48 раз.
Поблагодарили: 2177 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Left 4 Dead
Left 4 Dead 2

Re: Работа с системой nVault

Сообщение Fedcomp » 25 авг 2010, 12:13

DJ_WEST писал(а):Я про то, что statsx идет в пакете дополнения AMXX и как бы многих это устраивает (в плане размерности).

Там настройками по умолчанию - лимитированный размер файла. После чего обнуляется :zzz:
Не помогаю в ЛС - есть форум.
Плагины тоже не пишу, на форуме достаточно хороших скриптеров.


"я ставлю зависимости потому что мне приятно" - subb98 @ 2017
Аватара пользователя
Fedcomp
Администратор
 
Сообщения: 4506
Зарегистрирован: 28 авг 2009, 20:47
Благодарил (а): 721 раз.
Поблагодарили: 1224 раз.
Языки программирования: =>
pawn / php / python / ruby
javascript

Re: Работа с системой nVault

Сообщение DJ_WEST » 25 авг 2010, 18:09

Там настройками по умолчанию - лимитированный размер файла. После чего обнуляется

Что можно сделать аналогично в своем плагине ;)
Не пишите мне в ЛС: если вам нужна помощь на бесплатной основе. Любые вопросы на форум.
Аватара пользователя
DJ_WEST
Администратор
 
Сообщения: 3649
Зарегистрирован: 22 авг 2009, 00:38
Благодарил (а): 48 раз.
Поблагодарили: 2177 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Left 4 Dead
Left 4 Dead 2

След.

Вернуться в Статьи / фрагменты кода

Кто сейчас на конференции

Сейчас этот форум просматривают: BlackSignature и гости: 1