Move OnConVarChanged into a global hook.

This commit is contained in:
David Anderson 2015-08-30 13:59:25 -07:00
parent 32ba03538b
commit 2ed044804d
8 changed files with 144 additions and 40 deletions

View File

@ -41,6 +41,7 @@ project.sources += [
'ConsoleDetours.cpp', 'ConsoleDetours.cpp',
'vprof_tool.cpp', 'vprof_tool.cpp',
'smn_commandline.cpp', 'smn_commandline.cpp',
'GameHooks.cpp',
] ]
for sdk_name in SM.sdks: for sdk_name in SM.sdks:

View File

@ -37,12 +37,6 @@
ConVarManager g_ConVarManager; ConVarManager g_ConVarManager;
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_HOOK3_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *, float);
#else
SH_DECL_HOOK2_void(ICvar, CallGlobalChangeCallback, SH_NOATTRIB, false, ConVar *, const char *);
#endif
#if SOURCE_ENGINE == SE_DOTA #if SOURCE_ENGINE == SE_DOTA
SH_DECL_HOOK5_void(IServerGameDLL, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, CEntityIndex, EQueryCvarValueStatus, const char *, const char *); SH_DECL_HOOK5_void(IServerGameDLL, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, CEntityIndex, EQueryCvarValueStatus, const char *, const char *);
SH_DECL_HOOK5_void(IServerPluginCallbacks, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, CEntityIndex, EQueryCvarValueStatus, const char *, const char *); SH_DECL_HOOK5_void(IServerPluginCallbacks, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, CEntityIndex, EQueryCvarValueStatus, const char *, const char *);
@ -125,12 +119,6 @@ void ConVarManager::OnSourceModAllInitialized()
g_Players.AddClientListener(this); g_Players.AddClientListener(this);
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_ADD_HOOK(ICvar, CallGlobalChangeCallbacks, icvar, SH_STATIC(OnConVarChanged), false);
#else
SH_ADD_HOOK(ICvar, CallGlobalChangeCallback, icvar, SH_STATIC(OnConVarChanged), false);
#endif
scripts->AddPluginsListener(this); scripts->AddPluginsListener(this);
/* Add the 'convars' option to the 'sm' console command */ /* Add the 'convars' option to the 'sm' console command */
@ -198,12 +186,6 @@ void ConVarManager::OnSourceModShutdown()
g_Players.RemoveClientListener(this); g_Players.RemoveClientListener(this);
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_REMOVE_HOOK(ICvar, CallGlobalChangeCallbacks, icvar, SH_STATIC(OnConVarChanged), false);
#else
SH_REMOVE_HOOK(ICvar, CallGlobalChangeCallback, icvar, SH_STATIC(OnConVarChanged), false);
#endif
/* Remove the 'convars' option from the 'sm' console command */ /* Remove the 'convars' option from the 'sm' console command */
rootmenu->RemoveRootConsoleCommand("cvars", this); rootmenu->RemoveRootConsoleCommand("cvars", this);
@ -696,11 +678,7 @@ void ConVarManager::AddConVarToPluginList(IPluginContext *pContext, const ConVar
} }
} }
#if SOURCE_ENGINE >= SE_ORANGEBOX
void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue) void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue)
#else
void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue)
#endif
{ {
/* If the values are the same, exit early in order to not trigger callbacks */ /* If the values are the same, exit early in order to not trigger callbacks */
if (strcmp(pConVar->GetString(), oldValue) == 0) if (strcmp(pConVar->GetString(), oldValue) == 0)
@ -720,16 +698,8 @@ void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue)
if (pInfo->changeListeners.size() != 0) if (pInfo->changeListeners.size() != 0)
{ {
for (List<IConVarChangeListener *>::iterator i = pInfo->changeListeners.begin(); for (auto i = pInfo->changeListeners.begin(); i != pInfo->changeListeners.end(); i++)
i != pInfo->changeListeners.end();
i++)
{
#if SOURCE_ENGINE >= SE_ORANGEBOX
(*i)->OnConVarChanged(pConVar, oldValue, flOldValue); (*i)->OnConVarChanged(pConVar, oldValue, flOldValue);
#else
(*i)->OnConVarChanged(pConVar, oldValue, atof(oldValue));
#endif
}
} }
if (pForward != NULL) if (pForward != NULL)

View File

@ -147,21 +147,15 @@ public:
HandleError ReadConVarHandle(Handle_t hndl, ConVar **pVar); HandleError ReadConVarHandle(Handle_t hndl, ConVar **pVar);
// Called via game hooks.
void OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue);
private: private:
/** /**
* Adds a convar to a plugin's list. * Adds a convar to a plugin's list.
*/ */
static void AddConVarToPluginList(IPluginContext *pContext, const ConVar *pConVar); static void AddConVarToPluginList(IPluginContext *pContext, const ConVar *pConVar);
/**
* Static callback that Valve's ConVar object executes when the convar's value changes.
*/
#if SOURCE_ENGINE >= SE_ORANGEBOX
static void OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue);
#else
static void OnConVarChanged(ConVar *pConVar, const char *oldValue);
#endif
/** /**
* Callback for when StartQueryCvarValue() has finished. * Callback for when StartQueryCvarValue() has finished.
*/ */

68
core/GameHooks.cpp Normal file
View File

