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);
|
SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
|
||||||
#endif
|
#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
|
#if SOURCE_ENGINE == SE_DOTA
|
||||||
SH_DECL_EXTERN2_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommandContext &, const CCommand &);
|
SH_DECL_EXTERN2_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommandContext &, const CCommand &);
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
#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, ClientCommand, serverClients, SH_MEMBER(this, &PlayerManager::OnClientCommand), false);
|
||||||
SH_ADD_HOOK(IServerGameClients, ClientSettingsChanged, serverClients, SH_MEMBER(this, &PlayerManager::OnClientSettingsChanged), true);
|
SH_ADD_HOOK(IServerGameClients, ClientSettingsChanged, serverClients, SH_MEMBER(this, &PlayerManager::OnClientSettingsChanged), true);
|
||||||
SH_ADD_HOOK(IServerGameDLL, ServerActivate, gamedll, SH_MEMBER(this, &PlayerManager::OnServerActivate), 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);
|
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, ClientCommand, serverClients, SH_MEMBER(this, &PlayerManager::OnClientCommand), false);
|
||||||
SH_REMOVE_HOOK(IServerGameClients, ClientSettingsChanged, serverClients, SH_MEMBER(this, &PlayerManager::OnClientSettingsChanged), true);
|
SH_REMOVE_HOOK(IServerGameClients, ClientSettingsChanged, serverClients, SH_MEMBER(this, &PlayerManager::OnClientSettingsChanged), true);
|
||||||
SH_REMOVE_HOOK(IServerGameDLL, ServerActivate, gamedll, SH_MEMBER(this, &PlayerManager::OnServerActivate), 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 */
|
/* Release forwards */
|
||||||
forwardsys->ReleaseForward(m_clconnect);
|
forwardsys->ReleaseForward(m_clconnect);
|
||||||
@ -756,6 +772,36 @@ void PlayerManager::OnSourceModLevelEnd()
|
|||||||
m_PlayerCount = 0;
|
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
|
#if SOURCE_ENGINE == SE_DOTA
|
||||||
void PlayerManager::OnClientDisconnect(CEntityIndex index, int reason)
|
void PlayerManager::OnClientDisconnect(CEntityIndex index, int reason)
|
||||||
{
|
{
|
||||||
|
@ -174,6 +174,7 @@ public:
|
|||||||
void OnClientSettingsChanged(edict_t *pEntity);
|
void OnClientSettingsChanged(edict_t *pEntity);
|
||||||
//void OnClientSettingsChanged_Pre(edict_t *pEntity);
|
//void OnClientSettingsChanged_Pre(edict_t *pEntity);
|
||||||
#endif
|
#endif
|
||||||
|
void OnServerHibernationUpdate(bool bHibernating);
|
||||||
public: //IPlayerManager
|
public: //IPlayerManager
|
||||||
void AddClientListener(IClientListener *listener);
|
void AddClientListener(IClientListener *listener);
|
||||||
void RemoveClientListener(IClientListener *listener);
|
void RemoveClientListener(IClientListener *listener);
|
||||||
|
Loading…
Reference in New Issue
Block a user