Skip to content

Instantly share code, notes, and snippets.

@markhc
Created March 30, 2016 17:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markhc/c975ce63c8714709e410f1be43e4048f to your computer and use it in GitHub Desktop.
Save markhc/c975ce63c8714709e410f1be43e4048f to your computer and use it in GitHub Desktop.
#include "SpoofedConvar.hpp"
using namespace SourceEngine;
SpoofedConvar::SpoofedConvar(const char* szCVar) {
m_pOriginalCVar = SourceEngine::Interfaces::CVar()->FindVar(szCVar);
Spoof();
}
SpoofedConvar::SpoofedConvar(SourceEngine::ConVar* pCVar) {
m_pOriginalCVar = pCVar;
Spoof();
}
SpoofedConvar::~SpoofedConvar() {
if(IsSpoofed()) {
DWORD dwOld;
//Restore flags
SetFlags(m_iOriginalFlags);
//Restore value
SetString(m_szOriginalValue);
//Restore the name
VirtualProtect((LPVOID)m_pOriginalCVar->m_pszName, 128, PAGE_READWRITE, &dwOld);
strcpy((char*)m_pOriginalCVar->m_pszName, m_szOriginalName);
VirtualProtect((LPVOID)m_pOriginalCVar->m_pszName, 128, dwOld, &dwOld);
//Unregister dummy cvar
SourceEngine::Interfaces::CVar()->UnregisterConCommand(m_pDummyCVar);
free(m_pDummyCVar);
m_pDummyCVar = nullptr;
}
}
bool SpoofedConvar::IsSpoofed() {
return m_pDummyCVar != nullptr;
}
void SpoofedConvar::Spoof() {
if(!IsSpoofed() && m_pOriginalCVar) {
//Save old name value and flags so we can restore the cvar lates if needed
m_iOriginalFlags = m_pOriginalCVar->m_nFlags;
strcpy(m_szOriginalName, m_pOriginalCVar->m_pszName);
strcpy(m_szOriginalValue, m_pOriginalCVar->GetString());
sprintf_s(m_szDummyName, 128, "dummy_%s", m_szOriginalName);
//Create the dummy cvar
m_pDummyCVar = (SourceEngine::ConVar*)malloc(sizeof(SourceEngine::ConVar));
if(!m_pDummyCVar) return;
memcpy(m_pDummyCVar, m_pOriginalCVar, sizeof(SourceEngine::ConVar));
m_pDummyCVar->m_pNext = nullptr;
//Register it
SourceEngine::Interfaces::CVar()->RegisterConCommand(m_pDummyCVar);
//Fix "write access violation" bullshit
DWORD dwOld;
VirtualProtect((LPVOID)m_pOriginalCVar->m_pszName, 128, PAGE_READWRITE, &dwOld);
//Rename the cvar
strcpy((char*)m_pOriginalCVar->m_pszName, m_szDummyName);
VirtualProtect((LPVOID)m_pOriginalCVar->m_pszName, 128, dwOld, &dwOld);
SetFlags(FCVAR_NONE);
}
}
void SpoofedConvar::SetFlags(int flags) {
if(IsSpoofed()) {
m_pOriginalCVar->m_nFlags = flags;
}
}
int SpoofedConvar::GetFlags() {
return m_pOriginalCVar->GetFlags();
}
void SpoofedConvar::SetInt(int iValue) {
if(IsSpoofed()) {
m_pOriginalCVar->SetValue(iValue);
}
}
void SpoofedConvar::SetBool(bool bValue) {
if(IsSpoofed()) {
m_pOriginalCVar->SetValue(bValue);
}
}
void SpoofedConvar::SetFloat(float flValue) {
if(IsSpoofed()) {
m_pOriginalCVar->SetValue(flValue);
}
}
void SpoofedConvar::SetString(const char* szValue) {
if(IsSpoofed()) {
m_pOriginalCVar->SetValue(szValue);
}
}
int SpoofedConvar::GetInt() {
return m_pOriginalCVar->GetInt();
}
float SpoofedConvar::GetFloat() {
return m_pOriginalCVar->GetFloat();
}
const char* SpoofedConvar::GetString() {
return m_pOriginalCVar->GetString();
}
#pragma once
#include "../SourceEngine/SDK.hpp"
class SpoofedConvar {
public:
SpoofedConvar(const char* szCVar);
SpoofedConvar(ConVar* pCVar);
~SpoofedConvar();
bool IsSpoofed();
void Spoof();
void SetFlags(int flags);
int GetFlags();
void SetBool(bool bValue);
void SetInt(int iValue);
void SetFloat(float flValue);
void SetString(const char* szValue);
int GetInt();
float GetFloat();
const char* GetString();
private:
ConVar* m_pOriginalCVar = nullptr;
ConVar* m_pDummyCVar = nullptr;
char m_szDummyName[128];
char m_szDummyValue[128];
char m_szOriginalName[128];
char m_szOriginalValue[128];
int m_iOriginalFlags;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment