diff --git a/Extension/swgsdetours.cpp b/Extension/swgsdetours.cpp index 675d331..225dbdc 100644 --- a/Extension/swgsdetours.cpp +++ b/Extension/swgsdetours.cpp @@ -21,13 +21,17 @@ DETOUR_DECL_STATIC0(SteamAPIShutdown, void) { - DETOUR_STATIC_CALL(SteamAPIShutdown)(); /* We're not a monster. */ - if (g_SteamWorks.pSWGameServer == NULL) + if (g_SteamWorks.pSWGameServer != NULL) { - return; + if (g_SteamWorks.pGSHooks != NULL) + { + g_SteamWorks.pGSHooks->RemoveHooks(g_SteamWorks.pSWGameServer->GetGameServer(), false); + } + + g_SteamWorks.pSWGameServer->Reset(); } - - g_SteamWorks.pSWGameServer->Reset(); + + DETOUR_STATIC_CALL(SteamAPIShutdown)(); /* We're not a monster. */ } SteamWorksGSDetours::SteamWorksGSDetours() diff --git a/Extension/swgshooks.cpp b/Extension/swgshooks.cpp index bccd579..f0c280f 100644 --- a/Extension/swgshooks.cpp +++ b/Extension/swgshooks.cpp @@ -19,6 +19,13 @@ #include "swgshooks.h" +enum +{ + eUnhooked = 0, + eHooking, + eHooked +}; + SH_DECL_HOOK0(ISteamGameServer, WasRestartRequested, SH_NOATTRIB, 0, bool); /* From SteamTools. */ static ISteamGameServer *GetGameServerPointer() @@ -28,7 +35,7 @@ static ISteamGameServer *GetGameServerPointer() SteamWorksGSHooks::SteamWorksGSHooks() { - this->bHooked = false; + this->uHooked = eHooking; this->pFORR = forwards->CreateForward("SteamWorks_RestartRequested", ET_Hook, 0, NULL); smutils->AddGameFrameHook(OurGameFrameHook); @@ -36,9 +43,8 @@ SteamWorksGSHooks::SteamWorksGSHooks() SteamWorksGSHooks::~SteamWorksGSHooks() { + this->RemoveHooks(GetGameServerPointer(), true); smutils->RemoveGameFrameHook(OurGameFrameHook); - - this->RemoveHooks(GetGameServerPointer()); forwards->ReleaseForward(this->pFORR); } @@ -58,24 +64,31 @@ bool SteamWorksGSHooks::WasRestartRequested(void) /* Mimic SteamTools. */ void SteamWorksGSHooks::AddHooks(ISteamGameServer *pGameServer) { - if (this->bHooked == true || pGameServer == NULL) + if (this->uHooked == eHooked || pGameServer == NULL) { return; } - this->bHooked = true; + this->uHooked = eHooked; SH_ADD_HOOK(ISteamGameServer, WasRestartRequested, pGameServer, SH_MEMBER(this, &SteamWorksGSHooks::WasRestartRequested), false); } -void SteamWorksGSHooks::RemoveHooks(ISteamGameServer *pGameServer) +void SteamWorksGSHooks::RemoveHooks(ISteamGameServer *pGameServer, bool destroyed) { - if (this->bHooked == false || pGameServer == NULL) + if (this->uHooked != eHooked || pGameServer == NULL) { return; } - this->bHooked = false; SH_REMOVE_HOOK(ISteamGameServer, WasRestartRequested, pGameServer, SH_MEMBER(this, &SteamWorksGSHooks::WasRestartRequested), false); + if (destroyed) + { + this->uHooked = eUnhooked; + return; + } + + this->uHooked = eHooking; + smutils->AddGameFrameHook(OurGameFrameHook); } void OurGameFrameHook(bool simulating) /* What we do for SDK independence. */ diff --git a/Extension/swgshooks.h b/Extension/swgshooks.h index 46cf95a..654924f 100644 --- a/Extension/swgshooks.h +++ b/Extension/swgshooks.h @@ -31,14 +31,14 @@ class SteamWorksGSHooks public: void AddHooks(ISteamGameServer *pGameServer); - void RemoveHooks(ISteamGameServer *pGameServer); + void RemoveHooks(ISteamGameServer *pGameServer, bool destroyed = false); public: bool WasRestartRequested(void); private: IForward *pFORR; /* On Restart Requested. */ - bool bHooked; + unsigned char uHooked; }; void OurGameFrameHook(bool simulating);