AntonZavodskih С отключением немного сложнее
Ибо отключение бывают несколько видов
1 Игрок нажал отключиться и ждет 15 сек
2 Игрок нажал отключиться и не ждет а жмакает отключиться
3 Игрок отключился тк крашнулся клиент
4 Игрок отключился тк произошел разрыв связи, баттлай его кикнул (тут баттла сама в чат всем напишет)
вобщем есть решение, но оно иногда может написать 2 раза в чат
Берем нативную функцию обработки отключения InvokeOnDisconnect и делаем отправку сообщения в чат там
Ну и вставляем в тот же класс мисcии под InvokeOnConnect
override void InvokeOnDisconnect( PlayerBase player )
{
if (player && player.GetIdentity())
{
GetGame().ChatPlayer("Игрок " + player.GetIdentity().GetName() + " отключился");
}
super.InvokeOnDisconnect( player );
}
Но иногда Identity для перса уже NULL и сообщение не отправляется... Вот в чем засада
А отправлять сообщение без имени не комильфо.
Потому решал сделать еще и так:
override void OnClientDisconnectedEvent(PlayerIdentity identity, PlayerBase player, int logoutTime, bool authFailed)
{
if (player.GetIdentity())
{
string playerNAME = player.GetIdentity().GetName(); // Помещаем в переменную имя игрока заранее
}
//Код из штатной функции весь тут тк мы вносим изменения и в него то же, а не просто дополняем, поэтому вызова нативной функции через super тут не будет
bool disconnectNow = true;
Message = "Игрок " + playerNAME + " отключился";
msgSended = false;
// TODO: get out of vehicle
// using database and no saving if authorization failed
// TODO: get out of vehicle
// using database and no saving if authorization failed
if (GetHive() && !authFailed)
{
if (player.IsAlive())
{
if (!m_LogoutPlayers.Contains(player))
{
Print("[Logout]: New player " + identity.GetId() + " with logout time " + logoutTime.ToString());
// inform client about logout time
GetGame().SendLogoutTime(player, logoutTime);
// wait for some time before logout and save
LogoutInfo params = new LogoutInfo(GetGame().GetTime() + logoutTime * 1000, identity.GetId());
m_LogoutPlayers.Insert(player, params);
// allow reconnecting to old char
GetGame().AddToReconnectCache(identity);
// wait until logout timer runs out
disconnectNow = false;
}
return;
}
}
//Код из штатной функции
//Код из штатной функции
if (disconnectNow) //условие выполнится если клиент долждался обратного отчета или нажал кнопку отключения не ожидая таймаута
{
Print("[Logout]: New player " + identity.GetId() + " with instant logout");
// inform client about instant logout
GetGame().SendLogoutTime(player, 1);
PlayerDisconnected(player, identity, identity.GetId());
//После PlayerDisconnected identity уже всегда NULL и имя игрока, но мы заранее поместили в переменную playerNAME имя отключающегося игрока.
//Проверяем получено имя игрока в начале.
if (playerNAME)
{
GetGame().ChatPlayer(message);
msgSended = true;
}
}
//Код из штатной функции
//Можно конечтно и тут организовать доп проверку (а вдруг disconnectNow = false, а игрок все же отключился - такое бывало много раз)
if (!identity && playerNAME && !msgSended) //Если identity = NULL (клиент отключился), получено имя игрока в начале и сообщение не отсылалось в предыдущем условии
{
GetGame().ChatPlayer(message);
}
}
Откорректировал штатную функцию и переопределил ее ниже под переопределенной InvokeOnConnect
Правда бывает (редко) прилетает 2 сообщения, но редко