Remove unfinished ConVar queries on client disconnect (bug 6003, r=psychonic).

This commit is contained in:
Kyle Sanderson 2014-02-27 19:55:13 -07:00
parent 5630fa67fc
commit 3fffcdb931
2 changed files with 28 additions and 2 deletions

View File

@ -126,6 +126,8 @@ void ConVarManager::OnSourceModAllInitialized()
} }
#endif #endif
g_Players.AddClientListener(this);
SH_ADD_HOOK_STATICFUNC(ICvar, CallGlobalChangeCallbacks, icvar, OnConVarChanged, false); SH_ADD_HOOK_STATICFUNC(ICvar, CallGlobalChangeCallbacks, icvar, OnConVarChanged, false);
g_PluginSys.AddPluginsListener(this); g_PluginSys.AddPluginsListener(this);
@ -191,6 +193,8 @@ void ConVarManager::OnSourceModShutdown()
} }
#endif #endif
g_Players.RemoveClientListener(this);
SH_REMOVE_HOOK_STATICFUNC(ICvar, CallGlobalChangeCallbacks, icvar, OnConVarChanged, false); SH_REMOVE_HOOK_STATICFUNC(ICvar, CallGlobalChangeCallbacks, icvar, OnConVarChanged, false);
/* Remove the 'convars' option from the 'sm' console command */ /* Remove the 'convars' option from the 'sm' console command */
@ -307,6 +311,22 @@ void ConVarManager::OnPluginUnloaded(IPlugin *plugin)
} }
} }
void ConVarManager::OnClientDisconnected(int client)
{
/* Remove convar queries for this client that haven't returned results yet */
for (List<ConVarQuery>::iterator iter = m_ConVarQueries.begin(); iter != m_ConVarQueries.end();)
{
ConVarQuery &query = (*iter);
if (query.client == client)
{
iter = m_ConVarQueries.erase(iter);
continue;
}
++iter;
}
}
void ConVarManager::OnHandleDestroy(HandleType_t type, void *object) void ConVarManager::OnHandleDestroy(HandleType_t type, void *object)
{ {
} }
@ -619,7 +639,7 @@ QueryCvarCookie_t ConVarManager::QueryClientConVar(edict_t *pPlayer, const char
return InvalidQueryCvarCookie; return InvalidQueryCvarCookie;
} }
ConVarQuery query = {cookie, pCallback, hndl}; ConVarQuery query = {cookie, pCallback, (cell_t)hndl, IndexOfEdict(pPlayer)};
m_ConVarQueries.push_back(query); m_ConVarQueries.push_back(query);
#endif #endif

View File

@ -39,8 +39,10 @@
#include <IForwardSys.h> #include <IForwardSys.h>
#include <IHandleSys.h> #include <IHandleSys.h>
#include <IRootConsoleMenu.h> #include <IRootConsoleMenu.h>
#include <IPlayerHelpers.h>
#include <compat_wrappers.h> #include <compat_wrappers.h>
#include "concmd_cleaner.h" #include "concmd_cleaner.h"
#include "PlayerManager.h"
#if SOURCE_ENGINE == SE_DARKMESSIAH #if SOURCE_ENGINE == SE_DARKMESSIAH
class EQueryCvarValueStatus; class EQueryCvarValueStatus;
@ -75,6 +77,7 @@ struct ConVarQuery
QueryCvarCookie_t cookie; /**< Cookie that identifies query */ QueryCvarCookie_t cookie; /**< Cookie that identifies query */
IPluginFunction *pCallback; /**< Function that will be called when query is finished */ IPluginFunction *pCallback; /**< Function that will be called when query is finished */
cell_t value; /**< Optional value passed to query function */ cell_t value; /**< Optional value passed to query function */
cell_t client; /**< Only used for cleaning up on client disconnection */
}; };
class ConVarManager : class ConVarManager :
@ -82,7 +85,8 @@ class ConVarManager :
public IHandleTypeDispatch, public IHandleTypeDispatch,
public IPluginsListener, public IPluginsListener,
public IRootConsoleCommand, public IRootConsoleCommand,
public IConCommandTracker public IConCommandTracker,
public IClientListener
{ {
public: public:
ConVarManager(); ConVarManager();
@ -101,6 +105,8 @@ public: //IRootConsoleCommand
void OnRootConsoleCommand(const char *cmdname, const CCommand &command); void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
public: //IConCommandTracker public: //IConCommandTracker
void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe); void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe);
public: //IClientListener
void OnClientDisconnected(int client);
public: public:
/** /**
* Create a convar and return a handle to it. * Create a convar and return a handle to it.