overhaul of the vsp listening code
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401587
This commit is contained in:
parent
0600be8c3a
commit
60d8e4f248
@ -46,7 +46,7 @@ SH_DECL_HOOK5_void(IServerPluginCallbacks, OnQueryCvarValueFinished, SH_NOATTRIB
|
||||
const ParamType CONVARCHANGE_PARAMS[] = {Param_Cell, Param_String, Param_String};
|
||||
typedef List<const ConVar *> ConVarList;
|
||||
|
||||
ConVarManager::ConVarManager() : m_ConVarType(0), m_VSPIface(NULL), m_CanQueryConVars(false)
|
||||
ConVarManager::ConVarManager() : m_ConVarType(0), m_bIsDLLQueryHooked(false), m_bIsVSPQueryHooked(false)
|
||||
{
|
||||
#if PLAPI_VERSION < 12
|
||||
m_IgnoreHandle = false;
|
||||
@ -74,11 +74,15 @@ ConVarManager::~ConVarManager()
|
||||
|
||||
void ConVarManager::OnSourceModAllInitialized()
|
||||
{
|
||||
/* Only valid with ServerGameDLL006 or greater */
|
||||
/**
|
||||
* Episode 2 has this function by default, but the older versions do not.
|
||||
*/
|
||||
#if !defined ORANGEBOX_BUILD
|
||||
if (g_SMAPI->GetGameDLLVersion() >= 6)
|
||||
#endif
|
||||
{
|
||||
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, OnQueryCvarValueFinished, gamedll, this, &ConVarManager::OnQueryCvarValueFinished, false);
|
||||
m_CanQueryConVars = true;
|
||||
m_bIsDLLQueryHooked = true;
|
||||
}
|
||||
|
||||
HandleAccess sec;
|
||||
@ -97,10 +101,15 @@ void ConVarManager::OnSourceModAllInitialized()
|
||||
|
||||
void ConVarManager::OnSourceModShutdown()
|
||||
{
|
||||
if (m_CanQueryConVars)
|
||||
if (m_bIsDLLQueryHooked)
|
||||
{
|
||||
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, OnQueryCvarValueFinished, gamedll, this, &ConVarManager::OnQueryCvarValueFinished, false);
|
||||
SH_REMOVE_HOOK_MEMFUNC(IServerPluginCallbacks, OnQueryCvarValueFinished, m_VSPIface, this, &ConVarManager::OnQueryCvarValueFinished, false);
|
||||
m_bIsDLLQueryHooked = false;
|
||||
}
|
||||
else if (m_bIsVSPQueryHooked)
|
||||
{
|
||||
SH_REMOVE_HOOK_MEMFUNC(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, this, &ConVarManager::OnQueryCvarValueFinished, false);
|
||||
m_bIsVSPQueryHooked = false;
|
||||
}
|
||||
|
||||
IChangeableForward *fwd;
|
||||
@ -125,27 +134,35 @@ void ConVarManager::OnSourceModShutdown()
|
||||
g_HandleSys.RemoveType(m_ConVarType, g_pCoreIdent);
|
||||
}
|
||||
|
||||
void ConVarManager::OnSourceModVSPReceived(IServerPluginCallbacks *iface)
|
||||
/**
|
||||
* Orange Box will never use this.
|
||||
*/
|
||||
void ConVarManager::OnSourceModVSPReceived()
|
||||
{
|
||||
/* This will be called after OnSourceModAllInitialized(), so...
|
||||
*
|
||||
* If we haven't been able to hook the IServerGameDLL version at this point,
|
||||
* then use hook IServerPluginCallbacks version from the engine.
|
||||
/**
|
||||
* Don't bother if the DLL is already hooked.
|
||||
*/
|
||||
|
||||
/* The Ship currently only supports ServerPluginCallbacks001, but we need 002 */
|
||||
if (g_IsOriginalEngine)
|
||||
if (m_bIsDLLQueryHooked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_CanQueryConVars)
|
||||
/* For later MM:S versions, use the updated API, since it's cleaner. */
|
||||
#if defined METAMOD_PLAPI_VERSION
|
||||
int engine = g_SMAPI->GetSourceEngineBuild();
|
||||
if (engine == SOURCE_ENGINE_ORIGINAL || vsp_version < 2)
|
||||
{
|
||||
m_VSPIface = iface;
|
||||
|
||||
SH_ADD_HOOK_MEMFUNC(IServerPluginCallbacks, OnQueryCvarValueFinished, iface, this, &ConVarManager::OnQueryCvarValueFinished, false);
|
||||
m_CanQueryConVars = true;
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (g_HL2.IsOriginalEngine() || vsp_version < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
SH_ADD_HOOK_MEMFUNC(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, this, &ConVarManager::OnQueryCvarValueFinished, false);
|
||||
m_bIsVSPQueryHooked = true;
|
||||
}
|
||||
|
||||
#if PLAPI_VERSION >= 12
|
||||
@ -306,7 +323,9 @@ Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name,
|
||||
if (sm_trie_retrieve(m_ConVarCache, name, (void **)&pInfo))
|
||||
{
|
||||
return pInfo->handle;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we don't, then create a new handle from the convar */
|
||||
hndl = g_HandleSys.CreateHandle(m_ConVarType, pConVar, NULL, g_pCoreIdent, NULL);
|
||||
|
||||
@ -478,12 +497,18 @@ QueryCvarCookie_t ConVarManager::QueryClientConVar(edict_t *pPlayer, const char
|
||||
QueryCvarCookie_t cookie;
|
||||
|
||||
/* Call StartQueryCvarValue() in either the IVEngineServer or IServerPluginHelpers depending on situation */
|
||||
if (!m_VSPIface)
|
||||
if (m_bIsDLLQueryHooked)
|
||||
{
|
||||
cookie = engine->StartQueryCvarValue(pPlayer, name);
|
||||
} else {
|
||||
}
|
||||
else if (m_bIsVSPQueryHooked)
|
||||
{
|
||||
cookie = serverpluginhelpers->StartQueryCvarValue(pPlayer, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return InvalidQueryCvarCookie;
|
||||
}
|
||||
|
||||
ConVarQuery query = {cookie, pCallback, hndl};
|
||||
m_ConVarQueries.push_back(query);
|
||||
@ -505,7 +530,9 @@ void ConVarManager::AddConVarToPluginList(IPluginContext *pContext, const ConVar
|
||||
{
|
||||
pConVarList = new ConVarList();
|
||||
plugin->SetProperty("ConVarList", pConVarList);
|
||||
} else if (pConVarList->find(pConVar) != pConVarList->end()) {
|
||||
}
|
||||
else if (pConVarList->find(pConVar) != pConVarList->end())
|
||||
{
|
||||
/* If convar is already in list, then don't add it */
|
||||
return;
|
||||
}
|
||||
@ -568,6 +595,11 @@ void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue)
|
||||
pForward->Execute(NULL);
|
||||
}
|
||||
|
||||
bool ConVarManager::IsQueryingSupported()
|
||||
{
|
||||
return (m_bIsDLLQueryHooked || m_bIsVSPQueryHooked);
|
||||
}
|
||||
|
||||
void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue)
|
||||
{
|
||||
IPluginFunction *pCallback = NULL;
|
||||
@ -597,7 +629,9 @@ void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *
|
||||
if (result == eQueryCvarValueStatus_ValueIntact)
|
||||
{
|
||||
pCallback->PushString(cvarValue);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
pCallback->PushString("\0");
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ public:
|
||||
public: // SMGlobalClass
|
||||
void OnSourceModAllInitialized();
|
||||
void OnSourceModShutdown();
|
||||
void OnSourceModVSPReceived(IServerPluginCallbacks *iface);
|
||||
void OnSourceModVSPReceived();
|
||||
public: // IHandleTypeDispatch
|
||||
void OnHandleDestroy(HandleType_t type, void *object);
|
||||
public: // IPluginsListener
|
||||
@ -131,6 +131,8 @@ public:
|
||||
QueryCvarCookie_t QueryClientConVar(edict_t *pPlayer, const char *name, IPluginFunction *pCallback,
|
||||
Handle_t hndl);
|
||||
|
||||
bool IsQueryingSupported();
|
||||
|
||||
#if PLAPI_VERSION >= 12
|
||||
/**
|
||||
* Called when Metamod:Source is about to remove convar
|
||||
@ -167,8 +169,8 @@ private:
|
||||
List<ConVarInfo *> m_ConVars;
|
||||
List<ConVarQuery> m_ConVarQueries;
|
||||
Trie *m_ConVarCache;
|
||||
IServerPluginCallbacks *m_VSPIface;
|
||||
bool m_CanQueryConVars;
|
||||
bool m_bIsDLLQueryHooked;
|
||||
bool m_bIsVSPQueryHooked;
|
||||
#if PLAPI_VERSION < 12
|
||||
bool m_IgnoreHandle;
|
||||
#endif
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include <compat_wrappers.h>
|
||||
|
||||
CHalfLife2 g_HL2;
|
||||
bool g_IsOriginalEngine = false;
|
||||
ConVar *sv_lan = NULL;
|
||||
|
||||
namespace SourceHook
|
||||
@ -90,15 +89,21 @@ CHalfLife2::~CHalfLife2()
|
||||
}
|
||||
|
||||
CSharedEdictChangeInfo *g_pSharedChangeInfo = NULL;
|
||||
bool is_original_engine = false;
|
||||
|
||||
void CHalfLife2::OnSourceModStartup(bool late)
|
||||
{
|
||||
/* The Ship currently is the only known game to use an older version of the engine */
|
||||
#if defined METAMOD_PLAPI_VERSION
|
||||
if (g_SMAPI->GetSourceEngineBuild() == SOURCE_ENGINE_ORIGINAL)
|
||||
#else
|
||||
if (strcasecmp(g_SourceMod.GetGameFolderName(), "ship") == 0)
|
||||
#endif
|
||||
{
|
||||
is_original_engine = true;
|
||||
}
|
||||
else if (g_pSharedChangeInfo == NULL)
|
||||
{
|
||||
/* :TODO: Better engine versioning - perhaps something added to SourceMM? */
|
||||
g_IsOriginalEngine = true;
|
||||
} else if (!g_pSharedChangeInfo) {
|
||||
g_pSharedChangeInfo = engine->GetSharedEdictChangeInfo();
|
||||
}
|
||||
}
|
||||
@ -111,6 +116,13 @@ void CHalfLife2::OnSourceModAllInitialized()
|
||||
g_ShareSys.AddInterface(NULL, this);
|
||||
}
|
||||
|
||||
#if !defined METAMOD_PLAPI_VERSION
|
||||
bool CHalfLife2::IsOriginalEngine()
|
||||
{
|
||||
return is_original_engine;
|
||||
}
|
||||
#endif
|
||||
|
||||
IChangeInfoAccessor *CBaseEdict::GetChangeAccessor()
|
||||
{
|
||||
return engine->GetChangeAccessor( (const edict_t *)this );
|
||||
@ -254,7 +266,7 @@ typedescription_t *CHalfLife2::FindInDataMap(datamap_t *pMap, const char *offset
|
||||
|
||||
void CHalfLife2::SetEdictStateChanged(edict_t *pEdict, unsigned short offset)
|
||||
{
|
||||
if (!g_IsOriginalEngine)
|
||||
if (g_pSharedChangeInfo != NULL)
|
||||
{
|
||||
if (offset)
|
||||
{
|
||||
@ -262,7 +274,9 @@ void CHalfLife2::SetEdictStateChanged(edict_t *pEdict, unsigned short offset)
|
||||
} else {
|
||||
pEdict->StateChanged();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
pEdict->m_fStateFlags |= FL_EDICT_CHANGED;
|
||||
}
|
||||
}
|
||||
|
@ -105,6 +105,9 @@ public:
|
||||
void PopCommandStack();
|
||||
const CCommand *PeekCommandStack();
|
||||
const char *CurrentCommandName();
|
||||
#if !defined METAMOD_PLAPI_VERSION
|
||||
bool IsOriginalEngine();
|
||||
#endif
|
||||
private:
|
||||
DataTableInfo *_FindServerClass(const char *classname);
|
||||
private:
|
||||
@ -120,6 +123,5 @@ private:
|
||||
};
|
||||
|
||||
extern CHalfLife2 g_HL2;
|
||||
extern bool g_IsOriginalEngine;
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_CHALFLIFE2_H_
|
||||
|
@ -799,6 +799,10 @@
|
||||
RelativePath="..\ChatTriggers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\public\compat_wrappers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\ConCmdManager.h"
|
||||
>
|
||||
|
@ -143,7 +143,7 @@ public:
|
||||
/**
|
||||
* @brief Called when SourceMod receives a pointer to IServerPluginCallbacks from SourceMM
|
||||
*/
|
||||
virtual void OnSourceModVSPReceived(IServerPluginCallbacks *iface)
|
||||
virtual void OnSourceModVSPReceived()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -507,7 +507,7 @@ static cell_t sm_QueryClientConVar(IPluginContext *pContext, const cell_t *param
|
||||
char *name;
|
||||
IPluginFunction *pCallback;
|
||||
|
||||
if (g_IsOriginalEngine)
|
||||
if (!g_ConVarManager.IsQueryingSupported())
|
||||
{
|
||||
if (!s_QueryAlreadyWarned)
|
||||
{
|
||||
|
@ -36,17 +36,6 @@
|
||||
#include "PlayerManager.h"
|
||||
#include "HalfLife2.h"
|
||||
|
||||
IServerPluginCallbacks *g_VSP = NULL;
|
||||
|
||||
class HalfLifeNatives : public SMGlobalClass
|
||||
{
|
||||
public: //SMGlobalClass
|
||||
void OnSourceModVSPReceived(IServerPluginCallbacks *iface)
|
||||
{
|
||||
g_VSP = iface;
|
||||
}
|
||||
};
|
||||
|
||||
static cell_t SetRandomSeed(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
engrandom->SetSeed(params[1]);
|
||||
@ -270,7 +259,10 @@ static cell_t smn_CreateDialog(IPluginContext *pContext, const cell_t *params)
|
||||
return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
serverpluginhelpers->CreateMessage(pPlayer->GetEdict(), static_cast<DIALOG_TYPE>(params[3]), pKV, g_VSP);
|
||||
serverpluginhelpers->CreateMessage(pPlayer->GetEdict(),
|
||||
static_cast<DIALOG_TYPE>(params[3]),
|
||||
pKV,
|
||||
vsp_interface);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -415,8 +407,6 @@ static cell_t ShowVGUIPanel(IPluginContext *pContext, const cell_t *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HalfLifeNatives s_HalfLifeNatives;
|
||||
|
||||
REGISTER_NATIVES(halflifeNatives)
|
||||
{
|
||||
{"CreateFakeClient", CreateFakeClient},
|
||||
|
@ -50,6 +50,8 @@ IPlayerInfoManager *playerinfo = NULL;
|
||||
IBaseFileSystem *basefilesystem = NULL;
|
||||
IEngineSound *enginesound = NULL;
|
||||
IServerPluginHelpers *serverpluginhelpers = NULL;
|
||||
IServerPluginCallbacks *vsp_interface = NULL;
|
||||
int vsp_version = 0;
|
||||
|
||||
PLUGIN_EXPOSE(SourceMod, g_SourceMod_Core);
|
||||
|
||||
@ -82,7 +84,13 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen
|
||||
gpGlobals = ismm->GetCGlobals();
|
||||
|
||||
ismm->AddListener(this, this);
|
||||
ismm->EnableVSPListener();
|
||||
|
||||
#if defined METAMOD_PLAPI_VERSION
|
||||
if ((vsp_interface = g_SMAPI->GetVSPInfo(&vsp_version)) == NULL)
|
||||
#endif
|
||||
{
|
||||
g_SMAPI->EnableVSPListener();
|
||||
}
|
||||
|
||||
return g_SourceMod.InitializeSourceMod(error, maxlen, late);
|
||||
}
|
||||
@ -153,15 +161,44 @@ void SourceMod_Core::OnVSPListening(IServerPluginCallbacks *iface)
|
||||
/* This shouldn't happen */
|
||||
if (!iface)
|
||||
{
|
||||
g_Logger.LogFatal("Metamod:Source version is out of date. SourceMod requires 1.4 or greater.");
|
||||
g_Logger.LogFatal("Metamod:Source version is out of date. SourceMod requires 1.4.2 or greater.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (vsp_interface == NULL)
|
||||
{
|
||||
vsp_interface = iface;
|
||||
}
|
||||
|
||||
if (!g_Loaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined METAMOD_PLAPI_VERSION
|
||||
if (vsp_version == 0)
|
||||
{
|
||||
g_SMAPI->GetVSPInfo(&vsp_version);
|
||||
}
|
||||
#else
|
||||
if (vsp_version == 0)
|
||||
{
|
||||
if (strcmp(g_SourceMod.GetGameFolderName(), "ship") == 0)
|
||||
{
|
||||
vsp_version = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
vsp_version = 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Notify! */
|
||||
SMGlobalClass *pBase = SMGlobalClass::head;
|
||||
while (pBase)
|
||||
{
|
||||
pBase->OnSourceModVSPReceived(iface);
|
||||
pBase->OnSourceModVSPReceived();
|
||||
pBase = pBase->m_pGlobalClassNext;
|
||||
}
|
||||
}
|
||||
|
@ -96,6 +96,8 @@ extern IPlayerInfoManager *playerinfo;
|
||||
extern IBaseFileSystem *basefilesystem;
|
||||
extern IEngineSound *enginesound;
|
||||
extern IServerPluginHelpers *serverpluginhelpers;
|
||||
extern IServerPluginCallbacks *vsp_interface;
|
||||
extern int vsp_version;
|
||||
|
||||
#define ENGINE_CALL(func) SH_CALL(enginePatch, &IVEngineServer::func)
|
||||
#define SERVER_CALL(func) SH_CALL(gamedllPatch, &IServerGameDLL::func)
|
||||
|
@ -306,6 +306,12 @@ void SourceModBase::StartSourceMod(bool late)
|
||||
|
||||
/* We're loaded! */
|
||||
g_Loaded = true;
|
||||
|
||||
/* Initialize VSP stuff */
|
||||
if (vsp_interface != NULL)
|
||||
{
|
||||
g_SourceMod_Core.OnVSPListening(vsp_interface);
|
||||
}
|
||||
}
|
||||
|
||||
static bool g_LevelEndBarrier = false;
|
||||
|
@ -128,6 +128,7 @@ private:
|
||||
bool m_GotBasePath;
|
||||
};
|
||||
|
||||
extern bool g_Loaded;
|
||||
extern SourceModBase g_SourceMod;
|
||||
extern HandleType_t g_WrBitBufType; //:TODO: find a better place for this
|
||||
extern HandleType_t g_RdBitBufType; //:TODO: find a better place for this
|
||||
|
Loading…
Reference in New Issue
Block a user