extensions/sdktools/vglobals.cpp
author Matt Woodrow <pred@alliedmods.net>
Fri Jul 24 12:34:31 2009 +1200 (2009-07-24)
changeset 2746 8d68569b9648
parent 2535 b3bfd3c1ad9f
child 2858 c03bf7e8cba8
permissions -rw-r--r--
Added support for logical (non-networked) entities using entity references - See http://wiki.alliedmods.net/Entity_References_%28SourceMod%29 (bug 2459, r=dvander)
teame06@1245
     1
/**
teame06@1245
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
teame06@1245
     4
 * SourceMod SDKTools Extension
ds@1947
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
teame06@1245
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
teame06@1245
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
teame06@1245
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
teame06@1245
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
faluco@1247
    28
 *
faluco@1247
    29
 * Version: $Id$
faluco@1247
    30
 */
faluco@1247
    31
faluco@1247
    32
#include "extension.h"
faluco@1247
    33
faluco@1247
    34
void **g_pGameRules = NULL;
faluco@1247
    35
void *g_EntList = NULL;
faluco@1247
    36
pred@2746
    37
faluco@1247
    38
void InitializeValveGlobals()
faluco@1247
    39
{
pred@2746
    40
	g_EntList = gamehelpers->GetGlobalEntityList();
faluco@1247
    41
pred@2746
    42
	char *addr;
faluco@1718
    43
pred@2746
    44
#ifdef PLATFORM_WINDOWS
faluco@1718
    45
	/* g_pGameRules */
faluco@1718
    46
	if (!g_pGameConf->GetMemSig("CreateGameRulesObject", (void **)&addr) || !addr)
faluco@1718
    47
	{
faluco@1718
    48
		return;
faluco@1718
    49
	}
pred@2746
    50
pred@2746
    51
	int offset;
faluco@1718
    52
	if (!g_pGameConf->GetOffset("g_pGameRules", &offset) || !offset)
faluco@1718
    53
	{
faluco@1718
    54
		return;
faluco@1718
    55
	}
faluco@1718
    56
	g_pGameRules = *reinterpret_cast<void ***>(addr + offset);
faluco@1247
    57
#elif defined PLATFORM_LINUX
faluco@1247
    58
	/* g_pGameRules */
faluco@1247
    59
	if (!g_pGameConf->GetMemSig("g_pGameRules", (void **)&addr) || !addr)
faluco@1247
    60
	{
faluco@1247
    61
		return;
faluco@1247
    62
	}
faluco@1247
    63
	g_pGameRules = reinterpret_cast<void **>(addr);
pred@2746
    64
#endif
faluco@1247
    65
}
faluco@1769
    66
ds@2535
    67
size_t UTIL_StringToSignature(const char *str, char buffer[], size_t maxlength)
ds@1952
    68
{
ds@2535
    69
	size_t real_bytes = 0;
ds@2535
    70
	size_t length = strlen(str);
ds@1952
    71
ds@2535
    72
	for (size_t i=0; i<length; i++)
ds@2535
    73
	{
ds@2535
    74
		if (real_bytes >= maxlength)
ds@2535
    75
		{
ds@2535
    76
			break;
ds@2535
    77
		}
ds@2535
    78
		buffer[real_bytes++] = (unsigned char)str[i];
ds@2535
    79
		if (str[i] == '\\'
ds@2535
    80
			&& str[i+1] == 'x')
ds@2535
    81
		{
ds@2535
    82
			if (i + 3 >= length)
ds@2535
    83
			{
ds@2535
    84
				continue;
ds@2535
    85
			}
ds@2535
    86
			/* Get the hex part */
ds@2535
    87
			char s_byte[3];
ds@2535
    88
			int r_byte;
ds@2535
    89
			s_byte[0] = str[i+2];
ds@2535
    90
			s_byte[1] = str[i+3];
ds@2535
    91
			s_byte[2] = '\n';
ds@2535
    92
			/* Read it as an integer */
ds@2535
    93
			sscanf(s_byte, "%x", &r_byte);
ds@2535
    94
			/* Save the value */
ds@2535
    95
			buffer[real_bytes-1] = (unsigned char)r_byte;
ds@2535
    96
			/* Adjust index */
ds@2535
    97
			i += 3;
ds@2535
    98
		}
ds@2535
    99
	}
ds@2535
   100
ds@2535
   101
	return real_bytes;
ds@2535
   102
}
ds@2535
   103
