freax
07-11-2011, 06:46 PM
This is to stop boiiiis crying for nullpointer interfaces. Have phun...
typedef void* (*CreateInterfaceFunc)(const char *pName, int *pReturnCode);
class CSystem
{
public:
void OnLoad();
private:
void AddFactory(const string &strModule);
void *GetInterface(const string &strName) const;
private:
list<CreateInterfaceFunc> m_Factories;
};
void CSystem::OnLoad()
{
this->AddFactory("client.dll");
this->AddFactory("engine.dll");
this->AddFactory("vphysics.dll");
this->AddFactory("FileSystem_Steam.dll");
this->AddFactory("StudioRender.dll");
this->AddFactory("MaterialSystem.dll");
this->AddFactory("vguimatsurface.dll");
this->AddFactory("SteamClient.dll");
CreateInterfaceFunc AppSystemFactory = reinterpret_cast<CreateInterfaceFunc>(CSigScanner("engine.dll").Find(reinterpret_cast<unsigned char*>("\x8B\x44\x24\x04\x8B\x0D\x00\x00\x00\x00\x50\xE8\x00\x00\x00\x00\x8B\x 4C\x24\x08\x85\xC9\x74\x09"), "xxxxxx????xx????xxxxxxxx"));
if (AppSystemFactory)
{
this->m_Factories.push_front(AppSystemFactory);
ConnectTier1Libraries(&AppSystemFactory, 1);
ConnectTier2Libraries(&AppSystemFactory, 1);
ConnectTier3Libraries(&AppSystemFactory, 1);
}
ConVar_Register(0);
g_pClient = static_cast<IBaseClientDLL*>(this->GetInterface(CLIENT_DLL_INTERFACE_VERSION));
g_pEngine = static_cast<IVEngineClient*>(this->GetInterface(VENGINE_CLIENT_INTERFACE_VERSION));
// ect
}
void CSystem::AddFactory(const string &strModule)
{
HMODULE hModule = NULL;
for ( ; !hModule; hModule = GetModuleHandle(strModule.c_str()), Sleep(10));
CreateInterfaceFunc Factory = reinterpret_cast<CreateInterfaceFunc>(GetProcAddress(hModule, "CreateInterface"));
if (Factory != NULL)
{
this->m_Factories.push_back(Factory);
}
}
void *CSystem::GetInterface(const string &strName) const
{
for (list<CreateInterfaceFunc>::const_iterator it = this->m_Factories.begin(); it != this->m_Factories.end(); ++it)
{
void *pInterface = (*it)(strName.c_str(), NULL);
if (pInterface)
{
return pInterface;
}
}
string strVersion = strName.substr(strName.length() - 3, 3);
if (isdigit(strVersion[0]) && isdigit(strVersion[1]) && isdigit(strVersion[2]))
{
string strInterface = strName.substr(0, strName.length() - 3);
for (int i = 100; i >= 0; --i)
{
string strCurrent = (strInterface + g_pUtils->Format("%03d", i));
for (list<CreateInterfaceFunc>::const_iterator it = this->m_Factories.begin(); it != this->m_Factories.end(); ++it)
{
void *pInterface = (*it)(strCurrent.c_str(), NULL);
if (pInterface)
{
return pInterface;
}
}
}
}
return NULL;
}
I know that I actually could use templates to avoid static_cast, but well. I'm fucking lazy.
typedef void* (*CreateInterfaceFunc)(const char *pName, int *pReturnCode);
class CSystem
{
public:
void OnLoad();
private:
void AddFactory(const string &strModule);
void *GetInterface(const string &strName) const;
private:
list<CreateInterfaceFunc> m_Factories;
};
void CSystem::OnLoad()
{
this->AddFactory("client.dll");
this->AddFactory("engine.dll");
this->AddFactory("vphysics.dll");
this->AddFactory("FileSystem_Steam.dll");
this->AddFactory("StudioRender.dll");
this->AddFactory("MaterialSystem.dll");
this->AddFactory("vguimatsurface.dll");
this->AddFactory("SteamClient.dll");
CreateInterfaceFunc AppSystemFactory = reinterpret_cast<CreateInterfaceFunc>(CSigScanner("engine.dll").Find(reinterpret_cast<unsigned char*>("\x8B\x44\x24\x04\x8B\x0D\x00\x00\x00\x00\x50\xE8\x00\x00\x00\x00\x8B\x 4C\x24\x08\x85\xC9\x74\x09"), "xxxxxx????xx????xxxxxxxx"));
if (AppSystemFactory)
{
this->m_Factories.push_front(AppSystemFactory);
ConnectTier1Libraries(&AppSystemFactory, 1);
ConnectTier2Libraries(&AppSystemFactory, 1);
ConnectTier3Libraries(&AppSystemFactory, 1);
}
ConVar_Register(0);
g_pClient = static_cast<IBaseClientDLL*>(this->GetInterface(CLIENT_DLL_INTERFACE_VERSION));
g_pEngine = static_cast<IVEngineClient*>(this->GetInterface(VENGINE_CLIENT_INTERFACE_VERSION));
// ect
}
void CSystem::AddFactory(const string &strModule)
{
HMODULE hModule = NULL;
for ( ; !hModule; hModule = GetModuleHandle(strModule.c_str()), Sleep(10));
CreateInterfaceFunc Factory = reinterpret_cast<CreateInterfaceFunc>(GetProcAddress(hModule, "CreateInterface"));
if (Factory != NULL)
{
this->m_Factories.push_back(Factory);
}
}
void *CSystem::GetInterface(const string &strName) const
{
for (list<CreateInterfaceFunc>::const_iterator it = this->m_Factories.begin(); it != this->m_Factories.end(); ++it)
{
void *pInterface = (*it)(strName.c_str(), NULL);
if (pInterface)
{
return pInterface;
}
}
string strVersion = strName.substr(strName.length() - 3, 3);
if (isdigit(strVersion[0]) && isdigit(strVersion[1]) && isdigit(strVersion[2]))
{
string strInterface = strName.substr(0, strName.length() - 3);
for (int i = 100; i >= 0; --i)
{
string strCurrent = (strInterface + g_pUtils->Format("%03d", i));
for (list<CreateInterfaceFunc>::const_iterator it = this->m_Factories.begin(); it != this->m_Factories.end(); ++it)
{
void *pInterface = (*it)(strCurrent.c_str(), NULL);
if (pInterface)
{
return pInterface;
}
}
}
}
return NULL;
}
I know that I actually could use templates to avoid static_cast, but well. I'm fucking lazy.