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

Работа с системой 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
Администратор
 
Сообщения: 3641
Зарегистрирован: 22 авг 2009, 00:38
Благодарил (а): 48 раз.
Поблагодарили: 2209 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Left 4 Dead
Left 4 Dead 2

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

Сообщение lashshs » 29 авг 2010, 01:09

a kak soxranit XP mojesh zdelat takoi Статьи?
Аватара пользователя
lashshs
 
Сообщения: 11
Зарегистрирован: 06 авг 2010, 18:53
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Языки программирования: Counter-Strike 1.6

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

Сообщение WaterBall » 09 июл 2011, 04:55

А можно ли как-нибудь вывести список всех значений в консоль или в мотд?
Или, к примеру, десять самых высоких значений.
Аватара пользователя
WaterBall
 
Сообщения: 554
Зарегистрирован: 27 май 2011, 10:04
Благодарил (а): 4 раз.
Поблагодарили: 182 раз.
Языки программирования: Counter-Strike 1.6

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

Сообщение Dr.Freeman » 14 авг 2011, 21:20

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

Тогда что лучше для статистики? Использовать file будет еще лажнее
А так nVault ништяк штука. Кому не нравится используйте FVault. Тоже самое но уже через обычные файлы

Добавлено спустя 8 минут 16 секунд:
WaterBall писал(а):А можно ли как-нибудь вывести список всех значений в консоль или в мотд?
Или, к примеру, десять самых высоких значений.


Придется использовать Вы должны зарегистрироваться, чтобы видеть ссылки.
А для поиска 10 самых высоких вот это:
[pawn]
  1. lc_find_max_stats(g_stb[],iphone,eid[]){

  2.         new g_datamax=0

  3.         new iid

  4.        

  5.         for(new j;j<iphone;j++){

  6.                 if(!eid[j]){

  7.                         if(g_stb[j]>g_datamax){

  8.                                 g_datamax=g_stb[j]

  9.                                 eid[j]=true

  10.                                 iid=j

  11.                         }

  12.                 }

  13.         }

  14.         return iid

  15. }
[/pawn]

К примеру Top10 смертей:
[pawn]
  1.   new lc_num =get_statsnum() // Получаем кол-во записей csstats.dat

  2.         new stats[8], bh[8] // Само собой

  3.  

  4.         new g_basestats[100] // Небольшой аррай

  5.         new bool:eid[100]

  6.        

  7.         if(lc_num>100)lc_num = 100

  8.  

  9.         for(new i;i<lc_num;i++){

  10.                 get_stats(i,stats,bh,comrad_buffer,NAME_LEN)

  11.                 g_basestats[i] = stats[STATS_DEATHS]

  12.         }

  13.  

  14. for(new i;i<10;i++){

  15.         lc_get_stats(lc_find_max_stats(g_basestats,lc_num,eid),stats,bh,comrad_buffer,NAME_LEN)

  16.               server_print("stats for %s is %d",comrad_buffer,stats[STATS_DEATHS])

  17. }
[/pawn]
Аватара пользователя
Dr.Freeman
 
Сообщения: 12
Зарегистрирован: 14 авг 2011, 21:09
Откуда: Leet Town
Благодарил (а): 0 раз.
Поблагодарили: 2 раз.
Опыт программирования: Около года
Языки программирования: Half-Life 1 (бесплатно)
Counter-Strike (-75% от вашей цены)

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

Сообщение KORD_12.7 » 15 авг 2011, 10:06

Dr.Freeman, для статистики лучше всего модуль + плагин, все эти "ваулты" (особенно FVault) не нужны.

_http://aghl.ru/ - Half-Life и Adrenaline Gamer: за пределами возможного
Аватара пользователя
KORD_12.7
Скриптер
 
