credits to fysions

Code:
#include "CAntiSmac.h"
 
#include "SDK.h"
#include "Util.h"
 
bool __stdcall Hooked_ProcessGetCvarValue(SVC_GetCvarValue *msg)
{
 
	return CAntiSmac::getInst()->processGetCvarValue(msg);
 
	// VMTManager &hook = VMTManager::GetHook(pClientState);
	// bool bRet = hook.GetMethod<bool(__stdcall *)(SVC_GetCvarValue *)>(gOffsets.iProcessGetCvarValue)(msg);
 
	// return bRet;
}
 
bool __stdcall Hooked_ProcessSetConVar(NET_SetConVar *msg)
{
 
	return CAntiSmac::getInst()->processSetConVar(msg);
 
	// VMTManager &hook = VMTManager::GetHook(pClientState);
	// bool bRet = hook.GetMethod<bool(__stdcall *)(SVC_GetCvarValue *)>(gOffsets.iProcessGetCvarValue)(msg);
 
	// return bRet;
}
 
bool __stdcall Hooked_StringCmd(NET_StringCmd *msg) { return CAntiSmac::getInst()->processStringCmd(msg); }
 
const char *CAntiSmac::name() const { return "ANTI-SMAC"; }
 
void CAntiSmac::init()
{
	// hook the stuff
	//clientStateHook = new VMTBaseManager();
	//// hook and manually say that there are 28 vfuncs in the table
	//clientStateHook->Init(gInts.ClientState, 0x8);
	//clientStateHook->HookMethod(&Hooked_ProcessGetCvarValue, gOffsets.processGetCvarValue);
	//clientStateHook->HookMethod(&Hooked_ProcessSetConVar, gOffsets.processSetConVar);
	//clientStateHook->Rehook();
 
	gHookManager.hookMethod(gInts.ClientState.get(), gOffsets.processGetCvarValue, &Hooked_ProcessGetCvarValue, 0x8);
	gHookManager.hookMethod(gInts.ClientState.get(), gOffsets.processSetConVar, &Hooked_ProcessSetConVar, 0x8);
/*
	#if _MSC_VER == 1900
 
	// open this file for reading
	auto handle = gFileManager.open(getPathForDll(gInts.thisDll) + "..\\config\\CAntiSmac.txt", std::ios::in);
 
	if( handle == CFileManager::invalidHandle )
		Log::Console( "unable to get CAntiSmac.txt config file" );
 
	// tokenize this file when we start
	cvarList = gFileManager.TokenFile(handle, ':');
 
	//nameVar = gInts.Cvar->FindVar("name");
 
	//nameVar->m_fnChangeCallback = nullptr;
 
	#endif
*/
 
	return;
}
 
void CAntiSmac::processCommand(CUserCmd *pUserCmd)
{
	if(nameSpam->getValue() == true)
	{
		// Log::Console("NameSpam enabled");
		std::string randName;
		for(int i = 0; i < 32; i++)
			randName += "\n";
 
		char *newName = const_cast<char *>(randName.c_str());
 
		// add one more character at the end so the server accepts it.
		newName[0] = '_';
 
		gLocalPlayerVars.name = newName;
	}
	else
	{
		gLocalPlayerVars.name = gInts.steam.friends->GetPersonaName();
	}
 
	return;
}
 
