Правила форума Гаранты форума
Размещение рекламы AMX-X компилятор

Здравствуйте, гость Вход | Регистрация

Наши новости:

14-дек
24-апр
10-апр
11-апр

nvault и get_systime()

Статус пользователя Deimos7
сообщение 8.2.2026, 13:04
Сообщение #1
Стаж: 13 лет
Город: Киев

Сообщений: 93
Благодарностей: 5
Полезность: 47

Есть здесь те, кто часто использовал nvault в своих плагинах?

У меня через nvault реализованы лимиты на покупку игровых вещей в игре. Лимиты эти должны действовать в пределах одной карты (сессии) и поддерживать реконнект. Суть проблемы объясню в самом конце темы.

Сейчас я создаю ключи чтоб записать в nvault информацию в пределах одной карты (сессии). Ключи у меня - это timestamp:steam_id в таком формате (пример: 1770512640:STEAM_0:0:357956451). Время я достаю с помощью get_systime() в plugin_init и записываю сразу в cvar (так же пробовал делать это в plugin_cfg с заддержкой и без заддержки set_task). Суть в том, что этот cvar хранящий timestamp будет обновляться при каждой инициализации карты и следовательно лимиты будут сбрасываться.

Вот моя стоковая функция которая достает ключ:

Код:
stock get_limit_key(id, key[], keylen)
{
new auth[64]
get_user_authid(id, auth, charsmax(auth))

new session = get_pcvar_num(cvar_map_session);

// 1700000000:STEAM_0:1:12345
formatex(key, keylen, "%d:%s", session, auth)
}


Проблема: Лимиты которые я таким образом записываю иногда не сбрасываются при смене карты. Вероятно при нормальных обстоятельствах когда карты меняются на сервере каждых 20-40 минут такой проблемы нету (я не уверен в этом!), НО конкретно когда я тестировал свои лимиты при быстрой ротации, то есть принудительная смена через amx_map/changelevel каждых пол минуты тире 5 минут, то у меня такая проблема возникает. После смены карты игрок видит старое значение, а не новое, хотя ключ должен обновиться, потому что timestamp это время с 1 января 1970 года именно в секундах, а не, например, в минутах (если бы я произвел ротацию в течении одной минуты тогда ладно). Может дело в обновлении cvar_map_session хранящий timestamp?

Вот что примерно я делаю в plugin_init:
Код:
cvar_map_session = register_cvar("zp_map_session_id", "0");
set_pcvar_num(cvar_map_session, get_systime());


Отредактировал: Deimos7, - 8.2.2026, 15:07
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   Цитировать сообщение
Статус пользователя murlemur
сообщение 9.2.2026, 7:47
Сообщение #2
Стаж: 5 лет 5 месяцев

Сообщений: 28
Благодарностей: 8
Полезность: 174

Мне кажется для твоей задачи вообще nvault не подходит, ведь тебе тебе данные сохранять нужно на время карты - а для этого и быстрее и удобнее будет использовать глобальные переменные. Например данные хранить в каком нибудь Trie , взяв за ключ стимайди игрока ...
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя Gecko
сообщение 9.2.2026, 11:34
Сообщение #3
Стаж: 7 лет 4 месяца

Сообщений: 1247
Благодарностей: 518
Полезность: 345

Deimos7,



ответ


Объяснение проблемы

Когда вы меняете карту, сервер перезагружает плагины, и вызывается plugin_init. В этот момент вы обновляете квар через
set_pcvar_num. Однако система кваров не всегда обновляет значение мгновенно для всех частей движка. Может возникнуть задержка,
особенно при быстрой смене карт.

В результате, когда игрок подключается и для него вызывается функция get_limit_key, get_pcvar_num может вернуть старое значение из
предыдущей сессии (карты), потому что новое значение еще не "дошло" до нее.

Решение

Самый надежный способ решить эту проблему — отказаться от использования квара для хранения ID сессии и вместо этого использовать
глобальную переменную. Глобальные переменные сбрасываются при каждой перезагрузке плагина (то есть при каждой смене карты), и их
значения доступны мгновенно внутри плагина.

Вот как можно изменить ваш код:
1. Объявите глобальную переменную в начале вашего скрипта:
Код
new g_map_session;



2. В `plugin_init` инициализируйте эту переменную. Вы можете оставить квар для отладки, чтобы можно было проверить значение через
консоль, но не используйте его в основной логике.



Код
    
        public plugin_init()
         {
             // ... ваш остальной код ...
    
             // Устанавливаем ID сессии в глобальную переменную
             g_map_session = get_systime();
    
             // Можно по-прежнему регистрировать и устанавливать квар для отладки,
             // но основная логика больше не будет от него зависеть.
            cvar_map_session = register_cvar("zp_map_session_id", "0");
            set_pcvar_num(cvar_map_session, g_map_session);
  
            // ...
        }


3. Измените `get_limit_key`, чтобы она использовала глобальную переменную:



Код
    1     stock get_limit_key(id, key[], keylen)
         {
             new auth[64];
             get_user_authid(id, auth, charsmax(auth));
    
             // Используем глобальную переменную напрямую вместо чтения квара
             // Старый код: new session = get_pcvar_num(cvar_map_session);
    
             // 1700000000:STEAM_0:1:12345
            formatex(key, keylen, "%d:%s", g_map_session, auth);
        }



Почему это сработает?

* Значение глобальной переменной g_map_session устанавливается в plugin_init и сразу же доступно для всех функций вашего плагина.
* Нет никакой задержки, связанной с системой кваров.
* При каждой смене карты плагин перезагружается, переменная обнуляется, а затем в plugin_init ей присваивается новое актуальное
значение get_systime().


