Событие player_disconnect, iClient == 0

Planes

Потерявшиеся точка с запятой
Сообщения
356
Реакции
97
Есть у меня событие player_disconnect, зачастую, работает нормально и выдает информацию о игроке при выходе. Но иногда бывает ошибка и не получает значение iClient

PHP:
public void Ev_OnPlayerDisconnect(Event hEvent, const char[] sEvent, bool bDontBroadcast)
{
    int iClient = GetClientOfUserId(hEvent.GetInt("userid"));
    
    char szBuff[1024], sSteam[128];
    int curTime = GetTime();
    GetClientAuthId(iClient, AuthId_SteamID64, sSteam, sizeof(sSteam), true); // Получаем SteamID игрока
    
    FormatEx(szBuff, sizeof(szBuff), "UPDATE `HS_UserInfo` SET `disconnected` = '%i', `online` = '0' WHERE `steamid` LIKE '%s'", curTime, sSteam);
    g_hDB.Query(DB_CheckERR, szBuff);
    
}

В данном коде он должен обновлять данные игрока, но т.к iCLient == 0 , он не сможет этого сделать.

PHP:
L 06/20/2019 - 21:13:57: [SM] Exception reported: Client index 0 is invalid
L 06/20/2019 - 21:13:57: [SM] Blaming: HS_UserManager.smx
L 06/20/2019 - 21:13:57: [SM] Call stack trace:
L 06/20/2019 - 21:13:57: [SM]   [0] GetClientAuthId
L 06/20/2019 - 21:13:57: [SM]   [1] Line 41, HSUM/events.sp::Ev_OnPlayerDisconnect

Как можно получить со 100% вероятностью, информацию о вышедшем игроке?
 

Tomiks

Участник
Сообщения
419
Реакции
288
PHP:
HookEvent("player_disconnect", Ev_OnPlayerDisconnect, EventHookMode_Pre);

Попробуй, но думаю ты и сам пробовал поставить EventHookMode_Pre
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,924
  • Команда форума
  • #4
Это не влияет.
События, как правило, вызываются после того, как действие полностью произошло. Pre-хук даёт изменить содержимое события (или вообще запретить его отправку на клиенты), не более.

@Planes, как вариант, кешировать в глобальном массиве Стимы, как выше @Grey83 и подсказал.
 

Planes

Потерявшиеся точка с запятой
Сообщения
356
Реакции
97
хранить всё время игры на сервере, а сохранять в БД в OnClientDisconnect(int client)
кешировать в глобальном массиве Стимы
OnClientDisconnect(int client) помог вроде решить проблему данную.

Какой толк будет от кэширования, если после отключения игрока, невозможно узнать, какой именно STEAMID брать )) Либо я туплю, ибо в моем понимании, код кэширования что-то типо такого:
PHP:
char g_STEAM[MAXPLAYERS][128];

OnClientPostAdminCheck(int iClient)
{
   GetClientAuthId(iClient, AuthId_SteamID64, g_STEAM[iClient], sizeof(g_STEAM[iClient]), true);
}
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,924
  • Команда форума
  • #6
OnClientDisconnect(int client) помог вроде решить проблему данную.
Он так же вызывается над всеми при смене карты. Если Вас это устраивает - хорошо.

Какой толк будет от кэширования, если после отключения игрока, невозможно узнать, какой именно STEAMID брать ))
А Вы ассоциативку с помощью StringMap того же сделайте, где в качестве ключа будет выступать UserID.
Вообще, не пойму, зачем Вы делаете GetClientAuthId(), если в событии есть поле со SteamID
Screenshot_20190621-062905_Firefox.jpg
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,569
Реакции
5,071
@Planes, при входе ты получил и сохранил SteamID игрока, при его выходе сохранил в БД данные, используя сохранённый SteamID.
Не нужно больше получать SteamID при его выходе.
 
Сверху Снизу