А разве она не проверяет наличие клиента в игре в данный момент ?
Не совсем. Если конектишься и почти в самый последний момент жмешь "Отмена" (выход), то IsClientInGame вернет true, но игрок то полностью не вошел.его ответ правильный
Наверно нет, только если с расширением каким-то, да и зачем это.Проще говоря, можно получить id игрока раньше вызова OnClientConnect?
new bool:g_InGame[MAXPLAYERS + 1];Вот, например, игрок начинает подключаться и сразу нажимает отмена. Как исключить такие случаи из проверки ?
if (g_InGame[client])
{
g_InGame[client] = false;
// ...
}
Не совсем. Если конектишься и почти в самый последний момент жмешь "Отмена" (выход), то IsClientInGame вернет true, но игрок то полностью не вошел.
значит у игрока просто медленный компьютер и не успевает убрать интерфейс, потому как игрок действительно прошёл все этапы захода, даже его ник окажется в наблюдателях
Кстати, на каком этапе игроку назначается id? Когда делаю хук player_connect, то в этот момент получить через GetClientOfUserId клиента нельзя... Или при EventHookMode_Post уже должен назначиться? (там где я это уже испоользовал, было EventHookMode_Pre, и там его не было...)
Проще говоря, можно получить id игрока раньше вызова OnClientConnect?
https://forums.alliedmods.net/showthread.php?t=162489 - раньше чем даже OnClientConnect
Может и так, но автор просил учитывать факт нажатия кнопки отмены во время конекта, пусть даже это этот баг. Так что в его случае такой вариант с IsClientInGame может не всегда работать, если он хочет быть уверен, что покинувший сервер чел хотя бы видел motd окно-приветствие.значит у игрока просто медленный компьютер и не успевает убрать интерфейс, потому как игрок действительно прошёл все этапы захода, даже его ник окажется в наблюдателях
Может и так, но автор просил учитывать факт нажатия кнопки отмены во время конекта, пусть даже это этот баг. Так что в его случае такой вариант с IsClientInGame может не всегда работать, если он хочет быть уверен, что покинувший сервер чел хотя бы видел motd окно-приветствие.
Да и я думаю, не обязательно чел должен появляться в спек именно четко после того, как этот интерфейс с полоской потухнет. Чтобы утверждать такое (хоть оно и звучит логично), нужно точно знать как вся эта цепь событий работает.
Как вариант вместо IsClientInGame использовать GetClientAvgLatency(client, NetFlow_Outgoing). Если игрок не подключен, то вернет -1 (по идее, я не проверял). Ну, или же вернет какое-то поднебесное значение (стремящееся к бесконечности; рассчет на то, что пакет будет идти ооооочень долго).
Это будет не -1, а ошибка в логи скорее всего.On error / Errors:
Invalid client index, client not in game, or fake client.
http://docs.sourcemod.net/api/index.php?fastload=show&id=437&
Это будет не -1, а ошибка в логи скорее всего.
if (IsClientInGame(client))
GetClientAvgLatency(client, NetFlow_Outgoing)
Так можно использовать гибрид
C-подобный:if (IsClientInGame(client)) GetClientAvgLatency(client, NetFlow_Outgoing)
Если IsClientInGame возвращает true, то проверяем задержку. По идее, в таком случае ерроров не должно быть, ведь индекс будет нормальным, игрок будет "на сервере" и он не фейковый.
И какой смысл этого "гибрида"??? Когда клиент - бот, тоже будет материться, так как, еще раз повторю, "On error / Errors: Invalid client index, client not in game, or fake client". А если он InGame и не фейк, то какой вообще смысл проверки на задержку, она и так должна быть...
public OnClientDisconnect(client)
{
if (IsClientInGame(client) && !IsFakeClient(client))
{
// Клиент был в игре, не был ботом и отключился
// Нужно попробовать запустить с этой строчкой, чтобы понять какое значение вернется
LogError("%i", GetClientAvgLatency(client, NetFlow_Outgoing));
// Как только мы в самый первый раз узнаем что вернет функция, то оставляем только след. строчку, которая будет проверять
if (GetClientAvgLatency(client, NetFlow_Outgoing)) != -1 // (или > N, зависит от результатов теста)
{
// Делаем то, что нужно
}
}
}
Ну еще и IsFakeClient добавить. А смысл простой. Тебе ведь объясняли: если нажать отмену в самый последний момент, то IsClientInGame будет возвращать true. Если IP клиента останется, то пинговаться будет. А так - не думаю, ведь даже кидать пакеты некуда будет.
Итог такой:
PHP:public OnClientDisconnect(client) { if (IsClientInGame(client) && !IsFakeClient(client)) { // Клиент был в игре, не был ботом и отключился // Нужно попробовать запустить с этой строчкой, чтобы понять какое значение вернется LogError("%i", GetClientAvgLatency(client, NetFlow_Outgoing)); // Как только мы в самый первый раз узнаем что вернет функция, то оставляем только след. строчку, которая будет проверять if (GetClientAvgLatency(client, NetFlow_Outgoing)) != -1 // (или > N, зависит от результатов теста) { // Делаем то, что нужно } } }
думаешь если игрок IsClientInGame, но вышел в последний момент, GetClientAvgLatency вернет 0?
L 05/04/2013 - 23:36:54: [test.smx] 28.329099
L 05/04/2013 - 23:37:41: [test.smx] 67.290275
Если бы ты поподробнее описал цель, возможно тебе бы и помогли.
public OnClientDisconnect(client) // ну или event незнаю, что лучше использовать
{
PrintToChatAll("%N \x01отключился от сервера.", client);
}
Цель: при отключении игрока исключить из проверки тех игроков, которые либо недоподключились или были забанены и не смогли подключится(тем самым вызвав событие дисконнект).
На примере.
PHP:public OnClientDisconnect(client) // ну или event незнаю, что лучше использовать { PrintToChatAll("%N \x01отключился от сервера.", client); }
Так когда, к примеру, забаненый игрок пытается зайти в чат пишет "ник joined the game" но тут оказывается забаненым, ему пишет "user steam id xxxx is banned" а на сервере в чат пишет "ник left the game" и + плагин выводит "ник отключился от сервера.". Так вот должно выводить только когда игрок действительно вышел, а не любой дисконнект.
public OnClientDisconnect_Post(client)
{
PrintToChatAll("%N \x01отключился от сервера.", client);
}