Удаление таймера при дисконекте

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
@oleg_nelasy, я бы подсказал как отловить открытие меню с выбором команды в КСС, но подозреваю, что тебе нужно для КСГО, а там мой метод не срабатывает, емнип.
 

oleg_nelasy

Участник
Сообщения
664
Реакции
46
@oleg_nelasy, я бы подсказал как отловить открытие меню с выбором команды в КСС, но подозреваю, что тебе нужно для КСГО, а там мой метод не срабатывает, емнип.
Про это в курсе. Но мне по факту нужно не открытие меню а именно событие когда игрок подключился и он уже не грузится то есть ему это меню выбора команды отрисовало.
 

oleg_nelasy

Участник
Сообщения
664
Реакции
46
Лучше вот так:
C-подобный:
public void Event_Activate(Event event, const char[] sEvName, bool bDontBroadcast)
{
    int client = GetClientOfUserId(event.GetInt("userid"));
    if(!g_hTimer[client]) g_hTimer[client] = CreateTimer(g_fTimer, Timer_ConnectTeam, GetClientUserId(client));
}

public Action Timer_ConnectTeam(Handle timer, any client)
{
    if((client = GetClientOfUserId(client)))    // если игрок всё ещё на сервере, возможно эта проверка не нужна
    {
        if(GetClientTeam(client) == CS_TEAM_NONE) ChangeClientTeam(client, CS_TEAM_SPECTATOR);
        g_hTimer[client] = null;    // обнуляем хэндл таймера
    }
    return Plugin_Stop;
}

public void OnClientDisconnect(int client)
{
    if(g_hTimer[client]) delete g_hTimer[client];    // если таймер существует, то его удаляем
}

Заметил что ошибку не в игре при перезапуске сервера иногда появлялась. По сути сервер еще не поменял карту но игрок уже не в игре. И я надеюсь При смене карты таймер убивается если он есть?


Сделал как-то-так:
if(IsClientInGame(iClient) && GetClientTeam(iClient) == CS_TEAM_NONE) ChangeClientTeam(iClient, CS_TEAM_SPECTATOR);

Надеюсь если игрок не в игре на GetClientTeam уже проверять не будет?
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
Надеюсь если игрок не в игре на GetClientTeam уже проверять не будет?
если первая проверка возвращает false, то последующие через && не производятся за ненадобностью
Сообщения автоматически склеены:

Заметил что ошибку не в игре при перезапуске сервера иногда появлялась. По сути сервер еще не поменял карту но игрок уже не в игре.
текст ошибки?
 

oleg_nelasy

Участник
Сообщения
664
Реакции
46
если первая проверка возвращает false, то последующие через && не производятся за ненадобностью
Сообщения автоматически склеены:


текст ошибки?
Клиент не в игре. После данной правки у всех все работает четко ошибка больше не вылазит. это выбивало иногда когда новый игрок недавно зашел и тут же карта поменялась. По сути у него таймер вот вот должен отработать и карта начала меняться.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
При смене карты таймер убивается если он есть?
вообще при смене карты происходит дисконнект игроков
Но можно при событии OnMapEnd() убивать таймеры
Сообщения автоматически склеены:

Клиент не в игре. После данной правки у всех все работает четко ошибка больше не вылазит.
так в логе и пишет, на русском языке и без подробностей?
 

oleg_nelasy

Участник
Сообщения
664
Реакции
46
вообще при смене карты происходит дисконнект игроков
Но можно при событии OnMapEnd() убивать таймеры
Сообщения автоматически склеены:


так в логе и пишет, на русском языке и без подробностей?
В логе пишет на английском. Клиент не в игре. Указывает данною строку и ругалось на GetClientTeam.

Согласен на всякий случай продублирую убийство таймера в OnMapEnd(). Важный вопрос что отработает раньше OnMapEnd() или Event_Activate?

Хотя мне кажется лучшее сделать так?

C-подобный:
public void Event_Activate(Event hEvent, const char[] sEvName, bool bDontBroadcast)
{
    int iClient = GetClientOfUserId(hEvent.GetInt("userid"));
  
    if(g_hTimer[iClient])
    {
        g_hTimer[iClient] = null;
        delete g_hTimer[iClient];
    }
  
    g_hTimer[iClient] = CreateTimer(g_fTaimer, TimerConnectTeam, GetClientUserId(iClient));
}
 
Последнее редактирование:

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
if(g_hTimer[iClient]) { g_hTimer[iClient] = null; delete g_hTimer[iClient]; }
Обнулять хэндл нужно после убийства таймера, а если используешь delete, то обнулять не нужно т.к. он и так обнуляется.
Сообщения автоматически склеены:

Важный вопрос что отработает раньше OnMapEnd() или Event_Activate?
понятия не имею: ты так нигде не упомянул что за это у тебя событие ловится
 

_wS_

Участник
Сообщения
383
Реакции
760
а если используешь delete, то обнулять не нужно т.к. он и так обнуляется.
А потом пишешь на C++ и тоже думаешь, что и там обнулять не нужно, и проги крашатся =) Я из-за этого свои ClearHandle/ClearTimer функции юзаю, а когда нужно просто закрыть и приравнивание к null не нужно, скармливаю delete, если лень написать более длинное CloseHandle или какое-то неявное не пойми где .Close(). Зачем sm ушёл от логики в этом моменте, странно, и плохо 🙉
 

oleg_nelasy

Участник
Сообщения
664
Реакции
46
понятия не имею: ты так нигде не упомянул что за это у тебя событие ловится

Это насколько я понял подключение игрока к серверу. Как мне объяснили когда игрок полностью подключен к серверу. Игрок при подключении активирует таймер. Таймер убивается если он отработал. Или если не отработал то при дисконекте убивается. Вызывается только один раз поэтому при дисконекте в любом случаи таймер убьет.

 
Сверху Снизу