1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2024-11-28 10:24:20 +01:00

Added plugin pausing, the Plugin typedef is now an int, SH_GLOB_PLUGPTR is now g_PLID by default

--HG--
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%409
This commit is contained in:
Pavol Marko 2005-04-16 20:26:33 +00:00
parent 118d4a85ff
commit aed73ffa76
5 changed files with 83 additions and 11 deletions

View File

@ -17,7 +17,7 @@
#endif #endif
#ifndef SH_GLOB_PLUGPTR #ifndef SH_GLOB_PLUGPTR
#define SH_GLOB_PLUGPTR g_Plug #define SH_GLOB_PLUGPTR g_PLID
#endif #endif
#define SH_ASSERT(x) if (!(x)) __asm { int 3 } #define SH_ASSERT(x) if (!(x)) __asm { int 3 }
@ -79,7 +79,7 @@ namespace SourceHook
* SourceHook doesn't really care what this is. As long as the ==, != and = operators work on it * SourceHook doesn't really care what this is. As long as the ==, != and = operators work on it
* and every plugin has a unique identifier, everything is ok. * and every plugin has a unique identifier, everything is ok.
*/ */
typedef void* Plugin; typedef int Plugin;
enum HookManagerAction enum HookManagerAction
{ {
@ -141,6 +141,7 @@ namespace SourceHook
struct Hook struct Hook
{ {
ISHDelegate *handler; //!< Pointer to the handler ISHDelegate *handler; //!< Pointer to the handler
bool paused; //!< If true, the hook should not be executed
Plugin plug; //!< The owner plugin Plugin plug; //!< The owner plugin
}; };
void *callclass; //!< Stores a call class for this interface void *callclass; //!< Stores a call class for this interface
@ -397,6 +398,7 @@ namespace SourceHook
prev_res = MRES_IGNORED; \ prev_res = MRES_IGNORED; \
for (std::list<HookManagerInfo::Iface::Hook>::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \ for (std::list<HookManagerInfo::Iface::Hook>::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \
{ \ { \
if (hiter->paused) continue; \
cur_res = MRES_IGNORED; \ cur_res = MRES_IGNORED; \
plugin_ret = reinterpret_cast<CSHDelegate<FD>*>(hiter->handler)->GetDeleg() params; \ plugin_ret = reinterpret_cast<CSHDelegate<FD>*>(hiter->handler)->GetDeleg() params; \
prev_res = cur_res; \ prev_res = cur_res; \
@ -448,6 +450,7 @@ namespace SourceHook
prev_res = MRES_IGNORED; \ prev_res = MRES_IGNORED; \
for (std::list<HookManagerInfo::Iface::Hook>::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \ for (std::list<HookManagerInfo::Iface::Hook>::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \
{ \ { \
if (hiter->paused) continue; \
cur_res = MRES_IGNORED; \ cur_res = MRES_IGNORED; \
reinterpret_cast<CSHDelegate<FD>*>(hiter->handler)->GetDeleg() params; \ reinterpret_cast<CSHDelegate<FD>*>(hiter->handler)->GetDeleg() params; \
prev_res = cur_res; \ prev_res = cur_res; \

View File

@ -87,6 +87,10 @@ namespace SourceHook
// Iterate through their hooks // Iterate through their hooks
// If a hook from an other plugin is found, return true // If a hook from an other plugin is found, return true
// Return false otherwise // Return false otherwise
#define TMP_CHECK_LIST(name) \
for (iter3 = iter2->name.begin(); iter3 != iter2->name.end(); ++iter3) \
if (iter3->plug == plug) \
return true;
for (HookManInfoList::iterator iter = m_HookMans.begin(); iter != m_HookMans.end(); ++iter) for (HookManInfoList::iterator iter = m_HookMans.begin(); iter != m_HookMans.end(); ++iter)
{ {
@ -95,15 +99,12 @@ namespace SourceHook
for (std::list<HookManagerInfo::Iface>::iterator iter2 = iter->ifaces.begin(); iter2 != iter->ifaces.end(); ++iter2) for (std::list<HookManagerInfo::Iface>::iterator iter2 = iter->ifaces.begin(); iter2 != iter->ifaces.end(); ++iter2)
{ {
std::list<HookManagerInfo::Iface::Hook>::iterator iter3; std::list<HookManagerInfo::Iface::Hook>::iterator iter3;
for (iter3 = iter2->hooks_pre.begin(); iter3 != iter2->hooks_pre.end(); ++iter3) TMP_CHECK_LIST(hooks_pre);
if (iter3->plug == plug) TMP_CHECK_LIST(hooks_post);
return true;
for (iter3 = iter2->hooks_post.begin(); iter3 != iter2->hooks_post.end(); ++iter3)
if (iter3->plug == plug)
return true;
} }
} }
} }
#undef TMP_CHECK_LIST
return false; return false;
} }
@ -255,6 +256,7 @@ namespace SourceHook
HookManagerInfo::Iface::Hook hookinfo; HookManagerInfo::Iface::Hook hookinfo;
hookinfo.handler = handler; hookinfo.handler = handler;
hookinfo.plug = plug; hookinfo.plug = plug;
hookinfo.paused = false;
if (post) if (post)
ifsiter->hooks_post.push_back(hookinfo); ifsiter->hooks_post.push_back(hookinfo);
else else
@ -479,6 +481,43 @@ namespace SourceHook
return hookmaniter; return hookmaniter;
} }
void CSourceHookImpl::PausePlugin(Plugin plug)
{
// Go through all hook managers, all interfaces, and set the status of all hooks of this plugin to paused
for (HookManInfoList::iterator hookmaniter = m_HookMans.begin(); hookmaniter != m_HookMans.end(); ++hookmaniter)
for (std::list<HookManagerInfo::Iface>::iterator ifaceiter = hookmaniter->ifaces.begin();
ifaceiter != hookmaniter->ifaces.end(); ++ifaceiter)
{
for (std::list<HookManagerInfo::Iface::Hook>::iterator hookiter = ifaceiter->hooks_pre.begin();
hookiter != ifaceiter->hooks_pre.end(); ++hookiter)
if (plug == hookiter->plug)
hookiter->paused = true;
for (std::list<HookManagerInfo::Iface::Hook>::iterator hookiter = ifaceiter->hooks_post.begin();
hookiter != ifaceiter->hooks_post.end(); ++hookiter)
if (plug == hookiter->plug)
hookiter->paused = true;
}
}
void CSourceHookImpl::UnpausePlugin(Plugin plug)
{
// Go through all hook managers, all interfaces, and set the status of all hooks of this plugin to normal
for (HookManInfoList::iterator hookmaniter = m_HookMans.begin(); hookmaniter != m_HookMans.end(); ++hookmaniter)
for (std::list<HookManagerInfo::Iface>::iterator ifaceiter = hookmaniter->ifaces.begin();
ifaceiter != hookmaniter->ifaces.end(); ++ifaceiter)
{
for (std::list<HookManagerInfo::Iface::Hook>::iterator hookiter = ifaceiter->hooks_pre.begin();
hookiter != ifaceiter->hooks_pre.end(); ++hookiter)
if (plug == hookiter->plug)
hookiter->paused = false;
for (std::list<HookManagerInfo::Iface::Hook>::iterator hookiter = ifaceiter->hooks_post.begin();
hookiter != ifaceiter->hooks_post.end(); ++hookiter)
if (plug == hookiter->plug)
hookiter->paused = false;
}
}
void CSourceHookImpl::SetRes(META_RES res) void CSourceHookImpl::SetRes(META_RES res)
{ {

View File

@ -17,7 +17,7 @@
#endif #endif
#ifndef SH_GLOB_PLUGPTR #ifndef SH_GLOB_PLUGPTR
#define SH_GLOB_PLUGPTR g_Plug #define SH_GLOB_PLUGPTR g_PLID
#endif #endif
#define SH_ASSERT(x) if (!(x)) __asm { int 3 } #define SH_ASSERT(x) if (!(x)) __asm { int 3 }
@ -79,7 +79,7 @@ namespace SourceHook
* SourceHook doesn't really care what this is. As long as the ==, != and = operators work on it * SourceHook doesn't really care what this is. As long as the ==, != and = operators work on it
* and every plugin has a unique identifier, everything is ok. * and every plugin has a unique identifier, everything is ok.
*/ */
typedef void* Plugin; typedef int Plugin;
enum HookManagerAction enum HookManagerAction
{ {
@ -141,6 +141,7 @@ namespace SourceHook
struct Hook struct Hook
{ {
ISHDelegate *handler; //!< Pointer to the handler ISHDelegate *handler; //!< Pointer to the handler
bool paused; //!< If true, the hook should not be executed
Plugin plug; //!< The owner plugin Plugin plug; //!< The owner plugin
}; };
void *callclass; //!< Stores a call class for this interface void *callclass; //!< Stores a call class for this interface
@ -397,6 +398,7 @@ namespace SourceHook
prev_res = MRES_IGNORED; \ prev_res = MRES_IGNORED; \
for (std::list<HookManagerInfo::Iface::Hook>::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \ for (std::list<HookManagerInfo::Iface::Hook>::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \
{ \ { \
if (hiter->paused) continue; \
cur_res = MRES_IGNORED; \ cur_res = MRES_IGNORED; \
plugin_ret = reinterpret_cast<CSHDelegate<FD>*>(hiter->handler)->GetDeleg() params; \ plugin_ret = reinterpret_cast<CSHDelegate<FD>*>(hiter->handler)->GetDeleg() params; \
prev_res = cur_res; \ prev_res = cur_res; \
@ -448,6 +450,7 @@ namespace SourceHook
prev_res = MRES_IGNORED; \ prev_res = MRES_IGNORED; \
for (std::list<HookManagerInfo::Iface::Hook>::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \ for (std::list<HookManagerInfo::Iface::Hook>::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \
{ \ { \
if (hiter->paused) continue; \
cur_res = MRES_IGNORED; \ cur_res = MRES_IGNORED; \
reinterpret_cast<CSHDelegate<FD>*>(hiter->handler)->GetDeleg() params; \ reinterpret_cast<CSHDelegate<FD>*>(hiter->handler)->GetDeleg() params; \
prev_res = cur_res; \ prev_res = cur_res; \

View File

@ -117,6 +117,20 @@ namespace SourceHook
*/ */
bool IsPluginInUse(Plugin plug); bool IsPluginInUse(Plugin plug);
/**
* @brief Pauses all hooks of a plugin
*
* @param plug The unique identifier of the plugin
*/
void PausePlugin(Plugin plug);
/**
* @brief Unpauses all hooks of a plugin
*
* @param plug The unique identifier of the plugin
*/
void UnpausePlugin(Plugin plug);
/** /**
* @brief Return a pointer to a callclass. Generate a new one if required. * @brief Return a pointer to a callclass. Generate a new one if required.
* *

View File

@ -359,7 +359,7 @@ public:
}; };
// Sourcehook needs g_Plug and g_SHPtr, it will be customizable in the next release // Sourcehook needs g_Plug and g_SHPtr, it will be customizable in the next release
void *g_Plug = (void*)1337; int g_PLID = 1337;
SourceHook::ISourceHook *g_SHPtr; SourceHook::ISourceHook *g_SHPtr;
SourceHook::CSourceHookImpl g_SHImpl; SourceHook::CSourceHookImpl g_SHImpl;
@ -465,6 +465,19 @@ int main(int argc, char *argv[])
printf("TEST2.8: Calling F16(155) through CC\n"); printf("TEST2.8: Calling F16(155) through CC\n");
printf("Returned: %d\n", cc->F16(155) ? 1 : 0); printf("Returned: %d\n", cc->F16(155) ? 1 : 0);
printf("TEST2.9: Removing pre hook\n"); printf("TEST2.9: Removing pre hook\n");
printf("TEST2.XX.1: Pausing the plugin\n");
g_SHImpl.PausePlugin(g_PLID);
printf("TEST2.XX.2: Calling F16(155)\n");
printf("Returned: %d\n", zLOL_Ptr->F16(155) ? 1 : 0);
printf("TEST2.XX.3: Calling F16(155) through CC\n");
printf("Returned: %d\n", cc->F16(155) ? 1 : 0);
printf("TEST2.XX.4: Unpausing the plugin\n");
g_SHImpl.UnpausePlugin(g_PLID);
printf("TEST2.XX.5: Calling F16(155)\n");
printf("Returned: %d\n", zLOL_Ptr->F16(155) ? 1 : 0);
printf("TEST2.XX.6: Calling F16(155) through CC\n");
printf("Returned: %d\n", cc->F16(155) ? 1 : 0);
printf("TEST2.9: Removing pre hook\n");
SH_REMOVE_HOOK_STATICFUNC(Test, F16, zLOL_Ptr, Test_F16_int_pre_handler, false); SH_REMOVE_HOOK_STATICFUNC(Test, F16, zLOL_Ptr, Test_F16_int_pre_handler, false);
printf("TEST2.10: Calling F16(155)\n"); printf("TEST2.10: Calling F16(155)\n");
printf("Returned: %d\n", zLOL_Ptr->F16(155) ? 1 : 0); printf("Returned: %d\n", zLOL_Ptr->F16(155) ? 1 : 0);