void GetIServer()
{
	int offset;
	void *vfunc = NULL;

	/* Get the offset into CreateFakeClient */
	if (!g_pGameConf->GetOffset("sv", &offset))
	{
		return;
	}
#if defined METAMOD_PLAPI_VERSION
	/* Get the CreateFakeClient function pointer */
	if (!(vfunc=SH_GET_ORIG_VFNPTR_ENTRY(engine, &IVEngineServer::CreateFakeClient)))
	{
		return;
	}

	/* Check if we're on the expected function */
	if (!vcmp(vfunc, ISERVER_WIN_SIG, ISERVER_WIN_SIG_LEN))
	{
		return;
	}

	/* Finally we have the interface we were looking for */
	iserver = *reinterpret_cast<IServer **>(reinterpret_cast<unsigned char *>(vfunc) + offset);
#else
	/* Get the interface manually */
	SourceHook::MemFuncInfo info = {true, -1, 0, 0};
	SourceHook::GetFuncInfo(&IVEngineServer::CreateFakeClient, info);

	vfunc = enginePatch->GetOrigFunc(info.vtbloffs, info.vtblindex);
	if (!vfunc)
	{
		void **vtable = *reinterpret_cast<void ***>(enginePatch->GetThisPtr() + info.thisptroffs + info.vtbloffs);
		vfunc = vtable[info.vtblindex];
	}
	/* Check if we're on the expected function */
	if (!vcmp(vfunc, ISERVER_WIN_SIG, ISERVER_WIN_SIG_LEN))
	{
		return;
	}

	iserver = *reinterpret_cast<IServer **>(reinterpret_cast<unsigned char *>(vfunc) + offset);
#endif
}
Beispiel #2
0
void GetIServer()
{
#if SOURCE_ENGINE == SE_TF2        \
	|| SOURCE_ENGINE == SE_DODS    \
	|| SOURCE_ENGINE == SE_HL2DM   \
	|| SOURCE_ENGINE == SE_CSS     \
	|| SOURCE_ENGINE == SE_SDK2013 \
	|| SOURCE_ENGINE == SE_BMS     \
	|| SOURCE_ENGINE == SE_INSURGENCY

#if SOURCE_ENGINE != SE_INSURGENCY
	if (g_SMAPI->GetEngineFactory(false)("VEngineServer022", nullptr))
#endif // !SE_INSURGENCY
	{
		iserver = engine->GetIServer();
		return;
	}
#endif

	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)))
	{
		return;
	}
#else
	/* Get the interface manually */
	SourceHook::MemFuncInfo info = {true, -1, 0, 0};
	SourceHook::GetFuncInfo(&IVEngineServer::CreateFakeClient, info);

	vfunc = enginePatch->GetOrigFunc(info.vtbloffs, info.vtblindex);
	if (!vfunc)
	{
		void **vtable = *reinterpret_cast<void ***>(enginePatch->GetThisPtr() + info.thisptroffs + info.vtbloffs);
		vfunc = vtable[info.vtblindex];
	}
#endif

	/* Get signature string for IVEngineServer::CreateFakeClient() */
	sigstr = g_pGameConf->GetKeyValue(FAKECLIENT_KEY);

	if (!sigstr)
	{
		return;
	}

	/* Convert signature string to signature bytes */
	siglen = UTIL_StringToSignature(sigstr, sig, sizeof(sig));

	/* Check if we're on the expected function */
	if (!UTIL_VerifySignature(vfunc, sig, siglen))
	{
		return;
	}

	/* Get the offset into CreateFakeClient */
	if (!g_pGameConf->GetOffset("sv", &offset))
	{
		return;
	}

	/* Finally we have the interface we were looking for */
	iserver = *reinterpret_cast<IServer **>(reinterpret_cast<unsigned char *>(vfunc) + offset);
}