Merge pull request #20 from psychonic/bot-hibernation-disconnect
Fix case where bots leave server without disconnect notice (hibernation) (r=KyleS).
This commit is contained in:
commit
39993c7019
@ -81,6 +81,12 @@ SH_DECL_HOOK0_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0);
|
||||
SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD && SOURCE_ENGINE != SE_DOTA
|
||||
SH_DECL_HOOK1_void(IServerGameDLL, ServerHibernationUpdate, SH_NOATTRIB, 0, bool);
|
||||
#elif SOURCE_ENGINE > SE_EYE // 2013/orangebox, but not original orangebox. +dota
|
||||
SH_DECL_HOOK1_void(IServerGameDLL, SetServerHibernation, SH_NOATTRIB, 0, bool);
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
SH_DECL_EXTERN2_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommandContext &, const CCommand &);
|
||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
@ -152,6 +158,11 @@ void PlayerManager::OnSourceModAllInitialized()
|
||||
SH_ADD_HOOK(IServerGameClients, ClientCommand, serverClients, SH_MEMBER(this, &PlayerManager::OnClientCommand), false);
|
||||
SH_ADD_HOOK(IServerGameClients, ClientSettingsChanged, serverClients, SH_MEMBER(this, &PlayerManager::OnClientSettingsChanged), true);
|
||||
SH_ADD_HOOK(IServerGameDLL, ServerActivate, gamedll, SH_MEMBER(this, &PlayerManager::OnServerActivate), true);
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD && SOURCE_ENGINE != SE_DOTA
|
||||
SH_ADD_HOOK(IServerGameDLL, ServerHibernationUpdate, gamedll, SH_MEMBER(this, &PlayerManager::OnServerHibernationUpdate), true);
|
||||
#elif SOURCE_ENGINE > SE_EYE // 2013/orangebox, but not original orangebox. +dota
|
||||
SH_ADD_HOOK(IServerGameDLL, SetServerHibernation, gamedll, SH_MEMBER(this, &PlayerManager::OnServerHibernationUpdate), true);
|
||||
#endif
|
||||
|
||||
sharesys->AddInterface(NULL, this);
|
||||
|
||||
@ -194,6 +205,11 @@ void PlayerManager::OnSourceModShutdown()
|
||||
SH_REMOVE_HOOK(IServerGameClients, ClientCommand, serverClients, SH_MEMBER(this, &PlayerManager::OnClientCommand), false);
|
||||
SH_REMOVE_HOOK(IServerGameClients, ClientSettingsChanged, serverClients, SH_MEMBER(this, &PlayerManager::OnClientSettingsChanged), true);
|
||||
SH_REMOVE_HOOK(IServerGameDLL, ServerActivate, gamedll, SH_MEMBER(this, &PlayerManager::OnServerActivate), true);
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD && SOURCE_ENGINE != SE_DOTA
|
||||
SH_REMOVE_HOOK(IServerGameDLL, ServerHibernationUpdate, gamedll, SH_MEMBER(this, &PlayerManager::OnServerHibernationUpdate), true);
|
||||
#elif SOURCE_ENGINE > SE_EYE // 2013/orangebox, but not original orangebox. +dota
|
||||
SH_REMOVE_HOOK(IServerGameDLL, SetServerHibernation, gamedll, SH_MEMBER(this, &PlayerManager::OnServerHibernationUpdate), true);
|
||||
#endif
|
||||
|
||||
/* Release forwards */
|
||||
forwardsys->ReleaseForward(m_clconnect);
|
||||
@ -756,6 +772,36 @@ void PlayerManager::OnSourceModLevelEnd()
|
||||
m_PlayerCount = 0;
|
||||
}
|
||||
|
||||
void PlayerManager::OnServerHibernationUpdate(bool bHibernating)
|
||||
{
|
||||
/* If bots were added at map start, but not fully inited before hibernation, there will
|
||||
* be no OnClientDisconnect for them, despite them getting booted right before this.
|
||||
*/
|
||||
|
||||
if (bHibernating)
|
||||
{
|
||||
for (int i = 1; i <= m_maxClients; i++)
|
||||
{
|
||||
CPlayer *pPlayer = &m_Players[i];
|
||||
if (pPlayer->IsConnected() && pPlayer->IsFakeClient())
|
||||
{
|
||||
#if SOURCE_ENGINE < SE_LEFT4DEAD || SOURCE_ENGINE >= SE_CSGO || SOURCE_ENGINE == SE_NUCLEARDAWN
|
||||
// These games have the bug fixed where hltv/replay was getting kicked on hibernation
|
||||
if (pPlayer->IsSourceTV() || pPlayer->IsReplay())
|
||||
continue;
|
||||
#endif
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
OnClientDisconnect(m_Players[i].GetIndex(), 0);
|
||||
OnClientDisconnect_Post(m_Players[i].GetIndex(), 0);
|
||||
#else
|
||||
OnClientDisconnect(m_Players[i].GetEdict());
|
||||
OnClientDisconnect_Post(m_Players[i].GetEdict());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
void PlayerManager::OnClientDisconnect(CEntityIndex index, int reason)
|
||||
{
|
||||
|
@ -174,6 +174,7 @@ public:
|
||||
void OnClientSettingsChanged(edict_t *pEntity);
|
||||
//void OnClientSettingsChanged_Pre(edict_t *pEntity);
|
||||
#endif
|
||||
void OnServerHibernationUpdate(bool bHibernating);
|
||||
public: //IPlayerManager
|
||||
void AddClientListener(IClientListener *listener);
|
||||
void RemoveClientListener(IClientListener *listener);
|
||||
|
Loading…
Reference in New Issue
Block a user