@ -0,0 +1,68 @@
// vim: set ts=4 sw=4 tw=99 noet :
// =============================================================================
// SourceMod
// Copyright (C) 2004-2015 AlliedModders LLC. All rights reserved.
// =============================================================================
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License, version 3.0, as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
//
// As a special exception, AlliedModders LLC gives you permission to link the
// code of this program (as well as its derivative works) to "Half-Life 2," the
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
// by the Valve Corporation. You must obey the GNU General Public License in
// all respects for all other code used. Additionally, AlliedModders LLC grants
// this exception to all derivative works. AlliedModders LLC defines further
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
// or <http://www.sourcemod.net/license.php>.
#include "GameHooks.h"
#include "sourcemod.h"
#include "ConVarManager.h"
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_HOOK3_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *, float);
#else
SH_DECL_HOOK2_void(ICvar, CallGlobalChangeCallback, SH_NOATTRIB, false, ConVar *, const char *);
#endif
GameHooks::GameHooks()
{
}
void GameHooks::Start()
{
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_ADD_HOOK(ICvar, CallGlobalChangeCallbacks, icvar, SH_STATIC(OnConVarChanged), false);
#else
SH_ADD_HOOK(ICvar, CallGlobalChangeCallback, icvar, SH_STATIC(OnConVarChanged), false);
#endif
}
void GameHooks::Shutdown()
{
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_REMOVE_HOOK(ICvar, CallGlobalChangeCallbacks, icvar, SH_STATIC(OnConVarChanged), false);
#else
SH_REMOVE_HOOK(ICvar, CallGlobalChangeCallback, icvar, SH_STATIC(OnConVarChanged), false);
#endif
}
#if SOURCE_ENGINE >= SE_ORANGEBOX
void GameHooks::OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue)
{
#else
void GameHooks::OnConVarChanged(ConVar *pConVar, const char *oldValue)
{
float flOldValue = atof(oldValue);
#endif
g_ConVarManager.OnConVarChanged(pConVar, oldValue, flOldValue);
}

52
core/GameHooks.h Normal file
View File

@ -0,0 +1,52 @@
// vim: set ts=4 sw=4 tw=99 noet :
// =============================================================================
// SourceMod
// Copyright (C) 2004-2015 AlliedModders LLC. All rights reserved.
// =============================================================================
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License, version 3.0, as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
//
// As a special exception, AlliedModders LLC gives you permission to link the
// code of this program (as well as its derivative works) to "Half-Life 2," the
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
// by the Valve Corporation. You must obey the GNU General Public License in
// all respects for all other code used. Additionally, AlliedModders LLC grants
// this exception to all derivative works. AlliedModders LLC defines further
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
// or <http://www.sourcemod.net/license.php>.
#ifndef _INCLUDE_SOURCEMOD_PROVIDER_GAME_HOOKS_H_
#define _INCLUDE_SOURCEMOD_PROVIDER_GAME_HOOKS_H_
class ConVar;
namespace SourceMod {
class GameHooks
{
public:
GameHooks();
void Start();
void Shutdown();
// Static callback that Valve's ConVar object executes when the convar's value changes.
#if SOURCE_ENGINE >= SE_ORANGEBOX
static void OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue);
#else
static void OnConVarChanged(ConVar *pConVar, const char *oldValue);
#endif
};
} // namespace SourceMod
#endif // _INCLUDE_SOURCEMOD_PROVIDER_GAME_HOOKS_H_

View File

@ -716,6 +716,16 @@ bool CoreProviderImpl::LoadBridge(char *error, size_t maxlength)
return true; return true;
} }
void CoreProviderImpl::InitializeHooks()
{
hooks_.Start();
}
void CoreProviderImpl::ShutdownHooks()
{
hooks_.Shutdown();
}
void CoreProviderImpl::ShutdownBridge() void CoreProviderImpl::ShutdownBridge()
{ {
logic_ = nullptr; logic_ = nullptr;

View File

@ -28,6 +28,7 @@
#define _INCLUDE_SOURCEMOD_CORE_PROVIDER_IMPL_H_ #define _INCLUDE_SOURCEMOD_CORE_PROVIDER_IMPL_H_
#include "logic/intercom.h" #include "logic/intercom.h"
#include "GameHooks.h"
#include <amtl/os/am-shared-library.h> #include <amtl/os/am-shared-library.h>
class CoreProviderImpl : public CoreProvider class CoreProviderImpl : public CoreProvider
@ -40,6 +41,9 @@ public:
bool LoadBridge(char *error, size_t maxlength); bool LoadBridge(char *error, size_t maxlength);
void ShutdownBridge(); void ShutdownBridge();
void InitializeHooks();
void ShutdownHooks();
// Provider implementation. // Provider implementation.
ConVar *FindConVar(const char *name) override; ConVar *FindConVar(const char *name) override;
const char *GetCvarString(ConVar *cvar) override; const char *GetCvarString(ConVar *cvar) override;
@ -61,6 +65,7 @@ public:
private: private:
ke::Ref<ke::SharedLib> logic_; ke::Ref<ke::SharedLib> logic_;
LogicInitFunction logic_init_; LogicInitFunction logic_init_;
GameHooks hooks_;
}; };
extern CoreProviderImpl sCoreProviderImpl; extern CoreProviderImpl sCoreProviderImpl;

View File

@ -267,6 +267,8 @@ void SourceModBase::StartSourceMod(bool late)
} }
g_pGameConf = logicore.GetCoreGameConfig(); g_pGameConf = logicore.GetCoreGameConfig();
sCoreProviderImpl.InitializeHooks();
/* Notify! */ /* Notify! */
pBase = SMGlobalClass::head; pBase = SMGlobalClass::head;
while (pBase) while (pBase)
@ -520,6 +522,8 @@ void SourceModBase::ShutdownServices()
} }
m_freepacks.popall(); m_freepacks.popall();
sCoreProviderImpl.ShutdownHooks();
/* Notify! */ /* Notify! */
pBase = SMGlobalClass::head; pBase = SMGlobalClass::head;
while (pBase) while (pBase)