void ReBuy_handler() #endif { if(ProcessPluginPaused()) RETURN_META(MRES_IGNORED); gpManiWeaponMgr->PreAutoBuyReBuy(); #ifdef GAME_ORANGE SH_CALL(pReBuyCmd, &ConCommand::Dispatch)(command); #else SH_CALL(SH_GET_CALLCLASS(pReBuyCmd), &ConCommand::Dispatch)(); #endif gpManiWeaponMgr->AutoBuyReBuy(); RETURN_META(MRES_SUPERCEDE); }
bool SteamWorksGCHooks::IsMessageAvailable(uint32_t *pcubMsgSize) { if (this->pGCMsgAvail->GetFunctionCount() == 0) { RETURN_META_VALUE(MRES_IGNORED, false); } bool res = META_RESULT_ORIG_RET(bool); if (!res) { RETURN_META_VALUE(MRES_IGNORED, false); } uint32_t shill; if (!pcubMsgSize) { shill = 0; SH_CALL(GetSteamGCPointer(), &ISteamGameCoordinator::IsMessageAvailable)(&shill); pcubMsgSize = &shill; } this->pGCMsgAvail->PushCell(*pcubMsgSize); this->pGCMsgAvail->Execute(NULL); RETURN_META_VALUE(MRES_IGNORED, true); }
void AutoBuy_handler() #endif { if(ProcessPluginPaused()) RETURN_META(MRES_IGNORED); gpManiWeaponMgr->PreAutoBuyReBuy(); #ifdef GAME_ORANGE SH_CALL(pAutoBuyCmd, &ConCommand::Dispatch)(command); #else #ifndef SOURCEMM SH_CALL(pAutoBuyCmd, &ConCommand::Dispatch)(); #else SH_CALL(autobuy_cc, &ConCommand::Dispatch)(); #endif #endif gpManiWeaponMgr->AutoBuyReBuy(); RETURN_META(MRES_SUPERCEDE); }
void CValveMenuDisplay::SendRawDisplay(int client, int priority, unsigned int time) { m_pKv->SetInt("level", priority); m_pKv->SetInt("time", time ? time : 200); SH_CALL(g_pSPHCC, &IServerPluginHelpers::CreateMessage)( PEntityOfEntIndex(client), DIALOG_MENU, m_pKv, vsp_interface); }
void CForwardManager::HandleSpectatorDisconnect(IClient *client, const char *reason) { UnhookClient(client); char disconnectReason[255]; V_strncpy(disconnectReason, reason, 255); int clientIndex = client->GetPlayerSlot() + 1; m_SpectatorDisconnectFwd->PushCell(clientIndex); m_SpectatorDisconnectFwd->PushStringEx(disconnectReason, 255, SM_PARAM_STRING_UTF8 | SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); m_SpectatorDisconnectFwd->Execute(); // We always call the IClient::Disconnect variant, even if we're coming from CGameClient::Disconnect on linux. // They point to the same function in the engine though. Could only confuse other hooks, so might need to revisit this. #if SOURCE_ENGINE == SE_CSGO SH_CALL(client, &IClient::Disconnect)(disconnectReason); #else SH_CALL(client, &IClient::Disconnect)("%s", disconnectReason); #endif m_SpectatorDisconnectedFwd->PushCell(clientIndex); m_SpectatorDisconnectedFwd->PushString(disconnectReason); m_SpectatorDisconnectedFwd->Execute(); }
EGCResults SteamWorksGCHooks::RetrieveMessage(uint32 *punMsgType, void *pubDest, uint32 cubDest, uint32 *pcubMsgSize) { if (this->pGCRetMsg->GetFunctionCount() == 0) { RETURN_META_VALUE(MRES_IGNORED, k_EGCResultOK); } /* Don't trust a bitch, except for 2GD. https://www.youtube.com/watch?v=MgePh_YJgrc */ cell_t Result = k_EGCResultOK; EGCResults res = SH_CALL(GetSteamGCPointer(), &ISteamGameCoordinator::RetrieveMessage)(punMsgType, pubDest, cubDest, pcubMsgSize); if (punMsgType) this->pGCRetMsg->PushCell(*punMsgType); else this->pGCRetMsg->PushCell(0); if (pubDest) this->pGCSendMsg->PushStringEx(reinterpret_cast<char *>(pubDest), cubDest, SM_PARAM_STRING_BINARY | SM_PARAM_STRING_COPY, 0); else this->pGCSendMsg->PushStringEx(const_cast<char *>(""), 1, SM_PARAM_STRING_BINARY | SM_PARAM_STRING_COPY, 0); this->pGCRetMsg->PushCell(cubDest); if (pcubMsgSize) this->pGCRetMsg->PushCell(*pcubMsgSize); else this->pGCRetMsg->PushCell(0); this->pGCRetMsg->Execute(&Result); if (Result != k_EGCResultOK) { if (Result == -1) { Result = k_EGCResultOK; } RETURN_META_VALUE(MRES_SUPERCEDE, static_cast<EGCResults>(Result)); } RETURN_META_VALUE(MRES_IGNORED, k_EGCResultOK); }
void HLTVServerWrapper::HandleClientPrintf(IClient *pClient, const char* buf) { // Craft our own "NetChan" pointer static int offset = -1; if (!g_pGameConf->GetOffset("CBaseClient::m_NetChannel", &offset) || offset == -1) { smutils->LogError(myself, "Failed to find CBaseClient::m_NetChannel offset. Can't print to demo console."); return; } #ifdef WIN32 void *pNetChannel = (void *)((char *)pClient + offset); #else void *pNetChannel = (void *)((char *)pClient + offset - 4); #endif // Set our fake netchannel *(void **)pNetChannel = &FakeNetChan; // Call ClientPrintf again, this time with a "Netchannel" set on the bot. // This will call our own OnHLTVBotNetChanSendNetMsg function SH_CALL(pClient, &IClient::ClientPrintf)("%s", buf); // Set the fake netchannel back to 0. *(void **)pNetChannel = nullptr; }
static cell_t EmitSound(IPluginContext *pContext, const cell_t *params) { cell_t *addr, *cl_array; CellRecipientFilter crf; unsigned int numClients; int client; IGamePlayer *pPlayer = NULL; pContext->LocalToPhysAddr(params[1], &cl_array); numClients = params[2]; /* Client validation */ for (unsigned int i = 0; i < numClients; i++) { client = cl_array[i]; pPlayer = playerhelpers->GetGamePlayer(client); if (!pPlayer) { return pContext->ThrowNativeError("Client index %d is invalid", client); } else if (!pPlayer->IsInGame()) { return pContext->ThrowNativeError("Client %d is not connected", client); } } crf.Initialize(cl_array, numClients); char *sample; pContext->LocalToString(params[3], &sample); int entity = SoundReferenceToIndex(params[4]); int channel = params[5]; int level = params[6]; int flags = params[7]; float vol = sp_ctof(params[8]); int pitch = params[9]; int speakerentity = params[10]; Vector *pOrigin = NULL, origin; Vector *pDir = NULL, dir; pContext->LocalToPhysAddr(params[11], &addr); if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) { pOrigin = &origin; origin.x = sp_ctof(addr[0]); origin.y = sp_ctof(addr[1]); origin.z = sp_ctof(addr[2]); } pContext->LocalToPhysAddr(params[12], &addr); if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) { pDir = &dir; dir.x = sp_ctof(addr[0]); dir.y = sp_ctof(addr[1]); dir.z = sp_ctof(addr[2]); } bool updatePos = params[13] ? true : false; float soundtime = sp_ctof(params[14]); CUtlVector<Vector> *pOrigVec = NULL; CUtlVector<Vector> origvec; if (params[0] > 14) { pOrigVec = &origvec; for (cell_t i = 15; i <= params[0]; i++) { Vector vec; pContext->LocalToPhysAddr(params[i], &addr); vec.x = sp_ctof(addr[0]); vec.y = sp_ctof(addr[1]); vec.z = sp_ctof(addr[2]); origvec.AddToTail(vec); } } /* If we're going to a "local player" and this is a dedicated server, * intelligently redirect each sound. */ if (entity == -2 && engine->IsDedicatedServer()) { for (unsigned int i = 0; i < numClients; i++) { cell_t player[1]; player[0] = cl_array[i]; crf.Reset(); crf.Initialize(player, 1); #if SOURCE_ENGINE >= SE_PORTAL2 if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound)) (crf, player[0], channel, sample, -1, sample, vol, (soundlevel_t)level, 0, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, player[0], channel, sample, -1, sample, vol, (soundlevel_t)level, 0, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } #elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \ || SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2 if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound)) (crf, player[0], channel, sample, vol, (soundlevel_t)level, flags, pitch, 0, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, player[0], channel, sample, vol, (soundlevel_t)level, flags, pitch, 0, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } #else if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound)) (crf, player[0], channel, sample, vol, (soundlevel_t)level, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, player[0], channel, sample, vol, (soundlevel_t)level, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } #endif } } else { #if SOURCE_ENGINE >= SE_PORTAL2 if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound)) (crf, entity, channel, sample, -1, sample, vol, (soundlevel_t)level, 0, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, entity, channel, sample, -1, sample, vol, (soundlevel_t)level, 0, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } #elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \ || SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2 if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound)) (crf, entity, channel, sample, vol, (soundlevel_t)level, flags, pitch, 0, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, entity, channel, sample, vol, (soundlevel_t)level, flags, pitch, 0, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } #else if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound)) (crf, entity, channel, sample, vol, (soundlevel_t)level, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, entity, channel, sample, vol, (soundlevel_t)level, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } #endif } return 1; }
static cell_t EmitSoundEntry(IPluginContext *pContext, const cell_t *params) { #if SOURCE_ENGINE < SE_PORTAL2 return pContext->ThrowNativeError("EmitSoundEntry is not available in this game."); #else cell_t *addr, *cl_array; CellRecipientFilter crf; unsigned int numClients; int client; IGamePlayer *pPlayer = NULL; pContext->LocalToPhysAddr(params[1], &cl_array); numClients = params[2]; /* Client validation */ for (unsigned int i = 0; i < numClients; i++) { client = cl_array[i]; pPlayer = playerhelpers->GetGamePlayer(client); if (!pPlayer) { return pContext->ThrowNativeError("Client index %d is invalid", client); } else if (!pPlayer->IsInGame()) { return pContext->ThrowNativeError("Client %d is not connected", client); } } crf.Initialize(cl_array, numClients); char *soundEntry; pContext->LocalToString(params[3], &soundEntry); char *sample; pContext->LocalToString(params[4], &sample); // By default, we want the hash to equal maxint unsigned int soundEntryHash = -1; // We only generate a hash if the sample is not the same as the sound entry and the sound entry is not empty. if (strcmp(soundEntry, sample) != 0 && strcmp(soundEntry, "") != 0) soundEntryHash = GenerateSoundEntryHash(soundEntry); int entity = SoundReferenceToIndex(params[5]); int channel = params[6]; int level = params[7]; int seed = params[8]; int flags = params[9]; float vol = sp_ctof(params[10]); int pitch = params[11]; int speakerentity = params[12]; Vector *pOrigin = NULL, origin; Vector *pDir = NULL, dir; pContext->LocalToPhysAddr(params[13], &addr); if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) { pOrigin = &origin; origin.x = sp_ctof(addr[0]); origin.y = sp_ctof(addr[1]); origin.z = sp_ctof(addr[2]); } pContext->LocalToPhysAddr(params[14], &addr); if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) { pDir = &dir; dir.x = sp_ctof(addr[0]); dir.y = sp_ctof(addr[1]); dir.z = sp_ctof(addr[2]); } bool updatePos = params[15] ? true : false; float soundtime = sp_ctof(params[16]); CUtlVector<Vector> *pOrigVec = NULL; CUtlVector<Vector> origvec; if (params[0] > 16) { pOrigVec = &origvec; for (cell_t i = 17; i <= params[0]; i++) { Vector vec; pContext->LocalToPhysAddr(params[i], &addr); vec.x = sp_ctof(addr[0]); vec.y = sp_ctof(addr[1]); vec.z = sp_ctof(addr[2]); origvec.AddToTail(vec); } } /* If we're going to a "local player" and this is a dedicated server, * intelligently redirect each sound. */ if (entity == -2 && engine->IsDedicatedServer()) { for (unsigned int i = 0; i < numClients; i++) { cell_t player[1]; player[0] = cl_array[i]; crf.Reset(); crf.Initialize(player, 1); if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound))(crf, player[0], channel, soundEntry, soundEntryHash, sample, vol, (soundlevel_t)level, seed, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, player[0], channel, soundEntry, soundEntryHash, sample, vol, (soundlevel_t)level, seed, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } } } else { if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound))(crf, entity, channel, soundEntry, soundEntryHash, sample, vol, (soundlevel_t)level, seed, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, entity, channel, soundEntry, soundEntryHash, sample, vol, (soundlevel_t)level, seed, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } } return 1; #endif }
static cell_t EmitSound(IPluginContext *pContext, const cell_t *params) { cell_t *addr, *pl_addr; CellRecipientFilter crf; pContext->LocalToPhysAddr(params[1], &pl_addr); crf.Initialize(pl_addr, params[2]); char *sample; pContext->LocalToString(params[3], &sample); int entity = params[4]; int channel = params[5]; int level = params[6]; int flags = params[7]; float vol = sp_ctof(params[8]); int pitch = params[9]; int speakerentity = params[10]; Vector *pOrigin = NULL, origin; Vector *pDir = NULL, dir; pContext->LocalToPhysAddr(params[11], &addr); if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) { pOrigin = &origin; origin.x = sp_ctof(addr[0]); origin.y = sp_ctof(addr[1]); origin.z = sp_ctof(addr[2]); } pContext->LocalToPhysAddr(params[12], &addr); if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) { pDir = &dir; dir.x = sp_ctof(addr[0]); dir.y = sp_ctof(addr[1]); dir.z = sp_ctof(addr[2]); } bool updatePos = params[13] ? true : false; float soundtime = sp_ctof(params[14]); CUtlVector<Vector> *pOrigVec = NULL; CUtlVector<Vector> origvec; if (params[0] > 14) { pOrigVec = &origvec; for (cell_t i = 15; i <= params[0]; i++) { Vector vec; pContext->LocalToPhysAddr(params[i], &addr); vec.x = sp_ctof(addr[0]); vec.y = sp_ctof(addr[1]); vec.z = sp_ctof(addr[2]); origvec.AddToTail(vec); } } /* If we're going to a "local player" and this is a dedicated server, * intelligently redirect each sound. */ if (entity == -2 && engine->IsDedicatedServer()) { for (cell_t i=0; i<params[2]; i++) { cell_t player[1]; player[0] = pl_addr[i]; crf.Reset(); crf.Initialize(player, 1); if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound)) (crf, player[0], channel, sample, vol, (soundlevel_t)level, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, player[0], channel, sample, vol, (soundlevel_t)level, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } } } else { if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound)) (crf, entity, channel, sample, vol, (soundlevel_t)level, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, entity, channel, sample, vol, (soundlevel_t)level, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } } return 1; }
bool TestVafmtAndOverload(std::string &error) { GET_SHPTR(g_SHPtr); g_PLID = 1337; Whatever gabgab; IGaben *pGab = &gabgab; // Part 1 SH_CALL(pGab, static_cast<void (IGaben::*)()>(&IGaben::EatYams))(); SH_CALL(pGab, static_cast<bool (IGaben::*)(const char *) const>(&IGaben::EatYams))("Here!"); SH_ADD_HOOK(IGaben, EatYams, pGab, EatYams0_Handler, false); SH_ADD_HOOK(IGaben, EatYams, pGab, EatYams1_Handler, false); pGab->EatYams(); pGab->EatYams("Here!"); SH_REMOVE_HOOK(IGaben, EatYams, pGab, EatYams0_Handler, false); SH_REMOVE_HOOK(IGaben, EatYams, pGab, EatYams1_Handler, false); CHECK_STATES((&g_States, new State_EatYams_Called(0), new State_EatYams_Called(1), new State_EatYams_Handler_Called(0), new State_EatYams_Called(0), new State_EatYams_Handler_Called(1), new State_EatYams_Called(1), NULL),"Part 1"); // Part 2 pGab->Vafmt1(true, 55, "Hello %s%d%s", "BA", 1, "L"); SH_CALL(pGab, &IGaben::Vafmt1)(true, 55, "Hello %s%d%s", "BA", 1, "L"); pGab->Vafmt2("Hello %s%d%s", "BA", 1, "LOPAN"); SH_CALL(pGab, &IGaben::Vafmt2)("Hello %s%d%s", "BA", 1, "LOPAN"); CHECK_STATES((&g_States, new State_Vafmt_Called(1, "Hello BA1L"), new State_Vafmt_Called(1, "Hello BA1L"), new State_Vafmt_Called(2, "Hello BA1LOPAN"), new State_Vafmt_Called(2, "Hello BA1LOPAN"), NULL), "Part 2"); // Part 3 SH_ADD_HOOK(IGaben, Vafmt1, pGab, Vafmt1_PreHandler, false); SH_ADD_HOOK(IGaben, Vafmt1, pGab, Vafmt1_PostHandler, true); SH_ADD_HOOK(IGaben, Vafmt2, pGab, Vafmt2_PreHandler, false); SH_ADD_HOOK(IGaben, Vafmt2, pGab, Vafmt2_PostHandler, true); pGab->Vafmt1(true, 55, "Hello %s%d%s", "BA", 1, "L"); pGab->Vafmt2("Hello %s%d%s", "BA", 1, "LOPAN"); CHECK_STATES((&g_States, new State_Vafmt_PreHandler_Called(1, std::string("Hello BA1L")), new State_Vafmt_Called(1, std::string("Hello BA1L")), new State_Vafmt_PostHandler_Called(1, std::string("Hello BA1L")), new State_Vafmt_PreHandler_Called(2, std::string("Hello BA1LOPAN")), new State_Vafmt_Called(2, std::string("Hello BA1LOPAN")), new State_Vafmt_PostHandler_Called(2, std::string("Hello BA1LOPAN")), NULL), "Part 3"); // Part 4 SH_REMOVE_HOOK(IGaben, Vafmt1, pGab, Vafmt1_PreHandler, false); SH_REMOVE_HOOK(IGaben, Vafmt1, pGab, Vafmt1_PostHandler, true); SH_REMOVE_HOOK(IGaben, Vafmt2, pGab, Vafmt2_PreHandler, false); SH_REMOVE_HOOK(IGaben, Vafmt2, pGab, Vafmt2_PostHandler, true); pGab->Vafmt1(true, 55, "Hello %s%d%s", "BA", 1, "L"); pGab->Vafmt2("Hello %s%d%s", "BA", 1, "LOPAN"); CHECK_STATES((&g_States, new State_Vafmt_Called(1, "Hello BA1L"), new State_Vafmt_Called(2, "Hello BA1LOPAN"), NULL), "Part 4"); return true; }
bool TestThisPtrOffs(std::string &error) { GET_SHPTR(g_SHPtr); g_PLID = 1337; Derived *pD = MyInstanceFactory(); Base1 *pB1 = pD; Base2 *pB2 = pD; CAutoPtrDestruction<Derived> apd(pD); // It should be: // pB1 = pD // pB2 > pB1 // 1) // Get a callclass for pD // Verify whether the this pointers are correct // Also call them normally to make sure that we aren't messing it up ;) SourceHook::CallClass<Derived> *pD_CC = SH_GET_CALLCLASS(pD); SH_CALL(pD_CC, &Derived::Func1)(); SH_CALL(pD_CC, &Derived::Func2)(); SH_CALL(pD_CC, &Derived::Func3)(); pD->Func1(); pD->Func2(); pD->Func3(); CHECK_STATES((&g_States, new State_Func1_Called(pB1), new State_Func2_Called(pB2), new State_Func3_Called(pD), new State_Func1_Called(pB1), new State_Func2_Called(pB2), new State_Func3_Called(pD), NULL), "Part 1"); SH_CALL(pD_CC, &Base1::Func1)(); SH_CALL(pD_CC, &Base2::Func2)(); CHECK_STATES((&g_States, new State_Func1_Called(pB1), new State_Func2_Called(pB2), NULL), "Part 1.1"); // 2) // Get callclasses for the other ones and verify it as well SourceHook::CallClass<Base1> *pB1_CC = SH_GET_CALLCLASS(pB1); SourceHook::CallClass<Base2> *pB2_CC = SH_GET_CALLCLASS(pB2); SH_CALL(pB1_CC, &Base1::Func1)(); SH_CALL(pB2_CC, &Base2::Func2)(); CHECK_STATES((&g_States, new State_Func1_Called(pB1), new State_Func2_Called(pB2), NULL), "Part 2"); // 3) Add hooks on them (referring to them through pD1 / Derived) // Check whether the hooks are called with the correct this pointer SH_ADD_HOOK(Derived, Func1, pD, SH_STATIC(Handler_Func1), false); SH_ADD_HOOK(Derived, Func2, pD, SH_STATIC(Handler_Func2), false); SH_ADD_HOOK(Derived, Func3, pD, SH_STATIC(Handler_Func3), false); pD->Func1(); pD->Func2(); pD->Func3(); pB1->Func1(); pB2->Func2(); // The handlers should always be called with the pointer to Derived CHECK_STATES((&g_States, new State_Func1H_Called(pD), new State_Func1_Called(pB1), new State_Func2H_Called(pD), new State_Func2_Called(pB2), new State_Func3H_Called(pD), new State_Func3_Called(pD), new State_Func1H_Called(pD), new State_Func1_Called(pB1), new State_Func2H_Called(pD), new State_Func2_Called(pB2), NULL), "Part 3"); SH_REMOVE_HOOK(Derived, Func1, pD, SH_STATIC(Handler_Func1), false); SH_REMOVE_HOOK(Derived, Func2, pD, SH_STATIC(Handler_Func2), false); SH_REMOVE_HOOK(Derived, Func3, pD, SH_STATIC(Handler_Func3), false); // 4) // Now add the hooks on Base1 and Base2 and check again // Note that the new implicit_cast should convert the pD to Base1*/Base2* :) SH_ADD_HOOK(Base1, Func1, pD, SH_STATIC(Handler_Func1), false); SH_ADD_HOOK(Base2, Func2, pD, SH_STATIC(Handler_Func2), false); SH_ADD_HOOK(Derived, Func3, pD, SH_STATIC(Handler_Func3), false); pD->Func1(); pD->Func2(); pD->Func3(); pB1->Func1(); pB2->Func2(); // This time, the handlers for Func1 should be called with pB1 and the handlers // for Func2 should be called with pB2 CHECK_STATES((&g_States, new State_Func1H_Called(pB1), new State_Func1_Called(pB1), new State_Func2H_Called(pB2), new State_Func2_Called(pB2), new State_Func3H_Called(pD), new State_Func3_Called(pD), new State_Func1H_Called(pB1), new State_Func1_Called(pB1), new State_Func2H_Called(pB2), new State_Func2_Called(pB2), NULL), "Part 4"); SH_REMOVE_HOOK(Base1, Func1, pD, SH_STATIC(Handler_Func1), false); SH_REMOVE_HOOK(Base2, Func2, pD, SH_STATIC(Handler_Func2), false); SH_REMOVE_HOOK(Derived, Func3, pD, SH_STATIC(Handler_Func3), false); // 5) // Add some hooks, and use callclasses // 5.1) First off, add all of them on pD SH_ADD_HOOK(Derived, Func1, pD, SH_STATIC(Handler_Func1), false); SH_ADD_HOOK(Derived, Func2, pD, SH_STATIC(Handler_Func2), false); SH_ADD_HOOK(Derived, Func3, pD, SH_STATIC(Handler_Func3), false); pD->Func1(); pD->Func2(); pD->Func3(); CHECK_STATES((&g_States, new State_Func1H_Called(pD), new State_Func1_Called(pB1), new State_Func2H_Called(pD), new State_Func2_Called(pB2), new State_Func3H_Called(pD), new State_Func3_Called(pD), NULL), "Part 5.1"); SH_CALL(pD_CC, &Derived::Func1)(); SH_CALL(pD_CC, &Derived::Func2)(); SH_CALL(pD_CC, &Derived::Func3)(); SH_CALL(pB1_CC, &Base1::Func1)(); SH_CALL(pB2_CC, &Base2::Func2)(); CHECK_STATES((&g_States, new State_Func1_Called(pB1), new State_Func2_Called(pB2), new State_Func3_Called(pD), new State_Func1_Called(pB1), new State_Func2_Called(pB2), NULL), "Part 5.2"); SH_REMOVE_HOOK(Derived, Func1, pD, SH_STATIC(Handler_Func1), false); SH_REMOVE_HOOK(Derived, Func2, pD, SH_STATIC(Handler_Func2), false); SH_REMOVE_HOOK(Derived, Func3, pD, SH_STATIC(Handler_Func3), false); SH_RELEASE_CALLCLASS(pB1_CC); SH_RELEASE_CALLCLASS(pB2_CC); SH_RELEASE_CALLCLASS(pD_CC); return true; }