void CForwardManager::OnStopRecording() #endif { IDemoRecorder *recorder = META_IFACEPTR(IDemoRecorder); CallOnStopRecording(recorder); RETURN_META(MRES_IGNORED); }
bool CForwardManager::OnSpectatorExecuteStringCommand(const char *s) { if (!hltvserver) RETURN_META_VALUE(MRES_IGNORED, true); IClient *client = META_IFACEPTR(IClient); if (!s || !s[0]) RETURN_META_VALUE(MRES_IGNORED, true); CCommand args; if (!args.Tokenize(s)) RETURN_META_VALUE(MRES_IGNORED, true); // See if the client wants to chat. if (!Q_stricmp(args[0], "say") && args.ArgC() > 1) { // TODO find correct hltvserver this client is connected to! // Save the client index and message. hltvserver->SetLastChatClient(client); hltvserver->SetLastChatMessage(args[1]); } RETURN_META_VALUE(MRES_IGNORED, true); }
void HLTVServerWrapper::OnIClient_ClientPrintf_Post(const char* buf) { IClient *pClient = META_IFACEPTR(IClient); HandleClientPrintf(pClient, buf); RETURN_META(MRES_IGNORED); }
CBaseEntity *Hook_GiveNamedItem_Post(char const *szClassname, int iSubType, CEconItemView *cscript, bool b) { CBaseEntity *player = META_IFACEPTR(CBaseEntity); CBaseEntity *pItemEntiy; if (META_RESULT_STATUS >= MRES_OVERRIDE) { pItemEntiy = META_RESULT_OVERRIDE_RET(CBaseEntity *); } else {
void CSrcHooks::onTraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { edict_t *edictAttacker = pevAttacker->pContainingEntity; edict_t *edictVictim = META_IFACEPTR(CBaseEntity)->edict(); CPlayer *pAttacker = (CPlayer *) g_PlayerManager.getPlayer(edictAttacker); CPlayer *pVictim = (CPlayer *) g_PlayerManager.getPlayer(edictVictim); if( pAttacker != NULL && pVictim != NULL ) g_SBG.onTakeDamage(pVictim, pAttacker); RETURN_META(MRES_IGNORED); }
bool ManiSMMHooks::Weapon_CanUse(CBaseCombatWeapon *pWeapon) { if (!gpManiWeaponMgr->CanPickUpWeapon(META_IFACEPTR(CBasePlayer), pWeapon)) { RETURN_META_VALUE(MRES_SUPERCEDE, false); } RETURN_META_VALUE(MRES_IGNORED, true); }
void CForwardManager::IClient_OnSpectatorDisconnect(const char *reason) { IClient *client = META_IFACEPTR(IClient); if (!client) RETURN_META(MRES_IGNORED); HandleSpectatorDisconnect(client, reason); RETURN_META(MRES_SUPERCEDE); }
// When bots issue a command that would print stuff to their console, // the server might crash, because ExecuteStringCommand doesn't set the // global host_client pointer to the client on whom the command is run. // Host_Client_Printf blatantly tries to call host_client->ClientPrintf // while the pointer might point to some other player or garbage. // This leads to e.g. the output of the "status" command not being // recorded in the SourceTV demo. // The approach here is to set host_client correctly for the SourceTV // bot and reset it to the old value after command execution. bool HLTVServerWrapper::OnHLTVBotExecuteStringCommand(const char *s) { if (!host_client) RETURN_META_VALUE(MRES_IGNORED, 0); IClient *pClient = META_IFACEPTR(IClient); if (!pClient) RETURN_META_VALUE(MRES_IGNORED, 0); // The IClient vtable is +4 from the CBaseClient vtable due to multiple inheritance. void *pGameClient = (void *)((intptr_t)pClient - 4); old_host_client = *(void **)host_client; *(void **)host_client = pGameClient; g_HostClientOverridden = true; RETURN_META_VALUE(MRES_IGNORED, 0); }
void CHookManager::PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper) { if (m_usercmdsFwd->GetFunctionCount() == 0) { RETURN_META(MRES_IGNORED); } CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity); if (!pEntity) { RETURN_META(MRES_IGNORED); } edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); if (!pEdict) { RETURN_META(MRES_IGNORED); } int client = IndexOfEdict(pEdict); cell_t result = 0; /* Impulse is a byte so we copy it back manually */ cell_t impulse = ucmd->impulse; cell_t vel[3] = {sp_ftoc(ucmd->forwardmove), sp_ftoc(ucmd->sidemove), sp_ftoc(ucmd->upmove)}; cell_t angles[3] = {sp_ftoc(ucmd->viewangles.x), sp_ftoc(ucmd->viewangles.y), sp_ftoc(ucmd->viewangles.z)}; cell_t mouse[2] = {ucmd->mousedx, ucmd->mousedy}; m_usercmdsFwd->PushCell(client); m_usercmdsFwd->PushCellByRef(&ucmd->buttons); m_usercmdsFwd->PushCellByRef(&impulse); m_usercmdsFwd->PushArray(vel, 3, SM_PARAM_COPYBACK); m_usercmdsFwd->PushArray(angles, 3, SM_PARAM_COPYBACK); m_usercmdsFwd->PushCellByRef(&ucmd->weaponselect); m_usercmdsFwd->PushCellByRef(&ucmd->weaponsubtype); m_usercmdsFwd->PushCellByRef(&ucmd->command_number); m_usercmdsFwd->PushCellByRef(&ucmd->tick_count); m_usercmdsFwd->PushCellByRef(&ucmd->random_seed); m_usercmdsFwd->PushArray(mouse, 2, SM_PARAM_COPYBACK); m_usercmdsFwd->Execute(&result); ucmd->impulse = impulse; ucmd->forwardmove = sp_ctof(vel[0]); ucmd->sidemove = sp_ctof(vel[1]); ucmd->upmove = sp_ctof(vel[2]); ucmd->viewangles.x = sp_ctof(angles[0]); ucmd->viewangles.y = sp_ctof(angles[1]); ucmd->viewangles.z = sp_ctof(angles[2]); ucmd->mousedx = mouse[0]; ucmd->mousedy = mouse[1]; if (result == Pl_Handled) { RETURN_META(MRES_SUPERCEDE); } RETURN_META(MRES_IGNORED); }
// These two hooks are actually only hooked on windows. void CForwardManager::OnStartRecording_Post(const char *filename, bool bContinuously) { IDemoRecorder *recorder = META_IFACEPTR(IDemoRecorder); CallOnStartRecording(recorder, filename, bContinuously); RETURN_META(MRES_IGNORED); }
IClient *CForwardManager::OnSpectatorConnect(netadr_t & address, int nProtocol, int iChallenge, int iClientChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie) #endif { if (!pCookie || (size_t)cbCookie < sizeof(uint64)) RETURN_META_VALUE(MRES_IGNORED, nullptr); #if SOURCE_ENGINE == SE_CSGO // CS:GO doesn't send the player name in pchName, but only in the client info convars. // Try to extract the name from the protobuf msg. char playerName[MAX_PLAYER_NAME_LENGTH]; if (ExtractPlayerName(pSplitPlayerConnectVector, playerName, sizeof(playerName))) pchName = playerName; #endif char ipString[16]; V_snprintf(ipString, sizeof(ipString), "%u.%u.%u.%u", address.ip[0], address.ip[1], address.ip[2], address.ip[3]); V_strncpy(passwordBuffer, pchPassword, 255); // SourceTV doesn't validate steamids?! char rejectReason[255]; m_SpectatorPreConnectFwd->PushString(pchName); m_SpectatorPreConnectFwd->PushStringEx(passwordBuffer, 255, SM_PARAM_STRING_UTF8 | SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); m_SpectatorPreConnectFwd->PushString(ipString); m_SpectatorPreConnectFwd->PushStringEx(rejectReason, 255, SM_PARAM_STRING_UTF8 | SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); cell_t retVal = 1; m_SpectatorPreConnectFwd->Execute(&retVal); IServer *server = META_IFACEPTR(IServer); if (retVal == 0) { if (m_bHasRejectConnectionOffset) { #if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_LEFT4DEAD || SOURCE_ENGINE == SE_LEFT4DEAD2 SH_MCALL(server, CHLTVServer_RejectConnection)(address, rejectReason); #else SH_MCALL(server, CHLTVServer_RejectConnection)(address, iClientChallenge, rejectReason); #endif } RETURN_META_VALUE(MRES_SUPERCEDE, nullptr); } // Call the original function. #if SOURCE_ENGINE == SE_CSGO IClient *client = SH_MCALL(server, CHLTVServer_ConnectClient)(address, nProtocol, iChallenge, nAuthProtocol, pchName, passwordBuffer, pCookie, cbCookie, pSplitPlayerConnectVector, bUnknown, platform, pUnknown, iUnknown); #elif SOURCE_ENGINE == SE_LEFT4DEAD || SOURCE_ENGINE == SE_LEFT4DEAD2 IClient *client = SH_MCALL(server, CHLTVServer_ConnectClient)(address, nProtocol, iChallenge, nAuthProtocol, pchName, passwordBuffer, pCookie, cbCookie, pSplitPlayerConnectVector, bUnknown); #else IClient *client = SH_MCALL(server, CHLTVServer_ConnectClient)(address, nProtocol, iChallenge, iClientChallenge, nAuthProtocol, pchName, passwordBuffer, pCookie, cbCookie); #endif if (!client) RETURN_META_VALUE(MRES_SUPERCEDE, nullptr); HookClient(client); HLTVServerWrapper *wrapper = g_HLTVServers.GetWrapper(server); if (wrapper) { HLTVClientWrapper *clientWrapper = wrapper->GetClient(client->GetPlayerSlot() + 1); clientWrapper->Initialize(ipString, pchPassword, client); } m_SpectatorConnectedFwd->PushCell(client->GetPlayerSlot() + 1); m_SpectatorConnectedFwd->Execute(); // Don't call the hooked function again, just return its value. RETURN_META_VALUE(MRES_SUPERCEDE, client); }
CBaseEntity *Hook_GiveNamedItem(char const *szClassname, int iSubType, CEconItemView *cscript, bool b) { #if defined TF2ITEMS_DEBUG_HOOKING || defined TF2ITEMS_DEBUG_HOOKING_GNI g_pSM->LogMessage(myself, "GiveNamedItem called."); #endif // TF2ITEMS_DEBUG_HOOKING #ifdef TF2ITEMS_DEBUG_ITEMS g_pSM->LogMessage(myself, "---------------------------------------"); g_pSM->LogMessage(myself, ">>> Start of GiveNamedItem call."); #endif CBasePlayer *player = META_IFACEPTR(CBasePlayer); if (cscript == NULL || szClassname == NULL) { #if defined TF2ITEMS_DEBUG_HOOKING_GNI g_pSM->LogMessage(myself, "(cscript == NULL || szClassname == NULL), RETURN_META_VALUE(MRES_IGNORED, NULL);"); #endif // TF2ITEMS_DEBUG_HOOKING_GNI RETURN_META_VALUE(MRES_IGNORED, NULL); } // Retrieve client index. edict_t *playerEdict = gameents->BaseEntityToEdict((CBaseEntity *)player); IGamePlayer * pPlayer = playerhelpers->GetGamePlayer(playerEdict); int client = gamehelpers->IndexOfEdict(playerEdict); if (g_pVTable == NULL) { g_pVTable = cscript->m_pVTable; g_pVTable_Attributes = cscript->m_pVTable_Attributes; } #ifdef TF2ITEMS_DEBUG_ITEMS /*char *roflmelon = new char[32]; sprintf(roflmelon, "debug_item_%d_%d.txt", cscript->m_iAccountID, cscript->m_iItemDefinitionIndex); FILE *fp = fopen(roflmelon, "wb"); fwrite(cscript, sizeof(CEconItemView), 1, fp); fclose(fp);*/ g_pSM->LogMessage(myself, "---------------------------------------"); g_pSM->LogMessage(myself, ">>> Client = %s", pPlayer->GetName()); g_pSM->LogMessage(myself, ">>> szClassname = %s", szClassname); g_pSM->LogMessage(myself, ">>> iSubType = %d", iSubType); g_pSM->LogMessage(myself, ">>> b = %s", b?"true":"false"); g_pSM->LogMessage(myself, "---------------------------------------"); g_pSM->LogMessage(myself, ">>> m_iItemDefinitionIndex = %u", cscript->m_iItemDefinitionIndex); g_pSM->LogMessage(myself, ">>> m_iEntityQuality = %u", cscript->m_iEntityQuality); g_pSM->LogMessage(myself, ">>> m_iEntityLevel = %u", cscript->m_iEntityLevel); g_pSM->LogMessage(myself, ">>> m_iItemID = %lu", cscript->m_iItemID); g_pSM->LogMessage(myself, ">>> m_iItemIDHigh = %u", cscript->m_iItemIDHigh); g_pSM->LogMessage(myself, ">>> m_iItemIDLow = %u", cscript->m_iItemIDLow); g_pSM->LogMessage(myself, ">>> m_iAccountID = %u", cscript->m_iAccountID); g_pSM->LogMessage(myself, ">>> m_iPosition = %u", cscript->m_iInventoryPosition); g_pSM->LogMessage(myself, ">>> m_bInitialized = %s", cscript->m_bInitialized?"true":"false"); g_pSM->LogMessage(myself, "---------------------------------------"); for (int i = 0; i < ((cscript->m_Attributes.Count() > 16)?0:cscript->m_Attributes.Count()); i++) { g_pSM->LogMessage(myself, ">>> m_iAttributeDefinitionIndex = %u", cscript->m_Attributes.Element(i).m_iAttributeDefinitionIndex); g_pSM->LogMessage(myself, ">>> m_flValue = %f", cscript->m_Attributes.Element(i).m_flValue); g_pSM->LogMessage(myself, "---------------------------------------"); } g_pSM->LogMessage(myself, ">>> Size of CEconItemView = %d", sizeof(CEconItemView)); g_pSM->LogMessage(myself, ">>> Size of CEconItemAttribute = %d", sizeof(CEconItemAttribute)); g_pSM->LogMessage(myself, ">>> No. of Attributes = %d", cscript->m_Attributes.Count()); g_pSM->LogMessage(myself, "---------------------------------------"); #endif // Summon forward cell_t cellResults = 0; cell_t cellOverrideHandle = 0; g_pForwardGiveItem->PushCell(client); g_pForwardGiveItem->PushString(szClassname); g_pForwardGiveItem->PushCell(cscript->m_iItemDefinitionIndex); g_pForwardGiveItem->PushCellByRef(&cellOverrideHandle); g_pForwardGiveItem->Execute(&cellResults); // Determine what to do switch(cellResults) { case Pl_Continue: { RETURN_META_VALUE(MRES_IGNORED, NULL); } case Pl_Changed: { TScriptedItemOverride *pScriptedItemOverride = GetScriptedItemOverrideFromHandle(cellOverrideHandle); if (pScriptedItemOverride == NULL) { RETURN_META_VALUE(MRES_IGNORED, NULL); } // Execute the new attributes set and we're done! char *finalitem = (char *)szClassname; CEconItemView newitem; CSCICopy(cscript, &newitem); // Override based on the flags passed to this object. if (pScriptedItemOverride->m_bFlags & OVERRIDE_CLASSNAME) { finalitem = pScriptedItemOverride->m_strWeaponClassname; } if (pScriptedItemOverride->m_bFlags & OVERRIDE_ITEM_DEF) { newitem.m_iItemDefinitionIndex = pScriptedItemOverride->m_iItemDefinitionIndex; } if (pScriptedItemOverride->m_bFlags & OVERRIDE_ITEM_LEVEL) { newitem.m_iEntityLevel = pScriptedItemOverride->m_iEntityLevel; } if (pScriptedItemOverride->m_bFlags & OVERRIDE_ITEM_QUALITY) { newitem.m_iEntityQuality = pScriptedItemOverride->m_iEntityQuality; } if (pScriptedItemOverride->m_bFlags & OVERRIDE_ATTRIBUTES) { #ifndef NO_FORCE_QUALITY // Even if we don't want to override the item quality, do if it's set to 0. if (newitem.m_iEntityQuality == 0 && !(pScriptedItemOverride->m_bFlags & OVERRIDE_ITEM_QUALITY) && pScriptedItemOverride->m_iCount > 0) newitem.m_iEntityQuality = 6; #endif if (!(pScriptedItemOverride->m_bFlags & PRESERVE_ATTRIBUTES)) { newitem.m_bDoNotIterateStaticAttributes = true; } newitem.m_Attributes.RemoveAll(); newitem.m_Attributes.AddMultipleToTail(pScriptedItemOverride->m_iCount, pScriptedItemOverride->m_Attributes); } if (cscript->m_iEntityQuality == 0) { newitem.m_iEntityQuality = 0; } RETURN_META_VALUE_MNEWPARAMS(MRES_HANDLED, NULL, MHook_GiveNamedItem, (finalitem, iSubType, &newitem, ((pScriptedItemOverride->m_bFlags & FORCE_GENERATION) == FORCE_GENERATION))); } case Pl_Handled: case Pl_Stop: { RETURN_META_VALUE(MRES_SUPERCEDE, NULL); } } RETURN_META_VALUE(MRES_IGNORED, NULL); }
void ManiSMMHooks::ProcessUsercmds(CUserCmd *cmds, int numcmds, int totalcmds, int dropped_packets, bool paused) { gpManiAFK->ProcessUsercmds(META_IFACEPTR(CBasePlayer), cmds, numcmds); RETURN_META(MRES_IGNORED); }