Это простое изменение должно полностью устранить проблему с несбрасываемыми лимитами при быстрой смене карт.


В терминале, браузере (Ctrl+x), в редакторе кода, почти везде есть ИИ ассистент который подобные задачи решает на ура (уровень джуна)

Отредактировал: Gecko, - 9.2.2026, 18:29


Не отвечаю на ЛС.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя Deimos7
сообщение 9.2.2026, 22:18
Сообщение #4
Стаж: 13 лет
Город: Киев

Сообщений: 93
Благодарностей: 5
Полезность: 47

Gecko, cbf1b2bfde1a.gif )))

Я бы не создавал тему если бы не понимал ограничения ИИ. То что выдал тебе Gemini - это просто более разширенный код того, что у меня лежит сейчас в исходнике. Он просто "догадался" что я пытаюсь сделать из описания и сгенерировал тебе код, думая что это мне это как то поможет. Твой ответ пока не приближает меня ни на шаг. У меня уже есть глобальная переменная, и этот тот код что я написал действительно лежит в plugin_init (я сам об этом написал в своем посте). Мне не нужно делать то, что предложил Gemini, потому что это то с чем я уже пришел на этот форум. Может я удивлю тебя, но прежде чем создать тему, я сам писал и анализировал свой код с GPT Plus :)

Единственное, что полезного выдал Gemini, это то что вероятней всего дело в race conditions, но я и сам интутивно это чувствую, поэтому и написал что экспериментовал переносить установку значения в plugin_cfg, так же добавлял заддержки. Вопрос здесь не в самом коде, а в архитектуре кода или подходе к решению задачи. Например, надежно ли использовать nvault здесь, или как правильно обойти race conditions.

Но за ответ спасибо. Видео очень улыбнуло фразой "Показываю банально как это решается в 2026 году" )

Cкрытый текст

Цитата(murlemur @ 9.2.2026, 7:47) *
Мне кажется для твоей задачи вообще nvault не подходит, ведь тебе тебе данные сохранять нужно на время карты - а для этого и быстрее и удобнее будет использовать глобальные переменные. Например данные хранить в каком нибудь Trie , взяв за ключ стимайди игрока ...

Я и использую глобальную переменную, просто у меня фиксация к карте идет по системному времени в момент инициализации плагина. Все ключи по SteamId в nvault содержат это время, и оно измениться только после смены карты.

Спасибо, я почитаю про Trie. Интересно попробовать его вместо Nvault. Как я понял их сходство в том что они оба работают по принципу ключ-значение, но tries быстрее, потому что живет в памяти между инициализациями (картами).

Отредактировал: Deimos7, - 9.2.2026, 22:48
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя Gecko
сообщение 9.2.2026, 22:49
Сообщение #5
Стаж: 7 лет 4 месяца

Сообщений: 1247
Благодарностей: 518
Полезность: 345

Deimos7, так не зная полного кода тебе тут никто не поможет )))
Ты дал код в общих чертах, в общих чертах и получил ответ, я на виде сразу сказал, сервер твой и тебе виднее как и что у тебя там работает.

Не понимаю тогда в чём проблема, если (с твоих слов) ты и так понимаешь суть проблемы.

Цитата
Может я удивлю тебя этим или нет, но прежде чем создать тему, я сам писал и анализировал свой код с GPT Plus :)

Ни разу не удивил, просто не понимаю суть твоего поста.

Какой ты хотел увидеть ответ?







Не отвечаю на ЛС.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя Deimos7
сообщение 9.2.2026, 22:53
Сообщение #6
Стаж: 13 лет
Город: Киев

Сообщений: 93
Благодарностей: 5
Полезность: 47

Gecko, ответ с Trie мне очень понравился, буду пробовать. Я вообще не знал о его существовании. Ненужно будет никаких timestamp.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя Gecko
сообщение 9.2.2026, 22:59
Сообщение #7
Стаж: 7 лет 4 месяца

Сообщений: 1247
Благодарностей: 518
Полезность: 345

Цитата(Deimos7 @ 9.2.2026, 22:53) *
Gecko, ответ с Trie мне очень понравился, буду пробовать. Я вообще не знал о его существовании. Ненужно будет никаких timestamp.

Я тебе больше скажу, Trie + Array (Trie + map_session_id) - первое что мне выдал бот, именно как альтернативу nvault. Но твой вопрос ведь касался NVault.


Отредактировал: Gecko, - 9.2.2026, 23:12


Не отвечаю на ЛС.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя Deimos7
сообщение 9.2.2026, 23:14
Сообщение #8
Стаж: 13 лет
Город: Киев

Сообщений: 93
Благодарностей: 5
Полезность: 47

Gecko, в следующий раз не буду столь ограничен в выборе заголовка для темы)) Главное нашли решение, спасибо)

Отредактировал: Deimos7, - 9.2.2026, 23:14
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя Gecko
сообщение 9.2.2026, 23:30
Сообщение #9
Стаж: 7 лет 4 месяца

Сообщений: 1247
Благодарностей: 518
Полезность: 345

Цитата(Deimos7 @ 9.2.2026, 23:14) *
Gecko, в следующий раз не буду столь ограничен в выборе заголовка для темы)) Главное нашли решение, спасибо)

Тогда удачи

Отредактировал: Gecko, - 9.2.2026, 23:54


Не отвечаю на ЛС.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
  Ответить в данную темуНачать новую тему
 
0 пользователей и 1 гостей читают эту тему: