If you are in need of hooking into a continuous loop of a source dedicated server, for rejoining a thread for example, you cannot rely on the "GameFrame" loop, because it will simply stop looping if there are no clients connected to the server. So in that case you will need to hook into "Think" which loops both in hibernation mode and when a client is connected ("GameFrame").
In order to hook into "Think" you'll have to do the following;
Declare a function in your class (if you use classes)
This is done in your plugin class, declare your "Think" function as a public member.
public void My_Think_Hook_Function(bool running);
Declare the hook
This one should be done in your global scope, by using "SH_DECL_HOOK1_void()".
SH_DECL_HOOK1_void(IServerGameDLL, Think, SH_NOATTRIB, 0, bool);
Get the interface pointer
You probably have this one already, since most of the main hooks are running on this one, if you don't;
Firstly have a pointer declared to null in your global scope.
IServerGameDLL *serverDLL = NULL;
In your "YourPluginClass::load()" function you would need to get the current interface.
GET_V_IFACE_CURRENT(GetServerFactory, serverDLL, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL);
Hook it to your function
In order to use the hook you'll need to pair it to a function, for example YourPluginClass::My_Think_Hook_Function.
You have to do this also inside your YourPluginClass::Load() function.
SH_ADD_HOOK(IServerGameDLL, Think, serverDLL, SH_MEMBER(this, &YourPluginClass::My_Think_Hook_Function), true);
Now your "My_Think_Hook_Function()" will always be executed when the server calls "Think".
Also don't forget to remove your hook when your plugin gets unloaded by adding the following to "YourPluginClass::Unload()";
SH_REMOVE_HOOK(IServerGameDLL, Think, serverDLL, SH_MEMBER(this, &YourPluginClass::My_Think_Hook_Function), true);