bool CAntiSmac::processGetCvarValue(SVC_GetCvarValue *msg)
{
	CLC_RespondCvarValue returnMsg;
 
	returnMsg.m_iCookie		= msg->m_iCookie;
	returnMsg.m_szCvarName  = msg->m_szCvarName;
	returnMsg.m_szCvarValue = "";
	returnMsg.m_eStatusCode = eQueryCvarValueStatus_ValueIntact; // always pretend that we have it
 
	Log::Console("{CVAR} GetCvarValue wants cvar %s", msg->m_szCvarName);
 
	char tempValue[256];
 
	tempValue[0] = '\0';
 
	bool hasValue = false;
 
	// check server vars
	for(auto &var : serverConvars)
	{
		if(!strcmp(msg->m_szCvarName, var.name))
		{
			returnMsg.m_szCvarValue = var.value;
			Log::Console("{CVAR}	we got value %s for cvar %s", returnMsg.m_szCvarValue, msg->m_szCvarName);
			hasValue = true;
			break;
		}
	}
 
	// possible optimization - doesnt convert every time
	std::string cvarName = msg->m_szCvarName;
 
	// check custom list
	for(auto &var : cvarList)
	{
		if(var.first == cvarName)
		{
			returnMsg.m_szCvarValue = var.second.c_str();
			Log::Console("{CVAR}	returning custom %s for cvar for %s", returnMsg.m_szCvarValue, msg->m_szCvarName);
			hasValue = true;
			break;
		}
	}
 
	// see if we got a value for it
	if(!hasValue)
	{
		// if not...
		Log::Console("{CVAR}	unable to return a value for %s: getting it!!", msg->m_szCvarName);
 
		// Does any ConCommand exist with this name?
		auto pVar = gInts.Cvar->FindVar(msg->m_szCvarName);
		if(pVar)
		{
			if(pVar->m_nFlags & (int)ConvarFlags::FCVAR_SERVER_CANNOT_QUERY)
			{
				// The server isn't allowed to query this.
				// just say its intact anyway
				returnMsg.m_eStatusCode = eQueryCvarValueStatus_ValueIntact;
			}
			else
			{
				returnMsg.m_eStatusCode = eQueryCvarValueStatus_ValueIntact;
 
				// default values should be allowed... I hope
				Log::Console("{CVAR}	getting default value for cvar %s", msg->m_szCvarName);
				strcpy_s(tempValue, pVar->m_pszDefaultValue);
				returnMsg.m_szCvarValue = tempValue;
			}
		}
		else
		{
			Log::Console("{CVAR}	cvar %s not found!!", msg->m_szCvarName);
			returnMsg.m_eStatusCode = eQueryCvarValueStatus_CvarNotFound;
			returnMsg.m_szCvarValue = tempValue;
		}
 
		// special constants because fuck you thats why
		if(!strcmp(msg->m_szCvarName, "mat_dxlevel") )
		{
			// mat_dxlevel default value is 0 for some fucking reason
			returnMsg.m_szCvarValue = "95";
		}
	}
 
	Log::Console("{CVAR} ending getCvarValue for %s by returning '%s'", returnMsg.m_szCvarName, returnMsg.m_szCvarValue);
 
	// send back via clientstate netchannel
	gInts.Engine->GetNetChannelInfo()->SendNetMsg(returnMsg);
 
	return true;
}
 
bool CAntiSmac::processSetConVar(NET_SetConVar *msg)
{
	#if _MSC_VER == 1900
	// Never process on local client, since the ConVar is directly linked here
	if(gInts.Engine->GetNetChannelInfo()->IsLoopback())
		return true;
 
	bool changed = false;
	
	// TODO: we do need to change some of these convars that handle gamemodes
 
	for(auto &var : msg->m_ConVars)
	{
		Log::Console("ProcessSetConvar got '%s' with value '%s'", var.name, var.value);
		for(auto &vvar : serverConvars)
		{
			if(!strcmp(var.name, vvar.name))
			{
				changed = true;
				Log::Console("changing value from %s to %s", vvar.value, var.value);
				vvar = var;
			}
		}
 
		if(!changed)
			serverConvars.push_back(var);
	}
 
	#endif
 
	return true;
}
 
bool CAntiSmac::processStringCmd(NET_StringCmd *msg)
{
	Log::Console("'%s': '%s'", msg->GetName(), msg->m_szCommand);
	return gInts.ClientState->ProcessStringCmd(msg);
}
 
void CAntiSmac::menuUpdate( F1_IConVar ** menuArray, int & currIndex )
{
	menuArray[ currIndex++ ] = antiSmacSwitch;
 
	if(antiSmacSwitch->getValue() )
	{
		menuArray[ currIndex++ ] = nameSpam;
	}
}