Проверка на отключение игрока(Вопрос)

Тема в разделе "Программирование / Скриптинг", создана пользователем R1KO, 21 апр 2013.

  1. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.993
    Симпатии:
    2.989
    Здавствуйте. Не подкажете как в sourcepawn, при отключении игрока проверить находился ли он в игре ?

    Вот, например, игрок начинает подключаться и сразу нажимает отмена. Как исключить такие случаи из проверки ?
     
  2. The End Is Near...

    The End Is Near... Russian Roulette

    Сообщения:
    893
    Симпатии:
    659
  3. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.993
    Симпатии:
    2.989
    А разве она не проверяет наличие клиента в игре в данный момент ?
     
  4. FrozDark

    FrozDark Команда сайта HLMod Модератор

    Сообщения:
    1.761
    Симпатии:
    1.915
    его ответ правильный

    if (IsClientConnected(client) && !IsClientInGame(client)) - игрок все ещё подключается
     
  5. KorDen

    KorDen Atra esterní ono thelduin! Ньюсмейкер

    Сообщения:
    2.194
    Симпатии:
    1.398
    Кстати, на каком этапе игроку назначается id? Когда делаю хук player_connect, то в этот момент получить через GetClientOfUserId клиента нельзя... Или при EventHookMode_Post уже должен назначиться? (там где я это уже испоользовал, было EventHookMode_Pre, и там его не было...)

    Проще говоря, можно получить id игрока раньше вызова OnClientConnect?
     
  6. schmidt

    schmidt wS (skype: ws.css)

    Сообщения:
    188
    Симпатии:
    347
    Не совсем. Если конектишься и почти в самый последний момент жмешь "Отмена" (выход), то IsClientInGame вернет true, но игрок то полностью не вошел.

    Наверно нет, только если с расширением каким-то, да и зачем это.

    new bool:g_InGame[MAXPLAYERS + 1];

    В событии каком-нибудь, когда уверен что он зашел (spawn, team и тд), делаешь g_InGame[client] = true;
    Ну а когда выходит, просто:

    Код:
    if (g_InGame[client])
    {
        g_InGame[client] = false;
    
        // ...
    }
    Или с таймером есть вариант, неужели фантазии нет.
     
    R1KO нравится это.
  7. FrozDark

    FrozDark Команда сайта HLMod Модератор

    Сообщения:
    1.761
    Симпатии:
    1.915
     
    R1KO нравится это.
  8. schmidt

    schmidt wS (skype: ws.css)

    Сообщения:
    188
    Симпатии:
    347
    Может и так, но автор просил учитывать факт нажатия кнопки отмены во время конекта, пусть даже это этот баг. Так что в его случае такой вариант с IsClientInGame может не всегда работать, если он хочет быть уверен, что покинувший сервер чел хотя бы видел motd окно-приветствие.
     
    Последнее редактирование: 22 апр 2013
  9. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.993
    Симпатии:
    2.989
    Просто игрок нажимая отмену так же вызывает дисконнект. А нужно отловить только дисконнект игрока который был в игре.
     
  10. V-Rico

    V-Rico SM Скриптер (Skype: v-rico.95)

    Сообщения:
    22
    Симпатии:
    9
    Как вариант вместо IsClientInGame использовать GetClientAvgLatency(client, NetFlow_Outgoing). Если игрок не подключен, то вернет -1 (по идее, я не проверял). Ну, или же вернет какое-то поднебесное значение (стремящееся к бесконечности; рассчет на то, что пакет будет идти ооооочень долго).
     
  11. KorDen

    KorDen Atra esterní ono thelduin! Ньюсмейкер

    Сообщения:
    2.194
    Симпатии:
    1.398
    http://docs.sourcemod.net/api/index.php?fastload=show&id=437&
    Это будет не -1, а ошибка в логи скорее всего.
     
  12. V-Rico

    V-Rico SM Скриптер (Skype: v-rico.95)

    Сообщения:
    22
    Симпатии:
    9
    Да, пожалуй ты прав. Не обратил внимание на ерроры.

    Добавлено через 4 минуты
    Так можно использовать гибрид
    Если IsClientInGame возвращает true, то проверяем задержку. По идее, в таком случае ерроров не должно быть, ведь индекс будет нормальным, игрок будет "на сервере" и он не фейковый.
     
    Последнее редактирование: 4 май 2013
    R1KO нравится это.
  13. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.993
    Симпатии:
    2.989
    Не подкажете как это использовать ? :)

    Чтобы отловить дисконнект игрока который был в игре, а тех кто нажал отмена или были забанены и попытались войти исключались.
     
  14. FrozDark

    FrozDark Команда сайта HLMod Модератор

    Сообщения:
    1.761
    Симпатии:
    1.915
    PHP:
    public OnClientDisconnect(client)
    {
         if (
    IsClientInGame(client))
         {
              
    // Клиент был в игре и отключился
         
    }
    }
     
    R1KO и schmidt нравится это.
  15. KorDen

    KorDen Atra esterní ono thelduin! Ньюсмейкер

    Сообщения:
    2.194
    Симпатии:
    1.398
    И какой смысл этого "гибрида"??? Когда клиент - бот, тоже будет материться, так как, еще раз повторю, "On error / Errors: Invalid client index, client not in game, or fake client". А если он InGame и не фейк, то какой вообще смысл проверки на задержку, она и так должна быть...
     
  16. V-Rico

    V-Rico SM Скриптер (Skype: v-rico.95)

    Сообщения:
    22
    Симпатии:
    9
    Ну еще и IsFakeClient добавить. А смысл простой. Тебе ведь объясняли: если нажать отмену в самый последний момент, то IsClientInGame будет возвращать true. Если IP клиента останется, то пинговаться будет. А так - не думаю, ведь даже кидать пакеты некуда будет.

    Итог такой:
    PHP:
    public OnClientDisconnect(client

         if (
    IsClientInGame(client) && !IsFakeClient(client)) 
         { 
              
    // Клиент был в игре, не был ботом и отключился

              // Нужно попробовать запустить с этой строчкой, чтобы понять какое значение вернется
              
    LogError("%i"GetClientAvgLatency(clientNetFlow_Outgoing));

              
    // Как только мы в самый первый раз узнаем что вернет функция, то оставляем только след. строчку, которая будет проверять
              
    if (GetClientAvgLatency(clientNetFlow_Outgoing)) != -// (или > N, зависит от результатов теста)
              
    {
                       
    // Делаем то, что нужно
              
    }
         } 
    }
     
    R1KO нравится это.
  17. FrozDark

    FrozDark Команда сайта HLMod Модератор

    Сообщения:
    1.761
    Симпатии:
    1.915
    думаешь если игрок IsClientInGame, но вышел в последний момент, GetClientAvgLatency вернет 0?
     
  18. V-Rico

    V-Rico SM Скриптер (Skype: v-rico.95)

    Сообщения:
    22
    Симпатии:
    9
    Предполагаю, что вернет -1. Я сегодня попробую.

    Добавлено через 1 час 40 минут
    К сожалению, не получилось.
    То есть пинг просто вырос в 2 раза, а это ни о чём не говорит

    Добавлено через 1 час 46 минут
    Кстати, если использовать OnClientDisconnect_Post вместо OnClientDisconnect, то при проверке IsClientInGame будет возвращено false. Может тебе это поможет. Если бы ты поподробнее описал цель, возможно тебе бы и помогли.

    Добавлено через 1 час 48 минут
    Относительно твоего случая: тебе может помочь, если т будешь менять значение переменной g_bConnected[client]. В OnClientConnect ставишь g_bConnected[client] = true, в OnClientDisconnect_Post - g_bConnected[client] = false. Если я неправильно понял твою цель, поправь меня.
     
    Последнее редактирование: 4 май 2013
    R1KO нравится это.
  19. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.993
    Симпатии:
    2.989
    Цель: при отключении игрока исключить из проверки тех игроков, которые либо недоподключились или были забанены и не смогли подключится(тем самым вызвав событие дисконнект).

    На примере.

    PHP:
    public OnClientDisconnect(client// ну или event незнаю, что лучше использовать
    {
    PrintToChatAll("%N \x01отключился от сервера."client);
    }
    Так когда, к примеру, забаненый игрок пытается зайти в чат пишет "ник joined the game" но тут оказывается забаненым, ему пишет "user steam id xxxx is banned" а на сервере в чат пишет "ник left the game" и + плагин выводит "ник отключился от сервера.". Так вот должно выводить только когда игрок действительно вышел, а не любой дисконнект.
     
  20. V-Rico

    V-Rico SM Скриптер (Skype: v-rico.95)

    Сообщения:
    22
    Симпатии:
    9
    Используй так:
    PHP:
    public OnClientDisconnect_Post(client)

        
    PrintToChatAll("%N \x01отключился от сервера."client); 
    }
     
    R1KO нравится это.