Сообщения: 298
Зарегистрирован: 28 сен 2009, 10:14
Откуда: Владивосток
Благодарил (а): 142 раз.
Поблагодарили: 257 раз.
Опыт программирования: Больше трех лет
Языки программирования: Half-Life
Opposing Force
Adrenaline Gamer
Counter-Strike

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

Сообщение Dr.Freeman » 17 авг 2011, 09:21

KORD_12.7 писал(а):Dr.Freeman, для статистики лучше всего модуль + плагин, все эти "ваулты" (особенно FVault) не нужны.


nVault очень быстрый, из-за того что прост в обращении.
К примеру сохранение, чтение, удаление 5000 ваултов заняло всего 1 секунду (нудно данные в парсить)
MySQL (через SQL_Execute) - около 24 секунд (1000 запросов в секунду?)
SQLite (через SQL_Execute) - -1 секунд т.к дождаться завершения я так и не смог
FVault - около 3х (немного глючит если часто (напр. после убийства) сохранять данные
NFVault - (сохранение 2500 Данных в 2 ключа) - около 4x
Vault - 2 минуты :)
Аватара пользователя
Dr.Freeman
 
Сообщения: 12
Зарегистрирован: 14 авг 2011, 21:09
Откуда: Leet Town
Благодарил (а): 0 раз.
Поблагодарили: 2 раз.
Опыт программирования: Около года
Языки программирования: Half-Life 1 (бесплатно)
Counter-Strike (-75% от вашей цены)

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

Сообщение StRiKeR.csF » 12 дек 2011, 13:34

Спасибо за статью.
Чего добился ты и бла, бла, бла
Тут, типа, посыл был, но админ его потёр :(

Skype: nestle.csf
-В чём сила, брат?
-Сила в Debug.log xD
Аватара пользователя
StRiKeR.csF
Скриптер
 
Сообщения: 771
Зарегистрирован: 03 июн 2011, 06:26
Откуда: Кубань
Благодарил (а): 126 раз.
Поблагодарили: 181 раз.
Опыт программирования: Больше трех лет
Языки программирования: C++
C#
JavaScript
PHP(+MySQL)
Assembler

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

Сообщение 9iky6 » 12 июн 2012, 05:26

Эм, а при загрузке удалять значение можно? Просто хочу использовать плагин как временное хранилище на время смены карты или перезагрузки сервера.
Аватара пользователя
9iky6
 
Сообщения: 2174
Зарегистрирован: 30 янв 2012, 19:07
Откуда: Россия
Благодарил (а): 375 раз.
Поблагодарили: 707 раз.

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

Сообщение HENRI(_)LLOYD » 23 мар 2013, 13:07

как сохранить в 1 ключ несколько данных, + эти данные записываютьв через цыкл
всего данных гдето 10, то есть на 1 человека 10 примочек, которые должны сохраниться
Аватара пользователя
HENRI(_)LLOYD
 
Сообщения: 189
Зарегистрирован: 26 дек 2012, 03:07
Благодарил (а): 34 раз.
Поблагодарили: 7 раз.

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

Сообщение HENRI(_)LLOYD » 24 мар 2013, 20:58

Все разобрался
Аватара пользователя
HENRI(_)LLOYD
 
Сообщения: 189
Зарегистрирован: 26 дек 2012, 03:07
Благодарил (а): 34 раз.
Поблагодарили: 7 раз.

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

Сообщение Denis8388 » 02 ноя 2013, 13:02

у меня такая проблема, я поствил плагин на сохранение денег по стиму (код взял из статьи) но сохраняется на одну карту, после смены карты все сбивается, у меня стоит бай меню. что делать? чтоб деньги хранились на каждой карте, и чтоб при перезагрузки сервера тоже сохранились
Аватара пользователя
Denis8388
 
Сообщения: 172
Зарегистрирован: 11 май 2013, 20:27
Благодарил (а): 21 раз.
Поблагодарили: 0 раз.
Опыт программирования: Меньше месяца
Языки программирования: Counter-Strike 1.6

Пред.След.

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

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 13