void CForwardManager::UnhookRecorder(IDemoRecorder *recorder) { #ifdef WIN32 SH_REMOVE_HOOK(IDemoRecorder, StartRecording, recorder, SH_MEMBER(this, &CForwardManager::OnStartRecording_Post), true); SH_REMOVE_HOOK(IDemoRecorder, StopRecording, recorder, SH_MEMBER(this, &CForwardManager::OnStopRecording), false); #endif }
void HLTVServerWrapper::Hook() { if (!m_Connected) return; g_pSTVForwards.HookServer(this); if (m_DemoRecorder) g_pSTVForwards.HookRecorder(m_DemoRecorder); if (g_HLTVServers.HasShutdownOffset()) SH_ADD_MANUALHOOK(CHLTVServer_Shutdown, m_HLTVServer->GetBaseServer(), SH_MEMBER(this, &HLTVServerWrapper::OnHLTVServerShutdown), false); if (iserver) { IClient *pClient = iserver->GetClient(m_HLTVServer->GetHLTVSlot()); if (pClient) { SH_ADD_HOOK(IClient, ExecuteStringCommand, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnHLTVBotExecuteStringCommand), false); SH_ADD_HOOK(IClient, ExecuteStringCommand, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnHLTVBotExecuteStringCommand_Post), true); #if SOURCE_ENGINE != SE_CSGO SH_ADD_HOOK(IClient, ClientPrintf, pClient, SH_MEMBER(this, &HLTVServerWrapper::OnIClient_ClientPrintf_Post), false); #ifndef WIN32 // The IClient vtable is +4 from the CBaseClient vtable due to multiple inheritance. void *pGameClient = (void *)((intptr_t)pClient - 4); if (g_HLTVServers.HasClientPrintfOffset()) SH_ADD_MANUALHOOK(CGameClient_ClientPrintf, pGameClient, SH_MEMBER(this, &HLTVServerWrapper::OnCGameClient_ClientPrintf_Post), false); #endif // !WIN32 #endif // SOURCE_ENGINE != SE_CSGO } } }
void LuaEx::InitHooks() { SH_ADD_HOOK(IScriptManager, CreateVM, scriptmgr, SH_MEMBER(this, &LuaEx::Hook_CreateVMPost), true); SH_ADD_HOOK(IScriptManager, DestroyVM, scriptmgr, SH_MEMBER(this, &LuaEx::Hook_DestroyVM), true); SetupDetours(); }
void EventManager::OnSourceModShutdown() { /* Remove hook for IGameEventManager2::FireEvent() */ SH_REMOVE_HOOK(IGameEventManager2, FireEvent, gameevents, SH_MEMBER(this, &EventManager::OnFireEvent), false); SH_REMOVE_HOOK(IGameEventManager2, FireEvent, gameevents, SH_MEMBER(this, &EventManager::OnFireEvent_Post), true); /* Remove the 'GameEvent' handle type */ handlesys->RemoveType(m_EventType, g_pCoreIdent); /* Remove ourselves as listener for events */ gameevents->RemoveListener(this); }
void SteamWorksGCHooks::AddHooks(ISteamGameCoordinator *pGC) { if (this->uHooked == eHooked || pGC == NULL) { return; } this->uHooked = eHooked; SH_ADD_HOOK(ISteamGameCoordinator, SendMessage, pGC, SH_MEMBER(this, &SteamWorksGCHooks::SendMessage), false); SH_ADD_HOOK(ISteamGameCoordinator, IsMessageAvailable, pGC, SH_MEMBER(this, &SteamWorksGCHooks::IsMessageAvailable), true); SH_ADD_HOOK(ISteamGameCoordinator, RetrieveMessage, pGC, SH_MEMBER(this, &SteamWorksGCHooks::RetrieveMessage), false); }
void SourceModBase::ShutdownServices() { /* Unload plugins */ scripts->Shutdown(); /* Unload extensions */ extsys->Shutdown(); if (g_pOnMapEnd) forwardsys->ReleaseForward(g_pOnMapEnd); /* Notify! */ SMGlobalClass *pBase = SMGlobalClass::head; while (pBase) { pBase->OnSourceModShutdown(); pBase = pBase->m_pGlobalClassNext; } /* Delete all data packs */ CStack<CDataPack *>::iterator iter; CDataPack *pd; for (iter=m_freepacks.begin(); iter!=m_freepacks.end(); iter++) { pd = (*iter); delete pd; } m_freepacks.popall(); /* Notify! */ pBase = SMGlobalClass::head; while (pBase) { pBase->OnSourceModAllShutdown(); pBase = pBase->m_pGlobalClassNext; } if (enginePatch) { SH_RELEASE_CALLCLASS(enginePatch); enginePatch = NULL; } if (gamedllPatch) { SH_RELEASE_CALLCLASS(gamedllPatch); gamedllPatch = NULL; } SH_REMOVE_HOOK(IServerGameDLL, LevelShutdown, gamedll, SH_MEMBER(this, &SourceModBase::LevelShutdown), false); SH_REMOVE_HOOK(IServerGameDLL, GameFrame, gamedll, SH_MEMBER(&g_Timers, &TimerSystem::GameFrame), false); }
void SoundHooks::Shutdown() { plsys->RemovePluginsListener(this); if (m_NormalCount) { SH_REMOVE_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound), false); SH_REMOVE_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound2), false); } if (m_AmbientCount) { SH_REMOVE_HOOK(IVEngineServer, EmitAmbientSound, engine, SH_MEMBER(this, &SoundHooks::OnEmitAmbientSound), false); } }
void ChatTriggers::OnSourceModShutdown() { if (m_pSayCmd) { SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true); SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false); } if (m_pSayTeamCmd) { SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true); SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false); } #if SOURCE_ENGINE == SE_EPISODEONE if (m_bIsINS && m_pSay2Cmd) { SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSay2Cmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false); SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSay2Cmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true); } #elif SOURCE_ENGINE == SE_NUCLEARDAWN if (m_pSaySquadCmd) { SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSaySquadCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false); SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSaySquadCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true); } #endif forwardsys->ReleaseForward(m_pShouldFloodBlock); forwardsys->ReleaseForward(m_pDidFloodBlock); forwardsys->ReleaseForward(m_pOnClientSayCmd); forwardsys->ReleaseForward(m_pOnClientSayCmd_Post); }
void NextMapManager::OnSourceModAllInitialized_Post() { #if SOURCE_ENGINE >= SE_ORANGEBOX SH_ADD_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false); #else SH_ADD_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false); #endif ConCommand *pCmd = FindCommand("changelevel"); if (pCmd != NULL) { SH_ADD_HOOK(ConCommand, Dispatch, pCmd, SH_STATIC(CmdChangeLevelCallback), false); changeLevelCmd = pCmd; } }
void CForwardManager::UnhookClient(IClient *client) { // Remove ExecuteStringCommand hook g_pSTVCommonHooks.RemoveSpectatorHook(this, client); void *pGameClient = (void *)((intptr_t)client - 4); if (m_bHasActivatePlayerOffset) SH_REMOVE_MANUALHOOK(CBaseClient_ActivatePlayer, pGameClient, SH_MEMBER(this, &CForwardManager::OnSpectatorPutInServer), true); SH_REMOVE_HOOK(IClient, Disconnect, client, SH_MEMBER(this, &CForwardManager::IClient_OnSpectatorDisconnect), false); #ifndef WIN32 if (m_bHasDisconnectOffset) SH_REMOVE_MANUALHOOK(CBaseClient_Disconnect, pGameClient, SH_MEMBER(this, &CForwardManager::BaseClient_OnSpectatorDisconnect), false); #endif }
bool SDKTools::SDK_OnMetamodUnload(char *error, size_t maxlen) { #if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_CSGO SH_REMOVE_HOOK(IVEngineServer, ClientCommand, engine, SH_MEMBER(this, &SDKTools::OnSendClientCommand), false); #endif return true; }
bool SDKTools::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late) { GET_V_IFACE_ANY(GetServerFactory, gameents, IServerGameEnts, INTERFACEVERSION_SERVERGAMEENTS); GET_V_IFACE_ANY(GetEngineFactory, engsound, IEngineSound, IENGINESOUND_SERVER_INTERFACE_VERSION); GET_V_IFACE_ANY(GetEngineFactory, enginetrace, IEngineTrace, INTERFACEVERSION_ENGINETRACE_SERVER); GET_V_IFACE_ANY(GetEngineFactory, netstringtables, INetworkStringTableContainer, INTERFACENAME_NETWORKSTRINGTABLESERVER); #if SOURCE_ENGINE != SE_DOTA GET_V_IFACE_ANY(GetEngineFactory, pluginhelpers, IServerPluginHelpers, INTERFACEVERSION_ISERVERPLUGINHELPERS); #endif GET_V_IFACE_ANY(GetServerFactory, serverClients, IServerGameClients, INTERFACEVERSION_SERVERGAMECLIENTS); GET_V_IFACE_ANY(GetEngineFactory, voiceserver, IVoiceServer, INTERFACEVERSION_VOICESERVER); GET_V_IFACE_ANY(GetServerFactory, playerinfomngr, IPlayerInfoManager, INTERFACEVERSION_PLAYERINFOMANAGER); GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION); GET_V_IFACE_CURRENT(GetFileSystemFactory, basefilesystem, IBaseFileSystem, BASEFILESYSTEM_INTERFACE_VERSION); #if SOURCE_ENGINE >= SE_ORANGEBOX GET_V_IFACE_ANY(GetServerFactory, servertools, IServerTools, VSERVERTOOLS_INTERFACE_VERSION); #endif GET_V_IFACE_ANY(GetEngineFactory, soundemitterbase, ISoundEmitterSystemBase, SOUNDEMITTERSYSTEM_INTERFACE_VERSION); #if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_CSGO SH_ADD_HOOK(IVEngineServer, ClientCommand, engine, SH_MEMBER(this, &SDKTools::OnSendClientCommand), false); #endif gpGlobals = ismm->GetCGlobals(); enginePatch = SH_GET_CALLCLASS(engine); enginesoundPatch = SH_GET_CALLCLASS(engsound); return true; }
void TempEntHooks::_IncRefCounter() { if (m_HookCount++ == 0) { SH_ADD_HOOK(IVEngineServer, PlaybackTempEntity, engine, SH_MEMBER(this, &TempEntHooks::OnPlaybackTempEntity), false); } }
/** * Orange Box will never use this. */ void ConVarManager::OnSimillimumVSPReceived() { /** * Don't bother if the DLL is already hooked. */ if (m_bIsDLLQueryHooked) { return; } /* For later MM:S versions, use the updated API, since it's cleaner. */ #if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11 int engine = g_SMAPI->GetSourceEngineBuild(); if (engine == SOURCE_ENGINE_ORIGINAL || vsp_version < 2) { return; } #else if (g_HL2.IsOriginalEngine() || vsp_version < 2) { return; } #endif #if SOURCE_ENGINE != SE_DARKMESSIAH SH_ADD_HOOK(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, SH_MEMBER(this, &ConVarManager::OnQueryCvarValueFinished), false); m_bIsVSPQueryHooked = true; #endif }
void HolidayManager::HookIfNecessary() { // Already hooked if (m_iHookID) return; // Nothing wants us if (m_isHolidayForward->GetFunctionCount() == 0) return; void *pGameRules = GetGameRules(); if (!pGameRules) { if (m_bInMap) { g_pSM->LogError(myself, "Gamerules ptr not found. TF2_OnIsHolidayActive will not be available."); } return; } static int offset = -1; if (offset == -1) { if (!g_pGameConf->GetOffset("IsHolidayActive", &offset)) { g_pSM->LogError(myself, "IsHolidayActive gamedata offset missing. TF2_OnIsHolidayActive will not be available."); return; } SH_MANUALHOOK_RECONFIGURE(IsHolidayActive, offset, 0, 0); } m_iHookID = SH_ADD_MANUALHOOK(IsHolidayActive, pGameRules, SH_MEMBER(this, &HolidayManager::Hook_IsHolidayActive), false); }
void TempEntHooks::_DecRefCounter() { if (--m_HookCount == 0) { SH_REMOVE_HOOK(IVEngineServer, PlaybackTempEntity, engine, SH_MEMBER(this, &TempEntHooks::OnPlaybackTempEntity), false); } }
void ConVarManager::OnSourceModAllInitialized() { /** * Episode 2 has this function by default, but the older versions do not. */ #if SOURCE_ENGINE == SE_EPISODEONE if (g_SMAPI->GetGameDLLVersion() >= 6) { SH_ADD_HOOK(IServerGameDLL, OnQueryCvarValueFinished, gamedll, SH_MEMBER(this, &ConVarManager::OnQueryCvarValueFinished), false); m_bIsDLLQueryHooked = true; } #endif g_Players.AddClientListener(this); #if SOURCE_ENGINE >= SE_ORANGEBOX SH_ADD_HOOK(ICvar, CallGlobalChangeCallbacks, icvar, SH_STATIC(OnConVarChanged), false); #else SH_ADD_HOOK(ICvar, CallGlobalChangeCallback, icvar, SH_STATIC(OnConVarChanged), false); #endif scripts->AddPluginsListener(this); /* Add the 'convars' option to the 'sm' console command */ g_RootMenu.AddRootConsoleCommand("cvars", "View convars created by a plugin", this); }
void EventManager::OnSourceModAllInitialized() { /* Add a hook for IGameEventManager2::FireEvent() */ SH_ADD_HOOK(IGameEventManager2, FireEvent, gameevents, SH_MEMBER(this, &EventManager::OnFireEvent), false); SH_ADD_HOOK(IGameEventManager2, FireEvent, gameevents, SH_MEMBER(this, &EventManager::OnFireEvent_Post), true); HandleAccess sec; /* Handle access security for 'GameEvent' handle type */ sec.access[HandleAccess_Read] = 0; sec.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER; sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER; /* Create the 'GameEvent' handle type */ m_EventType = handlesys->CreateType("GameEvent", this, 0, NULL, &sec, g_pCoreIdent, NULL); }
void CSteamAPI::InitForwards() { g_pRestartReqFwd = forwards->CreateForward( "SteamAPI_RestartRequested", ET_Ignore, 0, NULL ); g_pValidatedFwd = forwards->CreateForward( "SteamAPI_OnClientValidated", ET_Ignore, 2, NULL, Param_Cell, Param_Cell ); SH_ADD_HOOK( ISteamGameServer, WasRestartRequested, g_APIContext.SteamGameServer(), SH_MEMBER( this, &CSteamAPI::WasRestartRequested ), false ); }
void CHookManager::OnClientPutInServer(int client) { if (!PRCH_enabled) return; if (!PRCH_used) return; edict_t *pEdict = PEntityOfEntIndex(client); if (!pEdict) { return; } IServerUnknown *pUnknown = pEdict->GetUnknown(); if (!pUnknown) { return; } CBaseEntity *pEntity = pUnknown->GetBaseEntity(); if (!pEntity) { return; } SH_ADD_MANUALHOOK(PlayerRunCmdHook, pEntity, SH_MEMBER(this, &CHookManager::PlayerRunCmd), false); }
void SDKTools::SDK_OnUnload() { SourceHook::List<ValveCall *>::iterator iter; for (iter = g_RegCalls.begin(); iter != g_RegCalls.end(); iter++) { delete (*iter); } g_RegCalls.clear(); ShutdownHelpers(); if (g_pAcceptInput) { g_pAcceptInput->Destroy(); g_pAcceptInput = NULL; } g_TEManager.Shutdown(); s_TempEntHooks.Shutdown(); s_SoundHooks.Shutdown(); g_Hooks.Shutdown(); g_OutputManager.Shutdown(); gameconfs->CloseGameConfigFile(g_pGameConf); playerhelpers->RemoveClientListener(&g_SdkTools); playerhelpers->UnregisterCommandTargetProcessor(this); plsys->RemovePluginsListener(&g_OutputManager); SH_REMOVE_HOOK(IServerGameDLL, LevelInit, gamedll, SH_MEMBER(this, &SDKTools::LevelInit), true); if (enginePatch) { SH_RELEASE_CALLCLASS(enginePatch); enginePatch = NULL; } if (enginesoundPatch) { SH_RELEASE_CALLCLASS(enginesoundPatch); enginesoundPatch = NULL; } bool err; if (g_CallHandle != 0) { if ((err = handlesys->RemoveType(g_CallHandle, myself->GetIdentity())) != true) { g_pSM->LogError(myself, "Could not remove call handle (type=%x, err=%d)", g_CallHandle, err); } } if (g_TraceHandle != 0) { if ((err = handlesys->RemoveType(g_TraceHandle, myself->GetIdentity())) != true) { g_pSM->LogError(myself, "Could not remove trace handle (type=%x, err=%d)", g_TraceHandle, err); } } }
void HolidayManager::OnSDKUnload() { UnhookIfNecessary(); SH_REMOVE_HOOK(IServerGameDLL, LevelShutdown, gamedll, SH_MEMBER(this, &HolidayManager::Hook_LevelShutdown), false); plsys->RemovePluginsListener(this); forwards->ReleaseForward(m_isHolidayForward); }
void CForwardManager::HookClient(IClient *client) { // Hook ExecuteStringCommand for chat messages g_pSTVCommonHooks.AddSpectatorHook(this, client); void *pGameClient = (void *)((intptr_t)client - 4); if (m_bHasActivatePlayerOffset) SH_ADD_MANUALHOOK(CBaseClient_ActivatePlayer, pGameClient, SH_MEMBER(this, &CForwardManager::OnSpectatorPutInServer), true); // Linux' engine uses the CGameClient vtable internally, but we're using the IClient vtable to kick players. // Need to hook both to catch all cases >.< SH_ADD_HOOK(IClient, Disconnect, client, SH_MEMBER(this, &CForwardManager::IClient_OnSpectatorDisconnect), false); #ifndef WIN32 if (m_bHasDisconnectOffset) SH_ADD_MANUALHOOK(CBaseClient_Disconnect, pGameClient, SH_MEMBER(this, &CForwardManager::BaseClient_OnSpectatorDisconnect), false); #endif }
void CForwardManager::UnhookServer(HLTVServerWrapper *wrapper) { IServer *server = wrapper->GetBaseServer(); if (m_bHasClientConnectOffset) SH_REMOVE_MANUALHOOK(CHLTVServer_ConnectClient, server, SH_MEMBER(this, &CForwardManager::OnSpectatorConnect), false); if (m_bHasGetChallengeTypeOffset) SH_REMOVE_MANUALHOOK(CHLTVServer_GetChallengeType, server, SH_MEMBER(this, &CForwardManager::OnGetChallengeType), false); // Unhook all connected clients as well. for (int i = 0; i < server->GetClientCount(); i++) { IClient *client = server->GetClient(i); if (client->IsConnected()) UnhookClient(client); } }
void SourceModBase::ShutdownServices() { /* Unload plugins */ scripts->Shutdown(); /* Unload extensions */ extsys->Shutdown(); if (g_pOnMapEnd) forwardsys->ReleaseForward(g_pOnMapEnd); /* Notify! */ SMGlobalClass *pBase = SMGlobalClass::head; while (pBase) { pBase->OnSourceModShutdown(); pBase = pBase->m_pGlobalClassNext; } sCoreProviderImpl.ShutdownHooks(); /* Notify! */ pBase = SMGlobalClass::head; while (pBase) { pBase->OnSourceModAllShutdown(); pBase = pBase->m_pGlobalClassNext; } if (enginePatch) { SH_RELEASE_CALLCLASS(enginePatch); enginePatch = NULL; } if (gamedllPatch) { SH_RELEASE_CALLCLASS(gamedllPatch); gamedllPatch = NULL; } SH_REMOVE_HOOK(IServerGameDLL, LevelShutdown, gamedll, SH_MEMBER(this, &SourceModBase::LevelShutdown), false); SH_REMOVE_HOOK(IServerGameDLL, GameFrame, gamedll, SH_MEMBER(&g_Timers, &TimerSystem::GameFrame), false); SH_REMOVE_HOOK(IServerGameDLL, Think, gamedll, SH_MEMBER(logicore.callbacks, &IProviderCallbacks::OnThink), false); }
void HolidayManager::OnSDKLoad(bool bLate) { m_bInMap = bLate; plsys->AddPluginsListener(this); m_isHolidayForward = forwards->CreateForward("TF2_OnIsHolidayActive", ET_Event, 2, NULL, Param_Cell, Param_CellByRef); SH_ADD_HOOK(IServerGameDLL, LevelShutdown, gamedll, SH_MEMBER(this, &HolidayManager::Hook_LevelShutdown), false); }
void SoundHooks::_IncRefCounter(int type) { if (type == NORMAL_SOUND_HOOK) { if (m_NormalCount++ == 0) { SH_ADD_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound), false); SH_ADD_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound2), false); } } else if (type == AMBIENT_SOUND_HOOK) { if (m_AmbientCount++ == 0) { SH_ADD_HOOK(IVEngineServer, EmitAmbientSound, engine, SH_MEMBER(this, &SoundHooks::OnEmitAmbientSound), false); } } }
void SteamWorksGCHooks::RemoveHooks(ISteamGameCoordinator *pGC, bool destroyed) { if (this->uHooked != eHooked || pGC == NULL) { return; } SH_REMOVE_HOOK(ISteamGameCoordinator, SendMessage, pGC, SH_MEMBER(this, &SteamWorksGCHooks::SendMessage), false); SH_REMOVE_HOOK(ISteamGameCoordinator, IsMessageAvailable, pGC, SH_MEMBER(this, &SteamWorksGCHooks::IsMessageAvailable), true); SH_REMOVE_HOOK(ISteamGameCoordinator, RetrieveMessage, pGC, SH_MEMBER(this, &SteamWorksGCHooks::RetrieveMessage), false); if (destroyed) { this->uHooked = eUnhooked; return; } this->uHooked = eHooking; smutils->AddGameFrameHook(OurGCGameFrameHook); }
/** * Manage the wrappers! */ void HLTVServerWrapperManager::InitHooks() { int offset; if (g_pGameConf->GetOffset("CHLTVServer::Shutdown", &offset)) { SH_MANUALHOOK_RECONFIGURE(CHLTVServer_Shutdown, offset, 0, 0); m_bHasShutdownOffset = true; } else { smutils->LogError(myself, "Failed to find CHLTVServer::Shutdown offset."); } #if SOURCE_ENGINE != SE_CSGO #ifndef WIN32 if (g_pGameConf->GetOffset("CGameClient::ClientPrintf", &offset)) { SH_MANUALHOOK_RECONFIGURE(CGameClient_ClientPrintf, offset, 0, 0); m_bHasClientPrintfOffset = true; } else { smutils->LogError(myself, "Failed to find CGameClient::ClientPrintf offset. Won't catch \"status\" console output."); } #endif // !WIN32 if (g_pGameConf->GetOffset("CNetChan::SendNetMsg", &offset)) { if (offset >= FAKE_VTBL_LENGTH) { smutils->LogError(myself, "CNetChan::SendNetMsg offset too big. Need to raise define and recompile. Contact the author."); } else { // This is a hack. Bots don't have a net channel, but ClientPrintf tries to call m_NetChannel->SendNetMsg directly. // CGameClient::SendNetMsg would have redirected it to the hltvserver correctly, but isn't used there.. // We craft a fake object with a large enough "vtable" and hook it using sourcehook. // Before a call to ClientPrintf, this fake object is set as CBaseClient::m_NetChannel, so ClientPrintf creates // the SVC_Print INetMessage and calls our "hooked" m_NetChannel->SendNetMsg function. // In that function we just call CGameClient::SendNetMsg with the given INetMessage to flow it through the same // path as other net messages. SH_MANUALHOOK_RECONFIGURE(NetChan_SendNetMsg, offset, 0, 0); SH_ADD_MANUALHOOK(NetChan_SendNetMsg, &FakeNetChan, SH_MEMBER(this, &HLTVServerWrapperManager::OnHLTVBotNetChanSendNetMsg), false); m_bSendNetMsgHooked = true; } } else { smutils->LogError(myself, "Failed to find CNetChan::SendNetMsg offset. Can't print to demo console."); } #endif }
void NextMapManager::OnSourceModShutdown() { #if SOURCE_ENGINE >= SE_ORANGEBOX SH_REMOVE_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false); #else SH_REMOVE_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false); #endif if (changeLevelCmd != NULL) { SH_REMOVE_HOOK(ConCommand, Dispatch, changeLevelCmd, SH_STATIC(CmdChangeLevelCallback), false); } SourceHook::List<MapChangeData *>::iterator iter; iter = m_mapHistory.begin(); while (iter != m_mapHistory.end()) { delete (MapChangeData *)*iter; iter = m_mapHistory.erase(iter); } }