ds@2535
   104
bool UTIL_VerifySignature(const void *addr, const char *sig, size_t len)
ds@2535
   105
{
ds@2535
   106
	unsigned char *addr1 = (unsigned char *) addr;
ds@2535
   107
	unsigned char *addr2 = (unsigned char *) sig;
ds@2535
   108
ds@2535
   109
	for (size_t i = 0; i < len; i++)
ds@1952
   110
	{
ds@1952
   111
		if (addr2[i] == '*')
ds@1952
   112
			continue;
ds@1952
   113
		if (addr1[i] != addr2[i])
ds@1952
   114
			return false;
ds@1952
   115
	}
ds@1952
   116
ds@1952
   117
	return true;
faluco@1773
   118
}
faluco@1773
   119
faluco@1769
   120
#if defined PLATFORM_WINDOWS
faluco@1769
   121
void GetIServer()
faluco@1769
   122
{
ds@2535
   123
	const char *sigstr;
ds@2535
   124
	char sig[32];
ds@2535
   125
	size_t siglen;
faluco@1769
   126
	int offset;
faluco@1769
   127
	void *vfunc = NULL;
faluco@1769
   128
faluco@1769
   129
#if defined METAMOD_PLAPI_VERSION
faluco@1769
   130
	/* Get the CreateFakeClient function pointer */
faluco@1769
   131
	if (!(vfunc=SH_GET_ORIG_VFNPTR_ENTRY(engine, &IVEngineServer::CreateFakeClient)))
faluco@1769
   132
	{
faluco@1769
   133
		return;
faluco@1769
   134
	}
faluco@1769
   135
#else
faluco@1769
   136
	/* Get the interface manually */
faluco@1769
   137
	SourceHook::MemFuncInfo info = {true, -1, 0, 0};
faluco@1769
   138
	SourceHook::GetFuncInfo(&IVEngineServer::CreateFakeClient, info);
faluco@1769
   139
faluco@1769
   140
	vfunc = enginePatch->GetOrigFunc(info.vtbloffs, info.vtblindex);
faluco@1769
   141
	if (!vfunc)
faluco@1769
   142
	{
faluco@1769
   143
		void **vtable = *reinterpret_cast<void ***>(enginePatch->GetThisPtr() + info.thisptroffs + info.vtbloffs);
faluco@1769
   144
		vfunc = vtable[info.vtblindex];
faluco@1769
   145
	}
ds@2535
   146
#endif
ds@2535
   147
ds@2535
   148
	/* Get signature string for IVEngineServer::CreateFakeClient() */
ds@2535
   149
	sigstr = g_pGameConf->GetKeyValue("CreateFakeClient_Windows");
ds@2535
   150
ds@2535
   151
	if (!sigstr)
faluco@1773
   152
	{
faluco@1773
   153
		return;
faluco@1773
   154
	}
faluco@1769
   155
ds@2535
   156
	/* Convert signature string to signature bytes */
ds@2535
   157
	siglen = UTIL_StringToSignature(sigstr, sig, sizeof(sig));
ds@2535
   158
ds@2535
   159
	/* Check if we're on the expected function */
ds@2535
   160
	if (!UTIL_VerifySignature(vfunc, sig, siglen))
ds@2535
   161
	{
ds@2535
   162
		return;
ds@2535
   163
	}
ds@2535
   164
ds@2535
   165
	/* Get the offset into CreateFakeClient */
ds@2535
   166
	if (!g_pGameConf->GetOffset("sv", &offset))
ds@2535
   167
	{
ds@2535
   168
		return;
ds@2535
   169
	}
ds@2535
   170
ds@2535
   171
	/* Finally we have the interface we were looking for */
faluco@1769
   172
	iserver = *reinterpret_cast<IServer **>(reinterpret_cast<unsigned char *>(vfunc) + offset);
faluco@1769
   173
}
faluco@1769
   174
#elif defined PLATFORM_POSIX
faluco@1769
   175
void GetIServer()
faluco@1769
   176
{
faluco@1769
   177
	void *addr;
faluco@1769
   178
	if (!g_pGameConf->GetMemSig("sv", &addr) || !addr)
faluco@1769
   179
	{
faluco@1769
   180
		return;
faluco@1769
   181
	}
faluco@1769
   182
faluco@1773
   183
	iserver = reinterpret_cast<IServer *>(addr);
faluco@1769
   184
}
faluco@1769
   185
#endif