diff --git a/Makefile b/Makefile
index 817f0ff..f64e965 100644
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,7 @@ PROJECT = SteamWorks
#USEMETA = true
USESH = true
-OBJECTS = sdk/smsdk_ext.cpp extension.cpp swgameserver.cpp swgamedata.cpp swforwards.cpp gsnatives.cpp
+OBJECTS = sdk/smsdk_ext.cpp extension.cpp swgameserver.cpp swgamedata.cpp swforwards.cpp gsnatives.cpp swgshooks.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
diff --git a/extension.cpp b/extension.cpp
index 45f0786..a9d1601 100644
--- a/extension.cpp
+++ b/extension.cpp
@@ -47,11 +47,13 @@ bool SteamWorks::SDK_OnLoad(char *error, size_t maxlength, bool late)
this->pSWForward = new SteamWorksForwards;
this->pGSNatives = new SteamWorksGSNatives;
+ this->pGSHooks = new SteamWorksGSHooks;
return true;
}
void SteamWorks::SDK_OnUnload()
{
+ delete this->pGSHooks;
delete this->pGSNatives;
delete this->pSWForward;
diff --git a/extension.h b/extension.h
index bc95e38..269de09 100644
--- a/extension.h
+++ b/extension.h
@@ -46,6 +46,7 @@
#include "swforwards.h"
#include "gsnatives.h"
+#include "swgshooks.h"
/**
* @brief Sample implementation of the SDK Extension.
@@ -129,6 +130,7 @@ public:
SteamWorksGameData *pSWGameData;
SteamWorksGameServer *pSWGameServer;
SteamWorksGSNatives *pGSNatives;
+ SteamWorksGSHooks *pGSHooks;
};
extern SteamWorks g_SteamWorks;
diff --git a/swgshooks.cpp b/swgshooks.cpp
new file mode 100644
index 0000000..bccd579
--- /dev/null
+++ b/swgshooks.cpp
@@ -0,0 +1,91 @@
+/*
+ This file is part of SourcePawn SteamWorks.
+
+ SourcePawn SteamWorks is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SourcePawn SteamWorks 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 SourcePawn SteamWorks. If not, see .
+
+ Author: Kyle Sanderson (KyleS).
+*/
+
+#include "swgshooks.h"
+
+SH_DECL_HOOK0(ISteamGameServer, WasRestartRequested, SH_NOATTRIB, 0, bool); /* From SteamTools. */
+
+static ISteamGameServer *GetGameServerPointer()
+{
+ return g_SteamWorks.pSWGameServer->GetGameServer();
+}
+
+SteamWorksGSHooks::SteamWorksGSHooks()
+{
+ this->bHooked = false;
+ this->pFORR = forwards->CreateForward("SteamWorks_RestartRequested", ET_Hook, 0, NULL);
+
+ smutils->AddGameFrameHook(OurGameFrameHook);
+}
+
+SteamWorksGSHooks::~SteamWorksGSHooks()
+{
+ smutils->RemoveGameFrameHook(OurGameFrameHook);
+
+ this->RemoveHooks(GetGameServerPointer());
+ forwards->ReleaseForward(this->pFORR);
+}
+
+bool SteamWorksGSHooks::WasRestartRequested(void) /* Mimic SteamTools. */
+{
+ bool bWasRestartRequested = SH_CALL(GetGameServerPointer(), &ISteamGameServer::WasRestartRequested)();
+ if (bWasRestartRequested && this->pFORR->GetFunctionCount() != 0)
+ {
+ cell_t Result = Pl_Continue;
+ this->pFORR->Execute(&Result);
+ bWasRestartRequested = (Result >= Pl_Handled);
+ }
+
+ /* With how this function works, all following will be given poisoned values from SH_Call. */
+ RETURN_META_VALUE(MRES_SUPERCEDE, bWasRestartRequested);
+}
+
+void SteamWorksGSHooks::AddHooks(ISteamGameServer *pGameServer)
+{
+ if (this->bHooked == true || pGameServer == NULL)
+ {
+ return;
+ }
+
+ this->bHooked = true;
+ SH_ADD_HOOK(ISteamGameServer, WasRestartRequested, pGameServer, SH_MEMBER(this, &SteamWorksGSHooks::WasRestartRequested), false);
+}
+
+void SteamWorksGSHooks::RemoveHooks(ISteamGameServer *pGameServer)
+{
+ if (this->bHooked == false || pGameServer == NULL)
+ {
+ return;
+ }
+
+ this->bHooked = false;
+ SH_REMOVE_HOOK(ISteamGameServer, WasRestartRequested, pGameServer, SH_MEMBER(this, &SteamWorksGSHooks::WasRestartRequested), false);
+}
+
+void OurGameFrameHook(bool simulating) /* What we do for SDK independence. */
+{
+ ISteamGameServer *pGameServer = GetGameServerPointer();
+ if (pGameServer == NULL)
+ {
+ return;
+ }
+
+ g_SteamWorks.pGSHooks->AddHooks(pGameServer);
+ smutils->RemoveGameFrameHook(OurGameFrameHook);
+}
diff --git a/swgshooks.h b/swgshooks.h
new file mode 100644
index 0000000..46cf95a
--- /dev/null
+++ b/swgshooks.h
@@ -0,0 +1,46 @@
+/*
+ This file is part of SourcePawn SteamWorks.
+
+ SourcePawn SteamWorks is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SourcePawn SteamWorks 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 SourcePawn SteamWorks. If not, see .
+
+ Author: Kyle Sanderson (KyleS).
+*/
+
+#pragma once
+#include "isteamgameserver.h"
+#include "steam_gameserver.h"
+#include "smsdk_ext.h"
+#include "sourcehook.h"
+
+class SteamWorksGSHooks
+{
+ public:
+ SteamWorksGSHooks();
+ ~SteamWorksGSHooks();
+
+ public:
+ void AddHooks(ISteamGameServer *pGameServer);
+ void RemoveHooks(ISteamGameServer *pGameServer);
+
+ public:
+ bool WasRestartRequested(void);
+
+ private:
+ IForward *pFORR; /* On Restart Requested. */
+ bool bHooked;
+};
+
+void OurGameFrameHook(bool simulating);
+
+#include "extension.h"
\ No newline at end of file