extensions/sdktools/vglobals.cpp
author David Anderson <dvander@alliedmods.net>
Tue Jan 22 17:18:15 2008 +0000 (2008-01-22)
changeset 1855 7871fb255eb5
parent 1773 d00a853ec547
child 1947 e73a1e51833b
permissions -rw-r--r--
added amb1383 - data value to filter functions
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod SDKTools Extension
     5  * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
     6  * =============================================================================
     7  *
     8  * This program is free software; you can redistribute it and/or modify it under
     9  * the terms of the GNU General Public License, version 3.0, as published by the
    10  * Free Software Foundation.
    11  * 
    12  * This program is distributed in the hope that it will be useful, but WITHOUT
    13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    15  * details.
    16  *
    17  * You should have received a copy of the GNU General Public License along with
    18  * this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  * As a special exception, AlliedModders LLC gives you permission to link the
    21  * code of this program (as well as its derivative works) to "Half-Life 2," the
    22  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    23  * by the Valve Corporation.  You must obey the GNU General Public License in
    24  * all respects for all other code used.  Additionally, AlliedModders LLC grants
    25  * this exception to all derivative works.  AlliedModders LLC defines further
    26  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    27  * or <http://www.sourcemod.net/license.php>.
    28  *
    29  * Version: $Id$
    30  */
    31 
    32 #include "extension.h"
    33 
    34 void **g_pGameRules = NULL;
    35 void *g_EntList = NULL;
    36 
    37 #ifdef PLATFORM_WINDOWS
    38 void InitializeValveGlobals()
    39 {
    40 	char *addr = NULL;
    41 	int offset;
    42 
    43 	/* gEntList and/or g_pEntityList */
    44 	if (!g_pGameConf->GetMemSig("LevelShutdown", (void **)&addr) || !addr)
    45 	{
    46 		return;
    47 	}
    48 	if (!g_pGameConf->GetOffset("gEntList", &offset) || !offset)
    49 	{
    50 		return;
    51 	}
    52 	g_EntList = *reinterpret_cast<void **>(addr + offset);
    53 
    54 	/* g_pGameRules */
    55 	if (!g_pGameConf->GetMemSig("CreateGameRulesObject", (void **)&addr) || !addr)
    56 	{
    57 		return;
    58 	}
    59 	if (!g_pGameConf->GetOffset("g_pGameRules", &offset) || !offset)
    60 	{
    61 		return;
    62 	}
    63 	g_pGameRules = *reinterpret_cast<void ***>(addr + offset);
    64 }
    65 #elif defined PLATFORM_LINUX
    66 void InitializeValveGlobals()
    67 {
    68 	char *addr = NULL;
    69 
    70 	/* gEntList and/or g_pEntityList */
    71 	if (!g_pGameConf->GetMemSig("gEntList", (void **)&addr) || !addr)
    72 	{
    73 		return;
    74 	}
    75 	g_EntList = reinterpret_cast<void *>(addr);
    76 
    77 	/* g_pGameRules */
    78 	if (!g_pGameConf->GetMemSig("g_pGameRules", (void **)&addr) || !addr)
    79 	{
    80 		return;
    81 	}
    82 	g_pGameRules = reinterpret_cast<void **>(addr);
    83 }
    84 #endif
    85 
    86 bool vcmp(const void *_addr1, const void *_addr2, size_t len)
    87 {
    88 	unsigned char *addr1 = (unsigned char *)_addr1;
    89 	unsigned char *addr2 = (unsigned char *)_addr2;
    90 
    91 	for (size_t i=0; i<len; i++)
    92 	{
    93 		if (addr2[i] == '*')
    94 			continue;
    95 		if (addr1[i] != addr2[i])
    96 			return false;
    97 	}
    98 
    99 	return true;
   100 }
   101 
   102 #if defined PLATFORM_WINDOWS
   103 	/* Thanks to DS for the sigs */
   104 	#define ISERVER_WIN_SIG				"\x8B\x44\x24\x2A\x50\xB9\x2A\x2A\x2A\x2A\xE8"
   105 	#define ISERVER_WIN_SIG_LEN			11
   106 void GetIServer()
   107 {
   108 	int offset;
   109 	void *vfunc = NULL;
   110 
   111 	/* Get the offset into CreateFakeClient */
   112 	if (!g_pGameConf->GetOffset("sv", &offset))
   113 	{
   114 		return;
   115 	}
   116 #if defined METAMOD_PLAPI_VERSION
   117 	/* Get the CreateFakeClient function pointer */
   118 	if (!(vfunc=SH_GET_ORIG_VFNPTR_ENTRY(engine, &IVEngineServer::CreateFakeClient)))
   119 	{
   120 		return;
   121 	}
   122 
   123 	/* Check if we're on the expected function */
   124 	if (!vcmp(vfunc, ISERVER_WIN_SIG, ISERVER_WIN_SIG_LEN))
   125 	{
   126 		return;
   127 	}
   128 
   129 	/* Finally we have the interface we were looking for */
   130 	iserver = *reinterpret_cast<IServer **>(reinterpret_cast<unsigned char *>(vfunc) + offset);
   131 #else
   132 	/* Get the interface manually */
   133 	SourceHook::MemFuncInfo info = {true, -1, 0, 0};
   134 	SourceHook::GetFuncInfo(&IVEngineServer::CreateFakeClient, info);
   135 
   136 	vfunc = enginePatch->GetOrigFunc(info.vtbloffs, info.vtblindex);
   137 	if (!vfunc)
   138 	{
   139 		void **vtable = *reinterpret_cast<void ***>(enginePatch->GetThisPtr() + info.thisptroffs + info.vtbloffs);
   140 		vfunc = vtable[info.vtblindex];
   141 	}
   142 	/* Check if we're on the expected function */
   143 	if (!vcmp(vfunc, ISERVER_WIN_SIG, ISERVER_WIN_SIG_LEN))
   144 	{
   145 		return;
   146 	}
   147 
   148 	iserver = *reinterpret_cast<IServer **>(reinterpret_cast<unsigned char *>(vfunc) + offset);
   149 #endif
   150 }
   151 #elif defined PLATFORM_POSIX
   152 void GetIServer()
   153 {
   154 	void *addr;
   155 	if (!g_pGameConf->GetMemSig("sv", &addr) || !addr)
   156 	{
   157 		return;
   158 	}
   159 
   160 	iserver = reinterpret_cast<IServer *>(addr);
   161 }
   162 #endif