Add gamedata for EntityFactoryDictionary and IServer for Dota 2 on Linux (bug 6068, r=psychonic).

This commit is contained in:
Scott Ehlert 2014-03-03 05:20:40 -06:00
parent aa75fd24d8
commit 22e8b53029
3 changed files with 50 additions and 16 deletions

View File

@ -119,14 +119,31 @@ bool UTIL_VerifySignature(const void *addr, const char *sig, size_t len)
}
#if defined PLATFORM_WINDOWS
#define FAKECLIENT_KEY "CreateFakeClient_Windows"
#elif defined PLATFORM_LINUX
#define FAKECLIENT_KEY "CreateFakeClient_Linux"
#elif defined PLATFORM_APPLE
#define FAKECLIENT_KEY "CreateFakeClient_Mac"
#else
#error "Unsupported platform"
#endif
void GetIServer()
{
void *addr;
const char *sigstr;
char sig[32];
size_t siglen;
int offset;
void *vfunc = NULL;
/* Use the symbol if it exists */
if (g_pGameConf->GetMemSig("sv", &addr) && addr)
{
iserver = reinterpret_cast<IServer *>(addr);
return;
}
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
/* Get the CreateFakeClient function pointer */
if (!(vfunc=SH_GET_ORIG_VFNPTR_ENTRY(engine, &IVEngineServer::CreateFakeClient)))
@ -147,7 +164,7 @@ void GetIServer()
#endif
/* Get signature string for IVEngineServer::CreateFakeClient() */
sigstr = g_pGameConf->GetKeyValue("CreateFakeClient_Windows");
sigstr = g_pGameConf->GetKeyValue(FAKECLIENT_KEY);
if (!sigstr)
{
@ -172,18 +189,6 @@ void GetIServer()
/* Finally we have the interface we were looking for */
iserver = *reinterpret_cast<IServer **>(reinterpret_cast<unsigned char *>(vfunc) + offset);
}
#elif defined PLATFORM_POSIX
void GetIServer()
{
void *addr;
if (!g_pGameConf->GetMemSig("sv", &addr) || !addr)
{
return;
}
iserver = reinterpret_cast<IServer *>(addr);
}
#endif
void GetResourceEntity()
{

View File

@ -533,11 +533,26 @@ CEntityFactoryDictionary *GetEntityFactoryDictionary()
retData.type = PassType_Basic;
void *addr;
if (g_pGameConf->GetMemSig("EntityFactory", &addr) && addr != NULL)
if (!g_pGameConf->GetMemSig("EntityFactory", &addr) || !addr)
{
pWrapper = g_pBinTools->CreateCall(addr, CallConv_Cdecl, &retData, NULL, 0);
int offset;
if (!g_pGameConf->GetMemSig("EntityFactoryCaller", &addr) || !addr)
return NULL;
if (!g_pGameConf->GetOffset("EntityFactoryCallOffset", &offset))
return NULL;
// Get relative offset to function
int32_t funcOffset = *(int32_t *)((intptr_t)addr + offset);
// Get real address of function
// Address of signature + offset of relative offset + sizeof(int32_t) offset + relative offset
addr = (void *)((intptr_t)addr + offset + 4 + funcOffset);
}
pWrapper = g_pBinTools->CreateCall(addr, CallConv_Cdecl, &retData, NULL, 0);
if (pWrapper)
{
void *returnData = NULL;

View File

@ -146,6 +146,7 @@
* here.
*/
"CreateFakeClient_Windows" "\x55\x8B\xEC\x56\xFF\x75\x0C\xB9\x2A\x2A\x2A\x2A\xE8"
"CreateFakeClient_Linux" "\x55\x89\xE5\x83\xEC\x2A\x8B\x45\x10\x89\x5D\xF8\x89\x75\xFC\x8B\x5D\x08\xC7\x04\x24\x2A\x2A\x2A\x2A\x89"
}
"Offsets"
@ -154,6 +155,7 @@
"sv"
{
"windows" "8"
"linux" "21"
}
}
@ -186,7 +188,6 @@
"EntityFactory"
{
"library" "server"
// "linux" "" // TODO
"mac" "@_Z23EntityFactoryDictionaryv"
}
@ -196,6 +197,13 @@
"library" "server"
"windows" "\xFF\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x8B\xC8\xC7"
}
// EntityFactoryDictionary is difficult to find on Linux due to multiple matches. This finds a caller of it instead.
"EntityFactoryCaller"
{
"library" "server"
"linux" "\x55\x89\xE5\x57\x56\x53\x83\xEC\x2A\xE8\x2A\x2A\x2A\x2A\x85\xC0\x89\x45"
}
}
"Offsets"
@ -204,6 +212,12 @@
{
"windows" "4"
}
// This is the offset into the address found by the EntityFactoryCaller signature.
"EntityFactoryCallOffset"
{
"linux" "10"
}
}
}