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);
}
Exemple #2
0
void MConsole::AddCommand(SMJS_Plugin *pl, const char *cmdName, v8::Handle<v8::Function> func, bool serverOnly){
	std::string stdCmdName(cmdName);
	std::transform(stdCmdName.begin(), stdCmdName.end(), stdCmdName.begin(), ::tolower);


	CommandHook *wrapper = new CommandHook;
	wrapper->pl = pl;
	wrapper->func = v8::Persistent<v8::Function>::New(func);
	wrapper->serverOnly = serverOnly;

	auto infoIt = g_MConsole->pluginCmds2.find(stdCmdName);
	
	if(infoIt == g_MConsole->pluginCmds2.end()){
		CommandHookInfo *info = new CommandHookInfo();

		g_MConsole->pluginCmds2.insert(std::make_pair(stdCmdName, info));
		infoIt = g_MConsole->pluginCmds2.find(stdCmdName);

		ConCommand *conCmd = icvar->FindCommand(cmdName);
		if(!conCmd){
			conCmd = new ConCommand(dupstring(cmdName), MConsole::CommandCallback2);
			icvar->RegisterConCommand(conCmd);
			info->isSMJS = true;
		}else{
			SH_ADD_HOOK(ConCommand, Dispatch, conCmd, SH_STATIC(MConsole::CommandCallback), false);
			info->isSMJS = false;
		}
	}

	infoIt->second->hooks.push_back(wrapper);
}
bool StubPlugin::Unload(char *error, size_t maxlen)
{
	SM_UnloadExtension();

	SH_REMOVE_HOOK(IServerGameDLL, ServerActivate, server, SH_STATIC(Hook_ServerActivate), true);

	return true;
}
Exemple #4
0
MConsole::MConsole(){
	g_MConsole = this;
	identifier = "console";

	SH_ADD_HOOK(IServerGameClients, SetCommandClient, serverClients, SH_MEMBER(this, &MConsole::SetCommandClient), false);

	cmdSay = icvar->FindCommand("say");
	cmdSayTeam = icvar->FindCommand("say_team");

	Assert(cmdSay != NULL);
	Assert(cmdSayTeam != NULL);

	SH_ADD_HOOK(ConCommand, Dispatch, cmdSay, SH_STATIC(&MConsole::OnSayCommand_Pre), false);
	SH_ADD_HOOK(ConCommand, Dispatch, cmdSay, SH_STATIC(&MConsole::OnSayCommand_Post), true);

	SH_ADD_HOOK(ConCommand, Dispatch, cmdSayTeam, SH_STATIC(&MConsole::OnSayCommand_Pre), false);
	SH_ADD_HOOK(ConCommand, Dispatch, cmdSayTeam, SH_STATIC(&MConsole::OnSayCommand_Post), true);
}
void CSourceMMMAP::HookConCommands()
{
	//find the commands in the server's CVAR list
#if defined (GAME_CSGO)
	pSayCmd = static_cast<ConCommand *>(g_pCVar->FindCommand("say"));
	pTeamSayCmd = static_cast<ConCommand *>(g_pCVar->FindCommand("say_team"));
	pChangeLevelCmd = static_cast<ConCommand *>(g_pCVar->FindCommand("changelevel"));
	pAutoBuyCmd = static_cast<ConCommand *>(g_pCVar->FindCommand("autobuy"));
	pReBuyCmd = static_cast<ConCommand *>(g_pCVar->FindCommand("rebuy"));
	pRespawnEntities = static_cast<ConCommand *>(g_pCVar->FindCommand("respawn_entities"));
#else
	ConCommandBase *pCmd = g_pCVar->GetCommands();
	while (pCmd)
	{
		if (pCmd->IsCommand())
		{
			if (strcmp(pCmd->GetName(), "say") == 0)
				pSayCmd = static_cast<ConCommand *>(pCmd);
			else if (strcmp(pCmd->GetName(), "say_team") == 0)
				pTeamSayCmd = static_cast<ConCommand *>(pCmd);
			else if (strcmp(pCmd->GetName(), "changelevel") == 0)
				pChangeLevelCmd = static_cast<ConCommand *>(pCmd);
			else if (strcmp(pCmd->GetName(), "autobuy") == 0)
				pAutoBuyCmd = static_cast<ConCommand *>(pCmd);
			else if (strcmp(pCmd->GetName(), "rebuy") == 0)
				pReBuyCmd = static_cast<ConCommand *>(pCmd);
			else if (strcmp(pCmd->GetName(), "respawn_entities") == 0)
				pRespawnEntities = static_cast<ConCommand *>(pCmd);
		}

		pCmd = const_cast<ConCommandBase *>(pCmd->GetNext());
	}
#endif 

#if !defined GAME_ORANGE && defined SOURCEMM
	if (pSayCmd) SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pSayCmd, Say_handler, false);
	if (pRespawnEntities) SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pRespawnEntities, RespawnEntities_handler, false);
	if (pTeamSayCmd) SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pTeamSayCmd, TeamSay_handler, false);
	if (pChangeLevelCmd) SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pChangeLevelCmd, ChangeLevel_handler, false);
	if (pAutoBuyCmd) 
	{
		SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pAutoBuyCmd, AutoBuy_handler, false);
		autobuy_cc = SH_GET_CALLCLASS(pAutoBuyCmd);
	}

	if (pReBuyCmd) 
	{
		SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pReBuyCmd, ReBuy_handler, false);
		rebuy_cc = SH_GET_CALLCLASS(pReBuyCmd);
	}
#else
	if (pSayCmd) SH_ADD_HOOK(ConCommand, Dispatch, pSayCmd, SH_STATIC(Say_handler), false);
	if (pRespawnEntities) SH_ADD_HOOK(ConCommand, Dispatch, pRespawnEntities, SH_STATIC(RespawnEntities_handler), false);
	if (pTeamSayCmd) SH_ADD_HOOK(ConCommand, Dispatch, pTeamSayCmd, SH_STATIC(TeamSay_handler), false);
	if (pChangeLevelCmd) SH_ADD_HOOK(ConCommand, Dispatch, pChangeLevelCmd, SH_STATIC(ChangeLevel_handler), false);
	if (pAutoBuyCmd) SH_ADD_HOOK(ConCommand, Dispatch, pAutoBuyCmd, SH_STATIC(AutoBuy_handler), false);
	if (pReBuyCmd) SH_ADD_HOOK(ConCommand, Dispatch, pReBuyCmd, SH_STATIC(ReBuy_handler), false);
#endif
}
bool TF2Tools::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late)
{
	GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);

	gpGlobals = ismm->GetCGlobals();

	SH_ADD_HOOK(IServerGameDLL, ServerActivate, gamedll, SH_STATIC(OnServerActivate), true);

	GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION);

	GET_V_IFACE_CURRENT(GetEngineFactory, m_GameEventManager, IGameEventManager2, INTERFACEVERSION_GAMEEVENTSMANAGER2);
	m_GameEventManager->AddListener(this, "teamplay_restart_round", true);

	return true;
}
Exemple #7
0
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;
	}
}
bool StubPlugin::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late)
{
	PLUGIN_SAVEVARS();

#if defined METAMOD_PLAPI_VERSION
	GET_V_IFACE_ANY(GetServerFactory, server, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL);
	GET_V_IFACE_ANY(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
#else
	GET_V_IFACE_ANY(serverFactory, server, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL);
	GET_V_IFACE_ANY(engineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
#endif

	SH_ADD_HOOK(IServerGameDLL, ServerActivate, server, SH_STATIC(Hook_ServerActivate), true);

	ismm->AddListener(this, this);

	return true;
}
Exemple #9
0
void TF2Tools::SDK_OnUnload()
{
	SH_REMOVE_HOOK(IServerGameDLL, ServerActivate, gamedll, SH_STATIC(OnServerActivate), true);

	g_RegNatives.UnregisterAll();
	gameconfs->CloseGameConfigFile(g_pGameConf);
	playerhelpers->UnregisterCommandTargetProcessor(this);
	playerhelpers->RemoveClientListener(this);

	plsys->RemovePluginsListener(this);

	forwards->ReleaseForward(g_critForward);
	forwards->ReleaseForward(g_isHolidayForward);
	forwards->ReleaseForward(g_addCondForward);
	forwards->ReleaseForward(g_removeCondForward);
	forwards->ReleaseForward(g_waitingPlayersStartForward);
	forwards->ReleaseForward(g_waitingPlayersEndForward);
	forwards->ReleaseForward(g_teleportForward);
}
Exemple #10
0
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);
	}
}
Exemple #11
0
MClient::MClient(){
	self = this;
	

	identifier = "clients";
	SH_ADD_HOOK(IServerGameClients, ClientConnect, serverClients, SH_STATIC(OnClientConnect), false);
	SH_ADD_HOOK(IServerGameClients, ClientConnect, serverClients, SH_STATIC(OnClientConnect_Post), true);

	
	SH_ADD_HOOK(IServerGameClients, ClientPutInServer, serverClients, SH_STATIC(OnClientPutInServer), true);
	SH_ADD_HOOK(IServerGameClients, ClientDisconnect, serverClients, SH_STATIC(OnClientDisconnect), false);
	SH_ADD_HOOK(IServerGameClients, ClientDisconnect, serverClients, SH_STATIC(OnClientDisconnect_Post), true);
	SH_ADD_HOOK(IServerGameClients, ClientCommand, serverClients, SH_STATIC(OnClientCommand), false);

	//SH_ADD_HOOK(IServerGameClients, ClientSettingsChanged, serverClients, SH_STATIC(OnClientSettingsChanged), true);

	smutils->AddGameFrameHook(MClient::OnGameFrame);
}
void	ManiSMMHooks::HookConCommands()
{
	//find the commands in the server's CVAR list
#if defined (GAME_CSGO)
	pSayCmd = static_cast<ConCommand *>(g_pCVar->FindCommand("say"));
	pTeamSayCmd = static_cast<ConCommand *>(g_pCVar->FindCommand("say_team"));
	pChangeLevelCmd = static_cast<ConCommand *>(g_pCVar->FindCommand("changelevel"));
	pAutoBuyCmd = static_cast<ConCommand *>(g_pCVar->FindCommand("autobuy"));
	pReBuyCmd = static_cast<ConCommand *>(g_pCVar->FindCommand("rebuy"));
	pRespawnEntities = static_cast<ConCommand *>(g_pCVar->FindCommand("respawn_entities"));
#else
	ConCommandBase *pCmd = NULL;
	pCmd = g_pCVar->GetCommands();

	while (pCmd)
	{
		if (pCmd->IsCommand())
		{
			if (strcmp(pCmd->GetName(), "say") == 0)
				pSayCmd = static_cast<ConCommand *>(pCmd);
			else if (strcmp(pCmd->GetName(), "say_team") == 0)
				pTeamSayCmd = static_cast<ConCommand *>(pCmd);
			else if (strcmp(pCmd->GetName(), "changelevel") == 0)
				pChangeLevelCmd = static_cast<ConCommand *>(pCmd);
			else if (strcmp(pCmd->GetName(), "autobuy") == 0)
				pAutoBuyCmd = static_cast<ConCommand *>(pCmd);
			else if (strcmp(pCmd->GetName(), "rebuy") == 0)
				pReBuyCmd = static_cast<ConCommand *>(pCmd);
			else if (strcmp(pCmd->GetName(), "respawn_entities") == 0)
				pRespawnEntities = static_cast<ConCommand *>(pCmd);
		}

		pCmd = const_cast<ConCommandBase *>(pCmd->GetNext());
	}
#endif
	if (pSayCmd) SH_ADD_HOOK(ConCommand, Dispatch, pSayCmd, SH_STATIC(Say_handler), false);
	if (pRespawnEntities) SH_ADD_HOOK(ConCommand, Dispatch, pRespawnEntities, SH_STATIC(RespawnEntities_handler), false);
	if (pTeamSayCmd) SH_ADD_HOOK(ConCommand, Dispatch, pTeamSayCmd, SH_STATIC(TeamSay_handler), false);
	if (pChangeLevelCmd) SH_ADD_HOOK(ConCommand, Dispatch, pChangeLevelCmd, SH_STATIC(ChangeLevel_handler), false);
	if (pAutoBuyCmd) SH_ADD_HOOK(ConCommand, Dispatch, pAutoBuyCmd, SH_STATIC(AutoBuy_handler), false);
	if (pReBuyCmd) SH_ADD_HOOK(ConCommand, Dispatch, pReBuyCmd, SH_STATIC(ReBuy_handler), false);
}
Exemple #13
0
void ConVarManager::OnSimillimumShutdown()
{
	List<ConVarInfo *>::iterator iter = m_ConVars.begin();
	HandleSecurity sec(NULL, g_pCoreIdent);

	/* Iterate list of ConVarInfo structures, remove every one of them */
	while (iter != m_ConVars.end())
	{
		ConVarInfo *pInfo = (*iter);

		iter = m_ConVars.erase(iter);

		handlesys->FreeHandle(pInfo->handle, &sec);
		if (pInfo->pChangeForward != NULL)
		{
			g_Forwards.ReleaseForward(pInfo->pChangeForward);
		}
		if (pInfo->sourceMod)
		{
			/* If we created it, we won't be tracking it, therefore it is 
			 * safe to remove everything in one go.
			 */
			META_UNREGCVAR(pInfo->pVar);
			delete [] pInfo->pVar->GetName();
			delete [] pInfo->pVar->GetHelpText();
			delete [] pInfo->pVar->GetDefault();
			delete pInfo->pVar;
		}
		else
		{
			/* If we didn't create it, we might be tracking it.  Also, 
			 * it could be unreadable.
			 */
			UntrackConCommandBase(pInfo->pVar, this);
		}

		/* It's not safe to read the name here, so we simply delete the 
		 * the info struct and clear the lookup cache at the end.
		 */
		delete pInfo;
	}
	convar_cache.clear();

#if SOURCE_ENGINE != SE_DARKMESSIAH
	/* Unhook things */
	if (m_bIsDLLQueryHooked)
	{
		SH_REMOVE_HOOK(IServerGameDLL, OnQueryCvarValueFinished, gamedll, SH_MEMBER(this, &ConVarManager::OnQueryCvarValueFinished), false);
		m_bIsDLLQueryHooked = false;
	}
	else if (m_bIsVSPQueryHooked)
	{
		SH_REMOVE_HOOK(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, SH_MEMBER(this, &ConVarManager::OnQueryCvarValueFinished), false);
		m_bIsVSPQueryHooked = false;
	}
#endif

#if SOURCE_ENGINE >= SE_ORANGEBOX
	SH_REMOVE_HOOK(ICvar, CallGlobalChangeCallbacks, icvar, SH_STATIC(OnConVarChanged), false);
#else
	SH_REMOVE_HOOK(ICvar, CallGlobalChangeCallback, icvar, SH_STATIC(OnConVarChanged), false);
#endif

	/* Remove the 'convars' option from the 'sm' console command */
	g_RootMenu.RemoveRootConsoleCommand("cvars", this);

	scripts->RemovePluginsListener(this);

	/* Remove the 'ConVar' handle type */
	handlesys->RemoveType(m_ConVarType, g_pCoreIdent);
}
Exemple #14
0
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;
}
bool TestReentr(std::string &error)
{
	GET_SHPTR(g_SHPtr);
	g_PLID = 1337;

	g_pC1 = &g_C1;
	g_pC2 = &g_C2;
	g_pC3 = &g_C3;
	g_pC4 = &g_C4;
	g_pC5 = &g_C5;
	g_pC6 = &g_C6;
	g_pC7 = &g_C7;
	g_pC8 = &g_C8;

	SH_ADD_HOOK(C1, F, g_pC1, SH_STATIC(Handler_C1_F), false);
	SH_ADD_HOOK(C1, G, g_pC1, SH_STATIC(Handler_C1_G), false);
	SH_ADD_HOOK(C2, F, g_pC2, SH_STATIC(Handler_C2_F), false);
	SH_ADD_HOOK(C2, G, g_pC2, SH_STATIC(Handler_C2_G), false);
	SH_ADD_HOOK(C3, F, g_pC3, SH_STATIC(Handler_C3_F), false);
	SH_ADD_HOOK(C3, G, g_pC3, SH_STATIC(Handler_C3_G), false);
	SH_ADD_HOOK(C4, F, g_pC4, SH_STATIC(Handler_C4_F), false);
	SH_ADD_HOOK(C4, G, g_pC4, SH_STATIC(Handler_C4_G), false);
	SH_ADD_HOOK(C5, F, g_pC5, SH_STATIC(Handler_C5_F), false);
	SH_ADD_HOOK(C5, G, g_pC5, SH_STATIC(Handler_C5_G), false);
	SH_ADD_HOOK(C6, F, g_pC6, SH_STATIC(Handler_C6_F), false);
	SH_ADD_HOOK(C6, G, g_pC6, SH_STATIC(Handler_C6_G), false);
	SH_ADD_HOOK(C7, F, g_pC7, SH_STATIC(Handler_C7_F), false);
	SH_ADD_HOOK(C7, G, g_pC7, SH_STATIC(Handler_C7_G), false);
	SH_ADD_HOOK(C8, F, g_pC8, SH_STATIC(Handler_C8_F), false);
	SH_ADD_HOOK(C8, G, g_pC8, SH_STATIC(Handler_C8_G), false);

	g_pC1->F();

	CHECK_STATES((&g_States,
		new State_H_C1_F(g_pC1),
		new State_H_C1_G(g_pC1),
		new State_H_C2_F(g_pC2),
		new State_H_C2_G(g_pC2),
		new State_H_C3_F(g_pC3),
		new State_H_C3_G(g_pC3),
		new State_H_C4_F(g_pC4),
		new State_H_C4_G(g_pC4),
		new State_H_C5_F(g_pC5),
		new State_H_C5_G(g_pC5),
		new State_H_C6_F(g_pC6),
		new State_H_C6_G(g_pC6),
		new State_H_C7_F(g_pC7),
		new State_H_C7_G(g_pC7),
		new State_H_C8_F(g_pC8),
		new State_H_C8_G(g_pC8),
		new State_C8_G(g_pC8),
		new State_C8_F(g_pC8),
		new State_C7_G(g_pC7),
		new State_C7_F(g_pC7),
		new State_C6_G(g_pC6),
		new State_C6_F(g_pC6),
		new State_C5_G(g_pC5),
		new State_C5_F(g_pC5),
		new State_C4_G(g_pC4),
		new State_C4_F(g_pC4),
		new State_C3_G(g_pC3),
		new State_C3_F(g_pC3),
		new State_C2_G(g_pC2),
		new State_C2_F(g_pC2),
		new State_C1_G(g_pC1),
		new State_C1_F(g_pC1),
		NULL), "1");


	SH_ADD_HOOK(C4, G, g_pC4, SH_STATIC(Handler2_C4_G), false);

	g_pC1->F();

	CHECK_STATES((&g_States,
		new State_H_C1_F(g_pC1),
		new State_H_C1_G(g_pC1),
		new State_H_C2_F(g_pC2),
		new State_H_C2_G(g_pC2),
		new State_H_C3_F(g_pC3),
		new State_H_C3_G(g_pC3),
		new State_H_C4_F(g_pC4),
		new State_H_C4_G(g_pC4),
		new State_H_C5_F(g_pC5),
		new State_H_C5_G(g_pC5),
		new State_H_C6_F(g_pC6),
		new State_H_C6_G(g_pC6),
		new State_H_C7_F(g_pC7),
		new State_H_C7_G(g_pC7),
		new State_H_C8_F(g_pC8),
		new State_H_C8_G(g_pC8),
		new State_C8_G(g_pC8),
		new State_C8_F(g_pC8),
		new State_C7_G(g_pC7),
		new State_C7_F(g_pC7),
		new State_C6_G(g_pC6),
		new State_C6_F(g_pC6),
		new State_C5_G(g_pC5),
		new State_C5_F(g_pC5),
		new State_H2_C4_G(g_pC4),
		new State_C4_G(g_pC4),
		new State_C4_F(g_pC4),
		new State_C3_G(g_pC3),
		new State_C3_F(g_pC3),
		new State_C2_G(g_pC2),
		new State_C2_F(g_pC2),
		new State_C1_G(g_pC1),
		new State_C1_F(g_pC1),
		NULL), "2");

	g_pC1->F();

	CHECK_STATES((&g_States,
		new State_H_C1_F(g_pC1),
		new State_H_C1_G(g_pC1),
		new State_H_C2_F(g_pC2),
		new State_H_C2_G(g_pC2),
		new State_H_C3_F(g_pC3),
		new State_H_C3_G(g_pC3),
		new State_H_C4_F(g_pC4),
		new State_H_C4_G(g_pC4),
		new State_H_C5_F(g_pC5),
		new State_H_C5_G(g_pC5),
		new State_H_C6_F(g_pC6),
		new State_H_C6_G(g_pC6),
		new State_H_C7_F(g_pC7),
		new State_H_C7_G(g_pC7),
		new State_H_C8_F(g_pC8),
		new State_H_C8_G(g_pC8),
		new State_C8_G(g_pC8),
		new State_C8_F(g_pC8),
		new State_C7_G(g_pC7),
		new State_C7_F(g_pC7),
		new State_C6_G(g_pC6),
		new State_C6_F(g_pC6),
		new State_C5_G(g_pC5),
		new State_C5_F(g_pC5),
		new State_H2_C4_G(g_pC4),
		new State_C4_G(g_pC4),
		new State_C4_F(g_pC4),
		new State_C3_G(g_pC3),
		new State_C3_F(g_pC3),
		new State_C2_G(g_pC2),
		new State_C2_F(g_pC2),
		new State_C1_G(g_pC1),
		new State_C1_F(g_pC1),
		NULL), "3");

	g_TestID = 1;

	g_pC1->F();

	CHECK_STATES((&g_States,
		new State_H_C1_F(g_pC1),
		new State_H_C1_G(g_pC1),
		new State_H_C2_F(g_pC2),
		new State_H_C2_G(g_pC2),
		new State_H_C3_F(g_pC3),
		new State_H_C3_G(g_pC3),
		new State_H_C4_F(g_pC4),
		new State_H_C4_G(g_pC4),
		new State_H_C5_F(g_pC5),
		new State_H_C5_G(g_pC5),
		new State_H_C6_F(g_pC6),
		new State_H_C6_G(g_pC6),
		new State_H_C7_F(g_pC7),
		new State_H_C7_G(g_pC7),
		new State_H_C8_F(g_pC8),
		new State_H_C8_G(g_pC8),
		new State_C8_G(g_pC8),
		new State_C8_F(g_pC8),
		new State_C7_G(g_pC7),
		new State_C7_F(g_pC7),
		new State_C6_G(g_pC6),
		new State_C6_F(g_pC6),
		new State_C5_G(g_pC5),
		new State_C5_F(g_pC5),
		new State_C4_G(g_pC4),
		new State_C4_F(g_pC4),
		new State_C3_G(g_pC3),
		new State_C3_F(g_pC3),
		new State_C2_G(g_pC2),
		new State_C2_F(g_pC2),
		new State_C1_G(g_pC1),
		new State_C1_F(g_pC1),
		NULL), "4");

	g_pC1->F();

	CHECK_STATES((&g_States,
		new State_H_C1_F(g_pC1),
		new State_H_C1_G(g_pC1),
		new State_H_C2_F(g_pC2),
		new State_H_C2_G(g_pC2),
		new State_H_C3_F(g_pC3),
		new State_H_C3_G(g_pC3),
		new State_H_C4_F(g_pC4),
		new State_H_C4_G(g_pC4),
		new State_H_C5_F(g_pC5),
		new State_H_C5_G(g_pC5),
		new State_H_C6_F(g_pC6),
		new State_H_C6_G(g_pC6),
		new State_H_C7_F(g_pC7),
		new State_H_C7_G(g_pC7),
		new State_H_C8_F(g_pC8),
		new State_H_C8_G(g_pC8),
		new State_C8_G(g_pC8),
		new State_C8_F(g_pC8),
		new State_C7_G(g_pC7),
		new State_C7_F(g_pC7),
		new State_C6_G(g_pC6),
		new State_C6_F(g_pC6),
		new State_C5_G(g_pC5),
		new State_C5_F(g_pC5),
		new State_C4_G(g_pC4),
		new State_C4_F(g_pC4),
		new State_C3_G(g_pC3),
		new State_C3_F(g_pC3),
		new State_C2_G(g_pC2),
		new State_C2_F(g_pC2),
		new State_C1_G(g_pC1),
		new State_C1_F(g_pC1),
		NULL), "5");



	SH_ADD_HOOK(C4, G, g_pC4, SH_STATIC(Handler2_C4_G), false);

	g_TestID = 2;

	g_pC1->F();

	CHECK_STATES((&g_States,
		new State_H_C1_F(g_pC1),
		new State_H_C1_G(g_pC1),
		new State_H_C2_F(g_pC2),
		new State_H_C2_G(g_pC2),
		new State_H_C3_F(g_pC3),
		new State_H_C3_G(g_pC3),
		new State_H_C4_F(g_pC4),
		new State_H_C4_G(g_pC4),
		new State_H_C5_F(g_pC5),
		new State_H_C5_G(g_pC5),
		new State_H_C6_F(g_pC6),
		new State_H_C6_G(g_pC6),
		new State_H_C7_F(g_pC7),
		new State_H_C7_G(g_pC7),
		new State_H_C8_F(g_pC8),
		new State_H_C8_G(g_pC8),
		new State_C8_G(g_pC8),
		new State_C8_F(g_pC8),
		new State_C7_G(g_pC7),
		new State_C7_F(g_pC7),
		new State_C6_G(g_pC6),
		new State_C6_F(g_pC6),
		new State_C5_G(g_pC5),
		new State_C5_F(g_pC5),
		new State_C4_G(g_pC4),
		new State_C4_F(g_pC4),
		new State_C3_G(g_pC3),
		new State_C3_F(g_pC3),
		new State_C2_G(g_pC2),
		new State_C2_F(g_pC2),
		new State_C1_G(g_pC1),
		new State_C1_F(g_pC1),
		NULL), "6");

	g_pC1->F();

	CHECK_STATES((&g_States,
		new State_H_C1_F(g_pC1),
		new State_H_C1_G(g_pC1),
		new State_H_C2_F(g_pC2),
		new State_H_C2_G(g_pC2),
		new State_H_C3_F(g_pC3),
		new State_H_C3_G(g_pC3),
		new State_H_C4_F(g_pC4),
		new State_C4_G(g_pC4),
		new State_C4_F(g_pC4),
		new State_C3_G(g_pC3),
		new State_C3_F(g_pC3),
		new State_C2_G(g_pC2),
		new State_C2_F(g_pC2),
		new State_C1_G(g_pC1),
		new State_C1_F(g_pC1),
		NULL), "7");

	SH_REMOVE_HOOK(C1, F, g_pC1, SH_STATIC(Handler_C1_F), false);
	SH_REMOVE_HOOK(C1, G, g_pC1, SH_STATIC(Handler_C1_G), false);
	SH_REMOVE_HOOK(C2, F, g_pC2, SH_STATIC(Handler_C2_F), false);
	SH_REMOVE_HOOK(C2, G, g_pC2, SH_STATIC(Handler_C2_G), false);
	SH_REMOVE_HOOK(C3, F, g_pC3, SH_STATIC(Handler_C3_F), false);
	SH_REMOVE_HOOK(C3, G, g_pC3, SH_STATIC(Handler_C3_G), false);
	SH_REMOVE_HOOK(C4, F, g_pC4, SH_STATIC(Handler_C4_F), false);
	SH_REMOVE_HOOK(C4, G, g_pC4, SH_STATIC(Handler_C4_G), false);
	SH_REMOVE_HOOK(C5, F, g_pC5, SH_STATIC(Handler_C5_F), false);
	SH_REMOVE_HOOK(C5, G, g_pC5, SH_STATIC(Handler_C5_G), false);
	SH_REMOVE_HOOK(C6, F, g_pC6, SH_STATIC(Handler_C6_F), false);
	SH_REMOVE_HOOK(C6, G, g_pC6, SH_STATIC(Handler_C6_G), false);
	SH_REMOVE_HOOK(C7, F, g_pC7, SH_STATIC(Handler_C7_F), false);
	SH_REMOVE_HOOK(C7, G, g_pC7, SH_STATIC(Handler_C7_G), false);
	SH_REMOVE_HOOK(C8, F, g_pC8, SH_STATIC(Handler_C8_F), false);
	SH_REMOVE_HOOK(C8, G, g_pC8, SH_STATIC(Handler_C8_G), false);

	return true;
}